mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 09:09:10 -04:00
Merge branch 'feature/ble_mesh_multi_adv_instance_support' into 'master'
Feature/ble mesh multi adv instance support Closes BLERP-1282 See merge request espressif/esp-idf!35208
This commit is contained in:
commit
305f1c1e5b
@ -501,13 +501,15 @@ if(CONFIG_BT_ENABLED)
|
|||||||
"esp_ble_mesh/common/common.c"
|
"esp_ble_mesh/common/common.c"
|
||||||
"esp_ble_mesh/common/kernel.c"
|
"esp_ble_mesh/common/kernel.c"
|
||||||
"esp_ble_mesh/common/mutex.c"
|
"esp_ble_mesh/common/mutex.c"
|
||||||
|
"esp_ble_mesh/common/queue.c"
|
||||||
"esp_ble_mesh/common/timer.c"
|
"esp_ble_mesh/common/timer.c"
|
||||||
"esp_ble_mesh/common/utils.c"
|
"esp_ble_mesh/common/utils.c"
|
||||||
"esp_ble_mesh/core/storage/settings_nvs.c"
|
"esp_ble_mesh/core/storage/settings_nvs.c"
|
||||||
"esp_ble_mesh/core/storage/settings_uid.c"
|
"esp_ble_mesh/core/storage/settings_uid.c"
|
||||||
"esp_ble_mesh/core/storage/settings.c"
|
"esp_ble_mesh/core/storage/settings.c"
|
||||||
"esp_ble_mesh/core/access.c"
|
"esp_ble_mesh/core/access.c"
|
||||||
"esp_ble_mesh/core/adv.c"
|
"esp_ble_mesh/core/adv_common.c"
|
||||||
|
"esp_ble_mesh/core/ble_adv.c"
|
||||||
"esp_ble_mesh/core/beacon.c"
|
"esp_ble_mesh/core/beacon.c"
|
||||||
"esp_ble_mesh/core/cfg_cli.c"
|
"esp_ble_mesh/core/cfg_cli.c"
|
||||||
"esp_ble_mesh/core/cfg_srv.c"
|
"esp_ble_mesh/core/cfg_srv.c"
|
||||||
@ -579,6 +581,11 @@ if(CONFIG_BT_ENABLED)
|
|||||||
list(APPEND srcs
|
list(APPEND srcs
|
||||||
"esp_ble_mesh/core/transport.c")
|
"esp_ble_mesh/core/transport.c")
|
||||||
endif()
|
endif()
|
||||||
|
if(CONFIG_BLE_MESH_SUPPORT_MULTI_ADV)
|
||||||
|
list(APPEND srcs "esp_ble_mesh/core/ext_adv.c")
|
||||||
|
else()
|
||||||
|
list(APPEND srcs "esp_ble_mesh/core/adv.c")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,6 +34,63 @@ if BLE_MESH
|
|||||||
help
|
help
|
||||||
This option to enable BLE Mesh using some BLE 5.0 APIs.
|
This option to enable BLE Mesh using some BLE 5.0 APIs.
|
||||||
|
|
||||||
|
config BLE_MESH_ADV_INST_ID
|
||||||
|
depends on BLE_MESH_USE_BLE_50
|
||||||
|
int "Extended adv instance for Mesh normal packets"
|
||||||
|
default 0
|
||||||
|
range 0 3
|
||||||
|
help
|
||||||
|
Extended ADV instance used by Mesh normal advertising packets.
|
||||||
|
|
||||||
|
menuconfig BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
bool "Support using multiple adv instance for BLE Mesh"
|
||||||
|
depends on BLE_MESH_USE_BLE_50
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Enable this option to support using multiple adv instance while running BLE Mesh.
|
||||||
|
|
||||||
|
config BLE_MESH_PROXY_ADV_INST_ID
|
||||||
|
int "Extended adv instance for Mesh proxy packets"
|
||||||
|
depends on BLE_MESH_PROXY
|
||||||
|
depends on (BLE_MESH_PB_GATT || BLE_MESH_GATT_PROXY_SERVER)
|
||||||
|
depends on BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
default 1
|
||||||
|
range 0 3
|
||||||
|
help
|
||||||
|
Extended ADV instance used by Mesh proxy advertising packets.
|
||||||
|
|
||||||
|
menuconfig BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE
|
||||||
|
bool "Use separate extended adv instance for Mesh relay packets"
|
||||||
|
depends on BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
depends on BLE_MESH_RELAY_ADV_BUF
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Enable this option to support using a separate extended ADV instance for Mesh relay packets.
|
||||||
|
|
||||||
|
config BLE_MESH_RELAY_ADV_INST_ID
|
||||||
|
int "Extended adv instance for Mesh relay packets"
|
||||||
|
depends on BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE
|
||||||
|
default 2
|
||||||
|
range 0 3
|
||||||
|
help
|
||||||
|
Extended ADV instance used by Mesh relay advertising packets.
|
||||||
|
|
||||||
|
menuconfig BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
|
||||||
|
bool "Use separate extended adv instance for BLE normal packets"
|
||||||
|
depends on BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
depends on BLE_MESH_SUPPORT_BLE_ADV
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Enable this option to support using a separate extended ADV instance for normal BLE advertising packets.
|
||||||
|
|
||||||
|
config BLE_MESH_BLE_ADV_INST_ID
|
||||||
|
int "Extended adv instance for normal BLE packets"
|
||||||
|
depends on BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
|
||||||
|
default 3
|
||||||
|
range 0 3
|
||||||
|
help
|
||||||
|
Extended ADV instance used by normal BLE advertising packets.
|
||||||
|
|
||||||
config BLE_MESH_USE_DUPLICATE_SCAN
|
config BLE_MESH_USE_DUPLICATE_SCAN
|
||||||
bool "Support Duplicate Scan in BLE Mesh"
|
bool "Support Duplicate Scan in BLE Mesh"
|
||||||
select BTDM_BLE_SCAN_DUPL if IDF_TARGET_ESP32
|
select BTDM_BLE_SCAN_DUPL if IDF_TARGET_ESP32
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -32,6 +32,11 @@ void bt_mesh_r_mutex_free(bt_mesh_mutex_t *mutex);
|
|||||||
void bt_mesh_r_mutex_lock(bt_mesh_mutex_t *mutex);
|
void bt_mesh_r_mutex_lock(bt_mesh_mutex_t *mutex);
|
||||||
void bt_mesh_r_mutex_unlock(bt_mesh_mutex_t *mutex);
|
void bt_mesh_r_mutex_unlock(bt_mesh_mutex_t *mutex);
|
||||||
|
|
||||||
|
void bt_mesh_c_semaphore_create(bt_mesh_mutex_t *mutex, int max, int init);
|
||||||
|
void bt_mesh_c_semaphore_free(bt_mesh_mutex_t *mutex);
|
||||||
|
void bt_mesh_c_semaphore_give(bt_mesh_mutex_t *mutex);
|
||||||
|
void bt_mesh_c_semaphore_take(bt_mesh_mutex_t *mutex, uint32_t timeout);
|
||||||
|
|
||||||
void bt_mesh_alarm_lock(void);
|
void bt_mesh_alarm_lock(void);
|
||||||
void bt_mesh_alarm_unlock(void);
|
void bt_mesh_alarm_unlock(void);
|
||||||
|
|
||||||
|
33
components/bt/esp_ble_mesh/common/include/mesh/queue.h
Normal file
33
components/bt/esp_ble_mesh/common/include/mesh/queue.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _BLE_MESH_QUEUE_H_
|
||||||
|
#define _BLE_MESH_QUEUE_H_
|
||||||
|
|
||||||
|
#include "mesh/kernel.h"
|
||||||
|
#include "mesh/slist.h"
|
||||||
|
#include "mesh/atomic.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
QueueHandle_t handle;
|
||||||
|
#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
|
||||||
|
StaticQueue_t *buffer;
|
||||||
|
uint8_t *storage;
|
||||||
|
#endif
|
||||||
|
} bt_mesh_queue_t;
|
||||||
|
|
||||||
|
int bt_mesh_queue_init(bt_mesh_queue_t *queue, uint8_t queue_size, uint8_t item_size);
|
||||||
|
int bt_mesh_queue_deinit(bt_mesh_queue_t *queue);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _BLE_MESH_QUEUE_H_ */
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -125,6 +125,57 @@ void bt_mesh_r_mutex_unlock(bt_mesh_mutex_t *mutex)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bt_mesh_c_semaphore_free(bt_mesh_mutex_t *mutex)
|
||||||
|
{
|
||||||
|
bt_mesh_mutex_free(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_c_semaphore_create(bt_mesh_mutex_t *mutex, int max, int init)
|
||||||
|
{
|
||||||
|
if (!mutex) {
|
||||||
|
BT_ERR("Create, invalid mutex");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
|
||||||
|
#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
|
||||||
|
mutex->buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||||
|
#elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
|
||||||
|
mutex->buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||||
|
#endif
|
||||||
|
__ASSERT(mutex->buffer, "Failed to create counting semaphore buffer");
|
||||||
|
mutex->mutex = xSemaphoreCreateCountingStatic(max, init, mutex->buffer);
|
||||||
|
__ASSERT(mutex->mutex, "Failed to create static counting semaphore");
|
||||||
|
#else /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
|
||||||
|
mutex->mutex = xSemaphoreCreateCounting(max, init);
|
||||||
|
__ASSERT(mutex->mutex, "Failed to create counting semaphore");
|
||||||
|
#endif /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_c_semaphore_take(bt_mesh_mutex_t *mutex, uint32_t timeout)
|
||||||
|
{
|
||||||
|
if (!mutex) {
|
||||||
|
BT_ERR("Lock, invalid counting semaphore");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mutex->mutex) {
|
||||||
|
xSemaphoreTake(mutex->mutex, timeout / portTICK_PERIOD_MS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_c_semaphore_give(bt_mesh_mutex_t *mutex)
|
||||||
|
{
|
||||||
|
if (!mutex) {
|
||||||
|
BT_ERR("Unlock, invalid counting semaphore");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mutex->mutex) {
|
||||||
|
xSemaphoreGive(mutex->mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void bt_mesh_alarm_lock(void)
|
void bt_mesh_alarm_lock(void)
|
||||||
{
|
{
|
||||||
bt_mesh_mutex_lock(&alarm_lock);
|
bt_mesh_mutex_lock(&alarm_lock);
|
||||||
|
48
components/bt/esp_ble_mesh/common/queue.c
Normal file
48
components/bt/esp_ble_mesh/common/queue.c
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mesh/common.h"
|
||||||
|
#include "mesh/queue.h"
|
||||||
|
|
||||||
|
int bt_mesh_queue_init(bt_mesh_queue_t *queue, uint8_t queue_size, uint8_t item_size)
|
||||||
|
{
|
||||||
|
__ASSERT(queue && queue_size && item_size, "Invalid queue init parameters");
|
||||||
|
|
||||||
|
#if !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
|
||||||
|
queue->handle = xQueueCreate(queue_size, item_size);
|
||||||
|
__ASSERT(queue->handle, "Failed to create queue");
|
||||||
|
#else /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
|
||||||
|
#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
|
||||||
|
queue->buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||||
|
#elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
|
||||||
|
queue->buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||||
|
#endif
|
||||||
|
__ASSERT(queue->buffer, "Failed to create queue buffer");
|
||||||
|
#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
|
||||||
|
queue->storage = heap_caps_calloc_prefer(1, (queue_size * item_size), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||||
|
#elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
|
||||||
|
queue->storage = heap_caps_calloc_prefer(1, (queue_size * item_size), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||||
|
#endif
|
||||||
|
__ASSERT(queue->storage, "Failed to create queue storage");
|
||||||
|
queue->handle = xQueueCreateStatic(queue_size, item_size, (uint8_t*)queue->storage, queue->buffer);
|
||||||
|
__ASSERT(queue->handle, "Failed to create static queue");
|
||||||
|
#endif /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bt_mesh_queue_deinit(bt_mesh_queue_t *queue)
|
||||||
|
{
|
||||||
|
__ASSERT(queue, "Invalid queue init parameters");
|
||||||
|
vQueueDelete(queue->handle);
|
||||||
|
queue->handle = NULL;
|
||||||
|
#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
|
||||||
|
heap_caps_free(queue->buffer);
|
||||||
|
queue->buffer = NULL;
|
||||||
|
heap_caps_free(queue->storage);
|
||||||
|
queue->storage = NULL;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
@ -23,158 +23,20 @@
|
|||||||
#include "proxy_client.h"
|
#include "proxy_client.h"
|
||||||
#include "prov_pvnr.h"
|
#include "prov_pvnr.h"
|
||||||
#include "mesh/adapter.h"
|
#include "mesh/adapter.h"
|
||||||
|
#include "adv_common.h"
|
||||||
|
#include "ble_adv.h"
|
||||||
|
|
||||||
/* Convert from ms to 0.625ms units */
|
static struct bt_mesh_adv_queue *adv_queue;
|
||||||
#define ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5)
|
|
||||||
/* Convert from 0.625ms units to interval(ms) */
|
|
||||||
#define ADV_SCAN_INT(val) ((val) * 5 / 8)
|
|
||||||
|
|
||||||
/* Pre-5.0 controllers enforce a minimum interval of 100ms
|
|
||||||
* whereas 5.0+ controllers can go down to 20ms.
|
|
||||||
*/
|
|
||||||
#if CONFIG_BLE_MESH_HCI_5_0
|
|
||||||
#define ADV_ITVL_MIN 20
|
|
||||||
#else
|
|
||||||
#define ADV_ITVL_MIN 100
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const uint8_t adv_type[] = {
|
|
||||||
[BLE_MESH_ADV_PROV] = BLE_MESH_DATA_MESH_PROV,
|
|
||||||
[BLE_MESH_ADV_DATA] = BLE_MESH_DATA_MESH_MESSAGE,
|
|
||||||
[BLE_MESH_ADV_BEACON] = BLE_MESH_DATA_MESH_BEACON,
|
|
||||||
[BLE_MESH_ADV_URI] = BLE_MESH_DATA_URI,
|
|
||||||
};
|
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
|
||||||
#define ESP_BLE_MESH_INST_UNUSED_ELT_(IDX, _) [IDX] = {.id = IDX}
|
|
||||||
|
|
||||||
static struct bt_mesh_adv_inst adv_insts[BLE_MESH_ADV_INS_CNT] = {
|
|
||||||
LISTIFY(BLE_MESH_ADV_INS_CNT, ESP_BLE_MESH_INST_UNUSED_ELT_, (,)),
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NET_BUF_POOL_DEFINE(adv_buf_pool, CONFIG_BLE_MESH_ADV_BUF_COUNT,
|
|
||||||
BLE_MESH_ADV_DATA_SIZE, BLE_MESH_ADV_USER_DATA_SIZE, NULL);
|
|
||||||
|
|
||||||
static struct bt_mesh_adv adv_pool[CONFIG_BLE_MESH_ADV_BUF_COUNT];
|
|
||||||
|
|
||||||
struct bt_mesh_queue {
|
|
||||||
QueueHandle_t handle;
|
|
||||||
#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
|
|
||||||
StaticQueue_t *buffer;
|
|
||||||
uint8_t *storage;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct bt_mesh_queue adv_queue;
|
|
||||||
/* We reserve one queue item for bt_mesh_adv_update() */
|
|
||||||
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
|
||||||
#define BLE_MESH_ADV_QUEUE_SIZE (CONFIG_BLE_MESH_ADV_BUF_COUNT + CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT + 1)
|
|
||||||
#else
|
|
||||||
#define BLE_MESH_ADV_QUEUE_SIZE (CONFIG_BLE_MESH_ADV_BUF_COUNT + 1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||||
NET_BUF_POOL_DEFINE(relay_adv_buf_pool, CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT,
|
|
||||||
BLE_MESH_ADV_DATA_SIZE, BLE_MESH_ADV_USER_DATA_SIZE, NULL);
|
|
||||||
|
|
||||||
static struct bt_mesh_adv relay_adv_pool[CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT];
|
|
||||||
|
|
||||||
static struct bt_mesh_queue relay_queue;
|
|
||||||
#define BLE_MESH_RELAY_QUEUE_SIZE CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT
|
#define BLE_MESH_RELAY_QUEUE_SIZE CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT
|
||||||
|
|
||||||
static QueueSetHandle_t mesh_queue_set;
|
static QueueSetHandle_t mesh_queue_set;
|
||||||
#define BLE_MESH_QUEUE_SET_SIZE (BLE_MESH_ADV_QUEUE_SIZE + BLE_MESH_RELAY_QUEUE_SIZE)
|
#define BLE_MESH_QUEUE_SET_SIZE (BLE_MESH_ADV_QUEUE_SIZE + BLE_MESH_RELAY_QUEUE_SIZE)
|
||||||
|
|
||||||
#define BLE_MESH_RELAY_TIME_INTERVAL K_SECONDS(6)
|
|
||||||
#define BLE_MESH_MAX_TIME_INTERVAL 0xFFFFFFFF
|
|
||||||
|
|
||||||
static bool ignore_relay_packet(uint32_t timestamp);
|
|
||||||
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
|
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
|
||||||
/* length + advertising data + length + scan response data */
|
|
||||||
NET_BUF_POOL_DEFINE(ble_adv_buf_pool, CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT,
|
|
||||||
((BLE_MESH_ADV_DATA_SIZE + 3) << 1), BLE_MESH_ADV_USER_DATA_SIZE, NULL);
|
|
||||||
|
|
||||||
static struct bt_mesh_adv ble_adv_pool[CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT];
|
|
||||||
|
|
||||||
enum {
|
|
||||||
TIMER_INIT, /* Resend timer is initialized */
|
|
||||||
NUM_FLAGS,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct ble_adv_tx {
|
|
||||||
struct bt_mesh_ble_adv_param param;
|
|
||||||
struct net_buf *buf;
|
|
||||||
struct k_delayed_work resend;
|
|
||||||
BLE_MESH_ATOMIC_DEFINE(flags, NUM_FLAGS);
|
|
||||||
} ble_adv_tx[CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT];
|
|
||||||
|
|
||||||
#define SEND_BLE_ADV_INFINITE 0xFFFF
|
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_DEINIT
|
|
||||||
static void bt_mesh_ble_adv_deinit(void);
|
|
||||||
#endif /* CONFIG_BLE_MESH_DEINIT */
|
|
||||||
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
|
|
||||||
|
|
||||||
struct bt_mesh_adv_task {
|
|
||||||
TaskHandle_t handle;
|
|
||||||
#if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \
|
|
||||||
(CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && \
|
|
||||||
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY)
|
|
||||||
StaticTask_t *task;
|
|
||||||
StackType_t *stack;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct bt_mesh_adv_task adv_task;
|
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
|
||||||
bool bt_mesh_is_adv_inst_used(uint8_t adv_inst_id)
|
|
||||||
{
|
|
||||||
uint8_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(adv_insts); i++) {
|
|
||||||
if (adv_insts[i].id == adv_inst_id) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t bt_mesh_get_proxy_inst(void)
|
|
||||||
{
|
|
||||||
return adv_insts[0].id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bt_mesh_adv_inst_deinit(void)
|
|
||||||
{
|
|
||||||
uint8_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(adv_insts); i++) {
|
|
||||||
bt_le_ext_adv_stop(adv_insts[i].id);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct bt_mesh_adv *adv_alloc(int id)
|
|
||||||
{
|
|
||||||
return &adv_pool[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
int ble_mesh_adv_task_wakeup(uint16_t adv_inst_id)
|
|
||||||
{
|
|
||||||
xTaskNotify(adv_task.handle, BIT(adv_inst_id), eSetBits);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool ble_mesh_adv_task_wait(uint32_t timeout, uint32_t *notify)
|
|
||||||
{
|
|
||||||
return xTaskNotifyWait(UINT32_MAX, UINT32_MAX, notify, timeout) == pdTRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void adv_send_start(uint16_t duration, int err,
|
static inline void adv_send_start(uint16_t duration, int err,
|
||||||
const struct bt_mesh_send_cb *cb,
|
const struct bt_mesh_send_cb *cb,
|
||||||
void *cb_data)
|
void *cb_data)
|
||||||
@ -192,27 +54,8 @@ static inline void adv_send_end(int err, const struct bt_mesh_send_cb *cb,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t bt_mesh_pdu_duration(uint8_t xmit)
|
|
||||||
{
|
|
||||||
uint16_t duration = 0U;
|
|
||||||
uint16_t adv_int = 0U;
|
|
||||||
|
|
||||||
adv_int = MAX(ADV_ITVL_MIN, BLE_MESH_TRANSMIT_INT(xmit));
|
|
||||||
duration = (BLE_MESH_TRANSMIT_COUNT(xmit) + 1) * (adv_int + 10);
|
|
||||||
|
|
||||||
return duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline TickType_t K_WAIT(int32_t val)
|
|
||||||
{
|
|
||||||
return (val == K_FOREVER) ? portMAX_DELAY : (val / portTICK_PERIOD_MS);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int adv_send(struct net_buf *buf)
|
static inline int adv_send(struct net_buf *buf)
|
||||||
{
|
{
|
||||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
|
||||||
struct bt_mesh_adv_inst *adv_ins = &adv_insts[0];
|
|
||||||
#endif
|
|
||||||
const struct bt_mesh_send_cb *cb = BLE_MESH_ADV(buf)->cb;
|
const struct bt_mesh_send_cb *cb = BLE_MESH_ADV(buf)->cb;
|
||||||
void *cb_data = BLE_MESH_ADV(buf)->cb_data;
|
void *cb_data = BLE_MESH_ADV(buf)->cb_data;
|
||||||
struct bt_mesh_adv_param param = {0};
|
struct bt_mesh_adv_param param = {0};
|
||||||
@ -259,7 +102,7 @@ static inline int adv_send(struct net_buf *buf)
|
|||||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
param.primary_phy = BLE_MESH_ADV_PHY_1M;
|
param.primary_phy = BLE_MESH_ADV_PHY_1M;
|
||||||
param.secondary_phy = BLE_MESH_ADV_PHY_1M;
|
param.secondary_phy = BLE_MESH_ADV_PHY_1M;
|
||||||
err = bt_le_ext_adv_start(adv_ins->id, ¶m, &ad, 3, NULL, 0);
|
err = bt_le_ext_adv_start(CONFIG_BLE_MESH_ADV_INST_ID, ¶m, &ad, 3, NULL, 0);
|
||||||
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
|
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||||
err = bt_le_adv_start(¶m, &ad, 3, NULL, 0);
|
err = bt_le_adv_start(¶m, &ad, 3, NULL, 0);
|
||||||
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||||
@ -270,7 +113,7 @@ static inline int adv_send(struct net_buf *buf)
|
|||||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
param.primary_phy = BLE_MESH_ADV_PHY_1M;
|
param.primary_phy = BLE_MESH_ADV_PHY_1M;
|
||||||
param.secondary_phy = BLE_MESH_ADV_PHY_1M;
|
param.secondary_phy = BLE_MESH_ADV_PHY_1M;
|
||||||
err = bt_le_ext_adv_start(adv_ins->id, ¶m, &ad, 1, NULL, 0);
|
err = bt_le_ext_adv_start(CONFIG_BLE_MESH_ADV_INST_ID, ¶m, &ad, 1, NULL, 0);
|
||||||
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
|
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||||
err = bt_le_adv_start(¶m, &ad, 1, NULL, 0);
|
err = bt_le_adv_start(¶m, &ad, 1, NULL, 0);
|
||||||
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||||
@ -278,7 +121,7 @@ static inline int adv_send(struct net_buf *buf)
|
|||||||
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||||
} else {
|
} else {
|
||||||
struct bt_mesh_ble_adv_data data = {0};
|
struct bt_mesh_ble_adv_data data = {0};
|
||||||
struct ble_adv_tx *tx = cb_data;
|
struct bt_mesh_ble_adv_tx *tx = cb_data;
|
||||||
|
|
||||||
if (tx == NULL) {
|
if (tx == NULL) {
|
||||||
BT_ERR("Invalid adv user data");
|
BT_ERR("Invalid adv user data");
|
||||||
@ -303,7 +146,7 @@ static inline int adv_send(struct net_buf *buf)
|
|||||||
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
|
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
err = bt_mesh_ble_ext_adv_start(adv_ins->id, &tx->param, &data);
|
err = bt_mesh_ble_ext_adv_start(CONFIG_BLE_MESH_ADV_INST_ID, &tx->param, &data);
|
||||||
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
|
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||||
err = bt_mesh_ble_adv_start(&tx->param, &data);
|
err = bt_mesh_ble_adv_start(&tx->param, &data);
|
||||||
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||||
@ -320,12 +163,12 @@ static inline int adv_send(struct net_buf *buf)
|
|||||||
BT_DBG("Advertising started. Sleeping %u ms", duration);
|
BT_DBG("Advertising started. Sleeping %u ms", duration);
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
if (!ble_mesh_adv_task_wait(K_WAIT(K_FOREVER), NULL)) {
|
if (!ble_mesh_adv_task_wait(UINT32_MAX, K_FOREVER, NULL)) {
|
||||||
BT_WARN("Advertising didn't finish on time");
|
BT_WARN("Advertising didn't finish on time");
|
||||||
bt_le_ext_adv_stop(adv_ins->id);
|
bt_le_ext_adv_stop(CONFIG_BLE_MESH_ADV_INST_ID);
|
||||||
}
|
}
|
||||||
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
|
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||||
k_sleep(K_MSEC(duration));
|
ble_mesh_adv_task_wait(K_MSEC(duration));
|
||||||
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||||
|
|
||||||
#if !CONFIG_BLE_MESH_USE_BLE_50
|
#if !CONFIG_BLE_MESH_USE_BLE_50
|
||||||
@ -346,6 +189,8 @@ static void adv_thread(void *p)
|
|||||||
{
|
{
|
||||||
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||||
QueueSetMemberHandle_t handle = NULL;
|
QueueSetMemberHandle_t handle = NULL;
|
||||||
|
QueueHandle_t relay_adv_handle =
|
||||||
|
bt_mesh_adv_types_mgnt_get(BLE_MESH_ADV_RELAY_DATA)->adv_q->q.handle;
|
||||||
#endif
|
#endif
|
||||||
bt_mesh_msg_t msg = {0};
|
bt_mesh_msg_t msg = {0};
|
||||||
struct net_buf **buf = NULL;
|
struct net_buf **buf = NULL;
|
||||||
@ -359,28 +204,28 @@ static void adv_thread(void *p)
|
|||||||
#if !CONFIG_BLE_MESH_RELAY_ADV_BUF
|
#if !CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||||
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
|
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
|
||||||
CONFIG_BLE_MESH_GATT_PROXY_SERVER
|
CONFIG_BLE_MESH_GATT_PROXY_SERVER
|
||||||
xQueueReceive(adv_queue.handle, &msg, K_NO_WAIT);
|
xQueueReceive(adv_queue->q.handle, &msg, K_NO_WAIT);
|
||||||
while (!(*buf)) {
|
while (!(*buf)) {
|
||||||
int32_t timeout = 0;
|
int32_t timeout = 0;
|
||||||
BT_DBG("Mesh Proxy Advertising start");
|
BT_DBG("Mesh Proxy Advertising start");
|
||||||
timeout = bt_mesh_proxy_server_adv_start();
|
timeout = bt_mesh_proxy_server_adv_start();
|
||||||
BT_DBG("Mesh Proxy Advertising up to %d ms", timeout);
|
BT_DBG("Mesh Proxy Advertising up to %d ms", timeout);
|
||||||
xQueueReceive(adv_queue.handle, &msg, K_WAIT(timeout));
|
xQueueReceive(adv_queue->q.handle, &msg, K_WAIT(timeout));
|
||||||
BT_DBG("Mesh Proxy Advertising stop");
|
BT_DBG("Mesh Proxy Advertising stop");
|
||||||
bt_mesh_proxy_server_adv_stop();
|
bt_mesh_proxy_server_adv_stop();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
xQueueReceive(adv_queue.handle, &msg, portMAX_DELAY);
|
xQueueReceive(adv_queue->q.handle, &msg, portMAX_DELAY);
|
||||||
#endif /* (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_SERVER */
|
#endif /* (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_SERVER */
|
||||||
#else /* !CONFIG_BLE_MESH_RELAY_ADV_BUF */
|
#else /* !CONFIG_BLE_MESH_RELAY_ADV_BUF */
|
||||||
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
|
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
|
||||||
CONFIG_BLE_MESH_GATT_PROXY_SERVER
|
CONFIG_BLE_MESH_GATT_PROXY_SERVER
|
||||||
handle = xQueueSelectFromSet(mesh_queue_set, K_NO_WAIT);
|
handle = xQueueSelectFromSet(mesh_queue_set, K_NO_WAIT);
|
||||||
if (handle) {
|
if (handle) {
|
||||||
if (uxQueueMessagesWaiting(adv_queue.handle)) {
|
if (uxQueueMessagesWaiting(adv_queue->q.handle)) {
|
||||||
xQueueReceive(adv_queue.handle, &msg, K_NO_WAIT);
|
xQueueReceive(adv_queue->q.handle, &msg, K_NO_WAIT);
|
||||||
} else if (uxQueueMessagesWaiting(relay_queue.handle)) {
|
} else if (uxQueueMessagesWaiting(relay_adv_handle)) {
|
||||||
xQueueReceive(relay_queue.handle, &msg, K_NO_WAIT);
|
xQueueReceive(relay_adv_handle, &msg, K_NO_WAIT);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (!(*buf)) {
|
while (!(*buf)) {
|
||||||
@ -392,10 +237,10 @@ static void adv_thread(void *p)
|
|||||||
BT_DBG("Mesh Proxy Advertising stop");
|
BT_DBG("Mesh Proxy Advertising stop");
|
||||||
bt_mesh_proxy_server_adv_stop();
|
bt_mesh_proxy_server_adv_stop();
|
||||||
if (handle) {
|
if (handle) {
|
||||||
if (uxQueueMessagesWaiting(adv_queue.handle)) {
|
if (uxQueueMessagesWaiting(adv_queue->q.handle)) {
|
||||||
xQueueReceive(adv_queue.handle, &msg, K_NO_WAIT);
|
xQueueReceive(adv_queue->q.handle, &msg, K_NO_WAIT);
|
||||||
} else if (uxQueueMessagesWaiting(relay_queue.handle)) {
|
} else if (uxQueueMessagesWaiting(relay_adv_handle)) {
|
||||||
xQueueReceive(relay_queue.handle, &msg, K_NO_WAIT);
|
xQueueReceive(relay_adv_handle, &msg, K_NO_WAIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -403,10 +248,10 @@ static void adv_thread(void *p)
|
|||||||
#else
|
#else
|
||||||
handle = xQueueSelectFromSet(mesh_queue_set, portMAX_DELAY);
|
handle = xQueueSelectFromSet(mesh_queue_set, portMAX_DELAY);
|
||||||
if (handle) {
|
if (handle) {
|
||||||
if (uxQueueMessagesWaiting(adv_queue.handle)) {
|
if (uxQueueMessagesWaiting(adv_queue->q.handle)) {
|
||||||
xQueueReceive(adv_queue.handle, &msg, K_NO_WAIT);
|
xQueueReceive(adv_queue->q.handle, &msg, K_NO_WAIT);
|
||||||
} else if (uxQueueMessagesWaiting(relay_queue.handle)) {
|
} else if (uxQueueMessagesWaiting(relay_adv_handle)) {
|
||||||
xQueueReceive(relay_queue.handle, &msg, K_NO_WAIT);
|
xQueueReceive(relay_adv_handle, &msg, K_NO_WAIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_SERVER */
|
#endif /* (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_SERVER */
|
||||||
@ -423,7 +268,7 @@ static void adv_thread(void *p)
|
|||||||
BT_WARN("Failed to send adv packet");
|
BT_WARN("Failed to send adv packet");
|
||||||
}
|
}
|
||||||
#else /* !CONFIG_BLE_MESH_RELAY_ADV_BUF */
|
#else /* !CONFIG_BLE_MESH_RELAY_ADV_BUF */
|
||||||
if (msg.relay && ignore_relay_packet(msg.timestamp)) {
|
if (msg.relay && bt_mesh_ignore_relay_packet(msg.timestamp)) {
|
||||||
/* If the interval between "current time - msg.timestamp" is bigger than
|
/* If the interval between "current time - msg.timestamp" is bigger than
|
||||||
* BLE_MESH_RELAY_TIME_INTERVAL, this relay packet will not be sent.
|
* BLE_MESH_RELAY_TIME_INTERVAL, this relay packet will not be sent.
|
||||||
*/
|
*/
|
||||||
@ -445,119 +290,6 @@ static void adv_thread(void *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct net_buf *bt_mesh_adv_create_from_pool(struct net_buf_pool *pool,
|
|
||||||
bt_mesh_adv_alloc_t get_id,
|
|
||||||
enum bt_mesh_adv_type type,
|
|
||||||
int32_t timeout)
|
|
||||||
{
|
|
||||||
struct bt_mesh_adv *adv = NULL;
|
|
||||||
struct net_buf *buf = NULL;
|
|
||||||
|
|
||||||
if (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_SUSPENDED)) {
|
|
||||||
BT_WARN("Refusing to allocate buffer while suspended");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = net_buf_alloc(pool, timeout);
|
|
||||||
if (!buf) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
BT_DBG("pool %p, buf_count %d, uinit_count %d",
|
|
||||||
buf->pool, pool->buf_count, pool->uninit_count);
|
|
||||||
|
|
||||||
adv = get_id(net_buf_id(buf));
|
|
||||||
BLE_MESH_ADV(buf) = adv;
|
|
||||||
|
|
||||||
(void)memset(adv, 0, sizeof(*adv));
|
|
||||||
|
|
||||||
adv->type = type;
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bt_mesh_unref_buf_from_pool(struct net_buf_pool *pool)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (pool == NULL) {
|
|
||||||
BT_ERR("%s, Invalid parameter", __func__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < pool->buf_count; i++) {
|
|
||||||
struct net_buf *buf = &pool->__bufs[i];
|
|
||||||
if (buf->ref > 1U) {
|
|
||||||
buf->ref = 1U;
|
|
||||||
}
|
|
||||||
net_buf_unref(buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, int32_t timeout)
|
|
||||||
{
|
|
||||||
return bt_mesh_adv_create_from_pool(&adv_buf_pool, adv_alloc,
|
|
||||||
type, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bt_mesh_adv_buf_ref_debug(const char *func, struct net_buf *buf,
|
|
||||||
uint8_t ref_cmp, bt_mesh_buf_ref_flag_t flag)
|
|
||||||
{
|
|
||||||
if (buf == NULL || func == NULL || flag >= BLE_MESH_BUF_REF_MAX) {
|
|
||||||
BT_ERR("%s, Invalid parameter", __func__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (flag) {
|
|
||||||
case BLE_MESH_BUF_REF_EQUAL:
|
|
||||||
if (buf->ref != ref_cmp) {
|
|
||||||
BT_ERR("Unexpected ref %d in %s, expect to equal to %d", buf->ref, func, ref_cmp);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BLE_MESH_BUF_REF_SMALL:
|
|
||||||
if (buf->ref >= ref_cmp) {
|
|
||||||
BT_ERR("Unexpected ref %d in %s, expect to smaller than %d", buf->ref, func, ref_cmp);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bt_mesh_unref_buf(bt_mesh_msg_t *msg)
|
|
||||||
{
|
|
||||||
struct net_buf *buf = NULL;
|
|
||||||
|
|
||||||
if (msg->arg) {
|
|
||||||
buf = (struct net_buf *)msg->arg;
|
|
||||||
bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 0);
|
|
||||||
if (buf->ref > 1U) {
|
|
||||||
buf->ref = 1U;
|
|
||||||
}
|
|
||||||
net_buf_unref(buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bt_mesh_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front)
|
|
||||||
{
|
|
||||||
if (adv_queue.handle == NULL) {
|
|
||||||
BT_ERR("Invalid adv queue");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (front) {
|
|
||||||
if (xQueueSendToFront(adv_queue.handle, msg, timeout) != pdTRUE) {
|
|
||||||
BT_ERR("Failed to send item to adv queue front");
|
|
||||||
bt_mesh_unref_buf(msg);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (xQueueSend(adv_queue.handle, msg, timeout) != pdTRUE) {
|
|
||||||
BT_ERR("Failed to send item to adv queue back");
|
|
||||||
bt_mesh_unref_buf(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void bt_mesh_adv_send(struct net_buf *buf, uint8_t xmit,
|
void bt_mesh_adv_send(struct net_buf *buf, uint8_t xmit,
|
||||||
const struct bt_mesh_send_cb *cb,
|
const struct bt_mesh_send_cb *cb,
|
||||||
void *cb_data)
|
void *cb_data)
|
||||||
@ -590,481 +322,55 @@ void bt_mesh_adv_update(void)
|
|||||||
bt_mesh_task_post(&msg, K_NO_WAIT, false);
|
bt_mesh_task_post(&msg, K_NO_WAIT, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
|
||||||
static bool ignore_relay_packet(uint32_t timestamp)
|
|
||||||
{
|
|
||||||
uint32_t now = k_uptime_get_32();
|
|
||||||
uint32_t interval = 0U;
|
|
||||||
|
|
||||||
if (now >= timestamp) {
|
|
||||||
interval = now - timestamp;
|
|
||||||
} else {
|
|
||||||
interval = BLE_MESH_MAX_TIME_INTERVAL - (timestamp - now) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (interval >= BLE_MESH_RELAY_TIME_INTERVAL) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct bt_mesh_adv *relay_adv_alloc(int id)
|
|
||||||
{
|
|
||||||
return &relay_adv_pool[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
struct net_buf *bt_mesh_relay_adv_create(enum bt_mesh_adv_type type, int32_t timeout)
|
|
||||||
{
|
|
||||||
return bt_mesh_adv_create_from_pool(&relay_adv_buf_pool, relay_adv_alloc,
|
|
||||||
type, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ble_mesh_relay_task_post(bt_mesh_msg_t *msg, uint32_t timeout)
|
|
||||||
{
|
|
||||||
QueueSetMemberHandle_t handle = NULL;
|
|
||||||
bt_mesh_msg_t old_msg = {0};
|
|
||||||
|
|
||||||
if (relay_queue.handle == NULL) {
|
|
||||||
BT_ERR("Invalid relay queue");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xQueueSend(relay_queue.handle, msg, timeout) == pdTRUE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If failed to send packet to the relay queue(queue is full), we will
|
|
||||||
* remove the oldest packet in the queue and put the new one into it.
|
|
||||||
*/
|
|
||||||
handle = xQueueSelectFromSet(mesh_queue_set, K_NO_WAIT);
|
|
||||||
if (handle && uxQueueMessagesWaiting(relay_queue.handle)) {
|
|
||||||
BT_INFO("Full queue, remove the oldest relay packet");
|
|
||||||
/* Remove the oldest relay packet from queue */
|
|
||||||
if (xQueueReceive(relay_queue.handle, &old_msg, K_NO_WAIT) != pdTRUE) {
|
|
||||||
BT_ERR("Failed to remove item from relay queue");
|
|
||||||
bt_mesh_unref_buf(msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* Unref buf used for the oldest relay packet */
|
|
||||||
bt_mesh_unref_buf(&old_msg);
|
|
||||||
/* Send the latest relay packet to queue */
|
|
||||||
if (xQueueSend(relay_queue.handle, msg, K_NO_WAIT) != pdTRUE) {
|
|
||||||
BT_ERR("Failed to send item to relay queue");
|
|
||||||
bt_mesh_unref_buf(msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
BT_WARN("Empty queue, but failed to send the relay packet");
|
|
||||||
bt_mesh_unref_buf(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void bt_mesh_relay_adv_send(struct net_buf *buf, uint8_t xmit,
|
|
||||||
uint16_t src, uint16_t dst,
|
|
||||||
const struct bt_mesh_send_cb *cb,
|
|
||||||
void *cb_data)
|
|
||||||
{
|
|
||||||
bt_mesh_msg_t msg = {
|
|
||||||
.relay = true,
|
|
||||||
};
|
|
||||||
|
|
||||||
BT_DBG("type 0x%02x len %u: %s", BLE_MESH_ADV(buf)->type, buf->len,
|
|
||||||
bt_hex(buf->data, buf->len));
|
|
||||||
|
|
||||||
BLE_MESH_ADV(buf)->cb = cb;
|
|
||||||
BLE_MESH_ADV(buf)->cb_data = cb_data;
|
|
||||||
bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1);
|
|
||||||
BLE_MESH_ADV(buf)->xmit = xmit;
|
|
||||||
|
|
||||||
msg.arg = (void *)net_buf_ref(buf);
|
|
||||||
msg.src = src;
|
|
||||||
msg.dst = dst;
|
|
||||||
msg.timestamp = k_uptime_get_32();
|
|
||||||
/* Use K_NO_WAIT here, if relay_queue is full return immediately */
|
|
||||||
ble_mesh_relay_task_post(&msg, K_NO_WAIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t bt_mesh_get_stored_relay_count(void)
|
|
||||||
{
|
|
||||||
return (uint16_t)uxQueueMessagesWaiting(relay_queue.handle);
|
|
||||||
}
|
|
||||||
#endif /* #if CONFIG_BLE_MESH_RELAY_ADV_BUF */
|
|
||||||
|
|
||||||
void bt_mesh_adv_init(void)
|
void bt_mesh_adv_init(void)
|
||||||
{
|
{
|
||||||
#if !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
|
|
||||||
adv_queue.handle = xQueueCreate(BLE_MESH_ADV_QUEUE_SIZE, sizeof(bt_mesh_msg_t));
|
|
||||||
__ASSERT(adv_queue.handle, "Failed to create queue");
|
|
||||||
#else /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
|
|
||||||
#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
|
|
||||||
adv_queue.buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
|
||||||
#elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
|
|
||||||
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);
|
|
||||||
#endif
|
|
||||||
__ASSERT(adv_queue.buffer, "Failed to create queue buffer");
|
|
||||||
#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
|
|
||||||
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);
|
|
||||||
#elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
|
|
||||||
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);
|
|
||||||
#endif
|
|
||||||
__ASSERT(adv_queue.storage, "Failed to create queue storage");
|
|
||||||
adv_queue.handle = xQueueCreateStatic(BLE_MESH_ADV_QUEUE_SIZE, sizeof(bt_mesh_msg_t), (uint8_t*)adv_queue.storage, adv_queue.buffer);
|
|
||||||
__ASSERT(adv_queue.handle, "Failed to create static queue");
|
|
||||||
#endif /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
|
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||||
#if !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
|
bt_mesh_relay_adv_init();
|
||||||
relay_queue.handle = xQueueCreate(BLE_MESH_RELAY_QUEUE_SIZE, sizeof(bt_mesh_msg_t));
|
|
||||||
__ASSERT(relay_queue.handle, "Failed to create relay queue");
|
|
||||||
#else /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
|
|
||||||
#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
|
|
||||||
relay_queue.buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
|
||||||
#elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
|
|
||||||
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);
|
|
||||||
#endif
|
#endif
|
||||||
__ASSERT(relay_queue.buffer, "Failed to create relay queue buffer");
|
|
||||||
#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
|
|
||||||
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);
|
|
||||||
#elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
|
|
||||||
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);
|
|
||||||
#endif
|
|
||||||
__ASSERT(relay_queue.storage, "Failed to create relay queue storage");
|
|
||||||
relay_queue.handle = xQueueCreateStatic(BLE_MESH_RELAY_QUEUE_SIZE, sizeof(bt_mesh_msg_t), (uint8_t*)relay_queue.storage, relay_queue.buffer);
|
|
||||||
__ASSERT(relay_queue.handle, "Failed to create static relay queue");
|
|
||||||
#endif /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
|
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||||
|
bt_mesh_ble_adv_init();
|
||||||
|
#endif
|
||||||
|
bt_mesh_adv_common_init();
|
||||||
|
adv_queue = bt_mesh_adv_queue_get();
|
||||||
|
|
||||||
|
assert(adv_queue && adv_queue->q.handle && adv_queue->send);
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_RELAY_ADV_BUF && !CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
QueueHandle_t relay_adv_handle =
|
||||||
|
bt_mesh_adv_types_mgnt_get(BLE_MESH_ADV_RELAY_DATA)->adv_q->q.handle;
|
||||||
mesh_queue_set = xQueueCreateSet(BLE_MESH_QUEUE_SET_SIZE);
|
mesh_queue_set = xQueueCreateSet(BLE_MESH_QUEUE_SET_SIZE);
|
||||||
__ASSERT(mesh_queue_set, "Failed to create queue set");
|
__ASSERT(mesh_queue_set, "Failed to create queue set");
|
||||||
xQueueAddToSet(adv_queue.handle, mesh_queue_set);
|
xQueueAddToSet(adv_queue->q.handle, mesh_queue_set);
|
||||||
xQueueAddToSet(relay_queue.handle, mesh_queue_set);
|
xQueueAddToSet(relay_adv_handle, mesh_queue_set);
|
||||||
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
|
#endif
|
||||||
|
|
||||||
#if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \
|
bt_mesh_adv_task_init(adv_thread);
|
||||||
(CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && \
|
|
||||||
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY)
|
|
||||||
adv_task.task = heap_caps_calloc(1, sizeof(StaticTask_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
|
||||||
__ASSERT(adv_task.task, "Failed to create adv thread task");
|
|
||||||
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);
|
|
||||||
__ASSERT(adv_task.stack, "Failed to create adv thread stack");
|
|
||||||
adv_task.handle = xTaskCreateStaticPinnedToCore(adv_thread, BLE_MESH_ADV_TASK_NAME, BLE_MESH_ADV_TASK_STACK_SIZE, NULL,
|
|
||||||
BLE_MESH_ADV_TASK_PRIO, adv_task.stack, adv_task.task, BLE_MESH_ADV_TASK_CORE);
|
|
||||||
__ASSERT(adv_task.handle, "Failed to create static adv thread");
|
|
||||||
#else /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY */
|
|
||||||
int ret = xTaskCreatePinnedToCore(adv_thread, BLE_MESH_ADV_TASK_NAME, BLE_MESH_ADV_TASK_STACK_SIZE, NULL,
|
|
||||||
BLE_MESH_ADV_TASK_PRIO, &adv_task.handle, BLE_MESH_ADV_TASK_CORE);
|
|
||||||
__ASSERT(ret == pdTRUE, "Failed to create adv thread");
|
|
||||||
(void)ret;
|
|
||||||
#endif /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_DEINIT
|
#if CONFIG_BLE_MESH_DEINIT
|
||||||
void bt_mesh_adv_deinit(void)
|
void bt_mesh_adv_deinit(void)
|
||||||
{
|
{
|
||||||
if (adv_queue.handle == NULL) {
|
/* Adv task must be deinit first */
|
||||||
return;
|
bt_mesh_adv_task_deinit();
|
||||||
}
|
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
|
||||||
bt_mesh_adv_inst_deinit();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
vTaskDelete(adv_task.handle);
|
|
||||||
adv_task.handle = NULL;
|
|
||||||
#if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \
|
|
||||||
(CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && \
|
|
||||||
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY)
|
|
||||||
heap_caps_free(adv_task.stack);
|
|
||||||
adv_task.stack = NULL;
|
|
||||||
heap_caps_free(adv_task.task);
|
|
||||||
adv_task.task = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||||
xQueueRemoveFromSet(adv_queue.handle, mesh_queue_set);
|
QueueHandle_t relay_adv_handle =
|
||||||
xQueueRemoveFromSet(relay_queue.handle, mesh_queue_set);
|
bt_mesh_adv_types_mgnt_get(BLE_MESH_ADV_RELAY_DATA)->adv_q->q.handle;
|
||||||
|
|
||||||
vQueueDelete(relay_queue.handle);
|
|
||||||
relay_queue.handle = NULL;
|
|
||||||
#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
|
|
||||||
heap_caps_free(relay_queue.buffer);
|
|
||||||
relay_queue.buffer = NULL;
|
|
||||||
heap_caps_free(relay_queue.storage);
|
|
||||||
relay_queue.storage = NULL;
|
|
||||||
#endif /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
|
|
||||||
|
|
||||||
bt_mesh_unref_buf_from_pool(&relay_adv_buf_pool);
|
|
||||||
memset(relay_adv_pool, 0, sizeof(relay_adv_pool));
|
|
||||||
|
|
||||||
|
xQueueRemoveFromSet(adv_queue->q.handle, mesh_queue_set);
|
||||||
|
xQueueRemoveFromSet(relay_adv_handle, mesh_queue_set);
|
||||||
vQueueDelete(mesh_queue_set);
|
vQueueDelete(mesh_queue_set);
|
||||||
mesh_queue_set = NULL;
|
mesh_queue_set = NULL;
|
||||||
|
|
||||||
|
bt_mesh_relay_adv_deinit();
|
||||||
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
|
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
|
||||||
|
|
||||||
vQueueDelete(adv_queue.handle);
|
|
||||||
adv_queue.handle = NULL;
|
|
||||||
#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
|
|
||||||
heap_caps_free(adv_queue.buffer);
|
|
||||||
adv_queue.buffer = NULL;
|
|
||||||
heap_caps_free(adv_queue.storage);
|
|
||||||
adv_queue.storage = NULL;
|
|
||||||
#endif /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
|
|
||||||
|
|
||||||
bt_mesh_unref_buf_from_pool(&adv_buf_pool);
|
|
||||||
memset(adv_pool, 0, sizeof(adv_pool));
|
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||||
bt_mesh_ble_adv_deinit();
|
bt_mesh_ble_adv_deinit();
|
||||||
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
|
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
|
||||||
|
|
||||||
|
bt_mesh_adv_common_deinit();
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BLE_MESH_DEINIT */
|
#endif /* CONFIG_BLE_MESH_DEINIT */
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
|
||||||
static struct bt_mesh_adv *ble_adv_alloc(int id)
|
|
||||||
{
|
|
||||||
return &ble_adv_pool[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct net_buf *bt_mesh_ble_adv_create(enum bt_mesh_adv_type type, int32_t timeout)
|
|
||||||
{
|
|
||||||
return bt_mesh_adv_create_from_pool(&ble_adv_buf_pool, ble_adv_alloc,
|
|
||||||
type, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bt_mesh_ble_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
|
|
||||||
void *cb_data, bool front)
|
|
||||||
{
|
|
||||||
bt_mesh_msg_t msg = {
|
|
||||||
.relay = false,
|
|
||||||
};
|
|
||||||
|
|
||||||
BT_DBG("type 0x%02x len %u: %s", BLE_MESH_ADV(buf)->type, buf->len,
|
|
||||||
bt_hex(buf->data, buf->len));
|
|
||||||
|
|
||||||
BLE_MESH_ADV(buf)->cb = cb;
|
|
||||||
BLE_MESH_ADV(buf)->cb_data = cb_data;
|
|
||||||
bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1);
|
|
||||||
|
|
||||||
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
|
|
||||||
|
|
||||||
msg.arg = (void *)net_buf_ref(buf);
|
|
||||||
bt_mesh_task_post(&msg, portMAX_DELAY, front);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ble_adv_tx_reset(struct ble_adv_tx *tx, bool unref)
|
|
||||||
{
|
|
||||||
if (tx->buf == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bt_mesh_atomic_test_bit(tx->flags, TIMER_INIT)) {
|
|
||||||
k_delayed_work_free(&tx->resend);
|
|
||||||
}
|
|
||||||
bt_mesh_atomic_set(tx->flags, 0);
|
|
||||||
memset(&tx->param, 0, sizeof(tx->param));
|
|
||||||
bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(tx->buf), 0);
|
|
||||||
if (unref) {
|
|
||||||
net_buf_unref(tx->buf);
|
|
||||||
}
|
|
||||||
tx->buf = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ble_adv_send_start(uint16_t duration, int err, void *cb_data)
|
|
||||||
{
|
|
||||||
struct ble_adv_tx *tx = cb_data;
|
|
||||||
|
|
||||||
BT_DBG("%s, duration %d, err %d", __func__, duration, err);
|
|
||||||
|
|
||||||
/* If failed to send BLE adv packet, and param->count is not 0
|
|
||||||
* which means the timer has been initialized, here we need to
|
|
||||||
* free the timer.
|
|
||||||
*/
|
|
||||||
if (err) {
|
|
||||||
ble_adv_tx_reset(tx, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ble_adv_send_end(int err, void *cb_data)
|
|
||||||
{
|
|
||||||
struct ble_adv_tx *tx = cb_data;
|
|
||||||
|
|
||||||
BT_DBG("%s, err %d", __func__, err);
|
|
||||||
|
|
||||||
if (err) {
|
|
||||||
ble_adv_tx_reset(tx, true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tx->param.count) {
|
|
||||||
k_delayed_work_submit(&tx->resend, tx->param.period);
|
|
||||||
} else {
|
|
||||||
ble_adv_tx_reset(tx, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct bt_mesh_send_cb ble_adv_send_cb = {
|
|
||||||
.start = ble_adv_send_start,
|
|
||||||
.end = ble_adv_send_end,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void ble_adv_resend(struct k_work *work)
|
|
||||||
{
|
|
||||||
struct ble_adv_tx *tx = CONTAINER_OF(work,
|
|
||||||
struct ble_adv_tx,
|
|
||||||
resend.work);
|
|
||||||
bool front = false;
|
|
||||||
|
|
||||||
if (tx->buf == NULL) {
|
|
||||||
/* The advertising has been cancelled */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
front = (tx->param.priority == BLE_MESH_BLE_ADV_PRIO_HIGH) ? true : false;
|
|
||||||
bt_mesh_ble_adv_send(tx->buf, &ble_adv_send_cb, tx, front);
|
|
||||||
|
|
||||||
if (tx->param.count == SEND_BLE_ADV_INFINITE) {
|
|
||||||
/* Send the BLE advertising packet infinitely */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tx->param.count > 0U) {
|
|
||||||
tx->param.count--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int bt_mesh_start_ble_advertising(const struct bt_mesh_ble_adv_param *param,
|
|
||||||
const struct bt_mesh_ble_adv_data *data, uint8_t *index)
|
|
||||||
{
|
|
||||||
struct ble_adv_tx *tx = NULL;
|
|
||||||
struct net_buf *buf = NULL;
|
|
||||||
bool front = false;
|
|
||||||
|
|
||||||
if (param == NULL || index == NULL) {
|
|
||||||
BT_ERR("%s, Invalid parameter", __func__);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (param->adv_type != BLE_MESH_ADV_DIRECT_IND &&
|
|
||||||
(param->interval < 0x20 || param->interval > 0x4000)) {
|
|
||||||
BT_ERR("Invalid adv interval 0x%04x", param->interval);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (param->adv_type > BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) {
|
|
||||||
BT_ERR("Invalid adv type 0x%02x", param->adv_type);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (param->own_addr_type > BLE_MESH_ADDR_RANDOM_ID) {
|
|
||||||
BT_ERR("Invalid own addr type 0x%02x", param->own_addr_type);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((param->own_addr_type == BLE_MESH_ADDR_PUBLIC_ID ||
|
|
||||||
param->own_addr_type == BLE_MESH_ADDR_RANDOM_ID ||
|
|
||||||
param->adv_type == BLE_MESH_ADV_DIRECT_IND ||
|
|
||||||
param->adv_type == BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) &&
|
|
||||||
param->peer_addr_type > BLE_MESH_ADDR_RANDOM) {
|
|
||||||
BT_ERR("Invalid peer addr type 0x%02x", param->peer_addr_type);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data && (data->adv_data_len > 31 || data->scan_rsp_data_len > 31)) {
|
|
||||||
BT_ERR("Invalid adv data length (adv %d, scan rsp %d)",
|
|
||||||
data->adv_data_len, data->scan_rsp_data_len);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (param->priority > BLE_MESH_BLE_ADV_PRIO_HIGH) {
|
|
||||||
BT_ERR("Invalid adv priority %d", param->priority);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (param->duration < ADV_SCAN_INT(param->interval)) {
|
|
||||||
BT_ERR("Too small duration %dms", param->duration);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = bt_mesh_ble_adv_create(BLE_MESH_ADV_BLE, K_NO_WAIT);
|
|
||||||
if (!buf) {
|
|
||||||
BT_ERR("No empty ble adv buffer");
|
|
||||||
return -ENOBUFS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set advertising data and scan response data */
|
|
||||||
memset(buf->data, 0, buf->size);
|
|
||||||
if (data) {
|
|
||||||
net_buf_add_u8(buf, data->adv_data_len);
|
|
||||||
if (data->adv_data_len) {
|
|
||||||
net_buf_add_mem(buf, data->adv_data, data->adv_data_len);
|
|
||||||
}
|
|
||||||
net_buf_add_u8(buf, data->scan_rsp_data_len);
|
|
||||||
if (data->scan_rsp_data_len) {
|
|
||||||
net_buf_add_mem(buf, data->scan_rsp_data, data->scan_rsp_data_len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*index = net_buf_id(buf);
|
|
||||||
tx = &ble_adv_tx[*index];
|
|
||||||
tx->buf = buf;
|
|
||||||
memcpy(&tx->param, param, sizeof(tx->param));
|
|
||||||
|
|
||||||
front = (tx->param.priority == BLE_MESH_BLE_ADV_PRIO_HIGH) ? true : false;
|
|
||||||
bt_mesh_ble_adv_send(buf, &ble_adv_send_cb, tx, front);
|
|
||||||
if (param->count) {
|
|
||||||
if (k_delayed_work_init(&tx->resend, ble_adv_resend)) {
|
|
||||||
/* If failed to create a timer, the BLE adv packet will be
|
|
||||||
* sent only once. Just give a warning here, and since the
|
|
||||||
* BLE adv packet can be sent, return 0 here.
|
|
||||||
*/
|
|
||||||
BT_WARN("Send BLE adv packet only once");
|
|
||||||
tx->param.count = 0;
|
|
||||||
net_buf_unref(buf);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
bt_mesh_atomic_set_bit(tx->flags, TIMER_INIT);
|
|
||||||
} else {
|
|
||||||
/* Send the BLE advertising packet only once */
|
|
||||||
net_buf_unref(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bt_mesh_stop_ble_advertising(uint8_t index)
|
|
||||||
{
|
|
||||||
struct ble_adv_tx *tx = NULL;
|
|
||||||
bool unref = true;
|
|
||||||
|
|
||||||
if (index >= ARRAY_SIZE(ble_adv_tx)) {
|
|
||||||
BT_ERR("Invalid adv index %d", index);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
tx = &ble_adv_tx[index];
|
|
||||||
|
|
||||||
if (tx->buf == NULL) {
|
|
||||||
BT_WARN("Already stopped, index %d", index);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* busy 1, ref 1; busy 1, ref 2;
|
|
||||||
* busy 0, ref 0; busy 0, ref 1;
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(tx->buf)) &&
|
|
||||||
tx->buf->ref == 1U) {
|
|
||||||
unref = false;
|
|
||||||
}
|
|
||||||
ble_adv_tx_reset(tx, unref);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_DEINIT
|
|
||||||
static void bt_mesh_ble_adv_deinit(void)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < ARRAY_SIZE(ble_adv_tx); i++) {
|
|
||||||
struct ble_adv_tx *tx = &ble_adv_tx[i];
|
|
||||||
ble_adv_tx_reset(tx, false);
|
|
||||||
}
|
|
||||||
bt_mesh_unref_buf_from_pool(&ble_adv_buf_pool);
|
|
||||||
memset(ble_adv_pool, 0, sizeof(ble_adv_pool));
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_BLE_MESH_DEINIT */
|
|
||||||
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
|
|
||||||
|
@ -10,118 +10,30 @@
|
|||||||
#ifndef _ADV_H_
|
#ifndef _ADV_H_
|
||||||
#define _ADV_H_
|
#define _ADV_H_
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
#include "ext_adv.h"
|
||||||
|
#else /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
|
||||||
#include "mesh/atomic.h"
|
#include "mesh/atomic.h"
|
||||||
#include "mesh/access.h"
|
#include "mesh/access.h"
|
||||||
#include "mesh/adapter.h"
|
#include "mesh/adapter.h"
|
||||||
#include "mesh/utils.h"
|
#include "mesh/utils.h"
|
||||||
|
#include "adv_common.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Maximum advertising data payload for a single data type */
|
|
||||||
#define BLE_MESH_ADV_DATA_SIZE 29
|
|
||||||
|
|
||||||
/* The user data is a pointer (4 bytes) to struct bt_mesh_adv */
|
|
||||||
#define BLE_MESH_ADV_USER_DATA_SIZE 4
|
|
||||||
|
|
||||||
#define BLE_MESH_ADV(buf) (*(struct bt_mesh_adv **)net_buf_user_data(buf))
|
|
||||||
#define BLE_MESH_ADV_BUSY(buf) (BLE_MESH_ADV(buf)->busy)
|
|
||||||
|
|
||||||
uint16_t bt_mesh_pdu_duration(uint8_t xmit);
|
|
||||||
|
|
||||||
typedef struct bt_mesh_msg {
|
|
||||||
bool relay; /* Flag indicates if the packet is a relayed one */
|
|
||||||
void *arg; /* Pointer to the struct net_buf */
|
|
||||||
uint16_t src; /* Source address for relay packets */
|
|
||||||
uint16_t dst; /* Destination address for relay packets */
|
|
||||||
uint32_t timestamp; /* Timestamp recorded when the relay packet is posted to queue */
|
|
||||||
} bt_mesh_msg_t;
|
|
||||||
|
|
||||||
enum bt_mesh_adv_type {
|
|
||||||
BLE_MESH_ADV_PROV,
|
|
||||||
BLE_MESH_ADV_DATA,
|
|
||||||
BLE_MESH_ADV_BEACON,
|
|
||||||
BLE_MESH_ADV_URI,
|
|
||||||
BLE_MESH_ADV_BLE,
|
|
||||||
BLE_MESH_ADV_PROXY_SOLIC,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bt_mesh_adv {
|
|
||||||
const struct bt_mesh_send_cb *cb;
|
|
||||||
void *cb_data;
|
|
||||||
|
|
||||||
uint8_t type:3;
|
|
||||||
|
|
||||||
bt_mesh_atomic_t busy;
|
|
||||||
|
|
||||||
uint8_t xmit;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct bt_mesh_adv *(*bt_mesh_adv_alloc_t)(int id);
|
|
||||||
|
|
||||||
struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, int32_t timeout);
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BLE_MESH_BUF_REF_EQUAL,
|
|
||||||
BLE_MESH_BUF_REF_SMALL,
|
|
||||||
BLE_MESH_BUF_REF_MAX,
|
|
||||||
} bt_mesh_buf_ref_flag_t;
|
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
|
||||||
|
|
||||||
#define BLE_MESH_ADV_INS_UNUSED 0xFF
|
|
||||||
#define BLE_MESH_ADV_INS_CNT 1
|
|
||||||
|
|
||||||
struct bt_mesh_adv_inst {
|
|
||||||
uint8_t id;
|
|
||||||
};
|
|
||||||
|
|
||||||
int ble_mesh_adv_task_wakeup(uint16_t adv_inst_id);
|
|
||||||
bool bt_mesh_is_adv_inst_used(uint8_t adv_inst_id);
|
|
||||||
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
|
||||||
|
|
||||||
void bt_mesh_adv_buf_ref_debug(const char *func, struct net_buf *buf,
|
|
||||||
uint8_t ref_cmp, bt_mesh_buf_ref_flag_t flag);
|
|
||||||
|
|
||||||
struct net_buf *bt_mesh_adv_create_from_pool(struct net_buf_pool *pool,
|
|
||||||
bt_mesh_adv_alloc_t get_id,
|
|
||||||
enum bt_mesh_adv_type type,
|
|
||||||
int32_t timeout);
|
|
||||||
|
|
||||||
void bt_mesh_unref_buf_from_pool(struct net_buf_pool *pool);
|
|
||||||
|
|
||||||
void bt_mesh_adv_send(struct net_buf *buf, uint8_t xmit,
|
void bt_mesh_adv_send(struct net_buf *buf, uint8_t xmit,
|
||||||
const struct bt_mesh_send_cb *cb,
|
const struct bt_mesh_send_cb *cb,
|
||||||
void *cb_data);
|
void *cb_data);
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_USE_BLE_50 && (CONFIG_BLE_MESH_GATT_PROXY_SERVER || CONFIG_BLE_MESH_PB_GATT)
|
|
||||||
uint8_t bt_mesh_get_proxy_inst(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct net_buf *bt_mesh_relay_adv_create(enum bt_mesh_adv_type type, int32_t timeout);
|
|
||||||
|
|
||||||
void bt_mesh_relay_adv_send(struct net_buf *buf, uint8_t xmit,
|
|
||||||
uint16_t src, uint16_t dst,
|
|
||||||
const struct bt_mesh_send_cb *cb,
|
|
||||||
void *cb_data);
|
|
||||||
|
|
||||||
uint16_t bt_mesh_get_stored_relay_count(void);
|
|
||||||
|
|
||||||
void bt_mesh_adv_update(void);
|
void bt_mesh_adv_update(void);
|
||||||
|
|
||||||
void bt_mesh_adv_init(void);
|
void bt_mesh_adv_init(void);
|
||||||
void bt_mesh_adv_deinit(void);
|
void bt_mesh_adv_deinit(void);
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
|
||||||
int bt_mesh_start_ble_advertising(const struct bt_mesh_ble_adv_param *param,
|
|
||||||
const struct bt_mesh_ble_adv_data *data, uint8_t *index);
|
|
||||||
|
|
||||||
int bt_mesh_stop_ble_advertising(uint8_t index);
|
|
||||||
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
|
||||||
#endif /* _ADV_H_ */
|
#endif /* _ADV_H_ */
|
||||||
|
680
components/bt/esp_ble_mesh/core/adv_common.c
Normal file
680
components/bt/esp_ble_mesh/core/adv_common.c
Normal file
@ -0,0 +1,680 @@
|
|||||||
|
/* Bluetooth Mesh */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||||
|
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "adv_common.h"
|
||||||
|
#include "net.h"
|
||||||
|
#include "ble_adv.h"
|
||||||
|
|
||||||
|
NET_BUF_POOL_DEFINE(adv_buf_pool, CONFIG_BLE_MESH_ADV_BUF_COUNT,
|
||||||
|
BLE_MESH_ADV_DATA_SIZE, BLE_MESH_ADV_USER_DATA_SIZE, NULL);
|
||||||
|
|
||||||
|
static struct bt_mesh_adv adv_pool[CONFIG_BLE_MESH_ADV_BUF_COUNT];
|
||||||
|
|
||||||
|
static struct bt_mesh_adv_queue adv_queue;
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||||
|
NET_BUF_POOL_DEFINE(relay_adv_buf_pool, CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT,
|
||||||
|
BLE_MESH_ADV_DATA_SIZE, BLE_MESH_ADV_USER_DATA_SIZE, NULL);
|
||||||
|
|
||||||
|
static struct bt_mesh_adv relay_adv_pool[CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT];
|
||||||
|
struct bt_mesh_adv_queue relay_adv_queue;
|
||||||
|
|
||||||
|
#define BLE_MESH_RELAY_TIME_INTERVAL K_SECONDS(6)
|
||||||
|
#define BLE_MESH_MAX_TIME_INTERVAL 0xFFFFFFFF
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_FRIEND
|
||||||
|
/* We reserve one extra buffer for each friendship, since we need to be able
|
||||||
|
* to resend the last sent PDU, which sits separately outside of the queue.
|
||||||
|
*/
|
||||||
|
#define FRIEND_BUF_COUNT ((CONFIG_BLE_MESH_FRIEND_QUEUE_SIZE + 1) * \
|
||||||
|
CONFIG_BLE_MESH_FRIEND_LPN_COUNT)
|
||||||
|
|
||||||
|
NET_BUF_POOL_FIXED_DEFINE(friend_buf_pool, FRIEND_BUF_COUNT,
|
||||||
|
BLE_MESH_ADV_DATA_SIZE, NULL);
|
||||||
|
|
||||||
|
bt_mesh_friend_adv_t frnd_adv_pool[FRIEND_BUF_COUNT];
|
||||||
|
|
||||||
|
struct bt_mesh_adv *bt_mesh_frnd_adv_buf_get(int idx)
|
||||||
|
{
|
||||||
|
frnd_adv_pool[idx].app_idx = BLE_MESH_KEY_UNUSED;
|
||||||
|
return &frnd_adv_pool[idx].adv;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct bt_mesh_adv_task {
|
||||||
|
TaskHandle_t handle;
|
||||||
|
#if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \
|
||||||
|
(CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && \
|
||||||
|
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY)
|
||||||
|
StaticTask_t *task;
|
||||||
|
StackType_t *stack;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct bt_mesh_adv_task adv_task;
|
||||||
|
static struct bt_mesh_adv_type_manager adv_types[BLE_MESH_ADV_TYPES_NUM];
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
|
static struct bt_mesh_adv_inst adv_insts[] = {
|
||||||
|
[BLE_MESH_ADV_INS] = {
|
||||||
|
.id = CONFIG_BLE_MESH_ADV_INST_ID,
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
.busy = false,
|
||||||
|
#endif
|
||||||
|
},
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
|
||||||
|
CONFIG_BLE_MESH_GATT_PROXY_SERVER
|
||||||
|
[BLE_MESH_ADV_PROXY_INS] = {
|
||||||
|
.id = CONFIG_BLE_MESH_PROXY_ADV_INST_ID,
|
||||||
|
.busy = false,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
#if CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE
|
||||||
|
[BLE_MESH_RELAY_ADV_INS] = {
|
||||||
|
.id = CONFIG_BLE_MESH_RELAY_ADV_INST_ID,
|
||||||
|
.busy = false,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
#if CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
|
||||||
|
[BLE_MESH_BLE_ADV_INS] = {
|
||||||
|
.id = CONFIG_BLE_MESH_BLE_ADV_INST_ID,
|
||||||
|
.busy = false,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct bt_mesh_adv_inst *find_adv_inst_with_inst_id(uint8_t id)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(adv_insts); i++) {
|
||||||
|
if (adv_insts[i].id == id) {
|
||||||
|
return &adv_insts[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct bt_mesh_adv_inst *bt_mesh_get_adv_insts_set(void)
|
||||||
|
{
|
||||||
|
return adv_insts;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bt_mesh_is_adv_inst_used(uint8_t adv_inst_id)
|
||||||
|
{
|
||||||
|
return (find_adv_inst_with_inst_id(adv_inst_id) != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bt_mesh_adv_inst_init(enum bt_mesh_adv_inst_type inst_type, uint8_t inst_id)
|
||||||
|
{
|
||||||
|
if (inst_type >= BLE_MESH_ADV_INS_TYPES_NUM) {
|
||||||
|
BT_ERR("Invalid instance type %d", inst_type);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inst_id == BLE_MESH_ADV_INS_UNUSED) {
|
||||||
|
BT_ERR("Invalid instance id %d", inst_id);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
adv_insts[inst_type].id = inst_id;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bt_mesh_adv_inst_deinit(enum bt_mesh_adv_inst_type inst_type)
|
||||||
|
{
|
||||||
|
if (inst_type >= BLE_MESH_ADV_INS_TYPES_NUM) {
|
||||||
|
BT_ERR("Invalid instance type %d", inst_type);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bt_le_ext_adv_stop(adv_insts[inst_type].id);
|
||||||
|
|
||||||
|
adv_insts[inst_type].id = BLE_MESH_ADV_INS_UNUSED;
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
adv_insts[inst_type].spt_mask = 0;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||||
|
|
||||||
|
struct bt_mesh_adv *adv_alloc(int id)
|
||||||
|
{
|
||||||
|
return &adv_pool[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct bt_mesh_adv_type_manager *bt_mesh_adv_types_mgnt_get(enum bt_mesh_adv_type adv_type)
|
||||||
|
{
|
||||||
|
return &adv_types[adv_type];
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_adv_buf_ref_debug(const char *func, struct net_buf *buf,
|
||||||
|
uint8_t ref_cmp, bt_mesh_buf_ref_flag_t flag)
|
||||||
|
{
|
||||||
|
if (buf == NULL || func == NULL || flag >= BLE_MESH_BUF_REF_MAX) {
|
||||||
|
BT_ERR("%s, Invalid parameter", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (flag) {
|
||||||
|
case BLE_MESH_BUF_REF_EQUAL:
|
||||||
|
if (buf->ref != ref_cmp) {
|
||||||
|
BT_ERR("Unexpected ref %d in %s, expect to equal to %d", buf->ref, func, ref_cmp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BLE_MESH_BUF_REF_SMALL:
|
||||||
|
if (buf->ref >= ref_cmp) {
|
||||||
|
BT_ERR("Unexpected ref %d in %s, expect to smaller than %d", buf->ref, func, ref_cmp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
void bt_mesh_adv_inst_supported_adv_type_add(enum bt_mesh_adv_inst_type inst_type,
|
||||||
|
enum bt_mesh_adv_type adv_type)
|
||||||
|
{
|
||||||
|
if (inst_type >= BLE_MESH_ADV_INS_TYPES_NUM) {
|
||||||
|
BT_ERR("Invalid instance type %d", inst_type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (adv_type >= BLE_MESH_ADV_TYPES_NUM) {
|
||||||
|
BT_ERR("Invalid adv type %d", adv_type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
adv_insts[inst_type].spt_mask |= BIT(adv_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_adv_inst_supported_adv_type_rm(enum bt_mesh_adv_inst_type inst_type,
|
||||||
|
enum bt_mesh_adv_type adv_type)
|
||||||
|
{
|
||||||
|
if (inst_type >= BLE_MESH_ADV_INS_TYPES_NUM) {
|
||||||
|
BT_ERR("Invalid instance type %d", inst_type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (adv_type >= BLE_MESH_ADV_TYPES_NUM) {
|
||||||
|
BT_ERR("Invalid adv type %d", adv_type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
adv_insts[inst_type].spt_mask &= ~BIT(adv_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_adv_inst_supported_adv_type_clear(enum bt_mesh_adv_inst_type inst_type,
|
||||||
|
enum bt_mesh_adv_type adv_type)
|
||||||
|
{
|
||||||
|
if (inst_type >= BLE_MESH_ADV_INS_TYPES_NUM) {
|
||||||
|
BT_ERR("Invalid instance type %d", inst_type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (adv_type >= BLE_MESH_ADV_TYPES_NUM) {
|
||||||
|
BT_ERR("Invalid adv type %d", adv_type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
adv_insts[inst_type].spt_mask = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int bt_mesh_adv_queue_init(struct bt_mesh_adv_queue *adv_queue, uint16_t queue_size,
|
||||||
|
bt_mesh_adv_queue_send_cb_t cb)
|
||||||
|
{
|
||||||
|
if (!adv_queue || !queue_size || !cb) {
|
||||||
|
BT_ERR("Invalid param %s", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bt_mesh_queue_init(&adv_queue->q, queue_size, sizeof(bt_mesh_msg_t));
|
||||||
|
|
||||||
|
adv_queue->send = cb;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bt_mesh_adv_queue_deinit(struct bt_mesh_adv_queue *adv_queue)
|
||||||
|
{
|
||||||
|
if (!adv_queue) {
|
||||||
|
BT_ERR("Invalid param %s", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bt_mesh_queue_deinit(&adv_queue->q);
|
||||||
|
|
||||||
|
adv_queue->send = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_adv_type_init(enum bt_mesh_adv_type adv_type,
|
||||||
|
struct bt_mesh_adv_queue *adv_queue,
|
||||||
|
struct net_buf_pool *buf_pool,
|
||||||
|
bt_mesh_pool_allocator_t adv_alloc)
|
||||||
|
{
|
||||||
|
if (adv_type >= BLE_MESH_ADV_TYPES_NUM) {
|
||||||
|
BT_ERR("%s Invalid adv type %d",__func__, adv_type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!adv_queue || !buf_pool || !adv_alloc) {
|
||||||
|
BT_ERR("Invalid parameters %s", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
adv_types[adv_type].adv_q = adv_queue;
|
||||||
|
adv_types[adv_type].pool = buf_pool;
|
||||||
|
adv_types[adv_type].pool_allocator = adv_alloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_adv_type_deinit(enum bt_mesh_adv_type adv_type)
|
||||||
|
{
|
||||||
|
if (adv_type >= BLE_MESH_ADV_TYPES_NUM) {
|
||||||
|
BT_ERR("%s Invalid adv type %d",__func__, adv_type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
adv_types[adv_type].adv_q = NULL;
|
||||||
|
adv_types[adv_type].pool = NULL;
|
||||||
|
adv_types[adv_type].pool_allocator = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
|
int ble_mesh_adv_task_wakeup(uint32_t evt)
|
||||||
|
{
|
||||||
|
xTaskNotify(adv_task.handle, evt, eSetBits);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ble_mesh_adv_task_wait(uint32_t wait_bits, uint32_t timeout, uint32_t *notify)
|
||||||
|
{
|
||||||
|
return (xTaskNotifyWait(wait_bits, UINT32_MAX, notify, K_WAIT(timeout)) == pdTRUE);
|
||||||
|
}
|
||||||
|
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||||
|
bool ble_mesh_adv_task_wait(uint32_t timeout)
|
||||||
|
{
|
||||||
|
vTaskDelay(K_WAIT(timeout));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||||
|
|
||||||
|
uint16_t bt_mesh_pdu_duration(uint8_t xmit)
|
||||||
|
{
|
||||||
|
uint16_t duration = 0U;
|
||||||
|
uint16_t adv_int = 0U;
|
||||||
|
|
||||||
|
adv_int = MAX(ADV_ITVL_MIN, BLE_MESH_TRANSMIT_INT(xmit));
|
||||||
|
duration = (BLE_MESH_TRANSMIT_COUNT(xmit) + 1) * (adv_int + 10);
|
||||||
|
|
||||||
|
return duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct net_buf *bt_mesh_adv_create_from_pool(enum bt_mesh_adv_type type,
|
||||||
|
int32_t timeout)
|
||||||
|
{
|
||||||
|
struct bt_mesh_adv *adv = NULL;
|
||||||
|
struct net_buf *buf = NULL;
|
||||||
|
struct net_buf_pool *pool = adv_types[type].pool;
|
||||||
|
|
||||||
|
if (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_SUSPENDED)) {
|
||||||
|
BT_WARN("Refusing to allocate buffer while suspended");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pool || !adv_types[type].pool_allocator) {
|
||||||
|
BT_ERR("Uninitialized adv type %d", type);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = net_buf_alloc(pool, timeout);
|
||||||
|
if (!buf) {
|
||||||
|
BT_WARN("Buf alloc failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BT_DBG("pool %p, buf_count %d, uinit_count %d, ref %d",
|
||||||
|
buf->pool, pool->buf_count, pool->uninit_count, buf->ref);
|
||||||
|
|
||||||
|
adv = adv_types[type].pool_allocator(net_buf_id(buf));
|
||||||
|
BLE_MESH_ADV(buf) = adv;
|
||||||
|
|
||||||
|
(void)memset(adv, 0, sizeof(*adv));
|
||||||
|
|
||||||
|
adv->type = type;
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_unref_buf_from_pool(struct net_buf_pool *pool)
|
||||||
|
{
|
||||||
|
if (pool == NULL) {
|
||||||
|
BT_ERR("%s, Invalid parameter", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < pool->buf_count; i++) {
|
||||||
|
struct net_buf *buf = &pool->__bufs[i];
|
||||||
|
if (buf->ref > 1U) {
|
||||||
|
buf->ref = 1U;
|
||||||
|
}
|
||||||
|
net_buf_unref(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_unref_buf(bt_mesh_msg_t *msg)
|
||||||
|
{
|
||||||
|
struct net_buf *buf = NULL;
|
||||||
|
|
||||||
|
if (msg->arg) {
|
||||||
|
buf = (struct net_buf *)msg->arg;
|
||||||
|
bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 0);
|
||||||
|
if (buf->ref > 1U) {
|
||||||
|
buf->ref = 1U;
|
||||||
|
}
|
||||||
|
net_buf_unref(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_generic_adv_send(struct net_buf *buf, uint8_t xmit,
|
||||||
|
const struct bt_mesh_send_cb *cb,
|
||||||
|
void *cb_data, uint16_t src,
|
||||||
|
uint16_t dst, bool front)
|
||||||
|
{
|
||||||
|
bt_mesh_msg_t msg = {
|
||||||
|
.relay = false, /* useless flag in multi-instance mode */
|
||||||
|
};
|
||||||
|
|
||||||
|
BT_DBG("type 0x%02x len %u: %s", BLE_MESH_ADV(buf)->type, buf->len,
|
||||||
|
bt_hex(buf->data, buf->len));
|
||||||
|
|
||||||
|
BLE_MESH_ADV(buf)->cb = cb;
|
||||||
|
BLE_MESH_ADV(buf)->cb_data = cb_data;
|
||||||
|
bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1);
|
||||||
|
BLE_MESH_ADV(buf)->xmit = xmit;
|
||||||
|
|
||||||
|
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
|
||||||
|
|
||||||
|
msg.arg = (void *)net_buf_ref(buf);
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||||
|
if (BLE_MESH_ADV(buf)->type == BLE_MESH_ADV_RELAY_DATA) {
|
||||||
|
msg.relay = true;
|
||||||
|
msg.src = src;
|
||||||
|
msg.dst = dst;
|
||||||
|
msg.timestamp = k_uptime_get_32();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
assert(adv_types[BLE_MESH_ADV(buf)->type].adv_q && adv_types[BLE_MESH_ADV(buf)->type].adv_q->send);
|
||||||
|
|
||||||
|
adv_types[BLE_MESH_ADV(buf)->type].adv_q->send(&msg, portMAX_DELAY, front);
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
ble_mesh_adv_task_wakeup(ADV_TASK_PKT_SEND_EVT);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
struct bt_mesh_adv_queue *bt_mesh_adv_queue_get(void)
|
||||||
|
{
|
||||||
|
return &adv_queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front)
|
||||||
|
{
|
||||||
|
if (adv_queue.q.handle == NULL) {
|
||||||
|
BT_ERR("Invalid adv queue");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (front) {
|
||||||
|
if (xQueueSendToFront(adv_queue.q.handle, msg, timeout) != pdTRUE) {
|
||||||
|
BT_ERR("Failed to send item to adv queue front");
|
||||||
|
bt_mesh_unref_buf(msg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (xQueueSend(adv_queue.q.handle, msg, timeout) != pdTRUE) {
|
||||||
|
BT_ERR("Failed to send item to adv queue back");
|
||||||
|
bt_mesh_unref_buf(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||||
|
bool bt_mesh_ignore_relay_packet(uint32_t timestamp)
|
||||||
|
{
|
||||||
|
uint32_t now = k_uptime_get_32();
|
||||||
|
uint32_t interval = 0U;
|
||||||
|
|
||||||
|
if (now >= timestamp) {
|
||||||
|
interval = now - timestamp;
|
||||||
|
} else {
|
||||||
|
interval = BLE_MESH_MAX_TIME_INTERVAL - (timestamp - now) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((interval >= BLE_MESH_RELAY_TIME_INTERVAL) ? true : false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct bt_mesh_adv *relay_adv_alloc(int id)
|
||||||
|
{
|
||||||
|
return &relay_adv_pool[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct net_buf *bt_mesh_relay_adv_create(enum bt_mesh_adv_type type, int32_t timeout)
|
||||||
|
{
|
||||||
|
return bt_mesh_adv_create_from_pool(type, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ble_mesh_relay_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front)
|
||||||
|
{
|
||||||
|
bt_mesh_msg_t old_msg = {0};
|
||||||
|
|
||||||
|
ARG_UNUSED(front);
|
||||||
|
|
||||||
|
if (relay_adv_queue.q.handle == NULL) {
|
||||||
|
BT_ERR("Invalid relay queue");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xQueueSend(relay_adv_queue.q.handle, msg, timeout) == pdTRUE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If failed to send packet to the relay queue(queue is full), we will
|
||||||
|
* remove the oldest packet in the queue and put the new one into it.
|
||||||
|
*/
|
||||||
|
if (uxQueueMessagesWaiting(relay_adv_queue.q.handle)) {
|
||||||
|
BT_INFO("Full queue, remove the oldest relay packet");
|
||||||
|
/* Remove the oldest relay packet from queue */
|
||||||
|
if (xQueueReceive(relay_adv_queue.q.handle, &old_msg, K_NO_WAIT) != pdTRUE) {
|
||||||
|
BT_ERR("Failed to remove item from relay queue");
|
||||||
|
bt_mesh_unref_buf(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Unref buf used for the oldest relay packet */
|
||||||
|
bt_mesh_unref_buf(&old_msg);
|
||||||
|
/* Send the latest relay packet to queue */
|
||||||
|
if (xQueueSend(relay_adv_queue.q.handle, msg, K_NO_WAIT) != pdTRUE) {
|
||||||
|
BT_ERR("Failed to send item to relay queue");
|
||||||
|
bt_mesh_unref_buf(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
BT_WARN("Empty queue, but failed to send the relay packet");
|
||||||
|
bt_mesh_unref_buf(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t bt_mesh_get_stored_relay_count(void)
|
||||||
|
{
|
||||||
|
return (uint16_t)uxQueueMessagesWaiting(relay_adv_queue.q.handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_relay_adv_init(void)
|
||||||
|
{
|
||||||
|
bt_mesh_adv_queue_init(&relay_adv_queue, CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT,
|
||||||
|
ble_mesh_relay_task_post);
|
||||||
|
bt_mesh_adv_type_init(BLE_MESH_ADV_RELAY_DATA, &relay_adv_queue,
|
||||||
|
&relay_adv_buf_pool, &relay_adv_alloc);
|
||||||
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
|
#if CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE
|
||||||
|
bt_mesh_adv_inst_init(BLE_MESH_RELAY_ADV_INS,
|
||||||
|
CONFIG_BLE_MESH_RELAY_ADV_INST_ID);
|
||||||
|
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_RELAY_ADV_INS, BLE_MESH_ADV_RELAY_DATA);
|
||||||
|
#else
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_RELAY_DATA);
|
||||||
|
#endif
|
||||||
|
#endif /* CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE */
|
||||||
|
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||||
|
}
|
||||||
|
#if CONFIG_BLE_MESH_DEINIT
|
||||||
|
void bt_mesh_relay_adv_deinit(void)
|
||||||
|
{
|
||||||
|
bt_mesh_adv_queue_deinit(&relay_adv_queue);
|
||||||
|
bt_mesh_adv_type_deinit(BLE_MESH_ADV_RELAY_DATA);
|
||||||
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
|
#if CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE
|
||||||
|
bt_mesh_adv_inst_supported_adv_type_rm(BLE_MESH_RELAY_ADV_INS, BLE_MESH_ADV_RELAY_DATA);
|
||||||
|
bt_mesh_adv_inst_deinit(BLE_MESH_RELAY_ADV_INS);
|
||||||
|
#else
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
bt_mesh_adv_inst_supported_adv_type_rm(BLE_MESH_ADV_INS, BLE_MESH_ADV_RELAY_DATA);
|
||||||
|
#endif
|
||||||
|
#endif /* CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE */
|
||||||
|
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||||
|
bt_mesh_unref_buf_from_pool(&relay_adv_buf_pool);
|
||||||
|
memset(relay_adv_pool, 0, sizeof(relay_adv_pool));
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BLE_MESH_DEINIT */
|
||||||
|
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_FRIEND
|
||||||
|
struct net_buf_pool *bt_mesh_frnd_adv_pool_get(void)
|
||||||
|
{
|
||||||
|
return &friend_buf_pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_frnd_adv_init(void)
|
||||||
|
{
|
||||||
|
bt_mesh_adv_type_init(BLE_MESH_ADV_FRIEND, &adv_queue, &friend_buf_pool, bt_mesh_frnd_adv_buf_get);
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_FRIEND);
|
||||||
|
#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_frnd_adv_deinit(void)
|
||||||
|
{
|
||||||
|
bt_mesh_adv_type_deinit(BLE_MESH_ADV_FRIEND);
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_FRIEND && CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
bt_mesh_adv_inst_supported_adv_type_rm(BLE_MESH_ADV_INS, BLE_MESH_ADV_FRIEND);
|
||||||
|
#endif /* CONFIG_BLE_MESH_FRIEND */
|
||||||
|
|
||||||
|
bt_mesh_unref_buf_from_pool(&friend_buf_pool);
|
||||||
|
memset(frnd_adv_pool, 0, sizeof(frnd_adv_pool));
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BLE_MESH_FRIEND */
|
||||||
|
|
||||||
|
void bt_mesh_adv_task_init(void adv_thread(void *p))
|
||||||
|
{
|
||||||
|
if (!adv_thread) {
|
||||||
|
BT_ERR("Invalid param %s", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \
|
||||||
|
(CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && \
|
||||||
|
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY)
|
||||||
|
adv_task.task = heap_caps_calloc(1, sizeof(StaticTask_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||||
|
__ASSERT(adv_task.task, "Failed to create adv thread task");
|
||||||
|
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);
|
||||||
|
__ASSERT(adv_task.stack, "Failed to create adv thread stack");
|
||||||
|
adv_task.handle = xTaskCreateStaticPinnedToCore(adv_thread, BLE_MESH_ADV_TASK_NAME, BLE_MESH_ADV_TASK_STACK_SIZE, NULL,
|
||||||
|
BLE_MESH_ADV_TASK_PRIO, adv_task.stack, adv_task.task, BLE_MESH_ADV_TASK_CORE);
|
||||||
|
__ASSERT(adv_task.handle, "Failed to create static adv thread");
|
||||||
|
#else /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY */
|
||||||
|
int ret = xTaskCreatePinnedToCore(adv_thread, BLE_MESH_ADV_TASK_NAME, BLE_MESH_ADV_TASK_STACK_SIZE, NULL,
|
||||||
|
BLE_MESH_ADV_TASK_PRIO, &adv_task.handle, BLE_MESH_ADV_TASK_CORE);
|
||||||
|
__ASSERT(ret == pdTRUE, "Failed to create adv thread");
|
||||||
|
(void)ret;
|
||||||
|
#endif /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY */
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_adv_common_init(void)
|
||||||
|
{
|
||||||
|
bt_mesh_adv_queue_init(&adv_queue, BLE_MESH_ADV_QUEUE_SIZE, bt_mesh_task_post);
|
||||||
|
bt_mesh_adv_type_init(BLE_MESH_ADV_PROV, &adv_queue, &adv_buf_pool, adv_alloc);
|
||||||
|
bt_mesh_adv_type_init(BLE_MESH_ADV_DATA, &adv_queue, &adv_buf_pool, adv_alloc);
|
||||||
|
bt_mesh_adv_type_init(BLE_MESH_ADV_BEACON, &adv_queue, &adv_buf_pool, adv_alloc);
|
||||||
|
bt_mesh_adv_type_init(BLE_MESH_ADV_URI, &adv_queue, &adv_buf_pool, adv_alloc);
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
|
bt_mesh_adv_inst_init(BLE_MESH_ADV_INS, CONFIG_BLE_MESH_ADV_INST_ID);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
/**
|
||||||
|
* Due to the limitation of the sequence number in the network layer,
|
||||||
|
* it is not possible to use multiple advertising instances to process
|
||||||
|
* data from the same message queue when sending mesh packets.
|
||||||
|
*
|
||||||
|
* Therefore, shall to check whether there are
|
||||||
|
* duplicates in the queue buffer corresponding to each advertising instance.
|
||||||
|
*/
|
||||||
|
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_PROV);
|
||||||
|
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_DATA);
|
||||||
|
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_BEACON);
|
||||||
|
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_URI);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_DEINIT
|
||||||
|
void bt_mesh_adv_task_deinit(void)
|
||||||
|
{
|
||||||
|
vTaskDelete(adv_task.handle);
|
||||||
|
adv_task.handle = NULL;
|
||||||
|
|
||||||
|
#if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \
|
||||||
|
(CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && \
|
||||||
|
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY)
|
||||||
|
heap_caps_free(adv_task.stack);
|
||||||
|
adv_task.stack = NULL;
|
||||||
|
heap_caps_free(adv_task.task);
|
||||||
|
adv_task.task = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_adv_common_deinit(void)
|
||||||
|
{
|
||||||
|
bt_mesh_adv_type_deinit(BLE_MESH_ADV_PROV);
|
||||||
|
bt_mesh_adv_type_deinit(BLE_MESH_ADV_DATA);
|
||||||
|
bt_mesh_adv_type_deinit(BLE_MESH_ADV_BEACON);
|
||||||
|
bt_mesh_adv_type_deinit(BLE_MESH_ADV_URI);
|
||||||
|
|
||||||
|
bt_mesh_adv_queue_deinit(&adv_queue);
|
||||||
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
|
bt_mesh_adv_inst_deinit(BLE_MESH_ADV_INS);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bt_mesh_unref_buf_from_pool(&adv_buf_pool);
|
||||||
|
memset(adv_pool, 0, sizeof(adv_pool));
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BLE_MESH_DEINIT */
|
290
components/bt/esp_ble_mesh/core/adv_common.h
Normal file
290
components/bt/esp_ble_mesh/core/adv_common.h
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
/* Bluetooth Mesh */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||||
|
* SPDX-FileContributor: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ADV_COMMON_H_
|
||||||
|
#define _ADV_COMMON_H_
|
||||||
|
|
||||||
|
#include "mesh/common.h"
|
||||||
|
#include "mesh/atomic.h"
|
||||||
|
#include "mesh/access.h"
|
||||||
|
#include "mesh/adapter.h"
|
||||||
|
#include "mesh/queue.h"
|
||||||
|
#include "mesh/timer.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Pre-5.0 controllers enforce a minimum interval of 100ms
|
||||||
|
* whereas 5.0+ controllers can go down to 20ms.
|
||||||
|
*/
|
||||||
|
#if CONFIG_BLE_MESH_HCI_5_0
|
||||||
|
#define ADV_ITVL_MIN 20
|
||||||
|
#else
|
||||||
|
#define ADV_ITVL_MIN 100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Convert from ms to 0.625ms units */
|
||||||
|
#define ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5)
|
||||||
|
/* Convert from 0.625ms units to interval(ms) */
|
||||||
|
#define ADV_SCAN_INT(val) ((val) * 5 / 8)
|
||||||
|
|
||||||
|
/* Maximum advertising data payload for a single data type */
|
||||||
|
#define BLE_MESH_ADV_DATA_SIZE 29
|
||||||
|
|
||||||
|
/* The user data is a pointer (4 bytes) to struct bt_mesh_adv */
|
||||||
|
#define BLE_MESH_ADV_USER_DATA_SIZE 4
|
||||||
|
|
||||||
|
#define BLE_MESH_ADV(buf) (*(struct bt_mesh_adv **)net_buf_user_data(buf))
|
||||||
|
#define BLE_MESH_ADV_BUSY(buf) (BLE_MESH_ADV(buf)->busy)
|
||||||
|
|
||||||
|
#define BLE_MESH_MSG_NET_BUF(msg) ((struct net_buf *)(msg->arg))
|
||||||
|
|
||||||
|
#define BLE_MESH_ADV_INS_UNUSED 0xFF
|
||||||
|
|
||||||
|
/* We reserve one queue item for bt_mesh_adv_update() */
|
||||||
|
#define BLE_MESH_ADV_QUEUE_SIZE (CONFIG_BLE_MESH_ADV_BUF_COUNT + 1)
|
||||||
|
|
||||||
|
struct bt_mesh_adv {
|
||||||
|
const struct bt_mesh_send_cb *cb;
|
||||||
|
void *cb_data;
|
||||||
|
|
||||||
|
uint8_t type;
|
||||||
|
|
||||||
|
bt_mesh_atomic_t busy;
|
||||||
|
|
||||||
|
uint8_t xmit;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_FRIEND
|
||||||
|
|
||||||
|
#define FRIEND_ADV(buf) CONTAINER_OF(BLE_MESH_ADV(buf), bt_mesh_friend_adv_t, adv)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct bt_mesh_adv adv;
|
||||||
|
uint16_t app_idx;
|
||||||
|
} bt_mesh_friend_adv_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum {
|
||||||
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
|
ADV_TASK_MESH_ADV_INST_EVT = BIT(CONFIG_BLE_MESH_ADV_INST_ID),
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
|
||||||
|
CONFIG_BLE_MESH_GATT_PROXY_SERVER
|
||||||
|
ADV_TASK_PROX_ADV_INST_EVT = BIT(CONFIG_BLE_MESH_PROXY_ADV_INST_ID),
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE
|
||||||
|
ADV_TASK_RELAY_ADV_INST_EVT = BIT(CONFIG_BLE_MESH_RELAY_ADV_INST_ID),
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
|
||||||
|
ADV_TASK_BLE_ADV_INST_EVT = BIT(CONFIG_BLE_MESH_BLE_ADV_INST_ID),
|
||||||
|
#endif
|
||||||
|
#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
|
||||||
|
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
|
||||||
|
CONFIG_BLE_MESH_GATT_PROXY_SERVER
|
||||||
|
ADV_TASK_PROXY_ADV_UPD_EVT = BIT(30),
|
||||||
|
#endif
|
||||||
|
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||||
|
ADV_TASK_PKT_SEND_EVT = BIT(31),
|
||||||
|
ADV_TASK_EVT_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint16_t bt_mesh_pdu_duration(uint8_t xmit);
|
||||||
|
|
||||||
|
typedef struct bt_mesh_msg {
|
||||||
|
bool relay; /* Flag indicates if the packet is a relayed one */
|
||||||
|
void *arg; /* Pointer to the struct net_buf */
|
||||||
|
uint16_t src; /* Source address for relay packets */
|
||||||
|
uint16_t dst; /* Destination address for relay packets */
|
||||||
|
uint32_t timestamp; /* Timestamp recorded when the relay packet is posted to queue */
|
||||||
|
} bt_mesh_msg_t;
|
||||||
|
|
||||||
|
typedef struct bt_mesh_adv *(*bt_mesh_pool_allocator_t)(int id);
|
||||||
|
typedef void (*bt_mesh_adv_queue_send_cb_t)(bt_mesh_msg_t *msg, uint32_t timeout, bool front);
|
||||||
|
|
||||||
|
struct bt_mesh_adv_queue {
|
||||||
|
bt_mesh_queue_t q;
|
||||||
|
bt_mesh_adv_queue_send_cb_t send;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bt_mesh_adv_inst {
|
||||||
|
uint8_t id;
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
bool busy;
|
||||||
|
struct net_buf *sending_buf;
|
||||||
|
|
||||||
|
/* indicates that which adv_type is supported by this instance */
|
||||||
|
uint32_t spt_mask;
|
||||||
|
#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
|
||||||
|
};
|
||||||
|
|
||||||
|
enum bt_mesh_adv_type {
|
||||||
|
BLE_MESH_ADV_PROV,
|
||||||
|
BLE_MESH_ADV_DATA,
|
||||||
|
#if CONFIG_BLE_MESH_FRIEND
|
||||||
|
BLE_MESH_ADV_FRIEND,
|
||||||
|
#endif
|
||||||
|
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||||
|
BLE_MESH_ADV_RELAY_DATA,
|
||||||
|
#endif
|
||||||
|
BLE_MESH_ADV_BEACON,
|
||||||
|
BLE_MESH_ADV_URI,
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||||
|
BLE_MESH_ADV_BLE,
|
||||||
|
#endif
|
||||||
|
BLE_MESH_ADV_TYPES_NUM,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BLE_MESH_BUF_REF_EQUAL,
|
||||||
|
BLE_MESH_BUF_REF_SMALL,
|
||||||
|
BLE_MESH_BUF_REF_MAX,
|
||||||
|
} bt_mesh_buf_ref_flag_t;
|
||||||
|
|
||||||
|
struct bt_mesh_adv_type_manager {
|
||||||
|
struct bt_mesh_adv_queue *adv_q;
|
||||||
|
struct net_buf_pool *pool;
|
||||||
|
bt_mesh_pool_allocator_t pool_allocator;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t adv_type[] = {
|
||||||
|
[BLE_MESH_ADV_PROV] = BLE_MESH_DATA_MESH_PROV,
|
||||||
|
[BLE_MESH_ADV_DATA] = BLE_MESH_DATA_MESH_MESSAGE,
|
||||||
|
#if CONFIG_BLE_MESH_FRIEND
|
||||||
|
[BLE_MESH_ADV_FRIEND] = BLE_MESH_DATA_MESH_MESSAGE,
|
||||||
|
#endif
|
||||||
|
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||||
|
[BLE_MESH_ADV_RELAY_DATA] = BLE_MESH_DATA_MESH_MESSAGE,
|
||||||
|
#endif
|
||||||
|
[BLE_MESH_ADV_BEACON] = BLE_MESH_DATA_MESH_BEACON,
|
||||||
|
[BLE_MESH_ADV_URI] = BLE_MESH_DATA_URI,
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline TickType_t K_WAIT(int32_t val)
|
||||||
|
{
|
||||||
|
return (val == K_FOREVER) ? portMAX_DELAY : (val / portTICK_PERIOD_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct bt_mesh_adv_queue *bt_mesh_adv_queue_get(void);
|
||||||
|
|
||||||
|
struct net_buf *bt_mesh_adv_create_from_pool(enum bt_mesh_adv_type type,
|
||||||
|
int32_t timeout);
|
||||||
|
|
||||||
|
static inline struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, int32_t timeout)
|
||||||
|
{
|
||||||
|
return bt_mesh_adv_create_from_pool(type, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_adv_buf_ref_debug(const char *func, struct net_buf *buf,
|
||||||
|
uint8_t ref_cmp, bt_mesh_buf_ref_flag_t flag);
|
||||||
|
|
||||||
|
struct bt_mesh_adv_type_manager *bt_mesh_adv_types_mgnt_get(enum bt_mesh_adv_type adv_type);
|
||||||
|
|
||||||
|
void bt_mesh_generic_adv_send(struct net_buf *buf, uint8_t xmit,
|
||||||
|
const struct bt_mesh_send_cb *cb,
|
||||||
|
void *cb_data, uint16_t src,
|
||||||
|
uint16_t dst, bool front);
|
||||||
|
|
||||||
|
void bt_mesh_unref_buf_from_pool(struct net_buf_pool *pool);
|
||||||
|
void bt_mesh_unref_buf(bt_mesh_msg_t *msg);
|
||||||
|
|
||||||
|
int bt_mesh_adv_queue_init(struct bt_mesh_adv_queue *adv_queue,
|
||||||
|
uint16_t queue_size,
|
||||||
|
bt_mesh_adv_queue_send_cb_t cb);
|
||||||
|
|
||||||
|
int bt_mesh_adv_queue_deinit(struct bt_mesh_adv_queue *adv_queue);
|
||||||
|
|
||||||
|
void bt_mesh_adv_type_init(enum bt_mesh_adv_type adv_type,
|
||||||
|
struct bt_mesh_adv_queue *adv_queue,
|
||||||
|
struct net_buf_pool *buf_pool,
|
||||||
|
bt_mesh_pool_allocator_t adv_alloc);
|
||||||
|
|
||||||
|
void bt_mesh_adv_type_deinit(enum bt_mesh_adv_type adv_type);
|
||||||
|
|
||||||
|
void bt_mesh_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front);
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
|
struct bt_mesh_adv_inst * bt_mesh_get_adv_insts_set(void);
|
||||||
|
int bt_mesh_adv_inst_init(enum bt_mesh_adv_inst_type inst_type, uint8_t inst_id);
|
||||||
|
int bt_mesh_adv_inst_deinit(enum bt_mesh_adv_inst_type inst_type);
|
||||||
|
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
void bt_mesh_adv_inst_supported_adv_type_add(enum bt_mesh_adv_inst_type inst_type,
|
||||||
|
enum bt_mesh_adv_type adv_type);
|
||||||
|
|
||||||
|
void bt_mesh_adv_inst_supported_adv_type_rm(enum bt_mesh_adv_inst_type inst_type,
|
||||||
|
enum bt_mesh_adv_type adv_type);
|
||||||
|
|
||||||
|
void bt_mesh_adv_inst_supported_adv_type_clear(enum bt_mesh_adv_inst_type inst_type,
|
||||||
|
enum bt_mesh_adv_type adv_type);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||||
|
void bt_mesh_relay_adv_init(void);
|
||||||
|
bool bt_mesh_ignore_relay_packet(uint32_t timestamp);
|
||||||
|
struct net_buf *bt_mesh_relay_adv_create(enum bt_mesh_adv_type type, int32_t timeout);
|
||||||
|
|
||||||
|
static inline void bt_mesh_relay_adv_send(struct net_buf *buf, uint8_t xmit,
|
||||||
|
uint16_t src, uint16_t dst,
|
||||||
|
const struct bt_mesh_send_cb *cb,
|
||||||
|
void *cb_data)
|
||||||
|
{
|
||||||
|
bt_mesh_generic_adv_send(buf, xmit, cb, cb_data, src, dst, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
uint16_t bt_mesh_get_stored_relay_count(void);
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_DEINIT
|
||||||
|
void bt_mesh_relay_adv_deinit(void);
|
||||||
|
#endif
|
||||||
|
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_FRIEND
|
||||||
|
struct bt_mesh_adv *bt_mesh_frnd_adv_buf_get(int id);
|
||||||
|
struct net_buf_pool *bt_mesh_frnd_adv_pool_get(void);
|
||||||
|
void bt_mesh_frnd_adv_init(void);
|
||||||
|
#if CONFIG_BLE_MESH_DEINIT
|
||||||
|
void bt_mesh_frnd_adv_deinit(void);
|
||||||
|
#endif /* CONFIG_BLE_MESH_DEINIT */
|
||||||
|
#endif /* CONFIG_BLE_MESH_FRIEND */
|
||||||
|
|
||||||
|
void bt_mesh_adv_task_init(void adv_thread(void *p));
|
||||||
|
void bt_mesh_adv_common_init(void);
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_DEINIT
|
||||||
|
void bt_mesh_adv_task_deinit(void);
|
||||||
|
void bt_mesh_adv_common_deinit(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
|
bool bt_mesh_is_adv_inst_used(uint8_t adv_inst_id);
|
||||||
|
bool ble_mesh_adv_task_wait(uint32_t wait_bits, TickType_t timeout, uint32_t *notify);
|
||||||
|
int ble_mesh_adv_task_wakeup(uint32_t evt);
|
||||||
|
#else
|
||||||
|
bool ble_mesh_adv_task_wait(uint32_t timeout);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||||
|
int bt_mesh_start_ble_advertising(const struct bt_mesh_ble_adv_param *param,
|
||||||
|
const struct bt_mesh_ble_adv_data *data, uint8_t *index);
|
||||||
|
|
||||||
|
int bt_mesh_stop_ble_advertising(uint8_t index);
|
||||||
|
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _ADV_COMMON_H_ */
|
323
components/bt/esp_ble_mesh/core/ble_adv.c
Normal file
323
components/bt/esp_ble_mesh/core/ble_adv.c
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
/* Bluetooth Mesh */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||||
|
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "ble_adv.h"
|
||||||
|
#include "mesh/common.h"
|
||||||
|
#include "mesh/buf.h"
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||||
|
|
||||||
|
static struct bt_mesh_adv_queue ble_adv_queue;
|
||||||
|
#define BLE_MESH_BLE_ADV_QUEUE_SIZE (CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT + 1)
|
||||||
|
/* length + advertising data + length + scan response data */
|
||||||
|
NET_BUF_POOL_DEFINE(ble_adv_buf_pool, CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT,
|
||||||
|
((BLE_MESH_ADV_DATA_SIZE + 3) << 1), BLE_MESH_ADV_USER_DATA_SIZE, NULL);
|
||||||
|
|
||||||
|
static struct bt_mesh_adv ble_adv_pool[CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT];
|
||||||
|
|
||||||
|
static struct bt_mesh_ble_adv_tx ble_adv_tx[CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT];
|
||||||
|
|
||||||
|
#define SEND_BLE_ADV_INFINITE 0xFFFF
|
||||||
|
|
||||||
|
static void bt_mesh_ble_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front);
|
||||||
|
|
||||||
|
static struct bt_mesh_adv *ble_adv_alloc(int id)
|
||||||
|
{
|
||||||
|
return &ble_adv_pool[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bt_mesh_ble_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front)
|
||||||
|
{
|
||||||
|
BT_DBG("%s", __func__);
|
||||||
|
|
||||||
|
if (ble_adv_queue.q.handle == NULL) {
|
||||||
|
BT_ERR("Invalid adv queue");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (front) {
|
||||||
|
if (xQueueSendToFront(ble_adv_queue.q.handle, msg, timeout) != pdTRUE) {
|
||||||
|
BT_ERR("Failed to send item to adv queue front");
|
||||||
|
bt_mesh_unref_buf(msg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (xQueueSend(ble_adv_queue.q.handle, msg, timeout) != pdTRUE) {
|
||||||
|
BT_ERR("Failed to send item to adv queue back");
|
||||||
|
bt_mesh_unref_buf(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct net_buf *bt_mesh_ble_adv_create(enum bt_mesh_adv_type type, int32_t timeout)
|
||||||
|
{
|
||||||
|
return bt_mesh_adv_create_from_pool(type, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void bt_mesh_ble_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
|
||||||
|
void *cb_data, bool front)
|
||||||
|
{
|
||||||
|
bt_mesh_generic_adv_send(buf, 0, cb, cb_data, BLE_MESH_ADDR_UNASSIGNED, BLE_MESH_ADDR_UNASSIGNED, front);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ble_adv_tx_reset(struct bt_mesh_ble_adv_tx *tx, bool unref)
|
||||||
|
{
|
||||||
|
if (tx->buf == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bt_mesh_atomic_test_bit(tx->flags, TIMER_INIT)) {
|
||||||
|
k_delayed_work_free(&tx->resend);
|
||||||
|
}
|
||||||
|
bt_mesh_atomic_set(tx->flags, 0);
|
||||||
|
memset(&tx->param, 0, sizeof(tx->param));
|
||||||
|
bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(tx->buf), 0);
|
||||||
|
if (unref) {
|
||||||
|
net_buf_unref(tx->buf);
|
||||||
|
}
|
||||||
|
tx->buf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ble_adv_send_start(uint16_t duration, int err, void *cb_data)
|
||||||
|
{
|
||||||
|
struct bt_mesh_ble_adv_tx *tx = cb_data;
|
||||||
|
|
||||||
|
BT_DBG("%s, duration %d, err %d", __func__, duration, err);
|
||||||
|
|
||||||
|
/* If failed to send BLE adv packet, and param->count is not 0
|
||||||
|
* which means the timer has been initialized, here we need to
|
||||||
|
* free the timer.
|
||||||
|
*/
|
||||||
|
if (err) {
|
||||||
|
ble_adv_tx_reset(tx, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ble_adv_send_end(int err, void *cb_data)
|
||||||
|
{
|
||||||
|
struct bt_mesh_ble_adv_tx *tx = cb_data;
|
||||||
|
|
||||||
|
BT_DBG("%s, err %d", __func__, err);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
ble_adv_tx_reset(tx, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tx->param.count) {
|
||||||
|
if (tx->param.period) {
|
||||||
|
k_delayed_work_submit(&tx->resend, tx->param.period);
|
||||||
|
} else {
|
||||||
|
k_work_submit(&tx->resend.work);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ble_adv_tx_reset(tx, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct bt_mesh_send_cb ble_adv_send_cb = {
|
||||||
|
.start = ble_adv_send_start,
|
||||||
|
.end = ble_adv_send_end,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void ble_adv_resend(struct k_work *work)
|
||||||
|
{
|
||||||
|
struct bt_mesh_ble_adv_tx *tx = CONTAINER_OF(work, struct bt_mesh_ble_adv_tx, resend.work);
|
||||||
|
bool front = false;
|
||||||
|
|
||||||
|
if (tx->buf == NULL) {
|
||||||
|
/* The advertising has been cancelled */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
front = (tx->param.priority == BLE_MESH_BLE_ADV_PRIO_HIGH) ? true : false;
|
||||||
|
bt_mesh_ble_adv_send(tx->buf, &ble_adv_send_cb, tx, front);
|
||||||
|
|
||||||
|
if (tx->param.count == SEND_BLE_ADV_INFINITE) {
|
||||||
|
/* Send the BLE advertising packet infinitely */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tx->param.count > 0U) {
|
||||||
|
tx->param.count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int bt_mesh_start_ble_advertising(const struct bt_mesh_ble_adv_param *param,
|
||||||
|
const struct bt_mesh_ble_adv_data *data, uint8_t *index)
|
||||||
|
{
|
||||||
|
struct bt_mesh_ble_adv_tx *tx = NULL;
|
||||||
|
struct net_buf *buf = NULL;
|
||||||
|
bool front = false;
|
||||||
|
|
||||||
|
if (param == NULL || index == NULL) {
|
||||||
|
BT_ERR("%s, Invalid parameter", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param->adv_type != BLE_MESH_ADV_DIRECT_IND &&
|
||||||
|
(param->interval < 0x20 || param->interval > 0x4000)) {
|
||||||
|
BT_ERR("Invalid adv interval 0x%04x", param->interval);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param->adv_type > BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) {
|
||||||
|
BT_ERR("Invalid adv type 0x%02x", param->adv_type);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param->own_addr_type > BLE_MESH_ADDR_RANDOM_ID) {
|
||||||
|
BT_ERR("Invalid own addr type 0x%02x", param->own_addr_type);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((param->own_addr_type == BLE_MESH_ADDR_PUBLIC_ID ||
|
||||||
|
param->own_addr_type == BLE_MESH_ADDR_RANDOM_ID ||
|
||||||
|
param->adv_type == BLE_MESH_ADV_DIRECT_IND ||
|
||||||
|
param->adv_type == BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) &&
|
||||||
|
param->peer_addr_type > BLE_MESH_ADDR_RANDOM) {
|
||||||
|
BT_ERR("Invalid peer addr type 0x%02x", param->peer_addr_type);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data && (data->adv_data_len > 31 || data->scan_rsp_data_len > 31)) {
|
||||||
|
BT_ERR("Invalid adv data length (adv %d, scan rsp %d)",
|
||||||
|
data->adv_data_len, data->scan_rsp_data_len);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param->priority > BLE_MESH_BLE_ADV_PRIO_HIGH) {
|
||||||
|
BT_ERR("Invalid adv priority %d", param->priority);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param->duration < ADV_SCAN_INT(param->interval)) {
|
||||||
|
BT_ERR("Too small duration %dms", param->duration);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = bt_mesh_ble_adv_create(BLE_MESH_ADV_BLE, K_NO_WAIT);
|
||||||
|
if (!buf) {
|
||||||
|
BT_ERR("No empty ble adv buffer");
|
||||||
|
return -ENOBUFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set advertising data and scan response data */
|
||||||
|
memset(buf->data, 0, buf->size);
|
||||||
|
if (data) {
|
||||||
|
net_buf_add_u8(buf, data->adv_data_len);
|
||||||
|
if (data->adv_data_len) {
|
||||||
|
net_buf_add_mem(buf, data->adv_data, data->adv_data_len);
|
||||||
|
}
|
||||||
|
net_buf_add_u8(buf, data->scan_rsp_data_len);
|
||||||
|
if (data->scan_rsp_data_len) {
|
||||||
|
net_buf_add_mem(buf, data->scan_rsp_data, data->scan_rsp_data_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*index = net_buf_id(buf);
|
||||||
|
tx = &ble_adv_tx[*index];
|
||||||
|
tx->buf = buf;
|
||||||
|
memcpy(&tx->param, param, sizeof(tx->param));
|
||||||
|
|
||||||
|
front = (tx->param.priority == BLE_MESH_BLE_ADV_PRIO_HIGH) ? true : false;
|
||||||
|
bt_mesh_ble_adv_send(buf, &ble_adv_send_cb, tx, front);
|
||||||
|
if (param->count) {
|
||||||
|
if (k_delayed_work_init(&tx->resend, ble_adv_resend)) {
|
||||||
|
/* If failed to create a timer, the BLE adv packet will be
|
||||||
|
* sent only once. Just give a warning here, and since the
|
||||||
|
* BLE adv packet can be sent, return 0 here.
|
||||||
|
*/
|
||||||
|
BT_WARN("Send BLE adv packet only once");
|
||||||
|
tx->param.count = 0;
|
||||||
|
net_buf_unref(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
bt_mesh_atomic_set_bit(tx->flags, TIMER_INIT);
|
||||||
|
} else {
|
||||||
|
/* Send the BLE advertising packet only once */
|
||||||
|
net_buf_unref(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bt_mesh_stop_ble_advertising(uint8_t index)
|
||||||
|
{
|
||||||
|
struct bt_mesh_ble_adv_tx *tx = NULL;
|
||||||
|
bool unref = true;
|
||||||
|
|
||||||
|
if (index >= ARRAY_SIZE(ble_adv_tx)) {
|
||||||
|
BT_ERR("Invalid adv index %d", index);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tx = &ble_adv_tx[index];
|
||||||
|
|
||||||
|
if (tx->buf == NULL) {
|
||||||
|
BT_WARN("Already stopped, index %d", index);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* busy 1, ref 1; busy 1, ref 2;
|
||||||
|
* busy 0, ref 0; busy 0, ref 1;
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(tx->buf)) &&
|
||||||
|
tx->buf->ref == 1U) {
|
||||||
|
unref = false;
|
||||||
|
}
|
||||||
|
ble_adv_tx_reset(tx, unref);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_ble_adv_init(void)
|
||||||
|
{
|
||||||
|
bt_mesh_adv_queue_init(&ble_adv_queue, CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT, bt_mesh_ble_task_post);
|
||||||
|
bt_mesh_adv_type_init(BLE_MESH_ADV_BLE, &ble_adv_queue, &ble_adv_buf_pool, ble_adv_alloc);
|
||||||
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
|
#if CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
|
||||||
|
bt_mesh_adv_inst_init(BLE_MESH_BLE_ADV_INS, CONFIG_BLE_MESH_BLE_ADV_INST_ID);
|
||||||
|
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_BLE_ADV_INS, BLE_MESH_ADV_BLE);
|
||||||
|
#else
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_BLE);
|
||||||
|
#endif
|
||||||
|
#endif /* CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE */
|
||||||
|
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_DEINIT
|
||||||
|
void bt_mesh_ble_adv_deinit(void)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(ble_adv_tx); i++) {
|
||||||
|
struct bt_mesh_ble_adv_tx *tx = &ble_adv_tx[i];
|
||||||
|
ble_adv_tx_reset(tx, false);
|
||||||
|
}
|
||||||
|
bt_mesh_unref_buf_from_pool(&ble_adv_buf_pool);
|
||||||
|
memset(ble_adv_pool, 0, sizeof(ble_adv_pool));
|
||||||
|
|
||||||
|
bt_mesh_adv_queue_deinit(&ble_adv_queue);
|
||||||
|
bt_mesh_adv_type_deinit(BLE_MESH_ADV_BLE);
|
||||||
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
|
#if CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
|
||||||
|
bt_mesh_adv_inst_deinit(BLE_MESH_BLE_ADV_INS);
|
||||||
|
bt_mesh_adv_inst_supported_adv_type_rm(BLE_MESH_BLE_ADV_INS, BLE_MESH_ADV_BLE);
|
||||||
|
#else
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
bt_mesh_adv_inst_supported_adv_type_rm(BLE_MESH_ADV_INS, BLE_MESH_ADV_BLE);
|
||||||
|
#endif
|
||||||
|
#endif /* CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE */
|
||||||
|
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BLE_MESH_DEINIT */
|
||||||
|
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
|
54
components/bt/esp_ble_mesh/core/ble_adv.h
Normal file
54
components/bt/esp_ble_mesh/core/ble_adv.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/* Bluetooth Mesh */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||||
|
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _BLE_ADV_H_
|
||||||
|
#define _BLE_ADV_H_
|
||||||
|
|
||||||
|
#include "mesh/atomic.h"
|
||||||
|
#include "mesh/access.h"
|
||||||
|
#include "mesh/adapter.h"
|
||||||
|
#include "mesh/utils.h"
|
||||||
|
#include "adv_common.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TIMER_INIT, /* Resend timer is initialized */
|
||||||
|
NUM_FLAGS,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bt_mesh_ble_adv_tx {
|
||||||
|
struct bt_mesh_ble_adv_param param;
|
||||||
|
struct net_buf *buf;
|
||||||
|
struct k_delayed_work resend;
|
||||||
|
BLE_MESH_ATOMIC_DEFINE(flags, NUM_FLAGS);
|
||||||
|
};
|
||||||
|
|
||||||
|
int bt_mesh_start_ble_advertising(const struct bt_mesh_ble_adv_param *param,
|
||||||
|
const struct bt_mesh_ble_adv_data *data, uint8_t *index);
|
||||||
|
|
||||||
|
int bt_mesh_stop_ble_advertising(uint8_t index);
|
||||||
|
|
||||||
|
void bt_mesh_ble_adv_init(void);
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_DEINIT
|
||||||
|
void bt_mesh_ble_adv_deinit(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _BLE_ADV_H_ */
|
@ -109,7 +109,9 @@ static struct bt_mesh_prov_conn_cb *bt_mesh_gattc_conn_cb;
|
|||||||
static tBTA_GATTC_IF bt_mesh_gattc_if;
|
static tBTA_GATTC_IF bt_mesh_gattc_if;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
#if CONFIG_BLE_MESH_USE_BLE_50 && \
|
||||||
|
CONFIG_BLE_MESH_SUPPORT_BLE_ADV && \
|
||||||
|
(!CONFIG_BLE_MESH_SUPPORT_MULTI_ADV)
|
||||||
static inline void bt_mesh_set_ble_adv_running();
|
static inline void bt_mesh_set_ble_adv_running();
|
||||||
|
|
||||||
static inline void bt_mesh_unset_ble_adv_running();
|
static inline void bt_mesh_unset_ble_adv_running();
|
||||||
@ -334,9 +336,12 @@ void ble_mesh_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
|
|||||||
if (!bt_mesh_is_adv_inst_used(params->adv_term.adv_handle)) {
|
if (!bt_mesh_is_adv_inst_used(params->adv_term.adv_handle)) {
|
||||||
goto transfer_to_user;
|
goto transfer_to_user;
|
||||||
}
|
}
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(params->adv_term.adv_handle));
|
||||||
|
#else /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
|
||||||
if (params->adv_term.status == 0x43 || /* Limit reached */
|
if (params->adv_term.status == 0x43 || /* Limit reached */
|
||||||
params->adv_term.status == 0x3C) { /* Advertising timeout */
|
params->adv_term.status == 0x3C) { /* Advertising timeout */
|
||||||
ble_mesh_adv_task_wakeup(params->adv_term.adv_handle);
|
ble_mesh_adv_task_wakeup(ADV_TASK_MESH_ADV_INST_EVT);
|
||||||
}
|
}
|
||||||
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||||
/**
|
/**
|
||||||
@ -359,9 +364,10 @@ void ble_mesh_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
|
|||||||
* could lead to resource contention issues.
|
* could lead to resource contention issues.
|
||||||
*/
|
*/
|
||||||
bt_mesh_unset_ble_adv_running();
|
bt_mesh_unset_ble_adv_running();
|
||||||
ble_mesh_adv_task_wakeup(params->adv_term.adv_handle);
|
ble_mesh_adv_task_wakeup(ADV_TASK_MESH_ADV_INST_EVT);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
|
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
|
||||||
|
#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
|
||||||
break;
|
break;
|
||||||
case BTA_DM_BLE_5_GAP_EXT_ADV_REPORT_EVT:
|
case BTA_DM_BLE_5_GAP_EXT_ADV_REPORT_EVT:
|
||||||
if (!bt_mesh_scan_result_process(¶ms->ext_adv_report)) {
|
if (!bt_mesh_scan_result_process(¶ms->ext_adv_report)) {
|
||||||
@ -821,7 +827,7 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param,
|
|||||||
|
|
||||||
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
|
#if !CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
static bool _ble_adv_running_flag;
|
static bool _ble_adv_running_flag;
|
||||||
|
|
||||||
static inline void bt_mesh_set_ble_adv_running()
|
static inline void bt_mesh_set_ble_adv_running()
|
||||||
@ -838,6 +844,7 @@ static inline bool bt_mesh_is_ble_adv_running()
|
|||||||
{
|
{
|
||||||
return _ble_adv_running_flag == true;
|
return _ble_adv_running_flag == true;
|
||||||
}
|
}
|
||||||
|
#endif /* !CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
|
||||||
|
|
||||||
int bt_mesh_ble_ext_adv_start(const uint8_t inst_id,
|
int bt_mesh_ble_ext_adv_start(const uint8_t inst_id,
|
||||||
const struct bt_mesh_ble_adv_param *param,
|
const struct bt_mesh_ble_adv_param *param,
|
||||||
@ -903,7 +910,9 @@ int bt_mesh_ble_ext_adv_start(const uint8_t inst_id,
|
|||||||
|
|
||||||
BTA_DmBleGapExtAdvEnable(true, 1, &ext_adv);
|
BTA_DmBleGapExtAdvEnable(true, 1, &ext_adv);
|
||||||
|
|
||||||
|
#if !CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
bt_mesh_set_ble_adv_running();
|
bt_mesh_set_ble_adv_running();
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
409
components/bt/esp_ble_mesh/core/ext_adv.c
Normal file
409
components/bt/esp_ble_mesh/core/ext_adv.c
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
/* Bluetooth Mesh */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||||
|
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "mesh/kernel.h"
|
||||||
|
#include "mesh.h"
|
||||||
|
#include "mesh/hci.h"
|
||||||
|
#include "mesh/common.h"
|
||||||
|
#include "mesh/ffs.h"
|
||||||
|
#include "ext_adv.h"
|
||||||
|
#include "beacon.h"
|
||||||
|
#include "prov_common.h"
|
||||||
|
#include "foundation.h"
|
||||||
|
#include "proxy_server.h"
|
||||||
|
#include "proxy_client.h"
|
||||||
|
#include "prov_pvnr.h"
|
||||||
|
#include "mesh/adapter.h"
|
||||||
|
|
||||||
|
#include "adv_common.h"
|
||||||
|
#include "ble_adv.h"
|
||||||
|
|
||||||
|
static struct bt_mesh_adv_queue *adv_queue;
|
||||||
|
|
||||||
|
static struct bt_mesh_adv_inst *adv_insts;
|
||||||
|
|
||||||
|
static inline void adv_send_start(uint16_t duration, int err,
|
||||||
|
const struct bt_mesh_send_cb *cb,
|
||||||
|
void *cb_data)
|
||||||
|
{
|
||||||
|
if (cb && cb->start) {
|
||||||
|
cb->start(duration, err, cb_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void adv_send_end(int err, const struct bt_mesh_send_cb *cb,
|
||||||
|
void *cb_data)
|
||||||
|
{
|
||||||
|
if (cb && cb->end) {
|
||||||
|
cb->end(err, cb_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration)
|
||||||
|
{
|
||||||
|
struct net_buf *buf = inst->sending_buf;
|
||||||
|
const struct bt_mesh_send_cb *cb = BLE_MESH_ADV(buf)->cb;
|
||||||
|
void *cb_data = BLE_MESH_ADV(buf)->cb_data;
|
||||||
|
struct bt_mesh_adv_param param = {0};
|
||||||
|
uint16_t duration = 0U, adv_int = 0U;
|
||||||
|
struct bt_mesh_adv_data ad = {0};
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
BT_DBG("type %u len %u: %s", BLE_MESH_ADV(buf)->type,
|
||||||
|
buf->len, bt_hex(buf->data, buf->len));
|
||||||
|
|
||||||
|
switch (BLE_MESH_ADV(buf)->type) {
|
||||||
|
case BLE_MESH_ADV_PROV:
|
||||||
|
case BLE_MESH_ADV_DATA:
|
||||||
|
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||||
|
case BLE_MESH_ADV_RELAY_DATA:
|
||||||
|
#endif
|
||||||
|
case BLE_MESH_ADV_BEACON:
|
||||||
|
case BLE_MESH_ADV_URI: {
|
||||||
|
adv_int = MAX(ADV_ITVL_MIN,
|
||||||
|
BLE_MESH_TRANSMIT_INT(BLE_MESH_ADV(buf)->xmit));
|
||||||
|
duration = (BLE_MESH_TRANSMIT_COUNT(BLE_MESH_ADV(buf)->xmit) + 1) *
|
||||||
|
(adv_int + 10);
|
||||||
|
|
||||||
|
BT_DBG("count %u interval %ums duration %ums",
|
||||||
|
BLE_MESH_TRANSMIT_COUNT(BLE_MESH_ADV(buf)->xmit) + 1, adv_int,
|
||||||
|
duration);
|
||||||
|
|
||||||
|
ad.type = adv_type[BLE_MESH_ADV(buf)->type];
|
||||||
|
ad.data_len = buf->len;
|
||||||
|
ad.data = buf->data;
|
||||||
|
|
||||||
|
param.options = 0U;
|
||||||
|
param.interval_min = ADV_SCAN_UNIT(adv_int);
|
||||||
|
param.interval_max = param.interval_min;
|
||||||
|
|
||||||
|
param.adv_duration = duration;
|
||||||
|
param.adv_count = BLE_MESH_TRANSMIT_COUNT(BLE_MESH_ADV(buf)->xmit) + 1;
|
||||||
|
|
||||||
|
param.primary_phy = BLE_MESH_ADV_PHY_1M;
|
||||||
|
param.secondary_phy = BLE_MESH_ADV_PHY_1M;
|
||||||
|
|
||||||
|
bt_mesh_adv_buf_ref_debug(__func__, buf, 4U, BLE_MESH_BUF_REF_SMALL);
|
||||||
|
|
||||||
|
err = bt_le_ext_adv_start(inst->id, ¶m, &ad, 1, NULL, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||||
|
case BLE_MESH_ADV_BLE:
|
||||||
|
struct bt_mesh_ble_adv_data data = {0};
|
||||||
|
struct bt_mesh_ble_adv_tx *tx = cb_data;
|
||||||
|
|
||||||
|
if (tx == NULL) {
|
||||||
|
BT_ERR("Invalid adv user data");
|
||||||
|
net_buf_unref(buf);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BT_DBG("interval %dms, duration %dms, period %dms, count %d",
|
||||||
|
ADV_SCAN_INT(tx->param.interval), tx->param.duration,
|
||||||
|
tx->param.period, tx->param.count);
|
||||||
|
|
||||||
|
data.adv_data_len = tx->buf->data[0];
|
||||||
|
if (data.adv_data_len) {
|
||||||
|
memcpy(data.adv_data, tx->buf->data + 1, data.adv_data_len);
|
||||||
|
}
|
||||||
|
data.scan_rsp_data_len = tx->buf->data[data.adv_data_len + 1];
|
||||||
|
if (data.scan_rsp_data_len) {
|
||||||
|
memcpy(data.scan_rsp_data, tx->buf->data + data.adv_data_len + 2, data.scan_rsp_data_len);
|
||||||
|
}
|
||||||
|
duration = tx->param.duration;
|
||||||
|
|
||||||
|
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
|
||||||
|
|
||||||
|
err = bt_mesh_ble_ext_adv_start(inst->id, &tx->param, &data);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
BT_ERR("Error Type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
adv_send_start(duration, err, cb, cb_data);
|
||||||
|
if (err) {
|
||||||
|
BT_ERR("Start advertising failed: err %d", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
*adv_duration = duration;
|
||||||
|
BT_DBG("Advertising started. %u ms", duration);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int find_valid_msg_from_queue(bt_mesh_queue_t *msg_queue, bt_mesh_msg_t *msg)
|
||||||
|
{
|
||||||
|
while(uxQueueMessagesWaiting(msg_queue->handle)) {
|
||||||
|
xQueueReceive(msg_queue->handle, msg, K_WAIT(K_FOREVER));
|
||||||
|
|
||||||
|
/* In the previous adv task design, only
|
||||||
|
* the *buf of messages pushed to the queue
|
||||||
|
* by adv_update would be empty, but in the
|
||||||
|
* new design, there is a new processing method
|
||||||
|
* for adv_update's messages,
|
||||||
|
* so *buf here cannot be empty. */
|
||||||
|
assert(msg->arg);
|
||||||
|
|
||||||
|
/* If the message is canceled for advertising,
|
||||||
|
* then continue to retrieve the next message
|
||||||
|
* from that queue. */
|
||||||
|
if (!bt_mesh_atomic_cas(&BLE_MESH_ADV_BUSY(BLE_MESH_MSG_NET_BUF(msg)), 1, 0)) {
|
||||||
|
bt_mesh_adv_buf_ref_debug(__func__, BLE_MESH_MSG_NET_BUF(msg), 1U, BLE_MESH_BUF_REF_EQUAL);
|
||||||
|
/* Cancel the adv task's reference to this data packet.
|
||||||
|
* tips: The reference of buffer by adv_task occurs
|
||||||
|
* when the buffer is pushed into the queue.
|
||||||
|
*/
|
||||||
|
net_buf_unref(BLE_MESH_MSG_NET_BUF(msg));
|
||||||
|
/* Avoid reading the last message in the queue, which could lead
|
||||||
|
* to pointing to an invalid buffer due to the absence of other
|
||||||
|
* messages in the queue. */
|
||||||
|
msg->arg = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||||
|
/* If the relay message should be ignored,
|
||||||
|
* then continue to retrieve the next message
|
||||||
|
* from that queue. */
|
||||||
|
if (msg->relay && bt_mesh_ignore_relay_packet(msg->timestamp)) {
|
||||||
|
/* If the interval between "current time - msg.timestamp" is bigger than
|
||||||
|
* BLE_MESH_RELAY_TIME_INTERVAL, this relay packet will not be sent.
|
||||||
|
*/
|
||||||
|
BT_DBG("Ignore relay packet");
|
||||||
|
net_buf_unref(BLE_MESH_MSG_NET_BUF(msg));
|
||||||
|
msg->arg = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg->arg == NULL) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int active_idle_adv_instance(uint32_t *update_evts, uint16_t *min_duration)
|
||||||
|
{
|
||||||
|
uint32_t evts = 0;
|
||||||
|
uint16_t duration = K_FOREVER;
|
||||||
|
uint16_t cur_min_duration = K_FOREVER;
|
||||||
|
enum bt_mesh_adv_type adv_type = 0;
|
||||||
|
struct bt_mesh_adv_inst *instance = NULL;
|
||||||
|
bt_mesh_queue_t *msg_queue = NULL;
|
||||||
|
bt_mesh_msg_t msg = {0};
|
||||||
|
uint32_t spt_mask = 0;
|
||||||
|
|
||||||
|
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
|
||||||
|
CONFIG_BLE_MESH_GATT_PROXY_SERVER
|
||||||
|
if (!adv_insts[BLE_MESH_ADV_PROXY_INS].busy) {
|
||||||
|
BT_DBG("Mesh Proxy Advertising start");
|
||||||
|
duration = bt_mesh_proxy_server_adv_start();
|
||||||
|
if (duration < cur_min_duration) {
|
||||||
|
cur_min_duration = duration;
|
||||||
|
}
|
||||||
|
adv_insts[BLE_MESH_ADV_PROXY_INS].busy = true;
|
||||||
|
evts |= ADV_TASK_ADV_INST_EVT(adv_insts[BLE_MESH_ADV_PROXY_INS].id);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (int i = BLE_MESH_ADV_INS; i < BLE_MESH_ADV_INS_TYPES_NUM; i++) {
|
||||||
|
instance = &adv_insts[i];
|
||||||
|
if (instance->busy
|
||||||
|
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
|
||||||
|
CONFIG_BLE_MESH_GATT_PROXY_SERVER
|
||||||
|
|| unlikely(instance->id == CONFIG_BLE_MESH_PROXY_ADV_INST_ID)
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
spt_mask = instance->spt_mask;
|
||||||
|
adv_type = 0;
|
||||||
|
|
||||||
|
while(spt_mask) {
|
||||||
|
adv_type = find_lsb_set(spt_mask) - 1;
|
||||||
|
spt_mask &= ~BIT(adv_type);
|
||||||
|
msg_queue = &(bt_mesh_adv_types_mgnt_get(adv_type)->adv_q->q);
|
||||||
|
|
||||||
|
/* When there is no new message in the queue, *buf (aka: msg.arg)
|
||||||
|
* will be empty. */
|
||||||
|
if (find_valid_msg_from_queue(msg_queue, &msg)) {
|
||||||
|
BT_DBG("no valid message for instance %d", instance->id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance->sending_buf = (struct net_buf *)msg.arg;
|
||||||
|
if (adv_send(instance, &duration)) {
|
||||||
|
BT_ERR("adv start failed");
|
||||||
|
net_buf_unref(instance->sending_buf);
|
||||||
|
instance->sending_buf = NULL;
|
||||||
|
/* When this adv instance fails to broadcast, it could be
|
||||||
|
* due to some persistent issues, such as incorrect adv
|
||||||
|
* parameter settings, or it could be due to some temporary
|
||||||
|
* issues, such as memory allocation failure. Therefore, it
|
||||||
|
* is advisable to skip subsequent queue reads for this instance
|
||||||
|
* and attempt to broadcast subsequent data again next time,
|
||||||
|
* rather than disabling the adv instance. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (duration < cur_min_duration) {
|
||||||
|
cur_min_duration = duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance->busy = true;
|
||||||
|
evts |= ADV_TASK_ADV_INST_EVT(adv_insts[i].id);
|
||||||
|
|
||||||
|
/* Must be nullified to avoid affecting the next adv
|
||||||
|
* instance's judgment on whether the message queue
|
||||||
|
* is empty. */
|
||||||
|
msg.arg = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*min_duration = cur_min_duration;
|
||||||
|
*update_evts |= evts;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t received_adv_evts_handle(uint32_t recv_evts)
|
||||||
|
{
|
||||||
|
uint32_t evt = 0;
|
||||||
|
|
||||||
|
if (!recv_evts) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; recv_evts && i < BLE_MESH_ADV_INS_TYPES_NUM; i++) {
|
||||||
|
evt = ADV_TASK_ADV_INST_EVT(adv_insts[i].id);
|
||||||
|
if (recv_evts & evt) {
|
||||||
|
recv_evts &= ~evt;
|
||||||
|
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
|
||||||
|
CONFIG_BLE_MESH_GATT_PROXY_SERVER
|
||||||
|
if (unlikely(i == BLE_MESH_ADV_PROXY_INS)) {
|
||||||
|
BT_DBG("Mesh Proxy Advertising auto stop");
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
/* adv_send_end maybe*/
|
||||||
|
adv_send_end(0, BLE_MESH_ADV(adv_insts[i].sending_buf)->cb, BLE_MESH_ADV(adv_insts[i].sending_buf)->cb_data);
|
||||||
|
bt_mesh_adv_buf_ref_debug(__func__, adv_insts[i].sending_buf, 4U, BLE_MESH_BUF_REF_SMALL);
|
||||||
|
net_buf_unref(adv_insts[i].sending_buf);
|
||||||
|
adv_insts[i].sending_buf = NULL;
|
||||||
|
}
|
||||||
|
adv_insts[i].busy = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return recv_evts;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void adv_thread(void *p)
|
||||||
|
{
|
||||||
|
uint16_t adv_duration = K_FOREVER;
|
||||||
|
uint32_t recv_evts = 0;
|
||||||
|
uint32_t wait_evts = 0;
|
||||||
|
|
||||||
|
BT_DBG("%s, starts", __func__);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
adv_duration = K_FOREVER;
|
||||||
|
wait_evts |= ADV_TASK_PKT_SEND_EVT;
|
||||||
|
|
||||||
|
active_idle_adv_instance(&wait_evts, &adv_duration);
|
||||||
|
|
||||||
|
ble_mesh_adv_task_wait(wait_evts, adv_duration, &recv_evts);
|
||||||
|
|
||||||
|
wait_evts &= ~recv_evts;
|
||||||
|
|
||||||
|
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
|
||||||
|
CONFIG_BLE_MESH_GATT_PROXY_SERVER
|
||||||
|
if (recv_evts & ADV_TASK_PROXY_ADV_UPD_EVT) {
|
||||||
|
adv_insts[BLE_MESH_ADV_PROXY_INS].busy = false;
|
||||||
|
recv_evts &= ~ADV_TASK_PROXY_ADV_UPD_EVT;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `recv_evts == ADV_TASK_PKT_SEND_EVT` indicates that new packets
|
||||||
|
* have been placed into the queue, and the advertising instances started
|
||||||
|
* previous have not yet stopped.
|
||||||
|
*/
|
||||||
|
if (recv_evts == ADV_TASK_PKT_SEND_EVT) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
recv_evts = received_adv_evts_handle(recv_evts);
|
||||||
|
|
||||||
|
if (recv_evts) {
|
||||||
|
BT_ERR("Remain evts %08x to handle", recv_evts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_adv_update(void)
|
||||||
|
{
|
||||||
|
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
|
||||||
|
CONFIG_BLE_MESH_GATT_PROXY_SERVER
|
||||||
|
BT_WARN("Mesh Proxy Advertising stopped manually");
|
||||||
|
bt_mesh_proxy_server_adv_stop();
|
||||||
|
if (adv_insts[BLE_MESH_ADV_PROXY_INS].busy) {
|
||||||
|
ble_mesh_adv_task_wakeup(ADV_TASK_PROXY_ADV_UPD_EVT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_adv_init(void)
|
||||||
|
{
|
||||||
|
bt_mesh_adv_common_init();
|
||||||
|
|
||||||
|
adv_insts = bt_mesh_get_adv_insts_set();
|
||||||
|
adv_queue = bt_mesh_adv_queue_get();
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||||
|
bt_mesh_relay_adv_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||||
|
bt_mesh_ble_adv_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bt_mesh_adv_task_init(adv_thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_DEINIT
|
||||||
|
void bt_mesh_adv_deinit(void)
|
||||||
|
{
|
||||||
|
bt_mesh_adv_task_deinit();
|
||||||
|
|
||||||
|
bt_mesh_adv_common_deinit();
|
||||||
|
|
||||||
|
adv_insts = NULL;
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||||
|
bt_mesh_relay_adv_deinit();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||||
|
bt_mesh_ble_adv_deinit();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BLE_MESH_DEINIT */
|
39
components/bt/esp_ble_mesh/core/ext_adv.h
Normal file
39
components/bt/esp_ble_mesh/core/ext_adv.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/* Bluetooth Mesh */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||||
|
* SPDX-FileContributor: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _EXT_ADV_H_
|
||||||
|
#define _EXT_ADV_H_
|
||||||
|
|
||||||
|
#include "mesh/atomic.h"
|
||||||
|
#include "mesh/access.h"
|
||||||
|
#include "mesh/adapter.h"
|
||||||
|
#include "mesh/queue.h"
|
||||||
|
#include "adv_common.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline void bt_mesh_adv_send(struct net_buf *buf, uint8_t xmit,
|
||||||
|
const struct bt_mesh_send_cb *cb,
|
||||||
|
void *cb_data)
|
||||||
|
{
|
||||||
|
bt_mesh_generic_adv_send(buf, xmit, cb, cb_data, BLE_MESH_ADDR_UNASSIGNED, BLE_MESH_ADDR_UNASSIGNED, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_mesh_adv_update(void);
|
||||||
|
|
||||||
|
void bt_mesh_adv_init(void);
|
||||||
|
void bt_mesh_adv_deinit(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _EXT_ADV_H_ */
|
@ -27,14 +27,6 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_BLE_MESH_FRIEND
|
#ifdef CONFIG_BLE_MESH_FRIEND
|
||||||
|
|
||||||
/* We reserve one extra buffer for each friendship, since we need to be able
|
|
||||||
* to resend the last sent PDU, which sits separately outside of the queue.
|
|
||||||
*/
|
|
||||||
#define FRIEND_BUF_COUNT ((CONFIG_BLE_MESH_FRIEND_QUEUE_SIZE + 1) * \
|
|
||||||
CONFIG_BLE_MESH_FRIEND_LPN_COUNT)
|
|
||||||
|
|
||||||
#define FRIEND_ADV(buf) CONTAINER_OF(BLE_MESH_ADV(buf), struct friend_adv, adv)
|
|
||||||
|
|
||||||
/* PDUs from Friend to the LPN should only be transmitted once with the
|
/* PDUs from Friend to the LPN should only be transmitted once with the
|
||||||
* smallest possible interval (20ms).
|
* smallest possible interval (20ms).
|
||||||
*
|
*
|
||||||
@ -57,14 +49,6 @@ struct friend_pdu_info {
|
|||||||
uint32_t iv_index;
|
uint32_t iv_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
NET_BUF_POOL_FIXED_DEFINE(friend_buf_pool, FRIEND_BUF_COUNT,
|
|
||||||
BLE_MESH_ADV_DATA_SIZE, NULL);
|
|
||||||
|
|
||||||
static struct friend_adv {
|
|
||||||
struct bt_mesh_adv adv;
|
|
||||||
uint16_t app_idx;
|
|
||||||
} adv_pool[FRIEND_BUF_COUNT];
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
BLE_MESH_FRIENDSHIP_TERMINATE_ESTABLISH_FAIL,
|
BLE_MESH_FRIENDSHIP_TERMINATE_ESTABLISH_FAIL,
|
||||||
BLE_MESH_FRIENDSHIP_TERMINATE_POLL_TIMEOUT,
|
BLE_MESH_FRIENDSHIP_TERMINATE_POLL_TIMEOUT,
|
||||||
@ -83,12 +67,6 @@ static struct bt_mesh_subnet *friend_subnet_get(uint16_t net_idx)
|
|||||||
return bt_mesh_subnet_get(net_idx);
|
return bt_mesh_subnet_get(net_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct bt_mesh_adv *adv_alloc(int id)
|
|
||||||
{
|
|
||||||
adv_pool[id].app_idx = BLE_MESH_KEY_UNUSED;
|
|
||||||
return &adv_pool[id].adv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_lpn_unicast(struct bt_mesh_friend *frnd, uint16_t addr)
|
static bool is_lpn_unicast(struct bt_mesh_friend *frnd, uint16_t addr)
|
||||||
{
|
{
|
||||||
if (frnd->lpn == BLE_MESH_ADDR_UNASSIGNED) {
|
if (frnd->lpn == BLE_MESH_ADDR_UNASSIGNED) {
|
||||||
@ -368,8 +346,7 @@ static struct net_buf *create_friend_pdu(struct bt_mesh_friend *frnd,
|
|||||||
{
|
{
|
||||||
struct net_buf *buf = NULL;
|
struct net_buf *buf = NULL;
|
||||||
|
|
||||||
buf = bt_mesh_adv_create_from_pool(&friend_buf_pool, adv_alloc,
|
buf = bt_mesh_adv_create_from_pool(BLE_MESH_ADV_FRIEND, K_NO_WAIT);
|
||||||
BLE_MESH_ADV_DATA, K_NO_WAIT);
|
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1323,6 +1300,8 @@ int bt_mesh_friend_init(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bt_mesh_frnd_adv_init();
|
||||||
|
|
||||||
friend_init = true;
|
friend_init = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1349,8 +1328,7 @@ int bt_mesh_friend_deinit(void)
|
|||||||
k_delayed_work_free(&frnd->clear.timer);
|
k_delayed_work_free(&frnd->clear.timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
bt_mesh_unref_buf_from_pool(&friend_buf_pool);
|
bt_mesh_frnd_adv_deinit();
|
||||||
memset(adv_pool, 0, sizeof(adv_pool));
|
|
||||||
|
|
||||||
friend_init = false;
|
friend_init = false;
|
||||||
|
|
||||||
|
@ -348,7 +348,7 @@ struct bt_mesh_model_op {
|
|||||||
* @return Mesh transmit value that can be used e.g. for the default
|
* @return Mesh transmit value that can be used e.g. for the default
|
||||||
* values of the configuration model data.
|
* values of the configuration model data.
|
||||||
*/
|
*/
|
||||||
#define BLE_MESH_TRANSMIT(count, int_ms) ((count) | ((((int_ms) / 10) - 1) << 3))
|
#define BLE_MESH_TRANSMIT(count, int_ms) ((uint8_t)(count) | ((((int_ms) / 10) - 1) << 3))
|
||||||
|
|
||||||
/** @def BLE_MESH_TRANSMIT_COUNT
|
/** @def BLE_MESH_TRANSMIT_COUNT
|
||||||
*
|
*
|
||||||
|
@ -487,15 +487,24 @@ struct bt_mesh_adv_param {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
#define ADV_TASK_ADV_INST_EVT(inst_id) BIT(inst_id)
|
||||||
|
|
||||||
enum bt_mesh_adv_inst_type {
|
enum bt_mesh_adv_inst_type {
|
||||||
BLE_MESH_ADV_PROXY_INS,
|
|
||||||
BLE_MESH_ADV_INS,
|
BLE_MESH_ADV_INS,
|
||||||
BLE_MESH_EXT_ADV_INS,
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
|
||||||
|
CONFIG_BLE_MESH_GATT_PROXY_SERVER
|
||||||
|
BLE_MESH_ADV_PROXY_INS,
|
||||||
|
#endif
|
||||||
|
#if CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE
|
||||||
|
BLE_MESH_RELAY_ADV_INS,
|
||||||
|
#endif
|
||||||
|
#if CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
|
||||||
BLE_MESH_BLE_ADV_INS,
|
BLE_MESH_BLE_ADV_INS,
|
||||||
BLE_MESH_ADV_INS_TYPE_NUMS,
|
#endif
|
||||||
|
#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
|
||||||
|
BLE_MESH_ADV_INS_TYPES_NUM,
|
||||||
};
|
};
|
||||||
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||||
enum bt_mesh_ble_adv_priority {
|
enum bt_mesh_ble_adv_priority {
|
||||||
|
@ -1682,7 +1682,7 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf,
|
|||||||
if (bt_mesh_get_stored_relay_count() >= BLE_MESH_MAX_STORED_RELAY_COUNT) {
|
if (bt_mesh_get_stored_relay_count() >= BLE_MESH_MAX_STORED_RELAY_COUNT) {
|
||||||
xmit = BLE_MESH_TRANSMIT(0, 20);
|
xmit = BLE_MESH_TRANSMIT(0, 20);
|
||||||
}
|
}
|
||||||
buf = bt_mesh_relay_adv_create(BLE_MESH_ADV_DATA, K_NO_WAIT);
|
buf = bt_mesh_relay_adv_create(BLE_MESH_ADV_RELAY_DATA, K_NO_WAIT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
|
@ -86,7 +86,9 @@ static bool g_gatts_svcs_add = false;
|
|||||||
#endif
|
#endif
|
||||||
#endif /* CONFIG_BLE_MESH_NODE */
|
#endif /* CONFIG_BLE_MESH_NODE */
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
#if CONFIG_BLE_MESH_USE_BLE_50 && \
|
||||||
|
CONFIG_BLE_MESH_SUPPORT_BLE_ADV && \
|
||||||
|
(!CONFIG_BLE_MESH_SUPPORT_MULTI_ADV)
|
||||||
static inline void bt_mesh_set_ble_adv_running();
|
static inline void bt_mesh_set_ble_adv_running();
|
||||||
|
|
||||||
static inline void bt_mesh_unset_ble_adv_running();
|
static inline void bt_mesh_unset_ble_adv_running();
|
||||||
@ -930,10 +932,14 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
|
|||||||
case BLE_GAP_EVENT_ADV_COMPLETE:
|
case BLE_GAP_EVENT_ADV_COMPLETE:
|
||||||
BT_DBG("advertise complete; reason=%d",
|
BT_DBG("advertise complete; reason=%d",
|
||||||
event->adv_complete.reason);
|
event->adv_complete.reason);
|
||||||
/* Limit Reached (0x43) and Advertising Timeout (0x3C) will cause BLE_HS_ETIMEOUT to be set. */
|
|
||||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(event->adv_complete.instance));
|
||||||
|
#else /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
|
||||||
|
assert(CONFIG_BLE_MESH_ADV_INST_ID == event->adv_complete.instance);
|
||||||
|
/* Limit Reached (0x43) and Advertising Timeout (0x3C) will cause BLE_HS_ETIMEOUT to be set. */
|
||||||
if (event->adv_complete.reason == BLE_HS_ETIMEOUT) {
|
if (event->adv_complete.reason == BLE_HS_ETIMEOUT) {
|
||||||
ble_mesh_adv_task_wakeup(event->adv_complete.instance);
|
ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(event->adv_complete.instance));
|
||||||
}
|
}
|
||||||
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||||
/**
|
/**
|
||||||
@ -956,9 +962,10 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
|
|||||||
* could lead to resource contention issues.
|
* could lead to resource contention issues.
|
||||||
*/
|
*/
|
||||||
bt_mesh_unset_ble_adv_running();
|
bt_mesh_unset_ble_adv_running();
|
||||||
ble_mesh_adv_task_wakeup(event->adv_complete.instance);
|
ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(event->adv_complete.instance));
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
|
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
|
||||||
|
#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
|
||||||
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1053,9 +1060,13 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
|
|||||||
case BLE_GAP_EVENT_ADV_COMPLETE:
|
case BLE_GAP_EVENT_ADV_COMPLETE:
|
||||||
BT_DBG("Provisioner advertise complete; reason=%d",
|
BT_DBG("Provisioner advertise complete; reason=%d",
|
||||||
event->adv_complete.reason);
|
event->adv_complete.reason);
|
||||||
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(event->adv_complete.instance));
|
||||||
|
#else /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
|
||||||
|
assert(CONFIG_BLE_MESH_ADV_INST_ID == event->adv_complete.instance);
|
||||||
/* Limit Reached (0x43) and Advertising Timeout (0x3C) will cause BLE_HS_ETIMEOUT to be set. */
|
/* Limit Reached (0x43) and Advertising Timeout (0x3C) will cause BLE_HS_ETIMEOUT to be set. */
|
||||||
if (event->adv_complete.reason == BLE_HS_ETIMEOUT) {
|
if (event->adv_complete.reason == BLE_HS_ETIMEOUT) {
|
||||||
ble_mesh_adv_task_wakeup(event->adv_complete.instance);
|
ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(CONFIG_BLE_MESH_ADV_INST_ID));
|
||||||
}
|
}
|
||||||
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||||
/**
|
/**
|
||||||
@ -1078,9 +1089,10 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
|
|||||||
* could lead to resource contention issues.
|
* could lead to resource contention issues.
|
||||||
*/
|
*/
|
||||||
bt_mesh_unset_ble_adv_running();
|
bt_mesh_unset_ble_adv_running();
|
||||||
ble_mesh_adv_task_wakeup(event->adv_complete.instance);
|
ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(CONFIG_BLE_MESH_ADV_INST_ID));
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
|
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
|
||||||
|
#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||||
@ -1211,8 +1223,6 @@ int bt_le_ext_adv_start(const uint8_t inst_id,
|
|||||||
interval >>= 1;
|
interval >>= 1;
|
||||||
interval += (bt_mesh_get_rand() % (interval + 1));
|
interval += (bt_mesh_get_rand() % (interval + 1));
|
||||||
|
|
||||||
adv_params->high_duty_directed = true;
|
|
||||||
|
|
||||||
BT_INFO("%u->%u", param->interval_min, interval);
|
BT_INFO("%u->%u", param->interval_min, interval);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1376,7 +1386,14 @@ again:
|
|||||||
|
|
||||||
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
|
#if !CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
/**
|
||||||
|
* The current flag is only used to distinguish between BLE ADV
|
||||||
|
* and proxy ADV in the same adv instance to handle the adv
|
||||||
|
* completed events.
|
||||||
|
*
|
||||||
|
* This flag is not needed in the case of multiple adv instances.
|
||||||
|
*/
|
||||||
static bool _ble_adv_running_flag;
|
static bool _ble_adv_running_flag;
|
||||||
|
|
||||||
static inline void bt_mesh_set_ble_adv_running()
|
static inline void bt_mesh_set_ble_adv_running()
|
||||||
@ -1393,6 +1410,7 @@ static inline bool bt_mesh_is_ble_adv_running()
|
|||||||
{
|
{
|
||||||
return _ble_adv_running_flag == true;
|
return _ble_adv_running_flag == true;
|
||||||
}
|
}
|
||||||
|
#endif /* BLE_MESH_SUPPORT_MULTI_ADV */
|
||||||
|
|
||||||
int bt_mesh_ble_ext_adv_start(const uint8_t inst_id,
|
int bt_mesh_ble_ext_adv_start(const uint8_t inst_id,
|
||||||
const struct bt_mesh_ble_adv_param *param,
|
const struct bt_mesh_ble_adv_param *param,
|
||||||
@ -1507,7 +1525,9 @@ int bt_mesh_ble_ext_adv_start(const uint8_t inst_id,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
bt_mesh_set_ble_adv_running();
|
bt_mesh_set_ble_adv_running();
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1043,7 +1043,6 @@ int bt_mesh_proxy_server_prov_enable(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1749,6 +1748,7 @@ static int32_t gatt_proxy_advertise(struct bt_mesh_subnet *sub)
|
|||||||
&& sub->private_node_id == BLE_MESH_PRIVATE_NODE_IDENTITY_STOPPED
|
&& sub->private_node_id == BLE_MESH_PRIVATE_NODE_IDENTITY_STOPPED
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
|
/* advertising node identity forever */
|
||||||
if (bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED) {
|
if (bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED) {
|
||||||
net_id_adv(sub);
|
net_id_adv(sub);
|
||||||
}
|
}
|
||||||
@ -1864,13 +1864,14 @@ static int32_t solic_adv_private_net_id(void)
|
|||||||
|
|
||||||
int32_t bt_mesh_proxy_server_adv_start(void)
|
int32_t bt_mesh_proxy_server_adv_start(void)
|
||||||
{
|
{
|
||||||
|
BT_DBG("proxy server start");
|
||||||
|
|
||||||
if (gatt_svc == MESH_GATT_NONE) {
|
if (gatt_svc == MESH_GATT_NONE) {
|
||||||
return K_FOREVER;
|
return K_FOREVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
if (proxy_adv_inst == BLE_MESH_ADV_INS_UNUSED) {
|
if (proxy_adv_inst == BLE_MESH_ADV_INS_UNUSED) {
|
||||||
BT_ERR("Proxy adv inst is not initialized!");
|
|
||||||
return K_FOREVER;
|
return K_FOREVER;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1931,23 +1932,22 @@ int32_t bt_mesh_proxy_server_adv_start(void)
|
|||||||
}
|
}
|
||||||
#endif /* GATT_PROXY */
|
#endif /* GATT_PROXY */
|
||||||
|
|
||||||
|
/* used to indicate proxy advertising could be stopped */
|
||||||
return K_FOREVER;
|
return K_FOREVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_mesh_proxy_server_adv_stop(void)
|
int bt_mesh_proxy_server_adv_stop(void)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
BT_DBG("adv_enabled %u", proxy_adv_enabled);
|
|
||||||
|
|
||||||
if (!proxy_adv_enabled) {
|
if (!proxy_adv_enabled) {
|
||||||
return;
|
return -EALREADY;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
if (proxy_adv_inst == BLE_MESH_ADV_INS_UNUSED) {
|
if (proxy_adv_inst == BLE_MESH_ADV_INS_UNUSED) {
|
||||||
BT_ERR("Proxy adv inst is not initialized!");
|
BT_ERR("Proxy adv inst is not initialized!");
|
||||||
return;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = bt_le_ext_adv_stop(proxy_adv_inst);
|
err = bt_le_ext_adv_stop(proxy_adv_inst);
|
||||||
@ -1956,9 +1956,11 @@ void bt_mesh_proxy_server_adv_stop(void)
|
|||||||
#endif
|
#endif
|
||||||
if (err) {
|
if (err) {
|
||||||
BT_ERR("Failed to stop advertising (err %d)", err);
|
BT_ERR("Failed to stop advertising (err %d)", err);
|
||||||
} else {
|
return -EINVAL;
|
||||||
proxy_adv_enabled = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proxy_adv_enabled = false;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct bt_mesh_conn_cb conn_callbacks = {
|
static struct bt_mesh_conn_cb conn_callbacks = {
|
||||||
@ -1971,7 +1973,11 @@ int bt_mesh_proxy_server_init(void)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||||
proxy_adv_inst = bt_mesh_get_proxy_inst();
|
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||||
|
proxy_adv_inst = CONFIG_BLE_MESH_PROXY_ADV_INST_ID;
|
||||||
|
#else /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
|
||||||
|
proxy_adv_inst = CONFIG_BLE_MESH_ADV_INST_ID;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_GATT_PROXY_SERVER
|
#if CONFIG_BLE_MESH_GATT_PROXY_SERVER
|
||||||
|
@ -95,7 +95,7 @@ void bt_mesh_proxy_server_beacon_send(struct bt_mesh_subnet *sub);
|
|||||||
struct net_buf_simple *bt_mesh_proxy_server_get_buf(void);
|
struct net_buf_simple *bt_mesh_proxy_server_get_buf(void);
|
||||||
|
|
||||||
int32_t bt_mesh_proxy_server_adv_start(void);
|
int32_t bt_mesh_proxy_server_adv_start(void);
|
||||||
void bt_mesh_proxy_server_adv_stop(void);
|
int bt_mesh_proxy_server_adv_stop(void);
|
||||||
|
|
||||||
void bt_mesh_proxy_server_update_net_id_rand(void);
|
void bt_mesh_proxy_server_update_net_id_rand(void);
|
||||||
void bt_mesh_proxy_server_update_net_id_rand_stop(void);
|
void bt_mesh_proxy_server_update_net_id_rand_stop(void);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user