From a63f2d8d608a249967975628aeaba23684a5aed7 Mon Sep 17 00:00:00 2001 From: Lingao Meng Date: Wed, 26 May 2021 20:32:18 -0700 Subject: [PATCH] Bluetooth: Mesh: Reconstructing adv callback logic The adv callback logic is reconstructed to coexist with proxy send callback. Signed-off-by: Lingao Meng --- subsys/bluetooth/mesh/adv.c | 11 ++++++++++- subsys/bluetooth/mesh/adv.h | 23 ++++++++++++++++------- subsys/bluetooth/mesh/adv_ext.c | 18 ++++++++++-------- subsys/bluetooth/mesh/adv_legacy.c | 12 +++++------- 4 files changed, 41 insertions(+), 23 deletions(-) diff --git a/subsys/bluetooth/mesh/adv.c b/subsys/bluetooth/mesh/adv.c index 550e3628ae9..7444e40208d 100644 --- a/subsys/bluetooth/mesh/adv.c +++ b/subsys/bluetooth/mesh/adv.c @@ -41,8 +41,17 @@ const uint8_t bt_mesh_adv_type[BT_MESH_ADV_TYPES] = { K_FIFO_DEFINE(bt_mesh_adv_queue); +static void adv_buf_destroy(struct net_buf *buf) +{ + struct bt_mesh_adv adv = *BT_MESH_ADV(buf); + + net_buf_destroy(buf); + + bt_mesh_adv_send_end(0, &adv); +} + NET_BUF_POOL_DEFINE(adv_buf_pool, CONFIG_BT_MESH_ADV_BUF_COUNT, - BT_MESH_ADV_DATA_SIZE, BT_MESH_ADV_USER_DATA_SIZE, NULL); + BT_MESH_ADV_DATA_SIZE, BT_MESH_ADV_USER_DATA_SIZE, adv_buf_destroy); static struct bt_mesh_adv adv_pool[CONFIG_BT_MESH_ADV_BUF_COUNT]; diff --git a/subsys/bluetooth/mesh/adv.h b/subsys/bluetooth/mesh/adv.h index b205ffd4565..35804e7bad3 100644 --- a/subsys/bluetooth/mesh/adv.h +++ b/subsys/bluetooth/mesh/adv.h @@ -35,7 +35,9 @@ struct bt_mesh_adv { void *cb_data; uint8_t type:2, + started:1, busy:1; + uint8_t xmit; }; @@ -75,18 +77,25 @@ int bt_mesh_adv_start(const struct bt_le_adv_param *param, int32_t duration, const struct bt_data *sd, size_t sd_len); static inline void bt_mesh_adv_send_start(uint16_t duration, int err, - const struct bt_mesh_send_cb *cb, - void *cb_data) + struct bt_mesh_adv *adv) { - if (cb && cb->start) { - cb->start(duration, err, cb_data); + if (!adv->started) { + adv->started = 1; + + if (adv->cb && adv->cb->start) { + adv->cb->start(duration, err, adv->cb_data); + } + + if (err) { + adv->cb = NULL; + } } } static inline void bt_mesh_adv_send_end( - int err, const struct bt_mesh_send_cb *cb, void *cb_data) + int err, struct bt_mesh_adv const *adv) { - if (cb && cb->end) { - cb->end(err, cb_data); + if (adv->started && adv->cb && adv->cb->end) { + adv->cb->end(err, adv->cb_data); } } diff --git a/subsys/bluetooth/mesh/adv_ext.c b/subsys/bluetooth/mesh/adv_ext.c index 392d8698a85..5999ff0c0cb 100644 --- a/subsys/bluetooth/mesh/adv_ext.c +++ b/subsys/bluetooth/mesh/adv_ext.c @@ -55,8 +55,7 @@ enum { static struct { ATOMIC_DEFINE(flags, ADV_FLAGS_NUM); struct bt_le_ext_adv *instance; - const struct bt_mesh_send_cb *cb; - void *cb_data; + struct net_buf *buf; uint64_t timestamp; struct k_work_delayable work; } adv; @@ -140,12 +139,12 @@ static int buf_send(struct net_buf *buf) atomic_set_bit(adv.flags, ADV_FLAG_UPDATE_PARAMS); } - adv.cb = BT_MESH_ADV(buf)->cb; - adv.cb_data = BT_MESH_ADV(buf)->cb_data; - err = adv_start(&adv_param, &start, &ad, 1, NULL, 0); - net_buf_unref(buf); - bt_mesh_adv_send_start(duration, err, adv.cb, adv.cb_data); + if (!err) { + adv.buf = net_buf_ref(buf); + } + + bt_mesh_adv_send_start(duration, err, BT_MESH_ADV(buf)); return err; } @@ -166,6 +165,9 @@ static void send_pending_adv(struct k_work *work) BT_MESH_ADV(buf)->busy = 0U; err = buf_send(buf); + + net_buf_unref(buf); + if (!err) { return; /* Wait for advertising to finish */ } @@ -235,7 +237,7 @@ static void adv_sent(struct bt_le_ext_adv *instance, atomic_clear_bit(adv.flags, ADV_FLAG_ACTIVE); if (!atomic_test_and_clear_bit(adv.flags, ADV_FLAG_PROXY)) { - bt_mesh_adv_send_end(0, adv.cb, adv.cb_data); + net_buf_unref(adv.buf); } schedule_send(); diff --git a/subsys/bluetooth/mesh/adv_legacy.c b/subsys/bluetooth/mesh/adv_legacy.c index 9285e2d85ef..ebae1aa13ef 100644 --- a/subsys/bluetooth/mesh/adv_legacy.c +++ b/subsys/bluetooth/mesh/adv_legacy.c @@ -46,8 +46,6 @@ static inline void adv_send(struct net_buf *buf) ((bt_dev.hci_version >= BT_HCI_VERSION_5_0) ? ADV_INT_FAST_MS : ADV_INT_DEFAULT_MS); - const struct bt_mesh_send_cb *cb = BT_MESH_ADV(buf)->cb; - void *cb_data = BT_MESH_ADV(buf)->cb_data; struct bt_le_adv_param param = {}; uint16_t duration, adv_int; struct bt_data ad; @@ -82,8 +80,9 @@ static inline void adv_send(struct net_buf *buf) uint64_t time = k_uptime_get(); err = bt_le_adv_start(¶m, &ad, 1, NULL, 0); - net_buf_unref(buf); - bt_mesh_adv_send_start(duration, err, cb, cb_data); + + bt_mesh_adv_send_start(duration, err, BT_MESH_ADV(buf)); + if (err) { BT_ERR("Advertising failed: err %d", err); return; @@ -94,7 +93,6 @@ static inline void adv_send(struct net_buf *buf) k_sleep(K_MSEC(duration)); err = bt_le_adv_stop(); - bt_mesh_adv_send_end(err, cb, cb_data); if (err) { BT_ERR("Stopping advertising failed: err %d", err); return; @@ -137,10 +135,10 @@ static void adv_thread(void *p1, void *p2, void *p3) if (BT_MESH_ADV(buf)->busy) { BT_MESH_ADV(buf)->busy = 0U; adv_send(buf); - } else { - net_buf_unref(buf); } + net_buf_unref(buf); + /* Give other threads a chance to run */ k_yield(); }