MyOverlay.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 
00023 #include <iostream>
00024 
00025 #include <UnderlayConfigurator.h>
00026 #include <GlobalStatistics.h>
00027 
00028 #include "MyOverlay_m.h"
00029 
00030 #include "MyOverlay.h"
00031 
00032 
00033 // Important! This line must be present for each module you extend (see BaseApp)
00034 Define_Module(MyOverlay);
00035 
00036 // To convert between IP addresses (which have bit 24 active), and keys (which don't), we'll need to set or remove this bit.
00037 #define BIGBIT (1 << 24)
00038 
00039 
00040 // Called when the module is being initialized
00041 void MyOverlay::initializeOverlay(int stage)
00042 {
00043     // see BaseApp.cc
00044     if (stage != MIN_STAGE_OVERLAY) return;
00045 
00046     // get our key from our IP address
00047     myKey = thisNode.getAddress().get4().getInt() & ~BIGBIT;
00048 
00049     // initialize the rest of variables
00050     numDropped = 0;
00051     if (!(par("enableDrops"))) {
00052         dropChance = 0;
00053     } else {
00054         dropChance = par("dropChance");
00055     }
00056 
00057     rpcTimer = new cMessage("RPC timer");
00058     scheduleAt(simTime() + 5, rpcTimer);
00059 }
00060 
00061 // Called to set our own overlay key (optional)
00062 void MyOverlay::setOwnNodeID()
00063 {
00064     // create the corresponding overlay key
00065     thisNode.setKey(OverlayKey(myKey));
00066 }
00067 
00068 
00069 // Called when the module is ready to join the overlay
00070 void MyOverlay::joinOverlay()
00071 {
00072     // Set the information of the previous step in the chain
00073     prevNode.setAddress(IPAddress(BIGBIT | (myKey - 1)));
00074     prevNode.setPort(thisNode.getPort());
00075     prevNode.setKey(OverlayKey(myKey - 1));
00076 
00077     // Set the information of the next step in the chain
00078     nextNode.setAddress(IPAddress(BIGBIT | (myKey + 1)));
00079     nextNode.setPort(thisNode.getPort());
00080     nextNode.setKey(OverlayKey(myKey + 1));
00081 
00082     // tell the simulator that we're ready
00083     setOverlayReady(true);
00084 }
00085 
00086 void MyOverlay::handleTimerEvent(cMessage *msg)
00087 {
00088     if (msg == rpcTimer) {
00089         // reschedule the timer
00090         scheduleAt(simTime() + 5, rpcTimer);
00091 
00092         // if the simulator is still busy creating the network, let's wait a bit longer
00093         if (underlayConfigurator->isInInitPhase()) return;
00094 
00095         // pick either or next neighbor, or our previous neighbor, and request their neighbors
00096         OverlayKey key;
00097         int neighborToAsk = intuniform(0, 1);
00098 
00099         if (neighborToAsk == 0) key = prevNode.getKey();
00100         else key = nextNode.getKey();
00101 
00102         getNeighbors(key);
00103     }
00104 }
00105 
00106 // Return whether the given node is responsible for the key
00107 bool MyOverlay::isSiblingFor(const NodeHandle& node,
00108                              const OverlayKey& key,
00109                              int numSiblings,
00110                              bool* err)
00111 {
00112     // is it our node and our key?
00113     if (node == thisNode && key == thisNode.getKey()) {
00114         return true;
00115     }
00116     // we don't know otherwise
00117     return false;
00118 }
00119 
00120 // Return the next step for the routing of the given message
00121 NodeVector *MyOverlay::findNode(const OverlayKey& key,
00122                                 int numRedundantNodes,
00123                                 int numSiblings,
00124                                 BaseOverlayMessage* msg)
00125 {
00126     NodeVector* nextHops;
00127 
00128     // do we drop the packet?
00129     if (uniform(0, 1) < dropChance) {
00130         // if yes, return an empty node vector
00131         nextHops = new NodeVector(0);
00132         numDropped++;
00133         return nextHops;
00134     }
00135 
00136     // else, set the response vector with one node
00137     nextHops = new NodeVector(1);
00138 
00139     // are we responsible? next step is this node
00140     if (key == thisNode.getKey()) {
00141         nextHops->add(thisNode);
00142     }
00143     // is the key behind us? next step is the previous node
00144     else if (key < thisNode.getKey()) {
00145         nextHops->add(prevNode);
00146     }
00147     // otherwise, the next step is the next node
00148     else {
00149         nextHops->add(nextNode);
00150     }
00151     return nextHops;
00152 }
00153 
00154 // Called when the module is about to be destroyed
00155 void MyOverlay::finishOverlay()
00156 {
00157     // remove this node from the overlay
00158     setOverlayReady(false);
00159 
00160     // save the statistics (see BaseApp)
00161     globalStatistics->addStdDev("MyOverlay: Dropped packets", numDropped);
00162 }
00163 
00164 // Return the max amount of siblings that can be queried about
00165 int MyOverlay::getMaxNumSiblings()
00166 {
00167     return 1;
00168 }
00169 
00170 // Return the max amount of redundant that can be queried about
00171 int MyOverlay::getMaxNumRedundantNodes()
00172 {
00173     return 1;
00174 }
00175 
00176 
00177 void MyOverlay::getNeighbors(const OverlayKey &neighborKey)
00178 {
00179     MyNeighborCall *msg = new MyNeighborCall();
00180     msg->setDestinationKey(neighborKey);
00181 
00182     // The function we'll be using to send an RPC is sendRouteRpcCall.
00183     // The first value is to which tier we'll be talking. Can be either
00184     // OVERLAY_COMP, TIER1_COMP, TIER2_COMP, and so on.
00185     // The second parameter is the node to which we'll send the message.
00186     // Can be either an OverlayKey or a TransportAddress.
00187     // The third parameter is the message.
00188 
00189     EV << thisNode << ": (RPC) Sending query to "
00190        << neighborKey << "!" << std::endl;
00191 
00192     sendRouteRpcCall(OVERLAY_COMP, neighborKey, msg);
00193 }
00194 
00195 // Handle an incoming Call message
00196 // Only delete msg if the RPC is handled here, and you won't respond using sendRpcResponse!
00197 bool MyOverlay::handleRpcCall(BaseCallMessage *msg)
00198 {
00199     // There are many macros to simplify the handling of RPCs. The full list is in <OverSim>/src/common/RpcMacros.h.
00200 
00201     // start a switch
00202     RPC_SWITCH_START(msg);
00203 
00204     // enters the following block if the message is of type MyNeighborCall (note the shortened parameter!)
00205     RPC_ON_CALL(MyNeighbor) {
00206         // get Call message
00207         MyNeighborCall *mrpc = (MyNeighborCall*)msg;
00208 
00209         // create response
00210         MyNeighborResponse *rrpc = new MyNeighborResponse();
00211         rrpc->setRespondingNode(thisNode);
00212         rrpc->setPrevNeighbor(prevNode);
00213         rrpc->setNextNeighbor(nextNode);
00214 
00215         // now send the response. sendRpcResponse can automatically tell where
00216         // to send it to. Note that sendRpcResponse will delete mrpc (aka msg)!
00217         sendRpcResponse(mrpc, rrpc);
00218 
00219         RPC_HANDLED = true;  // set to true, since we did handle this RPC (default is false)
00220     }
00221 
00222     // end the switch
00223     RPC_SWITCH_END();
00224 
00225     // return whether we handled the message or not.
00226     // don't delete unhandled messages!
00227     return RPC_HANDLED;
00228 }
00229 
00230 // Called when an RPC we sent has timed out.
00231 // Don't delete msg here!
00232 
00233 void MyOverlay::handleRpcTimeout(BaseCallMessage* msg,
00234                          const TransportAddress& dest,
00235                          cPolymorphic* context, int rpcId,
00236                          const OverlayKey&)
00237 {
00238     // Same macros as in handleRpc
00239 
00240     // start a switch
00241     RPC_SWITCH_START(msg);
00242 
00243     // enters the following block if the message is of type MyNeighborCall (note the shortened parameter!)
00244     RPC_ON_CALL(MyNeighbor) {
00245         MyNeighborCall *mrpc = (MyNeighborCall*)msg;          // get Call message
00246         callbackTimeout(mrpc->getDestinationKey());           // call interface function
00247     }
00248     // end the switch
00249     RPC_SWITCH_END();
00250 }
00251 
00252 // Called when we receive an RPC response from another node.
00253 // Don't delete msg here!
00254 
00255 void MyOverlay::handleRpcResponse(BaseResponseMessage* msg,
00256                                   cPolymorphic* context,
00257                                   int rpcId,
00258                                   simtime_t rtt)
00259 {
00260     // The macros are here similar. Just use RPC_ON_RESPONSE instead of RPC_ON_CALL.
00261 
00262     // start a switch
00263     RPC_SWITCH_START(msg);
00264 
00265     // enters the following block if the message is of type MyNeighborCall (note the shortened parameter!)
00266     RPC_ON_RESPONSE(MyNeighbor) {
00267         // get Response message
00268         MyNeighborResponse *mrpc = (MyNeighborResponse*)msg;
00269         // call our interface function
00270         callbackNeighbors(mrpc->getRespondingNode(),
00271                           mrpc->getPrevNeighbor(),
00272                           mrpc->getNextNeighbor());
00273     }
00274     // end the switch
00275     RPC_SWITCH_END();
00276 }
00277 
00278 void MyOverlay::callbackNeighbors(const NodeHandle& neighborKey,
00279                                   const NodeHandle& prevNeighbor,
00280                                   const NodeHandle& nextNeighbor)
00281 {
00282     EV << thisNode << ": (RPC) Got response from "
00283        << neighborKey << "\n"
00284        << thisNode << ": (RPC) Neighbors: "
00285        << prevNeighbor.getAddress() << ", "
00286        << nextNeighbor.getAddress() << std::endl;
00287 }
00288 
00289 void MyOverlay::callbackTimeout(const OverlayKey &neighborKey)
00290 {
00291     EV << thisNode << ": (RPC) Query to " << neighborKey
00292        << " timed out!" << std::endl;
00293 }
Generated on Wed May 26 16:21:14 2010 for OverSim by  doxygen 1.6.3