其他分享
首页 > 其他分享> > OpenHarmony之分布式软总线coap_discover.c(二)

OpenHarmony之分布式软总线coap_discover.c(二)

作者:互联网

前言

  这部分将分析当设备收到对端设备发现报文时,需要发送响应报文的过程。

接收与响应coap设备发现

 1 /*
 2     函数功能: 获取服务发现信息
 3     函数参数: 
 4             buf :  指向保存有服务信息的数据缓冲区
 5             size : 数据缓冲区大小
 6             deviceInfo:  用来保存设备信息
 7             remoteUrlPtr : 指向用来保存URL的缓存区
 8     详细:
 9             1. 判断buf是否为空
10             2. buf具有数据那么就分配一个同样大小的空间,并将buf中的数据拷贝到newbuf中,且将buf指针指向newbuf
11             3. 调用json_payload.c中ParseServiceDiscover解析出buf所指缓存区的数据(对端设备的 设备信息,设备功能,设备IP)保存在deviceInfo,url保存在由remoteUrlPtr指向的在url的缓存区
12             4. 释放newbuf空间
13 */
14 int GetServiceDiscoverInfo(const uint8_t *buf, size_t size, DeviceInfo *deviceInfo, char **remoteUrlPtr)
15 {
16     uint8_t *newBuf = NULL;
17     if (size <= 0) {
18         return NSTACKX_EFAILED;
19     }
20     //包含数据
21     if (buf[size - 1] != '\0') {
22         //newBuf 分配空间并初始化为1
23         newBuf = (uint8_t *)calloc(1, size + 1);
24         if (newBuf == NULL) {
25             return NSTACKX_ENOMEM;
26         }·
27         if (memcpy_s(newBuf, size + 1, buf, size) != EOK) {
28             goto L_COAP_ERR;
29         }
30         buf = newBuf;
31     }
32     //解析出设备发现信息
33     if (ParseServiceDiscover(buf, deviceInfo, remoteUrlPtr) != NSTACKX_EOK) {
34         goto L_COAP_ERR;
35     }
36     if (newBuf != NULL) {
37         free(newBuf);
38     }
39     return NSTACKX_EOK;
40 L_COAP_ERR:
41     if (newBuf != NULL) {
42         free(newBuf);
43     }
44     return NSTACKX_EFAILED;
45 }
 1 /*
 2     函数功能: 对接收到的消息进行服务发现响应
 3     函数功能: pkt: 接收到的coap数据包
 4     函数返回值 : 无
 5     详细:
 6         1. 声明remoteurl 来存储对端url,deiceInfo保存对端设备信息
 7         2. 调用GetServiceDiscoverInfo解析出device信息和对端url
 8         3. 创建字符数组wifiIpAddr用来保存对端ip地址
 9         4. 将点分IP转换为二进制网络字节序IP,并保存在wifiIpAddr
10         5. 发送响应报文,最后释放remoteUrl
11 */
12 void PostServiceDiscover(const COAP_Packet *pkt)
13 {
14     char *remoteUrl = NULL;
15     DeviceInfo deviceInfo;
16     if (pkt == NULL) {
17         return;
18     }
19     //为deiveInfo分配空间
20     (void)memset_s(&deviceInfo, sizeof(deviceInfo), 0, sizeof(deviceInfo));
21     if (GetServiceDiscoverInfo(pkt->payload.buffer, pkt->payload.len, &deviceInfo, &remoteUrl) != NSTACKX_EOK) {
22         return;
23     }
24     char wifiIpAddr[NSTACKX_MAX_IP_STRING_LEN];
25     (void)memset_s(wifiIpAddr, sizeof(wifiIpAddr), 0, sizeof(wifiIpAddr));  //初始化为0
26     (void)inet_ntop(AF_INET, &deviceInfo.netChannelInfo.wifiApInfo.ip, wifiIpAddr, sizeof(wifiIpAddr));
27     if (remoteUrl != NULL) {
28         CoapResponseService(pkt, remoteUrl, wifiIpAddr);
29         free(remoteUrl);
30     }
31 }
 1 /*
 2     函数功能: 处理读事件
 3     函数参数 : fd: 可读就绪的套接字
 4     函数返回值: 无
 5     详细:
 6         1. 分配一个1*(COAP_MAX_PDU_SIZE + 1) 接收缓存区
 7         2. 调用coap_socket.c中CoapSocketRecv函数接收数据
 8         3. 如果接收错误,释放接收缓冲区空间
 9         4. 创建一个COAP_Packet,用于保存从接收缓冲区解析出来的coap数据包
10         5. 最后需要对接收到的数据做出响应
11 */
12 static void HandleReadEvent(int fd)
13 {
14     int socketFd = fd;
15     unsigned char *recvBuffer = calloc(1, COAP_MAX_PDU_SIZE + 1);
16     if (recvBuffer == NULL) {
17         return;
18     }
19     ssize_t nRead;
20     nRead = CoapSocketRecv(socketFd, recvBuffer, COAP_MAX_PDU_SIZE);
21     if ((nRead == 0) || (nRead < 0 && errno != EAGAIN &&
22         errno != EWOULDBLOCK && errno != EINTR)) {
23         free(recvBuffer);
24         return;
25     }
26     COAP_Packet decodePacket;
27     (void)memset_s(&decodePacket, sizeof(COAP_Packet), 0, sizeof(COAP_Packet));
28     decodePacket.protocol = COAP_UDP;
29     COAP_SoftBusDecode(&decodePacket, recvBuffer, nRead);
30     PostServiceDiscover(&decodePacket);
31     free(recvBuffer);
32 }
33 /*
34     函数功能: 接收并处理收到的数据
35     详细:
36         1. 声明fd_set结构来表示一组等待检查的套接口,用于select 端口复用,可读文件描述符
37         2. 获取服务端socket
38         3. 将set清零使集合中不含任何fd,将服务socket接入到集合
39         4. 需要检查的文件描述字个数(即检查到fd_set的第几位),用来检查可读性的一组文件描述字readSet
40         5. 若有就绪描述符,则返回就绪描述符数目,检查readSet中对应serverFd的位是否被设置,如果该位被设置之后,那么readSet中与serverFd对应的位无关的位均清0
41         6. 最后处理读事件
42 */
43 static void CoapReadHandle(unsigned int uwParam1, unsigned int uwParam2, unsigned int uwParam3, unsigned int uwParam4)
44 {
45     //这些参数在函数体中没有用到,但是为了防止编译器警告
46     (void)uwParam1; 
47     (void)uwParam2;
48     (void)uwParam3;
49     (void)uwParam4;
50     int ret;
51     //fd_set结构来表示一组等待检查的套接口,用于select 端口复用,可读文件描述符
52     fd_set readSet;
53     //获取服务端socket
54     int serverFd = GetCoapServerSocket();
55     SOFTBUS_PRINT("[DISCOVERY] CoapReadHandle coin select begin\n");
56     while (g_terminalFlag) {  //设备为终端设备
57         FD_ZERO(&readSet);//将set清零使集合中不含任何fd
58         FD_SET(serverFd, &readSet); //将服务socket接入到集合
59         //需要检查的文件描述字个数(即检查到fd_set的第几位),用来检查可读性的一组文件描述字readSet   
60         ret = select(serverFd + 1, &readSet, NULL, NULL, NULL);
61         //若有就绪描述符,则返回就绪描述符数目
62         if (ret > 0) {
63             //检查readSet中对应serverFd的位是否被设置,如果该位被设置之后,那么readSet中与serverFd对应的位无关的位均清0,
64             if (FD_ISSET(serverFd, &readSet)) {
65                 //处理读事件
66                 HandleReadEvent(serverFd);
67             }
68         } else {
69             SOFTBUS_PRINT("[DISCOVERY]ret:%d,error:%d\n", ret, errno);
70         }
71     }
72     SOFTBUS_PRINT("[DISCOVERY] CoapReadHandle exit\n");
73 }

 

标签:OpenHarmony,serverFd,wifiIpAddr,void,COAP,discover,readSet,fd,coap
来源: https://www.cnblogs.com/zjra/p/16412506.html