summaryrefslogtreecommitdiff
path: root/ACE/examples/Bounded_Packet_Relay/BPR_Drivers.h
blob: 33d96964c37936aa0c4a26908f0fae2fac22d376 (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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
/* -*- C++ -*- */

//=============================================================================
/**
 *  @file    BPR_Drivers.h
 *
 *  This code builds abstractions to factor out common code from
 *  the different possible implementations of the Timer_Queue based
 *  bounded packet relay example.
 *
 *  @author Chris Gill           <cdgill@cs.wustl.edu>  and Douglas C. Schmidt   <d.schmidt@vanderbilt.edu> Based on the Timer Queue Test example written by Carlos O'Ryan        <coryan@cs.wustl.edu>  and Douglas C. Schmidt   <d.schmidt@vanderbilt.edu> and Sergio Flores-Gaitan <sergio@cs.wustl.edu>
 */
//=============================================================================


#ifndef _BPR_DRIVERS_H_
#define _BPR_DRIVERS_H_

#include "ace/Functor.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

#include "ace/Reactor.h"
#include "ace/Task.h"

// forward declarations
class Input_Device_Wrapper_Base;
class Output_Device_Wrapper_Base;

/**
 * @class Bounded_Packet_Relay
 *
 * @brief This class defines a packet relay abstraction for a
 * transmission bounded external commands to start and end the
 * transmission.  The transmission may be bounded by the number
 * of packets to send, the dration of the transmission, or any
 * other factors.
 *
 * The relay abstraction implemented by this class registers a
 * callback command with an input device wrapper, and relays
 * input to an output device at a pace specified in the start
 * transmission call.
 */
class Bounded_Packet_Relay
{
public:
  // = Enumerates possible status values for a transmission.
  enum Transmission_Status
  {
    UN_INITIALIZED,
    STARTED,
    COMPLETED,
    TIMED_OUT,
    CANCELLED,
    ERROR_DETECTED
  };

  enum Queue_Defaults
  {
    DEFAULT_HWM = 0x7FFFFFFF,
    DEFAULT_LWM = 0x7FFFFFFF
  };

  /// Command entry point type definition.
  typedef int (Bounded_Packet_Relay::*ACTION) (void *);

  /// Constructor.
  Bounded_Packet_Relay (ACE_Thread_Manager *input_task_mgr,
                        Input_Device_Wrapper_Base *input_wrapper,
                        Output_Device_Wrapper_Base *output_wrapper);

  /// Destructor.
  virtual ~Bounded_Packet_Relay (void);

  /// Requests output be sent to output device.
  int send_input (void);

  /// Requests a transmission be started.
  int start_transmission (u_long packet_count,
                          u_long arrival_period,
                          int logging_level);

  /// Requests a transmission be ended.
  int end_transmission (Transmission_Status status);

  /// Requests a report of statistics from the last transmission.
  int report_statistics (void);

  // = Command accessible entry points.

  /// Public entry point to which to push input.
  int receive_input (void *);

  // = Accessors and mutators for relay settings

  /// Get high water mark for relay queue.
  ACE_UINT32 queue_hwm (void);

  /// Set high water mark for relay queue.
  void queue_hwm (ACE_UINT32 hwm);

  /// Get low water mark for relay queue.
  ACE_UINT32 queue_lwm (void);

  /// Set low water mark for relay queue.
  void queue_lwm (ACE_UINT32 lwm);

private:
  // = Concurrency Management.

  /// flag for whether or not a transmission is active
  int is_active_;

  /// Thread manager for the input device task.
  ACE_Thread_Manager * input_task_mgr_;

  /// Pointer to the input device wrapper.
  Input_Device_Wrapper_Base * input_wrapper_;

  /// Pointer to the output device wrapper.
  Output_Device_Wrapper_Base * output_wrapper_;

  /// Queue used to buffer input messages.
  ACE_Message_Queue<ACE_SYNCH> queue_;

  /// High water mark for relay queue.
  ACE_UINT32 queue_hwm_;

  /// Low water mark for relay queue.
  ACE_UINT32 queue_lwm_;

  /// Lock for thread-safe synchronization of transmission startup and
  /// termination.
  ACE_SYNCH_MUTEX transmission_lock_;

  // = Transmission Statistics

  /// Returns string corresponding to current status.
  const char *status_msg (void);

  /// Number of transmissions sent.
  u_long transmission_number_;

  /// Count of packets sent in the most recent transmission.
  u_long packets_sent_;

  /// Status of the current or most recent transmission.
  Transmission_Status status_;

  /// Start time of the most recent transmission.
  ACE_Time_Value transmission_start_;

  /// Ending time of the most recent transmission.
  ACE_Time_Value transmission_end_;

};

/**
 * @class Input_Device_Wrapper_Base
 *
 * @brief This class defines an abstract base class for an input device
 * wrapper that hides the details of the specific device and
 * provides a consistent message passing interface without
 * knowing anything about the implementation of the input device
 * or the message receiver.
 * The abstract base class ctor takes a command template object
 * that is instantiated with the correct receiver and action
 * types. This command object is used to send newly created input
 * messages to the receiver.
 * The abstract base class is designed to operate in an active
 * "push" mode, sending input data to the receiver whenever the
 * data is ready.  The underlying device may be active, notifying
 * the wrapper when data is ready, or may be passive in which
 * case the wrapper must rely on a reactive and/or polling
 * mechanism.
 *
 * Derived classes are responsible for filling in concrete
 * definitions for the abstract message creation method and the
 * svc method.
 */
class Input_Device_Wrapper_Base : public ACE_Task_Base
{
public:
  /// Constructor.
  Input_Device_Wrapper_Base (ACE_Thread_Manager *input_task_mgr);

  /// Destructor.
  virtual ~Input_Device_Wrapper_Base ();

  /// Sets send input message command in the input device driver
  /// object.
  int set_send_input_msg_cmd (ACE_Command_Base *send_input_msg_cmd);

  /// Sets period (in usecs) between when inputs are created.
  int set_input_period (u_long input_period);

  /// Sets count of messages to send.
  int set_send_count (long count);

  /**
   * Requests that the input device stop sending messages and
   * terminate its thread.  Should return 1 if it will do so, 0 if it
   * has already done so, or -1 if there is a problem doing so.
   */
  int request_stop (void);

  /// This method runs the input device loop in the new thread.
  virtual int svc ();

  /// Provides an abstract interface to allow modifying device
  /// settings.
  virtual int modify_device_settings (void *) = 0;

protected:
  /// Creates a new message block, carrying data read from the
  /// underlying input device.
  virtual ACE_Message_Block *create_input_message (void) = 0;

  /**
   * Sends a newly created message block, carrying data read from the
   * underlying input device, by passing a pointer to the message
   * block to its command execution.
   */
  virtual int send_input_message (ACE_Message_Block *);

  /// Send newly created input message.
  ACE_Command_Base *send_input_msg_cmd_;

  /// Period between when input values are produced (usecs).
  u_long input_period_;

  /// Reactor used to multiplex input streams, timeouts.
  ACE_Reactor reactor_;

  /// Flag to indicate whether or not input object is
  /// (and should remain) active.
  int is_active_;

  /// Count of messages to send before stopping (-1 indicates the
  /// device should not stop).
  long send_count_;

  /// Currently remaining count of messages to send before stopping
  /// (-1 indicates the device should not stop).
  long current_count_;

};

/**
 * @class Output_Device_Wrapper_Base
 *
 * @brief This class defines an abstract base class for an output device
 * wrapper that hides the details of the specific device and
 * provides a consistent write method interface without knowing
 * anything about the implementation.
 *
 * The abstract methods write_output_message () and
 * modify_device_settings () are defined in derived classes to
 * write the contents of the passed message out the underlying
 * output device, and update device settings, respectively.
 */
class Output_Device_Wrapper_Base
{
public:

  virtual ~Output_Device_Wrapper_Base (void);

  /// Writes contents of the passed message block out to the underlying
  /// output device.
  virtual int write_output_message (void *) = 0;

  /// Provides an abstract interface to allow modifying device
  /// settings.
  virtual int modify_device_settings (void *) = 0;
};

// include the templates
#include "BPR_Drivers_T.h"

#endif /* _BPR_DRIVERS_H_ */