簡介
Discovery 是一種基于coap 通信協定的裝置發現機制;Coap(Constrained Application Protocol)是一種可以使用在資源受限的物聯網裝置上,并支援可靠傳輸的輕量化類web協定。它詳細規範定義在 RFC 7252, coap 協定支援IP多點傳播, 即可以同時向多個裝置發送請求,鴻蒙OS的裝置發現功能也是基于這個特性;使用者使用discovery功能時,需要保證發現端裝置與被發現端裝置在同一個區域網路内,并且都能收到對方coap協定封包;目前discovery服務僅支援基于Wi-Fi通信方式的裝置發現機制。
代碼分析
代碼目錄結構如下圖:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5CNmljZkJmMmNmMilzYxImZ5EmMykDO1MTY0YWYzETOj9CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
Discovery 對外提供PublishService() 接口來實作裝置的發現功能,其函數實作解讀如下:
PublishService主要的代碼流程圖如下,由于篇幅有限我們本次不做詳細的介紹。
被發現端主要是通過PublishService()這個函數釋出服務。PublishService()函數的實作在discovery_service.c檔案中,我們來看看這個函數的主流程代碼;
函數參數三個:
moduleName:調用者的子產品名稱
info:PublishInfo結構體,釋出的資訊
cb:釋出成功或者失敗的回調函數
在函數實作中,我們可以看到權限檢查,參數檢驗,信号量建立之類等代碼;這裡就不做介紹;我們從初始化服務 InitService()函數看,
InitCommonManager() 函數主要是調用InitLocalDeviceInfo()給g_deviceInfo結構體初始化;
RegisterWifiCallback(WifiEventTrigger)函數将WifiEventTrigger(unsigned int para)函數指派給全局變量g_wifiCallback
最主要看CoapInit()函數
這裡面我們優先分析下CoapInitSocket() 和 CreateCoapListenThread()
CoapInitSocket()函數實作如下:
可以看到CoapInitSocket()函數裡面其實就是調用了socket()函數建立了socket,然後調用bind()綁定到指定的ip跟port,然後将socket描述符指派給全局變量g_serverFd。以便後面GetCoapServerSocket()函數調用擷取socket描述符。
CreateCoapListenThread() 建立線程接收消息,函數實作如下;
CoapReadHandle 接收并處理收到的消息
HandleReadEvent函數實作如下,我們分别看看CoapSocketRecv()、COAP_SoftBusDecode()、PostServiceDiscover()函數;
CoapSocketRecv()實作就是調用recvfrom()接收消息。
收到消息放到recvBuffer裡面 然後調用COAP_SoftBusDecode()解碼收到的消息。解碼之後放到decodePacket裡面然後調用PostServiceDiscover()函數對接收到的消息進行回應。
PostServiceDiscover()函數代碼如下:
其中GetServiceDiscoverInfo(),這個函數可以擷取到對端的ip 和remoteUrl。
這裡可以擷取到裝置資訊,也就是deviceInfo 結構體成員如下:
擷取到這些資訊之後我們就可以調用CoapResponseService()函數回複消息了。這裡就看看主要的回複消息流程,其他的流程有興趣可以自己繼續鑽研。
調用socket()建立socket 并将socket描述符傳回跟全局變量g_clientFd,以便後面函數GetCoapClientSocket()擷取socket描述符。
調用sendto發送消息。
此文檔隻是介紹了收發消息的主要流程,其他的細節這裡并沒有詳細介紹。感興趣的同學可以根據這個主流程繼續鑽研下其他的功能實作。