/* -*- 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 and Douglas C. Schmidt Based on the Timer Queue Test example written by Carlos O'Ryan and Douglas C. Schmidt and Sergio Flores-Gaitan */ //============================================================================= #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 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_ */