2 * Common Functionality for pipe
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_pipe.c,v 1.22 2009-10-15 17:54:48 Exp $
19 /* Expected order for succesfull compliation */
26 #include <sys/types.h>
27 #include <sys/socket.h>
28 #include <arpa/inet.h>
32 #include <sys/ioctl.h>
41 #include <sys/types.h>
42 #include <sys/socket.h>
43 #include <netinet/in.h>
45 #if !defined(TARGETOS_nucleus) && !defined(MACOSX)
52 #include <proto/ethernet.h>
53 #include <bcmendian.h>
56 #include <proto/802.11.h>
57 #if defined(RWL_WIFI) || defined(WIFI_REFLECTOR)
59 #endif /* defined(RWL_WIFI) || defined(WIFI_REFLECTOR) */
61 #include "wlu_remote.h"
63 static rem_ioctl_t rem_cdc
;
64 char *g_rwl_device_name_serial
= "";
65 bool g_rwl_swap
= FALSE
;
66 char g_rem_ifname
[IFNAMSIZ
] = "\0";
67 int need_speedy_response
; /* Indicate findserver is checking channels */
72 #define UART_FIFO_LEN 64
73 #define END_OF_PACK_SEP_LEN 2
74 #define INIT_CMD_SLEEP 500
77 /* dword align allocation */
79 uchar bufdata
[ETHER_ADDR_LEN
];
82 char *g_rwl_buf_mac
= (char*) &bufmac_wlu
.bufdata
;
85 /* dword align allocation */
87 uchar shelldata
[WL_MAX_BUF_LEN
];
90 char *g_rwl_buf_shell
= (char*) &shell_wlu
.shelldata
;
91 int rwl_find_remote_wifi_server(void *wl
, char *id
);
92 int wl_ioctl(void *wl
, int cmd
, void *buf
, int len
, bool set
);
95 * This function runs a set of commands before running the wi-fi server
96 * This is avoids packet drops and improves performance.
97 * We run the following wl commands
98 * up, mpc 0, wsec 0, slow_timer 999999, fast_timer 999999, glacial_timer 999999
99 * legacylink 1, monitor 1.
101 void remote_wifi_ser_init_cmds(void *wl
)
104 char bigbuf
[RWL_WIFI_BUF_LEN
];
106 /* The array stores command, length and then data format */
107 remote_wifi_cmds_t wifi_cmds
[] = {
109 {WLC_SET_VAR
, "mpc", 0},
110 {WLC_SET_WSEC
, NULL
, 0x0},
111 {WLC_SET_VAR
, "slow_timer", 999999},
112 {WLC_SET_VAR
, "fast_timer", 999999},
113 {WLC_SET_VAR
, "glacial_timer", 999999},
114 {WLC_SET_MONITOR
, NULL
, 0x1},
115 {WLC_SET_PM
, NULL
, 0x0}
118 for (count
= 0; count
< ARRAYSIZE(wifi_cmds
); count
++) {
120 if (wifi_cmds
[count
].data
== NULL
)
123 len
= strlen(wifi_cmds
[count
].data
) + 1 + sizeof(int);
125 /* If the command length exceeds the buffer length continue
126 * executing the next command
128 if (len
> sizeof(bigbuf
)) {
129 DPRINT_ERR(ERR
, "Err: command len exceeds buf len. Check"
130 "initialization cmds\n");
134 if (wifi_cmds
[count
].data
!= NULL
) {
135 strcpy(bigbuf
, wifi_cmds
[count
].data
);
136 memcpy(&bigbuf
[strlen(wifi_cmds
[count
].data
)+1],
137 (char*)&wifi_cmds
[count
].value
, sizeof(int));
139 memcpy(&bigbuf
[0], (char*)&wifi_cmds
[count
].value
, sizeof(int));
142 /* Add OID base for NDIS commands */
144 err
= (int)ir_setinformation(wl
, wifi_cmds
[count
].cmd
+ WL_OID_BASE
,
148 if (wifi_cmds
[count
].cmd
== WLC_UP
)
149 /* NULL needs to be passed to the driver if WL UP command needs to
150 * be executed Otherwise driver hangs
152 err
= wl_ioctl(wl
, wifi_cmds
[count
].cmd
,
155 err
= wl_ioctl(wl
, wifi_cmds
[count
].cmd
,
156 (void*)&bigbuf
, len
, TRUE
);
158 rwl_sleep(INIT_CMD_SLEEP
);
162 /* When user wants to execute local CMD being in remote wifi mode, this fucntion is used
163 * to change the remote types.
164 * This fucntion is called to swap the remote type to execute the cmd using the local
166 * This is required for to call proper front end fucntions to achive the local set/get ioctl.
169 rwl_wifi_swap_remote_type(int flag
)
171 static int remote_flag
;
172 if (flag
== REMOTE_WIFI
) {
173 remote_type
= NO_REMOTE
;
175 } else if (remote_flag
== REMOTE_WIFI
) {
176 remote_type
= remote_flag
;
183 rwl_wifi_free_list(dot11_action_wifi_vendor_specific_t
*list
[])
186 for (i
= 0; i
< RWL_DEFAULT_WIFI_FRAG_COUNT
; i
++) {
193 * Configures local channel for finding server.
194 * Server call this fucntion for getting its current channel,
195 * client uses this fucntion for setting its channel to new channel.
198 rwl_wifi_config_channel(void *wl
, int cmd
, int *channel
)
203 /* Get functionality is used only by server */
204 if (cmd
== WLC_GET_CHANNEL
) {
205 memset((char*)&ci
, 0, sizeof(ci
));
206 if ((error
= wl_get(wl
, cmd
, &ci
, sizeof(channel_info_t
))))
208 ci
.hw_channel
= dtoh32(ci
.hw_channel
);
209 ci
.scan_channel
= dtoh32(ci
.scan_channel
);
210 ci
.target_channel
= dtoh32(ci
.target_channel
);
211 if (ci
.scan_channel
) {
212 printf("Scan in progress.\n");
214 *channel
= ci
.hw_channel
;
217 if (cmd
== WLC_SET_CHANNEL
) {
218 /* Set functionality is used by the client */
219 ci
.target_channel
= *channel
;
220 /* When user wants to execute local CMD being in remote wifi mode,
221 * rwl_wifi_swap_remote_type fucntion is used to change the remote types.
223 rwl_wifi_swap_remote_type(remote_type
);
224 error
= wl_set(wl
, cmd
, &ci
.target_channel
, sizeof(int));
225 /* rever it back to same old remote type */
226 rwl_wifi_swap_remote_type(remote_type
);
231 allocate the memory for action frame and update with wifi tranport header.
233 dot11_action_wifi_vendor_specific_t
*
234 rwl_wifi_allocate_actionframe()
236 dot11_action_wifi_vendor_specific_t
*action_frame
;
238 if ((action_frame
= (dot11_action_wifi_vendor_specific_t
*)
239 malloc(RWL_WIFI_ACTION_FRAME_SIZE
)) == NULL
) {
240 DPRINT_ERR(ERR
, "rwl_wifi_allocate_actionframe: unable to allocate frame \n");
243 action_frame
->category
= RWL_ACTION_WIFI_CATEGORY
;
244 action_frame
->OUI
[0] = RWL_WIFI_OUI_BYTE0
;
245 action_frame
->OUI
[1] = RWL_WIFI_OUI_BYTE1
;
246 action_frame
->OUI
[2] = RWL_WIFI_OUI_BYTE2
;
247 action_frame
->type
= RWL_WIFI_DEFAULT_TYPE
;
248 action_frame
->subtype
= RWL_WIFI_DEFAULT_SUBTYPE
;
253 * Send the valid action frame (CDC+DATA) through the REF driver interface.
254 * if the CMD is "findserver" then "findmypeer" frames are sent on the diffrent
255 * channels to reconnect
256 * to with server. Other wl cmd takes the normal path.
257 * parameter 3 , i.e. buf contains the cmd line arguments and buf_len is the actual
258 * length of the buf. data_len is the length of the actual data to be sent to remote server.
261 remote_CDC_wifi_tx(void *wl
, uint cmd
, uchar
*buf
, uint buf_len
, uint data_len
, uint flags
)
263 rem_ioctl_t
*rem_ptr
= &rem_cdc
;
265 dot11_action_wifi_vendor_specific_t
*rem_wifi_send
;
267 /* prepare CDC header */
268 rem_ptr
->msg
.cmd
= cmd
;
269 rem_ptr
->msg
.len
= buf_len
;
270 rem_ptr
->msg
.flags
= flags
;
271 rem_ptr
->data_len
= data_len
;
272 if (strlen(g_rem_ifname
) != 0)
273 strncpy(rem_ptr
->intf_name
, g_rem_ifname
, (int)IFNAMSIZ
);
274 rwl_swap_header(rem_ptr
, HOST_TO_NETWORK
);
276 if ((data_len
> buf_len
)) {
277 DPRINT_ERR(ERR
, "remote_CDC_wifi_tx: data_len (%d) > buf_len (%d)\n",
281 /* client will not send data greater than RWL_WIFI_FRAG_DATA_SIZE to server,
282 * this condition should not be hit on client side, when sending the cmd
285 if (data_len
> RWL_WIFI_FRAG_DATA_SIZE
)
286 DPRINT_DBG(OUTPUT
, "data size exceeds data_len %d\n", rem_ptr
->msg
.len
);
288 if ((buf
!= NULL
) && (strlen((char*)buf
) >= (sizeof(RWL_WIFI_FIND_SER_CMD
)-1)) &&
289 (!strcmp((char*)buf
, RWL_WIFI_FIND_SER_CMD
))) {
290 /* This is special case for wifi, when user wants to findserver,
291 * client has to execute it locally.Find the channel on the on
292 * which DUT is operating and sync up with specified MAC address,
293 * retry if fails to find the server
295 for (read_try
= 0; read_try
< RWL_WIFI_RETRY
; read_try
++) {
296 if (((error
= rwl_find_remote_wifi_server(wl
,
297 &g_rwl_buf_mac
[0])) == 0)) {
304 if ((rem_wifi_send
= rwl_wifi_allocate_actionframe()) == NULL
) {
305 DPRINT_ERR(ERR
, "remote_CDC_wifi_tx: Failed to allocate memory\n");
308 /* only data length needs to be sent to remote server using this function
309 * This function is only meant for client to send data to server
310 * Copy the CDC header and data to action frame data feild
311 * Now we have encapsulated the CDC header and data completely to in the
314 memcpy((void*)&rem_wifi_send
->data
[RWL_WIFI_CDC_HEADER_OFFSET
],
315 (char*)rem_ptr
, REMOTE_SIZE
);
317 memcpy((void*)&rem_wifi_send
->data
[REMOTE_SIZE
], buf
, data_len
);
320 /* Send the action frame to remote server using the rwl_var_setbuf fucntion,
321 * which will use the local driver interface to send this frame on the air
323 if ((error
= rwl_var_send_vs_actionframe(wl
, RWL_WIFI_ACTION_CMD
, rem_wifi_send
,
324 RWL_WIFI_ACTION_FRAME_SIZE
)) < 0) {
325 DPRINT_ERR(ERR
, "Unable to read the action frame %d error\n", error
);
332 * Read the valid action frame through the REF/DUT driver interface.
333 * Retry for no of times, wait for action frame for the specified time.
336 remote_CDC_DATA_wifi_rx(void *wl
, dot11_action_wifi_vendor_specific_t
* rec_frame
)
342 /* retry is to ensure to read late arrival action frame */
343 for (read_try
= 0; read_try
< RWL_WIFI_RX_RETRY
; read_try
++) {
344 /* read the action frame queued in the local driver wifi queue */
345 if ((error
= rwl_var_getbuf(wl
, RWL_WIFI_GET_ACTION_CMD
, rec_frame
,
346 RWL_WIFI_ACTION_FRAME_SIZE
, &ptr
)) < 0) {
347 DPRINT_ERR(ERR
, "remote_CDC_DATA_wifi_rx: Error in reading the frame %d\n",
351 /* copy the read action frame to the user frame and cjheck for the action category.
352 * If the action category matches with RWL_ACTION_WIFI_CATEGORY ,
353 * then its the valid frame, otherwise ignore it.
355 memcpy((char*)rec_frame
, ptr
, RWL_WIFI_ACTION_FRAME_SIZE
);
357 if (rec_frame
->category
== RWL_ACTION_WIFI_CATEGORY
) {
360 /* If we are executing findserver then sleep less */
361 if (!need_speedy_response
)
362 rwl_sleep(RWL_WIFI_RX_DELAY
);
364 rwl_sleep(RWL_CHANNEL_RX_SCAN_DELAY
);
367 /* If failed to get the valid frame , indicate the error */
368 if (!(rec_frame
->category
== RWL_ACTION_WIFI_CATEGORY
)) {
374 * read data that has reached client in fragments. If the functtion is
375 * called from rwl_shell_information_fe then the flag will be set to 1.
376 * For shell response this function will output the response on the standard interface.
377 * Response will be coming in out of order , this fucntion will make it inorder.
378 * Duplicate action frames are ignored.
381 remote_CDC_DATA_wifi_rx_frag(void *wl
, rem_ioctl_t
*rem_ptr
, uint input_len
,
382 void *input
, bool shell
)
384 int error
, totalfrag
, seq_num
, num_frags
, remainingbytes
;
385 dot11_action_wifi_vendor_specific_t
*rec_frame
;
386 uchar
*input_buf
= (uchar
*)input
;
387 /* An array of pointers to each recieved frag */
388 dot11_action_wifi_vendor_specific_t
*master_list
[RWL_DEFAULT_WIFI_FRAG_COUNT
];
390 UNUSED_PARAMETER(input_len
);
393 memset(master_list
, 0, sizeof(master_list
));
394 /* in case of shell cmd's receive size is unknown */
396 input_buf
= (uchar
*)g_rwl_buf_shell
;
397 memset(input_buf
, 0, WL_MAX_BUF_LEN
);
400 /* We don't yet know how many fragments we will need to read since the
401 length is contained in the first frgment of the message itself. Set
402 totalfrag to an arbitry large number and we will readjust it after we
403 successfully recieve the first frag.
405 totalfrag
= RWL_DEFAULT_WIFI_FRAG_COUNT
;
407 for (num_frags
= 0; num_frags
<= totalfrag
; num_frags
++) {
408 if ((rec_frame
= rwl_wifi_allocate_actionframe()) == NULL
) {
409 DPRINT_DBG(OUTPUT
, "malloc failure\n");
410 rwl_wifi_free_list(master_list
);
413 if ((error
= remote_CDC_DATA_wifi_rx((void*)wl
, rec_frame
)) < 0) {
415 rwl_wifi_free_list(master_list
);
419 if (rec_frame
->subtype
>= RWL_DEFAULT_WIFI_FRAG_COUNT
) {
420 DPRINT_DBG(OUTPUT
, " Read bogus subtype %d\n", rec_frame
->subtype
);
424 /* Keep only originals and discard any dup frags */
425 if (!master_list
[rec_frame
->subtype
]) {
426 master_list
[rec_frame
->subtype
] = rec_frame
;
432 /* Look for first frag so we can accurately calculate totalfrag */
433 if (rec_frame
->subtype
== RWL_WIFI_DEFAULT_SUBTYPE
) {
434 memcpy((char*)rem_ptr
,
435 (char*)&master_list
[rec_frame
->subtype
]->
436 data
[RWL_WIFI_CDC_HEADER_OFFSET
], REMOTE_SIZE
);
437 rwl_swap_header(rem_ptr
, NETWORK_TO_HOST
);
438 totalfrag
= rem_ptr
->msg
.len
/ RWL_WIFI_FRAG_DATA_SIZE
;
439 remainingbytes
= rem_ptr
->msg
.len
% RWL_WIFI_FRAG_DATA_SIZE
;
443 /* All frags are now read and there are no dups. Check for missing frags */
444 for (seq_num
= 0; seq_num
< totalfrag
; seq_num
++) {
445 if (!master_list
[seq_num
]) {
446 DPRINT_DBG(OUTPUT
, "Missing frag number %d\n", seq_num
);
447 rwl_wifi_free_list(master_list
);
452 case 1: response in one frame i.e if (totalfrag==0)
453 case 2: response in multiple frame ( multiple of RWL_WIFI_FRAG_DATA_SIZE)
454 case 3: response in multiple frame and not in multiple of RWL_WIFI_FRAG_DATA_SIZE
457 /* case 1: Check for the response in single frame */
459 memcpy((char*)&input_buf
[0],
460 (char*)&master_list
[0]->data
[REMOTE_SIZE
], rem_ptr
->msg
.len
);
461 else /* case 2: Copy fragments into contiguous frame */
462 memcpy((char*)&input_buf
[0],
463 (char*)&master_list
[0]->data
[REMOTE_SIZE
], RWL_WIFI_FRAG_DATA_SIZE
);
466 * If all the frames are recieved , copy them to a contigues buffer
468 for (seq_num
= 1; seq_num
< totalfrag
; seq_num
++) {
469 memcpy((char*)&input_buf
[seq_num
*RWL_WIFI_FRAG_DATA_SIZE
],
470 (char*)&master_list
[seq_num
]->data
, RWL_WIFI_FRAG_DATA_SIZE
);
473 /* case 3 : if response is in fragments and valid data in the last frame is less
474 * than RWL_WIFI_FRAG_DATA_SIZE
476 if (remainingbytes
&& (totalfrag
> 0))
477 memcpy((char*)&input_buf
[seq_num
*RWL_WIFI_FRAG_DATA_SIZE
],
478 (char*)&master_list
[seq_num
]->data
, remainingbytes
);
481 write(1, (char*)input_buf
, strlen((char*)input_buf
));
484 rwl_wifi_free_list(master_list
);
488 * read out all the action frame which are queued in the driver even
489 * before issuing any wl cmd. This is essential because due to late arrival of frame it can
490 * get queued after the read expires.
493 rwl_wifi_purge_actionframes(void *wl
)
495 dot11_action_wifi_vendor_specific_t
*rec_frame
;
498 if ((rec_frame
= (dot11_action_wifi_vendor_specific_t
*)
499 malloc(RWL_WIFI_ACTION_FRAME_SIZE
)) == NULL
) {
500 DPRINT_DBG(OUTPUT
, "Purge Error in reading the frame \n");
505 if (rwl_var_getbuf(wl
, RWL_WIFI_GET_ACTION_CMD
, rec_frame
,
506 RWL_WIFI_ACTION_FRAME_SIZE
, &ptr
) < 0) {
507 DPRINT_DBG(OUTPUT
, "rwl_wifi_purge_actionframes:"
508 "Purge Error in reading the frame \n");
511 memcpy((char*)rec_frame
, ptr
, RWL_WIFI_ACTION_FRAME_SIZE
);
513 if ((rec_frame
->category
!= RWL_ACTION_WIFI_CATEGORY
))
522 * check for the channel of remote and respond if it matches with its current
523 * channel. Once the server gets the handshake cmd, it will check the channel
524 * number of the remote with its channel and if it matches , then it send out the
525 * ack to the remote client. This fucntion is used only by the server.
528 rwl_wifi_find_server_response(void *wl
, dot11_action_wifi_vendor_specific_t
*rec_frame
)
530 int error
, send
, server_channel
;
532 if (rec_frame
->type
== RWL_WIFI_FIND_MY_PEER
) {
534 rec_frame
->type
= RWL_WIFI_FOUND_PEER
;
535 /* read channel on of the SERVER */
536 rwl_wifi_config_channel(wl
, WLC_GET_CHANNEL
, &server_channel
);
537 /* overlapping channel not supported,
538 so server will only respond to client on the channel of the client
540 if (rec_frame
->data
[RWL_WIFI_CLIENT_CHANNEL_OFFSET
] == server_channel
) {
541 /* send the response by updating server channel in the frame */
542 rec_frame
->data
[RWL_WIFI_SERVER_CHANNEL_OFFSET
] = server_channel
;
543 /* change the TYPE feild for giving the ACK */
544 for (send
= 0; send
< RWL_WIFI_SEND
; send
++) {
545 if ((error
= rwl_var_send_vs_actionframe(wl
,
548 RWL_WIFI_ACTION_FRAME_SIZE
)) < 0) {
549 DPRINT_ERR(ERR
, "rwl_wifi_find_server_response: Failed"
550 "to Send the Frame %d\n", error
);
553 rwl_sleep(RWL_WIFI_SEND_DELAY
);
560 * This function is used by client only. Sends the finmypeer sync frame to remote
561 * server on diffrent channels and waits for the response.
564 rwl_find_remote_wifi_server(void *wl
, char *id
)
566 dot11_action_wifi_vendor_specific_t
*rem_wifi_send
, *rem_wifi_recv
;
567 rem_ioctl_t
*rem_ptr
= &rem_cdc
;
568 /* This list is generated considering valid channel and if this
569 * may requires updation or deletion. This needs to be identified.
570 * we have assumed that server band is not known and considered all band channels.
572 int wifichannel
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
573 11, 36, 40, 44, 48, 149, 153, 157, 161, 165};
574 int i
, error
, schannel
, channel_count
;
575 struct ether_addr
* curr_macaddr
;
577 need_speedy_response
= TRUE
;
579 if ((rem_wifi_send
= rwl_wifi_allocate_actionframe()) == NULL
) {
580 DPRINT_ERR(ERR
, " rwl_find_remote_wifi_server : Failed to allocate \n");
583 if ((rem_wifi_recv
= rwl_wifi_allocate_actionframe()) == NULL
) {
584 DPRINT_ERR(ERR
, " rwl_find_remote_wifi_server : Failed to allocate\n");
589 channel_count
= sizeof(wifichannel
) / sizeof(int);
591 /* make dummy read to make sure we don't read the already queued
592 * actionframes against the cmd we issue
594 rwl_wifi_purge_actionframes(wl
);
596 /* update the client sync specifier */
597 rem_wifi_send
->type
= RWL_WIFI_FIND_MY_PEER
;
598 /* update the CDC flag to indicate it is handshake frame */
599 rem_ptr
->msg
.cmd
= 0;
600 /* cmd =0 ,this will be ignored when server receive frame
601 * with REMOTE_FINDSERVER_IOCTL flag
603 rem_ptr
->msg
.len
= RWL_WIFI_FRAG_DATA_SIZE
;
604 rem_ptr
->msg
.flags
= REMOTE_FINDSERVER_IOCTL
;
605 rem_ptr
->data_len
= RWL_WIFI_FRAG_DATA_SIZE
;
606 rwl_swap_header(rem_ptr
, HOST_TO_NETWORK
);
608 memcpy((char*)&rem_wifi_send
->data
, (char*)rem_ptr
, REMOTE_SIZE
);
609 /* copy server mac to which ref driver needs to send unicast action frame */
610 memcpy((char*)&rem_wifi_send
->data
[RWL_REF_MAC_ADDRESS_OFFSET
], &id
[0], ETHER_ADDR_LEN
);
612 if ((ret
= rwl_var_getbuf(wl
, "cur_etheraddr", NULL
, 0, (void**) &curr_macaddr
)) < 0) {
613 DPRINT_ERR(ERR
, "Error getting current Mac addr \n");
617 memcpy((char*)&rem_wifi_send
->data
[RWL_DUT_MAC_ADDRESS_OFFSET
], (char*)curr_macaddr
->octet
,
619 /* Start with the channel in the list and keep changing till the server
620 * responds or channels list ends
622 for (i
= 0; i
< channel_count
; i
++) {
623 DPRINT_INFO(OUTPUT
, "Scanning Channel: %d ...\n", wifichannel
[i
]);
624 if ((error
= rwl_wifi_config_channel(wl
, WLC_SET_CHANNEL
,
625 &wifichannel
[i
])) < 0) {
626 DPRINT_ERR(ERR
, " Failed to set the specified channel %d\n",
630 /* send channel detail of client to server */
631 rem_wifi_send
->data
[RWL_WIFI_CLIENT_CHANNEL_OFFSET
] = wifichannel
[i
];
633 if ((error
= rwl_var_send_vs_actionframe(wl
, RWL_WIFI_ACTION_CMD
, rem_wifi_send
,
634 RWL_WIFI_ACTION_FRAME_SIZE
)) < 0) {
635 DPRINT_DBG(OUTPUT
, "Failed to Send the Frame %d\n", error
);
638 /* read the server response on the same channel */
639 if ((error
= remote_CDC_DATA_wifi_rx(wl
, rem_wifi_recv
)) < 0) {
640 rwl_sleep(RWL_CHANNEL_SCAN_WAIT
);
643 /* Verify for the Type RWL_WIFI_FOUND_PEER */
644 if (rem_wifi_recv
->type
== RWL_WIFI_FOUND_PEER
) {
645 if (rem_wifi_recv
->data
[RWL_WIFI_SERVER_CHANNEL_OFFSET
] ==
646 rem_wifi_recv
->data
[RWL_WIFI_CLIENT_CHANNEL_OFFSET
]) {
648 DPRINT_INFO(OUTPUT
, "Server is on channel # %d\n",
649 rem_wifi_recv
->data
[RWL_WIFI_SERVER_CHANNEL_OFFSET
]);
651 schannel
= rem_wifi_recv
->data
[RWL_WIFI_SERVER_CHANNEL_OFFSET
];
652 /* Set the back to the channel on which REF was originally */
653 if ((error
= rwl_wifi_config_channel(wl
,
654 WLC_SET_CHANNEL
, &schannel
) < 0)) {
655 DPRINT_ERR(ERR
, "Failed to set the specified"
656 "channel %d\n", schannel
);
658 DPRINT_ERR(ERR
, "REF now moved to the"
659 "channel of server # %d\n", schannel
);
661 need_speedy_response
= FALSE
;
662 /* we are done here, end the loop */
665 DPRINT_INFO(OUTPUT
, "Server is operating on diffrent channel."
666 "continue scanning\n");
669 /* before chaning the channel of client and sending sync frame
670 * wait for while and send
672 rwl_sleep(RWL_CHANNEL_SCAN_WAIT
);
674 need_speedy_response
= FALSE
;
680 #endif /* RWL_WIFI */
683 remote_CDC_tx_dongle(void *wl
, rem_ioctl_t
*rem_ptr
, uchar
*buf
)
685 unsigned long numwritten
;
686 char end_of_packet
[END_OF_PACK_SEP_LEN
] = "\n\n";
687 uchar loc_buf
[UART_FIFO_LEN
];
688 uint len
= END_OF_PACK_SEP_LEN
;
689 uint noframes
, frame_count
, rem_bytes
;
693 /* Converting the CDC header with keyword 'rwl ' in ascii format
694 * as dongle UART understands only ascii format.
695 * In dongle UART driver CDC structure is made from the ascii data
698 sprintf((char*)loc_buf
, "rwl %d %d %d %d ", rem_ptr
->msg
.cmd
, rem_ptr
->msg
.len
,
699 rem_ptr
->msg
.flags
, rem_ptr
->data_len
);
700 n_bytes
= strlen((char*)loc_buf
);
702 data_len
= ltoh32(rem_ptr
->data_len
);
703 DPRINT_DBG(OUTPUT
, "rwl %x %d %d %d ", ltoh32(rem_ptr
->msg
.cmd
), ltoh32(rem_ptr
->msg
.len
),
704 ltoh32(rem_ptr
->msg
.flags
), data_len
);
705 DPRINT_DBG(OUTPUT
, "CDC Header:No of bytes to be sent=%d\n", n_bytes
);
706 DPRINT_DBG(OUTPUT
, "Data:No of bytes to be sent=%d\n", data_len
);
708 /* Send the CDC Header */
709 if (rwl_write_serial_port(wl
, (char*)loc_buf
, n_bytes
, &numwritten
) < 0) {
710 DPRINT_ERR(ERR
, "CDC_Tx: Header: Write failed\n");
711 DPRINT_ERR(ERR
, "CDC_Tx: Header: numwritten %ld != n_bytes %d\n",
712 numwritten
, n_bytes
);
716 /* Dongle UART FIFO len is 64 bytes and flow control is absent.
717 * While transmitting large chunk of data the data was getting lost
718 * at UART driver so for large chunk of data 64 bytes are sent at a time
719 * folowed by delay and then next set of 64 bytes and so on.
720 * For data which is less than 64 bytes it is sent in one shot
723 noframes
= rem_ptr
->data_len
/UART_FIFO_LEN
;
725 /* Send the data now */
726 if (rwl_write_serial_port(wl
, (char*)buf
, rem_ptr
->data_len
, &numwritten
) < 0) {
727 DPRINT_ERR(ERR
, "Data_Tx: Header: Write failed\n");
728 DPRINT_ERR(ERR
, "Data_Tx: Header: numwritten %ld != len %d\n",
729 numwritten
, rem_ptr
->data_len
);
734 if (rem_ptr
->data_len
% UART_FIFO_LEN
== 0) {
735 rem_bytes
= UART_FIFO_LEN
;
737 rem_bytes
= rem_ptr
->data_len
% UART_FIFO_LEN
;
741 for (frame_count
= 0; frame_count
< noframes
; frame_count
++) {
742 if (frame_count
!= noframes
-1) {
743 memcpy(loc_buf
, (char*)(&buf
[frame_count
*UART_FIFO_LEN
]),
745 /* Send the data now */
746 if (rwl_write_serial_port(wl
, (char*)loc_buf
, UART_FIFO_LEN
,
747 &numwritten
) == -1) {
748 DPRINT_ERR(ERR
, "Data_Tx: Header: Write failed\n");
753 memcpy(loc_buf
, (char*)(&buf
[frame_count
*UART_FIFO_LEN
]),
756 if (rwl_write_serial_port(wl
, (char*)loc_buf
, rem_bytes
,
757 &numwritten
) == -1) {
758 DPRINT_ERR(ERR
, "Data_Tx: Header: Write failed\n");
763 rwl_sleep(SYNC_TIME
);
767 /* Send end of packet now */
768 if (rwl_write_serial_port(wl
, end_of_packet
, len
, &numwritten
) == -1) {
769 DPRINT_ERR(ERR
, "CDC_Tx: Header: Write failed\n");
770 DPRINT_ERR(ERR
, "CDC_Tx: Header: numwritten %ld != len %d\n",
775 DPRINT_DBG(OUTPUT
, "Packet sent!\n");
777 /* Return size of actual buffer to satisfy accounting going on above this level */
778 return (ltoh32(rem_ptr
->msg
.len
));
780 #endif /* RWL_DONGLE */
782 #if defined(RWL_SERIAL) || defined(RWL_DONGLE)|| defined(RWL_SOCKET)
784 rwl_open_pipe(int remote_type
, char *port
, int ReadTotalTimeout
, int debug
)
786 return rwl_open_transport(remote_type
, port
, ReadTotalTimeout
, debug
);
790 rwl_close_pipe(int remote_type
, void* handle
)
792 return rwl_close_transport(remote_type
, handle
);
797 remote_CDC_tx(void *wl
, uint cmd
, uchar
*buf
, uint buf_len
, uint data_len
, uint flags
, int debug
)
799 #if defined(RWL_SOCKET) || defined(RWL_SERIAL)
800 unsigned long numwritten
= 0;
802 rem_ioctl_t
*rem_ptr
= &rem_cdc
;
805 uint totalframes
, tx_count
;
806 dot11_action_wifi_vendor_specific_t
*rem_wifi_send
;
808 UNUSED_PARAMETER(debug
);
810 memset(rem_ptr
, 0, sizeof(rem_ioctl_t
));
811 rem_ptr
->msg
.cmd
= cmd
;
812 rem_ptr
->msg
.len
= buf_len
;
813 rem_ptr
->msg
.flags
= flags
;
814 rem_ptr
->data_len
= data_len
;
815 if (strlen(g_rem_ifname
) != 0)
816 strncpy(rem_ptr
->intf_name
, g_rem_ifname
, (int)IFNAMSIZ
);
817 rwl_swap_header(rem_ptr
, HOST_TO_NETWORK
);
819 if (data_len
> buf_len
) {
820 DPRINT_ERR(ERR
, "remote_CDC_tx: data_len (%d) > buf_len (%d)\n", data_len
, buf_len
);
824 if (remote_type
== REMOTE_SERIAL
) {
826 /* Send CDC header first */
827 if ((ret
= rwl_write_serial_port(wl
, (char *)rem_ptr
,
828 REMOTE_SIZE
, &numwritten
)) == -1) {
829 DPRINT_ERR(ERR
, "CDC_Tx: Data: Write failed \n");
834 /* Send data second */
835 if ((ret
= rwl_write_serial_port(wl
, (char*)buf
,
836 data_len
, &numwritten
)) == -1) {
837 DPRINT_ERR(ERR
, "CDC_Tx: Data: Write failed \n");
844 #endif /* RWL_SERIAL */
846 if (remote_type
== REMOTE_DONGLE
) {
847 return (remote_CDC_tx_dongle(wl
, rem_ptr
, buf
));
849 #endif /* RWL_DONGLE */
851 if (remote_type
== REMOTE_SOCKET
) {
854 /* Send CDC header first */
855 if ((ret
= rwl_send_to_streamsocket(*(int*)wl
, (char *)rem_ptr
,
856 REMOTE_SIZE
, 0)) == -1) {
857 DPRINT_ERR(ERR
, "CDC_Tx: Data: Write failed \n");
862 /* Send data second */
863 if ((ret
= rwl_send_to_streamsocket(*(int*)wl
, (const char*)buf
,
864 data_len
, 0)) == -1) {
865 DPRINT_ERR(ERR
, "CDC_Tx: Data: Write failed \n");
872 #endif /* RWL_SOCKET */
876 * wifi action frame is formed based on the CDC header and data.
877 * If the data is bigger than RWL_WIFI_FRAG_DATA_SIZE size, number of fragments are
878 * calculated and sent
879 * similar number of action frames with subtype incremented with sequence.
880 * Frames are sent with delay to avoid the outof order at receving end
882 if (remote_type
== REMOTE_WIFI
) {
883 if ((rem_wifi_send
= rwl_wifi_allocate_actionframe()) == NULL
) {
884 DPRINT_ERR(ERR
, "remote_CDC_tx: Failed to get allocated buffer\n");
888 if (buf_len
> RWL_WIFI_FRAG_DATA_SIZE
) {
889 /* response needs to be sent in fragments */
890 totalframes
= buf_len
/ RWL_WIFI_FRAG_DATA_SIZE
;
891 memcpy((char*)&rem_wifi_send
->data
[RWL_WIFI_CDC_HEADER_OFFSET
],
892 (char*)rem_ptr
, REMOTE_SIZE
);
893 memcpy((char*)&rem_wifi_send
->data
[REMOTE_SIZE
], &buf
[0],
894 RWL_WIFI_FRAG_DATA_SIZE
);
895 /* update type feild to inform receiver it's frammeted response frame
897 rem_wifi_send
->type
= RWL_ACTION_WIFI_FRAG_TYPE
;
898 rem_wifi_send
->subtype
= RWL_WIFI_DEFAULT_SUBTYPE
;
900 if ((error
= rwl_var_send_vs_actionframe(wl
, RWL_WIFI_ACTION_CMD
,
901 rem_wifi_send
, RWL_WIFI_ACTION_FRAME_SIZE
)) < 0) {
902 DPRINT_DBG(OUTPUT
, "Failed to Send the Frame %d\n", error
);
906 /* Send remaining bytes in fragments */
907 for (tx_count
= 1; tx_count
< totalframes
; tx_count
++) {
908 rem_wifi_send
->type
= RWL_ACTION_WIFI_FRAG_TYPE
;
909 rem_wifi_send
->subtype
= tx_count
;
910 /* First frame onwards , buf contains only data */
911 memcpy((char*)&rem_wifi_send
->data
,
912 &buf
[tx_count
*RWL_WIFI_FRAG_DATA_SIZE
], RWL_WIFI_FRAG_DATA_SIZE
);
913 if ((error
= rwl_var_send_vs_actionframe(wl
, RWL_WIFI_ACTION_CMD
,
914 rem_wifi_send
, RWL_WIFI_ACTION_FRAME_SIZE
)) < 0) {
918 rwl_sleep(RWL_WIFI_SEND_DELAY
);
921 /* Check for remaing bytes to send */
922 if ((totalframes
*RWL_WIFI_FRAG_DATA_SIZE
) != buf_len
) {
923 rem_wifi_send
->type
= RWL_ACTION_WIFI_FRAG_TYPE
;
924 rem_wifi_send
->subtype
= tx_count
;
925 memcpy((char*)&rem_wifi_send
->data
,
926 &buf
[tx_count
*RWL_WIFI_FRAG_DATA_SIZE
],
927 (buf_len
- (tx_count
*RWL_WIFI_FRAG_DATA_SIZE
)));
928 if ((error
= rwl_var_send_vs_actionframe(wl
, RWL_WIFI_ACTION_CMD
,
929 rem_wifi_send
, RWL_WIFI_ACTION_FRAME_SIZE
)) < 0) {
935 /* response fits to single frame */
936 memcpy((char*)&rem_wifi_send
->data
[RWL_WIFI_CDC_HEADER_OFFSET
],
937 (char*)rem_ptr
, REMOTE_SIZE
);
938 /* when data_len is 0 , buf will be NULL */
940 memcpy((char*)&rem_wifi_send
->data
[REMOTE_SIZE
],
943 error
= rwl_var_send_vs_actionframe(wl
, RWL_WIFI_ACTION_CMD
, rem_wifi_send
,
944 RWL_WIFI_ACTION_FRAME_SIZE
);
949 #endif /* RWL_WIFI */
955 remote_CDC_rx_hdr(void *remote
, int debug
)
959 #endif /* RWL_SOCKET */
961 rem_ioctl_t
*rem_ptr
= &rem_cdc
;
962 memset(rem_ptr
, 0, sizeof(rem_ioctl_t
));
965 UNUSED_PARAMETER(remote
);
966 UNUSED_PARAMETER(numread
);
967 #endif /* RWL_WIFI */
969 UNUSED_PARAMETER(debug
);
971 switch (remote_type
) {
972 #if defined(RWL_SERIAL) || defined(RWL_DONGLE)
975 if (rwl_read_serial_port(remote
, (char *)rem_ptr
, sizeof(rem_ioctl_t
),
977 DPRINT_ERR(ERR
, "remote_CDC_rx_hdr: Header Read failed \n");
981 #endif /* RWL_SERIAL | RWL_DONGLE */
986 ret
= rwl_receive_from_streamsocket(*(int*)remote
, (char *)rem_ptr
,
987 sizeof(rem_ioctl_t
), 0);
990 DPRINT_ERR(ERR
, "remote_CDC_rx_hdr: numread:%d", numread
);
994 DPRINT_DBG(OUTPUT
, "\n remote_CDC_rx_hdr:No data to receive\n");
1000 DPRINT_ERR(ERR
, "\n Unknown Transport Type\n");
1007 /* Return a CDC type buffer */
1009 remote_CDC_rx(void *wl
, rem_ioctl_t
*rem_ptr
, uchar
*readbuf
, uint buflen
, int debug
)
1018 UNUSED_PARAMETER(wl
);
1019 UNUSED_PARAMETER(readbuf
);
1020 UNUSED_PARAMETER(numread
);
1021 #endif /* RWL_WIFI */
1022 UNUSED_PARAMETER(buflen
);
1023 UNUSED_PARAMETER(debug
);
1024 UNUSED_PARAMETER(numread
);
1026 if (rem_ptr
->data_len
> rem_ptr
->msg
.len
) {
1027 DPRINT_ERR(ERR
, "remote_CDC_rx: remote data len (%d) > msg len (%d)\n",
1028 rem_ptr
->data_len
, rem_ptr
->msg
.len
);
1033 #if defined(RWL_DONGLE) || defined(RWL_SERIAL)
1034 if ((remote_type
== REMOTE_DONGLE
) || (remote_type
== REMOTE_SERIAL
)) {
1035 if (rwl_read_serial_port(wl
, (char*)readbuf
, rem_ptr
->data_len
,
1037 DPRINT_ERR(ERR
, "remote_CDC_rx_hdr: Data Receivefailed \n");
1041 #endif /* RWL_DONGLE || RWL_SERIAL */
1044 if (remote_type
== REMOTE_SOCKET
) {
1045 if (((ret
= rwl_receive_from_streamsocket(*(int*)wl
, (char*)readbuf
,
1046 rem_ptr
->data_len
, 0)) == -1)) {
1047 DPRINT_ERR(ERR
, "remote_CDC_rx:Data Receive failed\n");
1051 #endif /* RWL_SOCKET */
1056 rwl_sockconnect(int SockDes
, struct sockaddr
*servAddr
, int size
)
1058 DPRINT_DBG(OUTPUT
, "sockconnet SockDes=%d\n", SockDes
);
1059 if (rwl_connectsocket(SockDes
, servAddr
, size
) < 0) {
1060 DPRINT_ERR(ERR
, "\n Server is not running\n");
1065 #endif /* RWL_SOCKET */
1067 rwl_swap_header(rem_ioctl_t
*rem_ptr
, bool host_to_network
)
1069 rem_ptr
->msg
.cmd
= host_to_network
?(htol32(rem_ptr
->msg
.cmd
)):(ltoh32(rem_ptr
->msg
.cmd
));
1070 rem_ptr
->msg
.len
= host_to_network
?(htol32(rem_ptr
->msg
.len
)):(ltoh32(rem_ptr
->msg
.len
));
1071 rem_ptr
->msg
.flags
= host_to_network
?(htol32(rem_ptr
->msg
.flags
)):
1072 (ltoh32(rem_ptr
->msg
.flags
));
1073 rem_ptr
->msg
.status
= host_to_network
?(htol32(rem_ptr
->msg
.status
)):
1074 (ltoh32(rem_ptr
->msg
.status
));
1075 rem_ptr
->data_len
= host_to_network
?(htol32(rem_ptr
->data_len
)):(ltoh32(rem_ptr
->data_len
));