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
diff --git a/config/esp32/components/chip/CMakeLists.txt b/config/esp32/components/chip/CMakeLists.txt
index e405201..94153fa 100644
--- a/config/esp32/components/chip/CMakeLists.txt
+++ b/config/esp32/components/chip/CMakeLists.txt
@@ -107,6 +107,11 @@
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 b7837b4..3e4dfb5 100644
--- a/config/esp32/components/chip/Kconfig
+++ b/config/esp32/components/chip/Kconfig
@@ -706,6 +706,11 @@
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 beb1956..266d8cb 100644
--- a/examples/tv-app/linux/args.gni
+++ b/examples/tv-app/linux/args.gni
@@ -26,4 +26,6 @@
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 e036446..3175a83 100644
--- a/examples/tv-casting-app/linux/args.gni
+++ b/examples/tv-casting-app/linux/args.gni
@@ -26,4 +26,6 @@
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 cd4d84e..e8ca517 100644
--- a/src/ble/CHIPBleServiceData.h
+++ b/src/ble/CHIPBleServiceData.h
@@ -45,12 +45,14 @@
*/
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 @@
deviceDiscriminator |= static_cast<uint16_t>(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<uint8_t>(~kAdditionalDataFlagMask);
+ }
+ }
} __attribute__((packed));
} /* namespace Ble */
diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn
index c154565..37dd34a 100644
--- a/src/platform/BUILD.gn
+++ b/src/platform/BUILD.gn
@@ -54,7 +54,7 @@
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 624da05..62ba2b7 100644
--- a/src/platform/ESP32/BLEManagerImpl.h
+++ b/src/platform/ESP32/BLEManagerImpl.h
@@ -189,6 +189,9 @@
uint16_t mServiceAttrHandle;
uint16_t mRXCharAttrHandle;
uint16_t mTXCharAttrHandle;
+#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
+ uint16_t mC3CharAttrHandle;
+#endif
uint16_t mTXCharCCCDAttrHandle;
BitFlags<Flags> mFlags;
char mDeviceName[kMaxDeviceNameLength + 1];
@@ -246,6 +249,11 @@
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 7d70d6b..3b13cfd 100644
--- a/src/platform/ESP32/BUILD.gn
+++ b/src/platform/ESP32/BUILD.gn
@@ -48,7 +48,10 @@
"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 a59ed79..f7dd906 100644
--- a/src/platform/ESP32/nimble/BLEManagerImpl.cpp
+++ b/src/platform/ESP32/nimble/BLEManagerImpl.cpp
@@ -34,6 +34,7 @@
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/internal/BLEManager.h>
+#include <setup_payload/AdditionalDataPayloadGenerator.h>
#include <system/SystemTimer.h>
#include "esp_log.h"
@@ -67,9 +68,6 @@
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 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 @@
.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 @@
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 @@
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 @@
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<uint8_t>(ShortUUID_CHIPoBLEService.value & 0xFF); // AD value
advData[index++] = static_cast<uint8_t>((ShortUUID_CHIPoBLEService.value >> 8) & 0xFF); // AD value
- chip::Ble::ChipBLEDeviceIdentificationInfo deviceIdInfo;
err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(deviceIdInfo);
if (err != CHIP_NO_ERROR)
{
@@ -719,6 +731,10 @@
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<uint8_t>(index + sizeof(deviceIdInfo));
@@ -1046,6 +1062,69 @@
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> 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 4da5da3..feae414 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 <ble/BleUUID.h>
#include <ble/CHIPBleServiceData.h>
#include <lib/support/BitFlags.h>
@@ -1520,6 +1519,10 @@
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 e7b99e7..072e1c0 100644
--- a/src/platform/Zephyr/BLEManagerImpl.cpp
+++ b/src/platform/Zephyr/BLEManagerImpl.cpp
@@ -269,7 +269,7 @@
}
// 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));