1 /* 2 * Copyright 2013 Tenkiv, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 5 * the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 10 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 11 * specific language governing permissions and limitations under the License. 12 */ 13 14 /** 15 * @file TelnetServer.h 16 * @brief Header file for the Telnet server of the Tekdaqc. 17 * 18 * Contains public definitions and data types for the Tekdaqc Telnet server. 19 * 20 * @author Jared Woolston (jwoolston@tenkiv.com) 21 * @since v1.0.0.0 22 */ 23 24 /* Define to prevent recursive inclusion -------------------------------------*/ 25 #ifndef TELNET_SERVER_H_ 26 #define TELNET_SERVER_H_ 27 #include "stdbool.h" 28 /* Define to provide proper behavior with C++ compilers ----------------------*/ 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 /*--------------------------------------------------------------------------------------------------------*/ 34 /* INCLUDES */ 35 /*--------------------------------------------------------------------------------------------------------*/ 36 37 #include "lwip/tcp.h" 38 39 /** @addtogroup tekdaqc_firmware_libraries Tekdaqc Firmware Libraries 40 * @{ 41 */ 42 43 /** @addtogroup telnet_server Telnet Server 44 * @{ 45 */ 46 47 /*--------------------------------------------------------------------------------------------------------*/ 48 /* EXPORTED CONSTANTS */ 49 /*--------------------------------------------------------------------------------------------------------*/ 50 51 /** 52 * @def TELNET_BUFFER_LENGTH 53 * @brief The length of the buffer to use for Telnet data. 54 */ 55 /* modify from 2056 to 4096 */ 56 #define TELNET_BUFFER_LENGTH 4096 57 58 /** 59 * @def NOT_CONNECTED 60 * @brief The Telnet server is not connected to a client. 61 */ 62 #define NOT_CONNECTED 0 63 64 /** 65 * @def CONNECTED 66 * @brief The Telnet server is connected to a client. 67 */ 68 #define CONNECTED 1 69 70 /** 71 * @internal 72 * Telnet commands, as defined by RFC854. 73 */ 74 #define TELNET_IAC ((char) 255) 75 #define TELNET_WILL ((char) 251) 76 #define TELNET_WONT ((char) 252) 77 #define TELNET_DO ((char) 253) 78 #define TELNET_DONT ((char) 254) 79 #define TELNET_SE ((char) 240) 80 #define TELNET_NOP ((char) 241) 81 #define TELNET_DATA_MARK ((char) 242) 82 #define TELNET_BREAK ((char) 243) 83 #define TELNET_IP ((char) 244) 84 #define TELNET_AO ((char) 245) 85 #define TELNET_AYT ((char) 246) 86 #define TELNET_EC ((char) 247) 87 #define TELNET_EL ((char) 248) 88 #define TELNET_GA ((char) 249) 89 #define TELNET_SB ((char) 250) 90 91 /** 92 * @internal 93 * Telnet options, as defined by RFC856-RFC861. 94 */ 95 #define TELNET_OPT_BINARY ((char) 0) 96 #define TELNET_OPT_ECHO ((char) 1) 97 #define TELNET_OPT_SUPPRESS_GA ((char) 3) 98 #define TELNET_OPT_STATUS ((char) 5) 99 #define TELNET_OPT_TIMING_MARK ((char) 6) 100 #define TELNET_OPT_EXOPL ((char) 255) 101 102 /** 103 * @def OPT_FLAG_WILL 104 * @brief The bit in the ucFlags member of the tTelnetOpts that is set when the remote client has sent a WILL 105 * request and the server has accepted it. 106 */ 107 #define OPT_FLAG_WILL ((uint8_t) 1) 108 109 /** 110 * @def OPT_FLAG_DO 111 * @brief The bit in the ucFlags member of tTelnetOpts that is set when the remote 112 * client has sent a DO request and the server has accepted it. 113 */ 114 #define OPT_FLAG_DO ((uint8_t) 2) 115 116 /** 117 * @brief Telnet options state structure. 118 * A structure that contains the state of the options supported by the telnet 119 * server, along with the possible flags. 120 */ 121 typedef struct { 122 char option; /**< The option byte. */ 123 char flags; /**< The flags for this option. The bits in this byte are defined by OPT_FLAG_WILL and OPT_FLAG_DO. */ 124 } TelnetOpts_t; 125 126 /** 127 * @brief Telnet parser state enumeration. 128 * The possible states of the telnet option parser. 129 */ 130 typedef enum { 131 STATE_NORMAL, /**< The telnet option parser is in its normal mode. Characters are passed as is until an IAC byte is received. */ 132 STATE_IAC, /**< The previous character received by the telnet option parser was an IAC byte. */ 133 STATE_WILL, /**< The previous character sequence received by the telnet option parser was IAC WILL. */ 134 STATE_WONT, /**< The previous character sequence received by the telnet option parser was IAC WONT. */ 135 STATE_DO, /**< The previous character sequence received by the telnet option parser was was IAC DO. */ 136 STATE_DONT, /**< The previous character sequence received by the telnet option parser was was IAC DONT. */ 137 } TelnetState_t; 138 139 /** 140 * @brief Telnet status enumeration. 141 * The possible success/error causes for the Telnet server's operation. 142 */ 143 typedef enum { 144 TELNET_OK, /**< Everything is normal with the telnet server. */ 145 TELNET_ERR_CONNECTED, /**< There was an error in connection with the telnet server. */ 146 /*TELNET_ERR_BADALOC,*//**< There was an error allocating memory for the telnet server. */ 147 TELNET_ERR_BIND, /**< There was an error binding a socket to a port for the telnet server. */ 148 TELNET_ERR_PCBCREATE /**< There was an error creating a PCB structure for the telnet server. */ 149 } TelnetStatus_t; 150 151 /** 152 * @brief Data structure to hold the state of the Telnet server. 153 * Contains all of the necessary state variables to impliment the Telnet server. Direct manipulation of these 154 * members is not recommended as it may leave the server in an inconsistent state. Instead, helper methods are 155 * provided which will ensure that all necessary operations occur as a result of any change. 156 */ 157 typedef struct { 158 int halt; /**< Halt signal when the lwIP TCP/IP stack has detected an error */ 159 TelnetState_t state; /**< The current state of the telnet option parser. */ 160 volatile unsigned long outstanding; /**< A count of the number of bytes that have been transmitted but have not yet been ACKed. */ 161 unsigned long close; /**< A value that is non-zero when the telnet connection should be closed down. */ 162 unsigned char buffer[TELNET_BUFFER_LENGTH]; /**< A buffer used to construct a packet of data to be transmitted to the telnet client. */ 163 volatile unsigned long length; /**< The number of bytes of valid data in the telnet packet buffer. */ 164 unsigned char recvBuffer[TELNET_BUFFER_LENGTH]; /**< A buffer used to receive data from the telnet connection. */ 165 volatile unsigned long recvWrite; /**< The offset into g_pucTelnetRecvBuffer of the next location to be written in the buffer. 166 The buffer is full if this value is one less than g_ulTelnetRecvRead (modulo the buffer size).*/ 167 volatile unsigned long recvRead; /**< The offset into g_pucTelnetRecvRead of the next location to be read from the buffer. 168 The buffer is empty if this value is equal to g_ulTelnetRecvWrite. */ 169 struct tcp_pcb* pcb; /**< A pointer to the telnet session PCB data structure. */ 170 unsigned char previous; /**< The character most recently received via the telnet interface. This is used to convert CR/LF sequences 171 into a simple CR sequence. */ 172 } TelnetServer_t; 173 174 /** 175 * @brief Initialize a TelnetServer_t struct with default values. 176 */ 177 TelnetStatus_t InitializeTelnetServer(void); 178 179 /** 180 * @brief This function is called when the the TCP connection should be closed. 181 */ 182 void TelnetClose(void); 183 184 /** 185 * @brief Indicates if the Telnet server is occupied or not. 186 */ 187 bool TelnetIsConnected(void); 188 189 /** 190 * @brief Called when the lwIP TCP/IP stack needs to poll the server with/for data. 191 */ 192 err_t TelnetPoll(void *arg, struct tcp_pcb *tpcb); 193 194 /** 195 * @brief Writes a character into the telnet receive buffer. 196 */ 197 void TelnetRecvBufferWrite(char character); 198 199 /** 200 * @brief Reads a character from the telnet interface. 201 */ 202 char TelnetRead(void); 203 204 /** 205 * @brief Writes a character to the telnet interface. 206 */ 207 208 void TelnetWrite(const char character); 209 210 /** 211 * @brief Writes a string to the telnet interface. 212 */ 213 void TelnetWriteString(char* string); 214 215 /** 216 * @brief Handle a WILL request for a telnet option. 217 */ 218 void TelnetProcessWill(char option); 219 220 /** 221 * @brief Handle a WONT request for a telnet option. 222 */ 223 void TelnetProcessWont(char option); 224 225 /** 226 * @brief Handle a DO request for a telnet option. 227 */ 228 void TelnetProcessDo(char option); 229 230 /** 231 * @brief Handle a DONT request for a telnet option. 232 */ 233 void TelnetProcessDont(char option); 234 235 /** 236 * @brief Process a character received from the telnet port. 237 */ 238 void TelnetProcessCharacter(char character); 239 240 /** 241 * @brief Print a message to the telnet connection formatted as an error. 242 */ 243 void TelnetWriteErrorMessage(char* message); 244 245 /** 246 * @brief Print a message to the telnet connection formatted as a status. 247 */ 248 void TelnetWriteStatusMessage(char* message); 249 250 /** 251 * @brief Print a message to the telnet connection formatted as a debug. 252 */ 253 void TelnetWriteDebugMessage(char* message); 254 255 /** 256 * @brief Print a message to the telnet connection formatted as a command data message. 257 */ 258 void TelnetWriteCommandDataMessage(char* message); 259 260 void telnetserver_start(); 261 262 void telnetserver_stop(); 263 264 /** 265 * @} 266 */ 267 268 /** 269 * @} 270 */ 271 272 #ifdef __cplusplus 273 } 274 #endif 275 276 #endif /* TELNET_SERVER_H_ */ 277