那麼如今回到程序上去吧,這個比較適合已經看過一些藍牙SDK代碼。api
1,首先協議棧是如何運做的?app
協議棧是基於100%的事件驅動,也就是說協議棧向app發送任何數據都是基於事件的。函數
當設備收到數據,協議棧獲得數據處理後,而後將數據打包成一個結構體,並附上事件id,好比BLE_GAP_EVT_CONNECTED,BLE_GATT_EVT_WRITE來分別告訴上層app這個事件結構體表明的事件。spa
好比BLE_GAP_EVT_CONNECTED表明連接事件,那麼這個事件結構體中包含的數據就是鏈接參數等數據。而BLE_GATT_EVT_WRITE表明寫事件,那麼結構體中數據就是對端設備寫給板子的數據。接口
根據上圖能夠明顯看出ble_evt_dispatch()函數就是事件派發函數,舉個例子:事件
static void ble_evt_dispatch(ble_evt_t *p_ble_evt)回調函數
{it
ble_conn_params_on_evt(p_ble_evt);打包
ble_nus_ble_evt(&m_nus,p_ble_evt);service
on_ble_evt(p_ble_evt);
}
鏈接參數管理處理函數ble_conn_params_on_evt(p_ble_evt);
UART服務時間處理函數ble_nus_ble_evt(&m_nus,p_ble_evt);
通用事件處理函數 on_ble_evt(p_ble_evt);
不一樣的事件在事件結構體ble_evt_t中經過id來區別。
而後建立一個服務應該添加到哪裏?
在main()函數中有一個services_init();這個函數的內部就是添加服務,特徵值等代碼。
該函數內部其實就是註冊了一個回調函數nus_data_handler(該函數會在手機發數據給板子時將數據從電腦串口打印出來)而後再執行真正的初始化函數ble_nus_init。該函數內部又會調用sd_ble_gatts_service_add這個協議棧的api接口來添加服務。後面也會調用 sd_ble_gatts_characteristic_add這個協議棧的api接口來添加特徵值。如圖所示:
最後手機發送的數據在哪裏,如何發送數據給手機?
手機發送給設備的數據是在哪一個函數裏出來的? 沒有函數,協議棧會拋上來一個事件結構體,收到的數據在結構體裏。藍牙數據接收在底層,接收完後會返回事件給上層的ble_evt_dispatch分發函數,他將事件分發給各個服務或者事件處理函數。服務或處理函數會捕獲是否存在寫事件case BLE_GATTS_EVT_WRITE:存在就作相應處理。BLE的發送數據給手機是有API接口的,即sd_ble_gatts_hvx(),能夠經過參數來設置是以通知方式發送仍是指示方式發送(通知不須要回復確認,指示須要)。可是手機發過來的數據沒有接受函數,由於他是基於事件驅動的。