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

Issue with closing a socket after sending a UDP message

Dear All,

I need to develop a low-power application that sends a UDP message, waits for a certain amount of time (5 seconds) for a response and if there is no response it closes the socket and goes to sleep. I am using the nRF9160DK

This is the functions I use to connect send and receive data:

int blockingRecv(int fd, u8_t *buf, u32_t size, u32_t flags)
{
	int err;
    uint32_t start = (uint32_t)k_uptime_get();
	do {
		err = recv(fd, buf, size, flags);
 	} while (err < 0 && errno == EAGAIN && (uint32_t)k_uptime_get() - start < UDP_TIMEOUT_MS);

	return err;
}

int blockingSend(int fd, u8_t *buf, u32_t size, u32_t flags)
{
	int err;
    uint32_t start = (uint32_t)k_uptime_get();
	do {
		err = send(fd, buf, size, flags);
	} while (err < 0 && errno == EAGAIN && (uint32_t)k_uptime_get() - start < UDP_TIMEOUT_MS);

	return err;
}

int blockingConnect(int fd, struct sockaddr *local_addr, socklen_t len)
{
	int err;
    uint32_t start = (uint32_t)k_uptime_get();
	do {
		err = connect(fd, local_addr, len);
	} while (err < 0 && errno == EAGAIN && (uint32_t)k_uptime_get() - start < UDP_TIMEOUT_MS);

	return err;
}

And this is the way I am sending the message:

void sendUDPMessage(u8_t *buffer, ssize_t size, u8_t *recv_buffer, ssize_t recv_size)
{
    int err;

    struct addrinfo *dest_addr;
    err = getaddrinfo(thishost, NULL, NULL, &dest_addr);
    if (err < 0) {
#ifdef UDP_LOG
        printk("getaddrinfo err: %d\n\r", err);
#endif
    }
    if (err != -1) {
        ((struct sockaddr_in *)dest_addr->ai_addr)->sin_port = htons(thisport);
        ((struct sockaddr_in *)dest_addr->ai_addr)->sin_family = AF_INET;

        int socket_sender_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (socket_sender_fd < 0) {
#ifdef UDP_LOG
            printk("socket_sender_fd: %d\n", socket_sender_fd);
#endif
        }
#ifdef UDP_LOG
        printk("Sending UDP Message\n");
#endif
        blockingConnect(socket_sender_fd, (struct sockaddr *)dest_addr->ai_addr, sizeof((struct sockaddr *)dest_addr->ai_addr));
        err = blockingSend(socket_sender_fd, buffer, size, 0);
#if UDP_LOG
		printk("Bytes sent: %d\n", err);
#endif
        if (err < 0) {
#ifdef UDP_LOG
            printk("Sending response err: %d errno: %d\n", err, errno);
#endif
        }
        blockingRecv(socket_sender_fd, recv_buffer, recv_size - 1, MSG_DONTWAIT);

        if (socket_sender_fd != -1) {
            (void)close(socket_sender_fd);
        }
        freeaddrinfo(dest_addr);
    }
}

This is my prj.conf:

# Network
CONFIG_NETWORKING=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_OFFLOAD=y
# CONFIG_NET_SOCKETS_POSIX_NAMES=y
CONFIG_NET_RAW_MODE=y

# BSD library
CONFIG_BSD_LIBRARY=y

# Stacks and heaps
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_HEAP_MEM_POOL_SIZE=1024

# NEW LIB
CONFIG_NEWLIB_LIBC=y

# SERIAL CONFIGURATION
CONFIG_SERIAL=n

# WATCHDOG CONFIGURATION
CONFIG_WATCHDOG=y

# I2C
CONFIG_I2C=y
CONFIG_I2C_NRFX=y
CONFIG_I2C_2=y
CONFIG_I2C_2_NRF_TWIM=y

# ADC
CONFIG_ADC=y
CONFIG_ADC_0=y
CONFIG_ADC_NRFX_SAADC=y

# FLASH MEMORY
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_MPU_ALLOW_FLASH_WRITE=y
CONFIG_NVS=y

# GPIO
CONFIG_GPIO=y

I have tried enabling and disabling the CONFIG_NET_SOCKETS_POSIX_NAMES option as well as commenting it out.

The issue that I am facing is the following:

Sometimes, after I send the message, the modem doesn't go entirely to sleep after the active time. Instead it behaves like this:


After the active time there are still some spikes that are happening that I don't know why they are there or what more do I need to do. Also the duration of those spikes is also inconsistent. I've noticed them to last for 2 minutes after the expiration of the active timer and I have seen them lasting for 30 seconds.

My PSM configuration is this: Periodic-TAU 00100001 (1 Hour) and Active Timer: 00000101 (10s).

Thank you very much for your help.

  • Hi.

    First of all, have you checked what PSM values you get from the network? You are free to request whatever you want, but it is up to the network to decide what you get.

    You can check the network granted PSM values using the +CEREG or %XMONITOR AT commands.

    Secondly, how do you go to sleep after receiving?

    When you close the socket, you close the connection to the server you were talking to, but you are still connected to the network.

    Best regards,

    Didrik

Related