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

Custom BLE data at application layer #36857

Merged
merged 9 commits into from
Dec 17, 2024
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
7 changes: 7 additions & 0 deletions config/zephyr/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -582,3 +582,10 @@ config CHIP_BLE_ADVERTISING_DURATION
else the maximum duration time can be extended to 2880 minutes (48h).

endif

if BT
config CHIP_CUSTOM_BLE_ADV_DATA
bool "Use custom BLE advertising data"
help
Customization of BLE advertising data at the application layer
endif
3 changes: 3 additions & 0 deletions examples/all-clusters-app/nxp/common/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ void AllClustersApp::AppTask::PostInitMatterStack()

void AllClustersApp::AppTask::PostInitMatterServerInstance()
{
#ifdef APP_BT_DEVICE_NAME
chip::DeviceLayer::ConnectivityMgr().SetBLEDeviceName(APP_BT_DEVICE_NAME);
#endif
// Disable last fixed endpoint, which is used as a placeholder for all of the
// supported clusters so that ZAP will generated the requisite code.
emberAfEndpointEnableDisable(emberAfEndpointFromIndex(static_cast<uint16_t>(emberAfFixedEndpointCount() - 1)), false);
Expand Down
4 changes: 4 additions & 0 deletions examples/all-clusters-app/nxp/rt/rt1060/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,10 @@ rt_executable("all_cluster_app") {
]
}

if (chip_enable_ble) {
defines += [ "APP_BT_DEVICE_NAME=\"NXP-AllClustersApp\"" ]
}

# In case a dedicated assert function needs to be supported the flag sdk_fsl_assert_support should be set to false
# The would add to the build a dedicated application assert implementation.
if (!sdk_fsl_assert_support) {
Expand Down
4 changes: 4 additions & 0 deletions examples/all-clusters-app/nxp/rt/rt1170/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@ rt_executable("all_cluster_app") {
sources += [ "${common_example_dir}/wifi_connect/source/WifiConnect.cpp" ]
}

if (chip_enable_ble) {
defines += [ "APP_BT_DEVICE_NAME=\"NXP-AllClustersApp\"" ]
}

# In case a dedicated assert function needs to be supported the flag sdk_fsl_assert_support should be set to false
# The would add to the build a dedicated application assert implementation.
if (!sdk_fsl_assert_support) {
Expand Down
4 changes: 4 additions & 0 deletions examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ rt_executable("all_cluster_app") {
sources += [ "${common_example_dir}/wifi_connect/source/WifiConnect.cpp" ]
}

if (chip_enable_ble) {
defines += [ "APP_BT_DEVICE_NAME=\"NXP-AllClustersApp\"" ]
}

# In case a dedicated assert function needs to be supported the flag sdk_fsl_assert_support should be set to false
# The would add to the build a dedicated application assert implementation.
if (!sdk_fsl_assert_support) {
Expand Down
11 changes: 11 additions & 0 deletions examples/thermostat/nxp/common/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
#include <app/InteractionModelEngine.h>
#include <app/util/attribute-storage.h>

#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
#include "BLEApplicationManager.h"
#endif

using namespace chip;

void ThermostatApp::AppTask::PreInitMatterStack()
Expand All @@ -33,6 +37,13 @@ void ThermostatApp::AppTask::PreInitMatterStack()

void ThermostatApp::AppTask::PostInitMatterStack()
{
#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
#ifdef APP_BT_DEVICE_NAME
chip::DeviceLayer::ConnectivityMgr().SetBLEDeviceName(APP_BT_DEVICE_NAME);
#endif
/* BLEApplicationManager implemented per platform or left blank */
chip::NXP::App::BleAppMgr().Init();
#endif
chip::app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(&chip::NXP::App::GetICDUtil());
}

Expand Down
100 changes: 100 additions & 0 deletions examples/thermostat/nxp/common/main/BleZephyrManagerApp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
*
* Copyright (c) 2024 Project CHIP Authors
* Copyright 2024 NXP
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "BLEApplicationManager.h"

#include <platform/internal/CHIPDeviceLayerInternal.h>

#include "BLEManagerImpl.h"
#include <ble/Ble.h>
#include <platform/ConfigurationManager.h>
#include <zephyr/bluetooth/gatt.h>

#define ADV_LEN 2

using namespace ::chip::DeviceLayer;
using namespace ::chip::DeviceLayer::Internal;
using namespace ::chip::NXP::App;

BLEApplicationManager BLEApplicationManager::sInstance;

struct ServiceData
{
uint8_t uuid[2];
chip::Ble::ChipBLEDeviceIdentificationInfo deviceIdInfo;
} __attribute__((packed));

ServiceData serviceData;
std::array<bt_data, 3> advertisingData;
std::array<bt_data, 1> scanResponseData;

constexpr uint8_t kAdvertisingFlags = BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR;

uint8_t manuf_data[ADV_LEN] = {
0x25,
0x00,
};

bt_uuid_16 UUID16_CHIPoBLEService = BT_UUID_INIT_16(0xFFF6);

/**
* @brief Init BLE application manager
*
* In this example, the application manager is used to customize BLE advertising
* parameters. This example is provided for platforms with Zephyr BLE manager support.
*
* @note This example set custom Zephyr BLE manager Matter advertising parameters (
* CONFIG_CHIP_CUSTOM_BLE_ADV_DATA for kconfig or ble_adv_data_custom for GN is set).
* To keep the advertising support for commissining, it is needed to register the whole
* adv data (adv flags + Matter adv data + custom adv data) and register scan
* response data as default adv and response data will be skipped.
* kAdvertisingFlags and manuf_data are given for examples, size of advertisingData and
* scanResponseData have to be set according to custom requirements.
*
* For custom Gatt services, APIs bt_gatt_service_register and bt_gatt_service_unregister
* could be called at application layer. It will not override Matter Gatt services but
* add new one.
*
* @note At the end of the commissioning advertising will be stopped.
*
* To start new advertising process, APIs :
* chip::DeviceLayer::BLEAdvertisingArbiter::InsertRequest
* chip::DeviceLayer::BLEAdvertisingArbiter::CancelRequest
* could be called. If InsertRequest API is called several time, only the request with the
* higher priority will be advertise.
*
*/
void BLEApplicationManager::Init(void)
{
/* Register Matter adv data + custom adv data */
static_assert(sizeof(serviceData) == 10, "Unexpected size of BLE advertising data!");
const char * name = bt_get_name();
const uint8_t nameSize = static_cast<uint8_t>(strlen(name));
Encoding::LittleEndian::Put16(serviceData.uuid, UUID16_CHIPoBLEService.val);
chip::DeviceLayer::ConfigurationMgr().GetBLEDeviceIdentificationInfo(serviceData.deviceIdInfo);

advertisingData[0] = BT_DATA(BT_DATA_FLAGS, &kAdvertisingFlags, sizeof(kAdvertisingFlags));
/* Matter adv data for commissining */
advertisingData[1] = BT_DATA(BT_DATA_SVC_DATA16, &serviceData, sizeof(serviceData));
/* Example of custom BLE adv data */
advertisingData[2] = BT_DATA(BT_DATA_MANUFACTURER_DATA, manuf_data, ADV_LEN);
scanResponseData[0] = BT_DATA(BT_DATA_NAME_COMPLETE, name, nameSize);
chip::DeviceLayer::Internal::BLEMgrImpl().SetCustomAdvertising(Span<bt_data>(advertisingData));
chip::DeviceLayer::Internal::BLEMgrImpl().SetCustomScanResponse(Span<bt_data>(scanResponseData));
}
16 changes: 16 additions & 0 deletions examples/thermostat/nxp/rt/rt1060/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,22 @@ rt_executable("thermostat") {
"../../common/main/main.cpp",
]

if (chip_enable_ble) {
defines += [ "APP_BT_DEVICE_NAME=\"NXP-ThermostatApp\"" ]
include_dirs += [ "${common_example_dir}/app_ble/include" ]
if (ble_adv_data_custom) {
# to customize BLE advertising data
defines += [ "CONFIG_CHIP_CUSTOM_BLE_ADV_DATA=1" ]
include_dirs += [ "${chip_root}/src/platform/nxp/common/ble_zephyr" ]
sources += [ "../../common/main/BleZephyrManagerApp.cpp" ]
} else {
# Empty implementation, default matter advertising data
sources += [
"${common_example_dir}/app_ble/source/BLEApplicationManagerEmpty.cpp",
]
}
}

if (chip_with_diag_logs_demo) {
include_dirs += [
"${common_example_dir}/diagnostic_logs/include",
Expand Down
4 changes: 4 additions & 0 deletions examples/thermostat/nxp/rt/rt1060/args.gni
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

import("//build_overrides/chip.gni")

# Set to true to customized BLE advertising data at application layer,
# instead of default Zephyr BLE manager implementation advertising data
ble_adv_data_custom = true

# SDK target definitions
nxp_sdk_target = get_label_info(":sdk", "label_no_toolchain")
nxp_sdk_driver_target = get_label_info(":sdk_driver", "label_no_toolchain")
16 changes: 16 additions & 0 deletions examples/thermostat/nxp/rt/rt1170/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,22 @@ rt_executable("thermostat") {
"../../common/main/main.cpp",
]

if (chip_enable_ble) {
defines += [ "APP_BT_DEVICE_NAME=\"NXP-ThermostatApp\"" ]
include_dirs += [ "${common_example_dir}/app_ble/include" ]
if (ble_adv_data_custom) {
# to customize BLE advertising data
defines += [ "CONFIG_CHIP_CUSTOM_BLE_ADV_DATA=1" ]
include_dirs += [ "${chip_root}/src/platform/nxp/common/ble_zephyr" ]
sources += [ "../../common/main/BleZephyrManagerApp.cpp" ]
} else {
# Empty implementation, default matter advertising data
sources += [
"${common_example_dir}/app_ble/source/BLEApplicationManagerEmpty.cpp",
]
}
}

if (chip_with_diag_logs_demo) {
include_dirs += [
"${common_example_dir}/diagnostic_logs/include",
Expand Down
4 changes: 4 additions & 0 deletions examples/thermostat/nxp/rt/rt1170/args.gni
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

import("//build_overrides/chip.gni")

# Set to true to customized BLE advertising data at application layer,
# instead of default Zephyr BLE manager implementation advertising data
ble_adv_data_custom = true

# SDK target definitions
nxp_sdk_target = get_label_info(":sdk", "label_no_toolchain")
nxp_sdk_driver_target = get_label_info(":sdk_driver", "label_no_toolchain")
16 changes: 16 additions & 0 deletions examples/thermostat/nxp/rt/rw61x/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,22 @@ rt_executable("thermostat") {
"../../common/main/main.cpp",
]

if (chip_enable_ble) {
defines += [ "APP_BT_DEVICE_NAME=\"NXP-ThermostatApp\"" ]
include_dirs += [ "${common_example_dir}/app_ble/include" ]
if (ble_adv_data_custom) {
# to customize BLE advertising data
defines += [ "CONFIG_CHIP_CUSTOM_BLE_ADV_DATA=1" ]
include_dirs += [ "${chip_root}/src/platform/nxp/common/ble_zephyr" ]
sources += [ "../../common/main/BleZephyrManagerApp.cpp" ]
} else {
# Empty implementation, default matter advertising data
sources += [
"${common_example_dir}/app_ble/source/BLEApplicationManagerEmpty.cpp",
]
}
}

if (chip_with_diag_logs_demo) {
include_dirs += [
"${common_example_dir}/diagnostic_logs/include",
Expand Down
4 changes: 4 additions & 0 deletions examples/thermostat/nxp/rt/rw61x/args.gni
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

import("//build_overrides/chip.gni")

# Set to true to customized BLE advertising data at application layer,
# instead of default Zephyr BLE manager implementation advertising data
ble_adv_data_custom = true

# SDK target definitions
nxp_sdk_target = get_label_info(":sdk", "label_no_toolchain")
nxp_sdk_driver_target = get_label_info(":sdk_driver", "label_no_toolchain")
11 changes: 11 additions & 0 deletions examples/thermostat/nxp/zephyr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ target_include_directories(app
${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/device_callbacks/include
${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/factory_data/include
${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_task/include
${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_ble/include
)

target_sources(app
Expand All @@ -73,6 +74,16 @@ target_compile_definitions(app PUBLIC
"EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/zephyr/FactoryDataProviderImpl.h\""
)

if(CONFIG_CHIP_CUSTOM_BLE_ADV_DATA)
target_sources(app PRIVATE
${THERMOSTAT_NXP_COMMON_DIR}/main/BleZephyrManagerApp.cpp
)
else()
target_sources(app PRIVATE
${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/app_ble/source/BLEApplicationManagerEmpty.cpp
)
endif()

if(CONFIG_CHIP_OTA_REQUESTOR)
target_sources(app PRIVATE
${EXAMPLE_PLATFORM_NXP_COMMON_DIR}/ota_requestor/source/OTARequestorInitiatorCommon.cpp
Expand Down
4 changes: 4 additions & 0 deletions examples/thermostat/nxp/zephyr/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,7 @@ CONFIG_CHIP_LIB_SHELL=y
# enable NET commands if desired
# CONFIG_NET_SHELL=y
CONFIG_CHIP_STATISTICS=y

# To customized BLE advertising data at application layer,
# instead of default Zephyr BLE manager implementation advertising data
CONFIG_CHIP_CUSTOM_BLE_ADV_DATA=y
31 changes: 27 additions & 4 deletions src/platform/Zephyr/BLEManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,13 @@ struct BLEManagerImpl::ServiceData

inline CHIP_ERROR BLEManagerImpl::PrepareAdvertisingRequest()
{
#ifdef CONFIG_CHIP_CUSTOM_BLE_ADV_DATA
if (mCustomAdvertising.empty())
{
ChipLogError(DeviceLayer, "mCustomAdvertising should be set when CONFIG_CHIP_CUSTOM_BLE_ADV_DATA is define");
return CHIP_ERROR_INTERNAL;
}
#else
static ServiceData serviceData;
static std::array<bt_data, 2> advertisingData;
static std::array<bt_data, 1> scanResponseData;
Expand All @@ -304,9 +311,10 @@ inline CHIP_ERROR BLEManagerImpl::PrepareAdvertisingRequest()
}
#endif

advertisingData[0] = BT_DATA(BT_DATA_FLAGS, &kAdvertisingFlags, sizeof(kAdvertisingFlags));
advertisingData[1] = BT_DATA(BT_DATA_SVC_DATA16, &serviceData, sizeof(serviceData));
scanResponseData[0] = BT_DATA(BT_DATA_NAME_COMPLETE, name, nameSize);
advertisingData[0] = BT_DATA(BT_DATA_FLAGS, &kAdvertisingFlags, sizeof(kAdvertisingFlags));
advertisingData[1] = BT_DATA(BT_DATA_SVC_DATA16, &serviceData, sizeof(serviceData));
scanResponseData[0] = BT_DATA(BT_DATA_NAME_COMPLETE, name, nameSize);
#endif // CONFIG_CHIP_CUSTOM_BLE_ADV_DATA

mAdvertisingRequest.priority = CHIP_DEVICE_BLE_ADVERTISING_PRIORITY;
mAdvertisingRequest.options = kAdvertisingOptions;
Expand All @@ -328,9 +336,13 @@ inline CHIP_ERROR BLEManagerImpl::PrepareAdvertisingRequest()
mAdvertisingRequest.minInterval = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN;
mAdvertisingRequest.maxInterval = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX;
}
#ifdef CONFIG_CHIP_CUSTOM_BLE_ADV_DATA
mAdvertisingRequest.advertisingData = mCustomAdvertising;
mAdvertisingRequest.scanResponseData = mCustomScanResponse;
#else
mAdvertisingRequest.advertisingData = Span<bt_data>(advertisingData);
mAdvertisingRequest.scanResponseData = nameSize ? Span<bt_data>(scanResponseData) : Span<bt_data>{};

#endif
mAdvertisingRequest.onStarted = [](int rc) {
if (rc == 0)
{
Expand Down Expand Up @@ -967,6 +979,17 @@ ssize_t BLEManagerImpl::HandleC3Read(struct bt_conn * conId, const struct bt_gat
}
#endif

#ifdef CONFIG_CHIP_CUSTOM_BLE_ADV_DATA
void BLEManagerImpl::SetCustomAdvertising(Span<bt_data> CustomAdvertising)
{
mCustomAdvertising = CustomAdvertising;
}
void BLEManagerImpl::SetCustomScanResponse(Span<bt_data> CustomScanResponse)
{
mCustomScanResponse = CustomScanResponse;
}
#endif

} // namespace Internal
} // namespace DeviceLayer
} // namespace chip
Expand Down
8 changes: 8 additions & 0 deletions src/platform/Zephyr/BLEManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla
#endif
// The summarized number of Bluetooth LE connections related to the device (including these not related to Matter service).
uint16_t mTotalConnNum;
#ifdef CONFIG_CHIP_CUSTOM_BLE_ADV_DATA
Span<bt_data> mCustomAdvertising = {};
Span<bt_data> mCustomScanResponse = {};
#endif

void DriveBLEState(void);
CHIP_ERROR PrepareAdvertisingRequest();
Expand Down Expand Up @@ -150,6 +154,10 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla
#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
static ssize_t HandleC3Read(struct bt_conn * conn, const struct bt_gatt_attr * attr, void * buf, uint16_t len, uint16_t offset);
#endif
#ifdef CONFIG_CHIP_CUSTOM_BLE_ADV_DATA
void SetCustomAdvertising(Span<bt_data> CustomAdvertising);
void SetCustomScanResponse(Span<bt_data> CustomScanResponse);
#endif
};

/**
Expand Down
Loading
Loading