K2.6 patches and update.
[tomato.git] / release / src-rt / wl / exe / wlu_pipe_linux.c
blob99f03c146ae6429b7f77dedf12cf1f8a113f53e0
1 /*
2 * linux version of remote Wl transport mechanisms (pipes).
4 * Copyright (C) 2010, Broadcom Corporation
5 * All Rights Reserved.
6 *
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
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <errno.h>
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #include <arpa/inet.h>
30 #include <unistd.h>
31 #include <netdb.h>
32 #include <signal.h>
33 #include <sys/ioctl.h>
34 #include <net/if.h>
35 #include <termios.h>
36 #include <fcntl.h>
37 #include <proto/802.11.h>
38 #include <bcmendian.h>
39 #include <bcmcdc.h>
40 #include <proto/802.11.h>
41 #include <wlioctl.h>
42 #if defined(MACOSX)
43 #include <netinet/in.h>
44 #endif
45 #include <typedefs.h>
46 #include "wlu_remote.h"
47 #include <miniopt.h>
48 #if defined(RWL_DONGLE) || defined(RWL_SERIAL)
49 #define READ_DELAY 500000
50 #define BAUD_RATE_115200 115200
51 #define VMIN_VAL 16
52 #define VTIME_VAL 50
53 #define LINUX_SYNC_DELAY 200
54 extern char *g_rwl_device_name_serial;
55 #endif
57 #define MICRO_SEC_CONVERTER_VAL 1000
58 int g_irh;
59 int g_shellsync_pid;
61 #ifdef RWL_SOCKET
62 #define MAX_INTERFACE_NAME 32
64 static int
65 rwl_opensocket(int AddrFamily, int Type, int Protocol)
67 int SockDes;
69 if ((SockDes = socket(AddrFamily, Type, Protocol)) == -1) {
70 perror("rwl_opensocket Fails:");
71 DPRINT_ERR(ERR, "\nerrno:%d\n", errno);
72 return FAIL;
74 return SockDes;
77 static int
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);
83 return FAIL;
85 return SUCCESS;
88 /* Function to connect with the server waiting in the same port */
89 int
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);
95 return FAIL;
97 return SUCCESS;
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);
109 return FAIL;
111 return SUCCESS;
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);
123 return FAIL;
125 return SUCCESS;
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)
135 int NewSockDes;
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);
140 return FAIL;
142 return NewSockDes;
145 static int
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);
151 return FAIL;
153 return SUCCESS;
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);
166 return (FAIL);
169 /* Sent successfully at first attempt no more retries */
170 if (numwritten == data_size) {
171 total_numwritten = numwritten;
172 break;
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)
193 int numread;
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);
200 return FAIL;
203 if (numread != data_size - total_numread) {
204 DPRINT_DBG(OUTPUT, "asked %d bytes got %d bytes\n",
205 data_size - total_numread, numread);
208 if (numread == 0)
209 break;
211 total_numread += numread;
212 RecvBuff += numread;
215 return 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;
227 /* Default option */
228 servPort = DEFAULT_SERVER_PORT;
230 #ifdef MACOSX
231 strcpy(netif, "en0");
232 #else
233 strcpy(netif, "eth0");
234 #endif
236 /* User option can override default arguments */
237 if (argc == 3) {
238 argv++;
240 if (isalpha(**argv) == FALSE) {
241 DPRINT_ERR(ERR, "USAGE ERROR:Incorrect network interface\n");
242 return FAIL;
244 strcpy(netif, *argv);
245 argv++;
247 if (isdigit(**argv) == FALSE) {
248 DPRINT_ERR(ERR, "USAGE ERROR:Incorrect port\n");
249 return FAIL;
251 servPort = atoi(*argv);
254 if (argc == 2) {
255 argv++;
257 if (isalpha(**argv) == FALSE) {
258 if (isdigit(**argv) == FALSE) {
259 DPRINT_ERR(ERR, "USAGE ERROR\n");
260 return FAIL;
262 else
263 servPort = atoi(*argv);
265 else
266 strcpy(netif, *argv);
269 DPRINT_INFO(OUTPUT, "INFO: Network Interface:%s, Port:%d\n",
270 netif, servPort);
272 if ((SockDes = (*(int *)rwl_open_transport(remote_type, NULL, 0, 0))) == FAIL)
273 return FAIL;
275 val = 1;
276 if ((rwl_set_socket_option(SockDes, SOL_SOCKET, SO_REUSEADDR, val)) == FAIL)
277 return 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))
287 return err;
288 if ((err = rwl_listensocket(SockDes, BACKLOG)) == FAIL)
289 return err;
291 DPRINT_DBG(OUTPUT, "Waiting for client to connect...\n");
293 return SockDes;
296 int rwl_GetifAddr(char *ifname, struct sockaddr_in *sa)
298 struct ifreq ifr;
299 int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
301 if (fd < 0)
303 DPRINT_ERR(ERR, "socket open error\n");
304 return FAIL;
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));
313 else
315 return FAIL;
317 close(fd);
318 return FAIL;
320 #endif /* RWL_SOCKET */
322 #if defined(RWL_SERIAL) || defined(RWL_DONGLE)
323 static int
324 rwl_open_serial(int remote_type, char *port)
326 struct termios tio;
327 int fCom;
328 int speed;
329 long BAUD, DATABITS, STOPBITS, PARITYON;
330 speed_t baud_rate;
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);
335 else
336 fCom = open(port, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC);
337 if (fCom < 0) {
338 DPRINT_ERR(ERR, "open COM failed with error %d.\n", errno);
339 return fCom;
340 } else {
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");
354 return FAIL;
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);
362 BAUD = B115200;
363 DATABITS = CS8;
364 STOPBITS = 1;
365 PARITYON = 0;
367 tio.c_cflag = BAUD | DATABITS | STOPBITS | PARITYON | CLOCAL | CREAD;
368 tio.c_iflag = IGNPAR;
369 tio.c_oflag = 0;
370 tio.c_lflag = 0;
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:");
377 return FAIL;
380 if (tcgetattr(fCom, &tio) < 0) {
381 perror("tcgetattr:");
382 return FAIL;
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);
389 else {
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;
403 tio.c_cflag |= CS8;
404 tio.c_cc[VTIME] = 255;
405 tio.c_cc[VMIN] = 1;
407 tio.c_iflag = 0;
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);
429 return (fCom);
432 rwl_write_serial_port(void* hndle, char* write_buf, unsigned long size, unsigned long *numwritten)
434 int ret;
436 ret = write((*(int *)hndle), (const void*)write_buf, size);
437 *numwritten = ret;
438 if (ret == -1) {
439 perror("WriteToPort Failed");
440 DPRINT_ERR(ERR, "Errno:%d\n", errno);
441 return FAIL;
443 if (*numwritten != size) {
444 DPRINT_ERR(ERR, "rwl_write_serial_port failed numwritten %ld != len %ld\n",
445 *numwritten, size);
446 return FAIL;
448 return SUCCESS;
452 rwl_read_serial_port(void* hndle, char* read_buf, uint data_size, uint *numread)
454 int ret;
455 uint total_numread = 0;
456 while (total_numread < data_size) {
457 ret = read(*(int *)hndle, read_buf, data_size - total_numread);
458 *numread = ret;
459 if (ret == -1) {
461 perror("ReadFromPort Failed");
462 DPRINT_ERR(ERR, "Errno:%d\n", errno);
463 return FAIL;
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);
469 if (*numread == 0)
470 break;
472 total_numread += *numread;
473 read_buf += *numread;
475 return SUCCESS;
478 void
479 rwl_sync_delay(uint noframes)
481 if (noframes > 1) {
482 rwl_sleep(LINUX_SYNC_DELAY);
486 #endif /* RWL_DONGLE ||RWL_SERIAL */
488 #if defined(RWL_DONGLE) || defined(RWL_SOCKET) || defined(RWL_SERIAL)
489 void*
490 rwl_open_transport(int remote_type, char *port, int ReadTotalTimeout, int debug)
492 void* hndle;
494 UNUSED_PARAMETER(port);
495 UNUSED_PARAMETER(ReadTotalTimeout);
496 UNUSED_PARAMETER(debug);
498 switch (remote_type) {
499 #if defined(RWL_DONGLE) || defined(RWL_SERIAL)
500 case REMOTE_SERIAL:
501 #ifdef RWL_SERIAL
502 g_rwl_device_name_serial = port;
503 #endif
504 case REMOTE_DONGLE:
505 if ((g_irh = rwl_open_serial(remote_type, g_rwl_device_name_serial))
506 == FAIL) {
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))
511 == FAIL) {
512 DPRINT_ERR(ERR, "Can't open serial port\n");
513 return NULL;
516 break;
517 #endif /* RWL_DONGLE || RWL_SERIAL */
519 #ifdef RWL_SOCKET
520 case REMOTE_SOCKET:
521 if ((g_irh = rwl_opensocket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == FAIL) {
522 DPRINT_ERR(ERR, "\nCan't open socket \n");
523 return NULL;
526 break;
527 #endif /* RWL_SOCKET */
529 default:
530 DPRINT_ERR(ERR, "rwl_open_transport: Unknown remote_type %d\n", remote_type);
531 return NULL;
532 break;
533 } /* end - switch case */
535 hndle = (void*) &g_irh;
536 return hndle;
540 rwl_close_transport(int remote_type, void* Des)
542 switch (remote_type) {
543 #ifdef RWL_SOCKET
544 case REMOTE_SOCKET:
545 if (rwl_closesocket(*(int *)Des) == FAIL)
546 return FAIL;
547 break;
548 #endif /* RWL_SOCKET */
550 #if defined(RWL_DONGLE) || defined(RWL_SERIAL)
551 case REMOTE_DONGLE:
552 case REMOTE_SERIAL:
553 if (close(*(int *)Des) == -1)
554 return FAIL;
555 break;
556 #endif /* RWL_DONGLE || RWL_SERIAL */
558 default:
559 DPRINT_ERR(ERR, "close_pipe: Unknown remote_type %d\n", remote_type);
560 break;
562 return SUCCESS;
564 #endif /* #if defined (RWL_DONGLE) || defined (RWL_SOCKET) */
566 void
567 rwl_sleep(int delay)
569 usleep(delay * MICRO_SEC_CONVERTER_VAL);
572 #if defined(WLMSO)
574 rwl_init_socket(void)
576 return 0;
578 #endif