feat(ble_mesh): Support BLE 5.0 for BLE Mesh

This commit is contained in:
luoxu
2024-05-30 16:44:12 +08:00
parent 7aaab5a3ff
commit a86bb375f7
29 changed files with 1961 additions and 187 deletions

View File

@ -254,9 +254,9 @@ static const btc_func_t profile_tab[BTC_PID_NUM] = {
#if CONFIG_BLE_MESH_MBT_SRV
[BTC_PID_MBT_SERVER] = {btc_ble_mesh_mbt_server_call_handler, btc_ble_mesh_mbt_server_cb_handler },
#endif /* CONFIG_BLE_MESH_MBT_SRV */
#if CONFIG_BLE_MESH_BLE_COEX_SUPPORT
#if CONFIG_BLE_MESH_BLE_COEX_SUPPORT || CONFIG_BLE_MESH_USE_BLE_50
[BTC_PID_BLE_MESH_BLE_COEX] = {btc_ble_mesh_ble_call_handler, btc_ble_mesh_ble_cb_handler },
#endif /* CONFIG_BLE_MESH_BLE_COEX_SUPPORT */
#endif /* CONFIG_BLE_MESH_BLE_COEX_SUPPORT || CONFIG_BLE_MESH_USE_BLE_50 */
#endif /* #if CONFIG_BLE_MESH */
};

View File

@ -21,13 +21,25 @@ if BLE_MESH
for mesh packets. And this could help avoid collision of
advertising packets.
menuconfig BLE_MESH_USE_BLE_50
bool "Support using BLE 5.0 APIs for BLE Mesh"
depends on BLE_MESH_EXPERIMENTAL
depends on IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
select BT_NIMBLE_50_FEATURE_SUPPORT if BT_NIMBLE_ENABLED
select BT_NIMBLE_EXT_ADV if BT_NIMBLE_ENABLED
select BT_BLE_50_FEATURES_SUPPORTED if BT_BLUEDROID_ENABLED
select BT_LE_50_FEATURE_SUPPORT if IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32H2
default n
help
This option to enable BLE Mesh using some BLE 5.0 APIs.
config BLE_MESH_USE_DUPLICATE_SCAN
bool "Support Duplicate Scan in BLE Mesh"
select BTDM_BLE_SCAN_DUPL if IDF_TARGET_ESP32
select BTDM_BLE_MESH_SCAN_DUPL_EN if IDF_TARGET_ESP32
select BT_CTRL_BLE_SCAN_DUPL if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
select BT_CTRL_BLE_MESH_SCAN_DUPL_EN if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
select BT_LE_SCAN_DUPL if IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32H2
select BT_LE_SCAN_DUPL if IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32H2 || IDF_TARGET_ESP32C61 || IDF_TARGET_ESP32C5
select BT_NIMBLE_VS_SUPPORT if BT_NIMBLE_ENABLED
default y
help
@ -1646,5 +1658,6 @@ if BLE_MESH
Make BLE Mesh Experimental features visible.
Experimental features list:
- CONFIG_BLE_MESH_NOT_RELAY_REPLAY_MSG
- CONFIG_BLE_MESH_USE_BLE_50
endif # BLE_MESH

View File

@ -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
*/
@ -12,14 +12,14 @@
#include "btc_ble_mesh_ble.h"
#include "esp_ble_mesh_ble_api.h"
#if CONFIG_BLE_MESH_BLE_COEX_SUPPORT
#if (CONFIG_BLE_MESH_BLE_COEX_SUPPORT || CONFIG_BLE_MESH_USE_BLE_50)
esp_err_t esp_ble_mesh_register_ble_callback(esp_ble_mesh_ble_cb_t callback)
{
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_BLE_MESH_BLE_COEX, callback) == 0 ? ESP_OK : ESP_FAIL);
}
#endif /* CONFIG_BLE_MESH_BLE_COEX_SUPPORT */
#endif /* (CONFIG_BLE_MESH_BLE_COEX_SUPPORT || CONFIG_BLE_MESH_USE_BLE_50) */
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
esp_err_t esp_ble_mesh_start_ble_advertising(const esp_ble_mesh_ble_adv_param_t *param,
@ -100,3 +100,23 @@ esp_err_t esp_ble_mesh_stop_ble_scanning(void)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
esp_err_t esp_ble_mesh_scan_params_update(esp_ble_mesh_scan_param_t *scan_param)
{
btc_ble_mesh_ble_args_t arg = {0};
btc_msg_t msg = {0};
if (!scan_param) {
return ESP_FAIL;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_BLE_MESH_BLE_COEX;
msg.act = BTC_BLE_MESH_ACT_UPDATE_SCAN_PARAMS;
arg.scan_params.scan_interval = scan_param->scan_interval;
arg.scan_params.uncoded_scan_window = scan_param->uncoded_scan_window;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_ble_args_t), NULL, NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}

View File

@ -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
*/

View File

@ -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
*/
@ -9,6 +9,10 @@
#include "esp_ble_mesh_defs.h"
#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BT_NIMBLE_ENABLED
#include "host/ble_gap.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -20,9 +24,38 @@ typedef enum {
ESP_BLE_MESH_START_BLE_SCANNING_COMP_EVT, /*!< Start BLE scanning completion event */
ESP_BLE_MESH_STOP_BLE_SCANNING_COMP_EVT, /*!< Stop BLE scanning completion event */
ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT, /*!< Scanning BLE advertising packets event */
ESP_BLE_MESH_SCAN_PARAMS_UPDATE_COMP_EVT, /*!< Scan parameters update completion event */
#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BT_NIMBLE_ENABLED
ESP_BLE_MESH_NIMBLE_GAP_EVENT_EVT, /*!< NIMBLE GAP event */
#endif /* CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BT_NIMBLE_ENABLED */
ESP_BLE_MESH_BLE_EVT_MAX,
} esp_ble_mesh_ble_cb_event_t;
/** Context of BLE advertising report. */
typedef struct {
uint8_t addr[6]; /*!< Device address */
uint8_t addr_type; /*!< Device address type */
#if CONFIG_BLE_MESH_USE_BLE_50
uint8_t adv_type __attribute__((deprecated("`event_type` should be used to determine the advertising type"))); /*!< advertising type */
#else
uint8_t adv_type; /*!< Advertising type */
#endif
uint8_t *data; /*!< Advertising data */
uint16_t length; /*!< Advertising data length */
int8_t rssi; /*!< RSSI of the advertising packet */
#if CONFIG_BLE_MESH_USE_BLE_50
uint8_t event_type; /*!< Extended advertising event type */
uint8_t primary_phy; /*!< Extended advertising primary PHY */
uint8_t secondary_phy; /*!< Extended advertising secondary PHY */
uint8_t sid; /*!< Extended advertising set ID */
uint8_t tx_power; /*!< Extended advertising TX power */
uint8_t dir_addr_type; /*!< Direct address type */
uint8_t dir_addr[6]; /*!< Direct address */
uint8_t data_status; /*!< Data type */
uint16_t per_adv_interval; /*!< Periodic advertising interval */
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
} esp_ble_mesh_ble_adv_rpt_t;
/** BLE operation callback parameters */
typedef union {
/**
@ -52,16 +85,24 @@ typedef union {
int err_code; /*!< Indicate the result of stopping BLE scanning */
} stop_ble_scan_comp; /*!< Event parameters of ESP_BLE_MESH_STOP_BLE_SCANNING_COMP_EVT */
/**
* @brief ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT
* @brief Event parameters of ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT
*/
struct {
uint8_t addr[6]; /*!< Device address */
uint8_t addr_type; /*!< Device address type */
uint8_t adv_type; /*!< Advertising data type */
uint8_t *data; /*!< Advertising data */
uint16_t length; /*!< Advertising data length */
int8_t rssi; /*!< RSSI of the advertising packet */
} scan_ble_adv_pkt; /*!< Event parameters of ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT */
esp_ble_mesh_ble_adv_rpt_t scan_ble_adv_pkt;
/**
* @brief Event parameter of ESP_BLE_MESH_SCAN_PARAMS_UPDATE_COMP_EVT
*/
struct ble_mesh_scan_params_update_comp_param {
int err_code; /*!< Indicates the result of updating scan parameters */
} scan_params_update_comp; /*!< Event parameter of ESP_BLE_MESH_SCAN_PARAMS_UPDATE_COMP_EVT */
#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BT_NIMBLE_ENABLED
/**
* @brief Event parameters of ESP_BLE_MESH_NIMBLE_GAP_EVENT_EVT
*/
struct ble_mesh_nimble_gap_event_evt_param {
struct ble_gap_event event; /*!< GAP event parameters for NimBLE Host */
void *arg; /*!< User parameters */
} nimble_gap_evt; /*!< Event parameters of ESP_BLE_MESH_NIMBLE_GAP_EVENT_EVT */
#endif /* CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BT_NIMBLE_ENABLED */
} esp_ble_mesh_ble_cb_param_t;
/**
@ -175,6 +216,33 @@ esp_err_t esp_ble_mesh_start_ble_scanning(esp_ble_mesh_ble_scan_param_t *param);
*/
esp_err_t esp_ble_mesh_stop_ble_scanning(void);
/**
* @brief Update BLE Mesh scan parameters.
*
* @note
* 1. This function shall be used after ESP BLE Mesh is initialized!
* Parameters `scan_interval` and `uncoded_scan_window` must both
* be multiples of 8.
*
* 2. If the config BLE_MESH_USE_BLE_50 is enabled, within the scan_interval:
* - If uncoded_scan_window is not zero, the scan_interval is divided into
* two parts:
* - uncoded_scan_window: Used for performing uncoded scanning.
* - (scan_interval - uncoded_scan_window): The remaining time is
* used for coded scanning (coded_scan).
* - If uncoded_scan_window is set to 0, it means the entire scan_interval
* is used for coded scanning.
* - If uncoded_scan_window is equal to scan_interval, it means the entire
* scan_interval is used for uncoded scanning.
*
* @param[in] scan_param: Scan parameters
*
* @return
* - ESP_OK: Success
* - ESP_FAIL: Invalid parameters or unable transfer this command to the stack
*/
esp_err_t esp_ble_mesh_scan_params_update(esp_ble_mesh_scan_param_t *scan_param);
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -415,6 +415,29 @@ typedef struct {
bool erase_flash; /*!< Indicate if erasing flash when deinit mesh stack */
} esp_ble_mesh_deinit_param_t;
/** Scan parameters */
typedef struct {
/**
* Scan interval.
*
* Range: 0x0004 to 0x4000.
*
* Time = N * 0.625 ms. Time Range: 2.5 ms to 10.24 s
*/
uint16_t scan_interval;
/**
* Uncoded Scan window.
*
* Time scanned on uncoded PHY within a scan interval.
*
* Range: 0x0004 to 0x4000.
*
* Time = N * 0.625 ms. Time Range: 2.5 ms to 10.24 s
*/
uint16_t uncoded_scan_window;
} esp_ble_mesh_scan_param_t;
/** Format of Unicast Address Range */
typedef struct {
uint16_t len_present:1, /*!< Indicate the presence or absence of the RangeLength field */

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -13,8 +13,7 @@
#include "mesh/adapter.h"
#include "esp_ble_mesh_ble_api.h"
#if CONFIG_BLE_MESH_BLE_COEX_SUPPORT
#if (CONFIG_BLE_MESH_BLE_COEX_SUPPORT || CONFIG_BLE_MESH_USE_BLE_50)
static void btc_ble_mesh_ble_copy_req_data(btc_msg_t *msg, void *p_dst, void *p_src)
{
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
@ -29,6 +28,7 @@ static void btc_ble_mesh_ble_copy_req_data(btc_msg_t *msg, void *p_dst, void *p_
switch (msg->act) {
case ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT:
if (p_src_data->scan_ble_adv_pkt.data && p_src_data->scan_ble_adv_pkt.length) {
memcpy(&p_dst_data->scan_ble_adv_pkt, &p_src_data->scan_ble_adv_pkt, sizeof(p_src_data->scan_ble_adv_pkt));
p_dst_data->scan_ble_adv_pkt.length = p_src_data->scan_ble_adv_pkt.length;
p_dst_data->scan_ble_adv_pkt.data = bt_mesh_calloc(p_src_data->scan_ble_adv_pkt.length);
if (p_dst_data->scan_ble_adv_pkt.data) {
@ -86,26 +86,34 @@ static void btc_ble_mesh_ble_callback(esp_ble_mesh_ble_cb_param_t *cb_params, ui
btc_ble_mesh_ble_copy_req_data, btc_ble_mesh_ble_free_req_data);
}
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
void bt_mesh_ble_scan_cb_evt_to_btc(const bt_mesh_addr_t *addr,
uint8_t adv_type, uint8_t data[],
uint16_t length, int8_t rssi)
#if CONFIG_BT_NIMBLE_ENABLED && CONFIG_BLE_MESH_USE_BLE_50
void bt_mesh_ble_nimble_evt_to_btc(struct ble_gap_event *event, void *arg)
{
esp_ble_mesh_ble_cb_param_t param = {0};
if (addr == NULL) {
if (event == NULL) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
memcpy(param.scan_ble_adv_pkt.addr, addr->val, sizeof(addr->val));
param.scan_ble_adv_pkt.addr_type = addr->type;
if (data && length) {
param.scan_ble_adv_pkt.data = data;
param.scan_ble_adv_pkt.length = length;
memcpy(&param.nimble_gap_evt.event, event, sizeof(struct ble_gap_event));
param.nimble_gap_evt.arg = arg;
btc_ble_mesh_ble_callback(&param, ESP_BLE_MESH_NIMBLE_GAP_EVENT_EVT);
}
#endif /* CONFIG_BT_NIMBLE_ENABLED && CONFIG_BLE_MESH_USE_BLE_50 */
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
void bt_mesh_ble_scan_cb_evt_to_btc(bt_mesh_ble_adv_report_t *adv_report)
{
esp_ble_mesh_ble_cb_param_t param = {0};
if (adv_report == NULL) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
param.scan_ble_adv_pkt.adv_type = adv_type;
param.scan_ble_adv_pkt.rssi = rssi;
memcpy(&param.scan_ble_adv_pkt, adv_report, sizeof(bt_mesh_ble_adv_report_t));
btc_ble_mesh_ble_callback(&param, ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT);
}
@ -157,6 +165,14 @@ void btc_ble_mesh_ble_call_handler(btc_msg_t *msg)
btc_ble_mesh_ble_callback(&param, ESP_BLE_MESH_STOP_BLE_SCANNING_COMP_EVT);
break;
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
case BTC_BLE_MESH_ACT_UPDATE_SCAN_PARAMS:
struct bt_mesh_scan_param scan_param = {
.interval = arg->scan_params.scan_interval,
.window = arg->scan_params.uncoded_scan_window,
};
param.scan_params_update_comp.err_code = bt_mesh_scan_param_update(&scan_param);
btc_ble_mesh_ble_callback(&param, ESP_BLE_MESH_SCAN_PARAMS_UPDATE_COMP_EVT);
break;
default:
return;
}
@ -191,5 +207,4 @@ void btc_ble_mesh_ble_cb_handler(btc_msg_t *msg)
btc_ble_mesh_ble_free_req_data(msg);
}
#endif /* CONFIG_BLE_MESH_BLE_COEX_SUPPORT */
#endif /* (CONFIG_BLE_MESH_BLE_COEX_SUPPORT || CONFIG_BLE_MESH_USE_BLE_50) */

View File

@ -30,6 +30,7 @@
#endif /* CONFIG_BLE_MESH_V11_SUPPORT */
#include "adv.h"
#include "scan.h"
#include "mesh/kernel.h"
#include "mesh/proxy.h"
#include "mesh.h"
@ -2948,6 +2949,7 @@ void btc_ble_mesh_model_call_handler(btc_msg_t *msg)
.ctx.send_tag = arg->model_send.ctx->send_tag,
.msg_timeout = arg->model_send.msg_timeout,
};
err = bt_mesh_client_send_msg(&param, buf, arg->model_send.need_rsp,
btc_ble_mesh_client_model_timeout_cb);
bt_mesh_free_buf(buf);

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -16,6 +16,30 @@
extern "C" {
#endif
typedef struct {
uint8_t addr[6]; /*!< Device address */
uint8_t addr_type; /*!< Device address type */
#if CONFIG_BLE_MESH_USE_BLE_50
uint8_t adv_type __attribute__((deprecated("`event_type` should be used to determine the advertising type"))); /*!< advertising type */
#else
uint8_t adv_type; /*!< Advertising type */
#endif
uint8_t *data; /*!< Advertising data */
uint16_t length; /*!< Advertising data length */
int8_t rssi; /*!< RSSI of the advertising packet */
#if CONFIG_BLE_MESH_USE_BLE_50
uint8_t event_type; /*!< Extended advertising event type */
uint8_t primary_phy; /*!< Extended advertising primary PHY */
uint8_t secondary_phy; /*!< Extended advertising secondary PHY */
uint8_t sid; /*!< Extended advertising set ID */
uint8_t tx_power; /*!< Extended advertising TX power */
uint8_t dir_addr_type; /*!< Direct address type */
uint8_t dir_addr[6]; /*!< Direct address */
uint8_t data_status; /*!< Data type */
uint16_t per_adv_interval; /*!< Periodic advertising interval */
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
} bt_mesh_ble_adv_report_t;
typedef union {
struct {
esp_ble_mesh_ble_adv_param_t param;
@ -30,6 +54,10 @@ typedef union {
struct {
/* RFU */
} stop_ble_scan;
struct ble_mesh_scan_params {
uint16_t scan_interval;
uint16_t uncoded_scan_window;
} scan_params;
} btc_ble_mesh_ble_args_t;
typedef enum {
@ -37,11 +65,14 @@ typedef enum {
BTC_BLE_MESH_ACT_STOP_BLE_ADV,
BTC_BLE_MESH_ACT_START_BLE_SCAN,
BTC_BLE_MESH_ACT_STOP_BLE_SCAN,
BTC_BLE_MESH_ACT_UPDATE_SCAN_PARAMS,
} btc_ble_mesh_ble_act_t;
void bt_mesh_ble_scan_cb_evt_to_btc(const bt_mesh_addr_t *addr,
uint8_t adv_type, uint8_t data[],
uint16_t length, int8_t rssi);
void bt_mesh_ble_scan_cb_evt_to_btc(bt_mesh_ble_adv_report_t *adv_report);
#if CONFIG_BT_NIMBLE_ENABLED && CONFIG_BLE_MESH_USE_BLE_50
void bt_mesh_ble_nimble_evt_to_btc(struct ble_gap_event *event, void *arg);
#endif /* CONFIG_BT_NIMBLE_ENABLED && CONFIG_BLE_MESH_USE_BLE_50 */
void btc_ble_mesh_ble_call_handler(btc_msg_t *msg);

View File

@ -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
*/

View File

@ -200,7 +200,7 @@ extern "C" {
* { MY_PWM0 , MY_PWM1 }
*
* @param LEN The length of the sequence. Must be an integer literal less
* than 255.
* than 255 (ref: utils_loops.h).
* @param F A macro function that accepts at least two arguments:
* <tt>F(i, ...)</tt>. @p F is called repeatedly in the expansion.
* Its first argument @p i is the index in the sequence, and

View File

@ -45,6 +45,14 @@ static const uint8_t adv_type[] = {
[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);
@ -122,11 +130,51 @@ struct bt_mesh_adv_task {
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,
const struct bt_mesh_send_cb *cb,
void *cb_data)
@ -155,8 +203,16 @@ uint16_t bt_mesh_pdu_duration(uint8_t xmit)
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)
{
#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;
void *cb_data = BLE_MESH_ADV(buf)->cb_data;
struct bt_mesh_adv_param param = {0};
@ -187,6 +243,11 @@ static inline int adv_send(struct net_buf *buf)
param.interval_min = ADV_SCAN_UNIT(adv_int);
param.interval_max = param.interval_min;
#if CONFIG_BLE_MESH_USE_BLE_50
param.adv_duration = duration;
param.adv_count = BLE_MESH_TRANSMIT_COUNT(BLE_MESH_ADV(buf)->xmit) + 1;
#endif
#if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX
if (BLE_MESH_ADV(buf)->type == BLE_MESH_ADV_PROXY_SOLIC) {
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
@ -195,12 +256,24 @@ static inline int adv_send(struct net_buf *buf)
BLE_MESH_ADV_DATA_BYTES(BLE_MESH_DATA_UUID16_ALL, 0x59, 0x18),
BLE_MESH_ADV_DATA(BLE_MESH_DATA_SVC_DATA16, buf->data, buf->len),
};
err = bt_le_adv_start(&param, solic_ad, 3, NULL, 0);
#if CONFIG_BLE_MESH_USE_BLE_50
param.primary_phy = BLE_MESH_ADV_PHY_1M;
param.secondary_phy = BLE_MESH_ADV_PHY_1M;
err = bt_le_ext_adv_start(adv_ins->id, &param, &ad, 3, NULL, 0);
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
err = bt_le_adv_start(&param, &ad, 3, NULL, 0);
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
} else
#endif
{
bt_mesh_adv_buf_ref_debug(__func__, buf, 4U, BLE_MESH_BUF_REF_SMALL);
#if CONFIG_BLE_MESH_USE_BLE_50
param.primary_phy = BLE_MESH_ADV_PHY_1M;
param.secondary_phy = BLE_MESH_ADV_PHY_1M;
err = bt_le_ext_adv_start(adv_ins->id, &param, &ad, 1, NULL, 0);
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
err = bt_le_adv_start(&param, &ad, 1, NULL, 0);
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
}
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
} else {
@ -229,7 +302,11 @@ static inline int adv_send(struct net_buf *buf)
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
#if CONFIG_BLE_MESH_USE_BLE_50
err = bt_mesh_ble_ext_adv_start(adv_ins->id, &tx->param, &data);
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
err = bt_mesh_ble_adv_start(&tx->param, &data);
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
}
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
@ -242,9 +319,19 @@ static inline int adv_send(struct net_buf *buf)
BT_DBG("Advertising started. Sleeping %u ms", duration);
#if CONFIG_BLE_MESH_USE_BLE_50
if (!ble_mesh_adv_task_wait(K_WAIT(K_FOREVER), NULL)) {
BT_WARN("Advertising didn't finish on time");
bt_le_ext_adv_stop(adv_ins->id);
}
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
k_sleep(K_MSEC(duration));
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
#if !CONFIG_BLE_MESH_USE_BLE_50
err = bt_le_adv_stop();
#endif
adv_send_end(err, cb, cb_data);
if (err) {
BT_ERR("Stop advertising failed: err %d", err);
@ -255,11 +342,6 @@ static inline int adv_send(struct net_buf *buf)
return 0;
}
static inline TickType_t K_WAIT(int32_t val)
{
return (val == K_FOREVER) ? portMAX_DELAY : (val / portTICK_PERIOD_MS);
}
static void adv_thread(void *p)
{
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
@ -679,6 +761,10 @@ void bt_mesh_adv_deinit(void)
return;
}
#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 && \

View File

@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -13,6 +13,7 @@
#include "mesh/atomic.h"
#include "mesh/access.h"
#include "mesh/adapter.h"
#include "mesh/utils.h"
#ifdef __cplusplus
extern "C" {
@ -67,6 +68,19 @@ typedef enum {
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);
@ -81,6 +95,10 @@ void bt_mesh_adv_send(struct net_buf *buf, uint8_t xmit,
const struct bt_mesh_send_cb *cb,
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,

View File

@ -29,8 +29,10 @@
#include "mesh/adapter.h"
#include "mesh/common.h"
#include "prov_pvnr.h"
#include "scan.h"
#include "net.h"
#include "beacon.h"
#include "btc_ble_mesh_ble.h"
#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
@ -60,7 +62,10 @@ static uint8_t bt_mesh_private_key[32];
/* Scan related functions */
static bt_mesh_scan_cb_t *bt_mesh_scan_dev_found_cb;
#if !CONFIG_BLE_MESH_USE_BLE_50
static void bt_mesh_scan_result_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data);
#endif
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_SERVER || \
@ -104,6 +109,14 @@ static struct bt_mesh_prov_conn_cb *bt_mesh_gattc_conn_cb;
static tBTA_GATTC_IF bt_mesh_gattc_if;
#endif
#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BLE_MESH_SUPPORT_BLE_ADV
static inline void bt_mesh_set_ble_adv_running();
static inline void bt_mesh_unset_ble_adv_running();
static inline bool bt_mesh_is_ble_adv_running();
#endif
int bt_mesh_host_init(void)
{
return 0;
@ -138,11 +151,18 @@ void bt_mesh_hci_init(void)
const uint8_t *p = controller_get_interface()->get_ble_supported_states();
uint64_t states_fh = 0, states_sh = 0;
STREAM_TO_UINT32(states_fh, p);
STREAM_TO_UINT32(states_sh, p);
/* macro STREAM_TO_UINT32 expansion */
states_fh = (((uint32_t)(*(p))) + ((((uint32_t)(*((p) + 1)))) << 8) + ((((uint32_t)(*((p) + 2)))) << 16) + ((((uint32_t)(*((p) + 3)))) << 24));
(p) += 4;
states_sh = (((uint32_t)(*(p))) + ((((uint32_t)(*((p) + 1)))) << 8) + ((((uint32_t)(*((p) + 2)))) << 16) + ((((uint32_t)(*((p) + 3)))) << 24));
(p) += 4;
bt_mesh_dev.le.states = (states_sh << 32) | states_fh;
}
#if !CONFIG_BLE_MESH_USE_BLE_50
static void bt_mesh_scan_results_change_2_bta(tBTM_INQ_RESULTS *p_inq, uint8_t *p_eir,
tBTA_DM_SEARCH_CBACK *p_scan_cback)
{
@ -185,6 +205,189 @@ static void bt_mesh_scan_results_cb(tBTM_INQ_RESULTS *p_inq, uint8_t *p_eir)
{
bt_mesh_scan_results_change_2_bta(p_inq, p_eir, bt_mesh_scan_result_callback);
}
#endif
#if CONFIG_BLE_MESH_USE_BLE_50
extern void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
tBTA_DM_BLE_5_GAP_CB_PARAMS *params);
void bt_mesh_ble_ext_adv_report(tBTM_BLE_EXT_ADV_REPORT *ext_adv_report)
{
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
bt_mesh_ble_adv_report_t adv_rpt = {0};
if (bt_mesh_ble_scan_state_get()) {
memcpy(adv_rpt.addr, ext_adv_report->addr, BLE_MESH_ADDR_LEN);
memcpy(adv_rpt.dir_addr, ext_adv_report->dir_addr, BLE_MESH_ADDR_LEN);
adv_rpt.addr_type = ext_adv_report->addr_type;
adv_rpt.data = ext_adv_report->adv_data;
adv_rpt.length = ext_adv_report->adv_data_len;
adv_rpt.rssi = ext_adv_report->rssi;
adv_rpt.event_type = ext_adv_report->event_type;
adv_rpt.primary_phy = ext_adv_report->primary_phy;
adv_rpt.secondary_phy = ext_adv_report->secondry_phy;
adv_rpt.sid = ext_adv_report->sid;
adv_rpt.tx_power = ext_adv_report->tx_power;
adv_rpt.dir_addr_type = ext_adv_report->dir_addr_type;
adv_rpt.data_status = ext_adv_report->data_status;
adv_rpt.per_adv_interval = ext_adv_report->per_adv_interval;
bt_mesh_ble_scan_cb_evt_to_btc(&adv_rpt);
}
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
}
static bool bt_mesh_scan_result_process(tBTM_BLE_EXT_ADV_REPORT *ext_adv_report)
{
struct bt_mesh_adv_report adv_rpt = {0};
assert(ext_adv_report);
adv_rpt.addr.type = ext_adv_report->addr_type;
memcpy(adv_rpt.addr.val, ext_adv_report->addr, BLE_MESH_ADDR_LEN);
adv_rpt.primary_phy = ext_adv_report->primary_phy;
adv_rpt.secondary_phy = ext_adv_report->secondry_phy;
adv_rpt.rssi = ext_adv_report->rssi;
if (!(ext_adv_report->event_type & BTM_BLE_ADV_LEGACY_MASK)) {
return false;
}
if (!bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) {
return false;
}
BT_DBG("Recv adv report type %04x", ext_adv_report->event_type);
switch (ext_adv_report->event_type) {
case BLE_MESH_ADV_IND:
case BLE_MESH_ADV_DIRECT_IND:
case BLE_MESH_ADV_SCAN_IND:
case BLE_MESH_ADV_NONCONN_IND:
case BLE_MESH_ADV_SCAN_RSP:
adv_rpt.adv_type = ext_adv_report->event_type;
break;
default:
return false;
break;
}
if (bt_mesh_scan_dev_found_cb) {
net_buf_simple_init_with_data(&adv_rpt.adv_data, ext_adv_report->adv_data, ext_adv_report->adv_data_len);
bt_mesh_scan_dev_found_cb(&adv_rpt);
if (adv_rpt.adv_data.len != ext_adv_report->adv_data_len) {
/* The advertising data has been processed by Mesh Protocol */
return true;
}
}
return false;
}
void ble_mesh_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
tBTA_DM_BLE_5_GAP_CB_PARAMS *params)
{
BT_DBG("recv event %d", event);
switch (event) {
case BTA_DM_BLE_5_GAP_EXT_ADV_SET_PARAMS_COMPLETE_EVT:
if (!bt_mesh_is_adv_inst_used(params->set_params.instance)) {
goto transfer_to_user;
}
if (params->set_params.status != BTM_SUCCESS) {
BT_ERR("BTA_DM_BLE_5_GAP_EXT_ADV_SET_PARAMS_COMPLETE_EVT Failed");
}
break;
case BTA_DM_BLE_5_GAP_EXT_ADV_DATA_SET_COMPLETE_EVT:
if (!bt_mesh_is_adv_inst_used(params->adv_data_set.instance)) {
goto transfer_to_user;
}
if (params->adv_data_set.status != BTM_SUCCESS) {
BT_ERR("BTA_DM_BLE_5_GAP_EXT_ADV_DATA_SET_COMPLETE_EVT Failed");
}
break;
case BTA_DM_BLE_5_GAP_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT:
if (!bt_mesh_is_adv_inst_used(params->scan_rsp_data_set.instance)) {
goto transfer_to_user;
}
if (params->scan_rsp_data_set.status != BTM_SUCCESS) {
BT_ERR("BTA_DM_BLE_5_GAP_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT Failed");
}
break;
case BTA_DM_BLE_5_GAP_EXT_ADV_START_COMPLETE_EVT:
if (!bt_mesh_is_adv_inst_used(params->adv_start.instance[0])) {
goto transfer_to_user;
}
if (params->adv_start.status != BTM_SUCCESS) {
BT_ERR("BTA_DM_BLE_5_GAP_EXT_ADV_START_COMPLETE_EVT Failed");
}
break;
case BTA_DM_BLE_5_GAP_EXT_ADV_STOP_COMPLETE_EVT:
if (!bt_mesh_is_adv_inst_used(params->adv_start.instance[0])) {
goto transfer_to_user;
}
if (params->adv_start.status != BTM_SUCCESS) {
BT_ERR("BTA_DM_BLE_5_GAP_EXT_ADV_STOP_COMPLETE_EVT Failed");
}
break;
case BTA_DM_BLE_5_GAP_ADV_TERMINATED_EVT:
if (!bt_mesh_is_adv_inst_used(params->adv_term.adv_handle)) {
goto transfer_to_user;
}
if (params->adv_term.status == 0x43 || /* Limit reached */
params->adv_term.status == 0x3C) { /* Advertising timeout */
ble_mesh_adv_task_wakeup(params->adv_term.adv_handle);
}
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
/**
* This judgment is to distinguish between the termination
* events of BLE connectable broadcasting and proxy connectable
* adv under the same instance ID, that is, when the status is 0.
*
* Since the host task and adv task are currently operated in
* series, there is no need to consider competition issues between
* tasks.
*
* @attention: once multiple adv instances are used, the adv task
* and host will be asynchronous, and it is necessary to consider
* the issue of resource competition.
*/
if (bt_mesh_is_ble_adv_running() &&
params->adv_term.status == 0x00) {
/* The unset operation must be performed before waking up the
* adv task; performing the unset after waking up the adv task
* could lead to resource contention issues.
*/
bt_mesh_unset_ble_adv_running();
ble_mesh_adv_task_wakeup(params->adv_term.adv_handle);
}
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
break;
case BTA_DM_BLE_5_GAP_EXT_ADV_REPORT_EVT:
if (!bt_mesh_scan_result_process(&params->ext_adv_report)) {
bt_mesh_ble_ext_adv_report(&params->ext_adv_report);
}
break;
case BTA_DM_BLE_5_GAP_EXT_SCAN_START_COMPLETE_EVT:
if (params->scan_start.status != BTM_SUCCESS) {
BT_ERR("BTA_DM_BLE_5_GAP_EXT_SCAN_START_COMPLETE_EVT Failed");
}
break;
case BTA_DM_BLE_5_GAP_EXT_SCAN_STOP_COMPLETE_EVT:
if (params->scan_stop.status != BTM_SUCCESS) {
BT_ERR("BTM_BLE_5_GAP_EXT_SCAN_START_COMPLETE_EVT Failed");
}
break;
default:
goto transfer_to_user;
}
return;
transfer_to_user:
btc_ble_5_gap_callback(event, params);
}
#endif
static bool valid_adv_param(const struct bt_mesh_adv_param *param)
{
@ -205,7 +408,12 @@ static bool valid_adv_param(const struct bt_mesh_adv_param *param)
return true;
}
#if CONFIG_BLE_MESH_USE_BLE_50
static int set_adv_data(uint16_t hci_op, const uint8_t inst_id,
const struct bt_mesh_adv_data *ad, size_t ad_len)
#else
static int set_adv_data(uint16_t hci_op, const struct bt_mesh_adv_data *ad, size_t ad_len)
#endif
{
struct bt_mesh_hci_cp_set_adv_data param = {0};
int i;
@ -227,16 +435,22 @@ static int set_adv_data(uint16_t hci_op, const struct bt_mesh_adv_data *ad, size
param.len += ad[i].data_len;
}
#if CONFIG_BLE_MESH_USE_BLE_50
BTA_DmBleGapConfigExtAdvDataRaw(hci_op == BLE_MESH_HCI_OP_SET_SCAN_RSP_DATA,
inst_id, param.len, param.data);
#else
/* Set adv data and scan rsp data. */
if (hci_op == BLE_MESH_HCI_OP_SET_ADV_DATA) {
BLE_MESH_BTM_CHECK_STATUS(BTM_BleWriteAdvDataRaw(param.data, param.len));
} else if (hci_op == BLE_MESH_HCI_OP_SET_SCAN_RSP_DATA) {
BLE_MESH_BTM_CHECK_STATUS(BTM_BleWriteScanRspRaw(param.data, param.len));
}
#endif
return 0;
}
#if !CONFIG_BLE_MESH_USE_BLE_50
static void start_adv_completed_cb(uint8_t status)
{
#if BLE_MESH_DEV
@ -245,6 +459,7 @@ static void start_adv_completed_cb(uint8_t status)
}
#endif
}
#endif
static bool valid_scan_param(const struct bt_mesh_scan_param *param)
{
@ -276,15 +491,54 @@ static bool valid_scan_param(const struct bt_mesh_scan_param *param)
static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window,
uint8_t filter_dup, uint8_t scan_fil_policy)
{
#if !CONFIG_BLE_MESH_USE_BLE_50
uint8_t addr_type_own = BLE_MESH_ADDR_PUBLIC; /* Currently only support Public Address */
tGATT_IF client_if = 0xFF; /* Default GATT interface id */
#endif
#if CONFIG_BLE_MESH_USE_BLE_50
tBTA_DM_BLE_EXT_SCAN_PARAMS ext_scan_params = {0};
if (interval == 0 ||
interval < window) {
BT_ERR("invalid scan param itvl %d win %d", interval, window);
return EINVAL;
}
ext_scan_params.own_addr_type = BLE_MESH_ADDR_PUBLIC;
ext_scan_params.filter_policy = scan_fil_policy;
ext_scan_params.scan_duplicate = filter_dup;
if (window == 0) {
ext_scan_params.cfg_mask = BTM_BLE_GAP_EXT_SCAN_CODE_MASK;
} else if (interval > window) {
ext_scan_params.cfg_mask = BTM_BLE_GAP_EXT_SCAN_UNCODE_MASK | BTM_BLE_GAP_EXT_SCAN_CODE_MASK;
} else {
// interval == window
ext_scan_params.cfg_mask = BTM_BLE_GAP_EXT_SCAN_UNCODE_MASK;
}
ext_scan_params.uncoded_cfg.scan_type = scan_type;
ext_scan_params.uncoded_cfg.scan_interval = interval;
ext_scan_params.uncoded_cfg.scan_window = window;
ext_scan_params.coded_cfg.scan_type = scan_type;
ext_scan_params.coded_cfg.scan_interval = interval;
ext_scan_params.coded_cfg.scan_window = interval - window;
BTA_DmBleGapSetExtScanParams(&ext_scan_params);
BTM_BleGapRegisterCallback(ble_mesh_5_gap_callback);
BTA_DmBleGapExtScan(true, 0, 0);
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
BLE_MESH_BTM_CHECK_STATUS(
BTM_BleSetScanFilterParams(client_if, interval, window, scan_type, addr_type_own,
filter_dup, scan_fil_policy, NULL));
/* BLE Mesh scan permanently, so no duration of scan here */
BLE_MESH_BTM_CHECK_STATUS(BTM_BleScan(true, 0, bt_mesh_scan_results_cb, NULL, NULL));
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
#if BLE_MESH_DEV
if (scan_type == BLE_MESH_SCAN_ACTIVE) {
@ -297,22 +551,32 @@ static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window,
return 0;
}
#if !CONFIG_BLE_MESH_USE_BLE_50
static void bt_mesh_scan_result_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
{
struct net_buf_simple buf = {0};
bt_mesh_addr_t addr = {0};
struct bt_mesh_adv_report adv_rpt = {0};
BT_DBG("%s, event %d", __func__, event);
if (event == BTA_DM_INQ_RES_EVT) {
/* TODO: How to process scan response here? PS: p_data->inq_res.scan_rsp_len */
addr.type = p_data->inq_res.ble_addr_type;
memcpy(addr.val, p_data->inq_res.bd_addr, BLE_MESH_ADDR_LEN);
net_buf_simple_init_with_data(&buf, p_data->inq_res.p_eir, p_data->inq_res.adv_data_len);
adv_rpt.addr.type = p_data->inq_res.ble_addr_type;
adv_rpt.rssi = p_data->inq_res.rssi;
adv_rpt.adv_type = p_data->inq_res.ble_evt_type;
memcpy(adv_rpt.addr.val, p_data->inq_res.bd_addr, BLE_MESH_ADDR_LEN);
net_buf_simple_init_with_data(&adv_rpt.adv_data, p_data->inq_res.p_eir, p_data->inq_res.adv_data_len);
if (bt_mesh_scan_dev_found_cb) {
bt_mesh_scan_dev_found_cb(&addr, p_data->inq_res.rssi, p_data->inq_res.ble_evt_type, &buf, p_data->inq_res.scan_rsp_len);
bt_mesh_scan_dev_found_cb(&adv_rpt);
if (p_data->inq_res.scan_rsp_len) {
adv_rpt.adv_type = BLE_MESH_ADV_SCAN_RSP;
net_buf_simple_init_with_data(&adv_rpt.adv_data, p_data->inq_res.p_eir + p_data->inq_res.adv_data_len, p_data->inq_res.scan_rsp_len);
bt_mesh_scan_dev_found_cb(&adv_rpt);
}
}
} else if (event == BTA_DM_INQ_CMPL_EVT) {
BT_INFO("Scan completed, number of scan response %d", p_data->inq_cmpl.num_resps);
@ -320,7 +584,132 @@ static void bt_mesh_scan_result_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARC
BT_WARN("Unexpected scan result event %d", event);
}
}
#endif
#if CONFIG_BLE_MESH_USE_BLE_50
int bt_le_ext_adv_start(const uint8_t inst_id,
const struct bt_mesh_adv_param *param,
const struct bt_mesh_adv_data *ad, size_t ad_len,
const struct bt_mesh_adv_data *sd, size_t sd_len)
{
tBTA_DM_BLE_GAP_EXT_ADV_PARAMS ext_adv_params = {0};
tBTA_DM_BLE_EXT_ADV ext_adv = {0};
uint16_t interval = 0U;
int err = 0;
assert(param);
#if BLE_MESH_DEV
if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING)) {
return -EALREADY;
}
#endif
if (!valid_adv_param(param)) {
BT_ERR("Invalid adv parameters");
return -EINVAL;
}
memset(&ext_adv_params, 0, sizeof(tBTA_DM_BLE_GAP_EXT_ADV_PARAMS));
if (param->options & BLE_MESH_ADV_OPT_CONNECTABLE) {
ext_adv_params.type = BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_IND;
} else if (sd != NULL) {
ext_adv_params.type = BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_SCAN;
} else {
if (param->primary_phy == BLE_MESH_ADV_PHY_1M &&
param->secondary_phy == BLE_MESH_ADV_PHY_1M) {
ext_adv_params.type = BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_NONCONN;
} else {
BT_ERR("Unsupported PHY: pri %d sec %d",param->primary_phy, param->secondary_phy);
return -EINVAL;
}
}
#if CONFIG_BLE_MESH_PRB_SRV
/* NOTE: When a Mesh Private beacon is advertised, the Mesh Private beacon shall
* use a resolvable private address or a non-resolvable private address in the
* AdvA field of the advertising PDU.
*/
if (ad->type == BLE_MESH_DATA_MESH_BEACON && ad->data[0] == BEACON_TYPE_PRIVATE) {
ext_adv_params.own_addr_type = BLE_MESH_ADDR_RANDOM;
} else {
ext_adv_params.own_addr_type = BLE_MESH_ADDR_PUBLIC;
}
#else
ext_adv_params.own_addr_type = BLE_MESH_ADDR_PUBLIC;
#endif
ext_adv_params.sid = inst_id;
ext_adv_params.max_skip = 0;
ext_adv_params.tx_power = 0x7F;
ext_adv_params.scan_req_notif = false;
ext_adv_params.primary_phy = param->primary_phy;
ext_adv_params.secondary_phy = param->secondary_phy;
ext_adv_params.filter_policy = BLE_MESH_AP_SCAN_CONN_ALL;
ext_adv_params.channel_map = BLE_MESH_ADV_CHNL_37 | BLE_MESH_ADV_CHNL_38 | BLE_MESH_ADV_CHNL_39;
interval = param->interval_min;
#if CONFIG_BLE_MESH_RANDOM_ADV_INTERVAL
/* If non-connectable mesh packets are transmitted with an adv interval
* not smaller than 10ms, then we will use a random adv interval between
* [interval / 2, interval] for them.
*/
if (adv_type == BLE_MESH_ADV_NONCONN_IND && interval >= 16) {
interval >>= 1;
interval += (bt_mesh_get_rand() % (interval + 1));
BT_INFO("%u->%u", param->interval_min, interval);
}
#endif
ext_adv_params.interval_min = interval;
ext_adv_params.interval_max = interval;
/* Check if we can start adv using BTM_BleSetAdvParamsStartAdvCheck */
BTA_DmBleGapExtAdvSetParams(inst_id, &ext_adv_params);
err = set_adv_data(BLE_MESH_HCI_OP_SET_ADV_DATA, inst_id, ad, ad_len);
if (err) {
BT_ERR("Failed to set adv data, err %d", err);
return err;
}
/*
* We need to set SCAN_RSP when enabling advertising type that allows
* for Scan Requests.
*
* If sd was not provided but we enable connectable undirected
* advertising sd needs to be cleared from values set by previous calls.
* Clearing sd is done by calling set_adv_data() with NULL data and zero len.
* So following condition check is unusual but correct.
*/
if (sd && (param->options & BLE_MESH_ADV_OPT_CONNECTABLE)) {
err = set_adv_data(BLE_MESH_HCI_OP_SET_SCAN_RSP_DATA, inst_id, sd, sd_len);
if (err) {
BT_ERR("Failed to set scan rsp data err %d", err);
return err;
}
}
ext_adv.instance = inst_id;
ext_adv.duration = param->adv_duration / 10;
ext_adv.max_events = param->adv_count;
BTA_DmBleGapExtAdvEnable(true, 1, &ext_adv);
#if BLE_MESH_DEV
bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
if (!(param->options & BLE_MESH_ADV_OPT_ONE_TIME)) {
bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_KEEP_ADVERTISING);
}
#endif
return 0;
}
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
/* APIs functions */
int bt_le_adv_start(const struct bt_mesh_adv_param *param,
const struct bt_mesh_adv_data *ad, size_t ad_len,
@ -348,7 +737,7 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param,
err = set_adv_data(BLE_MESH_HCI_OP_SET_ADV_DATA, ad, ad_len);
if (err) {
BT_ERR("Failed to set adv data");
BT_ERR("Failed to set adv data, err %d", err);
return err;
}
@ -364,7 +753,7 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param,
if (sd && (param->options & BLE_MESH_ADV_OPT_CONNECTABLE)) {
err = set_adv_data(BLE_MESH_HCI_OP_SET_SCAN_RSP_DATA, sd, sd_len);
if (err) {
BT_ERR("Failed to set scan rsp data");
BT_ERR("Failed to set scan rsp data, err %d", err);
return err;
}
}
@ -427,8 +816,97 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param,
return 0;
}
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
#if CONFIG_BLE_MESH_USE_BLE_50
static bool _ble_adv_running_flag;
static inline void bt_mesh_set_ble_adv_running()
{
_ble_adv_running_flag = true;
}
static inline void bt_mesh_unset_ble_adv_running()
{
_ble_adv_running_flag = false;
}
static inline bool bt_mesh_is_ble_adv_running()
{
return _ble_adv_running_flag == true;
}
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_data *data)
{
tBTA_DM_BLE_GAP_EXT_ADV_PARAMS ext_adv_params = {0};
tBTA_DM_BLE_EXT_ADV ext_adv = {0};
struct bt_mesh_hci_cp_set_adv_data set = {0};
if (data && param->adv_type != BLE_MESH_ADV_DIRECT_IND &&
param->adv_type != BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) {
if (data->adv_data_len) {
set.len = data->adv_data_len;
memcpy(set.data, data->adv_data, data->adv_data_len);
BTA_DmBleGapConfigExtAdvDataRaw(false, inst_id, set.len, set.data);
}
if (data->scan_rsp_data_len && param->adv_type != BLE_MESH_ADV_NONCONN_IND) {
set.len = data->scan_rsp_data_len;
memcpy(set.data, data->scan_rsp_data, data->scan_rsp_data_len);
BTA_DmBleGapConfigExtAdvDataRaw(true, inst_id, set.len, set.data);
}
}
switch (param->adv_type) {
case BLE_MESH_ADV_IND:
case BLE_MESH_ADV_DIRECT_IND:
case BLE_MESH_ADV_SCAN_IND:
case BLE_MESH_ADV_NONCONN_IND:
case BLE_MESH_ADV_SCAN_RSP:
ext_adv_params.type = param->adv_type;
break;
default:
BT_ERR("Unsupported adv type %d", param->adv_type);
return -EINVAL;
}
ext_adv_params.max_skip = 0;
ext_adv_params.tx_power = 0x7F;
ext_adv_params.sid = inst_id;
ext_adv_params.scan_req_notif = false;
ext_adv_params.own_addr_type = param->own_addr_type;
ext_adv_params.interval_min = param->interval;
ext_adv_params.interval_max = param->interval;
ext_adv_params.primary_phy = BLE_MESH_ADV_PHY_1M;
ext_adv_params.secondary_phy = BLE_MESH_ADV_PHY_1M;
ext_adv_params.filter_policy = BLE_MESH_AP_SCAN_CONN_ALL;
ext_adv_params.channel_map = BLE_MESH_ADV_CHNL_37 | BLE_MESH_ADV_CHNL_38 | BLE_MESH_ADV_CHNL_39;
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) {
ext_adv_params.peer_addr_type = param->peer_addr_type;
memcpy(ext_adv_params.peer_addr, param->peer_addr, BLE_MESH_ADDR_LEN);
}
ext_adv.instance = inst_id;
ext_adv.duration = param->duration;
ext_adv.max_events = param->count;
/* Check if we can start adv using BTM_BleSetAdvParamsStartAdvCheck */
BTA_DmBleGapExtAdvSetParams(inst_id, &ext_adv_params);
BTA_DmBleGapExtAdvEnable(true, 1, &ext_adv);
bt_mesh_set_ble_adv_running();
return 0;
}
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
int bt_mesh_ble_adv_start(const struct bt_mesh_ble_adv_param *param,
const struct bt_mesh_ble_adv_data *data)
{
@ -470,8 +948,32 @@ int bt_mesh_ble_adv_start(const struct bt_mesh_ble_adv_param *param,
return 0;
}
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
#if CONFIG_BLE_MESH_USE_BLE_50
int bt_le_ext_adv_stop(uint8_t inst_id)
{
tBTA_DM_BLE_EXT_ADV ext_adv = {0};
#if BLE_MESH_DEV
bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_KEEP_ADVERTISING);
if (!bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING)) {
return 0;
}
#endif
ext_adv.instance = inst_id;
BTA_DmBleGapExtAdvEnable(false, 1, &ext_adv);
#if BLE_MESH_DEV
bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
#endif
return 0;
}
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
int bt_le_adv_stop(void)
{
#if BLE_MESH_DEV
@ -489,6 +991,7 @@ int bt_le_adv_stop(void)
return 0;
}
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
int bt_le_scan_start(const struct bt_mesh_scan_param *param, bt_mesh_scan_cb_t cb)
{
@ -530,7 +1033,11 @@ int bt_le_scan_stop(void)
return -EALREADY;
}
#if CONFIG_BLE_MESH_USE_BLE_50
BTA_DmBleGapExtScan(false, 0 ,0);
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
BLE_MESH_BTM_CHECK_STATUS(BTM_BleScan(false, 0, NULL, NULL, NULL));
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING);
bt_mesh_scan_dev_found_cb = NULL;
@ -1198,6 +1705,9 @@ uint16_t bt_mesh_gattc_get_service_uuid(struct bt_mesh_conn *conn)
int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, uint16_t service_uuid)
{
#if CONFIG_BLE_MESH_USE_BLE_50
tBTA_DM_BLE_CONN_PARAMS conn_1m_param = {0};
#endif
uint8_t zero[6] = {0};
int i;
@ -1240,21 +1750,47 @@ int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, uint16_t service_uuid)
}
if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) {
#if CONFIG_BLE_MESH_USE_BLE_50
BTA_DmBleGapExtScan(false, 0 ,0);
#else
BLE_MESH_BTM_CHECK_STATUS(BTM_BleScan(false, 0, NULL, NULL, NULL));
#endif
bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING);
}
BT_DBG("Create conn with %s", bt_hex(addr->val, BLE_MESH_ADDR_LEN));
#if CONFIG_BLE_MESH_USE_BLE_50
/* Min_interval: 15ms 0x18, 0x18, 0x00, 0x64
* Max_interval: 15ms
* Slave_latency: 0x0
* Supervision_timeout: 1s
*/
conn_1m_param.scan_interval = 0x0020;
conn_1m_param.scan_window = 0x0020;
conn_1m_param.interval_min = 0x18;
conn_1m_param.interval_max = 0x18;
conn_1m_param.latency = 0;
conn_1m_param.supervision_timeout = 0x64;
conn_1m_param.min_ce_len = 0;
conn_1m_param.max_ce_len = 0;
BTA_DmBleGapPreferExtConnectParamsSet(bt_mesh_gattc_info[i].addr.val, 0x01, &conn_1m_param ,NULL, NULL);
BTA_GATTC_Open(bt_mesh_gattc_if, bt_mesh_gattc_info[i].addr.val,
bt_mesh_gattc_info[i].addr.type, true, BTA_GATT_TRANSPORT_LE, TRUE);
#else
/* Min_interval: 15ms
* Max_interval: 15ms
* Slave_latency: 0x0
* Supervision_timeout: 1s
*/
BTA_DmSetBlePrefConnParams(bt_mesh_gattc_info[i].addr.val, 0x18, 0x18, 0x00, 0x64);
BTA_GATTC_Open(bt_mesh_gattc_if, bt_mesh_gattc_info[i].addr.val,
bt_mesh_gattc_info[i].addr.type, true, BTA_GATT_TRANSPORT_LE, FALSE);
#endif
return 0;
}
@ -1655,11 +2191,15 @@ static void bt_mesh_bta_gattc_cb(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
* use BTM_BleScan() to re-enable scan.
*/
if (!bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) {
#if CONFIG_BLE_MESH_USE_BLE_50
BTA_DmBleGapExtScan(true, 0 ,0);
#else
tBTM_STATUS status = BTM_BleScan(true, 0, bt_mesh_scan_results_cb, NULL, NULL);
if (status != BTM_SUCCESS && status != BTM_CMD_STARTED) {
BT_ERR("Invalid scan status %d", status);
break;
}
#endif
bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING);
}
break;

View File

@ -4,7 +4,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileContributor: 2018-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

View File

@ -1,7 +1,7 @@
/*
* SPDX-FileCopyrightText: 2017 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2015-2017 Intel Corporation
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -33,6 +33,18 @@ extern "C" {
#define BLE_MESH_GATT_DEF_MTU_SIZE 23
#if CONFIG_BLE_MESH_USE_BLE_50
#define BLE_MESH_ADV_PHY_UNASSIGNED 0
#define BLE_MESH_ADV_PHY_1M 1
#define BLE_MESH_ADV_PHY_2M 2
#define BLE_MESH_ADV_PHY_CODED 3
#define BLE_MESH_ADV_PHY_OPTION_NO_PREFER 0
#define BLE_MESH_ADV_PHY_OPTION_PREFER_S2 1
#define BLE_MESH_ADV_PHY_OPTION_PREFER_S8 2
#define BLE_MESH_ADV_PHY_OPTION_REQUIRE_S2 3
#define BLE_MESH_ADV_PHY_OPTION_REQUIRE_S8 4
#endif
/* BD ADDR types */
#define BLE_MESH_ADDR_PUBLIC 0x00
#define BLE_MESH_ADDR_RANDOM 0x01
@ -43,11 +55,22 @@ extern "C" {
#define BLE_MESH_ADDR_LEN 0x06
/* Advertising types */
#if !CONFIG_BLE_MESH_USE_BLE_50
#define BLE_MESH_ADV_IND 0x00
#define BLE_MESH_ADV_DIRECT_IND 0x01
#define BLE_MESH_ADV_SCAN_IND 0x02
#define BLE_MESH_ADV_NONCONN_IND 0x03
#define BLE_MESH_ADV_DIRECT_IND_LOW_DUTY 0x04
#define BLE_MESH_ADV_SCAN_RSP 0x04
#else
/* Bluetooth Core Spec 6.0, Vol 4, Part E, 7.7.65.13 */
#define BLE_MESH_ADV_IND (0x13)
#define BLE_MESH_ADV_DIRECT_IND (0x15)
#define BLE_MESH_ADV_SCAN_IND (0x12)
#define BLE_MESH_ADV_NONCONN_IND (0x10)
#define BLE_MESH_ADV_DIRECT_IND_LOW_DUTY (0x1b)
#define BLE_MESH_ADV_SCAN_RSP (0x1b)
#endif
/* advertising channel map */
#define BLE_MESH_ADV_CHNL_37 BIT(0)
@ -400,8 +423,32 @@ struct bt_mesh_adv_param {
/** Maximum Advertising Interval (N * 0.625) */
uint16_t interval_max;
#if CONFIG_BLE_MESH_USE_BLE_50
/** Maximum Advertising Duration (N * 0.625) */
uint16_t adv_duration;
/** Advertising Packages Number */
uint16_t adv_count;
/** Advertising Primary PHY */
uint8_t primary_phy;
/** Advertising Secondary PHY */
uint8_t secondary_phy;
#endif
};
#if CONFIG_BLE_MESH_USE_BLE_50
enum bt_mesh_adv_inst_type {
BLE_MESH_ADV_PROXY_INS,
BLE_MESH_ADV_INS,
BLE_MESH_EXT_ADV_INS,
BLE_MESH_BLE_ADV_INS,
BLE_MESH_ADV_INS_TYPE_NUMS,
};
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
enum bt_mesh_ble_adv_priority {
BLE_MESH_BLE_ADV_PRIO_LOW,
@ -441,7 +488,7 @@ struct bt_mesh_scan_param {
/** Scan interval (N * 0.625 ms) */
uint16_t interval;
/** Scan window (N * 0.625 ms) */
/** Uncoded phy Scan window (N * 0.625 ms) */
uint16_t window;
/** BLE scan filter policy */
@ -453,21 +500,38 @@ struct bt_mesh_conn {
bt_mesh_atomic_t ref;
};
/* BLE Mesh advertising report */
struct bt_mesh_adv_report {
/* Advertiser LE address and type. */
bt_mesh_addr_t addr;
/* Strength of advertiser signal. */
int8_t rssi;
/* Type of advertising response from advertiser. */
uint8_t adv_type;
/* Buffer containing advertiser data. */
struct net_buf_simple adv_data;
#if CONFIG_BLE_MESH_USE_BLE_50
/* Primary advertising PHY */
uint8_t primary_phy;
/* Secondary advertising PHY */
uint8_t secondary_phy;
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
};
/** @typedef bt_mesh_scan_cb_t
* @brief Callback type for reporting LE scan results.
*
* A function of this type is given to the bt_le_scan_start() function
* and will be called for any discovered LE device.
*
* @param addr Advertiser LE address and type.
* @param rssi Strength of advertiser signal.
* @param adv_type Type of advertising response from advertiser.
* @param data Buffer containing advertiser data.
* @param scan_rsp_len Scan Response data length.
* @param adv_rpt: BLE Mesh advertising report.
*/
typedef void bt_mesh_scan_cb_t(const bt_mesh_addr_t *addr, int8_t rssi,
uint8_t adv_type, struct net_buf_simple *buf,
uint8_t scan_rsp_len);
typedef void bt_mesh_scan_cb_t(struct bt_mesh_adv_report *adv_rpt);
/* @typedef bt_mesh_dh_key_cb_t
* @brief Callback type for DH Key calculation.
@ -553,7 +617,7 @@ struct bt_mesh_gatt_attr {
* @param len Length of data to read
* @param offset Offset to start reading from
*
* @return Number fo bytes read, or in case of an error
* @return Number of bytes read, or in case of an error
* BLE_MESH_GATT_ERR() with a specific ATT error code.
*/
ssize_t (*read)(struct bt_mesh_conn *conn,
@ -684,6 +748,21 @@ struct bt_mesh_gatt_attr {
int bt_mesh_host_init(void);
int bt_mesh_host_deinit(void);
#if CONFIG_BLE_MESH_USE_BLE_50
int bt_le_ext_adv_start(const uint8_t inst_id,
const struct bt_mesh_adv_param *param,
const struct bt_mesh_adv_data *ad, size_t ad_len,
const struct bt_mesh_adv_data *sd, size_t sd_len);
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
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_data *adv_data);
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
int bt_le_ext_adv_stop(uint8_t inst_id);
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
int bt_le_adv_start(const struct bt_mesh_adv_param *param,
const struct bt_mesh_adv_data *ad, size_t ad_len,
const struct bt_mesh_adv_data *sd, size_t sd_len);
@ -691,9 +770,10 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param,
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
int bt_mesh_ble_adv_start(const struct bt_mesh_ble_adv_param *param,
const struct bt_mesh_ble_adv_data *data);
#endif
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
int bt_le_adv_stop(void);
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
int bt_le_scan_start(const struct bt_mesh_scan_param *param, bt_mesh_scan_cb_t cb);

View File

@ -13,6 +13,7 @@
#include "crypto.h"
#include "adv.h"
#include "net.h"
#include "scan.h"
#include "mesh.h"
#include "lpn.h"
@ -1123,6 +1124,15 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf,
tx->ctx->send_cred != BLE_MESH_FRIENDSHIP_CRED) {
if (bt_mesh_proxy_server_relay(&buf->b, tx->ctx->addr) &&
BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) {
/**
* When a message is sent to a proxy client, the message
* can be sent via GATT only, eliminating the need for
* an ADV bearer.
*/
if (bt_mesh_proxy_server_find_client_by_addr(tx->ctx->addr)) {
bearer &= ~BLE_MESH_ADV_BEARER;
}
/* Notify completion if this only went
* through the Mesh Proxy.
*/
@ -1892,24 +1902,26 @@ static bool ignore_net_msg(uint16_t src, uint16_t dst)
return false;
}
void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi,
enum bt_mesh_net_if net_if)
void bt_mesh_generic_net_recv(struct net_buf_simple *data,
struct bt_mesh_net_rx *rx,
enum bt_mesh_net_if net_if)
{
NET_BUF_SIMPLE_DEFINE(buf, 29);
struct bt_mesh_net_rx rx = { .ctx.recv_rssi = rssi };
struct net_buf_simple_state state = {0};
BT_DBG("rssi %d net_if %u", rssi, net_if);
assert(rx);
BT_DBG("rssi %d net_if %u", rx->ctx.recv_rssi, net_if);
if (!ready_to_recv()) {
return;
}
if (bt_mesh_net_decode(data, net_if, &rx, &buf)) {
if (bt_mesh_net_decode(data, net_if, rx, &buf)) {
return;
}
if (ignore_net_msg(rx.ctx.addr, rx.ctx.recv_dst)) {
if (ignore_net_msg(rx->ctx.addr, rx->ctx.recv_dst)) {
return;
}
@ -1919,26 +1931,26 @@ void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi,
BT_BQB(BLE_MESH_BQB_TEST_LOG_LEVEL_PRIMARY_ID_NODE | \
BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_NET,
"\nNetRecv: ctl: %d, src: %d, dst: %d, ttl: %d, data: 0x%s",
rx.ctl, rx.ctx.addr, rx.ctx.recv_dst, rx.ctx.recv_ttl,
rx->ctl, rx->ctx.addr, rx->ctx.recv_dst, rx->ctx.recv_ttl,
bt_hex(buf.data + BLE_MESH_NET_HDR_LEN, buf.len - BLE_MESH_NET_HDR_LEN));
/* If trying to handle a message with DST set to all-directed-forwarding-nodes,
* we need to make sure the directed forwarding functionality is enabled in the
* corresponding subnet.
*/
rx.local_match = (bt_mesh_fixed_group_match(rx.ctx.recv_dst) ||
bt_mesh_fixed_direct_match(rx.sub, rx.ctx.recv_dst) ||
bt_mesh_elem_find(rx.ctx.recv_dst));
rx->local_match = (bt_mesh_fixed_group_match(rx->ctx.recv_dst) ||
bt_mesh_fixed_direct_match(rx->sub, rx->ctx.recv_dst) ||
bt_mesh_elem_find(rx->ctx.recv_dst));
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
#if CONFIG_BLE_MESH_PRB_SRV
bt_mesh_private_gatt_proxy_state_get() != BLE_MESH_PRIVATE_GATT_PROXY_ENABLED &&
#endif
net_if == BLE_MESH_NET_IF_PROXY) {
bt_mesh_proxy_server_addr_add(data, rx.ctx.addr);
bt_mesh_proxy_server_addr_add(data, rx->ctx.addr);
if (bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_DISABLED &&
!rx.local_match) {
!rx->local_match) {
BT_INFO("Proxy is disabled; ignoring message");
return;
}
@ -1951,11 +1963,11 @@ void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi,
* tag the Network PDU with the immutable-credentials tag.
*/
#if CONFIG_BLE_MESH_DF_SRV
if (rx.sub->directed_proxy == BLE_MESH_DIRECTED_PROXY_ENABLED &&
rx.sub->use_directed == BLE_MESH_PROXY_USE_DIRECTED_ENABLED &&
!bt_mesh_addr_in_uar(&rx.sub->proxy_client_uar, rx.ctx.addr) &&
!bt_mesh_proxy_server_find_client_by_addr(rx.ctx.addr)) {
rx.ctx.recv_tag |= BLE_MESH_TAG_IMMUTABLE_CRED;
if (rx->sub->directed_proxy == BLE_MESH_DIRECTED_PROXY_ENABLED &&
rx->sub->use_directed == BLE_MESH_PROXY_USE_DIRECTED_ENABLED &&
!bt_mesh_addr_in_uar(&rx->sub->proxy_client_uar, rx->ctx.addr) &&
!bt_mesh_proxy_server_find_client_by_addr(rx->ctx.addr)) {
rx->ctx.recv_tag |= BLE_MESH_TAG_IMMUTABLE_CRED;
}
#endif /* CONFIG_BLE_MESH_DF_SRV */
}
@ -1967,24 +1979,24 @@ void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi,
* credentials. Remove it from the message cache so that we accept
* it again in the future.
*/
if (bt_mesh_trans_recv(&buf, &rx) == -EAGAIN) {
if (bt_mesh_trans_recv(&buf, rx) == -EAGAIN) {
BT_WARN("Removing rejected message from Network Message Cache");
msg_cache[rx.msg_cache_idx].src = BLE_MESH_ADDR_UNASSIGNED;
msg_cache[rx->msg_cache_idx].src = BLE_MESH_ADDR_UNASSIGNED;
/* Rewind the next index now that we're not using this entry */
msg_cache_next = rx.msg_cache_idx;
msg_cache_next = rx->msg_cache_idx;
}
/* Relay if this was a group/virtual address, or if the destination
* was neither a local element nor an LPN we're Friends for.
*/
if (!BLE_MESH_ADDR_IS_UNICAST(rx.ctx.recv_dst) ||
(!rx.local_match && !rx.friend_match
if (!BLE_MESH_ADDR_IS_UNICAST(rx->ctx.recv_dst) ||
(!rx->local_match && !rx->friend_match
#if CONFIG_BLE_MESH_NOT_RELAY_REPLAY_MSG
&& !rx.replay_msg
&& !rx->replay_msg
#endif
)) {
net_buf_simple_restore(&buf, &state);
bt_mesh_net_relay(&buf, &rx);
bt_mesh_net_relay(&buf, rx);
}
}

View File

@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -465,8 +465,16 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf,
int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if,
struct bt_mesh_net_rx *rx, struct net_buf_simple *buf);
void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi,
enum bt_mesh_net_if net_if);
void bt_mesh_generic_net_recv(struct net_buf_simple *data,
struct bt_mesh_net_rx *rx,
enum bt_mesh_net_if net_if);
static inline void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi,
enum bt_mesh_net_if net_if)
{
struct bt_mesh_net_rx rx = { .ctx.recv_rssi = rssi };
bt_mesh_generic_net_recv(data, &rx, net_if);
}
bool bt_mesh_primary_subnet_exist(void);

View File

@ -1,7 +1,7 @@
/*
* SPDX-FileCopyrightText: 2017 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2015-2016 Intel Corporation
* SPDX-FileContributor: 2018-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -27,6 +27,8 @@
#include "mesh/hci.h"
#include "mesh/common.h"
#include "prov_pvnr.h"
#include "scan.h"
#include "btc_ble_mesh_ble.h"
/** @def BT_UUID_MESH_PROV
* @brief Mesh Provisioning Service
@ -69,7 +71,6 @@ static uint8_t bt_mesh_private_key[32];
/* Scan related functions */
static bt_mesh_scan_cb_t *bt_mesh_scan_dev_found_cb;
#if CONFIG_BLE_MESH_NODE
/* the gatt database list to save the attribute table */
static sys_slist_t bt_mesh_gatts_db;
@ -79,10 +80,57 @@ static struct bt_mesh_conn bt_mesh_gatts_conn[BLE_MESH_MAX_CONN];
static struct bt_mesh_conn_cb *bt_mesh_gatts_conn_cb;
static uint8_t bt_mesh_gatts_addr[6];
#if CONFIG_BLE_MESH_USE_BLE_50
static bool g_gatts_svcs_add = false;
#endif
#endif /* CONFIG_BLE_MESH_NODE */
#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BLE_MESH_SUPPORT_BLE_ADV
static inline void bt_mesh_set_ble_adv_running();
static inline void bt_mesh_unset_ble_adv_running();
static inline bool bt_mesh_is_ble_adv_running();
#endif
static bool g_host_init = false;
#if CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_USE_BLE_50
#define BT_MESH_GATTS_CONN_UNUSED 0xFF
static void bt_mesh_gatts_conn_init(void)
{
int i;
for (i = 0; i < BLE_MESH_MAX_CONN; i++) {
bt_mesh_gatts_conn[i].handle = BT_MESH_GATTS_CONN_UNUSED;
}
}
static int bt_mesh_find_free_conn_idx(void)
{
int i;
for (i = 0; i < BLE_MESH_MAX_CONN; i++) {
if (bt_mesh_gatts_conn[i].handle == BT_MESH_GATTS_CONN_UNUSED) {
return i;
}
}
return -ENOMEM;
}
static int bt_mesh_find_conn_idx(uint16_t conn_handle)
{
int i;
for (i = 0; i < BLE_MESH_MAX_CONN; i++) {
if (bt_mesh_gatts_conn[i].handle == conn_handle) {
return i;
}
}
return -ENODEV;
}
#endif /* CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_USE_BLE_50 */
int bt_mesh_host_init(void)
{
int rc;
@ -145,7 +193,13 @@ void bt_mesh_hci_init(void)
#endif
}
#if CONFIG_BLE_MESH_USE_BLE_50
static struct ble_gap_ext_disc_params uncoded_disc_params;
static struct ble_gap_ext_disc_params coded_disc_params;
#else
static struct ble_gap_disc_params scan_param;
#endif
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_CLIENT
static struct gattc_prov_info {
@ -350,7 +404,7 @@ static int svc_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
}
uuid = &service->uuid;
uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16);
uuid_length = (uint8_t)(uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16);
if (uuid_length != 2) {
return 0;
}
@ -398,9 +452,45 @@ static int svc_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
}
#endif /* (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
static int disc_cb(struct ble_gap_event *event, void *arg)
#if CONFIG_BLE_MESH_USE_BLE_50
void bt_mesh_ble_ext_adv_report(struct ble_gap_ext_disc_desc *desc)
{
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
bt_mesh_ble_adv_report_t adv_rpt = {0};
if (bt_mesh_ble_scan_state_get()) {
memcpy(adv_rpt.addr, desc->addr.val, BLE_MESH_ADDR_LEN);
memcpy(adv_rpt.dir_addr, desc->direct_addr.val, BLE_MESH_ADDR_LEN);
/* Here, only a shallow copy needs to be implemented;
* deep copying behavior occurs in btc_ble_mesh_ble_copy_req_data. */
adv_rpt.data = desc->data;
adv_rpt.event_type = desc->props;
adv_rpt.addr_type = desc->addr.type;
adv_rpt.length = desc->length_data;
adv_rpt.rssi = desc->rssi;
adv_rpt.primary_phy = desc->prim_phy;
adv_rpt.secondary_phy = desc->sec_phy;
adv_rpt.sid = desc->sid;
adv_rpt.tx_power = desc->tx_power;
adv_rpt.dir_addr_type = desc->direct_addr.type;
adv_rpt.data_status = desc->data_status;
adv_rpt.per_adv_interval = desc->periodic_adv_itvl;
bt_mesh_ble_scan_cb_evt_to_btc(&adv_rpt);
}
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
}
#endif
int disc_cb(struct ble_gap_event *event, void *arg)
{
#if CONFIG_BLE_MESH_USE_BLE_50
struct ble_gap_ext_disc_desc *desc;
#else
struct ble_gap_disc_desc *desc;
#endif
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_CLIENT
int rc, i;
@ -412,21 +502,58 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
#endif
switch (event->type) {
case BLE_GAP_EVENT_DISC: {
struct net_buf_simple buf = {0};
#if CONFIG_BLE_MESH_USE_BLE_50
case BLE_GAP_EVENT_EXT_DISC: {
struct bt_mesh_adv_report adv_rpt = {0};
desc = &event->disc;
net_buf_simple_init_with_data(&buf, (void *)desc->data, desc->length_data);
desc = &event->ext_disc;
memcpy(&adv_rpt.addr, &desc->addr, sizeof(bt_mesh_addr_t));
adv_rpt.rssi = desc->rssi;
adv_rpt.adv_type = desc->props;
adv_rpt.primary_phy = desc->prim_phy;
adv_rpt.secondary_phy = desc->sec_phy;
net_buf_simple_init_with_data(&adv_rpt.adv_data, (void *)desc->data, desc->length_data);
if (bt_mesh_scan_dev_found_cb) {
/* TODO: Support Scan Response data length for NimBLE host */
bt_mesh_scan_dev_found_cb((bt_mesh_addr_t *)&desc->addr, desc->rssi, desc->event_type, &buf, 0);
if (desc->props & BLE_HCI_ADV_LEGACY_MASK) {
bt_mesh_scan_dev_found_cb(&adv_rpt);
}
}
/* Mesh didn't process that data */
if (adv_rpt.adv_data.len == desc->length_data) {
bt_mesh_ble_ext_adv_report(desc);
}
break;
}
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
case BLE_GAP_EVENT_DISC: {
struct bt_mesh_adv_report adv_rpt = {0};
desc = &event->disc;
adv_rpt.rssi = desc->rssi;
adv_rpt.adv_type = desc->event_type;
memcpy(&adv_rpt.addr, &desc->addr, sizeof(bt_mesh_addr_t));
net_buf_simple_init_with_data(&adv_rpt.adv_data, (void *)desc->data, desc->length_data);
if (bt_mesh_scan_dev_found_cb) {
/* TODO: Support Scan Response data length for NimBLE host */
bt_mesh_scan_dev_found_cb(&adv_rpt);
}
break;
}
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_CLIENT
case BLE_GAP_EVENT_CONNECT:
/* @todo: process connect failed event */
if (event->connect.status == 0) {
/* Connection successfully established. */
MODLOG_DFLT(INFO, "Connection established ");
@ -442,10 +569,21 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
break;
}
}
if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
goto transfer_to_user;
}
} else {
goto transfer_to_user;
}
}
if (!bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) {
#if CONFIG_BLE_MESH_USE_BLE_50
rc = ble_gap_ext_disc(BLE_OWN_ADDR_PUBLIC, 0, 0, 0, 0, 0,
uncoded_disc_params.itvl ? &uncoded_disc_params : NULL,
coded_disc_params.itvl ? &coded_disc_params : NULL, disc_cb, NULL);
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
rc = ble_gap_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER, &scan_param, disc_cb, NULL);
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
if (rc != 0) {
BT_ERR("Invalid scan status %d", rc);
break;
@ -494,7 +632,13 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
bt_mesh_gattc_info[i].wr_desc_done = false;
break;
}
if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
goto transfer_to_user;
}
}
} else {
goto transfer_to_user;
}
break;
case BLE_GAP_EVENT_MTU:
@ -521,6 +665,8 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
}
/* Search Mesh Provisioning Service or Mesh Proxy Service */
ble_gattc_disc_all_svcs(bt_mesh_gattc_info[i].conn.handle, svc_disced, NULL);
} else {
goto transfer_to_user;
}
break;
case BLE_GAP_EVENT_NOTIFY_RX:
@ -531,8 +677,8 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
}
if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
BT_ERR("Conn handle 0x%04x not found", event->notify_rx.conn_handle);
return 0;
BT_DBG("Conn handle 0x%04x not blonges to Mesh", event->notify_rx.conn_handle);
goto transfer_to_user;
}
conn = &bt_mesh_gattc_info[i].conn;
@ -557,7 +703,7 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROV_VAL) {
if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->prov_notify != NULL) {
len = bt_mesh_gattc_conn_cb->prov_notify(&bt_mesh_gattc_info[i].conn,
notif_data, notif_len);
notif_data, notif_len);
if (len < 0) {
BT_ERR("prov_notify failed");
bt_mesh_gattc_disconnect(conn);
@ -568,7 +714,7 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->proxy_notify != NULL &&
bt_mesh_gattc_info[i].wr_desc_done) {
len = bt_mesh_gattc_conn_cb->proxy_notify(&bt_mesh_gattc_info[i].conn,
notif_data, notif_len);
notif_data, notif_len);
if (len < 0) {
BT_ERR("proxy_notify failed");
bt_mesh_gattc_disconnect(conn);
@ -579,14 +725,53 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
break;
#endif
default:
goto transfer_to_user;
break;
}
return 0;
transfer_to_user:
#if CONFIG_BLE_MESH_USE_BLE_50
bt_mesh_ble_nimble_evt_to_btc(event, arg);
#endif
return 0;
}
#if CONFIG_BLE_MESH_USE_BLE_50
/**
* @brief Get the gap callback function used by BLE Mesh
*
* @note The user must get the mesh gap event handler function
* through the bt_mesh_nimble_gap_cb_get function and pass
* it in as a callback function when using the api:
* ble_gap_ext_connect, ble_gap_ext_disc, ble_gap_connect,
* and ble_gap_disc.
*
* @return void*
*/
void *bt_mesh_nimble_gap_cb_get(void)
{
return (void*)disc_cb;
}
#endif
static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window, uint8_t filter_dup)
{
#if CONFIG_BLE_MESH_USE_BLE_50
uncoded_disc_params.itvl = (window ? interval : 0);
uncoded_disc_params.window = window;
coded_disc_params.itvl = ((interval > window) ? interval : 0);
coded_disc_params.window = ((interval > window) ? interval - window : 0);
coded_disc_params.passive = (scan_type == BLE_MESH_SCAN_PASSIVE);
uncoded_disc_params.passive = (scan_type == BLE_MESH_SCAN_PASSIVE);
ble_gap_ext_disc(BLE_OWN_ADDR_PUBLIC, 0, 0, filter_dup, 0, 0,
uncoded_disc_params.itvl ? &uncoded_disc_params : NULL,
coded_disc_params.itvl ? &coded_disc_params : NULL, disc_cb, NULL);
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
scan_param.filter_duplicates = filter_dup;
scan_param.itvl = interval;
scan_param.window = window;
@ -597,6 +782,7 @@ static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window,
scan_param.passive = 0;
}
ble_gap_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER, &scan_param, disc_cb, NULL);
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
#if BLE_MESH_DEV
if (scan_type == BLE_MESH_SCAN_ACTIVE) {
@ -649,11 +835,23 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
bt_mesh_atomic_test_and_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
#endif
if (bt_mesh_gatts_conn_cb != NULL && bt_mesh_gatts_conn_cb->connected != NULL) {
uint8_t index = BLE_MESH_GATT_GET_CONN_ID(event->connect.conn_handle);
int index = 0;
#if CONFIG_BLE_MESH_USE_BLE_50
index = bt_mesh_find_free_conn_idx();
if (index != -ENOMEM) {
bt_mesh_gatts_conn[index].handle = BLE_MESH_GATT_GET_CONN_ID(event->connect.conn_handle);
(bt_mesh_gatts_conn_cb->connected)(&bt_mesh_gatts_conn[index], 0);
} else {
BT_ERR("No space for new connection");
ble_gap_terminate(event->connect.conn_handle, BLE_ERR_CONN_LIMIT);
}
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
index = BLE_MESH_GATT_GET_CONN_ID(event->connect.conn_handle);
if (index < BLE_MESH_MAX_CONN) {
bt_mesh_gatts_conn[index].handle = BLE_MESH_GATT_GET_CONN_ID(event->connect.conn_handle);
(bt_mesh_gatts_conn_cb->connected)(&bt_mesh_gatts_conn[index], 0);
}
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
memcpy(bt_mesh_gatts_addr, desc.peer_id_addr.val, BLE_MESH_ADDR_LEN);
/* This is for EspBleMesh Android app. When it tries to connect with the
* device at the first time and it fails due to some reason. And after
@ -673,11 +871,23 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
bt_mesh_atomic_test_and_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
#endif
if (bt_mesh_gatts_conn_cb != NULL && bt_mesh_gatts_conn_cb->disconnected != NULL) {
uint8_t index = BLE_MESH_GATT_GET_CONN_ID(event->disconnect.conn.conn_handle);
int index = 0;
#if CONFIG_BLE_MESH_USE_BLE_50
index = bt_mesh_find_conn_idx(BLE_MESH_GATT_GET_CONN_ID(event->disconnect.conn.conn_handle));
if (index != -ENODEV) {
bt_mesh_gatts_conn[index].handle = BLE_MESH_GATT_GET_CONN_ID(event->disconnect.conn.conn_handle);
(bt_mesh_gatts_conn_cb->disconnected)(&bt_mesh_gatts_conn[index], event->disconnect.reason);
} else {
BT_ERR("No device");
}
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
index = BLE_MESH_GATT_GET_CONN_ID(event->disconnect.conn.conn_handle);
if (index < BLE_MESH_MAX_CONN) {
bt_mesh_gatts_conn[index].handle = BLE_MESH_GATT_GET_CONN_ID(event->disconnect.conn.conn_handle);
(bt_mesh_gatts_conn_cb->disconnected)(&bt_mesh_gatts_conn[index], event->disconnect.reason);
}
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
bt_mesh_gatts_conn[index].handle = 0;
memset(bt_mesh_gatts_addr, 0x0, BLE_MESH_ADDR_LEN);
}
@ -693,8 +903,38 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
return 0;
case BLE_GAP_EVENT_ADV_COMPLETE:
MODLOG_DFLT(INFO, "advertise complete; reason=%d",
event->adv_complete.reason);
BT_DBG("advertise complete; reason=%d",
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 (event->adv_complete.reason == BLE_HS_ETIMEOUT) {
ble_mesh_adv_task_wakeup(event->adv_complete.instance);
}
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
/**
* This judgment is to distinguish between the termination
* events of BLE connectable broadcasting and proxy connectable
* adv under the same instance ID, that is, when the status is 0.
*
* Since the host task and adv task are currently operated in
* series, there is no need to consider competition issues between
* tasks.
*
* @attention: once multiple adv instances are used, the adv task
* and host will be asynchronous, and it is necessary to consider
* the issue of resource competition.
*/
if (bt_mesh_is_ble_adv_running() &&
event->adv_complete.reason == 0) {
/* The unset operation must be performed before waking up the
* adv task; performing the unset after waking up the adv task
* could lead to resource contention issues.
*/
bt_mesh_unset_ble_adv_running();
ble_mesh_adv_task_wakeup(event->adv_complete.instance);
}
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
return 0;
case BLE_GAP_EVENT_ENC_CHANGE:
@ -717,10 +957,20 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
event->subscribe.prev_indicate,
event->subscribe.cur_indicate);
struct bt_mesh_gatt_attr *attr = bt_mesh_gatts_find_attr_by_handle(event->subscribe.attr_handle + 1);
uint8_t index = BLE_MESH_GATT_GET_CONN_ID(event->subscribe.conn_handle);
int index = 0;
uint16_t len = 0;
uint16_t ccc_val = 0;
#if CONFIG_BLE_MESH_USE_BLE_50
index = bt_mesh_find_conn_idx(BLE_MESH_GATT_GET_CONN_ID(event->subscribe.conn_handle));
if (index == -ENODEV) {
BT_ERR("Couldn't find conn %d", event->subscribe.conn_handle);
return 0;
}
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
index = BLE_MESH_GATT_GET_CONN_ID(event->subscribe.conn_handle);
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
if (event->subscribe.prev_notify != event->subscribe.cur_notify) {
ccc_val = event->subscribe.cur_notify;
} else if (event->subscribe.prev_indicate != event->subscribe.cur_indicate) {
@ -773,10 +1023,231 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
#else
static int gap_event_cb(struct ble_gap_event *event, void *arg)
{
#if CONFIG_BLE_MESH_USE_BLE_50
switch (event->type) {
case BLE_GAP_EVENT_ADV_COMPLETE:
BT_DBG("Provisioner advertise complete; reason=%d",
event->adv_complete.reason);
/* Limit Reached (0x43) and Advertising Timeout (0x3C) will cause BLE_HS_ETIMEOUT to be set. */
if (event->adv_complete.reason == BLE_HS_ETIMEOUT) {
ble_mesh_adv_task_wakeup(event->adv_complete.instance);
}
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
/**
* This judgment is to distinguish between the termination
* events of BLE connectable broadcasting and proxy connectable
* adv under the same instance ID, that is, when the status is 0.
*
* Since the host task and adv task are currently operated in
* series, there is no need to consider competition issues between
* tasks.
*
* @attention: once multiple adv instances are used, the adv task
* and host will be asynchronous, and it is necessary to consider
* the issue of resource competition.
*/
if (bt_mesh_is_ble_adv_running() &&
event->adv_complete.reason == 0) {
/* The unset operation must be performed before waking up the
* adv task; performing the unset after waking up the adv task
* could lead to resource contention issues.
*/
bt_mesh_unset_ble_adv_running();
ble_mesh_adv_task_wakeup(event->adv_complete.instance);
}
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
break;
}
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
return 0;
}
#endif /* CONFIG_BLE_MESH_NODE */
#if CONFIG_BLE_MESH_USE_BLE_50
int bt_le_ext_adv_start(const uint8_t inst_id,
const struct bt_mesh_adv_param *param,
const struct bt_mesh_adv_data *ad, size_t ad_len,
const struct bt_mesh_adv_data *sd, size_t sd_len)
{
struct ble_gap_ext_adv_params adv_params = {0};
struct os_mbuf *data = NULL;
struct os_mbuf *scan_rsp = NULL;
uint8_t *buf = NULL;
uint16_t interval = 0;
uint8_t buf_len = 0;
int err = 0;
err = ble_gap_ext_adv_active(inst_id);
if (err) {
BT_ERR("adv inst(%d) is running %d", inst_id, err);
return -EINVAL;
}
#if BLE_MESH_DEV
if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING)) {
return -EALREADY;
}
#endif
buf = bt_mesh_calloc(ad_len * BLE_HS_ADV_MAX_SZ);
if (!buf) {
BT_ERR("ad buffer alloc failed");
return -ENOMEM;
}
err = set_ad(ad, ad_len, buf, &buf_len);
if (err) {
bt_mesh_free(buf);
BT_ERR("set_ad failed: err %d", err);
return err;
}
data = os_msys_get_pkthdr(buf_len, 0);
if (!data) {
bt_mesh_free(buf);
BT_ERR("os buf get failed");
return -ENOBUFS;
}
err = os_mbuf_append(data, buf, buf_len);
if (err) {
bt_mesh_free(buf);
BT_ERR("Append ad data to os buf failed %d", err);
return -EINVAL;
}
bt_mesh_free(buf);
if (sd && (param->options & BLE_MESH_ADV_OPT_CONNECTABLE)) {
buf_len = 0;
buf = bt_mesh_calloc(sd_len * BLE_HS_ADV_MAX_SZ);
if (!buf) {
BT_ERR("ad buffer alloc failed");
return -ENOMEM;
}
err = set_ad(sd, sd_len, buf, &buf_len);
if (err) {
bt_mesh_free(buf);
BT_ERR("set_ad failed: err %d", err);
return err;
}
scan_rsp = os_msys_get_pkthdr(buf_len, 0);
if (!data) {
bt_mesh_free(buf);
BT_ERR("os buf get failed");
return -ENOBUFS;
}
err = os_mbuf_append(scan_rsp, buf, buf_len);
if (err) {
bt_mesh_free(buf);
BT_ERR("Append ad data to os buf failed %d", err);
return -EINVAL;
}
bt_mesh_free(buf);
}
memset(&adv_params, 0, sizeof adv_params);
assert(param);
if (param->options & BLE_MESH_ADV_OPT_CONNECTABLE) {
adv_params.connectable = true;
adv_params.scannable = true;
adv_params.legacy_pdu = true;
} else if (sd != NULL) {
adv_params.connectable = false;
adv_params.scannable = true;
adv_params.legacy_pdu = true;
} else {
if (param->primary_phy == BLE_MESH_ADV_PHY_1M &&
param->secondary_phy == BLE_MESH_ADV_PHY_1M) {
adv_params.legacy_pdu = true;
}
}
adv_params.sid = inst_id;
adv_params.primary_phy = param->primary_phy;
adv_params.secondary_phy = param->secondary_phy;
adv_params.tx_power = 0x7F; // tx power will be selected by controller
adv_params.own_addr_type = BLE_OWN_ADDR_PUBLIC;
interval = param->interval_min;
#if CONFIG_BLE_MESH_RANDOM_ADV_INTERVAL
/* If non-connectable mesh packets are transmitted with an adv interval
* not smaller than 10ms, then we will use a random adv interval between
* [interval / 2, interval] for them.
*/
if (adv_params.conn_mode == BLE_GAP_CONN_MODE_NON &&
adv_params.disc_mode == BLE_GAP_DISC_MODE_NON && interval >= 16) {
interval >>= 1;
interval += (bt_mesh_get_rand() % (interval + 1));
adv_params->high_duty_directed = true;
BT_INFO("%u->%u", param->interval_min, interval);
}
#endif
adv_params.itvl_min = interval;
adv_params.itvl_max = interval;
err = ble_gap_ext_adv_configure(inst_id, &adv_params, NULL, gap_event_cb, NULL);
if (err != 0) {
BT_ERR("Advertising config failed: err %d", err);
return err;
}
err = ble_gap_ext_adv_set_data(inst_id, data);
if (err != 0) {
BT_ERR("Advertising set failed: err %d", err);
return err;
}
if (scan_rsp) {
err = ble_gap_ext_adv_rsp_set_data(inst_id, scan_rsp);
if (err != 0) {
BT_ERR("scan rsp set failed: err %d", err);
return err;
} else {
BT_INFO("scan rsp set succeed\n");
}
}
again:
if (param->adv_duration < 10 &&
param->adv_duration != 0) {
BT_WARN("adv duration shall not be less than 10ms");
}
err = ble_gap_ext_adv_start(inst_id, param->adv_duration ?
2 + param->adv_duration / 10 : 0, param->adv_count);
if (err) {
if (err == BLE_HS_EALREADY) {
ble_gap_ext_adv_stop(inst_id);
goto again;
}
BT_ERR("Advertising start failed: err %d", err);
return err;
}
#if BLE_MESH_DEV
bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
if (!(param->options & BLE_MESH_ADV_OPT_ONE_TIME)) {
bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_KEEP_ADVERTISING);
}
#endif
return 0;
}
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
/* APIs functions */
int bt_le_adv_start(const struct bt_mesh_adv_param *param,
const struct bt_mesh_adv_data *ad, size_t ad_len,
@ -877,8 +1348,146 @@ again:
return 0;
}
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
#if CONFIG_BLE_MESH_USE_BLE_50
static bool _ble_adv_running_flag;
static inline void bt_mesh_set_ble_adv_running()
{
_ble_adv_running_flag = true;
}
static inline void bt_mesh_unset_ble_adv_running()
{
_ble_adv_running_flag = false;
}
static inline bool bt_mesh_is_ble_adv_running()
{
return _ble_adv_running_flag == true;
}
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_data *adv_data)
{
struct ble_gap_ext_adv_params adv_params = {0};
struct os_mbuf *data = NULL;
int err = 0;
assert(param);
switch (param->adv_type) {
case BLE_MESH_ADV_IND:
adv_params.connectable = true;
adv_params.scannable = true;
adv_params.legacy_pdu = true;
break;
case BLE_MESH_ADV_DIRECT_IND:
adv_params.connectable = true;
adv_params.scannable = false;
adv_params.directed = true;
adv_params.high_duty_directed = false;
adv_params.legacy_pdu = true;
break;
case BLE_MESH_ADV_SCAN_IND:
adv_params.connectable = false;
adv_params.scannable = true;
adv_params.directed = false;
adv_params.high_duty_directed = false;
adv_params.legacy_pdu = true;
break;
case BLE_MESH_ADV_NONCONN_IND:
adv_params.connectable = false;
adv_params.scannable = false;
adv_params.directed = false;
adv_params.high_duty_directed = false;
adv_params.legacy_pdu = true;
break;
case BLE_MESH_ADV_DIRECT_IND_LOW_DUTY:
adv_params.connectable = true;
adv_params.scannable = false;
adv_params.directed = true;
adv_params.high_duty_directed = true;
adv_params.legacy_pdu = true;
break;
}
adv_params.itvl_min = param->interval;
adv_params.itvl_max = param->interval;
adv_params.channel_map = BLE_MESH_ADV_CHNL_37 | BLE_MESH_ADV_CHNL_38 | BLE_MESH_ADV_CHNL_39;
adv_params.filter_policy = BLE_MESH_AP_SCAN_CONN_ALL;
adv_params.primary_phy = BLE_MESH_ADV_PHY_1M;
adv_params.secondary_phy = BLE_MESH_ADV_PHY_1M;
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) {
adv_params.peer.type = param->peer_addr_type;
memcpy(adv_params.peer.val, param->peer_addr, BLE_MESH_ADDR_LEN);
}
if (ble_gap_ext_adv_configure(inst_id, &adv_params, NULL,
gap_event_cb, NULL)) {
BT_ERR("ble adv configure failed\n");
return -EINVAL;
}
if (adv_data && param->adv_type != BLE_MESH_ADV_DIRECT_IND &&
param->adv_type != BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) {
if (adv_data->adv_data_len) {
data = os_msys_get_pkthdr(adv_data->adv_data_len, 0);
if (!data) {
BT_ERR("Failed to alloc buffer for ble");
return -ENOMEM;
}
if (os_mbuf_append(data, adv_data->adv_data, adv_data->adv_data_len)) {
BT_ERR("Append data failed");
return -EINVAL;
}
err = ble_gap_ext_adv_set_data(inst_id, data);
if (err) {
BT_ERR("Failed to set advertising data, err %d", err);
return err;
}
}
if (adv_data->scan_rsp_data_len && param->adv_type != BLE_MESH_ADV_NONCONN_IND) {
data = os_msys_get_pkthdr(adv_data->scan_rsp_data_len, 0);
if (!data) {
BT_ERR("Failed to alloc buffer for ble");
return -ENOMEM;
}
if (os_mbuf_append(data, adv_data->scan_rsp_data, adv_data->scan_rsp_data_len)) {
BT_ERR("Append data failed");
return -EINVAL;
}
err = ble_gap_ext_adv_rsp_set_data(inst_id, data);
if (err) {
BT_ERR("Failed to set scan rsp data, err %d", err);
return err;
}
}
}
err = ble_gap_ext_adv_start(inst_id, 2 + param->duration / 10, param->count);
if (err) {
BT_ERR("Failed to start advertising, err %d", err);
return err;
}
bt_mesh_set_ble_adv_running();
return 0;
}
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
int bt_mesh_ble_adv_start(const struct bt_mesh_ble_adv_param *param,
const struct bt_mesh_ble_adv_data *data)
{
@ -949,8 +1558,27 @@ int bt_mesh_ble_adv_start(const struct bt_mesh_ble_adv_param *param,
return 0;
}
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
#if CONFIG_BLE_MESH_USE_BLE_50
int bt_le_ext_adv_stop(uint8_t inst_id)
{
#if BLE_MESH_DEV
bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_KEEP_ADVERTISING);
if (!bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING)) {
return 0;
}
#endif
ble_gap_ext_adv_stop(inst_id);
#if BLE_MESH_DEV
bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
#endif
return 0;
}
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
int bt_le_adv_stop(void)
{
#if BLE_MESH_DEV
@ -967,6 +1595,7 @@ int bt_le_adv_stop(void)
return 0;
}
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
int bt_le_scan_start(const struct bt_mesh_scan_param *param, bt_mesh_scan_cb_t cb)
{
@ -987,6 +1616,7 @@ int bt_le_scan_start(const struct bt_mesh_scan_param *param, bt_mesh_scan_cb_t c
err = start_le_scan(param->type, param->interval, param->window, param->filter_dup);
if (err) {
BT_ERR("Failed to start advertising, err %d", err);
return err;
}
@ -1554,6 +2184,7 @@ int bt_mesh_gattc_write_no_rsp(struct bt_mesh_conn *conn,
om = ble_hs_mbuf_from_flat(data, len);
if (om == NULL) {
BT_ERR("om buffer alloc failed");
return -1;
}
@ -1622,9 +2253,19 @@ static int proxy_char_access_cb(uint16_t conn_handle, uint16_t attr_handle,
{
if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR || ctxt->op == BLE_GATT_ACCESS_OP_WRITE_DSC) {
struct bt_mesh_gatt_attr *attr = bt_mesh_gatts_find_attr_by_handle(attr_handle);
uint8_t index = BLE_MESH_GATT_GET_CONN_ID(conn_handle);
int index = 0;
uint16_t len = 0;
#if CONFIG_BLE_MESH_USE_BLE_50
index = bt_mesh_find_conn_idx(BLE_MESH_GATT_GET_CONN_ID(conn_handle));
if (index == -ENODEV) {
BT_ERR("Unknown conn handle");
return 0;
}
#else
index = BLE_MESH_GATT_GET_CONN_ID(conn_handle);
#endif
BT_DBG("write, handle %d, len %d, data %s", attr_handle,
ctxt->om->om_len,
bt_hex(ctxt->om->om_data, ctxt->om->om_len));
@ -1713,6 +2354,58 @@ void gatt_register_cb(struct ble_gatt_register_ctxt *ctxt,
}
}
#if CONFIG_BLE_MESH_USE_BLE_50
void bt_mesh_gatts_svcs_add(void)
{
ble_hs_cfg.gatts_register_cb = gatt_register_cb;
#if CONFIG_BLE_MESH_NODE
int rc = 0;
ble_svc_gap_init();
ble_svc_gatt_init();
rc = ble_gatts_count_cfg(svc_defs);
assert(rc == 0);
rc = ble_gatts_add_svcs(svc_defs);
assert(rc == 0);
g_gatts_svcs_add = true;
#endif
}
void bt_mesh_gatt_init(void)
{
ble_att_set_preferred_mtu(BLE_MESH_GATT_DEF_MTU_SIZE);
#if CONFIG_BLE_MESH_NODE
static bool init = false;
if (init == false) {
__ASSERT(g_gatts_svcs_add, "func bt_mesh_gatts_svcs_add should be called before mesh init");
ble_gatts_svc_set_visibility(prov_svc_start_handle, 1);
ble_gatts_svc_set_visibility(proxy_svc_start_handle, 0);
#if CONFIG_BLE_MESH_USE_BLE_50
bt_mesh_gatts_conn_init();
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
init = true;
}
#endif /* CONFIG_BLE_MESH_NODE */
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_CLIENT
for (int i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
bt_mesh_gattc_info[i].conn.handle = 0xFFFF;
bt_mesh_gattc_info[i].mtu = BLE_ATT_MTU_DFLT;
bt_mesh_gattc_info[i].wr_desc_done = false;
}
#endif
}
#else
void bt_mesh_gatt_init(void)
{
ble_att_set_preferred_mtu(BLE_ATT_MTU_DFLT);
@ -1751,6 +2444,7 @@ void bt_mesh_gatt_init(void)
}
#endif
}
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
#if CONFIG_BLE_MESH_DEINIT
void bt_mesh_gatt_deinit(void)
@ -1981,12 +2675,12 @@ int bt_mesh_update_exceptional_list(uint8_t sub_code, uint32_t type, void *info)
if ((sub_code > BLE_MESH_EXCEP_LIST_SUB_CODE_CLEAN) ||
(sub_code < BLE_MESH_EXCEP_LIST_SUB_CODE_CLEAN &&
type > BLE_MESH_EXCEP_LIST_TYPE_MESH_PROXY_ADV) ||
type > BLE_MESH_EXCEP_LIST_TYPE_MAX) ||
(sub_code == BLE_MESH_EXCEP_LIST_SUB_CODE_CLEAN &&
!(type & BLE_MESH_EXCEP_LIST_CLEAN_ALL_LIST))) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
}
if (type == BLE_MESH_EXCEP_LIST_TYPE_MESH_LINK_ID) {
if (!info) {

View File

@ -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
*/

View File

@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -35,6 +35,10 @@ _Static_assert(!(IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) && IS_ENABLED(CON
"Not support Proxy Server and Proxy Client simultaneously");
#endif
#if CONFIG_BLE_MESH_USE_BLE_50
static uint8_t proxy_adv_inst = BLE_MESH_ADV_INS_UNUSED;
#endif
#define ADV_OPT (BLE_MESH_ADV_OPT_CONNECTABLE | BLE_MESH_ADV_OPT_ONE_TIME)
#if CONFIG_BLE_MESH_GATT_PROXY_SERVER && \
@ -52,12 +56,24 @@ static const struct bt_mesh_adv_param slow_adv_param = {
.options = ADV_OPT,
.interval_min = BLE_MESH_GAP_ADV_SLOW_INT_MIN,
.interval_max = BLE_MESH_GAP_ADV_SLOW_INT_MAX,
#if CONFIG_BLE_MESH_USE_BLE_50
.primary_phy = BLE_MESH_ADV_PHY_1M,
.secondary_phy = BLE_MESH_ADV_PHY_1M,
.adv_duration = 0,
.adv_count = 0,
#endif
};
static const struct bt_mesh_adv_param fast_adv_param = {
.options = ADV_OPT,
.interval_min = BLE_MESH_GAP_ADV_FAST_INT_MIN_0,
.interval_max = BLE_MESH_GAP_ADV_FAST_INT_MAX_0,
#if CONFIG_BLE_MESH_USE_BLE_50
.primary_phy = BLE_MESH_ADV_PHY_1M,
.secondary_phy = BLE_MESH_ADV_PHY_1M,
.adv_duration = 0,
.adv_count = 0,
#endif
};
static bool proxy_adv_enabled;
@ -1465,8 +1481,13 @@ static int node_id_adv(struct bt_mesh_subnet *sub)
memcpy(proxy_svc_data + 3, tmp + 8, 8);
proxy_sd_len = gatt_proxy_adv_create(&proxy_sd);
err = bt_le_adv_start(&fast_adv_param, node_id_ad,
ARRAY_SIZE(node_id_ad), &proxy_sd, proxy_sd_len);
#if CONFIG_BLE_MESH_USE_BLE_50
err = bt_le_ext_adv_start(proxy_adv_inst, &fast_adv_param, node_id_ad,
ARRAY_SIZE(node_id_ad), &proxy_sd, proxy_sd_len);
#else
err = bt_le_adv_start(&fast_adv_param, node_id_ad,
ARRAY_SIZE(node_id_ad), &proxy_sd, proxy_sd_len);
#endif
if (err) {
BT_WARN("Failed to advertise using Node ID (err %d)", err);
return err;
@ -1491,8 +1512,13 @@ static int net_id_adv(struct bt_mesh_subnet *sub)
memcpy(proxy_svc_data + 3, sub->keys[sub->kr_flag].net_id, 8);
proxy_sd_len = gatt_proxy_adv_create(&proxy_sd);
err = bt_le_adv_start(&slow_adv_param, net_id_ad,
ARRAY_SIZE(net_id_ad), &proxy_sd, proxy_sd_len);
#if CONFIG_BLE_MESH_USE_BLE_50
err = bt_le_ext_adv_start(proxy_adv_inst, &slow_adv_param, net_id_ad,
ARRAY_SIZE(net_id_ad), &proxy_sd, proxy_sd_len);
#else
err = bt_le_adv_start(&slow_adv_param, net_id_ad,
ARRAY_SIZE(net_id_ad), &proxy_sd, proxy_sd_len);
#endif
if (err) {
BT_WARN("Failed to advertise using Network ID (err %d)", err);
return err;
@ -1836,13 +1862,20 @@ int32_t bt_mesh_proxy_server_adv_start(void)
return K_FOREVER;
}
#if CONFIG_BLE_MESH_USE_BLE_50
if (proxy_adv_inst == BLE_MESH_ADV_INS_UNUSED) {
BT_ERR("Proxy adv inst is not initialized!");
return K_FOREVER;
}
#endif
#if CONFIG_BLE_MESH_PB_GATT
if (prov_fast_adv) {
prov_start_time = k_uptime_get_32();
}
if (!bt_mesh_is_provisioned()) {
const struct bt_mesh_adv_param *param;
const struct bt_mesh_adv_param *param = NULL;
struct bt_mesh_adv_data prov_sd[2];
size_t prov_sd_len;
@ -1854,8 +1887,14 @@ int32_t bt_mesh_proxy_server_adv_start(void)
prov_sd_len = gatt_prov_adv_create(prov_sd);
#if CONFIG_BLE_MESH_USE_BLE_50
if (bt_le_ext_adv_start(proxy_adv_inst, param, prov_ad, ARRAY_SIZE(prov_ad),
prov_sd, prov_sd_len) == 0) {
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
if (bt_le_adv_start(param, prov_ad, ARRAY_SIZE(prov_ad),
prov_sd, prov_sd_len) == 0) {
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
proxy_adv_enabled = true;
/* Advertise 60 seconds using fast interval */
@ -1899,7 +1938,16 @@ void bt_mesh_proxy_server_adv_stop(void)
return;
}
#if CONFIG_BLE_MESH_USE_BLE_50
if (proxy_adv_inst == BLE_MESH_ADV_INS_UNUSED) {
BT_ERR("Proxy adv inst is not initialized!");
return;
}
err = bt_le_ext_adv_stop(proxy_adv_inst);
#else
err = bt_le_adv_stop();
#endif
if (err) {
BT_ERR("Failed to stop advertising (err %d)", err);
} else {
@ -1916,6 +1964,10 @@ int bt_mesh_proxy_server_init(void)
{
int i;
#if CONFIG_BLE_MESH_USE_BLE_50
proxy_adv_inst = bt_mesh_get_proxy_inst();
#endif
#if CONFIG_BLE_MESH_GATT_PROXY_SERVER
bt_mesh_gatts_service_register(&proxy_svc);
#endif
@ -1954,6 +2006,10 @@ int bt_mesh_proxy_server_deinit(void)
{
int i;
#if CONFIG_BLE_MESH_USE_BLE_50
proxy_adv_inst = BLE_MESH_ADV_INS_UNUSED;
#endif
proxy_adv_enabled = false;
gatt_svc = MESH_GATT_NONE;

View File

@ -12,6 +12,7 @@
#include "net.h"
#include "mesh/adapter.h"
#include "adv.h"
#ifdef __cplusplus
extern "C" {

View File

@ -41,6 +41,22 @@
#define PROXY_SVC_DATA_LEN_PRIVATE_NET_ID 0x11
#define PROXY_SVC_DATA_LEN_PRIVATE_NODE_ID 0x11
static struct bt_mesh_scan_param scan_param = {
#if CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN
.type = BLE_MESH_SCAN_ACTIVE,
#else
.type = BLE_MESH_SCAN_PASSIVE,
#endif
#if CONFIG_BLE_MESH_USE_DUPLICATE_SCAN
.filter_dup = BLE_MESH_SCAN_FILTER_DUP_ENABLE,
#else
.filter_dup = BLE_MESH_SCAN_FILTER_DUP_DISABLE,
#endif
.interval = SCAN_INTERVAL,
.window = SCAN_WINDOW,
.scan_fil_policy = BLE_MESH_SP_ADV_ALL,
};
#if (CONFIG_BLE_MESH_PROVISIONER || CONFIG_BLE_MESH_RPR_SRV)
static const bt_mesh_addr_t *unprov_dev_addr;
static uint8_t current_adv_type;
@ -336,13 +352,27 @@ int bt_mesh_stop_ble_scan(void)
return 0;
}
bool bt_mesh_ble_scan_state_get(void)
{
return ble_scan_en;
}
static void inline callback_ble_adv_pkt(const bt_mesh_addr_t *addr,
uint8_t adv_type, uint8_t data[],
uint16_t length, int8_t rssi)
{
#if !CONFIG_BLE_MESH_USE_BLE_50
bt_mesh_ble_adv_report_t adv_rpt = {0};
if (ble_scan_en) {
bt_mesh_ble_scan_cb_evt_to_btc(addr, adv_type, data, length, rssi);
memcpy(adv_rpt.addr, addr->val, BD_ADDR_LEN);
adv_rpt.addr_type = addr->type;
adv_rpt.adv_type = adv_type;
adv_rpt.length = length;
adv_rpt.data = data;
adv_rpt.rssi = rssi;
bt_mesh_ble_scan_cb_evt_to_btc(&adv_rpt);
}
#endif
}
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
@ -364,11 +394,11 @@ static bool rpr_ext_scan_handle_adv_pkt(const bt_mesh_addr_t *addr,
}
#endif /* CONFIG_BLE_MESH_RPR_SRV */
static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
int8_t rssi, uint8_t adv_type,
struct net_buf_simple *buf,
uint8_t scan_rsp_len)
static void bt_mesh_scan_cb(struct bt_mesh_adv_report *adv_rpt)
{
struct net_buf_simple_state buf_state = {0};
struct net_buf_simple *buf = &adv_rpt->adv_data;
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \
CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX
@ -379,20 +409,44 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
uint16_t adv_len = buf->len;
#endif
if (adv_type != BLE_MESH_ADV_NONCONN_IND && adv_type != BLE_MESH_ADV_IND) {
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
callback_ble_adv_pkt(addr, adv_type, adv_data, adv_len, rssi);
net_buf_simple_save(buf, &buf_state);
if (adv_rpt->adv_type != BLE_MESH_ADV_NONCONN_IND &&
adv_rpt->adv_type != BLE_MESH_ADV_IND
#if CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN
&& adv_rpt->adv_type != BLE_MESH_ADV_SCAN_RSP
#endif
) {
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
net_buf_simple_restore(buf, &buf_state);
return;
}
BT_DBG("scan, len %u: %s", buf->len, bt_hex(buf->data, buf->len));
#if (CONFIG_BLE_MESH_PROVISIONER || CONFIG_BLE_MESH_RPR_SRV)
unprov_dev_addr = addr;
current_adv_type = adv_type;
unprov_dev_addr = &adv_rpt->addr;
current_adv_type = adv_rpt->adv_type;
#endif
#if CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN
if (adv_rpt->adv_type == BLE_MESH_ADV_SCAN_RSP) {
/**
* scan response is only visible for remote provisioning extend scan.
*/
if (rpr_ext_scan_handle_adv_pkt(&adv_rpt->addr, adv_data, adv_len)) {
return;
} else {
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
net_buf_simple_restore(buf, &buf_state);
}
}
#endif /* CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN */
while (buf->len > 1) {
struct net_buf_simple_state state;
uint8_t len, type;
@ -401,16 +455,18 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
/* Check for early termination */
if (len == 0U) {
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
callback_ble_adv_pkt(addr, adv_type, adv_data, adv_len, rssi);
callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
net_buf_simple_restore(buf, &buf_state);
return;
}
if (len > buf->len) {
BT_DBG("AD malformed");
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
callback_ble_adv_pkt(addr, adv_type, adv_data, adv_len, rssi);
callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
net_buf_simple_restore(buf, &buf_state);
return;
}
@ -421,14 +477,17 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
buf->len = len - 1;
if ((type == BLE_MESH_DATA_MESH_PROV || type == BLE_MESH_DATA_MESH_MESSAGE ||
type == BLE_MESH_DATA_MESH_BEACON) && (adv_type != BLE_MESH_ADV_NONCONN_IND)) {
BT_DBG("Ignore mesh packet (type 0x%02x) with adv_type 0x%02x", type, adv_type);
type == BLE_MESH_DATA_MESH_BEACON) && (adv_rpt->adv_type != BLE_MESH_ADV_NONCONN_IND)) {
BT_DBG("Ignore mesh packet (type 0x%02x) with adv_type 0x%02x", type, adv_rpt->adv_type);
return;
}
switch (type) {
case BLE_MESH_DATA_MESH_MESSAGE:
bt_mesh_net_recv(buf, rssi, BLE_MESH_NET_IF_ADV);
struct bt_mesh_net_rx rx = {
.ctx.recv_rssi = adv_rpt->rssi,
};
bt_mesh_generic_net_recv(buf, &rx, BLE_MESH_NET_IF_ADV);
break;
#if CONFIG_BLE_MESH_PB_ADV
case BLE_MESH_DATA_MESH_PROV:
@ -441,7 +500,7 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
break;
#endif /* CONFIG_BLE_MESH_PB_ADV */
case BLE_MESH_DATA_MESH_BEACON:
bt_mesh_beacon_recv(buf, rssi);
bt_mesh_beacon_recv(buf, adv_rpt->rssi);
break;
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \
@ -450,8 +509,9 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
if (!adv_flags_valid(buf)) {
BT_DBG("Adv Flags mismatch, ignore this adv pkt");
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
callback_ble_adv_pkt(addr, adv_type, adv_data, adv_len, rssi);
callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
net_buf_simple_restore(buf, &buf_state);
return;
}
break;
@ -459,7 +519,7 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
if (!adv_service_uuid_valid(buf, &uuid)) {
BT_DBG("Adv Service UUID mismatch, ignore this adv pkt");
#if CONFIG_BLE_MESH_RPR_SRV
if (rpr_ext_scan_handle_adv_pkt(addr, adv_data, adv_len)) {
if (rpr_ext_scan_handle_adv_pkt(&adv_rpt->addr, adv_data, adv_len)) {
/* If handled as extended scan report successfully, then not
* notify to the application layer as normal BLE adv packet.
*/
@ -467,18 +527,19 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
}
#endif
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
callback_ble_adv_pkt(addr, adv_type, adv_data, adv_len, rssi);
callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
net_buf_simple_restore(buf, &buf_state);
return;
}
break;
case BLE_MESH_DATA_SVC_DATA16:
handle_adv_service_data(buf, addr, uuid, rssi);
handle_adv_service_data(buf, &adv_rpt->addr, uuid, adv_rpt->rssi);
break;
#endif
default:
#if CONFIG_BLE_MESH_RPR_SRV
if (rpr_ext_scan_handle_adv_pkt(addr, adv_data, adv_len)) {
if (rpr_ext_scan_handle_adv_pkt(&adv_rpt->addr, adv_data, adv_len)) {
/* If handled as extended scan report successfully, then not
* notify to the application layer as normal BLE adv packet.
*/
@ -486,44 +547,21 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
}
#endif
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
callback_ble_adv_pkt(addr, adv_type, adv_data, adv_len, rssi);
callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
net_buf_simple_restore(buf, &buf_state);
return;
}
net_buf_simple_restore(buf, &state);
net_buf_simple_pull(buf, len);
}
#if CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN
if (scan_rsp_len != 0) {
/**
* scan response is only visible for remote provisioning extend scan.
*/
rpr_ext_scan_handle_adv_pkt(addr, adv_data + adv_len, scan_rsp_len);
}
#endif /* CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN */
}
int bt_mesh_scan_enable(void)
{
int err = 0;
struct bt_mesh_scan_param scan_param = {
#if CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN
.type = BLE_MESH_SCAN_ACTIVE,
#else
.type = BLE_MESH_SCAN_PASSIVE,
#endif
#if CONFIG_BLE_MESH_USE_DUPLICATE_SCAN
.filter_dup = BLE_MESH_SCAN_FILTER_DUP_ENABLE,
#else
.filter_dup = BLE_MESH_SCAN_FILTER_DUP_DISABLE,
#endif
.interval = SCAN_INTERVAL,
.window = SCAN_WINDOW,
.scan_fil_policy = BLE_MESH_SP_ADV_ALL,
};
err = bt_le_scan_start(&scan_param, bt_mesh_scan_cb);
if (err && err != -EALREADY) {
BT_ERR("starting scan failed (err %d)", err);
@ -546,6 +584,49 @@ int bt_mesh_scan_disable(void)
return 0;
}
int bt_mesh_scan_param_update(struct bt_mesh_scan_param *param)
{
int err = 0;
if (param == NULL ||
param->interval == 0 ||
param->interval < param->window) {
return -EINVAL;
}
scan_param.interval = param->interval;
scan_param.window = param->window;
err = bt_le_scan_stop();
if (err) {
if (err == -EALREADY) {
BT_INFO("New scan parameters will take effect after scan starts");
return 0;
}
BT_ERR("Failed to stop scan (err %d)", err);
return err;
}
/**
* Since the user only needs to set the scan interval
* and scan window parameters, only the interval and
* window parameters in the `param` are correct.
*
* For the aforementioned reason, when updating the scan
* parameters, the other parameters also need to be set
* correctly, and these other parameters are saved in the
* `scan_param`. Therefore, `scan_param` must be used instead
* of `param` here.
*/
err = bt_le_scan_start(&scan_param, bt_mesh_scan_cb);
if (err && err != -EALREADY) {
BT_ERR("Failed to start scan (err %d)", err);
return err;
}
return 0;
}
#if CONFIG_BLE_MESH_TEST_USE_WHITE_LIST
int bt_mesh_scan_with_wl_enable(void)
{

View File

@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileContributor: 2020-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileContributor: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -33,16 +33,22 @@ int bt_mesh_scan_enable(void);
int bt_mesh_scan_disable(void);
int bt_mesh_scan_param_update(struct bt_mesh_scan_param *scan_param);
int bt_mesh_scan_with_wl_enable(void);
struct bt_mesh_ble_scan_param {
uint32_t duration;
};
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
int bt_mesh_start_ble_scan(struct bt_mesh_ble_scan_param *param);
int bt_mesh_stop_ble_scan(void);
bool bt_mesh_ble_scan_state_get(void);
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
#ifdef __cplusplus
}
#endif

View File

@ -1512,18 +1512,18 @@ typedef UINT8 tBTA_DM_LINK_TYPE;
#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_INCLUDE_TX_PWR (1 << 6)
#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_MASK (0x7F)
#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_IND (ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\
ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE |\
ESP_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE)
#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_LD_DIR (ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\
ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE |\
ESP_BLE_GAP_SET_EXT_ADV_PROP_DIRECTED)
#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_HD_DIR (ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\
ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE |\
ESP_BLE_GAP_SET_EXT_ADV_PROP_HD_DIRECTED)
#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_SCAN (ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\
ESP_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE)
#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_NONCONN (ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY)
#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_IND (BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\
BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE |\
BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE)
#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_LD_DIR (BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\
BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE |\
BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_DIRECTED)
#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_HD_DIR (BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\
BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE |\
BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_HD_DIRECTED)
#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_SCAN (BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY |\
BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE)
#define BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_NONCONN (BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY)
typedef UINT16 tBTA_DM_BLE_EXT_ADV_TYPE_MASK;

View File

@ -958,7 +958,7 @@ static void btc_read_ble_rssi_cmpl_callback(void *p_data)
}
#if (BLE_50_FEATURE_SUPPORT == TRUE)
static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
tBTA_DM_BLE_5_GAP_CB_PARAMS *params)
{
esp_ble_gap_cb_param_t param;

View File

@ -29,6 +29,7 @@ INPUT = \
$(PROJECT_PATH)/components/bootloader_support/include/esp_flash_encrypt.h \
$(PROJECT_PATH)/components/esp_coex/include/esp_coexist.h \
$(PROJECT_PATH)/components/bt/common/api/include/api/esp_blufi_api.h \
$(PROJECT_PATH)/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_ble_api.h \
$(PROJECT_PATH)/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_common_api.h \
$(PROJECT_PATH)/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_local_data_operation_api.h \
$(PROJECT_PATH)/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_low_power_api.h \

View File

@ -71,6 +71,9 @@ Reading of Local Data Information
.. include-build-file:: inc/esp_ble_mesh_local_data_operation_api.inc
Coexist with BLE
.. include-build-file:: inc/esp_ble_mesh_ble_api.inc
Low Power Operation (Updating)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -1,6 +1,6 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -155,6 +155,22 @@ esp_err_t bluetooth_init(void)
/* XXX Need to have template for store */
ble_store_config_init();
#if CONFIG_BLE_MESH_USE_BLE_50
/**
* On the NimBLE host, once any of the discovery,
* advertising, or connection is enabled, it is
* no longer possible to register GATT services.
*
* Once the NimBLE host is started, it will call
* the registered sync callback. Since it is
* uncertain what the user will do in the sync
* callback, GATT services should be registered
* before starting the NimBLE.
*/
extern void bt_mesh_gatts_svcs_add(void);
bt_mesh_gatts_svcs_add();
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
nimble_port_freertos_init(mesh_host_task);
xSemaphoreTake(mesh_sem, portMAX_DELAY);