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.