Skip to content

Commit

Permalink
Bluetooth: Mesh: Add support for manipulating Label UUIDs
Browse files Browse the repository at this point in the history
Add support for sending messages that add, delete or overwrite Label
UUIDs, and add commands for these to the shell. With the help of these
commands it's possible to pass Transport Layer PTS tests (in
particular TNPT/BV-05-C) by manually adding a Label UUID through
module subscription, since the test case itself does not do this.

Signed-off-by: Johan Hedberg <[email protected]>
  • Loading branch information
Johan Hedberg authored and jhedberg committed Nov 24, 2017
1 parent 23ffed0 commit 35fd523
Show file tree
Hide file tree
Showing 3 changed files with 246 additions and 4 deletions.
26 changes: 26 additions & 0 deletions include/bluetooth/mesh/cfg_cli.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,32 @@ int bt_mesh_cfg_mod_sub_overwrite_vnd(u16_t net_idx, u16_t addr,
u16_t elem_addr, u16_t sub_addr,
u16_t mod_id, u16_t cid, u8_t *status);

int bt_mesh_cfg_mod_sub_va_add(u16_t net_idx, u16_t addr, u16_t elem_addr,
const u8_t label[16], u16_t mod_id,
u16_t *virt_addr, u8_t *status);

int bt_mesh_cfg_mod_sub_va_add_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
const u8_t label[16], u16_t mod_id,
u16_t cid, u16_t *virt_addr, u8_t *status);

int bt_mesh_cfg_mod_sub_va_del(u16_t net_idx, u16_t addr, u16_t elem_addr,
const u8_t label[16], u16_t mod_id,
u16_t *virt_addr, u8_t *status);

int bt_mesh_cfg_mod_sub_va_del_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
const u8_t label[16], u16_t mod_id,
u16_t cid, u16_t *virt_addr, u8_t *status);

int bt_mesh_cfg_mod_sub_va_overwrite(u16_t net_idx, u16_t addr,
u16_t elem_addr, const u8_t label[16],
u16_t mod_id, u16_t *virt_addr,
u8_t *status);

int bt_mesh_cfg_mod_sub_va_overwrite_vnd(u16_t net_idx, u16_t addr,
u16_t elem_addr, const u8_t label[16],
u16_t mod_id, u16_t cid,
u16_t *virt_addr, u8_t *status);

struct bt_mesh_cfg_hb_sub {
u16_t src;
u16_t dst;
Expand Down
127 changes: 123 additions & 4 deletions subsys/bluetooth/host/mesh/cfg_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,8 @@ static void mod_pub_status(struct bt_mesh_model *model,
struct mod_sub_param {
u8_t *status;
u16_t elem_addr;
u16_t sub_addr;
u16_t *sub_addr;
u16_t *expect_sub;
u16_t mod_id;
u16_t cid;
};
Expand Down Expand Up @@ -335,13 +336,17 @@ static void mod_sub_status(struct bt_mesh_model *model,
mod_id = net_buf_simple_pull_le16(buf);

param = cli->op_param;
if (param->elem_addr != elem_addr ||
param->sub_addr != sub_addr || param->mod_id != mod_id ||
if (param->elem_addr != elem_addr || param->mod_id != mod_id ||
(param->expect_sub && *param->expect_sub != sub_addr) ||
param->cid != cid) {
BT_WARN("Model Subscription Status parameters did not match");
return;
}

if (param->sub_addr) {
*param->sub_addr = sub_addr;
}

*param->status = status;

k_sem_give(&cli->op_sync);
Expand Down Expand Up @@ -788,7 +793,7 @@ static int mod_sub(u32_t op, u16_t net_idx, u16_t addr, u16_t elem_addr,
struct mod_sub_param param = {
.status = status,
.elem_addr = elem_addr,
.sub_addr = sub_addr,
.expect_sub = &sub_addr,
.mod_id = mod_id,
.cid = cid,
};
Expand Down Expand Up @@ -879,6 +884,120 @@ int bt_mesh_cfg_mod_sub_overwrite_vnd(u16_t net_idx, u16_t addr,
sub_addr, mod_id, cid, status);
}

static int mod_sub_va(u32_t op, u16_t net_idx, u16_t addr, u16_t elem_addr,
const u8_t label[16], u16_t mod_id, u16_t cid,
u16_t *virt_addr, u8_t *status)
{
struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 22 + 4);
struct bt_mesh_msg_ctx ctx = {
.net_idx = net_idx,
.app_idx = BT_MESH_KEY_DEV,
.addr = addr,
.send_ttl = BT_MESH_TTL_DEFAULT,
};
struct mod_sub_param param = {
.status = status,
.elem_addr = elem_addr,
.sub_addr = virt_addr,
.mod_id = mod_id,
.cid = cid,
};
int err;

err = check_cli();
if (err) {
return err;
}

BT_DBG("net_idx 0x%04x addr 0x%04x elem_addr 0x%04x label %s",
net_idx, addr, elem_addr, label);
BT_DBG("mod_id 0x%04x cid 0x%04x", mod_id, cid);

bt_mesh_model_msg_init(msg, op);
net_buf_simple_add_le16(msg, elem_addr);
net_buf_simple_add_mem(msg, label, 16);

if (cid != CID_NVAL) {
net_buf_simple_add_le16(msg, cid);
}

net_buf_simple_add_le16(msg, mod_id);

err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL);
if (err) {
BT_ERR("model_send() failed (err %d)", err);
return err;
}

if (!status) {
return 0;
}

return cli_wait(&param, OP_MOD_SUB_STATUS);
}

int bt_mesh_cfg_mod_sub_va_add(u16_t net_idx, u16_t addr, u16_t elem_addr,
const u8_t label[16], u16_t mod_id,
u16_t *virt_addr, u8_t *status)
{
return mod_sub_va(OP_MOD_SUB_VA_ADD, net_idx, addr, elem_addr, label,
mod_id, CID_NVAL, virt_addr, status);
}

int bt_mesh_cfg_mod_sub_va_add_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
const u8_t label[16], u16_t mod_id,
u16_t cid, u16_t *virt_addr, u8_t *status)
{
if (cid == CID_NVAL) {
return -EINVAL;
}

return mod_sub_va(OP_MOD_SUB_VA_ADD, net_idx, addr, elem_addr, label,
mod_id, cid, virt_addr, status);
}

int bt_mesh_cfg_mod_sub_va_del(u16_t net_idx, u16_t addr, u16_t elem_addr,
const u8_t label[16], u16_t mod_id,
u16_t *virt_addr, u8_t *status)
{
return mod_sub_va(OP_MOD_SUB_VA_DEL, net_idx, addr, elem_addr, label,
mod_id, CID_NVAL, virt_addr, status);
}

int bt_mesh_cfg_mod_sub_va_del_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
const u8_t label[16], u16_t mod_id,
u16_t cid, u16_t *virt_addr, u8_t *status)
{
if (cid == CID_NVAL) {
return -EINVAL;
}

return mod_sub_va(OP_MOD_SUB_VA_DEL, net_idx, addr, elem_addr, label,
mod_id, cid, virt_addr, status);
}

int bt_mesh_cfg_mod_sub_va_overwrite(u16_t net_idx, u16_t addr,
u16_t elem_addr, const u8_t label[16],
u16_t mod_id, u16_t *virt_addr,
u8_t *status)
{
return mod_sub_va(OP_MOD_SUB_VA_OVERWRITE, net_idx, addr, elem_addr,
label, mod_id, CID_NVAL, virt_addr, status);
}

int bt_mesh_cfg_mod_sub_va_overwrite_vnd(u16_t net_idx, u16_t addr,
u16_t elem_addr, const u8_t label[16],
u16_t mod_id, u16_t cid,
u16_t *virt_addr, u8_t *status)
{
if (cid == CID_NVAL) {
return -EINVAL;
}

return mod_sub_va(OP_MOD_SUB_VA_OVERWRITE, net_idx, addr, elem_addr,
label, mod_id, cid, virt_addr, status);
}

static int mod_pub_get(u16_t net_idx, u16_t addr, u16_t elem_addr,
u16_t mod_id, u16_t cid,
struct bt_mesh_cfg_mod_pub *pub, u8_t *status)
Expand Down
97 changes: 97 additions & 0 deletions subsys/bluetooth/host/mesh/shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,99 @@ static int cmd_mod_sub_del(int argc, char *argv[])
return 0;
}

static int cmd_mod_sub_add_va(int argc, char *argv[])
{
u16_t elem_addr, sub_addr, mod_id, cid;
u8_t label[16];
u8_t status;
size_t len;
int err;

if (argc < 4) {
return -EINVAL;
}

elem_addr = strtoul(argv[1], NULL, 0);

len = hex2bin(argv[2], label, sizeof(label));
memset(label + len, 0, sizeof(label) - len);

mod_id = strtoul(argv[3], NULL, 0);

if (argc > 4) {
cid = strtoul(argv[4], NULL, 0);
err = bt_mesh_cfg_mod_sub_va_add_vnd(net.net_idx, net.dst,
elem_addr, label, mod_id,
cid, &sub_addr, &status);
} else {
err = bt_mesh_cfg_mod_sub_va_add(net.net_idx, net.dst,
elem_addr, label, mod_id,
&sub_addr, &status);
}

if (err) {
printk("Unable to send Mod Sub VA Add (err %d)\n", err);
return 0;
}

if (status) {
printk("Mod Sub VA Add failed with status 0x%02x\n",
status);
} else {
printk("0x%04x subscribed to Label UUID %s (va 0x%04x)\n",
elem_addr, argv[2], sub_addr);
}

return 0;
}

static int cmd_mod_sub_del_va(int argc, char *argv[])
{
u16_t elem_addr, sub_addr, mod_id, cid;
u8_t label[16];
u8_t status;
size_t len;
int err;

if (argc < 4) {
return -EINVAL;
}

elem_addr = strtoul(argv[1], NULL, 0);

len = hex2bin(argv[2], label, sizeof(label));
memset(label + len, 0, sizeof(label) - len);

mod_id = strtoul(argv[3], NULL, 0);

if (argc > 4) {
cid = strtoul(argv[4], NULL, 0);
err = bt_mesh_cfg_mod_sub_va_del_vnd(net.net_idx, net.dst,
elem_addr, label, mod_id,
cid, &sub_addr, &status);
} else {
err = bt_mesh_cfg_mod_sub_va_del(net.net_idx, net.dst,
elem_addr, label, mod_id,
&sub_addr, &status);
}

if (err) {
printk("Unable to send Model Subscription Delete (err %d)\n",
err);
return 0;
}

if (status) {
printk("Model Subscription Delete failed with status 0x%02x\n",
status);
} else {
printk("0x%04x unsubscribed from Label UUID %s (va 0x%04x)\n",
elem_addr, argv[2], sub_addr);
}

return 0;
}

static int mod_pub_get(u16_t addr, u16_t mod_id, u16_t cid)
{
struct bt_mesh_cfg_mod_pub pub;
Expand Down Expand Up @@ -1685,6 +1778,10 @@ static const struct shell_cmd mesh_commands[] = {
"<elem addr> <sub addr> <Model ID> [Company ID]" },
{ "mod-sub-del", cmd_mod_sub_del,
"<elem addr> <sub addr> <Model ID> [Company ID]" },
{ "mod-sub-add-va", cmd_mod_sub_add_va,
"<elem addr> <Label UUID> <Model ID> [Company ID]" },
{ "mod-sub-del-va", cmd_mod_sub_del_va,
"<elem addr> <Label UUID> <Model ID> [Company ID]" },
{ "hb-sub", cmd_hb_sub, "[<src> <dst> <period>]" },
{ "hb-pub", cmd_hb_pub,
"[<dst> <count> <period> <ttl> <features> <NetKeyIndex>]" },
Expand Down

0 comments on commit 35fd523

Please sign in to comment.