}\r
else if (uip_connected())\r
{\r
- /* New connection - initialize connection state and data pointer to the appropriate HTTP header */\r
+ /* New connection - initialize connection state values */\r
AppState->PrevState = WEBSERVER_STATE_OpenRequestedFile;\r
AppState->CurrentState = WEBSERVER_STATE_OpenRequestedFile;\r
+ AppState->FileOpen = false;\r
}\r
else if (uip_rexmit())\r
{\r
/* Wait for the packet containing the request header */\r
if (uip_newdata())\r
{\r
+ char* RequestToken = strtok(AppData, " ");\r
+ \r
/* Must be a GET request, abort otherwise */\r
- if (strncmp(AppData, "GET ", (sizeof("GET ") - 1)) != 0)\r
+ if (strcmp(RequestToken, "GET") != 0)\r
{\r
uip_abort();\r
break;\r
}\r
\r
- /* Copy over the requested filename from the GET request as all-lowercase */\r
- for (uint8_t i = 0; i < (sizeof(AppState->FileName) - 1); i++)\r
- {\r
- AppState->FileName[i] = tolower(AppData[sizeof("GET ") + i]);\r
- \r
- if (AppState->FileName[i] == ' ')\r
- {\r
- AppState->FileName[i] = 0x00;\r
- break;\r
- }\r
- }\r
- \r
- /* Ensure requested filename is null-terminated */\r
- AppState->FileName[(sizeof(AppState->FileName) - 1)] = 0x00;\r
+ char* RequestedFileName = strtok(NULL, " ");\r
\r
- /* If no filename specified, assume the default of index.htm */\r
- if (AppState->FileName[0] == 0x00)\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
+ else\r
strcpy(AppState->FileName, "index.htm");\r
+\r
+ /* Ensure filename is null-terminated */\r
+ AppState->FileName[(sizeof(AppState->FileName) - 1)] = 0x00;\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
strncpy_P(AppData, HTTP404Header, AppDataSize);\r
}\r
\r
- uip_send(AppData, AppDataSize);\r
- \r
AppState->PrevState = WEBSERVER_STATE_SendResponseHeader;\r
AppState->CurrentState = WEBSERVER_STATE_SendMIMETypeHeader;\r
break;\r
/* Add the end-of line terminator and end-of-headers terminator after the MIME type */\r
strncpy(&AppData[AppDataSize], "\r\n\r\n", sizeof("\r\n\r\n"));\r
AppDataSize += (sizeof("\r\n\r\n") - 1);\r
- \r
- uip_send(AppData, AppDataSize);\r
}\r
\r
AppState->PrevState = WEBSERVER_STATE_SendMIMETypeHeader;\r
\r
uint16_t MaxSegSize = uip_mss();\r
\r
- /* Return file pointer to the last ACKed position if retransmitting */\r
+ /* Return file pointer to the last ACKed position */\r
f_lseek(&AppState->FileHandle, AppState->CurrentFilePos);\r
\r
/* Read the next chunk of data from the open file */\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
+ /* If we are not re-transmitting a lost segment, advance file position */\r
+ if (uip_acked() && !(uip_rexmit()))\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
+ AppState->FileOpen = (AppDataSize > 0);\r
+ AppState->CurrentFilePos += AppDataSize;\r
}\r
\r
+ /* Stay in the SendData state if retransmission is required until all data sent */\r
AppState->PrevState = WEBSERVER_STATE_SendData;\r
\r
break;\r
}\r
+\r
+ /* If data has been loaded into the application buffer by the server, send it to the client */\r
+ if (AppDataSize)\r
+ uip_send(AppData, AppDataSize);\r
}\r
{\r
/* uIP Timing Initialization */\r
clock_init();\r
- timer_set(&ConnectionTimer, CLOCK_SECOND / 100);\r
+ timer_set(&ConnectionTimer, CLOCK_SECOND / 2);\r
timer_set(&ARPTimer, CLOCK_SECOND * 10); \r
\r
/* uIP Stack Initialization */\r
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);\r
\r
/* Read the incomming packet straight into the UIP packet buffer */\r
- RNDIS_Host_ReadPacket(&Ethernet_RNDIS_Interface, &uip_buf[0], &uip_len);\r
+ RNDIS_Host_ReadPacket(&Ethernet_RNDIS_Interface, uip_buf, &uip_len);\r
\r
if (uip_len > 0)\r
{\r
bool PacketHandled = true;\r
\r
- struct uip_eth_hdr* EthernetHeader = (struct uip_eth_hdr*)&uip_buf[0];\r
+ struct uip_eth_hdr* EthernetHeader = (struct uip_eth_hdr*)uip_buf;\r
if (EthernetHeader->type == HTONS(UIP_ETHTYPE_IP))\r
{\r
/* Filter packet by MAC destination */\r
\r
/* If a response was generated, send it */\r
if ((uip_len > 0) && PacketHandled)\r
- RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, &uip_buf[0], uip_len);\r
+ RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, uip_buf, uip_len);\r
}\r
\r
LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
/** Manages the currently open network connections, including TCP and (if enabled) UDP. */\r
static void uIPManagement_ManageConnections(void)\r
{\r
- /* Manage open connections */\r
+ /* Poll TCP connections for more data to send back to the host */\r
+ for (uint8_t i = 0; i < UIP_CONNS; i++)\r
+ {\r
+ uip_poll_conn(&uip_conns[i]);\r
+\r
+ /* If a response was generated, send it */\r
+ if (uip_len > 0)\r
+ {\r
+ /* Add destination MAC to outgoing packet */\r
+ uip_arp_out();\r
+\r
+ RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, uip_buf, uip_len);\r
+ }\r
+ }\r
+\r
+ /* Manage open connections for timeouts */\r
if (timer_expired(&ConnectionTimer))\r
{\r
timer_reset(&ConnectionTimer);\r
/* Add destination MAC to outgoing packet */\r
uip_arp_out();\r
\r
- RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, &uip_buf[0], uip_len);\r
+ RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, uip_buf, uip_len);\r
}\r
}\r
\r
/* Add destination MAC to outgoing packet */\r
uip_arp_out();\r
\r
- RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, &uip_buf[0], uip_len);\r
+ RNDIS_Host_SendPacket(&Ethernet_RNDIS_Interface, uip_buf, uip_len);\r
}\r
}\r
#endif\r