Can't get UDP packet size from WiFi Shield driver

I'm using the UDP mode of the WiFi shield (w/Mega2560) and find that the this comment is not true:

/* return number of bytes available in the current packet,
   will return zero if parsePacket hasn't been called yet */
int WiFiUDP::available() {
     if (_sock != NO_SOCKET_AVAIL)
     {
          return ServerDrv::availData(_sock);
     }
     return 0;
}

After looking at the WiFi firmware, it turns out that availData() returns the total number of bytes buffered in the UC3, not the current packet.

I need to know the size of the packets to properly parse them. Is there any way to do this besides modifying the firmware?

Thanks, Darren

Take a look at the WiFi UdpSendReceiveString sketch in the WiFi examples. It is the Udp.parsePacket() function that returns the packet size.

All parsePacket() does is call available() so back to square one:

int WiFiUDP::parsePacket()
{
    return available();
}

You have upgraded the WiFi shield firmware to version 1.1.0, correct? After the shield status check, add the firmware version check below. If it does not report 1.1.0, then you need to upgrade.

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present"); 
    // don't continue:
    while(true);
  } 

// check firmware version
Serial.print(F("Firmware version: "));
Serial.println(WiFi.firmwareVersion());

// rest of your setup code

Yes, just checked as you described and I have 1.1.0.

The source I'm quoting from the latest on github. Though it seems the WiFi shield firmware hasn't been changed in about a year.

As far as I can tell, this has never worked as advertised. parsePacket() and available() always return the number of bytes the UC3 has buffered, and not the individual packet sizes.

In the WiFiUdpSendReceiveString example you mentioned, packetSize is never actually used as a packet size, only as a "data available" flag.

It does work if you send packets with a lot of time in between. But if you blast the shield with a bunch of data that it must buffer before the Mega can pull it across the SPI link, the reported "packet size" gets much bigger than any individual transmitted packet.

You are correct about the buffer. If you blast it with data faster than it can take it, it will fail. The TCP server code has the same bug. It accepts client requests faster than the shield can process them, and the incorrect or corrupted page is returned to the client.

It also has a UDP bug that it will return a response to a packet from a different port that you sent the packet to. I send a packet to the wifi shield to port 5005, and it returns the packet to the correct port, but it will be from port 4097 on my shield.

I have received and sent 48 byte UDP packets at 10 per second with no problems. I haven't tested it at rates faster than that.

This is why I use an ethernet shield instead.

Hmmm. Yeah there are a lot of frustrating things about the WiFi shield... the crazy amount of overhead in the handshaking between the Arduino and the shield makes it so slow to drain the buffer. I guess I'll have to either modify the firmware to fix the available() issue or break compatibility with the protocol and add a size byte to the start of the packet. Thanks for the info though.