ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-06-25 22:01:07  阅读:174  来源: 互联网

标签:OpenHarmony serverFd wifiIpAddr void COAP discover readSet fd coap


前言

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

接收与响应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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有