Hi,
I'm transferring a file by TFTP from PC to our board, using a LM3S9B96. It works fine, except when I break the connection in the middle of a transfer (i.e. forcibly closing application on PC). After this event, no more UDP connection can be made to the board (i.e. also the Finder application couldn't locate the board).
As I don't have an evaluation board to test the original qs-checkout demo to see if this happens, I would like to know if there is anybody that could perform this test and post results here.
Many thanks in advance and best regards
Stefano
Stefano,
We have seen this issue before, it is typically due to the network restrictions for UDP. Check with your internal network to see if UDP (UPnP) is enabled.
The finder application does not work on development or evaluation kits with an OLED. This is done within StellarisWare. If you are using unmodified StellarisWare example qs-checkout, then the finder will not find it.
Thanks,
Sean de la Haye
Hi Sean,
I think UDP is correctly working, as Finder is locating all of our boards. The problem arise when a TFTP connection is closed by the client. I'm using TFTPD32 (64 bit version, you can find it here). When I start a PUT request and then, after some packets, click on the break button, the transfer stop. From this moment Finder is not working anymore and I have to reset my board to make it working again. I'm currently investigating this problem and will post here my results.
Best regards,
Ok, after a little bit of investigation I found the problem being into UDP socket handling.
Actually lwIP is configured with an UDP pcb pool size of 4 elements. Two pcb are in use:
When a TFTP connection is started, a new pcb is allocated from the pool; once upon a connection is correctly completed, pcb is removed and put back in the pool. If a connection is broken, the active pcb still remain in the active pcb list, and it's not released back in the pool. If you have two TFTP connection that suddenly blocks, you waste two pcb so that no more pcb are available into the pool.
Now, when a new connection attempt is made on UDP/69, a new pcb should be allocated and put into the active pcb list. Allocation obviously fails, as there are no more pcb in the pool, and it seems that a NULL pcb pointer is put into the active pcb list, breaking up the list and all of the active pcb. Now I'm trying to search why this non-allocated pcb is put into the list, instead of discarding the incoming packet. Furthermore it would be great to have a timeout option on the TFTP server side to abort the TFTP connection so that all unused allocated pcb could be freed-up.
Cheers,
Ok, found the problem about the NULL pcb pointer.
Actually I'm using tftp.c from Stellarisware revision 8555. You can easily find that on lines #613 and #696 there is no error checking for udp_new() function return.
Line #613 is causing the overwriting problem: return code should be checked and eventually a TFTP error should be returned to the remote party if no more pcb are available.
On line #696 udp_new() function return should be checked to eventually signal the main application about the service not being started.
Now I'm looking for some way to handle a timeout on UDP connection.
Bye,
I can confirm that I've been able to replicate the problem on a DK-LM3S9B96 board. I will talk with my co-workers and start investigating what it will take to fix this problem.
Sean
Thanks Sean.
In the meanwhile I modified tftp.c source code (see attached files). Basically I added two test on udp_new() result value: these test avoid overwriting UDP pcb list.
About the timeout to be used for closing pending opened connection, I decided to work on a per-connection base. Assuming we transfer one file at a time, when a new connection request is coming from a client we should abort the previous connection. So:
This way we have at most one pcb wasted in case of communication trouble, but this pcb is recollected when a new incoming connection is done.
I'll wait for your comments.
Thanks and greetings,
8738.tftp_server_code.zip
I am glad to hear you got it working. I have created an internal bug report to get this problem fixed in the TFTP server. I have attached your code as reference for the fix.
It sounds like we may also need to record current connections and add a timer to the server to provide a method to check for timeouts.
Thanks for your support Sean.
See you.