4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 \brief Module public header
32 #include <boost/utility.hpp>
33 #include <boost/ptr_container/ptr_vector.hpp>
34 #include "../Scheduler/ClockService.hh"
37 //#include "Module.mpp"
38 ///////////////////////////////hh.p////////////////////////////////////////
44 /** \namespace senf::ppi::module
47 The modules build the PPI core. The PPI provides a set of general purpose infrastructure
48 modules. For concrete applications, additional application specific processing modules need
51 \section module_impl Implementing Modules
53 All modules derive from senf::ppi::module::Module. See this class for a documentation on how
56 \section infrastructure_modules General Purpose Modules
58 The PPI provided general purpose modules can be grouped into several categories
60 \li \ref io_modules receive external data or forward packets out of the PPI
61 \li \ref routing_modules forward packets within the network
62 \li \ref adapter_modules are used to connect incompatible connectors to each other
64 \todo Implement Spliters: PassiveSplitter, PrioritySplitter, CloneSplitter
67 /** \defgroup io_modules Source/Sink Modules
69 Source and Sink modules generate or absorb packets in some way: Reading data from a file
70 descriptor, discarding packets etc.
73 /** \defgroup routing_modules Routing Modules
75 Routing modules perform packet forwarding within the network. They do not process the packet
76 data, they just route it.
79 /** \defgroup adapter_modules Adapter Modules
81 Adapter modules adapt incompatible connectors to each other. They allow connection a pair of
82 active or passive connectors.
85 /** \brief Module base-class
87 senf::ppi::Module is the base-class of all PPI modules. It provides the module implementation
88 with interfaces to several PPI facilities:
90 \li Connector management
91 \li Flow management (routing)
94 To provide internal bookkeeping, most access to the PPI infrastructure is managed through
95 this base class. This is an example module specification:
97 class SomeModule : public senf::ppi::module::Module
99 SENF_PPI_MODULE(SomeModule);
101 senf::FileHandle handle;
103 // If needed, define events
104 senf::ppi::IOEvent event;
107 // Define connectors. Any number and type of connectors may be defined. Connectors
108 // must be public since they need to be accessed to connect modules with each other.
109 senf::ppi::connector::PassiveInput<> input;
110 senf::ppi::connector::ActiveOutput<> output;
112 SomeModule(senf::FileHandle h)
114 event ( handle, senf::ppi::IOEvent::Read )
116 // Set up routing. If some connector is not routed you need to explicitly state this
118 route( input, output );
119 route( event, output )
120 .autoThrottling( false );
122 // Register event handlers
123 registerEvent( event, &SomeModule::read );
125 // Register passive connector handlers
126 input.onRequest( &SomeModule::outputRequest );
128 // If needed, you may register throttling event handlers
129 output.onThrottle( &SomeModule::throttle );
130 output.onUnthrottle( &SomeModule::unthrottle );
134 // Called whenever the 'handle' is readable. Read data, do processing and so
135 // on. This example reads the data, puts it into an ethernet packet and sends the
136 // packet out via the active output.
137 output(senf::EthernetPacket::create(handle.read()))
140 void outputRequest() {
141 // Called whenever a packet is sent into the input to. Here we just forward it to
142 // the output if it is an EthernetPacket
143 senf::EthernetPacket p (input().find<EthernetPacket>(senf::nothrow));
149 // Called whenever a throttle notification comes in. Here, we just disable the
150 // event (which is stupid since we should just not have disabled autoThrottling on
151 // the route but this is only an example which tries to be simple ...)
155 void onUnthrottle() {
156 // and for unthrottle notifications
163 If your module only has a single input connector, you should call this connector \c
164 input. If it has only a single output connector, you should call it \c output. This allows
165 to setup connections without stating the connector explicitly (see senf::ppi::connect()).
167 \see \ref ppi_modules
179 template <class Source, class Target>
180 Route<Source, Target> & route(Source & source, Target & target);
182 Route<connector::InputConnector, connector::OutputConnector> &
183 route(connector::InputConnector & input, connector::OutputConnector & output);
184 ///< Define flow information
185 /**< Using the route() and noroute() members, the
186 information flow within the module is defined. Routing
187 may be defined between inputs, outputs and events. The
188 routing information is used to perform automatic
189 throttling. The throttling behavior may however be
192 Even if no automatic throttling is desired <em>it is
193 essential to define the flow information for all inputs
194 and outputs</em>. Without flow information important
195 internal state of the module cannot be
196 initialized. This includes, explicitly defining
197 terminal inputs and outputs using noroute. Event
198 routing is optional however.
200 The return value may be used to alter routing
201 parameters like throttling parameters.
203 \param[in] input Data source, object which controls
204 incoming data (connector or event)
205 \param[in] output Data target, object which controls
206 outgoing data (connector or event)
207 \returns Route instance describing this route
208 \see \ref ppi_throttling
209 \note The real implementation is not provided by three
210 overloads but by a single template member */
212 Route<connector::InputConnector, EventDescriptor> &
213 route(connector::InputConnector & input, EventDescriptor & output);
214 ///< Define flow information
215 /**< Route from a connector to an event. Routing from a
216 connector to an event defines the event as the
217 conceptual 'receiver' of the data. This means, the
218 event is controlling the processing of received data
219 packets (Example: Routing from an input to an IOEvent
220 defines, that input data will be processed whenever the
223 This event routing allows to automatically
224 enable/disable the event on throttling notifications.
228 Route<EventDescriptor, connector::OutputConnector> &
229 route(EventDescriptor & input, connector::OutputConnector & output);
230 ///< Define flow information
231 /**< Route from an event to a connector. Routing from an
232 event to a connector defines the event as the
233 conceptual 'source' of the data. This means, the event
234 controls how packets are sent (Example: Routing from an
235 IOEVent to an output defines, that output data will be
236 generated whenever the event is signaled).
238 This event routing allows to automatically
239 enable/disable the event on throttling notifications.
244 void noroute(connector::Connector & connector); ///< Define terminal connectors
245 /**< The noroute() member explicitly declares, that a
246 connector is terminal and does not directly
247 receive/forward data from/to some other
248 connector. <em>It is mandatory to define routing
249 information for terminal connectors</em>.
251 See the route() documentation for more on routing
253 \param[in] connector Terminal connector to declare */
256 template <class Descriptor, class Target>
257 void registerEvent(Descriptor & descriptor, Target target);
259 template <class Target>
260 void registerEvent(EventDescriptor & descriptor, Target target);
261 ///< Register an external event
262 /**< The \a target argument may be either an arbitrary
263 callable object or it may be a member function pointer
264 pointing to a member function of the Module derived
265 classed. The handler may \e optionally take an Argument
266 of type <tt>Descriptor::Event const &</tt>. This object
267 allows to access detailed information on the event
270 The \a descriptor describes the event to signal like a
271 timer event or some type of I/O event on a file
272 descriptor or socket.
274 \param[in] target The handler to call whenever the
276 \param[in] descriptor The type of event to register
277 \note The real implementation has the second arguments
278 type as an additional template parameter. */
281 ClockService::clock_type time() const; ///< Time-stamp of the currently processing event
282 /**< If available, this returns the scheduled time of the
285 ClockService::clock_type now() const; ///< Current time of the currently processing event
288 virtual void macro_SENF_PPI_MODULE_missing() = 0;
292 virtual void init(); ///< Called just before the network is run
300 EventManager & eventManager() const;
301 ModuleManager & moduleManager() const;
303 void registerConnector(connector::Connector & connector);
304 RouteBase & addRoute(std::auto_ptr<RouteBase> route);
306 typedef std::vector<connector::Connector *> ConnectorRegistry;
307 ConnectorRegistry connectorRegistry_;
309 typedef boost::ptr_vector<RouteBase> RouteInfoBase;
310 RouteInfoBase routes_;
312 template <class Source, class Target>
313 friend class detail::RouteHelper;
314 friend class senf::ppi::ModuleManager;
317 /** \brief Define PPI Module
319 Every module must begin by using this macro.
321 \see senf::ppi::module::Module
323 # define SENF_PPI_MODULE(name) \
325 ~ name() { destroy(); } \
326 void macro_SENF_PPI_MODULE_missing() {} \
331 ///////////////////////////////hh.e////////////////////////////////////////
332 #include "Module.cci"
334 //#include "Module.cti"
341 // c-file-style: "senf"
342 // indent-tabs-mode: nil
343 // ispell-local-dictionary: "american"
344 // compile-command: "scons -u test"
345 // comment-column: 40