lwip -telnet移植

2019-07-14 10:24发布

//注:telnet命令在超级终端输入字符,是需要远程回显字符才能看到(即要软件自己实现)   /* Includes ------------------------------------------------------------------*/
#include "helloworld.h"
#include "lwip/tcp.h"
#include


/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define GREETING "Hello. What is your name? "
#define HELLO "Hello "
#define MAX_NAME_SIZE 32


/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
struct name 
{
  int length;
  char bytes[MAX_NAME_SIZE];
};


/* Private function prototypes -----------------------------------------------*/
static err_t HelloWorld_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
static err_t HelloWorld_accept(void *arg, struct tcp_pcb *pcb, err_t err);
static void HelloWorld_conn_err(void *arg, err_t err);


/* Private functions ---------------------------------------------------------*/


/**
  * @brief  Called when a data is received on the telnet connection
  * @param  arg        the user argument
  * @param  pcb        the tcp_pcb that has received the data
  * @param  p        the packet buffer
  * @param  err        the error value linked with the received data
  * @retval error value
  */
static err_t HelloWorld_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
  struct pbuf *q;
  struct name *name = (struct name *)arg;
  int done;
  char *c;
  int i;
 


  /* We perform here any necessary processing on the pbuf */
  if (p != NULL) 
  {        
        /* We call this function to tell the LwIp that we have processed the data */
        /* This lets the stack advertise a larger window, so more data can be received*/
        tcp_recved(pcb, p->tot_len);


    /* Check the name if NULL, no data passed, return withh illegal argument error */
        if(!name) 
    {
      pbuf_free(p);
      return ERR_ARG;
    }


    done = 0;
    for(q=p; q != NULL; q = q->next) 
    {
      c = q->payload;
      for(i=0; ilen && !done; i++) 
          {
        done = ((c[i] == ' ') || (c[i] == ' '));
        if(name->length < MAX_NAME_SIZE) 
            {
          name->bytes[name->length++] = c[i];
        }
      }
    }
    if(done) 
    {
      if(name->bytes[name->length-2] != ' ' || name->bytes[name->length-1] != ' ') 
          {
        if((name->bytes[name->length-1] == ' ' || name->bytes[name->length-1] == ' ') && (name->length+1 <= MAX_NAME_SIZE)) 
            {
              name->length += 1;
        } 
            else if(name->length+2 <= MAX_NAME_SIZE) 
            {
          name->length += 2;
        } 
            else 
            {
          name->length = MAX_NAME_SIZE;
        }


        name->bytes[name->length-2] = ' ';
        name->bytes[name->length-1] = ' ';
      }
      tcp_write(pcb, HELLO, strlen(HELLO), 1);


      tcp_write(pcb, name->bytes, name->length, TCP_WRITE_FLAG_COPY);
      name->length = 0;
    }
        
        /* End of processing, we free the pbuf */
    pbuf_free(p);
  }  
  else if (err == ERR_OK) 
  {
    /* When the pbuf is NULL and the err is ERR_OK, the remote end is closing the connection. */
    /* We free the allocated memory and we close the connection */
    mem_free(name);
    return tcp_close(pcb);
  }
  return ERR_OK;




}


/**
  * @brief  This function when the Telnet connection is established
  * @param  arg  user supplied argument 
  * @param  pcb         the tcp_pcb which accepted the connection
  * @param  err         error value
  * @retval ERR_OK
  */
static err_t HelloWorld_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{     
  
  /* Tell LwIP to associate this structure with this connection. */
  tcp_arg(pcb, mem_calloc(sizeof(struct name), 1));        
  
  /* Configure LwIP to use our call back functions. */
  tcp_err(pcb, HelloWorld_conn_err);
  tcp_recv(pcb, HelloWorld_recv);
  
  /* Send out the first message */  
  tcp_write(pcb, GREETING, strlen(GREETING), 1); 


  return ERR_OK;
}


/**
  * @brief  Initialize the hello application  
  * @param  None 
  * @retval None 
  */
void HelloWorld_init(void)
{
  struct tcp_pcb *pcb;                                    
  
  /* Create a new TCP control block  */
  pcb = tcp_new();                                                 


  /* Assign to the new pcb a local IP address and a port number */
  /* Using IP_ADDR_ANY allow the pcb to be used by any local interface */
  tcp_bind(pcb, IP_ADDR_ANY, 23);       




  /* Set the connection to the LISTEN state */
  pcb = tcp_listen(pcb);                                


  /* Specify the function to be called when a connection is established */        
  tcp_accept(pcb, HelloWorld_accept);   
                                                                                
}


/**
  * @brief  This function is called when an error occurs on the connection 
  * @param  arg
  * @parm   err
  * @retval None 
  */
static void HelloWorld_conn_err(void *arg, err_t err)
{
  struct name *name;
  name = (struct name *)arg;


  mem_free(name);
}