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