LWIP через некоторое время зависает - PullRequest
0 голосов
/ 11 июля 2020

Я использую LWIP (2.1.3) на LPC546xx со связью по 2 портам. После инициализации TCPIP вызывается port_init (), port2_init () для портов binf 23,24. Когда я получаю данные, я передаю их функциям task_port1 и task_port2. Когда у меня есть данные, я вызываю функцию send_response_port, send_response_port2. Это работает, но моя проблема в том, что он иногда теряет ответный пакет, а иногда застревает, поэтому его необходимо сбросить.

Правильно ли я использую ссылку на pcbAcceptedport, которую я сохраняю в переменной в функции port_accept?

Спасибо.

static struct tcp_pcb *pcbAcceptedport = NULL;
static struct tcp_pcb *pcbAcceptedport2 = NULL;

    void
port1_init(void)
{
    pcbAcceptedport = tcp_new();
  if (pcbAcceptedport != NULL)
  {
    err_t err;

    err = tcp_bind(pcbAcceptedport, IP_ADDR_ANY, 23);
    if (err == ERR_OK)
    {
        pcbAcceptedport = tcp_listen(pcbAcceptedport);
      tcp_accept(pcbAcceptedport, port_accept);
    }
    else
    {
      /* abort? output diagnostic? */
    }
  }
  else
  {
    /* abort? output diagnostic? */
  }
}

static void port_close_conn(struct tcp_pcb *pcb){
      tcp_arg(pcb, NULL);
      tcp_sent(pcb, NULL);
      tcp_recv(pcb, NULL);
      tcp_close(pcb);
}

static err_t port_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err){
      int i;
      int len;
      char *pc;

      if (err == ERR_OK && p != NULL) {
            /* Inform TCP that we have taken the data. */
            u32_rec_port = p->tot_len;
            tcp_recved(pcbAcceptedport, u32_rec_port);
            task_port1(p);            
           //Free the packet buffer
            pbuf_free(p);

      } else {
            pbuf_free(p);
      }

      if (err == ERR_OK && p == NULL) {
          port_close_conn(pcb);
      }
      return ERR_OK;
}
void port_error(void *arg, err_t err)
{
  LWIP_UNUSED_ARG(err);
}
static err_t port_accept(void *arg, struct tcp_pcb *pcb, err_t err){
      LWIP_UNUSED_ARG(arg);
      LWIP_UNUSED_ARG(err);
      tcp_setprio(pcb, TCP_PRIO_NORMAL);
      tcp_recv(pcb, port_recv);
      tcp_err(pcb, port_error); //Don't care about error here
      tcp_poll(pcb, NULL, 4); //No polling here
      pcbAcceptedport = pcb;
      return ERR_OK;
}

err_t port_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
{
  LWIP_UNUSED_ARG(len);
  return ERR_OK;
}

err_t send_response_port(uint8_t *data, uint32_t len){
    err_t e = 0xFF;
    //check output buffer capacity
    if (len < tcp_sndbuf(pcbAcceptedPort)){
        e = tcp_write(pcbAcceptedport, data, len, 0);
        if(e == ERR_OK){
            tcp_sent(pcbAcceptedport, port_sent); /* No need to call back */
            if(e == ERR_OK){
                tcp_recved(pcbAcceptedport, u32_rec_port);
                e = tcp_output(pcbAcceptedport);
            }
        }
    }
    return e;
}
/************************************************************/

void
port2_init(void)
{
    pcbAcceptedPort2 = tcp_new();
      if (pcbAcceptedPort2 != NULL)
      {
        err_t err;

        err = tcp_bind(pcbAcceptedPort2, IP_ADDR_ANY, 24);
        if (err == ERR_OK)
        {
            pcbAcceptedPort2 = tcp_listen(pcbAcceptedPort2);
            tcp_accept(pcbAcceptedPort2, port2_accept);
        }
        else
        {
          /* abort? output diagnostic? */
        }
      }
      else
      {
        /* abort? output diagnostic? */
      }
}

static void port2_close_conn(struct tcp_pcb *pcb){
      tcp_arg(pcb, NULL);
      tcp_sent(pcb, NULL);
      tcp_recv(pcb, NULL);
      tcp_close(pcb);
}

static err_t port2_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err){

      if (err == ERR_OK && p != NULL) {
          /* Inform TCP that we have taken the data. */
          u32_rec_Port2 = p->tot_len;
          tcp_recved(pcbAcceptedPort2, u32_rec_Port2);         
          task_port2(p);
          //Free the packet buffer
          pbuf_free(p);

      } else {
            pbuf_free(p);
      }

      if (err == ERR_OK && p == NULL) {
          port2_close_conn(pcb);
      }
      return ERR_OK;
}
void port2_error(void *arg, err_t err)
{
  LWIP_UNUSED_ARG(err);
}
static err_t port2_accept(void *arg, struct tcp_pcb *pcb, err_t err){
      LWIP_UNUSED_ARG(arg);
      LWIP_UNUSED_ARG(err);
      tcp_setprio(pcb, TCP_PRIO_NORMAL);
      tcp_recv(pcb, port2_recv);
      tcp_err(pcb, port2_error); //Don't care about error here
      tcp_poll(pcb, NULL, 4); //No polling here
      pcbAcceptedPort2 = pcb;
      return ERR_OK;
}


err_t Port2_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
{
  LWIP_UNUSED_ARG(len);
  return ERR_OK;
}


err_t send_response_Port2(uint8_t *data, uint32_t len){
    err_t e = 0xFF;
    if (len <= tcp_sndbuf(pcbAcceptedPort2)){
        e = tcp_write(pcbAcceptedPort2, data, len, 0);
        if(e == ERR_OK){
            tcp_sent(pcbAcceptedPort2, Port2_sent); /* No need to call back */
            if(e == ERR_OK){
                e = tcp_output(pcbAcceptedPort2);
            }
        }
        
    }
    return e;


}
...