Skip to content

Commit

Permalink
ble: stop adv when connected
Browse files Browse the repository at this point in the history
prevent calling change_adv_work when already connected

Signed-off-by: Robert Gałat <[email protected]>
  • Loading branch information
RobertGalatNordic committed Nov 21, 2024
1 parent 0438cd7 commit b7e3e6b
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 47 deletions.
4 changes: 2 additions & 2 deletions samples/sid_end_device/Kconfig.defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ config BT_PERIPHERAL_PREF_TIMEOUT
default 400

config BT_EXT_ADV_MAX_ADV_SET
default 3 if SIDEWALK_DFU
default 2
default 2 if SIDEWALK_DFU
default 1

config BT_MAX_CONN
default 2 if SIDEWALK_DFU
Expand Down
6 changes: 6 additions & 0 deletions subsys/sal/sid_pal/include/sid_ble_advert.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ int sid_ble_advert_deinit(void);
*/
int sid_ble_advert_start(void);

/**
* @brief Notify sid_ble_advert that connection has been made
*
*/
void sid_ble_advert_notify_connection(void);

/**
* @brief Stop Bluetooth advertising.
*
Expand Down
85 changes: 46 additions & 39 deletions subsys/sal/sid_pal/src/sid_ble_advert.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ static struct bt_le_adv_param adv_param_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;
static struct bt_le_ext_adv *adv_set = NULL;

/**
* @brief Advertising data items values size in bytes.
Expand Down Expand Up @@ -117,109 +116,117 @@ 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);
LOG_INF("Change advertisement interval");

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);
err = bt_le_ext_adv_stop(adv_set);
if (err) {
atomic_set(&adv_state, BLE_ADV_DISABLE);
LOG_ERR("Failed to stop fast adv errno %d (%s)", err, strerror(err));
return;
}
err = bt_le_ext_adv_set_data(adv_set_slow, adv_data, ARRAY_SIZE(adv_data), sd,
err = bt_le_ext_adv_delete(adv_set);
if (err) {
atomic_set(&adv_state, BLE_ADV_DISABLE);
LOG_ERR("Failed to delete adv set");
return;
}
adv_set = NULL;
err = bt_le_ext_adv_create(&adv_param_slow, NULL, &adv_set);
if (err) {
atomic_set(&adv_state, BLE_ADV_DISABLE);
LOG_ERR("Failed to create slow adv set");
return;
}
err = bt_le_ext_adv_set_data(adv_set, adv_data, ARRAY_SIZE(adv_data), sd,
ARRAY_SIZE(sd));
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);
err = bt_le_ext_adv_start(adv_set, &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");
LOG_DBG("Change succesful");
}
}

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 (adv_set == NULL) {
ret = bt_le_ext_adv_create(&adv_param_fast, NULL, &adv_set);
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;
if (adv_set != NULL) {
int err = bt_le_ext_adv_delete(adv_set);
if (err) {
LOG_ERR("Failed to delete adv_set_fast errno %d (%s)", err, strerror(err));
return err;
}
adv_set = NULL;
}
adv_set_slow = NULL;

return 0;
}

int sid_ble_advert_start(void)
void sid_ble_advert_notify_connection(void)
{
k_work_reschedule(&change_adv_work, K_SECONDS(CONFIG_SIDEWALK_BLE_ADV_INT_TRANSITION));
LOG_INF("Conneciton has been made, cancel change adv");
k_work_cancel_delayable(&change_adv_work);
}

int sid_ble_advert_start(void)
{
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), sd,
ARRAY_SIZE(sd));
// make sure to always start with fast advertising set
sid_ble_advert_deinit();
sid_ble_advert_init();
err = bt_le_ext_adv_set_data(adv_set, adv_data, ARRAY_SIZE(adv_data), sd, ARRAY_SIZE(sd));
if (err) {
atomic_set(&adv_state, BLE_ADV_DISABLE);
LOG_ERR("Failed to set fast adv data errno: %d (%s)", err, strerror(err));
return err;
}

err = bt_le_ext_adv_start(adv_set_fast, &ext_adv_start_param);
err = bt_le_ext_adv_start(adv_set, &ext_adv_start_param);
if (err) {
atomic_set(&adv_state, BLE_ADV_DISABLE);
LOG_ERR("Failed to start fast adv errno: %d (%s)", err, strerror(err));
return err;
}

atomic_set(&adv_state, BLE_ADV_FAST);
k_work_reschedule(&change_adv_work, K_SECONDS(CONFIG_SIDEWALK_BLE_ADV_INT_TRANSITION));

return err;
}

int sid_ble_advert_stop(void)
{
k_work_cancel_delayable(&change_adv_work);
int err = bt_le_ext_adv_stop(atomic_get(&adv_state) == BLE_ADV_FAST ? adv_set_fast :
adv_set_slow);
int err = bt_le_ext_adv_stop(adv_set);

if (0 == err) {
atomic_set(&adv_state, BLE_ADV_DISABLE);
Expand All @@ -242,8 +249,8 @@ int sid_ble_advert_update(uint8_t *data, uint8_t data_len)

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), sd, ARRAY_SIZE(sd));
err = bt_le_ext_adv_set_data(adv_set, adv_data, ARRAY_SIZE(adv_data), sd,
ARRAY_SIZE(sd));
}

return err;
Expand Down
3 changes: 2 additions & 1 deletion subsys/sal/sid_pal/src/sid_ble_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <sid_ble_connection.h>
#include <sid_ble_adapter_callbacks.h>
#include <sid_ble_advert.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/gatt.h>
Expand Down Expand Up @@ -70,7 +71,7 @@ static void ble_connect_cb(struct bt_conn *conn, uint8_t err)
LOG_ERR("Connection failed (err %u)\n", err);
return;
}

sid_ble_advert_notify_connection();
bt_addr_le = bt_conn_get_dst(conn);

if (bt_addr_le) {
Expand Down
5 changes: 5 additions & 0 deletions tests/unit_tests/pal_ble_adapter/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ FAKE_VALUE_FUNC(int, bt_le_ext_adv_set_data, struct bt_le_ext_adv *, const struc
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_delete, struct bt_le_ext_adv *);
FAKE_VALUE_FUNC(int, bt_le_ext_adv_create, const struct bt_le_adv_param *,
const struct bt_le_ext_adv_cb *, struct bt_le_ext_adv **);
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 *,
Expand Down Expand Up @@ -63,6 +66,8 @@ FAKE_VALUE_FUNC(int, bt_conn_get_info, const struct bt_conn *, struct bt_conn_in
FAKE(bt_enable) \
FAKE(bt_disable) \
FAKE(bt_le_adv_start) \
FAKE(bt_le_ext_adv_delete) \
FAKE(bt_le_ext_adv_create) \
FAKE(bt_le_adv_stop) \
FAKE(bt_conn_cb_register) \
FAKE(bt_conn_ref) \
Expand Down
16 changes: 12 additions & 4 deletions tests/unit_tests/sid_ble_advert/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <sid_ble_advert.h>
#include <sid_ble_uuid.h>
#include <sid_ble_connection.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
Expand All @@ -20,11 +21,18 @@ FAKE_VALUE_FUNC(int, bt_le_ext_adv_start, struct bt_le_ext_adv *,
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_delete, struct bt_le_ext_adv *);
FAKE_VALUE_FUNC(int, bt_le_ext_adv_create, const struct bt_le_adv_param *,
const struct bt_le_ext_adv_cb *, struct bt_le_ext_adv **);
FAKE_VALUE_FUNC(const sid_ble_conn_params_t *, sid_ble_conn_params_get);

#define FFF_FAKES_LIST(FAKE) \
FAKE(bt_le_ext_adv_start) \
FAKE(bt_le_ext_adv_stop) \
FAKE(bt_le_ext_adv_set_data)
FAKE(bt_le_ext_adv_start) \
FAKE(bt_le_ext_adv_stop) \
FAKE(bt_le_ext_adv_set_data) \
FAKE(bt_le_ext_adv_delete) \
FAKE(bt_le_ext_adv_create) \
FAKE(sid_ble_conn_params_get)

#define ESUCCESS (0)
#define TEST_BUFFER_LEN (100)
Expand Down Expand Up @@ -111,7 +119,7 @@ bool advert_data_manuf_data_get(const struct bt_data *ad, size_t ad_len, uint8_t
for (size_t i = 0; i < ad_len; i++) {
if (ad[i].type == BT_DATA_MANUFACTURER_DATA) {
TEST_ASSERT_GREATER_OR_EQUAL_UINT8(BT_COMP_ID_LEN, ad[i].data_len);
TEST_ASSERT_EQUAL_UINT8(((BT_COMP_ID_AMA) & 0xff), ad[i].data[0]);
TEST_ASSERT_EQUAL_UINT8(((BT_COMP_ID_AMA)&0xff), ad[i].data[0]);
TEST_ASSERT_EQUAL_UINT8((((BT_COMP_ID_AMA) >> 8) & 0xff), ad[i].data[1]);

*result_len = ad[i].data_len - BT_COMP_ID_LEN;
Expand Down
4 changes: 3 additions & 1 deletion tests/unit_tests/sid_ble_connection/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ 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 *);
FAKE_VOID_FUNC(sid_ble_advert_notify_connection);

#define FFF_FAKES_LIST(FAKE) \
FAKE(bt_conn_cb_register) \
Expand All @@ -34,7 +35,8 @@ FAKE_VALUE_FUNC(int, bt_conn_get_info, const struct bt_conn *, struct bt_conn_in
FAKE(bt_conn_unref) \
FAKE(bt_conn_get_dst) \
FAKE(bt_conn_disconnect) \
FAKE(bt_conn_get_info)
FAKE(bt_conn_get_info) \
FAKE(sid_ble_advert_notify_connection)

#define CONNECTED (true)
#define DISCONNECTED (false)
Expand Down
9 changes: 9 additions & 0 deletions utils/sidewalk_dfu/nordic_dfu.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include "zephyr/kernel.h"
#include <sidewalk_dfu/nordic_dfu.h>
#include <dk_buttons_and_leds.h>
#include <stdbool.h>
Expand All @@ -24,9 +25,11 @@ LOG_MODULE_REGISTER(nordic_dfu, CONFIG_SIDEWALK_LOG_LEVEL);
#define LED_PERIOD_LOADING_WHEEL 150

static void pending_adv_start(struct k_work *work);
static void deinit_nordic_dfu(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 k_work exit_dfu = Z_WORK_INITIALIZER(deinit_nordic_dfu);

static struct bt_le_adv_param adv_params = { .id = BT_ID_DEFAULT,
.sid = 0,
Expand All @@ -53,6 +56,11 @@ static enum led_status_e {
static struct k_timer led_timer;
static struct k_timer exit_timer;

static void deinit_nordic_dfu(struct k_work *work)
{
nordic_dfu_ble_stop();
}

static int create_ble_id(void)
{
int ret;
Expand Down Expand Up @@ -101,6 +109,7 @@ 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. Exit dfu mode");
k_work_submit(&exit_dfu);
}

static void connected(struct bt_conn *conn, uint8_t err)
Expand Down

0 comments on commit b7e3e6b

Please sign in to comment.