ble_mesh: support scanning normal ble adv pkt

This commit is contained in:
lly
2020-12-09 16:47:01 +08:00
committed by maojianxin
parent d91f8b8a8b
commit 7d4829bc37
11 changed files with 485 additions and 2 deletions

View File

@@ -306,6 +306,7 @@ if(CONFIG_BT_ENABLED)
"esp_ble_mesh/api")
list(APPEND COMPONENT_SRCS
"esp_ble_mesh/api/core/esp_ble_mesh_ble_api.c"
"esp_ble_mesh/api/core/esp_ble_mesh_common_api.c"
"esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c"
"esp_ble_mesh/api/core/esp_ble_mesh_low_power_api.c"
@@ -318,6 +319,7 @@ if(CONFIG_BT_ENABLED)
"esp_ble_mesh/api/models/esp_ble_mesh_lighting_model_api.c"
"esp_ble_mesh/api/models/esp_ble_mesh_sensor_model_api.c"
"esp_ble_mesh/api/models/esp_ble_mesh_time_scene_model_api.c"
"esp_ble_mesh/btc/btc_ble_mesh_ble.c"
"esp_ble_mesh/btc/btc_ble_mesh_config_model.c"
"esp_ble_mesh/btc/btc_ble_mesh_generic_model.c"
"esp_ble_mesh/btc/btc_ble_mesh_health_model.c"

View File

@@ -1644,6 +1644,13 @@ if BLE_MESH
option in the Bluetooth Controller section in menuconfig, which is
"Scan Duplicate By Device Address and Advertising Data".
config BLE_MESH_SUPPORT_BLE_SCAN
bool "Support scanning normal BLE advertising packets"
default n
help
When selected, users can register a callback and receive normal BLE
advertising packets in the application layer.
config BLE_MESH_ALLOC_FROM_PSRAM_FIRST
bool "BLE Mesh will first allocate memory from PSRAM"
default n

View File

@@ -48,6 +48,7 @@
#endif /* #if CONFIG_CLASSIC_BT_ENABLED */
#if CONFIG_BLE_MESH
#include "btc_ble_mesh_ble.h"
#include "btc_ble_mesh_prov.h"
#include "btc_ble_mesh_health_model.h"
#include "btc_ble_mesh_config_model.h"
@@ -114,6 +115,9 @@ static btc_func_t profile_tab[BTC_PID_NUM] = {
[BTC_PID_LIGHTING_SERVER] = {NULL, btc_ble_mesh_lighting_server_cb_handler },
[BTC_PID_SENSOR_SERVER] = {NULL, btc_ble_mesh_sensor_server_cb_handler },
[BTC_PID_TIME_SCENE_SERVER] = {NULL, btc_ble_mesh_time_scene_server_cb_handler},
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
[BTC_PID_BLE_MESH_BLE_COEX] = {btc_ble_mesh_ble_call_handler, btc_ble_mesh_ble_cb_handler },
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
#endif /* #if CONFIG_BLE_MESH */
};

View File

@@ -79,6 +79,7 @@ typedef enum {
BTC_PID_LIGHTING_SERVER,
BTC_PID_SENSOR_SERVER,
BTC_PID_TIME_SCENE_SERVER,
BTC_PID_BLE_MESH_BLE_COEX,
#endif /* CONFIG_BLE_MESH */
BTC_PID_NUM,
} btc_pid_t; //btc profile id

View File

@@ -0,0 +1,62 @@
// Copyright 2017-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include <string.h>
#include "esp_err.h"
#include "btc_ble_mesh_ble.h"
#include "esp_ble_mesh_ble_api.h"
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
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);
}
esp_err_t esp_ble_mesh_start_ble_scanning(esp_ble_mesh_ble_scan_param_t *param)
{
btc_ble_mesh_ble_args_t arg = {0};
btc_msg_t msg = {0};
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_BLE_MESH_BLE_COEX;
msg.act = BTC_BLE_MESH_ACT_START_BLE_SCAN;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_ble_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_stop_ble_scanning(void)
{
btc_ble_mesh_ble_args_t arg = {0};
btc_msg_t msg = {0};
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_BLE_MESH_BLE_COEX;
msg.act = BTC_BLE_MESH_ACT_STOP_BLE_SCAN;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_ble_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */

View File

@@ -0,0 +1,107 @@
// Copyright 2017-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_BLE_MESH_BLE_API_H_
#define _ESP_BLE_MESH_BLE_API_H_
#include "esp_ble_mesh_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/** This enum value is the event of BLE operations */
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_BLE_EVT_MAX,
} esp_ble_mesh_ble_cb_event_t;
/** BLE operation callback parameters */
typedef union {
/**
* @brief ESP_BLE_MESH_START_BLE_SCANNING_COMP_EVT
*/
struct {
int err_code; /*!< Indicate the result of starting BLE scanning */
} start_ble_scan_comp; /*!< Event parameters of ESP_BLE_MESH_START_BLE_SCANNING_COMP_EVT */
/**
* @brief ESP_BLE_MESH_STOP_BLE_SCANNING_COMP_EVT
*/
struct {
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
*/
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_cb_param_t;
/**
* @brief BLE scanning callback function type
*
* @param event: BLE scanning callback event type
* @param param: BLE scanning callback parameter
*/
typedef void (* esp_ble_mesh_ble_cb_t)(esp_ble_mesh_ble_cb_event_t event,
esp_ble_mesh_ble_cb_param_t *param);
/**
* @brief Register BLE scanning callback.
*
* @param[in] callback: Pointer to the BLE scaning callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_ble_callback(esp_ble_mesh_ble_cb_t callback);
/** Context of BLE scanning parameters. */
typedef struct {
uint8_t dummy; /*!< Currently no parameters for BLE scanning */
} esp_ble_mesh_ble_scan_param_t;
/**
* @brief This function is called to start scanning normal BLE advertising packets
* and notifying the packets to the application layer.
*
* @param[in] param: Pointer to the BLE scanning parameters
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_start_ble_scanning(esp_ble_mesh_ble_scan_param_t *param);
/**
* @brief This function is called to stop notifying normal BLE advertising packets
* to the application layer.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_stop_ble_scanning(void);
#ifdef __cplusplus
}
#endif
#endif /* _ESP_BLE_MESH_BLE_API_H_ */

View File

@@ -0,0 +1,172 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include <string.h>
#include "btc_ble_mesh_ble.h"
#include "adv.h"
#include "mesh_bearer_adapt.h"
#include "esp_ble_mesh_ble_api.h"
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
static void btc_ble_mesh_ble_copy_req_data(btc_msg_t *msg, void *p_dst, void *p_src)
{
esp_ble_mesh_ble_cb_param_t *p_dst_data = (esp_ble_mesh_ble_cb_param_t *)p_dst;
esp_ble_mesh_ble_cb_param_t *p_src_data = (esp_ble_mesh_ble_cb_param_t *)p_src;
if (!msg || !p_src_data || !p_dst_data) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
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) {
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) {
memcpy(p_dst_data->scan_ble_adv_pkt.data, p_src_data->scan_ble_adv_pkt.data,
p_src_data->scan_ble_adv_pkt.length);
} else {
BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
}
}
break;
default:
break;
}
}
static void btc_ble_mesh_ble_free_req_data(btc_msg_t *msg)
{
esp_ble_mesh_ble_cb_param_t *arg = NULL;
if (!msg || !msg->arg) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
arg = (esp_ble_mesh_ble_cb_param_t *)msg->arg;
switch (msg->act) {
case ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT:
if (arg->scan_ble_adv_pkt.data) {
bt_mesh_free(arg->scan_ble_adv_pkt.data);
}
break;
default:
break;
}
}
static void btc_ble_mesh_ble_callback(esp_ble_mesh_ble_cb_param_t *cb_params, uint8_t act)
{
btc_msg_t msg = {0};
/* If corresponding callback is not registered, event will not be posted. */
if (!btc_profile_cb_get(BTC_PID_BLE_MESH_BLE_COEX)) {
return;
}
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_BLE_MESH_BLE_COEX;
msg.act = act;
btc_transfer_context(&msg, cb_params, sizeof(esp_ble_mesh_ble_cb_param_t),
btc_ble_mesh_ble_copy_req_data);
}
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)
{
esp_ble_mesh_ble_cb_param_t param = {0};
if (addr == 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;
}
param.scan_ble_adv_pkt.adv_type = adv_type;
param.scan_ble_adv_pkt.rssi = rssi;
btc_ble_mesh_ble_callback(&param, ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT);
}
void btc_ble_mesh_ble_call_handler(btc_msg_t *msg)
{
esp_ble_mesh_ble_cb_param_t param = {0};
btc_ble_mesh_ble_args_t *arg = NULL;
if (!msg || !msg->arg) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
arg = (btc_ble_mesh_ble_args_t *)msg->arg;
switch (msg->act) {
case BTC_BLE_MESH_ACT_START_BLE_SCAN:
param.start_ble_scan_comp.err_code =
bt_mesh_start_ble_scan((struct bt_mesh_ble_scan_param *)&arg->start_ble_scan.param);
btc_ble_mesh_ble_callback(&param, ESP_BLE_MESH_START_BLE_SCANNING_COMP_EVT);
break;
case BTC_BLE_MESH_ACT_STOP_BLE_SCAN:
param.stop_ble_scan_comp.err_code = bt_mesh_stop_ble_scan();
btc_ble_mesh_ble_callback(&param, ESP_BLE_MESH_STOP_BLE_SCANNING_COMP_EVT);
break;
default:
return;
}
}
static inline void btc_ble_mesh_ble_cb_to_app(esp_ble_mesh_ble_cb_event_t event,
esp_ble_mesh_ble_cb_param_t *param)
{
esp_ble_mesh_ble_cb_t btc_ble_mesh_cb =
(esp_ble_mesh_ble_cb_t)btc_profile_cb_get(BTC_PID_BLE_MESH_BLE_COEX);
if (btc_ble_mesh_cb) {
btc_ble_mesh_cb(event, param);
}
}
void btc_ble_mesh_ble_cb_handler(btc_msg_t *msg)
{
esp_ble_mesh_ble_cb_param_t *param = NULL;
if (!msg) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
param = (esp_ble_mesh_ble_cb_param_t *)msg->arg;
if (msg->act < ESP_BLE_MESH_BLE_EVT_MAX) {
btc_ble_mesh_ble_cb_to_app(msg->act, param);
} else {
BT_ERR("%s, Unknown act %d", __func__, msg->act);
}
btc_ble_mesh_ble_free_req_data(msg);
}
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */

View File

@@ -0,0 +1,53 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _BTC_BLE_MESH_BLE_H_
#define _BTC_BLE_MESH_BLE_H_
#include <stdint.h>
#include "btc/btc_manage.h"
#include "mesh_bearer_adapt.h"
#include "esp_ble_mesh_ble_api.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef union {
struct {
esp_ble_mesh_ble_scan_param_t param;
} start_ble_scan;
struct {
/* RFU */
} stop_ble_scan;
} btc_ble_mesh_ble_args_t;
typedef enum {
BTC_BLE_MESH_ACT_START_BLE_SCAN,
BTC_BLE_MESH_ACT_STOP_BLE_SCAN,
} 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 btc_ble_mesh_ble_call_handler(btc_msg_t *msg);
void btc_ble_mesh_ble_cb_handler(btc_msg_t *msg);
#ifdef __cplusplus
}
#endif
#endif /* _BTC_BLE_MESH_BLE_H_ */

View File

@@ -19,6 +19,8 @@
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLE_MESH_DEBUG_ADV)
#include "btc_ble_mesh_ble.h"
#include "mesh.h"
#include "mesh_hci.h"
#include "adv.h"
@@ -642,6 +644,41 @@ static void bt_mesh_adv_srv_data_recv(struct net_buf_simple *buf, const bt_mesh_
}
#endif
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
static bool ble_scan_en;
int bt_mesh_start_ble_scan(struct bt_mesh_ble_scan_param *param)
{
if (ble_scan_en == true) {
BT_WARN("%s, Already", __func__);
return -EALREADY;
}
ble_scan_en = true;
return 0;
}
int bt_mesh_stop_ble_scan(void)
{
if (ble_scan_en == false) {
BT_WARN("%s, Already", __func__);
return -EALREADY;
}
ble_scan_en = false;
return 0;
}
static void inline callback_ble_adv_pkt(const bt_mesh_addr_t *addr,
u8_t adv_type, u8_t data[],
u16_t length, s8_t rssi)
{
if (ble_scan_en) {
bt_mesh_ble_scan_cb_evt_to_btc(addr, adv_type, data, length, rssi);
}
}
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, s8_t rssi,
u8_t adv_type, struct net_buf_simple *buf)
{
@@ -649,8 +686,15 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, s8_t rssi,
CONFIG_BLE_MESH_GATT_PROXY_CLIENT
u16_t uuid = 0U;
#endif
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
u8_t *adv_data = buf->data;
u16_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);
#endif
return;
}
@@ -665,11 +709,17 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, s8_t rssi,
len = net_buf_simple_pull_u8(buf);
/* 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);
#endif
return;
}
if (len > buf->len) {
BT_WARN("AD malformed");
BT_DBG("AD malformed");
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
callback_ble_adv_pkt(addr, adv_type, adv_data, adv_len, rssi);
#endif
return;
}
@@ -711,12 +761,18 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, s8_t rssi,
case BLE_MESH_DATA_FLAGS:
if (!bt_mesh_is_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);
#endif
return;
}
break;
case BLE_MESH_DATA_UUID16_ALL:
if (!bt_mesh_is_adv_srv_uuid_valid(buf, &uuid)) {
BT_DBG("Adv Service UUID mismatch, ignore this adv pkt");
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
callback_ble_adv_pkt(addr, adv_type, adv_data, adv_len, rssi);
#endif
return;
}
break;
@@ -725,7 +781,10 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, s8_t rssi,
break;
#endif
default:
break;
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
callback_ble_adv_pkt(addr, adv_type, adv_data, adv_len, rssi);
#endif
return;
}
net_buf_simple_restore(buf, &state);
@@ -837,6 +896,10 @@ void bt_mesh_adv_deinit(void)
bt_mesh_unref_buf_from_pool(&adv_buf_pool);
memset(adv_pool, 0, sizeof(adv_pool));
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
ble_scan_en = false;
#endif
}
int bt_mesh_scan_enable(void)

View File

@@ -97,4 +97,12 @@ int bt_mesh_scan_enable(void);
int bt_mesh_scan_disable(void);
struct bt_mesh_ble_scan_param {
u8_t dummy;
};
int bt_mesh_start_ble_scan(struct bt_mesh_ble_scan_param *param);
int bt_mesh_stop_ble_scan(void);
#endif /* _ADV_H_ */

View File

@@ -583,6 +583,10 @@ void bt_mesh_rpl_reset(void)
} else {
rpl->old_iv = true;
}
if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
bt_mesh_store_rpl(rpl);
}
}
}
}