diff options
author | Dean Camera <dean@fourwalledcubicle.com> | 2011-05-22 08:28:40 +0000 |
---|---|---|
committer | Dean Camera <dean@fourwalledcubicle.com> | 2011-05-22 08:28:40 +0000 |
commit | 3cba88e4c05d6a3c25ffa9c7185d41a84b7f72b1 (patch) | |
tree | f356fef599a6b9fd290f99ecf694b6f84f8a61b7 /Projects | |
parent | e349974aa9fdd6679a385d0da66005a27706b275 (diff) | |
download | lufa-3cba88e4c05d6a3c25ffa9c7185d41a84b7f72b1.tar.gz lufa-3cba88e4c05d6a3c25ffa9c7185d41a84b7f72b1.tar.bz2 lufa-3cba88e4c05d6a3c25ffa9c7185d41a84b7f72b1.zip |
Add RNDIS Device support to the Webserver project, so that the files stored on the device can be viewed from a web-browser while the board is plugged into a host machine.
Diffstat (limited to 'Projects')
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 \ |