This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to set Non-blocking UDP socket?

I want to receive data through UDP in eDRX

I tried to set up non-blocking UDP by reading this post, but I can't achieve the function yet. Any help?
https://devzone.nordicsemi.com/f/nordic-q-a/49918/non-blocking-udp-socket-fcntl-error-enotsock---argument-is-not-a-socket/199022#199022

I copied this ntp program and fixed it like this.
https://github.com/Rallare/fw-nrfconnect-nrf/blob/nrf9160_samples/samples/nrf9160/ntp/src/main.c

<main.c>
#include <fcntl.h>
.
.

void app_ntp_socket_start(void)
{
	struct addrinfo *res;
	struct ntp_format ntp = { 0 };
	socklen_t addrlen = sizeof(struct sockaddr_storage);

	ntp.flags = 0xe3;
	int err = getaddrinfo(NTP_HOST, NULL, NULL, &res);

	printk("getaddrinfo err: %d\n\r", err);
	((struct sockaddr_in *)res->ai_addr)->sin_port = htons(NTP_PORT);
	struct sockaddr_in local_addr;

	local_addr.sin_family = AF_INET;
	local_addr.sin_port = htons(0);
	local_addr.sin_addr.s_addr = 0;

	int client_fd = socket(AF_INET, SOCK_DGRAM, 0);
	printk("client_fd: %d\n\r", client_fd);

    int flags = fcntl(client_fd, F_GETFL);
    printk("Flags = %d\n Errno = %d\n", flags, errno);

    fcntl(client_fd, F_SETFL, flags | O_NONBLOCK);
    printk("Flags = %d\n Errno = %d\n", flags, errno);

	err = bind(client_fd, (struct sockaddr *)&local_addr,
		   sizeof(local_addr));
	printk("bind err: %d\n\r", err);

	err = blocking_connect(client_fd, (struct sockaddr *)res->ai_addr,
			       sizeof(struct sockaddr_in));
	if (err < 0) {
		printk("connect err: %d\n\r", errno);
	}

	err = send(client_fd, &ntp, sizeof(struct ntp_format), 0);
	printk("sendto ret: %d\n\r", err);
	if (err < 0) {
		printk("sendto err: %d\n\r", errno);
	}

	err = blocking_recvfrom(client_fd, &ntp, sizeof(struct ntp_format), 0,
				(struct sockaddr *)res->ai_addr, &addrlen);
	if (err < 0) {
		printk("recvfrom err: %d\n\r", errno);
	}
	ntp_swap_endianess(&ntp);
	ntp_print(&ntp);
	freeaddrinfo(res);
	(void)close(client_fd);
}

This is output

SPM: NS image at 0xc000
SPM: NS MSP at 0x20024578
SPM: NS reset vector at 0x130c5
SPM: prepare to jump to Non-Secure image.
***** Booting Zephyr OS v1.14.99-ncs2 *****
getaddrinfo err: 0
client_fd: 3
Flags = 0
 Errno = 0
Flags = 0
 Errno = 0
bind err: -1
connect err: 119
sendto ret: -1
sendto err: 119

firmware: v1.0.0
DK: v0.8.5
GNU Arm toolchain: 7-2018-q2-update

Parents
  • Hi,

     

    Have you updated to the latest v1.0.0 tag, as described in this post?

    What happens if you run the ntp example without setting fcntl()?

     

    Kind regards,

    Håkon

  • Hi, Hakon. Thank you for helping me many times.

    > Have you updated to the latest v1.0.0 tag, as described in this post?

    Yes, I use v1.0.0

    > What happens if you run the ntp example without setting fcntl()?

    It works fine. This is output.

    SPM: NS image at 0xc000
    SPM: NS MSP at 0x20024578
    SPM: NS reset vector at 0x1306d
    SPM: prepare to jump to Non-Secure image.
    ***** Booting Zephyr OS v1.14.99-ncs2 *****
    getaddrinfo err: 0
    client_fd: 3
    bind err: 0
    sendto ret: 48
    Flags: 36
    Stratum: 2
    Poll: 3
    Precision: 4294967272
    Root delay: 1728249856
    Root dispersion: 2114125824
    Ref ID: 4027000512
    Ref timestamp: 37747758182192391172
    Orig Timestamp: 00
    Receive timestamp: 37747763311848377896
    Transmit: 37747763311848543134
    Unix time: 1565787531
    Time: Wed Aug 14 12:58:51 2019

    this post says this.

    so basically the socket opening function works fine, but somehow the fcntl doesn't recognize just opened socket descriptor. The program goes all the way down to the recvfrom function and the bind/send functions work fine with the same socket:

    In my case, fcntl apparently works out, but bind and connect functions cause error.

  • Hi,

     

    There's something strange here. bind() returns this errno when using newlib c:

    https://github.com/eblot/newlib/blob/master/newlib/libc/machine/cris/sys/errno.h#L153

     

    when I tried using minimal c (zephyr libc), it returns EINPROGRESS.

    Other calls seems to be returning the expected errno when its non blocking, but bind should not return that errno per the "man bind" documentation.

    I've reported this internally, and asked about this behavior. 

     

    Kind regards,

    Håkon

Reply Children
Related