nRF9151: fcntl() errno 9 EBADF

Hi,

When we open a TCP socket in our nRF9151 application, we set it to non-blocking.

The flow:

fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

...
setsockopt(fd, SOL_SOCKET, SO_RAI, &rai, sizeof(rai));

nrf_fcntl(fd, NRF_F_SETFL, NRF_O_NONBLOCK);

Sometimes, seemingly at random, nrf_fcntl() returns -1 and errno == 9 (EBADF).

We also check the return values of socket() and setsockopt() and both of those succeed right before fcntl! fd >= 0 and the return value of setsockopt() is 0.

What does it mean when nrf_fcntl returns EBADF here? It appears this happens at random.

Parents Reply Children
  • We use SDK v2.7.0 (working on moving up), modem firmware 2.0.2 on nRF9151.

    It's really this simple piece of code:

    fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    /* fd >= 0 */
    
    int rai = RAI_ONGOING;
    err = setsockopt(fd, SOL_SOCKET, SO_RAI, &rai, sizeof(rai));
    /* err == 0 */
    
    nrf_fcntl(fd, NRF_F_SETFL, NRF_O_NONBLOCK);
    /* err == -1 && errno == 9 */

    While Registered and RRC Connected on an NB-IoT network (example 20620), sometimes nrf_fcntl returns this.

    The response is immediate (<1ms).

    In what case does fcntl set errno to EBADF?

  • Using fcntl() instead of nrf_fcntl() seems to work for me. This kinda makes sense since you are using the Zephyr socket API when creating the socket, but you are calling nrf_fcntl() which is the modem lib API. I think you should stick to one API when dealing with sockets.

    Edit; Never mind, it works with the Zephyr stack, but not with the offloaded sockets.

    Edit2; This works for me;

    #include <stdio.h>
    #include <ncs_version.h>
    #include <zephyr/kernel.h>
    #include <zephyr/net/socket.h>
    #include <zephyr/logging/log.h>
    #include <fcntl.h>
    
    #include <nrf_socket.h>
    #include <modem/nrf_modem_lib.h>
    #include <modem/lte_lc.h>
    
    int main(void) {
        int fd;
        int err;
        printk("Starting fcntl test\n");
        
        err = nrf_modem_lib_init();
        fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        /* fd >= 0 */
    
        int rai = RAI_ONGOING;
        err = setsockopt(fd, SOL_SOCKET, SO_RAI, &rai, sizeof(rai));
        /* err == 0 */
    
        err = fcntl(fd, NRF_F_SETFL, NRF_O_NONBLOCK);
        /* err == -1 && errno == 9 */
        printk("%d\n", err);
        printk("%d\n", errno);
        return 0;
    }

Related