aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2010-01-31 04:23:55 +0000
committerDean Camera <dean@fourwalledcubicle.com>2010-01-31 04:23:55 +0000
commit97f7cd947be1469c223d09b2e6573051f6629cee (patch)
tree9afd9e15a799d6dc5a31dcc1e1e4bfa769f74607
parente8b8ed2bad293b190c6b2ce9a575e73fbf93e9e2 (diff)
downloadlufa-97f7cd947be1469c223d09b2e6573051f6629cee.tar.gz
lufa-97f7cd947be1469c223d09b2e6573051f6629cee.tar.bz2
lufa-97f7cd947be1469c223d09b2e6573051f6629cee.zip
Better HTTP GET parsing in the Webserver demo, add application polling.
-rw-r--r--Projects/Benito/Benito.h1
-rw-r--r--Projects/Webserver/Lib/HTTPServerApp.c54
-rw-r--r--Projects/Webserver/Lib/HTTPServerApp.h3
-rw-r--r--Projects/Webserver/Lib/uIPManagement.c29
-rw-r--r--Projects/Webserver/Lib/uip/conf/apps-conf.h2
-rw-r--r--Projects/Webserver/Webserver.c6
-rw-r--r--Projects/Webserver/Webserver.txt3
7 files changed, 52 insertions, 46 deletions
diff --git a/Projects/Benito/Benito.h b/Projects/Benito/Benito.h
index 835079a3a..c6b534e42 100644
--- a/Projects/Benito/Benito.h
+++ b/Projects/Benito/Benito.h
@@ -40,7 +40,6 @@
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
- #include <avr/power.h>
#include "Descriptors.h"
#include "Lib/RingBuff.h"
diff --git a/Projects/Webserver/Lib/HTTPServerApp.c b/Projects/Webserver/Lib/HTTPServerApp.c
index 78c1b131c..5f0b2cfcd 100644
--- a/Projects/Webserver/Lib/HTTPServerApp.c
+++ b/Projects/Webserver/Lib/HTTPServerApp.c
@@ -112,9 +112,10 @@ void WebserverApp_Callback(void)
}
else if (uip_connected())
{
- /* New connection - initialize connection state and data pointer to the appropriate HTTP header */
+ /* New connection - initialize connection state values */
AppState->PrevState = WEBSERVER_STATE_OpenRequestedFile;
AppState->CurrentState = WEBSERVER_STATE_OpenRequestedFile;
+ AppState->FileOpen = false;
}
else if (uip_rexmit())
{
@@ -128,31 +129,25 @@ void WebserverApp_Callback(void)
/* Wait for the packet containing the request header */
if (uip_newdata())
{
+ char* RequestToken = strtok(AppData, " ");
+
/* Must be a GET request, abort otherwise */
- if (strncmp(AppData, "GET ", (sizeof("GET ") - 1)) != 0)
+ if (strcmp(RequestToken, "GET") != 0)
{
uip_abort();
break;
}
- /* Copy over the requested filename from the GET request as all-lowercase */
- for (uint8_t i = 0; i < (sizeof(AppState->FileName) - 1); i++)
- {
- AppState->FileName[i] = tolower(AppData[sizeof("GET ") + i]);
-
- if (AppState->FileName[i] == ' ')
- {
- AppState->FileName[i] = 0x00;
- break;
- }
- }
-
- /* Ensure requested filename is null-terminated */
- AppState->FileName[(sizeof(AppState->FileName) - 1)] = 0x00;
+ char* RequestedFileName = strtok(NULL, " ");
- /* If no filename specified, assume the default of index.htm */
- if (AppState->FileName[0] == 0x00)
+ /* If the requested filename has more that just the leading '/' path in it, copy it over */
+ if (strlen(RequestedFileName) > 1)
+ strncpy(AppState->FileName, &RequestedFileName[1], (sizeof(AppState->FileName) - 1));
+ else
strcpy(AppState->FileName, "index.htm");
+
+ /* Ensure filename is null-terminated */
+ AppState->FileName[(sizeof(AppState->FileName) - 1)] = 0x00;
/* Try to open the file from the Dataflash disk */
AppState->FileOpen = (f_open(&AppState->FileHandle, AppState->FileName, FA_OPEN_EXISTING | FA_READ) == FR_OK);
@@ -176,8 +171,6 @@ void WebserverApp_Callback(void)
strncpy_P(AppData, HTTP404Header, AppDataSize);
}
- uip_send(AppData, AppDataSize);
-
AppState->PrevState = WEBSERVER_STATE_SendResponseHeader;
AppState->CurrentState = WEBSERVER_STATE_SendMIMETypeHeader;
break;
@@ -213,8 +206,6 @@ void WebserverApp_Callback(void)
/* Add the end-of line terminator and end-of-headers terminator after the MIME type */
strncpy(&AppData[AppDataSize], "\r\n\r\n", sizeof("\r\n\r\n"));
AppDataSize += (sizeof("\r\n\r\n") - 1);
-
- uip_send(AppData, AppDataSize);
}
AppState->PrevState = WEBSERVER_STATE_SendMIMETypeHeader;
@@ -234,25 +225,26 @@ void WebserverApp_Callback(void)
uint16_t MaxSegSize = uip_mss();
- /* Return file pointer to the last ACKed position if retransmitting */
+ /* Return file pointer to the last ACKed position */
f_lseek(&AppState->FileHandle, AppState->CurrentFilePos);
/* Read the next chunk of data from the open file */
f_read(&AppState->FileHandle, AppData, MaxSegSize, &AppDataSize);
- AppState->FileOpen = (AppDataSize > 0);
- /* If data was read, send it to the client */
- if (AppDataSize)
+ /* If we are not re-transmitting a lost segment, advance file position */
+ if (uip_acked() && !(uip_rexmit()))
{
- /* If we are not re-transmitting a lost segment, advance file position */
- if (!(uip_rexmit()))
- AppState->CurrentFilePos += AppDataSize;
-
- uip_send(AppData, AppDataSize);
+ AppState->FileOpen = (AppDataSize > 0);
+ AppState->CurrentFilePos += AppDataSize;
}
+ /* Stay in the SendData state if retransmission is required until all data sent */
AppState->PrevState = WEBSERVER_STATE_SendData;
break;
}
+
+ /* If data has been loaded into the application buffer by the server, send it to the client */
+ if (AppDataSize)
+ uip_send(AppData, AppDataSize);
}
diff --git a/Projects/Webserver/Lib/HTTPServerApp.h b/Projects/Webserver/Lib/HTTPServerApp.h
index 7a4c87374..1ab64b323 100644
--- a/Projects/Webserver/Lib/HTTPServerApp.h
+++ b/Projects/Webserver/Lib/HTTPServerApp.h
@@ -39,9 +39,6 @@
/* Includes: */
#include <avr/pgmspace.h>
#include <string.h>
- #include <ctype.h>
-
- #include <LUFA/Version.h>
#include <uip.h>
#include <ff.h>
diff --git a/Projects/Webserver/Lib/uIPManagement.c b/Projects/Webserver/Lib/uIPManagement.c
index f00119372..c816dea6c 100644
--- a/Projects/Webserver/Lib/uIPManagement.c
+++ b/Projects/Webserver/Lib/uIPManagement.c
@@ -52,7 +52,7 @@ void uIPManagement_Init(void)
{
/* uIP Timing Initialization */
clock_init();
- timer_set(&ConnectionTimer, CLOCK_SECOND / 100);
+ timer_set(&ConnectionTimer, CLOCK_SECOND / 2);
timer_set(&ARPTimer, CLOCK_SECOND * 10);
/* uIP Stack Initialization */
@@ -97,13 +97,13 @@ static void uIPManagement_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[0], &uip_len);
+ RNDIS_Host_ReadPacket(&Ethernet_RNDIS_Interface, uip_buf, &uip_len);
if (uip_len > 0)
{
bool PacketHandled = true;
- struct uip_eth_hdr* EthernetHeader = (struct uip_eth_hdr*)&uip_buf[0];
+ struct uip_eth_hdr* EthernetHeader = (struct uip_eth_hdr*)uip_buf;
if (EthernetHeader->type == HTONS(UIP_ETHTYPE_IP))
{
/* Filter packet by MAC destination */
@@ -128,7 +128,7 @@ static void uIPManagement_ProcessIncommingPacket(void)
/* If a response was generated, send it */
if ((uip_len > 0) && PacketHandled)
- RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, &uip_buf[0], uip_len);
+ RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, uip_buf, uip_len);
}
LEDs_SetAllLEDs(LEDMASK_USB_READY);
@@ -138,7 +138,22 @@ static void uIPManagement_ProcessIncommingPacket(void)
/** Manages the currently open network connections, including TCP and (if enabled) UDP. */
static void uIPManagement_ManageConnections(void)
{
- /* Manage open connections */
+ /* Poll TCP connections for more data to send back to the host */
+ for (uint8_t i = 0; i < UIP_CONNS; i++)
+ {
+ uip_poll_conn(&uip_conns[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, uip_len);
+ }
+ }
+
+ /* Manage open connections for timeouts */
if (timer_expired(&ConnectionTimer))
{
timer_reset(&ConnectionTimer);
@@ -156,7 +171,7 @@ static void uIPManagement_ManageConnections(void)
/* Add destination MAC to outgoing packet */
uip_arp_out();
- RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, &uip_buf[0], uip_len);
+ RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, uip_buf, uip_len);
}
}
@@ -172,7 +187,7 @@ static void uIPManagement_ManageConnections(void)
/* Add destination MAC to outgoing packet */
uip_arp_out();
- RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, &uip_buf[0], uip_len);
+ RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, uip_buf, uip_len);
}
}
#endif
diff --git a/Projects/Webserver/Lib/uip/conf/apps-conf.h b/Projects/Webserver/Lib/uip/conf/apps-conf.h
index 88885a303..540fc33a8 100644
--- a/Projects/Webserver/Lib/uip/conf/apps-conf.h
+++ b/Projects/Webserver/Lib/uip/conf/apps-conf.h
@@ -9,7 +9,7 @@
uint8_t CurrentState;
FIL FileHandle;
- char FileName[13];
+ char FileName[50];
bool FileOpen;
uint32_t CurrentFilePos;
} uip_tcp_appstate_t;
diff --git a/Projects/Webserver/Webserver.c b/Projects/Webserver/Webserver.c
index 47fd9c7e5..541e0e2c5 100644
--- a/Projects/Webserver/Webserver.c
+++ b/Projects/Webserver/Webserver.c
@@ -47,8 +47,10 @@ int main(void)
for (;;)
{
- USBDeviceMode_USBTask();
- USBHostMode_USBTask();
+ if (USB_CurrentMode == USB_MODE_HOST)
+ USBHostMode_USBTask();
+ else
+ USBDeviceMode_USBTask();
USB_USBTask();
}
diff --git a/Projects/Webserver/Webserver.txt b/Projects/Webserver/Webserver.txt
index f13c17f5b..5b62f067c 100644
--- a/Projects/Webserver/Webserver.txt
+++ b/Projects/Webserver/Webserver.txt
@@ -54,7 +54,8 @@
*
* 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
- * <i>index.htm</i>. Filenames must be in 8.3 format for them to be retrieved correctly by the webserver.
+ * <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 50 characters.
*
* 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. The device IP,