Skip to content

Bluetooth: Mesh: Cherry pick BLE Mesh 27.03.2025 #2677

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 1, 2025
13 changes: 9 additions & 4 deletions subsys/bluetooth/mesh/adv_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,12 +342,17 @@ static void start_proxy_sol_or_proxy_adv(struct bt_mesh_ext_adv *ext_adv)
}
}

if (IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER) &&
!atomic_test_and_set_bit(ext_adv->flags, ADV_FLAG_PROXY)) {
if (bt_mesh_adv_gatt_send()) {
atomic_clear_bit(ext_adv->flags, ADV_FLAG_PROXY);
if (IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER)) {
if (stop_proxy_adv(ext_adv)) {
return;
}

if (!atomic_test_and_set_bit(ext_adv->flags, ADV_FLAG_PROXY)) {
if (bt_mesh_adv_gatt_send()) {
atomic_clear_bit(ext_adv->flags, ADV_FLAG_PROXY);
return;
}
}
}
}

Expand Down
47 changes: 27 additions & 20 deletions subsys/bluetooth/mesh/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx,
LOG_INF("Primary Element: 0x%04x", addr);
LOG_DBG("net_idx 0x%04x flags 0x%02x iv_index 0x%04x", net_idx, flags, iv_index);

if (atomic_test_and_set_bit(bt_mesh.flags, BT_MESH_VALID)) {
if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
return -EALREADY;
}

Expand All @@ -74,14 +74,12 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx,
comp = bt_mesh_comp_get();
if (comp == NULL) {
LOG_ERR("Failed to get node composition");
atomic_clear_bit(bt_mesh.flags, BT_MESH_VALID);
return -EINVAL;
}

subnet = bt_mesh_cdb_subnet_get(net_idx);
if (!subnet) {
LOG_ERR("No subnet with idx %d", net_idx);
atomic_clear_bit(bt_mesh.flags, BT_MESH_VALID);
return -ENOENT;
}

Expand All @@ -90,7 +88,6 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx,
comp->elem_count, net_idx);
if (node == NULL) {
LOG_ERR("Failed to allocate database node");
atomic_clear_bit(bt_mesh.flags, BT_MESH_VALID);
return -ENOMEM;
}

Expand All @@ -108,42 +105,43 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx,
net_key);
if (err) {
LOG_ERR("Failed to import cdb network key");
goto end;
goto error_exit;
}
bt_mesh_cdb_subnet_store(subnet);

addr = node->addr;
bt_mesh_cdb_iv_update(iv_index, BT_MESH_IV_UPDATE(flags));

err = bt_mesh_cdb_node_key_import(node, dev_key);
if (err) {
LOG_ERR("Failed to import cdb device key");
goto end;
}

if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_cdb_node_store(node);
goto error_exit;
}
}

err = bt_mesh_key_import(BT_MESH_KEY_TYPE_DEV, dev_key, &mesh_dev_key);
if (err) {
LOG_ERR("Failed to import device key");
goto end;
goto error_exit;
}
is_dev_key_valid = true;

err = bt_mesh_key_import(BT_MESH_KEY_TYPE_NET, net_key, &mesh_net_key);
if (err) {
LOG_ERR("Failed to import network key");
goto end;
goto error_exit;
}
is_net_key_valid = true;

err = bt_mesh_net_create(net_idx, flags, &mesh_net_key, iv_index);
if (err) {
atomic_clear_bit(bt_mesh.flags, BT_MESH_VALID);
goto end;
LOG_ERR("Failed to create network");
goto error_exit;
}

if (IS_ENABLED(CONFIG_BT_MESH_CDB) &&
atomic_test_bit(bt_mesh_cdb.flags, BT_MESH_CDB_VALID)) {
bt_mesh_cdb_subnet_store(subnet);
bt_mesh_cdb_node_store(node);
}

bt_mesh_net_settings_commit();
Expand All @@ -163,18 +161,21 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx,
bt_mesh_net_store();
}

atomic_set_bit(bt_mesh.flags, BT_MESH_VALID);
bt_mesh_start();

end:
if (err && node != NULL && IS_ENABLED(CONFIG_BT_MESH_CDB)) {
bt_mesh_cdb_node_del(node, true);
return 0;

error_exit:
if (node != NULL && IS_ENABLED(CONFIG_BT_MESH_CDB)) {
bt_mesh_cdb_node_del(node, false);
}

if (err && is_dev_key_valid) {
if (is_dev_key_valid) {
bt_mesh_key_destroy(&mesh_dev_key);
}

if (err && is_net_key_valid) {
if (is_net_key_valid) {
bt_mesh_key_destroy(&mesh_net_key);
}

Expand Down Expand Up @@ -236,6 +237,8 @@ void bt_mesh_dev_key_cand_remove(void)
}

LOG_DBG("");
bt_mesh_key_destroy(&bt_mesh.dev_key_cand);
memset(&bt_mesh.dev_key_cand, 0, sizeof(struct bt_mesh_key));

if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_net_dev_key_cand_store();
Expand Down Expand Up @@ -397,6 +400,10 @@ void bt_mesh_reset(void)
bt_mesh_key_destroy(&bt_mesh.dev_key);
memset(&bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key));

if (IS_ENABLED(CONFIG_BT_MESH_RPR_SRV)) {
bt_mesh_dev_key_cand_remove();
}

bt_mesh_beacon_disable();

bt_mesh_comp_unprovision();
Expand Down
49 changes: 35 additions & 14 deletions subsys/bluetooth/mesh/pb_adv.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,14 +482,16 @@ static void gen_prov_cont(struct prov_rx *rx, struct net_buf_simple *buf)
{
uint8_t seg = CONT_SEG_INDEX(rx->gpc);

if (link.tx.adv[0]) {
LOG_DBG("Ongoing tx transaction has not been completed yet");
return;
}

LOG_DBG("len %u, seg_index %u", buf->len, seg);

/* When link.rx.seg is zero for a valid link.rx.id, this means that transaction
* has already been received. The other device probably missed the Transaction
* Acknowledgment PDU, so we need to resend it regardless of the active transmission.
*/
if (!link.rx.seg && link.rx.id == rx->xact_id) {
/* Send ack if another ack is NOT pending for transmission. Otherwise, skip sending
* this ack for now.
*/
if (!ack_pending()) {
LOG_DBG("Resending ack");
gen_prov_ack_send(rx->xact_id);
Expand All @@ -498,6 +500,11 @@ static void gen_prov_cont(struct prov_rx *rx, struct net_buf_simple *buf)
return;
}

if (link.tx.adv[0]) {
LOG_DBG("Ongoing tx transaction has not been completed yet");
return;
}

if (!link.rx.seg &&
next_transaction_id(link.rx.id) == rx->xact_id) {
LOG_DBG("Start segment lost");
Expand Down Expand Up @@ -575,21 +582,28 @@ static void gen_prov_start(struct prov_rx *rx, struct net_buf_simple *buf)
{
uint8_t seg = SEG_NVAL;

/* When link.rx.seg is zero for a valid link.rx.id, this means that transaction
* has already been received. The other device probably missed the Transaction
* Acknowledgment PDU, so we need to resend it regardless of the active transmission.
*/
if (rx->xact_id == link.rx.id && !link.rx.seg) {
/* Send ack if another ack is NOT pending for transmission. Otherwise, skip sending
* this ack for now.
*/
if (!ack_pending()) {
LOG_DBG("Resending ack");
gen_prov_ack_send(rx->xact_id);
}

return;
}

if (link.tx.adv[0]) {
LOG_DBG("Ongoing tx transaction has not been completed yet");
return;
}

if (rx->xact_id == link.rx.id) {
if (!link.rx.seg) {
if (!ack_pending()) {
LOG_DBG("Resending ack");
gen_prov_ack_send(rx->xact_id);
}

return;
}

if (!(link.rx.seg & BIT(0))) {
LOG_DBG("Ignoring duplicate segment");
return;
Expand Down Expand Up @@ -1057,6 +1071,12 @@ static int prov_link_accept(const struct prov_bearer_cb *cb, void *cb_data)
return 0;
}

static void prov_link_cancel(void)
{
bt_mesh_beacon_disable();
bt_mesh_scan_disable();
}

static void prov_link_close(enum prov_bearer_link_status status)
{
int err;
Expand Down Expand Up @@ -1095,6 +1115,7 @@ const struct prov_bearer bt_mesh_pb_adv = {
.type = BT_MESH_PROV_ADV,
.link_open = prov_link_open,
.link_accept = prov_link_accept,
.link_cancel = prov_link_cancel,
.link_close = prov_link_close,
.send = prov_send_adv,
.clear_tx = prov_clear_tx,
Expand Down
6 changes: 6 additions & 0 deletions subsys/bluetooth/mesh/pb_gatt.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@ static int link_accept(const struct prov_bearer_cb *cb, void *cb_data)

return 0;
}

static void link_cancel(void)
{
(void)bt_mesh_pb_gatt_srv_disable();
}
#endif

static void buf_send_end(struct bt_conn *conn, void *user_data)
Expand Down Expand Up @@ -246,6 +251,7 @@ const struct prov_bearer bt_mesh_pb_gatt = {
#endif
#if defined(CONFIG_BT_MESH_PB_GATT)
.link_accept = link_accept,
.link_cancel = link_cancel,
#endif
.send = buf_send,
.clear_tx = clear_tx,
Expand Down
6 changes: 6 additions & 0 deletions subsys/bluetooth/mesh/prov_bearer.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ struct prov_bearer {
*/
int (*link_accept)(const struct prov_bearer_cb *cb, void *cb_data);

/** @brief Disable link establishment as a provisionee.
*
* Stops accepting link open messages and sending unprovisioned beacons.
*/
void (*link_cancel)(void);

/** @brief Send a packet on an established link.
*
* @param buf Payload buffer. Requires @ref
Expand Down
Loading