aboutsummaryrefslogtreecommitdiffstats
path: root/Projects
diff options
context:
space:
mode:
Diffstat (limited to 'Projects')
-rw-r--r--Projects/Webserver/Lib/DHCPApp.c237
-rw-r--r--Projects/Webserver/Lib/DHCPApp.h125
-rw-r--r--Projects/Webserver/Lib/WebserverApp.c29
-rw-r--r--Projects/Webserver/Lib/WebserverApp.h11
-rw-r--r--Projects/Webserver/Lib/uip/conf/apps-conf.h23
-rw-r--r--Projects/Webserver/Lib/uip/conf/clock-arch.c3
-rw-r--r--Projects/Webserver/Lib/uip/conf/global-conf.h4
-rw-r--r--Projects/Webserver/Lib/uip/conf/uip-conf.h6
-rw-r--r--Projects/Webserver/Webserver.c43
-rw-r--r--Projects/Webserver/Webserver.h13
-rw-r--r--Projects/Webserver/Webserver.txt12
-rw-r--r--Projects/Webserver/makefile2
12 files changed, 466 insertions, 42 deletions
diff --git a/Projects/Webserver/Lib/DHCPApp.c b/Projects/Webserver/Lib/DHCPApp.c
new file mode 100644
index 000000000..ec5a815ef
--- /dev/null
+++ b/Projects/Webserver/Lib/DHCPApp.c
@@ -0,0 +1,237 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2010 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
+ *
+ * DHCP Client Application. When connected to the uIP stack, this will retrieve IP configuration settings from the
+ * DHCP server on the network.
+ */
+
+#include "DHCPApp.h"
+
+#if defined(ENABLE_DHCP)
+/** Timer for managing the timeout period for a DHCP server to respond */
+struct timer DHCPTimer;
+
+/** Initialization function for the DHCP client. */
+void DHCPApp_Init(void)
+{
+ uip_udp_appstate_t* const AppState = &uip_udp_conn->appstate;
+
+ /* Create a new UDP connection to the DHCP server port for the DHCP solicitation */
+ uip_ipaddr_t DHCPServerIPAddress;
+ uip_ipaddr(&DHCPServerIPAddress, 255, 255, 255, 255);
+ AppState->Connection = uip_udp_new(&DHCPServerIPAddress, HTONS(DHCPC_SERVER_PORT));
+
+ /* If the connection was sucessfully created, bind it to the local DHCP client port */
+ if(AppState->Connection != NULL)
+ {
+ uip_udp_bind(AppState->Connection, HTONS(DHCPC_CLIENT_PORT));
+ AppState->CurrentState = DHCP_STATE_SendDiscover;
+ }
+
+ /* Set timeout period to half a second for a DHCP server to respond */
+ timer_set(&DHCPTimer, CLOCK_SECOND / 2);
+}
+
+/** uIP stack application callback for the DHCP client. This function must be called each time the TCP/IP stack
+ * needs a UDP packet to be processed.
+ */
+void DHCPApp_Callback(void)
+{
+ uip_udp_appstate_t* const AppState = &uip_udp_conn->appstate;
+ DHCP_Header_t* const AppData = (DHCP_Header_t*)uip_appdata;
+ uint16_t AppDataSize = 0;
+
+ switch (AppState->CurrentState)
+ {
+ case DHCP_STATE_SendDiscover:
+ /* Clear all DHCP settings, reset client IP address */
+ memset(&AppState->DHCPOffer_Data, 0x00, sizeof(AppState->DHCPOffer_Data));
+ uip_sethostaddr(&AppState->DHCPOffer_Data.AllocatedIP);
+
+ /* Fill out the DHCP response header */
+ AppDataSize += DHCPApp_FillDHCPHeader(AppData, DHCP_DISCOVER, AppState);
+
+ /* Add the required DHCP options list to the packet */
+ uint8_t RequiredOptionList[] = {DHCP_OPTION_SUBNET_MASK, DHCP_OPTION_ROUTER, DHCP_OPTION_DNS_SERVER};
+ AppDataSize += DHCPApp_SetOption(AppData->Options, DHCP_OPTION_REQ_LIST, sizeof(RequiredOptionList),
+ RequiredOptionList);
+
+ /* Send the DHCP DISCOVER packet */
+ uip_send(AppData, AppDataSize);
+
+ /* Reset the timeout timer, progress to next state */
+ timer_reset(&DHCPTimer);
+ AppState->CurrentState = DHCP_STATE_WaitForResponse;
+
+ break;
+ case DHCP_STATE_WaitForResponse:
+ if (!(uip_newdata()))
+ {
+ /* Check if the DHCP timeout period has expired while waiting for a response */
+ if (timer_expired(&DHCPTimer))
+ AppState->CurrentState = DHCP_STATE_SendDiscover;
+
+ break;
+ }
+
+ uint8_t OfferResponse_MessageType;
+ if ((AppData->TransactionID == DHCP_TRANSACTION_ID) &&
+ DHCPApp_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->DHCPOffer_Data.AllocatedIP, &AppData->YourIP, sizeof(uip_ipaddr_t));
+ DHCPApp_GetOption(AppData->Options, DHCP_OPTION_SUBNET_MASK, &AppState->DHCPOffer_Data.Netmask);
+ DHCPApp_GetOption(AppData->Options, DHCP_OPTION_ROUTER, &AppState->DHCPOffer_Data.GatewayIP);
+ DHCPApp_GetOption(AppData->Options, DHCP_OPTION_SERVER_ID, &AppState->DHCPOffer_Data.ServerIP);
+
+ timer_reset(&DHCPTimer);
+ AppState->CurrentState = DHCP_STATE_SendRequest;
+ }
+
+ break;
+ case DHCP_STATE_SendRequest:
+ /* Fill out the DHCP response header */
+ AppDataSize += DHCPApp_FillDHCPHeader(AppData, DHCP_REQUEST, AppState);
+
+ /* Add the DHCP REQUESTED IP ADDRESS option to the packet */
+ AppDataSize += DHCPApp_SetOption(AppData->Options, DHCP_OPTION_REQ_IPADDR, sizeof(uip_ipaddr_t),
+ &AppState->DHCPOffer_Data.AllocatedIP);
+
+ /* Add the DHCP SERVER IP ADDRESS option to the packet */
+ AppDataSize += DHCPApp_SetOption(AppData->Options, DHCP_OPTION_SERVER_ID, sizeof(uip_ipaddr_t),
+ &AppState->DHCPOffer_Data.ServerIP);
+
+ /* Send the DHCP REQUEST packet */
+ uip_send(AppData, AppDataSize);
+
+ /* Reset the timeout timer, progress to next state */
+ timer_reset(&DHCPTimer);
+ AppState->CurrentState = DHCP_STATE_WaitForACK;
+
+ break;
+ case DHCP_STATE_WaitForACK:
+ if (!(uip_newdata()))
+ {
+ /* Check if the DHCP timeout period has expired while waiting for a response */
+ if (timer_expired(&DHCPTimer))
+ AppState->CurrentState = DHCP_STATE_SendDiscover;
+
+ break;
+ }
+
+ uint8_t RequestResponse_MessageType;
+ if ((AppData->TransactionID == DHCP_TRANSACTION_ID) &&
+ DHCPApp_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &RequestResponse_MessageType) &&
+ (RequestResponse_MessageType == DHCP_ACK))
+ {
+ /* Set the new network parameters from the DHCP server */
+ uip_sethostaddr(&AppState->DHCPOffer_Data.AllocatedIP);
+ uip_setnetmask(&AppState->DHCPOffer_Data.Netmask);
+ uip_setdraddr(&AppState->DHCPOffer_Data.GatewayIP);
+
+ AppState->CurrentState = DHCP_STATE_AddressLeased;
+ }
+
+ break;
+ }
+}
+
+uint16_t DHCPApp_FillDHCPHeader(DHCP_Header_t* DHCPHeader, uint8_t DHCPMessageType, uip_udp_appstate_t* AppState)
+{
+ /* Erase existing packet data so that we start will all 0x00 DHCP header data */
+ memset(DHCPHeader, 0, sizeof(DHCP_Header_t));
+
+ /* Fill out the DHCP packet header */
+ DHCPHeader->Operation = DHCP_OP_BOOTREQUEST;
+ DHCPHeader->HardwareType = DHCP_HTYPE_ETHERNET;
+ DHCPHeader->HardwareAddressLength = sizeof(MACAddress);
+ DHCPHeader->Hops = 0;
+ DHCPHeader->TransactionID = DHCP_TRANSACTION_ID;
+ DHCPHeader->ElapsedSeconds = 0;
+ DHCPHeader->Flags = HTONS(BOOTP_BROADCAST);
+ memcpy(&DHCPHeader->ClientIP, &uip_hostaddr, sizeof(uip_ipaddr_t));
+ memcpy(&DHCPHeader->YourIP, &AppState->DHCPOffer_Data.AllocatedIP, sizeof(uip_ipaddr_t));
+ memcpy(&DHCPHeader->NextServerIP, &AppState->DHCPOffer_Data.ServerIP, sizeof(uip_ipaddr_t));
+ memcpy(&DHCPHeader->ClientHardwareAddress, &MACAddress, sizeof(struct uip_eth_addr));
+ DHCPHeader->Cookie = DHCP_MAGIC_COOKIE;
+
+ /* Add a DHCP 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);
+}
+
+uint8_t DHCPApp_SetOption(uint8_t* DHCPOptionList, uint8_t Option, uint8_t DataLen, void* Source)
+{
+ /* 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], Source, DataLen);
+ DHCPOptionList[2 + DataLen] = DHCP_OPTION_END;
+
+ /* Calculate the total number of bytes added to the outgoing packet */
+ return (2 + DataLen);
+}
+
+bool DHCPApp_GetOption(uint8_t* DHCPOptionList, uint8_t Option, void* Destination)
+{
+ /* Look through the incomming 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 sucessfully retrieved */
+ return true;
+ }
+
+ /* Skip to next DHCP option in the options list */
+ DHCPOptionList += (DHCPOptionList[1] + 2);
+ }
+
+ /* Requested option not found in the incomming packet's DHCP options list */
+ return false;
+}
+
+#endif
diff --git a/Projects/Webserver/Lib/DHCPApp.h b/Projects/Webserver/Lib/DHCPApp.h
new file mode 100644
index 000000000..9e9faaa36
--- /dev/null
+++ b/Projects/Webserver/Lib/DHCPApp.h
@@ -0,0 +1,125 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2010 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 DHCPApp.c.
+ */
+
+#ifndef _DHCP_APP_H_
+#define _DHCP_APP_H_
+
+ /* Includes: */
+ #include <stdio.h>
+
+ #include <uip.h>
+
+ #include "../Webserver.h"
+
+ /* Macros: */
+ #define DHCPC_SERVER_PORT 67
+ #define DHCPC_CLIENT_PORT 68
+
+ #define DHCP_OP_BOOTREQUEST 0x01
+ #define DHCP_OP_BOOTREPLY 0x02
+
+ #define BOOTP_BROADCAST 0x8000
+
+ #define DHCP_MAGIC_COOKIE 0x63538263
+
+ #define DHCP_TRANSACTION_ID 0x13245466
+
+ #define DHCP_DISCOVER 1
+ #define DHCP_OFFER 2
+ #define DHCP_REQUEST 3
+ #define DHCP_DECLINE 4
+ #define DHCP_ACK 5
+ #define DHCP_NAK 6
+ #define DHCP_RELEASE 7
+
+ #define DHCP_HTYPE_ETHERNET 1
+
+ #define DHCP_OPTION_SUBNET_MASK 1
+ #define DHCP_OPTION_ROUTER 3
+ #define DHCP_OPTION_DNS_SERVER 6
+ #define DHCP_OPTION_REQ_IPADDR 50
+ #define DHCP_OPTION_LEASE_TIME 51
+ #define DHCP_OPTION_MSG_TYPE 53
+ #define DHCP_OPTION_SERVER_ID 54
+ #define DHCP_OPTION_REQ_LIST 55
+ #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;
+
+ /* Enums: */
+ enum DHCP_States_t
+ {
+ DHCP_STATE_SendDiscover,
+ DHCP_STATE_WaitForResponse,
+ DHCP_STATE_SendRequest,
+ DHCP_STATE_WaitForACK,
+ DHCP_STATE_AddressLeased,
+ };
+
+ /* Function Prototypes: */
+ void DHCPApp_Init(void);
+ void DHCPApp_Callback(void);
+
+ uint16_t DHCPApp_FillDHCPHeader(DHCP_Header_t* DHCPHeader, uint8_t DHCPMessageType, uip_udp_appstate_t* AppState);
+ uint8_t DHCPApp_SetOption(uint8_t* DHCPOptionList, uint8_t Option, uint8_t DataLen, void* Source);
+ bool DHCPApp_GetOption(uint8_t* DHCPOptionList, uint8_t Option, void* Destination);
+
+#endif
diff --git a/Projects/Webserver/Lib/WebserverApp.c b/Projects/Webserver/Lib/WebserverApp.c
index cba3b43fa..02f38be87 100644
--- a/Projects/Webserver/Lib/WebserverApp.c
+++ b/Projects/Webserver/Lib/WebserverApp.c
@@ -76,7 +76,7 @@ char PROGMEM HTTPPage[] =
void WebserverApp_Init(void)
{
/* Listen on port 80 for HTTP connections from hosts */
- uip_listen(HTONS(80));
+ uip_listen(HTONS(HTTP_SERVER_PORT));
}
/** uIP stack application callback for the simple HTTP webserver. This function must be called each time the
@@ -84,8 +84,9 @@ void WebserverApp_Init(void)
*/
void WebserverApp_Callback(void)
{
- char* AppDataPtr = (char*)uip_appdata;
- uint16_t AppDataSize = 0;
+ uip_tcp_appstate_t* const AppState = &uip_conn->appstate;
+ char* AppData = (char*)uip_appdata;
+ uint16_t AppDataSize = 0;
if (uip_closed() || uip_aborted() || uip_timedout())
{
@@ -95,12 +96,12 @@ void WebserverApp_Callback(void)
else if (uip_connected())
{
/* New connection - initialize connection state and data pointer to the appropriate HTTP header */
- uip_conn->appstate.SendPos = HTTP200Header;
- uip_conn->appstate.CurrentState = WEBSERVER_STATE_SendHeaders;
+ AppState->SendPos = HTTP200Header;
+ AppState->CurrentState = WEBSERVER_STATE_SendHeaders;
}
/* Calculate the maximum segment size and remaining data size */
- uint16_t BytesRemaining = strlen_P(uip_conn->appstate.SendPos);
+ uint16_t BytesRemaining = strlen_P(AppState->SendPos);
uint16_t MaxSegSize = uip_mss();
/* No more bytes remaining in the current data being sent - progress to next data chunk or
@@ -108,15 +109,15 @@ void WebserverApp_Callback(void)
if (!(BytesRemaining))
{
/* Check which data chunk we are currently sending (header or data) */
- if (uip_conn->appstate.CurrentState == WEBSERVER_STATE_SendHeaders)
+ if (AppState->CurrentState == WEBSERVER_STATE_SendHeaders)
{
- uip_conn->appstate.SendPos = HTTPPage;
- uip_conn->appstate.CurrentState = WEBSERVER_STATE_SendData;
+ AppState->SendPos = HTTPPage;
+ AppState->CurrentState = WEBSERVER_STATE_SendData;
}
- else if (uip_conn->appstate.CurrentState == WEBSERVER_STATE_SendData)
+ else if (AppState->CurrentState == WEBSERVER_STATE_SendData)
{
uip_close();
- uip_conn->appstate.CurrentState = WEBSERVER_STATE_Closed;
+ AppState->CurrentState = WEBSERVER_STATE_Closed;
}
return;
@@ -133,9 +134,9 @@ void WebserverApp_Callback(void)
}
/* Copy over the next data segment to the application buffer, advance send position pointer */
- strncpy_P(uip_appdata, uip_conn->appstate.SendPos, AppDataSize);
- uip_conn->appstate.SendPos += AppDataSize;
+ strncpy_P(AppData, AppState->SendPos, AppDataSize);
+ AppState->SendPos += AppDataSize;
/* Send the data to the requesting host */
- uip_send(AppDataPtr, AppDataSize);
+ uip_send(AppData, AppDataSize);
}
diff --git a/Projects/Webserver/Lib/WebserverApp.h b/Projects/Webserver/Lib/WebserverApp.h
index 4d1d76cc9..3cb97c667 100644
--- a/Projects/Webserver/Lib/WebserverApp.h
+++ b/Projects/Webserver/Lib/WebserverApp.h
@@ -43,6 +43,17 @@
#include <LUFA/Version.h>
#include <uip.h>
+
+ /* Enums: */
+ enum Webserver_States_t
+ {
+ WEBSERVER_STATE_SendHeaders,
+ WEBSERVER_STATE_SendData,
+ WEBSERVER_STATE_Closed,
+ };
+
+ /* Macros: */
+ #define HTTP_SERVER_PORT 80
/* Function Prototypes: */
void WebserverApp_Init(void);
diff --git a/Projects/Webserver/Lib/uip/conf/apps-conf.h b/Projects/Webserver/Lib/uip/conf/apps-conf.h
index 22bab81bf..fc9727dcd 100644
--- a/Projects/Webserver/Lib/uip/conf/apps-conf.h
+++ b/Projects/Webserver/Lib/uip/conf/apps-conf.h
@@ -1,20 +1,29 @@
#ifndef __APPS_CONF_H__
#define __APPS_CONF_H__
- enum Webserver_States_t
- {
- WEBSERVER_STATE_SendHeaders,
- WEBSERVER_STATE_SendData,
- WEBSERVER_STATE_Closed,
- };
-
typedef struct
{
uint8_t CurrentState;
char* SendPos;
} uip_tcp_appstate_t;
+ typedef struct
+ {
+ uint8_t CurrentState;
+ struct uip_udp_conn* Connection;
+
+ struct
+ {
+ uint8_t AllocatedIP[4];
+ uint8_t Netmask[4];
+ uint8_t GatewayIP[4];
+ uint8_t ServerIP[4];
+ } DHCPOffer_Data;
+ } uip_udp_appstate_t;
+
#define UIP_APPCALL WebserverApp_Callback
+ #define UIP_UDP_APPCALL DHCPApp_Callback
void UIP_APPCALL(void);
+ void UIP_UDP_APPCALL(void);
#endif /*__APPS_CONF_H__*/
diff --git a/Projects/Webserver/Lib/uip/conf/clock-arch.c b/Projects/Webserver/Lib/uip/conf/clock-arch.c
index 8363d96e0..2007de4e9 100644
--- a/Projects/Webserver/Lib/uip/conf/clock-arch.c
+++ b/Projects/Webserver/Lib/uip/conf/clock-arch.c
@@ -21,8 +21,7 @@ ISR(TIMER1_COMPA_vect)
void clock_init()
{
OCR1A = ((F_CPU / 1024) / 100);
- TCCR1A = (1 << WGM12);
- TCCR1B = ((1 << CS12) | (1 << CS10));
+ TCCR1B = ((1 << WGM12) | (1 << CS12) | (1 << CS10));
TIMSK1 = (1 << OCIE1A);
}
diff --git a/Projects/Webserver/Lib/uip/conf/global-conf.h b/Projects/Webserver/Lib/uip/conf/global-conf.h
index a9f118d4d..5cfc60746 100644
--- a/Projects/Webserver/Lib/uip/conf/global-conf.h
+++ b/Projects/Webserver/Lib/uip/conf/global-conf.h
@@ -2,10 +2,6 @@
#ifndef __GLOBAL_CONF_H__
#define __GLOBAL_CONF_H__
-//Define frequency
-// #define F_CPU 12500000UL
-//
-
//Include uip.h gives all the uip configurations in uip-conf.h
#include "uip.h"
diff --git a/Projects/Webserver/Lib/uip/conf/uip-conf.h b/Projects/Webserver/Lib/uip/conf/uip-conf.h
index d3d9bc453..e89e7c4c6 100644
--- a/Projects/Webserver/Lib/uip/conf/uip-conf.h
+++ b/Projects/Webserver/Lib/uip/conf/uip-conf.h
@@ -79,7 +79,11 @@ typedef unsigned short uip_stats_t;
*
* \hideinitializer
*/
-#define UIP_CONF_UDP 0
+#if defined(ENABLE_DHCP)
+ #define UIP_CONF_UDP 1
+#else
+ #define UIP_CONF_UDP 0
+#endif
/**
* UDP checksums on or off
diff --git a/Projects/Webserver/Webserver.c b/Projects/Webserver/Webserver.c
index d1764ee84..78e60f866 100644
--- a/Projects/Webserver/Webserver.c
+++ b/Projects/Webserver/Webserver.c
@@ -63,6 +63,8 @@ struct timer ConnectionTimer;
/** ARP timer, to retain the time elapsed since the ARP cache was last updated. */
struct timer ARPTimer;
+/** MAC address of the RNDIS device, when enumerated */
+struct uip_eth_addr MACAddress;
/** Main program entry point. This routine configures the hardware required by the application, then
* enters a loop to run the application tasks in sequence.
@@ -122,7 +124,6 @@ int main(void)
break;
}
- struct uip_eth_addr MACAddress;
if (RNDIS_Host_QueryRNDISProperty(&Ethernet_RNDIS_Interface, OID_802_3_CURRENT_ADDRESS,
&MACAddress, sizeof(MACAddress)) != HOST_SENDCONTROL_Successful)
{
@@ -204,14 +205,36 @@ void ManageConnections(void)
for (uint8_t i = 0; i < UIP_CONNS; i++)
{
- /* Run periodic connection management for each connection */
+ /* Run periodic connection management for each TCP connection */
uip_periodic(i);
/* If a response was generated, send it */
if (uip_len > 0)
- RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, &uip_buf[0], uip_len);
+ {
+ /* Add destination MAC to outgoing packet */
+ uip_arp_out();
+
+ RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, &uip_buf[0], uip_len);
+ }
}
+ #if defined(ENABLE_DHCP)
+ for (uint8_t i = 0; i < UIP_UDP_CONNS; i++)
+ {
+ /* Run periodic connection management for each UDP connection */
+ uip_udp_periodic(i);
+
+ /* If a response was generated, send it */
+ if (uip_len > 0)
+ {
+ /* Add destination MAC to outgoing packet */
+ uip_arp_out();
+
+ RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, &uip_buf[0], uip_len);
+ }
+ }
+ #endif
+
LEDs_SetAllLEDs(LEDMASK_USB_READY);
}
@@ -244,14 +267,20 @@ void SetupHardware(void)
/* uIP Stack Initialization */
uip_init();
+
+ /* DHCP/Server IP Settings Initialization */
+ #if defined(ENABLE_DHCP)
+ DHCPApp_Init();
+ #else
uip_ipaddr_t IPAddress, Netmask, GatewayIPAddress;
- uip_ipaddr(&IPAddress, DEVICE_IP_ADDRESS[0], DEVICE_IP_ADDRESS[1], DEVICE_IP_ADDRESS[2], DEVICE_IP_ADDRESS[3]);
- uip_ipaddr(&Netmask, DEVICE_NETMASK[0], DEVICE_NETMASK[1], DEVICE_NETMASK[2], DEVICE_NETMASK[3]);
- uip_ipaddr(&GatewayIPAddress, DEVICE_GATEWAY[0], DEVICE_GATEWAY[1], DEVICE_GATEWAY[2], DEVICE_GATEWAY[3]);
+ uip_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
+
/* HTTP Webserver Initialization */
WebserverApp_Init();
}
diff --git a/Projects/Webserver/Webserver.h b/Projects/Webserver/Webserver.h
index 8d23bc1d5..13462a2a2 100644
--- a/Projects/Webserver/Webserver.h
+++ b/Projects/Webserver/Webserver.h
@@ -43,7 +43,6 @@
#include <avr/power.h>
#include <LUFA/Version.h>
- #include <LUFA/Drivers/Misc/TerminalCodes.h>
#include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/RNDIS.h>
@@ -53,15 +52,18 @@
#include <timer.h>
#include "Lib/WebserverApp.h"
+ #include "Lib/DHCPApp.h"
/* Macros: */
- /** IP address that the webserver should use once connected to a RNDIS device. */
+ /** 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}
- /** Netmask that the webserver should once connected to a RNDIS device. */
+ /** Netmask that the webserver should once connected to a RNDIS device (when DHCP is disabled). */
#define DEVICE_NETMASK (uint8_t[]){255, 255, 255, 0}
- /** IP address of the default gateway the webserver should use when routing outside the local subnet. */
+ /** 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}
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
@@ -78,6 +80,9 @@
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */
#define LEDMASK_USB_BUSY LEDS_LED2
+
+ /* External Variables: */
+ extern struct uip_eth_addr MACAddress;
/* Function Prototypes: */
void SetupHardware(void);
diff --git a/Projects/Webserver/Webserver.txt b/Projects/Webserver/Webserver.txt
index 5c27954a9..e1d298596 100644
--- a/Projects/Webserver/Webserver.txt
+++ b/Projects/Webserver/Webserver.txt
@@ -63,19 +63,25 @@
* <td><b>Description:</b></td>
* </tr>
* <tr>
+ * <td>ENABLE_DHCP</td>
+ * <td>Makefile CDEFS</td>
+ * <td>When defined, enables the DHCP client for dynamic IP allocation of the network settings from a DHCP server.</td>
+ * </tr>
+ * <tr>
* <td>DEVICE_IP_ADDRESS</td>
* <td>Webserver.h</td>
- * <td>IP address that the webserver should use when connected to a RNDIS device.</td>
+ * <td>IP address that the webserver should use when connected to a RNDIS device (when ENABLE_DHCP is not defined).</td>
* </tr>
* <tr>
* <td>DEVICE_NETMASK</td>
* <td>Webserver.h</td>
- * <td>Netmask that the webserver should use when connected to a RNDIS device.</td>
+ * <td>Netmask that the webserver should use when connected to a RNDIS device (when ENABLE_DHCP is not defined).</td>
* </tr>
* <tr>
* <td>DEVICE_GATEWAY</td>
* <td>Webserver.h</td>
- * <td>Default routing gateway that the webserver should use when connected to a RNDIS device.</td>
+ * <td>Default routing gateway that the webserver should use when connected to a RNDIS device (when ENABLE_DHCP
+ * is not defined).</td>
* </tr>
* </table>
*/ \ No newline at end of file
diff --git a/Projects/Webserver/makefile b/Projects/Webserver/makefile
index 27a7850aa..4a1b85bdd 100644
--- a/Projects/Webserver/makefile
+++ b/Projects/Webserver/makefile
@@ -122,6 +122,7 @@ LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
+ Lib/DHCPApp.c \
Lib/WebserverApp.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c \
@@ -188,6 +189,7 @@ CSTANDARD = -std=gnu99
# Place -D or -U options here for C sources
CDEFS = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD) $(LUFA_OPTS)
+CDEFS += -DENABLE_DHCP
# Place -D or -U options here for ASM sources