author | Bruce Sun <brsun@mozilla.com> |
Mon, 22 Feb 2016 11:41:07 +0800 | |
changeset 285025 | 807683706e4ed63cd348a3c748bcc028cb4c3d3e |
parent 285017 | 241581e67d7535834591ae9ec031e5f0f37f6210 |
child 285026 | 7d2bc215980907d791c942ae3b8783a97b060d34 |
push id | 30022 |
push user | cbook@mozilla.com |
push date | Tue, 23 Feb 2016 15:52:25 +0000 |
treeherder | mozilla-central@25697d503815 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | tzimmermann |
bugs | 1222956 |
milestone | 47.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/bluetooth/common/BluetoothCommon.cpp +++ b/dom/bluetooth/common/BluetoothCommon.cpp @@ -20,9 +20,32 @@ const BluetoothAddress BluetoothAddress: 0x00, 0x00, 0x00); const BluetoothAddress BluetoothAddress::ALL(0xff, 0xff, 0xff, 0xff, 0xff, 0xff); const BluetoothAddress BluetoothAddress::LOCAL(0x00, 0x00, 0x00, 0xff, 0xff, 0xff); +// +// |BluetoothUuid| +// + +const BluetoothUuid BluetoothUuid::ZERO(0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00); + +/* + * [Bluetooth Specification Version 4.2, Volume 3, Part B, Section 2.5.1] + * + * To reduce the burden of storing and transferring 128-bit UUID values, a + * range of UUID values has been pre-allocated for assignment to often-used, + * registered purposes. The first UUID in this pre-allocated range is known as + * the Bluetooth Base UUID and has the value 00000000-0000-1000-8000- + * 00805F9B34FB, from the Bluetooth Assigned Numbers document. + */ +const BluetoothUuid BluetoothUuid::BASE(0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x80, + 0x5f, 0x9b, 0x34, 0xfb); + END_BLUETOOTH_NAMESPACE
--- a/dom/bluetooth/common/BluetoothCommon.h +++ b/dom/bluetooth/common/BluetoothCommon.h @@ -545,21 +545,23 @@ enum BluetoothServiceClass { HID = 0x1124, PBAP_PCE = 0x112e, PBAP_PSE = 0x112f, MAP_MAS = 0x1132, MAP_MNS = 0x1133 }; struct BluetoothUuid { + static const BluetoothUuid ZERO; + static const BluetoothUuid BASE; - uint8_t mUuid[16]; + uint8_t mUuid[16]; // store 128-bit UUID value in big-endian order BluetoothUuid() - : BluetoothUuid(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + : BluetoothUuid(ZERO) { } MOZ_IMPLICIT BluetoothUuid(const BluetoothUuid&) = default; BluetoothUuid(uint8_t aUuid0, uint8_t aUuid1, uint8_t aUuid2, uint8_t aUuid3, uint8_t aUuid4, uint8_t aUuid5, uint8_t aUuid6, uint8_t aUuid7, @@ -603,73 +605,69 @@ struct BluetoothUuid { BluetoothUuid& operator=(const BluetoothUuid& aRhs) = default; /** * |Clear| assigns an invalid value (i.e., zero) to the UUID. */ void Clear() { - operator=(BluetoothUuid()); + operator=(ZERO); } /** * |IsCleared| returns true if the UUID contains a value of * zero. */ bool IsCleared() const { - return operator==(BluetoothUuid()); + return operator==(ZERO); } bool operator==(const BluetoothUuid& aRhs) const { return std::equal(aRhs.mUuid, aRhs.mUuid + MOZ_ARRAY_LENGTH(aRhs.mUuid), mUuid); } bool operator!=(const BluetoothUuid& aRhs) const { return !operator==(aRhs); } + /* This less-than operator is used for sorted insertion of nsTArray */ + bool operator<(const BluetoothUuid& aUuid) const + { + return memcmp(mUuid, aUuid.mUuid, sizeof(aUuid.mUuid)) < 0; + }; + /* * Getter-setter methods for short UUIDS. The first 4 bytes in the * UUID are represented by the short notation UUID32, and bytes 3 * and 4 (indices 2 and 3) are represented by UUID16. The rest of - * the UUID is filled with the SDP base UUID. + * the UUID is filled with the Bluetooth Base UUID. * * Below are helpers for accessing these values. */ void SetUuid32(uint32_t aUuid32) { + operator=(BASE); BigEndian::writeUint32(&mUuid[0], aUuid32); - mUuid[4] = 0x00; - mUuid[5] = 0x00; - mUuid[6] = 0x10; - mUuid[7] = 0x00; - mUuid[8] = 0x80; - mUuid[9] = 0x00; - mUuid[10] = 0x00; - mUuid[11] = 0x80; - mUuid[12] = 0x5f; - mUuid[13] = 0x9b; - mUuid[14] = 0x34; - mUuid[15] = 0xfb; } uint32_t GetUuid32() const { return BigEndian::readUint32(&mUuid[0]); } void SetUuid16(uint16_t aUuid16) { - SetUuid32(aUuid16); // MSB is 0x0000 + operator=(BASE); + BigEndian::writeUint16(&mUuid[2], aUuid16); } uint16_t GetUuid16() const { return BigEndian::readUint16(&mUuid[2]); } };
--- a/dom/bluetooth/common/BluetoothUtils.cpp +++ b/dom/bluetooth/common/BluetoothUtils.cpp @@ -273,16 +273,96 @@ StringToUuid(const nsAString& aString, B memcpy(&aUuid.mUuid[8], &uuid3, sizeof(uint16_t)); memcpy(&aUuid.mUuid[10], &uuid4, sizeof(uint32_t)); memcpy(&aUuid.mUuid[14], &uuid5, sizeof(uint16_t)); return NS_OK; } nsresult +BytesToUuid(const nsTArray<uint8_t>& aArray, + nsTArray<uint8_t>::index_type aOffset, + BluetoothUuidType aType, + BluetoothProfileEndian aEndian, + BluetoothUuid& aUuid) +{ + MOZ_ASSERT(aType == UUID_16_BIT || + aType == UUID_32_BIT || + aType == UUID_128_BIT); + MOZ_ASSERT(aEndian == ENDIAN_BIG || aEndian == ENDIAN_LITTLE); + + size_t index = (aType == UUID_16_BIT) ? 2 : 0; + size_t length = 0; + + if (aType == UUID_16_BIT) { + length = sizeof(uint16_t); + } else if (aType == UUID_32_BIT) { + length = sizeof(uint32_t); + } else { + length = MOZ_ARRAY_LENGTH(aUuid.mUuid); + } + + if (aArray.Length() < aOffset + length) { + return NS_ERROR_ILLEGAL_VALUE; + } + + aUuid = BluetoothUuid::BASE; + + if (aEndian == ENDIAN_BIG) { + for (size_t i = 0; i < length; ++i) { + aUuid.mUuid[index + i] = aArray[aOffset + i]; + } + } else { + for (size_t i = 0; i < length; ++i) { + aUuid.mUuid[index + i] = aArray[aOffset + length - i - 1]; + } + } + + return NS_OK; +} + +nsresult +UuidToBytes(const BluetoothUuid& aUuid, + BluetoothUuidType aType, + BluetoothProfileEndian aEndian, + nsTArray<uint8_t>& aArray, + nsTArray<uint8_t>::index_type aOffset) +{ + MOZ_ASSERT(aType == UUID_16_BIT || + aType == UUID_32_BIT || + aType == UUID_128_BIT); + MOZ_ASSERT(aEndian == ENDIAN_BIG || aEndian == ENDIAN_LITTLE); + + size_t index = (aType == UUID_16_BIT) ? 2 : 0; + size_t length = 0; + + if (aType == UUID_16_BIT) { + length = sizeof(uint16_t); + } else if (aType == UUID_32_BIT) { + length = sizeof(uint32_t); + } else { + length = MOZ_ARRAY_LENGTH(aUuid.mUuid); + } + + aArray.SetCapacity(aOffset + length); + + if (aEndian == ENDIAN_BIG) { + for (size_t i = 0; i < length; ++i) { + aArray[aOffset + i] = aUuid.mUuid[index + i]; + } + } else { + for (size_t i = 0; i < length; ++i) { + aArray[aOffset + length - i - 1] = aUuid.mUuid[index + i]; + } + } + + return NS_OK; +} + +nsresult GenerateUuid(BluetoothUuid &aUuid) { nsresult rv; nsCOMPtr<nsIUUIDGenerator> uuidGenerator = do_GetService("@mozilla.org/uuid-generator;1", &rv); NS_ENSURE_SUCCESS(rv, rv); nsID uuid;
--- a/dom/bluetooth/common/BluetoothUtils.h +++ b/dom/bluetooth/common/BluetoothUtils.h @@ -19,16 +19,40 @@ class BluetoothAdvertisingData; } BEGIN_BLUETOOTH_NAMESPACE class BluetoothNamedValue; class BluetoothReplyRunnable; class BluetoothValue; +/* + * Each profile has its distinct endianness for multi-byte values + */ +enum BluetoothProfileEndian { + ENDIAN_BIG, + ENDIAN_LITTLE, + ENDIAN_SDP = ENDIAN_BIG, // SDP uses big endian + ENDIAN_GAP = ENDIAN_LITTLE, // GAP uses little endian + ENDIAN_GATT = ENDIAN_LITTLE, // GATT uses little endian +}; + +/* + * A UUID is a 128-bit value. To reduce the burden of storing and transferring + * 128-bit UUID values, a range of UUID values has been pre-allocated for + * assignment to often-used, registered purposes. UUID values in the + * pre-allocated range have aliases that are represented as 16-bit or 32-bit + * values. + */ +enum BluetoothUuidType { + UUID_16_BIT, + UUID_32_BIT, + UUID_128_BIT, +}; + // // Address/String conversion // void AddressToString(const BluetoothAddress& aAddress, nsAString& aString); nsresult @@ -100,16 +124,46 @@ UuidToString(const BluetoothUuid& aUuid, * * Note: This utility function is used by gecko internal only to convert uuid * string created by gecko back to BluetoothUuid representation. */ nsresult StringToUuid(const nsAString& aString, BluetoothUuid& aUuid); /** + * Convert continuous bytes from nsTArray to BluetoothUuid object. + * @param aArray [in] The byte array. + * @param aOffset [in] The offset of continuous bytes of UUID value. + * @param aType [in] The type of UUID. + * @param aEndian [in] The endianness of UUID value. + * @param aUuid [out] The BluetoothUuid object. + */ +nsresult +BytesToUuid(const nsTArray<uint8_t>& aArray, + nsTArray<uint8_t>::index_type aOffset, + BluetoothUuidType aType, + BluetoothProfileEndian aEndian, + BluetoothUuid& aUuid); + +/** + * Convert BluetoothUuid object to nsTArray with continuous bytes. + * @param aUuid [in] The BluetoothUuid object. + * @param aType [in] The type of UUID. + * @param aEndian [in] The endianness of UUID value. + * @param aArray [out] The byte array. + * @param aOffset [in] The offset of continuous bytes of UUID value. + */ +nsresult +UuidToBytes(const BluetoothUuid& aUuid, + BluetoothUuidType aType, + BluetoothProfileEndian aEndian, + nsTArray<uint8_t>& aArray, + nsTArray<uint8_t>::index_type aOffset); + +/** * Generate a random uuid. * * @param aUuid [out] The generated uuid. */ nsresult GenerateUuid(BluetoothUuid &aUuid); /**
--- a/dom/bluetooth/common/webapi/BluetoothAdapter.cpp +++ b/dom/bluetooth/common/webapi/BluetoothAdapter.cpp @@ -126,17 +126,17 @@ public: private: RefPtr<BluetoothAdapter> mAdapter; }; class StartLeScanTask final : public BluetoothReplyRunnable { public: StartLeScanTask(BluetoothAdapter* aAdapter, Promise* aPromise, - const nsTArray<nsString>& aServiceUuids) + const nsTArray<BluetoothUuid>& aServiceUuids) : BluetoothReplyRunnable(nullptr, aPromise) , mAdapter(aAdapter) , mServiceUuids(aServiceUuids) { MOZ_ASSERT(aPromise); MOZ_ASSERT(aAdapter); } @@ -145,25 +145,25 @@ public: { aValue.setUndefined(); AutoJSAPI jsapi; NS_ENSURE_TRUE(jsapi.Init(mAdapter->GetParentObject()), false); JSContext* cx = jsapi.cx(); const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value(); - NS_ENSURE_TRUE(v.type() == BluetoothValue::TnsString, false); + NS_ENSURE_TRUE(v.type() == BluetoothValue::TBluetoothUuid, false); /** * Create a new discovery handle and wrap it to return. Each * discovery handle is one-time-use only. */ RefPtr<BluetoothDiscoveryHandle> discoveryHandle = BluetoothDiscoveryHandle::Create(mAdapter->GetParentObject(), - mServiceUuids, v.get_nsString()); + mServiceUuids, v.get_BluetoothUuid()); if (!ToJSValue(cx, discoveryHandle, aValue)) { JS_ClearPendingException(cx); return false; } // Append a BluetoothDiscoveryHandle to LeScan handle array. mAdapter->AppendLeScanHandle(discoveryHandle); @@ -175,32 +175,32 @@ public: ReleaseMembers() override { BluetoothReplyRunnable::ReleaseMembers(); mAdapter = nullptr; } private: RefPtr<BluetoothAdapter> mAdapter; - nsTArray<nsString> mServiceUuids; + nsTArray<BluetoothUuid> mServiceUuids; }; class StopLeScanTask final : public BluetoothReplyRunnable { public: StopLeScanTask(BluetoothAdapter* aAdapter, Promise* aPromise, - const nsAString& aScanUuid) + const BluetoothUuid& aScanUuid) : BluetoothReplyRunnable(nullptr, aPromise) , mAdapter(aAdapter) , mScanUuid(aScanUuid) { MOZ_ASSERT(aPromise); MOZ_ASSERT(aAdapter); - MOZ_ASSERT(!aScanUuid.IsEmpty()); + MOZ_ASSERT(!aScanUuid.IsCleared()); } protected: virtual bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) override { mAdapter->RemoveLeScanHandle(mScanUuid); aValue.setUndefined(); @@ -211,17 +211,17 @@ protected: ReleaseMembers() override { BluetoothReplyRunnable::ReleaseMembers(); mAdapter = nullptr; } private: RefPtr<BluetoothAdapter> mAdapter; - nsString mScanUuid; + BluetoothUuid mScanUuid; }; class GetDevicesTask : public BluetoothReplyRunnable { public: GetDevicesTask(BluetoothAdapter* aAdapterPtr, nsIDOMDOMRequest* aReq) : BluetoothReplyRunnable(aReq) , mAdapterPtr(aAdapterPtr) @@ -361,26 +361,22 @@ BluetoothAdapter::Cleanup() { UnregisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_ADAPTER), this); // Stop ongoing LE scans and clear the LeScan handle array if (!mLeScanHandleArray.IsEmpty()) { BluetoothService* bs = BluetoothService::Get(); NS_ENSURE_TRUE_VOID(bs); - nsString uuidStr; - for (uint32_t i = 0; i < mLeScanHandleArray.Length(); ++i) { - mLeScanHandleArray[i]->GetLeScanUuid(uuidStr); + for (size_t i = 0; i < mLeScanHandleArray.Length(); ++i) { + BluetoothUuid uuid; + mLeScanHandleArray[i]->GetLeScanUuid(uuid); RefPtr<BluetoothVoidReplyRunnable> results = new BluetoothVoidReplyRunnable(nullptr); - - BluetoothUuid uuid; - if (NS_SUCCEEDED(StringToUuid(uuidStr, uuid))) { - bs->StopLeScanInternal(uuid, results); - } + bs->StopLeScanInternal(uuid, results); } mLeScanHandleArray.Clear(); } } BluetoothGattServer* BluetoothAdapter::GetGattServer() { @@ -601,22 +597,22 @@ BluetoothAdapter::SetDiscoveryHandleInUs void BluetoothAdapter::AppendLeScanHandle( BluetoothDiscoveryHandle* aDiscoveryHandle) { mLeScanHandleArray.AppendElement(aDiscoveryHandle); } void -BluetoothAdapter::RemoveLeScanHandle(const nsAString& aScanUuid) +BluetoothAdapter::RemoveLeScanHandle(const BluetoothUuid& aScanUuid) { - nsString uuid; - for (uint32_t i = 0; i < mLeScanHandleArray.Length(); ++i) { + for (size_t i = 0; i < mLeScanHandleArray.Length(); ++i) { + BluetoothUuid uuid; mLeScanHandleArray[i]->GetLeScanUuid(uuid); - if (aScanUuid.Equals(uuid)) { + if (aScanUuid == uuid) { mLeScanHandleArray.RemoveElementAt(i); break; } } } already_AddRefed<Promise> BluetoothAdapter::StartDiscovery(ErrorResult& aRv) @@ -713,17 +709,17 @@ BluetoothAdapter::StartLeScan(const nsTA BT_ENSURE_TRUE_REJECT(mState == BluetoothAdapterState::Enabled, promise, NS_ERROR_DOM_INVALID_STATE_ERR); BluetoothService* bs = BluetoothService::Get(); BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE); RefPtr<BluetoothReplyRunnable> result = - new StartLeScanTask(this, promise, aServiceUuids); + new StartLeScanTask(this, promise, serviceUuids); bs->StartLeScanInternal(serviceUuids, result); return promise.forget(); } already_AddRefed<Promise> BluetoothAdapter::StopLeScan(BluetoothDiscoveryHandle& aDiscoveryHandle, ErrorResult& aRv) @@ -744,26 +740,21 @@ BluetoothAdapter::StopLeScan(BluetoothDi BluetoothService* bs = BluetoothService::Get(); BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE); // Reject the request if there's no ongoing LE Scan using this handle. BT_ENSURE_TRUE_REJECT(mLeScanHandleArray.Contains(&aDiscoveryHandle), promise, NS_ERROR_DOM_BLUETOOTH_DONE); - nsString scanUuidStr; - aDiscoveryHandle.GetLeScanUuid(scanUuidStr); - BluetoothUuid scanUuid; - BT_ENSURE_TRUE_REJECT(NS_SUCCEEDED(StringToUuid(scanUuidStr, scanUuid)), - promise, - NS_ERROR_DOM_OPERATION_ERR); + aDiscoveryHandle.GetLeScanUuid(scanUuid); RefPtr<BluetoothReplyRunnable> result = - new StopLeScanTask(this, promise, scanUuidStr); + new StopLeScanTask(this, promise, scanUuid); bs->StopLeScanInternal(scanUuid, result); return promise.forget(); } already_AddRefed<Promise> BluetoothAdapter::SetName(const nsAString& aName, ErrorResult& aRv) {
--- a/dom/bluetooth/common/webapi/BluetoothAdapter.h +++ b/dom/bluetooth/common/webapi/BluetoothAdapter.h @@ -215,17 +215,17 @@ public: void AppendLeScanHandle(BluetoothDiscoveryHandle* aDiscoveryHandle); /** * Remove the BluetoothDiscoverHandle with the given UUID from LeScan handle * array. * * @param aScanUuid [in] The UUID of the LE scan task. */ - void RemoveLeScanHandle(const nsAString& aScanUuid); + void RemoveLeScanHandle(const BluetoothUuid& aScanUuid); private: BluetoothAdapter(nsPIDOMWindowInner* aOwner, const BluetoothValue& aValue); ~BluetoothAdapter(); /** * Unregister signal handler and clean up LE scan handles. */
--- a/dom/bluetooth/common/webapi/BluetoothDevice.cpp +++ b/dom/bluetooth/common/webapi/BluetoothDevice.cpp @@ -113,16 +113,27 @@ BluetoothDevice::BluetoothDevice(nsPIDOM } BluetoothDevice::~BluetoothDevice() { UnregisterBluetoothSignalHandler(mAddress, this); } void +BluetoothDevice::GetUuids(nsTArray<nsString>& aUuids) const +{ + aUuids.Clear(); + for (size_t i = 0; i < mUuids.Length(); ++i) { + nsAutoString uuidStr; + UuidToString(mUuids[i], uuidStr); + aUuids.AppendElement(uuidStr); + } +} + +void BluetoothDevice::DisconnectFromOwner() { DOMEventTargetHelper::DisconnectFromOwner(); UnregisterBluetoothSignalHandler(mAddress, this); } BluetoothDeviceType BluetoothDevice::ConvertUint32ToDeviceType(const uint32_t aValue) @@ -153,29 +164,25 @@ BluetoothDevice::SetPropertyByValue(cons } else { AddressToString(value.get_BluetoothAddress(), mAddress); } } else if (name.EqualsLiteral("Cod")) { mCod->Update(value.get_uint32_t()); } else if (name.EqualsLiteral("Paired")) { mPaired = value.get_bool(); } else if (name.EqualsLiteral("UUIDs")) { - // While converting to strings, we sort the received UUIDs and remove - // any duplicates. + // We sort the received UUIDs and remove any duplicates. const nsTArray<BluetoothUuid>& uuids = value.get_ArrayOfBluetoothUuid(); nsTArray<nsString> uuidStrs; + mUuids.Clear(); for (uint32_t index = 0; index < uuids.Length(); ++index) { - nsAutoString uuidStr; - UuidToString(uuids[index], uuidStr); - - if (!uuidStrs.Contains(uuidStr)) { // filter out duplicate UUIDs - uuidStrs.InsertElementSorted(uuidStr); + if (!mUuids.Contains(uuids[index])) { // filter out duplicate UUIDs + mUuids.InsertElementSorted(uuids[index]); } } - mUuids = Move(uuidStrs); BluetoothDeviceBinding::ClearCachedUuidsValue(this); } else if (name.EqualsLiteral("Type")) { mType = ConvertUint32ToDeviceType(value.get_uint32_t()); } else if (name.EqualsLiteral("GattAdv")) { MOZ_ASSERT(value.type() == BluetoothValue::TArrayOfuint8_t); nsTArray<uint8_t> advData; advData = value.get_ArrayOfuint8_t(); UpdatePropertiesFromAdvData(advData); @@ -270,33 +277,24 @@ BluetoothDevice::IsDeviceAttributeChange return !mName.Equals(remoteNameStr); } case BluetoothDeviceAttribute::Paired: MOZ_ASSERT(aValue.type() == BluetoothValue::Tbool); return mPaired != aValue.get_bool(); case BluetoothDeviceAttribute::Uuids: { MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothUuid); const auto& uuids = aValue.get_ArrayOfBluetoothUuid(); - - nsTArray<nsString> uuidStrs; - - // Construct a sorted uuid set + nsTArray<BluetoothUuid> sortedUuids; + // Construct a sorted UUID set for (size_t index = 0; index < uuids.Length(); ++index) { - nsAutoString uuidStr; - UuidToString(uuids[index], uuidStr); - - if (!uuidStrs.Contains(uuidStr)) { // filter out duplicate uuids - uuidStrs.InsertElementSorted(uuidStr); + if (!sortedUuids.Contains(uuids[index])) { // filter out duplicate uuids + sortedUuids.InsertElementSorted(uuids[index]); } } - - // We assume the received uuids array is sorted without duplicate items. - // If it's not, we require additional processing before comparing it - // directly. - return mUuids != uuidStrs; + return mUuids != sortedUuids; } default: BT_WARNING("Type %d is not handled", uint32_t(aType)); return false; } } void @@ -381,68 +379,54 @@ BluetoothDevice::UpdatePropertiesFromAdv // Length of the data field which is composed by AD type (1 byte) and // AD data (dataFieldLength -1 bytes) int dataLength = dataFieldLength - 1; if (offset + dataLength >= aAdvData.Length()) { break; } // Update UUIDs and name of BluetoothDevice. - int type = aAdvData[offset++]; + BluetoothGapDataType type = + static_cast<BluetoothGapDataType>(aAdvData[offset++]); switch (type) { case GAP_INCOMPLETE_UUID16: case GAP_COMPLETE_UUID16: case GAP_INCOMPLETE_UUID32: case GAP_COMPLETE_UUID32: case GAP_INCOMPLETE_UUID128: case GAP_COMPLETE_UUID128: { mUuids.Clear(); - // The length of uint16_t UUID array - uint8_t len = 0; - if (GAP_INCOMPLETE_UUID16 && GAP_COMPLETE_UUID16) { - len = 1; - } else if (GAP_INCOMPLETE_UUID32 && GAP_COMPLETE_UUID32) { - len = 2; - } else { - len = 8; - } - uint16_t uuid[len]; - while (dataLength > 0) { - // Read (len * 2) bytes from the data buffer and compose a 16-bits - // UUID array. - for (uint8_t i = 0; i < len; ++i) { - uuid[i] = aAdvData[offset++]; - uuid[i] += (aAdvData[offset++] << 8); - dataLength -= 2; - } - - char uuidStr[37]; // one more char to be null-terminated + BluetoothUuid uuid; + size_t length = 0; if (type == GAP_INCOMPLETE_UUID16 || type == GAP_COMPLETE_UUID16) { - // Convert 16-bits UUID into string. - snprintf(uuidStr, sizeof(uuidStr), - "0000%04x-0000-1000-8000-00805f9b34fb", uuid[0]); + length = 2; + if (NS_FAILED(BytesToUuid(aAdvData, offset, UUID_16_BIT, + ENDIAN_GAP, uuid))) { + break; + } } else if (type == GAP_INCOMPLETE_UUID32 || type == GAP_COMPLETE_UUID32) { - // Convert 32-bits UUID into string. - snprintf(uuidStr, sizeof(uuidStr), - "%04x%04x-0000-1000-8000-00805f9b34fb", uuid[1], uuid[0]); + length = 4; + if (NS_FAILED(BytesToUuid(aAdvData, offset, UUID_32_BIT, + ENDIAN_GAP, uuid))) { + break; + } } else if (type == GAP_INCOMPLETE_UUID128 || type == GAP_COMPLETE_UUID128) { - // Convert 128-bits UUID into string. - snprintf(uuidStr, sizeof(uuidStr), - "%04x%04x-%04x-%04x-%04x-%04x%04x%04x", - uuid[7], uuid[6], uuid[5], uuid[4], - uuid[3], uuid[2], uuid[1], uuid[0]); + length = 16; + if (NS_FAILED(BytesToUuid(aAdvData, offset, UUID_128_BIT, + ENDIAN_GAP, uuid))) { + break; + } } - nsString uuidNsString; - uuidNsString.AssignLiteral(uuidStr); - - mUuids.AppendElement(uuidNsString); + mUuids.AppendElement(uuid); + offset += length; + dataLength -= length; } BluetoothDeviceBinding::ClearCachedUuidsValue(this); break; } case GAP_SHORTENED_NAME: if (!mName.IsEmpty()) break; case GAP_COMPLETE_NAME: {
--- a/dom/bluetooth/common/webapi/BluetoothDevice.h +++ b/dom/bluetooth/common/webapi/BluetoothDevice.h @@ -54,20 +54,17 @@ public: aName = mName; } bool Paired() const { return mPaired; } - void GetUuids(nsTArray<nsString>& aUuids) const - { - aUuids = mUuids; - } + void GetUuids(nsTArray<nsString>& aUuids) const; BluetoothDeviceType Type() const { return mType; } BluetoothGatt* GetGatt(); @@ -92,16 +89,21 @@ public: { return GetOwner(); } virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override; virtual void DisconnectFromOwner() override; + void GetUuids(nsTArray<BluetoothUuid>& aUuids) const + { + aUuids = mUuids; + } + private: BluetoothDevice(nsPIDOMWindowInner* aOwner, const BluetoothValue& aValue); ~BluetoothDevice(); /** * Set device properties according to properties array * * @param aValue [in] Properties array to set with @@ -183,17 +185,17 @@ private: /** * Whether this device is paired or not. */ bool mPaired; /** * Cached UUID list of services which this device provides. */ - nsTArray<nsString> mUuids; + nsTArray<BluetoothUuid> mUuids; /** * Type of this device. Can be unknown/classic/le/dual. */ BluetoothDeviceType mType; /** * GATT client object to interact with the remote device.
--- a/dom/bluetooth/common/webapi/BluetoothDiscoveryHandle.cpp +++ b/dom/bluetooth/common/webapi/BluetoothDiscoveryHandle.cpp @@ -24,18 +24,18 @@ NS_IMPL_RELEASE_INHERITED(BluetoothDisco BluetoothDiscoveryHandle::BluetoothDiscoveryHandle(nsPIDOMWindowInner* aWindow) : DOMEventTargetHelper(aWindow) { MOZ_ASSERT(aWindow); } BluetoothDiscoveryHandle::BluetoothDiscoveryHandle( nsPIDOMWindowInner* aWindow, - const nsTArray<nsString>& aServiceUuids, - const nsAString& aLeScanUuid) + const nsTArray<BluetoothUuid>& aServiceUuids, + const BluetoothUuid& aLeScanUuid) : DOMEventTargetHelper(aWindow) , mLeScanUuid(aLeScanUuid) , mServiceUuids(aServiceUuids) { MOZ_ASSERT(aWindow); } BluetoothDiscoveryHandle::~BluetoothDiscoveryHandle() @@ -52,18 +52,18 @@ BluetoothDiscoveryHandle::Create(nsPIDOM RefPtr<BluetoothDiscoveryHandle> handle = new BluetoothDiscoveryHandle(aWindow); return handle.forget(); } already_AddRefed<BluetoothDiscoveryHandle> BluetoothDiscoveryHandle::Create( nsPIDOMWindowInner* aWindow, - const nsTArray<nsString>& aServiceUuids, - const nsAString& aLeScanUuid) + const nsTArray<BluetoothUuid>& aServiceUuids, + const BluetoothUuid& aLeScanUuid) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aWindow); RefPtr<BluetoothDiscoveryHandle> handle = new BluetoothDiscoveryHandle(aWindow, aServiceUuids, aLeScanUuid); return handle.forget(); } @@ -84,17 +84,17 @@ BluetoothDiscoveryHandle::DispatchDevice } void BluetoothDiscoveryHandle::DispatchLeDeviceEvent(BluetoothDevice* aLeDevice, int32_t aRssi, nsTArray<uint8_t>& aScanRecord) { MOZ_ASSERT(aLeDevice); - nsTArray<nsString> remoteUuids; + nsTArray<BluetoothUuid> remoteUuids; aLeDevice->GetUuids(remoteUuids); bool hasUuidsFilter = !mServiceUuids.IsEmpty(); bool noAdvertisingUuid = remoteUuids.IsEmpty(); // If an LE device doesn't advertise its service UUIDs, it can't possibly pass // the UUIDs filter. if (hasUuidsFilter && noAdvertisingUuid) { return;
--- a/dom/bluetooth/common/webapi/BluetoothDiscoveryHandle.h +++ b/dom/bluetooth/common/webapi/BluetoothDiscoveryHandle.h @@ -23,57 +23,57 @@ class BluetoothDiscoveryHandle final : p public: NS_DECL_ISUPPORTS_INHERITED static already_AddRefed<BluetoothDiscoveryHandle> Create(nsPIDOMWindowInner* aWindow); static already_AddRefed<BluetoothDiscoveryHandle> Create(nsPIDOMWindowInner* aWindow, - const nsTArray<nsString>& aServiceUuids, - const nsAString& aLeScanUuid); + const nsTArray<BluetoothUuid>& aServiceUuids, + const BluetoothUuid& aLeScanUuid); void DispatchDeviceEvent(BluetoothDevice* aDevice); void DispatchLeDeviceEvent(BluetoothDevice* aLeDevice, int32_t aRssi, nsTArray<uint8_t>& aScanRecord); IMPL_EVENT_HANDLER(devicefound); - void GetLeScanUuid(nsString& aLeScanUuid) const + void GetLeScanUuid(BluetoothUuid& aLeScanUuid) const { aLeScanUuid = mLeScanUuid; } virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override; private: BluetoothDiscoveryHandle(nsPIDOMWindowInner* aWindow); BluetoothDiscoveryHandle(nsPIDOMWindowInner* aWindow, - const nsTArray<nsString>& aServiceUuids, - const nsAString& aLeScanUuid); + const nsTArray<BluetoothUuid>& aServiceUuids, + const BluetoothUuid& aLeScanUuid); ~BluetoothDiscoveryHandle(); /** * Random generated UUID of LE scan * * This UUID is used only when the handle is built for LE scan. * If BluetoothDiscoveryHandle is built for classic discovery, the value would * remain empty string during the entire life cycle. */ - nsString mLeScanUuid; + BluetoothUuid mLeScanUuid; /** - * A DOMString array of service UUIDs to discover / scan for. + * A BluetoothUuid array of service UUIDs to discover / scan for. * * This array is only used by LE scan. If BluetoothDiscoveryHandle is built * for classic discovery, the array should be empty. */ - nsTArray<nsString> mServiceUuids; + nsTArray<BluetoothUuid> mServiceUuids; }; END_BLUETOOTH_NAMESPACE #endif // mozilla_dom_bluetooth_BluetoothDiscoveryHandle_h