New file structure towards SLIP/PPP. Renamed tcp_*.c for 8.3 sake.

See lwip@sics.se Mon, 21 Oct 2002 magnus.ivarsson
This commit is contained in:
likewise 2002-10-22 12:32:58 +00:00
parent 18ee2d90c9
commit bcb2600107
10 changed files with 845 additions and 232 deletions

View File

@ -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

View File

@ -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

View File

@ -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 <adam@sics.se>
*
*/
#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__ */

129
src/arch/unix/netif/fifo.c Normal file
View File

@ -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 <unistd.h>
#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;
}

302
src/arch/unix/netif/sio.c Normal file
View File

@ -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 <stdlib.h>
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <sys/types.h>
//#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;
}
}

View File

@ -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 <adam@sics.se>
*
*/
#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. */
}
/*-----------------------------------------------------------------------------------*/

View File

@ -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 <adam@sics.se>
*
* $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

235
src/netif/slipif.c Normal file
View File

@ -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 <magnus.ivarsson(at)volvo.com>
*/
#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);
}
/*-----------------------------------------------------------------------------------*/