UDP receive not working Topic is solved

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

Moderators: RoccoMarco, barthess

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

UDP receive not working

Postby hybridA » Mon May 29, 2023 1:38 am

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: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: UDP receive not working

Postby Giovanni » Mon May 29, 2023 5:51 am

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: 32
Joined: Wed Jan 12, 2022 7:15 am
Has thanked: 10 times
Been thanked: 5 times

Re: UDP receive not working

Postby hybridA » Mon May 29, 2023 6:36 am

Thanks Giovanni. I tried without any flags, but recvfrom() then just blocks forever.
I can try rewriting it to test with TCP.

steved
Posts: 823
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 12 times
Been thanked: 135 times

Re: UDP receive not working

Postby steved » Mon May 29, 2023 8:42 am

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: 32
Joined: Wed Jan 12, 2022 7:15 am
Has thanked: 10 times
Been thanked: 5 times

Re: UDP receive not working

Postby hybridA » Mon May 29, 2023 4:30 pm

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: 823
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 12 times
Been thanked: 135 times

Re: UDP receive not working

Postby steved » Tue May 30, 2023 9:36 am

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: 32
Joined: Wed Jan 12, 2022 7:15 am
Has thanked: 10 times
Been thanked: 5 times

Re: UDP receive not working  Topic is solved

Postby hybridA » Tue May 30, 2023 9:53 pm

Thanks everyone.
I found it.
Once I added

Code: Select all

#define DEFAULT_UDP_RECVMBOX_SIZE 40

everything worked fine.


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 27 guests