/* * This function is used for transmitting the response over different * transports. * In case of socket the data is directly sent to the client which is waiting on a open socket. * In case of socket the data is sent in one big chunk unlike other transports * * In case of serial the data is sent to the driver using remote_CDC_dongle_tx function * which in turn may fragment the data and send it in chunks to the client. * * In case of wi-fi the data is sent to the driver using the remote_CDC_tx. However * in this case the data is converted into 802.11 Action frames and sent using wi-fi driver. * Arguments: wl - Driver handle * hndle - Socket handle for socket transport. */ int remote_tx_response(void *wl, void* buf_ptr, int cmd) { int error = -1; UNUSED_PARAMETER(wl); UNUSED_PARAMETER(buf_ptr); UNUSED_PARAMETER(cmd); #if defined (RWL_SOCKET) || defined (RWL_SERIAL) if ((error = remote_CDC_tx((void*)&g_rwl_hndle, cmd, buf_ptr, g_rem_ptr->msg.len, g_rem_ptr->msg.len, REMOTE_REPLY, 0)) < 0) DPRINT_ERR(ERR, "wl_server: Return results failed\n"); #endif /* RWL_SOCKET || RWL_SERIAL */ #ifdef RWL_DONGLE if ((error = remote_CDC_dongle_tx(wl, cmd, buf_ptr, g_rem_ptr->msg.len, g_rem_ptr->data_len, g_rem_ptr->msg.flags)) < 0) DPRINT_ERR(ERR, "wl_server: Return results failed\n"); #endif /* RWL_DONGLE */ #ifdef RWL_WIFI /* Purge all the queued cmd's , this to ensure late response time out at */ /* client side and client might issue the next cmd if server is slow */ rwl_wifi_purge_actionframes(wl); if ((g_rem_ptr->msg.flags & REMOTE_SHELL_CMD) || (g_rem_ptr->msg.flags & REMOTE_GET_IOCTL)|| (g_rem_ptr->msg.flags & REMOTE_ASD_CMD) || (g_rem_ptr->msg.flags & REMOTE_VISTA_CMD)) { if ((error = remote_CDC_tx(wl, cmd, buf_ptr, g_rem_ptr->msg.len, g_rem_ptr->msg.len, REMOTE_REPLY, 0)) < 0) DPRINT_ERR(ERR, "Wifi_server: Return results failed\n"); } else { if ((error = remote_CDC_tx(wl, cmd, buf_ptr, 0, 0, REMOTE_REPLY, 0)) < 0) DPRINT_ERR(ERR, "Failed due to bad flag %d\n", g_rem_ptr->msg.flags); } #endif /* RWL_WIFI */ return error; }
/* * 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; }
/* * This is the front end query function for Set Ioctls. This is used by clients for executing Set Ioctls. */ int rwl_setinformation_fe(void *wl, int cmd, void* buf, unsigned long *len, int debug, int rem_ioctl_select) { int error = 0; uint tx_len; #if defined (RWL_SERIAL) || (RWL_WIFI) rem_ioctl_t *rem_ptr = NULL; #endif #ifdef RWL_WIFI dot11_action_wifi_vendor_specific_t *list = NULL; char *cbuf, retry; #endif UNUSED_PARAMETER(debug); switch (remote_type) { case REMOTE_SOCKET: #ifdef RWL_SOCKET error = rwl_information_socket(wl, cmd, buf, len, len, rem_ioctl_select); #endif break; #ifdef RWL_SERIAL case REMOTE_SERIAL: if (remote_CDC_tx(wl, cmd, buf, *len, *len, rem_ioctl_select, debug) < 0) { DPRINT_ERR(ERR, "set_info_fe: Send command failed\n"); return FAIL; } if ((rem_ptr = remote_CDC_rx_hdr(wl, debug)) == NULL) { DPRINT_ERR(ERR, "set_info_fe: Reading CDC header failed\n"); return FAIL; } if (rem_ptr->msg.flags != REMOTE_REPLY) { DPRINT_ERR(ERR, "set_info_fe: response format error.\n"); return FAIL; } if (rem_ptr->msg.len > *len) { DPRINT_ERR(ERR, "set_info_fe: needed size (%d) greater than " "actual size (%lu)\n", rem_ptr->msg.len, *len); return FAIL; } error = rem_ptr->msg.cmd; if (error != 0) { DPRINT_ERR(ERR, "set_info_fe: remote cdc header return " "error code (%d)\n", error); } if (remote_CDC_rx(wl, rem_ptr, buf, rem_ptr->msg.len, debug) == -1) { DPRINT_ERR(ERR, "set_info_fe: fetching results failed\n"); return FAIL; } if (rem_ptr->msg.flags & REMOTE_REPLY) error = rem_ptr->msg.cmd; break; #endif /* RWL_SERIAL */ #ifdef RWL_DONGLE case REMOTE_DONGLE: if ((int)(*len) > SERVER_RESPONSE_MAX_BUF_LEN) *len = SERVER_RESPONSE_MAX_BUF_LEN; /* Actual buffer to be sent should be max 256 bytes as *UART input buffer * is 512 bytes */ tx_len = MIN(*len, 512); error = rwl_information_dongle(wl, cmd, buf, len, tx_len, rem_ioctl_select); break; #endif //ifdef RWL_DONGLE case REMOTE_WIFI: #ifdef RWL_WIFI if ((int)(*len) > SERVER_RESPONSE_MAX_BUF_LEN) *len = SERVER_RESPONSE_MAX_BUF_LEN; /* Actual buffer to be sent should be max 960 bytes * as wifi max frame size if 960 * and actual data for any command will not exceed 960 bytes */ tx_len = MIN(*len, RWL_WIFI_FRAG_DATA_SIZE); if ((cbuf = (char*) malloc(tx_len)) == NULL) { DPRINT_ERR(ERR, "Malloc failed for set_info_fe character buf\n"); return FAIL; } if ((list = (dot11_action_wifi_vendor_specific_t *) malloc(RWL_WIFI_ACTION_FRAME_SIZE)) == NULL) { free(cbuf); return FAIL; } if ((rem_ptr = (rem_ioctl_t *)malloc(sizeof(rem_ioctl_t))) == NULL) { free(list); free(cbuf); return FAIL; } memcpy(cbuf, (char*)buf, tx_len); for (retry = 0; retry < RWL_WIFI_RETRY; retry++) { rwl_wifi_purge_actionframes(wl); /* copy back the buffer to input buffer */ memcpy((char*)buf, (char*)cbuf, tx_len); if (retry > 3) DPRINT_INFO(OUTPUT, "retry %d cmd %d\n", retry, cmd); if ((error = remote_CDC_wifi_tx(wl, cmd, buf, *len, tx_len, rem_ioctl_select) < 0)) { DPRINT_ERR(ERR, "ir_setinformation_fe: Send" "command failed\n"); rwl_sleep(RWL_WIFI_RETRY_DELAY); continue; } if ((char*)buf != NULL) { /* In case cmd is findserver, response is not * required from the server */ if (!strcmp((char*)buf, RWL_WIFI_FIND_SER_CMD)) { break; } } /* Read the CDC header and data of for the sent cmd * resposne */ if ((error = remote_CDC_DATA_wifi_rx((void*)wl, list) < 0)) { DPRINT_ERR(ERR, "ir_setinformation_fe: failed to read" "the response\n"); rwl_sleep(RWL_WIFI_RETRY_DELAY); continue; } memcpy((char*)rem_ptr, (char*)&list->data[RWL_WIFI_CDC_HEADER_OFFSET], REMOTE_SIZE); rwl_swap_header(rem_ptr, NETWORK_TO_HOST); memcpy((char*)buf, (char*)&list->data[REMOTE_SIZE], rem_ptr->msg.len); if (rem_ptr->msg.flags & REMOTE_REPLY) { error = rem_ptr->msg.cmd; break; } else { rwl_sleep(RWL_WIFI_RETRY_DELAY); } } free(rem_ptr); free(list); if (cbuf != NULL) free(cbuf); break; #endif /* RWL_WIFI */ default: DPRINT_ERR(ERR, "rwl_setinformation_fe: Unknown remote_type:%d\n", remote_type); break; } return error; }
/* transport independent entry point for GET ioctls */ int rwl_queryinformation_fe(void *wl, int cmd, void* input_buf, unsigned long *input_len, int debug, int rem_ioctl_select) { int error = 0; uint tx_len; #if defined (RWL_SERIAL) || (RWL_WIFI) rem_ioctl_t *rem_ptr = NULL; #endif #ifdef RWL_WIFI int retry; char *cinput_buf; #endif UNUSED_PARAMETER(debug); switch (remote_type) { case REMOTE_SOCKET: #ifdef RWL_SOCKET /* We don't want the server to allocate bigger buffers * for some of the commands * like scanresults. Server can still allocate 8K memory * and send the response */ if ((int)(*input_len) > SERVER_RESPONSE_MAX_BUF_LEN) *input_len = SERVER_RESPONSE_MAX_BUF_LEN; error = rwl_information_socket(wl, cmd, input_buf, input_len, input_len, rem_ioctl_select); #endif /* RWL_SOCKET */ break; #ifdef RWL_SERIAL /* System serial transport is not supported in Linux. Only XP */ case REMOTE_SERIAL: tx_len = MIN(*input_len, SERVER_RESPONSE_MAX_BUF_LEN); if (remote_CDC_tx(wl, cmd, input_buf, tx_len, tx_len, rem_ioctl_select, debug) < 0) { DPRINT_ERR(ERR, "query_info_fe: Send command failed\n"); return FAIL; } if ((rem_ptr = remote_CDC_rx_hdr(wl, debug)) == NULL) { DPRINT_ERR(ERR, "query_info_fe: Reading CDC header failed\n"); return FAIL; } if (rem_ptr->msg.flags != REMOTE_REPLY) { DPRINT_ERR(ERR, "query_info_fe: response format error.\n"); return FAIL; } if (rem_ptr->msg.len > *input_len) { DPRINT_ERR(ERR, "query_info_fe: needed size(%d) greater than " "actual size(%lu)\n", rem_ptr->msg.len, *input_len); return FAIL; } error = rem_ptr->msg.status; if (error != 0) DPRINT_ERR(ERR, "query_info_fe: remote cdc header return " "error code %d\n", error); if (remote_CDC_rx(wl, rem_ptr, input_buf, *input_len, debug) == -1) { DPRINT_ERR(ERR, "query_info_fe: No results!\n"); return FAIL; } if (rem_ptr->msg.flags & REMOTE_REPLY) error = rem_ptr->msg.cmd; break; #endif /* RWL_SERIAL */ #ifdef RWL_DONGLE case REMOTE_DONGLE: /* We don't want the server to allocate bigger buffers * for some of the commands * like scanresults. Server can still allocate 8K *memory and send the response * in fragments. */ if ((int)(*input_len) > SERVER_RESPONSE_MAX_BUF_LEN) *input_len = SERVER_RESPONSE_MAX_BUF_LEN; /* Actual buffer to be sent should be max 256 bytes as *UART input buffer * is 512 bytes */ tx_len = MIN(*input_len, 256); error = rwl_information_dongle(wl, cmd, input_buf, input_len, tx_len, rem_ioctl_select); break; #endif //ifdef RWL_DONGLE case REMOTE_WIFI: #ifdef RWL_WIFI /* We don't want the server to allocate bigger buffers * for some of the commands * like scanresults. Server can still allocate 8K memory * and send the response * in fragments. */ if ((int)(*input_len) > SERVER_RESPONSE_MAX_BUF_LEN) *input_len = SERVER_RESPONSE_MAX_BUF_LEN; /* Actual buffer to be sent should be max 960 bytes * as wifi max frame size if 960 * and actual data for any command will not exceed 960 bytes */ tx_len = MIN(*input_len, RWL_WIFI_FRAG_DATA_SIZE); if ((rem_ptr = (rem_ioctl_t *)malloc(REMOTE_SIZE)) == NULL) { return FAIL; } if ((cinput_buf = (char*)malloc(tx_len)) == NULL) { DPRINT_ERR(ERR, "Malloc failed for query information fe" "character buf \n"); free(rem_ptr); return FAIL; } memcpy(cinput_buf, (char*)input_buf, tx_len); /* Keep a copy of input_buf */ for (retry = 0; retry < RWL_WIFI_RETRY; retry++) { rwl_wifi_purge_actionframes(wl); if (retry > 3) DPRINT_INFO(OUTPUT, "ir_queryinformation_fe : retry %d" "cmd %d\n", retry, cmd); /* copy back the buffer to input buffer */ memcpy((char*)input_buf, cinput_buf, tx_len); /* Issue the command */ if ((error = remote_CDC_wifi_tx(wl, cmd, input_buf, *input_len, tx_len, rem_ioctl_select)) < 0) { DPRINT_DBG(OUTPUT, "query_info_fe: Send command failed\n"); rwl_sleep(RWL_WIFI_RETRY_DELAY); continue; } if ((error = remote_CDC_DATA_wifi_rx_frag(wl, rem_ptr, *input_len, input_buf, RWL_WIFI_WL_CMD) < 0)) { DPRINT_DBG(OUTPUT, "ir_queryinformation_fe :" "Error in reading the frag bytes\n"); rwl_sleep(RWL_WIFI_RETRY_DELAY); continue; } if (rem_ptr->msg.flags & REMOTE_REPLY) { error = rem_ptr->msg.cmd; break; } else { rwl_sleep(RWL_WIFI_RETRY_DELAY); } } free(rem_ptr); if (cinput_buf) free(cinput_buf); break; #endif /* RWL_WIFI */ default: DPRINT_ERR(ERR, "rwl_queryinformation_fe: Unknown" "remote_type %d\n", remote_type); break; } return error; }
/* Issue shell commands independent of transport type and return result */ static int rwl_shell_information_fe(void *wl, int cmd, uchar* input_buf, unsigned long *input_len) { int error = 0, remote_cmd; uchar* resp_buf = NULL; rem_ioctl_t *rem_ptr = NULL; #ifdef RWL_WIFI char *cbuf, retry; dot11_action_wifi_vendor_specific_t *list; #endif #ifdef RWL_SOCKET int Sockfd; #endif remote_cmd = REMOTE_SHELL_CMD; #ifdef RWLASD if (cmd == ASD_CMD) remote_cmd = REMOTE_ASD_CMD; #endif if (cmd == VISTA_CMD) remote_cmd = REMOTE_VISTA_CMD; switch (remote_type) { case REMOTE_SOCKET: #ifdef RWL_SOCKET if ((Sockfd = rwl_connect_socket_server()) < 0) { DPRINT_ERR(ERR, " Error in getting the SocDes\n"); return BCME_ERROR; } wl = (void *)(&Sockfd); if (remote_CDC_tx(wl, cmd, input_buf, *input_len, *input_len, remote_cmd, 0) < 0) { DPRINT_ERR(ERR, "shell_info_fe: Send command failed\n"); rwl_close_pipe(remote_type, wl); return BCME_ERROR; } /* For backward compatibility for ASD, async and kill commands do the * old way */ if (remote_cmd == REMOTE_SHELL_CMD && !strstr((char*)input_buf, "%") && !strstr((char*)input_buf, "kill")) error = rwl_socket_shellresp(wl, rem_ptr, input_buf); else { if ((rem_ptr = remote_CDC_rx_hdr(wl, 0)) == NULL) { DPRINT_ERR(ERR, "shell_info_fe: Receiving CDC" "header failed\n"); rwl_close_pipe(remote_type, wl); return FAIL; } if ((resp_buf = malloc(rem_ptr->msg.len + 1)) == NULL) { DPRINT_ERR(ERR, "Mem alloc fails\n"); rwl_close_pipe(remote_type, wl); return FAIL; } if (remote_CDC_rx(wl, rem_ptr, resp_buf, rem_ptr->msg.len, 0) == FAIL) { DPRINT_ERR(ERR, "shell_info_fe: No results!\n"); rwl_close_pipe(remote_type, wl); free(resp_buf); return FAIL; } /* print the shell result */ resp_buf[rem_ptr->msg.len] = '\0'; /* The return value of the shell command * will be stored in rem_ptr->msg.cmd * Return that value to the client process */ if (rem_ptr->msg.flags & REMOTE_REPLY) error = rem_ptr->msg.cmd; fputs((char*)resp_buf, stdout); } rwl_close_pipe(remote_type, wl); #endif /* RWL_SOCKET */ break; #if defined( RWL_DONGLE ) || defined( RWL_SERIAL ) case REMOTE_DONGLE: case REMOTE_SERIAL: if (remote_CDC_tx(wl, cmd, input_buf, *input_len, *input_len, remote_cmd, 0) < 0) { DPRINT_ERR(ERR, "shell_info_fe: Send command failed\n"); return FAIL; } /* For backward compatibility for ASD, async and kill commands do the * old way */ // if (remote_cmd != REMOTE_ASD_CMD && !strstr((char*)input_buf, "%") && // !strstr((char*)input_buf, "kill")) // error = rwl_dongle_shellresp(wl, rem_ptr, input_buf, cmd); // else { if ((rem_ptr = remote_CDC_rx_hdr(wl, 0)) == NULL) { DPRINT_ERR(ERR, "shell_info_fe:" "Receiving CDC header failed\n"); return BCME_SERIAL_PORT_ERR; } rwl_swap_header(rem_ptr, NETWORK_TO_HOST); /* In case of shell or ASD commands the response * size is not known in advance * Hence based on response from the server memory is allocated */ if ((resp_buf = malloc(rem_ptr->msg.len + 1)) == NULL) { DPRINT_ERR(ERR, "Mem alloc fails for shell response buffer\n"); return FAIL; } if (rem_ptr->data_len < DATA_FRAME_LEN) { /* Response comes in one shot not in fragments */ if (remote_CDC_rx(wl, rem_ptr, resp_buf, rem_ptr->msg.len, 0) == FAIL) { DPRINT_ERR(ERR, "shell_info_fe: No results!\n"); free(resp_buf); return FAIL; } } else { error = rwl_serial_fragmented_response_fe(wl, rem_ptr, resp_buf, (unsigned long *)&(rem_ptr->msg.len)); } /* print the shell result */ resp_buf[rem_ptr->msg.len] = '\0'; /* The return value of the shell command will be stored in rem_ptr->msg.cmd * Return that value to the client process */ if (rem_ptr->msg.flags & REMOTE_REPLY) error = rem_ptr->msg.cmd; fputs((char*)resp_buf, stdout); } break; #endif //if defined( RWL_DONGLE ) || defined( RWL_SERIAL ) case REMOTE_WIFI: #ifdef RWL_WIFI /* Unlike dongle or UART case the response for wi-fi comes in single frame. * (CDC header + data). Hence the single read is called for header and data. * If any error in reading then we sleep for some time before retrying. */ if ((list = (dot11_action_wifi_vendor_specific_t *) malloc(RWL_WIFI_ACTION_FRAME_SIZE)) == NULL) { return FAIL; } if ((rem_ptr = (rem_ioctl_t *)malloc(REMOTE_SIZE)) == NULL) { free(list); return FAIL; } if ((cbuf = (char*) malloc(*input_len)) == NULL) { DPRINT_ERR(ERR, "Malloc failed for shell response\n"); free(rem_ptr); free(list); return FAIL; } /* copy of the original buf is required for retry */ memcpy(cbuf, (char*)input_buf, *input_len); for (retry = 0; retry < RWL_WIFI_RETRY; retry++) { rwl_wifi_purge_actionframes(wl); if (remote_CDC_tx(wl, cmd, input_buf, *input_len, *input_len, remote_cmd, 0) < 0) { DPRINT_DBG(OUTPUT, "rwl_shell_information_fe(wifi):" "Send command failed\n"); rwl_sleep(RWL_WIFI_RETRY_DELAY); free(rem_ptr); free(list); return FAIL; } /* For backward compatibility for ASD, * async and kill commands do the * old way */ if (remote_cmd == REMOTE_SHELL_CMD && !strstr((char*)input_buf, "%") && !strstr((char*)input_buf, "kill")) { error = rwl_wifi_shellresp(wl, rem_ptr, input_buf); if (rem_ptr->msg.len == 0) break; } else if (remote_cmd == REMOTE_VISTA_CMD) { if ((error = remote_CDC_DATA_wifi_rx_frag(wl, rem_ptr, 0, NULL, RWL_WIFI_SHELL_CMD)) < 0) { DPRINT_DBG(OUTPUT, "rwl_shell_information_fe(wifi):" "error in reading shell response\n"); continue; } if (rem_ptr->msg.flags & REMOTE_REPLY) { error = rem_ptr->msg.cmd; break; } else { rwl_sleep(RWL_WIFI_RETRY_DELAY); continue; } } else { /* ASD commands may take long time to give back * the response (eg: file transfer) */ if (remote_cmd == REMOTE_ASD_CMD) { for (;;) { /* copy back the buffer to input buffer */ memcpy((char*)input_buf, cbuf, *input_len); if ((error = remote_CDC_DATA_wifi_rx_frag( wl, rem_ptr, 0, NULL, RWL_WIFI_SHELL_CMD)) < 0) { DPRINT_DBG(OUTPUT, "rwl_shell_information_fe(wifi):" "err in reading shell response\n"); continue; } if (rem_ptr->msg.flags & REMOTE_REPLY) { error = rem_ptr->msg.cmd; retry = RWL_WIFI_RETRY; break; } else { rwl_sleep(RWL_WIFI_RETRY_DELAY); continue; } } } } } free(rem_ptr); free(list); if (cbuf != NULL) free(cbuf); #endif /* RWL_WIFI */ break; default: break; } /* End of switch (remote_type) */ if (resp_buf) free(resp_buf); return error; }