• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 FuZhou Lockzhiner Electronic Co., Ltd. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "ohos_init.h"
16 #include "cmsis_os2.h"
17 #include "los_task.h"
18 #include "lz_hardware.h"
19 #include "config_network.h"
20 #include "lwip/udp.h"
21 #include "lwip/ip_addr.h"
22 #include "lwip/priv/tcp_priv.h"
23 #include "lwip/stats.h"
24 #include "lwip/inet_chksum.h"
25 
26 /* 任务的堆栈大小 */
27 #define TASK_STACK_SIZE     20480
28 /* 任务的优先级 */
29 #define TASK_PRIO           24
30 
31 /* 循环等待时间 */
32 #define GET_WIFI_WAIT_MSEC      1000
33 #define SERVER_WAIT_MSEC        2000
34 #define CLIENT_WAIT_MSEC        100
35 
36 /* 打印信息 */
37 #define LOG_TAG             "udp"
38 
39 /* UDP服务端IP地址和端口号 */
40 #define OC_SERVER_IP        "192.168.2.49"
41 #define SERVER_PORT         6666
42 /* UDP客户端端口号 */
43 #define CLIENT_LOCAL_PORT   8888
44 
45 /* 字节缓冲区大小 */
46 #define BUFF_LEN            256
47 
48 WifiLinkedInfo wifiinfo;
49 
udp_get_wifi_info(WifiLinkedInfo * info)50 int udp_get_wifi_info(WifiLinkedInfo *info)
51 {
52     int ret = -1;
53     int gw, netmask;
54     memset(info, 0, sizeof(WifiLinkedInfo));
55     unsigned int retry = 15;
56     struct in_addr addr;
57 
58     while (retry) {
59         if (GetLinkedInfo(info) == WIFI_SUCCESS) {
60             if (info->connState == WIFI_CONNECTED) {
61                 if (info->ipAddress != 0) {
62                     addr.s_addr = (in_addr_t)info->ipAddress;
63                     LZ_HARDWARE_LOGD(LOG_TAG, "rknetwork IP (%s)", inet_ntoa(addr));
64 
65                     if (WIFI_SUCCESS == GetLocalWifiGw(&gw)) {
66                         addr.s_addr = (in_addr_t)gw;
67                         LZ_HARDWARE_LOGD(LOG_TAG, "network GW (%s)", inet_ntoa(addr));
68                     }
69                     if (WIFI_SUCCESS == GetLocalWifiNetmask(&netmask)) {
70                         addr.s_addr = (in_addr_t)netmask;
71                         LZ_HARDWARE_LOGD(LOG_TAG, "network NETMASK (%s)", inet_ntoa(addr));
72                     }
73                     if (WIFI_SUCCESS == SetLocalWifiGw()) {
74                         LZ_HARDWARE_LOGD(LOG_TAG, "set network GW");
75                     }
76                     if (WIFI_SUCCESS == GetLocalWifiGw(&gw)) {
77                         addr.s_addr = (in_addr_t)gw;
78                         LZ_HARDWARE_LOGD(LOG_TAG, "network GW (%s)", inet_ntoa(addr));
79                     }
80                     if (WIFI_SUCCESS == GetLocalWifiNetmask(&netmask)) {
81                         addr.s_addr = (in_addr_t)netmask;
82                         LZ_HARDWARE_LOGD(LOG_TAG, "network NETMASK (%s)", inet_ntoa(addr));
83                     }
84                     ret = 0;
85                     retry = 0;
86                     continue;
87                 }
88             }
89         }
90         LOS_Msleep(GET_WIFI_WAIT_MSEC);
91         retry--;
92     }
93 
94     return ret;
95 }
96 
97 
udp_server_msg_handle(int fd)98 void udp_server_msg_handle(int fd)
99 {
100     char buf[BUFF_LEN];  // 接收缓冲区
101     socklen_t len;
102     int cnt = 0, count;
103     struct sockaddr_in client_addr = {0};
104 
105     while (1) {
106         memset(buf, 0, BUFF_LEN);
107         len = sizeof(client_addr);
108 
109         printf("[udp server]------------------------------------------------\n");
110         printf("[udp server] waitting client message!!!\n");
111 
112         /* recvfrom是阻塞函数,没有数据就一直阻塞 */
113         count = recvfrom(fd, buf, BUFF_LEN, 0, (struct sockaddr*)&client_addr, &len);
114         if (count == -1) {
115             printf("[udp server] recieve data fail!\n");
116             LOS_Msleep(SERVER_WAIT_MSEC);
117             break;
118         }
119 
120         printf("[udp server] remote addr:%s port:%u\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
121         printf("[udp server] rev:%s\n", buf);
122         memset(buf, 0, BUFF_LEN);
123         snprintf(buf, sizeof(buf), "I have recieved %d bytes data! recieved cnt:%d", count, ++cnt);
124         printf("[udp server] send:%s\n", buf);
125         sendto(fd, buf, strlen(buf), 0, (struct sockaddr*)&client_addr, len);   // 发送信息给client
126     }
127     lwip_close(fd);
128 }
129 
wifi_udp_server(void)130 int wifi_udp_server(void)
131 {
132     int server_fd, ret;
133     struct in_addr addr;
134 
135     while (1) {
136         server_fd = socket(AF_INET, SOCK_DGRAM, 0); // AF_INET:IPV4;SOCK_DGRAM:UDP
137         if (server_fd < 0) {
138             printf("create socket fail!\n");
139             return -1;
140         }
141 
142         /*
143          * 设置调用close(socket)后,仍可继续重用该socket。
144          * 调用close(socket)一般不会立即关闭socket,而经历TIME_WAIT的过程。
145          */
146         int flag = 1;
147 
148         ret = setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int));
149         if (ret != 0) {
150             printf("[CommInitUdpServer]setsockopt fail, ret[%d]!\n", ret);
151         }
152 
153         struct sockaddr_in serv_addr = {0};
154         serv_addr.sin_family = AF_INET;
155         /* IP地址,需要进行网络序转换,INADDR_ANY:本地地址 */
156         serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
157         /* 端口号,需要网络序转换 */
158         serv_addr.sin_port = htons(SERVER_PORT);
159         /* 绑定服务器地址结构 */
160         ret = bind(server_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
161         if (ret < 0) {
162             printf("socket bind fail!\n");
163             lwip_close(server_fd);
164             return -1;
165         }
166 
167         addr.s_addr = (in_addr_t)wifiinfo.ipAddress;
168         printf("[udp server] local  addr:%s,port:%u\n", inet_ntoa(addr), ntohs(serv_addr.sin_port));
169 
170         /* 处理接收到的数据 */
171         udp_server_msg_handle(server_fd);
172         LOS_Msleep(SERVER_WAIT_MSEC);
173     }
174 }
175 
udp_client_msg_handle(int fd,struct sockaddr * dst)176 void udp_client_msg_handle(int fd, struct sockaddr* dst)
177 {
178     socklen_t len = sizeof(*dst);
179 
180     struct sockaddr_in client_addr;
181     int cnt = 0, count = 0;
182 
183     printf("[udp client] remote addr:%s port:%u\n", inet_ntoa(((struct sockaddr_in*)dst)->sin_addr),
184         ntohs(((struct sockaddr_in*)dst)->sin_port));
185     connect(fd, dst, len);
186     getsockname(fd, (struct sockaddr*)&client_addr, &len);
187     printf("[udp client] local  addr:%s port:%u\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
188 
189     while (1) {
190         char buf[BUFF_LEN];
191 
192         printf("[udp client]------------------------------------------------\n");
193         printf("[udp client] waitting server message!!!\n");
194 
195         /*
196          * recv接收来server的消息
197          * recvfrom是阻塞函数,没有数据就一直阻塞
198          */
199         count = recvfrom(fd, buf, BUFF_LEN, 0, (struct sockaddr*)&client_addr, &len);
200         if (count == -1) {
201             printf("[udp client] No server message!!!\n");
202         } else {
203             printf("[udp client] remote addr:%s port:%u\n",
204                 inet_ntoa(client_addr.sin_addr),
205                 ntohs(client_addr.sin_port));
206             printf("[udp client] rev:%s\n", buf);
207         }
208         memset(buf, 0, BUFF_LEN);
209         snprintf(buf, sizeof(buf), "UDP TEST cilent send:%d", ++cnt);
210         /* 发送数据给server */
211         count = sendto(fd, buf, strlen(buf), 0, (struct sockaddr*)&client_addr, len);
212         printf("[udp client] send:%s\n", buf);
213         printf("[udp client] client sendto msg to server %dbyte,waitting server respond msg!!!\n", count);
214 
215         LOS_Msleep(CLIENT_WAIT_MSEC);
216     }
217     lwip_close(fd);
218 }
219 
220 
wifi_udp_client(void)221 int wifi_udp_client(void)
222 {
223     int client_fd, ret;
224     struct sockaddr_in serv_addr, local_addr;
225 
226     while (1) {
227         client_fd = socket(AF_INET, SOCK_DGRAM, 0); // AF_INET:IPV4;SOCK_DGRAM:UDP
228         if (client_fd < 0) {
229             printf("create socket fail!\n");
230             return -1;
231         }
232 
233         /*
234          * 设置调用close(socket)后,仍可继续重用该socket。
235          * 调用close(socket)一般不会立即关闭socket,而经历TIME_WAIT的过程。
236          */
237         int flag = 1;
238         ret = setsockopt(client_fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int));
239         if (ret != 0) {
240             printf("[CommInitUdpServer]setsockopt fail, ret[%d]!\n", ret);
241             close(client_fd);
242             continue;
243         }
244 
245         memset(&local_addr, 0, sizeof(local_addr));
246         local_addr.sin_family = AF_INET;
247         local_addr.sin_addr.s_addr = wifiinfo.ipAddress;
248         local_addr.sin_port = htons(CLIENT_LOCAL_PORT);
249         /* 绑定本地ip端口号 */
250         ret = bind(client_fd, (struct sockaddr*)&local_addr, sizeof(local_addr));
251         if (ret == -1) {
252             printf("client bind failed(%d)\n", ret);
253             close(client_fd);
254             continue;
255         }
256 
257         memset(&serv_addr, 0, sizeof(serv_addr));
258         serv_addr.sin_family = AF_INET;
259         /* IP地址,需要进行网络序转换,INADDR_ANY:本地地址 */
260         serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
261         serv_addr.sin_port = htons(SERVER_PORT);
262         udp_client_msg_handle(client_fd, (struct sockaddr*)&serv_addr);
263 
264         LOS_Msleep(CLIENT_WAIT_MSEC);
265     }
266 
267     return 0;
268 }
269 
270 
wifi_udp_process(void)271 void wifi_udp_process(void)
272 {
273     unsigned int threadID_client, threadID_server;
274     unsigned int ret = LOS_OK;
275 
276     WifiLinkedInfo info;
277 
278     /* 开启WiFi连接任务 */
279     ExternalTaskConfigNetwork();
280     while (udp_get_wifi_info(&info) != 0) {
281         /* 等待,不做任何事情 */
282     }
283 
284     wifiinfo = info;
285     LOS_Msleep(WAIT_MSEC);
286 
287     CreateThread(&threadID_client,  wifi_udp_client, NULL, "udp client@ process");
288     CreateThread(&threadID_server,  wifi_udp_server, NULL, "udp server@ process");
289 }
290 
291 
wifi_udp_example(void)292 void wifi_udp_example(void)
293 {
294     unsigned int ret = LOS_OK;
295     unsigned int thread_id;
296     TSK_INIT_PARAM_S task = {0};
297 
298     task.pfnTaskEntry = (TSK_ENTRY_FUNC)wifi_udp_process;
299     task.uwStackSize = TASK_STACK_SIZE;
300     task.pcName = "wifi_process";
301     task.usTaskPrio = TASK_PRIO;
302     ret = LOS_TaskCreate(&thread_id, &task);
303     if (ret != LOS_OK) {
304         printf("Falied to create wifi_process ret:0x%x\n", ret);
305         return;
306     }
307 }
308 
309 
310 APP_FEATURE_INIT(wifi_udp_example);
311