OpenHarmony-分布式軟總線發布服務與設備發現


discovery_service.c

 

前言

分布式軟總線是鴻蒙系統的基石,它不僅負責設備間的發現和服務的發布,還要負責實現設備間的數據傳輸。鴻蒙其他模塊,比如設備認證等,都是需要通過軟總線來與其他設備進行通信。本篇將基於OpenHarmony(v1.x)對其軟總線進行分析。

發布與訂閱

概述

  分布式軟總線實現設備間無感發現,我覺得其一就是這種發布與訂閱模式,OpenHarmony系統的服務發布與訂閱是基於COAP輕量級協議進行實現的。

  主控設備可以提前訂閱自己想要的服務,一旦有某個設備發布了這個服務,就可以立刻保存它的設備信息,對應發現端和被發現端的發現邏輯如下:

 

  

 

  發現端通過coap廣播自己的發現請求,同時被發現端發布自己的服務,當被發現段接收到一個發現請求,那么單播響應該請求。發現端收到響應之后,保存被發現端的設備信息。(OpenHarmony(v1.0.0)dsoft_lite 只具有右邊部分,並不具有訂閱服務部分,這部分在2.0版 本已經實現)。

 

服務發布

  discovery_service.c實現了輕量級設備端的服務發布功能。

  首先介紹服務發布模塊的服務結構信息,它包含服務模塊的屬性:

  

/*
  發布模塊結構
  publishId : 服務發布ID 標識服務
  medium : 服務發布的媒介(wifi 藍牙..) 
  capabilityBitmap : 對應的功能位圖
  capabilityData : 服務發布的功能數據
  dataLength : 數據長度
*/
typedef struct {
  char package[MAX_PACKAGE_NAME];
  int publishId;
  unsigned short medium;
  unsigned short capabilityBitmap;
  char *capabilityData;
  unsigned short dataLength;
  unsigned short used;
} PublishModule;

 

 

  首先它的入口函數為 PublishService ,這個函數實現服務發布的總流程。 

/*
函數參數: 
            moduleName : 服務模塊名
            info : 發布的服務信息
            IPublishCallback: 服務發布成功或者失敗的回調函數 發布成功后會創建會話,等待發現端連接    
*/
int PublishService(const char *moduleName, const struct PublishInfo *info, const struct IPublishCallback *cb)

 

  在 PublishService 需要做的事主要有:

  •   軟總線權限和參數檢查(目前是查看總線是否開啟)
  •        初始化功能模塊
  •        向g_publishModule 添加相應的模塊
  •        注冊服務(將服務數據和功能添加到設備信息中)
  •        調用發布服務回調函數

服務發布流程樹

  發布服務將其他模塊緊密結合在一起,理解它的運行流程有助於理清各個模塊的關系。下面給出發布服務的流程樹(自左往右,自上往下):

 

  

 

 

 

 

一開始對總線權限和參數進行檢查,檢查完之后就是發布服務初始化,這個初始化分為:初始化基本的設備信息、初始化發布模塊和服務數據存儲空間、注冊回調函數、coap相關初始化、處理IP更新事件、注冊設備信息。 這個部分是發布服務中的重中之重,初始化完成之后就將發布info添加到發布模塊存儲空間,然后注冊服務,之后調用發布回調函數。

現在依次分析初始化:

  1. 初始化基本的設備信息:這一部分很簡單,初始化為0,然后初始接口、是否可信賬戶、設備名、類型、ID、系統版本;
  2. 初始化發布模塊和服務數據存儲空間: calloc分配空間;
  3. 注冊wifi事件回調函數(wifiEventTrigger) : 這個函數的觸發體現在IP地址事件處理上,它用於獲取或清除IP,調用總線管理器開啟或關閉軟總線、注冊設備信息和服務(清空,全部置0)
  4. coap相關初始化:
    • CJSON_init 就是使用默認分配和釋放函數(malloc/free)。
    •      重要的是初始化coap設備發現,這個初始化過程它會創建服務端套接字(g_serverFd)和coap消息ID,並且在創建套接字時,由於當前設備IP為(0.0.0.0),所以內核會隨機分配可用IP(INADDR_ANY)然后該套接字綁定該IP(當前還沒有存儲在設備信息結構體中)
    •      創建一個wifi事件消息隊列,這個消息隊列存儲wifi地址事件的處理信息,並創建一個消息隊列監聽線程不斷的讀這個消息隊列,一旦有地址事件,那么利用其中的處理函數( wifiEventTrigger )處理。
    •      最后,創建coap監聽線程監聽g_serverFd,調用select等待g_serverFd可讀事件發生,因為可讀事件發生表示收到了一個發現請求,那么設備就需要進行響應。   

          5. 處理IP更新事件 : 當前g_serverFd綁定的IP地址,但是IP地址沒有存儲在設備信息結構體當中且未開啟軟總線初始設備信息和服務,所以在coap初始化之后,立即向消息隊列中寫入一個IP更新事件,然后消息隊列監聽線程讀取出事件信息,創建一個線程調用事件處理函數(wifiEventTrigger),將剛剛綁定的IP存儲到設備信息中,然后開啟軟總線、初始設備信息和服務

 

發現請求與響應

 

   服務發布之后,發現設備發現服務,需要對該服務響應請求。

  一旦coap監聽線程,發現g_serverFd可讀了,那么表示收到了一個請求,那么要對請求數據分析,然后來響應這個請求,如圖:

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM