This is a lengthy explanation, but after
2-3 weeks of banging my head into the wall I think it is necessary.
I am working on a Telnet server using
1.2.0 release (as I am unable to get latest CVS head to compile and run
on the AT91SAM7X demo board under FreeRTOS). Because 1.2.0 does not
support receive timeouts, the server is implemented as two tasks. One
handles the "receive from network" and the other "send to
network" functions, using FreeRTOS queues to send character data to/from
the application task.
Before you say "upgrade to the
latest CVS head" - I have already tried unsuccessfully for much of
this time to do just that, however the update simply doesn't work, even
when I roll back to just porting the new LWIP to the original FreeRTOS
demo that I got with the original.
A little more background...
It is possible for the application task
to request a session end (primarily to log out idle users). This
is accomplished with the following code:
static void close_telnet (void)
{
if
(net_connection_open)
{
// Network connection is closed again
net_connection_open = FALSE;
// Don't do this again until new connection
starts
idletimer = 0;
netconn_close (telnetNetCon);
tn_isonline[0] = FALSE;
while (netconn_delete (telnetNetCon) != ERR_OK)
{
vTaskDelay
(TELNET_SHORT_DELAY);
}
vTaskDelay (TELNET_LONG_DELAY);
}
}
(Note: The variable "net_connection_open"
is a flag which is set TRUE when the receiver task gets a connection from
a client and starts communicating with them.)
While this is going on, the "read
from network" task is waiting in a netconn_recv() call. It does
not return immediately when the other task calls close_telnet() above (which
I would expect due to the netconn_close() and netconn_delete() calls).
The client tells me immediately that
it has lost its connection when close_telnet() is executed.
If I then attempt another connection
from a client, the "read from network" task returns from the
netconn_recv() it has been in, but the return value is pointing to the
same location as when it was receiving valid data. At this point
I just netbuf_delete() it, then go back to a netconn_accept() waiting for
the next telnet client to attach.
It accepts the connection, returning
same pointer address as previous connection. Starts the connection
process (which includes sending a DO and DONT string to the client), but
when the program starts attempting to wait for more data to come from the
new client, the micro resets with a data abort (on the ARM7, this generally
means that data was either mis-aligned or not present).
Another scenario - the client disconnects
from the server. When this happens, I am able to start a new client
and log in once successfully, but logging out and attempting a third time
results in a data abort also.
If you need the code, I would be happy
to provide it. If you have ANY advice, I'd love to hear it.