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