Index: sample/pingpong/PingPong.cpp
===================================================================
--- sample/pingpong/PingPong.cpp	(revision 12775)
+++ sample/pingpong/PingPong.cpp	(revision 2378)
@@ -1,221 +1,173 @@
 #include "PingPong.h"
-#include <boost/property_tree/ptree.hpp>
-#include <boost/property_tree/json_parser.hpp>
 
-using namespace ariba;
+#include "ariba/interface/UnderlayAbstraction.h"
 
 namespace ariba {
-namespace application {
+namespace appplication {
 namespace pingpong {
 
-// logging
-use_logging_cpp( PingPong );
+use_logging_cpp(PingPong);
+ServiceID PingPong::PINGPONG_ID = ServiceID(111);
 
-// the service that the pingpong wants to use
-ServiceID PingPong::PINGPONG_SERVICEID = ServiceID( 111 );
-
-// construction
-PingPong::PingPong( string config)  :
-        node(),
-        counter( 0 ),
-        pingId( 0 ),
-        config_file(config)
-{
-	Timer::setInterval( 5000 );
+PingPong::PingPong() : pingid( 0 ) {
 }
 
-// destruction
-PingPong::~PingPong() {
+PingPong::~PingPong(){
 }
 
-// implementation of the startup interface
-void PingPong::startup()
-{
-    using boost::property_tree::ptree;
-    using boost::property_tree::json_parser::read_json;
-    
-	// set up logging
-	logging_rootlevel_debug();
-	logging_classlevel_debug(PingPong);
-
-	logging_info( "[PINGPONG]\t starting up PingPong service ... " );
-
-    // read config
-    ptree config;
-    try
-    {
-        read_json(config_file, config);
-    }
-    catch ( exception& e )
-    {
-        logging_warn("ERROR: Failed to read config file Â»" << config_file << "Â«: ");
-        logging_warn(e.what());
-        logging_warn("---> Using fallback config.");
-        
-        config.put("ariba.spovnet_name", "pingpong");
-    }
-    
-    // use node name also in the application
-    name = config.get("ariba.node_name", "NO_NAME");
-    
-	// bind communication and node listener
-	node.bind( this );                              /*NodeListener*/
-	node.bind( this, PingPong::PINGPONG_SERVICEID); /*CommunicationListener*/
-
-    // connecting
-    logging_debug( "connecting ... " );
-
-	node.connect(config.get_child("ariba"));
-
-	// ping pong started up...
-	logging_info( "[PINGPONG]\t pingpong starting up with"
-			<< " [spovnetid " << node.getSpoVNetId().toString() << "]"
-			<< " and [nodeid " << node.getNodeId().toString() << "]" );
+void PingPong::setMode(bool startingNode){
+	startping = startingNode;
 }
 
-// implementation of the startup interface
-void PingPong::shutdown() {
+void PingPong::startup(){
+	abstraction = new UnderlayAbstraction();
 
-	logging_info( "[PINGPONG]\t pingpong service starting shutdown sequence ..." );
+	logging_info( "starting up PingPong service ... " );
 
-	// stop timer
+	SpoVNetID spovnetid (Identifier(5000));
+
+	setMode( !Configuration::instance().read<bool>("GENERAL_Initiator") );
+
+	NodeID nodeid = (Configuration::instance().exists("BASE_nodeid") ?
+			NodeID(Identifier(Configuration::instance().read<unsigned long>("BASE_nodeid"))) :
+			NodeID::UNSPECIFIED);
+
+	IPv4Locator* locallocator = (Configuration::instance().exists("BASE_localLocator") ?
+					&(IPv4Locator::fromString(Configuration::instance().read<string>("BASE_localLocator"))) :
+					NULL);
+
+	uint16_t localport = Configuration::instance().exists("BASE_port") ?
+				Configuration::instance().read<uint16_t>("BASE_port") :
+				ARIBA_DEFAULT_PORT;
+
+	if( !startping ){
+
+		context = abstraction->createSpoVNet(
+			spovnetid, nodeid, locallocator, localport );
+
+	} else {
+
+		if( !Configuration::instance().exists("BASE_bootstrapIP")){
+			logging_fatal( "no bootstrap address found" );
+			return;
+		}
+
+		logging_info( "using bootstrap point " <<
+			Configuration::instance().read<string>("BASE_bootstrapIP") );
+
+		EndpointDescriptor bootstrap(
+		new IPv4Locator(IPv4Locator::fromString(
+			Configuration::instance().read<string>("BASE_bootstrapIP"))));
+
+		context = abstraction->joinSpoVNet(
+			spovnetid, bootstrap, nodeid, locallocator, localport );
+
+	}
+
+	overlay = &context->getOverlay();
+	overlay->bind( this, PingPong::PINGPONG_ID );
+
+	logging_info( "PingPong started up" );
+
+	// trigger the creation of the pathload measurement module
+	//PathloadMeasurement::instance( overlay );
+}
+
+void PingPong::shutdown(){
+	logging_info( "shutting down PingPong service ..." );
+
+	overlay->unbind( this, PingPong::PINGPONG_ID );
 	Timer::stop();
 
-	// leave spovnet
-	node.leave();
+	if( !startping ) abstraction->destroySpoVNet( context );
+	else             abstraction->leaveSpoVNet( context );
 
-	// unbind communication and node listener
-	node.unbind( this );                               /*NodeListener*/
-	node.unbind( this, PingPong::PINGPONG_SERVICEID ); /*CommunicationListener*/
+	delete abstraction;
 
-	// now we are completely shut down
-	logging_info( "pingpong service shut down" );
+	logging_info( "PingPong service shut down" );
 }
 
-// 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
-	// NOTE: Currently ariba only supports the Chord overlay.
+bool PingPong::receiveMessage(const Message* message, const LinkID& link, const NodeID& node){
 
-	// In this sample we use auto-links: we just send out our message
-	// to the node and the link is established automatically. for more
-	// control we would use the node->establishLink function to create
-	// a link and start using the link in the CommunicationListener::onLinkUp
-	// function that is implemented further down in PingPong::onLinkUp
-	
-	// NOTE: This example still uses the old deprecated ariba::message messages 
-	//   with the ariba built-in serialization. 
-	// For future applications please use the new reboost::message_t messages. 
-	//   Data is stored in high efficient zero-copy buffers of type 
-	//   reboost::shared_buffer_t. These buffers hold plain data, so you have to 
-	//   serialize the data "on your own".
-	// We recommend third-party serialization libraries like:
-	//   - Protocol Buffers (http://en.wikipedia.org/wiki/Protocol_Buffers)
-	//   - MessagePack      (http://en.wikipedia.org/wiki/MessagePack)
+	PingPongMessage* incoming = ((Message*)message)->decapsulate<PingPongMessage>();
 
-	
-	// don't do anything if we have no neighbors
-	if ( node.getNeighborNodes().size() == 0)
-    {
-        logging_info( "[PINGPONG]\t +++ no neighbors +++" );
-        return;
-    }
-    
-    
-	pingId++;
-    logging_info( "\n|||||||||| >>>>>>>>>>\n"
-	        << "[PINGPONG]\t PINGING overlay neighbors with ping id " << pingId );
-	PingPongMessage pingmsg( pingId, name );
-	
-	//-----------------------------------------------------------------------
-	// Option 1: get all neighboring nodes and send the message to each
-	//-----------------------------------------------------------------------
-	counter++;
-	if (counter<0 || counter>4) {
-		counter = 0;
-		string s;
-		for (int i=0; i<names.size();i++) {
-			if (i!=0) s+= ", ";
-			s = s+names[i];
-		}
-		logging_info("[PINGPONG]\t ----> I am " << name << " and I know " << s);
-		names.clear();
-	}
+	logging_info( "received ping message on link " << link.toString() <<
+				 " from node with id " << (int)incoming->getid());
 
-	vector<NodeID> nodes = node.getNeighborNodes();
-	BOOST_FOREACH( NodeID nid, nodes ){
-		logging_info( "[PINGPONG]\t sending ping message to " << nid.toString() );
-		node.sendMessage( pingmsg, nid, PingPong::PINGPONG_SERVICEID );
-	}
-
-	//-----------------------------------------------------------------------
-	// 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_SERVICEID );
+// 	if( ((int)incoming->getid() % 5) == 0 )
+// 		PathloadMeasurement::instance().measure( node, this );
 }
 
-void PingPong::onJoinCompleted( const SpoVNetID& vid ) {
-	logging_info( "pingpong node join completed, spovnetid=" << vid.toString() );
+void PingPong::eventFunction(){
 
-	// start the timer to ping every second
-	Timer::start();
+	logging_info( "pinging our remote nodes" );
+
+	RemoteNodes::iterator i = remoteNodes.begin();
+	RemoteNodes::iterator iend = remoteNodes.end();
+
+	pingid++;
+
+	for( ; i != iend; i++ ){
+		logging_info( "     -> pinging " << i->first );
+
+		PingPongMessage pingmsg( pingid );
+		overlay->sendMessage( &pingmsg, i->second );
+	}
 }
 
-void PingPong::onJoinFailed( const SpoVNetID& vid ) {
-	logging_error("pingpong node join failed, spovnetid=" << vid.toString() );
+void PingPong::onMeasurement(NodeID node, double mbps){
+	logging_info( "pingpong received measurement for node " << node.toString() << " with result " << mbps );
 }
 
-void PingPong::onLeaveCompleted( const SpoVNetID& vid ){
-	logging_info("pingpong node leave completed, spovnetid=" << vid.toString() );
+void PingPong::onJoinSuccess( const SpoVNetID& spovnetid ){
 }
 
-void PingPong::onLeaveFailed( const SpoVNetID& vid ){
-	logging_error("pingpong node leave failed, spovnetid=" << vid.toString() );
+void PingPong::onOverlayCreate( const SpoVNetID& id ){
 }
 
-void PingPong::onMessage(const DataMessage& msg, const NodeID& remote, const LinkID& lnk) {
-	PingPongMessage* pingmsg = msg.getMessage()->convert<PingPongMessage> ();
-	bool found=false;
-	for (int i=0;i<names.size(); i++) if (names[i]==pingmsg->getName()) found=true;
-	if (!found) names.push_back(pingmsg->getName());
-	logging_info( "\n<<<<<<<<<< ||||||||||\n"
-	        << "[PINGPONG]\t RECEIVED ping message on link "
-	        << lnk.toString()
-	        << " " << (node.isLinkDirect(lnk) ? "[DIRECT-LINK]" : "[INDIRECT-LINK]")
-	        << " HopCount: " << node.getHopCount(lnk)
-			<< " from node " << remote.toString()
-			<< " (" << pingmsg->getName() << ")"
-			<< ": " << pingmsg->info() );
-	delete pingmsg;
+void PingPong::onOverlayDestroy( const SpoVNetID& id ){
 }
 
-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( "link-changed event for link " << lnk.toString()
-			<< " and node " << remote.toString() );
-}
-
-bool PingPong::onLinkRequest(const NodeID& remote) {
-	logging_info( "node " << remote.toString() << " wants to build up a link with us ... allowing" );
+bool PingPong::isJoinAllowed( const NodeID& nodeid, const SpoVNetID& spovnetid ){
 	return true;
 }
 
-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::onNodeJoin( const NodeID& nodeid, const SpoVNetID& spovnetid ){
+
+	if( !startping ){
+
+		logging_info( "establishing link to node " << nodeid.toString() );
+		const LinkID link = overlay->establishLink( nodeid, PingPong::PINGPONG_ID );
+
+		logging_info( "adding node to registered nodes in pingpong: " << nodeid.toString() );
+		remoteNodes.insert( make_pair(nodeid,link) );
+
+		Timer::setInterval( 2000 );
+		Timer::start();
+	}
 }
 
-}}} // namespace ariba, application, pingpong
+void PingPong::onNodeLeave( const NodeID& id, const SpoVNetID& spovnetid ){
+	RemoteNodes::iterator i = remoteNodes.find( id );
+	if( i != remoteNodes.end() ) remoteNodes.erase( i );
+}
+
+void PingPong::onJoinFail( const SpoVNetID& spovnetid ){
+}
+
+void PingPong::onLinkUp( const LinkID& link, const NodeID& local, const NodeID& remote ){
+}
+
+void PingPong::onLinkDown( const LinkID& link, const NodeID& local, const NodeID& remote ){
+}
+
+void PingPong::onLinkChanged( const LinkID& link, const NodeID& local, const NodeID& remote ){
+}
+
+void PingPong::onLinkFail(const LinkID& id, const NodeID& local, const NodeID& remote){
+}
+
+void PingPong::onLinkQoSChanged(const LinkID& id, const NodeID& local, const NodeID& remote , const QoSParameterSet& qos){
+}
+
+}}} // namespace ariba, appplication, pingpong
