From 1316316f3eca5ce7e548f2e19021559dbcf08304 Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Tue, 4 Jan 2022 21:31:30 +0530 Subject: [PATCH] ESP32: Rotating device ID for BLE transport (#13206) * ESP32: Rotating device ID for BLE transport * Remove the ifdefs and fix the Zephyr static assert Also, set the default value of chip_enable_additional_data_advertising to false in src/platform/BUILD.gn. If this flag is set then Linux and ESP32 set the Additional Data flag and displayes the C3 characteristic. * Changed kServiceDataLenSize to kServiceDataTypeSize Added chip_enable_additional_data_advertising = true to tv-app and tv-cast-app Removed the unused characteristic definitions --- config/esp32/components/chip/CMakeLists.txt | 5 + config/esp32/components/chip/Kconfig | 5 + examples/tv-app/linux/args.gni | 2 + examples/tv-casting-app/linux/args.gni | 2 + src/ble/CHIPBleServiceData.h | 18 +++- src/platform/BUILD.gn | 2 +- src/platform/ESP32/BLEManagerImpl.h | 8 ++ src/platform/ESP32/BUILD.gn | 5 +- src/platform/ESP32/nimble/BLEManagerImpl.cpp | 103 ++++++++++++++++--- src/platform/Linux/bluez/Helper.cpp | 7 +- src/platform/Zephyr/BLEManagerImpl.cpp | 2 +- 11 files changed, 141 insertions(+), 18 deletions(-) diff --git a/config/esp32/components/chip/CMakeLists.txt b/config/esp32/components/chip/CMakeLists.txt index e405201395f065..94153fa20085ac 100644 --- a/config/esp32/components/chip/CMakeLists.txt +++ b/config/esp32/components/chip/CMakeLists.txt @@ -107,6 +107,11 @@ if (CONFIG_ENABLE_OTA_REQUESTOR) chip_gn_arg_append("chip_enable_ota_requestor" "true") endif() +if (CONFIG_ENABLE_ROTATING_DEVICE_ID) + chip_gn_arg_append("chip_enable_additional_data_advertising" "true") + chip_gn_arg_append("chip_enable_rotating_device_id" "true") +endif() + set(args_gn_input "${CMAKE_CURRENT_BINARY_DIR}/args.gn.in") file(GENERATE OUTPUT "${args_gn_input}" CONTENT "${chip_gn_args}") diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index b7837b42cc9696..3e4dfb53823eb5 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -706,6 +706,11 @@ menu "CHIP Device Layer" Setting this to y will cause the commissioner to send commissioning commands to the various clusters after establishing a PASE session. + config ENABLE_ROTATING_DEVICE_ID + depends on ENABLE_CHIPOBLE + bool "Enable Rotating Device Identifier Support" + default n + endmenu diff --git a/examples/tv-app/linux/args.gni b/examples/tv-app/linux/args.gni index beb195669abda2..266d8cbe2c7b58 100644 --- a/examples/tv-app/linux/args.gni +++ b/examples/tv-app/linux/args.gni @@ -26,4 +26,6 @@ chip_project_config_include_dirs += [ "${chip_root}/config/standalone" ] chip_build_libshell = true +chip_enable_additional_data_advertising = true + chip_enable_rotating_device_id = true diff --git a/examples/tv-casting-app/linux/args.gni b/examples/tv-casting-app/linux/args.gni index e0364467f6c10e..3175a832930e5e 100644 --- a/examples/tv-casting-app/linux/args.gni +++ b/examples/tv-casting-app/linux/args.gni @@ -26,4 +26,6 @@ chip_project_config_include_dirs += [ "${chip_root}/config/standalone" ] chip_build_libshell = true +chip_enable_additional_data_advertising = true + chip_enable_rotating_device_id = true diff --git a/src/ble/CHIPBleServiceData.h b/src/ble/CHIPBleServiceData.h index cd4d84e8b11df9..e8ca5172ebadc3 100644 --- a/src/ble/CHIPBleServiceData.h +++ b/src/ble/CHIPBleServiceData.h @@ -45,12 +45,14 @@ enum chipBLEServiceDataType */ struct ChipBLEDeviceIdentificationInfo { - constexpr static uint16_t kDiscriminatorMask = 0xfff; + constexpr static uint16_t kDiscriminatorMask = 0xfff; + constexpr static uint8_t kAdditionalDataFlagMask = 0x1; uint8_t OpCode; uint8_t DeviceDiscriminator[2]; uint8_t DeviceVendorId[2]; uint8_t DeviceProductId[2]; + uint8_t AdditionalDataFlag; void Init() { memset(this, 0, sizeof(*this)); } @@ -74,6 +76,20 @@ struct ChipBLEDeviceIdentificationInfo deviceDiscriminator |= static_cast(DeviceDiscriminator[1] << 8u & ~kDiscriminatorMask); chip::Encoding::LittleEndian::Put16(DeviceDiscriminator, deviceDiscriminator); } + + uint8_t GetAdditionalDataFlag() const { return (AdditionalDataFlag & kAdditionalDataFlagMask); } + + void SetAdditionalDataFlag(bool flag) + { + if (flag) + { + AdditionalDataFlag |= kAdditionalDataFlagMask; + } + else + { + AdditionalDataFlag &= static_cast(~kAdditionalDataFlagMask); + } + } } __attribute__((packed)); } /* namespace Ble */ diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn index c154565b8ab042..37dd34ab3f86d8 100644 --- a/src/platform/BUILD.gn +++ b/src/platform/BUILD.gn @@ -54,7 +54,7 @@ if (chip_device_platform != "none") { chip_bypass_rendezvous = false # Enable including the additional data in the advertisement packets - chip_enable_additional_data_advertising = true + chip_enable_additional_data_advertising = false # Enable adding optional rotating device id to the additional data. chip_enable_rotating_device_id = false diff --git a/src/platform/ESP32/BLEManagerImpl.h b/src/platform/ESP32/BLEManagerImpl.h index 624da05ea2d4ce..62ba2b79ba9097 100644 --- a/src/platform/ESP32/BLEManagerImpl.h +++ b/src/platform/ESP32/BLEManagerImpl.h @@ -189,6 +189,9 @@ class BLEManagerImpl final : public BLEManager, uint16_t mServiceAttrHandle; uint16_t mRXCharAttrHandle; uint16_t mTXCharAttrHandle; +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + uint16_t mC3CharAttrHandle; +#endif uint16_t mTXCharCCCDAttrHandle; BitFlags mFlags; char mDeviceName[kMaxDeviceNameLength + 1]; @@ -246,6 +249,11 @@ class BLEManagerImpl final : public BLEManager, static int ble_svr_gap_event(struct ble_gap_event * event, void * arg); static int gatt_svr_chr_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt * ctxt, void * arg); +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + static int gatt_svr_chr_access_additional_data(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt * ctxt, + void * arg); + void HandleC3CharRead(struct ble_gatt_char_context * param); +#endif /* CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING */ #endif static void DriveBLEState(intptr_t arg); diff --git a/src/platform/ESP32/BUILD.gn b/src/platform/ESP32/BUILD.gn index 7d70d6bec7f839..3b13cfd87d9509 100644 --- a/src/platform/ESP32/BUILD.gn +++ b/src/platform/ESP32/BUILD.gn @@ -48,7 +48,10 @@ static_library("ESP32") { "nimble/BLEManagerImpl.cpp", ] - deps = [ "${chip_root}/src/lib/dnssd:platform_header" ] + deps = [ + "${chip_root}/src/lib/dnssd:platform_header", + "${chip_root}/src/setup_payload", + ] public_deps = [ "${chip_root}/src/crypto", diff --git a/src/platform/ESP32/nimble/BLEManagerImpl.cpp b/src/platform/ESP32/nimble/BLEManagerImpl.cpp index a59ed79a80add9..f7dd906108c6c2 100644 --- a/src/platform/ESP32/nimble/BLEManagerImpl.cpp +++ b/src/platform/ESP32/nimble/BLEManagerImpl.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include "esp_log.h" @@ -67,9 +68,6 @@ struct ESP32ChipServiceData ChipBLEDeviceIdentificationInfo DeviceIdInfo; }; -const ble_uuid128_t UUID_CHIPoBLEService = { - BLE_UUID_TYPE_128, { 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xF6, 0xFF, 0x00, 0x00 } -}; const ble_uuid16_t ShortUUID_CHIPoBLEService = { BLE_UUID_TYPE_16, 0xFFF6 }; const ble_uuid128_t UUID128_CHIPoBLEChar_RX = { @@ -77,19 +75,19 @@ const ble_uuid128_t UUID128_CHIPoBLEChar_RX = { }; const ChipBleUUID chipUUID_CHIPoBLEChar_RX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, 0x9D, 0x11 } }; -const ble_uuid128_t UUID_CHIPoBLEChar_RX = { - { BLE_UUID_TYPE_128 }, { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, 0x9D, 0x11 } -}; -const ble_uuid128_t UUID128_CHIPoBLEChar_TX = { - BLE_UUID_TYPE_128, { 0x12, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18 } -}; const ChipBleUUID chipUUID_CHIPoBLEChar_TX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, 0x9D, 0x12 } }; const ble_uuid128_t UUID_CHIPoBLEChar_TX = { { BLE_UUID_TYPE_128 }, { 0x12, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18 } }; +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING +const ble_uuid128_t UUID_CHIPoBLEChar_C3 = { + { BLE_UUID_TYPE_128 }, { 0x04, 0x8F, 0x21, 0x83, 0x8A, 0x74, 0x7D, 0xB8, 0xF2, 0x45, 0x72, 0x87, 0x38, 0x02, 0x63, 0x64 } +}; +#endif + SemaphoreHandle_t semaphoreHandle = NULL; } // unnamed namespace @@ -115,6 +113,14 @@ const struct ble_gatt_svc_def BLEManagerImpl::CHIPoBLEGATTAttrs[] = { .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY, .val_handle = &sInstance.mTXCharCCCDAttrHandle, }, +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + { + .uuid = (ble_uuid_t *) (&UUID_CHIPoBLEChar_C3), + .access_cb = gatt_svr_chr_access_additional_data, + .flags = BLE_GATT_CHR_F_READ, + .val_handle = &sInstance.mC3CharAttrHandle, + }, +#endif { 0, /* No more characteristics in this service */ }, @@ -133,7 +139,10 @@ CHIP_ERROR BLEManagerImpl::_Init() err = BleLayer::Init(this, this, &DeviceLayer::SystemLayer()); SuccessOrExit(err); - mRXCharAttrHandle = 0; + mRXCharAttrHandle = 0; +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + mC3CharAttrHandle = 0; +#endif mTXCharCCCDAttrHandle = 0; mFlags.ClearAll().Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART); mFlags.Set(Flags::kFastAdvertisingEnabled, true); @@ -683,6 +692,10 @@ CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void) uint8_t advData[MAX_ADV_DATA_LEN]; uint8_t index = 0; + constexpr uint8_t kServiceDataTypeSize = 1; + + chip::Ble::ChipBLEDeviceIdentificationInfo deviceIdInfo; + // If a custom device name has not been specified, generate a CHIP-standard name based on the // bottom digits of the Chip device id. uint16_t discriminator; @@ -706,12 +719,11 @@ CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void) advData[index++] = 0x02; // length advData[index++] = CHIP_ADV_DATA_TYPE_FLAGS; // AD type : flags advData[index++] = CHIP_ADV_DATA_FLAGS; // AD value - advData[index++] = 0x0A; // length + advData[index++] = kServiceDataTypeSize + sizeof(ESP32ChipServiceData); // length advData[index++] = CHIP_ADV_DATA_TYPE_SERVICE_DATA; // AD type: (Service Data - 16-bit UUID) advData[index++] = static_cast(ShortUUID_CHIPoBLEService.value & 0xFF); // AD value advData[index++] = static_cast((ShortUUID_CHIPoBLEService.value >> 8) & 0xFF); // AD value - chip::Ble::ChipBLEDeviceIdentificationInfo deviceIdInfo; err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(deviceIdInfo); if (err != CHIP_NO_ERROR) { @@ -719,6 +731,10 @@ CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void) ExitNow(); } +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + deviceIdInfo.SetAdditionalDataFlag(true); +#endif + VerifyOrExit(index + sizeof(deviceIdInfo) <= sizeof(advData), err = CHIP_ERROR_OUTBOUND_MESSAGE_TOO_BIG); memcpy(&advData[index], &deviceIdInfo, sizeof(deviceIdInfo)); index = static_cast(index + sizeof(deviceIdInfo)); @@ -1046,6 +1062,69 @@ int BLEManagerImpl::ble_svr_gap_event(struct ble_gap_event * event, void * arg) return err.AsInteger(); } +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING +void BLEManagerImpl::HandleC3CharRead(struct ble_gatt_char_context * param) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + chip::System::PacketBufferHandle bufferHandle; + + char serialNumber[ConfigurationManager::kMaxSerialNumberLength + 1]; + uint16_t lifetimeCounter = 0; + BitFlags additionalDataFields; + +#if CHIP_ENABLE_ROTATING_DEVICE_ID + err = ConfigurationMgr().GetSerialNumber(serialNumber, sizeof(serialNumber)); + SuccessOrExit(err); + err = ConfigurationMgr().GetLifetimeCounter(lifetimeCounter); + SuccessOrExit(err); + + additionalDataFields.Set(AdditionalDataFields::RotatingDeviceId); +#endif /* CHIP_ENABLE_ROTATING_DEVICE_ID */ + + err = AdditionalDataPayloadGenerator().generateAdditionalDataPayload(lifetimeCounter, serialNumber, strlen(serialNumber), + bufferHandle, additionalDataFields); + SuccessOrExit(err); + + os_mbuf_append(param->ctxt->om, bufferHandle->Start(), bufferHandle->DataLength()); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to generate TLV encoded Additional Data (%s)", __func__); + } + return; +} + +int BLEManagerImpl::gatt_svr_chr_access_additional_data(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt * ctxt, void * arg) +{ + struct ble_gatt_char_context param; + int err = 0; + + memset(¶m, 0, sizeof(struct ble_gatt_char_context)); + + switch (ctxt->op) + { + case BLE_GATT_ACCESS_OP_READ_CHR: + + param.conn_handle = conn_handle; + param.attr_handle = attr_handle; + param.ctxt = ctxt; + param.arg = arg; + sInstance.HandleC3CharRead(¶m); + break; + + default: + err = BLE_ATT_ERR_UNLIKELY; + break; + } + + PlatformMgr().ScheduleWork(DriveBLEState, 0); + + return err; +} +#endif /* CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING */ + int BLEManagerImpl::gatt_svr_chr_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt * ctxt, void * arg) { struct ble_gatt_char_context param; diff --git a/src/platform/Linux/bluez/Helper.cpp b/src/platform/Linux/bluez/Helper.cpp index 4da5da3021be03..feae4149eab7d4 100644 --- a/src/platform/Linux/bluez/Helper.cpp +++ b/src/platform/Linux/bluez/Helper.cpp @@ -45,9 +45,8 @@ /** * @file - * Provides Bluez dbus implementatioon for BLE + * Provides Bluez dbus implementation for BLE */ - #include #include #include @@ -1520,6 +1519,10 @@ CHIP_ERROR ConfigureBluezAdv(BLEAdvConfig & aBleAdvConfig, BluezEndpoint * apEnd err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(apEndpoint->mDeviceIdInfo); SuccessOrExit(err); +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + apEndpoint->mDeviceIdInfo.SetAdditionalDataFlag(true); +#endif + exit: if (nullptr != msg) { diff --git a/src/platform/Zephyr/BLEManagerImpl.cpp b/src/platform/Zephyr/BLEManagerImpl.cpp index e7b99e7792890c..072e1c0d6903a6 100644 --- a/src/platform/Zephyr/BLEManagerImpl.cpp +++ b/src/platform/Zephyr/BLEManagerImpl.cpp @@ -269,7 +269,7 @@ CHIP_ERROR BLEManagerImpl::StartAdvertising(void) } // Initialize service data - static_assert(sizeof(serviceData) == 9, "Size of BLE advertisement data changed! Was that intentional?"); + static_assert(sizeof(serviceData) == 10, "Size of BLE advertisement data changed! Was that intentional?"); chip::Encoding::LittleEndian::Put16(serviceData.uuid, UUID16_CHIPoBLEService.val); ReturnErrorOnFailure(ConfigurationMgr().GetBLEDeviceIdentificationInfo(serviceData.deviceIdInfo));