#include "PingPong.h" #include "ariba/utility/configuration/Configuration.h" using ariba::utility::Configuration; using namespace ariba; namespace ariba { namespace application { namespace pingpong { // logging use_logging_cpp( PingPong ); // the service that the pingpong wants to use ServiceID PingPong::PINGPONG_ID = ServiceID( 111 ); // construction PingPong::PingPong() : pingId( 0 ) { Timer::setInterval( 5000 ); } // destruction PingPong::~PingPong() { } // implementation of the startup interface void PingPong::startup() { logging_info( "starting up PingPong service ... " ); // create ariba module logging_debug( "creating ariba underlay module ... " ); ariba = new AribaModule(); // get the configuration object Configuration& config = Configuration::instance(); // generate spovnet name Name spovnetName("pingpong"); // get initiator flag this->isInitiator = Configuration::instance().read("node.initiator"); // get node name Name nodeName = Name::UNSPECIFIED; if (config.exists("node.name")) nodeName = config.read ("node.name"); // configure ariba module if (config.exists("ariba.ip.addr")) ariba->setProperty("ip.addr", config.read("ariba.ip.addr")); if (config.exists("ariba.tcp.port")) ariba->setProperty("tcp.port", config.read("ariba.tcp.port")); if (config.exists("ariba.udp.port")) ariba->setProperty("udp.port", config.read("ariba.udp.port")); if (config.exists("ariba.bootstrap.hints")) ariba->setProperty("bootstrap.hints", config.read("ariba.bootstrap.hints")); // start ariba module ariba->start(); // create node and join node = new Node( *ariba, nodeName ); // start node module node->start(); // initiate or join the spovnet if (!isInitiator) node->join(spovnetName); else node->initiate(spovnetName); // bind communication and node listener node->bind( this ); /*NodeListener*/ node->bind( this, PingPong::PINGPONG_ID); /*CommunicationListener*/ // start the ping timer. if we are not // the initiator this will happen in onJoinCompleted if( isInitiator ) Timer::start(); // ping pong started up... logging_info( "pingpong starting up with" << " [spovnetid " << node->getSpoVNetId().toString() << "]" << " and [nodeid " << node->getNodeId().toString() << "]" ); } // implementation of the startup interface void PingPong::shutdown() { logging_info( "pingpong service starting shutdown sequence ..." ); // stop timer Timer::stop(); // unbind communication and node listener node->unbind( this ); /*NodeListener*/ node->unbind( this, PingPong::PINGPONG_ID ); /*CommunicationListener*/ // leave spovnet node->leave(); // stop the ariba module ariba->stop(); // delete node and ariba module delete node; delete ariba; // now we are completely shut down logging_info( "pingpong service shut down" ); } // node listener interface void PingPong::onJoinCompleted( const SpoVNetID& vid ) { logging_error( "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX pingpong node join completed, spovnetid=" << vid.toString() ); // start the timer to ping every second Timer::start(); } void PingPong::onJoinFailed( const SpoVNetID& vid ) { logging_error("pingpong node join failed, spovnetid=" << vid.toString() ); } void PingPong::onLeaveCompleted( const SpoVNetID& vid ){ logging_info("pingpong node leave completed, spovnetid=" << vid.toString() ); } void PingPong::onLeaveFailed( const SpoVNetID& vid ){ logging_error("pingpong node leave failed, spovnetid=" << vid.toString() ); } // timer event void PingPong::eventFunction() { // we ping all nodes that are known in the overlay structure // this can be all nodes (OneHop) overlay or just some neighbors // in case of a Chord or Kademlia structure logging_info( "pinging overlay neighbors with ping id " << ++pingId ); PingPongMessage pingmsg( pingId ); //----------------------------------------------------------------------- // Option 1: get all neighboring nodes and send the message to each //----------------------------------------------------------------------- vector nodes = node->getNeighborNodes(); BOOST_FOREACH( NodeID nid, nodes ){ node->sendMessage( pingmsg, nid, PingPong::PINGPONG_ID ); } //----------------------------------------------------------------------- // Option 2: send a "broadcast message" that actually does the same thing // internally, gets all neighboring nodes and sends the message //----------------------------------------------------------------------- // node->sendBroadcastMessage( pingmsg, PingPong::PINGPONG_ID ); } // communication listener bool PingPong::onLinkRequest(const NodeID& remote, const DataMessage& msg) { return false; } void PingPong::onMessage(const DataMessage& msg, const NodeID& remote, const LinkID& lnk) { PingPongMessage* pingmsg = msg.getMessage()->convert (); logging_info( "received ping message on link " << lnk.toString() << " from node " << remote.toString() << ": " << pingmsg->info() ); } void PingPong::onLinkUp(const LinkID& lnk, const NodeID& remote){ logging_info( "received link-up event for link " << lnk.toString() << " and node " << remote.toString() ); } void PingPong::onLinkDown(const LinkID& lnk, const NodeID& remote){ logging_info( "received link-down event for link " << lnk.toString() << " and node " << remote.toString() ); } void PingPong::onLinkChanged(const LinkID& lnk, const NodeID& remote){ logging_info( "received link-changed event for link " << lnk.toString() << " and node " << remote.toString() ); } void PingPong::onLinkFail(const LinkID& lnk, const NodeID& remote){ logging_info( "received link-failed event for link " << lnk.toString() << " and node " << remote.toString() ); } void PingPong::onLinkQoSChanged(const LinkID& lnk, const NodeID& remote, const LinkProperties& prop){ logging_info( "received link-qos-changed event for link " << lnk.toString() << " and node " << remote.toString() << " with link properties " << prop.toString() ); } void PingPong::onMessageSent(seqnum_t seq_num, bool failed, const DataMessage& msg ){ logging_info( "received message sent event for seqnum " << seq_num << " with result " << failed ); } }}} // namespace ariba, application, pingpong