服务发现过程分析
本講主要針對 主從連接后主機(jī)如何在從機(jī)上找到自己需要的服務(wù)的過程。需要和 主從通信過程分析教程一起看。
?
服務(wù)查找過程就是主從連接后,主機(jī)需要在從機(jī)上查找所有的服務(wù)以及服務(wù)下面的特征值和描述符等信息。 不過Sdk中的主從通信例子因?yàn)槭莻€(gè) 簡單的主從點(diǎn)燈demo,所以服務(wù)查找過程中并不是搜尋從機(jī)上的所有服務(wù),而是根據(jù)初始化時(shí)注冊的要查找的服務(wù)來定向搜尋從機(jī)上的服務(wù),已經(jīng)其下面的特征值和描述符信息。
?
服務(wù)發(fā)現(xiàn)過程的細(xì)節(jié)比較多,文字描述不方面將所有考慮的細(xì)節(jié)都說到,所以這里描述的是 服務(wù)發(fā)現(xiàn)的主要過程。
?
在主機(jī)代碼中,當(dāng)連接到從機(jī)后,協(xié)議棧會將BLE_GAP_EVT_CONNECTED事件傳遞給上層派發(fā)函數(shù)ble_evt_dispatch
該函數(shù)會將事件傳遞給所有事件處理函數(shù),設(shè)備管理模塊的事件處理函數(shù)dm_ble_evt_handler對連接事件進(jìn)行了處理
而dm_ble_evt_handler處理連接事件時(shí)會生成一個(gè) 設(shè)備管理模塊的內(nèi)部事件DM_EVT_CONNECTION,然后再將其傳遞給 設(shè)備管理模塊 初始化時(shí)注冊的回調(diào)函數(shù)。如下圖
所以最終由device_manager_event_handler函數(shù)來處理DM_EVT_CONNECTION這個(gè)事件。
?
而該函數(shù)在處理DM_EVT_CONNECTION事件時(shí)會調(diào)用client_handling_create函數(shù),該函數(shù)內(nèi)部就會啟動(dòng)服務(wù)發(fā)現(xiàn)過程
在ble_db_discovery_start函數(shù)中,會提取 main函數(shù)中調(diào)用client_handling_init注冊的要找的服務(wù)的uuid。來執(zhí)行服務(wù)查找
如下圖所示:
當(dāng)服務(wù)查找完成后 協(xié)議棧傳遞BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP事件給派發(fā)函數(shù),派發(fā)函數(shù)再遞交給事件處理函數(shù),在事件處理函數(shù)client_handling_ble_evt_handler 的最后調(diào)用了ble_db_discovery_on_ble_evt函數(shù),該函數(shù)就是處理服務(wù)發(fā)現(xiàn)過程中的相關(guān)事件。
在收到服務(wù)發(fā)現(xiàn)完成事件后,再進(jìn)一步到on_primary_srv_discovery_rsp函數(shù)中處理
???
而該函數(shù)內(nèi)部的處理就是開始啟動(dòng) 服務(wù)中特性的查找。如下圖
????
每個(gè)特性查找完成后都會返回BLE_GATTC_EVT_CHAR_DISC_RSP事件,于是再進(jìn)入
on_characteristic_discovery_rsp函數(shù)處理
該處理函數(shù)比較長不便于整體截圖,這里部分截圖其主要功能部分,其主要功能就是更新已經(jīng)查找到的特性的總數(shù)量的值,并且判斷是否還有可能的特性需要發(fā)現(xiàn),如果可能還有(目前查找到的特性的特征值的handle小于服務(wù)的end handle),那么就繼續(xù)執(zhí)行上面說的特性發(fā)現(xiàn)發(fā)現(xiàn),如果沒有了,就開始執(zhí)行描述符發(fā)現(xiàn)過程。
?
綜上,當(dāng)特性發(fā)現(xiàn)完成后就開始調(diào)用descriptors_discover來執(zhí)行描述符發(fā)現(xiàn)過程了。
該函數(shù)的主要功能就是 判斷是否有描述符需要發(fā)現(xiàn),如果有的話設(shè)置發(fā)現(xiàn)尋找過程中要尋找的句柄范圍,部分截圖如下
然后根據(jù)是否需要查找描述符標(biāo)志來執(zhí)行發(fā)現(xiàn)描述符函數(shù)
描述符發(fā)現(xiàn)完成后會收到事件BLE_GATTC_EVT_DESC_DISC_RSP,并由相應(yīng)事件處理函數(shù)處理
該處理函數(shù)中首先會判斷發(fā)現(xiàn)的描述符是不是CCCD,如果是就記錄下其句柄。然后判斷當(dāng)發(fā)現(xiàn)的是描述符是第幾個(gè)特性下的,如果還沒達(dá)到之前發(fā)現(xiàn)的特性總數(shù),就繼續(xù)執(zhí)行查找描述符來查找下一個(gè)特性的描述符的
當(dāng)所有描述符發(fā)現(xiàn)完成后就會調(diào)用下面兩個(gè)函數(shù)
?discovery_complete_evt_trigger函數(shù)會產(chǎn)生服務(wù)發(fā)現(xiàn)完成事件給之前 main中初始化client_handling_init函數(shù)里面注冊的要找的服務(wù)找到后會執(zhí)行的回調(diào)函數(shù),并且當(dāng)所有注冊的要找的服務(wù)都找完后就調(diào)用那些回調(diào)函數(shù)。
而on_srv_disc_completion函數(shù)負(fù)責(zé)判斷是否查找玩了之前調(diào)用client_handling_init中注冊的所有要找的服務(wù),如果沒有就繼續(xù)尋找下一個(gè)需要找的服務(wù)。
PS:這兩個(gè)函數(shù)不是一定會在描述符發(fā)現(xiàn)完成后才被調(diào)用,也可能特性發(fā)現(xiàn)完后就直接調(diào)用。因?yàn)榭赡懿]有描述符需要發(fā)現(xiàn)
總結(jié)
- 上一篇: nrf51822-主从通信分析2
- 下一篇: ESP32 各种时钟参数值设置