nrf51822-主从通信分析2
解決第三個(gè)問題:如何使能從機(jī)上的特征值的 notify功能,使其能通過notify方式發(fā)送數(shù)據(jù)
?
使能從機(jī)的notify功能是通過寫0x0001到從機(jī)的那個(gè)具有notify功能的特征值的CCCD描述符中來實(shí)現(xiàn)的。 既然要寫那就需要先有服務(wù)發(fā)現(xiàn)過程,服務(wù)發(fā)現(xiàn)就是找到從機(jī)里我們需要的服務(wù)以及服務(wù)下面的 特征值,描述符等。 關(guān)于服務(wù)發(fā)現(xiàn)過程的具體講解 參見? 服務(wù)發(fā)現(xiàn)過程解析 教程。
?
因?yàn)榉?wù)發(fā)現(xiàn)過程sdk已經(jīng)做好了,我們不需要去處理。我們要做的就是注冊自己需要找的那個(gè)服務(wù)。 對于sdk中的這個(gè)主從例子來說。因?yàn)閷?shí)現(xiàn)的就是從機(jī)按鍵然后發(fā)數(shù)據(jù)給主機(jī),主機(jī)對應(yīng)亮/滅 led燈, 功能很簡單,所以從機(jī)就定義了一個(gè)服務(wù),該服務(wù)只包含一個(gè) 具有notify功能的特征值,以用來發(fā)送數(shù)據(jù)給主機(jī)。可以在從機(jī)的services_init函數(shù)中看到,如下圖:
服務(wù)和其下的特征值的UUID定義如上圖。這里是128位的uuid,所以還有個(gè)自定義的基準(zhǔn)uuid
?
所以對于主機(jī)端來說,主機(jī)端只要 找到這個(gè)我們需要的服務(wù)以及它下面的那個(gè)具有notify功能的特征值和CCCD就可以了。然后直接寫0x0001到CCCD,就使能從機(jī)的notify功能了。
?
前面說道主機(jī)工程中sdk已經(jīng)做好了服務(wù)發(fā)現(xiàn)的相關(guān)流程,也就是主機(jī)連接上從機(jī)后會(huì)自動(dòng)開始查找從機(jī)里面我們需要的服務(wù),特征值等信息。所以我們需要做的就是直接指明自己想要找的那個(gè)服務(wù)就行了。 SDK提供的機(jī)制就是注冊機(jī)制,也就是SDK在執(zhí)行完 服務(wù)發(fā)現(xiàn)過程前會(huì)有個(gè)初始化,在這個(gè)初始化中注冊自己想要找的服務(wù),以及對應(yīng)的回調(diào)處理函數(shù)。之后會(huì)自動(dòng)進(jìn)行服務(wù)查找,并且查找完成后會(huì)調(diào)用之前一同注冊的回調(diào)函數(shù)
?
綜上 要做的其實(shí)就是注冊 上面說過的 從機(jī)中創(chuàng)建的那個(gè)服務(wù)和對應(yīng)處理函數(shù),在main函數(shù)中的client_handling_init就做了如上處理
該函數(shù)首先設(shè)置了和從機(jī)一樣的 基準(zhǔn)UUID和服務(wù)UUID,然后調(diào)用
ble_db_discovery_evt_register函數(shù)注冊改服務(wù)和回調(diào)函數(shù)db_discovery_evt_handler。如下圖所示。
所以最終當(dāng)主從機(jī)連接完成后,主機(jī)執(zhí)行服務(wù)發(fā)現(xiàn)過程,開始查找我們調(diào)用ble_db_discovery_evt_register函數(shù)注冊過的要找的服務(wù)。? 找到了從機(jī)上的服務(wù)之后,然后便調(diào)用一同注冊的回調(diào)函數(shù)db_discovery_evt_handler。
?
再來看下這個(gè)回調(diào)函數(shù)的實(shí)現(xiàn)
回調(diào)函數(shù)的目的就是找到從機(jī)上那個(gè)服務(wù)下面的具有notify特性的特征值,并且記錄下是第幾個(gè),然后調(diào)用寫函數(shù) 寫改特征值的 附屬描述符CCCD來實(shí)現(xiàn)使能notify功能。(demo中雖然這個(gè)服務(wù)下面只有一個(gè)特征值,但是代碼中實(shí)際還是有一個(gè)查找過程,因?yàn)橐话闱闆r下可能會(huì)存在多個(gè)特征值)如下圖所示
?
再看下notify_enable的實(shí)現(xiàn),就是寫0x0001到該特征值的附屬描述符CCCD中以實(shí)現(xiàn)使能從機(jī)上改特征值的notify功能
?
正常情況下,上面執(zhí)行后,從機(jī)的中服務(wù)下面的那個(gè)唯一的特征值的notify功能就已經(jīng)被使能了,后續(xù)從機(jī)應(yīng)該就可以使用notify方式來發(fā)送數(shù)據(jù)給主機(jī)了。但是demo中到這里其實(shí)并未使能從機(jī)的notify功能,原因在于從機(jī)中對 其特征值的附屬描述符CCCD做了安全要求,要求寫該描述符時(shí)是需要鏈路被加密過的。如下圖
在從機(jī)的services_init函數(shù)中有下面這段設(shè)置。
因?yàn)橹鲝倪B接上后,鏈路并不是加密的,所以當(dāng)之前的 為了使能notify而寫CCCD的操作發(fā)送給從機(jī)后,從機(jī)就會(huì)返回 安全不足錯(cuò)誤。
因?yàn)樯厦娴膎otify_enable中是通過BLE_GATT_OP_WRITE_REQ 即需要回復(fù)的寫操作,主機(jī)于是在收道BLE_GATTC_EVT_WRITE_RSP事件后判斷是不是有安全不足錯(cuò)誤,是就啟動(dòng)建立加密鏈路。如下圖
?
后續(xù)就是安全鏈路的建立。實(shí)際就是配對綁定的過程。Sdk中已經(jīng)做好了這些過程。這部分內(nèi)容比較多,這里不便展開。前面也有一些關(guān)于配對綁定的一些教程,感興趣的可以自己花時(shí)間看下。
?
上面的dm_security_setup_req調(diào)用后,主機(jī)就啟動(dòng)配對綁定過程來加密鏈路了。當(dāng)鏈路加密完成后,協(xié)議棧會(huì)產(chǎn)生 BLE_GAP_EVT_CONN_SEC_UPDATE事件給派發(fā)函數(shù)
在dm_ble_evt_handler處理函數(shù)中處理了該事件
處理過程就是 設(shè)置了一個(gè)內(nèi)部事件id(dm 這個(gè)設(shè)備管理模塊內(nèi)部自定義的事件),然后再轉(zhuǎn)交給device_manager_event_handler 函數(shù)處理(這個(gè)過程前面有描述),這個(gè)函數(shù)最后又會(huì)調(diào)用client_handling_dm_event_handler函數(shù),再最后這個(gè)函數(shù)內(nèi)部會(huì)判斷是不是鏈路加密完成事件,如果是就再次 通過notif_enable 函數(shù)來使能從機(jī)上特征值的notify功能
如圖所示
到這里,主機(jī)如何使能從機(jī)上的特征值的notify功能也解決了。
?
?
最后一個(gè)問題:如何通信,即從機(jī)如何在按鍵后將信息發(fā)給主機(jī)
?
在從機(jī)main初始化中對 按鍵模塊做了初始化,并注冊了一個(gè)按鍵事件回調(diào)函數(shù)
?
sdk9中的程序都是根據(jù)官方PCA10028板子來編寫的,這個(gè)板子上有四個(gè)按鍵button1-4分別對應(yīng)引腳pin0.17-pin0.20,當(dāng)初始化函數(shù)buttons_leds_init被調(diào)用后,就默認(rèn)配置這四個(gè)按鍵被按下時(shí)對應(yīng)產(chǎn)生BSP_EVENT_KEY_0- BSP_EVENT_KEY_3事件。
?
Sdk中主從demo做的是,從機(jī)按下button1主機(jī)就會(huì)對應(yīng)亮/滅某個(gè)led燈(具體第幾個(gè)有從機(jī)是第幾個(gè)連接上的決定),所以從機(jī)中對button1按鍵做了處理,因?yàn)閎utton1按鍵會(huì)產(chǎn)生BSP_EVENT_KEY_0事件,所以按鍵事件處理函數(shù)中就對該事件做了處理,具體就是 使用notify發(fā)送一個(gè)值給主機(jī),如下圖
?
主機(jī)端收到從機(jī)的notify后協(xié)議棧產(chǎn)生BLE_GATTC_EVT_HVX事件,并由派發(fā)函數(shù)遞交給client_handling_ble_evt_handler處理函數(shù)
?
client_handling_ble_evt_handler函數(shù)中首先找到是第幾個(gè)連接的從機(jī)發(fā)來的數(shù)據(jù),然后將index作為參數(shù) 傳遞給on_evt_hvx函數(shù)最終處理
on_evt_hvx 函數(shù)最終就是根據(jù)index亮滅LED,因?yàn)榘遄由螸ED只有4個(gè),所以index<4,主機(jī)上的led燈才會(huì)對應(yīng)亮/滅。
總結(jié)
以上是生活随笔為你收集整理的nrf51822-主从通信分析2的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nrf51822-主从通信分析1
- 下一篇: 服务发现过程分析