Commit 84e1241f authored by Dean Camera's avatar Dean Camera
Browse files

Replace the Webserver demo's uIP with the latest code ripped from the Contiki...

Replace the Webserver demo's uIP with the latest code ripped from the Contiki project by Adam Dunkels.
parent 10082609
This diff is collapsed.
...@@ -127,6 +127,115 @@ ...@@ -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 @@ ...@@ -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) ...@@ -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) ...@@ -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" ...@@ -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) ...@@ -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)
......
#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;
}
/** #ifndef __CLOCK_ARCH_H__
* \defgroup clock Clock interface #define __CLOCK_ARCH_H__
*
* The clock interface is the interface between the \ref timer "timer library" #include <stdint.h>
* and the platform specific clock functionality. The clock
* interface must be implemented for each platform that uses the \ref typedef uint16_t clock_time_t;
* timer "timer library". #define CLOCK_SECOND 100
* void clock_init(void);
* The clock interface does only one this: it measures time. The clock clock_time_t clock_time(void);
* interface provides a macro, CLOCK_SECOND, which corresponds to one
* second of system time. #endif /* __CLOCK_ARCH_H__ */
*
* \sa \ref timer "Timer library"
*
* @{
*/
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: clock.h,v 1.3 2006/06/11 21:46:39 adam Exp $
*/
#ifndef __CLOCK_H__
#define __CLOCK_H__
#include "clock-arch.h"
/**
* Initialize the clock library.
*
* This function initializes the clock library and should be called
* from the main() function of the system.
*
*/
void clock_init(void);
/**
* Get the current clock time.
*
* This function returns the current system clock time.
*
* \return The current clock time, measured in system ticks.
*/
clock_time_t clock_time(void);
/**
* A second, measured in system clock time.
*
* \hideinitializer
*/
#ifdef CLOCK_CONF_SECOND
#define CLOCK_SECOND CLOCK_CONF_SECOND
#else
#define CLOCK_SECOND (clock_time_t)32
#endif
#endif /* __CLOCK_H__ */
/** @} */
/*
* 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__ */
/** @} */
/*
* 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__ */
/** @} */
/*
* 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__ */
/** @} */
/** @} */
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.