1 /*
2  * Copyright (c) 2021 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/bluetooth/mesh.h>
8 #include <zephyr/bluetooth/mesh/access.h>
9 
10 #include <common/bt_str.h>
11 
12 #include "net.h"
13 #include "access.h"
14 #include "foundation.h"
15 #include "mesh.h"
16 #include "sar_cfg_internal.h"
17 
18 #define LOG_LEVEL CONFIG_BT_MESH_MODEL_LOG_LEVEL
19 #include <zephyr/logging/log.h>
20 LOG_MODULE_REGISTER(bt_mesh_sar_cfg_cli);
21 
22 static struct bt_mesh_sar_cfg_cli *cli;
23 
transmitter_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)24 static int transmitter_status(const struct bt_mesh_model *model,
25 			       struct bt_mesh_msg_ctx *ctx,
26 			       struct net_buf_simple *buf)
27 {
28 	struct bt_mesh_sar_tx *rsp;
29 
30 	if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_SAR_CFG_TX_STATUS,
31 				       ctx->addr, (void **)&rsp)) {
32 		return 0;
33 	}
34 
35 	bt_mesh_sar_tx_decode(buf, rsp);
36 
37 	LOG_DBG("SAR TX {0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x}",
38 		rsp->seg_int_step, rsp->unicast_retrans_count,
39 		rsp->unicast_retrans_without_prog_count,
40 		rsp->unicast_retrans_int_step, rsp->unicast_retrans_int_inc,
41 		rsp->multicast_retrans_count, rsp->multicast_retrans_int);
42 
43 	bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
44 
45 	return 0;
46 }
47 
receiver_status(const struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)48 static int receiver_status(const struct bt_mesh_model *model,
49 			    struct bt_mesh_msg_ctx *ctx,
50 			    struct net_buf_simple *buf)
51 {
52 	struct bt_mesh_sar_rx *rsp;
53 
54 	LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
55 		ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
56 		bt_hex(buf->data, buf->len));
57 
58 	if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_SAR_CFG_RX_STATUS,
59 				       ctx->addr, (void **)&rsp)) {
60 		return 0;
61 	}
62 
63 	bt_mesh_sar_rx_decode(buf, rsp);
64 
65 	LOG_DBG("SAR RX {0x%02x 0x%02x 0x%02x 0x%02x 0x%02x}", rsp->seg_thresh,
66 		rsp->ack_delay_inc, rsp->discard_timeout, rsp->rx_seg_int_step,
67 		rsp->ack_retrans_count);
68 
69 	bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
70 
71 	return 0;
72 }
73 
74 const struct bt_mesh_model_op _bt_mesh_sar_cfg_cli_op[] = {
75 	{ OP_SAR_CFG_TX_STATUS, BT_MESH_LEN_EXACT(BT_MESH_SAR_TX_LEN), transmitter_status },
76 	{ OP_SAR_CFG_RX_STATUS, BT_MESH_LEN_EXACT(BT_MESH_SAR_RX_LEN), receiver_status },
77 	BT_MESH_MODEL_OP_END,
78 };
79 
bt_mesh_sar_cfg_cli_timeout_get(void)80 int32_t bt_mesh_sar_cfg_cli_timeout_get(void)
81 {
82 	return cli->timeout;
83 }
84 
bt_mesh_sar_cfg_cli_timeout_set(int32_t timeout)85 void bt_mesh_sar_cfg_cli_timeout_set(int32_t timeout)
86 {
87 	cli->timeout = timeout;
88 }
89 
bt_mesh_sar_cfg_cli_init(const struct bt_mesh_model * model)90 static int bt_mesh_sar_cfg_cli_init(const struct bt_mesh_model *model)
91 {
92 	if (!bt_mesh_model_in_primary(model)) {
93 		LOG_ERR("SAR Configuration Client only allowed in primary element");
94 		return -EINVAL;
95 	}
96 
97 	if (!model->rt->user_data) {
98 		LOG_ERR("No SAR Configuration Client context provided");
99 		return -EINVAL;
100 	}
101 
102 	cli = model->rt->user_data;
103 	cli->model = model;
104 	cli->timeout = 2 * MSEC_PER_SEC;
105 
106 	model->keys[0] = BT_MESH_KEY_DEV_ANY;
107 	model->rt->flags |= BT_MESH_MOD_DEVKEY_ONLY;
108 
109 	bt_mesh_msg_ack_ctx_init(&cli->ack_ctx);
110 
111 	return 0;
112 }
113 
bt_mesh_sar_cfg_cli_reset(const struct bt_mesh_model * model)114 static void bt_mesh_sar_cfg_cli_reset(const struct bt_mesh_model *model)
115 {
116 	struct bt_mesh_sar_cfg_cli *model_cli;
117 
118 	model_cli = model->rt->user_data;
119 
120 	bt_mesh_msg_ack_ctx_clear(&model_cli->ack_ctx);
121 }
122 
123 const struct bt_mesh_model_cb _bt_mesh_sar_cfg_cli_cb = {
124 	.init = bt_mesh_sar_cfg_cli_init,
125 	.reset = bt_mesh_sar_cfg_cli_reset,
126 };
127 
bt_mesh_sar_cfg_cli_transmitter_get(uint16_t net_idx,uint16_t addr,struct bt_mesh_sar_tx * rsp)128 int bt_mesh_sar_cfg_cli_transmitter_get(uint16_t net_idx, uint16_t addr,
129 					struct bt_mesh_sar_tx *rsp)
130 {
131 	BT_MESH_MODEL_BUF_DEFINE(msg, OP_SAR_CFG_TX_GET, 0);
132 	struct bt_mesh_msg_ctx ctx = {
133 		.net_idx = net_idx,
134 		.app_idx = BT_MESH_KEY_DEV,
135 		.addr = addr,
136 		.send_ttl = BT_MESH_TTL_DEFAULT,
137 	};
138 	int err;
139 
140 	err = bt_mesh_msg_ack_ctx_prepare(&cli->ack_ctx, OP_SAR_CFG_TX_STATUS, addr, rsp);
141 	if (err) {
142 		return err;
143 	}
144 
145 	bt_mesh_model_msg_init(&msg, OP_SAR_CFG_TX_GET);
146 
147 	err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
148 	if (err) {
149 		LOG_ERR("model_send() failed (err %d)", err);
150 		bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx);
151 		return err;
152 	}
153 
154 	return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(cli->timeout));
155 }
156 
bt_mesh_sar_cfg_cli_transmitter_set(uint16_t net_idx,uint16_t addr,const struct bt_mesh_sar_tx * set,struct bt_mesh_sar_tx * rsp)157 int bt_mesh_sar_cfg_cli_transmitter_set(uint16_t net_idx, uint16_t addr,
158 					const struct bt_mesh_sar_tx *set,
159 					struct bt_mesh_sar_tx *rsp)
160 {
161 	BT_MESH_MODEL_BUF_DEFINE(msg, OP_SAR_CFG_TX_SET, BT_MESH_SAR_TX_LEN);
162 	struct bt_mesh_msg_ctx ctx = {
163 		.net_idx = net_idx,
164 		.app_idx = BT_MESH_KEY_DEV,
165 		.addr = addr,
166 		.send_ttl = BT_MESH_TTL_DEFAULT,
167 	};
168 	int err;
169 
170 	err = bt_mesh_msg_ack_ctx_prepare(&cli->ack_ctx, OP_SAR_CFG_TX_STATUS, addr, rsp);
171 	if (err) {
172 		return err;
173 	}
174 
175 	bt_mesh_model_msg_init(&msg, OP_SAR_CFG_TX_SET);
176 	bt_mesh_sar_tx_encode(&msg, set);
177 
178 	err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
179 	if (err) {
180 		LOG_ERR("model_send() failed (err %d)", err);
181 		bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx);
182 		return err;
183 	}
184 
185 	return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(cli->timeout));
186 }
187 
bt_mesh_sar_cfg_cli_receiver_get(uint16_t net_idx,uint16_t addr,struct bt_mesh_sar_rx * rsp)188 int bt_mesh_sar_cfg_cli_receiver_get(uint16_t net_idx, uint16_t addr,
189 				     struct bt_mesh_sar_rx *rsp)
190 {
191 	BT_MESH_MODEL_BUF_DEFINE(msg, OP_SAR_CFG_RX_GET, 0);
192 	struct bt_mesh_msg_ctx ctx = {
193 		.net_idx = net_idx,
194 		.app_idx = BT_MESH_KEY_DEV,
195 		.addr = addr,
196 		.send_ttl = BT_MESH_TTL_DEFAULT,
197 	};
198 	int err;
199 
200 	err = bt_mesh_msg_ack_ctx_prepare(&cli->ack_ctx, OP_SAR_CFG_RX_STATUS, addr, rsp);
201 	if (err) {
202 		return err;
203 	}
204 
205 	bt_mesh_model_msg_init(&msg, OP_SAR_CFG_RX_GET);
206 
207 	err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
208 	if (err) {
209 		LOG_ERR("model_send() failed (err %d)", err);
210 		bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx);
211 		return err;
212 	}
213 
214 	return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(cli->timeout));
215 }
216 
bt_mesh_sar_cfg_cli_receiver_set(uint16_t net_idx,uint16_t addr,const struct bt_mesh_sar_rx * set,struct bt_mesh_sar_rx * rsp)217 int bt_mesh_sar_cfg_cli_receiver_set(uint16_t net_idx, uint16_t addr,
218 				     const struct bt_mesh_sar_rx *set,
219 				     struct bt_mesh_sar_rx *rsp)
220 {
221 	BT_MESH_MODEL_BUF_DEFINE(msg, OP_SAR_CFG_RX_SET, BT_MESH_SAR_RX_LEN);
222 	struct bt_mesh_msg_ctx ctx = {
223 		.net_idx = net_idx,
224 		.app_idx = BT_MESH_KEY_DEV,
225 		.addr = addr,
226 		.send_ttl = BT_MESH_TTL_DEFAULT,
227 	};
228 	int err;
229 
230 	err = bt_mesh_msg_ack_ctx_prepare(&cli->ack_ctx, OP_SAR_CFG_RX_STATUS, addr, rsp);
231 	if (err) {
232 		return err;
233 	}
234 
235 	bt_mesh_model_msg_init(&msg, OP_SAR_CFG_RX_SET);
236 	bt_mesh_sar_rx_encode(&msg, set);
237 
238 	err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
239 	if (err) {
240 		LOG_ERR("model_send() failed (err %d)", err);
241 		bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx);
242 		return err;
243 	}
244 
245 	return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(cli->timeout));
246 }
247