Skip to content
This repository was archived by the owner on Dec 20, 2023. It is now read-only.

Commit eec889d

Browse files
author
Jay Logue
committed
Fix for Issue #283: Invalid Weave BLE scan response from nRF5 Device Layer
-- Corrected a mistake in the encoding of the Weave BLE device identification block that gets sent as BLE service advertisement data by the nRF52840. The previous version of the code omitted two fields, which caused considerable heartburn for the Nest mobile application. -- Corrected another minor mistake in the encoding of the device identification block on the ESP32 which resulted in the wrong data block type being sent. This bug didn’t seem to bother the mobile application. -- Created a common data structure for encoding and decoding a Weave BLE device identification block and refactored the nRF5 and ESP32 code bases to use this structure.
1 parent 840f4c2 commit eec889d

File tree

8 files changed

+171
-40
lines changed

8 files changed

+171
-40
lines changed

src/adaptations/device-layer/ESP32/BLEManagerImpl.cpp

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include <Weave/DeviceLayer/internal/WeaveDeviceLayerInternal.h>
2626
#include <Weave/DeviceLayer/internal/BLEManager.h>
27+
#include <BleLayer/WeaveBleServiceData.h>
2728
#include <new>
2829

2930
#if WEAVE_DEVICE_CONFIG_ENABLE_WOBLE
@@ -45,17 +46,11 @@ namespace Internal {
4546

4647
namespace {
4748

48-
struct WeaveServiceData
49+
50+
struct ESP32WeaveServiceData
4951
{
5052
uint8_t ServiceUUID[2];
51-
uint8_t DataBlockLen;
52-
uint8_t DataBlockType;
53-
uint8_t DataBlockMajorVersion;
54-
uint8_t DataBlockMinorVersion;
55-
uint8_t DeviceVendorId[2];
56-
uint8_t DeviceProductId[2];
57-
uint8_t DeviceId[8];
58-
uint8_t PairingStatus;
53+
WeaveBLEDeviceIdentificationInfo DeviceIdInfo;
5954
};
6055

6156
const uint16_t WoBLEAppId = 0x235A;
@@ -562,7 +557,7 @@ WEAVE_ERROR BLEManagerImpl::ConfigureAdvertisingData(void)
562557
{
563558
WEAVE_ERROR err;
564559
esp_ble_adv_data_t advertData;
565-
WeaveServiceData weaveServiceData;
560+
ESP32WeaveServiceData weaveServiceData;
566561

567562
// If a custom device name has not been specified, generate a Nest-standard name based on the
568563
// bottom digits of the Weave device id.
@@ -604,16 +599,11 @@ WEAVE_ERROR BLEManagerImpl::ConfigureAdvertisingData(void)
604599
ExitNow();
605600
}
606601

607-
// Construct the Weave Service Data to be sent in the scan response packet.
602+
// Construct the Weave BLE Service Data to be sent in the scan response packet. On the ESP32,
603+
// the buffer given to esp_ble_gap_config_adv_data() must begin with the Weave BLE service UUID.
608604
memcpy(weaveServiceData.ServiceUUID, ShortUUID_WoBLEService, sizeof(weaveServiceData.ServiceUUID));
609-
weaveServiceData.DataBlockLen = 16;
610-
weaveServiceData.DataBlockType = 0x16;
611-
weaveServiceData.DataBlockMajorVersion = 0;
612-
weaveServiceData.DataBlockMinorVersion = 1;
613-
Encoding::LittleEndian::Put16(weaveServiceData.DeviceVendorId, (uint16_t)WEAVE_DEVICE_CONFIG_DEVICE_VENDOR_ID);
614-
Encoding::LittleEndian::Put16(weaveServiceData.DeviceProductId, (uint16_t)WEAVE_DEVICE_CONFIG_DEVICE_PRODUCT_ID);
615-
Encoding::LittleEndian::Put64(weaveServiceData.DeviceId, FabricState.LocalNodeId);
616-
weaveServiceData.PairingStatus = ConfigurationMgr().IsPairedToAccount() ? 1 : 0;
605+
err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(weaveServiceData.DeviceIdInfo);
606+
SuccessOrExit(err);
617607

618608
// Configure the contents of the scan response packet.
619609
memset(&advertData, 0, sizeof(advertData));

src/adaptations/device-layer/include/Weave/DeviceLayer/ConfigurationManager.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@
2828
#include <Weave/Profiles/device-description/DeviceDescription.h>
2929
#include <Weave/Profiles/network-provisioning/NetworkProvisioning.h>
3030

31+
namespace nl {
32+
namespace Ble {
33+
struct WeaveBLEDeviceIdentificationInfo;
34+
}
35+
}
36+
3137
namespace nl {
3238
namespace Weave {
3339
namespace DeviceLayer {
@@ -98,6 +104,8 @@ class ConfigurationManager
98104

99105
WEAVE_ERROR GetWiFiAPSSID(char * buf, size_t bufSize);
100106

107+
WEAVE_ERROR GetBLEDeviceIdentificationInfo(Ble::WeaveBLEDeviceIdentificationInfo & deviceIdInfo);
108+
101109
bool IsServiceProvisioned();
102110
bool IsPairedToAccount();
103111
bool IsMemberOfFabric();
@@ -362,6 +370,11 @@ inline WEAVE_ERROR ConfigurationManager::GetWiFiAPSSID(char * buf, size_t bufSiz
362370
return static_cast<ImplClass*>(this)->_GetWiFiAPSSID(buf, bufSize);
363371
}
364372

373+
inline WEAVE_ERROR ConfigurationManager::GetBLEDeviceIdentificationInfo(Ble::WeaveBLEDeviceIdentificationInfo & deviceIdInfo)
374+
{
375+
return static_cast<ImplClass*>(this)->_GetBLEDeviceIdentificationInfo(deviceIdInfo);
376+
}
377+
365378
inline bool ConfigurationManager::IsServiceProvisioned()
366379
{
367380
return static_cast<ImplClass*>(this)->_IsServiceProvisioned();

src/adaptations/device-layer/include/Weave/DeviceLayer/internal/GenericConfigurationManagerImpl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ class GenericConfigurationManagerImpl
8585
WEAVE_ERROR _GetDeviceDescriptorTLV(uint8_t * buf, size_t bufSize, size_t & encodedLen);
8686
WEAVE_ERROR _GetQRCodeString(char * buf, size_t bufSize);
8787
WEAVE_ERROR _GetWiFiAPSSID(char * buf, size_t bufSize);
88+
WEAVE_ERROR _GetBLEDeviceIdentificationInfo(Ble::WeaveBLEDeviceIdentificationInfo & deviceIdInfo);
8889
bool _IsServiceProvisioned();
8990
bool _IsMemberOfFabric();
9091
bool _IsPairedToAccount();

src/adaptations/device-layer/include/Weave/DeviceLayer/internal/GenericConfigurationManagerImpl.ipp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include <Weave/DeviceLayer/internal/WeaveDeviceLayerInternal.h>
2929
#include <Weave/DeviceLayer/internal/GenericConfigurationManagerImpl.h>
30+
#include <BleLayer/WeaveBleServiceData.h>
3031

3132

3233
namespace nl {
@@ -615,6 +616,32 @@ exit:
615616
return err;
616617
}
617618

619+
template<class ImplClass>
620+
WEAVE_ERROR GenericConfigurationManagerImpl<ImplClass>::_GetBLEDeviceIdentificationInfo(Ble::WeaveBLEDeviceIdentificationInfo & deviceIdInfo)
621+
{
622+
WEAVE_ERROR err;
623+
uint16_t id;
624+
625+
deviceIdInfo.Init();
626+
627+
err = Impl()->_GetVendorId(id);
628+
SuccessOrExit(err);
629+
deviceIdInfo.SetVendorId(id);
630+
631+
err = Impl()->_GetProductId(id);
632+
SuccessOrExit(err);
633+
deviceIdInfo.SetProductId(id);
634+
635+
deviceIdInfo.SetDeviceId(FabricState.LocalNodeId);
636+
637+
deviceIdInfo.PairingStatus = Impl()->_IsPairedToAccount()
638+
? Ble::WeaveBLEDeviceIdentificationInfo::kPairingStatus_Paired
639+
: Ble::WeaveBLEDeviceIdentificationInfo::kPairingStatus_Unpaired;
640+
641+
exit:
642+
return err;
643+
}
644+
618645
template<class ImplClass>
619646
bool GenericConfigurationManagerImpl<ImplClass>::_IsServiceProvisioned()
620647
{

src/adaptations/device-layer/nRF5/BLEManagerImpl.cpp

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include <Weave/DeviceLayer/internal/WeaveDeviceLayerInternal.h>
2626
#include <Weave/DeviceLayer/internal/BLEManager.h>
27+
#include <BleLayer/WeaveBleServiceData.h>
2728
#include <new>
2829

2930
#if WEAVE_DEVICE_CONFIG_ENABLE_WOBLE
@@ -49,16 +50,6 @@ namespace Internal {
4950

5051
namespace {
5152

52-
struct WeaveServiceData
53-
{
54-
uint8_t MajorVersion;
55-
uint8_t MinorVersion;
56-
uint8_t DeviceVendorId[2];
57-
uint8_t DeviceProductId[2];
58-
uint8_t DeviceId[8];
59-
uint8_t PairingStatus;
60-
};
61-
6253
const uint16_t UUID16_WoBLEService = 0xFEAF;
6354
const ble_uuid_t UUID_WoBLEService = { UUID16_WoBLEService, BLE_UUID_TYPE_BLE };
6455

@@ -519,7 +510,7 @@ WEAVE_ERROR BLEManagerImpl::EncodeAdvertisingData(ble_gap_adv_data_t & gapAdvDat
519510
WEAVE_ERROR err = WEAVE_NO_ERROR;
520511
ble_advdata_t advData;
521512
ble_advdata_service_data_t serviceData;
522-
WeaveServiceData weaveServiceData;
513+
WeaveBLEDeviceIdentificationInfo deviceIdInfo;
523514

524515
// Form the contents of the advertising packet.
525516
memset(&advData, 0, sizeof(advData));
@@ -533,20 +524,16 @@ WEAVE_ERROR BLEManagerImpl::EncodeAdvertisingData(ble_gap_adv_data_t & gapAdvDat
533524
err = ble_advdata_encode(&advData, mAdvDataBuf, &gapAdvData.adv_data.len);
534525
SuccessOrExit(err);
535526

536-
// Construct the Weave Service Data structure that will be sent in the scan response packet.
537-
memset(&weaveServiceData, 0, sizeof(weaveServiceData));
538-
weaveServiceData.MajorVersion = 0;
539-
weaveServiceData.MinorVersion = 1;
540-
Encoding::LittleEndian::Put16(weaveServiceData.DeviceVendorId, (uint16_t)WEAVE_DEVICE_CONFIG_DEVICE_VENDOR_ID);
541-
Encoding::LittleEndian::Put16(weaveServiceData.DeviceProductId, (uint16_t)WEAVE_DEVICE_CONFIG_DEVICE_PRODUCT_ID);
542-
Encoding::LittleEndian::Put64(weaveServiceData.DeviceId, FabricState.LocalNodeId);
543-
weaveServiceData.PairingStatus = ConfigurationMgr().IsPairedToAccount() ? 1 : 0;
527+
// Initialize the Weave BLE Device Identification Information block that will be sent as payload
528+
// within the BLE service advertisement data.
529+
err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(deviceIdInfo);
530+
SuccessOrExit(err);
544531

545532
// Form the contents of the scan response packet.
546533
memset(&serviceData, 0, sizeof(serviceData));
547534
serviceData.service_uuid = UUID16_WoBLEService;
548-
serviceData.data.size = sizeof(weaveServiceData);
549-
serviceData.data.p_data = (uint8_t *)&weaveServiceData;
535+
serviceData.data.size = sizeof(deviceIdInfo);
536+
serviceData.data.p_data = (uint8_t *)&deviceIdInfo;
550537
memset(&advData, 0, sizeof(advData));
551538
advData.name_type = BLE_ADVDATA_NO_NAME;
552539
advData.include_appearance = false;

src/ble/WeaveBleServiceData.h

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
*
3+
* Copyright (c) 2019 Google LLC.
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
/**
20+
* @file
21+
* Definitions for Weave BLE service advertisement data.
22+
*/
23+
24+
#ifndef WEAVE_BLE_SERVICE_DATA_H
25+
#define WEAVE_BLE_SERVICE_DATA_H
26+
27+
namespace nl {
28+
namespace Ble {
29+
30+
/**
31+
* Weave data block types that may appear with Weave BLE service advertisement data.
32+
*/
33+
enum WeaveBLEServiceDataType
34+
{
35+
kWeaveBLEServiceDataType_DeviceIdentificationInfo = 0x01,
36+
kWeaveBLEServiceDataType_TokenIdentificationInfo = 0x02,
37+
};
38+
39+
/**
40+
* Weave BLE Device Identification Information Block
41+
*
42+
* Defines the over-the-air encoded format of the device identification information block that appears
43+
* within Weave BLE service advertisement data.
44+
*/
45+
struct WeaveBLEDeviceIdentificationInfo
46+
{
47+
enum
48+
{
49+
kMajorVersion = 0,
50+
kMinorVersion = 1,
51+
};
52+
53+
enum
54+
{
55+
kPairingStatus_Unpaired = 0,
56+
kPairingStatus_Paired = 1,
57+
};
58+
59+
uint8_t BlockLen;
60+
uint8_t BlockType;
61+
uint8_t MajorVersion;
62+
uint8_t MinorVersion;
63+
uint8_t DeviceVendorId[2];
64+
uint8_t DeviceProductId[2];
65+
uint8_t DeviceId[8];
66+
uint8_t PairingStatus;
67+
68+
void Init()
69+
{
70+
memset(this, 0, sizeof(*this));
71+
BlockLen = sizeof(*this) - sizeof(BlockLen); // size of all fields EXCEPT BlockLen
72+
BlockType = kWeaveBLEServiceDataType_DeviceIdentificationInfo;
73+
MajorVersion = kMajorVersion;
74+
MinorVersion = kMinorVersion;
75+
}
76+
77+
uint16_t GetVendorId(void)
78+
{
79+
return nl::Weave::Encoding::LittleEndian::Get16(DeviceVendorId);
80+
}
81+
82+
void SetVendorId(uint16_t vendorId)
83+
{
84+
nl::Weave::Encoding::LittleEndian::Put16(DeviceVendorId, vendorId);
85+
}
86+
87+
uint16_t GetProductId(void)
88+
{
89+
return nl::Weave::Encoding::LittleEndian::Get16(DeviceProductId);
90+
}
91+
92+
void SetProductId(uint16_t productId)
93+
{
94+
nl::Weave::Encoding::LittleEndian::Put16(DeviceProductId, productId);
95+
}
96+
97+
uint64_t GetDeviceId(void)
98+
{
99+
return nl::Weave::Encoding::LittleEndian::Get64(DeviceId);
100+
}
101+
102+
void SetDeviceId(uint64_t deviceId)
103+
{
104+
nl::Weave::Encoding::LittleEndian::Put64(DeviceId, deviceId);
105+
}
106+
} __attribute__((packed));
107+
108+
} /* namespace Ble */
109+
} /* namespace nl */
110+
111+
#endif // WEAVE_BLE_SERVICE_DATA_H

src/include/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ $(nl_public_BleLayer_ble_source_dirstem)/BleLayer.h \
8181
$(nl_public_BleLayer_ble_source_dirstem)/BlePlatformDelegate.h \
8282
$(nl_public_BleLayer_ble_source_dirstem)/BleUUID.h \
8383
$(nl_public_BleLayer_ble_source_dirstem)/WoBle.h \
84+
$(nl_public_BleLayer_ble_source_dirstem)/WeaveBleServiceData.h \
8485
$(NULL)
8586

8687
dist_ble_ble_HEADERS = $(addprefix ../,$(nl_public_BleLayer_ble_header_sources))

src/include/Makefile.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,7 @@ $(nl_public_BleLayer_ble_source_dirstem)/BleLayer.h \
717717
$(nl_public_BleLayer_ble_source_dirstem)/BlePlatformDelegate.h \
718718
$(nl_public_BleLayer_ble_source_dirstem)/BleUUID.h \
719719
$(nl_public_BleLayer_ble_source_dirstem)/WoBle.h \
720+
$(nl_public_BleLayer_ble_source_dirstem)/WeaveBleServiceData.h \
720721
$(NULL)
721722

722723
dist_ble_ble_HEADERS = $(addprefix ../,$(nl_public_BleLayer_ble_header_sources))

0 commit comments

Comments
 (0)