/* Search and verify the request type of adapter (wl or dhd) * This is called by main before executing local dhd commands * or sending remote dhd commands over wifi transport */ void dhd_find(struct ifreq *ifr, char *type) { char proc_net_dev[] = "/proc/net/dev"; FILE *fp; static char buf[400]; char *c, *name; char dev_type[32]; ifr->ifr_name[0] = '\0'; /* eat first two lines */ if (!(fp = fopen(proc_net_dev, "r")) || !fgets(buf, sizeof(buf), fp) || !fgets(buf, sizeof(buf), fp)) return; while (fgets(buf, sizeof(buf), fp)) { c = buf; while (isspace(*c)) c++; if (!(name = strsep(&c, ":"))) continue; strncpy(ifr->ifr_name, name, IFNAMSIZ); if (dhd_get_dev_type(name, dev_type, type) >= 0 && !strncmp(dev_type, type, strlen(dev_type) - 1)) { if (!wl_check((void*)ifr)) break; } ifr->ifr_name[0] = '\0'; } fclose(fp); }
int wl_validatedev(void *dev_handle) { int retval = 1; struct ifreq *ifr = (struct ifreq *)dev_handle; /* validate the interface */ if (!ifr->ifr_name || wl_check((void *)ifr)) { retval = 0; } return retval; }
static int wl_find(struct ifreq *ifr) { char proc_net_dev[] = "/proc/net/dev"; FILE *fp; char buf[1000], *c, *name; char dev_type[DEV_TYPE_LEN]; int status; ifr->ifr_name[0] = '\0'; if (!(fp = fopen(proc_net_dev, "r"))) return BCME_ERROR; /* eat first two lines */ if (!fgets(buf, sizeof(buf), fp) || !fgets(buf, sizeof(buf), fp)) { fclose(fp); return BCME_ERROR; } while (fgets(buf, sizeof(buf), fp)) { c = buf; while (isspace(*c)) c++; if (!(name = strsep(&c, ":"))) continue; strncpy(ifr->ifr_name, name, IFNAMSIZ); if (wl_get_dev_type(name, dev_type, DEV_TYPE_LEN) >= 0 && !strncmp(dev_type, "wl", 2)) if (wl_check((void *) ifr) == 0) break; ifr->ifr_name[0] = '\0'; } if (ifr->ifr_name[0] == '\0') status = BCME_ERROR; else status = BCME_OK; fclose(fp); return status; }
/* Main server module common for all transports * This module will do the initial transport setups. * Then it receives the command from client in CDC format * and transmits the response back to the client. * In the case of socket, it receives the command from the client * and sends the response directly to the client via TCP socket. * * In the case of serial & wifi , it receives the command from the driver * and sends the response to the driver. */ int remote_server_exec(int argc, char **argv, void *wl) { int err; int transport_descriptor; char *async_cmd_flag = NULL; int skip; int download_flag = 0; #if defined(LINUX) || defined(vxworks) || defined(OLYMPIC_RWL) char old_intf_name[IFNAMSIZ]; #endif #ifdef WIN32 char shell_fname[MAX_SHELL_FILE_LENGTH]; DWORD dwlen; #endif #ifdef RWL_DONGLE int uart_enable = 1; /* To set dongle flag when dongle server starts */ if ((err = rwl_var_setbuf(wl, dongleset, &uart_enable, sizeof(int))) < 0) { DPRINT_INFO(OUTPUT, "Unable to send to wl driver,error=%d\n", err); } #endif if (rwl_iovar_check (wl) < 0) { DPRINT_ERR(ERR, "wl_server: RWL_WIFI/RWL_DONGLE not defined "); DPRINT_ERR(ERR, "Or In-Dongle mode enabled\n"); exit(0); } /* Initialise for all the transports - socket, serial, and wifi * In Socket transport, main socket handler will be returned. */ if ((transport_descriptor = rwl_transport_setup(argc, argv)) < 0) return BCME_ERROR; #ifdef RWL_WIFI remote_wifi_ser_init_cmds(wl); #endif /* Create a directory /tmp/RWL for the shell response files */ if (rwl_create_dir() < 0) return BCME_ERROR; #ifdef RWLASD /* DUT initialization function */ wfa_dut_init(&trafficBuf, &respBuf, &parmsVal, &xcCmdBuf, &toutvalp); #endif #if defined(LINUX) || defined(vxworks) /* Copy old interface name to restore it */ store_old_interface(wl, old_intf_name); #endif /* defined(LINUX) || defined(vxworks) */ while (1) { uchar *buf_ptr = NULL; #ifdef VISTA_SERVER int index; char *vista_buf[MAX_VISTA_ARGC]; #endif #ifdef RWL_SERIAL g_rwl_hndle = transport_descriptor; #else g_rwl_hndle = -1; #endif #ifdef RWL_DONGLE if (set_ctrlc) { uart_enable = 0; if ((err = rwl_var_setbuf(wl, dongleset, &uart_enable, sizeof(int))) < 0) { DPRINT_INFO(OUTPUT, "Unable to send to wl driver,error=%d\n", err); } set_ctrlc = 0; exit(0); } #endif /* RWL_DONGLE */ /* Receive the CDC header */ if ((remote_rx_header(wl, transport_descriptor)) == BCME_ERROR) { DPRINT_DBG(OUTPUT, "\n Waiting for client to transmit command\n"); continue; } DPRINT_INFO(OUTPUT, "REC : cmd %d\t msg len %d msg flag %d\t msg status %d\n", g_rem_ptr->msg.cmd, g_rem_ptr->msg.len, g_rem_ptr->msg.flags, g_rem_ptr->msg.status); #ifdef RWL_WIFI /* send the response to remote if it is findserver cmd, this is specific to wifi */ if (g_rem_ptr->msg.flags & REMOTE_FINDSERVER_IOCTL) { remote_wifi_response(wl); continue; } #endif /* RWL_WIFI */ /* * Allocate buffer only if there is a response message expected. * Some commands such as up/down do not output anything. */ if (g_rem_ptr->msg.len) { if ((buf_ptr = malloc(g_rem_ptr->msg.len)) == NULL) { DPRINT_ERR(ERR, "malloc of %d bytes failed\n", g_rem_ptr->msg.len); continue; } } /* Receive the data */ if ((err = remote_rx_data(buf_ptr)) == BCME_ERROR) { if (buf_ptr) free(buf_ptr); continue; } /* Process RWL negotiate commands */ if (g_rem_ptr->msg.flags & REMOTE_NEGOTIATE_CMD) { if (g_rem_ptr->msg.cmd == NEGOTIATE_GET_OS) { if (g_rem_ptr->msg.len >= sizeof(int)) { #if defined(LINUX) *(int*)buf_ptr = LINUX_OS; #elif defined(VISTA_SERVER) *(int*)buf_ptr = WINVISTA_OS; #elif defined(WIN32) *(int*)buf_ptr = WIN32_OS; #elif defined(MACOSX) *(int*)buf_ptr = MAC_OSX; #else *(int*)buf_ptr = UNKNOWN_OS; #endif g_rem_ptr->msg.len = sizeof(int); DPRINT_INFO(OUTPUT, "RESP : os type %d\n", *(int*)buf_ptr); if (remote_tx_response(wl, buf_ptr, 0) < 0) DPRINT_ERR(ERR, "\nReturn results failed\n"); } } #ifdef RWL_SOCKET close_sock_handle(g_rwl_hndle); #endif /* RWL_SOCKET */ if (buf_ptr) free(buf_ptr); continue; } /* Process command */ if (g_rem_ptr->msg.flags & REMOTE_SHELL_CMD) { /* Get the response length first and get the response buffer in case of * synchronous shell commands and the buf_ptr will have the response file * name. In case of asynchronous shell commands, buf_ptr * will be get updated by the remote_shell_execute function. */ need_speedy_response = 1; #ifndef WIN32 if (buf_ptr) { async_cmd_flag = strstr((char*)buf_ptr, "%"); } if ((err = remote_shell_execute((char*)buf_ptr, wl)) > 0) { if (async_cmd_flag) g_rem_ptr->msg.len = err; } /* Sync shell command: No need to send response from here */ else { #ifdef RWL_SOCKET /* Transmitted to client. Then close the handle & * get the new handle for next transmission & reception. */ close_sock_handle(g_rwl_hndle); #endif /* RWL_SOCKET */ continue; } #else if ((err = remote_shell_execute((char*)buf_ptr, wl)) != SUCCESS) { DPRINT_ERR(ERR, "Error in executing shell command\n"); if (buf_ptr) free(buf_ptr); #ifdef RWL_SOCKET /* Transmitted to client. Then close the handle & * get the new handle for next transmission & reception. */ close_sock_handle(g_rwl_hndle); #endif /* RWL_SOCKET */ continue; } /* Get the response from the temporary file */ if ((err = remote_shell_get_resp(shell_fname, wl)) != SUCCESS) { DPRINT_ERR(ERR, "Error in executing shell command\n"); } if (buf_ptr) free(buf_ptr); #ifdef RWL_SOCKET /* Transmitted to client. Then close the handle & * get the new handle for next transmission & reception. */ close_sock_handle(g_rwl_hndle); #endif /* RWL_SOCKET */ continue; #endif /* WIN32 */ } /* REMOTE_SHELL_CMD */ #ifdef RWLASD if (g_rem_ptr->msg.flags & REMOTE_ASD_CMD) { if ((err = remote_asd_exec(buf_ptr, (int *)&g_rem_ptr->msg.len)) < 0) { DPRINT_ERR(ERR, "Error in executing asd command\n"); } } /* REMOTE_ASD_CMD */ #endif /* * added to take care of OID base problem for cross OS RWL cleint server * In case of LX Server and WIN32 client OID base need to be removed * In case of WIN32 server and LX client OID base need to be added */ if (!(g_rem_ptr->msg.flags & REMOTE_ASD_CMD)) { #if defined(LINUX) || defined(vxworks) if (g_rem_ptr->msg.cmd > MAX_IOVAR) g_rem_ptr->msg.cmd -= WL_OID_BASE; #endif #if defined(WIN32) if (g_rem_ptr->msg.cmd < MAX_IOVAR) g_rem_ptr->msg.cmd += WL_OID_BASE; #endif } #ifdef VISTA_SERVER if (g_rem_ptr->msg.flags & REMOTE_VISTA_CMD) { vista_buf[0] = strtok(buf_ptr, " \t\n"); for (index = 1; (vista_buf[index] = strtok(NULL, " \t\n")) != NULL; index++); if ((err = remote_vista_exec(wl, vista_buf)) < 0) { DPRINT_ERR(ERR, "Error in executing vista command\n"); } memcpy(buf_ptr, vista_buf[0], strlen(vista_buf[0])); g_rem_ptr->msg.len = strlen(vista_buf[0]); } /* REMOTE_VISTA_CMD */ #endif /* VISTA_SERVER */ #ifndef OLYMPIC_RWL #if defined(LINUX) || defined(vxworks) #ifndef RWL_DONGLE if (g_rem_ptr->msg.flags & REMOTE_GET_IOCTL || g_rem_ptr->msg.flags & REMOTE_SET_IOCTL) { if (strlen(g_rem_ptr->intf_name) != 0) { #if defined(LINUX) struct ifreq ifr; /* validate the interface */ memset(&ifr, 0, sizeof(ifr)); if (g_rem_ptr->intf_name) strncpy(ifr.ifr_name, g_rem_ptr->intf_name, IFNAMSIZ); if (wl_check((void *)&ifr)) { DPRINT_ERR(ERR, "%s: wl driver adapter not found\n", g_rem_ptr->intf_name); /* Signal end of command output */ g_rem_ptr->msg.len = 0; remote_tx_response(wl, NULL, BCME_NODEVICE); if (buf_ptr) free(buf_ptr); #ifdef RWL_SOCKET close_sock_handle(g_rwl_hndle); #endif continue; } #endif /* LINUX */ #if defined(vxworks) if (wl_check((void *)g_rem_ptr->intf_name)) { DPRINT_ERR(ERR, "%s: wl driver adapter not found\n", g_rem_ptr->intf_name); /* Signal end of command output */ g_rem_ptr->msg.len = 0; remote_tx_response(wl, NULL, BCME_NODEVICE); if (buf_ptr) free(buf_ptr); #ifdef RWL_SOCKET close_sock_handle(g_rwl_hndle); #endif continue; } #endif /* vxworks */ if (set_interface(wl, g_rem_ptr->intf_name) == BCME_OK) DPRINT_DBG(OUTPUT, "\n %s Interface will be used \n", (char *)wl); } } #endif /* ifndef RWL_DONGLE */ #endif /* defined(LINUX) || defined(vxworks) */ #endif /* ifndef OLYMPIC_RWL */ if (g_rem_ptr->msg.flags & REMOTE_SET_IOCTL || g_rem_ptr->msg.flags & RDHD_SET_IOCTL) { #ifdef WIN32 #if defined (RWL_DONGLE) || defined (RWL_WIFI) /* For commands with msg length as zero initialize the buffer to null */ if (g_rem_ptr->msg.len == 0) buf_ptr = NULL; #endif #else if (g_rem_ptr->msg.len == 0) buf_ptr = NULL; #endif /* WIN32 */ #if defined(LINUX) || defined(TARGETOS_symbian) || defined(TARGETOS_nucleus) || defined(MACOSX) || defined(TARGET_wiced) #ifdef OLYMPIC_RWL set_interface(wl, old_intf_name); #endif #if defined( TARGET_wiced ) set_interface(wl, g_rem_ptr->intf_name); #endif if (g_rem_ptr->msg.flags & REMOTE_SET_IOCTL) { if (g_rem_ptr->msg.cmd == WLC_SET_VAR && buf_ptr && !strncmp((const char *)buf_ptr, "init", g_rem_ptr->msg.len)) { DPRINT_INFO(OUTPUT, "REC : init command\n"); err = 0; } else if (g_rem_ptr->msg.cmd == WLC_SET_VAR && buf_ptr && !strncmp((const char *)buf_ptr, "download", g_rem_ptr->msg.len)) { DPRINT_INFO(OUTPUT, "REC : download command\n"); download_flag = download_flag? 0: 1; if (download_flag) { DPRINT_INFO(OUTPUT, "download started\n"); start_download( ); } else { DPRINT_INFO(OUTPUT, "download completed\n"); finish_download( ); } err = 0; } else if (g_rem_ptr->msg.cmd == WLC_SET_VAR && buf_ptr && !strncmp((const char *)buf_ptr, "membytes", g_rem_ptr->msg.len)) { DPRINT_INFO(OUTPUT, "REC : membytes command\n"); skip = strlen("membytes "); uint32_t address = *((uint32_t*)(buf_ptr + skip)); skip += sizeof(uint32_t); uint32_t len = *((uint32_t*)(buf_ptr + skip)); skip += sizeof(uint32_t); if ( len != g_rem_ptr->msg.len - skip ) { DPRINT_ERR(ERR, "Length does not match\n"); } membytes_write( address, buf_ptr + skip, g_rem_ptr->msg.len - skip ); err = 0; } else { err = wl_ioctl(wl, g_rem_ptr->msg.cmd, (void *)buf_ptr, g_rem_ptr->msg.len, TRUE); DPRINT_INFO(OUTPUT, "SEND : cmd %d\t msg len %d\n", g_rem_ptr->msg.cmd, g_rem_ptr->msg.len); DPRINT_INFO(OUTPUT, "error code: %d\n", err); } } #if defined(LINUX) if (err == IOCTL_ERROR) { DPRINT_ERR(ERR, "Error in executing wl_ioctl\n"); DPRINT_ERR(ERR, "Setting Default Interface1 \n"); set_interface(wl, old_intf_name); } if (g_rem_ptr->msg.flags & RDHD_SET_IOCTL) { err = dhd_ioctl(wl, g_rem_ptr->msg.cmd, (void *)buf_ptr, g_rem_ptr->msg.len, TRUE); } #endif /* LINUX */ #elif vxworks if ((err = wl_ioctl_vx(wl, g_rem_ptr->msg.cmd, (void *)buf_ptr, g_rem_ptr->msg.len)) != 0) { DPRINT_ERR(ERR, "Error in executing wl_ioctl_vx\n"); } if (err == IOCTL_ERROR) { DPRINT_ERR(ERR, "Error in executing wl_ioctl\n"); DPRINT_ERR(ERR, "Setting Default Interface \n"); set_interface(wl, old_intf_name); } #elif WIN32 dwlen = g_rem_ptr->msg.len; if (g_rem_ptr->msg.flags & RDHD_SET_IOCTL) { g_rem_ptr->msg.cmd = g_rem_ptr->msg.cmd - WL_OID_BASE + OID_DHD_IOCTLS; } err = (int)ir_setinformation(wl, g_rem_ptr->msg.cmd, buf_ptr, &dwlen); #endif /* LINUX TARGETOS_symbian MACOSX */ g_rem_ptr->msg.flags = REMOTE_SET_IOCTL; } /* RDHD/REMOTE_SET_IOCTL */ if (g_rem_ptr->msg.flags & REMOTE_GET_IOCTL || g_rem_ptr->msg.flags & RDHD_GET_IOCTL) { #if defined(LINUX) || defined(TARGETOS_symbian) || defined(TARGETOS_nucleus) || defined(MACOSX) || defined(TARGET_wiced) if (g_rem_ptr->msg.cmd == WLC_GET_VAR && buf_ptr && strncmp((const char *)buf_ptr, "exit", g_rem_ptr->msg.len) == 0) { /* exit command from remote client terminates server */ free(buf_ptr); break; } #if defined( TARGET_wiced ) set_interface(wl, g_rem_ptr->intf_name); #endif if (g_rem_ptr->msg.flags & REMOTE_GET_IOCTL) err = wl_ioctl(wl, g_rem_ptr->msg.cmd, (void *)buf_ptr, g_rem_ptr->msg.len, FALSE); #if defined (LINUX) if (err == IOCTL_ERROR) { DPRINT_ERR(ERR, "REMOTE_GET_IOCTL::Error in executing wl_ioctl\n"); DPRINT_ERR(ERR, "Setting Default Interface \n"); set_interface(wl, old_intf_name); } if (g_rem_ptr->msg.flags & RDHD_GET_IOCTL) err = dhd_ioctl(wl, g_rem_ptr->msg.cmd, (void *)buf_ptr, g_rem_ptr->msg.len, FALSE); #endif /* LINUX */ #elif vxworks if ((err = wl_ioctl_vx(wl, g_rem_ptr->msg.cmd, (void *)buf_ptr, g_rem_ptr->msg.len)) != 0) { DPRINT_ERR(ERR, "Error in executing wl_ioctl_vx\n"); } if (err == IOCTL_ERROR) { DPRINT_ERR(ERR, "Error in executing wl_ioctl_vx\n"); DPRINT_ERR(ERR, "Setting Default Interface \n"); set_interface(wl, old_intf_name); } #elif WIN32 if (g_rem_ptr->msg.cmd == (WL_OID_BASE + WLC_GET_VAR) && strncmp(buf_ptr, "exit", g_rem_ptr->msg.len) == 0) { /* exit command from remote client terminates server */ if (buf_ptr) { free(buf_ptr); } break; } dwlen = g_rem_ptr->msg.len; if (g_rem_ptr->msg.flags & RDHD_GET_IOCTL) { g_rem_ptr->msg.cmd = g_rem_ptr->msg.cmd - WL_OID_BASE + OID_DHD_IOCTLS; } err = (int)ir_queryinformation(wl, g_rem_ptr->msg.cmd, buf_ptr, &dwlen); #endif /* defined(LINUX) || defined(TARGETOS_symbian) || defined(TARGETOS_nucleus) || defined(TARGET_wiced) */ g_rem_ptr->msg.flags = REMOTE_GET_IOCTL; } /* REMOTE_GET_IOCTL */ DPRINT_INFO(OUTPUT, "RESP : cmd %d\t msg len %d\n", g_rem_ptr->msg.cmd, g_rem_ptr->msg.len); #if defined(LINUX) || defined(vxworks) /* setting back default interface */ set_interface(wl, old_intf_name); #endif /* defined(LINUX) || defined(vxworks) */ /* Transmit the response results */ if (remote_tx_response(wl, buf_ptr, err) < 0) { DPRINT_ERR(ERR, "\nReturn results failed\n"); } #ifdef RWL_SOCKET if (g_rem_ptr->msg.flags != REMOTE_SHELL_CMD) /* Transmitted to client. Then close the handle & get the new handle * for next transmission & reception. In case of shell commands this * should be closed in respective shellproc files. */ close_sock_handle(g_rwl_hndle); #endif /* RWL_SOCKET */ if (buf_ptr) { free(buf_ptr); } } /* end of while */ #if defined (RWL_SOCKET) /* Close the main handle for socket */ close_sock_handle(transport_descriptor); #elif defined(RWL_SERIAL) /* Close the main handle for serial pipe */ rwl_close_pipe(remote_type, (void*)&transport_descriptor); #endif #ifdef RWLASD wfa_dut_deinit(); #endif return err; }
int wl_lib(char *input_str) { struct ifreq ifr; char *ifname = NULL; int err = 0; int help = 0; int status = CMD_WL; void* serialHandle = NULL; char *tmp_argv[LINUX_NUM_ARGS]; char **argv = tmp_argv; int argc; /* buf_to_args return 0 if no args or string too long * or return NDIS_NUM_ARGS if too many args */ if (((argc = buf_to_args(input_str, argv)) == 0) || (argc == LINUX_NUM_ARGS)) { printf("wl:error: can't convert input string\n"); return (-1); } #else /* Main client function */ int main(int argc, char **argv) { struct ifreq ifr; char *ifname = NULL; int err = 0; int help = 0; int status = CMD_WL; #if defined(RWL_DONGLE) || RWL_SERIAL void* serialHandle = NULL; #endif #endif /* WLMSO */ wlu_av0 = argv[0]; wlu_init(); memset(&ifr, 0, sizeof(ifr)); (void)*argv++; if ((status = wl_option(&argv, &ifname, &help)) == CMD_OPT) { if (ifname) { if (strcmp(ifname, "eth1") == 0) { strncpy(ifr.ifr_name, "wl0", IFNAMSIZ); } else if (strcmp(ifname, "eth2") == 0) { strncpy(ifr.ifr_name, "wl1", IFNAMSIZ); } else { strncpy(ifr.ifr_name, ifname, IFNAMSIZ); } } /* Bug fix: If -h is used as an option, the above function call * will notice it and raise the flag but it won't be processed * in this function so we undo the argv increment so that the -h * can be spotted by the next call of wl_option. This will ensure * that wl -h [cmd] will function as desired. */ else if (help) (void)*argv--; } /* Linux client looking for a indongle reflector */ if (*argv && strncmp (*argv, "--indongle", strlen(*argv)) == 0) { rwl_dut_autodetect = FALSE; (void)*argv++; } /* Linux client looking for a WinVista server */ if (*argv && strncmp (*argv, "--vista", strlen(*argv)) == 0) { rwl_os_type = WINVISTA_OS; rwl_dut_autodetect = FALSE; (void)*argv++; } /* Provide option for disabling remote DUT autodetect */ if (*argv && strncmp(*argv, "--nodetect", strlen(*argv)) == 0) { rwl_dut_autodetect = FALSE; argv++; } if (*argv && strncmp (*argv, "--debug", strlen(*argv)) == 0) { debug = TRUE; argv++; } /* RWL socket transport Usage: --socket ipaddr/hostname [port num] */ if (*argv && strncmp (*argv, "--socket", strlen(*argv)) == 0) { (void)*argv++; remote_type = REMOTE_SOCKET; if (!(*argv)) { rwl_usage(remote_type); return err; } /* IP address validation is done in client_shared file */ g_rwl_servIP = *argv; (void)*argv++; g_rwl_servport = DEFAULT_SERVER_PORT; if ((*argv) && isdigit(**argv)) { g_rwl_servport = atoi(*argv); (void)*argv++; } } /* RWL from system serial port on client to uart serial port on server */ /* Usage: --serial /dev/ttyS0 */ if (*argv && strncmp (*argv, "--serial", strlen(*argv)) == 0) { (void)*argv++; remote_type = REMOTE_SERIAL; } /* RWL from system serial port on client to uart dongle port on server */ /* Usage: --dongle /dev/ttyS0 */ if (*argv && strncmp (*argv, "--dongle", strlen(*argv)) == 0) { (void)*argv++; remote_type = REMOTE_DONGLE; } #if defined(RWL_SERIAL) || defined(RWL_DONGLE) if (remote_type == REMOTE_SERIAL || remote_type == REMOTE_DONGLE) { if (!(*argv)) { rwl_usage(remote_type); return err; } g_rwl_device_name_serial = *argv; (void)*argv++; if ((serialHandle = rwl_open_pipe(remote_type, g_rwl_device_name_serial, 0, 0)) == NULL) { DPRINT_ERR(ERR, "serial device open error\r\n"); return -1; } ifr = (*(struct ifreq *)serialHandle); } #endif /* RWL_SERIAL */ /* RWL over wifi. Usage: --wifi mac_address */ if (*argv && strncmp (*argv, "--wifi", strlen(*argv)) == 0) { (void)*argv++; /* use default interface */ if (!*ifr.ifr_name) wl_find(&ifr); /* validate the interface */ if (!*ifr.ifr_name) { errno = ENXIO; syserr("interface"); } if ((err = wl_check((void *)&ifr)) < 0) { fprintf(stderr, "%s: wl driver adapter not found\n", wlu_av0); exit(1); } remote_type = REMOTE_WIFI; if (argc < 4) { rwl_usage(remote_type); return err; } /* copy server mac address to local buffer for later use by findserver cmd */ if (!wl_ether_atoe(*argv, (struct ether_addr *)g_rwl_buf_mac)) { fprintf(stderr, "could not parse as an ethternet MAC address\n"); return FAIL; } (void)*argv++; } if ((*argv) && (strlen(*argv) > 2) && (strncmp(*argv, "--interactive", strlen(*argv)) == 0)) { interactive_flag = 1; } /* Process for local wl */ if (remote_type == NO_REMOTE) { if (interactive_flag == 1) (void)*argv--; err = process_args(&ifr, argv); return err; } else { #ifndef OLYMPIC_RWL /* Autodetect remote DUT */ if (rwl_dut_autodetect == TRUE) rwl_detect((void*)&ifr, debug, &rwl_os_type); #endif /* OLYMPIC_RWL */ } /* RWL client needs to initialize ioctl_version */ if (wl_check((void *)&ifr) != 0) { fprintf(stderr, "%s: wl driver adapter not found\n", wlu_av0); exit(1); } if (interactive_flag == 1) { err = do_interactive(&ifr); return err; } if ((*argv) && (interactive_flag == 0)) { err = process_args(&ifr, argv); if ((err == SERIAL_PORT_ERR) && (remote_type == REMOTE_DONGLE)) { DPRINT_ERR(ERR, "\n Retry again\n"); err = process_args((struct ifreq*)&ifr, argv); } return err; } rwl_usage(remote_type); #if defined(RWL_DONGLE) || RWL_SERIAL if (remote_type == REMOTE_DONGLE || remote_type == REMOTE_SERIAL) rwl_close_pipe(remote_type, (void*)&ifr); #endif /* RWL_DONGLE || RWL_SERIAL */ return err; } /* * Function called for 'local' execution and for 'remote' non-interactive session * (shell cmd, wl cmd) */ int process_args(struct ifreq* ifr, char **argv) { char *ifname = NULL; int help = 0; int status = 0; int vista_cmd_index; int err = 0; cmd_t *cmd = NULL; #ifdef RWL_WIFI int retry; #endif while (*argv) { if ((strcmp (*argv, "sh") == 0) && (remote_type != NO_REMOTE)) { (void)*argv++; /* Get the shell command */ if (*argv) { /* Register handler in case of shell command only */ err = rwl_shell_cmd_proc((void*)ifr, argv, SHELL_CMD); } else { DPRINT_ERR(ERR, "Enter the shell " "command, e.g. ls(Linux) or dir(Win CE)\n"); err = -1; } return err; } #ifdef RWLASD if ((strcmp (*argv, "asd") == 0) && (remote_type != NO_REMOTE)) { (void)*argv++; /* Get the asd command */ if (*argv) { err = rwl_shell_cmd_proc((void*)ifr, argv, ASD_CMD); } else { DPRINT_ERR(ERR, "Enter the ASD command, e.g. ca_get_version\n"); err = -1; } return err; } #endif if (rwl_os_type == WINVISTA_OS) { for (vista_cmd_index = 0; remote_vista_cmds[vista_cmd_index] && strcmp(remote_vista_cmds[vista_cmd_index], *argv); vista_cmd_index++); if (remote_vista_cmds[vista_cmd_index] != NULL) { err = rwl_shell_cmd_proc((void *)ifr, argv, VISTA_CMD); if ((remote_type == REMOTE_WIFI) && ((!strcmp(*argv, "join")))) { #ifdef RWL_WIFI DPRINT_INFO(OUTPUT, "\nChannel will be synchronized by Findserver\n\n"); sleep(RWL_WIFI_JOIN_DELAY); for (retry = 0; retry < RWL_WIFI_RETRY; retry++) { if ((rwl_find_remote_wifi_server(ifr, &g_rwl_buf_mac[0]) == 0)) { break; } } #endif /* RWL_WIFI */ } return err; } } if ((status = wl_option(&argv, &ifname, &help)) == CMD_OPT) { if (help) break; if (ifname) { if (remote_type == NO_REMOTE) { strncpy((*ifr).ifr_name, ifname, IFNAMSIZ); } else { strncpy(g_rem_ifname, ifname, IFNAMSIZ); } } continue; } /* parse error */ else if (status == CMD_ERR) break; if (remote_type == NO_REMOTE) { /* use default interface */ if (!*(*ifr).ifr_name) wl_find(ifr); /* validate the interface */ if (!*(*ifr).ifr_name) { errno = ENXIO; syserr("interface"); } if ((err = wl_check((void *)ifr)) < 0) { fprintf(stderr, "%s: wl driver adapter not found\n", wlu_av0); exit(1); } if ((strcmp (*argv, "--interactive") == 0) || (interactive_flag == 1)) { err = do_interactive(ifr); return err; } } /* search for command */ cmd = wl_find_cmd(*argv); /* if not found, use default set_var and get_var commands */ if (!cmd) { cmd = &wl_varcmd; } #ifdef RWL_WIFI if (!strcmp(cmd->name, "findserver")) { remote_wifi_ser_init_cmds((void *) ifr); } #endif /* RWL_WIFI */ /* RWL over Wifi supports 'lchannel' command which lets client * (ie *this* machine) change channels since normal 'channel' command * applies to the server (ie target machine) */ if (remote_type == REMOTE_WIFI) { #ifdef RWL_WIFI if (!strcmp(argv[0], "lchannel")) { strcpy(argv[0], "channel"); rwl_wifi_swap_remote_type(remote_type); err = (*cmd->func)((void *) ifr, cmd, argv); rwl_wifi_swap_remote_type(remote_type); } else { err = (*cmd->func)((void *) ifr, cmd, argv); } /* After join cmd's gets exeuted on the server side , client needs to know * the channel on which the server is associated with AP , after delay of * few seconds client will intiate the scan on diffrent channels by calling * rwl_find_remote_wifi_server fucntion */ if ((!strcmp(cmd->name, "join") || ((!strcmp(cmd->name, "ssid") && (*(++argv) != NULL))))) { DPRINT_INFO(OUTPUT, "\n Findserver is called to synchronize the" "channel\n\n"); sleep(RWL_WIFI_JOIN_DELAY); for (retry = 0; retry < RWL_WIFI_RETRY; retry++) { if ((rwl_find_remote_wifi_server(ifr, &g_rwl_buf_mac[0]) == 0)) { break; } } } #endif /* RWL_WIFI */ } else { /* do command */ err = (*cmd->func)((void *) ifr, cmd, argv); } break; } /* while loop end */ /* provide for help on a particular command */ if (help && *argv) { cmd = wl_find_cmd(*argv); if (cmd) { wl_cmd_usage(stdout, cmd); } else { DPRINT_ERR(ERR, "%s: Unrecognized command \"%s\", type -h for help\n", wlu_av0, *argv); } } else if (!cmd) wl_usage(stdout, NULL); else if (err == USAGE_ERROR) wl_cmd_usage(stderr, cmd); else if (err == IOCTL_ERROR) wl_printlasterror((void *) ifr); else if (err == BCME_NODEVICE) DPRINT_ERR(ERR, "%s : wl driver adapter not found\n", g_rem_ifname); return err; }
/* Main client function * The code is mostly from wlu_linux.c. This function takes care of executing remote dhd commands * along with the local dhd commands now. */ int main(int argc, char **argv) { struct ifreq ifr; char *ifname = NULL; int err = 0; int help = 0; int status = CMD_DHD; #ifdef RWL_SOCKET struct ipv4_addr temp; #endif /* RWL_SOCKET */ UNUSED_PARAMETER(argc); av0 = argv[0]; memset(&ifr, 0, sizeof(ifr)); argv++; if ((status = dhd_option(&argv, &ifname, &help)) == CMD_OPT) { if (ifname) strncpy(ifr.ifr_name, ifname, IFNAMSIZ); } /* Linux client looking for a Win32 server */ if (*argv && strncmp (*argv, "--wince", strlen(*argv)) == 0) { rwl_os_type = WIN32_OS; argv++; } /* RWL socket transport Usage: --socket ipaddr [port num] */ if (*argv && strncmp (*argv, "--socket", strlen(*argv)) == 0) { argv++; remote_type = REMOTE_SOCKET; #ifdef RWL_SOCKET if (!(*argv)) { rwl_usage(remote_type); return err; } if (!dhd_atoip(*argv, &temp)) { rwl_usage(remote_type); return err; } g_rwl_servIP = *argv; argv++; g_rwl_servport = DEFAULT_SERVER_PORT; if ((*argv) && isdigit(**argv)) { g_rwl_servport = atoi(*argv); argv++; } #endif /* RWL_SOCKET */ } /* RWL from system serial port on client to uart dongle port on server */ /* Usage: --dongle /dev/ttyS0 */ if (*argv && strncmp (*argv, "--dongle", strlen(*argv)) == 0) { argv++; remote_type = REMOTE_DONGLE; } /* RWL over wifi. Usage: --wifi mac_address */ if (*argv && strncmp (*argv, "--wifi", strlen(*argv)) == 0) { argv++; #ifdef RWL_WIFI remote_type = NO_REMOTE; if (!ifr.ifr_name[0]) { dhd_find(&ifr, "wl"); } /* validate the interface */ if (!ifr.ifr_name[0] || wl_check((void*)&ifr)) { fprintf(stderr, "%s: wl driver adapter not found\n", av0); exit(1); } remote_type = REMOTE_WIFI; if (argc < 4) { rwl_usage(remote_type); return err; } /* copy server mac address to local buffer for later use by findserver cmd */ if (!dhd_ether_atoe(*argv, (struct ether_addr *)g_rwl_buf_mac)) { fprintf(stderr, "could not parse as an ethernet MAC address\n"); return FAIL; } argv++; #else /* RWL_WIFI */ remote_type = REMOTE_WIFI; #endif /* RWL_WIFI */ } /* Process for local dhd */ if (remote_type == NO_REMOTE) { err = process_args(&ifr, argv); return err; } #ifdef RWL_ENABLE if (*argv) { err = process_args(&ifr, argv); if ((err == SERIAL_PORT_ERR) && (remote_type == REMOTE_DONGLE)) { DPRINT_ERR(ERR, "\n Retry again\n"); err = process_args((struct ifreq*)&ifr, argv); } return err; } rwl_usage(remote_type); #endif /* RWL_ENABLE */ return err; }
int main(int argc, char **argv) #endif { struct ifreq ifr; cmd_t *cmd = NULL; int err = 0; char *ifname = NULL; int help = 0; int status = CMD_WL; av0 = argv[0]; memset(&ifr, 0, sizeof(ifr)); for (++argv; *argv;) { /* command option */ if ((status = wl_option(&argv, &ifname, &help)) == CMD_OPT) { if (help) break; if (ifname) strncpy(ifr.ifr_name, ifname, IFNAMSIZ); continue; } /* parse error */ else if (status == CMD_ERR) break; /* wl command */ /* * else if (status == CMD_WL) * ; */ /* use default interface */ if (!*ifr.ifr_name) wl_find(&ifr); /* validate the interface */ if (!*ifr.ifr_name || wl_check((void *)&ifr)) { fprintf(stderr, "%s: wl driver adapter not found\n", av0); #ifdef DSLCPE_SHLIB return -1; #else exit(1); #endif } /* search for command */ cmd = wl_find_cmd(*argv); /* defaults to using the set_var and get_var commands */ if (!cmd) cmd = &wl_varcmd; /* do command */ err = (*cmd->func)((void *) &ifr, cmd, argv); break; } if (help && *argv) { cmd = wl_find_cmd(*argv); if (cmd) cmd_usage(stdout, cmd); else { printf("%s: Unrecognized command \"%s\", type -h for help\n", av0, *argv); } } else if (!cmd) wl_usage(stdout, NULL); else if (err == USAGE_ERROR) cmd_usage(stderr, cmd); else if (err == IOCTL_ERROR) wl_printlasterror((void *) &ifr); return err; }