1 /*
2 * Copyright (c) 2021 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <string.h>
9 #include <errno.h>
10 #include <stdbool.h>
11 #include <zephyr/types.h>
12 #include <zephyr/sys/util.h>
13 #include <zephyr/sys/byteorder.h>
14
15 #include <zephyr/bluetooth/bluetooth.h>
16 #include <zephyr/bluetooth/conn.h>
17 #include <zephyr/bluetooth/mesh.h>
18
19 #include "net.h"
20 #include "access.h"
21 #include "foundation.h"
22 #include "mesh.h"
23 #include "sar_cfg_internal.h"
24 #include "settings.h"
25
26 #define LOG_LEVEL CONFIG_BT_MESH_MODEL_LOG_LEVEL
27 #include <zephyr/logging/log.h>
28 LOG_MODULE_REGISTER(bt_mesh_sar_cfg_srv);
29
sar_rx_store(const struct bt_mesh_model * model,bool delete)30 static int sar_rx_store(const struct bt_mesh_model *model, bool delete)
31 {
32 const void *data = delete ? NULL : &bt_mesh.sar_rx;
33 size_t len = delete ? 0 : sizeof(struct bt_mesh_sar_rx);
34
35 return bt_mesh_model_data_store(model, false, "sar_rx", data, len);
36 }
37
sar_tx_store(const struct bt_mesh_model * model,bool delete)38 static int sar_tx_store(const struct bt_mesh_model *model, bool delete)
39 {
40 const void *data = delete ? NULL : &bt_mesh.sar_tx;
41 size_t len = delete ? 0 : sizeof(struct bt_mesh_sar_tx);
42
43 return bt_mesh_model_data_store(model, false, "sar_tx", data, len);
44 }
45
transmitter_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx)46 static void transmitter_status(const struct bt_mesh_model *model,
47 struct bt_mesh_msg_ctx *ctx)
48 {
49 BT_MESH_MODEL_BUF_DEFINE(msg, OP_SAR_CFG_TX_STATUS, BT_MESH_SAR_TX_LEN);
50 const struct bt_mesh_sar_tx *tx = &bt_mesh.sar_tx;
51
52 LOG_DBG("SAR TX {0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x}",
53 tx->seg_int_step, tx->unicast_retrans_count,
54 tx->unicast_retrans_without_prog_count,
55 tx->unicast_retrans_int_step, tx->unicast_retrans_int_inc,
56 tx->multicast_retrans_count, tx->multicast_retrans_int);
57
58 bt_mesh_model_msg_init(&msg, OP_SAR_CFG_TX_STATUS);
59 bt_mesh_sar_tx_encode(&msg, tx);
60
61 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
62 LOG_ERR("Unable to send Transmitter Status");
63 }
64 }
65
receiver_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx)66 static void receiver_status(const struct bt_mesh_model *model,
67 struct bt_mesh_msg_ctx *ctx)
68 {
69 BT_MESH_MODEL_BUF_DEFINE(msg, OP_SAR_CFG_RX_STATUS, BT_MESH_SAR_RX_LEN);
70 const struct bt_mesh_sar_rx *rx = &bt_mesh.sar_rx;
71
72 LOG_DBG("SAR RX {0x%02x 0x%02x 0x%02x 0x%02x 0x%02x}", rx->seg_thresh,
73 rx->ack_delay_inc, rx->discard_timeout, rx->rx_seg_int_step,
74 rx->ack_retrans_count);
75
76 bt_mesh_model_msg_init(&msg, OP_SAR_CFG_RX_STATUS);
77 bt_mesh_sar_rx_encode(&msg, rx);
78
79 if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
80 LOG_ERR("Unable to send Receiver Status");
81 }
82 }
83
transmitter_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)84 static int transmitter_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
85 struct net_buf_simple *buf)
86 {
87 LOG_DBG("src 0x%04x", ctx->addr);
88
89 transmitter_status(model, ctx);
90
91 return 0;
92 }
93
transmitter_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)94 static int transmitter_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
95 struct net_buf_simple *buf)
96 {
97 struct bt_mesh_sar_tx *tx = &bt_mesh.sar_tx;
98
99 LOG_DBG("src 0x%04x", ctx->addr);
100
101 bt_mesh_sar_tx_decode(buf, tx);
102 transmitter_status(model, ctx);
103
104 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
105 sar_tx_store(model, false);
106 }
107
108 return 0;
109 }
110
receiver_get(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)111 static int receiver_get(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
112 struct net_buf_simple *buf)
113 {
114 LOG_DBG("src 0x%04x", ctx->addr);
115
116 receiver_status(model, ctx);
117
118 return 0;
119 }
120
receiver_set(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)121 static int receiver_set(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
122 struct net_buf_simple *buf)
123 {
124 struct bt_mesh_sar_rx *rx = &bt_mesh.sar_rx;
125
126 LOG_DBG("src 0x%04x", ctx->addr);
127
128 bt_mesh_sar_rx_decode(buf, rx);
129 receiver_status(model, ctx);
130
131 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
132 sar_rx_store(model, false);
133 }
134
135 return 0;
136 }
137
138 const struct bt_mesh_model_op bt_mesh_sar_cfg_srv_op[] = {
139 { OP_SAR_CFG_TX_GET, BT_MESH_LEN_EXACT(0), transmitter_get },
140 { OP_SAR_CFG_TX_SET, BT_MESH_LEN_EXACT(BT_MESH_SAR_TX_LEN), transmitter_set },
141 { OP_SAR_CFG_RX_GET, BT_MESH_LEN_EXACT(0), receiver_get },
142 { OP_SAR_CFG_RX_SET, BT_MESH_LEN_EXACT(BT_MESH_SAR_RX_LEN), receiver_set },
143 BT_MESH_MODEL_OP_END,
144 };
145
sar_cfg_srv_init(const struct bt_mesh_model * model)146 static int sar_cfg_srv_init(const struct bt_mesh_model *model)
147 {
148 if (!bt_mesh_model_in_primary(model)) {
149 LOG_ERR("Configuration Server only allowed in primary element");
150 return -EINVAL;
151 }
152
153 /*
154 * SAR Configuration Model security is device-key based and only the local
155 * device-key is allowed to access this model.
156 */
157 model->keys[0] = BT_MESH_KEY_DEV_LOCAL;
158 model->rt->flags |= BT_MESH_MOD_DEVKEY_ONLY;
159
160 return 0;
161 }
162
sar_cfg_srv_reset(const struct bt_mesh_model * model)163 static void sar_cfg_srv_reset(const struct bt_mesh_model *model)
164 {
165 struct bt_mesh_sar_tx sar_tx = BT_MESH_SAR_TX_INIT;
166 struct bt_mesh_sar_rx sar_rx = BT_MESH_SAR_RX_INIT;
167
168 bt_mesh.sar_tx = sar_tx;
169 bt_mesh.sar_rx = sar_rx;
170
171 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
172 sar_rx_store(model, true);
173 sar_tx_store(model, true);
174 }
175 }
176
177 #ifdef CONFIG_BT_SETTINGS
sar_cfg_srv_settings_set(const struct bt_mesh_model * model,const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_data)178 static int sar_cfg_srv_settings_set(const struct bt_mesh_model *model, const char *name,
179 size_t len_rd, settings_read_cb read_cb,
180 void *cb_data)
181 {
182 if (!strncmp(name, "sar_rx", 5)) {
183 return bt_mesh_settings_set(read_cb, cb_data, &bt_mesh.sar_rx,
184 sizeof(bt_mesh.sar_rx));
185 }
186
187 if (!strncmp(name, "sar_tx", 5)) {
188 return bt_mesh_settings_set(read_cb, cb_data, &bt_mesh.sar_tx,
189 sizeof(bt_mesh.sar_tx));
190 }
191
192 return 0;
193 }
194 #endif
195
196 const struct bt_mesh_model_cb bt_mesh_sar_cfg_srv_cb = {
197 .init = sar_cfg_srv_init,
198 .reset = sar_cfg_srv_reset,
199 #ifdef CONFIG_BT_SETTINGS
200 .settings_set = sar_cfg_srv_settings_set
201 #endif
202 };
203