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 handleEvent (GameAPIMessage *msg)
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]

00866 {
00867     // destroy self timer messages
00868     cancelAndDelete(join_timer);
00869     cancelAndDelete(ping_timer);
00870     cancelAndDelete(sec_timer);
00871 }


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.

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

void Vast::finishOverlay (  )  [virtual]

collects statistical data in derived class

Reimplemented from BaseOverlay.

00826 {
00827     bootstrapOracle->removePeer(thisNode);
00828 
00829     simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
00830     if(time == 0) return;
00831 
00832     // collect statistics
00833     globalStatistics->addStdDev("Vast: JOIN_REQUEST bytes sent/s", joinRequestBytesSent/time);
00834     globalStatistics->addStdDev("Vast: JOIN_ACKNOWLEDGE bytes sent/s", joinAcknowledgeBytesSent/time);
00835     globalStatistics->addStdDev("Vast: NODE_MOVE bytes sent/s", nodeMoveBytesSent/time);
00836     globalStatistics->addStdDev("Vast: NEW_NEIGHBORS bytes sent/s", newNeighborsBytesSent/time);
00837     globalStatistics->addStdDev("Vast: NODE_LEAVE bytes sent/s", nodeLeaveBytesSent/time);
00838     globalStatistics->addStdDev("Vast: ENCLOSING_NEIGHBORS_REQUEST bytes sent/s", enclosingNeighborsRequestBytesSent/time);
00839     globalStatistics->addStdDev("Vast: PING bytes sent/s", pingBytesSent/time);
00840     globalStatistics->addStdDev("Vast: PONG bytes sent/s", pongBytesSent/time);
00841     globalStatistics->addStdDev("Vast: DISCARD_NODE bytes sent/s", discardNodeBytesSent/time);
00842 
00843     globalStatistics->addStdDev("max bytes/second sent", maxBytesPerSecondSent);
00844     globalStatistics->addStdDev("average bytes/second sent", averageBytesPerSecondSent / time);
00845 }

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

Processes messages from underlay.

Parameters:
msg Message from UDP

Reimplemented from BaseOverlay.

00202 {
00203     if(state == INIT) {
00204         delete msg;
00205         return;
00206     }
00207     if(dynamic_cast<VastMessage*>(msg)) {
00208         VastMessage* vastMsg = check_and_cast<VastMessage*>(msg);
00209         if(ignoreFalseKeys || vastMsg->getDestKey() == thisNode.key) {
00210             // debug output
00211             if(debugOutput) ev << "VAST: Node " << thisNode.ip << " received " << vastMsg->name() << " from " << vastMsg->getSourceNode().ip << "." << endl;
00212             bool doUpdate = true;
00213             if(state == READY) {
00214                 switch(vastMsg->getCommand()) {
00215                     case JOIN_REQUEST: {
00216                         handleJoinRequest(vastMsg);
00217                         doUpdate = false;
00218                     } break;
00219                     case NODE_MOVE: {
00220                         VastMoveMessage* vastMoveMsg = check_and_cast<VastMoveMessage*>(msg);
00221                         handleNodeMove(vastMoveMsg);
00222                     } break;
00223                     case NEW_NEIGHBORS: {
00224                         VastListMessage* vastListMsg = check_and_cast<VastListMessage*>(msg);
00225                         handleNewNeighbors(vastListMsg);
00226                     } break;
00227                     case NODE_LEAVE: {
00228                         VastListMessage* vastListMsg = check_and_cast<VastListMessage*>(msg);
00229                         handleNodeLeave(vastListMsg);
00230                     } break;
00231                     case ENCLOSING_NEIGHBORS_REQUEST: {
00232                         handleEnclosingNeighborsRequest(vastMsg);
00233                     } break;
00234                     case PING: {
00235                         handlePing(vastMsg);
00236                     } break;
00237                     case PONG: {
00238                         handlePong(vastMsg);
00239                     } break;
00240                     case DISCARD_NODE: {
00241                         VastDiscardMessage* vastDiscardMsg = check_and_cast<VastDiscardMessage*>(msg);
00242                         handleDiscardNode(vastDiscardMsg);
00243                     } break;
00244                     case VAST_EVENT: {
00245                         sendToApp( vastMsg->decapsulate() );
00246                         doUpdate = false;
00247                         delete vastMsg;
00248                     } break;
00249                 }
00250                 // update timestamp
00251                 if(doUpdate) {
00252                     neighborsList->updateTimeStamp(vastMsg->getSourceNode());
00253                     delete msg;
00254                 }
00255             }
00256             else if(state == JOINING && vastMsg->getCommand() == JOIN_ACKNOWLEDGE) {
00257                 VastListMessage* vastListMsg = check_and_cast<VastListMessage*>(msg);
00258                 handleJoinAcknowledge(vastListMsg);
00259                 delete msg;
00260             }
00261             else delete msg;
00262         }
00263         else {
00264             sendDiscardNode(vastMsg);
00265             delete msg;
00266         }
00267     }
00268     else delete msg;
00269 }

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

Processes "timer" self-messages.

Parameters:
msg A self-message

Reimplemented from BaseOverlay.

00142 {
00143     if(msg->isName("join_timer")) {
00144         //reset timer
00145         cancelEvent(join_timer);
00146         scheduleAt(simulation.simTime() + joinTimeout, msg);
00147         // handle event
00148         processJoinTimer();
00149     }
00150     else if(msg->isName("ping_timer")) {
00151         //reset timer
00152         cancelEvent(ping_timer);
00153         scheduleAt(simulation.simTime() + pingTimeout, msg);
00154         // handle event
00155         processPingTimer();
00156     }
00157     else if(msg->isName("sec_timer")) {
00158         //reset timer
00159         cancelEvent(sec_timer);
00160         scheduleAt(simulation.simTime() + 1, msg);
00161         // handle event
00162         processSecTimer();
00163     }
00164 }

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

Processes non-commonAPI messages.

Parameters:
msg non-commonAPIMessage

Reimplemented from BaseOverlay.

00167 {
00168     if(dynamic_cast<GameAPIMessage*>(msg)) {
00169         GameAPIMessage* gameAPIMsg = check_and_cast<GameAPIMessage*>(msg);
00170         // debug output
00171         if(debugOutput) ev << "VAST: Node " << thisNode.ip << " received " << gameAPIMsg->name() << " from application." << endl;
00172         switch(gameAPIMsg->getCommand()) {
00173             case MOVEMENT_INDICATION: {
00174                 GameAPIPositionMessage* gameAPIPosMsg = check_and_cast<GameAPIPositionMessage*>(msg);
00175                 if(state == JOINING) {
00176                     handleJoin(gameAPIPosMsg);
00177                     delete msg;
00178                 }
00179                 else if(state == READY) {
00180                     handleMove(gameAPIPosMsg);
00181                     delete msg;
00182                 }
00183             } break;
00184             case GAMEEVENT_CHAT:
00185             case GAMEEVENT_SNOW:
00186             case GAMEEVENT_FROZEN:
00187                 handleEvent( gameAPIMsg );
00188                 delete msg;
00189                 break;
00190             //case EVENT: {
00191                 // insert handling for additional application messages like events etc. here
00192             //} break;
00193             default: {
00194                 delete msg;
00195             }
00196         }
00197     }
00198     else delete msg;
00199 }

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

callback-method for events at the NotificationBoard

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

Reimplemented from BaseOverlay.

00272 {
00273     if(category == NF_OVERLAY_NODE_GRACEFUL_LEAVE && state == READY) {
00274         int i;
00275         // debug output
00276         if(debugOutput) {
00277             ev << "VAST: Node " << thisNode.ip << " is leaving the overlay." << endl;
00278         }
00279 
00280         // generate node leave messages
00281         VastListMessage *vastListMsg = new VastListMessage("NODE_LEAVE");
00282         vastListMsg->setCommand(NODE_LEAVE);
00283         vastListMsg->setSourceNode(thisNode);
00284         vastListMsg->setPos(position);
00285         // fill neighbors list
00286         vastListMsg->setNeighborNodeArraySize(neighborsList->getSize());
00287         vastListMsg->setNeighborPosArraySize(neighborsList->getSize());
00288         i = 0;
00289         SiteMap::iterator itSites = neighborsList->Sites.begin();
00290         while(itSites != neighborsList->Sites.end()) {
00291             if(itSites->second.type & ENCLOSING) {
00292                 vastListMsg->setNeighborNode(i, itSites->second.addr);
00293                 vastListMsg->setNeighborPos(i, itSites->second.coord);
00294                 ++i;
00295             }
00296             ++itSites;
00297         }
00298         vastListMsg->setNeighborNodeArraySize(i);
00299         vastListMsg->setNeighborPosArraySize(i);
00300         vastListMsg->setRequestEnclosingNeighbors(false);
00301 
00302         vastListMsg->setLength(VASTLIST_L(vastListMsg));
00303         if(vastListMsg->getNeighborNodeArraySize() > 0) {
00304             itSites = neighborsList->Sites.begin();
00305             while(itSites != neighborsList->Sites.end()) {
00306                 VastListMessage *vastCopyMsg = new VastListMessage(*vastListMsg);
00307                 // prevent notification board from taking the message
00308                take(vastCopyMsg);
00309                sendMessage(vastCopyMsg, itSites->second.addr);
00310                ++itSites;
00311             }
00312         }
00313         delete vastListMsg;
00314 
00315         CompReadyMessage* readyMsg = new CompReadyMessage("OVERLAY_FINISHED");
00316         readyMsg->setReady(false);
00317         readyMsg->setComp(getThisCompType());
00318         take(readyMsg);
00319         sendToApp(readyMsg);
00320 
00321         changeState(INIT);
00322     }
00323 }

double Vast::getAOI (  ) 

00848 {
00849     Enter_Method_Silent();
00850     return AOI_size;
00851 }

Vector2D Vast::getPosition (  ) 

00854 {
00855     Enter_Method_Silent();
00856     return position;
00857 }

NeighborsList * Vast::getList (  ) 

Referenced by ConnectivityProbe::getComponentSize().

00860 {
00861     Enter_Method_Silent();
00862     return neighborsList;
00863 }

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

Referenced by changeState(), handleMove(), handleUDPMessage(), processJoinTimer(), receiveChangeNotification(), and synchronizeApp().

00756 {
00757     // debug output
00758     if(debugOutput) ev << "VAST: Node " << thisNode.ip << " sending " << msg->name() << " to application." << endl;
00759     send(msg, "to_app");
00760 }

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

Referenced by handleEnclosingNeighborsRequest(), handleEvent(), handleJoin(), handleJoinAcknowledge(), handleJoinRequest(), handleMove(), handleNewNeighbors(), handleNodeMove(), handlePing(), processPingTimer(), receiveChangeNotification(), and sendDiscardNode().

00763 {
00764     // collect statistics
00765     switch(vastMsg->getCommand()) {
00766         case JOIN_REQUEST: {
00767             joinRequestBytesSent += vastMsg->byteLength();
00768         } break;
00769         case JOIN_ACKNOWLEDGE: {
00770             joinAcknowledgeBytesSent += vastMsg->byteLength();
00771         } break;
00772         case NODE_MOVE: {
00773             nodeMoveBytesSent += vastMsg->byteLength();
00774         } break;
00775         case NEW_NEIGHBORS: {
00776             newNeighborsBytesSent += vastMsg->byteLength();
00777         } break;
00778         case NODE_LEAVE: {
00779             nodeLeaveBytesSent += vastMsg->byteLength();
00780         } break;
00781         case ENCLOSING_NEIGHBORS_REQUEST: {
00782             enclosingNeighborsRequestBytesSent += vastMsg->byteLength();
00783         } break;
00784         case PING: {
00785             pingBytesSent += vastMsg->byteLength();
00786         } break;
00787         case PONG: {
00788             pongBytesSent += vastMsg->byteLength();
00789         } break;
00790         case DISCARD_NODE: {
00791             discardNodeBytesSent += vastMsg->byteLength();
00792         } break;
00793     }
00794     bytesPerSecond += vastMsg->byteLength();
00795 
00796     // debug output
00797     if(debugOutput) ev << "VAST: Node " << thisNode.ip << " sending " << vastMsg->name() << " to " << destAddr.ip << "." << endl;
00798     vastMsg->setDestKey(destAddr.key);
00799     sendMessageToUDP(destAddr, vastMsg);
00800 }

void Vast::setBootstrapedIcon (  )  [protected]

Referenced by changeState().

00808 {
00809     if(ev.isGUI()) {
00810         if(state == READY) {
00811             parentModule()->parentModule()->displayString().setTagArg("i2", 1, "green");
00812             displayString().setTagArg("i", 1, "green");
00813         }
00814         else if(state == JOINING) {
00815             parentModule()->parentModule()->displayString().setTagArg("i2", 1, "yellow");
00816             displayString().setTagArg("i", 1, "yellow");
00817         }
00818         else {
00819             parentModule()->parentModule()->displayString().setTagArg("i2", 1, "red");
00820             displayString().setTagArg("i", 1, "red");
00821         }
00822     }
00823 }

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

Referenced by handleJoin(), handleJoinAcknowledge(), initializeOverlay(), and receiveChangeNotification().

00100 {
00101     switch(state) {
00102         case INIT: {
00103             this->state = INIT;
00104             bootstrapOracle->removePeer(thisNode);
00105         } break;
00106         case JOINING: {
00107             this->state = JOINING;
00108             scheduleAt(simulation.simTime(), join_timer);
00109             scheduleAt(simulation.simTime() + 1.0, sec_timer);
00110         } break;
00111         case READY: {
00112             this->state = READY;
00113             cancelEvent(join_timer);
00114             neighborsList->initializeList(position, thisNode, AOI_size);
00115             bootstrapOracle->registerPeer(thisNode);
00116             scheduleAt(simulation.simTime() + pingTimeout, ping_timer);
00117             // tell the application we are ready
00118             CompReadyMessage* readyMsg = new CompReadyMessage("OVERLAY_READY");
00119             readyMsg->setReady(true);
00120             readyMsg->setComp(getThisCompType());
00121             sendToApp(readyMsg);
00122             GameAPIResizeAOIMessage* gameMsg = new GameAPIResizeAOIMessage("RESIZE_AOI");
00123             gameMsg->setCommand(RESIZE_AOI);
00124             gameMsg->setAOIsize(AOI_size);
00125             sendToApp(gameMsg);
00126         } break;
00127     }
00128     setBootstrapedIcon();
00129     // debug output
00130     if(debugOutput) {
00131         ev << "VAST: Node " << thisNode.ip << " entered ";
00132         switch(state) {
00133             case INIT: ev << "INIT"; break;
00134             case JOINING: ev << "JOINING"; break;
00135             case READY: ev << "READY"; break;
00136         }
00137         ev << " state." << endl;
00138     }
00139 }

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

Referenced by handleJoinRequest().

00803 {
00804     return s.coord.distanceSqr(msg->getPos());
00805 }

void Vast::processJoinTimer (  )  [protected]

Referenced by handleTimerEvent().

00326 {
00327     GameAPIMessage *sgcMsg = new GameAPIMessage("MOVEMENT_REQUEST");
00328     sgcMsg->setCommand(MOVEMENT_REQUEST);
00329     sendToApp(sgcMsg);
00330 }

void Vast::processPingTimer (  )  [protected]

Referenced by handleTimerEvent().

00333 {
00334     bool abnormalLeave = false;
00335     bool boundaryLeave = false;
00336     SiteMap::iterator itSites = neighborsList->Sites.begin();
00337     while(itSites != neighborsList->Sites.end()) {
00338         if(itSites->second.tstamp < 0.0) { // node is dropped cause no pong has been received see below
00339             abnormalLeave = true;
00340             if(!(itSites->second.type & NEIGHBOR)) boundaryLeave = true;
00341             itSites->second.type = UNDEF;
00342         }
00343         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
00344             VastMessage *vastMsg = new VastMessage("PING");
00345             vastMsg->setCommand(PING);
00346             vastMsg->setSourceNode(thisNode);
00347             vastMsg->setPos(position);
00348             vastMsg->setLength(VAST_L(vastMsg));
00349             sendMessage(vastMsg, itSites->second.addr);
00350             itSites->second.tstamp = -1.0;
00351         }
00352         ++itSites;
00353     }
00354     if(abnormalLeave) {
00355         synchronizeApp();
00356         neighborsList->removeNeighbors();
00357         if(boundaryLeave) {
00358             itSites = neighborsList->Sites.begin();
00359             while(itSites != neighborsList->Sites.end()) {
00360                 if(itSites->second.type & BOUNDARY) {
00361                     VastMessage *vastMsg = new VastMessage("ENCLOSING_NEIGHBORS_REQUEST");
00362                     vastMsg->setCommand(ENCLOSING_NEIGHBORS_REQUEST);
00363                     vastMsg->setSourceNode(thisNode);
00364                     vastMsg->setPos(position);
00365                     vastMsg->setLength(VAST_L(vastMsg));
00366                     sendMessage(vastMsg, itSites->second.addr);
00367                 }
00368                 ++itSites;
00369             }
00370         }
00371         neighborsList->buildVoronoi();
00372         //neighborsList->removeNeighbors(); should be superfluous
00373     }
00374 }

void Vast::processSecTimer (  )  [protected]

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

Referenced by handleAppMessage().

00386 {
00387     NodeHandle joinNode = bootstrapList->getBootstrapNode();
00388     position = sgcMsg->getPosition();
00389     // check if this is the only node in the overlay
00390     if(joinNode.isUnspecified()) {
00391         changeState(READY);
00392     }
00393     else {
00394         VastMessage *vastMsg = new VastMessage("JOIN_REQUEST");
00395         vastMsg->setCommand(JOIN_REQUEST);
00396         vastMsg->setSourceNode(thisNode);
00397         vastMsg->setPos(position);
00398         vastMsg->setLength(VAST_L(vastMsg));
00399         sendMessage(vastMsg, joinNode);
00400     }
00401 }

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

Referenced by handleAppMessage().

00404 {
00405     Vector2D pos = sgcMsg->getPosition();
00406     // test if new position is legal
00407     if(!neighborsList->validatePosition(pos)) {
00408         GameAPIMessage *gameMsg = new GameAPIMessage("MOVEMENT_REQUEST");
00409         gameMsg->setCommand(MOVEMENT_REQUEST);
00410         sendToApp(gameMsg);
00411         return;
00412     }
00413     // send position update to neighbors
00414     SiteMap::iterator itSites = neighborsList->Sites.begin();
00415     while(itSites != neighborsList->Sites.end()) {
00416         VastMoveMessage *vastMoveMsg = new VastMoveMessage("NODE_MOVE");
00417         vastMoveMsg->setCommand(NODE_MOVE);
00418         vastMoveMsg->setSourceNode(thisNode);
00419         vastMoveMsg->setPos(position);
00420         vastMoveMsg->setNewPos(pos);
00421         vastMoveMsg->setIs_boundary(itSites->second.type & BOUNDARY);
00422         vastMoveMsg->setLength(VASTMOVE_L(vastMoveMsg));
00423         sendMessage(vastMoveMsg, itSites->second.addr);
00424         ++itSites;
00425     }
00426     // set new position
00427     position = pos;
00428     neighborsList->changePosition(pos);
00429     // update voronoi
00430     neighborsList->buildVoronoi();
00431     synchronizeApp();
00432     neighborsList->removeNeighbors();
00433 }

void Vast::handleEvent ( GameAPIMessage *  msg  )  [protected]

Referenced by handleAppMessage().

00436 {
00437     // send evbent to neighbors
00438     SiteMap::iterator itSites = neighborsList->Sites.begin();
00439     while(itSites != neighborsList->Sites.end()) {
00440         VastEventMessage *vastMsg = new VastEventMessage("EVENT");
00441         vastMsg->setCommand(VAST_EVENT);
00442         vastMsg->encapsulate( (cMessage*) msg->dup() );
00443         // FIXME: Message length!
00444         sendMessage(vastMsg, itSites->second.addr);
00445         ++itSites;
00446     }
00447 }

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

Referenced by handleUDPMessage().

00450 {
00451     Site *forwardSite = NULL;
00452     double min_dist;
00453     // start with this node
00454     min_dist = distance_square(neighborsList->thisSite, vastMsg);
00455     forwardSite = &neighborsList->thisSite;
00456     // iterate through all neighbors
00457     SiteMap::iterator itSites = neighborsList->Sites.begin();
00458     while(itSites != neighborsList->Sites.end()) {
00459         if(distance_square(itSites->second, vastMsg) < min_dist) {
00460             min_dist = distance_square(itSites->second, vastMsg);
00461             forwardSite = &itSites->second;
00462         }
00463         ++itSites;
00464     }
00465     // do nothing and let node retry with new position if current position is illegal
00466     if(min_dist == 0.0) {
00467         delete vastMsg;
00468     }
00469     else {
00470         // send an acknowledge or forward request if any of our neighbors is closer to joining node
00471         if(forwardSite->type & THIS) {
00472             VastListMessage *vastListMsg = new VastListMessage("JOIN_ACKNOWLEDGE");
00473             vastListMsg->setCommand(JOIN_ACKNOWLEDGE);
00474             vastListMsg->setSourceNode(thisNode);
00475             vastListMsg->setPos(position);
00476             // fill neighbors list
00477             vastListMsg->setNeighborNodeArraySize(neighborsList->getSize());
00478             vastListMsg->setNeighborPosArraySize(neighborsList->getSize());
00479             int i = 0;
00480             itSites = neighborsList->Sites.begin();
00481             while(itSites != neighborsList->Sites.end()) {
00482                 vastListMsg->setNeighborNode(i, itSites->second.addr);
00483                 vastListMsg->setNeighborPos(i, itSites->second.coord);
00484                 ++i;
00485                 ++itSites;
00486             }
00487             vastListMsg->setNeighborNodeArraySize(i);
00488             vastListMsg->setNeighborPosArraySize(i);
00489             vastListMsg->setRequestEnclosingNeighbors(false);
00490 
00491             vastListMsg->setLength(VASTLIST_L(vastListMsg));
00492             sendMessage(vastListMsg, vastMsg->getSourceNode());
00493             delete vastMsg;
00494         }
00495         else {
00496             sendMessage(vastMsg, forwardSite->addr);
00497         }
00498     }
00499 }

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

Referenced by handleUDPMessage().

00502 {
00503     Vector2D p, p_join;
00504     p_join = vastListMsg->getPos();
00505     // add acceptor node
00506     changeState(READY);
00507     neighborsList->addNode(p_join, vastListMsg->getSourceNode());
00508     // add new neighbors
00509     for(unsigned int i=0; i<vastListMsg->getNeighborNodeArraySize(); i++) {
00510         p = vastListMsg->getNeighborPos(i);
00511         neighborsList->addNode(p, vastListMsg->getNeighborNode(i));
00512     }
00513     // update voronoi with new neighbors
00514     neighborsList->buildVoronoi();
00515     synchronizeApp();
00516     neighborsList->removeNeighbors();
00517     // contact new neighbors
00518     SiteMap::iterator itSites = neighborsList->Sites.begin();
00519     while(itSites != neighborsList->Sites.end()) {
00520         VastMoveMessage *vastMoveMsg = new VastMoveMessage("NODE_MOVE");
00521         vastMoveMsg->setCommand(NODE_MOVE);
00522         vastMoveMsg->setSourceNode(thisNode);
00523         vastMoveMsg->setPos(p_join);
00524         vastMoveMsg->setNewPos(position);
00525         vastMoveMsg->setIs_boundary(itSites->second.type & BOUNDARY);
00526         vastMoveMsg->setLength(VASTMOVE_L(vastMoveMsg));
00527         sendMessage(vastMoveMsg, itSites->second.addr);
00528         ++itSites;
00529     }
00530 }

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

Referenced by handleUDPMessage().

00533 {
00534     RECORD_STATS(
00535             globalStatistics->addStdDev(
00536                 "Vast: MoveDelay",
00537                 simulation.simTime() - vastMoveMsg->creationTime()
00538                 );
00539             );
00540 
00541     Vector2D old_p, new_p;
00542     old_p = vastMoveMsg->getPos();
00543     new_p = vastMoveMsg->getNewPos();
00544     neighborsList->addNode(new_p, vastMoveMsg->getSourceNode());
00545     // update voronoi with new neighbor detection or without
00546     if(vastMoveMsg->getIs_boundary()) {
00547         neighborsList->buildVoronoi(old_p, new_p);
00548         synchronizeApp(vastMoveMsg);
00549         neighborsList->removeNeighbors();
00550         // send new neighbors
00551         VastListMessage *vastListMsg = new VastListMessage("NEW_NEIGHBORS");
00552         vastListMsg->setCommand(NEW_NEIGHBORS);
00553         vastListMsg->setSourceNode(thisNode);
00554         vastListMsg->setPos(position);
00555 
00556         vastListMsg->setNeighborNodeArraySize(neighborsList->getSize());
00557         vastListMsg->setNeighborPosArraySize(neighborsList->getSize());
00558 
00559         int i = 0;
00560         SiteMap::iterator itSites = neighborsList->Sites.begin();
00561         while(itSites != neighborsList->Sites.end()) {
00562             if(itSites->second.type & NEW) {
00563                 vastListMsg->setNeighborNode(i, itSites->second.addr);
00564                 vastListMsg->setNeighborPos(i, itSites->second.coord);
00565                 ++i;
00566             }
00567             ++itSites;
00568         }
00569         vastListMsg->setNeighborNodeArraySize(i);
00570         vastListMsg->setNeighborPosArraySize(i);
00571         vastListMsg->setRequestEnclosingNeighbors(true);
00572 
00573         vastListMsg->setLength(VASTLIST_L(vastListMsg));
00574         if(vastListMsg->getNeighborNodeArraySize() > 0) {
00575             sendMessage(vastListMsg, vastMoveMsg->getSourceNode());
00576         }
00577         else {
00578             delete vastListMsg;
00579         }
00580     }
00581     else {
00582         neighborsList->buildVoronoi();
00583         synchronizeApp(vastMoveMsg);
00584         neighborsList->removeNeighbors();
00585     }
00586 }

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

Referenced by handleUDPMessage().

00589 {
00590     Vector2D p;
00591     // add new neighbors
00592     for(unsigned int i=0; i<vastListMsg->getNeighborNodeArraySize(); i++) {
00593         p = vastListMsg->getNeighborPos(i);
00594         neighborsList->addNode(p, vastListMsg->getNeighborNode(i));
00595 
00596         if(vastListMsg->getRequestEnclosingNeighbors()) {
00597             VastMessage *vastMsg = new VastMessage("ENCLOSING_NEIGHBORS_REQUEST");
00598             vastMsg->setCommand(ENCLOSING_NEIGHBORS_REQUEST);
00599             vastMsg->setSourceNode(thisNode);
00600             vastMsg->setPos(position);
00601             vastMsg->setLength(VAST_L(vastMsg));
00602             sendMessage(vastMsg, vastListMsg->getNeighborNode(i));
00603         }
00604     }
00605     // update voronoi with new neighbors
00606     neighborsList->buildVoronoi();
00607     synchronizeApp();
00608     neighborsList->removeNeighbors();
00609 }

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

Referenced by handleUDPMessage().

00612 {
00613     Vector2D p;
00614     neighborsList->removeNode(vastListMsg->getSourceNode());
00615     // add possible new neighbors
00616     for(unsigned int i=0; i<vastListMsg->getNeighborNodeArraySize(); i++) {
00617         p = vastListMsg->getNeighborPos(i);
00618         neighborsList->addNode(p, vastListMsg->getNeighborNode(i));
00619     }
00620     // update voronoi with new neighbors
00621     neighborsList->buildVoronoi();
00622     synchronizeApp();
00623     neighborsList->removeNeighbors();
00624 }

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

Referenced by handleUDPMessage().

00627 {
00628     // send new neighbors
00629     VastListMessage *vastListMsg = new VastListMessage("NEW_NEIGHBORS");
00630     vastListMsg->setCommand(NEW_NEIGHBORS);
00631     vastListMsg->setSourceNode(thisNode);
00632     vastListMsg->setPos(position);
00633 
00634     vastListMsg->setNeighborNodeArraySize(neighborsList->getSize());
00635     vastListMsg->setNeighborPosArraySize(neighborsList->getSize());
00636 
00637     int i = 0;
00638     SiteMap::iterator itSites = neighborsList->Sites.begin();
00639     while(itSites != neighborsList->Sites.end()) {
00640         if((itSites->second.type & ENCLOSING) && itSites->second.addr != vastMsg->getSourceNode()) {
00641             vastListMsg->setNeighborNode(i, itSites->second.addr);
00642             vastListMsg->setNeighborPos(i, itSites->second.coord);
00643             ++i;
00644         }
00645         ++itSites;
00646     }
00647     vastListMsg->setNeighborNodeArraySize(i);
00648     vastListMsg->setNeighborPosArraySize(i);
00649     vastListMsg->setRequestEnclosingNeighbors(false);
00650 
00651     vastListMsg->setLength(VASTLIST_L(vastListMsg));
00652     if(vastListMsg->getNeighborNodeArraySize() > 0) {
00653         sendMessage(vastListMsg, vastMsg->getSourceNode());
00654     }
00655     else {
00656         delete vastListMsg;
00657     }
00658 }

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

Referenced by handleUDPMessage().

00661 {
00662     VastMessage *vastPongMsg = new VastMessage("PONG");
00663     vastPongMsg->setCommand(PONG);
00664     vastPongMsg->setSourceNode(thisNode);
00665     vastPongMsg->setPos(position);
00666     vastPongMsg->setLength(VAST_L(vastPongMsg));
00667     sendMessage(vastPongMsg, vastMsg->getSourceNode());
00668 }

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

Referenced by handleUDPMessage().

00671 {
00672     Vector2D p;
00673     // replace entry cause it was probably outdated
00674     p = vastMsg->getPos();
00675     neighborsList->addNode(p, vastMsg->getSourceNode());
00676     // update voronoi
00677     neighborsList->buildVoronoi();
00678     synchronizeApp();
00679     neighborsList->removeNeighbors();
00680 }

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

Referenced by handleUDPMessage().

00683 {
00684     // discard outdated entry
00685     neighborsList->removeNode(vastMsg->getDiscardNode());
00686     // update voronoi
00687     neighborsList->buildVoronoi();
00688     synchronizeApp();
00689     neighborsList->removeNeighbors();
00690 }

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

Referenced by handleUDPMessage().

00693 {
00694     NodeHandle discardNode;
00695     discardNode.ip = thisNode.ip;
00696     discardNode.key = vastMsg->getDestKey();
00697     // send message
00698     VastDiscardMessage *vastDiscardMsg = new VastDiscardMessage("DISCARD_NODE");
00699     vastDiscardMsg->setCommand(DISCARD_NODE);
00700     vastDiscardMsg->setSourceNode(thisNode);
00701     vastDiscardMsg->setPos(position);
00702     vastDiscardMsg->setDiscardNode(discardNode);
00703     // debug output
00704     if(debugOutput) ev << "VAST: Node " << thisNode.ip << " received message for an outdated node from " << vastMsg->getSourceNode().ip << "." << endl;
00705     vastDiscardMsg->setLength(VASTDISCARD_L(vastDiscardMsg));
00706     sendMessage(vastDiscardMsg, vastMsg->getSourceNode());
00707 }

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

Referenced by handleDiscardNode(), handleJoinAcknowledge(), handleMove(), handleNewNeighbors(), handleNodeLeave(), handleNodeMove(), handlePong(), and processPingTimer().

00710 {
00711     GameAPIListMessage *sgcMsg = new GameAPIListMessage("NEIGHBOR_UPDATE");
00712     sgcMsg->setCommand(NEIGHBOR_UPDATE);
00713 
00714     sgcMsg->setRemoveNeighborArraySize(neighborsList->getSize());
00715     sgcMsg->setAddNeighborArraySize(neighborsList->getSize() + 1);
00716     sgcMsg->setNeighborPositionArraySize(neighborsList->getSize() + 1);
00717 
00718     int remSize, addSize;
00719     remSize = addSize = 0;
00720     SiteMap::iterator itSites = neighborsList->Sites.begin();
00721     while(itSites != neighborsList->Sites.end()) {
00722         if(itSites->second.type == UNDEF) {
00723             sgcMsg->setRemoveNeighbor(remSize, itSites->second.addr);
00724             ++remSize;
00725         }
00726         else if(!itSites->second.isAdded) {
00727             sgcMsg->setAddNeighbor(addSize, itSites->second.addr);
00728             sgcMsg->setNeighborPosition(addSize, itSites->second.coord);
00729             itSites->second.isAdded = true;
00730             ++addSize;
00731         }
00732         ++itSites;
00733     }
00734 
00735     if(vastMoveMsg &&
00736        neighborsList->Sites.find(vastMoveMsg->getSourceNode()) != neighborsList->Sites.end() &&
00737        neighborsList->Sites.find(vastMoveMsg->getSourceNode())->second.isAdded) {
00738         sgcMsg->setAddNeighbor(addSize, vastMoveMsg->getSourceNode());
00739         sgcMsg->setNeighborPosition(addSize, vastMoveMsg->getNewPos());
00740         ++addSize;
00741     }
00742 
00743     sgcMsg->setRemoveNeighborArraySize(remSize);
00744     sgcMsg->setAddNeighborArraySize(addSize);
00745     sgcMsg->setNeighborPositionArraySize(addSize);
00746 
00747     if(sgcMsg->getAddNeighborArraySize() || sgcMsg->getRemoveNeighborArraySize()) {
00748         sendToApp(sgcMsg);
00749     }
00750     else {
00751         delete sgcMsg;
00752     }
00753 }


Member Data Documentation

double Vast::AOI_size [protected]

Vector2D Vast::position [protected]

long Vast::joinRequestBytesSent [protected]

long Vast::nodeMoveBytesSent [protected]

long Vast::newNeighborsBytesSent [protected]

long Vast::nodeLeaveBytesSent [protected]

long Vast::pingBytesSent [protected]

long Vast::pongBytesSent [protected]

long Vast::discardNodeBytesSent [protected]

long Vast::maxBytesPerSecondSent [protected]

long Vast::bytesPerSecond [protected]

bool Vast::debugVoronoiOutput [protected]

Referenced by initializeOverlay().

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 Fri Sep 19 13:05:08 2008 for ITM OverSim by  doxygen 1.5.5