aboutsummaryrefslogtreecommitdiffstats
path: root/Projects/Webserver
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2010-02-03 10:39:33 +0000
committerDean Camera <dean@fourwalledcubicle.com>2010-02-03 10:39:33 +0000
commit16ea5aa7a2e5f326f8ff129e740a19bb3fb7829f (patch)
treeaf3d7d3ccecbfb64d7cadbf1d731c7cfb5817e13 /Projects/Webserver
parent77e86e7d82c65b1c2a75f965cb936b8f7ad97ac2 (diff)
downloadlufa-16ea5aa7a2e5f326f8ff129e740a19bb3fb7829f.tar.gz
lufa-16ea5aa7a2e5f326f8ff129e740a19bb3fb7829f.tar.bz2
lufa-16ea5aa7a2e5f326f8ff129e740a19bb3fb7829f.zip
Add a TELNET server to the webserver project, which currently can list active TCP connections.
Diffstat (limited to 'Projects/Webserver')
-rw-r--r--Projects/Webserver/Lib/DHCPClientApp.c (renamed from Projects/Webserver/Lib/DHCPApp.c)76
-rw-r--r--Projects/Webserver/Lib/DHCPClientApp.h (renamed from Projects/Webserver/Lib/DHCPApp.h)16
-rw-r--r--Projects/Webserver/Lib/HTTPServerApp.c56
-rw-r--r--Projects/Webserver/Lib/HTTPServerApp.h2
-rw-r--r--Projects/Webserver/Lib/TELNETServerApp.c147
-rw-r--r--Projects/Webserver/Lib/TELNETServerApp.h68
-rw-r--r--Projects/Webserver/Lib/uIPManagement.c39
-rw-r--r--Projects/Webserver/Lib/uIPManagement.h5
-rw-r--r--Projects/Webserver/Lib/uip/clock.c5
-rw-r--r--Projects/Webserver/Lib/uip/clock.h1
-rw-r--r--Projects/Webserver/Lib/uip/uipopt.h60
-rw-r--r--Projects/Webserver/makefile9
12 files changed, 380 insertions, 104 deletions
diff --git a/Projects/Webserver/Lib/DHCPApp.c b/Projects/Webserver/Lib/DHCPClientApp.c
index 2aad7a65b..79170fabe 100644
--- a/Projects/Webserver/Lib/DHCPApp.c
+++ b/Projects/Webserver/Lib/DHCPClientApp.c
@@ -34,27 +34,27 @@
* DHCP server on the network.
*/
-#include "DHCPApp.h"
+#include "DHCPClientApp.h"
#if defined(ENABLE_DHCP) || defined(__DOXYGEN__)
/** Timer for managing the timeout period for a DHCP server to respond */
struct timer DHCPTimer;
/** Initialization function for the DHCP client. */
-void DHCPApp_Init(void)
+void DHCPClientApp_Init(void)
{
uip_udp_appstate_t* const AppState = &uip_udp_conn->appstate;
/* Create a new UDP connection to the DHCP server port for the DHCP solicitation */
uip_ipaddr_t DHCPServerIPAddress;
uip_ipaddr(&DHCPServerIPAddress, 255, 255, 255, 255);
- AppState->Connection = uip_udp_new(&DHCPServerIPAddress, HTONS(DHCPC_SERVER_PORT));
+ AppState->DHCPClient.Connection = uip_udp_new(&DHCPServerIPAddress, HTONS(DHCPC_SERVER_PORT));
/* If the connection was sucessfully created, bind it to the local DHCP client port */
- if(AppState->Connection != NULL)
+ if(AppState->DHCPClient.Connection != NULL)
{
- uip_udp_bind(AppState->Connection, HTONS(DHCPC_CLIENT_PORT));
- AppState->CurrentState = DHCP_STATE_SendDiscover;
+ uip_udp_bind(AppState->DHCPClient.Connection, HTONS(DHCPC_CLIENT_PORT));
+ AppState->DHCPClient.CurrentState = DHCP_STATE_SendDiscover;
}
/* Set timeout period to half a second for a DHCP server to respond */
@@ -64,33 +64,33 @@ void DHCPApp_Init(void)
/** uIP stack application callback for the DHCP client. This function must be called each time the TCP/IP stack
* needs a UDP packet to be processed.
*/
-void DHCPApp_Callback(void)
+void DHCPClientApp_Callback(void)
{
uip_udp_appstate_t* const AppState = &uip_udp_conn->appstate;
DHCP_Header_t* const AppData = (DHCP_Header_t*)uip_appdata;
uint16_t AppDataSize = 0;
- switch (AppState->CurrentState)
+ switch (AppState->DHCPClient.CurrentState)
{
case DHCP_STATE_SendDiscover:
/* Clear all DHCP settings, reset client IP address */
- memset(&AppState->DHCPOffer_Data, 0x00, sizeof(AppState->DHCPOffer_Data));
- uip_sethostaddr((uip_ipaddr_t*)&AppState->DHCPOffer_Data.AllocatedIP);
+ memset(&AppState->DHCPClient.DHCPOffer_Data, 0x00, sizeof(AppState->DHCPClient.DHCPOffer_Data));
+ uip_sethostaddr((uip_ipaddr_t*)&AppState->DHCPClient.DHCPOffer_Data.AllocatedIP);
/* Fill out the DHCP response header */
- AppDataSize += DHCPApp_FillDHCPHeader(AppData, DHCP_DISCOVER, AppState);
+ AppDataSize += DHCPClientApp_FillDHCPHeader(AppData, DHCP_DISCOVER, AppState);
/* Add the required DHCP options list to the packet */
uint8_t RequiredOptionList[] = {DHCP_OPTION_SUBNET_MASK, DHCP_OPTION_ROUTER, DHCP_OPTION_DNS_SERVER};
- AppDataSize += DHCPApp_SetOption(AppData->Options, DHCP_OPTION_REQ_LIST, sizeof(RequiredOptionList),
- RequiredOptionList);
+ AppDataSize += DHCPClientApp_SetOption(AppData->Options, DHCP_OPTION_REQ_LIST, sizeof(RequiredOptionList),
+ RequiredOptionList);
/* Send the DHCP DISCOVER packet */
uip_udp_send(AppDataSize);
/* Reset the timeout timer, progress to next state */
timer_reset(&DHCPTimer);
- AppState->CurrentState = DHCP_STATE_WaitForOffer;
+ AppState->DHCPClient.CurrentState = DHCP_STATE_WaitForOffer;
break;
case DHCP_STATE_WaitForOffer:
@@ -98,45 +98,45 @@ void DHCPApp_Callback(void)
{
/* Check if the DHCP timeout period has expired while waiting for a response */
if (timer_expired(&DHCPTimer))
- AppState->CurrentState = DHCP_STATE_SendDiscover;
+ AppState->DHCPClient.CurrentState = DHCP_STATE_SendDiscover;
break;
}
uint8_t OfferResponse_MessageType;
if ((AppData->TransactionID == DHCP_TRANSACTION_ID) &&
- DHCPApp_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &OfferResponse_MessageType) &&
+ DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &OfferResponse_MessageType) &&
(OfferResponse_MessageType == DHCP_OFFER))
{
/* Received a DHCP offer for an IP address, copy over values for later request */
- memcpy(&AppState->DHCPOffer_Data.AllocatedIP, &AppData->YourIP, sizeof(uip_ipaddr_t));
- DHCPApp_GetOption(AppData->Options, DHCP_OPTION_SUBNET_MASK, &AppState->DHCPOffer_Data.Netmask);
- DHCPApp_GetOption(AppData->Options, DHCP_OPTION_ROUTER, &AppState->DHCPOffer_Data.GatewayIP);
- DHCPApp_GetOption(AppData->Options, DHCP_OPTION_SERVER_ID, &AppState->DHCPOffer_Data.ServerIP);
+ memcpy(&AppState->DHCPClient.DHCPOffer_Data.AllocatedIP, &AppData->YourIP, sizeof(uip_ipaddr_t));
+ DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_SUBNET_MASK, &AppState->DHCPClient.DHCPOffer_Data.Netmask);
+ DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_ROUTER, &AppState->DHCPClient.DHCPOffer_Data.GatewayIP);
+ DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_SERVER_ID, &AppState->DHCPClient.DHCPOffer_Data.ServerIP);
timer_reset(&DHCPTimer);
- AppState->CurrentState = DHCP_STATE_SendRequest;
+ AppState->DHCPClient.CurrentState = DHCP_STATE_SendRequest;
}
break;
case DHCP_STATE_SendRequest:
/* Fill out the DHCP response header */
- AppDataSize += DHCPApp_FillDHCPHeader(AppData, DHCP_REQUEST, AppState);
+ AppDataSize += DHCPClientApp_FillDHCPHeader(AppData, DHCP_REQUEST, AppState);
/* Add the DHCP REQUESTED IP ADDRESS option to the packet */
- AppDataSize += DHCPApp_SetOption(AppData->Options, DHCP_OPTION_REQ_IPADDR, sizeof(uip_ipaddr_t),
- &AppState->DHCPOffer_Data.AllocatedIP);
+ AppDataSize += DHCPClientApp_SetOption(AppData->Options, DHCP_OPTION_REQ_IPADDR, sizeof(uip_ipaddr_t),
+ &AppState->DHCPClient.DHCPOffer_Data.AllocatedIP);
/* Add the DHCP SERVER IP ADDRESS option to the packet */
- AppDataSize += DHCPApp_SetOption(AppData->Options, DHCP_OPTION_SERVER_ID, sizeof(uip_ipaddr_t),
- &AppState->DHCPOffer_Data.ServerIP);
+ AppDataSize += DHCPClientApp_SetOption(AppData->Options, DHCP_OPTION_SERVER_ID, sizeof(uip_ipaddr_t),
+ &AppState->DHCPClient.DHCPOffer_Data.ServerIP);
/* Send the DHCP REQUEST packet */
uip_udp_send(AppDataSize);
/* Reset the timeout timer, progress to next state */
timer_reset(&DHCPTimer);
- AppState->CurrentState = DHCP_STATE_WaitForACK;
+ AppState->DHCPClient.CurrentState = DHCP_STATE_WaitForACK;
break;
case DHCP_STATE_WaitForACK:
@@ -144,22 +144,22 @@ void DHCPApp_Callback(void)
{
/* Check if the DHCP timeout period has expired while waiting for a response */
if (timer_expired(&DHCPTimer))
- AppState->CurrentState = DHCP_STATE_SendDiscover;
+ AppState->DHCPClient.CurrentState = DHCP_STATE_SendDiscover;
break;
}
uint8_t RequestResponse_MessageType;
if ((AppData->TransactionID == DHCP_TRANSACTION_ID) &&
- DHCPApp_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &RequestResponse_MessageType) &&
+ DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &RequestResponse_MessageType) &&
(RequestResponse_MessageType == DHCP_ACK))
{
/* Set the new network parameters from the DHCP server */
- uip_sethostaddr((uip_ipaddr_t*)&AppState->DHCPOffer_Data.AllocatedIP);
- uip_setnetmask((uip_ipaddr_t*)&AppState->DHCPOffer_Data.Netmask);
- uip_setdraddr((uip_ipaddr_t*)&AppState->DHCPOffer_Data.GatewayIP);
+ uip_sethostaddr((uip_ipaddr_t*)&AppState->DHCPClient.DHCPOffer_Data.AllocatedIP);
+ uip_setnetmask((uip_ipaddr_t*)&AppState->DHCPClient.DHCPOffer_Data.Netmask);
+ uip_setdraddr((uip_ipaddr_t*)&AppState->DHCPClient.DHCPOffer_Data.GatewayIP);
- AppState->CurrentState = DHCP_STATE_AddressLeased;
+ AppState->DHCPClient.CurrentState = DHCP_STATE_AddressLeased;
}
break;
@@ -175,7 +175,7 @@ void DHCPApp_Callback(void)
*
* \return Size in bytes of the created DHCP packet
*/
-uint16_t DHCPApp_FillDHCPHeader(DHCP_Header_t* DHCPHeader, uint8_t DHCPMessageType, uip_udp_appstate_t* AppState)
+uint16_t DHCPClientApp_FillDHCPHeader(DHCP_Header_t* DHCPHeader, uint8_t DHCPMessageType, uip_udp_appstate_t* AppState)
{
/* Erase existing packet data so that we start will all 0x00 DHCP header data */
memset(DHCPHeader, 0, sizeof(DHCP_Header_t));
@@ -189,8 +189,8 @@ uint16_t DHCPApp_FillDHCPHeader(DHCP_Header_t* DHCPHeader, uint8_t DHCPMessageTy
DHCPHeader->ElapsedSeconds = 0;
DHCPHeader->Flags = HTONS(BOOTP_BROADCAST);
memcpy(&DHCPHeader->ClientIP, &uip_hostaddr, sizeof(uip_ipaddr_t));
- memcpy(&DHCPHeader->YourIP, &AppState->DHCPOffer_Data.AllocatedIP, sizeof(uip_ipaddr_t));
- memcpy(&DHCPHeader->NextServerIP, &AppState->DHCPOffer_Data.ServerIP, sizeof(uip_ipaddr_t));
+ memcpy(&DHCPHeader->YourIP, &AppState->DHCPClient.DHCPOffer_Data.AllocatedIP, sizeof(uip_ipaddr_t));
+ memcpy(&DHCPHeader->NextServerIP, &AppState->DHCPClient.DHCPOffer_Data.ServerIP, sizeof(uip_ipaddr_t));
memcpy(&DHCPHeader->ClientHardwareAddress, &MACAddress, sizeof(struct uip_eth_addr));
DHCPHeader->Cookie = DHCP_MAGIC_COOKIE;
@@ -214,7 +214,7 @@ uint16_t DHCPApp_FillDHCPHeader(DHCP_Header_t* DHCPHeader, uint8_t DHCPMessageTy
*
* \return Number of bytes added to the DHCP packet
*/
-uint8_t DHCPApp_SetOption(uint8_t* DHCPOptionList, uint8_t Option, uint8_t DataLen, void* OptionData)
+uint8_t DHCPClientApp_SetOption(uint8_t* DHCPOptionList, uint8_t Option, uint8_t DataLen, void* OptionData)
{
/* Skip through the DHCP options list until the terminator option is found */
while (*DHCPOptionList != DHCP_OPTION_END)
@@ -238,7 +238,7 @@ uint8_t DHCPApp_SetOption(uint8_t* DHCPOptionList, uint8_t Option, uint8_t DataL
*
* \return Boolean true if the option was found in the DHCP packet's options list, false otherwise
*/
-bool DHCPApp_GetOption(uint8_t* DHCPOptionList, uint8_t Option, void* Destination)
+bool DHCPClientApp_GetOption(uint8_t* DHCPOptionList, uint8_t Option, void* Destination)
{
/* Look through the incomming DHCP packet's options list for the requested option */
while (*DHCPOptionList != DHCP_OPTION_END)
diff --git a/Projects/Webserver/Lib/DHCPApp.h b/Projects/Webserver/Lib/DHCPClientApp.h
index 5d11d8236..947151d0b 100644
--- a/Projects/Webserver/Lib/DHCPApp.h
+++ b/Projects/Webserver/Lib/DHCPClientApp.h
@@ -30,11 +30,11 @@
/** \file
*
- * Header file for DHCPApp.c.
+ * Header file for DHCPClientApp.c.
*/
-#ifndef _DHCP_APP_H_
-#define _DHCP_APP_H_
+#ifndef _DHCPCLIENT_APP_H_
+#define _DHCPCLIENT_APP_H_
/* Includes: */
#include <stdio.h>
@@ -156,11 +156,11 @@
};
/* Function Prototypes: */
- void DHCPApp_Init(void);
- void DHCPApp_Callback(void);
+ void DHCPClientApp_Init(void);
+ void DHCPClientApp_Callback(void);
- uint16_t DHCPApp_FillDHCPHeader(DHCP_Header_t* DHCPHeader, uint8_t DHCPMessageType, uip_udp_appstate_t* AppState);
- uint8_t DHCPApp_SetOption(uint8_t* DHCPOptionList, uint8_t Option, uint8_t DataLen, void* OptionData);
- bool DHCPApp_GetOption(uint8_t* DHCPOptionList, uint8_t Option, void* Destination);
+ uint16_t DHCPClientApp_FillDHCPHeader(DHCP_Header_t* DHCPHeader, uint8_t DHCPMessageType, uip_udp_appstate_t* AppState);
+ uint8_t DHCPClientApp_SetOption(uint8_t* DHCPOptionList, uint8_t Option, uint8_t DataLen, void* OptionData);
+ bool DHCPClientApp_GetOption(uint8_t* DHCPOptionList, uint8_t Option, void* Destination);
#endif
diff --git a/Projects/Webserver/Lib/HTTPServerApp.c b/Projects/Webserver/Lib/HTTPServerApp.c
index 18366888d..9a70dade1 100644
--- a/Projects/Webserver/Lib/HTTPServerApp.c
+++ b/Projects/Webserver/Lib/HTTPServerApp.c
@@ -98,36 +98,36 @@ void HTTPServerApp_Callback(void)
if (uip_aborted() || uip_timedout() || uip_closed())
{
/* Connection is being terminated for some reason - close file handle */
- f_close(&AppState->FileHandle);
- AppState->FileOpen = false;
+ f_close(&AppState->HTTPServer.FileHandle);
+ AppState->HTTPServer.FileOpen = false;
/* Lock to the closed state so that no further processing will occur on the connection */
- AppState->CurrentState = WEBSERVER_STATE_Closed;
- AppState->NextState = WEBSERVER_STATE_Closed;
+ AppState->HTTPServer.CurrentState = WEBSERVER_STATE_Closed;
+ AppState->HTTPServer.NextState = WEBSERVER_STATE_Closed;
}
if (uip_connected())
{
/* New connection - initialize connection state values */
- AppState->CurrentState = WEBSERVER_STATE_OpenRequestedFile;
- AppState->NextState = WEBSERVER_STATE_OpenRequestedFile;
- AppState->FileOpen = false;
- AppState->ACKedFilePos = 0;
- AppState->SentChunkSize = 0;
+ AppState->HTTPServer.CurrentState = WEBSERVER_STATE_OpenRequestedFile;
+ AppState->HTTPServer.NextState = WEBSERVER_STATE_OpenRequestedFile;
+ AppState->HTTPServer.FileOpen = false;
+ AppState->HTTPServer.ACKedFilePos = 0;
+ AppState->HTTPServer.SentChunkSize = 0;
}
if (uip_acked())
{
/* Add the amount of ACKed file data to the total sent file bytes counter */
- AppState->ACKedFilePos += AppState->SentChunkSize;
+ AppState->HTTPServer.ACKedFilePos += AppState->HTTPServer.SentChunkSize;
/* Progress to the next state once the current state's data has been ACKed */
- AppState->CurrentState = AppState->NextState;
+ AppState->HTTPServer.CurrentState = AppState->HTTPServer.NextState;
}
if (uip_rexmit() || uip_acked() || uip_newdata() || uip_connected() || uip_poll())
{
- switch (AppState->CurrentState)
+ switch (AppState->HTTPServer.CurrentState)
{
case WEBSERVER_STATE_OpenRequestedFile:
HTTPServerApp_OpenRequestedFile();
@@ -144,7 +144,7 @@ void HTTPServerApp_Callback(void)
case WEBSERVER_STATE_Closing:
uip_close();
- AppState->NextState = WEBSERVER_STATE_Closed;
+ AppState->HTTPServer.NextState = WEBSERVER_STATE_Closed;
break;
}
}
@@ -175,19 +175,19 @@ static void HTTPServerApp_OpenRequestedFile(void)
/* If the requested filename has more that just the leading '/' path in it, copy it over */
if (strlen(RequestedFileName) > 1)
- strncpy(AppState->FileName, &RequestedFileName[1], (sizeof(AppState->FileName) - 1));
+ strncpy(AppState->HTTPServer.FileName, &RequestedFileName[1], (sizeof(AppState->HTTPServer.FileName) - 1));
else
- strcpy(AppState->FileName, "index.htm");
+ strcpy(AppState->HTTPServer.FileName, "index.htm");
/* Ensure filename is null-terminated */
- AppState->FileName[(sizeof(AppState->FileName) - 1)] = 0x00;
+ AppState->HTTPServer.FileName[(sizeof(AppState->HTTPServer.FileName) - 1)] = 0x00;
/* Try to open the file from the Dataflash disk */
- AppState->FileOpen = (f_open(&AppState->FileHandle, AppState->FileName, FA_OPEN_EXISTING | FA_READ) == FR_OK);
+ AppState->HTTPServer.FileOpen = (f_open(&AppState->HTTPServer.FileHandle, AppState->HTTPServer.FileName, FA_OPEN_EXISTING | FA_READ) == FR_OK);
/* Lock to the SendResponseHeader state until connection terminated */
- AppState->CurrentState = WEBSERVER_STATE_SendResponseHeader;
- AppState->NextState = WEBSERVER_STATE_SendResponseHeader;
+ AppState->HTTPServer.CurrentState = WEBSERVER_STATE_SendResponseHeader;
+ AppState->HTTPServer.NextState = WEBSERVER_STATE_SendResponseHeader;
}
/** HTTP Server State handler for the HTTP Response Header Send state. This state manages the transmission of
@@ -202,15 +202,15 @@ static void HTTPServerApp_SendResponseHeader(void)
uint16_t HeaderLength;
/* Determine which HTTP header should be sent to the client */
- if (AppState->FileOpen)
+ if (AppState->HTTPServer.FileOpen)
{
HeaderToSend = HTTP200Header;
- AppState->NextState = WEBSERVER_STATE_SendMIMETypeHeader;
+ AppState->HTTPServer.NextState = WEBSERVER_STATE_SendMIMETypeHeader;
}
else
{
HeaderToSend = HTTP404Header;
- AppState->NextState = WEBSERVER_STATE_Closing;
+ AppState->HTTPServer.NextState = WEBSERVER_STATE_Closing;
}
/* Copy over the HTTP response header and send it to the receiving client */
@@ -227,7 +227,7 @@ static void HTTPServerApp_SendMIMETypeHeader(void)
uip_tcp_appstate_t* const AppState = &uip_conn->appstate;
char* const AppData = (char*)uip_appdata;
- char* Extension = strpbrk(AppState->FileName, ".");
+ char* Extension = strpbrk(AppState->HTTPServer.FileName, ".");
uint16_t MIMEHeaderLength = 0;
/* Check to see if a file extension was found for the requested filename */
@@ -261,7 +261,7 @@ static void HTTPServerApp_SendMIMETypeHeader(void)
uip_send(AppData, MIMEHeaderLength);
/* When the MIME header is ACKed, progress to the data send stage */
- AppState->NextState = WEBSERVER_STATE_SendData;
+ AppState->HTTPServer.NextState = WEBSERVER_STATE_SendData;
}
/** HTTP Server State handler for the Data Send state. This state manages the transmission of file chunks
@@ -276,14 +276,14 @@ static void HTTPServerApp_SendData(void)
uint16_t MaxSegmentSize = uip_mss();
/* Return file pointer to the last ACKed position */
- f_lseek(&AppState->FileHandle, AppState->ACKedFilePos);
+ f_lseek(&AppState->HTTPServer.FileHandle, AppState->HTTPServer.ACKedFilePos);
/* Read the next chunk of data from the open file */
- f_read(&AppState->FileHandle, AppData, MaxSegmentSize, &AppState->SentChunkSize);
+ f_read(&AppState->HTTPServer.FileHandle, AppData, MaxSegmentSize, &AppState->HTTPServer.SentChunkSize);
/* Send the next file chunk to the receiving client */
- uip_send(AppData, AppState->SentChunkSize);
+ uip_send(AppData, AppState->HTTPServer.SentChunkSize);
/* Check if we are at the last chunk of the file, if so next ACK should close the connection */
- AppState->NextState = (MaxSegmentSize != AppState->SentChunkSize) ? WEBSERVER_STATE_Closing : WEBSERVER_STATE_SendData;
+ AppState->HTTPServer.NextState = (MaxSegmentSize != AppState->HTTPServer.SentChunkSize) ? WEBSERVER_STATE_Closing : WEBSERVER_STATE_SendData;
}
diff --git a/Projects/Webserver/Lib/HTTPServerApp.h b/Projects/Webserver/Lib/HTTPServerApp.h
index 43ad5b18c..13399b0f9 100644
--- a/Projects/Webserver/Lib/HTTPServerApp.h
+++ b/Projects/Webserver/Lib/HTTPServerApp.h
@@ -47,7 +47,7 @@
/** States for each HTTP connection to the webserver. */
enum Webserver_States_t
{
- WEBSERVER_STATE_OpenRequestedFile, /** Currently opening requested file */
+ WEBSERVER_STATE_OpenRequestedFile, /**< Currently opening requested file */
WEBSERVER_STATE_SendResponseHeader, /**< Currently sending HTTP response headers to the client */
WEBSERVER_STATE_SendMIMETypeHeader, /**< Currently sending HTTP MIME type header to the client */
WEBSERVER_STATE_SendData, /**< Currently sending HTTP page data to the client */
diff --git a/Projects/Webserver/Lib/TELNETServerApp.c b/Projects/Webserver/Lib/TELNETServerApp.c
new file mode 100644
index 000000000..cabf52756
--- /dev/null
+++ b/Projects/Webserver/Lib/TELNETServerApp.c
@@ -0,0 +1,147 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ *
+ * TELNET Webserver Application. When connected to the uIP stack,
+ * this will serve out connection information to the client.
+ */
+
+#define INCLUDE_FROM_TELNETSERVERAPP_C
+#include "TELNETServerApp.h"
+
+/** Welcome message to send to a TELNET client when a connection is first made. */
+char PROGMEM WelcomeHeader[] = "********************************************\r\n"
+ "* LUFA uIP Webserver (TELNET) *\r\n"
+ "********************************************\r\n";
+
+/** Main TELNET menu, giving the user the list of available commands they may issue */
+char PROGMEM TELNETMenu[] = "\r\n"
+ " Available Commands:\r\n"
+ " c) List Active TCP Connections\r\n"
+ "\r\nCommand>";
+
+/** Initialization function for the simple HTTP webserver. */
+void TELNETServerApp_Init(void)
+{
+ /* Listen on port 23 for TELNET connections from hosts */
+ uip_listen(HTONS(TELNET_SERVER_PORT));
+}
+
+/** uIP stack application callback for the TELNET server. This function must be called each time the
+ * TCP/IP stack needs a TCP packet to be processed.
+ */
+void TELNETServerApp_Callback(void)
+{
+ uip_tcp_appstate_t* const AppState = &uip_conn->appstate;
+ char* const AppData = (char*)uip_appdata;
+
+ if (uip_connected())
+ {
+ AppState->TELNETServer.CurrentState = TELNET_STATE_SendHeader;
+ }
+
+ if (uip_acked())
+ {
+ AppState->TELNETServer.CurrentState = AppState->TELNETServer.NextState;
+ }
+
+ if (uip_rexmit() || uip_acked() || uip_newdata() || uip_connected() || uip_poll())
+ {
+ switch (AppState->TELNETServer.CurrentState)
+ {
+ case TELNET_STATE_SendHeader:
+ /* Copy over and send the TELNET welcome message upon first connection */
+ strncpy_P(AppData, WelcomeHeader, strlen_P(WelcomeHeader));
+ uip_send(AppData, strlen_P(WelcomeHeader));
+
+ AppState->TELNETServer.NextState = TELNET_STATE_SendMenu;
+ break;
+ case TELNET_STATE_SendMenu:
+ /* Copy over and send the TELNET menu to the client */
+ strncpy_P(AppData, TELNETMenu, strlen_P(TELNETMenu));
+ uip_send(AppData, strlen_P(TELNETMenu));
+
+ AppState->TELNETServer.NextState = TELNET_STATE_GetCommand;
+ break;
+ case TELNET_STATE_GetCommand:
+ if (!(uip_datalen()))
+ break;
+
+ /* Save the issued command for later processing */
+ AppState->TELNETServer.IssuedCommand = AppData[0];
+
+ AppState->TELNETServer.CurrentState = TELNET_STATE_SendResponse;
+ break;
+ case TELNET_STATE_SendResponse:
+ /* Determine which command was issued, perform command processing */
+ switch (AppState->TELNETServer.IssuedCommand)
+ {
+ case 'c':
+ TELNETServerApp_DisplayTCPConnections();
+ break;
+ }
+
+ AppState->TELNETServer.NextState = TELNET_STATE_SendMenu;
+ break;
+ }
+ }
+}
+
+/** Sends a list of active TCP connections to the TELNET client. */
+static void TELNETServerApp_DisplayTCPConnections(void)
+{
+ char* const AppData = (char*)uip_appdata;
+
+ strcpy(AppData, "\r\n* Current TCP Connections: *\r\n");
+
+ uint16_t ResponseLen = strlen(AppData);
+ uint8_t ActiveConnCount = 0;
+
+ /* Loop through the complete uIP TCP connections list, looking for active connections */
+ for (uint8_t i = 0; i < UIP_CONNS; i++)
+ {
+ struct uip_conn* CurrConnection = &uip_conns[i];
+
+ /* If the connection is not closed, it is active and must be added to the out buffer */
+ if (CurrConnection->tcpstateflags != UIP_CLOSED)
+ {
+ /* Add the current connection's details to the out buffer */
+ ResponseLen += sprintf(&AppData[ResponseLen], "%u) %02d.%02d.%02d.%02d (Local %u, Remote %u)\r\n",
+ ++ActiveConnCount, CurrConnection->ripaddr.u8[0],
+ CurrConnection->ripaddr.u8[1],
+ CurrConnection->ripaddr.u8[2],
+ CurrConnection->ripaddr.u8[3],
+ HTONS(CurrConnection->lport), HTONS(CurrConnection->rport));
+ }
+ }
+
+ uip_send(AppData, ResponseLen);
+} \ No newline at end of file
diff --git a/Projects/Webserver/Lib/TELNETServerApp.h b/Projects/Webserver/Lib/TELNETServerApp.h
new file mode 100644
index 000000000..7b1eb46ee
--- /dev/null
+++ b/Projects/Webserver/Lib/TELNETServerApp.h
@@ -0,0 +1,68 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ *
+ * Header file for TELNETServerApp.c.
+ */
+
+#ifndef _TELNETSERVER_APP_H_
+#define _TELNETSERVER_APP_H_
+
+ /* Includes: */
+ #include <avr/pgmspace.h>
+ #include <string.h>
+ #include <stdio.h>
+
+ #include <uip.h>
+
+ /* Macros: */
+ /** TCP listen port for incomming TELNET traffic */
+ #define TELNET_SERVER_PORT 23
+
+ /* Enums: */
+ /** States for each TELNET connection to the server. */
+ enum TELNET_States_t
+ {
+ TELNET_STATE_SendHeader, /**< Currently sending welcome header to the client */
+ TELNET_STATE_SendMenu, /**< Currently sending the command list menu to the client */
+ TELNET_STATE_GetCommand, /**< Currently waiting for a command from the client */
+ TELNET_STATE_SendResponse, /**< Processing the issued command and sending a response */
+ };
+
+ /* Function Prototypes: */
+ void TELNETServerApp_Init(void);
+ void TELNETServerApp_Callback(void);
+
+ #if defined(INCLUDE_FROM_TELNETSERVERAPP_C)
+ static void TELNETServerApp_DisplayTCPConnections(void);
+ #endif
+
+#endif
diff --git a/Projects/Webserver/Lib/uIPManagement.c b/Projects/Webserver/Lib/uIPManagement.c
index e207d9ce1..a2cadd674 100644
--- a/Projects/Webserver/Lib/uIPManagement.c
+++ b/Projects/Webserver/Lib/uIPManagement.c
@@ -58,10 +58,11 @@ void uIPManagement_Init(void)
/* uIP Stack Initialization */
uip_init();
uip_arp_init();
+ uip_setethaddr(MACAddress);
/* DHCP/Server IP Settings Initialization */
#if defined(ENABLE_DHCP)
- DHCPApp_Init();
+ DHCPClientApp_Init();
#else
uip_ipaddr_t IPAddress, Netmask, GatewayIPAddress;
uip_ipaddr(&IPAddress, DEVICE_IP_ADDRESS[0], DEVICE_IP_ADDRESS[1], DEVICE_IP_ADDRESS[2], DEVICE_IP_ADDRESS[3]);
@@ -71,11 +72,12 @@ void uIPManagement_Init(void)
uip_setnetmask(&Netmask);
uip_setdraddr(&GatewayIPAddress);
#endif
-
- uip_setethaddr(MACAddress);
/* HTTP Webserver Initialization */
HTTPServerApp_Init();
+
+ /* TELNET Server Initialization */
+ TELNETServerApp_Init();
}
/** uIP Management function. This function manages the uIP stack when called while an RNDIS device has been
@@ -90,6 +92,37 @@ void uIPManagement_ManageNetwork(void)
}
}
+/** uIP TCP/IP network stack callback function for the processing of a given TCP connection. This routine dispatches
+ * to the appropriate TCP protocol application based on the connection's listen port number.
+ */
+void uIPManagement_TCPCallback(void)
+{
+ /* Call the correct TCP application based on the port number the connection is listening on */
+ switch (uip_conn->lport)
+ {
+ case HTONS(HTTP_SERVER_PORT):
+ HTTPServerApp_Callback();
+ break;
+ case HTONS(TELNET_SERVER_PORT):
+ TELNETServerApp_Callback();
+ break;
+ }
+}
+
+/** uIP TCP/IP network stack callback function for the processing of a given UDP connection. This routine dispatches
+ * to the appropriate UDP protocol application based on the connection's listen port number.
+ */
+void uIPManagement_UDPCallback(void)
+{
+ /* Call the correct UDP application based on the port number the connection is listening on */
+ switch (uip_udp_conn->lport)
+ {
+ case HTONS(DHCPC_CLIENT_PORT):
+ DHCPClientApp_Callback();
+ break;
+ }
+}
+
/** Processes incomming packets to the server from the connected RNDIS device, creating responses as needed. */
static void uIPManagement_ProcessIncommingPacket(void)
{
diff --git a/Projects/Webserver/Lib/uIPManagement.h b/Projects/Webserver/Lib/uIPManagement.h
index 57a1393fe..1e7ffd0be 100644
--- a/Projects/Webserver/Lib/uIPManagement.h
+++ b/Projects/Webserver/Lib/uIPManagement.h
@@ -43,8 +43,9 @@
#include <uip_arp.h>
#include <timer.h>
- #include "Lib/DHCPApp.h"
+ #include "Lib/DHCPClientApp.h"
#include "Lib/HTTPServerApp.h"
+ #include "Lib/TELNETServerApp.h"
/* Macros: */
/** IP address that the webserver should use once connected to a RNDIS device (when DHCP is disabled). */
@@ -64,6 +65,8 @@
/* Function Prototypes: */
void uIPManagement_Init(void);
void uIPManagement_ManageNetwork(void);
+ void uIPManagement_TCPCallback(void);
+ void uIPManagement_UDPCallback(void);
#if defined(INCLUDE_FROM_UIPMANAGEMENT_C)
static void uIPManagement_ProcessIncommingPacket(void);
diff --git a/Projects/Webserver/Lib/uip/clock.c b/Projects/Webserver/Lib/uip/clock.c
index e8a676b1a..299a747bc 100644
--- a/Projects/Webserver/Lib/uip/clock.c
+++ b/Projects/Webserver/Lib/uip/clock.c
@@ -29,9 +29,10 @@ clock_time_t clock_time()
{
clock_time_t time;
- cli();
+ ATOMIC_BLOCK(ATOMIC_FORCEON)
+ {
time = clock_datetime;
- sei();
+ }
return time;
}
diff --git a/Projects/Webserver/Lib/uip/clock.h b/Projects/Webserver/Lib/uip/clock.h
index 0852cde15..3e42e4a59 100644
--- a/Projects/Webserver/Lib/uip/clock.h
+++ b/Projects/Webserver/Lib/uip/clock.h
@@ -2,6 +2,7 @@
#define __CLOCK_ARCH_H__
#include <stdint.h>
+#include <util/atomic.h>
typedef uint16_t clock_time_t;
#define CLOCK_SECOND 100
diff --git a/Projects/Webserver/Lib/uip/uipopt.h b/Projects/Webserver/Lib/uip/uipopt.h
index 23bce28a3..c8b3ad59e 100644
--- a/Projects/Webserver/Lib/uip/uipopt.h
+++ b/Projects/Webserver/Lib/uip/uipopt.h
@@ -346,14 +346,18 @@
*
* \hideinitializer
*/
+#if !defined(UIP_URGDATA)
#define UIP_URGDATA 0
+#endif
/**
* The initial retransmission timeout counted in timer pulses.
*
* This should not be changed.
*/
+#if !defined(UIP_RTO)
#define UIP_RTO 3
+#endif
/**
* The maximum number of times a segment should be retransmitted
@@ -361,7 +365,9 @@
*
* This should not be changed.
*/
+#if !defined(UIP_MAXRTX)
#define UIP_MAXRTX 8
+#endif
/**
* The maximum number of times a SYN segment should be retransmitted
@@ -370,7 +376,9 @@
*
* This should not need to be changed.
*/
+#if !defined(UIP_MAXSYNRTX)
#define UIP_MAXSYNRTX 5
+#endif
/**
* The TCP maximum segment size.
@@ -654,7 +662,7 @@ typedef uint32_t uip_stats_t;
typedef struct httpd_state uip_tcp_appstate_t
\endcode
*/
-#define UIP_UDP_APPCALL DHCPApp_Callback
+#define UIP_UDP_APPCALL uIPManagement_UDPCallback
void UIP_UDP_APPCALL(void);
/**
@@ -664,7 +672,7 @@ void UIP_UDP_APPCALL(void);
* response to TCP/IP events.
*
*/
-#define UIP_APPCALL HTTPServerApp_Callback
+#define UIP_APPCALL uIPManagement_TCPCallback
void UIP_APPCALL(void);
/**
@@ -674,16 +682,27 @@ void UIP_APPCALL(void);
* uip_conn structure. This usually is typedef:ed to a struct holding
* application state information.
*/
-typedef struct
+typedef union
{
- uint8_t CurrentState;
- uint8_t NextState;
+ struct
+ {
+ uint8_t CurrentState;
+ uint8_t NextState;
+
+ char FileName[30];
+ FIL FileHandle;
+ bool FileOpen;
+ uint32_t ACKedFilePos;
+ uint16_t SentChunkSize;
+ } HTTPServer;
- char FileName[30];
- FIL FileHandle;
- bool FileOpen;
- uint32_t ACKedFilePos;
- uint16_t SentChunkSize;
+ struct
+ {
+ uint8_t CurrentState;
+ uint8_t NextState;
+
+ uint8_t IssuedCommand;
+ } TELNETServer;
} uip_tcp_appstate_t;
/**
@@ -693,18 +712,21 @@ typedef struct
* uip_conn structure. This usually is typedef:ed to a struct holding
* application state information.
*/
-typedef struct
+typedef union
{
- uint8_t CurrentState;
- struct uip_udp_conn* Connection;
-
struct
{
- uint8_t AllocatedIP[4];
- uint8_t Netmask[4];
- uint8_t GatewayIP[4];
- uint8_t ServerIP[4];
- } DHCPOffer_Data;
+ uint8_t CurrentState;
+ struct uip_udp_conn* Connection;
+
+ struct
+ {
+ uint8_t AllocatedIP[4];
+ uint8_t Netmask[4];
+ uint8_t GatewayIP[4];
+ uint8_t ServerIP[4];
+ } DHCPOffer_Data;
+ } DHCPClient;
} uip_udp_appstate_t;
/** @} */
diff --git a/Projects/Webserver/makefile b/Projects/Webserver/makefile
index 37aecc76f..949283383 100644
--- a/Projects/Webserver/makefile
+++ b/Projects/Webserver/makefile
@@ -128,10 +128,11 @@ SRC = $(TARGET).c \
USBDeviceMode.c \
USBHostMode.c \
Lib/SCSI.c \
+ Lib/DataflashManager.c \
Lib/uIPManagement.c \
- Lib/DHCPApp.c \
+ Lib/DHCPClientApp.c \
Lib/HTTPServerApp.c \
- Lib/DataflashManager.c \
+ Lib/TELNETServerApp.c \
Lib/uip/uip.c \
Lib/uip/uip_arp.c \
Lib/uip/timer.c \
@@ -200,10 +201,10 @@ CDEFS = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD) $(LUFA
CDEFS += -DENABLE_DHCP=1
CDEFS += -DUIP_CONF_UDP_CONNS=1 -DUIP_CONF_TCP=1 -DUIP_CONF_MAX_CONNECTIONS=5
-CDEFS += -DUIP_CONF_MAX_LISTENPORTS=1 -DUIP_CONF_BUFFER_SIZE=1514
+CDEFS += -DUIP_CONF_MAX_LISTENPORTS=5 -DUIP_CONF_BUFFER_SIZE=1514
CDEFS += -DUIP_CONF_LL_802154=0 -DUIP_CONF_LL_80211=0 -DUIP_CONF_ROUTER=0 -DUIP_CONF_ICMP6=0 -DUIP_CONF_LL_802154=0
CDEFS += -DUIP_ARCH_ADD32=0 -DUIP_ARCH_CHKSUM=0 -DUIP_CONF_ICMP_DEST_UNREACH=1 -DUIP_NEIGHBOR_CONF_ADDRTYPE=0
-CDEFS += -DUIP_CONF_UDP=ENABLE_DHCP
+CDEFS += -DUIP_URGDATA=0 -DUIP_CONF_UDP=ENABLE_DHCP
# Place -D or -U options here for ASM sources