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可读了,那么表示收到了一个请求,那么要对请求数据分析,然后来响应这个请求,如图:

  

 

posted @   沉心慢慢  阅读(2781)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示