adv.c 32 KB

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