This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

non - blocking socket nrf9160 HTTP TCP

Hello

I am using HTTP to requests on the server with NB-IoT network on NRF9160 chip

I found that in the HTTP REQUEST command with 1 REV () function to get the results returned via socket

When I encounter weak NB-IOT network conditions, there is no returned data and the REV function hangs forever. This is very dangerous.

pubs.opengroup.org/.../recv.html

In this document says I need to turn on non-blocking mode so that the Rev function doesn't hang, I have followed it but it still hang.

This is my code. Please help me handle this as quickly as possible.

int setup_socket(sa_family_t familyconst char *serverint port,
               int *sockstruct sockaddr *addrsocklen_t addr_lenbool domain)
{
     const char *family_str = family == AF_INET ? "IPv4" : "IPv6";
     int ret = 0;
     int verify = TLS_PEER_VERIFY_NONE;
     struct addrinfo *res;
     struct addrinfo hints = {
               .ai_family = AF_INET,
               .ai_socktype = SOCK_STREAM,
     };

     memset(addr0addr_len);

     if (domain)
     {
          ret = getaddrinfo(serverNULL, &hints, &res);
          if (ret) {
               LOG_ERR("getaddrinfo() failed, err %d\n", errno);
               return;
          }
          
               memcpy(addrres->ai_addrsizeof(res->ai_addr));
     } 
     
     if (family == AF_INET) {
          net_sin(addr)->sin_family = AF_INET;
          net_sin(addr)->sin_port = htons(port);
          inet_pton(familyserver, &net_sin(addr)->sin_addr);
     } else {
          net_sin6(addr)->sin6_family = AF_INET6;
          net_sin6(addr)->sin6_port = htons(port);
          inet_pton(familyserver, &net_sin6(addr)->sin6_addr);
     }
 
          *sock = socket(family, SOCK_STREAM, IPPROTO_TCP);
          
          int flags = nrf_fcntl(*sock, NRF_F_GETFL, 0);
          LOG_DBG(">>>>>>>> nrf_fcntl verified value get to %d\n"flags);
          ret = nrf_fcntl(*sock, NRF_F_SETFL, flags | NRF_O_NONBLOCK);
          int rflags = nrf_fcntl(*sock, NRF_F_GETFL, 0);
          LOG_DBG(">>>>>>>> nrf_fcntl verified value set to %d\n"flags);
     if (*sock < 0) {
          LOG_ERR("Failed to create %s HTTP socket (%d)"family_str,
               -errno);
     }

     return ret;
}

int connect_socket(sa_family_t familyconst char *serverint port,
                 int *sockstruct sockaddr *addrsocklen_t addr_lenbool domain)
{
     int ret;
     ret = setup_socket(familyserverportsockaddraddr_lendomain);
     if (ret < 0 || *sock < 0) {
          return -1;
     }
     ret = connect(*sockaddraddr_len);
     if (ret < 0) {
          LOG_ERR("Cannot connect to %s remote (%d)",
               family == AF_INET ? "IPv4" : "IPv6",
               -errno);
          ret = -errno;
     }
     LOG_DBG("Pass ret");
     return ret;
}

/*This is HTTP request*/
int http_request_config(char * http_payload)
{
     int ret;
     struct sockaddr_in server_sockadd_in;
     int server_sock = -1;
     
     struct http_request http_req;
     const char *headers[] = {
          "Content-Type: application/json\r\n",
          NULL
     };

     memset(&http_req0sizeof(http_req));
     memset(http_recv_buf,0,strlen(http_recv_buf));

     ret = connect_socket(AF_INET, IOT_SERVER_IPIOT_SERVER_HTTP_PORT,
                         &server_sock, (struct sockaddr *) &server_sockadd_in,
                         sizeof(server_sockadd_in), false);
     if (ret >= 0) {
          http_req.url = url;
          http_req.method = HTTP_POST;
          http_req.protocol = "HTTP/1.1";
          http_req.host = IOT_SERVER_IP;
          http_req.payload = http_payload;
          http_req.payload_len = strlen(http_payload);
          http_req.header_fields = headers;
          http_req.response = response_cb;
          http_req.recv_buf = http_recv_buf;
          http_req.recv_buf_len = sizeof(http_recv_buf);
          ret = http_client_req(server_sock, &http_req3 * MSEC_PER_SEC, "IPv4 POST");
          if (ret < 0) {
               LOG_ERR("Fail to request to server!");
          }
          close(server_sock);
          return 0;
     }
     else {
          LOG_DBG("Network err");
          close(server_sock);
          return -1;
     }
}

Thank you

Parents
  • Hello,

    haohv6 said:
    Please check and explain what I wrong.

    Are you using a TLS socket? In this case, my suspicion is that the response data is too large (>2kB, which is our limit in the modem).

    haohv6 said:
    Moreover, I do http request by a work and submit it to my queue, is there anyway to abort ( or cancel, disable, exit, etc....) that work when socket is blocked

    Theoretically this is not possible. But in practice you can close the socket from another thread, which should make the recv function to return an error. Another alternative would be to set a timeout on the socket with the setsockopt API. If the socket won't unblock until the timeout expires, it'll return with an error.

    Regards,

    Markus

Reply
  • Hello,

    haohv6 said:
    Please check and explain what I wrong.

    Are you using a TLS socket? In this case, my suspicion is that the response data is too large (>2kB, which is our limit in the modem).

    haohv6 said:
    Moreover, I do http request by a work and submit it to my queue, is there anyway to abort ( or cancel, disable, exit, etc....) that work when socket is blocked

    Theoretically this is not possible. But in practice you can close the socket from another thread, which should make the recv function to return an error. Another alternative would be to set a timeout on the socket with the setsockopt API. If the socket won't unblock until the timeout expires, it'll return with an error.

    Regards,

    Markus

Children
No Data
Related