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

Generated on Tue Sep 8 17:26:53 2009 for OverSim by  doxygen 1.5.8