CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
orangepi-xunlong

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: orangepi-xunlong/orangepi-build
Path: blob/next/external/cache/sources/wl/shared/wlu_pipe.c
Views: 3959
1
/*
2
* Common Functionality for pipe
3
*
4
* $Copyright (C) 2008 Broadcom Corporation$
5
*
6
* $Id: wlu_pipe.c 385622 2013-02-16 03:40:23Z jwang $
7
*/
8
#ifdef WIN32
9
#define NEED_IR_TYPES
10
11
#include <windows.h>
12
#ifdef UNDER_CE
13
/* Expected order for succesfull compliation */
14
#include <winsock2.h>
15
#endif
16
#include <epictrl.h>
17
#include <irelay.h>
18
#endif /* WIN32 */
19
20
#ifdef LINUX
21
#include <sys/types.h>
22
#include <sys/socket.h>
23
#include <arpa/inet.h>
24
#include <unistd.h>
25
#include <netdb.h>
26
#include <signal.h>
27
#include <sys/ioctl.h>
28
#include <wlioctl.h>
29
#include <net/if.h>
30
#endif
31
32
#ifdef vxworks
33
#include "wlu_vx.h"
34
#include "inetLib.h"
35
#endif
36
#include <stdio.h>
37
#include <stdlib.h>
38
#include <string.h>
39
#include <ctype.h>
40
#ifdef TARGETOS_symbian
41
#include <sys/types.h>
42
#include <sys/socket.h>
43
#include <netinet/in.h>
44
#else
45
#if !defined(TARGETOS_nucleus) && !defined (MACOSX) && !defined (vxworks)
46
#include <malloc.h>
47
#endif
48
#endif /* TARGETOS_symbian */
49
#include <typedefs.h>
50
#include <wlioctl.h>
51
52
#include <proto/ethernet.h>
53
#include <bcmendian.h>
54
#include <bcmutils.h>
55
#include <bcmcdc.h>
56
#include <proto/802.11.h>
57
#if defined(RWL_WIFI) || defined(WIFI_REFLECTOR)
58
#include <rwl_wifi.h>
59
#endif /* defined(RWL_WIFI) || defined(WIFI_REFLECTOR) */
60
#include "wlu.h"
61
#include "wlu_remote.h"
62
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 */
68
69
#ifdef LINUX
70
/* Linux 100 usec */
71
#define SYNC_TIME 100
72
#else
73
/* WinXP 1 sec */
74
#define SYNC_TIME 1
75
#endif
76
77
#define UART_FIFO_LEN 64
78
#define END_OF_PACK_SEP_LEN 2
79
#define INIT_CMD_SLEEP 500
80
#define dtoh32(i) i
81
82
/* dword align allocation */
83
union {
84
uchar bufdata[ETHER_ADDR_LEN];
85
uint32 alignme;
86
} bufmac_wlu;
87
char *g_rwl_buf_mac = (char*) &bufmac_wlu.bufdata;
88
89
#ifdef RWL_WIFI
90
/* dword align allocation */
91
union {
92
uchar shelldata[WL_MAX_BUF_LEN];
93
uint32 alignme;
94
} shell_wlu;
95
char *g_rwl_buf_shell = (char*) &shell_wlu.shelldata;
96
int rwl_find_remote_wifi_server(void *wl, char *id);
97
int wl_ioctl(void *wl, int cmd, void *buf, int len, bool set);
98
99
/*
100
* This function runs a set of commands before running the wi-fi server
101
* This is avoids packet drops and improves performance.
102
* We run the following wl commands
103
* up, mpc 0, wsec 0, slow_timer 999999, fast_timer 999999, glacial_timer 999999
104
* legacylink 1, monitor 1.
105
*/
106
void remote_wifi_ser_init_cmds(void *wl)
107
{
108
int err;
109
char bigbuf[RWL_WIFI_BUF_LEN];
110
uint len = 0, count;
111
/* The array stores command, length and then data format */
112
remote_wifi_cmds_t wifi_cmds[] = {
113
{WLC_UP, NULL, 0x0},
114
{WLC_SET_VAR, "mpc", 0},
115
{WLC_SET_WSEC, NULL, 0x0},
116
{WLC_SET_VAR, "slow_timer", 999999},
117
{WLC_SET_VAR, "fast_timer", 999999},
118
{WLC_SET_VAR, "glacial_timer", 999999},
119
{WLC_SET_MONITOR, NULL, 0x1},
120
{WLC_SET_PM, NULL, 0x0}
121
};
122
123
for (count = 0; count < ARRAYSIZE(wifi_cmds); count++) {
124
125
if (wifi_cmds[count].data == NULL)
126
len = sizeof(int);
127
else
128
len = strlen(wifi_cmds[count].data) + 1 + sizeof(int);
129
130
/* If the command length exceeds the buffer length continue
131
* executing the next command
132
*/
133
if (len > sizeof(bigbuf)) {
134
DPRINT_ERR(ERR, "Err: command len exceeds buf len. Check"
135
"initialization cmds\n");
136
continue;
137
}
138
139
if (wifi_cmds[count].data != NULL) {
140
strcpy(bigbuf, wifi_cmds[count].data);
141
memcpy(&bigbuf[strlen(wifi_cmds[count].data)+1],
142
(char*)&wifi_cmds[count].value, sizeof(int));
143
} else {
144
memcpy(&bigbuf[0], (char*)&wifi_cmds[count].value, sizeof(int));
145
}
146
#ifdef WIN32
147
/* Add OID base for NDIS commands */
148
149
err = (int)ir_setinformation(wl, wifi_cmds[count].cmd + WL_OID_BASE,
150
bigbuf, &len);
151
#endif
152
153
#if defined(LINUX) || defined(TARGETOS_symbian) || defined(MACOSX)
154
if (wifi_cmds[count].cmd == WLC_UP)
155
/* NULL needs to be passed to the driver if WL UP command needs to
156
* be executed Otherwise driver hangs
157
*/
158
err = wl_ioctl(wl, wifi_cmds[count].cmd,
159
NULL, 0, TRUE);
160
else
161
err = wl_ioctl(wl, wifi_cmds[count].cmd,
162
(void*)&bigbuf, len, TRUE);
163
164
#elif vxworks
165
if (wifi_cmds[count].cmd == WLC_UP) {
166
/* NULL needs to be passed to the driver if WL UP command needs to
167
* be executed Otherwise driver hangs
168
*/
169
if ((err = wl_ioctl_vx(wl, wifi_cmds[count].cmd,
170
NULL, 0)) == FAIL)
171
DPRINT_ERR(ERR, "wifi_cmds: Error in wl_ioctl_vx\n");
172
}
173
else {
174
if ((err = wl_ioctl_vx(wl, wifi_cmds[count].cmd,
175
(void*)&bigbuf, len)) == FAIL)
176
DPRINT_ERR(ERR, "remote_wifi_ser_init_cmds:Error in wl_ioctl_vx\n");
177
}
178
#endif /* LINUX || TARGETOS_symbian || MACOSX */
179
rwl_sleep(INIT_CMD_SLEEP);
180
}
181
BCM_REFERENCE(err);
182
}
183
184
/* When user wants to execute local CMD being in remote wifi mode, this fucntion is used
185
* to change the remote types.
186
* This fucntion is called to swap the remote type to execute the cmd using the local
187
* driver interface.
188
* This is required for to call proper front end fucntions to achive the local set/get ioctl.
189
*/
190
void
191
rwl_wifi_swap_remote_type(int flag)
192
{
193
static int remote_flag;
194
if (flag == REMOTE_WIFI) {
195
remote_type = NO_REMOTE;
196
remote_flag = flag;
197
} else if (remote_flag == REMOTE_WIFI) {
198
remote_type = remote_flag;
199
remote_flag = flag;
200
}
201
return;
202
}
203
204
void
205
rwl_wifi_free_list(dot11_action_wifi_vendor_specific_t *list[])
206
{
207
int i;
208
for (i = 0; i < RWL_DEFAULT_WIFI_FRAG_COUNT; i++) {
209
if (list[i])
210
free(list[i]);
211
}
212
}
213
214
/*
215
* Configures local channel for finding server.
216
* Server call this fucntion for getting its current channel,
217
* client uses this fucntion for setting its channel to new channel.
218
*/
219
static int
220
rwl_wifi_config_channel(void *wl, int cmd, int *channel)
221
{
222
int error;
223
channel_info_t ci;
224
error = -1;
225
/* Get functionality is used only by server */
226
if (cmd == WLC_GET_CHANNEL) {
227
memset((char*)&ci, 0, sizeof(ci));
228
if ((error = wl_get(wl, cmd, &ci, sizeof(channel_info_t))) < 0)
229
return error;
230
ci.hw_channel = dtoh32(ci.hw_channel);
231
ci.scan_channel = dtoh32(ci.scan_channel);
232
ci.target_channel = dtoh32(ci.target_channel);
233
if (ci.scan_channel) {
234
printf("Scan in progress.\n");
235
}
236
*channel = ci.hw_channel;
237
}
238
239
if (cmd == WLC_SET_CHANNEL) {
240
/* Set functionality is used by the client */
241
ci.target_channel = *channel;
242
/* When user wants to execute local CMD being in remote wifi mode,
243
* rwl_wifi_swap_remote_type fucntion is used to change the remote types.
244
*/
245
rwl_wifi_swap_remote_type(remote_type);
246
error = wl_set(wl, cmd, &ci.target_channel, sizeof(int));
247
/* rever it back to same old remote type */
248
rwl_wifi_swap_remote_type(remote_type);
249
}
250
return error;
251
}
252
/*
253
allocate the memory for action frame and update with wifi tranport header.
254
*/
255
dot11_action_wifi_vendor_specific_t *
256
rwl_wifi_allocate_actionframe()
257
{
258
dot11_action_wifi_vendor_specific_t *action_frame;
259
260
if ((action_frame = (dot11_action_wifi_vendor_specific_t *)
261
malloc(RWL_WIFI_ACTION_FRAME_SIZE)) == NULL) {
262
DPRINT_ERR(ERR, "rwl_wifi_allocate_actionframe: unable to allocate frame \n");
263
return action_frame;
264
}
265
action_frame->category = RWL_ACTION_WIFI_CATEGORY;
266
action_frame->OUI[0] = RWL_WIFI_OUI_BYTE0;
267
action_frame->OUI[1] = RWL_WIFI_OUI_BYTE1;
268
action_frame->OUI[2] = RWL_WIFI_OUI_BYTE2;
269
action_frame->type = RWL_WIFI_DEFAULT_TYPE;
270
action_frame->subtype = RWL_WIFI_DEFAULT_SUBTYPE;
271
272
return action_frame;
273
}
274
/*
275
* Send the valid action frame (CDC+DATA) through the REF driver interface.
276
* if the CMD is "findserver" then "findmypeer" frames are sent on the diffrent
277
* channels to reconnect
278
* to with server. Other wl cmd takes the normal path.
279
* parameter 3 , i.e. buf contains the cmd line arguments and buf_len is the actual
280
* length of the buf. data_len is the length of the actual data to be sent to remote server.
281
*/
282
int
283
remote_CDC_wifi_tx(void *wl, uint cmd, uchar *buf, uint buf_len, uint data_len, uint flags)
284
{
285
rem_ioctl_t *rem_ptr = &rem_cdc;
286
int error, read_try;
287
dot11_action_wifi_vendor_specific_t *rem_wifi_send;
288
289
/* prepare CDC header */
290
rem_ptr->msg.cmd = cmd;
291
rem_ptr->msg.len = buf_len;
292
rem_ptr->msg.flags = flags;
293
rem_ptr->data_len = data_len;
294
#ifndef OLYMPIC_RWL
295
if (strlen(g_rem_ifname) != 0)
296
strncpy(rem_ptr->intf_name, g_rem_ifname, (int)IFNAMSIZ);
297
rwl_swap_header(rem_ptr, HOST_TO_NETWORK);
298
#endif
299
300
if ((data_len > buf_len)) {
301
DPRINT_ERR(ERR, "remote_CDC_wifi_tx: data_len (%d) > buf_len (%d)\n",
302
data_len, buf_len);
303
return (FAIL);
304
}
305
/* client will not send data greater than RWL_WIFI_FRAG_DATA_SIZE to server,
306
* this condition should not be hit on client side, when sending the cmd
307
* to remote server
308
*/
309
if (data_len > RWL_WIFI_FRAG_DATA_SIZE)
310
DPRINT_DBG(OUTPUT, "data size exceeds data_len %d\n", rem_ptr->msg.len);
311
312
if ((buf != NULL) && (strlen((char*)buf) >= (sizeof(RWL_WIFI_FIND_SER_CMD)-1)) &&
313
(!strcmp((char*)buf, RWL_WIFI_FIND_SER_CMD))) {
314
/* This is special case for wifi, when user wants to findserver,
315
* client has to execute it locally.Find the channel on the on
316
* which DUT is operating and sync up with specified MAC address,
317
* retry if fails to find the server
318
*/
319
for (read_try = 0; read_try < RWL_WIFI_RETRY; read_try++) {
320
if (((error = rwl_find_remote_wifi_server(wl,
321
&g_rwl_buf_mac[0])) == 0)) {
322
break;
323
}
324
}
325
return error;
326
}
327
328
if ((rem_wifi_send = rwl_wifi_allocate_actionframe()) == NULL) {
329
DPRINT_ERR(ERR, "remote_CDC_wifi_tx: Failed to allocate memory\n");
330
return (FAIL);
331
}
332
/* only data length needs to be sent to remote server using this function
333
* This function is only meant for client to send data to server
334
* Copy the CDC header and data to action frame data feild
335
* Now we have encapsulated the CDC header and data completely to in the
336
* action frame.
337
*/
338
memcpy((void*)&rem_wifi_send->data[RWL_WIFI_CDC_HEADER_OFFSET],
339
(char*)rem_ptr, REMOTE_SIZE);
340
if (buf != NULL) {
341
memcpy((void*)&rem_wifi_send->data[REMOTE_SIZE], buf, data_len);
342
}
343
344
/* Send the action frame to remote server using the rwl_var_setbuf fucntion,
345
* which will use the local driver interface to send this frame on the air
346
*/
347
if ((error = rwl_var_send_vs_actionframe(wl, RWL_WIFI_ACTION_CMD, rem_wifi_send,
348
RWL_WIFI_ACTION_FRAME_SIZE)) < 0) {
349
DPRINT_ERR(ERR, "Unable to read the action frame %d error\n", error);
350
}
351
free(rem_wifi_send);
352
return error;
353
}
354
355
/*
356
* Read the valid action frame through the REF/DUT driver interface.
357
* Retry for no of times, wait for action frame for the specified time.
358
*/
359
int
360
remote_CDC_DATA_wifi_rx(void *wl, dot11_action_wifi_vendor_specific_t * rec_frame)
361
{
362
int error, read_try;
363
void *ptr = NULL;
364
365
366
/* retry is to ensure to read late arrival action frame */
367
for (read_try = 0; read_try < RWL_WIFI_RX_RETRY; read_try++) {
368
/* read the action frame queued in the local driver wifi queue */
369
if ((error = rwl_var_getbuf(wl, RWL_WIFI_GET_ACTION_CMD, rec_frame,
370
RWL_WIFI_ACTION_FRAME_SIZE, &ptr)) < 0) {
371
DPRINT_ERR(ERR, "remote_CDC_DATA_wifi_rx: Error in reading the frame %d\n",
372
error);
373
return error;
374
}
375
/* copy the read action frame to the user frame and cjheck for the action category.
376
* If the action category matches with RWL_ACTION_WIFI_CATEGORY ,
377
* then its the valid frame, otherwise ignore it.
378
*/
379
memcpy((char*)rec_frame, ptr, RWL_WIFI_ACTION_FRAME_SIZE);
380
381
if (rec_frame->category == RWL_ACTION_WIFI_CATEGORY) {
382
break;
383
} else {
384
/* If we are executing findserver then sleep less */
385
if (!need_speedy_response)
386
rwl_sleep(RWL_WIFI_RX_DELAY);
387
else
388
rwl_sleep(RWL_CHANNEL_RX_SCAN_DELAY);
389
}
390
}
391
/* If failed to get the valid frame , indicate the error */
392
if (!(rec_frame->category == RWL_ACTION_WIFI_CATEGORY)) {
393
return (FAIL);
394
}
395
return error;
396
}
397
/*
398
* read data that has reached client in fragments. If the functtion is
399
* called from rwl_shell_information_fe then the flag will be set to 1.
400
* For shell response this function will output the response on the standard interface.
401
* Response will be coming in out of order , this fucntion will make it inorder.
402
* Duplicate action frames are ignored.
403
*/
404
int
405
remote_CDC_DATA_wifi_rx_frag(void *wl, rem_ioctl_t *rem_ptr, uint input_len,
406
void *input, bool shell)
407
{
408
int error, totalfrag, seq_num, num_frags, remainingbytes;
409
dot11_action_wifi_vendor_specific_t *rec_frame;
410
uchar *input_buf = (uchar*)input;
411
/* An array of pointers to each recieved frag */
412
dot11_action_wifi_vendor_specific_t *master_list[RWL_DEFAULT_WIFI_FRAG_COUNT];
413
414
UNUSED_PARAMETER(input_len);
415
remainingbytes = 0;
416
417
memset(master_list, 0, sizeof(master_list));
418
/* in case of shell cmd's receive size is unknown */
419
if (shell) {
420
input_buf = (uchar*)g_rwl_buf_shell;
421
memset(input_buf, 0, WL_MAX_BUF_LEN);
422
}
423
424
/* We don't yet know how many fragments we will need to read since the
425
length is contained in the first frgment of the message itself. Set
426
totalfrag to an arbitry large number and we will readjust it after we
427
successfully recieve the first frag.
428
*/
429
totalfrag = RWL_DEFAULT_WIFI_FRAG_COUNT;
430
431
for (num_frags = 0; num_frags <= totalfrag; num_frags++) {
432
if ((rec_frame = rwl_wifi_allocate_actionframe()) == NULL) {
433
DPRINT_DBG(OUTPUT, "malloc failure\n");
434
rwl_wifi_free_list(master_list);
435
return (FAIL);
436
}
437
if ((error = remote_CDC_DATA_wifi_rx((void*)wl, rec_frame)) < 0) {
438
free(rec_frame);
439
rwl_wifi_free_list(master_list);
440
return FAIL;
441
}
442
443
if (rec_frame->subtype >= RWL_DEFAULT_WIFI_FRAG_COUNT) {
444
DPRINT_DBG(OUTPUT, " Read bogus subtype %d\n", rec_frame->subtype);
445
free(rec_frame);
446
continue;
447
}
448
/* Keep only originals and discard any dup frags */
449
if (!master_list[rec_frame->subtype]) {
450
master_list[rec_frame->subtype] = rec_frame;
451
} else {
452
num_frags--;
453
free(rec_frame);
454
}
455
456
/* Look for first frag so we can accurately calculate totalfrag */
457
if (rec_frame->subtype == RWL_WIFI_DEFAULT_SUBTYPE) {
458
memcpy((char*)rem_ptr,
459
(char*)&master_list[rec_frame->subtype]->
460
data[RWL_WIFI_CDC_HEADER_OFFSET], REMOTE_SIZE);
461
rwl_swap_header(rem_ptr, NETWORK_TO_HOST);
462
totalfrag = rem_ptr->msg.len / RWL_WIFI_FRAG_DATA_SIZE;
463
remainingbytes = rem_ptr->msg.len % RWL_WIFI_FRAG_DATA_SIZE;
464
}
465
}
466
467
/* All frags are now read and there are no dups. Check for missing frags */
468
for (seq_num = 0; seq_num < totalfrag; seq_num++) {
469
if (!master_list[seq_num]) {
470
DPRINT_DBG(OUTPUT, "Missing frag number %d\n", seq_num);
471
rwl_wifi_free_list(master_list);
472
return (FAIL);
473
}
474
}
475
/*
476
case 1: response in one frame i.e if (totalfrag==0)
477
case 2: response in multiple frame ( multiple of RWL_WIFI_FRAG_DATA_SIZE)
478
case 3: response in multiple frame and not in multiple of RWL_WIFI_FRAG_DATA_SIZE
479
*/
480
481
/* case 1: Check for the response in single frame */
482
if (totalfrag == 0)
483
memcpy((char*)&input_buf[0],
484
(char*)&master_list[0]->data[REMOTE_SIZE], rem_ptr->msg.len);
485
else /* case 2: Copy fragments into contiguous frame */
486
memcpy((char*)&input_buf[0],
487
(char*)&master_list[0]->data[REMOTE_SIZE], RWL_WIFI_FRAG_DATA_SIZE);
488
489
/*
490
* If all the frames are recieved , copy them to a contigues buffer
491
*/
492
for (seq_num = 1; seq_num < totalfrag; seq_num++) {
493
memcpy((char*)&input_buf[seq_num*RWL_WIFI_FRAG_DATA_SIZE],
494
(char*)&master_list[seq_num]->data, RWL_WIFI_FRAG_DATA_SIZE);
495
}
496
497
/* case 3 : if response is in fragments and valid data in the last frame is less
498
* than RWL_WIFI_FRAG_DATA_SIZE
499
*/
500
if (remainingbytes && (totalfrag > 0))
501
memcpy((char*)&input_buf[seq_num*RWL_WIFI_FRAG_DATA_SIZE],
502
(char*)&master_list[seq_num]->data, remainingbytes);
503
504
if (shell) {
505
#ifdef LINUX
506
write(1, (char*)input_buf, strlen((char*)input_buf));
507
#else
508
fputs((char*)input_buf, stdout);
509
#endif /* LINUX */
510
}
511
512
rwl_wifi_free_list(master_list);
513
return error;
514
}
515
/*
516
* read out all the action frame which are queued in the driver even
517
* before issuing any wl cmd. This is essential because due to late arrival of frame it can
518
* get queued after the read expires.
519
*/
520
void
521
rwl_wifi_purge_actionframes(void *wl)
522
{
523
dot11_action_wifi_vendor_specific_t *rec_frame;
524
void *ptr = NULL;
525
526
if ((rec_frame = (dot11_action_wifi_vendor_specific_t *)
527
malloc(RWL_WIFI_ACTION_FRAME_SIZE)) == NULL) {
528
DPRINT_DBG(OUTPUT, "Purge Error in reading the frame \n");
529
return;
530
}
531
532
for (;;) {
533
if (rwl_var_getbuf(wl, RWL_WIFI_GET_ACTION_CMD, rec_frame,
534
RWL_WIFI_ACTION_FRAME_SIZE, &ptr) < 0) {
535
DPRINT_DBG(OUTPUT, "rwl_wifi_purge_actionframes:"
536
"Purge Error in reading the frame \n");
537
break;
538
}
539
memcpy((char*)rec_frame, ptr, RWL_WIFI_ACTION_FRAME_SIZE);
540
541
if ((rec_frame->category != RWL_ACTION_WIFI_CATEGORY))
542
break;
543
}
544
545
free(rec_frame);
546
547
return;
548
}
549
/*
550
* check for the channel of remote and respond if it matches with its current
551
* channel. Once the server gets the handshake cmd, it will check the channel
552
* number of the remote with its channel and if it matches , then it send out the
553
* ack to the remote client. This fucntion is used only by the server.
554
*/
555
void
556
rwl_wifi_find_server_response(void *wl, dot11_action_wifi_vendor_specific_t *rec_frame)
557
{
558
int error, send, server_channel;
559
560
if (rec_frame->type == RWL_WIFI_FIND_MY_PEER) {
561
562
rec_frame->type = RWL_WIFI_FOUND_PEER;
563
/* read channel on of the SERVER */
564
rwl_wifi_config_channel(wl, WLC_GET_CHANNEL, &server_channel);
565
/* overlapping channel not supported,
566
so server will only respond to client on the channel of the client
567
*/
568
if (rec_frame->data[RWL_WIFI_CLIENT_CHANNEL_OFFSET] == server_channel) {
569
/* send the response by updating server channel in the frame */
570
rec_frame->data[RWL_WIFI_SERVER_CHANNEL_OFFSET] = server_channel;
571
/* change the TYPE feild for giving the ACK */
572
for (send = 0; send < RWL_WIFI_SEND; send++) {
573
if ((error = rwl_var_send_vs_actionframe(wl,
574
RWL_WIFI_ACTION_CMD,
575
rec_frame,
576
RWL_WIFI_ACTION_FRAME_SIZE)) < 0) {
577
DPRINT_ERR(ERR, "rwl_wifi_find_server_response: Failed"
578
"to Send the Frame %d\n", error);
579
break;
580
}
581
rwl_sleep(RWL_WIFI_SEND_DELAY);
582
}
583
}
584
}
585
return;
586
}
587
/*
588
* This function is used by client only. Sends the finmypeer sync frame to remote
589
* server on diffrent channels and waits for the response.
590
*/
591
int
592
rwl_find_remote_wifi_server(void *wl, char *id)
593
{
594
dot11_action_wifi_vendor_specific_t *rem_wifi_send, *rem_wifi_recv;
595
rem_ioctl_t *rem_ptr = &rem_cdc;
596
/* This list is generated considering valid channel and if this
597
* may requires updation or deletion. This needs to be identified.
598
* we have assumed that server band is not known and considered all band channels.
599
*/
600
int wifichannel[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
601
11, 36, 40, 44, 48, 149, 153, 157, 161, 165};
602
int i, error, schannel, channel_count;
603
struct ether_addr * curr_macaddr;
604
int ret;
605
need_speedy_response = TRUE;
606
607
if ((rem_wifi_send = rwl_wifi_allocate_actionframe()) == NULL) {
608
DPRINT_ERR(ERR, " rwl_find_remote_wifi_server : Failed to allocate \n");
609
return FAIL;
610
}
611
if ((rem_wifi_recv = rwl_wifi_allocate_actionframe()) == NULL) {
612
DPRINT_ERR(ERR, " rwl_find_remote_wifi_server : Failed to allocate\n");
613
free(rem_wifi_send);
614
return FAIL;
615
}
616
617
channel_count = sizeof(wifichannel) / sizeof(int);
618
619
/* make dummy read to make sure we don't read the already queued
620
* actionframes against the cmd we issue
621
*/
622
rwl_wifi_purge_actionframes(wl);
623
624
/* update the client sync specifier */
625
rem_wifi_send->type = RWL_WIFI_FIND_MY_PEER;
626
/* update the CDC flag to indicate it is handshake frame */
627
rem_ptr->msg.cmd = 0;
628
/* cmd =0 ,this will be ignored when server receive frame
629
* with REMOTE_FINDSERVER_IOCTL flag
630
*/
631
rem_ptr->msg.len = RWL_WIFI_FRAG_DATA_SIZE;
632
rem_ptr->msg.flags = REMOTE_FINDSERVER_IOCTL;
633
rem_ptr->data_len = RWL_WIFI_FRAG_DATA_SIZE;
634
rwl_swap_header(rem_ptr, HOST_TO_NETWORK);
635
636
memcpy((char*)&rem_wifi_send->data, (char*)rem_ptr, REMOTE_SIZE);
637
/* copy server mac to which ref driver needs to send unicast action frame */
638
memcpy((char*)&rem_wifi_send->data[RWL_REF_MAC_ADDRESS_OFFSET], &id[0], ETHER_ADDR_LEN);
639
640
if ((ret = rwl_var_getbuf(wl, "cur_etheraddr", NULL, 0, (void**) &curr_macaddr)) < 0) {
641
DPRINT_ERR(ERR, "Error getting current Mac addr \n");
642
return FAIL;
643
}
644
645
memcpy((char*)&rem_wifi_send->data[RWL_DUT_MAC_ADDRESS_OFFSET], (char*)curr_macaddr->octet,
646
ETHER_ADDR_LEN);
647
/* Start with the channel in the list and keep changing till the server
648
* responds or channels list ends
649
*/
650
for (i = 0; i < channel_count; i++) {
651
DPRINT_INFO(OUTPUT, "Scanning Channel: %d ...\n", wifichannel[i]);
652
if ((error = rwl_wifi_config_channel(wl, WLC_SET_CHANNEL,
653
&wifichannel[i])) < 0) {
654
DPRINT_ERR(ERR, " Failed to set the specified channel %d\n",
655
wifichannel[i]);
656
break;
657
}
658
/* send channel detail of client to server */
659
rem_wifi_send->data[RWL_WIFI_CLIENT_CHANNEL_OFFSET] = wifichannel[i];
660
661
if ((error = rwl_var_send_vs_actionframe(wl, RWL_WIFI_ACTION_CMD, rem_wifi_send,
662
RWL_WIFI_ACTION_FRAME_SIZE)) < 0) {
663
DPRINT_DBG(OUTPUT, "Failed to Send the Frame %d\n", error);
664
break;
665
}
666
/* read the server response on the same channel */
667
if ((error = remote_CDC_DATA_wifi_rx(wl, rem_wifi_recv)) < 0) {
668
rwl_sleep(RWL_CHANNEL_SCAN_WAIT);
669
continue;
670
}
671
/* Verify for the Type RWL_WIFI_FOUND_PEER */
672
if (rem_wifi_recv->type == RWL_WIFI_FOUND_PEER) {
673
if (rem_wifi_recv->data[RWL_WIFI_SERVER_CHANNEL_OFFSET] ==
674
rem_wifi_recv->data[RWL_WIFI_CLIENT_CHANNEL_OFFSET]) {
675
676
DPRINT_INFO(OUTPUT, "Server is on channel # %d\n",
677
rem_wifi_recv->data[RWL_WIFI_SERVER_CHANNEL_OFFSET]);
678
679
schannel = rem_wifi_recv->data[RWL_WIFI_SERVER_CHANNEL_OFFSET];
680
/* Set the back to the channel on which REF was originally */
681
if ((error = rwl_wifi_config_channel(wl,
682
WLC_SET_CHANNEL, &schannel) < 0)) {
683
DPRINT_ERR(ERR, "Failed to set the specified"
684
"channel %d\n", schannel);
685
} else {
686
DPRINT_ERR(ERR, "REF now moved to the"
687
"channel of server # %d\n", schannel);
688
}
689
need_speedy_response = FALSE;
690
/* we are done here, end the loop */
691
break;
692
} else {
693
DPRINT_INFO(OUTPUT, "Server is operating on diffrent channel."
694
"continue scanning\n");
695
}
696
}
697
/* before chaning the channel of client and sending sync frame
698
* wait for while and send
699
*/
700
rwl_sleep(RWL_CHANNEL_SCAN_WAIT);
701
}
702
need_speedy_response = FALSE;
703
704
free(rem_wifi_send);
705
free(rem_wifi_recv);
706
return error;
707
}
708
#endif /* RWL_WIFI */
709
#ifdef RWL_DONGLE
710
static int
711
remote_CDC_tx_dongle(void *wl, rem_ioctl_t *rem_ptr, uchar *buf)
712
{
713
unsigned long numwritten;
714
char end_of_packet[END_OF_PACK_SEP_LEN] = "\n\n";
715
uchar loc_buf[UART_FIFO_LEN];
716
uint len = END_OF_PACK_SEP_LEN;
717
uint noframes, frame_count, rem_bytes;
718
uint n_bytes;
719
uint data_len;
720
721
/* Converting the CDC header with keyword 'rwl ' in ascii format
722
* as dongle UART understands only ascii format.
723
* In dongle UART driver CDC structure is made from the ascii data
724
* it received.
725
*/
726
sprintf((char*)loc_buf, "rwl %d %d %d %d ", rem_ptr->msg.cmd, rem_ptr->msg.len,
727
rem_ptr->msg.flags, rem_ptr->data_len);
728
n_bytes = strlen((char*)loc_buf);
729
730
data_len = ltoh32(rem_ptr->data_len);
731
DPRINT_DBG(OUTPUT, "rwl %x %d %d %d ", ltoh32(rem_ptr->msg.cmd), ltoh32(rem_ptr->msg.len),
732
ltoh32(rem_ptr->msg.flags), data_len);
733
DPRINT_DBG(OUTPUT, "CDC Header:No of bytes to be sent=%d\n", n_bytes);
734
DPRINT_DBG(OUTPUT, "Data:No of bytes to be sent=%d\n", data_len);
735
736
/* Send the CDC Header */
737
if (rwl_write_serial_port(wl, (char*)loc_buf, n_bytes, &numwritten) < 0) {
738
DPRINT_ERR(ERR, "CDC_Tx: Header: Write failed\n");
739
DPRINT_ERR(ERR, "CDC_Tx: Header: numwritten %ld != n_bytes %d\n",
740
numwritten, n_bytes);
741
return (FAIL);
742
}
743
744
/* Dongle UART FIFO len is 64 bytes and flow control is absent.
745
* While transmitting large chunk of data the data was getting lost
746
* at UART driver so for large chunk of data 64 bytes are sent at a time
747
* folowed by delay and then next set of 64 bytes and so on.
748
* For data which is less than 64 bytes it is sent in one shot
749
*/
750
751
noframes = rem_ptr->data_len/UART_FIFO_LEN;
752
if (noframes == 0) {
753
/* Send the data now */
754
if (rwl_write_serial_port(wl, (char*)buf, rem_ptr->data_len, &numwritten) < 0) {
755
DPRINT_ERR(ERR, "Data_Tx: Header: Write failed\n");
756
DPRINT_ERR(ERR, "Data_Tx: Header: numwritten %ld != len %d\n",
757
numwritten, rem_ptr->data_len);
758
return (FAIL);
759
}
760
761
} else {
762
if (rem_ptr->data_len % UART_FIFO_LEN == 0) {
763
rem_bytes = UART_FIFO_LEN;
764
} else {
765
rem_bytes = rem_ptr->data_len % UART_FIFO_LEN;
766
noframes += 1;
767
}
768
769
for (frame_count = 0; frame_count < noframes; frame_count++) {
770
if (frame_count != noframes-1) {
771
memcpy(loc_buf, (char*)(&buf[frame_count*UART_FIFO_LEN]),
772
UART_FIFO_LEN);
773
/* Send the data now */
774
if (rwl_write_serial_port(wl, (char*)loc_buf, UART_FIFO_LEN,
775
&numwritten) == -1) {
776
DPRINT_ERR(ERR, "Data_Tx: Header: Write failed\n");
777
return (-1);
778
}
779
780
} else {
781
memcpy(loc_buf, (char*)(&buf[frame_count*UART_FIFO_LEN]),
782
rem_bytes);
783
784
if (rwl_write_serial_port(wl, (char*)loc_buf, rem_bytes,
785
&numwritten) == -1) {
786
DPRINT_ERR(ERR, "Data_Tx: Header: Write failed\n");
787
return (-1);
788
}
789
790
}
791
rwl_sleep(SYNC_TIME);
792
}
793
}
794
795
/* Send end of packet now */
796
if (rwl_write_serial_port(wl, end_of_packet, len, &numwritten) == -1) {
797
DPRINT_ERR(ERR, "CDC_Tx: Header: Write failed\n");
798
DPRINT_ERR(ERR, "CDC_Tx: Header: numwritten %ld != len %d\n",
799
numwritten, len);
800
return (FAIL);
801
}
802
803
DPRINT_DBG(OUTPUT, "Packet sent!\n");
804
805
/* Return size of actual buffer to satisfy accounting going on above this level */
806
return (ltoh32(rem_ptr->msg.len));
807
}
808
#endif /* RWL_DONGLE */
809
810
#if defined (RWL_SERIAL) || defined (RWL_DONGLE)|| defined (RWL_SOCKET)
811
void *
812
rwl_open_pipe(int remote_type, char *port, int ReadTotalTimeout, int debug)
813
{
814
return rwl_open_transport(remote_type, port, ReadTotalTimeout, debug);
815
}
816
817
int
818
rwl_close_pipe(int remote_type, void* handle)
819
{
820
return rwl_close_transport(remote_type, handle);
821
}
822
#endif
823
824
int
825
remote_CDC_tx(void *wl, uint cmd, uchar *buf, uint buf_len, uint data_len, uint flags, int debug)
826
{
827
#ifdef RWL_SERIAL
828
unsigned long numwritten = 0;
829
#endif
830
rem_ioctl_t *rem_ptr = &rem_cdc;
831
#ifdef RWL_WIFI
832
int error;
833
uint totalframes, tx_count;
834
dot11_action_wifi_vendor_specific_t *rem_wifi_send;
835
#endif
836
UNUSED_PARAMETER(debug);
837
UNUSED_PARAMETER(buf);
838
UNUSED_PARAMETER(wl);
839
840
memset(rem_ptr, 0, sizeof(rem_ioctl_t));
841
rem_ptr->msg.cmd = cmd;
842
rem_ptr->msg.len = buf_len;
843
rem_ptr->msg.flags = flags;
844
rem_ptr->data_len = data_len;
845
#ifndef OLYMPIC_RWL
846
if (strlen(g_rem_ifname) != 0)
847
strncpy(rem_ptr->intf_name, g_rem_ifname, (int)IFNAMSIZ);
848
rwl_swap_header(rem_ptr, HOST_TO_NETWORK);
849
#endif
850
if (data_len > buf_len) {
851
DPRINT_ERR(ERR, "remote_CDC_tx: data_len (%d) > buf_len (%d)\n", data_len, buf_len);
852
return (FAIL);
853
}
854
#ifdef RWL_SERIAL
855
if (remote_type == REMOTE_SERIAL) {
856
int ret;
857
/* Send CDC header first */
858
if ((ret = rwl_write_serial_port(wl, (char *)rem_ptr,
859
REMOTE_SIZE, &numwritten)) == -1) {
860
DPRINT_ERR(ERR, "CDC_Tx: Data: Write failed \n");
861
return (FAIL);
862
}
863
numwritten = ret;
864
865
/* Send data second */
866
if ((ret = rwl_write_serial_port(wl, (char*)buf,
867
data_len, &numwritten)) == -1) {
868
DPRINT_ERR(ERR, "CDC_Tx: Data: Write failed \n");
869
return (FAIL);
870
}
871
numwritten = ret;
872
873
return (buf_len);
874
}
875
#endif /* RWL_SERIAL */
876
#ifdef RWL_DONGLE
877
if (remote_type == REMOTE_DONGLE) {
878
return (remote_CDC_tx_dongle(wl, rem_ptr, buf));
879
}
880
#endif /* RWL_DONGLE */
881
#ifdef RWL_SOCKET
882
if (remote_type == REMOTE_SOCKET) {
883
int ret;
884
885
/* Send CDC header first */
886
if ((ret = rwl_send_to_streamsocket(*(int*)wl, (char *)rem_ptr,
887
REMOTE_SIZE, 0)) == -1) {
888
DPRINT_ERR(ERR, "CDC_Tx: Data: Write failed \n");
889
return (FAIL);
890
}
891
892
/* Send data second */
893
if ((ret = rwl_send_to_streamsocket(*(int*)wl, (const char*)buf,
894
data_len, 0)) == -1) {
895
DPRINT_ERR(ERR, "CDC_Tx: Data: Write failed \n");
896
return (FAIL);
897
}
898
899
return (buf_len);
900
}
901
#endif /* RWL_SOCKET */
902
903
#ifdef RWL_WIFI
904
/*
905
* wifi action frame is formed based on the CDC header and data.
906
* If the data is bigger than RWL_WIFI_FRAG_DATA_SIZE size, number of fragments are
907
* calculated and sent
908
* similar number of action frames with subtype incremented with sequence.
909
* Frames are sent with delay to avoid the outof order at receving end
910
*/
911
if (remote_type == REMOTE_WIFI) {
912
if ((rem_wifi_send = rwl_wifi_allocate_actionframe()) == NULL) {
913
DPRINT_ERR(ERR, "remote_CDC_tx: Failed to get allocated buffer\n");
914
return (FAIL);
915
}
916
917
if (buf_len > RWL_WIFI_FRAG_DATA_SIZE) {
918
/* response needs to be sent in fragments */
919
totalframes = buf_len / RWL_WIFI_FRAG_DATA_SIZE;
920
memcpy((char*)&rem_wifi_send->data[RWL_WIFI_CDC_HEADER_OFFSET],
921
(char*)rem_ptr, REMOTE_SIZE);
922
memcpy((char*)&rem_wifi_send->data[REMOTE_SIZE], &buf[0],
923
RWL_WIFI_FRAG_DATA_SIZE);
924
/* update type feild to inform receiver it's frammeted response frame
925
*/
926
rem_wifi_send->type = RWL_ACTION_WIFI_FRAG_TYPE;
927
rem_wifi_send->subtype = RWL_WIFI_DEFAULT_SUBTYPE;
928
929
if ((error = rwl_var_send_vs_actionframe(wl, RWL_WIFI_ACTION_CMD,
930
rem_wifi_send, RWL_WIFI_ACTION_FRAME_SIZE)) < 0) {
931
DPRINT_DBG(OUTPUT, "Failed to Send the Frame %d\n", error);
932
free(rem_wifi_send);
933
return error;
934
}
935
/* Send remaining bytes in fragments */
936
for (tx_count = 1; tx_count < totalframes; tx_count++) {
937
rem_wifi_send->type = RWL_ACTION_WIFI_FRAG_TYPE;
938
rem_wifi_send->subtype = tx_count;
939
/* First frame onwards , buf contains only data */
940
memcpy((char*)&rem_wifi_send->data,
941
&buf[tx_count*RWL_WIFI_FRAG_DATA_SIZE], RWL_WIFI_FRAG_DATA_SIZE);
942
if ((error = rwl_var_send_vs_actionframe(wl, RWL_WIFI_ACTION_CMD,
943
rem_wifi_send, RWL_WIFI_ACTION_FRAME_SIZE)) < 0) {
944
free(rem_wifi_send);
945
return error;
946
}
947
rwl_sleep(RWL_WIFI_SEND_DELAY);
948
}
949
950
/* Check for remaing bytes to send */
951
if ((totalframes*RWL_WIFI_FRAG_DATA_SIZE) != buf_len) {
952
rem_wifi_send->type = RWL_ACTION_WIFI_FRAG_TYPE;
953
rem_wifi_send->subtype = tx_count;
954
memcpy((char*)&rem_wifi_send->data,
955
&buf[tx_count*RWL_WIFI_FRAG_DATA_SIZE],
956
(buf_len - (tx_count*RWL_WIFI_FRAG_DATA_SIZE)));
957
if ((error = rwl_var_send_vs_actionframe(wl, RWL_WIFI_ACTION_CMD,
958
rem_wifi_send, RWL_WIFI_ACTION_FRAME_SIZE)) < 0) {
959
free(rem_wifi_send);
960
return error;
961
}
962
}
963
} else {
964
/* response fits to single frame */
965
memcpy((char*)&rem_wifi_send->data[RWL_WIFI_CDC_HEADER_OFFSET],
966
(char*)rem_ptr, REMOTE_SIZE);
967
/* when data_len is 0 , buf will be NULL */
968
if (buf != NULL) {
969
memcpy((char*)&rem_wifi_send->data[REMOTE_SIZE],
970
&buf[0], data_len);
971
}
972
error = rwl_var_send_vs_actionframe(wl, RWL_WIFI_ACTION_CMD, rem_wifi_send,
973
RWL_WIFI_ACTION_FRAME_SIZE);
974
free(rem_wifi_send);
975
return error;
976
}
977
}
978
#endif /* RWL_WIFI */
979
return (0);
980
}
981
982
983
rem_ioctl_t *
984
remote_CDC_rx_hdr(void *remote, int debug)
985
{
986
#ifdef RWL_SOCKET
987
int ret;
988
#endif /* RWL_SOCKET */
989
990
#if defined(RWL_SERIAL) || defined (RWL_DONGLE) || defined (RWL_SOCKET)
991
uint numread = 0;
992
#endif
993
rem_ioctl_t *rem_ptr = &rem_cdc;
994
memset(rem_ptr, 0, sizeof(rem_ioctl_t));
995
996
UNUSED_PARAMETER(remote);
997
UNUSED_PARAMETER(debug);
998
999
switch (remote_type) {
1000
#if defined(RWL_SERIAL) || defined (RWL_DONGLE)
1001
case REMOTE_SERIAL:
1002
case REMOTE_DONGLE:
1003
if (rwl_read_serial_port(remote, (char *)rem_ptr, sizeof(rem_ioctl_t),
1004
&numread) < 0) {
1005
DPRINT_ERR(ERR, "remote_CDC_rx_hdr: Header Read failed \n");
1006
return (NULL);
1007
}
1008
break;
1009
#endif /* RWL_SERIAL | RWL_DONGLE */
1010
1011
1012
#ifdef RWL_SOCKET
1013
case REMOTE_SOCKET:
1014
ret = rwl_receive_from_streamsocket(*(int*)remote, (char *)rem_ptr,
1015
sizeof(rem_ioctl_t), 0);
1016
numread = ret;
1017
if (ret == -1) {
1018
DPRINT_ERR(ERR, "remote_CDC_rx_hdr: numread:%d", numread);
1019
return (NULL);
1020
}
1021
if (numread == 0) {
1022
DPRINT_DBG(OUTPUT, "\n remote_CDC_rx_hdr:No data to receive\n");
1023
return NULL;
1024
}
1025
break;
1026
#endif
1027
default:
1028
DPRINT_ERR(ERR, "\n Unknown Transport Type\n");
1029
break;
1030
}
1031
1032
return (rem_ptr);
1033
}
1034
1035
/* Return a CDC type buffer */
1036
int
1037
remote_CDC_rx(void *wl, rem_ioctl_t *rem_ptr, uchar *readbuf, uint buflen, int debug)
1038
{
1039
uint numread = 0;
1040
1041
#ifdef RWL_SOCKET
1042
int ret;
1043
#endif
1044
1045
#ifdef RWL_WIFI
1046
UNUSED_PARAMETER(numread);
1047
#endif /* RWL_WIFI */
1048
UNUSED_PARAMETER(wl);
1049
UNUSED_PARAMETER(readbuf);
1050
UNUSED_PARAMETER(buflen);
1051
UNUSED_PARAMETER(debug);
1052
UNUSED_PARAMETER(numread);
1053
1054
if (rem_ptr->data_len > rem_ptr->msg.len) {
1055
DPRINT_ERR(ERR, "remote_CDC_rx: remote data len (%d) > msg len (%d)\n",
1056
rem_ptr->data_len, rem_ptr->msg.len);
1057
return (FAIL);
1058
}
1059
1060
1061
#if defined (RWL_DONGLE) || defined (RWL_SERIAL)
1062
if ((remote_type == REMOTE_DONGLE) || (remote_type == REMOTE_SERIAL)) {
1063
if (rwl_read_serial_port(wl, (char*)readbuf, rem_ptr->data_len,
1064
&numread) < 0) {
1065
DPRINT_ERR(ERR, "remote_CDC_rx_hdr: Data Receivefailed \n");
1066
return (FAIL);
1067
}
1068
}
1069
#endif /* RWL_DONGLE || RWL_SERIAL */
1070
1071
#ifdef RWL_SOCKET
1072
if (remote_type == REMOTE_SOCKET) {
1073
if (((ret = rwl_receive_from_streamsocket(*(int*)wl, (char*)readbuf,
1074
rem_ptr->data_len, 0)) == -1)) {
1075
DPRINT_ERR(ERR, "remote_CDC_rx:Data Receive failed\n");
1076
return (FAIL);
1077
}
1078
}
1079
#endif /* RWL_SOCKET */
1080
return (SUCCESS);
1081
}
1082
#ifdef RWL_SOCKET
1083
int
1084
rwl_sockconnect(int SockDes, struct sockaddr *servAddr, int size)
1085
{
1086
DPRINT_DBG(OUTPUT, "sockconnet SockDes=%d\n", SockDes);
1087
if (rwl_connectsocket(SockDes, servAddr, size) < 0) {
1088
DPRINT_ERR(ERR, "\n rwl_socketconnect failed\n");
1089
return FAIL;
1090
}
1091
return SUCCESS;
1092
}
1093
#endif /* RWL_SOCKET */
1094
void
1095
rwl_swap_header(rem_ioctl_t *rem_ptr, bool host_to_network)
1096
{
1097
rem_ptr->msg.cmd = host_to_network?(htol32(rem_ptr->msg.cmd)):(ltoh32(rem_ptr->msg.cmd));
1098
rem_ptr->msg.len = host_to_network?(htol32(rem_ptr->msg.len)):(ltoh32(rem_ptr->msg.len));
1099
rem_ptr->msg.flags = host_to_network?(htol32(rem_ptr->msg.flags)):
1100
(ltoh32(rem_ptr->msg.flags));
1101
rem_ptr->msg.status = host_to_network?(htol32(rem_ptr->msg.status)):
1102
(ltoh32(rem_ptr->msg.status));
1103
rem_ptr->data_len = host_to_network?(htol32(rem_ptr->data_len)):(ltoh32(rem_ptr->data_len));
1104
}
1105
1106