2017-06-16 12:30:54 +03:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2017 Intel Corporation
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
|
includes: prefer <zephyr/kernel.h> over <zephyr/zephyr.h>
As of today <zephyr/zephyr.h> is 100% equivalent to <zephyr/kernel.h>.
This patch proposes to then include <zephyr/kernel.h> instead of
<zephyr/zephyr.h> since it is more clear that you are including the
Kernel APIs and (probably) nothing else. <zephyr/zephyr.h> sounds like a
catch-all header that may be confusing. Most applications need to
include a bunch of other things to compile, e.g. driver headers or
subsystem headers like BT, logging, etc.
The idea of a catch-all header in Zephyr is probably not feasible
anyway. Reason is that Zephyr is not a library, like it could be for
example `libpython`. Zephyr provides many utilities nowadays: a kernel,
drivers, subsystems, etc and things will likely grow. A catch-all header
would be massive, difficult to keep up-to-date. It is also likely that
an application will only build a small subset. Note that subsystem-level
headers may use a catch-all approach to make things easier, though.
NOTE: This patch is **NOT** removing the header, just removing its usage
in-tree. I'd advocate for its deprecation (add a #warning on it), but I
understand many people will have concerns.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-08-25 09:58:46 +02:00
|
|
|
#include <zephyr/kernel.h>
|
2017-06-16 12:30:54 +03:00
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <zephyr/types.h>
|
2022-05-06 11:12:04 +02:00
|
|
|
#include <zephyr/sys/util.h>
|
|
|
|
#include <zephyr/sys/byteorder.h>
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-05-06 11:12:04 +02:00
|
|
|
#include <zephyr/bluetooth/bluetooth.h>
|
|
|
|
#include <zephyr/bluetooth/conn.h>
|
|
|
|
#include <zephyr/bluetooth/mesh.h>
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-10-25 08:48:54 +02:00
|
|
|
#include "common/bt_str.h"
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2024-08-23 12:34:08 +02:00
|
|
|
#include "testing.h"
|
2017-12-27 20:26:50 +01:00
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
#include "mesh.h"
|
|
|
|
#include "net.h"
|
2020-09-09 16:59:43 +08:00
|
|
|
#include "rpl.h"
|
2017-06-16 12:30:54 +03:00
|
|
|
#include "lpn.h"
|
|
|
|
#include "transport.h"
|
2020-08-12 17:07:38 +02:00
|
|
|
#include "heartbeat.h"
|
2017-06-16 12:30:54 +03:00
|
|
|
#include "crypto.h"
|
|
|
|
#include "access.h"
|
|
|
|
#include "beacon.h"
|
|
|
|
#include "proxy.h"
|
|
|
|
#include "foundation.h"
|
2017-10-31 16:16:28 +02:00
|
|
|
#include "friend.h"
|
2018-05-07 12:23:37 +03:00
|
|
|
#include "settings.h"
|
2020-08-18 13:36:38 +02:00
|
|
|
#include "cfg.h"
|
2023-05-14 18:43:12 +02:00
|
|
|
#include "va.h"
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
#define LOG_LEVEL CONFIG_BT_MESH_MODEL_LOG_LEVEL
|
|
|
|
#include <zephyr/logging/log.h>
|
|
|
|
LOG_MODULE_REGISTER(bt_mesh_cfg_srv);
|
|
|
|
|
2022-07-12 09:36:51 +02:00
|
|
|
static void node_reset_pending_handler(struct k_work *work)
|
|
|
|
{
|
|
|
|
bt_mesh_reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
static K_WORK_DEFINE(node_reset_pending, node_reset_pending_handler);
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int dev_comp_data_get(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2018-02-10 10:32:58 +02:00
|
|
|
NET_BUF_SIMPLE_DEFINE(sdu, BT_MESH_TX_SDU_MAX);
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t page;
|
2021-04-14 13:17:59 +02:00
|
|
|
int err;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
|
|
|
|
ctx->addr, buf->len, bt_hex(buf->data, buf->len));
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2023-10-06 08:56:49 +02:00
|
|
|
page = bt_mesh_comp_parse_page(buf);
|
2022-08-31 11:58:06 +02:00
|
|
|
LOG_DBG("Preparing Composition data page %d", page);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&sdu, OP_DEV_COMP_DATA_STATUS);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_u8(&sdu, page);
|
2020-03-13 15:58:47 +01:00
|
|
|
|
2023-08-24 11:51:33 +02:00
|
|
|
if (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) && page < 128) {
|
|
|
|
sdu.size -= BT_MESH_MIC_SHORT;
|
|
|
|
err = bt_mesh_comp_read(&sdu, page);
|
2020-03-13 15:58:47 +01:00
|
|
|
sdu.size += BT_MESH_MIC_SHORT;
|
|
|
|
} else {
|
2023-08-24 11:51:33 +02:00
|
|
|
err = bt_mesh_comp_data_get_page(&sdu, page, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (err) {
|
|
|
|
LOG_ERR("Failed to get CDP%d, err:%d", page, err);
|
|
|
|
return err;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &sdu, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Device Composition Status response");
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return err;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-17 09:36:34 +08:00
|
|
|
static const struct bt_mesh_model *get_model(const struct bt_mesh_elem *elem,
|
2017-06-16 12:30:54 +03:00
|
|
|
struct net_buf_simple *buf, bool *vnd)
|
|
|
|
{
|
|
|
|
if (buf->len < 4) {
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t id;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
id = net_buf_simple_pull_le16(buf);
|
|
|
|
|
2023-11-17 09:36:34 +08:00
|
|
|
LOG_DBG("ID 0x%04x addr 0x%04x", id, elem->rt->addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
*vnd = false;
|
|
|
|
|
|
|
|
return bt_mesh_model_find(elem, id);
|
|
|
|
} else {
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t company, id;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
company = net_buf_simple_pull_le16(buf);
|
|
|
|
id = net_buf_simple_pull_le16(buf);
|
|
|
|
|
2023-11-17 09:36:34 +08:00
|
|
|
LOG_DBG("Company 0x%04x ID 0x%04x addr 0x%04x", company, id, elem->rt->addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
*vnd = true;
|
|
|
|
|
|
|
|
return bt_mesh_model_find_vnd(elem, company, id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static uint8_t _mod_pub_set(const struct bt_mesh_model *model, uint16_t pub_addr,
|
|
|
|
const uint8_t *uuid, uint16_t app_idx, uint8_t cred_flag,
|
|
|
|
uint8_t ttl, uint8_t period, uint8_t retransmit, bool store)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
|
|
|
if (!model->pub) {
|
|
|
|
return STATUS_NVAL_PUB_PARAM;
|
|
|
|
}
|
|
|
|
|
2017-08-09 09:21:11 +03:00
|
|
|
if (!IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) && cred_flag) {
|
2017-06-16 12:30:54 +03:00
|
|
|
return STATUS_FEAT_NOT_SUPP;
|
|
|
|
}
|
|
|
|
|
2017-11-20 17:13:44 +02:00
|
|
|
if (!model->pub->update && period) {
|
2017-06-16 12:30:54 +03:00
|
|
|
return STATUS_NVAL_PUB_PARAM;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pub_addr == BT_MESH_ADDR_UNASSIGNED) {
|
2018-06-26 11:32:40 +03:00
|
|
|
if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) {
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
model->pub->addr = BT_MESH_ADDR_UNASSIGNED;
|
2019-03-26 19:57:45 -06:00
|
|
|
model->pub->key = 0U;
|
|
|
|
model->pub->cred = 0U;
|
|
|
|
model->pub->ttl = 0U;
|
|
|
|
model->pub->period = 0U;
|
|
|
|
model->pub->retransmit = 0U;
|
|
|
|
model->pub->count = 0U;
|
2023-05-14 18:43:12 +02:00
|
|
|
model->pub->uuid = NULL;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2017-11-20 17:13:44 +02:00
|
|
|
if (model->pub->update) {
|
2021-04-15 12:28:20 +02:00
|
|
|
/* If this fails, the timer will check pub->addr and
|
|
|
|
* exit without transmitting.
|
|
|
|
*/
|
|
|
|
(void)k_work_cancel_delayable(&model->pub->timer);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2018-06-26 11:34:27 +03:00
|
|
|
if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) {
|
2021-01-06 09:56:56 +01:00
|
|
|
bt_mesh_model_pub_store(model);
|
2018-05-10 09:38:24 +03:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2021-09-07 13:14:48 +02:00
|
|
|
if (!bt_mesh_app_key_exists(app_idx) || !bt_mesh_model_has_key(model, app_idx)) {
|
2017-06-16 12:30:54 +03:00
|
|
|
return STATUS_INVALID_APPKEY;
|
|
|
|
}
|
|
|
|
|
2020-09-10 15:36:15 +02:00
|
|
|
#if CONFIG_BT_MESH_LABEL_COUNT > 0
|
|
|
|
if (BT_MESH_ADDR_IS_VIRTUAL(model->pub->addr)) {
|
2023-05-14 18:43:12 +02:00
|
|
|
(void)bt_mesh_va_del(model->pub->uuid);
|
2020-09-10 15:36:15 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
model->pub->addr = pub_addr;
|
|
|
|
model->pub->key = app_idx;
|
|
|
|
model->pub->cred = cred_flag;
|
|
|
|
model->pub->ttl = ttl;
|
|
|
|
model->pub->period = period;
|
|
|
|
model->pub->retransmit = retransmit;
|
2023-05-14 18:43:12 +02:00
|
|
|
model->pub->uuid = uuid;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2017-11-20 17:13:44 +02:00
|
|
|
if (model->pub->update) {
|
2020-05-27 11:26:57 -05:00
|
|
|
int32_t period_ms;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
period_ms = bt_mesh_model_pub_period_get(model);
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("period %u ms", period_ms);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-04-06 13:56:14 +02:00
|
|
|
if (period_ms > 0) {
|
2021-04-15 12:28:20 +02:00
|
|
|
k_work_reschedule(&model->pub->timer,
|
|
|
|
K_MSEC(period_ms));
|
2017-06-16 12:30:54 +03:00
|
|
|
} else {
|
2021-04-15 12:28:20 +02:00
|
|
|
/* If this fails, publication will stop after the
|
|
|
|
* ongoing set of retransmits.
|
|
|
|
*/
|
|
|
|
(void)k_work_cancel_delayable(&model->pub->timer);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-26 11:34:27 +03:00
|
|
|
if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) {
|
2021-01-06 09:56:56 +01:00
|
|
|
bt_mesh_model_pub_store(model);
|
2018-05-10 09:38:24 +03:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static uint8_t mod_bind(const struct bt_mesh_model *model, uint16_t key_idx)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("model %p key_idx 0x%03x", model, key_idx);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-25 11:03:42 +02:00
|
|
|
if (!bt_mesh_app_key_exists(key_idx)) {
|
2017-06-16 12:30:54 +03:00
|
|
|
return STATUS_INVALID_APPKEY;
|
|
|
|
}
|
|
|
|
|
2022-11-02 19:31:26 +08:00
|
|
|
for (i = 0; i < model->keys_cnt; i++) {
|
2021-02-18 14:09:18 +01:00
|
|
|
LOG_DBG("model %p id 0x%04x i %d key 0x%03x", model, model->id, i, model->keys[i]);
|
2017-06-16 12:30:54 +03:00
|
|
|
/* Treat existing binding as success */
|
|
|
|
if (model->keys[i] == key_idx) {
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-02 19:31:26 +08:00
|
|
|
for (i = 0; i < model->keys_cnt; i++) {
|
2017-06-16 12:30:54 +03:00
|
|
|
if (model->keys[i] == BT_MESH_KEY_UNUSED) {
|
|
|
|
model->keys[i] = key_idx;
|
2018-05-09 21:34:52 +03:00
|
|
|
|
|
|
|
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
2021-01-06 09:56:56 +01:00
|
|
|
bt_mesh_model_bind_store(model);
|
2018-05-09 21:34:52 +03:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return STATUS_INSUFF_RESOURCES;
|
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static uint8_t mod_unbind(const struct bt_mesh_model *model, uint16_t key_idx, bool store)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("model %p key_idx 0x%03x store %u", model, key_idx, store);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-25 11:03:42 +02:00
|
|
|
if (!bt_mesh_app_key_exists(key_idx)) {
|
2017-06-16 12:30:54 +03:00
|
|
|
return STATUS_INVALID_APPKEY;
|
|
|
|
}
|
|
|
|
|
2022-11-02 19:31:26 +08:00
|
|
|
for (i = 0; i < model->keys_cnt; i++) {
|
2017-06-16 12:30:54 +03:00
|
|
|
if (model->keys[i] != key_idx) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
model->keys[i] = BT_MESH_KEY_UNUSED;
|
|
|
|
|
2018-06-26 11:34:27 +03:00
|
|
|
if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) {
|
2021-01-06 09:56:56 +01:00
|
|
|
bt_mesh_model_bind_store(model);
|
2018-05-09 21:34:52 +03:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
if (model->pub && model->pub->key == key_idx) {
|
2023-05-14 18:43:12 +02:00
|
|
|
_mod_pub_set(model, BT_MESH_ADDR_UNASSIGNED, NULL,
|
2018-06-26 11:34:27 +03:00
|
|
|
0, 0, 0, 0, 0, store);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-04 09:45:09 +01:00
|
|
|
return STATUS_SUCCESS;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-07-05 14:52:55 +02:00
|
|
|
static void key_idx_pack_list(struct net_buf_simple *buf, uint16_t *arr, size_t cnt)
|
|
|
|
{
|
|
|
|
uint16_t *idx = NULL;
|
|
|
|
|
|
|
|
for (int i = 0; i < cnt; i++) {
|
|
|
|
if (arr[i] != BT_MESH_KEY_UNUSED) {
|
|
|
|
if (!idx) {
|
|
|
|
idx = &arr[i];
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
key_idx_pack_pair(buf, *idx, arr[i]);
|
|
|
|
idx = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (idx) {
|
|
|
|
net_buf_simple_add_le16(buf, *idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int send_app_key_status(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
uint8_t status,
|
|
|
|
uint16_t app_idx, uint16_t net_idx)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-08-25 11:03:42 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_STATUS, 4);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-25 11:03:42 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_APP_KEY_STATUS);
|
|
|
|
net_buf_simple_add_u8(&msg, status);
|
2023-07-05 14:52:55 +02:00
|
|
|
key_idx_pack_pair(&msg, net_idx, app_idx);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-25 11:03:42 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send App Key Status response");
|
2018-05-07 12:23:37 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int app_key_add(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t key_net_idx, key_app_idx;
|
|
|
|
uint8_t status;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2023-07-05 14:52:55 +02:00
|
|
|
key_idx_unpack_pair(buf, &key_net_idx, &key_app_idx);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("AppIdx 0x%04x NetIdx 0x%04x", key_app_idx, key_net_idx);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-25 11:03:42 +02:00
|
|
|
status = bt_mesh_app_key_add(key_app_idx, key_net_idx, buf->data);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_app_key_status(model, ctx, status, key_app_idx, key_net_idx);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int app_key_update(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t key_net_idx, key_app_idx;
|
|
|
|
uint8_t status;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2023-07-05 14:52:55 +02:00
|
|
|
key_idx_unpack_pair(buf, &key_net_idx, &key_app_idx);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("AppIdx 0x%04x NetIdx 0x%04x", key_app_idx, key_net_idx);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-25 11:03:42 +02:00
|
|
|
status = bt_mesh_app_key_update(key_app_idx, key_net_idx, buf->data);
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("status 0x%02x", status);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_app_key_status(model, ctx, status, key_app_idx, key_net_idx);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static void mod_app_key_del(const struct bt_mesh_model *mod,
|
2023-11-17 09:36:34 +08:00
|
|
|
const struct bt_mesh_elem *elem, bool vnd, bool primary,
|
2020-08-25 11:03:42 +02:00
|
|
|
void *user_data)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-08-25 11:03:42 +02:00
|
|
|
uint16_t *app_idx = user_data;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-25 11:03:42 +02:00
|
|
|
mod_unbind(mod, *app_idx, true);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2020-08-25 11:03:42 +02:00
|
|
|
static void app_key_evt(uint16_t app_idx, uint16_t net_idx,
|
|
|
|
enum bt_mesh_key_evt evt)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-08-25 11:03:42 +02:00
|
|
|
if (evt == BT_MESH_KEY_DELETED) {
|
|
|
|
bt_mesh_model_foreach(&mod_app_key_del, &app_idx);
|
2018-05-08 09:21:57 +03:00
|
|
|
}
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2020-08-25 11:03:42 +02:00
|
|
|
BT_MESH_APP_KEY_CB_DEFINE(app_key_evt);
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int app_key_del(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t key_net_idx, key_app_idx;
|
|
|
|
uint8_t status;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2023-07-05 14:52:55 +02:00
|
|
|
key_idx_unpack_pair(buf, &key_net_idx, &key_app_idx);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("AppIdx 0x%04x NetIdx 0x%04x", key_app_idx, key_net_idx);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-12-06 18:04:06 -08:00
|
|
|
status = bt_mesh_app_key_del(key_app_idx, key_net_idx);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_app_key_status(model, ctx, status, key_app_idx, key_net_idx);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Index list length: 3 bytes for every pair and 2 bytes for an odd idx */
|
|
|
|
#define IDX_LEN(num) (((num) / 2) * 3 + ((num) % 2) * 2)
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int app_key_get(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_LIST,
|
|
|
|
3 + IDX_LEN(CONFIG_BT_MESH_APP_KEY_COUNT));
|
2020-08-25 11:03:42 +02:00
|
|
|
uint16_t app_idx[CONFIG_BT_MESH_APP_KEY_COUNT];
|
|
|
|
uint16_t get_idx;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t status;
|
2020-08-25 11:03:42 +02:00
|
|
|
ssize_t count;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
get_idx = net_buf_simple_pull_le16(buf);
|
|
|
|
if (get_idx > 0xfff) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Invalid NetKeyIndex 0x%04x", get_idx);
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("idx 0x%04x", get_idx);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_APP_KEY_LIST);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-25 11:03:42 +02:00
|
|
|
if (!bt_mesh_subnet_exists(get_idx)) {
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_INVALID_NETKEY;
|
|
|
|
} else {
|
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_u8(&msg, status);
|
|
|
|
net_buf_simple_add_le16(&msg, get_idx);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
if (status != STATUS_SUCCESS) {
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
2020-08-25 11:03:42 +02:00
|
|
|
count = bt_mesh_app_keys_get(get_idx, app_idx, ARRAY_SIZE(app_idx), 0);
|
|
|
|
if (count < 0 || count > ARRAY_SIZE(app_idx)) {
|
|
|
|
count = ARRAY_SIZE(app_idx);
|
|
|
|
}
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2023-07-05 14:52:55 +02:00
|
|
|
key_idx_pack_list(&msg, app_idx, count);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
send_status:
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send AppKey List");
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int beacon_get(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_BEACON_STATUS, 1);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
|
|
|
|
ctx->addr, buf->len, bt_hex(buf->data, buf->len));
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_BEACON_STATUS);
|
2020-08-18 13:36:38 +02:00
|
|
|
net_buf_simple_add_u8(&msg, bt_mesh_beacon_enabled());
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Config Beacon Status response");
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int beacon_set(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_BEACON_STATUS, 1);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
|
|
|
|
ctx->addr, buf->len, bt_hex(buf->data, buf->len));
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-18 13:36:38 +02:00
|
|
|
if (buf->data[0] != 0x00 && buf->data[0] != 0x01) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Invalid Config Beacon value 0x%02x", buf->data[0]);
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2020-08-18 13:36:38 +02:00
|
|
|
bt_mesh_beacon_set(buf->data[0]);
|
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_BEACON_STATUS);
|
2020-08-18 13:36:38 +02:00
|
|
|
net_buf_simple_add_u8(&msg, buf->data[0]);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Config Beacon Status response");
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int default_ttl_get(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_DEFAULT_TTL_STATUS, 1);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
|
|
|
|
ctx->addr, buf->len, bt_hex(buf->data, buf->len));
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_DEFAULT_TTL_STATUS);
|
|
|
|
net_buf_simple_add_u8(&msg, bt_mesh_default_ttl_get());
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Default TTL Status response");
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int default_ttl_set(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_DEFAULT_TTL_STATUS, 1);
|
2020-08-18 13:36:38 +02:00
|
|
|
int err;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
|
|
|
|
ctx->addr, buf->len, bt_hex(buf->data, buf->len));
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-18 13:36:38 +02:00
|
|
|
err = bt_mesh_default_ttl_set(buf->data[0]);
|
|
|
|
if (err) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Prohibited Default TTL value 0x%02x", buf->data[0]);
|
2021-04-14 13:17:59 +02:00
|
|
|
return err;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_DEFAULT_TTL_STATUS);
|
2020-08-18 13:36:38 +02:00
|
|
|
net_buf_simple_add_u8(&msg, buf->data[0]);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Default TTL Status response");
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int send_gatt_proxy_status(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_GATT_PROXY_STATUS, 1);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_GATT_PROXY_STATUS);
|
|
|
|
net_buf_simple_add_u8(&msg, bt_mesh_gatt_proxy_get());
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send GATT Proxy Status");
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int gatt_proxy_get(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
|
|
|
|
ctx->addr, buf->len, bt_hex(buf->data, buf->len));
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_gatt_proxy_status(model, ctx);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int gatt_proxy_set(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
|
|
|
|
ctx->addr, buf->len, bt_hex(buf->data, buf->len));
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
if (buf->data[0] != 0x00 && buf->data[0] != 0x01) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Invalid GATT Proxy value 0x%02x", buf->data[0]);
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2020-08-18 13:36:38 +02:00
|
|
|
(void)bt_mesh_gatt_proxy_set(buf->data[0]);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-06-02 12:04:53 +02:00
|
|
|
/** 4.2.46.1: If the value of the Node Identity state of the node for any subnet is 0x01,
|
|
|
|
* then the value of the Private Node Identity state shall be Disable (0x00).
|
|
|
|
*/
|
|
|
|
if (IS_ENABLED(CONFIG_BT_MESH_PRIV_BEACONS) && buf->data[0]) {
|
|
|
|
(void)bt_mesh_priv_gatt_proxy_set(BT_MESH_FEATURE_DISABLED);
|
|
|
|
}
|
|
|
|
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_gatt_proxy_status(model, ctx);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int net_transmit_get(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_NET_TRANSMIT_STATUS, 1);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
|
|
|
|
ctx->addr, buf->len, bt_hex(buf->data, buf->len));
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_NET_TRANSMIT_STATUS);
|
|
|
|
net_buf_simple_add_u8(&msg, bt_mesh_net_transmit_get());
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Config Network Transmit Status");
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int net_transmit_set(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_NET_TRANSMIT_STATUS, 1);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
|
|
|
|
ctx->addr, buf->len, bt_hex(buf->data, buf->len));
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("Transmit 0x%02x (count %u interval %ums)", buf->data[0],
|
|
|
|
BT_MESH_TRANSMIT_COUNT(buf->data[0]), BT_MESH_TRANSMIT_INT(buf->data[0]));
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-18 13:36:38 +02:00
|
|
|
bt_mesh_net_transmit_set(buf->data[0]);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_NET_TRANSMIT_STATUS);
|
2020-08-18 13:36:38 +02:00
|
|
|
net_buf_simple_add_u8(&msg, buf->data[0]);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Network Transmit Status");
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int relay_get(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_STATUS, 2);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
|
|
|
|
ctx->addr, buf->len, bt_hex(buf->data, buf->len));
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_RELAY_STATUS);
|
|
|
|
net_buf_simple_add_u8(&msg, bt_mesh_relay_get());
|
|
|
|
net_buf_simple_add_u8(&msg, bt_mesh_relay_retransmit_get());
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Config Relay Status response");
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int relay_set(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_STATUS, 2);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
|
|
|
|
ctx->addr, buf->len, bt_hex(buf->data, buf->len));
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-18 13:36:38 +02:00
|
|
|
if (buf->data[0] != 0x00 && buf->data[0] != 0x01) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Invalid Relay value 0x%02x", buf->data[0]);
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2020-08-18 13:36:38 +02:00
|
|
|
(void)bt_mesh_relay_set(buf->data[0], buf->data[1]);
|
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_RELAY_STATUS);
|
|
|
|
net_buf_simple_add_u8(&msg, bt_mesh_relay_get());
|
|
|
|
net_buf_simple_add_u8(&msg, bt_mesh_relay_retransmit_get());
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Relay Status response");
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int send_mod_pub_status(const struct bt_mesh_model *cfg_mod,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx, uint16_t elem_addr,
|
|
|
|
uint16_t pub_addr, bool vnd,
|
2023-11-14 12:00:30 +08:00
|
|
|
const struct bt_mesh_model *mod, uint8_t status,
|
2021-04-14 13:17:59 +02:00
|
|
|
uint8_t *mod_id)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_STATUS, 14);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_MOD_PUB_STATUS);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_u8(&msg, status);
|
|
|
|
net_buf_simple_add_le16(&msg, elem_addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
if (status != STATUS_SUCCESS) {
|
2018-09-11 19:09:03 -07:00
|
|
|
(void)memset(net_buf_simple_add(&msg, 7), 0, 7);
|
2017-06-16 12:30:54 +03:00
|
|
|
} else {
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t idx_cred;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_le16(&msg, pub_addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-05-27 11:26:57 -05:00
|
|
|
idx_cred = mod->pub->key | (uint16_t)mod->pub->cred << 12;
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_le16(&msg, idx_cred);
|
|
|
|
net_buf_simple_add_u8(&msg, mod->pub->ttl);
|
|
|
|
net_buf_simple_add_u8(&msg, mod->pub->period);
|
|
|
|
net_buf_simple_add_u8(&msg, mod->pub->retransmit);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (vnd) {
|
2018-02-10 10:32:58 +02:00
|
|
|
memcpy(net_buf_simple_add(&msg, 4), mod_id, 4);
|
2017-06-16 12:30:54 +03:00
|
|
|
} else {
|
2018-02-10 10:32:58 +02:00
|
|
|
memcpy(net_buf_simple_add(&msg, 2), mod_id, 2);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(cfg_mod, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Model Publication Status");
|
2017-11-21 21:22:46 +02:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int mod_pub_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t elem_addr, pub_addr = 0U;
|
2023-11-14 12:00:30 +08:00
|
|
|
const struct bt_mesh_model *mod;
|
2023-11-17 09:36:34 +08:00
|
|
|
const struct bt_mesh_elem *elem;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t *mod_id, status;
|
2017-06-16 12:30:54 +03:00
|
|
|
bool vnd;
|
|
|
|
|
2021-04-27 15:59:54 +02:00
|
|
|
if ((buf->len != 4U) && (buf->len != 6U)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("The message size for the application opcode is incorrect.");
|
2021-04-27 15:59:54 +02:00
|
|
|
return -EMSGSIZE;
|
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
elem_addr = net_buf_simple_pull_le16(buf);
|
2018-06-26 21:42:10 +03:00
|
|
|
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Prohibited element address");
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2018-06-26 21:42:10 +03:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
mod_id = buf->data;
|
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("elem_addr 0x%04x", elem_addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
elem = bt_mesh_elem_find(elem_addr);
|
|
|
|
if (!elem) {
|
|
|
|
mod = NULL;
|
2019-03-26 19:57:45 -06:00
|
|
|
vnd = (buf->len == 4U);
|
2017-06-16 12:30:54 +03:00
|
|
|
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_SUCCESS;
|
|
|
|
|
|
|
|
send_status:
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod,
|
|
|
|
status, mod_id);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int mod_pub_set(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t retransmit, status, pub_ttl, pub_period, cred_flag;
|
|
|
|
uint16_t elem_addr, pub_addr, pub_app_idx;
|
2023-11-14 12:00:30 +08:00
|
|
|
const struct bt_mesh_model *mod;
|
2023-11-17 09:36:34 +08:00
|
|
|
const struct bt_mesh_elem *elem;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t *mod_id;
|
2017-06-16 12:30:54 +03:00
|
|
|
bool vnd;
|
|
|
|
|
2021-04-27 15:59:54 +02:00
|
|
|
if ((buf->len != 11U) && (buf->len != 13U)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("The message size for the application opcode is incorrect.");
|
2021-04-27 15:59:54 +02:00
|
|
|
return -EMSGSIZE;
|
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
elem_addr = net_buf_simple_pull_le16(buf);
|
2018-06-26 21:42:10 +03:00
|
|
|
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Prohibited element address");
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2018-06-26 21:42:10 +03:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
pub_addr = net_buf_simple_pull_le16(buf);
|
|
|
|
pub_app_idx = net_buf_simple_pull_le16(buf);
|
|
|
|
cred_flag = ((pub_app_idx >> 12) & BIT_MASK(1));
|
|
|
|
pub_app_idx &= BIT_MASK(12);
|
|
|
|
|
|
|
|
pub_ttl = net_buf_simple_pull_u8(buf);
|
2017-11-13 00:14:25 +02:00
|
|
|
if (pub_ttl > BT_MESH_TTL_MAX && pub_ttl != BT_MESH_TTL_DEFAULT) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Invalid TTL value 0x%02x", pub_ttl);
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
pub_period = net_buf_simple_pull_u8(buf);
|
|
|
|
retransmit = net_buf_simple_pull_u8(buf);
|
|
|
|
mod_id = buf->data;
|
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("elem_addr 0x%04x pub_addr 0x%04x cred_flag %u", elem_addr, pub_addr, cred_flag);
|
|
|
|
LOG_DBG("pub_app_idx 0x%03x, pub_ttl %u pub_period 0x%02x", pub_app_idx, pub_ttl,
|
|
|
|
pub_period);
|
|
|
|
LOG_DBG("retransmit 0x%02x (count %u interval %ums)", retransmit,
|
|
|
|
BT_MESH_PUB_TRANSMIT_COUNT(retransmit), BT_MESH_PUB_TRANSMIT_INT(retransmit));
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
elem = bt_mesh_elem_find(elem_addr);
|
|
|
|
if (!elem) {
|
|
|
|
mod = NULL;
|
2019-03-26 19:57:45 -06:00
|
|
|
vnd = (buf->len == 4U);
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_INVALID_ADDRESS;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
|
|
|
mod = get_model(elem, buf, &vnd);
|
|
|
|
if (!mod) {
|
|
|
|
status = STATUS_INVALID_MODEL;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
status = _mod_pub_set(mod, pub_addr, NULL, pub_app_idx, cred_flag, pub_ttl,
|
2018-06-26 11:34:27 +03:00
|
|
|
pub_period, retransmit, true);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
send_status:
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod,
|
|
|
|
status, mod_id);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static size_t mod_sub_list_clear(const struct bt_mesh_model *mod)
|
2018-01-09 14:25:16 +01:00
|
|
|
{
|
2019-03-20 13:46:37 +02:00
|
|
|
size_t clear_count;
|
2018-01-09 14:25:16 +01:00
|
|
|
int i;
|
|
|
|
|
2022-11-02 19:31:26 +08:00
|
|
|
for (i = 0, clear_count = 0; i < mod->groups_cnt; i++) {
|
2023-05-14 18:43:12 +02:00
|
|
|
/* mod->groups contains both, group and virtual addrs. Virtual addrs deletion will
|
|
|
|
* be handled separately.
|
|
|
|
*/
|
|
|
|
if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) {
|
|
|
|
mod->groups[i] = BT_MESH_ADDR_UNASSIGNED;
|
|
|
|
clear_count++;
|
|
|
|
}
|
|
|
|
}
|
2019-03-20 13:46:37 +02:00
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
#if CONFIG_BT_MESH_LABEL_COUNT > 0
|
|
|
|
/* Unref stored labels related to this model */
|
|
|
|
for (i = 0; i < CONFIG_BT_MESH_LABEL_COUNT; i++) {
|
|
|
|
if (mod->uuids[i] == NULL) {
|
2018-01-09 14:25:16 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
(void)bt_mesh_va_del(mod->uuids[i]);
|
|
|
|
mod->uuids[i] = NULL;
|
|
|
|
/* No need to increment `clear_count` as `groups` contains virtual addresses. */
|
2018-01-09 14:25:16 +01:00
|
|
|
}
|
2023-05-14 18:43:12 +02:00
|
|
|
#endif
|
2018-01-09 14:25:16 +01:00
|
|
|
|
2019-03-20 13:46:37 +02:00
|
|
|
return clear_count;
|
2018-01-09 14:25:16 +01:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int mod_pub_va_set(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2023-05-14 18:43:12 +02:00
|
|
|
const struct bt_mesh_va *va;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t retransmit, status, pub_ttl, pub_period, cred_flag;
|
2023-05-14 18:43:12 +02:00
|
|
|
uint16_t elem_addr, pub_app_idx;
|
|
|
|
uint16_t pub_addr = 0U;
|
2023-11-14 12:00:30 +08:00
|
|
|
const struct bt_mesh_model *mod;
|
2023-11-17 09:36:34 +08:00
|
|
|
const struct bt_mesh_elem *elem;
|
2023-05-14 18:43:12 +02:00
|
|
|
const uint8_t *uuid;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t *mod_id;
|
2017-06-16 12:30:54 +03:00
|
|
|
bool vnd;
|
|
|
|
|
2021-04-27 15:59:54 +02:00
|
|
|
if ((buf->len != 25U) && (buf->len != 27U)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("The message size for the application opcode is incorrect.");
|
2021-04-27 15:59:54 +02:00
|
|
|
return -EMSGSIZE;
|
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
elem_addr = net_buf_simple_pull_le16(buf);
|
2018-06-26 21:42:10 +03:00
|
|
|
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Prohibited element address");
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2018-06-26 21:42:10 +03:00
|
|
|
}
|
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
uuid = net_buf_simple_pull_mem(buf, 16);
|
2017-06-16 12:30:54 +03:00
|
|
|
pub_app_idx = net_buf_simple_pull_le16(buf);
|
|
|
|
cred_flag = ((pub_app_idx >> 12) & BIT_MASK(1));
|
|
|
|
pub_app_idx &= BIT_MASK(12);
|
|
|
|
pub_ttl = net_buf_simple_pull_u8(buf);
|
2017-11-13 00:14:25 +02:00
|
|
|
if (pub_ttl > BT_MESH_TTL_MAX && pub_ttl != BT_MESH_TTL_DEFAULT) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Invalid TTL value 0x%02x", pub_ttl);
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
pub_period = net_buf_simple_pull_u8(buf);
|
|
|
|
retransmit = net_buf_simple_pull_u8(buf);
|
|
|
|
mod_id = buf->data;
|
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("elem_addr 0x%04x cred_flag %u", elem_addr, cred_flag);
|
|
|
|
LOG_DBG("pub_app_idx 0x%03x, pub_ttl %u pub_period 0x%02x", pub_app_idx, pub_ttl,
|
|
|
|
pub_period);
|
|
|
|
LOG_DBG("retransmit 0x%02x (count %u interval %ums)", retransmit,
|
|
|
|
BT_MESH_PUB_TRANSMIT_COUNT(retransmit), BT_MESH_PUB_TRANSMIT_INT(retransmit));
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
elem = bt_mesh_elem_find(elem_addr);
|
|
|
|
if (!elem) {
|
|
|
|
mod = NULL;
|
2019-03-26 19:57:45 -06:00
|
|
|
vnd = (buf->len == 4U);
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_INVALID_ADDRESS;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
|
|
|
mod = get_model(elem, buf, &vnd);
|
|
|
|
if (!mod) {
|
|
|
|
status = STATUS_INVALID_MODEL;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
status = bt_mesh_va_add(uuid, &va);
|
2020-09-10 15:36:15 +02:00
|
|
|
if (status != STATUS_SUCCESS) {
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
pub_addr = va->addr;
|
|
|
|
|
|
|
|
status = _mod_pub_set(mod, pub_addr, va->uuid, pub_app_idx, cred_flag, pub_ttl,
|
2020-09-10 15:36:15 +02:00
|
|
|
pub_period, retransmit, true);
|
|
|
|
if (status != STATUS_SUCCESS) {
|
2023-05-14 18:43:12 +02:00
|
|
|
(void)bt_mesh_va_del(va->uuid);
|
2018-06-26 21:42:10 +03:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
send_status:
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod,
|
|
|
|
status, mod_id);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int send_mod_sub_status(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx, uint8_t status,
|
|
|
|
uint16_t elem_addr, uint16_t sub_addr, uint8_t *mod_id,
|
|
|
|
bool vnd)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_SUB_STATUS, 9);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("status 0x%02x elem_addr 0x%04x sub_addr 0x%04x", status, elem_addr, sub_addr);
|
2017-11-24 12:43:23 +02:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_MOD_SUB_STATUS);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_u8(&msg, status);
|
|
|
|
net_buf_simple_add_le16(&msg, elem_addr);
|
|
|
|
net_buf_simple_add_le16(&msg, sub_addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
if (vnd) {
|
2018-02-10 10:32:58 +02:00
|
|
|
memcpy(net_buf_simple_add(&msg, 4), mod_id, 4);
|
2017-06-16 12:30:54 +03:00
|
|
|
} else {
|
2018-02-10 10:32:58 +02:00
|
|
|
memcpy(net_buf_simple_add(&msg, 2), mod_id, 2);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Model Subscription Status");
|
2017-11-21 21:22:46 +02:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int mod_sub_add(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t elem_addr, sub_addr;
|
2023-11-14 12:00:30 +08:00
|
|
|
const struct bt_mesh_model *mod;
|
2023-11-17 09:36:34 +08:00
|
|
|
const struct bt_mesh_elem *elem;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t *mod_id;
|
|
|
|
uint8_t status;
|
|
|
|
uint16_t *entry;
|
2017-06-16 12:30:54 +03:00
|
|
|
bool vnd;
|
|
|
|
|
2021-04-27 15:59:54 +02:00
|
|
|
if ((buf->len != 6U) && (buf->len != 8U)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("The message size for the application opcode is incorrect.");
|
2021-04-27 15:59:54 +02:00
|
|
|
return -EMSGSIZE;
|
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
elem_addr = net_buf_simple_pull_le16(buf);
|
2018-06-26 21:42:10 +03:00
|
|
|
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Prohibited element address");
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2018-06-26 21:42:10 +03:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
sub_addr = net_buf_simple_pull_le16(buf);
|
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("elem_addr 0x%04x, sub_addr 0x%04x", elem_addr, sub_addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
mod_id = buf->data;
|
|
|
|
|
|
|
|
elem = bt_mesh_elem_find(elem_addr);
|
|
|
|
if (!elem) {
|
|
|
|
mod = NULL;
|
2019-03-26 19:57:45 -06:00
|
|
|
vnd = (buf->len == 4U);
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_INVALID_ADDRESS;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
|
|
|
mod = get_model(elem, buf, &vnd);
|
|
|
|
if (!mod) {
|
|
|
|
status = STATUS_INVALID_MODEL;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
2022-04-20 10:35:44 +02:00
|
|
|
if (!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) {
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_INVALID_ADDRESS;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
2019-10-18 13:23:06 +02:00
|
|
|
if (bt_mesh_model_find_group(&mod, sub_addr)) {
|
2017-06-16 12:30:54 +03:00
|
|
|
/* Tried to add existing subscription */
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("found existing subscription");
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
2019-10-18 13:23:06 +02:00
|
|
|
entry = bt_mesh_model_find_group(&mod, BT_MESH_ADDR_UNASSIGNED);
|
|
|
|
if (!entry) {
|
|
|
|
status = STATUS_INSUFF_RESOURCES;
|
|
|
|
goto send_status;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2019-10-18 13:23:06 +02:00
|
|
|
*entry = sub_addr;
|
|
|
|
status = STATUS_SUCCESS;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2019-10-18 13:23:06 +02:00
|
|
|
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
2021-01-06 09:56:56 +01:00
|
|
|
bt_mesh_model_sub_store(mod);
|
2019-10-18 13:23:06 +02:00
|
|
|
}
|
2018-05-09 21:47:01 +03:00
|
|
|
|
2019-10-18 13:23:06 +02:00
|
|
|
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
|
|
|
|
bt_mesh_lpn_group_add(sub_addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2019-10-18 13:23:06 +02:00
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
send_status:
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
|
|
|
|
mod_id, vnd);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int mod_sub_del(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t elem_addr, sub_addr;
|
2023-11-14 12:00:30 +08:00
|
|
|
const struct bt_mesh_model *mod;
|
2023-11-17 09:36:34 +08:00
|
|
|
const struct bt_mesh_elem *elem;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t *mod_id;
|
|
|
|
uint16_t *match;
|
|
|
|
uint8_t status;
|
2017-06-16 12:30:54 +03:00
|
|
|
bool vnd;
|
|
|
|
|
2021-04-27 15:59:54 +02:00
|
|
|
if ((buf->len != 6U) && (buf->len != 8U)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("The message size for the application opcode is incorrect.");
|
2021-04-27 15:59:54 +02:00
|
|
|
return -EMSGSIZE;
|
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
elem_addr = net_buf_simple_pull_le16(buf);
|
2018-06-26 21:42:10 +03:00
|
|
|
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Prohibited element address");
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2018-06-26 21:42:10 +03:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
sub_addr = net_buf_simple_pull_le16(buf);
|
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("elem_addr 0x%04x sub_addr 0x%04x", elem_addr, sub_addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
mod_id = buf->data;
|
|
|
|
|
|
|
|
elem = bt_mesh_elem_find(elem_addr);
|
|
|
|
if (!elem) {
|
|
|
|
mod = NULL;
|
2019-03-26 19:57:45 -06:00
|
|
|
vnd = (buf->len == 4U);
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_INVALID_ADDRESS;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
|
|
|
mod = get_model(elem, buf, &vnd);
|
|
|
|
if (!mod) {
|
|
|
|
status = STATUS_INVALID_MODEL;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
2022-04-20 10:35:44 +02:00
|
|
|
if (!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) {
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_INVALID_ADDRESS;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* An attempt to remove a non-existing address shall be treated
|
|
|
|
* as a success.
|
|
|
|
*/
|
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
|
2017-08-09 09:21:11 +03:00
|
|
|
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
|
2017-06-16 12:30:54 +03:00
|
|
|
bt_mesh_lpn_group_del(&sub_addr, 1);
|
|
|
|
}
|
|
|
|
|
2019-10-18 13:23:06 +02:00
|
|
|
match = bt_mesh_model_find_group(&mod, sub_addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
if (match) {
|
|
|
|
*match = BT_MESH_ADDR_UNASSIGNED;
|
2018-05-09 21:47:01 +03:00
|
|
|
|
|
|
|
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
2021-01-06 09:56:56 +01:00
|
|
|
bt_mesh_model_sub_store(mod);
|
2018-05-09 21:47:01 +03:00
|
|
|
}
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
send_status:
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
|
|
|
|
mod_id, vnd);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static enum bt_mesh_walk mod_sub_clear_visitor(const struct bt_mesh_model *mod, void *user_data)
|
2019-10-18 13:23:06 +02:00
|
|
|
{
|
|
|
|
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
|
2022-11-02 19:31:26 +08:00
|
|
|
bt_mesh_lpn_group_del(mod->groups, mod->groups_cnt);
|
2019-10-18 13:23:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
mod_sub_list_clear(mod);
|
|
|
|
|
|
|
|
return BT_MESH_WALK_CONTINUE;
|
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int mod_sub_overwrite(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t elem_addr, sub_addr;
|
2023-11-14 12:00:30 +08:00
|
|
|
const struct bt_mesh_model *mod;
|
2023-11-17 09:36:34 +08:00
|
|
|
const struct bt_mesh_elem *elem;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t *mod_id;
|
|
|
|
uint8_t status;
|
2017-06-16 12:30:54 +03:00
|
|
|
bool vnd;
|
|
|
|
|
2021-04-27 15:59:54 +02:00
|
|
|
if ((buf->len != 6U) && (buf->len != 8U)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("The message size for the application opcode is incorrect.");
|
2021-04-27 15:59:54 +02:00
|
|
|
return -EMSGSIZE;
|
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
elem_addr = net_buf_simple_pull_le16(buf);
|
2018-06-26 21:42:10 +03:00
|
|
|
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Prohibited element address");
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2018-06-26 21:42:10 +03:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
sub_addr = net_buf_simple_pull_le16(buf);
|
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("elem_addr 0x%04x sub_addr 0x%04x", elem_addr, sub_addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
mod_id = buf->data;
|
|
|
|
|
|
|
|
elem = bt_mesh_elem_find(elem_addr);
|
|
|
|
if (!elem) {
|
|
|
|
mod = NULL;
|
2019-03-26 19:57:45 -06:00
|
|
|
vnd = (buf->len == 4U);
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_INVALID_ADDRESS;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
|
|
|
mod = get_model(elem, buf, &vnd);
|
|
|
|
if (!mod) {
|
|
|
|
status = STATUS_INVALID_MODEL;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
2022-04-20 10:35:44 +02:00
|
|
|
if (!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) {
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_INVALID_ADDRESS;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-11-02 19:31:26 +08:00
|
|
|
if (mod->groups_cnt > 0) {
|
2021-07-26 16:16:01 +02:00
|
|
|
bt_mesh_model_extensions_walk(mod, mod_sub_clear_visitor, NULL);
|
2019-10-18 13:23:06 +02:00
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
mod->groups[0] = sub_addr;
|
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
|
2018-05-09 21:47:01 +03:00
|
|
|
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
2021-01-06 09:56:56 +01:00
|
|
|
bt_mesh_model_sub_store(mod);
|
2018-05-09 21:47:01 +03:00
|
|
|
}
|
|
|
|
|
2017-08-09 09:21:11 +03:00
|
|
|
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
|
2017-06-16 12:30:54 +03:00
|
|
|
bt_mesh_lpn_group_add(sub_addr);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
status = STATUS_INSUFF_RESOURCES;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
send_status:
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
|
|
|
|
mod_id, vnd);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int mod_sub_del_all(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2023-11-14 12:00:30 +08:00
|
|
|
const struct bt_mesh_model *mod;
|
2023-11-17 09:36:34 +08:00
|
|
|
const struct bt_mesh_elem *elem;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t elem_addr;
|
|
|
|
uint8_t *mod_id;
|
|
|
|
uint8_t status;
|
2017-06-16 12:30:54 +03:00
|
|
|
bool vnd;
|
|
|
|
|
2021-04-27 15:59:54 +02:00
|
|
|
if ((buf->len != 4U) && (buf->len != 6U)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("The message size for the application opcode is incorrect.");
|
2021-04-27 15:59:54 +02:00
|
|
|
return -EMSGSIZE;
|
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
elem_addr = net_buf_simple_pull_le16(buf);
|
2018-06-26 21:42:10 +03:00
|
|
|
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Prohibited element address");
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2018-06-26 21:42:10 +03:00
|
|
|
}
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("elem_addr 0x%04x", elem_addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
mod_id = buf->data;
|
|
|
|
|
|
|
|
elem = bt_mesh_elem_find(elem_addr);
|
|
|
|
if (!elem) {
|
|
|
|
mod = NULL;
|
2019-03-26 19:57:45 -06:00
|
|
|
vnd = (buf->len == 4U);
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_INVALID_ADDRESS;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
|
|
|
mod = get_model(elem, buf, &vnd);
|
|
|
|
if (!mod) {
|
|
|
|
status = STATUS_INVALID_MODEL;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
2021-07-26 16:16:01 +02:00
|
|
|
bt_mesh_model_extensions_walk(mod, mod_sub_clear_visitor, NULL);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-05-09 21:47:01 +03:00
|
|
|
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
2021-01-06 09:56:56 +01:00
|
|
|
bt_mesh_model_sub_store(mod);
|
2018-05-09 21:47:01 +03:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
send_status:
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_mod_sub_status(model, ctx, status, elem_addr,
|
|
|
|
BT_MESH_ADDR_UNASSIGNED, mod_id, vnd);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2019-10-18 13:23:06 +02:00
|
|
|
struct mod_sub_list_ctx {
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t elem_idx;
|
2019-10-18 13:23:06 +02:00
|
|
|
struct net_buf_simple *msg;
|
|
|
|
};
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static enum bt_mesh_walk mod_sub_list_visitor(const struct bt_mesh_model *mod, void *ctx)
|
2019-10-18 13:23:06 +02:00
|
|
|
{
|
|
|
|
struct mod_sub_list_ctx *visit = ctx;
|
|
|
|
int count = 0;
|
|
|
|
int i;
|
|
|
|
|
2023-11-15 18:03:40 +08:00
|
|
|
if (mod->rt->elem_idx != visit->elem_idx) {
|
2019-10-18 13:23:06 +02:00
|
|
|
return BT_MESH_WALK_CONTINUE;
|
|
|
|
}
|
|
|
|
|
2022-11-02 19:31:26 +08:00
|
|
|
for (i = 0; i < mod->groups_cnt; i++) {
|
2019-10-18 13:23:06 +02:00
|
|
|
if (mod->groups[i] == BT_MESH_ADDR_UNASSIGNED) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (net_buf_simple_tailroom(visit->msg) <
|
|
|
|
2 + BT_MESH_MIC_SHORT) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("No room for all groups");
|
2019-10-18 13:23:06 +02:00
|
|
|
return BT_MESH_WALK_STOP;
|
|
|
|
}
|
|
|
|
|
|
|
|
net_buf_simple_add_le16(visit->msg, mod->groups[i]);
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
2023-11-15 18:03:40 +08:00
|
|
|
LOG_DBG("sublist: model %u:%x: %u groups", mod->rt->elem_idx, mod->id, count);
|
2019-10-18 13:23:06 +02:00
|
|
|
|
|
|
|
return BT_MESH_WALK_CONTINUE;
|
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int mod_sub_get(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-18 13:23:06 +02:00
|
|
|
NET_BUF_SIMPLE_DEFINE(msg, BT_MESH_TX_SDU_MAX);
|
|
|
|
struct mod_sub_list_ctx visit_ctx;
|
2023-11-14 12:00:30 +08:00
|
|
|
const struct bt_mesh_model *mod;
|
2023-11-17 09:36:34 +08:00
|
|
|
const struct bt_mesh_elem *elem;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t addr, id;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
addr = net_buf_simple_pull_le16(buf);
|
2018-06-26 21:42:10 +03:00
|
|
|
if (!BT_MESH_ADDR_IS_UNICAST(addr)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Prohibited element address");
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2018-06-26 21:42:10 +03:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
id = net_buf_simple_pull_le16(buf);
|
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("addr 0x%04x id 0x%04x", addr, id);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_MOD_SUB_LIST);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
elem = bt_mesh_elem_find(addr);
|
|
|
|
if (!elem) {
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_u8(&msg, STATUS_INVALID_ADDRESS);
|
|
|
|
net_buf_simple_add_le16(&msg, addr);
|
|
|
|
net_buf_simple_add_le16(&msg, id);
|
2017-06-16 12:30:54 +03:00
|
|
|
goto send_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
mod = bt_mesh_model_find(elem, id);
|
|
|
|
if (!mod) {
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_u8(&msg, STATUS_INVALID_MODEL);
|
|
|
|
net_buf_simple_add_le16(&msg, addr);
|
|
|
|
net_buf_simple_add_le16(&msg, id);
|
2017-06-16 12:30:54 +03:00
|
|
|
goto send_list;
|
|
|
|
}
|
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_u8(&msg, STATUS_SUCCESS);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_le16(&msg, addr);
|
|
|
|
net_buf_simple_add_le16(&msg, id);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2019-10-18 13:23:06 +02:00
|
|
|
visit_ctx.msg = &msg;
|
2023-11-15 18:03:40 +08:00
|
|
|
visit_ctx.elem_idx = mod->rt->elem_idx;
|
2021-07-26 16:16:01 +02:00
|
|
|
bt_mesh_model_extensions_walk(mod, mod_sub_list_visitor, &visit_ctx);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
send_list:
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Model Subscription List");
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int mod_sub_get_vnd(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-18 13:23:06 +02:00
|
|
|
NET_BUF_SIMPLE_DEFINE(msg, BT_MESH_TX_SDU_MAX);
|
2020-06-22 13:29:31 +02:00
|
|
|
struct mod_sub_list_ctx visit_ctx;
|
2023-11-14 12:00:30 +08:00
|
|
|
const struct bt_mesh_model *mod;
|
2023-11-17 09:36:34 +08:00
|
|
|
const struct bt_mesh_elem *elem;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t company, addr, id;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
addr = net_buf_simple_pull_le16(buf);
|
2018-06-26 21:42:10 +03:00
|
|
|
if (!BT_MESH_ADDR_IS_UNICAST(addr)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Prohibited element address");
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2018-06-26 21:42:10 +03:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
company = net_buf_simple_pull_le16(buf);
|
|
|
|
id = net_buf_simple_pull_le16(buf);
|
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("addr 0x%04x company 0x%04x id 0x%04x", addr, company, id);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_MOD_SUB_LIST_VND);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
elem = bt_mesh_elem_find(addr);
|
|
|
|
if (!elem) {
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_u8(&msg, STATUS_INVALID_ADDRESS);
|
|
|
|
net_buf_simple_add_le16(&msg, addr);
|
|
|
|
net_buf_simple_add_le16(&msg, company);
|
|
|
|
net_buf_simple_add_le16(&msg, id);
|
2017-06-16 12:30:54 +03:00
|
|
|
goto send_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
mod = bt_mesh_model_find_vnd(elem, company, id);
|
|
|
|
if (!mod) {
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_u8(&msg, STATUS_INVALID_MODEL);
|
|
|
|
net_buf_simple_add_le16(&msg, addr);
|
|
|
|
net_buf_simple_add_le16(&msg, company);
|
|
|
|
net_buf_simple_add_le16(&msg, id);
|
2017-06-16 12:30:54 +03:00
|
|
|
goto send_list;
|
|
|
|
}
|
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_u8(&msg, STATUS_SUCCESS);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_le16(&msg, addr);
|
|
|
|
net_buf_simple_add_le16(&msg, company);
|
|
|
|
net_buf_simple_add_le16(&msg, id);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-06-22 13:29:31 +02:00
|
|
|
visit_ctx.msg = &msg;
|
2023-11-15 18:03:40 +08:00
|
|
|
visit_ctx.elem_idx = mod->rt->elem_idx;
|
2021-07-26 16:16:01 +02:00
|
|
|
bt_mesh_model_extensions_walk(mod, mod_sub_list_visitor, &visit_ctx);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
send_list:
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Vendor Model Subscription List");
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int mod_sub_va_add(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2023-05-14 18:43:12 +02:00
|
|
|
const struct bt_mesh_va *va;
|
|
|
|
uint16_t elem_addr, sub_addr = BT_MESH_ADDR_UNASSIGNED;
|
2023-11-14 12:00:30 +08:00
|
|
|
const struct bt_mesh_model *mod;
|
2023-11-17 09:36:34 +08:00
|
|
|
const struct bt_mesh_elem *elem;
|
2023-05-14 18:43:12 +02:00
|
|
|
const uint8_t *uuid;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t *mod_id;
|
2023-05-14 18:43:12 +02:00
|
|
|
uint16_t *group_entry;
|
|
|
|
const uint8_t **label_entry;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t status;
|
2017-06-16 12:30:54 +03:00
|
|
|
bool vnd;
|
|
|
|
|
2021-04-27 15:59:54 +02:00
|
|
|
if ((buf->len != 20U) && (buf->len != 22U)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("The message size for the application opcode is incorrect.");
|
2021-04-27 15:59:54 +02:00
|
|
|
return -EMSGSIZE;
|
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
elem_addr = net_buf_simple_pull_le16(buf);
|
2018-06-26 21:42:10 +03:00
|
|
|
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Prohibited element address");
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2018-06-26 21:42:10 +03:00
|
|
|
}
|
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
uuid = net_buf_simple_pull_mem(buf, 16);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("elem_addr 0x%04x", elem_addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
mod_id = buf->data;
|
|
|
|
elem = bt_mesh_elem_find(elem_addr);
|
|
|
|
if (!elem) {
|
|
|
|
mod = NULL;
|
2019-03-26 19:57:45 -06:00
|
|
|
vnd = (buf->len == 4U);
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_INVALID_ADDRESS;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
|
|
|
mod = get_model(elem, buf, &vnd);
|
|
|
|
if (!mod) {
|
|
|
|
status = STATUS_INVALID_MODEL;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
status = bt_mesh_va_add(uuid, &va);
|
2017-06-16 12:30:54 +03:00
|
|
|
if (status != STATUS_SUCCESS) {
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
if (bt_mesh_model_find_uuid(&mod, va->uuid)) {
|
2017-06-16 12:30:54 +03:00
|
|
|
/* Tried to add existing subscription */
|
|
|
|
status = STATUS_SUCCESS;
|
2023-05-14 18:43:12 +02:00
|
|
|
(void)bt_mesh_va_del(va->uuid);
|
2017-06-16 12:30:54 +03:00
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
label_entry = bt_mesh_model_find_uuid(&mod, NULL);
|
|
|
|
if (!label_entry) {
|
|
|
|
status = STATUS_INSUFF_RESOURCES;
|
|
|
|
(void)bt_mesh_va_del(va->uuid);
|
|
|
|
goto send_status;
|
|
|
|
}
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
group_entry = NULL;
|
|
|
|
|
|
|
|
for (int i = 0; i < mod->groups_cnt; i++) {
|
|
|
|
if (mod->groups[i] == BT_MESH_ADDR_UNASSIGNED) {
|
|
|
|
group_entry = &mod->groups[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* bt_mesh_model_find_uuid() should find a model where both, uuids and groups lists have
|
|
|
|
* empty entry.
|
|
|
|
*/
|
|
|
|
if (!group_entry) {
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_INSUFF_RESOURCES;
|
2023-05-14 18:43:12 +02:00
|
|
|
(void)bt_mesh_va_del(va->uuid);
|
2019-10-18 13:23:06 +02:00
|
|
|
goto send_status;
|
|
|
|
}
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
*group_entry = va->addr;
|
|
|
|
*label_entry = va->uuid;
|
2018-05-09 21:47:01 +03:00
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) && va->ref == 1 &&
|
|
|
|
!bt_mesh_va_collision_check(va->addr)) {
|
|
|
|
bt_mesh_lpn_group_add(va->addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2019-10-18 13:23:06 +02:00
|
|
|
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
2021-01-06 09:56:56 +01:00
|
|
|
bt_mesh_model_sub_store(mod);
|
2019-10-18 13:23:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
status = STATUS_SUCCESS;
|
2023-05-14 18:43:12 +02:00
|
|
|
sub_addr = va->addr;
|
2019-10-18 13:23:06 +02:00
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
send_status:
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
|
|
|
|
mod_id, vnd);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int mod_sub_va_del(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2023-05-14 18:43:12 +02:00
|
|
|
const struct bt_mesh_va *va;
|
|
|
|
uint16_t elem_addr, sub_addr = BT_MESH_ADDR_UNASSIGNED;
|
2023-11-14 12:00:30 +08:00
|
|
|
const struct bt_mesh_model *mod;
|
2023-11-17 09:36:34 +08:00
|
|
|
const struct bt_mesh_elem *elem;
|
2023-05-14 18:43:12 +02:00
|
|
|
const uint8_t *uuid;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t *mod_id;
|
2023-05-14 18:43:12 +02:00
|
|
|
const uint8_t **label_match;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t status;
|
2017-06-16 12:30:54 +03:00
|
|
|
bool vnd;
|
|
|
|
|
2021-04-27 15:59:54 +02:00
|
|
|
if ((buf->len != 20U) && (buf->len != 22U)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("The message size for the application opcode is incorrect.");
|
2021-04-27 15:59:54 +02:00
|
|
|
return -EMSGSIZE;
|
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
elem_addr = net_buf_simple_pull_le16(buf);
|
2018-06-26 21:42:10 +03:00
|
|
|
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Prohibited element address");
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2018-06-26 21:42:10 +03:00
|
|
|
}
|
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
uuid = net_buf_simple_pull_mem(buf, 16);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("elem_addr 0x%04x", elem_addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
mod_id = buf->data;
|
|
|
|
|
|
|
|
elem = bt_mesh_elem_find(elem_addr);
|
|
|
|
if (!elem) {
|
|
|
|
mod = NULL;
|
2019-03-26 19:57:45 -06:00
|
|
|
vnd = (buf->len == 4U);
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_INVALID_ADDRESS;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
|
|
|
mod = get_model(elem, buf, &vnd);
|
|
|
|
if (!mod) {
|
|
|
|
status = STATUS_INVALID_MODEL;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
va = bt_mesh_va_find(uuid);
|
|
|
|
if (!va) {
|
|
|
|
status = STATUS_CANNOT_REMOVE;
|
2017-06-16 12:30:54 +03:00
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) && va->ref == 1 &&
|
|
|
|
!bt_mesh_va_collision_check(va->addr)) {
|
|
|
|
bt_mesh_lpn_group_del(&va->addr, 1);
|
2018-01-09 14:10:23 +01:00
|
|
|
}
|
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
label_match = bt_mesh_model_find_uuid(&mod, va->uuid);
|
|
|
|
if (!label_match) {
|
|
|
|
status = STATUS_CANNOT_REMOVE;
|
|
|
|
goto send_status;
|
|
|
|
}
|
2018-05-09 21:47:01 +03:00
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
for (int i = 0; i < mod->groups_cnt; i++) {
|
|
|
|
if (mod->groups[i] == va->addr) {
|
|
|
|
mod->groups[i] = BT_MESH_ADDR_UNASSIGNED;
|
|
|
|
break;
|
2018-05-09 21:47:01 +03:00
|
|
|
}
|
2023-05-14 18:43:12 +02:00
|
|
|
}
|
2018-05-09 21:47:01 +03:00
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
*label_match = NULL;
|
|
|
|
|
|
|
|
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
|
|
|
bt_mesh_model_sub_store(mod);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
sub_addr = va->addr;
|
|
|
|
(void)bt_mesh_va_del(va->uuid);
|
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
send_status:
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
|
|
|
|
mod_id, vnd);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int mod_sub_va_overwrite(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2023-05-14 18:43:12 +02:00
|
|
|
const struct bt_mesh_va *va;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t elem_addr, sub_addr = BT_MESH_ADDR_UNASSIGNED;
|
2023-11-14 12:00:30 +08:00
|
|
|
const struct bt_mesh_model *mod;
|
2023-11-17 09:36:34 +08:00
|
|
|
const struct bt_mesh_elem *elem;
|
2023-05-14 18:43:12 +02:00
|
|
|
const uint8_t *uuid;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t *mod_id;
|
|
|
|
uint8_t status;
|
2017-06-16 12:30:54 +03:00
|
|
|
bool vnd;
|
|
|
|
|
2021-04-27 15:59:54 +02:00
|
|
|
if ((buf->len != 20U) && (buf->len != 22U)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("The message size for the application opcode is incorrect.");
|
2021-04-27 15:59:54 +02:00
|
|
|
return -EMSGSIZE;
|
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
elem_addr = net_buf_simple_pull_le16(buf);
|
2018-06-26 21:42:10 +03:00
|
|
|
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Prohibited element address");
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2018-06-26 21:42:10 +03:00
|
|
|
}
|
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
uuid = net_buf_simple_pull_mem(buf, 16);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("elem_addr 0x%04x", elem_addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
mod_id = buf->data;
|
|
|
|
|
|
|
|
elem = bt_mesh_elem_find(elem_addr);
|
|
|
|
if (!elem) {
|
|
|
|
mod = NULL;
|
2019-03-26 19:57:45 -06:00
|
|
|
vnd = (buf->len == 4U);
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_INVALID_ADDRESS;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
|
|
|
mod = get_model(elem, buf, &vnd);
|
|
|
|
if (!mod) {
|
|
|
|
status = STATUS_INVALID_MODEL;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
if (CONFIG_BT_MESH_LABEL_COUNT == 0 || mod->groups_cnt == 0) {
|
|
|
|
(void)va;
|
|
|
|
status = STATUS_INSUFF_RESOURCES;
|
|
|
|
goto send_status;
|
|
|
|
}
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
#if CONFIG_BT_MESH_LABEL_COUNT > 0
|
|
|
|
status = bt_mesh_va_add(uuid, &va);
|
|
|
|
if (status != STATUS_SUCCESS) {
|
|
|
|
goto send_status;
|
|
|
|
}
|
2019-10-18 13:23:06 +02:00
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
bt_mesh_model_extensions_walk(mod, mod_sub_clear_visitor, NULL);
|
|
|
|
mod->groups[0] = va->addr;
|
|
|
|
mod->uuids[0] = va->uuid;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
|
|
|
bt_mesh_model_sub_store(mod);
|
|
|
|
}
|
2018-05-09 21:47:01 +03:00
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) && va->ref == 1 &&
|
|
|
|
!bt_mesh_va_collision_check(va->addr)) {
|
|
|
|
bt_mesh_lpn_group_add(va->addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-05-14 18:43:12 +02:00
|
|
|
sub_addr = va->addr;
|
|
|
|
#endif
|
2017-06-16 12:30:54 +03:00
|
|
|
send_status:
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_mod_sub_status(model, ctx, status, elem_addr, sub_addr,
|
|
|
|
mod_id, vnd);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int send_net_key_status(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx, uint16_t idx,
|
|
|
|
uint8_t status)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_STATUS, 3);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_NET_KEY_STATUS);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_u8(&msg, status);
|
|
|
|
net_buf_simple_add_le16(&msg, idx);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send NetKey Status");
|
2017-11-21 21:22:46 +02:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int net_key_add(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-08-25 11:03:42 +02:00
|
|
|
uint8_t status;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t idx;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
idx = net_buf_simple_pull_le16(buf);
|
|
|
|
if (idx > 0xfff) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Invalid NetKeyIndex 0x%04x", idx);
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("idx 0x%04x", idx);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-25 11:03:42 +02:00
|
|
|
status = bt_mesh_subnet_add(idx, buf->data);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_net_key_status(model, ctx, idx, status);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int net_key_update(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-08-25 11:03:42 +02:00
|
|
|
uint8_t status;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t idx;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
idx = net_buf_simple_pull_le16(buf);
|
|
|
|
if (idx > 0xfff) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Invalid NetKeyIndex 0x%04x", idx);
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2020-08-25 11:03:42 +02:00
|
|
|
status = bt_mesh_subnet_update(idx, buf->data);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_net_key_status(model, ctx, idx, status);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int net_key_del(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t del_idx;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
del_idx = net_buf_simple_pull_le16(buf);
|
|
|
|
if (del_idx > 0xfff) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Invalid NetKeyIndex 0x%04x", del_idx);
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("idx 0x%04x", del_idx);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
/* The key that the message was encrypted with cannot be removed.
|
|
|
|
* The NetKey List must contain a minimum of one NetKey.
|
|
|
|
*/
|
|
|
|
if (ctx->net_idx == del_idx) {
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_net_key_status(model, ctx, del_idx,
|
|
|
|
STATUS_CANNOT_REMOVE);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2021-04-14 13:17:59 +02:00
|
|
|
(void)bt_mesh_subnet_del(del_idx);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_net_key_status(model, ctx, del_idx, STATUS_SUCCESS);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int net_key_get(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_LIST,
|
|
|
|
IDX_LEN(CONFIG_BT_MESH_SUBNET_COUNT));
|
2020-08-25 11:03:42 +02:00
|
|
|
uint16_t net_idx[CONFIG_BT_MESH_SUBNET_COUNT];
|
|
|
|
ssize_t count;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_NET_KEY_LIST);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-25 11:03:42 +02:00
|
|
|
count = bt_mesh_subnets_get(net_idx, ARRAY_SIZE(net_idx), 0);
|
|
|
|
if (count < 0 || count > ARRAY_SIZE(net_idx)) {
|
|
|
|
count = ARRAY_SIZE(net_idx);
|
|
|
|
}
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2023-07-05 14:52:55 +02:00
|
|
|
key_idx_pack_list(&msg, net_idx, count);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send NetKey List");
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int send_node_id_status(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
uint8_t status,
|
|
|
|
uint16_t net_idx, uint8_t node_id)
|
2020-08-25 11:03:42 +02:00
|
|
|
{
|
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_IDENTITY_STATUS, 4);
|
|
|
|
|
|
|
|
bt_mesh_model_msg_init(&msg, OP_NODE_IDENTITY_STATUS);
|
|
|
|
net_buf_simple_add_u8(&msg, status);
|
|
|
|
net_buf_simple_add_le16(&msg, net_idx);
|
|
|
|
net_buf_simple_add_u8(&msg, node_id);
|
|
|
|
|
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Node Identity Status");
|
2020-08-25 11:03:42 +02:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2020-08-25 11:03:42 +02:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int node_identity_get(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-08-25 11:03:42 +02:00
|
|
|
enum bt_mesh_feat_state node_id;
|
|
|
|
uint8_t status;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t idx;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
|
|
|
|
ctx->addr, buf->len, bt_hex(buf->data, buf->len));
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
idx = net_buf_simple_pull_le16(buf);
|
|
|
|
if (idx > 0xfff) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Invalid NetKeyIndex 0x%04x", idx);
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2020-08-25 11:03:42 +02:00
|
|
|
status = bt_mesh_subnet_node_id_get(idx, &node_id);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_node_id_status(model, ctx, status, idx, node_id);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int node_identity_set(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-08-25 11:03:42 +02:00
|
|
|
uint8_t node_id, status;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t idx;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
|
|
|
|
ctx->addr, buf->len, bt_hex(buf->data, buf->len));
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
idx = net_buf_simple_pull_le16(buf);
|
|
|
|
if (idx > 0xfff) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Invalid NetKeyIndex 0x%04x", idx);
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
node_id = net_buf_simple_pull_u8(buf);
|
|
|
|
if (node_id != 0x00 && node_id != 0x01) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Invalid Node ID value 0x%02x", node_id);
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2020-08-25 11:03:42 +02:00
|
|
|
status = bt_mesh_subnet_node_id_set(idx, node_id);
|
|
|
|
if (status == STATUS_INVALID_NETKEY) {
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_node_id_status(model, ctx, status, idx,
|
|
|
|
BT_MESH_NODE_IDENTITY_STOPPED);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2020-08-25 11:03:42 +02:00
|
|
|
if (status == STATUS_FEAT_NOT_SUPP) {
|
|
|
|
/* Should return success, even if feature isn't supported: */
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_node_id_status(model, ctx, STATUS_SUCCESS, idx,
|
|
|
|
BT_MESH_NODE_IDENTITY_NOT_SUPPORTED);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2020-08-25 11:03:42 +02:00
|
|
|
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_node_id_status(model, ctx, status, idx, node_id);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void create_mod_app_status(struct net_buf_simple *msg,
|
2023-11-14 12:00:30 +08:00
|
|
|
const struct bt_mesh_model *mod, bool vnd,
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t elem_addr, uint16_t app_idx,
|
|
|
|
uint8_t status, uint8_t *mod_id)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
|
|
|
bt_mesh_model_msg_init(msg, OP_MOD_APP_STATUS);
|
|
|
|
|
|
|
|
net_buf_simple_add_u8(msg, status);
|
|
|
|
net_buf_simple_add_le16(msg, elem_addr);
|
|
|
|
net_buf_simple_add_le16(msg, app_idx);
|
|
|
|
|
|
|
|
if (vnd) {
|
|
|
|
memcpy(net_buf_simple_add(msg, 4), mod_id, 4);
|
|
|
|
} else {
|
|
|
|
memcpy(net_buf_simple_add(msg, 2), mod_id, 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int mod_app_bind(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_STATUS, 9);
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t elem_addr, key_app_idx;
|
2023-11-14 12:00:30 +08:00
|
|
|
const struct bt_mesh_model *mod;
|
2023-11-17 09:36:34 +08:00
|
|
|
const struct bt_mesh_elem *elem;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t *mod_id, status;
|
2017-06-16 12:30:54 +03:00
|
|
|
bool vnd;
|
|
|
|
|
2021-04-27 15:59:54 +02:00
|
|
|
if ((buf->len != 6U) && (buf->len != 8U)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("The message size for the application opcode is incorrect.");
|
2021-04-27 15:59:54 +02:00
|
|
|
return -EMSGSIZE;
|
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
elem_addr = net_buf_simple_pull_le16(buf);
|
2018-06-26 21:42:10 +03:00
|
|
|
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Prohibited element address");
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2018-06-26 21:42:10 +03:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
key_app_idx = net_buf_simple_pull_le16(buf);
|
|
|
|
mod_id = buf->data;
|
|
|
|
|
|
|
|
elem = bt_mesh_elem_find(elem_addr);
|
|
|
|
if (!elem) {
|
|
|
|
mod = NULL;
|
2019-03-26 19:57:45 -06:00
|
|
|
vnd = (buf->len == 4U);
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_INVALID_ADDRESS;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
|
|
|
mod = get_model(elem, buf, &vnd);
|
|
|
|
if (!mod) {
|
|
|
|
status = STATUS_INVALID_MODEL;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
2021-01-21 14:47:19 +01:00
|
|
|
/* Some models only allow device key based access */
|
2023-11-15 18:03:40 +08:00
|
|
|
if (mod->rt->flags & BT_MESH_MOD_DEVKEY_ONLY) {
|
2021-01-21 14:47:19 +01:00
|
|
|
LOG_ERR("Client tried to bind AppKey to DevKey based model");
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_CANNOT_BIND;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
|
|
|
status = mod_bind(mod, key_app_idx);
|
|
|
|
|
2017-12-27 20:26:50 +01:00
|
|
|
if (IS_ENABLED(CONFIG_BT_TESTING) && status == STATUS_SUCCESS) {
|
2024-08-23 12:46:25 +02:00
|
|
|
bt_mesh_test_model_bound(ctx->addr, mod, key_app_idx);
|
2017-12-27 20:26:50 +01:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
send_status:
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("status 0x%02x", status);
|
2018-02-10 10:32:58 +02:00
|
|
|
create_mod_app_status(&msg, mod, vnd, elem_addr, key_app_idx, status,
|
2017-06-16 12:30:54 +03:00
|
|
|
mod_id);
|
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Model App Bind Status response");
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int mod_app_unbind(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_STATUS, 9);
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t elem_addr, key_app_idx;
|
2023-11-14 12:00:30 +08:00
|
|
|
const struct bt_mesh_model *mod;
|
2023-11-17 09:36:34 +08:00
|
|
|
const struct bt_mesh_elem *elem;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t *mod_id, status;
|
2017-06-16 12:30:54 +03:00
|
|
|
bool vnd;
|
|
|
|
|
2021-04-27 15:59:54 +02:00
|
|
|
if ((buf->len != 6U) && (buf->len != 8U)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("The message size for the application opcode is incorrect.");
|
2021-04-27 15:59:54 +02:00
|
|
|
return -EMSGSIZE;
|
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
elem_addr = net_buf_simple_pull_le16(buf);
|
2018-06-26 21:42:10 +03:00
|
|
|
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Prohibited element address");
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2018-06-26 21:42:10 +03:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
key_app_idx = net_buf_simple_pull_le16(buf);
|
|
|
|
mod_id = buf->data;
|
|
|
|
|
|
|
|
elem = bt_mesh_elem_find(elem_addr);
|
|
|
|
if (!elem) {
|
|
|
|
mod = NULL;
|
2019-03-26 19:57:45 -06:00
|
|
|
vnd = (buf->len == 4U);
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_INVALID_ADDRESS;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
|
|
|
mod = get_model(elem, buf, &vnd);
|
|
|
|
if (!mod) {
|
|
|
|
status = STATUS_INVALID_MODEL;
|
|
|
|
goto send_status;
|
|
|
|
}
|
|
|
|
|
2018-06-26 11:34:27 +03:00
|
|
|
status = mod_unbind(mod, key_app_idx, true);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2017-12-27 20:26:50 +01:00
|
|
|
if (IS_ENABLED(CONFIG_BT_TESTING) && status == STATUS_SUCCESS) {
|
2024-08-23 12:46:25 +02:00
|
|
|
bt_mesh_test_model_unbound(ctx->addr, mod, key_app_idx);
|
2017-12-27 20:26:50 +01:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
send_status:
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("status 0x%02x", status);
|
2018-02-10 10:32:58 +02:00
|
|
|
create_mod_app_status(&msg, mod, vnd, elem_addr, key_app_idx, status,
|
2017-06-16 12:30:54 +03:00
|
|
|
mod_id);
|
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Model App Unbind Status response");
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2017-08-09 09:21:11 +03:00
|
|
|
#define KEY_LIST_LEN (CONFIG_BT_MESH_MODEL_KEY_COUNT * 2)
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int mod_app_get(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
NET_BUF_SIMPLE_DEFINE(msg,
|
|
|
|
MAX(BT_MESH_MODEL_BUF_LEN(OP_VND_MOD_APP_LIST,
|
|
|
|
9 + KEY_LIST_LEN),
|
|
|
|
BT_MESH_MODEL_BUF_LEN(OP_SIG_MOD_APP_LIST,
|
|
|
|
9 + KEY_LIST_LEN)));
|
2023-11-14 12:00:30 +08:00
|
|
|
const struct bt_mesh_model *mod;
|
2023-11-17 09:36:34 +08:00
|
|
|
const struct bt_mesh_elem *elem;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t *mod_id, status;
|
|
|
|
uint16_t elem_addr;
|
2017-06-16 12:30:54 +03:00
|
|
|
bool vnd;
|
|
|
|
|
2021-04-27 15:59:54 +02:00
|
|
|
if ((buf->len != 4U) && (buf->len != 6U)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("The message size for the application opcode is incorrect.");
|
2021-04-27 15:59:54 +02:00
|
|
|
return -EMSGSIZE;
|
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
elem_addr = net_buf_simple_pull_le16(buf);
|
2018-06-26 21:42:10 +03:00
|
|
|
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Prohibited element address");
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2018-06-26 21:42:10 +03:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
mod_id = buf->data;
|
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("elem_addr 0x%04x", elem_addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
elem = bt_mesh_elem_find(elem_addr);
|
|
|
|
if (!elem) {
|
|
|
|
mod = NULL;
|
2019-03-26 19:57:45 -06:00
|
|
|
vnd = (buf->len == 4U);
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_INVALID_ADDRESS;
|
|
|
|
goto send_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
mod = get_model(elem, buf, &vnd);
|
|
|
|
if (!mod) {
|
|
|
|
status = STATUS_INVALID_MODEL;
|
|
|
|
goto send_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
send_list:
|
|
|
|
if (vnd) {
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_VND_MOD_APP_LIST);
|
2017-06-16 12:30:54 +03:00
|
|
|
} else {
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_SIG_MOD_APP_LIST);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_u8(&msg, status);
|
|
|
|
net_buf_simple_add_le16(&msg, elem_addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
if (vnd) {
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_mem(&msg, mod_id, 4);
|
2017-06-16 12:30:54 +03:00
|
|
|
} else {
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_mem(&msg, mod_id, 2);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (mod) {
|
2023-07-05 14:52:55 +02:00
|
|
|
key_idx_pack_list(&msg, mod->keys, mod->keys_cnt);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Model Application List message");
|
2017-11-21 21:22:46 +02:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2021-05-26 20:39:13 -07:00
|
|
|
static void reset_send_start(uint16_t duration, int err, void *cb_data)
|
|
|
|
{
|
|
|
|
if (err) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Sending Node Reset Status failed (err %d)", err);
|
2022-07-12 09:36:51 +02:00
|
|
|
k_work_submit(&node_reset_pending);
|
2021-05-26 20:39:13 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void reset_send_end(int err, void *cb_data)
|
|
|
|
{
|
2022-07-12 09:36:51 +02:00
|
|
|
k_work_submit(&node_reset_pending);
|
2021-05-26 20:39:13 -07:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int node_reset(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2021-05-26 20:39:13 -07:00
|
|
|
static const struct bt_mesh_send_cb reset_cb = {
|
|
|
|
.start = reset_send_start,
|
|
|
|
.end = reset_send_end,
|
|
|
|
};
|
2020-07-06 14:09:16 +02:00
|
|
|
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_RESET_STATUS, 0);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
|
|
|
|
ctx->addr, buf->len, bt_hex(buf->data, buf->len));
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_NODE_RESET_STATUS);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2021-05-26 20:39:13 -07:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, &reset_cb, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Node Reset Status");
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int send_friend_status(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_FRIEND_STATUS, 1);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_FRIEND_STATUS);
|
2020-08-18 13:36:38 +02:00
|
|
|
net_buf_simple_add_u8(&msg, bt_mesh_friend_get());
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Friend Status");
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int friend_get(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
|
|
|
|
ctx->addr, buf->len, bt_hex(buf->data, buf->len));
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_friend_status(model, ctx);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int friend_set(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx,
|
|
|
|
ctx->addr, buf->len, bt_hex(buf->data, buf->len));
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
if (buf->data[0] != 0x00 && buf->data[0] != 0x01) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Invalid Friend value 0x%02x", buf->data[0]);
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2020-08-18 13:36:38 +02:00
|
|
|
(void)bt_mesh_friend_set(buf->data[0]);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_friend_status(model, ctx);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int lpn_timeout_get(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_LPN_TIMEOUT_STATUS, 5);
|
2017-11-05 20:09:04 +02:00
|
|
|
struct bt_mesh_friend *frnd;
|
2021-04-15 12:30:47 +02:00
|
|
|
int32_t timeout_steps;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t lpn_addr;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
lpn_addr = net_buf_simple_pull_le16(buf);
|
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x lpn_addr 0x%02x", ctx->net_idx,
|
|
|
|
ctx->app_idx, ctx->addr, lpn_addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2017-09-28 18:05:01 +03:00
|
|
|
if (!BT_MESH_ADDR_IS_UNICAST(lpn_addr)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Invalid LPNAddress; ignoring msg");
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-09-28 18:05:01 +03:00
|
|
|
}
|
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_LPN_TIMEOUT_STATUS);
|
|
|
|
net_buf_simple_add_le16(&msg, lpn_addr);
|
2017-11-05 20:09:04 +02:00
|
|
|
|
2018-05-23 22:11:58 +03:00
|
|
|
if (!IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
|
2021-04-15 12:30:47 +02:00
|
|
|
timeout_steps = 0;
|
2017-11-05 20:09:04 +02:00
|
|
|
goto send_rsp;
|
|
|
|
}
|
|
|
|
|
2017-11-10 10:15:23 +02:00
|
|
|
frnd = bt_mesh_friend_find(BT_MESH_KEY_ANY, lpn_addr, true, true);
|
2017-11-05 20:09:04 +02:00
|
|
|
if (!frnd) {
|
2021-04-15 12:30:47 +02:00
|
|
|
timeout_steps = 0;
|
2017-11-05 20:09:04 +02:00
|
|
|
goto send_rsp;
|
|
|
|
}
|
|
|
|
|
2021-04-15 12:30:47 +02:00
|
|
|
/* PollTimeout should be reported in steps of 100ms. */
|
|
|
|
timeout_steps = frnd->poll_to / 100;
|
2017-11-05 20:09:04 +02:00
|
|
|
|
|
|
|
send_rsp:
|
2021-04-15 12:30:47 +02:00
|
|
|
net_buf_simple_add_le24(&msg, timeout_steps);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send LPN PollTimeout Status");
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int send_krp_status(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx, uint16_t idx,
|
|
|
|
uint8_t phase, uint8_t status)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_KRP_STATUS, 4);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_KRP_STATUS);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_u8(&msg, status);
|
|
|
|
net_buf_simple_add_le16(&msg, idx);
|
|
|
|
net_buf_simple_add_u8(&msg, phase);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Key Refresh State Status");
|
2017-11-21 21:22:46 +02:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int krp_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
|
2017-06-16 12:30:54 +03:00
|
|
|
struct net_buf_simple *buf)
|
|
|
|
{
|
2020-08-25 11:03:42 +02:00
|
|
|
uint8_t kr_phase, status;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t idx;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
idx = net_buf_simple_pull_le16(buf);
|
|
|
|
if (idx > 0xfff) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Invalid NetKeyIndex 0x%04x", idx);
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("idx 0x%04x", idx);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-25 11:03:42 +02:00
|
|
|
status = bt_mesh_subnet_kr_phase_get(idx, &kr_phase);
|
|
|
|
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_krp_status(model, ctx, idx, kr_phase, status);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int krp_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-08-25 11:03:42 +02:00
|
|
|
uint8_t phase, status;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t idx;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
idx = net_buf_simple_pull_le16(buf);
|
|
|
|
phase = net_buf_simple_pull_u8(buf);
|
|
|
|
|
|
|
|
if (idx > 0xfff) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Invalid NetKeyIndex 0x%04x", idx);
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2020-08-25 11:03:42 +02:00
|
|
|
status = bt_mesh_subnet_kr_phase_set(idx, &phase);
|
|
|
|
if (status == STATUS_CANNOT_UPDATE) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Invalid kr phase transition 0x%02x", phase);
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2021-04-14 13:17:59 +02:00
|
|
|
return send_krp_status(model, ctx, idx, phase, status);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2020-07-16 14:16:46 +02:00
|
|
|
static uint8_t hb_sub_count_log(uint32_t val)
|
|
|
|
{
|
|
|
|
if (val == 0xffff) {
|
|
|
|
return 0xff;
|
|
|
|
} else {
|
|
|
|
return bt_mesh_hb_log(val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-27 11:26:57 -05:00
|
|
|
static uint8_t hb_pub_count_log(uint16_t val)
|
2017-11-02 15:24:24 +02:00
|
|
|
{
|
|
|
|
if (!val) {
|
|
|
|
return 0x00;
|
|
|
|
} else if (val == 0x01) {
|
|
|
|
return 0x01;
|
2020-07-16 14:16:46 +02:00
|
|
|
} else if (val == 0xfffe) {
|
|
|
|
return 0x11;
|
2017-11-02 15:24:24 +02:00
|
|
|
} else if (val == 0xffff) {
|
|
|
|
return 0xff;
|
|
|
|
} else {
|
|
|
|
return 32 - __builtin_clz(val - 1) + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
struct hb_pub_param {
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t dst;
|
|
|
|
uint8_t count_log;
|
|
|
|
uint8_t period_log;
|
|
|
|
uint8_t ttl;
|
|
|
|
uint16_t feat;
|
|
|
|
uint16_t net_idx;
|
2017-06-16 12:30:54 +03:00
|
|
|
} __packed;
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int hb_pub_send_status(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx, uint8_t status,
|
|
|
|
const struct bt_mesh_hb_pub *pub)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_PUB_STATUS, 10);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("src 0x%04x status 0x%02x", ctx->addr, status);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_PUB_STATUS);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
net_buf_simple_add_u8(&msg, status);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-12 17:07:38 +02:00
|
|
|
net_buf_simple_add_le16(&msg, pub->dst);
|
2023-10-25 11:08:21 +02:00
|
|
|
if (pub->dst == BT_MESH_ADDR_UNASSIGNED) {
|
|
|
|
(void)memset(net_buf_simple_add(&msg, 7), 0, 7);
|
|
|
|
} else {
|
|
|
|
net_buf_simple_add_u8(&msg, hb_pub_count_log(pub->count));
|
|
|
|
net_buf_simple_add_u8(&msg, bt_mesh_hb_log(pub->period));
|
|
|
|
net_buf_simple_add_u8(&msg, pub->ttl);
|
|
|
|
net_buf_simple_add_le16(&msg, pub->feat);
|
2023-10-25 11:08:21 +02:00
|
|
|
net_buf_simple_add_le16(&msg, pub->net_idx & 0xfff);
|
2023-10-25 11:08:21 +02:00
|
|
|
}
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Heartbeat Publication Status");
|
2017-11-21 21:22:46 +02:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int heartbeat_pub_get(const struct bt_mesh_model *model,
|
2017-09-28 17:24:11 +03:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-08-12 17:07:38 +02:00
|
|
|
struct bt_mesh_hb_pub pub;
|
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("src 0x%04x", ctx->addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-12 17:07:38 +02:00
|
|
|
bt_mesh_hb_pub_get(&pub);
|
|
|
|
|
2021-04-14 13:17:59 +02:00
|
|
|
return hb_pub_send_status(model, ctx, STATUS_SUCCESS, &pub);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int heartbeat_pub_set(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
|
|
|
struct hb_pub_param *param = (void *)buf->data;
|
2020-08-12 17:07:38 +02:00
|
|
|
struct bt_mesh_hb_pub pub;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint8_t status;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("src 0x%04x", ctx->addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-12 17:07:38 +02:00
|
|
|
pub.dst = sys_le16_to_cpu(param->dst);
|
2020-07-16 14:16:46 +02:00
|
|
|
if (param->count_log == 0x11) {
|
2023-10-20 08:58:06 +02:00
|
|
|
/* Special case defined in MshPRFv1.1 Errata 11737 */
|
2020-07-16 14:16:46 +02:00
|
|
|
pub.count = 0xfffe;
|
|
|
|
} else {
|
|
|
|
pub.count = bt_mesh_hb_pwr2(param->count_log);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (param->period_log == 0x11) {
|
|
|
|
pub.period = 0x10000;
|
|
|
|
} else {
|
|
|
|
pub.period = bt_mesh_hb_pwr2(param->period_log);
|
|
|
|
}
|
|
|
|
|
2020-08-12 17:07:38 +02:00
|
|
|
pub.ttl = param->ttl;
|
|
|
|
pub.feat = sys_le16_to_cpu(param->feat);
|
|
|
|
pub.net_idx = sys_le16_to_cpu(param->net_idx);
|
|
|
|
|
2017-06-16 12:30:54 +03:00
|
|
|
/* All other address types but virtual are valid */
|
2020-08-12 17:07:38 +02:00
|
|
|
if (BT_MESH_ADDR_IS_VIRTUAL(pub.dst)) {
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_INVALID_ADDRESS;
|
2020-08-12 17:07:38 +02:00
|
|
|
goto rsp;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (param->count_log > 0x11 && param->count_log != 0xff) {
|
|
|
|
status = STATUS_CANNOT_SET;
|
2020-08-12 17:07:38 +02:00
|
|
|
goto rsp;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2020-07-16 14:16:46 +02:00
|
|
|
if (param->period_log > 0x11) {
|
2017-06-16 12:30:54 +03:00
|
|
|
status = STATUS_CANNOT_SET;
|
2020-08-12 17:07:38 +02:00
|
|
|
goto rsp;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2017-11-13 00:14:25 +02:00
|
|
|
if (param->ttl > BT_MESH_TTL_MAX && param->ttl != BT_MESH_TTL_DEFAULT) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Invalid TTL value 0x%02x", param->ttl);
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2020-08-12 17:07:38 +02:00
|
|
|
if (pub.net_idx > 0xfff) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Invalid NetKeyIndex 0x%04x", pub.net_idx);
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2020-08-12 17:07:38 +02:00
|
|
|
status = bt_mesh_hb_pub_set(&pub);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-12 17:07:38 +02:00
|
|
|
rsp:
|
2021-04-14 13:17:59 +02:00
|
|
|
return hb_pub_send_status(model, ctx, status, &pub);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int hb_sub_send_status(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
const struct bt_mesh_hb_sub *sub)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-10-08 09:39:48 +02:00
|
|
|
BT_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_SUB_STATUS, 9);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("src 0x%04x ", ctx->addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
bt_mesh_model_msg_init(&msg, OP_HEARTBEAT_SUB_STATUS);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-12 17:07:38 +02:00
|
|
|
net_buf_simple_add_u8(&msg, STATUS_SUCCESS);
|
|
|
|
net_buf_simple_add_le16(&msg, sub->src);
|
|
|
|
net_buf_simple_add_le16(&msg, sub->dst);
|
|
|
|
net_buf_simple_add_u8(&msg, bt_mesh_hb_log(sub->remaining));
|
2020-07-16 14:16:46 +02:00
|
|
|
net_buf_simple_add_u8(&msg, hb_sub_count_log(sub->count));
|
2020-08-12 17:07:38 +02:00
|
|
|
net_buf_simple_add_u8(&msg, sub->min_hops);
|
|
|
|
net_buf_simple_add_u8(&msg, sub->max_hops);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2018-02-10 10:32:58 +02:00
|
|
|
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Unable to send Heartbeat Subscription Status");
|
2017-11-21 21:22:46 +02:00
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int heartbeat_sub_get(const struct bt_mesh_model *model,
|
2017-09-28 17:24:11 +03:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-08-12 17:07:38 +02:00
|
|
|
struct bt_mesh_hb_sub sub;
|
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("src 0x%04x", ctx->addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-12 17:07:38 +02:00
|
|
|
bt_mesh_hb_sub_get(&sub);
|
|
|
|
|
2021-04-14 13:17:59 +02:00
|
|
|
return hb_sub_send_status(model, ctx, &sub);
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int heartbeat_sub_set(const struct bt_mesh_model *model,
|
2021-04-14 13:17:59 +02:00
|
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
|
|
struct net_buf_simple *buf)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2020-08-12 17:07:38 +02:00
|
|
|
uint8_t period_log, status;
|
|
|
|
struct bt_mesh_hb_sub sub;
|
2020-05-27 11:26:57 -05:00
|
|
|
uint16_t sub_src, sub_dst;
|
2020-08-12 17:07:38 +02:00
|
|
|
uint32_t period;
|
2021-04-14 13:17:59 +02:00
|
|
|
int err;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("src 0x%04x", ctx->addr);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
sub_src = net_buf_simple_pull_le16(buf);
|
|
|
|
sub_dst = net_buf_simple_pull_le16(buf);
|
2020-08-12 17:07:38 +02:00
|
|
|
period_log = net_buf_simple_pull_u8(buf);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_DBG("sub_src 0x%04x sub_dst 0x%04x period 0x%02x", sub_src, sub_dst, period_log);
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-12 17:07:38 +02:00
|
|
|
if (period_log > 0x11) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_WRN("Prohibited subscription period 0x%02x", period_log);
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2020-07-16 14:16:46 +02:00
|
|
|
if (period_log == 0x11) {
|
|
|
|
period = 0x10000;
|
|
|
|
} else {
|
|
|
|
period = bt_mesh_hb_pwr2(period_log);
|
|
|
|
}
|
2017-06-16 12:30:54 +03:00
|
|
|
|
2020-08-12 17:07:38 +02:00
|
|
|
status = bt_mesh_hb_sub_set(sub_src, sub_dst, period);
|
|
|
|
if (status != STATUS_SUCCESS) {
|
|
|
|
/* All errors are caused by invalid packets, which should be
|
|
|
|
* ignored.
|
2017-11-02 20:46:15 +03:00
|
|
|
*/
|
2021-04-14 13:17:59 +02:00
|
|
|
return -EINVAL;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2020-08-12 17:07:38 +02:00
|
|
|
bt_mesh_hb_sub_get(&sub);
|
2018-08-15 14:58:26 +03:00
|
|
|
|
|
|
|
/* MESH/NODE/CFG/HBS/BV-01-C expects the MinHops to be 0x7f after
|
|
|
|
* disabling subscription, but 0x00 for subsequent Get requests.
|
|
|
|
*/
|
2020-12-17 16:22:49 +01:00
|
|
|
if (sub.src == BT_MESH_ADDR_UNASSIGNED || !period_log) {
|
2020-08-12 17:07:38 +02:00
|
|
|
sub.min_hops = BT_MESH_TTL_MAX;
|
2018-08-15 14:58:26 +03:00
|
|
|
}
|
2020-08-12 17:07:38 +02:00
|
|
|
|
2021-04-14 13:17:59 +02:00
|
|
|
err = hb_sub_send_status(model, ctx, &sub);
|
|
|
|
if (err) {
|
|
|
|
return err;
|
|
|
|
}
|
2020-12-17 16:22:49 +01:00
|
|
|
|
|
|
|
/* MESH/NODE/CFG/HBS/BV-02-C expects us to return previous
|
|
|
|
* count value and then reset it to 0.
|
|
|
|
*/
|
|
|
|
if (sub.src != BT_MESH_ADDR_UNASSIGNED &&
|
|
|
|
sub.dst != BT_MESH_ADDR_UNASSIGNED && !period) {
|
|
|
|
bt_mesh_hb_sub_reset_count();
|
|
|
|
}
|
2021-04-14 13:17:59 +02:00
|
|
|
|
|
|
|
return 0;
|
2017-06-16 12:30:54 +03:00
|
|
|
}
|
|
|
|
|
2017-11-13 21:31:25 +02:00
|
|
|
const struct bt_mesh_model_op bt_mesh_cfg_srv_op[] = {
|
2021-04-27 15:59:54 +02:00
|
|
|
{ OP_DEV_COMP_DATA_GET, BT_MESH_LEN_EXACT(1), dev_comp_data_get },
|
|
|
|
{ OP_APP_KEY_ADD, BT_MESH_LEN_EXACT(19), app_key_add },
|
|
|
|
{ OP_APP_KEY_UPDATE, BT_MESH_LEN_EXACT(19), app_key_update },
|
|
|
|
{ OP_APP_KEY_DEL, BT_MESH_LEN_EXACT(3), app_key_del },
|
|
|
|
{ OP_APP_KEY_GET, BT_MESH_LEN_EXACT(2), app_key_get },
|
|
|
|
{ OP_BEACON_GET, BT_MESH_LEN_EXACT(0), beacon_get },
|
|
|
|
{ OP_BEACON_SET, BT_MESH_LEN_EXACT(1), beacon_set },
|
|
|
|
{ OP_DEFAULT_TTL_GET, BT_MESH_LEN_EXACT(0), default_ttl_get },
|
|
|
|
{ OP_DEFAULT_TTL_SET, BT_MESH_LEN_EXACT(1), default_ttl_set },
|
|
|
|
{ OP_GATT_PROXY_GET, BT_MESH_LEN_EXACT(0), gatt_proxy_get },
|
|
|
|
{ OP_GATT_PROXY_SET, BT_MESH_LEN_EXACT(1), gatt_proxy_set },
|
|
|
|
{ OP_NET_TRANSMIT_GET, BT_MESH_LEN_EXACT(0), net_transmit_get },
|
|
|
|
{ OP_NET_TRANSMIT_SET, BT_MESH_LEN_EXACT(1), net_transmit_set },
|
|
|
|
{ OP_RELAY_GET, BT_MESH_LEN_EXACT(0), relay_get },
|
|
|
|
{ OP_RELAY_SET, BT_MESH_LEN_EXACT(2), relay_set },
|
|
|
|
{ OP_MOD_PUB_GET, BT_MESH_LEN_MIN(4), mod_pub_get },
|
|
|
|
{ OP_MOD_PUB_SET, BT_MESH_LEN_MIN(11), mod_pub_set },
|
|
|
|
{ OP_MOD_PUB_VA_SET, BT_MESH_LEN_MIN(25), mod_pub_va_set },
|
|
|
|
{ OP_MOD_SUB_ADD, BT_MESH_LEN_MIN(6), mod_sub_add },
|
|
|
|
{ OP_MOD_SUB_VA_ADD, BT_MESH_LEN_MIN(20), mod_sub_va_add },
|
|
|
|
{ OP_MOD_SUB_DEL, BT_MESH_LEN_MIN(6), mod_sub_del },
|
|
|
|
{ OP_MOD_SUB_VA_DEL, BT_MESH_LEN_MIN(20), mod_sub_va_del },
|
|
|
|
{ OP_MOD_SUB_OVERWRITE, BT_MESH_LEN_MIN(6), mod_sub_overwrite },
|
|
|
|
{ OP_MOD_SUB_VA_OVERWRITE, BT_MESH_LEN_MIN(20), mod_sub_va_overwrite },
|
|
|
|
{ OP_MOD_SUB_DEL_ALL, BT_MESH_LEN_MIN(4), mod_sub_del_all },
|
|
|
|
{ OP_MOD_SUB_GET, BT_MESH_LEN_EXACT(4), mod_sub_get },
|
|
|
|
{ OP_MOD_SUB_GET_VND, BT_MESH_LEN_EXACT(6), mod_sub_get_vnd },
|
|
|
|
{ OP_NET_KEY_ADD, BT_MESH_LEN_EXACT(18), net_key_add },
|
|
|
|
{ OP_NET_KEY_UPDATE, BT_MESH_LEN_EXACT(18), net_key_update },
|
|
|
|
{ OP_NET_KEY_DEL, BT_MESH_LEN_EXACT(2), net_key_del },
|
|
|
|
{ OP_NET_KEY_GET, BT_MESH_LEN_EXACT(0), net_key_get },
|
|
|
|
{ OP_NODE_IDENTITY_GET, BT_MESH_LEN_EXACT(2), node_identity_get },
|
|
|
|
{ OP_NODE_IDENTITY_SET, BT_MESH_LEN_EXACT(3), node_identity_set },
|
|
|
|
{ OP_MOD_APP_BIND, BT_MESH_LEN_MIN(6), mod_app_bind },
|
|
|
|
{ OP_MOD_APP_UNBIND, BT_MESH_LEN_MIN(6), mod_app_unbind },
|
|
|
|
{ OP_SIG_MOD_APP_GET, BT_MESH_LEN_MIN(4), mod_app_get },
|
|
|
|
{ OP_VND_MOD_APP_GET, BT_MESH_LEN_MIN(6), mod_app_get },
|
|
|
|
{ OP_NODE_RESET, BT_MESH_LEN_EXACT(0), node_reset },
|
|
|
|
{ OP_FRIEND_GET, BT_MESH_LEN_EXACT(0), friend_get },
|
|
|
|
{ OP_FRIEND_SET, BT_MESH_LEN_EXACT(1), friend_set },
|
|
|
|
{ OP_LPN_TIMEOUT_GET, BT_MESH_LEN_EXACT(2), lpn_timeout_get },
|
|
|
|
{ OP_KRP_GET, BT_MESH_LEN_EXACT(2), krp_get },
|
|
|
|
{ OP_KRP_SET, BT_MESH_LEN_EXACT(3), krp_set },
|
|
|
|
{ OP_HEARTBEAT_PUB_GET, BT_MESH_LEN_EXACT(0), heartbeat_pub_get },
|
|
|
|
{ OP_HEARTBEAT_PUB_SET, BT_MESH_LEN_EXACT(9), heartbeat_pub_set },
|
|
|
|
{ OP_HEARTBEAT_SUB_GET, BT_MESH_LEN_EXACT(0), heartbeat_sub_get },
|
|
|
|
{ OP_HEARTBEAT_SUB_SET, BT_MESH_LEN_EXACT(5), heartbeat_sub_set },
|
2017-06-16 12:30:54 +03:00
|
|
|
BT_MESH_MODEL_OP_END,
|
|
|
|
};
|
|
|
|
|
2023-11-14 12:00:30 +08:00
|
|
|
static int cfg_srv_init(const struct bt_mesh_model *model)
|
2017-06-16 12:30:54 +03:00
|
|
|
{
|
2019-08-19 10:05:36 +02:00
|
|
|
if (!bt_mesh_model_in_primary(model)) {
|
2022-11-02 14:31:13 +01:00
|
|
|
LOG_ERR("Configuration Server only allowed in primary element");
|
2019-08-19 10:05:36 +02:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2019-07-12 15:57:58 +02:00
|
|
|
/*
|
|
|
|
* Configuration Model security is device-key based and only the local
|
|
|
|
* device-key is allowed to access this model.
|
|
|
|
*/
|
|
|
|
model->keys[0] = BT_MESH_KEY_DEV_LOCAL;
|
2023-11-15 18:03:40 +08:00
|
|
|
model->rt->flags |= BT_MESH_MOD_DEVKEY_ONLY;
|
2017-06-16 12:30:54 +03:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-08-19 10:05:36 +02:00
|
|
|
const struct bt_mesh_model_cb bt_mesh_cfg_srv_cb = {
|
|
|
|
.init = cfg_srv_init,
|
|
|
|
};
|
|
|
|
|
2023-11-17 09:36:34 +08:00
|
|
|
static void mod_reset(const struct bt_mesh_model *mod, const struct bt_mesh_elem *elem,
|
2018-05-09 21:47:01 +03:00
|
|
|
bool vnd, bool primary, void *user_data)
|
|
|
|
{
|
2019-03-20 13:46:37 +02:00
|
|
|
size_t clear_count;
|
|
|
|
|
2018-05-09 21:47:01 +03:00
|
|
|
/* Clear model state that isn't otherwise cleared. E.g. AppKey
|
|
|
|
* binding and model publication is cleared as a consequence
|
2019-09-16 14:48:11 +02:00
|
|
|
* of removing all app keys, however model subscription and user data
|
|
|
|
* clearing must be taken care of here.
|
2018-05-09 21:47:01 +03:00
|
|
|
*/
|
|
|
|
|
2019-03-20 13:46:37 +02:00
|
|
|
clear_count = mod_sub_list_clear(mod);
|
2018-05-09 21:47:01 +03:00
|
|
|
|
2019-09-16 14:48:11 +02:00
|
|
|
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
|
|
|
if (clear_count) {
|
2021-01-06 09:56:56 +01:00
|
|
|
bt_mesh_model_sub_store(mod);
|
2019-09-16 14:48:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mod->cb && mod->cb->reset) {
|
|
|
|
mod->cb->reset(mod);
|
2018-05-09 21:47:01 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-23 16:27:35 +02:00
|
|
|
void bt_mesh_model_reset(void)
|
2017-11-20 14:51:32 +02:00
|
|
|
{
|
2018-05-09 21:47:01 +03:00
|
|
|
bt_mesh_model_foreach(mod_reset, NULL);
|
2017-11-20 14:51:32 +02:00
|
|
|
}
|