mirror of
				https://github.com/mfulz/qmk_firmware.git
				synced 2025-10-31 21:32:31 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			163 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			163 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|              LUFA Library
 | |
|      Copyright (C) Dean Camera, 2009.
 | |
|               
 | |
|   dean [at] fourwalledcubicle [dot] com
 | |
|       www.fourwalledcubicle.com
 | |
| */
 | |
| 
 | |
| /*
 | |
|   Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)
 | |
| 
 | |
|   Permission to use, copy, modify, and distribute this software
 | |
|   and its documentation for any purpose and without fee is hereby
 | |
|   granted, 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
 | |
|  *
 | |
|  *  Simple webserver application for demonstrating the RNDIS demo and TCP/IP stack. This
 | |
|  *  application will serve up a static HTTP webpage when requested by the host.
 | |
|  */
 | |
| 
 | |
| #include "Webserver.h"
 | |
| 
 | |
| /** HTTP server response header, for transmission before the page contents. This indicates to the host that a page exists at the
 | |
|  *  given location, and gives extra connection information.
 | |
|  */
 | |
| char PROGMEM HTTPHeader[] = "HTTP/1.1 200 OK\r\n"
 | |
|                             "Server: LUFA RNDIS\r\n"
 | |
|                             "Content-type: text/html\r\n"
 | |
|                             "Connection: close\r\n\r\n";
 | |
| 
 | |
| /** HTTP page to serve to the host when a HTTP request is made. This page is too long for a single response, thus it is automatically
 | |
|  *  broken up into smaller blocks and sent as a series of packets each time the webserver application callback is run.
 | |
|  */
 | |
| char PROGMEM HTTPPage[]   = 
 | |
| 		"<html>"
 | |
| 		"	<head>"
 | |
| 		"		<title>"
 | |
| 		"			LUFA Webserver Demo"
 | |
| 		"		</title>"
 | |
| 		"	</head>"
 | |
| 		"	<body>"
 | |
| 		"		<h1>Hello from your USB AVR!</h1>"
 | |
| 		"		<p>"
 | |
| 		"			Hello! Welcome to the LUFA RNDIS Demo Webserver test page, running on your USB AVR via the LUFA library. This demonstrates the HTTP webserver, TCP/IP stack and RNDIS demo all running atop the LUFA USB stack."
 | |
| 		"			<br /><br />"
 | |
| 		"			<small>Project Information: <a href=\"http://www.fourwalledcubicle.com/LUFA.php\">http://www.fourwalledcubicle.com/LUFA.php</a>.</small>"
 | |
| 		"			<hr />"
 | |
| 		"			<i>LUFA Version: </i>" LUFA_VERSION_STRING
 | |
| 		"		</p>"
 | |
| 		"	</body>"
 | |
| 		"</html>";
 | |
| 
 | |
| 
 | |
| /** Initializes the Webserver application, opening the appropriate HTTP port in the TCP handler and registering the application
 | |
|  *  callback routine for packets sent to the HTTP protocol port.
 | |
|  */
 | |
| void Webserver_Init(void)
 | |
| {
 | |
| 	/* Open the HTTP port in the TCP protocol so that HTTP connections to the device can be established */
 | |
| 	TCP_SetPortState(TCP_PORT_HTTP, TCP_Port_Open, Webserver_ApplicationCallback);
 | |
| }
 | |
| 
 | |
| /** Indicates if a given request equals the given HTTP command.
 | |
|  *
 | |
|  *  \param RequestHeader  HTTP request made by the host
 | |
|  *  \param Command        HTTP command to compare the request to
 | |
|  *
 | |
|  *  \return Boolean true if the command matches the request, false otherwise
 | |
|  */
 | |
| static bool IsHTTPCommand(uint8_t* RequestHeader, char* Command)
 | |
| {
 | |
| 	/* Returns true if the non null terminated string in RequestHeader matches the null terminated string Command */
 | |
| 	return (strncmp((char*)RequestHeader, Command, strlen(Command)) == 0);
 | |
| }
 | |
| 
 | |
| /** Application callback routine, executed each time the TCP processing task runs. This callback determines what request
 | |
|  *  has been made (if any), and serves up appropriate responses.
 | |
|  *
 | |
|  *  \param ConnectionState  Pointer to a TCP Connection State structure giving connection information
 | |
|  *  \param Buffer           Pointer to the application's send/receive packet buffer
 | |
|  */
 | |
| void Webserver_ApplicationCallback(TCP_ConnectionState_t* ConnectionState, TCP_ConnectionBuffer_t* Buffer)
 | |
| {
 | |
| 	char*          BufferDataStr = (char*)Buffer->Data;
 | |
| 	static uint8_t PageBlock     = 0;
 | |
| 	
 | |
| 	/* Check to see if a packet has been received on the HTTP port from a remote host */
 | |
| 	if (TCP_APP_HAS_RECEIVED_PACKET(Buffer))
 | |
| 	{
 | |
| 		if (IsHTTPCommand(Buffer->Data, "GET"))
 | |
| 		{
 | |
| 			PageBlock = 0;
 | |
| 
 | |
| 			/* Copy the HTTP response header into the packet buffer */
 | |
| 			strcpy_P(BufferDataStr, HTTPHeader);
 | |
| 			
 | |
| 			/* Send the buffer contents to the host */
 | |
| 			TCP_APP_SEND_BUFFER(Buffer, strlen(BufferDataStr));
 | |
| 
 | |
| 			/* Lock the buffer to Device->Host transmissions only while we send the page contents */
 | |
| 			TCP_APP_CAPTURE_BUFFER(Buffer);
 | |
| 		}
 | |
| 		else if (IsHTTPCommand(Buffer->Data, "HEAD"))
 | |
| 		{
 | |
| 			/* Copy the HTTP response header into the packet buffer */
 | |
| 			strcpy_P(BufferDataStr, HTTPHeader);
 | |
| 
 | |
| 			/* Send the buffer contents to the host */
 | |
| 			TCP_APP_SEND_BUFFER(Buffer, strlen(BufferDataStr));
 | |
| 		}
 | |
| 		else if (IsHTTPCommand(Buffer->Data, "TRACE"))
 | |
| 		{
 | |
| 			/* Echo the host's query back to the host */
 | |
| 			TCP_APP_SEND_BUFFER(Buffer, Buffer->Length);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			/* Unknown request, just clear the buffer (drop the packet) */
 | |
| 			TCP_APP_CLEAR_BUFFER(Buffer);
 | |
| 		}
 | |
| 	}
 | |
| 	else if (TCP_APP_HAVE_CAPTURED_BUFFER(Buffer))
 | |
| 	{
 | |
| 		uint16_t RemLength = strlen_P(&HTTPPage[PageBlock * HTTP_REPLY_BLOCK_SIZE]);
 | |
| 		uint16_t Length;
 | |
| 	
 | |
| 		/* Determine the length of the loaded block */
 | |
| 		Length = ((RemLength > HTTP_REPLY_BLOCK_SIZE) ? HTTP_REPLY_BLOCK_SIZE : RemLength);
 | |
| 
 | |
| 		/* Copy the next buffer sized block of the page to the packet buffer */
 | |
| 		strncpy_P(BufferDataStr, &HTTPPage[PageBlock * HTTP_REPLY_BLOCK_SIZE], Length);
 | |
| 		
 | |
| 		/* Send the buffer contents to the host */
 | |
| 		TCP_APP_SEND_BUFFER(Buffer, Length);
 | |
| 
 | |
| 		/* Check to see if the entire page has been sent */
 | |
| 		if (PageBlock++ == (sizeof(HTTPPage) / HTTP_REPLY_BLOCK_SIZE))
 | |
| 		{
 | |
| 			/* Unlock the buffer so that the host can fill it with future packets */
 | |
| 			TCP_APP_RELEASE_BUFFER(Buffer);
 | |
| 			
 | |
| 			/* Close the connection to the host */
 | |
| 			TCP_APP_CLOSECONNECTION(ConnectionState);
 | |
| 		}
 | |
| 	}
 | |
| }
 | 
