/* * check for the channel of remote and respond if it matches with its current * channel. Once the server gets the handshake cmd, it will check the channel * number of the remote with its channel and if it matches , then it send out the * ack to the remote client. This fucntion is used only by the server. */ void rwl_wifi_find_server_response(void *wl, dot11_action_wifi_vendor_specific_t *rec_frame) { int error, send, server_channel; if (rec_frame->type == RWL_WIFI_FIND_MY_PEER) { rec_frame->type = RWL_WIFI_FOUND_PEER; /* read channel on of the SERVER */ rwl_wifi_config_channel(wl, WLC_GET_CHANNEL, &server_channel); /* overlapping channel not supported, so server will only respond to client on the channel of the client */ if (rec_frame->data[RWL_WIFI_CLIENT_CHANNEL_OFFSET] == server_channel) { /* send the response by updating server channel in the frame */ rec_frame->data[RWL_WIFI_SERVER_CHANNEL_OFFSET] = server_channel; /* change the TYPE feild for giving the ACK */ for (send = 0; send < RWL_WIFI_SEND; send++) { if ((error = rwl_var_setbuf(wl, RWL_WIFI_ACTION_CMD, rec_frame, RWL_WIFI_ACTION_FRAME_SIZE)) < 0) { DPRINT_ERR(ERR, "rwl_wifi_find_server_response: Failed" "to Send the Frame %d\n", error); break; } rwl_sleep(RWL_WIFI_SEND_DELAY); } } } return; }
static int remote_CDC_dongle_tx(void *wl, uint cmd, uchar *buf, uint buf_len, uint data_len, uint flags) { int error; rem_ioctl_t resp_rem_cdc; if (flags & REMOTE_SET_IOCTL) { uchar* rem_buf_ptr; /* for set commands message length and data length should be set to zero * unlike Get Ioctl which will have valid data and message length */ resp_rem_cdc.msg.len = 0; resp_rem_cdc.data_len = 0; resp_rem_cdc.msg.cmd = cmd; resp_rem_cdc.msg.flags = REMOTE_REPLY; DPRINT_INFO(OUTPUT, "Set:Resp packet:%d %d %d %d\n", resp_rem_cdc.msg.cmd, resp_rem_cdc.msg.len, resp_rem_cdc.msg.flags, resp_rem_cdc.data_len); if ((rem_buf_ptr = (uchar*)malloc(DONGLE_TX_FRAME_SIZE + REMOTE_SIZE)) == NULL) { DPRINT_ERR(ERR, "malloc failed for remote_CDC_dongle_tx\n"); return BCME_ERROR; } /* Send reply to client here */ memcpy(rem_buf_ptr, (char*)(&resp_rem_cdc), REMOTE_SIZE); if ((error = rwl_var_setbuf((void*)wl, cmdname, rem_buf_ptr, DONGLE_TX_FRAME_SIZE + REMOTE_SIZE)) < 0) { DPRINT_ERR(ERR, "unable to send SET results to driver=%d\n", error); } else DPRINT_INFO(OUTPUT, "Packet sent to wl driver, error=%d\n", error); if (rem_buf_ptr) free(rem_buf_ptr); } else { /* GET_IOCTL */ resp_rem_cdc.msg.cmd = cmd; resp_rem_cdc.msg.len = buf_len; resp_rem_cdc.msg.flags = flags; resp_rem_cdc.data_len = data_len; if ((error = rwl_serial_fragmented_tx(wl, &resp_rem_cdc, buf, cmd)) < 0) DPRINT_ERR(ERR, "wl_server_serial: Return error code failed\n"); } return error; }
int remote_CDC_tx(void *wl, uint cmd, uchar *buf, uint buf_len, uint data_len, uint flags, int debug) { #if defined(RWL_SOCKET) || defined(RWL_SERIAL) unsigned long numwritten = 0; #endif rem_ioctl_t *rem_ptr = &rem_cdc; #ifdef RWL_WIFI int error; uint totalframes, tx_count; dot11_action_wifi_vendor_specific_t *rem_wifi_send; #endif UNUSED_PARAMETER(debug); rem_ptr->msg.cmd = cmd; rem_ptr->msg.len = buf_len; rem_ptr->msg.flags = flags; rem_ptr->data_len = data_len; if (data_len > buf_len) { DPRINT_ERR(ERR, "remote_CDC_tx: data_len (%d) > buf_len (%d)\n", data_len, buf_len); return (FAIL); } #ifdef RWL_SERIAL if (remote_type == REMOTE_SERIAL) { int ret; /* Send CDC header first */ if ((ret = rwl_write_serial_port(wl, (char *)rem_ptr, REMOTE_SIZE, &numwritten)) == -1) { DPRINT_ERR(ERR, "CDC_Tx: Data: Write failed \n"); return (FAIL); } numwritten = ret; /* Send data second */ if ((ret = rwl_write_serial_port(wl, (char*)buf, data_len, &numwritten)) == -1) { DPRINT_ERR(ERR, "CDC_Tx: Data: Write failed \n"); return (FAIL); } numwritten = ret; return (buf_len); } #endif /* RWL_SERIAL */ #ifdef RWL_DONGLE if (remote_type == REMOTE_DONGLE) { return (remote_CDC_tx_dongle(wl, rem_ptr, buf)); } #endif /* RWL_DONGLE */ #ifdef RWL_SOCKET if (remote_type == REMOTE_SOCKET) { int ret; /* Send CDC header first */ if ((ret = rwl_send_to_streamsocket(*(int*)wl, (char *)rem_ptr, REMOTE_SIZE, 0)) == -1) { DPRINT_ERR(ERR, "CDC_Tx: Data: Write failed \n"); return (FAIL); } numwritten = ret; /* Send data second */ if ((ret = rwl_send_to_streamsocket(*(int*)wl, (const char*)buf, data_len, 0)) == -1) { DPRINT_ERR(ERR, "CDC_Tx: Data: Write failed \n"); return (FAIL); } numwritten = ret; return (buf_len); } #endif /* RWL_SOCKET */ #ifdef RWL_WIFI /* * wifi action frame is formed based on the CDC header and data. * If the data is bigger than RWL_WIFI_FRAG_DATA_SIZE size, number of fragments are * calculated and sent * similar number of action frames with subtype incremented with sequence. * Frames are sent with delay to avoid the outof order at receving end */ if (remote_type == REMOTE_WIFI) { if ((rem_wifi_send = rwl_wifi_allocate_actionframe()) == NULL) { DPRINT_ERR(ERR, "remote_CDC_tx: Failed to get allocated buffer\n"); return (FAIL); } if (rem_ptr->msg.len > RWL_WIFI_FRAG_DATA_SIZE) { /* response needs to be sent in fragments */ totalframes = rem_ptr->msg.len / RWL_WIFI_FRAG_DATA_SIZE; memcpy((char*)&rem_wifi_send->data[RWL_WIFI_CDC_HEADER_OFFSET], (char*)rem_ptr, REMOTE_SIZE); memcpy((char*)&rem_wifi_send->data[REMOTE_SIZE], &buf[0], RWL_WIFI_FRAG_DATA_SIZE); /* update type feild to inform receiver it's frammeted response frame */ rem_wifi_send->type = RWL_ACTION_WIFI_FRAG_TYPE; rem_wifi_send->subtype = RWL_WIFI_DEFAULT_SUBTYPE; if ((error = rwl_var_setbuf(wl, RWL_WIFI_ACTION_CMD, rem_wifi_send, RWL_WIFI_ACTION_FRAME_SIZE)) < 0) { DPRINT_DBG(OUTPUT, "Failed to Send the Frame %d\n", error); free(rem_wifi_send); return error; } /* Send remaining bytes in fragments */ for (tx_count = 1; tx_count < totalframes; tx_count++) { rem_wifi_send->type = RWL_ACTION_WIFI_FRAG_TYPE; rem_wifi_send->subtype = tx_count; /* First frame onwards , buf contains only data */ memcpy((char*)&rem_wifi_send->data, &buf[tx_count*RWL_WIFI_FRAG_DATA_SIZE], RWL_WIFI_FRAG_DATA_SIZE); if ((error = rwl_var_setbuf(wl, RWL_WIFI_ACTION_CMD, rem_wifi_send, RWL_WIFI_ACTION_FRAME_SIZE)) < 0) { free(rem_wifi_send); return error; } rwl_sleep(RWL_WIFI_SEND_DELAY); } /* Check for remaing bytes to send */ if ((totalframes*RWL_WIFI_FRAG_DATA_SIZE) != rem_ptr->msg.len) { rem_wifi_send->type = RWL_ACTION_WIFI_FRAG_TYPE; rem_wifi_send->subtype = tx_count; memcpy((char*)&rem_wifi_send->data, &buf[tx_count*RWL_WIFI_FRAG_DATA_SIZE], (rem_ptr->msg.len - (tx_count*RWL_WIFI_FRAG_DATA_SIZE))); if ((error = rwl_var_setbuf(wl, RWL_WIFI_ACTION_CMD, rem_wifi_send, RWL_WIFI_ACTION_FRAME_SIZE)) < 0) { free(rem_wifi_send); return error; } } } else { /* response fits to single frame */ memcpy((char*)&rem_wifi_send->data[RWL_WIFI_CDC_HEADER_OFFSET], (char*)rem_ptr, REMOTE_SIZE); /* when data_len is 0 , buf will be NULL */ if (buf != NULL) { memcpy((char*)&rem_wifi_send->data[REMOTE_SIZE], &buf[0], data_len); } error = rwl_var_setbuf(wl, RWL_WIFI_ACTION_CMD, rem_wifi_send, RWL_WIFI_ACTION_FRAME_SIZE); free(rem_wifi_send); return error; } } #endif /* RWL_WIFI */ return (0); }
/* * This function is used by client only. Sends the finmypeer sync frame to remote * server on diffrent channels and waits for the response. */ int rwl_find_remote_wifi_server(void *wl, char *id) { dot11_action_wifi_vendor_specific_t *rem_wifi_send, *rem_wifi_recv; rem_ioctl_t *rem_ptr = &rem_cdc; /* This list is generated considering valid channel and if this * may requires updation or deletion. This needs to be identified. * we have assumed that server band is not known and considered all band channels. */ int wifichannel[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 149, 153, 157, 161, 165}; int i, error, schannel, channel_count; if ((rem_wifi_send = rwl_wifi_allocate_actionframe()) == NULL) { DPRINT_ERR(ERR, " rwl_find_remote_wifi_server : Failed to allocate \n"); return FAIL; } if ((rem_wifi_recv = rwl_wifi_allocate_actionframe()) == NULL) { DPRINT_ERR(ERR, " rwl_find_remote_wifi_server : Failed to allocate\n"); free(rem_wifi_send); return FAIL; } channel_count = sizeof(wifichannel) / sizeof(int); /* make dummy read to make sure we don't read the already queued * actionframes against the cmd we issue */ rwl_wifi_purge_actionframes(wl); /* update the client sync specifier */ rem_wifi_send->type = RWL_WIFI_FIND_MY_PEER; /* update the CDC flag to indicate it is handshake frame */ rem_ptr->msg.cmd = 0; /* cmd =0 ,this will be ignored when server receive frame * with REMOTE_FINDSERVER_IOCTL flag */ rem_ptr->msg.len = RWL_WIFI_FRAG_DATA_SIZE; rem_ptr->msg.flags = REMOTE_FINDSERVER_IOCTL; rem_ptr->data_len = RWL_WIFI_FRAG_DATA_SIZE; memcpy((char*)&rem_wifi_send->data, (char*)rem_ptr, REMOTE_SIZE); /* copy server mac to which ref driver needs to send unicast action frame */ memcpy(&rem_wifi_send->data[RWL_REF_MAC_ADDRESS_OFFSET], &id[0], ETHER_ADDR_LEN); /* Start with the channel in the list and keep changing till the server * responds or channels list ends */ for (i = 0; i < channel_count; i++) { if ((error = rwl_wifi_config_channel(wl, WLC_SET_CHANNEL, &wifichannel[i])) < 0) { DPRINT_ERR(ERR, " Failed to set the specified channel %d\n", wifichannel[i]); break; } /* send channel detail of client to server */ rem_wifi_send->data[RWL_WIFI_CLIENT_CHANNEL_OFFSET] = wifichannel[i]; if ((error = rwl_var_setbuf(wl, RWL_WIFI_ACTION_CMD, rem_wifi_send, RWL_WIFI_ACTION_FRAME_SIZE)) < 0) { DPRINT_DBG(OUTPUT, "Failed to Send the Frame %d\n", error); break; } /* read the server response on the same channel */ if ((error = remote_CDC_DATA_wifi_rx(wl, rem_wifi_recv)) < 0) { rwl_sleep(RWL_WIFI_RETRY_DELAY); continue; } /* Verify for the Type RWL_WIFI_FOUND_PEER */ if (rem_wifi_recv->type == RWL_WIFI_FOUND_PEER) { if (rem_wifi_recv->data[RWL_WIFI_SERVER_CHANNEL_OFFSET] == rem_wifi_recv->data[RWL_WIFI_CLIENT_CHANNEL_OFFSET]) { DPRINT_INFO(OUTPUT, "Server is on channel # %d\n", rem_wifi_recv->data[RWL_WIFI_SERVER_CHANNEL_OFFSET]); schannel = rem_wifi_recv->data[RWL_WIFI_SERVER_CHANNEL_OFFSET]; /* Set the back to the channel on which REF was originally */ if ((error = rwl_wifi_config_channel(wl, WLC_SET_CHANNEL, &schannel) < 0)) { DPRINT_ERR(ERR, "Failed to set the specified" "channel %d\n", schannel); } else { DPRINT_ERR(ERR, "REF now moved to the" "channel of server # %d\n", schannel); } /* we are done here, end the loop */ break; } else { DPRINT_INFO(OUTPUT, "Server is operating on diffrent channel." "continue scanning\n"); } } /* before chaning the channel of client and sending sync frame * wait for while and send */ rwl_sleep(RWL_WIFI_RETRY_DELAY); } free(rem_wifi_send); free(rem_wifi_recv); return error; }
/* * Send the valid action frame (CDC+DATA) through the REF driver interface. * if the CMD is "findserver" then "findmypeer" frames are sent on the diffrent * channels to reconnect * to with server. Other wl cmd takes the normal path. * parameter 3 , i.e. buf contains the cmd line arguments and buf_len is the actual * length of the buf. data_len is the length of the actual data to be sent to remote server. */ int remote_CDC_wifi_tx(void *wl, uint cmd, uchar *buf, uint buf_len, uint data_len, uint flags) { rem_ioctl_t *rem_ptr = &rem_cdc; int error, read_try; dot11_action_wifi_vendor_specific_t *rem_wifi_send; /* prepare CDC header */ rem_ptr->msg.cmd = cmd; rem_ptr->msg.len = buf_len; rem_ptr->msg.flags = flags; rem_ptr->data_len = data_len; if ((data_len > buf_len)) { DPRINT_ERR(ERR, "remote_CDC_wifi_tx: data_len (%d) > buf_len (%d)\n", data_len, buf_len); return (FAIL); } /* client will not send data greater than RWL_WIFI_FRAG_DATA_SIZE to server, * this condition should not be hit on client side, when sending the cmd * to remote server */ if (rem_ptr->data_len > RWL_WIFI_FRAG_DATA_SIZE) DPRINT_DBG(OUTPUT, "data size exceeds data_len %d\n", rem_ptr->msg.len); if ((buf != NULL) && (strlen((char*)buf) >= (sizeof(RWL_WIFI_FIND_SER_CMD)-1)) && (!strcmp((char*)buf, RWL_WIFI_FIND_SER_CMD))) { /* This is special case for wifi, when user wants to findserver, * client has to execute it locally.Find the channel on the on * which DUT is operating and sync up with specified MAC address, * retry if fails to find the server */ for (read_try = 0; read_try < RWL_WIFI_RETRY; read_try++) { if (((error = rwl_find_remote_wifi_server(wl, &g_rwl_buf_mac[0])) == 0)) { break; } } return error; } if ((rem_wifi_send = rwl_wifi_allocate_actionframe()) == NULL) { DPRINT_ERR(ERR, "remote_CDC_wifi_tx: Failed to allocate memory\n"); return (FAIL); } /* only data length needs to be sent to remote server using this function * This function is only meant for client to send data to server * Copy the CDC header and data to action frame data feild * Now we have encapsulated the CDC header and data completely to in the * action frame. */ memcpy(&rem_wifi_send->data[RWL_WIFI_CDC_HEADER_OFFSET], (char*)rem_ptr, REMOTE_SIZE); if (buf != NULL) { memcpy(&rem_wifi_send->data[REMOTE_SIZE], buf, data_len); } /* Send the action frame to remote server using the rwl_var_setbuf fucntion, * which will use the local driver interface to send this frame on the air */ if ((error = rwl_var_setbuf(wl, RWL_WIFI_ACTION_CMD, rem_wifi_send, RWL_WIFI_ACTION_FRAME_SIZE)) < 0) { DPRINT_ERR(ERR, "Unable to read the action frame %d error\n", error); } free(rem_wifi_send); return error; }
/* 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; }
static int rwl_serial_fragmented_tx(void* wl, rem_ioctl_t *rem_ptr, uchar *buf_ptr, int error) { rem_ioctl_t *loc_ptr = &loc_cdc; uchar* rem_buf_ptr; uint noframes = 1; /* Default noframes = 1 */ uint count; uint frame_count; uint rem_bytes; loc_ptr->msg.cmd = error; loc_ptr->msg.flags = REMOTE_REPLY; loc_ptr->msg.len = rem_ptr->msg.len; loc_ptr->data_len = rem_ptr->data_len; /* Fragment the result if it is more than DATA_FRAME_LEN (960) */ if (loc_ptr->msg.len > DATA_FRAME_LEN) { /* Calculate no of frames */ noframes = (loc_ptr->msg.len)/DATA_FRAME_LEN; if ((loc_ptr->msg.len) % DATA_FRAME_LEN > 0) { noframes += 1; rem_bytes = (loc_ptr->msg.len) % DATA_FRAME_LEN; } else { rem_bytes = DATA_FRAME_LEN; } } else { rem_bytes = loc_ptr->msg.len; } DPRINT_INFO(OUTPUT, "No of frames = %d, rem_bytes:%d\n", noframes, rem_bytes); count = 0; frame_count = noframes; rem_buf_ptr = (uchar*)malloc(DONGLE_TX_FRAME_SIZE + REMOTE_SIZE); while (count < noframes) { memset(rem_buf_ptr, 0, DONGLE_TX_FRAME_SIZE + REMOTE_SIZE); /* Send reply to client */ rem_ptr->msg.cmd = loc_ptr->msg.cmd; rem_ptr->msg.flags = loc_ptr->msg.flags; rem_ptr->msg.len = loc_ptr->msg.len; if (frame_count == 1) rem_ptr->data_len = rem_bytes; else rem_ptr->data_len = DATA_FRAME_LEN; DPRINT_DBG(OUTPUT, "GET--rem_ptr->data_len=%d\n", rem_ptr->data_len); /* Copy CDC Header */ memcpy(rem_buf_ptr, (uchar*)rem_ptr, REMOTE_SIZE); /* Copy Data now */ memcpy(&rem_buf_ptr[REMOTE_SIZE], &buf_ptr[count*DATA_FRAME_LEN], rem_ptr->data_len); count++; frame_count--; DPRINT_INFO(OUTPUT, "FRAME %d\n", count); DPRINT_INFO(OUTPUT, "%d %d %d %d\n", rem_ptr->msg.cmd, rem_ptr->msg.len, rem_ptr->msg.flags, rem_ptr->data_len); rwl_sync_delay(noframes); if ((error = rwl_var_setbuf(wl, cmdname, rem_buf_ptr, DONGLE_TX_FRAME_SIZE+REMOTE_SIZE)) < 0) { DPRINT_INFO(OUTPUT, "Unable to send to wl driver,error=%d\n", error); if (rem_buf_ptr) free(rem_buf_ptr); return BCME_ERROR; } else DPRINT_INFO(OUTPUT, "Packet sent to wl driver,error=%d\n", error); } if (rem_buf_ptr) free(rem_buf_ptr); return error; }