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

Mqtt connection timeout setting

Hi, 

We have observed that in areas of poor lte connectivity, the client_inti() works well but the mqtt_connect() takes a couple of minutes and times out.

I need to change the mqtt connection timeout duration make it 20-30 seconds, since if it does not connect in this duration, for our use-case, it wont connect after either and the firmware can move on.

In decent lte connectivity regions, mqtt_connect returns within a second or less.

Thanks

Noaman

Parents
  • Hi,

     

    Unfortunately, there is no option to set the timeout at this time, but I will add this as a feature request internally.

     

    Kind regards,

    Håkon

  • thank you Haken.

    Can you help me add a timeout for http connection requests?

    Regards

    Noaman

  • Hi,

     

    If you enable non-blocking socket operations, the connect() call will return EINPROGRESS until its done.

    That can be done like this:

    #include <fcntl.h>
    
        ....
    	printk("enable non-blocking connect\n");
    	printk("Will return EINPROGRESS (%d) when in progress\n", EINPROGRESS);
    	int flags = fcntl(fd, F_GETFL, 0);
    	int ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    	int rflags = fcntl(fd, F_GETFL, 0);	
    	
    	
    	printk("connect time: %lld\n", k_uptime_get());
    	ret = connect(...)
    	printk("connect time: %lld\n", k_uptime_get());
    	....

     

    I added the logic to the https_client sample in ncs v1.6.0 just so that you can see that the call returns almost immediately when you enable nonblocking socket operation.

    diff --git a/samples/nrf9160/https_client/src/main.c b/samples/nrf9160/https_client/src/main.c
    index 509aacb96..18f01a410 100644
    --- a/samples/nrf9160/https_client/src/main.c
    +++ b/samples/nrf9160/https_client/src/main.c
    @@ -5,6 +5,7 @@
      */
     
     #include <string.h>
    +#include <fcntl.h>
     #include <zephyr.h>
     #include <stdlib.h>
     #include <net/socket.h>
    @@ -202,7 +203,25 @@ void main(void)
     	}
     
     	printk("Connecting to %s\n", "example.com");
    +	#if 1
    +	printk("enable non-blocking connect\n");
    +	printk("Will return EINPROGRESS (%d) when in progress\n", EINPROGRESS);
    +	int flags = fcntl(fd, F_GETFL, 0);
    +	int ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    +	int rflags = fcntl(fd, F_GETFL, 0);	
    +	#endif
    +	printk("connect time: %lld\n", k_uptime_get());
    +
    +	/* define this to handle EINPROGRESS scenario */
    +	#if ENABLE_NONBLOCK
    +	do {
    +	#endif
     	err = connect(fd, res->ai_addr, sizeof(struct sockaddr_in));
    +	#if ENABLE_NONBLOCK
    +	} while (err == EINPROGRESS);
    +	#endif
    +	
    +	printk("connect time: %lld\n", k_uptime_get());
     	if (err) {
     		printk("connect() failed, err: %d\n", errno);
     		goto clean_up;
    

     

    Kind regards,

    Håkon

Reply
  • Hi,

     

    If you enable non-blocking socket operations, the connect() call will return EINPROGRESS until its done.

    That can be done like this:

    #include <fcntl.h>
    
        ....
    	printk("enable non-blocking connect\n");
    	printk("Will return EINPROGRESS (%d) when in progress\n", EINPROGRESS);
    	int flags = fcntl(fd, F_GETFL, 0);
    	int ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    	int rflags = fcntl(fd, F_GETFL, 0);	
    	
    	
    	printk("connect time: %lld\n", k_uptime_get());
    	ret = connect(...)
    	printk("connect time: %lld\n", k_uptime_get());
    	....

     

    I added the logic to the https_client sample in ncs v1.6.0 just so that you can see that the call returns almost immediately when you enable nonblocking socket operation.

    diff --git a/samples/nrf9160/https_client/src/main.c b/samples/nrf9160/https_client/src/main.c
    index 509aacb96..18f01a410 100644
    --- a/samples/nrf9160/https_client/src/main.c
    +++ b/samples/nrf9160/https_client/src/main.c
    @@ -5,6 +5,7 @@
      */
     
     #include <string.h>
    +#include <fcntl.h>
     #include <zephyr.h>
     #include <stdlib.h>
     #include <net/socket.h>
    @@ -202,7 +203,25 @@ void main(void)
     	}
     
     	printk("Connecting to %s\n", "example.com");
    +	#if 1
    +	printk("enable non-blocking connect\n");
    +	printk("Will return EINPROGRESS (%d) when in progress\n", EINPROGRESS);
    +	int flags = fcntl(fd, F_GETFL, 0);
    +	int ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    +	int rflags = fcntl(fd, F_GETFL, 0);	
    +	#endif
    +	printk("connect time: %lld\n", k_uptime_get());
    +
    +	/* define this to handle EINPROGRESS scenario */
    +	#if ENABLE_NONBLOCK
    +	do {
    +	#endif
     	err = connect(fd, res->ai_addr, sizeof(struct sockaddr_in));
    +	#if ENABLE_NONBLOCK
    +	} while (err == EINPROGRESS);
    +	#endif
    +	
    +	printk("connect time: %lld\n", k_uptime_get());
     	if (err) {
     		printk("connect() failed, err: %d\n", errno);
     		goto clean_up;
    

     

    Kind regards,

    Håkon

Children
  • Hi Haken,

    I am currently using sdk 1.4.2. should this work on it?

    It does not seem to be working for me. here is the console log

    RRC mode: Connected
    getaddrInfo errno: 0
    fcntl nonblocking set: 0. fd : 0, flags: 16384, rflags: 16384
    In http timer. http state: 3, currentState: 0, httpQuit: 0
    In http timer. http state: 3, currentState: 3, httpQuit: 0
    http waiting to connect
    http: Connected

    "in http timer" is printed every 5 second by a timer callback. "http waiting to connect" is printed from within the do while loop as per code below:

    flags = fcntl(fd, F_GETFL, 0);
    ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    rflags = fcntl(fd, F_GETFL, 0);	
    printk("fcntl nonblocking set: %d. fd : %d, flags: %d, rflags: %d\n", ret, fd, flags, rflags);
    
    fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TLS_1_2);
    if (fd == -1) 
    {
    	if (DEBUG_PRINT_HTTP) printk("Failed to open socket!\n");
    	errorReason = ERROR_HTTP_SOCKET_FAILED;
    	goto clean_up;
    }
    
    httpState = 2;
    /* Setup TLS socket options */
    err = httpTlsSetup(fd);
    if (err) 
    {
    	errorReason = ERROR_HTTP_SECURECLIENT_INIT_FAIL;
    	goto clean_up;
    }
    
    httpState = 3;
    
    //Connect
    {
    	waitingToConnect = 0;
    	do 
    	{
    		err = connect(fd, res->ai_addr , sizeof(struct sockaddr_in));
    		k_sleep(100);
    		waitingToConnect++;
    		printk("http waiting to connect\n");
    	} while ((err == EINPROGRESS) && (waitingToConnect <300));
    
    	if (err || waitingToConnect >=300)
    	{
    		if (DEBUG_PRINT_HTTP) printk("connect() failed, time: %d, err: %d\n", waitingToConnect, errno);
    		if (errno == 23)
    			sys_reboot(0);
    
    		errorReason = ERROR_HTTP_CONNECT_FAILED;
    		goto clean_up;
    	}
    	if (DEBUG_PRINT_HTTP) printk("http: Connected\n");
    }
    

    "http waiting to connect" should be printed every 100ms if connect() is non-blocking. so it seems that connect() is still using a blocking call.

  • Hi,

     

    My apologies for the late reply.

     

    Stratosphere said:
    I am currently using sdk 1.4.2. should this work on it?

    This functionality was not added until more recent. Is it technically possible for you to use a newer ncs version?

     

    Kind regards,

    Håkon

Related