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

Commit fdbbcf3

Browse files
author
Jay Logue
authored
Merge pull request #288 from openweave/issue/invalid-ble-scan-response
Fix for Issue #283: Invalid Weave BLE scan response from nRF5 Device Layer
2 parents 840f4c2 + eec889d commit fdbbcf3

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)