2 * File Name: wlu_server_shared.c
3 * Common server specific functions for linux and win32
5 * Copyright (C) 2010, Broadcom Corporation
8 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
9 * the contents of this file may not be disclosed to third parties, copied
10 * or duplicated in any form, in whole or in part, without the prior
11 * written permission of Broadcom Corporation.
13 * $Id: wlu_server_shared.c,v 1.38.2.2 2011-01-27 23:11:30 Exp $
17 * Description: Main Server specific wrappers
18 * This module implements all the server specific functions
26 #include <sys/types.h>
27 #include <sys/socket.h>
28 #include <netinet/in.h>
30 #if !defined(TARGETOS_nucleus) && !defined(MACOSX)
42 #if !defined(TARGETOS_nucleus)
43 #include <sys/types.h>
44 #include <sys/socket.h>
45 #include <arpa/inet.h>
50 #endif /* TARGETOS_nucleus */
60 #include <proto/ethernet.h>
62 #include <bcmendian.h>
65 #include <proto/802.11.h>
71 #include <bcmendian.h>
73 #if defined(RWL_WIFI) || defined(WIFI_REFLECTOR)
75 #endif /* defined(RWL_WIFI) || defined(WIFI_REFLECTOR) */
77 #include "wlu_remote.h"
79 #include "wlu_server_shared.h"
81 extern int g_serv_sock_desc
;
87 static rem_ioctl_t loc_cdc
;
88 static const char* cmdname
= "remote";
89 static const char* dongleset
= "dongleset";
92 extern void store_old_interface(void *wl
, char *old_intf_name
);
93 extern int wl_check(void *wl
);
95 extern void handle_ctrlc(int unused
);
96 /* Function: rwl_transport_setup
97 * This will do the initialization for
98 * for all the transports
101 rwl_transport_setup(int argc
, char** argv
)
103 int transport_descriptor
= -1;
105 UNUSED_PARAMETER(argc
);
106 UNUSED_PARAMETER(argv
);
109 /* This function will parse the socket command line arguments
110 * & open the socket in listen mode
112 remote_type
= REMOTE_SOCKET
;
113 transport_descriptor
= rwl_init_server_socket_setup(argc
, argv
, remote_type
);
115 if (transport_descriptor
< 0) {
116 DPRINT_ERR(ERR
, "wl_socket_server:Transport setup failed \n");
118 #endif /* RWL_SOCKET */
119 #if defined(RWL_DONGLE) || defined(RWL_WIFI) || defined(RWL_SERIAL)
120 g_rem_pkt_ptr
= &g_rem_pkt
;
121 transport_descriptor
= 0;
124 remote_type
= REMOTE_WIFI
;
128 remote_type
= REMOTE_DONGLE
;
129 #endif /* RWL_DONGLE */
131 remote_type
= REMOTE_SERIAL
;
133 DPRINT_ERR(ERR
, "Port name is required from the command line\n");
136 DPRINT_DBG(OUTPUT
, "Port name is %s\n", *argv
);
137 transport_descriptor
= *(int*) rwl_open_transport(remote_type
, *argv
, 0, 0);
139 #endif /* RWL_SERIAL */
140 #endif /* RWL_DONGLE ||RWL_SERIAL ||RWL_WIFI */
142 g_serv_sock_desc
= transport_descriptor
;
144 return transport_descriptor
;
148 /* Function: remote_rx_header
149 * This function will receive the CDC header from client
150 * for socket transport
151 * It will receive the command or ioctl from dongle driver for
152 * dongle UART serial transport and wifi transport.
153 * Arguments: wl - handle to driver
154 * : Des - Socket Descriptor to pass in AcceptConnection
155 * : g_rwl_hndle - Return socket handle that is used for transmission
156 * : and reception of data in case of socket
157 * In case of serial, it is just a return value
160 remote_rx_header(void *wl
, int trans_Des
)
163 struct sockaddr_in ClientAddress
;
165 SizeOfCliAdd
= sizeof(ClientAddress
);
167 UNUSED_PARAMETER(wl
);
169 /* Get the socket handle g_rwl_hndle for transmission & reception */
170 if ((g_rwl_hndle
= rwl_acceptconnection(trans_Des
, (struct sockaddr
*)&ClientAddress
,
171 &SizeOfCliAdd
)) == BCME_ERROR
) {
175 /* Get CDC header in order to determine buffer requirements */
176 if ((g_rem_ptr
= remote_CDC_rx_hdr((void *)&g_rwl_hndle
, 0)) == NULL
) {
177 DPRINT_DBG(OUTPUT
, "\n Waiting for client to transmit command\n");
181 #endif /* RWL_SOCKET */
184 void *pkt_ptr
= NULL
;
187 UNUSED_PARAMETER(trans_Des
);
189 /* wl driver is polled after every 200 ms (POLLING_TIME) */
190 rwl_sleep(POLLING_TIME
);
192 if ((error
= rwl_var_getbuf(wl
, cmdname
, NULL
, 0, &pkt_ptr
)) < 0) {
193 DPRINT_ERR(ERR
, "No packet in wl driver\r\n");
197 DPRINT_DBG(OUTPUT
, "Polling the wl driver, error status=%d\n", error
);
199 if ((*(int *)pkt_ptr
) == 0) {
200 DPRINT_DBG(ERR
, "packet not received\n");
204 DPRINT_DBG(OUTPUT
, "packet received\n");
206 /* Extract CDC header in order to determine buffer requirements */
207 memcpy((char*)g_rem_pkt_ptr
, (char*)pkt_ptr
, sizeof(rem_packet_t
));
208 g_rem_ptr
= &(g_rem_pkt_ptr
->rem_cdc
);
210 #endif /* RWL_DONGLE */
213 UNUSED_PARAMETER(wl
);
214 UNUSED_PARAMETER(trans_Des
);
215 if (g_rwl_hndle
== -1) {
216 DPRINT_ERR(ERR
, "failed to open com port.\r\n");
220 if ((g_rem_ptr
= remote_CDC_rx_hdr((void*)&g_rwl_hndle
, 1)) == NULL
) {
221 DPRINT_DBG(OUTPUT
, "\n Waiting for client to transmit command\n");
224 #endif /* RWL_SERIAL */
228 /* Poll the driver for the valid action frame and update the CDC + data */
229 dot11_action_wifi_vendor_specific_t
*list
;
231 UNUSED_PARAMETER(trans_Des
);
233 if ((list
= rwl_wifi_allocate_actionframe()) == NULL
) {
234 DPRINT_DBG(OUTPUT
, "remote_rx_header: Failed to allocate frame \n");
238 if (remote_CDC_DATA_wifi_rx((void*)wl
, list
) < 0) {
243 /* copy the valid length of the data to the g_rem_pkt_ptr */
244 memcpy((char*)g_rem_pkt_ptr
, (char*)&list
->data
[0], sizeof(rem_packet_t
));
245 g_rem_ptr
= &(g_rem_pkt_ptr
->rem_cdc
);
247 #endif /* RWL_WIFI */
248 rwl_swap_header(g_rem_ptr
, NETWORK_TO_HOST
);
250 DPRINT_INFO(OUTPUT
, "%d %d %d %d\r\n", g_rem_ptr
->msg
.cmd
,
251 g_rem_ptr
->msg
.len
, g_rem_ptr
->msg
.flags
, g_rem_ptr
->data_len
);
257 /* Function: remote_rx_data
258 * This function will receive the data from client
259 * for different transports
260 * In case of socket the data comes from a open TCP socket
261 * However in case of dongle UART or wi-fi the data is accessed
262 * from the driver buffers.
265 remote_rx_data(void* buf_ptr
)
267 #if defined(RWL_SOCKET) || defined(RWL_SERIAL)
269 if ((remote_CDC_rx((void *)&g_rwl_hndle
, g_rem_ptr
, buf_ptr
,
270 g_rem_ptr
->msg
.len
, 0)) == BCME_ERROR
) {
271 DPRINT_ERR(ERR
, "Reading CDC %d data bytes failed\n", g_rem_ptr
->msg
.len
);
274 #elif defined(RWL_DONGLE) || defined(RWL_WIFI)
275 if (g_rem_ptr
->data_len
!= 0) {
276 int length
= g_rem_ptr
->data_len
;
277 if (g_rem_ptr
->data_len
> g_rem_ptr
->msg
.len
) {
278 length
= g_rem_ptr
->msg
.len
;
280 memcpy(buf_ptr
, g_rem_pkt_ptr
->message
, length
);
284 #endif /* RWL_SOCKET || RWL_SERIAL */
290 * Function to send the serial response to wl driver
291 * The function calculates the no of frames based on the DATA_FRAME_LEN
292 * adds cdc header to every frame, copies the header and fragmented frame
293 * into rem_buf_ptr and sends the packet down to wl driver
297 rwl_serial_fragmented_tx(void* wl
, rem_ioctl_t
*rem_ptr
, uchar
*buf_ptr
, int error
)
299 rem_ioctl_t
*loc_ptr
= &loc_cdc
;
301 uint noframes
= 1; /* Default noframes = 1 */
306 loc_ptr
->msg
.cmd
= error
;
307 loc_ptr
->msg
.flags
= REMOTE_REPLY
;
308 loc_ptr
->msg
.len
= rem_ptr
->msg
.len
;
309 loc_ptr
->data_len
= rem_ptr
->data_len
;
311 /* Fragment the result if it is more than DATA_FRAME_LEN (960) */
312 if (loc_ptr
->msg
.len
> DATA_FRAME_LEN
) {
313 /* Calculate no of frames */
314 noframes
= (loc_ptr
->msg
.len
)/DATA_FRAME_LEN
;
315 if ((loc_ptr
->msg
.len
) % DATA_FRAME_LEN
> 0) {
317 rem_bytes
= (loc_ptr
->msg
.len
) % DATA_FRAME_LEN
;
319 rem_bytes
= DATA_FRAME_LEN
;
322 rem_bytes
= loc_ptr
->msg
.len
;
324 DPRINT_INFO(OUTPUT
, "No of frames = %d, rem_bytes:%d\n", noframes
, rem_bytes
);
326 frame_count
= noframes
;
327 rem_buf_ptr
= (uchar
*)malloc(DONGLE_TX_FRAME_SIZE
+ REMOTE_SIZE
);
329 while (count
< noframes
) {
330 memset(rem_buf_ptr
, 0, DONGLE_TX_FRAME_SIZE
+ REMOTE_SIZE
);
331 /* Send reply to client */
332 rem_ptr
->msg
.cmd
= loc_ptr
->msg
.cmd
;
333 rem_ptr
->msg
.flags
= loc_ptr
->msg
.flags
;
334 rem_ptr
->msg
.len
= loc_ptr
->msg
.len
;
336 if (frame_count
== 1)
337 rem_ptr
->data_len
= rem_bytes
;
339 rem_ptr
->data_len
= DATA_FRAME_LEN
;
341 DPRINT_DBG(OUTPUT
, "GET--rem_ptr->data_len=%d\n", rem_ptr
->data_len
);
343 /* Copy CDC Header */
344 memcpy(rem_buf_ptr
, (uchar
*)rem_ptr
, REMOTE_SIZE
);
347 memcpy(&rem_buf_ptr
[REMOTE_SIZE
], &buf_ptr
[count
*DATA_FRAME_LEN
],
352 DPRINT_INFO(OUTPUT
, "FRAME %d\n", count
);
353 DPRINT_INFO(OUTPUT
, "%d %d %d %d\n", rem_ptr
->msg
.cmd
, rem_ptr
->msg
.len
,
354 rem_ptr
->msg
.flags
, rem_ptr
->data_len
);
356 rwl_sync_delay(noframes
);
358 if ((error
= rwl_var_setbuf(wl
, cmdname
, rem_buf_ptr
,
359 DONGLE_TX_FRAME_SIZE
+REMOTE_SIZE
)) < 0) {
360 DPRINT_INFO(OUTPUT
, "Unable to send to wl driver,error=%d\n", error
);
366 DPRINT_INFO(OUTPUT
, "Packet sent to wl driver,error=%d\n", error
);
375 /* This function transmits the response to the dongle driver in the case
376 * of serial dongle transport.
377 * In the case of big response, it calls the rwl_serial_fragmented_response
378 * function to fragment the response and sends down to the driver.
382 remote_CDC_dongle_tx(void *wl
, uint cmd
, uchar
*buf
, uint buf_len
, uint data_len
, uint flags
)
385 rem_ioctl_t resp_rem_cdc
;
387 if (flags
& REMOTE_SET_IOCTL
) {
389 /* for set commands message length and data length should be set to zero
390 * unlike Get Ioctl which will have valid data and message length
392 resp_rem_cdc
.msg
.len
= 0;
393 resp_rem_cdc
.data_len
= 0;
394 resp_rem_cdc
.msg
.cmd
= cmd
;
395 resp_rem_cdc
.msg
.flags
= REMOTE_REPLY
;
397 DPRINT_INFO(OUTPUT
, "Set:Resp packet:%d %d %d %d\n", resp_rem_cdc
.msg
.cmd
,
398 resp_rem_cdc
.msg
.len
, resp_rem_cdc
.msg
.flags
, resp_rem_cdc
.data_len
);
400 if ((rem_buf_ptr
= (uchar
*)malloc(DONGLE_TX_FRAME_SIZE
+ REMOTE_SIZE
)) == NULL
) {
401 DPRINT_ERR(ERR
, "malloc failed for remote_CDC_dongle_tx\n");
405 /* Send reply to client here */
406 memcpy(rem_buf_ptr
, (char*)(&resp_rem_cdc
), REMOTE_SIZE
);
407 if ((error
= rwl_var_setbuf((void*)wl
, cmdname
, rem_buf_ptr
,
408 DONGLE_TX_FRAME_SIZE
+ REMOTE_SIZE
)) < 0) {
409 DPRINT_ERR(ERR
, "unable to send SET results to driver=%d\n", error
);
411 DPRINT_INFO(OUTPUT
, "Packet sent to wl driver, error=%d\n", error
);
416 } else { /* GET_IOCTL */
417 resp_rem_cdc
.msg
.cmd
= cmd
;
418 resp_rem_cdc
.msg
.len
= buf_len
;
419 resp_rem_cdc
.msg
.flags
= flags
;
420 resp_rem_cdc
.data_len
= data_len
;
421 if ((error
= rwl_serial_fragmented_tx(wl
, &resp_rem_cdc
, buf
, cmd
)) < 0)
422 DPRINT_ERR(ERR
, "wl_server_serial: Return error code failed\n");
426 #endif /* RWL_DONGLE */
428 /* This function gets the command send by the client from the dongle driver */
430 rwl_var_getbuf(void* wl
, const char* iovar
, void* param
, int param_len
, void** buf_ptr
)
434 memset(rwl_buf
, 0, WLC_IOCTL_MAXLEN
);
435 strcpy((char*)rwl_buf
, iovar
);
436 /* include the null */
437 len
= strlen(iovar
) + 1;
440 memcpy(&rwl_buf
[len
], param
, param_len
);
444 return wl_get(wl
, WLC_GET_VAR
, &rwl_buf
[0], WLC_IOCTL_MAXLEN
);
447 /* This function will send the buffer to the dongle driver */
449 rwl_var_setbuf(void* wl
, const char* iovar
, void* param
, int param_len
)
453 memset(rwl_buf
, 0, WLC_IOCTL_MAXLEN
);
454 strcpy((char*)rwl_buf
, iovar
);
456 /* include the null */
457 len
= strlen(iovar
) + 1;
460 memcpy(&rwl_buf
[len
], param
, param_len
);
464 DPRINT_DBG(OUTPUT
, "setbuf:%s, len:%d\n", rwl_buf
, len
);
466 return wl_set(wl
, WLC_SET_VAR
, &rwl_buf
[0], len
);
469 /* This function will send the buffer to the dongle driver */
471 rwl_var_send_vs_actionframe(void* wl
, const char* iovar
, void* param
, int param_len
)
475 memset(rwl_buf
, 0, WLC_IOCTL_MAXLEN
);
476 strcpy((char*) rwl_buf
, iovar
);
478 /* include the null */
479 len
= strlen(iovar
) + 1;
482 memcpy((void*)&rwl_buf
[len
+ OFFSETOF(wl_action_frame_t
, data
)], param
, param_len
);
484 /* Set the PacketID (not used by remote WL */
485 memset((void*)&rwl_buf
[len
+ OFFSETOF(wl_action_frame_t
, packetId
)], 0, 4);
487 /* Set the dest addr */
488 memcpy((void*)&rwl_buf
[len
+ OFFSETOF(wl_action_frame_t
, da
)],
493 memcpy((void*)&rwl_buf
[len
+ OFFSETOF(wl_action_frame_t
, len
)], (void*) ¶m_len
, 2);
495 len
+= param_len
+ ETHER_ADDR_LEN
+ 2 + 4;
497 DPRINT_DBG(OUTPUT
, "setbuf:%s, len:%d\n", rwl_buf
, len
);
499 return wl_set(wl
, WLC_SET_VAR
, &rwl_buf
[0], len
);
502 * This function is used for transmitting the response over different
504 * In case of socket the data is directly sent to the client which is waiting on a open socket.
505 * In case of socket the data is sent in one big chunk unlike other transports
507 * In case of serial the data is sent to the driver using remote_CDC_dongle_tx function
508 * which in turn may fragment the data and send it in chunks to the client.
510 * In case of wi-fi the data is sent to the driver using the remote_CDC_tx. However
511 * in this case the data is converted into 802.11 Action frames and sent using wi-fi driver.
512 * Arguments: wl - Driver handle
513 * hndle - Socket handle for socket transport.
516 remote_tx_response(void *wl
, void* buf_ptr
, int cmd
)
520 #if defined(RWL_SOCKET) || defined(RWL_SERIAL)
521 UNUSED_PARAMETER(wl
);
522 if ((error
= remote_CDC_tx((void*)&g_rwl_hndle
, cmd
, buf_ptr
, g_rem_ptr
->msg
.len
,
523 g_rem_ptr
->msg
.len
, REMOTE_REPLY
, 0)) < 0)
524 DPRINT_ERR(ERR
, "wl_server: Return results failed\n");
525 #endif /* RWL_SOCKET || RWL_SERIAL */
528 if ((error
= remote_CDC_dongle_tx(wl
, cmd
, buf_ptr
, g_rem_ptr
->msg
.len
,
529 g_rem_ptr
->data_len
, g_rem_ptr
->msg
.flags
)) < 0)
530 DPRINT_ERR(ERR
, "wl_server: Return results failed\n");
531 #endif /* RWL_DONGLE */
534 /* Purge all the queued cmd's , this to ensure late response time out at */
535 /* client side and client might issue the next cmd if server is slow */
536 rwl_wifi_purge_actionframes(wl
);
537 if ((g_rem_ptr
->msg
.flags
& REMOTE_SHELL_CMD
) ||
538 (g_rem_ptr
->msg
.flags
& REMOTE_GET_IOCTL
)||
539 (g_rem_ptr
->msg
.flags
& REMOTE_ASD_CMD
) ||
540 (g_rem_ptr
->msg
.flags
& REMOTE_VISTA_CMD
)) {
541 if ((error
= remote_CDC_tx(wl
, cmd
, buf_ptr
, g_rem_ptr
->msg
.len
,
542 g_rem_ptr
->msg
.len
, REMOTE_REPLY
, 0)) < 0)
543 DPRINT_ERR(ERR
, "wl_wifi_server_ce: Return results failed\n");
545 if ((error
= remote_CDC_tx(wl
, cmd
, buf_ptr
, 0, 0, REMOTE_REPLY
, 0)) < 0)
546 DPRINT_ERR(ERR
, "wl_wifi_server_ce: Return results failed\n");
548 #endif /* RWL_WIFI */
552 /* Close the Socket handle */
553 void close_sock_handle(int hndle
)
556 rwl_close_pipe(remote_type
, (void*)&hndle
);
558 UNUSED_PARAMETER(hndle
);
564 * Send the response to the remote if the channel of the server matches with the
567 void remote_wifi_response(void* wl
)
570 dot11_action_wifi_vendor_specific_t
*list
;
572 if ((list
= rwl_wifi_allocate_actionframe()) == NULL
) {
573 DPRINT_DBG(OUTPUT
, "remote_wifi_response: Failed to allocate frame \n");
577 /* it's sync frame and received from client */
578 memcpy((char*)&list
->data
[RWL_WIFI_CDC_HEADER_OFFSET
],
579 &g_rem_pkt_ptr
[RWL_WIFI_CDC_HEADER_OFFSET
], REMOTE_SIZE
);
580 memcpy((char*)&list
->data
[REMOTE_SIZE
], g_rem_pkt_ptr
->message
,
581 RWL_WIFI_FRAG_DATA_SIZE
);
582 list
->type
= RWL_WIFI_FIND_MY_PEER
;
583 /* Store the client mac addr */
584 memcpy((void*)&rwlea
, (void*)&list
->data
[RWL_DUT_MAC_ADDRESS_OFFSET
], ETHER_ADDR_LEN
);
585 /* send the response to client if server is on the same channel */
586 rwl_wifi_find_server_response(wl
, list
);
590 UNUSED_PARAMETER(wl
);
591 #endif /* RWL_WIFI */
595 /* Function to check IN-dongle mode firmware */
597 rwl_iovar_check(void *wl
)
601 dot11_action_wifi_vendor_specific_t rec_frame
;
603 /* Check for indongle mode firmware */
604 return rwl_var_getbuf(wl
, RWL_WIFI_GET_ACTION_CMD
, &rec_frame
,
605 RWL_WIFI_ACTION_FRAME_SIZE
, &ptr
);
607 UNUSED_PARAMETER(ptr
);
608 UNUSED_PARAMETER(wl
);
610 return rwl_var_getbuf(wl
, "remote", NULL
, 0, &ptr
);
615 /* Function to get a ctrl-c packet */
617 get_ctrlc_header(void *wl
)
619 #if defined(RWL_SOCKET) || defined(RWL_SERIAL)
622 UNUSED_PARAMETER(wl
);
624 FD_SET((unsigned)g_rwl_hndle
, &fdset
);
627 if ((select(g_rwl_hndle
+1, &fdset
, NULL
, NULL
, &tv
)) > 0) {
628 if (FD_ISSET(g_rwl_hndle
, &fdset
)) {
629 remote_CDC_rx_hdr((void *)&g_rwl_hndle
, 0);
636 return remote_rx_header(wl
, 0);
637 #endif /* if defined(RWL_SOCKET) || defined(RWL_SERIAL) */
640 /* Main server module common for all transports
641 * This module will do the initial transport setups.
642 * Then it receives the command from client in CDC format
643 * and transmits the response back to the client.
644 * In the case of socket, it receives the command from the client
645 * and sends the response directly to the client via TCP socket.
647 * In the case of serial & wifi , it receives the command from the driver
648 * and sends the response to the driver.
651 remote_server_exec(int argc
, char **argv
, void *wl
)
654 int transport_descriptor
;
655 char *async_cmd_flag
;
656 char old_intf_name
[IFNAMSIZ
];
658 char shell_fname
[MAX_SHELL_FILE_LENGTH
];
663 /* To set dongle flag when dongle server starts */
664 if ((err
= rwl_var_setbuf(wl
, dongleset
, &uart_enable
,
666 DPRINT_INFO(OUTPUT
, "Unable to send to wl driver,error=%d\n", err
);
669 if (rwl_iovar_check (wl
) < 0) {
670 DPRINT_ERR(ERR
, "wl_server: RWL_WIFI/RWL_DONGLE not defined ");
671 DPRINT_ERR(ERR
, "Or In-Dongle mode enabled\n");
674 /* Initialise for all the transports - socket, serial, and wifi
675 * In Socket transport, main socket handler will be returned.
677 if ((transport_descriptor
= rwl_transport_setup(argc
, argv
)) < 0)
681 remote_wifi_ser_init_cmds(wl
);
683 /* Create a directory /tmp/RWL for the shell response files */
684 if (rwl_create_dir() < 0)
689 /* DUT initialization function */
690 wfa_dut_init(&trafficBuf
, &respBuf
, &parmsVal
, &xcCmdBuf
, &toutvalp
);
693 /* Copy old interface name to restore it */
694 store_old_interface(wl
, old_intf_name
);
697 uchar
*buf_ptr
= NULL
;
700 char *vista_buf
[MAX_VISTA_ARGC
];
703 g_rwl_hndle
= transport_descriptor
;
710 if ((err
= rwl_var_setbuf(wl
, dongleset
, &uart_enable
,
712 DPRINT_INFO(OUTPUT
, "Unable to send to wl driver,error=%d\n", err
);
717 #endif /* RWL_DONGLE */
719 /* Receive the CDC header */
720 if ((remote_rx_header(wl
, transport_descriptor
)) == BCME_ERROR
) {
721 DPRINT_DBG(OUTPUT
, "\n Waiting for client to transmit command\n");
725 DPRINT_INFO(OUTPUT
, "REC : cmd %d\t msg len %d msg flag %d\t msg status %d\n",
726 g_rem_ptr
->msg
.cmd
, g_rem_ptr
->msg
.len
,
727 g_rem_ptr
->msg
.flags
, g_rem_ptr
->msg
.status
);
730 /* send the response to remote if it is findserver cmd, this is specific to wifi */
731 if (g_rem_ptr
->msg
.flags
& REMOTE_FINDSERVER_IOCTL
) {
732 remote_wifi_response(wl
);
735 #endif /* RWL_WIFI */
738 * Allocate buffer only if there is a response message expected.
739 * Some commands such as up/down do not output anything.
741 if (g_rem_ptr
->msg
.len
) {
742 if ((buf_ptr
= malloc(g_rem_ptr
->msg
.len
)) == NULL
) {
743 DPRINT_ERR(ERR
, "malloc of %d bytes failed\n", g_rem_ptr
->msg
.len
);
748 /* Receive the data */
749 if ((err
= remote_rx_data(buf_ptr
)) == BCME_ERROR
) {
755 /* Process command */
756 if (g_rem_ptr
->msg
.flags
& REMOTE_SHELL_CMD
) {
757 /* Get the response length first and get the response buffer in case of
758 * synchronous shell commands and the buf_ptr will have the response file
759 * name. In case of asynchronous shell commands, buf_ptr
760 * will be get updated by the remote_shell_execute function.
762 need_speedy_response
= 1;
765 async_cmd_flag
= strstr((char*)buf_ptr
, "%");
767 if ((err
= remote_shell_execute((char*)buf_ptr
, wl
)) > 0) {
769 g_rem_ptr
->msg
.len
= err
;
771 /* Sync shell command: No need to send response from here */
774 /* Transmitted to client. Then close the handle &
775 * get the new handle for next transmission & reception.
777 close_sock_handle(g_rwl_hndle
);
778 #endif /* RWL_SOCKET */
782 if ((err
= remote_shell_execute((char*)buf_ptr
, wl
)) != SUCCESS
) {
783 DPRINT_ERR(ERR
, "Error in executing shell command\n");
787 /* Transmitted to client. Then close the handle &
788 * get the new handle for next transmission & reception.
790 close_sock_handle(g_rwl_hndle
);
791 #endif /* RWL_SOCKET */
794 /* Get the response from the temporary file */
795 if ((err
= remote_shell_get_resp(shell_fname
, wl
)) != SUCCESS
) {
796 DPRINT_ERR(ERR
, "Error in executing shell command\n");
801 /* Transmitted to client. Then close the handle &
802 * get the new handle for next transmission & reception.
804 close_sock_handle(g_rwl_hndle
);
805 #endif /* RWL_SOCKET */
808 } /* REMOTE_SHELL_CMD */
811 if (g_rem_ptr
->msg
.flags
& REMOTE_ASD_CMD
) {
812 if ((err
= remote_asd_exec(buf_ptr
, (int *)&g_rem_ptr
->msg
.len
)) < 0) {
813 DPRINT_ERR(ERR
, "Error in executing asd command\n");
815 } /* REMOTE_ASD_CMD */
819 * added to take care of OID base problem for cross OS RWL cleint server
820 * In case of LX Server and WIN32 client OID base need to be removed
821 * In case of WIN32 server and LX client OID base need to be added
823 if (g_rem_ptr
->msg
.cmd
> MAX_IOVAR
)
824 g_rem_ptr
->msg
.cmd
-= WL_OID_BASE
;
826 if (g_rem_ptr
->msg
.cmd
< MAX_IOVAR
)
827 g_rem_ptr
->msg
.cmd
+= WL_OID_BASE
;
830 if (g_rem_ptr
->msg
.flags
& REMOTE_VISTA_CMD
) {
831 vista_buf
[0] = strtok(buf_ptr
, " \t\n");
832 for (index
= 1; (vista_buf
[index
] = strtok(NULL
, " \t\n")) != NULL
;
834 if ((err
= remote_vista_exec(wl
, vista_buf
)) < 0) {
835 DPRINT_ERR(ERR
, "Error in executing vista command\n");
837 memcpy(buf_ptr
, vista_buf
[0], strlen(vista_buf
[0]));
838 g_rem_ptr
->msg
.len
= strlen(vista_buf
[0]);
839 } /* REMOTE_VISTA_CMD */
840 #endif /* VISTA_SERVER */
843 if (g_rem_ptr
->msg
.flags
& REMOTE_GET_IOCTL
||
844 g_rem_ptr
->msg
.flags
& REMOTE_SET_IOCTL
) {
845 if (strlen(g_rem_ptr
->intf_name
) != 0) {
847 /* validate the interface */
848 memset(&ifr
, 0, sizeof(ifr
));
849 if (g_rem_ptr
->intf_name
)
850 strncpy(ifr
.ifr_name
, g_rem_ptr
->intf_name
, IFNAMSIZ
);
852 if (wl_check((void *)&ifr
)) {
853 DPRINT_ERR(ERR
, "%s: wl driver adapter not found\n",
854 g_rem_ptr
->intf_name
);
855 /* Signal end of command output */
856 g_rem_ptr
->msg
.len
= 0;
857 remote_tx_response(wl
, NULL
, BCME_NODEVICE
);
862 close_sock_handle(g_rwl_hndle
);
863 #endif /* RWL_SOCKET */
867 if (set_interface(wl
, g_rem_ptr
->intf_name
) == BCME_OK
)
868 DPRINT_DBG(OUTPUT
, "\n %s Interface will be used \n",
872 #endif /* ifndef RWL_DONGLE */
873 if (g_rem_ptr
->msg
.flags
& REMOTE_SET_IOCTL
||
874 g_rem_ptr
->msg
.flags
& RDHD_SET_IOCTL
) {
876 #if defined(RWL_DONGLE) || defined(RWL_WIFI)
877 /* For commands with msg length as zero initialize the buffer to null */
878 if (g_rem_ptr
->msg
.len
== 0)
882 if (g_rem_ptr
->msg
.len
== 0)
886 if (g_rem_ptr
->msg
.flags
& REMOTE_SET_IOCTL
) {
887 err
= wl_ioctl(wl
, g_rem_ptr
->msg
.cmd
,
888 (void *)buf_ptr
, g_rem_ptr
->msg
.len
, TRUE
);
890 if (err
== IOCTL_ERROR
) {
891 DPRINT_ERR(ERR
, "Error in executing wl_ioctl\n");
892 DPRINT_ERR(ERR
, "Setting Default Interface1 \n");
893 set_interface(wl
, old_intf_name
);
896 if (g_rem_ptr
->msg
.flags
& RDHD_SET_IOCTL
) {
897 err
= dhd_ioctl(wl
, g_rem_ptr
->msg
.cmd
,
898 (void *)buf_ptr
, g_rem_ptr
->msg
.len
, TRUE
);
901 g_rem_ptr
->msg
.flags
= REMOTE_SET_IOCTL
;
903 } /* RDHD/REMOTE_SET_IOCTL */
905 if (g_rem_ptr
->msg
.flags
& REMOTE_GET_IOCTL
||
906 g_rem_ptr
->msg
.flags
& RDHD_GET_IOCTL
) {
907 if (g_rem_ptr
->msg
.cmd
== WLC_GET_VAR
&& buf_ptr
&&
908 strncmp((const char *)buf_ptr
, "exit", g_rem_ptr
->msg
.len
) == 0) {
909 /* exit command from remote client terminates server */
913 if (g_rem_ptr
->msg
.flags
& REMOTE_GET_IOCTL
)
914 err
= wl_ioctl(wl
, g_rem_ptr
->msg
.cmd
, (void *)buf_ptr
,
915 g_rem_ptr
->msg
.len
, FALSE
);
916 if (err
== IOCTL_ERROR
) {
917 DPRINT_ERR(ERR
, "REMOTE_GET_IOCTL::Error in executing wl_ioctl\n");
918 DPRINT_ERR(ERR
, "Setting Default Interface \n");
919 set_interface(wl
, old_intf_name
);
922 if (g_rem_ptr
->msg
.flags
& RDHD_GET_IOCTL
)
923 err
= dhd_ioctl(wl
, g_rem_ptr
->msg
.cmd
, (void *)buf_ptr
,
924 g_rem_ptr
->msg
.len
, FALSE
);
925 g_rem_ptr
->msg
.flags
= REMOTE_GET_IOCTL
;
926 } /* REMOTE_GET_IOCTL */
927 DPRINT_INFO(OUTPUT
, "RESP : cmd %d\t msg len %d\n",
928 g_rem_ptr
->msg
.cmd
, g_rem_ptr
->msg
.len
);
929 /* setting back default interface */
930 set_interface(wl
, old_intf_name
);
931 /* Transmit the response results */
932 if (remote_tx_response(wl
, buf_ptr
, err
) < 0) {
933 DPRINT_ERR(ERR
, "\nReturn results failed\n");
937 if (g_rem_ptr
->msg
.flags
!= REMOTE_SHELL_CMD
)
938 /* Transmitted to client. Then close the handle & get the new handle
939 * for next transmission & reception. In case of shell commands this
940 * should be closed in respective shellproc files.
942 close_sock_handle(g_rwl_hndle
);
943 #endif /* RWL_SOCKET */
949 #if defined(RWL_SOCKET)
950 /* Close the main handle for socket */
951 close_sock_handle(transport_descriptor
);
952 #elif defined(RWL_SERIAL)
953 /* Close the main handle for serial pipe */
954 rwl_close_pipe(remote_type
, (void*)&transport_descriptor
);