UDP receive not working Topic is solved

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
hybridA
Posts: 40
Joined: Wed Jan 12, 2022 7:15 am
Has thanked: 10 times
Been thanked: 5 times

UDP receive not working

Post by hybridA »

I have a socket for sending and receiving UDP broadcast messages.
The send works fine, but I can't receive data. recvfrom() either waits forever, or returns -1 (when using MSG_DONTWAIT for non-blocking reads)

Here's the init code:

Code: Select all

    static int sock = -1;
    struct sockaddr_in eth_tx_addr;
    struct sockaddr_in eth_rx_addr;
    lwipInit(NULL);
    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sock == -1) {
        return -1;
    }

    /* broadcast */
    int broadcast = 1;
    if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0) {
        close(sock);
        return -1;
    }

    memset(&eth_rx_addr, 0, sizeof(eth_rx_addr));
    memset(&eth_tx_addr, 0, sizeof(eth_tx_addr));
    eth_tx_addr.sin_family = AF_INET;
    eth_tx_addr.sin_port = htons(1234);
    eth_tx_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);

    eth_rx_addr.sin_family = AF_INET;
    eth_rx_addr.sin_port = htons(1234);
    eth_rx_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if (bind(sock, (struct sockaddr *) &eth_rx_addr, sizeof(eth_rx_addr)) < 0) {
        close(sock);
        return -1;
    }


The send (which works fine):

Code: Select all

sendto(sock, xmit_buf, len, 0, (struct sockaddr*) &eth_tx_addr, sizeof(eth_tx_addr));


The receive (which currently doesn't work):

Code: Select all

uint8_t recv_buf[4095];
int len = recvfrom(sock, recv_buf, sizeof(recv_buf), MSG_DONTWAIT, (struct sockaddr*) &eth_rx_addr, (socklen_t *)sizeof(eth_rx_addr));


I'm able to see the data in wireshark + I can successfully ping the embedded device, so I can rule out any hardware issues.
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: UDP receive not working

Post by Giovanni »

Hi,

The HTTP demo is able to send and receive using TCP so I guess the integration is working.

I never used UDP with lwIP, MSG_DONTWAIT, perhaps you should wait for the message?

Giovanni
hybridA
Posts: 40
Joined: Wed Jan 12, 2022 7:15 am
Has thanked: 10 times
Been thanked: 5 times

Re: UDP receive not working

Post by hybridA »

Thanks Giovanni. I tried without any flags, but recvfrom() then just blocks forever.
I can try rewriting it to test with TCP.
steved
Posts: 834
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 12 times
Been thanked: 138 times

Re: UDP receive not working

Post by steved »

On a quick look, UDP receive operates much the same as TCP/IP receive.
Could be your 'MSG_DONTWAIT' flag in the recvfrom() call - I have zero there (to block until a packet is received)

You're using the sockets interface (rather than lwIP's custom interface) so there will be a vast range of examples out there!
hybridA
Posts: 40
Joined: Wed Jan 12, 2022 7:15 am
Has thanked: 10 times
Been thanked: 5 times

Re: UDP receive not working

Post by hybridA »

Thank you Steve! I tried using no flags (i.e. '0' instead of 'MSG_DONTWAIT') but then recvfrom() blocks forever.
Do you have an example you can share that is working on your end?
steved
Posts: 834
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 12 times
Been thanked: 138 times

Re: UDP receive not working

Post by steved »

Before I forget, I'll mention the lwIP options - its possible that something there isn't set up right.

My code is a bit spread out; basically I dedicate a thread to UCP receive - set it up, then loop waiting for messages. (You can also use select(), I think).
I've picked out what I hope are the relevant bits:

Code: Select all

static SOCKET mainSock;
  struct  sockaddr_in ourAddr;
  // set up the network bits
  mainSock = socket(AF_INET, SOCK_DGRAM, 0);         // UDP listening socket
  if (mainSock < 0)
  {
   chprintf("Error %d creating socket = %d\n", mainSock, getErrno());
    return NOT_OK;
  }

  memset(&ourAddr, 0, sizeof(ourAddr));
 
   ourAddr.sin_addr.s_addr   = INADDR_ANY;
   ourAddr.sin_family        = AF_INET;
   ourAddr.sin_len           = sizeof(ourAddr);
   ourAddr.sin_port          = htons(PORT_NUMBER);
   if ((errCode = bind(mainSock, (struct sockaddr *)&ourAddr, sizeof(ourAddr))) < 0)
  {
   chprintf("Error %d on port bind, %d\n", errCode, getErrno() );
    return -1;
  }

  socklen_t addrLen;

  struct sockaddr_in rxAddr;

  //create buffers for send and receive
  static uint8_t  rxBuf[100];
  static uint8_t  txBuf[150];

  while(true)
  {
    /* Getting the pointer to the frame buffer and passing it as message.*/
    int rxResp;

    memset(&rxAddr, 0, sizeof(rxAddr));
    addrLen = sizeof(rxAddr);

    /**
     *  Try and receive a message
     *
     */
    if ((rxResp = recvfrom(mainSock, rxBuf, sizeof(rxBuf), 0, (struct sockaddr *)&rxAddr, &addrLen)) < 0)
    {
      chprintf("Error %d in UDP receive, %d\n", mainSock, getErrno());
      chThdYield();
      continue;         // OK to carry on - some errors can reasonably occur
    }

    //=========================================================================

    //We have a message!

    uint8_t *rxPtr = &rxBuf[8];
    int8_t identifierNumber = 0;

      ddprintf("\n-- -- -- -- -- -- --\n");
      ddprintf("Msg rec skt %d port %d addr %s size %d\n", mainSock, rxAddr.sin_port, inet_ntoa(rxAddr.sin_addr), rxResp);
      ddprintf("Identifier: %c%c%c%c   Type: 0x%02X, payload length: %d\n", rxBuf[0], rxBuf[1], rxBuf[2], rxBuf[3], (rxBuf[4] << 8) | rxBuf[5], (rxBuf[6] << 8) | rxBuf[7] );

    // ********** Received message to process ***************
}
hybridA
Posts: 40
Joined: Wed Jan 12, 2022 7:15 am
Has thanked: 10 times
Been thanked: 5 times

Re: UDP receive not working

Post by hybridA »

Thanks everyone.
I found it.
Once I added

Code: Select all

#define DEFAULT_UDP_RECVMBOX_SIZE 40

everything worked fine.
Post Reply