Vast Class Reference

#include <Vast.h>

Inheritance diagram for Vast:

BaseOverlay BaseRpc TopologyVis RpcListener

List of all members.


Detailed Description

Voronoi class.

An overlay network based on voronoi diagrams.

Public Member Functions

virtual ~Vast ()
virtual void initializeOverlay (int stage)
 Initializes derived-class-attributes.
virtual void finishOverlay ()
 collects statistical data in derived class
virtual void handleUDPMessage (BaseOverlayMessage *msg)
 Processes messages from underlay.
virtual void handleTimerEvent (cMessage *msg)
 Processes "timer" self-messages.
virtual void handleAppMessage (cMessage *msg)
 Processes non-commonAPI messages.
virtual void receiveChangeNotification (int category, cPolymorphic *details)
 callback-method for events at the NotificationBoard
double getAOI ()
Vector2D getPosition ()
NeighborsListgetList ()

Protected Member Functions

void sendToApp (cMessage *msg)
void sendMessage (VastMessage *vastMsg, NodeHandle destAddr)
void setBootstrapedIcon ()
void changeState (int state)
double distance_square (Site s, VastMessage *msg)
void processJoinTimer ()
void processPingTimer ()
void processSecTimer ()
void handleJoin (GameAPIPositionMessage *sgcMsg)
void handleMove (GameAPIPositionMessage *sgcMsg)
void handleJoinRequest (VastMessage *vastMsg)
void handleJoinAcknowledge (VastListMessage *vastListMsg)
void handleNodeMove (VastMoveMessage *vastMoveMsg)
void handleNewNeighbors (VastListMessage *vastListMsg)
void handleNodeLeave (VastListMessage *vastListMsg)
void handleEnclosingNeighborsRequest (VastMessage *vastMsg)
void handlePing (VastMessage *vastMsg)
void handlePong (VastMessage *vastMsg)
void handleDiscardNode (VastDiscardMessage *vastMsg)
void sendDiscardNode (VastMessage *vastMsg)
void synchronizeApp (VastMoveMessage *vastMoveMsg=NULL)

Protected Attributes

double AOI_size
Vector2D position
NeighborsListneighborsList
long joinRequestBytesSent
long joinAcknowledgeBytesSent
long nodeMoveBytesSent
long newNeighborsBytesSent
long nodeLeaveBytesSent
long enclosingNeighborsRequestBytesSent
long pingBytesSent
long pongBytesSent
long discardNodeBytesSent
long maxBytesPerSecondSent
long averageBytesPerSecondSent
long bytesPerSecond
bool debugVoronoiOutput
bool ignoreFalseKeys
double joinTimeout
double pingTimeout
cMessage * join_timer
cMessage * ping_timer
cMessage * sec_timer


Constructor & Destructor Documentation

Vast::~Vast (  )  [virtual]

00819 {
00820     // destroy self timer messages
00821     cancelAndDelete(join_timer);
00822     cancelAndDelete(ping_timer);
00823     cancelAndDelete(sec_timer);
00824 }


Member Function Documentation

void Vast::initializeOverlay ( int  stage  )  [virtual]

Initializes derived-class-attributes.


Initializes derived-class-attributes, called by BaseOverlay::initialize(). By default this method is called once. If more stages are needed one can overload numInitStages() and add more stages.

Parameters:
stage the init stage

Reimplemented from BaseOverlay.

00029 {
00030     // because of IPAddressResolver, we need to wait until interfaces are registered,
00031     // address auto-assignment takes place etc.
00032     if(stage != MIN_STAGE_OVERLAY) return;
00033 
00034     // fetch parameters
00035     debugVoronoiOutput = par("debugVastOutput");
00036     ignoreFalseKeys = par("ignoreFalseKeys");
00037     AOI_size = par("AOIWidth");
00038     joinTimeout = par("joinTimeout");
00039     pingTimeout = par("pingTimeout");
00040 
00041     // find friend modules
00042     neighborsList = check_and_cast<NeighborsList*>(parentModule()->submodule("neighborsList"));
00043 
00044     // set node key
00045     thisNode.key = OverlayKey::random();
00046 
00047     // initialize neighborsList
00048     neighborsList->setDebug(debugVoronoiOutput);
00049 
00050     // self-messages
00051     join_timer = new cMessage("join_timer");
00052     ping_timer = new cMessage("ping_timer");
00053     sec_timer = new cMessage("sec_timer");
00054 
00055     // statistics
00056     joinRequestBytesSent = 0;
00057     joinAcknowledgeBytesSent = 0;
00058     nodeMoveBytesSent = 0;
00059     newNeighborsBytesSent = 0;
00060     nodeLeaveBytesSent = 0;
00061     enclosingNeighborsRequestBytesSent = 0;
00062     pingBytesSent = 0;
00063     pongBytesSent = 0;
00064     discardNodeBytesSent = 0;
00065 
00066     maxBytesPerSecondSent = 0;
00067     averageBytesPerSecondSent = 0;
00068     bytesPerSecond = 0;
00069 
00070     // watch some variables
00071     WATCH(position);
00072     WATCH(thisNode);
00073     WATCH(AOI_size);
00074 
00075     WATCH(joinRequestBytesSent);
00076     WATCH(joinAcknowledgeBytesSent);
00077     WATCH(nodeMoveBytesSent);
00078     WATCH(newNeighborsBytesSent);
00079     WATCH(nodeLeaveBytesSent);
00080     WATCH(enclosingNeighborsRequestBytesSent);
00081     WATCH(pingBytesSent);
00082     WATCH(pongBytesSent);
00083     WATCH(discardNodeBytesSent);
00084 
00085     WATCH(maxBytesPerSecondSent);
00086     WATCH(bytesPerSecond);
00087 
00088     // set initial state
00089     changeState(INIT);
00090     changeState(JOINING);
00091 }

void Vast::finishOverlay (  )  [virtual]

collects statistical data in derived class

Reimplemented from BaseOverlay.

00782 {
00783     // collect statistics
00784     globalStatistics->addStdDev("JOIN_REQUEST bytes sent", joinRequestBytesSent);
00785     globalStatistics->addStdDev("JOIN_ACKNOWLEDGE bytes sent", joinAcknowledgeBytesSent);
00786     globalStatistics->addStdDev("NODE_MOVE bytes sent", nodeMoveBytesSent);
00787     globalStatistics->addStdDev("NEW_NEIGHBORS bytes sent", newNeighborsBytesSent);
00788     globalStatistics->addStdDev("NODE_LEAVE bytes sent", nodeLeaveBytesSent);
00789     globalStatistics->addStdDev("ENCLOSING_NEIGHBORS_REQUEST bytes sent", enclosingNeighborsRequestBytesSent);
00790     globalStatistics->addStdDev("PING bytes sent", pingBytesSent);
00791     globalStatistics->addStdDev("PONG bytes sent", pongBytesSent);
00792     globalStatistics->addStdDev("DISCARD_NODE bytes sent", discardNodeBytesSent);
00793 
00794     globalStatistics->addStdDev("max bytes/second sent", maxBytesPerSecondSent);
00795     globalStatistics->addStdDev("average bytes/second sent", (long)(averageBytesPerSecondSent / simTime()));
00796 
00797     bootstrapOracle->removePeer(thisNode);
00798 }

void Vast::handleUDPMessage ( BaseOverlayMessage *  msg  )  [virtual]

Processes messages from underlay.

Parameters:
msg Message from UDP

Reimplemented from BaseOverlay.

00185 {
00186     if(state == INIT) {
00187         delete msg;
00188         return;
00189     }
00190     if(dynamic_cast<VastMessage*>(msg)) {
00191         VastMessage* vastMsg = check_and_cast<VastMessage*>(msg);
00192         if(ignoreFalseKeys || vastMsg->getDestKey() == thisNode.key) {
00193             // debug output
00194             if(debugOutput) ev << "VAST: Node " << thisNode.ip << " received " << vastMsg->name() << " from " << vastMsg->getSourceNode().ip << "." << endl;
00195             bool doUpdate = true;
00196             if(state == READY) {
00197                 switch(vastMsg->getCommand()) {
00198                     case JOIN_REQUEST: {
00199                         handleJoinRequest(vastMsg);
00200                         doUpdate = false;
00201                     } break;
00202                     case NODE_MOVE: {
00203                         VastMoveMessage* vastMoveMsg = check_and_cast<VastMoveMessage*>(msg);
00204                         handleNodeMove(vastMoveMsg);
00205                     } break;
00206                     case NEW_NEIGHBORS: {
00207                         VastListMessage* vastListMsg = check_and_cast<VastListMessage*>(msg);
00208                         handleNewNeighbors(vastListMsg);
00209                     } break;
00210                     case NODE_LEAVE: {
00211                         VastListMessage* vastListMsg = check_and_cast<VastListMessage*>(msg);
00212                         handleNodeLeave(vastListMsg);
00213                     } break;
00214                     case ENCLOSING_NEIGHBORS_REQUEST: {
00215                         handleEnclosingNeighborsRequest(vastMsg);
00216                     } break;
00217                     case PING: {
00218                         handlePing(vastMsg);
00219                     } break;
00220                     case PONG: {
00221                         handlePong(vastMsg);
00222                     } break;
00223                     case DISCARD_NODE: {
00224                         VastDiscardMessage* vastDiscardMsg = check_and_cast<VastDiscardMessage*>(msg);
00225                         handleDiscardNode(vastDiscardMsg);
00226                     } break;
00227                 }
00228                 // update timestamp
00229                 if(doUpdate) {
00230                     neighborsList->updateTimeStamp(vastMsg->getSourceNode());
00231                     delete msg;
00232                 }
00233             }
00234             else if(state == JOINING && vastMsg->getCommand() == JOIN_ACKNOWLEDGE) {
00235                 VastListMessage* vastListMsg = check_and_cast<VastListMessage*>(msg);
00236                 handleJoinAcknowledge(vastListMsg);
00237                 delete msg;
00238             }
00239             else delete msg;
00240         }
00241         else {
00242             sendDiscardNode(vastMsg);
00243             delete msg;
00244         }
00245     }
00246     else delete msg;
00247 }

void Vast::handleTimerEvent ( cMessage *  msg  )  [virtual]

Processes "timer" self-messages.

Parameters:
msg A self-message

Reimplemented from BaseOverlay.

00131 {
00132     if(msg->isName("join_timer")) {
00133         //reset timer
00134         cancelEvent(join_timer);
00135         scheduleAt(simulation.simTime() + joinTimeout, msg);
00136         // handle event
00137         processJoinTimer();
00138     }
00139     else if(msg->isName("ping_timer")) {
00140         //reset timer
00141         cancelEvent(ping_timer);
00142         scheduleAt(simulation.simTime() + pingTimeout, msg);
00143         // handle event
00144         processPingTimer();
00145     }
00146     else if(msg->isName("sec_timer")) {
00147         //reset timer
00148         cancelEvent(sec_timer);
00149         scheduleAt(simulation.simTime() + 1, msg);
00150         // handle event
00151         processSecTimer();
00152     }
00153 }

void Vast::handleAppMessage ( cMessage *  msg  )  [virtual]

Processes non-commonAPI messages.

Parameters:
msg non-commonAPIMessage

Reimplemented from BaseOverlay.

00156 {
00157     if(dynamic_cast<GameAPIMessage*>(msg)) {
00158         GameAPIMessage* gameAPIMsg = check_and_cast<GameAPIMessage*>(msg);
00159         // debug output
00160         if(debugOutput) ev << "VAST: Node " << thisNode.ip << " received " << gameAPIMsg->name() << " from application." << endl;
00161         switch(gameAPIMsg->getCommand()) {
00162             case MOVEMENT_INDICATION: {
00163                 GameAPIPositionMessage* gameAPIPosMsg = check_and_cast<GameAPIPositionMessage*>(msg);
00164                 if(state == JOINING) {
00165                     handleJoin(gameAPIPosMsg);
00166                     delete msg;
00167                 }
00168                 else if(state == READY) {
00169                     handleMove(gameAPIPosMsg);
00170                     delete msg;
00171                 }
00172             } break;
00173             //case EVENT: {
00174                 // insert handling for additional application messages like events etc. here
00175             //} break;
00176             default: {
00177                 delete msg;
00178             }
00179         }
00180     }
00181     else delete msg;
00182 }

void Vast::receiveChangeNotification ( int  category,
cPolymorphic *  details 
) [virtual]

callback-method for events at the NotificationBoard

Parameters:
category ... TODO ...
details ... TODO ...

Reimplemented from BaseOverlay.

00250 {
00251     if(category == NF_OVERLAY_NODE_GRACEFUL_LEAVE && state == READY) {
00252         int i;
00253         // debug output
00254         if(debugOutput) {
00255             ev << "VAST: Node " << thisNode.ip << " is leaving the overlay." << endl;
00256         }
00257 
00258         // generate node leave messages
00259         VastListMessage *vastListMsg = new VastListMessage("NODE_LEAVE");
00260         vastListMsg->setCommand(NODE_LEAVE);
00261         vastListMsg->setSourceNode(thisNode);
00262         vastListMsg->setPos(position);
00263         // fill neighbors list
00264         vastListMsg->setNeighborNodeArraySize(neighborsList->getSize());
00265         vastListMsg->setNeighborPosArraySize(neighborsList->getSize());
00266         i = 0;
00267         SiteMap::iterator itSites = neighborsList->Sites.begin();
00268         while(itSites != neighborsList->Sites.end()) {
00269             if(itSites->second.type & ENCLOSING) {
00270                 vastListMsg->setNeighborNode(i, itSites->second.addr);
00271                 vastListMsg->setNeighborPos(i, itSites->second.coord);
00272                 ++i;
00273             }
00274             ++itSites;
00275         }
00276         vastListMsg->setNeighborNodeArraySize(i);
00277         vastListMsg->setNeighborPosArraySize(i);
00278         vastListMsg->setRequestEnclosingNeighbors(false);
00279 
00280         vastListMsg->setLength(VASTLIST_L(vastListMsg));
00281         if(vastListMsg->getNeighborNodeArraySize() > 0) {
00282             itSites = neighborsList->Sites.begin();
00283             while(itSites != neighborsList->Sites.end()) {
00284                 VastListMessage *vastCopyMsg = new VastListMessage(*vastListMsg);
00285                 // prevent notification board from taking the message
00286                take(vastCopyMsg);
00287                sendMessage(vastCopyMsg, itSites->second.addr);
00288                ++itSites;
00289             }
00290         }
00291         delete vastListMsg;
00292 
00293         TierReadyMessage* readyMsg = new TierReadyMessage("OVERLAY_FINISHED");
00294         readyMsg->setReady(false);
00295         take(readyMsg);
00296         sendToApp(readyMsg);
00297 
00298         changeState(INIT);
00299     }
00300 }

double Vast::getAOI (  ) 

00801 {
00802     Enter_Method_Silent();
00803     return AOI_size;
00804 }

Vector2D Vast::getPosition (  ) 

00807 {
00808     Enter_Method_Silent();
00809     return position;
00810 }

NeighborsList * Vast::getList (  ) 

00813 {
00814     Enter_Method_Silent();
00815     return neighborsList;
00816 }

void Vast::sendToApp ( cMessage *  msg  )  [protected]

00712 {
00713     // debug output
00714     if(debugOutput) ev << "VAST: Node " << thisNode.ip << " sending " << msg->name() << " to application." << endl;
00715     send(msg, "to_app");
00716 }

void Vast::sendMessage ( VastMessage *  vastMsg,
NodeHandle  destAddr 
) [protected]

00719 {
00720     // collect statistics
00721     switch(vastMsg->getType()) {
00722         case JOIN_REQUEST: {
00723             joinRequestBytesSent += vastMsg->byteLength();
00724         } break;
00725         case JOIN_ACKNOWLEDGE: {
00726             joinAcknowledgeBytesSent += vastMsg->byteLength();
00727         } break;
00728         case NODE_MOVE: {
00729             nodeMoveBytesSent += vastMsg->byteLength();
00730         } break;
00731         case NEW_NEIGHBORS: {
00732             newNeighborsBytesSent += vastMsg->byteLength();
00733         } break;
00734         case NODE_LEAVE: {
00735             nodeLeaveBytesSent += vastMsg->byteLength();
00736         } break;
00737         case ENCLOSING_NEIGHBORS_REQUEST: {
00738             enclosingNeighborsRequestBytesSent += vastMsg->byteLength();
00739         } break;
00740         case PING: {
00741             pingBytesSent += vastMsg->byteLength();
00742         } break;
00743         case PONG: {
00744             pongBytesSent += vastMsg->byteLength();
00745         } break;
00746         case DISCARD_NODE: {
00747             discardNodeBytesSent += vastMsg->byteLength();
00748         } break;
00749     }
00750     bytesPerSecond += vastMsg->byteLength();
00751 
00752     // debug output
00753     if(debugOutput) ev << "VAST: Node " << thisNode.ip << " sending " << vastMsg->name() << " to " << destAddr.ip << "." << endl;
00754     vastMsg->setDestKey(destAddr.key);
00755     sendMessageToUDP(destAddr, vastMsg);
00756 }

void Vast::setBootstrapedIcon (  )  [protected]

00764 {
00765     if(ev.isGUI()) {
00766         if(state == READY) {
00767             parentModule()->parentModule()->displayString().setTagArg("i2", 1, "green");
00768             displayString().setTagArg("i", 1, "green");
00769         }
00770         else if(state == JOINING) {
00771             parentModule()->parentModule()->displayString().setTagArg("i2", 1, "yellow");
00772             displayString().setTagArg("i", 1, "yellow");
00773         }
00774         else {
00775             parentModule()->parentModule()->displayString().setTagArg("i2", 1, "red");
00776             displayString().setTagArg("i", 1, "red");
00777         }
00778     }
00779 }

void Vast::changeState ( int  state  )  [protected]

00094 {
00095     switch(state) {
00096         case INIT: {
00097             this->state = INIT;
00098             bootstrapOracle->removePeer(thisNode);
00099         } break;
00100         case JOINING: {
00101             this->state = JOINING;
00102             scheduleAt(simulation.simTime(), join_timer);
00103             scheduleAt(simulation.simTime() + 1.0, sec_timer);
00104         } break;
00105         case READY: {
00106             this->state = READY;
00107             cancelEvent(join_timer);
00108             neighborsList->initializeList(position, thisNode, AOI_size);
00109             bootstrapOracle->registerPeer(thisNode);
00110             scheduleAt(simulation.simTime() + pingTimeout, ping_timer);
00111             // tell the application we are ready
00112             TierReadyMessage* readyMsg = new TierReadyMessage("OVERLAY_READY");
00113             readyMsg->setReady(true);
00114             sendToApp(readyMsg);
00115         } break;
00116     }
00117     setBootstrapedIcon();
00118     // debug output
00119     if(debugOutput) {
00120         ev << "VAST: Node " << thisNode.ip << " entered ";
00121         switch(state) {
00122             case INIT: ev << "INIT"; break;
00123             case JOINING: ev << "JOINING"; break;
00124             case READY: ev << "READY"; break;
00125         }
00126         ev << " state." << endl;
00127     }
00128 }

double Vast::distance_square ( Site  s,
VastMessage *  msg 
) [protected]

00759 {
00760     return s.coord.distanceSqr(msg->getPos());
00761 }

void Vast::processJoinTimer (  )  [protected]

00303 {
00304     GameAPIMessage *sgcMsg = new GameAPIMessage("MOVEMENT_REQUEST");
00305     sgcMsg->setCommand(MOVEMENT_REQUEST);
00306     sendToApp(sgcMsg);
00307 }

void Vast::processPingTimer (  )  [protected]

00310 {
00311     bool abnormalLeave = false;
00312     bool boundaryLeave = false;
00313     SiteMap::iterator itSites = neighborsList->Sites.begin();
00314     while(itSites != neighborsList->Sites.end()) {
00315         if(itSites->second.tstamp < 0.0) { // node is dropped cause no pong has been received see below
00316             abnormalLeave = true;
00317             if(!(itSites->second.type & NEIGHBOR)) boundaryLeave = true;
00318             itSites->second.type = UNDEF;
00319         }
00320         else if(itSites->second.tstamp < simulation.simTime() - pingTimeout) { // node showed no activity for some time request pong and mark it to be dropped next time
00321             VastMessage *vastMsg = new VastMessage("PING");
00322             vastMsg->setCommand(PING);
00323             vastMsg->setSourceNode(thisNode);
00324             vastMsg->setPos(position);
00325             vastMsg->setLength(VAST_L(vastMsg));
00326             sendMessage(vastMsg, itSites->second.addr);
00327             itSites->second.tstamp = -1.0;
00328         }
00329         ++itSites;
00330     }
00331     if(abnormalLeave) {
00332         synchronizeApp();
00333         neighborsList->removeNeighbors();
00334         if(boundaryLeave) {
00335             itSites = neighborsList->Sites.begin();
00336             while(itSites != neighborsList->Sites.end()) {
00337                 if(itSites->second.type & BOUNDARY) {
00338                     VastMessage *vastMsg = new VastMessage("ENCLOSING_NEIGHBORS_REQUEST");
00339                     vastMsg->setCommand(ENCLOSING_NEIGHBORS_REQUEST);
00340                     vastMsg->setSourceNode(thisNode);
00341                     vastMsg->setPos(position);
00342                     vastMsg->setLength(VAST_L(vastMsg));
00343                     sendMessage(vastMsg, itSites->second.addr);
00344                 }
00345                 ++itSites;
00346             }
00347         }
00348         neighborsList->buildVoronoi();
00349         //neighborsList->removeNeighbors(); should be superfluous
00350     }
00351 }

void Vast::processSecTimer (  )  [protected]

void Vast::handleJoin ( GameAPIPositionMessage *  sgcMsg  )  [protected]

00363 {
00364     NodeHandle joinNode = bootstrapOracle->getBootstrapNode();
00365     position = sgcMsg->getPosition();
00366     // check if this is the only node in the overlay
00367     if(joinNode.isUnspecified()) {
00368         changeState(READY);
00369     }
00370     else {
00371         VastMessage *vastMsg = new VastMessage("JOIN_REQUEST");
00372         vastMsg->setCommand(JOIN_REQUEST);
00373         vastMsg->setSourceNode(thisNode);
00374         vastMsg->setPos(position);
00375         vastMsg->setLength(VAST_L(vastMsg));
00376         sendMessage(vastMsg, joinNode);
00377     }
00378 }

void Vast::handleMove ( GameAPIPositionMessage *  sgcMsg  )  [protected]

00381 {
00382     Vector2D pos = sgcMsg->getPosition();
00383     // test if new position is legal
00384     if(!neighborsList->validatePosition(pos)) {
00385         GameAPIMessage *gameMsg = new GameAPIMessage("MOVEMENT_REQUEST");
00386         gameMsg->setCommand(MOVEMENT_REQUEST);
00387         sendToApp(gameMsg);
00388         return;
00389     }
00390     // send position update to neighbors
00391     SiteMap::iterator itSites = neighborsList->Sites.begin();
00392     while(itSites != neighborsList->Sites.end()) {
00393         VastMoveMessage *vastMoveMsg = new VastMoveMessage("NODE_MOVE");
00394         vastMoveMsg->setCommand(NODE_MOVE);
00395         vastMoveMsg->setSourceNode(thisNode);
00396         vastMoveMsg->setPos(position);
00397         vastMoveMsg->setNewPos(pos);
00398         vastMoveMsg->setIs_boundary(itSites->second.type & BOUNDARY);
00399         vastMoveMsg->setLength(VASTMOVE_L(vastMoveMsg));
00400         sendMessage(vastMoveMsg, itSites->second.addr);
00401         ++itSites;
00402     }
00403     // set new position
00404     position = pos;
00405     neighborsList->changePosition(pos);
00406     // update voronoi
00407     neighborsList->buildVoronoi();
00408     synchronizeApp();
00409     neighborsList->removeNeighbors();
00410 }

void Vast::handleJoinRequest ( VastMessage *  vastMsg  )  [protected]

00413 {
00414     Site *forwardSite = NULL;
00415     double min_dist;
00416     // start with this node
00417     min_dist = distance_square(neighborsList->thisSite, vastMsg);
00418     forwardSite = &neighborsList->thisSite;
00419     // iterate through all neighbors
00420     SiteMap::iterator itSites = neighborsList->Sites.begin();
00421     while(itSites != neighborsList->Sites.end()) {
00422         if(distance_square(itSites->second, vastMsg) < min_dist) {
00423             min_dist = distance_square(itSites->second, vastMsg);
00424             forwardSite = &itSites->second;
00425         }
00426         ++itSites;
00427     }
00428     // do nothing and let node retry with new position if current position is illegal
00429     if(min_dist == 0.0) {
00430         delete vastMsg;
00431     }
00432     else {
00433         // send an acknowledge or forward request if any of our neighbors is closer to joining node
00434         if(forwardSite->type & THIS) {
00435             VastListMessage *vastListMsg = new VastListMessage("JOIN_ACKNOWLEDGE");
00436             vastListMsg->setCommand(JOIN_ACKNOWLEDGE);
00437             vastListMsg->setSourceNode(thisNode);
00438             vastListMsg->setPos(position);
00439             // fill neighbors list
00440             vastListMsg->setNeighborNodeArraySize(neighborsList->getSize());
00441             vastListMsg->setNeighborPosArraySize(neighborsList->getSize());
00442             int i = 0;
00443             itSites = neighborsList->Sites.begin();
00444             while(itSites != neighborsList->Sites.end()) {
00445                 vastListMsg->setNeighborNode(i, itSites->second.addr);
00446                 vastListMsg->setNeighborPos(i, itSites->second.coord);
00447                 ++i;
00448                 ++itSites;
00449             }
00450             vastListMsg->setNeighborNodeArraySize(i);
00451             vastListMsg->setNeighborPosArraySize(i);
00452             vastListMsg->setRequestEnclosingNeighbors(false);
00453 
00454             vastListMsg->setLength(VASTLIST_L(vastListMsg));
00455             sendMessage(vastListMsg, vastMsg->getSourceNode());
00456             delete vastMsg;
00457         }
00458         else {
00459             sendMessage(vastMsg, forwardSite->addr);
00460         }
00461     }
00462 }

void Vast::handleJoinAcknowledge ( VastListMessage *  vastListMsg  )  [protected]

00465 {
00466     Vector2D p, p_join;
00467     p_join = vastListMsg->getPos();
00468     // add acceptor node
00469     changeState(READY);
00470     neighborsList->addNode(p_join, vastListMsg->getSourceNode());
00471     // add new neighbors
00472     for(unsigned int i=0; i<vastListMsg->getNeighborNodeArraySize(); i++) {
00473         p = vastListMsg->getNeighborPos(i);
00474         neighborsList->addNode(p, vastListMsg->getNeighborNode(i));
00475     }
00476     // update voronoi with new neighbors
00477     neighborsList->buildVoronoi();
00478     synchronizeApp();
00479     neighborsList->removeNeighbors();
00480     // contact new neighbors
00481     SiteMap::iterator itSites = neighborsList->Sites.begin();
00482     while(itSites != neighborsList->Sites.end()) {
00483         VastMoveMessage *vastMoveMsg = new VastMoveMessage("NODE_MOVE");
00484         vastMoveMsg->setCommand(NODE_MOVE);
00485         vastMoveMsg->setSourceNode(thisNode);
00486         vastMoveMsg->setPos(p_join);
00487         vastMoveMsg->setNewPos(position);
00488         vastMoveMsg->setIs_boundary(itSites->second.type & BOUNDARY);
00489         vastMoveMsg->setLength(VASTMOVE_L(vastMoveMsg));
00490         sendMessage(vastMoveMsg, itSites->second.addr);
00491         ++itSites;
00492     }
00493 }

void Vast::handleNodeMove ( VastMoveMessage *  vastMoveMsg  )  [protected]

00496 {
00497     Vector2D old_p, new_p;
00498     old_p = vastMoveMsg->getPos();
00499     new_p = vastMoveMsg->getNewPos();
00500     neighborsList->addNode(new_p, vastMoveMsg->getSourceNode());
00501     // update voronoi with new neighbor detection or without
00502     if(vastMoveMsg->getIs_boundary()) {
00503         neighborsList->buildVoronoi(old_p, new_p);
00504         synchronizeApp(vastMoveMsg);
00505         neighborsList->removeNeighbors();
00506         // send new neighbors
00507         VastListMessage *vastListMsg = new VastListMessage("NEW_NEIGHBORS");
00508         vastListMsg->setCommand(NEW_NEIGHBORS);
00509         vastListMsg->setSourceNode(thisNode);
00510         vastListMsg->setPos(position);
00511 
00512         vastListMsg->setNeighborNodeArraySize(neighborsList->getSize());
00513         vastListMsg->setNeighborPosArraySize(neighborsList->getSize());
00514 
00515         int i = 0;
00516         SiteMap::iterator itSites = neighborsList->Sites.begin();
00517         while(itSites != neighborsList->Sites.end()) {
00518             if(itSites->second.type & NEW) {
00519                 vastListMsg->setNeighborNode(i, itSites->second.addr);
00520                 vastListMsg->setNeighborPos(i, itSites->second.coord);
00521                 ++i;
00522             }
00523             ++itSites;
00524         }
00525         vastListMsg->setNeighborNodeArraySize(i);
00526         vastListMsg->setNeighborPosArraySize(i);
00527         vastListMsg->setRequestEnclosingNeighbors(true);
00528 
00529         vastListMsg->setLength(VASTLIST_L(vastListMsg));
00530         if(vastListMsg->getNeighborNodeArraySize() > 0) {
00531             sendMessage(vastListMsg, vastMoveMsg->getSourceNode());
00532         }
00533         else {
00534             delete vastListMsg;
00535         }
00536     }
00537     else {
00538         neighborsList->buildVoronoi();
00539         synchronizeApp(vastMoveMsg);
00540         neighborsList->removeNeighbors();
00541     }
00542 }

void Vast::handleNewNeighbors ( VastListMessage *  vastListMsg  )  [protected]

00545 {
00546     Vector2D p;
00547     // add new neighbors
00548     for(unsigned int i=0; i<vastListMsg->getNeighborNodeArraySize(); i++) {
00549         p = vastListMsg->getNeighborPos(i);
00550         neighborsList->addNode(p, vastListMsg->getNeighborNode(i));
00551 
00552         if(vastListMsg->getRequestEnclosingNeighbors()) {
00553             VastMessage *vastMsg = new VastMessage("ENCLOSING_NEIGHBORS_REQUEST");
00554             vastMsg->setCommand(ENCLOSING_NEIGHBORS_REQUEST);
00555             vastMsg->setSourceNode(thisNode);
00556             vastMsg->setPos(position);
00557             vastMsg->setLength(VAST_L(vastMsg));
00558             sendMessage(vastMsg, vastListMsg->getNeighborNode(i));
00559         }
00560     }
00561     // update voronoi with new neighbors
00562     neighborsList->buildVoronoi();
00563     synchronizeApp();
00564     neighborsList->removeNeighbors();
00565 }

void Vast::handleNodeLeave ( VastListMessage *  vastListMsg  )  [protected]

00568 {
00569     Vector2D p;
00570     neighborsList->removeNode(vastListMsg->getSourceNode());
00571     // add possible new neighbors
00572     for(unsigned int i=0; i<vastListMsg->getNeighborNodeArraySize(); i++) {
00573         p = vastListMsg->getNeighborPos(i);
00574         neighborsList->addNode(p, vastListMsg->getNeighborNode(i));
00575     }
00576     // update voronoi with new neighbors
00577     neighborsList->buildVoronoi();
00578     synchronizeApp();
00579     neighborsList->removeNeighbors();
00580 }

void Vast::handleEnclosingNeighborsRequest ( VastMessage *  vastMsg  )  [protected]

00583 {
00584     // send new neighbors
00585     VastListMessage *vastListMsg = new VastListMessage("NEW_NEIGHBORS");
00586     vastListMsg->setCommand(NEW_NEIGHBORS);
00587     vastListMsg->setSourceNode(thisNode);
00588     vastListMsg->setPos(position);
00589 
00590     vastListMsg->setNeighborNodeArraySize(neighborsList->getSize());
00591     vastListMsg->setNeighborPosArraySize(neighborsList->getSize());
00592 
00593     int i = 0;
00594     SiteMap::iterator itSites = neighborsList->Sites.begin();
00595     while(itSites != neighborsList->Sites.end()) {
00596         if((itSites->second.type & ENCLOSING) && itSites->second.addr != vastMsg->getSourceNode()) {
00597             vastListMsg->setNeighborNode(i, itSites->second.addr);
00598             vastListMsg->setNeighborPos(i, itSites->second.coord);
00599             ++i;
00600         }
00601         ++itSites;
00602     }
00603     vastListMsg->setNeighborNodeArraySize(i);
00604     vastListMsg->setNeighborPosArraySize(i);
00605     vastListMsg->setRequestEnclosingNeighbors(false);
00606 
00607     vastListMsg->setLength(VASTLIST_L(vastListMsg));
00608     if(vastListMsg->getNeighborNodeArraySize() > 0) {
00609         sendMessage(vastListMsg, vastMsg->getSourceNode());
00610     }
00611     else {
00612         delete vastListMsg;
00613     }
00614 }

void Vast::handlePing ( VastMessage *  vastMsg  )  [protected]

00617 {
00618     VastMessage *vastPongMsg = new VastMessage("PONG");
00619     vastPongMsg->setCommand(PONG);
00620     vastPongMsg->setSourceNode(thisNode);
00621     vastPongMsg->setPos(position);
00622     vastPongMsg->setLength(VAST_L(vastPongMsg));
00623     sendMessage(vastPongMsg, vastMsg->getSourceNode());
00624 }

void Vast::handlePong ( VastMessage *  vastMsg  )  [protected]

00627 {
00628     Vector2D p;
00629     // replace entry cause it was probably outdated
00630     p = vastMsg->getPos();
00631     neighborsList->addNode(p, vastMsg->getSourceNode());
00632     // update voronoi
00633     neighborsList->buildVoronoi();
00634     synchronizeApp();
00635     neighborsList->removeNeighbors();
00636 }

void Vast::handleDiscardNode ( VastDiscardMessage *  vastMsg  )  [protected]

00639 {
00640     // discard outdated entry
00641     neighborsList->removeNode(vastMsg->getDiscardNode());
00642     // update voronoi
00643     neighborsList->buildVoronoi();
00644     synchronizeApp();
00645     neighborsList->removeNeighbors();
00646 }

void Vast::sendDiscardNode ( VastMessage *  vastMsg  )  [protected]

00649 {
00650     NodeHandle discardNode;
00651     discardNode.ip = thisNode.ip;
00652     discardNode.key = vastMsg->getDestKey();
00653     // send message
00654     VastDiscardMessage *vastDiscardMsg = new VastDiscardMessage("DISCARD_NODE");
00655     vastDiscardMsg->setCommand(DISCARD_NODE);
00656     vastDiscardMsg->setSourceNode(thisNode);
00657     vastDiscardMsg->setPos(position);
00658     vastDiscardMsg->setDiscardNode(discardNode);
00659     // debug output
00660     if(debugOutput) ev << "VAST: Node " << thisNode.ip << " received message for an outdated node from " << vastMsg->getSourceNode().ip << "." << endl;
00661     vastDiscardMsg->setLength(VASTDISCARD_L(vastDiscardMsg));
00662     sendMessage(vastDiscardMsg, vastMsg->getSourceNode());
00663 }

void Vast::synchronizeApp ( VastMoveMessage *  vastMoveMsg = NULL  )  [protected]

00666 {
00667     GameAPIListMessage *sgcMsg = new GameAPIListMessage("NEIGHBOR_UPDATE");
00668     sgcMsg->setCommand(NEIGHBOR_UPDATE);
00669 
00670     sgcMsg->setRemoveNeighborArraySize(neighborsList->getSize());
00671     sgcMsg->setAddNeighborArraySize(neighborsList->getSize() + 1);
00672     sgcMsg->setNeighborPositionArraySize(neighborsList->getSize() + 1);
00673 
00674     int remSize, addSize;
00675     remSize = addSize = 0;
00676     SiteMap::iterator itSites = neighborsList->Sites.begin();
00677     while(itSites != neighborsList->Sites.end()) {
00678         if(itSites->second.type == UNDEF) {
00679             sgcMsg->setRemoveNeighbor(remSize, itSites->second.addr);
00680             ++remSize;
00681         }
00682         else if(!itSites->second.isAdded) {
00683             sgcMsg->setAddNeighbor(addSize, itSites->second.addr);
00684             sgcMsg->setNeighborPosition(addSize, itSites->second.coord);
00685             itSites->second.isAdded = true;
00686             ++addSize;
00687         }
00688         ++itSites;
00689     }
00690 
00691     if(vastMoveMsg &&
00692        neighborsList->Sites.find(vastMoveMsg->getSourceNode()) != neighborsList->Sites.end() &&
00693        neighborsList->Sites.find(vastMoveMsg->getSourceNode())->second.isAdded) {
00694         sgcMsg->setAddNeighbor(addSize, vastMoveMsg->getSourceNode());
00695         sgcMsg->setNeighborPosition(addSize, vastMoveMsg->getNewPos());
00696         ++addSize;
00697     }
00698 
00699     sgcMsg->setRemoveNeighborArraySize(remSize);
00700     sgcMsg->setAddNeighborArraySize(addSize);
00701     sgcMsg->setNeighborPositionArraySize(addSize);
00702 
00703     if(sgcMsg->getAddNeighborArraySize() || sgcMsg->getRemoveNeighborArraySize()) {
00704         sendToApp(sgcMsg);
00705     }
00706     else {
00707         delete sgcMsg;
00708     }
00709 }


Member Data Documentation

double Vast::AOI_size [protected]

Vector2D Vast::position [protected]

NeighborsList* Vast::neighborsList [protected]

long Vast::joinRequestBytesSent [protected]

long Vast::joinAcknowledgeBytesSent [protected]

long Vast::nodeMoveBytesSent [protected]

long Vast::newNeighborsBytesSent [protected]

long Vast::nodeLeaveBytesSent [protected]

long Vast::enclosingNeighborsRequestBytesSent [protected]

long Vast::pingBytesSent [protected]

long Vast::pongBytesSent [protected]

long Vast::discardNodeBytesSent [protected]

long Vast::maxBytesPerSecondSent [protected]

long Vast::averageBytesPerSecondSent [protected]

long Vast::bytesPerSecond [protected]

bool Vast::debugVoronoiOutput [protected]

bool Vast::ignoreFalseKeys [protected]

double Vast::joinTimeout [protected]

double Vast::pingTimeout [protected]

cMessage* Vast::join_timer [protected]

cMessage* Vast::ping_timer [protected]

cMessage* Vast::sec_timer [protected]


The documentation for this class was generated from the following files:
Generated on Thu Apr 17 13:19:30 2008 for ITM OverSim by  doxygen 1.5.3