mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 05:45:37 +00:00
Bug 1073548: Implement Bluetooth Core module for Bluetooth daemon, r=shawnjohnjr
This patch adds support for the Bluetooth daemon's Core module. It provides the basic Bluetooth functionality, such as searching and pairing with devices, and accessing device properties.
This commit is contained in:
parent
1225ee6a20
commit
1bd066721a
@ -6,12 +6,168 @@
|
||||
|
||||
#include "BluetoothDaemonHelpers.h"
|
||||
|
||||
#define MAX_UUID_SIZE 16
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
//
|
||||
// Conversion
|
||||
//
|
||||
|
||||
nsresult
|
||||
Convert(bool aIn, uint8_t& aOut)
|
||||
{
|
||||
static const bool sValue[] = {
|
||||
CONVERT(false, 0x00),
|
||||
CONVERT(true, 0x01)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sValue))) {
|
||||
aOut = 0;
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sValue[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(bool aIn, BluetoothScanMode& aOut)
|
||||
{
|
||||
static const BluetoothScanMode sScanMode[] = {
|
||||
CONVERT(false, SCAN_MODE_CONNECTABLE),
|
||||
CONVERT(true, SCAN_MODE_CONNECTABLE_DISCOVERABLE)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sScanMode))) {
|
||||
aOut = SCAN_MODE_NONE; // silences compiler warning
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sScanMode[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, bool& aOut)
|
||||
{
|
||||
static const bool sBool[] = {
|
||||
CONVERT(0x00, false),
|
||||
CONVERT(0x01, true)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sBool))) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sBool[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothAclState& aOut)
|
||||
{
|
||||
static const BluetoothAclState sAclState[] = {
|
||||
CONVERT(0x00, ACL_STATE_CONNECTED),
|
||||
CONVERT(0x01, ACL_STATE_DISCONNECTED),
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sAclState))) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sAclState[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothBondState& aOut)
|
||||
{
|
||||
static const BluetoothBondState sBondState[] = {
|
||||
CONVERT(0x00, BOND_STATE_NONE),
|
||||
CONVERT(0x01, BOND_STATE_BONDING),
|
||||
CONVERT(0x02, BOND_STATE_BONDED)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sBondState))) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sBondState[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(int32_t aIn, BluetoothDeviceType& aOut)
|
||||
{
|
||||
static const BluetoothDeviceType sDeviceType[] = {
|
||||
CONVERT(0x00, static_cast<BluetoothDeviceType>(0)), // invalid, required by gcc
|
||||
CONVERT(0x01, DEVICE_TYPE_BREDR),
|
||||
CONVERT(0x02, DEVICE_TYPE_BLE),
|
||||
CONVERT(0x03, DEVICE_TYPE_DUAL)
|
||||
};
|
||||
if (NS_WARN_IF(!aIn) ||
|
||||
NS_WARN_IF(static_cast<size_t>(aIn) >= MOZ_ARRAY_LENGTH(sDeviceType))) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sDeviceType[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothPropertyType& aOut)
|
||||
{
|
||||
static const BluetoothPropertyType sPropertyType[] = {
|
||||
CONVERT(0x00, static_cast<BluetoothPropertyType>(0)), // invalid, required by gcc
|
||||
CONVERT(0x01, PROPERTY_BDNAME),
|
||||
CONVERT(0x02, PROPERTY_BDADDR),
|
||||
CONVERT(0x03, PROPERTY_UUIDS),
|
||||
CONVERT(0x04, PROPERTY_CLASS_OF_DEVICE),
|
||||
CONVERT(0x05, PROPERTY_TYPE_OF_DEVICE),
|
||||
CONVERT(0x06, PROPERTY_SERVICE_RECORD),
|
||||
CONVERT(0x07, PROPERTY_ADAPTER_SCAN_MODE),
|
||||
CONVERT(0x08, PROPERTY_ADAPTER_BONDED_DEVICES),
|
||||
CONVERT(0x09, PROPERTY_ADAPTER_DISCOVERY_TIMEOUT),
|
||||
CONVERT(0x0a, PROPERTY_REMOTE_FRIENDLY_NAME),
|
||||
CONVERT(0x0b, PROPERTY_REMOTE_RSSI),
|
||||
CONVERT(0x0c, PROPERTY_REMOTE_VERSION_INFO)
|
||||
};
|
||||
if (aIn == 0xff) {
|
||||
/* This case is handled separately to not populate
|
||||
* |sPropertyType| with empty entries. */
|
||||
aOut = PROPERTY_REMOTE_DEVICE_TIMESTAMP;
|
||||
return NS_OK;
|
||||
}
|
||||
if (NS_WARN_IF(!aIn) ||
|
||||
NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sPropertyType))) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sPropertyType[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(int32_t aIn, BluetoothScanMode& aOut)
|
||||
{
|
||||
static const BluetoothScanMode sScanMode[] = {
|
||||
CONVERT(0x00, SCAN_MODE_NONE),
|
||||
CONVERT(0x01, SCAN_MODE_CONNECTABLE),
|
||||
CONVERT(0x02, SCAN_MODE_CONNECTABLE_DISCOVERABLE)
|
||||
};
|
||||
if (NS_WARN_IF(aIn < 0) ||
|
||||
NS_WARN_IF(static_cast<size_t>(aIn) >= MOZ_ARRAY_LENGTH(sScanMode))) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sScanMode[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothSspPairingVariant& aOut)
|
||||
{
|
||||
static const BluetoothSspPairingVariant sSspPairingVariant[] = {
|
||||
CONVERT(0x00, SSP_VARIANT_PASSKEY_CONFIRMATION),
|
||||
CONVERT(0x01, SSP_VARIANT_PASSKEY_ENTRY),
|
||||
CONVERT(0x02, SSP_VARIANT_CONSENT),
|
||||
CONVERT(0x03, SSP_VARIANT_PASSKEY_NOTIFICATION)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sSspPairingVariant))) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sSspPairingVariant[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothStatus& aOut)
|
||||
{
|
||||
@ -35,10 +191,274 @@ Convert(uint8_t aIn, BluetoothStatus& aOut)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint32_t aIn, int& aOut)
|
||||
{
|
||||
aOut = static_cast<int>(aIn);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(size_t aIn, uint16_t& aOut)
|
||||
{
|
||||
if (NS_WARN_IF(aIn >= (1ul << 16))) {
|
||||
aOut = 0; // silences compiler warning
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = static_cast<uint16_t>(aIn);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(const nsAString& aIn, BluetoothAddress& aOut)
|
||||
{
|
||||
NS_ConvertUTF16toUTF8 bdAddressUTF8(aIn);
|
||||
const char* str = bdAddressUTF8.get();
|
||||
|
||||
for (size_t i = 0; i < MOZ_ARRAY_LENGTH(aOut.mAddr); ++i, ++str) {
|
||||
aOut.mAddr[i] =
|
||||
static_cast<uint8_t>(strtoul(str, const_cast<char**>(&str), 16));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(const nsAString& aIn, BluetoothPinCode& aOut)
|
||||
{
|
||||
if (NS_WARN_IF(aIn.Length() > MOZ_ARRAY_LENGTH(aOut.mPinCode))) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
NS_ConvertUTF16toUTF8 pinCodeUTF8(aIn);
|
||||
const char* str = pinCodeUTF8.get();
|
||||
|
||||
nsAString::size_type i;
|
||||
|
||||
// Fill pin into aOut
|
||||
for (i = 0; i < aIn.Length(); ++i, ++str) {
|
||||
aOut.mPinCode[i] = static_cast<uint8_t>(*str);
|
||||
}
|
||||
|
||||
// Clear remaining bytes in aOut
|
||||
size_t ntrailing = (MOZ_ARRAY_LENGTH(aOut.mPinCode) - aIn.Length()) *
|
||||
sizeof(aOut.mPinCode[0]);
|
||||
memset(aOut.mPinCode + aIn.Length(), 0, ntrailing);
|
||||
|
||||
aOut.mLength = aIn.Length();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(const nsAString& aIn, BluetoothPropertyType& aOut)
|
||||
{
|
||||
if (aIn.EqualsLiteral("Name")) {
|
||||
aOut = PROPERTY_BDNAME;
|
||||
} else if (aIn.EqualsLiteral("Discoverable")) {
|
||||
aOut = PROPERTY_ADAPTER_SCAN_MODE;
|
||||
} else if (aIn.EqualsLiteral("DiscoverableTimeout")) {
|
||||
aOut = PROPERTY_ADAPTER_DISCOVERY_TIMEOUT;
|
||||
} else {
|
||||
BT_LOGR("Invalid property name: %s", NS_ConvertUTF16toUTF8(aIn).get());
|
||||
aOut = static_cast<BluetoothPropertyType>(0); // silences compiler warning
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(const nsAString& aIn, BluetoothSspPairingVariant& aOut)
|
||||
{
|
||||
if (aIn.EqualsLiteral("PasskeyConfirmation")) {
|
||||
aOut = SSP_VARIANT_PASSKEY_CONFIRMATION;
|
||||
} else if (aIn.EqualsLiteral("PasskeyEntry")) {
|
||||
aOut = SSP_VARIANT_PASSKEY_ENTRY;
|
||||
} else if (aIn.EqualsLiteral("Consent")) {
|
||||
aOut = SSP_VARIANT_CONSENT;
|
||||
} else if (aIn.EqualsLiteral("PasskeyNotification")) {
|
||||
aOut = SSP_VARIANT_PASSKEY_NOTIFICATION;
|
||||
} else {
|
||||
BT_LOGR("Invalid SSP variant name: %s", NS_ConvertUTF16toUTF8(aIn).get());
|
||||
aOut = SSP_VARIANT_PASSKEY_CONFIRMATION; // silences compiler warning
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothAclState aIn, bool& aOut)
|
||||
{
|
||||
static const bool sBool[] = {
|
||||
CONVERT(ACL_STATE_CONNECTED, true),
|
||||
CONVERT(ACL_STATE_DISCONNECTED, false)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sBool))) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sBool[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(const BluetoothAddress& aIn, nsAString& aOut)
|
||||
{
|
||||
char str[BLUETOOTH_ADDRESS_LENGTH + 1];
|
||||
|
||||
int res = snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
static_cast<int>(aIn.mAddr[0]),
|
||||
static_cast<int>(aIn.mAddr[1]),
|
||||
static_cast<int>(aIn.mAddr[2]),
|
||||
static_cast<int>(aIn.mAddr[3]),
|
||||
static_cast<int>(aIn.mAddr[4]),
|
||||
static_cast<int>(aIn.mAddr[5]));
|
||||
if (NS_WARN_IF(res < 0)) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
} else if (NS_WARN_IF((size_t)res >= sizeof(str))) {
|
||||
return NS_ERROR_OUT_OF_MEMORY; /* string buffer too small */
|
||||
}
|
||||
|
||||
aOut = NS_ConvertUTF8toUTF16(str);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothPropertyType aIn, uint8_t& aOut)
|
||||
{
|
||||
static const uint8_t sPropertyType[] = {
|
||||
CONVERT(PROPERTY_UNKNOWN, 0x00),
|
||||
CONVERT(PROPERTY_BDNAME, 0x01),
|
||||
CONVERT(PROPERTY_BDADDR, 0x02),
|
||||
CONVERT(PROPERTY_UUIDS, 0x03),
|
||||
CONVERT(PROPERTY_CLASS_OF_DEVICE, 0x04),
|
||||
CONVERT(PROPERTY_TYPE_OF_DEVICE, 0x05),
|
||||
CONVERT(PROPERTY_SERVICE_RECORD, 0x06),
|
||||
CONVERT(PROPERTY_ADAPTER_SCAN_MODE, 0x07),
|
||||
CONVERT(PROPERTY_ADAPTER_BONDED_DEVICES, 0x08),
|
||||
CONVERT(PROPERTY_ADAPTER_DISCOVERY_TIMEOUT, 0x09),
|
||||
CONVERT(PROPERTY_REMOTE_FRIENDLY_NAME, 0x0a),
|
||||
CONVERT(PROPERTY_REMOTE_RSSI, 0x0b),
|
||||
CONVERT(PROPERTY_REMOTE_VERSION_INFO, 0x0c),
|
||||
CONVERT(PROPERTY_REMOTE_DEVICE_TIMESTAMP, 0xff)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sPropertyType))) {
|
||||
aOut = 0x00; // silences compiler warning
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sPropertyType[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(const BluetoothRemoteName& aIn, nsAString& aOut)
|
||||
{
|
||||
// We construct an nsCString here because the string
|
||||
// returned from the PDU is not 0-terminated.
|
||||
aOut = NS_ConvertUTF8toUTF16(
|
||||
nsCString(reinterpret_cast<const char*>(aIn.mName), sizeof(aIn.mName)));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothScanMode aIn, int32_t& aOut)
|
||||
{
|
||||
static const int32_t sScanMode[] = {
|
||||
CONVERT(SCAN_MODE_NONE, 0x00),
|
||||
CONVERT(SCAN_MODE_CONNECTABLE, 0x01),
|
||||
CONVERT(SCAN_MODE_CONNECTABLE_DISCOVERABLE, 0x02)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sScanMode))) {
|
||||
aOut = 0; // silences compiler warning
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sScanMode[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothSspPairingVariant aIn, uint8_t& aOut)
|
||||
{
|
||||
static const uint8_t sValue[] = {
|
||||
CONVERT(SSP_VARIANT_PASSKEY_CONFIRMATION, 0x00),
|
||||
CONVERT(SSP_VARIANT_PASSKEY_ENTRY, 0x01),
|
||||
CONVERT(SSP_VARIANT_CONSENT, 0x02),
|
||||
CONVERT(SSP_VARIANT_PASSKEY_NOTIFICATION, 0x03)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sValue))) {
|
||||
aOut = 0; // silences compiler warning
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sValue[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothSspPairingVariant aIn, nsAString& aOut)
|
||||
{
|
||||
static const char* const sString[] = {
|
||||
CONVERT(SSP_VARIANT_PASSKEY_CONFIRMATION, "PasskeyConfirmation"),
|
||||
CONVERT(SSP_VARIANT_PASSKEY_ENTRY, "PasskeyEntry"),
|
||||
CONVERT(SSP_VARIANT_CONSENT, "Consent"),
|
||||
CONVERT(SSP_VARIANT_PASSKEY_NOTIFICATION, "PasskeyNotification")
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sString))) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = NS_ConvertUTF8toUTF16(sString[aIn]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* |ConvertArray| is a helper for converting arrays. Pass an
|
||||
* instance of this structure as the first argument to |Convert|
|
||||
* to convert an array. The output type has to support the array
|
||||
* subscript operator.
|
||||
*/
|
||||
template <typename T>
|
||||
struct ConvertArray
|
||||
{
|
||||
ConvertArray(const T* aData, unsigned long aLength)
|
||||
: mData(aData)
|
||||
, mLength(aLength)
|
||||
{ }
|
||||
|
||||
const T* mData;
|
||||
unsigned long mLength;
|
||||
};
|
||||
|
||||
/* This implementation of |Convert| converts the elements of an
|
||||
* array one-by-one. The result data structures must have enough
|
||||
* memory allocated.
|
||||
*/
|
||||
template<typename Tin, typename Tout>
|
||||
inline nsresult
|
||||
Convert(const ConvertArray<Tin>& aIn, Tout& aOut)
|
||||
{
|
||||
for (unsigned long i = 0; i < aIn.mLength; ++i) {
|
||||
nsresult rv = Convert(aIn.mData[i], aOut[i]);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// Packing
|
||||
//
|
||||
|
||||
nsresult
|
||||
PackPDU(bool aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
return PackPDU(PackConversion<bool, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothAddress& aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
return PackPDU(PackArray<uint8_t>(aIn.mAddr, sizeof(aIn.mAddr)), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothConfigurationParameter& aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
@ -52,10 +472,235 @@ PackPDU(const BluetoothDaemonPDUHeader& aIn, BluetoothDaemonPDU& aPDU)
|
||||
return PackPDU(aIn.mService, aIn.mOpcode, aIn.mLength, aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothNamedValue& aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
nsresult rv = PackPDU(
|
||||
PackConversion<nsString, BluetoothPropertyType>(aIn.name()), aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (aIn.value().type() == BluetoothValue::Tuint32_t) {
|
||||
// Set discoverable timeout
|
||||
rv = PackPDU(static_cast<uint16_t>(sizeof(uint32_t)),
|
||||
aIn.value().get_uint32_t(), aPDU);
|
||||
} else if (aIn.value().type() == BluetoothValue::TnsString) {
|
||||
// Set name
|
||||
const nsCString value =
|
||||
NS_ConvertUTF16toUTF8(aIn.value().get_nsString());
|
||||
|
||||
rv = PackPDU(PackConversion<size_t, uint16_t>(value.Length()),
|
||||
PackArray<uint8_t>(
|
||||
reinterpret_cast<const uint8_t*>(value.get()),
|
||||
value.Length()),
|
||||
aPDU);
|
||||
} else if (aIn.value().type() == BluetoothValue::Tbool) {
|
||||
// Set scan mode
|
||||
bool value = aIn.value().get_bool();
|
||||
|
||||
rv = PackPDU(static_cast<uint16_t>(sizeof(int32_t)),
|
||||
PackConversion<bool, BluetoothScanMode>(value), aPDU);
|
||||
} else {
|
||||
BT_LOGR("Invalid property value type");
|
||||
rv = NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothPinCode& aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
return PackPDU(aIn.mLength,
|
||||
PackArray<uint8_t>(aIn.mPinCode, sizeof(aIn.mPinCode)),
|
||||
aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothPropertyType aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
return PackPDU(PackConversion<BluetoothPropertyType, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothSspPairingVariant aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
return PackPDU(PackConversion<BluetoothSspPairingVariant, uint8_t>(aIn),
|
||||
aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothScanMode aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
return PackPDU(PackConversion<BluetoothScanMode, int32_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
//
|
||||
// Unpacking
|
||||
//
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, bool& aOut)
|
||||
{
|
||||
return UnpackPDU(aPDU, UnpackConversion<uint8_t, bool>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAclState& aOut)
|
||||
{
|
||||
return UnpackPDU(aPDU, UnpackConversion<uint8_t, BluetoothAclState>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothBondState& aOut)
|
||||
{
|
||||
return UnpackPDU(aPDU, UnpackConversion<uint8_t, BluetoothBondState>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothDeviceType& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<int32_t, BluetoothDeviceType>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothProperty& aOut)
|
||||
{
|
||||
nsresult rv = UnpackPDU(aPDU, aOut.mType);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
uint16_t len;
|
||||
rv = UnpackPDU(aPDU, len);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
switch (aOut.mType) {
|
||||
case PROPERTY_BDNAME:
|
||||
/* fall through */
|
||||
case PROPERTY_REMOTE_FRIENDLY_NAME: {
|
||||
const uint8_t* data = aPDU.Consume(len);
|
||||
if (NS_WARN_IF(!data)) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
// We construct an nsCString here because the string
|
||||
// returned from the PDU is not 0-terminated.
|
||||
aOut.mString = NS_ConvertUTF8toUTF16(
|
||||
nsCString(reinterpret_cast<const char*>(data), len));
|
||||
}
|
||||
break;
|
||||
case PROPERTY_BDADDR:
|
||||
rv = UnpackPDU<BluetoothAddress>(
|
||||
aPDU, UnpackConversion<BluetoothAddress, nsAString>(aOut.mString));
|
||||
break;
|
||||
case PROPERTY_UUIDS: {
|
||||
size_t numUuids = len / MAX_UUID_SIZE;
|
||||
aOut.mUuidArray.SetLength(numUuids);
|
||||
rv = UnpackPDU(aPDU, aOut.mUuidArray);
|
||||
}
|
||||
break;
|
||||
case PROPERTY_CLASS_OF_DEVICE:
|
||||
/* fall through */
|
||||
case PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
|
||||
rv = UnpackPDU(aPDU, aOut.mUint32);
|
||||
break;
|
||||
case PROPERTY_TYPE_OF_DEVICE:
|
||||
rv = UnpackPDU(aPDU, aOut.mDeviceType);
|
||||
break;
|
||||
case PROPERTY_SERVICE_RECORD:
|
||||
rv = UnpackPDU(aPDU, aOut.mServiceRecord);
|
||||
break;
|
||||
case PROPERTY_ADAPTER_SCAN_MODE:
|
||||
rv = UnpackPDU(aPDU, aOut.mScanMode);
|
||||
break;
|
||||
case PROPERTY_ADAPTER_BONDED_DEVICES: {
|
||||
/* unpack addresses */
|
||||
size_t numAddresses = len / BLUETOOTH_ADDRESS_BYTES;
|
||||
nsAutoArrayPtr<BluetoothAddress> addresses;
|
||||
UnpackArray<BluetoothAddress> addressArray(addresses, numAddresses);
|
||||
rv = UnpackPDU(aPDU, addressArray);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
/* convert addresses to strings */
|
||||
aOut.mStringArray.SetLength(numAddresses);
|
||||
ConvertArray<BluetoothAddress> convertArray(addressArray.mData,
|
||||
addressArray.mLength);
|
||||
rv = Convert(convertArray, aOut.mStringArray);
|
||||
}
|
||||
break;
|
||||
case PROPERTY_REMOTE_RSSI: {
|
||||
int8_t rssi;
|
||||
rv = UnpackPDU(aPDU, rssi);
|
||||
aOut.mInt32 = rssi;
|
||||
}
|
||||
break;
|
||||
case PROPERTY_REMOTE_VERSION_INFO:
|
||||
rv = UnpackPDU(aPDU, aOut.mRemoteInfo);
|
||||
break;
|
||||
case PROPERTY_REMOTE_DEVICE_TIMESTAMP:
|
||||
/* nothing to do */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothPropertyType& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothPropertyType>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothRemoteInfo& aOut)
|
||||
{
|
||||
nsresult rv = UnpackPDU(aPDU,
|
||||
UnpackConversion<uint32_t, int>(aOut.mVerMajor));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(aPDU, UnpackConversion<uint32_t, int>(aOut.mVerMinor));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
return UnpackPDU(aPDU, UnpackConversion<uint32_t, int>(aOut.mManufacturer));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothScanMode& aOut)
|
||||
{
|
||||
return UnpackPDU(aPDU, UnpackConversion<int32_t, BluetoothScanMode>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothServiceRecord& aOut)
|
||||
{
|
||||
/* unpack UUID */
|
||||
nsresult rv = UnpackPDU(aPDU, aOut.mUuid);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
/* unpack channel */
|
||||
rv = UnpackPDU(aPDU, aOut.mChannel);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
/* unpack name */
|
||||
return aPDU.Read(aOut.mName, sizeof(aOut.mName));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothSspPairingVariant& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothSspPairingVariant>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothStatus& aOut)
|
||||
{
|
||||
|
@ -9,23 +9,47 @@
|
||||
|
||||
#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 CONVERT(in_, out_) \
|
||||
#define INIT_ARRAY_AT(in_, out_) \
|
||||
[in_] = out_
|
||||
#else
|
||||
/* otherwise init array element by position */
|
||||
#define CONVERT(in_, out_) \
|
||||
#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;
|
||||
@ -50,6 +74,15 @@ struct BluetoothDaemonPDUHeader {
|
||||
uint16_t mLength;
|
||||
};
|
||||
|
||||
struct BluetoothPinCode {
|
||||
uint8_t mPinCode[16];
|
||||
uint8_t mLength;
|
||||
};
|
||||
|
||||
struct BluetoothRemoteName {
|
||||
uint8_t mName[249];
|
||||
};
|
||||
|
||||
//
|
||||
// Conversion
|
||||
//
|
||||
@ -60,13 +93,82 @@ struct BluetoothDaemonPDUHeader {
|
||||
// packing and unpacking.
|
||||
//
|
||||
|
||||
nsresult
|
||||
Convert(bool aIn, uint8_t& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(bool aIn, BluetoothScanMode& 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, 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(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)
|
||||
{
|
||||
@ -79,12 +181,68 @@ 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(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.
|
||||
@ -117,6 +275,14 @@ PackPDU(const PackArray<T>& aIn, BluetoothDaemonPDU& aPDU)
|
||||
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)
|
||||
@ -168,6 +334,12 @@ PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4,
|
||||
// Unpacking
|
||||
//
|
||||
|
||||
inline nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, int8_t& aOut)
|
||||
{
|
||||
return aPDU.Read(aOut);
|
||||
}
|
||||
|
||||
inline nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, uint8_t& aOut)
|
||||
{
|
||||
@ -180,6 +352,33 @@ 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)
|
||||
{
|
||||
@ -194,9 +393,42 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothDaemonPDUHeader& aOut)
|
||||
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.
|
||||
@ -222,6 +454,72 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackConversion<Tin, Tout>& aOut)
|
||||
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;
|
||||
}
|
||||
|
||||
template<typename T1, uint8_t Service, uint8_t Opcode>
|
||||
inline nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, T1& aArg1)
|
||||
@ -240,6 +538,25 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, T1& aArg1, T2& aArg2)
|
||||
return UnpackPDU(aPDU, aArg2);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline nsresult
|
||||
UnpackPDU<int, nsAutoArrayPtr<BluetoothProperty>, 0x01, 0x84>(
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
int& aArg1, nsAutoArrayPtr<BluetoothProperty>& aArg2)
|
||||
{
|
||||
/* Read number of properties */
|
||||
uint8_t numProperties;
|
||||
nsresult rv = UnpackPDU(aPDU, numProperties);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
aArg1 = numProperties;
|
||||
|
||||
/* Read properties array */
|
||||
UnpackArray<BluetoothProperty> properties(aArg2, aArg1);
|
||||
return UnpackPDU(aPDU, properties);
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3,
|
||||
uint8_t Service, uint8_t Opcode>
|
||||
inline nsresult
|
||||
@ -256,6 +573,120 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, T1& aArg1, T2& aArg2, T3& aArg3)
|
||||
return UnpackPDU(aPDU, aArg3);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline nsresult
|
||||
UnpackPDU<BluetoothStatus, int, nsAutoArrayPtr<BluetoothProperty>, 0x01, 0x82>(
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothStatus& aArg1, int& aArg2, nsAutoArrayPtr<BluetoothProperty>& aArg3)
|
||||
{
|
||||
/* Read status */
|
||||
nsresult rv = UnpackPDU(aPDU, aArg1);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Read number of properties */
|
||||
uint8_t numProperties;
|
||||
rv = UnpackPDU(aPDU, numProperties);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
aArg2 = numProperties;
|
||||
|
||||
/* Read properties array */
|
||||
UnpackArray<BluetoothProperty> properties(aArg3, aArg2);
|
||||
return UnpackPDU(aPDU, properties);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline nsresult
|
||||
UnpackPDU<nsString, nsString, uint32_t, 0x01, 0x86>(
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
nsString& aArg1, nsString& aArg2, uint32_t& aArg3)
|
||||
{
|
||||
/* Read remote address */
|
||||
nsresult rv = UnpackPDU(
|
||||
aPDU, UnpackConversion<BluetoothAddress, nsAString>(aArg1));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Read remote name */
|
||||
rv = UnpackPDU(aPDU, UnpackConversion<BluetoothRemoteName, nsAString>(aArg2));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Read CoD */
|
||||
return UnpackPDU(aPDU, aArg3);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline nsresult
|
||||
UnpackPDU<BluetoothStatus, nsString, BluetoothBondState, 0x01, 0x88>(
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothStatus& aArg1, nsString& aArg2, BluetoothBondState& aArg3)
|
||||
{
|
||||
/* Read status */
|
||||
nsresult rv = UnpackPDU(aPDU, aArg1);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Read remote address */
|
||||
rv = UnpackPDU(aPDU, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Read bond state */
|
||||
return UnpackPDU(aPDU, aArg3);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline nsresult
|
||||
UnpackPDU<BluetoothStatus, nsString, bool, 0x01, 0x89>(
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothStatus& aArg1, nsString& aArg2, bool& aArg3)
|
||||
{
|
||||
/* Read status */
|
||||
nsresult rv = UnpackPDU(aPDU, aArg1);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Read remote address */
|
||||
rv = UnpackPDU(aPDU, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Read ACL state */
|
||||
return UnpackPDU(aPDU, UnpackConversion<BluetoothAclState, bool>(aArg3));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline nsresult
|
||||
UnpackPDU<uint16_t, nsAutoArrayPtr<uint8_t>, uint8_t, 0x01, 0x8a>(
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
uint16_t& aArg1, nsAutoArrayPtr<uint8_t>& aArg2, uint8_t& aArg3)
|
||||
{
|
||||
/* Read opcode */
|
||||
nsresult rv = UnpackPDU(aPDU, aArg1);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Read length */
|
||||
rv = UnpackPDU(aPDU, aArg3);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Read data */
|
||||
return UnpackPDU(aPDU, UnpackArray<uint8_t>(aArg2, aArg3));
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4,
|
||||
uint8_t Service, uint8_t Opcode>
|
||||
inline nsresult
|
||||
@ -276,6 +707,39 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4)
|
||||
return UnpackPDU(aPDU, aArg4);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline nsresult
|
||||
UnpackPDU<BluetoothStatus, nsString, int, nsAutoArrayPtr<BluetoothProperty>,
|
||||
0x01, 0x83>(
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothStatus& aArg1, nsString& aArg2, int& aArg3,
|
||||
nsAutoArrayPtr<BluetoothProperty>& aArg4)
|
||||
{
|
||||
/* Read status */
|
||||
nsresult rv = UnpackPDU(aPDU, aArg1);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Read address */
|
||||
rv = UnpackPDU(aPDU, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Read number of properties */
|
||||
uint8_t numProperties;
|
||||
rv = UnpackPDU(aPDU, numProperties);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
aArg3 = numProperties;
|
||||
|
||||
/* Read properties array */
|
||||
UnpackArray<BluetoothProperty> properties(aArg4, aArg3);
|
||||
return UnpackPDU(aPDU, properties);
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
uint8_t Service, uint8_t Opcode>
|
||||
inline nsresult
|
||||
@ -301,6 +765,43 @@ UnpackPDU(BluetoothDaemonPDU& aPDU,
|
||||
return UnpackPDU(aPDU, aArg5);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline nsresult
|
||||
UnpackPDU<nsString, nsString, uint32_t, nsString, uint32_t, 0x01, 0x87>(
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
nsString& aArg1, nsString& aArg2, uint32_t& aArg3,
|
||||
nsString& aArg4, uint32_t& aArg5)
|
||||
{
|
||||
/* Read remote address */
|
||||
nsresult rv = UnpackPDU(
|
||||
aPDU, UnpackConversion<BluetoothAddress, nsAString>(aArg1));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Read remote name */
|
||||
rv = UnpackPDU(aPDU, UnpackConversion<BluetoothRemoteName, nsAString>(aArg2));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Read CoD */
|
||||
rv = UnpackPDU(aPDU, aArg3);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Read pairing variant */
|
||||
rv = UnpackPDU(
|
||||
aPDU, UnpackConversion<BluetoothSspPairingVariant, nsAString>(aArg4));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Read passkey */
|
||||
return UnpackPDU(aPDU, aArg5);
|
||||
}
|
||||
|
||||
//
|
||||
// Result handling
|
||||
//
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user