继续看CoapInitDiscovery()的代码:

a4b72b04507816790d2e6ed98856b617.png

这里大致分三个部分:

⑴ CoapInitSocket()

4bbf716ffcf0070f81f188c53f04f1aa.png

CoapInitSocket()函数调用了CoapCreateUdpServer()函数,创建了一个UDP的socket,并绑定到COAP_DEFAULT_PORT(5684)端口上面上面。这个socket赋值给****g_serverFd****,在下面还会使用。

8edb4062847545f3533d2d6e12f6b69c.png

CoapCreateUdpServer()函数的实现基本上都是用socket族的标准接口实现,首先是socket()创建一个socket,然后用bind()绑定到指定的IP+PORT。

⑵ CoapInitWifiEvent()

bee0c35acb54b740197ef20cee2d7ae9.png

CoapInitWifiEvent()函数大致分为两个部分:

1、CreateMsgQue()创建一个消息队列,使用RegisterWifiEvent()向wifi_lite注册事件回调函数。g_coapEventHandler.OnWifiConnectionChanged 就是当wifi连接状态发生改变(例如:设备连接到wifi后)被回调。

我们看一下CoapConnectionChangedHandler()这个回调函数:

a423712bc5c7538b86544cb1ca163dea.png

再看下CoapWriteMsgQueue()函数代码:

9989159561532eb81c470f6879dd51d5.png

所以这个函数的功能就是向消息队列中放置了一个消息。这个消息包含了wifi的状态和一个回调函数。

这个回调函数是CoapHandleWifiEvent(),代码如下:

6b866389e130507a1977d62359835c97.png

所以这个回调函数就是调用g_wifiCallback。前面我们介绍过,g_wifiCallback被设置成了WifiEventTrigger()函数。最终当wifi状态改变后,会调用WifiEventTrigger()函数。

备注:RegisterWifiEvent()的实现在./vendor/hisi/hi3861/hi3861_adapter/hals/communication/wifi_lite/wifiservice/source/wifi_device.c中。

2、创建wifi消息队列的处理线程(任务)CoapWifiEventThread()

CoapWifiEventThread()函数的代码如下:

3fb0dbcb468f1e54e77a007b7c2864b9.png

这个函数主要就是从wifi的消息队列中获取消息,然后执行消息中的回调函数,也就是WifiEventTrigger()函数。

⑶ CreateCoapListenThread()

这个函数的代码如下:

7e74e9b6556808e9820fbfd7ad13b3ec.png

这个函数主要就是创建了一个线程CoapReadHandle,用于处理COAP_DEFAULT_PORT端口上的UDP socket的数据(也就是基于COAP协议的discover广播消息),代码如下:

0603d26d792d44976c698ee0ffd287ba.png

这个函数的核心是调用了HandleReadEvent()。从UDP socket中读取数据,并解析COAP协议。代码如下:

990f69ccfab24b05c60d6cd2f13fa9d7.png

上面的代码中 CoapSocketRecv()就是调用recvfrom()从socket中读取数据。然后调用COAP_SoftBusDecode()函数对COAP协议进行解析,解析的内容放在decodePacket结构中。最后调用PostServiceDiscover()对智慧屏发送的DISCOVER消息进行回应。这里代码不再展开,有兴趣同学自己读一下。

F、调用CoapWriteMsgQueue()触发获取wifi的IP地址,并启动总线

CoapWriteMsgQueue()函数的代码如下:

40d4a56a0724d2707c7b082dda4f5608.png

这个函数就是向wifi的消息队列写入一个消息,强制触发消息回调函数的执行。前面我们介绍过,消息回调函数就是WifiEventTrigger()。

流程图如下:

e3b99d5e0ac81b3889bed55d297d76af.png

WifiEventTrigger()函数的代码如下:

fe36f56ed1be14359ccf83e50ff03b6a.png

这个函数的主要工作是:

1、通过CoapGetIp()获取本地设备wifi连接后的IP地址,并放入到deviceInfo->deviceIp中。后续会使用。

8f4724099273348b9aea150716be099a.png

CoapGetIp()函数会循环执行,每次sleep 10ms,一直到能拿到IP地址。CoapGetWifiIp()函数有两个版本,分别对应LiteOS和Linux,有兴趣的同学可以自己看下代码。

2、BusManager()函数启动软总线。

b3cfd7a927ea19416c75ab882eeffc73.png

StartBus()函数主要完成两个任务:

a、创建认证服务

877febdbe394fa351ec169421fb2e1dc.png

b、创建会话服务

9a36b08c156aae8627cf3462186b5c5c.png

c9f4e4659399c60627d8b2a35582ed9a.png

SelectSessionLoop()就是任务线程,会根据模块注册的sessionServer的数组监听所有的session的数据通信情况,并处理数据。这里不再展开,有兴趣同学可以自己看下代码。

注意:上层模块注册的session将保持在g_sessionMgr->sessionMap_[]数组中。

G、向COAP中注册设备信息

e0cf65b67d52cb2ef31a1eb9b295a7b0.png

这个函数主要完成g_localDeviceInfo数据结构的初始化,有兴趣的同学可以自己看一下。

整个InitService的流程图如下:

71bee9b1c7d74aa14711a74da350afb6.png

小结:

初始化服务调用InitService()函数实现了如下的功能:

1、初始化了g_deviceInfo结构体,包括:deviceName,deviceId,deviceIp。

2、注册wifi_lite的event监控事件,当wifi链路发生变化的情况下(例如:设备wifi连接成功),获取当前设备wifi的IP地址,并放入到g_deviceInfo->deviceIp中,为下面TCP/IP协议栈的初始化做准备。

3、初始化UDP协议socket绑定在COAP_DEFAULT_PORT端口上,监听COAP的discover消息,并进行处理。

4、根据deviceIp初始化TCP协议socket,并且启动一个监听任务,处理连接请求,并进行auth的校验。

5、根据deviceIp初始化TCP协议socket,并且启动一个监听任务,处理session的会话请求。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐