Not much more than a reformatted uIP so far - this will eventually replace the FreeRTOS-uIP files.

pull/4/head
Richard Barry 15 years ago
parent 7c54dfea37
commit d60032cec3

@ -0,0 +1,486 @@
const char http_http[8] = /* "http://" */ { 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, };
const char http_200[5] = /* "200 " */ { 0x32, 0x30, 0x30, 0x20, };
const char http_301[5] = /* "301 " */ { 0x33, 0x30, 0x31, 0x20, };
const char http_302[5] = /* "302 " */ { 0x33, 0x30, 0x32, 0x20, };
const char http_get[5] = /* "GET " */ { 0x47, 0x45, 0x54, 0x20, };
const char http_10[9] = /* "HTTP/1.0" */ { 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, };
const char http_11[9] = /* "HTTP/1.1" */ { 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, };
const char http_content_type[15] =
/* "content-type: " */
{ 0x63,
0x6f,
0x6e,
0x74,
0x65,
0x6e,
0x74,
0x2d,
0x74,
0x79,
0x70,
0x65,
0x3a,
0x20,
};
const char http_texthtml[10] = /* "text/html" */ { 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, };
const char http_location[11] = /* "location: " */ { 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, };
const char http_host[7] = /* "host: " */ { 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x20, };
const char http_crnl[3] = /* "\r\n" */ { 0xd, 0xa, };
const char http_index_html[12] = /* "/index.html" */ { 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, };
const char http_404_html[10] = /* "/404.html" */ { 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, };
const char http_referer[9] = /* "Referer:" */ { 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, 0x3a, };
const char http_header_200[84] =
/* "HTTP/1.0 200 OK\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" */
{ 0x48,
0x54,
0x54,
0x50,
0x2f,
0x31,
0x2e,
0x30,
0x20,
0x32,
0x30,
0x30,
0x20,
0x4f,
0x4b,
0xd,
0xa,
0x53,
0x65,
0x72,
0x76,
0x65,
0x72,
0x3a,
0x20,
0x75,
0x49,
0x50,
0x2f,
0x31,
0x2e,
0x30,
0x20,
0x68,
0x74,
0x74,
0x70,
0x3a,
0x2f,
0x2f,
0x77,
0x77,
0x77,
0x2e,
0x73,
0x69,
0x63,
0x73,
0x2e,
0x73,
0x65,
0x2f,
0x7e,
0x61,
0x64,
0x61,
0x6d,
0x2f,
0x75,
0x69,
0x70,
0x2f,
0xd,
0xa,
0x43,
0x6f,
0x6e,
0x6e,
0x65,
0x63,
0x74,
0x69,
0x6f,
0x6e,
0x3a,
0x20,
0x63,
0x6c,
0x6f,
0x73,
0x65,
0xd,
0xa,
};
const char http_header_404[91] =
/* "HTTP/1.0 404 Not found\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" */
{ 0x48,
0x54,
0x54,
0x50,
0x2f,
0x31,
0x2e,
0x30,
0x20,
0x34,
0x30,
0x34,
0x20,
0x4e,
0x6f,
0x74,
0x20,
0x66,
0x6f,
0x75,
0x6e,
0x64,
0xd,
0xa,
0x53,
0x65,
0x72,
0x76,
0x65,
0x72,
0x3a,
0x20,
0x75,
0x49,
0x50,
0x2f,
0x31,
0x2e,
0x30,
0x20,
0x68,
0x74,
0x74,
0x70,
0x3a,
0x2f,
0x2f,
0x77,
0x77,
0x77,
0x2e,
0x73,
0x69,
0x63,
0x73,
0x2e,
0x73,
0x65,
0x2f,
0x7e,
0x61,
0x64,
0x61,
0x6d,
0x2f,
0x75,
0x69,
0x70,
0x2f,
0xd,
0xa,
0x43,
0x6f,
0x6e,
0x6e,
0x65,
0x63,
0x74,
0x69,
0x6f,
0x6e,
0x3a,
0x20,
0x63,
0x6c,
0x6f,
0x73,
0x65,
0xd,
0xa,
};
const char http_content_type_plain[29] =
/* "Content-type: text/plain\r\n\r\n" */
{ 0x43,
0x6f,
0x6e,
0x74,
0x65,
0x6e,
0x74,
0x2d,
0x74,
0x79,
0x70,
0x65,
0x3a,
0x20,
0x74,
0x65,
0x78,
0x74,
0x2f,
0x70,
0x6c,
0x61,
0x69,
0x6e,
0xd,
0xa,
0xd,
0xa,
};
const char http_content_type_html[28] =
/* "Content-type: text/html\r\n\r\n" */
{ 0x43,
0x6f,
0x6e,
0x74,
0x65,
0x6e,
0x74,
0x2d,
0x74,
0x79,
0x70,
0x65,
0x3a,
0x20,
0x74,
0x65,
0x78,
0x74,
0x2f,
0x68,
0x74,
0x6d,
0x6c,
0xd,
0xa,
0xd,
0xa,
};
const char http_content_type_css[27] =
/* "Content-type: text/css\r\n\r\n" */
{ 0x43,
0x6f,
0x6e,
0x74,
0x65,
0x6e,
0x74,
0x2d,
0x74,
0x79,
0x70,
0x65,
0x3a,
0x20,
0x74,
0x65,
0x78,
0x74,
0x2f,
0x63,
0x73,
0x73,
0xd,
0xa,
0xd,
0xa,
};
const char http_content_type_text[28] =
/* "Content-type: text/text\r\n\r\n" */
{ 0x43,
0x6f,
0x6e,
0x74,
0x65,
0x6e,
0x74,
0x2d,
0x74,
0x79,
0x70,
0x65,
0x3a,
0x20,
0x74,
0x65,
0x78,
0x74,
0x2f,
0x74,
0x65,
0x78,
0x74,
0xd,
0xa,
0xd,
0xa,
};
const char http_content_type_png[28] =
/* "Content-type: image/png\r\n\r\n" */
{ 0x43,
0x6f,
0x6e,
0x74,
0x65,
0x6e,
0x74,
0x2d,
0x74,
0x79,
0x70,
0x65,
0x3a,
0x20,
0x69,
0x6d,
0x61,
0x67,
0x65,
0x2f,
0x70,
0x6e,
0x67,
0xd,
0xa,
0xd,
0xa,
};
const char http_content_type_gif[28] =
/* "Content-type: image/gif\r\n\r\n" */
{ 0x43,
0x6f,
0x6e,
0x74,
0x65,
0x6e,
0x74,
0x2d,
0x74,
0x79,
0x70,
0x65,
0x3a,
0x20,
0x69,
0x6d,
0x61,
0x67,
0x65,
0x2f,
0x67,
0x69,
0x66,
0xd,
0xa,
0xd,
0xa,
};
const char http_content_type_jpg[29] =
/* "Content-type: image/jpeg\r\n\r\n" */
{ 0x43,
0x6f,
0x6e,
0x74,
0x65,
0x6e,
0x74,
0x2d,
0x74,
0x79,
0x70,
0x65,
0x3a,
0x20,
0x69,
0x6d,
0x61,
0x67,
0x65,
0x2f,
0x6a,
0x70,
0x65,
0x67,
0xd,
0xa,
0xd,
0xa,
};
const char http_content_type_binary[43] =
/* "Content-type: application/octet-stream\r\n\r\n" */
{ 0x43,
0x6f,
0x6e,
0x74,
0x65,
0x6e,
0x74,
0x2d,
0x74,
0x79,
0x70,
0x65,
0x3a,
0x20,
0x61,
0x70,
0x70,
0x6c,
0x69,
0x63,
0x61,
0x74,
0x69,
0x6f,
0x6e,
0x2f,
0x6f,
0x63,
0x74,
0x65,
0x74,
0x2d,
0x73,
0x74,
0x72,
0x65,
0x61,
0x6d,
0xd,
0xa,
0xd,
0xa,
};
const char http_html[6] = /* ".html" */ { 0x2e, 0x68, 0x74, 0x6d, 0x6c, };
const char http_shtml[7] = /* ".shtml" */ { 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, };
const char http_htm[5] = /* ".htm" */ { 0x2e, 0x68, 0x74, 0x6d, };
const char http_css[5] = /* ".css" */ { 0x2e, 0x63, 0x73, 0x73, };
const char http_png[5] = /* ".png" */ { 0x2e, 0x70, 0x6e, 0x67, };
const char http_gif[5] = /* ".gif" */ { 0x2e, 0x67, 0x69, 0x66, };
const char http_jpg[5] = /* ".jpg" */ { 0x2e, 0x6a, 0x70, 0x67, };
const char http_text[5] = /* ".txt" */ { 0x2e, 0x74, 0x78, 0x74, };
const char http_txt[5] = /* ".txt" */ { 0x2e, 0x74, 0x78, 0x74, };

@ -0,0 +1,169 @@
/**
* \addtogroup httpd
* @{
*/
/**
* \file
* Web server script interface
* \author
* Adam Dunkels <adam@sics.se>
*
*/
/*
* Copyright (c) 2001-2006, 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: httpd-cgi.c,v 1.2 2006/06/11 21:46:37 adam Exp $
*
*/
#include "net/uip.h"
#include "net/psock.h"
#include "httpd.h"
#include "httpd-cgi.h"
#include "httpd-fs.h"
#include <stdio.h>
#include <string.h>
HTTPD_CGI_CALL( file, "file-stats", file_stats );
HTTPD_CGI_CALL( tcp, "tcp-connections", tcp_stats );
HTTPD_CGI_CALL( net, "net-stats", net_stats );
static const struct httpd_cgi_call *calls[] = { &file, &tcp, &net, NULL };
/*---------------------------------------------------------------------------*/
static PT_THREAD( nullfunction ( struct httpd_state *s, char *ptr ) )
{
PSOCK_BEGIN( &s->sout );
PSOCK_END( &s->sout );
}
/*---------------------------------------------------------------------------*/
httpd_cgifunction httpd_cgi( char *name )
{
const struct httpd_cgi_call **f;
/* Find the matching name in the table, return the function. */
for( f = calls; *f != NULL; ++f )
{
if( strncmp((*f)->name, name, strlen((*f)->name)) == 0 )
{
return( *f )->function;
}
}
return nullfunction;
}
/*---------------------------------------------------------------------------*/
static unsigned short generate_file_stats( void *arg )
{
char *f = ( char * ) arg;
return snprintf( ( char * ) uip_appdata, UIP_APPDATA_SIZE, "%5u", httpd_fs_count(f) );
}
/*---------------------------------------------------------------------------*/
static PT_THREAD( file_stats ( struct httpd_state *s, char *ptr ) )
{
PSOCK_BEGIN( &s->sout );
PSOCK_GENERATOR_SEND( &s->sout, generate_file_stats, strchr(ptr, ' ') + 1 );
PSOCK_END( &s->sout );
}
/*---------------------------------------------------------------------------*/
static const char closed[] = /* "CLOSED",*/ { 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0 };
static const char syn_rcvd[] = /* "SYN-RCVD",*/ { 0x53, 0x59, 0x4e, 0x2d, 0x52, 0x43, 0x56, 0x44, 0 };
static const char syn_sent[] = /* "SYN-SENT",*/ { 0x53, 0x59, 0x4e, 0x2d, 0x53, 0x45, 0x4e, 0x54, 0 };
static const char established[] = /* "ESTABLISHED",*/ { 0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x45, 0x44, 0 };
static const char fin_wait_1[] = /* "FIN-WAIT-1",*/ { 0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, 0x54, 0x2d, 0x31, 0 };
static const char fin_wait_2[] = /* "FIN-WAIT-2",*/ { 0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, 0x54, 0x2d, 0x32, 0 };
static const char closing[] = /* "CLOSING",*/ { 0x43, 0x4c, 0x4f, 0x53, 0x49, 0x4e, 0x47, 0 };
static const char time_wait[] = /* "TIME-WAIT,"*/ { 0x54, 0x49, 0x4d, 0x45, 0x2d, 0x57, 0x41, 0x49, 0x54, 0 };
static const char last_ack[] = /* "LAST-ACK"*/ { 0x4c, 0x41, 0x53, 0x54, 0x2d, 0x41, 0x43, 0x4b, 0 };
static const char *states[] = { closed, syn_rcvd, syn_sent, established, fin_wait_1, fin_wait_2, closing, time_wait, last_ack };
static unsigned short generate_tcp_stats( void *arg )
{
struct uip_conn *conn;
struct httpd_state *s = ( struct httpd_state * ) arg;
conn = &uip_conns[s->count];
return snprintf( ( char * ) uip_appdata, UIP_APPDATA_SIZE,
"<tr><td>%d</td><td>%u.%u.%u.%u:%u</td><td>%s</td><td>%u</td><td>%u</td><td>%c %c</td></tr>\r\n", htons(conn->lport),
htons(conn->ripaddr[0]) >> 8, htons(conn->ripaddr[0]) & 0xff, htons(conn->ripaddr[1]) >> 8,
htons(conn->ripaddr[1]) & 0xff, htons(conn->rport), states[conn->tcpstateflags & UIP_TS_MASK], conn->nrtx, conn->timer,
(uip_outstanding(conn)) ? '*' : ' ', (uip_stopped(conn)) ? '!' : ' ' );
}
/*---------------------------------------------------------------------------*/
static PT_THREAD( tcp_stats ( struct httpd_state *s, char *ptr ) )
{
PSOCK_BEGIN( &s->sout );
for( s->count = 0; s->count < UIP_CONNS; ++s->count )
{
if( (uip_conns[s->count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED )
{
PSOCK_GENERATOR_SEND( &s->sout, generate_tcp_stats, s );
}
}
PSOCK_END( &s->sout );
}
/*---------------------------------------------------------------------------*/
static unsigned short generate_net_stats( void *arg )
{
struct httpd_state *s = ( struct httpd_state * ) arg;
return snprintf( ( char * ) uip_appdata, UIP_APPDATA_SIZE, "%5u\n", (( uip_stats_t * ) &uip_stat)[s->count] );
}
static PT_THREAD( net_stats ( struct httpd_state *s, char *ptr ) )
{
PSOCK_BEGIN( &s->sout );
#if UIP_STATISTICS
for( s->count = 0; s->count < sizeof(uip_stat) / sizeof(uip_stats_t); ++s->count )
{
PSOCK_GENERATOR_SEND( &s->sout, generate_net_stats, s );
}
#endif /* UIP_STATISTICS */
PSOCK_END( &s->sout );
}
/*---------------------------------------------------------------------------*/
/** @} */

@ -0,0 +1,133 @@
/*
* Copyright (c) 2001, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: httpd-fs.c,v 1.1 2006/06/07 09:13:08 adam Exp $
*/
#include "httpd.h"
#include "httpd-fs.h"
#include "httpd-fsdata.h"
#ifndef NULL
#define NULL 0
#endif /* NULL */
#include "httpd-fsdata.c"
#if HTTPD_FS_STATISTICS
static u16_t count[HTTPD_FS_NUMFILES];
#endif /* HTTPD_FS_STATISTICS */
/*-----------------------------------------------------------------------------------*/
static u8_t httpd_fs_strcmp( const char *str1, const char *str2 )
{
u8_t i;
i = 0;
loop:
if( str2[i] == 0 || str1[i] == '\r' || str1[i] == '\n' )
{
return 0;
}
if( str1[i] != str2[i] )
{
return 1;
}
++i;
goto loop;
}
/*-----------------------------------------------------------------------------------*/
int httpd_fs_open( const char *name, struct httpd_fs_file *file )
{
#if HTTPD_FS_STATISTICS
u16_t i = 0;
#endif /* HTTPD_FS_STATISTICS */
struct httpd_fsdata_file_noconst *f;
for( f = ( struct httpd_fsdata_file_noconst * ) HTTPD_FS_ROOT; f != NULL; f = ( struct httpd_fsdata_file_noconst * ) f->next )
{
if( httpd_fs_strcmp(name, f->name) == 0 )
{
file->data = f->data;
file->len = f->len;
#if HTTPD_FS_STATISTICS
++count[i];
#endif /* HTTPD_FS_STATISTICS */
return 1;
}
#if HTTPD_FS_STATISTICS
++i;
#endif /* HTTPD_FS_STATISTICS */
}
return 0;
}
/*-----------------------------------------------------------------------------------*/
void httpd_fs_init( void )
{
#if HTTPD_FS_STATISTICS
u16_t i;
for( i = 0; i < HTTPD_FS_NUMFILES; i++ )
{
count[i] = 0;
}
#endif /* HTTPD_FS_STATISTICS */
}
/*-----------------------------------------------------------------------------------*/
#if HTTPD_FS_STATISTICS
u16_t httpd_fs_count( char *name )
{
struct httpd_fsdata_file_noconst *f;
u16_t i;
i = 0;
for( f = ( struct httpd_fsdata_file_noconst * ) HTTPD_FS_ROOT; f != NULL; f = ( struct httpd_fsdata_file_noconst * ) f->next )
{
if( httpd_fs_strcmp(name, f->name) == 0 )
{
return count[i];
}
++i;
}
return 0;
}
#endif /* HTTPD_FS_STATISTICS */
/*-----------------------------------------------------------------------------------*/

@ -0,0 +1,57 @@
/*
* Copyright (c) 2001, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: httpd-fs.h,v 1.1 2006/06/07 09:13:08 adam Exp $
*/
#ifndef __HTTPD_FS_H__
#define __HTTPD_FS_H__
#define HTTPD_FS_STATISTICS 1
struct httpd_fs_file
{
char *data;
int len;
};
/* file must be allocated by caller and will be filled in
by the function. */
int httpd_fs_open( const char *name, struct httpd_fs_file *file );
#ifdef HTTPD_FS_STATISTICS
#if HTTPD_FS_STATISTICS == 1
u16_t httpd_fs_count( char *name );
#endif /* HTTPD_FS_STATISTICS */
#endif /* HTTPD_FS_STATISTICS */
void httpd_fs_init( void );
#endif /* __HTTPD_FS_H__ */

@ -0,0 +1,62 @@
/*
* Copyright (c) 2001, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: httpd-fsdata.h,v 1.1 2006/06/17 22:41:14 adamdunkels Exp $
*/
#ifndef __HTTPD_FSDATA_H__
#define __HTTPD_FSDATA_H__
struct httpd_fsdata_file {
const struct httpd_fsdata_file *next;
const char *name;
const char *data;
const int len;
#ifdef HTTPD_FS_STATISTICS
#if HTTPD_FS_STATISTICS == 1
u16_t count;
#endif /* HTTPD_FS_STATISTICS */
#endif /* HTTPD_FS_STATISTICS */
};
struct httpd_fsdata_file_noconst {
struct httpd_fsdata_file *next;
char *name;
char *data;
int len;
#ifdef HTTPD_FS_STATISTICS
#if HTTPD_FS_STATISTICS == 1
u16_t count;
#endif /* HTTPD_FS_STATISTICS */
#endif /* HTTPD_FS_STATISTICS */
};
#endif /* __HTTPD_FSDATA_H__ */

@ -0,0 +1,388 @@
/**
* \addtogroup apps
* @{
*/
/**
* \defgroup httpd Web server
* @{
* The uIP web server is a very simplistic implementation of an HTTP
* server. It can serve web pages and files from a read-only ROM
* filesystem, and provides a very small scripting language.
*/
/**
* \file
* Web server
* \author
* Adam Dunkels <adam@sics.se>
*/
/*
* Copyright (c) 2004, 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. 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: httpd.c,v 1.2 2006/06/11 21:46:38 adam Exp $
*/
#include "net/uip.h"
#include "net/httpd.h"
#include "net/httpd-fs.h"
#include "net/httpd-cgi.h"
#include "net/http-strings.h"
#include <string.h>
#define STATE_WAITING 0
#define STATE_OUTPUT 1
#define ISO_nl 0x0a
#define ISO_space 0x20
#define ISO_bang 0x21
#define ISO_percent 0x25
#define ISO_period 0x2e
#define ISO_slash 0x2f
#define ISO_colon 0x3a
/*---------------------------------------------------------------------------*/
static unsigned short generate_part_of_file( void *state )
{
struct httpd_state *s = ( struct httpd_state * ) state;
if( s->file.len > uip_mss() )
{
s->len = uip_mss();
}
else
{
s->len = s->file.len;
}
memcpy( uip_appdata, s->file.data, s->len );
return s->len;
}
/*---------------------------------------------------------------------------*/
static PT_THREAD( send_file ( struct httpd_state *s ) )
{
PSOCK_BEGIN( &s->sout );
do
{
PSOCK_GENERATOR_SEND( &s->sout, generate_part_of_file, s );
s->file.len -= s->len;
s->file.data += s->len;
} while( s->file.len > 0 );
PSOCK_END( &s->sout );
}
/*---------------------------------------------------------------------------*/
static PT_THREAD( send_part_of_file ( struct httpd_state *s ) )
{
PSOCK_BEGIN( &s->sout );
PSOCK_SEND( &s->sout, s->file.data, s->len );
PSOCK_END( &s->sout );
}
/*---------------------------------------------------------------------------*/
static void next_scriptstate( struct httpd_state *s )
{
char *p;
p = strchr( s->scriptptr, ISO_nl ) + 1;
s->scriptlen -= ( unsigned short ) ( p - s->scriptptr );
s->scriptptr = p;
}
/*---------------------------------------------------------------------------*/
static PT_THREAD( handle_script ( struct httpd_state *s ) )
{
char *ptr;
PT_BEGIN( &s->scriptpt );
while( s->file.len > 0 )
{
/* Check if we should start executing a script. */
if( *s->file.data == ISO_percent && *(s->file.data + 1) == ISO_bang )
{
s->scriptptr = s->file.data + 3;
s->scriptlen = s->file.len - 3;
if( *(s->scriptptr - 1) == ISO_colon )
{
httpd_fs_open( s->scriptptr + 1, &s->file );
PT_WAIT_THREAD( &s->scriptpt, send_file(s) );
}
else
{
PT_WAIT_THREAD( &s->scriptpt, httpd_cgi(s->scriptptr) (s, s->scriptptr) );
}
next_scriptstate( s );
/* The script is over, so we reset the pointers and continue
sending the rest of the file. */
s->file.data = s->scriptptr;
s->file.len = s->scriptlen;
}
else
{
/* See if we find the start of script marker in the block of HTML
to be sent. */
if( s->file.len > uip_mss() )
{
s->len = uip_mss();
}
else
{
s->len = s->file.len;
}
if( *s->file.data == ISO_percent )
{
ptr = strchr( s->file.data + 1, ISO_percent );
}
else
{
ptr = strchr( s->file.data, ISO_percent );
}
if( ptr != NULL && ptr != s->file.data )
{
s->len = ( int ) ( ptr - s->file.data );
if( s->len >= uip_mss() )
{
s->len = uip_mss();
}
}
PT_WAIT_THREAD( &s->scriptpt, send_part_of_file(s) );
s->file.data += s->len;
s->file.len -= s->len;
}
}
PT_END( &s->scriptpt );
}
/*---------------------------------------------------------------------------*/
static PT_THREAD( send_headers ( struct httpd_state *s, const char *statushdr ) )
{
char *ptr;
PSOCK_BEGIN( &s->sout );
PSOCK_SEND_STR( &s->sout, statushdr );
ptr = strrchr( s->filename, ISO_period );
if( ptr == NULL )
{
PSOCK_SEND_STR( &s->sout, http_content_type_binary );
}
else if( strncmp(http_html, ptr, 5) == 0 || strncmp(http_shtml, ptr, 6) == 0 )
{
PSOCK_SEND_STR( &s->sout, http_content_type_html );
}
else if( strncmp(http_css, ptr, 4) == 0 )
{
PSOCK_SEND_STR( &s->sout, http_content_type_css );
}
else if( strncmp(http_png, ptr, 4) == 0 )
{
PSOCK_SEND_STR( &s->sout, http_content_type_png );
}
else if( strncmp(http_gif, ptr, 4) == 0 )
{
PSOCK_SEND_STR( &s->sout, http_content_type_gif );
}
else if( strncmp(http_jpg, ptr, 4) == 0 )
{
PSOCK_SEND_STR( &s->sout, http_content_type_jpg );
}
else
{
PSOCK_SEND_STR( &s->sout, http_content_type_plain );
}
PSOCK_END( &s->sout );
}
/*---------------------------------------------------------------------------*/
static PT_THREAD( handle_output ( struct httpd_state *s ) )
{
char *ptr;
PT_BEGIN( &s->outputpt );
if( !httpd_fs_open(s->filename, &s->file) )
{
httpd_fs_open( http_404_html, &s->file );
strcpy( s->filename, http_404_html );
PT_WAIT_THREAD( &s->outputpt, send_headers(s, http_header_404) );
PT_WAIT_THREAD( &s->outputpt, send_file(s) );
}
else
{
PT_WAIT_THREAD( &s->outputpt, send_headers(s, http_header_200) );
ptr = strchr( s->filename, ISO_period );
if( ptr != NULL && strncmp(ptr, http_shtml, 6) == 0 )
{
PT_INIT( &s->scriptpt );
PT_WAIT_THREAD( &s->outputpt, handle_script(s) );
}
else
{
PT_WAIT_THREAD( &s->outputpt, send_file(s) );
}
}
PSOCK_CLOSE( &s->sout );
PT_END( &s->outputpt );
}
/*---------------------------------------------------------------------------*/
static PT_THREAD( handle_input ( struct httpd_state *s ) )
{
PSOCK_BEGIN( &s->sin );
PSOCK_READTO( &s->sin, ISO_space );
if( strncmp(s->inputbuf, http_get, 4) != 0 )
{
PSOCK_CLOSE_EXIT( &s->sin );
}
PSOCK_READTO( &s->sin, ISO_space );
if( s->inputbuf[0] != ISO_slash )
{
PSOCK_CLOSE_EXIT( &s->sin );
}
if( s->inputbuf[1] == ISO_space )
{
strncpy( s->filename, http_index_html, sizeof(s->filename) );
}
else
{
s->inputbuf[PSOCK_DATALEN( &s->sin ) - 1] = 0;
strncpy( s->filename, &s->inputbuf[0], sizeof(s->filename) );
}
/* httpd_log_file(uip_conn->ripaddr, s->filename);*/
s->state = STATE_OUTPUT;
while( 1 )
{
PSOCK_READTO( &s->sin, ISO_nl );
if( strncmp(s->inputbuf, http_referer, 8) == 0 )
{
s->inputbuf[PSOCK_DATALEN( &s->sin ) - 2] = 0;
/* httpd_log(&s->inputbuf[9]);*/
}
}
PSOCK_END( &s->sin );
}
/*---------------------------------------------------------------------------*/
static void handle_connection( struct httpd_state *s )
{
handle_input( s );
if( s->state == STATE_OUTPUT )
{
handle_output( s );
}
}
/*---------------------------------------------------------------------------*/
void httpd_appcall( void )
{
struct httpd_state *s = ( struct httpd_state * ) &( uip_conn->appstate );
if( uip_closed() || uip_aborted() || uip_timedout() )
{
}
else if( uip_connected() )
{
PSOCK_INIT( &s->sin, s->inputbuf, sizeof(s->inputbuf) - 1 );
PSOCK_INIT( &s->sout, s->inputbuf, sizeof(s->inputbuf) - 1 );
PT_INIT( &s->outputpt );
s->state = STATE_WAITING;
/* timer_set(&s->timer, CLOCK_SECOND * 100);*/
s->timer = 0;
handle_connection( s );
}
else if( s != NULL )
{
if( uip_poll() )
{
++s->timer;
if( s->timer >= 20 )
{
uip_abort();
}
}
else
{
s->timer = 0;
}
handle_connection( s );
}
else
{
uip_abort();
}
}
/*---------------------------------------------------------------------------*/
/**
* \brief Initialize the web server
*
* This function initializes the web server and should be
* called at system boot-up.
*/
void httpd_init( void )
{
uip_listen( HTONS(80) );
}
/*---------------------------------------------------------------------------*/
/** @} */

@ -0,0 +1,61 @@
/*
* Copyright (c) 2001-2005, 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: httpd.h,v 1.2 2006/06/11 21:46:38 adam Exp $
*
*/
#ifndef __HTTPD_H__
#define __HTTPD_H__
#include "net/psock.h"
#include "httpd-fs.h"
struct httpd_state
{
unsigned char timer;
struct psock sin, sout;
struct pt outputpt, scriptpt;
char inputbuf[50];
char filename[20];
char state;
struct httpd_fs_file file;
int len;
char *scriptptr;
int scriptlen;
unsigned short count;
};
void httpd_init( void );
void httpd_appcall( void );
void httpd_log( char *msg );
void httpd_log_file( u16_t *requester, char *file );
#endif /* __HTTPD_H__ */

@ -0,0 +1,78 @@
#!/usr/bin/perl
open(OUTPUT, "> httpd-fsdata.c");
chdir("httpd-fs");
opendir(DIR, ".");
@files = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR);
closedir(DIR);
foreach $file (@files) {
if(-d $file && $file !~ /^\./) {
print "Processing directory $file\n";
opendir(DIR, $file);
@newfiles = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR);
closedir(DIR);
printf "Adding files @newfiles\n";
@files = (@files, map { $_ = "$file/$_" } @newfiles);
next;
}
}
foreach $file (@files) {
if(-f $file) {
print "Adding file $file\n";
open(FILE, $file) || die "Could not open file $file\n";
$file =~ s-^-/-;
$fvar = $file;
$fvar =~ s-/-_-g;
$fvar =~ s-\.-_-g;
# for AVR, add PROGMEM here
print(OUTPUT "static const unsigned char data".$fvar."[] = {\n");
print(OUTPUT "\t/* $file */\n\t");
for($j = 0; $j < length($file); $j++) {
printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1)));
}
printf(OUTPUT "0,\n");
$i = 0;
while(read(FILE, $data, 1)) {
if($i == 0) {
print(OUTPUT "\t");
}
printf(OUTPUT "%#02x, ", unpack("C", $data));
$i++;
if($i == 10) {
print(OUTPUT "\n");
$i = 0;
}
}
print(OUTPUT "0};\n\n");
close(FILE);
push(@fvars, $fvar);
push(@pfiles, $file);
}
}
for($i = 0; $i < @fvars; $i++) {
$file = $pfiles[$i];
$fvar = $fvars[$i];
if($i == 0) {
$prevfile = "NULL";
} else {
$prevfile = "file" . $fvars[$i - 1];
}
print(OUTPUT "const struct httpd_fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, ");
print(OUTPUT "data$fvar + ". (length($file) + 1) .", ");
print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n");
}
print(OUTPUT "#define HTTPD_FS_ROOT file$fvars[$i - 1]\n\n");
print(OUTPUT "#define HTTPD_FS_NUMFILES $i\n");

@ -0,0 +1,131 @@
/*
* 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 Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: memb.h,v 1.6 2009/04/06 21:18:04 adamdunkels Exp $
*/
/**
* \addtogroup mem
* @{
*/
/**
* \defgroup memb Memory block management functions
*
* The memory block allocation routines provide a simple yet powerful
* set of functions for managing a set of memory blocks of fixed
* size. A set of memory blocks is statically declared with the
* MEMB() macro. Memory blocks are allocated from the declared
* memory by the memb_alloc() function, and are deallocated with the
* memb_free() function.
*
* @{
*/
/**
* \file
* Memory block allocation routines.
* \author
* Adam Dunkels <adam@sics.se>
*
*/
#ifndef __MEMB_H__
#define __MEMB_H__
#include "sys/cc.h"
/**
* Declare a memory block.
*
* This macro is used to statically declare a block of memory that can
* be used by the block allocation functions. The macro statically
* declares a C array with a size that matches the specified number of
* blocks and their individual sizes.
*
* Example:
\code
MEMB(connections, struct connection, 16);
\endcode
*
* \param name The name of the memory block (later used with
* memb_init(), memb_alloc() and memb_free()).
*
* \param structure The name of the struct that the memory block holds
*
* \param num The total number of memory chunks in the block.
*
*/
#define MEMB( name, structure, num ) \
static char CC_CONCAT( name, _memb_count )[num]; \
static structure CC_CONCAT( name, _memb_mem )[num]; \
static struct memb name = \
{ \
sizeof( structure ), num, CC_CONCAT( name, _memb_count ), ( void * ) CC_CONCAT( name, _memb_mem ) \
}
struct memb
{ unsigned short size; unsigned short num; char *count; void *mem; };
/**
* Initialize a memory block that was declared with MEMB().
*
* \param m A memory block previously declared with MEMB().
*/
void memb_init( struct memb *m );
/**
* Allocate a memory block from a block of memory declared with MEMB().
*
* \param m A memory block previously declared with MEMB().
*/
void *memb_alloc( struct memb *m );
/**
* Deallocate a memory block from a memory block previously declared
* with MEMB().
*
* \param m m A memory block previously declared with MEMB().
*
* \param ptr A pointer to the memory block that is to be deallocated.
*
* \return The new reference count for the memory block (should be 0
* if successfully deallocated) or -1 if the pointer "ptr" did not
* point to a legal memory block.
*/
char memb_free( struct memb *m, void *ptr );
int memb_inmemb( struct memb *m, void *ptr );
/** @} */
/** @} */
#endif /* __MEMB_H__ */

@ -0,0 +1,42 @@
/*
* 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: clock-arch.h,v 1.2 2006/06/12 08:00:31 adam Exp $
*/
#ifndef __CLOCK_ARCH_H__
#define __CLOCK_ARCH_H__
#include "FreeRTOS.h"
typedef unsigned long clock_time_t;
#define CLOCK_CONF_SECOND configTICK_RATE_HZ
#endif /* __CLOCK_ARCH_H__ */

@ -0,0 +1,76 @@
/*
* 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_SWTICH_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__ */
/** @} */

@ -0,0 +1,131 @@
/*
* 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__ */
/** @} */
/** @} */

@ -0,0 +1,7 @@
#ifdef __GNUC__
__attribute__( (packed) );
#endif
#ifdef __RENESAS__
;
#pragma unpack
#endif

@ -0,0 +1,8 @@
#ifdef __GNUC__
/* Nothing to do here. */
;
#endif
#ifdef __RENESAS__
#pragma pack 1
#endif

@ -0,0 +1,380 @@
/*
* 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__ */
/** @} */

@ -0,0 +1,323 @@
/*
* 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__ */
/** @} */

File diff suppressed because it is too large Load Diff

@ -0,0 +1,149 @@
/**
* \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.2 2006/08/26 23:58:45 oliverschmidt Exp $
*
*/
#ifndef __UIP_ARP_H__
#define __UIP_ARP_H__
#include "net/uip.h"
CCIF extern struct uip_eth_addr uip_ethaddr;
/**
* The Ethernet header.
*/
#include "net/pack_struct_start.h"
struct uip_eth_hdr
{
struct uip_eth_addr dest;
struct uip_eth_addr src;
u16_t type;
}
#include "net/pack_struct_end.h"
#define UIP_ETHTYPE_ARP 0x0806
#define UIP_ETHTYPE_IP 0x0800
#define UIP_ETHTYPE_IPV6 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__ */
/** @} */

@ -0,0 +1,695 @@
/**
* \addtogroup uip
* @{
*/
/**
* \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 Contiki does not use the uipopt.h file to configure uIP, but
* uses a per-port uip-conf.h file that should be edited instead.
*/
/**
* \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.11 2009/04/10 00:37:48 adamdunkels 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"
//_RB_#include "contiki-conf.h"
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptstaticconf 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 applicable only
* if uIP should be run over Ethernet.
*
* This options are meaningful only for the IPv4 code.
*
* 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
*/
#ifdef UIP_CONF_FIXEDADDR
#define UIP_FIXED_ADDR UIP_CONF_FIXEDADDR
#define UIP_FIXEDADDR 1
#endif
/**
* Ping IP address assignment.
*
* 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
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptip 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
/**
* The maximum time an IP fragment should wait in the reassembly
* buffer before it is dropped.
*
*/
#define UIP_REASS_MAXAGE 60 /*60s*/
/**
* Turn on support for IP packet reassembly.
*
* uIP supports reassembly of fragmented IP packets. This features
* requires an additional 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
*/
#ifdef UIP_CONF_REASSEMBLY
#define UIP_REASSEMBLY UIP_CONF_REASSEMBLY
#else /* UIP_CONF_REASSEMBLY */
#define UIP_REASSEMBLY 0
#endif /* UIP_CONF_REASSEMBLY */
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptipv6 IPv6 configuration options
* @{
*
*/
/** The maximum transmission unit at the IP Layer*/
#define UIP_LINK_MTU 1280
#ifndef UIP_CONF_IPV6
/** Do we use IPv6 or not (default: no) */
#define UIP_CONF_IPV6 0
#endif
#ifndef UIP_CONF_IPV6_QUEUE_PKT
/** Do we do per %neighbor queuing during address resolution (default: no) */
#define UIP_CONF_IPV6_QUEUE_PKT 0
#endif
#ifndef UIP_CONF_IPV6_CHECKS
/** Do we do IPv6 consistency checks (highly recommended, default: yes) */
#define UIP_CONF_IPV6_CHECKS 1
#endif
#ifndef UIP_CONF_IPV6_REASSEMBLY
/** Do we do IPv6 fragmentation (default: no) */
#define UIP_CONF_IPV6_REASSEMBLY 0
#endif
#ifndef UIP_CONF_NETIF_MAX_ADDRESSES
/** Default number of IPv6 addresses associated to the node's interface */
#define UIP_CONF_NETIF_MAX_ADDRESSES 3
#endif
#ifndef UIP_CONF_ND6_MAX_PREFIXES
/** Default number of IPv6 prefixes associated to the node's interface */
#define UIP_CONF_ND6_MAX_PREFIXES 3
#endif
#ifndef UIP_CONF_ND6_MAX_NEIGHBORS
/** Default number of neighbors that can be stored in the %neighbor cache */
#define UIP_CONF_ND6_MAX_NEIGHBORS 4
#endif
#ifndef UIP_CONF_ND6_MAX_DEFROUTERS
/** Minimum number of default routers */
#define UIP_CONF_ND6_MAX_DEFROUTERS 2
#endif
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptudp UDP configuration options
* @{
*
* \note The UDP support in uIP is still not entirely complete; there
* is no support for sending or receiving broadcast or multicast
* packets, but it works well enough to support a number of vital
* applications such as DNS queries, though
*/
/**
* Toggles whether 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
*/
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipopttcp TCP configuration options
* @{
*/
/**
* Toggles whether UDP support should be compiled in or not.
*
* \hideinitializer
*/
#ifdef UIP_CONF_TCP
#define UIP_TCP UIP_CONF_TCP
#else /* UIP_CONF_UDP */
#define UIP_TCP 1
#endif /* UIP_CONF_UDP */
/**
* 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 configuration
* option can be turned off to reduce the code size of uIP.
*
* \hideinitializer
*/
#ifndef UIP_CONF_ACTIVE_OPEN
#define UIP_ACTIVE_OPEN 1
#else /* UIP_CONF_ACTIVE_OPEN */
#define UIP_ACTIVE_OPEN UIP_CONF_ACTIVE_OPEN
#endif /* UIP_CONF_ACTIVE_OPEN */
/**
* 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 approximately 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.
*/
#ifdef UIP_CONF_TCP_MSS
#define UIP_TCP_MSS UIP_CONF_TCP_MSS
#else
#define UIP_TCP_MSS ( UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN )
#endif
/**
* The size of the advertised receiver's window.
*
* Should be set low (i.e., to the size of the uip_buf buffer) if 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 configuration option has no real implication, and it should be
* left untouched.
*/
#define UIP_TIME_WAIT_TIMEOUT 120
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptarp 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 maximum 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
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptmac layer 2 options (for ipv6)
* @{
*/
#define UIP_DEFAULT_PREFIX_LEN 64
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptsics 6lowpan options (for ipv6)
* @{
*/
/**
* Timeout for packet reassembly at the 6lowpan layer
* (should be < 60s)
*/
#ifdef SICSLOWPAN_CONF_MAXAGE
#define SICSLOWPAN_REASS_MAXAGE SICSLOWPAN_CONF_MAXAGE
#else
#define SICSLOWPAN_REASS_MAXAGE 20
#endif
/**
* Do we compress the IP header or not (default: no)
*/
#ifndef SICSLOWPAN_CONF_COMPRESSION
#define SICSLOWPAN_CONF_COMPRESSION 0
#endif
/**
* If we use IPHC compression, how many address contexts do we support
*/
#ifndef SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS
#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1
#endif
/**
* Do we support 6lowpan fragmentation
*/
#ifndef SICSLOWPAN_CONF_FRAG
#define SICSLOWPAN_CONF_FRAG 0
#endif
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptgeneral 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 1514 bytes. Lower size results in lower
* TCP throughput, larger size results in higher TCP throughput.
*
* \hideinitializer
*/
#ifndef UIP_CONF_BUFFER_SIZE
#define UIP_BUFSIZE UIP_LINK_MTU + UIP_LLH_LEN
#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.
*
* \note we probably won't use this constant for other link layers than
* ethernet as they have variable header length (this is due to variable
* number and type of address fields and to optional security features)
* E.g.: 802.15.4 -> 2 + (1/2*4/8) + 0/5/6/10/14
* 802.11 -> 4 + (6*3/4) + 2
* \hideinitializer
*/
#ifdef UIP_CONF_LLH_LEN
#define UIP_LLH_LEN UIP_CONF_LLH_LEN
#else /* UIP_LLH_LEN */
#define UIP_LLH_LEN 14
#endif /* UIP_CONF_LLH_LEN */
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptcpu 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 UIP_BIG_ENDIAN (Motorola byte order) or
* UIP_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 */
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptapp Application 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__ */
/** @} */
/** @} */

@ -0,0 +1,338 @@
/*
* 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 "net/uipopt.h"
#include "net/psock.h"
#include "net/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)
{
( void ) len;
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 = (unsigned char*)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 = 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, (unsigned char*)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, (unsigned char * ) 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_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, (unsigned char*) buffer, buffersize);
PT_INIT(&psock->pt);
PT_INIT(&psock->psockpt);
}
/*---------------------------------------------------------------------------*/

@ -0,0 +1,115 @@
/** \addtogroup sys
* @{
*/
/**
* \defgroup clock Clock library
*
* The clock library is the interface between Contiki and the platform
* specific clock functionality. The clock library performs a single
* function: measuring time. Additionally, the clock library provides
* a macro, CLOCK_SECOND, which corresponds to one second of system
* time.
*
* \note The clock library need in many cases not be used
* directly. Rather, the \ref timer "timer library" or the \ref etimer
* "event timers" should be used.
*
* \sa \ref timer "Timer library"
* \sa \ref etimer "Event timers"
*
* @{
*/
/*
* 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 Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: clock.h,v 1.11 2009/01/24 15:20:11 adamdunkels Exp $
*/
#ifndef __CLOCK_H__
#define __CLOCK_H__
#include "net/clock-arch.h"
//_RB_#include "contiki-conf.h"
#if 0 /* XXX problems with signedness and use in timer_expired(). #if:ed it out for now. */
/**
* Check if a clock time value is less than another clock time value.
*
* This macro checks if a clock time value is less than another clock
* time value. This macro is needed to correctly handle wrap-around of
* clock time values.
*
*/
#define CLOCK_LT( a, b ) ( (clock_time_t) ((a) - (b)) < ((clock_time_t) (~((clock_time_t) 0)) >> 1) )
#endif /* 0 */
/**
* 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.
*/
CCIF clock_time_t clock_time( void );
void clock_delay( unsigned int );
/**
* 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
int clock_fine_max( void );
unsigned short clock_fine( void );
CCIF unsigned long clock_seconds( void );
#endif /* __CLOCK_H__ */
/** @} */
/** @} */

@ -0,0 +1,335 @@
/*
* 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 Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: pt.h,v 1.3 2008/10/14 12:46:39 nvt-se Exp $
*/
/**
* \addtogroup pt
* @{
*/
/**
* \file
* Protothreads implementation.
* \author
* Adam Dunkels <adam@sics.se>
*
*/
#ifndef __PT_H__
#define __PT_H__
#include "sys/lc.h"
struct pt
{
lc_t lc;
};
#define PT_WAITING 0
#define PT_YIELDED 1
#define PT_EXITED 2
#define PT_ENDED 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 schedules 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_EXITED )
/** @} */
/**
* \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__ */
/** @} */

@ -0,0 +1,101 @@
/** \addtogroup sys
* @{ */
/**
* \defgroup timer Timer library
*
* The Contiki kernel does not provide support for timed
* events. Rather, an application that wants to use timers needs to
* explicitly use the 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 is not able to post events when a timer
* expires. The \ref etimer "Event timers" should be used for this
* purpose.
*
* \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.
*
* \sa \ref etimer "Event timers"
*
* @{
*/
/**
* \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 Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: timer.h,v 1.2 2008/09/21 08:58:05 adamdunkels Exp $
*/
#ifndef __TIMER_H__
#define __TIMER_H__
#include "sys/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 );
clock_time_t timer_remaining( struct timer *t );
#endif /* __TIMER_H__ */
/** @} */
/** @} */

@ -0,0 +1,151 @@
/**
* \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 Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: timer.c,v 1.5 2009/01/24 15:20:11 adamdunkels Exp $
*/
//_RB_#include "contiki-conf.h"
#include "uip-conf.h"
#include "net/clock-arch.h"
#include "sys/clock.h"
#include "sys/timer.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_restart() 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.
*
*/
int timer_expired( struct timer *t )
{
return( clock_time_t ) ( clock_time() - t->start ) >= ( clock_time_t ) t->interval;
}
/*---------------------------------------------------------------------------*/
/**
* The time until the timer expires
*
* This function returns the time until the timer expires.
*
* \param t A pointer to the timer
*
* \return The time until the timer expires
*
*/
clock_time_t timer_remaining( struct timer *t )
{
return t->start + t->interval - clock_time();
}
/*---------------------------------------------------------------------------*/
/** @} */

File diff suppressed because it is too large Load Diff

@ -0,0 +1,472 @@
/**
* \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.5 2008/02/07 01:35:00 adamdunkels Exp $
*
*/
#include "net/uip_arp.h"
#include <string.h>
#include "net/pack_struct_start.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;
uip_ipaddr_t sipaddr;
struct uip_eth_addr dhwaddr;
uip_ipaddr_t dipaddr;
}
#include "net/pack_struct_end.h"
#include "net/pack_struct_start.h"
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;
uip_ipaddr_t srcipaddr, destipaddr;
}
#include "net/pack_struct_end.h"
#define ARP_REQUEST 1
#define ARP_REPLY 2
#define ARP_HWTYPE_ETH 1
struct arp_entry
{
uip_ipaddr_t ipaddr;
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 uip_ipaddr_t ipaddr;
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] )
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF( ... ) printf( __VA_ARGS__ )
#else
//#define PRINTF( ... )
#endif
/*-----------------------------------------------------------------------------------*/
/**
* 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( uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr) && arptime - tabptr->time >= UIP_ARP_MAXAGE )
{
memset( &tabptr->ipaddr, 0, 4 );
}
}
}
/*-----------------------------------------------------------------------------------*/
static void uip_arp_update( uip_ipaddr_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( !uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr) )
{
/* Check if the source IP address of the incoming packet matches
the IP address in this ARP table entry. */
if( uip_ipaddr_cmp(ipaddr, &tabptr->ipaddr) )
{
/* 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( uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr) )
{
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. */
uip_ipaddr_copy( &tabptr->ipaddr, ipaddr );
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(BUF->dipaddr[0] == uip_hostaddr[0] &&
BUF->dipaddr[1] == uip_hostaddr[1]) {*/
//PRINTF( "uip_arp_arpin: request for %d.%d.%d.%d (we are %d.%d.%d.%d)\n", BUF->dipaddr.u8[0], BUF->dipaddr.u8[1], BUF->dipaddr.u8[2],
//BUF->dipaddr.u8[3], uip_hostaddr.u8[0], uip_hostaddr.u8[1], uip_hostaddr.u8[2], uip_hostaddr.u8[3] );
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 );
BUF->opcode = HTONS( ARP_REPLY );
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 );
uip_ipaddr_copy( &BUF->dipaddr, &BUF->sipaddr );
uip_ipaddr_copy( &BUF->sipaddr, &uip_hostaddr );
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, &uip_broadcast_addr) )
{
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 );
}
/*-----------------------------------------------------------------------------------*/
/** @} */
/** @} */
Loading…
Cancel
Save