commit
7066b3491b
|
@ -1,47 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
ifdef APPS
|
|
||||||
APPDIRS = $(foreach APP, $(APPS), ../apps/$(APP))
|
|
||||||
-include $(foreach APP, $(APPS), ../apps/$(APP)/Makefile.$(APP))
|
|
||||||
CFLAGS += $(addprefix -I../apps/,$(APPS))
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifndef CCDEP
|
|
||||||
CCDEP = $(CC)
|
|
||||||
endif
|
|
||||||
ifndef CCDEPCFLAGS
|
|
||||||
CCDEPCFLAGS = $(CFLAGS)
|
|
||||||
endif
|
|
||||||
ifndef OBJECTDIR
|
|
||||||
OBJECTDIR = obj
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq (${wildcard $(OBJECTDIR)},)
|
|
||||||
DUMMY := ${shell mkdir $(OBJECTDIR)}
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
vpath %.c . ../uip ../lib $(APPDIRS)
|
|
||||||
|
|
||||||
$(OBJECTDIR)/%.o: %.c
|
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
|
||||||
|
|
||||||
$(OBJECTDIR)/%.d: %.c
|
|
||||||
@set -e; rm -f $@; \
|
|
||||||
$(CCDEP) -MM $(CCDEPCFLAGS) $< > $@.$$$$; \
|
|
||||||
sed 's,\($*\)\.o[ :]*,$(OBJECTDIR)/\1.o $@ : ,g' < $@.$$$$ > $@; \
|
|
||||||
rm -f $@.$$$$
|
|
||||||
|
|
||||||
UIP_SOURCES=uip.c uip_arp.c uiplib.c psock.c timer.c uip-neighbor.c
|
|
||||||
|
|
||||||
|
|
||||||
ifneq ($(MAKECMDGOALS),clean)
|
|
||||||
-include $(addprefix $(OBJECTDIR)/,$(UIP_SOURCES:.c=.d) \
|
|
||||||
$(APP_SOURCES:.c=.d))
|
|
||||||
endif
|
|
||||||
|
|
||||||
uip.a: ${addprefix $(OBJECTDIR)/, $(UIP_SOURCES:.c=.o)}
|
|
||||||
$(AR) rcf $@ $^
|
|
||||||
|
|
||||||
apps.a: ${addprefix $(OBJECTDIR)/, $(APP_SOURCES:.c=.o)}
|
|
||||||
$(AR) rcf $@ $^
|
|
|
@ -1,83 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2004-2005, 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 uIP TCP/IP stack
|
|
||||||
*
|
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
* $Id: lc-addrlabels.h,v 1.3 2006/06/12 08:00:30 adam Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \addtogroup lc
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* Implementation of local continuations based on the "Labels as
|
|
||||||
* values" feature of gcc
|
|
||||||
* \author
|
|
||||||
* Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
* This implementation of local continuations is based on a special
|
|
||||||
* feature of the GCC C compiler called "labels as values". This
|
|
||||||
* feature allows assigning pointers with the address of the code
|
|
||||||
* corresponding to a particular C label.
|
|
||||||
*
|
|
||||||
* For more information, see the GCC documentation:
|
|
||||||
* http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
|
|
||||||
*
|
|
||||||
* Thanks to dividuum for finding the nice local scope label
|
|
||||||
* implementation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LC_ADDRLABELS_H__
|
|
||||||
#define __LC_ADDRLABELS_H__
|
|
||||||
|
|
||||||
/** \hideinitializer */
|
|
||||||
typedef void * lc_t;
|
|
||||||
|
|
||||||
#define LC_INIT(s) s = NULL
|
|
||||||
|
|
||||||
|
|
||||||
#define LC_RESUME(s) \
|
|
||||||
do { \
|
|
||||||
if(s != NULL) { \
|
|
||||||
goto *s; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define LC_SET(s) \
|
|
||||||
do { ({ __label__ resume; resume: (s) = &&resume; }); }while(0)
|
|
||||||
|
|
||||||
#define LC_END(s)
|
|
||||||
|
|
||||||
#endif /* __LC_ADDRLABELS_H__ */
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,76 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2004-2005, 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 uIP TCP/IP stack
|
|
||||||
*
|
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
* $Id: lc-switch.h,v 1.2 2006/06/12 08:00:30 adam Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \addtogroup lc
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* Implementation of local continuations based on switch() statment
|
|
||||||
* \author Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
* This implementation of local continuations uses the C switch()
|
|
||||||
* statement to resume execution of a function somewhere inside the
|
|
||||||
* function's body. The implementation is based on the fact that
|
|
||||||
* switch() statements are able to jump directly into the bodies of
|
|
||||||
* control structures such as if() or while() statmenets.
|
|
||||||
*
|
|
||||||
* This implementation borrows heavily from Simon Tatham's coroutines
|
|
||||||
* implementation in C:
|
|
||||||
* http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LC_SWITCH_H__
|
|
||||||
#define __LC_SWITCH_H__
|
|
||||||
|
|
||||||
/* WARNING! lc implementation using switch() does not work if an
|
|
||||||
LC_SET() is done within another switch() statement! */
|
|
||||||
|
|
||||||
/** \hideinitializer */
|
|
||||||
typedef unsigned short lc_t;
|
|
||||||
|
|
||||||
#define LC_INIT(s) s = 0;
|
|
||||||
|
|
||||||
#define LC_RESUME(s) switch(s) { case 0:
|
|
||||||
|
|
||||||
#define LC_SET(s) s = __LINE__; case __LINE__:
|
|
||||||
|
|
||||||
#define LC_END(s) }
|
|
||||||
|
|
||||||
#endif /* __LC_SWITCH_H__ */
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,131 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2004-2005, 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 uIP TCP/IP stack
|
|
||||||
*
|
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
* $Id: lc.h,v 1.2 2006/06/12 08:00:30 adam Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \addtogroup pt
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \defgroup lc Local continuations
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* Local continuations form the basis for implementing protothreads. A
|
|
||||||
* local continuation can be <i>set</i> in a specific function to
|
|
||||||
* capture the state of the function. After a local continuation has
|
|
||||||
* been set can be <i>resumed</i> in order to restore the state of the
|
|
||||||
* function at the point where the local continuation was set.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file lc.h
|
|
||||||
* Local continuations
|
|
||||||
* \author
|
|
||||||
* Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef DOXYGEN
|
|
||||||
/**
|
|
||||||
* Initialize a local continuation.
|
|
||||||
*
|
|
||||||
* This operation initializes the local continuation, thereby
|
|
||||||
* unsetting any previously set continuation state.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define LC_INIT(lc)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a local continuation.
|
|
||||||
*
|
|
||||||
* The set operation saves the state of the function at the point
|
|
||||||
* where the operation is executed. As far as the set operation is
|
|
||||||
* concerned, the state of the function does <b>not</b> include the
|
|
||||||
* call-stack or local (automatic) variables, but only the program
|
|
||||||
* counter and such CPU registers that needs to be saved.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define LC_SET(lc)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resume a local continuation.
|
|
||||||
*
|
|
||||||
* The resume operation resumes a previously set local continuation, thus
|
|
||||||
* restoring the state in which the function was when the local
|
|
||||||
* continuation was set. If the local continuation has not been
|
|
||||||
* previously set, the resume operation does nothing.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define LC_RESUME(lc)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mark the end of local continuation usage.
|
|
||||||
*
|
|
||||||
* The end operation signifies that local continuations should not be
|
|
||||||
* used any more in the function. This operation is not needed for
|
|
||||||
* most implementations of local continuation, but is required by a
|
|
||||||
* few implementations.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define LC_END(lc)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \var typedef lc_t;
|
|
||||||
*
|
|
||||||
* The local continuation type.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#endif /* DOXYGEN */
|
|
||||||
|
|
||||||
#ifndef __LC_H__
|
|
||||||
#define __LC_H__
|
|
||||||
|
|
||||||
#ifdef LC_CONF_INCLUDE
|
|
||||||
#include LC_CONF_INCLUDE
|
|
||||||
#else
|
|
||||||
#include "lc-switch.h"
|
|
||||||
#endif /* LC_CONF_INCLUDE */
|
|
||||||
|
|
||||||
#endif /* __LC_H__ */
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
/** @} */
|
|
|
@ -1,338 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2004, 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 uIP TCP/IP stack
|
|
||||||
*
|
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
* $Id: psock.c,v 1.2 2006/06/12 08:00:30 adam Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "uipopt.h"
|
|
||||||
#include "psock.h"
|
|
||||||
#include "uip.h"
|
|
||||||
|
|
||||||
#define STATE_NONE 0
|
|
||||||
#define STATE_ACKED 1
|
|
||||||
#define STATE_READ 2
|
|
||||||
#define STATE_BLOCKED_NEWDATA 3
|
|
||||||
#define STATE_BLOCKED_CLOSE 4
|
|
||||||
#define STATE_BLOCKED_SEND 5
|
|
||||||
#define STATE_DATA_SENT 6
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return value of the buffering functions that indicates that a
|
|
||||||
* buffer was not filled by incoming data.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define BUF_NOT_FULL 0
|
|
||||||
#define BUF_NOT_FOUND 0
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return value of the buffering functions that indicates that a
|
|
||||||
* buffer was completely filled by incoming data.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define BUF_FULL 1
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return value of the buffering functions that indicates that an
|
|
||||||
* end-marker byte was found.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define BUF_FOUND 2
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
static void
|
|
||||||
buf_setup(struct psock_buf *buf,
|
|
||||||
u8_t *bufptr, u16_t bufsize)
|
|
||||||
{
|
|
||||||
buf->ptr = bufptr;
|
|
||||||
buf->left = bufsize;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
static u8_t
|
|
||||||
buf_bufdata(struct psock_buf *buf, u16_t len,
|
|
||||||
u8_t **dataptr, u16_t *datalen)
|
|
||||||
{
|
|
||||||
if(*datalen < buf->left) {
|
|
||||||
memcpy(buf->ptr, *dataptr, *datalen);
|
|
||||||
buf->ptr += *datalen;
|
|
||||||
buf->left -= *datalen;
|
|
||||||
*dataptr += *datalen;
|
|
||||||
*datalen = 0;
|
|
||||||
return BUF_NOT_FULL;
|
|
||||||
} else if(*datalen == buf->left) {
|
|
||||||
memcpy(buf->ptr, *dataptr, *datalen);
|
|
||||||
buf->ptr += *datalen;
|
|
||||||
buf->left = 0;
|
|
||||||
*dataptr += *datalen;
|
|
||||||
*datalen = 0;
|
|
||||||
return BUF_FULL;
|
|
||||||
} else {
|
|
||||||
memcpy(buf->ptr, *dataptr, buf->left);
|
|
||||||
buf->ptr += buf->left;
|
|
||||||
*datalen -= buf->left;
|
|
||||||
*dataptr += buf->left;
|
|
||||||
buf->left = 0;
|
|
||||||
return BUF_FULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
static u8_t
|
|
||||||
buf_bufto(register struct psock_buf *buf, u8_t endmarker,
|
|
||||||
register u8_t **dataptr, register u16_t *datalen)
|
|
||||||
{
|
|
||||||
u8_t c;
|
|
||||||
while(buf->left > 0 && *datalen > 0) {
|
|
||||||
c = *buf->ptr = **dataptr;
|
|
||||||
++*dataptr;
|
|
||||||
++buf->ptr;
|
|
||||||
--*datalen;
|
|
||||||
--buf->left;
|
|
||||||
|
|
||||||
if(c == endmarker) {
|
|
||||||
return BUF_FOUND;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(*datalen == 0) {
|
|
||||||
return BUF_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(*datalen > 0) {
|
|
||||||
c = **dataptr;
|
|
||||||
--*datalen;
|
|
||||||
++*dataptr;
|
|
||||||
|
|
||||||
if(c == endmarker) {
|
|
||||||
return BUF_FOUND | BUF_FULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return BUF_FULL;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
static char
|
|
||||||
send_data(register struct psock *s)
|
|
||||||
{
|
|
||||||
if(s->state != STATE_DATA_SENT || uip_rexmit()) {
|
|
||||||
if(s->sendlen > uip_mss()) {
|
|
||||||
uip_send(s->sendptr, uip_mss());
|
|
||||||
} else {
|
|
||||||
uip_send(s->sendptr, s->sendlen);
|
|
||||||
}
|
|
||||||
s->state = STATE_DATA_SENT;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
static char
|
|
||||||
data_acked(register struct psock *s)
|
|
||||||
{
|
|
||||||
if(s->state == STATE_DATA_SENT && uip_acked()) {
|
|
||||||
if(s->sendlen > uip_mss()) {
|
|
||||||
s->sendlen -= uip_mss();
|
|
||||||
s->sendptr += uip_mss();
|
|
||||||
} else {
|
|
||||||
s->sendptr += s->sendlen;
|
|
||||||
s->sendlen = 0;
|
|
||||||
}
|
|
||||||
s->state = STATE_ACKED;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
PT_THREAD(psock_send(register struct psock *s, const char *buf,
|
|
||||||
unsigned int len))
|
|
||||||
{
|
|
||||||
PT_BEGIN(&s->psockpt);
|
|
||||||
|
|
||||||
/* If there is no data to send, we exit immediately. */
|
|
||||||
if(len == 0) {
|
|
||||||
PT_EXIT(&s->psockpt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save the length of and a pointer to the data that is to be
|
|
||||||
sent. */
|
|
||||||
s->sendptr = buf;
|
|
||||||
s->sendlen = len;
|
|
||||||
|
|
||||||
s->state = STATE_NONE;
|
|
||||||
|
|
||||||
/* We loop here until all data is sent. The s->sendlen variable is
|
|
||||||
updated by the data_sent() function. */
|
|
||||||
while(s->sendlen > 0) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The condition for this PT_WAIT_UNTIL is a little tricky: the
|
|
||||||
* protothread will wait here until all data has been acknowledged
|
|
||||||
* (data_acked() returns true) and until all data has been sent
|
|
||||||
* (send_data() returns true). The two functions data_acked() and
|
|
||||||
* send_data() must be called in succession to ensure that all
|
|
||||||
* data is sent. Therefore the & operator is used instead of the
|
|
||||||
* && operator, which would cause only the data_acked() function
|
|
||||||
* to be called when it returns false.
|
|
||||||
*/
|
|
||||||
PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
s->state = STATE_NONE;
|
|
||||||
|
|
||||||
PT_END(&s->psockpt);
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
PT_THREAD(psock_generator_send(register struct psock *s,
|
|
||||||
unsigned short (*generate)(void *), void *arg))
|
|
||||||
{
|
|
||||||
PT_BEGIN(&s->psockpt);
|
|
||||||
|
|
||||||
/* Ensure that there is a generator function to call. */
|
|
||||||
if(generate == NULL) {
|
|
||||||
PT_EXIT(&s->psockpt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Call the generator function to generate the data in the
|
|
||||||
uip_appdata buffer. */
|
|
||||||
s->sendlen = generate(arg);
|
|
||||||
s->sendptr =(const u8_t*) uip_appdata;
|
|
||||||
|
|
||||||
s->state = STATE_NONE;
|
|
||||||
do {
|
|
||||||
/* Call the generator function again if we are called to perform a
|
|
||||||
retransmission. */
|
|
||||||
if(uip_rexmit()) {
|
|
||||||
generate(arg);
|
|
||||||
}
|
|
||||||
/* Wait until all data is sent and acknowledged. */
|
|
||||||
PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
|
|
||||||
} while(s->sendlen > 0);
|
|
||||||
|
|
||||||
s->state = STATE_NONE;
|
|
||||||
|
|
||||||
PT_END(&s->psockpt);
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
u16_t
|
|
||||||
psock_datalen(struct psock *psock)
|
|
||||||
{
|
|
||||||
return psock->bufsize - psock->buf.left;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
char
|
|
||||||
psock_newdata(struct psock *s)
|
|
||||||
{
|
|
||||||
if(s->readlen > 0) {
|
|
||||||
/* There is data in the uip_appdata buffer that has not yet been
|
|
||||||
read with the PSOCK_READ functions. */
|
|
||||||
return 1;
|
|
||||||
} else if(s->state == STATE_READ) {
|
|
||||||
/* All data in uip_appdata buffer already consumed. */
|
|
||||||
s->state = STATE_BLOCKED_NEWDATA;
|
|
||||||
return 0;
|
|
||||||
} else if(uip_newdata()) {
|
|
||||||
/* There is new data that has not been consumed. */
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
/* There is no new data. */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
PT_THREAD(psock_readto(register struct psock *psock, unsigned char c))
|
|
||||||
{
|
|
||||||
PT_BEGIN(&psock->psockpt);
|
|
||||||
|
|
||||||
buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
|
|
||||||
|
|
||||||
/* XXX: Should add buf_checkmarker() before do{} loop, if
|
|
||||||
incoming data has been handled while waiting for a write. */
|
|
||||||
|
|
||||||
do {
|
|
||||||
if(psock->readlen == 0) {
|
|
||||||
PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
|
|
||||||
psock->state = STATE_READ;
|
|
||||||
psock->readptr = (u8_t *)uip_appdata;
|
|
||||||
psock->readlen = uip_datalen();
|
|
||||||
}
|
|
||||||
} while((buf_bufto(&psock->buf, c,
|
|
||||||
&psock->readptr,
|
|
||||||
&psock->readlen) & BUF_FOUND) == 0);
|
|
||||||
|
|
||||||
if(psock_datalen(psock) == 0) {
|
|
||||||
psock->state = STATE_NONE;
|
|
||||||
PT_RESTART(&psock->psockpt);
|
|
||||||
}
|
|
||||||
PT_END(&psock->psockpt);
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
PT_THREAD(psock_readbuf(register struct psock *psock))
|
|
||||||
{
|
|
||||||
PT_BEGIN(&psock->psockpt);
|
|
||||||
|
|
||||||
buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
|
|
||||||
|
|
||||||
/* XXX: Should add buf_checkmarker() before do{} loop, if
|
|
||||||
incoming data has been handled while waiting for a write. */
|
|
||||||
|
|
||||||
do {
|
|
||||||
if(psock->readlen == 0) {
|
|
||||||
PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
|
|
||||||
printf("Waited for newdata\n");
|
|
||||||
psock->state = STATE_READ;
|
|
||||||
psock->readptr = (u8_t *)uip_appdata;
|
|
||||||
psock->readlen = uip_datalen();
|
|
||||||
}
|
|
||||||
} while(buf_bufdata(&psock->buf, psock->bufsize,
|
|
||||||
&psock->readptr,
|
|
||||||
&psock->readlen) != BUF_FULL);
|
|
||||||
|
|
||||||
if(psock_datalen(psock) == 0) {
|
|
||||||
psock->state = STATE_NONE;
|
|
||||||
PT_RESTART(&psock->psockpt);
|
|
||||||
}
|
|
||||||
PT_END(&psock->psockpt);
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
psock_init(register struct psock *psock, char *buffer, unsigned int buffersize)
|
|
||||||
{
|
|
||||||
psock->state = STATE_NONE;
|
|
||||||
psock->readlen = 0;
|
|
||||||
psock->bufptr = buffer;
|
|
||||||
psock->bufsize = buffersize;
|
|
||||||
buf_setup(&psock->buf, buffer, buffersize);
|
|
||||||
PT_INIT(&psock->pt);
|
|
||||||
PT_INIT(&psock->psockpt);
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
|
@ -1,380 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2004, 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 uIP TCP/IP stack
|
|
||||||
*
|
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
* $Id: psock.h,v 1.3 2006/06/12 08:00:30 adam Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \defgroup psock Protosockets library
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* The protosocket library provides an interface to the uIP stack that is
|
|
||||||
* similar to the traditional BSD socket interface. Unlike programs
|
|
||||||
* written for the ordinary uIP event-driven interface, programs
|
|
||||||
* written with the protosocket library are executed in a sequential
|
|
||||||
* fashion and does not have to be implemented as explicit state
|
|
||||||
* machines.
|
|
||||||
*
|
|
||||||
* Protosockets only work with TCP connections.
|
|
||||||
*
|
|
||||||
* The protosocket library uses \ref pt protothreads to provide
|
|
||||||
* sequential control flow. This makes the protosockets lightweight in
|
|
||||||
* terms of memory, but also means that protosockets inherits the
|
|
||||||
* functional limitations of protothreads. Each protosocket lives only
|
|
||||||
* within a single function. Automatic variables (stack variables) are
|
|
||||||
* not retained across a protosocket library function call.
|
|
||||||
*
|
|
||||||
* \note Because the protosocket library uses protothreads, local
|
|
||||||
* variables will not always be saved across a call to a protosocket
|
|
||||||
* library function. It is therefore advised that local variables are
|
|
||||||
* used with extreme care.
|
|
||||||
*
|
|
||||||
* The protosocket library provides functions for sending data without
|
|
||||||
* having to deal with retransmissions and acknowledgements, as well
|
|
||||||
* as functions for reading data without having to deal with data
|
|
||||||
* being split across more than one TCP segment.
|
|
||||||
*
|
|
||||||
* Because each protosocket runs as a protothread, the protosocket has to be
|
|
||||||
* started with a call to PSOCK_BEGIN() at the start of the function
|
|
||||||
* in which the protosocket is used. Similarly, the protosocket protothread can
|
|
||||||
* be terminated by a call to PSOCK_EXIT().
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* Protosocket library header file
|
|
||||||
* \author
|
|
||||||
* Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __PSOCK_H__
|
|
||||||
#define __PSOCK_H__
|
|
||||||
|
|
||||||
#include "uipopt.h"
|
|
||||||
#include "pt.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The structure that holds the state of a buffer.
|
|
||||||
*
|
|
||||||
* This structure holds the state of a uIP buffer. The structure has
|
|
||||||
* no user-visible elements, but is used through the functions
|
|
||||||
* provided by the library.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
struct psock_buf {
|
|
||||||
u8_t *ptr;
|
|
||||||
unsigned short left;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The representation of a protosocket.
|
|
||||||
*
|
|
||||||
* The protosocket structrure is an opaque structure with no user-visible
|
|
||||||
* elements.
|
|
||||||
*/
|
|
||||||
struct psock {
|
|
||||||
struct pt pt, psockpt; /* Protothreads - one that's using the psock
|
|
||||||
functions, and one that runs inside the
|
|
||||||
psock functions. */
|
|
||||||
const u8_t *sendptr; /* Pointer to the next data to be sent. */
|
|
||||||
u8_t *readptr; /* Pointer to the next data to be read. */
|
|
||||||
|
|
||||||
char *bufptr; /* Pointer to the buffer used for buffering
|
|
||||||
incoming data. */
|
|
||||||
|
|
||||||
u16_t sendlen; /* The number of bytes left to be sent. */
|
|
||||||
u16_t readlen; /* The number of bytes left to be read. */
|
|
||||||
|
|
||||||
struct psock_buf buf; /* The structure holding the state of the
|
|
||||||
input buffer. */
|
|
||||||
unsigned int bufsize; /* The size of the input buffer. */
|
|
||||||
|
|
||||||
unsigned char state; /* The state of the protosocket. */
|
|
||||||
};
|
|
||||||
|
|
||||||
void psock_init(struct psock *psock, char *buffer, unsigned int buffersize);
|
|
||||||
/**
|
|
||||||
* Initialize a protosocket.
|
|
||||||
*
|
|
||||||
* This macro initializes a protosocket and must be called before the
|
|
||||||
* protosocket is used. The initialization also specifies the input buffer
|
|
||||||
* for the protosocket.
|
|
||||||
*
|
|
||||||
* \param psock (struct psock *) A pointer to the protosocket to be
|
|
||||||
* initialized
|
|
||||||
*
|
|
||||||
* \param buffer (char *) A pointer to the input buffer for the
|
|
||||||
* protosocket.
|
|
||||||
*
|
|
||||||
* \param buffersize (unsigned int) The size of the input buffer.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PSOCK_INIT(psock, buffer, buffersize) \
|
|
||||||
psock_init(psock, buffer, buffersize)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start the protosocket protothread in a function.
|
|
||||||
*
|
|
||||||
* This macro starts the protothread associated with the protosocket and
|
|
||||||
* must come before other protosocket calls in the function it is used.
|
|
||||||
*
|
|
||||||
* \param psock (struct psock *) A pointer to the protosocket to be
|
|
||||||
* started.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PSOCK_BEGIN(psock) PT_BEGIN(&((psock)->pt))
|
|
||||||
|
|
||||||
PT_THREAD(psock_send(struct psock *psock, const char *buf, unsigned int len));
|
|
||||||
/**
|
|
||||||
* Send data.
|
|
||||||
*
|
|
||||||
* This macro sends data over a protosocket. The protosocket protothread blocks
|
|
||||||
* until all data has been sent and is known to have been received by
|
|
||||||
* the remote end of the TCP connection.
|
|
||||||
*
|
|
||||||
* \param psock (struct psock *) A pointer to the protosocket over which
|
|
||||||
* data is to be sent.
|
|
||||||
*
|
|
||||||
* \param data (char *) A pointer to the data that is to be sent.
|
|
||||||
*
|
|
||||||
* \param datalen (unsigned int) The length of the data that is to be
|
|
||||||
* sent.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PSOCK_SEND(psock, data, datalen) \
|
|
||||||
PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, data, datalen))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Send a null-terminated string.
|
|
||||||
* \param psock Pointer to the protosocket.
|
|
||||||
* \param str The string to be sent.
|
|
||||||
*
|
|
||||||
* This function sends a null-terminated string over the
|
|
||||||
* protosocket.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PSOCK_SEND_STR(psock, str) \
|
|
||||||
PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, str, strlen(str)))
|
|
||||||
|
|
||||||
PT_THREAD(psock_generator_send(struct psock *psock,
|
|
||||||
unsigned short (*f)(void *), void *arg));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Generate data with a function and send it
|
|
||||||
* \param psock Pointer to the protosocket.
|
|
||||||
* \param generator Pointer to the generator function
|
|
||||||
* \param arg Argument to the generator function
|
|
||||||
*
|
|
||||||
* This function generates data and sends it over the
|
|
||||||
* protosocket. This can be used to dynamically generate
|
|
||||||
* data for a transmission, instead of generating the data
|
|
||||||
* in a buffer beforehand. This function reduces the need for
|
|
||||||
* buffer memory. The generator function is implemented by
|
|
||||||
* the application, and a pointer to the function is given
|
|
||||||
* as an argument with the call to PSOCK_GENERATOR_SEND().
|
|
||||||
*
|
|
||||||
* The generator function should place the generated data
|
|
||||||
* directly in the uip_appdata buffer, and return the
|
|
||||||
* length of the generated data. The generator function is
|
|
||||||
* called by the protosocket layer when the data first is
|
|
||||||
* sent, and once for every retransmission that is needed.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PSOCK_GENERATOR_SEND(psock, generator, arg) \
|
|
||||||
PT_WAIT_THREAD(&((psock)->pt), \
|
|
||||||
psock_generator_send(psock, generator, arg))
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close a protosocket.
|
|
||||||
*
|
|
||||||
* This macro closes a protosocket and can only be called from within the
|
|
||||||
* protothread in which the protosocket lives.
|
|
||||||
*
|
|
||||||
* \param psock (struct psock *) A pointer to the protosocket that is to
|
|
||||||
* be closed.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PSOCK_CLOSE(psock) uip_close()
|
|
||||||
|
|
||||||
PT_THREAD(psock_readbuf(struct psock *psock));
|
|
||||||
/**
|
|
||||||
* Read data until the buffer is full.
|
|
||||||
*
|
|
||||||
* This macro will block waiting for data and read the data into the
|
|
||||||
* input buffer specified with the call to PSOCK_INIT(). Data is read
|
|
||||||
* until the buffer is full..
|
|
||||||
*
|
|
||||||
* \param psock (struct psock *) A pointer to the protosocket from which
|
|
||||||
* data should be read.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PSOCK_READBUF(psock) \
|
|
||||||
PT_WAIT_THREAD(&((psock)->pt), psock_readbuf(psock))
|
|
||||||
|
|
||||||
PT_THREAD(psock_readto(struct psock *psock, unsigned char c));
|
|
||||||
/**
|
|
||||||
* Read data up to a specified character.
|
|
||||||
*
|
|
||||||
* This macro will block waiting for data and read the data into the
|
|
||||||
* input buffer specified with the call to PSOCK_INIT(). Data is only
|
|
||||||
* read until the specifieed character appears in the data stream.
|
|
||||||
*
|
|
||||||
* \param psock (struct psock *) A pointer to the protosocket from which
|
|
||||||
* data should be read.
|
|
||||||
*
|
|
||||||
* \param c (char) The character at which to stop reading.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PSOCK_READTO(psock, c) \
|
|
||||||
PT_WAIT_THREAD(&((psock)->pt), psock_readto(psock, c))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The length of the data that was previously read.
|
|
||||||
*
|
|
||||||
* This macro returns the length of the data that was previously read
|
|
||||||
* using PSOCK_READTO() or PSOCK_READ().
|
|
||||||
*
|
|
||||||
* \param psock (struct psock *) A pointer to the protosocket holding the data.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PSOCK_DATALEN(psock) psock_datalen(psock)
|
|
||||||
|
|
||||||
u16_t psock_datalen(struct psock *psock);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exit the protosocket's protothread.
|
|
||||||
*
|
|
||||||
* This macro terminates the protothread of the protosocket and should
|
|
||||||
* almost always be used in conjunction with PSOCK_CLOSE().
|
|
||||||
*
|
|
||||||
* \sa PSOCK_CLOSE_EXIT()
|
|
||||||
*
|
|
||||||
* \param psock (struct psock *) A pointer to the protosocket.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PSOCK_EXIT(psock) PT_EXIT(&((psock)->pt))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close a protosocket and exit the protosocket's protothread.
|
|
||||||
*
|
|
||||||
* This macro closes a protosocket and exits the protosocket's protothread.
|
|
||||||
*
|
|
||||||
* \param psock (struct psock *) A pointer to the protosocket.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PSOCK_CLOSE_EXIT(psock) \
|
|
||||||
do { \
|
|
||||||
PSOCK_CLOSE(psock); \
|
|
||||||
PSOCK_EXIT(psock); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Declare the end of a protosocket's protothread.
|
|
||||||
*
|
|
||||||
* This macro is used for declaring that the protosocket's protothread
|
|
||||||
* ends. It must always be used together with a matching PSOCK_BEGIN()
|
|
||||||
* macro.
|
|
||||||
*
|
|
||||||
* \param psock (struct psock *) A pointer to the protosocket.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PSOCK_END(psock) PT_END(&((psock)->pt))
|
|
||||||
|
|
||||||
char psock_newdata(struct psock *s);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if new data has arrived on a protosocket.
|
|
||||||
*
|
|
||||||
* This macro is used in conjunction with the PSOCK_WAIT_UNTIL()
|
|
||||||
* macro to check if data has arrived on a protosocket.
|
|
||||||
*
|
|
||||||
* \param psock (struct psock *) A pointer to the protosocket.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PSOCK_NEWDATA(psock) psock_newdata(psock)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wait until a condition is true.
|
|
||||||
*
|
|
||||||
* This macro blocks the protothread until the specified condition is
|
|
||||||
* true. The macro PSOCK_NEWDATA() can be used to check if new data
|
|
||||||
* arrives when the protosocket is waiting.
|
|
||||||
*
|
|
||||||
* Typically, this macro is used as follows:
|
|
||||||
*
|
|
||||||
\code
|
|
||||||
PT_THREAD(thread(struct psock *s, struct timer *t))
|
|
||||||
{
|
|
||||||
PSOCK_BEGIN(s);
|
|
||||||
|
|
||||||
PSOCK_WAIT_UNTIL(s, PSOCK_NEWADATA(s) || timer_expired(t));
|
|
||||||
|
|
||||||
if(PSOCK_NEWDATA(s)) {
|
|
||||||
PSOCK_READTO(s, '\n');
|
|
||||||
} else {
|
|
||||||
handle_timed_out(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
PSOCK_END(s);
|
|
||||||
}
|
|
||||||
\endcode
|
|
||||||
*
|
|
||||||
* \param psock (struct psock *) A pointer to the protosocket.
|
|
||||||
* \param condition The condition to wait for.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PSOCK_WAIT_UNTIL(psock, condition) \
|
|
||||||
PT_WAIT_UNTIL(&((psock)->pt), (condition));
|
|
||||||
|
|
||||||
#define PSOCK_WAIT_THREAD(psock, condition) \
|
|
||||||
PT_WAIT_THREAD(&((psock)->pt), (condition))
|
|
||||||
|
|
||||||
#endif /* __PSOCK_H__ */
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,323 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2004-2005, 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 uIP TCP/IP stack
|
|
||||||
*
|
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
* $Id: pt.h,v 1.2 2006/06/12 08:00:30 adam Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \addtogroup pt
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* Protothreads implementation.
|
|
||||||
* \author
|
|
||||||
* Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __PT_H__
|
|
||||||
#define __PT_H__
|
|
||||||
|
|
||||||
#include "lc.h"
|
|
||||||
|
|
||||||
struct pt {
|
|
||||||
lc_t lc;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define PT_WAITING 0
|
|
||||||
#define PT_EXITED 1
|
|
||||||
#define PT_ENDED 2
|
|
||||||
#define PT_YIELDED 3
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \name Initialization
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize a protothread.
|
|
||||||
*
|
|
||||||
* Initializes a protothread. Initialization must be done prior to
|
|
||||||
* starting to execute the protothread.
|
|
||||||
*
|
|
||||||
* \param pt A pointer to the protothread control structure.
|
|
||||||
*
|
|
||||||
* \sa PT_SPAWN()
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PT_INIT(pt) LC_INIT((pt)->lc)
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \name Declaration and definition
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Declaration of a protothread.
|
|
||||||
*
|
|
||||||
* This macro is used to declare a protothread. All protothreads must
|
|
||||||
* be declared with this macro.
|
|
||||||
*
|
|
||||||
* \param name_args The name and arguments of the C function
|
|
||||||
* implementing the protothread.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PT_THREAD(name_args) char name_args
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Declare the start of a protothread inside the C function
|
|
||||||
* implementing the protothread.
|
|
||||||
*
|
|
||||||
* This macro is used to declare the starting point of a
|
|
||||||
* protothread. It should be placed at the start of the function in
|
|
||||||
* which the protothread runs. All C statements above the PT_BEGIN()
|
|
||||||
* invokation will be executed each time the protothread is scheduled.
|
|
||||||
*
|
|
||||||
* \param pt A pointer to the protothread control structure.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Declare the end of a protothread.
|
|
||||||
*
|
|
||||||
* This macro is used for declaring that a protothread ends. It must
|
|
||||||
* always be used together with a matching PT_BEGIN() macro.
|
|
||||||
*
|
|
||||||
* \param pt A pointer to the protothread control structure.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \
|
|
||||||
PT_INIT(pt); return PT_ENDED; }
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \name Blocked wait
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Block and wait until condition is true.
|
|
||||||
*
|
|
||||||
* This macro blocks the protothread until the specified condition is
|
|
||||||
* true.
|
|
||||||
*
|
|
||||||
* \param pt A pointer to the protothread control structure.
|
|
||||||
* \param condition The condition.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PT_WAIT_UNTIL(pt, condition) \
|
|
||||||
do { \
|
|
||||||
LC_SET((pt)->lc); \
|
|
||||||
if(!(condition)) { \
|
|
||||||
return PT_WAITING; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Block and wait while condition is true.
|
|
||||||
*
|
|
||||||
* This function blocks and waits while condition is true. See
|
|
||||||
* PT_WAIT_UNTIL().
|
|
||||||
*
|
|
||||||
* \param pt A pointer to the protothread control structure.
|
|
||||||
* \param cond The condition.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond))
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \name Hierarchical protothreads
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Block and wait until a child protothread completes.
|
|
||||||
*
|
|
||||||
* This macro schedules a child protothread. The current protothread
|
|
||||||
* will block until the child protothread completes.
|
|
||||||
*
|
|
||||||
* \note The child protothread must be manually initialized with the
|
|
||||||
* PT_INIT() function before this function is used.
|
|
||||||
*
|
|
||||||
* \param pt A pointer to the protothread control structure.
|
|
||||||
* \param thread The child protothread with arguments
|
|
||||||
*
|
|
||||||
* \sa PT_SPAWN()
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spawn a child protothread and wait until it exits.
|
|
||||||
*
|
|
||||||
* This macro spawns a child protothread and waits until it exits. The
|
|
||||||
* macro can only be used within a protothread.
|
|
||||||
*
|
|
||||||
* \param pt A pointer to the protothread control structure.
|
|
||||||
* \param child A pointer to the child protothread's control structure.
|
|
||||||
* \param thread The child protothread with arguments
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PT_SPAWN(pt, child, thread) \
|
|
||||||
do { \
|
|
||||||
PT_INIT((child)); \
|
|
||||||
PT_WAIT_THREAD((pt), (thread)); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \name Exiting and restarting
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Restart the protothread.
|
|
||||||
*
|
|
||||||
* This macro will block and cause the running protothread to restart
|
|
||||||
* its execution at the place of the PT_BEGIN() call.
|
|
||||||
*
|
|
||||||
* \param pt A pointer to the protothread control structure.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PT_RESTART(pt) \
|
|
||||||
do { \
|
|
||||||
PT_INIT(pt); \
|
|
||||||
return PT_WAITING; \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exit the protothread.
|
|
||||||
*
|
|
||||||
* This macro causes the protothread to exit. If the protothread was
|
|
||||||
* spawned by another protothread, the parent protothread will become
|
|
||||||
* unblocked and can continue to run.
|
|
||||||
*
|
|
||||||
* \param pt A pointer to the protothread control structure.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PT_EXIT(pt) \
|
|
||||||
do { \
|
|
||||||
PT_INIT(pt); \
|
|
||||||
return PT_EXITED; \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \name Calling a protothread
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Schedule a protothread.
|
|
||||||
*
|
|
||||||
* This function shedules a protothread. The return value of the
|
|
||||||
* function is non-zero if the protothread is running or zero if the
|
|
||||||
* protothread has exited.
|
|
||||||
*
|
|
||||||
* \param f The call to the C function implementing the protothread to
|
|
||||||
* be scheduled
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PT_SCHEDULE(f) ((f) == PT_WAITING)
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \name Yielding from a protothread
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Yield from the current protothread.
|
|
||||||
*
|
|
||||||
* This function will yield the protothread, thereby allowing other
|
|
||||||
* processing to take place in the system.
|
|
||||||
*
|
|
||||||
* \param pt A pointer to the protothread control structure.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PT_YIELD(pt) \
|
|
||||||
do { \
|
|
||||||
PT_YIELD_FLAG = 0; \
|
|
||||||
LC_SET((pt)->lc); \
|
|
||||||
if(PT_YIELD_FLAG == 0) { \
|
|
||||||
return PT_YIELDED; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Yield from the protothread until a condition occurs.
|
|
||||||
* \param pt A pointer to the protothread control structure.
|
|
||||||
* \param cond The condition.
|
|
||||||
*
|
|
||||||
* This function will yield the protothread, until the
|
|
||||||
* specified condition evaluates to true.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define PT_YIELD_UNTIL(pt, cond) \
|
|
||||||
do { \
|
|
||||||
PT_YIELD_FLAG = 0; \
|
|
||||||
LC_SET((pt)->lc); \
|
|
||||||
if((PT_YIELD_FLAG == 0) || !(cond)) { \
|
|
||||||
return PT_YIELDED; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif /* __PT_H__ */
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,532 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2004, 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 uIP TCP/IP stack
|
|
||||||
*
|
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
* $Id: uip-fw.c,v 1.2 2006/06/12 08:00:30 adam Exp $
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* \addtogroup uip
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \defgroup uipfw uIP packet forwarding
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* uIP packet forwarding.
|
|
||||||
* \author Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
* This file implements a number of simple functions which do packet
|
|
||||||
* forwarding over multiple network interfaces with uIP.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "uip.h"
|
|
||||||
#include "uip_arch.h"
|
|
||||||
#include "uip-fw.h"
|
|
||||||
|
|
||||||
#include <string.h> /* for memcpy() */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The list of registered network interfaces.
|
|
||||||
*/
|
|
||||||
static struct uip_fw_netif *netifs = NULL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A pointer to the default network interface.
|
|
||||||
*/
|
|
||||||
static struct uip_fw_netif *defaultnetif = NULL;
|
|
||||||
|
|
||||||
struct tcpip_hdr {
|
|
||||||
/* IP header. */
|
|
||||||
u8_t vhl,
|
|
||||||
tos;
|
|
||||||
u16_t len,
|
|
||||||
ipid,
|
|
||||||
ipoffset;
|
|
||||||
u8_t ttl,
|
|
||||||
proto;
|
|
||||||
u16_t ipchksum;
|
|
||||||
u16_t srcipaddr[2],
|
|
||||||
destipaddr[2];
|
|
||||||
|
|
||||||
/* TCP header. */
|
|
||||||
u16_t srcport,
|
|
||||||
destport;
|
|
||||||
u8_t seqno[4],
|
|
||||||
ackno[4],
|
|
||||||
tcpoffset,
|
|
||||||
flags,
|
|
||||||
wnd[2];
|
|
||||||
u16_t tcpchksum;
|
|
||||||
u8_t urgp[2];
|
|
||||||
u8_t optdata[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct icmpip_hdr {
|
|
||||||
/* IP header. */
|
|
||||||
u8_t vhl,
|
|
||||||
tos,
|
|
||||||
len[2],
|
|
||||||
ipid[2],
|
|
||||||
ipoffset[2],
|
|
||||||
ttl,
|
|
||||||
proto;
|
|
||||||
u16_t ipchksum;
|
|
||||||
u16_t srcipaddr[2],
|
|
||||||
destipaddr[2];
|
|
||||||
/* ICMP (echo) header. */
|
|
||||||
u8_t type, icode;
|
|
||||||
u16_t icmpchksum;
|
|
||||||
u16_t id, seqno;
|
|
||||||
u8_t payload[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ICMP ECHO. */
|
|
||||||
#define ICMP_ECHO 8
|
|
||||||
|
|
||||||
/* ICMP TIME-EXCEEDED. */
|
|
||||||
#define ICMP_TE 11
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Pointer to the TCP/IP headers of the packet in the uip_buf buffer.
|
|
||||||
*/
|
|
||||||
#define BUF ((struct tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Pointer to the ICMP/IP headers of the packet in the uip_buf buffer.
|
|
||||||
*/
|
|
||||||
#define ICMPBUF ((struct icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Certain fields of an IP packet that are used for identifying
|
|
||||||
* duplicate packets.
|
|
||||||
*/
|
|
||||||
struct fwcache_entry {
|
|
||||||
u16_t timer;
|
|
||||||
|
|
||||||
u16_t srcipaddr[2];
|
|
||||||
u16_t destipaddr[2];
|
|
||||||
u16_t ipid;
|
|
||||||
u8_t proto;
|
|
||||||
u8_t unused;
|
|
||||||
|
|
||||||
#if notdef
|
|
||||||
u16_t payload[2];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if UIP_REASSEMBLY > 0
|
|
||||||
u16_t len, offset;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The number of packets to remember when looking for duplicates.
|
|
||||||
*/
|
|
||||||
#ifdef UIP_CONF_FWCACHE_SIZE
|
|
||||||
#define FWCACHE_SIZE UIP_CONF_FWCACHE_SIZE
|
|
||||||
#else
|
|
||||||
#define FWCACHE_SIZE 2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A cache of packet header fields which are used for
|
|
||||||
* identifying duplicate packets.
|
|
||||||
*/
|
|
||||||
static struct fwcache_entry fwcache[FWCACHE_SIZE];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \internal
|
|
||||||
* The time that a packet cache is active.
|
|
||||||
*/
|
|
||||||
#define FW_TIME 20
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* Initialize the uIP packet forwarding module.
|
|
||||||
*/
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
uip_fw_init(void)
|
|
||||||
{
|
|
||||||
struct uip_fw_netif *t;
|
|
||||||
defaultnetif = NULL;
|
|
||||||
while(netifs != NULL) {
|
|
||||||
t = netifs;
|
|
||||||
netifs = netifs->next;
|
|
||||||
t->next = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* \internal
|
|
||||||
* Check if an IP address is within the network defined by an IP
|
|
||||||
* address and a netmask.
|
|
||||||
*
|
|
||||||
* \param ipaddr The IP address to be checked.
|
|
||||||
* \param netipaddr The IP address of the network.
|
|
||||||
* \param netmask The netmask of the network.
|
|
||||||
*
|
|
||||||
* \return Non-zero if IP address is in network, zero otherwise.
|
|
||||||
*/
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
static unsigned char
|
|
||||||
ipaddr_maskcmp(u16_t *ipaddr, u16_t *netipaddr, u16_t *netmask)
|
|
||||||
{
|
|
||||||
return (ipaddr[0] & netmask [0]) == (netipaddr[0] & netmask[0]) &&
|
|
||||||
(ipaddr[1] & netmask[1]) == (netipaddr[1] & netmask[1]);
|
|
||||||
}
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* \internal
|
|
||||||
* Send out an ICMP TIME-EXCEEDED message.
|
|
||||||
*
|
|
||||||
* This function replaces the packet in the uip_buf buffer with the
|
|
||||||
* ICMP packet.
|
|
||||||
*/
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
static void
|
|
||||||
time_exceeded(void)
|
|
||||||
{
|
|
||||||
u16_t tmp16;
|
|
||||||
|
|
||||||
/* We don't send out ICMP errors for ICMP messages. */
|
|
||||||
if(ICMPBUF->proto == UIP_PROTO_ICMP) {
|
|
||||||
uip_len = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* Copy fields from packet header into payload of this ICMP packet. */
|
|
||||||
memcpy(&(ICMPBUF->payload[0]), ICMPBUF, 28);
|
|
||||||
|
|
||||||
/* Set the ICMP type and code. */
|
|
||||||
ICMPBUF->type = ICMP_TE;
|
|
||||||
ICMPBUF->icode = 0;
|
|
||||||
|
|
||||||
/* Calculate the ICMP checksum. */
|
|
||||||
ICMPBUF->icmpchksum = 0;
|
|
||||||
ICMPBUF->icmpchksum = ~uip_chksum((u16_t *)&(ICMPBUF->type), 36);
|
|
||||||
|
|
||||||
/* Set the IP destination address to be the source address of the
|
|
||||||
original packet. */
|
|
||||||
tmp16= BUF->destipaddr[0];
|
|
||||||
BUF->destipaddr[0] = BUF->srcipaddr[0];
|
|
||||||
BUF->srcipaddr[0] = tmp16;
|
|
||||||
tmp16 = BUF->destipaddr[1];
|
|
||||||
BUF->destipaddr[1] = BUF->srcipaddr[1];
|
|
||||||
BUF->srcipaddr[1] = tmp16;
|
|
||||||
|
|
||||||
/* Set our IP address as the source address. */
|
|
||||||
BUF->srcipaddr[0] = uip_hostaddr[0];
|
|
||||||
BUF->srcipaddr[1] = uip_hostaddr[1];
|
|
||||||
|
|
||||||
/* The size of the ICMP time exceeded packet is 36 + the size of the
|
|
||||||
IP header (20) = 56. */
|
|
||||||
uip_len = 56;
|
|
||||||
ICMPBUF->len[0] = 0;
|
|
||||||
ICMPBUF->len[1] = uip_len;
|
|
||||||
|
|
||||||
/* Fill in the other fields in the IP header. */
|
|
||||||
ICMPBUF->vhl = 0x45;
|
|
||||||
ICMPBUF->tos = 0;
|
|
||||||
ICMPBUF->ipoffset[0] = ICMPBUF->ipoffset[1] = 0;
|
|
||||||
ICMPBUF->ttl = UIP_TTL;
|
|
||||||
ICMPBUF->proto = UIP_PROTO_ICMP;
|
|
||||||
|
|
||||||
/* Calculate IP checksum. */
|
|
||||||
ICMPBUF->ipchksum = 0;
|
|
||||||
ICMPBUF->ipchksum = ~(uip_ipchksum());
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* \internal
|
|
||||||
* Register a packet in the forwarding cache so that it won't be
|
|
||||||
* forwarded again.
|
|
||||||
*/
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
static void
|
|
||||||
fwcache_register(void)
|
|
||||||
{
|
|
||||||
struct fwcache_entry *fw;
|
|
||||||
int i, oldest;
|
|
||||||
|
|
||||||
oldest = FW_TIME;
|
|
||||||
fw = NULL;
|
|
||||||
|
|
||||||
/* Find the oldest entry in the cache. */
|
|
||||||
for(i = 0; i < FWCACHE_SIZE; ++i) {
|
|
||||||
if(fwcache[i].timer == 0) {
|
|
||||||
fw = &fwcache[i];
|
|
||||||
break;
|
|
||||||
} else if(fwcache[i].timer <= oldest) {
|
|
||||||
fw = &fwcache[i];
|
|
||||||
oldest = fwcache[i].timer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fw->timer = FW_TIME;
|
|
||||||
fw->ipid = BUF->ipid;
|
|
||||||
fw->srcipaddr[0] = BUF->srcipaddr[0];
|
|
||||||
fw->srcipaddr[1] = BUF->srcipaddr[1];
|
|
||||||
fw->destipaddr[0] = BUF->destipaddr[0];
|
|
||||||
fw->destipaddr[1] = BUF->destipaddr[1];
|
|
||||||
fw->proto = BUF->proto;
|
|
||||||
#if notdef
|
|
||||||
fw->payload[0] = BUF->srcport;
|
|
||||||
fw->payload[1] = BUF->destport;
|
|
||||||
#endif
|
|
||||||
#if UIP_REASSEMBLY > 0
|
|
||||||
fw->len = BUF->len;
|
|
||||||
fw->offset = BUF->ipoffset;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* \internal
|
|
||||||
* Find a network interface for the IP packet in uip_buf.
|
|
||||||
*/
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
static struct uip_fw_netif *
|
|
||||||
find_netif(void)
|
|
||||||
{
|
|
||||||
struct uip_fw_netif *netif;
|
|
||||||
|
|
||||||
/* Walk through every network interface to check for a match. */
|
|
||||||
for(netif = netifs; netif != NULL; netif = netif->next) {
|
|
||||||
if(ipaddr_maskcmp(BUF->destipaddr, netif->ipaddr,
|
|
||||||
netif->netmask)) {
|
|
||||||
/* If there was a match, we break the loop. */
|
|
||||||
return netif;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If no matching netif was found, we use default netif. */
|
|
||||||
return defaultnetif;
|
|
||||||
}
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* Output an IP packet on the correct network interface.
|
|
||||||
*
|
|
||||||
* The IP packet should be present in the uip_buf buffer and its
|
|
||||||
* length in the global uip_len variable.
|
|
||||||
*
|
|
||||||
* \retval UIP_FW_ZEROLEN Indicates that a zero-length packet
|
|
||||||
* transmission was attempted and that no packet was sent.
|
|
||||||
*
|
|
||||||
* \retval UIP_FW_NOROUTE No suitable network interface could be found
|
|
||||||
* for the outbound packet, and the packet was not sent.
|
|
||||||
*
|
|
||||||
* \return The return value from the actual network interface output
|
|
||||||
* function is passed unmodified as a return value.
|
|
||||||
*/
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
u8_t
|
|
||||||
uip_fw_output(void)
|
|
||||||
{
|
|
||||||
struct uip_fw_netif *netif;
|
|
||||||
|
|
||||||
if(uip_len == 0) {
|
|
||||||
return UIP_FW_ZEROLEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
fwcache_register();
|
|
||||||
|
|
||||||
#if UIP_BROADCAST
|
|
||||||
/* Link local broadcasts go out on all interfaces. */
|
|
||||||
if(/*BUF->proto == UIP_PROTO_UDP &&*/
|
|
||||||
BUF->destipaddr[0] == 0xffff &&
|
|
||||||
BUF->destipaddr[1] == 0xffff) {
|
|
||||||
if(defaultnetif != NULL) {
|
|
||||||
defaultnetif->output();
|
|
||||||
}
|
|
||||||
for(netif = netifs; netif != NULL; netif = netif->next) {
|
|
||||||
netif->output();
|
|
||||||
}
|
|
||||||
return UIP_FW_OK;
|
|
||||||
}
|
|
||||||
#endif /* UIP_BROADCAST */
|
|
||||||
|
|
||||||
netif = find_netif();
|
|
||||||
/* printf("uip_fw_output: netif %p ->output %p len %d\n", netif,
|
|
||||||
netif->output,
|
|
||||||
uip_len);*/
|
|
||||||
|
|
||||||
if(netif == NULL) {
|
|
||||||
return UIP_FW_NOROUTE;
|
|
||||||
}
|
|
||||||
/* If we now have found a suitable network interface, we call its
|
|
||||||
output function to send out the packet. */
|
|
||||||
return netif->output();
|
|
||||||
}
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* Forward an IP packet in the uip_buf buffer.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* \return UIP_FW_FORWARDED if the packet was forwarded, UIP_FW_LOCAL if
|
|
||||||
* the packet should be processed locally.
|
|
||||||
*/
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
u8_t
|
|
||||||
uip_fw_forward(void)
|
|
||||||
{
|
|
||||||
struct fwcache_entry *fw;
|
|
||||||
|
|
||||||
/* First check if the packet is destined for ourselves and return 0
|
|
||||||
to indicate that the packet should be processed locally. */
|
|
||||||
if(BUF->destipaddr[0] == uip_hostaddr[0] &&
|
|
||||||
BUF->destipaddr[1] == uip_hostaddr[1]) {
|
|
||||||
return UIP_FW_LOCAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we use ping IP address configuration, and our IP address is
|
|
||||||
not yet configured, we should intercept all ICMP echo packets. */
|
|
||||||
#if UIP_PINGADDRCONF
|
|
||||||
if((uip_hostaddr[0] | uip_hostaddr[1]) == 0 &&
|
|
||||||
BUF->proto == UIP_PROTO_ICMP &&
|
|
||||||
ICMPBUF->type == ICMP_ECHO) {
|
|
||||||
return UIP_FW_LOCAL;
|
|
||||||
}
|
|
||||||
#endif /* UIP_PINGADDRCONF */
|
|
||||||
|
|
||||||
/* Check if the packet is in the forwarding cache already, and if so
|
|
||||||
we drop it. */
|
|
||||||
|
|
||||||
for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
|
|
||||||
if(fw->timer != 0 &&
|
|
||||||
#if UIP_REASSEMBLY > 0
|
|
||||||
fw->len == BUF->len &&
|
|
||||||
fw->offset == BUF->ipoffset &&
|
|
||||||
#endif
|
|
||||||
fw->ipid == BUF->ipid &&
|
|
||||||
fw->srcipaddr[0] == BUF->srcipaddr[0] &&
|
|
||||||
fw->srcipaddr[1] == BUF->srcipaddr[1] &&
|
|
||||||
fw->destipaddr[0] == BUF->destipaddr[0] &&
|
|
||||||
fw->destipaddr[1] == BUF->destipaddr[1] &&
|
|
||||||
#if notdef
|
|
||||||
fw->payload[0] == BUF->srcport &&
|
|
||||||
fw->payload[1] == BUF->destport &&
|
|
||||||
#endif
|
|
||||||
fw->proto == BUF->proto) {
|
|
||||||
/* Drop packet. */
|
|
||||||
return UIP_FW_FORWARDED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the TTL reaches zero we produce an ICMP time exceeded message
|
|
||||||
in the uip_buf buffer and forward that packet back to the sender
|
|
||||||
of the packet. */
|
|
||||||
if(BUF->ttl <= 1) {
|
|
||||||
/* No time exceeded for broadcasts and multicasts! */
|
|
||||||
if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) {
|
|
||||||
return UIP_FW_LOCAL;
|
|
||||||
}
|
|
||||||
time_exceeded();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decrement the TTL (time-to-live) value in the IP header */
|
|
||||||
BUF->ttl = BUF->ttl - 1;
|
|
||||||
|
|
||||||
/* Update the IP checksum. */
|
|
||||||
if(BUF->ipchksum >= HTONS(0xffff - 0x0100)) {
|
|
||||||
BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1;
|
|
||||||
} else {
|
|
||||||
BUF->ipchksum = BUF->ipchksum + HTONS(0x0100);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(uip_len > 0) {
|
|
||||||
uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN];
|
|
||||||
uip_fw_output();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if UIP_BROADCAST
|
|
||||||
if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) {
|
|
||||||
return UIP_FW_LOCAL;
|
|
||||||
}
|
|
||||||
#endif /* UIP_BROADCAST */
|
|
||||||
|
|
||||||
/* Return non-zero to indicate that the packet was forwarded and that no
|
|
||||||
other processing should be made. */
|
|
||||||
return UIP_FW_FORWARDED;
|
|
||||||
}
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* Register a network interface with the forwarding module.
|
|
||||||
*
|
|
||||||
* \param netif A pointer to the network interface that is to be
|
|
||||||
* registered.
|
|
||||||
*/
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
uip_fw_register(struct uip_fw_netif *netif)
|
|
||||||
{
|
|
||||||
netif->next = netifs;
|
|
||||||
netifs = netif;
|
|
||||||
}
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* Register a default network interface.
|
|
||||||
*
|
|
||||||
* All packets that don't go out on any of the other interfaces will
|
|
||||||
* be routed to the default interface.
|
|
||||||
*
|
|
||||||
* \param netif A pointer to the network interface that is to be
|
|
||||||
* registered.
|
|
||||||
*/
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
uip_fw_default(struct uip_fw_netif *netif)
|
|
||||||
{
|
|
||||||
defaultnetif = netif;
|
|
||||||
}
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* Perform periodic processing.
|
|
||||||
*/
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
uip_fw_periodic(void)
|
|
||||||
{
|
|
||||||
struct fwcache_entry *fw;
|
|
||||||
for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
|
|
||||||
if(fw->timer > 0) {
|
|
||||||
--fw->timer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
|
@ -1,176 +0,0 @@
|
||||||
/**
|
|
||||||
* \addtogroup uipfw
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* uIP packet forwarding header file.
|
|
||||||
* \author Adam Dunkels <adam@sics.se>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2004, 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 uIP TCP/IP stack
|
|
||||||
*
|
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
* $Id: uip-fw.h,v 1.2 2006/06/12 08:00:30 adam Exp $
|
|
||||||
*/
|
|
||||||
#ifndef __UIP_FW_H__
|
|
||||||
#define __UIP_FW_H__
|
|
||||||
|
|
||||||
#include "uip.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Representation of a uIP network interface.
|
|
||||||
*/
|
|
||||||
struct uip_fw_netif {
|
|
||||||
struct uip_fw_netif *next; /**< Pointer to the next interface when
|
|
||||||
linked in a list. */
|
|
||||||
u16_t ipaddr[2]; /**< The IP address of this interface. */
|
|
||||||
u16_t netmask[2]; /**< The netmask of the interface. */
|
|
||||||
u8_t (* output)(void);
|
|
||||||
/**< A pointer to the function that
|
|
||||||
sends a packet. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Intantiating macro for a uIP network interface.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
\code
|
|
||||||
struct uip_fw_netif slipnetif =
|
|
||||||
{UIP_FW_NETIF(192,168,76,1, 255,255,255,0, slip_output)};
|
|
||||||
\endcode
|
|
||||||
* \param ip1,ip2,ip3,ip4 The IP address of the network interface.
|
|
||||||
*
|
|
||||||
* \param nm1,nm2,nm3,nm4 The netmask of the network interface.
|
|
||||||
*
|
|
||||||
* \param outputfunc A pointer to the output function of the network interface.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define UIP_FW_NETIF(ip1,ip2,ip3,ip4, nm1,nm2,nm3,nm4, outputfunc) \
|
|
||||||
NULL, \
|
|
||||||
{HTONS((ip1 << 8) | ip2), HTONS((ip3 << 8) | ip4)}, \
|
|
||||||
{HTONS((nm1 << 8) | nm2), HTONS((nm3 << 8) | nm4)}, \
|
|
||||||
outputfunc
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the IP address of a network interface.
|
|
||||||
*
|
|
||||||
* \param netif A pointer to the uip_fw_netif structure for the network interface.
|
|
||||||
*
|
|
||||||
* \param addr A pointer to an IP address.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define uip_fw_setipaddr(netif, addr) \
|
|
||||||
do { (netif)->ipaddr[0] = ((u16_t *)(addr))[0]; \
|
|
||||||
(netif)->ipaddr[1] = ((u16_t *)(addr))[1]; } while(0)
|
|
||||||
/**
|
|
||||||
* Set the netmask of a network interface.
|
|
||||||
*
|
|
||||||
* \param netif A pointer to the uip_fw_netif structure for the network interface.
|
|
||||||
*
|
|
||||||
* \param addr A pointer to an IP address representing the netmask.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define uip_fw_setnetmask(netif, addr) \
|
|
||||||
do { (netif)->netmask[0] = ((u16_t *)(addr))[0]; \
|
|
||||||
(netif)->netmask[1] = ((u16_t *)(addr))[1]; } while(0)
|
|
||||||
|
|
||||||
void uip_fw_init(void);
|
|
||||||
u8_t uip_fw_forward(void);
|
|
||||||
u8_t uip_fw_output(void);
|
|
||||||
void uip_fw_register(struct uip_fw_netif *netif);
|
|
||||||
void uip_fw_default(struct uip_fw_netif *netif);
|
|
||||||
void uip_fw_periodic(void);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A non-error message that indicates that a packet should be
|
|
||||||
* processed locally.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define UIP_FW_LOCAL 0
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A non-error message that indicates that something went OK.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define UIP_FW_OK 0
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A non-error message that indicates that a packet was forwarded.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define UIP_FW_FORWARDED 1
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A non-error message that indicates that a zero-length packet
|
|
||||||
* transmission was attempted, and that no packet was sent.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define UIP_FW_ZEROLEN 2
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An error message that indicates that a packet that was too large
|
|
||||||
* for the outbound network interface was detected.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define UIP_FW_TOOLARGE 3
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An error message that indicates that no suitable interface could be
|
|
||||||
* found for an outbound packet.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define UIP_FW_NOROUTE 4
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An error message that indicates that a packet that should be
|
|
||||||
* forwarded or output was dropped.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define UIP_FW_DROPPED 5
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __UIP_FW_H__ */
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,158 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2006, 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 uIP TCP/IP stack
|
|
||||||
*
|
|
||||||
* $Id: uip-neighbor.c,v 1.2 2006/06/12 08:00:30 adam Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* Database of link-local neighbors, used by IPv6 code and
|
|
||||||
* to be used by a future ARP code rewrite.
|
|
||||||
* \author
|
|
||||||
* Adam Dunkels <adam@sics.se>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "uip-neighbor.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define MAX_TIME 128
|
|
||||||
|
|
||||||
#ifdef UIP_NEIGHBOR_CONF_ENTRIES
|
|
||||||
#define ENTRIES UIP_NEIGHBOR_CONF_ENTRIES
|
|
||||||
#else /* UIP_NEIGHBOR_CONF_ENTRIES */
|
|
||||||
#define ENTRIES 8
|
|
||||||
#endif /* UIP_NEIGHBOR_CONF_ENTRIES */
|
|
||||||
|
|
||||||
struct neighbor_entry {
|
|
||||||
uip_ipaddr_t ipaddr;
|
|
||||||
struct uip_neighbor_addr addr;
|
|
||||||
u8_t time;
|
|
||||||
};
|
|
||||||
static struct neighbor_entry entries[ENTRIES];
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
uip_neighbor_init(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i = 0; i < ENTRIES; ++i) {
|
|
||||||
entries[i].time = MAX_TIME;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
uip_neighbor_periodic(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i = 0; i < ENTRIES; ++i) {
|
|
||||||
if(entries[i].time < MAX_TIME) {
|
|
||||||
entries[i].time++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr)
|
|
||||||
{
|
|
||||||
int i, oldest;
|
|
||||||
u8_t oldest_time;
|
|
||||||
|
|
||||||
printf("Adding neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n",
|
|
||||||
addr->addr.addr[0], addr->addr.addr[1], addr->addr.addr[2], addr->addr.addr[3],
|
|
||||||
addr->addr.addr[4], addr->addr.addr[5]);
|
|
||||||
|
|
||||||
/* Find the first unused entry or the oldest used entry. */
|
|
||||||
oldest_time = 0;
|
|
||||||
oldest = 0;
|
|
||||||
for(i = 0; i < ENTRIES; ++i) {
|
|
||||||
if(entries[i].time == MAX_TIME) {
|
|
||||||
oldest = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(uip_ipaddr_cmp(entries[i].ipaddr, addr)) {
|
|
||||||
oldest = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(entries[i].time > oldest_time) {
|
|
||||||
oldest = i;
|
|
||||||
oldest_time = entries[i].time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Use the oldest or first free entry (either pointed to by the
|
|
||||||
"oldest" variable). */
|
|
||||||
entries[oldest].time = 0;
|
|
||||||
uip_ipaddr_copy(entries[oldest].ipaddr, ipaddr);
|
|
||||||
memcpy(&entries[oldest].addr, addr, sizeof(struct uip_neighbor_addr));
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
static struct neighbor_entry *
|
|
||||||
find_entry(uip_ipaddr_t ipaddr)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i = 0; i < ENTRIES; ++i) {
|
|
||||||
if(uip_ipaddr_cmp(entries[i].ipaddr, ipaddr)) {
|
|
||||||
return &entries[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
uip_neighbor_update(uip_ipaddr_t ipaddr)
|
|
||||||
{
|
|
||||||
struct neighbor_entry *e;
|
|
||||||
|
|
||||||
e = find_entry(ipaddr);
|
|
||||||
if(e != NULL) {
|
|
||||||
e->time = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
struct uip_neighbor_addr *
|
|
||||||
uip_neighbor_lookup(uip_ipaddr_t ipaddr)
|
|
||||||
{
|
|
||||||
struct neighbor_entry *e;
|
|
||||||
|
|
||||||
e = find_entry(ipaddr);
|
|
||||||
if(e != NULL) {
|
|
||||||
/* printf("Lookup neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n",
|
|
||||||
e->addr.addr.addr[0], e->addr.addr.addr[1], e->addr.addr.addr[2], e->addr.addr.addr[3],
|
|
||||||
e->addr.addr.addr[4], e->addr.addr.addr[5]);*/
|
|
||||||
|
|
||||||
return &e->addr;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
|
@ -1,61 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2006, 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 uIP TCP/IP stack
|
|
||||||
*
|
|
||||||
* $Id: uip-neighbor.h,v 1.2 2006/06/12 08:00:30 adam Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* Header file for database of link-local neighbors, used by
|
|
||||||
* IPv6 code and to be used by future ARP code.
|
|
||||||
* \author
|
|
||||||
* Adam Dunkels <adam@sics.se>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UIP_NEIGHBOR_H__
|
|
||||||
#define __UIP_NEIGHBOR_H__
|
|
||||||
|
|
||||||
#include "uip.h"
|
|
||||||
|
|
||||||
struct uip_neighbor_addr {
|
|
||||||
#if UIP_NEIGHBOR_CONF_ADDRTYPE
|
|
||||||
UIP_NEIGHBOR_CONF_ADDRTYPE addr;
|
|
||||||
#else
|
|
||||||
struct uip_eth_addr addr;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
void uip_neighbor_init(void);
|
|
||||||
void uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr);
|
|
||||||
void uip_neighbor_update(uip_ipaddr_t ipaddr);
|
|
||||||
struct uip_neighbor_addr *uip_neighbor_lookup(uip_ipaddr_t ipaddr);
|
|
||||||
void uip_neighbor_periodic(void);
|
|
||||||
|
|
||||||
#endif /* __UIP-NEIGHBOR_H__ */
|
|
|
@ -1,136 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2004, 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 uIP TCP/IP stack
|
|
||||||
*
|
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
* $Id: uip-split.c,v 1.2 2006/06/12 08:00:30 adam Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "uip-split.h"
|
|
||||||
#include "uip.h"
|
|
||||||
#include "uip-fw.h"
|
|
||||||
#include "uip_arch.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
uip_split_output(void)
|
|
||||||
{
|
|
||||||
u16_t tcplen, len1, len2;
|
|
||||||
|
|
||||||
/* We only try to split maximum sized TCP segments. */
|
|
||||||
if(BUF->proto == UIP_PROTO_TCP &&
|
|
||||||
uip_len == UIP_BUFSIZE - UIP_LLH_LEN) {
|
|
||||||
|
|
||||||
tcplen = uip_len - UIP_TCPIP_HLEN;
|
|
||||||
/* Split the segment in two. If the original packet length was
|
|
||||||
odd, we make the second packet one byte larger. */
|
|
||||||
len1 = len2 = tcplen / 2;
|
|
||||||
if(len1 + len2 < tcplen) {
|
|
||||||
++len2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the first packet. This is done by altering the length
|
|
||||||
field of the IP header and updating the checksums. */
|
|
||||||
uip_len = len1 + UIP_TCPIP_HLEN;
|
|
||||||
#if UIP_CONF_IPV6
|
|
||||||
/* For IPv6, the IP length field does not include the IPv6 IP header
|
|
||||||
length. */
|
|
||||||
BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
|
||||||
BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
|
||||||
#else /* UIP_CONF_IPV6 */
|
|
||||||
BUF->len[0] = uip_len >> 8;
|
|
||||||
BUF->len[1] = uip_len & 0xff;
|
|
||||||
#endif /* UIP_CONF_IPV6 */
|
|
||||||
|
|
||||||
/* Recalculate the TCP checksum. */
|
|
||||||
BUF->tcpchksum = 0;
|
|
||||||
BUF->tcpchksum = ~(uip_tcpchksum());
|
|
||||||
|
|
||||||
#if !UIP_CONF_IPV6
|
|
||||||
/* Recalculate the IP checksum. */
|
|
||||||
BUF->ipchksum = 0;
|
|
||||||
BUF->ipchksum = ~(uip_ipchksum());
|
|
||||||
#endif /* UIP_CONF_IPV6 */
|
|
||||||
|
|
||||||
/* Transmit the first packet. */
|
|
||||||
/* uip_fw_output();*/
|
|
||||||
tcpip_output();
|
|
||||||
|
|
||||||
/* Now, create the second packet. To do this, it is not enough to
|
|
||||||
just alter the length field, but we must also update the TCP
|
|
||||||
sequence number and point the uip_appdata to a new place in
|
|
||||||
memory. This place is detemined by the length of the first
|
|
||||||
packet (len1). */
|
|
||||||
uip_len = len2 + UIP_TCPIP_HLEN;
|
|
||||||
#if UIP_CONF_IPV6
|
|
||||||
/* For IPv6, the IP length field does not include the IPv6 IP header
|
|
||||||
length. */
|
|
||||||
BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
|
||||||
BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
|
||||||
#else /* UIP_CONF_IPV6 */
|
|
||||||
BUF->len[0] = uip_len >> 8;
|
|
||||||
BUF->len[1] = uip_len & 0xff;
|
|
||||||
#endif /* UIP_CONF_IPV6 */
|
|
||||||
|
|
||||||
/* uip_appdata += len1;*/
|
|
||||||
memcpy(uip_appdata, (u8_t *)uip_appdata + len1, len2);
|
|
||||||
|
|
||||||
uip_add32(BUF->seqno, len1);
|
|
||||||
BUF->seqno[0] = uip_acc32[0];
|
|
||||||
BUF->seqno[1] = uip_acc32[1];
|
|
||||||
BUF->seqno[2] = uip_acc32[2];
|
|
||||||
BUF->seqno[3] = uip_acc32[3];
|
|
||||||
|
|
||||||
/* Recalculate the TCP checksum. */
|
|
||||||
BUF->tcpchksum = 0;
|
|
||||||
BUF->tcpchksum = ~(uip_tcpchksum());
|
|
||||||
|
|
||||||
#if !UIP_CONF_IPV6
|
|
||||||
/* Recalculate the IP checksum. */
|
|
||||||
BUF->ipchksum = 0;
|
|
||||||
BUF->ipchksum = ~(uip_ipchksum());
|
|
||||||
#endif /* UIP_CONF_IPV6 */
|
|
||||||
|
|
||||||
/* Transmit the second packet. */
|
|
||||||
/* uip_fw_output();*/
|
|
||||||
tcpip_output();
|
|
||||||
} else {
|
|
||||||
/* uip_fw_output();*/
|
|
||||||
tcpip_output();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
|
|
@ -1,96 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2004, 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 uIP TCP/IP stack
|
|
||||||
*
|
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
* $Id: uip-split.h,v 1.2 2006/06/12 08:00:30 adam Exp $
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* \addtogroup uip
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \defgroup uipsplit uIP TCP throughput booster hack
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* The basic uIP TCP implementation only allows each TCP connection to
|
|
||||||
* have a single TCP segment in flight at any given time. Because of
|
|
||||||
* the delayed ACK algorithm employed by most TCP receivers, uIP's
|
|
||||||
* limit on the amount of in-flight TCP segments seriously reduces the
|
|
||||||
* maximum achievable throughput for sending data from uIP.
|
|
||||||
*
|
|
||||||
* The uip-split module is a hack which tries to remedy this
|
|
||||||
* situation. By splitting maximum sized outgoing TCP segments into
|
|
||||||
* two, the delayed ACK algorithm is not invoked at TCP
|
|
||||||
* receivers. This improves the throughput when sending data from uIP
|
|
||||||
* by orders of magnitude.
|
|
||||||
*
|
|
||||||
* The uip-split module uses the uip-fw module (uIP IP packet
|
|
||||||
* forwarding) for sending packets. Therefore, the uip-fw module must
|
|
||||||
* be set up with the appropriate network interfaces for this module
|
|
||||||
* to work.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* Module for splitting outbound TCP segments in two to avoid the
|
|
||||||
* delayed ACK throughput degradation.
|
|
||||||
* \author
|
|
||||||
* Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UIP_SPLIT_H__
|
|
||||||
#define __UIP_SPLIT_H__
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle outgoing packets.
|
|
||||||
*
|
|
||||||
* This function inspects an outgoing packet in the uip_buf buffer and
|
|
||||||
* sends it out using the uip_fw_output() function. If the packet is a
|
|
||||||
* full-sized TCP segment it will be split into two segments and
|
|
||||||
* transmitted separately. This function should be called instead of
|
|
||||||
* the actual device driver output function, or the uip_fw_output()
|
|
||||||
* function.
|
|
||||||
*
|
|
||||||
* The headers of the outgoing packet is assumed to be in the uip_buf
|
|
||||||
* buffer and the payload is assumed to be wherever uip_appdata
|
|
||||||
* points. The length of the outgoing packet is assumed to be in the
|
|
||||||
* uip_len variable.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void uip_split_output(void);
|
|
||||||
|
|
||||||
#endif /* __UIP_SPLIT_H__ */
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
/** @} */
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,138 +0,0 @@
|
||||||
/**
|
|
||||||
* \addtogroup uip
|
|
||||||
* {@
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \defgroup uiparch Architecture specific uIP functions
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* The functions in the architecture specific module implement the IP
|
|
||||||
* check sum and 32-bit additions.
|
|
||||||
*
|
|
||||||
* The IP checksum calculation is the most computationally expensive
|
|
||||||
* operation in the TCP/IP stack and it therefore pays off to
|
|
||||||
* implement this in efficient assembler. The purpose of the uip-arch
|
|
||||||
* module is to let the checksum functions to be implemented in
|
|
||||||
* architecture specific assembler.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* Declarations of architecture specific functions.
|
|
||||||
* \author Adam Dunkels <adam@dunkels.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2001, Adam Dunkels.
|
|
||||||
* 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 uIP TCP/IP stack.
|
|
||||||
*
|
|
||||||
* $Id: uip_arch.h,v 1.2 2006/06/07 09:15:19 adam Exp $
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UIP_ARCH_H__
|
|
||||||
#define __UIP_ARCH_H__
|
|
||||||
|
|
||||||
#include "uip.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Carry out a 32-bit addition.
|
|
||||||
*
|
|
||||||
* Because not all architectures for which uIP is intended has native
|
|
||||||
* 32-bit arithmetic, uIP uses an external C function for doing the
|
|
||||||
* required 32-bit additions in the TCP protocol processing. This
|
|
||||||
* function should add the two arguments and place the result in the
|
|
||||||
* global variable uip_acc32.
|
|
||||||
*
|
|
||||||
* \note The 32-bit integer pointed to by the op32 parameter and the
|
|
||||||
* result in the uip_acc32 variable are in network byte order (big
|
|
||||||
* endian).
|
|
||||||
*
|
|
||||||
* \param op32 A pointer to a 4-byte array representing a 32-bit
|
|
||||||
* integer in network byte order (big endian).
|
|
||||||
*
|
|
||||||
* \param op16 A 16-bit integer in host byte order.
|
|
||||||
*/
|
|
||||||
void uip_add32(u8_t *op32, u16_t op16);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate the Internet checksum over a buffer.
|
|
||||||
*
|
|
||||||
* The Internet checksum is the one's complement of the one's
|
|
||||||
* complement sum of all 16-bit words in the buffer.
|
|
||||||
*
|
|
||||||
* See RFC1071.
|
|
||||||
*
|
|
||||||
* \note This function is not called in the current version of uIP,
|
|
||||||
* but future versions might make use of it.
|
|
||||||
*
|
|
||||||
* \param buf A pointer to the buffer over which the checksum is to be
|
|
||||||
* computed.
|
|
||||||
*
|
|
||||||
* \param len The length of the buffer over which the checksum is to
|
|
||||||
* be computed.
|
|
||||||
*
|
|
||||||
* \return The Internet checksum of the buffer.
|
|
||||||
*/
|
|
||||||
u16_t uip_chksum(u16_t *buf, u16_t len);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate the IP header checksum of the packet header in uip_buf.
|
|
||||||
*
|
|
||||||
* The IP header checksum is the Internet checksum of the 20 bytes of
|
|
||||||
* the IP header.
|
|
||||||
*
|
|
||||||
* \return The IP header checksum of the IP header in the uip_buf
|
|
||||||
* buffer.
|
|
||||||
*/
|
|
||||||
u16_t uip_ipchksum(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
|
|
||||||
*
|
|
||||||
* The TCP checksum is the Internet checksum of data contents of the
|
|
||||||
* TCP segment, and a pseudo-header as defined in RFC793.
|
|
||||||
*
|
|
||||||
* \note The uip_appdata pointer that points to the packet data may
|
|
||||||
* point anywhere in memory, so it is not possible to simply calculate
|
|
||||||
* the Internet checksum of the contents of the uip_buf buffer.
|
|
||||||
*
|
|
||||||
* \return The TCP checksum of the TCP segment in uip_buf and pointed
|
|
||||||
* to by uip_appdata.
|
|
||||||
*/
|
|
||||||
u16_t uip_tcpchksum(void);
|
|
||||||
|
|
||||||
u16_t uip_udpchksum(void);
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif /* __UIP_ARCH_H__ */
|
|
|
@ -1,423 +0,0 @@
|
||||||
/**
|
|
||||||
* \addtogroup uip
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \defgroup uiparp uIP Address Resolution Protocol
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* The Address Resolution Protocol ARP is used for mapping between IP
|
|
||||||
* addresses and link level addresses such as the Ethernet MAC
|
|
||||||
* addresses. ARP uses broadcast queries to ask for the link level
|
|
||||||
* address of a known IP address and the host which is configured with
|
|
||||||
* the IP address for which the query was meant, will respond with its
|
|
||||||
* link level address.
|
|
||||||
*
|
|
||||||
* \note This ARP implementation only supports Ethernet.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* Implementation of the ARP Address Resolution Protocol.
|
|
||||||
* \author Adam Dunkels <adam@dunkels.com>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2001-2003, Adam Dunkels.
|
|
||||||
* 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 uIP TCP/IP stack.
|
|
||||||
*
|
|
||||||
* $Id: uip_arp.c,v 1.8 2006/06/02 23:36:21 adam Exp $
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "uip_arp.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
struct arp_hdr {
|
|
||||||
struct uip_eth_hdr ethhdr;
|
|
||||||
u16_t hwtype;
|
|
||||||
u16_t protocol;
|
|
||||||
u8_t hwlen;
|
|
||||||
u8_t protolen;
|
|
||||||
u16_t opcode;
|
|
||||||
struct uip_eth_addr shwaddr;
|
|
||||||
u16_t sipaddr[2];
|
|
||||||
struct uip_eth_addr dhwaddr;
|
|
||||||
u16_t dipaddr[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ethip_hdr {
|
|
||||||
struct uip_eth_hdr ethhdr;
|
|
||||||
/* IP header. */
|
|
||||||
u8_t vhl,
|
|
||||||
tos,
|
|
||||||
len[2],
|
|
||||||
ipid[2],
|
|
||||||
ipoffset[2],
|
|
||||||
ttl,
|
|
||||||
proto;
|
|
||||||
u16_t ipchksum;
|
|
||||||
u16_t srcipaddr[2],
|
|
||||||
destipaddr[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define ARP_REQUEST 1
|
|
||||||
#define ARP_REPLY 2
|
|
||||||
|
|
||||||
#define ARP_HWTYPE_ETH 1
|
|
||||||
|
|
||||||
struct arp_entry {
|
|
||||||
u16_t ipaddr[2];
|
|
||||||
struct uip_eth_addr ethaddr;
|
|
||||||
u8_t time;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct uip_eth_addr broadcast_ethaddr =
|
|
||||||
{{0xff,0xff,0xff,0xff,0xff,0xff}};
|
|
||||||
static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff};
|
|
||||||
|
|
||||||
static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
|
|
||||||
static u16_t ipaddr[2];
|
|
||||||
static u8_t i, c;
|
|
||||||
|
|
||||||
static u8_t arptime;
|
|
||||||
static u8_t tmpage;
|
|
||||||
|
|
||||||
#define BUF ((struct arp_hdr *)&uip_buf[0])
|
|
||||||
#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* Initialize the ARP module.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
uip_arp_init(void)
|
|
||||||
{
|
|
||||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
|
||||||
memset(arp_table[i].ipaddr, 0, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* Periodic ARP processing function.
|
|
||||||
*
|
|
||||||
* This function performs periodic timer processing in the ARP module
|
|
||||||
* and should be called at regular intervals. The recommended interval
|
|
||||||
* is 10 seconds between the calls.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
uip_arp_timer(void)
|
|
||||||
{
|
|
||||||
struct arp_entry *tabptr;
|
|
||||||
|
|
||||||
++arptime;
|
|
||||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
|
||||||
tabptr = &arp_table[i];
|
|
||||||
if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
|
|
||||||
arptime - tabptr->time >= UIP_ARP_MAXAGE) {
|
|
||||||
memset(tabptr->ipaddr, 0, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
static void
|
|
||||||
uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
|
|
||||||
{
|
|
||||||
register struct arp_entry *tabptr;
|
|
||||||
/* Walk through the ARP mapping table and try to find an entry to
|
|
||||||
update. If none is found, the IP -> MAC address mapping is
|
|
||||||
inserted in the ARP table. */
|
|
||||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
|
||||||
|
|
||||||
tabptr = &arp_table[i];
|
|
||||||
/* Only check those entries that are actually in use. */
|
|
||||||
if(tabptr->ipaddr[0] != 0 &&
|
|
||||||
tabptr->ipaddr[1] != 0) {
|
|
||||||
|
|
||||||
/* Check if the source IP address of the incoming packet matches
|
|
||||||
the IP address in this ARP table entry. */
|
|
||||||
if(ipaddr[0] == tabptr->ipaddr[0] &&
|
|
||||||
ipaddr[1] == tabptr->ipaddr[1]) {
|
|
||||||
|
|
||||||
/* An old entry found, update this and return. */
|
|
||||||
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
|
|
||||||
tabptr->time = arptime;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we get here, no existing ARP table entry was found, so we
|
|
||||||
create one. */
|
|
||||||
|
|
||||||
/* First, we try to find an unused entry in the ARP table. */
|
|
||||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
|
||||||
tabptr = &arp_table[i];
|
|
||||||
if(tabptr->ipaddr[0] == 0 &&
|
|
||||||
tabptr->ipaddr[1] == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If no unused entry is found, we try to find the oldest entry and
|
|
||||||
throw it away. */
|
|
||||||
if(i == UIP_ARPTAB_SIZE) {
|
|
||||||
tmpage = 0;
|
|
||||||
c = 0;
|
|
||||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
|
||||||
tabptr = &arp_table[i];
|
|
||||||
if(arptime - tabptr->time > tmpage) {
|
|
||||||
tmpage = arptime - tabptr->time;
|
|
||||||
c = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i = c;
|
|
||||||
tabptr = &arp_table[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now, i is the ARP table entry which we will fill with the new
|
|
||||||
information. */
|
|
||||||
memcpy(tabptr->ipaddr, ipaddr, 4);
|
|
||||||
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
|
|
||||||
tabptr->time = arptime;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* ARP processing for incoming IP packets
|
|
||||||
*
|
|
||||||
* This function should be called by the device driver when an IP
|
|
||||||
* packet has been received. The function will check if the address is
|
|
||||||
* in the ARP cache, and if so the ARP cache entry will be
|
|
||||||
* refreshed. If no ARP cache entry was found, a new one is created.
|
|
||||||
*
|
|
||||||
* This function expects an IP packet with a prepended Ethernet header
|
|
||||||
* in the uip_buf[] buffer, and the length of the packet in the global
|
|
||||||
* variable uip_len.
|
|
||||||
*/
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
#if 0
|
|
||||||
void
|
|
||||||
uip_arp_ipin(void)
|
|
||||||
{
|
|
||||||
uip_len -= sizeof(struct uip_eth_hdr);
|
|
||||||
|
|
||||||
/* Only insert/update an entry if the source IP address of the
|
|
||||||
incoming IP packet comes from a host on the local network. */
|
|
||||||
if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
|
|
||||||
(uip_hostaddr[0] & uip_netmask[0])) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if((IPBUF->srcipaddr[1] & uip_netmask[1]) !=
|
|
||||||
(uip_hostaddr[1] & uip_netmask[1])) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif /* 0 */
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* ARP processing for incoming ARP packets.
|
|
||||||
*
|
|
||||||
* This function should be called by the device driver when an ARP
|
|
||||||
* packet has been received. The function will act differently
|
|
||||||
* depending on the ARP packet type: if it is a reply for a request
|
|
||||||
* that we previously sent out, the ARP cache will be filled in with
|
|
||||||
* the values from the ARP reply. If the incoming ARP packet is an ARP
|
|
||||||
* request for our IP address, an ARP reply packet is created and put
|
|
||||||
* into the uip_buf[] buffer.
|
|
||||||
*
|
|
||||||
* When the function returns, the value of the global variable uip_len
|
|
||||||
* indicates whether the device driver should send out a packet or
|
|
||||||
* not. If uip_len is zero, no packet should be sent. If uip_len is
|
|
||||||
* non-zero, it contains the length of the outbound packet that is
|
|
||||||
* present in the uip_buf[] buffer.
|
|
||||||
*
|
|
||||||
* This function expects an ARP packet with a prepended Ethernet
|
|
||||||
* header in the uip_buf[] buffer, and the length of the packet in the
|
|
||||||
* global variable uip_len.
|
|
||||||
*/
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
uip_arp_arpin(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
if(uip_len < sizeof(struct arp_hdr)) {
|
|
||||||
uip_len = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
uip_len = 0;
|
|
||||||
|
|
||||||
switch(BUF->opcode) {
|
|
||||||
case HTONS(ARP_REQUEST):
|
|
||||||
/* ARP request. If it asked for our address, we send out a
|
|
||||||
reply. */
|
|
||||||
if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
|
|
||||||
/* First, we register the one who made the request in our ARP
|
|
||||||
table, since it is likely that we will do more communication
|
|
||||||
with this host in the future. */
|
|
||||||
uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
|
|
||||||
|
|
||||||
/* The reply opcode is 2. */
|
|
||||||
BUF->opcode = HTONS(2);
|
|
||||||
|
|
||||||
memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
|
|
||||||
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
|
|
||||||
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
|
|
||||||
memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
|
|
||||||
|
|
||||||
BUF->dipaddr[0] = BUF->sipaddr[0];
|
|
||||||
BUF->dipaddr[1] = BUF->sipaddr[1];
|
|
||||||
BUF->sipaddr[0] = uip_hostaddr[0];
|
|
||||||
BUF->sipaddr[1] = uip_hostaddr[1];
|
|
||||||
|
|
||||||
BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
|
|
||||||
uip_len = sizeof(struct arp_hdr);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case HTONS(ARP_REPLY):
|
|
||||||
/* ARP reply. We insert or update the ARP table if it was meant
|
|
||||||
for us. */
|
|
||||||
if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
|
|
||||||
uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* Prepend Ethernet header to an outbound IP packet and see if we need
|
|
||||||
* to send out an ARP request.
|
|
||||||
*
|
|
||||||
* This function should be called before sending out an IP packet. The
|
|
||||||
* function checks the destination IP address of the IP packet to see
|
|
||||||
* what Ethernet MAC address that should be used as a destination MAC
|
|
||||||
* address on the Ethernet.
|
|
||||||
*
|
|
||||||
* If the destination IP address is in the local network (determined
|
|
||||||
* by logical ANDing of netmask and our IP address), the function
|
|
||||||
* checks the ARP cache to see if an entry for the destination IP
|
|
||||||
* address is found. If so, an Ethernet header is prepended and the
|
|
||||||
* function returns. If no ARP cache entry is found for the
|
|
||||||
* destination IP address, the packet in the uip_buf[] is replaced by
|
|
||||||
* an ARP request packet for the IP address. The IP packet is dropped
|
|
||||||
* and it is assumed that they higher level protocols (e.g., TCP)
|
|
||||||
* eventually will retransmit the dropped packet.
|
|
||||||
*
|
|
||||||
* If the destination IP address is not on the local network, the IP
|
|
||||||
* address of the default router is used instead.
|
|
||||||
*
|
|
||||||
* When the function returns, a packet is present in the uip_buf[]
|
|
||||||
* buffer, and the length of the packet is in the global variable
|
|
||||||
* uip_len.
|
|
||||||
*/
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
uip_arp_out(void)
|
|
||||||
{
|
|
||||||
struct arp_entry *tabptr;
|
|
||||||
|
|
||||||
/* Find the destination IP address in the ARP table and construct
|
|
||||||
the Ethernet header. If the destination IP addres isn't on the
|
|
||||||
local network, we use the default router's IP address instead.
|
|
||||||
|
|
||||||
If not ARP table entry is found, we overwrite the original IP
|
|
||||||
packet with an ARP request for the IP address. */
|
|
||||||
|
|
||||||
/* First check if destination is a local broadcast. */
|
|
||||||
if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) {
|
|
||||||
memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
|
|
||||||
} else {
|
|
||||||
/* Check if the destination address is on the local network. */
|
|
||||||
if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) {
|
|
||||||
/* Destination address was not on the local network, so we need to
|
|
||||||
use the default router's IP address instead of the destination
|
|
||||||
address when determining the MAC address. */
|
|
||||||
uip_ipaddr_copy(ipaddr, uip_draddr);
|
|
||||||
} else {
|
|
||||||
/* Else, we use the destination IP address. */
|
|
||||||
uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
|
||||||
tabptr = &arp_table[i];
|
|
||||||
if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(i == UIP_ARPTAB_SIZE) {
|
|
||||||
/* The destination address was not in our ARP table, so we
|
|
||||||
overwrite the IP packet with an ARP request. */
|
|
||||||
|
|
||||||
memset(BUF->ethhdr.dest.addr, 0xff, 6);
|
|
||||||
memset(BUF->dhwaddr.addr, 0x00, 6);
|
|
||||||
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
|
|
||||||
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
|
|
||||||
|
|
||||||
uip_ipaddr_copy(BUF->dipaddr, ipaddr);
|
|
||||||
uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);
|
|
||||||
BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
|
|
||||||
BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
|
|
||||||
BUF->protocol = HTONS(UIP_ETHTYPE_IP);
|
|
||||||
BUF->hwlen = 6;
|
|
||||||
BUF->protolen = 4;
|
|
||||||
BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
|
|
||||||
|
|
||||||
uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
|
|
||||||
|
|
||||||
uip_len = sizeof(struct arp_hdr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build an ethernet header. */
|
|
||||||
memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
|
|
||||||
}
|
|
||||||
memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
|
|
||||||
|
|
||||||
IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
|
|
||||||
|
|
||||||
uip_len += sizeof(struct uip_eth_hdr);
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
/** @} */
|
|
|
@ -1,144 +0,0 @@
|
||||||
/**
|
|
||||||
* \addtogroup uip
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \addtogroup uiparp
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* Macros and definitions for the ARP module.
|
|
||||||
* \author Adam Dunkels <adam@dunkels.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2001-2003, Adam Dunkels.
|
|
||||||
* 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 uIP TCP/IP stack.
|
|
||||||
*
|
|
||||||
* $Id: uip_arp.h,v 1.5 2006/06/11 21:46:39 adam Exp $
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UIP_ARP_H__
|
|
||||||
#define __UIP_ARP_H__
|
|
||||||
|
|
||||||
#include "uip.h"
|
|
||||||
|
|
||||||
|
|
||||||
extern struct uip_eth_addr uip_ethaddr;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Ethernet header.
|
|
||||||
*/
|
|
||||||
struct uip_eth_hdr {
|
|
||||||
struct uip_eth_addr dest;
|
|
||||||
struct uip_eth_addr src;
|
|
||||||
u16_t type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define UIP_ETHTYPE_ARP 0x0806
|
|
||||||
#define UIP_ETHTYPE_IP 0x0800
|
|
||||||
#define UIP_ETHTYPE_IP6 0x86dd
|
|
||||||
|
|
||||||
|
|
||||||
/* The uip_arp_init() function must be called before any of the other
|
|
||||||
ARP functions. */
|
|
||||||
void uip_arp_init(void);
|
|
||||||
|
|
||||||
/* The uip_arp_ipin() function should be called whenever an IP packet
|
|
||||||
arrives from the Ethernet. This function refreshes the ARP table or
|
|
||||||
inserts a new mapping if none exists. The function assumes that an
|
|
||||||
IP packet with an Ethernet header is present in the uip_buf buffer
|
|
||||||
and that the length of the packet is in the uip_len variable. */
|
|
||||||
/*void uip_arp_ipin(void);*/
|
|
||||||
#define uip_arp_ipin()
|
|
||||||
|
|
||||||
/* The uip_arp_arpin() should be called when an ARP packet is received
|
|
||||||
by the Ethernet driver. This function also assumes that the
|
|
||||||
Ethernet frame is present in the uip_buf buffer. When the
|
|
||||||
uip_arp_arpin() function returns, the contents of the uip_buf
|
|
||||||
buffer should be sent out on the Ethernet if the uip_len variable
|
|
||||||
is > 0. */
|
|
||||||
void uip_arp_arpin(void);
|
|
||||||
|
|
||||||
/* The uip_arp_out() function should be called when an IP packet
|
|
||||||
should be sent out on the Ethernet. This function creates an
|
|
||||||
Ethernet header before the IP header in the uip_buf buffer. The
|
|
||||||
Ethernet header will have the correct Ethernet MAC destination
|
|
||||||
address filled in if an ARP table entry for the destination IP
|
|
||||||
address (or the IP address of the default router) is present. If no
|
|
||||||
such table entry is found, the IP packet is overwritten with an ARP
|
|
||||||
request and we rely on TCP to retransmit the packet that was
|
|
||||||
overwritten. In any case, the uip_len variable holds the length of
|
|
||||||
the Ethernet frame that should be transmitted. */
|
|
||||||
void uip_arp_out(void);
|
|
||||||
|
|
||||||
/* The uip_arp_timer() function should be called every ten seconds. It
|
|
||||||
is responsible for flushing old entries in the ARP table. */
|
|
||||||
void uip_arp_timer(void);
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \addtogroup uipconffunc
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifiy the Ethernet MAC address.
|
|
||||||
*
|
|
||||||
* The ARP code needs to know the MAC address of the Ethernet card in
|
|
||||||
* order to be able to respond to ARP queries and to generate working
|
|
||||||
* Ethernet headers.
|
|
||||||
*
|
|
||||||
* \note This macro only specifies the Ethernet MAC address to the ARP
|
|
||||||
* code. It cannot be used to change the MAC address of the Ethernet
|
|
||||||
* card.
|
|
||||||
*
|
|
||||||
* \param eaddr A pointer to a struct uip_eth_addr containing the
|
|
||||||
* Ethernet MAC address of the Ethernet card.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define uip_setethaddr(eaddr) do {uip_ethaddr.addr[0] = eaddr.addr[0]; \
|
|
||||||
uip_ethaddr.addr[1] = eaddr.addr[1];\
|
|
||||||
uip_ethaddr.addr[2] = eaddr.addr[2];\
|
|
||||||
uip_ethaddr.addr[3] = eaddr.addr[3];\
|
|
||||||
uip_ethaddr.addr[4] = eaddr.addr[4];\
|
|
||||||
uip_ethaddr.addr[5] = eaddr.addr[5];} while(0)
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif /* __UIP_ARP_H__ */
|
|
|
@ -1,88 +0,0 @@
|
||||||
/**
|
|
||||||
* \defgroup clock Clock interface
|
|
||||||
*
|
|
||||||
* The clock interface is the interface between the \ref timer "timer library"
|
|
||||||
* and the platform specific clock functionality. The clock
|
|
||||||
* interface must be implemented for each platform that uses the \ref
|
|
||||||
* timer "timer library".
|
|
||||||
*
|
|
||||||
* The clock interface does only one this: it measures time. The clock
|
|
||||||
* interface provides a macro, CLOCK_SECOND, which corresponds to one
|
|
||||||
* second of system time.
|
|
||||||
*
|
|
||||||
* \sa \ref timer "Timer library"
|
|
||||||
*
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2004, 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 uIP TCP/IP stack
|
|
||||||
*
|
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
* $Id: clock.h,v 1.3 2006/06/11 21:46:39 adam Exp $
|
|
||||||
*/
|
|
||||||
#ifndef __CLOCK_H__
|
|
||||||
#define __CLOCK_H__
|
|
||||||
|
|
||||||
#include "clock-arch.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the clock library.
|
|
||||||
*
|
|
||||||
* This function initializes the clock library and should be called
|
|
||||||
* from the main() function of the system.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void clock_init(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current clock time.
|
|
||||||
*
|
|
||||||
* This function returns the current system clock time.
|
|
||||||
*
|
|
||||||
* \return The current clock time, measured in system ticks.
|
|
||||||
*/
|
|
||||||
clock_time_t clock_time(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A second, measured in system clock time.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#ifdef CLOCK_CONF_SECOND
|
|
||||||
#define CLOCK_SECOND CLOCK_CONF_SECOND
|
|
||||||
#else
|
|
||||||
#define CLOCK_SECOND (clock_time_t)32
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __CLOCK_H__ */
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,197 +0,0 @@
|
||||||
/**
|
|
||||||
* \addtogroup timer
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* Timer library implementation.
|
|
||||||
* \author
|
|
||||||
* Adam Dunkels <adam@sics.se>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2004, 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 uIP TCP/IP stack
|
|
||||||
*
|
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
* $Id: timer.c,v 1.2 2006/06/12 08:00:30 adam Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "uip_clock.h"
|
|
||||||
#include "uip_timer.h"
|
|
||||||
//#include "rtconfig.h"
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* Set a timer.
|
|
||||||
*
|
|
||||||
* This function is used to set a timer for a time sometime in the
|
|
||||||
* future. The function timer_expired() will evaluate to true after
|
|
||||||
* the timer has expired.
|
|
||||||
*
|
|
||||||
* \param t A pointer to the timer
|
|
||||||
* \param interval The interval before the timer expires.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
timer_set(struct timer *t, clock_time_t interval)
|
|
||||||
{
|
|
||||||
t->interval = interval;
|
|
||||||
t->start = clock_time();
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* Reset the timer with the same interval.
|
|
||||||
*
|
|
||||||
* This function resets the timer with the same interval that was
|
|
||||||
* given to the timer_set() function. The start point of the interval
|
|
||||||
* is the exact time that the timer last expired. Therefore, this
|
|
||||||
* function will cause the timer to be stable over time, unlike the
|
|
||||||
* timer_rester() function.
|
|
||||||
*
|
|
||||||
* \param t A pointer to the timer.
|
|
||||||
*
|
|
||||||
* \sa timer_restart()
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
timer_reset(struct timer *t)
|
|
||||||
{
|
|
||||||
t->start += t->interval;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* Restart the timer from the current point in time
|
|
||||||
*
|
|
||||||
* This function restarts a timer with the same interval that was
|
|
||||||
* given to the timer_set() function. The timer will start at the
|
|
||||||
* current time.
|
|
||||||
*
|
|
||||||
* \note A periodic timer will drift if this function is used to reset
|
|
||||||
* it. For preioric timers, use the timer_reset() function instead.
|
|
||||||
*
|
|
||||||
* \param t A pointer to the timer.
|
|
||||||
*
|
|
||||||
* \sa timer_reset()
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
timer_restart(struct timer *t)
|
|
||||||
{
|
|
||||||
t->start = clock_time();
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* Check if a timer has expired.
|
|
||||||
*
|
|
||||||
* This function tests if a timer has expired and returns true or
|
|
||||||
* false depending on its status.
|
|
||||||
*
|
|
||||||
* \param t A pointer to the timer
|
|
||||||
*
|
|
||||||
* \return Non-zero if the timer has expired, zero otherwise.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include "rtdef.h"
|
|
||||||
#include "uip-conf.h"
|
|
||||||
#include "uip.h"
|
|
||||||
|
|
||||||
/* eth rx/tx thread */
|
|
||||||
static struct rt_mailbox uip_mbox;
|
|
||||||
static struct rt_thread aa;
|
|
||||||
|
|
||||||
static char uip_timeout_mb_pool[4 * 4];
|
|
||||||
extern u16_t uip_len, uip_slen;
|
|
||||||
|
|
||||||
void uip_timeout_entry2(void* parameter)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
void uip_timeout_entry(void* parameter)//由于TIMEOUT函数,不参与调度
|
|
||||||
{
|
|
||||||
// struct timer periodic_timer, arp_timer;
|
|
||||||
static uint8_t cnt;
|
|
||||||
int i;
|
|
||||||
/* post message to ethernet thread */
|
|
||||||
|
|
||||||
//if ((rt_sem_take(msg,RT_WAITING_NO)) != -RT_ETIMEOUT)
|
|
||||||
//if (timer_expired(&periodic_timer)) //5s enter once
|
|
||||||
{
|
|
||||||
//timer_reset(&periodic_timer);
|
|
||||||
for (i = 0; i < UIP_CONNS; i++)
|
|
||||||
{
|
|
||||||
uip_periodic(i);
|
|
||||||
/* If the above function invocation resulted in data that
|
|
||||||
should be sent out on the network, the global variable
|
|
||||||
uip_len is set to a value > 0. */
|
|
||||||
if (uip_len > 0)
|
|
||||||
{
|
|
||||||
uip_arp_out();
|
|
||||||
TransmitPacket();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if UIP_UDP
|
|
||||||
for (i = 0; i < UIP_UDP_CONNS; i++) //
|
|
||||||
{
|
|
||||||
uip_udp_periodic(i);
|
|
||||||
/* If the above function invocation resulted in data that
|
|
||||||
should be sent out on the network, the global variable
|
|
||||||
uip_len is set to a value > 0. */
|
|
||||||
if (uip_len > 0)
|
|
||||||
{
|
|
||||||
uip_arp_out();
|
|
||||||
TransmitPacket();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* UIP_UDP */
|
|
||||||
|
|
||||||
/* Call the ARP timer function every 10 seconds. */
|
|
||||||
//if (timer_expired(&arp_timer))
|
|
||||||
if (++cnt >= 2) //t
|
|
||||||
{
|
|
||||||
//timer_reset(&arp_timer);
|
|
||||||
uip_arp_timer();
|
|
||||||
cnt = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
int
|
|
||||||
timer_expired(struct timer *t)
|
|
||||||
{//潜在隐形bug
|
|
||||||
if ((clock_time() - t->start) >= (clock_time_t)t->interval)
|
|
||||||
{
|
|
||||||
//rt_mb_send(mbox,&
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,86 +0,0 @@
|
||||||
/**
|
|
||||||
* \defgroup timer Timer library
|
|
||||||
*
|
|
||||||
* The timer library provides functions for setting, resetting and
|
|
||||||
* restarting timers, and for checking if a timer has expired. An
|
|
||||||
* application must "manually" check if its timers have expired; this
|
|
||||||
* is not done automatically.
|
|
||||||
*
|
|
||||||
* A timer is declared as a \c struct \c timer and all access to the
|
|
||||||
* timer is made by a pointer to the declared timer.
|
|
||||||
*
|
|
||||||
* \note The timer library uses the \ref clock "Clock library" to
|
|
||||||
* measure time. Intervals should be specified in the format used by
|
|
||||||
* the clock library.
|
|
||||||
*
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* Timer library header file.
|
|
||||||
* \author
|
|
||||||
* Adam Dunkels <adam@sics.se>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2004, 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 uIP TCP/IP stack
|
|
||||||
*
|
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
* $Id: timer.h,v 1.3 2006/06/11 21:46:39 adam Exp $
|
|
||||||
*/
|
|
||||||
#ifndef __TIMER_H__
|
|
||||||
#define __TIMER_H__
|
|
||||||
|
|
||||||
#include "uip_clock.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A timer.
|
|
||||||
*
|
|
||||||
* This structure is used for declaring a timer. The timer must be set
|
|
||||||
* with timer_set() before it can be used.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
struct timer {
|
|
||||||
clock_time_t start;
|
|
||||||
clock_time_t interval;
|
|
||||||
};
|
|
||||||
|
|
||||||
void timer_set(struct timer *t, clock_time_t interval);
|
|
||||||
void timer_reset(struct timer *t);
|
|
||||||
void timer_restart(struct timer *t);
|
|
||||||
int timer_expired(struct timer *t);
|
|
||||||
|
|
||||||
#endif /* __TIMER_H__ */
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,74 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2004, Adam Dunkels and the 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 uIP TCP/IP stack
|
|
||||||
*
|
|
||||||
* $Id: uiplib.c,v 1.2 2006/06/12 08:00:31 adam Exp $
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "uip.h"
|
|
||||||
#include "uiplib.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
unsigned char
|
|
||||||
uiplib_ipaddrconv(char *addrstr, unsigned char *ipaddr)
|
|
||||||
{
|
|
||||||
unsigned char tmp;
|
|
||||||
char c;
|
|
||||||
unsigned char i, j;
|
|
||||||
|
|
||||||
tmp = 0;
|
|
||||||
|
|
||||||
for(i = 0; i < 4; ++i) {
|
|
||||||
j = 0;
|
|
||||||
do {
|
|
||||||
c = *addrstr;
|
|
||||||
++j;
|
|
||||||
if(j > 4) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(c == '.' || c == 0) {
|
|
||||||
*ipaddr = tmp;
|
|
||||||
++ipaddr;
|
|
||||||
tmp = 0;
|
|
||||||
} else if(c >= '0' && c <= '9') {
|
|
||||||
tmp = (tmp * 10) + (c - '0');
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
++addrstr;
|
|
||||||
} while(c != '.' && c != 0);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
|
@ -1,71 +0,0 @@
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* Various uIP library functions.
|
|
||||||
* \author
|
|
||||||
* Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2002, Adam Dunkels.
|
|
||||||
* 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 uIP TCP/IP stack
|
|
||||||
*
|
|
||||||
* $Id: uiplib.h,v 1.1 2006/06/07 09:15:19 adam Exp $
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifndef __UIPLIB_H__
|
|
||||||
#define __UIPLIB_H__
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \addtogroup uipconvfunc
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a textual representation of an IP address to a numerical representation.
|
|
||||||
*
|
|
||||||
* This function takes a textual representation of an IP address in
|
|
||||||
* the form a.b.c.d and converts it into a 4-byte array that can be
|
|
||||||
* used by other uIP functions.
|
|
||||||
*
|
|
||||||
* \param addrstr A pointer to a string containing the IP address in
|
|
||||||
* textual form.
|
|
||||||
*
|
|
||||||
* \param addr A pointer to a 4-byte array that will be filled in with
|
|
||||||
* the numerical representation of the address.
|
|
||||||
*
|
|
||||||
* \retval 0 If the IP address could not be parsed.
|
|
||||||
* \retval Non-zero If the IP address was parsed.
|
|
||||||
*/
|
|
||||||
unsigned char uiplib_ipaddrconv(char *addrstr, unsigned char *addr);
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif /* __UIPLIB_H__ */
|
|
|
@ -1,539 +0,0 @@
|
||||||
/**
|
|
||||||
* \defgroup uipopt Configuration options for uIP
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* uIP is configured using the per-project configuration file
|
|
||||||
* uipopt.h. This file contains all compile-time options for uIP and
|
|
||||||
* should be tweaked to match each specific project. The uIP
|
|
||||||
* distribution contains a documented example "uipopt.h" that can be
|
|
||||||
* copied and modified for each project.
|
|
||||||
*
|
|
||||||
* \note Most of the configuration options in the uipopt.h should not
|
|
||||||
* be changed, but rather the per-project uip-conf.h file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* Configuration options for uIP.
|
|
||||||
* \author Adam Dunkels <adam@dunkels.com>
|
|
||||||
*
|
|
||||||
* This file is used for tweaking various configuration options for
|
|
||||||
* uIP. You should make a copy of this file into one of your project's
|
|
||||||
* directories instead of editing this example "uipopt.h" file that
|
|
||||||
* comes with the uIP distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2001-2003, Adam Dunkels.
|
|
||||||
* 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 uIP TCP/IP stack.
|
|
||||||
*
|
|
||||||
* $Id: uipopt.h,v 1.4 2006/06/12 08:00:31 adam Exp $
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UIPOPT_H__
|
|
||||||
#define __UIPOPT_H__
|
|
||||||
|
|
||||||
#ifndef UIP_LITTLE_ENDIAN
|
|
||||||
#define UIP_LITTLE_ENDIAN 3412
|
|
||||||
#endif /* UIP_LITTLE_ENDIAN */
|
|
||||||
#ifndef UIP_BIG_ENDIAN
|
|
||||||
#define UIP_BIG_ENDIAN 1234
|
|
||||||
#endif /* UIP_BIG_ENDIAN */
|
|
||||||
|
|
||||||
#include "uip-conf.h"
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \name Static configuration options
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* These configuration options can be used for setting the IP address
|
|
||||||
* settings statically, but only if UIP_FIXEDADDR is set to 1. The
|
|
||||||
* configuration options for a specific node includes IP address,
|
|
||||||
* netmask and default router as well as the Ethernet address. The
|
|
||||||
* netmask, default router and Ethernet address are appliciable only
|
|
||||||
* if uIP should be run over Ethernet.
|
|
||||||
*
|
|
||||||
* All of these should be changed to suit your project.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if uIP should use a fixed IP address or not.
|
|
||||||
*
|
|
||||||
* If uIP should use a fixed IP address, the settings are set in the
|
|
||||||
* uipopt.h file. If not, the macros uip_sethostaddr(),
|
|
||||||
* uip_setdraddr() and uip_setnetmask() should be used instead.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define UIP_FIXEDADDR 0
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ping IP address asignment.
|
|
||||||
*
|
|
||||||
* uIP uses a "ping" packets for setting its own IP address if this
|
|
||||||
* option is set. If so, uIP will start with an empty IP address and
|
|
||||||
* the destination IP address of the first incoming "ping" (ICMP echo)
|
|
||||||
* packet will be used for setting the hosts IP address.
|
|
||||||
*
|
|
||||||
* \note This works only if UIP_FIXEDADDR is 0.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#ifdef UIP_CONF_PINGADDRCONF
|
|
||||||
#define UIP_PINGADDRCONF UIP_CONF_PINGADDRCONF
|
|
||||||
#else /* UIP_CONF_PINGADDRCONF */
|
|
||||||
#define UIP_PINGADDRCONF 0
|
|
||||||
#endif /* UIP_CONF_PINGADDRCONF */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies if the uIP ARP module should be compiled with a fixed
|
|
||||||
* Ethernet MAC address or not.
|
|
||||||
*
|
|
||||||
* If this configuration option is 0, the macro uip_setethaddr() can
|
|
||||||
* be used to specify the Ethernet address at run-time.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define UIP_FIXEDETHADDR 0
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* \name IP configuration options
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* The IP TTL (time to live) of IP packets sent by uIP.
|
|
||||||
*
|
|
||||||
* This should normally not be changed.
|
|
||||||
*/
|
|
||||||
#define UIP_TTL 64
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Turn on support for IP packet reassembly.
|
|
||||||
*
|
|
||||||
* uIP supports reassembly of fragmented IP packets. This features
|
|
||||||
* requires an additonal amount of RAM to hold the reassembly buffer
|
|
||||||
* and the reassembly code size is approximately 700 bytes. The
|
|
||||||
* reassembly buffer is of the same size as the uip_buf buffer
|
|
||||||
* (configured by UIP_BUFSIZE).
|
|
||||||
*
|
|
||||||
* \note IP packet reassembly is not heavily tested.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define UIP_REASSEMBLY 0
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum time an IP fragment should wait in the reassembly
|
|
||||||
* buffer before it is dropped.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define UIP_REASS_MAXAGE 40
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* \name UDP configuration options
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggles wether UDP support should be compiled in or not.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#ifdef UIP_CONF_UDP
|
|
||||||
#define UIP_UDP UIP_CONF_UDP
|
|
||||||
#else /* UIP_CONF_UDP */
|
|
||||||
#define UIP_UDP 0
|
|
||||||
#endif /* UIP_CONF_UDP */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggles if UDP checksums should be used or not.
|
|
||||||
*
|
|
||||||
* \note Support for UDP checksums is currently not included in uIP,
|
|
||||||
* so this option has no function.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#ifdef UIP_CONF_UDP_CHECKSUMS
|
|
||||||
#define UIP_UDP_CHECKSUMS UIP_CONF_UDP_CHECKSUMS
|
|
||||||
#else
|
|
||||||
#define UIP_UDP_CHECKSUMS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum amount of concurrent UDP connections.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#ifdef UIP_CONF_UDP_CONNS
|
|
||||||
#define UIP_UDP_CONNS UIP_CONF_UDP_CONNS
|
|
||||||
#else /* UIP_CONF_UDP_CONNS */
|
|
||||||
#define UIP_UDP_CONNS 10
|
|
||||||
#endif /* UIP_CONF_UDP_CONNS */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the function that should be called when UDP datagrams arrive.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* \name TCP configuration options
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if support for opening connections from uIP should be
|
|
||||||
* compiled in.
|
|
||||||
*
|
|
||||||
* If the applications that are running on top of uIP for this project
|
|
||||||
* do not need to open outgoing TCP connections, this configration
|
|
||||||
* option can be turned off to reduce the code size of uIP.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define UIP_ACTIVE_OPEN 1
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum number of simultaneously open TCP connections.
|
|
||||||
*
|
|
||||||
* Since the TCP connections are statically allocated, turning this
|
|
||||||
* configuration knob down results in less RAM used. Each TCP
|
|
||||||
* connection requires approximatly 30 bytes of memory.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#ifndef UIP_CONF_MAX_CONNECTIONS
|
|
||||||
#define UIP_CONNS 10
|
|
||||||
#else /* UIP_CONF_MAX_CONNECTIONS */
|
|
||||||
#define UIP_CONNS UIP_CONF_MAX_CONNECTIONS
|
|
||||||
#endif /* UIP_CONF_MAX_CONNECTIONS */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum number of simultaneously listening TCP ports.
|
|
||||||
*
|
|
||||||
* Each listening TCP port requires 2 bytes of memory.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#ifndef UIP_CONF_MAX_LISTENPORTS
|
|
||||||
#define UIP_LISTENPORTS 20
|
|
||||||
#else /* UIP_CONF_MAX_LISTENPORTS */
|
|
||||||
#define UIP_LISTENPORTS UIP_CONF_MAX_LISTENPORTS
|
|
||||||
#endif /* UIP_CONF_MAX_LISTENPORTS */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if support for TCP urgent data notification should be
|
|
||||||
* compiled in.
|
|
||||||
*
|
|
||||||
* Urgent data (out-of-band data) is a rarely used TCP feature that
|
|
||||||
* very seldom would be required.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#define UIP_URGDATA 0
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The initial retransmission timeout counted in timer pulses.
|
|
||||||
*
|
|
||||||
* This should not be changed.
|
|
||||||
*/
|
|
||||||
#define UIP_RTO 3
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum number of times a segment should be retransmitted
|
|
||||||
* before the connection should be aborted.
|
|
||||||
*
|
|
||||||
* This should not be changed.
|
|
||||||
*/
|
|
||||||
#define UIP_MAXRTX 8
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum number of times a SYN segment should be retransmitted
|
|
||||||
* before a connection request should be deemed to have been
|
|
||||||
* unsuccessful.
|
|
||||||
*
|
|
||||||
* This should not need to be changed.
|
|
||||||
*/
|
|
||||||
#define UIP_MAXSYNRTX 5
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The TCP maximum segment size.
|
|
||||||
*
|
|
||||||
* This is should not be to set to more than
|
|
||||||
* UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN.
|
|
||||||
*/
|
|
||||||
#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The size of the advertised receiver's window.
|
|
||||||
*
|
|
||||||
* Should be set low (i.e., to the size of the uip_buf buffer) is the
|
|
||||||
* application is slow to process incoming data, or high (32768 bytes)
|
|
||||||
* if the application processes data quickly.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#ifndef UIP_CONF_RECEIVE_WINDOW
|
|
||||||
#define UIP_RECEIVE_WINDOW UIP_TCP_MSS
|
|
||||||
#else
|
|
||||||
#define UIP_RECEIVE_WINDOW UIP_CONF_RECEIVE_WINDOW
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* How long a connection should stay in the TIME_WAIT state.
|
|
||||||
*
|
|
||||||
* This configiration option has no real implication, and it should be
|
|
||||||
* left untouched.
|
|
||||||
*/
|
|
||||||
#define UIP_TIME_WAIT_TIMEOUT 120
|
|
||||||
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* \name ARP configuration options
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The size of the ARP table.
|
|
||||||
*
|
|
||||||
* This option should be set to a larger value if this uIP node will
|
|
||||||
* have many connections from the local network.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#ifdef UIP_CONF_ARPTAB_SIZE
|
|
||||||
#define UIP_ARPTAB_SIZE UIP_CONF_ARPTAB_SIZE
|
|
||||||
#else
|
|
||||||
#define UIP_ARPTAB_SIZE 8
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The maxium age of ARP table entries measured in 10ths of seconds.
|
|
||||||
*
|
|
||||||
* An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD
|
|
||||||
* default).
|
|
||||||
*/
|
|
||||||
#define UIP_ARP_MAXAGE 120
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \name General configuration options
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The size of the uIP packet buffer.
|
|
||||||
*
|
|
||||||
* The uIP packet buffer should not be smaller than 60 bytes, and does
|
|
||||||
* not need to be larger than 1500 bytes. Lower size results in lower
|
|
||||||
* TCP throughput, larger size results in higher TCP throughput.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#ifndef UIP_CONF_BUFFER_SIZE
|
|
||||||
#define UIP_BUFSIZE 400
|
|
||||||
#else /* UIP_CONF_BUFFER_SIZE */
|
|
||||||
#define UIP_BUFSIZE UIP_CONF_BUFFER_SIZE
|
|
||||||
#endif /* UIP_CONF_BUFFER_SIZE */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if statistics support should be compiled in.
|
|
||||||
*
|
|
||||||
* The statistics is useful for debugging and to show the user.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#ifndef UIP_CONF_STATISTICS
|
|
||||||
#define UIP_STATISTICS 0
|
|
||||||
#else /* UIP_CONF_STATISTICS */
|
|
||||||
#define UIP_STATISTICS UIP_CONF_STATISTICS
|
|
||||||
#endif /* UIP_CONF_STATISTICS */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if logging of certain events should be compiled in.
|
|
||||||
*
|
|
||||||
* This is useful mostly for debugging. The function uip_log()
|
|
||||||
* must be implemented to suit the architecture of the project, if
|
|
||||||
* logging is turned on.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#ifndef UIP_CONF_LOGGING
|
|
||||||
#define UIP_LOGGING 0
|
|
||||||
#else /* UIP_CONF_LOGGING */
|
|
||||||
#define UIP_LOGGING UIP_CONF_LOGGING
|
|
||||||
#endif /* UIP_CONF_LOGGING */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Broadcast support.
|
|
||||||
*
|
|
||||||
* This flag configures IP broadcast support. This is useful only
|
|
||||||
* together with UDP.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifndef UIP_CONF_BROADCAST
|
|
||||||
#define UIP_BROADCAST 0
|
|
||||||
#else /* UIP_CONF_BROADCAST */
|
|
||||||
#define UIP_BROADCAST UIP_CONF_BROADCAST
|
|
||||||
#endif /* UIP_CONF_BROADCAST */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print out a uIP log message.
|
|
||||||
*
|
|
||||||
* This function must be implemented by the module that uses uIP, and
|
|
||||||
* is called by uIP whenever a log message is generated.
|
|
||||||
*/
|
|
||||||
void uip_log(char *msg);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The link level header length.
|
|
||||||
*
|
|
||||||
* This is the offset into the uip_buf where the IP header can be
|
|
||||||
* found. For Ethernet, this should be set to 14. For SLIP, this
|
|
||||||
* should be set to 0.
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#ifdef UIP_CONF_LLH_LEN
|
|
||||||
#define UIP_LLH_LEN UIP_CONF_LLH_LEN
|
|
||||||
#else /* UIP_CONF_LLH_LEN */
|
|
||||||
#define UIP_LLH_LEN 14
|
|
||||||
#endif /* UIP_CONF_LLH_LEN */
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* \name CPU architecture configuration
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* The CPU architecture configuration is where the endianess of the
|
|
||||||
* CPU on which uIP is to be run is specified. Most CPUs today are
|
|
||||||
* little endian, and the most notable exception are the Motorolas
|
|
||||||
* which are big endian. The BYTE_ORDER macro should be changed to
|
|
||||||
* reflect the CPU architecture on which uIP is to be run.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The byte order of the CPU architecture on which uIP is to be run.
|
|
||||||
*
|
|
||||||
* This option can be either BIG_ENDIAN (Motorola byte order) or
|
|
||||||
* LITTLE_ENDIAN (Intel byte order).
|
|
||||||
*
|
|
||||||
* \hideinitializer
|
|
||||||
*/
|
|
||||||
#ifdef UIP_CONF_BYTE_ORDER
|
|
||||||
#define UIP_BYTE_ORDER UIP_CONF_BYTE_ORDER
|
|
||||||
#else /* UIP_CONF_BYTE_ORDER */
|
|
||||||
#define UIP_BYTE_ORDER UIP_LITTLE_ENDIAN
|
|
||||||
#endif /* UIP_CONF_BYTE_ORDER */
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \name Appication specific configurations
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* An uIP application is implemented using a single application
|
|
||||||
* function that is called by uIP whenever a TCP/IP event occurs. The
|
|
||||||
* name of this function must be registered with uIP at compile time
|
|
||||||
* using the UIP_APPCALL definition.
|
|
||||||
*
|
|
||||||
* uIP applications can store the application state within the
|
|
||||||
* uip_conn structure by specifying the type of the application
|
|
||||||
* structure by typedef:ing the type uip_tcp_appstate_t and uip_udp_appstate_t.
|
|
||||||
*
|
|
||||||
* The file containing the definitions must be included in the
|
|
||||||
* uipopt.h file.
|
|
||||||
*
|
|
||||||
* The following example illustrates how this can look.
|
|
||||||
\code
|
|
||||||
|
|
||||||
void httpd_appcall(void);
|
|
||||||
#define UIP_APPCALL httpd_appcall
|
|
||||||
|
|
||||||
struct httpd_state {
|
|
||||||
u8_t state;
|
|
||||||
u16_t count;
|
|
||||||
char *dataptr;
|
|
||||||
char *script;
|
|
||||||
};
|
|
||||||
typedef struct httpd_state uip_tcp_appstate_t
|
|
||||||
\endcode
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \var #define UIP_APPCALL
|
|
||||||
*
|
|
||||||
* The name of the application function that uIP should call in
|
|
||||||
* response to TCP/IP events.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \var typedef uip_tcp_appstate_t
|
|
||||||
*
|
|
||||||
* The type of the application state that is to be stored in the
|
|
||||||
* uip_conn structure. This usually is typedef:ed to a struct holding
|
|
||||||
* application state information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \var typedef uip_udp_appstate_t
|
|
||||||
*
|
|
||||||
* The type of the application state that is to be stored in the
|
|
||||||
* uip_conn structure. This usually is typedef:ed to a struct holding
|
|
||||||
* application state information.
|
|
||||||
*/
|
|
||||||
/** @} */
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif /* __UIPOPT_H__ */
|
|
Loading…
Reference in New Issue