開發板: W801-KIT
SDK: WM-W80X-SDK-v1.00.10-202308(使用NimBLE藍牙協議棧)
在串口輸入: t-bt-on, t-ble-server-on,依次打開藍牙模塊, 藍牙服務器demo
bug複現:
調試過程:
tls_ble_server_demo_api_init
// 將GAP事件回調注冊到全局GAP監聽鏈表
le_gap_event_listener_register(..., ble_gap_evt_cb, NULL)
ble_gatts_start()
// 啟動廣播
wm_ble_server_api_demo_adv(true)
tls_nimble_gap_adv(WM_BLE_ADV_IND, 0)
// 指定廣播過程的事件回調(建立連接後, 該回調賦值給連接對象)
ble_gap_adv_start(..., gap_event, NULL);
通過追蹤源碼發現,事件回調函數有2個,一個是ble_gap_evt_cb, 另一個是gap_event。疑似重新配對事件沒有傳遞給ble_gap_evt_cb回調函數。分別在他們的開頭添加printf,輸出遇到的觸發的事件類型(ID),如下:
// 位於: src/app/bleapp/wm_ble_gap.c
static int gap_event(struct ble_gap_event *event, void *arg)
{
// 添加printf幫助定位問題
printf("%s:%d gap_event, type=%d\n", __FILE__, __LINE__, event->type);
return 0;
}
// 位於: src/app/bleapp/wm_ble_server_api_demo.c
static int ble_gap_evt_cb(struct ble_gap_event *event, void *arg)
{
int rc;
struct ble_gap_conn_desc desc;
// 開頭添加printf,幫助定位問題
printf("%s:%d, ble_gap_evt_cb, type:%d\n", __FILE__, __LINE__, event->type);
// 後面的不修改
switch(event->type) {
case BLE_GAP_EVENT_CONNECT:
...
case BLE_GAP_EVENT_DISCONNECT:
...
case BLE_GAP_EVENT_REPEAT_PAIRING: // 有重複配對這塊的處理
...
}
}
串口工具的輸出如下:
結論:
藍牙手機刪除首次配對信息,重新進行配對時,會出現配對失敗的現象。追蹤源碼發現,gap事件處理函數有兩個:
我在學習nimble協議棧時發現,通過register方式注冊的GAP回調,能收到廣播相關,建立連接,斷開連接,nofity等事件。但建立連接後的相關事件就收不到,譬如說重複配對事件。
最簡單的修複方式是把ble_gap_evt_cb中處理重複配對的代碼(case BLE_GAP_EVENT_REPEAT_PAIRING)拷貝到gap_event函數中。但,我覺得這是官方對NimBLE的事件回調有誤解導致的,請進行修複!。或修改API,能把ble_gap_evt_cb回調直接傳遞給ble_gap_adv_start。