Skip to content

Commit

Permalink
Bluetooth: Mesh: remove 20ms tx delay in adv bearer
Browse files Browse the repository at this point in the history
The recommendation to have 20ms is fair for two
consecutive messages over a single bearer. When mesh
sends two messages it can be interpreted as two
bearers working in parallel. No need to keep
an artificial 20ms delay for that. Delay was
removed and all related bsim tests were fixed.

Signed-off-by: Aleksandr Khromykh <[email protected]>
  • Loading branch information
alxelax authored and carlescufi committed Dec 19, 2023
1 parent 8d51a1d commit ac4cfe9
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 38 deletions.
54 changes: 16 additions & 38 deletions subsys/bluetooth/mesh/adv_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ struct bt_mesh_ext_adv {
ATOMIC_DEFINE(flags, ADV_FLAGS_NUM);
struct bt_le_ext_adv *instance;
struct bt_mesh_adv *adv;
uint64_t timestamp;
struct k_work_delayable work;
uint32_t timestamp;
struct k_work work;
struct bt_le_adv_param adv_param;
};

Expand All @@ -85,7 +85,7 @@ static struct bt_mesh_ext_adv advs[] = {
#endif /* CONFIG_BT_MESH_PB_ADV */
BT_MESH_ADV_TAG_BIT_LOCAL
),
.work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv),
.work = Z_WORK_INITIALIZER(send_pending_adv),
},
#if CONFIG_BT_MESH_RELAY_ADV_SETS
[1 ... CONFIG_BT_MESH_RELAY_ADV_SETS] = {
Expand All @@ -97,19 +97,19 @@ static struct bt_mesh_ext_adv advs[] = {
BT_MESH_ADV_TAG_BIT_PROV |
#endif /* CONFIG_BT_MESH_PB_ADV_USE_RELAY_SETS */
0),
.work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv),
.work = Z_WORK_INITIALIZER(send_pending_adv),
},
#endif /* CONFIG_BT_MESH_RELAY_ADV_SETS */
#if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)
{
.tags = BT_MESH_ADV_TAG_BIT_FRIEND,
.work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv),
.work = Z_WORK_INITIALIZER(send_pending_adv),
},
#endif /* CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE */
#if defined(CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE)
{
.tags = BT_MESH_ADV_TAG_BIT_PROXY,
.work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv),
.work = Z_WORK_INITIALIZER(send_pending_adv),
},
#endif /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */
};
Expand Down Expand Up @@ -172,7 +172,7 @@ static int adv_start(struct bt_mesh_ext_adv *ext_adv,
return err;
}

ext_adv->timestamp = k_uptime_get();
ext_adv->timestamp = k_uptime_get_32();

err = bt_le_ext_adv_start(ext_adv->instance, start);
if (err) {
Expand Down Expand Up @@ -246,18 +246,13 @@ static void send_pending_adv(struct k_work *work)
struct bt_mesh_adv *adv;
int err;

ext_adv = CONTAINER_OF(work, struct bt_mesh_ext_adv, work.work);
ext_adv = CONTAINER_OF(work, struct bt_mesh_ext_adv, work);

if (atomic_test_and_clear_bit(ext_adv->flags, ADV_FLAG_SENT)) {
/* Calling k_uptime_delta on a timestamp moves it to the current time.
* This is essential here, as schedule_send() uses the end of the event
* as a reference to avoid sending the next advertisement too soon.
*/
int64_t duration = k_uptime_delta(&ext_adv->timestamp);

LOG_DBG("Advertising stopped after %u ms for %s", (uint32_t)duration,
ext_adv->adv ? adv_tag_to_str[ext_adv->adv->ctx.tag] :
adv_tag_to_str[BT_MESH_ADV_TAG_PROXY]);
LOG_DBG("Advertising stopped after %u ms for %s",
k_uptime_get_32() - ext_adv->timestamp,
ext_adv->adv ? adv_tag_to_str[ext_adv->adv->ctx.tag]
: adv_tag_to_str[BT_MESH_ADV_TAG_PROXY]);

atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE);
atomic_clear_bit(ext_adv->flags, ADV_FLAG_PROXY);
Expand Down Expand Up @@ -315,11 +310,6 @@ static void send_pending_adv(struct k_work *work)

static bool schedule_send(struct bt_mesh_ext_adv *ext_adv)
{
uint64_t timestamp;
int64_t delta;

timestamp = ext_adv->timestamp;

if (atomic_test_and_clear_bit(ext_adv->flags, ADV_FLAG_PROXY)) {
atomic_clear_bit(ext_adv->flags, ADV_FLAG_PROXY_START);
(void)bt_le_ext_adv_stop(ext_adv->instance);
Expand All @@ -335,19 +325,7 @@ static bool schedule_send(struct bt_mesh_ext_adv *ext_adv)
}

atomic_clear_bit(ext_adv->flags, ADV_FLAG_SCHEDULE_PENDING);

if ((IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) &&
ext_adv->tags & BT_MESH_ADV_TAG_BIT_FRIEND) ||
(CONFIG_BT_MESH_RELAY_ADV_SETS > 0 && ext_adv->tags & BT_MESH_ADV_TAG_BIT_RELAY)) {
k_work_reschedule(&ext_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(&timestamp);
k_work_reschedule(&ext_adv->work, K_MSEC(ADV_INT_FAST_MS - delta));
}
k_work_submit(&ext_adv->work);

return true;
}
Expand Down Expand Up @@ -413,7 +391,7 @@ void bt_mesh_adv_terminate(struct bt_mesh_adv *adv)

atomic_set_bit(ext_adv->flags, ADV_FLAG_SENT);

k_work_submit(&ext_adv->work.work);
k_work_submit(&ext_adv->work);

return;
}
Expand Down Expand Up @@ -462,7 +440,7 @@ static void adv_sent(struct bt_le_ext_adv *instance,

atomic_set_bit(ext_adv->flags, ADV_FLAG_SENT);

k_work_submit(&ext_adv->work.work);
k_work_submit(&ext_adv->work);
}

#if defined(CONFIG_BT_MESH_GATT_SERVER)
Expand Down Expand Up @@ -511,7 +489,7 @@ int bt_mesh_adv_disable(void)
struct k_work_sync sync;

for (int i = 0; i < ARRAY_SIZE(advs); i++) {
k_work_flush_delayable(&advs[i].work, &sync);
k_work_flush(&advs[i].work, &sync);

err = bt_le_ext_adv_stop(advs[i].instance);
if (err) {
Expand Down
2 changes: 2 additions & 0 deletions tests/bsim/bluetooth/mesh/overlay_pst.conf
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ CONFIG_BT_MESH_SEQ_STORE_RATE=1
CONFIG_BT_MESH_RPL_STORE_TIMEOUT=1
CONFIG_BT_MESH_STORE_TIMEOUT=1
CONFIG_BT_MESH_TX_SEG_RETRANS_COUNT=1
CONFIG_BT_MESH_TX_SEG_RETRANS_TIMEOUT_UNICAST=200
CONFIG_BT_MESH_SEG_ACK_BASE_TIMEOUT=400
CONFIG_BT_MESH_COMP_PST_BUF_SIZE=600
6 changes: 6 additions & 0 deletions tests/bsim/bluetooth/mesh/src/test_persistence.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,12 @@ static void provisioner_setup(void)
FAIL("Failed to add test_netkey (err: %d, status: %d)", err, status);
}

err = bt_mesh_cfg_cli_net_transmit_set(test_netkey_idx, TEST_PROV_ADDR,
BT_MESH_TRANSMIT(3, 50), &status);
if (err || status != BT_MESH_TRANSMIT(3, 50)) {
FAIL("Net transmit set failed (err %d, transmit %x)", err, status);
}

provisioner_ready = true;
}

Expand Down
10 changes: 10 additions & 0 deletions tests/bsim/bluetooth/mesh/src/test_provision.c
Original file line number Diff line number Diff line change
Expand Up @@ -1211,6 +1211,7 @@ static void test_provisioner_pb_remote_client_nppi_robustness(void)
uint16_t pb_remote_server_addr;
uint8_t status;
struct bt_mesh_cdb_node *node;
int err;

provisioner_pb_remote_client_setup();

Expand All @@ -1224,6 +1225,15 @@ static void test_provisioner_pb_remote_client_nppi_robustness(void)
.ttl = 3,
};

/* Set Network Transmit Count state on the remote client greater than on the remote server
* to increase probability of reception responses.
*/
err = bt_mesh_cfg_cli_net_transmit_set(0, current_dev_addr, BT_MESH_TRANSMIT(3, 50),
&status);
if (err || status != BT_MESH_TRANSMIT(3, 50)) {
FAIL("Net transmit set failed (err %d, transmit %x)", err, status);
}

ASSERT_OK(provision_remote(&srv, 2, &srv.addr));

/* Check device key by adding appkey. */
Expand Down

0 comments on commit ac4cfe9

Please sign in to comment.