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

nRF9160 making mqtt_client_tls_connect() non-blocking

Hi,

What cellular connectivity, the provider's DNS, and backend cloud services, invariably connecting over MQTT is transient and the internal blocking timeout of mqtt_client_tls_connect is inordinately long which can cause significant loss of battery life. We're perfectly fine modifying mqtt_client_tls_connect in mqtt_transport_socket_tls.c to make it a non-blocking socket connect() with our own timeout value but I'm observing the following:

  • When calling fcntl(client->transport.tls.sock, F_SETFL, O_NONBLOCK); the flags parameter get unpacked in nrf91_socket_offload_fcntl, but flags = va_arg(args, int) is returning 0 instead of 0x4000 (O_NONBLOCK) even though I can see 0x4000 is being passed down before it becomes a va-arg.   

  • To eliminate va_arg as an issue we brought up the direct call to nrf_fcntl with NRF_O_NONBLOCK into mqtt_client_tls_connect and verified it is being set properly by calling nrf_fcntl(.. NRF_F_GETFL..) which returns NRF_O_NONBLOCK. However the subsequent socket connect(...) behaves as still blocking and doesn't return EINPROGRESS.

Full code below, any ideas?

Thanks!

// Set to non blocking
int flags = nrf_fcntl(client->transport.tls.sock, NRF_F_GETFL, 0);
ret = nrf_fcntl(client->transport.tls.sock, NRF_F_SETFL, flags | NRF_O_NONBLOCK);
int rflags = nrf_fcntl(client->transport.tls.sock, NRF_F_GETFL, 0);

printk(">>>>>>>> nrf_fcntl verified value set to %d\n", rflags);

ret = connect(client->transport.tls.sock, client->broker, peer_addr_size);
if (ret == EINPROGRESS) {
  printk(">>>>>>>> connect EINPROGRESS\n");

  fd_set wait_set;
  struct timeval tv;

  // make file descriptor set with socket
  FD_ZERO(&wait_set);
  FD_SET(client->transport.tls.sock, &wait_set);

  // wait for socket to be writable; return after given timeout
  tv.tv_sec = 30; // 30 seconds
  tv.tv_usec = 0;
  ret = select(client->transport.tls.sock + 1, NULL, &wait_set, NULL, &tv);
  } else if (ret < 0) {
  goto error;
}

ret = nrf_fcntl(client->transport.tls.sock, NRF_F_SETFL, flags); // restore to blocking socket calls

     

Parents Reply Children
No Data
Related