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

nRF9160 TCP connect errno -116

Shalom!

 I am getting with the nRF9160, BSD TCP sockets, a connect()  errno=116  after disconnecting and closing a previous TCP connection.

I have two TCP servers with the same IP just different ports. When I switch to the second one, I get this error. I can connect at startup to the second server so the problem is not with the  server.

What am I doing wrong?

I use set the socket SO_RCVTIMEO to 30000 so that when closing the previous server the blocking call to blocking_recv() will return.

I had thought, that if I had not set the socket receive timeout, that closing the socket would cause the recv() call to return but this is not the case, so I set the timeout.

#define CONFIG_DOWNLOAD_CLIENT_TCP_SOCK_TIMEO_MS 30000

Below is my connection snippet.

Thanks

//-----------------------------------------------------------------------------
// Flag to indicate if a disconnect has been requested. 
//-----------------------------------------------------------------------------
static atomic_t disconnect_requested;
static int      app_socket_fd = -1;
...

//-----------------------------------------------------------------------------
// ami_socket_get_disconnect_requested
//  Description
//    
//  Parameters
//  Returns
//
//-----------------------------------------------------------------------------
bool ami_socket_get_disconnect_requested(void)
{
  return (bool)atomic_get(&disconnect_requested);
} // ami_socket_get_disconnect_requested

//-----------------------------------------------------------------------------
// blocking_recv
//  Description
//    
//  Parameters
//  Returns
//
//-----------------------------------------------------------------------------
int blocking_recv(int fd, u8_t *buf, u32_t size, u32_t flags)
{
  int err;

  do{
     err = recv(fd, buf, size, flags);
  }while ((err<0) && (errno==EAGAIN) && !ami_socket_get_disconnect_requested());
  return err;
} // blocking_recv

//-----------------------------------------------------------------------------
// blocking_send
//  Description
//    
//  Parameters
//  Returns
//
//-----------------------------------------------------------------------------
static int blocking_send(int fd, u8_t *buf, u32_t size, u32_t flags)
{
  int err;

  do{
     err = send(fd, buf, size, flags);
  }while ((err<0) && (errno==EAGAIN) && !ami_socket_get_disconnect_requested());
  return err;
} // blocking_send

//-----------------------------------------------------------------------------
// ami_main_SendBinaryData
//  Description
//    Tries to send the bianry data over the connection
//  Parameters
//    buf
//    len
//  Returns
//    true if sent
//-----------------------------------------------------------------------------
bool ami_socket_SendBinaryData(const unsigned char *buf,uint16_t len)
{
  int err = blocking_send(app_socket_fd,(u8_t *)buf, len, 0);
  if (err < 0) {
    d_printf(LINE_INFO,kDbg_Error|kDbg_General,"TX Fail:%d", errno);
  }
  return (err==0);
} // ami_socket_SendBinaryData

//-----------------------------------------------------------------------------
// blocking_connect
//  Description
//    
//  Parameters
//  Returns
//   0 = OK
//-----------------------------------------------------------------------------
static 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) && !ami_socket_get_disconnect_requested());
  return err;
} // blocking_connect

//-----------------------------------------------------------------------------
// socket_timeout_set
//  Description
//    
//  Parameters
//  Returns
//   0 = OK
//-----------------------------------------------------------------------------
static int socket_timeout_set(int fd, int type)
{
  int err;
  uint32_t timeout_ms;

  if (type == SOCK_STREAM) {
    timeout_ms = CONFIG_DOWNLOAD_CLIENT_TCP_SOCK_TIMEO_MS;
  }else{
        timeout_ms = CONFIG_DOWNLOAD_CLIENT_UDP_SOCK_TIMEO_MS;
  }

  if (timeout_ms <= 0) {
    return 0;
  }

  struct timeval timeo = {
    .tv_sec = (timeout_ms / 1000),
    .tv_usec = (timeout_ms % 1000) * 1000,
  };

  d_printf(LINE_INFO,kDbg_Info|kDbg_General,"SocketTimeout:%lds", timeo.tv_sec);
  err = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
  if (err){
    d_printf(LINE_INFO,kDbg_Error|kDbg_General,"SocketTimeoutErr:%d", errno);
    return -errno;
  }
  return 0;
} // socket_timeout_set

//-----------------------------------------------------------------------------
// connect_to_cloud
//  Description
//    Tries to connect to the Cloud
//  Parameters
//  Returns
//   ami_socket_connect_result
//-----------------------------------------------------------------------------
static int connect_to_cloud(void)
{
  atomic_set(&disconnect_requested, 0);

  struct sockaddr    local_addr;
  int                err;
  char               sIPPort[24];

  sprintf(sIPPort,"%u.%u.%u.%u:%u",
      cur_server.server_ip.bytes[MSB_HI_BYTE],
      cur_server.server_ip.bytes[MSB_LO_BYTE],
      cur_server.server_ip.bytes[LSB_HI_BYTE],
      cur_server.server_ip.bytes[LSB_LO_BYTE],
      cur_server.server_port.word
   );
  //---------------------------------------------------------------------------
  // Parse the IP:Port string
  //---------------------------------------------------------------------------
  if (!net_ipaddr_parse((const char *)sIPPort,strlen(sIPPort),&local_addr)){
    d_printf(LINE_INFO,kDbg_Error|kDbg_General,"ServerIP:PortParsingErr");
    return AMI_SOCKET_CONNECT_RES_ERR_NOT_INITD;
  }
  //---------------------------------------------------------------------------
  // Close socket if opened
  //---------------------------------------------------------------------------
  if (app_socket_fd>=0){
    close(app_socket_fd);
  }
  //---------------------------------------------------------------------------
  // Create a TCP socket
  //---------------------------------------------------------------------------
  app_socket_fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  d_printf(LINE_INFO,kDbg_Info|kDbg_General,"SocketFD:%d",app_socket_fd);
  //---------------------------------------------------------------------------
  // Set socket timeout
  //---------------------------------------------------------------------------
  err = socket_timeout_set(app_socket_fd,SOCK_STREAM);
  if (err) {
    d_printf(LINE_INFO,kDbg_Info|kDbg_General,"SetSockTimeoutErr:%d", errno);
    return err;
  }
  //---------------------------------------------------------------------------
  // Connect
  //---------------------------------------------------------------------------
  err = blocking_connect(app_socket_fd, (struct sockaddr *)&local_addr,sizeof(struct sockaddr_in));
  if (errno){
    err = errno;
    d_printf(LINE_INFO,kDbg_Info|kDbg_General,"ConnectionErr:%d %s",errno,sIPPort);
  }else
    d_printf(LINE_INFO,kDbg_Info|kDbg_General,"Connected:%s",sIPPort);
  return err;
} // connect_to_cloud

  • Shalom!

     I am now testing my re-connection algorithm in case that our TCP server is restarted or the network does down and etc.

    The same thing happens when I try to reconnect to the same IP.

    It must be something that I forgot to do.

    6-16 15:36 16/06/2021 12:36:48 |  16/06/2021 15:37:06[ami_socket.c: 342] SocketFD:1
    6-16 15:36 16/06/2021 12:36:48 |  16/06/2021 15:37:06[ami_socket.c: 286] SocketTimeout:30s
    6-16 15:36 16/06/2021 12:36:48 |  16/06/2021 15:37:06[ami_main.c: 359] RRC mode:Connected
    6-16 15:36 16/06/2021 12:36:48 |  16/06/2021 15:37:06[ami_socket.c: 357] ConnectionErr:116 192.117.103.217:8808

    Thanks David

  • Shalom!

     I had another bug opened and I posted this morning's testing there by mistake so please see that thread with debug information.

    I am very sorry about the mixup, David

    https://devzone.nordicsemi.com/f/nordic-q-a/76060/lte-m-always-connected/314587#314587

  • Hello,

    have you checked the server side for any issues? Have you made sure that the connection isn't being rejected by the server?

  • Shalom!

     This morning we found my problem. I was checking the errno after calling the blocking_connect() function even when the err returned from connect() was zero therefore I was closing the socket. Now the modem seems to re-connect to our TCP server.

    Thank you very much

     David

    //-----------------------------------------------------------------------------
    // connect_to_cloud
    //  Description
    //    Tries to connect to the Cloud
    //  Parameters
    //  Returns
    //   ami_socket_connect_result
    //-----------------------------------------------------------------------------
    static int connect_to_cloud(void)
    {
      atomic_set(&disconnect_requested, 0);
    
      struct sockaddr    local_addr;
      int                err;
      char               sIPPort[24];
    
      sprintf(sIPPort,"%u.%u.%u.%u:%u",
          cur_server.server_ip.bytes[MSB_HI_BYTE],
          cur_server.server_ip.bytes[MSB_LO_BYTE],
          cur_server.server_ip.bytes[LSB_HI_BYTE],
          cur_server.server_ip.bytes[LSB_LO_BYTE],
          cur_server.server_port.word
       );
      //---------------------------------------------------------------------------
      // Parse the IP:Port string
      //---------------------------------------------------------------------------
      if (!net_ipaddr_parse((const char *)sIPPort,strlen(sIPPort),&local_addr)){
        d_printf(LINE_INFO,kDbg_Error|kDbg_General,"ServerIP:PortParsingErr");
        return AMI_SOCKET_CONNECT_RES_ERR_NOT_INITD;
      }
      //---------------------------------------------------------------------------
      // Close socket if opened
      //---------------------------------------------------------------------------
      if (app_socket_fd>=0){
        close(app_socket_fd);
      }
      //---------------------------------------------------------------------------
      // Create a TCP socket
      //---------------------------------------------------------------------------
      app_socket_fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
      d_printf(LINE_INFO,kDbg_Info|kDbg_General,"SocketFD:%d",app_socket_fd);
      //---------------------------------------------------------------------------
      // Set socket timeout
      //---------------------------------------------------------------------------
      err = socket_timeout_set(app_socket_fd,SOCK_STREAM);
      if (err) {
        d_printf(LINE_INFO,kDbg_Info|kDbg_General,"SetSockTimeoutErr:%d", errno);
        return err;
      }
      //---------------------------------------------------------------------------
      // Connect
      //---------------------------------------------------------------------------
      err = blocking_connect(app_socket_fd, (struct sockaddr *)&local_addr,sizeof(struct sockaddr_in));
      if (errno && err<0){
        err = errno;
        d_printf(LINE_INFO,kDbg_Info|kDbg_General,"ConnectionErr:%d %s",errno,sIPPort);
      }else
        d_printf(LINE_INFO,kDbg_Info|kDbg_General,"Connected:%s",sIPPort);
      return err;
    } // connect_to_cloud
    

Related