2 * linux version of remote Wl transport mechanisms (pipes).
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_linux.c,v 1.14 2009-11-10 20:02:55 Exp $
15 /* Revision History: Linux version of remote Wl transport mechanisms (pipes).
17 * Date Author Description
19 * 27-Dec-2007 Suganthi Version 0.0
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #include <arpa/inet.h>
33 #include <sys/ioctl.h>
37 #include <proto/802.11.h>
38 #include <bcmendian.h>
40 #include <proto/802.11.h>
43 #include <netinet/in.h>
46 #include "wlu_remote.h"
48 #if defined(RWL_DONGLE) || defined(RWL_SERIAL)
49 #define READ_DELAY 500000
50 #define BAUD_RATE_115200 115200
53 #define LINUX_SYNC_DELAY 200
54 extern char *g_rwl_device_name_serial
;
57 #define MICRO_SEC_CONVERTER_VAL 1000
62 #define MAX_INTERFACE_NAME 32
65 rwl_opensocket(int AddrFamily
, int Type
, int Protocol
)
69 if ((SockDes
= socket(AddrFamily
, Type
, Protocol
)) == -1) {
70 perror("rwl_opensocket Fails:");
71 DPRINT_ERR(ERR
, "\nerrno:%d\n", errno
);
78 rwl_set_socket_option(int SocketDes
, int Level
, int OptName
, int Val
)
80 if (setsockopt(SocketDes
, Level
, OptName
, &Val
, sizeof(int)) == -1) {
81 perror("Error at SetTCPSocketOpt()");
82 DPRINT_ERR(ERR
, "\n errno:%d\n", errno
);
88 /* Function to connect with the server waiting in the same port */
90 rwl_connectsocket(int SocketDes
, struct sockaddr
* SerAddr
, int SizeOfAddr
)
92 if (connect(SocketDes
, SerAddr
, SizeOfAddr
) == -1) {
93 perror("Failed to connect() to server");
94 DPRINT_ERR(ERR
, "\n errno:%d\n", errno
);
101 * Function for associating a local address with a socket.
104 rwl_bindsocket(int SocketDes
, struct sockaddr
* MyAddr
, int SizeOfAddr
)
106 if (bind(SocketDes
, MyAddr
, SizeOfAddr
) == -1) {
107 perror("Error at rwl_bindSocket()");
108 DPRINT_ERR(ERR
, "\n errno:%d\n", errno
);
115 * Function for making the socket to listen for incoming connection.
118 rwl_listensocket(int SocketDes
, int BackLog
)
120 if (listen(SocketDes
, BackLog
) == -1) {
121 perror("Error at rwl_listensocket()");
122 DPRINT_ERR(ERR
, "\n errno:%d\n", errno
);
129 * Function for permitting an incoming connection attempt on a socket
130 * Function called by server
133 rwl_acceptconnection(int SocketDes
, struct sockaddr
* ClientAddr
, int *SizeOfAddr
)
137 if ((NewSockDes
= accept(SocketDes
, ClientAddr
, (socklen_t
*)SizeOfAddr
)) == -1) {
138 perror("Error at rwl_acceptConnection()");
139 DPRINT_ERR(ERR
, "\n errno:%d\n", errno
);
146 rwl_closesocket(int SocketDes
)
148 if (close(SocketDes
) == -1) {
149 perror("Error at rwl_closeSocket()");
150 DPRINT_ERR(ERR
, "\n errno:%d\n", errno
);
156 /* Transmit the response in the opened TCP stream socket */
158 rwl_send_to_streamsocket(int SocketDes
, const char* SendBuff
, int data_size
, int Flag
)
160 int total_numwritten
= 0, numwritten
= 0;
161 while (total_numwritten
< data_size
) {
162 if ((numwritten
= send(SocketDes
, SendBuff
,
163 data_size
- total_numwritten
, Flag
)) == -1) {
164 perror("Failed to send()");
165 DPRINT_ERR(ERR
, "\n errno:%d\n", errno
);
169 /* Sent successfully at first attempt no more retries */
170 if (numwritten
== data_size
) {
171 total_numwritten
= numwritten
;
175 /* If socket is busy we may hit this condition */
176 if (numwritten
!= data_size
- total_numwritten
) {
177 DPRINT_DBG(OUTPUT
, "wanted to send %d bytes sent only %d bytes\n",
178 data_size
- total_numwritten
, numwritten
);
181 /* Now send the remaining buffer */
182 total_numwritten
+= numwritten
;
183 SendBuff
+= numwritten
;
186 return total_numwritten
;
189 /* Receive the response from the opened TCP stream socket */
191 rwl_receive_from_streamsocket(int SocketDes
, char* RecvBuff
, int data_size
, int Flag
)
194 int total_numread
= 0;
196 while (total_numread
< data_size
) {
197 if ((numread
= recv(SocketDes
, RecvBuff
, data_size
- total_numread
, Flag
)) == -1) {
198 perror("Failed to Receive()");
199 DPRINT_ERR(ERR
, "\n errno:%d\n", errno
);
203 if (numread
!= data_size
- total_numread
) {
204 DPRINT_DBG(OUTPUT
, "asked %d bytes got %d bytes\n",
205 data_size
- total_numread
, numread
);
211 total_numread
+= numread
;
220 rwl_init_server_socket_setup(int argc
, char** argv
, uint remote_type
)
222 char netif
[MAX_INTERFACE_NAME
];
223 unsigned short servPort
;
224 struct sockaddr_in ServerAddress
;
225 int err
, SockDes
, val
;
228 servPort
= DEFAULT_SERVER_PORT
;
231 strcpy(netif
, "en0");
233 strcpy(netif
, "eth0");
236 /* User option can override default arguments */
240 if (isalpha(**argv
) == FALSE
) {
241 DPRINT_ERR(ERR
, "USAGE ERROR:Incorrect network interface\n");
244 strcpy(netif
, *argv
);
247 if (isdigit(**argv
) == FALSE
) {
248 DPRINT_ERR(ERR
, "USAGE ERROR:Incorrect port\n");
251 servPort
= atoi(*argv
);
257 if (isalpha(**argv
) == FALSE
) {
258 if (isdigit(**argv
) == FALSE
) {
259 DPRINT_ERR(ERR
, "USAGE ERROR\n");
263 servPort
= atoi(*argv
);
266 strcpy(netif
, *argv
);
269 DPRINT_INFO(OUTPUT
, "INFO: Network Interface:%s, Port:%d\n",
272 if ((SockDes
= (*(int *)rwl_open_transport(remote_type
, NULL
, 0, 0))) == FAIL
)
276 if ((rwl_set_socket_option(SockDes
, SOL_SOCKET
, SO_REUSEADDR
, val
)) == FAIL
)
279 memset(&ServerAddress
, 0, sizeof(ServerAddress
));
281 rwl_GetifAddr(netif
, &ServerAddress
);
282 ServerAddress
.sin_family
= AF_INET
; /* host byte order */
283 ServerAddress
.sin_port
= hton16(servPort
); /* short, network byte order */
285 if (((err
= rwl_bindsocket(SockDes
, (struct sockaddr
*)&ServerAddress
,
286 sizeof(ServerAddress
))) == FAIL
))
288 if ((err
= rwl_listensocket(SockDes
, BACKLOG
)) == FAIL
)
291 DPRINT_DBG(OUTPUT
, "Waiting for client to connect...\n");
296 int rwl_GetifAddr(char *ifname
, struct sockaddr_in
*sa
)
299 int fd
= socket(PF_INET
, SOCK_DGRAM
, IPPROTO_IP
);
303 DPRINT_ERR(ERR
, "socket open error\n");
307 strcpy(ifr
.ifr_name
, ifname
);
308 ifr
.ifr_addr
.sa_family
= AF_INET
;
309 if (ioctl(fd
, SIOCGIFADDR
, &ifr
) == 0)
311 memcpy(sa
, (struct sockaddr_in
*)&ifr
.ifr_addr
, sizeof(struct sockaddr_in
));
320 #endif /* RWL_SOCKET */
322 #if defined(RWL_SERIAL) || defined(RWL_DONGLE)
324 rwl_open_serial(int remote_type
, char *port
)
329 long BAUD
, DATABITS
, STOPBITS
, PARITYON
;
332 DPRINT_DBG(OUTPUT
, "\n rwl_open_serial:%s\n", port
);
333 if (remote_type
== REMOTE_DONGLE
)
334 fCom
= open(port
, O_RDWR
| O_NOCTTY
| O_NDELAY
);
336 fCom
= open(port
, O_RDWR
| O_NOCTTY
| O_NDELAY
| O_SYNC
);
338 DPRINT_ERR(ERR
, "open COM failed with error %d.\n", errno
);
341 /* To make the read as a blocking operation */
342 fcntl(fCom
, F_SETFL
, 0);
345 bzero(&tio
, sizeof(tio
));
346 /* Get the current option for the port... */
347 tcgetattr(fCom
, &tio
);
348 /* Set the baud rate */
349 cfsetispeed(&tio
, B115200
);
350 cfsetospeed(&tio
, B115200
);
351 if (remote_type
== REMOTE_DONGLE
) {
352 if (tcsetattr(fCom
, TCSANOW
, &tio
) < 0) {
353 perror("tcsetattr:setspeed");
357 baud_rate
= cfgetospeed(&tio
);
358 if (baud_rate
== B115200
)
359 speed
= BAUD_RATE_115200
;
360 DPRINT_DBG(OUTPUT
, "Baud_rate set is:%d\n", speed
);
367 tio
.c_cflag
= BAUD
| DATABITS
| STOPBITS
| PARITYON
| CLOCAL
| CREAD
;
368 tio
.c_iflag
= IGNPAR
;
371 tio
.c_cc
[VMIN
] = VMIN_VAL
;
372 tio
.c_cc
[VTIME
] = VTIME_VAL
;
374 tcflush(fCom
, TCIOFLUSH
);
375 if (tcsetattr(fCom
, TCSANOW
, &tio
) < 0) {
376 perror("tcsetattr:");
380 if (tcgetattr(fCom
, &tio
) < 0) {
381 perror("tcgetattr:");
385 DPRINT_DBG(OUTPUT
, "tcgetattr:VMIN is:%d\n", tio
.c_cc
[VMIN
]);
386 DPRINT_DBG(OUTPUT
, "tcgetattr:VTIME is:%d\n", tio
.c_cc
[VTIME
]);
387 tcflush(fCom
, TCIOFLUSH
);
390 UNUSED_PARAMETER(PARITYON
);
391 UNUSED_PARAMETER(STOPBITS
);
392 UNUSED_PARAMETER(DATABITS
);
393 UNUSED_PARAMETER(BAUD
);
394 UNUSED_PARAMETER(baud_rate
);
395 UNUSED_PARAMETER(speed
);
397 /* Enable the receiver and set local mode */
398 tio
.c_cflag
|= (CLOCAL
| CREAD
);
400 tio
.c_cflag
&= ~PARENB
;
401 tio
.c_cflag
&= ~CSTOPB
;
402 tio
.c_cflag
&= ~CSIZE
;
404 tio
.c_cc
[VTIME
] = 255;
408 tio
.c_iflag
|= IGNBRK
;
410 tio
.c_oflag
&= ~OPOST
;
411 tio
.c_oflag
&= ~OLCUC
;
412 tio
.c_oflag
&= ~ONLCR
;
413 tio
.c_oflag
&= ~OCRNL
;
414 tio
.c_oflag
&= ~ONOCR
;
415 tio
.c_oflag
&= ~ONLRET
;
416 tio
.c_oflag
&= ~OFILL
;
418 tio
.c_lflag
&= ~ICANON
;
419 tio
.c_lflag
&= ~ISIG
;
420 tio
.c_lflag
&= ~XCASE
;
421 tio
.c_lflag
&= ~ECHO
;
422 tio
.c_lflag
&= ~FLUSHO
;
423 tio
.c_lflag
&= ~IEXTEN
;
424 tio
.c_lflag
|= NOFLSH
;
425 /* Set the new tio for the port... */
426 tcsetattr(fCom
, TCSANOW
, &tio
);
427 tcflush(fCom
, TCIOFLUSH
);
432 rwl_write_serial_port(void* hndle
, char* write_buf
, unsigned long size
, unsigned long *numwritten
)
436 ret
= write((*(int *)hndle
), (const void*)write_buf
, size
);
439 perror("WriteToPort Failed");
440 DPRINT_ERR(ERR
, "Errno:%d\n", errno
);
443 if (*numwritten
!= size
) {
444 DPRINT_ERR(ERR
, "rwl_write_serial_port failed numwritten %ld != len %ld\n",
452 rwl_read_serial_port(void* hndle
, char* read_buf
, uint data_size
, uint
*numread
)
455 uint total_numread
= 0;
456 while (total_numread
< data_size
) {
457 ret
= read(*(int *)hndle
, read_buf
, data_size
- total_numread
);
461 perror("ReadFromPort Failed");
462 DPRINT_ERR(ERR
, "Errno:%d\n", errno
);
465 if (*numread
!= data_size
- total_numread
) {
466 DPRINT_DBG(OUTPUT
, "asked for %d bytes got %d bytes\n",
467 data_size
- total_numread
, *numread
);
472 total_numread
+= *numread
;
473 read_buf
+= *numread
;
479 rwl_sync_delay(uint noframes
)
482 rwl_sleep(LINUX_SYNC_DELAY
);
486 #endif /* RWL_DONGLE ||RWL_SERIAL */
488 #if defined(RWL_DONGLE) || defined(RWL_SOCKET) || defined(RWL_SERIAL)
490 rwl_open_transport(int remote_type
, char *port
, int ReadTotalTimeout
, int debug
)
494 UNUSED_PARAMETER(port
);
495 UNUSED_PARAMETER(ReadTotalTimeout
);
496 UNUSED_PARAMETER(debug
);
498 switch (remote_type
) {
499 #if defined(RWL_DONGLE) || defined(RWL_SERIAL)
502 g_rwl_device_name_serial
= port
;
505 if ((g_irh
= rwl_open_serial(remote_type
, g_rwl_device_name_serial
))
507 /* Initial port opening settings failed in reboot.
508 * So retry opening the serial port
510 if ((g_irh
= rwl_open_serial(remote_type
, g_rwl_device_name_serial
))
512 DPRINT_ERR(ERR
, "Can't open serial port\n");
517 #endif /* RWL_DONGLE || RWL_SERIAL */
521 if ((g_irh
= rwl_opensocket(AF_INET
, SOCK_STREAM
, IPPROTO_TCP
)) == FAIL
) {
522 DPRINT_ERR(ERR
, "\nCan't open socket \n");
527 #endif /* RWL_SOCKET */
530 DPRINT_ERR(ERR
, "rwl_open_transport: Unknown remote_type %d\n", remote_type
);
533 } /* end - switch case */
535 hndle
= (void*) &g_irh
;
540 rwl_close_transport(int remote_type
, void* Des
)
542 switch (remote_type
) {
545 if (rwl_closesocket(*(int *)Des
) == FAIL
)
548 #endif /* RWL_SOCKET */
550 #if defined(RWL_DONGLE) || defined(RWL_SERIAL)
553 if (close(*(int *)Des
) == -1)
556 #endif /* RWL_DONGLE || RWL_SERIAL */
559 DPRINT_ERR(ERR
, "close_pipe: Unknown remote_type %d\n", remote_type
);
564 #endif /* #if defined (RWL_DONGLE) || defined (RWL_SOCKET) */
569 usleep(delay
* MICRO_SEC_CONVERTER_VAL
);
574 rwl_init_socket(void)