gecko/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h
Thomas Zimmermann b9631a0fc1 Bug 1091577: Remove unused helpers from daemon backend, r=shawnjohnjr
This patch removes unused unpack functions, notification and
interface runnables from Bluetooth's daemon backend.
2014-11-05 15:43:07 +01:00

730 lines
15 KiB
C++

/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_bluedroid_bluetoothdaemonhelpers_h__
#define mozilla_dom_bluetooth_bluedroid_bluetoothdaemonhelpers_h__
#include "BluetoothCommon.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/ipc/BluetoothDaemonConnection.h"
#include "nsThreadUtils.h"
#if MOZ_IS_GCC && MOZ_GCC_VERSION_AT_LEAST(4, 7, 0)
/* use designated array initializers if supported */
#define INIT_ARRAY_AT(in_, out_) \
[in_] = out_
#else
/* otherwise init array element by position */
#define INIT_ARRAY_AT(in_, out_) \
out_
#endif
#define CONVERT(in_, out_) \
INIT_ARRAY_AT(in_, out_)
using namespace mozilla::ipc;
BEGIN_BLUETOOTH_NAMESPACE
//
// Helper structures
//
enum BluetoothAclState {
ACL_STATE_CONNECTED,
ACL_STATE_DISCONNECTED
};
enum BluetoothSspPairingVariant {
SSP_VARIANT_PASSKEY_CONFIRMATION,
SSP_VARIANT_PASSKEY_ENTRY,
SSP_VARIANT_CONSENT,
SSP_VARIANT_PASSKEY_NOTIFICATION
};
struct BluetoothAddress {
uint8_t mAddr[6];
};
struct BluetoothConfigurationParameter {
uint8_t mType;
uint16_t mLength;
nsAutoArrayPtr<uint8_t> mValue;
};
struct BluetoothDaemonPDUHeader {
BluetoothDaemonPDUHeader()
: mService(0x00)
, mOpcode(0x00)
, mLength(0x00)
{ }
BluetoothDaemonPDUHeader(uint8_t aService, uint8_t aOpcode, uint8_t aLength)
: mService(aService)
, mOpcode(aOpcode)
, mLength(aLength)
{ }
uint8_t mService;
uint8_t mOpcode;
uint16_t mLength;
};
struct BluetoothPinCode {
uint8_t mPinCode[16];
uint8_t mLength;
};
struct BluetoothRemoteName {
uint8_t mName[249];
};
struct BluetoothServiceName {
uint8_t mName[256];
};
//
// Conversion
//
// PDUs can only store primitive data types, such as intergers or
// strings. Gecko often uses more complex data types, such as
// enumators or stuctures. Conversion functions convert between
// primitive data and internal Gecko's data types during a PDU's
// packing and unpacking.
//
nsresult
Convert(bool aIn, uint8_t& aOut);
nsresult
Convert(bool aIn, BluetoothScanMode& aOut);
nsresult
Convert(int aIn, int16_t& aOut);
nsresult
Convert(uint8_t aIn, bool& aOut);
nsresult
Convert(uint8_t aIn, BluetoothAclState& aOut);
nsresult
Convert(uint8_t aIn, BluetoothBondState& aOut);
nsresult
Convert(uint8_t aIn, BluetoothDeviceType& aOut);
nsresult
Convert(uint8_t aIn, BluetoothPropertyType& aOut);
nsresult
Convert(uint8_t aIn, BluetoothScanMode& aOut);
nsresult
Convert(uint8_t aIn, BluetoothSspPairingVariant& aOut);
nsresult
Convert(uint8_t aIn, BluetoothStatus& aOut);
nsresult
Convert(uint32_t aIn, int& aOut);
nsresult
Convert(size_t aIn, uint16_t& aOut);
nsresult
Convert(const nsAString& aIn, BluetoothAddress& aOut);
nsresult
Convert(const nsAString& aIn, BluetoothPinCode& aOut);
nsresult
Convert(const nsAString& aIn, BluetoothPropertyType& aOut);
nsresult
Convert(const nsAString& aIn, BluetoothServiceName& aOut);
nsresult
Convert(const nsAString& aIn, BluetoothSspPairingVariant& aOut);
nsresult
Convert(BluetoothAclState aIn, bool& aOut);
nsresult
Convert(const BluetoothAddress& aIn, nsAString& aOut);
nsresult
Convert(BluetoothPropertyType aIn, uint8_t& aOut);
nsresult
Convert(const BluetoothRemoteName& aIn, nsAString& aOut);
nsresult
Convert(BluetoothScanMode aIn, uint8_t& aOut);
nsresult
Convert(BluetoothSocketType aIn, uint8_t& aOut);
nsresult
Convert(BluetoothSspPairingVariant aIn, uint8_t& aOut);
nsresult
Convert(BluetoothSspPairingVariant aIn, nsAString& aOut);
//
// Packing
//
nsresult
PackPDU(bool aIn, BluetoothDaemonPDU& aPDU);
inline nsresult
PackPDU(uint8_t aIn, BluetoothDaemonPDU& aPDU)
{
return aPDU.Write(aIn);
}
inline nsresult
PackPDU(uint16_t aIn, BluetoothDaemonPDU& aPDU)
{
return aPDU.Write(aIn);
}
inline nsresult
PackPDU(int32_t aIn, BluetoothDaemonPDU& aPDU)
{
return aPDU.Write(aIn);
}
inline nsresult
PackPDU(uint32_t aIn, BluetoothDaemonPDU& aPDU)
{
return aPDU.Write(aIn);
}
nsresult
PackPDU(const BluetoothAddress& aIn, BluetoothDaemonPDU& aPDU);
nsresult
PackPDU(const BluetoothConfigurationParameter& aIn, BluetoothDaemonPDU& aPDU);
nsresult
PackPDU(const BluetoothDaemonPDUHeader& aIn, BluetoothDaemonPDU& aPDU);
nsresult
PackPDU(const BluetoothNamedValue& aIn, BluetoothDaemonPDU& aPDU);
nsresult
PackPDU(const BluetoothPinCode& aIn, BluetoothDaemonPDU& aPDU);
nsresult
PackPDU(BluetoothPropertyType aIn, BluetoothDaemonPDU& aPDU);
nsresult
PackPDU(const BluetoothServiceName& aIn, BluetoothDaemonPDU& aPDU);
nsresult
PackPDU(BluetoothSocketType aIn, BluetoothDaemonPDU& aPDU);
nsresult
PackPDU(BluetoothSspPairingVariant aIn, BluetoothDaemonPDU& aPDU);
nsresult
PackPDU(BluetoothScanMode aIn, BluetoothDaemonPDU& aPDU);
/* |PackConversion| is a helper for packing converted values. Pass
* an instance of this structure to |PackPDU| to convert a value from
* the input type to the output type and and write it to the PDU.
*/
template<typename Tin, typename Tout>
struct PackConversion {
PackConversion(const Tin& aIn)
: mIn(aIn)
{ }
const Tin& mIn;
};
template<typename Tin, typename Tout>
inline nsresult
PackPDU(const PackConversion<Tin, Tout>& aIn, BluetoothDaemonPDU& aPDU)
{
Tout out;
nsresult rv = Convert(aIn.mIn, out);
if (NS_FAILED(rv)) {
return rv;
}
return PackPDU(out, aPDU);
}
/* |PackArray| is a helper for packing arrays. Pass an instance
* of this structure as the first argument to |PackPDU| to pack
* an array. The array's maximum default length is 255 elements.
*/
template <typename T>
struct PackArray
{
PackArray(const T* aData, size_t aLength)
: mData(aData)
, mLength(aLength)
{ }
const T* mData;
size_t mLength;
};
/* This implementation of |PackPDU| packs the length of an array
* and the elements of the array one-by-one.
*/
template<typename T>
inline nsresult
PackPDU(const PackArray<T>& aIn, BluetoothDaemonPDU& aPDU)
{
for (size_t i = 0; i < aIn.mLength; ++i) {
nsresult rv = PackPDU(aIn.mData[i], aPDU);
if (NS_FAILED(rv)) {
return rv;
}
}
return NS_OK;
}
template<>
inline nsresult
PackPDU<uint8_t>(const PackArray<uint8_t>& aIn, BluetoothDaemonPDU& aPDU)
{
/* Write raw bytes in one pass */
return aPDU.Write(aIn.mData, aIn.mLength);
}
template <typename T1, typename T2>
inline nsresult
PackPDU(const T1& aIn1, const T2& aIn2, BluetoothDaemonPDU& aPDU)
{
nsresult rv = PackPDU(aIn1, aPDU);
if (NS_FAILED(rv)) {
return rv;
}
return PackPDU(aIn2, aPDU);
}
template <typename T1, typename T2, typename T3>
inline nsresult
PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
BluetoothDaemonPDU& aPDU)
{
nsresult rv = PackPDU(aIn1, aPDU);
if (NS_FAILED(rv)) {
return rv;
}
rv = PackPDU(aIn2, aPDU);
if (NS_FAILED(rv)) {
return rv;
}
return PackPDU(aIn3, aPDU);
}
template <typename T1, typename T2, typename T3, typename T4>
inline nsresult
PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4,
BluetoothDaemonPDU& aPDU)
{
nsresult rv = PackPDU(aIn1, aPDU);
if (NS_FAILED(rv)) {
return rv;
}
rv = PackPDU(aIn2, aPDU);
if (NS_FAILED(rv)) {
return rv;
}
rv = PackPDU(aIn3, aPDU);
if (NS_FAILED(rv)) {
return rv;
}
return PackPDU(aIn4, aPDU);
}
template <typename T1, typename T2, typename T3,
typename T4, typename T5>
inline nsresult
PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
const T4& aIn4, const T5& aIn5,
BluetoothDaemonPDU& aPDU)
{
nsresult rv = PackPDU(aIn1, aPDU);
if (NS_FAILED(rv)) {
return rv;
}
rv = PackPDU(aIn2, aPDU);
if (NS_FAILED(rv)) {
return rv;
}
rv = PackPDU(aIn3, aPDU);
if (NS_FAILED(rv)) {
return rv;
}
rv = PackPDU(aIn4, aPDU);
if (NS_FAILED(rv)) {
return rv;
}
return PackPDU(aIn5, aPDU);
}
//
// Unpacking
//
inline nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, int8_t& aOut)
{
return aPDU.Read(aOut);
}
inline nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, uint8_t& aOut)
{
return aPDU.Read(aOut);
}
inline nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, uint16_t& aOut)
{
return aPDU.Read(aOut);
}
inline nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, int32_t& aOut)
{
return aPDU.Read(aOut);
}
inline nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, uint32_t& aOut)
{
return aPDU.Read(aOut);
}
nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, bool& aOut);
nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAclState& aOut);
inline nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAddress& aOut)
{
return aPDU.Read(aOut.mAddr, sizeof(aOut.mAddr));
}
nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothBondState& aOut);
inline nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothDaemonPDUHeader& aOut)
{
nsresult rv = UnpackPDU(aPDU, aOut.mService);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(aPDU, aOut.mOpcode);
if (NS_FAILED(rv)) {
return rv;
}
return UnpackPDU(aPDU, aOut.mLength);
}
nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothDeviceType& aOut);
nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothRemoteInfo& aOut);
inline nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothRemoteName& aOut)
{
return aPDU.Read(aOut.mName, sizeof(aOut.mName));
}
nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothProperty& aOut);
nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothPropertyType& aOut);
nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothScanMode& aOut);
nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothServiceRecord& aOut);
nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothSspPairingVariant& aOut);
nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothStatus& aOut);
inline nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothUuid& aOut)
{
return aPDU.Read(aOut.mUuid, sizeof(aOut.mUuid));
}
/* |UnpackConversion| is a helper for convering unpacked values. Pass
* an instance of this structure to |UnpackPDU| to read a value from
* the PDU in the input type and convert it to the output type.
*/
template<typename Tin, typename Tout>
struct UnpackConversion {
UnpackConversion(Tout& aOut)
: mOut(aOut)
{ }
Tout& mOut;
};
template<typename Tin, typename Tout>
inline nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackConversion<Tin, Tout>& aOut)
{
Tin in;
nsresult rv = UnpackPDU(aPDU, in);
if (NS_FAILED(rv)) {
return rv;
}
return Convert(in, aOut.mOut);
}
/* |UnpackArray| is a helper for unpacking arrays. Pass an instance
* of this structure as the second argument to |UnpackPDU| to unpack
* an array.
*/
template <typename T>
struct UnpackArray
{
UnpackArray(T* aData, size_t aLength)
: mData(aData)
, mLength(aLength)
{ }
UnpackArray(nsAutoArrayPtr<T>& aData, size_t aLength)
: mData(nullptr)
, mLength(aLength)
{
aData = new T[mLength];
mData = aData.get();
}
UnpackArray(nsAutoArrayPtr<T>& aData, size_t aSize, size_t aElemSize)
: mData(nullptr)
, mLength(aSize / aElemSize)
{
aData = new T[mLength];
mData = aData.get();
}
T* mData;
size_t mLength;
};
template<typename T>
inline nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackArray<T>& aOut)
{
for (size_t i = 0; i < aOut.mLength; ++i) {
nsresult rv = UnpackPDU(aPDU, aOut.mData[i]);
if (NS_FAILED(rv)) {
return rv;
}
}
return NS_OK;
}
template<>
inline nsresult
UnpackPDU<uint8_t>(BluetoothDaemonPDU& aPDU, const UnpackArray<uint8_t>& aOut)
{
/* Read raw bytes in one pass */
return aPDU.Read(aOut.mData, aOut.mLength);
}
template<typename T>
inline nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, nsTArray<T>& aOut)
{
for (typename nsTArray<T>::size_type i = 0; i < aOut.Length(); ++i) {
nsresult rv = UnpackPDU(aPDU, aOut[i]);
if (NS_FAILED(rv)) {
return rv;
}
}
return NS_OK;
}
//
// Init operators
//
// |PDUInitOP| provides functionality for init operators that unpack PDUs.
class PDUInitOp
{
protected:
PDUInitOp(BluetoothDaemonPDU& aPDU)
: mPDU(&aPDU)
{ }
BluetoothDaemonPDU& GetPDU() const
{
return *mPDU; // cannot be nullptr
}
void WarnAboutTrailingData() const
{
size_t size = mPDU->GetSize();
if (MOZ_LIKELY(!size)) {
return;
}
uint8_t service, opcode;
uint16_t payloadSize;
mPDU->GetHeader(service, opcode, payloadSize);
BT_LOGR("Unpacked PDU of type (%x,%x) still contains %zu Bytes of data.",
service, opcode, size);
}
private:
BluetoothDaemonPDU* mPDU; // Hold pointer to allow for constant instances
};
// |UnpackPDUInitOp| is a general-purpose init operator for all variants
// of |BluetoothResultRunnable| and |BluetoothNotificationRunnable|. The
// call operators of |UnpackPDUInitOp| unpack a PDU into the supplied
// arguments.
class UnpackPDUInitOp MOZ_FINAL : private PDUInitOp
{
public:
UnpackPDUInitOp(BluetoothDaemonPDU& aPDU)
: PDUInitOp(aPDU)
{ }
nsresult operator () () const
{
WarnAboutTrailingData();
return NS_OK;
}
template<typename T1>
nsresult operator () (T1& aArg1) const
{
nsresult rv = UnpackPDU(GetPDU(), aArg1);
if (NS_FAILED(rv)) {
return rv;
}
WarnAboutTrailingData();
return NS_OK;
}
template<typename T1, typename T2>
nsresult operator () (T1& aArg1, T2& aArg2) const
{
BluetoothDaemonPDU& pdu = GetPDU();
nsresult rv = UnpackPDU(pdu, aArg1);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg2);
if (NS_FAILED(rv)) {
return rv;
}
WarnAboutTrailingData();
return NS_OK;
}
template<typename T1, typename T2, typename T3>
nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3) const
{
BluetoothDaemonPDU& pdu = GetPDU();
nsresult rv = UnpackPDU(pdu, aArg1);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg2);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg3);
if (NS_FAILED(rv)) {
return rv;
}
WarnAboutTrailingData();
return NS_OK;
}
template<typename T1, typename T2, typename T3, typename T4>
nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4) const
{
BluetoothDaemonPDU& pdu = GetPDU();
nsresult rv = UnpackPDU(pdu, aArg1);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg2);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg3);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg4);
if (NS_FAILED(rv)) {
return rv;
}
WarnAboutTrailingData();
return NS_OK;
}
template<typename T1, typename T2, typename T3, typename T4, typename T5>
nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4,
T5& aArg5) const
{
BluetoothDaemonPDU& pdu = GetPDU();
nsresult rv = UnpackPDU(pdu, aArg1);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg2);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg3);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg4);
if (NS_FAILED(rv)) {
return rv;
}
rv = UnpackPDU(pdu, aArg5);
if (NS_FAILED(rv)) {
return rv;
}
WarnAboutTrailingData();
return NS_OK;
}
};
END_BLUETOOTH_NAMESPACE
#endif