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 routing_modules forward packets within the network
60 \li \ref adapter_modules are used to connect incompatible connectors to each other
62 \todo Implement Spliters: PassiveSplitter, PrioritySplitter, CloneSplitter
65 /** \defgroup io_modules Source/Sink Modules
67 Source and Sink modules generate or absorb packets in some way: Reading data from a file
68 descriptor, discarding packets etc.
71 /** \defgroup routing_modules Routing Modules
73 Routing modules perform packet forwarding within the network. They do not process the packet
74 data, they just route it.
77 /** \defgroup adapter_modules Adapter Modules
79 Adapter modules adapt incompatible connectors to each other. They allow connection a pair of
80 active or passive connectors.
83 /** \brief Module base-class
85 senf::ppi::Module is the base-class of all PPI modules. It provides the module implementation
86 with interfaces to several PPI facilities:
88 \li Connector management
89 \li Flow management (routing)
92 To provide internal bookkeeping, most access to the PPI infrastructure is managed through
93 this base class. This is an example module specification:
95 class SomeModule : public senf::ppi::module::Module
97 SENF_PPI_MODULE(SomeModule);
99 senf::FileHandle handle;
101 // If needed, define events
102 senf::ppi::IOEvent event;
105 // Define connectors. Any number and type of connectors may be defined. Connectors
106 // must be public since they need to be accessed to connect modules with each other.
107 senf::ppi::connector::PassiveInput input;
108 senf::ppi::connector::ActiveOutput output;
110 SomeModule(senf::FileHandle h)
112 event ( handle, senf::ppi::IOEvent::Read )
114 // Set up routing. If some connector is not routed you need to explicitly state this
116 route( input, output );
117 route( event, output )
118 .autoThrottling( false );
120 // Register event handlers
121 registerEvent( event, &SomeModule::read );
123 // Register passive connector handlers
124 input.onRequest( &SomeModule::outputRequest );
126 // If needed, you may register throttling event handlers
127 output.onThrottle( &SomeModule::throttle );
128 output.onUnthrottle( &SomeModule::unthrottle );
132 // Called whenever the 'handle' is readable. Read data, do processing and so
133 // on. This example reads the data, puts it into an ethernet packet and sends the
134 // packet out via the active output.
135 output(senf::EthernetPacket::create(handle.read()))
138 void outputRequest() {
139 // Called whenever a packet is sent into the input to. Here we just forward it to
140 // the output if it is an EthernetPacket
141 senf::EthernetPacket p (input().find<EthernetPacket>(senf::nothrow));
147 // Called whenever a throttle notification comes in. Here, we just disable the
148 // event (which is stupid since we should just not have disabled autoThrottling on
149 // the route but this is only an example which tries to be simple ...)
153 void onUnthrottle() {
154 // and for unthrottle notifications
161 If your module only has a single input connector, you should call this connector \c
162 input. If it has only a single output connector, you should call it \c output. This allows
163 to setup connections without stating the connector explicitly (see senf::ppi::connect()).
165 \see \ref ppi_modules
177 template <class Source, class Target>
178 Route<Source, Target> & route(Source & source, Target & target);
180 Route<connector::InputConnector, connector::OutputConnector> &
181 route(connector::InputConnector & input, connector::OutputConnector & output);
182 ///< Define flow information
183 /**< Using the route() and noroute() members, the
184 information flow within the module is defined. Routing
185 may be defined between inputs, outputs and events. The
186 routing information is used to perform automatic
187 throttling. The throttling behavior may however be
190 Even if no automatic throttling is desired <em>it is
191 essential to define the flow information for all inputs
192 and outputs</em>. Without flow information important
193 internal state of the module cannot be
194 initialized. This includes, explicitly defining
195 terminal inputs and outputs using noroute. Event
196 routing is optional however.
198 The return value may be used to alter routing
199 parameters like throttling parameters.
201 \param[in] input Data source, object which controls
202 incoming data (connector or event)
203 \param[in] output Data target, object which controls
204 outgoing data (connector or event)
205 \returns Route instance describing this route
206 \see \ref ppi_throttling
207 \note The real implementation is not provided by three
208 overloads but by a single template member */
210 Route<connector::InputConnector, EventDescriptor> &
211 route(connector::InputConnector & input, EventDescriptor & output);
212 ///< Define flow information
213 /**< Route from a connector to an event. Routing from a
214 connector to an event defines the event as the
215 conceptual 'receiver' of the data. This means, the
216 event is controlling the processing of received data
217 packets (Example: Routing from an input to an IOEvent
218 defines, that input data will be processed whenever the
221 This event routing allows to automatically
222 enable/disable the event on throttling notifications.
226 Route<EventDescriptor, connector::OutputConnector> &
227 route(EventDescriptor & input, connector::OutputConnector & output);
228 ///< Define flow information
229 /**< Route from an event to a connector. Routing from an
230 event to a connector defines the event as the
231 conceptual 'source' of the data. This means, the event
232 controls how packets are sent (Example: Routing from an
233 IOEVent to an output defines, that output data will be
234 generated whenever the event is signaled).
236 This event routing allows to automatically
237 enable/disable the event on throttling notifications.
242 void noroute(connector::Connector & connector); ///< Define terminal connectors
243 /**< The noroute() member explicitly declares, that a
244 connector is terminal and does not directly
245 receive/forward data from/to some other
246 connector. <em>It is mandatory to define routing
247 information for terminal connectors</em>.
249 See the route() documentation for more on routing
251 \param[in] connector Terminal connector to declare */
254 template <class Descriptor, class Target>
255 void registerEvent(Descriptor & descriptor, Target target);
257 template <class Target>
258 void registerEvent(EventDescriptor & descriptor, Target target);
259 ///< Register an external event
260 /**< The \a target argument may be either an arbitrary
261 callable object or it may be a member function pointer
262 pointing to a member function of the Module derived
263 classed. The handler may \e optionally take an Argument
264 of type <tt>Descriptor::Event const &</tt>. This object
265 allows to access detailed information on the event
268 The \a descriptor describes the event to signal like a
269 timer event or some type of I/O event on a file
270 descriptor or socket.
272 \param[in] target The handler to call whenever the
274 \param[in] descriptor The type of event to register
275 \note The real implementation has the second arguments
276 type as an additional template parameter. */
279 ClockService::clock_type time() const; ///< Time-stamp of the currently processing event
280 /**< If available, this returns the scheduled time of the
283 ClockService::clock_type now() const; ///< Current time of the currently processing event
286 virtual void macro_SENF_PPI_MODULE_missing() = 0;
290 virtual void init(); ///< Called just before the network is run
298 EventManager & eventManager() const;
299 ModuleManager & moduleManager() const;
301 void registerConnector(connector::Connector & connector);
302 RouteBase & addRoute(std::auto_ptr<RouteBase> route);
304 typedef std::vector<connector::Connector *> ConnectorRegistry;
305 ConnectorRegistry connectorRegistry_;
307 typedef boost::ptr_vector<RouteBase> RouteInfoBase;
308 RouteInfoBase routes_;
310 template <class Source, class Target>
311 friend class detail::RouteHelper;
312 friend class senf::ppi::ModuleManager;
315 /** \brief Define PPI Module
317 Every module must begin by using this macro.
319 \see senf::ppi::module::Module
321 # define SENF_PPI_MODULE(name) \
323 ~ name() { destroy(); } \
324 void macro_SENF_PPI_MODULE_missing() {} \
329 ///////////////////////////////hh.e////////////////////////////////////////
330 #include "Module.cci"
332 //#include "Module.cti"
339 // c-file-style: "senf"
340 // indent-tabs-mode: nil
341 // ispell-local-dictionary: "american"
342 // compile-command: "scons -u test"
343 // comment-column: 40