1 /*  Bluetooth Mesh */
2 
3 /*
4  * Copyright (c) 2017 Intel Corporation
5  * Copyright (c) 2021 Lingao Meng
6  *
7  * SPDX-License-Identifier: Apache-2.0
8  */
9 
10 #include <zephyr/kernel.h>
11 #include <zephyr/sys/byteorder.h>
12 
13 #include <zephyr/net_buf.h>
14 #include <zephyr/bluetooth/bluetooth.h>
15 #include <zephyr/bluetooth/conn.h>
16 #include <zephyr/bluetooth/gatt.h>
17 #include <zephyr/bluetooth/mesh.h>
18 
19 #include <zephyr/bluetooth/hci.h>
20 
21 #include "common/bt_str.h"
22 
23 #include "mesh.h"
24 #include "net.h"
25 #include "rpl.h"
26 #include "transport.h"
27 #include "prov.h"
28 #include "beacon.h"
29 #include "foundation.h"
30 #include "access.h"
31 #include "proxy.h"
32 #include "proxy_msg.h"
33 
34 #define LOG_LEVEL CONFIG_BT_MESH_PROXY_LOG_LEVEL
35 #include <zephyr/logging/log.h>
36 LOG_MODULE_REGISTER(bt_mesh_proxy);
37 
38 #define PDU_SAR(data)      (data[0] >> 6)
39 
40 /* MshPRTv1.1: 6.3.2.2:
41  * "The timeout for the SAR transfer is 20 seconds. When the timeout
42  *  expires, the Proxy Server shall disconnect."
43  */
44 #define PROXY_SAR_TIMEOUT  K_SECONDS(20)
45 
46 #define SAR_COMPLETE       0x00
47 #define SAR_FIRST          0x01
48 #define SAR_CONT           0x02
49 #define SAR_LAST           0x03
50 
51 #define PDU_HDR(sar, type) (sar << 6 | (type & BIT_MASK(6)))
52 
53 static uint8_t __noinit bufs[CONFIG_BT_MAX_CONN * CONFIG_BT_MESH_PROXY_MSG_LEN];
54 
55 static struct bt_mesh_proxy_role roles[CONFIG_BT_MAX_CONN];
56 
57 static int conn_count;
58 
proxy_sar_timeout(struct k_work * work)59 static void proxy_sar_timeout(struct k_work *work)
60 {
61 	struct bt_mesh_proxy_role *role;
62 	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
63 
64 	LOG_WRN("Proxy SAR timeout");
65 
66 	role = CONTAINER_OF(dwork, struct bt_mesh_proxy_role, sar_timer);
67 
68 	while (!k_fifo_is_empty(&role->pending)) {
69 		struct bt_mesh_adv *adv = k_fifo_get(&role->pending, K_NO_WAIT);
70 
71 		__ASSERT_NO_MSG(adv);
72 
73 		bt_mesh_adv_unref(adv);
74 	}
75 
76 	if (role->conn) {
77 		bt_conn_disconnect(role->conn,
78 				   BT_HCI_ERR_REMOTE_USER_TERM_CONN);
79 	}
80 }
81 
bt_mesh_proxy_msg_recv(struct bt_conn * conn,const void * buf,uint16_t len)82 ssize_t bt_mesh_proxy_msg_recv(struct bt_conn *conn,
83 			       const void *buf, uint16_t len)
84 {
85 	const uint8_t *data = buf;
86 	struct bt_mesh_proxy_role *role = &roles[bt_conn_index(conn)];
87 
88 	if (net_buf_simple_tailroom(&role->buf) < len - 1) {
89 		LOG_WRN("Proxy role buffer overflow");
90 		return -EINVAL;
91 	}
92 
93 	switch (PDU_SAR(data)) {
94 	case SAR_COMPLETE:
95 		if (role->buf.len) {
96 			LOG_WRN("Complete PDU while a pending incomplete one");
97 			return -EINVAL;
98 		}
99 
100 		role->msg_type = PDU_TYPE(data);
101 		net_buf_simple_add_mem(&role->buf, data + 1, len - 1);
102 		role->cb.recv(role);
103 		net_buf_simple_reset(&role->buf);
104 		break;
105 
106 	case SAR_FIRST:
107 		if (role->buf.len) {
108 			LOG_WRN("First PDU while a pending incomplete one");
109 			return -EINVAL;
110 		}
111 
112 		k_work_reschedule(&role->sar_timer, PROXY_SAR_TIMEOUT);
113 		role->msg_type = PDU_TYPE(data);
114 		net_buf_simple_add_mem(&role->buf, data + 1, len - 1);
115 		break;
116 
117 	case SAR_CONT:
118 		if (!role->buf.len) {
119 			LOG_WRN("Continuation with no prior data");
120 			return -EINVAL;
121 		}
122 
123 		if (role->msg_type != PDU_TYPE(data)) {
124 			LOG_WRN("Unexpected message type in continuation");
125 			return -EINVAL;
126 		}
127 
128 		k_work_reschedule(&role->sar_timer, PROXY_SAR_TIMEOUT);
129 		net_buf_simple_add_mem(&role->buf, data + 1, len - 1);
130 		break;
131 
132 	case SAR_LAST:
133 		if (!role->buf.len) {
134 			LOG_WRN("Last SAR PDU with no prior data");
135 			return -EINVAL;
136 		}
137 
138 		if (role->msg_type != PDU_TYPE(data)) {
139 			LOG_WRN("Unexpected message type in last SAR PDU");
140 			return -EINVAL;
141 		}
142 
143 		/* If this fails, the work handler exits early, as there's no
144 		 * active SAR buffer.
145 		 */
146 		(void)k_work_cancel_delayable(&role->sar_timer);
147 		net_buf_simple_add_mem(&role->buf, data + 1, len - 1);
148 		role->cb.recv(role);
149 		net_buf_simple_reset(&role->buf);
150 		break;
151 	}
152 
153 	return len;
154 }
155 
bt_mesh_proxy_msg_send(struct bt_conn * conn,uint8_t type,struct net_buf_simple * msg,bt_gatt_complete_func_t end,void * user_data)156 int bt_mesh_proxy_msg_send(struct bt_conn *conn, uint8_t type,
157 			   struct net_buf_simple *msg,
158 			   bt_gatt_complete_func_t end, void *user_data)
159 {
160 	int err;
161 	uint16_t mtu;
162 	struct bt_mesh_proxy_role *role = &roles[bt_conn_index(conn)];
163 
164 	LOG_DBG("conn %p type 0x%02x len %u: %s", (void *)conn, type, msg->len,
165 		bt_hex(msg->data, msg->len));
166 
167 	/* ATT_MTU - OpCode (1 byte) - Handle (2 bytes) */
168 	mtu = bt_gatt_get_mtu(conn) - 3;
169 	if (mtu > msg->len) {
170 		net_buf_simple_push_u8(msg, PDU_HDR(SAR_COMPLETE, type));
171 		return role->cb.send(conn, msg->data, msg->len, end, user_data);
172 	}
173 
174 	net_buf_simple_push_u8(msg, PDU_HDR(SAR_FIRST, type));
175 	err = role->cb.send(conn, msg->data, mtu, NULL, NULL);
176 	if (err) {
177 		return err;
178 	}
179 
180 	net_buf_simple_pull(msg, mtu);
181 
182 	while (msg->len) {
183 		if (msg->len + 1 <= mtu) {
184 			net_buf_simple_push_u8(msg, PDU_HDR(SAR_LAST, type));
185 			err = role->cb.send(conn, msg->data, msg->len, end, user_data);
186 			if (err) {
187 				return err;
188 			}
189 
190 			break;
191 		}
192 
193 		net_buf_simple_push_u8(msg, PDU_HDR(SAR_CONT, type));
194 		err = role->cb.send(conn, msg->data, mtu, NULL, NULL);
195 		if (err) {
196 			return err;
197 		}
198 
199 		net_buf_simple_pull(msg, mtu);
200 	}
201 
202 	return 0;
203 }
204 
buf_send_end(struct bt_conn * conn,void * user_data)205 static void buf_send_end(struct bt_conn *conn, void *user_data)
206 {
207 	struct bt_mesh_adv *adv = user_data;
208 
209 	bt_mesh_adv_unref(adv);
210 }
211 
proxy_relay_send(struct bt_conn * conn,struct bt_mesh_adv * adv)212 static int proxy_relay_send(struct bt_conn *conn, struct bt_mesh_adv *adv)
213 {
214 	int err;
215 
216 	NET_BUF_SIMPLE_DEFINE(msg, 1 + BT_MESH_NET_MAX_PDU_LEN);
217 
218 	/* Proxy PDU sending modifies the original buffer,
219 	 * so we need to make a copy.
220 	 */
221 	net_buf_simple_reserve(&msg, 1);
222 	net_buf_simple_add_mem(&msg, adv->b.data, adv->b.len);
223 
224 	err = bt_mesh_proxy_msg_send(conn, BT_MESH_PROXY_NET_PDU,
225 				     &msg, buf_send_end, bt_mesh_adv_ref(adv));
226 
227 	bt_mesh_adv_send_start(0, err, &adv->ctx);
228 	if (err) {
229 		LOG_ERR("Failed to send proxy message (err %d)", err);
230 
231 		/* If segment_and_send() fails the buf_send_end() callback will
232 		 * not be called, so we need to clear the user data (net_buf,
233 		 * which is just opaque data to segment_and send) reference given
234 		 * to segment_and_send() here.
235 		 */
236 		bt_mesh_adv_unref(adv);
237 	}
238 
239 	return err;
240 }
241 
bt_mesh_proxy_relay_send(struct bt_conn * conn,struct bt_mesh_adv * adv)242 int bt_mesh_proxy_relay_send(struct bt_conn *conn, struct bt_mesh_adv *adv)
243 {
244 	struct bt_mesh_proxy_role *role = &roles[bt_conn_index(conn)];
245 
246 	k_fifo_put(&role->pending, bt_mesh_adv_ref(adv));
247 
248 	bt_mesh_wq_submit(&role->work);
249 
250 	return 0;
251 }
252 
proxy_msg_send_pending(struct k_work * work)253 static void proxy_msg_send_pending(struct k_work *work)
254 {
255 	struct bt_mesh_proxy_role *role = CONTAINER_OF(work, struct bt_mesh_proxy_role, work);
256 	struct bt_mesh_adv *adv;
257 
258 	if (!role->conn) {
259 		return;
260 	}
261 
262 	adv = k_fifo_get(&role->pending, K_NO_WAIT);
263 	if (!adv) {
264 		return;
265 	}
266 
267 	(void)proxy_relay_send(role->conn, adv);
268 	bt_mesh_adv_unref(adv);
269 
270 	if (!k_fifo_is_empty(&role->pending)) {
271 		bt_mesh_wq_submit(&role->work);
272 	}
273 }
274 
proxy_msg_init(struct bt_mesh_proxy_role * role)275 static void proxy_msg_init(struct bt_mesh_proxy_role *role)
276 {
277 	/* Check if buf has been allocated, in this way, we no longer need
278 	 * to repeat the operation.
279 	 */
280 	if (role->buf.__buf) {
281 		net_buf_simple_reset(&role->buf);
282 		return;
283 	}
284 
285 	net_buf_simple_init_with_data(&role->buf,
286 				      &bufs[bt_conn_index(role->conn) *
287 					    CONFIG_BT_MESH_PROXY_MSG_LEN],
288 				      CONFIG_BT_MESH_PROXY_MSG_LEN);
289 
290 	net_buf_simple_reset(&role->buf);
291 
292 	k_fifo_init(&role->pending);
293 	k_work_init(&role->work, proxy_msg_send_pending);
294 
295 	k_work_init_delayable(&role->sar_timer, proxy_sar_timeout);
296 }
297 
bt_mesh_proxy_role_setup(struct bt_conn * conn,proxy_send_cb_t send,proxy_recv_cb_t recv)298 struct bt_mesh_proxy_role *bt_mesh_proxy_role_setup(struct bt_conn *conn,
299 						    proxy_send_cb_t send,
300 						    proxy_recv_cb_t recv)
301 {
302 	struct bt_mesh_proxy_role *role;
303 
304 	conn_count++;
305 
306 	role = &roles[bt_conn_index(conn)];
307 
308 	role->conn = bt_conn_ref(conn);
309 	proxy_msg_init(role);
310 
311 	role->cb.recv = recv;
312 	role->cb.send = send;
313 
314 	return role;
315 }
316 
bt_mesh_proxy_role_cleanup(struct bt_mesh_proxy_role * role)317 void bt_mesh_proxy_role_cleanup(struct bt_mesh_proxy_role *role)
318 {
319 	/* If this fails, the work handler exits early, as
320 	 * there's no active connection.
321 	 */
322 	(void)k_work_cancel_delayable(&role->sar_timer);
323 	bt_conn_unref(role->conn);
324 	role->conn = NULL;
325 
326 	conn_count--;
327 
328 	bt_mesh_adv_gatt_update();
329 }
330 
bt_mesh_proxy_has_avail_conn(void)331 bool bt_mesh_proxy_has_avail_conn(void)
332 {
333 	return conn_count < CONFIG_BT_MESH_MAX_CONN;
334 }
335