2 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
3 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
4 // Stefan Bund <g0dil@berlios.de>
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the
18 // Free Software Foundation, Inc.,
19 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 \brief Module public header
30 #include <boost/utility.hpp>
31 #include <boost/ptr_container/ptr_vector.hpp>
32 #include "Scheduler/ClockService.hh"
35 //#include "Module.mpp"
36 ///////////////////////////////hh.p////////////////////////////////////////
42 /** \namespace senf::ppi::module
45 The modules build the PPI core. The PPI provides a set of general purpose infrastructure
46 modules. For concrete applications, additional application specific processing modules need
49 \section module_impl Implementing Modules
51 All modules derive from senf::ppi::module::Module. See this class for a documentation on how
54 \section infrastructure_modules General Purpose Modules
56 The PPI provided general purpose modules can be grouped into several categories
58 \li \ref io_modules receive external data or forward packets out of the PPI
59 \li \ref sourcesink_modules generate or absorb packets internally
60 \li \ref routing_modules forward packets within the network
61 \li \ref adapter_modules are used to connect incompatible connectors to each other
64 /** \defgroup io_modules Input/Output Modules
66 Input/Output Modules receive data from external sources or forward data from the PPI to
70 /** \defgroup sourcesink_modules Source/Sink Modules
72 Source and Sink modules generate or absorb packets internally. In contrast to \ref
73 io_modules, they do not communicate outside the PPI.
76 /** \defgroup routing_modules Routing Modules
78 Routing modules perform packet forwarding within the network. They do not process the packet
79 data, they just route it.
82 /** \defgroup adapter_modules Adapter Modules
84 Adapter modules adapt incompatible connectors to each other. They allow connection a pair of
85 active or passive connectors.
88 /** \brief Module base-class
90 senf::ppi::Module is the base-class of all PPI modules. It provides the module implementation
91 with interfaces to several PPI facilities:
93 \li Connector management
94 \li Flow management (routing)
97 To provide internal bookkeeping, most access to the PPI infrastructure is managed through
98 this base class. This is an example module specification:
100 class SomeModule : public senf::ppi::module::Module
102 SENF_PPI_MODULE(SomeModule);
104 senf::FileHandle handle;
106 // If needed, define events
107 senf::ppi::IOEvent event;
110 // Define connectors. Any number and type of connectors may be defined. Connectors
111 // must be public since they need to be accessed to connect modules with each other.
112 senf::ppi::connector::PassiveInput input;
113 senf::ppi::connector::ActiveOutput output;
115 SomeModule(senf::FileHandle h)
117 event ( handle, senf::ppi::IOEvent::Read )
119 // Set up routing. If some connector is not routed you need to explicitly state this
121 route( input, output );
122 route( event, output )
123 .autoThrottling( false );
125 // Register event handlers
126 registerEvent( &SomeModule::read, event );
128 // Register passive connector handlers
129 input.onRequest( &SomeModule::outputRequest );
131 // If needed, you may register throttling event handlers
132 output.onThrottle( &SomeModule::throttle );
133 output.onUnthrottle( &SomeModule::unthrottle );
137 // Called whenever the 'handle' is readable. Read data, do processing and so
138 // on. This example reads the data, puts it into an ethernet packet and sends the
139 // packet out via the active output.
140 output(senf::EthernetPacket::create(handle.read()))
143 void outputRequest() {
144 // Called whenever a packet is sent into the input to. Here we just forward it to
145 // the output if it is an EthernetPacket
146 senf::EthernetPacket p (input().find<EthernetPacket>(senf::nothrow));
152 // Called whenever a throttle notification comes in. Here, we just disable the
153 // event (which is stupid since we should just not have disabled autoThrottling on
154 // the route but this is only an example which tries to be simple ...)
158 void onUnthrottle() {
159 // and for unthrottle notifications
166 If your module only has a single input connector, you should call this connector \c
167 input. If it has only a single output connector, you should call it \c output. This allows
168 to setup connections without stating the connector explicitly (see senf::ppi::connect()).
179 template <class Source, class Target>
180 Route<Source, Target> & route(Source & source, Target & target);
181 ///< Define flow information
182 /**< Using the route() and noroute() members, the
183 information flow within the module is defined. Routing
184 may be specified either between inputs, outputs and
185 events. The routing information is used to perform
186 automatic throttling. The throttling behavior may
187 however be controlled manually.
189 Even if no automatic throttling is desired <em>it is
190 vital to define the flow information for all inputs and
191 outputs</em>. Without flow information important
192 internal state of the module cannot be
193 initialized. This includes, explicitly defining
194 terminal inputs and outputs using noroute. Event
195 routing however is optional.
197 The return value may be used to alter routing
198 parameters like throttling parameters.
200 \param[in] source Data source, object which controls
202 \param[in] target Data target, object which controls
204 \returns Route instance describing this route */
206 void noroute(connector::Connector & connector); ///< Define terminal connectors
207 /**< The noroute() member explicitly declares, that a
208 connector is terminal and does not directly
209 receive/forward data from/to some other
210 connector. <em>It is mandatory to define routing
211 information for terminal connectors</em>.
213 See the route() documentation for more on routing
215 \param[in] connector Terminal connector to declare */
217 template <class Target, class Descriptor>
218 void registerEvent(Target target, Descriptor & descriptor);
219 ///< Register an external event
220 /**< The \a target argument may be either an arbitrary
221 callable object or it may be a member function pointer
222 pointing to a member function of the Module derived
223 classed. The handler may \e optionally take an Argument
224 of type <tt>Descriptor::Event const &</tt>. This object
225 allows to access detailed information on the event
228 The \a descriptor describes the event to signal. This
230 may be a timer event or some type of I/O event on a
231 file descriptor or socket.
233 \param[in] target The handler to call whenever the
235 \param[in] descriptor The type of event to register */
237 ClockService::clock_type time() const; ///< Time-stamp of the currently processing event
238 /**< If available, this returns the scheduled time of the
241 ClockService::clock_type now() const; ///< Current time of the currently processing event
244 virtual void macro_SENF_PPI_MODULE_missing() = 0;
250 virtual void init(); ///< Called just before the network is run
258 EventManager & eventManager() const;
259 ModuleManager & moduleManager() const;
261 void registerConnector(connector::Connector & connector);
262 RouteBase & addRoute(std::auto_ptr<RouteBase> route);
264 typedef std::vector<connector::Connector *> ConnectorRegistry;
265 ConnectorRegistry connectorRegistry_;
267 typedef boost::ptr_vector<RouteBase> RouteInfoBase;
268 RouteInfoBase routes_;
270 template <class Source, class Target>
271 friend class detail::RouteHelper;
272 friend class senf::ppi::ModuleManager;
275 /** \brief Define PPI Module
277 Every module must begin by using this macro.
279 \see senf::ppi::module::Module
281 # define SENF_PPI_MODULE(name) \
283 ~ name() { destroy(); } \
284 void macro_SENF_PPI_MODULE_missing() {} \
289 ///////////////////////////////hh.e////////////////////////////////////////
290 #include "Module.cci"
292 //#include "Module.cti"
299 // c-file-style: "senf"
300 // indent-tabs-mode: nil
301 // ispell-local-dictionary: "american"
302 // compile-command: "scons -u test"
303 // comment-column: 40