4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
19 // The Original Code is Fraunhofer FOKUS code.
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief Connectors non-inline non-template implementation */
31 #include "Connectors.hh"
32 #include "Connectors.ih"
35 #include "ModuleManager.hh"
36 #include <senf/Utils/Console/ParsedCommand.hh>
38 //#include "Connectors.mpp"
40 //-/////////////////////////////////////////////////////////////////////////////////////////////////
42 //-/////////////////////////////////////////////////////////////////////////////////////////////////
43 // senf::ppi::connector::Connector
45 prefix_ senf::ppi::connector::Connector::~Connector()
48 Connector & peer (*peer_);
50 if (! peer.initializationScheduled())
51 peer.enqueueInitializable();
52 peer.v_disconnected();
56 prefix_ void senf::ppi::connector::Connector::connect(Connector & target)
58 // The connector is not registered -> route() or noroute() statement missing
60 "senf::ppi::connector::Connector::connect(): (source) "
61 "Missing route() or noroute()" );
62 // The connector is already connected
64 "senf::ppi::connector::Connector::connect(): (source) "
65 "duplicate connection" );
66 // The target connector is not registered -> route() or noroute() statement missing
67 SENF_ASSERT( target.module_,
68 "senf::ppi::connector::Connector::connect(): (target) "
69 "Missing route() or noroute()" );
70 // The target connector is already connected
71 SENF_ASSERT( ! target.peer_,
72 "senf::ppi::connector::Connector::connect(): (target) "
73 "duplicate connection" );
75 if (! (packetTypeID() == typeid(void) ||
76 target.packetTypeID() == typeid(void) ||
77 packetTypeID() == target.packetTypeID()) )
78 throw IncompatibleConnectorsException()
79 << ": " << prettyName(packetTypeID())
80 << " [in module " << prettyName(typeid(*module_)) << "] "
81 << ", " << prettyName(target.packetTypeID())
82 << " [in module " << prettyName(typeid(*target.module_)) << "]";
87 if (! initializationScheduled())
88 enqueueInitializable();
89 if (! peer().initializationScheduled())
90 peer().enqueueInitializable();
97 senf::ppi::connector::Connector::TraceState senf::ppi::connector::Connector::traceState_ (
98 senf::ppi::connector::Connector::NO_TRACING);
100 prefix_ void senf::ppi::connector::Connector::trace(Packet const & p, char const * label)
102 if (traceState_ == NO_TRACING)
105 std::string type (prettyName(p.typeId().id()));
106 log << "PPI packet trace: " << label << " 0x" << std::hex << p.id() << " "
107 << type.substr(21, type.size()-22) << " on " << & module() << " "
108 << prettyName(typeid(module())) << " connector 0x" << this << "\n";
109 if (traceState_ == TRACE_CONTENTS)
114 prefix_ void senf::ppi::connector::Connector::throttleTrace(char const * label,
117 if (traceState_ == NO_TRACING)
120 log << "PPI throttling trace: " << label << " " << type << " on " << & module()
121 << " " << prettyName(typeid(module())) << " connector 0x" << this << "\n";
125 namespace senf { namespace ppi { namespace connector {
127 SENF_CONSOLE_REGISTER_ENUM_MEMBER(
128 Connector, TraceState, (NO_TRACING)(TRACE_IDS)(TRACE_CONTENTS) );
134 struct ConsoleRegister
139 ConsoleRegister::ConsoleRegister()
141 #ifndef SENF_PPI_NOTRACE
142 senf::ppi::ModuleManager::instance().consoleDir()
143 .add("tracing", senf::console::factory::Command(
144 SENF_FNP(senf::ppi::connector::Connector::TraceState,
145 senf::ppi::connector::Connector::tracing, ()))
146 .doc("Log every packet sent or received by any module.\n"
147 "There are three different tracing levels:\n"
149 " NO_TRACING don't output any tracing information\n"
150 " TRACE_IDS trace packet id's but do not show packet contents\n"
151 " TRACE_CONTENTS trace complete packet contents\n"
153 "A log message is generated whenever the packet traverses a connector. The\n"
154 "TRACE_IDS log message has the following format:\n"
156 " PPI packet trace: <direction> <packet-id> <packet-type>\n"
157 " on <module-id> <module-type> connector <connector-id>\n"
158 " PPI throttling trace: <direction> <throttle-msg>\n"
159 " on <module-id> <module-type> connector <connector-id>\n"
163 " direction 'IN' for packets/throttle notifications entering the module,\n"
164 " 'OUT' for packets/throttle notifications leaving it\n"
165 " packet-id Numeric unique packet id. This value is unique for packets\n"
166 " alive at the same time, packets at different times may (and\n"
167 " will) share id's\n"
168 " packet-type The type of the packet header\n"
169 " module-id Unique module id\n"
170 " module-type Type of the module the packet is sent to/from\n"
171 " connector-id Unique connector id\n"
172 " throttle-msg Type of throttling event\n")
175 senf::ppi::ModuleManager::instance().consoleDir()
176 .add("tracing", senf::console::factory::Command(
177 SENF_FNP(void, senf::ppi::connector::Connector::tracing,
178 (senf::ppi::connector::Connector::TraceState)))
179 .arg("state", "new tracing state")
184 ConsoleRegister consoleRegister;
188 prefix_ void senf::ppi::connector::Connector::disconnect()
190 // Cannot disconnected a non-connected connector
192 "senf::ppi::connector::Connector::disconnect(): Not connected" );
194 Connector & peer (*peer_);
198 if (! initializationScheduled())
199 enqueueInitializable();
200 if (! peer.initializationScheduled())
201 peer.enqueueInitializable();
204 peer.v_disconnected();
207 prefix_ std::type_info const & senf::ppi::connector::Connector::packetTypeID()
212 prefix_ void senf::ppi::connector::Connector::unregisterConnector()
215 module_->unregisterConnector(*this);
218 prefix_ void senf::ppi::connector::Connector::setModule(module::Module & module)
223 prefix_ void senf::ppi::connector::Connector::v_disconnected()
226 prefix_ void senf::ppi::connector::Connector::v_connected()
229 //-/////////////////////////////////////////////////////////////////////////////////////////////////
230 // senf::ppi::connector::PassiveConnector
232 prefix_ senf::ppi::connector::PassiveConnector::~PassiveConnector()
234 // Must be here and NOT in base so it is called before destructing the routes_ member
235 unregisterConnector();
238 prefix_ void senf::ppi::connector::PassiveConnector::v_disconnected()
240 Connector::v_disconnected();
244 prefix_ void senf::ppi::connector::PassiveConnector::v_connected()
246 Connector::v_connected();
247 peer_ = & dynamic_cast<ActiveConnector&>(Connector::peer());
250 //-/////////////////////////////////////////////////////////////////////////////////////////////////
253 prefix_ void senf::ppi::connector::PassiveConnector::v_init()
255 Routes::const_iterator i (routes_.begin());
256 Routes::const_iterator const i_end (routes_.end());
257 for (; i != i_end; ++i)
258 if ((*i)->throttled())
261 remoteThrottled_ = false;
268 prefix_ void senf::ppi::connector::PassiveConnector::registerRoute(ForwardingRoute & route)
270 routes_.push_back(&route);
273 prefix_ void senf::ppi::connector::PassiveConnector::unregisterRoute(ForwardingRoute & route)
275 Routes::iterator i (std::find(routes_.begin(), routes_.end(), &route));
276 if (i != routes_.end())
280 prefix_ void senf::ppi::connector::PassiveConnector::v_unthrottleEvent()
283 prefix_ void senf::ppi::connector::PassiveConnector::notifyUnthrottle()
285 if (std::find_if(routes_.begin(), routes_.end(),
286 boost::bind(&ForwardingRoute::throttled, _1)) == routes_.end()) {
287 remoteThrottled_ = false;
288 if (!nativeThrottled_)
291 SENF_PPI_THROTTLE_TRACE("OUT", "not forwarding unthrottle event");
294 //-/////////////////////////////////////////////////////////////////////////////////////////////////
295 // senf::ppi::connector::ActiveConnector
297 prefix_ senf::ppi::connector::ActiveConnector::~ActiveConnector()
299 // Must be here and NOT in base so it is called before destructing the routes_ member
300 unregisterConnector();
303 prefix_ void senf::ppi::connector::ActiveConnector::v_disconnected()
305 Connector::v_disconnected();
309 prefix_ void senf::ppi::connector::ActiveConnector::v_connected()
311 Connector::v_connected();
312 peer_ = & dynamic_cast<PassiveConnector&>(Connector::peer());
315 //-/////////////////////////////////////////////////////////////////////////////////////////////////
318 prefix_ void senf::ppi::connector::ActiveConnector::v_init()
324 prefix_ void senf::ppi::connector::ActiveConnector::notifyThrottle()
326 SENF_PPI_THROTTLE_TRACE("IN ", "throttle");
329 if (throttleCallback_)
331 NotifyRoutes::const_iterator i (notifyRoutes_.begin());
332 NotifyRoutes::const_iterator const i_end (notifyRoutes_.end());
333 for (; i != i_end; ++i)
334 (*i)->notifyThrottle();
338 prefix_ void senf::ppi::connector::ActiveConnector::notifyUnthrottle()
340 SENF_PPI_THROTTLE_TRACE("IN ", "unthrottle");
343 if (unthrottleCallback_)
344 unthrottleCallback_();
345 NotifyRoutes::const_iterator i (notifyRoutes_.begin());
346 NotifyRoutes::const_iterator const i_end (notifyRoutes_.end());
347 for (; i != i_end; ++i)
348 (*i)->notifyUnthrottle();
352 prefix_ void senf::ppi::connector::ActiveConnector::registerRoute(ForwardingRoute & route)
354 notifyRoutes_.push_back(&route);
357 prefix_ void senf::ppi::connector::ActiveConnector::unregisterRoute(ForwardingRoute & route)
359 NotifyRoutes::iterator i (std::find(notifyRoutes_.begin(), notifyRoutes_.end(), &route));
360 if (i != notifyRoutes_.end())
361 notifyRoutes_.erase(i);
364 //-/////////////////////////////////////////////////////////////////////////////////////////////////
365 // senf::ppi::connector::InputConnector
367 prefix_ senf::Packet senf::ppi::connector::InputConnector::operator()()
372 Packet p ( queue_.back());
375 SENF_PPI_TRACE(p, "IN ");
378 SENF_PPI_TRACE(Packet(), "IN ");
383 prefix_ void senf::ppi::connector::InputConnector::v_disconnected()
385 Connector::v_disconnected();
389 prefix_ void senf::ppi::connector::InputConnector::v_connected()
391 Connector::v_connected();
392 peer_ = & dynamic_cast<OutputConnector&>(Connector::peer());
395 //-/////////////////////////////////////////////////////////////////////////////////////////////////
398 prefix_ void senf::ppi::connector::InputConnector::v_requestEvent()
401 prefix_ void senf::ppi::connector::InputConnector::v_enqueueEvent()
404 prefix_ void senf::ppi::connector::InputConnector::v_dequeueEvent()
407 //-/////////////////////////////////////////////////////////////////////////////////////////////////
408 // senf::ppi::connector::OutputConnector
410 prefix_ void senf::ppi::connector::OutputConnector::v_disconnected()
412 Connector::v_disconnected();
416 prefix_ void senf::ppi::connector::OutputConnector::v_connected()
418 Connector::v_connected();
419 peer_ = & dynamic_cast<InputConnector&>(Connector::peer());
422 //-/////////////////////////////////////////////////////////////////////////////////////////////////
423 // senf::ppi::connector::GenericActiveInput
425 //-/////////////////////////////////////////////////////////////////////////////////////////////////
428 prefix_ void senf::ppi::connector::GenericActiveInput::v_requestEvent()
433 //-/////////////////////////////////////////////////////////////////////////////////////////////////
434 // senf::ppi::connector::GenericPassiveInput
436 prefix_ void senf::ppi::connector::GenericPassiveInput::v_disconnected()
438 PassiveConnector::v_disconnected();
439 InputConnector::v_disconnected();
443 prefix_ void senf::ppi::connector::GenericPassiveInput::v_connected()
445 PassiveConnector::v_connected();
446 InputConnector::v_connected();
447 peer_ = & dynamic_cast<GenericActiveOutput&>(Connector::peer());
450 //-/////////////////////////////////////////////////////////////////////////////////////////////////
453 prefix_ void senf::ppi::connector::GenericPassiveInput::v_enqueueEvent()
457 qdisc_->update(*this, QueueingDiscipline::ENQUEUE);
460 prefix_ void senf::ppi::connector::GenericPassiveInput::v_dequeueEvent()
463 qdisc_->update(*this, QueueingDiscipline::DEQUEUE);
466 prefix_ void senf::ppi::connector::GenericPassiveInput::qdisc(QueueingDiscipline::None_t)
471 prefix_ void senf::ppi::connector::GenericPassiveInput::v_unthrottleEvent()
473 size_type n (queueSize());
476 size_type nn (queueSize());
483 //-/////////////////////////////////////////////////////////////////////////////////////////////////
484 // senf::ppi::connector::GenericPassiveOutput
486 prefix_ void senf::ppi::connector::GenericPassiveOutput::v_disconnected()
488 PassiveConnector::v_disconnected();
489 OutputConnector::v_disconnected();
493 prefix_ void senf::ppi::connector::GenericPassiveOutput::v_connected()
495 PassiveConnector::v_connected();
496 OutputConnector::v_connected();
497 peer_ = & dynamic_cast<GenericActiveInput&>(Connector::peer());
500 //-/////////////////////////////////////////////////////////////////////////////////////////////////
501 // senf::ppi::connector::GenericActiveInput
503 prefix_ void senf::ppi::connector::GenericActiveInput::v_disconnected()
505 ActiveConnector::v_disconnected();
506 InputConnector::v_disconnected();
510 prefix_ void senf::ppi::connector::GenericActiveInput::v_connected()
512 ActiveConnector::v_connected();
513 InputConnector::v_connected();
514 peer_ = & dynamic_cast<GenericPassiveOutput&>(Connector::peer());
517 //-/////////////////////////////////////////////////////////////////////////////////////////////////
518 // senf::ppi::connector::GenericActiveOutput
520 prefix_ void senf::ppi::connector::GenericActiveOutput::v_disconnected()
522 ActiveConnector::v_disconnected();
523 OutputConnector::v_disconnected();
527 prefix_ void senf::ppi::connector::GenericActiveOutput::v_connected()
529 ActiveConnector::v_connected();
530 OutputConnector::v_connected();
531 peer_ = & dynamic_cast<GenericPassiveInput&>(Connector::peer());
535 //-/////////////////////////////////////////////////////////////////////////////////////////////////
537 //#include "Connectors.mpp"
543 // comment-column: 40
544 // c-file-style: "senf"
545 // indent-tabs-mode: nil
546 // ispell-local-dictionary: "american"
547 // compile-command: "scons -u test"