diff --git a/docs/guides/esp32/README.md b/docs/guides/esp32/README.md index 89d9225cf65dd8..e487a58f318591 100644 --- a/docs/guides/esp32/README.md +++ b/docs/guides/esp32/README.md @@ -17,3 +17,4 @@ example on ESP32 series of SoCs - [RPC Console and Device Tracing](rpc_console.md) - [Matter OTA](ota.md) - [Generating and Using ESP Secure Cert Partition](secure_cert_partition.md) +- [BLE Settings](ble_settings.md) diff --git a/docs/guides/esp32/ble_settings.md b/docs/guides/esp32/ble_settings.md new file mode 100644 index 00000000000000..36178ebece5d71 --- /dev/null +++ b/docs/guides/esp32/ble_settings.md @@ -0,0 +1,32 @@ +# Bluetooth Low Energy (BLE) + +## Nimble: scan response + +The `ConfigureScanResponseData` API is used to configure the scan response data +for advertising in a Bluetooth Low Energy (BLE) application based on the NimBLE +BLE stack. Scan response data is additional data that a BLE peripheral device +can include in its advertising packets to provide more information about itself. +This API allows you to set the scan response data that will be included in the +advertising packets. + +### Usage + +``` +{ + uint8_t scanResponse[31]; // 0x05, 0x09, a, b, c, d + scanResponse[0] = 0x05; + scanResponse[1] = 0x09; + scanResponse[2] = 0x61; + scanResponse[3] = 0x62; + scanResponse[4] = 0x63; + scanResponse[5] = 0x64; + chip::ByteSpan data(scanResponse); + CHIP_ERROR err = chip::DeviceLayer::Internal::BLEMgrImpl().ConfigureScanResponseData(data); + if (err != CHIP_NO_ERROR) + { + ESP_LOGE(TAG, "Failed to configure scan response, err:%" CHIP_ERROR_FORMAT, err.Format()); + } +} +``` + +Note: Scan response should be configure before `InitServer`. diff --git a/src/platform/ESP32/BLEManagerImpl.h b/src/platform/ESP32/BLEManagerImpl.h index e7f61785ffa5c8..5cb1421750786a 100644 --- a/src/platform/ESP32/BLEManagerImpl.h +++ b/src/platform/ESP32/BLEManagerImpl.h @@ -71,6 +71,8 @@ struct ble_gatt_char_context #include #endif +#define MAX_SCAN_RSP_DATA_LEN 31 + namespace chip { namespace DeviceLayer { namespace Internal { @@ -132,6 +134,7 @@ class BLEManagerImpl final : public BLEManager, #endif { public: + uint8_t scanResponseBuffer[MAX_SCAN_RSP_DATA_LEN]; BLEManagerImpl() {} #if CONFIG_ENABLE_ESP32_BLE_CONTROLLER CHIP_ERROR ConfigureBle(uint32_t aAdapterId, bool aIsCentral); @@ -140,7 +143,12 @@ class BLEManagerImpl final : public BLEManager, #endif #endif + CHIP_ERROR ConfigureScanResponseData(ByteSpan data); + void ClearScanResponseData(void); + private: + chip::Optional mScanResponse; + // Allow the BLEManager interface class to delegate method calls to // the implementation methods provided by this class. friend BLEManager; diff --git a/src/platform/ESP32/nimble/BLEManagerImpl.cpp b/src/platform/ESP32/nimble/BLEManagerImpl.cpp index 52e86d4b050a7f..6a9a047ab84db1 100644 --- a/src/platform/ESP32/nimble/BLEManagerImpl.cpp +++ b/src/platform/ESP32/nimble/BLEManagerImpl.cpp @@ -1012,6 +1012,25 @@ CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void) return err; } +CHIP_ERROR BLEManagerImpl::ConfigureScanResponseData(ByteSpan data) +{ + if (!IsSpanUsable(data) || data.size() > MAX_SCAN_RSP_DATA_LEN) + { + ChipLogError(DeviceLayer, "scan response data is invalid"); + return CHIP_ERROR_INVALID_ARGUMENT; + } + memcpy(scanResponseBuffer, data.data(), data.size()); + ByteSpan scanResponseSpan(scanResponseBuffer); + mScanResponse = chip::Optional(scanResponseSpan); + return CHIP_NO_ERROR; +} + +void BLEManagerImpl::ClearScanResponseData(void) +{ + mScanResponse.ClearValue(); + ChipLogDetail(DeviceLayer, "scan response data is cleared"); +} + void BLEManagerImpl::HandleRXCharWrite(struct ble_gatt_char_context * param) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -1584,6 +1603,15 @@ CHIP_ERROR BLEManagerImpl::StartAdvertising(void) } } #endif + if (mScanResponse.HasValue()) + { + err = MapBLEError(ble_gap_adv_rsp_set_data(mScanResponse.Value().data(), mScanResponse.Value().size())); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "ble_gap_adv_rsp_set_data failed: %s", ErrorStr(err)); + return err; + } + } err = MapBLEError(ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER, &adv_params, ble_svr_gap_event, NULL)); if (err == CHIP_NO_ERROR) {