Nice.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2009 Institut fuer Telematik, Universitaet Karlsruhe (TH)
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 //
00018 
00025 #include <stdio.h>
00026 
00027 #include <GlobalStatistics.h>
00028 #include "SimpleInfo.h"
00029 #include "SimpleNodeEntry.h"
00030 #include "SimpleUDP.h"
00031 #include "GlobalNodeListAccess.h"
00032 #include <BootstrapList.h>
00033 #include "Nice.h"
00034 
00035 namespace oversim
00036 {
00037 
00041 const char *clustercolors[] = { "yellow",
00042                                 "magenta",
00043                                 "red",
00044                                 "orange",
00045                                 "green",
00046                                 "aquamarine",
00047                                 "cyan",
00048                                 "blue",
00049                                 "navy",
00050                                 "yellow"
00051                               };
00052 
00053 const char *clusterarrows[] = { "m=m,50,50,50,50;ls=yellow,2",
00054                                 "m=m,50,50,50,50;ls=magenta,3",
00055                                 "m=m,50,50,50,50;ls=red,4",
00056                                 "m=m,50,50,50,50;ls=orange,5",
00057                                 "m=m,50,50,50,50;ls=green,6",
00058                                 "m=m,50,50,50,50;ls=aquamarine,7",
00059                                 "m=m,50,50,50,50;ls=cyan,8",
00060                                 "m=m,50,50,50,50;ls=blue,9",
00061                                 "m=m,50,50,50,50;ls=navy,10",
00062                                 "m=m,50,50,50,50;ls=yellow,11"
00063                               };
00064 
00065 Define_Module(Nice);
00066 
00067 const short Nice::maxLayers;
00068 
00069 /******************************************************************************
00070  * Constructor
00071  */
00072 Nice::Nice() : isRendevouzPoint(false),
00073                isTempPeered(false),
00074                numInconsistencies(0),
00075                numQueryTimeouts(0),
00076                numPeerTimeouts(0),
00077                numTempPeerTimeouts(0),
00078                numStructurePartitions(0),
00079                numOwnMessagesReceived(0),
00080                totalSCMinCompare(0),
00081                numJoins(0),
00082                totalForwardBytes(0),
00083                numReceived(0),
00084                totalReceivedBytes(0),
00085                numHeartbeat(0),
00086                totalHeartbeatBytes(0)
00087 {
00088 
00089     /* do nothing at this point of time, OverSim calls initializeOverlay */
00090 
00091 } // Nice
00092 
00093 
00094 /******************************************************************************
00095  * Destructor
00096  */
00097 Nice::~Nice()
00098 {
00099 
00100     // destroy self timer messages
00101     cancelAndDelete(heartbeatTimer);
00102     cancelAndDelete(maintenanceTimer);
00103     cancelAndDelete(rpPollTimer);
00104     cancelAndDelete(queryTimer);
00105     cancelAndDelete(visualizationTimer);
00106 
00107     std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.begin();
00108 
00109     for (; it != peerInfos.end(); it++) {
00110 
00111         delete it->second;
00112 
00113     }
00114 
00115 } // ~NICE
00116 
00117 
00118 /******************************************************************************
00119  * initializeOverlay
00120  * see BaseOverlay.h
00121  */
00122 void Nice::initializeOverlay( int stage )
00123 {
00124 
00125     /* Because of IPAddressResolver, we need to wait until interfaces
00126      * are registered, address auto-assignment takes place etc. */
00127     if (stage != MIN_STAGE_OVERLAY)
00128         return;
00129 
00130     /* Set appearance of node in visualization */
00131     getParentModule()->getParentModule()->getDisplayString().setTagArg("i", 0, "device/pc_vs");
00132     getParentModule()->getParentModule()->getDisplayString().setTagArg("i2", 0, "block/circle_vs");
00133 
00134     /* Initially clear all clusters */
00135     for (int i=0; i<maxLayers; i++) {
00136 
00137         for (TaSet::iterator itn = clusters[i].begin(); itn != clusters[i].end(); ++itn) {
00138             deleteOverlayNeighborArrow(*itn);
00139         }
00140         clusters[i].clear();
00141 
00142     }
00143 
00144     /* Initialize Self-Messages */
00145 
00146     // Periodic Heartbeat Messages
00147     heartbeatInterval = par("heartbeatInterval");
00148     heartbeatTimer = new cMessage("heartbeatTimer");
00149 
00150     // Periodic Protocol Maintenance
00151     maintenanceInterval = par("maintenanceInterval");
00152     maintenanceTimer = new cMessage("maintenanceTimer");
00153 
00154     queryInterval = par("queryInterval");
00155     queryTimer = new cMessage("queryTimer");
00156 
00157     rpPollTimer = new cMessage("rpPollTimer");
00158     rpPollTimerInterval = par("rpPollTimerInterval");
00159 
00160     peerTimeoutHeartbeats = par("peerTimeoutHeartbeats");
00161 
00162     pimp = par("enhancedMode");
00163 
00164     isRendevouzPoint = false;
00165 
00166     polledRendevouzPoint = TransportAddress::UNSPECIFIED_NODE;
00167 
00168     /* DEBUG */
00169     clusterrefinement = par("debug_clusterrefinement");
00170     debug_heartbeats = par("debug_heartbeats");
00171     debug_visualization = par("debug_visualization");
00172     debug_join = par("debug_join");
00173     debug_peertimeouts = par("debug_peertimeouts");
00174     debug_removes = par("debug_removes");
00175     debug_queries = par("debug_queries");
00176 
00177     visualizationTimer = new cMessage("visualizationTimer");
00178 
00179     /* Read cluster parameter k */
00180     k = par("k");
00181 
00182     CLUSTERLEADERBOUND = par("clusterLeaderBound");
00183     CLUSTERLEADERCOMPAREDIST = par("clusterLeaderCompareDist");
00184     SC_PROC_DISTANCE = par("scProcDistance");
00185     SC_MIN_OFFSET = par("scMinOffset");
00186 
00187     /* Add own node to peerInfos */
00188     NicePeerInfo* pi = new NicePeerInfo(this);
00189     pi->set_distance(0);
00190     peerInfos.insert(std::make_pair(thisNode, pi));
00191 
00192     /* Set evaluation layer to not specified */
00193     evalLayer = -1;
00194     joinLayer = -1;
00195 
00196     first_leader = TransportAddress::UNSPECIFIED_NODE;
00197     second_leader = TransportAddress::UNSPECIFIED_NODE;
00198 
00199     // add some watches
00200     WATCH(thisNode);
00201     WATCH_POINTER_MAP(peerInfos);
00202     WATCH(evalLayer);
00203     WATCH(query_start);
00204     WATCH(heartbeatTimer);
00205     WATCH_MAP(tempPeers);
00206     WATCH(RendevouzPoint);
00207     WATCH(isRendevouzPoint);
00208 
00209     WATCH(numInconsistencies);
00210     WATCH(numQueryTimeouts);
00211     WATCH(numPeerTimeouts);
00212     WATCH(numTempPeerTimeouts);
00213     WATCH(numStructurePartitions);
00214     WATCH(numOwnMessagesReceived);
00215     WATCH(totalSCMinCompare);
00216     WATCH(numJoins);
00217     WATCH(totalForwardBytes);
00218     WATCH(numReceived);
00219     WATCH(totalReceivedBytes);
00220     WATCH(numHeartbeat);
00221     WATCH(totalHeartbeatBytes);
00222 
00223 } // initializeOverlay
00224 
00225 
00226 /******************************************************************************
00227  * joinOverlay
00228  * see BaseOverlay.h
00229  */
00230 void Nice::joinOverlay()
00231 {
00232     changeState(INIT);
00233     changeState(BOOTSTRAP);
00234 } // joinOverlay
00235 
00236 void Nice::handleNodeLeaveNotification() {
00237     if (isRendevouzPoint) {
00238         opp_error("The NICE Rendevouz Point is being churned out and the simulation cannot continue. "
00239                 "Please, check your config and make sure that the Chrun Generator's configuration is correct. "
00240                 "Specifically, the Rendevouz Point must not get churned out during the simulation.");
00241     }
00242 }
00243 
00244 /******************************************************************************
00245  * changeState
00246  * see BaseOverlay.h
00247  */
00248 void Nice::changeState( int toState )
00249 {
00250     switch (toState) {
00251 
00252     case INIT:
00253 
00254         state = INIT;
00255 
00256         getParentModule()->getParentModule()->getDisplayString().setTagArg("i2", 1, "red");
00257 
00258         scheduleAt(simTime() + 1, visualizationTimer);
00259 
00260         break;
00261 
00262     case BOOTSTRAP:
00263 
00264         state = BOOTSTRAP;
00265 
00266         /* get rendevouz point */
00267         RendevouzPoint = bootstrapList->getBootstrapNode();
00268         if (RendevouzPoint.isUnspecified()) {
00269 
00270             RendevouzPoint = thisNode;
00271             isRendevouzPoint = true;
00272 
00273             /* join cluster layer 0 as first node */
00274             clusters[0].add(thisNode);
00275             clusters[0].setLeader(thisNode);
00276 
00277             changeState(READY);
00278 
00279             return;
00280 
00281         }
00282         else {
00283 
00284             pollRP(-1);
00285 
00286             /* initiate NICE structure joining */
00287             BasicJoinLayer(-1);
00288 
00289         }
00290 
00291         break;
00292 
00293     case READY:
00294 
00295         state = READY;
00296 
00297         cancelEvent(heartbeatTimer);
00298         scheduleAt(simTime() + heartbeatInterval, heartbeatTimer);
00299         cancelEvent(maintenanceTimer);
00300         scheduleAt(simTime() + maintenanceInterval, maintenanceTimer);
00301 
00302         getParentModule()->getParentModule()->getDisplayString().setTagArg
00303         ("i2", 1, clustercolors[getHighestLayer()]);
00304 
00305         setOverlayReady(true);
00306         /* allow only rendevouz point to be bootstrap node */
00307         if (!isRendevouzPoint) bootstrapList->removeBootstrapNode(thisNode);
00308 
00309         break;
00310 
00311     }
00312 
00313 } // changeState
00314 
00315 
00316 /******************************************************************************
00317  * changeState
00318  * see BaseOverlay.h
00319  */
00320 void Nice::handleTimerEvent( cMessage* msg )
00321 {
00322 
00323     if (msg->isName("visualizationTimer")) {
00324 
00325         updateVisualization();
00326         scheduleAt(simTime() + 1, visualizationTimer);
00327 
00328     }
00329     else if (msg->isName("heartbeatTimer")) {
00330 
00331         sendHeartbeats();
00332         scheduleAt(simTime() + heartbeatInterval, heartbeatTimer);
00333 
00334     }
00335     else if (msg->isName("maintenanceTimer")) {
00336 
00337         maintenance();
00338         cancelEvent(maintenanceTimer);
00339         scheduleAt(simTime() + maintenanceInterval, maintenanceTimer);
00340 
00341     }
00342     else if (msg->isName("queryTimer")) {
00343 
00344         RECORD_STATS(++numInconsistencies; ++numQueryTimeouts);
00345         if (!tempResolver.isUnspecified() && 
00346                 (tempResolver == RendevouzPoint ||
00347                  (!polledRendevouzPoint.isUnspecified() && tempResolver == polledRendevouzPoint))) {
00348             Query(RendevouzPoint, joinLayer);
00349         }
00350         else {
00351             Query(tempResolver, joinLayer);
00352         }
00353 
00354     }
00355     else if (msg->isName("rpPollTimer")) {
00356 
00357         pollRP(-1);
00358 
00359     }
00360 
00361 } // handleTimerEvent
00362 
00363 
00364 /******************************************************************************
00365  * handleUDPMessage
00366  * see BaseOverlay.h
00367  */
00368 void Nice::handleUDPMessage(BaseOverlayMessage* msg)
00369 {
00370 
00371     // try message cast to NICE base message
00372     if (dynamic_cast<NiceMessage*>(msg) != NULL) {
00373 
00374         NiceMessage* niceMsg = check_and_cast<NiceMessage*>(msg);
00375 
00376         // First of all, update activity information for sourcenode
00377         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(niceMsg->getSrcNode());
00378 
00379         if (it != peerInfos.end()) {
00380 
00381             it->second->touch();
00382 
00383         }
00384 
00385         /* Dispatch message, possibly downcasting to a more concrete type */
00386         switch (niceMsg->getCommand()) {
00387 
00388             /* More concrete types, to which the message is cast if needed */
00389             NiceMemberMessage* queryRspMsg;
00390             NiceClusterMerge* mergeMsg;
00391             NiceMulticastMessage* multicastMsg;
00392 
00393             case NICE_QUERY:
00394 
00395                 handleNiceQuery(niceMsg);
00396 
00397                 break;
00398 
00399             case NICE_QUERY_RESPONSE:
00400 
00401                 queryRspMsg = check_and_cast<NiceMemberMessage*>(niceMsg);
00402                 handleNiceQueryResponse(queryRspMsg);
00403 
00404                 break;
00405 
00406             case NICE_JOIN_CLUSTER:
00407 
00408                 handleNiceJoinCluster(niceMsg);
00409 
00410                 break;
00411 
00412             case NICE_POLL_RP:
00413 
00414                 handleNicePollRp(niceMsg);
00415 
00416                 break;
00417 
00418             case NICE_POLL_RP_RESPONSE:
00419 
00420                 handleNicePollRpResponse(niceMsg);
00421 
00422                 break;
00423 
00424             case NICE_HEARTBEAT:
00425 
00426                 handleNiceHeartbeat(check_and_cast<NiceHeartbeat*>(niceMsg));
00427 
00428                 break;
00429 
00430             case NICE_LEADERHEARTBEAT:
00431 
00432                 handleNiceLeaderHeartbeat(check_and_cast<NiceLeaderHeartbeat*>(niceMsg));
00433 
00434                 break;
00435 
00436             case NICE_LEADERTRANSFER:
00437 
00438                 handleNiceLeaderTransfer(check_and_cast<NiceLeaderHeartbeat*>(niceMsg));
00439 
00440                 break;
00441 
00442             case NICE_JOINEVAL:
00443 
00444                 handleNiceJoineval(niceMsg);
00445 
00446                 break;
00447 
00448             case NICE_JOINEVAL_RESPONSE:
00449 
00450                 handleNiceJoinevalResponse(niceMsg);
00451 
00452                 break;
00453 
00454             case NICE_REMOVE:
00455 
00456                 handleNiceRemove(niceMsg);
00457 
00458                 break;
00459 
00460             case NICE_PEER_TEMPORARY:
00461 
00462                 handleNicePeerTemporary(niceMsg);
00463 
00464                 break;
00465 
00466             case NICE_PEER_TEMPORARY_RELEASE:
00467 
00468                 handleNicePeerTemporaryRelease(niceMsg);
00469 
00470                 break;
00471 
00472             case NICE_PING_PROBE:
00473 
00474                 handleNicePingProbe(niceMsg);
00475 
00476                 break;
00477 
00478             case NICE_PING_PROBE_RESPONSE:
00479 
00480                 handleNicePingProbeResponse(niceMsg);
00481 
00482                 break;
00483 
00484             case NICE_FORCE_MERGE:
00485 
00486                 handleNiceForceMerge(niceMsg);
00487 
00488                 break;
00489 
00490             case NICE_CLUSTER_MERGE_REQUEST:
00491 
00492                 mergeMsg = check_and_cast<NiceClusterMerge*>(niceMsg);
00493 
00494                 handleNiceClusterMergeRequest(mergeMsg);
00495 
00496                 break;
00497 
00498             case NICE_MULTICAST:
00499 
00500                 multicastMsg = check_and_cast<NiceMulticastMessage*>(msg);
00501 
00502                 handleNiceMulticast(multicastMsg);
00503 
00504                 break;
00505 
00506             default:
00507                 
00508                 delete niceMsg;
00509         }
00510     }
00511     else {
00512         delete msg;
00513     }
00514 } // handleUDPMessage
00515 
00516 
00517 /******************************************************************************
00518  * finishOverlay
00519  * see BaseOverlay.h
00520  */
00521 void Nice::finishOverlay()
00522 {
00523 
00524     if (isRendevouzPoint) {
00525         RendevouzPoint = TransportAddress::UNSPECIFIED_NODE;
00526     }
00527 
00528     simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
00529     if (time < GlobalStatistics::MIN_MEASURED) return;
00530 
00531     globalStatistics->addStdDev("Nice: Inconsistencies/s", (double)numInconsistencies / time);
00532     globalStatistics->addStdDev("Nice: Query Timeouts/s", (double)numQueryTimeouts / time);
00533     globalStatistics->addStdDev("Nice: Peer Timeouts/s", (double)numPeerTimeouts / time);
00534     globalStatistics->addStdDev("Nice: Temporary Peer Timeouts/s", (double)numTempPeerTimeouts / time);
00535     globalStatistics->addStdDev("Nice: Structure Partitions/s", (double)numStructurePartitions / time);
00536     globalStatistics->addStdDev("Nice: Own Messages Received/s", (double)numOwnMessagesReceived / time);
00537     globalStatistics->addStdDev("Nice: SC Minimum Compare/s", (double)totalSCMinCompare / time);
00538     globalStatistics->addStdDev("Nice: Received JOIN Messages/s", (double)numJoins / time);
00539     globalStatistics->addStdDev("Nice: Forwarded Multicast Messages/s", (double)numForward / time);
00540     globalStatistics->addStdDev("Nice: Forwarded Multicast Bytes/s", (double)totalForwardBytes / time);
00541     globalStatistics->addStdDev("Nice: Received Multicast Messages/s (subscribed groups only)", (double)numReceived / time);
00542     globalStatistics->addStdDev("Nice: Received Multicast Bytes/s (subscribed groups only)", (double)totalReceivedBytes / time);
00543     globalStatistics->addStdDev("Nice: Send Heartbeat Messages/s", (double)numHeartbeat / time);
00544     globalStatistics->addStdDev("Nice: Send Heartbeat Bytes/s", (double)totalHeartbeatBytes / time);
00545     if( debug_join ) recordScalar("Nice: Total joins", (double)numJoins);
00546 
00547 } // finishOverlay
00548 
00549 
00550 /******************************************************************************
00551  * BasicJoinLayer
00552  * Queries RendevouzPoint, sets targetLayer to the given layer
00553  * and peers temporarily with the RendevouzPoint.
00554  */
00555 void Nice::BasicJoinLayer(short layer)
00556 {
00557 
00558     // Cancel timers involved in structure refinement
00559     /*
00560     if (layer == -1 || layer == 0) {
00561         cancelEvent(maintenanceTimer);
00562         cancelEvent(heartbeatTimer);
00563     }
00564     */
00565 
00566     Query(RendevouzPoint, -1);
00567 
00568     if (layer > -1)
00569         targetLayer = layer;
00570     else
00571         targetLayer = 0;
00572 
00573     // Temporary peer with RP for faster data reception
00574     NiceMessage* msg = new NiceMessage("NICE_PEER_TEMPORARY");
00575     msg->setSrcNode(thisNode);
00576     msg->setCommand(NICE_PEER_TEMPORARY);
00577     msg->setLayer(-1);
00578     msg->setBitLength(NICEMESSAGE_L(msg));
00579 
00580     sendMessageToUDP(RendevouzPoint, msg);
00581 
00582     isTempPeered = true;
00583 
00584 } // BasicJoinLayer
00585 
00586 
00587 /******************************************************************************
00588  * Query
00589  * Sends a query message to destination.
00590  * Records query_start time.
00591  * Sets tempResolver to destination.
00592  * Sets joinLayer to layer.
00593  */
00594 void Nice::Query(const TransportAddress& destination, short layer)
00595 {
00596     if (debug_queries)
00597         EV << simTime() << " : " << thisNode.getIp() << " : Query()" << endl;
00598 
00599 
00600     NiceMessage* msg = new NiceMessage("NICE_QUERY");
00601     msg->setSrcNode(thisNode);
00602     msg->setCommand(NICE_QUERY);
00603     msg->setLayer(layer);
00604     msg->setBitLength(NICEMESSAGE_L(msg));
00605 
00606     query_start = simTime();
00607     tempResolver = destination;
00608 
00609     cancelEvent(queryTimer);
00610     scheduleAt(simTime() + queryInterval, queryTimer);
00611 
00612     joinLayer = layer;
00613 
00614     sendMessageToUDP(destination, msg);
00615 
00616     if (debug_queries)
00617         EV << simTime() << " : " << thisNode.getIp() << " : Query() finished." << endl;
00618 
00619 } // Query
00620 
00621 /* Functions handling NICE messages */
00622 
00623 void Nice::handleNiceQuery(NiceMessage* queryMsg)
00624 {
00625 
00626     if (debug_queries)
00627         EV << simTime() << " : " << thisNode.getIp() << " : handleNiceQuery()" << endl;
00628 
00629     short layer = queryMsg->getLayer();
00630     if (layer >= maxLayers) {
00631         if (debug_queries)
00632             EV << "Layer " << layer << " >=  max layer " << maxLayers << " ! Returning." << endl;
00633         delete queryMsg;
00634         return;
00635     }
00636 
00637     if (debug_queries)
00638         EV << " layer before: " << layer << endl;
00639 
00640     if (layer > getHighestLeaderLayer()) {
00641         if (isRendevouzPoint) {
00642             if (debug_queries)
00643                 EV << " getHighestLeaderLayer(): " << getHighestLeaderLayer() << " ! RP self-promoting." << endl;
00644 
00645             for (int i = getHighestLeaderLayer() + 1; i <= layer; ++i) {
00646                 clusters[i].add(thisNode);
00647                 clusters[i].setLeader(thisNode);
00648             }
00649         }
00650         else {
00651             if (debug_queries)
00652                 EV << " getHighestLeaderLayer(): " << getHighestLeaderLayer() << " ! Returning." << endl;
00653 
00654             delete queryMsg;
00655             return;
00656         }
00657     }
00658 
00659     if (layer < 0) {
00660 
00661         if (isRendevouzPoint) {
00662 
00663             /* If layer is < 0, response with highest layer I am leader of */
00664             if (debug_queries)
00665                 EV << " I am RP." << endl;
00666             layer = getHighestLeaderLayer();
00667 
00668         }
00669         else {
00670 
00671             if (debug_queries)
00672                 EV << " I am not RP. Return." << endl;
00673 
00674             if (pimp) {
00675 
00676                 /* forward to Rendevouz Point */
00677                 NiceMessage* dup = static_cast<NiceMessage*>(queryMsg->dup());
00678                 sendMessageToUDP(RendevouzPoint, dup);
00679 
00680             }
00681 
00682             delete queryMsg;
00683             return;
00684 
00685         }
00686 
00687     }
00688 
00689     if (debug_queries)
00690         EV << " layer after: " << layer << endl;
00691 
00692     if (!clusters[layer].getLeader().isUnspecified()) {
00693 
00694         if (clusters[layer].getLeader() != thisNode) {
00695 
00696             if (pimp) {
00697 
00698                 NiceMessage* dup = static_cast<NiceMessage*>(queryMsg->dup());
00699                 sendMessageToUDP(clusters[layer].getLeader(), dup);
00700 
00701             }
00702 
00703             if (debug_queries)
00704                 EV << " I am not leader of this cluster. return." << endl;
00705 
00706             delete queryMsg;
00707             return;
00708 
00709         }
00710 
00711     }
00712     else {
00713 
00714         delete queryMsg;
00715         return;
00716 
00717     }
00718 
00719     NiceMemberMessage* response = new NiceMemberMessage("NICE_QUERY_RESPONSE");
00720     response->setSrcNode(thisNode);
00721     response->setCommand(NICE_QUERY_RESPONSE);
00722     response->setLayer(layer);
00723 
00724     /* Fill in current cluster members except me */
00725     response->setMembersArraySize(clusters[layer].getSize()-1);
00726 
00727     int j=0;
00728 
00729     for (int i = 0; i < clusters[layer].getSize(); i++) {
00730 
00731         if (clusters[layer].get(i) != thisNode) {
00732 
00733             response->setMembers(j, clusters[layer].get(i));
00734             if (debug_queries)
00735                 EV << " Response: " << i << " : " << clusters[layer].get(i) << endl;
00736             j++;
00737 
00738         }
00739 
00740     }
00741 
00742     response->setBitLength(NICEMEMBERMESSAGE_L(response));
00743 
00744     sendMessageToUDP(queryMsg->getSrcNode(), response);
00745 
00746     if (debug_queries)
00747         EV << " Sent response to: " << queryMsg->getSrcNode() << endl;
00748 
00749     if (debug_queries)
00750         EV << simTime() << " : " << thisNode.getIp() << " : handleNiceQuery() finished." << endl;
00751 
00752     delete queryMsg;
00753 } // handleNiceQuery
00754 
00755 void Nice::handleNiceClusterMergeRequest(NiceClusterMerge* mergeMsg)
00756 {
00757     EV << simTime() << " : " << thisNode.getIp() << " : NICE_CLUSTER_MERGE_REQUEST" << endl;
00758 
00759     short layer = mergeMsg->getLayer();
00760 
00761     // Only react if I am a leader of this cluster layer
00762 
00763     if (clusters[layer].getLeader().isUnspecified()) {
00764 
00765         EV << simTime() << " : " << thisNode.getIp() << " : NO LEADER! BREAK. NICE_CLUSTER_MERGE_REQUEST finished" << endl;
00766 
00767         delete mergeMsg;
00768 
00769         return;
00770 
00771     }
00772 
00773     if (clusters[layer].getLeader() == thisNode) {
00774 
00775         clusters[layer+1].remove(mergeMsg->getSrcNode());
00776         deleteOverlayNeighborArrow(mergeMsg->getSrcNode());
00777 
00778         TransportAddress oldLeader = clusters[layer+1].getLeader();
00779         if (oldLeader.isUnspecified() || oldLeader != thisNode) {
00780             clusters[layer+1].add(mergeMsg->getNewClusterLeader());
00781             clusters[layer+1].setLeader(mergeMsg->getNewClusterLeader());
00782         }
00783 
00784         for (unsigned int i=0; i<mergeMsg->getMembersArraySize(); i++) {
00785 
00786             /* Add new node to cluster */
00787             clusters[layer].add(mergeMsg->getMembers(i));
00788 
00789             /* Create peer context to joining node */
00790             /* Check if peer info already exists */
00791             std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(mergeMsg->getMembers(i));
00792 
00793             if (it != peerInfos.end()) { /* We already know this node */
00794 
00795             }
00796             else { /* Create PeerInfo object */
00797 
00798                 NicePeerInfo* pi = new NicePeerInfo(this);
00799 
00800                 pi->set_last_HB_arrival(simTime().dbl());
00801 
00802                 peerInfos.insert(std::make_pair(mergeMsg->getMembers(i), pi));
00803 
00804             }
00805 
00806             /* Draw arrow to new member */
00807             showOverlayNeighborArrow(mergeMsg->getMembers(i), false, clusterarrows[layer]);
00808 
00809             EV << "getHighestLeaderLayer()].getSize(): " << clusters[getHighestLeaderLayer()].getSize() << endl;
00810 
00811 #if 0
00812             if (clusters[getHighestLeaderLayer()].getSize() < 2) {
00813 
00814                 // cancel layer
00815                 for (TaSet::iterator itn = clusters[i].begin(); itn != clusters[i].end(); ++itn) {
00816                     deleteOverlayNeighborArrow(*itn);
00817                 }
00818                 clusters[getHighestLeaderLayer()].clear();
00819 
00820                 for (short i=0; i<maxLayers; i++) {
00821 
00822                     if (clusters[i].getSize() > 0) {
00823 
00824                         if (clusters[i].contains(thisNode)) {
00825 
00826                             getParentModule()->getParentModule()->getDisplayString().setTagArg
00827                                 ("i2", 1, clustercolors[i]);
00828 
00829                         }
00830 
00831                     }
00832 
00833                 }
00834 
00835             }
00836 #endif
00837 
00838         }
00839 
00840     }
00841     else { // Forward to new cluster leader
00842 
00843         if (pimp) {
00844 
00845             NiceMemberMessage* dup = static_cast<NiceMemberMessage*>(mergeMsg->dup());
00846             sendMessageToUDP(clusters[layer].getLeader(), dup);
00847             delete mergeMsg;
00848             return;
00849 
00850         }
00851 
00852     }
00853 
00854     if (pimp)
00855         sendHeartbeats();
00856 
00857     delete mergeMsg;
00858 
00859     EV << simTime() << " : " << thisNode.getIp() << " : NICE_CLUSTER_MERGE_REQUEST finished" << endl;
00860 }
00861 
00862 void Nice::handleNiceForceMerge(NiceMessage* msg)
00863 {
00864     ClusterMergeRequest(msg->getSrcNode(), msg->getLayer());
00865 
00866     delete msg;
00867 }
00868 
00869 void Nice::handleNiceHeartbeat(NiceHeartbeat* hbMsg)
00870 {
00871     if (debug_heartbeats)
00872         EV << simTime() << " : " << thisNode.getIp() << " : NICE_HEARTBEAT from  " << hbMsg->getSrcNode() << endl;
00873 
00874     /* Update sequence number information and evaluate distance */
00875     std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(hbMsg->getSrcNode());
00876 
00877     if (it != peerInfos.end()) {
00878 
00879         /* We already know this node */
00880         // Collect subcluster infos
00881         it->second->setSubClusterMembers(hbMsg->getSublayermembers());
00882 
00883         it->second->set_last_HB_arrival(simTime().dbl());
00884 
00885         if (it->second->get_backHB(hbMsg->getSeqRspNo()) > 0) {
00886 
00887             /* Valid distance measurement, get value */
00888             double oldDistance = it->second->get_distance();
00889 
00890             /* Use Exponential Moving Average with factor 0.1 */
00891             double newDistance = (simTime().dbl() - it->second->get_backHB(hbMsg->getSeqRspNo()) - hbMsg->getHb_delay())/2.0;
00892 
00893             if (oldDistance > 0) {
00894 
00895                 it->second->set_distance((0.1 * newDistance) + (0.9 * oldDistance));
00896 
00897             }
00898             else {
00899 
00900                 it->second->set_distance(newDistance);
00901 
00902             }
00903 
00904         }
00905 
00906         it->second->set_last_recv_HB(hbMsg->getSeqNo());
00907 
00908     }
00909 
00910     it = peerInfos.find(hbMsg->getSrcNode());
00911 
00912     if (it != peerInfos.end()) {
00913 
00914         for (unsigned int i=0; i<hbMsg->getMembersArraySize(); i++) {
00915 
00916             it->second->updateDistance(hbMsg->getMembers(i), hbMsg->getDistances(i));
00917 
00918         }
00919 
00920     }
00921 
00922     delete hbMsg;
00923 
00924     if (debug_heartbeats)
00925         EV << simTime() << " : " << thisNode.getIp() << " : handleHeartbeat() finished.  " << endl;
00926 }
00927 
00928 void Nice::handleNiceLeaderHeartbeat(NiceLeaderHeartbeat* lhbMsg)
00929 {
00930     if (debug_heartbeats)
00931         EV << simTime() << " : " << thisNode.getIp() << " : NICE_LEADERHEARTBEAT from  " << lhbMsg->getSrcNode() << endl;
00932 
00933     ASSERT(lhbMsg->getSrcNode() != thisNode);
00934 
00935     /* Update sequence number information and evaluate distance */
00936     std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(lhbMsg->getSrcNode());
00937 
00938     if (it != peerInfos.end()) { /* We already know this node */
00939 
00940         it->second->set_last_HB_arrival(simTime().dbl());
00941 
00942         if (it->second->get_backHB(lhbMsg->getSeqRspNo()) > 0) {
00943 
00944             /* Valid distance measurement, get value */
00945             it->second->set_distance((simTime().dbl() - it->second->get_backHB(lhbMsg->getSeqRspNo()) - lhbMsg->getHb_delay())/2);
00946 
00947         }
00948 
00949         it->second->set_last_recv_HB(lhbMsg->getSeqNo());
00950 
00951     }
00952 
00953     it = peerInfos.find(lhbMsg->getSrcNode());
00954 
00955     if (it != peerInfos.end()) {
00956 
00957         for (unsigned int i=0; i<lhbMsg->getMembersArraySize(); i++) {
00958 
00959             it->second->updateDistance(lhbMsg->getMembers(i), lhbMsg->getDistances(i));
00960 
00961         }
00962 
00963     }
00964 
00965     // Maintain cluster memberships
00966 
00967     if (lhbMsg->getLayer() > getHighestLayer()) {
00968 
00969         /* Node is not part of this cluster, remove it */
00970         sendRemoveTo(lhbMsg->getSrcNode(), lhbMsg->getLayer());
00971 
00972         if (debug_heartbeats)
00973             EV << "Node is not part of this cluster (" << lhbMsg->getLayer() << "), removing it..." << endl;
00974 
00975         delete lhbMsg;
00976         return;
00977 
00978     }
00979 
00980     if (!clusters[lhbMsg->getLayer()].getLeader().isUnspecified() && 
00981             clusters[lhbMsg->getLayer()].getLeader() == thisNode) {
00982 
00983         if (debug_heartbeats)
00984             EV << "Leader collision...";
00985 
00986         if (lhbMsg->getSrcNode() < thisNode) {
00987 
00988             if (debug_heartbeats)
00989                 EV << "...making other leader." << endl;
00990 
00991             if (lhbMsg->getLayer() + 1 <= getHighestLayer()) {
00992                 gracefulLeave(lhbMsg->getLayer() + 1);
00993             }
00994 
00995             /* Fix visualisation - remove arrows */
00996             int hbLayer = lhbMsg->getLayer();
00997             for (TaSet::iterator itn = clusters[hbLayer].begin(); itn != clusters[hbLayer].end(); ++itn) {
00998                 deleteOverlayNeighborArrow(*itn);
00999             }
01000 
01001             clusters[lhbMsg->getLayer()].add(lhbMsg->getSrcNode());
01002             clusters[lhbMsg->getLayer()].setLeader(lhbMsg->getSrcNode());
01003             LeaderTransfer(lhbMsg->getLayer(), lhbMsg->getSrcNode());
01004         }
01005         else {
01006             if (debug_heartbeats)
01007                 EV << "...remaining leader." << endl;
01008             delete lhbMsg;
01009             return;
01010         }
01011     }
01012     else if (!clusters[lhbMsg->getLayer()].getLeader().isUnspecified() &&
01013             clusters[lhbMsg->getLayer()].getLeader() != lhbMsg->getSrcNode()) {
01014         if (debug_heartbeats)
01015             EV << "Possible multiple leaders detected... sending remove to " << clusters[lhbMsg->getLayer()].getLeader() << " leader.\n";
01016         sendRemoveTo(clusters[lhbMsg->getLayer()].getLeader(), lhbMsg->getLayer());
01017         
01018     }
01019 
01020     /* Everything is in order. Process HB */
01021     bool leaderChanged = clusters[lhbMsg->getLayer()].getLeader().isUnspecified() || clusters[lhbMsg->getLayer()].getLeader() != lhbMsg->getSrcNode();
01022 
01023     for (int m=lhbMsg->getLayer(); m<maxLayers; m++) {
01024         for (TaSet::iterator itn = clusters[m].begin(); itn != clusters[m].end(); ++itn) {
01025             deleteOverlayNeighborArrow(*itn);
01026         }
01027         clusters[m].clear();
01028     }
01029 
01030     for (unsigned int i=0; i<lhbMsg->getMembersArraySize(); i++) {
01031 
01032         //Check if member is already part of cluster
01033 
01034         /* Check if peer info already exists */
01035         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(lhbMsg->getMembers(i));
01036 
01037         if (it != peerInfos.end()) { /* We already know this node */
01038 
01039         }
01040         else { /* Create PeerInfo object */
01041 
01042             NicePeerInfo* pi = new NicePeerInfo(this);
01043 
01044             pi->set_last_HB_arrival(simTime().dbl());
01045 
01046             peerInfos.insert(std::make_pair(lhbMsg->getMembers(i), pi));
01047 
01048         }
01049 
01050         clusters[lhbMsg->getLayer()].add(lhbMsg->getMembers(i));
01051 
01052     }
01053 
01054     clusters[lhbMsg->getLayer()].setLeader(lhbMsg->getSrcNode());
01055     if (!leaderChanged)
01056         clusters[lhbMsg->getLayer()].confirmLeader();
01057 
01058     if (lhbMsg->getSupercluster_membersArraySize() > 0) {
01059 
01060         for (TaSet::iterator itn = clusters[lhbMsg->getLayer() + 1].begin(); itn != clusters[lhbMsg->getLayer() + 1].end(); ++itn) {
01061             deleteOverlayNeighborArrow(*itn);
01062         }
01063         clusters[lhbMsg->getLayer()+1].clear();
01064 
01065         for (unsigned int i=0; i<lhbMsg->getSupercluster_membersArraySize(); i++) {
01066 
01067             /* Check if peer info already exists */
01068             std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(lhbMsg->getSupercluster_members(i));
01069 
01070             if (it != peerInfos.end()) { /* We already know this node */
01071 
01072             }
01073             else { /* Create PeerInfo object */
01074 
01075                 NicePeerInfo* pi = new NicePeerInfo(this);
01076 
01077                 pi->set_last_HB_arrival(simTime().dbl());
01078 
01079                 peerInfos.insert(std::make_pair(lhbMsg->getSupercluster_members(i), pi));
01080 
01081             }
01082 
01083             clusters[lhbMsg->getLayer()+1].add(lhbMsg->getSupercluster_members(i));
01084 
01085         }
01086 
01087         clusters[lhbMsg->getLayer()+1].setLeader(lhbMsg->getSupercluster_leader());
01088 
01089         it = peerInfos.find(lhbMsg->getSrcNode());
01090 
01091         if (it != peerInfos.end()) {
01092 
01093             for (unsigned int k=0; k<lhbMsg->getMembersArraySize(); k++) {
01094 
01095                 it->second->updateDistance(lhbMsg->getMembers(k), lhbMsg->getDistances(k));
01096 
01097             }
01098 
01099         }
01100         else {
01101 
01102             NicePeerInfo* pi = new NicePeerInfo(this);
01103 
01104             pi->set_last_HB_arrival(simTime().dbl());
01105 
01106             peerInfos.insert(std::make_pair(lhbMsg->getSrcNode(), pi));
01107 
01108         }
01109     }
01110 
01111     if (debug_heartbeats)
01112         EV << simTime() << " : " << thisNode.getIp() << " : handleNiceLeaderHeartbeat() finished.  " << endl;
01113 
01114     delete lhbMsg;
01115 }
01116 
01117 void Nice::handleNiceLeaderTransfer(NiceLeaderHeartbeat* transferMsg)
01118 {
01119 
01120     if (debug_heartbeats)
01121         EV << simTime() << " : " << thisNode.getIp() << " : NICE_LEADERTRANSFER from " << transferMsg->getSrcNode() << " for " << transferMsg->getLayer() << endl;
01122 
01123     if (!clusters[transferMsg->getLayer()].getLeader().isUnspecified()) {
01124 
01125         /* React only if I am not already leader */
01126         if (clusters[transferMsg->getLayer()].getLeader() != thisNode) {
01127 
01128             if (debug_heartbeats)
01129                 EV << "I am not already leader of this cluster layer." << endl;
01130 
01131             for (TaSet::iterator itn = clusters[transferMsg->getLayer()].begin(); itn != clusters[transferMsg->getLayer()].end(); ++itn) {
01132                 deleteOverlayNeighborArrow(*itn);
01133             }
01134             clusters[transferMsg->getLayer()].clear();
01135             clusters[transferMsg->getLayer()].add(thisNode);
01136             clusters[transferMsg->getLayer()].setLeader(thisNode);
01137 
01138             for (unsigned int i=0; i<transferMsg->getMembersArraySize(); i++) {
01139 
01140                 if (debug_heartbeats)
01141                     EV << "Adding: " << transferMsg->getMembers(i) << endl;
01142 
01143                 clusters[transferMsg->getLayer()].add(transferMsg->getMembers(i));
01144                 showOverlayNeighborArrow(transferMsg->getMembers(i), false, clusterarrows[transferMsg->getLayer()]);
01145 
01146                 std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(transferMsg->getMembers(i));
01147 
01148                 if (it != peerInfos.end()) {
01149 
01150                     /* We already know this node */
01151                     it->second->touch();
01152 
01153                 }
01154                 else {
01155 
01156                     //We don't know him yet
01157                     NicePeerInfo* pi = new NicePeerInfo(this);
01158 
01159                     pi->set_last_HB_arrival(simTime().dbl());
01160 
01161                     peerInfos.insert(std::make_pair(transferMsg->getMembers(i), pi));
01162 
01163                 }
01164 
01165             }
01166 
01167             if (transferMsg->getSupercluster_membersArraySize() > 0) {
01168 
01169                 for (TaSet::iterator itn = clusters[transferMsg->getLayer() + 1].begin(); itn != clusters[transferMsg->getLayer() + 1].end(); ++itn) {
01170                     deleteOverlayNeighborArrow(*itn);
01171                 }
01172                 clusters[transferMsg->getLayer()+1].clear();
01173 
01174                 for (unsigned int i=0; i<transferMsg->getSupercluster_membersArraySize(); i++) {
01175 
01176                     clusters[transferMsg->getLayer()+1].add(transferMsg->getSupercluster_members(i));
01177 
01178                     std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(transferMsg->getSupercluster_members(i));
01179 
01180                     if (it != peerInfos.end()) {
01181 
01182                         /* We already know this node */
01183                         it->second->touch();
01184 
01185                     }
01186                     else {
01187 
01188                         //We don't know him yet
01189                         NicePeerInfo* pi = new NicePeerInfo(this);
01190 
01191                         pi->set_last_HB_arrival(simTime().dbl());
01192 
01193                         peerInfos.insert(std::make_pair(transferMsg->getSupercluster_members(i), pi));
01194 
01195                     }
01196 
01197                 }
01198 
01199                 // experimental
01200                 clusters[transferMsg->getLayer()+1].add(thisNode);
01201 
01202                 if (!transferMsg->getSupercluster_leader().isUnspecified()) {
01203 
01204                     clusters[transferMsg->getLayer()+1].setLeader(transferMsg->getSupercluster_leader());
01205 
01206                     if ((clusters[transferMsg->getLayer()+1].getLeader() == thisNode) &&
01207                             (clusters[transferMsg->getLayer()+2].getSize() == 0)) {
01208 
01209                         for (unsigned int i=0; i<transferMsg->getSupercluster_membersArraySize(); i++) {
01210 
01211                             showOverlayNeighborArrow(transferMsg->getSupercluster_members(i), false, clusterarrows[transferMsg->getLayer()+1]);
01212 
01213                         }
01214 
01215                     }
01216                     else {
01217 
01218                         JoinCluster(transferMsg->getSupercluster_leader(), transferMsg->getLayer()+1);
01219 
01220                     }
01221 
01222                 }
01223 
01224             }
01225             else {
01226 
01227                 if (!isRendevouzPoint && RendevouzPoint != transferMsg->getSrcNode()) {
01228                     BasicJoinLayer(transferMsg->getLayer() + 1);
01229                 }
01230 
01231             }
01232 
01233             for (int i=0; i<maxLayers; i++) {
01234 
01235                 if (clusters[i].contains(thisNode))
01236                     getParentModule()->getParentModule()->getDisplayString().setTagArg("i2", 1, clustercolors[i]);
01237 
01238             }
01239 
01240             clusters[transferMsg->getLayer()].setLastLT();
01241 
01242 
01243         }
01244         else {
01245 
01246             for (unsigned int i=0; i<transferMsg->getMembersArraySize(); i++) {
01247 
01248                 if (debug_heartbeats)
01249                     EV << "Adding: " << transferMsg->getMembers(i) << endl;
01250 
01251                 clusters[transferMsg->getLayer()].add(transferMsg->getMembers(i));
01252                 showOverlayNeighborArrow(transferMsg->getMembers(i), false, clusterarrows[transferMsg->getLayer()]);
01253 
01254                 std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(transferMsg->getMembers(i));
01255 
01256                 if (it == peerInfos.end()) {
01257 
01258                     //We don't know him yet
01259                     NicePeerInfo* pi = new NicePeerInfo(this);
01260 
01261                     pi->set_last_HB_arrival(simTime().dbl());
01262 
01263                     peerInfos.insert(std::make_pair(transferMsg->getMembers(i), pi));
01264 
01265                 }
01266 
01267             }
01268 
01269         }
01270 
01271     }
01272 
01273     if (pimp)
01274         sendHeartbeats();
01275 
01276     if (debug_heartbeats)
01277         EV << simTime() << " : " << thisNode.getIp() << " : handleNiceLeaderTransfer() finished.  " << endl;
01278 
01279     delete transferMsg;
01280 }
01281 
01282 void Nice::handleNiceJoinCluster(NiceMessage* joinMsg)
01283 {
01284     if (debug_join)
01285         EV << simTime() << " : " << thisNode.getIp() << " : handleNiceJoinCluster()" << endl;
01286 
01287     short layer = joinMsg->getLayer();
01288 
01289     if (debug_join)
01290         std::cout << " From : " << joinMsg->getSrcNode() << ", Layer:  " << layer << endl;
01291 
01292     if (!clusters[layer].getLeader().isUnspecified()) {
01293 
01294         if (clusters[layer].getLeader() != thisNode) {
01295 
01296             if (pimp) {
01297 
01298                 NiceMessage* dup = static_cast<NiceMessage*>(joinMsg->dup());
01299                 sendMessageToUDP(clusters[layer].getLeader(), dup);
01300 
01301             }
01302 
01303         }
01304         else {
01305 
01306             RECORD_STATS(++numJoins);
01307 
01308             /* Add new node to cluster */
01309             clusters[layer].add(joinMsg->getSrcNode());
01310 
01311             /* Create peer context to joining node */
01312             /* Check if peer info already exists */
01313             std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(joinMsg->getSrcNode());
01314 
01315             if (it != peerInfos.end()) { /* We already know this node */
01316 
01317 
01318             }
01319             else { /* Create PeerInfo object */
01320 
01321                 NicePeerInfo* pi = new NicePeerInfo(this);
01322 
01323                 peerInfos.insert(std::make_pair(joinMsg->getSrcNode(), pi));
01324 
01325             }
01326 
01327             /* Draw arrow to new member */
01328             showOverlayNeighborArrow(joinMsg->getSrcNode(), false, clusterarrows[layer]);
01329 
01330             if (pimp)
01331                 sendHeartbeatTo(joinMsg->getSrcNode(), layer);
01332         }
01333 
01334     }
01335     else {
01336 
01337         if (debug_join)
01338             EV << "Leader unspecified. Ignoring request." << endl;
01339 
01340     }
01341 
01342     if (debug_join)
01343         EV << simTime() << " : " << thisNode.getIp() << " : handleNiceJoinCluster() finished." << endl;
01344 
01345     delete joinMsg;
01346 } // handleNiceJoinCluster
01347 
01348 void Nice::handleNiceJoineval(NiceMessage* msg)
01349 {
01350     NiceMessage* responseMsg = new NiceMessage("NICE_JOINEVAL_RESPONSE");
01351     responseMsg->setSrcNode(thisNode);
01352     responseMsg->setCommand(NICE_JOINEVAL_RESPONSE);
01353     responseMsg->setLayer(msg->getLayer());
01354 
01355     responseMsg->setBitLength(NICEMESSAGE_L(responseMsg));
01356 
01357     sendMessageToUDP(msg->getSrcNode(), responseMsg);
01358 
01359     delete msg;
01360 }
01361 
01362 void Nice::handleNiceJoinevalResponse(NiceMessage* msg)
01363 {
01364     if (evalLayer > 0 && evalLayer == msg->getLayer()) {
01365 
01366         query_compare = simTime() - query_compare;
01367 
01368         if (query_compare < query_start) {
01369 
01370             Query(msg->getSrcNode(), msg->getLayer()-1);
01371 
01372         }
01373         else {
01374 
01375             Query(tempResolver, msg->getLayer() - 1);
01376 
01377         }
01378 
01379         evalLayer = -1;
01380     }
01381 
01382     delete msg;
01383 }
01384 
01385 void Nice::handleNiceMulticast(NiceMulticastMessage* multicastMsg)
01386 {
01387     RECORD_STATS(++numReceived; totalReceivedBytes += multicastMsg->getByteLength());
01388 
01389     /* If it is mine, count */
01390     if (multicastMsg->getSrcNode() == thisNode) {
01391 
01392         RECORD_STATS(++numOwnMessagesReceived);
01393 
01394     }
01395     else {
01396 
01397         unsigned int hopCount = multicastMsg->getHopCount();
01398         hopCount++;
01399 
01400         if (hopCount < 8) {
01401 
01402             RECORD_STATS(++numForward; totalForwardBytes += multicastMsg->getByteLength());
01403 
01404             NiceMulticastMessage* forOverlay = static_cast<NiceMulticastMessage*>(multicastMsg->dup());
01405             forOverlay->setHopCount(hopCount);
01406             sendDataToOverlay(forOverlay);
01407 
01408             send(multicastMsg->decapsulate(), "appOut");
01409 
01410         }
01411     }
01412 
01413     delete multicastMsg;
01414 }
01415 
01416 void Nice::handleNicePeerTemporary(NiceMessage* msg)
01417 {
01418     // Add node to tempPeers
01419     tempPeers.insert(std::make_pair(msg->getSrcNode(), simTime()));
01420 
01421     delete msg;
01422 }
01423 
01424 void Nice::handleNicePeerTemporaryRelease(NiceMessage* msg)
01425 {
01426     // Remove node from tempPeers
01427     tempPeers.erase(msg->getSrcNode());
01428     deleteOverlayNeighborArrow(msg->getSrcNode());
01429 
01430     delete msg;
01431 }
01432 
01433 void Nice::handleNicePingProbe(NiceMessage* msg)
01434 {
01435     // Only answer if I am part of requested layer
01436     if (clusters[msg->getLayer()].contains(thisNode)) {
01437 
01438         NiceMessage* probe = new NiceMessage("NICE_PING_PROBE");
01439         probe->setSrcNode(thisNode);
01440         probe->setCommand(NICE_PING_PROBE_RESPONSE);
01441         probe->setLayer(msg->getLayer());
01442 
01443         probe->setBitLength(NICEMESSAGE_L(probe));
01444 
01445         sendMessageToUDP(msg->getSrcNode(), probe);
01446 
01447     }
01448     else {
01449 
01450         //Do nothing
01451 
01452     }
01453 
01454     delete msg;
01455 }
01456 
01457 void Nice::handleNicePingProbeResponse(NiceMessage* msg)
01458 {
01459     //Only react if still in same cluster as when asked
01460     if (msg->getLayer() == getHighestLayer()+1) {
01461 
01462         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(msg->getSrcNode());
01463 
01464         if (it != peerInfos.end()) {
01465 
01466             double distance = simTime().dbl() - it->second->getDES();
01467 
01468             it->second->set_distance(distance);
01469             it->second->touch();
01470 
01471         }
01472 
01473     }
01474 
01475     delete msg;
01476 }
01477 
01478 void Nice::handleNicePollRp(NiceMessage* msg)
01479 {
01480     if (isRendevouzPoint) {
01481 
01482         NiceMessage* response = new NiceMessage("NICE_POLL_RP_RESPONSE");
01483         response->setSrcNode(thisNode);
01484         response->setCommand(NICE_POLL_RP_RESPONSE);
01485         response->setLayer(getHighestLeaderLayer());
01486         response->setBitLength(NICEMESSAGE_L(response));
01487 
01488         sendMessageToUDP(msg->getSrcNode(), response);
01489 
01490     }
01491     delete msg;
01492 }
01493 
01494 void Nice::handleNicePollRpResponse(NiceMessage* msg)
01495 {
01496     if (!polledRendevouzPoint.isUnspecified() && polledRendevouzPoint == RendevouzPoint) {
01497 
01498         polledRendevouzPoint = TransportAddress::UNSPECIFIED_NODE;
01499         cancelEvent(rpPollTimer);
01500 
01501     }
01502 
01503     delete msg;
01504 }
01505 
01506 void Nice::handleNiceQueryResponse(NiceMemberMessage* queryRspMsg)
01507 {
01508 
01509     cancelEvent(queryTimer);
01510 
01511     short layer = queryRspMsg->getLayer();
01512 
01513     /* Check layer response */
01514     if (layer == targetLayer) {
01515 
01516         /* Use member information for own cluster update */
01517         for (unsigned int i = 0; i < queryRspMsg->getMembersArraySize(); i++) {
01518 
01519             clusters[layer].add(queryRspMsg->getMembers(i));
01520 
01521         }
01522 
01523         clusters[layer].add(queryRspMsg->getSrcNode());
01524 
01525         /* Initiate joining of lowest layer */
01526         JoinCluster(queryRspMsg->getSrcNode(), layer);
01527 
01528         changeState(READY);
01529 
01530     }
01531     else {
01532 
01533         /* Evaluate RTT to queried node */
01534         query_start = simTime() - query_start;
01535 
01536         /* Find out who is nearest cluster member in response, if nodes are given */
01537         if (queryRspMsg->getMembersArraySize() > 0) {
01538 
01539             NiceMessage* joineval = new NiceMessage("NICE_JOINEVAL");
01540             joineval->setSrcNode(thisNode);
01541             joineval->setCommand(NICE_JOINEVAL);
01542             joineval->setLayer(layer);
01543 
01544             joineval->setBitLength(NICEMESSAGE_L(joineval));
01545 
01546             /* Initiate evaluation with all cluster members */
01547             for (unsigned int i = 0; i < queryRspMsg->getMembersArraySize(); i++) {
01548 
01549                 NiceMessage* dup = static_cast<NiceMessage*>(joineval->dup());
01550 
01551                 sendMessageToUDP(queryRspMsg->getMembers(i), dup);
01552 
01553             }
01554 
01555             delete joineval;
01556 
01557         }
01558         else { // Directly query same node again for lower layer
01559 
01560             Query(queryRspMsg->getSrcNode(), queryRspMsg->getLayer()-1);
01561 
01562         }
01563 
01564         evalLayer = layer;
01565         query_compare = simTime();
01566 
01567     }
01568 
01569     delete queryRspMsg;
01570 } // handleNiceQueryResponse
01571 
01572 void Nice::handleNiceRemove(NiceMessage* msg)
01573 {
01574     if (debug_removes)
01575         EV << simTime() << " : " << thisNode.getIp() << " : NICE_REMOVE" << endl;
01576 
01577     if (msg->getSrcNode() == thisNode) {
01578         if (debug_removes)
01579             EV << simTime() << " : " << thisNode.getIp() << " : received remove from self. Disregard.";
01580         delete msg;
01581         return;
01582     }
01583 
01584     short layer = msg->getLayer();
01585 
01586     if (pimp) {
01587         if (!clusters[layer].getLeader().isUnspecified()) {
01588             if (clusters[layer].getLeader() != thisNode && (clusters[layer].getLeader() != msg->getSrcNode())) {
01589 
01590                 NiceMessage* dup = static_cast<NiceMessage*>(msg->dup());
01591                 sendMessageToUDP(clusters[layer].getLeader(), dup);
01592                 delete msg;
01593                 return;
01594             }
01595         }
01596     }
01597 
01598     if (debug_removes)
01599         EV << simTime() << " : " << thisNode.getIp() << " : removing " << msg->getSrcNode() << " from layer " << layer << endl;
01600 
01601     if (!clusters[msg->getLayer()].getLeader().isUnspecified()) {
01602 
01603         if (clusters[msg->getLayer()].getLeader() == thisNode) {
01604 
01605             // check prevents visualization arrows to be deleted by error
01606             if (clusters[msg->getLayer()].contains(msg->getSrcNode())) {
01607 
01608                 clusters[msg->getLayer()].remove(msg->getSrcNode());
01609                 deleteOverlayNeighborArrow(msg->getSrcNode());
01610                 updateVisualization();
01611 
01612             }
01613 
01614         }
01615     }
01616 
01617     if (debug_removes)
01618         EV << simTime() << " : " << thisNode.getIp() << " : NICE_REMOVE finished." << endl;
01619 
01620     delete msg;
01621 }
01622 
01623 /* End handlers for NICE messages */
01624 
01625 /******************************************************************************
01626  * getHighestLeaderLayer
01627  */
01628 int Nice::getHighestLeaderLayer()
01629 {
01630     int layer = getHighestLayer();
01631     if (!clusters[layer].getLeader().isUnspecified() && clusters[layer].getLeader() == thisNode) {
01632         return layer;
01633     }
01634     else if (layer == -1) {
01635         return -1;
01636     }
01637     else {
01638         return layer - 1;
01639     }
01640 } // getHighestLeaderLayer
01641 
01642 int Nice::getHighestLayer()
01643 {
01644     if (clusters[0].getSize() == 0) {
01645         // Not yet joined to overlay
01646         return -1;
01647     }
01648 
01649     int highest = 0;
01650 
01651     while (highest < maxLayers &&
01652            !clusters[highest].getLeader().isUnspecified() &&
01653            clusters[highest].getLeader() == thisNode) {
01654         ++highest;
01655     }
01656 
01657     if (highest == maxLayers) {
01658         // we are top leader
01659         return maxLayers - 1;
01660     }
01661     else if (!clusters[highest].contains(thisNode)) {
01662         // we are top leader. highest is one plus our layer.
01663         return highest - 1;
01664     }
01665     else {
01666         return highest;
01667     }
01668 } // getHighestLayer
01669 
01670 void Nice::JoinCluster(const TransportAddress& leader, short layer)
01671 {
01672 
01673     if (debug_join)
01674         EV << simTime() << " : " << thisNode.getIp() << " : JoinCluster()" << endl;
01675 
01676     NiceMessage* msg = new NiceMessage("NICE_JOIN_CLUSTER");
01677     msg->setSrcNode(thisNode);
01678     msg->setCommand(NICE_JOIN_CLUSTER);
01679     msg->setLayer(layer);
01680     msg->setBitLength(NICEMESSAGE_L(msg));
01681 
01682     sendMessageToUDP(leader, msg);
01683 
01684     /* Create peer context to leader */
01685     /* Check if peer info already exists */
01686     std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(leader);
01687 
01688     if (it != peerInfos.end()) { /* We already know this node */
01689 
01690     }
01691     else { /* Create PeerInfo object */
01692 
01693         NicePeerInfo* pi = new NicePeerInfo(this);
01694 
01695         peerInfos.insert(std::make_pair(leader, pi));
01696 
01697     }
01698 
01699     /* Locally add thisNode, too */
01700     clusters[layer].add(thisNode);
01701 
01702     /* Set leader for cluster */
01703     clusters[layer].add(leader);
01704     clusters[layer].setLeader(leader);
01705 
01706     for (short i=0; i<maxLayers; i++) {
01707 
01708         if (clusters[i].getSize() > 0) {
01709 
01710             if (clusters[i].contains(thisNode)) {
01711 
01712                 getParentModule()->getParentModule()->getDisplayString().setTagArg
01713                 ("i2", 1, clustercolors[i]);
01714 
01715             }
01716 
01717         }
01718 
01719     }
01720 
01721     // If not already running, schedule some timers
01722     if (!heartbeatTimer->isScheduled()) {
01723 
01724         scheduleAt(simTime() + heartbeatInterval, heartbeatTimer);
01725 
01726     }
01727     if (!maintenanceTimer->isScheduled()) {
01728 
01729         scheduleAt(simTime() + heartbeatInterval, maintenanceTimer);
01730 
01731     }
01732 
01733     if (isTempPeered) {
01734 
01735         // Release temporary peering
01736         NiceMessage* msg = new NiceMessage("NICE_PEER_TEMPORARY_RELEASE");
01737         msg->setSrcNode(thisNode);
01738         msg->setCommand(NICE_PEER_TEMPORARY_RELEASE);
01739         msg->setLayer(-1);
01740         msg->setBitLength(NICEMESSAGE_L(msg));
01741 
01742         sendMessageToUDP(RendevouzPoint, msg);
01743 
01744         isTempPeered = false;
01745 
01746     }
01747 
01748     if (debug_join)
01749         EV << simTime() << " : " << thisNode.getIp() << " : JoinCluster() finished." << endl;
01750 
01751 } // JoinCluster
01752 
01753 
01754 /******************************************************************************
01755  * sendHeartbeats
01756  */
01757 void Nice::sendHeartbeats()
01758 {
01759 
01760     /* Go through all cluster layers from top to bottom */
01761 
01762     for (int i=getHighestLayer(); i >= 0; i--) {
01763 
01764         /* Determine if node is cluster leader in this layer */
01765         if (!clusters[i].getLeader().isUnspecified()) {
01766 
01767             if (clusters[i].getLeader() == thisNode) {
01768                 clusters[i].confirmLeader();
01769 
01770                 /* Build heartbeat message with info on all current members */
01771                 NiceLeaderHeartbeat* msg = new NiceLeaderHeartbeat("NICE_LEADERHEARTBEAT");
01772                 msg->setSrcNode(thisNode);
01773                 msg->setCommand(NICE_LEADERHEARTBEAT);
01774                 msg->setLayer(i);
01775                 msg->setOne_hop_distance(simTime().dbl());
01776                 msg->setK(k);
01777                 msg->setSc_tolerance(SC_PROC_DISTANCE);
01778 
01779                 msg->setMembersArraySize(clusters[i].getSize());
01780 
01781                 /* Fill in members */
01782                 for (int j = 0; j < clusters[i].getSize(); j++) {
01783 
01784                     msg->setMembers(j, clusters[i].get(j));
01785 
01786                 }
01787 
01788                 /* Fill in distances to members */
01789                 msg->setDistancesArraySize(clusters[i].getSize());
01790 
01791                 for (int j = 0; j < clusters[i].getSize(); j++) {
01792 
01793                     std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[i].get(j));
01794 
01795                     if (it != peerInfos.end()) {
01796 
01797                         msg->setDistances(j, it->second->get_distance());
01798 
01799                     }
01800                     else {
01801 
01802                         msg->setDistances(j, -1);
01803 
01804                     }
01805 
01806                 }
01807 
01808                 /* Fill in Supercluster members, if existent */
01809                 if (clusters[i+1].getSize() > 0) {
01810 
01811                     msg->setSupercluster_leader(clusters[i+1].getLeader());
01812 
01813                     msg->setSupercluster_membersArraySize(clusters[i+1].getSize());
01814 
01815                     for (int j = 0; j < clusters[i+1].getSize(); j++) {
01816 
01817                         msg->setSupercluster_members(j, clusters[i+1].get(j));
01818 
01819                     }
01820 
01821                 }
01822 
01823                 /* Send Heartbeat to all members in cluster, except me */
01824                 for (int j = 0; j < clusters[i].getSize(); j++) {
01825 
01826                     if (clusters[i].get(j) != thisNode) {
01827 
01828                         NiceLeaderHeartbeat *copy = static_cast<NiceLeaderHeartbeat*>(msg->dup());
01829 
01830                         /* Get corresponding sequence numbers out of peerInfo */
01831                         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[i].get(j));
01832 
01833                         if (it != peerInfos.end()) {
01834 
01835                             unsigned int seqNo = it->second->get_last_sent_HB();
01836 
01837                             copy->setSeqNo(++seqNo);
01838 
01839                             it->second->set_backHB(it->second->get_backHBPointer(), seqNo, simTime().dbl());
01840                             it->second->set_last_sent_HB(seqNo);
01841                             it->second->set_backHBPointer(!it->second->get_backHBPointer());
01842 
01843                             copy->setSeqRspNo(it->second->get_last_recv_HB());
01844 
01845                             if (it->second->get_last_HB_arrival() > 0) {
01846 
01847                                 copy->setHb_delay(simTime().dbl() - it->second->get_last_HB_arrival());
01848 
01849                             }
01850                             else {
01851 
01852                                 copy->setHb_delay(0.0);
01853 
01854                             }
01855 
01856                         }
01857 
01858                         copy->setBitLength(NICELEADERHEARTBEAT_L(msg));
01859 
01860                         RECORD_STATS(++numHeartbeat; totalHeartbeatBytes += copy->getByteLength());
01861 
01862                         sendMessageToUDP(clusters[i].get(j), copy);
01863 
01864                     }
01865 
01866                 }
01867 
01868                 delete msg;
01869 
01870             }
01871             else { // I am normal cluster member
01872 
01873                 /* Build heartbeat message with info on all current members */
01874                 NiceHeartbeat* msg = new NiceHeartbeat("NICE_HEARTBEAT");
01875                 msg->setSrcNode(thisNode);
01876                 msg->setCommand(NICE_HEARTBEAT);
01877                 msg->setLayer(i);
01878                 msg->setOne_hop_distance(simTime().dbl());
01879 
01880                 msg->setSublayermembers(0);
01881                 if (i>0) {
01882                     if (clusters[i-1].getLeader() == thisNode)
01883                         msg->setSublayermembers(clusters[i-1].getSize());
01884 
01885                 }
01886 
01887                 msg->setMembersArraySize(clusters[i].getSize());
01888 
01889                 /* Fill in members */
01890                 for (int j = 0; j < clusters[i].getSize(); j++) {
01891 
01892                     msg->setMembers(j, clusters[i].get(j));
01893 
01894                 }
01895 
01896                 /* Fill in distances to members */
01897                 msg->setDistancesArraySize(clusters[i].getSize());
01898 
01899                 for (int j = 0; j < clusters[i].getSize(); j++) {
01900 
01901                     std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[i].get(j));
01902 
01903                     if (it != peerInfos.end()) {
01904 
01905                         msg->setDistances(j, it->second->get_distance());
01906 
01907                     }
01908                     else {
01909 
01910                         msg->setDistances(j, -1);
01911 
01912                     }
01913 
01914                 }
01915 
01916                 /* Send Heartbeat to all members in cluster, except me */
01917                 for (int j = 0; j < clusters[i].getSize(); j++) {
01918 
01919                     if (clusters[i].get(j) != thisNode) {
01920 
01921                         NiceHeartbeat *copy = static_cast<NiceHeartbeat*>(msg->dup());
01922 
01923                         /* Get corresponding sequence number out of peerInfo */
01924                         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[i].get(j));
01925 
01926                         if (it != peerInfos.end()) {
01927 
01928                             unsigned int seqNo = it->second->get_last_sent_HB();
01929 
01930                             copy->setSeqNo(++seqNo);
01931 
01932                             it->second->set_backHB(it->second->get_backHBPointer(), seqNo, simTime().dbl());
01933                             it->second->set_backHBPointer(!it->second->get_backHBPointer());
01934                             it->second->set_last_sent_HB(seqNo);
01935 
01936                             copy->setSeqRspNo(it->second->get_last_recv_HB());
01937 
01938                             copy->setHb_delay(simTime().dbl() - it->second->get_last_HB_arrival());
01939 
01940                         }
01941 
01942                         copy->setBitLength(NICEHEARTBEAT_L(msg));
01943 
01944                         RECORD_STATS(++numHeartbeat; totalHeartbeatBytes += copy->getByteLength());
01945 
01946                         sendMessageToUDP(clusters[i].get(j), copy);
01947 
01948                     }
01949 
01950                 }
01951 
01952                 delete msg;
01953 
01954             }
01955         }
01956 
01957     }
01958 
01959     // Additionally, ping all supercluster members, if existent
01960     if (clusters[getHighestLayer()+1].getSize() > 0 && !clusters[getHighestLayer()].getLeader().isUnspecified()) {
01961 
01962         NiceMessage* msg = new NiceMessage("NICE_PING_PROBE");
01963         msg->setSrcNode(thisNode);
01964         msg->setCommand(NICE_PING_PROBE);
01965         msg->setLayer(getHighestLayer()+1);
01966 
01967         msg->setBitLength(NICEMESSAGE_L(msg));
01968 
01969         for (int i=0; i<clusters[getHighestLayer()+1].getSize(); i++) {
01970 
01971             if (clusters[getHighestLayer()+1].get(i) != clusters[getHighestLayer()].getLeader()) {
01972 
01973                 NiceMessage* dup = static_cast<NiceMessage*>(msg->dup());
01974 
01975                 sendMessageToUDP(clusters[getHighestLayer()+1].get(i), dup);
01976 
01977                 std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[getHighestLayer()+1].get(i));
01978 
01979                 if (it != peerInfos.end()) {
01980 
01981                     it->second->set_distance_estimation_start(simTime().dbl());
01982 
01983                 }
01984 
01985             }
01986 
01987         }
01988 
01989         delete msg;
01990 
01991     }
01992 
01993 } // sendHeartbeats
01994 
01995 
01996 /******************************************************************************
01997  * sendHeartbeatTo
01998  */
01999 void Nice::sendHeartbeatTo(const TransportAddress& node, int layer)
02000 {
02001 
02002     if (clusters[layer].getLeader() == thisNode) {
02003 
02004         /* Build heartbeat message with info on all current members */
02005         NiceLeaderHeartbeat* msg = new NiceLeaderHeartbeat("NICE_LEADERHEARTBEAT");
02006         msg->setSrcNode(thisNode);
02007         msg->setCommand(NICE_LEADERHEARTBEAT);
02008         msg->setLayer(layer);
02009 
02010         msg->setMembersArraySize(clusters[layer].getSize());
02011 
02012         /* Fill in members */
02013         for (int j = 0; j < clusters[layer].getSize(); j++) {
02014 
02015             msg->setMembers(j, clusters[layer].get(j));
02016 
02017         }
02018 
02019         /* Fill in distances to members */
02020         msg->setDistancesArraySize(clusters[layer].getSize());
02021 
02022         for (int j = 0; j < clusters[layer].getSize(); j++) {
02023 
02024             std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[layer].get(j));
02025 
02026             if (it != peerInfos.end()) {
02027 
02028                 msg->setDistances(j, it->second->get_distance());
02029 
02030             }
02031             else {
02032 
02033                 msg->setDistances(j, -1);
02034 
02035             }
02036 
02037         }
02038 
02039         /* Fill in Supercluster members, if existent */
02040         if (clusters[layer+1].getSize() > 0) {
02041 
02042             msg->setSupercluster_leader(clusters[layer+1].getLeader());
02043 
02044             msg->setSupercluster_membersArraySize(clusters[layer+1].getSize());
02045 
02046             for (int j = 0; j < clusters[layer+1].getSize(); j++) {
02047 
02048                 msg->setSupercluster_members(j, clusters[layer+1].get(j));
02049 
02050             }
02051 
02052         }
02053 
02054         /* Get corresponding sequence numbers out of peerInfo */
02055         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(node);
02056 
02057         if (it != peerInfos.end()) {
02058 
02059             unsigned int seqNo = it->second->get_last_sent_HB();
02060 
02061             msg->setSeqNo(++seqNo);
02062 
02063             it->second->set_backHB(it->second->get_backHBPointer(), seqNo, simTime().dbl());
02064             it->second->set_last_sent_HB(seqNo);
02065             it->second->set_backHBPointer(!it->second->get_backHBPointer());
02066 
02067             msg->setSeqRspNo(it->second->get_last_recv_HB());
02068 
02069             msg->setHb_delay(simTime().dbl() - it->second->get_last_HB_arrival());
02070 
02071         }
02072 
02073         msg->setBitLength(NICELEADERHEARTBEAT_L(msg));
02074 
02075         RECORD_STATS(++numHeartbeat; totalHeartbeatBytes += msg->getByteLength());
02076 
02077         sendMessageToUDP(node, msg);
02078 
02079     }
02080     else {
02081 
02082         // build heartbeat message with info on all current members
02083         NiceHeartbeat* msg = new NiceHeartbeat("NICE_HEARTBEAT");
02084         msg->setSrcNode(thisNode);
02085         msg->setCommand(NICE_HEARTBEAT);
02086         msg->setLayer(layer);
02087 
02088         msg->setMembersArraySize(clusters[layer].getSize());
02089 
02090         // fill in members
02091         for (int j = 0; j < clusters[layer].getSize(); j++) {
02092 
02093             msg->setMembers(j, clusters[layer].get(j));
02094 
02095         }
02096 
02097         // fill in distances to members
02098         msg->setDistancesArraySize(clusters[layer].getSize());
02099 
02100         for (int j = 0; j < clusters[layer].getSize(); j++) {
02101 
02102             std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[layer].get(j));
02103 
02104             if (it != peerInfos.end()) {
02105 
02106                 msg->setDistances(j, it->second->get_distance());
02107 
02108             }
02109             else if (clusters[layer].get(j) == thisNode) {
02110 
02111                 msg->setDistances(j, 0);
02112 
02113             }
02114             else {
02115 
02116                 msg->setDistances(j, -1);
02117 
02118             }
02119 
02120         }
02121 
02122         msg->setBitLength(NICEHEARTBEAT_L(msg));
02123 
02124         RECORD_STATS(++numHeartbeat; totalHeartbeatBytes += msg->getByteLength());
02125 
02126         sendMessageToUDP(node, msg);
02127 
02128     }
02129 
02130 } // sendHeartbeatTo
02131 
02135 void Nice::sendRemoveTo(const TransportAddress& node, int layer)
02136 {
02137     NiceMessage* msg = new NiceMessage("NICE_REMOVE");
02138     msg->setSrcNode(thisNode);
02139     msg->setCommand(NICE_REMOVE);
02140     msg->setLayer(layer);
02141 
02142     msg->setBitLength(NICEMESSAGE_L(msg));
02143 
02144     sendMessageToUDP(node, msg);
02145 } // sendRemoveTo
02146 
02150 void Nice::cleanPeers()
02151 {
02152     // Clean tempPeers
02153     std::vector<TransportAddress> deadTempPeers;
02154     
02155     std::map<TransportAddress, simtime_t>::iterator itTempPeer;
02156     for (itTempPeer = tempPeers.begin(); itTempPeer != tempPeers.end(); ++itTempPeer) {
02157         if (simTime() > (itTempPeer->second + 3 * heartbeatInterval)) {
02158             RECORD_STATS(++numTempPeerTimeouts);
02159             deadTempPeers.push_back(itTempPeer->first);
02160         }
02161     }
02162 
02163     std::vector<TransportAddress>::iterator itDead;
02164     for (itDead = deadTempPeers.begin(); itDead != deadTempPeers.end(); ++itDead) {
02165         tempPeers.erase(*itDead);
02166         deleteOverlayNeighborArrow(*itDead);
02167     }
02168 
02169     /* Delete nodes that haven't been active for too long autonomously */
02170     std::vector<TransportAddress> deadPeers;
02171 
02172     std::map<TransportAddress, NicePeerInfo*>::iterator itPeer = peerInfos.begin();
02173     while (itPeer != peerInfos.end()) {
02174 
02175         double offset = peerTimeoutHeartbeats * heartbeatInterval.dbl();
02176         if (itPeer->first != thisNode && simTime() > (itPeer->second->getActivity() + offset)) {
02177 
02178             if (debug_peertimeouts) {
02179                 EV << simTime() << " : " << thisNode.getIp() << " : PEER TIMED OUT! : " << itPeer->first << endl;
02180                 EV << "Activity : " << itPeer->second->getActivity() << endl;
02181             }
02182 
02183             RECORD_STATS(++numPeerTimeouts);
02184 
02185             deadPeers.push_back(itPeer->first);
02186 
02187         }
02188 
02189         ++itPeer;
02190 
02191     }
02192 
02193     for (itDead = deadPeers.begin(); itDead != deadPeers.end(); ++itDead) {
02194         delete peerInfos[*itDead];
02195         peerInfos.erase(*itDead);
02196 
02197         // Delete nodes from all layer clusters
02198         for (int i = 0; i < maxLayers; i++) {
02199             clusters[i].remove(*itDead);
02200             deleteOverlayNeighborArrow(*itDead);
02201         }
02202     }
02203 } // cleanPeers
02204 
02208 bool Nice::splitNeeded()
02209 {
02210     bool splitMade = false;
02211     // Check if cluster split is necessary
02212     // Find lowest layer that needs splitting and split it. If we're still cluster leader, continue up.
02213     for (int i = 0, highest = std::min(getHighestLeaderLayer(), maxLayers - 2);
02214             i <= highest && !clusters[i].getLeader().isUnspecified() && clusters[i].getLeader() == thisNode;
02215             ++i) {
02216         if (clusters[i].getSize() > 3 * k + 1 &&
02217                 clusters[i].isLeaderConfirmed() &&
02218                 (i == maxLayers - 1 || clusters[i + 1].getSize() == 0 || clusters[i + 1].isLeaderConfirmed())) {
02219             splitMade = true;
02220             ClusterSplit(i);
02221         }
02222     }
02223     return splitMade;
02224 } // splitNeeded
02225 
02229 bool Nice::mergeNeeded()
02230 {
02231     if (isRendevouzPoint) {
02232         // The Rendevouz Point can't initiate a merge, since that would
02233         // compromise its status as a Rendevouz Point.
02234         return false;
02235     }
02236 
02237     // The layer at which we must merge
02238     int mergeLayer;
02239     int highestLeaderLayer = getHighestLeaderLayer();
02240     
02241     // Find lowest layer that needs merging.
02242     // The node will disappear from all higher layers.
02243     for (mergeLayer= 0; mergeLayer <= highestLeaderLayer && mergeLayer < maxLayers - 1; ++mergeLayer) {
02244         /* Do not attempt merging if we're not sure we belong as leader */
02245         if (clusters[mergeLayer].getSize() < k && clusters[mergeLayer].isLeaderConfirmed() &&
02246                 clusters[mergeLayer + 1].isLeaderConfirmed()) {
02247             ClusterMerge(mergeLayer);
02248 
02249             // The merge may fail, check if it did.
02250             // If it really did, we should try to see if there's some other layer that we may merge.
02251             if (!clusters[mergeLayer + 1].contains(thisNode)) {
02252                 return true;
02253             }
02254         }
02255     }
02256     
02257     return false;
02258 }
02259 
02263 bool Nice::checkLeaderHeartbeatsForCollisions(NiceLeaderHeartbeat* hbMsg)
02264 {
02265 
02266     bool collisionDetected = false;
02267 
02268     //Alternative Detection
02269     leaderHeartbeats.push_back(std::make_pair(hbMsg->getSrcNode(), simTime()));
02270 
02271     if (leaderHeartbeats.size() > 3) {
02272 
02273         if (debug_heartbeats)
02274             EV << simTime() << "leaderHeartbeats.size() > 3 :  " << leaderHeartbeats.size() << endl;
02275 
02276         simtime_t predecessor =  leaderHeartbeats.at(leaderHeartbeats.size()-2).second;
02277 
02278         if (debug_heartbeats)
02279             EV << simTime() << "predecessor :  " << predecessor << endl;
02280 
02281 
02282         if (simTime() < (predecessor + heartbeatInterval)) {
02283 
02284             if (debug_heartbeats)
02285                 EV << simTime() << "simTime() < (predecessor + heartbeatInterval)" << endl;
02286 
02287             if (leaderHeartbeats.at(leaderHeartbeats.size()-2).first != hbMsg->getSrcNode()) {
02288 
02289                 if (debug_heartbeats) {
02290                     EV << simTime() << "(leaderHeartbeats.at(leaderHeartbeats.size()-2).first != hbMsg->getSrcNode())" << endl;
02291                     EV << "leaderHeartbeats.at(leaderHeartbeats.size()-2).first: " << leaderHeartbeats.at(leaderHeartbeats.size()-2).first << endl;
02292                 }
02293 
02294                 if (leaderHeartbeats.at(leaderHeartbeats.size()-3).first == hbMsg->getSrcNode()) {
02295 
02296                     if (debug_heartbeats) {
02297                         EV << simTime() << "(leaderHeartbeats.at(leaderHeartbeats.size()-3).first == hbMsg->getSrcNode())" << endl;
02298                         EV << "leaderHeartbeats.at(leaderHeartbeats.size()-3).first: " << leaderHeartbeats.at(leaderHeartbeats.size()-3).first << endl;
02299                         EV << "timestamp: " << leaderHeartbeats.at(leaderHeartbeats.size()-3).second << endl;
02300                     }
02301 
02302                     if (leaderHeartbeats.at(leaderHeartbeats.size()-4).first == leaderHeartbeats.at(leaderHeartbeats.size()-2).first) {
02303 
02304                         if (debug_heartbeats) {
02305                             EV << simTime() << "(leaderHeartbeats.at(leaderHeartbeats.size()-4).first == leaderHeartbeats.at(leaderHeartbeats.size()-2).first" << endl;
02306                             EV << "leaderHeartbeats.at(leaderHeartbeats.size()-4).first: " << leaderHeartbeats.at(leaderHeartbeats.size()-4).first << endl;
02307                             EV << "timestamp: " << leaderHeartbeats.at(leaderHeartbeats.size()-4).second << endl;
02308 
02309                         }
02310 
02311                         if (debug_heartbeats)
02312                             EV << simTime() << " : " << thisNode.getIp() << " : CONFLICTING LEADERS!" << endl;
02313 
02314                         NiceMessage* removeMsg = new NiceMessage("NICE_REMOVE");
02315                         removeMsg->setSrcNode(thisNode);
02316                         removeMsg->setCommand(NICE_REMOVE);
02317                         removeMsg->setLayer(hbMsg->getLayer());
02318 
02319                         removeMsg->setBitLength(NICEMESSAGE_L(removeMsg));
02320 
02321                         sendMessageToUDP(leaderHeartbeats.at(leaderHeartbeats.size()-2).first, removeMsg);
02322 
02323                         collisionDetected = true;
02324 
02325                     }
02326 
02327                 }
02328 
02329             }
02330         }
02331 
02332     }
02333 
02334 
02335     /* Tidy up leaderheartbeats */
02336     if (leaderHeartbeats.size() > 4) {
02337 
02338         for (unsigned int i=0; i<(leaderHeartbeats.size()-4); i++) {
02339 
02340             leaderHeartbeats.erase(leaderHeartbeats.begin());
02341 
02342         }
02343 
02344     }
02345 
02346     return collisionDetected;
02347 }
02348 
02349 /******************************************************************************
02350  * maintenance
02351  */
02352 void Nice::maintenance()
02353 {
02354     // care for structure connection timer
02355     if (RendevouzPoint.isUnspecified()) {
02356 
02357         EV << "No RendevouzPoint! " << endl;
02358 
02359     }
02360 
02361     int highestLayer = getHighestLayer();
02362     bool leaderDied = false;
02363     clusters[highestLayer].isLeaderConfirmed();
02364     TransportAddress newLeader;
02365     TransportAddress oldLeader = clusters[highestLayer].getLeader();
02366     cleanPeers();
02367     // Cluster Leader died. Select new. If the old leader is unspecified, then we're
02368     // probably waiting to join the layer.
02369     if (clusters[highestLayer].getLeader().isUnspecified() && !oldLeader.isUnspecified()) {
02370         leaderDied = true;
02371         RECORD_STATS(++numStructurePartitions; ++numInconsistencies);
02372         newLeader = findCenter(clusters[highestLayer]).first;
02373     }
02374 
02375     splitNeeded();
02376     mergeNeeded();
02377 
02378     if (leaderDied && RendevouzPoint != oldLeader) {
02379         clusters[highestLayer].setLeader(newLeader);
02380         if (newLeader == thisNode) {
02381             clusters[highestLayer + 1].add(newLeader);
02382             BasicJoinLayer(highestLayer + 1);
02383         }
02384         else {
02385             LeaderTransfer(highestLayer, newLeader);
02386         }
02387     }
02388     else if (getHighestLayer() == getHighestLeaderLayer()) {
02389         if (!isRendevouzPoint) {
02390             pollRP(-1);
02391             BasicJoinLayer(getHighestLayer() + 1);
02392         }
02393     }
02394 
02395     highestLayer = getHighestLayer();
02396     for (int i = highestLayer + 1; i < maxLayers; ++i) {
02397         if (clusters[i].getSize() != 0) {
02398             EV << "Stale data for cluster " << i << endl;
02399             for (TaSet::iterator itn = clusters[i].begin(); itn != clusters[i].end(); ++itn) {
02400                 deleteOverlayNeighborArrow(*itn);
02401             }
02402             clusters[i].clear();
02403         }
02404     }
02405 
02406     // if highest super cluster has more than one member, try to find a closer leader.
02407     // However, the Rendevouz Point must can't move between clusters.
02408     if (!isRendevouzPoint && highestLayer < maxLayers - 1 && clusters[highestLayer + 1].getSize() > 1) {
02409 
02410         if (clusterrefinement)
02411             EV << simTime() << " : " << thisNode.getIp() << " : Look for better parent node in cluster : " << highestLayer + 1 << " ..."<< endl;
02412 
02413         TransportAddress highestLeader = clusters[highestLayer].getLeader();
02414         std::map<TransportAddress, NicePeerInfo*>::iterator it;
02415         if (!highestLeader.isUnspecified()) {
02416             it = peerInfos.find(highestLeader);
02417         }
02418         else {
02419             it = peerInfos.end();
02420         }
02421 
02422         if (it != peerInfos.end() && it->second->get_distance() > 0) {
02423 
02424             double distance = it->second->get_distance() - ((it->second->get_distance()/100.0) * SC_PROC_DISTANCE);
02425 
02426             double smallest = 10000.0;
02427             TransportAddress candidate = TransportAddress::UNSPECIFIED_NODE;
02428 
02429             for (int i=0; i < clusters[highestLayer+1].getSize(); i++) {
02430 
02431                 if (clusters[highestLayer+1].get(i) != clusters[highestLayer].getLeader()) {
02432 
02433                     std::map<TransportAddress, NicePeerInfo*>::iterator it2 = peerInfos.find(clusters[highestLayer+1].get(i));
02434 
02435                     if (it2 != peerInfos.end()) {
02436 
02437                         if ((it2->second->get_distance() < smallest) && (it2->second->get_distance() > 0)) {
02438                             smallest = it2->second->get_distance();
02439                             candidate = it2->first;
02440                         }
02441 
02442                     }
02443 
02444                 }
02445 
02446             }
02447 
02448             std::set<TransportAddress> clusterset;
02449 
02450             for (int m=0; m<clusters[getHighestLayer()+1].getSize(); m++) {
02451 
02452                 clusterset.insert(clusters[getHighestLayer()+1].get(m));
02453 
02454             }
02455 
02456             simtime_t meanDistance = getMeanDistance(clusterset);
02457 
02458             simtime_t minCompare = (meanDistance/100.0)*SC_MIN_OFFSET;
02459 
02460             RECORD_STATS(totalSCMinCompare += minCompare.dbl());
02461 
02462             if (minCompare < 0.005)
02463                 minCompare = 0.005;
02464 
02465             if ((smallest < distance) && ((distance - smallest) > minCompare.dbl())) { // change supercluster
02466 
02467 
02468                 if (clusterrefinement) {
02469                     EV << simTime() <<" : " << thisNode.getIp() << ": Change SuperCluster! to " << candidate.getIp() << endl;
02470                     EV << "Old distance ():  " << it->second->get_distance() << endl;
02471                     EV << "SC_PROC_DISTANCE:  " << SC_PROC_DISTANCE << endl;
02472                     EV << "Compare distance:  " << distance << endl;
02473                     EV << "New distance:  " << smallest << endl;
02474                     EV << "New SC_MIN_OFFSET:  " << SC_MIN_OFFSET << endl;
02475                 }
02476 
02477                 // leave old
02478                 Remove(highestLayer);
02479 
02480                 // join new
02481                 JoinCluster(candidate, highestLayer);
02482 
02483                 return;
02484 
02485             }
02486         }
02487         else {
02488 
02489             //Do nothing
02490 
02491         }
02492 
02493     }
02494 
02495     if (!isRendevouzPoint) {
02496 
02497         // Try to find better leader.
02498         for (int i = getHighestLeaderLayer(); i >= 0; i--) {
02499 
02500             if (clusters[i].getSize() > 1 && clusters[i].isLeaderConfirmed()) {
02501 
02502                 bool allDistancesKnown = true;
02503 
02504                 if (clusterrefinement)
02505                     EV << simTime() << " : " << thisNode.getIp() << " : Find better cluster leader in ..." << i << endl;
02506 
02507                 /* Only make decisions if node has total distance knowledge in this cluster */
02508                 for (int j = 0; j < clusters[i].getSize() && allDistancesKnown; j++) {
02509 
02510                     /* Check if peer info already exists */
02511                     std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[i].get(j));
02512 
02513                     if (it != peerInfos.end()) {
02514 
02515                         simtime_t distance = it->second->get_distance();
02516 
02517                         //EV << "My distance to " << it->first << " : " << distance << endl;
02518 
02519                         if (distance < 0) {
02520                             allDistancesKnown = false;
02521                             continue;
02522                         }
02523 
02524                         for (int k = 0; k < clusters[i].getSize(); k++) {
02525 
02526                             if ((it->first != thisNode) && (clusters[i].get(k) != it->first)) {
02527 
02528                                 if (it->second->getDistanceTo(clusters[i].get(k)) < 0) {
02529                                     allDistancesKnown = false;
02530                                     break;
02531                                 }
02532                             }
02533 
02534                         }
02535 
02536                     }
02537                     else {
02538 
02539                         allDistancesKnown = false;
02540 
02541                     }
02542 
02543                 }
02544 
02545                 if (allDistancesKnown) {
02546 
02547                     if (clusterrefinement)
02548                         EV << "Complete distance knowledge available." << endl;
02549 
02550                     // Perform check for better cluster leader
02551                     TransportAddress new_leader = findCenter(clusters[i]).first;
02552 
02553                     if (clusterrefinement)
02554                         EV << "NEW LEADER laut " << thisNode.getIp() << " --> " << new_leader.getIp() << endl;
02555 
02556                     std::set<TransportAddress> clusterset;
02557 
02558                     for (int m=0; m<clusters[i].getSize(); m++) {
02559 
02560                         clusterset.insert(clusters[i].get(m));
02561 
02562                     }
02563 
02564 
02565                     simtime_t meanDistance = getMeanDistance(clusterset);
02566                     simtime_t oldDistance = getMaxDistance(clusters[i].getLeader(), clusterset);
02567                     simtime_t newDistance = getMaxDistance(new_leader, clusterset);
02568                     simtime_t compareDistance = (oldDistance - ((oldDistance/100.0)*CLUSTERLEADERCOMPAREDIST));
02569 
02570                     simtime_t minCompare = (meanDistance/100.0)*CLUSTERLEADERBOUND;
02571 
02572                     if (minCompare < 0.005)
02573                         minCompare = 0.005;
02574 
02575                     if ((newDistance.dbl() < compareDistance.dbl()) && ((compareDistance.dbl() - newDistance.dbl()) > minCompare.dbl())) {
02576 
02577                         if (clusterrefinement)
02578                             EV << "CHANGE " << CLUSTERLEADERCOMPAREDIST << endl;
02579 
02580                         if (new_leader != thisNode) {
02581 
02582                             // Set new leader for this cluster
02583                             clusters[i].setLeader(new_leader);
02584 
02585                             for (int j=0; j<clusters[i].getSize(); j++) {
02586 
02587                                 deleteOverlayNeighborArrow(clusters[i].get(j));
02588 
02589                             }
02590 
02591                             gracefulLeave(i);
02592                             LeaderTransfer(i, new_leader);
02593 
02594                             getParentModule()->getParentModule()->getDisplayString().setTagArg("i2", 0, "block/circle_vs");
02595 
02596                         }
02597 
02598                     }
02599 
02600                     if (clusterrefinement) {
02601                         EV << "MaxDistance " << new_leader.getIp() << " : " << getMaxDistance(new_leader, clusterset) << endl;
02602                         EV << "MaxDistance " << clusters[i].getLeader() << " : " << getMaxDistance(clusters[i].getLeader(), clusterset) << endl;
02603                         EV << "MaxDistance " << thisNode.getIp() << " : " << getMaxDistance(thisNode, clusterset) << endl;
02604                     }
02605 
02606 
02607                 }
02608 
02609             } // if cluster i has other members
02610 
02611         } // for i from highest leader layer to 0
02612 
02613     } // if this is not the rendevouz point
02614 
02615 } // maintenance
02616 
02617 
02618 /******************************************************************************
02619  * ClusterSplit
02620  */
02621 void Nice::ClusterSplit(int layer)
02622 {
02623 
02624     EV << simTime() << " : " << thisNode.getIp() << " : ClusterSplit in Layer " << layer << endl;
02625 
02626     /* Get cluster to be splitted */
02627     NiceCluster cluster = clusters[layer];
02628 
02629     /* Introduce some helper structures */
02630     std::vector<TransportAddress> vec1;
02631     std::vector<TransportAddress> vec2;
02632     std::vector<TransportAddress> cl1;
02633     std::vector<TransportAddress> cl2;
02634     TaSet cl1set, cl2set;
02635     TransportAddress cl1_center = TransportAddress::UNSPECIFIED_NODE;
02636     TransportAddress cl2_center = TransportAddress::UNSPECIFIED_NODE;
02637     simtime_t min_delay = 999;
02638 
02639     for (int i=0; i<cluster.getSize(); i++) {
02640 
02641         /* Delete all arrows in visualization */
02642         deleteOverlayNeighborArrow(cluster.get(i));
02643 
02644         /* Put all members to first vector */
02645         vec1.push_back(cluster.get(i));
02646         //EV << "vec1.push_back(cluster.get(i)): " << cluster.get(i).getIp() << endl;
02647 
02648         /* Put first half of members to second vector */
02649         if (i < cluster.getSize()/2) {
02650             vec2.push_back(cluster.get(i));
02651             //EV << "vec2.push_back(cluster.get(i)): " << cluster.get(i).getIp() << endl;
02652         }
02653 
02654     }
02655 
02656     int combinations = 0;
02657 
02658     TaSet::iterator sit;
02659 
02660     if (cluster.getSize() < 18) {
02661 
02662         /* Go through all combinations of clusters */
02663         do {
02664 
02665             combinations++;
02666 
02667             //EV << "combinations: " << combinations << endl;
02668 
02669             /* Introduce some helper structures */
02670             TransportAddress q1_center;
02671             TransportAddress q2_center;
02672             std::vector<TransportAddress> vec3;
02673 
02674             /* Determine elements that are in first set but not in second */
02675             std::set_difference(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), inserter(vec3, vec3.begin()));
02676 
02677             simtime_t min_q1_delay = 999;
02678             simtime_t min_q2_delay = 999;
02679             simtime_t max_delay = 0;
02680 
02681             q1_center = findCenter(vec2).first;
02682 
02683             //EV << "q1_center: " << q1_center.getIp() << endl;
02684 
02685             std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(q1_center);
02686 
02687             if (it != peerInfos.end()) {
02688 
02689                 min_q1_delay = it->second->get_distance();
02690 
02691             }
02692             else {
02693 
02694                 min_q1_delay = 0;
02695 
02696             }
02697 
02698             q2_center = findCenter(vec3).first;
02699 
02700             //EV << "q2_center: " << q2_center.getIp() << endl;
02701 
02702             it = peerInfos.find(q2_center);
02703 
02704             if (it != peerInfos.end()) {
02705 
02706                 min_q2_delay = it->second->get_distance();
02707 
02708             }
02709             else {
02710 
02711                 min_q2_delay = 0;
02712 
02713             }
02714 
02715             max_delay = std::max(min_q1_delay, min_q2_delay);
02716 
02717             if (min_delay == 0) min_delay = max_delay;
02718 
02719             if ((max_delay < min_delay) && !q1_center.isUnspecified() && !q2_center.isUnspecified()) {
02720 
02721                 min_delay = max_delay;
02722                 cl1 = vec2;
02723                 cl2 = vec3;
02724                 cl1_center = q1_center;
02725                 cl2_center = q2_center;
02726             }
02727 
02728         } while (next_combination(vec1.begin(), vec1.end(), vec2.begin(), vec2.end()));
02729 
02730         //build sets
02731         cl1set.insert(cl1.begin(), cl1.end());
02732         cl2set.insert(cl2.begin(), cl2.end());
02733 
02734     }
02735     else {
02736         EV << thisNode.getIp() << " RANDOM SPLIT" << endl;
02737         cl1set.clear();
02738         cl2set.clear();
02739         for (int i=0; i<cluster.getSize(); i++) {
02740             if (i < cluster.getSize()/2) {
02741                 cl1set.insert(cluster.get(i));
02742             }
02743             else {
02744                 cl2set.insert(cluster.get(i));
02745             }
02746         }
02747         cl1_center = findCenter(cl1set,true).first;
02748         cl2_center = findCenter(cl2set,true).first;
02749     }
02750 
02751     if (isRendevouzPoint) {
02752         // Make certain that we remain leader
02753         if (cl1set.count(thisNode) > 0) {
02754             cl1_center = thisNode;
02755         }
02756         else {
02757             cl2_center = thisNode;
02758         }
02759     }
02760 
02761     // Cluster split accomplished, now handling consequences
02762 
02763     // CASE 1: We lost all cluster leaderships
02764     // repair all cluster layer, top down
02765     if ((cl1_center != thisNode) && (cl2_center != thisNode)) {
02766 
02767         clusters[layer+1].add(cl1_center);
02768         clusters[layer+1].add(cl2_center);
02769         TaSet superCluster = TaSet(clusters[layer + 1].begin(), clusters[layer + 1].end());
02770         TransportAddress scLeader;
02771 
02772         if (layer < getHighestLayer()) {
02773             gracefulLeave(layer+1);
02774             scLeader = clusters[layer + 1].getLeader();
02775         }
02776         else {
02777             scLeader = cl1_center;
02778             if (isRendevouzPoint) {
02779                 opp_error("Something went wrong in Nice::ClusterSplit and the RendevouzPoint is trying to give up leadership. This is a bug in OverSim's implementation of Nice. Please fix it, or file a bug.");
02780             }
02781         }
02782 
02783         // Leaving the upper layer before sending LTs leads to wrong information in the packets.
02784         LeaderTransfer(layer, cl1_center, cl1set, scLeader, superCluster);
02785         LeaderTransfer(layer, cl2_center, cl2set, scLeader, superCluster);
02786 
02787         if (layer < maxLayers - 1) {
02788             for (TaSet::iterator itn = clusters[layer + 1].begin(); itn != clusters[layer + 1].end(); ++itn) {
02789                 deleteOverlayNeighborArrow(*itn);
02790             }
02791             clusters[layer + 1].clear();
02792         }
02793 
02794         getParentModule()->getParentModule()->getDisplayString().setTagArg("i2", 0, "block/circle_vs");
02795 
02796     }
02797 
02798     // CASE 2: We stay leader in one of the new clusters
02799     if ((cl1_center == thisNode) || (cl2_center == thisNode)) {
02800 
02801         if (clusters[layer + 1].getSize() == 0) {
02802 
02803             clusters[layer + 1].add(cl1_center);
02804             clusters[layer + 1].add(cl2_center);
02805 
02806             clusters[layer + 1].setLeader(thisNode);
02807             clusters[layer + 1].confirmLeader();
02808 
02809         }
02810 
02811         clusters[layer + 1].add(cl2_center);
02812         clusters[layer + 1].add(cl1_center);
02813         TaSet superCluster = TaSet(clusters[layer + 1].begin(), clusters[layer + 1].end());
02814         if (cl1_center == thisNode) {
02815 
02816             LeaderTransfer(layer, cl2_center, cl2set, clusters[layer + 1].getLeader(), superCluster);
02817 
02818         }
02819         else {
02820 
02821             LeaderTransfer(layer, cl1_center, cl1set, clusters[layer + 1].getLeader(), superCluster);
02822 
02823         }
02824 
02825 
02826     }
02827 
02828     // Set local cluster info
02829     clusters[layer].clear();
02830 
02831     // Depends on in which of the two clusters this node is
02832     if (cl1set.count(thisNode)) {
02833 
02834         TaSet::iterator cit = cl1set.begin();
02835         while (cit != cl1set.end()) {
02836             clusters[layer].add(*cit);
02837             cit++;
02838         }
02839 
02840         clusters[layer].setLeader(cl1_center);
02841 
02842     }
02843     else {
02844 
02845         TaSet::iterator cit = cl2set.begin();
02846         while (cit != cl2set.end()) {
02847             clusters[layer].add(*cit);
02848             cit++;
02849         }
02850 
02851         clusters[layer].setLeader(cl2_center);
02852 
02853     }
02854     clusters[layer].confirmLeader();
02855 
02856     //update arrows
02857     updateVisualization();
02858 
02859     if (pimp)
02860         sendHeartbeats();
02861 
02862 } // ClusterSplit
02863 
02864 
02865 /******************************************************************************
02866  * ClusterMerge
02867  */
02868 void Nice::ClusterMerge(int layer)
02869 {
02870 
02871     ASSERT(layer < maxLayers - 1);
02872     ASSERT(clusters[layer].getLeader() == thisNode);
02873     simtime_t min_delay = 999;
02874 
02875     TransportAddress min_node = TransportAddress::UNSPECIFIED_NODE;
02876 
02877     for (int i=0; i<clusters[layer+1].getSize(); i++) {
02878 
02879         TransportAddress node = clusters[layer+1].get(i);
02880 
02881         if (node != thisNode) {
02882 
02883             std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(node);
02884 
02885             if (it != peerInfos.end()) {
02886                 simtime_t delay = it->second->get_distance();
02887 
02888                 if ((delay > 0) && (delay < min_delay)) {
02889 
02890                     min_delay = delay;
02891                     min_node = node;
02892 
02893                 }
02894             }
02895         }
02896 
02897     }
02898 
02899     if (!min_node.isUnspecified()) {
02900 
02901         // send merge request
02902         ClusterMergeRequest(min_node, layer);
02903 
02904         // leave above layer, we are no longer the leader of this cluster.
02905         gracefulLeave(layer + 1);
02906 
02907         clusters[layer].add(min_node);
02908         clusters[layer].setLeader(min_node);
02909         clusters[layer].confirmLeader();
02910 
02911         for (int j=0; j<clusters[layer+1].getSize(); j++) {
02912 
02913             deleteOverlayNeighborArrow(clusters[layer+1].get(j));
02914 
02915         }
02916 
02917         for (int i = 0, highest = getHighestLayer(); i < highest; i++) {
02918 
02919             getParentModule()->getParentModule()->getDisplayString().setTagArg("i2", 1, clustercolors[i]);
02920 
02921         }
02922 
02923     }
02924     else {
02925 
02926         EV << thisNode.getIp() << " no suitable cluster found";
02927 
02928     }
02929 
02930 } // ClusterMerge
02931 
02932 
02933 /******************************************************************************
02934  * ClusterMergeRequest
02935  */
02936 void Nice::ClusterMergeRequest(const TransportAddress& node, int layer)
02937 {
02938     ASSERT(clusters[layer+1].contains(thisNode));
02939     ASSERT(!clusters[layer+1].getLeader().isUnspecified());
02940 
02941     NiceClusterMerge* msg = new NiceClusterMerge("NICE_CLUSTER_MERGE_REQUEST");
02942     msg->setSrcNode(thisNode);
02943     msg->setCommand(NICE_CLUSTER_MERGE_REQUEST);
02944     msg->setLayer(layer);
02945 
02946     msg->setMembersArraySize(clusters[layer].getSize());
02947 
02948     /* Fill in members */
02949     for (int j = 0; j < clusters[layer].getSize(); j++) {
02950 
02951         msg->setMembers(j, clusters[layer].get(j));
02952 
02953         deleteOverlayNeighborArrow(clusters[layer].get(j));
02954 
02955     }
02956 
02957     msg->setNewClusterLeader(clusters[layer+1].getLeader());
02958 
02959     msg->setBitLength(NICECLUSTERMERGE_L(msg));
02960 
02961     getParentModule()->getParentModule()->getDisplayString().setTagArg("i2", 0, "block/circle_vs");
02962 
02963     sendMessageToUDP(node, msg);
02964 
02965 } // ClusterMergeRequest
02966 
02967 
02968 /******************************************************************************
02969  * findCenter
02970  */
02971 std::pair<TransportAddress,simtime_t> Nice::findCenter(TaSet cluster, bool allowRandom)
02972 {
02973     return findCenter(cluster.begin(), cluster.end(), allowRandom);
02974 }
02975 
02976 
02977 /******************************************************************************
02978  * findCenter
02979  */
02980 std::pair<TransportAddress, simtime_t> Nice::findCenter(std::vector<TransportAddress> cluster, bool allowRandom)
02981 {
02982     return findCenter(cluster.begin(), cluster.end(), allowRandom);
02983 }
02984 
02985 
02986 /******************************************************************************
02987  * findCenter
02988  */
02989 std::pair<TransportAddress, simtime_t> Nice::findCenter(const NiceCluster& cluster, bool allowRandom)
02990 {
02991     return findCenter(cluster.begin(), cluster.end(), allowRandom);
02992 }
02993 
02994 /******************************************************************************
02995  * findCenter
02996  */
02997 template <class ConstIter>
02998 std::pair<TransportAddress, simtime_t> Nice::findCenter(ConstIter begin, ConstIter end, bool allowRandom)
02999 {
03000 
03001     TransportAddress center = TransportAddress::UNSPECIFIED_NODE;
03002     simtime_t min_delay = 1000;
03003 
03004     for (ConstIter it = begin; it != end; ++it) {
03005 
03006         simtime_t delay = getMaxDistance(*it, begin, end);
03007 
03008         if ((delay > 0) && (delay < min_delay)) {
03009 
03010             min_delay = delay;
03011             center = *it;
03012 
03013         }
03014 
03015     }
03016 
03017     if (center.isUnspecified()) {
03018         center = *begin;
03019     }
03020 
03021     //EV << "center: " << center << endl;
03022     return std::make_pair(center, min_delay);
03023 
03024 } // findCenter
03025 
03026 
03027 /******************************************************************************
03028  * getMaxDistance
03029  */
03030 template <class ConstIter>
03031 simtime_t Nice::getMaxDistance(TransportAddress member, ConstIter neighborsBegin, ConstIter neighborsEnd)
03032 {
03033     simtime_t maxDelay = 0;
03034     simtime_t delay = 0;
03035 
03036     if (member == thisNode) {
03037 
03038         for (ConstIter it = neighborsBegin; it != neighborsEnd; ++it) {
03039 
03040             std::map<TransportAddress, NicePeerInfo*>::iterator itInfo = peerInfos.find(*it);
03041 
03042             if (itInfo != peerInfos.end()) {
03043 
03044                 delay = itInfo->second->get_distance();
03045                 maxDelay = std::max(delay, maxDelay);
03046 
03047             }
03048 
03049         }
03050 
03051     }
03052     else {
03053 
03054         std::map<TransportAddress, NicePeerInfo*>::iterator itInfo = peerInfos.find(member);
03055 
03056         if (itInfo != peerInfos.end()) {
03057 
03058             for (ConstIter it = neighborsBegin; it != neighborsEnd; ++it) {
03059 
03060                 //EV << "getDistanceTo " << *it2 << endl;
03061                 delay = itInfo->second->getDistanceTo(*it);
03062                 //EV << thisNode.getIp() << " : Distance to " << it2->getIp() << " : " << delay << endl;
03063                 maxDelay = std::max(delay, maxDelay);
03064 
03065             }
03066 
03067         }
03068 
03069     }
03070 
03071     return maxDelay;
03072 
03073 } // getMaxDistance
03074 
03075 simtime_t Nice::getMaxDistance(TransportAddress member, const std::set<TransportAddress>& neighbors)
03076 {
03077     return getMaxDistance(member, neighbors.begin(), neighbors.end());
03078 } // getMaxDistance
03079 
03080 /******************************************************************************
03081  * getMeanDistance
03082  */
03083 simtime_t Nice::getMeanDistance(std::set<TransportAddress> neighbors)
03084 {
03085     simtime_t meanDelay = 0;
03086     simtime_t delay = 0;
03087     unsigned int number = 0;
03088 
03089     std::set<TransportAddress>::iterator it = neighbors.begin();
03090 
03091     while (it != neighbors.end()) {
03092 
03093         if (*it != thisNode) {
03094 
03095             std::map<TransportAddress, NicePeerInfo*>::iterator it2 = peerInfos.find(*it);
03096 
03097             if (it2 != peerInfos.end()) {
03098 
03099                 delay = it2->second->get_distance();
03100                 //EV << "delay to " << *it << " : " << delay << endl;
03101 
03102                 if  (delay > 0.0) {
03103 
03104                     meanDelay += delay;
03105                     number++;
03106 
03107                 }
03108 
03109             }
03110 
03111         }
03112 
03113         it++;
03114 
03115     }
03116 
03117     if (number > 0) {
03118 
03119         return meanDelay/number;
03120 
03121     }
03122     else {
03123 
03124         return 0;
03125 
03126     }
03127 
03128 } // getMeanDistance
03129 
03130 
03131 /******************************************************************************
03132  * LeaderTransfer
03133  * Does not actually change stored cluster information.
03134  */
03135 void Nice::LeaderTransfer(int layer, TransportAddress leader, TaSet cluster, TransportAddress sc_leader, TaSet superCluster)
03136 {
03137 
03138     NiceLeaderHeartbeat* msg = new NiceLeaderHeartbeat("NICE_LEADERTRANSFER");
03139     msg->setSrcNode(thisNode);
03140     msg->setCommand(NICE_LEADERTRANSFER);
03141     msg->setLayer(layer);
03142 
03143     msg->setMembersArraySize(cluster.size());
03144 
03145     // fill in members
03146     TaSet::iterator it = cluster.begin();
03147     int i = 0;
03148     while (it != cluster.end()) {
03149         msg->setMembers(i++, *it);
03150         it++;
03151     }
03152 
03153     // fill in supercluster members, if existent
03154     msg->setSupercluster_leader(sc_leader);
03155 
03156     msg->setSupercluster_membersArraySize(superCluster.size());
03157 
03158     it = superCluster.begin();
03159     i = 0;
03160     while (it != superCluster.end()) {
03161         msg->setSupercluster_members(i++, *it);
03162         ++it;
03163     }
03164 
03165     msg->setBitLength(NICELEADERHEARTBEAT_L(msg));
03166 
03167     sendMessageToUDP(leader, msg);
03168 
03169 } // LeaderTransfer
03170 
03171 void Nice::LeaderTransfer(int layer, TransportAddress leader)
03172 {
03173     ASSERT(clusters[layer].contains(leader));
03174 
03175     if (isRendevouzPoint) {
03176         opp_error("The RendevouzPoint is handing off leadership and the simulation cannot continue. This is a bug in the Nice implementation in OverSim, please check the backtrace and fix it or submit a bug report.");
03177     }
03178 
03179     TaSet cluster(clusters[layer].begin(), clusters[layer].end());
03180 
03181     if (layer == maxLayers - 1)
03182         LeaderTransfer(layer, leader, cluster, TransportAddress::UNSPECIFIED_NODE, TaSet());
03183     else
03184         LeaderTransfer(layer, leader, cluster, clusters[layer + 1].getLeader(), TaSet(clusters[layer + 1].begin(), clusters[layer+1].end()));
03185 }
03186 
03187 /******************************************************************************
03188  * Remove
03189  */
03190 void Nice::Remove(int layer)
03191 {
03192     if (debug_removes)
03193         EV << simTime() << " : " << thisNode.getIp() << " : Remove()" << endl;
03194 
03195     int highestLayer = getHighestLayer();
03196     ASSERT(layer <= highestLayer);
03197 
03198     NiceMessage* msg = new NiceMessage("NICE_REMOVE");
03199     msg->setSrcNode(thisNode);
03200     msg->setCommand(NICE_REMOVE);
03201     msg->setLayer(layer);
03202 
03203     msg->setBitLength(NICEMESSAGE_L(msg));
03204 
03205     sendMessageToUDP(clusters[layer].getLeader(), msg);
03206 
03207     clusters[layer].remove(thisNode);
03208 
03209     for (short i=0; i<maxLayers; i++) {
03210 
03211         if (clusters[i].getSize() > 0) {
03212 
03213             if (clusters[i].contains(thisNode)) {
03214 
03215                 getParentModule()->getParentModule()->getDisplayString().setTagArg
03216                 ("i2", 1, clustercolors[i]);
03217 
03218             }
03219 
03220         }
03221 
03222     }
03223 
03224     if (debug_removes)
03225         EV << simTime() << " : " << thisNode.getIp() << " : Remove() finished." << endl;
03226 
03227 
03228 } // Remove
03229 
03230 
03231 /******************************************************************************
03232  * gracefulLeave
03233  */
03234 void Nice::gracefulLeave(short bottomLayer)
03235 {
03236     EV << simTime() << " : " << thisNode.getIp() << " : gracefulLeave()" << endl;
03237 
03238     int layer = getHighestLayer();
03239 
03240     ASSERT(layer >= bottomLayer);
03241 
03242     if (isRendevouzPoint) {
03243         opp_error("The RendevouzPoint is trying to leave a layer and the simulation cannot continue. This is a bug in the Nice implementation in OverSim, please check the backtrace and fix it or submit a bug report.");
03244     }
03245 
03246     if (!clusters[layer].getLeader().isUnspecified() && clusters[layer].getLeader() != thisNode) {
03247         // simply leave cluster
03248         EV << "removing " << thisNode.getIp() << " from " << layer << endl;
03249         if (!clusters[layer].getLeader().isUnspecified()) {
03250             Remove(layer);
03251         }
03252         clusters[layer].remove(thisNode);
03253     }
03254 
03255     for (layer = getHighestLeaderLayer(); layer >= bottomLayer; layer--) {
03256 
03257         EV << "REPAIR: " << layer << endl;
03258 
03259         for (TaSet::const_iterator itNode = clusters[layer].begin(); itNode != clusters[layer].end(); ++itNode) {
03260 
03261             EV << "rest: " << itNode->getIp() << endl;
03262 
03263             deleteOverlayNeighborArrow(*itNode);
03264 
03265         }
03266 
03267         EV << "remove from: " << layer << endl;
03268         Remove(layer);
03269 
03270         if (clusters[layer].getSize() > 0) {
03271             TransportAddress new_sc_center = findCenter(clusters[layer]).first;
03272 
03273             EV << "NEW LEADER (GL): " << layer << " --> " << new_sc_center.getIp() << endl;
03274 
03275             if (new_sc_center.isUnspecified()) {
03276 
03277                 new_sc_center = clusters[layer].get(0);
03278 
03279                 EV << "UNSPECIFIED! instead choose: " << new_sc_center.getIp() << endl;
03280 
03281             }
03282 
03283             clusters[layer].setLeader(new_sc_center);
03284 
03285             LeaderTransfer(layer, new_sc_center);
03286 
03287         }
03288 
03289     }
03290 
03291     EV << simTime() << " : " << thisNode.getIp() << " : gracefulLeave() finished." << endl;
03292 
03293 
03294 } // gracefulLeave
03295 
03296 
03297 /******************************************************************************
03298  * handleAppMessage
03299  */
03300 void Nice::handleAppMessage(cMessage* msg)
03301 {
03302     if ( ALMAnycastMessage* anycastMsg = dynamic_cast<ALMAnycastMessage*>(msg) ) {
03303         EV << "[Nice::handleAppMessage() @ " << overlay->getThisNode().getIp()
03304            << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
03305            << "    Anycast message for group " << anycastMsg->getGroupId() << "\n"
03306            << "    ignored: Not implemented yet!"
03307            << endl;
03308     }
03309     else if ( ALMCreateMessage* createMsg = dynamic_cast<ALMCreateMessage*>(msg) ) {
03310         EV << "[Nice::handleAppMessage() @ " << overlay->getThisNode().getIp()
03311            << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
03312            << "    Create message for group " << createMsg->getGroupId() << "\n"
03313            << "    ignored: Not implemented yet!"
03314            << endl;
03315     }
03316     else if ( ALMDeleteMessage* deleteMsg = dynamic_cast<ALMDeleteMessage*>(msg) ) {
03317         EV << "[Nice::handleAppMessage() @ " << overlay->getThisNode().getIp()
03318            << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
03319            << "    Delete message for group " << deleteMsg->getGroupId() << "\n"
03320            << "    ignored: Not implemented yet!"
03321            << endl;
03322     }
03323     else if ( ALMLeaveMessage* leaveMsg = dynamic_cast<ALMLeaveMessage*>(msg) ) {
03324         EV << "[Nice::handleAppMessage() @ " << overlay->getThisNode().getIp()
03325            << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
03326            << "    Leave message for group " << leaveMsg->getGroupId() << "\n"
03327            << "    ignored: Not implemented yet!"
03328            << endl;
03329     }
03330     else if ( ALMMulticastMessage* multicastMsg = dynamic_cast<ALMMulticastMessage*>(msg) ) {
03331         NiceMulticastMessage *niceMsg = new NiceMulticastMessage("NICE_MULTICAST");
03332         niceMsg->setCommand(NICE_MULTICAST);
03333         niceMsg->setLayer(-1);
03334         niceMsg->setSrcNode(thisNode);
03335         niceMsg->setLastHop(thisNode);
03336         niceMsg->setHopCount(0);
03337 
03338         niceMsg->setBitLength(NICEMULTICAST_L(niceMsg));
03339 
03340         niceMsg->encapsulate(multicastMsg);
03341         sendDataToOverlay(niceMsg);
03342 
03343         // otherwise msg gets deleted later
03344         msg = NULL;
03345     }
03346     else if ( ALMSubscribeMessage* subscribeMsg = dynamic_cast<ALMSubscribeMessage*>(msg) ) {
03347         EV << "[Nice::handleAppMessage() @ " << overlay->getThisNode().getIp()
03348            << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
03349            << "    Subscribe message for group " << subscribeMsg->getGroupId() << "\n"
03350            << "    ignored: Not implemented yet!"
03351            << endl;
03352     }
03353 
03354     // Delete msg if not already deleted
03355     if ( msg ) {
03356         delete msg;
03357     }
03358 
03359 } // handleAppMessage
03360 
03361 
03362 /******************************************************************************
03363  * sendDataToOverlay
03364  */
03365 void Nice::sendDataToOverlay(NiceMulticastMessage *appMsg)
03366 {
03367 
03368     for (int layer=0; layer <= getHighestLayer(); layer++) {
03369 
03370         if ( appMsg->getLayer() != layer ) {
03371 
03372             for (int j=0; j<clusters[layer].getSize(); j++) {
03373 
03374                 if (!(clusters[layer].contains(appMsg->getLastHop())) || appMsg->getSrcNode() == thisNode) {
03375 
03376                     const TransportAddress& member = clusters[layer].get(j);
03377 
03378                     if (!(member == thisNode)) {
03379 
03380                         NiceMulticastMessage* dup = static_cast<NiceMulticastMessage*>(appMsg->dup());
03381 
03382                         dup->setLayer( layer );
03383                         dup->setLastHop(thisNode);
03384 
03385                         sendMessageToUDP(member, dup);
03386 
03387                     }
03388 
03389                 }
03390 
03391             } // for
03392 
03393         }
03394 
03395     }
03396 
03397     // Also forward data to temporary peers
03398     std::map<TransportAddress, simtime_t>::iterator it = tempPeers.begin();
03399 
03400     while (it != tempPeers.end()) {
03401 
03402         NiceMulticastMessage* dup = static_cast<NiceMulticastMessage*>(appMsg->dup());
03403 
03404         dup->setSrcNode(thisNode);
03405 
03406         sendMessageToUDP(it->first, dup);
03407 
03408         it++;
03409 
03410     }
03411 
03412     delete appMsg;
03413 
03414 } // sendDataToOverlay
03415 
03416 
03417 /******************************************************************************
03418  * updateVisualization
03419  */
03420 void Nice::updateVisualization()
03421 {
03422 
03423     if (debug_visualization)
03424         EV << simTime() << " : " << thisNode.getIp() << " : updateVisualization" << endl;
03425 
03426     /* Update node symbol */
03427     getParentModule()->getParentModule()
03428     ->getDisplayString().setTagArg("i2", 0, "block/circle_vs");
03429 
03430     if (isRendevouzPoint) {
03431 
03432         getParentModule()->getParentModule()->getDisplayString().setTagArg("i2", 0, "block/star_vs");
03433 
03434     }
03435 
03436     /* Update node color */
03437     if (debug_visualization)
03438         EV << "getHighestLayer(): " << getHighestLayer() << endl;
03439 
03440     getParentModule()->getParentModule()
03441     ->getDisplayString().setTagArg("i2", 1, clustercolors[getHighestLayer()]);
03442 
03443     //redraw
03444     for (int i=0; clusters[i].contains(thisNode); i++) {
03445 
03446         if (!(clusters[i].getLeader().isUnspecified())) {
03447 
03448             if (clusters[i].getLeader() == thisNode) {
03449 
03450                 for (int j=0; j<clusters[i].getSize();j++) {
03451 
03452                     if (debug_visualization)
03453                         EV << "draw to: " << clusters[i].get(j) << endl;
03454 
03455                     showOverlayNeighborArrow(clusters[i].get(j), false, clusterarrows[i]);
03456 
03457                 }
03458 
03459             }
03460 
03461         }
03462     }
03463 
03464 
03465 } // updateVisualization
03466 
03467 void Nice::pollRP(int layer)
03468 {
03469 
03470     if (debug_queries)
03471         EV << simTime() << " : " << thisNode.getIp() << " : pollRP()" << endl;
03472 
03473     NiceMessage* msg = new NiceMessage("NICE_POLL_RP");
03474     msg->setSrcNode(thisNode);
03475     msg->setCommand(NICE_POLL_RP);
03476     msg->setLayer(layer);
03477     msg->setBitLength(NICEMESSAGE_L(msg));
03478 
03479     cancelEvent(rpPollTimer);
03480     scheduleAt(simTime() + rpPollTimerInterval, rpPollTimer);
03481 
03482     sendMessageToUDP(RendevouzPoint, msg);
03483 
03484     polledRendevouzPoint = RendevouzPoint;
03485 
03486     if (debug_queries)
03487         EV << simTime() << " : " << thisNode.getIp() << " : pollRP() finished." << endl;
03488 
03489 } // pollRP
03490 
03491 
03492 
03493 }; //namespace