Bluetooth: Mesh: Separate adv tag/set for friend
The purpose of this commit is to facilitate future improvements to the LPN and friendship feature. By being able to identify friendship related messages on the advertising layer, it will be possible to treat these in a specific manner so that message exchange between LPN and friend devices can be conducted in a more power efficient manner. This commit adds the following: - A separate tag for friendship related messages - A optional separate advertising set for friend related messages Signed-off-by: Anders Storrø <anders.storro@nordicsemi.no>
This commit is contained in:
parent
bedace2105
commit
c819f0f8d6
5 changed files with 117 additions and 36 deletions
|
@ -421,7 +421,17 @@ config BT_MESH_ADV_EXT_GATT_SEPARATE
|
|||
depends on BT_MESH_GATT_SERVER
|
||||
help
|
||||
Use a separate extended advertising set for GATT Server Advertising,
|
||||
otherwise will be used a shared advertising set.
|
||||
otherwise a shared advertising set will be used.
|
||||
|
||||
config BT_MESH_ADV_EXT_FRIEND_SEPARATE
|
||||
bool "Use a separate extended advertising set for Friend advertising"
|
||||
depends on BT_MESH_FRIEND
|
||||
help
|
||||
Use a separate extended advertising set for Friend advertising,
|
||||
otherwise a shared advertising set will be used. Using the separate
|
||||
extended advertising set makes the Friend node send friendship
|
||||
messages as close to the start of the ReceiveWindow as possible,
|
||||
thus reducing the scanning time on the Low Power node.
|
||||
|
||||
endif # BT_MESH_ADV_EXT
|
||||
|
||||
|
@ -880,12 +890,14 @@ config BT_MESH_FRIEND_SEG_RX
|
|||
|
||||
config BT_MESH_FRIEND_ADV_LATENCY
|
||||
int "Latency for enabling advertising"
|
||||
range 0 4
|
||||
default 0
|
||||
help
|
||||
Latency in milliseconds that it takes to start friend advertising
|
||||
after requesting it. Used to tune the receive delay window to make
|
||||
Friend poll events more efficient by compensating for the time the
|
||||
non-ideal latency otherwise would add to the delay.
|
||||
Latency in milliseconds between request for and start of Friend
|
||||
advertising. Used to tune the ReceiveDelay, making Friend
|
||||
start sending a message earlier thus compensating for the time between
|
||||
pushing the message to the Bluetooth host and the actual advertising
|
||||
start.
|
||||
|
||||
endif # BT_MESH_FRIEND
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ const uint8_t bt_mesh_adv_type[BT_MESH_ADV_TYPES] = {
|
|||
|
||||
static K_FIFO_DEFINE(bt_mesh_adv_queue);
|
||||
static K_FIFO_DEFINE(bt_mesh_relay_queue);
|
||||
static K_FIFO_DEFINE(bt_mesh_friend_queue);
|
||||
|
||||
static void adv_buf_destroy(struct net_buf *buf)
|
||||
{
|
||||
|
@ -67,6 +68,14 @@ NET_BUF_POOL_DEFINE(relay_buf_pool, CONFIG_BT_MESH_RELAY_BUF_COUNT,
|
|||
static struct bt_mesh_adv adv_relay_pool[CONFIG_BT_MESH_RELAY_BUF_COUNT];
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)
|
||||
NET_BUF_POOL_DEFINE(friend_buf_pool, CONFIG_BT_MESH_FRIEND_LPN_COUNT,
|
||||
BT_MESH_ADV_DATA_SIZE, BT_MESH_ADV_USER_DATA_SIZE,
|
||||
adv_buf_destroy);
|
||||
|
||||
static struct bt_mesh_adv adv_friend_pool[CONFIG_BT_MESH_FRIEND_LPN_COUNT];
|
||||
#endif
|
||||
|
||||
static struct net_buf *bt_mesh_adv_create_from_pool(struct net_buf_pool *buf_pool,
|
||||
struct bt_mesh_adv *adv_pool,
|
||||
enum bt_mesh_adv_type type,
|
||||
|
@ -110,11 +119,19 @@ struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type,
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)
|
||||
if (tag & BT_MESH_FRIEND_ADV) {
|
||||
return bt_mesh_adv_create_from_pool(&friend_buf_pool,
|
||||
adv_friend_pool, type,
|
||||
tag, xmit, timeout);
|
||||
}
|
||||
#endif
|
||||
|
||||
return bt_mesh_adv_create_from_pool(&adv_buf_pool, adv_local_pool, type,
|
||||
tag, xmit, timeout);
|
||||
}
|
||||
|
||||
#if CONFIG_BT_MESH_RELAY_ADV_SETS
|
||||
#if CONFIG_BT_MESH_RELAY_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE
|
||||
static struct net_buf *process_events(struct k_poll_event *ev, int count)
|
||||
{
|
||||
for (; count; ev++, count--) {
|
||||
|
@ -159,22 +176,21 @@ struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout)
|
|||
return process_events(events, ARRAY_SIZE(events));
|
||||
}
|
||||
|
||||
static struct net_buf *bt_mesh_adv_buf_relay_get(k_timeout_t timeout)
|
||||
{
|
||||
return net_buf_get(&bt_mesh_relay_queue, timeout);
|
||||
}
|
||||
|
||||
struct net_buf *bt_mesh_adv_buf_get_by_tag(uint8_t tag, k_timeout_t timeout)
|
||||
{
|
||||
if (tag & BT_MESH_LOCAL_ADV) {
|
||||
return bt_mesh_adv_buf_get(timeout);
|
||||
} else if (tag & BT_MESH_RELAY_ADV) {
|
||||
return bt_mesh_adv_buf_relay_get(timeout);
|
||||
} else {
|
||||
return NULL;
|
||||
if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && tag & BT_MESH_FRIEND_ADV) {
|
||||
return net_buf_get(&bt_mesh_friend_queue, timeout);
|
||||
}
|
||||
|
||||
#if CONFIG_BT_MESH_RELAY_ADV_SETS
|
||||
if (tag & BT_MESH_RELAY_ADV) {
|
||||
return net_buf_get(&bt_mesh_relay_queue, timeout);
|
||||
}
|
||||
#endif
|
||||
|
||||
return bt_mesh_adv_buf_get(timeout);
|
||||
}
|
||||
#else /* !CONFIG_BT_MESH_RELAY_ADV_SETS */
|
||||
#else /* !(CONFIG_BT_MESH_RELAY_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) */
|
||||
struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout)
|
||||
{
|
||||
return net_buf_get(&bt_mesh_adv_queue, timeout);
|
||||
|
@ -186,7 +202,7 @@ struct net_buf *bt_mesh_adv_buf_get_by_tag(uint8_t tag, k_timeout_t timeout)
|
|||
|
||||
return bt_mesh_adv_buf_get(timeout);
|
||||
}
|
||||
#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */
|
||||
#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS || CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */
|
||||
|
||||
void bt_mesh_adv_buf_get_cancel(void)
|
||||
{
|
||||
|
@ -198,6 +214,9 @@ void bt_mesh_adv_buf_get_cancel(void)
|
|||
k_fifo_cancel_wait(&bt_mesh_relay_queue);
|
||||
#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)) {
|
||||
k_fifo_cancel_wait(&bt_mesh_friend_queue);
|
||||
}
|
||||
}
|
||||
|
||||
void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
|
||||
|
@ -210,18 +229,23 @@ void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
|
|||
BT_MESH_ADV(buf)->cb_data = cb_data;
|
||||
BT_MESH_ADV(buf)->busy = 1U;
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) &&
|
||||
BT_MESH_ADV(buf)->tag == BT_MESH_FRIEND_ADV) {
|
||||
net_buf_put(&bt_mesh_friend_queue, net_buf_ref(buf));
|
||||
bt_mesh_adv_buf_friend_ready();
|
||||
return;
|
||||
}
|
||||
|
||||
#if CONFIG_BT_MESH_RELAY_ADV_SETS
|
||||
if (BT_MESH_ADV(buf)->tag == BT_MESH_LOCAL_ADV) {
|
||||
net_buf_put(&bt_mesh_adv_queue, net_buf_ref(buf));
|
||||
bt_mesh_adv_buf_local_ready();
|
||||
} else {
|
||||
if (BT_MESH_ADV(buf)->tag == BT_MESH_RELAY_ADV) {
|
||||
net_buf_put(&bt_mesh_relay_queue, net_buf_ref(buf));
|
||||
bt_mesh_adv_buf_relay_ready();
|
||||
return;
|
||||
}
|
||||
#else /* !CONFIG_BT_MESH_RELAY_ADV_SETS */
|
||||
#endif
|
||||
|
||||
net_buf_put(&bt_mesh_adv_queue, net_buf_ref(buf));
|
||||
bt_mesh_adv_buf_local_ready();
|
||||
#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */
|
||||
}
|
||||
|
||||
int bt_mesh_adv_gatt_send(void)
|
||||
|
|
|
@ -29,6 +29,7 @@ enum bt_mesh_adv_tag {
|
|||
BT_MESH_LOCAL_ADV = BIT(0),
|
||||
BT_MESH_RELAY_ADV = BIT(1),
|
||||
BT_MESH_PROXY_ADV = BIT(2),
|
||||
BT_MESH_FRIEND_ADV = BIT(3),
|
||||
};
|
||||
|
||||
struct bt_mesh_adv {
|
||||
|
@ -38,7 +39,7 @@ struct bt_mesh_adv {
|
|||
uint8_t type:2,
|
||||
started:1,
|
||||
busy:1,
|
||||
tag:3;
|
||||
tag:4;
|
||||
|
||||
uint8_t xmit;
|
||||
};
|
||||
|
@ -74,6 +75,8 @@ void bt_mesh_adv_buf_local_ready(void);
|
|||
|
||||
void bt_mesh_adv_buf_relay_ready(void);
|
||||
|
||||
void bt_mesh_adv_buf_friend_ready(void);
|
||||
|
||||
int bt_mesh_adv_gatt_send(void);
|
||||
|
||||
int bt_mesh_adv_gatt_start(const struct bt_le_adv_param *param, int32_t duration,
|
||||
|
|
|
@ -68,6 +68,9 @@ static bool schedule_send(struct bt_mesh_ext_adv *adv);
|
|||
|
||||
static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_main) = {
|
||||
.tag = (
|
||||
#if !defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)
|
||||
BT_MESH_FRIEND_ADV |
|
||||
#endif
|
||||
#if !defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE)
|
||||
BT_MESH_PROXY_ADV |
|
||||
#endif /* !CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */
|
||||
|
@ -88,16 +91,28 @@ static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_relay[CONFIG_BT_MESH_RELAY_A
|
|||
};
|
||||
#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */
|
||||
|
||||
#if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)
|
||||
#define ADV_EXT_FRIEND 1
|
||||
static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_friend) = {
|
||||
.tag = BT_MESH_FRIEND_ADV,
|
||||
.work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv),
|
||||
};
|
||||
#else /* CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */
|
||||
#define ADV_EXT_FRIEND 0
|
||||
#endif /* CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */
|
||||
|
||||
#if defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE)
|
||||
#define BT_MESH_ADV_COUNT (1 + CONFIG_BT_MESH_RELAY_ADV_SETS + 1)
|
||||
#define ADV_EXT_GATT 1
|
||||
static STRUCT_SECTION_ITERABLE(bt_mesh_ext_adv, adv_gatt) = {
|
||||
.tag = BT_MESH_PROXY_ADV,
|
||||
.work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv),
|
||||
};
|
||||
#else /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */
|
||||
#define BT_MESH_ADV_COUNT (1 + CONFIG_BT_MESH_RELAY_ADV_SETS)
|
||||
#define ADV_EXT_GATT 0
|
||||
#endif /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */
|
||||
|
||||
#define BT_MESH_ADV_COUNT (1 + CONFIG_BT_MESH_RELAY_ADV_SETS + ADV_EXT_FRIEND + ADV_EXT_GATT)
|
||||
|
||||
BUILD_ASSERT(CONFIG_BT_EXT_ADV_MAX_ADV_SET >= BT_MESH_ADV_COUNT,
|
||||
"Insufficient adv instances");
|
||||
|
||||
|
@ -208,6 +223,21 @@ static int buf_send(struct bt_mesh_ext_adv *adv, struct net_buf *buf)
|
|||
return err;
|
||||
}
|
||||
|
||||
static const char *adv_tag_to_str(enum bt_mesh_adv_tag tag)
|
||||
{
|
||||
if (tag & BT_MESH_LOCAL_ADV) {
|
||||
return "local adv";
|
||||
} else if (tag & BT_MESH_PROXY_ADV) {
|
||||
return "proxy adv";
|
||||
} else if (tag & BT_MESH_RELAY_ADV) {
|
||||
return "relay adv";
|
||||
} else if (tag & BT_MESH_FRIEND_ADV) {
|
||||
return "friend adv";
|
||||
} else {
|
||||
return "(unknown tag)";
|
||||
}
|
||||
}
|
||||
|
||||
static void send_pending_adv(struct k_work *work)
|
||||
{
|
||||
struct bt_mesh_ext_adv *adv;
|
||||
|
@ -223,7 +253,8 @@ static void send_pending_adv(struct k_work *work)
|
|||
*/
|
||||
int64_t duration = k_uptime_delta(&adv->timestamp);
|
||||
|
||||
LOG_DBG("Advertising stopped after %u ms", (uint32_t)duration);
|
||||
LOG_DBG("Advertising stopped after %u ms for (%u) %s", (uint32_t)duration, adv->tag,
|
||||
adv_tag_to_str(adv->tag));
|
||||
|
||||
atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE);
|
||||
atomic_clear_bit(adv->flags, ADV_FLAG_PROXY);
|
||||
|
@ -297,12 +328,16 @@ static bool schedule_send(struct bt_mesh_ext_adv *adv)
|
|||
|
||||
atomic_clear_bit(adv->flags, ADV_FLAG_SCHEDULE_PENDING);
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && adv->tag & BT_MESH_FRIEND_ADV) {
|
||||
k_work_reschedule(&adv->work, K_NO_WAIT);
|
||||
} else {
|
||||
/* The controller will send the next advertisement immediately.
|
||||
* Introduce a delay here to avoid sending the next mesh packet closer
|
||||
* to the previous packet than what's permitted by the specification.
|
||||
*/
|
||||
delta = k_uptime_delta(×tamp);
|
||||
k_work_reschedule(&adv->work, K_MSEC(ADV_INT_FAST_MS - delta));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -333,6 +368,13 @@ void bt_mesh_adv_buf_relay_ready(void)
|
|||
}
|
||||
}
|
||||
|
||||
void bt_mesh_adv_buf_friend_ready(void)
|
||||
{
|
||||
#if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)
|
||||
(void)schedule_send(&adv_friend);
|
||||
#endif
|
||||
}
|
||||
|
||||
void bt_mesh_adv_init(void)
|
||||
{
|
||||
struct bt_le_adv_param adv_param = {
|
||||
|
|
|
@ -1269,7 +1269,7 @@ static void friend_timeout(struct k_work *work)
|
|||
frnd->queue_size--;
|
||||
|
||||
send_last:
|
||||
buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV,
|
||||
buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_FRIEND_ADV,
|
||||
FRIEND_XMIT, K_NO_WAIT);
|
||||
if (!buf) {
|
||||
LOG_ERR("Unable to allocate friend adv buffer");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue