lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lwip-users] Need help with tcp-raw-api app. Wrong checksum sometimes ca


From: Steffen
Subject: [lwip-users] Need help with tcp-raw-api app. Wrong checksum sometimes calculatet ....THX !!!
Date: Sun, 08 Nov 2009 17:52:36 +0100
User-agent: Thunderbird 2.0.0.23 (Windows/20090812)

Hi @ all,

I have a urgent problem with a Lwip-tcp-App. I use a standart raw api tcp app except the sending function at the end of the file. The applications works. The problem is, in some situations the tcp checksum is wrong. When i receive a PSH/ACK paket, i send a answere (tcp_recv_diag). This works fine, but i have to send a second paket after a while (when results of something are available). For this i've wrote a function (SendDiagnoseMessage(u08 source_address, u08 destination_address, u08 *message, u16 length) you can find it at the end of the file). This function works most time fine, but sometimes the tcp-checksum of exatly this paket is wrong. The wrong checksum happens ONLY when 1ms bevor i send this paket another paket is received (it seems the connection gets asynchron).

thank you very much for your help Steffen

/*-----------------------------------------------------------------------------------*/
static void
tcp_conn_err_diag(void *arg, err_t err)
{

struct ETH_Diagnose_Struct *hs;

LWIP_UNUSED_ARG(err);

hs = arg;
mem_free(hs);
}
/*-----------------------------------------------------------------------------------*/
static void
tcp_close_conn_diag(struct tcp_pcb *pcb, struct ETH_Diagnose_Struct *hs)
{
tcp_arg(pcb, NULL);
tcp_sent(pcb, NULL);
tcp_recv(pcb, NULL);
if(hs!=NULL)
{  mem_free(hs);}
tcp_close(pcb);
}
/*-----------------------------------------------------------------------------------*/

static void
tcp_send_data_diag(struct tcp_pcb *pcb, struct ETH_Diagnose_Struct *hs)
{
err_t err;
u16_t len;

/* We cannot send more data than space available in the send
 buffer. */
if (tcp_sndbuf(pcb) < hs->left)
{
len = tcp_sndbuf(pcb);
}
else
{
len = hs->left;
}




do
{
err = tcp_write(pcb, hs->file, len, 1);
tcp_output(pcb);
/*Changed from ,0 to ,
 * The copy argument is either 0 or 1 and indicates
* whether the new memory should be allocated for the data to be copied into. */
if (err == ERR_MEM)
{
  len /= 2;
}
} while (err == ERR_MEM && len > 1);

if (err == ERR_OK)
{
hs->file += len;
hs->left -= len;
/*  } else {
printf("send_data: error %s len %d %d\n", lwip_strerr(err), len, tcp_sndbuf(pcb));*/

}
}
/*-----------------------------------------------------------------------------------*/
static err_t
tcp_poll_diag(void *arg, struct tcp_pcb *pcb)
{
struct ETH_Diagnose_Struct *hs;

hs = arg;

/*  printf("Poll\n");*/
if (hs == NULL)
{
/*    printf("Null, close\n");*/
tcp_abort(pcb);
return ERR_ABRT;
}
else
{
++hs->retries;
if (hs->retries == 4)
{
  // disable automatic connection closing
  //tcp_abort(pcb);
  return ERR_ABRT;
}
tcp_send_data_diag(pcb, hs);
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static s08
tcp_sent_diag(void *arg, struct tcp_pcb *pcb, u16_t len)
{
struct ETH_Diagnose_Struct *hs;

LWIP_UNUSED_ARG(len);

hs = arg;

hs->retries = 0;

if (hs->left > 0)
{
  tcp_send_data_diag(pcb, hs);
}
else
{
  // clear if connection should not be closed
  //tcp_close_conn_diag(pcb, hs);
}

return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/

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

struct ETH_Diagnose_Struct *hs_send_diagnose_message;

hs_send_diagnose_message = arg;

if (err == ERR_OK && p != NULL)
{
  /* Inform TCP that we have taken the data. */
  tcp_recved(pcb, p->tot_len);

  if (hs_send_diagnose_message->file == NULL )
  {

      // Handle received message
      //------------------------
hs_send_diagnose_message->left = ProcessDiagPacket (p->payload, p->len);
      hs_send_diagnose_message->file = ack_buf;

      if(hs_send_diagnose_message->left >0)
        {
            // send reply
            pbuf_free(p);
            tcp_send_data_diag(pcb, hs_send_diagnose_message);
            tcp_sent(pcb, tcp_sent_diag);


        }
        else
        {
            //WrongMsgReceived
            pbuf_free(p);
        }
  }
  else
  {
      pbuf_free(p);
  }
}

//send_data(pcb, hs);
if (err == ERR_OK && p == NULL)
{
tcp_close_conn_diag(pcb, hs_send_diagnose_message);
}

return ERR_OK;
}

/*-----------------------------------------------------------------------------------*/
static err_t
tcp_accept_diag(void *arg, struct tcp_pcb *pcb, err_t err)
{
struct ETH_Diagnose_Struct *hs;

LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(err);

tcp_setprio(pcb, TCP_PRIO_MIN);

/* Allocate memory for the structure that holds the state of the
 connection. */
hs = (struct ETH_Diagnose_Struct *)mem_malloc(sizeof(struct ETH_Diagnose_Struct));

if (hs == NULL) {
return ERR_MEM;
}


/* Initialize the structure. */
hs->file = NULL;
hs->left = 0;
hs->retries = 0;

/* Tell TCP that this is the structure we wish to be passed for our
 callbacks. */
tcp_arg(pcb, hs);

/* Tell TCP that we wish to be informed of incoming data by a call
 to the http_recv() function. */
tcp_recv(pcb, tcp_recv_diag);

tcp_err(pcb, tcp_conn_err_diag);

tcp_poll(pcb, tcp_poll_diag, 4);
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
void
tcp_init_diag(void)
{
struct tcp_pcb *pcb;

pcb = tcp_new();
tcp_bind(pcb, IP_ADDR_ANY, DIAGNOSE_TCP_PORT);
pcb = tcp_listen(pcb);
tcp_accept(pcb, tcp_accept_diag);
}
/*-----------------------------------------------------------------------------------*/

void SendDiagnoseMessage(u08 source_address, u08 destination_address, u08 *message, u16 length)
{

struct ETH_Diagnose_Struct *hs_send_diagnose_message;
struct tcp_pcb *apcbs = tcp_active_pcbs;
u32 i=0;

while (apcbs != NULL)
{
        if (apcbs->local_port == DIAGNOSE_TCP_PORT)
        {
            hs_send_diagnose_message = apcbs->callback_arg;

            if (hs_send_diagnose_message->file == NULL  )
            {

                /* build tcp_diag_response_header */
                DiagResponseHeader->len = (u32)length + DIAG_ADDRESS_LEN;
                DiagResponseHeader->ctrl_word = DIAG_RESP_CW;
                DiagResponseHeader->source = source_address;
                DiagResponseHeader->target = destination_address;

                /* copy payload */
                for(i=0; i < length; i++)
                {
                    diag_buf[i+ HEADER_LEN + DIAG_ADDRESS_LEN] = *message;
                    message++;
                }


                hs_send_diagnose_message->file = (u08*)&diag_buf;
hs_send_diagnose_message->left = length + HEADER_LEN + DIAG_ADDRESS_LEN;

                if(hs_send_diagnose_message->left >0)
                {
                    tcp_send_data_diag(apcbs, hs_send_diagnose_message);
                    tcp_sent(apcbs, tcp_sent_diag);
                }
            }
            break;
        }
        apcbs = apcbs->next;
}
}





reply via email to

[Prev in Thread] Current Thread [Next in Thread]