2 * Common code for remotewl client
4 * Copyright (C) 2010, Broadcom Corporation
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_client_shared.c,v 1.32 2010-01-30 06:03:24 Exp $
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <arpa/inet.h>
28 #include <sys/ioctl.h>
41 #include <proto/ethernet.h>
42 #include <bcmendian.h>
45 #include <proto/802.11.h>
49 #if defined(RWL_WIFI) || defined(WIFI_REFLECTOR)
51 #endif /* defined(RWL_WIFI) || defined(WIFI_REFLECTOR) */
53 #include "wlu_remote.h"
55 #include "wlu_client_shared.h"
57 char* remote_vista_cmds
[] = {"join", "sup_wpa", "wsec", "set_pmk", "legacylink", "list",
58 "disassoc", "xlist", NULL
};
60 #define SHELL_CMD_LEN (256)
63 extern int validate_server_address();
64 static int rwl_socket_shellresp(void *wl
, rem_ioctl_t
*rem_ptr
, uchar
*input_buf
);
66 static int rwl_dongle_shellresp(void *wl
, rem_ioctl_t
*rem_ptr
, uchar
*input_buf
, int cmd
);
68 static int rwl_wifi_shellresp(void *wl
, rem_ioctl_t
*rem_ptr
, uchar
*input_buf
);
70 /* We don't want the server to allocate bigger buffers for some of the commands
71 * like scanresults. Server can still allocate 8K memory and send the response
72 * in fragments. This is used in case of Get commands only.
74 #define SERVER_RESPONSE_MAX_BUF_LEN 8192
76 extern unsigned short g_rwl_servport
;
77 extern char *g_rwl_servIP
;
80 /* dword align allocation */
82 char bufdata
[WLC_IOCTL_MAXLEN
];
85 static char *g_rwl_aligned_buf
= (char*) &bufstruct_wlu
.bufdata
;
87 extern char *g_rwl_buf_mac
;
90 /* Make initial connection from client to server through sockets */
92 rwl_connect_socket_server(void)
95 struct sockaddr_in servAddr
;
96 memset(&servAddr
, 0, sizeof(servAddr
));
97 if ((SockDes
= (*(int *)rwl_open_pipe(remote_type
, "\0", 0, 0))) == FAIL
)
99 if (!validate_server_address())
101 DPRINT_DBG(OUTPUT
, "ServerIP:%s,ServerPort:%d\n", g_rwl_servIP
, g_rwl_servport
);
102 servAddr
.sin_family
= AF_INET
;
103 servAddr
.sin_port
= hton16(g_rwl_servport
);
104 servAddr
.sin_addr
.s_addr
= inet_addr(g_rwl_servIP
);
106 if (rwl_sockconnect(SockDes
, (struct sockaddr
*)&servAddr
, sizeof(servAddr
)) < 0) {
107 rwl_close_pipe(remote_type
, (void*) &SockDes
);
113 /* This routine is used for both Get and Set Ioctls for the socket */
115 rwl_information_socket(void *wl
, int cmd
, void* input_buf
, unsigned long *input_len
,
116 unsigned long *tx_len
, uint flags
)
119 rem_ioctl_t
*rem_ptr
= NULL
;
121 if ((Sockfd
= rwl_connect_socket_server()) < 0) {
122 DPRINT_ERR(ERR
, "Error in getting the Socket Descriptor\n");
125 wl
= (void *)(&Sockfd
);
127 if (remote_CDC_tx(wl
, cmd
, input_buf
, *input_len
,
128 *tx_len
, flags
, 0) < 0) {
129 DPRINT_ERR(ERR
, "query_info_fe: Send command failed\n");
130 rwl_close_pipe(remote_type
, wl
);
134 if ((rem_ptr
= remote_CDC_rx_hdr(wl
, 0)) == NULL
) {
135 DPRINT_ERR(ERR
, "query_info_fe: Reading CDC header failed\n");
136 rwl_close_pipe(remote_type
, wl
);
139 rwl_swap_header(rem_ptr
, NETWORK_TO_HOST
);
141 if (rem_ptr
->msg
.len
> *input_len
) {
142 DPRINT_ERR(ERR
, "query_info_fe: needed size(%d) > "
143 "actual size(%ld)\n", rem_ptr
->msg
.len
, *input_len
);
144 rwl_close_pipe(remote_type
, wl
);
148 if (remote_CDC_rx(wl
, rem_ptr
, input_buf
, *input_len
, 0) == FAIL
) {
149 DPRINT_ERR(ERR
, "query_info_fe: No results!\n");
150 rwl_close_pipe(remote_type
, wl
);
154 if (rem_ptr
->msg
.flags
& REMOTE_REPLY
)
155 error
= rem_ptr
->msg
.cmd
;
159 rwl_close_pipe(remote_type
, wl
);
163 #endif /* RWL_SOCKET */
165 * Receives the fragmented response from serial server.
166 * Called from rwl_queryinformation_fe front end function for dongle case only when
167 * the client expects data in chunks more than DATA_FRAME_LEN * (960) bytes.
170 rwl_serial_fragmented_response_fe(void *wl
, rem_ioctl_t
*rem_ptr
, void* input_buf
,
171 unsigned long *bytes_to_read
)
174 uint32 total_numread
;
175 uchar
*local_buf
, *local_result
;
176 uint frames_to_read
, frame_count
;
178 DPRINT_DBG(OUTPUT
, "rem_ptr->msg.len=%d \t rem_ptr->data_len=%d\n",
179 rem_ptr
->msg
.len
, rem_ptr
->data_len
);
181 /* Calculate the number of frames for the response */
182 if (rem_ptr
->data_len
== 0) {
183 DPRINT_ERR(ERR
, "data_len is:%d\n", rem_ptr
->data_len
);
186 frames_to_read
= (*bytes_to_read
)/rem_ptr
->data_len
;
187 if ((*bytes_to_read
) % rem_ptr
->data_len
> 0)
190 DPRINT_DBG(OUTPUT
, "No of frames=%d\n", frames_to_read
);
192 if ((local_result
= (uchar
*)malloc(rem_ptr
->msg
.len
)) == NULL
) {
193 DPRINT_ERR(ERR
, "Malloc failed for serial fragmented frame"
198 /* Response will come in DATA_FRAME_LEN + REMOTE_SIZE (960+16) bytes
199 * packet with CDC header and then followed by response.
203 while (total_numread
!= *bytes_to_read
) {
204 local_buf
= (uchar
*)malloc(rem_ptr
->data_len
);
205 if (local_buf
== NULL
) {
210 DPRINT_DBG(OUTPUT
, "Total bytes=%d\n", total_numread
);
211 DPRINT_DBG(OUTPUT
, "Frame (Reverse):%d\n", frames_to_read
);
213 if (remote_CDC_rx(wl
, rem_ptr
, local_buf
, rem_ptr
->data_len
, 0) == -1) {
219 /* Concatenate the response to loc_res. */
220 memcpy(&local_result
[frame_count
*DATA_FRAME_LEN
], local_buf
,
223 total_numread
+= rem_ptr
->data_len
;
227 DPRINT_DBG(OUTPUT
, "Total bytes=%d\n", total_numread
);
229 if (frames_to_read
== 0) {
230 /* When all the frames are received copy the data to original buf */
231 memcpy(input_buf
, local_result
, total_numread
);
232 if (rem_ptr
->msg
.flags
& REMOTE_REPLY
) {
233 error
= rem_ptr
->msg
.cmd
;
237 if (total_numread
!= *bytes_to_read
) {
238 /* Receive the next header */
239 if ((rem_ptr
= remote_CDC_rx_hdr(wl
, 0)) == NULL
) {
240 DPRINT_ERR(ERR
, "query_info_fe: Reading CDC header failed");
249 /* This routine is common to both set and Get Ioctls for the dongle case */
251 rwl_information_dongle(void *wl
, int cmd
, void* input_buf
, unsigned long *input_len
,
252 uint tx_len
, uint flags
)
255 rem_ioctl_t
*rem_ptr
= NULL
;
257 if (remote_CDC_tx(wl
, cmd
, input_buf
, *input_len
,
258 tx_len
, flags
, 0) < 0) {
259 DPRINT_ERR(ERR
, "query_info_fe: Send command failed\n");
264 if ((rem_ptr
= remote_CDC_rx_hdr(wl
, 0)) == NULL
) {
265 DPRINT_ERR(ERR
, "query_info_fe: Reading CDC header failed\n");
266 return SERIAL_PORT_ERR
;
269 /* Make sure there is enough room */
270 if (rem_ptr
->msg
.len
> *input_len
) {
271 DPRINT_DBG(OUTPUT
, "query_info_fe: needed size(%d) > actual"
272 "size(%ld)\n", rem_ptr
->msg
.len
, *input_len
);
276 /* We can grab short frames all at once. Longer frames (> 960 bytes)
279 if (rem_ptr
->data_len
< DATA_FRAME_LEN
) {
280 if (remote_CDC_rx(wl
, rem_ptr
, input_buf
, *input_len
, 0) == FAIL
) {
281 DPRINT_ERR(ERR
, "query_info_fe: No results!\n");
284 if (rem_ptr
->msg
.flags
& REMOTE_REPLY
)
285 error
= rem_ptr
->msg
.cmd
;
289 /* rwl_serial_fragmented_response_fe returns either valid number or FAIL.
290 * In any case return the same value to caller
292 error
= rwl_serial_fragmented_response_fe(wl
, rem_ptr
, input_buf
, input_len
);
296 /* Handler to signal the reader thread that ctrl-C is pressed */
298 volatile sig_atomic_t g_sig_ctrlc
= 1;
299 void ctrlc_handler(int num
)
301 UNUSED_PARAMETER(num
);
308 /* Issue shell commands independent of transport type and return result */
310 rwl_shell_information_fe(void *wl
, int cmd
, uchar
* input_buf
, unsigned long *input_len
)
312 int error
, remote_cmd
;
313 uchar
* resp_buf
= NULL
;
314 rem_ioctl_t
*rem_ptr
= NULL
;
318 dot11_action_wifi_vendor_specific_t
*list
;
325 remote_cmd
= REMOTE_SHELL_CMD
;
329 remote_cmd
= REMOTE_ASD_CMD
;
331 if (cmd
== VISTA_CMD
)
332 remote_cmd
= REMOTE_VISTA_CMD
;
334 switch (remote_type
) {
337 if ((Sockfd
= rwl_connect_socket_server()) < 0) {
338 DPRINT_ERR(ERR
, " Error in getting the SocDes\n");
342 wl
= (void *)(&Sockfd
);
343 if (remote_CDC_tx(wl
, cmd
, input_buf
, *input_len
, *input_len
,
344 remote_cmd
, 0) < 0) {
345 DPRINT_ERR(ERR
, "shell_info_fe: Send command failed\n");
346 rwl_close_pipe(remote_type
, wl
);
349 /* For backward compatibility for ASD, async and kill commands do the
352 if (remote_cmd
== REMOTE_SHELL_CMD
&& !strstr((char*)input_buf
, "%") &&
353 !strstr((char*)input_buf
, "kill"))
354 error
= rwl_socket_shellresp(wl
, rem_ptr
, input_buf
);
356 if ((rem_ptr
= remote_CDC_rx_hdr(wl
, 0)) == NULL
) {
357 DPRINT_ERR(ERR
, "shell_info_fe: Receiving CDC"
359 rwl_close_pipe(remote_type
, wl
);
363 if ((resp_buf
= malloc(rem_ptr
->msg
.len
+ 1)) == NULL
) {
364 DPRINT_ERR(ERR
, "Mem alloc fails\n");
365 rwl_close_pipe(remote_type
, wl
);
369 if (remote_CDC_rx(wl
, rem_ptr
, resp_buf
,
370 rem_ptr
->msg
.len
, 0) == FAIL
) {
371 DPRINT_ERR(ERR
, "shell_info_fe: No results!\n");
372 rwl_close_pipe(remote_type
, wl
);
377 /* print the shell result */
378 resp_buf
[rem_ptr
->msg
.len
] = '\0';
379 /* The return value of the shell command
380 * will be stored in rem_ptr->msg.cmd
381 * Return that value to the client process
383 if (rem_ptr
->msg
.flags
& REMOTE_REPLY
)
384 error
= rem_ptr
->msg
.cmd
;
385 fputs((char*)resp_buf
, stdout
);
387 rwl_close_pipe(remote_type
, wl
);
388 #endif /* RWL_SOCKET */
392 if (remote_CDC_tx(wl
, cmd
, input_buf
, *input_len
, *input_len
,
393 remote_cmd
, 0) < 0) {
394 DPRINT_ERR(ERR
, "shell_info_fe: Send command failed\n");
398 /* For backward compatibility for ASD, async and kill commands do the
401 if (remote_cmd
!= REMOTE_ASD_CMD
&& !strstr((char*)input_buf
, "%") &&
402 !strstr((char*)input_buf
, "kill"))
403 error
= rwl_dongle_shellresp(wl
, rem_ptr
, input_buf
, cmd
);
405 if ((rem_ptr
= remote_CDC_rx_hdr(wl
, 0)) == NULL
) {
406 DPRINT_ERR(ERR
, "shell_info_fe:"
407 "Receiving CDC header failed\n");
408 return SERIAL_PORT_ERR
;
410 rwl_swap_header(rem_ptr
, NETWORK_TO_HOST
);
411 /* In case of shell or ASD commands the response
412 * size is not known in advance
413 * Hence based on response from the server memory is allocated
415 if ((resp_buf
= malloc(rem_ptr
->msg
.len
+ 1)) == NULL
) {
416 DPRINT_ERR(ERR
, "Mem alloc fails for shell response buffer\n");
420 if (rem_ptr
->data_len
< DATA_FRAME_LEN
) {
421 /* Response comes in one shot not in fragments */
422 if (remote_CDC_rx(wl
, rem_ptr
, resp_buf
,
423 rem_ptr
->msg
.len
, 0) == FAIL
) {
424 DPRINT_ERR(ERR
, "shell_info_fe: No results!\n");
429 error
= rwl_serial_fragmented_response_fe(wl
, rem_ptr
,
430 resp_buf
, (unsigned long *)&(rem_ptr
->msg
.len
));
432 /* print the shell result */
433 resp_buf
[rem_ptr
->msg
.len
] = '\0';
434 /* The return value of the shell command will be stored in rem_ptr->msg.cmd
435 * Return that value to the client process
437 if (rem_ptr
->msg
.flags
& REMOTE_REPLY
)
438 error
= rem_ptr
->msg
.cmd
;
439 fputs((char*)resp_buf
, stdout
);
445 /* Unlike dongle or UART case the response for wi-fi comes in single frame.
446 * (CDC header + data). Hence the single read is called for header and data.
447 * If any error in reading then we sleep for some time before retrying.
449 if ((list
= (dot11_action_wifi_vendor_specific_t
*)
450 malloc(RWL_WIFI_ACTION_FRAME_SIZE
)) == NULL
) {
453 if ((rem_ptr
= (rem_ioctl_t
*)malloc(REMOTE_SIZE
)) == NULL
) {
458 if ((cbuf
= (char*) malloc(*input_len
)) == NULL
) {
459 DPRINT_ERR(ERR
, "Malloc failed for shell response\n");
465 /* copy of the original buf is required for retry */
466 memcpy(cbuf
, (char*)input_buf
, *input_len
);
467 for (retry
= 0; retry
< RWL_WIFI_RETRY
; retry
++) {
469 rwl_wifi_purge_actionframes(wl
);
470 if (remote_CDC_tx(wl
, cmd
, input_buf
, *input_len
, *input_len
,
471 remote_cmd
, 0) < 0) {
472 DPRINT_DBG(OUTPUT
, "rwl_shell_information_fe(wifi):"
473 "Send command failed\n");
474 rwl_sleep(RWL_WIFI_RETRY_DELAY
);
479 /* For backward compatibility for ASD,
480 * async and kill commands do the
483 if (remote_cmd
== REMOTE_SHELL_CMD
&&
484 !strstr((char*)input_buf
, "%") &&
485 !strstr((char*)input_buf
, "kill")) {
486 error
= rwl_wifi_shellresp(wl
, rem_ptr
, input_buf
);
487 if (rem_ptr
->msg
.len
== 0)
490 else if (remote_cmd
== REMOTE_VISTA_CMD
) {
491 if ((error
= remote_CDC_DATA_wifi_rx_frag(wl
, rem_ptr
, 0,
492 NULL
, RWL_WIFI_SHELL_CMD
)) < 0) {
493 DPRINT_DBG(OUTPUT
, "rwl_shell_information_fe(wifi):"
494 "error in reading shell response\n");
497 if (rem_ptr
->msg
.flags
& REMOTE_REPLY
) {
498 error
= rem_ptr
->msg
.cmd
;
501 rwl_sleep(RWL_WIFI_RETRY_DELAY
);
506 /* ASD commands may take long time to give back
507 * the response (eg: file transfer)
509 if (remote_cmd
== REMOTE_ASD_CMD
) {
511 /* copy back the buffer to input buffer */
512 memcpy((char*)input_buf
, cbuf
, *input_len
);
514 if ((error
= remote_CDC_DATA_wifi_rx_frag(
515 wl
, rem_ptr
, 0, NULL
,
516 RWL_WIFI_SHELL_CMD
)) < 0) {
518 "rwl_shell_information_fe(wifi):"
519 "err in reading shell response\n");
522 if (rem_ptr
->msg
.flags
& REMOTE_REPLY
) {
523 error
= rem_ptr
->msg
.cmd
;
524 retry
= RWL_WIFI_RETRY
;
527 rwl_sleep(RWL_WIFI_RETRY_DELAY
);
539 #endif /* RWL_WIFI */
544 } /* End of switch (remote_type) */
552 /* Prepare to issue shell command */
554 rwl_shell_cmd_proc(void *wl
, char **argv
, int cmd
)
557 unsigned long len
= SHELL_CMD_LEN
;
560 if ((buff
= malloc(SHELL_CMD_LEN
)) == NULL
) {
561 DPRINT_ERR(ERR
, "\n Mem alloc fails for shell cmd buffer\n");
565 memset(buff
, 0, sizeof(SHELL_CMD_LEN
));
567 strcat((char*)buff
, *argv
);
570 strcat((char*)buff
, " "); /* leave space between args */
573 err
= rwl_shell_information_fe(wl
, cmd
, buff
, &len
);
578 /* transport independent entry point for GET ioctls */
580 rwl_queryinformation_fe(void *wl
, int cmd
, void* input_buf
,
581 unsigned long *input_len
, int debug
, int rem_ioctl_select
) {
584 #if defined(RWL_SERIAL) || RWL_WIFI
585 rem_ioctl_t
*rem_ptr
= NULL
;
593 UNUSED_PARAMETER(debug
);
595 switch (remote_type
) {
598 /* We don't want the server to allocate bigger buffers
599 * for some of the commands
600 * like scanresults. Server can still allocate 8K memory
601 * and send the response
603 if (*input_len
> SERVER_RESPONSE_MAX_BUF_LEN
)
604 *input_len
= SERVER_RESPONSE_MAX_BUF_LEN
;
605 error
= rwl_information_socket(wl
, cmd
, input_buf
, input_len
,
606 input_len
, rem_ioctl_select
);
607 #endif /* RWL_SOCKET */
611 /* System serial transport is not supported in Linux. Only XP */
614 tx_len
= MIN(*input_len
, 512);
616 tx_len
= MIN(*input_len
, 1024);
618 /* Time estimate assumes 115K baud */
619 if (*input_len
> (1024 *10))
620 /* Multiply by 2. The buffer has to go there and back */
621 DPRINT_DBG(OUTPUT
, "Wait time: %lu seconds\n",
622 ((*input_len
)+ tx_len
) / (115200/8));
624 if (remote_CDC_tx(wl
, cmd
, input_buf
, *input_len
,
625 tx_len
, rem_ioctl_select
, debug
) < 0) {
626 DPRINT_ERR(ERR
, "query_info_fe: Send command failed\n");
630 if ((rem_ptr
= remote_CDC_rx_hdr(wl
, debug
)) == NULL
) {
631 DPRINT_ERR(ERR
, "query_info_fe: Reading CDC header failed\n");
635 if (rem_ptr
->msg
.flags
!= REMOTE_REPLY
) {
636 DPRINT_ERR(ERR
, "query_info_fe: response format error.\n");
639 if (rem_ptr
->msg
.len
> *input_len
) {
640 DPRINT_ERR(ERR
, "query_info_fe: needed size(%d) greater than "
641 "actual size(%lu)\n", rem_ptr
->msg
.len
, *input_len
);
646 DPRINT_ERR(ERR
, "query_info_fe: remote cdc header return "
647 "error code %d\n", error
);
648 if (remote_CDC_rx(wl
, rem_ptr
, input_buf
, *input_len
, debug
) == -1) {
649 DPRINT_ERR(ERR
, "query_info_fe: No results!\n");
652 if (rem_ptr
->msg
.flags
& REMOTE_REPLY
)
653 error
= rem_ptr
->msg
.cmd
;
656 #endif /* RWL_SERIAL */
658 /* We don't want the server to allocate bigger buffers
659 * for some of the commands
660 * like scanresults. Server can still allocate 8K
661 *memory and send the response
664 if (*input_len
> SERVER_RESPONSE_MAX_BUF_LEN
)
665 *input_len
= SERVER_RESPONSE_MAX_BUF_LEN
;
667 /* Actual buffer to be sent should be max 256 bytes as
671 tx_len
= MIN(*input_len
, 256);
672 error
= rwl_information_dongle(wl
, cmd
, input_buf
, input_len
,
673 tx_len
, rem_ioctl_select
);
679 /* We don't want the server to allocate bigger buffers
680 * for some of the commands
681 * like scanresults. Server can still allocate 8K memory
682 * and send the response
685 if (*input_len
> SERVER_RESPONSE_MAX_BUF_LEN
)
686 *input_len
= SERVER_RESPONSE_MAX_BUF_LEN
;
688 /* Actual buffer to be sent should be max 960 bytes
689 * as wifi max frame size if 960
690 * and actual data for any command will not exceed 960 bytes
692 tx_len
= MIN(*input_len
, RWL_WIFI_FRAG_DATA_SIZE
);
694 if ((rem_ptr
= (rem_ioctl_t
*)malloc(REMOTE_SIZE
)) == NULL
) {
697 if ((cinput_buf
= (char*)malloc(tx_len
)) == NULL
) {
698 DPRINT_ERR(ERR
, "Malloc failed for query information fe"
704 memcpy(cinput_buf
, (char*)input_buf
, tx_len
); /* Keep a copy of input_buf */
706 for (retry
= 0; retry
< RWL_WIFI_RETRY
; retry
++) {
708 rwl_wifi_purge_actionframes(wl
);
711 DPRINT_INFO(OUTPUT
, "ir_queryinformation_fe : retry %d"
712 "cmd %d\n", retry
, cmd
);
714 /* copy back the buffer to input buffer */
715 memcpy((char*)input_buf
, cinput_buf
, tx_len
);
717 /* Issue the command */
718 if ((error
= remote_CDC_wifi_tx(wl
, cmd
, input_buf
,
719 *input_len
, tx_len
, rem_ioctl_select
)) < 0) {
720 DPRINT_DBG(OUTPUT
, "query_info_fe: Send command failed\n");
721 rwl_sleep(RWL_WIFI_RETRY_DELAY
);
725 if ((error
= remote_CDC_DATA_wifi_rx_frag(wl
, rem_ptr
,
726 *input_len
, input_buf
, RWL_WIFI_WL_CMD
) < 0)) {
727 DPRINT_DBG(OUTPUT
, "ir_queryinformation_fe :"
728 "Error in reading the frag bytes\n");
729 rwl_sleep(RWL_WIFI_RETRY_DELAY
);
733 if (rem_ptr
->msg
.flags
& REMOTE_REPLY
) {
734 error
= rem_ptr
->msg
.cmd
;
737 rwl_sleep(RWL_WIFI_RETRY_DELAY
);
745 #endif /* RWL_WIFI */
747 DPRINT_ERR(ERR
, "rwl_queryinformation_fe: Unknown"
748 "remote_type %d\n", remote_type
);
755 * This is the front end query function for Set Ioctls. This is used by clients
756 for executing Set Ioctls.
759 rwl_setinformation_fe(void *wl
, int cmd
, void* buf
,
760 unsigned long *len
, int debug
, int rem_ioctl_select
) {
763 #if defined(RWL_SERIAL) || RWL_WIFI
764 rem_ioctl_t
*rem_ptr
= NULL
;
768 dot11_action_wifi_vendor_specific_t
*list
= NULL
;
772 UNUSED_PARAMETER(debug
);
774 switch (remote_type
) {
777 error
= rwl_information_socket(wl
, cmd
, buf
, len
, len
, rem_ioctl_select
);
782 if (*len
> (1024 *10))
783 DPRINT_DBG(OUTPUT
, "Wait time: %lu seconds\n", (*len
)/(115200/8));
785 if (remote_CDC_tx(wl
, cmd
, buf
, *len
, *len
, rem_ioctl_select
, debug
) < 0) {
786 DPRINT_ERR(ERR
, "set_info_fe: Send command failed\n");
790 if ((rem_ptr
= remote_CDC_rx_hdr(wl
, debug
)) == NULL
) {
791 DPRINT_ERR(ERR
, "set_info_fe: Reading CDC header failed\n");
795 if (rem_ptr
->msg
.flags
!= REMOTE_REPLY
) {
796 DPRINT_ERR(ERR
, "set_info_fe: response format error.\n");
800 if (rem_ptr
->msg
.len
> *len
) {
801 DPRINT_ERR(ERR
, "set_info_fe: needed size (%d) greater than "
802 "actual size (%lu)\n", rem_ptr
->msg
.len
, *len
);
807 DPRINT_ERR(ERR
, "set_info_fe: remote cdc header return "
808 "error code (%d)\n", error
);
810 if (remote_CDC_rx(wl
, rem_ptr
, buf
, rem_ptr
->msg
.len
, debug
) == -1) {
811 DPRINT_ERR(ERR
, "set_info_fe: fetching results failed\n");
815 if (rem_ptr
->msg
.flags
& REMOTE_REPLY
)
816 error
= rem_ptr
->msg
.cmd
;
818 #endif /* RWL_SERIAL */
820 if (*len
> SERVER_RESPONSE_MAX_BUF_LEN
)
821 *len
= SERVER_RESPONSE_MAX_BUF_LEN
;
823 /* Actual buffer to be sent should be max 256 bytes as
827 tx_len
= MIN(*len
, 512);
828 error
= rwl_information_dongle(wl
, cmd
, buf
, len
, tx_len
, rem_ioctl_select
);
833 if (*len
> SERVER_RESPONSE_MAX_BUF_LEN
)
834 *len
= SERVER_RESPONSE_MAX_BUF_LEN
;
836 /* Actual buffer to be sent should be max 960 bytes
837 * as wifi max frame size if 960
838 * and actual data for any command will not exceed 960 bytes
840 tx_len
= MIN(*len
, RWL_WIFI_FRAG_DATA_SIZE
);
842 if ((cbuf
= (char*) malloc(tx_len
)) == NULL
) {
843 DPRINT_ERR(ERR
, "Malloc failed for set_info_fe character buf\n");
846 if ((list
= (dot11_action_wifi_vendor_specific_t
*)
847 malloc(RWL_WIFI_ACTION_FRAME_SIZE
)) == NULL
) {
852 if ((rem_ptr
= (rem_ioctl_t
*)malloc(sizeof(rem_ioctl_t
))) == NULL
) {
858 memcpy(cbuf
, (char*)buf
, tx_len
);
860 for (retry
= 0; retry
< RWL_WIFI_RETRY
; retry
++) {
862 rwl_wifi_purge_actionframes(wl
);
863 /* copy back the buffer to input buffer */
864 memcpy((char*)buf
, (char*)cbuf
, tx_len
);
867 DPRINT_INFO(OUTPUT
, "retry %d cmd %d\n", retry
, cmd
);
869 if ((error
= remote_CDC_wifi_tx(wl
, cmd
, buf
, *len
,
870 tx_len
, rem_ioctl_select
) < 0)) {
871 DPRINT_ERR(ERR
, "ir_setinformation_fe: Send"
873 rwl_sleep(RWL_WIFI_RETRY_DELAY
);
877 if ((char*)buf
!= NULL
) {
878 /* In case cmd is findserver, response is not
879 * required from the server
881 if (!strcmp((char*)buf
, RWL_WIFI_FIND_SER_CMD
)) {
886 /* Read the CDC header and data of for the sent cmd
889 if ((error
= remote_CDC_DATA_wifi_rx((void*)wl
, list
) < 0)) {
890 DPRINT_ERR(ERR
, "ir_setinformation_fe: failed to read"
892 rwl_sleep(RWL_WIFI_RETRY_DELAY
);
896 memcpy((char*)rem_ptr
,
897 (char*)&list
->data
[RWL_WIFI_CDC_HEADER_OFFSET
],
899 rwl_swap_header(rem_ptr
, NETWORK_TO_HOST
);
901 memcpy((char*)buf
, (char*)&list
->data
[REMOTE_SIZE
],
904 if (rem_ptr
->msg
.flags
& REMOTE_REPLY
) {
905 error
= rem_ptr
->msg
.cmd
;
908 rwl_sleep(RWL_WIFI_RETRY_DELAY
);
916 #endif /* RWL_WIFI */
918 DPRINT_ERR(ERR
, "rwl_setinformation_fe: Unknown remote_type:%d\n",
928 rwl_var_getbuf(void *wl
, const char *iovar
, void *param
, int param_len
, void **bufptr
)
932 memset((char*)g_rwl_aligned_buf
, 0, WLC_IOCTL_MAXLEN
);
933 strcpy(g_rwl_aligned_buf
, iovar
);
935 /* include the null */
936 len
= strlen(iovar
) + 1;
939 memcpy(&g_rwl_aligned_buf
[len
], param
, param_len
);
941 *bufptr
= g_rwl_aligned_buf
;
942 /* When user wants to execute local CMD being in remote wifi mode,
943 * rwl_wifi_swap_remote_type fucntion is used to change the remote types.
945 rwl_wifi_swap_remote_type(remote_type
);
947 error
= wl_get(wl
, WLC_GET_VAR
, &g_rwl_aligned_buf
[0], WLC_IOCTL_MAXLEN
);
948 /* revert back to the old remote type */
949 rwl_wifi_swap_remote_type(remote_type
);
954 rwl_var_setbuf(void *wl
, const char *iovar
, void *param
, int param_len
)
958 memset(g_rwl_aligned_buf
, 0, WLC_IOCTL_MAXLEN
);
959 strcpy(g_rwl_aligned_buf
, iovar
);
961 /* include the null */
962 len
= strlen(iovar
) + 1;
965 memcpy(&g_rwl_aligned_buf
[len
], param
, param_len
);
968 /* When user wants to execute local CMD being in remote wifi mode,
969 * rwl_wifi_swap_remote_type fucntion is used to change the remote types.
971 rwl_wifi_swap_remote_type(remote_type
);
972 error
= wl_set(wl
, WLC_SET_VAR
, &g_rwl_aligned_buf
[0], len
);
973 /* revert back to the old type */
974 rwl_wifi_swap_remote_type(remote_type
);
978 /* This function will send the buffer to the dongle driver */
980 rwl_var_send_vs_actionframe(void* wl
, const char* iovar
, void* param
, int param_len
)
984 memset(g_rwl_aligned_buf
, 0, WLC_IOCTL_MAXLEN
);
985 strcpy(g_rwl_aligned_buf
, iovar
);
987 /* include the null */
988 len
= strlen(iovar
) + 1;
991 memcpy((void*)&g_rwl_aligned_buf
[len
+ OFFSETOF(wl_action_frame_t
, data
)],
995 /* Set the PacketID (not used by remote WL */
996 memset((void*)&g_rwl_aligned_buf
[len
+ OFFSETOF(wl_action_frame_t
, packetId
)], 0, 4);
998 /* Set the dest addr */
999 memcpy((void*)&g_rwl_aligned_buf
[len
+ OFFSETOF(wl_action_frame_t
, da
)],
1000 (void*)g_rwl_buf_mac
,
1003 /* set the length */
1004 memcpy((void*)&g_rwl_aligned_buf
[len
+ OFFSETOF(wl_action_frame_t
, len
)],
1008 len
+= param_len
+ ETHER_ADDR_LEN
+ 2 + 4;
1010 /* When user wants to execute local CMD being in remote wifi mode,
1011 * rwl_wifi_swap_remote_type fucntion is used to change the remote types.
1013 rwl_wifi_swap_remote_type(remote_type
);
1015 error
= wl_set(wl
, WLC_SET_VAR
, &g_rwl_aligned_buf
[0], len
);
1016 /* revert back to the old type */
1017 rwl_wifi_swap_remote_type(remote_type
);
1020 #endif /* RWL_WIFI */
1022 * Function for printing the usage if user type invalid command line
1023 * options(e.g wl --serial or --dongle or --socket or --wifi)
1026 rwl_usage(int remote_type
)
1028 switch (remote_type
) {
1030 fprintf(stderr
, " Usage: wl/dhd [--linuxdut/linux] [--debug]");
1031 fprintf(stderr
, " [--serial port no]");
1032 fprintf(stderr
, "[--ReadTimeout n] [--interactive] [--clientbatch] \n");
1033 fprintf(stderr
, "\t--linuxdut/linux removes the WLC_OID_BASE");
1034 fprintf(stderr
, "when sending the IOCTL command \n");
1035 fprintf(stderr
, "\t--debug prints out tx packets sending down ");
1036 fprintf(stderr
, " the serial line, and other debug info \n");
1037 fprintf(stderr
, "\t--serial enables the remoteWL serial port number\n");
1038 fprintf(stderr
, "\t--interactive enables using WL in interactive mode\n");
1039 fprintf(stderr
, "\t--clientbatch enables command batchinng on the client,");
1040 fprintf(stderr
, " the default is batching on driver\n");
1043 fprintf(stderr
, " Usage: wl/dhd --dongle <Device Name> <command>\n");
1044 fprintf(stderr
, "\t<Device Name> COM1/COM2 (WinXP) or /dev/ttyS0"
1045 " or /dev/ttyS1 (Linux)\n");
1046 fprintf(stderr
, "\t<command> - wl, shell or dhd command\n");
1047 fprintf(stderr
, "\tDepending on the client you are using(wl or dhd)\n");
1048 fprintf(stderr
, "\t\t shell command usage: sh <command>\n");
1051 fprintf(stderr
, " Usage: wl/dhd --socket <IP ADDRESS> <PORT>\n");
1052 fprintf(stderr
, "\t<IPADDRESS> IP address of server machine\n");
1053 fprintf(stderr
, "\t<PORT> Port no of server\n");
1054 fprintf(stderr
, "\t<command> - wl, shell or dhd command\n");
1055 fprintf(stderr
, "\tDepending on the client you are using(wl or dhd)\n");
1056 fprintf(stderr
, "\t\t shell command usage: sh <command>\n");
1059 fprintf(stderr
, " Usage: wl/dhd --wifi <MAC Address> <command>\n");
1060 fprintf(stderr
, "\t<MAC Address> MAC Address\n");
1061 fprintf(stderr
, "\t<command> - wl, shell or dhd command\n");
1062 fprintf(stderr
, "\tDepending on the client you are using(wl or dhd)\n");
1063 fprintf(stderr
, "\t\t shell command usage: sh <command>\n");
1071 rwl_socket_shellresp(void *wl
, rem_ioctl_t
*rem_ptr
, uchar
*input_buf
)
1073 uchar
* resp_buf
= NULL
;
1074 int pid
, msg_len
, error
;
1076 g_child_pid
= pid
= rwl_shell_createproc(wl
);
1078 while (g_sig_ctrlc
);
1079 remote_CDC_tx(wl
, 0, input_buf
, 0, 0, CTRLC_FLAG
, 0);
1084 if ((rem_ptr
= remote_CDC_rx_hdr(wl
, 0)) == NULL
) {
1085 DPRINT_ERR(ERR
, "rwl_socket_shellresp: Receiving CDC"
1087 rwl_close_pipe(remote_type
, wl
);
1090 msg_len
= rem_ptr
->msg
.len
;
1091 if ((resp_buf
= malloc(rem_ptr
->msg
.len
+ 1)) == NULL
) {
1092 DPRINT_ERR(ERR
, "rwl_socket_shellresp: Mem alloc fails\n");
1093 rwl_close_pipe(remote_type
, wl
);
1097 if (remote_CDC_rx(wl
, rem_ptr
, resp_buf
,
1098 rem_ptr
->msg
.len
, 0) == FAIL
) {
1099 DPRINT_ERR(ERR
, "rwl_socket_shellresp: No results!\n");
1100 rwl_close_pipe(remote_type
, wl
);
1105 /* print the shell result */
1106 resp_buf
[rem_ptr
->msg
.len
] = '\0';
1107 /* The return value of the shell command
1108 * will be stored in rem_ptr->msg.cmd
1109 * Return that value to the client process
1111 if (rem_ptr
->msg
.flags
& REMOTE_REPLY
)
1112 error
= rem_ptr
->msg
.cmd
;
1113 write(1, resp_buf
, msg_len
);
1115 rwl_shell_killproc(pid
);
1118 #endif /* RWL_SOCKET */
1119 /* For wifi shell responses read data until server stops sending */
1122 rwl_wifi_shellresp(void *wl
, rem_ioctl_t
*rem_ptr
, uchar
*input_buf
)
1124 int pid
, msg_len
, error
;
1126 g_child_pid
= pid
= rwl_shell_createproc(wl
);
1129 while (g_sig_ctrlc
);
1130 remote_CDC_tx(wl
, 0, input_buf
, 0, 0, CTRLC_FLAG
, 0);
1135 if ((error
= remote_CDC_DATA_wifi_rx_frag(wl
, rem_ptr
, 0,
1136 NULL
, RWL_WIFI_SHELL_CMD
)) < 0) {
1137 DPRINT_DBG(OUTPUT
, "rwl_shell_information_fe(wifi):"
1138 "error in reading shell response\n");
1141 msg_len
= rem_ptr
->msg
.len
;
1142 error
= rem_ptr
->msg
.cmd
;
1145 rwl_shell_killproc(pid
);
1148 #endif /* RWL_WIFI */
1150 /* For dongle or system serial shell responses read data until server stops sending */
1152 rwl_dongle_shellresp(void *wl
, rem_ioctl_t
*rem_ptr
, uchar
*input_buf
, int cmd
)
1154 int pid
, msg_len
, error
;
1158 g_child_pid
= pid
= rwl_shell_createproc(wl
);
1160 while (g_sig_ctrlc
);
1161 remote_CDC_tx(wl
, cmd
, input_buf
, 0, 0, CTRLC_FLAG
, 0);
1166 if ((rem_ptr
= remote_CDC_rx_hdr(wl
, 0)) == NULL
) {
1167 DPRINT_ERR(ERR
, "shell_info_fe: Receiving CDC header failed\n");
1168 return SERIAL_PORT_ERR
;
1170 /* In case of shell or ASD commands the response size is not known in advance
1171 * Hence based on response from the server memory is allocated
1173 msg_len
= rem_ptr
->msg
.len
;
1174 if ((resp_buf
= malloc(rem_ptr
->msg
.len
+ 1)) == NULL
) {
1175 DPRINT_ERR(ERR
, "Mem alloc fails for shell response buffer\n");
1178 /* Response comes in one shot not in fragments */
1179 if (remote_CDC_rx(wl
, rem_ptr
, resp_buf
,
1180 rem_ptr
->msg
.len
, 0) == FAIL
) {
1181 DPRINT_ERR(ERR
, "shell_info_fe: No results!\n");
1185 /* print the shell result */
1186 resp_buf
[rem_ptr
->msg
.len
] = '\0';
1187 /* The return value of the shell command will be stored in rem_ptr->msg.cmd
1188 * Return that value to the client process
1190 if (rem_ptr
->msg
.flags
& REMOTE_REPLY
)
1191 error
= rem_ptr
->msg
.cmd
;
1192 write(1, resp_buf
, msg_len
);
1194 rwl_shell_killproc(pid
);