summaryrefslogtreecommitdiff
path: root/examples/IPC_SAP/TLI_SAP/CPP-ATM-client.cpp
blob: a9fe506d555386c1f6dd675c249b1a0a6ecc9a3a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// $Id$

#include "ace/TLI_Connector.h"
#include "ace/ATM_Addr.h"                              

ACE_RCSID(TLI_SAP, CPP_ATM_client, "$Id$")

#if defined (ACE_HAS_FORE_ATM_XTI)

/* ACE_XTI/ATM Client */

int main (int argc, char *argv[])                       
{
  if (argc < 2)
    ACE_ERROR_RETURN ((LM_ERROR, 
                       "Usage: %s hostname [-s selector] [QoS in KB/sec]\n",
                       argv[0]),
                      1);

  const char *host = argv[1];
  unsigned char selector = ACE_ATM_Addr::DEFAULT_SELECTOR;
  int selector_specified = 0;
  int opt;
  while ((opt = ACE_OS::getopt (argc, argv, "s:?h")) != EOF)
    {
    switch(opt)
      {
      case 's':
        selector = ACE_OS::atoi (optarg);
        selector_specified = 1;
        break;
      case '?':
      case 'h':
        ACE_ERROR_RETURN ((LM_ERROR,
                           "Usage: %s hostname [-s selector] [QoS in KB/s]\n",
                           argv[0]),
                          1);
      } // switch
    } // while getopt

  int qos = (argc == 3) ? ACE_OS::atoi (argv[2]) :
    (argc == 5) ? ACE_OS::atoi (argv[4]) : 0;
  // The timeout really gets ignored since FORE's drivers don't work when
  //  ioctl or fcntl calls are made on the transport id/file descriptor
  int timeout = ACE_DEFAULT_TIMEOUT;

  char buf[BUFSIZ];

  ACE_TLI_Stream cli_stream;

  ACE_ATM_Addr remote_addr (host);
  if (selector_specified)
    remote_addr.set_selector(selector);
  char hostname[MAXNAMELEN];
  ACE_OS::hostname(hostname, MAXNAMELEN);
  ACE_ATM_Addr local_addr (hostname);

  // In order to construct connections options the file handle is
  // needed.  Therefore, we need to open the TLI_Stream before we
  // construct the options.
  if (cli_stream.open (ACE_XTI_ATM_DEVICE, O_RDWR, 0) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "%p\n",
                       "open failed"),
                      1);

  ACE_DEBUG ((LM_DEBUG,
              "starting non-blocking connect\n"));

  // Initiate timed, non-blocking connection with server.
  ACE_TLI_Connector con;
                                                        
  // Construct QoS options - currently FORE only supports bandwidth
  long optlen = 0;
  char *options = ACE_ATM_Addr::construct_options (cli_stream.get_handle (),
                                                   qos,
                                                   ACE_ATM_Addr::OPT_FLAGS_CPID,
                                                   &optlen);
  struct netbuf optbuf;
  optbuf.len = optlen;
  optbuf.buf = options;

  // Not sure why but reuse_addr set to true/1 causes problems for
  // FORE/XTI/ATM - this is now handled in ACE_TLI_Connector::connect()
  if (con.connect (cli_stream,
                   remote_addr, 
                   (ACE_Time_Value *) &ACE_Time_Value::zero,
                   local_addr,
                   1,
                   O_RDWR,
                   0,
                   ACE_XTI_ATM_DEVICE,
                   0,
                   1,
                   0,
                   &optbuf) == -1)
    {
      if (errno != EWOULDBLOCK)
	ACE_ERROR_RETURN ((LM_ERROR,
                           "%p\n",
                           "connection failed"),
                          1);

      ACE_DEBUG ((LM_DEBUG,
                  "starting timed connect\n"));

      // Check if non-blocking connection is in progress, and wait up
      // to timeout seconds for it to complete.
      ACE_Time_Value tv (timeout);

      if (con.complete (cli_stream,
                        &remote_addr,
                        &tv) == -1)
	ACE_ERROR_RETURN ((LM_ERROR,
                           "%p\n",
                           "connection failed"),
                          1);
      else
	ACE_DEBUG ((LM_DEBUG,
                    "connected to %s\n", 
		    remote_addr.addr_to_string ()));
    }

  // Send data to server (correctly handles "incomplete writes").
  
  for (int r_bytes;
       (r_bytes = ACE_OS::read (ACE_STDIN, buf, sizeof buf)) > 0; 
       )
    if (cli_stream.send_n (buf,
                           r_bytes,
                           0) == -1)
      ACE_ERROR_RETURN ((LM_ERROR,
                         "%p\n",
                         "send_n"),
                        1);

  // Explicitly close the connection.
  if (cli_stream.close () == -1) 
    ACE_ERROR_RETURN ((LM_ERROR,
                       "%p\n",
                       "close"),
                      -1);
  return 0;
}                                                       
#else
int main (int, char *[])
{
  ACE_ERROR_RETURN ((LM_ERROR, 
		     "your platform isn't configured to support XTI/ATM\n"),
                    1);
}
#endif /* ACE_HAS_TLI */