aboutsummaryrefslogtreecommitdiffstats
path: root/lib/lufa/Projects/Webserver
diff options
context:
space:
mode:
authorWilliam Chang <william@factual.com>2019-11-20 22:17:07 -0800
committerWilliam Chang <william@factual.com>2019-11-20 22:17:07 -0800
commite7f4d56592b3975c38af329e77b4efd9108495e8 (patch)
tree0a416bccbf70bfdbdb9ffcdb3bf136b47378c014 /lib/lufa/Projects/Webserver
parent71493b2f9bbd5f3d18373c518fa14ccafcbf48fc (diff)
parent8416a94ad27b3ff058576f09f35f0704a8b39ff3 (diff)
downloadfirmware-e7f4d56592b3975c38af329e77b4efd9108495e8.tar.gz
firmware-e7f4d56592b3975c38af329e77b4efd9108495e8.tar.bz2
firmware-e7f4d56592b3975c38af329e77b4efd9108495e8.zip
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'lib/lufa/Projects/Webserver')
m---------lib/lufa0
-rw-r--r--lib/lufa/Projects/Webserver/Config/AppConfig.h73
-rw-r--r--lib/lufa/Projects/Webserver/Config/LUFAConfig.h93
-rw-r--r--lib/lufa/Projects/Webserver/Descriptors.c295
-rw-r--r--lib/lufa/Projects/Webserver/Descriptors.h128
-rw-r--r--lib/lufa/Projects/Webserver/LUFA Webserver RNDIS.inf59
-rw-r--r--lib/lufa/Projects/Webserver/Lib/DHCPClientApp.c208
-rw-r--r--lib/lufa/Projects/Webserver/Lib/DHCPClientApp.h69
-rw-r--r--lib/lufa/Projects/Webserver/Lib/DHCPCommon.c103
-rw-r--r--lib/lufa/Projects/Webserver/Lib/DHCPCommon.h159
-rw-r--r--lib/lufa/Projects/Webserver/Lib/DHCPServerApp.c265
-rw-r--r--lib/lufa/Projects/Webserver/Lib/DHCPServerApp.h64
-rw-r--r--lib/lufa/Projects/Webserver/Lib/DataflashManager.c534
-rw-r--r--lib/lufa/Projects/Webserver/Lib/DataflashManager.h87
-rw-r--r--lib/lufa/Projects/Webserver/Lib/FATFs/00readme.txt135
-rw-r--r--lib/lufa/Projects/Webserver/Lib/FATFs/diskio.c65
-rw-r--r--lib/lufa/Projects/Webserver/Lib/FATFs/diskio.h52
-rw-r--r--lib/lufa/Projects/Webserver/Lib/FATFs/ff.c4139
-rw-r--r--lib/lufa/Projects/Webserver/Lib/FATFs/ff.h337
-rw-r--r--lib/lufa/Projects/Webserver/Lib/FATFs/ffconf.h190
-rw-r--r--lib/lufa/Projects/Webserver/Lib/FATFs/integer.h38
-rw-r--r--lib/lufa/Projects/Webserver/Lib/HTTPServerApp.c284
-rw-r--r--lib/lufa/Projects/Webserver/Lib/HTTPServerApp.h84
-rw-r--r--lib/lufa/Projects/Webserver/Lib/SCSI.c344
-rw-r--r--lib/lufa/Projects/Webserver/Lib/SCSI.h87
-rw-r--r--lib/lufa/Projects/Webserver/Lib/TELNETServerApp.c163
-rw-r--r--lib/lufa/Projects/Webserver/Lib/TELNETServerApp.h71
-rw-r--r--lib/lufa/Projects/Webserver/Lib/uIPManagement.c298
-rw-r--r--lib/lufa/Projects/Webserver/Lib/uIPManagement.h69
-rw-r--r--lib/lufa/Projects/Webserver/Lib/uip/clock.c37
-rw-r--r--lib/lufa/Projects/Webserver/Lib/uip/clock.h13
-rw-r--r--lib/lufa/Projects/Webserver/Lib/uip/timer.c128
-rw-r--r--lib/lufa/Projects/Webserver/Lib/uip/timer.h87
-rw-r--r--lib/lufa/Projects/Webserver/Lib/uip/uip-split.c151
-rw-r--r--lib/lufa/Projects/Webserver/Lib/uip/uip-split.h104
-rw-r--r--lib/lufa/Projects/Webserver/Lib/uip/uip.c1941
-rw-r--r--lib/lufa/Projects/Webserver/Lib/uip/uip.h2130
-rw-r--r--lib/lufa/Projects/Webserver/Lib/uip/uip_arp.c432
-rw-r--r--lib/lufa/Projects/Webserver/Lib/uip/uip_arp.h146
-rw-r--r--lib/lufa/Projects/Webserver/Lib/uip/uipopt.h740
-rw-r--r--lib/lufa/Projects/Webserver/USBDeviceMode.c162
-rw-r--r--lib/lufa/Projects/Webserver/USBDeviceMode.h62
-rw-r--r--lib/lufa/Projects/Webserver/USBHostMode.c172
-rw-r--r--lib/lufa/Projects/Webserver/USBHostMode.h60
-rw-r--r--lib/lufa/Projects/Webserver/Webserver.c77
-rw-r--r--lib/lufa/Projects/Webserver/Webserver.h76
-rw-r--r--lib/lufa/Projects/Webserver/Webserver.txt126
-rw-r--r--lib/lufa/Projects/Webserver/asf.xml96
-rw-r--r--lib/lufa/Projects/Webserver/doxyfile2396
-rw-r--r--lib/lufa/Projects/Webserver/makefile46
50 files changed, 0 insertions, 17675 deletions
diff --git a/lib/lufa b/lib/lufa
new file mode 160000
+Subproject ce10f7642b0459e409839b23cc91498945119b4
diff --git a/lib/lufa/Projects/Webserver/Config/AppConfig.h b/lib/lufa/Projects/Webserver/Config/AppConfig.h
deleted file mode 100644
index 30a265767..000000000
--- a/lib/lufa/Projects/Webserver/Config/AppConfig.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- * \brief Application Configuration Header File
- *
- * This is a header file which is be used to configure some of
- * the application's compile time options, as an alternative to
- * specifying the compile time constants supplied through a
- * makefile or build system.
- *
- * For information on what each token does, refer to the
- * \ref Sec_Options section of the application documentation.
- */
-
-#ifndef _APP_CONFIG_H_
-#define _APP_CONFIG_H_
-
- #define ENABLE_DHCP_CLIENT
- #define ENABLE_DHCP_SERVER
- #define ENABLE_TELNET_SERVER
- #define MAX_URI_LENGTH 50
-
- #define DEVICE_IP_ADDRESS (uint8_t[]){ 10, 0, 0, 2}
- #define DEVICE_NETMASK (uint8_t[]){255, 255, 255, 0}
- #define DEVICE_GATEWAY (uint8_t[]){ 10, 0, 0, 1}
- #define SERVER_MAC_ADDRESS (uint8_t[]){ 1, 0, 1, 0, 1, 0}
-
- #define UIP_CONF_UDP (defined(ENABLE_DHCP_CLIENT) || defined(ENABLE_DHCP_SERVER))
- #define UIP_CONF_BROADCAST 1
- #define UIP_CONF_TCP 1
- #define UIP_CONF_UDP_CONNS 1
- #define UIP_CONF_MAX_CONNECTIONS 3
- #define UIP_CONF_MAX_LISTENPORTS 5
- #define UIP_CONF_BUFFER_SIZE 1514
- #define UIP_CONF_LL_802154 0
- #define UIP_CONF_LL_80211 0
- #define UIP_CONF_ROUTER 0
- #define UIP_CONF_ICMP6 0
- #define UIP_CONF_ICMP_DEST_UNREACH 1
- #define UIP_URGDATA 0
- #define UIP_ARCH_CHKSUM 0
- #define UIP_ARCH_ADD32 0
- #define UIP_NEIGHBOR_CONF_ADDRTYPE 0
-
-#endif
diff --git a/lib/lufa/Projects/Webserver/Config/LUFAConfig.h b/lib/lufa/Projects/Webserver/Config/LUFAConfig.h
deleted file mode 100644
index ba602dbad..000000000
--- a/lib/lufa/Projects/Webserver/Config/LUFAConfig.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- * \brief LUFA Library Configuration Header File
- *
- * This header file is used to configure LUFA's compile time options,
- * as an alternative to the compile time constants supplied through
- * a makefile.
- *
- * For information on what each token does, refer to the LUFA
- * manual section "Summary of Compile Tokens".
- */
-
-#ifndef _LUFA_CONFIG_H_
-#define _LUFA_CONFIG_H_
-
- #if (ARCH == ARCH_AVR8)
-
- /* Non-USB Related Configuration Tokens: */
-// #define DISABLE_TERMINAL_CODES
-
- /* USB Class Driver Related Tokens: */
-// #define HID_HOST_BOOT_PROTOCOL_ONLY
-// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here}
-// #define HID_USAGE_STACK_DEPTH {Insert Value Here}
-// #define HID_MAX_COLLECTIONS {Insert Value Here}
-// #define HID_MAX_REPORTITEMS {Insert Value Here}
-// #define HID_MAX_REPORT_IDS {Insert Value Here}
-// #define NO_CLASS_DRIVER_AUTOFLUSH
-
- /* General USB Driver Related Tokens: */
-// #define ORDERED_EP_CONFIG
- #define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)
-// #define USB_DEVICE_ONLY
-// #define USB_HOST_ONLY
-// #define USB_STREAM_TIMEOUT_MS {Insert Value Here}
-// #define NO_LIMITED_CONTROLLER_CONNECT
-// #define NO_SOF_EVENTS
-
- /* USB Device Mode Driver Related Tokens: */
-// #define USE_RAM_DESCRIPTORS
- #define USE_FLASH_DESCRIPTORS
-// #define USE_EEPROM_DESCRIPTORS
-// #define NO_INTERNAL_SERIAL
- #define FIXED_CONTROL_ENDPOINT_SIZE 8
- #define DEVICE_STATE_AS_GPIOR 0
- #define FIXED_NUM_CONFIGURATIONS 1
-// #define CONTROL_ONLY_DEVICE
- #define INTERRUPT_CONTROL_ENDPOINT
-// #define NO_DEVICE_REMOTE_WAKEUP
-// #define NO_DEVICE_SELF_POWER
-
- /* USB Host Mode Driver Related Tokens: */
- #define HOST_STATE_AS_GPIOR 0
-// #define USB_HOST_TIMEOUT_MS {Insert Value Here}
-// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here}
-// #define NO_AUTO_VBUS_MANAGEMENT
-// #define INVERTED_VBUS_ENABLE_LINE
-
- #else
-
- #error Unsupported architecture for this LUFA configuration file.
-
- #endif
-#endif
diff --git a/lib/lufa/Projects/Webserver/Descriptors.c b/lib/lufa/Projects/Webserver/Descriptors.c
deleted file mode 100644
index 72dda9f12..000000000
--- a/lib/lufa/Projects/Webserver/Descriptors.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
- * computer-readable structures which the host requests upon device enumeration, to determine
- * the device's capabilities and functions.
- */
-
-#include "Descriptors.h"
-
-
-/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
- * device characteristics, including the supported USB version, control endpoint size and the
- * number of device configurations. The descriptor is read out by the USB host when the enumeration
- * process begins.
- */
-const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
-{
- .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
-
- .USBSpecification = VERSION_BCD(1,1,0),
- .Class = USB_CSCP_IADDeviceClass,
- .SubClass = USB_CSCP_IADDeviceSubclass,
- .Protocol = USB_CSCP_IADDeviceProtocol,
-
- .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
-
- .VendorID = 0x03EB,
- .ProductID = 0x2069,
- .ReleaseNumber = VERSION_BCD(0,0,1),
-
- .ManufacturerStrIndex = STRING_ID_Manufacturer,
- .ProductStrIndex = STRING_ID_Product,
- .SerialNumStrIndex = USE_INTERNAL_SERIAL,
-
- .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
-};
-
-/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
- * of the device in one of its supported configurations, including information about any device interfaces
- * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
- * a configuration so that the host may correctly communicate with the USB device.
- */
-const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
-{
- .Config =
- {
- .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
-
- .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
- .TotalInterfaces = 3,
-
- .ConfigurationNumber = 1,
- .ConfigurationStrIndex = NO_DESCRIPTOR,
-
- .ConfigAttributes = USB_CONFIG_ATTR_RESERVED,
-
- .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
- },
-
- .CDC_IAD =
- {
- .Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
-
- .FirstInterfaceIndex = INTERFACE_ID_CDC_CCI,
- .TotalInterfaces = 2,
-
- .Class = CDC_CSCP_CDCClass,
- .SubClass = CDC_CSCP_ACMSubclass,
- .Protocol = CDC_CSCP_VendorSpecificProtocol,
-
- .IADStrIndex = NO_DESCRIPTOR
- },
-
- .CDC_CCI_Interface =
- {
- .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
-
- .InterfaceNumber = INTERFACE_ID_CDC_CCI,
- .AlternateSetting = 0,
-
- .TotalEndpoints = 1,
-
- .Class = CDC_CSCP_CDCClass,
- .SubClass = CDC_CSCP_ACMSubclass,
- .Protocol = CDC_CSCP_VendorSpecificProtocol,
-
- .InterfaceStrIndex = NO_DESCRIPTOR
- },
-
- .CDC_Functional_Header =
- {
- .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
- .Subtype = CDC_DSUBTYPE_CSInterface_Header,
-
- .CDCSpecification = VERSION_BCD(1,1,0),
- },
-
- .CDC_Functional_ACM =
- {
- .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
- .Subtype = CDC_DSUBTYPE_CSInterface_ACM,
-
- .Capabilities = 0x00,
- },
-
- .CDC_Functional_Union =
- {
- .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
- .Subtype = CDC_DSUBTYPE_CSInterface_Union,
-
- .MasterInterfaceNumber = INTERFACE_ID_CDC_CCI,
- .SlaveInterfaceNumber = INTERFACE_ID_CDC_DCI,
- },
-
- .CDC_NotificationEndpoint =
- {
- .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
- .EndpointAddress = CDC_NOTIFICATION_EPADDR,
- .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
- .EndpointSize = CDC_NOTIFICATION_EPSIZE,
- .PollingIntervalMS = 0xFF
- },
-
- .CDC_DCI_Interface =
- {
- .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
-
- .InterfaceNumber = INTERFACE_ID_CDC_DCI,
- .AlternateSetting = 0,
-
- .TotalEndpoints = 2,
-
- .Class = CDC_CSCP_CDCDataClass,
- .SubClass = CDC_CSCP_NoDataSubclass,
- .Protocol = CDC_CSCP_NoDataProtocol,
-
- .InterfaceStrIndex = NO_DESCRIPTOR
- },
-
- .RNDIS_DataOutEndpoint =
- {
- .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
- .EndpointAddress = CDC_RX_EPADDR,
- .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
- .EndpointSize = CDC_TXRX_EPSIZE,
- .PollingIntervalMS = 0x05
- },
-
- .RNDIS_DataInEndpoint =
- {
- .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
- .EndpointAddress = CDC_TX_EPADDR,
- .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
- .EndpointSize = CDC_TXRX_EPSIZE,
- .PollingIntervalMS = 0x05
- },
-
- .MS_Interface =
- {
- .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
-
- .InterfaceNumber = INTERFACE_ID_MassStorage,
- .AlternateSetting = 0,
-
- .TotalEndpoints = 2,
-
- .Class = MS_CSCP_MassStorageClass,
- .SubClass = MS_CSCP_SCSITransparentSubclass,
- .Protocol = MS_CSCP_BulkOnlyTransportProtocol,
-
- .InterfaceStrIndex = NO_DESCRIPTOR
- },
-
- .MS_DataInEndpoint =
- {
- .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
- .EndpointAddress = MASS_STORAGE_IN_EPADDR,
- .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
- .EndpointSize = MASS_STORAGE_IO_EPSIZE,
- .PollingIntervalMS = 0x05
- },
-
- .MS_DataOutEndpoint =
- {
- .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
- .EndpointAddress = MASS_STORAGE_OUT_EPADDR,
- .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
- .EndpointSize = MASS_STORAGE_IO_EPSIZE,
- .PollingIntervalMS = 0x05
- }
-};
-
-/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
- * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
- * via the language ID table available at USB.org what languages the device supports for its string descriptors.
- */
-const USB_Descriptor_String_t PROGMEM LanguageString = USB_STRING_DESCRIPTOR_ARRAY(LANGUAGE_ID_ENG);
-
-/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
- * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
- * Descriptor.
- */
-const USB_Descriptor_String_t PROGMEM ManufacturerString = USB_STRING_DESCRIPTOR(L"Dean Camera");
-
-/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
- * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
- * Descriptor.
- */
-const USB_Descriptor_String_t PROGMEM ProductString = USB_STRING_DESCRIPTOR(L"LUFA Webserver");
-
-/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
- * documentation) by the application code so that the address and size of a requested descriptor can be given
- * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
- * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
- * USB host.
- */
-uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
- const uint16_t wIndex,
- const void** const DescriptorAddress)
-{
- const uint8_t DescriptorType = (wValue >> 8);
- const uint8_t DescriptorNumber = (wValue & 0xFF);
-
- const void* Address = NULL;
- uint16_t Size = NO_DESCRIPTOR;
-
- switch (DescriptorType)
- {
- case DTYPE_Device:
- Address = &DeviceDescriptor;
- Size = sizeof(USB_Descriptor_Device_t);
- break;
- case DTYPE_Configuration:
- Address = &ConfigurationDescriptor;
- Size = sizeof(USB_Descriptor_Configuration_t);
- break;
- case DTYPE_String:
- switch (DescriptorNumber)
- {
- case STRING_ID_Language:
- Address = &LanguageString;
- Size = pgm_read_byte(&LanguageString.Header.Size);
- break;
- case STRING_ID_Manufacturer:
- Address = &ManufacturerString;
- Size = pgm_read_byte(&ManufacturerString.Header.Size);
- break;
- case STRING_ID_Product:
- Address = &ProductString;
- Size = pgm_read_byte(&ProductString.Header.Size);
- break;
- }
-
- break;
- }
-
- *DescriptorAddress = Address;
- return Size;
-}
-
diff --git a/lib/lufa/Projects/Webserver/Descriptors.h b/lib/lufa/Projects/Webserver/Descriptors.h
deleted file mode 100644
index 66da1b654..000000000
--- a/lib/lufa/Projects/Webserver/Descriptors.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Header file for Descriptors.c.
- */
-
-#ifndef _DESCRIPTORS_H_
-#define _DESCRIPTORS_H_
-
- /* Includes: */
- #include <avr/pgmspace.h>
-
- #include <LUFA/Drivers/USB/USB.h>
-
- #include "Config/AppConfig.h"
-
- /* Macros: */
- /** Endpoint address of the Mass Storage device-to-host data IN endpoint. */
- #define MASS_STORAGE_IN_EPADDR (ENDPOINT_DIR_IN | 3)
-
- /** Endpoint address of the Mass Storage host-to-device data OUT endpoint. */
- #define MASS_STORAGE_OUT_EPADDR (ENDPOINT_DIR_OUT | 4)
-
- /** Size in bytes of the Mass Storage data endpoints. */
- #define MASS_STORAGE_IO_EPSIZE 64
-
- /** Endpoint address of the CDC device-to-host notification IN endpoint. */
- #define CDC_NOTIFICATION_EPADDR (ENDPOINT_DIR_IN | 5)
-
- /** Endpoint address of the CDC device-to-host data IN endpoint. */
- #define CDC_TX_EPADDR (ENDPOINT_DIR_IN | 1)
-
- /** Endpoint address of the CDC host-to-device data OUT endpoint. */
- #define CDC_RX_EPADDR (ENDPOINT_DIR_OUT | 2)
-
- /** Size in bytes of the CDC device-to-host notification IN endpoint. */
- #define CDC_NOTIFICATION_EPSIZE 8
-
- /** Size in bytes of the CDC data IN and OUT endpoints. */
- #define CDC_TXRX_EPSIZE 64
-
- /* Type Defines: */
- /** Type define for the device configuration descriptor structure. This must be defined in the
- * application code, as the configuration descriptor contains several sub-descriptors which
- * vary between devices, and which describe the device's usage to the host.
- */
- typedef struct
- {
- USB_Descriptor_Configuration_Header_t Config;
-
- // RNDIS CDC Command Interface
- USB_Descriptor_Interface_Association_t CDC_IAD;
- USB_Descriptor_Interface_t CDC_CCI_Interface;
- USB_CDC_Descriptor_FunctionalHeader_t CDC_Functional_Header;
- USB_CDC_Descriptor_FunctionalACM_t CDC_Functional_ACM;
- USB_CDC_Descriptor_FunctionalUnion_t CDC_Functional_Union;
- USB_Descriptor_Endpoint_t CDC_NotificationEndpoint;
-
- // RNDIS CDC Data Interface
- USB_Descriptor_Interface_t CDC_DCI_Interface;
- USB_Descriptor_Endpoint_t RNDIS_DataOutEndpoint;
- USB_Descriptor_Endpoint_t RNDIS_DataInEndpoint;
-
- // Mass Storage Interface
- USB_Descriptor_Interface_t MS_Interface;
- USB_Descriptor_Endpoint_t MS_DataInEndpoint;
- USB_Descriptor_Endpoint_t MS_DataOutEndpoint;
- } USB_Descriptor_Configuration_t;
-
- /** Enum for the device interface descriptor IDs within the device. Each interface descriptor
- * should have a unique ID index associated with it, which can be used to refer to the
- * interface from other descriptors.
- */
- enum InterfaceDescriptors_t
- {
- INTERFACE_ID_CDC_CCI = 0, /**< CDC CCI interface descriptor ID */
- INTERFACE_ID_CDC_DCI = 1, /**< CDC DCI interface descriptor ID */
- INTERFACE_ID_MassStorage = 2, /**< Mass storage interface descriptor ID */
- };
-
- /** Enum for the device string descriptor IDs within the device. Each string descriptor should
- * have a unique ID index associated with it, which can be used to refer to the string from
- * other descriptors.
- */
- enum StringDescriptors_t
- {
- STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */
- STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */
- STRING_ID_Product = 2, /**< Product string ID */
- };
-
- /* Function Prototypes: */
- uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
- const uint16_t wIndex,
- const void** const DescriptorAddress)
- ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
-
-#endif
-
diff --git a/lib/lufa/Projects/Webserver/LUFA Webserver RNDIS.inf b/lib/lufa/Projects/Webserver/LUFA Webserver RNDIS.inf
deleted file mode 100644
index c77de8f6b..000000000
--- a/lib/lufa/Projects/Webserver/LUFA Webserver RNDIS.inf
+++ /dev/null
@@ -1,59 +0,0 @@
-; Windows LUFA RNDIS Setup File
-; Copyright (c) 2000 Microsoft Corporation
-
-[DefaultInstall]
-CopyINF="LUFA Webserver RNDIS.inf"
-
-[Version]
-Signature="$Windows NT$"
-Class=Net
-ClassGuid={4d36e972-e325-11ce-bfc1-08002be10318}
-Provider=%MFGNAME%
-DriverVer=7/1/2012,10.0.0.0
-
-[Manufacturer]
-%MFGNAME%=DeviceList, NTx86, NTamd64, NTia64
-
-[ControlFlags]
-ExcludeFromSelect=*
-
-[DriverInstall]
-Characteristics=0x84 ; NCF_PHYSICAL + NCF_HAS_UI
-BusType=15
-include=netrndis.inf
-needs=Usb_Rndis.ndi
-AddReg=Rndis_AddReg_Vista
-
-[DriverInstall.Services]
-include=netrndis.inf
-needs=Usb_Rndis.ndi.Services
-
-;------------------------------------------------------------------------------
-; Vendor and Product ID Definitions
-;------------------------------------------------------------------------------
-; When developing your USB device, the VID and PID used in the PC side
-; application program and the firmware on the microcontroller must match.
-; Modify the below line to use your VID and PID. Use the format as shown below.
-; Note: One INF file can be used for multiple devices with different VID and PIDs.
-; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line.
-;------------------------------------------------------------------------------
-[DeviceList]
-%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_2069
-
-[DeviceList.NTx86]
-%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_2069
-
-[DeviceList.NTamd64]
-%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_2069
-
-[DeviceList.NTia64]
-%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_2069
-
-;------------------------------------------------------------------------------
-; String Definitions
-;------------------------------------------------------------------------------
-;Modify these strings to customize your device
-;------------------------------------------------------------------------------
-[Strings]
-MFGNAME="http://www.lufa-lib.org"
-DESCRIPTION="LUFA USB RNDIS Demo"
diff --git a/lib/lufa/Projects/Webserver/Lib/DHCPClientApp.c b/lib/lufa/Projects/Webserver/Lib/DHCPClientApp.c
deleted file mode 100644
index 760718127..000000000
--- a/lib/lufa/Projects/Webserver/Lib/DHCPClientApp.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * DHCP Client Application. When connected to the uIP stack, this will retrieve IP configuration settings from the
- * DHCP server on the network.
- */
-
-#define INCLUDE_FROM_DHCPCLIENTAPP_C
-#include "DHCPClientApp.h"
-
-#if defined(ENABLE_DHCP_CLIENT) || defined(__DOXYGEN__)
-
-/** Initialization function for the DHCP client. */
-void DHCPClientApp_Init(void)
-{
- /* Create a new UDP connection to the DHCP server port for the DHCP solicitation */
- struct uip_udp_conn* Connection = uip_udp_new(&uip_broadcast_addr, HTONS(DHCP_SERVER_PORT));
-
- /* If the connection was successfully created, bind it to the local DHCP client port */
- if (Connection != NULL)
- {
- uip_udp_appstate_t* const AppState = &Connection->appstate;
- uip_udp_bind(Connection, HTONS(DHCP_CLIENT_PORT));
-
- /* Set the initial client state */
- AppState->DHCPClient.CurrentState = DHCP_STATE_SendDiscover;
-
- /* Set timeout period to half a second for a DHCP server to respond */
- timer_set(&AppState->DHCPClient.Timeout, CLOCK_SECOND / 2);
- }
-}
-
-/** uIP stack application callback for the DHCP client. This function must be called each time the TCP/IP stack
- * needs a UDP packet to be processed.
- */
-void DHCPClientApp_Callback(void)
-{
- uip_udp_appstate_t* const AppState = &uip_udp_conn->appstate;
- DHCP_Header_t* const AppData = (DHCP_Header_t*)uip_appdata;
- uint16_t AppDataSize = 0;
-
- switch (AppState->DHCPClient.CurrentState)
- {
- case DHCP_STATE_SendDiscover:
- /* Clear all DHCP settings, reset client IP address */
- memset(&AppState->DHCPClient.DHCPOffer_Data, 0x00, sizeof(AppState->DHCPClient.DHCPOffer_Data));
- uip_sethostaddr((uip_ipaddr_t*)&AppState->DHCPClient.DHCPOffer_Data.AllocatedIP);
-
- /* Fill out the DHCP response header */
- AppDataSize += DHCPClientApp_FillDHCPHeader(AppData, DHCP_DISCOVER, AppState);
-
- /* Add the required DHCP options list to the packet */
- uint8_t RequiredOptionList[] = {DHCP_OPTION_SUBNET_MASK, DHCP_OPTION_ROUTER, DHCP_OPTION_DNS_SERVER};
- AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_REQ_LIST, sizeof(RequiredOptionList),
- RequiredOptionList);
-
- /* Send the DHCP DISCOVER packet */
- uip_udp_send(AppDataSize);
-
- /* Reset the timeout timer, progress to next state */
- timer_reset(&AppState->DHCPClient.Timeout);
- AppState->DHCPClient.CurrentState = DHCP_STATE_WaitForOffer;
-
- break;
- case DHCP_STATE_WaitForOffer:
- if (!(uip_newdata()))
- {
- /* Check if the DHCP timeout period has expired while waiting for a response */
- if (timer_expired(&AppState->DHCPClient.Timeout))
- AppState->DHCPClient.CurrentState = DHCP_STATE_SendDiscover;
-
- break;
- }
-
- uint8_t OfferResponse_MessageType;
- if ((AppData->TransactionID == DHCP_TRANSACTION_ID) &&
- DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &OfferResponse_MessageType) &&
- (OfferResponse_MessageType == DHCP_OFFER))
- {
- /* Received a DHCP offer for an IP address, copy over values for later request */
- memcpy(&AppState->DHCPClient.DHCPOffer_Data.AllocatedIP, &AppData->YourIP, sizeof(uip_ipaddr_t));
- DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_SUBNET_MASK, &AppState->DHCPClient.DHCPOffer_Data.Netmask);
- DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_ROUTER, &AppState->DHCPClient.DHCPOffer_Data.GatewayIP);
- DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_SERVER_ID, &AppState->DHCPClient.DHCPOffer_Data.ServerIP);
-
- timer_reset(&AppState->DHCPClient.Timeout);
- AppState->DHCPClient.CurrentState = DHCP_STATE_SendRequest;
- }
-
- break;
- case DHCP_STATE_SendRequest:
- /* Fill out the DHCP response header */
- AppDataSize += DHCPClientApp_FillDHCPHeader(AppData, DHCP_REQUEST, AppState);
-
- /* Add the DHCP REQUESTED IP ADDRESS option to the packet */
- AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_REQ_IPADDR, sizeof(uip_ipaddr_t),
- &AppState->DHCPClient.DHCPOffer_Data.AllocatedIP);
-
- /* Add the DHCP SERVER IP ADDRESS option to the packet */
- AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_SERVER_ID, sizeof(uip_ipaddr_t),
- &AppState->DHCPClient.DHCPOffer_Data.ServerIP);
-
- /* Send the DHCP REQUEST packet */
- uip_udp_send(AppDataSize);
-
- /* Reset the timeout timer, progress to next state */
- timer_reset(&AppState->DHCPClient.Timeout);
- AppState->DHCPClient.CurrentState = DHCP_STATE_WaitForACK;
-
- break;
- case DHCP_STATE_WaitForACK:
- if (!(uip_newdata()))
- {
- /* Check if the DHCP timeout period has expired while waiting for a response */
- if (timer_expired(&AppState->DHCPClient.Timeout))
- AppState->DHCPClient.CurrentState = DHCP_STATE_SendDiscover;
-
- break;
- }
-
- uint8_t RequestResponse_MessageType;
- if ((AppData->TransactionID == DHCP_TRANSACTION_ID) &&
- DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &RequestResponse_MessageType) &&
- (RequestResponse_MessageType == DHCP_ACK))
- {
- /* Set the new network parameters from the DHCP server */
- uip_sethostaddr((uip_ipaddr_t*)&AppState->DHCPClient.DHCPOffer_Data.AllocatedIP);
- uip_setnetmask((uip_ipaddr_t*)&AppState->DHCPClient.DHCPOffer_Data.Netmask);
- uip_setdraddr((uip_ipaddr_t*)&AppState->DHCPClient.DHCPOffer_Data.GatewayIP);
-
- AppState->DHCPClient.CurrentState = DHCP_STATE_AddressLeased;
- }
-
- break;
- }
-}
-
-/** Fills the DHCP packet response with the appropriate BOOTP header for DHCP. This fills out all the required
- * fields, leaving only the additional DHCP options to be added to the packet before it is sent to the DHCP server.
- *
- * \param[out] DHCPHeader Location in the packet buffer where the BOOTP header should be written to
- * \param[in] DHCPMessageType DHCP Message type, such as DHCP_DISCOVER
- * \param[in] AppState Application state of the current UDP connection
- *
- * \return Size in bytes of the created DHCP packet
- */
-static uint16_t DHCPClientApp_FillDHCPHeader(DHCP_Header_t* const DHCPHeader,
- const uint8_t DHCPMessageType,
- uip_udp_appstate_t* const AppState)
-{
- /* Erase existing packet data so that we start will all 0x00 DHCP header data */
- memset(DHCPHeader, 0, sizeof(DHCP_Header_t));
-
- /* Fill out the DHCP packet header */
- DHCPHeader->Operation = DHCP_OP_BOOTREQUEST;
- DHCPHeader->HardwareType = DHCP_HTYPE_ETHERNET;
- DHCPHeader->HardwareAddressLength = sizeof(MACAddress);
- DHCPHeader->Hops = 0;
- DHCPHeader->TransactionID = DHCP_TRANSACTION_ID;
- DHCPHeader->ElapsedSeconds = 0;
- DHCPHeader->Flags = HTONS(BOOTP_BROADCAST);
- memcpy(&DHCPHeader->ClientIP, &uip_hostaddr, sizeof(uip_ipaddr_t));
- memcpy(&DHCPHeader->YourIP, &AppState->DHCPClient.DHCPOffer_Data.AllocatedIP, sizeof(uip_ipaddr_t));
- memcpy(&DHCPHeader->NextServerIP, &AppState->DHCPClient.DHCPOffer_Data.ServerIP, sizeof(uip_ipaddr_t));
- memcpy(&DHCPHeader->ClientHardwareAddress, &MACAddress, sizeof(struct uip_eth_addr));
- DHCPHeader->Cookie = DHCP_MAGIC_COOKIE;
-
- /* Add a DHCP message type and terminator options to the start of the DHCP options field */
- DHCPHeader->Options[0] = DHCP_OPTION_MSG_TYPE;
- DHCPHeader->Options[1] = 1;
- DHCPHeader->Options[2] = DHCPMessageType;
- DHCPHeader->Options[3] = DHCP_OPTION_END;
-
- /* Calculate the total number of bytes added to the outgoing packet */
- return (sizeof(DHCP_Header_t) + 4);
-}
-
-#endif
-
diff --git a/lib/lufa/Projects/Webserver/Lib/DHCPClientApp.h b/lib/lufa/Projects/Webserver/Lib/DHCPClientApp.h
deleted file mode 100644
index 0aec00331..000000000
--- a/lib/lufa/Projects/Webserver/Lib/DHCPClientApp.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Header file for DHCPClientApp.c.
- */
-
-#ifndef _DHCPCLIENT_APP_H_
-#define _DHCPCLIENT_APP_H_
-
- /* Includes: */
- #include <stdio.h>
-
- #include <uip.h>
-
- #include "Config/AppConfig.h"
- #include "../Webserver.h"
- #include "DHCPCommon.h"
-
- /* Enums: */
- /** States for each DHCP connection to a DHCP client. */
- enum DHCP_Client_States_t
- {
- DHCP_STATE_SendDiscover, /**< Send DISCOVER packet to retrieve DHCP lease offers */
- DHCP_STATE_WaitForOffer, /**< Waiting for OFFER packet giving available DHCP leases */
- DHCP_STATE_SendRequest, /**< Send REQUEST packet to request a DHCP lease */
- DHCP_STATE_WaitForACK, /**< Wait for ACK packet to complete the DHCP lease */
- DHCP_STATE_AddressLeased, /**< DHCP address has been leased from a DHCP server */
- };
-
- /* Function Prototypes: */
- void DHCPClientApp_Init(void);
- void DHCPClientApp_Callback(void);
-
- #if defined(INCLUDE_FROM_DHCPCLIENTAPP_C)
- static uint16_t DHCPClientApp_FillDHCPHeader(DHCP_Header_t* const DHCPHeader,
- const uint8_t DHCPMessageType,
- uip_udp_appstate_t* const AppState);
- #endif
-#endif
-
diff --git a/lib/lufa/Projects/Webserver/Lib/DHCPCommon.c b/lib/lufa/Projects/Webserver/Lib/DHCPCommon.c
deleted file mode 100644
index 6d80f65ca..000000000
--- a/lib/lufa/Projects/Webserver/Lib/DHCPCommon.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Common DHCP routines to manage DHCP packet data.
- */
-
-#include "DHCPCommon.h"
-
-#if defined(ENABLE_DHCP_CLIENT) || defined(ENABLE_DHCP_SERVER) || defined(__DOXYGEN__)
-
-/** Sets the given DHCP option in the DHCP packet's option list. This automatically moves the
- * end of options terminator past the new option in the options list.
- *
- * \param[in,out] DHCPOptionList Pointer to the start of the DHCP packet's options list
- * \param[in] Option DHCP option to add to the list
- * \param[in] DataLen Size in bytes of the option data to add
- * \param[in] OptionData Buffer where the option's data is to be sourced from
- *
- * \return Number of bytes added to the DHCP packet
- */
-uint8_t DHCPCommon_SetOption(uint8_t* DHCPOptionList,
- const uint8_t Option,
- const uint8_t DataLen,
- void* const OptionData)
-{
- /* Skip through the DHCP options list until the terminator option is found */
- while (*DHCPOptionList != DHCP_OPTION_END)
- DHCPOptionList += (DHCPOptionList[1] + 2);
-
- /* Overwrite the existing terminator with the new option, add a new terminator at the end of the list */
- DHCPOptionList[0] = Option;
- DHCPOptionList[1] = DataLen;
- memcpy(&DHCPOptionList[2], OptionData, DataLen);
- DHCPOptionList[2 + DataLen] = DHCP_OPTION_END;
-
- /* Calculate the total number of bytes added to the outgoing packet */
- return (2 + DataLen);
-}
-
-/** Retrieves the given option's data (if present) from the DHCP packet's options list.
- *
- * \param[in,out] DHCPOptionList Pointer to the start of the DHCP packet's options list
- * \param[in] Option DHCP option to retrieve to the list
- * \param[out] Destination Buffer where the option's data is to be written to if found
- *
- * \return Boolean \c true if the option was found in the DHCP packet's options list, \c false otherwise
- */
-bool DHCPCommon_GetOption(const uint8_t* DHCPOptionList,
- const uint8_t Option,
- void* const Destination)
-{
- /* Look through the incoming DHCP packet's options list for the requested option */
- while (*DHCPOptionList != DHCP_OPTION_END)
- {
- /* Check if the current DHCP option in the packet is the one requested */
- if (DHCPOptionList[0] == Option)
- {
- /* Copy request option's data to the destination buffer */
- memcpy(Destination, &DHCPOptionList[2], DHCPOptionList[1]);
-
- /* Indicate that the requested option data was successfully retrieved */
- return true;
- }
-
- /* Skip to next DHCP option in the options list */
- DHCPOptionList += (DHCPOptionList[1] + 2);
- }
-
- /* Requested option not found in the incoming packet's DHCP options list */
- return false;
-}
-
-#endif
-
diff --git a/lib/lufa/Projects/Webserver/Lib/DHCPCommon.h b/lib/lufa/Projects/Webserver/Lib/DHCPCommon.h
deleted file mode 100644
index 8f54c1671..000000000
--- a/lib/lufa/Projects/Webserver/Lib/DHCPCommon.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Header file for common DHCP defines.
- */
-
-#ifndef _DHCP_COMMON_H_
-#define _DHCP_COMMON_H_
-
- /* Includes: */
- #include <stdint.h>
- #include <stdbool.h>
- #include <string.h>
-
- #include "Config/AppConfig.h"
-
- #include <uip.h>
-
- /* Macros: */
- /** UDP listen port for a BOOTP server. */
- #define DHCP_SERVER_PORT 67
-
- /** UDP listen port for a BOOTP client. */
- #define DHCP_CLIENT_PORT 68
-
- /** BOOTP message type for a BOOTP REQUEST message. */
- #define DHCP_OP_BOOTREQUEST 0x01
-
- /** BOOTP message type for a BOOTP REPLY message. */
- #define DHCP_OP_BOOTREPLY 0x02
-
- /** BOOTP flag for a BOOTP broadcast message. */
- #define BOOTP_BROADCAST 0x8000
-
- /** Magic DHCP cookie for a BOOTP message to identify it as a DHCP message. */
- #define DHCP_MAGIC_COOKIE 0x63538263
-
- /** Unique transaction ID used to identify DHCP responses to the client. */
- #define DHCP_TRANSACTION_ID 0x13245466
-
- /** DHCP message type for a DISCOVER message. */
- #define DHCP_DISCOVER 1
-
- /** DHCP message type for an OFFER message. */
- #define DHCP_OFFER 2
-
- /** DHCP message type for a REQUEST message. */
- #define DHCP_REQUEST 3
-
- /** DHCP message type for a DECLINE message. */
- #define DHCP_DECLINE 4
-
- /** DHCP message type for an ACK message. */
- #define DHCP_ACK 5
-
- /** DHCP message type for a NAK message. */
- #define DHCP_NAK 6
-
- /** DHCP message type for a RELEASE message. */
- #define DHCP_RELEASE 7
-
- /** DHCP medium type for standard Ethernet. */
- #define DHCP_HTYPE_ETHERNET 1
-
- /** DHCP message option for the network subnet mask. */
- #define DHCP_OPTION_SUBNET_MASK 1
-
- /** DHCP message option for the network gateway IP. */
- #define DHCP_OPTION_ROUTER 3
-
- /** DHCP message option for the network DNS server. */
- #define DHCP_OPTION_DNS_SERVER 6
-
- /** DHCP message option for the requested client IP address. */
- #define DHCP_OPTION_REQ_IPADDR 50
-
- /** DHCP message option for the IP address lease time. */
- #define DHCP_OPTION_LEASE_TIME 51
-
- /** DHCP message option for the DHCP message type. */
- #define DHCP_OPTION_MSG_TYPE 53
-
- /** DHCP message option for the DHCP server IP. */
- #define DHCP_OPTION_SERVER_ID 54
-
- /** DHCP message option for the list of required options from the server. */
- #define DHCP_OPTION_REQ_LIST 55
-
- /** DHCP message option for the options list terminator. */
- #define DHCP_OPTION_END 255
-
- /* Type Defines: */
- /** Type define for a DHCP packet inside an Ethernet frame. */
- typedef struct
- {
- uint8_t Operation; /**< DHCP operation, either DHCP_OP_BOOTREQUEST or DHCP_OP_BOOTREPLY */
- uint8_t HardwareType; /**< Hardware carrier type constant */
- uint8_t HardwareAddressLength; /**< Length in bytes of a hardware (MAC) address on the network */
- uint8_t Hops; /**< Number of hops required to reach the server, unused */
-
- uint32_t TransactionID; /**< Unique ID of the DHCP packet, for positive matching between sent and received packets */
-
- uint16_t ElapsedSeconds; /**< Elapsed seconds since the request was made */
- uint16_t Flags; /**< BOOTP packet flags */
-
- uip_ipaddr_t ClientIP; /**< Client IP address, if already leased an IP */
- uip_ipaddr_t YourIP; /**< Client IP address */
- uip_ipaddr_t NextServerIP; /**< Legacy BOOTP protocol field, unused for DHCP */
- uip_ipaddr_t RelayAgentIP; /**< Legacy BOOTP protocol field, unused for DHCP */
-
- uint8_t ClientHardwareAddress[16]; /**< Hardware (MAC) address of the client making a request to the DHCP server */
- uint8_t ServerHostnameString[64]; /**< Legacy BOOTP protocol field, unused for DHCP */
- uint8_t BootFileName[128]; /**< Legacy BOOTP protocol field, unused for DHCP */
-
- uint32_t Cookie; /**< Magic BOOTP protocol cookie to indicate a valid packet */
-
- uint8_t Options[]; /**< DHCP message options */
- } DHCP_Header_t;
-
- /* Function Prototypes: */
- uint8_t DHCPCommon_SetOption(uint8_t* DHCPOptionList,
- const uint8_t Option,
- const uint8_t DataLen,
- void* const OptionData);
- bool DHCPCommon_GetOption(const uint8_t* DHCPOptionList,
- const uint8_t Option,
- void* const Destination);
-
-#endif
-
diff --git a/lib/lufa/Projects/Webserver/Lib/DHCPServerApp.c b/lib/lufa/Projects/Webserver/Lib/DHCPServerApp.c
deleted file mode 100644
index fea54ddb0..000000000
--- a/lib/lufa/Projects/Webserver/Lib/DHCPServerApp.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * DHCP Server Application. When connected to the uIP stack, this will send IP configuration settings to a
- * DHCP client on the network.
- */
-
-#define INCLUDE_FROM_DHCPSERVERAPP_C
-#include "DHCPServerApp.h"
-
-#if defined(ENABLE_DHCP_SERVER) || defined(__DOXYGEN__)
-
-struct uip_conn* BroadcastConnection;
-
-uint8_t LeasedIPs[255 / 8];
-
-/** Initialization function for the DHCP server. */
-void DHCPServerApp_Init(void)
-{
- /* Listen on port 67 for DHCP server connections from hosts */
- uip_listen(HTONS(DHCP_SERVER_PORT));
-
- /* Create a new UDP connection to the DHCP server port for the DHCP solicitation */
- struct uip_udp_conn* BroadcastConnection = uip_udp_new(&uip_broadcast_addr, HTONS(DHCP_CLIENT_PORT));
-
- /* If the connection was successfully created, bind it to the local DHCP client port */
- if (BroadcastConnection != NULL)
- uip_udp_bind(BroadcastConnection, HTONS(DHCP_SERVER_PORT));
-
- /* Set all IP addresses as unleased */
- memset(LeasedIPs, 0x00, sizeof(LeasedIPs));
-}
-
-/** uIP stack application callback for the DHCP server. This function must be called each time the TCP/IP stack
- * needs a UDP packet to be processed.
- */
-void DHCPServerApp_Callback(void)
-{
- DHCP_Header_t* const AppData = (DHCP_Header_t*)uip_appdata;
- uint16_t AppDataSize = 0;
-
- /* Only process when new data arrives - don't retransmit lost packets */
- if (uip_newdata())
- {
- /* Get the DHCP message type (if present), otherwise early-abort */
- uint8_t DHCPMessageType;
- if (!(DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &DHCPMessageType)))
- return;
-
- uip_ipaddr_t Netmask, GatewayIPAddress, PreferredClientIP;
- struct uip_eth_addr RemoteMACAddress;
- uint32_t TransactionID;
-
- /* Get configured network mask, gateway IP and extract out DHCP transaction ID and remote IP */
- uip_getnetmask(&Netmask);
- uip_getdraddr(&GatewayIPAddress);
- memcpy(&RemoteMACAddress, &AppData->ClientHardwareAddress, sizeof(struct uip_eth_addr));
- TransactionID = AppData->TransactionID;
-
- /* Try to extract out the client's preferred IP address if it is indicated in the packet */
- if (!(DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_REQ_IPADDR, &PreferredClientIP)))
- memcpy(&PreferredClientIP, &uip_all_zeroes_addr, sizeof(uip_ipaddr_t));
-
- switch (DHCPMessageType)
- {
- case DHCP_DISCOVER:
- /* If no preference was made or the preferred IP is already taken, find a new address */
- if (DHCPServerApp_CheckIfIPLeased(&PreferredClientIP))
- DHCPServerApp_GetUnleasedIP(&PreferredClientIP);
-
- /* Create a new DHCP OFFER packet with the offered IP address */
- AppDataSize += DHCPServerApp_FillDHCPHeader(AppData, DHCP_OFFER, &RemoteMACAddress, &PreferredClientIP, TransactionID);
-
- /* Add network mask and router information to the list of DHCP OFFER packet options */
- AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_SUBNET_MASK,
- sizeof(uip_ipaddr_t), &Netmask);
- AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_ROUTER,
- sizeof(uip_ipaddr_t), &GatewayIPAddress);
-
- /* Send the DHCP OFFER packet */
- uip_poll_conn(BroadcastConnection);
- memcpy(&uip_udp_conn->ripaddr, &uip_broadcast_addr, sizeof(uip_ipaddr_t));
- uip_udp_send(AppDataSize);
-
- break;
- case DHCP_REQUEST:
- /* Check to see if the requested IP address has already been leased to a client */
- if (!(DHCPServerApp_CheckIfIPLeased(&PreferredClientIP)))
- {
- /* Create a new DHCP ACK packet to accept the IP address lease */
- AppDataSize += DHCPServerApp_FillDHCPHeader(AppData, DHCP_ACK, &RemoteMACAddress, &PreferredClientIP, TransactionID);
-
- /* Add network mask and router information to the list of DHCP ACK packet options */
- AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_SUBNET_MASK,
- sizeof(uip_ipaddr_t), &Netmask);
- AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_ROUTER,
- sizeof(uip_ipaddr_t), &GatewayIPAddress);
-
- /* Mark the requested IP as leased to a client */
- DHCPServerApp_LeaseIP(&PreferredClientIP);
- }
- else
- {
- /* Create a new DHCP NAK packet to reject the requested allocation */
- AppDataSize += DHCPServerApp_FillDHCPHeader(AppData, DHCP_NAK, &RemoteMACAddress, &uip_all_zeroes_addr, TransactionID);
- }
-
- /* Send the DHCP ACK or NAK packet */
- uip_poll_conn(BroadcastConnection);
- memcpy(&uip_udp_conn->ripaddr, &uip_broadcast_addr, sizeof(uip_ipaddr_t));
- uip_udp_send(AppDataSize);
-
- break;
- case DHCP_RELEASE:
- /* Mark the IP address as released in the allocation table */
- DHCPServerApp_UnleaseIP(&uip_udp_conn->ripaddr);
- break;
- }
- }
-}
-
-/** Fills the DHCP packet response with the appropriate BOOTP header for DHCP. This fills out all the required
- * fields, leaving only the additional DHCP options to be added to the packet before it is sent to the DHCP client.
- *
- * \param[out] DHCPHeader Location in the packet buffer where the BOOTP header should be written to
- * \param[in] DHCPMessageType DHCP Message type, such as DHCP_DISCOVER
- * \param[in] ClientHardwareAddress Client MAC address the created transaction should be directed to
- * \param[in] PreferredClientIP Preferred IP that should be given to the client if it is unallocated
- * \param[in] TransactionID Transaction ID the created transaction should be associated with
- *
- * \return Size in bytes of the created DHCP packet
- */
-static uint16_t DHCPServerApp_FillDHCPHeader(DHCP_Header_t* const DHCPHeader,
- const uint8_t DHCPMessageType,
- const struct uip_eth_addr* const ClientHardwareAddress,
- const uip_ipaddr_t* const PreferredClientIP,
- const uint32_t TransactionID)
-{
- /* Erase existing packet data so that we start will all 0x00 DHCP header data */
- memset(DHCPHeader, 0, sizeof(DHCP_Header_t));
-
- DHCPHeader->Operation = DHCPMessageType;
- DHCPHeader->HardwareType = DHCP_HTYPE_ETHERNET;
- DHCPHeader->HardwareAddressLength = sizeof(MACAddress);
- DHCPHeader->Hops = 0;
- DHCPHeader->TransactionID = TransactionID;
- DHCPHeader->ElapsedSeconds = 0;
- DHCPHeader->Flags = 0;
- memcpy(&DHCPHeader->NextServerIP, &uip_hostaddr, sizeof(uip_ipaddr_t));
- memcpy(&DHCPHeader->YourIP, PreferredClientIP, sizeof(uip_ipaddr_t));
- memcpy(&DHCPHeader->ClientHardwareAddress, ClientHardwareAddress, sizeof(struct uip_eth_addr));
- DHCPHeader->Cookie = DHCP_MAGIC_COOKIE;
-
- /* Add a DHCP message type and terminator options to the start of the DHCP options field */
- DHCPHeader->Options[0] = DHCP_OPTION_MSG_TYPE;
- DHCPHeader->Options[1] = 1;
- DHCPHeader->Options[2] = DHCPMessageType;
- DHCPHeader->Options[3] = DHCP_OPTION_END;
-
- /* Calculate the total number of bytes added to the outgoing packet */
- return (sizeof(DHCP_Header_t) + 4);
-}
-
-/** Checks to see if the nominated IP address has already been allocated to a client.
- *
- * \param[in] IPAddress IP Address whose lease status should be checked
- *
- * \pre The IP address must be within the same /24 subnet as the virtual webserver.
- *
- * \return Boolean \c true if the IP has already been leased to a client, \c false otherwise.
- */
-static bool DHCPServerApp_CheckIfIPLeased(const uip_ipaddr_t* const IPAddress)
-{
- uint8_t Byte = (IPAddress->u8[3] / 8);
- uint8_t Mask = (1 << (IPAddress->u8[3] % 8));
-
- /* Make sure that the requested IP address isn't already leased to the virtual server or another client */
- if (IPAddress->u8[3] && !(IPAddress->u8[3] == uip_hostaddr.u8[3]) && !(LeasedIPs[Byte] & Mask))
- return false;
- else
- return true;
-}
-
-/** Retrieves the next unleased IP in the IP address pool.
- *
- * \param[out] NewIPAddress Location where the generated IP Address should be stored
- */
-static void DHCPServerApp_GetUnleasedIP(uip_ipaddr_t* const NewIPAddress)
-{
- uip_ipaddr_copy(NewIPAddress, &uip_hostaddr);
-
- /** Look through the current subnet, skipping the broadcast and zero IP addresses */
- for (uint8_t IP = 1; IP < 254; IP++)
- {
- /* Update new IP address to lease with the current IP address to test */
- NewIPAddress->u8[3] = IP;
-
- /* If we've found an unleased IP, abort with the updated IP stored for the called */
- if (!(DHCPServerApp_CheckIfIPLeased(NewIPAddress)))
- return;
- }
-}
-
-/** Marks the given IP Address as leased in the address pool, so that it will not be
- * allocated to another client unless it is first released.
- *
- * \param[in] IPAddress IP Address to mark as leased
- *
- * \pre The IP address must be within the same /24 subnet as the virtual webserver.
- */
-static void DHCPServerApp_LeaseIP(const uip_ipaddr_t* const IPAddress)
-{
- uint8_t Byte = (IPAddress->u8[3] / 8);
- uint8_t Mask = (1 << (IPAddress->u8[3] % 8));
-
- /* Mark the IP address as leased in the allocation table */
- LeasedIPs[Byte] |= Mask;
-}
-
-/** Marks the given IP Address as not leased in the address pool, so that it can be
- * allocated to another client upon request.
- *
- * \param[in] IPAddress IP Address to mark as not leased
- *
- * \pre The IP address must be within the same /24 subnet as the virtual webserver.
- */
-static void DHCPServerApp_UnleaseIP(const uip_ipaddr_t* const IPAddress)
-{
- uint8_t Byte = (IPAddress->u8[3] / 8);
- uint8_t Mask = (1 << (IPAddress->u8[3] % 8));
-
- /* Mark the IP address as unleased in the allocation table */
- LeasedIPs[Byte] &= ~Mask;
-}
-#endif
-
diff --git a/lib/lufa/Projects/Webserver/Lib/DHCPServerApp.h b/lib/lufa/Projects/Webserver/Lib/DHCPServerApp.h
deleted file mode 100644
index a9dae7bf3..000000000
--- a/lib/lufa/Projects/Webserver/Lib/DHCPServerApp.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Header file for DHCPServerApp.c.
- */
-
-#ifndef _DHCPSERVER_APP_H_
-#define _DHCPSERVER_APP_H_
-
- /* Includes: */
- #include <stdio.h>
-
- #include <uip.h>
-
- #include "Config/AppConfig.h"
- #include "../Webserver.h"
- #include "DHCPCommon.h"
-
- /* Function Prototypes: */
- void DHCPServerApp_Init(void);
- void DHCPServerApp_Callback(void);
-
- #if defined(INCLUDE_FROM_DHCPSERVERAPP_C)
- static uint16_t DHCPServerApp_FillDHCPHeader(DHCP_Header_t* const DHCPHeader,
- const uint8_t DHCPMessageType,
- const struct uip_eth_addr* const ClientHardwareAddress,
- const uip_ipaddr_t* const PreferredClientIP,
- const uint32_t TransactionID);
- static bool DHCPServerApp_CheckIfIPLeased(const uip_ipaddr_t* const IPAddress);
- static void DHCPServerApp_GetUnleasedIP(uip_ipaddr_t* const NewIPAddress);
- static void DHCPServerApp_LeaseIP(const uip_ipaddr_t* const IPAddress);
- static void DHCPServerApp_UnleaseIP(const uip_ipaddr_t* const IPAddress);
- #endif
-#endif
-
diff --git a/lib/lufa/Projects/Webserver/Lib/DataflashManager.c b/lib/lufa/Projects/Webserver/Lib/DataflashManager.c
deleted file mode 100644
index b1111ce39..000000000
--- a/lib/lufa/Projects/Webserver/Lib/DataflashManager.c
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Functions to manage the physical Dataflash media, including reading and writing of
- * blocks of data. These functions are called by the SCSI layer when data must be stored
- * or retrieved to/from the physical storage media. If a different media is used (such
- * as a SD card or EEPROM), functions similar to these will need to be generated.
- */
-
-#define INCLUDE_FROM_DATAFLASHMANAGER_C
-#include "DataflashManager.h"
-
-/** Writes blocks (OS blocks, not Dataflash pages) to the storage medium, the board Dataflash IC(s), from
- * the pre-selected data OUT endpoint. This routine reads in OS sized blocks from the endpoint and writes
- * them to the Dataflash in Dataflash page sized blocks.
- *
- * \param[in] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state
- * \param[in] BlockAddress Data block starting address for the write sequence
- * \param[in] TotalBlocks Number of blocks of data to write
- */
-void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
- const uint32_t BlockAddress,
- uint16_t TotalBlocks)
-{
- uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
- uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
- uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
- bool UsingSecondBuffer = false;
-
- /* Select the correct starting Dataflash IC for the block requested */
- Dataflash_SelectChipFromPage(CurrDFPage);
-
-#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
- /* Copy selected dataflash's current page contents to the Dataflash buffer */
- Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);
- Dataflash_SendAddressBytes(CurrDFPage, 0);
- Dataflash_WaitWhileBusy();
-#endif
-
- /* Send the Dataflash buffer write command */
- Dataflash_SendByte(DF_CMD_BUFF1WRITE);
- Dataflash_SendAddressBytes(0, CurrDFPageByte);
-
- /* Wait until endpoint is ready before continuing */
- if (Endpoint_WaitUntilReady())
- return;
-
- while (TotalBlocks)
- {
- uint8_t BytesInBlockDiv16 = 0;
-
- /* Write an endpoint packet sized data block to the Dataflash */
- while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
- {
- /* Check if the endpoint is currently empty */
- if (!(Endpoint_IsReadWriteAllowed()))
- {
- /* Clear the current endpoint bank */
- Endpoint_ClearOUT();
-
- /* Wait until the host has sent another packet */
- if (Endpoint_WaitUntilReady())
- return;
- }
-
- /* Check if end of Dataflash page reached */
- if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
- {
- /* Write the Dataflash buffer contents back to the Dataflash page */
- Dataflash_WaitWhileBusy();
- Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
- Dataflash_SendAddressBytes(CurrDFPage, 0);
-
- /* Reset the Dataflash buffer counter, increment the page counter */
- CurrDFPageByteDiv16 = 0;
- CurrDFPage++;
-
- /* Once all the Dataflash ICs have had their first buffers filled, switch buffers to maintain throughput */
- if (Dataflash_GetSelectedChip() == DATAFLASH_CHIP_MASK(DATAFLASH_TOTALCHIPS))
- UsingSecondBuffer = !(UsingSecondBuffer);
-
- /* Select the next Dataflash chip based on the new Dataflash page index */
- Dataflash_SelectChipFromPage(CurrDFPage);
-
-#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
- /* If less than one Dataflash page remaining, copy over the existing page to preserve trailing data */
- if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))
- {
- /* Copy selected dataflash's current page contents to the Dataflash buffer */
- Dataflash_WaitWhileBusy();
- Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1);
- Dataflash_SendAddressBytes(CurrDFPage, 0);
- Dataflash_WaitWhileBusy();
- }
-#endif
-
- /* Send the Dataflash buffer write command */
- Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2WRITE : DF_CMD_BUFF1WRITE);
- Dataflash_SendAddressBytes(0, 0);
- }
-
- /* Write one 16-byte chunk of data to the Dataflash */
- Dataflash_SendByte(Endpoint_Read_8());
- Dataflash_SendByte(Endpoint_Read_8());
- Dataflash_SendByte(Endpoint_Read_8());
- Dataflash_SendByte(Endpoint_Read_8());
- Dataflash_SendByte(Endpoint_Read_8());
- Dataflash_SendByte(Endpoint_Read_8());
- Dataflash_SendByte(Endpoint_Read_8());
- Dataflash_SendByte(Endpoint_Read_8());
- Dataflash_SendByte(Endpoint_Read_8());
- Dataflash_SendByte(Endpoint_Read_8());
- Dataflash_SendByte(Endpoint_Read_8());
- Dataflash_SendByte(Endpoint_Read_8());
- Dataflash_SendByte(Endpoint_Read_8());
- Dataflash_SendByte(Endpoint_Read_8());
- Dataflash_SendByte(Endpoint_Read_8());
- Dataflash_SendByte(Endpoint_Read_8());
-
- /* Increment the Dataflash page 16 byte block counter */
- CurrDFPageByteDiv16++;
-
- /* Increment the block 16 byte block counter */
- BytesInBlockDiv16++;
-
- /* Check if the current command is being aborted by the host */
- if (MSInterfaceInfo->State.IsMassStoreReset)
- return;
- }
-
- /* Decrement the blocks remaining counter */
- TotalBlocks--;
- }
-
- /* Write the Dataflash buffer contents back to the Dataflash page */
- Dataflash_WaitWhileBusy();
- Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
- Dataflash_SendAddressBytes(CurrDFPage, 0x00);
- Dataflash_WaitWhileBusy();
-
- /* If the endpoint is empty, clear it ready for the next packet from the host */
- if (!(Endpoint_IsReadWriteAllowed()))
- Endpoint_ClearOUT();
-
- /* Deselect all Dataflash chips */
- Dataflash_DeselectChip();
-}
-
-/** Reads blocks (OS blocks, not Dataflash pages) from the storage medium, the board Dataflash IC(s), into
- * the pre-selected data IN endpoint. This routine reads in Dataflash page sized blocks from the Dataflash
- * and writes them in OS sized blocks to the endpoint.
- *
- * \param[in] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state
- * \param[in] BlockAddress Data block starting address for the read sequence
- * \param[in] TotalBlocks Number of blocks of data to read
- */
-void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
- const uint32_t BlockAddress,
- uint16_t TotalBlocks)
-{
- uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
- uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
- uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
-
- /* Select the correct starting Dataflash IC for the block requested */
- Dataflash_SelectChipFromPage(CurrDFPage);
-
- /* Send the Dataflash main memory page read command */
- Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
- Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);
- Dataflash_SendByte(0x00);
- Dataflash_SendByte(0x00);
- Dataflash_SendByte(0x00);
- Dataflash_SendByte(0x00);
-
- /* Wait until endpoint is ready before continuing */
- if (Endpoint_WaitUntilReady())
- return;
-
- while (TotalBlocks)
- {
- uint8_t BytesInBlockDiv16 = 0;
-
- /* Read an endpoint packet sized data block from the Dataflash */
- while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
- {
- /* Check if the endpoint is currently full */
- if (!(Endpoint_IsReadWriteAllowed()))
- {
- /* Clear the endpoint bank to send its contents to the host */
- Endpoint_ClearIN();
-
- /* Wait until the endpoint is ready for more data */
- if (Endpoint_WaitUntilReady())
- return;
- }
-
- /* Check if end of Dataflash page reached */
- if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
- {
- /* Reset the Dataflash buffer counter, increment the page counter */
- CurrDFPageByteDiv16 = 0;
- CurrDFPage++;
-
- /* Select the next Dataflash chip based on the new Dataflash page index */
- Dataflash_SelectChipFromPage(CurrDFPage);
-
- /* Send the Dataflash main memory page read command */
- Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
- Dataflash_SendAddressBytes(CurrDFPage, 0);
- Dataflash_SendByte(0x00);
- Dataflash_SendByte(0x00);
- Dataflash_SendByte(0x00);
- Dataflash_SendByte(0x00);
- }
-
- /* Read one 16-byte chunk of data from the Dataflash */
- Endpoint_Write_8(Dataflash_ReceiveByte());
- Endpoint_Write_8(Dataflash_ReceiveByte());
- Endpoint_Write_8(Dataflash_ReceiveByte());
- Endpoint_Write_8(Dataflash_ReceiveByte());
- Endpoint_Write_8(Dataflash_ReceiveByte());
- Endpoint_Write_8(Dataflash_ReceiveByte());
- Endpoint_Write_8(Dataflash_ReceiveByte());
- Endpoint_Write_8(Dataflash_ReceiveByte());
- Endpoint_Write_8(Dataflash_ReceiveByte());
- Endpoint_Write_8(Dataflash_ReceiveByte());
- Endpoint_Write_8(Dataflash_ReceiveByte());
- Endpoint_Write_8(Dataflash_ReceiveByte());
- Endpoint_Write_8(Dataflash_ReceiveByte());
- Endpoint_Write_8(Dataflash_ReceiveByte());
- Endpoint_Write_8(Dataflash_ReceiveByte());
- Endpoint_Write_8(Dataflash_ReceiveByte());
-
- /* Increment the Dataflash page 16 byte block counter */
- CurrDFPageByteDiv16++;
-
- /* Increment the block 16 byte block counter */
- BytesInBlockDiv16++;
-
- /* Check if the current command is being aborted by the host */
- if (MSInterfaceInfo->State.IsMassStoreReset)
- return;
- }
-
- /* Decrement the blocks remaining counter */
- TotalBlocks--;
- }
-
- /* If the endpoint is full, send its contents to the host */
- if (!(Endpoint_IsReadWriteAllowed()))
- Endpoint_ClearIN();
-
- /* Deselect all Dataflash chips */
- Dataflash_DeselectChip();
-}
-
-/** Writes blocks (OS blocks, not Dataflash pages) to the storage medium, the board Dataflash IC(s), from
- * the given RAM buffer. This routine reads in OS sized blocks from the buffer and writes them to the
- * Dataflash in Dataflash page sized blocks. This can be linked to FAT libraries to write files to the
- * Dataflash.
- *
- * \param[in] BlockAddress Data block starting address for the write sequence
- * \param[in] TotalBlocks Number of blocks of data to write
- * \param[in] BufferPtr Pointer to the data source RAM buffer
- */
-void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress,
- uint16_t TotalBlocks,
- const uint8_t* BufferPtr)
-{
- uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
- uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
- uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
- bool UsingSecondBuffer = false;
-
- /* Select the correct starting Dataflash IC for the block requested */
- Dataflash_SelectChipFromPage(CurrDFPage);
-
-#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
- /* Copy selected dataflash's current page contents to the Dataflash buffer */
- Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);
- Dataflash_SendAddressBytes(CurrDFPage, 0);
- Dataflash_WaitWhileBusy();
-#endif
-
- /* Send the Dataflash buffer write command */
- Dataflash_SendByte(DF_CMD_BUFF1WRITE);
- Dataflash_SendAddressBytes(0, CurrDFPageByte);
-
- while (TotalBlocks)
- {
- uint8_t BytesInBlockDiv16 = 0;
-
- /* Write an endpoint packet sized data block to the Dataflash */
- while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
- {
- /* Check if end of Dataflash page reached */
- if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
- {
- /* Write the Dataflash buffer contents back to the Dataflash page */
- Dataflash_WaitWhileBusy();
- Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
- Dataflash_SendAddressBytes(CurrDFPage, 0);
-
- /* Reset the Dataflash buffer counter, increment the page counter */
- CurrDFPageByteDiv16 = 0;
- CurrDFPage++;
-
- /* Once all the Dataflash ICs have had their first buffers filled, switch buffers to maintain throughput */
- if (Dataflash_GetSelectedChip() == DATAFLASH_CHIP_MASK(DATAFLASH_TOTALCHIPS))
- UsingSecondBuffer = !(UsingSecondBuffer);
-
- /* Select the next Dataflash chip based on the new Dataflash page index */
- Dataflash_SelectChipFromPage(CurrDFPage);
-
-#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
- /* If less than one Dataflash page remaining, copy over the existing page to preserve trailing data */
- if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))
- {
- /* Copy selected dataflash's current page contents to the Dataflash buffer */
- Dataflash_WaitWhileBusy();
- Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1);
- Dataflash_SendAddressBytes(CurrDFPage, 0);
- Dataflash_WaitWhileBusy();
- }
-#endif
-
- /* Send the Dataflash buffer write command */
- Dataflash_ToggleSelectedChipCS();
- Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2WRITE : DF_CMD_BUFF1WRITE);
- Dataflash_SendAddressBytes(0, 0);
- }
-
- /* Write one 16-byte chunk of data to the Dataflash */
- for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++)
- Dataflash_SendByte(*(BufferPtr++));
-
- /* Increment the Dataflash page 16 byte block counter */
- CurrDFPageByteDiv16++;
-
- /* Increment the block 16 byte block counter */
- BytesInBlockDiv16++;
- }
-
- /* Decrement the blocks remaining counter */
- TotalBlocks--;
- }
-
- /* Write the Dataflash buffer contents back to the Dataflash page */
- Dataflash_WaitWhileBusy();
- Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
- Dataflash_SendAddressBytes(CurrDFPage, 0x00);
- Dataflash_WaitWhileBusy();
-
- /* Deselect all Dataflash chips */
- Dataflash_DeselectChip();
-}
-
-/** Reads blocks (OS blocks, not Dataflash pages) from the storage medium, the board Dataflash IC(s), into
- * the preallocated RAM buffer. This routine reads in Dataflash page sized blocks from the Dataflash
- * and writes them in OS sized blocks to the given buffer. This can be linked to FAT libraries to read
- * the files stored on the Dataflash.
- *
- * \param[in] BlockAddress Data block starting address for the read sequence
- * \param[in] TotalBlocks Number of blocks of data to read
- * \param[out] BufferPtr Pointer to the data destination RAM buffer
- */
-void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress,
- uint16_t TotalBlocks,
- uint8_t* BufferPtr)
-{
- uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
- uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
- uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
-
- /* Select the correct starting Dataflash IC for the block requested */
- Dataflash_SelectChipFromPage(CurrDFPage);
-
- /* Send the Dataflash main memory page read command */
- Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
- Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);
- Dataflash_SendByte(0x00);
- Dataflash_SendByte(0x00);
- Dataflash_SendByte(0x00);
- Dataflash_SendByte(0x00);
-
- while (TotalBlocks)
- {
- uint8_t BytesInBlockDiv16 = 0;
-
- /* Read an endpoint packet sized data block from the Dataflash */
- while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
- {
- /* Check if end of Dataflash page reached */
- if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
- {
- /* Reset the Dataflash buffer counter, increment the page counter */
- CurrDFPageByteDiv16 = 0;
- CurrDFPage++;
-
- /* Select the next Dataflash chip based on the new Dataflash page index */
- Dataflash_SelectChipFromPage(CurrDFPage);
-
- /* Send the Dataflash main memory page read command */
- Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
- Dataflash_SendAddressBytes(CurrDFPage, 0);
- Dataflash_SendByte(0x00);
- Dataflash_SendByte(0x00);
- Dataflash_SendByte(0x00);
- Dataflash_SendByte(0x00);
- }
-
- /* Read one 16-byte chunk of data from the Dataflash */
- for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++)
- *(BufferPtr++) = Dataflash_ReceiveByte();
-
- /* Increment the Dataflash page 16 byte block counter */
- CurrDFPageByteDiv16++;
-
- /* Increment the block 16 byte block counter */
- BytesInBlockDiv16++;
- }
-
- /* Decrement the blocks remaining counter */
- TotalBlocks--;
- }
-
- /* Deselect all Dataflash chips */
- Dataflash_DeselectChip();
-}
-
-/** Disables the Dataflash memory write protection bits on the board Dataflash ICs, if enabled. */
-void DataflashManager_ResetDataflashProtections(void)
-{
- /* Select first Dataflash chip, send the read status register command */
- Dataflash_SelectChip(DATAFLASH_CHIP1);
- Dataflash_SendByte(DF_CMD_GETSTATUS);
-
- /* Check if sector protection is enabled */
- if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON)
- {
- Dataflash_ToggleSelectedChipCS();
-
- /* Send the commands to disable sector protection */
- Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]);
- Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]);
- Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]);
- Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]);
- }
-
- /* Select second Dataflash chip (if present on selected board), send read status register command */
- #if (DATAFLASH_TOTALCHIPS == 2)
- Dataflash_SelectChip(DATAFLASH_CHIP2);
- Dataflash_SendByte(DF_CMD_GETSTATUS);
-
- /* Check if sector protection is enabled */
- if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON)
- {
- Dataflash_ToggleSelectedChipCS();
-
- /* Send the commands to disable sector protection */
- Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]);
- Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]);
- Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]);
- Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]);
- }
- #endif
-
- /* Deselect current Dataflash chip */
- Dataflash_DeselectChip();
-}
-
-/** Performs a simple test on the attached Dataflash IC(s) to ensure that they are working.
- *
- * \return Boolean \c true if all media chips are working, \c false otherwise
- */
-bool DataflashManager_CheckDataflashOperation(void)
-{
- uint8_t ReturnByte;
-
- /* Test first Dataflash IC is present and responding to commands */
- Dataflash_SelectChip(DATAFLASH_CHIP1);
- Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO);
- ReturnByte = Dataflash_ReceiveByte();
- Dataflash_DeselectChip();
-
- /* If returned data is invalid, fail the command */
- if (ReturnByte != DF_MANUFACTURER_ATMEL)
- return false;
-
- #if (DATAFLASH_TOTALCHIPS == 2)
- /* Test second Dataflash IC is present and responding to commands */
- Dataflash_SelectChip(DATAFLASH_CHIP2);
- Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO);
- ReturnByte = Dataflash_ReceiveByte();
- Dataflash_DeselectChip();
-
- /* If returned data is invalid, fail the command */
- if (ReturnByte != DF_MANUFACTURER_ATMEL)
- return false;
- #endif
-
- return true;
-}
-
diff --git a/lib/lufa/Projects/Webserver/Lib/DataflashManager.h b/lib/lufa/Projects/Webserver/Lib/DataflashManager.h
deleted file mode 100644
index 367fbac8c..000000000
--- a/lib/lufa/Projects/Webserver/Lib/DataflashManager.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Header file for DataflashManager.c.
- */
-
-#ifndef _DATAFLASH_MANAGER_H_
-#define _DATAFLASH_MANAGER_H_
-
- /* Includes: */
- #include <avr/io.h>
-
- #include "../Descriptors.h"
-
- #include <LUFA/Common/Common.h>
- #include <LUFA/Drivers/USB/USB.h>
- #include <LUFA/Drivers/Board/Dataflash.h>
-
- /* Preprocessor Checks: */
- #if (DATAFLASH_PAGE_SIZE % 16)
- #error Dataflash page size must be a multiple of 16 bytes.
- #endif
-
- /* Defines: */
- /** Total number of bytes of the storage medium, comprised of one or more Dataflash ICs. */
- #define VIRTUAL_MEMORY_BYTES ((uint32_t)DATAFLASH_PAGES * DATAFLASH_PAGE_SIZE * DATAFLASH_TOTALCHIPS)
-
- /** Block size of the device. This is kept at 512 to remain compatible with the OS despite the underlying
- * storage media (Dataflash) using a different native block size. Do not change this value.
- */
- #define VIRTUAL_MEMORY_BLOCK_SIZE 512
-
- /** Total number of blocks of the virtual memory for reporting to the host as the device's total capacity. Do not
- * change this value; change VIRTUAL_MEMORY_BYTES instead to alter the media size.
- */
- #define VIRTUAL_MEMORY_BLOCKS (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE)
-
- /** Indicates if the disk is write protected or not. */
- #define DISK_READ_ONLY false
-
- /* Function Prototypes: */
- void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
- const uint32_t BlockAddress,
- uint16_t TotalBlocks);
- void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
- const uint32_t BlockAddress,
- uint16_t TotalBlocks);
- void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress,
- uint16_t TotalBlocks,
- const uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
- void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress,
- uint16_t TotalBlocks,
- uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
- void DataflashManager_ResetDataflashProtections(void);
- bool DataflashManager_CheckDataflashOperation(void);
-
-#endif
-
diff --git a/lib/lufa/Projects/Webserver/Lib/FATFs/00readme.txt b/lib/lufa/Projects/Webserver/Lib/FATFs/00readme.txt
deleted file mode 100644
index 80d8843d1..000000000
--- a/lib/lufa/Projects/Webserver/Lib/FATFs/00readme.txt
+++ /dev/null
@@ -1,135 +0,0 @@
-FatFs Module Source Files R0.09a (C)ChaN, 2012
-
-
-FILES
-
- ffconf.h Configuration file for FatFs module.
- ff.h Common include file for FatFs and application module.
- ff.c FatFs module.
- diskio.h Common include file for FatFs and disk I/O module.
- diskio.c An example of glue function to attach existing disk I/O module to FatFs.
- integer.h Integer type definitions for FatFs.
- option Optional external functions.
-
- Low level disk I/O module is not included in this archive because the FatFs
- module is only a generic file system layer and not depend on any specific
- storage device. You have to provide a low level disk I/O module that written
- to control your storage device.
-
-
-
-AGREEMENTS
-
- FatFs module is an open source software to implement FAT file system to
- small embedded systems. This is a free software and is opened for education,
- research and commercial developments under license policy of following trems.
-
- Copyright (C) 2012, ChaN, all right reserved.
-
- * The FatFs module is a free software and there is NO WARRANTY.
- * No restriction on use. You can use, modify and redistribute it for
- personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
- * Redistributions of source code must retain the above copyright notice.
-
-
-
-REVISION HISTORY
-
- Feb 26, 2006 R0.00 Prototype
-
- Apr 29, 2006 R0.01 First release.
-
- Jun 01, 2006 R0.02 Added FAT12.
- Removed unbuffered mode.
- Fixed a problem on small (<32M) patition.
-
- Jun 10, 2006 R0.02a Added a configuration option _FS_MINIMUM.
-
- Sep 22, 2006 R0.03 Added f_rename.
- Changed option _FS_MINIMUM to _FS_MINIMIZE.
-
- Dec 11, 2006 R0.03a Improved cluster scan algolithm to write files fast.
- Fixed f_mkdir creates incorrect directory on FAT32.
-
- Feb 04, 2007 R0.04 Supported multiple drive system. (FatFs)
- Changed some APIs for multiple drive system.
- Added f_mkfs. (FatFs)
- Added _USE_FAT32 option. (Tiny-FatFs)
-
- Apr 01, 2007 R0.04a Supported multiple partitions on a plysical drive. (FatFs)
- Fixed an endian sensitive code in f_mkfs. (FatFs)
- Added a capability of extending the file size to f_lseek.
- Added minimization level 3.
- Fixed a problem that can collapse a sector when recreate an
- existing file in any sub-directory at non FAT32 cfg. (Tiny-FatFs)
-
- May 05, 2007 R0.04b Added _USE_NTFLAG option.
- Added FSInfo support.
- Fixed some problems corresponds to FAT32. (Tiny-FatFs)
- Fixed DBCS name can result FR_INVALID_NAME.
- Fixed short seek (0 < ofs <= csize) collapses the file object.
-
- Aug 25, 2007 R0.05 Changed arguments of f_read, f_write.
- Changed arguments of f_mkfs. (FatFs)
- Fixed f_mkfs on FAT32 creates incorrect FSInfo. (FatFs)
- Fixed f_mkdir on FAT32 creates incorrect directory. (FatFs)
-
- Feb 03, 2008 R0.05a Added f_truncate().
- Added f_utime().
- Fixed off by one error at FAT sub-type determination.
- Fixed btr in f_read() can be mistruncated.
- Fixed cached sector is not flushed when create and close without write.
-
- Apr 01, 2008 R0.06 Added f_forward(). (Tiny-FatFs)
- Added string functions: fputc(), fputs(), fprintf() and fgets().
- Improved performance of f_lseek() on move to the same or following cluster.
-
- Apr 01, 2009, R0.07 Merged Tiny-FatFs as a buffer configuration option.
- Added long file name support.
- Added multiple code page support.
- Added re-entrancy for multitask operation.
- Added auto cluster size selection to f_mkfs().
- Added rewind option to f_readdir().
- Changed result code of critical errors.
- Renamed string functions to avoid name collision.
-
- Apr 14, 2009, R0.07a Separated out OS dependent code on reentrant cfg.
- Added multiple sector size support.
-
- Jun 21, 2009, R0.07c Fixed f_unlink() may return FR_OK on error.
- Fixed wrong cache control in f_lseek().
- Added relative path feature.
- Added f_chdir().
- Added f_chdrive().
- Added proper case conversion for extended characters.
-
- Nov 03, 2009 R0.07e Separated out configuration options from ff.h to ffconf.h.
- Added a configuration option, _LFN_UNICODE.
- Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH.
- Fixed name matching error on the 13 char boundary.
- Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
-
- May 15, 2010, R0.08 Added a memory configuration option. (_USE_LFN)
- Added file lock feature. (_FS_SHARE)
- Added fast seek feature. (_USE_FASTSEEK)
- Changed some types on the API, XCHAR->TCHAR.
- Changed fname member in the FILINFO structure on Unicode cfg.
- String functions support UTF-8 encoding files on Unicode cfg.
-
- Aug 16,'10 R0.08a Added f_getcwd(). (_FS_RPATH = 2)
- Added sector erase feature. (_USE_ERASE)
- Moved file lock semaphore table from fs object to the bss.
- Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'.
- Fixed f_mkfs() creates wrong FAT32 volume.
-
- Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write().
- f_lseek() reports required table size on creating CLMP.
- Extended format syntax of f_printf function.
- Ignores duplicated directory separators in given path names.
-
- Sep 06,'11 R0.09 f_mkfs() supports multiple partition to finish the multiple partition feature.
- Added f_fdisk(). (_MULTI_PARTITION = 2)
-
- Aug 27,'12 R0.09a Fixed assertion failure due to OS/2 EA on FAT12/16.
- Changed API rejects null object pointer to avoid crash.
- Changed option name _FS_SHARE to _FS_LOCK.
diff --git a/lib/lufa/Projects/Webserver/Lib/FATFs/diskio.c b/lib/lufa/Projects/Webserver/Lib/FATFs/diskio.c
deleted file mode 100644
index b119b1a40..000000000
--- a/lib/lufa/Projects/Webserver/Lib/FATFs/diskio.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-----------------------------------------------------------------------*/
-/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */
-/*-----------------------------------------------------------------------*/
-/* This is a stub disk I/O module that acts as front end of the existing */
-/* disk I/O modules and attach it to FatFs module with common interface. */
-/*-----------------------------------------------------------------------*/
-
-#include "diskio.h"
-
-/*-----------------------------------------------------------------------*/
-/* Initialize a Drive */
-
-DSTATUS disk_initialize (
- BYTE drv /* Physical drive number (0..) */
-)
-{
- return FR_OK;
-}
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Return Disk Status */
-
-DSTATUS disk_status (
- BYTE drv /* Physical drive number (0..) */
-)
-{
- return FR_OK;
-}
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Read Sector(s) */
-
-DRESULT disk_read (
- BYTE drv, /* Physical drive number (0..) */
- BYTE *buff, /* Data buffer to store read data */
- DWORD sector, /* Sector address (LBA) */
- BYTE count /* Number of sectors to read (1..128) */
-)
-{
- DataflashManager_ReadBlocks_RAM(sector, count, buff);
- return RES_OK;
-}
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Write Sector(s) */
-
-#if _READONLY == 0
-DRESULT disk_write (
- BYTE drv, /* Physical drive number (0..) */
- const BYTE *buff, /* Data to be written */
- DWORD sector, /* Sector address (LBA) */
- BYTE count /* Number of sectors to write (1..128) */
-)
-{
- DataflashManager_WriteBlocks_RAM(sector, count, buff);
- return RES_OK;
-}
-#endif /* _READONLY */
-
diff --git a/lib/lufa/Projects/Webserver/Lib/FATFs/diskio.h b/lib/lufa/Projects/Webserver/Lib/FATFs/diskio.h
deleted file mode 100644
index 65e3048a0..000000000
--- a/lib/lufa/Projects/Webserver/Lib/FATFs/diskio.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*-----------------------------------------------------------------------
-/ Low level disk interface module include file
-/-----------------------------------------------------------------------*/
-
-#ifndef _DISKIO_DEFINED
-#define _DISKIO_DEFINED
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "integer.h"
-#include "ff.h"
-
-#include "../DataflashManager.h"
-
-
-/* Status of Disk Functions */
-typedef BYTE DSTATUS;
-
-/* Results of Disk Functions */
-typedef enum {
- RES_OK = 0, /* 0: Successful */
- RES_ERROR, /* 1: R/W Error */
- RES_WRPRT, /* 2: Write Protected */
- RES_NOTRDY, /* 3: Not Ready */
- RES_PARERR /* 4: Invalid Parameter */
-} DRESULT;
-
-
-/*---------------------------------------*/
-/* Prototypes for disk control functions */
-
-DSTATUS disk_initialize (BYTE);
-DSTATUS disk_status (BYTE);
-DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);
-DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);
-DRESULT disk_ioctl (BYTE, BYTE, void*);
-
-
-/* Disk Status Bits (DSTATUS) */
-
-#define STA_NOINIT 0x01 /* Drive not initialized */
-#define STA_NODISK 0x02 /* No medium in the drive */
-#define STA_PROTECT 0x04 /* Write protected */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/lufa/Projects/Webserver/Lib/FATFs/ff.c b/lib/lufa/Projects/Webserver/Lib/FATFs/ff.c
deleted file mode 100644
index 2f58adf83..000000000
--- a/lib/lufa/Projects/Webserver/Lib/FATFs/ff.c
+++ /dev/null
@@ -1,4139 +0,0 @@
-/*----------------------------------------------------------------------------/
-/ FatFs - FAT file system module R0.09a (C)ChaN, 2012
-/-----------------------------------------------------------------------------/
-/ FatFs module is a generic FAT file system module for small embedded systems.
-/ This is a free software that opened for education, research and commercial
-/ developments under license policy of following terms.
-/
-/ Copyright (C) 2012, ChaN, all right reserved.
-/
-/ * The FatFs module is a free software and there is NO WARRANTY.
-/ * No restriction on use. You can use, modify and redistribute it for
-/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
-/ * Redistributions of source code must retain the above copyright notice.
-/
-/-----------------------------------------------------------------------------/
-/ Feb 26,'06 R0.00 Prototype.
-/
-/ Apr 29,'06 R0.01 First stable version.
-/
-/ Jun 01,'06 R0.02 Added FAT12 support.
-/ Removed unbuffered mode.
-/ Fixed a problem on small (<32M) partition.
-/ Jun 10,'06 R0.02a Added a configuration option (_FS_MINIMUM).
-/
-/ Sep 22,'06 R0.03 Added f_rename().
-/ Changed option _FS_MINIMUM to _FS_MINIMIZE.
-/ Dec 11,'06 R0.03a Improved cluster scan algorithm to write files fast.
-/ Fixed f_mkdir() creates incorrect directory on FAT32.
-/
-/ Feb 04,'07 R0.04 Supported multiple drive system.
-/ Changed some interfaces for multiple drive system.
-/ Changed f_mountdrv() to f_mount().
-/ Added f_mkfs().
-/ Apr 01,'07 R0.04a Supported multiple partitions on a physical drive.
-/ Added a capability of extending file size to f_lseek().
-/ Added minimization level 3.
-/ Fixed an endian sensitive code in f_mkfs().
-/ May 05,'07 R0.04b Added a configuration option _USE_NTFLAG.
-/ Added FSInfo support.
-/ Fixed DBCS name can result FR_INVALID_NAME.
-/ Fixed short seek (<= csize) collapses the file object.
-/
-/ Aug 25,'07 R0.05 Changed arguments of f_read(), f_write() and f_mkfs().
-/ Fixed f_mkfs() on FAT32 creates incorrect FSInfo.
-/ Fixed f_mkdir() on FAT32 creates incorrect directory.
-/ Feb 03,'08 R0.05a Added f_truncate() and f_utime().
-/ Fixed off by one error at FAT sub-type determination.
-/ Fixed btr in f_read() can be mistruncated.
-/ Fixed cached sector is not flushed when create and close without write.
-/
-/ Apr 01,'08 R0.06 Added fputc(), fputs(), fprintf() and fgets().
-/ Improved performance of f_lseek() on moving to the same or following cluster.
-/
-/ Apr 01,'09 R0.07 Merged Tiny-FatFs as a configuration option. (_FS_TINY)
-/ Added long file name feature.
-/ Added multiple code page feature.
-/ Added re-entrancy for multitask operation.
-/ Added auto cluster size selection to f_mkfs().
-/ Added rewind option to f_readdir().
-/ Changed result code of critical errors.
-/ Renamed string functions to avoid name collision.
-/ Apr 14,'09 R0.07a Separated out OS dependent code on reentrant cfg.
-/ Added multiple sector size feature.
-/ Jun 21,'09 R0.07c Fixed f_unlink() can return FR_OK on error.
-/ Fixed wrong cache control in f_lseek().
-/ Added relative path feature.
-/ Added f_chdir() and f_chdrive().
-/ Added proper case conversion to extended char.
-/ Nov 03,'09 R0.07e Separated out configuration options from ff.h to ffconf.h.
-/ Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH.
-/ Fixed name matching error on the 13 char boundary.
-/ Added a configuration option, _LFN_UNICODE.
-/ Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
-/
-/ May 15,'10 R0.08 Added a memory configuration option. (_USE_LFN = 3)
-/ Added file lock feature. (_FS_SHARE)
-/ Added fast seek feature. (_USE_FASTSEEK)
-/ Changed some types on the API, XCHAR->TCHAR.
-/ Changed fname member in the FILINFO structure on Unicode cfg.
-/ String functions support UTF-8 encoding files on Unicode cfg.
-/ Aug 16,'10 R0.08a Added f_getcwd(). (_FS_RPATH = 2)
-/ Added sector erase feature. (_USE_ERASE)
-/ Moved file lock semaphore table from fs object to the bss.
-/ Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'.
-/ Fixed f_mkfs() creates wrong FAT32 volume.
-/ Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write().
-/ f_lseek() reports required table size on creating CLMP.
-/ Extended format syntax of f_printf function.
-/ Ignores duplicated directory separators in given path name.
-/
-/ Sep 06,'11 R0.09 f_mkfs() supports multiple partition to finish the multiple partition feature.
-/ Added f_fdisk(). (_MULTI_PARTITION = 2)
-/ Aug 27,'12 R0.09a Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
-/ Changed f_open() and f_opendir reject null object pointer to avoid crash.
-/ Changed option name _FS_SHARE to _FS_LOCK.
-/---------------------------------------------------------------------------*/
-
-#include "ff.h" /* FatFs configurations and declarations */
-#include "diskio.h" /* Declarations of low level disk I/O functions */
-
-
-/*--------------------------------------------------------------------------
-
- Module Private Definitions
-
----------------------------------------------------------------------------*/
-
-#if _FATFS != 4004 /* Revision ID */
-#error Wrong include file (ff.h).
-#endif
-
-
-/* Definitions on sector size */
-#if _MAX_SS != 512 && _MAX_SS != 1024 && _MAX_SS != 2048 && _MAX_SS != 4096
-#error Wrong sector size.
-#endif
-#if _MAX_SS != 512
-#define SS(fs) ((fs)->ssize) /* Variable sector size */
-#else
-#define SS(fs) 512U /* Fixed sector size */
-#endif
-
-
-/* Reentrancy related */
-#if _FS_REENTRANT
-#if _USE_LFN == 1
-#error Static LFN work area must not be used in re-entrant configuration.
-#endif
-#define ENTER_FF(fs) { if (!lock_fs(fs)) return FR_TIMEOUT; }
-#define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; }
-#else
-#define ENTER_FF(fs)
-#define LEAVE_FF(fs, res) return res
-#endif
-
-#define ABORT(fs, res) { fp->flag |= FA__ERROR; LEAVE_FF(fs, res); }
-
-
-/* File access control feature */
-#if _FS_LOCK
-#if _FS_READONLY
-#error _FS_LOCK must be 0 on read-only cfg.
-#endif
-typedef struct {
- FATFS *fs; /* File ID 1, volume (NULL:blank entry) */
- DWORD clu; /* File ID 2, directory */
- WORD idx; /* File ID 3, directory index */
- WORD ctr; /* File open counter, 0:none, 0x01..0xFF:read open count, 0x100:write mode */
-} FILESEM;
-#endif
-
-
-
-/* DBCS code ranges and SBCS extend char conversion table */
-
-#if _CODE_PAGE == 932 /* Japanese Shift-JIS */
-#define _DF1S 0x81 /* DBC 1st byte range 1 start */
-#define _DF1E 0x9F /* DBC 1st byte range 1 end */
-#define _DF2S 0xE0 /* DBC 1st byte range 2 start */
-#define _DF2E 0xFC /* DBC 1st byte range 2 end */
-#define _DS1S 0x40 /* DBC 2nd byte range 1 start */
-#define _DS1E 0x7E /* DBC 2nd byte range 1 end */
-#define _DS2S 0x80 /* DBC 2nd byte range 2 start */
-#define _DS2E 0xFC /* DBC 2nd byte range 2 end */
-
-#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */
-#define _DF1S 0x81
-#define _DF1E 0xFE
-#define _DS1S 0x40
-#define _DS1E 0x7E
-#define _DS2S 0x80
-#define _DS2E 0xFE
-
-#elif _CODE_PAGE == 949 /* Korean */
-#define _DF1S 0x81
-#define _DF1E 0xFE
-#define _DS1S 0x41
-#define _DS1E 0x5A
-#define _DS2S 0x61
-#define _DS2E 0x7A
-#define _DS3S 0x81
-#define _DS3E 0xFE
-
-#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
-#define _DF1S 0x81
-#define _DF1E 0xFE
-#define _DS1S 0x40
-#define _DS1E 0x7E
-#define _DS2S 0xA1
-#define _DS2E 0xFE
-
-#elif _CODE_PAGE == 437 /* U.S. (OEM) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
- 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
-
-#elif _CODE_PAGE == 720 /* Arabic (OEM) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
- 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
-
-#elif _CODE_PAGE == 737 /* Greek (OEM) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \
- 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
-
-#elif _CODE_PAGE == 775 /* Baltic (OEM) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
- 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
-
-#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
- 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
-
-#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \
- 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}
-
-#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */
-#define _DF1S 0
-#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \
- 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \
- 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}
-
-#elif _CODE_PAGE == 857 /* Turkish (OEM) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \
- 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
-
-#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
- 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
-
-#elif _CODE_PAGE == 862 /* Hebrew (OEM) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
- 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
-
-#elif _CODE_PAGE == 866 /* Russian (OEM) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
- 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
-
-#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
- 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
-
-#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
- 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
-
-#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
- 0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF}
-
-#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \
- 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
-
-#elif _CODE_PAGE == 1253 /* Greek (Windows) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
- 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \
- 0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF}
-
-#elif _CODE_PAGE == 1254 /* Turkish (Windows) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \
- 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
-
-#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
- 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
-
-#elif _CODE_PAGE == 1256 /* Arabic (Windows) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \
- 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF}
-
-#elif _CODE_PAGE == 1257 /* Baltic (Windows) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
- 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
-
-#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */
-#define _DF1S 0
-#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \
- 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F}
-
-#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */
-#if _USE_LFN
-#error Cannot use LFN feature without valid code page.
-#endif
-#define _DF1S 0
-
-#else
-#error Unknown code page
-
-#endif
-
-
-/* Character code support macros */
-#define IsUpper(c) (((c)>='A')&&((c)<='Z'))
-#define IsLower(c) (((c)>='a')&&((c)<='z'))
-#define IsDigit(c) (((c)>='0')&&((c)<='9'))
-
-#if _DF1S /* Code page is DBCS */
-
-#ifdef _DF2S /* Two 1st byte areas */
-#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))
-#else /* One 1st byte area */
-#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E)
-#endif
-
-#ifdef _DS3S /* Three 2nd byte areas */
-#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E))
-#else /* Two 2nd byte areas */
-#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))
-#endif
-
-#else /* Code page is SBCS */
-
-#define IsDBCS1(c) 0
-#define IsDBCS2(c) 0
-
-#endif /* _DF1S */
-
-
-/* Name status flags */
-#define NS 11 /* Index of name status byte in fn[] */
-#define NS_LOSS 0x01 /* Out of 8.3 format */
-#define NS_LFN 0x02 /* Force to create LFN entry */
-#define NS_LAST 0x04 /* Last segment */
-#define NS_BODY 0x08 /* Lower case flag (body) */
-#define NS_EXT 0x10 /* Lower case flag (ext) */
-#define NS_DOT 0x20 /* Dot entry */
-
-
-/* FAT sub-type boundaries */
-/* Note that the FAT spec by Microsoft says 4085 but Windows works with 4087! */
-#define MIN_FAT16 4086 /* Minimum number of clusters for FAT16 */
-#define MIN_FAT32 65526 /* Minimum number of clusters for FAT32 */
-
-
-/* FatFs refers the members in the FAT structures as byte array instead of
-/ structure member because the structure is not binary compatible between
-/ different platforms */
-
-#define BS_jmpBoot 0 /* Jump instruction (3) */
-#define BS_OEMName 3 /* OEM name (8) */
-#define BPB_BytsPerSec 11 /* Sector size [byte] (2) */
-#define BPB_SecPerClus 13 /* Cluster size [sector] (1) */
-#define BPB_RsvdSecCnt 14 /* Size of reserved area [sector] (2) */
-#define BPB_NumFATs 16 /* Number of FAT copies (1) */
-#define BPB_RootEntCnt 17 /* Number of root dir entries for FAT12/16 (2) */
-#define BPB_TotSec16 19 /* Volume size [sector] (2) */
-#define BPB_Media 21 /* Media descriptor (1) */
-#define BPB_FATSz16 22 /* FAT size [sector] (2) */
-#define BPB_SecPerTrk 24 /* Track size [sector] (2) */
-#define BPB_NumHeads 26 /* Number of heads (2) */
-#define BPB_HiddSec 28 /* Number of special hidden sectors (4) */
-#define BPB_TotSec32 32 /* Volume size [sector] (4) */
-#define BS_DrvNum 36 /* Physical drive number (2) */
-#define BS_BootSig 38 /* Extended boot signature (1) */
-#define BS_VolID 39 /* Volume serial number (4) */
-#define BS_VolLab 43 /* Volume label (8) */
-#define BS_FilSysType 54 /* File system type (1) */
-#define BPB_FATSz32 36 /* FAT size [sector] (4) */
-#define BPB_ExtFlags 40 /* Extended flags (2) */
-#define BPB_FSVer 42 /* File system version (2) */
-#define BPB_RootClus 44 /* Root dir first cluster (4) */
-#define BPB_FSInfo 48 /* Offset of FSInfo sector (2) */
-#define BPB_BkBootSec 50 /* Offset of backup boot sector (2) */
-#define BS_DrvNum32 64 /* Physical drive number (2) */
-#define BS_BootSig32 66 /* Extended boot signature (1) */
-#define BS_VolID32 67 /* Volume serial number (4) */
-#define BS_VolLab32 71 /* Volume label (8) */
-#define BS_FilSysType32 82 /* File system type (1) */
-#define FSI_LeadSig 0 /* FSI: Leading signature (4) */
-#define FSI_StrucSig 484 /* FSI: Structure signature (4) */
-#define FSI_Free_Count 488 /* FSI: Number of free clusters (4) */
-#define FSI_Nxt_Free 492 /* FSI: Last allocated cluster (4) */
-#define MBR_Table 446 /* MBR: Partition table offset (2) */
-#define SZ_PTE 16 /* MBR: Size of a partition table entry */
-#define BS_55AA 510 /* Boot sector signature (2) */
-
-#define DIR_Name 0 /* Short file name (11) */
-#define DIR_Attr 11 /* Attribute (1) */
-#define DIR_NTres 12 /* NT flag (1) */
-#define DIR_CrtTimeTenth 13 /* Created time sub-second (1) */
-#define DIR_CrtTime 14 /* Created time (2) */
-#define DIR_CrtDate 16 /* Created date (2) */
-#define DIR_LstAccDate 18 /* Last accessed date (2) */
-#define DIR_FstClusHI 20 /* Higher 16-bit of first cluster (2) */
-#define DIR_WrtTime 22 /* Modified time (2) */
-#define DIR_WrtDate 24 /* Modified date (2) */
-#define DIR_FstClusLO 26 /* Lower 16-bit of first cluster (2) */
-#define DIR_FileSize 28 /* File size (4) */
-#define LDIR_Ord 0 /* LFN entry order and LLE flag (1) */
-#define LDIR_Attr 11 /* LFN attribute (1) */
-#define LDIR_Type 12 /* LFN type (1) */
-#define LDIR_Chksum 13 /* Sum of corresponding SFN entry */
-#define LDIR_FstClusLO 26 /* Filled by zero (0) */
-#define SZ_DIR 32 /* Size of a directory entry */
-#define LLE 0x40 /* Last long entry flag in LDIR_Ord */
-#define DDE 0xE5 /* Deleted directory entry mark in DIR_Name[0] */
-#define NDDE 0x05 /* Replacement of the character collides with DDE */
-
-
-/*------------------------------------------------------------*/
-/* Module private work area */
-/*------------------------------------------------------------*/
-/* Note that uninitialized variables with static duration are
-/ zeroed/nulled at start-up. If not, the compiler or start-up
-/ routine is out of ANSI-C standard.
-*/
-
-#if _VOLUMES
-static
-FATFS *FatFs[_VOLUMES]; /* Pointer to the file system objects (logical drives) */
-#else
-#error Number of volumes must not be 0.
-#endif
-
-static
-WORD Fsid; /* File system mount ID */
-
-#if _FS_RPATH
-static
-BYTE CurrVol; /* Current drive */
-#endif
-
-#if _FS_LOCK
-static
-FILESEM Files[_FS_LOCK]; /* File lock semaphores */
-#endif
-
-#if _USE_LFN == 0 /* No LFN feature */
-#define DEF_NAMEBUF BYTE sfn[12]
-#define INIT_BUF(dobj) (dobj).fn = sfn
-#define FREE_BUF()
-
-#elif _USE_LFN == 1 /* LFN feature with static working buffer */
-static WCHAR LfnBuf[_MAX_LFN+1];
-#define DEF_NAMEBUF BYTE sfn[12]
-#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = LfnBuf; }
-#define FREE_BUF()
-
-#elif _USE_LFN == 2 /* LFN feature with dynamic working buffer on the stack */
-#define DEF_NAMEBUF BYTE sfn[12]; WCHAR lbuf[_MAX_LFN+1]
-#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = lbuf; }
-#define FREE_BUF()
-
-#elif _USE_LFN == 3 /* LFN feature with dynamic working buffer on the heap */
-#define DEF_NAMEBUF BYTE sfn[12]; WCHAR *lfn
-#define INIT_BUF(dobj) { lfn = ff_memalloc((_MAX_LFN + 1) * 2); \
- if (!lfn) LEAVE_FF((dobj).fs, FR_NOT_ENOUGH_CORE); \
- (dobj).lfn = lfn; (dobj).fn = sfn; }
-#define FREE_BUF() ff_memfree(lfn)
-
-#else
-#error Wrong LFN configuration.
-#endif
-
-
-
-
-/*--------------------------------------------------------------------------
-
- Module Private Functions
-
----------------------------------------------------------------------------*/
-
-
-/*-----------------------------------------------------------------------*/
-/* String functions */
-/*-----------------------------------------------------------------------*/
-
-/* Copy memory to memory */
-static
-void mem_cpy (void* dst, const void* src, UINT cnt) {
- BYTE *d = (BYTE*)dst;
- const BYTE *s = (const BYTE*)src;
-
-#if _WORD_ACCESS == 1
- while (cnt >= sizeof (int)) {
- *(int*)d = *(int*)s;
- d += sizeof (int); s += sizeof (int);
- cnt -= sizeof (int);
- }
-#endif
- while (cnt--)
- *d++ = *s++;
-}
-
-/* Fill memory */
-static
-void mem_set (void* dst, int val, UINT cnt) {
- BYTE *d = (BYTE*)dst;
-
- while (cnt--)
- *d++ = (BYTE)val;
-}
-
-/* Compare memory to memory */
-static
-int mem_cmp (const void* dst, const void* src, UINT cnt) {
- const BYTE *d = (const BYTE *)dst, *s = (const BYTE *)src;
- int r = 0;
-
- while (cnt-- && (r = *d++ - *s++) == 0) ;
- return r;
-}
-
-/* Check if chr is contained in the string */
-static
-int chk_chr (const char* str, int chr) {
- while (*str && *str != chr) str++;
- return *str;
-}
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Request/Release grant to access the volume */
-/*-----------------------------------------------------------------------*/
-#if _FS_REENTRANT
-
-static
-int lock_fs (
- FATFS *fs /* File system object */
-)
-{
- return ff_req_grant(fs->sobj);
-}
-
-
-static
-void unlock_fs (
- FATFS *fs, /* File system object */
- FRESULT res /* Result code to be returned */
-)
-{
- if (fs &&
- res != FR_NOT_ENABLED &&
- res != FR_INVALID_DRIVE &&
- res != FR_INVALID_OBJECT &&
- res != FR_TIMEOUT) {
- ff_rel_grant(fs->sobj);
- }
-}
-#endif
-
-
-
-/*-----------------------------------------------------------------------*/
-/* File lock control functions */
-/*-----------------------------------------------------------------------*/
-#if _FS_LOCK
-
-static
-FRESULT chk_lock ( /* Check if the file can be accessed */
- DIR* dj, /* Directory object pointing the file to be checked */
- int acc /* Desired access (0:Read, 1:Write, 2:Delete/Rename) */
-)
-{
- UINT i, be;
-
- /* Search file semaphore table */
- for (i = be = 0; i < _FS_LOCK; i++) {
- if (Files[i].fs) { /* Existing entry */
- if (Files[i].fs == dj->fs && /* Check if the file matched with an open file */
- Files[i].clu == dj->sclust &&
- Files[i].idx == dj->index) break;
- } else { /* Blank entry */
- be++;
- }
- }
- if (i == _FS_LOCK) /* The file is not opened */
- return (be || acc == 2) ? FR_OK : FR_TOO_MANY_OPEN_FILES; /* Is there a blank entry for new file? */
-
- /* The file has been opened. Reject any open against writing file and all write mode open */
- return (acc || Files[i].ctr == 0x100) ? FR_LOCKED : FR_OK;
-}
-
-
-static
-int enq_lock (void) /* Check if an entry is available for a new file */
-{
- UINT i;
-
- for (i = 0; i < _FS_LOCK && Files[i].fs; i++) ;
- return (i == _FS_LOCK) ? 0 : 1;
-}
-
-
-static
-UINT inc_lock ( /* Increment file open counter and returns its index (0:int error) */
- DIR* dj, /* Directory object pointing the file to register or increment */
- int acc /* Desired access mode (0:Read, !0:Write) */
-)
-{
- UINT i;
-
-
- for (i = 0; i < _FS_LOCK; i++) { /* Find the file */
- if (Files[i].fs == dj->fs &&
- Files[i].clu == dj->sclust &&
- Files[i].idx == dj->index) break;
- }
-
- if (i == _FS_LOCK) { /* Not opened. Register it as new. */
- for (i = 0; i < _FS_LOCK && Files[i].fs; i++) ;
- if (i == _FS_LOCK) return 0; /* No space to register (int err) */
- Files[i].fs = dj->fs;
- Files[i].clu = dj->sclust;
- Files[i].idx = dj->index;
- Files[i].ctr = 0;
- }
-
- if (acc && Files[i].ctr) return 0; /* Access violation (int err) */
-
- Files[i].ctr = acc ? 0x100 : Files[i].ctr + 1; /* Set semaphore value */
-
- return i + 1;
-}
-
-
-static
-FRESULT dec_lock ( /* Decrement file open counter */
- UINT i /* Semaphore index */
-)
-{
- WORD n;
- FRESULT res;
-
-
- if (--i < _FS_LOCK) {
- n = Files[i].ctr;
- if (n == 0x100) n = 0;
- if (n) n--;
- Files[i].ctr = n;
- if (!n) Files[i].fs = 0;
- res = FR_OK;
- } else {
- res = FR_INT_ERR;
- }
- return res;
-}
-
-
-static
-void clear_lock ( /* Clear lock entries of the volume */
- FATFS *fs
-)
-{
- UINT i;
-
- for (i = 0; i < _FS_LOCK; i++) {
- if (Files[i].fs == fs) Files[i].fs = 0;
- }
-}
-#endif
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Change window offset */
-/*-----------------------------------------------------------------------*/
-
-static
-FRESULT move_window (
- FATFS *fs, /* File system object */
- DWORD sector /* Sector number to make appearance in the fs->win[] */
-) /* Move to zero only writes back dirty window */
-{
- DWORD wsect;
-
-
- wsect = fs->winsect;
- if (wsect != sector) { /* Changed current window */
-#if !_FS_READONLY
- if (fs->wflag) { /* Write back dirty window if needed */
- if (disk_write(fs->drv, fs->win, wsect, 1) != RES_OK)
- return FR_DISK_ERR;
- fs->wflag = 0;
- if (wsect < (fs->fatbase + fs->fsize)) { /* In FAT area */
- BYTE nf;
- for (nf = fs->n_fats; nf > 1; nf--) { /* Reflect the change to all FAT copies */
- wsect += fs->fsize;
- disk_write(fs->drv, fs->win, wsect, 1);
- }
- }
- }
-#endif
- if (sector) {
- if (disk_read(fs->drv, fs->win, sector, 1) != RES_OK)
- return FR_DISK_ERR;
- fs->winsect = sector;
- }
- }
-
- return FR_OK;
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Clean-up cached data */
-/*-----------------------------------------------------------------------*/
-#if !_FS_READONLY
-static
-FRESULT sync ( /* FR_OK: successful, FR_DISK_ERR: failed */
- FATFS *fs /* File system object */
-)
-{
- FRESULT res;
-
-
- res = move_window(fs, 0);
- if (res == FR_OK) {
- /* Update FSInfo sector if needed */
- if (fs->fs_type == FS_FAT32 && fs->fsi_flag) {
- fs->winsect = 0;
- /* Create FSInfo structure */
- mem_set(fs->win, 0, 512);
- ST_WORD(fs->win+BS_55AA, 0xAA55);
- ST_DWORD(fs->win+FSI_LeadSig, 0x41615252);
- ST_DWORD(fs->win+FSI_StrucSig, 0x61417272);
- ST_DWORD(fs->win+FSI_Free_Count, fs->free_clust);
- ST_DWORD(fs->win+FSI_Nxt_Free, fs->last_clust);
- /* Write it into the FSInfo sector */
- disk_write(fs->drv, fs->win, fs->fsi_sector, 1);
- fs->fsi_flag = 0;
- }
- /* Make sure that no pending write process in the physical drive */
- if (disk_ioctl(fs->drv, CTRL_SYNC, 0) != RES_OK)
- res = FR_DISK_ERR;
- }
-
- return res;
-}
-#endif
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Get sector# from cluster# */
-/*-----------------------------------------------------------------------*/
-
-
-DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */
- FATFS *fs, /* File system object */
- DWORD clst /* Cluster# to be converted */
-)
-{
- clst -= 2;
- if (clst >= (fs->n_fatent - 2)) return 0; /* Invalid cluster# */
- return clst * fs->csize + fs->database;
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* FAT access - Read value of a FAT entry */
-/*-----------------------------------------------------------------------*/
-
-
-DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status */
- FATFS *fs, /* File system object */
- DWORD clst /* Cluster# to get the link information */
-)
-{
- UINT wc, bc;
- BYTE *p;
-
-
- if (clst < 2 || clst >= fs->n_fatent) /* Check range */
- return 1;
-
- switch (fs->fs_type) {
- case FS_FAT12 :
- bc = (UINT)clst; bc += bc / 2;
- if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;
- wc = fs->win[bc % SS(fs)]; bc++;
- if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;
- wc |= fs->win[bc % SS(fs)] << 8;
- return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);
-
- case FS_FAT16 :
- if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)))) break;
- p = &fs->win[clst * 2 % SS(fs)];
- return LD_WORD(p);
-
- case FS_FAT32 :
- if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)))) break;
- p = &fs->win[clst * 4 % SS(fs)];
- return LD_DWORD(p) & 0x0FFFFFFF;
- }
-
- return 0xFFFFFFFF; /* An error occurred at the disk I/O layer */
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* FAT access - Change value of a FAT entry */
-/*-----------------------------------------------------------------------*/
-#if !_FS_READONLY
-
-FRESULT put_fat (
- FATFS *fs, /* File system object */
- DWORD clst, /* Cluster# to be changed in range of 2 to fs->n_fatent - 1 */
- DWORD val /* New value to mark the cluster */
-)
-{
- UINT bc;
- BYTE *p;
- FRESULT res;
-
-
- if (clst < 2 || clst >= fs->n_fatent) { /* Check range */
- res = FR_INT_ERR;
-
- } else {
- switch (fs->fs_type) {
- case FS_FAT12 :
- bc = (UINT)clst; bc += bc / 2;
- res = move_window(fs, fs->fatbase + (bc / SS(fs)));
- if (res != FR_OK) break;
- p = &fs->win[bc % SS(fs)];
- *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val;
- bc++;
- fs->wflag = 1;
- res = move_window(fs, fs->fatbase + (bc / SS(fs)));
- if (res != FR_OK) break;
- p = &fs->win[bc % SS(fs)];
- *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F));
- break;
-
- case FS_FAT16 :
- res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)));
- if (res != FR_OK) break;
- p = &fs->win[clst * 2 % SS(fs)];
- ST_WORD(p, (WORD)val);
- break;
-
- case FS_FAT32 :
- res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)));
- if (res != FR_OK) break;
- p = &fs->win[clst * 4 % SS(fs)];
- val |= LD_DWORD(p) & 0xF0000000;
- ST_DWORD(p, val);
- break;
-
- default :
- res = FR_INT_ERR;
- }
- fs->wflag = 1;
- }
-
- return res;
-}
-#endif /* !_FS_READONLY */
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* FAT handling - Remove a cluster chain */
-/*-----------------------------------------------------------------------*/
-#if !_FS_READONLY
-static
-FRESULT remove_chain (
- FATFS *fs, /* File system object */
- DWORD clst /* Cluster# to remove a chain from */
-)
-{
- FRESULT res;
- DWORD nxt;
-#if _USE_ERASE
- DWORD scl = clst, ecl = clst, rt[2];
-#endif
-
- if (clst < 2 || clst >= fs->n_fatent) { /* Check range */
- res = FR_INT_ERR;
-
- } else {
- res = FR_OK;
- while (clst < fs->n_fatent) { /* Not a last link? */
- nxt = get_fat(fs, clst); /* Get cluster status */
- if (nxt == 0) break; /* Empty cluster? */
- if (nxt == 1) { res = FR_INT_ERR; break; } /* Internal error? */
- if (nxt == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } /* Disk error? */
- res = put_fat(fs, clst, 0); /* Mark the cluster "empty" */
- if (res != FR_OK) break;
- if (fs->free_clust != 0xFFFFFFFF) { /* Update FSInfo */
- fs->free_clust++;
- fs->fsi_flag = 1;
- }
-#if _USE_ERASE
- if (ecl + 1 == nxt) { /* Is next cluster contiguous? */
- ecl = nxt;
- } else { /* End of contiguous clusters */
- rt[0] = clust2sect(fs, scl); /* Start sector */
- rt[1] = clust2sect(fs, ecl) + fs->csize - 1; /* End sector */
- disk_ioctl(fs->drv, CTRL_ERASE_SECTOR, rt); /* Erase the block */
- scl = ecl = nxt;
- }
-#endif
- clst = nxt; /* Next cluster */
- }
- }
-
- return res;
-}
-#endif
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* FAT handling - Stretch or Create a cluster chain */
-/*-----------------------------------------------------------------------*/
-#if !_FS_READONLY
-static
-DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */
- FATFS *fs, /* File system object */
- DWORD clst /* Cluster# to stretch. 0 means create a new chain. */
-)
-{
- DWORD cs, ncl, scl;
- FRESULT res;
-
-
- if (clst == 0) { /* Create a new chain */
- scl = fs->last_clust; /* Get suggested start point */
- if (!scl || scl >= fs->n_fatent) scl = 1;
- }
- else { /* Stretch the current chain */
- cs = get_fat(fs, clst); /* Check the cluster status */
- if (cs < 2) return 1; /* It is an invalid cluster */
- if (cs < fs->n_fatent) return cs; /* It is already followed by next cluster */
- scl = clst;
- }
-
- ncl = scl; /* Start cluster */
- for (;;) {
- ncl++; /* Next cluster */
- if (ncl >= fs->n_fatent) { /* Wrap around */
- ncl = 2;
- if (ncl > scl) return 0; /* No free cluster */
- }
- cs = get_fat(fs, ncl); /* Get the cluster status */
- if (cs == 0) break; /* Found a free cluster */
- if (cs == 0xFFFFFFFF || cs == 1)/* An error occurred */
- return cs;
- if (ncl == scl) return 0; /* No free cluster */
- }
-
- res = put_fat(fs, ncl, 0x0FFFFFFF); /* Mark the new cluster "last link" */
- if (res == FR_OK && clst != 0) {
- res = put_fat(fs, clst, ncl); /* Link it to the previous one if needed */
- }
- if (res == FR_OK) {
- fs->last_clust = ncl; /* Update FSINFO */
- if (fs->free_clust != 0xFFFFFFFF) {
- fs->free_clust--;
- fs->fsi_flag = 1;
- }
- } else {
- ncl = (res == FR_DISK_ERR) ? 0xFFFFFFFF : 1;
- }
-
- return ncl; /* Return new cluster number or error code */
-}
-#endif /* !_FS_READONLY */
-
-
-
-/*-----------------------------------------------------------------------*/
-/* FAT handling - Convert offset into cluster with link map table */
-/*-----------------------------------------------------------------------*/
-
-#if _USE_FASTSEEK
-static
-DWORD clmt_clust ( /* <2:Error, >=2:Cluster number */
- FIL* fp, /* Pointer to the file object */
- DWORD ofs /* File offset to be converted to cluster# */
-)
-{
- DWORD cl, ncl, *tbl;
-
-
- tbl = fp->cltbl + 1; /* Top of CLMT */
- cl = ofs / SS(fp->fs) / fp->fs->csize; /* Cluster order from top of the file */
- for (;;) {
- ncl = *tbl++; /* Number of cluters in the fragment */
- if (!ncl) return 0; /* End of table? (error) */
- if (cl < ncl) break; /* In this fragment? */
- cl -= ncl; tbl++; /* Next fragment */
- }
- return cl + *tbl; /* Return the cluster number */
-}
-#endif /* _USE_FASTSEEK */
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Directory handling - Set directory index */
-/*-----------------------------------------------------------------------*/
-
-static
-FRESULT dir_sdi (
- DIR *dj, /* Pointer to directory object */
- WORD idx /* Index of directory table */
-)
-{
- DWORD clst;
- WORD ic;
-
-
- dj->index = idx;
- clst = dj->sclust;
- if (clst == 1 || clst >= dj->fs->n_fatent) /* Check start cluster range */
- return FR_INT_ERR;
- if (!clst && dj->fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */
- clst = dj->fs->dirbase;
-
- if (clst == 0) { /* Static table (root-dir in FAT12/16) */
- dj->clust = clst;
- if (idx >= dj->fs->n_rootdir) /* Index is out of range */
- return FR_INT_ERR;
- dj->sect = dj->fs->dirbase + idx / (SS(dj->fs) / SZ_DIR); /* Sector# */
- }
- else { /* Dynamic table (sub-dirs or root-dir in FAT32) */
- ic = SS(dj->fs) / SZ_DIR * dj->fs->csize; /* Entries per cluster */
- while (idx >= ic) { /* Follow cluster chain */
- clst = get_fat(dj->fs, clst); /* Get next cluster */
- if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */
- if (clst < 2 || clst >= dj->fs->n_fatent) /* Reached to end of table or int error */
- return FR_INT_ERR;
- idx -= ic;
- }
- dj->clust = clst;
- dj->sect = clust2sect(dj->fs, clst) + idx / (SS(dj->fs) / SZ_DIR); /* Sector# */
- }
-
- dj->dir = dj->fs->win + (idx % (SS(dj->fs) / SZ_DIR)) * SZ_DIR; /* Ptr to the entry in the sector */
-
- return FR_OK; /* Seek succeeded */
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Directory handling - Move directory table index next */
-/*-----------------------------------------------------------------------*/
-
-static
-FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:EOT and could not stretch */
- DIR *dj, /* Pointer to directory object */
- int stretch /* 0: Do not stretch table, 1: Stretch table if needed */
-)
-{
- DWORD clst;
- WORD i;
-
-
- stretch = stretch; /* To suppress warning on read-only cfg. */
- i = dj->index + 1;
- if (!i || !dj->sect) /* Report EOT when index has reached 65535 */
- return FR_NO_FILE;
-
- if (!(i % (SS(dj->fs) / SZ_DIR))) { /* Sector changed? */
- dj->sect++; /* Next sector */
-
- if (dj->clust == 0) { /* Static table */
- if (i >= dj->fs->n_rootdir) /* Report EOT when end of table */
- return FR_NO_FILE;
- }
- else { /* Dynamic table */
- if (((i / (SS(dj->fs) / SZ_DIR)) & (dj->fs->csize - 1)) == 0) { /* Cluster changed? */
- clst = get_fat(dj->fs, dj->clust); /* Get next cluster */
- if (clst <= 1) return FR_INT_ERR;
- if (clst == 0xFFFFFFFF) return FR_DISK_ERR;
- if (clst >= dj->fs->n_fatent) { /* When it reached end of dynamic table */
-#if !_FS_READONLY
- BYTE c;
- if (!stretch) return FR_NO_FILE; /* When do not stretch, report EOT */
- clst = create_chain(dj->fs, dj->clust); /* Stretch cluster chain */
- if (clst == 0) return FR_DENIED; /* No free cluster */
- if (clst == 1) return FR_INT_ERR;
- if (clst == 0xFFFFFFFF) return FR_DISK_ERR;
- /* Clean-up stretched table */
- if (move_window(dj->fs, 0)) return FR_DISK_ERR; /* Flush active window */
- mem_set(dj->fs->win, 0, SS(dj->fs)); /* Clear window buffer */
- dj->fs->winsect = clust2sect(dj->fs, clst); /* Cluster start sector */
- for (c = 0; c < dj->fs->csize; c++) { /* Fill the new cluster with 0 */
- dj->fs->wflag = 1;
- if (move_window(dj->fs, 0)) return FR_DISK_ERR;
- dj->fs->winsect++;
- }
- dj->fs->winsect -= c; /* Rewind window address */
-#else
- return FR_NO_FILE; /* Report EOT */
-#endif
- }
- dj->clust = clst; /* Initialize data for new cluster */
- dj->sect = clust2sect(dj->fs, clst);
- }
- }
- }
-
- dj->index = i;
- dj->dir = dj->fs->win + (i % (SS(dj->fs) / SZ_DIR)) * SZ_DIR;
-
- return FR_OK;
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Directory handling - Load/Store start cluster number */
-/*-----------------------------------------------------------------------*/
-
-static
-DWORD ld_clust (
- FATFS *fs, /* Pointer to the fs object */
- BYTE *dir /* Pointer to the directory entry */
-)
-{
- DWORD cl;
-
- cl = LD_WORD(dir+DIR_FstClusLO);
- if (fs->fs_type == FS_FAT32)
- cl |= (DWORD)LD_WORD(dir+DIR_FstClusHI) << 16;
-
- return cl;
-}
-
-
-#if !_FS_READONLY
-static
-void st_clust (
- BYTE *dir, /* Pointer to the directory entry */
- DWORD cl /* Value to be set */
-)
-{
- ST_WORD(dir+DIR_FstClusLO, cl);
- ST_WORD(dir+DIR_FstClusHI, cl >> 16);
-}
-#endif
-
-
-
-/*-----------------------------------------------------------------------*/
-/* LFN handling - Test/Pick/Fit an LFN segment from/to directory entry */
-/*-----------------------------------------------------------------------*/
-#if _USE_LFN
-static
-const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30}; /* Offset of LFN chars in the directory entry */
-
-
-static
-int cmp_lfn ( /* 1:Matched, 0:Not matched */
- WCHAR *lfnbuf, /* Pointer to the LFN to be compared */
- BYTE *dir /* Pointer to the directory entry containing a part of LFN */
-)
-{
- UINT i, s;
- WCHAR wc, uc;
-
-
- i = ((dir[LDIR_Ord] & ~LLE) - 1) * 13; /* Get offset in the LFN buffer */
- s = 0; wc = 1;
- do {
- uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */
- if (wc) { /* Last char has not been processed */
- wc = ff_wtoupper(uc); /* Convert it to upper case */
- if (i >= _MAX_LFN || wc != ff_wtoupper(lfnbuf[i++])) /* Compare it */
- return 0; /* Not matched */
- } else {
- if (uc != 0xFFFF) return 0; /* Check filler */
- }
- } while (++s < 13); /* Repeat until all chars in the entry are checked */
-
- if ((dir[LDIR_Ord] & LLE) && wc && lfnbuf[i]) /* Last segment matched but different length */
- return 0;
-
- return 1; /* The part of LFN matched */
-}
-
-
-
-static
-int pick_lfn ( /* 1:Succeeded, 0:Buffer overflow */
- WCHAR *lfnbuf, /* Pointer to the Unicode-LFN buffer */
- BYTE *dir /* Pointer to the directory entry */
-)
-{
- UINT i, s;
- WCHAR wc, uc;
-
-
- i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13; /* Offset in the LFN buffer */
-
- s = 0; wc = 1;
- do {
- uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */
- if (wc) { /* Last char has not been processed */
- if (i >= _MAX_LFN) return 0; /* Buffer overflow? */
- lfnbuf[i++] = wc = uc; /* Store it */
- } else {
- if (uc != 0xFFFF) return 0; /* Check filler */
- }
- } while (++s < 13); /* Read all character in the entry */
-
- if (dir[LDIR_Ord] & LLE) { /* Put terminator if it is the last LFN part */
- if (i >= _MAX_LFN) return 0; /* Buffer overflow? */
- lfnbuf[i] = 0;
- }
-
- return 1;
-}
-
-
-#if !_FS_READONLY
-static
-void fit_lfn (
- const WCHAR *lfnbuf, /* Pointer to the LFN buffer */
- BYTE *dir, /* Pointer to the directory entry */
- BYTE ord, /* LFN order (1-20) */
- BYTE sum /* SFN sum */
-)
-{
- UINT i, s;
- WCHAR wc;
-
-
- dir[LDIR_Chksum] = sum; /* Set check sum */
- dir[LDIR_Attr] = AM_LFN; /* Set attribute. LFN entry */
- dir[LDIR_Type] = 0;
- ST_WORD(dir+LDIR_FstClusLO, 0);
-
- i = (ord - 1) * 13; /* Get offset in the LFN buffer */
- s = wc = 0;
- do {
- if (wc != 0xFFFF) wc = lfnbuf[i++]; /* Get an effective char */
- ST_WORD(dir+LfnOfs[s], wc); /* Put it */
- if (!wc) wc = 0xFFFF; /* Padding chars following last char */
- } while (++s < 13);
- if (wc == 0xFFFF || !lfnbuf[i]) ord |= LLE; /* Bottom LFN part is the start of LFN sequence */
- dir[LDIR_Ord] = ord; /* Set the LFN order */
-}
-
-#endif
-#endif
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Create numbered name */
-/*-----------------------------------------------------------------------*/
-#if _USE_LFN
-void gen_numname (
- BYTE *dst, /* Pointer to generated SFN */
- const BYTE *src, /* Pointer to source SFN to be modified */
- const WCHAR *lfn, /* Pointer to LFN */
- WORD seq /* Sequence number */
-)
-{
- BYTE ns[8], c;
- UINT i, j;
-
-
- mem_cpy(dst, src, 11);
-
- if (seq > 5) { /* On many collisions, generate a hash number instead of sequential number */
- do seq = (seq >> 1) + (seq << 15) + (WORD)*lfn++; while (*lfn);
- }
-
- /* itoa (hexdecimal) */
- i = 7;
- do {
- c = (seq % 16) + '0';
- if (c > '9') c += 7;
- ns[i--] = c;
- seq /= 16;
- } while (seq);
- ns[i] = '~';
-
- /* Append the number */
- for (j = 0; j < i && dst[j] != ' '; j++) {
- if (IsDBCS1(dst[j])) {
- if (j == i - 1) break;
- j++;
- }
- }
- do {
- dst[j++] = (i < 8) ? ns[i++] : ' ';
- } while (j < 8);
-}
-#endif
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Calculate sum of an SFN */
-/*-----------------------------------------------------------------------*/
-#if _USE_LFN
-static
-BYTE sum_sfn (
- const BYTE *dir /* Ptr to directory entry */
-)
-{
- BYTE sum = 0;
- UINT n = 11;
-
- do sum = (sum >> 1) + (sum << 7) + *dir++; while (--n);
- return sum;
-}
-#endif
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Directory handling - Find an object in the directory */
-/*-----------------------------------------------------------------------*/
-
-static
-FRESULT dir_find (
- DIR *dj /* Pointer to the directory object linked to the file name */
-)
-{
- FRESULT res;
- BYTE c, *dir;
-#if _USE_LFN
- BYTE a, ord, sum;
-#endif
-
- res = dir_sdi(dj, 0); /* Rewind directory object */
- if (res != FR_OK) return res;
-
-#if _USE_LFN
- ord = sum = 0xFF;
-#endif
- do {
- res = move_window(dj->fs, dj->sect);
- if (res != FR_OK) break;
- dir = dj->dir; /* Ptr to the directory entry of current index */
- c = dir[DIR_Name];
- if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */
-#if _USE_LFN /* LFN configuration */
- a = dir[DIR_Attr] & AM_MASK;
- if (c == DDE || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */
- ord = 0xFF;
- } else {
- if (a == AM_LFN) { /* An LFN entry is found */
- if (dj->lfn) {
- if (c & LLE) { /* Is it start of LFN sequence? */
- sum = dir[LDIR_Chksum];
- c &= ~LLE; ord = c; /* LFN start order */
- dj->lfn_idx = dj->index;
- }
- /* Check validity of the LFN entry and compare it with given name */
- ord = (c == ord && sum == dir[LDIR_Chksum] && cmp_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF;
- }
- } else { /* An SFN entry is found */
- if (!ord && sum == sum_sfn(dir)) break; /* LFN matched? */
- ord = 0xFF; dj->lfn_idx = 0xFFFF; /* Reset LFN sequence */
- if (!(dj->fn[NS] & NS_LOSS) && !mem_cmp(dir, dj->fn, 11)) break; /* SFN matched? */
- }
- }
-#else /* Non LFN configuration */
- if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */
- break;
-#endif
- res = dir_next(dj, 0); /* Next entry */
- } while (res == FR_OK);
-
- return res;
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Read an object from the directory */
-/*-----------------------------------------------------------------------*/
-#if _FS_MINIMIZE <= 1
-static
-FRESULT dir_read (
- DIR *dj /* Pointer to the directory object that pointing the entry to be read */
-)
-{
- FRESULT res;
- BYTE c, *dir;
-#if _USE_LFN
- BYTE a, ord = 0xFF, sum = 0xFF;
-#endif
-
- res = FR_NO_FILE;
- while (dj->sect) {
- res = move_window(dj->fs, dj->sect);
- if (res != FR_OK) break;
- dir = dj->dir; /* Ptr to the directory entry of current index */
- c = dir[DIR_Name];
- if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */
-#if _USE_LFN /* LFN configuration */
- a = dir[DIR_Attr] & AM_MASK;
- if (c == DDE || (!_FS_RPATH && c == '.') || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */
- ord = 0xFF;
- } else {
- if (a == AM_LFN) { /* An LFN entry is found */
- if (c & LLE) { /* Is it start of LFN sequence? */
- sum = dir[LDIR_Chksum];
- c &= ~LLE; ord = c;
- dj->lfn_idx = dj->index;
- }
- /* Check LFN validity and capture it */
- ord = (c == ord && sum == dir[LDIR_Chksum] && pick_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF;
- } else { /* An SFN entry is found */
- if (ord || sum != sum_sfn(dir)) /* Is there a valid LFN? */
- dj->lfn_idx = 0xFFFF; /* It has no LFN. */
- break;
- }
- }
-#else /* Non LFN configuration */
- if (c != DDE && (_FS_RPATH || c != '.') && !(dir[DIR_Attr] & AM_VOL)) /* Is it a valid entry? */
- break;
-#endif
- res = dir_next(dj, 0); /* Next entry */
- if (res != FR_OK) break;
- }
-
- if (res != FR_OK) dj->sect = 0;
-
- return res;
-}
-#endif
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Register an object to the directory */
-/*-----------------------------------------------------------------------*/
-#if !_FS_READONLY
-static
-FRESULT dir_register ( /* FR_OK:Successful, FR_DENIED:No free entry or too many SFN collision, FR_DISK_ERR:Disk error */
- DIR *dj /* Target directory with object name to be created */
-)
-{
- FRESULT res;
- BYTE c, *dir;
-#if _USE_LFN /* LFN configuration */
- WORD n, ne, is;
- BYTE sn[12], *fn, sum;
- WCHAR *lfn;
-
-
- fn = dj->fn; lfn = dj->lfn;
- mem_cpy(sn, fn, 12);
-
- if (_FS_RPATH && (sn[NS] & NS_DOT)) /* Cannot create dot entry */
- return FR_INVALID_NAME;
-
- if (sn[NS] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */
- fn[NS] = 0; dj->lfn = 0; /* Find only SFN */
- for (n = 1; n < 100; n++) {
- gen_numname(fn, sn, lfn, n); /* Generate a numbered name */
- res = dir_find(dj); /* Check if the name collides with existing SFN */
- if (res != FR_OK) break;
- }
- if (n == 100) return FR_DENIED; /* Abort if too many collisions */
- if (res != FR_NO_FILE) return res; /* Abort if the result is other than 'not collided' */
- fn[NS] = sn[NS]; dj->lfn = lfn;
- }
-
- if (sn[NS] & NS_LFN) { /* When LFN is to be created, reserve an SFN + LFN entries. */
- for (ne = 0; lfn[ne]; ne++) ;
- ne = (ne + 25) / 13;
- } else { /* Otherwise reserve only an SFN entry. */
- ne = 1;
- }
-
- /* Reserve contiguous entries */
- res = dir_sdi(dj, 0);
- if (res != FR_OK) return res;
- n = is = 0;
- do {
- res = move_window(dj->fs, dj->sect);
- if (res != FR_OK) break;
- c = *dj->dir; /* Check the entry status */
- if (c == DDE || c == 0) { /* Is it a blank entry? */
- if (n == 0) is = dj->index; /* First index of the contiguous entry */
- if (++n == ne) break; /* A contiguous entry that required count is found */
- } else {
- n = 0; /* Not a blank entry. Restart to search */
- }
- res = dir_next(dj, 1); /* Next entry with table stretch */
- } while (res == FR_OK);
-
- if (res == FR_OK && ne > 1) { /* Initialize LFN entry if needed */
- res = dir_sdi(dj, is);
- if (res == FR_OK) {
- sum = sum_sfn(dj->fn); /* Sum of the SFN tied to the LFN */
- ne--;
- do { /* Store LFN entries in bottom first */
- res = move_window(dj->fs, dj->sect);
- if (res != FR_OK) break;
- fit_lfn(dj->lfn, dj->dir, (BYTE)ne, sum);
- dj->fs->wflag = 1;
- res = dir_next(dj, 0); /* Next entry */
- } while (res == FR_OK && --ne);
- }
- }
-
-#else /* Non LFN configuration */
- res = dir_sdi(dj, 0);
- if (res == FR_OK) {
- do { /* Find a blank entry for the SFN */
- res = move_window(dj->fs, dj->sect);
- if (res != FR_OK) break;
- c = *dj->dir;
- if (c == DDE || c == 0) break; /* Is it a blank entry? */
- res = dir_next(dj, 1); /* Next entry with table stretch */
- } while (res == FR_OK);
- }
-#endif
-
- if (res == FR_OK) { /* Initialize the SFN entry */
- res = move_window(dj->fs, dj->sect);
- if (res == FR_OK) {
- dir = dj->dir;
- mem_set(dir, 0, SZ_DIR); /* Clean the entry */
- mem_cpy(dir, dj->fn, 11); /* Put SFN */
-#if _USE_LFN
- dir[DIR_NTres] = *(dj->fn+NS) & (NS_BODY | NS_EXT); /* Put NT flag */
-#endif
- dj->fs->wflag = 1;
- }
- }
-
- return res;
-}
-#endif /* !_FS_READONLY */
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Remove an object from the directory */
-/*-----------------------------------------------------------------------*/
-#if !_FS_READONLY && !_FS_MINIMIZE
-static
-FRESULT dir_remove ( /* FR_OK: Successful, FR_DISK_ERR: A disk error */
- DIR *dj /* Directory object pointing the entry to be removed */
-)
-{
- FRESULT res;
-#if _USE_LFN /* LFN configuration */
- WORD i;
-
- i = dj->index; /* SFN index */
- res = dir_sdi(dj, (WORD)((dj->lfn_idx == 0xFFFF) ? i : dj->lfn_idx)); /* Goto the SFN or top of the LFN entries */
- if (res == FR_OK) {
- do {
- res = move_window(dj->fs, dj->sect);
- if (res != FR_OK) break;
- *dj->dir = DDE; /* Mark the entry "deleted" */
- dj->fs->wflag = 1;
- if (dj->index >= i) break; /* When reached SFN, all entries of the object has been deleted. */
- res = dir_next(dj, 0); /* Next entry */
- } while (res == FR_OK);
- if (res == FR_NO_FILE) res = FR_INT_ERR;
- }
-
-#else /* Non LFN configuration */
- res = dir_sdi(dj, dj->index);
- if (res == FR_OK) {
- res = move_window(dj->fs, dj->sect);
- if (res == FR_OK) {
- *dj->dir = DDE; /* Mark the entry "deleted" */
- dj->fs->wflag = 1;
- }
- }
-#endif
-
- return res;
-}
-#endif /* !_FS_READONLY */
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Pick a segment and create the object name in directory form */
-/*-----------------------------------------------------------------------*/
-
-static
-FRESULT create_name (
- DIR *dj, /* Pointer to the directory object */
- const TCHAR **path /* Pointer to pointer to the segment in the path string */
-)
-{
-#ifdef _EXCVT
- static const BYTE excvt[] = _EXCVT; /* Upper conversion table for extended chars */
-#endif
-
-#if _USE_LFN /* LFN configuration */
- BYTE b, cf;
- WCHAR w, *lfn;
- UINT i, ni, si, di;
- const TCHAR *p;
-
- /* Create LFN in Unicode */
- for (p = *path; *p == '/' || *p == '\\'; p++) ; /* Strip duplicated separator */
- lfn = dj->lfn;
- si = di = 0;
- for (;;) {
- w = p[si++]; /* Get a character */
- if (w < ' ' || w == '/' || w == '\\') break; /* Break on end of segment */
- if (di >= _MAX_LFN) /* Reject too long name */
- return FR_INVALID_NAME;
-#if !_LFN_UNICODE
- w &= 0xFF;
- if (IsDBCS1(w)) { /* Check if it is a DBC 1st byte (always false on SBCS cfg) */
- b = (BYTE)p[si++]; /* Get 2nd byte */
- if (!IsDBCS2(b))
- return FR_INVALID_NAME; /* Reject invalid sequence */
- w = (w << 8) + b; /* Create a DBC */
- }
- w = ff_convert(w, 1); /* Convert ANSI/OEM to Unicode */
- if (!w) return FR_INVALID_NAME; /* Reject invalid code */
-#endif
- if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) /* Reject illegal chars for LFN */
- return FR_INVALID_NAME;
- lfn[di++] = w; /* Store the Unicode char */
- }
- *path = &p[si]; /* Return pointer to the next segment */
- cf = (w < ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */
-#if _FS_RPATH
- if ((di == 1 && lfn[di-1] == '.') || /* Is this a dot entry? */
- (di == 2 && lfn[di-1] == '.' && lfn[di-2] == '.')) {
- lfn[di] = 0;
- for (i = 0; i < 11; i++)
- dj->fn[i] = (i < di) ? '.' : ' ';
- dj->fn[i] = cf | NS_DOT; /* This is a dot entry */
- return FR_OK;
- }
-#endif
- while (di) { /* Strip trailing spaces and dots */
- w = lfn[di-1];
- if (w != ' ' && w != '.') break;
- di--;
- }
- if (!di) return FR_INVALID_NAME; /* Reject nul string */
-
- lfn[di] = 0; /* LFN is created */
-
- /* Create SFN in directory form */
- mem_set(dj->fn, ' ', 11);
- for (si = 0; lfn[si] == ' ' || lfn[si] == '.'; si++) ; /* Strip leading spaces and dots */
- if (si) cf |= NS_LOSS | NS_LFN;
- while (di && lfn[di - 1] != '.') di--; /* Find extension (di<=si: no extension) */
-
- b = i = 0; ni = 8;
- for (;;) {
- w = lfn[si++]; /* Get an LFN char */
- if (!w) break; /* Break on end of the LFN */
- if (w == ' ' || (w == '.' && si != di)) { /* Remove spaces and dots */
- cf |= NS_LOSS | NS_LFN; continue;
- }
-
- if (i >= ni || si == di) { /* Extension or end of SFN */
- if (ni == 11) { /* Long extension */
- cf |= NS_LOSS | NS_LFN; break;
- }
- if (si != di) cf |= NS_LOSS | NS_LFN; /* Out of 8.3 format */
- if (si > di) break; /* No extension */
- si = di; i = 8; ni = 11; /* Enter extension section */
- b <<= 2; continue;
- }
-
- if (w >= 0x80) { /* Non ASCII char */
-#ifdef _EXCVT
- w = ff_convert(w, 0); /* Unicode -> OEM code */
- if (w) w = excvt[w - 0x80]; /* Convert extended char to upper (SBCS) */
-#else
- w = ff_convert(ff_wtoupper(w), 0); /* Upper converted Unicode -> OEM code */
-#endif
- cf |= NS_LFN; /* Force create LFN entry */
- }
-
- if (_DF1S && w >= 0x100) { /* Double byte char (always false on SBCS cfg) */
- if (i >= ni - 1) {
- cf |= NS_LOSS | NS_LFN; i = ni; continue;
- }
- dj->fn[i++] = (BYTE)(w >> 8);
- } else { /* Single byte char */
- if (!w || chk_chr("+,;=[]", w)) { /* Replace illegal chars for SFN */
- w = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */
- } else {
- if (IsUpper(w)) { /* ASCII large capital */
- b |= 2;
- } else {
- if (IsLower(w)) { /* ASCII small capital */
- b |= 1; w -= 0x20;
- }
- }
- }
- }
- dj->fn[i++] = (BYTE)w;
- }
-
- if (dj->fn[0] == DDE) dj->fn[0] = NDDE; /* If the first char collides with deleted mark, replace it with 0x05 */
-
- if (ni == 8) b <<= 2;
- if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) /* Create LFN entry when there are composite capitals */
- cf |= NS_LFN;
- if (!(cf & NS_LFN)) { /* When LFN is in 8.3 format without extended char, NT flags are created */
- if ((b & 0x03) == 0x01) cf |= NS_EXT; /* NT flag (Extension has only small capital) */
- if ((b & 0x0C) == 0x04) cf |= NS_BODY; /* NT flag (Filename has only small capital) */
- }
-
- dj->fn[NS] = cf; /* SFN is created */
-
- return FR_OK;
-
-
-#else /* Non-LFN configuration */
- BYTE b, c, d, *sfn;
- UINT ni, si, i;
- const char *p;
-
- /* Create file name in directory form */
- for (p = *path; *p == '/' || *p == '\\'; p++) ; /* Strip duplicated separator */
- sfn = dj->fn;
- mem_set(sfn, ' ', 11);
- si = i = b = 0; ni = 8;
-#if _FS_RPATH
- if (p[si] == '.') { /* Is this a dot entry? */
- for (;;) {
- c = (BYTE)p[si++];
- if (c != '.' || si >= 3) break;
- sfn[i++] = c;
- }
- if (c != '/' && c != '\\' && c > ' ') return FR_INVALID_NAME;
- *path = &p[si]; /* Return pointer to the next segment */
- sfn[NS] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT; /* Set last segment flag if end of path */
- return FR_OK;
- }
-#endif
- for (;;) {
- c = (BYTE)p[si++];
- if (c <= ' ' || c == '/' || c == '\\') break; /* Break on end of segment */
- if (c == '.' || i >= ni) {
- if (ni != 8 || c != '.') return FR_INVALID_NAME;
- i = 8; ni = 11;
- b <<= 2; continue;
- }
- if (c >= 0x80) { /* Extended char? */
- b |= 3; /* Eliminate NT flag */
-#ifdef _EXCVT
- c = excvt[c - 0x80]; /* Upper conversion (SBCS) */
-#else
-#if !_DF1S /* ASCII only cfg */
- return FR_INVALID_NAME;
-#endif
-#endif
- }
- if (IsDBCS1(c)) { /* Check if it is a DBC 1st byte (always false on SBCS cfg) */
- d = (BYTE)p[si++]; /* Get 2nd byte */
- if (!IsDBCS2(d) || i >= ni - 1) /* Reject invalid DBC */
- return FR_INVALID_NAME;
- sfn[i++] = c;
- sfn[i++] = d;
- } else { /* Single byte code */
- if (chk_chr("\"*+,:;<=>\?[]|\x7F", c)) /* Reject illegal chrs for SFN */
- return FR_INVALID_NAME;
- if (IsUpper(c)) { /* ASCII large capital? */
- b |= 2;
- } else {
- if (IsLower(c)) { /* ASCII small capital? */
- b |= 1; c -= 0x20;
- }
- }
- sfn[i++] = c;
- }
- }
- *path = &p[si]; /* Return pointer to the next segment */
- c = (c <= ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */
-
- if (!i) return FR_INVALID_NAME; /* Reject nul string */
- if (sfn[0] == DDE) sfn[0] = NDDE; /* When first char collides with DDE, replace it with 0x05 */
-
- if (ni == 8) b <<= 2;
- if ((b & 0x03) == 0x01) c |= NS_EXT; /* NT flag (Name extension has only small capital) */
- if ((b & 0x0C) == 0x04) c |= NS_BODY; /* NT flag (Name body has only small capital) */
-
- sfn[NS] = c; /* Store NT flag, File name is created */
-
- return FR_OK;
-#endif
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Get file information from directory entry */
-/*-----------------------------------------------------------------------*/
-#if _FS_MINIMIZE <= 1
-static
-void get_fileinfo ( /* No return code */
- DIR *dj, /* Pointer to the directory object */
- FILINFO *fno /* Pointer to the file information to be filled */
-)
-{
- UINT i;
- BYTE nt, *dir;
- TCHAR *p, c;
-
-
- p = fno->fname;
- if (dj->sect) {
- dir = dj->dir;
- nt = dir[DIR_NTres]; /* NT flag */
- for (i = 0; i < 8; i++) { /* Copy name body */
- c = dir[i];
- if (c == ' ') break;
- if (c == NDDE) c = (TCHAR)DDE;
- if (_USE_LFN && (nt & NS_BODY) && IsUpper(c)) c += 0x20;
-#if _LFN_UNICODE
- if (IsDBCS1(c) && i < 7 && IsDBCS2(dir[i+1]))
- c = (c << 8) | dir[++i];
- c = ff_convert(c, 1);
- if (!c) c = '?';
-#endif
- *p++ = c;
- }
- if (dir[8] != ' ') { /* Copy name extension */
- *p++ = '.';
- for (i = 8; i < 11; i++) {
- c = dir[i];
- if (c == ' ') break;
- if (_USE_LFN && (nt & NS_EXT) && IsUpper(c)) c += 0x20;
-#if _LFN_UNICODE
- if (IsDBCS1(c) && i < 10 && IsDBCS2(dir[i+1]))
- c = (c << 8) | dir[++i];
- c = ff_convert(c, 1);
- if (!c) c = '?';
-#endif
- *p++ = c;
- }
- }
- fno->fattrib = dir[DIR_Attr]; /* Attribute */
- fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */
- fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */
- fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */
- }
- *p = 0; /* Terminate SFN str by a \0 */
-
-#if _USE_LFN
- if (fno->lfname && fno->lfsize) {
- TCHAR *tp = fno->lfname;
- WCHAR w, *lfn;
-
- i = 0;
- if (dj->sect && dj->lfn_idx != 0xFFFF) {/* Get LFN if available */
- lfn = dj->lfn;
- while ((w = *lfn++) != 0) { /* Get an LFN char */
-#if !_LFN_UNICODE
- w = ff_convert(w, 0); /* Unicode -> OEM conversion */
- if (!w) { i = 0; break; } /* Could not convert, no LFN */
- if (_DF1S && w >= 0x100) /* Put 1st byte if it is a DBC (always false on SBCS cfg) */
- tp[i++] = (TCHAR)(w >> 8);
-#endif
- if (i >= fno->lfsize - 1) { i = 0; break; } /* Buffer overflow, no LFN */
- tp[i++] = (TCHAR)w;
- }
- }
- tp[i] = 0; /* Terminate the LFN str by a \0 */
- }
-#endif
-}
-#endif /* _FS_MINIMIZE <= 1 */
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Follow a file path */
-/*-----------------------------------------------------------------------*/
-
-static
-FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */
- DIR *dj, /* Directory object to return last directory and found object */
- const TCHAR *path /* Full-path string to find a file or directory */
-)
-{
- FRESULT res;
- BYTE *dir, ns;
-
-
-#if _FS_RPATH
- if (*path == '/' || *path == '\\') { /* There is a heading separator */
- path++; dj->sclust = 0; /* Strip it and start from the root dir */
- } else { /* No heading separator */
- dj->sclust = dj->fs->cdir; /* Start from the current dir */
- }
-#else
- if (*path == '/' || *path == '\\') /* Strip heading separator if exist */
- path++;
- dj->sclust = 0; /* Start from the root dir */
-#endif
-
- if ((UINT)*path < ' ') { /* Nul path means the start directory itself */
- res = dir_sdi(dj, 0);
- dj->dir = 0;
- } else { /* Follow path */
- for (;;) {
- res = create_name(dj, &path); /* Get a segment */
- if (res != FR_OK) break;
- res = dir_find(dj); /* Find it */
- ns = *(dj->fn+NS);
- if (res != FR_OK) { /* Failed to find the object */
- if (res != FR_NO_FILE) break; /* Abort if any hard error occurred */
- /* Object not found */
- if (_FS_RPATH && (ns & NS_DOT)) { /* If dot entry is not exit */
- dj->sclust = 0; dj->dir = 0; /* It is the root dir */
- res = FR_OK;
- if (!(ns & NS_LAST)) continue;
- } else { /* Could not find the object */
- if (!(ns & NS_LAST)) res = FR_NO_PATH;
- }
- break;
- }
- if (ns & NS_LAST) break; /* Last segment match. Function completed. */
- dir = dj->dir; /* There is next segment. Follow the sub directory */
- if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */
- res = FR_NO_PATH; break;
- }
- dj->sclust = ld_clust(dj->fs, dir);
- }
- }
-
- return res;
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Load a sector and check if it is an FAT Volume Boot Record */
-/*-----------------------------------------------------------------------*/
-
-static
-BYTE check_fs ( /* 0:FAT-VBR, 1:Any BR but not FAT, 2:Not a BR, 3:Disk error */
- FATFS *fs, /* File system object */
- DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */
-)
-{
- if (disk_read(fs->drv, fs->win, sect, 1) != RES_OK) /* Load boot record */
- return 3;
- if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55) /* Check record signature (always placed at offset 510 even if the sector size is >512) */
- return 2;
-
- if ((LD_DWORD(&fs->win[BS_FilSysType]) & 0xFFFFFF) == 0x544146) /* Check "FAT" string */
- return 0;
- if ((LD_DWORD(&fs->win[BS_FilSysType32]) & 0xFFFFFF) == 0x544146)
- return 0;
-
- return 1;
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Check if the file system object is valid or not */
-/*-----------------------------------------------------------------------*/
-
-static
-FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occurred */
- const TCHAR **path, /* Pointer to pointer to the path name (drive number) */
- FATFS **rfs, /* Pointer to pointer to the found file system object */
- BYTE wmode /* !=0: Check write protection for write access */
-)
-{
- BYTE fmt, b, pi, *tbl;
- UINT vol;
- DSTATUS stat;
- DWORD bsect, fasize, tsect, sysect, nclst, szbfat;
- WORD nrsv;
- const TCHAR *p = *path;
- FATFS *fs;
-
-
- /* Get logical drive number from the path name */
- vol = p[0] - '0'; /* Is there a drive number? */
- if (vol <= 9 && p[1] == ':') { /* Found a drive number, get and strip it */
- p += 2; *path = p; /* Return pointer to the path name */
- } else { /* No drive number is given */
-#if _FS_RPATH
- vol = CurrVol; /* Use current drive */
-#else
- vol = 0; /* Use drive 0 */
-#endif
- }
-
- /* Check if the file system object is valid or not */
- *rfs = 0;
- if (vol >= _VOLUMES) /* Is the drive number valid? */
- return FR_INVALID_DRIVE;
- fs = FatFs[vol]; /* Get corresponding file system object */
- if (!fs) return FR_NOT_ENABLED; /* Is the file system object available? */
-
- ENTER_FF(fs); /* Lock file system */
-
- *rfs = fs; /* Return pointer to the corresponding file system object */
- if (fs->fs_type) { /* If the volume has been mounted */
- stat = disk_status(fs->drv);
- if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized (has not been changed), */
- if (!_FS_READONLY && wmode && (stat & STA_PROTECT)) /* Check write protection if needed */
- return FR_WRITE_PROTECTED;
- return FR_OK; /* The file system object is valid */
- }
- }
-
- /* The file system object is not valid. */
- /* Following code attempts to mount the volume. (analyze BPB and initialize the fs object) */
-
- fs->fs_type = 0; /* Clear the file system object */
- fs->drv = LD2PD(vol); /* Bind the logical drive and a physical drive */
- stat = disk_initialize(fs->drv); /* Initialize the physical drive */
- if (stat & STA_NOINIT) /* Check if the initialization succeeded */
- return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */
- if (!_FS_READONLY && wmode && (stat & STA_PROTECT)) /* Check disk write protection if needed */
- return FR_WRITE_PROTECTED;
-#if _MAX_SS != 512 /* Get disk sector size (variable sector size cfg only) */
- if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &fs->ssize) != RES_OK)
- return FR_DISK_ERR;
-#endif
- /* Search FAT partition on the drive. Supports only generic partitions, FDISK and SFD. */
- fmt = check_fs(fs, bsect = 0); /* Load sector 0 and check if it is an FAT-VBR (in SFD) */
- if (LD2PT(vol) && !fmt) fmt = 1; /* Force non-SFD if the volume is forced partition */
- if (fmt == 1) { /* Not an FAT-VBR, the physical drive can be partitioned */
- /* Check the partition listed in the partition table */
- pi = LD2PT(vol);
- if (pi) pi--;
- tbl = &fs->win[MBR_Table + pi * SZ_PTE];/* Partition table */
- if (tbl[4]) { /* Is the partition existing? */
- bsect = LD_DWORD(&tbl[8]); /* Partition offset in LBA */
- fmt = check_fs(fs, bsect); /* Check the partition */
- }
- }
- if (fmt == 3) return FR_DISK_ERR;
- if (fmt) return FR_NO_FILESYSTEM; /* No FAT volume is found */
-
- /* An FAT volume is found. Following code initializes the file system object */
-
- if (LD_WORD(fs->win+BPB_BytsPerSec) != SS(fs)) /* (BPB_BytsPerSec must be equal to the physical sector size) */
- return FR_NO_FILESYSTEM;
-
- fasize = LD_WORD(fs->win+BPB_FATSz16); /* Number of sectors per FAT */
- if (!fasize) fasize = LD_DWORD(fs->win+BPB_FATSz32);
- fs->fsize = fasize;
-
- fs->n_fats = b = fs->win[BPB_NumFATs]; /* Number of FAT copies */
- if (b != 1 && b != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */
- fasize *= b; /* Number of sectors for FAT area */
-
- fs->csize = b = fs->win[BPB_SecPerClus]; /* Number of sectors per cluster */
- if (!b || (b & (b - 1))) return FR_NO_FILESYSTEM; /* (Must be power of 2) */
-
- fs->n_rootdir = LD_WORD(fs->win+BPB_RootEntCnt); /* Number of root directory entries */
- if (fs->n_rootdir % (SS(fs) / SZ_DIR)) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be sector aligned) */
-
- tsect = LD_WORD(fs->win+BPB_TotSec16); /* Number of sectors on the volume */
- if (!tsect) tsect = LD_DWORD(fs->win+BPB_TotSec32);
-
- nrsv = LD_WORD(fs->win+BPB_RsvdSecCnt); /* Number of reserved sectors */
- if (!nrsv) return FR_NO_FILESYSTEM; /* (BPB_RsvdSecCnt must not be 0) */
-
- /* Determine the FAT sub type */
- sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZ_DIR); /* RSV+FAT+DIR */
- if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */
- nclst = (tsect - sysect) / fs->csize; /* Number of clusters */
- if (!nclst) return FR_NO_FILESYSTEM; /* (Invalid volume size) */
- fmt = FS_FAT12;
- if (nclst >= MIN_FAT16) fmt = FS_FAT16;
- if (nclst >= MIN_FAT32) fmt = FS_FAT32;
-
- /* Boundaries and Limits */
- fs->n_fatent = nclst + 2; /* Number of FAT entries */
- fs->database = bsect + sysect; /* Data start sector */
- fs->fatbase = bsect + nrsv; /* FAT start sector */
- if (fmt == FS_FAT32) {
- if (fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */
- fs->dirbase = LD_DWORD(fs->win+BPB_RootClus); /* Root directory start cluster */
- szbfat = fs->n_fatent * 4; /* (Required FAT size) */
- } else {
- if (!fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */
- fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */
- szbfat = (fmt == FS_FAT16) ? /* (Required FAT size) */
- fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1);
- }
- if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) /* (BPB_FATSz must not be less than required) */
- return FR_NO_FILESYSTEM;
-
-#if !_FS_READONLY
- /* Initialize cluster allocation information */
- fs->free_clust = 0xFFFFFFFF;
- fs->last_clust = 0;
-
- /* Get fsinfo if available */
- if (fmt == FS_FAT32) {
- fs->fsi_flag = 0;
- fs->fsi_sector = bsect + LD_WORD(fs->win+BPB_FSInfo);
- if (disk_read(fs->drv, fs->win, fs->fsi_sector, 1) == RES_OK &&
- LD_WORD(fs->win+BS_55AA) == 0xAA55 &&
- LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 &&
- LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) {
- fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free);
- fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count);
- }
- }
-#endif
- fs->fs_type = fmt; /* FAT sub-type */
- fs->id = ++Fsid; /* File system mount ID */
- fs->winsect = 0; /* Invalidate sector cache */
- fs->wflag = 0;
-#if _FS_RPATH
- fs->cdir = 0; /* Current directory (root dir) */
-#endif
-#if _FS_LOCK /* Clear file lock semaphores */
- clear_lock(fs);
-#endif
-
- return FR_OK;
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Check if the file/dir object is valid or not */
-/*-----------------------------------------------------------------------*/
-
-static
-FRESULT validate ( /* FR_OK(0): The object is valid, !=0: Invalid */
- void* obj /* Pointer to the object FIL/DIR to check validity */
-)
-{
- FIL *fil;
-
-
- fil = (FIL*)obj; /* Assuming offset of fs and id in the FIL/DIR is identical */
- if (!fil->fs || !fil->fs->fs_type || fil->fs->id != fil->id)
- return FR_INVALID_OBJECT;
-
- ENTER_FF(fil->fs); /* Lock file system */
-
- if (disk_status(fil->fs->drv) & STA_NOINIT)
- return FR_NOT_READY;
-
- return FR_OK;
-}
-
-
-
-
-/*--------------------------------------------------------------------------
-
- Public Functions
-
---------------------------------------------------------------------------*/
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Mount/Unmount a Logical Drive */
-/*-----------------------------------------------------------------------*/
-
-FRESULT f_mount (
- BYTE vol, /* Logical drive number to be mounted/unmounted */
- FATFS *fs /* Pointer to new file system object (NULL for unmount)*/
-)
-{
- FATFS *rfs;
-
-
- if (vol >= _VOLUMES) /* Check if the drive number is valid */
- return FR_INVALID_DRIVE;
- rfs = FatFs[vol]; /* Get current fs object */
-
- if (rfs) {
-#if _FS_LOCK
- clear_lock(rfs);
-#endif
-#if _FS_REENTRANT /* Discard sync object of the current volume */
- if (!ff_del_syncobj(rfs->sobj)) return FR_INT_ERR;
-#endif
- rfs->fs_type = 0; /* Clear old fs object */
- }
-
- if (fs) {
- fs->fs_type = 0; /* Clear new fs object */
-#if _FS_REENTRANT /* Create sync object for the new volume */
- if (!ff_cre_syncobj(vol, &fs->sobj)) return FR_INT_ERR;
-#endif
- }
- FatFs[vol] = fs; /* Register new fs object */
-
- return FR_OK;
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Open or Create a File */
-/*-----------------------------------------------------------------------*/
-
-FRESULT f_open (
- FIL *fp, /* Pointer to the blank file object */
- const TCHAR *path, /* Pointer to the file name */
- BYTE mode /* Access mode and file open mode flags */
-)
-{
- FRESULT res;
- DIR dj;
- BYTE *dir;
- DEF_NAMEBUF;
-
-
- if (!fp) return FR_INVALID_OBJECT;
- fp->fs = 0; /* Clear file object */
-
-#if !_FS_READONLY
- mode &= FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW;
- res = chk_mounted(&path, &dj.fs, (BYTE)(mode & ~FA_READ));
-#else
- mode &= FA_READ;
- res = chk_mounted(&path, &dj.fs, 0);
-#endif
- if (res == FR_OK) {
- INIT_BUF(dj);
- res = follow_path(&dj, path); /* Follow the file path */
- dir = dj.dir;
-#if !_FS_READONLY /* R/W configuration */
- if (res == FR_OK) {
- if (!dir) /* Current dir itself */
- res = FR_INVALID_NAME;
-#if _FS_LOCK
- else
- res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0);
-#endif
- }
- /* Create or Open a file */
- if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) {
- DWORD dw, cl;
-
- if (res != FR_OK) { /* No file, create new */
- if (res == FR_NO_FILE) /* There is no file to open, create a new entry */
-#if _FS_LOCK
- res = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES;
-#else
- res = dir_register(&dj);
-#endif
- mode |= FA_CREATE_ALWAYS; /* File is created */
- dir = dj.dir; /* New entry */
- }
- else { /* Any object is already existing */
- if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) { /* Cannot overwrite it (R/O or DIR) */
- res = FR_DENIED;
- } else {
- if (mode & FA_CREATE_NEW) /* Cannot create as new file */
- res = FR_EXIST;
- }
- }
- if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */
- dw = get_fattime(); /* Created time */
- ST_DWORD(dir+DIR_CrtTime, dw);
- dir[DIR_Attr] = 0; /* Reset attribute */
- ST_DWORD(dir+DIR_FileSize, 0); /* size = 0 */
- cl = ld_clust(dj.fs, dir); /* Get start cluster */
- st_clust(dir, 0); /* cluster = 0 */
- dj.fs->wflag = 1;
- if (cl) { /* Remove the cluster chain if exist */
- dw = dj.fs->winsect;
- res = remove_chain(dj.fs, cl);
- if (res == FR_OK) {
- dj.fs->last_clust = cl - 1; /* Reuse the cluster hole */
- res = move_window(dj.fs, dw);
- }
- }
- }
- }
- else { /* Open an existing file */
- if (res == FR_OK) { /* Follow succeeded */
- if (dir[DIR_Attr] & AM_DIR) { /* It is a directory */
- res = FR_NO_FILE;
- } else {
- if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */
- res = FR_DENIED;
- }
- }
- }
- if (res == FR_OK) {
- if (mode & FA_CREATE_ALWAYS) /* Set file change flag if created or overwritten */
- mode |= FA__WRITTEN;
- fp->dir_sect = dj.fs->winsect; /* Pointer to the directory entry */
- fp->dir_ptr = dir;
-#if _FS_LOCK
- fp->lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0);
- if (!fp->lockid) res = FR_INT_ERR;
-#endif
- }
-
-#else /* R/O configuration */
- if (res == FR_OK) { /* Follow succeeded */
- dir = dj.dir;
- if (!dir) { /* Current dir itself */
- res = FR_INVALID_NAME;
- } else {
- if (dir[DIR_Attr] & AM_DIR) /* It is a directory */
- res = FR_NO_FILE;
- }
- }
-#endif
- FREE_BUF();
-
- if (res == FR_OK) {
- fp->flag = mode; /* File access mode */
- fp->sclust = ld_clust(dj.fs, dir); /* File start cluster */
- fp->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */
- fp->fptr = 0; /* File pointer */
- fp->dsect = 0;
-#if _USE_FASTSEEK
- fp->cltbl = 0; /* Normal seek mode */
-#endif
- fp->fs = dj.fs; fp->id = dj.fs->id; /* Validate file object */
- }
- }
-
- LEAVE_FF(dj.fs, res);
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Read File */
-/*-----------------------------------------------------------------------*/
-
-FRESULT f_read (
- FIL *fp, /* Pointer to the file object */
- void *buff, /* Pointer to data buffer */
- UINT btr, /* Number of bytes to read */
- UINT *br /* Pointer to number of bytes read */
-)
-{
- FRESULT res;
- DWORD clst, sect, remain;
- UINT rcnt, cc;
- BYTE csect, *rbuff = buff;
-
-
- *br = 0; /* Clear read byte counter */
-
- res = validate(fp); /* Check validity */
- if (res != FR_OK) LEAVE_FF(fp->fs, res);
- if (fp->flag & FA__ERROR) /* Aborted file? */
- LEAVE_FF(fp->fs, FR_INT_ERR);
- if (!(fp->flag & FA_READ)) /* Check access mode */
- LEAVE_FF(fp->fs, FR_DENIED);
- remain = fp->fsize - fp->fptr;
- if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */
-
- for ( ; btr; /* Repeat until all data read */
- rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) {
- if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */
- csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */
- if (!csect) { /* On the cluster boundary? */
- if (fp->fptr == 0) { /* On the top of the file? */
- clst = fp->sclust; /* Follow from the origin */
- } else { /* Middle or end of the file */
-#if _USE_FASTSEEK
- if (fp->cltbl)
- clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
- else
-#endif
- clst = get_fat(fp->fs, fp->clust); /* Follow cluster chain on the FAT */
- }
- if (clst < 2) ABORT(fp->fs, FR_INT_ERR);
- if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
- fp->clust = clst; /* Update current cluster */
- }
- sect = clust2sect(fp->fs, fp->clust); /* Get current sector */
- if (!sect) ABORT(fp->fs, FR_INT_ERR);
- sect += csect;
- cc = btr / SS(fp->fs); /* When remaining bytes >= sector size, */
- if (cc) { /* Read maximum contiguous sectors directly */
- if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */
- cc = fp->fs->csize - csect;
- if (disk_read(fp->fs->drv, rbuff, sect, (BYTE)cc) != RES_OK)
- ABORT(fp->fs, FR_DISK_ERR);
-#if !_FS_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */
-#if _FS_TINY
- if (fp->fs->wflag && fp->fs->winsect - sect < cc)
- mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs));
-#else
- if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc)
- mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs));
-#endif
-#endif
- rcnt = SS(fp->fs) * cc; /* Number of bytes transferred */
- continue;
- }
-#if !_FS_TINY
- if (fp->dsect != sect) { /* Load data sector if not in cache */
-#if !_FS_READONLY
- if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */
- if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
- ABORT(fp->fs, FR_DISK_ERR);
- fp->flag &= ~FA__DIRTY;
- }
-#endif
- if (disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK) /* Fill sector cache */
- ABORT(fp->fs, FR_DISK_ERR);
- }
-#endif
- fp->dsect = sect;
- }
- rcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs)); /* Get partial sector data from sector buffer */
- if (rcnt > btr) rcnt = btr;
-#if _FS_TINY
- if (move_window(fp->fs, fp->dsect)) /* Move sector window */
- ABORT(fp->fs, FR_DISK_ERR);
- mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */
-#else
- mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */
-#endif
- }
-
- LEAVE_FF(fp->fs, FR_OK);
-}
-
-
-
-
-#if !_FS_READONLY
-/*-----------------------------------------------------------------------*/
-/* Write File */
-/*-----------------------------------------------------------------------*/
-
-FRESULT f_write (
- FIL *fp, /* Pointer to the file object */
- const void *buff, /* Pointer to the data to be written */
- UINT btw, /* Number of bytes to write */
- UINT *bw /* Pointer to number of bytes written */
-)
-{
- FRESULT res;
- DWORD clst, sect;
- UINT wcnt, cc;
- const BYTE *wbuff = buff;
- BYTE csect;
-
-
- *bw = 0; /* Clear write byte counter */
-
- res = validate(fp); /* Check validity */
- if (res != FR_OK) LEAVE_FF(fp->fs, res);
- if (fp->flag & FA__ERROR) /* Aborted file? */
- LEAVE_FF(fp->fs, FR_INT_ERR);
- if (!(fp->flag & FA_WRITE)) /* Check access mode */
- LEAVE_FF(fp->fs, FR_DENIED);
- if ((DWORD)(fp->fsize + btw) < fp->fsize) btw = 0; /* File size cannot reach 4GB */
-
- for ( ; btw; /* Repeat until all data written */
- wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) {
- if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */
- csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */
- if (!csect) { /* On the cluster boundary? */
- if (fp->fptr == 0) { /* On the top of the file? */
- clst = fp->sclust; /* Follow from the origin */
- if (clst == 0) /* When no cluster is allocated, */
- fp->sclust = clst = create_chain(fp->fs, 0); /* Create a new cluster chain */
- } else { /* Middle or end of the file */
-#if _USE_FASTSEEK
- if (fp->cltbl)
- clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
- else
-#endif
- clst = create_chain(fp->fs, fp->clust); /* Follow or stretch cluster chain on the FAT */
- }
- if (clst == 0) break; /* Could not allocate a new cluster (disk full) */
- if (clst == 1) ABORT(fp->fs, FR_INT_ERR);
- if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
- fp->clust = clst; /* Update current cluster */
- }
-#if _FS_TINY
- if (fp->fs->winsect == fp->dsect && move_window(fp->fs, 0)) /* Write-back sector cache */
- ABORT(fp->fs, FR_DISK_ERR);
-#else
- if (fp->flag & FA__DIRTY) { /* Write-back sector cache */
- if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
- ABORT(fp->fs, FR_DISK_ERR);
- fp->flag &= ~FA__DIRTY;
- }
-#endif
- sect = clust2sect(fp->fs, fp->clust); /* Get current sector */
- if (!sect) ABORT(fp->fs, FR_INT_ERR);
- sect += csect;
- cc = btw / SS(fp->fs); /* When remaining bytes >= sector size, */
- if (cc) { /* Write maximum contiguous sectors directly */
- if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */
- cc = fp->fs->csize - csect;
- if (disk_write(fp->fs->drv, wbuff, sect, (BYTE)cc) != RES_OK)
- ABORT(fp->fs, FR_DISK_ERR);
-#if _FS_TINY
- if (fp->fs->winsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */
- mem_cpy(fp->fs->win, wbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), SS(fp->fs));
- fp->fs->wflag = 0;
- }
-#else
- if (fp->dsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */
- mem_cpy(fp->buf, wbuff + ((fp->dsect - sect) * SS(fp->fs)), SS(fp->fs));
- fp->flag &= ~FA__DIRTY;
- }
-#endif
- wcnt = SS(fp->fs) * cc; /* Number of bytes transferred */
- continue;
- }
-#if _FS_TINY
- if (fp->fptr >= fp->fsize) { /* Avoid silly cache filling at growing edge */
- if (move_window(fp->fs, 0)) ABORT(fp->fs, FR_DISK_ERR);
- fp->fs->winsect = sect;
- }
-#else
- if (fp->dsect != sect) { /* Fill sector cache with file data */
- if (fp->fptr < fp->fsize &&
- disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK)
- ABORT(fp->fs, FR_DISK_ERR);
- }
-#endif
- fp->dsect = sect;
- }
- wcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs));/* Put partial sector into file I/O buffer */
- if (wcnt > btw) wcnt = btw;
-#if _FS_TINY
- if (move_window(fp->fs, fp->dsect)) /* Move sector window */
- ABORT(fp->fs, FR_DISK_ERR);
- mem_cpy(&fp->fs->win[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */
- fp->fs->wflag = 1;
-#else
- mem_cpy(&fp->buf[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */
- fp->flag |= FA__DIRTY;
-#endif
- }
-
- if (fp->fptr > fp->fsize) fp->fsize = fp->fptr; /* Update file size if needed */
- fp->flag |= FA__WRITTEN; /* Set file change flag */
-
- LEAVE_FF(fp->fs, FR_OK);
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Synchronize the File Object */
-/*-----------------------------------------------------------------------*/
-
-FRESULT f_sync (
- FIL *fp /* Pointer to the file object */
-)
-{
- FRESULT res;
- DWORD tim;
- BYTE *dir;
-
-
- res = validate(fp); /* Check validity of the object */
- if (res == FR_OK) {
- if (fp->flag & FA__WRITTEN) { /* Has the file been written? */
-#if !_FS_TINY /* Write-back dirty buffer */
- if (fp->flag & FA__DIRTY) {
- if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
- LEAVE_FF(fp->fs, FR_DISK_ERR);
- fp->flag &= ~FA__DIRTY;
- }
-#endif
- /* Update the directory entry */
- res = move_window(fp->fs, fp->dir_sect);
- if (res == FR_OK) {
- dir = fp->dir_ptr;
- dir[DIR_Attr] |= AM_ARC; /* Set archive bit */
- ST_DWORD(dir+DIR_FileSize, fp->fsize); /* Update file size */
- st_clust(dir, fp->sclust); /* Update start cluster */
- tim = get_fattime(); /* Update updated time */
- ST_DWORD(dir+DIR_WrtTime, tim);
- ST_WORD(dir+DIR_LstAccDate, 0);
- fp->flag &= ~FA__WRITTEN;
- fp->fs->wflag = 1;
- res = sync(fp->fs);
- }
- }
- }
-
- LEAVE_FF(fp->fs, res);
-}
-
-#endif /* !_FS_READONLY */
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Close File */
-/*-----------------------------------------------------------------------*/
-
-FRESULT f_close (
- FIL *fp /* Pointer to the file object to be closed */
-)
-{
- FRESULT res;
-
-
-#if _FS_READONLY
- res = validate(fp);
- {
-#if _FS_REENTRANT
- FATFS *fs = fp->fs;
-#endif
- if (res == FR_OK) fp->fs = 0; /* Discard file object */
- LEAVE_FF(fs, res);
- }
-#else
- res = f_sync(fp); /* Flush cached data */
-#if _FS_LOCK
- if (res == FR_OK) { /* Decrement open counter */
-#if _FS_REENTRANT
- FATFS *fs = fp->fs;;
- res = validate(fp);
- if (res == FR_OK) {
- res = dec_lock(fp->lockid);
- unlock_fs(fs, FR_OK);
- }
-#else
- res = dec_lock(fp->lockid);
-#endif
- }
-#endif
- if (res == FR_OK) fp->fs = 0; /* Discard file object */
- return res;
-#endif
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Current Drive/Directory Handlings */
-/*-----------------------------------------------------------------------*/
-
-#if _FS_RPATH >= 1
-
-FRESULT f_chdrive (
- BYTE drv /* Drive number */
-)
-{
- if (drv >= _VOLUMES) return FR_INVALID_DRIVE;
-
- CurrVol = drv;
-
- return FR_OK;
-}
-
-
-
-FRESULT f_chdir (
- const TCHAR *path /* Pointer to the directory path */
-)
-{
- FRESULT res;
- DIR dj;
- DEF_NAMEBUF;
-
-
- res = chk_mounted(&path, &dj.fs, 0);
- if (res == FR_OK) {
- INIT_BUF(dj);
- res = follow_path(&dj, path); /* Follow the path */
- FREE_BUF();
- if (res == FR_OK) { /* Follow completed */
- if (!dj.dir) {
- dj.fs->cdir = dj.sclust; /* Start directory itself */
- } else {
- if (dj.dir[DIR_Attr] & AM_DIR) /* Reached to the directory */
- dj.fs->cdir = ld_clust(dj.fs, dj.dir);
- else
- res = FR_NO_PATH; /* Reached but a file */
- }
- }
- if (res == FR_NO_FILE) res = FR_NO_PATH;
- }
-
- LEAVE_FF(dj.fs, res);
-}
-
-
-#if _FS_RPATH >= 2
-FRESULT f_getcwd (
- TCHAR *path, /* Pointer to the directory path */
- UINT sz_path /* Size of path */
-)
-{
- FRESULT res;
- DIR dj;
- UINT i, n;
- DWORD ccl;
- TCHAR *tp;
- FILINFO fno;
- DEF_NAMEBUF;
-
-
- *path = 0;
- res = chk_mounted((const TCHAR**)&path, &dj.fs, 0); /* Get current volume */
- if (res == FR_OK) {
- INIT_BUF(dj);
- i = sz_path; /* Bottom of buffer (dir stack base) */
- dj.sclust = dj.fs->cdir; /* Start to follow upper dir from current dir */
- while ((ccl = dj.sclust) != 0) { /* Repeat while current dir is a sub-dir */
- res = dir_sdi(&dj, 1); /* Get parent dir */
- if (res != FR_OK) break;
- res = dir_read(&dj);
- if (res != FR_OK) break;
- dj.sclust = ld_clust(dj.fs, dj.dir); /* Goto parent dir */
- res = dir_sdi(&dj, 0);
- if (res != FR_OK) break;
- do { /* Find the entry links to the child dir */
- res = dir_read(&dj);
- if (res != FR_OK) break;
- if (ccl == ld_clust(dj.fs, dj.dir)) break; /* Found the entry */
- res = dir_next(&dj, 0);
- } while (res == FR_OK);
- if (res == FR_NO_FILE) res = FR_INT_ERR;/* It cannot be 'not found'. */
- if (res != FR_OK) break;
-#if _USE_LFN
- fno.lfname = path;
- fno.lfsize = i;
-#endif
- get_fileinfo(&dj, &fno); /* Get the dir name and push it to the buffer */
- tp = fno.fname;
- if (_USE_LFN && *path) tp = path;
- for (n = 0; tp[n]; n++) ;
- if (i < n + 3) {
- res = FR_NOT_ENOUGH_CORE; break;
- }
- while (n) path[--i] = tp[--n];
- path[--i] = '/';
- }
- tp = path;
- if (res == FR_OK) {
- *tp++ = '0' + CurrVol; /* Put drive number */
- *tp++ = ':';
- if (i == sz_path) { /* Root-dir */
- *tp++ = '/';
- } else { /* Sub-dir */
- do /* Add stacked path str */
- *tp++ = path[i++];
- while (i < sz_path);
- }
- }
- *tp = 0;
- FREE_BUF();
- }
-
- LEAVE_FF(dj.fs, res);
-}
-#endif /* _FS_RPATH >= 2 */
-#endif /* _FS_RPATH >= 1 */
-
-
-
-#if _FS_MINIMIZE <= 2
-/*-----------------------------------------------------------------------*/
-/* Seek File R/W Pointer */
-/*-----------------------------------------------------------------------*/
-
-FRESULT f_lseek (
- FIL *fp, /* Pointer to the file object */
- DWORD ofs /* File pointer from top of file */
-)
-{
- FRESULT res;
-
-
- res = validate(fp); /* Check validity of the object */
- if (res != FR_OK) LEAVE_FF(fp->fs, res);
- if (fp->flag & FA__ERROR) /* Check abort flag */
- LEAVE_FF(fp->fs, FR_INT_ERR);
-
-#if _USE_FASTSEEK
- if (fp->cltbl) { /* Fast seek */
- DWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl;
-
- if (ofs == CREATE_LINKMAP) { /* Create CLMT */
- tbl = fp->cltbl;
- tlen = *tbl++; ulen = 2; /* Given table size and required table size */
- cl = fp->sclust; /* Top of the chain */
- if (cl) {
- do {
- /* Get a fragment */
- tcl = cl; ncl = 0; ulen += 2; /* Top, length and used items */
- do {
- pcl = cl; ncl++;
- cl = get_fat(fp->fs, cl);
- if (cl <= 1) ABORT(fp->fs, FR_INT_ERR);
- if (cl == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
- } while (cl == pcl + 1);
- if (ulen <= tlen) { /* Store the length and top of the fragment */
- *tbl++ = ncl; *tbl++ = tcl;
- }
- } while (cl < fp->fs->n_fatent); /* Repeat until end of chain */
- }
- *fp->cltbl = ulen; /* Number of items used */
- if (ulen <= tlen)
- *tbl = 0; /* Terminate table */
- else
- res = FR_NOT_ENOUGH_CORE; /* Given table size is smaller than required */
-
- } else { /* Fast seek */
- if (ofs > fp->fsize) /* Clip offset at the file size */
- ofs = fp->fsize;
- fp->fptr = ofs; /* Set file pointer */
- if (ofs) {
- fp->clust = clmt_clust(fp, ofs - 1);
- dsc = clust2sect(fp->fs, fp->clust);
- if (!dsc) ABORT(fp->fs, FR_INT_ERR);
- dsc += (ofs - 1) / SS(fp->fs) & (fp->fs->csize - 1);
- if (fp->fptr % SS(fp->fs) && dsc != fp->dsect) { /* Refill sector cache if needed */
-#if !_FS_TINY
-#if !_FS_READONLY
- if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */
- if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
- ABORT(fp->fs, FR_DISK_ERR);
- fp->flag &= ~FA__DIRTY;
- }
-#endif
- if (disk_read(fp->fs->drv, fp->buf, dsc, 1) != RES_OK) /* Load current sector */
- ABORT(fp->fs, FR_DISK_ERR);
-#endif
- fp->dsect = dsc;
- }
- }
- }
- } else
-#endif
-
- /* Normal Seek */
- {
- DWORD clst, bcs, nsect, ifptr;
-
- if (ofs > fp->fsize /* In read-only mode, clip offset with the file size */
-#if !_FS_READONLY
- && !(fp->flag & FA_WRITE)
-#endif
- ) ofs = fp->fsize;
-
- ifptr = fp->fptr;
- fp->fptr = nsect = 0;
- if (ofs) {
- bcs = (DWORD)fp->fs->csize * SS(fp->fs); /* Cluster size (byte) */
- if (ifptr > 0 &&
- (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */
- fp->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */
- ofs -= fp->fptr;
- clst = fp->clust;
- } else { /* When seek to back cluster, */
- clst = fp->sclust; /* start from the first cluster */
-#if !_FS_READONLY
- if (clst == 0) { /* If no cluster chain, create a new chain */
- clst = create_chain(fp->fs, 0);
- if (clst == 1) ABORT(fp->fs, FR_INT_ERR);
- if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
- fp->sclust = clst;
- }
-#endif
- fp->clust = clst;
- }
- if (clst != 0) {
- while (ofs > bcs) { /* Cluster following loop */
-#if !_FS_READONLY
- if (fp->flag & FA_WRITE) { /* Check if in write mode or not */
- clst = create_chain(fp->fs, clst); /* Force stretch if in write mode */
- if (clst == 0) { /* When disk gets full, clip file size */
- ofs = bcs; break;
- }
- } else
-#endif
- clst = get_fat(fp->fs, clst); /* Follow cluster chain if not in write mode */
- if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
- if (clst <= 1 || clst >= fp->fs->n_fatent) ABORT(fp->fs, FR_INT_ERR);
- fp->clust = clst;
- fp->fptr += bcs;
- ofs -= bcs;
- }
- fp->fptr += ofs;
- if (ofs % SS(fp->fs)) {
- nsect = clust2sect(fp->fs, clst); /* Current sector */
- if (!nsect) ABORT(fp->fs, FR_INT_ERR);
- nsect += ofs / SS(fp->fs);
- }
- }
- }
- if (fp->fptr % SS(fp->fs) && nsect != fp->dsect) { /* Fill sector cache if needed */
-#if !_FS_TINY
-#if !_FS_READONLY
- if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */
- if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
- ABORT(fp->fs, FR_DISK_ERR);
- fp->flag &= ~FA__DIRTY;
- }
-#endif
- if (disk_read(fp->fs->drv, fp->buf, nsect, 1) != RES_OK) /* Fill sector cache */
- ABORT(fp->fs, FR_DISK_ERR);
-#endif
- fp->dsect = nsect;
- }
-#if !_FS_READONLY
- if (fp->fptr > fp->fsize) { /* Set file change flag if the file size is extended */
- fp->fsize = fp->fptr;
- fp->flag |= FA__WRITTEN;
- }
-#endif
- }
-
- LEAVE_FF(fp->fs, res);
-}
-
-
-
-#if _FS_MINIMIZE <= 1
-/*-----------------------------------------------------------------------*/
-/* Create a Directory Object */
-/*-----------------------------------------------------------------------*/
-
-FRESULT f_opendir (
- DIR *dj, /* Pointer to directory object to create */
- const TCHAR *path /* Pointer to the directory path */
-)
-{
- FRESULT res;
- FATFS *fs;
- DEF_NAMEBUF;
-
-
- if (!dj) return FR_INVALID_OBJECT;
-
- res = chk_mounted(&path, &dj->fs, 0);
- fs = dj->fs;
- if (res == FR_OK) {
- INIT_BUF(*dj);
- res = follow_path(dj, path); /* Follow the path to the directory */
- FREE_BUF();
- if (res == FR_OK) { /* Follow completed */
- if (dj->dir) { /* It is not the root dir */
- if (dj->dir[DIR_Attr] & AM_DIR) { /* The object is a directory */
- dj->sclust = ld_clust(fs, dj->dir);
- } else { /* The object is not a directory */
- res = FR_NO_PATH;
- }
- }
- if (res == FR_OK) {
- dj->id = fs->id;
- res = dir_sdi(dj, 0); /* Rewind dir */
- }
- }
- if (res == FR_NO_FILE) res = FR_NO_PATH;
- if (res != FR_OK) dj->fs = 0; /* Invalidate the dir object if function failed */
- } else {
- dj->fs = 0;
- }
-
- LEAVE_FF(fs, res);
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Read Directory Entry in Sequence */
-/*-----------------------------------------------------------------------*/
-
-FRESULT f_readdir (
- DIR *dj, /* Pointer to the open directory object */
- FILINFO *fno /* Pointer to file information to return */
-)
-{
- FRESULT res;
- DEF_NAMEBUF;
-
-
- res = validate(dj); /* Check validity of the object */
- if (res == FR_OK) {
- if (!fno) {
- res = dir_sdi(dj, 0); /* Rewind the directory object */
- } else {
- INIT_BUF(*dj);
- res = dir_read(dj); /* Read an directory item */
- if (res == FR_NO_FILE) { /* Reached end of dir */
- dj->sect = 0;
- res = FR_OK;
- }
- if (res == FR_OK) { /* A valid entry is found */
- get_fileinfo(dj, fno); /* Get the object information */
- res = dir_next(dj, 0); /* Increment index for next */
- if (res == FR_NO_FILE) {
- dj->sect = 0;
- res = FR_OK;
- }
- }
- FREE_BUF();
- }
- }
-
- LEAVE_FF(dj->fs, res);
-}
-
-
-
-#if _FS_MINIMIZE == 0
-/*-----------------------------------------------------------------------*/
-/* Get File Status */
-/*-----------------------------------------------------------------------*/
-
-FRESULT f_stat (
- const TCHAR *path, /* Pointer to the file path */
- FILINFO *fno /* Pointer to file information to return */
-)
-{
- FRESULT res;
- DIR dj;
- DEF_NAMEBUF;
-
-
- res = chk_mounted(&path, &dj.fs, 0);
- if (res == FR_OK) {
- INIT_BUF(dj);
- res = follow_path(&dj, path); /* Follow the file path */
- if (res == FR_OK) { /* Follow completed */
- if (dj.dir) /* Found an object */
- get_fileinfo(&dj, fno);
- else /* It is root dir */
- res = FR_INVALID_NAME;
- }
- FREE_BUF();
- }
-
- LEAVE_FF(dj.fs, res);
-}
-
-
-
-#if !_FS_READONLY
-/*-----------------------------------------------------------------------*/
-/* Get Number of Free Clusters */
-/*-----------------------------------------------------------------------*/
-
-FRESULT f_getfree (
- const TCHAR *path, /* Pointer to the logical drive number (root dir) */
- DWORD *nclst, /* Pointer to the variable to return number of free clusters */
- FATFS **fatfs /* Pointer to pointer to corresponding file system object to return */
-)
-{
- FRESULT res;
- FATFS *fs;
- DWORD n, clst, sect, stat;
- UINT i;
- BYTE fat, *p;
-
-
- /* Get drive number */
- res = chk_mounted(&path, fatfs, 0);
- fs = *fatfs;
- if (res == FR_OK) {
- /* If free_clust is valid, return it without full cluster scan */
- if (fs->free_clust <= fs->n_fatent - 2) {
- *nclst = fs->free_clust;
- } else {
- /* Get number of free clusters */
- fat = fs->fs_type;
- n = 0;
- if (fat == FS_FAT12) {
- clst = 2;
- do {
- stat = get_fat(fs, clst);
- if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; }
- if (stat == 1) { res = FR_INT_ERR; break; }
- if (stat == 0) n++;
- } while (++clst < fs->n_fatent);
- } else {
- clst = fs->n_fatent;
- sect = fs->fatbase;
- i = 0; p = 0;
- do {
- if (!i) {
- res = move_window(fs, sect++);
- if (res != FR_OK) break;
- p = fs->win;
- i = SS(fs);
- }
- if (fat == FS_FAT16) {
- if (LD_WORD(p) == 0) n++;
- p += 2; i -= 2;
- } else {
- if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) n++;
- p += 4; i -= 4;
- }
- } while (--clst);
- }
- fs->free_clust = n;
- if (fat == FS_FAT32) fs->fsi_flag = 1;
- *nclst = n;
- }
- }
- LEAVE_FF(fs, res);
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Truncate File */
-/*-----------------------------------------------------------------------*/
-
-FRESULT f_truncate (
- FIL *fp /* Pointer to the file object */
-)
-{
- FRESULT res;
- DWORD ncl;
-
-
- if (!fp) return FR_INVALID_OBJECT;
-
- res = validate(fp); /* Check validity of the object */
- if (res == FR_OK) {
- if (fp->flag & FA__ERROR) { /* Check abort flag */
- res = FR_INT_ERR;
- } else {
- if (!(fp->flag & FA_WRITE)) /* Check access mode */
- res = FR_DENIED;
- }
- }
- if (res == FR_OK) {
- if (fp->fsize > fp->fptr) {
- fp->fsize = fp->fptr; /* Set file size to current R/W point */
- fp->flag |= FA__WRITTEN;
- if (fp->fptr == 0) { /* When set file size to zero, remove entire cluster chain */
- res = remove_chain(fp->fs, fp->sclust);
- fp->sclust = 0;
- } else { /* When truncate a part of the file, remove remaining clusters */
- ncl = get_fat(fp->fs, fp->clust);
- res = FR_OK;
- if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR;
- if (ncl == 1) res = FR_INT_ERR;
- if (res == FR_OK && ncl < fp->fs->n_fatent) {
- res = put_fat(fp->fs, fp->clust, 0x0FFFFFFF);
- if (res == FR_OK) res = remove_chain(fp->fs, ncl);
- }
- }
- }
- if (res != FR_OK) fp->flag |= FA__ERROR;
- }
-
- LEAVE_FF(fp->fs, res);
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Delete a File or Directory */
-/*-----------------------------------------------------------------------*/
-
-FRESULT f_unlink (
- const TCHAR *path /* Pointer to the file or directory path */
-)
-{
- FRESULT res;
- DIR dj, sdj;
- BYTE *dir;
- DWORD dclst;
- DEF_NAMEBUF;
-
-
- res = chk_mounted(&path, &dj.fs, 1);
- if (res == FR_OK) {
- INIT_BUF(dj);
- res = follow_path(&dj, path); /* Follow the file path */
- if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))
- res = FR_INVALID_NAME; /* Cannot remove dot entry */
-#if _FS_LOCK
- if (res == FR_OK) res = chk_lock(&dj, 2); /* Cannot remove open file */
-#endif
- if (res == FR_OK) { /* The object is accessible */
- dir = dj.dir;
- if (!dir) {
- res = FR_INVALID_NAME; /* Cannot remove the start directory */
- } else {
- if (dir[DIR_Attr] & AM_RDO)
- res = FR_DENIED; /* Cannot remove R/O object */
- }
- dclst = ld_clust(dj.fs, dir);
- if (res == FR_OK && (dir[DIR_Attr] & AM_DIR)) { /* Is it a sub-dir? */
- if (dclst < 2) {
- res = FR_INT_ERR;
- } else {
- mem_cpy(&sdj, &dj, sizeof (DIR)); /* Check if the sub-dir is empty or not */
- sdj.sclust = dclst;
- res = dir_sdi(&sdj, 2); /* Exclude dot entries */
- if (res == FR_OK) {
- res = dir_read(&sdj);
- if (res == FR_OK /* Not empty dir */
-#if _FS_RPATH
- || dclst == dj.fs->cdir /* Current dir */
-#endif
- ) res = FR_DENIED;
- if (res == FR_NO_FILE) res = FR_OK; /* Empty */
- }
- }
- }
- if (res == FR_OK) {
- res = dir_remove(&dj); /* Remove the directory entry */
- if (res == FR_OK) {
- if (dclst) /* Remove the cluster chain if exist */
- res = remove_chain(dj.fs, dclst);
- if (res == FR_OK) res = sync(dj.fs);
- }
- }
- }
- FREE_BUF();
- }
- LEAVE_FF(dj.fs, res);
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Create a Directory */
-/*-----------------------------------------------------------------------*/
-
-FRESULT f_mkdir (
- const TCHAR *path /* Pointer to the directory path */
-)
-{
- FRESULT res;
- DIR dj;
- BYTE *dir, n;
- DWORD dsc, dcl, pcl, tim = get_fattime();
- DEF_NAMEBUF;
-
-
- res = chk_mounted(&path, &dj.fs, 1);
- if (res == FR_OK) {
- INIT_BUF(dj);
- res = follow_path(&dj, path); /* Follow the file path */
- if (res == FR_OK) res = FR_EXIST; /* Any object with same name is already existing */
- if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NS] & NS_DOT))
- res = FR_INVALID_NAME;
- if (res == FR_NO_FILE) { /* Can create a new directory */
- dcl = create_chain(dj.fs, 0); /* Allocate a cluster for the new directory table */
- res = FR_OK;
- if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster */
- if (dcl == 1) res = FR_INT_ERR;
- if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR;
- if (res == FR_OK) /* Flush FAT */
- res = move_window(dj.fs, 0);
- if (res == FR_OK) { /* Initialize the new directory table */
- dsc = clust2sect(dj.fs, dcl);
- dir = dj.fs->win;
- mem_set(dir, 0, SS(dj.fs));
- mem_set(dir+DIR_Name, ' ', 8+3); /* Create "." entry */
- dir[DIR_Name] = '.';
- dir[DIR_Attr] = AM_DIR;
- ST_DWORD(dir+DIR_WrtTime, tim);
- st_clust(dir, dcl);
- mem_cpy(dir+SZ_DIR, dir, SZ_DIR); /* Create ".." entry */
- dir[33] = '.'; pcl = dj.sclust;
- if (dj.fs->fs_type == FS_FAT32 && pcl == dj.fs->dirbase)
- pcl = 0;
- st_clust(dir+SZ_DIR, pcl);
- for (n = dj.fs->csize; n; n--) { /* Write dot entries and clear following sectors */
- dj.fs->winsect = dsc++;
- dj.fs->wflag = 1;
- res = move_window(dj.fs, 0);
- if (res != FR_OK) break;
- mem_set(dir, 0, SS(dj.fs));
- }
- }
- if (res == FR_OK) res = dir_register(&dj); /* Register the object to the directory */
- if (res != FR_OK) {
- remove_chain(dj.fs, dcl); /* Could not register, remove cluster chain */
- } else {
- dir = dj.dir;
- dir[DIR_Attr] = AM_DIR; /* Attribute */
- ST_DWORD(dir+DIR_WrtTime, tim); /* Created time */
- st_clust(dir, dcl); /* Table start cluster */
- dj.fs->wflag = 1;
- res = sync(dj.fs);
- }
- }
- FREE_BUF();
- }
-
- LEAVE_FF(dj.fs, res);
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Change Attribute */
-/*-----------------------------------------------------------------------*/
-
-FRESULT f_chmod (
- const TCHAR *path, /* Pointer to the file path */
- BYTE value, /* Attribute bits */
- BYTE mask /* Attribute mask to change */
-)
-{
- FRESULT res;
- DIR dj;
- BYTE *dir;
- DEF_NAMEBUF;
-
-
- res = chk_mounted(&path, &dj.fs, 1);
- if (res == FR_OK) {
- INIT_BUF(dj);
- res = follow_path(&dj, path); /* Follow the file path */
- FREE_BUF();
- if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))
- res = FR_INVALID_NAME;
- if (res == FR_OK) {
- dir = dj.dir;
- if (!dir) { /* Is it a root directory? */
- res = FR_INVALID_NAME;
- } else { /* File or sub directory */
- mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */
- dir[DIR_Attr] = (value & mask) | (dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */
- dj.fs->wflag = 1;
- res = sync(dj.fs);
- }
- }
- }
-
- LEAVE_FF(dj.fs, res);
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Change Timestamp */
-/*-----------------------------------------------------------------------*/
-
-FRESULT f_utime (
- const TCHAR *path, /* Pointer to the file/directory name */
- const FILINFO *fno /* Pointer to the time stamp to be set */
-)
-{
- FRESULT res;
- DIR dj;
- BYTE *dir;
- DEF_NAMEBUF;
-
-
- res = chk_mounted(&path, &dj.fs, 1);
- if (res == FR_OK) {
- INIT_BUF(dj);
- res = follow_path(&dj, path); /* Follow the file path */
- FREE_BUF();
- if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))
- res = FR_INVALID_NAME;
- if (res == FR_OK) {
- dir = dj.dir;
- if (!dir) { /* Root directory */
- res = FR_INVALID_NAME;
- } else { /* File or sub-directory */
- ST_WORD(dir+DIR_WrtTime, fno->ftime);
- ST_WORD(dir+DIR_WrtDate, fno->fdate);
- dj.fs->wflag = 1;
- res = sync(dj.fs);
- }
- }
- }
-
- LEAVE_FF(dj.fs, res);
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Rename File/Directory */
-/*-----------------------------------------------------------------------*/
-
-FRESULT f_rename (
- const TCHAR *path_old, /* Pointer to the old name */
- const TCHAR *path_new /* Pointer to the new name */
-)
-{
- FRESULT res;
- DIR djo, djn;
- BYTE buf[21], *dir;
- DWORD dw;
- DEF_NAMEBUF;
-
-
- res = chk_mounted(&path_old, &djo.fs, 1);
- if (res == FR_OK) {
- djn.fs = djo.fs;
- INIT_BUF(djo);
- res = follow_path(&djo, path_old); /* Check old object */
- if (_FS_RPATH && res == FR_OK && (djo.fn[NS] & NS_DOT))
- res = FR_INVALID_NAME;
-#if _FS_LOCK
- if (res == FR_OK) res = chk_lock(&djo, 2);
-#endif
- if (res == FR_OK) { /* Old object is found */
- if (!djo.dir) { /* Is root dir? */
- res = FR_NO_FILE;
- } else {
- mem_cpy(buf, djo.dir+DIR_Attr, 21); /* Save the object information except for name */
- mem_cpy(&djn, &djo, sizeof (DIR)); /* Check new object */
- res = follow_path(&djn, path_new);
- if (res == FR_OK) res = FR_EXIST; /* The new object name is already existing */
- if (res == FR_NO_FILE) { /* Is it a valid path and no name collision? */
-/* Start critical section that an interruption or error can cause cross-link */
- res = dir_register(&djn); /* Register the new entry */
- if (res == FR_OK) {
- dir = djn.dir; /* Copy object information except for name */
- mem_cpy(dir+13, buf+2, 19);
- dir[DIR_Attr] = buf[0] | AM_ARC;
- djo.fs->wflag = 1;
- if (djo.sclust != djn.sclust && (dir[DIR_Attr] & AM_DIR)) { /* Update .. entry in the directory if needed */
- dw = clust2sect(djo.fs, ld_clust(djo.fs, dir));
- if (!dw) {
- res = FR_INT_ERR;
- } else {
- res = move_window(djo.fs, dw);
- dir = djo.fs->win+SZ_DIR; /* .. entry */
- if (res == FR_OK && dir[1] == '.') {
- dw = (djo.fs->fs_type == FS_FAT32 && djn.sclust == djo.fs->dirbase) ? 0 : djn.sclust;
- st_clust(dir, dw);
- djo.fs->wflag = 1;
- }
- }
- }
- if (res == FR_OK) {
- res = dir_remove(&djo); /* Remove old entry */
- if (res == FR_OK)
- res = sync(djo.fs);
- }
- }
-/* End critical section */
- }
- }
- }
- FREE_BUF();
- }
- LEAVE_FF(djo.fs, res);
-}
-
-#endif /* !_FS_READONLY */
-#endif /* _FS_MINIMIZE == 0 */
-#endif /* _FS_MINIMIZE <= 1 */
-#endif /* _FS_MINIMIZE <= 2 */
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Forward data to the stream directly (available on only tiny cfg) */
-/*-----------------------------------------------------------------------*/
-#if _USE_FORWARD && _FS_TINY
-
-FRESULT f_forward (
- FIL *fp, /* Pointer to the file object */
- UINT (*func)(const BYTE*,UINT), /* Pointer to the streaming function */
- UINT btr, /* Number of bytes to forward */
- UINT *bf /* Pointer to number of bytes forwarded */
-)
-{
- FRESULT res;
- DWORD remain, clst, sect;
- UINT rcnt;
- BYTE csect;
-
-
- *bf = 0; /* Clear transfer byte counter */
-
- if (!fp) return FR_INVALID_OBJECT;
-
- res = validate(fp); /* Check validity of the object */
- if (res != FR_OK) LEAVE_FF(fp->fs, res);
- if (fp->flag & FA__ERROR) /* Check error flag */
- LEAVE_FF(fp->fs, FR_INT_ERR);
- if (!(fp->flag & FA_READ)) /* Check access mode */
- LEAVE_FF(fp->fs, FR_DENIED);
-
- remain = fp->fsize - fp->fptr;
- if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */
-
- for ( ; btr && (*func)(0, 0); /* Repeat until all data transferred or stream becomes busy */
- fp->fptr += rcnt, *bf += rcnt, btr -= rcnt) {
- csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */
- if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */
- if (!csect) { /* On the cluster boundary? */
- clst = (fp->fptr == 0) ? /* On the top of the file? */
- fp->sclust : get_fat(fp->fs, fp->clust);
- if (clst <= 1) ABORT(fp->fs, FR_INT_ERR);
- if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
- fp->clust = clst; /* Update current cluster */
- }
- }
- sect = clust2sect(fp->fs, fp->clust); /* Get current data sector */
- if (!sect) ABORT(fp->fs, FR_INT_ERR);
- sect += csect;
- if (move_window(fp->fs, sect)) /* Move sector window */
- ABORT(fp->fs, FR_DISK_ERR);
- fp->dsect = sect;
- rcnt = SS(fp->fs) - (WORD)(fp->fptr % SS(fp->fs)); /* Forward data from sector window */
- if (rcnt > btr) rcnt = btr;
- rcnt = (*func)(&fp->fs->win[(WORD)fp->fptr % SS(fp->fs)], rcnt);
- if (!rcnt) ABORT(fp->fs, FR_INT_ERR);
- }
-
- LEAVE_FF(fp->fs, FR_OK);
-}
-#endif /* _USE_FORWARD */
-
-
-
-#if _USE_MKFS && !_FS_READONLY
-/*-----------------------------------------------------------------------*/
-/* Create File System on the Drive */
-/*-----------------------------------------------------------------------*/
-#define N_ROOTDIR 512 /* Number of root dir entries for FAT12/16 */
-#define N_FATS 1 /* Number of FAT copies (1 or 2) */
-
-
-FRESULT f_mkfs (
- BYTE drv, /* Logical drive number */
- BYTE sfd, /* Partitioning rule 0:FDISK, 1:SFD */
- UINT au /* Allocation unit size [bytes] */
-)
-{
- static const WORD vst[] = { 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 0};
- static const WORD cst[] = {32768, 16384, 8192, 4096, 2048, 16384, 8192, 4096, 2048, 1024, 512};
- BYTE fmt, md, sys, *tbl, pdrv, part;
- DWORD n_clst, vs, n, wsect;
- UINT i;
- DWORD b_vol, b_fat, b_dir, b_data; /* LBA */
- DWORD n_vol, n_rsv, n_fat, n_dir; /* Size */
- FATFS *fs;
- DSTATUS stat;
-
-
- /* Check mounted drive and clear work area */
- if (drv >= _VOLUMES) return FR_INVALID_DRIVE;
- if (sfd > 1) return FR_INVALID_PARAMETER;
- if (au & (au - 1)) return FR_INVALID_PARAMETER;
- fs = FatFs[drv];
- if (!fs) return FR_NOT_ENABLED;
- fs->fs_type = 0;
- pdrv = LD2PD(drv); /* Physical drive */
- part = LD2PT(drv); /* Partition (0:auto detect, 1-4:get from partition table)*/
-
- /* Get disk statics */
- stat = disk_initialize(pdrv);
- if (stat & STA_NOINIT) return FR_NOT_READY;
- if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
-#if _MAX_SS != 512 /* Get disk sector size */
- if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS)
- return FR_DISK_ERR;
-#endif
- if (_MULTI_PARTITION && part) {
- /* Get partition information from partition table in the MBR */
- if (disk_read(pdrv, fs->win, 0, 1) != RES_OK) return FR_DISK_ERR;
- if (LD_WORD(fs->win+BS_55AA) != 0xAA55) return FR_MKFS_ABORTED;
- tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE];
- if (!tbl[4]) return FR_MKFS_ABORTED; /* No partition? */
- b_vol = LD_DWORD(tbl+8); /* Volume start sector */
- n_vol = LD_DWORD(tbl+12); /* Volume size */
- } else {
- /* Create a partition in this function */
- if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &n_vol) != RES_OK || n_vol < 128)
- return FR_DISK_ERR;
- b_vol = (sfd) ? 0 : 63; /* Volume start sector */
- n_vol -= b_vol; /* Volume size */
- }
-
- if (!au) { /* AU auto selection */
- vs = n_vol / (2000 / (SS(fs) / 512));
- for (i = 0; vs < vst[i]; i++) ;
- au = cst[i];
- }
- au /= SS(fs); /* Number of sectors per cluster */
- if (au == 0) au = 1;
- if (au > 128) au = 128;
-
- /* Pre-compute number of clusters and FAT sub-type */
- n_clst = n_vol / au;
- fmt = FS_FAT12;
- if (n_clst >= MIN_FAT16) fmt = FS_FAT16;
- if (n_clst >= MIN_FAT32) fmt = FS_FAT32;
-
- /* Determine offset and size of FAT structure */
- if (fmt == FS_FAT32) {
- n_fat = ((n_clst * 4) + 8 + SS(fs) - 1) / SS(fs);
- n_rsv = 32;
- n_dir = 0;
- } else {
- n_fat = (fmt == FS_FAT12) ? (n_clst * 3 + 1) / 2 + 3 : (n_clst * 2) + 4;
- n_fat = (n_fat + SS(fs) - 1) / SS(fs);
- n_rsv = 1;
- n_dir = (DWORD)N_ROOTDIR * SZ_DIR / SS(fs);
- }
- b_fat = b_vol + n_rsv; /* FAT area start sector */
- b_dir = b_fat + n_fat * N_FATS; /* Directory area start sector */
- b_data = b_dir + n_dir; /* Data area start sector */
- if (n_vol < b_data + au - b_vol) return FR_MKFS_ABORTED; /* Too small volume */
-
- /* Align data start sector to erase block boundary (for flash memory media) */
- if (disk_ioctl(pdrv, GET_BLOCK_SIZE, &n) != RES_OK || !n || n > 32768) n = 1;
- n = (b_data + n - 1) & ~(n - 1); /* Next nearest erase block from current data start */
- n = (n - b_data) / N_FATS;
- if (fmt == FS_FAT32) { /* FAT32: Move FAT offset */
- n_rsv += n;
- b_fat += n;
- } else { /* FAT12/16: Expand FAT size */
- n_fat += n;
- }
-
- /* Determine number of clusters and final check of validity of the FAT sub-type */
- n_clst = (n_vol - n_rsv - n_fat * N_FATS - n_dir) / au;
- if ( (fmt == FS_FAT16 && n_clst < MIN_FAT16)
- || (fmt == FS_FAT32 && n_clst < MIN_FAT32))
- return FR_MKFS_ABORTED;
-
- switch (fmt) { /* Determine system ID for partition table */
- case FS_FAT12: sys = 0x01; break;
- case FS_FAT16: sys = (n_vol < 0x10000) ? 0x04 : 0x06; break;
- default: sys = 0x0C;
- }
-
- if (_MULTI_PARTITION && part) {
- /* Update system ID in the partition table */
- tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE];
- tbl[4] = sys;
- if (disk_write(pdrv, fs->win, 0, 1) != RES_OK) return FR_DISK_ERR;
- md = 0xF8;
- } else {
- if (sfd) { /* No partition table (SFD) */
- md = 0xF0;
- } else { /* Create partition table (FDISK) */
- mem_set(fs->win, 0, SS(fs));
- tbl = fs->win+MBR_Table; /* Create partition table for single partition in the drive */
- tbl[1] = 1; /* Partition start head */
- tbl[2] = 1; /* Partition start sector */
- tbl[3] = 0; /* Partition start cylinder */
- tbl[4] = sys; /* System type */
- tbl[5] = 254; /* Partition end head */
- n = (b_vol + n_vol) / 63 / 255;
- tbl[6] = (BYTE)((n >> 2) | 63); /* Partition end sector */
- tbl[7] = (BYTE)n; /* End cylinder */
- ST_DWORD(tbl+8, 63); /* Partition start in LBA */
- ST_DWORD(tbl+12, n_vol); /* Partition size in LBA */
- ST_WORD(fs->win+BS_55AA, 0xAA55); /* MBR signature */
- if (disk_write(pdrv, fs->win, 0, 1) != RES_OK) /* Write it to the MBR sector */
- return FR_DISK_ERR;
- md = 0xF8;
- }
- }
-
- /* Create BPB in the VBR */
- tbl = fs->win; /* Clear sector */
- mem_set(tbl, 0, SS(fs));
- mem_cpy(tbl, "\xEB\xFE\x90" "MSDOS5.0", 11);/* Boot jump code, OEM name */
- i = SS(fs); /* Sector size */
- ST_WORD(tbl+BPB_BytsPerSec, i);
- tbl[BPB_SecPerClus] = (BYTE)au; /* Sectors per cluster */
- ST_WORD(tbl+BPB_RsvdSecCnt, n_rsv); /* Reserved sectors */
- tbl[BPB_NumFATs] = N_FATS; /* Number of FATs */
- i = (fmt == FS_FAT32) ? 0 : N_ROOTDIR; /* Number of rootdir entries */
- ST_WORD(tbl+BPB_RootEntCnt, i);
- if (n_vol < 0x10000) { /* Number of total sectors */
- ST_WORD(tbl+BPB_TotSec16, n_vol);
- } else {
- ST_DWORD(tbl+BPB_TotSec32, n_vol);
- }
- tbl[BPB_Media] = md; /* Media descriptor */
- ST_WORD(tbl+BPB_SecPerTrk, 63); /* Number of sectors per track */
- ST_WORD(tbl+BPB_NumHeads, 255); /* Number of heads */
- ST_DWORD(tbl+BPB_HiddSec, b_vol); /* Hidden sectors */
- n = get_fattime(); /* Use current time as VSN */
- if (fmt == FS_FAT32) {
- ST_DWORD(tbl+BS_VolID32, n); /* VSN */
- ST_DWORD(tbl+BPB_FATSz32, n_fat); /* Number of sectors per FAT */
- ST_DWORD(tbl+BPB_RootClus, 2); /* Root directory start cluster (2) */
- ST_WORD(tbl+BPB_FSInfo, 1); /* FSInfo record offset (VBR+1) */
- ST_WORD(tbl+BPB_BkBootSec, 6); /* Backup boot record offset (VBR+6) */
- tbl[BS_DrvNum32] = 0x80; /* Drive number */
- tbl[BS_BootSig32] = 0x29; /* Extended boot signature */
- mem_cpy(tbl+BS_VolLab32, "NO NAME " "FAT32 ", 19); /* Volume label, FAT signature */
- } else {
- ST_DWORD(tbl+BS_VolID, n); /* VSN */
- ST_WORD(tbl+BPB_FATSz16, n_fat); /* Number of sectors per FAT */
- tbl[BS_DrvNum] = 0x80; /* Drive number */
- tbl[BS_BootSig] = 0x29; /* Extended boot signature */
- mem_cpy(tbl+BS_VolLab, "NO NAME " "FAT ", 19); /* Volume label, FAT signature */
- }
- ST_WORD(tbl+BS_55AA, 0xAA55); /* Signature (Offset is fixed here regardless of sector size) */
- if (disk_write(pdrv, tbl, b_vol, 1) != RES_OK) /* Write it to the VBR sector */
- return FR_DISK_ERR;
- if (fmt == FS_FAT32) /* Write backup VBR if needed (VBR+6) */
- disk_write(pdrv, tbl, b_vol + 6, 1);
-
- /* Initialize FAT area */
- wsect = b_fat;
- for (i = 0; i < N_FATS; i++) { /* Initialize each FAT copy */
- mem_set(tbl, 0, SS(fs)); /* 1st sector of the FAT */
- n = md; /* Media descriptor byte */
- if (fmt != FS_FAT32) {
- n |= (fmt == FS_FAT12) ? 0x00FFFF00 : 0xFFFFFF00;
- ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT12/16) */
- } else {
- n |= 0xFFFFFF00;
- ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT32) */
- ST_DWORD(tbl+4, 0xFFFFFFFF);
- ST_DWORD(tbl+8, 0x0FFFFFFF); /* Reserve cluster #2 for root dir */
- }
- if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK)
- return FR_DISK_ERR;
- mem_set(tbl, 0, SS(fs)); /* Fill following FAT entries with zero */
- for (n = 1; n < n_fat; n++) { /* This loop may take a time on FAT32 volume due to many single sector writes */
- if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK)
- return FR_DISK_ERR;
- }
- }
-
- /* Initialize root directory */
- i = (fmt == FS_FAT32) ? au : n_dir;
- do {
- if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK)
- return FR_DISK_ERR;
- } while (--i);
-
-#if _USE_ERASE /* Erase data area if needed */
- {
- DWORD eb[2];
-
- eb[0] = wsect; eb[1] = wsect + (n_clst - ((fmt == FS_FAT32) ? 1 : 0)) * au - 1;
- disk_ioctl(pdrv, CTRL_ERASE_SECTOR, eb);
- }
-#endif
-
- /* Create FSInfo if needed */
- if (fmt == FS_FAT32) {
- ST_DWORD(tbl+FSI_LeadSig, 0x41615252);
- ST_DWORD(tbl+FSI_StrucSig, 0x61417272);
- ST_DWORD(tbl+FSI_Free_Count, n_clst - 1); /* Number of free clusters */
- ST_DWORD(tbl+FSI_Nxt_Free, 2); /* Last allocated cluster# */
- ST_WORD(tbl+BS_55AA, 0xAA55);
- disk_write(pdrv, tbl, b_vol + 1, 1); /* Write original (VBR+1) */
- disk_write(pdrv, tbl, b_vol + 7, 1); /* Write backup (VBR+7) */
- }
-
- return (disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR;
-}
-
-
-#if _MULTI_PARTITION == 2
-/*-----------------------------------------------------------------------*/
-/* Divide Physical Drive */
-/*-----------------------------------------------------------------------*/
-
-FRESULT f_fdisk (
- BYTE pdrv, /* Physical drive number */
- const DWORD szt[], /* Pointer to the size table for each partitions */
- void* work /* Pointer to the working buffer */
-)
-{
- UINT i, n, sz_cyl, tot_cyl, b_cyl, e_cyl, p_cyl;
- BYTE s_hd, e_hd, *p, *buf = (BYTE*)work;
- DSTATUS stat;
- DWORD sz_disk, sz_part, s_part;
-
-
- stat = disk_initialize(pdrv);
- if (stat & STA_NOINIT) return FR_NOT_READY;
- if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
- if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_disk)) return FR_DISK_ERR;
-
- /* Determine CHS in the table regardless of the drive geometry */
- for (n = 16; n < 256 && sz_disk / n / 63 > 1024; n *= 2) ;
- if (n == 256) n--;
- e_hd = n - 1;
- sz_cyl = 63 * n;
- tot_cyl = sz_disk / sz_cyl;
-
- /* Create partition table */
- mem_set(buf, 0, _MAX_SS);
- p = buf + MBR_Table; b_cyl = 0;
- for (i = 0; i < 4; i++, p += SZ_PTE) {
- p_cyl = (szt[i] <= 100) ? (DWORD)tot_cyl * szt[i] / 100 : szt[i] / sz_cyl;
- if (!p_cyl) continue;
- s_part = (DWORD)sz_cyl * b_cyl;
- sz_part = (DWORD)sz_cyl * p_cyl;
- if (i == 0) { /* Exclude first track of cylinder 0 */
- s_hd = 1;
- s_part += 63; sz_part -= 63;
- } else {
- s_hd = 0;
- }
- e_cyl = b_cyl + p_cyl - 1;
- if (e_cyl >= tot_cyl) return FR_INVALID_PARAMETER;
-
- /* Set partition table */
- p[1] = s_hd; /* Start head */
- p[2] = (BYTE)((b_cyl >> 2) + 1); /* Start sector */
- p[3] = (BYTE)b_cyl; /* Start cylinder */
- p[4] = 0x06; /* System type (temporary setting) */
- p[5] = e_hd; /* End head */
- p[6] = (BYTE)((e_cyl >> 2) + 63); /* End sector */
- p[7] = (BYTE)e_cyl; /* End cylinder */
- ST_DWORD(p + 8, s_part); /* Start sector in LBA */
- ST_DWORD(p + 12, sz_part); /* Partition size */
-
- /* Next partition */
- b_cyl += p_cyl;
- }
- ST_WORD(p, 0xAA55);
-
- /* Write it to the MBR */
- return (disk_write(pdrv, buf, 0, 1) || disk_ioctl(pdrv, CTRL_SYNC, 0)) ? FR_DISK_ERR : FR_OK;
-}
-
-
-#endif /* _MULTI_PARTITION == 2 */
-#endif /* _USE_MKFS && !_FS_READONLY */
-
-
-
-
-#if _USE_STRFUNC
-/*-----------------------------------------------------------------------*/
-/* Get a string from the file */
-/*-----------------------------------------------------------------------*/
-TCHAR* f_gets (
- TCHAR* buff, /* Pointer to the string buffer to read */
- int len, /* Size of string buffer (characters) */
- FIL* fil /* Pointer to the file object */
-)
-{
- int n = 0;
- TCHAR c, *p = buff;
- BYTE s[2];
- UINT rc;
-
-
- while (n < len - 1) { /* Read bytes until buffer gets filled */
- f_read(fil, s, 1, &rc);
- if (rc != 1) break; /* Break on EOF or error */
- c = s[0];
-#if _LFN_UNICODE /* Read a character in UTF-8 encoding */
- if (c >= 0x80) {
- if (c < 0xC0) continue; /* Skip stray trailer */
- if (c < 0xE0) { /* Two-byte sequence */
- f_read(fil, s, 1, &rc);
- if (rc != 1) break;
- c = ((c & 0x1F) << 6) | (s[0] & 0x3F);
- if (c < 0x80) c = '?';
- } else {
- if (c < 0xF0) { /* Three-byte sequence */
- f_read(fil, s, 2, &rc);
- if (rc != 2) break;
- c = (c << 12) | ((s[0] & 0x3F) << 6) | (s[1] & 0x3F);
- if (c < 0x800) c = '?';
- } else { /* Reject four-byte sequence */
- c = '?';
- }
- }
- }
-#endif
-#if _USE_STRFUNC >= 2
- if (c == '\r') continue; /* Strip '\r' */
-#endif
- *p++ = c;
- n++;
- if (c == '\n') break; /* Break on EOL */
- }
- *p = 0;
- return n ? buff : 0; /* When no data read (eof or error), return with error. */
-}
-
-
-
-#if !_FS_READONLY
-#include <stdarg.h>
-/*-----------------------------------------------------------------------*/
-/* Put a character to the file */
-/*-----------------------------------------------------------------------*/
-int f_putc (
- TCHAR c, /* A character to be output */
- FIL* fil /* Pointer to the file object */
-)
-{
- UINT bw, btw;
- BYTE s[3];
-
-
-#if _USE_STRFUNC >= 2
- if (c == '\n') f_putc ('\r', fil); /* LF -> CRLF conversion */
-#endif
-
-#if _LFN_UNICODE /* Write the character in UTF-8 encoding */
- if (c < 0x80) { /* 7-bit */
- s[0] = (BYTE)c;
- btw = 1;
- } else {
- if (c < 0x800) { /* 11-bit */
- s[0] = (BYTE)(0xC0 | (c >> 6));
- s[1] = (BYTE)(0x80 | (c & 0x3F));
- btw = 2;
- } else { /* 16-bit */
- s[0] = (BYTE)(0xE0 | (c >> 12));
- s[1] = (BYTE)(0x80 | ((c >> 6) & 0x3F));
- s[2] = (BYTE)(0x80 | (c & 0x3F));
- btw = 3;
- }
- }
-#else /* Write the character without conversion */
- s[0] = (BYTE)c;
- btw = 1;
-#endif
- f_write(fil, s, btw, &bw); /* Write the char to the file */
- return (bw == btw) ? 1 : EOF; /* Return the result */
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Put a string to the file */
-/*-----------------------------------------------------------------------*/
-int f_puts (
- const TCHAR* str, /* Pointer to the string to be output */
- FIL* fil /* Pointer to the file object */
-)
-{
- int n;
-
-
- for (n = 0; *str; str++, n++) {
- if (f_putc(*str, fil) == EOF) return EOF;
- }
- return n;
-}
-
-
-
-
-/*-----------------------------------------------------------------------*/
-/* Put a formatted string to the file */
-/*-----------------------------------------------------------------------*/
-int f_printf (
- FIL* fil, /* Pointer to the file object */
- const TCHAR* str, /* Pointer to the format string */
- ... /* Optional arguments... */
-)
-{
- va_list arp;
- BYTE f, r;
- UINT i, j, w;
- ULONG v;
- TCHAR c, d, s[16], *p;
- int res, chc, cc;
-
-
- va_start(arp, str);
-
- for (cc = res = 0; cc != EOF; res += cc) {
- c = *str++;
- if (c == 0) break; /* End of string */
- if (c != '%') { /* Non escape character */
- cc = f_putc(c, fil);
- if (cc != EOF) cc = 1;
- continue;
- }
- w = f = 0;
- c = *str++;
- if (c == '0') { /* Flag: '0' padding */
- f = 1; c = *str++;
- } else {
- if (c == '-') { /* Flag: left justified */
- f = 2; c = *str++;
- }
- }
- while (IsDigit(c)) { /* Precision */
- w = w * 10 + c - '0';
- c = *str++;
- }
- if (c == 'l' || c == 'L') { /* Prefix: Size is long int */
- f |= 4; c = *str++;
- }
- if (!c) break;
- d = c;
- if (IsLower(d)) d -= 0x20;
- switch (d) { /* Type is... */
- case 'S' : /* String */
- p = va_arg(arp, TCHAR*);
- for (j = 0; p[j]; j++) ;
- chc = 0;
- if (!(f & 2)) {
- while (j++ < w) chc += (cc = f_putc(' ', fil));
- }
- chc += (cc = f_puts(p, fil));
- while (j++ < w) chc += (cc = f_putc(' ', fil));
- if (cc != EOF) cc = chc;
- continue;
- case 'C' : /* Character */
- cc = f_putc((TCHAR)va_arg(arp, int), fil); continue;
- case 'B' : /* Binary */
- r = 2; break;
- case 'O' : /* Octal */
- r = 8; break;
- case 'D' : /* Signed decimal */
- case 'U' : /* Unsigned decimal */
- r = 10; break;
- case 'X' : /* Hexdecimal */
- r = 16; break;
- default: /* Unknown type (pass-through) */
- cc = f_putc(c, fil); continue;
- }
-
- /* Get an argument and put it in numeral */
- v = (f & 4) ? (ULONG)va_arg(arp, long) : ((d == 'D') ? (ULONG)(long)va_arg(arp, int) : (ULONG)va_arg(arp, unsigned int));
- if (d == 'D' && (v & 0x80000000)) {
- v = 0 - v;
- f |= 8;
- }
- i = 0;
- do {
- d = (TCHAR)(v % r); v /= r;
- if (d > 9) d += (c == 'x') ? 0x27 : 0x07;
- s[i++] = d + '0';
- } while (v && i < sizeof s / sizeof s[0]);
- if (f & 8) s[i++] = '-';
- j = i; d = (f & 1) ? '0' : ' ';
- res = 0;
- while (!(f & 2) && j++ < w) res += (cc = f_putc(d, fil));
- do res += (cc = f_putc(s[--i], fil)); while(i);
- while (j++ < w) res += (cc = f_putc(' ', fil));
- if (cc != EOF) cc = res;
- }
-
- va_end(arp);
- return (cc == EOF) ? cc : res;
-}
-
-#endif /* !_FS_READONLY */
-#endif /* _USE_STRFUNC */
diff --git a/lib/lufa/Projects/Webserver/Lib/FATFs/ff.h b/lib/lufa/Projects/Webserver/Lib/FATFs/ff.h
deleted file mode 100644
index 627cbaabe..000000000
--- a/lib/lufa/Projects/Webserver/Lib/FATFs/ff.h
+++ /dev/null
@@ -1,337 +0,0 @@
-/*---------------------------------------------------------------------------/
-/ FatFs - FAT file system module include file R0.09a (C)ChaN, 2012
-/----------------------------------------------------------------------------/
-/ FatFs module is a generic FAT file system module for small embedded systems.
-/ This is a free software that opened for education, research and commercial
-/ developments under license policy of following terms.
-/
-/ Copyright (C) 2012, ChaN, all right reserved.
-/
-/ * The FatFs module is a free software and there is NO WARRANTY.
-/ * No restriction on use. You can use, modify and redistribute it for
-/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
-/ * Redistributions of source code must retain the above copyright notice.
-/
-/----------------------------------------------------------------------------*/
-
-#ifndef _FATFS
-#define _FATFS 4004 /* Revision ID */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "integer.h" /* Basic integer types */
-#include "ffconf.h" /* FatFs configuration options */
-
-#if _FATFS != _FFCONF
-#error Wrong configuration file (ffconf.h).
-#endif
-
-
-
-/* Definitions of volume management */
-
-#if _MULTI_PARTITION /* Multiple partition configuration */
-typedef struct {
- BYTE pd; /* Physical drive number */
- BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
-} PARTITION;
-extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
-#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */
-#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */
-
-#else /* Single partition configuration */
-#define LD2PD(vol) (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */
-#define LD2PT(vol) 0 /* Always mounts the 1st partition or in SFD */
-
-#endif
-
-
-
-/* Type of path name strings on FatFs API */
-
-#if _LFN_UNICODE /* Unicode string */
-#if !_USE_LFN
-#error _LFN_UNICODE must be 0 in non-LFN cfg.
-#endif
-#ifndef _INC_TCHAR
-typedef WCHAR TCHAR;
-#define _T(x) L ## x
-#define _TEXT(x) L ## x
-#endif
-
-#else /* ANSI/OEM string */
-#ifndef _INC_TCHAR
-typedef char TCHAR;
-#define _T(x) x
-#define _TEXT(x) x
-#endif
-
-#endif
-
-
-
-/* File system object structure (FATFS) */
-
-typedef struct {
- BYTE fs_type; /* FAT sub-type (0:Not mounted) */
- BYTE drv; /* Physical drive number */
- BYTE csize; /* Sectors per cluster (1,2,4...128) */
- BYTE n_fats; /* Number of FAT copies (1,2) */
- BYTE wflag; /* win[] dirty flag (1:must be written back) */
- BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
- WORD id; /* File system mount ID */
- WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
-#if _MAX_SS != 512
- WORD ssize; /* Bytes per sector (512, 1024, 2048 or 4096) */
-#endif
-#if _FS_REENTRANT
- _SYNC_t sobj; /* Identifier of sync object */
-#endif
-#if !_FS_READONLY
- DWORD last_clust; /* Last allocated cluster */
- DWORD free_clust; /* Number of free clusters */
- DWORD fsi_sector; /* fsinfo sector (FAT32) */
-#endif
-#if _FS_RPATH
- DWORD cdir; /* Current directory start cluster (0:root) */
-#endif
- DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */
- DWORD fsize; /* Sectors per FAT */
- DWORD fatbase; /* FAT start sector */
- DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
- DWORD database; /* Data start sector */
- DWORD winsect; /* Current sector appearing in the win[] */
- BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */
-} FATFS;
-
-
-
-/* File object structure (FIL) */
-
-typedef struct {
- FATFS* fs; /* Pointer to the related file system object */
- WORD id; /* File system mount ID of the related file system object */
- BYTE flag; /* File status flags */
- BYTE pad1;
- DWORD fptr; /* File read/write pointer (0ed on file open) */
- DWORD fsize; /* File size */
- DWORD sclust; /* File data start cluster (0:no data cluster, always 0 when fsize is 0) */
- DWORD clust; /* Current cluster of fpter */
- DWORD dsect; /* Current data sector of fpter */
-#if !_FS_READONLY
- DWORD dir_sect; /* Sector containing the directory entry */
- BYTE* dir_ptr; /* Pointer to the directory entry in the window */
-#endif
-#if _USE_FASTSEEK
- DWORD* cltbl; /* Pointer to the cluster link map table (null on file open) */
-#endif
-#if _FS_LOCK
- UINT lockid; /* File lock ID (index of file semaphore table Files[]) */
-#endif
-#if !_FS_TINY
- BYTE buf[_MAX_SS]; /* File data read/write buffer */
-#endif
-} FIL;
-
-
-
-/* Directory object structure (DIR) */
-
-typedef struct {
- FATFS* fs; /* Pointer to the owner file system object */
- WORD id; /* Owner file system mount ID */
- WORD index; /* Current read/write index number */
- DWORD sclust; /* Table start cluster (0:Root dir) */
- DWORD clust; /* Current cluster */
- DWORD sect; /* Current sector */
- BYTE* dir; /* Pointer to the current SFN entry in the win[] */
- BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
-#if _USE_LFN
- WCHAR* lfn; /* Pointer to the LFN working buffer */
- WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
-#endif
-} DIR;
-
-
-
-/* File status structure (FILINFO) */
-
-typedef struct {
- DWORD fsize; /* File size */
- WORD fdate; /* Last modified date */
- WORD ftime; /* Last modified time */
- BYTE fattrib; /* Attribute */
- TCHAR fname[13]; /* Short file name (8.3 format) */
-#if _USE_LFN
- TCHAR* lfname; /* Pointer to the LFN buffer */
- UINT lfsize; /* Size of LFN buffer in TCHAR */
-#endif
-} FILINFO;
-
-
-
-/* File function return code (FRESULT) */
-
-typedef enum {
- FR_OK = 0, /* (0) Succeeded */
- FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
- FR_INT_ERR, /* (2) Assertion failed */
- FR_NOT_READY, /* (3) The physical drive cannot work */
- FR_NO_FILE, /* (4) Could not find the file */
- FR_NO_PATH, /* (5) Could not find the path */
- FR_INVALID_NAME, /* (6) The path name format is invalid */
- FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
- FR_EXIST, /* (8) Access denied due to prohibited access */
- FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
- FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
- FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
- FR_NOT_ENABLED, /* (12) The volume has no work area */
- FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
- FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
- FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
- FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
- FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
- FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_SHARE */
- FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
-} FRESULT;
-
-
-
-/*--------------------------------------------------------------*/
-/* FatFs module application interface */
-
-FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
-FRESULT f_open (FIL*, const TCHAR*, BYTE); /* Open or create a file */
-FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */
-FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
-FRESULT f_close (FIL*); /* Close an open file object */
-FRESULT f_opendir (DIR*, const TCHAR*); /* Open an existing directory */
-FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */
-FRESULT f_stat (const TCHAR*, FILINFO*); /* Get file status */
-FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */
-FRESULT f_getfree (const TCHAR*, DWORD*, FATFS**); /* Get number of free clusters on the drive */
-FRESULT f_truncate (FIL*); /* Truncate file */
-FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
-FRESULT f_unlink (const TCHAR*); /* Delete an existing file or directory */
-FRESULT f_mkdir (const TCHAR*); /* Create a new directory */
-FRESULT f_chmod (const TCHAR*, BYTE, BYTE); /* Change attribute of the file/dir */
-FRESULT f_utime (const TCHAR*, const FILINFO*); /* Change times-tamp of the file/dir */
-FRESULT f_rename (const TCHAR*, const TCHAR*); /* Rename/Move a file or directory */
-FRESULT f_chdrive (BYTE); /* Change current drive */
-FRESULT f_chdir (const TCHAR*); /* Change current directory */
-FRESULT f_getcwd (TCHAR*, UINT); /* Get current directory */
-FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */
-FRESULT f_mkfs (BYTE, BYTE, UINT); /* Create a file system on the drive */
-FRESULT f_fdisk (BYTE, const DWORD[], void*); /* Divide a physical drive into some partitions */
-int f_putc (TCHAR, FIL*); /* Put a character to the file */
-int f_puts (const TCHAR*, FIL*); /* Put a string to the file */
-int f_printf (FIL*, const TCHAR*, ...); /* Put a formatted string to the file */
-TCHAR* f_gets (TCHAR*, int, FIL*); /* Get a string from the file */
-
-#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)
-#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)
-#define f_tell(fp) ((fp)->fptr)
-#define f_size(fp) ((fp)->fsize)
-
-#ifndef EOF
-#define EOF (-1)
-#endif
-
-
-
-
-/*--------------------------------------------------------------*/
-/* Additional user defined functions */
-
-/* RTC function */
-#if !_FS_READONLY
-DWORD get_fattime (void);
-#endif
-
-/* Unicode support functions */
-#if _USE_LFN /* Unicode - OEM code conversion */
-WCHAR ff_convert (WCHAR, UINT); /* OEM-Unicode bidirectional conversion */
-WCHAR ff_wtoupper (WCHAR); /* Unicode upper-case conversion */
-#if _USE_LFN == 3 /* Memory functions */
-void* ff_memalloc (UINT); /* Allocate memory block */
-void ff_memfree (void*); /* Free memory block */
-#endif
-#endif
-
-/* Sync functions */
-#if _FS_REENTRANT
-int ff_cre_syncobj (BYTE, _SYNC_t*);/* Create a sync object */
-int ff_req_grant (_SYNC_t); /* Lock sync object */
-void ff_rel_grant (_SYNC_t); /* Unlock sync object */
-int ff_del_syncobj (_SYNC_t); /* Delete a sync object */
-#endif
-
-
-
-
-/*--------------------------------------------------------------*/
-/* Flags and offset address */
-
-
-/* File access control and file status flags (FIL.flag) */
-
-#define FA_READ 0x01
-#define FA_OPEN_EXISTING 0x00
-#define FA__ERROR 0x80
-
-#if !_FS_READONLY
-#define FA_WRITE 0x02
-#define FA_CREATE_NEW 0x04
-#define FA_CREATE_ALWAYS 0x08
-#define FA_OPEN_ALWAYS 0x10
-#define FA__WRITTEN 0x20
-#define FA__DIRTY 0x40
-#endif
-
-
-/* FAT sub type (FATFS.fs_type) */
-
-#define FS_FAT12 1
-#define FS_FAT16 2
-#define FS_FAT32 3
-
-
-/* File attribute bits for directory entry */
-
-#define AM_RDO 0x01 /* Read only */
-#define AM_HID 0x02 /* Hidden */
-#define AM_SYS 0x04 /* System */
-#define AM_VOL 0x08 /* Volume label */
-#define AM_LFN 0x0F /* LFN entry */
-#define AM_DIR 0x10 /* Directory */
-#define AM_ARC 0x20 /* Archive */
-#define AM_MASK 0x3F /* Mask of defined bits */
-
-
-/* Fast seek feature */
-#define CREATE_LINKMAP 0xFFFFFFFF
-
-
-
-/*--------------------------------*/
-/* Multi-byte word access macros */
-
-#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
-#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
-#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
-#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
-#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
-#else /* Use byte-by-byte access to the FAT structure */
-#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
-#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))
-#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)
-#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FATFS */
diff --git a/lib/lufa/Projects/Webserver/Lib/FATFs/ffconf.h b/lib/lufa/Projects/Webserver/Lib/FATFs/ffconf.h
deleted file mode 100644
index 243a20fa2..000000000
--- a/lib/lufa/Projects/Webserver/Lib/FATFs/ffconf.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/*---------------------------------------------------------------------------/
-/ FatFs - FAT file system module configuration file R0.09a (C)ChaN, 2012
-/----------------------------------------------------------------------------/
-/
-/ CAUTION! Do not forget to make clean the project after any changes to
-/ the configuration options.
-/
-/----------------------------------------------------------------------------*/
-#ifndef _FFCONF
-#define _FFCONF 4004 /* Revision ID */
-
-
-/*---------------------------------------------------------------------------/
-/ Function and Buffer Configurations
-/----------------------------------------------------------------------------*/
-
-#define _FS_TINY 1 /* 0:Normal or 1:Tiny */
-/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
-/ object instead of the sector buffer in the individual file object for file
-/ data transfer. This reduces memory consumption 512 bytes each file object. */
-
-
-#define _FS_READONLY 1 /* 0:Read/Write or 1:Read only */
-/* Setting _FS_READONLY to 1 defines read only configuration. This removes
-/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
-/ f_truncate and useless f_getfree. */
-
-
-#define _FS_MINIMIZE 2 /* 0 to 3 */
-/* The _FS_MINIMIZE option defines minimization level to remove some functions.
-/
-/ 0: Full function.
-/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
-/ are removed.
-/ 2: f_opendir and f_readdir are removed in addition to 1.
-/ 3: f_lseek is removed in addition to 2. */
-
-
-#define _USE_STRFUNC 0 /* 0:Disable or 1-2:Enable */
-/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
-
-
-#define _USE_MKFS 0 /* 0:Disable or 1:Enable */
-/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
-
-
-#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */
-/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
-
-
-#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */
-/* To enable fast seek feature, set _USE_FASTSEEK to 1. */
-
-
-
-/*---------------------------------------------------------------------------/
-/ Locale and Namespace Configurations
-/----------------------------------------------------------------------------*/
-
-#define _CODE_PAGE 932
-/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
-/ Incorrect setting of the code page can cause a file open failure.
-/
-/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows)
-/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
-/ 949 - Korean (DBCS, OEM, Windows)
-/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
-/ 1250 - Central Europe (Windows)
-/ 1251 - Cyrillic (Windows)
-/ 1252 - Latin 1 (Windows)
-/ 1253 - Greek (Windows)
-/ 1254 - Turkish (Windows)
-/ 1255 - Hebrew (Windows)
-/ 1256 - Arabic (Windows)
-/ 1257 - Baltic (Windows)
-/ 1258 - Vietnam (OEM, Windows)
-/ 437 - U.S. (OEM)
-/ 720 - Arabic (OEM)
-/ 737 - Greek (OEM)
-/ 775 - Baltic (OEM)
-/ 850 - Multilingual Latin 1 (OEM)
-/ 858 - Multilingual Latin 1 + Euro (OEM)
-/ 852 - Latin 2 (OEM)
-/ 855 - Cyrillic (OEM)
-/ 866 - Russian (OEM)
-/ 857 - Turkish (OEM)
-/ 862 - Hebrew (OEM)
-/ 874 - Thai (OEM, Windows)
-/ 1 - ASCII only (Valid for non LFN cfg.)
-*/
-
-
-#define _USE_LFN 0 /* 0 to 3 */
-#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
-/* The _USE_LFN option switches the LFN support.
-/
-/ 0: Disable LFN feature. _MAX_LFN and _LFN_UNICODE have no effect.
-/ 1: Enable LFN with static working buffer on the BSS. Always NOT reentrant.
-/ 2: Enable LFN with dynamic working buffer on the STACK.
-/ 3: Enable LFN with dynamic working buffer on the HEAP.
-/
-/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. To enable LFN,
-/ Unicode handling functions ff_convert() and ff_wtoupper() must be added
-/ to the project. When enable to use heap, memory control functions
-/ ff_memalloc() and ff_memfree() must be added to the project. */
-
-
-#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
-/* To switch the character code set on FatFs API to Unicode,
-/ enable LFN feature and set _LFN_UNICODE to 1. */
-
-
-#define _FS_RPATH 0 /* 0 to 2 */
-/* The _FS_RPATH option configures relative path feature.
-/
-/ 0: Disable relative path feature and remove related functions.
-/ 1: Enable relative path. f_chdrive() and f_chdir() are available.
-/ 2: f_getcwd() is available in addition to 1.
-/
-/ Note that output of the f_readdir function is affected by this option. */
-
-
-
-/*---------------------------------------------------------------------------/
-/ Physical Drive Configurations
-/----------------------------------------------------------------------------*/
-
-#define _VOLUMES 1
-/* Number of volumes (logical drives) to be used. */
-
-
-#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
-/* Maximum sector size to be handled.
-/ Always set 512 for memory card and hard disk but a larger value may be
-/ required for on-board flash memory, floppy disk and optical disk.
-/ When _MAX_SS is larger than 512, it configures FatFs to variable sector size
-/ and GET_SECTOR_SIZE command must be implemented to the disk_ioctl function. */
-
-
-#define _MULTI_PARTITION 0 /* 0:Single partition, 1/2:Enable multiple partition */
-/* When set to 0, each volume is bound to the same physical drive number and
-/ it can mount only first primary partition. When it is set to 1, each volume
-/ is tied to the partitions listed in VolToPart[]. */
-
-
-#define _USE_ERASE 0 /* 0:Disable or 1:Enable */
-/* To enable sector erase feature, set _USE_ERASE to 1. CTRL_ERASE_SECTOR command
-/ should be added to the disk_ioctl function. */
-
-
-
-/*---------------------------------------------------------------------------/
-/ System Configurations
-/----------------------------------------------------------------------------*/
-
-#define _WORD_ACCESS 1 /* 0 or 1 */
-/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS
-/ option defines which access method is used to the word data on the FAT volume.
-/
-/ 0: Byte-by-byte access.
-/ 1: Word access. Do not choose this unless following condition is met.
-/
-/ When the byte order on the memory is big-endian or address miss-aligned word
-/ access results incorrect behavior, the _WORD_ACCESS must be set to 0.
-/ If it is not the case, the value can also be set to 1 to improve the
-/ performance and code size. */
-
-
-/* A header file that defines sync object types on the O/S, such as
-/ windows.h, ucos_ii.h and semphr.h, must be included prior to ff.h. */
-
-#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */
-#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
-#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
-
-/* The _FS_REENTRANT option switches the reentrancy (thread safe) of the FatFs module.
-/
-/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect.
-/ 1: Enable reentrancy. Also user provided synchronization handlers,
-/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj
-/ function must be added to the project. */
-
-
-#define _FS_LOCK 0 /* 0:Disable or >=1:Enable */
-/* To enable file lock control feature, set _FS_LOCK to 1 or greater.
- The value defines how many files can be opened simultaneously. */
-
-
-#endif /* _FFCONFIG */
-
diff --git a/lib/lufa/Projects/Webserver/Lib/FATFs/integer.h b/lib/lufa/Projects/Webserver/Lib/FATFs/integer.h
deleted file mode 100644
index 5408fe6b3..000000000
--- a/lib/lufa/Projects/Webserver/Lib/FATFs/integer.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*-------------------------------------------*/
-/* Integer type definitions for FatFs module */
-/*-------------------------------------------*/
-
-#ifndef _INTEGER
-#define _INTEGER
-
-#ifdef _WIN32 /* FatFs development platform */
-
-#include <windows.h>
-#include <tchar.h>
-
-#else /* Embedded platform */
-
-/* These types must be 16-bit, 32-bit or larger integer */
-typedef int INT;
-typedef unsigned int UINT;
-
-/* These types must be 8-bit integer */
-typedef char CHAR;
-typedef unsigned char UCHAR;
-typedef unsigned char BYTE;
-
-/* These types must be 16-bit integer */
-typedef short SHORT;
-typedef unsigned short USHORT;
-typedef unsigned short WORD;
-typedef unsigned short WCHAR;
-
-/* These types must be 32-bit integer */
-typedef long LONG;
-typedef unsigned long ULONG;
-typedef unsigned long DWORD;
-
-#endif
-
-#endif
-
diff --git a/lib/lufa/Projects/Webserver/Lib/HTTPServerApp.c b/lib/lufa/Projects/Webserver/Lib/HTTPServerApp.c
deleted file mode 100644
index ba5ce8b99..000000000
--- a/lib/lufa/Projects/Webserver/Lib/HTTPServerApp.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Simple HTTP Webserver Application. When connected to the uIP stack,
- * this will serve out files to HTTP clients on port 80.
- */
-
-#define INCLUDE_FROM_HTTPSERVERAPP_C
-#include "HTTPServerApp.h"
-
-/** HTTP server response header, for transmission before the page contents. This indicates to the host that a page exists at the
- * given location, and gives extra connection information.
- */
-const char PROGMEM HTTP200Header[] = "HTTP/1.1 200 OK\r\n"
- "Server: LUFA " LUFA_VERSION_STRING "\r\n"
- "Connection: close\r\n"
- "MIME-version: 1.0\r\n"
- "Content-Type: ";
-
-/** HTTP server response header, for transmission before a resource not found error. This indicates to the host that the given
- * URL is invalid, and gives extra error information.
- */
-const char PROGMEM HTTP404Header[] = "HTTP/1.1 404 Not Found\r\n"
- "Server: LUFA " LUFA_VERSION_STRING "\r\n"
- "Connection: close\r\n"
- "MIME-version: 1.0\r\n"
- "Content-Type: text/plain\r\n\r\n"
- "Error 404: File Not Found: /";
-
-/** Default filename to fetch when a directory is requested */
-const char PROGMEM DefaultDirFileName[] = "index.htm";
-
-/** Default MIME type sent if no other MIME type can be determined. */
-const char PROGMEM DefaultMIMEType[] = "text/plain";
-
-/** List of MIME types for each supported file extension. */
-const MIME_Type_t MIMETypes[] =
- {
- {.Extension = "htm", .MIMEType = "text/html"},
- {.Extension = "jpg", .MIMEType = "image/jpeg"},
- {.Extension = "gif", .MIMEType = "image/gif"},
- {.Extension = "bmp", .MIMEType = "image/bmp"},
- {.Extension = "png", .MIMEType = "image/png"},
- {.Extension = "ico", .MIMEType = "image/x-icon"},
- {.Extension = "exe", .MIMEType = "application/octet-stream"},
- {.Extension = "gz", .MIMEType = "application/x-gzip"},
- {.Extension = "zip", .MIMEType = "application/zip"},
- {.Extension = "pdf", .MIMEType = "application/pdf"},
- };
-
-/** FATFs structure to hold the internal state of the FAT driver for the Dataflash contents. */
-FATFS DiskFATState;
-
-
-/** Initialization function for the simple HTTP webserver. */
-void HTTPServerApp_Init(void)
-{
- /* Listen on port 80 for HTTP connections from hosts */
- uip_listen(HTONS(HTTP_SERVER_PORT));
-
- /* Mount the Dataflash disk via FatFS */
- f_mount(0, &DiskFATState);
-}
-
-/** uIP stack application callback for the simple HTTP webserver. This function must be called each time the
- * TCP/IP stack needs a TCP packet to be processed.
- */
-void HTTPServerApp_Callback(void)
-{
- uip_tcp_appstate_t* const AppState = &uip_conn->appstate;
-
- if (uip_aborted() || uip_timedout() || uip_closed())
- {
- /* Lock to the closed state so that no further processing will occur on the connection */
- AppState->HTTPServer.CurrentState = WEBSERVER_STATE_Closing;
- AppState->HTTPServer.NextState = WEBSERVER_STATE_Closing;
- }
-
- if (uip_connected())
- {
- /* New connection - initialize connection state values */
- AppState->HTTPServer.CurrentState = WEBSERVER_STATE_OpenRequestedFile;
- AppState->HTTPServer.NextState = WEBSERVER_STATE_OpenRequestedFile;
- AppState->HTTPServer.FileOpen = false;
- AppState->HTTPServer.ACKedFilePos = 0;
- AppState->HTTPServer.SentChunkSize = 0;
- }
-
- if (uip_acked())
- {
- /* Add the amount of ACKed file data to the total sent file bytes counter */
- AppState->HTTPServer.ACKedFilePos += AppState->HTTPServer.SentChunkSize;
-
- /* Progress to the next state once the current state's data has been ACKed */
- AppState->HTTPServer.CurrentState = AppState->HTTPServer.NextState;
- }
-
- if (uip_rexmit())
- {
- /* Return file pointer to the last ACKed position */
- f_lseek(&AppState->HTTPServer.FileHandle, AppState->HTTPServer.ACKedFilePos);
- }
-
- if (uip_rexmit() || uip_acked() || uip_newdata() || uip_connected() || uip_poll())
- {
- switch (AppState->HTTPServer.CurrentState)
- {
- case WEBSERVER_STATE_OpenRequestedFile:
- HTTPServerApp_OpenRequestedFile();
- break;
- case WEBSERVER_STATE_SendResponseHeader:
- HTTPServerApp_SendResponseHeader();
- break;
- case WEBSERVER_STATE_SendData:
- HTTPServerApp_SendData();
- break;
- case WEBSERVER_STATE_Closing:
- /* Connection is being terminated for some reason - close file handle */
- f_close(&AppState->HTTPServer.FileHandle);
- AppState->HTTPServer.FileOpen = false;
-
- /* If connection is not already closed, close it */
- uip_close();
-
- AppState->HTTPServer.CurrentState = WEBSERVER_STATE_Closed;
- AppState->HTTPServer.NextState = WEBSERVER_STATE_Closed;
- break;
- }
- }
-}
-
-/** HTTP Server State handler for the Request Process state. This state manages the processing of incoming HTTP
- * GET requests to the server from the receiving HTTP client.
- */
-static void HTTPServerApp_OpenRequestedFile(void)
-{
- uip_tcp_appstate_t* const AppState = &uip_conn->appstate;
- char* const AppData = (char*)uip_appdata;
-
- /* No HTTP header received from the client, abort processing */
- if (!(uip_newdata()))
- return;
-
- char* RequestToken = strtok(AppData, " ");
- char* RequestedFileName = strtok(NULL, " ");
-
- /* Must be a GET request, abort otherwise */
- if (strcmp_P(RequestToken, PSTR("GET")) != 0)
- {
- uip_abort();
- return;
- }
-
- /* Copy over the requested filename */
- strlcpy(AppState->HTTPServer.FileName, &RequestedFileName[1], sizeof(AppState->HTTPServer.FileName));
-
- /* Determine the length of the URI so that it can be checked to see if it is a directory */
- uint8_t FileNameLen = strlen(AppState->HTTPServer.FileName);
-
- /* If the URI is a directory, append the default filename */
- if ((AppState->HTTPServer.FileName[FileNameLen - 1] == '/') || !(FileNameLen))
- {
- strlcpy_P(&AppState->HTTPServer.FileName[FileNameLen], DefaultDirFileName,
- (sizeof(AppState->HTTPServer.FileName) - FileNameLen));
- }
-
- /* Try to open the file from the Dataflash disk */
- AppState->HTTPServer.FileOpen = (f_open(&AppState->HTTPServer.FileHandle, AppState->HTTPServer.FileName,
- (FA_OPEN_EXISTING | FA_READ)) == FR_OK);
-
- /* Lock to the SendResponseHeader state until connection terminated */
- AppState->HTTPServer.CurrentState = WEBSERVER_STATE_SendResponseHeader;
- AppState->HTTPServer.NextState = WEBSERVER_STATE_SendResponseHeader;
-}
-
-/** HTTP Server State handler for the HTTP Response Header Send state. This state manages the transmission of
- * the HTTP response header to the receiving HTTP client.
- */
-static void HTTPServerApp_SendResponseHeader(void)
-{
- uip_tcp_appstate_t* const AppState = &uip_conn->appstate;
- char* const AppData = (char*)uip_appdata;
-
- char* Extension = strpbrk(AppState->HTTPServer.FileName, ".");
- bool FoundMIMEType = false;
-
- /* If the file isn't already open, it wasn't found - send back a 404 error response and abort */
- if (!(AppState->HTTPServer.FileOpen))
- {
- /* Copy over the HTTP 404 response header and send it to the receiving client */
- strcpy_P(AppData, HTTP404Header);
- strcat(AppData, AppState->HTTPServer.FileName);
- uip_send(AppData, strlen(AppData));
-
- AppState->HTTPServer.NextState = WEBSERVER_STATE_Closing;
- return;
- }
-
- /* Copy over the HTTP 200 response header and send it to the receiving client */
- strcpy_P(AppData, HTTP200Header);
-
- /* Check to see if a MIME type for the requested file's extension was found */
- if (Extension != NULL)
- {
- /* Look through the MIME type list, copy over the required MIME type if found */
- for (uint8_t i = 0; i < (sizeof(MIMETypes) / sizeof(MIMETypes[0])); i++)
- {
- if (strcmp(&Extension[1], MIMETypes[i].Extension) == 0)
- {
- strcat(AppData, MIMETypes[i].MIMEType);
- FoundMIMEType = true;
- break;
- }
- }
- }
-
- /* Check if a MIME type was found and copied to the output buffer */
- if (!(FoundMIMEType))
- {
- /* MIME type not found - copy over the default MIME type */
- strcat_P(AppData, DefaultMIMEType);
- }
-
- /* Add the end-of-line terminator and end-of-headers terminator after the MIME type */
- strcat_P(AppData, PSTR("\r\n\r\n"));
-
- /* Send the MIME header to the receiving client */
- uip_send(AppData, strlen(AppData));
-
- /* When the MIME header is ACKed, progress to the data send stage */
- AppState->HTTPServer.NextState = WEBSERVER_STATE_SendData;
-}
-
-/** HTTP Server State handler for the Data Send state. This state manages the transmission of file chunks
- * to the receiving HTTP client.
- */
-static void HTTPServerApp_SendData(void)
-{
- uip_tcp_appstate_t* const AppState = &uip_conn->appstate;
- char* const AppData = (char*)uip_appdata;
-
- /* Get the maximum segment size for the current packet */
- uint16_t MaxChunkSize = uip_mss();
-
- /* Read the next chunk of data from the open file */
- f_read(&AppState->HTTPServer.FileHandle, AppData, MaxChunkSize, &AppState->HTTPServer.SentChunkSize);
-
- /* Send the next file chunk to the receiving client */
- uip_send(AppData, AppState->HTTPServer.SentChunkSize);
-
- /* Check if we are at the last chunk of the file, if so next ACK should close the connection */
- if (MaxChunkSize != AppState->HTTPServer.SentChunkSize)
- AppState->HTTPServer.NextState = WEBSERVER_STATE_Closing;
-}
-
diff --git a/lib/lufa/Projects/Webserver/Lib/HTTPServerApp.h b/lib/lufa/Projects/Webserver/Lib/HTTPServerApp.h
deleted file mode 100644
index 11c39d87e..000000000
--- a/lib/lufa/Projects/Webserver/Lib/HTTPServerApp.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Header file for HTTPServerApp.c.
- */
-
-#ifndef _HTTPSERVER_APP_H_
-#define _HTTPSERVER_APP_H_
-
- /* Includes: */
- #include <avr/pgmspace.h>
- #include <string.h>
-
- #include <LUFA/Version.h>
-
- #include "Config/AppConfig.h"
-
- #include <uip.h>
- #include <ff.h>
-
- /* Enums: */
- /** States for each HTTP connection to the webserver. */
- enum Webserver_States_t
- {
- WEBSERVER_STATE_OpenRequestedFile, /**< Currently opening requested file */
- WEBSERVER_STATE_SendResponseHeader, /**< Currently sending HTTP response headers to the client */
- WEBSERVER_STATE_SendData, /**< Currently sending HTTP page data to the client */
- WEBSERVER_STATE_Closing, /**< Ready to close the connection to the client */
- WEBSERVER_STATE_Closed, /**< Connection closed after all data sent */
- };
-
- /* Type Defines: */
- /** Type define for a MIME type handler. */
- typedef struct
- {
- char* Extension; /**< File extension (no leading '.' character) */
- char* MIMEType; /**< Appropriate MIME type to send when the extension is encountered */
- } MIME_Type_t;
-
- /* Macros: */
- /** TCP listen port for incoming HTTP traffic. */
- #define HTTP_SERVER_PORT 80
-
- /* Function Prototypes: */
- void HTTPServerApp_Init(void);
- void HTTPServerApp_Callback(void);
-
- #if defined(INCLUDE_FROM_HTTPSERVERAPP_C)
- static void HTTPServerApp_OpenRequestedFile(void);
- static void HTTPServerApp_SendResponseHeader(void);
- static void HTTPServerApp_SendData(void);
- #endif
-
-#endif
-
diff --git a/lib/lufa/Projects/Webserver/Lib/SCSI.c b/lib/lufa/Projects/Webserver/Lib/SCSI.c
deleted file mode 100644
index 4fbbfd60e..000000000
--- a/lib/lufa/Projects/Webserver/Lib/SCSI.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * SCSI command processing routines, for SCSI commands issued by the host. Mass Storage
- * devices use a thin "Bulk-Only Transport" protocol for issuing commands and status information,
- * which wrap around standard SCSI device commands for controlling the actual storage medium.
- */
-
-#define INCLUDE_FROM_SCSI_C
-#include "SCSI.h"
-
-/** Structure to hold the SCSI response data to a SCSI INQUIRY command. This gives information about the device's
- * features and capabilities.
- */
-static const SCSI_Inquiry_Response_t InquiryData =
- {
- .DeviceType = DEVICE_TYPE_BLOCK,
- .PeripheralQualifier = 0,
-
- .Removable = true,
-
- .Version = 0,
-
- .ResponseDataFormat = 2,
- .NormACA = false,
- .TrmTsk = false,
- .AERC = false,
-
- .AdditionalLength = 0x1F,
-
- .SoftReset = false,
- .CmdQue = false,
- .Linked = false,
- .Sync = false,
- .WideBus16Bit = false,
- .WideBus32Bit = false,
- .RelAddr = false,
-
- .VendorID = "LUFA",
- .ProductID = "Dataflash Disk",
- .RevisionID = {'0','.','0','0'},
- };
-
-/** Structure to hold the sense data for the last issued SCSI command, which is returned to the host after a SCSI REQUEST SENSE
- * command is issued. This gives information on exactly why the last command failed to complete.
- */
-static SCSI_Request_Sense_Response_t SenseData =
- {
- .ResponseCode = 0x70,
- .AdditionalLength = 0x0A,
- };
-
-
-/** Main routine to process the SCSI command located in the Command Block Wrapper read from the host. This dispatches
- * to the appropriate SCSI command handling routine if the issued command is supported by the device, else it returns
- * a command failure due to a ILLEGAL REQUEST.
- *
- * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
- *
- * \return Boolean \c true if the command completed successfully, \c false otherwise
- */
-bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
-{
- bool CommandSuccess = false;
-
- /* Run the appropriate SCSI command hander function based on the passed command */
- switch (MSInterfaceInfo->State.CommandBlock.SCSICommandData[0])
- {
- case SCSI_CMD_INQUIRY:
- CommandSuccess = SCSI_Command_Inquiry(MSInterfaceInfo);
- break;
- case SCSI_CMD_REQUEST_SENSE:
- CommandSuccess = SCSI_Command_Request_Sense(MSInterfaceInfo);
- break;
- case SCSI_CMD_READ_CAPACITY_10:
- CommandSuccess = SCSI_Command_Read_Capacity_10(MSInterfaceInfo);
- break;
- case SCSI_CMD_SEND_DIAGNOSTIC:
- CommandSuccess = SCSI_Command_Send_Diagnostic(MSInterfaceInfo);
- break;
- case SCSI_CMD_WRITE_10:
- CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE);
- break;
- case SCSI_CMD_READ_10:
- CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_READ);
- break;
- case SCSI_CMD_MODE_SENSE_6:
- CommandSuccess = SCSI_Command_ModeSense_6(MSInterfaceInfo);
- break;
- case SCSI_CMD_START_STOP_UNIT:
- case SCSI_CMD_TEST_UNIT_READY:
- case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
- case SCSI_CMD_VERIFY_10:
- /* These commands should just succeed, no handling required */
- CommandSuccess = true;
- MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0;
- break;
- default:
- /* Update the SENSE key to reflect the invalid command */
- SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
- SCSI_ASENSE_INVALID_COMMAND,
- SCSI_ASENSEQ_NO_QUALIFIER);
- break;
- }
-
- /* Check if command was successfully processed */
- if (CommandSuccess)
- {
- SCSI_SET_SENSE(SCSI_SENSE_KEY_GOOD,
- SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
- SCSI_ASENSEQ_NO_QUALIFIER);
-
- return true;
- }
-
- return false;
-}
-
-/** Command processing for an issued SCSI INQUIRY command. This command returns information about the device's features
- * and capabilities to the host.
- *
- * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
- *
- * \return Boolean \c true if the command completed successfully, \c false otherwise.
- */
-static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
-{
- uint16_t AllocationLength = SwapEndian_16(*(uint16_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[3]);
- uint16_t BytesTransferred = MIN(AllocationLength, sizeof(InquiryData));
-
- /* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */
- if ((MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) ||
- MSInterfaceInfo->State.CommandBlock.SCSICommandData[2])
- {
- /* Optional but unsupported bits set - update the SENSE key and fail the request */
- SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
- SCSI_ASENSE_INVALID_FIELD_IN_CDB,
- SCSI_ASENSEQ_NO_QUALIFIER);
-
- return false;
- }
-
- Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, NULL);
-
- /* Pad out remaining bytes with 0x00 */
- Endpoint_Null_Stream((AllocationLength - BytesTransferred), NULL);
-
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearIN();
-
- /* Succeed the command and update the bytes transferred counter */
- MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
-
- return true;
-}
-
-/** Command processing for an issued SCSI REQUEST SENSE command. This command returns information about the last issued command,
- * including the error code and additional error information so that the host can determine why a command failed to complete.
- *
- * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
- *
- * \return Boolean \c true if the command completed successfully, \c false otherwise.
- */
-static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
-{
- uint8_t AllocationLength = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4];
- uint8_t BytesTransferred = MIN(AllocationLength, sizeof(SenseData));
-
- Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NULL);
- Endpoint_Null_Stream((AllocationLength - BytesTransferred), NULL);
- Endpoint_ClearIN();
-
- /* Succeed the command and update the bytes transferred counter */
- MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
-
- return true;
-}
-
-/** Command processing for an issued SCSI READ CAPACITY (10) command. This command returns information about the device's capacity
- * on the selected Logical Unit (drive), as a number of OS-sized blocks.
- *
- * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
- *
- * \return Boolean \c true if the command completed successfully, \c false otherwise.
- */
-static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
-{
- uint32_t LastBlockAddressInLUN = (VIRTUAL_MEMORY_BLOCKS - 1);
- uint32_t MediaBlockSize = VIRTUAL_MEMORY_BLOCK_SIZE;
-
- Endpoint_Write_Stream_BE(&LastBlockAddressInLUN, sizeof(LastBlockAddressInLUN), NULL);
- Endpoint_Write_Stream_BE(&MediaBlockSize, sizeof(MediaBlockSize), NULL);
- Endpoint_ClearIN();
-
- /* Succeed the command and update the bytes transferred counter */
- MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 8;
-
- return true;
-}
-
-/** Command processing for an issued SCSI SEND DIAGNOSTIC command. This command performs a quick check of the Dataflash ICs on the
- * board, and indicates if they are present and functioning correctly. Only the Self-Test portion of the diagnostic command is
- * supported.
- *
- * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
- *
- * \return Boolean \c true if the command completed successfully, \c false otherwise.
- */
-static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
-{
- /* Check to see if the SELF TEST bit is not set */
- if (!(MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & (1 << 2)))
- {
- /* Only self-test supported - update SENSE key and fail the command */
- SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
- SCSI_ASENSE_INVALID_FIELD_IN_CDB,
- SCSI_ASENSEQ_NO_QUALIFIER);
-
- return false;
- }
-
- /* Check to see if all attached Dataflash ICs are functional */
- if (!(DataflashManager_CheckDataflashOperation()))
- {
- /* Update SENSE key with a hardware error condition and return command fail */
- SCSI_SET_SENSE(SCSI_SENSE_KEY_HARDWARE_ERROR,
- SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
- SCSI_ASENSEQ_NO_QUALIFIER);
-
- return false;
- }
-
- /* Succeed the command and update the bytes transferred counter */
- MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0;
-
- return true;
-}
-
-/** Command processing for an issued SCSI READ (10) or WRITE (10) command. This command reads in the block start address
- * and total number of blocks to process, then calls the appropriate low-level Dataflash routine to handle the actual
- * reading and writing of the data.
- *
- * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
- * \param[in] IsDataRead Indicates if the command is a READ (10) command or WRITE (10) command (DATA_READ or DATA_WRITE)
- *
- * \return Boolean \c true if the command completed successfully, \c false otherwise.
- */
-static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
- const bool IsDataRead)
-{
- uint32_t BlockAddress;
- uint16_t TotalBlocks;
-
- /* Check if the disk is write protected or not */
- if ((IsDataRead == DATA_WRITE) && DISK_READ_ONLY)
- {
- /* Block address is invalid, update SENSE key and return command fail */
- SCSI_SET_SENSE(SCSI_SENSE_KEY_DATA_PROTECT,
- SCSI_ASENSE_WRITE_PROTECTED,
- SCSI_ASENSEQ_NO_QUALIFIER);
-
- return false;
- }
-
- /* Load in the 32-bit block address (SCSI uses big-endian, so have to reverse the byte order) */
- BlockAddress = SwapEndian_32(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]);
-
- /* Load in the 16-bit total blocks (SCSI uses big-endian, so have to reverse the byte order) */
- TotalBlocks = SwapEndian_16(*(uint16_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]);
-
- /* Check if the block address is outside the maximum allowable value for the LUN */
- if (BlockAddress >= VIRTUAL_MEMORY_BLOCKS)
- {
- /* Block address is invalid, update SENSE key and return command fail */
- SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
- SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
- SCSI_ASENSEQ_NO_QUALIFIER);
-
- return false;
- }
-
- /* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */
- if (IsDataRead == DATA_READ)
- DataflashManager_ReadBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
- else
- DataflashManager_WriteBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
-
- /* Update the bytes transferred counter and succeed the command */
- MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);
-
- return true;
-}
-
-/** Command processing for an issued SCSI MODE SENSE (6) command. This command returns various informational pages about
- * the SCSI device, as well as the device's Write Protect status.
- *
- * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
- *
- * \return Boolean \c true if the command completed successfully, \c false otherwise.
- */
-static bool SCSI_Command_ModeSense_6(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
-{
- /* Send an empty header response with the Write Protect flag status */
- Endpoint_Write_8(0x00);
- Endpoint_Write_8(0x00);
- Endpoint_Write_8(DISK_READ_ONLY ? 0x80 : 0x00);
- Endpoint_Write_8(0x00);
- Endpoint_ClearIN();
-
- /* Update the bytes transferred counter and succeed the command */
- MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 4;
-
- return true;
-}
-
diff --git a/lib/lufa/Projects/Webserver/Lib/SCSI.h b/lib/lufa/Projects/Webserver/Lib/SCSI.h
deleted file mode 100644
index 8f41f63b4..000000000
--- a/lib/lufa/Projects/Webserver/Lib/SCSI.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Header file for SCSI.c.
- */
-
-#ifndef _SCSI_H_
-#define _SCSI_H_
-
- /* Includes: */
- #include <avr/io.h>
- #include <avr/pgmspace.h>
-
- #include <LUFA/Drivers/USB/USB.h>
-
- #include "../Descriptors.h"
- #include "DataflashManager.h"
-
- /* Macros: */
- /** Macro to set the current SCSI sense data to the given key, additional sense code and additional sense qualifier. This
- * is for convenience, as it allows for all three sense values (returned upon request to the host to give information about
- * the last command failure) in a quick and easy manner.
- *
- * \param[in] Key New SCSI sense key to set the sense code to
- * \param[in] Acode New SCSI additional sense key to set the additional sense code to
- * \param[in] Aqual New SCSI additional sense key qualifier to set the additional sense qualifier code to
- */
- #define SCSI_SET_SENSE(Key, Acode, Aqual) do { SenseData.SenseKey = (Key); \
- SenseData.AdditionalSenseCode = (Acode); \
- SenseData.AdditionalSenseQualifier = (Aqual); } while (0)
-
- /** Macro for the \ref SCSI_Command_ReadWrite_10() function, to indicate that data is to be read from the storage medium. */
- #define DATA_READ true
-
- /** Macro for the \ref SCSI_Command_ReadWrite_10() function, to indicate that data is to be written to the storage medium. */
- #define DATA_WRITE false
-
- /** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a Block Media device. */
- #define DEVICE_TYPE_BLOCK 0x00
-
- /** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */
- #define DEVICE_TYPE_CDROM 0x05
-
- /* Function Prototypes: */
- bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
-
- #if defined(INCLUDE_FROM_SCSI_C)
- static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
- static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
- static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
- static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
- static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
- const bool IsDataRead);
- static bool SCSI_Command_ModeSense_6(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
- #endif
-
-#endif
-
diff --git a/lib/lufa/Projects/Webserver/Lib/TELNETServerApp.c b/lib/lufa/Projects/Webserver/Lib/TELNETServerApp.c
deleted file mode 100644
index 4500a4b78..000000000
--- a/lib/lufa/Projects/Webserver/Lib/TELNETServerApp.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * TELNET Webserver Application. When connected to the uIP stack,
- * this will serve out raw TELNET to the client on port 23.
- */
-
-#define INCLUDE_FROM_TELNETSERVERAPP_C
-#include "TELNETServerApp.h"
-
-#if defined(ENABLE_TELNET_SERVER) || defined(__DOXYGEN__)
-
-/** Welcome message to send to a TELNET client when a connection is first made. */
-const char PROGMEM WelcomeHeader[] = "********************************************\r\n"
- "* LUFA uIP Webserver (TELNET) *\r\n"
- "********************************************\r\n";
-
-/** Main TELNET menu, giving the user the list of available commands they may issue */
-const char PROGMEM TELNETMenu[] = "\r\n"
- " == Available Commands: ==\r\n"
- " c) List Active TCP Connections\r\n"
- " =========================\r\n"
- "\r\n>";
-
-/** Header to print before the current connections are printed to the client */
-const char PROGMEM CurrentConnectionsHeader[] = "\r\n* Current TCP Connections: *\r\n";
-
-/** Initialization function for the simple TELNET webserver. */
-void TELNETServerApp_Init(void)
-{
- /* Listen on port 23 for TELNET connections from hosts */
- uip_listen(HTONS(TELNET_SERVER_PORT));
-}
-
-/** uIP stack application callback for the TELNET server. This function must be called each time the
- * TCP/IP stack needs a TCP packet to be processed.
- */
-void TELNETServerApp_Callback(void)
-{
- uip_tcp_appstate_t* const AppState = &uip_conn->appstate;
- char* const AppData = (char*)uip_appdata;
-
- if (uip_connected())
- {
- /* New connection - initialize connection state values */
- AppState->TELNETServer.CurrentState = TELNET_STATE_SendHeader;
- }
-
- if (uip_acked())
- {
- /* Progress to the next state once the current state's data has been ACKed */
- AppState->TELNETServer.CurrentState = AppState->TELNETServer.NextState;
- }
-
- if (uip_rexmit() || uip_acked() || uip_newdata() || uip_connected() || uip_poll())
- {
- switch (AppState->TELNETServer.CurrentState)
- {
- case TELNET_STATE_SendHeader:
- /* Copy over and send the TELNET welcome message upon first connection */
- strcpy_P(AppData, WelcomeHeader);
- uip_send(AppData, strlen(AppData));
-
- AppState->TELNETServer.NextState = TELNET_STATE_SendMenu;
- break;
- case TELNET_STATE_SendMenu:
- /* Copy over and send the TELNET menu to the client */
- strcpy_P(AppData, TELNETMenu);
- uip_send(AppData, strlen(AppData));
-
- AppState->TELNETServer.NextState = TELNET_STATE_GetCommand;
- break;
- case TELNET_STATE_GetCommand:
- if (!(uip_datalen()))
- break;
-
- /* Save the issued command for later processing */
- AppState->TELNETServer.IssuedCommand = AppData[0];
-
- AppState->TELNETServer.CurrentState = TELNET_STATE_SendResponse;
- break;
- case TELNET_STATE_SendResponse:
- /* Determine which command was issued, perform command processing */
- switch (AppState->TELNETServer.IssuedCommand)
- {
- case 'c':
- TELNETServerApp_DisplayTCPConnections();
- break;
- default:
- strcpy_P(AppData, PSTR("Invalid Command.\r\n"));
- uip_send(AppData, strlen(AppData));
- break;
- }
-
- AppState->TELNETServer.NextState = TELNET_STATE_SendMenu;
- break;
- }
- }
-}
-
-/** Sends a list of active TCP connections to the TELNET client. */
-static void TELNETServerApp_DisplayTCPConnections(void)
-{
- char* const AppData = (char*)uip_appdata;
-
- strcpy_P(AppData, CurrentConnectionsHeader);
-
- uint16_t ResponseLen = strlen(AppData);
- uint8_t ActiveConnCount = 0;
-
- /* Loop through the complete uIP TCP connections list, looking for active connections */
- for (uint8_t i = 0; i < UIP_CONNS; i++)
- {
- struct uip_conn* CurrConnection = &uip_conns[i];
-
- /* If the connection is not closed, it is active and must be added to the out buffer */
- if (CurrConnection->tcpstateflags != UIP_CLOSED)
- {
- /* Add the current connection's details to the out buffer */
- ResponseLen += sprintf_P(&AppData[ResponseLen], PSTR("%u) %d.%d.%d.%d (Local Port %u <=> Remote Port %u)\r\n"),
- ++ActiveConnCount,
- CurrConnection->ripaddr.u8[0],
- CurrConnection->ripaddr.u8[1],
- CurrConnection->ripaddr.u8[2],
- CurrConnection->ripaddr.u8[3],
- HTONS(CurrConnection->lport), HTONS(CurrConnection->rport));
- }
- }
-
- uip_send(AppData, ResponseLen);
-}
-
-#endif
-
diff --git a/lib/lufa/Projects/Webserver/Lib/TELNETServerApp.h b/lib/lufa/Projects/Webserver/Lib/TELNETServerApp.h
deleted file mode 100644
index 67301ba09..000000000
--- a/lib/lufa/Projects/Webserver/Lib/TELNETServerApp.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Header file for TELNETServerApp.c.
- */
-
-#ifndef _TELNETSERVER_APP_H_
-#define _TELNETSERVER_APP_H_
-
- /* Includes: */
- #include <avr/pgmspace.h>
- #include <string.h>
- #include <stdio.h>
-
- #include <uip.h>
-
- #include "Config/AppConfig.h"
-
- /* Macros: */
- /** TCP listen port for incoming TELNET traffic. */
- #define TELNET_SERVER_PORT 23
-
- /* Enums: */
- /** States for each TELNET connection to the server. */
- enum TELNET_States_t
- {
- TELNET_STATE_SendHeader, /**< Currently sending welcome header to the client */
- TELNET_STATE_SendMenu, /**< Currently sending the command list menu to the client */
- TELNET_STATE_GetCommand, /**< Currently waiting for a command from the client */
- TELNET_STATE_SendResponse, /**< Processing the issued command and sending a response */
- };
-
- /* Function Prototypes: */
- void TELNETServerApp_Init(void);
- void TELNETServerApp_Callback(void);
-
- #if defined(INCLUDE_FROM_TELNETSERVERAPP_C)
- static void TELNETServerApp_DisplayTCPConnections(void);
- #endif
-
-#endif
-
diff --git a/lib/lufa/Projects/Webserver/Lib/uIPManagement.c b/lib/lufa/Projects/Webserver/Lib/uIPManagement.c
deleted file mode 100644
index 12f6c8f9e..000000000
--- a/lib/lufa/Projects/Webserver/Lib/uIPManagement.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * uIP Management functions. This file contains the functions and globals needed to maintain the uIP
- * stack once an RNDIS device has been attached to the system.
- */
-
-#define INCLUDE_FROM_UIPMANAGEMENT_C
-#include "uIPManagement.h"
-
-/** Connection timer, to retain the time elapsed since the last time the uIP connections were managed. */
-static struct timer ConnectionTimer;
-
-/** ARP timer, to retain the time elapsed since the ARP cache was last updated. */
-static struct timer ARPTimer;
-
-/** MAC address of the RNDIS device, when enumerated. */
-struct uip_eth_addr MACAddress;
-
-
-/** Configures the uIP stack ready for network traffic processing. */
-void uIPManagement_Init(void)
-{
- /* uIP Timing Initialization */
- clock_init();
- timer_set(&ConnectionTimer, CLOCK_SECOND / 2);
- timer_set(&ARPTimer, CLOCK_SECOND * 10);
-
- /* uIP Stack Initialization */
- uip_init();
- uip_arp_init();
-
- /* DHCP/Server IP Settings Initialization */
- if (USB_CurrentMode == USB_MODE_Device)
- {
- MACAddress.addr[0] = SERVER_MAC_ADDRESS[0];
- MACAddress.addr[1] = SERVER_MAC_ADDRESS[1];
- MACAddress.addr[2] = SERVER_MAC_ADDRESS[2];
- MACAddress.addr[3] = SERVER_MAC_ADDRESS[3];
- MACAddress.addr[4] = SERVER_MAC_ADDRESS[4];
- MACAddress.addr[5] = SERVER_MAC_ADDRESS[5];
-
- #if defined(ENABLE_DHCP_SERVER)
- DHCPServerApp_Init();
- #endif
-
- uip_ipaddr_t IPAddress, Netmask, GatewayIPAddress;
- uip_ipaddr(&IPAddress, DEVICE_IP_ADDRESS[0], DEVICE_IP_ADDRESS[1], DEVICE_IP_ADDRESS[2], DEVICE_IP_ADDRESS[3]);
- uip_ipaddr(&Netmask, DEVICE_NETMASK[0], DEVICE_NETMASK[1], DEVICE_NETMASK[2], DEVICE_NETMASK[3]);
- uip_ipaddr(&GatewayIPAddress, DEVICE_GATEWAY[0], DEVICE_GATEWAY[1], DEVICE_GATEWAY[2], DEVICE_GATEWAY[3]);
- uip_sethostaddr(&IPAddress);
- uip_setnetmask(&Netmask);
- uip_setdraddr(&GatewayIPAddress);
- }
- else
- {
- #if defined(ENABLE_DHCP_CLIENT)
- DHCPClientApp_Init();
- #else
- uip_ipaddr_t IPAddress, Netmask, GatewayIPAddress;
- uip_ipaddr(&IPAddress, DEVICE_IP_ADDRESS[0], DEVICE_IP_ADDRESS[1], DEVICE_IP_ADDRESS[2], DEVICE_IP_ADDRESS[3]);
- uip_ipaddr(&Netmask, DEVICE_NETMASK[0], DEVICE_NETMASK[1], DEVICE_NETMASK[2], DEVICE_NETMASK[3]);
- uip_ipaddr(&GatewayIPAddress, DEVICE_GATEWAY[0], DEVICE_GATEWAY[1], DEVICE_GATEWAY[2], DEVICE_GATEWAY[3]);
- uip_sethostaddr(&IPAddress);
- uip_setnetmask(&Netmask);
- uip_setdraddr(&GatewayIPAddress);
- #endif
- }
-
- /* Virtual Webserver Ethernet Address Configuration */
- uip_setethaddr(MACAddress);
-
- /* HTTP Webserver Initialization */
- HTTPServerApp_Init();
-
- /* TELNET Server Initialization */
- #if defined(ENABLE_TELNET_SERVER)
- TELNETServerApp_Init();
- #endif
-}
-
-/** uIP Management function. This function manages the uIP stack when called while an RNDIS device has been
- * attached to the system.
- */
-void uIPManagement_ManageNetwork(void)
-{
- if (((USB_CurrentMode == USB_MODE_Host) && (USB_HostState == HOST_STATE_Configured)) ||
- ((USB_CurrentMode == USB_MODE_Device) && (USB_DeviceState == DEVICE_STATE_Configured)))
- {
- uIPManagement_ProcessIncomingPacket();
- uIPManagement_ManageConnections();
- }
-}
-
-/** uIP TCP/IP network stack callback function for the processing of a given TCP connection. This routine dispatches
- * to the appropriate TCP protocol application based on the connection's listen port number.
- */
-void uIPManagement_TCPCallback(void)
-{
- /* Call the correct TCP application based on the port number the connection is listening on */
- switch (uip_conn->lport)
- {
- case HTONS(HTTP_SERVER_PORT):
- HTTPServerApp_Callback();
- break;
- #if defined(ENABLE_TELNET_SERVER)
- case HTONS(TELNET_SERVER_PORT):
- TELNETServerApp_Callback();
- break;
- #endif
- }
-}
-
-/** uIP TCP/IP network stack callback function for the processing of a given UDP connection. This routine dispatches
- * to the appropriate UDP protocol application based on the connection's listen port number.
- */
-void uIPManagement_UDPCallback(void)
-{
- /* Call the correct UDP application based on the port number the connection is listening on */
- switch (uip_udp_conn->lport)
- {
- #if defined(ENABLE_DHCP_CLIENT)
- case HTONS(DHCP_CLIENT_PORT):
- DHCPClientApp_Callback();
- break;
- #endif
- #if defined(ENABLE_DHCP_SERVER)
- case HTONS(DHCP_SERVER_PORT):
- DHCPServerApp_Callback();
- break;
- #endif
- }
-}
-
-/** Processes Incoming packets to the server from the connected RNDIS device, creating responses as needed. */
-static void uIPManagement_ProcessIncomingPacket(void)
-{
- /* Determine which USB mode the system is currently initialized in */
- if (USB_CurrentMode == USB_MODE_Device)
- {
- /* If no packet received, exit processing routine */
- if (!(RNDIS_Device_IsPacketReceived(&Ethernet_RNDIS_Interface_Device)))
- return;
-
- LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
-
- /* Read the Incoming packet straight into the UIP packet buffer */
- RNDIS_Device_ReadPacket(&Ethernet_RNDIS_Interface_Device, uip_buf, &uip_len);
- }
- else
- {
- /* If no packet received, exit processing routine */
- if (!(RNDIS_Host_IsPacketReceived(&Ethernet_RNDIS_Interface_Host)))
- return;
-
- LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
-
- /* Read the Incoming packet straight into the UIP packet buffer */
- RNDIS_Host_ReadPacket(&Ethernet_RNDIS_Interface_Host, uip_buf, &uip_len);
- }
-
- /* If the packet contains an Ethernet frame, process it */
- if (uip_len > 0)
- {
- switch (((struct uip_eth_hdr*)uip_buf)->type)
- {
- case HTONS(UIP_ETHTYPE_IP):
- /* Filter packet by MAC destination */
- uip_arp_ipin();
-
- /* Process Incoming packet */
- uip_input();
-
- /* If a response was generated, send it */
- if (uip_len > 0)
- {
- /* Add destination MAC to outgoing packet */
- uip_arp_out();
-
- uip_split_output();
- }
-
- break;
- case HTONS(UIP_ETHTYPE_ARP):
- /* Process ARP packet */
- uip_arp_arpin();
-
- /* If a response was generated, send it */
- if (uip_len > 0)
- uip_split_output();
-
- break;
- }
- }
-
- LEDs_SetAllLEDs(LEDMASK_USB_READY);
-}
-
-/** Manages the currently open network connections, including TCP and (if enabled) UDP. */
-static void uIPManagement_ManageConnections(void)
-{
- /* Poll TCP connections for more data to send back to the host */
- for (uint8_t i = 0; i < UIP_CONNS; i++)
- {
- uip_poll_conn(&uip_conns[i]);
-
- /* If a response was generated, send it */
- if (uip_len > 0)
- {
- /* Add destination MAC to outgoing packet */
- uip_arp_out();
-
- /* Split and send the outgoing packet */
- uip_split_output();
- }
- }
-
- /* Manage open connections for timeouts */
- if (timer_expired(&ConnectionTimer))
- {
- timer_reset(&ConnectionTimer);
-
- LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
-
- for (uint8_t i = 0; i < UIP_CONNS; i++)
- {
- /* Run periodic connection management for each TCP connection */
- uip_periodic(i);
-
- /* If a response was generated, send it */
- if (uip_len > 0)
- {
- /* Add destination MAC to outgoing packet */
- uip_arp_out();
-
- /* Split and send the outgoing packet */
- uip_split_output();
- }
- }
-
- #if defined(ENABLE_DHCP_CLIENT)
- for (uint8_t i = 0; i < UIP_UDP_CONNS; i++)
- {
- /* Run periodic connection management for each UDP connection */
- uip_udp_periodic(i);
-
- /* If a response was generated, send it */
- if (uip_len > 0)
- {
- /* Add destination MAC to outgoing packet */
- uip_arp_out();
-
- /* Split and send the outgoing packet */
- uip_split_output();
- }
- }
- #endif
-
- LEDs_SetAllLEDs(LEDMASK_USB_READY);
- }
-
- /* Manage ARP cache refreshing */
- if (timer_expired(&ARPTimer))
- {
- timer_reset(&ARPTimer);
- uip_arp_timer();
- }
-}
-
diff --git a/lib/lufa/Projects/Webserver/Lib/uIPManagement.h b/lib/lufa/Projects/Webserver/Lib/uIPManagement.h
deleted file mode 100644
index 3bdc5c96b..000000000
--- a/lib/lufa/Projects/Webserver/Lib/uIPManagement.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Header file for uIPManagement.c.
- */
-
-#ifndef _UIP_MANAGEMENT_H_
-#define _UIP_MANAGEMENT_H_
-
- /* Includes: */
- #include <LUFA/Drivers/USB/USB.h>
-
- #include <uip.h>
- #include <uip_arp.h>
- #include <uip-split.h>
- #include <timer.h>
-
- #include "Config/AppConfig.h"
-
- #include "DHCPClientApp.h"
- #include "DHCPServerApp.h"
- #include "HTTPServerApp.h"
- #include "TELNETServerApp.h"
-
- /* External Variables: */
- extern struct uip_eth_addr MACAddress;
-
- /* Function Prototypes: */
- void uIPManagement_Init(void);
- void uIPManagement_ManageNetwork(void);
- void uIPManagement_TCPCallback(void);
- void uIPManagement_UDPCallback(void);
-
- #if defined(INCLUDE_FROM_UIPMANAGEMENT_C)
- static void uIPManagement_ProcessIncomingPacket(void);
- static void uIPManagement_ManageConnections(void);
- #endif
-
-#endif
-
diff --git a/lib/lufa/Projects/Webserver/Lib/uip/clock.c b/lib/lufa/Projects/Webserver/Lib/uip/clock.c
deleted file mode 100644
index e71f7209d..000000000
--- a/lib/lufa/Projects/Webserver/Lib/uip/clock.c
+++ /dev/null
@@ -1,37 +0,0 @@
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <LUFA/Common/Common.h>
-
-#include "clock.h"
-
-//Counted time
-volatile clock_time_t clock_datetime = 0;
-
-//Overflow interrupt
-ISR(TIMER1_COMPA_vect, ISR_BLOCK)
-{
- clock_datetime += 1;
-}
-
-//Initialise the clock
-void clock_init()
-{
- OCR1A = (((F_CPU / 1024) / 100) - 1);
- TCCR1B = ((1 << WGM12) | (1 << CS12) | (1 << CS10));
- TIMSK1 = (1 << OCIE1A);
-}
-
-//Return time
-clock_time_t clock_time()
-{
- clock_time_t time;
-
- GlobalInterruptDisable();
- time = clock_datetime;
- GlobalInterruptEnable();
-
- return time;
-}
-
diff --git a/lib/lufa/Projects/Webserver/Lib/uip/clock.h b/lib/lufa/Projects/Webserver/Lib/uip/clock.h
deleted file mode 100644
index bbfa4ac0e..000000000
--- a/lib/lufa/Projects/Webserver/Lib/uip/clock.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __CLOCK_ARCH_H__
-#define __CLOCK_ARCH_H__
-
-#include <stdint.h>
-#include <util/atomic.h>
-
-typedef uint16_t clock_time_t;
-#define CLOCK_SECOND 100
-void clock_init(void);
-clock_time_t clock_time(void);
-
-#endif /* __CLOCK_ARCH_H__ */
-
diff --git a/lib/lufa/Projects/Webserver/Lib/uip/timer.c b/lib/lufa/Projects/Webserver/Lib/uip/timer.c
deleted file mode 100644
index eae06f43b..000000000
--- a/lib/lufa/Projects/Webserver/Lib/uip/timer.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * \addtogroup timer
- * @{
- */
-
-/**
- * \file
- * Timer library implementation.
- * \author
- * Adam Dunkels <adam@sics.se>
- */
-
-/*
- * Copyright (c) 2004, Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Institute nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file is part of the uIP TCP/IP stack
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- * $Id: timer.c,v 1.2 2006/06/12 08:00:30 adam Exp $
- */
-
-#include "clock.h"
-#include "timer.h"
-
-/*---------------------------------------------------------------------------*/
-/**
- * Set a timer.
- *
- * This function is used to set a timer for a time sometime in the
- * future. The function timer_expired() will evaluate to true after
- * the timer has expired.
- *
- * \param t A pointer to the timer
- * \param interval The interval before the timer expires.
- *
- */
-void
-timer_set(struct timer *t, clock_time_t interval)
-{
- t->interval = interval;
- t->start = clock_time();
-}
-/*---------------------------------------------------------------------------*/
-/**
- * Reset the timer with the same interval.
- *
- * This function resets the timer with the same interval that was
- * given to the timer_set() function. The start point of the interval
- * is the exact time that the timer last expired. Therefore, this
- * function will cause the timer to be stable over time, unlike the
- * timer_restart() function.
- *
- * \param t A pointer to the timer.
- *
- * \sa timer_restart()
- */
-void
-timer_reset(struct timer *t)
-{
- t->start += t->interval;
-}
-/*---------------------------------------------------------------------------*/
-/**
- * Restart the timer from the current point in time
- *
- * This function restarts a timer with the same interval that was
- * given to the timer_set() function. The timer will start at the
- * current time.
- *
- * \note A periodic timer will drift if this function is used to reset
- * it. For periodic timers, use the timer_reset() function instead.
- *
- * \param t A pointer to the timer.
- *
- * \sa timer_reset()
- */
-void
-timer_restart(struct timer *t)
-{
- t->start = clock_time();
-}
-/*---------------------------------------------------------------------------*/
-/**
- * Check if a timer has expired.
- *
- * This function tests if a timer has expired and returns true or
- * false depending on its status.
- *
- * \param t A pointer to the timer
- *
- * \return Non-zero if the timer has expired, zero otherwise.
- *
- */
-int
-timer_expired(struct timer *t)
-{
- return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval;
-}
-/*---------------------------------------------------------------------------*/
-
-/** @} */
-
diff --git a/lib/lufa/Projects/Webserver/Lib/uip/timer.h b/lib/lufa/Projects/Webserver/Lib/uip/timer.h
deleted file mode 100644
index 04917e4c5..000000000
--- a/lib/lufa/Projects/Webserver/Lib/uip/timer.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * \defgroup timer Timer library
- *
- * The timer library provides functions for setting, resetting and
- * restarting timers, and for checking if a timer has expired. An
- * application must "manually" check if its timers have expired; this
- * is not done automatically.
- *
- * A timer is declared as a \c struct \c timer and all access to the
- * timer is made by a pointer to the declared timer.
- *
- * \note The timer library uses the \ref clock "Clock library" to
- * measure time. Intervals should be specified in the format used by
- * the clock library.
- *
- * @{
- */
-
-
-/**
- * \file
- * Timer library header file.
- * \author
- * Adam Dunkels <adam@sics.se>
- */
-
-/*
- * Copyright (c) 2004, Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Institute nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file is part of the uIP TCP/IP stack
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- * $Id: timer.h,v 1.3 2006/06/11 21:46:39 adam Exp $
- */
-#ifndef __TIMER_H__
-#define __TIMER_H__
-
-#include "clock.h"
-
-/**
- * A timer.
- *
- * This structure is used for declaring a timer. The timer must be set
- * with timer_set() before it can be used.
- *
- * \hideinitializer
- */
-struct timer {
- clock_time_t start;
- clock_time_t interval;
-};
-
-void timer_set(struct timer *t, clock_time_t interval);
-void timer_reset(struct timer *t);
-void timer_restart(struct timer *t);
-int timer_expired(struct timer *t);
-
-#endif /* __TIMER_H__ */
-
-/** @} */
-
diff --git a/lib/lufa/Projects/Webserver/Lib/uip/uip-split.c b/lib/lufa/Projects/Webserver/Lib/uip/uip-split.c
deleted file mode 100644
index 5222a05b6..000000000
--- a/lib/lufa/Projects/Webserver/Lib/uip/uip-split.c
+++ /dev/null
@@ -1,151 +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 Contiki operating system.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- * $Id: uip-split.c,v 1.2 2008/10/14 13:39:12 julienabeille Exp $
- */
-
-#include "uip-split.h"
-
-
-#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
-
-/*-----------------------------------------------------------------------------*/
-void
-uip_split_output(void)
-{
-#if UIP_TCP
- u16_t tcplen, len1, len2;
-
- /* We only try to split maximum sized TCP segments. */
- if(BUF->proto == UIP_PROTO_TCP && uip_len == UIP_BUFSIZE) {
-
- tcplen = uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN;
- /* 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 + UIP_LLH_LEN;
-#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 - UIP_LLH_LEN) >> 8;
- BUF->len[1] = (uip_len - UIP_LLH_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. */
-#if UIP_CONF_IPV6
- tcpip_ipv6_output();
-#else
- if (USB_CurrentMode == USB_MODE_Device)
- RNDIS_Device_SendPacket(&Ethernet_RNDIS_Interface_Device, uip_buf, uip_len);
- else
- RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface_Host, uip_buf, uip_len);
-#endif /* UIP_CONF_IPV6 */
-
- /* 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 determined by the length of the first
- packet (len1). */
- uip_len = len2 + UIP_TCPIP_HLEN + UIP_LLH_LEN;
-#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 - UIP_LLH_LEN) >> 8;
- BUF->len[1] = (uip_len - UIP_LLH_LEN) & 0xff;
-#endif /* UIP_CONF_IPV6 */
-
- 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. */
-#if UIP_CONF_IPV6
- tcpip_ipv6_output();
-#else
- if (USB_CurrentMode == USB_MODE_Device)
- RNDIS_Device_SendPacket(&Ethernet_RNDIS_Interface_Device, uip_buf, uip_len);
- else
- RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface_Host, uip_buf, uip_len);
-#endif /* UIP_CONF_IPV6 */
- return;
- }
-#endif /* UIP_TCP */
-
- /* uip_fw_output();*/
-#if UIP_CONF_IPV6
- tcpip_ipv6_output();
-#else
- if (USB_CurrentMode == USB_MODE_Device)
- RNDIS_Device_SendPacket(&Ethernet_RNDIS_Interface_Device, uip_buf, uip_len);
- else
- RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface_Host, uip_buf, uip_len);
-#endif /* UIP_CONF_IPV6 */
-}
-
-/*-----------------------------------------------------------------------------*/
-
diff --git a/lib/lufa/Projects/Webserver/Lib/uip/uip-split.h b/lib/lufa/Projects/Webserver/Lib/uip/uip-split.h
deleted file mode 100644
index 0c768ce40..000000000
--- a/lib/lufa/Projects/Webserver/Lib/uip/uip-split.h
+++ /dev/null
@@ -1,104 +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 Contiki operating system.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- * $Id: uip-split.h,v 1.1 2006/06/17 22:41:19 adamdunkels 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__
-
-#include <string.h>
-#include <uip.h>
-
-#include "../../USBHostMode.h"
-
-#include <LUFA/Drivers/USB/USB.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);
-void uip_add32(u8_t *op32, u16_t op16);
-#endif /* __UIP_SPLIT_H__ */
-
-/** @} */
-/** @} */
-
diff --git a/lib/lufa/Projects/Webserver/Lib/uip/uip.c b/lib/lufa/Projects/Webserver/Lib/uip/uip.c
deleted file mode 100644
index fead75775..000000000
--- a/lib/lufa/Projects/Webserver/Lib/uip/uip.c
+++ /dev/null
@@ -1,1941 +0,0 @@
-#define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/
-
-/**
- * \addtogroup uip
- * @{
- */
-
-/**
- * \file
- * The uIP TCP/IP stack code.
- * \author Adam Dunkels <adam@dunkels.com>
- */
-
-/*
- * Copyright (c) 2001-2003, Adam Dunkels.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * This file is part of the uIP TCP/IP stack.
- *
- * $Id: uip.c,v 1.15 2008/10/15 08:08:32 adamdunkels Exp $
- *
- */
-
-/*
- * uIP is a small implementation of the IP, UDP and TCP protocols (as
- * well as some basic ICMP stuff). The implementation couples the IP,
- * UDP, TCP and the application layers very tightly. To keep the size
- * of the compiled code down, this code frequently uses the goto
- * statement. While it would be possible to break the uip_process()
- * function into many smaller functions, this would increase the code
- * size because of the overhead of parameter passing and the fact that
- * the optimizer would not be as efficient.
- *
- * The principle is that we have a small buffer, called the uip_buf,
- * in which the device driver puts an incoming packet. The TCP/IP
- * stack parses the headers in the packet, and calls the
- * application. If the remote host has sent data to the application,
- * this data is present in the uip_buf and the application read the
- * data from there. It is up to the application to put this data into
- * a byte stream if needed. The application will not be fed with data
- * that is out of sequence.
- *
- * If the application whishes to send data to the peer, it should put
- * its data into the uip_buf. The uip_appdata pointer points to the
- * first available byte. The TCP/IP stack will calculate the
- * checksums, and fill in the necessary header fields and finally send
- * the packet back to the peer.
-*/
-
-#include "uip.h"
-#include "uipopt.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
-#include "net/uip-neighbor.h"
-#endif /* UIP_CONF_IPV6 */
-
-#include <string.h>
-
-/*---------------------------------------------------------------------------*/
-/* Variable definitions. */
-
-
-/* The IP address of this host. If it is defined to be fixed (by
- setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set
- here. Otherwise, the address */
-#if UIP_FIXEDADDR > 0
-const uip_ipaddr_t uip_hostaddr =
- { UIP_IPADDR0, UIP_IPADDR1, UIP_IPADDR2, UIP_IPADDR3 };
-const uip_ipaddr_t uip_draddr =
- { UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3 };
-const uip_ipaddr_t uip_netmask =
- { UIP_NETMASK0, UIP_NETMASK1, UIP_NETMASK2, UIP_NETMASK3 };
-#else
-uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
-#endif /* UIP_FIXEDADDR */
-
-const uip_ipaddr_t uip_broadcast_addr =
-#if UIP_CONF_IPV6
- { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
-#else /* UIP_CONF_IPV6 */
- { { 0xff, 0xff, 0xff, 0xff } };
-#endif /* UIP_CONF_IPV6 */
-const uip_ipaddr_t uip_all_zeroes_addr = { { 0x0, /* rest is 0 */ } };
-
-#if UIP_FIXEDETHADDR
-const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
- UIP_ETHADDR1,
- UIP_ETHADDR2,
- UIP_ETHADDR3,
- UIP_ETHADDR4,
- UIP_ETHADDR5}};
-#else
-struct uip_eth_addr uip_ethaddr = {{0,0,0,0,0,0}};
-#endif
-
-#ifndef UIP_CONF_EXTERNAL_BUFFER
-u8_t uip_buf[UIP_BUFSIZE + 2]; /* The packet buffer that contains
- incoming packets. */
-#endif /* UIP_CONF_EXTERNAL_BUFFER */
-
-void *uip_appdata; /* The uip_appdata pointer points to
- application data. */
-void *uip_sappdata; /* The uip_appdata pointer points to
- the application data which is to
- be sent. */
-#if UIP_URGDATA > 0
-void *uip_urgdata; /* The uip_urgdata pointer points to
- urgent data (out-of-band data), if
- present. */
-u16_t uip_urglen, uip_surglen;
-#endif /* UIP_URGDATA > 0 */
-
-u16_t uip_len, uip_slen;
- /* The uip_len is either 8 or 16 bits,
- depending on the maximum packet
- size. */
-
-u8_t uip_flags; /* The uip_flags variable is used for
- communication between the TCP/IP stack
- and the application program. */
-struct uip_conn *uip_conn; /* uip_conn always points to the current
- connection. */
-
-struct uip_conn uip_conns[UIP_CONNS];
- /* The uip_conns array holds all TCP
- connections. */
-u16_t uip_listenports[UIP_LISTENPORTS];
- /* The uip_listenports list all currently
- listening ports. */
-#if UIP_UDP
-struct uip_udp_conn *uip_udp_conn;
-struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
-#endif /* UIP_UDP */
-
-static u16_t ipid; /* Ths ipid variable is an increasing
- number that is used for the IP ID
- field. */
-
-void uip_setipid(u16_t id) { ipid = id; }
-
-static u8_t iss[4]; /* The iss variable is used for the TCP
- initial sequence number. */
-
-#if UIP_ACTIVE_OPEN
-static u16_t lastport; /* Keeps track of the last port used for
- a new connection. */
-#endif /* UIP_ACTIVE_OPEN */
-
-/* Temporary variables. */
-u8_t uip_acc32[4];
-static u8_t c, opt;
-static u16_t tmp16;
-
-/* Structures and definitions. */
-#define TCP_FIN 0x01
-#define TCP_SYN 0x02
-#define TCP_RST 0x04
-#define TCP_PSH 0x08
-#define TCP_ACK 0x10
-#define TCP_URG 0x20
-#define TCP_CTL 0x3f
-
-#define TCP_OPT_END 0 /* End of TCP options list */
-#define TCP_OPT_NOOP 1 /* "No-operation" TCP option */
-#define TCP_OPT_MSS 2 /* Maximum segment size TCP option */
-
-#define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */
-
-#define ICMP_ECHO_REPLY 0
-#define ICMP_ECHO 8
-
-#define ICMP_DEST_UNREACHABLE 3
-#define ICMP_PORT_UNREACHABLE 3
-
-#define ICMP6_ECHO_REPLY 129
-#define ICMP6_ECHO 128
-#define ICMP6_NEIGHBOR_SOLICITATION 135
-#define ICMP6_NEIGHBOR_ADVERTISEMENT 136
-
-#define ICMP6_FLAG_S (1 << 6)
-
-#define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1
-#define ICMP6_OPTION_TARGET_LINK_ADDRESS 2
-
-
-/* Macros. */
-#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
-#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
-#define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
-#define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
-
-
-#if UIP_STATISTICS == 1
-struct uip_stats uip_stat;
-#define UIP_STAT(s) s
-#else
-#define UIP_STAT(s)
-#endif /* UIP_STATISTICS == 1 */
-
-#if UIP_LOGGING == 1
-#include <stdio.h>
-void uip_log(char *msg);
-#define UIP_LOG(m) uip_log(m)
-#else
-#define UIP_LOG(m)
-#endif /* UIP_LOGGING == 1 */
-
-#if ! UIP_ARCH_ADD32
-void
-uip_add32(u8_t *op32, u16_t op16)
-{
- uip_acc32[3] = op32[3] + (op16 & 0xff);
- uip_acc32[2] = op32[2] + (op16 >> 8);
- uip_acc32[1] = op32[1];
- uip_acc32[0] = op32[0];
-
- if(uip_acc32[2] < (op16 >> 8)) {
- ++uip_acc32[1];
- if(uip_acc32[1] == 0) {
- ++uip_acc32[0];
- }
- }
-
-
- if(uip_acc32[3] < (op16 & 0xff)) {
- ++uip_acc32[2];
- if(uip_acc32[2] == 0) {
- ++uip_acc32[1];
- if(uip_acc32[1] == 0) {
- ++uip_acc32[0];
- }
- }
- }
-}
-
-#endif /* UIP_ARCH_ADD32 */
-
-#if ! UIP_ARCH_CHKSUM
-/*---------------------------------------------------------------------------*/
-static u16_t
-chksum(u16_t sum, const u8_t *data, u16_t len)
-{
- u16_t t;
- const u8_t *dataptr;
- const u8_t *last_byte;
-
- dataptr = data;
- last_byte = data + len - 1;
-
- while(dataptr < last_byte) { /* At least two more bytes */
- t = (dataptr[0] << 8) + dataptr[1];
- sum += t;
- if(sum < t) {
- sum++; /* carry */
- }
- dataptr += 2;
- }
-
- if(dataptr == last_byte) {
- t = (dataptr[0] << 8) + 0;
- sum += t;
- if(sum < t) {
- sum++; /* carry */
- }
- }
-
- /* Return sum in host byte order. */
- return sum;
-}
-/*---------------------------------------------------------------------------*/
-u16_t
-uip_chksum(u16_t *data, u16_t len)
-{
- return htons(chksum(0, (u8_t *)data, len));
-}
-/*---------------------------------------------------------------------------*/
-#ifndef UIP_ARCH_IPCHKSUM
-u16_t
-uip_ipchksum(void)
-{
- u16_t sum;
-
- sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
- DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum);
- return (sum == 0) ? 0xffff : htons(sum);
-}
-#endif
-/*---------------------------------------------------------------------------*/
-static u16_t
-upper_layer_chksum(u8_t proto)
-{
- u16_t upper_layer_len;
- u16_t sum;
-
-#if UIP_CONF_IPV6
- upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]);
-#else /* UIP_CONF_IPV6 */
- upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;
-#endif /* UIP_CONF_IPV6 */
-
- /* First sum pseudo-header. */
-
- /* IP protocol and length fields. This addition cannot carry. */
- sum = upper_layer_len + proto;
- /* Sum IP source and destination addresses. */
- sum = chksum(sum, (u8_t *)&BUF->srcipaddr, 2 * sizeof(uip_ipaddr_t));
-
- /* Sum TCP header and data. */
- sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN],
- upper_layer_len);
-
- return (sum == 0) ? 0xffff : htons(sum);
-}
-/*---------------------------------------------------------------------------*/
-#if UIP_CONF_IPV6
-u16_t
-uip_icmp6chksum(void)
-{
- return upper_layer_chksum(UIP_PROTO_ICMP6);
-
-}
-#endif /* UIP_CONF_IPV6 */
-/*---------------------------------------------------------------------------*/
-u16_t
-uip_tcpchksum(void)
-{
- return upper_layer_chksum(UIP_PROTO_TCP);
-}
-/*---------------------------------------------------------------------------*/
-#if UIP_UDP_CHECKSUMS
-u16_t
-uip_udpchksum(void)
-{
- return upper_layer_chksum(UIP_PROTO_UDP);
-}
-#endif /* UIP_UDP_CHECKSUMS */
-#endif /* UIP_ARCH_CHKSUM */
-/*---------------------------------------------------------------------------*/
-void
-uip_init(void)
-{
- for(c = 0; c < UIP_LISTENPORTS; ++c) {
- uip_listenports[c] = 0;
- }
- for(c = 0; c < UIP_CONNS; ++c) {
- uip_conns[c].tcpstateflags = UIP_CLOSED;
- }
-#if UIP_ACTIVE_OPEN
- lastport = 1024;
-#endif /* UIP_ACTIVE_OPEN */
-
-#if UIP_UDP
- for(c = 0; c < UIP_UDP_CONNS; ++c) {
- uip_udp_conns[c].lport = 0;
- }
-#endif /* UIP_UDP */
-
-
- /* IPv4 initialization. */
-#if UIP_FIXEDADDR == 0
- /* uip_hostaddr[0] = uip_hostaddr[1] = 0;*/
-#endif /* UIP_FIXEDADDR */
-
-}
-/*---------------------------------------------------------------------------*/
-#if UIP_ACTIVE_OPEN
-struct uip_conn *
-uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)
-{
- register struct uip_conn *conn, *cconn;
-
- /* Find an unused local port. */
- again:
- ++lastport;
-
- if(lastport >= 32000) {
- lastport = 4096;
- }
-
- /* Check if this port is already in use, and if so try to find
- another one. */
- for(c = 0; c < UIP_CONNS; ++c) {
- conn = &uip_conns[c];
- if(conn->tcpstateflags != UIP_CLOSED &&
- conn->lport == htons(lastport)) {
- goto again;
- }
- }
-
- conn = 0;
- for(c = 0; c < UIP_CONNS; ++c) {
- cconn = &uip_conns[c];
- if(cconn->tcpstateflags == UIP_CLOSED) {
- conn = cconn;
- break;
- }
- if(cconn->tcpstateflags == UIP_TIME_WAIT) {
- if(conn == 0 ||
- cconn->timer > conn->timer) {
- conn = cconn;
- }
- }
- }
-
- if(conn == 0) {
- return 0;
- }
-
- conn->tcpstateflags = UIP_SYN_SENT;
-
- conn->snd_nxt[0] = iss[0];
- conn->snd_nxt[1] = iss[1];
- conn->snd_nxt[2] = iss[2];
- conn->snd_nxt[3] = iss[3];
-
- conn->initialmss = conn->mss = UIP_TCP_MSS;
-
- conn->len = 1; /* TCP length of the SYN is one. */
- conn->nrtx = 0;
- conn->timer = 1; /* Send the SYN next time around. */
- conn->rto = UIP_RTO;
- conn->sa = 0;
- conn->sv = 16; /* Initial value of the RTT variance. */
- conn->lport = htons(lastport);
- conn->rport = rport;
- uip_ipaddr_copy(&conn->ripaddr, ripaddr);
-
- return conn;
-}
-#endif /* UIP_ACTIVE_OPEN */
-/*---------------------------------------------------------------------------*/
-#if UIP_UDP
-struct uip_udp_conn *
-uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport)
-{
- register struct uip_udp_conn *conn;
-
- /* Find an unused local port. */
- again:
- ++lastport;
-
- if(lastport >= 32000) {
- lastport = 4096;
- }
-
- for(c = 0; c < UIP_UDP_CONNS; ++c) {
- if(uip_udp_conns[c].lport == htons(lastport)) {
- goto again;
- }
- }
-
-
- conn = 0;
- for(c = 0; c < UIP_UDP_CONNS; ++c) {
- if(uip_udp_conns[c].lport == 0) {
- conn = &uip_udp_conns[c];
- break;
- }
- }
-
- if(conn == 0) {
- return 0;
- }
-
- conn->lport = HTONS(lastport);
- conn->rport = rport;
- if(ripaddr == NULL) {
- memset(&conn->ripaddr, 0, sizeof(uip_ipaddr_t));
- } else {
- uip_ipaddr_copy(&conn->ripaddr, ripaddr);
- }
- conn->ttl = UIP_TTL;
-
- return conn;
-}
-#endif /* UIP_UDP */
-/*---------------------------------------------------------------------------*/
-void
-uip_unlisten(u16_t port)
-{
- for(c = 0; c < UIP_LISTENPORTS; ++c) {
- if(uip_listenports[c] == port) {
- uip_listenports[c] = 0;
- return;
- }
- }
-}
-/*---------------------------------------------------------------------------*/
-void
-uip_listen(u16_t port)
-{
- for(c = 0; c < UIP_LISTENPORTS; ++c) {
- if(uip_listenports[c] == 0) {
- uip_listenports[c] = port;
- return;
- }
- }
-}
-/*---------------------------------------------------------------------------*/
-/* XXX: IP fragment reassembly: not well-tested. */
-
-#if UIP_REASSEMBLY && !UIP_CONF_IPV6
-#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
-static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];
-static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
-static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
- 0x0f, 0x07, 0x03, 0x01};
-static u16_t uip_reasslen;
-static u8_t uip_reassflags;
-#define UIP_REASS_FLAG_LASTFRAG 0x01
-static u8_t uip_reasstmr;
-
-#define IP_MF 0x20
-
-static u8_t
-uip_reass(void)
-{
- u16_t offset, len;
- u16_t i;
-
- /* If ip_reasstmr is zero, no packet is present in the buffer, so we
- write the IP header of the fragment into the reassembly
- buffer. The timer is updated with the maximum age. */
- if(uip_reasstmr == 0) {
- memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN);
- uip_reasstmr = UIP_REASS_MAXAGE;
- uip_reassflags = 0;
- /* Clear the bitmap. */
- memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap));
- }
-
- /* Check if the incoming fragment matches the one currently present
- in the reasembly buffer. If so, we proceed with copying the
- fragment into the buffer. */
- if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
- BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
- BUF->destipaddr[0] == FBUF->destipaddr[0] &&
- BUF->destipaddr[1] == FBUF->destipaddr[1] &&
- BUF->ipid[0] == FBUF->ipid[0] &&
- BUF->ipid[1] == FBUF->ipid[1]) {
-
- len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
- offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
-
- /* If the offset or the offset + fragment length overflows the
- reassembly buffer, we discard the entire packet. */
- if(offset > UIP_REASS_BUFSIZE ||
- offset + len > UIP_REASS_BUFSIZE) {
- uip_reasstmr = 0;
- goto nullreturn;
- }
-
- /* Copy the fragment into the reassembly buffer, at the right
- offset. */
- memcpy(&uip_reassbuf[UIP_IPH_LEN + offset],
- (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
- len);
-
- /* Update the bitmap. */
- if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
- /* If the two endpoints are in the same byte, we only update
- that byte. */
-
- uip_reassbitmap[offset / (8 * 8)] |=
- bitmap_bits[(offset / 8 ) & 7] &
- ~bitmap_bits[((offset + len) / 8 ) & 7];
- } else {
- /* If the two endpoints are in different bytes, we update the
- bytes in the endpoints and fill the stuff in-between with
- 0xff. */
- uip_reassbitmap[offset / (8 * 8)] |=
- bitmap_bits[(offset / 8 ) & 7];
- for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
- uip_reassbitmap[i] = 0xff;
- }
- uip_reassbitmap[(offset + len) / (8 * 8)] |=
- ~bitmap_bits[((offset + len) / 8 ) & 7];
- }
-
- /* If this fragment has the More Fragments flag set to zero, we
- know that this is the last fragment, so we can calculate the
- size of the entire packet. We also set the
- IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
- the final fragment. */
-
- if((BUF->ipoffset[0] & IP_MF) == 0) {
- uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
- uip_reasslen = offset + len;
- }
-
- /* Finally, we check if we have a full packet in the buffer. We do
- this by checking if we have the last fragment and if all bits
- in the bitmap are set. */
- if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
- /* Check all bytes up to and including all but the last byte in
- the bitmap. */
- for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
- if(uip_reassbitmap[i] != 0xff) {
- goto nullreturn;
- }
- }
- /* Check the last byte in the bitmap. It should contain just the
- right amount of bits. */
- if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=
- (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
- goto nullreturn;
- }
-
- /* If we have come this far, we have a full packet in the
- buffer, so we allocate a pbuf and copy the packet into it. We
- also reset the timer. */
- uip_reasstmr = 0;
- memcpy(BUF, FBUF, uip_reasslen);
-
- /* Pretend to be a "normal" (i.e., not fragmented) IP packet
- from now on. */
- BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
- BUF->len[0] = uip_reasslen >> 8;
- BUF->len[1] = uip_reasslen & 0xff;
- BUF->ipchksum = 0;
- BUF->ipchksum = ~(uip_ipchksum());
-
- return uip_reasslen;
- }
- }
-
- nullreturn:
- return 0;
-}
-#endif /* UIP_REASSEMBLY */
-/*---------------------------------------------------------------------------*/
-static void
-uip_add_rcv_nxt(u16_t n)
-{
- uip_add32(uip_conn->rcv_nxt, n);
- uip_conn->rcv_nxt[0] = uip_acc32[0];
- uip_conn->rcv_nxt[1] = uip_acc32[1];
- uip_conn->rcv_nxt[2] = uip_acc32[2];
- uip_conn->rcv_nxt[3] = uip_acc32[3];
-}
-/*---------------------------------------------------------------------------*/
-void
-uip_process(u8_t flag)
-{
- register struct uip_conn *uip_connr = uip_conn;
-
-#if UIP_UDP
- if(flag == UIP_UDP_SEND_CONN) {
- goto udp_send;
- }
-#endif /* UIP_UDP */
-
- uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
-
- /* Check if we were invoked because of a poll request for a
- particular connection. */
- if(flag == UIP_POLL_REQUEST) {
- if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
- !uip_outstanding(uip_connr)) {
- uip_len = uip_slen = 0;
- uip_flags = UIP_POLL;
- UIP_APPCALL();
- goto appsend;
- }
- goto drop;
-
- /* Check if we were invoked because of the periodic timer firing. */
- } else if(flag == UIP_TIMER) {
-#if UIP_REASSEMBLY
- if(uip_reasstmr != 0) {
- --uip_reasstmr;
- }
-#endif /* UIP_REASSEMBLY */
- /* Increase the initial sequence number. */
- if(++iss[3] == 0) {
- if(++iss[2] == 0) {
- if(++iss[1] == 0) {
- ++iss[0];
- }
- }
- }
-
- /* Reset the length variables. */
- uip_len = 0;
- uip_slen = 0;
-
- /* Check if the connection is in a state in which we simply wait
- for the connection to time out. If so, we increase the
- connection's timer and remove the connection if it times
- out. */
- if(uip_connr->tcpstateflags == UIP_TIME_WAIT ||
- uip_connr->tcpstateflags == UIP_FIN_WAIT_2) {
- ++(uip_connr->timer);
- if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
- uip_connr->tcpstateflags = UIP_CLOSED;
- }
- } else if(uip_connr->tcpstateflags != UIP_CLOSED) {
- /* If the connection has outstanding data, we increase the
- connection's timer and see if it has reached the RTO value
- in which case we retransmit. */
- if(uip_outstanding(uip_connr)) {
- if(uip_connr->timer-- == 0) {
- if(uip_connr->nrtx == UIP_MAXRTX ||
- ((uip_connr->tcpstateflags == UIP_SYN_SENT ||
- uip_connr->tcpstateflags == UIP_SYN_RCVD) &&
- uip_connr->nrtx == UIP_MAXSYNRTX)) {
- uip_connr->tcpstateflags = UIP_CLOSED;
-
- /* We call UIP_APPCALL() with uip_flags set to
- UIP_TIMEDOUT to inform the application that the
- connection has timed out. */
- uip_flags = UIP_TIMEDOUT;
- UIP_APPCALL();
-
- /* We also send a reset packet to the remote host. */
- BUF->flags = TCP_RST | TCP_ACK;
- goto tcp_send_nodata;
- }
-
- /* Exponential back-off. */
- uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
- 4:
- uip_connr->nrtx);
- ++(uip_connr->nrtx);
-
- /* Ok, so we need to retransmit. We do this differently
- depending on which state we are in. In ESTABLISHED, we
- call upon the application so that it may prepare the
- data for the retransmit. In SYN_RCVD, we resend the
- SYNACK that we sent earlier and in LAST_ACK we have to
- retransmit our FINACK. */
- UIP_STAT(++uip_stat.tcp.rexmit);
- switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
- case UIP_SYN_RCVD:
- /* In the SYN_RCVD state, we should retransmit our
- SYNACK. */
- goto tcp_send_synack;
-
-#if UIP_ACTIVE_OPEN
- case UIP_SYN_SENT:
- /* In the SYN_SENT state, we retransmit out SYN. */
- BUF->flags = 0;
- goto tcp_send_syn;
-#endif /* UIP_ACTIVE_OPEN */
-
- case UIP_ESTABLISHED:
- /* In the ESTABLISHED state, we call upon the application
- to do the actual retransmit after which we jump into
- the code for sending out the packet (the apprexmit
- label). */
- uip_flags = UIP_REXMIT;
- UIP_APPCALL();
- goto apprexmit;
-
- case UIP_FIN_WAIT_1:
- case UIP_CLOSING:
- case UIP_LAST_ACK:
- /* In all these states we should retransmit a FINACK. */
- goto tcp_send_finack;
-
- }
- }
- } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
- /* If there was no need for a retransmission, we poll the
- application for new data. */
- uip_len = uip_slen = 0;
- uip_flags = UIP_POLL;
- UIP_APPCALL();
- goto appsend;
- }
- }
- goto drop;
- }
-#if UIP_UDP
- if(flag == UIP_UDP_TIMER) {
- if(uip_udp_conn->lport != 0) {
- uip_conn = NULL;
- uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
- uip_len = uip_slen = 0;
- uip_flags = UIP_POLL;
- UIP_UDP_APPCALL();
- goto udp_send;
- } else {
- goto drop;
- }
- }
-#endif
-
- /* This is where the input processing starts. */
- UIP_STAT(++uip_stat.ip.recv);
-
- /* Start of IP input header processing code. */
-
-#if UIP_CONF_IPV6
- /* Check validity of the IP header. */
- if((BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */
- UIP_STAT(++uip_stat.ip.drop);
- UIP_STAT(++uip_stat.ip.vhlerr);
- UIP_LOG("ipv6: invalid version.");
- goto drop;
- }
-#else /* UIP_CONF_IPV6 */
- /* Check validity of the IP header. */
- if(BUF->vhl != 0x45) { /* IP version and header length. */
- UIP_STAT(++uip_stat.ip.drop);
- UIP_STAT(++uip_stat.ip.vhlerr);
- UIP_LOG("ip: invalid version or header length.");
- goto drop;
- }
-#endif /* UIP_CONF_IPV6 */
-
- /* Check the size of the packet. If the size reported to us in
- uip_len is smaller the size reported in the IP header, we assume
- that the packet has been corrupted in transit. If the size of
- uip_len is larger than the size reported in the IP packet header,
- the packet has been padded and we set uip_len to the correct
- value.. */
-
- if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) {
- uip_len = (BUF->len[0] << 8) + BUF->len[1];
-#if UIP_CONF_IPV6
- uip_len += 40; /* The length reported in the IPv6 header is the
- length of the payload that follows the
- header. However, uIP uses the uip_len variable
- for holding the size of the entire packet,
- including the IP header. For IPv4 this is not a
- problem as the length field in the IPv4 header
- contains the length of the entire packet. But
- for IPv6 we need to add the size of the IPv6
- header (40 bytes). */
-#endif /* UIP_CONF_IPV6 */
- } else {
- UIP_LOG("ip: packet shorter than reported in IP header.");
- goto drop;
- }
-
-#if !UIP_CONF_IPV6
- /* Check the fragment flag. */
- if((BUF->ipoffset[0] & 0x3f) != 0 ||
- BUF->ipoffset[1] != 0) {
-#if UIP_REASSEMBLY
- uip_len = uip_reass();
- if(uip_len == 0) {
- goto drop;
- }
-#else /* UIP_REASSEMBLY */
- UIP_STAT(++uip_stat.ip.drop);
- UIP_STAT(++uip_stat.ip.fragerr);
- UIP_LOG("ip: fragment dropped.");
- goto drop;
-#endif /* UIP_REASSEMBLY */
- }
-#endif /* UIP_CONF_IPV6 */
-
- if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) {
- /* If we are configured to use ping IP address configuration and
- hasn't been assigned an IP address yet, we accept all ICMP
- packets. */
-#if UIP_PINGADDRCONF && !UIP_CONF_IPV6
- if(BUF->proto == UIP_PROTO_ICMP) {
- UIP_LOG("ip: possible ping config packet received.");
- goto icmp_input;
- } else {
- UIP_LOG("ip: packet dropped since no address assigned.");
- goto drop;
- }
-#endif /* UIP_PINGADDRCONF */
-
- } else {
- /* If IP broadcast support is configured, we check for a broadcast
- UDP packet, which may be destined to us. */
-#if UIP_BROADCAST
- DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum());
- if(BUF->proto == UIP_PROTO_UDP &&
- uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr))
- {
- if (uip_ipaddr_cmp(&BUF->srcipaddr, &uip_all_zeroes_addr))
- uip_ipaddr_copy(&BUF->srcipaddr, &uip_broadcast_addr);
-
- goto udp_input;
- }
-#endif /* UIP_BROADCAST */
-
- /* Check if the packet is destined for our IP address. */
-#if !UIP_CONF_IPV6
- if(!uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr)) {
- UIP_STAT(++uip_stat.ip.drop);
- goto drop;
- }
-#else /* UIP_CONF_IPV6 */
- /* For IPv6, packet reception is a little trickier as we need to
- make sure that we listen to certain multicast addresses (all
- hosts multicast address, and the solicited-node multicast
- address) as well. However, we will cheat here and accept all
- multicast packets that are sent to the ff02::/16 addresses. */
- if(!uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr) &&
- BUF->destipaddr.u16[0] != HTONS(0xff02)) {
- UIP_STAT(++uip_stat.ip.drop);
- goto drop;
- }
-#endif /* UIP_CONF_IPV6 */
- }
-
-#if !UIP_CONF_IPV6
- if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
- checksum. */
- UIP_STAT(++uip_stat.ip.drop);
- UIP_STAT(++uip_stat.ip.chkerr);
- UIP_LOG("ip: bad checksum.");
- goto drop;
- }
-#endif /* UIP_CONF_IPV6 */
-
- if(BUF->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so,
- proceed with TCP input
- processing. */
- goto tcp_input;
- }
-
-#if UIP_UDP
- if(BUF->proto == UIP_PROTO_UDP) {
- goto udp_input;
- }
-#endif /* UIP_UDP */
-
-#if !UIP_CONF_IPV6
- /* ICMPv4 processing code follows. */
- if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from
- here. */
- UIP_STAT(++uip_stat.ip.drop);
- UIP_STAT(++uip_stat.ip.protoerr);
- UIP_LOG("ip: neither tcp nor icmp.");
- goto drop;
- }
-
-#if UIP_PINGADDRCONF
- icmp_input:
-#endif /* UIP_PINGADDRCONF */
- UIP_STAT(++uip_stat.icmp.recv);
-
- /* ICMP echo (i.e., ping) processing. This is simple, we only change
- the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP
- checksum before we return the packet. */
- if(ICMPBUF->type != ICMP_ECHO) {
- UIP_STAT(++uip_stat.icmp.drop);
- UIP_STAT(++uip_stat.icmp.typeerr);
- UIP_LOG("icmp: not icmp echo.");
- goto drop;
- }
-
- /* If we are configured to use ping IP address assignment, we use
- the destination IP address of this ping packet and assign it to
- yourself. */
-#if UIP_PINGADDRCONF
- if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) {
- uip_hostaddr = BUF->destipaddr;
- }
-#endif /* UIP_PINGADDRCONF */
-
- ICMPBUF->type = ICMP_ECHO_REPLY;
-
- if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
- ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
- } else {
- ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
- }
-
- /* Swap IP addresses. */
- uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr);
- uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
-
- UIP_STAT(++uip_stat.icmp.sent);
- BUF->ttl = UIP_TTL;
- goto ip_send_nolen;
-
- /* End of IPv4 input header processing code. */
-#else /* !UIP_CONF_IPV6 */
-
- /* This is IPv6 ICMPv6 processing code. */
- DEBUG_PRINTF("icmp6_input: length %d\n", uip_len);
-
- if(BUF->proto != UIP_PROTO_ICMP6) { /* We only allow ICMPv6 packets from
- here. */
- UIP_STAT(++uip_stat.ip.drop);
- UIP_STAT(++uip_stat.ip.protoerr);
- UIP_LOG("ip: neither tcp nor icmp6.");
- goto drop;
- }
-
- UIP_STAT(++uip_stat.icmp.recv);
-
- /* If we get a neighbor solicitation for our address we should send
- a neighbor advertisement message back. */
- if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) {
- if(uip_ipaddr_cmp(&ICMPBUF->icmp6data, &uip_hostaddr)) {
-
- if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) {
- /* Save the sender's address in our neighbor list. */
- uip_neighbor_add(&ICMPBUF->srcipaddr, &(ICMPBUF->options[2]));
- }
-
- /* We should now send a neighbor advertisement back to where the
- neighbor solicitation came from. */
- ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT;
- ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */
-
- ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0;
-
- uip_ipaddr_copy(&ICMPBUF->destipaddr, &ICMPBUF->srcipaddr);
- uip_ipaddr_copy(&ICMPBUF->srcipaddr, &uip_hostaddr);
- ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS;
- ICMPBUF->options[1] = 1; /* Options length, 1 = 8 bytes. */
- memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr));
- ICMPBUF->icmpchksum = 0;
- ICMPBUF->icmpchksum = ~uip_icmp6chksum();
-
- goto send;
-
- }
- goto drop;
- } else if(ICMPBUF->type == ICMP6_ECHO) {
- /* ICMP echo (i.e., ping) processing. This is simple, we only
- change the ICMP type from ECHO to ECHO_REPLY and update the
- ICMP checksum before we return the packet. */
-
- ICMPBUF->type = ICMP6_ECHO_REPLY;
-
- uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr);
- uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
- ICMPBUF->icmpchksum = 0;
- ICMPBUF->icmpchksum = ~uip_icmp6chksum();
-
- UIP_STAT(++uip_stat.icmp.sent);
- goto send;
- } else {
- DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type);
- UIP_STAT(++uip_stat.icmp.drop);
- UIP_STAT(++uip_stat.icmp.typeerr);
- UIP_LOG("icmp: unknown ICMP message.");
- goto drop;
- }
-
- /* End of IPv6 ICMP processing. */
-
-#endif /* !UIP_CONF_IPV6 */
-
-#if UIP_UDP
- /* UDP input processing. */
- udp_input:
- /* UDP processing is really just a hack. We don't do anything to the
- UDP/IP headers, but let the UDP application do all the hard
- work. If the application sets uip_slen, it has a packet to
- send. */
-#if UIP_UDP_CHECKSUMS
- uip_len = uip_len - UIP_IPUDPH_LEN;
- uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
- if(UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
- UIP_STAT(++uip_stat.udp.drop);
- UIP_STAT(++uip_stat.udp.chkerr);
- UIP_LOG("udp: bad checksum.");
- goto drop;
- }
-#else /* UIP_UDP_CHECKSUMS */
- uip_len = uip_len - UIP_IPUDPH_LEN;
-#endif /* UIP_UDP_CHECKSUMS */
-
- /* Demultiplex this UDP packet between the UDP "connections". */
- for(uip_udp_conn = &uip_udp_conns[0];
- uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
- ++uip_udp_conn) {
- /* If the local UDP port is non-zero, the connection is considered
- to be used. If so, the local port number is checked against the
- destination port number in the received packet. If the two port
- numbers match, the remote port number is checked if the
- connection is bound to a remote port. Finally, if the
- connection is bound to a remote IP address, the source IP
- address of the packet is checked. */
- if(uip_udp_conn->lport != 0 &&
- UDPBUF->destport == uip_udp_conn->lport &&
- (uip_udp_conn->rport == 0 ||
- UDPBUF->srcport == uip_udp_conn->rport) &&
- (uip_ipaddr_cmp(&uip_udp_conn->ripaddr, &uip_all_zeroes_addr) ||
- uip_ipaddr_cmp(&uip_udp_conn->ripaddr, &uip_broadcast_addr) ||
- uip_ipaddr_cmp(&BUF->srcipaddr, &uip_udp_conn->ripaddr))) {
- goto udp_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;
-#endif /* UIP_CONF_ICMP_DEST_UNREACH */
-
- udp_found:
- uip_conn = NULL;
- uip_flags = UIP_NEWDATA;
- uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
- uip_slen = 0;
- UIP_UDP_APPCALL();
-
- udp_send:
- if(uip_slen == 0) {
- goto drop;
- }
- uip_len = uip_slen + UIP_IPUDPH_LEN;
-
-#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 */
-
- BUF->ttl = uip_udp_conn->ttl;
- BUF->proto = UIP_PROTO_UDP;
-
- UDPBUF->udplen = HTONS(uip_slen + UIP_UDPH_LEN);
- UDPBUF->udpchksum = 0;
-
- BUF->srcport = uip_udp_conn->lport;
- BUF->destport = uip_udp_conn->rport;
-
- uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
- uip_ipaddr_copy(&BUF->destipaddr, &uip_udp_conn->ripaddr);
-
- uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
-
-#if UIP_UDP_CHECKSUMS
- /* Calculate UDP checksum. */
- UDPBUF->udpchksum = ~(uip_udpchksum());
- if(UDPBUF->udpchksum == 0) {
- UDPBUF->udpchksum = 0xffff;
- }
-#endif /* UIP_UDP_CHECKSUMS */
-
- goto ip_send_nolen;
-#endif /* UIP_UDP */
-
- /* TCP input processing. */
- tcp_input:
- UIP_STAT(++uip_stat.tcp.recv);
-
- /* Start of TCP input header processing code. */
-
- if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
- checksum. */
- UIP_STAT(++uip_stat.tcp.drop);
- UIP_STAT(++uip_stat.tcp.chkerr);
- UIP_LOG("tcp: bad checksum.");
- goto drop;
- }
-
- /* Demultiplex this segment. */
- /* First check any active connections. */
- for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1];
- ++uip_connr) {
- if(uip_connr->tcpstateflags != UIP_CLOSED &&
- BUF->destport == uip_connr->lport &&
- BUF->srcport == uip_connr->rport &&
- uip_ipaddr_cmp(&BUF->srcipaddr, &uip_connr->ripaddr)) {
- goto found;
- }
- }
-
- /* If we didn't find and active connection that expected the packet,
- either this packet is an old duplicate, or this is a SYN packet
- destined for a connection in LISTEN. If the SYN flag isn't set,
- it is an old packet and we send a RST. */
- if((BUF->flags & TCP_CTL) != TCP_SYN) {
- goto reset;
- }
-
- tmp16 = BUF->destport;
- /* Next, check listening connections. */
- for(c = 0; c < UIP_LISTENPORTS; ++c) {
- if(tmp16 == uip_listenports[c]) {
- goto found_listen;
- }
- }
-
- /* No matching connection found, so we send a RST packet. */
- UIP_STAT(++uip_stat.tcp.synrst);
-
- reset:
- /* We do not send resets in response to resets. */
- if(BUF->flags & TCP_RST) {
- goto drop;
- }
-
- UIP_STAT(++uip_stat.tcp.rst);
-
- BUF->flags = TCP_RST | TCP_ACK;
- uip_len = UIP_IPTCPH_LEN;
- BUF->tcpoffset = 5 << 4;
-
- /* Flip the seqno and ackno fields in the TCP header. */
- c = BUF->seqno[3];
- BUF->seqno[3] = BUF->ackno[3];
- BUF->ackno[3] = c;
-
- c = BUF->seqno[2];
- BUF->seqno[2] = BUF->ackno[2];
- BUF->ackno[2] = c;
-
- c = BUF->seqno[1];
- BUF->seqno[1] = BUF->ackno[1];
- BUF->ackno[1] = c;
-
- c = BUF->seqno[0];
- BUF->seqno[0] = BUF->ackno[0];
- BUF->ackno[0] = c;
-
- /* We also have to increase the sequence number we are
- acknowledging. If the least significant byte overflowed, we need
- to propagate the carry to the other bytes as well. */
- if(++BUF->ackno[3] == 0) {
- if(++BUF->ackno[2] == 0) {
- if(++BUF->ackno[1] == 0) {
- ++BUF->ackno[0];
- }
- }
- }
-
- /* Swap port numbers. */
- tmp16 = BUF->srcport;
- BUF->srcport = BUF->destport;
- BUF->destport = tmp16;
-
- /* Swap IP addresses. */
- uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr);
- uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
-
- /* And send out the RST packet! */
- goto tcp_send_noconn;
-
- /* This label will be jumped to if we matched the incoming packet
- with a connection in LISTEN. In that case, we should create a new
- connection and send a SYNACK in return. */
- found_listen:
- /* First we check if there are any connections available. Unused
- connections are kept in the same table as used connections, but
- unused ones have the tcpstate set to CLOSED. Also, connections in
- TIME_WAIT are kept track of and we'll use the oldest one if no
- CLOSED connections are found. Thanks to Eddie C. Dost for a very
- nice algorithm for the TIME_WAIT search. */
- uip_connr = 0;
- for(c = 0; c < UIP_CONNS; ++c) {
- if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
- uip_connr = &uip_conns[c];
- break;
- }
- if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
- if(uip_connr == 0 ||
- uip_conns[c].timer > uip_connr->timer) {
- uip_connr = &uip_conns[c];
- }
- }
- }
-
- if(uip_connr == 0) {
- /* All connections are used already, we drop packet and hope that
- the remote end will retransmit the packet at a time when we
- have more spare connections. */
- UIP_STAT(++uip_stat.tcp.syndrop);
- UIP_LOG("tcp: found no unused connections.");
- goto drop;
- }
- uip_conn = uip_connr;
-
- /* Fill in the necessary fields for the new connection. */
- uip_connr->rto = uip_connr->timer = UIP_RTO;
- uip_connr->sa = 0;
- uip_connr->sv = 4;
- uip_connr->nrtx = 0;
- uip_connr->lport = BUF->destport;
- uip_connr->rport = BUF->srcport;
- uip_ipaddr_copy(&uip_connr->ripaddr, &BUF->srcipaddr);
- uip_connr->tcpstateflags = UIP_SYN_RCVD;
-
- uip_connr->snd_nxt[0] = iss[0];
- uip_connr->snd_nxt[1] = iss[1];
- uip_connr->snd_nxt[2] = iss[2];
- uip_connr->snd_nxt[3] = iss[3];
- uip_connr->len = 1;
-
- /* rcv_nxt should be the seqno from the incoming packet + 1. */
- uip_connr->rcv_nxt[3] = BUF->seqno[3];
- uip_connr->rcv_nxt[2] = BUF->seqno[2];
- uip_connr->rcv_nxt[1] = BUF->seqno[1];
- uip_connr->rcv_nxt[0] = BUF->seqno[0];
- uip_add_rcv_nxt(1);
-
- /* Parse the TCP MSS option, if present. */
- if((BUF->tcpoffset & 0xf0) > 0x50) {
- for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
- opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
- if(opt == TCP_OPT_END) {
- /* End of options. */
- break;
- } else if(opt == TCP_OPT_NOOP) {
- ++c;
- /* NOP option. */
- } else if(opt == TCP_OPT_MSS &&
- uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
- /* An MSS option with the right option length. */
- tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
- (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
- uip_connr->initialmss = uip_connr->mss =
- tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
-
- /* And we are done processing options. */
- break;
- } else {
- /* All other options have a length field, so that we easily
- can skip past them. */
- if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
- /* If the length field is zero, the options are malformed
- and we don't process them further. */
- break;
- }
- c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
- }
- }
- }
-
- /* Our response will be a SYNACK. */
-#if UIP_ACTIVE_OPEN
- tcp_send_synack:
- BUF->flags = TCP_ACK;
-
- tcp_send_syn:
- BUF->flags |= TCP_SYN;
-#else /* UIP_ACTIVE_OPEN */
- tcp_send_synack:
- BUF->flags = TCP_SYN | TCP_ACK;
-#endif /* UIP_ACTIVE_OPEN */
-
- /* We send out the TCP Maximum Segment Size option with our
- SYNACK. */
- BUF->optdata[0] = TCP_OPT_MSS;
- BUF->optdata[1] = TCP_OPT_MSS_LEN;
- BUF->optdata[2] = (UIP_TCP_MSS) / 256;
- BUF->optdata[3] = (UIP_TCP_MSS) & 255;
- uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
- BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
- goto tcp_send;
-
- /* This label will be jumped to if we found an active connection. */
- found:
- uip_conn = uip_connr;
- uip_flags = 0;
- /* We do a very naive form of TCP reset processing; we just accept
- any RST and kill our connection. We should in fact check if the
- sequence number of this reset is within our advertised window
- before we accept the reset. */
- if(BUF->flags & TCP_RST) {
- uip_connr->tcpstateflags = UIP_CLOSED;
- UIP_LOG("tcp: got reset, aborting connection.");
- uip_flags = UIP_ABORT;
- UIP_APPCALL();
- goto drop;
- }
- /* Calculate the length of the data, if the application has sent
- any data to us. */
- c = (BUF->tcpoffset >> 4) << 2;
- /* uip_len will contain the length of the actual TCP data. This is
- calculated by subtracing the length of the TCP header (in
- c) and the length of the IP header (20 bytes). */
- uip_len = uip_len - c - UIP_IPH_LEN;
-
- /* First, check if the sequence number of the incoming packet is
- what we're expecting next. If not, we send out an ACK with the
- correct numbers in. */
- if(!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
- ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)))) {
- if((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
- (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
- BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
- BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
- BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
- goto tcp_send_ack;
- }
- }
-
- /* Next, check if the incoming segment acknowledges any outstanding
- data. If so, we update the sequence number, reset the length of
- the outstanding data, calculate RTT estimations, and reset the
- retransmission timer. */
- if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
- uip_add32(uip_connr->snd_nxt, uip_connr->len);
-
- if(BUF->ackno[0] == uip_acc32[0] &&
- BUF->ackno[1] == uip_acc32[1] &&
- BUF->ackno[2] == uip_acc32[2] &&
- BUF->ackno[3] == uip_acc32[3]) {
- /* Update sequence number. */
- uip_connr->snd_nxt[0] = uip_acc32[0];
- uip_connr->snd_nxt[1] = uip_acc32[1];
- uip_connr->snd_nxt[2] = uip_acc32[2];
- uip_connr->snd_nxt[3] = uip_acc32[3];
-
- /* Do RTT estimation, unless we have done retransmissions. */
- if(uip_connr->nrtx == 0) {
- signed char m;
- m = uip_connr->rto - uip_connr->timer;
- /* This is taken directly from VJs original code in his paper */
- m = m - (uip_connr->sa >> 3);
- uip_connr->sa += m;
- if(m < 0) {
- m = -m;
- }
- m = m - (uip_connr->sv >> 2);
- uip_connr->sv += m;
- uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
-
- }
- /* Set the acknowledged flag. */
- uip_flags = UIP_ACKDATA;
- /* Reset the retransmission timer. */
- uip_connr->timer = uip_connr->rto;
-
- /* Reset length of outstanding data. */
- uip_connr->len = 0;
- }
-
- }
-
- /* Do different things depending on in what state the connection is. */
- switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
- /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
- implemented, since we force the application to close when the
- peer sends a FIN (hence the application goes directly from
- ESTABLISHED to LAST_ACK). */
- case UIP_SYN_RCVD:
- /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
- we are waiting for an ACK that acknowledges the data we sent
- out the last time. Therefore, we want to have the UIP_ACKDATA
- flag set. If so, we enter the ESTABLISHED state. */
- if(uip_flags & UIP_ACKDATA) {
- uip_connr->tcpstateflags = UIP_ESTABLISHED;
- uip_flags = UIP_CONNECTED;
- uip_connr->len = 0;
- if(uip_len > 0) {
- uip_flags |= UIP_NEWDATA;
- uip_add_rcv_nxt(uip_len);
- }
- uip_slen = 0;
- UIP_APPCALL();
- goto appsend;
- }
- goto drop;
-#if UIP_ACTIVE_OPEN
- case UIP_SYN_SENT:
- /* In SYN_SENT, we wait for a SYNACK that is sent in response to
- our SYN. The rcv_nxt is set to sequence number in the SYNACK
- plus one, and we send an ACK. We move into the ESTABLISHED
- state. */
- if((uip_flags & UIP_ACKDATA) &&
- (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
-
- /* Parse the TCP MSS option, if present. */
- if((BUF->tcpoffset & 0xf0) > 0x50) {
- for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
- opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];
- if(opt == TCP_OPT_END) {
- /* End of options. */
- break;
- } else if(opt == TCP_OPT_NOOP) {
- ++c;
- /* NOP option. */
- } else if(opt == TCP_OPT_MSS &&
- uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
- /* An MSS option with the right option length. */
- tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
- uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
- uip_connr->initialmss =
- uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
-
- /* And we are done processing options. */
- break;
- } else {
- /* All other options have a length field, so that we easily
- can skip past them. */
- if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
- /* If the length field is zero, the options are malformed
- and we don't process them further. */
- break;
- }
- c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
- }
- }
- }
- uip_connr->tcpstateflags = UIP_ESTABLISHED;
- uip_connr->rcv_nxt[0] = BUF->seqno[0];
- uip_connr->rcv_nxt[1] = BUF->seqno[1];
- uip_connr->rcv_nxt[2] = BUF->seqno[2];
- uip_connr->rcv_nxt[3] = BUF->seqno[3];
- uip_add_rcv_nxt(1);
- uip_flags = UIP_CONNECTED | UIP_NEWDATA;
- uip_connr->len = 0;
- uip_len = 0;
- uip_slen = 0;
- UIP_APPCALL();
- goto appsend;
- }
- /* Inform the application that the connection failed */
- uip_flags = UIP_ABORT;
- UIP_APPCALL();
- /* The connection is closed after we send the RST */
- uip_conn->tcpstateflags = UIP_CLOSED;
- goto reset;
-#endif /* UIP_ACTIVE_OPEN */
-
- case UIP_ESTABLISHED:
- /* In the ESTABLISHED state, we call upon the application to feed
- data into the uip_buf. If the UIP_ACKDATA flag is set, the
- application should put new data into the buffer, otherwise we are
- retransmitting an old segment, and the application should put that
- data into the buffer.
-
- If the incoming packet is a FIN, we should close the connection on
- this side as well, and we send out a FIN and enter the LAST_ACK
- state. We require that there is no outstanding data; otherwise the
- sequence numbers will be screwed up. */
-
- if(BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
- if(uip_outstanding(uip_connr)) {
- goto drop;
- }
- uip_add_rcv_nxt(1 + uip_len);
- uip_flags |= UIP_CLOSE;
- if(uip_len > 0) {
- uip_flags |= UIP_NEWDATA;
- }
- UIP_APPCALL();
- uip_connr->len = 1;
- uip_connr->tcpstateflags = UIP_LAST_ACK;
- uip_connr->nrtx = 0;
- tcp_send_finack:
- BUF->flags = TCP_FIN | TCP_ACK;
- goto tcp_send_nodata;
- }
-
- /* Check the URG flag. If this is set, the segment carries urgent
- data that we must pass to the application. */
- if((BUF->flags & TCP_URG) != 0) {
-#if UIP_URGDATA > 0
- uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
- if(uip_urglen > uip_len) {
- /* There is more urgent data in the next segment to come. */
- uip_urglen = uip_len;
- }
- uip_add_rcv_nxt(uip_urglen);
- uip_len -= uip_urglen;
- uip_urgdata = uip_appdata;
- uip_appdata += uip_urglen;
- } else {
- uip_urglen = 0;
-#else /* UIP_URGDATA > 0 */
- uip_appdata = ((char *)uip_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]);
- uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
-#endif /* UIP_URGDATA > 0 */
- }
-
- /* If uip_len > 0 we have TCP data in the packet, and we flag this
- by setting the UIP_NEWDATA flag and update the sequence number
- we acknowledge. If the application has stopped the dataflow
- using uip_stop(), we must not accept any data packets from the
- remote host. */
- if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
- uip_flags |= UIP_NEWDATA;
- uip_add_rcv_nxt(uip_len);
- }
-
- /* Check if the available buffer space advertised by the other end
- is smaller than the initial MSS for this connection. If so, we
- set the current MSS to the window size to ensure that the
- application does not send more data than the other end can
- handle.
-
- If the remote host advertises a zero window, we set the MSS to
- the initial MSS so that the application will send an entire MSS
- of data. This data will not be acknowledged by the receiver,
- and the application will retransmit it. This is called the
- "persistent timer" and uses the retransmission mechanism.
- */
- tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1];
- if(tmp16 > uip_connr->initialmss ||
- tmp16 == 0) {
- tmp16 = uip_connr->initialmss;
- }
- uip_connr->mss = tmp16;
-
- /* If this packet constitutes an ACK for outstanding data (flagged
- by the UIP_ACKDATA flag, we should call the application since it
- might want to send more data. If the incoming packet had data
- from the peer (as flagged by the UIP_NEWDATA flag), the
- application must also be notified.
-
- When the application is called, the global variable uip_len
- contains the length of the incoming data. The application can
- access the incoming data through the global pointer
- uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN
- bytes into the uip_buf array.
-
- If the application wishes to send any data, this data should be
- put into the uip_appdata and the length of the data should be
- put into uip_len. If the application don't have any data to
- send, uip_len must be set to 0. */
- if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
- uip_slen = 0;
- UIP_APPCALL();
-
- appsend:
-
- if(uip_flags & UIP_ABORT) {
- uip_slen = 0;
- uip_connr->tcpstateflags = UIP_CLOSED;
- BUF->flags = TCP_RST | TCP_ACK;
- goto tcp_send_nodata;
- }
-
- if(uip_flags & UIP_CLOSE) {
- uip_slen = 0;
- uip_connr->len = 1;
- uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
- uip_connr->nrtx = 0;
- BUF->flags = TCP_FIN | TCP_ACK;
- goto tcp_send_nodata;
- }
-
- /* If uip_slen > 0, the application has data to be sent. */
- if(uip_slen > 0) {
-
- /* If the connection has acknowledged data, the contents of
- the ->len variable should be discarded. */
- if((uip_flags & UIP_ACKDATA) != 0) {
- uip_connr->len = 0;
- }
-
- /* If the ->len variable is non-zero the connection has
- already data in transit and cannot send anymore right
- now. */
- if(uip_connr->len == 0) {
-
- /* The application cannot send more than what is allowed by
- the mss (the minumum of the MSS and the available
- window). */
- if(uip_slen > uip_connr->mss) {
- uip_slen = uip_connr->mss;
- }
-
- /* Remember how much data we send out now so that we know
- when everything has been acknowledged. */
- uip_connr->len = uip_slen;
- } else {
-
- /* If the application already had unacknowledged data, we
- make sure that the application does not send (i.e.,
- retransmit) out more than it previously sent out. */
- uip_slen = uip_connr->len;
- }
- }
- uip_connr->nrtx = 0;
- apprexmit:
- uip_appdata = uip_sappdata;
-
- /* If the application has data to be sent, or if the incoming
- packet had new data in it, we must send out a packet. */
- if(uip_slen > 0 && uip_connr->len > 0) {
- /* Add the length of the IP and TCP headers. */
- uip_len = uip_connr->len + UIP_TCPIP_HLEN;
- /* We always set the ACK flag in response packets. */
- BUF->flags = TCP_ACK | TCP_PSH;
- /* Send the packet. */
- goto tcp_send_noopts;
- }
- /* If there is no data to send, just send out a pure ACK if
- there is newdata. */
- if(uip_flags & UIP_NEWDATA) {
- uip_len = UIP_TCPIP_HLEN;
- BUF->flags = TCP_ACK;
- goto tcp_send_noopts;
- }
- }
- goto drop;
- case UIP_LAST_ACK:
- /* We can close this connection if the peer has acknowledged our
- FIN. This is indicated by the UIP_ACKDATA flag. */
- if(uip_flags & UIP_ACKDATA) {
- uip_connr->tcpstateflags = UIP_CLOSED;
- uip_flags = UIP_CLOSE;
- UIP_APPCALL();
- }
- break;
-
- case UIP_FIN_WAIT_1:
- /* The application has closed the connection, but the remote host
- hasn't closed its end yet. Thus we do nothing but wait for a
- FIN from the other side. */
- if(uip_len > 0) {
- uip_add_rcv_nxt(uip_len);
- }
- if(BUF->flags & TCP_FIN) {
- if(uip_flags & UIP_ACKDATA) {
- uip_connr->tcpstateflags = UIP_TIME_WAIT;
- uip_connr->timer = 0;
- uip_connr->len = 0;
- } else {
- uip_connr->tcpstateflags = UIP_CLOSING;
- }
- uip_add_rcv_nxt(1);
- uip_flags = UIP_CLOSE;
- UIP_APPCALL();
- goto tcp_send_ack;
- } else if(uip_flags & UIP_ACKDATA) {
- uip_connr->tcpstateflags = UIP_FIN_WAIT_2;
- uip_connr->len = 0;
- goto drop;
- }
- if(uip_len > 0) {
- goto tcp_send_ack;
- }
- goto drop;
-
- case UIP_FIN_WAIT_2:
- if(uip_len > 0) {
- uip_add_rcv_nxt(uip_len);
- }
- if(BUF->flags & TCP_FIN) {
- uip_connr->tcpstateflags = UIP_TIME_WAIT;
- uip_connr->timer = 0;
- uip_add_rcv_nxt(1);
- uip_flags = UIP_CLOSE;
- UIP_APPCALL();
- goto tcp_send_ack;
- }
- if(uip_len > 0) {
- goto tcp_send_ack;
- }
- goto drop;
-
- case UIP_TIME_WAIT:
- goto tcp_send_ack;
-
- case UIP_CLOSING:
- if(uip_flags & UIP_ACKDATA) {
- uip_connr->tcpstateflags = UIP_TIME_WAIT;
- uip_connr->timer = 0;
- }
- }
- goto drop;
-
- /* 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. */
- tcp_send_ack:
- BUF->flags = TCP_ACK;
-
- tcp_send_nodata:
- uip_len = UIP_IPTCPH_LEN;
-
- tcp_send_noopts:
- BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
-
- /* 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
- headers before calculating the checksum and finally send the
- packet. */
- tcp_send:
- BUF->ackno[0] = uip_connr->rcv_nxt[0];
- BUF->ackno[1] = uip_connr->rcv_nxt[1];
- BUF->ackno[2] = uip_connr->rcv_nxt[2];
- BUF->ackno[3] = uip_connr->rcv_nxt[3];
-
- BUF->seqno[0] = uip_connr->snd_nxt[0];
- BUF->seqno[1] = uip_connr->snd_nxt[1];
- BUF->seqno[2] = uip_connr->snd_nxt[2];
- BUF->seqno[3] = uip_connr->snd_nxt[3];
-
- BUF->proto = UIP_PROTO_TCP;
-
- BUF->srcport = uip_connr->lport;
- BUF->destport = uip_connr->rport;
-
- uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
- uip_ipaddr_copy(&BUF->destipaddr, &uip_connr->ripaddr);
-
- if(uip_connr->tcpstateflags & UIP_STOPPED) {
- /* If the connection has issued uip_stop(), we advertise a zero
- window so that the remote host will stop sending data. */
- BUF->wnd[0] = BUF->wnd[1] = 0;
- } else {
- BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
- BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
- }
-
- tcp_send_noconn:
- BUF->ttl = UIP_TTL;
-#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 */
-
- BUF->urgp[0] = BUF->urgp[1] = 0;
-
- /* Calculate TCP checksum. */
- BUF->tcpchksum = 0;
- BUF->tcpchksum = ~(uip_tcpchksum());
-
- ip_send_nolen:
-#if UIP_CONF_IPV6
- BUF->vtc = 0x60;
- BUF->tcflow = 0x00;
- BUF->flow = 0x00;
-#else /* UIP_CONF_IPV6 */
- BUF->vhl = 0x45;
- BUF->tos = 0;
- BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
- ++ipid;
- BUF->ipid[0] = ipid >> 8;
- BUF->ipid[1] = ipid & 0xff;
- /* Calculate IP checksum. */
- BUF->ipchksum = 0;
- BUF->ipchksum = ~(uip_ipchksum());
- DEBUG_PRINTF("uip ip_send_nolen: checksum 0x%04x\n", uip_ipchksum());
-#endif /* UIP_CONF_IPV6 */
- UIP_STAT(++uip_stat.tcp.sent);
-#if UIP_CONF_IPV6
- send:
-#endif /* UIP_CONF_IPV6 */
- DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len,
- (BUF->len[0] << 8) | BUF->len[1]);
-
- UIP_STAT(++uip_stat.ip.sent);
- /* Return and let the caller do the actual transmission. */
- uip_flags = 0;
- return;
-
- drop:
- uip_len = 0;
- uip_flags = 0;
- return;
-}
-/*---------------------------------------------------------------------------*/
-u16_t
-htons(u16_t val)
-{
- return HTONS(val);
-}
-
-u32_t
-htonl(u32_t val)
-{
- return HTONL(val);
-}
-/*---------------------------------------------------------------------------*/
-void
-uip_send(const void *data, int len)
-{
- int copylen;
-#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) {
- memcpy(uip_sappdata, (data), uip_slen);
- }
- }
-}
-/*---------------------------------------------------------------------------*/
-/** @} */
-#endif /* UIP_CONF_IPV6 */
-
diff --git a/lib/lufa/Projects/Webserver/Lib/uip/uip.h b/lib/lufa/Projects/Webserver/Lib/uip/uip.h
deleted file mode 100644
index 7b87a2c77..000000000
--- a/lib/lufa/Projects/Webserver/Lib/uip/uip.h
+++ /dev/null
@@ -1,2130 +0,0 @@
-
-/**
- * \addtogroup uip
- * @{
- */
-
-/**
- * \file
- * Header file for the uIP TCP/IP stack.
- * \author Adam Dunkels <adam@dunkels.com>
- * \author Julien Abeille <jabeille@cisco.com> (IPv6 related code)
- * \author Mathilde Durvy <mdurvy@cisco.com> (IPv6 related code)
- *
- * The uIP TCP/IP stack header file contains definitions for a number
- * of C macros that are used by uIP programs as well as internal uIP
- * structures, TCP/IP header structures and function declarations.
- *
- */
-
-/*
- * Copyright (c) 2001-2003, Adam Dunkels.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * This file is part of the uIP TCP/IP stack.
- *
- * $Id: uip.h,v 1.24 2009/04/06 13:18:50 nvt-se Exp $
- *
- */
-
-#ifndef __UIP_H__
-#define __UIP_H__
-
-#include "uipopt.h"
-
-/**
- * Representation of an IP address.
- *
- */
-#if UIP_CONF_IPV6
-typedef union uip_ip6addr_t {
- u8_t u8[16]; /* Initialiser, must come first!!! */
- u16_t u16[8];
-} uip_ip6addr_t;
-
-typedef uip_ip6addr_t uip_ipaddr_t;
-#else /* UIP_CONF_IPV6 */
-typedef union uip_ip4addr_t {
- u8_t u8[4]; /* Initialiser, must come first!!! */
- u16_t u16[2];
-#if 0
- u32_t u32;
-#endif
-} uip_ip4addr_t;
-typedef uip_ip4addr_t uip_ipaddr_t;
-#endif /* UIP_CONF_IPV6 */
-
-
-/*---------------------------------------------------------------------------*/
-
-/** \brief 16 bit 802.15.4 address */
-struct uip_802154_shortaddr {
- u8_t addr[2];
-};
-/** \brief 64 bit 802.15.4 address */
-struct uip_802154_longaddr {
- u8_t addr[8];
-};
-
-/** \brief 802.11 address */
-struct uip_80211_addr {
- u8_t addr[6];
-};
-
-/** \brief 802.3 address */
-struct uip_eth_addr {
- u8_t addr[6];
-};
-
-#if UIP_CONF_LL_802154
-/** \brief 802.15.4 address */
-typedef struct uip_802154_longaddr uip_lladdr_t;
-#define UIP_802154_SHORTADDR_LEN 2
-#define UIP_802154_LONGADDR_LEN 8
-#define UIP_LLADDR_LEN UIP_802154_LONGADDR_LEN
-#else /*UIP_CONF_LL_802154*/
-#if UIP_CONF_LL_80211
-/** \brief 802.11 address */
-typedef struct uip_80211_addr uip_lladdr_t;
-#define UIP_LLADDR_LEN 6
-#else /*UIP_CONF_LL_80211*/
-/** \brief Ethernet address */
-typedef struct uip_eth_addr uip_lladdr_t;
-#define UIP_LLADDR_LEN 6
-#endif /*UIP_CONF_LL_80211*/
-#endif /*UIP_CONF_LL_802154*/
-
-/*---------------------------------------------------------------------------*/
-/* First, the functions that should be called from the
- * system. Initialization, the periodic timer, and incoming packets are
- * handled by the following three functions.
- */
-/**
- * \defgroup uipconffunc uIP configuration functions
- * @{
- *
- * The uIP configuration functions are used for setting run-time
- * parameters in uIP such as IP addresses.
- */
-
-/**
- * Set the IP address of this host.
- *
- * The IP address is represented as a 4-byte array where the first
- * octet of the IP address is put in the first member of the 4-byte
- * array.
- *
- * Example:
- \code
-
- uip_ipaddr_t addr;
-
- uip_ipaddr(&addr, 192,168,1,2);
- uip_sethostaddr(&addr);
-
- \endcode
- * \param addr A pointer to an IP address of type uip_ipaddr_t;
- *
- * \sa uip_ipaddr()
- *
- * \hideinitializer
- */
-#define uip_sethostaddr(addr) uip_ipaddr_copy(&uip_hostaddr, (addr))
-
-/**
- * Get the IP address of this host.
- *
- * The IP address is represented as a 4-byte array where the first
- * octet of the IP address is put in the first member of the 4-byte
- * array.
- *
- * Example:
- \code
- uip_ipaddr_t hostaddr;
-
- uip_gethostaddr(&hostaddr);
- \endcode
- * \param addr A pointer to a uip_ipaddr_t variable that will be
- * filled in with the currently configured IP address.
- *
- * \hideinitializer
- */
-#define uip_gethostaddr(addr) uip_ipaddr_copy((addr), &uip_hostaddr)
-
-/**
- * Set the default router's IP address.
- *
- * \param addr A pointer to a uip_ipaddr_t variable containing the IP
- * address of the default router.
- *
- * \sa uip_ipaddr()
- *
- * \hideinitializer
- */
-#define uip_setdraddr(addr) uip_ipaddr_copy(&uip_draddr, (addr))
-
-/**
- * Set the netmask.
- *
- * \param addr A pointer to a uip_ipaddr_t variable containing the IP
- * address of the netmask.
- *
- * \sa uip_ipaddr()
- *
- * \hideinitializer
- */
-#define uip_setnetmask(addr) uip_ipaddr_copy(&uip_netmask, (addr))
-
-
-/**
- * Get the default router's IP address.
- *
- * \param addr A pointer to a uip_ipaddr_t variable that will be
- * filled in with the IP address of the default router.
- *
- * \hideinitializer
- */
-#define uip_getdraddr(addr) uip_ipaddr_copy((addr), &uip_draddr)
-
-/**
- * Get the netmask.
- *
- * \param addr A pointer to a uip_ipaddr_t variable that will be
- * filled in with the value of the netmask.
- *
- * \hideinitializer
- */
-#define uip_getnetmask(addr) uip_ipaddr_copy((addr), &uip_netmask)
-
-/** @} */
-
-/**
- * \defgroup uipinit uIP initialization functions
- * @{
- *
- * The uIP initialization functions are used for booting uIP.
- */
-
-/**
- * uIP initialization function.
- *
- * This function should be called at boot up to initialize the uIP
- * TCP/IP stack.
- */
-void uip_init(void);
-
-/**
- * uIP initialization function.
- *
- * This function may be used at boot time to set the initial ip_id.
- */
-void uip_setipid(u16_t id);
-
-/** @} */
-
-/**
- * \defgroup uipdevfunc uIP device driver functions
- * @{
- *
- * These functions are used by a network device driver for interacting
- * with uIP.
- */
-
-/**
- * Process an incoming packet.
- *
- * This function should be called when the device driver has received
- * a packet from the network. The packet from the device driver must
- * be present in the uip_buf buffer, and the length of the packet
- * should be placed in the uip_len variable.
- *
- * When the function returns, there may be an outbound packet placed
- * in the uip_buf packet buffer. If so, the uip_len variable is set to
- * the length of the packet. If no packet is to be sent out, the
- * uip_len variable is set to 0.
- *
- * The usual way of calling the function is presented by the source
- * code below.
- \code
- uip_len = devicedriver_poll();
- if(uip_len > 0) {
- uip_input();
- if(uip_len > 0) {
- devicedriver_send();
- }
- }
- \endcode
- *
- * \note If you are writing a uIP device driver that needs ARP
- * (Address Resolution Protocol), e.g., when running uIP over
- * Ethernet, you will need to call the uIP ARP code before calling
- * this function:
- \code
- #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
- uip_len = ethernet_devicedrver_poll();
- if(uip_len > 0) {
- if(BUF->type == HTONS(UIP_ETHTYPE_IP)) {
- uip_arp_ipin();
- uip_input();
- if(uip_len > 0) {
- uip_arp_out();
- ethernet_devicedriver_send();
- }
- } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
- uip_arp_arpin();
- if(uip_len > 0) {
- ethernet_devicedriver_send();
- }
- }
- \endcode
- *
- * \hideinitializer
- */
-#define uip_input() uip_process(UIP_DATA)
-
-
-/**
- * Periodic processing for a connection identified by its number.
- *
- * This function does the necessary periodic processing (timers,
- * polling) for a uIP TCP connection, and should be called when the
- * periodic uIP timer goes off. It should be called for every
- * connection, regardless of whether they are open of closed.
- *
- * When the function returns, it may have an outbound packet waiting
- * for service in the uIP packet buffer, and if so the uip_len
- * variable is set to a value larger than zero. The device driver
- * should be called to send out the packet.
- *
- * The usual way of calling the function is through a for() loop like
- * this:
- \code
- for(i = 0; i < UIP_CONNS; ++i) {
- uip_periodic(i);
- if(uip_len > 0) {
- devicedriver_send();
- }
- }
- \endcode
- *
- * \note If you are writing a uIP device driver that needs ARP
- * (Address Resolution Protocol), e.g., when running uIP over
- * Ethernet, you will need to call the uip_arp_out() function before
- * calling the device driver:
- \code
- for(i = 0; i < UIP_CONNS; ++i) {
- uip_periodic(i);
- if(uip_len > 0) {
- uip_arp_out();
- ethernet_devicedriver_send();
- }
- }
- \endcode
- *
- * \param conn The number of the connection which is to be periodically polled.
- *
- * \hideinitializer
- */
-#if UIP_TCP
-#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \
- uip_process(UIP_TIMER); } while (0)
-
-/**
- *
- *
- */
-#define uip_conn_active(conn) (uip_conns[conn].tcpstateflags != UIP_CLOSED)
-
-/**
- * Perform periodic processing for a connection identified by a pointer
- * to its structure.
- *
- * Same as uip_periodic() but takes a pointer to the actual uip_conn
- * struct instead of an integer as its argument. This function can be
- * used to force periodic processing of a specific connection.
- *
- * \param conn A pointer to the uip_conn struct for the connection to
- * be processed.
- *
- * \hideinitializer
- */
-#define uip_periodic_conn(conn) do { uip_conn = conn; \
- uip_process(UIP_TIMER); } while (0)
-
-/**
- * Request that a particular connection should be polled.
- *
- * Similar to uip_periodic_conn() but does not perform any timer
- * processing. The application is polled for new data.
- *
- * \param conn A pointer to the uip_conn struct for the connection to
- * be processed.
- *
- * \hideinitializer
- */
-#define uip_poll_conn(conn) do { uip_conn = conn; \
- uip_process(UIP_POLL_REQUEST); } while (0)
-
-#endif /* UIP_TCP */
-
-#if UIP_UDP
-/**
- * Periodic processing for a UDP connection identified by its number.
- *
- * This function is essentially the same as uip_periodic(), but for
- * UDP connections. It is called in a similar fashion as the
- * uip_periodic() function:
- \code
- for(i = 0; i < UIP_UDP_CONNS; i++) {
- uip_udp_periodic(i);
- if(uip_len > 0) {
- devicedriver_send();
- }
- }
- \endcode
- *
- * \note As for the uip_periodic() function, special care has to be
- * taken when using uIP together with ARP and Ethernet:
- \code
- for(i = 0; i < UIP_UDP_CONNS; i++) {
- uip_udp_periodic(i);
- if(uip_len > 0) {
- uip_arp_out();
- ethernet_devicedriver_send();
- }
- }
- \endcode
- *
- * \param conn The number of the UDP connection to be processed.
- *
- * \hideinitializer
- */
-#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \
- uip_process(UIP_UDP_TIMER); } while(0)
-
-/**
- * Periodic processing for a UDP connection identified by a pointer to
- * its structure.
- *
- * Same as uip_udp_periodic() but takes a pointer to the actual
- * uip_conn struct instead of an integer as its argument. This
- * function can be used to force periodic processing of a specific
- * connection.
- *
- * \param conn A pointer to the uip_udp_conn struct for the connection
- * to be processed.
- *
- * \hideinitializer
- */
-#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \
- uip_process(UIP_UDP_TIMER); } while(0)
-#endif /* UIP_UDP */
-
-/** \brief Abandon the reassembly of the current packet */
-void uip_reass_over(void);
-
-/**
- * The uIP packet buffer.
- *
- * The uip_buf array is used to hold incoming and outgoing
- * packets. The device driver should place incoming data into this
- * buffer. When sending data, the device driver should read the link
- * level headers and the TCP/IP headers from this buffer. The size of
- * the link level headers is configured by the UIP_LLH_LEN define.
- *
- * \note The application data need not be placed in this buffer, so
- * the device driver must read it from the place pointed to by the
- * uip_appdata pointer as illustrated by the following example:
- \code
- void
- devicedriver_send(void)
- {
- hwsend(&uip_buf[0], UIP_LLH_LEN);
- if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) {
- hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN);
- } else {
- hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN);
- hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN);
- }
- }
- \endcode
-*/
-extern u8_t uip_buf[UIP_BUFSIZE+2];
-
-
-
-/** @} */
-
-/*---------------------------------------------------------------------------*/
-/* Functions that are used by the uIP application program. Opening and
- * closing connections, sending and receiving data, etc. is all
- * handled by the functions below.
- */
-/**
- * \defgroup uipappfunc uIP application functions
- * @{
- *
- * Functions used by an application running of top of uIP.
- */
-
-/**
- * Start listening to the specified port.
- *
- * \note Since this function expects the port number in network byte
- * order, a conversion using HTONS() or htons() is necessary.
- *
- \code
- uip_listen(HTONS(80));
- \endcode
- *
- * \param port A 16-bit port number in network byte order.
- */
-void uip_listen(u16_t port);
-
-/**
- * Stop listening to the specified port.
- *
- * \note Since this function expects the port number in network byte
- * order, a conversion using HTONS() or htons() is necessary.
- *
- \code
- uip_unlisten(HTONS(80));
- \endcode
- *
- * \param port A 16-bit port number in network byte order.
- */
-void uip_unlisten(u16_t port);
-
-/**
- * Connect to a remote host using TCP.
- *
- * This function is used to start a new connection to the specified
- * port on the specified host. It allocates a new connection identifier,
- * sets the connection to the SYN_SENT state and sets the
- * retransmission timer to 0. This will cause a TCP SYN segment to be
- * sent out the next time this connection is periodically processed,
- * which usually is done within 0.5 seconds after the call to
- * uip_connect().
- *
- * \note This function is available only if support for active open
- * has been configured by defining UIP_ACTIVE_OPEN to 1 in uipopt.h.
- *
- * \note Since this function requires the port number to be in network
- * byte order, a conversion using HTONS() or htons() is necessary.
- *
- \code
- uip_ipaddr_t ipaddr;
-
- uip_ipaddr(&ipaddr, 192,168,1,2);
- uip_connect(&ipaddr, HTONS(80));
- \endcode
- *
- * \param ripaddr The IP address of the remote host.
- *
- * \param port A 16-bit port number in network byte order.
- *
- * \return A pointer to the uIP connection identifier for the new connection,
- * or NULL if no connection could be allocated.
- *
- */
-struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, u16_t port);
-
-
-
-/**
- * \internal
- *
- * Check if a connection has outstanding (i.e., unacknowledged) data.
- *
- * \param conn A pointer to the uip_conn structure for the connection.
- *
- * \hideinitializer
- */
-#define uip_outstanding(conn) ((conn)->len)
-
-/**
- * Send data on the current connection.
- *
- * This function is used to send out a single segment of TCP
- * data. Only applications that have been invoked by uIP for event
- * processing can send data.
- *
- * The amount of data that actually is sent out after a call to this
- * function is determined by the maximum amount of data TCP allows. uIP
- * will automatically crop the data so that only the appropriate
- * amount of data is sent. The function uip_mss() can be used to query
- * uIP for the amount of data that actually will be sent.
- *
- * \note This function does not guarantee that the sent data will
- * arrive at the destination. If the data is lost in the network, the
- * application will be invoked with the uip_rexmit() event being
- * set. The application will then have to resend the data using this
- * function.
- *
- * \param data A pointer to the data which is to be sent.
- *
- * \param len The maximum amount of data bytes to be sent.
- *
- * \hideinitializer
- */
-void uip_send(const void *data, int len);
-
-/**
- * The length of any incoming data that is currently available (if available)
- * in the uip_appdata buffer.
- *
- * The test function uip_data() must first be used to check if there
- * is any data available at all.
- *
- * \hideinitializer
- */
-/*void uip_datalen(void);*/
-#define uip_datalen() uip_len
-
-/**
- * The length of any out-of-band data (urgent data) that has arrived
- * on the connection.
- *
- * \note The configuration parameter UIP_URGDATA must be set for this
- * function to be enabled.
- *
- * \hideinitializer
- */
-#define uip_urgdatalen() uip_urglen
-
-/**
- * Close the current connection.
- *
- * This function will close the current connection in a nice way.
- *
- * \hideinitializer
- */
-#define uip_close() (uip_flags = UIP_CLOSE)
-
-/**
- * Abort the current connection.
- *
- * This function will abort (reset) the current connection, and is
- * usually used when an error has occurred that prevents using the
- * uip_close() function.
- *
- * \hideinitializer
- */
-#define uip_abort() (uip_flags = UIP_ABORT)
-
-/**
- * Tell the sending host to stop sending data.
- *
- * This function will close our receiver's window so that we stop
- * receiving data for the current connection.
- *
- * \hideinitializer
- */
-#define uip_stop() (uip_conn->tcpstateflags |= UIP_STOPPED)
-
-/**
- * Find out if the current connection has been previously stopped with
- * uip_stop().
- *
- * \hideinitializer
- */
-#define uip_stopped(conn) ((conn)->tcpstateflags & UIP_STOPPED)
-
-/**
- * Restart the current connection, if is has previously been stopped
- * with uip_stop().
- *
- * This function will open the receiver's window again so that we
- * start receiving data for the current connection.
- *
- * \hideinitializer
- */
-#define uip_restart() do { uip_flags |= UIP_NEWDATA; \
- uip_conn->tcpstateflags &= ~UIP_STOPPED; \
- } while(0)
-
-
-/* uIP tests that can be made to determine in what state the current
- connection is, and what the application function should do. */
-
-/**
- * Is the current connection a UDP connection?
- *
- * This function checks whether the current connection is a UDP connection.
- *
- * \hideinitializer
- *
- */
-#define uip_udpconnection() (uip_conn == NULL)
-
-/**
- * Is new incoming data available?
- *
- * Will reduce to non-zero if there is new data for the application
- * present at the uip_appdata pointer. The size of the data is
- * available through the uip_len variable.
- *
- * \hideinitializer
- */
-#define uip_newdata() (uip_flags & UIP_NEWDATA)
-
-/**
- * Has previously sent data been acknowledged?
- *
- * Will reduce to non-zero if the previously sent data has been
- * acknowledged by the remote host. This means that the application
- * can send new data.
- *
- * \hideinitializer
- */
-#define uip_acked() (uip_flags & UIP_ACKDATA)
-
-/**
- * Has the connection just been connected?
- *
- * Reduces to non-zero if the current connection has been connected to
- * a remote host. This will happen both if the connection has been
- * actively opened (with uip_connect()) or passively opened (with
- * uip_listen()).
- *
- * \hideinitializer
- */
-#define uip_connected() (uip_flags & UIP_CONNECTED)
-
-/**
- * Has the connection been closed by the other end?
- *
- * Is non-zero if the connection has been closed by the remote
- * host. The application may then do the necessary clean-ups.
- *
- * \hideinitializer
- */
-#define uip_closed() (uip_flags & UIP_CLOSE)
-
-/**
- * Has the connection been aborted by the other end?
- *
- * Non-zero if the current connection has been aborted (reset) by the
- * remote host.
- *
- * \hideinitializer
- */
-#define uip_aborted() (uip_flags & UIP_ABORT)
-
-/**
- * Has the connection timed out?
- *
- * Non-zero if the current connection has been aborted due to too many
- * retransmissions.
- *
- * \hideinitializer
- */
-#define uip_timedout() (uip_flags & UIP_TIMEDOUT)
-
-/**
- * Do we need to retransmit previously data?
- *
- * Reduces to non-zero if the previously sent data has been lost in
- * the network, and the application should retransmit it. The
- * application should send the exact same data as it did the last
- * time, using the uip_send() function.
- *
- * \hideinitializer
- */
-#define uip_rexmit() (uip_flags & UIP_REXMIT)
-
-/**
- * Is the connection being polled by uIP?
- *
- * Is non-zero if the reason the application is invoked is that the
- * current connection has been idle for a while and should be
- * polled.
- *
- * The polling event can be used for sending data without having to
- * wait for the remote host to send data.
- *
- * \hideinitializer
- */
-#define uip_poll() (uip_flags & UIP_POLL)
-
-/**
- * Get the initial maximum segment size (MSS) of the current
- * connection.
- *
- * \hideinitializer
- */
-#define uip_initialmss() (uip_conn->initialmss)
-
-/**
- * Get the current maximum segment size that can be sent on the current
- * connection.
- *
- * The current maximum segment size that can be sent on the
- * connection is computed from the receiver's window and the MSS of
- * the connection (which also is available by calling
- * uip_initialmss()).
- *
- * \hideinitializer
- */
-#define uip_mss() (uip_conn->mss)
-
-/**
- * Set up a new UDP connection.
- *
- * This function sets up a new UDP connection. The function will
- * automatically allocate an unused local port for the new
- * connection. However, another port can be chosen by using the
- * uip_udp_bind() call, after the uip_udp_new() function has been
- * called.
- *
- * Example:
- \code
- uip_ipaddr_t addr;
- struct uip_udp_conn *c;
-
- uip_ipaddr(&addr, 192,168,2,1);
- c = uip_udp_new(&addr, HTONS(12345));
- if(c != NULL) {
- uip_udp_bind(c, HTONS(12344));
- }
- \endcode
- * \param ripaddr The IP address of the remote host.
- *
- * \param rport The remote port number in network byte order.
- *
- * \return The uip_udp_conn structure for the new connection or NULL
- * if no connection could be allocated.
- */
-struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport);
-
-/**
- * Removed a UDP connection.
- *
- * \param conn A pointer to the uip_udp_conn structure for the connection.
- *
- * \hideinitializer
- */
-#define uip_udp_remove(conn) (conn)->lport = 0
-
-/**
- * Bind a UDP connection to a local port.
- *
- * \param conn A pointer to the uip_udp_conn structure for the
- * connection.
- *
- * \param port The local port number, in network byte order.
- *
- * \hideinitializer
- */
-#define uip_udp_bind(conn, port) (conn)->lport = port
-
-/**
- * Send a UDP datagram of length len on the current connection.
- *
- * This function can only be called in response to a UDP event (poll
- * or newdata). The data must be present in the uip_buf buffer, at the
- * place pointed to by the uip_appdata pointer.
- *
- * \param len The length of the data in the uip_buf buffer.
- *
- * \hideinitializer
- */
-#define uip_udp_send(len) uip_send((char *)uip_appdata, len)
-
-/** @} */
-
-/* uIP convenience and converting functions. */
-
-/**
- * \defgroup uipconvfunc uIP conversion functions
- * @{
- *
- * These functions can be used for converting between different data
- * formats used by uIP.
- */
-
-/**
- * Convert an IP address to four bytes separated by commas.
- *
- * Example:
- \code
- uip_ipaddr_t ipaddr;
- printf("ipaddr=%d.%d.%d.%d\n", uip_ipaddr_to_quad(&ipaddr));
- \endcode
- *
- * \param a A pointer to a uip_ipaddr_t.
- * \hideinitializer
- */
-#define uip_ipaddr_to_quad(a) (a)->u8[0],(a)->u8[1],(a)->u8[2],(a)->u8[3]
-
-/**
- * Construct an IP address from four bytes.
- *
- * This function constructs an IP address of the type that uIP handles
- * internally from four bytes. The function is handy for specifying IP
- * addresses to use with e.g. the uip_connect() function.
- *
- * Example:
- \code
- uip_ipaddr_t ipaddr;
- struct uip_conn *c;
-
- uip_ipaddr(&ipaddr, 192,168,1,2);
- c = uip_connect(&ipaddr, HTONS(80));
- \endcode
- *
- * \param addr A pointer to a uip_ipaddr_t variable that will be
- * filled in with the IP address.
- *
- * \param addr0 The first octet of the IP address.
- * \param addr1 The second octet of the IP address.
- * \param addr2 The third octet of the IP address.
- * \param addr3 The forth octet of the IP address.
- *
- * \hideinitializer
- */
-#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \
- (addr)->u8[0] = addr0; \
- (addr)->u8[1] = addr1; \
- (addr)->u8[2] = addr2; \
- (addr)->u8[3] = addr3; \
- } while(0)
-
-/**
- * Construct an IPv6 address from eight 16-bit words.
- *
- * This function constructs an IPv6 address.
- *
- * \hideinitializer
- */
-#define uip_ip6addr(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7) do { \
- (addr)->u16[0] = HTONS(addr0); \
- (addr)->u16[1] = HTONS(addr1); \
- (addr)->u16[2] = HTONS(addr2); \
- (addr)->u16[3] = HTONS(addr3); \
- (addr)->u16[4] = HTONS(addr4); \
- (addr)->u16[5] = HTONS(addr5); \
- (addr)->u16[6] = HTONS(addr6); \
- (addr)->u16[7] = HTONS(addr7); \
- } while(0)
-
-/**
- * Construct an IPv6 address from sixteen 8-bit words.
- *
- * This function constructs an IPv6 address.
- *
- * \hideinitializer
- */
-#define uip_ip6addr_u8(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7,addr8,addr9,addr10,addr11,addr12,addr13,addr14,addr15) do { \
- (addr)->u8[0] = addr0; \
- (addr)->u8[1] = addr1; \
- (addr)->u8[2] = addr2; \
- (addr)->u8[3] = addr3; \
- (addr)->u8[4] = addr4; \
- (addr)->u8[5] = addr5; \
- (addr)->u8[6] = addr6; \
- (addr)->u8[7] = addr7; \
- (addr)->u8[8] = addr8; \
- (addr)->u8[9] = addr9; \
- (addr)->u8[10] = addr10; \
- (addr)->u8[11] = addr11; \
- (addr)->u8[12] = addr12; \
- (addr)->u8[13] = addr13; \
- (addr)->u8[14] = addr14; \
- (addr)->u8[15] = addr15; \
- } while(0)
-
-
-/**
- * Copy an IP address to another IP address.
- *
- * Copies an IP address from one place to another.
- *
- * Example:
- \code
- uip_ipaddr_t ipaddr1, ipaddr2;
-
- uip_ipaddr(&ipaddr1, 192,16,1,2);
- uip_ipaddr_copy(&ipaddr2, &ipaddr1);
- \endcode
- *
- * \param dest The destination for the copy.
- * \param src The source from where to copy.
- *
- * \hideinitializer
- */
-#ifndef uip_ipaddr_copy
-#define uip_ipaddr_copy(dest, src) (*(dest) = *(src))
-#endif
-
-/**
- * Compare two IP addresses
- *
- * Compares two IP addresses.
- *
- * Example:
- \code
- uip_ipaddr_t ipaddr1, ipaddr2;
-
- uip_ipaddr(&ipaddr1, 192,16,1,2);
- if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) {
- printf("They are the same");
- }
- \endcode
- *
- * \param addr1 The first IP address.
- * \param addr2 The second IP address.
- *
- * \hideinitializer
- */
-#if !UIP_CONF_IPV6
-#define uip_ipaddr_cmp(addr1, addr2) ((addr1)->u16[0] == (addr2)->u16[0] && \
- (addr1)->u16[1] == (addr2)->u16[1])
-#else /* !UIP_CONF_IPV6 */
-#define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0)
-#endif /* !UIP_CONF_IPV6 */
-
-/**
- * Compare two IP addresses with netmasks
- *
- * Compares two IP addresses with netmasks. The masks are used to mask
- * out the bits that are to be compared.
- *
- * Example:
- \code
- uip_ipaddr_t ipaddr1, ipaddr2, mask;
-
- uip_ipaddr(&mask, 255,255,255,0);
- uip_ipaddr(&ipaddr1, 192,16,1,2);
- uip_ipaddr(&ipaddr2, 192,16,1,3);
- if(uip_ipaddr_maskcmp(&ipaddr1, &ipaddr2, &mask)) {
- printf("They are the same");
- }
- \endcode
- *
- * \param addr1 The first IP address.
- * \param addr2 The second IP address.
- * \param mask The netmask.
- *
- * \hideinitializer
- */
-#if !UIP_CONF_IPV6
-#define uip_ipaddr_maskcmp(addr1, addr2, mask) \
- (((((u16_t *)addr1)[0] & ((u16_t *)mask)[0]) == \
- (((u16_t *)addr2)[0] & ((u16_t *)mask)[0])) && \
- ((((u16_t *)addr1)[1] & ((u16_t *)mask)[1]) == \
- (((u16_t *)addr2)[1] & ((u16_t *)mask)[1])))
-#else
-#define uip_ipaddr_prefixcmp(addr1, addr2, length) (memcmp(addr1, addr2, length>>3) == 0)
-#endif
-
-
-/**
- * Check if an address is a broadcast address for a network.
- *
- * Checks if an address is the broadcast address for a network. The
- * network is defined by an IP address that is on the network and the
- * network's netmask.
- *
- * \param addr The IP address.
- * \param netaddr The network's IP address.
- * \param netmask The network's netmask.
- *
- * \hideinitializer
- */
-/*#define uip_ipaddr_isbroadcast(addr, netaddr, netmask)
- ((uip_ipaddr_t *)(addr)).u16 & ((uip_ipaddr_t *)(addr)).u16*/
-
-
-
-/**
- * Mask out the network part of an IP address.
- *
- * Masks out the network part of an IP address, given the address and
- * the netmask.
- *
- * Example:
- \code
- uip_ipaddr_t ipaddr1, ipaddr2, netmask;
-
- uip_ipaddr(&ipaddr1, 192,16,1,2);
- uip_ipaddr(&netmask, 255,255,255,0);
- uip_ipaddr_mask(&ipaddr2, &ipaddr1, &netmask);
- \endcode
- *
- * In the example above, the variable "ipaddr2" will contain the IP
- * address 192.168.1.0.
- *
- * \param dest Where the result is to be placed.
- * \param src The IP address.
- * \param mask The netmask.
- *
- * \hideinitializer
- */
-#define uip_ipaddr_mask(dest, src, mask) do { \
- ((u16_t *)dest)[0] = ((u16_t *)src)[0] & ((u16_t *)mask)[0]; \
- ((u16_t *)dest)[1] = ((u16_t *)src)[1] & ((u16_t *)mask)[1]; \
- } while(0)
-
-/**
- * Pick the first octet of an IP address.
- *
- * Picks out the first octet of an IP address.
- *
- * Example:
- \code
- uip_ipaddr_t ipaddr;
- u8_t octet;
-
- uip_ipaddr(&ipaddr, 1,2,3,4);
- octet = uip_ipaddr1(&ipaddr);
- \endcode
- *
- * In the example above, the variable "octet" will contain the value 1.
- *
- * \hideinitializer
- */
-#define uip_ipaddr1(addr) ((addr)->u8[0])
-
-/**
- * Pick the second octet of an IP address.
- *
- * Picks out the second octet of an IP address.
- *
- * Example:
- \code
- uip_ipaddr_t ipaddr;
- u8_t octet;
-
- uip_ipaddr(&ipaddr, 1,2,3,4);
- octet = uip_ipaddr2(&ipaddr);
- \endcode
- *
- * In the example above, the variable "octet" will contain the value 2.
- *
- * \hideinitializer
- */
-#define uip_ipaddr2(addr) ((addr)->u8[1])
-
-/**
- * Pick the third octet of an IP address.
- *
- * Picks out the third octet of an IP address.
- *
- * Example:
- \code
- uip_ipaddr_t ipaddr;
- u8_t octet;
-
- uip_ipaddr(&ipaddr, 1,2,3,4);
- octet = uip_ipaddr3(&ipaddr);
- \endcode
- *
- * In the example above, the variable "octet" will contain the value 3.
- *
- * \hideinitializer
- */
-#define uip_ipaddr3(addr) ((addr)->u8[2])
-
-/**
- * Pick the fourth octet of an IP address.
- *
- * Picks out the fourth octet of an IP address.
- *
- * Example:
- \code
- uip_ipaddr_t ipaddr;
- u8_t octet;
-
- uip_ipaddr(&ipaddr, 1,2,3,4);
- octet = uip_ipaddr4(&ipaddr);
- \endcode
- *
- * In the example above, the variable "octet" will contain the value 4.
- *
- * \hideinitializer
- */
-#define uip_ipaddr4(addr) ((addr)->u8[3])
-
-/**
- * Convert 16-bit quantity from host byte order to network byte order.
- *
- * This macro is primarily used for converting constants from host
- * byte order to network byte order. For converting variables to
- * network byte order, use the htons() function instead.
- *
- * \hideinitializer
- */
-#ifndef HTONS
-# if UIP_BYTE_ORDER == UIP_BIG_ENDIAN
-# define HTONS(n) (n)
-# define HTONL(n) (n)
-# else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
-# define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8))
-# define HTONL(n) (((u32_t)HTONS(n) << 16) | HTONS((u32_t)(n) >> 16))
-# endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
-#else
-#error "HTONS already defined!"
-#endif /* HTONS */
-
-/**
- * Convert 16-bit quantity from host byte order to network byte order.
- *
- * This function is primarily used for converting variables from host
- * byte order to network byte order. For converting constants to
- * network byte order, use the HTONS() macro instead.
- */
-#ifndef htons
-u16_t htons(u16_t val);
-#endif /* htons */
-#ifndef ntohs
-#define ntohs htons
-#endif
-
-#ifndef htonl
-u32_t htonl(u32_t val);
-#endif /* htonl */
-#ifndef ntohl
-#define ntohl htonl
-#endif
-
-/** @} */
-
-/**
- * Pointer to the application data in the packet buffer.
- *
- * This pointer points to the application data when the application is
- * called. If the application wishes to send data, the application may
- * use this space to write the data into before calling uip_send().
- */
-extern void *uip_appdata;
-
-#if UIP_URGDATA > 0
-/* u8_t *uip_urgdata:
- *
- * This pointer points to any urgent data that has been received. Only
- * present if compiled with support for urgent data (UIP_URGDATA).
- */
-extern void *uip_urgdata;
-#endif /* UIP_URGDATA > 0 */
-
-
-/**
- * \defgroup uipdrivervars Variables used in uIP device drivers
- * @{
- *
- * uIP has a few global variables that are used in device drivers for
- * uIP.
- */
-
-/**
- * The length of the packet in the uip_buf buffer.
- *
- * The global variable uip_len holds the length of the packet in the
- * uip_buf buffer.
- *
- * When the network device driver calls the uIP input function,
- * uip_len should be set to the length of the packet in the uip_buf
- * buffer.
- *
- * When sending packets, the device driver should use the contents of
- * the uip_len variable to determine the length of the outgoing
- * packet.
- *
- */
-extern u16_t uip_len;
-
-/**
- * The length of the extension headers
- */
-extern u8_t uip_ext_len;
-/** @} */
-
-#if UIP_URGDATA > 0
-extern u16_t uip_urglen, uip_surglen;
-#endif /* UIP_URGDATA > 0 */
-
-
-/**
- * Representation of a uIP TCP connection.
- *
- * The uip_conn structure is used for identifying a connection. All
- * but one field in the structure are to be considered read-only by an
- * application. The only exception is the appstate field whose purpose
- * is to let the application store application-specific state (e.g.,
- * file pointers) for the connection. The type of this field is
- * configured in the "uipopt.h" header file.
- */
-struct uip_conn {
- uip_ipaddr_t ripaddr; /**< The IP address of the remote host. */
-
- u16_t lport; /**< The local TCP port, in network byte order. */
- u16_t rport; /**< The local remote TCP port, in network byte
- order. */
-
- u8_t rcv_nxt[4]; /**< The sequence number that we expect to
- receive next. */
- u8_t snd_nxt[4]; /**< The sequence number that was last sent by
- us. */
- u16_t len; /**< Length of the data that was previously sent. */
- u16_t mss; /**< Current maximum segment size for the
- connection. */
- u16_t initialmss; /**< Initial maximum segment size for the
- connection. */
- u8_t sa; /**< Retransmission time-out calculation state
- variable. */
- u8_t sv; /**< Retransmission time-out calculation state
- variable. */
- u8_t rto; /**< Retransmission time-out. */
- u8_t tcpstateflags; /**< TCP state and flags. */
- u8_t timer; /**< The retransmission timer. */
- u8_t nrtx; /**< The number of retransmissions for the last
- segment sent. */
-
- /** The application state. */
- uip_tcp_appstate_t appstate;
-};
-
-
-/**
- * Pointer to the current TCP connection.
- *
- * The uip_conn pointer can be used to access the current TCP
- * connection.
- */
-
-extern struct uip_conn *uip_conn;
-#if UIP_TCP
-/* The array containing all uIP connections. */
-extern struct uip_conn uip_conns[UIP_CONNS];
-#endif
-
-/**
- * \addtogroup uiparch
- * @{
- */
-
-/**
- * 4-byte array used for the 32-bit sequence number calculations.
- */
-extern u8_t uip_acc32[4];
-/** @} */
-
-/**
- * Representation of a uIP UDP connection.
- */
-struct uip_udp_conn {
- uip_ipaddr_t ripaddr; /**< The IP address of the remote peer. */
- u16_t lport; /**< The local port number in network byte order. */
- u16_t rport; /**< The remote port number in network byte order. */
- u8_t ttl; /**< Default time-to-live. */
-
- /** The application state. */
- uip_udp_appstate_t appstate;
-};
-
-/**
- * The current UDP connection.
- */
-extern struct uip_udp_conn *uip_udp_conn;
-extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
-
-struct uip_router {
- int (*activate)(void);
- int (*deactivate)(void);
- uip_ipaddr_t *(*lookup)(uip_ipaddr_t *destipaddr, uip_ipaddr_t *nexthop);
-};
-
-#if UIP_CONF_ROUTER
-extern const struct uip_router *uip_router;
-
-/**
- * uIP routing driver registration function.
- */
-void uip_router_register(const struct uip_router *router);
-#endif /*UIP_CONF_ROUTER*/
-
-#if UIP_CONF_ICMP6
-struct uip_icmp6_conn {
- uip_icmp6_appstate_t appstate;
-};
-extern struct uip_icmp6_conn uip_icmp6_conns;
-#endif /*UIP_CONF_ICMP6*/
-
-/**
- * The uIP TCP/IP statistics.
- *
- * This is the variable in which the uIP TCP/IP statistics are gathered.
- */
-#if UIP_STATISTICS == 1
-extern struct uip_stats uip_stat;
-#define UIP_STAT(s) s
-#else
-#define UIP_STAT(s)
-#endif /* UIP_STATISTICS == 1 */
-
-/**
- * The structure holding the TCP/IP statistics that are gathered if
- * UIP_STATISTICS is set to 1.
- *
- */
-struct uip_stats {
- struct {
- uip_stats_t recv; /**< Number of received packets at the IP
- layer. */
- uip_stats_t sent; /**< Number of sent packets at the IP
- layer. */
- uip_stats_t forwarded;/**< Number of forwarded packets at the IP
- layer. */
- uip_stats_t drop; /**< Number of dropped packets at the IP
- layer. */
- uip_stats_t vhlerr; /**< Number of packets dropped due to wrong
- IP version or header length. */
- uip_stats_t hblenerr; /**< Number of packets dropped due to wrong
- IP length, high byte. */
- uip_stats_t lblenerr; /**< Number of packets dropped due to wrong
- IP length, low byte. */
- uip_stats_t fragerr; /**< Number of packets dropped since they
- were IP fragments. */
- uip_stats_t chkerr; /**< Number of packets dropped due to IP
- checksum errors. */
- uip_stats_t protoerr; /**< Number of packets dropped since they
- were neither ICMP, UDP nor TCP. */
- } ip; /**< IP statistics. */
- struct {
- uip_stats_t recv; /**< Number of received ICMP packets. */
- uip_stats_t sent; /**< Number of sent ICMP packets. */
- uip_stats_t drop; /**< Number of dropped ICMP packets. */
- uip_stats_t typeerr; /**< Number of ICMP packets with a wrong
- type. */
- uip_stats_t chkerr; /**< Number of ICMP packets with a bad
- checksum. */
- } icmp; /**< ICMP statistics. */
-#if UIP_TCP
- struct {
- uip_stats_t recv; /**< Number of received TCP segments. */
- uip_stats_t sent; /**< Number of sent TCP segments. */
- uip_stats_t drop; /**< Number of dropped TCP segments. */
- uip_stats_t chkerr; /**< Number of TCP segments with a bad
- checksum. */
- uip_stats_t ackerr; /**< Number of TCP segments with a bad ACK
- number. */
- uip_stats_t rst; /**< Number of received TCP RST (reset) segments. */
- uip_stats_t rexmit; /**< Number of retransmitted TCP segments. */
- uip_stats_t syndrop; /**< Number of dropped SYNs due to too few
- connections was available. */
- uip_stats_t synrst; /**< Number of SYNs for closed ports,
- triggering a RST. */
- } tcp; /**< TCP statistics. */
-#endif
-#if UIP_UDP
- struct {
- uip_stats_t drop; /**< Number of dropped UDP segments. */
- uip_stats_t recv; /**< Number of received UDP segments. */
- uip_stats_t sent; /**< Number of sent UDP segments. */
- uip_stats_t chkerr; /**< Number of UDP segments with a bad
- checksum. */
- } udp; /**< UDP statistics. */
-#endif /* UIP_UDP */
-#if UIP_CONF_IPV6
- struct {
- uip_stats_t drop; /**< Number of dropped ND6 packets. */
- uip_stats_t recv; /**< Number of received ND6 packets */
- uip_stats_t sent; /**< Number of sent ND6 packets */
- } nd6;
-#endif /*UIP_CONF_IPV6*/
-};
-
-
-/*---------------------------------------------------------------------------*/
-/* All the stuff below this point is internal to uIP and should not be
- * used directly by an application or by a device driver.
- */
-/*---------------------------------------------------------------------------*/
-
-
-
-/* u8_t uip_flags:
- *
- * When the application is called, uip_flags will contain the flags
- * that are defined in this file. Please read below for more
- * information.
- */
-extern u8_t uip_flags;
-
-/* The following flags may be set in the global variable uip_flags
- before calling the application callback. The UIP_ACKDATA,
- UIP_NEWDATA, and UIP_CLOSE flags may both be set at the same time,
- whereas the others are mutually exclusive. Note that these flags
- should *NOT* be accessed directly, but only through the uIP
- functions/macros. */
-
-#define UIP_ACKDATA 1 /* Signifies that the outstanding data was
- acked and the application should send
- out new data instead of retransmitting
- the last data. */
-#define UIP_NEWDATA 2 /* Flags the fact that the peer has sent
- us new data. */
-#define UIP_REXMIT 4 /* Tells the application to retransmit the
- data that was last sent. */
-#define UIP_POLL 8 /* Used for polling the application, to
- check if the application has data that
- it wants to send. */
-#define UIP_CLOSE 16 /* The remote host has closed the
- connection, thus the connection has
- gone away. Or the application signals
- that it wants to close the
- connection. */
-#define UIP_ABORT 32 /* The remote host has aborted the
- connection, thus the connection has
- gone away. Or the application signals
- that it wants to abort the
- connection. */
-#define UIP_CONNECTED 64 /* We have got a connection from a remote
- host and have set up a new connection
- for it, or an active connection has
- been successfully established. */
-
-#define UIP_TIMEDOUT 128 /* The connection has been aborted due to
- too many retransmissions. */
-
-
-/**
- * \brief process the options within a hop by hop or destination option header
- * \retval 0: nothing to send,
- * \retval 1: drop pkt
- * \retval 2: ICMP error message to send
-*/
-/*static u8_t
-uip_ext_hdr_options_process(); */
-
-/* uip_process(flag):
- *
- * The actual uIP function which does all the work.
- */
-void uip_process(u8_t flag);
-
- /* The following flags are passed as an argument to the uip_process()
- function. They are used to distinguish between the two cases where
- uip_process() is called. It can be called either because we have
- incoming data that should be processed, or because the periodic
- timer has fired. These values are never used directly, but only in
- the macros defined in this file. */
-
-#define UIP_DATA 1 /* Tells uIP that there is incoming
- data in the uip_buf buffer. The
- length of the data is stored in the
- global variable uip_len. */
-#define UIP_TIMER 2 /* Tells uIP that the periodic timer
- has fired. */
-#define UIP_POLL_REQUEST 3 /* Tells uIP that a connection should
- be polled. */
-#define UIP_UDP_SEND_CONN 4 /* Tells uIP that a UDP datagram
- should be constructed in the
- uip_buf buffer. */
-#if UIP_UDP
-#define UIP_UDP_TIMER 5
-#endif /* UIP_UDP */
-
-/* The TCP states used in the uip_conn->tcpstateflags. */
-#define UIP_CLOSED 0
-#define UIP_SYN_RCVD 1
-#define UIP_SYN_SENT 2
-#define UIP_ESTABLISHED 3
-#define UIP_FIN_WAIT_1 4
-#define UIP_FIN_WAIT_2 5
-#define UIP_CLOSING 6
-#define UIP_TIME_WAIT 7
-#define UIP_LAST_ACK 8
-#define UIP_TS_MASK 15
-
-#define UIP_STOPPED 16
-
-/* The TCP and IP headers. */
-struct uip_tcpip_hdr {
-#if UIP_CONF_IPV6
- /* IPv6 header. */
- u8_t vtc,
- tcflow;
- u16_t flow;
- u8_t len[2];
- u8_t proto, ttl;
- uip_ip6addr_t srcipaddr, destipaddr;
-#else /* UIP_CONF_IPV6 */
- /* IPv4 header. */
- u8_t vhl,
- tos,
- len[2],
- ipid[2],
- ipoffset[2],
- ttl,
- proto;
- u16_t ipchksum;
- uip_ipaddr_t srcipaddr, destipaddr;
-#endif /* UIP_CONF_IPV6 */
-
- /* 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];
-};
-
-/* The ICMP and IP headers. */
-struct uip_icmpip_hdr {
-#if UIP_CONF_IPV6
- /* IPv6 header. */
- u8_t vtc,
- tcf;
- u16_t flow;
- u8_t len[2];
- u8_t proto, ttl;
- uip_ip6addr_t srcipaddr, destipaddr;
-#else /* UIP_CONF_IPV6 */
- /* IPv4 header. */
- u8_t vhl,
- tos,
- len[2],
- ipid[2],
- ipoffset[2],
- ttl,
- proto;
- u16_t ipchksum;
- uip_ipaddr_t srcipaddr, destipaddr;
-#endif /* UIP_CONF_IPV6 */
-
- /* ICMP header. */
- u8_t type, icode;
- u16_t icmpchksum;
-#if !UIP_CONF_IPV6
- u16_t id, seqno;
- u8_t payload[1];
-#endif /* !UIP_CONF_IPV6 */
-};
-
-
-/* The UDP and IP headers. */
-struct uip_udpip_hdr {
-#if UIP_CONF_IPV6
- /* IPv6 header. */
- u8_t vtc,
- tcf;
- u16_t flow;
- u8_t len[2];
- u8_t proto, ttl;
- uip_ip6addr_t srcipaddr, destipaddr;
-#else /* UIP_CONF_IPV6 */
- /* IP header. */
- u8_t vhl,
- tos,
- len[2],
- ipid[2],
- ipoffset[2],
- ttl,
- proto;
- u16_t ipchksum;
- uip_ipaddr_t srcipaddr, destipaddr;
-#endif /* UIP_CONF_IPV6 */
-
- /* UDP header. */
- u16_t srcport,
- destport;
- u16_t udplen;
- u16_t udpchksum;
-};
-
-/*
- * In IPv6 the length of the L3 headers before the transport header is
- * not fixed, due to the possibility to include extension option headers
- * after the IP header. hence we split here L3 and L4 headers
- */
-/* The IP header */
-struct uip_ip_hdr {
-#if UIP_CONF_IPV6
- /* IPV6 header */
- u8_t vtc;
- u8_t tcflow;
- u16_t flow;
- u8_t len[2];
- u8_t proto, ttl;
- uip_ip6addr_t srcipaddr, destipaddr;
-#else /* UIP_CONF_IPV6 */
- /* IPV4 header */
- u8_t vhl,
- tos,
- len[2],
- ipid[2],
- ipoffset[2],
- ttl,
- proto;
- u16_t ipchksum;
- uip_ipaddr_t srcipaddr, destipaddr;
-#endif /* UIP_CONF_IPV6 */
-};
-
-
-/*
- * IPv6 extension option headers: we are able to process
- * the 4 extension headers defined in RFC2460 (IPv6):
- * - Hop by hop option header, destination option header:
- * These two are not used by any core IPv6 protocol, hence
- * we just read them and go to the next. They convey options,
- * the options defined in RFC2460 are Pad1 and PadN, which do
- * some padding, and that we do not need to read (the length
- * field in the header is enough)
- * - Routing header: this one is most notably used by MIPv6,
- * which we do not implement, hence we just read it and go
- * to the next
- * - Fragmentation header: we read this header and are able to
- * reassemble packets
- *
- * We do not offer any means to send packets with extension headers
- *
- * We do not implement Authentication and ESP headers, which are
- * used in IPSec and defined in RFC4302,4303,4305,4385
- */
-/* common header part */
-struct uip_ext_hdr {
- u8_t next;
- u8_t len;
-};
-
-/* Hop by Hop option header */
-struct uip_hbho_hdr {
- u8_t next;
- u8_t len;
-};
-
-/* destination option header */
-struct uip_desto_hdr {
- u8_t next;
- u8_t len;
-};
-
-/* We do not define structures for PAD1 and PADN options */
-
-/*
- * routing header
- * the routing header as 4 common bytes, then routing header type
- * specific data there are several types of routing header. Type 0 was
- * deprecated as per RFC5095 most notable other type is 2, used in
- * RFC3775 (MIPv6) here we do not implement MIPv6, so we just need to
- * parse the 4 first bytes
- */
-struct uip_routing_hdr {
- u8_t next;
- u8_t len;
- u8_t routing_type;
- u8_t seg_left;
-};
-
-/* fragmentation header */
-struct uip_frag_hdr {
- u8_t next;
- u8_t res;
- u16_t offsetresmore;
- u32_t id;
-};
-
-/*
- * an option within the destination or hop by hop option headers
- * it contains type an length, which is true for all options but PAD1
- */
-struct uip_ext_hdr_opt {
- u8_t type;
- u8_t len;
-};
-
-/* PADN option */
-struct uip_ext_hdr_opt_padn {
- u8_t opt_type;
- u8_t opt_len;
-};
-
-/* TCP header */
-struct uip_tcp_hdr {
- u16_t srcport;
- u16_t destport;
- u8_t seqno[4];
- u8_t ackno[4];
- u8_t tcpoffset;
- u8_t flags;
- u8_t wnd[2];
- u16_t tcpchksum;
- u8_t urgp[2];
- u8_t optdata[4];
-};
-
-/* The ICMP headers. */
-struct uip_icmp_hdr {
- u8_t type, icode;
- u16_t icmpchksum;
-#if !UIP_CONF_IPV6
- u16_t id, seqno;
-#endif /* !UIP_CONF_IPV6 */
-};
-
-
-/* The UDP headers. */
-struct uip_udp_hdr {
- u16_t srcport;
- u16_t destport;
- u16_t udplen;
- u16_t udpchksum;
-};
-
-
-/**
- * The buffer size available for user data in the \ref uip_buf buffer.
- *
- * This macro holds the available size for user data in the \ref
- * uip_buf buffer. The macro is intended to be used for checking
- * bounds of available user data.
- *
- * Example:
- \code
- snprintf(uip_appdata, UIP_APPDATA_SIZE, "%u\n", i);
- \endcode
- *
- * \hideinitializer
- */
-#define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
-#define UIP_APPDATA_PTR (void *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]
-
-#define UIP_PROTO_ICMP 1
-#define UIP_PROTO_TCP 6
-#define UIP_PROTO_UDP 17
-#define UIP_PROTO_ICMP6 58
-
-
-#if UIP_CONF_IPV6
-/** @{ */
-/** \brief extension headers types */
-#define UIP_PROTO_HBHO 0
-#define UIP_PROTO_DESTO 60
-#define UIP_PROTO_ROUTING 43
-#define UIP_PROTO_FRAG 44
-#define UIP_PROTO_NONE 59
-/** @} */
-
-/** @{ */
-/** \brief Destination and Hop By Hop extension headers option types */
-#define UIP_EXT_HDR_OPT_PAD1 0
-#define UIP_EXT_HDR_OPT_PADN 1
-/** @} */
-
-/** @{ */
-/**
- * \brief Bitmaps for extension header processing
- *
- * When processing extension headers, we should record somehow which one we
- * see, because you cannot have twice the same header, except for destination
- * We store all this in one u8_t bitmap one bit for each header expected. The
- * order in the bitmap is the order recommended in RFC2460
- */
-#define UIP_EXT_HDR_BITMAP_HBHO 0x01
-#define UIP_EXT_HDR_BITMAP_DESTO1 0x02
-#define UIP_EXT_HDR_BITMAP_ROUTING 0x04
-#define UIP_EXT_HDR_BITMAP_FRAG 0x08
-#define UIP_EXT_HDR_BITMAP_AH 0x10
-#define UIP_EXT_HDR_BITMAP_ESP 0x20
-#define UIP_EXT_HDR_BITMAP_DESTO2 0x40
-/** @} */
-
-
-#endif /* UIP_CONF_IPV6 */
-
-
-/* Header sizes. */
-#if UIP_CONF_IPV6
-#define UIP_IPH_LEN 40
-#define UIP_FRAGH_LEN 8
-#else /* UIP_CONF_IPV6 */
-#define UIP_IPH_LEN 20 /* Size of IP header */
-#endif /* UIP_CONF_IPV6 */
-
-#define UIP_UDPH_LEN 8 /* Size of UDP header */
-#define UIP_TCPH_LEN 20 /* Size of TCP header */
-#ifdef UIP_IPH_LEN
-#define UIP_ICMPH_LEN 4 /* Size of ICMP header */
-#endif
-#define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN) /* Size of IP +
- * UDP
- * header */
-#define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN) /* Size of IP +
- * TCP
- * header */
-#define UIP_TCPIP_HLEN UIP_IPTCPH_LEN
-#define UIP_IPICMPH_LEN (UIP_IPH_LEN + UIP_ICMPH_LEN) /* size of ICMP
- + IP header */
-#define UIP_LLIPH_LEN (UIP_LLH_LEN + UIP_IPH_LEN) /* size of L2
- + IP header */
-#if UIP_CONF_IPV6
-/**
- * The sums below are quite used in ND. When used for uip_buf, we
- * include link layer length when used for uip_len, we do not, hence
- * we need values with and without LLH_LEN we do not use capital
- * letters as these values are variable
- */
-#define uip_l2_l3_hdr_len (UIP_LLH_LEN + UIP_IPH_LEN + uip_ext_len)
-#define uip_l2_l3_icmp_hdr_len (UIP_LLH_LEN + UIP_IPH_LEN + uip_ext_len + UIP_ICMPH_LEN)
-#define uip_l3_hdr_len (UIP_IPH_LEN + uip_ext_len)
-#define uip_l3_icmp_hdr_len (UIP_IPH_LEN + uip_ext_len + UIP_ICMPH_LEN)
-#endif /*UIP_CONF_IPV6*/
-
-
-#if UIP_FIXEDADDR
-extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
-#else /* UIP_FIXEDADDR */
-extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
-#endif /* UIP_FIXEDADDR */
-extern const uip_ipaddr_t uip_broadcast_addr;
-extern const uip_ipaddr_t uip_all_zeroes_addr;
-
-#if UIP_FIXEDETHADDR
-extern const uip_lladdr_t uip_lladdr;
-#else
-extern uip_lladdr_t uip_lladdr;
-#endif
-
-
-
-
-#ifdef UIP_CONF_IPV6
-/**
- * \brief Is IPv6 address a the unspecified address
- * a is of type uip_ipaddr_t
- */
-#define uip_is_addr_unspecified(a) \
- ((((a)->u16[0]) == 0) && \
- (((a)->u16[1]) == 0) && \
- (((a)->u16[2]) == 0) && \
- (((a)->u16[3]) == 0) && \
- (((a)->u16[4]) == 0) && \
- (((a)->u16[5]) == 0) && \
- (((a)->u16[6]) == 0) && \
- (((a)->u16[7]) == 0))
-
-/** \brief Is IPv6 address a the link local all-nodes multicast address */
-#define uip_is_addr_linklocal_allnodes_mcast(a) \
- ((((a)->u8[0]) == 0xff) && \
- (((a)->u8[1]) == 0x02) && \
- (((a)->u16[1]) == 0) && \
- (((a)->u16[2]) == 0) && \
- (((a)->u16[3]) == 0) && \
- (((a)->u16[4]) == 0) && \
- (((a)->u16[5]) == 0) && \
- (((a)->u16[6]) == 0) && \
- (((a)->u8[14]) == 0) && \
- (((a)->u8[15]) == 0x01))
-
-/** \brief set IP address a to unspecified */
-#define uip_create_unspecified(a) uip_ip6addr(a, 0, 0, 0, 0, 0, 0, 0, 0)
-
-/** \brief set IP address a to the link local all-nodes multicast address */
-#define uip_create_linklocal_allnodes_mcast(a) uip_ip6addr(a, 0xff02, 0, 0, 0, 0, 0, 0, 0x0001)
-
-/** \brief set IP address a to the link local all-routers multicast address */
-#define uip_create_linklocal_allrouters_mcast(a) uip_ip6addr(a, 0xff02, 0, 0, 0, 0, 0, 0, 0x0002)
-
-/**
- * \brief is addr (a) a solicited node multicast address, see RFC3513
- * a is of type uip_ipaddr_t*
- */
-#define uip_is_addr_solicited_node(a) \
- ((((a)->u8[0]) == 0xFF) && \
- (((a)->u8[1]) == 0x02) && \
- (((a)->u16[1]) == 0) && \
- (((a)->u16[2]) == 0) && \
- (((a)->u16[3]) == 0) && \
- (((a)->u16[4]) == 0) && \
- (((a)->u16[5]) == 1) && \
- (((a)->u8[12]) == 0xFF))
-
-/**
- * \briefput in b the solicited node address corresponding to address a
- * both a and b are of type uip_ipaddr_t*
- * */
-#define uip_create_solicited_node(a, b) \
- (((b)->u8[0]) = 0xFF); \
- (((b)->u8[1]) = 0x02); \
- (((b)->u16[1]) = 0); \
- (((b)->u16[2]) = 0); \
- (((b)->u16[3]) = 0); \
- (((b)->u16[4]) = 0); \
- (((b)->u8[10]) = 0); \
- (((b)->u8[11]) = 0x01); \
- (((b)->u8[12]) = 0xFF); \
- (((b)->u8[13]) = ((a)->u8[13])); \
- (((b)->u16[7]) = ((a)->u16[7]))
-
-/**
- * \brief is addr (a) a link local unicast address, see RFC3513
- * i.e. is (a) on prefix FE80::/10
- * a is of type uip_ipaddr_t*
- */
-#define uip_is_addr_link_local(a) \
- ((((a)->u8[0]) == 0xFE) && \
- (((a)->u8[1]) == 0x80))
-
-/**
- * \brief was addr (a) forged based on the mac address m
- * a type is uip_ipaddr_t
- * m type is uiplladdr_t
- */
-#if UIP_CONF_LL_802154
-#define uip_is_addr_mac_addr_based(a, m) \
- ((((a)->u8[8]) == (((m)->addr[0]) ^ 0x02)) && \
- (((a)->u8[9]) == (m)->addr[1]) && \
- (((a)->u8[10]) == (m)->addr[2]) && \
- (((a)->u8[11]) == (m)->addr[3]) && \
- (((a)->u8[12]) == (m)->addr[4]) && \
- (((a)->u8[13]) == (m)->addr[5]) && \
- (((a)->u8[14]) == (m)->addr[6]) && \
- (((a)->u8[15]) == (m)->addr[7]))
-#else
-
-#define uip_is_addr_mac_addr_based(a, m) \
- ((((a)->u8[8]) == (((m)->addr[0]) | 0x02)) && \
- (((a)->u8[9]) == (m)->addr[1]) && \
- (((a)->u8[10]) == (m)->addr[2]) && \
- (((a)->u8[11]) == 0xff) && \
- (((a)->u8[12]) == 0xfe) && \
- (((a)->u8[13]) == (m)->addr[3]) && \
- (((a)->u8[14]) == (m)->addr[4]) && \
- (((a)->u8[15]) == (m)->addr[5]))
-
-#endif /*UIP_CONF_LL_802154*/
-
-/**
- * \brief is address a multicast address, see RFC 3513
- * a is of type uip_ipaddr_t*
- * */
-#define uip_is_addr_mcast(a) \
- (((a)->u8[0]) == 0xFF)
-
-/**
- * \brief is group-id of multicast address a
- * the all nodes group-id
- */
-#define uip_is_mcast_group_id_all_nodes(a) \
- ((((a)->u16[1]) == 0) && \
- (((a)->u16[2]) == 0) && \
- (((a)->u16[3]) == 0) && \
- (((a)->u16[4]) == 0) && \
- (((a)->u16[5]) == 0) && \
- (((a)->u16[6]) == 0) && \
- (((a)->u8[14]) == 0) && \
- (((a)->u8[15]) == 1))
-
-/**
- * \brief is group-id of multicast address a
- * the all routers group-id
- */
-#define uip_is_mcast_group_id_all_routers(a) \
- ((((a)->u16[1]) == 0) && \
- (((a)->u16[2]) == 0) && \
- (((a)->u16[3]) == 0) && \
- (((a)->u16[4]) == 0) && \
- (((a)->u16[5]) == 0) && \
- (((a)->u16[6]) == 0) && \
- (((a)->u8[14]) == 0) && \
- (((a)->u8[15]) == 2))
-
-
-#endif /*UIP_CONF_IPV6*/
-
-/**
- * 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.
- *
- * \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.
- *
- * \return The TCP checksum of the TCP segment in uip_buf and pointed
- * to by uip_appdata.
- */
-u16_t uip_tcpchksum(void);
-
-/**
- * Calculate the UDP checksum of the packet in uip_buf and uip_appdata.
- *
- * The UDP checksum is the Internet checksum of data contents of the
- * UDP segment, and a pseudo-header as defined in RFC768.
- *
- * \return The UDP checksum of the UDP segment in uip_buf and pointed
- * to by uip_appdata.
- */
-u16_t uip_udpchksum(void);
-
-/**
- * Calculate the ICMP checksum of the packet in uip_buf.
- *
- * \return The ICMP checksum of the ICMP packet in uip_buf
- */
-u16_t uip_icmp6chksum(void);
-
-
-#endif /* __UIP_H__ */
-
-
-/** @} */
-
diff --git a/lib/lufa/Projects/Webserver/Lib/uip/uip_arp.c b/lib/lufa/Projects/Webserver/Lib/uip/uip_arp.c
deleted file mode 100644
index fcb783b14..000000000
--- a/lib/lufa/Projects/Webserver/Lib/uip/uip_arp.c
+++ /dev/null
@@ -1,432 +0,0 @@
-/**
- * \addtogroup uip
- * @{
- */
-
-/**
- * \defgroup uiparp uIP Address Resolution Protocol
- * @{
- *
- * The Address Resolution Protocol ARP is used for mapping between IP
- * addresses and link level addresses such as the Ethernet MAC
- * addresses. ARP uses broadcast queries to ask for the link level
- * address of a known IP address and the host which is configured with
- * the IP address for which the query was meant, will respond with its
- * link level address.
- *
- * \note This ARP implementation only supports Ethernet.
- */
-
-/**
- * \file
- * Implementation of the ARP Address Resolution Protocol.
- * \author Adam Dunkels <adam@dunkels.com>
- *
- */
-
-/*
- * Copyright (c) 2001-2003, Adam Dunkels.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * This file is part of the uIP TCP/IP stack.
- *
- * $Id: uip_arp.c,v 1.5 2008/02/07 01:35:00 adamdunkels Exp $
- *
- */
-
-
-#include "uip_arp.h"
-
-#include <string.h>
-
-struct arp_hdr {
- struct uip_eth_hdr ethhdr;
- u16_t hwtype;
- u16_t protocol;
- u8_t hwlen;
- u8_t protolen;
- u16_t opcode;
- struct uip_eth_addr shwaddr;
- uip_ipaddr_t sipaddr;
- struct uip_eth_addr dhwaddr;
- uip_ipaddr_t dipaddr;
-};
-
-struct ethip_hdr {
- struct uip_eth_hdr ethhdr;
- /* IP header. */
- u8_t vhl,
- tos,
- len[2],
- ipid[2],
- ipoffset[2],
- ttl,
- proto;
- u16_t ipchksum;
- uip_ipaddr_t srcipaddr, destipaddr;
-};
-
-#define ARP_REQUEST 1
-#define ARP_REPLY 2
-
-#define ARP_HWTYPE_ETH 1
-
-struct arp_entry {
- uip_ipaddr_t ipaddr;
- struct uip_eth_addr ethaddr;
- u8_t time;
-};
-
-static const struct uip_eth_addr broadcast_ethaddr =
- {{0xff,0xff,0xff,0xff,0xff,0xff}};
-static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff};
-
-static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
-static uip_ipaddr_t ipaddr;
-static u8_t i, c;
-
-static u8_t arptime;
-static u8_t tmpage;
-
-#define BUF ((struct arp_hdr *)&uip_buf[0])
-#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
-
-#define DEBUG 0
-#if DEBUG
-#include <stdio.h>
-#define PRINTF(...) printf(__VA_ARGS__)
-#else
-#define PRINTF(...)
-#endif
-
-/*-----------------------------------------------------------------------------------*/
-/**
- * Initialize the ARP module.
- *
- */
-/*-----------------------------------------------------------------------------------*/
-void
-uip_arp_init(void)
-{
- for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
- memset(&arp_table[i].ipaddr, 0, 4);
- }
-}
-/*-----------------------------------------------------------------------------------*/
-/**
- * Periodic ARP processing function.
- *
- * This function performs periodic timer processing in the ARP module
- * and should be called at regular intervals. The recommended interval
- * is 10 seconds between the calls.
- *
- */
-/*-----------------------------------------------------------------------------------*/
-void
-uip_arp_timer(void)
-{
- struct arp_entry *tabptr = NULL;
-
- ++arptime;
- for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
- tabptr = &arp_table[i];
- if(uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr) &&
- arptime - tabptr->time >= UIP_ARP_MAXAGE) {
- memset(&tabptr->ipaddr, 0, 4);
- }
- }
-
-}
-/*-----------------------------------------------------------------------------------*/
-static void
-uip_arp_update(uip_ipaddr_t *ipaddr, struct uip_eth_addr *ethaddr)
-{
- register struct arp_entry *tabptr = NULL;
- /* Walk through the ARP mapping table and try to find an entry to
- update. If none is found, the IP -> MAC address mapping is
- inserted in the ARP table. */
- for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
-
- tabptr = &arp_table[i];
- /* Only check those entries that are actually in use. */
- if(!uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) {
-
- /* Check if the source IP address of the incoming packet matches
- the IP address in this ARP table entry. */
- if(uip_ipaddr_cmp(ipaddr, &tabptr->ipaddr)) {
-
- /* An old entry found, update this and return. */
- memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
- tabptr->time = arptime;
-
- return;
- }
- }
- }
-
- /* If we get here, no existing ARP table entry was found, so we
- create one. */
-
- /* First, we try to find an unused entry in the ARP table. */
- for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
- tabptr = &arp_table[i];
- if(uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) {
- break;
- }
- }
-
- /* If no unused entry is found, we try to find the oldest entry and
- throw it away. */
- if(i == UIP_ARPTAB_SIZE) {
- tmpage = 0;
- c = 0;
- for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
- tabptr = &arp_table[i];
- if(arptime - tabptr->time > tmpage) {
- tmpage = arptime - tabptr->time;
- c = i;
- }
- }
- i = c;
- tabptr = &arp_table[i];
- }
-
- /* Now, i is the ARP table entry which we will fill with the new
- information. */
- uip_ipaddr_copy(&tabptr->ipaddr, ipaddr);
- memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
- tabptr->time = arptime;
-}
-/*-----------------------------------------------------------------------------------*/
-/**
- * ARP processing for incoming IP packets
- *
- * This function should be called by the device driver when an IP
- * packet has been received. The function will check if the address is
- * in the ARP cache, and if so the ARP cache entry will be
- * refreshed. If no ARP cache entry was found, a new one is created.
- *
- * This function expects an IP packet with a prepended Ethernet header
- * in the uip_buf[] buffer, and the length of the packet in the global
- * variable uip_len.
- */
-/*-----------------------------------------------------------------------------------*/
-#if 0
-void
-uip_arp_ipin(void)
-{
- uip_len -= sizeof(struct uip_eth_hdr);
-
- /* Only insert/update an entry if the source IP address of the
- incoming IP packet comes from a host on the local network. */
- if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
- (uip_hostaddr[0] & uip_netmask[0])) {
- return;
- }
- if((IPBUF->srcipaddr[1] & uip_netmask[1]) !=
- (uip_hostaddr[1] & uip_netmask[1])) {
- return;
- }
- uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
-
- return;
-}
-#endif /* 0 */
-/*-----------------------------------------------------------------------------------*/
-/**
- * ARP processing for incoming ARP packets.
- *
- * This function should be called by the device driver when an ARP
- * packet has been received. The function will act differently
- * depending on the ARP packet type: if it is a reply for a request
- * that we previously sent out, the ARP cache will be filled in with
- * the values from the ARP reply. If the incoming ARP packet is an ARP
- * request for our IP address, an ARP reply packet is created and put
- * into the uip_buf[] buffer.
- *
- * When the function returns, the value of the global variable uip_len
- * indicates whether the device driver should send out a packet or
- * not. If uip_len is zero, no packet should be sent. If uip_len is
- * non-zero, it contains the length of the outbound packet that is
- * present in the uip_buf[] buffer.
- *
- * This function expects an ARP packet with a prepended Ethernet
- * header in the uip_buf[] buffer, and the length of the packet in the
- * global variable uip_len.
- */
-/*-----------------------------------------------------------------------------------*/
-void
-uip_arp_arpin(void)
-{
- if(uip_len < sizeof(struct arp_hdr)) {
- uip_len = 0;
- return;
- }
- uip_len = 0;
-
- switch(BUF->opcode) {
- case HTONS(ARP_REQUEST):
- /* ARP request. If it asked for our address, we send out a
- reply. */
- /* if(BUF->dipaddr[0] == uip_hostaddr[0] &&
- BUF->dipaddr[1] == uip_hostaddr[1]) {*/
- PRINTF("uip_arp_arpin: request for %d.%d.%d.%d (we are %d.%d.%d.%d)\n",
- BUF->dipaddr.u8[0], BUF->dipaddr.u8[1],
- BUF->dipaddr.u8[2], BUF->dipaddr.u8[3],
- uip_hostaddr.u8[0], uip_hostaddr.u8[1],
- uip_hostaddr.u8[2], uip_hostaddr.u8[3]);
- if(uip_ipaddr_cmp(&BUF->dipaddr, &uip_hostaddr)) {
- /* First, we register the one who made the request in our ARP
- table, since it is likely that we will do more communication
- with this host in the future. */
- uip_arp_update(&BUF->sipaddr, &BUF->shwaddr);
-
- BUF->opcode = HTONS(ARP_REPLY);
-
- memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
- memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
- memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
- memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
-
- uip_ipaddr_copy(&BUF->dipaddr, &BUF->sipaddr);
- uip_ipaddr_copy(&BUF->sipaddr, &uip_hostaddr);
-
- BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
- uip_len = sizeof(struct arp_hdr);
- }
- break;
- case HTONS(ARP_REPLY):
- /* ARP reply. We insert or update the ARP table if it was meant
- for us. */
- if(uip_ipaddr_cmp(&BUF->dipaddr, &uip_hostaddr)) {
- uip_arp_update(&BUF->sipaddr, &BUF->shwaddr);
- }
- break;
- }
-
- return;
-}
-/*-----------------------------------------------------------------------------------*/
-/**
- * Prepend Ethernet header to an outbound IP packet and see if we need
- * to send out an ARP request.
- *
- * This function should be called before sending out an IP packet. The
- * function checks the destination IP address of the IP packet to see
- * what Ethernet MAC address that should be used as a destination MAC
- * address on the Ethernet.
- *
- * If the destination IP address is in the local network (determined
- * by logical ANDing of netmask and our IP address), the function
- * checks the ARP cache to see if an entry for the destination IP
- * address is found. If so, an Ethernet header is prepended and the
- * function returns. If no ARP cache entry is found for the
- * destination IP address, the packet in the uip_buf[] is replaced by
- * an ARP request packet for the IP address. The IP packet is dropped
- * and it is assumed that they higher level protocols (e.g., TCP)
- * eventually will retransmit the dropped packet.
- *
- * If the destination IP address is not on the local network, the IP
- * address of the default router is used instead.
- *
- * When the function returns, a packet is present in the uip_buf[]
- * buffer, and the length of the packet is in the global variable
- * uip_len.
- */
-/*-----------------------------------------------------------------------------------*/
-void
-uip_arp_out(void)
-{
- struct arp_entry *tabptr = NULL;
-
- /* Find the destination IP address in the ARP table and construct
- the Ethernet header. If the destination IP address isn't on the
- local network, we use the default router's IP address instead.
-
- If not ARP table entry is found, we overwrite the original IP
- packet with an ARP request for the IP address. */
-
- /* First check if destination is a local broadcast. */
- if(uip_ipaddr_cmp(&IPBUF->destipaddr, &uip_broadcast_addr)) {
- memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
- } else {
- /* Check if the destination address is on the local network. */
- if(!uip_ipaddr_maskcmp(&IPBUF->destipaddr, &uip_hostaddr, &uip_netmask)) {
- /* Destination address was not on the local network, so we need to
- use the default router's IP address instead of the destination
- address when determining the MAC address. */
- uip_ipaddr_copy(&ipaddr, &uip_draddr);
- } else {
- /* Else, we use the destination IP address. */
- uip_ipaddr_copy(&ipaddr, &IPBUF->destipaddr);
- }
-
- for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
- tabptr = &arp_table[i];
- if(uip_ipaddr_cmp(&ipaddr, &tabptr->ipaddr)) {
- break;
- }
- }
-
- if(i == UIP_ARPTAB_SIZE) {
- /* The destination address was not in our ARP table, so we
- overwrite the IP packet with an ARP request. */
-
- memset(BUF->ethhdr.dest.addr, 0xff, 6);
- memset(BUF->dhwaddr.addr, 0x00, 6);
- memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
- memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
-
- uip_ipaddr_copy(&BUF->dipaddr, &ipaddr);
- uip_ipaddr_copy(&BUF->sipaddr, &uip_hostaddr);
- BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
- BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
- BUF->protocol = HTONS(UIP_ETHTYPE_IP);
- BUF->hwlen = 6;
- BUF->protolen = 4;
- BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
-
- uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
-
- uip_len = sizeof(struct arp_hdr);
- return;
- }
-
- /* Build an ethernet header. */
- memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
- }
- memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
-
- IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
-
- uip_len += sizeof(struct uip_eth_hdr);
-}
-/*-----------------------------------------------------------------------------------*/
-
-/** @} */
-/** @} */
-
diff --git a/lib/lufa/Projects/Webserver/Lib/uip/uip_arp.h b/lib/lufa/Projects/Webserver/Lib/uip/uip_arp.h
deleted file mode 100644
index 4e78ce7b7..000000000
--- a/lib/lufa/Projects/Webserver/Lib/uip/uip_arp.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/**
- * \addtogroup uip
- * @{
- */
-
-/**
- * \addtogroup uiparp
- * @{
- */
-
-/**
- * \file
- * Macros and definitions for the ARP module.
- * \author Adam Dunkels <adam@dunkels.com>
- */
-
-
-/*
- * Copyright (c) 2001-2003, Adam Dunkels.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * This file is part of the uIP TCP/IP stack.
- *
- * $Id: uip_arp.h,v 1.2 2006/08/26 23:58:45 oliverschmidt Exp $
- *
- */
-
-#ifndef __UIP_ARP_H__
-#define __UIP_ARP_H__
-
-#include "uip.h"
-
-
-extern struct uip_eth_addr uip_ethaddr;
-
-/**
- * The Ethernet header.
- */
-struct uip_eth_hdr {
- struct uip_eth_addr dest;
- struct uip_eth_addr src;
- u16_t type;
-};
-
-#define UIP_ETHTYPE_ARP 0x0806
-#define UIP_ETHTYPE_IP 0x0800
-#define UIP_ETHTYPE_IPV6 0x86dd
-
-
-/* The uip_arp_init() function must be called before any of the other
- ARP functions. */
-void uip_arp_init(void);
-
-/* The uip_arp_ipin() function should be called whenever an IP packet
- arrives from the Ethernet. This function refreshes the ARP table or
- inserts a new mapping if none exists. The function assumes that an
- IP packet with an Ethernet header is present in the uip_buf buffer
- and that the length of the packet is in the uip_len variable. */
-/*void uip_arp_ipin(void);*/
-#define uip_arp_ipin()
-
-/* The uip_arp_arpin() should be called when an ARP packet is received
- by the Ethernet driver. This function also assumes that the
- Ethernet frame is present in the uip_buf buffer. When the
- uip_arp_arpin() function returns, the contents of the uip_buf
- buffer should be sent out on the Ethernet if the uip_len variable
- is > 0. */
-void uip_arp_arpin(void);
-
-/* The uip_arp_out() function should be called when an IP packet
- should be sent out on the Ethernet. This function creates an
- Ethernet header before the IP header in the uip_buf buffer. The
- Ethernet header will have the correct Ethernet MAC destination
- address filled in if an ARP table entry for the destination IP
- address (or the IP address of the default router) is present. If no
- such table entry is found, the IP packet is overwritten with an ARP
- request and we rely on TCP to retransmit the packet that was
- overwritten. In any case, the uip_len variable holds the length of
- the Ethernet frame that should be transmitted. */
-void uip_arp_out(void);
-
-/* The uip_arp_timer() function should be called every ten seconds. It
- is responsible for flushing old entries in the ARP table. */
-void uip_arp_timer(void);
-
-/** @} */
-
-/**
- * \addtogroup uipconffunc
- * @{
- */
-
-
-/**
- * Specifiy the Ethernet MAC address.
- *
- * The ARP code needs to know the MAC address of the Ethernet card in
- * order to be able to respond to ARP queries and to generate working
- * Ethernet headers.
- *
- * \note This macro only specifies the Ethernet MAC address to the ARP
- * code. It cannot be used to change the MAC address of the Ethernet
- * card.
- *
- * \param eaddr A pointer to a struct uip_eth_addr containing the
- * Ethernet MAC address of the Ethernet card.
- *
- * \hideinitializer
- */
-#define uip_setethaddr(eaddr) do {uip_ethaddr.addr[0] = eaddr.addr[0]; \
- uip_ethaddr.addr[1] = eaddr.addr[1];\
- uip_ethaddr.addr[2] = eaddr.addr[2];\
- uip_ethaddr.addr[3] = eaddr.addr[3];\
- uip_ethaddr.addr[4] = eaddr.addr[4];\
- uip_ethaddr.addr[5] = eaddr.addr[5];} while(0)
-
-/** @} */
-
-
-#endif /* __UIP_ARP_H__ */
-/** @} */
-
diff --git a/lib/lufa/Projects/Webserver/Lib/uip/uipopt.h b/lib/lufa/Projects/Webserver/Lib/uip/uipopt.h
deleted file mode 100644
index 520c03f25..000000000
--- a/lib/lufa/Projects/Webserver/Lib/uip/uipopt.h
+++ /dev/null
@@ -1,740 +0,0 @@
-/**
- * \addtogroup uip
- * @{
- */
-
-/**
- * \defgroup uipopt Configuration options for uIP
- * @{
- *
- * uIP is configured using the per-project configuration file
- * "uipopt.h". This file contains all compile-time options for uIP and
- * should be tweaked to match each specific project. The uIP
- * distribution contains a documented example "uipopt.h" that can be
- * copied and modified for each project.
- */
-
-/**
- * \file
- * Configuration options for uIP.
- * \author Adam Dunkels <adam@dunkels.com>
- *
- * This file is used for tweaking various configuration options for
- * uIP. You should make a copy of this file into one of your project's
- * directories instead of editing this example "uipopt.h" file that
- * comes with the uIP distribution.
- */
-
-/*
- * Copyright (c) 2001-2003, Adam Dunkels.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * This file is part of the uIP TCP/IP stack.
- *
- * $Id: uipopt.h,v 1.11 2009/04/10 00:37:48 adamdunkels Exp $
- *
- */
-
-#ifndef __UIPOPT_H__
-#define __UIPOPT_H__
-
-#include "Config/AppConfig.h"
-
-#ifndef UIP_LITTLE_ENDIAN
-#define UIP_LITTLE_ENDIAN 3412
-#endif /* UIP_LITTLE_ENDIAN */
-#ifndef UIP_BIG_ENDIAN
-#define UIP_BIG_ENDIAN 1234
-#endif /* UIP_BIG_ENDIAN */
-
-/*------------------------------------------------------------------------------*/
-
-/**
- * \defgroup uipoptstaticconf Static configuration options
- * @{
- *
- * These configuration options can be used for setting the IP address
- * settings statically, but only if UIP_FIXEDADDR is set to 1. The
- * configuration options for a specific node includes IP address,
- * netmask and default router as well as the Ethernet address. The
- * netmask, default router and Ethernet address are applicable only
- * if uIP should be run over Ethernet.
- *
- * This options are meaningful only for the IPv4 code.
- *
- * All of these should be changed to suit your project.
- */
-
-/**
- * Determines if uIP should use a fixed IP address or not.
- *
- * If uIP should use a fixed IP address, the settings are set in the
- * uipopt.h file. If not, the macros uip_sethostaddr(),
- * uip_setdraddr() and uip_setnetmask() should be used instead.
- *
- * \hideinitializer
- */
-#define UIP_FIXEDADDR 0
-
-/**
- * Ping IP address assignment.
- *
- * uIP uses a "ping" packets for setting its own IP address if this
- * option is set. If so, uIP will start with an empty IP address and
- * the destination IP address of the first incoming "ping" (ICMP echo)
- * packet will be used for setting the hosts IP address.
- *
- * \note This works only if UIP_FIXEDADDR is 0.
- *
- * \hideinitializer
- */
-#ifdef UIP_CONF_PINGADDRCONF
-#define UIP_PINGADDRCONF UIP_CONF_PINGADDRCONF
-#else /* UIP_CONF_PINGADDRCONF */
-#define UIP_PINGADDRCONF 0
-#endif /* UIP_CONF_PINGADDRCONF */
-
-
-/**
- * Specifies if the uIP ARP module should be compiled with a fixed
- * Ethernet MAC address or not.
- *
- * If this configuration option is 0, the macro uip_setethaddr() can
- * be used to specify the Ethernet address at run-time.
- *
- * \hideinitializer
- */
-#define UIP_FIXEDETHADDR 0
-
-/** @} */
-/*------------------------------------------------------------------------------*/
-/**
- * \defgroup uipoptip IP configuration options
- * @{
- *
- */
-/**
- * The IP TTL (time to live) of IP packets sent by uIP.
- *
- * This should normally not be changed.
- */
-#define UIP_TTL 64
-
-/**
- * The maximum time an IP fragment should wait in the reassembly
- * buffer before it is dropped.
- *
- */
-#define UIP_REASS_MAXAGE 60 /*60s*/
-
-/**
- * Turn on support for IP packet reassembly.
- *
- * uIP supports reassembly of fragmented IP packets. This features
- * requires an additional amount of RAM to hold the reassembly buffer
- * and the reassembly code size is approximately 700 bytes. The
- * reassembly buffer is of the same size as the uip_buf buffer
- * (configured by UIP_BUFSIZE).
- *
- * \note IP packet reassembly is not heavily tested.
- *
- * \hideinitializer
- */
-#ifdef UIP_CONF_REASSEMBLY
-#define UIP_REASSEMBLY UIP_CONF_REASSEMBLY
-#else /* UIP_CONF_REASSEMBLY */
-#define UIP_REASSEMBLY 0
-#endif /* UIP_CONF_REASSEMBLY */
-/** @} */
-
-/*------------------------------------------------------------------------------*/
-/**
- * \defgroup uipoptipv6 IPv6 configuration options
- * @{
- *
- */
-
-/** The maximum transmission unit at the IP Layer*/
-#define UIP_LINK_MTU 1280
-
-#ifndef UIP_CONF_IPV6
-/** Do we use IPv6 or not (default: no) */
-#define UIP_CONF_IPV6 0
-#endif
-
-#ifndef UIP_CONF_IPV6_QUEUE_PKT
-/** Do we do per %neighbor queuing during address resolution (default: no) */
-#define UIP_CONF_IPV6_QUEUE_PKT 0
-#endif
-
-#ifndef UIP_CONF_IPV6_CHECKS
-/** Do we do IPv6 consistency checks (highly recommended, default: yes) */
-#define UIP_CONF_IPV6_CHECKS 1
-#endif
-
-#ifndef UIP_CONF_IPV6_REASSEMBLY
-/** Do we do IPv6 fragmentation (default: no) */
-#define UIP_CONF_IPV6_REASSEMBLY 0
-#endif
-
-#ifndef UIP_CONF_NETIF_MAX_ADDRESSES
-/** Default number of IPv6 addresses associated to the node's interface */
-#define UIP_CONF_NETIF_MAX_ADDRESSES 3
-#endif
-
-#ifndef UIP_CONF_ND6_MAX_PREFIXES
-/** Default number of IPv6 prefixes associated to the node's interface */
-#define UIP_CONF_ND6_MAX_PREFIXES 3
-#endif
-
-#ifndef UIP_CONF_ND6_MAX_NEIGHBORS
-/** Default number of neighbors that can be stored in the %neighbor cache */
-#define UIP_CONF_ND6_MAX_NEIGHBORS 4
-#endif
-
-#ifndef UIP_CONF_ND6_MAX_DEFROUTERS
-/** Minimum number of default routers */
-#define UIP_CONF_ND6_MAX_DEFROUTERS 2
-#endif
-/** @} */
-
-/*------------------------------------------------------------------------------*/
-/**
- * \defgroup uipoptudp UDP configuration options
- * @{
- *
- * \note The UDP support in uIP is still not entirely complete; there
- * is no support for sending or receiving broadcast or multicast
- * packets, but it works well enough to support a number of vital
- * applications such as DNS queries, though
- */
-
-/**
- * Toggles whether UDP support should be compiled in or not.
- *
- * \hideinitializer
- */
-#ifdef UIP_CONF_UDP
-#define UIP_UDP UIP_CONF_UDP
-#else /* UIP_CONF_UDP */
-#define UIP_UDP 1
-#endif /* UIP_CONF_UDP */
-
-/**
- * Toggles if UDP checksums should be used or not.
- *
- * \note Support for UDP checksums is currently not included in uIP,
- * so this option has no function.
- *
- * \hideinitializer
- */
-#ifdef UIP_CONF_UDP_CHECKSUMS
-#define UIP_UDP_CHECKSUMS UIP_CONF_UDP_CHECKSUMS
-#else
-#define UIP_UDP_CHECKSUMS 0
-#endif
-
-/**
- * The maximum amount of concurrent UDP connections.
- *
- * \hideinitializer
- */
-#ifdef UIP_CONF_UDP_CONNS
-#define UIP_UDP_CONNS UIP_CONF_UDP_CONNS
-#else /* UIP_CONF_UDP_CONNS */
-#define UIP_UDP_CONNS 10
-#endif /* UIP_CONF_UDP_CONNS */
-
-/**
- * The name of the function that should be called when UDP datagrams arrive.
- *
- * \hideinitializer
- */
-
-
-/** @} */
-/*------------------------------------------------------------------------------*/
-/**
- * \defgroup uipopttcp TCP configuration options
- * @{
- */
-
-/**
- * Toggles whether TCP support should be compiled in or not.
- *
- * \hideinitializer
- */
-#ifdef UIP_CONF_TCP
-#define UIP_TCP UIP_CONF_TCP
-#else /* UIP_CONF_TCP */
-#define UIP_TCP 1
-#endif /* UIP_CONF_TCP */
-
-/**
- * Determines if support for opening connections from uIP should be
- * compiled in.
- *
- * If the applications that are running on top of uIP for this project
- * do not need to open outgoing TCP connections, this configuration
- * option can be turned off to reduce the code size of uIP.
- *
- * \hideinitializer
- */
-#ifndef UIP_CONF_ACTIVE_OPEN
-#define UIP_ACTIVE_OPEN 1
-#else /* UIP_CONF_ACTIVE_OPEN */
-#define UIP_ACTIVE_OPEN UIP_CONF_ACTIVE_OPEN
-#endif /* UIP_CONF_ACTIVE_OPEN */
-
-/**
- * The maximum number of simultaneously open TCP connections.
- *
- * Since the TCP connections are statically allocated, turning this
- * configuration knob down results in less RAM used. Each TCP
- * connection requires approximately 30 bytes of memory.
- *
- * \hideinitializer
- */
-#ifndef UIP_CONF_MAX_CONNECTIONS
-#define UIP_CONNS 10
-#else /* UIP_CONF_MAX_CONNECTIONS */
-#define UIP_CONNS UIP_CONF_MAX_CONNECTIONS
-#endif /* UIP_CONF_MAX_CONNECTIONS */
-
-
-/**
- * The maximum number of simultaneously listening TCP ports.
- *
- * Each listening TCP port requires 2 bytes of memory.
- *
- * \hideinitializer
- */
-#ifndef UIP_CONF_MAX_LISTENPORTS
-#define UIP_LISTENPORTS 20
-#else /* UIP_CONF_MAX_LISTENPORTS */
-#define UIP_LISTENPORTS UIP_CONF_MAX_LISTENPORTS
-#endif /* UIP_CONF_MAX_LISTENPORTS */
-
-/**
- * Determines if support for TCP urgent data notification should be
- * compiled in.
- *
- * Urgent data (out-of-band data) is a rarely used TCP feature that
- * very seldom would be required.
- *
- * \hideinitializer
- */
-#if !defined(UIP_URGDATA)
-#define UIP_URGDATA 0
-#endif
-
-/**
- * The initial retransmission timeout counted in timer pulses.
- *
- * This should not be changed.
- */
-#if !defined(UIP_RTO)
-#define UIP_RTO 3
-#endif
-
-/**
- * The maximum number of times a segment should be retransmitted
- * before the connection should be aborted.
- *
- * This should not be changed.
- */
-#if !defined(UIP_MAXRTX)
-#define UIP_MAXRTX 8
-#endif
-
-/**
- * The maximum number of times a SYN segment should be retransmitted
- * before a connection request should be deemed to have been
- * unsuccessful.
- *
- * This should not need to be changed.
- */
-#if !defined(UIP_MAXSYNRTX)
-#define UIP_MAXSYNRTX 5
-#endif
-
-/**
- * The TCP maximum segment size.
- *
- * This is should not be to set to more than
- * UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN.
- */
-#ifdef UIP_CONF_TCP_MSS
-#define UIP_TCP_MSS UIP_CONF_TCP_MSS
-#else
-#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
-#endif
-
-/**
- * The size of the advertised receiver's window.
- *
- * Should be set low (i.e., to the size of the uip_buf buffer) if the
- * application is slow to process incoming data, or high (32768 bytes)
- * if the application processes data quickly.
- *
- * \hideinitializer
- */
-#ifndef UIP_CONF_RECEIVE_WINDOW
-#define UIP_RECEIVE_WINDOW UIP_TCP_MSS
-#else
-#define UIP_RECEIVE_WINDOW UIP_CONF_RECEIVE_WINDOW
-#endif
-
-/**
- * How long a connection should stay in the TIME_WAIT state.
- *
- * This configuration option has no real implication, and it should be
- * left untouched.
- */
-#define UIP_TIME_WAIT_TIMEOUT 120
-
-
-/** @} */
-/*------------------------------------------------------------------------------*/
-/**
- * \defgroup uipoptarp ARP configuration options
- * @{
- */
-
-/**
- * The size of the ARP table.
- *
- * This option should be set to a larger value if this uIP node will
- * have many connections from the local network.
- *
- * \hideinitializer
- */
-#ifdef UIP_CONF_ARPTAB_SIZE
-#define UIP_ARPTAB_SIZE UIP_CONF_ARPTAB_SIZE
-#else
-#define UIP_ARPTAB_SIZE 8
-#endif
-
-/**
- * The maximum age of ARP table entries measured in 10ths of seconds.
- *
- * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD
- * default).
- */
-#define UIP_ARP_MAXAGE 120
-
-
-/** @} */
-
-/*------------------------------------------------------------------------------*/
-
-/**
- * \defgroup uipoptmac layer 2 options (for ipv6)
- * @{
- */
-
-#define UIP_DEFAULT_PREFIX_LEN 64
-
-/** @} */
-
-/*------------------------------------------------------------------------------*/
-
-/**
- * \defgroup uipoptsics 6lowpan options (for ipv6)
- * @{
- */
-/**
- * Timeout for packet reassembly at the 6lowpan layer
- * (should be < 60s)
- */
-#ifdef SICSLOWPAN_CONF_MAXAGE
-#define SICSLOWPAN_REASS_MAXAGE SICSLOWPAN_CONF_MAXAGE
-#else
-#define SICSLOWPAN_REASS_MAXAGE 20
-#endif
-
-/**
- * Do we compress the IP header or not (default: no)
- */
-#ifndef SICSLOWPAN_CONF_COMPRESSION
-#define SICSLOWPAN_CONF_COMPRESSION 0
-#endif
-
-/**
- * If we use IPHC compression, how many address contexts do we support
- */
-#ifndef SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS
-#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1
-#endif
-
-/**
- * Do we support 6lowpan fragmentation
- */
-#ifndef SICSLOWPAN_CONF_FRAG
-#define SICSLOWPAN_CONF_FRAG 0
-#endif
-
-/** @} */
-
-/*------------------------------------------------------------------------------*/
-
-/**
- * \defgroup uipoptgeneral General configuration options
- * @{
- */
-
-/**
- * The size of the uIP packet buffer.
- *
- * The uIP packet buffer should not be smaller than 60 bytes, and does
- * not need to be larger than 1514 bytes. Lower size results in lower
- * TCP throughput, larger size results in higher TCP throughput.
- *
- * \hideinitializer
- */
-#ifndef UIP_CONF_BUFFER_SIZE
-#define UIP_BUFSIZE UIP_LINK_MTU + UIP_LLH_LEN
-#else /* UIP_CONF_BUFFER_SIZE */
-#define UIP_BUFSIZE UIP_CONF_BUFFER_SIZE
-#endif /* UIP_CONF_BUFFER_SIZE */
-
-
-/**
- * Determines if statistics support should be compiled in.
- *
- * The statistics is useful for debugging and to show the user.
- *
- * \hideinitializer
- */
-#ifndef UIP_CONF_STATISTICS
-#define UIP_STATISTICS 0
-#else /* UIP_CONF_STATISTICS */
-#define UIP_STATISTICS UIP_CONF_STATISTICS
-#endif /* UIP_CONF_STATISTICS */
-
-/**
- * Determines if logging of certain events should be compiled in.
- *
- * This is useful mostly for debugging. The function uip_log()
- * must be implemented to suit the architecture of the project, if
- * logging is turned on.
- *
- * \hideinitializer
- */
-#ifndef UIP_CONF_LOGGING
-#define UIP_LOGGING 0
-#else /* UIP_CONF_LOGGING */
-#define UIP_LOGGING UIP_CONF_LOGGING
-#endif /* UIP_CONF_LOGGING */
-
-/**
- * Broadcast support.
- *
- * This flag configures IP broadcast support. This is useful only
- * together with UDP.
- *
- * \hideinitializer
- *
- */
-#ifndef UIP_CONF_BROADCAST
-#define UIP_BROADCAST 0
-#else /* UIP_CONF_BROADCAST */
-#define UIP_BROADCAST UIP_CONF_BROADCAST
-#endif /* UIP_CONF_BROADCAST */
-
-/**
- * Print out a uIP log message.
- *
- * This function must be implemented by the module that uses uIP, and
- * is called by uIP whenever a log message is generated.
- */
-void uip_log(char *msg);
-
-/**
- * The link level header length.
- *
- * This is the offset into the uip_buf where the IP header can be
- * found. For Ethernet, this should be set to 14. For SLIP, this
- * should be set to 0.
- *
- * \note we probably won't use this constant for other link layers than
- * ethernet as they have variable header length (this is due to variable
- * number and type of address fields and to optional security features)
- * E.g.: 802.15.4 -> 2 + (1/2*4/8) + 0/5/6/10/14
- * 802.11 -> 4 + (6*3/4) + 2
- * \hideinitializer
- */
-#ifdef UIP_CONF_LLH_LEN
-#define UIP_LLH_LEN UIP_CONF_LLH_LEN
-#else /* UIP_LLH_LEN */
-#define UIP_LLH_LEN 14
-#endif /* UIP_CONF_LLH_LEN */
-
-/** @} */
-/*------------------------------------------------------------------------------*/
-/**
- * \defgroup uipoptcpu CPU architecture configuration
- * @{
- *
- * The CPU architecture configuration is where the endianess of the
- * CPU on which uIP is to be run is specified. Most CPUs today are
- * little endian, and the most notable exception are the Motorolas
- * which are big endian. The BYTE_ORDER macro should be changed to
- * reflect the CPU architecture on which uIP is to be run.
- */
-
-/**
- * The byte order of the CPU architecture on which uIP is to be run.
- *
- * This option can be either UIP_BIG_ENDIAN (Motorola byte order) or
- * UIP_LITTLE_ENDIAN (Intel byte order).
- *
- * \hideinitializer
- */
-#ifdef UIP_CONF_BYTE_ORDER
-#define UIP_BYTE_ORDER UIP_CONF_BYTE_ORDER
-#else /* UIP_CONF_BYTE_ORDER */
-#define UIP_BYTE_ORDER UIP_LITTLE_ENDIAN
-#endif /* UIP_CONF_BYTE_ORDER */
-
-/** @} */
-/*------------------------------------------------------------------------------*/
-
-#include <ff.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-#include "timer.h"
-
-typedef uint8_t u8_t;
-typedef uint16_t u16_t;
-typedef uint32_t u32_t;
-typedef uint32_t uip_stats_t;
-
-/**
- * \defgroup uipoptapp Application specific configurations
- * @{
- *
- * An uIP application is implemented using a single application
- * function that is called by uIP whenever a TCP/IP event occurs. The
- * name of this function must be registered with uIP at compile time
- * using the UIP_APPCALL definition.
- *
- * uIP applications can store the application state within the
- * uip_conn structure by specifying the type of the application
- * structure by typedef:ing the type uip_tcp_appstate_t and uip_udp_appstate_t.
- *
- * The file containing the definitions must be included in the
- * uipopt.h file.
- *
- * The following example illustrates how this can look.
- \code
-
- void httpd_appcall(void);
- #define UIP_APPCALL httpd_appcall
-
- struct httpd_state {
- u8_t state;
- u16_t count;
- char *dataptr;
- char *script;
- };
- typedef struct httpd_state uip_tcp_appstate_t
- \endcode
-*/
-#define UIP_UDP_APPCALL uIPManagement_UDPCallback
-void UIP_UDP_APPCALL(void);
-
-/**
- * \var #define UIP_APPCALL
- *
- * The name of the application function that uIP should call in
- * response to TCP/IP events.
- *
- */
-#define UIP_APPCALL uIPManagement_TCPCallback
-void UIP_APPCALL(void);
-
-/**
- * \var typedef uip_tcp_appstate_t
- *
- * The type of the application state that is to be stored in the
- * uip_conn structure. This usually is typedef:ed to a struct holding
- * application state information.
- */
-typedef union
-{
- struct
- {
- uint8_t CurrentState;
- uint8_t NextState;
-
- char FileName[MAX_URI_LENGTH];
- FIL FileHandle;
- bool FileOpen;
- uint32_t ACKedFilePos;
- uint16_t SentChunkSize;
- } HTTPServer;
-
- struct
- {
- uint8_t CurrentState;
- uint8_t NextState;
-
- uint8_t IssuedCommand;
- } TELNETServer;
-} uip_tcp_appstate_t;
-
-/**
- * \var typedef uip_udp_appstate_t
- *
- * The type of the application state that is to be stored in the
- * uip_conn structure. This usually is typedef:ed to a struct holding
- * application state information.
- */
-typedef union
-{
- struct
- {
- uint8_t CurrentState;
- struct timer Timeout;
-
- struct
- {
- uint8_t AllocatedIP[4];
- uint8_t Netmask[4];
- uint8_t GatewayIP[4];
- uint8_t ServerIP[4];
- } DHCPOffer_Data;
- } DHCPClient;
-} uip_udp_appstate_t;
-/** @} */
-
-#endif /* __UIPOPT_H__ */
-/** @} */
-/** @} */
-
diff --git a/lib/lufa/Projects/Webserver/USBDeviceMode.c b/lib/lufa/Projects/Webserver/USBDeviceMode.c
deleted file mode 100644
index c883f1441..000000000
--- a/lib/lufa/Projects/Webserver/USBDeviceMode.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * USB Device Mode management functions and variables. This file contains the LUFA code required to
- * manage the USB Mass Storage device mode.
- */
-
-#include "USBDeviceMode.h"
-
-/** Message buffer for RNDIS messages processed by the RNDIS device class driver. */
-static uint8_t RNDIS_Message_Buffer[192];
-
-/** LUFA RNDIS Class driver interface configuration and state information. This structure is
- * passed to all RNDIS Class driver functions, so that multiple instances of the same class
- * within a device can be differentiated from one another.
- */
-USB_ClassInfo_RNDIS_Device_t Ethernet_RNDIS_Interface_Device =
- {
- .Config =
- {
- .ControlInterfaceNumber = INTERFACE_ID_CDC_CCI,
- .DataINEndpoint =
- {
- .Address = CDC_TX_EPADDR,
- .Size = CDC_TXRX_EPSIZE,
- .Banks = 1,
- },
- .DataOUTEndpoint =
- {
- .Address = CDC_RX_EPADDR,
- .Size = CDC_TXRX_EPSIZE,
- .Banks = 1,
- },
- .NotificationEndpoint =
- {
- .Address = CDC_NOTIFICATION_EPADDR,
- .Size = CDC_NOTIFICATION_EPSIZE,
- .Banks = 1,
- },
- .AdapterVendorDescription = "LUFA RNDIS Adapter",
- .AdapterMACAddress = {{0x02, 0x00, 0x02, 0x00, 0x02, 0x00}},
- .MessageBuffer = RNDIS_Message_Buffer,
- .MessageBufferLength = sizeof(RNDIS_Message_Buffer),
- },
- };
-
-/** LUFA Mass Storage Class driver interface configuration and state information. This structure is
- * passed to all Mass Storage Class driver functions, so that multiple instances of the same class
- * within a device can be differentiated from one another.
- */
-USB_ClassInfo_MS_Device_t Disk_MS_Interface =
- {
- .Config =
- {
- .InterfaceNumber = INTERFACE_ID_MassStorage,
- .DataINEndpoint =
- {
- .Address = MASS_STORAGE_IN_EPADDR,
- .Size = MASS_STORAGE_IO_EPSIZE,
- .Banks = 1,
- },
- .DataOUTEndpoint =
- {
- .Address = MASS_STORAGE_OUT_EPADDR,
- .Size = MASS_STORAGE_IO_EPSIZE,
- .Banks = 1,
- },
- .TotalLUNs = 1,
- },
- };
-
-
-/** USB device mode management task. This function manages the Mass Storage Device class driver when the device is
- * initialized in USB device mode.
- */
-void USBDeviceMode_USBTask(void)
-{
- if (USB_CurrentMode != USB_MODE_Device)
- return;
-
- uIPManagement_ManageNetwork();
-
- RNDIS_Device_USBTask(&Ethernet_RNDIS_Interface_Device);
- MS_Device_USBTask(&Disk_MS_Interface);
-}
-
-/** Event handler for the library USB Connection event. */
-void EVENT_USB_Device_Connect(void)
-{
- LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-
- uIPManagement_Init();
-}
-
-/** Event handler for the library USB Disconnection event. */
-void EVENT_USB_Device_Disconnect(void)
-{
- LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
-}
-
-/** Event handler for the library USB Configuration Changed event. */
-void EVENT_USB_Device_ConfigurationChanged(void)
-{
- bool ConfigSuccess = true;
-
- ConfigSuccess &= RNDIS_Device_ConfigureEndpoints(&Ethernet_RNDIS_Interface_Device);
- ConfigSuccess &= MS_Device_ConfigureEndpoints(&Disk_MS_Interface);
-
- LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);
-}
-
-/** Event handler for the library USB Control Request reception event. */
-void EVENT_USB_Device_ControlRequest(void)
-{
- RNDIS_Device_ProcessControlRequest(&Ethernet_RNDIS_Interface_Device);
- MS_Device_ProcessControlRequest(&Disk_MS_Interface);
-}
-
-/** Mass Storage class driver callback function the reception of SCSI commands from the host, which must be processed.
- *
- * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface configuration structure being referenced
- */
-bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
-{
- bool CommandSuccess;
-
- LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
- CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo);
- LEDs_SetAllLEDs(LEDMASK_USB_READY);
-
- return CommandSuccess;
-}
-
diff --git a/lib/lufa/Projects/Webserver/USBDeviceMode.h b/lib/lufa/Projects/Webserver/USBDeviceMode.h
deleted file mode 100644
index f71490333..000000000
--- a/lib/lufa/Projects/Webserver/USBDeviceMode.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Header file for USBDeviceMode.c.
- */
-
-#ifndef _USBDEVICEMODE_H_
-#define _USBDEVICEMODE_H_
-
- /* Includes: */
- #include <LUFA/Drivers/USB/USB.h>
-
- #include "Webserver.h"
- #include "Descriptors.h"
- #include "Lib/uIPManagement.h"
- #include "Lib/SCSI.h"
- #include "Config/AppConfig.h"
-
- /* External Variables: */
- extern USB_ClassInfo_RNDIS_Device_t Ethernet_RNDIS_Interface_Device;
-
- /* Function Prototypes: */
- void USBDeviceMode_USBTask(void);
-
- void EVENT_USB_Device_Connect(void);
- void EVENT_USB_Device_Disconnect(void);
- void EVENT_USB_Device_ConfigurationChanged(void);
- void EVENT_USB_Device_ControlRequest(void);
-
- bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
-
-#endif
-
diff --git a/lib/lufa/Projects/Webserver/USBHostMode.c b/lib/lufa/Projects/Webserver/USBHostMode.c
deleted file mode 100644
index 04190bfe2..000000000
--- a/lib/lufa/Projects/Webserver/USBHostMode.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * USB Host Mode management functions and variables. This file contains the LUFA code required to
- * manage the USB RNDIS host mode.
- */
-
-#include "USBHostMode.h"
-
-/** LUFA RNDIS Class driver interface configuration and state information. This structure is
- * passed to all RNDIS Class driver functions, so that multiple instances of the same class
- * within a device can be differentiated from one another.
- */
-USB_ClassInfo_RNDIS_Host_t Ethernet_RNDIS_Interface_Host =
- {
- .Config =
- {
- .DataINPipe =
- {
- .Address = (PIPE_DIR_IN | 1),
- .Banks = 1,
- },
- .DataOUTPipe =
- {
- .Address = (PIPE_DIR_OUT | 2),
- .Banks = 1,
- },
- .NotificationPipe =
- {
- .Address = (PIPE_DIR_IN | 3),
- .Banks = 1,
- },
- .HostMaxPacketSize = UIP_CONF_BUFFER_SIZE,
- },
- };
-
-
-/** USB host mode management task. This function manages the RNDIS Host class driver and uIP stack when the device is
- * initialized in USB host mode.
- */
-void USBHostMode_USBTask(void)
-{
- if (USB_CurrentMode != USB_MODE_Host)
- return;
-
- uIPManagement_ManageNetwork();
-
- RNDIS_Host_USBTask(&Ethernet_RNDIS_Interface_Host);
-}
-
-/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
- * starts the library USB task to begin the enumeration and USB management process.
- */
-void EVENT_USB_Host_DeviceAttached(void)
-{
- LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-}
-
-/** Event handler for the USB_DeviceUnattached event. This indicates that a device has been removed from the host, and
- * stops the library USB task management process.
- */
-void EVENT_USB_Host_DeviceUnattached(void)
-{
- LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
-}
-
-/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully
- * enumerated by the host and is now ready to be used by the application.
- */
-void EVENT_USB_Host_DeviceEnumerationComplete(void)
-{
- LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-
- uint16_t ConfigDescriptorSize;
- uint8_t ConfigDescriptorData[512];
-
- if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
- sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
- {
- LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
- return;
- }
-
- if (RNDIS_Host_ConfigurePipes(&Ethernet_RNDIS_Interface_Host,
- ConfigDescriptorSize, ConfigDescriptorData) != RNDIS_ENUMERROR_NoError)
- {
- LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
- return;
- }
-
- if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
- {
- LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
- return;
- }
-
- if (RNDIS_Host_InitializeDevice(&Ethernet_RNDIS_Interface_Host) != HOST_SENDCONTROL_Successful)
- {
- LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
- USB_Host_SetDeviceConfiguration(0);
- return;
- }
-
- uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST);
- if (RNDIS_Host_SetRNDISProperty(&Ethernet_RNDIS_Interface_Host, OID_GEN_CURRENT_PACKET_FILTER,
- &PacketFilter, sizeof(PacketFilter)) != HOST_SENDCONTROL_Successful)
- {
- LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
- USB_Host_SetDeviceConfiguration(0);
- return;
- }
-
- if (RNDIS_Host_QueryRNDISProperty(&Ethernet_RNDIS_Interface_Host, OID_802_3_CURRENT_ADDRESS,
- &MACAddress, sizeof(MACAddress)) != HOST_SENDCONTROL_Successful)
- {
- LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
- USB_Host_SetDeviceConfiguration(0);
- return;
- }
-
- /* Initialize uIP stack */
- uIPManagement_Init();
-
- LEDs_SetAllLEDs(LEDMASK_USB_READY);
-}
-
-/** Event handler for the USB_HostError event. This indicates that a hardware error occurred while in host mode. */
-void EVENT_USB_Host_HostError(const uint8_t ErrorCode)
-{
- USB_Disable();
-
- LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
- for(;;);
-}
-
-/** Event handler for the USB_DeviceEnumerationFailed event. This indicates that a problem occurred while
- * enumerating an attached USB device.
- */
-void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8_t SubErrorCode)
-{
- LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-}
-
diff --git a/lib/lufa/Projects/Webserver/USBHostMode.h b/lib/lufa/Projects/Webserver/USBHostMode.h
deleted file mode 100644
index b2c8d66ec..000000000
--- a/lib/lufa/Projects/Webserver/USBHostMode.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Header file for USBHostMode.c.
- */
-
-#ifndef _USBHOSTMODE_H_
-#define _USBHOSTMODE_H_
-
- /* Includes: */
- #include <LUFA/Drivers/USB/USB.h>
-
- #include "Webserver.h"
- #include "Lib/uIPManagement.h"
- #include "Config/AppConfig.h"
-
- /* External Variables: */
- extern USB_ClassInfo_RNDIS_Host_t Ethernet_RNDIS_Interface_Host;
-
- /* Function Prototypes: */
- void USBHostMode_USBTask(void);
-
- void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
- void EVENT_USB_Host_DeviceAttached(void);
- void EVENT_USB_Host_DeviceUnattached(void);
- void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
- const uint8_t SubErrorCode);
- void EVENT_USB_Host_DeviceEnumerationComplete(void);
-
-#endif
-
diff --git a/lib/lufa/Projects/Webserver/Webserver.c b/lib/lufa/Projects/Webserver/Webserver.c
deleted file mode 100644
index bd8fa24ce..000000000
--- a/lib/lufa/Projects/Webserver/Webserver.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Main source file for the Webserver project. This file contains the main tasks of
- * the project and is responsible for the initial application hardware configuration.
- */
-
-#include "Webserver.h"
-
-/** Main program entry point. This routine configures the hardware required by the application, then
- * enters a loop to run the application tasks in sequence.
- */
-int main(void)
-{
- SetupHardware();
-
- LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
- GlobalInterruptEnable();
-
- for (;;)
- {
- if (USB_CurrentMode == USB_MODE_Host)
- USBHostMode_USBTask();
- else
- USBDeviceMode_USBTask();
-
- USB_USBTask();
- }
-}
-
-/** Configures the board hardware and chip peripherals for the demo's functionality. */
-void SetupHardware(void)
-{
-#if (ARCH == ARCH_AVR8)
- /* Disable watchdog if enabled by bootloader/fuses */
- MCUSR &= ~(1 << WDRF);
- wdt_disable();
-
- /* Disable clock division */
- clock_prescale_set(clock_div_1);
-#endif
-
- /* Hardware Initialization */
- Dataflash_Init();
- LEDs_Init();
- USB_Init(USB_MODE_UID);
-}
-
diff --git a/lib/lufa/Projects/Webserver/Webserver.h b/lib/lufa/Projects/Webserver/Webserver.h
deleted file mode 100644
index 0438fe0b9..000000000
--- a/lib/lufa/Projects/Webserver/Webserver.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2017.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-
-/*
- Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaims all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Header file for Webserver.c.
- */
-
-#ifndef _WEBSERVER_H_
-#define _WEBSERVER_H_
-
- /* Includes: */
- #include <avr/io.h>
- #include <avr/wdt.h>
- #include <avr/pgmspace.h>
- #include <avr/power.h>
- #include <avr/interrupt.h>
-
- #include <LUFA/Drivers/Board/LEDs.h>
- #include <LUFA/Drivers/Board/Dataflash.h>
- #include <LUFA/Drivers/Peripheral/SPI.h>
- #include <LUFA/Drivers/USB/USB.h>
- #include <LUFA/Platform/Platform.h>
-
- #include "USBDeviceMode.h"
- #include "USBHostMode.h"
- #include "Config/AppConfig.h"
-
- /* Macros: */
- /** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
- #define LEDMASK_USB_NOTREADY LEDS_LED1
-
- /** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
- #define LEDMASK_USB_ENUMERATING (LEDS_LED1 | LEDS_LED2)
-
- /** LED mask for the library LED driver, to indicate that the USB interface is ready. */
- #define LEDMASK_USB_READY LEDS_LED2
-
- /** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
- #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
-
- /** LED mask for the library LED driver, to indicate that the USB interface is busy. */
- #define LEDMASK_USB_BUSY (LEDS_LED1 | LEDS_LED3 | LEDS_LED4)
-
- /* Function Prototypes: */
- void SetupHardware(void);
-
-#endif
-
diff --git a/lib/lufa/Projects/Webserver/Webserver.txt b/lib/lufa/Projects/Webserver/Webserver.txt
deleted file mode 100644
index 10aa71652..000000000
--- a/lib/lufa/Projects/Webserver/Webserver.txt
+++ /dev/null
@@ -1,126 +0,0 @@
-/** \file
- *
- * This file contains special DoxyGen information for the generation of the main page and other special
- * documentation pages. It is not a project source file.
- */
-
-/** \mainpage uIP Powered Webserver Project
- *
- * \section Sec_Compat Project Compatibility:
- *
- * The following list indicates what microcontrollers are compatible with this project.
- *
- * \li Series 7 USB AVRs (AT90USBxxx7)
- *
- * \section Sec_Info USB Information:
- *
- * The following table gives a rundown of the USB utilization of this project.
- *
- * <table>
- * <tr>
- * <td><b>USB Mode:</b></td>
- * <td>Dual Mode Host/Device</td>
- * </tr>
- * <tr>
- * <td><b>USB Class:</b></td>
- * <td>Communications Device Class (CDC) \n
- * Mass Storage Device</td>
- * </tr>
- * <tr>
- * <td><b>USB Subclass:</b></td>
- * <td>Remote NDIS (Microsoft Proprietary CDC Class Networking Standard) \n
- * Bulk-Only Transport</td>
- * </tr>
- * <tr>
- * <td><b>Relevant Standards:</b></td>
- * <td>Microsoft RNDIS Specification \n
- * USBIF Mass Storage Standard \n
- * USB Bulk-Only Transport Standard \n
- * SCSI Primary Commands Specification \n
- * SCSI Block Commands Specification</td>
- * </tr>
- * <tr>
- * <td><b>Supported USB Speeds:</b></td>
- * <td>Full Speed Mode</td>
- * </tr>
- * </table>
- *
- * \section Sec_Description Project Description:
- *
- * Simple HTTP webserver project. This project combines the LUFA library with the uIP TCP/IP full network stack and FatFS
- * library to create a RNDIS host capable of serving out HTTP web pages to multiple hosts simultaneously. This project
- * demonstrates how the libraries can be combined into a robust network enabled application, with the addition of a RNDIS
- * network device.
- *
- * To use this project, plug the USB AVR into a computer, so that it enumerates as a standard Mass Storage and RNDIS composite
- * device. Load HTML files onto the disk, so that they can be served out to clients -- the default file to serve should be called
- * <i>index.htm</i>. Filenames must be in 8.3 format for them to be retrieved correctly by the webserver, and the total
- * requested file path must be equal to or less than the maximum URI length (\see \ref Sec_Options). Supply the included INF
- * file when requested on Windows machines to enable the RNDIS interface, and allow the files to be viewed on a standard web-browser
- * using the IP address 10.0.0.2.
- *
- * When attached to a RNDIS class device, such as a USB (desktop) modem, the system will enumerate the device, set the
- * appropriate parameters needed for connectivity and begin listening for new HTTP connections on port 80 and TELNET
- * connections on port 23. The device IP, netmask and default gateway IP must be set to values appropriate for the RNDIS
- * device being used for this project to work if the DHCP client is disabled (see \ref Sec_Options) - otherwise, the device
- * will query the network's DHCP server for these parameters automatically.
- *
- * When properly configured, the webserver can be accessed from any HTTP web browser by typing in the device's statically or
- * dynamically allocated IP address. The TELNET client can be accessed via any network socket app by connecting to the device
- * on port 23 on the device's statically or dynamically allocated IP address.
- *
- * \section Sec_Options Project Options
- *
- * The following defines can be found in this project, which can control the project behaviour when defined, or changed in value.
- *
- * <table>
- * <tr>
- * <th><b>Define Name:</b></th>
- * <th><b>Location:</b></th>
- * <th><b>Description:</b></th>
- * </tr>
- * <tr>
- * <td>ENABLE_TELNET_SERVER</td>
- * <td>AppConfig.h</td>
- * <td>When defined, this enables the TELNET server in addition to the HTTP webserver, which listens for incoming connections
- * and processes user commands.</td>
- * </tr>
- * <tr>
- * <td>ENABLE_DHCP_CLIENT</td>
- * <td>AppConfig.h</td>
- * <td>When defined, this enables the DHCP client for dynamic IP allocation of the network settings from a DHCP server.</td>
- * </tr>
- * <tr>
- * <td>ENABLE_DHCP_SERVER</td>
- * <td>AppConfig.h</td>
- * <td>When defined, this enables the DHCP server for dynamic IP allocation of the network settings to a DHCP client.</td>
- * </tr>
- * <tr>
- * <td>DEVICE_IP_ADDRESS</td>
- * <td>AppConfig.h</td>
- * <td>IP address that the webserver should use when connected to a RNDIS device (when ENABLE_DHCP_CLIENT is not defined).</td>
- * </tr>
- * <tr>
- * <td>DEVICE_NETMASK</td>
- * <td>AppConfig.h</td>
- * <td>Netmask that the webserver should use when connected to a RNDIS device (when ENABLE_DHCP_CLIENT is not defined).</td>
- * </tr>
- * <tr>
- * <td>DEVICE_GATEWAY</td>
- * <td>AppConfig.h</td>
- * <td>Default routing gateway that the webserver should use when connected to a RNDIS device (when ENABLE_DHCP_CLIENT
- * is not defined).</td>
- * </tr>
- * <tr>
- * <td>MAX_URI_LENGTH</td>
- * <td>AppConfig.h</td>
- * <td>Maximum length of a URI for the Webserver. This is the maximum file path, including subdirectories and separators.</td>
- * </tr>
- * <tr>
- * <td>SERVER_MAC_ADDRESS</td>
- * <td>AppConfig.h</td>
- * <td>MAC address of the server used when sending Ethernet packets onto the bus.</td>
- * </tr>
- * </table>
- */
-
diff --git a/lib/lufa/Projects/Webserver/asf.xml b/lib/lufa/Projects/Webserver/asf.xml
deleted file mode 100644
index ca1733e85..000000000
--- a/lib/lufa/Projects/Webserver/asf.xml
+++ /dev/null
@@ -1,96 +0,0 @@
-<asf xmlversion="1.0">
- <project caption="RNDIS Webserver" id="lufa.projects.webserver.avr8">
- <require idref="lufa.projects.webserver"/>
- <require idref="lufa.boards.dummy.avr8"/>
- <generator value="as5_8"/>
-
- <device-support value="at90usb1287"/>
- <config name="lufa.drivers.board.name" value="usbkey"/>
-
- <build type="define" name="F_CPU" value="8000000UL"/>
- <build type="define" name="F_USB" value="8000000UL"/>
- </project>
-
- <module type="application" id="lufa.projects.webserver" caption="RNDIS Webserver">
- <info type="description" value="summary">
- RNDIS Webserver project, using the open source uIP network stack.
- </info>
-
- <info type="gui-flag" value="move-to-root"/>
-
- <info type="keyword" value="Technology">
- <keyword value="Class Driver APIs"/>
- <keyword value="USB Dual Role"/>
- <keyword value="RNDIS Class"/>
- <keyword value="Mass Storage Class"/>
- </info>
-
- <device-support-alias value="lufa_avr8"/>
- <device-support-alias value="lufa_xmega"/>
- <device-support-alias value="lufa_uc3"/>
-
- <build type="distribute" subtype="user-file" value="doxyfile"/>
- <build type="distribute" subtype="user-file" value="Webserver.txt"/>
- <build type="distribute" subtype="user-file" value="LUFA Webserver RNDIS.inf"/>
-
- <build type="c-source" value="Webserver.c"/>
- <build type="c-source" value="USBDeviceMode.c"/>
- <build type="c-source" value="USBHostMode.c"/>
- <build type="c-source" value="Descriptors.c"/>
- <build type="header-file" value="Webserver.h"/>
- <build type="header-file" value="USBDeviceMode.h"/>
- <build type="header-file" value="USBHostMode.h"/>
- <build type="header-file" value="Descriptors.h"/>
-
- <build type="c-source" value="Lib/DataflashManager.c"/>
- <build type="header-file" value="Lib/DataflashManager.h"/>
- <build type="c-source" value="Lib/DHCPClientApp.c"/>
- <build type="header-file" value="Lib/DHCPClientApp.h"/>
- <build type="c-source" value="Lib/DHCPCommon.c"/>
- <build type="header-file" value="Lib/DHCPCommon.h"/>
- <build type="c-source" value="Lib/DHCPServerApp.c"/>
- <build type="header-file" value="Lib/DHCPServerApp.h"/>
- <build type="c-source" value="Lib/HTTPServerApp.c"/>
- <build type="header-file" value="Lib/HTTPServerApp.h"/>
- <build type="c-source" value="Lib/SCSI.c"/>
- <build type="header-file" value="Lib/SCSI.h"/>
- <build type="c-source" value="Lib/TELNETServerApp.c"/>
- <build type="header-file" value="Lib/TELNETServerApp.h"/>
- <build type="c-source" value="Lib/uIPManagement.c"/>
- <build type="header-file" value="Lib/uIPManagement.h"/>
-
- <build type="include-path" value="Lib/FATFs/"/>
- <build type="c-source" value="Lib/FATFs/ff.c"/>
- <build type="header-file" value="Lib/FATFs/ff.h"/>
- <build type="c-source" value="Lib/FATFs/diskio.c"/>
- <build type="header-file" value="Lib/FATFs/diskio.h"/>
- <build type="header-file" value="Lib/FATFs/ffconf.h"/>
- <build type="header-file" value="Lib/FATFs/integer.h"/>
-
- <build type="include-path" value="Lib/uip/"/>
- <build type="c-source" value="Lib/uip/clock.c"/>
- <build type="header-file" value="Lib/uip/clock.h"/>
- <build type="c-source" value="Lib/uip/timer.c"/>
- <build type="header-file" value="Lib/uip/timer.h"/>
- <build type="c-source" value="Lib/uip/uip.c"/>
- <build type="header-file" value="Lib/uip/uip.h"/>
- <build type="c-source" value="Lib/uip/uip_arp.c"/>
- <build type="header-file" value="Lib/uip/uip_arp.h"/>
- <build type="c-source" value="Lib/uip/uip-split.c"/>
- <build type="header-file" value="Lib/uip/uip-split.h"/>
- <build type="header-file" value="Lib/uip/uipopt.h"/>
-
- <build type="module-config" subtype="path" value="Config"/>
- <build type="module-config" subtype="required-header-file" value="AppConfig.h"/>
- <build type="header-file" value="Config/AppConfig.h"/>
- <build type="header-file" value="Config/LUFAConfig.h"/>
-
- <require idref="lufa.common"/>
- <require idref="lufa.platform"/>
- <require idref="lufa.drivers.usb"/>
- <require idref="lufa.drivers.board"/>
- <require idref="lufa.drivers.board.leds"/>
- <require idref="lufa.drivers.board.dataflash"/>
- <require idref="lufa.drivers.peripheral.spi"/>
- </module>
-</asf>
diff --git a/lib/lufa/Projects/Webserver/doxyfile b/lib/lufa/Projects/Webserver/doxyfile
deleted file mode 100644
index 0f01c93b3..000000000
--- a/lib/lufa/Projects/Webserver/doxyfile
+++ /dev/null
@@ -1,2396 +0,0 @@
-# Doxyfile 1.8.9
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project.
-#
-# All text after a double hash (##) is considered a comment and is placed in
-# front of the TAG it is preceding.
-#
-# All text after a single hash (#) is considered a comment and will be ignored.
-# The format is:
-# TAG = value [value, ...]
-# For lists, items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (\" \").
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# This tag specifies the encoding used for all characters in the config file
-# that follow. The default is UTF-8 which is also the encoding used for all text
-# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
-# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
-# for the list of possible encodings.
-# The default value is: UTF-8.
-
-DOXYFILE_ENCODING = UTF-8
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
-# double-quotes, unless you are using Doxywizard) that should identify the
-# project for which the documentation is generated. This name is used in the
-# title of most generated pages and in a few other places.
-# The default value is: My Project.
-
-PROJECT_NAME = "LUFA Library - uIP Powered Webserver Project"
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
-# could be handy for archiving the generated documentation or if some version
-# control system is used.
-
-PROJECT_NUMBER =
-
-# Using the PROJECT_BRIEF tag one can provide an optional one line description
-# for a project that appears at the top of each page and should give viewer a
-# quick idea about the purpose of the project. Keep the description short.
-
-PROJECT_BRIEF =
-
-# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
-# in the documentation. The maximum height of the logo should not exceed 55
-# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
-# the logo to the output directory.
-
-PROJECT_LOGO =
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
-# into which the generated documentation will be written. If a relative path is
-# entered, it will be relative to the location where doxygen was started. If
-# left blank the current directory will be used.
-
-OUTPUT_DIRECTORY = ./Documentation/
-
-# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
-# directories (in 2 levels) under the output directory of each output format and
-# will distribute the generated files over these directories. Enabling this
-# option can be useful when feeding doxygen a huge amount of source files, where
-# putting all generated files in the same directory would otherwise causes
-# performance problems for the file system.
-# The default value is: NO.
-
-CREATE_SUBDIRS = NO
-
-# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
-# characters to appear in the names of generated files. If set to NO, non-ASCII
-# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
-# U+3044.
-# The default value is: NO.
-
-ALLOW_UNICODE_NAMES = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
-# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
-# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
-# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
-# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
-# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
-# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
-# Ukrainian and Vietnamese.
-# The default value is: English.
-
-OUTPUT_LANGUAGE = English
-
-# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
-# descriptions after the members that are listed in the file and class
-# documentation (similar to Javadoc). Set to NO to disable this.
-# The default value is: YES.
-
-BRIEF_MEMBER_DESC = YES
-
-# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
-# description of a member or function before the detailed description
-#
-# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-# The default value is: YES.
-
-REPEAT_BRIEF = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator that is
-# used to form the text in various listings. Each string in this list, if found
-# as the leading text of the brief description, will be stripped from the text
-# and the result, after processing the whole list, is used as the annotated
-# text. Otherwise, the brief description is used as-is. If left blank, the
-# following values are used ($name is automatically replaced with the name of
-# the entity):The $name class, The $name widget, The $name file, is, provides,
-# specifies, contains, represents, a, an and the.
-
-ABBREVIATE_BRIEF = "The $name class" \
- "The $name widget" \
- "The $name file" \
- is \
- provides \
- specifies \
- contains \
- represents \
- a \
- an \
- the
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# doxygen will generate a detailed section even if there is only a brief
-# description.
-# The default value is: NO.
-
-ALWAYS_DETAILED_SEC = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-# The default value is: NO.
-
-INLINE_INHERITED_MEMB = NO
-
-# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
-# before files name in the file list and in the header files. If set to NO the
-# shortest path that makes the file name unique will be used
-# The default value is: YES.
-
-FULL_PATH_NAMES = YES
-
-# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
-# Stripping is only done if one of the specified strings matches the left-hand
-# part of the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the path to
-# strip.
-#
-# Note that you can specify absolute paths here, but also relative paths, which
-# will be relative from the directory where doxygen is started.
-# This tag requires that the tag FULL_PATH_NAMES is set to YES.
-
-STRIP_FROM_PATH =
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
-# path mentioned in the documentation of a class, which tells the reader which
-# header file to include in order to use a class. If left blank only the name of
-# the header file containing the class definition is used. Otherwise one should
-# specify the list of include paths that are normally passed to the compiler
-# using the -I flag.
-
-STRIP_FROM_INC_PATH =
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
-# less readable) file names. This can be useful is your file systems doesn't
-# support long names like on DOS, Mac, or CD-ROM.
-# The default value is: NO.
-
-SHORT_NAMES = YES
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
-# first line (until the first dot) of a Javadoc-style comment as the brief
-# description. If set to NO, the Javadoc-style will behave just like regular Qt-
-# style comments (thus requiring an explicit @brief command for a brief
-# description.)
-# The default value is: NO.
-
-JAVADOC_AUTOBRIEF = NO
-
-# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
-# line (until the first dot) of a Qt-style comment as the brief description. If
-# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
-# requiring an explicit \brief command for a brief description.)
-# The default value is: NO.
-
-QT_AUTOBRIEF = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
-# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
-# a brief description. This used to be the default behavior. The new default is
-# to treat a multi-line C++ comment block as a detailed description. Set this
-# tag to YES if you prefer the old behavior instead.
-#
-# Note that setting this tag to YES also means that rational rose comments are
-# not recognized any more.
-# The default value is: NO.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
-# documentation from any documented member that it re-implements.
-# The default value is: YES.
-
-INHERIT_DOCS = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
-# page for each member. If set to NO, the documentation of a member will be part
-# of the file/class/namespace that contains it.
-# The default value is: NO.
-
-SEPARATE_MEMBER_PAGES = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
-# uses this value to replace tabs by spaces in code fragments.
-# Minimum value: 1, maximum value: 16, default value: 4.
-
-TAB_SIZE = 4
-
-# This tag can be used to specify a number of aliases that act as commands in
-# the documentation. An alias has the form:
-# name=value
-# For example adding
-# "sideeffect=@par Side Effects:\n"
-# will allow you to put the command \sideeffect (or @sideeffect) in the
-# documentation, which will result in a user-defined paragraph with heading
-# "Side Effects:". You can put \n's in the value part of an alias to insert
-# newlines.
-
-ALIASES =
-
-# This tag can be used to specify a number of word-keyword mappings (TCL only).
-# A mapping has the form "name=value". For example adding "class=itcl::class"
-# will allow you to use the command class in the itcl::class meaning.
-
-TCL_SUBST =
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
-# only. Doxygen will then generate output that is more tailored for C. For
-# instance, some of the names that are used will be different. The list of all
-# members will be omitted, etc.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_FOR_C = YES
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
-# Python sources only. Doxygen will then generate output that is more tailored
-# for that language. For instance, namespaces will be presented as packages,
-# qualified scopes will look different, etc.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_JAVA = NO
-
-# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
-# sources. Doxygen will then generate output that is tailored for Fortran.
-# The default value is: NO.
-
-OPTIMIZE_FOR_FORTRAN = NO
-
-# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
-# sources. Doxygen will then generate output that is tailored for VHDL.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_VHDL = NO
-
-# Doxygen selects the parser to use depending on the extension of the files it
-# parses. With this tag you can assign which parser to use for a given
-# extension. Doxygen has a built-in mapping, but you can override or extend it
-# using this tag. The format is ext=language, where ext is a file extension, and
-# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
-# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
-# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
-# Fortran. In the later case the parser tries to guess whether the code is fixed
-# or free formatted code, this is the default for Fortran type files), VHDL. For
-# instance to make doxygen treat .inc files as Fortran files (default is PHP),
-# and .f files as C (default is Fortran), use: inc=Fortran f=C.
-#
-# Note: For files without extension you can use no_extension as a placeholder.
-#
-# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
-# the files are not read by doxygen.
-
-EXTENSION_MAPPING =
-
-# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
-# according to the Markdown format, which allows for more readable
-# documentation. See http://daringfireball.net/projects/markdown/ for details.
-# The output of markdown processing is further processed by doxygen, so you can
-# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
-# case of backward compatibilities issues.
-# The default value is: YES.
-
-MARKDOWN_SUPPORT = NO
-
-# When enabled doxygen tries to link words that correspond to documented
-# classes, or namespaces to their corresponding documentation. Such a link can
-# be prevented in individual cases by putting a % sign in front of the word or
-# globally by setting AUTOLINK_SUPPORT to NO.
-# The default value is: YES.
-
-AUTOLINK_SUPPORT = YES
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
-# to include (a tag file for) the STL sources as input, then you should set this
-# tag to YES in order to let doxygen match functions declarations and
-# definitions whose arguments contain STL classes (e.g. func(std::string);
-# versus func(std::string) {}). This also make the inheritance and collaboration
-# diagrams that involve STL classes more complete and accurate.
-# The default value is: NO.
-
-BUILTIN_STL_SUPPORT = NO
-
-# If you use Microsoft's C++/CLI language, you should set this option to YES to
-# enable parsing support.
-# The default value is: NO.
-
-CPP_CLI_SUPPORT = NO
-
-# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
-# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
-# will parse them like normal C++ but will assume all classes use public instead
-# of private inheritance when no explicit protection keyword is present.
-# The default value is: NO.
-
-SIP_SUPPORT = NO
-
-# For Microsoft's IDL there are propget and propput attributes to indicate
-# getter and setter methods for a property. Setting this option to YES will make
-# doxygen to replace the get and set methods by a property in the documentation.
-# This will only work if the methods are indeed getting or setting a simple
-# type. If this is not the case, or you want to show the methods anyway, you
-# should set this option to NO.
-# The default value is: YES.
-
-IDL_PROPERTY_SUPPORT = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-# The default value is: NO.
-
-DISTRIBUTE_GROUP_DOC = NO
-
-# Set the SUBGROUPING tag to YES to allow class member groups of the same type
-# (for instance a group of public functions) to be put as a subgroup of that
-# type (e.g. under the Public Functions section). Set it to NO to prevent
-# subgrouping. Alternatively, this can be done per class using the
-# \nosubgrouping command.
-# The default value is: YES.
-
-SUBGROUPING = YES
-
-# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
-# are shown inside the group in which they are included (e.g. using \ingroup)
-# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
-# and RTF).
-#
-# Note that this feature does not work in combination with
-# SEPARATE_MEMBER_PAGES.
-# The default value is: NO.
-
-INLINE_GROUPED_CLASSES = NO
-
-# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
-# with only public data fields or simple typedef fields will be shown inline in
-# the documentation of the scope in which they are defined (i.e. file,
-# namespace, or group documentation), provided this scope is documented. If set
-# to NO, structs, classes, and unions are shown on a separate page (for HTML and
-# Man pages) or section (for LaTeX and RTF).
-# The default value is: NO.
-
-INLINE_SIMPLE_STRUCTS = NO
-
-# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
-# enum is documented as struct, union, or enum with the name of the typedef. So
-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
-# with name TypeT. When disabled the typedef will appear as a member of a file,
-# namespace, or class. And the struct will be named TypeS. This can typically be
-# useful for C code in case the coding convention dictates that all compound
-# types are typedef'ed and only the typedef is referenced, never the tag name.
-# The default value is: NO.
-
-TYPEDEF_HIDES_STRUCT = NO
-
-# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
-# cache is used to resolve symbols given their name and scope. Since this can be
-# an expensive process and often the same symbol appears multiple times in the
-# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
-# doxygen will become slower. If the cache is too large, memory is wasted. The
-# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
-# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
-# symbols. At the end of a run doxygen will report the cache usage and suggest
-# the optimal cache size from a speed point of view.
-# Minimum value: 0, maximum value: 9, default value: 0.
-
-LOOKUP_CACHE_SIZE = 0
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
-# documentation are documented, even if no documentation was available. Private
-# class members and static file members will be hidden unless the
-# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
-# Note: This will also disable the warnings about undocumented members that are
-# normally produced when WARNINGS is set to YES.
-# The default value is: NO.
-
-EXTRACT_ALL = YES
-
-# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
-# be included in the documentation.
-# The default value is: NO.
-
-EXTRACT_PRIVATE = YES
-
-# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
-# scope will be included in the documentation.
-# The default value is: NO.
-
-EXTRACT_PACKAGE = NO
-
-# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
-# included in the documentation.
-# The default value is: NO.
-
-EXTRACT_STATIC = YES
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
-# locally in source files will be included in the documentation. If set to NO,
-# only classes defined in header files are included. Does not have any effect
-# for Java sources.
-# The default value is: YES.
-
-EXTRACT_LOCAL_CLASSES = YES
-
-# This flag is only useful for Objective-C code. If set to YES, local methods,
-# which are defined in the implementation section but not in the interface are
-# included in the documentation. If set to NO, only methods in the interface are
-# included.
-# The default value is: NO.
-
-EXTRACT_LOCAL_METHODS = NO
-
-# If this flag is set to YES, the members of anonymous namespaces will be
-# extracted and appear in the documentation as a namespace called
-# 'anonymous_namespace{file}', where file will be replaced with the base name of
-# the file that contains the anonymous namespace. By default anonymous namespace
-# are hidden.
-# The default value is: NO.
-
-EXTRACT_ANON_NSPACES = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
-# undocumented members inside documented classes or files. If set to NO these
-# members will be included in the various overviews, but no documentation
-# section is generated. This option has no effect if EXTRACT_ALL is enabled.
-# The default value is: NO.
-
-HIDE_UNDOC_MEMBERS = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy. If set
-# to NO, these classes will be included in the various overviews. This option
-# has no effect if EXTRACT_ALL is enabled.
-# The default value is: NO.
-
-HIDE_UNDOC_CLASSES = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
-# (class|struct|union) declarations. If set to NO, these declarations will be
-# included in the documentation.
-# The default value is: NO.
-
-HIDE_FRIEND_COMPOUNDS = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
-# documentation blocks found inside the body of a function. If set to NO, these
-# blocks will be appended to the function's detailed documentation block.
-# The default value is: NO.
-
-HIDE_IN_BODY_DOCS = NO
-
-# The INTERNAL_DOCS tag determines if documentation that is typed after a
-# \internal command is included. If the tag is set to NO then the documentation
-# will be excluded. Set it to YES to include the internal documentation.
-# The default value is: NO.
-
-INTERNAL_DOCS = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
-# names in lower-case letters. If set to YES, upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-# The default value is: system dependent.
-
-CASE_SENSE_NAMES = NO
-
-# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
-# their full class and namespace scopes in the documentation. If set to YES, the
-# scope will be hidden.
-# The default value is: NO.
-
-HIDE_SCOPE_NAMES = NO
-
-# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
-# append additional text to a page's title, such as Class Reference. If set to
-# YES the compound reference will be hidden.
-# The default value is: NO.
-
-HIDE_COMPOUND_REFERENCE= NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
-# the files that are included by a file in the documentation of that file.
-# The default value is: YES.
-
-SHOW_INCLUDE_FILES = YES
-
-# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
-# grouped member an include statement to the documentation, telling the reader
-# which file to include in order to use the member.
-# The default value is: NO.
-
-SHOW_GROUPED_MEMB_INC = NO
-
-# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
-# files with double quotes in the documentation rather than with sharp brackets.
-# The default value is: NO.
-
-FORCE_LOCAL_INCLUDES = NO
-
-# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
-# documentation for inline members.
-# The default value is: YES.
-
-INLINE_INFO = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
-# (detailed) documentation of file and class members alphabetically by member
-# name. If set to NO, the members will appear in declaration order.
-# The default value is: YES.
-
-SORT_MEMBER_DOCS = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
-# descriptions of file, namespace and class members alphabetically by member
-# name. If set to NO, the members will appear in declaration order. Note that
-# this will also influence the order of the classes in the class list.
-# The default value is: NO.
-
-SORT_BRIEF_DOCS = NO
-
-# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
-# (brief and detailed) documentation of class members so that constructors and
-# destructors are listed first. If set to NO the constructors will appear in the
-# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
-# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
-# member documentation.
-# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
-# detailed member documentation.
-# The default value is: NO.
-
-SORT_MEMBERS_CTORS_1ST = NO
-
-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
-# of group names into alphabetical order. If set to NO the group names will
-# appear in their defined order.
-# The default value is: NO.
-
-SORT_GROUP_NAMES = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
-# fully-qualified names, including namespaces. If set to NO, the class list will
-# be sorted only by class name, not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the alphabetical
-# list.
-# The default value is: NO.
-
-SORT_BY_SCOPE_NAME = NO
-
-# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
-# type resolution of all parameters of a function it will reject a match between
-# the prototype and the implementation of a member function even if there is
-# only one candidate or it is obvious which candidate to choose by doing a
-# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
-# accept a match between prototype and implementation in such cases.
-# The default value is: NO.
-
-STRICT_PROTO_MATCHING = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
-# list. This list is created by putting \todo commands in the documentation.
-# The default value is: YES.
-
-GENERATE_TODOLIST = NO
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
-# list. This list is created by putting \test commands in the documentation.
-# The default value is: YES.
-
-GENERATE_TESTLIST = NO
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
-# list. This list is created by putting \bug commands in the documentation.
-# The default value is: YES.
-
-GENERATE_BUGLIST = NO
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
-# the deprecated list. This list is created by putting \deprecated commands in
-# the documentation.
-# The default value is: YES.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional documentation
-# sections, marked by \if <section_label> ... \endif and \cond <section_label>
-# ... \endcond blocks.
-
-ENABLED_SECTIONS =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
-# initial value of a variable or macro / define can have for it to appear in the
-# documentation. If the initializer consists of more lines than specified here
-# it will be hidden. Use a value of 0 to hide initializers completely. The
-# appearance of the value of individual variables and macros / defines can be
-# controlled using \showinitializer or \hideinitializer command in the
-# documentation regardless of this setting.
-# Minimum value: 0, maximum value: 10000, default value: 30.
-
-MAX_INITIALIZER_LINES = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
-# the bottom of the documentation of classes and structs. If set to YES, the
-# list will mention the files that were used to generate the documentation.
-# The default value is: YES.
-
-SHOW_USED_FILES = YES
-
-# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
-# will remove the Files entry from the Quick Index and from the Folder Tree View
-# (if specified).
-# The default value is: YES.
-
-SHOW_FILES = YES
-
-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
-# page. This will remove the Namespaces entry from the Quick Index and from the
-# Folder Tree View (if specified).
-# The default value is: YES.
-
-SHOW_NAMESPACES = YES
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from
-# the version control system). Doxygen will invoke the program by executing (via
-# popen()) the command command input-file, where command is the value of the
-# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
-# by doxygen. Whatever the program writes to standard output is used as the file
-# version. For an example see the documentation.
-
-FILE_VERSION_FILTER =
-
-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
-# by doxygen. The layout file controls the global structure of the generated
-# output files in an output format independent way. To create the layout file
-# that represents doxygen's defaults, run doxygen with the -l option. You can
-# optionally specify a file name after the option, if omitted DoxygenLayout.xml
-# will be used as the name of the layout file.
-#
-# Note that if you run doxygen from a directory containing a file called
-# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
-# tag is left empty.
-
-LAYOUT_FILE =
-
-# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
-# the reference definitions. This must be a list of .bib files. The .bib
-# extension is automatically appended if omitted. This requires the bibtex tool
-# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
-# For LaTeX the style of the bibliography can be controlled using
-# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
-# search path. See also \cite for info how to create references.
-
-CITE_BIB_FILES =
-
-#---------------------------------------------------------------------------
-# Configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated to
-# standard output by doxygen. If QUIET is set to YES this implies that the
-# messages are off.
-# The default value is: NO.
-
-QUIET = YES
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
-# this implies that the warnings are on.
-#
-# Tip: Turn warnings on while writing the documentation.
-# The default value is: YES.
-
-WARNINGS = YES
-
-# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
-# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
-# will automatically be disabled.
-# The default value is: YES.
-
-WARN_IF_UNDOCUMENTED = YES
-
-# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some parameters
-# in a documented function, or documenting parameters that don't exist or using
-# markup commands wrongly.
-# The default value is: YES.
-
-WARN_IF_DOC_ERROR = YES
-
-# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
-# are documented, but have no documentation for their parameters or return
-# value. If set to NO, doxygen will only warn about wrong or incomplete
-# parameter documentation, but not about the absence of documentation.
-# The default value is: NO.
-
-WARN_NO_PARAMDOC = YES
-
-# The WARN_FORMAT tag determines the format of the warning messages that doxygen
-# can produce. The string should contain the $file, $line, and $text tags, which
-# will be replaced by the file and line number from which the warning originated
-# and the warning text. Optionally the format may contain $version, which will
-# be replaced by the version of the file (if it could be obtained via
-# FILE_VERSION_FILTER)
-# The default value is: $file:$line: $text.
-
-WARN_FORMAT = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning and error
-# messages should be written. If left blank the output is written to standard
-# error (stderr).
-
-WARN_LOGFILE =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag is used to specify the files and/or directories that contain
-# documented source files. You may enter file names like myfile.cpp or
-# directories like /usr/src/myproject. Separate the files or directories with
-# spaces.
-# Note: If this tag is empty the current directory is searched.
-
-INPUT = ./
-
-# This tag can be used to specify the character encoding of the source files
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
-# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
-# documentation (see: http://www.gnu.org/software/libiconv) for the list of
-# possible encodings.
-# The default value is: UTF-8.
-
-INPUT_ENCODING = UTF-8
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
-# *.h) to filter out the source-files in the directories. If left blank the
-# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
-# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
-# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
-# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
-# *.qsf, *.as and *.js.
-
-FILE_PATTERNS = *.h \
- *.c \
- *.txt
-
-# The RECURSIVE tag can be used to specify whether or not subdirectories should
-# be searched for input files as well.
-# The default value is: NO.
-
-RECURSIVE = YES
-
-# The EXCLUDE tag can be used to specify files and/or directories that should be
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-#
-# Note that relative paths are relative to the directory from which doxygen is
-# run.
-
-EXCLUDE = Documentation/
-
-# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
-# directories that are symbolic links (a Unix file system feature) are excluded
-# from the input.
-# The default value is: NO.
-
-EXCLUDE_SYMLINKS = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories.
-#
-# Note that the wildcards are matched against the file with absolute path, so to
-# exclude all test directories for example use the pattern */test/*
-
-EXCLUDE_PATTERNS = */uip/* \
- */FATFs/*
-
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
-# (namespaces, classes, functions, etc.) that should be excluded from the
-# output. The symbol name can be a fully qualified name, a word, or if the
-# wildcard * is used, a substring. Examples: ANamespace, AClass,
-# AClass::ANamespace, ANamespace::*Test
-#
-# Note that the wildcards are matched against the file with absolute path, so to
-# exclude all test directories use the pattern */test/*
-
-EXCLUDE_SYMBOLS = __* \
- INCLUDE_FROM_*
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or directories
-# that contain example code fragments that are included (see the \include
-# command).
-
-EXAMPLE_PATH =
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
-# *.h) to filter out the source-files in the directories. If left blank all
-# files are included.
-
-EXAMPLE_PATTERNS = *
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude commands
-# irrespective of the value of the RECURSIVE tag.
-# The default value is: NO.
-
-EXAMPLE_RECURSIVE = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or directories
-# that contain images that are to be included in the documentation (see the
-# \image command).
-
-IMAGE_PATH =
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command:
-#
-# <filter> <input-file>
-#
-# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
-# name of an input file. Doxygen will then use the output that the filter
-# program writes to standard output. If FILTER_PATTERNS is specified, this tag
-# will be ignored.
-#
-# Note that the filter must not add or remove lines; it is applied before the
-# code is scanned, but not when the output code is generated. If lines are added
-# or removed, the anchors will not be placed correctly.
-
-INPUT_FILTER =
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis. Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match. The filters are a list of the form: pattern=filter
-# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
-# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
-# patterns match the file name, INPUT_FILTER is applied.
-
-FILTER_PATTERNS =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will also be used to filter the input files that are used for
-# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
-# The default value is: NO.
-
-FILTER_SOURCE_FILES = NO
-
-# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
-# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
-# it is also possible to disable source filtering for a specific pattern using
-# *.ext= (so without naming a filter).
-# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
-
-FILTER_SOURCE_PATTERNS =
-
-# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
-# is part of the input, its contents will be placed on the main page
-# (index.html). This can be useful if you have a project on for instance GitHub
-# and want to reuse the introduction page also for the doxygen output.
-
-USE_MDFILE_AS_MAINPAGE =
-
-#---------------------------------------------------------------------------
-# Configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
-# generated. Documented entities will be cross-referenced with these sources.
-#
-# Note: To get rid of all source code in the generated output, make sure that
-# also VERBATIM_HEADERS is set to NO.
-# The default value is: NO.
-
-SOURCE_BROWSER = NO
-
-# Setting the INLINE_SOURCES tag to YES will include the body of functions,
-# classes and enums directly into the documentation.
-# The default value is: NO.
-
-INLINE_SOURCES = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
-# special comment blocks from generated source code fragments. Normal C, C++ and
-# Fortran comments will always remain visible.
-# The default value is: YES.
-
-STRIP_CODE_COMMENTS = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
-# function all documented functions referencing it will be listed.
-# The default value is: NO.
-
-REFERENCED_BY_RELATION = NO
-
-# If the REFERENCES_RELATION tag is set to YES then for each documented function
-# all documented entities called/used by that function will be listed.
-# The default value is: NO.
-
-REFERENCES_RELATION = NO
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
-# to YES then the hyperlinks from functions in REFERENCES_RELATION and
-# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
-# link to the documentation.
-# The default value is: YES.
-
-REFERENCES_LINK_SOURCE = NO
-
-# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
-# source code will show a tooltip with additional information such as prototype,
-# brief description and links to the definition and documentation. Since this
-# will make the HTML file larger and loading of large files a bit slower, you
-# can opt to disable this feature.
-# The default value is: YES.
-# This tag requires that the tag SOURCE_BROWSER is set to YES.
-
-SOURCE_TOOLTIPS = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code will
-# point to the HTML generated by the htags(1) tool instead of doxygen built-in
-# source browser. The htags tool is part of GNU's global source tagging system
-# (see http://www.gnu.org/software/global/global.html). You will need version
-# 4.8.6 or higher.
-#
-# To use it do the following:
-# - Install the latest version of global
-# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
-# - Make sure the INPUT points to the root of the source tree
-# - Run doxygen as normal
-#
-# Doxygen will invoke htags (and that will in turn invoke gtags), so these
-# tools must be available from the command line (i.e. in the search path).
-#
-# The result: instead of the source browser generated by doxygen, the links to
-# source code will now point to the output of htags.
-# The default value is: NO.
-# This tag requires that the tag SOURCE_BROWSER is set to YES.
-
-USE_HTAGS = NO
-
-# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
-# verbatim copy of the header file for each class for which an include is
-# specified. Set to NO to disable this.
-# See also: Section \class.
-# The default value is: YES.
-
-VERBATIM_HEADERS = NO
-
-# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
-# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
-# cost of reduced performance. This can be particularly helpful with template
-# rich C++ code for which doxygen's built-in parser lacks the necessary type
-# information.
-# Note: The availability of this option depends on whether or not doxygen was
-# compiled with the --with-libclang option.
-# The default value is: NO.
-
-CLANG_ASSISTED_PARSING = NO
-
-# If clang assisted parsing is enabled you can provide the compiler with command
-# line options that you would normally use when invoking the compiler. Note that
-# the include paths will already be set by doxygen for the files and directories
-# specified with INPUT and INCLUDE_PATH.
-# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
-
-CLANG_OPTIONS =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
-# compounds will be generated. Enable this if the project contains a lot of
-# classes, structs, unions or interfaces.
-# The default value is: YES.
-
-ALPHABETICAL_INDEX = YES
-
-# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
-# which the alphabetical index list will be split.
-# Minimum value: 1, maximum value: 20, default value: 5.
-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
-
-COLS_IN_ALPHA_INDEX = 5
-
-# In case all classes in a project start with a common prefix, all classes will
-# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
-# can be used to specify a prefix (or a list of prefixes) that should be ignored
-# while generating the index headers.
-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
-
-IGNORE_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
-# The default value is: YES.
-
-GENERATE_HTML = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: html.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_OUTPUT = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
-# generated HTML page (for example: .htm, .php, .asp).
-# The default value is: .html.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_FILE_EXTENSION = .html
-
-# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
-# each generated HTML page. If the tag is left blank doxygen will generate a
-# standard header.
-#
-# To get valid HTML the header file that includes any scripts and style sheets
-# that doxygen needs, which is dependent on the configuration options used (e.g.
-# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
-# default header using
-# doxygen -w html new_header.html new_footer.html new_stylesheet.css
-# YourConfigFile
-# and then modify the file new_header.html. See also section "Doxygen usage"
-# for information on how to generate the default header that doxygen normally
-# uses.
-# Note: The header is subject to change so you typically have to regenerate the
-# default header when upgrading to a newer version of doxygen. For a description
-# of the possible markers and block names see the documentation.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_HEADER =
-
-# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
-# generated HTML page. If the tag is left blank doxygen will generate a standard
-# footer. See HTML_HEADER for more information on how to generate a default
-# footer and what special commands can be used inside the footer. See also
-# section "Doxygen usage" for information on how to generate the default footer
-# that doxygen normally uses.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_FOOTER =
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
-# sheet that is used by each HTML page. It can be used to fine-tune the look of
-# the HTML output. If left blank doxygen will generate a default style sheet.
-# See also section "Doxygen usage" for information on how to generate the style
-# sheet that doxygen normally uses.
-# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
-# it is more robust and this tag (HTML_STYLESHEET) will in the future become
-# obsolete.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_STYLESHEET =
-
-# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
-# cascading style sheets that are included after the standard style sheets
-# created by doxygen. Using this option one can overrule certain style aspects.
-# This is preferred over using HTML_STYLESHEET since it does not replace the
-# standard style sheet and is therefore more robust against future updates.
-# Doxygen will copy the style sheet files to the output directory.
-# Note: The order of the extra style sheet files is of importance (e.g. the last
-# style sheet in the list overrules the setting of the previous ones in the
-# list). For an example see the documentation.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_EXTRA_STYLESHEET =
-
-# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the HTML output directory. Note
-# that these files will be copied to the base HTML output directory. Use the
-# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
-# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
-# files will be copied as-is; there are no commands or markers available.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_EXTRA_FILES =
-
-# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
-# will adjust the colors in the style sheet and background images according to
-# this color. Hue is specified as an angle on a colorwheel, see
-# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
-# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
-# purple, and 360 is red again.
-# Minimum value: 0, maximum value: 359, default value: 220.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_HUE = 220
-
-# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
-# in the HTML output. For a value of 0 the output will use grayscales only. A
-# value of 255 will produce the most vivid colors.
-# Minimum value: 0, maximum value: 255, default value: 100.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_SAT = 100
-
-# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
-# luminance component of the colors in the HTML output. Values below 100
-# gradually make the output lighter, whereas values above 100 make the output
-# darker. The value divided by 100 is the actual gamma applied, so 80 represents
-# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
-# change the gamma.
-# Minimum value: 40, maximum value: 240, default value: 80.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_GAMMA = 80
-
-# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
-# page will contain the date and time when the page was generated. Setting this
-# to NO can help when comparing the output of multiple runs.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_TIMESTAMP = NO
-
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
-# documentation will contain sections that can be hidden and shown after the
-# page has loaded.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_DYNAMIC_SECTIONS = YES
-
-# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
-# shown in the various tree structured indices initially; the user can expand
-# and collapse entries dynamically later on. Doxygen will expand the tree to
-# such a level that at most the specified number of entries are visible (unless
-# a fully collapsed tree already exceeds this amount). So setting the number of
-# entries 1 will produce a full collapsed tree by default. 0 is a special value
-# representing an infinite number of entries and will result in a full expanded
-# tree by default.
-# Minimum value: 0, maximum value: 9999, default value: 100.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_INDEX_NUM_ENTRIES = 100
-
-# If the GENERATE_DOCSET tag is set to YES, additional index files will be
-# generated that can be used as input for Apple's Xcode 3 integrated development
-# environment (see: http://developer.apple.com/tools/xcode/), introduced with
-# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
-# Makefile in the HTML output directory. Running make will produce the docset in
-# that directory and running make install will install the docset in
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
-# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
-# for more information.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_DOCSET = NO
-
-# This tag determines the name of the docset feed. A documentation feed provides
-# an umbrella under which multiple documentation sets from a single provider
-# (such as a company or product suite) can be grouped.
-# The default value is: Doxygen generated docs.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_FEEDNAME = "Doxygen generated docs"
-
-# This tag specifies a string that should uniquely identify the documentation
-# set bundle. This should be a reverse domain-name style string, e.g.
-# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_BUNDLE_ID = org.doxygen.Project
-
-# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
-# the documentation publisher. This should be a reverse domain-name style
-# string, e.g. com.mycompany.MyDocSet.documentation.
-# The default value is: org.doxygen.Publisher.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_PUBLISHER_ID = org.doxygen.Publisher
-
-# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
-# The default value is: Publisher.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_PUBLISHER_NAME = Publisher
-
-# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
-# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
-# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
-# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
-# Windows.
-#
-# The HTML Help Workshop contains a compiler that can convert all HTML output
-# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
-# files are now used as the Windows 98 help format, and will replace the old
-# Windows help format (.hlp) on all Windows platforms in the future. Compressed
-# HTML files also contain an index, a table of contents, and you can search for
-# words in the documentation. The HTML workshop also contains a viewer for
-# compressed HTML files.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_HTMLHELP = NO
-
-# The CHM_FILE tag can be used to specify the file name of the resulting .chm
-# file. You can add a path in front of the file if the result should not be
-# written to the html output directory.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-CHM_FILE =
-
-# The HHC_LOCATION tag can be used to specify the location (absolute path
-# including file name) of the HTML help compiler (hhc.exe). If non-empty,
-# doxygen will try to run the HTML help compiler on the generated index.hhp.
-# The file has to be specified with full path.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-HHC_LOCATION =
-
-# The GENERATE_CHI flag controls if a separate .chi index file is generated
-# (YES) or that it should be included in the master .chm file (NO).
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-GENERATE_CHI = NO
-
-# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
-# and project file content.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-CHM_INDEX_ENCODING =
-
-# The BINARY_TOC flag controls whether a binary table of contents is generated
-# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
-# enables the Previous and Next buttons.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-BINARY_TOC = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members to
-# the table of contents of the HTML help documentation and to the tree view.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-TOC_EXPAND = YES
-
-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
-# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
-# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
-# (.qch) of the generated HTML documentation.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_QHP = NO
-
-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
-# the file name of the resulting .qch file. The path specified is relative to
-# the HTML output folder.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QCH_FILE =
-
-# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
-# Project output. For more information please see Qt Help Project / Namespace
-# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_NAMESPACE = org.doxygen.Project
-
-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
-# Help Project output. For more information please see Qt Help Project / Virtual
-# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
-# folders).
-# The default value is: doc.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_VIRTUAL_FOLDER = doc
-
-# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
-# filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
-# filters).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_CUST_FILTER_NAME =
-
-# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
-# custom filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
-# filters).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_CUST_FILTER_ATTRS =
-
-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
-# project's filter section matches. Qt Help Project / Filter Attributes (see:
-# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_SECT_FILTER_ATTRS =
-
-# The QHG_LOCATION tag can be used to specify the location of Qt's
-# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
-# generated .qhp file.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHG_LOCATION =
-
-# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
-# generated, together with the HTML files, they form an Eclipse help plugin. To
-# install this plugin and make it available under the help contents menu in
-# Eclipse, the contents of the directory containing the HTML and XML files needs
-# to be copied into the plugins directory of eclipse. The name of the directory
-# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
-# After copying Eclipse needs to be restarted before the help appears.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_ECLIPSEHELP = NO
-
-# A unique identifier for the Eclipse help plugin. When installing the plugin
-# the directory name containing the HTML and XML files should also have this
-# name. Each documentation set should have its own identifier.
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
-
-ECLIPSE_DOC_ID = org.doxygen.Project
-
-# If you want full control over the layout of the generated HTML pages it might
-# be necessary to disable the index and replace it with your own. The
-# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
-# of each HTML page. A value of NO enables the index and the value YES disables
-# it. Since the tabs in the index contain the same information as the navigation
-# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-DISABLE_INDEX = YES
-
-# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
-# structure should be generated to display hierarchical information. If the tag
-# value is set to YES, a side panel will be generated containing a tree-like
-# index structure (just like the one that is generated for HTML Help). For this
-# to work a browser that supports JavaScript, DHTML, CSS and frames is required
-# (i.e. any modern browser). Windows users are probably better off using the
-# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
-# further fine-tune the look of the index. As an example, the default style
-# sheet generated by doxygen has an example that shows how to put an image at
-# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
-# the same information as the tab index, you could consider setting
-# DISABLE_INDEX to YES when enabling this option.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_TREEVIEW = YES
-
-# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
-# doxygen will group on one line in the generated HTML documentation.
-#
-# Note that a value of 0 will completely suppress the enum values from appearing
-# in the overview section.
-# Minimum value: 0, maximum value: 20, default value: 4.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-ENUM_VALUES_PER_LINE = 1
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
-# to set the initial width (in pixels) of the frame in which the tree is shown.
-# Minimum value: 0, maximum value: 1500, default value: 250.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-TREEVIEW_WIDTH = 250
-
-# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
-# external symbols imported via tag files in a separate window.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-EXT_LINKS_IN_WINDOW = NO
-
-# Use this tag to change the font size of LaTeX formulas included as images in
-# the HTML documentation. When you change the font size after a successful
-# doxygen run you need to manually remove any form_*.png images from the HTML
-# output directory to force them to be regenerated.
-# Minimum value: 8, maximum value: 50, default value: 10.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-FORMULA_FONTSIZE = 10
-
-# Use the FORMULA_TRANPARENT tag to determine whether or not the images
-# generated for formulas are transparent PNGs. Transparent PNGs are not
-# supported properly for IE 6.0, but are supported on all modern browsers.
-#
-# Note that when changing this option you need to delete any form_*.png files in
-# the HTML output directory before the changes have effect.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-FORMULA_TRANSPARENT = YES
-
-# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
-# http://www.mathjax.org) which uses client side Javascript for the rendering
-# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
-# installed or if you want to formulas look prettier in the HTML output. When
-# enabled you may also need to install MathJax separately and configure the path
-# to it using the MATHJAX_RELPATH option.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-USE_MATHJAX = NO
-
-# When MathJax is enabled you can set the default output format to be used for
-# the MathJax output. See the MathJax site (see:
-# http://docs.mathjax.org/en/latest/output.html) for more details.
-# Possible values are: HTML-CSS (which is slower, but has the best
-# compatibility), NativeMML (i.e. MathML) and SVG.
-# The default value is: HTML-CSS.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_FORMAT = HTML-CSS
-
-# When MathJax is enabled you need to specify the location relative to the HTML
-# output directory using the MATHJAX_RELPATH option. The destination directory
-# should contain the MathJax.js script. For instance, if the mathjax directory
-# is located at the same level as the HTML output directory, then
-# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
-# Content Delivery Network so you can quickly see the result without installing
-# MathJax. However, it is strongly recommended to install a local copy of
-# MathJax from http://www.mathjax.org before deployment.
-# The default value is: http://cdn.mathjax.org/mathjax/latest.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
-
-# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
-# extension names that should be enabled during MathJax rendering. For example
-# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_EXTENSIONS =
-
-# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
-# of code that will be used on startup of the MathJax code. See the MathJax site
-# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
-# example see the documentation.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_CODEFILE =
-
-# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
-# the HTML output. The underlying search engine uses javascript and DHTML and
-# should work on any modern browser. Note that when using HTML help
-# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
-# there is already a search function so this one should typically be disabled.
-# For large projects the javascript based search engine can be slow, then
-# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
-# search using the keyboard; to jump to the search box use <access key> + S
-# (what the <access key> is depends on the OS and browser, but it is typically
-# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
-# key> to jump into the search results window, the results can be navigated
-# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
-# the search. The filter options can be selected when the cursor is inside the
-# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
-# to select a filter and <Enter> or <escape> to activate or cancel the filter
-# option.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-SEARCHENGINE = NO
-
-# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
-# implemented using a web server instead of a web client using Javascript. There
-# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
-# setting. When disabled, doxygen will generate a PHP script for searching and
-# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
-# and searching needs to be provided by external tools. See the section
-# "External Indexing and Searching" for details.
-# The default value is: NO.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SERVER_BASED_SEARCH = NO
-
-# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
-# script for searching. Instead the search results are written to an XML file
-# which needs to be processed by an external indexer. Doxygen will invoke an
-# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
-# search results.
-#
-# Doxygen ships with an example indexer (doxyindexer) and search engine
-# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: http://xapian.org/).
-#
-# See the section "External Indexing and Searching" for details.
-# The default value is: NO.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTERNAL_SEARCH = NO
-
-# The SEARCHENGINE_URL should point to a search engine hosted by a web server
-# which will return the search results when EXTERNAL_SEARCH is enabled.
-#
-# Doxygen ships with an example indexer (doxyindexer) and search engine
-# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: http://xapian.org/). See the section "External Indexing and
-# Searching" for details.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SEARCHENGINE_URL =
-
-# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
-# search data is written to a file for indexing by an external tool. With the
-# SEARCHDATA_FILE tag the name of this file can be specified.
-# The default file is: searchdata.xml.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SEARCHDATA_FILE = searchdata.xml
-
-# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
-# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
-# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
-# projects and redirect the results back to the right project.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTERNAL_SEARCH_ID =
-
-# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
-# projects other than the one defined by this configuration file, but that are
-# all added to the same external search index. Each project needs to have a
-# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
-# to a relative location where the documentation can be found. The format is:
-# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTRA_SEARCH_MAPPINGS =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
-# The default value is: YES.
-
-GENERATE_LATEX = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: latex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_OUTPUT = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked.
-#
-# Note that when enabling USE_PDFLATEX this option is only used for generating
-# bitmaps for formulas in the HTML output, but not in the Makefile that is
-# written to the output directory.
-# The default file is: latex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_CMD_NAME = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
-# index for LaTeX.
-# The default file is: makeindex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-MAKEINDEX_CMD_NAME = makeindex
-
-# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
-# documents. This may be useful for small projects and may help to save some
-# trees in general.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-COMPACT_LATEX = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used by the
-# printer.
-# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
-# 14 inches) and executive (7.25 x 10.5 inches).
-# The default value is: a4.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-PAPER_TYPE = a4wide
-
-# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
-# that should be included in the LaTeX output. To get the times font for
-# instance you can specify
-# EXTRA_PACKAGES=times
-# If left blank no extra packages will be included.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-EXTRA_PACKAGES =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
-# generated LaTeX document. The header should contain everything until the first
-# chapter. If it is left blank doxygen will generate a standard header. See
-# section "Doxygen usage" for information on how to let doxygen write the
-# default header to a separate file.
-#
-# Note: Only use a user-defined header if you know what you are doing! The
-# following commands have a special meaning inside the header: $title,
-# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
-# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
-# string, for the replacement values of the other commands the user is referred
-# to HTML_HEADER.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_HEADER =
-
-# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
-# generated LaTeX document. The footer should contain everything after the last
-# chapter. If it is left blank doxygen will generate a standard footer. See
-# LATEX_HEADER for more information on how to generate a default footer and what
-# special commands can be used inside the footer.
-#
-# Note: Only use a user-defined footer if you know what you are doing!
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_FOOTER =
-
-# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
-# LaTeX style sheets that are included after the standard style sheets created
-# by doxygen. Using this option one can overrule certain style aspects. Doxygen
-# will copy the style sheet files to the output directory.
-# Note: The order of the extra style sheet files is of importance (e.g. the last
-# style sheet in the list overrules the setting of the previous ones in the
-# list).
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_EXTRA_STYLESHEET =
-
-# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the LATEX_OUTPUT output
-# directory. Note that the files will be copied as-is; there are no commands or
-# markers available.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_EXTRA_FILES =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
-# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
-# contain links (just like the HTML output) instead of page references. This
-# makes the output suitable for online browsing using a PDF viewer.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-PDF_HYPERLINKS = YES
-
-# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
-# the PDF file directly from the LaTeX files. Set this option to YES, to get a
-# higher quality PDF documentation.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-USE_PDFLATEX = YES
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
-# command to the generated LaTeX files. This will instruct LaTeX to keep running
-# if errors occur, instead of asking the user for help. This option is also used
-# when generating formulas in HTML.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_BATCHMODE = NO
-
-# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
-# index chapters (such as File Index, Compound Index, etc.) in the output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_HIDE_INDICES = NO
-
-# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
-# code with syntax highlighting in the LaTeX output.
-#
-# Note that which sources are shown also depends on other settings such as
-# SOURCE_BROWSER.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_SOURCE_CODE = NO
-
-# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
-# bibliography, e.g. plainnat, or ieeetr. See
-# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
-# The default value is: plain.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_BIB_STYLE = plain
-
-#---------------------------------------------------------------------------
-# Configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
-# RTF output is optimized for Word 97 and may not look too pretty with other RTF
-# readers/editors.
-# The default value is: NO.
-
-GENERATE_RTF = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: rtf.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_OUTPUT = rtf
-
-# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
-# documents. This may be useful for small projects and may help to save some
-# trees in general.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-COMPACT_RTF = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
-# contain hyperlink fields. The RTF file will contain links (just like the HTML
-# output) instead of page references. This makes the output suitable for online
-# browsing using Word or some other Word compatible readers that support those
-# fields.
-#
-# Note: WordPad (write) and others do not support links.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_HYPERLINKS = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's config
-# file, i.e. a series of assignments. You only have to provide replacements,
-# missing definitions are set to their default value.
-#
-# See also section "Doxygen usage" for information on how to generate the
-# default style sheet that doxygen normally uses.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_STYLESHEET_FILE =
-
-# Set optional variables used in the generation of an RTF document. Syntax is
-# similar to doxygen's config file. A template extensions file can be generated
-# using doxygen -e rtf extensionFile.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_EXTENSIONS_FILE =
-
-# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
-# with syntax highlighting in the RTF output.
-#
-# Note that which sources are shown also depends on other settings such as
-# SOURCE_BROWSER.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_SOURCE_CODE = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
-# classes and files.
-# The default value is: NO.
-
-GENERATE_MAN = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it. A directory man3 will be created inside the directory specified by
-# MAN_OUTPUT.
-# The default directory is: man.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_OUTPUT = man
-
-# The MAN_EXTENSION tag determines the extension that is added to the generated
-# man pages. In case the manual section does not start with a number, the number
-# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
-# optional.
-# The default value is: .3.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_EXTENSION = .3
-
-# The MAN_SUBDIR tag determines the name of the directory created within
-# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
-# MAN_EXTENSION with the initial . removed.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_SUBDIR =
-
-# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
-# will generate one additional man file for each entity documented in the real
-# man page(s). These additional files only source the real man page, but without
-# them the man command would be unable to find the correct page.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_LINKS = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
-# captures the structure of the code including all documentation.
-# The default value is: NO.
-
-GENERATE_XML = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: xml.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_OUTPUT = xml
-
-# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
-# listings (including syntax highlighting and cross-referencing information) to
-# the XML output. Note that enabling this will significantly increase the size
-# of the XML output.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_PROGRAMLISTING = YES
-
-#---------------------------------------------------------------------------
-# Configuration options related to the DOCBOOK output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
-# that can be used to generate PDF.
-# The default value is: NO.
-
-GENERATE_DOCBOOK = NO
-
-# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
-# front of it.
-# The default directory is: docbook.
-# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
-
-DOCBOOK_OUTPUT = docbook
-
-# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
-# program listings (including syntax highlighting and cross-referencing
-# information) to the DOCBOOK output. Note that enabling this will significantly
-# increase the size of the DOCBOOK output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
-
-DOCBOOK_PROGRAMLISTING = NO
-
-#---------------------------------------------------------------------------
-# Configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
-# AutoGen Definitions (see http://autogen.sf.net) file that captures the
-# structure of the code including all documentation. Note that this feature is
-# still experimental and incomplete at the moment.
-# The default value is: NO.
-
-GENERATE_AUTOGEN_DEF = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
-# file that captures the structure of the code including all documentation.
-#
-# Note that this feature is still experimental and incomplete at the moment.
-# The default value is: NO.
-
-GENERATE_PERLMOD = NO
-
-# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
-# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
-# output from the Perl module output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_LATEX = NO
-
-# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
-# formatted so it can be parsed by a human reader. This is useful if you want to
-# understand what is going on. On the other hand, if this tag is set to NO, the
-# size of the Perl module output will be much smaller and Perl will parse it
-# just the same.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_PRETTY = YES
-
-# The names of the make variables in the generated doxyrules.make file are
-# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
-# so different doxyrules.make files included by the same Makefile don't
-# overwrite each other's variables.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_MAKEVAR_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
-# C-preprocessor directives found in the sources and include files.
-# The default value is: YES.
-
-ENABLE_PREPROCESSING = YES
-
-# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
-# in the source code. If set to NO, only conditional compilation will be
-# performed. Macro expansion can be done in a controlled way by setting
-# EXPAND_ONLY_PREDEF to YES.
-# The default value is: NO.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-MACRO_EXPANSION = YES
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
-# the macro expansion is limited to the macros specified with the PREDEFINED and
-# EXPAND_AS_DEFINED tags.
-# The default value is: NO.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-EXPAND_ONLY_PREDEF = YES
-
-# If the SEARCH_INCLUDES tag is set to YES, the include files in the
-# INCLUDE_PATH will be searched if a #include is found.
-# The default value is: YES.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-SEARCH_INCLUDES = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by the
-# preprocessor.
-# This tag requires that the tag SEARCH_INCLUDES is set to YES.
-
-INCLUDE_PATH =
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will be
-# used.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-INCLUDE_FILE_PATTERNS =
-
-# The PREDEFINED tag can be used to specify one or more macro names that are
-# defined before the preprocessor is started (similar to the -D option of e.g.
-# gcc). The argument of the tag is a list of macros of the form: name or
-# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
-# is assumed. To prevent a macro definition from being undefined via #undef or
-# recursively expanded use the := operator instead of the = operator.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-PREDEFINED = __DOXYGEN__ \
- PROGMEM
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
-# tag can be used to specify a list of macro names that should be expanded. The
-# macro definition that is found in the sources will be used. Use the PREDEFINED
-# tag if you want to use a different macro definition that overrules the
-# definition found in the source code.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-EXPAND_AS_DEFINED =
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
-# remove all references to function-like macros that are alone on a line, have
-# an all uppercase name, and do not end with a semicolon. Such function macros
-# are typically used for boiler-plate code, and will confuse the parser if not
-# removed.
-# The default value is: YES.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-SKIP_FUNCTION_MACROS = YES
-
-#---------------------------------------------------------------------------
-# Configuration options related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES tag can be used to specify one or more tag files. For each tag
-# file the location of the external documentation should be added. The format of
-# a tag file without this location is as follows:
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where loc1 and loc2 can be relative or absolute paths or URLs. See the
-# section "Linking to external documentation" for more information about the use
-# of tag files.
-# Note: Each tag file must have a unique name (where the name does NOT include
-# the path). If a tag file is not located in the directory in which doxygen is
-# run, you must also specify the path to the tagfile here.
-
-TAGFILES =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
-# tag file that is based on the input files it reads. See section "Linking to
-# external documentation" for more information about the usage of tag files.
-
-GENERATE_TAGFILE =
-
-# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
-# the class index. If set to NO, only the inherited external classes will be
-# listed.
-# The default value is: NO.
-
-ALLEXTERNALS = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will be
-# listed.
-# The default value is: YES.
-
-EXTERNAL_GROUPS = YES
-
-# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
-# the related pages index. If set to NO, only the current project's pages will
-# be listed.
-# The default value is: YES.
-
-EXTERNAL_PAGES = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of 'which perl').
-# The default file (with absolute path) is: /usr/bin/perl.
-
-PERL_PATH = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
-# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
-# NO turns the diagrams off. Note that this option also works with HAVE_DOT
-# disabled, but it is recommended to install and use dot, since it yields more
-# powerful graphs.
-# The default value is: YES.
-
-CLASS_DIAGRAMS = NO
-
-# You can define message sequence charts within doxygen comments using the \msc
-# command. Doxygen will then run the mscgen tool (see:
-# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
-# documentation. The MSCGEN_PATH tag allows you to specify the directory where
-# the mscgen tool resides. If left empty the tool is assumed to be found in the
-# default search path.
-
-MSCGEN_PATH =
-
-# You can include diagrams made with dia in doxygen documentation. Doxygen will
-# then run dia to produce the diagram and insert it in the documentation. The
-# DIA_PATH tag allows you to specify the directory where the dia binary resides.
-# If left empty dia is assumed to be found in the default search path.
-
-DIA_PATH =
-
-# If set to YES the inheritance and collaboration graphs will hide inheritance
-# and usage relations if the target is undocumented or is not a class.
-# The default value is: YES.
-
-HIDE_UNDOC_RELATIONS = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz (see:
-# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
-# Bell Labs. The other options in this section have no effect if this option is
-# set to NO
-# The default value is: NO.
-
-HAVE_DOT = NO
-
-# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
-# to run in parallel. When set to 0 doxygen will base this on the number of
-# processors available in the system. You can set it explicitly to a value
-# larger than 0 to get control over the balance between CPU load and processing
-# speed.
-# Minimum value: 0, maximum value: 32, default value: 0.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_NUM_THREADS = 0
-
-# When you want a differently looking font in the dot files that doxygen
-# generates you can specify the font name using DOT_FONTNAME. You need to make
-# sure dot is able to find the font, which can be done by putting it in a
-# standard location or by setting the DOTFONTPATH environment variable or by
-# setting DOT_FONTPATH to the directory containing the font.
-# The default value is: Helvetica.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTNAME =
-
-# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
-# dot graphs.
-# Minimum value: 4, maximum value: 24, default value: 10.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTSIZE = 10
-
-# By default doxygen will tell dot to use the default font as specified with
-# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
-# the path where dot can find it using this tag.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTPATH =
-
-# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
-# each documented class showing the direct and indirect inheritance relations.
-# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CLASS_GRAPH = NO
-
-# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
-# graph for each documented class showing the direct and indirect implementation
-# dependencies (inheritance, containment, and class references variables) of the
-# class with other documented classes.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-COLLABORATION_GRAPH = NO
-
-# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
-# groups, showing the direct groups dependencies.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GROUP_GRAPHS = NO
-
-# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-UML_LOOK = NO
-
-# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
-# class node. If there are many fields or methods and many nodes the graph may
-# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
-# number of items for each type to make the size more manageable. Set this to 0
-# for no limit. Note that the threshold may be exceeded by 50% before the limit
-# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
-# but if the number exceeds 15, the total amount of fields shown is limited to
-# 10.
-# Minimum value: 0, maximum value: 100, default value: 10.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-UML_LIMIT_NUM_FIELDS = 10
-
-# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
-# collaboration graphs will show the relations between templates and their
-# instances.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-TEMPLATE_RELATIONS = NO
-
-# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
-# YES then doxygen will generate a graph for each documented file showing the
-# direct and indirect include dependencies of the file with other documented
-# files.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INCLUDE_GRAPH = NO
-
-# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
-# set to YES then doxygen will generate a graph for each documented file showing
-# the direct and indirect include dependencies of the file with other documented
-# files.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INCLUDED_BY_GRAPH = NO
-
-# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
-# dependency graph for every global function or class method.
-#
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable call graphs for selected
-# functions only using the \callgraph command.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CALL_GRAPH = NO
-
-# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
-# dependency graph for every global function or class method.
-#
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable caller graphs for selected
-# functions only using the \callergraph command.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CALLER_GRAPH = NO
-
-# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
-# hierarchy of all classes instead of a textual one.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GRAPHICAL_HIERARCHY = NO
-
-# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
-# dependencies a directory has on other directories in a graphical way. The
-# dependency relations are determined by the #include relations between the
-# files in the directories.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DIRECTORY_GRAPH = NO
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot.
-# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
-# to make the SVG files visible in IE 9+ (other browsers do not have this
-# requirement).
-# Possible values are: png, jpg, gif and svg.
-# The default value is: png.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_IMAGE_FORMAT = png
-
-# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
-# enable generation of interactive SVG images that allow zooming and panning.
-#
-# Note that this requires a modern browser other than Internet Explorer. Tested
-# and working are Firefox, Chrome, Safari, and Opera.
-# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
-# the SVG files visible. Older versions of IE do not have SVG support.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INTERACTIVE_SVG = NO
-
-# The DOT_PATH tag can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_PATH =
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the \dotfile
-# command).
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOTFILE_DIRS =
-
-# The MSCFILE_DIRS tag can be used to specify one or more directories that
-# contain msc files that are included in the documentation (see the \mscfile
-# command).
-
-MSCFILE_DIRS =
-
-# The DIAFILE_DIRS tag can be used to specify one or more directories that
-# contain dia files that are included in the documentation (see the \diafile
-# command).
-
-DIAFILE_DIRS =
-
-# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
-# path where java can find the plantuml.jar file. If left blank, it is assumed
-# PlantUML is not used or called during a preprocessing step. Doxygen will
-# generate a warning when it encounters a \startuml command in this case and
-# will not generate output for the diagram.
-
-PLANTUML_JAR_PATH =
-
-# When using plantuml, the specified paths are searched for files specified by
-# the !include statement in a plantuml block.
-
-PLANTUML_INCLUDE_PATH =
-
-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
-# that will be shown in the graph. If the number of nodes in a graph becomes
-# larger than this value, doxygen will truncate the graph, which is visualized
-# by representing a node as a red box. Note that doxygen if the number of direct
-# children of the root node in a graph is already larger than
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
-# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
-# Minimum value: 0, maximum value: 10000, default value: 50.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_GRAPH_MAX_NODES = 15
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
-# generated by dot. A depth value of 3 means that only nodes reachable from the
-# root by following a path via at most 3 edges will be shown. Nodes that lay
-# further from the root node will be omitted. Note that setting this option to 1
-# or 2 may greatly reduce the computation time needed for large code bases. Also
-# note that the size of a graph can be further restricted by
-# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
-# Minimum value: 0, maximum value: 1000, default value: 0.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-MAX_DOT_GRAPH_DEPTH = 2
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, because dot on Windows does not seem
-# to support this out of the box.
-#
-# Warning: Depending on the platform used, enabling this option may lead to
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
-# read).
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_TRANSPARENT = YES
-
-# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10) support
-# this, this feature is disabled by default.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_MULTI_TARGETS = NO
-
-# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
-# explaining the meaning of the various boxes and arrows in the dot generated
-# graphs.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GENERATE_LEGEND = YES
-
-# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
-# files that are used to generate the various graphs.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_CLEANUP = YES
diff --git a/lib/lufa/Projects/Webserver/makefile b/lib/lufa/Projects/Webserver/makefile
deleted file mode 100644
index 852d011bc..000000000
--- a/lib/lufa/Projects/Webserver/makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# LUFA Library
-# Copyright (C) Dean Camera, 2017.
-#
-# dean [at] fourwalledcubicle [dot] com
-# www.lufa-lib.org
-#
-# --------------------------------------
-# LUFA Project Makefile.
-# --------------------------------------
-
-# Run "make help" for target help.
-
-MCU = at90usb1287
-ARCH = AVR8
-BOARD = USBKEY
-F_CPU = 8000000
-F_USB = $(F_CPU)
-OPTIMIZATION = s
-TARGET = Webserver
-SRC = $(TARGET).c Descriptors.c USBDeviceMode.c USBHostMode.c Lib/SCSI.c Lib/DataflashManager.c \
- Lib/uIPManagement.c Lib/DHCPCommon.c Lib/DHCPClientApp.c Lib/DHCPServerApp.c Lib/HTTPServerApp.c \
- Lib/TELNETServerApp.c Lib/uip/uip.c Lib/uip/uip_arp.c Lib/uip/timer.c Lib/uip/clock.c \
- Lib/uip/uip-split.c Lib/FATFs/diskio.c Lib/FATFs/ff.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
-LUFA_PATH = ../../LUFA
-CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/ -ILib/uip/ -ILib/FATFs/
-LD_FLAGS =
-
-# Default target
-all:
-
-# Include LUFA-specific DMBS extension modules
-DMBS_LUFA_PATH ?= $(LUFA_PATH)/Build/LUFA
-include $(DMBS_LUFA_PATH)/lufa-sources.mk
-include $(DMBS_LUFA_PATH)/lufa-gcc.mk
-
-# Include common DMBS build system modules
-DMBS_PATH ?= $(LUFA_PATH)/Build/DMBS/DMBS
-include $(DMBS_PATH)/core.mk
-include $(DMBS_PATH)/cppcheck.mk
-include $(DMBS_PATH)/doxygen.mk
-include $(DMBS_PATH)/dfu.mk
-include $(DMBS_PATH)/gcc.mk
-include $(DMBS_PATH)/hid.mk
-include $(DMBS_PATH)/avrdude.mk
-include $(DMBS_PATH)/atprogram.mk