Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP32: Rotating device ID for BLE transport #13206

Merged
merged 3 commits into from
Jan 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions config/esp32/components/chip/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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}")

Expand Down
5 changes: 5 additions & 0 deletions config/esp32/components/chip/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down
2 changes: 2 additions & 0 deletions examples/tv-app/linux/args.gni
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 2 additions & 0 deletions examples/tv-casting-app/linux/args.gni
Original file line number Diff line number Diff line change
Expand Up @@ -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
18 changes: 17 additions & 1 deletion src/ble/CHIPBleServiceData.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)); }

Expand All @@ -74,6 +76,20 @@ struct ChipBLEDeviceIdentificationInfo
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 */
Expand Down
2 changes: 1 addition & 1 deletion src/platform/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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
dhrishi marked this conversation as resolved.
Show resolved Hide resolved

# Enable adding optional rotating device id to the additional data.
chip_enable_rotating_device_id = false
Expand Down
8 changes: 8 additions & 0 deletions src/platform/ESP32/BLEManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<Flags> mFlags;
char mDeviceName[kMaxDeviceNameLength + 1];
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 4 additions & 1 deletion src/platform/ESP32/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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",
dhrishi marked this conversation as resolved.
Show resolved Hide resolved
]

public_deps = [
"${chip_root}/src/crypto",
Expand Down
103 changes: 91 additions & 12 deletions src/platform/ESP32/nimble/BLEManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -67,29 +68,26 @@ 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 = {
BLE_UUID_TYPE_128, { 0x11, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18 }
};
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 }
shubhamdp marked this conversation as resolved.
Show resolved Hide resolved
};
#endif

SemaphoreHandle_t semaphoreHandle = NULL;

} // unnamed namespace
Expand All @@ -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 */
},
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -706,19 +719,22 @@ 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<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)
{
ChipLogError(DeviceLayer, "GetBLEDeviceIdentificationInfo(): %s", ErrorStr(err));
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));
Expand Down Expand Up @@ -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> 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(&param, 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(&param);
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;
Expand Down
7 changes: 5 additions & 2 deletions src/platform/Linux/bluez/Helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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)
{
Expand Down
2 changes: 1 addition & 1 deletion src/platform/Zephyr/BLEManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,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));

Expand Down