summaryrefslogtreecommitdiff
path: root/examples/IPC_SAP/TLI_SAP/CPP-ATM-client.cpp
blob: 35dda19f05e2478e3665e843e39947c36b7cbc1c (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
153
154
155
156
157
158
159
160
161
162
// $Id$

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

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

#if defined (ACE_HAS_FORE_ATM_XTI)

/* ACE_XTI/ATM Client */

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

  unsigned char selector = ACE_ATM_Addr::DEFAULT_SELECTOR;
  int selector_specified = 0;
  extern int optind;
  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

  const char *host = argv[optind];

  int rate = (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
  ACE_ATM_QoS qos;
  qos.set_rate(cli_stream.get_handle (),
               rate,
               ACE_ATM_QoS::OPT_FLAGS_CPID);

  struct netbuf optbuf = qos.get_qos();
//   long optlen = 0;
//   char *options = remote_addr.construct_options (cli_stream.get_handle (),
//                                                  rate,
//                                                  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 ACE_TMAIN (int, ACE_TCHAR *[])
{
  ACE_ERROR_RETURN ((LM_ERROR,
		     "your platform isn't configured to support XTI/ATM\n"),
                    1);
}
#endif /* ACE_HAS_TLI */