Просмотр исходного кода

ble_mesh: stack: Support reporting normal ble adv packets

lly 5 лет назад
Родитель
Сommit
53d1eda84c

+ 7 - 0
components/bt/Kconfig

@@ -1817,6 +1817,13 @@ if BLE_MESH
 
         endif # BLE_MESH_SUPPORT_BLE_ADV
 
+        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.
+
     endmenu # BLE Mesh and BLE coexistence support
 
     config BLE_MESH_FAST_PROV

+ 3 - 3
components/bt/common/btc/core/btc_task.c

@@ -140,9 +140,9 @@ static btc_func_t profile_tab[BTC_PID_NUM] = {
 #if CONFIG_BLE_MESH_TIME_SCENE_SERVER
     [BTC_PID_TIME_SCENE_SERVER] = {NULL,                                        btc_ble_mesh_time_scene_server_cb_handler},
 #endif /* CONFIG_BLE_MESH_TIME_SCENE_SERVER */
-#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
-    [BTC_PID_BLE_MESH_BLE_COEX]     = {btc_ble_mesh_ble_call_handler,               btc_ble_mesh_ble_cb_handler              },
-#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
+#if CONFIG_BLE_MESH_BLE_COEX_SUPPORT
+    [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 /* #if CONFIG_BLE_MESH */
 };
 

+ 35 - 1
components/bt/esp_ble_mesh/api/core/esp_ble_mesh_ble_api.c

@@ -20,14 +20,16 @@
 #include "btc_ble_mesh_ble.h"
 #include "esp_ble_mesh_ble_api.h"
 
-#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
+#if CONFIG_BLE_MESH_BLE_COEX_SUPPORT
 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 */
 
+#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,
                                              const esp_ble_mesh_ble_adv_data_t *data)
 {
@@ -74,3 +76,35 @@ esp_err_t esp_ble_mesh_stop_ble_advertising(uint8_t index)
             == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
 }
 #endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
+
+#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
+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 */

+ 51 - 0
components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_ble_api.h

@@ -25,6 +25,9 @@ extern "C" {
 typedef enum {
     ESP_BLE_MESH_START_BLE_ADVERTISING_COMP_EVT, /*!< Start BLE advertising completion event */
     ESP_BLE_MESH_STOP_BLE_ADVERTISING_COMP_EVT,  /*!< Stop BLE advertising completion event */
+    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;
 
@@ -44,6 +47,29 @@ typedef union {
         int err_code;            /*!< Indicate the result of stopping BLE advertising */
         uint8_t index;           /*!< Index of the BLE advertising */
     } stop_ble_advertising_comp; /*!< Event parameters of ESP_BLE_MESH_STOP_BLE_ADVERTISING_COMP_EVT */
+    /**
+     * @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;
 
 /**
@@ -132,6 +158,31 @@ esp_err_t esp_ble_mesh_start_ble_advertising(const esp_ble_mesh_ble_adv_param_t
  */
 esp_err_t esp_ble_mesh_stop_ble_advertising(uint8_t index);
 
+/** Context of BLE scanning parameters. */
+typedef struct {
+    uint32_t duration; /*!< Duration used to scan normal BLE advertising packets */
+} 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

+ 66 - 3
components/bt/esp_ble_mesh/btc/btc_ble_mesh_ble.c

@@ -17,13 +17,15 @@
 
 #include "btc_ble_mesh_ble.h"
 #include "adv.h"
+#include "scan.h"
 #include "mesh_bearer_adapt.h"
 #include "esp_ble_mesh_ble_api.h"
 
-#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
+#if CONFIG_BLE_MESH_BLE_COEX_SUPPORT
 
 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
     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;
 
@@ -33,22 +35,46 @@ 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) {
+            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;
     }
+#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
 }
 
 static void btc_ble_mesh_ble_free_req_data(btc_msg_t *msg)
 {
+#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
+    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;
     }
+#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
 }
 
 static void btc_ble_mesh_ble_callback(esp_ble_mesh_ble_cb_param_t *cb_params, uint8_t act)
@@ -68,6 +94,31 @@ static void btc_ble_mesh_ble_callback(esp_ble_mesh_ble_cb_param_t *cb_params, ui
                          btc_ble_mesh_ble_copy_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)
+{
+    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);
+}
+#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
+
 void btc_ble_mesh_ble_call_handler(btc_msg_t *msg)
 {
     esp_ble_mesh_ble_cb_param_t param = {0};
@@ -103,6 +154,17 @@ void btc_ble_mesh_ble_call_handler(btc_msg_t *msg)
         btc_ble_mesh_ble_callback(&param, ESP_BLE_MESH_STOP_BLE_ADVERTISING_COMP_EVT);
         break;
 #endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
+#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
+    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;
+#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
     default:
         return;
     }
@@ -111,7 +173,8 @@ void btc_ble_mesh_ble_call_handler(btc_msg_t *msg)
 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);
+    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);
     }
@@ -137,4 +200,4 @@ void btc_ble_mesh_ble_cb_handler(btc_msg_t *msg)
     btc_ble_mesh_ble_free_req_data(msg);
 }
 
-#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
+#endif /* CONFIG_BLE_MESH_BLE_COEX_SUPPORT */

+ 12 - 0
components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_ble.h

@@ -32,13 +32,25 @@ typedef union {
     struct {
         uint8_t index;
     } stop_ble_adv;
+    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_ADV,
     BTC_BLE_MESH_ACT_STOP_BLE_ADV,
+    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);

+ 3 - 0
components/bt/esp_ble_mesh/mesh_common/include/mesh_config.h

@@ -45,6 +45,9 @@ extern "C" {
                                       CONFIG_BLE_MESH_TIME_SCENE_SERVER | \
                                       CONFIG_BLE_MESH_LIGHTING_SERVER)
 
+#define CONFIG_BLE_MESH_BLE_COEX_SUPPORT (CONFIG_BLE_MESH_SUPPORT_BLE_ADV | \
+                                          CONFIG_BLE_MESH_SUPPORT_BLE_SCAN)
+
 #ifdef __cplusplus
 }
 #endif

+ 64 - 2
components/bt/esp_ble_mesh/mesh_core/scan.c

@@ -11,10 +11,13 @@
 #include <stdbool.h>
 #include <errno.h>
 
+#include "btc_ble_mesh_ble.h"
+
 #include "mesh_config.h"
 #include "mesh_trace.h"
 #include "mesh_buf.h"
 #include "mesh_uuid.h"
+#include "scan.h"
 #include "beacon.h"
 #include "net.h"
 #include "prov.h"
@@ -140,6 +143,43 @@ static void handle_adv_service_data(struct net_buf_simple *buf,
 #endif /* (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
            CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
 
+#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,
+                                        uint8_t adv_type, uint8_t data[],
+                                        uint16_t length, int8_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,
                             int8_t rssi, uint8_t adv_type,
                             struct net_buf_simple *buf)
@@ -148,8 +188,15 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
      CONFIG_BLE_MESH_GATT_PROXY_CLIENT
     uint16_t uuid = 0U;
 #endif
+#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
+    uint8_t *adv_data = buf->data;
+    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);
+#endif
         return;
     }
 
@@ -166,11 +213,17 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
         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;
         }
 
@@ -211,12 +264,18 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
         case BLE_MESH_DATA_FLAGS:
             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);
+#endif
                 return;
             }
             break;
         case BLE_MESH_DATA_UUID16_ALL:
             if (!adv_service_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;
@@ -225,7 +284,10 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
             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);

+ 8 - 0
components/bt/esp_ble_mesh/mesh_core/scan.h

@@ -24,6 +24,14 @@ int bt_mesh_scan_disable(void);
 
 int bt_mesh_scan_with_wl_enable(void);
 
+struct bt_mesh_ble_scan_param {
+    uint32_t duration;
+};
+
+int bt_mesh_start_ble_scan(struct bt_mesh_ble_scan_param *param);
+
+int bt_mesh_stop_ble_scan(void);
+
 #ifdef __cplusplus
 }
 #endif