AnsweredAssumed Answered

How to diagnose RTCS connection problems?

Question asked by Michael Wahler on Jun 18, 2014
Latest reply on Jun 20, 2014 by Michael Wahler

Hi again,

 

I have been able to compile and run a simple RTCS-based program (MQX 4.1, C++). As a simple example, I am trying to connect to a web server.

 

The problem is that the connection times out. I am unsure about the following things:

 

- After initialization, mac_address is 1 and ethernet_address is {0, 0, 94, 168, 1, 202}. Is this correct?

- Does the rest of the code look OK (in terms of RTCS initialization

 

Kind regards

 

Michael

 

 

 

 

#ifndef NETWORK_H_

#define NETWORK_H_

 

#include <mqx.h>

#include <bsp.h>

 

// network-specific headers below

extern "C" {

#include <rtcs.h>

#include <ipcfg.h>

#include <enet.h>

}

 

/*

** Define IP address and IP network mask

*/

#ifndef ENET_IPADDR

#define ENET_IPADDR    IPADDR(192, 168, 1, 202)

#endif

 

 

#ifndef ENET_IPMASK

#define ENET_IPMASK    IPADDR(255, 255, 255, 0)

#endif

 

 

#ifndef ENET_IPGATEWAY

#define ENET_IPGATEWAY IPADDR(192, 168, 1, 1)

#endif

 

 

#define TCPSERVER_RECV_BUF_SIZE     10

#define TCPSERVER_SEND_BUF_SIZE    50

#define TCPSERVER_TASK_INDX         2

#define TCPS_SUBTHREAD_INDX 3

 

struct _ip_digital

{

  uint8_t high;

  uint8_t middlehigh;

  uint8_t middlelow;

  uint8_t low;

};

 

void ip_to_digital(_ip_address ip, _ip_digital *p)

{

  p->high       = (ip >> 24) & 0xFF;

  p->middlehigh = (ip >> 16) & 0xFF;

  p->middlelow  = (ip >> 8)  & 0xFF;

  p->low        = (ip)       & 0xFF;

}

 

 

class Network

{

private:

  _enet_address ethernet_address;  // TODO ?? = BSP_DEFAULT_ENET_OUI;

  IPCFG_IP_ADDRESS_DATA ip_data;

  uint32_t mac_address;

 

public:

  Network ()

{

  _RTCS_socket_part_init = 8;

  uint32_t result = RTCS_create();

 

 

  if (result == RTCS_OK)

  {

  mac_address = ENET_get_mac_address (

  BSP_DEFAULT_ENET_DEVICE,

  ENET_IPADDR,

  ethernet_address);

 

 

  ip_data.ip      = ENET_IPADDR;

  ip_data.mask    = ENET_IPMASK;

  ip_data.gateway = ENET_IPGATEWAY;

 

 

  result = ipcfg_init_device (BSP_DEFAULT_ENET_DEVICE, ethernet_address);

 

 

  if (result == RTCS_OK)

  {

  result = ipcfg_bind_staticip (BSP_DEFAULT_ENET_DEVICE, &ip_data);

 

  if (result == RTCS_OK)

  {

// _task_create (0, TCPSERVER_TASK_INDX, 0);

  }

  else

  {

  _io_printf ("[Network] Error binding to IP address.\n");

  }

  }

  else

  {

  _io_printf ("[Network] Error initalizing device.\n");

  }

  }

 

 

  print_status_info ();

  _io_printf ("[Network] constructor finished.\n");

}

 

 

  void print_status_info ()

  {

  _io_printf("[Network] Ethernet address: '");

  for (size_t i = 0; i < 6; ++i)

  {

  _io_printf ("%d",ethernet_address [i]);

  if (i < 5)

  _io_printf ("-");

  else

  _io_printf("\n");

  }

 

  _ip_digital x;

  ip_to_digital(ENET_IPADDR, &x);

 

 

  _io_printf("[Network] IP address: %d.%d.%d.%d\n", x.high, x.middlehigh, x.middlelow, x.low);

  _io_printf("[Network] MAC address: %d\n", mac_address);

 

 

  }

 

 

  /**

  * just a test routine to send a packet to a server

  */

  void send_something ()

  {

  _ip_address ip = IPADDR(192,168,1,100);

  uint16_t port = 8000;

  _io_printf ("[Network::send_something] to 192.168.1.100:8000\n");

  uint32_t     error;

  char        buffer[50];

  sockaddr    server_socket_addr;

  uint32_t     socket_handle;

  _ip_digital digit;

  uint32_t     opt_val;

  uint32_t     opt_len;

 

  opt_val =  15 * 1000;

  opt_len = sizeof(uint32_t);

 

  // set remote host(TCPServer) socket address

  server_socket_addr.sin_family      = AF_INET;

  server_socket_addr.sin_port        = port;

  server_socket_addr.sin_addr.s_addr = ip;

 

 

  // loop to establish connection

  do {

  // Create a stream socket for TCPClient.

  socket_handle = socket(AF_INET, SOCK_STREAM, 0);

  if (socket_handle == RTCS_SOCKET_ERROR) {

  _io_printf("\n[Network::send_something]: Failed to create socket.\n");

  _task_block();

  }

  _io_printf ("[Network::send_something] created socket.\n");

 

 

  // set 15s for connection Timeout

  error = setsockopt(socket_handle, SOL_TCP, OPT_CONNECT_TIMEOUT, &opt_val, opt_len);

  if (error != RTCS_OK) {

  _io_printf("\n[Network::send_something]: Failed to setsockopt for OPT_CONNECT_TIMEOUT, CODE = 0x%x.\n", error);

  _task_block();

  }

 

 

  _io_printf ("[Network::send_something] set socket timeout.\n");

 

 

  // try to connect TCPServer

  error = connect(socket_handle, &server_socket_addr, sizeof(server_socket_addr));

  if (error != RTCS_OK) {

  if (error == RTCSERR_TCP_TIMED_OUT) {

  _io_printf("\n[Network::send_something]: Connection timeout.\n");

  } else if (error == RTCSERR_TCP_CONN_RESET) {

  _io_printf("\n[Network::send_something]: Connection reset by peer.\n"); // When connect to PC but TCPServer shuntdown, will alert this error

  }

  shutdown(socket_handle, FLAG_ABORT_CONNECTION);

  _io_printf("\n[Network::send_something]: Retry to connect TCPServer 5 seconds later...\n");

  _time_delay(5 * 1000);

  }

  else

  {

  _io_printf ("[Network::send_something] connection established.\n");

  }

  } while (error != RTCS_OK);

 

 

  _io_printf ("[Network::send_something] ready to send.\n");

 

  }

};

 

 

#endif /* NETWORK_H_ */

Outcomes