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 = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
133 	int err;
134 
135 	err = bt_mesh_msg_ack_ctx_prepare(&cli->ack_ctx, OP_SAR_CFG_TX_STATUS, addr, rsp);
136 	if (err) {
137 		return err;
138 	}
139 
140 	bt_mesh_model_msg_init(&msg, OP_SAR_CFG_TX_GET);
141 
142 	err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
143 	if (err) {
144 		LOG_ERR("model_send() failed (err %d)", err);
145 		bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx);
146 		return err;
147 	}
148 
149 	return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(cli->timeout));
150 }
151 
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)152 int bt_mesh_sar_cfg_cli_transmitter_set(uint16_t net_idx, uint16_t addr,
153 					const struct bt_mesh_sar_tx *set,
154 					struct bt_mesh_sar_tx *rsp)
155 {
156 	BT_MESH_MODEL_BUF_DEFINE(msg, OP_SAR_CFG_TX_SET, BT_MESH_SAR_TX_LEN);
157 	struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
158 	int err;
159 
160 	err = bt_mesh_msg_ack_ctx_prepare(&cli->ack_ctx, OP_SAR_CFG_TX_STATUS, addr, rsp);
161 	if (err) {
162 		return err;
163 	}
164 
165 	bt_mesh_model_msg_init(&msg, OP_SAR_CFG_TX_SET);
166 	bt_mesh_sar_tx_encode(&msg, set);
167 
168 	err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
169 	if (err) {
170 		LOG_ERR("model_send() failed (err %d)", err);
171 		bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx);
172 		return err;
173 	}
174 
175 	return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(cli->timeout));
176 }
177 
bt_mesh_sar_cfg_cli_receiver_get(uint16_t net_idx,uint16_t addr,struct bt_mesh_sar_rx * rsp)178 int bt_mesh_sar_cfg_cli_receiver_get(uint16_t net_idx, uint16_t addr,
179 				     struct bt_mesh_sar_rx *rsp)
180 {
181 	BT_MESH_MODEL_BUF_DEFINE(msg, OP_SAR_CFG_RX_GET, 0);
182 	struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
183 	int err;
184 
185 	err = bt_mesh_msg_ack_ctx_prepare(&cli->ack_ctx, OP_SAR_CFG_RX_STATUS, addr, rsp);
186 	if (err) {
187 		return err;
188 	}
189 
190 	bt_mesh_model_msg_init(&msg, OP_SAR_CFG_RX_GET);
191 
192 	err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
193 	if (err) {
194 		LOG_ERR("model_send() failed (err %d)", err);
195 		bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx);
196 		return err;
197 	}
198 
199 	return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(cli->timeout));
200 }
201 
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)202 int bt_mesh_sar_cfg_cli_receiver_set(uint16_t net_idx, uint16_t addr,
203 				     const struct bt_mesh_sar_rx *set,
204 				     struct bt_mesh_sar_rx *rsp)
205 {
206 	BT_MESH_MODEL_BUF_DEFINE(msg, OP_SAR_CFG_RX_SET, BT_MESH_SAR_RX_LEN);
207 	struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr);
208 	int err;
209 
210 	err = bt_mesh_msg_ack_ctx_prepare(&cli->ack_ctx, OP_SAR_CFG_RX_STATUS, addr, rsp);
211 	if (err) {
212 		return err;
213 	}
214 
215 	bt_mesh_model_msg_init(&msg, OP_SAR_CFG_RX_SET);
216 	bt_mesh_sar_rx_encode(&msg, set);
217 
218 	err = bt_mesh_model_send(cli->model, &ctx, &msg, NULL, NULL);
219 	if (err) {
220 		LOG_ERR("model_send() failed (err %d)", err);
221 		bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx);
222 		return err;
223 	}
224 
225 	return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(cli->timeout));
226 }
227