继续看CoapInitDiscovery()的代码:
这里大致分三个部分:
⑴ CoapInitSocket()
CoapInitSocket()函数调用了CoapCreateUdpServer()函数,创建了一个UDP的socket,并绑定到COAP_DEFAULT_PORT(5684)端口上面上面。这个socket赋值给****g_serverFd****,在下面还会使用。
CoapCreateUdpServer()函数的实现基本上都是用socket族的标准接口实现,首先是socket()创建一个socket,然后用bind()绑定到指定的IP+PORT。
⑵ CoapInitWifiEvent()
CoapInitWifiEvent()函数大致分为两个部分:
1、CreateMsgQue()创建一个消息队列,使用RegisterWifiEvent()向wifi_lite注册事件回调函数。g_coapEventHandler.OnWifiConnectionChanged 就是当wifi连接状态发生改变(例如:设备连接到wifi后)被回调。
我们看一下CoapConnectionChangedHandler()这个回调函数:
再看下CoapWriteMsgQueue()函数代码:
所以这个函数的功能就是向消息队列中放置了一个消息。这个消息包含了wifi的状态和一个回调函数。
这个回调函数是CoapHandleWifiEvent(),代码如下:
所以这个回调函数就是调用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()函数的代码如下:
这个函数主要就是从wifi的消息队列中获取消息,然后执行消息中的回调函数,也就是WifiEventTrigger()函数。
⑶ CreateCoapListenThread()
这个函数的代码如下:
这个函数主要就是创建了一个线程CoapReadHandle,用于处理COAP_DEFAULT_PORT端口上的UDP socket的数据(也就是基于COAP协议的discover广播消息),代码如下:
这个函数的核心是调用了HandleReadEvent()。从UDP socket中读取数据,并解析COAP协议。代码如下:
上面的代码中 CoapSocketRecv()就是调用recvfrom()从socket中读取数据。然后调用COAP_SoftBusDecode()函数对COAP协议进行解析,解析的内容放在decodePacket结构中。最后调用PostServiceDiscover()对智慧屏发送的DISCOVER消息进行回应。这里代码不再展开,有兴趣同学自己读一下。
F、调用CoapWriteMsgQueue()触发获取wifi的IP地址,并启动总线
CoapWriteMsgQueue()函数的代码如下:
这个函数就是向wifi的消息队列写入一个消息,强制触发消息回调函数的执行。前面我们介绍过,消息回调函数就是WifiEventTrigger()。
流程图如下:
WifiEventTrigger()函数的代码如下:
这个函数的主要工作是:
1、通过CoapGetIp()获取本地设备wifi连接后的IP地址,并放入到deviceInfo->deviceIp中。后续会使用。
CoapGetIp()函数会循环执行,每次sleep 10ms,一直到能拿到IP地址。CoapGetWifiIp()函数有两个版本,分别对应LiteOS和Linux,有兴趣的同学可以自己看下代码。
2、BusManager()函数启动软总线。
StartBus()函数主要完成两个任务:
a、创建认证服务
b、创建会话服务
SelectSessionLoop()就是任务线程,会根据模块注册的sessionServer的数组监听所有的session的数据通信情况,并处理数据。这里不再展开,有兴趣同学可以自己看下代码。
注意:上层模块注册的session将保持在g_sessionMgr->sessionMap_[]数组中。
G、向COAP中注册设备信息
这个函数主要完成g_localDeviceInfo数据结构的初始化,有兴趣的同学可以自己看一下。
整个InitService的流程图如下:
小结:
初始化服务调用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的会话请求。