• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
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  * Description: shell cmds APIs implementation about dhcps dhcp dns and so on.
15  * Author: none
16  * Create: 2020
17  */
18 
19 #include "lwip/nettool/misc.h"
20 #include "lwip/sntp.h"
21 #include "lwip/tftpc.h"
22 #include "lwip/dns.h"
23 #include "lwip/dhcp.h"
24 #include "lwip/sockets.h"
25 #include "lwip/netifapi.h"
26 #include "lwip/mld6.h"
27 #include "lwip/igmp.h"
28 #include "lwip/tcpip.h"
29 #include "lwip/init.h"
30 #include "lwip/nettool/utility.h"
31 #if LWIP_LITEOS_COMPAT
32 #include "los_config.h"
33 #endif
34 
35 #if LWIP_ENABLE_BASIC_SHELL_CMD
36 
37 #if LWIP_SNTP
38 u32_t
os_shell_ntpdate(int argc,const char ** argv)39 os_shell_ntpdate(int argc, const char **argv)
40 {
41   int server_num;
42   char *ret = NULL;
43   struct timeval get_time;
44 
45   (void)memset_s(&get_time, sizeof(struct timeval), 0, sizeof(struct timeval));
46 
47   if (tcpip_init_finish == 0) {
48     LWIP_PLATFORM_PRINT("%s: tcpip_init have not been called"CRLF, __FUNCTION__);
49     return OS_NOK;
50   }
51   if (argv == NULL) {
52     return OS_NOK;
53   }
54   if (argc < 1) {
55     goto usage;
56   }
57 
58   server_num = lwip_sntp_start(argc, (char **)argv, &get_time);
59   if (server_num >= 0 && server_num < argc) {
60     ret = ctime((time_t *)&get_time.tv_sec);
61     if (ret) {
62       LWIP_PLATFORM_PRINT("time server %s: %s"CRLF, argv[server_num], ret);
63     } else {
64       LWIP_PLATFORM_PRINT("ctime return null error"CRLF);
65     }
66   } else {
67     LWIP_PLATFORM_PRINT("no server suitable for synchronization found"CRLF);
68   }
69 
70   return OS_OK;
71 
72 usage:
73   LWIP_PLATFORM_PRINT("\nUsage:\n");
74   LWIP_PLATFORM_PRINT("ntpdate [SERVER_IP1] [SERVER_IP2] ..."CRLF);
75   return OS_NOK;
76 }
77 
78 #endif /* LWIP_SNTP */
79 
80 #if LWIP_TFTP
81 static char *tftp_error[] = {
82   "TFTP transfer finish"CRLF,
83   "Error while creating UDP socket"CRLF,
84   "Error while binding to the UDP socket"CRLF,
85   "Error returned by lwip_select() system call"CRLF,
86   "Error while receiving data from the peer"CRLF,
87   "Error while sending data to the peer"CRLF,
88   "Requested file is not found"CRLF,
89   "This is the error sent by the server when hostname cannot be resolved"CRLF,
90   "Input paramters passed to TFTP interfaces are invalid"CRLF,
91   "Error detected in TFTP packet or the error received from the TFTP server"CRLF,
92   "Error during packet synhronization while sending or unexpected packet is received"CRLF,
93   "File size limit crossed, Max block can be 0xFFFF, each block containing 512 bytes"CRLF,
94   "File name lenght greater than 256"CRLF,
95   "Hostname IP is not valid"CRLF,
96   "TFTP server returned file access error"CRLF,
97   "TFTP server returned error signifying that the DISK is full to write"CRLF,
98   "TFTP server returned error signifying that the file exist"CRLF,
99   "The source file name do not exisits"CRLF,
100   "Memory allocaion failed in TFTP client"CRLF,
101   "File open failed"CRLF,
102   "File read error"CRLF,
103   "File create error"CRLF,
104   "File write error"CRLF,
105   "Max time expired while waiting for file to be recived"CRLF,
106   "Error when the received packet is less than 4bytes(error lenght) or greater than 512bytes"CRLF,
107   "Returned by TFTP server for protocol user error"CRLF,
108   "The destination file path length greater than 256"CRLF,
109   "Returned by TFTP server for undefined transfer ID"CRLF,
110   "IOCTL fucntion failed at TFTP client while setting the socket to non-block"CRLF,
111 };
112 
113 static u32_t
tftp_invoke_operation(u8_t uc_tftp_get,u32_t ul_remote_addr,s8_t * sz_local_file_name,s8_t * sz_remote_file_name)114 tftp_invoke_operation(u8_t uc_tftp_get, u32_t ul_remote_addr, s8_t *sz_local_file_name, s8_t *sz_remote_file_name)
115 {
116   u16_t us_tftp_serv_port = 69;
117   u32_t ret;
118   if (sz_local_file_name == NULL || sz_remote_file_name == NULL) {
119     return OS_NOK;
120   }
121 
122   if (uc_tftp_get) {
123     ret = lwip_tftp_get_file_by_filename(ntohl(ul_remote_addr), us_tftp_serv_port,
124                                          TRANSFER_MODE_BINARY, sz_remote_file_name, sz_local_file_name);
125   } else {
126     ret = lwip_tftp_put_file_by_filename(ntohl(ul_remote_addr), us_tftp_serv_port,
127                                          TRANSFER_MODE_BINARY, sz_local_file_name, sz_remote_file_name);
128   }
129 
130   LWIP_ASSERT("TFTP UNKNOW ERROR!", ret < LWIP_ARRAYSIZE(tftp_error));
131   LWIP_PLATFORM_PRINT("%s", tftp_error[ret]);
132   if (ret) {
133     return OS_NOK;
134   } else {
135     return OS_OK;
136   }
137 }
138 
os_shell_tftp(int argc,const char ** argv)139 u32_t os_shell_tftp(int argc, const char **argv)
140 {
141   /* log off temporary for upgrade lwip to 2.0 */
142   u32_t  ul_remote_addr = IPADDR_NONE;
143   u8_t   uc_tftp_get = 0;
144   s8_t   *sz_local_file_name = NULL;
145   s8_t   *sz_remote_file_name = NULL;
146   int i = 0;
147   if (argv == NULL) {
148     return OS_NOK;
149   }
150   if (!tcpip_init_finish) {
151     LWIP_PLATFORM_PRINT("%s: tcpip_init have not been called"CRLF, __FUNCTION__);
152     return OS_NOK;
153   }
154 
155   while (i < argc) {
156     if (strcmp(argv[i], "-p") == 0) {
157       uc_tftp_get = 0;
158       i++;
159       continue;
160     }
161 
162     if (strcmp(argv[i], "-g") == 0) {
163       uc_tftp_get = 1;
164       i++;
165       continue;
166     }
167 
168     if (strcmp(argv[i], "-l") == 0 && ((i + 1) < argc)) {
169       sz_local_file_name = (s8_t *)argv[i + 1];
170       i += 2;
171       continue;
172     }
173 
174     if (strcmp(argv[i], "-r") == 0 && ((i + 1) < argc)) {
175       sz_remote_file_name = (s8_t *)argv[i + 1];
176       i += 2;
177       continue;
178     }
179 
180     if ((i + 1) == argc) {
181       ul_remote_addr = inet_addr(argv[i]);
182       break;
183     }
184 
185     goto usage;
186   }
187 
188   if (ul_remote_addr == IPADDR_NONE || sz_local_file_name == NULL || sz_remote_file_name == NULL) {
189     goto usage;
190   }
191 
192   return tftp_invoke_operation(uc_tftp_get, ul_remote_addr, sz_local_file_name, sz_remote_file_name);
193 
194 usage:
195   LWIP_PLATFORM_PRINT("usage:\nTransfer a file from/to tftp server"CRLF);
196   LWIP_PLATFORM_PRINT("tftp <-g/-p> -l FullPathLocalFile -r RemoteFile Host"CRLF);
197   return OS_NOK;
198 }
199 #endif /* LWIP_TFTP */
200 
201 #if LWIP_DNS
os_shell_show_dns(void)202 u32_t os_shell_show_dns(void)
203 {
204   ip_addr_t dns;
205   err_t err;
206   int i;
207 #ifdef CUSTOM_AT_COMMAND
208   (void)uapi_at_printf("+DNS:"CRLF);
209 #else
210   LWIP_PLATFORM_PRINT("+DNS:"CRLF);
211 #endif
212 
213   for (i = 0; i < DNS_MAX_SERVERS; i++) {
214     err = lwip_dns_getserver((u8_t)i, &dns);
215     if (err == ERR_OK) {
216       char buf[IPADDR_STRLEN_MAX];
217       (void)ipaddr_ntoa_r(&dns, buf, IPADDR_STRLEN_MAX);
218 #ifdef CUSTOM_AT_COMMAND
219       (void)uapi_at_printf("%s"CRLF, buf);
220 #else
221       LWIP_PLATFORM_PRINT("%s"CRLF, buf);
222 #endif
223     } else {
224       return OS_NOK;
225     }
226   }
227 #ifdef CUSTOM_AT_COMMAND
228   (void)uapi_at_printf("OK"CRLF);
229 #else
230   LWIP_PLATFORM_PRINT("OK"CRLF);
231 #endif
232   return OS_OK;
233 }
234 
235 u32_t
os_shell_dns(int argc,const char ** argv)236 os_shell_dns(int argc, const char **argv)
237 {
238   ip_addr_t dns;
239   err_t err;
240   int i;
241 
242   if (tcpip_init_finish == 0) {
243     PRINT_ERRCODE(API_SHELL_ERRCODE_TCPIP_UNINTED);
244     return OS_NOK;
245   }
246   if (argv == NULL) {
247     return OS_NOK;
248   }
249 
250   if(lwip_isdigitstr((s8_t *)argv[0]) != 0) {
251 #ifdef CUSTOM_AT_COMMAND
252     (void)uapi_at_printf("dns error parameter:%s"CRLF, argv[0]);
253 #else
254     LWIP_PLATFORM_PRINT("dns error parameter:%s"CRLF, argv[0]);
255 #endif
256     return OS_NOK;
257   }
258 
259   if ((argc == 1) && (strcmp(argv[0], "-a") == 0)) {
260     for (i = 0; i < DNS_MAX_SERVERS; i++) {
261       err = lwip_dns_getserver((u8_t)i, &dns);
262       if (err == ERR_OK) {
263         char buf[IPADDR_STRLEN_MAX];
264         (void)ipaddr_ntoa_r(&dns, buf, IPADDR_STRLEN_MAX);
265 #ifdef CUSTOM_AT_COMMAND
266         (void)uapi_at_printf("dns %d: %s"CRLF, i + 1, buf);
267 #else
268         LWIP_PLATFORM_PRINT("dns %d: %s"CRLF, i + 1, buf);
269 #endif
270       } else {
271 #ifdef CUSTOM_AT_COMMAND
272         (void)uapi_at_printf("dns: failed"CRLF);
273 #else
274         LWIP_PLATFORM_PRINT("dns: failed"CRLF);
275 #endif
276         return OS_NOK;
277       }
278     }
279 #ifdef CUSTOM_AT_COMMAND
280     (void)uapi_at_printf("OK"CRLF);
281 #endif
282     return OS_OK;
283   } else if (argc == 2) { /* 2 : current argc index */
284     i = atoi(argv[0]);
285     if ((i <= 0) || (i > DNS_MAX_SERVERS)) {
286       goto usage;
287     }
288 #if LWIP_IPV6
289     if (ip6addr_aton(argv[1], ((ip6_addr_t *)&dns))) {
290 #if LWIP_IPV4 && LWIP_IPV6
291       dns.type = IPADDR_TYPE_V6;
292 #endif
293 #ifdef LWIP_DNS_GLOBAL_ADDR
294       if (!ip6_addr_isglobal((ip6_addr_t *)&dns)) {
295 #ifdef CUSTOM_AT_COMMAND
296         (void)uapi_at_printf("ip address<%s> is wrong"CRLF, argv[1]);
297 #else
298         PRINT_ERRCODE(API_SHELL_ERRCODE_INVALID);
299 #endif
300         return OS_NOK;
301       }
302 #endif
303     } else
304 #endif
305     {
306 #if LWIP_IPV4
307       ((ip4_addr_t *)&dns)->addr = ipaddr_addr(argv[1]);
308       if (((ip4_addr_t *)&dns)->addr == IPADDR_NONE) {
309 #ifdef CUSTOM_AT_COMMAND
310         (void)uapi_at_printf("ip address<%s> is wrong"CRLF, argv[1]);
311 #else
312         PRINT_ERRCODE(API_SHELL_ERRCODE_INVALID);
313 #endif
314         return OS_NOK;
315       }
316 #if LWIP_IPV4 && LWIP_IPV6
317       dns.type = IPADDR_TYPE_V4;
318 #endif
319 #endif
320     }
321 
322     err = lwip_dns_setserver((u8_t)(i - 1), &dns);
323     if (err != ERR_OK) {
324 #ifdef CUSTOM_AT_COMMAND
325       (void)uapi_at_printf("dns : failed"CRLF);
326 #else
327       LWIP_PLATFORM_PRINT("dns : failed"CRLF);
328 #endif
329       return OS_NOK;
330     }
331 #ifdef CUSTOM_AT_COMMAND
332     (void)uapi_at_printf("OK"CRLF);
333 #endif
334     return OS_OK;
335   }
336 usage:
337 #ifndef CUSTOM_AT_COMMAND
338   LWIP_PLATFORM_PRINT("usage:"CRLF);
339   LWIP_PLATFORM_PRINT("\tdns <1-%d> <IP>"CRLF, DNS_MAX_SERVERS);
340   LWIP_PLATFORM_PRINT("\tdns -a"CRLF);
341 #endif
342   return OS_NOK;
343 }
344 #endif /* LWIP_DNS */
345 
346 #ifdef LWIP_TESTBED
347 extern void cmd_reset(void);
348 
os_shell_reboot(int argc,const char ** argv)349 void os_shell_reboot(int argc, const char **argv)
350 {
351   cmd_reset();
352 }
353 
354 #endif /* LWIP_TESTBED */
355 
356 #if LWIP_DHCP
357 err_t dhcp_idx_to_mac(const struct netif *netif, dhcp_num_t mac_idx, u8_t *hwaddr, u8_t *hwaddr_len);
358 static void
dhcp_client_info_show(struct dhcp_client * dhcp)359 dhcp_client_info_show(struct dhcp_client *dhcp)
360 {
361   ip4_addr_t cli_ip;
362   struct dhcp_state *dhcp_state = &((dhcp->states)[dhcp->cli_idx]);
363   char macaddr[MACADDR_BUF_LEN];
364   char *char_p = macaddr;
365   u8_t i;
366   u8_t state;
367   char buf[IP4ADDR_STRLEN_MAX];
368 
369   (void)memset_s(macaddr, sizeof(macaddr), 0, sizeof(macaddr));
370   for (i = 0; i < dhcp_state->hwaddr_len; i++) {
371     /* 2 : macaddr show in two hex */
372     (void)snprintf_s(char_p, (size_t)(MACADDR_BUF_LEN - 2 * i), (size_t)(MACADDR_BUF_LEN - 2 * i - 1),
373                      "%02x", dhcp->hwaddr[i]);
374     /* 2 : skip two index */
375     char_p = char_p + 2;
376   }
377   if (ip4_addr_isany_val(dhcp->relay_ip)) {
378     DHCP_HOST_TO_IP(cli_ip.addr, ip_2_ip4(&dhcp->server_ip_addr)->addr, dhcp->offered_sn_mask.addr,
379                     dhcp_state->offered_ip_addr);
380   } else {
381     DHCP_HOST_TO_IP(cli_ip.addr, dhcp->relay_ip.addr, dhcp->offered_sn_mask.addr,
382                     dhcp_state->offered_ip_addr);
383   }
384   state = dhcp_state->state;
385 
386   (void)ip4addr_ntoa_r(&cli_ip, buf, IP4ADDR_STRLEN_MAX);
387 #ifdef CUSTOM_AT_COMMAND
388   (void)uapi_at_printf("\t%-8"DHCP_NUM_F"%-16s%-16s%-8hhu%-8hu%-8hhu%-8hu"CRLF, dhcp_state->idx, macaddr,
389                      (dhcp_state->offered_ip_addr == 0) ? "0.0.0.0" : buf,
390                      state, dhcp_state->lease_used, dhcp_state->tries, dhcp_state->request_timeout);
391 #else
392   LWIP_PLATFORM_PRINT("\t%-8"DHCP_NUM_F"%-16s%-16s%-8hhu%-8hu%-8hhu%-8hu"CRLF, dhcp_state->idx, macaddr,
393                       (dhcp_state->offered_ip_addr == 0) ? "0.0.0.0" : buf,
394                       state, dhcp_state->lease_used, dhcp_state->tries, dhcp_state->request_timeout);
395 #endif
396 
397   return;
398 }
399 
400 void
dhcp_clients_info_show(struct netif * netif_p)401 dhcp_clients_info_show(struct netif *netif_p)
402 {
403   struct dhcp *netif_dhcp = NULL;
404   struct dhcp_client *dhcp = NULL;
405   struct dhcp_state *dhcp_state = NULL;
406   int i;
407   u8_t hwaddr_len;
408   char buf[IP4ADDR_STRLEN_MAX];
409 
410   if (netif_p == NULL) {
411     return;
412   }
413   netif_dhcp = netif_dhcp_data(netif_p);
414   if (netif_dhcp == NULL) {
415 #ifdef CUSTOM_AT_COMMAND
416     (void)uapi_at_printf("dhcpc not start on %s%hhu"CRLF, netif_p->name, netif_p->num);
417 #else
418     PRINT_ERRCODE(API_SHELL_ERRCODE_DEV_NOT_READY);
419 #endif
420     return;
421   }
422   dhcp = &(netif_dhcp->client);
423 #ifdef CUSTOM_AT_COMMAND
424   (void)uapi_at_printf("server :"CRLF);
425   (void)ip4addr_ntoa_r(ip_2_ip4(&(dhcp->server_ip_addr)), buf, IP4ADDR_STRLEN_MAX);
426   (void)uapi_at_printf("\tserver_id : %s"CRLF, buf);
427   (void)ip4addr_ntoa_r(&(dhcp->offered_sn_mask), buf, IP4ADDR_STRLEN_MAX);
428   (void)uapi_at_printf("\tmask : %s, %hhu"CRLF, buf, dhcp->subnet_mask_given);
429   (void)ip4addr_ntoa_r(&(dhcp->offered_gw_addr), buf, IP4ADDR_STRLEN_MAX);
430   (void)uapi_at_printf("\tgw : %s"CRLF, buf);
431   (void)uapi_at_printf("\tT0 : %u"CRLF, dhcp->offered_t0_lease);
432   (void)uapi_at_printf("\tT1 : %u"CRLF, dhcp->offered_t1_renew);
433   (void)uapi_at_printf("\tT2 : %u"CRLF, dhcp->offered_t2_rebind);
434 #else
435   LWIP_PLATFORM_PRINT("server :"CRLF);
436   (void)ip4addr_ntoa_r(ip_2_ip4(&(dhcp->server_ip_addr)), buf, IP4ADDR_STRLEN_MAX);
437   LWIP_PLATFORM_PRINT("\tserver_id : %s"CRLF, buf);
438   (void)ip4addr_ntoa_r(&(dhcp->offered_sn_mask), buf, IP4ADDR_STRLEN_MAX);
439   LWIP_PLATFORM_PRINT("\tmask : %s, %hhu"CRLF, buf, dhcp->subnet_mask_given);
440   (void)ip4addr_ntoa_r(&(dhcp->offered_gw_addr), buf, IP4ADDR_STRLEN_MAX);
441   LWIP_PLATFORM_PRINT("\tgw : %s"CRLF, buf);
442   LWIP_PLATFORM_PRINT("\tT0 : %u"CRLF, dhcp->offered_t0_lease);
443   LWIP_PLATFORM_PRINT("\tT1 : %u"CRLF, dhcp->offered_t1_renew);
444   LWIP_PLATFORM_PRINT("\tT2 : %u"CRLF, dhcp->offered_t2_rebind);
445 #endif
446   if (ip4_addr_isany_val(*ip_2_ip4(&dhcp->server_ip_addr))) {
447     return;
448   }
449 
450 #ifdef CUSTOM_AT_COMMAND
451   (void)uapi_at_printf("clients <%"DHCP_NUM_F"> :"CRLF, dhcp->cli_cnt);
452   (void)uapi_at_printf("\t%-8s%-16s%-16s%-8s%-8s%-8s%-8s"CRLF,
453                      "mac_idx", "mac", "addr", "state", "lease", "tries", "rto");
454 #else
455   LWIP_PLATFORM_PRINT("clients <%"DHCP_NUM_F"> :"CRLF, dhcp->cli_cnt);
456   LWIP_PLATFORM_PRINT("\t%-8s%-16s%-16s%-8s%-8s%-8s%-8s"CRLF,
457                       "mac_idx", "mac", "addr", "state", "lease", "tries", "rto");
458 #endif
459   for (i = 0; i < DHCP_CLIENT_NUM; i++) {
460     dhcp->cli_idx = (dhcp_num_t)i;
461     dhcp_state = &((dhcp->states)[i]);
462     if ((i != LWIP_DHCP_NATIVE_IDX) && (dhcp_state->idx == 0)) {
463       continue;
464     }
465     if (dhcp_idx_to_mac(netif_p, dhcp_state->idx, dhcp->hwaddr, &hwaddr_len) != ERR_OK) {
466 #ifdef CUSTOM_AT_COMMAND
467       (void)uapi_at_printf("<%d> idx %"DHCP_NUM_F" to mac failed"CRLF, i, dhcp_state->idx);
468 #else
469       LWIP_PLATFORM_PRINT("<%d> idx %"DHCP_NUM_F" to mac failed"CRLF, i, dhcp_state->idx);
470 #endif
471       continue;
472     }
473     dhcp_state->hwaddr_len = hwaddr_len;
474     dhcp_client_info_show(dhcp);
475   }
476 
477   return;
478 }
479 
480 u32_t
os_shell_dhcp(int argc,const char ** argv)481 os_shell_dhcp(int argc, const char **argv)
482 {
483   int ret = 0;
484   struct netif *netif_p = NULL;
485 
486   if (tcpip_init_finish == 0) {
487     PRINT_ERRCODE(API_SHELL_ERRCODE_TCPIP_UNINTED);
488     return OS_NOK;
489   }
490 
491   if ((argc != 2) || (argv == NULL)) { /* 2 : total argc num */
492     goto usage;
493   }
494 
495   netif_p = netif_find(argv[0]);
496   if (netif_p == NULL) {
497     PRINT_ERRCODE(API_SHELL_ERRCODE_DEV_NOT_FOUND);
498     goto usage;
499   }
500 #ifdef CUSTOM_AT_COMMAND
501   if (strcmp(argv[1], "1") == 0) {
502     ret = netifapi_dhcp_start(netif_p);
503   } else if (strcmp(argv[1], "0") == 0) {
504     ret = netifapi_dhcp_stop(netif_p);
505   } else {
506     goto usage;
507   }
508 #else
509   if (strcmp(argv[1], "start") == 0) {
510     ret = netifapi_dhcp_start(netif_p);
511   } else if (strcmp(argv[1], "stop") == 0) {
512     ret = netifapi_dhcp_stop(netif_p);
513   } else if (strcmp(argv[1], "inform") == 0) {
514     ret = netifapi_dhcp_inform(netif_p);
515   } else if (strcmp(argv[1], "renew") == 0) {
516     ret = netifapi_dhcp_renew(netif_p);
517   } else if (strcmp(argv[1], "release") == 0) {
518     ret = netifapi_dhcp_release(netif_p);
519   } else if (strcmp(argv[1], "show") == 0) {
520     ret = netifapi_netif_common(netif_p, dhcp_clients_info_show, NULL);
521   } else {
522     goto usage;
523   }
524 #endif
525   if (ret == OS_OK) {
526     LWIP_PLATFORM_PRINT("OK"CRLF);
527   }
528 
529   return (ret == 0) ? OS_OK : OS_NOK;
530 usage:
531 #ifndef CUSTOM_AT_COMMAND
532   LWIP_PLATFORM_PRINT("dhcp\n\tifname {start | stop | inform | renew | release | show}"CRLF);
533 #endif
534   return OS_NOK;
535 }
536 #endif /* LWIP_DHCP */
537 
538 #if (LWIP_IPV6 && (LWIP_IPV6_MLD || LWIP_IPV6_MLD_QUERIER))
539 static void
os_shell_mld6_usage(void)540 os_shell_mld6_usage(void)
541 {
542 #ifdef LWIP_DEBUG_OPEN
543   (void)uapi_at_printf("mld6\r\n\tshow\r\n\tifname {report | stop}\r\n\tifname {join | leave} groupaddr\r\n\t\
544                      ifname querier {start | stop | show}"CRLF);
545 #else
546   LWIP_PLATFORM_PRINT("mld6\n\tshow\n\tifname {report | stop}\n\tifname {join | leave} groupaddr\n\tifname querier \
547                       {start | stop | show}"CRLF);
548 #endif
549 }
550 
551 static void
mld6_netif_show(void)552 mld6_netif_show(void)
553 {
554   struct netif *netif_p = NULL;
555   struct mld_group *group = NULL;
556   char buf[IP6ADDR_STRLEN_MAX];
557 
558 #ifdef LWIP_DEBUG_OPEN
559   (void)uapi_at_printf("\t%-50s%-16s%-16s%-16s%-16s"CRLF, "groupaddr", "reporter", "state", "timer(100ms)", "use");
560 #else
561   LWIP_PLATFORM_PRINT("\t%-50s%-16s%-16s%-16s%-16s"CRLF, "groupaddr", "reporter", "state", "timer(100ms)", "use");
562 #endif
563   for (netif_p = netif_list; netif_p != NULL; netif_p = netif_p->next) {
564     if ((netif_p->flags & NETIF_FLAG_MLD6) == 0) {
565       continue;
566     }
567 #ifdef LWIP_DEBUG_OPEN
568     (void)uapi_at_printf("%s%hhu"CRLF, netif_p->name, netif_p->num);
569 #else
570     LWIP_PLATFORM_PRINT("%s%hhu"CRLF, netif_p->name, netif_p->num);
571 #endif
572     group = netif_mld6_data(netif_p);
573     if (group == NULL) {
574 #ifdef LWIP_DEBUG_OPEN
575       (void)uapi_at_printf(CRLF);
576 #else
577       LWIP_PLATFORM_PRINT("\n");
578 #endif
579       continue;
580     }
581     while (group != NULL) {
582       (void)ip6addr_ntoa_r(&(group->group_address), buf, IP6ADDR_STRLEN_MAX);
583 #ifdef LWIP_DEBUG_OPEN
584       (void)uapi_at_printf("\t%-50s%-16hhu%-16hhu%-16hu%-16hhu"CRLF, buf,
585                          group->last_reporter_flag, group->group_state,
586                          group->timer, group->use);
587 #else
588       LWIP_PLATFORM_PRINT("\t%-50s%-16hhu%-16hhu%-16hu%-16hhu"CRLF, buf,
589                           group->last_reporter_flag, group->group_state,
590                           group->timer, group->use);
591 #endif
592       group = group->next;
593     }
594   }
595 }
596 
597 static s32_t
mld6_netif_ctrl(const char ** argv)598 mld6_netif_ctrl(const char **argv)
599 {
600   s32_t ret = 0;
601   struct netif *netif_p = NULL;
602 
603   netif_p = netif_find(argv[0]);
604   if (netif_p == NULL) {
605     LWIP_PLATFORM_PRINT("no such netif named %s"CRLF, argv[0]);
606     goto usage;
607   }
608   if (strcmp(argv[1], "stop") == 0) {
609     ret = mld6_stop(netif_p);
610   } else if (strcmp(argv[1], "report") == 0) {
611     mld6_report_groups(netif_p);
612   } else {
613     goto usage;
614   }
615 
616   return ret;
617 usage:
618   os_shell_mld6_usage();
619   return -1;
620 }
621 
622 static s32_t
mld6_membership_ctrl(const char ** argv)623 mld6_membership_ctrl(const char **argv)
624 {
625   s32_t ret = 0;
626   struct netif *netif_p = NULL;
627   ip6_addr_t groupaddr = {0};
628 
629   if (!ip6addr_aton(argv[2], &(groupaddr))) {
630     LWIP_PLATFORM_PRINT("Invalid IPv6 Address : %s"CRLF, argv[2]);
631     goto usage;
632   }
633 
634   if (ip6_addr_isany_val(groupaddr) || ip6_addr_isnone_val(groupaddr) || !(ip6_addr_ismulticast(&groupaddr))) {
635     LWIP_PLATFORM_PRINT("invalid groupaddr %s"CRLF, argv[2]);
636     goto usage;
637   }
638   netif_p = netif_find(argv[0]);
639   if (netif_p == NULL) {
640     LWIP_PLATFORM_PRINT("no such netif named %s"CRLF, argv[0]);
641     goto usage;
642   }
643   if (strcmp(argv[1], "join") == 0) {
644     ret = mld6_joingroup_netif(netif_p, &groupaddr);
645   } else if (strcmp(argv[1], "leave") == 0) {
646     ret = mld6_leavegroup_netif(netif_p, &groupaddr);
647   } else {
648     goto usage;
649   }
650 
651   return ret;
652 usage:
653   os_shell_mld6_usage();
654   return -1;
655 }
656 
657 #if LWIP_IPV6_MLD_QUERIER
658 static void
mld6_querier_status_show(struct mld6_querier * querier)659 mld6_querier_status_show(struct mld6_querier *querier)
660 {
661   struct mld6_listener *listener = NULL;
662   char buf[IP6ADDR_STRLEN_MAX];
663 
664 #ifdef LWIP_DEBUG_OPEN
665   (void)uapi_at_printf("\t%-16s%-16s%-16s"CRLF, "state", "count", "timer");
666   (void)uapi_at_printf("\t%-16hhu%-16hhu%-16hu"CRLF, querier->querier_state, querier->query_count, querier->timer);
667   (void)uapi_at_printf("listeners:"CRLF);
668 #else
669   LWIP_PLATFORM_PRINT("\t%-16s%-16s%-16s"CRLF, "state", "count", "timer");
670   LWIP_PLATFORM_PRINT("\t%-16hhu%-16hhu%-16hu"CRLF, querier->querier_state, querier->query_count, querier->timer);
671   LWIP_PLATFORM_PRINT("listeners:"CRLF);
672 #endif
673 
674   if (querier->listeners != NULL) {
675 #ifdef LWIP_DEBUG_OPEN
676     (void)uapi_at_printf("\t%-50s%-16s%-16s%-16s%-16s"CRLF, "addr", "state", "count", "timer", "rexmt_timer");
677 #else
678     LWIP_PLATFORM_PRINT("\t%-50s%-16s%-16s%-16s%-16s"CRLF, "addr", "state", "count", "timer", "rexmt_timer");
679 #endif
680     listener = querier->listeners;
681     do {
682       (void)ip6addr_ntoa_r(&(listener->group_address), buf, IP6ADDR_STRLEN_MAX);
683 #ifdef LWIP_DEBUG_OPEN
684       (void)uapi_at_printf("\t%-50s%-16hhu%-16hhu%-16hu%-16hu"CRLF, buf,
685                          listener->state, listener->query_count, listener->timer, listener->rexmt_timer);
686 #else
687       LWIP_PLATFORM_PRINT("\t%-50s%-16hhu%-16hhu%-16hu%-16hu"CRLF, buf,
688                           listener->state, listener->query_count, listener->timer, listener->rexmt_timer);
689 #endif
690       listener = listener->next;
691     } while (listener != NULL);
692   }
693 
694   return;
695 }
696 #endif /* LWIP_IPV6_MLD_QUERIER */
697 
698 static s32_t
mld6_querier_ctrl(const char ** argv)699 mld6_querier_ctrl(const char **argv)
700 {
701 #if LWIP_IPV6_MLD_QUERIER
702   s32_t ret = 0;
703   struct netif *netif_p = NULL;
704   struct mld6_querier *querier = NULL;
705 
706   netif_p = netif_find(argv[0]);
707   if (netif_p == NULL) {
708     LWIP_PLATFORM_PRINT("no such netif named %s"CRLF, argv[0]);
709     goto usage;
710   }
711   if (strcmp(argv[2], "start") == 0) {
712     ret = mld6_querier_start(netif_p);
713   } else if (strcmp(argv[2], "stop") == 0) {
714     mld6_querier_stop(netif_p);
715   } else if (strcmp(argv[2], "show") == 0) {
716     querier = netif_mld6_querier_data(netif_p);
717     if (querier == NULL) {
718       LWIP_PLATFORM_PRINT("mld6 querier not start"CRLF);
719     } else {
720       mld6_querier_status_show(querier);
721     }
722   } else {
723     goto usage;
724   }
725 
726   return ret;
727 usage:
728   os_shell_mld6_usage();
729   return -1;
730 #else
731   (void)argv;
732   LWIP_PLATFORM_PRINT("mld6 querier not support"CRLF);
733   return -1;
734 #endif /* LWIP_IPV6_MLD_QUERIER */
735 }
736 
737 u32_t
os_shell_mld6(int argc,const char ** argv)738 os_shell_mld6(int argc, const char **argv)
739 {
740   s32_t ret = 0;
741 
742   if (tcpip_init_finish == 0) {
743 #ifdef LWIP_DEBUG_OPEN
744     (void)uapi_at_printf("%s: tcpip_init have not been called"CRLF, __FUNCTION__);
745 #else
746     LWIP_PLATFORM_PRINT("%s: tcpip_init have not been called"CRLF, __FUNCTION__);
747 #endif
748     return OS_NOK;
749   }
750   if (argv == NULL) {
751     return OS_NOK;
752   }
753   if ((argc == 1) && (strcmp(argv[0], "show") == 0)) {
754     mld6_netif_show();
755   } else if (argc == 2) { /* 2 : argc index */
756     ret = mld6_netif_ctrl(argv);
757   } else if (argc == 3) { /* 3 : argc index */
758     if (strcmp(argv[1], "querier") == 0) {
759       ret = mld6_querier_ctrl(argv);
760     } else {
761       ret = mld6_membership_ctrl(argv);
762     }
763   } else {
764     os_shell_mld6_usage();
765   }
766 #ifdef LWIP_DEBUG_OPEN
767   (void)uapi_at_printf("mld6 ret %d"CRLF, ret);
768 #else
769   LWIP_PLATFORM_PRINT("mld6 ret %d"CRLF, ret);
770 #endif
771   return OS_OK;
772 }
773 
774 #endif /* (LWIP_IPV6 && (LWIP_IPV6_MLD || LWIP_IPV6_MLD_QUERIER)) */
775 
776 #if LWIP_IPV4 && LWIP_IGMP
777 static void
os_shell_igmp_usage(void)778 os_shell_igmp_usage(void)
779 {
780   LWIP_PLATFORM_PRINT("igmp\tshow\tifname {start | stop | report}\t{ifname | ifaddr} {join | leave} groupaddr"CRLF);
781 }
782 
783 static void
igmp_netif_show(void)784 igmp_netif_show(void)
785 {
786   struct netif *netif_p = NULL;
787   struct igmp_group *igmp_group_p = NULL;
788   char buf[IP4ADDR_STRLEN_MAX];
789 #ifdef LWIP_DEBUG_OPEN
790   (void)uapi_at_printf("\t%-16s%-16s%-16s%-16s%-16s"CRLF, "groupaddr", "reporter", "state", "timer(100ms)", "use");
791 #else
792   LWIP_PLATFORM_PRINT("\t%-16s%-16s%-16s%-16s%-16s"CRLF, "groupaddr", "reporter", "state", "timer(100ms)", "use");
793 #endif
794   for (netif_p = netif_list; netif_p != NULL; netif_p = netif_p->next) {
795     if ((netif_p->flags & NETIF_FLAG_IGMP) == 0) {
796       continue;
797     }
798 #ifdef LWIP_DEBUG_OPEN
799     (void)uapi_at_printf("%s%d"CRLF, netif_p->name, netif_p->num);
800 #else
801     LWIP_PLATFORM_PRINT("%s%d"CRLF, netif_p->name, netif_p->num);
802 #endif
803     igmp_group_p = netif_igmp_data(netif_p);
804     if (igmp_group_p == NULL) {
805 #ifdef LWIP_DEBUG_OPEN
806       (void)uapi_at_printf(CRLF);
807 #else
808       LWIP_PLATFORM_PRINT(CRLF);
809 #endif
810       continue;
811     }
812     while (igmp_group_p != NULL) {
813       (void)ip4addr_ntoa_r(&(igmp_group_p->group_address), buf, IP4ADDR_STRLEN_MAX);
814 #ifdef LWIP_DEBUG_OPEN
815       (void)uapi_at_printf("\t%-16s%-16hhu%-16hhu%-16hu%-16hhu"CRLF, buf,
816                          igmp_group_p->last_reporter_flag, igmp_group_p->group_state,
817                          igmp_group_p->timer, igmp_group_p->use);
818 #else
819       LWIP_PLATFORM_PRINT("\t%-16s%-16hhu%-16hhu%-16hu%-16hhu"CRLF, buf,
820                           igmp_group_p->last_reporter_flag, igmp_group_p->group_state,
821                           igmp_group_p->timer, igmp_group_p->use);
822 #endif
823       igmp_group_p = igmp_group_p->next;
824     }
825   }
826 }
827 
828 static s32_t
igmp_netif_control(const char ** argv)829 igmp_netif_control(const char **argv)
830 {
831   s32_t ret = 0;
832   struct netif *netif_p = NULL;
833 
834   netif_p = netif_find(argv[0]);
835   if (netif_p == NULL) {
836 #ifdef LWIP_DEBUG_OPEN
837     (void)uapi_at_printf("no such netif named %s"CRLF, argv[0]);
838 #else
839     LWIP_PLATFORM_PRINT("no such netif named %s"CRLF, argv[0]);
840 #endif
841     goto usage;
842   }
843   if (strcmp(argv[1], "start") == 0) {
844     ret = igmp_start(netif_p);
845   } else if (strcmp(argv[1], "stop") == 0) {
846     ret = igmp_stop(netif_p);
847   } else if (strcmp(argv[1], "report") == 0) {
848     igmp_report_groups(netif_p);
849   } else {
850     goto usage;
851   }
852 
853   return ret;
854 usage:
855   os_shell_igmp_usage();
856   return -1;
857 }
858 
859 static s32_t
igmp_membership_netif_ctrl(struct netif * netif_p,ip4_addr_t groupaddr,const char ** argv)860 igmp_membership_netif_ctrl(struct netif *netif_p,
861                            ip4_addr_t groupaddr, const char **argv)
862 {
863   s32_t ret;
864 
865   if (strcmp(argv[1], "join") == 0) {
866     ret = igmp_joingroup_netif(netif_p, &groupaddr);
867   } else if (strcmp(argv[1], "leave") == 0) {
868     ret = igmp_leavegroup_netif(netif_p, &groupaddr);
869   } else {
870     ret = -1;
871     os_shell_igmp_usage();
872   }
873 
874   return ret;
875 }
876 
877 static s32_t
igmp_membership_addr_ctrl(ip4_addr_t groupaddr,const char ** argv)878 igmp_membership_addr_ctrl(ip4_addr_t groupaddr,
879                           const char **argv)
880 {
881   s32_t ret = 0;
882   ip4_addr_t ifaddr = {0};
883 
884   ifaddr.addr = inet_addr(argv[0]);
885   if (ifaddr.addr == IPADDR_NONE) {
886     goto usage;
887   }
888   if (strcmp(argv[1], "join") == 0) {
889     ret = igmp_joingroup(&ifaddr, &groupaddr);
890   } else if (strcmp(argv[1], "leave") == 0) {
891     ret = igmp_leavegroup(&ifaddr, &groupaddr);
892   } else {
893     goto usage;
894   }
895 
896   return ret;
897 usage:
898   os_shell_igmp_usage();
899   return -1;
900 }
901 
902 static s32_t
igmp_membership_ctrl(const char ** argv)903 igmp_membership_ctrl(const char **argv)
904 {
905   s32_t ret;
906   struct netif *netif_p = NULL;
907   ip4_addr_t groupaddr = {0};
908 
909   groupaddr.addr = inet_addr(argv[2]);
910   if ((groupaddr.addr == IPADDR_NONE) || !(ip4_addr_ismulticast(&groupaddr))) {
911 #ifdef LWIP_DEBUG_OPEN
912     (void)uapi_at_printf("invalid groupaddr %s"CRLF, argv[2]); // 2 is cast addr
913 #else
914     LWIP_PLATFORM_PRINT("invalid groupaddr %s"CRLF, argv[2]); // 2 is cast addr
915 #endif
916     os_shell_igmp_usage();
917     return -1;
918   }
919   netif_p = netif_find(argv[0]);
920   if (netif_p == NULL) {
921     ret = igmp_membership_addr_ctrl(groupaddr, argv);
922   } else {
923     ret = igmp_membership_netif_ctrl(netif_p, groupaddr, argv);
924   }
925 
926   return ret;
927 }
928 
929 u32_t
os_shell_igmp(int argc,const char ** argv)930 os_shell_igmp(int argc, const char **argv)
931 {
932   s32_t ret = 0;
933 
934   if (tcpip_init_finish == 0) {
935 #ifdef LWIP_DEBUG_OPEN
936     (void)uapi_at_printf("%s: tcpip_init have not been called"CRLF, __FUNCTION__);
937 #else
938     LWIP_PLATFORM_PRINT("%s: tcpip_init have not been called"CRLF, __FUNCTION__);
939 #endif
940     return OS_NOK;
941   }
942   if (argv == NULL) {
943     return OS_NOK;
944   }
945   LOCK_TCPIP_CORE();
946   if ((argc == 1) && (strcmp(argv[0], "show") == 0)) {
947     igmp_netif_show();
948   } else if (argc == 2) {
949     ret = igmp_netif_control(argv);
950   } else if (argc == 3) {
951     ret = igmp_membership_ctrl(argv);
952   } else {
953     os_shell_igmp_usage();
954   }
955   UNLOCK_TCPIP_CORE();
956 #ifdef LWIP_DEBUG_OPEN
957   (void)uapi_at_printf("igmp ret %d"CRLF, ret);
958 #else
959   LWIP_PLATFORM_PRINT("igmp ret %d"CRLF, ret);
960 #endif
961   return OS_OK;
962 }
963 
964 u32_t
at_os_shell_igmp(int argc,const char ** argv)965 at_os_shell_igmp(int argc, const char **argv)
966 {
967   u32_t ret = os_shell_igmp(argc, argv);
968 
969   return ret;
970 }
971 
972 #endif /* LWIP_IPV4 && LWIP_IGMP */
973 
974 #ifdef LWIP_DEBUG_TCPSERVER
975 
976 #define MAX_SIZE 1024
977 void
tcp_access(int sockfd)978 tcp_access(int sockfd)
979 {
980   size_t n, i;
981   ssize_t ret;
982   char msg[MAX_SIZE] = {0};
983   while (1) {
984     LWIP_PLATFORM_PRINT("waiting for recv"CRLF);
985     (void)memset_s(msg, MAX_SIZE, 0, MAX_SIZE);
986     ret = recv(sockfd, msg, MAX_SIZE - 1, 0);
987     if (ret < 0) {
988       LWIP_PLATFORM_PRINT("recv failed errno = %d "CRLF, errno);
989       (void)closesocket(sockfd);
990       return;
991     } else if (ret == 0) {
992       (void)closesocket(sockfd);
993       LWIP_PLATFORM_PRINT("client disconnect."CRLF);
994       return;
995     }
996 
997     n = strlen(msg);
998     for (i = 0; i < n; ++i) {
999       if ((msg[i] >= 'a') && (msg[i] <= 'z')) {
1000         msg[i] = (char)(msg[i] + ('A' - 'a'));
1001       } else if ((msg[i] >= 'A') && (msg[i] <= 'Z')) {
1002         msg[i] = (char)(msg[i] + ('a' - 'A'));
1003       }
1004     }
1005 
1006     if (send(sockfd, msg, n, 0) < 0) {
1007       LWIP_PLATFORM_PRINT("send failed!"CRLF);
1008       continue;
1009     }
1010   }
1011 }
1012 
1013 u32_t
os_tcpserver(int argc,const char ** argv)1014 os_tcpserver(int argc, const char **argv)
1015 {
1016   uint16_t port;
1017   int sockfd = -1;
1018   int ret;
1019   struct sockaddr_in seraddr;
1020   struct sockaddr_in cliaddr;
1021   u32_t cliaddr_size = (u32_t)sizeof(cliaddr);
1022   int reuse, i_port_val;
1023 
1024   if (tcpip_init_finish == 0) {
1025     LWIP_PLATFORM_PRINT("tcpip_init have not been called"CRLF);
1026     return OS_NOK;
1027   }
1028 
1029   if (argc < 1) {
1030     LWIP_PLATFORM_PRINT(CRLF"Usage: tcpserver <port>"CRLF);
1031     return OS_NOK;
1032   }
1033 
1034   i_port_val = atoi(argv[0]);
1035   /* Port 0 not supported , negative values not supported , max port limit is 65535 */
1036   if (i_port_val <= 0 || i_port_val > 65535) {
1037     LWIP_PLATFORM_PRINT(CRLF"Usage: Invalid port"CRLF);
1038     return OS_NOK;
1039   }
1040 
1041   port = (uint16_t)i_port_val;
1042 
1043   /*
1044    * removed the print of argv[1] as its accessing argv[1] without verifying argc and argv[1] not used anywhere else
1045    */
1046   LWIP_PLATFORM_PRINT("argv[0]:%s, argc:%d, port:%d"CRLF, argv[0], argc, port);
1047   sockfd = socket(AF_INET, SOCK_STREAM, 0);
1048   reuse = 1;
1049   if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
1050                  (const char *)&reuse, sizeof(reuse)) != 0) {
1051     LWIP_PLATFORM_PRINT("set SO_REUSEADDR failed errno = %d"CRLF, errno);
1052     (void)closesocket(sockfd);
1053     return OS_NOK;
1054   }
1055 
1056   (void)memset_s(&seraddr, sizeof(seraddr), 0, sizeof(seraddr));
1057   seraddr.sin_family = AF_INET;
1058   seraddr.sin_addr.s_addr = htonl(INADDR_ANY);
1059   seraddr.sin_port = htons(port);
1060 
1061   ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
1062   if (ret < 0) {
1063     LWIP_PLATFORM_PRINT("bind ip and port failed errno = %d", errno);
1064     (void)closesocket(sockfd);
1065     return OS_NOK;
1066   }
1067 
1068   ret = listen(sockfd, 5); /* 5 : max tcp listen backlog queue */
1069   if (ret < 0) {
1070     LWIP_PLATFORM_PRINT("listen failed errno = %d"CRLF, errno);
1071     (void)closesocket(sockfd);
1072     return OS_NOK;
1073   }
1074   while (1) {
1075     LWIP_PLATFORM_PRINT("waiting for accept"CRLF);
1076     (void)memset_s(&cliaddr, sizeof(struct sockaddr_in), 0, sizeof(struct sockaddr_in));
1077     ret = (int)accept(sockfd, (struct sockaddr *)&cliaddr, &cliaddr_size);
1078     if (ret < 0) {
1079       LWIP_PLATFORM_PRINT("Accept failed errno = %d"CRLF, errno);
1080       (void)closesocket(sockfd);
1081       break;
1082     }
1083     tcp_access(ret);
1084   }
1085   return OS_NOK;            // Hits Only If Accept Fails
1086 }
1087 #endif /* LWIP_DEBUG_TCPSERVER */
1088 
1089 #ifdef LWIP_DEBUG_UDPSERVER
udpserver(int argc,const char ** argv)1090 u32_t udpserver(int argc, const char **argv)
1091 {
1092   int sockfd = -1;
1093   int ret, i_port_val, fromlen;
1094   struct sockaddr_in seraddr;
1095   struct sockaddr_in cliaddr;
1096   size_t n, i;
1097 
1098   char msg[MAX_SIZE];
1099   uint16_t port;
1100   if (argv == NULL) {
1101     return OS_NOK;
1102   }
1103   if (argc < 1) {
1104     LWIP_PLATFORM_PRINT(CRLF"Usage: udpserver <port>"CRLF);
1105     return OS_NOK;
1106   }
1107 
1108   i_port_val = atoi(argv[0]);
1109   /* Port 0 not supported , negative values not supported , max port limit is 65535 */
1110   if ((i_port_val <= 0) || (i_port_val > 65535)) {
1111     LWIP_PLATFORM_PRINT(CRLF"Usage: Invalid Port"CRLF);
1112     return OS_NOK;
1113   }
1114 
1115   port = (uint16_t)i_port_val;
1116 
1117   LWIP_PLATFORM_PRINT("port:%d"CRLF, port);
1118 
1119   sockfd = lwip_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
1120 
1121   (void)memset_s(&seraddr, sizeof(seraddr), 0, sizeof(seraddr));
1122   (void)memset_s(&cliaddr, sizeof(cliaddr), 0, sizeof(cliaddr));
1123   seraddr.sin_family = AF_INET;
1124   seraddr.sin_addr.s_addr = htonl(INADDR_ANY);
1125   seraddr.sin_port = htons(port);
1126   ret = lwip_bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
1127   if (ret < 0) {
1128     LWIP_PLATFORM_PRINT("bind ip and port failed:%d"CRLF, errno);
1129     (void)closesocket(sockfd);
1130     return OS_NOK;
1131   }
1132 
1133   fromlen = (int)sizeof(cliaddr);
1134   while (1) {
1135     ret = recvfrom(sockfd, msg, MAX_SIZE - 1, 0, (struct sockaddr *)&cliaddr, (socklen_t *)&fromlen);
1136     if (ret < 0) {
1137       if ((errno == EAGAIN) || (errno == EINTR)) {
1138         continue;
1139       } else {
1140         break;
1141       }
1142     }
1143     n = strlen(msg);
1144     for (i = 0; i < n; ++i) {
1145       if (msg[i] >= 'a' && msg[i] <= 'z') {
1146         msg[i] = (char)(msg[i] + 'A' - 'a');
1147       } else if (msg[i] >= 'A' && msg[i] <= 'Z') {
1148         msg[i] = (char)(msg[i] + 'a' - 'A');
1149       }
1150     }
1151     ret = sendto(sockfd, msg, n + 1, 0, (struct sockaddr *)&cliaddr, (socklen_t)fromlen);
1152     if ((ret <= 0) && (errno == EPIPE)) {
1153       break;
1154     }
1155   }
1156 
1157   (void)closesocket(sockfd);
1158   return OS_NOK;
1159 }
1160 #endif /* LWIP_DEBUG_UDPSERVER */
1161 
1162 #if LWIP_DHCPS
1163 static void
dhcps_info_show(struct netif * netif)1164 dhcps_info_show(struct netif *netif)
1165 {
1166   struct dhcps *dhcps = NULL;
1167   struct dyn_lease_addr *lease = NULL;
1168   u8_t i, j;
1169   int k = 0;
1170   ip4_addr_t addr;
1171   char buf[IP4ADDR_STRLEN_MAX];
1172 
1173   /* netif is ensured not to be NULL by the caller */
1174   LWIP_ASSERT("netif is NULL!", netif != NULL);
1175 
1176   dhcps = netif->dhcps;
1177 
1178   if ((dhcps == NULL) || (dhcps->pcb == NULL)) {
1179 #ifdef CUSTOM_AT_COMMAND
1180     (void)uapi_at_printf("dhcps of %s%hhu not start\r\n", netif->name, netif->num);
1181 #else
1182     PRINT_ERRCODE(API_SHELL_ERRCODE_DEV_NOT_READY);
1183 #endif
1184     return;
1185   }
1186   addr.addr = lwip_htonl(dhcps->start_addr.addr);
1187   (void)ip4addr_ntoa_r(&addr, buf, IP4ADDR_STRLEN_MAX);
1188 #ifdef CUSTOM_AT_COMMAND
1189   (void)uapi_at_printf("start ip : %s"CRLF, buf);
1190 #else
1191   LWIP_PLATFORM_PRINT("start ip : %s"CRLF, buf);
1192 #endif
1193   addr.addr = lwip_htonl(dhcps->end_addr.addr);
1194   (void)ip4addr_ntoa_r(&addr, buf, IP4ADDR_STRLEN_MAX);
1195 #ifdef CUSTOM_AT_COMMAND
1196   (void)uapi_at_printf("end ip : %s"CRLF, buf);
1197   (void)uapi_at_printf("lease num %hhu"CRLF, dhcps->lease_num);
1198   (void)uapi_at_printf("sys_now %u"CRLF, sys_now());
1199 #else
1200   LWIP_PLATFORM_PRINT("end ip : %s"CRLF, buf);
1201   LWIP_PLATFORM_PRINT("lease num %hhu"CRLF, dhcps->lease_num);
1202   LWIP_PLATFORM_PRINT("sys_now %u"CRLF, sys_now());
1203 #endif
1204 
1205   for (i = 0; i < dhcps->lease_num; i++) {
1206     if (dhcps->leasearr[i].flags != 0) {
1207       lease = &(dhcps->leasearr[i]);
1208 #ifdef CUSTOM_AT_COMMAND
1209       (void)uapi_at_printf("%d : ", k++);
1210 #else
1211       LWIP_PLATFORM_PRINT("%d : ", k++);
1212 #endif
1213       for (j = 0; j < NETIF_MAX_HWADDR_LEN; j++) {
1214 #ifdef CUSTOM_AT_COMMAND
1215         (void)uapi_at_printf("%02x", lease->cli_hwaddr[j]);
1216 #else
1217         LWIP_PLATFORM_PRINT("%02x", lease->cli_hwaddr[j]);
1218 #endif
1219       }
1220       addr.addr = lwip_htonl(lease->cli_addr.addr);
1221       (void)ip4addr_ntoa_r(&addr, buf, IP4ADDR_STRLEN_MAX);
1222 #ifdef CUSTOM_AT_COMMAND
1223       (void)uapi_at_printf(" %s leasetime = %u(%u), proposed_leasetime = %u"CRLF, buf, lease->leasetime,
1224                          (lease->leasetime - sys_now()) / US_PER_MSECOND, lease->proposed_leasetime);
1225 #else
1226       LWIP_PLATFORM_PRINT(" %s leasetime = %u(%u), proposed_leasetime = %u"CRLF, buf, lease->leasetime,
1227                           (lease->leasetime - sys_now()) / US_PER_MSECOND, lease->proposed_leasetime);
1228 #endif
1229     }
1230   }
1231 }
1232 
1233 u32_t
os_shell_dhcps(int argc,const char ** argv)1234 os_shell_dhcps(int argc, const char **argv)
1235 {
1236   int ret = 0;
1237   struct netif *netif_p = NULL;
1238 
1239   if (tcpip_init_finish == 0) {
1240     PRINT_ERRCODE(API_SHELL_ERRCODE_TCPIP_UNINTED);
1241     return OS_NOK;
1242   }
1243 
1244   if ((argc != 2) || (argv == NULL)) { /* 2 : totol argc num */
1245     goto usage;
1246   }
1247 
1248   netif_p = netif_find(argv[0]);
1249   if (netif_p == NULL) {
1250     PRINT_ERRCODE(API_SHELL_ERRCODE_DEV_NOT_FOUND);
1251     goto usage;
1252   }
1253 #ifdef CUSTOM_AT_COMMAND
1254   if (strcmp(argv[1], "1") == 0) {
1255     ret = netifapi_dhcps_start(netif_p, NULL, 0);
1256   } else if (strcmp(argv[1], "0") == 0) {
1257     ret = netifapi_dhcps_stop(netif_p);
1258   } else {
1259     goto usage;
1260   }
1261 #else
1262   if (strcmp(argv[1], "start") == 0) {
1263     ret = netifapi_dhcps_start(netif_p, NULL, 0);
1264   } else if (strcmp(argv[1], "stop") == 0) {
1265     ret = netifapi_dhcps_stop(netif_p);
1266   } else if (strcmp(argv[1], "show") == 0) {
1267     ret = netifapi_netif_common(netif_p, dhcps_info_show, NULL);
1268   } else {
1269     goto usage;
1270   }
1271 #endif
1272   if (ret == OS_OK) {
1273     LWIP_PLATFORM_PRINT("OK"CRLF);
1274   }
1275 
1276   return (ret == 0) ? OS_OK : OS_NOK;
1277 usage:
1278 #ifndef CUSTOM_AT_COMMAND
1279   LWIP_PLATFORM_PRINT("dhcps\n\tifname {start | stop | show}"CRLF);
1280 #endif
1281   return OS_NOK;
1282 }
1283 #endif /* LWIP_DHCPS */
1284 
1285 
1286 void ifup_internal(void *arg);
1287 void ifdown_internal(void *arg);
1288 
1289 struct if_cmd_data {
1290   char *if_name;
1291   err_t err;
1292   sys_sem_t cb_completed;
1293 };
1294 
ifup_internal(void * arg)1295 void ifup_internal(void *arg)
1296 {
1297   struct netif *netif = NULL;
1298   struct if_cmd_data *ifcmd_data = NULL;
1299 
1300   ifcmd_data = (struct if_cmd_data *)arg;
1301   netif = netif_find(ifcmd_data->if_name);
1302   if (netif == NULL) {
1303     ifcmd_data->err = ERR_VAL;
1304   } else {
1305     (void)netif_set_up(netif);
1306     ifcmd_data->err = ERR_OK;
1307   }
1308 
1309   sys_sem_signal(&ifcmd_data->cb_completed);
1310   return;
1311 }
1312 
ifdown_internal(void * arg)1313 void ifdown_internal(void *arg)
1314 {
1315   struct netif *netif = NULL;
1316   struct if_cmd_data *ifcmd_data = NULL;
1317 
1318   ifcmd_data = (struct if_cmd_data *)arg;
1319   netif = netif_find(ifcmd_data->if_name);
1320   if (netif == NULL) {
1321     ifcmd_data->err = ERR_VAL;
1322   } else {
1323     (void)netif_set_down(netif);
1324     ifcmd_data->err = ERR_OK;
1325   }
1326 
1327   sys_sem_signal(&ifcmd_data->cb_completed);
1328   return;
1329 }
1330 
1331 #endif /* LWIP_ENABLE_BASIC_SHELL_CMD */
1332