K2.6 patches and update.
[tomato.git] / release / src-rt / wl / exe / wlu_linux.c
blob2bee69686f08d1f9b0644f8e9b7e7d5c2f79ab9f
1 /*
2 * Linux port of wl command line utility
4 * Copyright (C) 2010, Broadcom Corporation
5 * All Rights Reserved.
6 *
7 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
8 * the contents of this file may not be disclosed to third parties, copied
9 * or duplicated in any form, in whole or in part, without the prior
10 * written permission of Broadcom Corporation.
12 * $Id: wlu_linux.c,v 1.53 2010-02-03 06:58:43 Exp $
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <unistd.h>
17 #include <ctype.h>
18 #include <string.h>
19 #include <errno.h>
20 #ifndef TARGETENV_android
21 #include <error.h>
22 #endif /* TARGETENV_android */
23 #include <sys/types.h>
24 #include <sys/socket.h>
25 #include <arpa/inet.h>
26 #include <sys/ioctl.h>
27 #include <net/if.h>
28 #include <proto/ethernet.h>
29 #include <proto/bcmip.h>
31 #ifndef TARGETENV_android
32 typedef u_int64_t u64;
33 typedef u_int32_t u32;
34 typedef u_int16_t u16;
35 typedef u_int8_t u8;
36 typedef u_int64_t __u64;
37 typedef u_int32_t __u32;
38 typedef u_int16_t __u16;
39 typedef u_int8_t __u8;
40 #endif /* TARGETENV_android */
42 #include <linux/sockios.h>
43 #include <linux/ethtool.h>
44 #include <signal.h>
45 #include <typedefs.h>
46 #include <wlioctl.h>
47 #include <bcmutils.h>
48 #include <sys/wait.h>
49 #include <netdb.h>
50 #include <netinet/in.h>
51 #include "wlu.h"
52 #include <bcmcdc.h>
53 #include "wlu_remote.h"
54 #include "wlu_client_shared.h"
55 #include "wlu_pipe.h"
56 #include <miniopt.h>
58 #define DEV_TYPE_LEN 3 /* length for devtype 'wl'/'et' */
59 #define INTERACTIVE_NUM_ARGS 15
60 #define INTERACTIVE_MAX_INPUT_LENGTH 256
61 #define NO_ERROR 0
62 #define RWL_WIFI_JOIN_DELAY 5
64 /* Function prototypes */
65 static cmd_t *wl_find_cmd(char* name);
66 static int do_interactive(struct ifreq *ifr);
67 static int wl_do_cmd(struct ifreq *ifr, char **argv);
68 int process_args(struct ifreq* ifr, char **argv);
69 extern int g_child_pid;
70 /* RemoteWL declarations */
71 int remote_type = NO_REMOTE;
72 int rwl_os_type = LINUX_OS;
73 extern char *g_rwl_buf_mac;
74 extern char* g_rwl_device_name_serial;
75 unsigned short g_rwl_servport;
76 char *g_rwl_servIP = NULL;
77 unsigned short defined_debug = DEBUG_ERR | DEBUG_INFO;
78 static uint interactive_flag = 0;
79 extern char *remote_vista_cmds[];
80 extern char g_rem_ifname[IFNAMSIZ];
81 static void
82 syserr(char *s)
84 fprintf(stderr, "%s: ", wlu_av0);
85 perror(s);
86 exit(errno);
89 int
90 wl_ioctl(void *wl, int cmd, void *buf, int len, bool set)
92 struct ifreq *ifr = (struct ifreq *) wl;
93 wl_ioctl_t ioc;
94 int ret = 0;
95 int s;
97 /* open socket to kernel */
98 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
99 syserr("socket");
101 /* do it */
102 ioc.cmd = cmd;
103 ioc.buf = buf;
104 ioc.len = len;
105 ioc.set = set;
106 ifr->ifr_data = (caddr_t) &ioc;
107 if ((ret = ioctl(s, SIOCDEVPRIVATE, ifr)) < 0) {
108 if (cmd != WLC_GET_MAGIC) {
109 ret = IOCTL_ERROR;
113 /* cleanup */
114 close(s);
115 return ret;
118 static int
119 wl_get_dev_type(char *name, void *buf, int len)
121 int s;
122 int ret;
123 struct ifreq ifr;
124 struct ethtool_drvinfo info;
126 /* open socket to kernel */
127 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
128 syserr("socket");
130 /* get device type */
131 memset(&info, 0, sizeof(info));
132 info.cmd = ETHTOOL_GDRVINFO;
133 ifr.ifr_data = (caddr_t)&info;
134 strncpy(ifr.ifr_name, name, IFNAMSIZ);
135 if ((ret = ioctl(s, SIOCETHTOOL, &ifr)) < 0) {
137 /* print a good diagnostic if not superuser */
138 if (errno == EPERM)
139 syserr("wl_get_dev_type");
141 *(char *)buf = '\0';
142 } else {
143 strncpy(buf, info.driver, len);
146 close(s);
147 return ret;
150 static int
151 wl_find(struct ifreq *ifr)
153 char proc_net_dev[] = "/proc/net/dev";
154 FILE *fp;
155 char buf[1000], *c, *name;
156 char dev_type[DEV_TYPE_LEN];
157 int status;
159 ifr->ifr_name[0] = '\0';
161 if (!(fp = fopen(proc_net_dev, "r")))
162 return BCME_ERROR;
164 /* eat first two lines */
165 if (!fgets(buf, sizeof(buf), fp) ||
166 !fgets(buf, sizeof(buf), fp)) {
167 fclose(fp);
168 return BCME_ERROR;
171 while (fgets(buf, sizeof(buf), fp)) {
172 c = buf;
173 while (isspace(*c))
174 c++;
175 if (!(name = strsep(&c, ":")))
176 continue;
177 strncpy(ifr->ifr_name, name, IFNAMSIZ);
178 if (wl_get_dev_type(name, dev_type, DEV_TYPE_LEN) >= 0 &&
179 !strncmp(dev_type, "wl", 2))
180 if (wl_check((void *) ifr) == 0)
181 break;
182 ifr->ifr_name[0] = '\0';
184 if (ifr->ifr_name[0] == '\0')
185 status = BCME_ERROR;
186 else
187 status = BCME_OK;
189 fclose(fp);
190 return status;
194 static int
195 ioctl_queryinformation_fe(void *wl, int cmd, void* input_buf, int *input_len)
197 int error = NO_ERROR;
199 if (remote_type == NO_REMOTE) {
200 error = wl_ioctl(wl, cmd, input_buf, *input_len, FALSE);
201 } else {
202 error = rwl_queryinformation_fe(wl, cmd, input_buf,
203 (unsigned long*)input_len, 0, REMOTE_GET_IOCTL);
206 return error;
209 static int
210 ioctl_setinformation_fe(void *wl, int cmd, void* buf, int *len)
212 int error = 0;
214 if (remote_type == NO_REMOTE) {
215 error = wl_ioctl(wl, cmd, buf, *len, TRUE);
216 } else {
217 error = rwl_setinformation_fe(wl, cmd, buf,
218 (unsigned long*)len, 0, REMOTE_SET_IOCTL);
221 return error;
225 wl_get(void *wl, int cmd, void *buf, int len)
227 int error = 0;
228 /* For RWL: When interfacing to a Windows client, need t add in OID_BASE */
229 error = (int)ioctl_queryinformation_fe(wl, cmd, buf, &len);
231 if (error == SERIAL_PORT_ERR)
232 return SERIAL_PORT_ERR;
233 else if (error == BCME_NODEVICE)
234 return BCME_NODEVICE;
235 else if (error != 0)
236 return IOCTL_ERROR;
238 return 0;
242 wl_set(void *wl, int cmd, void *buf, int len)
244 int error = 0;
246 /* For RWL: When interfacing to a Windows client, need t add in OID_BASE */
247 error = (int)ioctl_setinformation_fe(wl, cmd, buf, &len);
249 if (error == SERIAL_PORT_ERR)
250 return SERIAL_PORT_ERR;
251 else if (error == BCME_NODEVICE)
252 return BCME_NODEVICE;
253 else if (error != 0)
254 return IOCTL_ERROR;
256 return 0;
259 #if defined(WLMSO)
260 int wl_os_type_get_rwl()
262 return rwl_os_type;
265 void wl_os_type_set_rwl(int os_type)
267 rwl_os_type = os_type;
270 int wl_ir_init_rwl(void **irh)
272 switch (rwl_get_remote_type()) {
273 case NO_REMOTE:
274 case REMOTE_WIFI: {
275 struct ifreq *ifr;
276 ifr = malloc(sizeof(struct ifreq));
277 if (ifr) {
278 memset(ifr, 0, sizeof(ifr));
279 wl_find(ifr);
281 *irh = ifr;
283 break;
284 default:
285 break;
288 return 0;
291 void wl_close_rwl(int remote_type, void *irh)
293 switch (remote_type) {
294 case NO_REMOTE:
295 case REMOTE_WIFI:
296 free(irh);
297 break;
298 default:
299 break;
303 #define LINUX_NUM_ARGS 16
305 static int
306 buf_to_args(char *tmp, char *new_args[])
308 char line[256];
309 char *token;
310 int argc = 0;
312 strcpy(line, tmp);
313 while ((argc < (LINUX_NUM_ARGS - 1)) &&
314 ((token = strtok(argc ? NULL : line, " \t")) != NULL)) {
315 new_args[argc] = malloc(strlen(token)+1);
316 strncpy(new_args[argc], token, strlen(token)+1);
317 argc++;
319 new_args[argc] = NULL;
320 return argc;
324 wl_lib(char *input_str)
326 struct ifreq ifr;
327 char *ifname = NULL;
328 int err = 0;
329 int help = 0;
330 int status = CMD_WL;
331 void* serialHandle = NULL;
332 char *tmp_argv[LINUX_NUM_ARGS];
333 char **argv = tmp_argv;
334 int argc;
336 if ((argc = buf_to_args(input_str, argv)) <= 0) {
337 printf("wl: can't convert input string\n");
338 return (-1);
340 #else
341 /* Main client function */
343 main(int argc, char **argv)
345 struct ifreq ifr;
346 char *ifname = NULL;
347 int err = 0;
348 int help = 0;
349 int status = CMD_WL;
350 #if defined(RWL_DONGLE) || RWL_SERIAL
351 void* serialHandle = NULL;
352 #endif
354 #endif /* WLMSO */
355 wlu_av0 = argv[0];
357 wlu_init();
358 memset(&ifr, 0, sizeof(ifr));
359 (void)*argv++;
361 if ((status = wl_option(&argv, &ifname, &help)) == CMD_OPT) {
362 if (ifname)
363 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
366 /* Linux client looking for a indongle/Win Vista server */
368 /* Linux client looking for a indongle reflector */
369 if (*argv && strncmp (*argv, "--indongle", strlen(*argv)) == 0) {
370 (void)*argv++;
372 /* Linux client looking for a WinVista server */
373 if (*argv && strncmp (*argv, "--vista", strlen(*argv)) == 0) {
374 rwl_os_type = WINVISTA_OS;
375 (void)*argv++;
378 /* RWL socket transport Usage: --socket ipaddr/hostname [port num] */
379 if (*argv && strncmp (*argv, "--socket", strlen(*argv)) == 0) {
380 (void)*argv++;
382 remote_type = REMOTE_SOCKET;
384 if (!(*argv)) {
385 rwl_usage(remote_type);
386 return err;
388 /* IP address validation is done in client_shared file */
389 g_rwl_servIP = *argv;
390 (void)*argv++;
392 g_rwl_servport = DEFAULT_SERVER_PORT;
393 if ((*argv) && isdigit(**argv)) {
394 g_rwl_servport = atoi(*argv);
395 (void)*argv++;
399 /* RWL from system serial port on client to uart serial port on server */
400 /* Usage: --serial /dev/ttyS0 */
401 if (*argv && strncmp (*argv, "--serial", strlen(*argv)) == 0) {
402 (void)*argv++;
403 remote_type = REMOTE_SERIAL;
406 /* RWL from system serial port on client to uart dongle port on server */
407 /* Usage: --dongle /dev/ttyS0 */
408 if (*argv && strncmp (*argv, "--dongle", strlen(*argv)) == 0) {
409 (void)*argv++;
410 remote_type = REMOTE_DONGLE;
413 #if defined(RWL_SERIAL) || defined(RWL_DONGLE)
414 if (remote_type == REMOTE_SERIAL || remote_type == REMOTE_DONGLE) {
415 if (!(*argv)) {
416 rwl_usage(remote_type);
417 return err;
419 g_rwl_device_name_serial = *argv;
420 (void)*argv++;
421 if ((serialHandle = rwl_open_pipe(remote_type, g_rwl_device_name_serial, 0, 0))
422 == NULL) {
423 DPRINT_ERR(ERR, "serial device open error\r\n");
424 return -1;
426 ifr = (*(struct ifreq *)serialHandle);
428 #endif /* RWL_SERIAL */
430 /* RWL over wifi. Usage: --wifi mac_address */
431 if (*argv && strncmp (*argv, "--wifi", strlen(*argv)) == 0) {
432 (void)*argv++;
433 /* use default interface */
434 if (!*ifr.ifr_name)
435 wl_find(&ifr);
436 /* validate the interface */
437 if (!*ifr.ifr_name || wl_check((void*)&ifr)) {
438 fprintf(stderr, "%s: wl driver adapter not found\n", wlu_av0);
439 exit(1);
441 remote_type = REMOTE_WIFI;
443 if (argc < 4) {
444 rwl_usage(remote_type);
445 return err;
447 /* copy server mac address to local buffer for later use by findserver cmd */
448 if (!wl_ether_atoe(*argv, (struct ether_addr *)g_rwl_buf_mac)) {
449 fprintf(stderr,
450 "could not parse as an ethternet MAC address\n");
451 return FAIL;
453 (void)*argv++;
456 if ((*argv) && (strlen(*argv) > 2) &&
457 (strncmp(*argv, "--interactive", strlen(*argv)) == 0)) {
458 interactive_flag = 1;
461 /* Process for local wl */
462 if (remote_type == NO_REMOTE) {
463 if (interactive_flag == 1)
464 (void)*argv--;
465 err = process_args(&ifr, argv);
466 return err;
469 if (interactive_flag == 1) {
470 err = do_interactive(&ifr);
471 return err;
474 if ((*argv) && (interactive_flag == 0)) {
475 err = process_args(&ifr, argv);
476 if ((err == SERIAL_PORT_ERR) && (remote_type == REMOTE_DONGLE)) {
477 DPRINT_ERR(ERR, "\n Retry again\n");
478 err = process_args((struct ifreq*)&ifr, argv);
480 return err;
482 rwl_usage(remote_type);
483 #if defined(RWL_DONGLE) || RWL_SERIAL
484 if (remote_type == REMOTE_DONGLE || remote_type == REMOTE_SERIAL)
485 rwl_close_pipe(remote_type, (void*)&ifr);
486 #endif /* RWL_DONGLE || RWL_SERIAL */
487 return err;
491 * Function called for 'local' execution and for 'remote' non-interactive session
492 * (shell cmd, wl cmd)
495 process_args(struct ifreq* ifr, char **argv)
497 char *ifname = NULL;
498 int help = 0;
499 int status = 0;
500 int vista_cmd_index;
501 int err = 0;
502 cmd_t *cmd = NULL;
503 #ifdef RWL_WIFI
504 int retry;
505 #endif
507 while (*argv) {
508 if ((strcmp (*argv, "sh") == 0) && (remote_type != NO_REMOTE)) {
509 (void)*argv++; /* Get the shell command */
510 if (*argv) {
511 /* Register handler in case of shell command only */
512 err = rwl_shell_cmd_proc((void*)ifr, argv, SHELL_CMD);
513 } else {
514 DPRINT_ERR(ERR, "Enter the shell "
515 "command, e.g. ls(Linux) or dir(Win CE)\n");
516 err = -1;
518 return err;
521 #ifdef RWLASD
522 if ((strcmp (*argv, "asd") == 0) && (remote_type != NO_REMOTE)) {
523 (void)*argv++; /* Get the asd command */
524 if (*argv) {
525 err = rwl_shell_cmd_proc((void*)ifr, argv, ASD_CMD);
526 } else {
527 DPRINT_ERR(ERR, "Enter the ASD command, e.g. ca_get_version\n");
528 err = -1;
530 return err;
532 #endif
533 if (rwl_os_type == WINVISTA_OS) {
534 for (vista_cmd_index = 0; remote_vista_cmds[vista_cmd_index] &&
535 strcmp(remote_vista_cmds[vista_cmd_index], *argv);
536 vista_cmd_index++);
537 if (remote_vista_cmds[vista_cmd_index] != NULL) {
538 err = rwl_shell_cmd_proc((void *)ifr, argv, VISTA_CMD);
539 if ((remote_type == REMOTE_WIFI) && ((!strcmp(*argv, "join")))) {
540 #ifdef RWL_WIFI
541 DPRINT_INFO(OUTPUT,
542 "\nChannel will be synchronized by Findserver\n\n");
543 sleep(RWL_WIFI_JOIN_DELAY);
544 for (retry = 0; retry < RWL_WIFI_RETRY; retry++) {
545 if ((rwl_find_remote_wifi_server(ifr,
546 &g_rwl_buf_mac[0]) == 0)) {
547 break;
550 #endif /* RWL_WIFI */
552 return err;
556 if ((status = wl_option(&argv, &ifname, &help)) == CMD_OPT) {
557 if (help)
558 break;
559 if (ifname) {
560 if (remote_type == NO_REMOTE) {
561 strncpy((*ifr).ifr_name, ifname, IFNAMSIZ);
563 else {
564 strncpy(g_rem_ifname, ifname, IFNAMSIZ);
567 continue;
569 /* parse error */
570 else if (status == CMD_ERR)
571 break;
573 if (remote_type == NO_REMOTE) {
574 /* use default interface */
575 if (!*(*ifr).ifr_name)
576 wl_find(ifr);
577 /* validate the interface */
578 if (!*(*ifr).ifr_name || wl_check((void *)ifr)) {
579 fprintf(stderr, "%s: wl driver adapter not found\n", wlu_av0);
580 exit(1);
583 if ((strcmp (*argv, "--interactive") == 0) || (interactive_flag == 1)) {
584 err = do_interactive(ifr);
585 return err;
588 /* search for command */
589 cmd = wl_find_cmd(*argv);
590 /* if not found, use default set_var and get_var commands */
591 if (!cmd) {
592 cmd = &wl_varcmd;
594 #ifdef RWL_WIFI
595 if (!strcmp(cmd->name, "findserver")) {
596 remote_wifi_ser_init_cmds((void *) ifr);
598 #endif /* RWL_WIFI */
600 /* RWL over Wifi supports 'lchannel' command which lets client
601 * (ie *this* machine) change channels since normal 'channel' command
602 * applies to the server (ie target machine)
604 if (remote_type == REMOTE_WIFI) {
605 #ifdef RWL_WIFI
606 if (!strcmp(argv[0], "lchannel")) {
607 strcpy(argv[0], "channel");
608 rwl_wifi_swap_remote_type(remote_type);
609 err = (*cmd->func)((void *) ifr, cmd, argv);
610 rwl_wifi_swap_remote_type(remote_type);
611 } else {
612 err = (*cmd->func)((void *) ifr, cmd, argv);
614 /* After join cmd's gets exeuted on the server side , client needs to know
615 * the channel on which the server is associated with AP , after delay of
616 * few seconds client will intiate the scan on diffrent channels by calling
617 * rwl_find_remote_wifi_server fucntion
619 if ((!strcmp(cmd->name, "join") || ((!strcmp(cmd->name, "ssid") &&
620 (*(++argv) != NULL))))) {
621 DPRINT_INFO(OUTPUT, "\n Findserver is called to synchronize the"
622 "channel\n\n");
623 sleep(RWL_WIFI_JOIN_DELAY);
624 for (retry = 0; retry < RWL_WIFI_RETRY; retry++) {
625 if ((rwl_find_remote_wifi_server(ifr,
626 &g_rwl_buf_mac[0]) == 0)) {
627 break;
631 #endif /* RWL_WIFI */
632 } else {
633 /* do command */
634 err = (*cmd->func)((void *) ifr, cmd, argv);
636 break;
637 } /* while loop end */
639 /* provide for help on a particular command */
640 if (help && *argv) {
641 cmd = wl_find_cmd(*argv);
642 if (cmd) {
643 wl_cmd_usage(stdout, cmd);
644 } else {
645 DPRINT_ERR(ERR, "%s: Unrecognized command \"%s\", type -h for help\n",
646 wlu_av0, *argv);
648 } else if (!cmd)
649 wl_usage(stdout, NULL);
650 else if (err == USAGE_ERROR)
651 wl_cmd_usage(stderr, cmd);
652 else if (err == IOCTL_ERROR)
653 wl_printlasterror((void *) ifr);
654 else if (err == BCME_NODEVICE)
655 DPRINT_ERR(ERR, "%s : wl driver adapter not found\n", g_rem_ifname);
657 return err;
660 /* Function called for 'local' interactive session and for 'remote' interactive session */
661 static int
662 do_interactive(struct ifreq *ifr)
664 int err = 0;
666 #ifdef RWL_WIFI
667 int retry;
668 #endif
670 while (1) {
671 char *fgsret;
672 char line[INTERACTIVE_MAX_INPUT_LENGTH];
673 fprintf(stdout, "> ");
674 fgsret = fgets(line, sizeof(line), stdin);
676 /* end of file */
677 if (fgsret == NULL)
678 break;
679 if (line[0] == '\n')
680 continue;
682 if (strlen (line) > 0) {
683 /* skip past first arg if it's "wl" and parse up arguments */
684 char *argv[INTERACTIVE_NUM_ARGS];
685 int argc;
686 char *token;
687 argc = 0;
689 while ((argc < (INTERACTIVE_NUM_ARGS - 1)) &&
690 ((token = strtok(argc ? NULL : line, " \t\n")) != NULL)) {
692 /* Specifically make sure empty arguments (like SSID) are empty */
693 if (token[0] == '"' && token[1] == '"') {
694 token[0] = '\0';
697 argv[argc++] = token;
699 argv[argc] = NULL;
700 #ifdef RWL_WIFI
701 if (!strcmp(argv[0], "findserver")) {
702 remote_wifi_ser_init_cmds((void *) ifr);
704 #endif /* RWL_WIFI */
706 if (strcmp(argv[0], "q") == 0 || strcmp(argv[0], "exit") == 0) {
707 break;
710 if ((strcmp(argv[0], "sh") == 0) && (remote_type != NO_REMOTE)) {
711 if (argv[1]) {
712 process_args(ifr, argv);
713 } else {
714 DPRINT_ERR(ERR, "Give shell command");
715 continue;
717 } else { /* end shell */
718 /* check for lchannel support,applicable only for wifi transport.
719 * when lchannel is called remote type is swapped by calling swap_
720 * remote_type.This is done to change, the remote type to local,
721 * so that local machine's channel can be executed and
722 * returned to the user.
723 * To get back the original remote type, swap is recalled.
725 if (remote_type == REMOTE_WIFI) {
726 #ifdef RWL_WIFI
727 if (!strcmp(argv[0], "lchannel")) {
728 strcpy(argv[0], "channel");
729 rwl_wifi_swap_remote_type(remote_type);
730 err = wl_do_cmd(ifr, argv);
731 rwl_wifi_swap_remote_type(remote_type);
732 } else {
733 err = wl_do_cmd(ifr, argv);
735 /* After join cmd's gets exeuted on the server side, client
736 * needs to know the channel on which the server is associated
737 * with AP , after delay of few seconds client will intiate the
738 * scan on diffrent channels by calling
739 * rwl_find_remote_wifi_server function
741 if ((!strcmp(argv[0], "join")) ||
742 (!strcmp(argv[0], "ssid"))) {
743 DPRINT_INFO(OUTPUT, "\n Findserver is called"
744 "after the join issued to remote \n \n");
745 sleep(RWL_WIFI_JOIN_DELAY);
746 for (retry = 0; retry < RWL_WIFI_RETRY; retry++) {
747 if ((rwl_find_remote_wifi_server(ifr,
748 &g_rwl_buf_mac[0]) == 0)) {
749 break;
753 #endif /* RWL_WIFI */
754 } else {
755 err = wl_do_cmd(ifr, argv);
757 } /* end of wl */
758 } /* end of strlen (line) > 0 */
759 } /* while (1) */
761 return err;
765 * find command in argv and execute it
766 * Won't handle changing ifname yet, expects that to happen with the --interactive
767 * Return an error if unable to find/execute command
769 static int
770 wl_do_cmd(struct ifreq *ifr, char **argv)
772 cmd_t *cmd = NULL;
773 int err = 0;
774 int help = 0;
775 char *ifname = NULL;
776 int status = CMD_WL;
778 /* skip over 'wl' if it's there */
779 if (*argv && strcmp (*argv, "wl") == 0) {
780 argv++;
783 /* handle help or interface name changes */
784 if (*argv && (status = wl_option (&argv, &ifname, &help)) == CMD_OPT) {
785 if (ifname) {
786 fprintf(stderr,
787 "Interface name change not allowed within --interactive\n");
791 /* in case wl_option eats all the args */
792 if (!*argv) {
793 return err;
796 if (status != CMD_ERR) {
797 /* search for command */
798 cmd = wl_find_cmd(*argv);
800 /* defaults to using the set_var and get_var commands */
801 if (!cmd) {
802 cmd = &wl_varcmd;
804 /* do command */
805 err = (*cmd->func)((void *)ifr, cmd, argv);
807 /* provide for help on a particular command */
808 if (help && *argv) {
809 cmd = wl_find_cmd(*argv);
810 if (cmd) {
811 wl_cmd_usage(stdout, cmd);
812 } else {
813 DPRINT_ERR(ERR, "%s: Unrecognized command \"%s\", type -h for help\n",
814 wlu_av0, *argv);
816 } else if (!cmd)
817 wl_usage(stdout, NULL);
818 else if (err == USAGE_ERROR)
819 wl_cmd_usage(stderr, cmd);
820 else if (err == IOCTL_ERROR)
821 wl_printlasterror((void *)ifr);
822 else if (err == BCME_NODEVICE)
823 DPRINT_ERR(ERR, "%s : wl driver adapter not found\n", g_rem_ifname);
825 return err;
828 /* Search the wl_cmds table for a matching command name.
829 * Return the matching command or NULL if no match found.
831 static cmd_t *
832 wl_find_cmd(char* name)
834 cmd_t *cmd = NULL;
836 /* search the wl_cmds for a matching name */
837 for (cmd = wl_cmds; cmd->name && strcmp(cmd->name, name); cmd++);
839 if (cmd->name == NULL)
840 cmd = NULL;
842 return cmd;
845 void def_handler(int signum)
847 UNUSED_PARAMETER(signum);
848 kill(g_child_pid, SIGINT);
849 kill(getpid(), SIGINT);
850 exit(0);
852 /* Create a child that waits for Ctrl-C at the client side
854 int rwl_shell_createproc(void *wl)
856 UNUSED_PARAMETER(wl);
857 signal(SIGINT, ctrlc_handler);
858 signal(SIGTERM, def_handler);
859 signal(SIGABRT, def_handler);
860 return fork();
863 /* In case if the server shell command exits normally
864 * then kill the thread that was waiting for Ctr-C to happen
865 * at the client side
867 void rwl_shell_killproc(int pid)
869 kill(pid, SIGKILL);
870 signal(SIGINT, SIG_DFL);
871 wait(NULL);
873 #ifdef RWL_SOCKET
874 /* to validate hostname/ip given by the client */
875 int validate_server_address()
877 struct hostent *he;
878 struct ipv4_addr temp;
879 if (!wl_atoip(g_rwl_servIP, &temp)) {
880 /* Wrong IP address format check for hostname */
881 if ((he = gethostbyname(g_rwl_servIP)) != NULL) {
882 if (!wl_atoip(*he->h_addr_list, &temp)) {
883 g_rwl_servIP =
884 inet_ntoa(*(struct in_addr *)*he->h_addr_list);
885 if (g_rwl_servIP == NULL) {
886 DPRINT_ERR(ERR, "Error at inet_ntoa \n");
887 return FAIL;
889 } else {
890 DPRINT_ERR(ERR, "Error in IP address \n");
891 return FAIL;
893 } else {
894 DPRINT_ERR(ERR, "Enter correct IP address/hostname format\n");
895 return FAIL;
898 return SUCCESS;
900 #endif /* RWL_SOCKET */