Add DHCP server to the Webserver demo for automatic network configuration. Correct uIP timer clock not tracking the correct timespan.

pull/1469/head
Dean Camera 15 years ago
parent 1aeb5056d6
commit a960e4b3b2

File diff suppressed because one or more lines are too long

@ -11,6 +11,7 @@
* Development Blog: http://www.fourwalledcubicle.com/blog \n * Development Blog: http://www.fourwalledcubicle.com/blog \n
* Discussion Group: http://groups.google.com/group/myusb-support-list \n * Discussion Group: http://groups.google.com/group/myusb-support-list \n
* Official Releases, SVN Access, Issue Tracker: http://code.google.com/p/lufa-lib/ \n * Official Releases, SVN Access, Issue Tracker: http://code.google.com/p/lufa-lib/ \n
* Development Source Archives: http://github.com/abcminiuser/lufa-lib/archives/master
* Git Access: http://github.com/abcminiuser/lufa-lib * Git Access: http://github.com/abcminiuser/lufa-lib
* Commit RSS: http://github.com/feeds/abcminiuser/commits/lufa-lib/master * Commit RSS: http://github.com/feeds/abcminiuser/commits/lufa-lib/master
* Author's Website: http://www.fourwalledcubicle.com \n * Author's Website: http://www.fourwalledcubicle.com \n

@ -27,6 +27,9 @@
* library API more streamlined and robust. You can download AVR-GCC for free in a convenient windows package, * library API more streamlined and robust. You can download AVR-GCC for free in a convenient windows package,
* from the the WinAVR website (see \ref Page_Resources). * from the the WinAVR website (see \ref Page_Resources).
* *
* The only required AVR peripherals for LUFA is the USB controller itself and interrupts - LUFA does not require the use of the
* microcontroller's timers or other hardware, leaving more hardware to the application developer.
*
* Accompanying LUFA in the download package is a set of example demo applications, plus several Bootloaders of different classes * Accompanying LUFA in the download package is a set of example demo applications, plus several Bootloaders of different classes
* and open source LUFA powered projects. * and open source LUFA powered projects.
* *

@ -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

@ -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

@ -76,7 +76,7 @@ char PROGMEM HTTPPage[] =
void WebserverApp_Init(void) void WebserverApp_Init(void)
{ {
/* Listen on port 80 for HTTP connections from hosts */ /* 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 /** 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) void WebserverApp_Callback(void)
{ {
char* AppDataPtr = (char*)uip_appdata; uip_tcp_appstate_t* const AppState = &uip_conn->appstate;
uint16_t AppDataSize = 0; char* AppData = (char*)uip_appdata;
uint16_t AppDataSize = 0;
if (uip_closed() || uip_aborted() || uip_timedout()) if (uip_closed() || uip_aborted() || uip_timedout())
{ {
@ -95,12 +96,12 @@ void WebserverApp_Callback(void)
else if (uip_connected()) else if (uip_connected())
{ {
/* New connection - initialize connection state and data pointer to the appropriate HTTP header */ /* New connection - initialize connection state and data pointer to the appropriate HTTP header */
uip_conn->appstate.SendPos = HTTP200Header; AppState->SendPos = HTTP200Header;
uip_conn->appstate.CurrentState = WEBSERVER_STATE_SendHeaders; AppState->CurrentState = WEBSERVER_STATE_SendHeaders;
} }
/* Calculate the maximum segment size and remaining data size */ /* 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(); uint16_t MaxSegSize = uip_mss();
/* No more bytes remaining in the current data being sent - progress to next data chunk or /* 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)) if (!(BytesRemaining))
{ {
/* Check which data chunk we are currently sending (header or data) */ /* 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; AppState->SendPos = HTTPPage;
uip_conn->appstate.CurrentState = WEBSERVER_STATE_SendData; AppState->CurrentState = WEBSERVER_STATE_SendData;
} }
else if (uip_conn->appstate.CurrentState == WEBSERVER_STATE_SendData) else if (AppState->CurrentState == WEBSERVER_STATE_SendData)
{ {
uip_close(); uip_close();
uip_conn->appstate.CurrentState = WEBSERVER_STATE_Closed; AppState->CurrentState = WEBSERVER_STATE_Closed;
} }
return; return;
@ -133,9 +134,9 @@ void WebserverApp_Callback(void)
} }
/* Copy over the next data segment to the application buffer, advance send position pointer */ /* Copy over the next data segment to the application buffer, advance send position pointer */
strncpy_P(uip_appdata, uip_conn->appstate.SendPos, AppDataSize); strncpy_P(AppData, AppState->SendPos, AppDataSize);
uip_conn->appstate.SendPos += AppDataSize; AppState->SendPos += AppDataSize;
/* Send the data to the requesting host */ /* Send the data to the requesting host */
uip_send(AppDataPtr, AppDataSize); uip_send(AppData, AppDataSize);
} }

@ -44,6 +44,17 @@
#include <uip.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: */ /* Function Prototypes: */
void WebserverApp_Init(void); void WebserverApp_Init(void);
void WebserverApp_Callback(void); void WebserverApp_Callback(void);

@ -1,20 +1,29 @@
#ifndef __APPS_CONF_H__ #ifndef __APPS_CONF_H__
#define __APPS_CONF_H__ #define __APPS_CONF_H__
enum Webserver_States_t
{
WEBSERVER_STATE_SendHeaders,
WEBSERVER_STATE_SendData,
WEBSERVER_STATE_Closed,
};
typedef struct typedef struct
{ {
uint8_t CurrentState; uint8_t CurrentState;
char* SendPos; char* SendPos;
} uip_tcp_appstate_t; } 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_APPCALL WebserverApp_Callback
#define UIP_UDP_APPCALL DHCPApp_Callback
void UIP_APPCALL(void); void UIP_APPCALL(void);
void UIP_UDP_APPCALL(void);
#endif /*__APPS_CONF_H__*/ #endif /*__APPS_CONF_H__*/

@ -21,8 +21,7 @@ ISR(TIMER1_COMPA_vect)
void clock_init() void clock_init()
{ {
OCR1A = ((F_CPU / 1024) / 100); OCR1A = ((F_CPU / 1024) / 100);
TCCR1A = (1 << WGM12); TCCR1B = ((1 << WGM12) | (1 << CS12) | (1 << CS10));
TCCR1B = ((1 << CS12) | (1 << CS10));
TIMSK1 = (1 << OCIE1A); TIMSK1 = (1 << OCIE1A);
} }

@ -2,10 +2,6 @@
#ifndef __GLOBAL_CONF_H__ #ifndef __GLOBAL_CONF_H__
#define __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 gives all the uip configurations in uip-conf.h
#include "uip.h" #include "uip.h"

@ -79,7 +79,11 @@ typedef unsigned short uip_stats_t;
* *
* \hideinitializer * \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 * UDP checksums on or off

@ -63,6 +63,8 @@ struct timer ConnectionTimer;
/** ARP timer, to retain the time elapsed since the ARP cache was last updated. */ /** ARP timer, to retain the time elapsed since the ARP cache was last updated. */
struct timer ARPTimer; 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 /** Main program entry point. This routine configures the hardware required by the application, then
* enters a loop to run the application tasks in sequence. * enters a loop to run the application tasks in sequence.
@ -122,7 +124,6 @@ int main(void)
break; break;
} }
struct uip_eth_addr MACAddress;
if (RNDIS_Host_QueryRNDISProperty(&Ethernet_RNDIS_Interface, OID_802_3_CURRENT_ADDRESS, if (RNDIS_Host_QueryRNDISProperty(&Ethernet_RNDIS_Interface, OID_802_3_CURRENT_ADDRESS,
&MACAddress, sizeof(MACAddress)) != HOST_SENDCONTROL_Successful) &MACAddress, sizeof(MACAddress)) != HOST_SENDCONTROL_Successful)
{ {
@ -204,13 +205,35 @@ void ManageConnections(void)
for (uint8_t i = 0; i < UIP_CONNS; i++) 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); uip_periodic(i);
/* If a response was generated, send it */ /* If a response was generated, send it */
if (uip_len > 0) 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); LEDs_SetAllLEDs(LEDMASK_USB_READY);
} }
@ -244,13 +267,19 @@ void SetupHardware(void)
/* uIP Stack Initialization */ /* uIP Stack Initialization */
uip_init(); uip_init();
/* DHCP/Server IP Settings Initialization */
#if defined(ENABLE_DHCP)
DHCPApp_Init();
#else
uip_ipaddr_t IPAddress, Netmask, GatewayIPAddress; 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(&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(&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(&GatewayIPAddress, DEVICE_GATEWAY[0], DEVICE_GATEWAY[1], DEVICE_GATEWAY[2], DEVICE_GATEWAY[3]);
uip_sethostaddr(&IPAddress); uip_sethostaddr(&IPAddress);
uip_setnetmask(&Netmask); uip_setnetmask(&Netmask);
uip_setdraddr(&GatewayIPAddress); uip_setdraddr(&GatewayIPAddress);
#endif
/* HTTP Webserver Initialization */ /* HTTP Webserver Initialization */
WebserverApp_Init(); WebserverApp_Init();

@ -43,7 +43,6 @@
#include <avr/power.h> #include <avr/power.h>
#include <LUFA/Version.h> #include <LUFA/Version.h>
#include <LUFA/Drivers/Misc/TerminalCodes.h>
#include <LUFA/Drivers/Board/LEDs.h> #include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/RNDIS.h> #include <LUFA/Drivers/USB/Class/RNDIS.h>
@ -53,15 +52,18 @@
#include <timer.h> #include <timer.h>
#include "Lib/WebserverApp.h" #include "Lib/WebserverApp.h"
#include "Lib/DHCPApp.h"
/* Macros: */ /* 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} #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} #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} #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. */ /** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
@ -79,6 +81,9 @@
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */ /** LED mask for the library LED driver, to indicate that the USB interface is busy. */
#define LEDMASK_USB_BUSY LEDS_LED2 #define LEDMASK_USB_BUSY LEDS_LED2
/* External Variables: */
extern struct uip_eth_addr MACAddress;
/* Function Prototypes: */ /* Function Prototypes: */
void SetupHardware(void); void SetupHardware(void);
void ProcessIncommingPacket(void); void ProcessIncommingPacket(void);

@ -63,19 +63,25 @@
* <td><b>Description:</b></td> * <td><b>Description:</b></td>
* </tr> * </tr>
* <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>DEVICE_IP_ADDRESS</td>
* <td>Webserver.h</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>
* <tr> * <tr>
* <td>DEVICE_NETMASK</td> * <td>DEVICE_NETMASK</td>
* <td>Webserver.h</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>
* <tr> * <tr>
* <td>DEVICE_GATEWAY</td> * <td>DEVICE_GATEWAY</td>
* <td>Webserver.h</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> * </tr>
* </table> * </table>
*/ */

@ -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.) # List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \ SRC = $(TARGET).c \
Lib/DHCPApp.c \
Lib/WebserverApp.c \ Lib/WebserverApp.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c \ $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.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 # 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 = -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 # Place -D or -U options here for ASM sources

Loading…
Cancel
Save