[Top][All Lists]
[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;
}
}
- [lwip-users] Need help with tcp-raw-api app. Wrong checksum sometimes calculatet ....THX !!!,
Steffen <=