From bcb26001078185c2d63df15351e94731a107826f Mon Sep 17 00:00:00 2001 From: likewise Date: Tue, 22 Oct 2002 12:32:58 +0000 Subject: [PATCH] New file structure towards SLIP/PPP. Renamed tcp_*.c for 8.3 sake. See lwip@sics.se Mon, 21 Oct 2002 magnus.ivarsson --- src/arch/unix/include/netif/fifo.h | 54 +++++ src/arch/unix/include/netif/sio.h | 82 +++++++ src/arch/unix/include/netif/sioslipif.h | 43 ---- src/arch/unix/netif/fifo.c | 129 ++++++++++ src/arch/unix/netif/sio.c | 302 ++++++++++++++++++++++++ src/arch/unix/netif/sioslipif.c | 189 --------------- src/core/{tcp_input.c => tcp_in.c} | 0 src/core/{tcp_output.c => tcp_out.c} | 0 src/include/netif/slipif.h | 43 ++++ src/netif/slipif.c | 235 ++++++++++++++++++ 10 files changed, 845 insertions(+), 232 deletions(-) create mode 100644 src/arch/unix/include/netif/fifo.h create mode 100644 src/arch/unix/include/netif/sio.h delete mode 100644 src/arch/unix/include/netif/sioslipif.h create mode 100644 src/arch/unix/netif/fifo.c create mode 100644 src/arch/unix/netif/sio.c delete mode 100644 src/arch/unix/netif/sioslipif.c rename src/core/{tcp_input.c => tcp_in.c} (100%) rename src/core/{tcp_output.c => tcp_out.c} (100%) create mode 100644 src/include/netif/slipif.h create mode 100644 src/netif/slipif.c diff --git a/src/arch/unix/include/netif/fifo.h b/src/arch/unix/include/netif/fifo.h new file mode 100644 index 00000000..415cf017 --- /dev/null +++ b/src/arch/unix/include/netif/fifo.h @@ -0,0 +1,54 @@ +#ifndef FIFO_H +#define FIFO_H + +#include "lwip/sys.h" + +/** How many bytes in fifo */ +#define FIFOSIZE 2048 + +/** fifo data structure, this one is passed to all fifo functions */ +typedef struct fifo_t { + u8_t data[FIFOSIZE+10]; /// data segment, +10 is a hack probably not needed.. FIXME! + int dataslot; /// index to next char to be read + int emptyslot; /// index to next empty slot + int len; /// len probably not needed, may be calculated from dataslot and emptyslot in conjunction with FIFOSIZE + + sys_sem_t sem; /// semaphore protecting simultaneous data manipulation + sys_sem_t getSem; /// sepaphore used to signal new data if getWaiting is set + u8_t getWaiting; /// flag used to indicate that fifoget is waiting for data. fifoput is suposed to clear + /// this flag prior to signaling the getSem semaphore +} fifo_t; + + +/** +* Get a character from fifo +* Blocking call. +* @param pointer to fifo data structure +* @return character read from fifo +*/ +u8_t fifoGet(fifo_t * fifo); + +/** +* Get a character from fifo +* Non blocking call. +* @param pointer to fifo data structure +* @return character read from fifo, or < zero if non was available +*/ +s16_t fifoGetNonBlock(fifo_t * fifo); + +/** +* fifoput is called by the signalhandler when new data has arrived (or some other event is indicated) +* fifoput reads directly from the serialport and is thus highly dependent on unix arch at this moment +* @param fifo pointer to fifo data structure +* @param fd unix file descriptor +*/ +void fifoPut(fifo_t * fifo, int fd); + +/** +* fifoinit initiate fifo +* @param fifo pointer to fifo data structure, allocated by the user +*/ +void fifoInit(fifo_t * fifo); + +#endif + diff --git a/src/arch/unix/include/netif/sio.h b/src/arch/unix/include/netif/sio.h new file mode 100644 index 00000000..24a65553 --- /dev/null +++ b/src/arch/unix/include/netif/sio.h @@ -0,0 +1,82 @@ +#ifndef SIO_H +#define SIO_H + +#include "lwip/sys.h" +#include "lwip/netif.h" +#include "netif/fifo.h" +//#include "netif/pppif.h" +/* BAUDRATE is defined in sio.c as it is implementation specific */ + +typedef struct sio_status_t { + int fd; + fifo_t myfifo; +} sio_status_t; + + +/** Baudrates */ +typedef enum sioBaudrates { + SIO_BAUD_9600, + SIO_BAUD_19200, + SIO_BAUD_38400, + SIO_BAUD_57600, + SIO_BAUD_115200 +} sioBaudrates; + +/** +* Read a char from incoming data stream, this call blocks until data has arrived +* @param siostat siostatus struct, contains sio instance data, given by sio_open +* @return char read from input stream +*/ +u8_t sio_recv( sio_status_t * siostat ); + +/** +* Poll for a new character from incoming data stream +* @param siostat siostatus struct, contains sio instance data, given by sio_open +* @return char read from input stream, or < 0 if no char was available +*/ +s16_t sio_poll(sio_status_t * siostat); + +/** +* Parse incoming characters until a string str is recieved, blocking call +* @param str zero terminated string to expect +* @param siostat siostatus struct, contains sio instance data, given by sio_open +*/ +void sio_expect_string(u8_t *str, sio_status_t * siostat); + +/** +* Write a char to output data stream +* @param c char to write to output stream +* @param siostat siostatus struct, contains sio instance data, given by sio_open +*/ +void sio_send( u8_t c, sio_status_t * siostat ); + +/** +* Write a char to output data stream +* @param str pointer to a zero terminated string +* @param siostat siostatus struct, contains sio instance data, given by sio_open +*/ +void sio_send_string(u8_t *str, sio_status_t * siostat); + +/** +* Flush outbuffer (send everything in buffer now), useful if some layer below is +* holding on to data, waitng to fill a buffer +* @param siostat siostatus struct, contains sio instance data, given by sio_open +*/ +void sio_flush( sio_status_t * siostat ); + +/** +* Open serial port entry point from serial protocol (slipif, pppif) +* @param devnum the device number to use, i.e. ttySx, comx:, etc. there x = devnum +* @return siostatus struct, contains sio instance data, use when calling sio functions +*/ +sio_status_t * sio_open( int devnum ); + +/** +* Change baudrate of port, may close and reopen port +* @param baud new baudrate +* @param siostat siostatus struct, contains sio instance data, given by sio_open +*/ +void sio_change_baud( sioBaudrates baud, sio_status_t * siostat ); + +#endif + diff --git a/src/arch/unix/include/netif/sioslipif.h b/src/arch/unix/include/netif/sioslipif.h deleted file mode 100644 index ac31b0d8..00000000 --- a/src/arch/unix/include/netif/sioslipif.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2001, 2002 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __NETIF_SIOSLIPIF_H__ -#define __NETIF_SIOSLIPIF_H__ - -#include "lwip/netif.h" - -void sioslipif_init(struct netif *); - - -void sioslipif_init1(struct netif *); -void sioslipif_init2(struct netif *); - -#endif /* __NETIF_SIOSLIPIF_H__ */ diff --git a/src/arch/unix/netif/fifo.c b/src/arch/unix/netif/fifo.c new file mode 100644 index 00000000..23a87fb3 --- /dev/null +++ b/src/arch/unix/netif/fifo.c @@ -0,0 +1,129 @@ +/* ---------------------------------------------- */ +/* --- fifo 4 unix ------------------------------ */ +/* ---------------------------------------------- */ +#include "netif/fifo.h" +#include "lwip/debug.h" +#include "lwip/def.h" +#include "lwip/sys.h" +#include "lwip/arch.h" +#include + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + + +u8_t fifoGet(fifo_t * fifo) +{ + u8_t c; + + sys_sem_wait(fifo->sem); // enter critical section + + if (fifo->dataslot == fifo->emptyslot) + { + fifo->getWaiting = TRUE; // tell putFifo to signal us when data is available + sys_sem_signal(fifo->sem); // leave critical section (allow input from serial port..) + sys_sem_wait(fifo->getSem); // wait 4 data + sys_sem_wait(fifo->sem); // reenter critical section + } + + c = fifo->data[fifo->dataslot++]; + fifo->len--; + + if (fifo->dataslot == FIFOSIZE) + { + fifo->dataslot = 0; + } + sys_sem_signal(fifo->sem); // leave critical section + return c; +} + + +s16_t fifoGetNonBlock(fifo_t * fifo) +{ + u16_t c; + + sys_sem_wait(fifo->sem); // enter critical section + + if (fifo->dataslot == fifo->emptyslot) + { + // empty fifo + c = -1; + } + else + { + c = fifo->data[fifo->dataslot++]; + fifo->len--; + + if (fifo->dataslot == FIFOSIZE) + { + fifo->dataslot = 0; + } + } + sys_sem_signal(fifo->sem); // leave critical section + return c; +} + + +void fifoPut(fifo_t * fifo, int fd) +{ + /* FIXME: mutex around struct data.. */ + int cnt=0; + + sys_sem_wait( fifo->sem ); // enter critical + + DEBUGF( SIO_FIFO_DEBUG,("fifoput: len%d dat%d empt%d --> ", fifo->len, fifo->dataslot, fifo->emptyslot ) ); + + if ( fifo->emptyslot < fifo->dataslot ) + { + cnt = read( fd, &fifo->data[fifo->emptyslot], fifo->dataslot - fifo->emptyslot ); + } + else + { + cnt = read( fd, &fifo->data[fifo->emptyslot], FIFOSIZE-fifo->emptyslot ); + } + fifo->emptyslot += cnt; + fifo->len += cnt; + + DEBUGF( SIO_FIFO_DEBUG,("len%d dat%d empt%d\n", fifo->len, fifo->dataslot, fifo->emptyslot ) ); + + if ( fifo->len > FIFOSIZE ) + { + printf( "ERROR: fifo overrun detected len=%d, flushing\n", fifo->len ); + fifo->dataslot = 0; + fifo->emptyslot = 0; + fifo->len = 0; + } + + if ( fifo->emptyslot == FIFOSIZE ) + { + fifo->emptyslot = 0; + DEBUGF( SIO_FIFO_DEBUG, ("(WRAP) ") ); + + sys_sem_signal( fifo->sem ); // leave critical + fifoPut( fifo, fd ); + return; + } + if ( fifo->getWaiting ) + { + fifo->getWaiting = FALSE; + sys_sem_signal( fifo->getSem ); + } + + sys_sem_signal( fifo->sem ); // leave critical + return; +} + + +void fifoInit(fifo_t * fifo) +{ + fifo->dataslot = 0; + fifo->emptyslot = 0; + fifo->len = 0; + fifo->sem = sys_sem_new(1); // critical section 1=free to enter + fifo->getSem = sys_sem_new(0); // 0 = no one waiting + fifo->getWaiting = FALSE; +} diff --git a/src/arch/unix/netif/sio.c b/src/arch/unix/netif/sio.c new file mode 100644 index 00000000..8ea13c64 --- /dev/null +++ b/src/arch/unix/netif/sio.c @@ -0,0 +1,302 @@ +#include "netif/sio.h" +#include "netif/fifo.h" +#include "lwip/debug.h" +#include "lwip/def.h" +#include "lwip/sys.h" +#include "lwip/arch.h" + +#include +#include +#include +#include +#include +#include +#include + +//#define BAUDRATE B19200 +//#define BAUDRATE B57600 +#define BAUDRATE B115200 + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +/* for all of you who dont define SIO_DEBUG in debug.h */ +#ifndef SIO_DEBUG +#define SIO_DEBUG 0 +#endif + + +// typedef struct siostruct_t +// { +// sio_status_t *sio; +// } siostruct_t; + +/** array of ((siostruct*)netif->state)->sio structs */ +static sio_status_t statusar[2]; + +/* --private-functions----------------------------------------------------------------- */ +/** + * Signal handler for ttyXX0 to indicate bytes received + * one per interface is needed since we cannot send a instance number / pointer as callback argument (?) + */ +static void signal_handler_IO_0( int status ) +{ + DEBUGF(SIO_DEBUG, ("SigHand: rxSignal chanel 0")); + fifoPut( &statusar[0].myfifo, statusar[0].fd ); +} + +/** + * Signal handler for ttyXX1 to indicate bytes received + * one per interface is needed since we cannot send a instance number / pointer as callback argument (?) + */ +static void signal_handler_IO_1( int status ) +{ + DEBUGF(SIO_DEBUG, ("SigHand: rxSignal channel 1")); + fifoPut( &statusar[1].myfifo, statusar[1].fd ); +} + +/** +* Initiation of serial device +* @param device : string with the device name and path, eg. "/dev/ttyS0" +* @param netif : netinterface struct, contains interface instance data +* @return file handle to serial dev. +*/ +static int sio_init( char * device, int devnum, sio_status_t * siostat ) +{ + struct termios oldtio,newtio; + struct sigaction saio; /* definition of signal action */ + int fd; + + /* open the device to be non-blocking (read will return immediatly) */ + fd = open( device, O_RDWR | O_NOCTTY | O_NONBLOCK ); + if ( fd < 0 ) + { + perror( device ); + exit( -1 ); + } + + /* install the signal handler before making the device asynchronous */ + switch ( devnum ) + { + case 0: + DEBUGF( SIO_DEBUG, ("sioinit, signal_handler_IO_0\r\n") ); + saio.sa_handler = signal_handler_IO_0; + break; + case 1: + DEBUGF( SIO_DEBUG, ("sioinit, signal_handler_IO_1\r\n") ); + saio.sa_handler = signal_handler_IO_1; + break; + default: + DEBUGF( SIO_DEBUG,("sioinit, devnum not allowed\r\n") ); + break; + } + + saio.sa_flags = 0; + saio.sa_restorer = NULL; + sigaction( SIGIO,&saio,NULL ); + + /* allow the process to receive SIGIO */ + fcntl( fd, F_SETOWN, getpid( ) ); + /* Make the file descriptor asynchronous (the manual page says only + O_APPEND and O_NONBLOCK, will work with F_SETFL...) */ + fcntl( fd, F_SETFL, FASYNC ); + + tcgetattr( fd,&oldtio ); /* save current port settings */ + /* set new port settings */ + /* see 'man termios' for further settings */ + newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD; // | CRTSCTS; + newtio.c_iflag = 0; + newtio.c_oflag = 0; + newtio.c_lflag = 0; //ECHO; + newtio.c_cc[VMIN] = 1; /* Read 1 byte at a time, no timer */ + newtio.c_cc[VTIME] = 0; + + tcsetattr( fd,TCSANOW,&newtio ); + tcflush( fd, TCIOFLUSH ); + + return fd; +} + +/** +* +*/ +static void sio_speed( int fd, int speed ) +{ + struct termios oldtio,newtio; + // int fd; + + DEBUGF( 1,("sio_speed: baudcode:%d enter\n",speed ) ); + + if ( fd < 0 ) + { + DEBUGF(SIO_DEBUG, ( "sio_speed: fd ERROR\n" )); + exit( -1 ); + } + + tcgetattr( fd,&oldtio ); /* get current port settings */ + + /* set new port settings + * see 'man termios' for further settings */ + newtio.c_cflag = speed | CS8 | CLOCAL | CREAD; //§ | CRTSCTS; + newtio.c_iflag = 0; + newtio.c_oflag = 0; + newtio.c_lflag = 0; //ECHO; + newtio.c_cc[VMIN] = 1; /* Read 1 byte at a time, no timer */ + newtio.c_cc[VTIME] = 0; + + tcsetattr( fd,TCSANOW,&newtio ); + tcflush( fd, TCIOFLUSH ); + + DEBUGF( SIO_DEBUG ,("sio_speed: leave\n" )); +} + +/* --public-functions----------------------------------------------------------------------------- */ +void sio_send( u8_t c, sio_status_t * siostat ) +{ +// sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; + + if ( write( siostat->fd, &c, 1 ) <= 0 ) + { + DEBUGF( SIO_DEBUG,("sio_send: write refused") ); + } +} + +void sio_send_string( u8_t *str, sio_status_t * siostat ) +{ +// sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; + int len = strlen( str ); + + if ( write( siostat->fd, str, len ) <= 0 ) + { + DEBUGF( SIO_DEBUG,("sio_send_string: write refused") ); + } + DEBUGF( (PPP_DEBUG | SIO_DEBUG),("sent:%s",str ) ); +} + + +void sio_flush( sio_status_t * siostat ) +{ + /* not implemented in unix as it is not needed */ + //sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; +} + + +//u8_t sio_recv( struct netif * netif ) +u8_t sio_recv( sio_status_t * siostat ) +{ +// sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; + return fifoGet( &(siostat->myfifo) ); +} + +s16_t sio_poll(sio_status_t * siostat) +{ +// sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; + return fifoGetNonBlock( &(siostat->myfifo) ); +} + + +void sio_expect_string( u8_t *str, sio_status_t * siostat ) +{ +// sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; + u8_t c; + int finger=0; + + DEBUGF( (PPP_DEBUG | SIO_DEBUG), ("expect:%s\n",str) ); + while ( 1 ) + { + c=fifoGet( &(siostat->myfifo) ); + DEBUGF( (PPP_DEBUG | SIO_DEBUG), ("_%c",c) ); + if ( c==str[finger] ) + { + finger++; + } else if ( finger > 0 ) + { + //it might fit in the beginning? + if ( str[0] == c ) + { + finger = 1; + } + } + if ( 0 == str[finger] ) + break; // done, we have a match + } + DEBUGF( (PPP_DEBUG | SIO_DEBUG), ("[match]\n") ); +} + + +sio_status_t * sio_open( int devnum ) +{ + char dev[20]; + + /* would be nice with dynamic memory alloc */ + sio_status_t * siostate = &statusar[ devnum ]; +// siostruct_t * tmp; +// +// +// tmp = (siostruct_t*)(netif->state); +// tmp->sio = siostate; +// +// tmp = (siostruct_t*)(netif->state); +// +// ((sio_status_t*)(tmp->sio))->fd = 0; + + fifoInit( &siostate->myfifo ); + + sprintf( dev, "/dev/ttyS%d", devnum ); + + if ( (devnum == 1) || (devnum == 0) ) + { + if ( ( siostate->fd = sio_init( dev, devnum, siostate ) ) == 0 ) + { + DEBUGF(SIO_DEBUG, ( "sio_open: ERROR opening serial device" )); + abort( ); + return NULL; + } + } + else + { + DEBUGF(SIO_DEBUG, ( "sio_open: device %s (%d) is not supported", dev, devnum )); + return NULL; + } + DEBUGF( 1,("sio_open: dev=%s open.\n", dev )); + + return siostate; +} + +/** +* +*/ +void sio_change_baud( sioBaudrates baud, sio_status_t * siostat ) +{ +// sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; + + DEBUGF( 1,("sio_change_baud\n" )); + + switch ( baud ) + { + case SIO_BAUD_9600: + sio_speed( siostat->fd, B9600 ); + break; + case SIO_BAUD_19200: + sio_speed( siostat->fd, B19200 ); + break; + case SIO_BAUD_38400: + sio_speed( siostat->fd, B38400 ); + break; + case SIO_BAUD_57600: + sio_speed( siostat->fd, B57600 ); + break; + case SIO_BAUD_115200: + sio_speed( siostat->fd, B115200 ); + break; + + default: + DEBUGF( 1,("sio_change_baud: Unknown baudrate, code:%d", baud )); + break; + } +} + diff --git a/src/arch/unix/netif/sioslipif.c b/src/arch/unix/netif/sioslipif.c deleted file mode 100644 index 9659e37a..00000000 --- a/src/arch/unix/netif/sioslipif.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2001, 2002 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/debug.h" -#include "lwip/def.h" -#include "netif/sioslipif.h" -#include "lwip/pbuf.h" -#include "lwip/sys.h" -#include "lwip/stats.h" - -/* The maximum size that an incoming packet can have. */ -#define MAX_SIZE 1500 - -#define SLIP_END 0300 -#define SLIP_ESC 0333 -#define SLIP_ESC_END 0334 -#define SLIP_ESC_ESC 0335 - -/* Define those to whatever is needed to send and receive one byte of - data. */ -#define SIO_SEND(c) -#define SIO_RECV(c) - -static const unsigned char slip_end = SLIP_END, - slip_esc = SLIP_ESC, - slip_esc_end = SLIP_ESC_END, - slip_esc_esc = SLIP_ESC_ESC; - -/*-----------------------------------------------------------------------------------*/ -static err_t -sioslipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr) -{ - struct pbuf *q; - int i; - unsigned char *ptr; - u8_t c; - /* Send pbuf out on the serial I/O device. */ - SIO_SEND(slip_end); - - for(q = p; q != NULL; q = q->next) { - ptr = q->payload; - for(i = 0; i < q->len; i++) { - c = *ptr++; - switch(c) { - case SLIP_END: - SIO_SEND(slip_esc); - SIO_SEND(slip_esc_end); - break; - case SLIP_ESC: - SIO_SEND(slip_esc); - SIO_SEND(slip_esc_esc); - break; - default: - SIO_SEND(c); - break; - } - } - } -#ifdef LINK_STATS - stats.link.xmit++; -#endif /* LINK_STATS */ - SIO_SEND(slip_end); - - return ERR_OK; -} -/*-----------------------------------------------------------------------------------*/ -static struct pbuf * -sioslipif_input(void) -{ - u8_t c; - struct pbuf *p, *q; - int recved; - int i; - - q = p = NULL; - recved = i = 0; - c = 0; - - while(1) { - SIO_RECV(c); - switch(c) { - case SLIP_END: - if(p == NULL) { - return sioslipif_input(); - } - if(recved > 0) { - /* Received whole packet. */ - pbuf_realloc(q, recved); -#ifdef LINK_STATS - stats.link.recv++; -#endif /* LINK_STATS */ - return q; - } - break; - case SLIP_ESC: - SIO_RECV(c); - switch(c) { - case SLIP_ESC_END: - c = SLIP_END; - break; - case SLIP_ESC_ESC: - c = SLIP_ESC; - break; - } - /* FALLTHROUGH */ - default: - if(p == NULL) { - p = pbuf_alloc(PBUF_LINK, 128, PBUF_POOL); -#ifdef LINK_STATS - if(p == NULL) { - stats.link.drop++; - } -#endif /* LINK_STATS */ - if(q != NULL) { - pbuf_chain(q, p); - } else { - q = p; - } - } - if(p != NULL && recved < MAX_SIZE) { - ((u8_t *)p->payload)[i] = c; - recved++; - i++; - if(i >= p->len) { - i = 0; - p = NULL; - } - } - break; - } - - } - return NULL; -} -/*-----------------------------------------------------------------------------------*/ -static void -sioslipif_loop(void *arg) -{ - struct pbuf *p; - struct netif *netif; - - netif = arg; - while(1) { - p = sioslipif_input(); - netif->input(p, netif); - } -} -/*-----------------------------------------------------------------------------------*/ -void -sioslipif_init(struct netif *netif) -{ - netif->state = NULL; - netif->name[0] = 's'; - netif->name[1] = 'l'; - netif->output = sioslipif_output; - - sys_thread_new((void *)sioslipif_loop, netif); - /* Do some magic to make it possible to receive data from the serial I/O device. */ -} -/*-----------------------------------------------------------------------------------*/ diff --git a/src/core/tcp_input.c b/src/core/tcp_in.c similarity index 100% rename from src/core/tcp_input.c rename to src/core/tcp_in.c diff --git a/src/core/tcp_output.c b/src/core/tcp_out.c similarity index 100% rename from src/core/tcp_output.c rename to src/core/tcp_out.c diff --git a/src/include/netif/slipif.h b/src/include/netif/slipif.h new file mode 100644 index 00000000..aa99dc6b --- /dev/null +++ b/src/include/netif/slipif.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * $Id: slipif.h,v 1.1 2002/10/22 12:32:58 likewise Exp $ + */ +#ifndef __NETIF_SLIPIF_H__ +#define __NETIF_SLIPIF_H__ + +#include "lwip/netif.h" + +void slipif_init(struct netif * netif); + +#endif + diff --git a/src/netif/slipif.c b/src/netif/slipif.c new file mode 100644 index 00000000..a0e56f0a --- /dev/null +++ b/src/netif/slipif.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is built upon the file: src/arch/rtxc/netif/sioslip.c + * + * Author: Magnus Ivarsson + */ + +#include "netif/slipif.h" +#include "lwip/debug.h" +#include "lwip/def.h" +#include "lwip/pbuf.h" +#include "lwip/sys.h" +#include "lwip/stats.h" +#include "netif/sio.h" + +#define SLIP_END 0300 +#define SLIP_ESC 0333 +#define SLIP_ESC_END 0334 +#define SLIP_ESC_ESC 0335 + +#define MAX_SIZE 1500 +#define SLIPIF_NUM_OF_INTERFACES 2 + +typedef struct slip_status_t { + void *sio; +} slip_status_t; + +/* yes, this is ugly; TODO: should be dynamicaly allocated instead */ +static slip_status_t statusar[SLIPIF_NUM_OF_INTERFACES]; + +/*-----------------------------------------------------------------------------------*/ +err_t slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr) +{ + slip_status_t *slipState = (slip_status_t *) netif->state; + struct pbuf *q; + int i; + u8_t c; + + /* Send pbuf out on the serial I/O device. */ + sio_send(SLIP_END, slipState->sio); + + for(q = p; q != NULL; q = q->next) { + for(i = 0; i < q->len; i++) { + c = ((u8_t *)q->payload)[i]; + switch(c) { + case SLIP_END: + sio_send(SLIP_ESC, slipState->sio); + sio_send(SLIP_ESC_END, slipState->sio); + break; + case SLIP_ESC: + sio_send(SLIP_ESC, slipState->sio); + sio_send(SLIP_ESC_ESC, slipState->sio); + break; + default: + sio_send(c, slipState->sio); + break; + } + } + } + sio_send(SLIP_END, slipState->sio); + return 0; +} +/*-----------------------------------------------------------------------------------*/ + +static struct pbuf * slipif_input( struct netif * netif ) +{ + slip_status_t *slipState = (slip_status_t *) netif->state; + + u8_t c; + struct pbuf *p, *q; + int recved; + int i; + + q = p = NULL; + recved = i = 0; + c = 0; + + while ( 1 ) + { + c = sio_recv( slipState->sio ); + switch ( c ) + { + case SLIP_END: + if ( p == NULL ) + { + return slipif_input( netif ); + } + if ( recved > 0 ) + { + /* Received whole packet. */ + pbuf_realloc( q, recved ); + + #ifdef LINK_STATS + stats.link.recv++; + #endif /* LINK_STATS */ + + DEBUGF( SLIP_DEBUG, ("slipif: Got packet\n") ); + return q; + } + break; + + case SLIP_ESC: + c = sio_recv( slipState->sio ); + switch ( c ) + { + case SLIP_ESC_END: + c = SLIP_END; + break; + case SLIP_ESC_ESC: + c = SLIP_ESC; + break; + } + /* FALLTHROUGH */ + + default: + if ( p == NULL ) + { + DEBUGF( SLIP_DEBUG, ("slipif_input: alloc\n") ); + p = pbuf_alloc( PBUF_LINK, 128, PBUF_POOL ); + + #ifdef LINK_STATS + if ( p == NULL ) + { + stats.link.drop++; + DEBUGF( SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n") ); + } + #endif /* LINK_STATS */ + + if ( q != NULL ) + { + pbuf_chain( q, p ); + } + else + { + q = p; + } + } + if ( p != NULL && recved < MAX_SIZE ) + { + ((u8_t *)p->payload)[i] = c; + recved++; + i++; + if ( i >= p->len ) + { + i = 0; + p = NULL; + } + } + break; + } + + } + return NULL; +} +/*-----------------------------------------------------------------------------------*/ +static void slipif_loop(void *nf) +{ + struct pbuf *p; + struct netif *netif = (struct netif *) nf; +// slip_status_t *slipState = (slip_status_t *) netif->state; + + while(1) { + p = slipif_input( netif ); + netif->input(p, netif); + } +} +/*-----------------------------------------------------------------------------------*/ +// void +// sioslipif_init0(struct netif *netif) +// { +// slip_status_t * ss; +// printf("slipif_init0: netif->num=%x\n", (int)netif->num); +// +// netif->state = &statusar[0]; +// netif->name[0] = 's'; +// netif->name[1] = 'l'; +// netif->output = sioslipif_output; +// netif->num = 0; +// +// sio_open( netif ); +// ss = (slip_status_t*)(netif->state); +// printf("slipif_init0: netif=%x sio=0x%x\n", (int)netif, (int)(ss->sio)); +// sys_thread_new((void *)slipif_loop, netif); +// } + +/*-----------------------------------------------------------------------------------*/ +void slipif_init(struct netif *netif) +{ + slip_status_t *slipState; + + DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%x\n", (int)netif->num)); + if ( netif->num >= SLIPIF_NUM_OF_INTERFACES ) + { + DEBUGF( SLIP_DEBUG, ("ERROR: To many slipifs")); + return; + } + + /* dynamic allocation would be nice */ + netif->state = &statusar[ netif->num ]; + netif->name[0] = 's'; + netif->name[1] = 'l'; + netif->output = slipif_output; + + slipState = (slip_status_t *) netif->state; + slipState->sio = sio_open( netif->num ); + + sys_thread_new(slipif_loop, netif); +} +/*-----------------------------------------------------------------------------------*/