Hi,
please find here my function http_poll:
static err_t
http_poll(void *arg, struct tcp_pcb *pcb)
{
struct http_connect_state* hcs;
hcs = arg;
if (hcs == NULL) {
tcp_abort(pcb);
return ERR_ABRT;
} else {
++hcs->retries;
if (hcs->retries >= 4) {
tcp_abort(pcb);
return ERR_ABRT;
}
send_data(pcb, hcs);
}
return ERR_OK;
}
Can you explain me what is the purpose of this function?
Baptiste
Quoting Bill Auerbach <[email protected]>:
What does your http_poll do?
From: [email protected]
[mailto:[email protected]] On Behalf
Of Baptiste Chaboud-crousaz
Sent: Thursday, August 06, 2009 5:51 AM
To: [email protected]
Subject: Re: [lwip-users] Problem with NULL pcb->callback_arg
Hi all,
Since my problem is not resolved, I ask you again to help me.
I use the HTTP (RAW version) server provided by the lwip site in the
/contrib/apps/httpserver_raw folder.
Sometimes, the argument passed to http_sent is NULL which leads an hardfault
exception. In the majority of cases, there is no problem. This problem is
avoided or limited when I increases the size of MEM_SIZE. But I have to
drastically reduce this size to meet my hardware requirements.
My understanding is that a memory allocation is done out the memory space
dedicted to lwip.
But I don' understand how it can be possible. All the results of memory
allocation are checked. Would it be possible that there is a bug in lwip? If
yes where?
What should I do?????
Best regards.
Baptiste
Quoting Baptiste Chaboud-crousaz <[email protected]>:
Hi,
For a better understanding I give a part of the code of my HTTP server:
===============================================
void httpd_init(void)
{
struct tcp_pcb *pcb;
pcb = tcp_new();
tcp_bind(pcb, IP_ADDR_ANY, 80);
pcb = tcp_listen(pcb);
tcp_accept(pcb, http_accept);
}
===============================================
static err_t
http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
struct http_connect_state* hcs;
tcp_setprio(pcb, TCP_PRIO_MIN);
/* Allocate memory for the structure that holds the state of the
connection. */
hcs = mem_malloc(sizeof(struct http_connect_state));
if (hcs == NULL) {
return ERR_MEM;
}
/* Initialize the structure. */
hcs->file = NULL;
hcs->resource_id = 0;
hcs->method_id = 0;
hcs->retries = 0;
/* Tell TCP that this is the structure we wish to be passed for
our callbacks. */
tcp_arg(pcb, hcs);
/* Tell TCP that we wish to be informed of incoming data by a
call to the http_recv() function. */
tcp_recv(pcb, http_recv);
tcp_err(pcb, conn_err);
tcp_poll(pcb, http_poll, 4);
return ERR_OK;
}
===============================================
static err_t
http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
struct http_connect_state* hcs;
hcs = arg;
if (ERR_OK == err)
{
if (NULL != p)
{
/* Inform TCP that we have taken the data. */
tcp_recved(pcb, p->tot_len);
if (hcs->file == NULL)
{
ProcessHttpRequest(hcs, p, &(pcb->remote_ip));
if (hcs->file != NULL)
{
pbuf_free(p);
send_data(pcb, hcs);
/* Tell TCP that we wish be to informed of data
that has been
successfully sent by a call to the http_sent()
function. */
tcp_sent(pcb, http_sent);
}
else
{
pbuf_free(p);
p = NULL;
}
}
else
{
pbuf_free(p);
p = NULL;
}
}
if (NULL == p)
{
close_conn(pcb, hcs);
}
}
return err;
}
===============================================
static err_t
http_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
{
struct http_connect_state* hcs;
if(arg != NULL)
{
hcs = arg;
hcs->retries = 0;
send_data(pcb, hcs);
}
return ERR_OK;
}
===============================================
static void
close_conn(struct tcp_pcb *pcb, struct http_connect_state* hcs)
{
tcp_arg(pcb, NULL);
tcp_sent(pcb, NULL);
tcp_recv(pcb, NULL);
if(hcs->file) {
wfs_close(hcs->file);
hcs->file = NULL;
}
mem_free(hcs);
tcp_close(pcb);
}
===============================================
As you can see at the HTTP init, the http_accept is set as callback
for ACCEPT and in http_recv, http_sent is set as callback which will
be called by TCP_EVENT_SENT.
When I use a single web browser there is no problem: the arg value
passed to http_sent is never NULL. But when I launch another web
browser, this parameter becomes sometimes NULL. It seems to be when
the stack receives the new SYN frame from the client.
You said "That could be a hint that you are writing beyond allocated
memory
somwhere and overwrite the memory where the PCB lies with zeros". But
I always check the returned value when I make a memory allocation. If
the functions used for memory allocation return an invalid space =>
there is a bug in the stack!
Baptiste
Quoting "[email protected]" <[email protected]>:
Baptiste Chaboud-crousaz wrote:
Sometimes, the face trouble with my callback http_connect -
called by the macro TCP_EVENT_SENT - because "arg" is null.
I don't understand that one:
a) there is no function 'http_connect' in the code you posted
b) TCP_EVENT_SENT calls the function set by calling tcp_sent(pcb, fn) -
the code you posted doesn't call tcp_sent().
c) I would have thought a connect function would be used with a client,
not a server - whereas an accept function (as you posted) is used with
a server, not a client)
My understanding is that the http_accept function binds a pcb to
an argument by a call to tcp_arg(...). I don't undersatnd why
sometimes my callback is called with a NULL arg!!!
This issue seems to be avoided/limited by increasing the size of
MEM_SIZE and PBUF_POOL_SIZE.
That could be a hint that you are writing beyond allocated memory
somwhere and overwrite the memory where the PCB lies with zeros...
If anybody has an idea, let me knwo about it...
Except for the above, I'm afraid I don't have an idea. Unless you call
*tcp_arg(pcb, NULL) somewhere else, of course...*
Does the argument get NULL during the connection or right at the start?
Simon
_______________________________________________
lwip-users mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/lwip-users
_______________________________________________
lwip-users mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/lwip-users