Commit e8b8ed2b authored by Dean Camera's avatar Dean Camera
Browse files

Add TCP retransmission support to the HTTP webserver in the Webserver project,...

Add TCP retransmission support to the HTTP webserver in the Webserver project, so that lost segments are retransmitted as needed.
parent 254a0c1a
......@@ -14,7 +14,7 @@
/ Function and Buffer Configurations
/----------------------------------------------------------------------------*/
#define _FS_TINY 1 /* 0 or 1 */
#define _FS_TINY 0 /* 0 or 1 */
/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
/ object instead of the sector buffer in the individual file object for file
/ data transfer. This reduces memory consumption 512 bytes each file object. */
......
......@@ -96,17 +96,16 @@ void WebserverApp_Callback(void)
char* AppData = (char*)uip_appdata;
uint16_t AppDataSize = 0;
if (uip_aborted() || uip_timedout())
if (uip_aborted() || uip_timedout() || uip_closed())
{
/* Close the file before terminating, if it is open */
f_close(&AppState->FileToSend);
AppState->CurrentState = WEBSERVER_STATE_Closed;
return;
}
else if (uip_closed())
/* Check if the open file needs to be closed */
if (AppState->FileOpen)
{
f_close(&AppState->FileHandle);
AppState->FileOpen = false;
}
AppState->PrevState = WEBSERVER_STATE_Closed;
AppState->CurrentState = WEBSERVER_STATE_Closed;
return;
......@@ -114,14 +113,20 @@ void WebserverApp_Callback(void)
else if (uip_connected())
{
/* New connection - initialize connection state and data pointer to the appropriate HTTP header */
AppState->PrevState = WEBSERVER_STATE_OpenRequestedFile;
AppState->CurrentState = WEBSERVER_STATE_OpenRequestedFile;
}
else if (uip_rexmit())
{
/* Re-try last state */
AppState->CurrentState = AppState->PrevState;
}
switch (AppState->CurrentState)
{
case WEBSERVER_STATE_OpenRequestedFile:
/* Wait for the packet containing the request header */
if (uip_datalen())
if (uip_newdata())
{
/* Must be a GET request, abort otherwise */
if (strncmp(AppData, "GET ", (sizeof("GET ") - 1)) != 0)
......@@ -150,8 +155,10 @@ void WebserverApp_Callback(void)
strcpy(AppState->FileName, "index.htm");
/* Try to open the file from the Dataflash disk */
AppState->FileOpen = (f_open(&AppState->FileToSend, AppState->FileName, FA_OPEN_EXISTING | FA_READ) == FR_OK);
AppState->FileOpen = (f_open(&AppState->FileHandle, AppState->FileName, FA_OPEN_EXISTING | FA_READ) == FR_OK);
AppState->CurrentFilePos = 0;
AppState->PrevState = WEBSERVER_STATE_OpenRequestedFile;
AppState->CurrentState = WEBSERVER_STATE_SendResponseHeader;
}
......@@ -171,6 +178,7 @@ void WebserverApp_Callback(void)
uip_send(AppData, AppDataSize);
AppState->PrevState = WEBSERVER_STATE_SendResponseHeader;
AppState->CurrentState = WEBSERVER_STATE_SendMIMETypeHeader;
break;
case WEBSERVER_STATE_SendMIMETypeHeader:
......@@ -209,27 +217,41 @@ void WebserverApp_Callback(void)
uip_send(AppData, AppDataSize);
}
AppState->PrevState = WEBSERVER_STATE_SendMIMETypeHeader;
AppState->CurrentState = WEBSERVER_STATE_SendData;
break;
case WEBSERVER_STATE_SendData:
/* If end of file/file not open, progress to the close state */
if (!(AppState->FileOpen))
if (!(AppState->FileOpen) && !(uip_rexmit()))
{
f_close(&AppState->FileToSend);
f_close(&AppState->FileHandle);
uip_close();
AppState->PrevState = WEBSERVER_STATE_Closed;
AppState->CurrentState = WEBSERVER_STATE_Closed;
break;
}
uint16_t MaxSegSize = uip_mss();
/* Return file pointer to the last ACKed position if retransmitting */
f_lseek(&AppState->FileHandle, AppState->CurrentFilePos);
/* Read the next chunk of data from the open file */
f_read(&AppState->FileToSend, AppData, MaxSegSize, &AppDataSize);
AppState->FileOpen = (MaxSegSize == AppDataSize);
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_rexmit()))
AppState->CurrentFilePos += AppDataSize;
uip_send(AppData, AppDataSize);
}
AppState->PrevState = WEBSERVER_STATE_SendData;
break;
}
......
......@@ -52,7 +52,7 @@ void uIPManagement_Init(void)
{
/* uIP Timing Initialization */
clock_init();
timer_set(&ConnectionTimer, CLOCK_SECOND / 2);
timer_set(&ConnectionTimer, CLOCK_SECOND / 100);
timer_set(&ARPTimer, CLOCK_SECOND * 10);
/* uIP Stack Initialization */
......
......@@ -5,10 +5,13 @@
typedef struct
{
uint8_t PrevState;
uint8_t CurrentState;
FIL FileHandle;
char FileName[13];
FIL FileToSend;
bool FileOpen;
uint32_t CurrentFilePos;
} uip_tcp_appstate_t;
typedef struct
......
......@@ -45,10 +45,10 @@ USB_ClassInfo_RNDIS_Host_t Ethernet_RNDIS_Interface =
.Config =
{
.DataINPipeNumber = 1,
.DataINPipeDoubleBank = false,
.DataINPipeDoubleBank = true,
.DataOUTPipeNumber = 2,
.DataOUTPipeDoubleBank = false,
.DataOUTPipeDoubleBank = true,
.NotificationPipeNumber = 3,
.NotificationPipeDoubleBank = false,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment