Bluetooth: Mesh: split rpr cli ack ctx for provisionning and scanning

PR adds 2 acknowledgment contexts to RPR client to handle
scanning and provisioning in parallel.

Signed-off-by: Aleksandr Khromykh <aleksandr.khromykh@nordicsemi.no>
This commit is contained in:
Aleksandr Khromykh 2023-03-21 13:17:36 +01:00 committed by Fabio Baltieri
commit 9011a067f2
2 changed files with 26 additions and 24 deletions

View file

@ -84,7 +84,7 @@ static void tx_complete(struct bt_mesh_rpr_cli *cli, int err, void *cb_data)
LOG_DBG("%d", err);
cli->link.tx_pdu++;
bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx);
bt_mesh_msg_ack_ctx_clear(&cli->prov_ack_ctx);
if (bearer.tx.cb) {
bearer.tx.cb(err, cb_data);
@ -143,7 +143,7 @@ static int handle_link_report(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx
}
/* The server uses the link report to notify about failed tx */
if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, RPR_OP_LINK_REPORT,
if (bt_mesh_msg_ack_ctx_match(&cli->prov_ack_ctx, RPR_OP_LINK_REPORT,
srv.addr, &cb_data) &&
link.status != BT_MESH_RPR_SUCCESS) {
tx_complete(cli, -ECANCELED, cb_data);
@ -184,10 +184,10 @@ static int handle_link_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx
LOG_DBG("0x%04x: status: %u state: %u", srv.addr, link.status,
link.state);
if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, RPR_OP_LINK_STATUS,
if (bt_mesh_msg_ack_ctx_match(&cli->prov_ack_ctx, RPR_OP_LINK_STATUS,
srv.addr, (void **)&rsp)) {
*rsp = link;
bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
bt_mesh_msg_ack_ctx_rx(&cli->prov_ack_ctx);
}
if (cli->link.srv.addr == srv.addr) {
@ -223,7 +223,7 @@ static int handle_pdu_outbound_report(struct bt_mesh_model *mod, struct bt_mesh_
k_work_reschedule(&cli->link.timeout, K_SECONDS(cli->link.time));
if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, RPR_OP_PDU_OUTBOUND_REPORT,
if (!bt_mesh_msg_ack_ctx_match(&cli->prov_ack_ctx, RPR_OP_PDU_OUTBOUND_REPORT,
srv.addr, &cb_data) ||
num != cli->link.tx_pdu) {
LOG_WRN("Non-matching PDU report (%u)", num);
@ -273,7 +273,7 @@ static int handle_scan_caps_status(struct bt_mesh_model *mod, struct bt_mesh_msg
struct bt_mesh_rpr_node srv = RPR_NODE(ctx);
struct bt_mesh_rpr_caps *caps;
if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, RPR_OP_SCAN_CAPS_STATUS,
if (!bt_mesh_msg_ack_ctx_match(&cli->scan_ack_ctx, RPR_OP_SCAN_CAPS_STATUS,
srv.addr, (void **)&caps)) {
LOG_WRN("Unexpected scan caps rsp from 0x%04x", srv.addr);
return 0;
@ -285,7 +285,7 @@ static int handle_scan_caps_status(struct bt_mesh_model *mod, struct bt_mesh_msg
LOG_DBG("max devs: %u active scan: %u", caps->max_devs,
caps->active_scan);
bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
bt_mesh_msg_ack_ctx_rx(&cli->scan_ack_ctx);
return 0;
}
@ -329,7 +329,7 @@ static int handle_scan_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx
struct bt_mesh_rpr_scan_status *status;
struct bt_mesh_rpr_node srv = RPR_NODE(ctx);
if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, RPR_OP_SCAN_STATUS,
if (!bt_mesh_msg_ack_ctx_match(&cli->scan_ack_ctx, RPR_OP_SCAN_STATUS,
srv.addr, (void **)&status)) {
LOG_WRN("Unexpected scan status from 0x%04x", srv.addr);
return 0;
@ -342,7 +342,7 @@ static int handle_scan_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx
LOG_DBG("status: %u state: %u max devs: %u timeout: %u seconds",
status->status, status->scan, status->max_devs, status->timeout);
bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
bt_mesh_msg_ack_ctx_rx(&cli->scan_ack_ctx);
return 0;
}
@ -383,7 +383,8 @@ static int rpr_cli_init(struct bt_mesh_model *mod)
cli->mod = mod;
cli->link.time = LINK_TIMEOUT_SECONDS_DEFAULT;
bt_mesh_msg_ack_ctx_init(&cli->ack_ctx);
bt_mesh_msg_ack_ctx_init(&cli->scan_ack_ctx);
bt_mesh_msg_ack_ctx_init(&cli->prov_ack_ctx);
k_work_init_delayable(&cli->link.timeout, link_timeout);
mod->keys[0] = BT_MESH_KEY_DEV_ANY;
mod->flags |= BT_MESH_MOD_DEVKEY_ONLY;
@ -428,27 +429,27 @@ static const struct bt_mesh_send_cb pdu_send_cb = {
};
static int tx_wait(struct bt_mesh_rpr_cli *cli,
const struct bt_mesh_rpr_node *srv,
struct bt_mesh_msg_ack_ctx *ack_ctx, const struct bt_mesh_rpr_node *srv,
struct net_buf_simple *buf, uint32_t rsp, void *rsp_ctx)
{
struct bt_mesh_msg_ctx ctx = LINK_CTX(srv, false);
int err;
err = bt_mesh_msg_ack_ctx_prepare(&cli->ack_ctx, rsp, srv->addr, rsp_ctx);
err = bt_mesh_msg_ack_ctx_prepare(ack_ctx, rsp, srv->addr, rsp_ctx);
if (err) {
return err;
}
err = bt_mesh_model_send(cli->mod, &ctx, buf, NULL, NULL);
if (err) {
bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx);
bt_mesh_msg_ack_ctx_clear(ack_ctx);
LOG_WRN("TX fail");
return err;
}
err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(tx_timeout));
err = bt_mesh_msg_ack_ctx_wait(ack_ctx, K_MSEC(tx_timeout));
bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx);
bt_mesh_msg_ack_ctx_clear(ack_ctx);
return err;
}
@ -467,7 +468,7 @@ static void link_reset(struct bt_mesh_rpr_cli *cli)
k_work_cancel_delayable(&cli->link.timeout);
cli->link.srv.addr = BT_MESH_ADDR_UNASSIGNED;
cli->link.state = BT_MESH_RPR_LINK_IDLE;
bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx);
bt_mesh_msg_ack_ctx_clear(&cli->prov_ack_ctx);
}
static void link_closed(struct bt_mesh_rpr_cli *cli,
@ -494,7 +495,7 @@ int bt_mesh_rpr_scan_caps_get(struct bt_mesh_rpr_cli *cli,
BT_MESH_MODEL_BUF_DEFINE(buf, RPR_OP_SCAN_CAPS_GET, 0);
bt_mesh_model_msg_init(&buf, RPR_OP_SCAN_CAPS_GET);
return tx_wait(cli, srv, &buf, RPR_OP_SCAN_CAPS_STATUS, caps);
return tx_wait(cli, &cli->scan_ack_ctx, srv, &buf, RPR_OP_SCAN_CAPS_STATUS, caps);
}
int bt_mesh_rpr_scan_get(struct bt_mesh_rpr_cli *cli,
@ -504,7 +505,7 @@ int bt_mesh_rpr_scan_get(struct bt_mesh_rpr_cli *cli,
BT_MESH_MODEL_BUF_DEFINE(buf, RPR_OP_SCAN_GET, 0);
bt_mesh_model_msg_init(&buf, RPR_OP_SCAN_GET);
return tx_wait(cli, srv, &buf, RPR_OP_SCAN_STATUS, status);
return tx_wait(cli, &cli->scan_ack_ctx, srv, &buf, RPR_OP_SCAN_STATUS, status);
}
int bt_mesh_rpr_scan_start(struct bt_mesh_rpr_cli *cli,
@ -527,7 +528,7 @@ int bt_mesh_rpr_scan_start(struct bt_mesh_rpr_cli *cli,
net_buf_simple_add_mem(&buf, uuid, 16);
}
return tx_wait(cli, srv, &buf, RPR_OP_SCAN_STATUS, status);
return tx_wait(cli, &cli->scan_ack_ctx, srv, &buf, RPR_OP_SCAN_STATUS, status);
}
int bt_mesh_rpr_scan_start_ext(struct bt_mesh_rpr_cli *cli,
@ -564,7 +565,7 @@ int bt_mesh_rpr_scan_stop(struct bt_mesh_rpr_cli *cli,
BT_MESH_MODEL_BUF_DEFINE(buf, RPR_OP_SCAN_STOP, 0);
bt_mesh_model_msg_init(&buf, RPR_OP_SCAN_STOP);
return tx_wait(cli, srv, &buf, RPR_OP_SCAN_STATUS, status);
return tx_wait(cli, &cli->scan_ack_ctx, srv, &buf, RPR_OP_SCAN_STATUS, status);
}
int bt_mesh_rpr_link_get(struct bt_mesh_rpr_cli *cli,
@ -574,7 +575,7 @@ int bt_mesh_rpr_link_get(struct bt_mesh_rpr_cli *cli,
BT_MESH_MODEL_BUF_DEFINE(buf, RPR_OP_LINK_GET, 0);
bt_mesh_model_msg_init(&buf, RPR_OP_LINK_GET);
return tx_wait(cli, srv, &buf, RPR_OP_LINK_STATUS, rsp);
return tx_wait(cli, &cli->prov_ack_ctx, srv, &buf, RPR_OP_LINK_STATUS, rsp);
}
int bt_mesh_rpr_link_close(struct bt_mesh_rpr_cli *cli,
@ -585,7 +586,7 @@ int bt_mesh_rpr_link_close(struct bt_mesh_rpr_cli *cli,
bt_mesh_model_msg_init(&buf, RPR_OP_LINK_CLOSE);
net_buf_simple_add_u8(&buf, PROV_BEARER_LINK_STATUS_FAIL);
return tx_wait(cli, srv, &buf, RPR_OP_LINK_STATUS, rsp);
return tx_wait(cli, &cli->prov_ack_ctx, srv, &buf, RPR_OP_LINK_STATUS, rsp);
}
static int link_open_prov(struct bt_mesh_rpr_cli *cli,
@ -660,7 +661,7 @@ static int send(struct bt_mesh_rpr_cli *cli, struct net_buf_simple *buf,
return -EINVAL;
}
err = bt_mesh_msg_ack_ctx_prepare(&cli->ack_ctx,
err = bt_mesh_msg_ack_ctx_prepare(&cli->prov_ack_ctx,
RPR_OP_PDU_OUTBOUND_REPORT,
cli->link.srv.addr, cb_data);
if (err) {