in nimble/host/mesh/src/cfg_srv.c [1469:1549]
static int mod_sub_va_add(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct os_mbuf *buf)
{
uint16_t elem_addr, sub_addr;
struct bt_mesh_model *mod;
struct bt_mesh_elem *elem;
uint8_t *label_uuid;
uint8_t *mod_id;
uint16_t *entry;
uint8_t status;
bool vnd;
if ((buf->om_len != 20U) && (buf->om_len != 22U)) {
BT_ERR("The message size for the application opcode is incorrect.");
return -EMSGSIZE;
}
elem_addr = net_buf_simple_pull_le16(buf);
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
BT_WARN("Prohibited element address");
return -EINVAL;
}
label_uuid = net_buf_simple_pull_mem(buf, 16);
BT_DBG("elem_addr 0x%04x", elem_addr);
mod_id = buf->om_data;
elem = bt_mesh_elem_find(elem_addr);
if (!elem) {
mod = NULL;
vnd = (buf->om_len == 4);
sub_addr = BT_MESH_ADDR_UNASSIGNED;
status = STATUS_INVALID_ADDRESS;
goto send_status;
}
mod = get_model(elem, buf, &vnd);
if (!mod) {
sub_addr = BT_MESH_ADDR_UNASSIGNED;
status = STATUS_INVALID_MODEL;
goto send_status;
}
status = bt_mesh_va_add(label_uuid, &sub_addr);
if (status != STATUS_SUCCESS) {
goto send_status;
}
if (bt_mesh_model_find_group(&mod, sub_addr)) {
/* Tried to add existing subscription */
status = STATUS_SUCCESS;
bt_mesh_va_del(label_uuid, NULL);
goto send_status;
}
entry = bt_mesh_model_find_group(&mod, BT_MESH_ADDR_UNASSIGNED);
if (!entry) {
status = STATUS_INSUFF_RESOURCES;
bt_mesh_va_del(label_uuid, NULL);
goto send_status;
}
*entry = sub_addr;
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
bt_mesh_lpn_group_add(sub_addr);
}
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_mesh_model_sub_store(mod);
}
status = STATUS_SUCCESS;
send_status:
return send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
mod_id, vnd);
}