Re-add Webserver uIP application polling, apply patch to uIP by Andrew Ruder to fix...
[pub/USBasp.git] / Projects / Webserver / Lib / HTTPServerApp.c
index 7d29272..081207c 100644 (file)
@@ -43,8 +43,8 @@
 char PROGMEM HTTP200Header[] = "HTTP/1.1 200 OK\r\n"\r
                                "Server: LUFA RNDIS\r\n"\r
                                "Connection: close\r\n"\r
 char PROGMEM HTTP200Header[] = "HTTP/1.1 200 OK\r\n"\r
                                "Server: LUFA RNDIS\r\n"\r
                                "Connection: close\r\n"\r
-                                                          "MIME-version: 1.0\r\n"\r
-                                                          "Content-Type: ";\r
+                               "MIME-version: 1.0\r\n"\r
+                               "Content-Type: ";\r
 \r
 /** HTTP server response header, for transmission before a resource not found error. This indicates to the host that the given\r
  *  given URL is invalid, and gives extra error information.\r
 \r
 /** HTTP server response header, for transmission before a resource not found error. This indicates to the host that the given\r
  *  given URL is invalid, and gives extra error information.\r
@@ -52,14 +52,14 @@ char PROGMEM HTTP200Header[] = "HTTP/1.1 200 OK\r\n"
 char PROGMEM HTTP404Header[] = "HTTP/1.1 404 Not Found\r\n"\r
                                "Server: LUFA RNDIS\r\n"\r
                                "Connection: close\r\n"\r
 char PROGMEM HTTP404Header[] = "HTTP/1.1 404 Not Found\r\n"\r
                                "Server: LUFA RNDIS\r\n"\r
                                "Connection: close\r\n"\r
-                                                          "MIME-version: 1.0\r\n"\r
-                                                          "Content-Type: text/plain\r\n\r\n"\r
-                                                          "Error 404: File Not Found";\r
+                               "MIME-version: 1.0\r\n"\r
+                               "Content-Type: text/plain\r\n\r\n"\r
+                               "Error 404: File Not Found";\r
 \r
 /** Default MIME type sent if no other MIME type can be determined */\r
 char PROGMEM DefaultMIMEType[] = "text/plain";\r
 \r
 \r
 /** Default MIME type sent if no other MIME type can be determined */\r
 char PROGMEM DefaultMIMEType[] = "text/plain";\r
 \r
-/** List of MIME types for each supported file extension - must be terminated with \ref END_OF_MIME_LIST entry. */\r
+/** List of MIME types for each supported file extension. */\r
 MIME_Type_t PROGMEM MIMETypes[] =\r
        {\r
                {.Extension = "htm", .MIMEType = "text/html"},\r
 MIME_Type_t PROGMEM MIMETypes[] =\r
        {\r
                {.Extension = "htm", .MIMEType = "text/html"},\r
@@ -67,9 +67,9 @@ MIME_Type_t PROGMEM MIMETypes[] =
                {.Extension = "gif", .MIMEType = "image/gif"},\r
                {.Extension = "bmp", .MIMEType = "image/bmp"},\r
                {.Extension = "png", .MIMEType = "image/png"},\r
                {.Extension = "gif", .MIMEType = "image/gif"},\r
                {.Extension = "bmp", .MIMEType = "image/bmp"},\r
                {.Extension = "png", .MIMEType = "image/png"},\r
+               {.Extension = "ico", .MIMEType = "image/x-icon"},\r
                {.Extension = "exe", .MIMEType = "application/octet-stream"},\r
                {.Extension = "gz",  .MIMEType = "application/x-gzip"},\r
                {.Extension = "exe", .MIMEType = "application/octet-stream"},\r
                {.Extension = "gz",  .MIMEType = "application/x-gzip"},\r
-               {.Extension = "ico", .MIMEType = "image/x-icon"},\r
                {.Extension = "zip", .MIMEType = "application/zip"},\r
                {.Extension = "pdf", .MIMEType = "application/pdf"},\r
        };\r
                {.Extension = "zip", .MIMEType = "application/zip"},\r
                {.Extension = "pdf", .MIMEType = "application/pdf"},\r
        };\r
@@ -79,7 +79,7 @@ FATFS DiskFATState;
 \r
 \r
 /** Initialization function for the simple HTTP webserver. */\r
 \r
 \r
 /** Initialization function for the simple HTTP webserver. */\r
-void WebserverApp_Init(void)\r
+void HTTPServerApp_Init(void)\r
 {\r
        /* Listen on port 80 for HTTP connections from hosts */\r
        uip_listen(HTONS(HTTP_SERVER_PORT));\r
 {\r
        /* Listen on port 80 for HTTP connections from hosts */\r
        uip_listen(HTONS(HTTP_SERVER_PORT));\r
@@ -91,63 +91,60 @@ void WebserverApp_Init(void)
 /** uIP stack application callback for the simple HTTP webserver. This function must be called each time the\r
  *  TCP/IP stack needs a TCP packet to be processed.\r
  */\r
 /** uIP stack application callback for the simple HTTP webserver. This function must be called each time the\r
  *  TCP/IP stack needs a TCP packet to be processed.\r
  */\r
-void WebserverApp_Callback(void)\r
+void HTTPServerApp_Callback(void)\r
 {\r
        uip_tcp_appstate_t* const AppState = &uip_conn->appstate;\r
 \r
        if (uip_aborted() || uip_timedout() || uip_closed())\r
        {\r
 {\r
        uip_tcp_appstate_t* const AppState = &uip_conn->appstate;\r
 \r
        if (uip_aborted() || uip_timedout() || uip_closed())\r
        {\r
-               /* Connection is being terminated for some reason - close file handle if open */\r
-               if (AppState->FileOpen)\r
-               {\r
-                       f_close(&AppState->FileHandle);\r
-                       AppState->FileOpen = false;\r
-               }\r
+               /* Connection is being terminated for some reason - close file handle */\r
+               f_close(&AppState->HTTPServer.FileHandle);\r
+               AppState->HTTPServer.FileOpen = false;\r
                \r
                /* Lock to the closed state so that no further processing will occur on the connection */\r
                \r
                /* Lock to the closed state so that no further processing will occur on the connection */\r
-               AppState->CurrentState  = WEBSERVER_STATE_Closed;\r
-               AppState->NextState     = WEBSERVER_STATE_Closed;\r
+               AppState->HTTPServer.CurrentState  = WEBSERVER_STATE_Closed;\r
+               AppState->HTTPServer.NextState     = WEBSERVER_STATE_Closed;\r
        }\r
 \r
        if (uip_connected())\r
        {\r
                /* New connection - initialize connection state values */\r
        }\r
 \r
        if (uip_connected())\r
        {\r
                /* New connection - initialize connection state values */\r
-               AppState->CurrentState  = WEBSERVER_STATE_OpenRequestedFile;\r
-               AppState->NextState     = WEBSERVER_STATE_OpenRequestedFile;\r
-               AppState->FileOpen      = false;\r
-               AppState->ACKedFilePos  = 0;\r
-               AppState->SentChunkSize = 0;\r
+               AppState->HTTPServer.CurrentState  = WEBSERVER_STATE_OpenRequestedFile;\r
+               AppState->HTTPServer.NextState     = WEBSERVER_STATE_OpenRequestedFile;\r
+               AppState->HTTPServer.FileOpen      = false;\r
+               AppState->HTTPServer.ACKedFilePos  = 0;\r
+               AppState->HTTPServer.SentChunkSize = 0;\r
        }\r
 \r
        if (uip_acked())\r
        {\r
                /* Add the amount of ACKed file data to the total sent file bytes counter */\r
        }\r
 \r
        if (uip_acked())\r
        {\r
                /* Add the amount of ACKed file data to the total sent file bytes counter */\r
-               AppState->ACKedFilePos += AppState->SentChunkSize;\r
+               AppState->HTTPServer.ACKedFilePos += AppState->HTTPServer.SentChunkSize;\r
 \r
                /* Progress to the next state once the current state's data has been ACKed */\r
 \r
                /* Progress to the next state once the current state's data has been ACKed */\r
-               AppState->CurrentState = AppState->NextState;\r
+               AppState->HTTPServer.CurrentState = AppState->HTTPServer.NextState;\r
        }\r
 \r
        }\r
 \r
-       if (uip_rexmit() || uip_newdata() || uip_acked() || uip_connected() || uip_poll())\r
+       if (uip_rexmit() || uip_acked() || uip_newdata() || uip_connected() || uip_poll())\r
        {\r
        {\r
-               switch (AppState->CurrentState)\r
+               switch (AppState->HTTPServer.CurrentState)\r
                {\r
                        case WEBSERVER_STATE_OpenRequestedFile:\r
                {\r
                        case WEBSERVER_STATE_OpenRequestedFile:\r
-                               Webserver_OpenRequestedFile();\r
+                               HTTPServerApp_OpenRequestedFile();\r
                                break;\r
                        case WEBSERVER_STATE_SendResponseHeader:\r
                                break;\r
                        case WEBSERVER_STATE_SendResponseHeader:\r
-                               Webserver_SendResponseHeader();\r
+                               HTTPServerApp_SendResponseHeader();\r
                                break;\r
                        case WEBSERVER_STATE_SendMIMETypeHeader:\r
                                break;\r
                        case WEBSERVER_STATE_SendMIMETypeHeader:\r
-                               Webserver_SendMIMETypeHeader(); \r
+                               HTTPServerApp_SendMIMETypeHeader();     \r
                                break;\r
                        case WEBSERVER_STATE_SendData:\r
                                break;\r
                        case WEBSERVER_STATE_SendData:\r
-                               Webserver_SendData();\r
+                               HTTPServerApp_SendData();\r
                                break;\r
                        case WEBSERVER_STATE_Closing:\r
                                uip_close();\r
                                \r
                                break;\r
                        case WEBSERVER_STATE_Closing:\r
                                uip_close();\r
                                \r
-                               AppState->NextState = WEBSERVER_STATE_Closed;\r
+                               AppState->HTTPServer.NextState = WEBSERVER_STATE_Closed;\r
                                break;\r
                }                 \r
        }               \r
                                break;\r
                }                 \r
        }               \r
@@ -156,10 +153,10 @@ void WebserverApp_Callback(void)
 /** HTTP Server State handler for the Request Process state. This state manages the processing of incomming HTTP\r
  *  GET requests to the server from the receiving HTTP client.\r
  */\r
 /** HTTP Server State handler for the Request Process state. This state manages the processing of incomming HTTP\r
  *  GET requests to the server from the receiving HTTP client.\r
  */\r
-static void Webserver_OpenRequestedFile(void)\r
+static void HTTPServerApp_OpenRequestedFile(void)\r
 {\r
        uip_tcp_appstate_t* const AppState    = &uip_conn->appstate;\r
 {\r
        uip_tcp_appstate_t* const AppState    = &uip_conn->appstate;\r
-       char*                     AppData     = (char*)uip_appdata;\r
+       char*               const AppData     = (char*)uip_appdata;\r
        \r
        /* No HTTP header received from the client, abort processing */\r
        if (!(uip_newdata()))\r
        \r
        /* No HTTP header received from the client, abort processing */\r
        if (!(uip_newdata()))\r
@@ -178,58 +175,57 @@ static void Webserver_OpenRequestedFile(void)
        \r
        /* If the requested filename has more that just the leading '/' path in it, copy it over */\r
        if (strlen(RequestedFileName) > 1)\r
        \r
        /* If the requested filename has more that just the leading '/' path in it, copy it over */\r
        if (strlen(RequestedFileName) > 1)\r
-         strncpy(AppState->FileName, &RequestedFileName[1], (sizeof(AppState->FileName) - 1));\r
+         strncpy(AppState->HTTPServer.FileName, &RequestedFileName[1], (sizeof(AppState->HTTPServer.FileName) - 1));\r
        else\r
        else\r
-         strcpy(AppState->FileName, "index.htm");\r
+         strcpy(AppState->HTTPServer.FileName, "index.htm");\r
 \r
        /* Ensure filename is null-terminated */\r
 \r
        /* Ensure filename is null-terminated */\r
-       AppState->FileName[(sizeof(AppState->FileName) - 1)] = 0x00;\r
+       AppState->HTTPServer.FileName[(sizeof(AppState->HTTPServer.FileName) - 1)] = 0x00;\r
        \r
        /* Try to open the file from the Dataflash disk */\r
        \r
        /* Try to open the file from the Dataflash disk */\r
-       AppState->FileOpen     = (f_open(&AppState->FileHandle, AppState->FileName, FA_OPEN_EXISTING | FA_READ) == FR_OK);\r
+       AppState->HTTPServer.FileOpen     = (f_open(&AppState->HTTPServer.FileHandle, AppState->HTTPServer.FileName, FA_OPEN_EXISTING | FA_READ) == FR_OK);\r
 \r
        /* Lock to the SendResponseHeader state until connection terminated */\r
 \r
        /* Lock to the SendResponseHeader state until connection terminated */\r
-       AppState->CurrentState = WEBSERVER_STATE_SendResponseHeader;\r
-       AppState->NextState    = WEBSERVER_STATE_SendResponseHeader;\r
+       AppState->HTTPServer.CurrentState = WEBSERVER_STATE_SendResponseHeader;\r
+       AppState->HTTPServer.NextState    = WEBSERVER_STATE_SendResponseHeader;\r
 }\r
 \r
 /** HTTP Server State handler for the HTTP Response Header Send state. This state manages the transmission of\r
  *  the HTTP response header to the receiving HTTP client.\r
  */\r
 }\r
 \r
 /** HTTP Server State handler for the HTTP Response Header Send state. This state manages the transmission of\r
  *  the HTTP response header to the receiving HTTP client.\r
  */\r
-static void Webserver_SendResponseHeader(void)\r
+static void HTTPServerApp_SendResponseHeader(void)\r
 {\r
        uip_tcp_appstate_t* const AppState    = &uip_conn->appstate;\r
 {\r
        uip_tcp_appstate_t* const AppState    = &uip_conn->appstate;\r
-       char*                     AppData     = (char*)uip_appdata;\r
+       char*               const AppData     = (char*)uip_appdata;\r
 \r
 \r
-       char*    HeaderToSend;\r
-       uint16_t HeaderLength;\r
+       char* HeaderToSend;\r
 \r
 \r
-       /* Determine what HTTP header should be sent to the client */\r
-       if (AppState->FileOpen)\r
+       /* Determine which HTTP header should be sent to the client */\r
+       if (AppState->HTTPServer.FileOpen)\r
        {\r
                HeaderToSend = HTTP200Header;\r
        {\r
                HeaderToSend = HTTP200Header;\r
-               AppState->NextState = WEBSERVER_STATE_SendMIMETypeHeader;\r
+               AppState->HTTPServer.NextState = WEBSERVER_STATE_SendMIMETypeHeader;\r
        }\r
        else\r
        {\r
                HeaderToSend = HTTP404Header;\r
        }\r
        else\r
        {\r
                HeaderToSend = HTTP404Header;\r
-               AppState->NextState = WEBSERVER_STATE_Closing;\r
+               AppState->HTTPServer.NextState = WEBSERVER_STATE_Closing;\r
        }\r
 \r
        }\r
 \r
-       HeaderLength = strlen_P(HeaderToSend);\r
-       strncpy_P(AppData, HeaderToSend, HeaderLength);\r
-       uip_send(AppData, HeaderLength);\r
+       /* Copy over the HTTP response header and send it to the receiving client */\r
+       strcpy_P(AppData, HeaderToSend);\r
+       uip_send(AppData, strlen(AppData));\r
 }\r
 \r
 /** HTTP Server State handler for the MIME Header Send state. This state manages the transmission of the file\r
  *  MIME type header for the requested file to the receiving HTTP client.\r
  */\r
 }\r
 \r
 /** HTTP Server State handler for the MIME Header Send state. This state manages the transmission of the file\r
  *  MIME type header for the requested file to the receiving HTTP client.\r
  */\r
-static void Webserver_SendMIMETypeHeader(void)\r
+static void HTTPServerApp_SendMIMETypeHeader(void)\r
 {\r
        uip_tcp_appstate_t* const AppState    = &uip_conn->appstate;\r
 {\r
        uip_tcp_appstate_t* const AppState    = &uip_conn->appstate;\r
-       char*                     AppData     = (char*)uip_appdata;\r
+       char*               const AppData     = (char*)uip_appdata;\r
 \r
 \r
-       char*    Extension        = strpbrk(AppState->FileName, ".");\r
+       char*    Extension        = strpbrk(AppState->HTTPServer.FileName, ".");\r
        uint16_t MIMEHeaderLength = 0;\r
 \r
        /* Check to see if a file extension was found for the requested filename */\r
        uint16_t MIMEHeaderLength = 0;\r
 \r
        /* Check to see if a file extension was found for the requested filename */\r
@@ -263,29 +259,29 @@ static void Webserver_SendMIMETypeHeader(void)
        uip_send(AppData, MIMEHeaderLength);\r
        \r
        /* When the MIME header is ACKed, progress to the data send stage */\r
        uip_send(AppData, MIMEHeaderLength);\r
        \r
        /* When the MIME header is ACKed, progress to the data send stage */\r
-       AppState->NextState = WEBSERVER_STATE_SendData;\r
+       AppState->HTTPServer.NextState = WEBSERVER_STATE_SendData;\r
 }\r
 \r
 /** HTTP Server State handler for the Data Send state. This state manages the transmission of file chunks\r
  *  to the receiving HTTP client.\r
  */\r
 }\r
 \r
 /** HTTP Server State handler for the Data Send state. This state manages the transmission of file chunks\r
  *  to the receiving HTTP client.\r
  */\r
-static void Webserver_SendData(void)\r
+static void HTTPServerApp_SendData(void)\r
 {\r
        uip_tcp_appstate_t* const AppState    = &uip_conn->appstate;\r
 {\r
        uip_tcp_appstate_t* const AppState    = &uip_conn->appstate;\r
-       char*                     AppData     = (char*)uip_appdata;\r
+       char*               const AppData     = (char*)uip_appdata;\r
 \r
        /* Must determine the maximum segment size to determine maximum file chunk size */\r
        uint16_t MaxSegmentSize = uip_mss();\r
 \r
        /* Return file pointer to the last ACKed position */\r
 \r
        /* Must determine the maximum segment size to determine maximum file chunk size */\r
        uint16_t MaxSegmentSize = uip_mss();\r
 \r
        /* Return file pointer to the last ACKed position */\r
-       f_lseek(&AppState->FileHandle, AppState->ACKedFilePos);\r
+       f_lseek(&AppState->HTTPServer.FileHandle, AppState->HTTPServer.ACKedFilePos);\r
        \r
        /* Read the next chunk of data from the open file */\r
        \r
        /* Read the next chunk of data from the open file */\r
-       f_read(&AppState->FileHandle, AppData, MaxSegmentSize, &AppState->SentChunkSize);\r
+       f_read(&AppState->HTTPServer.FileHandle, AppData, MaxSegmentSize, &AppState->HTTPServer.SentChunkSize);\r
        \r
        /* Send the next file chunk to the receiving client */\r
        \r
        /* Send the next file chunk to the receiving client */\r
-       uip_send(AppData, AppState->SentChunkSize);\r
+       uip_send(AppData, AppState->HTTPServer.SentChunkSize);\r
                        \r
        /* Check if we are at the last chunk of the file, if so next ACK should close the connection */\r
                        \r
        /* Check if we are at the last chunk of the file, if so next ACK should close the connection */\r
-       AppState->NextState = (MaxSegmentSize != AppState->SentChunkSize) ? WEBSERVER_STATE_Closing : WEBSERVER_STATE_SendData;\r
+       AppState->HTTPServer.NextState = (MaxSegmentSize != AppState->HTTPServer.SentChunkSize) ? WEBSERVER_STATE_Closing : WEBSERVER_STATE_SendData;\r
 }\r
 }\r