]> git.gir.st - tmk_keyboard.git/blob - protocol/lufa/LUFA-git/Projects/Webserver/Lib/TELNETServerApp.c
Squashed 'tmk_core/' changes from caca2c0..dc0e46e
[tmk_keyboard.git] / protocol / lufa / LUFA-git / Projects / Webserver / Lib / TELNETServerApp.c
1 /*
2 LUFA Library
3 Copyright (C) Dean Camera, 2014.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7 */
8
9 /*
10 Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
12 Permission to use, copy, modify, distribute, and sell this
13 software and its documentation for any purpose is hereby granted
14 without fee, provided that the above copyright notice appear in
15 all copies and that both that the copyright notice and this
16 permission notice and warranty disclaimer appear in supporting
17 documentation, and that the name of the author not be used in
18 advertising or publicity pertaining to distribution of the
19 software without specific, written prior permission.
20
21 The author disclaims all warranties with regard to this
22 software, including all implied warranties of merchantability
23 and fitness. In no event shall the author be liable for any
24 special, indirect or consequential damages or any damages
25 whatsoever resulting from loss of use, data or profits, whether
26 in an action of contract, negligence or other tortious action,
27 arising out of or in connection with the use or performance of
28 this software.
29 */
30
31 /** \file
32 *
33 * TELNET Webserver Application. When connected to the uIP stack,
34 * this will serve out raw TELNET to the client on port 23.
35 */
36
37 #define INCLUDE_FROM_TELNETSERVERAPP_C
38 #include "TELNETServerApp.h"
39
40 #if defined(ENABLE_TELNET_SERVER) || defined(__DOXYGEN__)
41
42 /** Welcome message to send to a TELNET client when a connection is first made. */
43 const char PROGMEM WelcomeHeader[] = "********************************************\r\n"
44 "* LUFA uIP Webserver (TELNET) *\r\n"
45 "********************************************\r\n";
46
47 /** Main TELNET menu, giving the user the list of available commands they may issue */
48 const char PROGMEM TELNETMenu[] = "\r\n"
49 " == Available Commands: ==\r\n"
50 " c) List Active TCP Connections\r\n"
51 " =========================\r\n"
52 "\r\n>";
53
54 /** Header to print before the current connections are printed to the client */
55 const char PROGMEM CurrentConnectionsHeader[] = "\r\n* Current TCP Connections: *\r\n";
56
57 /** Initialization function for the simple TELNET webserver. */
58 void TELNETServerApp_Init(void)
59 {
60 /* Listen on port 23 for TELNET connections from hosts */
61 uip_listen(HTONS(TELNET_SERVER_PORT));
62 }
63
64 /** uIP stack application callback for the TELNET server. This function must be called each time the
65 * TCP/IP stack needs a TCP packet to be processed.
66 */
67 void TELNETServerApp_Callback(void)
68 {
69 uip_tcp_appstate_t* const AppState = &uip_conn->appstate;
70 char* const AppData = (char*)uip_appdata;
71
72 if (uip_connected())
73 {
74 /* New connection - initialize connection state values */
75 AppState->TELNETServer.CurrentState = TELNET_STATE_SendHeader;
76 }
77
78 if (uip_acked())
79 {
80 /* Progress to the next state once the current state's data has been ACKed */
81 AppState->TELNETServer.CurrentState = AppState->TELNETServer.NextState;
82 }
83
84 if (uip_rexmit() || uip_acked() || uip_newdata() || uip_connected() || uip_poll())
85 {
86 switch (AppState->TELNETServer.CurrentState)
87 {
88 case TELNET_STATE_SendHeader:
89 /* Copy over and send the TELNET welcome message upon first connection */
90 strcpy_P(AppData, WelcomeHeader);
91 uip_send(AppData, strlen(AppData));
92
93 AppState->TELNETServer.NextState = TELNET_STATE_SendMenu;
94 break;
95 case TELNET_STATE_SendMenu:
96 /* Copy over and send the TELNET menu to the client */
97 strcpy_P(AppData, TELNETMenu);
98 uip_send(AppData, strlen(AppData));
99
100 AppState->TELNETServer.NextState = TELNET_STATE_GetCommand;
101 break;
102 case TELNET_STATE_GetCommand:
103 if (!(uip_datalen()))
104 break;
105
106 /* Save the issued command for later processing */
107 AppState->TELNETServer.IssuedCommand = AppData[0];
108
109 AppState->TELNETServer.CurrentState = TELNET_STATE_SendResponse;
110 break;
111 case TELNET_STATE_SendResponse:
112 /* Determine which command was issued, perform command processing */
113 switch (AppState->TELNETServer.IssuedCommand)
114 {
115 case 'c':
116 TELNETServerApp_DisplayTCPConnections();
117 break;
118 default:
119 strcpy_P(AppData, PSTR("Invalid Command.\r\n"));
120 uip_send(AppData, strlen(AppData));
121 break;
122 }
123
124 AppState->TELNETServer.NextState = TELNET_STATE_SendMenu;
125 break;
126 }
127 }
128 }
129
130 /** Sends a list of active TCP connections to the TELNET client. */
131 static void TELNETServerApp_DisplayTCPConnections(void)
132 {
133 char* const AppData = (char*)uip_appdata;
134
135 strcpy_P(AppData, CurrentConnectionsHeader);
136
137 uint16_t ResponseLen = strlen(AppData);
138 uint8_t ActiveConnCount = 0;
139
140 /* Loop through the complete uIP TCP connections list, looking for active connections */
141 for (uint8_t i = 0; i < UIP_CONNS; i++)
142 {
143 struct uip_conn* CurrConnection = &uip_conns[i];
144
145 /* If the connection is not closed, it is active and must be added to the out buffer */
146 if (CurrConnection->tcpstateflags != UIP_CLOSED)
147 {
148 /* Add the current connection's details to the out buffer */
149 ResponseLen += sprintf_P(&AppData[ResponseLen], PSTR("%u) %d.%d.%d.%d (Local Port %u <=> Remote Port %u)\r\n"),
150 ++ActiveConnCount,
151 CurrConnection->ripaddr.u8[0],
152 CurrConnection->ripaddr.u8[1],
153 CurrConnection->ripaddr.u8[2],
154 CurrConnection->ripaddr.u8[3],
155 HTONS(CurrConnection->lport), HTONS(CurrConnection->rport));
156 }
157 }
158
159 uip_send(AppData, ResponseLen);
160 }
161
162 #endif
163
Imprint / Impressum