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

LTE_M reconnect

Dear, 

I am using THINGY91 for proving my concept, I put THINGY91 in the freezer - to adapt to the temperature. 

I am using NB_iot of telia (norway)

My problem is: sometimes my thingy91 lost the network (the freezer is so good :( ),  and couldn't send the data to my webserver

I tried to change my state-machine: THINGY91 will check the network and reconnect if it couldn't find the network 

1. check the network:

/****************************************************************************************************
*name:  NETWORK CHECK
*todo:  find status of the network
*return: connect/disconnect: *mccmnc
  * 
****************************************************************************************************/
void NETW_CHECK(char *mccmnc )
 {
	const char *ATCOPS="AT+COPS?"; 
        
        
        int at_socket_fd = socket(AF_LTE, 0, NPROTO_AT);
       // printk("LTE socket is: %d \n",at_socket_fd); 
	
	if (at_socket_fd < 0) {
		printk("Socket err: %d, errno: %d\r\n", at_socket_fd, errno);
	}
	/*
        * find MNC and MCC
        */
        int bytes_written0 = send(at_socket_fd, ATCOPS, strlen(ATCOPS), 0);
	if (bytes_written0 > 0) {
			int r_bytes =
				blocking_recv(at_socket_fd, recv_buf,
					      sizeof(recv_buf), MSG_DONTWAIT);
			if (r_bytes > 0) {
				//printk("%s", recv_buf);
                                char splitStringsmcc[10][10]; 
                                 split_string_ltepos(recv_buf,splitStringsmcc);
                                 memcpy(mccmnc,splitStringsmcc[1],sizeof(splitStringsmcc[1]));
                                
                                  printk("MCC&MNC: %s\n\r",mccmnc);
			              }
		
	}
       
        (void)close(at_socket_fd);
         
}

I will return MCCMNC,"24202" for telia, and if it couldnt find the network, I will try to reconnect: 

void reconnect_nw(void){
                
                int err;
		printk("ReConnecting to LTE network. ");
		printk("This may take several minutes.\n");
		//ui_led_set_pattern(UI_LTE_CONNECTING);

		err = lte_lc_init_and_connect();
		if (err) {
			printk("LTE link could not be established.\n");
			
		}

		printk("Connected to LTE network\n");
}  

But, this function lte_lc_init_and_connect()  didnt work, it just returned "LTE link could not be established.;

I am using the config file as the same with : master/applications/asset_tracker/prj_nrf9160_pca20035ns.conf, it will contain "CONFIG_LTE_AUTO_INIT_AND_CONNECT=n"

Could you plz help me, I need a solution how can thingy91 can automatically re-connect the network if the network is disconnected. 

Thanks so much 

Best Regards, 

Hoang Nguyen

Parents Reply Children
  • Hi

    I tried to simulate the situation: I used aluminum paper to cover the THINGY:91, and put them in 1 metal box, and connect to my computer to adapt the output report.

    I am using NB_ioT (Telia) 

     I got the problem in http_post: 

    bool myhttp_post (char *PostString, char *HTTP_HOST, int HTTP_PORT)
    {
         
       bool poststat = false;
       struct sockaddr_in local_addr;
       struct addrinfo *res;
       printk("Webserver: http://%s:%d \n\r",HTTP_HOST,HTTP_PORT); 
    
       local_addr.sin_family = AF_INET;
       local_addr.sin_port = htons(0);
       local_addr.sin_addr.s_addr = 0;
     
        int err = getaddrinfo(HTTP_HOST, NULL, NULL, &res);
        printk("get addrinfo\n\r");
        printk("getaddrinfo err: %d\n\r", err);
        ((struct sockaddr_in *)res->ai_addr)->sin_port = htons(HTTP_PORT);
        
       
        char send_buf[MAXLINE + 1];
        int send_data_len_post  = snprintk(send_buf,
    				         500, 
    				         POST_TEMPLATE, HTTP_PATH,
    				         HTTP_HOST, strlen(PostString),
    				         PostString);
    
        // printf("send_buf is: %s \n",send_buf);
        // printk("send err: %d\n\r", send_data_len_post);
         
         int client_fd = socket(AF_INET, SOCK_STREAM, 0);
    
         printk("client_fd: %d\n\r", client_fd);
         err = bind(client_fd, (struct sockaddr *)&local_addr, sizeof(local_addr));
         printk("bind err: %d\n\r", err);
         err = blocking_connect(client_fd, (struct sockaddr *)res->ai_addr,sizeof(struct sockaddr_in));
         printk("connect err: %d\n\r", err);
    
         int num_bytes = send(client_fd, send_buf, send_data_len_post, 0);
        
         printk("send err: %d\n\r", num_bytes);
         
         
         printk("Close socket \n\r");
         err = close(client_fd);
         
         freeaddrinfo(res);
         printk("============================== DONE SENDING =============================================== \n\r");
         poststat = true; 
         return poststat; 
         
         /*
         problem: take so long time to send()
         */
            
    }

    when the signal is bad (put the device in the metal box with aluminum paper cover around) 

    get addrinfo
    
    getaddrinfo err: 0
    
    client_fd: 3
    
    bind err: 0
    
    
    
    

    It stuck here 

    ................

    Case1: If I tried to take the device out early ( < 30s ) - the network is backed early

    It could work: 

    connect err: 0
    
    send err: 495
    
    Close socket 
    
    ============================== DONE SENDING =============================================== 
    

     

    Case 2: Keep the device in the box 

    It will return error after 30-40s:

    connect err: -1
    
    send err: -1
    
    Close socket 
    

    // couldnt send

    Case3:  If I tried to take the device out late( 1mn after that ) - the network is backed 

    Nothing comes, it just stuck here forever:

    get addrinfo
    
    getaddrinfo err: 0
    
    client_fd: 3
    
    bind err: 0
    

    ..................... the device stopped sending data and stuck here ( took the device out of the box, took away the aluminum paper) 

    I checked the code: I stuck at this step: 

    err = blocking_connect(client_fd, (struct sockaddr *)res->ai_addr,sizeof(struct sockaddr_in));

    and blocking_connect():

    int blocking_connect(int fd, struct sockaddr *local_addr, socklen_t len)
    {
    	int err;
    
    	do {
    		err = connect(fd, local_addr, len);
    	} while (err < 0 && errno == EAGAIN);
    
    	return err;
    }
    

    It stuck in the loop: do{}while() forever? without the timeout?

    Do you have any suggestions to fix it? 

    Thanks so much 

    Hoang Nguyen

  • I am a bit confused about the difference between cases 2 and 3.

    Do you take the device out of the box later in case 3 than 2?

    If so, why would you get a different result from case 2?

    Connect and send returns their error values in the errno variable. Can you print that value as well?

    Also, a modem trace in case 3 would be helpful.

Related