aboutsummaryrefslogtreecommitdiffstats
path: root/Projects
diff options
context:
space:
mode:
Diffstat (limited to 'Projects')
-rw-r--r--Projects/Webserver/Descriptors.c115
-rw-r--r--Projects/Webserver/Descriptors.h32
-rw-r--r--Projects/Webserver/LUFA Webserver RNDIS.inf52
-rw-r--r--Projects/Webserver/Lib/DHCPClientApp.c87
-rw-r--r--Projects/Webserver/Lib/DHCPClientApp.h111
-rw-r--r--Projects/Webserver/Lib/DHCPCommon.c102
-rw-r--r--Projects/Webserver/Lib/DHCPCommon.h157
-rw-r--r--Projects/Webserver/Lib/DHCPServerApp.c237
-rw-r--r--Projects/Webserver/Lib/DHCPServerApp.h62
-rw-r--r--Projects/Webserver/Lib/HTTPServerApp.c6
-rw-r--r--Projects/Webserver/Lib/uIPManagement.c96
-rw-r--r--Projects/Webserver/Lib/uIPManagement.h11
-rw-r--r--Projects/Webserver/Lib/uip/uip-split.c15
-rw-r--r--Projects/Webserver/Lib/uip/uip.c10
-rw-r--r--Projects/Webserver/USBDeviceMode.c40
-rw-r--r--Projects/Webserver/USBDeviceMode.h4
-rw-r--r--Projects/Webserver/USBHostMode.c12
-rw-r--r--Projects/Webserver/USBHostMode.h2
-rw-r--r--Projects/Webserver/Webserver.aps2
-rw-r--r--Projects/Webserver/Webserver.txt13
-rw-r--r--Projects/Webserver/makefile13
21 files changed, 932 insertions, 247 deletions
diff --git a/Projects/Webserver/Descriptors.c b/Projects/Webserver/Descriptors.c
index ba20f070a..63c43d763 100644
--- a/Projects/Webserver/Descriptors.c
+++ b/Projects/Webserver/Descriptors.c
@@ -59,15 +59,15 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(01.10),
- .Class = USB_CSCP_NoDeviceClass,
- .SubClass = USB_CSCP_NoDeviceSubclass,
- .Protocol = USB_CSCP_NoDeviceProtocol,
+ .Class = USB_CSCP_IADDeviceClass,
+ .SubClass = USB_CSCP_IADDeviceSubclass,
+ .Protocol = USB_CSCP_IADDeviceProtocol,
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB,
- .ProductID = 0x2045,
- .ReleaseNumber = VERSION_BCD(00.01),
+ .ProductID = 0x2069,
+ .ReleaseNumber = VERSION_BCD(00.10),
.ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02,
@@ -88,7 +88,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
- .TotalInterfaces = 1,
+ .TotalInterfaces = 3,
.ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR,
@@ -98,13 +98,114 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
},
- .MS_Interface =
+ .CDC_IAD =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
+
+ .FirstInterfaceIndex = 0,
+ .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 = 0,
.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(01.10),
+ },
+
+ .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 = 0,
+ .SlaveInterfaceNumber = 1,
+ },
+
+ .CDC_NotificationEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_NOTIFICATION_EPNUM),
+ .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 = 1,
+ .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 = (ENDPOINT_DESCRIPTOR_DIR_OUT | CDC_RX_EPNUM),
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_TXRX_EPSIZE,
+ .PollingIntervalMS = 0x01
+ },
+
+ .RNDIS_DataInEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_TX_EPNUM),
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_TXRX_EPSIZE,
+ .PollingIntervalMS = 0x01
+ },
+
+ .MS_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 2,
+ .AlternateSetting = 0,
+
.TotalEndpoints = 2,
.Class = MS_CSCP_MassStorageClass,
diff --git a/Projects/Webserver/Descriptors.h b/Projects/Webserver/Descriptors.h
index 38cb23131..e285dfba5 100644
--- a/Projects/Webserver/Descriptors.h
+++ b/Projects/Webserver/Descriptors.h
@@ -51,6 +51,21 @@
/** Size in bytes of the Mass Storage data endpoints. */
#define MASS_STORAGE_IO_EPSIZE 64
+ /** Endpoint number of the CDC device-to-host notification IN endpoint. */
+ #define CDC_NOTIFICATION_EPNUM 5
+
+ /** Endpoint number of the CDC device-to-host data IN endpoint. */
+ #define CDC_TX_EPNUM 1
+
+ /** Endpoint number of the CDC host-to-device data OUT endpoint. */
+ #define CDC_RX_EPNUM 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
@@ -58,10 +73,19 @@
*/
typedef struct
{
- USB_Descriptor_Configuration_Header_t Config;
- USB_Descriptor_Interface_t MS_Interface;
- USB_Descriptor_Endpoint_t MS_DataInEndpoint;
- USB_Descriptor_Endpoint_t MS_DataOutEndpoint;
+ USB_Descriptor_Configuration_Header_t Config;
+ 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;
+ USB_Descriptor_Interface_t CDC_DCI_Interface;
+ USB_Descriptor_Endpoint_t RNDIS_DataOutEndpoint;
+ USB_Descriptor_Endpoint_t RNDIS_DataInEndpoint;
+ USB_Descriptor_Interface_t MS_Interface;
+ USB_Descriptor_Endpoint_t MS_DataInEndpoint;
+ USB_Descriptor_Endpoint_t MS_DataOutEndpoint;
} USB_Descriptor_Configuration_t;
/* Function Prototypes: */
diff --git a/Projects/Webserver/LUFA Webserver RNDIS.inf b/Projects/Webserver/LUFA Webserver RNDIS.inf
new file mode 100644
index 000000000..6ed9cc74d
--- /dev/null
+++ b/Projects/Webserver/LUFA Webserver RNDIS.inf
@@ -0,0 +1,52 @@
+; Windows LUFA RNDIS Setup File
+; Copyright (c) 2000 Microsoft Corporation
+
+[Version]
+Signature = "$Windows NT$"
+Class = Net
+ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318}
+Provider = %COMPANY%
+DriverVer = 06/21/2006,6.0.6000.16384
+;CatalogFile = device.cat
+
+[Manufacturer]
+%COMPANY% = RndisDevices,NTx86,NTamd64,NTia64
+
+; Decoration for x86 architecture
+[RndisDevices.NTx86]
+%RNDISDEV% = RNDIS.NT.5.1, USB\VID_03EB&PID_2069&MI_00
+
+; Decoration for x64 architecture
+[RndisDevices.NTamd64]
+%RNDISDEV% = RNDIS.NT.5.1, USB\VID_03EB&PID_2069&MI_00
+
+; Decoration for ia64 architecture
+[RndisDevices.NTia64]
+%RNDISDEV% = RNDIS.NT.5.1, USB\VID_03EB&PID_2069&MI_00
+
+;@@@ This is the common setting for setup
+[ControlFlags]
+ExcludeFromSelect=*
+
+; DDInstall section
+; References the in-build Netrndis.inf
+[RNDIS.NT.5.1]
+Characteristics = 0x84 ; NCF_PHYSICAL + NCF_HAS_UI
+BusType = 15
+; NEVER REMOVE THE FOLLOWING REFERENCE FOR NETRNDIS.INF
+include = netrndis.inf
+needs = Usb_Rndis.ndi
+AddReg = Rndis_AddReg_Vista
+
+; DDInstal.Services section
+[RNDIS.NT.5.1.Services]
+include = netrndis.inf
+needs = Usb_Rndis.ndi.Services
+
+; No sys copyfiles - the sys files are already in-build
+; (part of the operating system).
+
+; Modify these strings for your device as needed.
+[Strings]
+COMPANY="LUFA Library"
+RNDISDEV="LUFA USB RNDIS Webserver" \ No newline at end of file
diff --git a/Projects/Webserver/Lib/DHCPClientApp.c b/Projects/Webserver/Lib/DHCPClientApp.c
index 4afe6bfe2..6a2f02938 100644
--- a/Projects/Webserver/Lib/DHCPClientApp.c
+++ b/Projects/Webserver/Lib/DHCPClientApp.c
@@ -43,13 +43,13 @@
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(DHCPC_SERVER_PORT));
+ 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(DHCPC_CLIENT_PORT));
+ uip_udp_bind(Connection, HTONS(DHCP_CLIENT_PORT));
/* Set the initial client state */
AppState->DHCPClient.CurrentState = DHCP_STATE_SendDiscover;
@@ -80,8 +80,8 @@ void DHCPClientApp_Callback(void)
/* Add the required DHCP options list to the packet */
uint8_t RequiredOptionList[] = {DHCP_OPTION_SUBNET_MASK, DHCP_OPTION_ROUTER, DHCP_OPTION_DNS_SERVER};
- AppDataSize += DHCPClientApp_SetOption(AppData->Options, DHCP_OPTION_REQ_LIST, sizeof(RequiredOptionList),
- RequiredOptionList);
+ AppDataSize += DHCPCommon_SetOption(AppData->Options, DHCP_OPTION_REQ_LIST, sizeof(RequiredOptionList),
+ RequiredOptionList);
/* Send the DHCP DISCOVER packet */
uip_udp_send(AppDataSize);
@@ -103,14 +103,14 @@ void DHCPClientApp_Callback(void)
uint8_t OfferResponse_MessageType;
if ((AppData->TransactionID == DHCP_TRANSACTION_ID) &&
- DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &OfferResponse_MessageType) &&
+ 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));
- DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_SUBNET_MASK, &AppState->DHCPClient.DHCPOffer_Data.Netmask);
- DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_ROUTER, &AppState->DHCPClient.DHCPOffer_Data.GatewayIP);
- DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_SERVER_ID, &AppState->DHCPClient.DHCPOffer_Data.ServerIP);
+ 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;
@@ -122,12 +122,12 @@ void DHCPClientApp_Callback(void)
AppDataSize += DHCPClientApp_FillDHCPHeader(AppData, DHCP_REQUEST, AppState);
/* Add the DHCP REQUESTED IP ADDRESS option to the packet */
- AppDataSize += DHCPClientApp_SetOption(AppData->Options, DHCP_OPTION_REQ_IPADDR, sizeof(uip_ipaddr_t),
- &AppState->DHCPClient.DHCPOffer_Data.AllocatedIP);
+ 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 += DHCPClientApp_SetOption(AppData->Options, DHCP_OPTION_SERVER_ID, sizeof(uip_ipaddr_t),
- &AppState->DHCPClient.DHCPOffer_Data.ServerIP);
+ 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);
@@ -149,7 +149,7 @@ void DHCPClientApp_Callback(void)
uint8_t RequestResponse_MessageType;
if ((AppData->TransactionID == DHCP_TRANSACTION_ID) &&
- DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &RequestResponse_MessageType) &&
+ DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &RequestResponse_MessageType) &&
(RequestResponse_MessageType == DHCP_ACK))
{
/* Set the new network parameters from the DHCP server */
@@ -207,66 +207,5 @@ static uint16_t DHCPClientApp_FillDHCPHeader(DHCP_Header_t* const DHCPHeader,
return (sizeof(DHCP_Header_t) + 4);
}
-/** 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
- */
-static uint8_t DHCPClientApp_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 true if the option was found in the DHCP packet's options list, false otherwise
- */
-static bool DHCPClientApp_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/Projects/Webserver/Lib/DHCPClientApp.h b/Projects/Webserver/Lib/DHCPClientApp.h
index cb4014fbc..1f3104c6f 100644
--- a/Projects/Webserver/Lib/DHCPClientApp.h
+++ b/Projects/Webserver/Lib/DHCPClientApp.h
@@ -42,111 +42,11 @@
#include <uip.h>
#include "../Webserver.h"
-
- /* Macros: */
- /** UDP listen port for a BOOTP server. */
- #define DHCPC_SERVER_PORT 67
-
- /** UDP listen port for a BOOTP client. */
- #define DHCPC_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;
+ #include "DHCPCommon.h"
/* Enums: */
/** States for each DHCP connection to a DHCP client. */
- enum DHCP_States_t
+ 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 */
@@ -163,13 +63,6 @@
static uint16_t DHCPClientApp_FillDHCPHeader(DHCP_Header_t* const DHCPHeader,
const uint8_t DHCPMessageType,
uip_udp_appstate_t* const AppState);
- static uint8_t DHCPClientApp_SetOption(uint8_t* DHCPOptionList,
- const uint8_t Option,
- const uint8_t DataLen,
- void* const OptionData);
- static bool DHCPClientApp_GetOption(const uint8_t* DHCPOptionList,
- const uint8_t Option,
- void* const Destination);
#endif
#endif
diff --git a/Projects/Webserver/Lib/DHCPCommon.c b/Projects/Webserver/Lib/DHCPCommon.c
new file mode 100644
index 000000000..dac5fa797
--- /dev/null
+++ b/Projects/Webserver/Lib/DHCPCommon.c
@@ -0,0 +1,102 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2011.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2011 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 disclaim 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.
+*/
+
+#if defined(ENABLE_DHCP_CLIENT) || defined(ENABLE_DHCP_SERVER) || defined(__DOXYGEN__)
+
+/** \file
+ *
+ * Common DHCP routines to manage DHCP packet data.
+ */
+
+#include "DHCPCommon.h"
+
+/** 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 true if the option was found in the DHCP packet's options list, 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/Projects/Webserver/Lib/DHCPCommon.h b/Projects/Webserver/Lib/DHCPCommon.h
new file mode 100644
index 000000000..652db683c
--- /dev/null
+++ b/Projects/Webserver/Lib/DHCPCommon.h
@@ -0,0 +1,157 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2011.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2011 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 disclaim 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 <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/Projects/Webserver/Lib/DHCPServerApp.c b/Projects/Webserver/Lib/DHCPServerApp.c
new file mode 100644
index 000000000..84c57d0a2
--- /dev/null
+++ b/Projects/Webserver/Lib/DHCPServerApp.c
@@ -0,0 +1,237 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2011.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2011 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 disclaim 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.
+*/
+
+#if defined(ENABLE_DHCP_SERVER) || defined(__DOXYGEN__)
+
+/** \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"
+
+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;
+
+ uint8_t DHCPMessageType;
+ if (!(DHCPCommon_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &DHCPMessageType)))
+ return;
+
+ uip_ipaddr_t Netmask, GatewayIPAddress;
+ struct uip_eth_addr RemoteMACAddress;
+ uint32_t TransactionID;
+
+ memcpy(&RemoteMACAddress, &AppData->ClientHardwareAddress, sizeof(struct uip_eth_addr));
+ uip_getnetmask(&Netmask);
+ uip_getdraddr(&GatewayIPAddress);
+ TransactionID = AppData->TransactionID;
+
+ switch (DHCPMessageType)
+ {
+ case DHCP_DISCOVER:
+ AppDataSize += DHCPServerApp_FillDHCPHeader(AppData, DHCP_OFFER, &RemoteMACAddress, TransactionID);
+
+ 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:
+ if (!(DHCPServerApp_CheckIfIPLeased(&AppData->YourIP)))
+ {
+ AppDataSize += DHCPServerApp_FillDHCPHeader(AppData, DHCP_ACK, &RemoteMACAddress, TransactionID);
+
+ 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);
+
+ DHCPServerApp_LeaseIP(&AppData->YourIP);
+ }
+ else
+ {
+ AppDataSize += DHCPServerApp_FillDHCPHeader(AppData, DHCP_NAK, &RemoteMACAddress, 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] 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,
+ struct uip_eth_addr* ClientHardwareAddress,
+ 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));
+ if (uip_ipaddr_cmp(&DHCPHeader->YourIP, &uip_all_zeroes_addr))
+ DHCPServerApp_GetUnleasedIP(&DHCPHeader->YourIP);
+ 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 true if the IP has already been leased to a client, false otherwise.
+ */
+static bool DHCPServerApp_CheckIfIPLeased(uip_ipaddr_t* IPAddress)
+{
+ uint8_t Byte = (IPAddress->u8[3] / 8);
+ uint8_t Mask = (1 << (IPAddress->u8[3] % 8));
+
+ if (!(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* NewIPAddress)
+{
+ uip_ipaddr_copy(NewIPAddress, &uip_hostaddr);
+
+ for (uint8_t IP = 1; IP < 254; IP++)
+ {
+ NewIPAddress->u8[3] = IP;
+
+ 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(uip_ipaddr_t* IPAddress)
+{
+ uint8_t Byte = (IPAddress->u8[3] / 8);
+ uint8_t Mask = (1 << (IPAddress->u8[3] % 8));
+
+ 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(uip_ipaddr_t* IPAddress)
+{
+ uint8_t Byte = (IPAddress->u8[3] / 8);
+ uint8_t Mask = (1 << (IPAddress->u8[3] % 8));
+
+ LeasedIPs[Byte] &= ~Mask;
+}
+#endif
+
diff --git a/Projects/Webserver/Lib/DHCPServerApp.h b/Projects/Webserver/Lib/DHCPServerApp.h
new file mode 100644
index 000000000..e70869588
--- /dev/null
+++ b/Projects/Webserver/Lib/DHCPServerApp.h
@@ -0,0 +1,62 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2011.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2011 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 disclaim 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 "../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,
+ struct uip_eth_addr* ClientHardwareAddress,
+ uint32_t TransactionID);
+ static bool DHCPServerApp_CheckIfIPLeased(uip_ipaddr_t* IPAddress);
+ static void DHCPServerApp_GetUnleasedIP(uip_ipaddr_t* NewIPAddress);
+ static void DHCPServerApp_LeaseIP(uip_ipaddr_t* IPAddress);
+ static void DHCPServerApp_UnleaseIP(uip_ipaddr_t* IPAddress);
+ #endif
+#endif
+
diff --git a/Projects/Webserver/Lib/HTTPServerApp.c b/Projects/Webserver/Lib/HTTPServerApp.c
index 8548045df..6822b270d 100644
--- a/Projects/Webserver/Lib/HTTPServerApp.c
+++ b/Projects/Webserver/Lib/HTTPServerApp.c
@@ -181,7 +181,7 @@ static void HTTPServerApp_OpenRequestedFile(void)
}
/* Copy over the requested filename */
- strncpy(AppState->HTTPServer.FileName, &RequestedFileName[1], (sizeof(AppState->HTTPServer.FileName) - 1));
+ strncpy(AppState->HTTPServer.FileName, &RequestedFileName[1], sizeof(AppState->HTTPServer.FileName));
/* Ensure filename is null-terminated */
AppState->HTTPServer.FileName[sizeof(AppState->HTTPServer.FileName) - 1] = 0x00;
@@ -190,11 +190,11 @@ static void HTTPServerApp_OpenRequestedFile(void)
uint8_t FileNameLen = strlen(AppState->HTTPServer.FileName);
/* If the URI is a directory, append the default filename */
- if (AppState->HTTPServer.FileName[FileNameLen - 1] == '/')
+ if ((AppState->HTTPServer.FileName[FileNameLen - 1] == '/') || !(FileNameLen))
{
strncpy_P(&AppState->HTTPServer.FileName[FileNameLen], DefaultDirFileName,
(sizeof(AppState->HTTPServer.FileName) - FileNameLen));
-
+
/* Ensure altered filename is still null-terminated */
AppState->HTTPServer.FileName[sizeof(AppState->HTTPServer.FileName) - 1] = 0x00;
}
diff --git a/Projects/Webserver/Lib/uIPManagement.c b/Projects/Webserver/Lib/uIPManagement.c
index a99e8be93..59045c06a 100644
--- a/Projects/Webserver/Lib/uIPManagement.c
+++ b/Projects/Webserver/Lib/uIPManagement.c
@@ -61,22 +61,49 @@ void uIPManagement_Init(void)
/* uIP Stack Initialization */
uip_init();
uip_arp_init();
- uip_setethaddr(MACAddress);
/* DHCP/Server IP Settings Initialization */
- #if defined(ENABLE_DHCP_CLIENT)
- HaveIPConfiguration = false;
- DHCPClientApp_Init();
- #else
- HaveIPConfiguration = true;
- 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
+ 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
+
+ HaveIPConfiguration = true;
+ 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)
+ HaveIPConfiguration = false;
+ DHCPClientApp_Init();
+ #else
+ HaveIPConfiguration = true;
+ 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();
@@ -92,7 +119,8 @@ void uIPManagement_Init(void)
*/
void uIPManagement_ManageNetwork(void)
{
- if ((USB_CurrentMode == USB_MODE_Host) && (USB_HostState == HOST_STATE_Configured))
+ 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();
@@ -126,24 +154,46 @@ void uIPManagement_UDPCallback(void)
/* Call the correct UDP application based on the port number the connection is listening on */
switch (uip_udp_conn->lport)
{
- case HTONS(DHCPC_CLIENT_PORT):
+ #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)
{
- /* If no packet received, exit processing routine */
- if (!(RNDIS_Host_IsPacketReceived(&Ethernet_RNDIS_Interface)))
- return;
-
- LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
+ /* Determine which USB mode the system is currently initialised 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_Host_ReadPacket(&Ethernet_RNDIS_Interface, uip_buf, &uip_len);
+ /* 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)
{
diff --git a/Projects/Webserver/Lib/uIPManagement.h b/Projects/Webserver/Lib/uIPManagement.h
index 7409eab90..c42e13225 100644
--- a/Projects/Webserver/Lib/uIPManagement.h
+++ b/Projects/Webserver/Lib/uIPManagement.h
@@ -45,12 +45,13 @@
#include <timer.h>
#include "Lib/DHCPClientApp.h"
+ #include "Lib/DHCPServerApp.h"
#include "Lib/HTTPServerApp.h"
#include "Lib/TELNETServerApp.h"
/* Macros: */
/** IP address that the webserver should use once connected to a RNDIS device (when DHCP is disabled). */
- #define DEVICE_IP_ADDRESS (uint8_t[]){192, 168, 1, 10}
+ #define DEVICE_IP_ADDRESS (uint8_t[]){10, 0, 0, 2}
/** Netmask that the webserver should once connected to a RNDIS device (when DHCP is disabled). */
#define DEVICE_NETMASK (uint8_t[]){255, 255, 255, 0}
@@ -58,7 +59,13 @@
/** IP address of the default gateway the webserver should use when routing outside the local subnet
* (when DHCP is disabled).
*/
- #define DEVICE_GATEWAY (uint8_t[]){192, 168, 1, 1}
+ #define DEVICE_GATEWAY (uint8_t[]){10, 0, 0, 1}
+
+ /** Ethernet MAC address of the virtual webserver. When in device RNDIS mode, the virtual webserver requires
+ * a unique MAC address that it can use when sending packets to the RNDIS adapter, which contains a seperate
+ * MAC address as set in the RNDIS class driver configuration structure.
+ */
+ #define SERVER_MAC_ADDRESS (uint8_t[]){1, 0, 1, 0, 1, 0}
/* External Variables: */
extern struct uip_eth_addr MACAddress;
diff --git a/Projects/Webserver/Lib/uip/uip-split.c b/Projects/Webserver/Lib/uip/uip-split.c
index 87dbd7e1f..5222a05b6 100644
--- a/Projects/Webserver/Lib/uip/uip-split.c
+++ b/Projects/Webserver/Lib/uip/uip-split.c
@@ -83,7 +83,10 @@ uip_split_output(void)
#if UIP_CONF_IPV6
tcpip_ipv6_output();
#else
- RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, uip_buf, uip_len);
+ 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
@@ -124,7 +127,10 @@ uip_split_output(void)
#if UIP_CONF_IPV6
tcpip_ipv6_output();
#else
- RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, uip_buf, uip_len);
+ 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;
}
@@ -134,7 +140,10 @@ uip_split_output(void)
#if UIP_CONF_IPV6
tcpip_ipv6_output();
#else
- RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, uip_buf, uip_len);
+ 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/Projects/Webserver/Lib/uip/uip.c b/Projects/Webserver/Lib/uip/uip.c
index afa19f750..94171adad 100644
--- a/Projects/Webserver/Lib/uip/uip.c
+++ b/Projects/Webserver/Lib/uip/uip.c
@@ -904,10 +904,12 @@ uip_process(u8_t flag)
#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)
- /*&&
- uip_ipchksum() == 0xffff*/) {
- goto udp_input;
+ 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 */
diff --git a/Projects/Webserver/USBDeviceMode.c b/Projects/Webserver/USBDeviceMode.c
index 44bae33d2..f5856ebbd 100644
--- a/Projects/Webserver/USBDeviceMode.c
+++ b/Projects/Webserver/USBDeviceMode.c
@@ -36,6 +36,33 @@
#include "USBDeviceMode.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_Device_t Ethernet_RNDIS_Interface_Device =
+ {
+ .Config =
+ {
+ .ControlInterfaceNumber = 0,
+
+ .DataINEndpointNumber = CDC_TX_EPNUM,
+ .DataINEndpointSize = CDC_TXRX_EPSIZE,
+ .DataINEndpointDoubleBank = false,
+
+ .DataOUTEndpointNumber = CDC_RX_EPNUM,
+ .DataOUTEndpointSize = CDC_TXRX_EPSIZE,
+ .DataOUTEndpointDoubleBank = false,
+
+ .NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
+ .NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
+ .NotificationEndpointDoubleBank = false,
+
+ .AdapterVendorDescription = "LUFA RNDIS Adapter",
+ .AdapterMACAddress = {{0x02, 0x00, 0x02, 0x00, 0x02, 0x00}},
+ },
+ };
+
/** 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.
@@ -44,15 +71,15 @@ USB_ClassInfo_MS_Device_t Disk_MS_Interface =
{
.Config =
{
- .InterfaceNumber = 0,
+ .InterfaceNumber = 2,
.DataINEndpointNumber = MASS_STORAGE_IN_EPNUM,
.DataINEndpointSize = MASS_STORAGE_IO_EPSIZE,
- .DataINEndpointDoubleBank = true,
+ .DataINEndpointDoubleBank = false,
.DataOUTEndpointNumber = MASS_STORAGE_OUT_EPNUM,
.DataOUTEndpointSize = MASS_STORAGE_IO_EPSIZE,
- .DataOUTEndpointDoubleBank = true,
+ .DataOUTEndpointDoubleBank = false,
.TotalLUNs = 1,
},
@@ -67,6 +94,9 @@ 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);
}
@@ -74,6 +104,8 @@ void USBDeviceMode_USBTask(void)
void EVENT_USB_Device_Connect(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+
+ uIPManagement_Init();
}
/** Event handler for the library USB Disconnection event. */
@@ -87,6 +119,7 @@ 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);
@@ -95,6 +128,7 @@ void EVENT_USB_Device_ConfigurationChanged(void)
/** 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);
}
diff --git a/Projects/Webserver/USBDeviceMode.h b/Projects/Webserver/USBDeviceMode.h
index 910dee0e7..02d522d65 100644
--- a/Projects/Webserver/USBDeviceMode.h
+++ b/Projects/Webserver/USBDeviceMode.h
@@ -40,9 +40,13 @@
#include <LUFA/Drivers/USB/USB.h>
#include "Webserver.h"
+ #include "Lib/uIPManagement.h"
#include "Descriptors.h"
#include "Lib/SCSI.h"
+ /* External Variables: */
+ extern USB_ClassInfo_RNDIS_Device_t Ethernet_RNDIS_Interface_Device;
+
/* Function Prototypes: */
void USBDeviceMode_USBTask(void);
diff --git a/Projects/Webserver/USBHostMode.c b/Projects/Webserver/USBHostMode.c
index 941ebba8d..1fcec3491 100644
--- a/Projects/Webserver/USBHostMode.c
+++ b/Projects/Webserver/USBHostMode.c
@@ -40,7 +40,7 @@
* 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 =
+USB_ClassInfo_RNDIS_Host_t Ethernet_RNDIS_Interface_Host =
{
.Config =
{
@@ -82,7 +82,7 @@ void USBHostMode_USBTask(void)
break;
}
- if (RNDIS_Host_ConfigurePipes(&Ethernet_RNDIS_Interface,
+ if (RNDIS_Host_ConfigurePipes(&Ethernet_RNDIS_Interface_Host,
ConfigDescriptorSize, ConfigDescriptorData) != RNDIS_ENUMERROR_NoError)
{
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
@@ -97,7 +97,7 @@ void USBHostMode_USBTask(void)
break;
}
- if (RNDIS_Host_InitializeDevice(&Ethernet_RNDIS_Interface) != HOST_SENDCONTROL_Successful)
+ if (RNDIS_Host_InitializeDevice(&Ethernet_RNDIS_Interface_Host) != HOST_SENDCONTROL_Successful)
{
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
@@ -105,7 +105,7 @@ void USBHostMode_USBTask(void)
}
uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST);
- if (RNDIS_Host_SetRNDISProperty(&Ethernet_RNDIS_Interface, OID_GEN_CURRENT_PACKET_FILTER,
+ if (RNDIS_Host_SetRNDISProperty(&Ethernet_RNDIS_Interface_Host, OID_GEN_CURRENT_PACKET_FILTER,
&PacketFilter, sizeof(PacketFilter)) != HOST_SENDCONTROL_Successful)
{
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
@@ -113,7 +113,7 @@ void USBHostMode_USBTask(void)
break;
}
- if (RNDIS_Host_QueryRNDISProperty(&Ethernet_RNDIS_Interface, OID_802_3_CURRENT_ADDRESS,
+ if (RNDIS_Host_QueryRNDISProperty(&Ethernet_RNDIS_Interface_Host, OID_802_3_CURRENT_ADDRESS,
&MACAddress, sizeof(MACAddress)) != HOST_SENDCONTROL_Successful)
{
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
@@ -133,7 +133,7 @@ void USBHostMode_USBTask(void)
break;
}
- RNDIS_Host_USBTask(&Ethernet_RNDIS_Interface);
+ 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
diff --git a/Projects/Webserver/USBHostMode.h b/Projects/Webserver/USBHostMode.h
index fa914013f..bb7107073 100644
--- a/Projects/Webserver/USBHostMode.h
+++ b/Projects/Webserver/USBHostMode.h
@@ -43,7 +43,7 @@
#include "Lib/uIPManagement.h"
/* External Variables: */
- extern USB_ClassInfo_RNDIS_Host_t Ethernet_RNDIS_Interface;
+ extern USB_ClassInfo_RNDIS_Host_t Ethernet_RNDIS_Interface_Host;
/* Function Prototypes: */
void USBHostMode_USBTask(void);
diff --git a/Projects/Webserver/Webserver.aps b/Projects/Webserver/Webserver.aps
index aaf3114f9..4c47287d0 100644
--- a/Projects/Webserver/Webserver.aps
+++ b/Projects/Webserver/Webserver.aps
@@ -1 +1 @@
-<AVRStudio><MANAGEMENT><ProjectName>Webserver</ProjectName><Created>13-Jul-2010 14:36:19</Created><LastEdit>13-Jul-2010 14:37:18</LastEdit><ICON>241</ICON><ProjectType>0</ProjectType><Created>13-Jul-2010 14:36:19</Created><Version>4</Version><Build>4, 18, 0, 685</Build><ProjectTypeName>AVR GCC</ProjectTypeName></MANAGEMENT><CODE_CREATION><ObjectFile>Webserver.elf</ObjectFile><EntryFile></EntryFile><SaveFolder>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\</SaveFolder></CODE_CREATION><DEBUG_TARGET><CURRENT_TARGET></CURRENT_TARGET><CURRENT_PART></CURRENT_PART><BREAKPOINTS></BREAKPOINTS><IO_EXPAND><HIDE>false</HIDE></IO_EXPAND><REGISTERNAMES><Register>R00</Register><Register>R01</Register><Register>R02</Register><Register>R03</Register><Register>R04</Register><Register>R05</Register><Register>R06</Register><Register>R07</Register><Register>R08</Register><Register>R09</Register><Register>R10</Register><Register>R11</Register><Register>R12</Register><Register>R13</Register><Register>R14</Register><Register>R15</Register><Register>R16</Register><Register>R17</Register><Register>R18</Register><Register>R19</Register><Register>R20</Register><Register>R21</Register><Register>R22</Register><Register>R23</Register><Register>R24</Register><Register>R25</Register><Register>R26</Register><Register>R27</Register><Register>R28</Register><Register>R29</Register><Register>R30</Register><Register>R31</Register></REGISTERNAMES><COM></COM><COMType>0</COMType><WATCHNUM>0</WATCHNUM><WATCHNAMES><Pane0></Pane0><Pane1></Pane1><Pane2></Pane2><Pane3></Pane3></WATCHNAMES><BreakOnTrcaeFull>0</BreakOnTrcaeFull></DEBUG_TARGET><Debugger><Triggers></Triggers></Debugger><AVRGCCPLUGIN><FILES><SOURCEFILE>Descriptors.c</SOURCEFILE><SOURCEFILE>USBDeviceMode.c</SOURCEFILE><SOURCEFILE>USBHostMode.c</SOURCEFILE><SOURCEFILE>Webserver.c</SOURCEFILE><SOURCEFILE>Lib\DataflashManager.c</SOURCEFILE><SOURCEFILE>Lib\DHCPClientApp.c</SOURCEFILE><SOURCEFILE>Lib\HTTPServerApp.c</SOURCEFILE><SOURCEFILE>Lib\SCSI.c</SOURCEFILE><SOURCEFILE>Lib\TELNETServerApp.c</SOURCEFILE><SOURCEFILE>Lib\uIPManagement.c</SOURCEFILE><HEADERFILE>Descriptors.h</HEADERFILE><HEADERFILE>USBDeviceMode.h</HEADERFILE><HEADERFILE>USBHostMode.h</HEADERFILE><HEADERFILE>Webserver.h</HEADERFILE><HEADERFILE>Lib\DataflashManager.h</HEADERFILE><HEADERFILE>Lib\DHCPClientApp.h</HEADERFILE><HEADERFILE>Lib\HTTPServerApp.h</HEADERFILE><HEADERFILE>Lib\SCSI.h</HEADERFILE><HEADERFILE>Lib\TELNETServerApp.h</HEADERFILE><HEADERFILE>Lib\uIPManagement.h</HEADERFILE><OTHERFILE>makefile</OTHERFILE></FILES><CONFIGS><CONFIG><NAME>default</NAME><USESEXTERNALMAKEFILE>YES</USESEXTERNALMAKEFILE><EXTERNALMAKEFILE>makefile</EXTERNALMAKEFILE><PART>atmega128</PART><HEX>1</HEX><LIST>1</LIST><MAP>1</MAP><OUTPUTFILENAME>Webserver.elf</OUTPUTFILENAME><OUTPUTDIR>default\</OUTPUTDIR><ISDIRTY>1</ISDIRTY><OPTIONS/><INCDIRS/><LIBDIRS/><LIBS/><LINKOBJECTS/><OPTIONSFORALL>-Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums</OPTIONSFORALL><LINKEROPTIONS></LINKEROPTIONS><SEGMENTS/></CONFIG></CONFIGS><LASTCONFIG>default</LASTCONFIG><USES_WINAVR>1</USES_WINAVR><GCC_LOC>C:\WinAVR-20100110\bin\avr-gcc.exe</GCC_LOC><MAKE_LOC>C:\WinAVR-20100110\utils\bin\make.exe</MAKE_LOC></AVRGCCPLUGIN><ProjectFiles><Files><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Descriptors.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\USBDeviceMode.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\USBHostMode.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Webserver.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\DataflashManager.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\DHCPClientApp.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\HTTPServerApp.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\SCSI.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\TELNETServerApp.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\uIPManagement.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Descriptors.c</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\USBDeviceMode.c</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\USBHostMode.c</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Webserver.c</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\DataflashManager.c</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\DHCPClientApp.c</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\HTTPServerApp.c</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\SCSI.c</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\TELNETServerApp.c</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\uIPManagement.c</Name></Files></ProjectFiles><IOView><usergroups/><sort sorted="0" column="0" ordername="0" orderaddress="0" ordergroup="0"/></IOView><Files></Files><Events><Bookmarks></Bookmarks></Events><Trace><Filters></Filters></Trace></AVRStudio>
+<AVRStudio><MANAGEMENT><ProjectName>Webserver</ProjectName><Created>13-Jul-2010 14:36:19</Created><LastEdit>13-Jul-2010 14:37:18</LastEdit><ICON>241</ICON><ProjectType>0</ProjectType><Created>13-Jul-2010 14:36:19</Created><Version>4</Version><Build>4, 18, 0, 685</Build><ProjectTypeName>AVR GCC</ProjectTypeName></MANAGEMENT><CODE_CREATION><ObjectFile>Webserver.elf</ObjectFile><EntryFile></EntryFile><SaveFolder>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\</SaveFolder></CODE_CREATION><DEBUG_TARGET><CURRENT_TARGET></CURRENT_TARGET><CURRENT_PART></CURRENT_PART><BREAKPOINTS></BREAKPOINTS><IO_EXPAND><HIDE>false</HIDE></IO_EXPAND><REGISTERNAMES><Register>R00</Register><Register>R01</Register><Register>R02</Register><Register>R03</Register><Register>R04</Register><Register>R05</Register><Register>R06</Register><Register>R07</Register><Register>R08</Register><Register>R09</Register><Register>R10</Register><Register>R11</Register><Register>R12</Register><Register>R13</Register><Register>R14</Register><Register>R15</Register><Register>R16</Register><Register>R17</Register><Register>R18</Register><Register>R19</Register><Register>R20</Register><Register>R21</Register><Register>R22</Register><Register>R23</Register><Register>R24</Register><Register>R25</Register><Register>R26</Register><Register>R27</Register><Register>R28</Register><Register>R29</Register><Register>R30</Register><Register>R31</Register></REGISTERNAMES><COM></COM><COMType>0</COMType><WATCHNUM>0</WATCHNUM><WATCHNAMES><Pane0></Pane0><Pane1></Pane1><Pane2></Pane2><Pane3></Pane3></WATCHNAMES><BreakOnTrcaeFull>0</BreakOnTrcaeFull></DEBUG_TARGET><Debugger><Triggers></Triggers></Debugger><AVRGCCPLUGIN><FILES><SOURCEFILE>Descriptors.c</SOURCEFILE><SOURCEFILE>USBDeviceMode.c</SOURCEFILE><SOURCEFILE>USBHostMode.c</SOURCEFILE><SOURCEFILE>Webserver.c</SOURCEFILE><SOURCEFILE>Lib\DataflashManager.c</SOURCEFILE><SOURCEFILE>Lib\DHCPClientApp.c</SOURCEFILE><SOURCEFILE>Lib\DHCPServerApp.c</SOURCEFILE><SOURCEFILE>Lib\DHCPCommon.c</SOURCEFILE><SOURCEFILE>Lib\HTTPServerApp.c</SOURCEFILE><SOURCEFILE>Lib\SCSI.c</SOURCEFILE><SOURCEFILE>Lib\TELNETServerApp.c</SOURCEFILE><SOURCEFILE>Lib\uIPManagement.c</SOURCEFILE><HEADERFILE>Descriptors.h</HEADERFILE><HEADERFILE>USBDeviceMode.h</HEADERFILE><HEADERFILE>USBHostMode.h</HEADERFILE><HEADERFILE>Webserver.h</HEADERFILE><HEADERFILE>Lib\DataflashManager.h</HEADERFILE><HEADERFILE>Lib\DHCPClientApp.h</HEADERFILE><HEADERFILE>Lib\DHCPServerApp.h</HEADERFILE><HEADERFILE>Lib\DHCPCommon.h</HEADERFILE><HEADERFILE>Lib\HTTPServerApp.h</HEADERFILE><HEADERFILE>Lib\SCSI.h</HEADERFILE><HEADERFILE>Lib\TELNETServerApp.h</HEADERFILE><HEADERFILE>Lib\uIPManagement.h</HEADERFILE><OTHERFILE>makefile</OTHERFILE></FILES><CONFIGS><CONFIG><NAME>default</NAME><USESEXTERNALMAKEFILE>YES</USESEXTERNALMAKEFILE><EXTERNALMAKEFILE>makefile</EXTERNALMAKEFILE><PART>atmega128</PART><HEX>1</HEX><LIST>1</LIST><MAP>1</MAP><OUTPUTFILENAME>Webserver.elf</OUTPUTFILENAME><OUTPUTDIR>default\</OUTPUTDIR><ISDIRTY>1</ISDIRTY><OPTIONS/><INCDIRS/><LIBDIRS/><LIBS/><LINKOBJECTS/><OPTIONSFORALL>-Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums</OPTIONSFORALL><LINKEROPTIONS></LINKEROPTIONS><SEGMENTS/></CONFIG></CONFIGS><LASTCONFIG>default</LASTCONFIG><USES_WINAVR>1</USES_WINAVR><GCC_LOC>C:\WinAVR-20100110\bin\avr-gcc.exe</GCC_LOC><MAKE_LOC>C:\WinAVR-20100110\utils\bin\make.exe</MAKE_LOC></AVRGCCPLUGIN><ProjectFiles><Files><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Descriptors.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\USBDeviceMode.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\USBHostMode.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Webserver.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\DataflashManager.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\DHCPClientApp.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\HTTPServerApp.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\SCSI.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\TELNETServerApp.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\uIPManagement.h</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Descriptors.c</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\USBDeviceMode.c</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\USBHostMode.c</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Webserver.c</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\DataflashManager.c</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\DHCPClientApp.c</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\HTTPServerApp.c</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\SCSI.c</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\TELNETServerApp.c</Name><Name>C:\Users\Dean\Documents\Electronics\Projects\WORK\LUFAWORK\Projects\Webserver\Lib\uIPManagement.c</Name></Files></ProjectFiles><IOView><usergroups/><sort sorted="0" column="0" ordername="0" orderaddress="0" ordergroup="0"/></IOView><Files></Files><Events><Bookmarks></Bookmarks></Events><Trace><Filters></Filters></Trace></AVRStudio>
diff --git a/Projects/Webserver/Webserver.txt b/Projects/Webserver/Webserver.txt
index ddb06590a..32bdb597a 100644
--- a/Projects/Webserver/Webserver.txt
+++ b/Projects/Webserver/Webserver.txt
@@ -52,10 +52,12 @@
* 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 device. Load
- * HTML files onto the disk, so that they can be served out to clients -- the default file to serve should be called
+ * 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).
+ * 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
@@ -89,6 +91,11 @@
* <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>Makefile LUFA_OPTS</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>Lib/uIPManagement.h</td>
* <td>IP address that the webserver should use when connected to a RNDIS device (when ENABLE_DHCP_CLIENT is not defined).</td>
diff --git a/Projects/Webserver/makefile b/Projects/Webserver/makefile
index bba6d057b..1602b2ff4 100644
--- a/Projects/Webserver/makefile
+++ b/Projects/Webserver/makefile
@@ -128,22 +128,25 @@ LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENAB
LUFA_OPTS += -D INTERRUPT_CONTROL_ENDPOINT
LUFA_OPTS += -D ENABLE_DHCP_CLIENT
+LUFA_OPTS += -D ENABLE_DHCP_SERVER
LUFA_OPTS += -D ENABLE_TELNET_SERVER
LUFA_OPTS += -D MAX_URI_LENGTH=50
-LUFA_OPTS += -D UIP_CONF_UDP="defined(ENABLE_DHCP_CLIENT)"
+
+LUFA_OPTS += -D UIP_CONF_UDP="defined(ENABLE_DHCP_CLIENT) || defined(ENABLE_DHCP_SERVER)"
+LUFA_OPTS += -D UIP_CONF_BROADCAST=1
LUFA_OPTS += -D UIP_CONF_TCP=1
LUFA_OPTS += -D UIP_CONF_UDP_CONNS=1
LUFA_OPTS += -D UIP_CONF_MAX_CONNECTIONS=3
LUFA_OPTS += -D UIP_CONF_MAX_LISTENPORTS=5
-LUFA_OPTS += -D UIP_URGDATA=0
LUFA_OPTS += -D UIP_CONF_BUFFER_SIZE=1514
-LUFA_OPTS += -D UIP_ARCH_CHKSUM=0
LUFA_OPTS += -D UIP_CONF_LL_802154=0
LUFA_OPTS += -D UIP_CONF_LL_80211=0
LUFA_OPTS += -D UIP_CONF_ROUTER=0
LUFA_OPTS += -D UIP_CONF_ICMP6=0
-LUFA_OPTS += -D UIP_ARCH_ADD32=0
LUFA_OPTS += -D UIP_CONF_ICMP_DEST_UNREACH=1
+LUFA_OPTS += -D UIP_URGDATA=0
+LUFA_OPTS += -D UIP_ARCH_CHKSUM=0
+LUFA_OPTS += -D UIP_ARCH_ADD32=0
LUFA_OPTS += -D UIP_NEIGHBOR_CONF_ADDRTYPE=0
@@ -159,7 +162,9 @@ SRC = $(TARGET).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 \