Bluetooth: Mesh: Move labels to transport
Moves the virtual address labels to the transport layer, disconnecting them from the configuration server. Signed-off-by: Trond Einar Snekvik <Trond.Einar.Snekvik@nordicsemi.no>
This commit is contained in:
parent
c9be68532c
commit
af5bd00d1c
7 changed files with 174 additions and 342 deletions
|
@ -42,12 +42,6 @@
|
||||||
|
|
||||||
static struct bt_mesh_cfg_srv *conf;
|
static struct bt_mesh_cfg_srv *conf;
|
||||||
|
|
||||||
static struct label labels[CONFIG_BT_MESH_LABEL_COUNT];
|
|
||||||
|
|
||||||
#if CONFIG_BT_MESH_LABEL_COUNT > 0
|
|
||||||
static uint8_t va_del(uint8_t *label_uuid, uint16_t *addr);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem,
|
static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem,
|
||||||
bool primary)
|
bool primary)
|
||||||
{
|
{
|
||||||
|
@ -225,10 +219,10 @@ static uint8_t _mod_pub_set(struct bt_mesh_model *model, uint16_t pub_addr,
|
||||||
|
|
||||||
#if CONFIG_BT_MESH_LABEL_COUNT > 0
|
#if CONFIG_BT_MESH_LABEL_COUNT > 0
|
||||||
if (BT_MESH_ADDR_IS_VIRTUAL(model->pub->addr)) {
|
if (BT_MESH_ADDR_IS_VIRTUAL(model->pub->addr)) {
|
||||||
uint8_t *uuid = bt_mesh_label_uuid_get(model->pub->addr);
|
uint8_t *uuid = bt_mesh_va_label_get(model->pub->addr);
|
||||||
|
|
||||||
if (uuid) {
|
if (uuid) {
|
||||||
va_del(uuid, NULL);
|
bt_mesh_va_del(uuid, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -896,100 +890,6 @@ send_status:
|
||||||
status, mod_id);
|
status, mod_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct label *get_label(uint16_t index)
|
|
||||||
{
|
|
||||||
if (index >= ARRAY_SIZE(labels)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return &labels[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CONFIG_BT_MESH_LABEL_COUNT > 0
|
|
||||||
static inline void va_store(struct label *store)
|
|
||||||
{
|
|
||||||
atomic_set_bit(store->flags, BT_MESH_VA_CHANGED);
|
|
||||||
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
|
||||||
bt_mesh_store_label();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct label *va_find(const uint8_t *label_uuid,
|
|
||||||
struct label **free_slot)
|
|
||||||
{
|
|
||||||
struct label *match = NULL;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (free_slot != NULL) {
|
|
||||||
*free_slot = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(labels); i++) {
|
|
||||||
if (labels[i].ref == 0) {
|
|
||||||
if (free_slot != NULL) {
|
|
||||||
*free_slot = &labels[i];
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!memcmp(labels[i].uuid, label_uuid, 16)) {
|
|
||||||
match = &labels[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t va_add(uint8_t *label_uuid, uint16_t *addr)
|
|
||||||
{
|
|
||||||
struct label *update, *free_slot = NULL;
|
|
||||||
|
|
||||||
update = va_find(label_uuid, &free_slot);
|
|
||||||
if (update) {
|
|
||||||
update->ref++;
|
|
||||||
va_store(update);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!free_slot) {
|
|
||||||
return STATUS_INSUFF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bt_mesh_virtual_addr(label_uuid, addr) < 0) {
|
|
||||||
return STATUS_UNSPECIFIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
free_slot->ref = 1U;
|
|
||||||
free_slot->addr = *addr;
|
|
||||||
memcpy(free_slot->uuid, label_uuid, 16);
|
|
||||||
va_store(free_slot);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t va_del(uint8_t *label_uuid, uint16_t *addr)
|
|
||||||
{
|
|
||||||
struct label *update;
|
|
||||||
|
|
||||||
update = va_find(label_uuid, NULL);
|
|
||||||
if (update) {
|
|
||||||
update->ref--;
|
|
||||||
|
|
||||||
if (addr) {
|
|
||||||
*addr = update->addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
va_store(update);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addr) {
|
|
||||||
*addr = BT_MESH_ADDR_UNASSIGNED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_CANNOT_REMOVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t mod_sub_list_clear(struct bt_mesh_model *mod)
|
static size_t mod_sub_list_clear(struct bt_mesh_model *mod)
|
||||||
{
|
{
|
||||||
uint8_t *label_uuid;
|
uint8_t *label_uuid;
|
||||||
|
@ -1007,13 +907,13 @@ static size_t mod_sub_list_clear(struct bt_mesh_model *mod)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
label_uuid = bt_mesh_label_uuid_get(mod->groups[i]);
|
label_uuid = bt_mesh_va_label_get(mod->groups[i]);
|
||||||
|
|
||||||
mod->groups[i] = BT_MESH_ADDR_UNASSIGNED;
|
mod->groups[i] = BT_MESH_ADDR_UNASSIGNED;
|
||||||
clear_count++;
|
clear_count++;
|
||||||
|
|
||||||
if (label_uuid) {
|
if (label_uuid) {
|
||||||
va_del(label_uuid, NULL);
|
bt_mesh_va_del(label_uuid, NULL);
|
||||||
} else {
|
} else {
|
||||||
BT_ERR("Label UUID not found");
|
BT_ERR("Label UUID not found");
|
||||||
}
|
}
|
||||||
|
@ -1077,7 +977,7 @@ static void mod_pub_va_set(struct bt_mesh_model *model,
|
||||||
goto send_status;
|
goto send_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = va_add(label_uuid, &pub_addr);
|
status = bt_mesh_va_add(label_uuid, &pub_addr);
|
||||||
if (status != STATUS_SUCCESS) {
|
if (status != STATUS_SUCCESS) {
|
||||||
goto send_status;
|
goto send_status;
|
||||||
}
|
}
|
||||||
|
@ -1085,81 +985,13 @@ static void mod_pub_va_set(struct bt_mesh_model *model,
|
||||||
status = _mod_pub_set(mod, pub_addr, pub_app_idx, cred_flag, pub_ttl,
|
status = _mod_pub_set(mod, pub_addr, pub_app_idx, cred_flag, pub_ttl,
|
||||||
pub_period, retransmit, true);
|
pub_period, retransmit, true);
|
||||||
if (status != STATUS_SUCCESS) {
|
if (status != STATUS_SUCCESS) {
|
||||||
va_del(label_uuid, NULL);
|
bt_mesh_va_del(label_uuid, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
send_status:
|
send_status:
|
||||||
send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod,
|
send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod,
|
||||||
status, mod_id);
|
status, mod_id);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static size_t mod_sub_list_clear(struct bt_mesh_model *mod)
|
|
||||||
{
|
|
||||||
size_t clear_count;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Unref stored labels related to this model */
|
|
||||||
for (i = 0, clear_count = 0; i < ARRAY_SIZE(mod->groups); i++) {
|
|
||||||
if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) {
|
|
||||||
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
|
|
||||||
bt_mesh_lpn_group_del(&mod->groups[i], 1);
|
|
||||||
}
|
|
||||||
mod->groups[i] = BT_MESH_ADDR_UNASSIGNED;
|
|
||||||
clear_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return clear_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mod_pub_va_set(struct bt_mesh_model *model,
|
|
||||||
struct bt_mesh_msg_ctx *ctx,
|
|
||||||
struct net_buf_simple *buf)
|
|
||||||
{
|
|
||||||
uint8_t *mod_id, status;
|
|
||||||
struct bt_mesh_model *mod;
|
|
||||||
struct bt_mesh_elem *elem;
|
|
||||||
uint16_t elem_addr, pub_addr = 0U;
|
|
||||||
bool vnd;
|
|
||||||
|
|
||||||
elem_addr = net_buf_simple_pull_le16(buf);
|
|
||||||
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
|
|
||||||
BT_WARN("Prohibited element address");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
net_buf_simple_pull(buf, 16);
|
|
||||||
mod_id = net_buf_simple_pull(buf, 4);
|
|
||||||
|
|
||||||
BT_DBG("elem_addr 0x%04x", elem_addr);
|
|
||||||
|
|
||||||
elem = bt_mesh_elem_find(elem_addr);
|
|
||||||
if (!elem) {
|
|
||||||
mod = NULL;
|
|
||||||
vnd = (buf->len == 4U);
|
|
||||||
status = STATUS_INVALID_ADDRESS;
|
|
||||||
goto send_status;
|
|
||||||
}
|
|
||||||
|
|
||||||
mod = get_model(elem, buf, &vnd);
|
|
||||||
if (!mod) {
|
|
||||||
status = STATUS_INVALID_MODEL;
|
|
||||||
goto send_status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mod->pub) {
|
|
||||||
status = STATUS_NVAL_PUB_PARAM;
|
|
||||||
goto send_status;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub_addr = mod->pub->addr;
|
|
||||||
status = STATUS_INSUFF_RESOURCES;
|
|
||||||
|
|
||||||
send_status:
|
|
||||||
send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod,
|
|
||||||
status, mod_id);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_BT_MESH_LABEL_COUNT > 0 */
|
|
||||||
|
|
||||||
static void send_mod_sub_status(struct bt_mesh_model *model,
|
static void send_mod_sub_status(struct bt_mesh_model *model,
|
||||||
struct bt_mesh_msg_ctx *ctx, uint8_t status,
|
struct bt_mesh_msg_ctx *ctx, uint8_t status,
|
||||||
|
@ -1604,7 +1436,6 @@ send_list:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_BT_MESH_LABEL_COUNT > 0
|
|
||||||
static void mod_sub_va_add(struct bt_mesh_model *model,
|
static void mod_sub_va_add(struct bt_mesh_model *model,
|
||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
|
@ -1645,7 +1476,7 @@ static void mod_sub_va_add(struct bt_mesh_model *model,
|
||||||
goto send_status;
|
goto send_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = va_add(label_uuid, &sub_addr);
|
status = bt_mesh_va_add(label_uuid, &sub_addr);
|
||||||
if (status != STATUS_SUCCESS) {
|
if (status != STATUS_SUCCESS) {
|
||||||
goto send_status;
|
goto send_status;
|
||||||
}
|
}
|
||||||
|
@ -1653,7 +1484,7 @@ static void mod_sub_va_add(struct bt_mesh_model *model,
|
||||||
if (bt_mesh_model_find_group(&mod, sub_addr)) {
|
if (bt_mesh_model_find_group(&mod, sub_addr)) {
|
||||||
/* Tried to add existing subscription */
|
/* Tried to add existing subscription */
|
||||||
status = STATUS_SUCCESS;
|
status = STATUS_SUCCESS;
|
||||||
va_del(label_uuid, NULL);
|
bt_mesh_va_del(label_uuid, NULL);
|
||||||
goto send_status;
|
goto send_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1661,7 +1492,7 @@ static void mod_sub_va_add(struct bt_mesh_model *model,
|
||||||
entry = bt_mesh_model_find_group(&mod, BT_MESH_ADDR_UNASSIGNED);
|
entry = bt_mesh_model_find_group(&mod, BT_MESH_ADDR_UNASSIGNED);
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
status = STATUS_INSUFF_RESOURCES;
|
status = STATUS_INSUFF_RESOURCES;
|
||||||
va_del(label_uuid, NULL);
|
bt_mesh_va_del(label_uuid, NULL);
|
||||||
goto send_status;
|
goto send_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1723,7 +1554,7 @@ static void mod_sub_va_del(struct bt_mesh_model *model,
|
||||||
goto send_status;
|
goto send_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = va_del(label_uuid, &sub_addr);
|
status = bt_mesh_va_del(label_uuid, &sub_addr);
|
||||||
if (sub_addr == BT_MESH_ADDR_UNASSIGNED) {
|
if (sub_addr == BT_MESH_ADDR_UNASSIGNED) {
|
||||||
goto send_status;
|
goto send_status;
|
||||||
}
|
}
|
||||||
|
@ -1791,7 +1622,7 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model,
|
||||||
|
|
||||||
if (ARRAY_SIZE(mod->groups) > 0) {
|
if (ARRAY_SIZE(mod->groups) > 0) {
|
||||||
|
|
||||||
status = va_add(label_uuid, &sub_addr);
|
status = bt_mesh_va_add(label_uuid, &sub_addr);
|
||||||
if (status == STATUS_SUCCESS) {
|
if (status == STATUS_SUCCESS) {
|
||||||
bt_mesh_model_tree_walk(bt_mesh_model_root(mod),
|
bt_mesh_model_tree_walk(bt_mesh_model_root(mod),
|
||||||
mod_sub_clear_visitor, NULL);
|
mod_sub_clear_visitor, NULL);
|
||||||
|
@ -1813,127 +1644,6 @@ send_status:
|
||||||
send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
|
send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
|
||||||
mod_id, vnd);
|
mod_id, vnd);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static void mod_sub_va_add(struct bt_mesh_model *model,
|
|
||||||
struct bt_mesh_msg_ctx *ctx,
|
|
||||||
struct net_buf_simple *buf)
|
|
||||||
{
|
|
||||||
struct bt_mesh_model *mod;
|
|
||||||
struct bt_mesh_elem *elem;
|
|
||||||
uint16_t elem_addr;
|
|
||||||
uint8_t *mod_id;
|
|
||||||
uint8_t status;
|
|
||||||
bool vnd;
|
|
||||||
|
|
||||||
elem_addr = net_buf_simple_pull_le16(buf);
|
|
||||||
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
|
|
||||||
BT_WARN("Prohibited element address");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
net_buf_simple_pull(buf, 16);
|
|
||||||
|
|
||||||
mod_id = buf->data;
|
|
||||||
|
|
||||||
elem = bt_mesh_elem_find(elem_addr);
|
|
||||||
if (!elem) {
|
|
||||||
mod = NULL;
|
|
||||||
vnd = (buf->len == 4U);
|
|
||||||
status = STATUS_INVALID_ADDRESS;
|
|
||||||
goto send_status;
|
|
||||||
}
|
|
||||||
|
|
||||||
mod = get_model(elem, buf, &vnd);
|
|
||||||
if (!mod) {
|
|
||||||
status = STATUS_INVALID_MODEL;
|
|
||||||
goto send_status;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = STATUS_INSUFF_RESOURCES;
|
|
||||||
|
|
||||||
send_status:
|
|
||||||
send_mod_sub_status(model, ctx, status, elem_addr,
|
|
||||||
BT_MESH_ADDR_UNASSIGNED, mod_id, vnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mod_sub_va_del(struct bt_mesh_model *model,
|
|
||||||
struct bt_mesh_msg_ctx *ctx,
|
|
||||||
struct net_buf_simple *buf)
|
|
||||||
{
|
|
||||||
struct bt_mesh_elem *elem;
|
|
||||||
uint16_t elem_addr;
|
|
||||||
uint8_t *mod_id;
|
|
||||||
uint8_t status;
|
|
||||||
bool vnd;
|
|
||||||
|
|
||||||
elem_addr = net_buf_simple_pull_le16(buf);
|
|
||||||
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
|
|
||||||
BT_WARN("Prohibited element address");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
net_buf_simple_pull(buf, 16);
|
|
||||||
|
|
||||||
mod_id = buf->data;
|
|
||||||
|
|
||||||
elem = bt_mesh_elem_find(elem_addr);
|
|
||||||
if (!elem) {
|
|
||||||
vnd = (buf->len == 4U);
|
|
||||||
status = STATUS_INVALID_ADDRESS;
|
|
||||||
goto send_status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!get_model(elem, buf, &vnd)) {
|
|
||||||
status = STATUS_INVALID_MODEL;
|
|
||||||
goto send_status;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = STATUS_INSUFF_RESOURCES;
|
|
||||||
|
|
||||||
send_status:
|
|
||||||
send_mod_sub_status(model, ctx, status, elem_addr,
|
|
||||||
BT_MESH_ADDR_UNASSIGNED, mod_id, vnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mod_sub_va_overwrite(struct bt_mesh_model *model,
|
|
||||||
struct bt_mesh_msg_ctx *ctx,
|
|
||||||
struct net_buf_simple *buf)
|
|
||||||
{
|
|
||||||
struct bt_mesh_elem *elem;
|
|
||||||
uint16_t elem_addr;
|
|
||||||
uint8_t *mod_id;
|
|
||||||
uint8_t status;
|
|
||||||
bool vnd;
|
|
||||||
|
|
||||||
elem_addr = net_buf_simple_pull_le16(buf);
|
|
||||||
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
|
|
||||||
BT_WARN("Prohibited element address");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
net_buf_simple_pull(buf, 18);
|
|
||||||
|
|
||||||
mod_id = buf->data;
|
|
||||||
|
|
||||||
elem = bt_mesh_elem_find(elem_addr);
|
|
||||||
if (!elem) {
|
|
||||||
vnd = (buf->len == 4U);
|
|
||||||
status = STATUS_INVALID_ADDRESS;
|
|
||||||
goto send_status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!get_model(elem, buf, &vnd)) {
|
|
||||||
status = STATUS_INVALID_MODEL;
|
|
||||||
goto send_status;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = STATUS_INSUFF_RESOURCES;
|
|
||||||
|
|
||||||
send_status:
|
|
||||||
send_mod_sub_status(model, ctx, status, elem_addr,
|
|
||||||
BT_MESH_ADDR_UNASSIGNED, mod_id, vnd);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_BT_MESH_LABEL_COUNT > 0 */
|
|
||||||
|
|
||||||
static void send_net_key_status(struct bt_mesh_model *model,
|
static void send_net_key_status(struct bt_mesh_model *model,
|
||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
|
@ -3050,8 +2760,6 @@ void bt_mesh_cfg_reset(void)
|
||||||
cfg->hb_sub.expiry = 0;
|
cfg->hb_sub.expiry = 0;
|
||||||
|
|
||||||
bt_mesh_model_foreach(mod_reset, NULL);
|
bt_mesh_model_foreach(mod_reset, NULL);
|
||||||
|
|
||||||
(void)memset(labels, 0, sizeof(labels));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_mesh_heartbeat(uint16_t src, uint16_t dst, uint8_t hops, uint16_t feat)
|
void bt_mesh_heartbeat(uint16_t src, uint16_t dst, uint8_t hops, uint16_t feat)
|
||||||
|
@ -3148,25 +2856,6 @@ uint8_t bt_mesh_default_ttl_get(void)
|
||||||
return DEFAULT_TTL;
|
return DEFAULT_TTL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *bt_mesh_label_uuid_get(uint16_t addr)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
BT_DBG("addr 0x%04x", addr);
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(labels); i++) {
|
|
||||||
if (labels[i].addr == addr) {
|
|
||||||
BT_DBG("Found Label UUID for 0x%04x: %s", addr,
|
|
||||||
bt_hex(labels[i].uuid, 16));
|
|
||||||
return labels[i].uuid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BT_WARN("No matching Label UUID for 0x%04x", addr);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void)
|
struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void)
|
||||||
{
|
{
|
||||||
return &conf->hb_pub;
|
return &conf->hb_pub;
|
||||||
|
|
|
@ -129,10 +129,6 @@ void bt_mesh_heartbeat(uint16_t src, uint16_t dst, uint8_t hops, uint16_t feat);
|
||||||
|
|
||||||
void bt_mesh_attention(struct bt_mesh_model *model, uint8_t time);
|
void bt_mesh_attention(struct bt_mesh_model *model, uint8_t time);
|
||||||
|
|
||||||
struct label *get_label(uint16_t index);
|
|
||||||
|
|
||||||
uint8_t *bt_mesh_label_uuid_get(uint16_t addr);
|
|
||||||
|
|
||||||
struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void);
|
struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void);
|
||||||
void bt_mesh_hb_pub_disable(void);
|
void bt_mesh_hb_pub_disable(void);
|
||||||
struct bt_mesh_cfg_srv *bt_mesh_cfg_get(void);
|
struct bt_mesh_cfg_srv *bt_mesh_cfg_get(void);
|
||||||
|
|
|
@ -367,7 +367,7 @@ static int unseg_app_sdu_unpack(struct bt_mesh_friend *frnd,
|
||||||
meta->crypto.aszmic = 0;
|
meta->crypto.aszmic = 0;
|
||||||
|
|
||||||
if (BT_MESH_ADDR_IS_VIRTUAL(meta->crypto.dst)) {
|
if (BT_MESH_ADDR_IS_VIRTUAL(meta->crypto.dst)) {
|
||||||
meta->crypto.ad = bt_mesh_label_uuid_get(meta->crypto.dst);
|
meta->crypto.ad = bt_mesh_va_label_get(meta->crypto.dst);
|
||||||
if (!meta->crypto.ad) {
|
if (!meta->crypto.ad) {
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,9 +170,7 @@ void bt_mesh_reset(void)
|
||||||
k_delayed_work_cancel(&bt_mesh.ivu_timer);
|
k_delayed_work_cancel(&bt_mesh.ivu_timer);
|
||||||
|
|
||||||
bt_mesh_cfg_reset();
|
bt_mesh_cfg_reset();
|
||||||
|
bt_mesh_trans_reset();
|
||||||
bt_mesh_rx_reset();
|
|
||||||
bt_mesh_tx_reset();
|
|
||||||
bt_mesh_app_keys_reset();
|
bt_mesh_app_keys_reset();
|
||||||
bt_mesh_net_keys_reset();
|
bt_mesh_net_keys_reset();
|
||||||
|
|
||||||
|
|
|
@ -652,7 +652,7 @@ static int va_set(const char *name, size_t len_rd,
|
||||||
settings_read_cb read_cb, void *cb_arg)
|
settings_read_cb read_cb, void *cb_arg)
|
||||||
{
|
{
|
||||||
struct va_val va;
|
struct va_val va;
|
||||||
struct label *lab;
|
struct bt_mesh_va *lab;
|
||||||
uint16_t index;
|
uint16_t index;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -679,7 +679,7 @@ static int va_set(const char *name, size_t len_rd,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lab = get_label(index);
|
lab = bt_mesh_va_get(index);
|
||||||
if (lab == NULL) {
|
if (lab == NULL) {
|
||||||
BT_WARN("Out of labels buffers");
|
BT_WARN("Out of labels buffers");
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
|
@ -1803,18 +1803,19 @@ static void store_pending_mod(struct bt_mesh_model *mod,
|
||||||
#define IS_VA_DEL(_label) ((_label)->ref == 0)
|
#define IS_VA_DEL(_label) ((_label)->ref == 0)
|
||||||
static void store_pending_va(void)
|
static void store_pending_va(void)
|
||||||
{
|
{
|
||||||
struct label *lab;
|
struct bt_mesh_va *lab;
|
||||||
struct va_val va;
|
struct va_val va;
|
||||||
char path[18];
|
char path[18];
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
for (i = 0; (lab = get_label(i)) != NULL; i++) {
|
for (i = 0; (lab = bt_mesh_va_get(i)) != NULL; i++) {
|
||||||
if (!atomic_test_and_clear_bit(lab->flags,
|
if (!lab->changed) {
|
||||||
BT_MESH_VA_CHANGED)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lab->changed = 0U;
|
||||||
|
|
||||||
snprintk(path, sizeof(path), "bt/mesh/Va/%x", i);
|
snprintk(path, sizeof(path), "bt/mesh/Va/%x", i);
|
||||||
|
|
||||||
if (IS_VA_DEL(lab)) {
|
if (IS_VA_DEL(lab)) {
|
||||||
|
|
|
@ -122,6 +122,8 @@ static struct seg_rx {
|
||||||
|
|
||||||
K_MEM_SLAB_DEFINE(segs, BT_MESH_APP_SEG_SDU_MAX, CONFIG_BT_MESH_SEG_BUFS, 4);
|
K_MEM_SLAB_DEFINE(segs, BT_MESH_APP_SEG_SDU_MAX, CONFIG_BT_MESH_SEG_BUFS, 4);
|
||||||
|
|
||||||
|
static struct bt_mesh_va virtual_addrs[CONFIG_BT_MESH_LABEL_COUNT];
|
||||||
|
|
||||||
static uint16_t hb_sub_dst = BT_MESH_ADDR_UNASSIGNED;
|
static uint16_t hb_sub_dst = BT_MESH_ADDR_UNASSIGNED;
|
||||||
|
|
||||||
void bt_mesh_set_hb_sub_dst(uint16_t addr)
|
void bt_mesh_set_hb_sub_dst(uint16_t addr)
|
||||||
|
@ -648,7 +650,7 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BT_MESH_ADDR_IS_VIRTUAL(tx->ctx->addr)) {
|
if (BT_MESH_ADDR_IS_VIRTUAL(tx->ctx->addr)) {
|
||||||
crypto.ad = bt_mesh_label_uuid_get(tx->ctx->addr);
|
crypto.ad = bt_mesh_va_label_get(tx->ctx->addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = bt_mesh_app_encrypt(key, &crypto, msg);
|
err = bt_mesh_app_encrypt(key, &crypto, msg);
|
||||||
|
@ -732,7 +734,7 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, uint8_t hdr, uint8_t aszmic,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BT_MESH_ADDR_IS_VIRTUAL(rx->ctx.recv_dst)) {
|
if (BT_MESH_ADDR_IS_VIRTUAL(rx->ctx.recv_dst)) {
|
||||||
ctx.crypto.ad = bt_mesh_label_uuid_get(rx->ctx.recv_dst);
|
ctx.crypto.ad = bt_mesh_va_label_get(rx->ctx.recv_dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
rx->ctx.app_idx = bt_mesh_app_key_find(ctx.crypto.dev_key, AID(&hdr),
|
rx->ctx.app_idx = bt_mesh_app_key_find(ctx.crypto.dev_key, AID(&hdr),
|
||||||
|
@ -1577,19 +1579,32 @@ void bt_mesh_rx_reset(void)
|
||||||
for (i = 0; i < ARRAY_SIZE(seg_rx); i++) {
|
for (i = 0; i < ARRAY_SIZE(seg_rx); i++) {
|
||||||
seg_rx_reset(&seg_rx[i], true);
|
seg_rx_reset(&seg_rx[i], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bt_mesh_rpl_clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_mesh_tx_reset(void)
|
void bt_mesh_trans_reset(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
bt_mesh_rx_reset();
|
||||||
|
|
||||||
BT_DBG("");
|
BT_DBG("");
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(seg_tx); i++) {
|
for (i = 0; i < ARRAY_SIZE(seg_tx); i++) {
|
||||||
seg_tx_reset(&seg_tx[i]);
|
seg_tx_reset(&seg_tx[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(virtual_addrs); i++) {
|
||||||
|
if (virtual_addrs[i].ref) {
|
||||||
|
virtual_addrs[i].ref = 0U;
|
||||||
|
virtual_addrs[i].changed = 1U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bt_mesh_rpl_clear();
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
||||||
|
bt_mesh_store_label();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_mesh_trans_init(void)
|
void bt_mesh_trans_init(void)
|
||||||
|
@ -1656,3 +1671,118 @@ int bt_mesh_heartbeat_send(const struct bt_mesh_send_cb *cb, void *cb_data)
|
||||||
return bt_mesh_ctl_send(&tx, TRANS_CTL_OP_HEARTBEAT, &hb, sizeof(hb),
|
return bt_mesh_ctl_send(&tx, TRANS_CTL_OP_HEARTBEAT, &hb, sizeof(hb),
|
||||||
cb, cb_data);
|
cb, cb_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct bt_mesh_va *bt_mesh_va_get(uint16_t index)
|
||||||
|
{
|
||||||
|
if (index >= ARRAY_SIZE(virtual_addrs)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &virtual_addrs[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void va_store(struct bt_mesh_va *store)
|
||||||
|
{
|
||||||
|
store->changed = 1U;
|
||||||
|
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
||||||
|
bt_mesh_store_label();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t bt_mesh_va_add(uint8_t uuid[16], uint16_t *addr)
|
||||||
|
{
|
||||||
|
struct bt_mesh_va *va = NULL;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(virtual_addrs); i++) {
|
||||||
|
if (!virtual_addrs[i].ref) {
|
||||||
|
if (!va) {
|
||||||
|
va = &virtual_addrs[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!memcmp(uuid, virtual_addrs[i].uuid,
|
||||||
|
ARRAY_SIZE(virtual_addrs[i].uuid))) {
|
||||||
|
*addr = virtual_addrs[i].addr;
|
||||||
|
virtual_addrs[i].ref++;
|
||||||
|
va_store(&virtual_addrs[i]);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!va) {
|
||||||
|
return STATUS_INSUFF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(va->uuid, uuid, ARRAY_SIZE(va->uuid));
|
||||||
|
err = bt_mesh_virtual_addr(uuid, &va->addr);
|
||||||
|
if (err) {
|
||||||
|
va->addr = BT_MESH_ADDR_UNASSIGNED;
|
||||||
|
return STATUS_UNSPECIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
va->ref = 1;
|
||||||
|
va_store(va);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t bt_mesh_va_del(uint8_t uuid[16], uint16_t *addr)
|
||||||
|
{
|
||||||
|
struct bt_mesh_va *va = NULL;
|
||||||
|
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(virtual_addrs); i++) {
|
||||||
|
if (virtual_addrs[i].ref &&
|
||||||
|
!memcmp(uuid, virtual_addrs[i].uuid,
|
||||||
|
ARRAY_SIZE(virtual_addrs[i].uuid))) {
|
||||||
|
va = &virtual_addrs[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!va) {
|
||||||
|
return STATUS_CANNOT_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
va->ref--;
|
||||||
|
if (addr) {
|
||||||
|
*addr = va->addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_store(va);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct bt_mesh_va *bt_mesh_va_find(uint8_t uuid[16])
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(virtual_addrs); i++) {
|
||||||
|
if (virtual_addrs[i].ref &&
|
||||||
|
!memcmp(uuid, virtual_addrs[i].uuid,
|
||||||
|
ARRAY_SIZE(virtual_addrs[i].uuid))) {
|
||||||
|
return &virtual_addrs[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *bt_mesh_va_label_get(uint16_t addr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
BT_DBG("addr 0x%04x", addr);
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(virtual_addrs); i++) {
|
||||||
|
if (virtual_addrs[i].ref && virtual_addrs[i].addr == addr) {
|
||||||
|
BT_DBG("Found Label UUID for 0x%04x: %s", addr,
|
||||||
|
bt_hex(virtual_addrs[i].uuid, 16));
|
||||||
|
return virtual_addrs[i].uuid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BT_WARN("No matching Label UUID for 0x%04x", addr);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
|
@ -79,12 +79,18 @@ struct bt_mesh_ctl_friend_sub_confirm {
|
||||||
uint8_t xact;
|
uint8_t xact;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
struct bt_mesh_va {
|
||||||
|
uint16_t ref:15,
|
||||||
|
changed:1;
|
||||||
|
uint16_t addr;
|
||||||
|
uint8_t uuid[16];
|
||||||
|
};
|
||||||
|
|
||||||
void bt_mesh_set_hb_sub_dst(uint16_t addr);
|
void bt_mesh_set_hb_sub_dst(uint16_t addr);
|
||||||
|
|
||||||
bool bt_mesh_tx_in_progress(void);
|
bool bt_mesh_tx_in_progress(void);
|
||||||
|
|
||||||
void bt_mesh_rx_reset(void);
|
void bt_mesh_rx_reset(void);
|
||||||
void bt_mesh_tx_reset(void);
|
|
||||||
|
|
||||||
int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, uint8_t ctl_op, void *data,
|
int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, uint8_t ctl_op, void *data,
|
||||||
size_t data_len, const struct bt_mesh_send_cb *cb,
|
size_t data_len, const struct bt_mesh_send_cb *cb,
|
||||||
|
@ -107,4 +113,16 @@ int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx);
|
||||||
|
|
||||||
void bt_mesh_trans_init(void);
|
void bt_mesh_trans_init(void);
|
||||||
|
|
||||||
|
void bt_mesh_trans_reset(void);
|
||||||
|
|
||||||
int bt_mesh_heartbeat_send(const struct bt_mesh_send_cb *cb, void *cb_data);
|
int bt_mesh_heartbeat_send(const struct bt_mesh_send_cb *cb, void *cb_data);
|
||||||
|
|
||||||
|
struct bt_mesh_va *bt_mesh_va_get(uint16_t index);
|
||||||
|
|
||||||
|
struct bt_mesh_va *bt_mesh_va_find(uint8_t uuid[16]);
|
||||||
|
|
||||||
|
uint8_t bt_mesh_va_add(uint8_t uuid[16], uint16_t *addr);
|
||||||
|
|
||||||
|
uint8_t bt_mesh_va_del(uint8_t uuid[16], uint16_t *addr);
|
||||||
|
|
||||||
|
uint8_t *bt_mesh_va_label_get(uint16_t addr);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue