mac address and allows to pass a senf::MACAddress value as routing key directly:
\code
- senf::ppi::module::AnnotationRouter router;
+ senf::ppi::module::AnnotationRouter<TargetInterface> router;
senf::ppi::connect(router, target1, senf::MACAddress::from_string("00:1a:2b:04:06:08"));
\endcode
PROJECT_NAME = libPPI
GENERATE_TAGFILE = doc/PPI.tag
-RECURSIVE = Yes
+RECURSIVE = No
SHOW_DIRECTORIES = Yes
-EXCLUDE = NetEmu
+INPUT = . detail
TAGFILES = \
"$(TOPDIR)/Scheduler/doc/Scheduler.tag" \
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
- \brief Splitters non-inline non-template implementation */
+ \brief Duplicators non-inline non-template implementation */
-#include "Splitters.hh"
-//#include "Splitters.ih"
+#include "Duplicators.hh"
+//#include "Duplicators.ih"
// Custom includes
-//#include "Splitters.mpp"
+//#include "Duplicators.mpp"
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
prefix_ senf::ppi::connector::ActiveOutput<> &
-senf::ppi::module::ActiveSplitter::newOutput()
+senf::ppi::module::ActiveDuplicator::newOutput()
{
outputs_.push_back(new connector::ActiveOutput<>());
connector::ActiveOutput<> & output (outputs_.back());
return output;
}
-prefix_ void senf::ppi::module::ActiveSplitter::request()
+prefix_ void senf::ppi::module::ActiveDuplicator::request()
{
Packet p (input());
Outputs::iterator i (outputs_.begin());
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
-//#include "Splitters.mpp"
+//#include "Duplicators.mpp"
\f
// Local Variables:
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
- \brief Splitters inline non-template implementation */
+ \brief Duplicators inline non-template implementation */
-//#include "Splitters.ih"
+//#include "Duplicators.ih"
// Custom includes
///////////////////////////////cci.p///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
-// senf::ppi::module::ActiveSplitter
+// senf::ppi::module::ActiveDuplicator
-prefix_ senf::ppi::module::ActiveSplitter::ActiveSplitter()
+prefix_ senf::ppi::module::ActiveDuplicator::ActiveDuplicator()
{
noroute(input);
- input.onRequest(&ActiveSplitter::request);
+ input.onRequest(&ActiveDuplicator::request);
}
///////////////////////////////cci.e///////////////////////////////////////
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
- \brief Splitters inline template implementation */
+ \brief Duplicators inline template implementation */
-//#include "Splitters.ih"
+//#include "Duplicators.ih"
// Custom includes
#include "Setup.hh"
template <class Target>
prefix_ senf::ppi::connector::GenericActiveOutput &
-senf::ppi::connect(module::ActiveSplitter & source, Target & target)
+senf::ppi::connect(module::ActiveDuplicator & source, Target & target)
{
return source.connect(target);
}
template <class Target>
prefix_ senf::ppi::connector::GenericActiveOutput &
-senf::ppi::module::ActiveSplitter::connect(Target & target)
+senf::ppi::module::ActiveDuplicator::connect(Target & target)
{
connector::GenericActiveOutput & output (newOutput());
ppi::connect(output, target);
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
- \brief Splitters public header */
+ \brief Duplicators public header */
-#ifndef HH_SENF_PPI_Splitters_
-#define HH_SENF_PPI_Splitters_ 1
+#ifndef HH_SENF_PPI_Duplicators_
+#define HH_SENF_PPI_Duplicators_ 1
// Custom includes
#include <boost/ptr_container/ptr_vector.hpp>
#include "Connectors.hh"
#include "Module.hh"
-//#include "Splitters.mpp"
+//#include "Duplicators.mpp"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
#ifndef DOXYGEN
template <class Target>
- connector::GenericActiveOutput & connect(module::ActiveSplitter & source, Target & target);
+ connector::GenericActiveOutput & connect(module::ActiveDuplicator & source, Target & target);
#endif
namespace module {
- class ActiveSplitter
+ /** \brief Copy every incoming packet to each output
+
+ ActiveDuplicator will take every received packet and push it out to each connected output.
+
+ Since ActiveDuplicator allows any number of incoming packet streams, the input connectors
+ are dynamically managed. A special senf::ppi::connect() overload is used to dynamically
+ create the needed input connectors. This hides this extra functionality from the user.
+ \code
+ senf::ppi::module::ActiveDuplicator dup;
+
+ senf::ppi::connect(sourceModule, dup);
+ senf::ppi::connect(dup, targetModule1);
+ senf::ppi::connect(dup, targetModule2.some_input);
+ \endcode
+
+ \ingroup routing_modules
+ */
+ class ActiveDuplicator
: public Module
{
- SENF_PPI_MODULE(ActiveSplitter);
+ SENF_PPI_MODULE(ActiveDuplicator);
public:
connector::PassiveInput<> input;
- ActiveSplitter();
+ ActiveDuplicator();
private:
connector::ActiveOutput<> & newOutput();
///////////////////////////////hh.e////////////////////////////////////////
-#include "Splitters.cci"
-//#include "Splitters.ct"
-#include "Splitters.cti"
+#include "Duplicators.cci"
+//#include "Duplicators.ct"
+#include "Duplicators.cti"
#endif
\f
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
- \brief Splitters.test unit tests */
+ \brief Duplicators.test unit tests */
-//#include "Splitters.test.hh"
-//#include "Splitters.test.ih"
+//#include "Duplicators.test.hh"
+//#include "Duplicators.test.ih"
// Custom includes
-#include "Splitters.hh"
+#include "Duplicators.hh"
#include "DebugModules.hh"
#include "Setup.hh"
#include "../Packets/Packets.hh"
namespace module = ppi::module;
namespace debug = module::debug;
-BOOST_AUTO_UNIT_TEST(activeSplitter)
+BOOST_AUTO_UNIT_TEST(activeDuplicator)
{
debug::ActiveSource source;
- module::ActiveSplitter splitter;
+ module::ActiveDuplicator duplicator;
debug::PassiveSink sink1;
debug::PassiveSink sink2;
- ppi::connect(source, splitter);
- ppi::connect(splitter, sink1);
- ppi::connect(splitter, sink2);
+ ppi::connect(source, duplicator);
+ ppi::connect(duplicator, sink1);
+ ppi::connect(duplicator, sink2);
ppi::init();
senf::Packet p (senf::DataPacket::create());
\li \ref io_modules receive external data or forward packets out of the PPI
\li \ref routing_modules forward packets within the network
\li \ref adapter_modules are used to connect incompatible connectors to each other
-
- \todo Implement Spliters: PassiveSplitter, PrioritySplitter, CloneSplitter
*/
/** \defgroup io_modules Source/Sink Modules
namespace ppi {
namespace module {
+ /** \brief Base class providing simple monitor module support
+
+ A monitor module is a module which needs information about traversing packets but does not
+ really act on the packets. Because of this, it is \e optional to connect the output: If the
+ output is not connected, the packets will be silently dropped.
+
+ This allows to add monitor modules either into an existing chain or add them using an
+ ActiveDuplicator.
+
+ To write a monitor module, derive from senf::ppi::module::MonitorModule instead of
+ senf::ppi::module and implement v_handlePacket():
+
+ \code
+ class CountPackets
+ : public senf::ppi::module::MonitorModule<>
+ {
+ SENF_PPI_MODULE(CountPackets);
+ public:
+ SomeMonitor() : counter_ (0u) {}
+
+ private:
+ virtual void v_handlePacket(Packet const & p)
+ { ++ counter_; }
+
+ unsigned counter_;
+ };
+ \endcode
+
+ You may of course add events (or even further connectors besides \c input and \c output
+ provided by MonitorModule) to the module.
+
+ \tparam PacketType type of packet expected on input and sent on output. This is also the
+ type of the v_handlePacket() argument.
+ */
template <class PacketType=Packet>
class MonitorModule : public Module
{
protected:
MonitorModule();
- virtual void v_handlePacket(PacketType const & p) = 0;
+ virtual void v_handlePacket(PacketType const & p) = 0; ///< Called for each packet
private:
void request();
}
class PassiveJoin;
class PriorityJoin;
- class ActiveSplitter;
+ class ActiveDuplicator;
}
namespace connector {