unable to receive large UDP packets

08 May 2012

My application requires to receive large UDP packets with payload of 900+ bytes. I'm using NetServices API. I discovered that I'm able to receive packets up to about 650 bytes, but anything larger is just lost somewhere in the labyrinth of HW and APIs. I use UDPSocket class and what I experience is that it's event handler method is not invoked on large packets.

I've made tests with different payload sizes and I found a strange behaviour. When I send a 750 bytes packet I receive the first one. Then I send another 750 bytes packet and I don't receive that one. But if I send smaller packets after that I receive all the smaller ones. So I'm able to receive only one packet of size 750. After a restart I can receive one more 750 bytes packet again (but not anything larger than that).

Does anyone know what could be the problem? - is it a hardware limitation? - is it a bug in the underlying APIs? - it it a bug in my application (I doubt that, as I sucessfully receive smaller packets) - is it a parameter of one of the API I should override?

09 May 2012

Any hint on how I could debug the problem is welcome. :)

I've made additional tests and I have exact numbers. I'm able to receive 722 bytes packets but not anything bigger than that.

Here is a simple program I test with:

#include "mbed.h"
#include "EthernetNetIf.h"
#include "UDPSocket.h"

EthernetNetIf eth;
UDPSocket udp;

void onUDPSocketEvent(UDPSocketEvent e)
{
    printf("UDPSocketEvent\n");
  switch(e)
  {
  case UDPSOCKET_READABLE: //The only event for now
    char buf[950] = {0};
    Host host;
    int total = 0;
    while( int len = udp.recvfrom( buf, 950, &host ) )
    {
      if( len <= 0 )
        break;
        total+=len;
    }
    printf("PacketSize: %d\n",total);
    break;
  }
}

int main() {
  printf("Setting up...\n");
  EthernetErr ethErr = eth.setup();
  if(ethErr)
  {
    printf("Error %d in setup.\n", ethErr);
    return -1;
  }
  printf("Setup OK\n");
  
  udp.setOnEvent(&onUDPSocketEvent);
  
      udp.bind(Host(IP_ADDR_ANY, 6000));


  while(true)
  {
    Net::poll();
  }

  
}

09 May 2012

My practical experience with UDP large packets revealed similar issue and constant crashes. I think it's widely known but not documented / discussed that the networking stack is broken. It's been that way for ever and there is no ownership to fix it. One of the aspirations that mBed posted on this forum was to try and get it looked into 'this year'.

You'll likely find your post is ignored .. as previously. Meanwhile I think you should consider using another product for anything but the most basic networking tasks. Disappointing ..but at least a practical way forward.

K

09 May 2012

Thanks for the reply. That sounds really bad. It's annoying since I've spent 5 months of my spare time building a prototype that is almost complete, but this bug makes it useless. I still hope someone would give me a hint. :)

I've already thought about using a different product. I've got an lpcxpresso board as well, but mbed seemed to be a better prototyping platform. It would take weeks to migrate to that as I have thousands of lines of code written to mbed.

09 May 2012

Hi Kevin, Sheldon,

Emilio and Donatien are working on a new ethernet and lwip port at the moment, but it is a little stuck behind our collaboration infrastructure roll out, which we want to proceed it. This is mainly because we (I, blame me) think this would be a great test project for development publicly engaging in feedback/patches/etc using the new infrastructure.

You've probably seen a new beta of the compiler is out. The next two compiler/website updates that will closely follow it will bring the collaboration infrastructure in to public beta; this is a huge step for mbed so we're really excited to let it free! But my plan is to use that for publishing the new networking stack, when we'll be happy to have some users after some support using it.

Simon

09 May 2012

This will be awesome.

-Adam

10 May 2012

<snipped by author>

10 May 2012

Sheldon, I had big trouble with the NetServices API code too. My problems were not the same as yours, and I was using TCP, but it is just possible you may be interested in my outcome.

I believe that the mbed platform situation is this:

The TCP/UDP protocol stack is LwIP. This is widely used, tough, and fit for purpose. It is very reliable. This sits on top of the mbed ethernet driver for the MAC and PHY. Luckily, this is also fast and reliable.

the let-down is the API-layer. This reduces the speed to a fraction of the system's capability, it has every kind of compatibility problem, and it is unreliable.

What to do? well, I simply turned to LwIP, and used the API layer for that. Here it is for UDP:

http://lwip.wikia.com/wiki/Raw/UDP

Here is the code that started me on the LwIP path, using TCP:

http://mbed.org/users/no2chem/programs/EthernetTester/6095m/docs/

see how the TCP API is used to generate an HTTP interface.

this code is old now, and has some library contentions. you need to copy "device.h" locally, and rename it.

But, I have found it to be very reliable over a long period of testing. I looked at LPCXpresso for this, too, after seeing the mess things are in. But LPCX does not have anything other than some rough testing code, last time I looked - unless the FreeRTOS version has now been properly developed (and you can cope with an RTOS!).

Naturally, I can't guarantee that this will solve your UDP problems, but it may be worth exploring.

10 May 2012

....O and if you try Michael Wei's Server, I think you must upgrade the library to at least 29 to use big packets. this library requires the device.h renaming.

I have not tested it on mbed Libraries later than 29.

10 May 2012

Thank you guys. All of you. You've given me enough info on how to move on. I'm going to try the things you suggested.

12 May 2012

I've made tests with pure lwip. I got the same results. The max UDP packet I can receive is 722, so it means the error is not in the NetServices API. I examined the lwip source codes and I found that in device.cpp, the MTU is set to 0x2EA, which is 746 and very close to the limit I experience. I very much suspect that the problem is related to MTU. At the moment I don't see how I could raise the MTU as it is seemingly hardcoded into lwip. Is this intentionally set to so low, because of some kind of HW limitation I'm not aware of?

12 May 2012

I finally made some progress. bugfix-670 version (15 months old) of mbed library contains bigger MTU support. The latest beta library is still lacking it.

12 May 2012

This issue is driving me crazy. While bugfix-670 fixes the MTU issue, it's not compatible with other parts of my application and it stopped working. :( Any ideas on how to raise MTU with latest mbed library?

12 May 2012

Hi Sheldon,

Have a chat with Emilio Monti as he's working on a new ethernet driver and lwip port now; perhaps he can give you a drop of something now or help you out directly.

Simon

14 May 2012

Just an update. We created the new lwIP repository 4 days ago (considering the week-end, 2 working days ago). I would consider it at very least "unripe". Do not expect a code drop very soon.

Cheers, Emilio