nRF9160 HTTP clien slow response

hi:

Use the https_client routine to send data after the socket is established, and then send the data after getting the response. The errno returns as 128, which can confirm that the cloud platform is not disconnected. In addition, the time from sending the request to getting the response is nearly 2 minutes, which is too long to receive. How can I improve the problem I'm encountering now, thank you

void main(void)
{
int err;
int fd;
char *p;
int bytes;
size_t off;
struct addrinfo *res;
struct addrinfo hints = {
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM,
};
struct timeval timeout;//666
int data_len;
uint32_t connect_attempt = 0;

printk("http link onenet sample started\n\r");


printk("Waiting for network.. ");
do{
err = lte_lc_init_and_connect();
if (err) {
printk("Failed to connect to the LTE network, err %d\n", err);
k_sleep(K_SECONDS(CONFIG_HTTP_RECONNECT_DELAY_S));
}
}while(err);
printk("OK\n");


if (connect_attempt++ > 0) {
printk("Reconnecting in %d seconds...",CONFIG_HTTP_RECONNECT_DELAY_S);
k_sleep(K_SECONDS(CONFIG_HTTP_RECONNECT_DELAY_S));
}

err = getaddrinfo(HTTP_HOSTNAME, NULL, &hints, &res);
if (err) {
printk("getaddrinfo() failed, err %d\n", errno);
goto clean_up;
}

((struct sockaddr_in *)res->ai_addr)->sin_port = htons(HTTP_PORT);

if (IS_ENABLED(CONFIG_SAMPLE_TFM_MBEDTLS)) {
fd = socket(AF_INET, SOCK_STREAM | SOCK_NATIVE_TLS, IPPROTO_TLS_1_2);
} else {
fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);// IPPROTO_TLS_1_2
}
if (fd == -1) {
printk("Failed to open socket!\n");
goto clean_up;
}

/*666*/
timeout.tv_sec = WEBCLIENT_DEFAULT_TIMEO;
timeout.tv_usec = 0;
/* set recv timeout option */
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void*) &timeout,
sizeof(timeout));
//setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (void*) &timeout,
// sizeof(timeout));
/*666*/

/* Setup TLS socket options */
//err = tls_setup(fd);
//if (err) {
// goto clean_up;
//}

printk("Connecting to %s\n", HTTP_HOSTNAME);
err = connect(fd, res->ai_addr, sizeof(struct sockaddr_in));
if (err) {
printk("connect() failed, err: %d\n", errno);
goto clean_up;
}

data_len = snprintf(send_buf,SEND_BUF_SIZE,"%s",HTTP_GET_DETECT);
off = 0;
do {
bytes = send(fd, &send_buf[off], data_len - off, 0);
if (bytes < 0) {
printk("send() failed, err %d\n", errno);
goto clean_up;
}
off += bytes;
} while (off < data_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);
}

data_len = snprintf(send_buf,SEND_BUF_SIZE,"%s",HTTP_GET_DETECT);
off = 0;
do {
bytes = send(fd, &send_buf[off], data_len - off, 0);
if (bytes < 0) {
printk("2.send() failed, err %d\n", errno);
goto clean_up;
}
off += bytes;
} while (off < data_len);

printk("2.Sent %d bytes\n", off);

off = 0;
do {
bytes = recv(fd, &recv_buf[off], RECV_BUF_SIZE - off, 0);
if (bytes < 0) {
printk("2.recv() failed, err %d\n", errno);
goto clean_up;
}
off += bytes;
} while (bytes != 0 /* peer closed connection */);

printk("2.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);
(void)close(fd);

lte_lc_power_off();
}

Parents
  • Hi,

     

    It seems that you have two issues, one errno returned, and the second that the process (when successful) takes up to 2 minutes. 

    The errno returns as 128, which can confirm that the cloud platform is not disconnected.

    That errno indicates that your LTE connection is lost, and sockets are also lost:

    https://github.com/eblot/newlib/blob/master/newlib/libc/include/sys/errno.h#L161

     

    What is the LTE connection status at this point? Are you using LTE-M or NB1?

     

    In addition, the time from sending the request to getting the response is nearly 2 minutes, which is too long to receive. How can I improve the problem I'm encountering now, thank you

    In your function, you also connect to the LTE network before opening a stream socket. That can take time, depending on the coverage near your area and the signal strength of the connected LTE cell tower.

    If you are using NB1, this is a much slower transport compared to LTE-M, which again adds time to the overall process.

     

    Kind regards,

    Håkon

     

  • OK, thanks. Regarding the problem of returning errno 128, the cloud platform did not actively disconnect. Why does it return errno 128 when sending the second packet, and why does the modem disconnect? Reconnecting to the cloud platform every time is time consuming.
    I use NB1, but the rate of 2 minutes per packet is unacceptable compared to GPRS.

  • nicekey said:
    will the operation of the modem affect my initialization of the screen? For example to interrupt?

    That depends on your local settings. But, yes; there's communication between the modem and the application, so you can get interrupts when things happen on the LTE Network side of things (for instance, receive a packet etc) that needs to be handled.

     

    Kind regards,

    Håkon

  • void main(void)
    {
    int err;
    int fd;
    char *p;
    int bytes;
    size_t off;
    struct addrinfo *res;
    struct addrinfo hints = {
    .ai_family = AF_INET,
    .ai_socktype = SOCK_STREAM,
    };
    struct timeval timeout;//666
    int data_len;
    int link_status = 0;
    int recv_data_len = 0;
    int result;
    //int result_bit;
    uint32_t connect_attempt = 0;
    cJSON *root = NULL, *object = NULL, *item = NULL;

    printk("http link onenet sample started\n\r");

    epd_spi_init();
    //k_sched_lock();
    epd_init();

    As in the above code, when the modem is turned on, epd_init() is executed,

    Will other tasks interrupt the execution of epd_init()?

    If so, how to protect it. In my project, there are no other threads.

    When the modem function is turned on, it takes a long time to boot to the application, it takes four minutes, is this normal?

    If Failed to open socket occurs, I find that calling lte_lc_init_and_connect() has no effect. Do I need to power off and restart the modem at this time?

  • Hi,

     

    nicekey said:

    As in the above code, when the modem is turned on, epd_init() is executed,

    Will other tasks interrupt the execution of epd_init()?

    You need to evaluate your own firmware and how it runs in general.

    Any interrupt that occurs in your application can potentially interrupt that function. However, it seems that very little else is running in your main function at the time of calling that function.

    nicekey said:

    When the modem function is turned on, it takes a long time to boot to the application, it takes four minutes, is this normal?

    It can be if you're waiting for the LTE Link to connect, ie. if CONFIG_LTE_AUTO_INIT_AND_CONNECT is set to 'y'.

     

    nicekey said:
    If Failed to open socket occurs, I find that calling lte_lc_init_and_connect() has no effect. Do I need to power off and restart the modem at this time?

    Calling that function again will not help. You're already enabled and have previously been connected, and the modem is highly likely trying to reconnect to the network. However:

    Without any debug information about the link status at this time, it is hard to say what happens.

    Please see my former responses on how to get detailed information about your link, ie. via CEREG or possibly the lte_lc handler.

    Kind regards,

    Håkon

  • CONFIG_LTE_AUTO_INIT_AND_CONNECT is set to 'n' in my project.

    When "Failed to open socket" appears, I make socket link every 20 seconds, but can't recover from "Failed to open socket", what should I do?

    When CONFIG_LTE_AUTO_INIT_AND_CONNECT is set to 'y', when "Failed to open socket" appears, it will always stop at "Failed to open socket" and cannot be recovered.

  • If you do not properly close() former sockets, this can happen. Is your code updated compared to the initial code you posted? if yes, can you share the updated project?

    Have you implemented the event handler for the lte_lc library, which can give you notifications on what is happening on the network side?

     

    Kind regards,

    Håkon

Reply Children
No Data
Related