forked from mfulz_github/qmk_firmware
Add a TELNET server to the webserver project, which currently can list active TCP connections.
This commit is contained in:
parent
77e86e7d82
commit
16ea5aa7a2
File diff suppressed because one or more lines are too long
|
@ -17,6 +17,7 @@
|
|||
* -# Add ability to get number of bytes not written with pipe/endpoint write routines after an error
|
||||
* -# Add standardized descriptor names to class driver structures
|
||||
* -# Correct mishandling of error cases in Mass Storage demos
|
||||
* -# Add BOARD=NONE Option
|
||||
* - Documentation/Support
|
||||
* -# Remake AVRStudio project files
|
||||
* -# Add detailed overviews of how each demo works
|
||||
|
|
|
@ -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)
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -29,9 +29,10 @@ clock_time_t clock_time()
|
|||
{
|
||||
clock_time_t time;
|
||||
|
||||
cli();
|
||||
ATOMIC_BLOCK(ATOMIC_FORCEON)
|
||||
{
|
||||
time = clock_datetime;
|
||||
sei();
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
/** @} */
|
||||
|
||||
|
|
|
@ -128,10 +128,11 @@ SRC = $(TARGET).c \
|
|||
USBDeviceMode.c \
|
||||
USBHostMode.c \
|
||||
Lib/SCSI.c \
|
||||
Lib/uIPManagement.c \
|
||||
Lib/DHCPApp.c \
|
||||
Lib/HTTPServerApp.c \
|
||||
Lib/DataflashManager.c \
|
||||
Lib/uIPManagement.c \
|
||||
Lib/DHCPClientApp.c \
|
||||
Lib/HTTPServerApp.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
|
||||
|
|
Loading…
Reference in New Issue