1

I'm facing a weird situation, where the UDP behavior seems different in STM32 porting (stm32duino).

Short question

Besides port and address, what are the other parameters that characterize the UDP protocol?

Long description

My code listens for incoming UDP packets and answer. The actual packets contains OSC messages, but they are just UDP messages with binary data.

On host side there is a proprietary software (MAX) that send those packets. The issue is the following:

  1. run both Arduino board and MAX software
  2. from software send a packet
  3. the Arduino receives the packet, and answer
  4. the software receive the answer
  5. now if the software sends more packets, they are not received anymore from Arduino

The weird thing is if I use another application to send the very same packets (i.e. PacketSender) all works fine and I can always send and receive correctly.

Furthermore, this happens with the STM32 porting only. The same code compiled for the standard Arduino Uno works fine.

Now some code:

//#define STM32
#define UNO

#if defined(UNO)
#include <SPI.h>
#include <Ethernet.h>
#elif defined(STM32)
  #include <LwIP.h>
  #include <STM32Ethernet.h>
#endif

#include <EthernetUdp.h>

#include <OSCMessage.h>
#include <OSCBundle.h>
#include <OSCData.h>

#if defined(UNO)
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
#endif

IPAddress remoteIP;
int remotePort;
OSCBundle bundleOut;
EthernetUDP Udp;
OSCErrorCode error;

void setup() 
{
  Serial.begin(115200);

#if defined(UNO)
  Ethernet.init(10);
#endif
  IPAddress localIP(192, 168, 100, 1);
  IPAddress subnet(255, 255, 0, 0);
  IPAddress dns(192, 168, 1, 1);
  IPAddress gateway(192, 168, 1, 1);

#if defined(UNO)
  Ethernet.begin(mac, localIP, subnet, dns, gateway);
#elif defined(STM32)
  Ethernet.begin(localIP, subnet, dns, gateway);
#endif

#if defined(STM32)
  uint8_t *mac = Ethernet.macAddress();
#endif
  char macString[32];
  sprintf(macString, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  Serial.print("IP Address: ");
  Serial.println(Ethernet.localIP());
  Serial.print("MAC Address: ");
  Serial.println(macString);

  int port = 8888;
  Udp.begin(port);
  Serial.print("UDP port: ");
  Serial.println(port);
}

void processOSCMessage(void)
{  
  OSCBundle bundle;

  int size = Udp.parsePacket();
  if (size > 0) 
  {
    remoteIP = Udp.remoteIP();
    remotePort = Udp.remotePort();

    while (size--) bundle.fill(Udp.read());  
    Serial.print("Source: ");
    Serial.print(remoteIP);
    Serial.print(":");
    Serial.println(remotePort);
    if (bundle.hasError()) 
    {
      error = bundle.getError();
      Serial.print("Error: ");
      Serial.println(error);
    } 
    else 
    {
      int size = bundle.size();
      for (int i = 0; i < size; i++)
      {
        OSCMessage msg = bundle.getOSCMessage(i);
        char buffer[32];
        msg.getAddress(buffer);
        Serial.print("Message: ");
        Serial.println(buffer);
      }

      bundle.route("/version", version_handler);
    }
  } 
}

void version_handler(OSCMessage &msg, int patternOffset)
{
    OSCBundle bundle;
    Serial.println("Answer to message");
    bundle.add("/version").add(1).add("0.1");  
    Udp.beginPacket(remoteIP, 8888);
    bundle.send(Udp);
    Udp.endPacket();
}

void loop() 
{
  processOSCMessage();
}

I can't understand the difference between the MAX application and PacketSender. They are both configured to send the same data, to the same address and same port, what else?

MAX is still working after point 5 because if I redirect the address to another pc where I have PacketSender I still receive the messages. It seems it's just the STM32 Arduino library that doesn't receive anymore the packets.

For STM32 I'm using the following setup:

Any further idea how to fix this issue?

UPDATE

Following the suggestion, using WireShark I found the only difference between the two packets: the source port. I'm not saying this is the cause, but it's the only difference I can see.

PacketSender sends packets from the same port it also listens too (i.e. 8888). MAX sends packets from a random port while it listens to the 8888.

Now I can partially replicate the behavior using PacketSender:

  1. open two instances of PacketSender
  2. A: set UDP port to 8888
  3. B: set UDP port to another, say 50127
  4. from B send the packet to Arduino (STM32)
  5. Arduino receives the packet and answers to 8888
  6. A receive the answer
  7. now if I send more packets from B, they are not received anymore from Arduino, this is the same behavior using MAX
  8. BUT if now I send packets from A they are received from Arduino and answered!

So it seems the problem rises when Arduino answer to a different port than the source one. This make no sense to me because the involved port is the source one (host side). Because UDP has no connection, why this might lead to such an issue!?

Furthermore, using the same code compiled for Arduino UNO, it works fine even at point 7.

  • 1
    I would suggest running Wireshark (or something similar) to examine the packets and see what is actually different. – Majenko May 5 at 10:21
  • Thanks, question updated. – Mark May 5 at 11:53
  • Are you using a W5100 interface with the STM32, or does it have its own internal Ethernet controller that just needs a PHY interface? I'm not that familiar with that family of chips. – Majenko May 5 at 12:11
  • @Majenko the F429ZI embed an Ethernet controller. It just needs the PHY interface. – Mark May 5 at 12:12
  • 2
    I would be inclined to raise it as an issue with the maintainers of the core / library. – Majenko May 5 at 12:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.