From 03ee87b35abdb8b92e8b55ec040fa943f9a6786c Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Thu, 21 Jan 2010 13:45:44 +0000 Subject: [PATCH] Fix up the incomplete Webserver project so that it integrates with the uIP stack correctly. Add simple HTTP webserver as a placeholder until FatFS can be integrated. Begin to look into the RNDIS Host Class Driver, which seems to crash on test hardware after many packets have been received. --- .../ClassDriver/RNDISEthernet/Lib/Webserver.c | 5 +- .../LowLevel/RNDISEthernet/Lib/Webserver.c | 3 + LUFA.pnproj | 2 +- LUFA/ManPages/ChangeLog.txt | 2 +- .../Incomplete/Webserver/Lib/WebserverApp.c | 131 ++++++++++++++++++ .../Incomplete/Webserver/Lib/WebserverApp.h | 50 +++++++ .../Webserver/Lib/uip/conf/apps-conf.h | 25 ++-- .../Webserver/Lib/uip/conf/uip-conf.h | 11 +- Projects/Incomplete/Webserver/Webserver.c | 80 +++++------ Projects/Incomplete/Webserver/Webserver.h | 9 +- Projects/Incomplete/Webserver/makefile | 1 + 11 files changed, 249 insertions(+), 70 deletions(-) create mode 100644 Projects/Incomplete/Webserver/Lib/WebserverApp.c create mode 100644 Projects/Incomplete/Webserver/Lib/WebserverApp.h diff --git a/Demos/Device/ClassDriver/RNDISEthernet/Lib/Webserver.c b/Demos/Device/ClassDriver/RNDISEthernet/Lib/Webserver.c index dff684b317..7f2502027e 100644 --- a/Demos/Device/ClassDriver/RNDISEthernet/Lib/Webserver.c +++ b/Demos/Device/ClassDriver/RNDISEthernet/Lib/Webserver.c @@ -43,7 +43,10 @@ char PROGMEM HTTP200Header[] = "HTTP/1.1 200 OK\r\n" "Server: LUFA RNDIS\r\n" "Content-type: text/html\r\n" "Connection: close\r\n\r\n"; - + +/** HTTP server response header, for transmission before a resource not found error. This indicates to the host that the given + * given URL is invalid, and gives extra error information. + */ char PROGMEM HTTP404Header[] = "HTTP/1.1 404 Not Found\r\n" "Server: LUFA RNDIS\r\n" "Connection: close\r\n\r\n"; diff --git a/Demos/Device/LowLevel/RNDISEthernet/Lib/Webserver.c b/Demos/Device/LowLevel/RNDISEthernet/Lib/Webserver.c index bf67b5d3a6..7ba1928818 100644 --- a/Demos/Device/LowLevel/RNDISEthernet/Lib/Webserver.c +++ b/Demos/Device/LowLevel/RNDISEthernet/Lib/Webserver.c @@ -44,6 +44,9 @@ char PROGMEM HTTP200Header[] = "HTTP/1.1 200 OK\r\n" "Content-type: text/html\r\n" "Connection: close\r\n\r\n"; +/** HTTP server response header, for transmission before a resource not found error. This indicates to the host that the given + * given URL is invalid, and gives extra error information. + */ char PROGMEM HTTP404Header[] = "HTTP/1.1 404 Not Found\r\n" "Server: LUFA RNDIS\r\n" "Connection: close\r\n\r\n"; diff --git a/LUFA.pnproj b/LUFA.pnproj index 3af9dc1dec..54dce2e1ef 100644 --- a/LUFA.pnproj +++ b/LUFA.pnproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index 74571e4c3f..6a2126fb4c 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -20,7 +20,7 @@ * - Added master mode hardware TWI driver * * Changed: - * - Slowed down PDI programming in the AVRISP project to prevent transmission errors + * - Slowed down software USART carried PDI programming in the AVRISP project to prevent transmission errors * - Renamed the AVRISP project folder to AVRISP-MKII to reduce confusion * - Renamed the RESET_LINE_* makefile tokens in the AVRISP MKII Project to AUX_LINE_*, as they are not always used for target * reset diff --git a/Projects/Incomplete/Webserver/Lib/WebserverApp.c b/Projects/Incomplete/Webserver/Lib/WebserverApp.c new file mode 100644 index 0000000000..97218b2be4 --- /dev/null +++ b/Projects/Incomplete/Webserver/Lib/WebserverApp.c @@ -0,0 +1,131 @@ +/* + 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 + * + * Simple HTTP Webserver Application. When connected to the uIP stack, + * this will serve out files to HTTP clients. + */ + +#include "WebserverApp.h" + +/** HTTP server response header, for transmission before the page contents. This indicates to the host that a page exists at the + * given location, and gives extra connection information. + */ +char PROGMEM HTTP200Header[] = "HTTP/1.1 200 OK\r\n" + "Server: LUFA RNDIS\r\n" + "Content-type: text/html\r\n" + "Connection: close\r\n\r\n"; + +/** HTTP server response header, for transmission before a resource not found error. This indicates to the host that the given + * given URL is invalid, and gives extra error information. + */ +char PROGMEM HTTP404Header[] = "HTTP/1.1 404 Not Found\r\n" + "Server: LUFA RNDIS\r\n" + "Connection: close\r\n\r\n"; + +/****************************************************************************************/ +/** HTTP page to serve to the host when a HTTP request is made. This page is too long for a single response, thus it is automatically + * broken up into smaller blocks and sent as a series of packets each time the webserver application callback is run. + */ +char PROGMEM HTTPPage[] = + "" + " " + " " + " LUFA Webserver Demo" + " " + " " + " " + "

Hello from your USB AVR!

" + "

" + " Hello! Welcome to the LUFA RNDIS Demo Webserver test page, running on your USB AVR via the LUFA library. This demonstrates the HTTP webserver, TCP/IP stack and RNDIS demo all running atop the LUFA USB stack." + "

" + " Project Information: http://www.fourwalledcubicle.com/LUFA.php." + "


" + " LUFA Version: " LUFA_VERSION_STRING + "

" + " " + ""; + +void WebserverAppCallback(void) +{ + char* AppDataPtr = (char*)uip_appdata; + uint16_t AppDataSize = 0; + + if (uip_closed() || uip_aborted() || uip_timedout()) + { + /* Terminated or completed connection - don't send any new data */ + return; + } + 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; + } + + /* Calculate the maximum segment size and remaining data size */ + uint16_t BytesRemaining = strlen_P(uip_conn->appstate.SendPos); + uint16_t MaxSegSize = uip_mss(); + + /* No more bytes remaining in the current data being sent - progress to next data chunk or + * terminate the connection once all chunks are sent */ + if (!(BytesRemaining)) + { + /* Check which data chunk we are currently sending (header or data) */ + if (uip_conn->appstate.CurrentState == WEBSERVER_STATE_SendHeaders) + { + uip_conn->appstate.SendPos = HTTPPage; + uip_conn->appstate.CurrentState = WEBSERVER_STATE_SendData; + } + else if (uip_conn->appstate.CurrentState == WEBSERVER_STATE_SendData) + { + uip_close(); + uip_conn->appstate.CurrentState = WEBSERVER_STATE_Closed; + } + + return; + } + else if (BytesRemaining > MaxSegSize) + { + AppDataSize = MaxSegSize; + } + else + { + AppDataSize = BytesRemaining; + } + + /* 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; + + /* Send the data to the requesting host */ + uip_send(AppDataPtr, AppDataSize); +} diff --git a/Projects/Incomplete/Webserver/Lib/WebserverApp.h b/Projects/Incomplete/Webserver/Lib/WebserverApp.h new file mode 100644 index 0000000000..b2696b28fb --- /dev/null +++ b/Projects/Incomplete/Webserver/Lib/WebserverApp.h @@ -0,0 +1,50 @@ +/* + 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 WebserverApp.c. + */ + +#ifndef _WEBSERVER_APP_H_ +#define _WEBSERVER_APP_H_ + + /* Includes: */ + #include + #include + + #include + + #include + + /* Function Prototypes: */ + void WebserverAppCallback(void); + +#endif diff --git a/Projects/Incomplete/Webserver/Lib/uip/conf/apps-conf.h b/Projects/Incomplete/Webserver/Lib/uip/conf/apps-conf.h index 60a7c9eb02..00919f2210 100644 --- a/Projects/Incomplete/Webserver/Lib/uip/conf/apps-conf.h +++ b/Projects/Incomplete/Webserver/Lib/uip/conf/apps-conf.h @@ -1,15 +1,20 @@ #ifndef __APPS_CONF_H__ #define __APPS_CONF_H__ -//Here we include the header file for the application(s) we use in our project. - -//#include "smtp.h" -//#include "hello-world.h" -//#include "simple-httpd.h" -//#include "telnetd.h" -//#include "webserver.h" -//#include "dhcpc.h" -//#include "resolv.h" -//#include "webclient.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; + + #define UIP_APPCALL WebserverAppCallback + void UIP_APPCALL(void); #endif /*__APPS_CONF_H__*/ diff --git a/Projects/Incomplete/Webserver/Lib/uip/conf/uip-conf.h b/Projects/Incomplete/Webserver/Lib/uip/conf/uip-conf.h index d46fa265cf..d3d9bc4535 100644 --- a/Projects/Incomplete/Webserver/Lib/uip/conf/uip-conf.h +++ b/Projects/Incomplete/Webserver/Lib/uip/conf/uip-conf.h @@ -6,15 +6,6 @@ #include #include -typedef int uip_tcp_appstate_t; -typedef int uip_udp_appstate_t; - -#define UIP_APPCALL TCPCallback -#define UIP_UDP_APPCALL TCPCallback - -void UIP_APPCALL(void); -void UIP_UDP_APPCALL(void); - #define UIP_CONF_LLH_LEN 14 /** @@ -68,7 +59,7 @@ typedef unsigned short uip_stats_t; * * \hideinitializer */ -#define UIP_CONF_BUFFER_SIZE 1100 +#define UIP_CONF_BUFFER_SIZE 1500 /** * CPU byte order. * diff --git a/Projects/Incomplete/Webserver/Webserver.c b/Projects/Incomplete/Webserver/Webserver.c index c706fd08a0..74636b8a55 100644 --- a/Projects/Incomplete/Webserver/Webserver.c +++ b/Projects/Incomplete/Webserver/Webserver.c @@ -31,7 +31,7 @@ /** \file * * Main source file for the Webserver project. This file contains the main tasks of - * the demo and is responsible for the initial application hardware configuration. + * the project and is responsible for the initial application hardware configuration. */ #include "Webserver.h" @@ -57,20 +57,13 @@ USB_ClassInfo_RNDIS_Host_t Ethernet_RNDIS_Interface = }, }; -struct timer ConnectionTimer, ARPTimer; -uint16_t MillisecondTickCount; +/** Connection timer, to retain the time elapsed since the last time the uIP connections were managed. */ +struct timer ConnectionTimer; + +/** ARP timer, to retain the time elapsed since the ARP cache was last updated. */ +struct timer ARPTimer; -/** ISR for the management of the connection management timeout counter */ -ISR(TIMER0_COMPA_vect, ISR_BLOCK) -{ - MillisecondTickCount++; -} -void TCPCallback(void) -{ - printf("Callback!\r\n"); -} - /** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ @@ -129,7 +122,7 @@ int main(void) printf("Device Max Transfer Size: %lu bytes.\r\n", Ethernet_RNDIS_Interface.State.DeviceMaxPacketSize); - uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST | REMOTE_NDIS_PACKET_ALL_MULTICAST); + uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST); if (RNDIS_Host_SetRNDISProperty(&Ethernet_RNDIS_Interface, OID_GEN_CURRENT_PACKET_FILTER, &PacketFilter, sizeof(PacketFilter)) != HOST_SENDCONTROL_Successful) { @@ -157,6 +150,8 @@ int main(void) uip_setethaddr(MACAddress); + LEDs_SetAllLEDs(LEDMASK_USB_READY); + printf("RNDIS Device Enumerated.\r\n"); USB_HostState = HOST_STATE_Configured; break; @@ -179,40 +174,39 @@ void ProcessIncommingPacket(void) LEDs_SetAllLEDs(LEDMASK_USB_BUSY); /* Read the incomming packet straight into the UIP packet buffer */ - RNDIS_Host_ReadPacket(&Ethernet_RNDIS_Interface, uip_buf, &uip_len); - - printf("RECEIVED PACKET (%d):\r\n", uip_len); - for (uint16_t i = 0; i < uip_len; i++) - printf("0x%02X ", uip_buf[i]); - printf("\r\n\r\n"); + printf("L=%d R=%d\r\n", uip_len, RNDIS_Host_ReadPacket(&Ethernet_RNDIS_Interface, &uip_buf[0], &uip_len)); - struct uip_eth_hdr* EthernetHeader = (struct uip_eth_hdr*)&uip_buf[0]; - if (EthernetHeader->type == HTONS(UIP_ETHTYPE_IP)) + if (uip_len > 0) { - /* Filter packet by MAC destination */ - uip_arp_ipin(); + bool PacketHandled = true; - /* Process incomming packet */ - uip_input(); + struct uip_eth_hdr* EthernetHeader = (struct uip_eth_hdr*)&uip_buf[0]; + if (EthernetHeader->type == HTONS(UIP_ETHTYPE_IP)) + { + /* Filter packet by MAC destination */ + uip_arp_ipin(); - /* Add destination MAC to outgoing packet */ - if (uip_len > 0) - uip_arp_out(); - } - else if (EthernetHeader->type == HTONS(UIP_ETHTYPE_ARP)) - { - /* Process ARP packet */ - uip_arp_arpin(); - } + /* Process incomming packet */ + uip_input(); - /* If a response was generated, send it */ - if (uip_len > 0) - RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, uip_buf, uip_len); + /* Add destination MAC to outgoing packet */ + if (uip_len > 0) + uip_arp_out(); + } + else if (EthernetHeader->type == HTONS(UIP_ETHTYPE_ARP)) + { + /* Process ARP packet */ + uip_arp_arpin(); + } + else + { + PacketHandled = false; + } - printf("SENT PACKET (%d):\r\n", uip_len); - for (uint16_t i = 0; i < uip_len; i++) - printf("0x%02X ", uip_buf[i]); - printf("\r\n\r\n"); + /* If a response was generated, send it */ + if ((uip_len > 0) && PacketHandled) + RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, &uip_buf[0], uip_len); + } LEDs_SetAllLEDs(LEDMASK_USB_READY); } @@ -234,7 +228,7 @@ void ManageConnections(void) /* If a response was generated, send it */ if (uip_len > 0) - RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, uip_buf, uip_len); + RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, &uip_buf[0], uip_len); } LEDs_SetAllLEDs(LEDMASK_USB_READY); diff --git a/Projects/Incomplete/Webserver/Webserver.h b/Projects/Incomplete/Webserver/Webserver.h index ef17d4c872..a2744b8273 100644 --- a/Projects/Incomplete/Webserver/Webserver.h +++ b/Projects/Incomplete/Webserver/Webserver.h @@ -30,11 +30,11 @@ /** \file * - * Header file for RNDISEthernetHost.c. + * Header file for Webserver.c. */ -#ifndef _RNDIS_HOST_H_ -#define _RNDIS_HOST_H_ +#ifndef _WEBSERVER_H_ +#define _WEBSERVER_H_ /* Includes: */ #include @@ -54,6 +54,8 @@ #include #include + #include "Lib/WebserverApp.h" + /* Macros: */ /** LED mask for the library LED driver, to indicate that the USB interface is not ready. */ #define LEDMASK_USB_NOTREADY LEDS_LED1 @@ -74,7 +76,6 @@ void SetupHardware(void); void ProcessIncommingPacket(void); void ManageConnections(void); - void TCPCallback(void); void EVENT_USB_Host_HostError(const uint8_t ErrorCode); void EVENT_USB_Host_DeviceAttached(void); diff --git a/Projects/Incomplete/Webserver/makefile b/Projects/Incomplete/Webserver/makefile index b51e510b6e..1e464a040d 100644 --- a/Projects/Incomplete/Webserver/makefile +++ b/Projects/Incomplete/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/WebserverApp.c \ $(LUFA_PATH)/LUFA/Drivers/Peripheral/SerialStream.c \ $(LUFA_PATH)/LUFA/Drivers/Peripheral/Serial.c \ $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c \