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 Reply Children
  • Hello, 

    I found this post

    https://devzone.nordicsemi.com/f/nordic-q-a/49556/enabling-config_posix_api-w-nrf-v1-0-0-causes-linker-error-for-multiple-definitions-of-fcntl

    And I remove nrf API and add Zephyr API, when I send http request, it exit immediately without data. 

    Please check and explain what I wrong.

    int http_request_config(char * http_payload)
    {
    int ret;
         
         struct sockaddr_in server_sockadd_in;
         int server_sock = -1;

         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) {

              int flags = fcntl(server_sock, F_GETFL, 0);
              LOG_DBG(">>>>>>>> nrf_fcntl verified value set to %d\n"flags);
              ret = fcntl(server_sock, F_SETFL, flags | O_NONBLOCK);
              int rflags = fcntl(server_sock, F_GETFL, 0);
              LOG_DBG(">>>>>>>> nrf_fcntl verified value set to %d\n"flags);


              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);
              LOG_DBG("Begin http request");
              ret = http_client_req(server_sock, &http_req7 * MSEC_PER_SEC, "IPv4 POST");
              if (ret < 0) {
                   LOG_ERR("Fail to request to server!");
              }
              LOG_DBG("Exit http request");
              close(server_sock);
              return 0;
         }
         else {
              LOG_DBG("Network err");
              close(server_sock);
              return -1;
         }

    }

    /*This is console LOG*/

    [00:05:28.680,938] <dbg> tracker_op_mode.tracker_start: ------------------
    [00:05:28.688,232] <dbg> tracker_op_mode.tracker_start: --!!!!!!!!!!!!!!!!!!!!!!!!!!!!----------------
    [00:05:28.698,303] <dbg> http_common.setup_socket: creat sock = 1
    [00:05:28.704,833] <dbg> http_common.connect_socket: Pass setup socket
    [00:05:29.241,485] <dbg> http_common.connect_socket: Pass connect
    [00:05:29.248,016] <dbg> http_common.connect_socket: Pass ret
    [00:05:29.254,211] <dbg> http_requests.http_request_config: >>>>>>>> nrf_fcntl verified value set to 0

    [00:05:29.263,977] <dbg> http_requests.http_request_config: >>>>>>>> nrf_fcntl verified value set to 0

    [00:05:29.273,773] <dbg> http_requests.http_request_config: Begin http request
    [00:05:29.281,463] <dbg> net_http.Data to send
    50 4f 53 54 20 2f 54 68 69 6e 67 77 6f 72 78 2f |POST /Th ingworx/
    54 68 69 6e 67 73 2f 62 32 65 36 64 31 35 33 2d |Things/b 2e6d153-
    37 61 64 36 2d 34 34 37 65 2d 38 63 64 39 2d 62 |7ad6-447 e-8cd9-b
    30 34 62 37 63 38 31 38 66 38 38 2f 53 65 72 76 |04b7c818 f88/Serv
    69 63 65 73 2f 43 6f 6e 66 69 67 3f 61 70 70 4b |ices/Con fig?appK
    65 79 3d 35 34 30 33 62 65 39 37 2d 35 36 36 65 |ey=5403b e97-566e
    2d 34 66 39 38 2d 62 36 65 32 2d 65 66 32 30 35 |-4f98-b6 e2-ef205
    37 33 34 33 32 64 66 26 41 63 63 65 70 74 3d 61 |73432df& Accept=a
    70 70 6c 69 63 61 74 69 6f 6e 25 32 46 6a 73 6f |pplicati on%2Fjso
    6e 20 48 54 54 50 2f 31 2e 31 0d 0a 48 6f 73 74 |n HTTP/1 .1..Host
    3a 20 31 37 31 2e 32 34 34 2e 31 33 33 2e 32 32 |: 171.24 4.133.22
    36 0d 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a |6..Conte nt-Type:
    [00:05:29.359,741] <dbg> net_http.Data to send
    20 61 70 70 6c 69 63 61 74 69 6f 6e 2f 6a 73 6f | applica tion/jso
    6e 0d 0a 0d 0a |n....
    [00:05:29.377,014] <dbg> net_http.http_client_req: (workqueue): Sent 375 bytes
    [00:05:29.384,674] <dbg> net_http.http_client_req: (workqueue): Pass http client init
    [00:05:29.392,913] <dbg> net_http.http_client_req: (workqueue): Pass k timeout EQ
    [00:05:29.400,787] <dbg> net_http.http_wait_data: http_wait_data running
    [00:05:29.407,897] <dbg> net_http.http_wait_data: Pass recv
    [00:05:29.413,909] <dbg> net_http.http_wait_data: Connection error (11)
    [00:05:29.420,959] <dbg> net_http.http_client_req: (workqueue): Wait data failure (-11)
    [00:05:29.429,351] <dbg> http_requests.http_request_config: Exit http request
    [00:05:29.436,920] <dbg> net_sock.z_impl_zsock_close: (workqueue): close: ctx=0x00000003, fd=1
    [00:05:30.804,138] <dbg> at_cmd.socket_thread_fn: at_cmd_rx 19 bytes, %CESQ: 41,2,10,1

    %CESQ: 41,2,10,1

    -->When it go into http_wait_data. it return connection error immediately

    Thank you

  • 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

Related