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