|  | /* | 
|  | * Copyright (c) 2020 Nordic Semiconductor ASA | 
|  | * | 
|  | * SPDX-License-Identifier: Apache-2.0 | 
|  | */ | 
|  | #include <zephyr/bluetooth/mesh.h> | 
|  | #include "net.h" | 
|  | #include "adv.h" | 
|  | #include <zephyr/bluetooth/conn.h> | 
|  | #include "proxy.h" | 
|  | #include "foundation.h" | 
|  | #include "beacon.h" | 
|  | #include "cfg.h" | 
|  |  | 
|  | #define LOG_LEVEL CONFIG_BT_MESH_MODEL_LOG_LEVEL | 
|  | #include <zephyr/logging/log.h> | 
|  | LOG_MODULE_REGISTER(bt_mesh_priv_beacon_srv); | 
|  |  | 
|  | static int beacon_status_rsp(struct bt_mesh_model *mod, | 
|  | struct bt_mesh_msg_ctx *ctx) | 
|  | { | 
|  | BT_MESH_MODEL_BUF_DEFINE(buf, OP_PRIV_BEACON_STATUS, 2); | 
|  | bt_mesh_model_msg_init(&buf, OP_PRIV_BEACON_STATUS); | 
|  |  | 
|  | net_buf_simple_add_u8(&buf, bt_mesh_priv_beacon_get()); | 
|  | net_buf_simple_add_u8(&buf, bt_mesh_priv_beacon_update_interval_get()); | 
|  |  | 
|  | bt_mesh_model_send(mod, ctx, &buf, NULL, NULL); | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int handle_beacon_get(struct bt_mesh_model *mod, | 
|  | struct bt_mesh_msg_ctx *ctx, | 
|  | struct net_buf_simple *buf) | 
|  | { | 
|  | LOG_DBG(""); | 
|  |  | 
|  | beacon_status_rsp(mod, ctx); | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int handle_beacon_set(struct bt_mesh_model *mod, | 
|  | struct bt_mesh_msg_ctx *ctx, | 
|  | struct net_buf_simple *buf) | 
|  | { | 
|  | uint8_t beacon; | 
|  |  | 
|  | if (buf->len > 2U) { | 
|  | return -EMSGSIZE; | 
|  | } | 
|  |  | 
|  | beacon = net_buf_simple_pull_u8(buf); | 
|  | if (beacon != BT_MESH_BEACON_DISABLED && | 
|  | beacon != BT_MESH_BEACON_ENABLED) { | 
|  | LOG_WRN("Invalid beacon value %u", beacon); | 
|  | return -EINVAL; | 
|  | } | 
|  |  | 
|  | if (buf->len == 1U) { | 
|  | bt_mesh_priv_beacon_update_interval_set(net_buf_simple_pull_u8(buf)); | 
|  | } | 
|  |  | 
|  | (void)bt_mesh_priv_beacon_set(beacon); | 
|  | beacon_status_rsp(mod, ctx); | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static void gatt_proxy_status_rsp(struct bt_mesh_model *mod, | 
|  | struct bt_mesh_msg_ctx *ctx) | 
|  | { | 
|  | BT_MESH_MODEL_BUF_DEFINE(buf, OP_PRIV_GATT_PROXY_STATUS, 1); | 
|  | bt_mesh_model_msg_init(&buf, OP_PRIV_GATT_PROXY_STATUS); | 
|  |  | 
|  | net_buf_simple_add_u8(&buf, bt_mesh_priv_gatt_proxy_get()); | 
|  |  | 
|  | bt_mesh_model_send(mod, ctx, &buf, NULL, NULL); | 
|  | } | 
|  |  | 
|  | static int handle_gatt_proxy_get(struct bt_mesh_model *mod, | 
|  | struct bt_mesh_msg_ctx *ctx, | 
|  | struct net_buf_simple *buf) | 
|  | { | 
|  | LOG_DBG(""); | 
|  |  | 
|  | gatt_proxy_status_rsp(mod, ctx); | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int handle_gatt_proxy_set(struct bt_mesh_model *mod, | 
|  | struct bt_mesh_msg_ctx *ctx, | 
|  | struct net_buf_simple *buf) | 
|  | { | 
|  | uint8_t gatt_proxy; | 
|  |  | 
|  | gatt_proxy = net_buf_simple_pull_u8(buf); | 
|  | if (gatt_proxy != BT_MESH_GATT_PROXY_DISABLED && | 
|  | gatt_proxy != BT_MESH_GATT_PROXY_ENABLED) { | 
|  | LOG_WRN("Invalid GATT proxy value %u", gatt_proxy); | 
|  | return -EINVAL; | 
|  | } | 
|  |  | 
|  | LOG_DBG("%u", gatt_proxy); | 
|  |  | 
|  | bt_mesh_priv_gatt_proxy_set(gatt_proxy); | 
|  |  | 
|  | gatt_proxy_status_rsp(mod, ctx); | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static void node_id_status_rsp(struct bt_mesh_model *mod, | 
|  | struct bt_mesh_msg_ctx *ctx, uint8_t status, | 
|  | uint16_t net_idx, uint8_t node_id) | 
|  | { | 
|  | BT_MESH_MODEL_BUF_DEFINE(buf, OP_PRIV_NODE_ID_STATUS, 4); | 
|  | bt_mesh_model_msg_init(&buf, OP_PRIV_NODE_ID_STATUS); | 
|  |  | 
|  | net_buf_simple_add_u8(&buf, status); | 
|  | net_buf_simple_add_le16(&buf, net_idx); | 
|  | net_buf_simple_add_u8(&buf, node_id); | 
|  |  | 
|  | bt_mesh_model_send(mod, ctx, &buf, NULL, NULL); | 
|  | } | 
|  |  | 
|  | static int handle_node_id_get(struct bt_mesh_model *mod, | 
|  | struct bt_mesh_msg_ctx *ctx, | 
|  | struct net_buf_simple *buf) | 
|  | { | 
|  | uint8_t node_id, status; | 
|  | uint16_t net_idx; | 
|  |  | 
|  | net_idx = net_buf_simple_pull_le16(buf) & 0xfff; | 
|  |  | 
|  | status = bt_mesh_subnet_priv_node_id_get(net_idx, (enum bt_mesh_feat_state *)&node_id); | 
|  | node_id_status_rsp(mod, ctx, status, net_idx, node_id); | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int handle_node_id_set(struct bt_mesh_model *mod, | 
|  | struct bt_mesh_msg_ctx *ctx, | 
|  | struct net_buf_simple *buf) | 
|  | { | 
|  | uint8_t node_id, status; | 
|  | uint16_t net_idx; | 
|  |  | 
|  | net_idx = net_buf_simple_pull_le16(buf) & 0xfff; | 
|  | node_id = net_buf_simple_pull_u8(buf); | 
|  | if (node_id != BT_MESH_NODE_IDENTITY_RUNNING && | 
|  | node_id != BT_MESH_NODE_IDENTITY_STOPPED) { | 
|  | LOG_ERR("Invalid node ID value 0x%02x", node_id); | 
|  | return -EINVAL; | 
|  | } | 
|  |  | 
|  | status = bt_mesh_subnet_priv_node_id_set(net_idx, node_id); | 
|  | node_id_status_rsp(mod, ctx, status, net_idx, node_id); | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | const struct bt_mesh_model_op bt_mesh_priv_beacon_srv_op[] = { | 
|  | { OP_PRIV_BEACON_GET, BT_MESH_LEN_EXACT(0), handle_beacon_get }, | 
|  | { OP_PRIV_BEACON_SET, BT_MESH_LEN_MIN(1), handle_beacon_set }, | 
|  | { OP_PRIV_GATT_PROXY_GET, BT_MESH_LEN_EXACT(0), handle_gatt_proxy_get }, | 
|  | { OP_PRIV_GATT_PROXY_SET, BT_MESH_LEN_EXACT(1), handle_gatt_proxy_set }, | 
|  | { OP_PRIV_NODE_ID_GET, BT_MESH_LEN_EXACT(2), handle_node_id_get }, | 
|  | { OP_PRIV_NODE_ID_SET, BT_MESH_LEN_EXACT(3), handle_node_id_set }, | 
|  | BT_MESH_MODEL_OP_END | 
|  | }; | 
|  |  | 
|  | static int priv_beacon_srv_init(struct bt_mesh_model *mod) | 
|  | { | 
|  | if (!bt_mesh_model_in_primary(mod)) { | 
|  | LOG_ERR("Priv beacon server not in primary element"); | 
|  | return -EINVAL; | 
|  | } | 
|  |  | 
|  | mod->keys[0] = BT_MESH_KEY_DEV_LOCAL; | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | const struct bt_mesh_model_cb bt_mesh_priv_beacon_srv_cb = { | 
|  | .init = priv_beacon_srv_init, | 
|  | }; |