uint8_t scan_rsp_len; /*!< Scan response length */
} scan_rst; /*!< Event parameter of ESP_GAP_BLE_SCAN_RESULT_EVT */
該事件還包括如下所示的子事件列表:
/// Sub Event of ESP_GAP_BLE_SCAN_RESULT_EVTtypedef enum {
ESP_GAP_SEARCH_INQ_RES_EVT = 0, /*!< Inquiry result for a peer device. */
ESP_GAP_SEARCH_INQ_CMPL_EVT = 1, /*!< Inquiry complete. */
ESP_GAP_SEARCH_DISC_RES_EVT = 2, /*!< Discovery result for a peer device. */
ESP_GAP_SEARCH_DISC_BLE_RES_EVT = 3, /*!< Discovery result for BLE GATT based service on a peer device. */
ESP_GAP_SEARCH_DISC_CMPL_EVT = 4, /*!< Discovery complete. */
ESP_GAP_SEARCH_DI_DISC_CMPL_EVT = 5, /*!< Discovery complete. */
ESP_GAP_SEARCH_SEARCH_CANCEL_CMPL_EVT = 6, /*!< Search cancelled */} esp_gap_search_evt_t;
ESP_GAP_SEARCH_INQ_RES_EVT事件,它在每次找到新設備時都會被調用。ESP_GAP_SEARCH_INQ_CMPL_EVT事件在掃描完成時觸發,可以用來重新啟動掃描過程:
case ESP_GAP_BLE_SCAN_RESULT_EVT: {
esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param;
switch (scan_result->scan_rst.search_evt) {
case ESP_GAP_SEARCH_INQ_RES_EVT:
esp_log_buffer_hex(GATTC_TAG, scan_result->scan_rst.bda, 6);
ESP_LOGI(GATTC_TAG, 'searched Adv Data Len %d, Scan Response Len %d', scan_result->scan_rst.adv_data_len, scan_result->scan_rst.scan_rsp_len);
adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv, ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len);
ESP_LOGI(GATTC_TAG, 'searched Device Name Len %d', adv_name_len);
esp_log_buffer_char(GATTC_TAG, adv_name, adv_name_len);
ESP_LOGI(GATTC_TAG, 'n');
if (adv_name != NULL) {
if (strlen(remote_device_name) == adv_name_len && strncmp((char *)adv_name, remote_device_name, adv_name_len) == 0) {
ESP_LOGI(GATTC_TAG, 'searched device %sn', remote_device_name);
if (connect == false) {
connect = true;
ESP_LOGI(GATTC_TAG, 'connect to the remote device.');
esp_ble_gap_stop_scanning();
esp_ble_gattc_open(gl_profile_tab[PROFILE_A_APP_ID].gattc_if, scan_result->scan_rst.bda, scan_result->scan_rst.ble_addr_type, true);
}
}
}
break;
首先解析設備名并與remote_device_name中定義的設備名進行比較。如果設備名相符,那么掃描就會停止,并發起連接。
六、發起連接
使用``函數打開到遠程設備的連接。該函數將應用程序配置文件GATT接口、遠程設備地址和一個布爾值作為參數。布爾值用于指示連接是直接完成的還是后臺完成的(自動連接),此時必須將布爾值設置為true以建立連接。請注意,客戶端打開到服務端的虛擬連接。虛擬連接返回一個連接ID。虛擬連接是應用程序配置文件和遠程服務端之間的連接。由于許多應用程序配置文件可以在一個ESP32上運行,所以可能會有許多虛擬連接打開到同一個遠程服務端。還有物理連接,即客戶端和服務端之間的實際BLE連接。因此,如果物理連接被esp_ble_gap_disconnect()函數斷開,那么所有其他的虛擬連接也會被關閉。在本例中,每個應用程序配置文件使用esp_ble_gattc_open()函數創建到同一服務端的虛擬連接,因此當調用close函數時,只有來自應用程序配置文件的連接是關閉的,而如果調用gap_disconnect函數,則兩個連接都將關閉。此外,連接事件被傳播到所有的應用程序配置文件,因為它與物理連接相關,而打開的事件只傳播到創建虛擬連接的應用程序配置文件。
七、連接事件,配置MTU大小
ATT_MTU定義為客戶端與服務端之間發送的任何數據包的最大大小。當客戶端連接到服務端時,它通過交換MTU請求和響應協議數據單元(PDU)通知服務端使用哪個MTU大小。這是在連接打開之后完成的。打開連接后,ESP_GATTC_CONNECT_EVT事件被觸發。
case ESP_GATTC_CONNECT_EVT:
//p_data->connect.status always be ESP_GATT_OK
ESP_LOGI(GATTC_TAG, 'ESP_GATTC_CONNECT_EVT conn_id %d, if %d, status %d', conn_id, gattc_if, p_data->connect.status);
conn_id = p_data->connect.conn_id;
gl_profile_tab[PROFILE_A_APP_ID].conn_id = p_data->connect.conn_id;
memcpy(gl_profile_tab[PROFILE_A_APP_ID].remote_bda, p_data->connect.remote_bda, sizeof(esp_bd_addr_t));
ESP_LOGI(GATTC_TAG, 'REMOTE BDA:');
esp_log_buffer_hex(GATTC_TAG, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, sizeof(esp_bd_addr_t));
esp_err_t mtu_ret = esp_ble_gattc_send_mtu_req (gattc_if, conn_id);
if (mtu_ret){
ESP_LOGE(GATTC_TAG, 'config MTU error, error code = %x', mtu_ret);
}
break;
遠程設備(服務端)的連接ID和地址存儲在Application Profile表中,并打?。?p>
conn_id = p_data->connect.conn_id;gl_profile_tab[PROFILE_A_APP_ID].conn_id = p_data->connect.conn_id;memcpy(gl_profile_tab[PROFILE_A_APP_ID].remote_bda, p_data->connect.remote_bda,
sizeof(esp_bd_addr_t));ESP_LOGI(GATTC_TAG, 'REMOTE BDA:');esp_log_buffer_hex(GATTC_TAG, gl_profile_tab[PROFILE_A_APP_ID].remote_bda,
sizeof(esp_bd_addr_t));
藍牙4.0連接的典型MTU大小是23字節。客戶端可以使用esp_ble_gattc_send_mtu_req()函數更改MTU的大小,該函數接受GATT接口和連接ID。請求的MTU大小由esp_ble_gatt_set_local_mtu()定義。然后服務端可以接受或者拒絕請求。ESP32支持高達517字節的MTU大小,這是由esp_gattc_api.h中的ESP_GATT_MAX_MTU_SIZE定義的。在本例中,MTU的大小設置為500字節。如果配置失敗,返回的錯誤被打印出來:
esp_err_t mtu_ret = esp_ble_gattc_send_mtu_req (gattc_if, conn_id);if (mtu_ret){
ESP_LOGE(GATTC_TAG, 'config MTU error, error code = %x', mtu_ret);}break;
打開連接會觸發ESP_GATTC_OPEN_EVT事件,它用于檢查連接的打開是否成功,否則打印錯誤并退出。
case ESP_GATTC_OPEN_EVT:
if (param->open.status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG, 'open failed, status %d', p_data->open.status);
break;
}ESP_LOGI(GATTC_TAG, 'open success');
當交換MTU時,ESP_GATTC_CFG_MTU_EVT被觸發,在本例中,它用于打印新的MTU大小。
case ESP_GATTC_CFG_MTU_EVT:
if (param->cfg_mtu.status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG,'config mtu failed, error status = %x', param->cfg_mtu.status);
}
ESP_LOGI(GATTC_TAG, 'ESP_GATTC_CFG_MTU_EVT, Status %d, MTU %d, conn_id %d', param->cfg_mtu.status, param->cfg_mtu.mtu, param->cfg_mtu.conn_id);…
八、斷開連接
由于許多應用程序配置文件可以在一個ESP32上運行,所以可能會有許多虛擬連接打開到同一個遠程服務端。還有物理連接,即客戶端和服務端之間的實際BLE連接。因此,如果物理連接被esp_ble_gap_disconnect()函數斷開,那么所有其他的虛擬連接也會被關閉。在本例中,每個應用程序配置文件使用esp_ble_gattc_open()函數創建到同一服務端的虛擬連接,因此當調用esp_ble_gattc_close()函數時,只有來自應用程序配置文件的連接是關閉的,而如果調用esp_ble_gap_disconnect()函數,則兩個連接都將關閉。
上一篇:ESP32學習筆記(33)——BLE GATT客戶端發現服務和讀寫特征值
下一篇:ESP32學習筆記(31)——BLE帶有屬性表的GATT服務
- 熱門資源推薦
- 熱門放大器推薦
設計資源 培訓 開發板 精華推薦
- LTC2945IMS 軌到軌雙向電流和功率監視器的典型應用
- P-NUCLEO-IHM001,帶有 NUCLEO-F302R8 和 X-NUCLEO-IHM07M1 的電機控制 Nucleo 包開發套件
- 五線舵機控制板
- ADA4627-1ACPZ-R7 帶保護同相放大器的典型應用電路
- LGS5600驗證板
- 具有浪涌電流控制的低壓熱插拔控制器
- AD8659ACPZ-R7電壓跟隨器運算放大器典型應用電路
- LT1076HVCT-5 5V 降壓型開關穩壓器的典型應用電路
- MC33072DR2G 高順從電壓灌電流轉換器的典型應用
- 以 2MHz 運行的 LT8611 縮小了解決方案尺寸,避免了 AM 頻帶,并且仍然允許高占空比