I3LatencyStretch.cc

Go to the documentation of this file.
00001 // Copyright (C) 2006 Institut fuer Telematik, Universitaet Karlsruhe (TH)
00002 //
00003 // This program is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU General Public License
00005 // as published by the Free Software Foundation; either version 2
00006 // of the License, or (at your option) any later version.
00007 //
00008 // This program is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 // GNU General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this program; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00016 //
00017 
00023 #include "I3BaseApp.h"
00024 #include "I3.h"
00025 
00026 #define TRIGGER_TIMER     1234
00027 
00028 #define STRETCH_HELLO     12345
00029 #define STRETCH_HELLOACK  12346
00030 #define STRETCH_I3MSG     12347
00031 #define STRETCH_IPMSG     12348
00032 
00033 #define USE_NO_SAMPLING   0
00034 #define USE_QUERY_FLAG    1
00035 #define USE_CLOSEST_ID    2
00036 #define USE_SAMPLING      (USE_QUERY_FLAG | USE_CLOSEST_ID)
00037 
00038 using namespace std;
00039 
00040 enum Stats {
00041     STAT_IP,
00042     STAT_I3,
00043     STAT_RATIO,
00044     NUM_STATS
00045 };
00046 
00047 static cStdDev stats[NUM_STATS];
00048 static bool statsDumped = false;
00049 
00050 struct NodeIdentity {
00051     I3Identifier id;
00052     I3IPAddress address;
00053 };
00054 
00055 struct LatencyInfo {
00056     simtime_t i3Time;
00057     simtime_t ipTime;
00058 };
00059 
00060 struct MsgContent {
00061     I3Identifier sourceId;
00062     I3IPAddress sourceIp;
00063     simtime_t creationTime;
00064 };
00065 
00066 class I3LatencyStretch : public I3BaseApp {
00067     int samplingType;
00068     I3Identifier generalId;
00069     I3Identifier myId;
00070     NodeIdentity partner;
00071     bool foundPartner;
00072     cStdDev myStats[NUM_STATS];
00073 
00074     std::map<I3IPAddress, LatencyInfo> latencies;
00075 
00076 
00077     void initializeApp(int stage);
00078     void initializeI3();
00079     void handleTimerEvent(cMessage *msg);
00080     void handleUDPMessage(cMessage* msg);
00081     void deliver(I3Trigger &trigger, I3IdentifierStack &stack, cPacket *msg);
00082     void finish();
00083 };
00084 
00085 Define_Module(I3LatencyStretch);
00086 
00087 
00088 void I3LatencyStretch::initializeApp(int stage) {
00089     statsDumped = false;
00090     I3BaseApp::initializeApp(stage);
00091 }
00092 
00093 void I3LatencyStretch::finish() {
00094     recordScalar("Number of samples", myStats[STAT_RATIO].getCount());
00095 
00096     recordScalar("IP Min  ", myStats[STAT_IP].getMin());
00097     recordScalar("IP Max  ", myStats[STAT_IP].getMax());
00098     recordScalar("IP Mean ", myStats[STAT_IP].getMean());
00099     recordScalar("IP Stdev", myStats[STAT_IP].getStddev());
00100 
00101     recordScalar("I3 Min  ", myStats[STAT_I3].getMin());
00102     recordScalar("I3 Max  ", myStats[STAT_I3].getMax());
00103     recordScalar("I3 Mean ", myStats[STAT_I3].getMean());
00104     recordScalar("I3 Stdev", myStats[STAT_I3].getStddev());
00105 
00106     recordScalar("Ratio Min  ", myStats[STAT_RATIO].getMin());
00107     recordScalar("Ratio Max  ", myStats[STAT_RATIO].getMax());
00108     recordScalar("Ratio Mean ", myStats[STAT_RATIO].getMean());
00109     recordScalar("Ratio Stdev", myStats[STAT_RATIO].getStddev());
00110 
00111     if (!statsDumped) {
00112         statsDumped = true;
00113         recordScalar("General Number of samples", stats[STAT_RATIO].getCount());
00114 
00115         recordScalar("General IP Min  ", stats[STAT_IP].getMin());
00116         recordScalar("General IP Max  ", stats[STAT_IP].getMax());
00117         recordScalar("General IP Mean ", stats[STAT_IP].getMean());
00118         recordScalar("General IP Stdev", stats[STAT_IP].getStddev());
00119         stats[STAT_IP].clearResult();
00120 
00121         recordScalar("General I3 Min  ", stats[STAT_I3].getMin());
00122         recordScalar("General I3 Max  ", stats[STAT_I3].getMax());
00123         recordScalar("General I3 Mean ", stats[STAT_I3].getMean());
00124         recordScalar("General I3 Stdev", stats[STAT_I3].getStddev());
00125         stats[STAT_I3].clearResult();
00126 
00127         recordScalar("General Ratio Min  ", stats[STAT_RATIO].getMin());
00128         recordScalar("General Ratio Max  ", stats[STAT_RATIO].getMax());
00129         recordScalar("General Ratio Mean ", stats[STAT_RATIO].getMean());
00130         recordScalar("General Ratio Stdev", stats[STAT_RATIO].getStddev());
00131         stats[STAT_RATIO].clearResult();
00132     }
00133 }
00134 
00135 void I3LatencyStretch::initializeI3() {
00136     foundPartner = false;
00137     samplingType = par("useSampling");
00138 
00139     generalId.createFromHash("LatencyStretch");
00140     generalId.setName("LatencyStretch");
00141     generalId.createRandomSuffix();
00142     insertTrigger(generalId);
00143 
00144     if (samplingType & USE_CLOSEST_ID) {
00145         myId = retrieveClosestIdentifier();
00146     } else {
00147         myId.createRandomKey();
00148     }
00149     insertTrigger(myId);
00150 
00151     cMessage *msg = new cMessage();
00152     msg->setKind(TRIGGER_TIMER);
00153     scheduleAt(simTime() + 5, msg);
00154 }
00155 
00156 void I3LatencyStretch::handleUDPMessage(cMessage *msg) {
00157     if (msg->getContextPointer() != 0) {
00158         MsgContent *mc = (MsgContent*)msg->getContextPointer();
00159 
00160         if (!latencies.count(mc->sourceIp)) opp_error("Unknown Id!");
00161 
00162         LatencyInfo &info = latencies[mc->sourceIp];
00163 
00164         info.ipTime = simTime() - mc->creationTime;
00165         delete mc;
00166         delete msg;
00167     } else {
00168         I3BaseApp::handleUDPMessage(msg);
00169     }
00170 }
00171 
00172 void I3LatencyStretch::deliver(I3Trigger &trigger, I3IdentifierStack &stack, cPacket *msg)
00173 {
00174     if (msg->getKind() == STRETCH_HELLO) {
00175         NodeIdentity *nid = (NodeIdentity*)msg->getContextPointer();
00176         I3Identifier otherId = nid->id;
00177 
00178         latencies[nid->address] = LatencyInfo();
00179         latencies[nid->address].i3Time = 0;
00180         latencies[nid->address].ipTime = 0;
00181 
00182         msg->setKind(STRETCH_HELLOACK);
00183         nid->id = myId;
00184         nid->address = I3IPAddress(nodeIPAddress, par("clientPort"));
00185         msg->setContextPointer(nid);
00186         sendPacket(otherId, msg, samplingType & USE_QUERY_FLAG);
00187 
00188     } else if (msg->getKind() == STRETCH_HELLOACK) {
00189 
00190         NodeIdentity *nid = (NodeIdentity*)msg->getContextPointer();
00191         partner = *nid;
00192         foundPartner = true;
00193         delete nid;
00194         delete msg;
00195 
00196     } else if (msg->getKind() == STRETCH_I3MSG) {
00197 
00198         MsgContent *mc = (MsgContent*)msg->getContextPointer();
00199 
00200         if (!latencies.count(mc->sourceIp)) opp_error("Unknown Id!");
00201 
00202         LatencyInfo &info = latencies[ mc->sourceIp ];
00203 
00204         info.i3Time = simTime() - mc->creationTime;
00205 
00206         if (info.ipTime != 0) {
00207             if (simTime() > 100) {
00208                 stats[STAT_IP].collect(info.ipTime);
00209                 stats[STAT_I3].collect(info.i3Time );
00210                 stats[STAT_RATIO].collect(info.i3Time / info.ipTime);
00211 
00212                 myStats[STAT_IP].collect(info.ipTime);
00213                 myStats[STAT_I3].collect(info.i3Time );
00214                 myStats[STAT_RATIO].collect(info.i3Time / info.ipTime);
00215             }
00216             info.i3Time = 0;
00217             info.ipTime = 0;
00218         }
00219 
00220 
00221         delete mc;
00222         delete msg;
00223     }
00224 }
00225 
00226 void I3LatencyStretch::handleTimerEvent(cMessage *msg) {
00227     if (msg->getKind() == TRIGGER_TIMER) {
00228         if (!foundPartner) {
00229             I3Identifier otherId;
00230 
00231             otherId.createFromHash("LatencyStretch");
00232             otherId.createRandomSuffix();
00233 
00234             cPacket *hmsg = new cPacket();
00235             NodeIdentity *nid = new NodeIdentity();
00236 
00237             nid->id = myId;
00238             nid->address = I3IPAddress(nodeIPAddress, par("clientPort"));
00239 
00240             hmsg->setKind(STRETCH_HELLO);
00241             hmsg->setContextPointer(nid);
00242             sendPacket(otherId, hmsg, samplingType & USE_QUERY_FLAG);
00243 
00244         } else {
00245             int length = (intrand(512) + 32) * 8;
00246 
00247             MsgContent *mc1 = new MsgContent();
00248             mc1->creationTime = simTime();
00249             mc1->sourceId = myId;
00250             mc1->sourceIp = I3IPAddress(nodeIPAddress, par("clientPort"));
00251 
00252             cPacket *i3msg = new cPacket();
00253             i3msg->setKind(STRETCH_I3MSG);
00254             i3msg->setContextPointer(mc1);
00255             i3msg->setBitLength(length);
00256 
00257             MsgContent *mc2 = new MsgContent(*mc1);
00258             cPacket *ipmsg = new cPacket();
00259             ipmsg->setKind(STRETCH_IPMSG);
00260             ipmsg->setContextPointer(mc2);
00261             ipmsg->setBitLength(length);
00262 
00263             sendPacket(partner.id, i3msg, samplingType & USE_QUERY_FLAG);
00264             sendThroughUDP(ipmsg, partner.address);
00265 
00266         }
00267 
00268         scheduleAt(simTime() + truncnormal(15, 5), msg);
00269 
00270     }
00271 }
Generated on Wed May 26 16:21:14 2010 for OverSim by  doxygen 1.6.3