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

Trouble connecting https socket second time in nrf9160. And connecting debugger issue

We are developing an application that requires the https connection to the server. I am using SDK v1.2.0 and https_client as a sample example. The trouble I am having is that the socket connects the first time and exchanges the data with the server. But next time the MCU tries to connect to the server it keeps waiting forever.

I tried a workaround that is working but not sure is the best way to do so. So basically if the socket id number is 2 I never close it even after the server data exchange and API calls are made, while any other socket created later is closed.

So basically socket num 2 is used one time to make the API calls but is never closed and it stays always open. Next time the call is made to create socket it creates the socket number 3 which works fine and after the API calls are completed the socket 3 is closed. So open close is working on socket 3 but not on socket 2.

The other issue I am having is connecting the debugger to the dev-kit. I am using the latest Segger Embedded studio v4.42a. The segger is unable to download the hex into board. I have to use nrf Connect Programmer to load the hex file.

I have tried different methods 

Debug>>Go

Target >>Connect J Link     Target >>Download File>>Download   Intel Hex file

I tried to connect the debugger after programming by using Target>>Attach debugger and it attaches me to the SPM project and does not allow to put any breakpoint in the main application. I have used the older versions of SES before with SDK v1.1.0 and earlier the debugger was working fine in that. A Debug>>Go was able to load and connect debugger.

Parents
  • Thanks Didrik,

    Sorry for the delay was busy in other stuff

    I was able to fix my SES with your files, thanks for that.

    Here is the source code with the workaround. It is based on https_client example. The workaround is 

    //Work around for socekt
            if(fd!=2)
            {
              printk("closing socket: %d\n", fd);
              (void)close(fd);
            }
            else
            {
              printk("skipping closing socket: %d\n", fd);
            }

    /*
     * Copyright (c) 2018 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
     */
    #include "prj_common.h"
    #include "drv_uart.h"
    #include "lte_modem.h"
    #include "http.h"
    
    #define TAG       "main"
    
    
    #define HTTPS_PORT 443
    
    #define HTTP_HEAD                                                              \
    	"HEAD / HTTP/1.1\r\n"                                                  \
    	"Host: www.google.com:443\r\n"                                         \
    	"Connection: close\r\n\r\n"
    
    #define HTTP_HEAD_LEN (sizeof(HTTP_HEAD) - 1)
    
    #define HTTP_HDR_END "\r\n\r\n"
    
    #define RECV_BUF_SIZE 2048
    #define TLS_SEC_TAG 42
    
    static const char send_buf[] = HTTP_HEAD;
    static char recv_buf[RECV_BUF_SIZE];
    
    /* Certificate for `google.com` */
    static const char cert[] = {
    	#include "GlobalSign-Root-CA-R2"
    };
    
    BUILD_ASSERT_MSG(sizeof(cert) < KB(4), "Certificate too large");
    
    /* Setup TLS options on a given socket */
    int tls_setup(int fd)
    {
    	int err;
    	int verify;
    
    	/* Security tag that we have provisioned the certificate with */
    	const sec_tag_t tls_sec_tag[] = {
    		TLS_SEC_TAG,
    	};
    
    	/* Set up TLS peer verification */
    	enum {
    		NONE = 0,
    		OPTIONAL = 1,
    		REQUIRED = 2,
    	};
    
    	verify = REQUIRED;
    
    	err = setsockopt(fd, SOL_TLS, TLS_PEER_VERIFY, &verify, sizeof(verify));
    	if (err) {
    		printk("Failed to setup peer verification, err %d\n", errno);
    		return err;
    	}
    
    	/* Associate the socket with the security tag
    	 * we have provisioned the certificate with.
    	 */
    	err = setsockopt(fd, SOL_TLS, TLS_SEC_TAG_LIST, tls_sec_tag,
    			 sizeof(tls_sec_tag));
    	if (err) {
    		printk("Failed to setup TLS sec tag, err %d\n", errno);
    		return err;
    	}
    
    	return 0;
    }
    
    
    void google()
    {
    	int fd;
    	char *p;
    	int bytes;
    	size_t off;
    	struct addrinfo *res;
    	struct addrinfo hints = {
    		.ai_family = AF_INET,
    		.ai_socktype = SOCK_STREAM,
    	};
    
    	int err = getaddrinfo("google.com", NULL, &hints, &res);
    	if (err) {
    		printk("getaddrinfo() failed, err %d\n", errno);
    		return;
    	}
    
    	((struct sockaddr_in *)res->ai_addr)->sin_port = htons(HTTPS_PORT);
    
    	fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TLS_1_2);
    	if (fd == -1) {
    		printk("Failed to open socket!\n");
    		goto clean_up;
    	}
    
    	/* Setup TLS socket options */
    	err = tls_setup(fd);
    	if (err) {
    		goto clean_up;
    	}
    
    	printk("Connecting to %s\n", "google.com");
    	err = connect(fd, res->ai_addr, sizeof(struct sockaddr_in));
    	if (err) {
    		printk("connect() failed, err: %d\n", errno);
    		goto clean_up;
    	}
    
    	off = 0;
    	do {
    		bytes = send(fd, &send_buf[off], HTTP_HEAD_LEN - off, 0);
    		if (bytes < 0) {
    			printk("send() failed, err %d\n", errno);
    			goto clean_up;
    		}
    		off += bytes;
    	} while (off < HTTP_HEAD_LEN);
    
    	printk("Sent %d bytes\n", off);
    
    	off = 0;
    	do {
    		bytes = recv(fd, &recv_buf[off], RECV_BUF_SIZE - off, 0);
    		if (bytes < 0) {
    			printk("recv() failed, err %d\n", errno);
    			goto clean_up;
    		}
    		off += bytes;
    	} while (bytes != 0 /* peer closed connection */);
    
    	printk("Received %d bytes\n", off);
    
    	/* Print HTTP response */
    	p = strstr(recv_buf, "\r\n");
    	if (p) {
    		off = p - recv_buf;
    		recv_buf[off + 1] = '\0';
    		printk("\n>\t %s\n\n", recv_buf);
    	}
    
    	printk("Finished, closing socket.\n");
    
    clean_up:
    	freeaddrinfo(res);
    
    //Work around for socekt
            if(1)//fd!=2)
            {
              printk("closing socket: %d\n", fd);
              (void)close(fd);
            }
            else
            {
              printk("skipping closing socket: %d\n", fd);
            }
    }
    
    
    /* Provision certificate to modem */
    int cert_provision(void)
    {
    	int err;
    	bool exists;
    	u8_t unused;
    
    	err = modem_key_mgmt_exists(TLS_SEC_TAG,
    				    MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN,
    				    &exists, &unused);
    	if (err) {
    		printk("Failed to check for certificates err %d\n", err);
    		return err;
    	}
    
    	if (exists) {
    		/* For the sake of simplicity we delete what is provisioned
    		 * with our security tag and reprovision our certificate.
    		 */
    		err = modem_key_mgmt_delete(TLS_SEC_TAG,
    					    MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN);
    		if (err) {
    			printk("Failed to delete existing certificate, err %d\n",
    			       err);
    		}
    	}
    
    	printk("Provisioning certificate\n");
    
    	/*  Provision certificate to the modem */
    	err = modem_key_mgmt_write(TLS_SEC_TAG,
    				   MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN,
    				   cert, sizeof(cert) - 1);
    	if (err) {
    		printk("Failed to provision certificate, err %d\n", err);
    		return err;
    	}
    
    	return 0;
    }
    
    void modem_init()
    {
    	int err = bsdlib_init();
    	if (err) {
    		printk("Failed to initialize bsdlib!");
    		return;
    	}
    
    	/* Initialize AT comms in order to provision the certificate */
    	err = at_comms_init();
    	if (err) {
    		return;
    	}
    
    	/* Provision certificates before connecting to the LTE network */
    	err = cert_provision();
    	if (err) {
    		return;
    	}
    
    	printk("Waiting for network.. ");
    	err = lte_lc_init_and_connect();
    	if (err) {
    		printk("Failed to connect to the LTE network, err %d\n", err);
    		return;
    	}
    	printk("OK\n");
    
    }
    /**
     * @brief This is Application Start Point.
     *      
     * @param None
     *
     * @return: None
     */
    void main(void)
    {
    
    	modem_init();
    
            while(1)
            {                 
                 google();    
                 k_sleep(3000);
            }
    
    
    }

     to disable workaround just change the if condition to be always true in close

    I am also attaching the modem trace files one in which socket is unresponsive and one with the work around

    code stuck.bin

    with-workaround.bin

  • Thanks for the traces and the code.

    We are still working on identifying the source of the problem, but it seems like it was introduced in bsdlib v6.1.

    If I use v6.0 instead, the problem does not occur for me.

    You can revert to v6.0 by replacing the 1.2.0 revision of nrfxlib on line 72 in <ncs>/nrf/west.yml with 3e381d09f1d305e230435f5b6e4c9ef928b6a697, and running "west update".

Reply Children
No Data
Related