forked from mfulz_github/qmk_firmware
		
	Replace the Webserver demo's uIP with the latest code ripped from the Contiki project by Adam Dunkels.
This commit is contained in:
		
							parent
							
								
									1008260985
								
							
						
					
					
						commit
						84e1241f80
					
				
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -127,6 +127,115 @@ | |||||||
|  *   <td bgcolor="#00EE00">Yes</td> |  *   <td bgcolor="#00EE00">Yes</td> | ||||||
|  *  </tr> |  *  </tr> | ||||||
|  *  </table> |  *  </table> | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  *  \section Sec_UsingClassDrivers Using the Class Drivers | ||||||
|  |  *  To make the Class drivers easy to integrate into a user application, they all implement a standardized | ||||||
|  |  *  design with similarly named/used function, enums, defines and types. The two different modes are implemented | ||||||
|  |  *  slightly differently, and thus will be explained separately. For information on a specific class driver, read | ||||||
|  |  *  the class driver's module documentation. | ||||||
|  |  * | ||||||
|  |  *  \subsection SSec_ClassDriverDevice Device Mode Class Drivers | ||||||
|  |  *  Implementing a Device Mode Class Driver in a user application requires a number of steps to be followed. Firstly, | ||||||
|  |  *  the module configuration and state structure must be added to the project source. These structures are named in a  | ||||||
|  |  *  similar manner between classes, that of <i>USB_ClassInfo_<b>{Class Name}</b>_Device_t</i>, and are used to hold the | ||||||
|  |  *  complete state and configuration for each class instance. Multiple class instances is where the power of the class  | ||||||
|  |  *  drivers lie; multiple interfaces of the same class simply require more instances of the Class Driver's ClassInfo  | ||||||
|  |  *  structure. | ||||||
|  |  * | ||||||
|  |  *  Inside the ClassInfo structure lies two sections, a <i>Config</i> section, and a <i>State</i> section. The Config | ||||||
|  |  *  section contains the instance's configuration parameters, and <b>must have all fields set by the user application</b> | ||||||
|  |  *  before the class driver is used. Each Device mode Class driver typically contains a set of configuration parameters | ||||||
|  |  *  for the endpoint size/number of the associated logical USB interface, plus any class-specific configuration parameters. | ||||||
|  |  * | ||||||
|  |  *  The <i>State</i> section of the ClassInfo structures are designed to be controlled by the Class Drivers only for | ||||||
|  |  *  maintaining the Class Driver instance's state, and should not normally be set by the user application. | ||||||
|  |  * | ||||||
|  |  *  The following is an example of a properly initialized instance of the Audio Class Driver structure: | ||||||
|  |  * | ||||||
|  |  *  \code | ||||||
|  |  *  USB_ClassInfo_Audio_Device_t My_Audio_Interface = | ||||||
|  |  *  { | ||||||
|  |  *      .Config = | ||||||
|  |  *          { | ||||||
|  |  *              .StreamingInterfaceNumber = 1, | ||||||
|  |  *               | ||||||
|  |  *              .DataINEndpointNumber     = 1, | ||||||
|  |  *              .DataINEndpointSize       = 256, | ||||||
|  |  *          }, | ||||||
|  |  *  }; | ||||||
|  |  *  \endcode | ||||||
|  |  * | ||||||
|  |  *  \note The class driver's configuration parameters should match those used in the device's descriptors that are | ||||||
|  |  *  sent to the host. | ||||||
|  |  * | ||||||
|  |  *  To initialize the Class driver instance, the driver's <i><b>{Class Name}</b>_Device_ConfigureEndpoints()</i> function | ||||||
|  |  *  should be called in response to the \ref EVENT_USB_Device_ConfigurationChanged() event. This function will return a | ||||||
|  |  *  boolean value if the driver sucessfully initialized the instance. Like all the class driver functions, this function | ||||||
|  |  *  takes in the address of the specific instance you wish to initialize - in this manner, multiple seperate instances of | ||||||
|  |  *  the same class type can be initialized like thus: | ||||||
|  |  * | ||||||
|  |  *  \code | ||||||
|  |  *  void EVENT_USB_Device_ConfigurationChanged(void) | ||||||
|  |  *  { | ||||||
|  |  *  	LEDs_SetAllLEDs(LEDMASK_USB_READY); | ||||||
|  |  *  	 | ||||||
|  |  *  	if (!(Audio_Device_ConfigureEndpoints(&My_Audio_Interface))) | ||||||
|  |  *  	  LEDs_SetAllLEDs(LEDMASK_USB_ERROR); | ||||||
|  |  *  } | ||||||
|  |  *  \endcode | ||||||
|  |  *  | ||||||
|  |  *  Once initialized, it is important to maintain the class driver's state by repeatedly calling the Class Driver's | ||||||
|  |  *  <i><b>{Class Name}</b>_Device_USBTask()</i> function in the main program loop. The exact implementation of this | ||||||
|  |  *  function varies between class drivers, and can be used for any internal class driver purpose to maintain each | ||||||
|  |  *  instance. Again, this function uses the address of the instance to operate on, and thus needs to be called for each | ||||||
|  |  *  seperate instance, just like the main USB maintenance routine \ref USB_USBTask(): | ||||||
|  |  * | ||||||
|  |  *  \code | ||||||
|  |  *  int main(void) | ||||||
|  |  *  { | ||||||
|  |  *      SetupHardware(); | ||||||
|  |  *   | ||||||
|  |  *      LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); | ||||||
|  |  *   | ||||||
|  |  *      for (;;) | ||||||
|  |  *      { | ||||||
|  |  *          Create_And_Process_Samples(); | ||||||
|  |  *       | ||||||
|  |  *          Audio_Device_USBTask(&My_Audio_Interface); | ||||||
|  |  *          USB_USBTask(); | ||||||
|  |  *      } | ||||||
|  |  *  } | ||||||
|  |  *  \endcode | ||||||
|  |  * | ||||||
|  |  *  The final standardized Device Class Driver function is the Control Request handler function | ||||||
|  |  *  <i><b>{Class Name}</b>_Device_ProcessControlRequest()</i>, which should be called when the | ||||||
|  |  *  \ref EVENT_USB_Device_UnhandledControlRequest() event fires. This function should also be | ||||||
|  |  *  called for each class driver instance, using the address of the instance to operate on as | ||||||
|  |  *  the function's parameter. The request handler will abort if it is determined that the current | ||||||
|  |  *  request is not targeted at the given class driver instance, thus these methods can safely be | ||||||
|  |  *  called one-after-another in the event handler with no form of error checking: | ||||||
|  |  * | ||||||
|  |  *  \code | ||||||
|  |  *  void EVENT_USB_Device_UnhandledControlRequest(void) | ||||||
|  |  *  { | ||||||
|  |  *      Audio_Device_ProcessControlRequest(&My_Audio_Interface); | ||||||
|  |  *  } | ||||||
|  |  *  \endcode | ||||||
|  |  * | ||||||
|  |  *  Each class driver may also define a set of callback functions (which are prefixed by "CALLBACK_" | ||||||
|  |  *  in the function's name) which <b>must</b> also be added to the user application - refer to each | ||||||
|  |  *  individual class driver's documentation for mandatory callbacks. In addition, each class driver may | ||||||
|  |  *  also define a set of events (identifiable by their prefix of "EVENT_" in the function's name), which | ||||||
|  |  *  the user application <b>may</b> choose to implement, or ignore if not needed. | ||||||
|  |  * | ||||||
|  |  *  The individual Device Mode Class Driver documentation contains more information on the non-standardized, | ||||||
|  |  *  class-specific functions which the user application can then use on the driver instances, such as data | ||||||
|  |  *  read and write routines. See each driver's individual documentation for more information on the | ||||||
|  |  *  class-specific functions. | ||||||
|  |  * | ||||||
|  |  *  \subsection SSec_ClassDriverHost Host Mode Class Drivers | ||||||
|  |  * | ||||||
|  */ |  */ | ||||||
|   |   | ||||||
| #ifndef __USB_H__ | #ifndef __USB_H__ | ||||||
|  | |||||||
| @ -66,6 +66,7 @@ | |||||||
|  *  - Mobo 4.3, a USB controlled all band (160-10m) HF SDR transceiver: http://sites.google.com/site/lofturj/mobo4_3 |  *  - Mobo 4.3, a USB controlled all band (160-10m) HF SDR transceiver: http://sites.google.com/site/lofturj/mobo4_3 | ||||||
|  *  - SEGA Megadrive/Super Nintendo Cartridge Reader: http://www.snega2usb.com |  *  - SEGA Megadrive/Super Nintendo Cartridge Reader: http://www.snega2usb.com | ||||||
|  *  - XMEGA Development Board, using LUFA as an On-Board Programmer: http://xmega.mattair.net/ |  *  - XMEGA Development Board, using LUFA as an On-Board Programmer: http://xmega.mattair.net/ | ||||||
|  |  *  - Penguino, an Arduino Board With On-Board LUFA Powered Debugger/Programmer: http://wiki.icy.com.au/PenguinoAVR | ||||||
|  * |  * | ||||||
|  *  \section Sec_LUFAPublications Publications Mentioning LUFA |  *  \section Sec_LUFAPublications Publications Mentioning LUFA | ||||||
|  *  - Elektor Magazine, "My First AVR-USB" by Antoine Authier (feature), January 2010 Issue |  *  - Elektor Magazine, "My First AVR-USB" by Antoine Authier (feature), January 2010 Issue | ||||||
|  | |||||||
| @ -75,7 +75,7 @@ void DHCPApp_Callback(void) | |||||||
| 		case DHCP_STATE_SendDiscover: | 		case DHCP_STATE_SendDiscover: | ||||||
| 			/* Clear all DHCP settings, reset client IP address */ | 			/* Clear all DHCP settings, reset client IP address */ | ||||||
| 			memset(&AppState->DHCPOffer_Data, 0x00, sizeof(AppState->DHCPOffer_Data)); | 			memset(&AppState->DHCPOffer_Data, 0x00, sizeof(AppState->DHCPOffer_Data)); | ||||||
| 			uip_sethostaddr(&AppState->DHCPOffer_Data.AllocatedIP); | 			uip_sethostaddr((uip_ipaddr_t*)&AppState->DHCPOffer_Data.AllocatedIP); | ||||||
| 
 | 
 | ||||||
| 			/* Fill out the DHCP response header */ | 			/* Fill out the DHCP response header */ | ||||||
| 			AppDataSize += DHCPApp_FillDHCPHeader(AppData, DHCP_DISCOVER, AppState); | 			AppDataSize += DHCPApp_FillDHCPHeader(AppData, DHCP_DISCOVER, AppState); | ||||||
| @ -155,9 +155,9 @@ void DHCPApp_Callback(void) | |||||||
| 			    (RequestResponse_MessageType == DHCP_ACK)) | 			    (RequestResponse_MessageType == DHCP_ACK)) | ||||||
| 			{ | 			{ | ||||||
| 				/* Set the new network parameters from the DHCP server */ | 				/* Set the new network parameters from the DHCP server */ | ||||||
| 				uip_sethostaddr(&AppState->DHCPOffer_Data.AllocatedIP); | 				uip_sethostaddr((uip_ipaddr_t*)&AppState->DHCPOffer_Data.AllocatedIP); | ||||||
| 				uip_setnetmask(&AppState->DHCPOffer_Data.Netmask); | 				uip_setnetmask((uip_ipaddr_t*)&AppState->DHCPOffer_Data.Netmask); | ||||||
| 				uip_setdraddr(&AppState->DHCPOffer_Data.GatewayIP); | 				uip_setdraddr((uip_ipaddr_t*)&AppState->DHCPOffer_Data.GatewayIP); | ||||||
| 			 | 			 | ||||||
| 				AppState->CurrentState = DHCP_STATE_AddressLeased; | 				AppState->CurrentState = DHCP_STATE_AddressLeased; | ||||||
| 			} | 			} | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ char PROGMEM HTTP404Header[] = "HTTP/1.1 404 Not Found\r\n" | |||||||
| /** Default MIME type sent if no other MIME type can be determined */ | /** Default MIME type sent if no other MIME type can be determined */ | ||||||
| char PROGMEM DefaultMIMEType[] = "text/plain"; | char PROGMEM DefaultMIMEType[] = "text/plain"; | ||||||
| 
 | 
 | ||||||
| /** List of MIME types for each supported file extension - must be terminated with \ref END_OF_MIME_LIST entry. */ | /** List of MIME types for each supported file extension. */ | ||||||
| MIME_Type_t PROGMEM MIMETypes[] = | MIME_Type_t PROGMEM MIMETypes[] = | ||||||
| 	{ | 	{ | ||||||
| 		{.Extension = "htm", .MIMEType = "text/html"}, | 		{.Extension = "htm", .MIMEType = "text/html"}, | ||||||
|  | |||||||
| @ -52,11 +52,12 @@ void uIPManagement_Init(void) | |||||||
| { | { | ||||||
| 	/* uIP Timing Initialization */ | 	/* uIP Timing Initialization */ | ||||||
| 	clock_init(); | 	clock_init(); | ||||||
| 	timer_set(&ConnectionTimer, CLOCK_SECOND / 10); | 	timer_set(&ConnectionTimer, CLOCK_SECOND / 8); | ||||||
| 	timer_set(&ARPTimer, CLOCK_SECOND * 10);	 | 	timer_set(&ARPTimer, CLOCK_SECOND * 10);	 | ||||||
| 
 | 
 | ||||||
| 	/* uIP Stack Initialization */ | 	/* uIP Stack Initialization */ | ||||||
| 	uip_init(); | 	uip_init(); | ||||||
|  | 	uip_arp_init(); | ||||||
| 
 | 
 | ||||||
| 	/* DHCP/Server IP Settings Initialization */ | 	/* DHCP/Server IP Settings Initialization */ | ||||||
| 	#if defined(ENABLE_DHCP) | 	#if defined(ENABLE_DHCP) | ||||||
|  | |||||||
							
								
								
									
										37
									
								
								Projects/Webserver/Lib/uip/clock.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								Projects/Webserver/Lib/uip/clock.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | #include <stdint.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <avr/interrupt.h> | ||||||
|  | #include <avr/io.h> | ||||||
|  | #include <avr/sfr_defs.h> | ||||||
|  | 
 | ||||||
|  | #include "clock.h" | ||||||
|  | 
 | ||||||
|  | //Counted time
 | ||||||
|  | volatile clock_time_t clock_datetime = 0; | ||||||
|  | 
 | ||||||
|  | //Overflow interrupt
 | ||||||
|  | ISR(TIMER1_COMPA_vect) | ||||||
|  | { | ||||||
|  | 	clock_datetime += 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //Initialise the clock
 | ||||||
|  | void clock_init() | ||||||
|  | { | ||||||
|  | 	OCR1A  = ((F_CPU / 1024) / 100); | ||||||
|  | 	TCCR1B = ((1 << WGM12) | (1 << CS12) | (1 << CS10)); | ||||||
|  | 	TIMSK1 = (1 << OCIE1A); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //Return time
 | ||||||
|  | clock_time_t clock_time() | ||||||
|  | { | ||||||
|  | 	clock_time_t time; | ||||||
|  | 
 | ||||||
|  | 	cli(); | ||||||
|  | 		time = clock_datetime; | ||||||
|  | 	sei(); | ||||||
|  | 
 | ||||||
|  | 	return time; | ||||||
|  | } | ||||||
| @ -1,88 +1,11 @@ | |||||||
| /**
 | #ifndef __CLOCK_ARCH_H__ | ||||||
|  * \defgroup clock Clock interface | #define __CLOCK_ARCH_H__ | ||||||
|  * |  | ||||||
|  * The clock interface is the interface between the \ref timer "timer library" |  | ||||||
|  * and the platform specific clock functionality. The clock |  | ||||||
|  * interface must be implemented for each platform that uses the \ref |  | ||||||
|  * timer "timer library". |  | ||||||
|  * |  | ||||||
|  * The clock interface does only one this: it measures time. The clock |  | ||||||
|  * interface provides a macro, CLOCK_SECOND, which corresponds to one |  | ||||||
|  * second of system time. |  | ||||||
|  * |  | ||||||
|  * \sa \ref timer "Timer library" |  | ||||||
|  * |  | ||||||
|  * @{ |  | ||||||
|  */ |  | ||||||
| 
 | 
 | ||||||
| /*
 | #include <stdint.h> | ||||||
|  * Copyright (c) 2004, Swedish Institute of Computer Science. |  | ||||||
|  * All rights reserved. |  | ||||||
|  * |  | ||||||
|  * Redistribution and use in source and binary forms, with or without |  | ||||||
|  * modification, are permitted provided that the following conditions |  | ||||||
|  * are met: |  | ||||||
|  * 1. Redistributions of source code must retain the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer. |  | ||||||
|  * 2. Redistributions in binary form must reproduce the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer in the |  | ||||||
|  *    documentation and/or other materials provided with the distribution. |  | ||||||
|  * 3. Neither the name of the Institute nor the names of its contributors |  | ||||||
|  *    may be used to endorse or promote products derived from this software |  | ||||||
|  *    without specific prior written permission. |  | ||||||
|  * |  | ||||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND |  | ||||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |  | ||||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |  | ||||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE |  | ||||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |  | ||||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |  | ||||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |  | ||||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |  | ||||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |  | ||||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |  | ||||||
|  * SUCH DAMAGE. |  | ||||||
|  * |  | ||||||
|  * This file is part of the uIP TCP/IP stack |  | ||||||
|  * |  | ||||||
|  * Author: Adam Dunkels <adam@sics.se> |  | ||||||
|  * |  | ||||||
|  * $Id: clock.h,v 1.3 2006/06/11 21:46:39 adam Exp $ |  | ||||||
|  */ |  | ||||||
| #ifndef __CLOCK_H__ |  | ||||||
| #define __CLOCK_H__ |  | ||||||
| 
 | 
 | ||||||
| #include "clock-arch.h" | typedef uint16_t clock_time_t; | ||||||
| 
 | #define CLOCK_SECOND 100 | ||||||
| /**
 |  | ||||||
|  * 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); | void clock_init(void); | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Get the current clock time. |  | ||||||
|  * |  | ||||||
|  * This function returns the current system clock time. |  | ||||||
|  * |  | ||||||
|  * \return The current clock time, measured in system ticks. |  | ||||||
|  */ |  | ||||||
| clock_time_t clock_time(void); | clock_time_t clock_time(void); | ||||||
| 
 | 
 | ||||||
| /**
 | #endif /* __CLOCK_ARCH_H__ */ | ||||||
|  * A second, measured in system clock time. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #ifdef CLOCK_CONF_SECOND |  | ||||||
| #define CLOCK_SECOND CLOCK_CONF_SECOND |  | ||||||
| #else |  | ||||||
| #define CLOCK_SECOND (clock_time_t)32 |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| #endif /* __CLOCK_H__ */ |  | ||||||
| 
 |  | ||||||
| /** @} */ |  | ||||||
|  | |||||||
| @ -1,83 +0,0 @@ | |||||||
| /*
 |  | ||||||
|  * Copyright (c) 2004-2005, Swedish Institute of Computer Science. |  | ||||||
|  * All rights reserved. |  | ||||||
|  * |  | ||||||
|  * Redistribution and use in source and binary forms, with or without |  | ||||||
|  * modification, are permitted provided that the following conditions |  | ||||||
|  * are met: |  | ||||||
|  * 1. Redistributions of source code must retain the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer. |  | ||||||
|  * 2. Redistributions in binary form must reproduce the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer in the |  | ||||||
|  *    documentation and/or other materials provided with the distribution. |  | ||||||
|  * 3. Neither the name of the Institute nor the names of its contributors |  | ||||||
|  *    may be used to endorse or promote products derived from this software |  | ||||||
|  *    without specific prior written permission. |  | ||||||
|  * |  | ||||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND |  | ||||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |  | ||||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |  | ||||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE |  | ||||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |  | ||||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |  | ||||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |  | ||||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |  | ||||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |  | ||||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |  | ||||||
|  * SUCH DAMAGE. |  | ||||||
|  * |  | ||||||
|  * This file is part of the uIP TCP/IP stack |  | ||||||
|  * |  | ||||||
|  * Author: Adam Dunkels <adam@sics.se> |  | ||||||
|  * |  | ||||||
|  * $Id: lc-addrlabels.h,v 1.3 2006/06/12 08:00:30 adam Exp $ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \addtogroup lc |  | ||||||
|  * @{ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \file |  | ||||||
|  * Implementation of local continuations based on the "Labels as |  | ||||||
|  * values" feature of gcc |  | ||||||
|  * \author |  | ||||||
|  * Adam Dunkels <adam@sics.se> |  | ||||||
|  * |  | ||||||
|  * This implementation of local continuations is based on a special |  | ||||||
|  * feature of the GCC C compiler called "labels as values". This |  | ||||||
|  * feature allows assigning pointers with the address of the code |  | ||||||
|  * corresponding to a particular C label. |  | ||||||
|  * |  | ||||||
|  * For more information, see the GCC documentation: |  | ||||||
|  * http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
 |  | ||||||
|  * |  | ||||||
|  * Thanks to dividuum for finding the nice local scope label |  | ||||||
|  * implementation. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #ifndef __LC_ADDRLABELS_H__ |  | ||||||
| #define __LC_ADDRLABELS_H__ |  | ||||||
| 
 |  | ||||||
| /** \hideinitializer */ |  | ||||||
| typedef void * lc_t; |  | ||||||
| 
 |  | ||||||
| #define LC_INIT(s) s = NULL |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| #define LC_RESUME(s)                            \ |  | ||||||
|   do {                                          \ |  | ||||||
|     if(s != NULL) {                             \ |  | ||||||
|       goto *s;                                  \ |  | ||||||
|     }                                           \ |  | ||||||
|   } while(0) |  | ||||||
| 
 |  | ||||||
| #define LC_SET(s)                               \ |  | ||||||
|   do { ({ __label__ resume; resume: (s) = &&resume; }); }while(0) |  | ||||||
| 
 |  | ||||||
| #define LC_END(s) |  | ||||||
| 
 |  | ||||||
| #endif /* __LC_ADDRLABELS_H__ */ |  | ||||||
| 
 |  | ||||||
| /**  @} */ |  | ||||||
| @ -1,76 +0,0 @@ | |||||||
| /*
 |  | ||||||
|  * Copyright (c) 2004-2005, Swedish Institute of Computer Science. |  | ||||||
|  * All rights reserved. |  | ||||||
|  * |  | ||||||
|  * Redistribution and use in source and binary forms, with or without |  | ||||||
|  * modification, are permitted provided that the following conditions |  | ||||||
|  * are met: |  | ||||||
|  * 1. Redistributions of source code must retain the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer. |  | ||||||
|  * 2. Redistributions in binary form must reproduce the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer in the |  | ||||||
|  *    documentation and/or other materials provided with the distribution. |  | ||||||
|  * 3. Neither the name of the Institute nor the names of its contributors |  | ||||||
|  *    may be used to endorse or promote products derived from this software |  | ||||||
|  *    without specific prior written permission. |  | ||||||
|  * |  | ||||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND |  | ||||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |  | ||||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |  | ||||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE |  | ||||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |  | ||||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |  | ||||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |  | ||||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |  | ||||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |  | ||||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |  | ||||||
|  * SUCH DAMAGE. |  | ||||||
|  * |  | ||||||
|  * This file is part of the uIP TCP/IP stack |  | ||||||
|  * |  | ||||||
|  * Author: Adam Dunkels <adam@sics.se> |  | ||||||
|  * |  | ||||||
|  * $Id: lc-switch.h,v 1.2 2006/06/12 08:00:30 adam Exp $ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \addtogroup lc |  | ||||||
|  * @{ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \file |  | ||||||
|  * Implementation of local continuations based on switch() statment |  | ||||||
|  * \author Adam Dunkels <adam@sics.se> |  | ||||||
|  * |  | ||||||
|  * This implementation of local continuations uses the C switch() |  | ||||||
|  * statement to resume execution of a function somewhere inside the |  | ||||||
|  * function's body. The implementation is based on the fact that |  | ||||||
|  * switch() statements are able to jump directly into the bodies of |  | ||||||
|  * control structures such as if() or while() statmenets. |  | ||||||
|  * |  | ||||||
|  * This implementation borrows heavily from Simon Tatham's coroutines |  | ||||||
|  * implementation in C: |  | ||||||
|  * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
 |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #ifndef __LC_SWITCH_H__ |  | ||||||
| #define __LC_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__ */ |  | ||||||
| 
 |  | ||||||
| /** @} */ |  | ||||||
| @ -1,131 +0,0 @@ | |||||||
| /*
 |  | ||||||
|  * Copyright (c) 2004-2005, Swedish Institute of Computer Science. |  | ||||||
|  * All rights reserved. |  | ||||||
|  * |  | ||||||
|  * Redistribution and use in source and binary forms, with or without |  | ||||||
|  * modification, are permitted provided that the following conditions |  | ||||||
|  * are met: |  | ||||||
|  * 1. Redistributions of source code must retain the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer. |  | ||||||
|  * 2. Redistributions in binary form must reproduce the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer in the |  | ||||||
|  *    documentation and/or other materials provided with the distribution. |  | ||||||
|  * 3. Neither the name of the Institute nor the names of its contributors |  | ||||||
|  *    may be used to endorse or promote products derived from this software |  | ||||||
|  *    without specific prior written permission. |  | ||||||
|  * |  | ||||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND |  | ||||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |  | ||||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |  | ||||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE |  | ||||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |  | ||||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |  | ||||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |  | ||||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |  | ||||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |  | ||||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |  | ||||||
|  * SUCH DAMAGE. |  | ||||||
|  * |  | ||||||
|  * This file is part of the uIP TCP/IP stack |  | ||||||
|  * |  | ||||||
|  * Author: Adam Dunkels <adam@sics.se> |  | ||||||
|  * |  | ||||||
|  * $Id: lc.h,v 1.2 2006/06/12 08:00:30 adam Exp $ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \addtogroup pt |  | ||||||
|  * @{ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \defgroup lc Local continuations |  | ||||||
|  * @{ |  | ||||||
|  * |  | ||||||
|  * Local continuations form the basis for implementing protothreads. A |  | ||||||
|  * local continuation can be <i>set</i> in a specific function to |  | ||||||
|  * capture the state of the function. After a local continuation has |  | ||||||
|  * been set can be <i>resumed</i> in order to restore the state of the |  | ||||||
|  * function at the point where the local continuation was set. |  | ||||||
|  * |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \file lc.h |  | ||||||
|  * Local continuations |  | ||||||
|  * \author |  | ||||||
|  * Adam Dunkels <adam@sics.se> |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #ifdef DOXYGEN |  | ||||||
| /**
 |  | ||||||
|  * Initialize a local continuation. |  | ||||||
|  * |  | ||||||
|  * This operation initializes the local continuation, thereby |  | ||||||
|  * unsetting any previously set continuation state. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define LC_INIT(lc) |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Set a local continuation. |  | ||||||
|  * |  | ||||||
|  * The set operation saves the state of the function at the point |  | ||||||
|  * where the operation is executed. As far as the set operation is |  | ||||||
|  * concerned, the state of the function does <b>not</b> include the |  | ||||||
|  * call-stack or local (automatic) variables, but only the program |  | ||||||
|  * counter and such CPU registers that needs to be saved. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define LC_SET(lc) |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Resume a local continuation. |  | ||||||
|  * |  | ||||||
|  * The resume operation resumes a previously set local continuation, thus |  | ||||||
|  * restoring the state in which the function was when the local |  | ||||||
|  * continuation was set. If the local continuation has not been |  | ||||||
|  * previously set, the resume operation does nothing. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define LC_RESUME(lc) |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Mark the end of local continuation usage. |  | ||||||
|  * |  | ||||||
|  * The end operation signifies that local continuations should not be |  | ||||||
|  * used any more in the function. This operation is not needed for |  | ||||||
|  * most implementations of local continuation, but is required by a |  | ||||||
|  * few implementations. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define LC_END(lc) |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \var typedef lc_t; |  | ||||||
|  * |  | ||||||
|  * The local continuation type. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #endif /* DOXYGEN */ |  | ||||||
| 
 |  | ||||||
| #ifndef __LC_H__ |  | ||||||
| #define __LC_H__ |  | ||||||
| 
 |  | ||||||
| #ifdef LC_CONF_INCLUDE |  | ||||||
| #include LC_CONF_INCLUDE |  | ||||||
| #else |  | ||||||
| #include "lc-switch.h" |  | ||||||
| #endif /* LC_CONF_INCLUDE */ |  | ||||||
| 
 |  | ||||||
| #endif /* __LC_H__ */ |  | ||||||
| 
 |  | ||||||
| /** @} */ |  | ||||||
| /** @} */ |  | ||||||
| @ -1,338 +0,0 @@ | |||||||
| /*
 |  | ||||||
|  * Copyright (c) 2004, Swedish Institute of Computer Science. |  | ||||||
|  * All rights reserved. |  | ||||||
|  * |  | ||||||
|  * Redistribution and use in source and binary forms, with or without |  | ||||||
|  * modification, are permitted provided that the following conditions |  | ||||||
|  * are met: |  | ||||||
|  * 1. Redistributions of source code must retain the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer. |  | ||||||
|  * 2. Redistributions in binary form must reproduce the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer in the |  | ||||||
|  *    documentation and/or other materials provided with the distribution. |  | ||||||
|  * 3. Neither the name of the Institute nor the names of its contributors |  | ||||||
|  *    may be used to endorse or promote products derived from this software |  | ||||||
|  *    without specific prior written permission. |  | ||||||
|  * |  | ||||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND |  | ||||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |  | ||||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |  | ||||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE |  | ||||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |  | ||||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |  | ||||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |  | ||||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |  | ||||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |  | ||||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |  | ||||||
|  * SUCH DAMAGE. |  | ||||||
|  * |  | ||||||
|  * This file is part of the uIP TCP/IP stack |  | ||||||
|  * |  | ||||||
|  * Author: Adam Dunkels <adam@sics.se> |  | ||||||
|  * |  | ||||||
|  * $Id: psock.c,v 1.2 2006/06/12 08:00:30 adam Exp $ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #include <stdio.h> |  | ||||||
| #include <string.h> |  | ||||||
| 
 |  | ||||||
| #include "uipopt.h" |  | ||||||
| #include "psock.h" |  | ||||||
| #include "uip.h" |  | ||||||
| 
 |  | ||||||
| #define STATE_NONE 0 |  | ||||||
| #define STATE_ACKED 1 |  | ||||||
| #define STATE_READ 2 |  | ||||||
| #define STATE_BLOCKED_NEWDATA 3 |  | ||||||
| #define STATE_BLOCKED_CLOSE 4 |  | ||||||
| #define STATE_BLOCKED_SEND 5 |  | ||||||
| #define STATE_DATA_SENT 6 |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * Return value of the buffering functions that indicates that a |  | ||||||
|  * buffer was not filled by incoming data. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| #define BUF_NOT_FULL 0 |  | ||||||
| #define BUF_NOT_FOUND 0 |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * Return value of the buffering functions that indicates that a |  | ||||||
|  * buffer was completely filled by incoming data. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| #define BUF_FULL 1 |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * Return value of the buffering functions that indicates that an |  | ||||||
|  * end-marker byte was found. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| #define BUF_FOUND 2 |  | ||||||
| 
 |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| static void |  | ||||||
| buf_setup(struct psock_buf *buf, |  | ||||||
| 	  u8_t *bufptr, u16_t bufsize) |  | ||||||
| { |  | ||||||
|   buf->ptr = bufptr; |  | ||||||
|   buf->left = bufsize; |  | ||||||
| } |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| static u8_t |  | ||||||
| buf_bufdata(struct psock_buf *buf, u16_t len, |  | ||||||
| 	    u8_t **dataptr, u16_t *datalen) |  | ||||||
| { |  | ||||||
|   if(*datalen < buf->left) { |  | ||||||
|     memcpy(buf->ptr, *dataptr, *datalen); |  | ||||||
|     buf->ptr += *datalen; |  | ||||||
|     buf->left -= *datalen; |  | ||||||
|     *dataptr += *datalen; |  | ||||||
|     *datalen = 0; |  | ||||||
|     return BUF_NOT_FULL; |  | ||||||
|   } else if(*datalen == buf->left) { |  | ||||||
|     memcpy(buf->ptr, *dataptr, *datalen); |  | ||||||
|     buf->ptr += *datalen; |  | ||||||
|     buf->left = 0; |  | ||||||
|     *dataptr += *datalen; |  | ||||||
|     *datalen = 0; |  | ||||||
|     return BUF_FULL; |  | ||||||
|   } else { |  | ||||||
|     memcpy(buf->ptr, *dataptr, buf->left); |  | ||||||
|     buf->ptr += buf->left; |  | ||||||
|     *datalen -= buf->left; |  | ||||||
|     *dataptr += buf->left; |  | ||||||
|     buf->left = 0; |  | ||||||
|     return BUF_FULL; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| static u8_t |  | ||||||
| buf_bufto(register struct psock_buf *buf, u8_t endmarker, |  | ||||||
| 	  register u8_t **dataptr, register u16_t *datalen) |  | ||||||
| { |  | ||||||
|   u8_t c; |  | ||||||
|   while(buf->left > 0 && *datalen > 0) { |  | ||||||
|     c = *buf->ptr = **dataptr; |  | ||||||
|     ++*dataptr; |  | ||||||
|     ++buf->ptr; |  | ||||||
|     --*datalen; |  | ||||||
|     --buf->left; |  | ||||||
|      |  | ||||||
|     if(c == endmarker) { |  | ||||||
|       return BUF_FOUND; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   if(*datalen == 0) { |  | ||||||
|     return BUF_NOT_FOUND; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   while(*datalen > 0) { |  | ||||||
|     c = **dataptr; |  | ||||||
|     --*datalen; |  | ||||||
|     ++*dataptr; |  | ||||||
|      |  | ||||||
|     if(c == endmarker) { |  | ||||||
|       return BUF_FOUND | BUF_FULL; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|    |  | ||||||
|   return BUF_FULL; |  | ||||||
| } |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| static char |  | ||||||
| send_data(register struct psock *s) |  | ||||||
| { |  | ||||||
|   if(s->state != STATE_DATA_SENT || uip_rexmit()) { |  | ||||||
|     if(s->sendlen > uip_mss()) { |  | ||||||
|       uip_send(s->sendptr, uip_mss()); |  | ||||||
|     } else { |  | ||||||
|       uip_send(s->sendptr, s->sendlen); |  | ||||||
|     } |  | ||||||
|     s->state = STATE_DATA_SENT; |  | ||||||
|     return 1; |  | ||||||
|   } |  | ||||||
|   return 0; |  | ||||||
| } |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| static char |  | ||||||
| data_acked(register struct psock *s) |  | ||||||
| { |  | ||||||
|   if(s->state == STATE_DATA_SENT && uip_acked()) { |  | ||||||
|     if(s->sendlen > uip_mss()) { |  | ||||||
|       s->sendlen -= uip_mss(); |  | ||||||
|       s->sendptr += uip_mss(); |  | ||||||
|     } else { |  | ||||||
|       s->sendptr += s->sendlen; |  | ||||||
|       s->sendlen = 0; |  | ||||||
|     } |  | ||||||
|     s->state = STATE_ACKED; |  | ||||||
|     return 1; |  | ||||||
|   } |  | ||||||
|   return 0; |  | ||||||
| } |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| PT_THREAD(psock_send(register struct psock *s, const char *buf, |  | ||||||
| 		     unsigned int len)) |  | ||||||
| { |  | ||||||
|   PT_BEGIN(&s->psockpt); |  | ||||||
| 
 |  | ||||||
|   /* If there is no data to send, we exit immediately. */ |  | ||||||
|   if(len == 0) { |  | ||||||
|     PT_EXIT(&s->psockpt); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   /* Save the length of and a pointer to the data that is to be
 |  | ||||||
|      sent. */ |  | ||||||
|   s->sendptr = buf; |  | ||||||
|   s->sendlen = len; |  | ||||||
| 
 |  | ||||||
|   s->state = STATE_NONE; |  | ||||||
| 
 |  | ||||||
|   /* We loop here until all data is sent. The s->sendlen variable is
 |  | ||||||
|      updated by the data_sent() function. */ |  | ||||||
|   while(s->sendlen > 0) { |  | ||||||
| 
 |  | ||||||
|     /*
 |  | ||||||
|      * The condition for this PT_WAIT_UNTIL is a little tricky: the |  | ||||||
|      * protothread will wait here until all data has been acknowledged |  | ||||||
|      * (data_acked() returns true) and until all data has been sent |  | ||||||
|      * (send_data() returns true). The two functions data_acked() and |  | ||||||
|      * send_data() must be called in succession to ensure that all |  | ||||||
|      * data is sent. Therefore the & operator is used instead of the |  | ||||||
|      * && operator, which would cause only the data_acked() function |  | ||||||
|      * to be called when it returns false. |  | ||||||
|      */ |  | ||||||
|     PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s)); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   s->state = STATE_NONE; |  | ||||||
|    |  | ||||||
|   PT_END(&s->psockpt); |  | ||||||
| } |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| PT_THREAD(psock_generator_send(register struct psock *s, |  | ||||||
| 			       unsigned short (*generate)(void *), void *arg)) |  | ||||||
| { |  | ||||||
|   PT_BEGIN(&s->psockpt); |  | ||||||
| 
 |  | ||||||
|   /* Ensure that there is a generator function to call. */ |  | ||||||
|   if(generate == NULL) { |  | ||||||
|     PT_EXIT(&s->psockpt); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   /* Call the generator function to generate the data in the
 |  | ||||||
|      uip_appdata buffer. */ |  | ||||||
|   s->sendlen = generate(arg); |  | ||||||
|   s->sendptr = uip_appdata; |  | ||||||
| 
 |  | ||||||
|   s->state = STATE_NONE;   |  | ||||||
|   do { |  | ||||||
|     /* Call the generator function again if we are called to perform a
 |  | ||||||
|        retransmission. */ |  | ||||||
|     if(uip_rexmit()) { |  | ||||||
|       generate(arg); |  | ||||||
|     } |  | ||||||
|     /* Wait until all data is sent and acknowledged. */ |  | ||||||
|     PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s)); |  | ||||||
|   } while(s->sendlen > 0); |  | ||||||
|    |  | ||||||
|   s->state = STATE_NONE; |  | ||||||
|    |  | ||||||
|   PT_END(&s->psockpt); |  | ||||||
| } |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| u16_t |  | ||||||
| psock_datalen(struct psock *psock) |  | ||||||
| { |  | ||||||
|   return psock->bufsize - psock->buf.left; |  | ||||||
| } |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| char |  | ||||||
| psock_newdata(struct psock *s) |  | ||||||
| { |  | ||||||
|   if(s->readlen > 0) { |  | ||||||
|     /* There is data in the uip_appdata buffer that has not yet been
 |  | ||||||
|        read with the PSOCK_READ functions. */ |  | ||||||
|     return 1; |  | ||||||
|   } else if(s->state == STATE_READ) { |  | ||||||
|     /* All data in uip_appdata buffer already consumed. */ |  | ||||||
|     s->state = STATE_BLOCKED_NEWDATA; |  | ||||||
|     return 0; |  | ||||||
|   } else if(uip_newdata()) { |  | ||||||
|     /* There is new data that has not been consumed. */ |  | ||||||
|     return 1; |  | ||||||
|   } else { |  | ||||||
|     /* There is no new data. */ |  | ||||||
|     return 0; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| PT_THREAD(psock_readto(register struct psock *psock, unsigned char c)) |  | ||||||
| { |  | ||||||
|   PT_BEGIN(&psock->psockpt); |  | ||||||
| 
 |  | ||||||
|   buf_setup(&psock->buf, psock->bufptr, psock->bufsize); |  | ||||||
|    |  | ||||||
|   /* XXX: Should add buf_checkmarker() before do{} loop, if
 |  | ||||||
|      incoming data has been handled while waiting for a write. */ |  | ||||||
| 
 |  | ||||||
|   do { |  | ||||||
|     if(psock->readlen == 0) { |  | ||||||
|       PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock)); |  | ||||||
|       psock->state = STATE_READ; |  | ||||||
|       psock->readptr = (u8_t *)uip_appdata; |  | ||||||
|       psock->readlen = uip_datalen(); |  | ||||||
|     } |  | ||||||
|   } while((buf_bufto(&psock->buf, c, |  | ||||||
| 		     &psock->readptr, |  | ||||||
| 		     &psock->readlen) & BUF_FOUND) == 0); |  | ||||||
|    |  | ||||||
|   if(psock_datalen(psock) == 0) { |  | ||||||
|     psock->state = STATE_NONE; |  | ||||||
|     PT_RESTART(&psock->psockpt); |  | ||||||
|   } |  | ||||||
|   PT_END(&psock->psockpt); |  | ||||||
| } |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| PT_THREAD(psock_readbuf(register struct psock *psock)) |  | ||||||
| { |  | ||||||
|   PT_BEGIN(&psock->psockpt); |  | ||||||
| 
 |  | ||||||
|   buf_setup(&psock->buf, psock->bufptr, psock->bufsize); |  | ||||||
|    |  | ||||||
|   /* XXX: Should add buf_checkmarker() before do{} loop, if
 |  | ||||||
|      incoming data has been handled while waiting for a write. */ |  | ||||||
| 
 |  | ||||||
|   do { |  | ||||||
|     if(psock->readlen == 0) { |  | ||||||
|       PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock)); |  | ||||||
|       printf("Waited for newdata\n"); |  | ||||||
|       psock->state = STATE_READ; |  | ||||||
|       psock->readptr = (u8_t *)uip_appdata; |  | ||||||
|       psock->readlen = uip_datalen(); |  | ||||||
|     } |  | ||||||
|   } while(buf_bufdata(&psock->buf, psock->bufsize, |  | ||||||
| 			 &psock->readptr, |  | ||||||
| 			 &psock->readlen) != BUF_FULL); |  | ||||||
| 
 |  | ||||||
|   if(psock_datalen(psock) == 0) { |  | ||||||
|     psock->state = STATE_NONE; |  | ||||||
|     PT_RESTART(&psock->psockpt); |  | ||||||
|   } |  | ||||||
|   PT_END(&psock->psockpt); |  | ||||||
| } |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| void |  | ||||||
| psock_init(register struct psock *psock, char *buffer, unsigned int buffersize) |  | ||||||
| { |  | ||||||
|   psock->state = STATE_NONE; |  | ||||||
|   psock->readlen = 0; |  | ||||||
|   psock->bufptr = buffer; |  | ||||||
|   psock->bufsize = buffersize; |  | ||||||
|   buf_setup(&psock->buf, buffer, buffersize); |  | ||||||
|   PT_INIT(&psock->pt); |  | ||||||
|   PT_INIT(&psock->psockpt); |  | ||||||
| } |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| @ -1,380 +0,0 @@ | |||||||
| /*
 |  | ||||||
|  * Copyright (c) 2004, Swedish Institute of Computer Science. |  | ||||||
|  * All rights reserved. |  | ||||||
|  * |  | ||||||
|  * Redistribution and use in source and binary forms, with or without |  | ||||||
|  * modification, are permitted provided that the following conditions |  | ||||||
|  * are met: |  | ||||||
|  * 1. Redistributions of source code must retain the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer. |  | ||||||
|  * 2. Redistributions in binary form must reproduce the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer in the |  | ||||||
|  *    documentation and/or other materials provided with the distribution. |  | ||||||
|  * 3. Neither the name of the Institute nor the names of its contributors |  | ||||||
|  *    may be used to endorse or promote products derived from this software |  | ||||||
|  *    without specific prior written permission. |  | ||||||
|  * |  | ||||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND |  | ||||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |  | ||||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |  | ||||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE |  | ||||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |  | ||||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |  | ||||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |  | ||||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |  | ||||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |  | ||||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |  | ||||||
|  * SUCH DAMAGE. |  | ||||||
|  * |  | ||||||
|  * This file is part of the uIP TCP/IP stack |  | ||||||
|  * |  | ||||||
|  * Author: Adam Dunkels <adam@sics.se> |  | ||||||
|  * |  | ||||||
|  * $Id: psock.h,v 1.3 2006/06/12 08:00:30 adam Exp $ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \defgroup psock Protosockets library |  | ||||||
|  * @{ |  | ||||||
|  * |  | ||||||
|  * The protosocket library provides an interface to the uIP stack that is |  | ||||||
|  * similar to the traditional BSD socket interface. Unlike programs |  | ||||||
|  * written for the ordinary uIP event-driven interface, programs |  | ||||||
|  * written with the protosocket library are executed in a sequential |  | ||||||
|  * fashion and does not have to be implemented as explicit state |  | ||||||
|  * machines. |  | ||||||
|  * |  | ||||||
|  * Protosockets only work with TCP connections. |  | ||||||
|  * |  | ||||||
|  * The protosocket library uses \ref pt protothreads to provide |  | ||||||
|  * sequential control flow. This makes the protosockets lightweight in |  | ||||||
|  * terms of memory, but also means that protosockets inherits the |  | ||||||
|  * functional limitations of protothreads. Each protosocket lives only |  | ||||||
|  * within a single function. Automatic variables (stack variables) are |  | ||||||
|  * not retained across a protosocket library function call. |  | ||||||
|  * |  | ||||||
|  * \note Because the protosocket library uses protothreads, local |  | ||||||
|  * variables will not always be saved across a call to a protosocket |  | ||||||
|  * library function. It is therefore advised that local variables are |  | ||||||
|  * used with extreme care. |  | ||||||
|  * |  | ||||||
|  * The protosocket library provides functions for sending data without |  | ||||||
|  * having to deal with retransmissions and acknowledgements, as well |  | ||||||
|  * as functions for reading data without having to deal with data |  | ||||||
|  * being split across more than one TCP segment. |  | ||||||
|  * |  | ||||||
|  * Because each protosocket runs as a protothread, the protosocket has to be |  | ||||||
|  * started with a call to PSOCK_BEGIN() at the start of the function |  | ||||||
|  * in which the protosocket is used. Similarly, the protosocket protothread can |  | ||||||
|  * be terminated by a call to PSOCK_EXIT(). |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \file |  | ||||||
|  * Protosocket library header file |  | ||||||
|  * \author |  | ||||||
|  * Adam Dunkels <adam@sics.se> |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #ifndef __PSOCK_H__ |  | ||||||
| #define __PSOCK_H__ |  | ||||||
| 
 |  | ||||||
| #include "uipopt.h" |  | ||||||
| #include "pt.h" |  | ||||||
| 
 |  | ||||||
|  /*
 |  | ||||||
|  * The structure that holds the state of a buffer. |  | ||||||
|  * |  | ||||||
|  * This structure holds the state of a uIP buffer. The structure has |  | ||||||
|  * no user-visible elements, but is used through the functions |  | ||||||
|  * provided by the library. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| struct psock_buf { |  | ||||||
|   u8_t *ptr; |  | ||||||
|   unsigned short left; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * The representation of a protosocket. |  | ||||||
|  * |  | ||||||
|  * The protosocket structrure is an opaque structure with no user-visible |  | ||||||
|  * elements. |  | ||||||
|  */ |  | ||||||
| struct psock { |  | ||||||
|   struct pt pt, psockpt; /* Protothreads - one that's using the psock
 |  | ||||||
| 			    functions, and one that runs inside the |  | ||||||
| 			    psock functions. */ |  | ||||||
|   const u8_t *sendptr;   /* Pointer to the next data to be sent. */ |  | ||||||
|   u8_t *readptr;         /* Pointer to the next data to be read. */ |  | ||||||
|    |  | ||||||
|   char *bufptr;          /* Pointer to the buffer used for buffering
 |  | ||||||
| 			    incoming data. */ |  | ||||||
|    |  | ||||||
|   u16_t sendlen;         /* The number of bytes left to be sent. */ |  | ||||||
|   u16_t readlen;         /* The number of bytes left to be read. */ |  | ||||||
| 
 |  | ||||||
|   struct psock_buf buf;  /* The structure holding the state of the
 |  | ||||||
| 			    input buffer. */ |  | ||||||
|   unsigned int bufsize;  /* The size of the input buffer. */ |  | ||||||
|    |  | ||||||
|   unsigned char state;   /* The state of the protosocket. */ |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| void psock_init(struct psock *psock, char *buffer, unsigned int buffersize); |  | ||||||
| /**
 |  | ||||||
|  * Initialize a protosocket. |  | ||||||
|  * |  | ||||||
|  * This macro initializes a protosocket and must be called before the |  | ||||||
|  * protosocket is used. The initialization also specifies the input buffer |  | ||||||
|  * for the protosocket. |  | ||||||
|  * |  | ||||||
|  * \param psock (struct psock *) A pointer to the protosocket to be |  | ||||||
|  * initialized |  | ||||||
|  * |  | ||||||
|  * \param buffer (char *) A pointer to the input buffer for the |  | ||||||
|  * protosocket. |  | ||||||
|  * |  | ||||||
|  * \param buffersize (unsigned int) The size of the input buffer. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PSOCK_INIT(psock, buffer, buffersize) \ |  | ||||||
|   psock_init(psock, buffer, buffersize) |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Start the protosocket protothread in a function. |  | ||||||
|  * |  | ||||||
|  * This macro starts the protothread associated with the protosocket and |  | ||||||
|  * must come before other protosocket calls in the function it is used. |  | ||||||
|  * |  | ||||||
|  * \param psock (struct psock *) A pointer to the protosocket to be |  | ||||||
|  * started. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PSOCK_BEGIN(psock) PT_BEGIN(&((psock)->pt)) |  | ||||||
| 
 |  | ||||||
| PT_THREAD(psock_send(struct psock *psock, const char *buf, unsigned int len)); |  | ||||||
| /**
 |  | ||||||
|  * Send data. |  | ||||||
|  * |  | ||||||
|  * This macro sends data over a protosocket. The protosocket protothread blocks |  | ||||||
|  * until all data has been sent and is known to have been received by |  | ||||||
|  * the remote end of the TCP connection. |  | ||||||
|  * |  | ||||||
|  * \param psock (struct psock *) A pointer to the protosocket over which |  | ||||||
|  * data is to be sent. |  | ||||||
|  * |  | ||||||
|  * \param data (char *) A pointer to the data that is to be sent. |  | ||||||
|  * |  | ||||||
|  * \param datalen (unsigned int) The length of the data that is to be |  | ||||||
|  * sent. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PSOCK_SEND(psock, data, datalen)		\ |  | ||||||
|     PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, data, datalen)) |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \brief      Send a null-terminated string. |  | ||||||
|  * \param psock Pointer to the protosocket. |  | ||||||
|  * \param str  The string to be sent. |  | ||||||
|  * |  | ||||||
|  *             This function sends a null-terminated string over the |  | ||||||
|  *             protosocket. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PSOCK_SEND_STR(psock, str)      		\ |  | ||||||
|     PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, str, strlen(str))) |  | ||||||
| 
 |  | ||||||
| PT_THREAD(psock_generator_send(struct psock *psock, |  | ||||||
| 				unsigned short (*f)(void *), void *arg)); |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \brief      Generate data with a function and send it |  | ||||||
|  * \param psock Pointer to the protosocket. |  | ||||||
|  * \param generator Pointer to the generator function |  | ||||||
|  * \param arg   Argument to the generator function |  | ||||||
|  * |  | ||||||
|  *             This function generates data and sends it over the |  | ||||||
|  *             protosocket. This can be used to dynamically generate |  | ||||||
|  *             data for a transmission, instead of generating the data |  | ||||||
|  *             in a buffer beforehand. This function reduces the need for |  | ||||||
|  *             buffer memory. The generator function is implemented by |  | ||||||
|  *             the application, and a pointer to the function is given |  | ||||||
|  *             as an argument with the call to PSOCK_GENERATOR_SEND(). |  | ||||||
|  * |  | ||||||
|  *             The generator function should place the generated data |  | ||||||
|  *             directly in the uip_appdata buffer, and return the |  | ||||||
|  *             length of the generated data. The generator function is |  | ||||||
|  *             called by the protosocket layer when the data first is |  | ||||||
|  *             sent, and once for every retransmission that is needed. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PSOCK_GENERATOR_SEND(psock, generator, arg)     \ |  | ||||||
|     PT_WAIT_THREAD(&((psock)->pt),					\ |  | ||||||
| 		   psock_generator_send(psock, generator, arg)) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Close a protosocket. |  | ||||||
|  * |  | ||||||
|  * This macro closes a protosocket and can only be called from within the |  | ||||||
|  * protothread in which the protosocket lives. |  | ||||||
|  * |  | ||||||
|  * \param psock (struct psock *) A pointer to the protosocket that is to |  | ||||||
|  * be closed. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PSOCK_CLOSE(psock) uip_close() |  | ||||||
| 
 |  | ||||||
| PT_THREAD(psock_readbuf(struct psock *psock)); |  | ||||||
| /**
 |  | ||||||
|  * Read data until the buffer is full. |  | ||||||
|  * |  | ||||||
|  * This macro will block waiting for data and read the data into the |  | ||||||
|  * input buffer specified with the call to PSOCK_INIT(). Data is read |  | ||||||
|  * until the buffer is full.. |  | ||||||
|  * |  | ||||||
|  * \param psock (struct psock *) A pointer to the protosocket from which |  | ||||||
|  * data should be read. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PSOCK_READBUF(psock)				\ |  | ||||||
|   PT_WAIT_THREAD(&((psock)->pt), psock_readbuf(psock)) |  | ||||||
| 
 |  | ||||||
| PT_THREAD(psock_readto(struct psock *psock, unsigned char c)); |  | ||||||
| /**
 |  | ||||||
|  * Read data up to a specified character. |  | ||||||
|  * |  | ||||||
|  * This macro will block waiting for data and read the data into the |  | ||||||
|  * input buffer specified with the call to PSOCK_INIT(). Data is only |  | ||||||
|  * read until the specifieed character appears in the data stream. |  | ||||||
|  * |  | ||||||
|  * \param psock (struct psock *) A pointer to the protosocket from which |  | ||||||
|  * data should be read. |  | ||||||
|  * |  | ||||||
|  * \param c (char) The character at which to stop reading. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PSOCK_READTO(psock, c)				\ |  | ||||||
|   PT_WAIT_THREAD(&((psock)->pt), psock_readto(psock, c)) |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * The length of the data that was previously read. |  | ||||||
|  * |  | ||||||
|  * This macro returns the length of the data that was previously read |  | ||||||
|  * using PSOCK_READTO() or PSOCK_READ(). |  | ||||||
|  * |  | ||||||
|  * \param psock (struct psock *) A pointer to the protosocket holding the data. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PSOCK_DATALEN(psock) psock_datalen(psock) |  | ||||||
| 
 |  | ||||||
| u16_t psock_datalen(struct psock *psock); |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Exit the protosocket's protothread. |  | ||||||
|  * |  | ||||||
|  * This macro terminates the protothread of the protosocket and should |  | ||||||
|  * almost always be used in conjunction with PSOCK_CLOSE(). |  | ||||||
|  * |  | ||||||
|  * \sa PSOCK_CLOSE_EXIT() |  | ||||||
|  * |  | ||||||
|  * \param psock (struct psock *) A pointer to the protosocket. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PSOCK_EXIT(psock) PT_EXIT(&((psock)->pt)) |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Close a protosocket and exit the protosocket's protothread. |  | ||||||
|  * |  | ||||||
|  * This macro closes a protosocket and exits the protosocket's protothread. |  | ||||||
|  * |  | ||||||
|  * \param psock (struct psock *) A pointer to the protosocket. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PSOCK_CLOSE_EXIT(psock)		\ |  | ||||||
|   do {						\ |  | ||||||
|     PSOCK_CLOSE(psock);			\ |  | ||||||
|     PSOCK_EXIT(psock);			\ |  | ||||||
|   } while(0) |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Declare the end of a protosocket's protothread. |  | ||||||
|  * |  | ||||||
|  * This macro is used for declaring that the protosocket's protothread |  | ||||||
|  * ends. It must always be used together with a matching PSOCK_BEGIN() |  | ||||||
|  * macro. |  | ||||||
|  * |  | ||||||
|  * \param psock (struct psock *) A pointer to the protosocket. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PSOCK_END(psock) PT_END(&((psock)->pt)) |  | ||||||
| 
 |  | ||||||
| char psock_newdata(struct psock *s); |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Check if new data has arrived on a protosocket. |  | ||||||
|  * |  | ||||||
|  * This macro is used in conjunction with the PSOCK_WAIT_UNTIL() |  | ||||||
|  * macro to check if data has arrived on a protosocket. |  | ||||||
|  * |  | ||||||
|  * \param psock (struct psock *) A pointer to the protosocket. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PSOCK_NEWDATA(psock) psock_newdata(psock) |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Wait until a condition is true. |  | ||||||
|  * |  | ||||||
|  * This macro blocks the protothread until the specified condition is |  | ||||||
|  * true. The macro PSOCK_NEWDATA() can be used to check if new data |  | ||||||
|  * arrives when the protosocket is waiting. |  | ||||||
|  * |  | ||||||
|  * Typically, this macro is used as follows: |  | ||||||
|  * |  | ||||||
|  \code |  | ||||||
|  PT_THREAD(thread(struct psock *s, struct timer *t)) |  | ||||||
|  { |  | ||||||
|    PSOCK_BEGIN(s); |  | ||||||
| 
 |  | ||||||
|    PSOCK_WAIT_UNTIL(s, PSOCK_NEWADATA(s) || timer_expired(t)); |  | ||||||
|     |  | ||||||
|    if(PSOCK_NEWDATA(s)) { |  | ||||||
|      PSOCK_READTO(s, '\n'); |  | ||||||
|    } else { |  | ||||||
|      handle_timed_out(s); |  | ||||||
|    } |  | ||||||
|     |  | ||||||
|    PSOCK_END(s); |  | ||||||
|  } |  | ||||||
|  \endcode |  | ||||||
|  * |  | ||||||
|  * \param psock (struct psock *) A pointer to the protosocket. |  | ||||||
|  * \param condition The condition to wait for. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PSOCK_WAIT_UNTIL(psock, condition)    \ |  | ||||||
|   PT_WAIT_UNTIL(&((psock)->pt), (condition)); |  | ||||||
| 
 |  | ||||||
| #define PSOCK_WAIT_THREAD(psock, condition)   \ |  | ||||||
|   PT_WAIT_THREAD(&((psock)->pt), (condition)) |  | ||||||
| 
 |  | ||||||
| #endif /* __PSOCK_H__ */ |  | ||||||
| 
 |  | ||||||
| /** @} */ |  | ||||||
| @ -1,323 +0,0 @@ | |||||||
| /*
 |  | ||||||
|  * Copyright (c) 2004-2005, Swedish Institute of Computer Science. |  | ||||||
|  * All rights reserved. |  | ||||||
|  * |  | ||||||
|  * Redistribution and use in source and binary forms, with or without |  | ||||||
|  * modification, are permitted provided that the following conditions |  | ||||||
|  * are met: |  | ||||||
|  * 1. Redistributions of source code must retain the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer. |  | ||||||
|  * 2. Redistributions in binary form must reproduce the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer in the |  | ||||||
|  *    documentation and/or other materials provided with the distribution. |  | ||||||
|  * 3. Neither the name of the Institute nor the names of its contributors |  | ||||||
|  *    may be used to endorse or promote products derived from this software |  | ||||||
|  *    without specific prior written permission. |  | ||||||
|  * |  | ||||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND |  | ||||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |  | ||||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |  | ||||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE |  | ||||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |  | ||||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |  | ||||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |  | ||||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |  | ||||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |  | ||||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |  | ||||||
|  * SUCH DAMAGE. |  | ||||||
|  * |  | ||||||
|  * This file is part of the uIP TCP/IP stack |  | ||||||
|  * |  | ||||||
|  * Author: Adam Dunkels <adam@sics.se> |  | ||||||
|  * |  | ||||||
|  * $Id: pt.h,v 1.2 2006/06/12 08:00:30 adam Exp $ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \addtogroup pt |  | ||||||
|  * @{ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \file |  | ||||||
|  * Protothreads implementation. |  | ||||||
|  * \author |  | ||||||
|  * Adam Dunkels <adam@sics.se> |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #ifndef __PT_H__ |  | ||||||
| #define __PT_H__ |  | ||||||
| 
 |  | ||||||
| #include "lc.h" |  | ||||||
| 
 |  | ||||||
| struct pt { |  | ||||||
|   lc_t lc; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| #define PT_WAITING 0 |  | ||||||
| #define PT_EXITED  1 |  | ||||||
| #define PT_ENDED   2 |  | ||||||
| #define PT_YIELDED 3 |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \name Initialization |  | ||||||
|  * @{ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Initialize a protothread. |  | ||||||
|  * |  | ||||||
|  * Initializes a protothread. Initialization must be done prior to |  | ||||||
|  * starting to execute the protothread. |  | ||||||
|  * |  | ||||||
|  * \param pt A pointer to the protothread control structure. |  | ||||||
|  * |  | ||||||
|  * \sa PT_SPAWN() |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PT_INIT(pt)   LC_INIT((pt)->lc) |  | ||||||
| 
 |  | ||||||
| /** @} */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \name Declaration and definition |  | ||||||
|  * @{ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Declaration of a protothread. |  | ||||||
|  * |  | ||||||
|  * This macro is used to declare a protothread. All protothreads must |  | ||||||
|  * be declared with this macro. |  | ||||||
|  * |  | ||||||
|  * \param name_args The name and arguments of the C function |  | ||||||
|  * implementing the protothread. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PT_THREAD(name_args) char name_args |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Declare the start of a protothread inside the C function |  | ||||||
|  * implementing the protothread. |  | ||||||
|  * |  | ||||||
|  * This macro is used to declare the starting point of a |  | ||||||
|  * protothread. It should be placed at the start of the function in |  | ||||||
|  * which the protothread runs. All C statements above the PT_BEGIN() |  | ||||||
|  * invokation will be executed each time the protothread is scheduled. |  | ||||||
|  * |  | ||||||
|  * \param pt A pointer to the protothread control structure. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc) |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Declare the end of a protothread. |  | ||||||
|  * |  | ||||||
|  * This macro is used for declaring that a protothread ends. It must |  | ||||||
|  * always be used together with a matching PT_BEGIN() macro. |  | ||||||
|  * |  | ||||||
|  * \param pt A pointer to the protothread control structure. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \ |  | ||||||
|                    PT_INIT(pt); return PT_ENDED; } |  | ||||||
| 
 |  | ||||||
| /** @} */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \name Blocked wait |  | ||||||
|  * @{ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Block and wait until condition is true. |  | ||||||
|  * |  | ||||||
|  * This macro blocks the protothread until the specified condition is |  | ||||||
|  * true. |  | ||||||
|  * |  | ||||||
|  * \param pt A pointer to the protothread control structure. |  | ||||||
|  * \param condition The condition. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PT_WAIT_UNTIL(pt, condition)	        \ |  | ||||||
|   do {						\ |  | ||||||
|     LC_SET((pt)->lc);				\ |  | ||||||
|     if(!(condition)) {				\ |  | ||||||
|       return PT_WAITING;			\ |  | ||||||
|     }						\ |  | ||||||
|   } while(0) |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Block and wait while condition is true. |  | ||||||
|  * |  | ||||||
|  * This function blocks and waits while condition is true. See |  | ||||||
|  * PT_WAIT_UNTIL(). |  | ||||||
|  * |  | ||||||
|  * \param pt A pointer to the protothread control structure. |  | ||||||
|  * \param cond The condition. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PT_WAIT_WHILE(pt, cond)  PT_WAIT_UNTIL((pt), !(cond)) |  | ||||||
| 
 |  | ||||||
| /** @} */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \name Hierarchical protothreads |  | ||||||
|  * @{ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Block and wait until a child protothread completes. |  | ||||||
|  * |  | ||||||
|  * This macro schedules a child protothread. The current protothread |  | ||||||
|  * will block until the child protothread completes. |  | ||||||
|  * |  | ||||||
|  * \note The child protothread must be manually initialized with the |  | ||||||
|  * PT_INIT() function before this function is used. |  | ||||||
|  * |  | ||||||
|  * \param pt A pointer to the protothread control structure. |  | ||||||
|  * \param thread The child protothread with arguments |  | ||||||
|  * |  | ||||||
|  * \sa PT_SPAWN() |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread)) |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Spawn a child protothread and wait until it exits. |  | ||||||
|  * |  | ||||||
|  * This macro spawns a child protothread and waits until it exits. The |  | ||||||
|  * macro can only be used within a protothread. |  | ||||||
|  * |  | ||||||
|  * \param pt A pointer to the protothread control structure. |  | ||||||
|  * \param child A pointer to the child protothread's control structure. |  | ||||||
|  * \param thread The child protothread with arguments |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PT_SPAWN(pt, child, thread)		\ |  | ||||||
|   do {						\ |  | ||||||
|     PT_INIT((child));				\ |  | ||||||
|     PT_WAIT_THREAD((pt), (thread));		\ |  | ||||||
|   } while(0) |  | ||||||
| 
 |  | ||||||
| /** @} */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \name Exiting and restarting |  | ||||||
|  * @{ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Restart the protothread. |  | ||||||
|  * |  | ||||||
|  * This macro will block and cause the running protothread to restart |  | ||||||
|  * its execution at the place of the PT_BEGIN() call. |  | ||||||
|  * |  | ||||||
|  * \param pt A pointer to the protothread control structure. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PT_RESTART(pt)				\ |  | ||||||
|   do {						\ |  | ||||||
|     PT_INIT(pt);				\ |  | ||||||
|     return PT_WAITING;			\ |  | ||||||
|   } while(0) |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Exit the protothread. |  | ||||||
|  * |  | ||||||
|  * This macro causes the protothread to exit. If the protothread was |  | ||||||
|  * spawned by another protothread, the parent protothread will become |  | ||||||
|  * unblocked and can continue to run. |  | ||||||
|  * |  | ||||||
|  * \param pt A pointer to the protothread control structure. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PT_EXIT(pt)				\ |  | ||||||
|   do {						\ |  | ||||||
|     PT_INIT(pt);				\ |  | ||||||
|     return PT_EXITED;			\ |  | ||||||
|   } while(0) |  | ||||||
| 
 |  | ||||||
| /** @} */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \name Calling a protothread |  | ||||||
|  * @{ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Schedule a protothread. |  | ||||||
|  * |  | ||||||
|  * This function shedules a protothread. The return value of the |  | ||||||
|  * function is non-zero if the protothread is running or zero if the |  | ||||||
|  * protothread has exited. |  | ||||||
|  * |  | ||||||
|  * \param f The call to the C function implementing the protothread to |  | ||||||
|  * be scheduled |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PT_SCHEDULE(f) ((f) == PT_WAITING) |  | ||||||
| 
 |  | ||||||
| /** @} */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \name Yielding from a protothread |  | ||||||
|  * @{ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Yield from the current protothread. |  | ||||||
|  * |  | ||||||
|  * This function will yield the protothread, thereby allowing other |  | ||||||
|  * processing to take place in the system. |  | ||||||
|  * |  | ||||||
|  * \param pt A pointer to the protothread control structure. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PT_YIELD(pt)				\ |  | ||||||
|   do {						\ |  | ||||||
|     PT_YIELD_FLAG = 0;				\ |  | ||||||
|     LC_SET((pt)->lc);				\ |  | ||||||
|     if(PT_YIELD_FLAG == 0) {			\ |  | ||||||
|       return PT_YIELDED;			\ |  | ||||||
|     }						\ |  | ||||||
|   } while(0) |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \brief      Yield from the protothread until a condition occurs. |  | ||||||
|  * \param pt   A pointer to the protothread control structure. |  | ||||||
|  * \param cond The condition. |  | ||||||
|  * |  | ||||||
|  *             This function will yield the protothread, until the |  | ||||||
|  *             specified condition evaluates to true. |  | ||||||
|  * |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define PT_YIELD_UNTIL(pt, cond)		\ |  | ||||||
|   do {						\ |  | ||||||
|     PT_YIELD_FLAG = 0;				\ |  | ||||||
|     LC_SET((pt)->lc);				\ |  | ||||||
|     if((PT_YIELD_FLAG == 0) || !(cond)) {	\ |  | ||||||
|       return PT_YIELDED;			\ |  | ||||||
|     }						\ |  | ||||||
|   } while(0) |  | ||||||
| 
 |  | ||||||
| /** @} */ |  | ||||||
| 
 |  | ||||||
| #endif /* __PT_H__ */ |  | ||||||
| 
 |  | ||||||
| /** @} */ |  | ||||||
| @ -1,532 +0,0 @@ | |||||||
| /*
 |  | ||||||
|  * Copyright (c) 2004, Swedish Institute of Computer Science. |  | ||||||
|  * All rights reserved. |  | ||||||
|  * |  | ||||||
|  * Redistribution and use in source and binary forms, with or without |  | ||||||
|  * modification, are permitted provided that the following conditions |  | ||||||
|  * are met: |  | ||||||
|  * 1. Redistributions of source code must retain the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer. |  | ||||||
|  * 2. Redistributions in binary form must reproduce the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer in the |  | ||||||
|  *    documentation and/or other materials provided with the distribution. |  | ||||||
|  * 3. Neither the name of the Institute nor the names of its contributors |  | ||||||
|  *    may be used to endorse or promote products derived from this software |  | ||||||
|  *    without specific prior written permission. |  | ||||||
|  * |  | ||||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND |  | ||||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |  | ||||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |  | ||||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE |  | ||||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |  | ||||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |  | ||||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |  | ||||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |  | ||||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |  | ||||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |  | ||||||
|  * SUCH DAMAGE. |  | ||||||
|  * |  | ||||||
|  * This file is part of the uIP TCP/IP stack |  | ||||||
|  * |  | ||||||
|  * Author: Adam Dunkels <adam@sics.se> |  | ||||||
|  * |  | ||||||
|  * $Id: uip-fw.c,v 1.2 2006/06/12 08:00:30 adam Exp $ |  | ||||||
|  */ |  | ||||||
| /**
 |  | ||||||
|  * \addtogroup uip |  | ||||||
|  * @{ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \defgroup uipfw uIP packet forwarding |  | ||||||
|  * @{ |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \file |  | ||||||
|  * uIP packet forwarding. |  | ||||||
|  * \author Adam Dunkels <adam@sics.se> |  | ||||||
|  * |  | ||||||
|  * This file implements a number of simple functions which do packet |  | ||||||
|  * forwarding over multiple network interfaces with uIP. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #include "uip.h" |  | ||||||
| #include "uip_arch.h" |  | ||||||
| #include "uip-fw.h" |  | ||||||
| 
 |  | ||||||
| #include <string.h> /* for memcpy() */ |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * The list of registered network interfaces. |  | ||||||
|  */ |  | ||||||
| static struct uip_fw_netif *netifs = NULL; |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * A pointer to the default network interface. |  | ||||||
|  */ |  | ||||||
| static struct uip_fw_netif *defaultnetif = NULL; |  | ||||||
| 
 |  | ||||||
| struct tcpip_hdr { |  | ||||||
|   /* IP header. */ |  | ||||||
|   u8_t vhl, |  | ||||||
|     tos; |  | ||||||
|   u16_t len, |  | ||||||
|     ipid, |  | ||||||
|     ipoffset; |  | ||||||
|   u8_t ttl, |  | ||||||
|     proto; |  | ||||||
|   u16_t ipchksum; |  | ||||||
|   u16_t srcipaddr[2], |  | ||||||
|     destipaddr[2]; |  | ||||||
|    |  | ||||||
|   /* TCP header. */ |  | ||||||
|   u16_t srcport, |  | ||||||
|     destport; |  | ||||||
|   u8_t seqno[4], |  | ||||||
|     ackno[4], |  | ||||||
|     tcpoffset, |  | ||||||
|     flags, |  | ||||||
|     wnd[2]; |  | ||||||
|   u16_t tcpchksum; |  | ||||||
|   u8_t urgp[2]; |  | ||||||
|   u8_t optdata[4]; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct icmpip_hdr { |  | ||||||
|   /* IP header. */ |  | ||||||
|   u8_t vhl, |  | ||||||
|     tos, |  | ||||||
|     len[2], |  | ||||||
|     ipid[2], |  | ||||||
|     ipoffset[2], |  | ||||||
|     ttl, |  | ||||||
|     proto; |  | ||||||
|   u16_t ipchksum; |  | ||||||
|   u16_t srcipaddr[2], |  | ||||||
|     destipaddr[2]; |  | ||||||
|   /* ICMP (echo) header. */ |  | ||||||
|   u8_t type, icode; |  | ||||||
|   u16_t icmpchksum; |  | ||||||
|   u16_t id, seqno; |  | ||||||
|   u8_t payload[1]; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /* ICMP ECHO. */ |  | ||||||
| #define ICMP_ECHO 8 |  | ||||||
| 
 |  | ||||||
| /* ICMP TIME-EXCEEDED. */ |  | ||||||
| #define ICMP_TE 11 |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * Pointer to the TCP/IP headers of the packet in the uip_buf buffer. |  | ||||||
|  */ |  | ||||||
| #define BUF ((struct tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * Pointer to the ICMP/IP headers of the packet in the uip_buf buffer. |  | ||||||
|  */ |  | ||||||
| #define ICMPBUF ((struct icmpip_hdr *)&uip_buf[UIP_LLH_LEN]) |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * Certain fields of an IP packet that are used for identifying |  | ||||||
|  * duplicate packets. |  | ||||||
|  */ |  | ||||||
| struct fwcache_entry { |  | ||||||
|   u16_t timer; |  | ||||||
|    |  | ||||||
|   u16_t srcipaddr[2]; |  | ||||||
|   u16_t destipaddr[2]; |  | ||||||
|   u16_t ipid; |  | ||||||
|   u8_t proto; |  | ||||||
|   u8_t unused; |  | ||||||
| 
 |  | ||||||
| #if notdef |  | ||||||
|   u16_t payload[2]; |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| #if UIP_REASSEMBLY > 0 |  | ||||||
|   u16_t len, offset; |  | ||||||
| #endif |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * The number of packets to remember when looking for duplicates. |  | ||||||
|  */ |  | ||||||
| #ifdef UIP_CONF_FWCACHE_SIZE |  | ||||||
| #define FWCACHE_SIZE UIP_CONF_FWCACHE_SIZE |  | ||||||
| #else |  | ||||||
| #define FWCACHE_SIZE 2 |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * A cache of packet header fields which are used for |  | ||||||
|  * identifying duplicate packets. |  | ||||||
|  */ |  | ||||||
| static struct fwcache_entry fwcache[FWCACHE_SIZE]; |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \internal |  | ||||||
|  * The time that a packet cache is active. |  | ||||||
|  */ |  | ||||||
| #define FW_TIME 20 |  | ||||||
| 
 |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| /**
 |  | ||||||
|  * Initialize the uIP packet forwarding module. |  | ||||||
|  */ |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| void |  | ||||||
| uip_fw_init(void) |  | ||||||
| { |  | ||||||
|   struct uip_fw_netif *t; |  | ||||||
|   defaultnetif = NULL; |  | ||||||
|   while(netifs != NULL) { |  | ||||||
|     t = netifs; |  | ||||||
|     netifs = netifs->next; |  | ||||||
|     t->next = NULL; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| /**
 |  | ||||||
|  * \internal |  | ||||||
|  * Check if an IP address is within the network defined by an IP |  | ||||||
|  * address and a netmask. |  | ||||||
|  * |  | ||||||
|  * \param ipaddr The IP address to be checked. |  | ||||||
|  * \param netipaddr The IP address of the network. |  | ||||||
|  * \param netmask The netmask of the network. |  | ||||||
|  * |  | ||||||
|  * \return Non-zero if IP address is in network, zero otherwise. |  | ||||||
|  */ |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| static unsigned char |  | ||||||
| ipaddr_maskcmp(u16_t *ipaddr, u16_t *netipaddr, u16_t *netmask) |  | ||||||
| { |  | ||||||
|   return (ipaddr[0] & netmask [0]) == (netipaddr[0] & netmask[0]) && |  | ||||||
|     (ipaddr[1] & netmask[1]) == (netipaddr[1] & netmask[1]); |  | ||||||
| } |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| /**
 |  | ||||||
|  * \internal |  | ||||||
|  * Send out an ICMP TIME-EXCEEDED message. |  | ||||||
|  * |  | ||||||
|  * This function replaces the packet in the uip_buf buffer with the |  | ||||||
|  * ICMP packet. |  | ||||||
|  */ |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| static void |  | ||||||
| time_exceeded(void) |  | ||||||
| { |  | ||||||
|   u16_t tmp16; |  | ||||||
| 
 |  | ||||||
|   /* We don't send out ICMP errors for ICMP messages. */ |  | ||||||
|   if(ICMPBUF->proto == UIP_PROTO_ICMP) { |  | ||||||
|     uip_len = 0; |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|   /* Copy fields from packet header into payload of this ICMP packet. */ |  | ||||||
|   memcpy(&(ICMPBUF->payload[0]), ICMPBUF, 28); |  | ||||||
| 
 |  | ||||||
|   /* Set the ICMP type and code. */ |  | ||||||
|   ICMPBUF->type = ICMP_TE; |  | ||||||
|   ICMPBUF->icode = 0; |  | ||||||
| 
 |  | ||||||
|   /* Calculate the ICMP checksum. */ |  | ||||||
|   ICMPBUF->icmpchksum = 0; |  | ||||||
|   ICMPBUF->icmpchksum = ~uip_chksum((u16_t *)&(ICMPBUF->type), 36); |  | ||||||
| 
 |  | ||||||
|   /* Set the IP destination address to be the source address of the
 |  | ||||||
|      original packet. */ |  | ||||||
|   tmp16= BUF->destipaddr[0]; |  | ||||||
|   BUF->destipaddr[0] = BUF->srcipaddr[0]; |  | ||||||
|   BUF->srcipaddr[0] = tmp16; |  | ||||||
|   tmp16 = BUF->destipaddr[1]; |  | ||||||
|   BUF->destipaddr[1] = BUF->srcipaddr[1]; |  | ||||||
|   BUF->srcipaddr[1] = tmp16; |  | ||||||
| 
 |  | ||||||
|   /* Set our IP address as the source address. */ |  | ||||||
|   BUF->srcipaddr[0] = uip_hostaddr[0]; |  | ||||||
|   BUF->srcipaddr[1] = uip_hostaddr[1]; |  | ||||||
| 
 |  | ||||||
|   /* The size of the ICMP time exceeded packet is 36 + the size of the
 |  | ||||||
|      IP header (20) = 56. */ |  | ||||||
|   uip_len = 56; |  | ||||||
|   ICMPBUF->len[0] = 0; |  | ||||||
|   ICMPBUF->len[1] = uip_len; |  | ||||||
| 
 |  | ||||||
|   /* Fill in the other fields in the IP header. */ |  | ||||||
|   ICMPBUF->vhl = 0x45; |  | ||||||
|   ICMPBUF->tos = 0; |  | ||||||
|   ICMPBUF->ipoffset[0] = ICMPBUF->ipoffset[1] = 0; |  | ||||||
|   ICMPBUF->ttl  = UIP_TTL; |  | ||||||
|   ICMPBUF->proto = UIP_PROTO_ICMP; |  | ||||||
|    |  | ||||||
|   /* Calculate IP checksum. */ |  | ||||||
|   ICMPBUF->ipchksum = 0; |  | ||||||
|   ICMPBUF->ipchksum = ~(uip_ipchksum()); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| /**
 |  | ||||||
|  * \internal |  | ||||||
|  * Register a packet in the forwarding cache so that it won't be |  | ||||||
|  * forwarded again. |  | ||||||
|  */ |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| static void |  | ||||||
| fwcache_register(void) |  | ||||||
| { |  | ||||||
|   struct fwcache_entry *fw; |  | ||||||
|   int i, oldest; |  | ||||||
| 
 |  | ||||||
|   oldest = FW_TIME; |  | ||||||
|   fw = NULL; |  | ||||||
|    |  | ||||||
|   /* Find the oldest entry in the cache. */ |  | ||||||
|   for(i = 0; i < FWCACHE_SIZE; ++i) { |  | ||||||
|     if(fwcache[i].timer == 0) { |  | ||||||
|       fw = &fwcache[i]; |  | ||||||
|       break; |  | ||||||
|     } else if(fwcache[i].timer <= oldest) { |  | ||||||
|       fw = &fwcache[i]; |  | ||||||
|       oldest = fwcache[i].timer; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   fw->timer = FW_TIME; |  | ||||||
|   fw->ipid = BUF->ipid; |  | ||||||
|   fw->srcipaddr[0] = BUF->srcipaddr[0]; |  | ||||||
|   fw->srcipaddr[1] = BUF->srcipaddr[1]; |  | ||||||
|   fw->destipaddr[0] = BUF->destipaddr[0]; |  | ||||||
|   fw->destipaddr[1] = BUF->destipaddr[1]; |  | ||||||
|   fw->proto = BUF->proto; |  | ||||||
| #if notdef |  | ||||||
|   fw->payload[0] = BUF->srcport; |  | ||||||
|   fw->payload[1] = BUF->destport; |  | ||||||
| #endif |  | ||||||
| #if UIP_REASSEMBLY > 0 |  | ||||||
|   fw->len = BUF->len; |  | ||||||
|   fw->offset = BUF->ipoffset; |  | ||||||
| #endif |  | ||||||
| } |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| /**
 |  | ||||||
|  * \internal |  | ||||||
|  * Find a network interface for the IP packet in uip_buf. |  | ||||||
|  */ |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| static struct uip_fw_netif * |  | ||||||
| find_netif(void) |  | ||||||
| { |  | ||||||
|   struct uip_fw_netif *netif; |  | ||||||
|    |  | ||||||
|   /* Walk through every network interface to check for a match. */ |  | ||||||
|   for(netif = netifs; netif != NULL; netif = netif->next) { |  | ||||||
|     if(ipaddr_maskcmp(BUF->destipaddr, netif->ipaddr, |  | ||||||
| 		      netif->netmask)) { |  | ||||||
|       /* If there was a match, we break the loop. */ |  | ||||||
|       return netif; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|    |  | ||||||
|   /* If no matching netif was found, we use default netif. */ |  | ||||||
|   return defaultnetif; |  | ||||||
| } |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| /**
 |  | ||||||
|  * Output an IP packet on the correct network interface. |  | ||||||
|  * |  | ||||||
|  * The IP packet should be present in the uip_buf buffer and its |  | ||||||
|  * length in the global uip_len variable. |  | ||||||
|  * |  | ||||||
|  * \retval UIP_FW_ZEROLEN Indicates that a zero-length packet |  | ||||||
|  * transmission was attempted and that no packet was sent. |  | ||||||
|  * |  | ||||||
|  * \retval UIP_FW_NOROUTE No suitable network interface could be found |  | ||||||
|  * for the outbound packet, and the packet was not sent. |  | ||||||
|  * |  | ||||||
|  * \return The return value from the actual network interface output |  | ||||||
|  * function is passed unmodified as a return value. |  | ||||||
|  */ |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| u8_t |  | ||||||
| uip_fw_output(void) |  | ||||||
| { |  | ||||||
|   struct uip_fw_netif *netif; |  | ||||||
| 
 |  | ||||||
|   if(uip_len == 0) { |  | ||||||
|     return UIP_FW_ZEROLEN; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   fwcache_register(); |  | ||||||
| 
 |  | ||||||
| #if UIP_BROADCAST |  | ||||||
|   /* Link local broadcasts go out on all interfaces. */ |  | ||||||
|   if(/*BUF->proto == UIP_PROTO_UDP &&*/ |  | ||||||
|      BUF->destipaddr[0] == 0xffff && |  | ||||||
|      BUF->destipaddr[1] == 0xffff) { |  | ||||||
|     if(defaultnetif != NULL) { |  | ||||||
|       defaultnetif->output(); |  | ||||||
|     } |  | ||||||
|     for(netif = netifs; netif != NULL; netif = netif->next) { |  | ||||||
|       netif->output(); |  | ||||||
|     } |  | ||||||
|     return UIP_FW_OK; |  | ||||||
|   } |  | ||||||
| #endif /* UIP_BROADCAST */ |  | ||||||
|    |  | ||||||
|   netif = find_netif(); |  | ||||||
|   /*  printf("uip_fw_output: netif %p ->output %p len %d\n", netif,
 |  | ||||||
| 	 netif->output, |  | ||||||
| 	 uip_len);*/ |  | ||||||
| 
 |  | ||||||
|   if(netif == NULL) { |  | ||||||
|     return UIP_FW_NOROUTE; |  | ||||||
|   } |  | ||||||
|   /* If we now have found a suitable network interface, we call its
 |  | ||||||
|      output function to send out the packet. */ |  | ||||||
|   return netif->output(); |  | ||||||
| } |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| /**
 |  | ||||||
|  * Forward an IP packet in the uip_buf buffer. |  | ||||||
|  * |  | ||||||
|  * |  | ||||||
|  * |  | ||||||
|  * \return UIP_FW_FORWARDED if the packet was forwarded, UIP_FW_LOCAL if |  | ||||||
|  * the packet should be processed locally. |  | ||||||
|  */ |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| u8_t |  | ||||||
| uip_fw_forward(void) |  | ||||||
| { |  | ||||||
|   struct fwcache_entry *fw; |  | ||||||
| 
 |  | ||||||
|   /* First check if the packet is destined for ourselves and return 0
 |  | ||||||
|      to indicate that the packet should be processed locally. */ |  | ||||||
|   if(BUF->destipaddr[0] == uip_hostaddr[0] && |  | ||||||
|      BUF->destipaddr[1] == uip_hostaddr[1]) { |  | ||||||
|     return UIP_FW_LOCAL; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   /* If we use ping IP address configuration, and our IP address is
 |  | ||||||
|      not yet configured, we should intercept all ICMP echo packets. */ |  | ||||||
| #if UIP_PINGADDRCONF |  | ||||||
|   if((uip_hostaddr[0] | uip_hostaddr[1]) == 0 && |  | ||||||
|      BUF->proto == UIP_PROTO_ICMP && |  | ||||||
|      ICMPBUF->type == ICMP_ECHO) { |  | ||||||
|     return UIP_FW_LOCAL; |  | ||||||
|   } |  | ||||||
| #endif /* UIP_PINGADDRCONF */ |  | ||||||
| 
 |  | ||||||
|   /* Check if the packet is in the forwarding cache already, and if so
 |  | ||||||
|      we drop it. */ |  | ||||||
| 
 |  | ||||||
|   for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) { |  | ||||||
|     if(fw->timer != 0 && |  | ||||||
| #if UIP_REASSEMBLY > 0 |  | ||||||
|        fw->len == BUF->len && |  | ||||||
|        fw->offset == BUF->ipoffset && |  | ||||||
| #endif |  | ||||||
|        fw->ipid == BUF->ipid && |  | ||||||
|        fw->srcipaddr[0] == BUF->srcipaddr[0] && |  | ||||||
|        fw->srcipaddr[1] == BUF->srcipaddr[1] && |  | ||||||
|        fw->destipaddr[0] == BUF->destipaddr[0] && |  | ||||||
|        fw->destipaddr[1] == BUF->destipaddr[1] && |  | ||||||
| #if notdef |  | ||||||
|        fw->payload[0] == BUF->srcport && |  | ||||||
|        fw->payload[1] == BUF->destport && |  | ||||||
| #endif |  | ||||||
|        fw->proto == BUF->proto) { |  | ||||||
|       /* Drop packet. */ |  | ||||||
|       return UIP_FW_FORWARDED; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   /* If the TTL reaches zero we produce an ICMP time exceeded message
 |  | ||||||
|      in the uip_buf buffer and forward that packet back to the sender |  | ||||||
|      of the packet. */ |  | ||||||
|   if(BUF->ttl <= 1) { |  | ||||||
|     /* No time exceeded for broadcasts and multicasts! */ |  | ||||||
|     if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) { |  | ||||||
|       return UIP_FW_LOCAL; |  | ||||||
|     } |  | ||||||
|     time_exceeded(); |  | ||||||
|   } |  | ||||||
|    |  | ||||||
|   /* Decrement the TTL (time-to-live) value in the IP header */ |  | ||||||
|   BUF->ttl = BUF->ttl - 1; |  | ||||||
|    |  | ||||||
|   /* Update the IP checksum. */ |  | ||||||
|   if(BUF->ipchksum >= HTONS(0xffff - 0x0100)) { |  | ||||||
|     BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1; |  | ||||||
|   } else { |  | ||||||
|     BUF->ipchksum = BUF->ipchksum + HTONS(0x0100); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   if(uip_len > 0) { |  | ||||||
|     uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]; |  | ||||||
|     uip_fw_output(); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
| #if UIP_BROADCAST |  | ||||||
|   if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) { |  | ||||||
|     return UIP_FW_LOCAL; |  | ||||||
|   } |  | ||||||
| #endif /* UIP_BROADCAST */ |  | ||||||
| 
 |  | ||||||
|   /* Return non-zero to indicate that the packet was forwarded and that no
 |  | ||||||
|      other processing should be made. */ |  | ||||||
|   return UIP_FW_FORWARDED; |  | ||||||
| } |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| /**
 |  | ||||||
|  * Register a network interface with the forwarding module. |  | ||||||
|  * |  | ||||||
|  * \param netif A pointer to the network interface that is to be |  | ||||||
|  * registered. |  | ||||||
|  */ |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| void |  | ||||||
| uip_fw_register(struct uip_fw_netif *netif) |  | ||||||
| { |  | ||||||
|   netif->next = netifs; |  | ||||||
|   netifs = netif; |  | ||||||
| } |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| /**
 |  | ||||||
|  * Register a default network interface. |  | ||||||
|  * |  | ||||||
|  * All packets that don't go out on any of the other interfaces will |  | ||||||
|  * be routed to the default interface. |  | ||||||
|  * |  | ||||||
|  * \param netif A pointer to the network interface that is to be |  | ||||||
|  * registered. |  | ||||||
|  */ |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| void |  | ||||||
| uip_fw_default(struct uip_fw_netif *netif) |  | ||||||
| { |  | ||||||
|   defaultnetif = netif; |  | ||||||
| } |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| /**
 |  | ||||||
|  * Perform periodic processing. |  | ||||||
|  */ |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| void |  | ||||||
| uip_fw_periodic(void) |  | ||||||
| { |  | ||||||
|   struct fwcache_entry *fw; |  | ||||||
|   for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) { |  | ||||||
|     if(fw->timer > 0) { |  | ||||||
|       --fw->timer; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| /*------------------------------------------------------------------------------*/ |  | ||||||
| @ -1,176 +0,0 @@ | |||||||
| /**
 |  | ||||||
|  * \addtogroup uipfw |  | ||||||
|  * @{ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \file |  | ||||||
|  * uIP packet forwarding header file. |  | ||||||
|  * \author Adam Dunkels <adam@sics.se> |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * Copyright (c) 2004, Swedish Institute of Computer Science. |  | ||||||
|  * All rights reserved. |  | ||||||
|  * |  | ||||||
|  * Redistribution and use in source and binary forms, with or without |  | ||||||
|  * modification, are permitted provided that the following conditions |  | ||||||
|  * are met: |  | ||||||
|  * 1. Redistributions of source code must retain the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer. |  | ||||||
|  * 2. Redistributions in binary form must reproduce the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer in the |  | ||||||
|  *    documentation and/or other materials provided with the distribution. |  | ||||||
|  * 3. Neither the name of the Institute nor the names of its contributors |  | ||||||
|  *    may be used to endorse or promote products derived from this software |  | ||||||
|  *    without specific prior written permission. |  | ||||||
|  * |  | ||||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND |  | ||||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |  | ||||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |  | ||||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE |  | ||||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |  | ||||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |  | ||||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |  | ||||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |  | ||||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |  | ||||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |  | ||||||
|  * SUCH DAMAGE. |  | ||||||
|  * |  | ||||||
|  * This file is part of the uIP TCP/IP stack |  | ||||||
|  * |  | ||||||
|  * Author: Adam Dunkels <adam@sics.se> |  | ||||||
|  * |  | ||||||
|  * $Id: uip-fw.h,v 1.2 2006/06/12 08:00:30 adam Exp $ |  | ||||||
|  */ |  | ||||||
| #ifndef __UIP_FW_H__ |  | ||||||
| #define __UIP_FW_H__ |  | ||||||
| 
 |  | ||||||
| #include "uip.h" |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Representation of a uIP network interface. |  | ||||||
|  */ |  | ||||||
| struct uip_fw_netif { |  | ||||||
|   struct uip_fw_netif *next;  /**< Pointer to the next interface when
 |  | ||||||
| 				 linked in a list. */ |  | ||||||
|   u16_t ipaddr[2];            /**< The IP address of this interface. */ |  | ||||||
|   u16_t netmask[2];           /**< The netmask of the interface. */ |  | ||||||
|   u8_t (* output)(void); |  | ||||||
|                               /**< A pointer to the function that
 |  | ||||||
| 				 sends a packet. */ |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Intantiating macro for a uIP network interface. |  | ||||||
|  * |  | ||||||
|  * Example: |  | ||||||
|  \code |  | ||||||
|  struct uip_fw_netif slipnetif = |  | ||||||
|    {UIP_FW_NETIF(192,168,76,1, 255,255,255,0, slip_output)}; |  | ||||||
|  \endcode |  | ||||||
|  * \param ip1,ip2,ip3,ip4 The IP address of the network interface. |  | ||||||
|  * |  | ||||||
|  * \param nm1,nm2,nm3,nm4 The netmask of the network interface. |  | ||||||
|  * |  | ||||||
|  * \param outputfunc A pointer to the output function of the network interface. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define UIP_FW_NETIF(ip1,ip2,ip3,ip4, nm1,nm2,nm3,nm4, outputfunc) \ |  | ||||||
|         NULL, \ |  | ||||||
| 	{HTONS((ip1 << 8) | ip2), HTONS((ip3 << 8) | ip4)}, \ |  | ||||||
| 	{HTONS((nm1 << 8) | nm2), HTONS((nm3 << 8) | nm4)}, \ |  | ||||||
|         outputfunc |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Set the IP address of a network interface. |  | ||||||
|  * |  | ||||||
|  * \param netif A pointer to the uip_fw_netif structure for the network interface. |  | ||||||
|  * |  | ||||||
|  * \param addr A pointer to an IP address. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define uip_fw_setipaddr(netif, addr) \ |  | ||||||
|         do { (netif)->ipaddr[0] = ((u16_t *)(addr))[0]; \ |  | ||||||
|              (netif)->ipaddr[1] = ((u16_t *)(addr))[1]; } while(0) |  | ||||||
| /**
 |  | ||||||
|  * Set the netmask of a network interface. |  | ||||||
|  * |  | ||||||
|  * \param netif A pointer to the uip_fw_netif structure for the network interface. |  | ||||||
|  * |  | ||||||
|  * \param addr A pointer to an IP address representing the netmask. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define uip_fw_setnetmask(netif, addr) \ |  | ||||||
|         do { (netif)->netmask[0] = ((u16_t *)(addr))[0]; \ |  | ||||||
|              (netif)->netmask[1] = ((u16_t *)(addr))[1]; } while(0) |  | ||||||
| 
 |  | ||||||
| void uip_fw_init(void); |  | ||||||
| u8_t uip_fw_forward(void); |  | ||||||
| u8_t uip_fw_output(void); |  | ||||||
| void uip_fw_register(struct uip_fw_netif *netif); |  | ||||||
| void uip_fw_default(struct uip_fw_netif *netif); |  | ||||||
| void uip_fw_periodic(void); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * A non-error message that indicates that a packet should be |  | ||||||
|  * processed locally. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define UIP_FW_LOCAL     0 |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * A non-error message that indicates that something went OK. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define UIP_FW_OK        0 |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * A non-error message that indicates that a packet was forwarded. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define UIP_FW_FORWARDED 1 |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * A non-error message that indicates that a zero-length packet |  | ||||||
|  * transmission was attempted, and that no packet was sent. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define UIP_FW_ZEROLEN   2 |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * An error message that indicates that a packet that was too large |  | ||||||
|  * for the outbound network interface was detected. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define UIP_FW_TOOLARGE  3 |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * An error message that indicates that no suitable interface could be |  | ||||||
|  * found for an outbound packet. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define UIP_FW_NOROUTE   4 |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * An error message that indicates that a packet that should be |  | ||||||
|  * forwarded or output was dropped. |  | ||||||
|  * |  | ||||||
|  * \hideinitializer |  | ||||||
|  */ |  | ||||||
| #define UIP_FW_DROPPED   5 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| #endif /* __UIP_FW_H__ */ |  | ||||||
| 
 |  | ||||||
| /** @} */ |  | ||||||
| @ -1,158 +0,0 @@ | |||||||
| /*
 |  | ||||||
|  * Copyright (c) 2006, Swedish Institute of Computer Science. |  | ||||||
|  * All rights reserved. |  | ||||||
|  * |  | ||||||
|  * Redistribution and use in source and binary forms, with or without |  | ||||||
|  * modification, are permitted provided that the following conditions |  | ||||||
|  * are met: |  | ||||||
|  * 1. Redistributions of source code must retain the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer. |  | ||||||
|  * 2. Redistributions in binary form must reproduce the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer in the |  | ||||||
|  *    documentation and/or other materials provided with the distribution. |  | ||||||
|  * 3. Neither the name of the Institute nor the names of its contributors |  | ||||||
|  *    may be used to endorse or promote products derived from this software |  | ||||||
|  *    without specific prior written permission. |  | ||||||
|  * |  | ||||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND |  | ||||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |  | ||||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |  | ||||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE |  | ||||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |  | ||||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |  | ||||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |  | ||||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |  | ||||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |  | ||||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |  | ||||||
|  * SUCH DAMAGE. |  | ||||||
|  * |  | ||||||
|  * This file is part of the uIP TCP/IP stack |  | ||||||
|  * |  | ||||||
|  * $Id: uip-neighbor.c,v 1.2 2006/06/12 08:00:30 adam Exp $ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \file |  | ||||||
|  *         Database of link-local neighbors, used by IPv6 code and |  | ||||||
|  *         to be used by a future ARP code rewrite. |  | ||||||
|  * \author |  | ||||||
|  *         Adam Dunkels <adam@sics.se> |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #include "uip-neighbor.h" |  | ||||||
| 
 |  | ||||||
| #include <string.h> |  | ||||||
| 
 |  | ||||||
| #define MAX_TIME 128 |  | ||||||
| 
 |  | ||||||
| #ifdef UIP_NEIGHBOR_CONF_ENTRIES |  | ||||||
| #define ENTRIES UIP_NEIGHBOR_CONF_ENTRIES |  | ||||||
| #else /* UIP_NEIGHBOR_CONF_ENTRIES */ |  | ||||||
| #define ENTRIES 8 |  | ||||||
| #endif /* UIP_NEIGHBOR_CONF_ENTRIES */ |  | ||||||
| 
 |  | ||||||
| struct neighbor_entry { |  | ||||||
|   uip_ipaddr_t ipaddr; |  | ||||||
|   struct uip_neighbor_addr addr; |  | ||||||
|   u8_t time; |  | ||||||
| }; |  | ||||||
| static struct neighbor_entry entries[ENTRIES]; |  | ||||||
| 
 |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| void |  | ||||||
| uip_neighbor_init(void) |  | ||||||
| { |  | ||||||
|   int i; |  | ||||||
| 
 |  | ||||||
|   for(i = 0; i < ENTRIES; ++i) { |  | ||||||
|     entries[i].time = MAX_TIME; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| void |  | ||||||
| uip_neighbor_periodic(void) |  | ||||||
| { |  | ||||||
|   int i; |  | ||||||
| 
 |  | ||||||
|   for(i = 0; i < ENTRIES; ++i) { |  | ||||||
|     if(entries[i].time < MAX_TIME) { |  | ||||||
|       entries[i].time++; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| void |  | ||||||
| uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr) |  | ||||||
| { |  | ||||||
|   int i, oldest; |  | ||||||
|   u8_t oldest_time; |  | ||||||
| 
 |  | ||||||
|   printf("Adding neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n", |  | ||||||
| 	 addr->addr.addr[0], addr->addr.addr[1], addr->addr.addr[2], addr->addr.addr[3], |  | ||||||
| 	 addr->addr.addr[4], addr->addr.addr[5]); |  | ||||||
|    |  | ||||||
|   /* Find the first unused entry or the oldest used entry. */ |  | ||||||
|   oldest_time = 0; |  | ||||||
|   oldest = 0; |  | ||||||
|   for(i = 0; i < ENTRIES; ++i) { |  | ||||||
|     if(entries[i].time == MAX_TIME) { |  | ||||||
|       oldest = i; |  | ||||||
|       break; |  | ||||||
|     } |  | ||||||
|     if(uip_ipaddr_cmp(entries[i].ipaddr, addr)) { |  | ||||||
|       oldest = i; |  | ||||||
|       break; |  | ||||||
|     } |  | ||||||
|     if(entries[i].time > oldest_time) { |  | ||||||
|       oldest = i; |  | ||||||
|       oldest_time = entries[i].time; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   /* Use the oldest or first free entry (either pointed to by the
 |  | ||||||
|      "oldest" variable). */ |  | ||||||
|   entries[oldest].time = 0; |  | ||||||
|   uip_ipaddr_copy(entries[oldest].ipaddr, ipaddr); |  | ||||||
|   memcpy(&entries[oldest].addr, addr, sizeof(struct uip_neighbor_addr)); |  | ||||||
| } |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| static struct neighbor_entry * |  | ||||||
| find_entry(uip_ipaddr_t ipaddr) |  | ||||||
| { |  | ||||||
|   int i; |  | ||||||
|    |  | ||||||
|   for(i = 0; i < ENTRIES; ++i) { |  | ||||||
|     if(uip_ipaddr_cmp(entries[i].ipaddr, ipaddr)) { |  | ||||||
|       return &entries[i]; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   return NULL; |  | ||||||
| } |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| void |  | ||||||
| uip_neighbor_update(uip_ipaddr_t ipaddr) |  | ||||||
| { |  | ||||||
|   struct neighbor_entry *e; |  | ||||||
| 
 |  | ||||||
|   e = find_entry(ipaddr); |  | ||||||
|   if(e != NULL) { |  | ||||||
|     e->time = 0; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| struct uip_neighbor_addr * |  | ||||||
| uip_neighbor_lookup(uip_ipaddr_t ipaddr) |  | ||||||
| { |  | ||||||
|   struct neighbor_entry *e; |  | ||||||
| 
 |  | ||||||
|   e = find_entry(ipaddr); |  | ||||||
|   if(e != NULL) { |  | ||||||
|     /*    printf("Lookup neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n",
 |  | ||||||
| 	   e->addr.addr.addr[0], e->addr.addr.addr[1], e->addr.addr.addr[2], e->addr.addr.addr[3], |  | ||||||
| 	   e->addr.addr.addr[4], e->addr.addr.addr[5]);*/ |  | ||||||
| 
 |  | ||||||
|     return &e->addr; |  | ||||||
|   } |  | ||||||
|   return NULL; |  | ||||||
| } |  | ||||||
| /*---------------------------------------------------------------------------*/ |  | ||||||
| @ -1,61 +0,0 @@ | |||||||
| /*
 |  | ||||||
|  * Copyright (c) 2006, Swedish Institute of Computer Science. |  | ||||||
|  * All rights reserved. |  | ||||||
|  * |  | ||||||
|  * Redistribution and use in source and binary forms, with or without |  | ||||||
|  * modification, are permitted provided that the following conditions |  | ||||||
|  * are met: |  | ||||||
|  * 1. Redistributions of source code must retain the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer. |  | ||||||
|  * 2. Redistributions in binary form must reproduce the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer in the |  | ||||||
|  *    documentation and/or other materials provided with the distribution. |  | ||||||
|  * 3. Neither the name of the Institute nor the names of its contributors |  | ||||||
|  *    may be used to endorse or promote products derived from this software |  | ||||||
|  *    without specific prior written permission. |  | ||||||
|  * |  | ||||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND |  | ||||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |  | ||||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |  | ||||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE |  | ||||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |  | ||||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |  | ||||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |  | ||||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |  | ||||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |  | ||||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |  | ||||||
|  * SUCH DAMAGE. |  | ||||||
|  * |  | ||||||
|  * This file is part of the uIP TCP/IP stack |  | ||||||
|  * |  | ||||||
|  * $Id: uip-neighbor.h,v 1.2 2006/06/12 08:00:30 adam Exp $ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \file |  | ||||||
|  *         Header file for database of link-local neighbors, used by |  | ||||||
|  *         IPv6 code and to be used by future ARP code. |  | ||||||
|  * \author |  | ||||||
|  *         Adam Dunkels <adam@sics.se> |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #ifndef __UIP_NEIGHBOR_H__ |  | ||||||
| #define __UIP_NEIGHBOR_H__ |  | ||||||
| 
 |  | ||||||
| #include "uip.h" |  | ||||||
| 
 |  | ||||||
| struct uip_neighbor_addr { |  | ||||||
| #if UIP_NEIGHBOR_CONF_ADDRTYPE |  | ||||||
|   UIP_NEIGHBOR_CONF_ADDRTYPE addr; |  | ||||||
| #else |  | ||||||
|   struct uip_eth_addr addr; |  | ||||||
| #endif |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| void uip_neighbor_init(void); |  | ||||||
| void uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr); |  | ||||||
| void uip_neighbor_update(uip_ipaddr_t ipaddr); |  | ||||||
| struct uip_neighbor_addr *uip_neighbor_lookup(uip_ipaddr_t ipaddr); |  | ||||||
| void uip_neighbor_periodic(void); |  | ||||||
| 
 |  | ||||||
| #endif /* __UIP-NEIGHBOR_H__ */ |  | ||||||
| @ -1,136 +0,0 @@ | |||||||
| /*
 |  | ||||||
|  * Copyright (c) 2004, Swedish Institute of Computer Science. |  | ||||||
|  * All rights reserved. |  | ||||||
|  * |  | ||||||
|  * Redistribution and use in source and binary forms, with or without |  | ||||||
|  * modification, are permitted provided that the following conditions |  | ||||||
|  * are met: |  | ||||||
|  * 1. Redistributions of source code must retain the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer. |  | ||||||
|  * 2. Redistributions in binary form must reproduce the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer in the |  | ||||||
|  *    documentation and/or other materials provided with the distribution. |  | ||||||
|  * 3. Neither the name of the Institute nor the names of its contributors |  | ||||||
|  *    may be used to endorse or promote products derived from this software |  | ||||||
|  *    without specific prior written permission. |  | ||||||
|  * |  | ||||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND |  | ||||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |  | ||||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |  | ||||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE |  | ||||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |  | ||||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |  | ||||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |  | ||||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |  | ||||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |  | ||||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |  | ||||||
|  * SUCH DAMAGE. |  | ||||||
|  * |  | ||||||
|  * This file is part of the uIP TCP/IP stack |  | ||||||
|  * |  | ||||||
|  * Author: Adam Dunkels <adam@sics.se> |  | ||||||
|  * |  | ||||||
|  * $Id: uip-split.c,v 1.2 2006/06/12 08:00:30 adam Exp $ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #include <string.h> |  | ||||||
| 
 |  | ||||||
| #include "uip-split.h" |  | ||||||
| #include "uip.h" |  | ||||||
| #include "uip-fw.h" |  | ||||||
| #include "uip_arch.h" |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| #define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) |  | ||||||
| 
 |  | ||||||
| /*-----------------------------------------------------------------------------*/ |  | ||||||
| void |  | ||||||
| uip_split_output(void) |  | ||||||
| { |  | ||||||
|   u16_t tcplen, len1, len2; |  | ||||||
| 
 |  | ||||||
|   /* We only try to split maximum sized TCP segments. */ |  | ||||||
|   if(BUF->proto == UIP_PROTO_TCP && |  | ||||||
|      uip_len == UIP_BUFSIZE - UIP_LLH_LEN) { |  | ||||||
| 
 |  | ||||||
|     tcplen = uip_len - UIP_TCPIP_HLEN; |  | ||||||
|     /* Split the segment in two. If the original packet length was
 |  | ||||||
|        odd, we make the second packet one byte larger. */ |  | ||||||
|     len1 = len2 = tcplen / 2; |  | ||||||
|     if(len1 + len2 < tcplen) { |  | ||||||
|       ++len2; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /* Create the first packet. This is done by altering the length
 |  | ||||||
|        field of the IP header and updating the checksums. */ |  | ||||||
|     uip_len = len1 + UIP_TCPIP_HLEN; |  | ||||||
| #if UIP_CONF_IPV6 |  | ||||||
|     /* For IPv6, the IP length field does not include the IPv6 IP header
 |  | ||||||
|        length. */ |  | ||||||
|     BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); |  | ||||||
|     BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); |  | ||||||
| #else /* UIP_CONF_IPV6 */ |  | ||||||
|     BUF->len[0] = uip_len >> 8; |  | ||||||
|     BUF->len[1] = uip_len & 0xff; |  | ||||||
| #endif /* UIP_CONF_IPV6 */ |  | ||||||
|      |  | ||||||
|     /* Recalculate the TCP checksum. */ |  | ||||||
|     BUF->tcpchksum = 0; |  | ||||||
|     BUF->tcpchksum = ~(uip_tcpchksum()); |  | ||||||
| 
 |  | ||||||
| #if !UIP_CONF_IPV6 |  | ||||||
|     /* Recalculate the IP checksum. */ |  | ||||||
|     BUF->ipchksum = 0; |  | ||||||
|     BUF->ipchksum = ~(uip_ipchksum()); |  | ||||||
| #endif /* UIP_CONF_IPV6 */ |  | ||||||
|      |  | ||||||
|     /* Transmit the first packet. */ |  | ||||||
|     /*    uip_fw_output();*/ |  | ||||||
|     tcpip_output(); |  | ||||||
| 
 |  | ||||||
|     /* Now, create the second packet. To do this, it is not enough to
 |  | ||||||
|        just alter the length field, but we must also update the TCP |  | ||||||
|        sequence number and point the uip_appdata to a new place in |  | ||||||
|        memory. This place is detemined by the length of the first |  | ||||||
|        packet (len1). */ |  | ||||||
|     uip_len = len2 + UIP_TCPIP_HLEN; |  | ||||||
| #if UIP_CONF_IPV6 |  | ||||||
|     /* For IPv6, the IP length field does not include the IPv6 IP header
 |  | ||||||
|        length. */ |  | ||||||
|     BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); |  | ||||||
|     BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); |  | ||||||
| #else /* UIP_CONF_IPV6 */ |  | ||||||
|     BUF->len[0] = uip_len >> 8; |  | ||||||
|     BUF->len[1] = uip_len & 0xff; |  | ||||||
| #endif /* UIP_CONF_IPV6 */ |  | ||||||
|      |  | ||||||
|     /*    uip_appdata += len1;*/ |  | ||||||
|     memcpy(uip_appdata, (u8_t *)uip_appdata + len1, len2); |  | ||||||
| 
 |  | ||||||
|     uip_add32(BUF->seqno, len1); |  | ||||||
|     BUF->seqno[0] = uip_acc32[0]; |  | ||||||
|     BUF->seqno[1] = uip_acc32[1]; |  | ||||||
|     BUF->seqno[2] = uip_acc32[2]; |  | ||||||
|     BUF->seqno[3] = uip_acc32[3]; |  | ||||||
|      |  | ||||||
|     /* Recalculate the TCP checksum. */ |  | ||||||
|     BUF->tcpchksum = 0; |  | ||||||
|     BUF->tcpchksum = ~(uip_tcpchksum()); |  | ||||||
| 
 |  | ||||||
| #if !UIP_CONF_IPV6 |  | ||||||
|     /* Recalculate the IP checksum. */ |  | ||||||
|     BUF->ipchksum = 0; |  | ||||||
|     BUF->ipchksum = ~(uip_ipchksum()); |  | ||||||
| #endif /* UIP_CONF_IPV6 */ |  | ||||||
| 
 |  | ||||||
|     /* Transmit the second packet. */ |  | ||||||
|     /*    uip_fw_output();*/ |  | ||||||
|     tcpip_output(); |  | ||||||
|   } else { |  | ||||||
|     /*    uip_fw_output();*/ |  | ||||||
|     tcpip_output(); |  | ||||||
|   } |  | ||||||
|       |  | ||||||
| } |  | ||||||
| /*-----------------------------------------------------------------------------*/ |  | ||||||
| @ -1,96 +0,0 @@ | |||||||
| /*
 |  | ||||||
|  * Copyright (c) 2004, Swedish Institute of Computer Science. |  | ||||||
|  * All rights reserved. |  | ||||||
|  * |  | ||||||
|  * Redistribution and use in source and binary forms, with or without |  | ||||||
|  * modification, are permitted provided that the following conditions |  | ||||||
|  * are met: |  | ||||||
|  * 1. Redistributions of source code must retain the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer. |  | ||||||
|  * 2. Redistributions in binary form must reproduce the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer in the |  | ||||||
|  *    documentation and/or other materials provided with the distribution. |  | ||||||
|  * 3. Neither the name of the Institute nor the names of its contributors |  | ||||||
|  *    may be used to endorse or promote products derived from this software |  | ||||||
|  *    without specific prior written permission. |  | ||||||
|  * |  | ||||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND |  | ||||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |  | ||||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |  | ||||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE |  | ||||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |  | ||||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |  | ||||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |  | ||||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |  | ||||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |  | ||||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |  | ||||||
|  * SUCH DAMAGE. |  | ||||||
|  * |  | ||||||
|  * This file is part of the uIP TCP/IP stack |  | ||||||
|  * |  | ||||||
|  * Author: Adam Dunkels <adam@sics.se> |  | ||||||
|  * |  | ||||||
|  * $Id: uip-split.h,v 1.2 2006/06/12 08:00:30 adam Exp $ |  | ||||||
|  */ |  | ||||||
| /**
 |  | ||||||
|  * \addtogroup uip |  | ||||||
|  * @{ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \defgroup uipsplit uIP TCP throughput booster hack |  | ||||||
|  * @{ |  | ||||||
|  * |  | ||||||
|  * The basic uIP TCP implementation only allows each TCP connection to |  | ||||||
|  * have a single TCP segment in flight at any given time. Because of |  | ||||||
|  * the delayed ACK algorithm employed by most TCP receivers, uIP's |  | ||||||
|  * limit on the amount of in-flight TCP segments seriously reduces the |  | ||||||
|  * maximum achievable throughput for sending data from uIP. |  | ||||||
|  * |  | ||||||
|  * The uip-split module is a hack which tries to remedy this |  | ||||||
|  * situation. By splitting maximum sized outgoing TCP segments into |  | ||||||
|  * two, the delayed ACK algorithm is not invoked at TCP |  | ||||||
|  * receivers. This improves the throughput when sending data from uIP |  | ||||||
|  * by orders of magnitude. |  | ||||||
|  * |  | ||||||
|  * The uip-split module uses the uip-fw module (uIP IP packet |  | ||||||
|  * forwarding) for sending packets. Therefore, the uip-fw module must |  | ||||||
|  * be set up with the appropriate network interfaces for this module |  | ||||||
|  * to work. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \file |  | ||||||
|  * Module for splitting outbound TCP segments in two to avoid the |  | ||||||
|  * delayed ACK throughput degradation. |  | ||||||
|  * \author |  | ||||||
|  * Adam Dunkels <adam@sics.se> |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #ifndef __UIP_SPLIT_H__ |  | ||||||
| #define __UIP_SPLIT_H__ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Handle outgoing packets. |  | ||||||
|  * |  | ||||||
|  * This function inspects an outgoing packet in the uip_buf buffer and |  | ||||||
|  * sends it out using the uip_fw_output() function. If the packet is a |  | ||||||
|  * full-sized TCP segment it will be split into two segments and |  | ||||||
|  * transmitted separately. This function should be called instead of |  | ||||||
|  * the actual device driver output function, or the uip_fw_output() |  | ||||||
|  * function. |  | ||||||
|  * |  | ||||||
|  * The headers of the outgoing packet is assumed to be in the uip_buf |  | ||||||
|  * buffer and the payload is assumed to be wherever uip_appdata |  | ||||||
|  * points. The length of the outgoing packet is assumed to be in the |  | ||||||
|  * uip_len variable. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| void uip_split_output(void); |  | ||||||
| 
 |  | ||||||
| #endif /* __UIP_SPLIT_H__ */ |  | ||||||
| 
 |  | ||||||
| /** @} */ |  | ||||||
| /** @} */ |  | ||||||
| @ -1,16 +1,8 @@ | |||||||
| #define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/ | #define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/ | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * \defgroup uip The uIP TCP/IP stack |  * \addtogroup uip | ||||||
|  * @{ |  * @{ | ||||||
|  * |  | ||||||
|  * uIP is an implementation of the TCP/IP protocol stack intended for |  | ||||||
|  * small 8-bit and 16-bit microcontrollers. |  | ||||||
|  * |  | ||||||
|  * uIP provides the necessary protocols for Internet communication, |  | ||||||
|  * with a very small code footprint and RAM requirements - the uIP |  | ||||||
|  * code size is on the order of a few kilobytes and RAM usage is on |  | ||||||
|  * the order of a few hundred bytes. |  | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
| @ -49,7 +41,7 @@ | |||||||
|  * |  * | ||||||
|  * This file is part of the uIP TCP/IP stack. |  * This file is part of the uIP TCP/IP stack. | ||||||
|  * |  * | ||||||
|  * $Id: uip.c,v 1.65 2006/06/11 21:46:39 adam Exp $ |  * $Id: uip.c,v 1.15 2008/10/15 08:08:32 adamdunkels Exp $ | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -81,10 +73,16 @@ | |||||||
| 
 | 
 | ||||||
| #include "uip.h" | #include "uip.h" | ||||||
| #include "uipopt.h" | #include "uipopt.h" | ||||||
| #include "uip_arch.h" | #include "uip_arp.h" | ||||||
|  | 
 | ||||||
|  | #if !UIP_CONF_IPV6 /* If UIP_CONF_IPV6 is defined, we compile the | ||||||
|  | 		      uip6.c file instead of this one. Therefore | ||||||
|  | 		      this #ifndef removes the entire compilation | ||||||
|  | 		      output of the uip.c file */ | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| #if UIP_CONF_IPV6 | #if UIP_CONF_IPV6 | ||||||
| #include "uip-neighbor.h" | #include "net/uip-neighbor.h" | ||||||
| #endif /* UIP_CONF_IPV6 */ | #endif /* UIP_CONF_IPV6 */ | ||||||
| 
 | 
 | ||||||
| #include <string.h> | #include <string.h> | ||||||
| @ -98,31 +96,23 @@ | |||||||
|    here. Otherwise, the address */ |    here. Otherwise, the address */ | ||||||
| #if UIP_FIXEDADDR > 0 | #if UIP_FIXEDADDR > 0 | ||||||
| const uip_ipaddr_t uip_hostaddr = | const uip_ipaddr_t uip_hostaddr = | ||||||
|   {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1), |   { UIP_IPADDR0, UIP_IPADDR1, UIP_IPADDR2, UIP_IPADDR3 }; | ||||||
|    HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)}; |  | ||||||
| const uip_ipaddr_t uip_draddr = | const uip_ipaddr_t uip_draddr = | ||||||
|   {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1), |   { UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3 }; | ||||||
|    HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)}; |  | ||||||
| const uip_ipaddr_t uip_netmask = | const uip_ipaddr_t uip_netmask = | ||||||
|   {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1), |   { UIP_NETMASK0, UIP_NETMASK1, UIP_NETMASK2, UIP_NETMASK3 }; | ||||||
|    HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)}; |  | ||||||
| #else | #else | ||||||
| uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask; | uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask; | ||||||
| #endif /* UIP_FIXEDADDR */ | #endif /* UIP_FIXEDADDR */ | ||||||
| 
 | 
 | ||||||
| static const uip_ipaddr_t all_ones_addr = | const uip_ipaddr_t uip_broadcast_addr = | ||||||
| #if UIP_CONF_IPV6 | #if UIP_CONF_IPV6 | ||||||
|   {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}; |   { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||||||
|  |       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } }; | ||||||
| #else /* UIP_CONF_IPV6 */ | #else /* UIP_CONF_IPV6 */ | ||||||
|   {0xffff,0xffff}; |   { { 0xff, 0xff, 0xff, 0xff } }; | ||||||
| #endif /* UIP_CONF_IPV6 */ | #endif /* UIP_CONF_IPV6 */ | ||||||
| static const uip_ipaddr_t all_zeroes_addr = | const uip_ipaddr_t uip_all_zeroes_addr = { { 0x0, /* rest is 0 */ } }; | ||||||
| #if UIP_CONF_IPV6 |  | ||||||
|   {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}; |  | ||||||
| #else /* UIP_CONF_IPV6 */ |  | ||||||
|   {0x0000,0x0000}; |  | ||||||
| #endif /* UIP_CONF_IPV6 */ |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| #if UIP_FIXEDETHADDR | #if UIP_FIXEDETHADDR | ||||||
| const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0, | const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0, | ||||||
| @ -211,6 +201,9 @@ static u16_t tmp16; | |||||||
| #define ICMP_ECHO_REPLY 0 | #define ICMP_ECHO_REPLY 0 | ||||||
| #define ICMP_ECHO       8 | #define ICMP_ECHO       8 | ||||||
| 
 | 
 | ||||||
|  | #define ICMP_DEST_UNREACHABLE        3 | ||||||
|  | #define ICMP_PORT_UNREACHABLE        3 | ||||||
|  | 
 | ||||||
| #define ICMP6_ECHO_REPLY             129 | #define ICMP6_ECHO_REPLY             129 | ||||||
| #define ICMP6_ECHO                   128 | #define ICMP6_ECHO                   128 | ||||||
| #define ICMP6_NEIGHBOR_SOLICITATION  135 | #define ICMP6_NEIGHBOR_SOLICITATION  135 | ||||||
| @ -342,7 +335,7 @@ upper_layer_chksum(u8_t proto) | |||||||
|   /* IP protocol and length fields. This addition cannot carry. */ |   /* IP protocol and length fields. This addition cannot carry. */ | ||||||
|   sum = upper_layer_len + proto; |   sum = upper_layer_len + proto; | ||||||
|   /* Sum IP source and destination addresses. */ |   /* Sum IP source and destination addresses. */ | ||||||
|   sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t)); |   sum = chksum(sum, (u8_t *)&BUF->srcipaddr, 2 * sizeof(uip_ipaddr_t)); | ||||||
| 
 | 
 | ||||||
|   /* Sum TCP header and data. */ |   /* Sum TCP header and data. */ | ||||||
|   sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], |   sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], | ||||||
| @ -470,7 +463,7 @@ uip_connect(uip_ipaddr_t *ripaddr, u16_t rport) | |||||||
| /*---------------------------------------------------------------------------*/ | /*---------------------------------------------------------------------------*/ | ||||||
| #if UIP_UDP | #if UIP_UDP | ||||||
| struct uip_udp_conn * | struct uip_udp_conn * | ||||||
| uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) | uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport) | ||||||
| { | { | ||||||
|   register struct uip_udp_conn *conn; |   register struct uip_udp_conn *conn; | ||||||
|    |    | ||||||
| @ -504,7 +497,7 @@ uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) | |||||||
|   conn->lport = HTONS(lastport); |   conn->lport = HTONS(lastport); | ||||||
|   conn->rport = rport; |   conn->rport = rport; | ||||||
|   if(ripaddr == NULL) { |   if(ripaddr == NULL) { | ||||||
|     memset(conn->ripaddr, 0, sizeof(uip_ipaddr_t)); |     memset(&conn->ripaddr, 0, sizeof(uip_ipaddr_t)); | ||||||
|   } else { |   } else { | ||||||
|     uip_ipaddr_copy(&conn->ripaddr, ripaddr); |     uip_ipaddr_copy(&conn->ripaddr, ripaddr); | ||||||
|   } |   } | ||||||
| @ -889,7 +882,7 @@ uip_process(u8_t flag) | |||||||
|   } |   } | ||||||
| #endif /* UIP_CONF_IPV6 */ | #endif /* UIP_CONF_IPV6 */ | ||||||
| 
 | 
 | ||||||
|   if(uip_ipaddr_cmp(uip_hostaddr, all_zeroes_addr)) { |   if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) { | ||||||
|     /* If we are configured to use ping IP address configuration and
 |     /* If we are configured to use ping IP address configuration and
 | ||||||
|        hasn't been assigned an IP address yet, we accept all ICMP |        hasn't been assigned an IP address yet, we accept all ICMP | ||||||
|        packets. */ |        packets. */ | ||||||
| @ -909,7 +902,7 @@ uip_process(u8_t flag) | |||||||
| #if UIP_BROADCAST | #if UIP_BROADCAST | ||||||
|     DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum()); |     DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum()); | ||||||
|     if(BUF->proto == UIP_PROTO_UDP && |     if(BUF->proto == UIP_PROTO_UDP && | ||||||
|        uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr) |        uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr) | ||||||
|        /*&&
 |        /*&&
 | ||||||
| 	 uip_ipchksum() == 0xffff*/) { | 	 uip_ipchksum() == 0xffff*/) { | ||||||
|       goto udp_input; |       goto udp_input; | ||||||
| @ -918,7 +911,7 @@ uip_process(u8_t flag) | |||||||
|      |      | ||||||
|     /* Check if the packet is destined for our IP address. */ |     /* Check if the packet is destined for our IP address. */ | ||||||
| #if !UIP_CONF_IPV6 | #if !UIP_CONF_IPV6 | ||||||
|     if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr)) { |     if(!uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr)) { | ||||||
|       UIP_STAT(++uip_stat.ip.drop); |       UIP_STAT(++uip_stat.ip.drop); | ||||||
|       goto drop; |       goto drop; | ||||||
|     } |     } | ||||||
| @ -928,8 +921,8 @@ uip_process(u8_t flag) | |||||||
|        hosts multicast address, and the solicited-node multicast |        hosts multicast address, and the solicited-node multicast | ||||||
|        address) as well. However, we will cheat here and accept all |        address) as well. However, we will cheat here and accept all | ||||||
|        multicast packets that are sent to the ff02::/16 addresses. */ |        multicast packets that are sent to the ff02::/16 addresses. */ | ||||||
|     if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr) && |     if(!uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr) && | ||||||
|        BUF->destipaddr[0] != HTONS(0xff02)) { |        BUF->destipaddr.u16[0] != HTONS(0xff02)) { | ||||||
|       UIP_STAT(++uip_stat.ip.drop); |       UIP_STAT(++uip_stat.ip.drop); | ||||||
|       goto drop; |       goto drop; | ||||||
|     } |     } | ||||||
| @ -987,9 +980,8 @@ uip_process(u8_t flag) | |||||||
|      the destination IP address of this ping packet and assign it to |      the destination IP address of this ping packet and assign it to | ||||||
|      ourself. */ |      ourself. */ | ||||||
| #if UIP_PINGADDRCONF | #if UIP_PINGADDRCONF | ||||||
|   if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) { |   if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) { | ||||||
|     uip_hostaddr[0] = BUF->destipaddr[0]; |     uip_hostaddr = BUF->destipaddr; | ||||||
|     uip_hostaddr[1] = BUF->destipaddr[1]; |  | ||||||
|   } |   } | ||||||
| #endif /* UIP_PINGADDRCONF */ | #endif /* UIP_PINGADDRCONF */ | ||||||
| 
 | 
 | ||||||
| @ -1002,11 +994,12 @@ uip_process(u8_t flag) | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /* Swap IP addresses. */ |   /* Swap IP addresses. */ | ||||||
|   uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); |   uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr); | ||||||
|   uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); |   uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr); | ||||||
| 
 | 
 | ||||||
|   UIP_STAT(++uip_stat.icmp.sent); |   UIP_STAT(++uip_stat.icmp.sent); | ||||||
|   goto send; |   BUF->ttl = UIP_TTL; | ||||||
|  |   goto ip_send_nolen; | ||||||
| 
 | 
 | ||||||
|   /* End of IPv4 input header processing code. */ |   /* End of IPv4 input header processing code. */ | ||||||
| #else /* !UIP_CONF_IPV6 */ | #else /* !UIP_CONF_IPV6 */ | ||||||
| @ -1027,11 +1020,11 @@ uip_process(u8_t flag) | |||||||
|   /* If we get a neighbor solicitation for our address we should send
 |   /* If we get a neighbor solicitation for our address we should send
 | ||||||
|      a neighbor advertisement message back. */ |      a neighbor advertisement message back. */ | ||||||
|   if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) { |   if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) { | ||||||
|     if(uip_ipaddr_cmp(ICMPBUF->icmp6data, uip_hostaddr)) { |     if(uip_ipaddr_cmp(&ICMPBUF->icmp6data, &uip_hostaddr)) { | ||||||
| 
 | 
 | ||||||
|       if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) { |       if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) { | ||||||
| 	/* Save the sender's address in our neighbor list. */ | 	/* Save the sender's address in our neighbor list. */ | ||||||
| 	uip_neighbor_add(ICMPBUF->srcipaddr, &(ICMPBUF->options[2])); | 	uip_neighbor_add(&ICMPBUF->srcipaddr, &(ICMPBUF->options[2])); | ||||||
|       } |       } | ||||||
|        |        | ||||||
|       /* We should now send a neighbor advertisement back to where the
 |       /* We should now send a neighbor advertisement back to where the
 | ||||||
| @ -1041,13 +1034,14 @@ uip_process(u8_t flag) | |||||||
|        |        | ||||||
|       ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0; |       ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0; | ||||||
|        |        | ||||||
|       uip_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr); |       uip_ipaddr_copy(&ICMPBUF->destipaddr, &ICMPBUF->srcipaddr); | ||||||
|       uip_ipaddr_copy(ICMPBUF->srcipaddr, uip_hostaddr); |       uip_ipaddr_copy(&ICMPBUF->srcipaddr, &uip_hostaddr); | ||||||
|       ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS; |       ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS; | ||||||
|       ICMPBUF->options[1] = 1;  /* Options length, 1 = 8 bytes. */ |       ICMPBUF->options[1] = 1;  /* Options length, 1 = 8 bytes. */ | ||||||
|       memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr)); |       memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr)); | ||||||
|       ICMPBUF->icmpchksum = 0; |       ICMPBUF->icmpchksum = 0; | ||||||
|       ICMPBUF->icmpchksum = ~uip_icmp6chksum(); |       ICMPBUF->icmpchksum = ~uip_icmp6chksum(); | ||||||
|  |        | ||||||
|       goto send; |       goto send; | ||||||
|        |        | ||||||
|     } |     } | ||||||
| @ -1059,8 +1053,8 @@ uip_process(u8_t flag) | |||||||
| 
 | 
 | ||||||
|     ICMPBUF->type = ICMP6_ECHO_REPLY; |     ICMPBUF->type = ICMP6_ECHO_REPLY; | ||||||
|      |      | ||||||
|     uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); |     uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr); | ||||||
|     uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); |     uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr); | ||||||
|     ICMPBUF->icmpchksum = 0; |     ICMPBUF->icmpchksum = 0; | ||||||
|     ICMPBUF->icmpchksum = ~uip_icmp6chksum(); |     ICMPBUF->icmpchksum = ~uip_icmp6chksum(); | ||||||
|      |      | ||||||
| @ -1113,14 +1107,44 @@ uip_process(u8_t flag) | |||||||
|        UDPBUF->destport == uip_udp_conn->lport && |        UDPBUF->destport == uip_udp_conn->lport && | ||||||
|        (uip_udp_conn->rport == 0 || |        (uip_udp_conn->rport == 0 || | ||||||
|         UDPBUF->srcport == uip_udp_conn->rport) && |         UDPBUF->srcport == uip_udp_conn->rport) && | ||||||
|        (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) || |        (uip_ipaddr_cmp(&uip_udp_conn->ripaddr, &uip_all_zeroes_addr) || | ||||||
| 	uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) || | 	uip_ipaddr_cmp(&uip_udp_conn->ripaddr, &uip_broadcast_addr) || | ||||||
| 	uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) { | 	uip_ipaddr_cmp(&BUF->srcipaddr, &uip_udp_conn->ripaddr))) { | ||||||
|       goto udp_found; |       goto udp_found; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   UIP_LOG("udp: no matching connection found"); |   UIP_LOG("udp: no matching connection found"); | ||||||
|  | #if UIP_CONF_ICMP_DEST_UNREACH && !UIP_CONF_IPV6 | ||||||
|  |   /* Copy fields from packet header into payload of this ICMP packet. */ | ||||||
|  |   memcpy(&(ICMPBUF->payload[0]), ICMPBUF, UIP_IPH_LEN + 8); | ||||||
|  | 
 | ||||||
|  |   /* Set the ICMP type and code. */ | ||||||
|  |   ICMPBUF->type = ICMP_DEST_UNREACHABLE; | ||||||
|  |   ICMPBUF->icode = ICMP_PORT_UNREACHABLE; | ||||||
|  | 
 | ||||||
|  |   /* Calculate the ICMP checksum. */ | ||||||
|  |   ICMPBUF->icmpchksum = 0; | ||||||
|  |   ICMPBUF->icmpchksum = ~uip_chksum((u16_t *)&(ICMPBUF->type), 36); | ||||||
|  | 
 | ||||||
|  |   /* Set the IP destination address to be the source address of the
 | ||||||
|  |      original packet. */ | ||||||
|  |   uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr); | ||||||
|  | 
 | ||||||
|  |   /* Set our IP address as the source address. */ | ||||||
|  |   uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr); | ||||||
|  | 
 | ||||||
|  |   /* The size of the ICMP destination unreachable packet is 36 + the
 | ||||||
|  |      size of the IP header (20) = 56. */ | ||||||
|  |   uip_len = 36 + UIP_IPH_LEN; | ||||||
|  |   ICMPBUF->len[0] = 0; | ||||||
|  |   ICMPBUF->len[1] = (u8_t)uip_len; | ||||||
|  |   ICMPBUF->ttl = UIP_TTL; | ||||||
|  |   ICMPBUF->proto = UIP_PROTO_ICMP; | ||||||
|  | 
 | ||||||
|  |   goto ip_send_nolen; | ||||||
|  | #else /* UIP_CONF_ICMP_DEST_UNREACH */ | ||||||
|   goto drop; |   goto drop; | ||||||
|  | #endif /* UIP_CONF_ICMP_DEST_UNREACH */ | ||||||
|    |    | ||||||
|  udp_found: |  udp_found: | ||||||
|   uip_conn = NULL; |   uip_conn = NULL; | ||||||
| @ -1128,6 +1152,7 @@ uip_process(u8_t flag) | |||||||
|   uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; |   uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; | ||||||
|   uip_slen = 0; |   uip_slen = 0; | ||||||
|   UIP_UDP_APPCALL(); |   UIP_UDP_APPCALL(); | ||||||
|  | 
 | ||||||
|  udp_send: |  udp_send: | ||||||
|   if(uip_slen == 0) { |   if(uip_slen == 0) { | ||||||
|     goto drop; |     goto drop; | ||||||
| @ -1153,8 +1178,8 @@ uip_process(u8_t flag) | |||||||
|   BUF->srcport  = uip_udp_conn->lport; |   BUF->srcport  = uip_udp_conn->lport; | ||||||
|   BUF->destport = uip_udp_conn->rport; |   BUF->destport = uip_udp_conn->rport; | ||||||
| 
 | 
 | ||||||
|   uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); |   uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr); | ||||||
|   uip_ipaddr_copy(BUF->destipaddr, uip_udp_conn->ripaddr); |   uip_ipaddr_copy(&BUF->destipaddr, &uip_udp_conn->ripaddr); | ||||||
|     |     | ||||||
|   uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN]; |   uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN]; | ||||||
| 
 | 
 | ||||||
| @ -1183,7 +1208,6 @@ uip_process(u8_t flag) | |||||||
|     goto drop; |     goto drop; | ||||||
|   } |   } | ||||||
|    |    | ||||||
|    |  | ||||||
|   /* Demultiplex this segment. */ |   /* Demultiplex this segment. */ | ||||||
|   /* First check any active connections. */ |   /* First check any active connections. */ | ||||||
|   for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1]; |   for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1]; | ||||||
| @ -1191,7 +1215,7 @@ uip_process(u8_t flag) | |||||||
|     if(uip_connr->tcpstateflags != UIP_CLOSED && |     if(uip_connr->tcpstateflags != UIP_CLOSED && | ||||||
|        BUF->destport == uip_connr->lport && |        BUF->destport == uip_connr->lport && | ||||||
|        BUF->srcport == uip_connr->rport && |        BUF->srcport == uip_connr->rport && | ||||||
|        uip_ipaddr_cmp(BUF->srcipaddr, uip_connr->ripaddr)) { |        uip_ipaddr_cmp(&BUF->srcipaddr, &uip_connr->ripaddr)) { | ||||||
|       goto found; |       goto found; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @ -1207,14 +1231,15 @@ uip_process(u8_t flag) | |||||||
|   tmp16 = BUF->destport; |   tmp16 = BUF->destport; | ||||||
|   /* Next, check listening connections. */ |   /* Next, check listening connections. */ | ||||||
|   for(c = 0; c < UIP_LISTENPORTS; ++c) { |   for(c = 0; c < UIP_LISTENPORTS; ++c) { | ||||||
|     if(tmp16 == uip_listenports[c]) |     if(tmp16 == uip_listenports[c]) { | ||||||
|       goto found_listen; |       goto found_listen; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|    |    | ||||||
|   /* No matching connection found, so we send a RST packet. */ |   /* No matching connection found, so we send a RST packet. */ | ||||||
|   UIP_STAT(++uip_stat.tcp.synrst); |   UIP_STAT(++uip_stat.tcp.synrst); | ||||||
|  reset: |  | ||||||
| 
 | 
 | ||||||
|  |  reset: | ||||||
|   /* We do not send resets in response to resets. */ |   /* We do not send resets in response to resets. */ | ||||||
|   if(BUF->flags & TCP_RST) { |   if(BUF->flags & TCP_RST) { | ||||||
|     goto drop; |     goto drop; | ||||||
| @ -1260,8 +1285,8 @@ uip_process(u8_t flag) | |||||||
|   BUF->destport = tmp16; |   BUF->destport = tmp16; | ||||||
|    |    | ||||||
|   /* Swap IP addresses. */ |   /* Swap IP addresses. */ | ||||||
|   uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); |   uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr); | ||||||
|   uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); |   uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr); | ||||||
|    |    | ||||||
|   /* And send out the RST packet! */ |   /* And send out the RST packet! */ | ||||||
|   goto tcp_send_noconn; |   goto tcp_send_noconn; | ||||||
| @ -1307,7 +1332,7 @@ uip_process(u8_t flag) | |||||||
|   uip_connr->nrtx = 0; |   uip_connr->nrtx = 0; | ||||||
|   uip_connr->lport = BUF->destport; |   uip_connr->lport = BUF->destport; | ||||||
|   uip_connr->rport = BUF->srcport; |   uip_connr->rport = BUF->srcport; | ||||||
|   uip_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr); |   uip_ipaddr_copy(&uip_connr->ripaddr, &BUF->srcipaddr); | ||||||
|   uip_connr->tcpstateflags = UIP_SYN_RCVD; |   uip_connr->tcpstateflags = UIP_SYN_RCVD; | ||||||
| 
 | 
 | ||||||
|   uip_connr->snd_nxt[0] = iss[0]; |   uip_connr->snd_nxt[0] = iss[0]; | ||||||
| @ -1393,7 +1418,7 @@ uip_process(u8_t flag) | |||||||
|     UIP_APPCALL(); |     UIP_APPCALL(); | ||||||
|     goto drop; |     goto drop; | ||||||
|   } |   } | ||||||
|   /* Calculated the length of the data, if the application has sent
 |   /* Calculate the length of the data, if the application has sent
 | ||||||
|      any data to us. */ |      any data to us. */ | ||||||
|   c = (BUF->tcpoffset >> 4) << 2; |   c = (BUF->tcpoffset >> 4) << 2; | ||||||
|   /* uip_len will contain the length of the actual TCP data. This is
 |   /* uip_len will contain the length of the actual TCP data. This is
 | ||||||
| @ -1432,7 +1457,6 @@ uip_process(u8_t flag) | |||||||
|       uip_connr->snd_nxt[2] = uip_acc32[2]; |       uip_connr->snd_nxt[2] = uip_acc32[2]; | ||||||
|       uip_connr->snd_nxt[3] = uip_acc32[3]; |       uip_connr->snd_nxt[3] = uip_acc32[3]; | ||||||
| 	 | 	 | ||||||
| 
 |  | ||||||
|       /* Do RTT estimation, unless we have done retransmissions. */ |       /* Do RTT estimation, unless we have done retransmissions. */ | ||||||
|       if(uip_connr->nrtx == 0) { |       if(uip_connr->nrtx == 0) { | ||||||
| 	signed char m; | 	signed char m; | ||||||
| @ -1785,20 +1809,22 @@ uip_process(u8_t flag) | |||||||
|   } |   } | ||||||
|   goto drop; |   goto drop; | ||||||
|    |    | ||||||
| 
 |  | ||||||
|   /* We jump here when we are ready to send the packet, and just want
 |   /* We jump here when we are ready to send the packet, and just want
 | ||||||
|      to set the appropriate TCP sequence numbers in the TCP header. */ |      to set the appropriate TCP sequence numbers in the TCP header. */ | ||||||
|  tcp_send_ack: |  tcp_send_ack: | ||||||
|   BUF->flags = TCP_ACK; |   BUF->flags = TCP_ACK; | ||||||
|  | 
 | ||||||
|  tcp_send_nodata: |  tcp_send_nodata: | ||||||
|   uip_len = UIP_IPTCPH_LEN; |   uip_len = UIP_IPTCPH_LEN; | ||||||
|  | 
 | ||||||
|  tcp_send_noopts: |  tcp_send_noopts: | ||||||
|   BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4; |   BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4; | ||||||
|  tcp_send: | 
 | ||||||
|   /* We're done with the input processing. We are now ready to send a
 |   /* We're done with the input processing. We are now ready to send a
 | ||||||
|      reply. Our job is to fill in all the fields of the TCP and IP |      reply. Our job is to fill in all the fields of the TCP and IP | ||||||
|      headers before calculating the checksum and finally send the |      headers before calculating the checksum and finally send the | ||||||
|      packet. */ |      packet. */ | ||||||
|  |  tcp_send: | ||||||
|   BUF->ackno[0] = uip_connr->rcv_nxt[0]; |   BUF->ackno[0] = uip_connr->rcv_nxt[0]; | ||||||
|   BUF->ackno[1] = uip_connr->rcv_nxt[1]; |   BUF->ackno[1] = uip_connr->rcv_nxt[1]; | ||||||
|   BUF->ackno[2] = uip_connr->rcv_nxt[2]; |   BUF->ackno[2] = uip_connr->rcv_nxt[2]; | ||||||
| @ -1814,8 +1840,8 @@ uip_process(u8_t flag) | |||||||
|   BUF->srcport  = uip_connr->lport; |   BUF->srcport  = uip_connr->lport; | ||||||
|   BUF->destport = uip_connr->rport; |   BUF->destport = uip_connr->rport; | ||||||
| 
 | 
 | ||||||
|   uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); |   uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr); | ||||||
|   uip_ipaddr_copy(BUF->destipaddr, uip_connr->ripaddr); |   uip_ipaddr_copy(&BUF->destipaddr, &uip_connr->ripaddr); | ||||||
| 
 | 
 | ||||||
|   if(uip_connr->tcpstateflags & UIP_STOPPED) { |   if(uip_connr->tcpstateflags & UIP_STOPPED) { | ||||||
|     /* If the connection has issued uip_stop(), we advertise a zero
 |     /* If the connection has issued uip_stop(), we advertise a zero
 | ||||||
| @ -1845,7 +1871,6 @@ uip_process(u8_t flag) | |||||||
|   BUF->tcpchksum = ~(uip_tcpchksum()); |   BUF->tcpchksum = ~(uip_tcpchksum()); | ||||||
| 
 | 
 | ||||||
|  ip_send_nolen: |  ip_send_nolen: | ||||||
| 
 |  | ||||||
| #if UIP_CONF_IPV6 | #if UIP_CONF_IPV6 | ||||||
|   BUF->vtc = 0x60; |   BUF->vtc = 0x60; | ||||||
|   BUF->tcflow = 0x00; |   BUF->tcflow = 0x00; | ||||||
| @ -1862,9 +1887,10 @@ uip_process(u8_t flag) | |||||||
|   BUF->ipchksum = ~(uip_ipchksum()); |   BUF->ipchksum = ~(uip_ipchksum()); | ||||||
|   DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum()); |   DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum()); | ||||||
| #endif /* UIP_CONF_IPV6 */    | #endif /* UIP_CONF_IPV6 */    | ||||||
|     |  | ||||||
|   UIP_STAT(++uip_stat.tcp.sent); |   UIP_STAT(++uip_stat.tcp.sent); | ||||||
|  | #if UIP_CONF_IPV6 | ||||||
|  send: |  send: | ||||||
|  | #endif /* UIP_CONF_IPV6 */ | ||||||
|   DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len, |   DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len, | ||||||
| 	       (BUF->len[0] << 8) | BUF->len[1]); | 	       (BUF->len[0] << 8) | BUF->len[1]); | ||||||
|    |    | ||||||
| @ -1872,6 +1898,7 @@ uip_process(u8_t flag) | |||||||
|   /* Return and let the caller do the actual transmission. */ |   /* Return and let the caller do the actual transmission. */ | ||||||
|   uip_flags = 0; |   uip_flags = 0; | ||||||
|   return; |   return; | ||||||
|  | 
 | ||||||
|  drop: |  drop: | ||||||
|   uip_len = 0; |   uip_len = 0; | ||||||
|   uip_flags = 0; |   uip_flags = 0; | ||||||
| @ -1883,15 +1910,27 @@ htons(u16_t val) | |||||||
| { | { | ||||||
|   return HTONS(val); |   return HTONS(val); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | u32_t | ||||||
|  | htonl(u32_t val) | ||||||
|  | { | ||||||
|  |   return HTONL(val); | ||||||
|  | } | ||||||
| /*---------------------------------------------------------------------------*/ | /*---------------------------------------------------------------------------*/ | ||||||
| void | void | ||||||
| uip_send(const void *data, int len) | uip_send(const void *data, int len) | ||||||
| { | { | ||||||
|   if(len > 0) { |   int copylen; | ||||||
|     uip_slen = len; | #define MIN(a,b) ((a) < (b)? (a): (b)) | ||||||
|  |   copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN - | ||||||
|  | 		(int)((char *)uip_sappdata - (char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN])); | ||||||
|  |   if(copylen > 0) { | ||||||
|  |     uip_slen = copylen; | ||||||
|     if(data != uip_sappdata) { |     if(data != uip_sappdata) { | ||||||
|       memcpy(uip_sappdata, (data), uip_slen); |       memcpy(uip_sappdata, (data), uip_slen); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | /*---------------------------------------------------------------------------*/ | ||||||
| /** @} */ | /** @} */ | ||||||
|  | #endif /* UIP_CONF_IPV6 */ | ||||||
|  | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,138 +0,0 @@ | |||||||
| /**
 |  | ||||||
|  * \addtogroup uip |  | ||||||
|  * {@ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \defgroup uiparch Architecture specific uIP functions |  | ||||||
|  * @{ |  | ||||||
|  * |  | ||||||
|  * The functions in the architecture specific module implement the IP |  | ||||||
|  * check sum and 32-bit additions. |  | ||||||
|  * |  | ||||||
|  * The IP checksum calculation is the most computationally expensive |  | ||||||
|  * operation in the TCP/IP stack and it therefore pays off to |  | ||||||
|  * implement this in efficient assembler. The purpose of the uip-arch |  | ||||||
|  * module is to let the checksum functions to be implemented in |  | ||||||
|  * architecture specific assembler. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \file |  | ||||||
|  * Declarations of architecture specific functions. |  | ||||||
|  * \author Adam Dunkels <adam@dunkels.com> |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * Copyright (c) 2001, Adam Dunkels. |  | ||||||
|  * All rights reserved. |  | ||||||
|  * |  | ||||||
|  * Redistribution and use in source and binary forms, with or without |  | ||||||
|  * modification, are permitted provided that the following conditions |  | ||||||
|  * are met: |  | ||||||
|  * 1. Redistributions of source code must retain the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer. |  | ||||||
|  * 2. Redistributions in binary form must reproduce the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer in the |  | ||||||
|  *    documentation and/or other materials provided with the distribution. |  | ||||||
|  * 3. The name of the author may not be used to endorse or promote |  | ||||||
|  *    products derived from this software without specific prior |  | ||||||
|  *    written permission. |  | ||||||
|  * |  | ||||||
|  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS |  | ||||||
|  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |  | ||||||
|  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |  | ||||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |  | ||||||
|  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |  | ||||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |  | ||||||
|  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |  | ||||||
|  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |  | ||||||
|  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |  | ||||||
|  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |  | ||||||
|  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |  | ||||||
|  * |  | ||||||
|  * This file is part of the uIP TCP/IP stack. |  | ||||||
|  * |  | ||||||
|  * $Id: uip_arch.h,v 1.2 2006/06/07 09:15:19 adam Exp $ |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #ifndef __UIP_ARCH_H__ |  | ||||||
| #define __UIP_ARCH_H__ |  | ||||||
| 
 |  | ||||||
| #include "uip.h" |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Carry out a 32-bit addition. |  | ||||||
|  * |  | ||||||
|  * Because not all architectures for which uIP is intended has native |  | ||||||
|  * 32-bit arithmetic, uIP uses an external C function for doing the |  | ||||||
|  * required 32-bit additions in the TCP protocol processing. This |  | ||||||
|  * function should add the two arguments and place the result in the |  | ||||||
|  * global variable uip_acc32. |  | ||||||
|  * |  | ||||||
|  * \note The 32-bit integer pointed to by the op32 parameter and the |  | ||||||
|  * result in the uip_acc32 variable are in network byte order (big |  | ||||||
|  * endian). |  | ||||||
|  * |  | ||||||
|  * \param op32 A pointer to a 4-byte array representing a 32-bit |  | ||||||
|  * integer in network byte order (big endian). |  | ||||||
|  * |  | ||||||
|  * \param op16 A 16-bit integer in host byte order. |  | ||||||
|  */ |  | ||||||
| void uip_add32(u8_t *op32, u16_t op16); |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Calculate the Internet checksum over a buffer. |  | ||||||
|  * |  | ||||||
|  * The Internet checksum is the one's complement of the one's |  | ||||||
|  * complement sum of all 16-bit words in the buffer. |  | ||||||
|  * |  | ||||||
|  * See RFC1071. |  | ||||||
|  * |  | ||||||
|  * \note This function is not called in the current version of uIP, |  | ||||||
|  * but future versions might make use of it. |  | ||||||
|  * |  | ||||||
|  * \param buf A pointer to the buffer over which the checksum is to be |  | ||||||
|  * computed. |  | ||||||
|  * |  | ||||||
|  * \param len The length of the buffer over which the checksum is to |  | ||||||
|  * be computed. |  | ||||||
|  * |  | ||||||
|  * \return The Internet checksum of the buffer. |  | ||||||
|  */ |  | ||||||
| u16_t uip_chksum(u16_t *buf, u16_t len); |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Calculate the IP header checksum of the packet header in uip_buf. |  | ||||||
|  * |  | ||||||
|  * The IP header checksum is the Internet checksum of the 20 bytes of |  | ||||||
|  * the IP header. |  | ||||||
|  * |  | ||||||
|  * \return The IP header checksum of the IP header in the uip_buf |  | ||||||
|  * buffer. |  | ||||||
|  */ |  | ||||||
| u16_t uip_ipchksum(void); |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Calculate the TCP checksum of the packet in uip_buf and uip_appdata. |  | ||||||
|  * |  | ||||||
|  * The TCP checksum is the Internet checksum of data contents of the |  | ||||||
|  * TCP segment, and a pseudo-header as defined in RFC793. |  | ||||||
|  * |  | ||||||
|  * \note The uip_appdata pointer that points to the packet data may |  | ||||||
|  * point anywhere in memory, so it is not possible to simply calculate |  | ||||||
|  * the Internet checksum of the contents of the uip_buf buffer. |  | ||||||
|  * |  | ||||||
|  * \return The TCP checksum of the TCP segment in uip_buf and pointed |  | ||||||
|  * to by uip_appdata. |  | ||||||
|  */ |  | ||||||
| u16_t uip_tcpchksum(void); |  | ||||||
| 
 |  | ||||||
| u16_t uip_udpchksum(void); |  | ||||||
| 
 |  | ||||||
| /** @} */ |  | ||||||
| /** @} */ |  | ||||||
| 
 |  | ||||||
| #endif /* __UIP_ARCH_H__ */ |  | ||||||
| @ -54,7 +54,7 @@ | |||||||
|  * |  * | ||||||
|  * This file is part of the uIP TCP/IP stack. |  * This file is part of the uIP TCP/IP stack. | ||||||
|  * |  * | ||||||
|  * $Id: uip_arp.c,v 1.8 2006/06/02 23:36:21 adam Exp $ |  * $Id: uip_arp.c,v 1.5 2008/02/07 01:35:00 adamdunkels Exp $ | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -71,9 +71,9 @@ struct arp_hdr { | |||||||
|   u8_t protolen; |   u8_t protolen; | ||||||
|   u16_t opcode; |   u16_t opcode; | ||||||
|   struct uip_eth_addr shwaddr; |   struct uip_eth_addr shwaddr; | ||||||
|   u16_t sipaddr[2]; |   uip_ipaddr_t sipaddr; | ||||||
|   struct uip_eth_addr dhwaddr; |   struct uip_eth_addr dhwaddr; | ||||||
|   u16_t dipaddr[2]; |   uip_ipaddr_t dipaddr; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct ethip_hdr { | struct ethip_hdr { | ||||||
| @ -87,8 +87,7 @@ struct ethip_hdr { | |||||||
|     ttl, |     ttl, | ||||||
|     proto; |     proto; | ||||||
|   u16_t ipchksum; |   u16_t ipchksum; | ||||||
|   u16_t srcipaddr[2], |   uip_ipaddr_t srcipaddr, destipaddr; | ||||||
|     destipaddr[2]; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #define ARP_REQUEST 1 | #define ARP_REQUEST 1 | ||||||
| @ -97,7 +96,7 @@ struct ethip_hdr { | |||||||
| #define ARP_HWTYPE_ETH 1 | #define ARP_HWTYPE_ETH 1 | ||||||
| 
 | 
 | ||||||
| struct arp_entry { | struct arp_entry { | ||||||
|   u16_t ipaddr[2]; |   uip_ipaddr_t ipaddr; | ||||||
|   struct uip_eth_addr ethaddr; |   struct uip_eth_addr ethaddr; | ||||||
|   u8_t time; |   u8_t time; | ||||||
| }; | }; | ||||||
| @ -107,7 +106,7 @@ static const struct uip_eth_addr broadcast_ethaddr = | |||||||
| static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff}; | static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff}; | ||||||
| 
 | 
 | ||||||
| static struct arp_entry arp_table[UIP_ARPTAB_SIZE]; | static struct arp_entry arp_table[UIP_ARPTAB_SIZE]; | ||||||
| static u16_t ipaddr[2]; | static uip_ipaddr_t ipaddr; | ||||||
| static u8_t i, c; | static u8_t i, c; | ||||||
| 
 | 
 | ||||||
| static u8_t arptime; | static u8_t arptime; | ||||||
| @ -115,6 +114,15 @@ static u8_t tmpage; | |||||||
| 
 | 
 | ||||||
| #define BUF   ((struct arp_hdr *)&uip_buf[0]) | #define BUF   ((struct arp_hdr *)&uip_buf[0]) | ||||||
| #define IPBUF ((struct ethip_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. |  * Initialize the ARP module. | ||||||
| @ -125,7 +133,7 @@ void | |||||||
| uip_arp_init(void) | uip_arp_init(void) | ||||||
| { | { | ||||||
|   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { |   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { | ||||||
|     memset(arp_table[i].ipaddr, 0, 4); |     memset(&arp_table[i].ipaddr, 0, 4); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| /*-----------------------------------------------------------------------------------*/ | /*-----------------------------------------------------------------------------------*/ | ||||||
| @ -146,16 +154,16 @@ uip_arp_timer(void) | |||||||
|   ++arptime; |   ++arptime; | ||||||
|   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { |   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { | ||||||
|     tabptr = &arp_table[i]; |     tabptr = &arp_table[i]; | ||||||
|     if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 && |     if(uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr) && | ||||||
|        arptime - tabptr->time >= UIP_ARP_MAXAGE) { |        arptime - tabptr->time >= UIP_ARP_MAXAGE) { | ||||||
|       memset(tabptr->ipaddr, 0, 4); |       memset(&tabptr->ipaddr, 0, 4); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| /*-----------------------------------------------------------------------------------*/ | /*-----------------------------------------------------------------------------------*/ | ||||||
| static void | static void | ||||||
| uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr) | uip_arp_update(uip_ipaddr_t *ipaddr, struct uip_eth_addr *ethaddr) | ||||||
| { | { | ||||||
|   register struct arp_entry *tabptr; |   register struct arp_entry *tabptr; | ||||||
|   /* Walk through the ARP mapping table and try to find an entry to
 |   /* Walk through the ARP mapping table and try to find an entry to
 | ||||||
| @ -165,13 +173,11 @@ uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr) | |||||||
| 
 | 
 | ||||||
|     tabptr = &arp_table[i]; |     tabptr = &arp_table[i]; | ||||||
|     /* Only check those entries that are actually in use. */ |     /* Only check those entries that are actually in use. */ | ||||||
|     if(tabptr->ipaddr[0] != 0 && |     if(!uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) { | ||||||
|        tabptr->ipaddr[1] != 0) { |  | ||||||
| 
 | 
 | ||||||
|       /* Check if the source IP address of the incoming packet matches
 |       /* Check if the source IP address of the incoming packet matches
 | ||||||
|          the IP address in this ARP table entry. */ |          the IP address in this ARP table entry. */ | ||||||
|       if(ipaddr[0] == tabptr->ipaddr[0] && |       if(uip_ipaddr_cmp(ipaddr, &tabptr->ipaddr)) { | ||||||
| 	 ipaddr[1] == tabptr->ipaddr[1]) { |  | ||||||
| 	  | 	  | ||||||
| 	/* An old entry found, update this and return. */ | 	/* An old entry found, update this and return. */ | ||||||
| 	memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); | 	memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); | ||||||
| @ -188,8 +194,7 @@ uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr) | |||||||
|   /* First, we try to find an unused entry in the ARP table. */ |   /* First, we try to find an unused entry in the ARP table. */ | ||||||
|   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { |   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { | ||||||
|     tabptr = &arp_table[i]; |     tabptr = &arp_table[i]; | ||||||
|     if(tabptr->ipaddr[0] == 0 && |     if(uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) { | ||||||
|        tabptr->ipaddr[1] == 0) { |  | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @ -212,7 +217,7 @@ uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr) | |||||||
| 
 | 
 | ||||||
|   /* Now, i is the ARP table entry which we will fill with the new
 |   /* Now, i is the ARP table entry which we will fill with the new
 | ||||||
|      information. */ |      information. */ | ||||||
|   memcpy(tabptr->ipaddr, ipaddr, 4); |   uip_ipaddr_copy(&tabptr->ipaddr, ipaddr); | ||||||
|   memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); |   memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); | ||||||
|   tabptr->time = arptime; |   tabptr->time = arptime; | ||||||
| } | } | ||||||
| @ -288,24 +293,28 @@ uip_arp_arpin(void) | |||||||
|   case HTONS(ARP_REQUEST): |   case HTONS(ARP_REQUEST): | ||||||
|     /* ARP request. If it asked for our address, we send out a
 |     /* ARP request. If it asked for our address, we send out a
 | ||||||
|        reply. */ |        reply. */ | ||||||
|     if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) { |     /*    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
 |       /* First, we register the one who made the request in our ARP
 | ||||||
| 	 table, since it is likely that we will do more communication | 	 table, since it is likely that we will do more communication | ||||||
| 	 with this host in the future. */ | 	 with this host in the future. */ | ||||||
|       uip_arp_update(BUF->sipaddr, &BUF->shwaddr); |       uip_arp_update(&BUF->sipaddr, &BUF->shwaddr); | ||||||
|        |        | ||||||
|       /* The reply opcode is 2. */ |       BUF->opcode = HTONS(ARP_REPLY); | ||||||
|       BUF->opcode = HTONS(2); |  | ||||||
| 
 | 
 | ||||||
|       memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6); |       memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6); | ||||||
|       memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6); |       memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6); | ||||||
|       memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6); |       memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6); | ||||||
|       memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6); |       memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6); | ||||||
|        |        | ||||||
|       BUF->dipaddr[0] = BUF->sipaddr[0]; |       uip_ipaddr_copy(&BUF->dipaddr, &BUF->sipaddr); | ||||||
|       BUF->dipaddr[1] = BUF->sipaddr[1]; |       uip_ipaddr_copy(&BUF->sipaddr, &uip_hostaddr); | ||||||
|       BUF->sipaddr[0] = uip_hostaddr[0]; |  | ||||||
|       BUF->sipaddr[1] = uip_hostaddr[1]; |  | ||||||
| 
 | 
 | ||||||
|       BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP); |       BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP); | ||||||
|       uip_len = sizeof(struct arp_hdr); |       uip_len = sizeof(struct arp_hdr); | ||||||
| @ -314,8 +323,8 @@ uip_arp_arpin(void) | |||||||
|   case HTONS(ARP_REPLY): |   case HTONS(ARP_REPLY): | ||||||
|     /* ARP reply. We insert or update the ARP table if it was meant
 |     /* ARP reply. We insert or update the ARP table if it was meant
 | ||||||
|        for us. */ |        for us. */ | ||||||
|     if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) { |     if(uip_ipaddr_cmp(&BUF->dipaddr, &uip_hostaddr)) { | ||||||
|       uip_arp_update(BUF->sipaddr, &BUF->shwaddr); |       uip_arp_update(&BUF->sipaddr, &BUF->shwaddr); | ||||||
|     } |     } | ||||||
|     break; |     break; | ||||||
|   } |   } | ||||||
| @ -363,23 +372,23 @@ uip_arp_out(void) | |||||||
|      packet with an ARP request for the IP address. */ |      packet with an ARP request for the IP address. */ | ||||||
| 
 | 
 | ||||||
|   /* First check if destination is a local broadcast. */ |   /* First check if destination is a local broadcast. */ | ||||||
|   if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) { |   if(uip_ipaddr_cmp(&IPBUF->destipaddr, &uip_broadcast_addr)) { | ||||||
|     memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6); |     memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6); | ||||||
|   } else { |   } else { | ||||||
|     /* Check if the destination address is on the local network. */ |     /* Check if the destination address is on the local network. */ | ||||||
|     if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) { |     if(!uip_ipaddr_maskcmp(&IPBUF->destipaddr, &uip_hostaddr, &uip_netmask)) { | ||||||
|       /* Destination address was not on the local network, so we need to
 |       /* Destination address was not on the local network, so we need to
 | ||||||
| 	 use the default router's IP address instead of the destination | 	 use the default router's IP address instead of the destination | ||||||
| 	 address when determining the MAC address. */ | 	 address when determining the MAC address. */ | ||||||
|       uip_ipaddr_copy(ipaddr, uip_draddr); |       uip_ipaddr_copy(&ipaddr, &uip_draddr); | ||||||
|     } else { |     } else { | ||||||
|       /* Else, we use the destination IP address. */ |       /* Else, we use the destination IP address. */ | ||||||
|       uip_ipaddr_copy(ipaddr, IPBUF->destipaddr); |       uip_ipaddr_copy(&ipaddr, &IPBUF->destipaddr); | ||||||
|     } |     } | ||||||
|        |        | ||||||
|     for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { |     for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { | ||||||
|       tabptr = &arp_table[i]; |       tabptr = &arp_table[i]; | ||||||
|       if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) { |       if(uip_ipaddr_cmp(&ipaddr, &tabptr->ipaddr)) { | ||||||
| 	break; | 	break; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @ -393,8 +402,8 @@ uip_arp_out(void) | |||||||
|       memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6); |       memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6); | ||||||
|       memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6); |       memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6); | ||||||
|      |      | ||||||
|       uip_ipaddr_copy(BUF->dipaddr, ipaddr); |       uip_ipaddr_copy(&BUF->dipaddr, &ipaddr); | ||||||
|       uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr); |       uip_ipaddr_copy(&BUF->sipaddr, &uip_hostaddr); | ||||||
|       BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */ |       BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */ | ||||||
|       BUF->hwtype = HTONS(ARP_HWTYPE_ETH); |       BUF->hwtype = HTONS(ARP_HWTYPE_ETH); | ||||||
|       BUF->protocol = HTONS(UIP_ETHTYPE_IP); |       BUF->protocol = HTONS(UIP_ETHTYPE_IP); | ||||||
|  | |||||||
| @ -45,7 +45,7 @@ | |||||||
|  * |  * | ||||||
|  * This file is part of the uIP TCP/IP stack. |  * This file is part of the uIP TCP/IP stack. | ||||||
|  * |  * | ||||||
|  * $Id: uip_arp.h,v 1.5 2006/06/11 21:46:39 adam Exp $ |  * $Id: uip_arp.h,v 1.2 2006/08/26 23:58:45 oliverschmidt Exp $ | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -66,9 +66,9 @@ struct uip_eth_hdr { | |||||||
|   u16_t type; |   u16_t type; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #define UIP_ETHTYPE_ARP 0x0806 | #define UIP_ETHTYPE_ARP  0x0806 | ||||||
| #define UIP_ETHTYPE_IP  0x0800 | #define UIP_ETHTYPE_IP   0x0800 | ||||||
| #define UIP_ETHTYPE_IP6 0x86dd | #define UIP_ETHTYPE_IPV6 0x86dd | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* The uip_arp_init() function must be called before any of the other
 | /* The uip_arp_init() function must be called before any of the other
 | ||||||
| @ -139,6 +139,7 @@ void uip_arp_timer(void); | |||||||
|                               uip_ethaddr.addr[5] = eaddr.addr[5];} while(0) |                               uip_ethaddr.addr[5] = eaddr.addr[5];} while(0) | ||||||
| 
 | 
 | ||||||
| /** @} */ | /** @} */ | ||||||
| /** @} */ | 
 | ||||||
| 
 | 
 | ||||||
| #endif /* __UIP_ARP_H__ */ | #endif /* __UIP_ARP_H__ */ | ||||||
|  | /** @} */ | ||||||
|  | |||||||
| @ -1,74 +0,0 @@ | |||||||
| /*
 |  | ||||||
|  * Copyright (c) 2004, Adam Dunkels and the Swedish Institute of |  | ||||||
|  * Computer Science. |  | ||||||
|  * All rights reserved. |  | ||||||
|  * |  | ||||||
|  * Redistribution and use in source and binary forms, with or without |  | ||||||
|  * modification, are permitted provided that the following conditions |  | ||||||
|  * are met: |  | ||||||
|  * 1. Redistributions of source code must retain the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer. |  | ||||||
|  * 2. Redistributions in binary form must reproduce the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer in the |  | ||||||
|  *    documentation and/or other materials provided with the distribution. |  | ||||||
|  * 3. The name of the author may not be used to endorse or promote |  | ||||||
|  *    products derived from this software without specific prior |  | ||||||
|  *    written permission. |  | ||||||
|  * |  | ||||||
|  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS |  | ||||||
|  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |  | ||||||
|  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |  | ||||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |  | ||||||
|  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |  | ||||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |  | ||||||
|  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |  | ||||||
|  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |  | ||||||
|  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |  | ||||||
|  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |  | ||||||
|  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |  | ||||||
|  * |  | ||||||
|  * This file is part of the uIP TCP/IP stack |  | ||||||
|  * |  | ||||||
|  * $Id: uiplib.c,v 1.2 2006/06/12 08:00:31 adam Exp $ |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| #include "uip.h" |  | ||||||
| #include "uiplib.h" |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /*-----------------------------------------------------------------------------------*/ |  | ||||||
| unsigned char |  | ||||||
| uiplib_ipaddrconv(char *addrstr, unsigned char *ipaddr) |  | ||||||
| { |  | ||||||
|   unsigned char tmp; |  | ||||||
|   char c; |  | ||||||
|   unsigned char i, j; |  | ||||||
| 
 |  | ||||||
|   tmp = 0; |  | ||||||
|    |  | ||||||
|   for(i = 0; i < 4; ++i) { |  | ||||||
|     j = 0; |  | ||||||
|     do { |  | ||||||
|       c = *addrstr; |  | ||||||
|       ++j; |  | ||||||
|       if(j > 4) { |  | ||||||
| 	return 0; |  | ||||||
|       } |  | ||||||
|       if(c == '.' || c == 0) { |  | ||||||
| 	*ipaddr = tmp; |  | ||||||
| 	++ipaddr; |  | ||||||
| 	tmp = 0; |  | ||||||
|       } else if(c >= '0' && c <= '9') { |  | ||||||
| 	tmp = (tmp * 10) + (c - '0'); |  | ||||||
|       } else { |  | ||||||
| 	return 0; |  | ||||||
|       } |  | ||||||
|       ++addrstr; |  | ||||||
|     } while(c != '.' && c != 0); |  | ||||||
|   } |  | ||||||
|   return 1; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /*-----------------------------------------------------------------------------------*/ |  | ||||||
| @ -1,71 +0,0 @@ | |||||||
| /**
 |  | ||||||
|  * \file |  | ||||||
|  * Various uIP library functions. |  | ||||||
|  * \author |  | ||||||
|  * Adam Dunkels <adam@sics.se> |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * Copyright (c) 2002, Adam Dunkels. |  | ||||||
|  * All rights reserved. |  | ||||||
|  * |  | ||||||
|  * Redistribution and use in source and binary forms, with or without |  | ||||||
|  * modification, are permitted provided that the following conditions |  | ||||||
|  * are met: |  | ||||||
|  * 1. Redistributions of source code must retain the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer. |  | ||||||
|  * 2. Redistributions in binary form must reproduce the above |  | ||||||
|  *    copyright notice, this list of conditions and the following |  | ||||||
|  *    disclaimer in the documentation and/or other materials provided |  | ||||||
|  *    with the distribution. |  | ||||||
|  * 3. The name of the author may not be used to endorse or promote |  | ||||||
|  *    products derived from this software without specific prior |  | ||||||
|  *    written permission. |  | ||||||
|  * |  | ||||||
|  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS |  | ||||||
|  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |  | ||||||
|  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |  | ||||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |  | ||||||
|  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |  | ||||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |  | ||||||
|  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |  | ||||||
|  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |  | ||||||
|  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |  | ||||||
|  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |  | ||||||
|  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |  | ||||||
|  * |  | ||||||
|  * This file is part of the uIP TCP/IP stack |  | ||||||
|  * |  | ||||||
|  * $Id: uiplib.h,v 1.1 2006/06/07 09:15:19 adam Exp $ |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| #ifndef __UIPLIB_H__ |  | ||||||
| #define __UIPLIB_H__ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * \addtogroup uipconvfunc |  | ||||||
|  * @{ |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Convert a textual representation of an IP address to a numerical representation. |  | ||||||
|  * |  | ||||||
|  * This function takes a textual representation of an IP address in |  | ||||||
|  * the form a.b.c.d and converts it into a 4-byte array that can be |  | ||||||
|  * used by other uIP functions. |  | ||||||
|  * |  | ||||||
|  * \param addrstr A pointer to a string containing the IP address in |  | ||||||
|  * textual form. |  | ||||||
|  * |  | ||||||
|  * \param addr A pointer to a 4-byte array that will be filled in with |  | ||||||
|  * the numerical representation of the address. |  | ||||||
|  * |  | ||||||
|  * \retval 0 If the IP address could not be parsed. |  | ||||||
|  * \retval Non-zero If the IP address was parsed. |  | ||||||
|  */ |  | ||||||
| unsigned char uiplib_ipaddrconv(char *addrstr, unsigned char *addr); |  | ||||||
| 
 |  | ||||||
| /** @} */ |  | ||||||
| 
 |  | ||||||
| #endif /* __UIPLIB_H__ */ |  | ||||||
| @ -1,15 +1,20 @@ | |||||||
|  | /**
 | ||||||
|  |  * \addtogroup uip | ||||||
|  |  * @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * \defgroup uipopt Configuration options for uIP |  * \defgroup uipopt Configuration options for uIP | ||||||
|  * @{ |  * @{ | ||||||
|  * |  * | ||||||
|  * uIP is configured using the per-project configuration file |  * uIP is configured using the per-project configuration file | ||||||
|  * uipopt.h. This file contains all compile-time options for uIP and |  * "uipopt.h". This file contains all compile-time options for uIP and | ||||||
|  * should be tweaked to match each specific project. The uIP |  * should be tweaked to match each specific project. The uIP | ||||||
|  * distribution contains a documented example "uipopt.h" that can be |  * distribution contains a documented example "uipopt.h" that can be | ||||||
|  * copied and modified for each project. |  * copied and modified for each project. | ||||||
|  * |  * | ||||||
|  * \note Most of the configuration options in the uipopt.h should not |  * \note Contiki does not use the uipopt.h file to configure uIP, but | ||||||
|  * be changed, but rather the per-project uip-conf.h file. |  * uses a per-port uip-conf.h file that should be edited instead. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
| @ -53,7 +58,7 @@ | |||||||
|  * |  * | ||||||
|  * This file is part of the uIP TCP/IP stack. |  * This file is part of the uIP TCP/IP stack. | ||||||
|  * |  * | ||||||
|  * $Id: uipopt.h,v 1.4 2006/06/12 08:00:31 adam Exp $ |  * $Id: uipopt.h,v 1.11 2009/04/10 00:37:48 adamdunkels Exp $ | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -67,23 +72,23 @@ | |||||||
| #define UIP_BIG_ENDIAN     1234 | #define UIP_BIG_ENDIAN     1234 | ||||||
| #endif /* UIP_BIG_ENDIAN */ | #endif /* UIP_BIG_ENDIAN */ | ||||||
| 
 | 
 | ||||||
| #include "uip-conf.h" |  | ||||||
| 
 |  | ||||||
| /*------------------------------------------------------------------------------*/ | /*------------------------------------------------------------------------------*/ | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * \name Static configuration options |  * \defgroup uipoptstaticconf Static configuration options | ||||||
|  * @{ |  * @{ | ||||||
|  * |  * | ||||||
|  * These configuration options can be used for setting the IP address |  * These configuration options can be used for setting the IP address | ||||||
|  * settings statically, but only if UIP_FIXEDADDR is set to 1. The |  * settings statically, but only if UIP_FIXEDADDR is set to 1. The | ||||||
|  * configuration options for a specific node includes IP address, |  * configuration options for a specific node includes IP address, | ||||||
|  * netmask and default router as well as the Ethernet address. The |  * netmask and default router as well as the Ethernet address. The | ||||||
|  * netmask, default router and Ethernet address are appliciable only |  * netmask, default router and Ethernet address are applicable only | ||||||
|  * if uIP should be run over Ethernet. |  * 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. |  * All of these should be changed to suit your project. | ||||||
| */ |  */ | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Determines if uIP should use a fixed IP address or not. |  * Determines if uIP should use a fixed IP address or not. | ||||||
| @ -97,7 +102,7 @@ | |||||||
| #define UIP_FIXEDADDR    0 | #define UIP_FIXEDADDR    0 | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Ping IP address asignment. |  * Ping IP address assignment. | ||||||
|  * |  * | ||||||
|  * uIP uses a "ping" packets for setting its own IP address if this |  * 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 |  * option is set. If so, uIP will start with an empty IP address and | ||||||
| @ -129,7 +134,7 @@ | |||||||
| /** @} */ | /** @} */ | ||||||
| /*------------------------------------------------------------------------------*/ | /*------------------------------------------------------------------------------*/ | ||||||
| /**
 | /**
 | ||||||
|  * \name IP configuration options |  * \defgroup uipoptip IP configuration options | ||||||
|  * @{ |  * @{ | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| @ -140,11 +145,18 @@ | |||||||
|  */ |  */ | ||||||
| #define UIP_TTL         64 | #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. |  * Turn on support for IP packet reassembly. | ||||||
|  * |  * | ||||||
|  * uIP supports reassembly of fragmented IP packets. This features |  * uIP supports reassembly of fragmented IP packets. This features | ||||||
|  * requires an additonal amount of RAM to hold the reassembly buffer |  * requires an additional amount of RAM to hold the reassembly buffer | ||||||
|  * and the reassembly code size is approximately 700 bytes.  The |  * and the reassembly code size is approximately 700 bytes.  The | ||||||
|  * reassembly buffer is of the same size as the uip_buf buffer |  * reassembly buffer is of the same size as the uip_buf buffer | ||||||
|  * (configured by UIP_BUFSIZE). |  * (configured by UIP_BUFSIZE). | ||||||
| @ -153,32 +165,84 @@ | |||||||
|  * |  * | ||||||
|  * \hideinitializer |  * \hideinitializer | ||||||
|  */ |  */ | ||||||
|  | #ifdef UIP_CONF_REASSEMBLY | ||||||
|  | #define UIP_REASSEMBLY UIP_CONF_REASSEMBLY | ||||||
|  | #else /* UIP_CONF_REASSEMBLY */ | ||||||
| #define UIP_REASSEMBLY 0 | #define UIP_REASSEMBLY 0 | ||||||
| 
 | #endif /* UIP_CONF_REASSEMBLY */ | ||||||
| /**
 |  | ||||||
|  * The maximum time an IP fragment should wait in the reassembly |  | ||||||
|  * buffer before it is dropped. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| #define UIP_REASS_MAXAGE 40 |  | ||||||
| 
 |  | ||||||
| /** @} */ | /** @} */ | ||||||
| 
 | 
 | ||||||
| /*------------------------------------------------------------------------------*/ | /*------------------------------------------------------------------------------*/ | ||||||
| /**
 | /**
 | ||||||
|  * \name UDP configuration options |  * \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 wether UDP support should be compiled in or not. |  * Toggles whether UDP support should be compiled in or not. | ||||||
|  * |  * | ||||||
|  * \hideinitializer |  * \hideinitializer | ||||||
|  */ |  */ | ||||||
| #ifdef UIP_CONF_UDP | #ifdef UIP_CONF_UDP | ||||||
| #define UIP_UDP UIP_CONF_UDP | #define UIP_UDP UIP_CONF_UDP | ||||||
| #else /* UIP_CONF_UDP */ | #else /* UIP_CONF_UDP */ | ||||||
| #define UIP_UDP           0 | #define UIP_UDP           1 | ||||||
| #endif /* UIP_CONF_UDP */ | #endif /* UIP_CONF_UDP */ | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
| @ -216,28 +280,43 @@ | |||||||
| /** @} */ | /** @} */ | ||||||
| /*------------------------------------------------------------------------------*/ | /*------------------------------------------------------------------------------*/ | ||||||
| /**
 | /**
 | ||||||
|  * \name TCP configuration options |  * \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 |  * Determines if support for opening connections from uIP should be | ||||||
|  * compiled in. |  * compiled in. | ||||||
|  * |  * | ||||||
|  * If the applications that are running on top of uIP for this project |  * If the applications that are running on top of uIP for this project | ||||||
|  * do not need to open outgoing TCP connections, this configration |  * do not need to open outgoing TCP connections, this configuration | ||||||
|  * option can be turned off to reduce the code size of uIP. |  * option can be turned off to reduce the code size of uIP. | ||||||
|  * |  * | ||||||
|  * \hideinitializer |  * \hideinitializer | ||||||
|  */ |  */ | ||||||
|  | #ifndef UIP_CONF_ACTIVE_OPEN | ||||||
| #define UIP_ACTIVE_OPEN 1 | #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. |  * The maximum number of simultaneously open TCP connections. | ||||||
|  * |  * | ||||||
|  * Since the TCP connections are statically allocated, turning this |  * Since the TCP connections are statically allocated, turning this | ||||||
|  * configuration knob down results in less RAM used. Each TCP |  * configuration knob down results in less RAM used. Each TCP | ||||||
|  * connection requires approximatly 30 bytes of memory. |  * connection requires approximately 30 bytes of memory. | ||||||
|  * |  * | ||||||
|  * \hideinitializer |  * \hideinitializer | ||||||
|  */ |  */ | ||||||
| @ -302,12 +381,16 @@ | |||||||
|  * This is should not be to set to more than |  * This is should not be to set to more than | ||||||
|  * UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN. |  * 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) | #define UIP_TCP_MSS     (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * The size of the advertised receiver's window. |  * The size of the advertised receiver's window. | ||||||
|  * |  * | ||||||
|  * Should be set low (i.e., to the size of the uip_buf buffer) is the |  * 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) |  * application is slow to process incoming data, or high (32768 bytes) | ||||||
|  * if the application processes data quickly. |  * if the application processes data quickly. | ||||||
|  * |  * | ||||||
| @ -322,7 +405,7 @@ | |||||||
| /**
 | /**
 | ||||||
|  * How long a connection should stay in the TIME_WAIT state. |  * How long a connection should stay in the TIME_WAIT state. | ||||||
|  * |  * | ||||||
|  * This configiration option has no real implication, and it should be |  * This configuration option has no real implication, and it should be | ||||||
|  * left untouched. |  * left untouched. | ||||||
|  */ |  */ | ||||||
| #define UIP_TIME_WAIT_TIMEOUT 120 | #define UIP_TIME_WAIT_TIMEOUT 120 | ||||||
| @ -331,7 +414,7 @@ | |||||||
| /** @} */ | /** @} */ | ||||||
| /*------------------------------------------------------------------------------*/ | /*------------------------------------------------------------------------------*/ | ||||||
| /**
 | /**
 | ||||||
|  * \name ARP configuration options |  * \defgroup uipoptarp ARP configuration options | ||||||
|  * @{ |  * @{ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -350,19 +433,70 @@ | |||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * The maxium age of ARP table entries measured in 10ths of seconds. |  * The maximum age of ARP table entries measured in 10ths of seconds. | ||||||
|  * |  * | ||||||
|  * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD |  * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD | ||||||
|  * default). |  * default). | ||||||
|  */ |  */ | ||||||
| #define UIP_ARP_MAXAGE 120 | #define UIP_ARP_MAXAGE 120 | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| /** @} */ | /** @} */ | ||||||
| 
 | 
 | ||||||
| /*------------------------------------------------------------------------------*/ | /*------------------------------------------------------------------------------*/ | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * \name General configuration options |  * \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 | ||||||
|  * @{ |  * @{ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -370,13 +504,13 @@ | |||||||
|  * The size of the uIP packet buffer. |  * The size of the uIP packet buffer. | ||||||
|  * |  * | ||||||
|  * The uIP packet buffer should not be smaller than 60 bytes, and does |  * The uIP packet buffer should not be smaller than 60 bytes, and does | ||||||
|  * not need to be larger than 1500 bytes. Lower size results in lower |  * not need to be larger than 1514 bytes. Lower size results in lower | ||||||
|  * TCP throughput, larger size results in higher TCP throughput. |  * TCP throughput, larger size results in higher TCP throughput. | ||||||
|  * |  * | ||||||
|  * \hideinitializer |  * \hideinitializer | ||||||
|  */ |  */ | ||||||
| #ifndef UIP_CONF_BUFFER_SIZE | #ifndef UIP_CONF_BUFFER_SIZE | ||||||
| #define UIP_BUFSIZE     400 | #define UIP_BUFSIZE UIP_LINK_MTU + UIP_LLH_LEN | ||||||
| #else /* UIP_CONF_BUFFER_SIZE */ | #else /* UIP_CONF_BUFFER_SIZE */ | ||||||
| #define UIP_BUFSIZE UIP_CONF_BUFFER_SIZE | #define UIP_BUFSIZE UIP_CONF_BUFFER_SIZE | ||||||
| #endif /* UIP_CONF_BUFFER_SIZE */ | #endif /* UIP_CONF_BUFFER_SIZE */ | ||||||
| @ -440,18 +574,23 @@ void uip_log(char *msg); | |||||||
|  * found. For Ethernet, this should be set to 14. For SLIP, this |  * found. For Ethernet, this should be set to 14. For SLIP, this | ||||||
|  * should be set to 0. |  * 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 |  * \hideinitializer | ||||||
|  */ |  */ | ||||||
| #ifdef UIP_CONF_LLH_LEN | #ifdef UIP_CONF_LLH_LEN | ||||||
| #define UIP_LLH_LEN UIP_CONF_LLH_LEN | #define UIP_LLH_LEN UIP_CONF_LLH_LEN | ||||||
| #else /* UIP_CONF_LLH_LEN */ | #else /* UIP_LLH_LEN */ | ||||||
| #define UIP_LLH_LEN     14 | #define UIP_LLH_LEN     14 | ||||||
| #endif /* UIP_CONF_LLH_LEN */ | #endif /* UIP_CONF_LLH_LEN */ | ||||||
| 
 | 
 | ||||||
| /** @} */ | /** @} */ | ||||||
| /*------------------------------------------------------------------------------*/ | /*------------------------------------------------------------------------------*/ | ||||||
| /**
 | /**
 | ||||||
|  * \name CPU architecture configuration |  * \defgroup uipoptcpu CPU architecture configuration | ||||||
|  * @{ |  * @{ | ||||||
|  * |  * | ||||||
|  * The CPU architecture configuration is where the endianess of the |  * The CPU architecture configuration is where the endianess of the | ||||||
| @ -464,8 +603,8 @@ void uip_log(char *msg); | |||||||
| /**
 | /**
 | ||||||
|  * The byte order of the CPU architecture on which uIP is to be run. |  * The byte order of the CPU architecture on which uIP is to be run. | ||||||
|  * |  * | ||||||
|  * This option can be either BIG_ENDIAN (Motorola byte order) or |  * This option can be either UIP_BIG_ENDIAN (Motorola byte order) or | ||||||
|  * LITTLE_ENDIAN (Intel byte order). |  * UIP_LITTLE_ENDIAN (Intel byte order). | ||||||
|  * |  * | ||||||
|  * \hideinitializer |  * \hideinitializer | ||||||
|  */ |  */ | ||||||
| @ -478,8 +617,17 @@ void uip_log(char *msg); | |||||||
| /** @} */ | /** @} */ | ||||||
| /*------------------------------------------------------------------------------*/ | /*------------------------------------------------------------------------------*/ | ||||||
| 
 | 
 | ||||||
|  | #include <ff.h> | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | typedef uint8_t u8_t; | ||||||
|  | typedef uint16_t u16_t; | ||||||
|  | typedef uint32_t u32_t; | ||||||
|  | typedef uint32_t uip_stats_t; | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * \name Appication specific configurations |  * \defgroup uipoptapp Application specific configurations | ||||||
|  * @{ |  * @{ | ||||||
|  * |  * | ||||||
|  * An uIP application is implemented using a single application |  * An uIP application is implemented using a single application | ||||||
| @ -497,18 +645,20 @@ void uip_log(char *msg); | |||||||
|  * The following example illustrates how this can look. |  * The following example illustrates how this can look. | ||||||
|  \code |  \code | ||||||
| 
 | 
 | ||||||
| void httpd_appcall(void); |  void httpd_appcall(void); | ||||||
| #define UIP_APPCALL     httpd_appcall |  #define UIP_APPCALL     httpd_appcall | ||||||
| 
 | 
 | ||||||
| struct httpd_state { |  struct httpd_state { | ||||||
|   u8_t state; |  u8_t state; | ||||||
|   u16_t count; |  u16_t count; | ||||||
|   char *dataptr; |  char *dataptr; | ||||||
|   char *script; |  char *script; | ||||||
| }; |  }; | ||||||
| typedef struct httpd_state uip_tcp_appstate_t |  typedef struct httpd_state uip_tcp_appstate_t | ||||||
|  \endcode |  \endcode | ||||||
|  */ | */ | ||||||
|  | 	#define UIP_UDP_APPCALL DHCPApp_Callback | ||||||
|  | 	void UIP_UDP_APPCALL(void); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * \var #define UIP_APPCALL |  * \var #define UIP_APPCALL | ||||||
| @ -517,6 +667,8 @@ typedef struct httpd_state uip_tcp_appstate_t | |||||||
|  * response to TCP/IP events. |  * response to TCP/IP events. | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
|  | 	#define UIP_APPCALL     WebserverApp_Callback | ||||||
|  | 	void UIP_APPCALL(void); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * \var typedef uip_tcp_appstate_t |  * \var typedef uip_tcp_appstate_t | ||||||
| @ -525,6 +677,17 @@ typedef struct httpd_state uip_tcp_appstate_t | |||||||
|  * uip_conn structure. This usually is typedef:ed to a struct holding |  * uip_conn structure. This usually is typedef:ed to a struct holding | ||||||
|  * application state information. |  * application state information. | ||||||
|  */ |  */ | ||||||
|  | 	typedef struct | ||||||
|  | 	{ | ||||||
|  | 		uint8_t  CurrentState; | ||||||
|  | 		uint8_t  NextState; | ||||||
|  | 		 | ||||||
|  | 		char     FileName[30]; | ||||||
|  | 		FIL      FileHandle; | ||||||
|  | 		bool     FileOpen; | ||||||
|  | 		uint32_t ACKedFilePos; | ||||||
|  | 		uint16_t SentChunkSize; | ||||||
|  | 	} uip_tcp_appstate_t; | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * \var typedef uip_udp_appstate_t |  * \var typedef uip_udp_appstate_t | ||||||
| @ -533,7 +696,21 @@ typedef struct httpd_state uip_tcp_appstate_t | |||||||
|  * uip_conn structure. This usually is typedef:ed to a struct holding |  * uip_conn structure. This usually is typedef:ed to a struct holding | ||||||
|  * application state information. |  * application state information. | ||||||
|  */ |  */ | ||||||
| /** @} */ | 	typedef struct | ||||||
|  | 	{ | ||||||
|  | 		uint8_t CurrentState; | ||||||
|  | 		struct  uip_udp_conn* Connection; | ||||||
|  | 		 | ||||||
|  | 		struct | ||||||
|  | 		{ | ||||||
|  | 			uint8_t AllocatedIP[4]; | ||||||
|  | 			uint8_t Netmask[4]; | ||||||
|  | 			uint8_t GatewayIP[4]; | ||||||
|  | 			uint8_t ServerIP[4]; | ||||||
|  | 		} DHCPOffer_Data; | ||||||
|  | 	} uip_udp_appstate_t; | ||||||
| /** @} */ | /** @} */ | ||||||
| 
 | 
 | ||||||
| #endif /* __UIPOPT_H__ */ | #endif /* __UIPOPT_H__ */ | ||||||
|  | /** @} */ | ||||||
|  | /** @} */ | ||||||
|  | |||||||
| @ -76,9 +76,10 @@ | |||||||
|  *    <td><b>Description:</b></td> |  *    <td><b>Description:</b></td> | ||||||
|  *   </tr> |  *   </tr> | ||||||
|  *   <tr> |  *   <tr> | ||||||
|  *    <td>ENABLE_DHCP</td> |  *    <td>ENABLE_DHCP=<i>x</i></td> | ||||||
|  *    <td>Makefile CDEFS</td> |  *    <td>Makefile CDEFS</td> | ||||||
|  *    <td>When defined, enables the DHCP client for dynamic IP allocation of the network settings from a DHCP server.</td> |  *    <td>When set to 1, this enables the DHCP client for dynamic IP allocation of the network settings from a DHCP server. | ||||||
|  |  *        To disable DHCP and use the fixed address settings set elsewhere, set this to zero (do not undefine it).</td> | ||||||
|  *   </tr> |  *   </tr> | ||||||
|  *   <tr> |  *   <tr> | ||||||
|  *    <td>DEVICE_IP_ADDRESS</td> |  *    <td>DEVICE_IP_ADDRESS</td> | ||||||
|  | |||||||
| @ -135,8 +135,7 @@ SRC = $(TARGET).c                                                 \ | |||||||
| 	  Lib/uip/uip.c                                               \
 | 	  Lib/uip/uip.c                                               \
 | ||||||
| 	  Lib/uip/uip_arp.c                                           \
 | 	  Lib/uip/uip_arp.c                                           \
 | ||||||
| 	  Lib/uip/timer.c                                             \
 | 	  Lib/uip/timer.c                                             \
 | ||||||
| 	  Lib/uip/uip-neighbor.c                                      \
 | 	  Lib/uip/clock.c                                             \
 | ||||||
| 	  Lib/uip/conf/clock-arch.c                                   \
 |  | ||||||
| 	  Lib/FATFs/diskio.c                                          \
 | 	  Lib/FATFs/diskio.c                                          \
 | ||||||
| 	  Lib/FATFs/ff.c                                              \
 | 	  Lib/FATFs/ff.c                                              \
 | ||||||
| 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \
 | 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \
 | ||||||
| @ -198,7 +197,13 @@ CSTANDARD = -std=gnu99 | |||||||
| 
 | 
 | ||||||
| # Place -D or -U options here for C sources
 | # Place -D or -U options here for C sources
 | ||||||
| CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD) $(LUFA_OPTS) | CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD) $(LUFA_OPTS) | ||||||
| CDEFS += -DENABLE_DHCP | CDEFS += -DENABLE_DHCP=1 | ||||||
|  | 
 | ||||||
|  | CDEFS += -DUIP_CONF_UDP_CONNS=1 -DUIP_CONF_TCP=1 -DUIP_CONF_MAX_CONNECTIONS=5 | ||||||
|  | CDEFS += -DUIP_CONF_MAX_LISTENPORTS=1 -DUIP_CONF_BUFFER_SIZE=1514  | ||||||
|  | CDEFS += -DUIP_CONF_LL_802154=0 -DUIP_CONF_LL_80211=0 -DUIP_CONF_ROUTER=0 -DUIP_CONF_ICMP6=0 -DUIP_CONF_LL_802154=0 | ||||||
|  | CDEFS += -DUIP_ARCH_ADD32=0 -DUIP_ARCH_CHKSUM=0 -DUIP_CONF_ICMP_DEST_UNREACH=1 -DUIP_NEIGHBOR_CONF_ADDRTYPE=0 | ||||||
|  | CDEFS += -DUIP_CONF_UDP=ENABLE_DHCP | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # Place -D or -U options here for ASM sources
 | # Place -D or -U options here for ASM sources
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Dean Camera
						Dean Camera