+ \r
+ /* Add the end-of-line terminator and end-of-headers terminator after the MIME type */\r
+ strcpy_P(&AppData[strlen(AppData)], PSTR("\r\n\r\n"));\r
+ \r
+ /* Send the MIME header to the receiving client */\r
+ uip_send(AppData, strlen(AppData));\r
+ \r
+ /* When the MIME header is ACKed, progress to the data send stage */\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
+static void HTTPServerApp_SendData(void)\r
+{\r
+ uip_tcp_appstate_t* const AppState = &uip_conn->appstate;\r
+ char* const AppData = (char*)uip_appdata;\r
+\r
+ /* Get the maximum segment size for the current packet */\r
+ uint16_t MaxChunkSize = uip_mss();\r
+\r
+ /* Read the next chunk of data from the open file */\r
+ f_read(&AppState->HTTPServer.FileHandle, AppData, MaxChunkSize, &AppState->HTTPServer.SentChunkSize);\r
+ \r
+ /* Send the next file chunk to the receiving client */\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
+ if (MaxChunkSize != AppState->HTTPServer.SentChunkSize)\r
+ AppState->HTTPServer.NextState = WEBSERVER_STATE_Closing;\r