3 //=============================================================================
7 * This code builds abstractions to factor out common code from
8 * the different possible implementations of the Timer_Queue based
9 * bounded packet relay example.
11 * @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>
13 //=============================================================================
16 #ifndef _BPR_DRIVERS_H_
17 #define _BPR_DRIVERS_H_
19 #include "ace/Functor.h"
21 #if !defined (ACE_LACKS_PRAGMA_ONCE)
23 #endif /* ACE_LACKS_PRAGMA_ONCE */
25 #include "ace/Reactor.h"
28 // forward declarations
29 class Input_Device_Wrapper_Base
;
30 class Output_Device_Wrapper_Base
;
33 * @class Bounded_Packet_Relay
35 * @brief This class defines a packet relay abstraction for a
36 * transmission bounded external commands to start and end the
37 * transmission. The transmission may be bounded by the number
38 * of packets to send, the dration of the transmission, or any
41 * The relay abstraction implemented by this class registers a
42 * callback command with an input device wrapper, and relays
43 * input to an output device at a pace specified in the start
46 class Bounded_Packet_Relay
49 // = Enumerates possible status values for a transmission.
50 enum Transmission_Status
62 DEFAULT_HWM
= 0x7FFFFFFF,
63 DEFAULT_LWM
= 0x7FFFFFFF
66 /// Command entry point type definition.
67 typedef int (Bounded_Packet_Relay::*ACTION
) (void *);
70 Bounded_Packet_Relay (ACE_Thread_Manager
*input_task_mgr
,
71 Input_Device_Wrapper_Base
*input_wrapper
,
72 Output_Device_Wrapper_Base
*output_wrapper
);
75 virtual ~Bounded_Packet_Relay ();
77 /// Requests output be sent to output device.
80 /// Requests a transmission be started.
81 int start_transmission (u_long packet_count
,
82 u_long arrival_period
,
85 /// Requests a transmission be ended.
86 int end_transmission (Transmission_Status status
);
88 /// Requests a report of statistics from the last transmission.
89 int report_statistics ();
91 // = Command accessible entry points.
93 /// Public entry point to which to push input.
94 int receive_input (void *);
96 // = Accessors and mutators for relay settings
98 /// Get high water mark for relay queue.
99 ACE_UINT32
queue_hwm ();
101 /// Set high water mark for relay queue.
102 void queue_hwm (ACE_UINT32 hwm
);
104 /// Get low water mark for relay queue.
105 ACE_UINT32
queue_lwm ();
107 /// Set low water mark for relay queue.
108 void queue_lwm (ACE_UINT32 lwm
);
111 // = Concurrency Management.
113 /// flag for whether or not a transmission is active
116 /// Thread manager for the input device task.
117 ACE_Thread_Manager
* input_task_mgr_
;
119 /// Pointer to the input device wrapper.
120 Input_Device_Wrapper_Base
* input_wrapper_
;
122 /// Pointer to the output device wrapper.
123 Output_Device_Wrapper_Base
* output_wrapper_
;
125 /// Queue used to buffer input messages.
126 ACE_Message_Queue
<ACE_SYNCH
> queue_
;
128 /// High water mark for relay queue.
129 ACE_UINT32 queue_hwm_
;
131 /// Low water mark for relay queue.
132 ACE_UINT32 queue_lwm_
;
134 /// Lock for thread-safe synchronization of transmission startup and
136 ACE_SYNCH_MUTEX transmission_lock_
;
138 // = Transmission Statistics
140 /// Returns string corresponding to current status.
141 const char *status_msg ();
143 /// Number of transmissions sent.
144 u_long transmission_number_
;
146 /// Count of packets sent in the most recent transmission.
147 u_long packets_sent_
;
149 /// Status of the current or most recent transmission.
150 Transmission_Status status_
;
152 /// Start time of the most recent transmission.
153 ACE_Time_Value transmission_start_
;
155 /// Ending time of the most recent transmission.
156 ACE_Time_Value transmission_end_
;
160 * @class Input_Device_Wrapper_Base
162 * @brief This class defines an abstract base class for an input device
163 * wrapper that hides the details of the specific device and
164 * provides a consistent message passing interface without
165 * knowing anything about the implementation of the input device
166 * or the message receiver.
167 * The abstract base class ctor takes a command template object
168 * that is instantiated with the correct receiver and action
169 * types. This command object is used to send newly created input
170 * messages to the receiver.
171 * The abstract base class is designed to operate in an active
172 * "push" mode, sending input data to the receiver whenever the
173 * data is ready. The underlying device may be active, notifying
174 * the wrapper when data is ready, or may be passive in which
175 * case the wrapper must rely on a reactive and/or polling
178 * Derived classes are responsible for filling in concrete
179 * definitions for the abstract message creation method and the
182 class Input_Device_Wrapper_Base
: public ACE_Task_Base
186 Input_Device_Wrapper_Base (ACE_Thread_Manager
*input_task_mgr
);
189 virtual ~Input_Device_Wrapper_Base ();
191 /// Sets send input message command in the input device driver
193 int set_send_input_msg_cmd (ACE_Command_Base
*send_input_msg_cmd
);
195 /// Sets period (in usecs) between when inputs are created.
196 int set_input_period (u_long input_period
);
198 /// Sets count of messages to send.
199 int set_send_count (long count
);
202 * Requests that the input device stop sending messages and
203 * terminate its thread. Should return 1 if it will do so, 0 if it
204 * has already done so, or -1 if there is a problem doing so.
208 /// This method runs the input device loop in the new thread.
211 /// Provides an abstract interface to allow modifying device
213 virtual int modify_device_settings (void *) = 0;
216 /// Creates a new message block, carrying data read from the
217 /// underlying input device.
218 virtual ACE_Message_Block
*create_input_message () = 0;
221 * Sends a newly created message block, carrying data read from the
222 * underlying input device, by passing a pointer to the message
223 * block to its command execution.
225 virtual int send_input_message (ACE_Message_Block
*);
227 /// Send newly created input message.
228 ACE_Command_Base
*send_input_msg_cmd_
;
230 /// Period between when input values are produced (usecs).
231 u_long input_period_
;
233 /// Reactor used to multiplex input streams, timeouts.
234 ACE_Reactor reactor_
;
236 /// Flag to indicate whether or not input object is
237 /// (and should remain) active.
240 /// Count of messages to send before stopping (-1 indicates the
241 /// device should not stop).
244 /// Currently remaining count of messages to send before stopping
245 /// (-1 indicates the device should not stop).
250 * @class Output_Device_Wrapper_Base
252 * @brief This class defines an abstract base class for an output device
253 * wrapper that hides the details of the specific device and
254 * provides a consistent write method interface without knowing
255 * anything about the implementation.
257 * The abstract methods write_output_message () and
258 * modify_device_settings () are defined in derived classes to
259 * write the contents of the passed message out the underlying
260 * output device, and update device settings, respectively.
262 class Output_Device_Wrapper_Base
265 virtual ~Output_Device_Wrapper_Base ();
267 /// Writes contents of the passed message block out to the underlying
269 virtual int write_output_message (void *) = 0;
271 /// Provides an abstract interface to allow modifying device
273 virtual int modify_device_settings (void *) = 0;
276 // include the templates
277 #include "BPR_Drivers_T.h"
279 #endif /* _BPR_DRIVERS_H_ */