📄 ser2enet.c
字号:
//
// Return without any further processing.
//
return;
}
}
//
// This option is not recognized, so send a WONT response.
//
g_pucTelnetBuffer[g_ulTelnetLength++] = TELNET_IAC;
g_pucTelnetBuffer[g_ulTelnetLength++] = TELNET_WONT;
g_pucTelnetBuffer[g_ulTelnetLength++] = ucOption;
}
//*****************************************************************************
//
//! Processes a character received from the telnet port.
//!
//! \param ucChar is the character in question.
//!
//! This function processes a character received from the telnet port, handling
//! the interpretation of telnet commands (as indicated by the telnet interpret
//! as command (IAC) byte).
//!
//! \return None.
//
//*****************************************************************************
static void
TelnetProcessCharacter(unsigned char ucChar)
{
//
// Determine the current state of the telnet command parser.
//
switch(g_eState)
{
//
// The normal state of the parser, were each character is either sent
// to the UART or is a telnet IAC character.
//
case STATE_NORMAL:
{
//
// See if this character is the IAC character.
//
if(ucChar == TELNET_IAC)
{
//
// Skip this character and go to the IAC state.
//
g_eState = STATE_IAC;
}
else
{
//
// Write this character to the UART.
//
UARTSend(ucChar);
}
//
// This state has been handled.
//
break;
}
//
// The previous character was the IAC character.
//
case STATE_IAC:
{
//
// Determine how to interpret this character.
//
switch(ucChar)
{
//
// See if this character is also an IAC character.
//
case TELNET_IAC:
{
//
// Send 0xff to the UART.
//
UARTSend(ucChar);
//
// Switch back to normal mode.
//
g_eState = STATE_NORMAL;
//
// This character has been handled.
//
break;
}
//
// See if this character is the WILL request.
//
case TELNET_WILL:
{
//
// Switch to the WILL mode; the next character will have
// the option in question.
//
g_eState = STATE_WILL;
//
// This character has been handled.
//
break;
}
//
// See if this character is the WONT request.
//
case TELNET_WONT:
{
//
// Switch to the WONT mode; the next character will have
// the option in question.
//
g_eState = STATE_WONT;
//
// This character has been handled.
//
break;
}
//
// See if this character is the DO request.
//
case TELNET_DO:
{
//
// Switch to the DO mode; the next character will have the
// option in question.
//
g_eState = STATE_DO;
//
// This character has been handled.
//
break;
}
//
// See if this character is the DONT request.
//
case TELNET_DONT:
{
//
// Switch to the DONT mode; the next character will have
// the option in question.
//
g_eState = STATE_DONT;
//
// This character has been handled.
//
break;
}
//
// See if this character is the AYT request.
//
case TELNET_AYT:
{
//
// Send a short string back to the client so that it knows
// that we're still alive.
//
g_pucTelnetBuffer[g_ulTelnetLength++] = '\r';
g_pucTelnetBuffer[g_ulTelnetLength++] = '\n';
g_pucTelnetBuffer[g_ulTelnetLength++] = '[';
g_pucTelnetBuffer[g_ulTelnetLength++] = 'Y';
g_pucTelnetBuffer[g_ulTelnetLength++] = 'e';
g_pucTelnetBuffer[g_ulTelnetLength++] = 's';
g_pucTelnetBuffer[g_ulTelnetLength++] = ']';
g_pucTelnetBuffer[g_ulTelnetLength++] = '\r';
g_pucTelnetBuffer[g_ulTelnetLength++] = '\n';
//
// Switch back to normal mode.
//
g_eState = STATE_NORMAL;
//
// This character has been handled.
//
break;
}
//
// Explicitly ignore the GA and NOP request, plus provide a
// catch-all ignore for unrecognized requests.
//
case TELNET_GA:
case TELNET_NOP:
default:
{
//
// Switch back to normal mode.
//
g_eState = STATE_NORMAL;
//
// This character has been handled.
//
break;
}
}
//
// This state has been handled.
//
break;
}
//
// The previous character sequence was IAC WILL.
//
case STATE_WILL:
{
//
// Process the WILL request on this option.
//
TelnetProcessWill(ucChar);
//
// Switch back to normal mode.
//
g_eState = STATE_NORMAL;
//
// This state has been handled.
//
break;
}
//
// The previous character sequence was IAC WONT.
//
case STATE_WONT:
{
//
// Process the WONT request on this option.
//
TelnetProcessWont(ucChar);
//
// Switch back to normal mode.
//
g_eState = STATE_NORMAL;
//
// This state has been handled.
//
break;
}
//
// The previous character sequence was IAC DO.
//
case STATE_DO:
{
//
// Process the DO request on this option.
//
TelnetProcessDo(ucChar);
//
// Switch back to normal mode.
//
g_eState = STATE_NORMAL;
//
// This state has been handled.
//
break;
}
//
// The previous character sequence was IAC DONT.
//
case STATE_DONT:
{
//
// Process the DONT request on this option.
//
TelnetProcessDont(ucChar);
//
// Switch back to normal mode.
//
g_eState = STATE_NORMAL;
//
// This state has been handled.
//
break;
}
//
// A catch-all for unknown states. This should never be reached, but
// is provided just in case it is ever needed.
//
default:
{
//
// Switch back to normal mode.
//
g_eState = STATE_NORMAL;
//
// This state has been handled.
//
break;
}
}
}
//*****************************************************************************
//
//! Receives a TCP packet from lwIP for the telnet server.
//!
//! \param arg is not used in this implementation.
//! \param pcb is the pointer to the TCP control structure.
//! \param p is the pointer to the PBUF structure containing the packet data.
//! \param err is used to indicate if any errors are associated with the
//! incoming packet.
//!
//! This function is called when the lwIP TCP/IP stack has an incoming packet
//! to be processed.
//!
//! \return This function will return an lwIP defined error code.
//
//*****************************************************************************
static err_t
TelnetReceive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
struct pbuf *q;
unsigned long ulIdx;
unsigned char *pucData;
//
// Process the incoming packet.
//
if((err == ERR_OK) && (p != NULL))
{
//
// Accept the packet from TCP.
//
tcp_recved(pcb, p->tot_len);
//
// Loop through the pbufs in this packet.
//
for(q = p, pucData = q->payload; q != NULL; q = q->next)
{
//
// Loop through the bytes in this pbuf.
//
for(ulIdx = 0; ulIdx < q->len; ulIdx++)
{
//
// Process this character.
//
TelnetProcessCharacter(pucData[ulIdx]);
}
}
//
// Free the pbuf.
//
pbuf_free(p);
}
//
// If a null packet is passed in, close the connection.
//
else if((err == ERR_OK) && (p == NULL))
{
TelnetClose(pcb);
}
//
// Return okay.
//
return(ERR_OK);
}
//*****************************************************************************
//
//! Handles lwIP TCP/IP errors.
//!
//! \param arg is not used in this implementation.
//! \param err is the error that was detected.
//!
//! This function is called when the lwIP TCP/IP stack has detected an error.
//! The connection is no longer valid.
//!
//! \return None.
//
//*****************************************************************************
static void
TelnetError(void *arg, err_t err)
{
//
// Reset our connection.
//
g_psTelnetPCB = NULL;
}
//*****************************************************************************
//
//! Handles lwIP TCP/IP polling and timeout requests.
//!
//! \param arg is not used in this implementation.
//! \param pcb is the pointer to the TCP control structure.
//!
//! This function is called when the lwIP TCP/IP stack has no incoming or
//! outgoing data. It can be used to reset an idle connection.
//!
//! \return This function will return an lwIP defined error code.
//
//*****************************************************************************
static err_t
TelnetPoll(void *arg, struct tcp_pcb *pcb)
{
//
// Increment the timeout value and close the telnet connection if the
// configured timeout has been exceeded.
//
#if TELNET_TIMEOUT
g_ulConnectionTimeout++;
if(g_ulConnectionTimeout > TELNET_TIMEOUT)
{
//
// Close the telnet connection.
//
tcp_abort(g_psTelnetPCB);
g_psTelnetPCB = NULL;
}
#endif
//
// Return OK.
//
return(ERR_OK);
}
//*****************************************************************************
//
//! Handles acknowledgment of data transmitted via Ethernet.
//!
//! \param arg is not used in this implementation.
//! \param pcb is the pointer to the TCP control structure.
//! \param len is the length of the data transmitted.
//!
//! This function is called when the lwIP TCP/IP stack has received an
//! acknowledgment for data that has been transmitted.
//!
//! \return This function will return an lwIP defined error code.
//
//*****************************************************************************
static err_t
TelnetSent(void *arg, struct tcp_pcb *pcb, u16_t len)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -