Files
SDK_GD32W51x/NSPE/WIFI_IOT/demo/telnetserver.h
2023-05-18 18:53:00 +08:00

279 lines
9.5 KiB
C

/*
* Copyright 2013 Tenkiv, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
/**
* @file TelnetServer.h
* @brief Header file for the Telnet server of the Tekdaqc.
*
* Contains public definitions and data types for the Tekdaqc Telnet server.
*
* @author Jared Woolston (jwoolston@tenkiv.com)
* @since v1.0.0.0
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef TELNET_SERVER_H_
#define TELNET_SERVER_H_
#include "stdbool.h"
/* Define to provide proper behavior with C++ compilers ----------------------*/
#ifdef __cplusplus
extern "C" {
#endif
/*--------------------------------------------------------------------------------------------------------*/
/* INCLUDES */
/*--------------------------------------------------------------------------------------------------------*/
#include "lwip/tcp.h"
/** @addtogroup tekdaqc_firmware_libraries Tekdaqc Firmware Libraries
* @{
*/
/** @addtogroup telnet_server Telnet Server
* @{
*/
/*--------------------------------------------------------------------------------------------------------*/
/* EXPORTED CONSTANTS */
/*--------------------------------------------------------------------------------------------------------*/
/**
* @def TELNET_BUFFER_LENGTH
* @brief The length of the buffer to use for Telnet data.
*/
/* modify from 2056 to 4096 */
#define TELNET_BUFFER_LENGTH 4096
/**
* @def NOT_CONNECTED
* @brief The Telnet server is not connected to a client.
*/
#define NOT_CONNECTED 0
/**
* @def CONNECTED
* @brief The Telnet server is connected to a client.
*/
#define CONNECTED 1
/**
* @internal
* Telnet commands, as defined by RFC854.
*/
#define TELNET_IAC ((char) 255)
#define TELNET_WILL ((char) 251)
#define TELNET_WONT ((char) 252)
#define TELNET_DO ((char) 253)
#define TELNET_DONT ((char) 254)
#define TELNET_SE ((char) 240)
#define TELNET_NOP ((char) 241)
#define TELNET_DATA_MARK ((char) 242)
#define TELNET_BREAK ((char) 243)
#define TELNET_IP ((char) 244)
#define TELNET_AO ((char) 245)
#define TELNET_AYT ((char) 246)
#define TELNET_EC ((char) 247)
#define TELNET_EL ((char) 248)
#define TELNET_GA ((char) 249)
#define TELNET_SB ((char) 250)
/**
* @internal
* Telnet options, as defined by RFC856-RFC861.
*/
#define TELNET_OPT_BINARY ((char) 0)
#define TELNET_OPT_ECHO ((char) 1)
#define TELNET_OPT_SUPPRESS_GA ((char) 3)
#define TELNET_OPT_STATUS ((char) 5)
#define TELNET_OPT_TIMING_MARK ((char) 6)
#define TELNET_OPT_EXOPL ((char) 255)
/**
* @def OPT_FLAG_WILL
* @brief The bit in the ucFlags member of the tTelnetOpts that is set when the remote client has sent a WILL
* request and the server has accepted it.
*/
#define OPT_FLAG_WILL ((uint8_t) 1)
/**
* @def OPT_FLAG_DO
* @brief The bit in the ucFlags member of tTelnetOpts that is set when the remote
* client has sent a DO request and the server has accepted it.
*/
#define OPT_FLAG_DO ((uint8_t) 2)
/**
* @brief Telnet options state structure.
* A structure that contains the state of the options supported by the telnet
* server, along with the possible flags.
*/
typedef struct {
char option; /**< The option byte. */
char flags; /**< The flags for this option. The bits in this byte are defined by OPT_FLAG_WILL and OPT_FLAG_DO. */
} TelnetOpts_t;
/**
* @brief Telnet parser state enumeration.
* The possible states of the telnet option parser.
*/
typedef enum {
STATE_NORMAL, /**< The telnet option parser is in its normal mode. Characters are passed as is until an IAC byte is received. */
STATE_IAC, /**< The previous character received by the telnet option parser was an IAC byte. */
STATE_WILL, /**< The previous character sequence received by the telnet option parser was IAC WILL. */
STATE_WONT, /**< The previous character sequence received by the telnet option parser was IAC WONT. */
STATE_DO, /**< The previous character sequence received by the telnet option parser was was IAC DO. */
STATE_DONT, /**< The previous character sequence received by the telnet option parser was was IAC DONT. */
} TelnetState_t;
/**
* @brief Telnet status enumeration.
* The possible success/error causes for the Telnet server's operation.
*/
typedef enum {
TELNET_OK, /**< Everything is normal with the telnet server. */
TELNET_ERR_CONNECTED, /**< There was an error in connection with the telnet server. */
/*TELNET_ERR_BADALOC,*//**< There was an error allocating memory for the telnet server. */
TELNET_ERR_BIND, /**< There was an error binding a socket to a port for the telnet server. */
TELNET_ERR_PCBCREATE /**< There was an error creating a PCB structure for the telnet server. */
} TelnetStatus_t;
/**
* @brief Data structure to hold the state of the Telnet server.
* Contains all of the necessary state variables to impliment the Telnet server. Direct manipulation of these
* members is not recommended as it may leave the server in an inconsistent state. Instead, helper methods are
* provided which will ensure that all necessary operations occur as a result of any change.
*/
typedef struct {
int halt; /**< Halt signal when the lwIP TCP/IP stack has detected an error */
TelnetState_t state; /**< The current state of the telnet option parser. */
volatile unsigned long outstanding; /**< A count of the number of bytes that have been transmitted but have not yet been ACKed. */
unsigned long close; /**< A value that is non-zero when the telnet connection should be closed down. */
unsigned char buffer[TELNET_BUFFER_LENGTH]; /**< A buffer used to construct a packet of data to be transmitted to the telnet client. */
volatile unsigned long length; /**< The number of bytes of valid data in the telnet packet buffer. */
unsigned char recvBuffer[TELNET_BUFFER_LENGTH]; /**< A buffer used to receive data from the telnet connection. */
volatile unsigned long recvWrite; /**< The offset into g_pucTelnetRecvBuffer of the next location to be written in the buffer.
The buffer is full if this value is one less than g_ulTelnetRecvRead (modulo the buffer size).*/
volatile unsigned long recvRead; /**< The offset into g_pucTelnetRecvRead of the next location to be read from the buffer.
The buffer is empty if this value is equal to g_ulTelnetRecvWrite. */
struct tcp_pcb* pcb; /**< A pointer to the telnet session PCB data structure. */
unsigned char previous; /**< The character most recently received via the telnet interface. This is used to convert CR/LF sequences
into a simple CR sequence. */
} TelnetServer_t;
/**
* @brief Initialize a TelnetServer_t struct with default values.
*/
TelnetStatus_t initialize_telnet_server(void);
/**
* @brief This function is called when the the telnet server TCP should be closed.
*/
void close_telnet_tcp(void);
/**
* @brief This function is called when the the TCP connection should be closed.
*/
void telnet_close(void);
/**
* @brief Indicates if the Telnet server is occupied or not.
*/
bool telnet_is_connected(void);
/**
* @brief Called when the lwIP TCP/IP stack needs to poll the server with/for data.
*/
err_t telnet_poll(void *arg, struct tcp_pcb *tpcb);
/**
* @brief Writes a character into the telnet receive buffer.
*/
void telnet_recv_buffer_write(char character);
/**
* @brief Reads a character from the telnet interface.
*/
char telnet_read(void);
/**
* @brief Writes a character to the telnet interface.
*/
void telnet_write(const char character);
/**
* @brief Writes a string to the telnet interface.
*/
void telnet_write_string(char* string);
/**
* @brief Handle a WILL request for a telnet option.
*/
void telnet_process_will(char option);
/**
* @brief Handle a WONT request for a telnet option.
*/
void telnet_process_wont(char option);
/**
* @brief Handle a DO request for a telnet option.
*/
void telnet_process_do(char option);
/**
* @brief Handle a DONT request for a telnet option.
*/
void telnet_process_dont(char option);
/**
* @brief Process a character received from the telnet port.
*/
void telnet_process_character(char character);
/**
* @brief Print a message to the telnet connection formatted as an error.
*/
void telnet_write_error_message(char* message);
/**
* @brief Print a message to the telnet connection formatted as a status.
*/
void telnet_write_wtatus_message(char* message);
/**
* @brief Print a message to the telnet connection formatted as a debug.
*/
void telnet_write_debug_message(char* message);
/**
* @brief Print a message to the telnet connection formatted as a command data message.
*/
void telnet_write_command_data_message(char* message);
void telnet_write_revc_message(char* message);
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* TELNET_SERVER_H_ */