1 /*  Bluetooth Mesh */
2 
3 /*
4  * SPDX-FileCopyrightText: 2017 Intel Corporation
5  * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
6  *
7  * SPDX-License-Identifier: Apache-2.0
8  */
9 
10 #include <stdint.h>
11 #include <string.h>
12 #include <errno.h>
13 
14 #include "mesh_kernel.h"
15 #include "mesh.h"
16 #include "mesh_hci.h"
17 #include "mesh_common.h"
18 #include "adv.h"
19 #include "beacon.h"
20 #include "prov.h"
21 #include "foundation.h"
22 #include "proxy_server.h"
23 #include "proxy_client.h"
24 #include "provisioner_prov.h"
25 #include "mesh_bearer_adapt.h"
26 
27 /* Convert from ms to 0.625ms units */
28 #define ADV_SCAN_UNIT(_ms)  ((_ms) * 8 / 5)
29 /* Convert from 0.625ms units to interval(ms) */
30 #define ADV_SCAN_INT(val)   ((val) * 5 / 8)
31 
32 /* Pre-5.0 controllers enforce a minimum interval of 100ms
33  * whereas 5.0+ controllers can go down to 20ms.
34  */
35 #define ADV_INT_DEFAULT_MS  100
36 #define ADV_INT_FAST_MS     20
37 
38 static const uint8_t adv_type[] = {
39     [BLE_MESH_ADV_PROV]   = BLE_MESH_DATA_MESH_PROV,
40     [BLE_MESH_ADV_DATA]   = BLE_MESH_DATA_MESH_MESSAGE,
41     [BLE_MESH_ADV_BEACON] = BLE_MESH_DATA_MESH_BEACON,
42     [BLE_MESH_ADV_URI]    = BLE_MESH_DATA_URI,
43 };
44 
45 NET_BUF_POOL_DEFINE(adv_buf_pool, CONFIG_BLE_MESH_ADV_BUF_COUNT,
46                     BLE_MESH_ADV_DATA_SIZE, BLE_MESH_ADV_USER_DATA_SIZE, NULL);
47 
48 static struct bt_mesh_adv adv_pool[CONFIG_BLE_MESH_ADV_BUF_COUNT];
49 
50 struct bt_mesh_queue {
51     QueueHandle_t handle;
52 #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
53     StaticQueue_t *buffer;
54     uint8_t *storage;
55 #endif
56 };
57 
58 static struct bt_mesh_queue adv_queue;
59 /* We reserve one queue item for bt_mesh_adv_update() */
60 #if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
61 #define BLE_MESH_ADV_QUEUE_SIZE     (CONFIG_BLE_MESH_ADV_BUF_COUNT + CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT + 1)
62 #else
63 #define BLE_MESH_ADV_QUEUE_SIZE     (CONFIG_BLE_MESH_ADV_BUF_COUNT + 1)
64 #endif
65 
66 #if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
67 NET_BUF_POOL_DEFINE(relay_adv_buf_pool, CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT,
68                     BLE_MESH_ADV_DATA_SIZE, BLE_MESH_ADV_USER_DATA_SIZE, NULL);
69 
70 static struct bt_mesh_adv relay_adv_pool[CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT];
71 
72 static struct bt_mesh_queue relay_queue;
73 #define BLE_MESH_RELAY_QUEUE_SIZE   CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT
74 
75 static QueueSetHandle_t mesh_queue_set;
76 #define BLE_MESH_QUEUE_SET_SIZE     (BLE_MESH_ADV_QUEUE_SIZE + BLE_MESH_RELAY_QUEUE_SIZE)
77 
78 #define BLE_MESH_RELAY_TIME_INTERVAL     K_SECONDS(6)
79 #define BLE_MESH_MAX_TIME_INTERVAL       0xFFFFFFFF
80 
81 static bool ignore_relay_packet(uint32_t timestamp);
82 #endif /* defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */
83 
84 #if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
85 /* length + advertising data + length + scan response data */
86 NET_BUF_POOL_DEFINE(ble_adv_buf_pool, CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT,
87                     ((BLE_MESH_ADV_DATA_SIZE + 3) << 1), BLE_MESH_ADV_USER_DATA_SIZE, NULL);
88 
89 static struct bt_mesh_adv ble_adv_pool[CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT];
90 
91 enum {
92     TIMER_INIT,  /* Resend timer is initialized */
93     NUM_FLAGS,
94 };
95 
96 static struct ble_adv_tx {
97     struct bt_mesh_ble_adv_param param;
98     struct net_buf              *buf;
99     struct k_delayed_work        resend;
100     BLE_MESH_ATOMIC_DEFINE(flags, NUM_FLAGS);
101 } ble_adv_tx[CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT];
102 
103 #define SEND_BLE_ADV_INFINITE    0xFFFF
104 
105 #if CONFIG_BLE_MESH_DEINIT
106 static void bt_mesh_ble_adv_deinit(void);
107 #endif /* CONFIG_BLE_MESH_DEINIT */
108 #endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
109 
110 struct bt_mesh_adv_task {
111     TaskHandle_t handle;
112 #if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \
113      (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && \
114      CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY)
115     StaticTask_t *task;
116     StackType_t *stack;
117 #endif
118 };
119 
120 static struct bt_mesh_adv_task adv_task;
121 
adv_alloc(int id)122 static struct bt_mesh_adv *adv_alloc(int id)
123 {
124     return &adv_pool[id];
125 }
126 
adv_send_start(uint16_t duration,int err,const struct bt_mesh_send_cb * cb,void * cb_data)127 static inline void adv_send_start(uint16_t duration, int err,
128                                   const struct bt_mesh_send_cb *cb,
129                                   void *cb_data)
130 {
131     if (cb && cb->start) {
132         cb->start(duration, err, cb_data);
133     }
134 }
135 
adv_send_end(int err,const struct bt_mesh_send_cb * cb,void * cb_data)136 static inline void adv_send_end(int err, const struct bt_mesh_send_cb *cb,
137                                 void *cb_data)
138 {
139     if (cb && cb->end) {
140         cb->end(err, cb_data);
141     }
142 }
143 
adv_send(struct net_buf * buf)144 static inline int adv_send(struct net_buf *buf)
145 {
146     const int32_t adv_int_min = ((bt_mesh_dev.hci_version >= BLE_MESH_HCI_VERSION_5_0) ?
147                                   ADV_INT_FAST_MS : ADV_INT_DEFAULT_MS);
148     const struct bt_mesh_send_cb *cb = BLE_MESH_ADV(buf)->cb;
149     void *cb_data = BLE_MESH_ADV(buf)->cb_data;
150     struct bt_mesh_adv_param param = {0};
151     uint16_t duration = 0U, adv_int = 0U;
152     struct bt_mesh_adv_data ad = {0};
153     int err = 0;
154 
155     BT_DBG("type %u len %u: %s", BLE_MESH_ADV(buf)->type,
156         buf->len, bt_hex(buf->data, buf->len));
157 
158 #if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
159     if (BLE_MESH_ADV(buf)->type != BLE_MESH_ADV_BLE) {
160 #endif
161         adv_int = MAX(adv_int_min,
162                       BLE_MESH_TRANSMIT_INT(BLE_MESH_ADV(buf)->xmit));
163         duration = (BLE_MESH_TRANSMIT_COUNT(BLE_MESH_ADV(buf)->xmit) + 1) *
164                    (adv_int + 10);
165 
166         BT_DBG("count %u interval %ums duration %ums",
167                BLE_MESH_TRANSMIT_COUNT(BLE_MESH_ADV(buf)->xmit) + 1, adv_int,
168                duration);
169 
170         ad.type = adv_type[BLE_MESH_ADV(buf)->type];
171         ad.data_len = buf->len;
172         ad.data = buf->data;
173 
174         param.options = 0U;
175         param.interval_min = ADV_SCAN_UNIT(adv_int);
176         param.interval_max = param.interval_min;
177 
178         bt_mesh_adv_buf_ref_debug(__func__, buf, 4U, BLE_MESH_BUF_REF_SMALL);
179 
180         err = bt_le_adv_start(&param, &ad, 1, NULL, 0);
181 #if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
182     } else {
183         struct bt_mesh_ble_adv_data data = {0};
184         struct ble_adv_tx *tx = cb_data;
185 
186         if (tx == NULL) {
187             BT_ERR("Invalid adv user data");
188             net_buf_unref(buf);
189             return -EINVAL;
190         }
191 
192         BT_DBG("interval %dms, duration %dms, period %dms, count %d",
193             ADV_SCAN_INT(tx->param.interval), tx->param.duration,
194             tx->param.period, tx->param.count);
195 
196         data.adv_data_len = tx->buf->data[0];
197         if (data.adv_data_len) {
198             memcpy(data.adv_data, tx->buf->data + 1, data.adv_data_len);
199         }
200         data.scan_rsp_data_len = tx->buf->data[data.adv_data_len + 1];
201         if (data.scan_rsp_data_len) {
202             memcpy(data.scan_rsp_data, tx->buf->data + data.adv_data_len + 2, data.scan_rsp_data_len);
203         }
204         duration = tx->param.duration;
205 
206         bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
207 
208         err = bt_mesh_ble_adv_start(&tx->param, &data);
209     }
210 #endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
211 
212     net_buf_unref(buf);
213     adv_send_start(duration, err, cb, cb_data);
214     if (err) {
215         BT_ERR("Start advertising failed: err %d", err);
216         return err;
217     }
218 
219     BT_DBG("Advertising started. Sleeping %u ms", duration);
220 
221     k_sleep(K_MSEC(duration));
222 
223     err = bt_le_adv_stop();
224     adv_send_end(err, cb, cb_data);
225     if (err) {
226         BT_ERR("Stop advertising failed: err %d", err);
227         return 0;
228     }
229 
230     BT_DBG("Advertising stopped");
231     return 0;
232 }
233 
K_WAIT(int32_t val)234 static inline TickType_t K_WAIT(int32_t val)
235 {
236     return (val == K_FOREVER) ? portMAX_DELAY : (val / portTICK_PERIOD_MS);
237 }
238 
adv_thread(void * p)239 static void adv_thread(void *p)
240 {
241 #if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
242     QueueSetMemberHandle_t handle = NULL;
243 #endif
244     bt_mesh_msg_t msg = {0};
245     struct net_buf **buf = NULL;
246 
247     buf = (struct net_buf **)(&msg.arg);
248 
249     BT_DBG("%s, starts", __func__);
250 
251     while (1) {
252         *buf = NULL;
253 #if !defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
254 #if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
255     CONFIG_BLE_MESH_GATT_PROXY_SERVER
256         xQueueReceive(adv_queue.handle, &msg, K_NO_WAIT);
257         while (!(*buf)) {
258             int32_t timeout = 0;
259             BT_DBG("Mesh Proxy Advertising start");
260             timeout = bt_mesh_proxy_server_adv_start();
261             BT_DBG("Mesh Proxy Advertising up to %d ms", timeout);
262             xQueueReceive(adv_queue.handle, &msg, K_WAIT(timeout));
263             BT_DBG("Mesh Proxy Advertising stop");
264             bt_mesh_proxy_server_adv_stop();
265         }
266 #else
267         xQueueReceive(adv_queue.handle, &msg, portMAX_DELAY);
268 #endif /* (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_SERVER */
269 #else /* !defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */
270 #if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
271     CONFIG_BLE_MESH_GATT_PROXY_SERVER
272         handle = xQueueSelectFromSet(mesh_queue_set, K_NO_WAIT);
273         if (handle) {
274             if (uxQueueMessagesWaiting(adv_queue.handle)) {
275                 xQueueReceive(adv_queue.handle, &msg, K_NO_WAIT);
276             } else if (uxQueueMessagesWaiting(relay_queue.handle)) {
277                 xQueueReceive(relay_queue.handle, &msg, K_NO_WAIT);
278             }
279         } else {
280             while (!(*buf)) {
281                 int32_t timeout = 0;
282                 BT_DBG("Mesh Proxy Advertising start");
283                 timeout = bt_mesh_proxy_server_adv_start();
284                 BT_DBG("Mesh Proxy Advertising up to %d ms", timeout);
285                 handle = xQueueSelectFromSet(mesh_queue_set, K_WAIT(timeout));
286                 BT_DBG("Mesh Proxy Advertising stop");
287                 bt_mesh_proxy_server_adv_stop();
288                 if (handle) {
289                     if (uxQueueMessagesWaiting(adv_queue.handle)) {
290                         xQueueReceive(adv_queue.handle, &msg, K_NO_WAIT);
291                     } else if (uxQueueMessagesWaiting(relay_queue.handle)) {
292                         xQueueReceive(relay_queue.handle, &msg, K_NO_WAIT);
293                     }
294                 }
295             }
296         }
297 #else
298         handle = xQueueSelectFromSet(mesh_queue_set, portMAX_DELAY);
299         if (handle) {
300             if (uxQueueMessagesWaiting(adv_queue.handle)) {
301                 xQueueReceive(adv_queue.handle, &msg, K_NO_WAIT);
302             } else if (uxQueueMessagesWaiting(relay_queue.handle)) {
303                 xQueueReceive(relay_queue.handle, &msg, K_NO_WAIT);
304             }
305         }
306 #endif /* (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_SERVER */
307 #endif /* !defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */
308 
309         if (*buf == NULL) {
310             continue;
311         }
312 
313         /* busy == 0 means this was canceled */
314          if (bt_mesh_atomic_cas(&BLE_MESH_ADV_BUSY(*buf), 1, 0)) {
315 #if !defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
316             if (adv_send(*buf)) {
317                 BT_WARN("Failed to send adv packet");
318             }
319 #else /* !defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */
320             if (msg.relay && ignore_relay_packet(msg.timestamp)) {
321                 /* If the interval between "current time - msg.timestamp" is bigger than
322                  * BLE_MESH_RELAY_TIME_INTERVAL, this relay packet will not be sent.
323                  */
324                 BT_INFO("Ignore relay packet");
325                 net_buf_unref(*buf);
326             } else {
327                 if (adv_send(*buf)) {
328                     BT_WARN("Failed to send adv packet");
329                 }
330             }
331 #endif
332         } else {
333             bt_mesh_adv_buf_ref_debug(__func__, *buf, 1U, BLE_MESH_BUF_REF_EQUAL);
334             net_buf_unref(*buf);
335         }
336 
337         /* Give other threads a chance to run */
338         taskYIELD();
339     }
340 }
341 
bt_mesh_adv_create_from_pool(struct net_buf_pool * pool,bt_mesh_adv_alloc_t get_id,enum bt_mesh_adv_type type,uint8_t xmit,int32_t timeout)342 struct net_buf *bt_mesh_adv_create_from_pool(struct net_buf_pool *pool,
343                                              bt_mesh_adv_alloc_t get_id,
344                                              enum bt_mesh_adv_type type,
345                                              uint8_t xmit, int32_t timeout)
346 {
347     struct bt_mesh_adv *adv = NULL;
348     struct net_buf *buf = NULL;
349 
350     if (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_SUSPENDED)) {
351         BT_WARN("Refusing to allocate buffer while suspended");
352         return NULL;
353     }
354 
355     buf = net_buf_alloc(pool, timeout);
356     if (!buf) {
357         return NULL;
358     }
359 
360     BT_DBG("pool %p, buf_count %d, uinit_count %d",
361             buf->pool, pool->buf_count, pool->uninit_count);
362 
363     adv = get_id(net_buf_id(buf));
364     BLE_MESH_ADV(buf) = adv;
365 
366     (void)memset(adv, 0, sizeof(*adv));
367 
368     adv->type = type;
369     adv->xmit = xmit;
370 
371     return buf;
372 }
373 
bt_mesh_unref_buf_from_pool(struct net_buf_pool * pool)374 void bt_mesh_unref_buf_from_pool(struct net_buf_pool *pool)
375 {
376     int i;
377 
378     if (pool == NULL) {
379         BT_ERR("%s, Invalid parameter", __func__);
380         return;
381     }
382 
383     for (i = 0; i < pool->buf_count; i++) {
384         struct net_buf *buf = &pool->__bufs[i];
385         if (buf->ref > 1U) {
386             buf->ref = 1U;
387         }
388         net_buf_unref(buf);
389     }
390 }
391 
bt_mesh_adv_create(enum bt_mesh_adv_type type,uint8_t xmit,int32_t timeout)392 struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, uint8_t xmit,
393                                    int32_t timeout)
394 {
395     return bt_mesh_adv_create_from_pool(&adv_buf_pool, adv_alloc, type,
396                                         xmit, timeout);
397 }
398 
bt_mesh_adv_buf_ref_debug(const char * func,struct net_buf * buf,uint8_t ref_cmp,bt_mesh_buf_ref_flag_t flag)399 void bt_mesh_adv_buf_ref_debug(const char *func, struct net_buf *buf,
400                                uint8_t ref_cmp, bt_mesh_buf_ref_flag_t flag)
401 {
402     if (buf == NULL || func == NULL || flag >= BLE_MESH_BUF_REF_MAX) {
403         BT_ERR("%s, Invalid parameter", __func__);
404         return;
405     }
406 
407     switch (flag) {
408     case BLE_MESH_BUF_REF_EQUAL:
409         if (buf->ref != ref_cmp) {
410             BT_ERR("Unexpected ref %d in %s, expect to equal to %d", buf->ref, func, ref_cmp);
411         }
412         break;
413     case BLE_MESH_BUF_REF_SMALL:
414         if (buf->ref >= ref_cmp) {
415             BT_ERR("Unexpected ref %d in %s, expect to smaller than %d", buf->ref, func, ref_cmp);
416         }
417         break;
418     default:
419         break;
420     }
421 }
422 
bt_mesh_unref_buf(bt_mesh_msg_t * msg)423 static void bt_mesh_unref_buf(bt_mesh_msg_t *msg)
424 {
425     struct net_buf *buf = NULL;
426 
427     if (msg->arg) {
428         buf = (struct net_buf *)msg->arg;
429         bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 0);
430         if (buf->ref > 1U) {
431             buf->ref = 1U;
432         }
433         net_buf_unref(buf);
434     }
435 
436     return;
437 }
438 
bt_mesh_task_post(bt_mesh_msg_t * msg,uint32_t timeout,bool front)439 static void bt_mesh_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front)
440 {
441     BT_DBG("%s", __func__);
442 
443     if (adv_queue.handle == NULL) {
444         BT_ERR("Invalid adv queue");
445         return;
446     }
447 
448     if (front) {
449         if (xQueueSendToFront(adv_queue.handle, msg, timeout) != pdTRUE) {
450             BT_ERR("Failed to send item to adv queue front");
451             bt_mesh_unref_buf(msg);
452         }
453     } else {
454         if (xQueueSend(adv_queue.handle, msg, timeout) != pdTRUE) {
455             BT_ERR("Failed to send item to adv queue back");
456             bt_mesh_unref_buf(msg);
457         }
458     }
459 }
460 
bt_mesh_adv_send(struct net_buf * buf,const struct bt_mesh_send_cb * cb,void * cb_data)461 void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
462                       void *cb_data)
463 {
464     bt_mesh_msg_t msg = {
465         .relay = false,
466     };
467 
468     BT_DBG("type 0x%02x len %u: %s", BLE_MESH_ADV(buf)->type, buf->len,
469            bt_hex(buf->data, buf->len));
470 
471     BLE_MESH_ADV(buf)->cb = cb;
472     BLE_MESH_ADV(buf)->cb_data = cb_data;
473     bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1);
474 
475     bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
476 
477     msg.arg = (void *)net_buf_ref(buf);
478     bt_mesh_task_post(&msg, portMAX_DELAY, false);
479 }
480 
bt_mesh_adv_update(void)481 void bt_mesh_adv_update(void)
482 {
483     bt_mesh_msg_t msg = {
484         .relay = false,
485         .arg = NULL,
486     };
487 
488     BT_DBG("%s", __func__);
489 
490     bt_mesh_task_post(&msg, K_NO_WAIT, false);
491 }
492 
493 #if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
ignore_relay_packet(uint32_t timestamp)494 static bool ignore_relay_packet(uint32_t timestamp)
495 {
496     uint32_t now = k_uptime_get_32();
497     uint32_t interval = 0U;
498 
499     if (now >= timestamp) {
500         interval = now - timestamp;
501     } else {
502         interval = BLE_MESH_MAX_TIME_INTERVAL - (timestamp - now) + 1;
503     }
504 
505     return (interval >= BLE_MESH_RELAY_TIME_INTERVAL) ? true : false;
506 }
507 
relay_adv_alloc(int id)508 static struct bt_mesh_adv *relay_adv_alloc(int id)
509 {
510     return &relay_adv_pool[id];
511 }
512 
bt_mesh_relay_adv_create(enum bt_mesh_adv_type type,uint8_t xmit,int32_t timeout)513 struct net_buf *bt_mesh_relay_adv_create(enum bt_mesh_adv_type type, uint8_t xmit,
514                                          int32_t timeout)
515 {
516     return bt_mesh_adv_create_from_pool(&relay_adv_buf_pool, relay_adv_alloc, type,
517                                         xmit, timeout);
518 }
519 
ble_mesh_relay_task_post(bt_mesh_msg_t * msg,uint32_t timeout)520 static void ble_mesh_relay_task_post(bt_mesh_msg_t *msg, uint32_t timeout)
521 {
522     QueueSetMemberHandle_t handle = NULL;
523     bt_mesh_msg_t old_msg = {0};
524 
525     BT_DBG("%s", __func__);
526 
527     if (relay_queue.handle == NULL) {
528         BT_ERR("Invalid relay queue");
529         return;
530     }
531 
532     if (xQueueSend(relay_queue.handle, msg, timeout) == pdTRUE) {
533         return;
534     }
535 
536     /**
537      * If failed to send packet to the relay queue(queue is full), we will
538      * remove the oldest packet in the queue and put the new one into it.
539      */
540     handle = xQueueSelectFromSet(mesh_queue_set, K_NO_WAIT);
541     if (handle && uxQueueMessagesWaiting(relay_queue.handle)) {
542         BT_INFO("Full queue, remove the oldest relay packet");
543         /* Remove the oldest relay packet from queue */
544         if (xQueueReceive(relay_queue.handle, &old_msg, K_NO_WAIT) != pdTRUE) {
545             BT_ERR("Failed to remove item from relay queue");
546             bt_mesh_unref_buf(msg);
547             return;
548         }
549         /* Unref buf used for the oldest relay packet */
550         bt_mesh_unref_buf(&old_msg);
551         /* Send the latest relay packet to queue */
552         if (xQueueSend(relay_queue.handle, msg, K_NO_WAIT) != pdTRUE) {
553             BT_ERR("Failed to send item to relay queue");
554             bt_mesh_unref_buf(msg);
555             return;
556         }
557     } else {
558         BT_WARN("Empty queue, but failed to send the relay packet");
559         bt_mesh_unref_buf(msg);
560     }
561 }
562 
bt_mesh_relay_adv_send(struct net_buf * buf,const struct bt_mesh_send_cb * cb,void * cb_data,uint16_t src,uint16_t dst)563 void bt_mesh_relay_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
564                             void *cb_data, uint16_t src, uint16_t dst)
565 {
566     bt_mesh_msg_t msg = {
567         .relay = true,
568     };
569 
570     BT_DBG("type 0x%02x len %u: %s", BLE_MESH_ADV(buf)->type, buf->len,
571            bt_hex(buf->data, buf->len));
572 
573     BLE_MESH_ADV(buf)->cb = cb;
574     BLE_MESH_ADV(buf)->cb_data = cb_data;
575     bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1);
576 
577     msg.arg = (void *)net_buf_ref(buf);
578     msg.src = src;
579     msg.dst = dst;
580     msg.timestamp = k_uptime_get_32();
581     /* Use K_NO_WAIT here, if relay_queue is full return immediately */
582     ble_mesh_relay_task_post(&msg, K_NO_WAIT);
583 }
584 
bt_mesh_get_stored_relay_count(void)585 uint16_t bt_mesh_get_stored_relay_count(void)
586 {
587     return (uint16_t)uxQueueMessagesWaiting(relay_queue.handle);
588 }
589 #endif /* #if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */
590 
bt_mesh_adv_init(void)591 void bt_mesh_adv_init(void)
592 {
593 #if !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
594     adv_queue.handle = xQueueCreate(BLE_MESH_ADV_QUEUE_SIZE, sizeof(bt_mesh_msg_t));
595     __ASSERT(adv_queue.handle, "Failed to create queue");
596 #else /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
597 #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
598     adv_queue.buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
599 #elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
600     adv_queue.buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
601 #endif
602     __ASSERT(adv_queue.buffer, "Failed to create queue buffer");
603 #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
604     adv_queue.storage = heap_caps_calloc_prefer(1, (BLE_MESH_ADV_QUEUE_SIZE * sizeof(bt_mesh_msg_t)), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
605 #elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
606     adv_queue.storage = heap_caps_calloc_prefer(1, (BLE_MESH_ADV_QUEUE_SIZE * sizeof(bt_mesh_msg_t)), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
607 #endif
608     __ASSERT(adv_queue.storage, "Failed to create queue storage");
609     adv_queue.handle = xQueueCreateStatic(BLE_MESH_ADV_QUEUE_SIZE, sizeof(bt_mesh_msg_t), (uint8_t*)adv_queue.storage, adv_queue.buffer);
610     __ASSERT(adv_queue.handle, "Failed to create static queue");
611 #endif /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
612 
613 #if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
614 #if !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
615     relay_queue.handle = xQueueCreate(BLE_MESH_RELAY_QUEUE_SIZE, sizeof(bt_mesh_msg_t));
616     __ASSERT(relay_queue.handle, "Failed to create relay queue");
617 #else /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
618 #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
619     relay_queue.buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
620 #elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
621     relay_queue.buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
622 #endif
623     __ASSERT(relay_queue.buffer, "Failed to create relay queue buffer");
624 #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
625     relay_queue.storage = heap_caps_calloc_prefer(1, (BLE_MESH_RELAY_QUEUE_SIZE * sizeof(bt_mesh_msg_t)), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
626 #elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
627     relay_queue.storage = heap_caps_calloc_prefer(1, (BLE_MESH_RELAY_QUEUE_SIZE * sizeof(bt_mesh_msg_t)), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
628 #endif
629     __ASSERT(relay_queue.storage, "Failed to create relay queue storage");
630     relay_queue.handle = xQueueCreateStatic(BLE_MESH_RELAY_QUEUE_SIZE, sizeof(bt_mesh_msg_t), (uint8_t*)relay_queue.storage, relay_queue.buffer);
631     __ASSERT(relay_queue.handle, "Failed to create static relay queue");
632 #endif /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
633 
634     mesh_queue_set = xQueueCreateSet(BLE_MESH_QUEUE_SET_SIZE);
635     __ASSERT(mesh_queue_set, "Failed to create queue set");
636     xQueueAddToSet(adv_queue.handle, mesh_queue_set);
637     xQueueAddToSet(relay_queue.handle, mesh_queue_set);
638 #endif /* defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */
639 
640 #if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \
641     (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && \
642      CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY)
643     adv_task.task = heap_caps_calloc(1, sizeof(StaticTask_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
644     __ASSERT(adv_task.task, "Failed to create adv thread task");
645     adv_task.stack = heap_caps_calloc_prefer(1, BLE_MESH_ADV_TASK_STACK_SIZE * sizeof(StackType_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
646     __ASSERT(adv_task.stack, "Failed to create adv thread stack");
647     adv_task.handle = xTaskCreateStaticPinnedToCore(adv_thread, BLE_MESH_ADV_TASK_NAME, BLE_MESH_ADV_TASK_STACK_SIZE, NULL,
648                                   BLE_MESH_ADV_TASK_PRIO, adv_task.stack, adv_task.task, BLE_MESH_ADV_TASK_CORE);
649     __ASSERT(adv_task.handle, "Failed to create static adv thread");
650 #else /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY */
651     int ret = xTaskCreatePinnedToCore(adv_thread, BLE_MESH_ADV_TASK_NAME, BLE_MESH_ADV_TASK_STACK_SIZE, NULL,
652                                       BLE_MESH_ADV_TASK_PRIO, &adv_task.handle, BLE_MESH_ADV_TASK_CORE);
653     __ASSERT(ret == pdTRUE, "Failed to create adv thread");
654     (void)ret;
655 #endif /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY */
656 }
657 
658 #if CONFIG_BLE_MESH_DEINIT
bt_mesh_adv_deinit(void)659 void bt_mesh_adv_deinit(void)
660 {
661     if (adv_queue.handle == NULL) {
662         return;
663     }
664 
665     vTaskDelete(adv_task.handle);
666     adv_task.handle = NULL;
667 #if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \
668     (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && \
669      CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY)
670     heap_caps_free(adv_task.stack);
671     adv_task.stack = NULL;
672     heap_caps_free(adv_task.task);
673     adv_task.task = NULL;
674 #endif
675 
676 #if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
677     xQueueRemoveFromSet(adv_queue.handle, mesh_queue_set);
678     xQueueRemoveFromSet(relay_queue.handle, mesh_queue_set);
679 
680     vQueueDelete(relay_queue.handle);
681     relay_queue.handle = NULL;
682 #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
683     heap_caps_free(relay_queue.buffer);
684     relay_queue.buffer = NULL;
685     heap_caps_free(relay_queue.storage);
686     relay_queue.storage = NULL;
687 #endif
688 
689     bt_mesh_unref_buf_from_pool(&relay_adv_buf_pool);
690     memset(relay_adv_pool, 0, sizeof(relay_adv_pool));
691 
692     vQueueDelete(mesh_queue_set);
693     mesh_queue_set = NULL;
694 #endif /* defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */
695 
696     vQueueDelete(adv_queue.handle);
697     adv_queue.handle = NULL;
698 #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
699     heap_caps_free(adv_queue.buffer);
700     adv_queue.buffer = NULL;
701     heap_caps_free(adv_queue.storage);
702     adv_queue.storage = NULL;
703 #endif
704 
705     bt_mesh_unref_buf_from_pool(&adv_buf_pool);
706     memset(adv_pool, 0, sizeof(adv_pool));
707 
708 #if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
709     bt_mesh_ble_adv_deinit();
710 #endif
711 }
712 #endif /* CONFIG_BLE_MESH_DEINIT */
713 
714 #if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
ble_adv_alloc(int id)715 static struct bt_mesh_adv *ble_adv_alloc(int id)
716 {
717     return &ble_adv_pool[id];
718 }
719 
bt_mesh_ble_adv_create(enum bt_mesh_adv_type type,uint8_t xmit,int32_t timeout)720 static struct net_buf *bt_mesh_ble_adv_create(enum bt_mesh_adv_type type, uint8_t xmit, int32_t timeout)
721 {
722     return bt_mesh_adv_create_from_pool(&ble_adv_buf_pool, ble_adv_alloc, type,
723                                         xmit, timeout);
724 }
725 
bt_mesh_ble_adv_send(struct net_buf * buf,const struct bt_mesh_send_cb * cb,void * cb_data,bool front)726 static void bt_mesh_ble_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
727                                  void *cb_data, bool front)
728 {
729     bt_mesh_msg_t msg = {
730         .relay = false,
731     };
732 
733     BT_DBG("type 0x%02x len %u: %s", BLE_MESH_ADV(buf)->type, buf->len,
734            bt_hex(buf->data, buf->len));
735 
736     BLE_MESH_ADV(buf)->cb = cb;
737     BLE_MESH_ADV(buf)->cb_data = cb_data;
738     bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1);
739 
740     bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
741 
742     msg.arg = (void *)net_buf_ref(buf);
743     bt_mesh_task_post(&msg, portMAX_DELAY, front);
744 }
745 
ble_adv_tx_reset(struct ble_adv_tx * tx,bool unref)746 static void ble_adv_tx_reset(struct ble_adv_tx *tx, bool unref)
747 {
748     if (tx->buf == NULL) {
749         return;
750     }
751 
752     if (bt_mesh_atomic_test_bit(tx->flags, TIMER_INIT)) {
753         k_delayed_work_free(&tx->resend);
754     }
755     bt_mesh_atomic_set(tx->flags, 0);
756     memset(&tx->param, 0, sizeof(tx->param));
757     bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(tx->buf), 0);
758     if (unref) {
759         net_buf_unref(tx->buf);
760     }
761     tx->buf = NULL;
762 }
763 
ble_adv_send_start(uint16_t duration,int err,void * cb_data)764 static void ble_adv_send_start(uint16_t duration, int err, void *cb_data)
765 {
766     struct ble_adv_tx *tx = cb_data;
767 
768     BT_DBG("%s, duration %d, err %d", __func__, duration, err);
769 
770     /* If failed to send BLE adv packet, and param->count is not 0
771      * which means the timer has been initialized, here we need to
772      * free the timer.
773      */
774     if (err) {
775         ble_adv_tx_reset(tx, true);
776     }
777 }
778 
ble_adv_send_end(int err,void * cb_data)779 static void ble_adv_send_end(int err, void *cb_data)
780 {
781     struct ble_adv_tx *tx = cb_data;
782 
783     BT_DBG("%s, err %d", __func__, err);
784 
785     if (err) {
786         ble_adv_tx_reset(tx, true);
787         return;
788     }
789 
790     if (tx->param.count) {
791         if (tx->param.period) {
792             k_delayed_work_submit(&tx->resend, tx->param.period);
793         } else {
794             k_work_submit(&tx->resend.work);
795         }
796     } else {
797         ble_adv_tx_reset(tx, true);
798     }
799 }
800 
801 static struct bt_mesh_send_cb ble_adv_send_cb = {
802     .start = ble_adv_send_start,
803     .end = ble_adv_send_end,
804 };
805 
ble_adv_resend(struct k_work * work)806 static void ble_adv_resend(struct k_work *work)
807 {
808     struct ble_adv_tx *tx = CONTAINER_OF(work, struct ble_adv_tx, resend.work);
809     bool front = false;
810 
811     if (tx->buf == NULL) {
812         /* The advertising has been cancelled */
813         return;
814     }
815 
816     front = (tx->param.priority == BLE_MESH_BLE_ADV_PRIO_HIGH) ? true : false;
817     bt_mesh_ble_adv_send(tx->buf, &ble_adv_send_cb, tx, front);
818 
819     if (tx->param.count == SEND_BLE_ADV_INFINITE) {
820         /* Send the BLE advertising packet infinitely */
821         return;
822     }
823 
824     if (tx->param.count > 0U) {
825         tx->param.count--;
826     }
827 }
828 
bt_mesh_start_ble_advertising(const struct bt_mesh_ble_adv_param * param,const struct bt_mesh_ble_adv_data * data,uint8_t * index)829 int bt_mesh_start_ble_advertising(const struct bt_mesh_ble_adv_param *param,
830                                   const struct bt_mesh_ble_adv_data *data, uint8_t *index)
831 {
832     struct ble_adv_tx *tx = NULL;
833     struct net_buf *buf = NULL;
834     bool front = false;
835 
836     if (param == NULL || index == NULL) {
837         BT_ERR("%s, Invalid parameter", __func__);
838         return -EINVAL;
839     }
840 
841     if (param->adv_type != BLE_MESH_ADV_DIRECT_IND &&
842         (param->interval < 0x20 || param->interval > 0x4000)) {
843         BT_ERR("Invalid adv interval 0x%04x", param->interval);
844         return -EINVAL;
845     }
846 
847     if (param->adv_type > BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) {
848         BT_ERR("Invalid adv type 0x%02x", param->adv_type);
849         return -EINVAL;
850     }
851 
852     if (param->own_addr_type > BLE_MESH_ADDR_RANDOM_ID) {
853         BT_ERR("Invalid own addr type 0x%02x", param->own_addr_type);
854         return -EINVAL;
855     }
856 
857     if ((param->own_addr_type == BLE_MESH_ADDR_PUBLIC_ID ||
858         param->own_addr_type == BLE_MESH_ADDR_RANDOM_ID ||
859         param->adv_type == BLE_MESH_ADV_DIRECT_IND ||
860         param->adv_type == BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) &&
861         param->peer_addr_type > BLE_MESH_ADDR_RANDOM) {
862         BT_ERR("Invalid peer addr type 0x%02x", param->peer_addr_type);
863         return -EINVAL;
864     }
865 
866     if (data && (data->adv_data_len > 31 || data->scan_rsp_data_len > 31)) {
867         BT_ERR("Invalid adv data length (adv %d, scan rsp %d)",
868                 data->adv_data_len, data->scan_rsp_data_len);
869         return -EINVAL;
870     }
871 
872     if (param->priority > BLE_MESH_BLE_ADV_PRIO_HIGH) {
873         BT_ERR("Invalid adv priority %d", param->priority);
874         return -EINVAL;
875     }
876 
877     if (param->duration < ADV_SCAN_INT(param->interval)) {
878         BT_ERR("Too small duration %dms", param->duration);
879         return -EINVAL;
880     }
881 
882     buf = bt_mesh_ble_adv_create(BLE_MESH_ADV_BLE, 0U, K_NO_WAIT);
883     if (!buf) {
884         BT_ERR("No empty ble adv buffer");
885         return -ENOBUFS;
886     }
887 
888     /* Set advertising data and scan response data */
889     memset(buf->data, 0, buf->size);
890     if (data) {
891         net_buf_add_u8(buf, data->adv_data_len);
892         if (data->adv_data_len) {
893             net_buf_add_mem(buf, data->adv_data, data->adv_data_len);
894         }
895         net_buf_add_u8(buf, data->scan_rsp_data_len);
896         if (data->scan_rsp_data_len) {
897             net_buf_add_mem(buf, data->scan_rsp_data, data->scan_rsp_data_len);
898         }
899     }
900 
901     *index = net_buf_id(buf);
902     tx = &ble_adv_tx[*index];
903     tx->buf = buf;
904     memcpy(&tx->param, param, sizeof(tx->param));
905 
906     front = (tx->param.priority == BLE_MESH_BLE_ADV_PRIO_HIGH) ? true : false;
907     bt_mesh_ble_adv_send(buf, &ble_adv_send_cb, tx, front);
908     if (param->count) {
909         if (k_delayed_work_init(&tx->resend, ble_adv_resend)) {
910             /* If failed to create a timer, the BLE adv packet will be
911              * sent only once. Just give a warning here, and since the
912              * BLE adv packet can be sent, return 0 here.
913              */
914             BT_WARN("Send BLE adv packet only once");
915             tx->param.count = 0;
916             net_buf_unref(buf);
917             return 0;
918         }
919         bt_mesh_atomic_set_bit(tx->flags, TIMER_INIT);
920     } else {
921         /* Send the BLE advertising packet only once */
922         net_buf_unref(buf);
923     }
924 
925     return 0;
926 }
927 
bt_mesh_stop_ble_advertising(uint8_t index)928 int bt_mesh_stop_ble_advertising(uint8_t index)
929 {
930     struct ble_adv_tx *tx = NULL;
931     bool unref = true;
932 
933     if (index >= ARRAY_SIZE(ble_adv_tx)) {
934         BT_ERR("Invalid adv index %d", index);
935         return -EINVAL;
936     }
937 
938     tx = &ble_adv_tx[index];
939 
940     if (tx->buf == NULL) {
941         BT_WARN("Already stopped, index %d", index);
942         return 0;
943     }
944 
945     /* busy 1, ref 1; busy 1, ref 2;
946      * busy 0, ref 0; busy 0, ref 1;
947      */
948 
949     if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(tx->buf)) &&
950         tx->buf->ref == 1U) {
951         unref = false;
952     }
953     ble_adv_tx_reset(tx, unref);
954 
955     return 0;
956 }
957 
958 #if CONFIG_BLE_MESH_DEINIT
bt_mesh_ble_adv_deinit(void)959 static void bt_mesh_ble_adv_deinit(void)
960 {
961     for (int i = 0; i < ARRAY_SIZE(ble_adv_tx); i++) {
962         struct ble_adv_tx *tx = &ble_adv_tx[i];
963         ble_adv_tx_reset(tx, false);
964     }
965     bt_mesh_unref_buf_from_pool(&ble_adv_buf_pool);
966     memset(ble_adv_pool, 0, sizeof(ble_adv_pool));
967 }
968 #endif /* CONFIG_BLE_MESH_DEINIT */
969 #endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
970