Skip to content
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