Bluetooth: Mesh: Reconstructing adv callback logic

The adv callback logic is reconstructed to coexist
with proxy send callback.

Signed-off-by: Lingao Meng <menglingao@xiaomi.com>
This commit is contained in:
Lingao Meng 2021-05-26 20:32:18 -07:00 committed by Johan Hedberg
commit a63f2d8d60
4 changed files with 41 additions and 23 deletions

View file

@ -41,8 +41,17 @@ const uint8_t bt_mesh_adv_type[BT_MESH_ADV_TYPES] = {
K_FIFO_DEFINE(bt_mesh_adv_queue); 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, 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]; static struct bt_mesh_adv adv_pool[CONFIG_BT_MESH_ADV_BUF_COUNT];

View file

@ -35,7 +35,9 @@ struct bt_mesh_adv {
void *cb_data; void *cb_data;
uint8_t type:2, uint8_t type:2,
started:1,
busy:1; busy:1;
uint8_t xmit; 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); const struct bt_data *sd, size_t sd_len);
static inline void bt_mesh_adv_send_start(uint16_t duration, int err, static inline void bt_mesh_adv_send_start(uint16_t duration, int err,
const struct bt_mesh_send_cb *cb, struct bt_mesh_adv *adv)
void *cb_data)
{ {
if (cb && cb->start) { if (!adv->started) {
cb->start(duration, err, cb_data); 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( 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) { if (adv->started && adv->cb && adv->cb->end) {
cb->end(err, cb_data); adv->cb->end(err, adv->cb_data);
} }
} }

View file

@ -55,8 +55,7 @@ enum {
static struct { static struct {
ATOMIC_DEFINE(flags, ADV_FLAGS_NUM); ATOMIC_DEFINE(flags, ADV_FLAGS_NUM);
struct bt_le_ext_adv *instance; struct bt_le_ext_adv *instance;
const struct bt_mesh_send_cb *cb; struct net_buf *buf;
void *cb_data;
uint64_t timestamp; uint64_t timestamp;
struct k_work_delayable work; struct k_work_delayable work;
} adv; } adv;
@ -140,12 +139,12 @@ static int buf_send(struct net_buf *buf)
atomic_set_bit(adv.flags, ADV_FLAG_UPDATE_PARAMS); 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); err = adv_start(&adv_param, &start, &ad, 1, NULL, 0);
net_buf_unref(buf); if (!err) {
bt_mesh_adv_send_start(duration, err, adv.cb, adv.cb_data); adv.buf = net_buf_ref(buf);
}
bt_mesh_adv_send_start(duration, err, BT_MESH_ADV(buf));
return err; return err;
} }
@ -166,6 +165,9 @@ static void send_pending_adv(struct k_work *work)
BT_MESH_ADV(buf)->busy = 0U; BT_MESH_ADV(buf)->busy = 0U;
err = buf_send(buf); err = buf_send(buf);
net_buf_unref(buf);
if (!err) { if (!err) {
return; /* Wait for advertising to finish */ 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); atomic_clear_bit(adv.flags, ADV_FLAG_ACTIVE);
if (!atomic_test_and_clear_bit(adv.flags, ADV_FLAG_PROXY)) { 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(); schedule_send();

View file

@ -46,8 +46,6 @@ static inline void adv_send(struct net_buf *buf)
((bt_dev.hci_version >= BT_HCI_VERSION_5_0) ? ((bt_dev.hci_version >= BT_HCI_VERSION_5_0) ?
ADV_INT_FAST_MS : ADV_INT_FAST_MS :
ADV_INT_DEFAULT_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 = {}; struct bt_le_adv_param param = {};
uint16_t duration, adv_int; uint16_t duration, adv_int;
struct bt_data ad; struct bt_data ad;
@ -82,8 +80,9 @@ static inline void adv_send(struct net_buf *buf)
uint64_t time = k_uptime_get(); uint64_t time = k_uptime_get();
err = bt_le_adv_start(&param, &ad, 1, NULL, 0); err = bt_le_adv_start(&param, &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) { if (err) {
BT_ERR("Advertising failed: err %d", err); BT_ERR("Advertising failed: err %d", err);
return; return;
@ -94,7 +93,6 @@ static inline void adv_send(struct net_buf *buf)
k_sleep(K_MSEC(duration)); k_sleep(K_MSEC(duration));
err = bt_le_adv_stop(); err = bt_le_adv_stop();
bt_mesh_adv_send_end(err, cb, cb_data);
if (err) { if (err) {
BT_ERR("Stopping advertising failed: err %d", err); BT_ERR("Stopping advertising failed: err %d", err);
return; return;
@ -137,10 +135,10 @@ static void adv_thread(void *p1, void *p2, void *p3)
if (BT_MESH_ADV(buf)->busy) { if (BT_MESH_ADV(buf)->busy) {
BT_MESH_ADV(buf)->busy = 0U; BT_MESH_ADV(buf)->busy = 0U;
adv_send(buf); adv_send(buf);
} else {
net_buf_unref(buf);
} }
net_buf_unref(buf);
/* Give other threads a chance to run */ /* Give other threads a chance to run */
k_yield(); k_yield();
} }