An Overlay-based
Virtual Network Substrate
SpoVNet

source: sample/pingpong/PingPong.cpp @ 5284

Last change on this file since 5284 was 5284, checked in by mies, 14 years ago

+ added new transport modules and adapted ariba to them
+ exchange endpoint descriptors an link establishment
+ clean up of base communication
+ link establishment with in the presence of multiple endpoints
+ local discovery for ipv6, ipv4 and bluetooth mac addresses

File size: 6.5 KB
Line 
1#include "PingPong.h"
2#include "ariba/utility/configuration/Configuration.h"
3
4using ariba::utility::Configuration;
5using namespace ariba;
6
7namespace ariba {
8namespace application {
9namespace pingpong {
10
11// logging
12use_logging_cpp( PingPong );
13
14// the service that the pingpong wants to use
15ServiceID PingPong::PINGPONG_SERVICEID = ServiceID( 111 );
16
17// construction
18PingPong::PingPong() : pingId( 0 ) {
19        Timer::setInterval( 1000 );
20}
21
22// destruction
23PingPong::~PingPong() {
24}
25
26// implementation of the startup interface
27void PingPong::startup() {
28
29        logging_info( "starting up PingPong service ... " );
30
31        // create ariba module
32        logging_debug( "creating ariba underlay module ... " );
33        ariba = new AribaModule();
34
35        // get the configuration object
36        Configuration& config = Configuration::instance();
37
38        // generate spovnet name
39        Name spovnetName("pingpong");
40
41        // get initiator flag
42        this->isInitiator = Configuration::instance().read<bool>("node.initiator");
43
44        this->name = string("<ping>");
45
46        // get node name
47        Name nodeName = Name::UNSPECIFIED;
48        if (config.exists("node.name")) nodeName = config.read<string> ("node.name");
49
50        // configure ariba module
51        if (config.exists("ariba.endpoints"))
52                ariba->setProperty("endpoints", config.read<string>("ariba.endpoints"));
53        if (config.exists("ariba.bootstrap.hints"))
54                ariba->setProperty("bootstrap.hints", config.read<string>("ariba.bootstrap.hints"));
55        if (config.exists("pingpong.name"))
56                name = config.read<string>("pingpong.name");
57
58        // start ariba module
59        ariba->start();
60
61        // create node and join
62        node = new Node( *ariba, nodeName );
63
64        // bind communication and node listener
65        node->bind( this );                              /*NodeListener*/
66        node->bind( this, PingPong::PINGPONG_SERVICEID); /*CommunicationListener*/
67
68        // start node module
69        node->start();
70
71        // when initiating, you can define the overlay type, default is Chord [CHORD_OVERLAY]
72        SpoVNetProperties params;
73        //params.setBaseOverlayType( SpoVNetProperties::ONE_HOP_OVERLAY ); // alternative: OneHop
74
75        // initiate or join the spovnet
76        if (!isInitiator) node->join(spovnetName);
77        else node->initiate(spovnetName, params);
78
79        // ping pong started up...
80        logging_info( "pingpong starting up with"
81                        << " [spovnetid " << node->getSpoVNetId().toString() << "]"
82                        << " and [nodeid " << node->getNodeId().toString() << "]" );
83}
84
85// implementation of the startup interface
86void PingPong::shutdown() {
87
88        logging_info( "pingpong service starting shutdown sequence ..." );
89
90        // stop timer
91        Timer::stop();
92
93        // leave spovnet
94        node->leave();
95
96        // unbind communication and node listener
97        node->unbind( this );                               /*NodeListener*/
98        node->unbind( this, PingPong::PINGPONG_SERVICEID ); /*CommunicationListener*/
99
100        // stop the ariba module
101        ariba->stop();
102
103        // delete node and ariba module
104        delete node;
105        delete ariba;
106
107        // now we are completely shut down
108        logging_info( "pingpong service shut down" );
109}
110
111// timer event
112void PingPong::eventFunction() {
113
114        // we ping all nodes that are known in the overlay structure
115        // this can be all nodes (OneHop) overlay or just some neighbors
116        // in case of a Chord or Kademlia structure
117
118        // in this sample we use auto-links: we just send out our message
119        // to the node and the link is established automatically. for more
120        // control we would use the node->establishLink function to create
121        // a link and start using the link in the CommunicationListener::onLinkUp
122        // function that is implemented further down in PingPong::onLinkUp
123
124//      logging_info( "pinging overlay neighbors with ping id " << ++pingId );
125
126        PingPongMessage pingmsg( pingId, name );
127
128        //-----------------------------------------------------------------------
129        // Option 1: get all neighboring nodes and send the message to each
130        //-----------------------------------------------------------------------
131        counter++;
132        if (counter<0 || counter>4) {
133                counter = 0;
134                string s;
135                for (int i=0; i<names.size();i++) {
136                        if (i!=0) s+= ", ";
137                        s = s+names[i];
138                }
139                logging_info("----> I am " << name << " and I know " << s);
140                names.clear();
141        }
142        vector<NodeID> nodes = node->getNeighborNodes();
143        BOOST_FOREACH( NodeID nid, nodes ){
144                node->sendMessage( pingmsg, nid, PingPong::PINGPONG_SERVICEID );
145        }
146
147        //-----------------------------------------------------------------------
148        // Option 2: send a "broadcast message" that actually does the same thing
149        //           internally, gets all neighboring nodes and sends the message
150        //-----------------------------------------------------------------------
151        // node->sendBroadcastMessage( pingmsg, PingPong::PINGPONG_SERVICEID );
152}
153
154void PingPong::onJoinCompleted( const SpoVNetID& vid ) {
155        logging_info( "pingpong node join completed, spovnetid=" << vid.toString() );
156
157        // start the timer to ping every second
158        Timer::start();
159}
160
161void PingPong::onJoinFailed( const SpoVNetID& vid ) {
162        logging_error("pingpong node join failed, spovnetid=" << vid.toString() );
163}
164
165void PingPong::onLeaveCompleted( const SpoVNetID& vid ){
166        logging_info("pingpong node leave completed, spovnetid=" << vid.toString() );
167}
168
169void PingPong::onLeaveFailed( const SpoVNetID& vid ){
170        logging_error("pingpong node leave failed, spovnetid=" << vid.toString() );
171}
172
173void PingPong::onMessage(const DataMessage& msg, const NodeID& remote, const LinkID& lnk) {
174        PingPongMessage* pingmsg = msg.getMessage()->convert<PingPongMessage> ();
175        bool found=false;
176        for (int i=0;i<names.size(); i++) if (names[i]==pingmsg->getName()) found=true;
177        if (!found) names.push_back(pingmsg->getName());
178//      logging_info( "received ping message on link " << lnk.toString()
179//                      << " from node " << remote.toString()
180//                      << ": " << pingmsg->info() );
181}
182
183void PingPong::onLinkUp(const LinkID& lnk, const NodeID& remote){
184        logging_info( "received link-up event for link " << lnk.toString()
185                        << " and node " << remote.toString() );
186}
187
188void PingPong::onLinkDown(const LinkID& lnk, const NodeID& remote){
189        logging_info( "received link-down event for link " << lnk.toString()
190                        << " and node " << remote.toString() );
191}
192
193void PingPong::onLinkChanged(const LinkID& lnk, const NodeID& remote){
194        logging_info( "link-changed event for link " << lnk.toString()
195                        << " and node " << remote.toString() );
196}
197
198bool PingPong::onLinkRequest(const NodeID& remote, const DataMessage& msg) {
199        logging_info( "node " << remote.toString() << " wants to build up a link with us ... allowing" );
200        return true;
201}
202
203void PingPong::onLinkFail(const LinkID& lnk, const NodeID& remote){
204        logging_info( "received link-failed event for link " << lnk.toString()
205                        << " and node " << remote.toString() );
206}
207
208}}} // namespace ariba, application, pingpong
Note: See TracBrowser for help on using the repository browser.