Merge pull request #28 from michal-narajowski/mesh_cli

mesh: Fix possible race condition and other issues
This commit is contained in:
Michał Narajowski
2018-04-10 13:35:06 +02:00
committed by GitHub
5 changed files with 139 additions and 73 deletions
+88 -46
View File
@@ -163,7 +163,9 @@ static void net_key_status(struct bt_mesh_model *model,
return;
}
*param->status = status;
if (param->status) {
*param->status = status;
}
k_sem_give(&cli->op_sync);
}
@@ -200,7 +202,9 @@ static void app_key_status(struct bt_mesh_model *model,
return;
}
*param->status = status;
if (param->status) {
*param->status = status;
}
k_sem_give(&cli->op_sync);
}
@@ -250,7 +254,9 @@ static void mod_app_status(struct bt_mesh_model *model,
return;
}
*param->status = status;
if (param->status) {
*param->status = status;
}
k_sem_give(&cli->op_sync);
}
@@ -313,7 +319,9 @@ static void mod_pub_status(struct bt_mesh_model *model,
return;
}
*param->status = status;
if (param->status) {
*param->status = status;
}
if (param->pub) {
param->pub->addr = net_buf_simple_pull_le16(buf);
@@ -378,7 +386,9 @@ static void mod_sub_status(struct bt_mesh_model *model,
*param->sub_addr = sub_addr;
}
*param->status = status;
if (param->status) {
*param->status = status;
}
k_sem_give(&cli->op_sync);
}
@@ -470,7 +480,7 @@ const struct bt_mesh_model_op bt_mesh_cfg_cli_op[] = {
BT_MESH_MODEL_OP_END,
};
static int check_cli(void)
static int cli_prepare(void *param, u32_t op)
{
if (!cli) {
BT_ERR("No available Configuration Client context!");
@@ -482,20 +492,25 @@ static int check_cli(void)
return -EBUSY;
}
return 0;
}
static int cli_wait(void *param, u32_t op)
{
int err;
cli->op_param = param;
cli->op_pending = op;
err = k_sem_take(&cli->op_sync, msg_timeout);
return 0;
}
static void cli_reset(void)
{
cli->op_pending = 0;
cli->op_param = NULL;
}
static int cli_wait(void)
{
int err;
err = k_sem_take(&cli->op_sync, msg_timeout);
cli_reset();
return err;
}
@@ -516,7 +531,7 @@ int bt_mesh_cfg_comp_data_get(u16_t net_idx, u16_t addr, u8_t page,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_DEV_COMP_DATA_STATUS);
if (err) {
goto done;
}
@@ -527,10 +542,11 @@ int bt_mesh_cfg_comp_data_get(u16_t net_idx, u16_t addr, u8_t page,
err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
err = cli_wait(&param, OP_DEV_COMP_DATA_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -548,7 +564,7 @@ static int get_state_u8(u16_t net_idx, u16_t addr, u32_t op, u32_t rsp,
};
int err;
err = check_cli();
err = cli_prepare(val, rsp);
if (err) {
goto done;
}
@@ -558,10 +574,11 @@ static int get_state_u8(u16_t net_idx, u16_t addr, u32_t op, u32_t rsp,
err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
err = cli_wait(val, rsp);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -579,7 +596,7 @@ static int set_state_u8(u16_t net_idx, u16_t addr, u32_t op, u32_t rsp,
};
int err;
err = check_cli();
err = cli_prepare(val, rsp);
if (err) {
goto done;
}
@@ -590,10 +607,11 @@ static int set_state_u8(u16_t net_idx, u16_t addr, u32_t op, u32_t rsp,
err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
err = cli_wait(val, rsp);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -664,7 +682,7 @@ int bt_mesh_cfg_relay_get(u16_t net_idx, u16_t addr, u8_t *status,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_RELAY_STATUS);
if (err) {
goto done;
}
@@ -674,10 +692,11 @@ int bt_mesh_cfg_relay_get(u16_t net_idx, u16_t addr, u8_t *status,
err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
err = cli_wait(&param, OP_RELAY_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -699,7 +718,7 @@ int bt_mesh_cfg_relay_set(u16_t net_idx, u16_t addr, u8_t new_relay,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_RELAY_STATUS);
if (err) {
goto done;
}
@@ -711,10 +730,11 @@ int bt_mesh_cfg_relay_set(u16_t net_idx, u16_t addr, u8_t new_relay,
err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
err = cli_wait(&param, OP_RELAY_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -736,7 +756,7 @@ int bt_mesh_cfg_net_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_NET_KEY_STATUS);
if (err) {
goto done;
}
@@ -748,14 +768,16 @@ int bt_mesh_cfg_net_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx,
err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
if (!status) {
cli_reset();
goto done;
}
err = cli_wait(&param, OP_NET_KEY_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -779,7 +801,7 @@ int bt_mesh_cfg_app_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_APP_KEY_STATUS);
if (err) {
goto done;
}
@@ -791,14 +813,16 @@ int bt_mesh_cfg_app_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx,
err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
if (!status) {
cli_reset();
goto done;
}
err = cli_wait(&param, OP_APP_KEY_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -824,7 +848,7 @@ static int mod_app_bind(u16_t net_idx, u16_t addr, u16_t elem_addr,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_MOD_APP_STATUS);
if (err) {
goto done;
}
@@ -842,14 +866,16 @@ static int mod_app_bind(u16_t net_idx, u16_t addr, u16_t elem_addr,
err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
if (!status) {
cli_reset();
goto done;
}
err = cli_wait(&param, OP_MOD_APP_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -893,7 +919,7 @@ static int mod_sub(u32_t op, u16_t net_idx, u16_t addr, u16_t elem_addr,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_MOD_SUB_STATUS);
if (err) {
goto done;
}
@@ -911,14 +937,16 @@ static int mod_sub(u32_t op, u16_t net_idx, u16_t addr, u16_t elem_addr,
err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
if (!status) {
cli_reset();
goto done;
}
err = cli_wait(&param, OP_MOD_SUB_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -1001,7 +1029,7 @@ static int mod_sub_va(u32_t op, u16_t net_idx, u16_t addr, u16_t elem_addr,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_MOD_SUB_STATUS);
if (err) {
goto done;
}
@@ -1023,14 +1051,16 @@ static int mod_sub_va(u32_t op, u16_t net_idx, u16_t addr, u16_t elem_addr,
err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
if (!status) {
cli_reset();
goto done;
}
err = cli_wait(&param, OP_MOD_SUB_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -1118,7 +1148,7 @@ static int mod_pub_get(u16_t net_idx, u16_t addr, u16_t elem_addr,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_MOD_PUB_STATUS);
if (err) {
goto done;
}
@@ -1136,14 +1166,16 @@ static int mod_pub_get(u16_t net_idx, u16_t addr, u16_t elem_addr,
err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
if (!status) {
cli_reset();
goto done;
}
err = cli_wait(&param, OP_MOD_PUB_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -1188,7 +1220,7 @@ static int mod_pub_set(u16_t net_idx, u16_t addr, u16_t elem_addr,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_MOD_PUB_STATUS);
if (err) {
goto done;
}
@@ -1211,14 +1243,16 @@ static int mod_pub_set(u16_t net_idx, u16_t addr, u16_t elem_addr,
err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
if (!status) {
cli_reset();
goto done;
}
err = cli_wait(&param, OP_MOD_PUB_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -1259,7 +1293,7 @@ int bt_mesh_cfg_hb_sub_set(u16_t net_idx, u16_t addr,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_HEARTBEAT_SUB_STATUS);
if (err) {
goto done;
}
@@ -1272,14 +1306,16 @@ int bt_mesh_cfg_hb_sub_set(u16_t net_idx, u16_t addr,
err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
if (!status) {
cli_reset();
goto done;
}
err = cli_wait(&param, OP_HEARTBEAT_SUB_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -1301,7 +1337,7 @@ int bt_mesh_cfg_hb_sub_get(u16_t net_idx, u16_t addr,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_HEARTBEAT_SUB_STATUS);
if (err) {
goto done;
}
@@ -1311,14 +1347,16 @@ int bt_mesh_cfg_hb_sub_get(u16_t net_idx, u16_t addr,
err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
if (!status) {
cli_reset();
goto done;
}
err = cli_wait(&param, OP_HEARTBEAT_SUB_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -1339,7 +1377,7 @@ int bt_mesh_cfg_hb_pub_set(u16_t net_idx, u16_t addr,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_HEARTBEAT_PUB_STATUS);
if (err) {
goto done;
}
@@ -1355,14 +1393,16 @@ int bt_mesh_cfg_hb_pub_set(u16_t net_idx, u16_t addr,
err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
if (!status) {
cli_reset();
goto done;
}
err = cli_wait(&param, OP_HEARTBEAT_PUB_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -1384,7 +1424,7 @@ int bt_mesh_cfg_hb_pub_get(u16_t net_idx, u16_t addr,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_HEARTBEAT_PUB_STATUS);
if (err) {
goto done;
}
@@ -1394,14 +1434,16 @@ int bt_mesh_cfg_hb_pub_get(u16_t net_idx, u16_t addr,
err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
if (!status) {
cli_reset();
goto done;
}
err = cli_wait(&param, OP_HEARTBEAT_PUB_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
+42 -24
View File
@@ -154,7 +154,9 @@ static void health_attention_status(struct bt_mesh_model *model,
param = health_cli->op_param;
*param->attention = net_buf_simple_pull_u8(buf);
if (param->attention) {
*param->attention = net_buf_simple_pull_u8(buf);
}
k_sem_give(&health_cli->op_sync);
}
@@ -167,7 +169,7 @@ const struct bt_mesh_model_op bt_mesh_health_cli_op[] = {
BT_MESH_MODEL_OP_END,
};
static int check_cli(void)
static int cli_prepare(void *param, u32_t op)
{
if (!health_cli) {
BT_ERR("No available Health Client context!");
@@ -179,20 +181,25 @@ static int check_cli(void)
return -EBUSY;
}
return 0;
}
static int cli_wait(void *param, u32_t op)
{
int err;
health_cli->op_param = param;
health_cli->op_pending = op;
err = k_sem_take(&health_cli->op_sync, msg_timeout);
return 0;
}
static void cli_reset(void)
{
health_cli->op_pending = 0;
health_cli->op_param = NULL;
}
static int cli_wait(void)
{
int err;
err = k_sem_take(&health_cli->op_sync, msg_timeout);
cli_reset();
return err;
}
@@ -212,7 +219,7 @@ int bt_mesh_health_attention_get(u16_t net_idx, u16_t addr, u16_t app_idx,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_ATTENTION_STATUS);
if (err) {
goto done;
}
@@ -222,10 +229,11 @@ int bt_mesh_health_attention_get(u16_t net_idx, u16_t addr, u16_t app_idx,
err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
err = cli_wait(&param, OP_ATTENTION_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -246,7 +254,7 @@ int bt_mesh_health_attention_set(u16_t net_idx, u16_t addr, u16_t app_idx,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_ATTENTION_STATUS);
if (err) {
goto done;
}
@@ -262,14 +270,16 @@ int bt_mesh_health_attention_set(u16_t net_idx, u16_t addr, u16_t app_idx,
err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
if (!updated_attention) {
cli_reset();
goto done;
}
err = cli_wait(&param, OP_ATTENTION_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -290,7 +300,7 @@ int bt_mesh_health_period_get(u16_t net_idx, u16_t addr, u16_t app_idx,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_HEALTH_PERIOD_STATUS);
if (err) {
goto done;
}
@@ -300,10 +310,11 @@ int bt_mesh_health_period_get(u16_t net_idx, u16_t addr, u16_t app_idx,
err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
err = cli_wait(&param, OP_HEALTH_PERIOD_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -324,7 +335,7 @@ int bt_mesh_health_period_set(u16_t net_idx, u16_t addr, u16_t app_idx,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_HEALTH_PERIOD_STATUS);
if (err) {
goto done;
}
@@ -340,14 +351,16 @@ int bt_mesh_health_period_set(u16_t net_idx, u16_t addr, u16_t app_idx,
err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
if (!updated_divisor) {
cli_reset();
goto done;
}
err = cli_wait(&param, OP_HEALTH_PERIOD_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -372,7 +385,7 @@ int bt_mesh_health_fault_test(u16_t net_idx, u16_t addr, u16_t app_idx,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_HEALTH_FAULT_STATUS);
if (err) {
goto done;
}
@@ -389,14 +402,16 @@ int bt_mesh_health_fault_test(u16_t net_idx, u16_t addr, u16_t app_idx,
err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
if (!faults) {
cli_reset();
goto done;
}
err = cli_wait(&param, OP_HEALTH_FAULT_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -421,7 +436,7 @@ int bt_mesh_health_fault_clear(u16_t net_idx, u16_t addr, u16_t app_idx,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_HEALTH_FAULT_STATUS);
if (err) {
goto done;
}
@@ -437,14 +452,16 @@ int bt_mesh_health_fault_clear(u16_t net_idx, u16_t addr, u16_t app_idx,
err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
if (!test_id) {
cli_reset();
goto done;
}
err = cli_wait(&param, OP_HEALTH_FAULT_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
@@ -469,7 +486,7 @@ int bt_mesh_health_fault_get(u16_t net_idx, u16_t addr, u16_t app_idx,
};
int err;
err = check_cli();
err = cli_prepare(&param, OP_HEALTH_FAULT_STATUS);
if (err) {
goto done;
}
@@ -480,10 +497,11 @@ int bt_mesh_health_fault_get(u16_t net_idx, u16_t addr, u16_t app_idx,
err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
cli_reset();
goto done;
}
err = cli_wait(&param, OP_HEALTH_FAULT_STATUS);
err = cli_wait();
done:
os_mbuf_free_chain(msg);
return err;
+1 -2
View File
@@ -476,8 +476,7 @@ int bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16],
sub->net_idx = idx;
if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY))) {
sub->node_id = BT_MESH_NODE_IDENTITY_RUNNING;
sub->node_id_start = k_uptime_get_32();
sub->node_id = BT_MESH_NODE_IDENTITY_STOPPED;
} else {
sub->node_id = BT_MESH_NODE_IDENTITY_NOT_SUPPORTED;
}
+7
View File
@@ -1073,6 +1073,13 @@ static void prov_data(const u8_t *data)
bt_mesh_provision(pdu, net_idx, flags, iv_index, 0, addr, dev_key);
#if MYNEWT_VAL(BLE_MESH_PB_GATT) && MYNEWT_VAL(BLE_MESH_GATT_PROXY)
/* After PB-GATT provisioning we should start advertising
* using Node Identity.
*/
bt_mesh_proxy_identity_enable();
#endif
done:
os_mbuf_free_chain(msg);
}
+1 -1
View File
@@ -133,7 +133,7 @@ void bt_test_print_credentials(void)
for (i = 0; i < MYNEWT_VAL(BLE_MESH_SUBNET_COUNT); ++i)
{
if (bt_mesh.app_keys[i].net_idx == BT_MESH_KEY_UNUSED) {
if (bt_mesh.sub[i].net_idx == BT_MESH_KEY_UNUSED) {
continue;
}