Add TCP retransmission support to the HTTP webserver in the Webserver project, so...
authorDean Camera <dean@fourwalledcubicle.com>
Fri, 29 Jan 2010 09:21:38 +0000 (09:21 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Fri, 29 Jan 2010 09:21:38 +0000 (09:21 +0000)
Projects/Webserver/Lib/FATFs/ffconf.h
Projects/Webserver/Lib/HTTPServerApp.c
Projects/Webserver/Lib/uIPManagement.c
Projects/Webserver/Lib/uip/conf/apps-conf.h
Projects/Webserver/USBHostMode.c

index 4b19f13..3ad7a56 100644 (file)
@@ -14,7 +14,7 @@
 / Function and Buffer Configurations\r
 /----------------------------------------------------------------------------*/\r
 \r
-#define        _FS_TINY        1               /* 0 or 1 */\r
+#define        _FS_TINY        0               /* 0 or 1 */\r
 /* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system\r
 /  object instead of the sector buffer in the individual file object for file\r
 /  data transfer. This reduces memory consumption 512 bytes each file object. */\r
index 3f8a2c3..78c1b13 100644 (file)
@@ -96,17 +96,16 @@ void WebserverApp_Callback(void)
        char*                     AppData     = (char*)uip_appdata;\r
        uint16_t                  AppDataSize = 0;\r
 \r
-       if (uip_aborted() || uip_timedout())\r
+       if (uip_aborted() || uip_timedout() || uip_closed())\r
        {\r
-               /* Close the file before terminating, if it is open */\r
-               f_close(&AppState->FileToSend);\r
+               /* Check if the open file needs to be closed */\r
+               if (AppState->FileOpen)\r
+               {\r
+                       f_close(&AppState->FileHandle);\r
+                       AppState->FileOpen = false;\r
+               }\r
 \r
-               AppState->CurrentState = WEBSERVER_STATE_Closed;\r
-\r
-               return;\r
-       }\r
-       else if (uip_closed())\r
-       {\r
+               AppState->PrevState    = WEBSERVER_STATE_Closed;\r
                AppState->CurrentState = WEBSERVER_STATE_Closed;\r
 \r
                return;\r
@@ -114,14 +113,20 @@ void WebserverApp_Callback(void)
        else if (uip_connected())\r
        {\r
                /* New connection - initialize connection state and data pointer to the appropriate HTTP header */\r
+               AppState->PrevState    = WEBSERVER_STATE_OpenRequestedFile;\r
                AppState->CurrentState = WEBSERVER_STATE_OpenRequestedFile;\r
        }\r
+       else if (uip_rexmit())\r
+       {\r
+               /* Re-try last state */\r
+               AppState->CurrentState = AppState->PrevState;\r
+       }\r
        \r
        switch (AppState->CurrentState)\r
        {\r
                case WEBSERVER_STATE_OpenRequestedFile:\r
                        /* Wait for the packet containing the request header */\r
-                       if (uip_datalen())\r
+                       if (uip_newdata())\r
                        {\r
                                /* Must be a GET request, abort otherwise */\r
                                if (strncmp(AppData, "GET ", (sizeof("GET ") - 1)) != 0)\r
@@ -150,8 +155,10 @@ void WebserverApp_Callback(void)
                                  strcpy(AppState->FileName, "index.htm");\r
                                \r
                                /* Try to open the file from the Dataflash disk */\r
-                               AppState->FileOpen = (f_open(&AppState->FileToSend, AppState->FileName, FA_OPEN_EXISTING | FA_READ) == FR_OK);\r
+                               AppState->FileOpen       = (f_open(&AppState->FileHandle, AppState->FileName, FA_OPEN_EXISTING | FA_READ) == FR_OK);\r
+                               AppState->CurrentFilePos = 0;\r
 \r
+                               AppState->PrevState    = WEBSERVER_STATE_OpenRequestedFile;\r
                                AppState->CurrentState = WEBSERVER_STATE_SendResponseHeader;\r
                        }\r
 \r
@@ -171,6 +178,7 @@ void WebserverApp_Callback(void)
                        \r
                        uip_send(AppData, AppDataSize);\r
                        \r
+                       AppState->PrevState    = WEBSERVER_STATE_SendResponseHeader;\r
                        AppState->CurrentState = WEBSERVER_STATE_SendMIMETypeHeader;\r
                        break;\r
                case WEBSERVER_STATE_SendMIMETypeHeader:\r
@@ -209,28 +217,42 @@ void WebserverApp_Callback(void)
                                uip_send(AppData, AppDataSize);\r
                        }\r
                                \r
+                       AppState->PrevState    = WEBSERVER_STATE_SendMIMETypeHeader;\r
                        AppState->CurrentState = WEBSERVER_STATE_SendData;                              \r
                        break;\r
                case WEBSERVER_STATE_SendData:\r
                        /* If end of file/file not open, progress to the close state */\r
-                       if (!(AppState->FileOpen))\r
+                       if (!(AppState->FileOpen) && !(uip_rexmit()))\r
                        {\r
-                               f_close(&AppState->FileToSend);\r
+                               f_close(&AppState->FileHandle);\r
                                uip_close();\r
+\r
+                               AppState->PrevState    = WEBSERVER_STATE_Closed;\r
                                AppState->CurrentState = WEBSERVER_STATE_Closed;\r
                                break;\r
                        }\r
 \r
                        uint16_t MaxSegSize = uip_mss();\r
                        \r
+                       /* Return file pointer to the last ACKed position if retransmitting */\r
+                       f_lseek(&AppState->FileHandle, AppState->CurrentFilePos);\r
+\r
                        /* Read the next chunk of data from the open file */\r
-                       f_read(&AppState->FileToSend, AppData, MaxSegSize, &AppDataSize);\r
-                       AppState->FileOpen = (MaxSegSize == AppDataSize);\r
+                       f_read(&AppState->FileHandle, AppData, MaxSegSize, &AppDataSize);\r
+                       AppState->FileOpen = (AppDataSize > 0);\r
 \r
                        /* If data was read, send it to the client */\r
                        if (AppDataSize)\r
-                         uip_send(AppData, AppDataSize);\r
-                                       \r
+                       {\r
+                               /* If we are not re-transmitting a lost segment, advance file position */\r
+                               if (!(uip_rexmit()))\r
+                                 AppState->CurrentFilePos += AppDataSize;\r
+\r
+                               uip_send(AppData, AppDataSize);\r
+                       }\r
+                       \r
+                       AppState->PrevState = WEBSERVER_STATE_SendData;\r
+\r
                        break;\r
        }\r
 }\r
index dd9f15f..f001193 100644 (file)
@@ -52,7 +52,7 @@ void uIPManagement_Init(void)
 {\r
        /* uIP Timing Initialization */\r
        clock_init();\r
-       timer_set(&ConnectionTimer, CLOCK_SECOND / 2);\r
+       timer_set(&ConnectionTimer, CLOCK_SECOND / 100);\r
        timer_set(&ARPTimer, CLOCK_SECOND * 10);        \r
 \r
        /* uIP Stack Initialization */\r
index 63a445c..88885a3 100644 (file)
@@ -5,10 +5,13 @@
 \r
        typedef struct\r
        {\r
+               uint8_t PrevState;\r
                uint8_t CurrentState;\r
+               \r
+               FIL     FileHandle;\r
                char    FileName[13];\r
-               FIL     FileToSend;\r
                bool    FileOpen;\r
+               uint32_t CurrentFilePos;\r
        } uip_tcp_appstate_t;\r
 \r
        typedef struct\r
index 14f33e0..b8e2dce 100644 (file)
@@ -45,10 +45,10 @@ USB_ClassInfo_RNDIS_Host_t Ethernet_RNDIS_Interface =
                .Config =\r
                        {\r
                                .DataINPipeNumber           = 1,\r
-                               .DataINPipeDoubleBank       = false,\r
+                               .DataINPipeDoubleBank       = true,\r
 \r
                                .DataOUTPipeNumber          = 2,\r
-                               .DataOUTPipeDoubleBank      = false,\r
+                               .DataOUTPipeDoubleBank      = true,\r
 \r
                                .NotificationPipeNumber     = 3,\r
                                .NotificationPipeDoubleBank = false,\r