diff --git a/Kconfig.dependencies b/Kconfig.dependencies index 2c3eb0014c..88c0462ef2 100644 --- a/Kconfig.dependencies +++ b/Kconfig.dependencies @@ -34,9 +34,22 @@ config SIDEWALK_BLE imply BT_CTLR_CONN_RSSI imply BT_CTLR_TX_PWR_DYNAMIC_CONTROL imply BT_CTLR_ADVANCED_FEATURES + imply BT_EXT_ADV help Sidewalk Bluetooth Low Energy (BLE) module +config SIDEWALK_BLE_NAME + string "BLE name adverticed for Sidewalk" + default "SID_APP" + +config BT_ID_MAX + default 3 if SIDEWALK_DFU + default 2 + +config BT_APP_IFC + bool "Enable BT app wrapper" + default y if SIDEWALK_BLE + config SIDEWALK_ASSERT bool default SIDEWALK diff --git a/samples/sid_end_device/Kconfig.defconfig b/samples/sid_end_device/Kconfig.defconfig index 6620cd88a6..f04ac7c907 100644 --- a/samples/sid_end_device/Kconfig.defconfig +++ b/samples/sid_end_device/Kconfig.defconfig @@ -42,6 +42,14 @@ config BT_PERIPHERAL_PREF_LATENCY config BT_PERIPHERAL_PREF_TIMEOUT default 400 +config BT_EXT_ADV_MAX_ADV_SET + default 3 if SIDEWALK_DFU + default 2 + +config BT_MAX_CONN + default 2 if SIDEWALK_DFU + default 1 + config NVS_LOOKUP_CACHE_SIZE default 256 if NVS diff --git a/samples/sid_end_device/src/hello/app.c b/samples/sid_end_device/src/hello/app.c index 18ada34b85..13d37e0e65 100644 --- a/samples/sid_end_device/src/hello/app.c +++ b/samples/sid_end_device/src/hello/app.c @@ -269,13 +269,9 @@ static void app_btn_dfu_state(uint32_t unused) ARG_UNUSED(unused); static bool go_to_dfu_state = true; if (go_to_dfu_state) { - sidewalk_event_send(sidewalk_event_exit, NULL, NULL); sidewalk_event_send(app_event_enter_dfu_mode, NULL, NULL); - application_state_working(&global_state_notifier, false); } else { sidewalk_event_send(app_event_exit_dfu_mode, NULL, NULL); - sidewalk_event_send(sidewalk_event_autostart, NULL, NULL); - application_state_working(&global_state_notifier, true); } go_to_dfu_state = !go_to_dfu_state; diff --git a/samples/sid_end_device/src/sensor_monitoring/app.c b/samples/sid_end_device/src/sensor_monitoring/app.c index 04fc08a72b..98595732ef 100644 --- a/samples/sid_end_device/src/sensor_monitoring/app.c +++ b/samples/sid_end_device/src/sensor_monitoring/app.c @@ -182,11 +182,9 @@ static void app_btn_dfu_state(uint32_t unused) ARG_UNUSED(unused); static bool go_to_dfu_state = true; if (go_to_dfu_state) { - sidewalk_event_send(sidewalk_event_exit, NULL, NULL); sidewalk_event_send(app_event_enter_dfu_mode, NULL, NULL); } else { sidewalk_event_send(app_event_exit_dfu_mode, NULL, NULL); - sidewalk_event_send(sidewalk_event_autostart, NULL, NULL); } go_to_dfu_state = !go_to_dfu_state; diff --git a/samples/sid_end_device/sysbuild/ipc_radio/prj.conf b/samples/sid_end_device/sysbuild/ipc_radio/prj.conf index 654a36b22a..459a998e25 100644 --- a/samples/sid_end_device/sysbuild/ipc_radio/prj.conf +++ b/samples/sid_end_device/sysbuild/ipc_radio/prj.conf @@ -13,11 +13,14 @@ CONFIG_BT_HCI_RAW=y CONFIG_BT_CTLR_ASSERT_HANDLER=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=n -CONFIG_BT_MAX_CONN=1 +CONFIG_BT_MAX_CONN=2 CONFIG_BT_BUF_ACL_RX_SIZE=502 CONFIG_BT_BUF_ACL_TX_SIZE=251 CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 +CONFIG_BT_CTLR_ADV_SET=3 +CONFIG_BT_CTLR_ADV_EXT=y + # IPC CONFIG_IPC_SERVICE=y CONFIG_MBOX=y diff --git a/scripts/ci/license.yml b/scripts/ci/license.yml index 547bf5ad24..d8a67d4cff 100644 --- a/scripts/ci/license.yml +++ b/scripts/ci/license.yml @@ -41,7 +41,7 @@ licenses: - sidewalk.*/subsys/config/common/src/.*(c|h)$ - sidewalk.*/subsys/hal(/.*)+h$ - sidewalk.*/subsys/hal/src/memory.c$ - - sidewalk.*/subsys/sal/common/.*(c|h)$ + - sidewalk.*/subsys/sal/common/.*/sid_.*(c|h)$ - sidewalk.*/subsys/semtech/include/semtech_radio_ifc.h$ - sidewalk.*/tools/.* - sidewalk.*/tests/validation/storage_kv/.*(c|h)$ diff --git a/subsys/config/common/src/app_ble_config.c b/subsys/config/common/src/app_ble_config.c index 5eef7dbe42..6fc6087a97 100644 --- a/subsys/config/common/src/app_ble_config.c +++ b/subsys/config/common/src/app_ble_config.c @@ -105,7 +105,7 @@ static const sid_ble_cfg_gatt_profile_t ble_profile[] = { }; static const sid_ble_config_t ble_cfg = { - .name = CONFIG_BT_DEVICE_NAME, + .name = CONFIG_SIDEWALK_BLE_NAME, .mtu = CONFIG_BT_L2CAP_TX_MTU, .is_adv_available = true, .mac_addr_type = SID_BLE_CFG_MAC_ADDRESS_TYPE_STATIC_RANDOM, diff --git a/subsys/sal/common/CMakeLists.txt b/subsys/sal/common/CMakeLists.txt index 61bf74755a..1eedcc5d14 100644 --- a/subsys/sal/common/CMakeLists.txt +++ b/subsys/sal/common/CMakeLists.txt @@ -9,3 +9,5 @@ zephyr_include_directories(sid_pal_ifc) zephyr_include_directories(sid_time_ops) add_subdirectory_ifdef(CONFIG_SIDEWALK_ON_DEV_CERT sid_on_dev_cert) + +zephyr_library_sources(sid_ifc/bt_app_callbacks.c) diff --git a/subsys/sal/common/sid_ifc/bt_app_callbacks.c b/subsys/sal/common/sid_ifc/bt_app_callbacks.c new file mode 100644 index 0000000000..ef6d79d6ab --- /dev/null +++ b/subsys/sal/common/sid_ifc/bt_app_callbacks.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +#include +#include +#include +#include + +static uint32_t bt_enable_count = 0; + +int app_bt_enable(bt_ready_cb_t cb) +{ + if (bt_enable_count == 0) { + int ret = bt_enable(cb); + if (ret == 0) { + bt_enable_count++; + } + return ret; + } + + bt_enable_count++; + if (cb) { + cb(0); + } + return 0; +} + +int app_bt_disable() +{ + if (bt_enable_count <= 0) { + bt_enable_count = 0; + return -EALREADY; + } + if (bt_enable_count == 1) { + bt_enable_count = 0; + return bt_disable(); + } else { + bt_enable_count--; + return 0; + } +} diff --git a/subsys/sal/common/sid_ifc/bt_app_callbacks.h b/subsys/sal/common/sid_ifc/bt_app_callbacks.h new file mode 100644 index 0000000000..5898f88e3b --- /dev/null +++ b/subsys/sal/common/sid_ifc/bt_app_callbacks.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef SID_PAL_APP_CALLBACKS_H +#define SID_PAL_APP_CALLBACKS_H + +#include +#include + +#if defined (CONFIG_BT_APP_IFC) + +/** + * @brief Wrapper for @bt_enable, with reference tracking. + * Real @bt_enable is called only of first call to app_bt_enable + * + * @param cb callback passed to @bt_enable + * @return int result from @bt_enable call or 0 if called multiple times + */ +int app_bt_enable(bt_ready_cb_t cb); + + +/** + * @brief Wrapper for @bt_disable. + * This function removes internal reference. + * If the internal reference counter shows 0, real @bt_disable is called + * + * @return int result from @bt_disable or 0 if app_bt_enable has been called more than app_bt_disable + */ +int app_bt_disable(); + + +/** + * @brief BT ids used for extended advertising. + * This allows to identify connections from different extended adverticements. + */ +enum BT_id_values{ + _BT_ID_DEFAULT = BT_ID_DEFAULT, + BT_ID_SIDEWALK, + #if defined (CONFIG_SIDEWALK_DFU) + BT_ID_SMP_DFU, + #endif + _BT_ID_MAX +}; + +BUILD_ASSERT(_BT_ID_MAX <= CONFIG_BT_ID_MAX, "Too many BT Ids! increase CONFIG_BT_ID_MAX, to match _BT_ID_MAX"); +#endif +#endif diff --git a/subsys/sal/sid_pal/include/sid_ble_advert.h b/subsys/sal/sid_pal/include/sid_ble_advert.h index 4e83ccb11b..65255850bc 100644 --- a/subsys/sal/sid_pal/include/sid_ble_advert.h +++ b/subsys/sal/sid_pal/include/sid_ble_advert.h @@ -9,6 +9,20 @@ #include +/** + * @brief Initialize Bluetooth Advertising. + * + * @return Zero on success or (negative) error code on failure. + */ +int sid_ble_advert_init(void); + +/** + * @brief Deinitialize Bluetooth Advertising. + * + * @return Zero on success or (negative) error code on failure. + */ +int sid_ble_advert_deinit(void); + /** * @brief Start Bluetooth advertising. * diff --git a/subsys/sal/sid_pal/src/sid_ble_adapter.c b/subsys/sal/sid_pal/src/sid_ble_adapter.c index c4ffad93d8..1bad31c8aa 100644 --- a/subsys/sal/sid_pal/src/sid_ble_adapter.c +++ b/subsys/sal/sid_pal/src/sid_ble_adapter.c @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -213,6 +214,27 @@ static sid_error_t ble_adapter_set_tx_pwr(int8_t tx_power) return SID_ERROR_NONE; } +static int create_ble_id(void) +{ + int ret; + size_t count = 0; + + /* Check if Bluetooth identites weren't already created. */ + bt_id_get(NULL, &count); + if (count > BT_ID_SIDEWALK) { + return 0; + } + + do { + ret = bt_id_create(NULL, NULL); + if (ret < 0) { + return ret; + } + } while (ret != BT_ID_SIDEWALK); + + return 0; +} + static sid_error_t ble_adapter_init(const sid_ble_config_t *cfg) { LOG_DBG("Sidewalk -> BLE"); @@ -220,7 +242,7 @@ static sid_error_t ble_adapter_init(const sid_ble_config_t *cfg) LOG_INF("Enable BT"); int err_code; - err_code = bt_enable(NULL); + err_code = app_bt_enable(NULL); switch (err_code) { case -EALREADY: case 0: @@ -231,6 +253,18 @@ static sid_error_t ble_adapter_init(const sid_ble_config_t *cfg) return SID_ERROR_GENERIC; } + err_code = create_ble_id(); + if (err_code) { + LOG_ERR("BT ID init failed (err: %d)", err_code); + return SID_ERROR_GENERIC; + } + + err_code = sid_ble_advert_init(); + if (err_code) { + LOG_ERR("BT Advertisement failed (err: %d)", err_code); + return SID_ERROR_GENERIC; + } + sid_ble_conn_init(); return SID_ERROR_NONE; @@ -404,8 +438,10 @@ static sid_error_t ble_adapter_deinit(void) { LOG_DBG("Sidewalk -> BLE"); sid_ble_conn_deinit(); - - int err = bt_disable(); + sid_ble_advert_deinit(); + bt_id_delete(BT_ID_SIDEWALK); + bt_id_reset(BT_ID_SIDEWALK, NULL, NULL); + int err = app_bt_disable(); if (err) { LOG_ERR("BT disable failed (error %d)", err); diff --git a/subsys/sal/sid_pal/src/sid_ble_advert.c b/subsys/sal/sid_pal/src/sid_ble_advert.c index 438631fee8..106f59e2fb 100644 --- a/subsys/sal/sid_pal/src/sid_ble_advert.c +++ b/subsys/sal/sid_pal/src/sid_ble_advert.c @@ -10,11 +10,13 @@ #include #include +#include #include #include #include #include +#include LOG_MODULE_REGISTER(sid_ble_advert, CONFIG_SIDEWALK_BLE_ADAPTER_LOG_LEVEL); @@ -36,17 +38,24 @@ LOG_MODULE_REGISTER(sid_ble_advert, CONFIG_SIDEWALK_BLE_ADAPTER_LOG_LEVEL); #endif /* Advertising parameters. */ -#define AMA_ADV_PARAM_FAST \ - BT_LE_ADV_PARAM(AMA_ADV_OPTIONS, MS_TO_INTERVAL_VAL(CONFIG_SIDEWALK_BLE_ADV_INT_FAST), \ - MS_TO_INTERVAL_VAL(CONFIG_SIDEWALK_BLE_ADV_INT_FAST + \ - CONFIG_SIDEWALK_BLE_ADV_INT_PRECISION), \ - NULL) - -#define AMA_ADV_PARAM_SLOW \ - BT_LE_ADV_PARAM(AMA_ADV_OPTIONS, MS_TO_INTERVAL_VAL(CONFIG_SIDEWALK_BLE_ADV_INT_SLOW), \ - MS_TO_INTERVAL_VAL(CONFIG_SIDEWALK_BLE_ADV_INT_SLOW + \ - CONFIG_SIDEWALK_BLE_ADV_INT_PRECISION), \ - NULL) +static struct bt_le_adv_param adv_param_fast = { + .id = BT_ID_SIDEWALK, + .options = (AMA_ADV_OPTIONS), + .interval_min = MS_TO_INTERVAL_VAL(CONFIG_SIDEWALK_BLE_ADV_INT_FAST), + .interval_max = MS_TO_INTERVAL_VAL(CONFIG_SIDEWALK_BLE_ADV_INT_FAST + + CONFIG_SIDEWALK_BLE_ADV_INT_PRECISION), +}; + +static struct bt_le_adv_param adv_param_slow = { + .id = BT_ID_SIDEWALK, + .options = (AMA_ADV_OPTIONS), + .interval_min = MS_TO_INTERVAL_VAL(CONFIG_SIDEWALK_BLE_ADV_INT_SLOW), + .interval_max = MS_TO_INTERVAL_VAL(CONFIG_SIDEWALK_BLE_ADV_INT_SLOW + + CONFIG_SIDEWALK_BLE_ADV_INT_PRECISION), +}; + +static struct bt_le_ext_adv *adv_set_fast = NULL; +static struct bt_le_ext_adv *adv_set_slow = NULL; /** * @brief Advertising data items values size in bytes. @@ -63,7 +72,7 @@ LOG_MODULE_REGISTER(sid_ble_advert, CONFIG_SIDEWALK_BLE_ADAPTER_LOG_LEVEL); enum adv_data_items { ADV_DATA_FLAGS, ADV_DATA_SERVICES, ADV_DATA_MANUF_DATA }; -typedef enum { BLE_ADV_DISABLE, BLE_ADV_ENABLE } sid_ble_adv_state_t; +typedef enum { BLE_ADV_DISABLE, BLE_ADV_FAST, BLE_ADV_SLOW } sid_ble_adv_state_t; static void change_advertisement_interval(struct k_work *); K_WORK_DELAYABLE_DEFINE(change_adv_work, change_advertisement_interval); @@ -103,28 +112,98 @@ static uint8_t advert_manuf_data_copy(uint8_t *data, uint8_t data_len) static void change_advertisement_interval(struct k_work *work) { ARG_UNUSED(work); - if (BLE_ADV_ENABLE == atomic_get(&adv_state)) { - if (bt_le_adv_stop()) { + + struct bt_le_ext_adv_start_param ext_adv_start_param = { 0 }; + + if (BLE_ADV_FAST == atomic_get(&adv_state)) { + int err = 0; + err = bt_le_ext_adv_stop(adv_set_fast); + if (err) { atomic_set(&adv_state, BLE_ADV_DISABLE); + LOG_ERR("Failed to stop fast adv errno %d (%s)", err, strerror(err)); return; } - if (bt_le_adv_start(AMA_ADV_PARAM_SLOW, adv_data, ARRAY_SIZE(adv_data), NULL, 0)) { + err = bt_le_ext_adv_set_data(adv_set_slow, adv_data, ARRAY_SIZE(adv_data), NULL, 0); + if (err) { atomic_set(&adv_state, BLE_ADV_DISABLE); + LOG_ERR("Failed to set adv data to slow adv errno %d (%s)", err, + strerror(err)); return; } + err = bt_le_ext_adv_start(adv_set_slow, &ext_adv_start_param); + if (err) { + atomic_set(&adv_state, BLE_ADV_DISABLE); + LOG_ERR("Failed to start slow adv errno %d (%s)", err, strerror(err)); + return; + } + + atomic_set(&adv_state, BLE_ADV_SLOW); + LOG_DBG("BLE -> BLE"); } } +int sid_ble_advert_init(void) +{ + int ret; + if (adv_set_fast == NULL) { + ret = bt_le_ext_adv_create(&adv_param_fast, NULL, &adv_set_fast); + if (ret) { + LOG_ERR("Failed to create fast advertising set errno %d (%s)", ret, + strerror(ret)); + return ret; + } + } + + if (adv_set_slow == NULL) { + ret = bt_le_ext_adv_create(&adv_param_slow, NULL, &adv_set_slow); + if (ret) { + LOG_ERR("Failed to create slow advertising set errno %d (%s)", ret, + strerror(ret)); + return ret; + } + } + + return 0; +} + +int sid_ble_advert_deinit(void) +{ + int err = bt_le_ext_adv_delete(adv_set_fast); + if (err) { + LOG_ERR("Failed to delete adv_set_fast errno %d (%s)", err, strerror(err)); + return err; + } + adv_set_fast = NULL; + err = bt_le_ext_adv_delete(adv_set_slow); + if (err) { + LOG_ERR("Failed to delete adv_set_slow errno %d (%s)", err, strerror(err)); + return err; + } + adv_set_slow = NULL; + return 0; +} + int sid_ble_advert_start(void) { k_work_reschedule(&change_adv_work, K_SECONDS(CONFIG_SIDEWALK_BLE_ADV_INT_TRANSITION)); - int err = bt_le_adv_start(AMA_ADV_PARAM_FAST, adv_data, ARRAY_SIZE(adv_data), NULL, 0); + struct bt_le_ext_adv_start_param ext_adv_start_param = { 0 }; + int err = 0; + + err = bt_le_ext_adv_set_data(adv_set_fast, adv_data, ARRAY_SIZE(adv_data), NULL, 0); if (err) { + LOG_ERR("Failed to set adv data errno: %d (%s)", err, strerror(err)); return err; } - atomic_set(&adv_state, BLE_ADV_ENABLE); + + err = bt_le_ext_adv_start(adv_set_fast, &ext_adv_start_param); + if (err) { + LOG_ERR("Failed to start adv errno: %d (%s)", err, strerror(err)); + return err; + } + + atomic_set(&adv_state, BLE_ADV_FAST); return err; } @@ -132,7 +211,8 @@ int sid_ble_advert_start(void) int sid_ble_advert_stop(void) { k_work_cancel_delayable(&change_adv_work); - int err = bt_le_adv_stop(); + int err = bt_le_ext_adv_stop(atomic_get(&adv_state) == BLE_ADV_FAST ? adv_set_fast : + adv_set_slow); if (0 == err) { atomic_set(&adv_state, BLE_ADV_DISABLE); @@ -143,6 +223,8 @@ int sid_ble_advert_stop(void) int sid_ble_advert_update(uint8_t *data, uint8_t data_len) { + sid_ble_adv_state_t state = atomic_get(&adv_state); + if (!data || 0 == data_len) { return -EINVAL; } @@ -151,8 +233,10 @@ int sid_ble_advert_update(uint8_t *data, uint8_t data_len) int err = 0; - if (BLE_ADV_ENABLE == atomic_get(&adv_state)) { - err = bt_le_adv_update_data(adv_data, ARRAY_SIZE(adv_data), NULL, 0); + if (BLE_ADV_DISABLE != state) { + /* Update currently advertised set, the other one will be set on start/transition */ + err = bt_le_ext_adv_set_data((state == BLE_ADV_FAST ? adv_set_fast : adv_set_slow), + adv_data, ARRAY_SIZE(adv_data), NULL, 0); } return err; diff --git a/subsys/sal/sid_pal/src/sid_ble_connection.c b/subsys/sal/sid_pal/src/sid_ble_connection.c index 2ad4edbe5c..3e5a988703 100644 --- a/subsys/sal/sid_pal/src/sid_ble_connection.c +++ b/subsys/sal/sid_pal/src/sid_ble_connection.c @@ -13,6 +13,7 @@ #include #include +#include #include K_MUTEX_DEFINE(bt_conn_mutex); @@ -33,6 +34,17 @@ static struct bt_conn_cb conn_callbacks = { static struct bt_gatt_cb gatt_callbacks = { .att_mtu_updated = ble_mtu_cb }; +static bool should_handle_event(struct bt_conn *conn) +{ + struct bt_conn_info conn_info = {}; + + if (!conn || bt_conn_get_info(conn, &conn_info) || conn_info.id != BT_ID_SIDEWALK) { + return false; + } + + return true; +} + /** * @brief The function is called when a new connection is established. * @@ -41,12 +53,18 @@ static struct bt_gatt_cb gatt_callbacks = { .att_mtu_updated = ble_mtu_cb }; */ static void ble_connect_cb(struct bt_conn *conn, uint8_t err) { + const bt_addr_le_t *bt_addr_le; + + if (!should_handle_event(conn)) { + return; + } + if (err) { LOG_ERR("Connection failed (err %u)\n", err); return; } - const bt_addr_le_t *bt_addr_le = bt_conn_get_dst(conn); + bt_addr_le = bt_conn_get_dst(conn); if (bt_addr_le) { memcpy(conn_params.addr, bt_addr_le->a.val, BT_ADDR_SIZE); @@ -72,10 +90,10 @@ static void ble_connect_cb(struct bt_conn *conn, uint8_t err) */ static void ble_disconnect_cb(struct bt_conn *conn, uint8_t reason) { - if (!conn || conn_params.conn != conn) { - LOG_WRN("Unknow connection"); + if (!should_handle_event(conn) || conn_params.conn != conn) { return; } + sid_ble_adapter_conn_disconnected((const uint8_t *)conn_params.addr); k_mutex_lock(&bt_conn_mutex, K_FOREVER); diff --git a/subsys/sal/sid_pal/src/sid_storage.c b/subsys/sal/sid_pal/src/sid_storage.c index e5dc826e8d..3619a61abb 100644 --- a/subsys/sal/sid_pal/src/sid_storage.c +++ b/subsys/sal/sid_pal/src/sid_storage.c @@ -219,7 +219,8 @@ sid_error_t sid_pal_storage_kv_record_delete(uint16_t group, uint16_t key) #ifdef CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE psa_key_id_t key_id = storage2key_id(group, key); if (SID_CRYPTO_KEYS_ID_IS_SIDEWALK_KEY(key_id)) { - return storage_key_delete_secure(key_id) ? SID_ERROR_NONE : SID_ERROR_STORAGE_ERASE_FAIL; + return storage_key_delete_secure(key_id) ? SID_ERROR_NONE : + SID_ERROR_STORAGE_ERASE_FAIL; } #endif /* CONFIG_SIDEWALK_CRYPTO_PSA_KEY_STORAGE */ diff --git a/tests/unit_tests/pal_ble_adapter/Kconfig b/tests/unit_tests/pal_ble_adapter/Kconfig index 062cbec5f7..2fd294e7d8 100644 --- a/tests/unit_tests/pal_ble_adapter/Kconfig +++ b/tests/unit_tests/pal_ble_adapter/Kconfig @@ -31,4 +31,10 @@ config SIDEWALK_LOG_LEVEL config SIDEWALK_BLE_ADAPTER_LOG_LEVEL default 0 +config BT_APP_IFC + default y + +config BT_ID_MAX + default 2 + source "Kconfig.zephyr" diff --git a/tests/unit_tests/pal_ble_adapter/src/main.c b/tests/unit_tests/pal_ble_adapter/src/main.c index 72bfbcc60b..e682840263 100644 --- a/tests/unit_tests/pal_ble_adapter/src/main.c +++ b/tests/unit_tests/pal_ble_adapter/src/main.c @@ -18,11 +18,16 @@ #include #include #include +#include #include DEFINE_FFF_GLOBALS; - +FAKE_VALUE_FUNC(int, bt_le_ext_adv_stop, struct bt_le_ext_adv *); +FAKE_VALUE_FUNC(int, bt_le_ext_adv_set_data, struct bt_le_ext_adv *, const struct bt_data *, size_t, + const struct bt_data *, size_t); +FAKE_VALUE_FUNC(int, bt_le_ext_adv_start, struct bt_le_ext_adv *, + const struct bt_le_ext_adv_start_param *); FAKE_VALUE_FUNC(int, bt_enable, bt_ready_cb_t); FAKE_VALUE_FUNC(int, bt_disable); FAKE_VALUE_FUNC(int, bt_le_adv_start, const struct bt_le_adv_param *, const struct bt_data *, @@ -41,6 +46,10 @@ FAKE_VALUE_FUNC(ssize_t, bt_gatt_attr_read_ccc, struct bt_conn *, const struct b void *, uint16_t, uint16_t); FAKE_VALUE_FUNC(ssize_t, bt_gatt_attr_write_ccc, struct bt_conn *, const struct bt_gatt_attr *, const void *, uint16_t, uint16_t, uint8_t); +FAKE_VOID_FUNC(bt_id_get, bt_addr_le_t *, size_t *); +FAKE_VALUE_FUNC(int, bt_id_create, bt_addr_le_t *, uint8_t *); +FAKE_VALUE_FUNC(int, bt_id_reset, uint8_t, bt_addr_le_t *, uint8_t *); +FAKE_VALUE_FUNC(int, bt_id_delete, uint8_t); FAKE_VALUE_FUNC(struct net_buf *, bt_hci_cmd_create, uint16_t, uint8_t); FAKE_VALUE_FUNC(int, bt_hci_cmd_send_sync, uint16_t, struct net_buf *, struct net_buf **); @@ -48,6 +57,7 @@ FAKE_VALUE_FUNC(int, bt_hci_cmd_send_sync, uint16_t, struct net_buf *, struct ne FAKE_VALUE_FUNC(int, bt_hci_get_conn_handle, const struct bt_conn *, uint16_t *); FAKE_VALUE_FUNC(void *, net_buf_simple_add, struct net_buf_simple *, size_t); FAKE_VOID_FUNC(net_buf_unref, struct net_buf *); +FAKE_VALUE_FUNC(int, bt_conn_get_info, const struct bt_conn *, struct bt_conn_info *); #define FFF_FAKES_LIST(FAKE) \ FAKE(bt_enable) \ @@ -58,6 +68,10 @@ FAKE_VOID_FUNC(net_buf_unref, struct net_buf *); FAKE(bt_conn_ref) \ FAKE(bt_conn_unref) \ FAKE(bt_conn_get_dst) \ + FAKE(bt_id_get) \ + FAKE(bt_id_create) \ + FAKE(bt_id_reset) \ + FAKE(bt_id_delete) \ FAKE(bt_gatt_attr_read_service) \ FAKE(bt_gatt_attr_read_chrc) \ FAKE(bt_gatt_attr_read_ccc) \ @@ -66,7 +80,11 @@ FAKE_VOID_FUNC(net_buf_unref, struct net_buf *); FAKE(bt_hci_cmd_send_sync) \ FAKE(bt_hci_get_conn_handle) \ FAKE(net_buf_simple_add) \ - FAKE(net_buf_unref) + FAKE(net_buf_unref) \ + FAKE(bt_le_ext_adv_stop) \ + FAKE(bt_le_ext_adv_set_data) \ + FAKE(bt_le_ext_adv_start) \ + FAKE(bt_conn_get_info) #define ESUCCESS (0) #define FAKE_SERVICE (9) @@ -91,11 +109,13 @@ void setUp(void) FFF_RESET_HISTORY(); memset(&data_cb_test, 0x00, sizeof(data_cb_test)); cmock_sid_ble_adapter_callbacks_Init(); + cmock_sid_ble_advert_Init(); } void tearDown(void) { cmock_sid_ble_adapter_callbacks_Verify(); + cmock_sid_ble_advert_Verify(); } static void ble_data_callback(sid_ble_cfg_service_identifier_t id, uint8_t *data, uint16_t length) @@ -155,11 +175,15 @@ void test_sid_pal_ble_adapter_init(void) TEST_ASSERT_EQUAL(SID_ERROR_NONE, sid_pal_ble_adapter_create(&p_test_ble_ifc)); + bt_id_create_fake.return_val = BT_ID_SIDEWALK; __cmock_sid_ble_conn_init_Expect(); + __cmock_sid_ble_advert_init_IgnoreAndReturn(0); TEST_ASSERT_EQUAL(SID_ERROR_NONE, p_test_ble_ifc->init(&test_ble_cfg)); + app_bt_disable(); __cmock_sid_ble_conn_init_Expect(); TEST_ASSERT_EQUAL(SID_ERROR_NONE, p_test_ble_ifc->init(NULL)); + app_bt_disable(); bt_enable_fake.return_val = -ENOENT; TEST_ASSERT_EQUAL(SID_ERROR_GENERIC, p_test_ble_ifc->init(&test_ble_cfg)); @@ -172,9 +196,12 @@ void test_sid_pal_ble_adapter_deinit(void) TEST_ASSERT_EQUAL(SID_ERROR_NONE, sid_pal_ble_adapter_create(&p_test_ble_ifc)); __cmock_settings_load_ExpectAndReturn(ESUCCESS); __cmock_sid_ble_conn_init_Expect(); + bt_id_create_fake.return_val = BT_ID_SIDEWALK; + __cmock_sid_ble_advert_init_IgnoreAndReturn(0); TEST_ASSERT_EQUAL(SID_ERROR_NONE, p_test_ble_ifc->init(&test_ble_cfg)); __cmock_sid_ble_conn_deinit_Expect(); + __cmock_sid_ble_advert_deinit_IgnoreAndReturn(0); TEST_ASSERT_EQUAL(SID_ERROR_NONE, p_test_ble_ifc->deinit()); } diff --git a/tests/unit_tests/sid_ble_advert/Kconfig b/tests/unit_tests/sid_ble_advert/Kconfig index 5b1ee8f4a4..a1fb4da783 100644 --- a/tests/unit_tests/sid_ble_advert/Kconfig +++ b/tests/unit_tests/sid_ble_advert/Kconfig @@ -9,6 +9,12 @@ config SIDEWALK_BUILD config SIDEWALK_LOG_LEVEL default 0 +config BT_ID_MAX + default 2 + +config BT_APP_IFC + default y + module = SIDEWALK_BLE_ADAPTER module-str = Sidewalk BLE interface source "${ZEPHYR_BASE}/subsys/logging/Kconfig.template.log_config" @@ -20,7 +26,7 @@ config SIDEWALK_BLE_ADV_INT_PRECISION config SIDEWALK_BLE_ADV_INT_FAST int "test value for Sidewalk configuration macro" default 160 - + config SIDEWALK_BLE_ADV_INT_SLOW int "test value for Sidewalk configuration macro" default 1000 diff --git a/tests/unit_tests/sid_ble_advert/src/main.c b/tests/unit_tests/sid_ble_advert/src/main.c index d77d19dd91..73cebe7ef5 100644 --- a/tests/unit_tests/sid_ble_advert/src/main.c +++ b/tests/unit_tests/sid_ble_advert/src/main.c @@ -15,16 +15,16 @@ DEFINE_FFF_GLOBALS; -FAKE_VALUE_FUNC(int, bt_le_adv_start, const struct bt_le_adv_param *, const struct bt_data *, - size_t, const struct bt_data *, size_t); -FAKE_VALUE_FUNC(int, bt_le_adv_stop); -FAKE_VALUE_FUNC(int, bt_le_adv_update_data, const struct bt_data *, size_t, const struct bt_data *, - size_t); +FAKE_VALUE_FUNC(int, bt_le_ext_adv_start, struct bt_le_ext_adv *, + const struct bt_le_ext_adv_start_param *); +FAKE_VALUE_FUNC(int, bt_le_ext_adv_stop, struct bt_le_ext_adv *); +FAKE_VALUE_FUNC(int, bt_le_ext_adv_set_data, struct bt_le_ext_adv *, const struct bt_data *, size_t, + const struct bt_data *, size_t); #define FFF_FAKES_LIST(FAKE) \ - FAKE(bt_le_adv_start) \ - FAKE(bt_le_adv_stop) \ - FAKE(bt_le_adv_update_data) + FAKE(bt_le_ext_adv_start) \ + FAKE(bt_le_ext_adv_stop) \ + FAKE(bt_le_ext_adv_set_data) #define ESUCCESS (0) #define TEST_BUFFER_LEN (100) @@ -40,30 +40,30 @@ void test_sid_ble_advert_start(void) { size_t adv_start_call_count = 0; - bt_le_adv_start_fake.return_val = ESUCCESS; + bt_le_ext_adv_start_fake.return_val = ESUCCESS; TEST_ASSERT_EQUAL(ESUCCESS, sid_ble_advert_start()); adv_start_call_count++; - TEST_ASSERT_EQUAL(adv_start_call_count, bt_le_adv_start_fake.call_count); + TEST_ASSERT_EQUAL(adv_start_call_count, bt_le_ext_adv_start_fake.call_count); - bt_le_adv_start_fake.return_val = -ENOENT; + bt_le_ext_adv_start_fake.return_val = -ENOENT; TEST_ASSERT_EQUAL(-ENOENT, sid_ble_advert_start()); adv_start_call_count++; - TEST_ASSERT_EQUAL(adv_start_call_count, bt_le_adv_start_fake.call_count); + TEST_ASSERT_EQUAL(adv_start_call_count, bt_le_ext_adv_start_fake.call_count); } void test_sid_ble_advert_stop(void) { size_t adv_stop_call_count = 0; - bt_le_adv_stop_fake.return_val = ESUCCESS; + bt_le_ext_adv_stop_fake.return_val = ESUCCESS; TEST_ASSERT_EQUAL(ESUCCESS, sid_ble_advert_stop()); adv_stop_call_count++; - TEST_ASSERT_EQUAL(adv_stop_call_count, bt_le_adv_stop_fake.call_count); + TEST_ASSERT_EQUAL(adv_stop_call_count, bt_le_ext_adv_stop_fake.call_count); - bt_le_adv_stop_fake.return_val = -ENOENT; + bt_le_ext_adv_stop_fake.return_val = -ENOENT; TEST_ASSERT_EQUAL(-ENOENT, sid_ble_advert_stop()); adv_stop_call_count++; - TEST_ASSERT_EQUAL(adv_stop_call_count, bt_le_adv_stop_fake.call_count); + TEST_ASSERT_EQUAL(adv_stop_call_count, bt_le_ext_adv_stop_fake.call_count); } void test_sid_ble_advert_update(void) @@ -71,19 +71,20 @@ void test_sid_ble_advert_update(void) uint8_t test_data[] = "Lorem ipsum."; size_t adv_update_call_count = 0; - bt_le_adv_start_fake.return_val = ESUCCESS; - bt_le_adv_update_data_fake.return_val = ESUCCESS; + bt_le_ext_adv_start_fake.return_val = ESUCCESS; + bt_le_ext_adv_set_data_fake.return_val = ESUCCESS; TEST_ASSERT_EQUAL(ESUCCESS, sid_ble_advert_start()); + adv_update_call_count++; TEST_ASSERT_EQUAL(ESUCCESS, sid_ble_advert_update(test_data, sizeof(test_data))); adv_update_call_count++; - TEST_ASSERT_EQUAL(adv_update_call_count, bt_le_adv_update_data_fake.call_count); + TEST_ASSERT_EQUAL(adv_update_call_count, bt_le_ext_adv_set_data_fake.call_count); - bt_le_adv_update_data_fake.return_val = -ENOENT; + bt_le_ext_adv_set_data_fake.return_val = -ENOENT; TEST_ASSERT_EQUAL(-ENOENT, sid_ble_advert_update(test_data, sizeof(test_data))); adv_update_call_count++; - TEST_ASSERT_EQUAL(adv_update_call_count, bt_le_adv_update_data_fake.call_count); + TEST_ASSERT_EQUAL(adv_update_call_count, bt_le_ext_adv_set_data_fake.call_count); - bt_le_adv_update_data_fake.return_val = ESUCCESS; + bt_le_ext_adv_set_data_fake.return_val = ESUCCESS; TEST_ASSERT_EQUAL(-EINVAL, sid_ble_advert_update(NULL, sizeof(test_data))); TEST_ASSERT_EQUAL(-EINVAL, sid_ble_advert_update(test_data, 0)); } @@ -94,12 +95,12 @@ void test_sid_ble_advert_update_in_every_state(void) TEST_ASSERT_EQUAL(ESUCCESS, sid_ble_advert_update(test_data, sizeof(test_data))); - bt_le_adv_start_fake.return_val = ESUCCESS; - bt_le_adv_update_data_fake.return_val = ESUCCESS; + bt_le_ext_adv_start_fake.return_val = ESUCCESS; + bt_le_ext_adv_set_data_fake.return_val = ESUCCESS; TEST_ASSERT_EQUAL(ESUCCESS, sid_ble_advert_start()); TEST_ASSERT_EQUAL(ESUCCESS, sid_ble_advert_update(test_data, sizeof(test_data))); - bt_le_adv_stop_fake.return_val = ESUCCESS; + bt_le_ext_adv_stop_fake.return_val = ESUCCESS; TEST_ASSERT_EQUAL(ESUCCESS, sid_ble_advert_stop()); TEST_ASSERT_EQUAL(ESUCCESS, sid_ble_advert_update(test_data, sizeof(test_data))); } @@ -130,17 +131,17 @@ void test_sid_ble_advert_update_before_start(void) size_t advert_data_size; bool found; - bt_le_adv_stop_fake.return_val = ESUCCESS; + bt_le_ext_adv_stop_fake.return_val = ESUCCESS; TEST_ASSERT_EQUAL(ESUCCESS, sid_ble_advert_stop()); - bt_le_adv_update_data_fake.return_val = ESUCCESS; + bt_le_ext_adv_set_data_fake.return_val = ESUCCESS; TEST_ASSERT_EQUAL(ESUCCESS, sid_ble_advert_update(test_data, sizeof(test_data))); - bt_le_adv_start_fake.return_val = ESUCCESS; + bt_le_ext_adv_start_fake.return_val = ESUCCESS; TEST_ASSERT_EQUAL(ESUCCESS, sid_ble_advert_start()); - advert_data = bt_le_adv_start_fake.arg1_val; - advert_data_size = bt_le_adv_start_fake.arg2_val; + advert_data = bt_le_ext_adv_set_data_fake.arg1_val; + advert_data_size = bt_le_ext_adv_set_data_fake.arg2_val; TEST_ASSERT_NOT_NULL(advert_data); TEST_ASSERT_GREATER_THAN_size_t(0, advert_data_size); @@ -159,13 +160,13 @@ void check_sid_ble_advert_update(uint8_t *data, uint8_t data_len) size_t advert_data_size; bool found; - bt_le_adv_start_fake.return_val = ESUCCESS; - bt_le_adv_update_data_fake.return_val = ESUCCESS; + bt_le_ext_adv_start_fake.return_val = ESUCCESS; + bt_le_ext_adv_set_data_fake.return_val = ESUCCESS; TEST_ASSERT_EQUAL(ESUCCESS, sid_ble_advert_start()); TEST_ASSERT_EQUAL(ESUCCESS, sid_ble_advert_update(data, data_len)); - advert_data = bt_le_adv_update_data_fake.arg0_val; - advert_data_size = bt_le_adv_update_data_fake.arg1_val; + advert_data = bt_le_ext_adv_set_data_fake.arg1_val; + advert_data_size = bt_le_ext_adv_set_data_fake.arg2_val; TEST_ASSERT_NOT_NULL(advert_data); TEST_ASSERT_GREATER_THAN_size_t(0, advert_data_size); diff --git a/tests/unit_tests/sid_ble_connection/Kconfig b/tests/unit_tests/sid_ble_connection/Kconfig index 50ffb0aeed..cb92a98f62 100644 --- a/tests/unit_tests/sid_ble_connection/Kconfig +++ b/tests/unit_tests/sid_ble_connection/Kconfig @@ -12,4 +12,10 @@ config SIDEWALK_LOG_LEVEL config SIDEWALK_BLE_ADAPTER_LOG_LEVEL default 0 +config BT_ID_MAX + default 2 + +config BT_APP_IFC + default y + source "Kconfig.zephyr" diff --git a/tests/unit_tests/sid_ble_connection/src/main.c b/tests/unit_tests/sid_ble_connection/src/main.c index d119a2ed07..3b09bb3a42 100644 --- a/tests/unit_tests/sid_ble_connection/src/main.c +++ b/tests/unit_tests/sid_ble_connection/src/main.c @@ -15,6 +15,7 @@ #include #include +#include DEFINE_FFF_GLOBALS; @@ -24,6 +25,7 @@ FAKE_VALUE_FUNC(struct bt_conn *, bt_conn_ref, struct bt_conn *); FAKE_VOID_FUNC(bt_conn_unref, struct bt_conn *); FAKE_VALUE_FUNC(const bt_addr_le_t *, bt_conn_get_dst, const struct bt_conn *); FAKE_VALUE_FUNC(int, bt_conn_disconnect, struct bt_conn *, uint8_t); +FAKE_VALUE_FUNC(int, bt_conn_get_info, const struct bt_conn *, struct bt_conn_info *); #define FFF_FAKES_LIST(FAKE) \ FAKE(bt_conn_cb_register) \ @@ -31,7 +33,8 @@ FAKE_VALUE_FUNC(int, bt_conn_disconnect, struct bt_conn *, uint8_t); FAKE(bt_conn_ref) \ FAKE(bt_conn_unref) \ FAKE(bt_conn_get_dst) \ - FAKE(bt_conn_disconnect) + FAKE(bt_conn_disconnect) \ + FAKE(bt_conn_get_info) #define CONNECTED (true) #define DISCONNECTED (false) @@ -102,6 +105,12 @@ void test_sid_ble_conn_params_get(void) TEST_ASSERT_NULL(params); } +int bt_conn_get_info_fake1(const struct bt_conn *a, struct bt_conn_info *b) +{ + b->id = BT_ID_SIDEWALK; + return 0; +} + void test_sid_ble_conn_positive(void) { uint8_t test_no_error = BT_HCI_ERR_SUCCESS; @@ -115,6 +124,9 @@ void test_sid_ble_conn_positive(void) bt_conn_get_dst_fake.return_val = &test_addr; bt_conn_ref_fake.return_val = &test_conn; + int (*custom_fakes[])(const struct bt_conn *, + struct bt_conn_info *) = { bt_conn_get_info_fake1 }; + SET_CUSTOM_FAKE_SEQ(bt_conn_get_info, custom_fakes, 1); sid_ble_conn_deinit(); sid_ble_conn_init(); @@ -143,6 +155,9 @@ void test_sid_ble_set_conn_cb_positive(void) bt_conn_get_dst_fake.return_val = &test_addr; bt_conn_ref_fake.return_val = &test_conn; + int (*custom_fakes[])(const struct bt_conn *, + struct bt_conn_info *) = { bt_conn_get_info_fake1 }; + SET_CUSTOM_FAKE_SEQ(bt_conn_get_info, custom_fakes, 1); sid_ble_conn_init(); __cmock_sid_ble_adapter_conn_connected_StubWithCallback(connection_callback); @@ -173,6 +188,9 @@ void test_sid_ble_conn_cb_set_call_count(void) bt_conn_get_dst_fake.return_val = &test_addr; bt_conn_ref_fake.return_val = &test_conn; + int (*custom_fakes[])(const struct bt_conn *, + struct bt_conn_info *) = { bt_conn_get_info_fake1 }; + SET_CUSTOM_FAKE_SEQ(bt_conn_get_info, custom_fakes, 1); sid_ble_conn_init(); __cmock_sid_ble_adapter_conn_connected_StubWithCallback(connection_callback); @@ -208,6 +226,9 @@ void test_sid_ble_disconnected_wrong_conn(void) bt_conn_get_dst_fake.return_val = &test_addr; bt_conn_ref_fake.return_val = &test_conn; + int (*custom_fakes[])(const struct bt_conn *, + struct bt_conn_info *) = { bt_conn_get_info_fake1 }; + SET_CUSTOM_FAKE_SEQ(bt_conn_get_info, custom_fakes, 1); sid_ble_conn_init(); __cmock_sid_ble_adapter_conn_connected_StubWithCallback(connection_callback); @@ -233,6 +254,9 @@ void test_sid_ble_cb_set_before_init(void) struct bt_conn test_conn = { .dummy = 0xDC }; bt_conn_ref_fake.return_val = &test_conn; + int (*custom_fakes[])(const struct bt_conn *, + struct bt_conn_info *) = { bt_conn_get_info_fake1 }; + SET_CUSTOM_FAKE_SEQ(bt_conn_get_info, custom_fakes, 1); sid_ble_conn_deinit(); sid_ble_conn_init(); @@ -269,6 +293,9 @@ void test_sid_ble_conn_mtu_callback_curent_connection(void) sid_ble_conn_init(); bt_conn_ref_fake.return_val = &curr_conn; + int (*custom_fakes[])(const struct bt_conn *, + struct bt_conn_info *) = { bt_conn_get_info_fake1 }; + SET_CUSTOM_FAKE_SEQ(bt_conn_get_info, custom_fakes, 1); __cmock_sid_ble_adapter_conn_connected_ExpectAnyArgs(); sid_bt_conn_cb->connected(&curr_conn, 0); diff --git a/utils/sidewalk_dfu/nordic_dfu.c b/utils/sidewalk_dfu/nordic_dfu.c index 6f1c2402c8..00114dddd8 100644 --- a/utils/sidewalk_dfu/nordic_dfu.c +++ b/utils/sidewalk_dfu/nordic_dfu.c @@ -7,11 +7,14 @@ #include #include #include +#include #include +#include #include #include #include #include +#include #include LOG_MODULE_REGISTER(nordic_dfu, CONFIG_SIDEWALK_LOG_LEVEL); @@ -19,6 +22,19 @@ LOG_MODULE_REGISTER(nordic_dfu, CONFIG_SIDEWALK_LOG_LEVEL); #define LED_PERIOD_TOGGLE_ALL 500 #define LED_PERIOD_LOADING_WHEEL 150 +static void pending_adv_start(struct k_work *work); +static struct bt_le_ext_adv *adv = NULL; +static struct bt_le_ext_adv_start_param ext_adv_param = { .num_events = 0, .timeout = 0 }; +static struct k_work_delayable adv_work = Z_WORK_DELAYABLE_INITIALIZER(pending_adv_start); + +static struct bt_le_adv_param adv_params = { .id = BT_ID_DEFAULT, + .sid = 0, + .secondary_max_skip = 0, + .options = BT_LE_ADV_OPT_CONNECTABLE, + .interval_min = BT_GAP_ADV_SLOW_INT_MIN, + .interval_max = BT_GAP_ADV_SLOW_INT_MAX, + .peer = NULL }; + static const struct bt_data ad[] = { BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), BT_DATA_BYTES(BT_DATA_UUID128_ALL, 0x84, 0xaa, 0x60, 0x74, 0x52, 0x8a, 0x8b, 0x86, 0xd3, @@ -37,6 +53,27 @@ static enum led_status_e { static struct k_timer led_timer; static struct k_timer exit_timer; +static int create_ble_id(void) +{ + int ret; + size_t count = 0; + + /* Check if Bluetooth identites weren't already created. */ + bt_id_get(NULL, &count); + if (count > BT_ID_SMP_DFU) { + return 0; + } + + do { + ret = bt_id_create(NULL, NULL); + if (ret < 0) { + return ret; + } + } while (ret != BT_ID_SMP_DFU); + + return BT_ID_DEFAULT; +} + static void led_action(struct k_timer *timer_id) { switch (led_status) { @@ -63,10 +100,52 @@ static void led_action(struct k_timer *timer_id) static void exit_dfu_mode(struct k_timer *timer_id) { - LOG_ERR("DFU did not start or could not complete. Reset to exit dfu mode"); - sys_reboot(SYS_REBOOT_COLD); + LOG_ERR("DFU did not start or could not complete. Exit dfu mode"); +} + +static void connected(struct bt_conn *conn, uint8_t err) +{ + struct bt_conn_info cinfo; + int ec; + + ec = bt_conn_get_info(conn, &cinfo); + if (ec) { + printk("Unable to get connection info (err %d)\n", ec); + return; + } + + if (cinfo.id != adv_params.id) { + return; + } + + printk("Connected to SMP service: err %d id %d\n", err, cinfo.id); } +static void disconnected(struct bt_conn *conn, uint8_t reason) +{ + int err; + struct bt_conn_info cinfo; + + err = bt_conn_get_info(conn, &cinfo); + if (err) { + printk("Unable to get connection info (err %d)\n", err); + return; + } + + if (cinfo.id != adv_params.id) { + return; + } + + printk("Disconnected from SMP service: reason %d id %d\n", reason, cinfo.id); + + k_work_schedule(&adv_work, K_NO_WAIT); +} + +static struct bt_conn_cb conn_callbacks = { + .connected = connected, + .disconnected = disconnected, +}; + static enum mgmt_cb_return dfu_mode_cb(uint32_t event, enum mgmt_cb_return prev_status, int32_t *rc, uint16_t *group, bool *abort_more, void *data, size_t data_size) @@ -110,6 +189,19 @@ static struct mgmt_callback dfu_mode_mgmt_cb = { MGMT_EVT_OP_IMG_MGMT_DFU_PENDING | MGMT_EVT_OP_IMG_MGMT_DFU_CHUNK, }; +static void pending_adv_start(struct k_work *work) +{ + int err; + + err = bt_le_ext_adv_start(adv, &ext_adv_param); + if (err) { + printk("Unable to restart SMP service advertising (err %d)\n", err); + return; + } + + printk("SMP service advertising restarted\n"); +} + int nordic_dfu_ble_start(void) { LOG_INF("Entering into DFU mode"); @@ -117,17 +209,34 @@ int nordic_dfu_ble_start(void) application_state_dfu(&global_state_notifier, true); dk_leds_init(); - int err = bt_enable(NULL); + int err = app_bt_enable(NULL); if (err && err != -EALREADY) { - LOG_ERR("Bluetooth enable failed (err %d)", err); + LOG_ERR("Bluetooth enable failed (err %d %s)", err, strerror(err)); return err; } + bt_conn_cb_register(&conn_callbacks); mgmt_callback_register(&dfu_mode_mgmt_cb); + int ret = create_ble_id(); + if (ret < 0) { + LOG_ERR("Failed to create BLE ID errno %d %s", ret, strerror(ret)); + return err; + } - err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd)); + adv_params.id = BT_ID_SMP_DFU; + err = bt_le_ext_adv_create(&adv_params, NULL, &adv); + if (err) { + LOG_ERR("Bluetooth advertising create failed (err %d %s)", err, strerror(err)); + return err; + } + err = bt_le_ext_adv_set_data(adv, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd)); if (err) { - LOG_ERR("Bluetooth advertising start failed (err %d)", err); + LOG_ERR("Bluetooth advertising data set failed (err %d %s)", err, strerror(err)); + return err; + } + err = bt_le_ext_adv_start(adv, &ext_adv_param); + if (err) { + LOG_ERR("Bluetooth advertising start failed (err %d %s)", err, strerror(err)); return err; } @@ -147,17 +256,24 @@ int nordic_dfu_ble_stop(void) { LOG_INF("Exiting DFU mode"); + bt_conn_cb_unregister(&conn_callbacks); mgmt_callback_unregister(&dfu_mode_mgmt_cb); - int err = bt_le_adv_stop(); + int err = bt_le_ext_adv_stop(adv); + if (err) { + LOG_ERR("Bluetooth advertising stop failed (err %d %s)", err, strerror(err)); + return err; + } + err = bt_le_ext_adv_delete(adv); if (err) { - LOG_ERR("Bluetooth advertising stop failed (err %d)", err); + LOG_ERR("Bluetooth advertising delete failed (err %d %s)", err, strerror(err)); return err; } + adv = NULL; - err = bt_disable(); + err = app_bt_disable(); if (err) { - LOG_ERR("Bluetooth disable failed (err %d)", err); + LOG_ERR("Bluetooth disable failed (err %d %s)", err, strerror(err)); return err; }