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
63 \todo Implement Spliters: PassiveSplitter, PrioritySplitter, CloneSplitter
66 /** \defgroup io_modules Input/Output Modules
68 Input/Output Modules receive data from external sources or forward data from the PPI to
72 /** \defgroup sourcesink_modules Source/Sink Modules
74 Source and Sink modules generate or absorb packets internally. In contrast to \ref
75 io_modules, they do not communicate outside the PPI.
78 /** \defgroup routing_modules Routing Modules
80 Routing modules perform packet forwarding within the network. They do not process the packet
81 data, they just route it.
84 /** \defgroup adapter_modules Adapter Modules
86 Adapter modules adapt incompatible connectors to each other. They allow connection a pair of
87 active or passive connectors.
90 /** \brief Module base-class
92 senf::ppi::Module is the base-class of all PPI modules. It provides the module implementation
93 with interfaces to several PPI facilities:
95 \li Connector management
96 \li Flow management (routing)
99 To provide internal bookkeeping, most access to the PPI infrastructure is managed through
100 this base class. This is an example module specification:
102 class SomeModule : public senf::ppi::module::Module
104 SENF_PPI_MODULE(SomeModule);
106 senf::FileHandle handle;
108 // If needed, define events
109 senf::ppi::IOEvent event;
112 // Define connectors. Any number and type of connectors may be defined. Connectors
113 // must be public since they need to be accessed to connect modules with each other.
114 senf::ppi::connector::PassiveInput input;
115 senf::ppi::connector::ActiveOutput output;
117 SomeModule(senf::FileHandle h)
119 event ( handle, senf::ppi::IOEvent::Read )
121 // Set up routing. If some connector is not routed you need to explicitly state this
123 route( input, output );
124 route( event, output )
125 .autoThrottling( false );
127 // Register event handlers
128 registerEvent( &SomeModule::read, event );
130 // Register passive connector handlers
131 input.onRequest( &SomeModule::outputRequest );
133 // If needed, you may register throttling event handlers
134 output.onThrottle( &SomeModule::throttle );
135 output.onUnthrottle( &SomeModule::unthrottle );
139 // Called whenever the 'handle' is readable. Read data, do processing and so
140 // on. This example reads the data, puts it into an ethernet packet and sends the
141 // packet out via the active output.
142 output(senf::EthernetPacket::create(handle.read()))
145 void outputRequest() {
146 // Called whenever a packet is sent into the input to. Here we just forward it to
147 // the output if it is an EthernetPacket
148 senf::EthernetPacket p (input().find<EthernetPacket>(senf::nothrow));
154 // Called whenever a throttle notification comes in. Here, we just disable the
155 // event (which is stupid since we should just not have disabled autoThrottling on
156 // the route but this is only an example which tries to be simple ...)
160 void onUnthrottle() {
161 // and for unthrottle notifications
168 If your module only has a single input connector, you should call this connector \c
169 input. If it has only a single output connector, you should call it \c output. This allows
170 to setup connections without stating the connector explicitly (see senf::ppi::connect()).
182 template <class Source, class Target>
183 Route<Source, Target> & route(Source & source, Target & target);
185 Route<connector::InputConnector, connector::OutputConnector> &
186 route(connector::InputConnector & input, connector::OutputConnector & output);
187 ///< Define flow information
188 /**< Using the route() and noroute() members, the
189 information flow within the module is defined. Routing
190 may be defined between inputs, outputs and events. The
191 routing information is used to perform automatic
192 throttling. The throttling behavior may however be
195 Even if no automatic throttling is desired <em>it is
196 essential to define the flow information for all inputs
197 and outputs</em>. Without flow information important
198 internal state of the module cannot be
199 initialized. This includes, explicitly defining
200 terminal inputs and outputs using noroute. Event
201 routing is optional however.
203 The return value may be used to alter routing
204 parameters like throttling parameters.
206 \param[in] source Data source, object which controls
207 incoming data (connector or event)
208 \param[in] target Data target, object which controls
209 outgoing data (connector or event)
210 \returns Route instance describing this route
211 \note The real implementation is not provided by three
212 overloads but by a single template member */
214 Route<connector::InputConnector, EventDescriptor> &
215 route(connector::InputConnector & input, EventDescriptor & output);
216 ///< Define flow information
217 /**< Route from a connector to an event. Routing from a
218 connector to an event defines the event as the
219 conceptual 'receiver' of the data. This means, the
220 event is controlling the processing of received data
221 packets (Example: Routing from an input to an IOEvent
222 defines, that input data will be processed whenever the
225 This event routing allows to automatically
226 enable/disable the event on throttling notifications.
230 Route<EventDescriptor, connector::OutputConnector> &
231 route(EventDescriptor & input, connector::OutputConnector & output);
232 ///< Define flow information
233 /**< Route from an event to a connector. Routing from an
234 event to a connector defeines the event as the
235 conceptual 'source' of the data. THis means, the event
236 controls how packets are sent (Example: Routing from an
237 IOEVent to an output defines, that output data will be
238 generated whenever the event is signaled).
240 This event routing allows to automatically
241 enable/disable the event on throttling notifications.
246 void noroute(connector::Connector & connector); ///< Define terminal connectors
247 /**< The noroute() member explicitly declares, that a
248 connector is terminal and does not directly
249 receive/forward data from/to some other
250 connector. <em>It is mandatory to define routing
251 information for terminal connectors</em>.
253 See the route() documentation for more on routing
255 \param[in] connector Terminal connector to declare */
258 template <class Descriptor, class Target>
259 void registerEvent(Descriptor & descriptor, Target target);
261 template <class Target>
262 void registerEvent(Target target, EventDescriptor & descriptor);
263 ///< Register an external event
264 /**< The \a target argument may be either an arbitrary
265 callable object or it may be a member function pointer
266 pointing to a member function of the Module derived
267 classed. The handler may \e optionally take an Argument
268 of type <tt>Descriptor::Event const &</tt>. This object
269 allows to access detailed information on the event
272 The \a descriptor describes the event to signal like a
273 timer event or some type of I/O event on a file
274 descriptor or socket.
276 \param[in] target The handler to call whenever the
278 \param[in] descriptor The type of event to register */
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