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