SimpleNodeEntry.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2006 Institut fuer Telematik, Universitaet Karlsruhe (TH)
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 //
00018 
00024 #include <sstream>
00025 #include <cassert>
00026 
00027 #include "SimpleNodeEntry.h"
00028 #include "SimpleUDP.h"
00029 #include "SHA1.h"
00030 #include "OverlayKey.h"
00031 #include "BinaryValue.h"
00032 #include "IPAddressResolver.h"
00033 
00034 
00035 uint8_t NodeRecord::dim;
00036 
00037 NodeRecord::NodeRecord()
00038 {
00039     coords = new double[dim];
00040 }
00041 
00042 NodeRecord::~NodeRecord()
00043 {
00044     delete[] coords;
00045     coords = NULL;
00046 }
00047 
00048 NodeRecord::NodeRecord(const NodeRecord& nodeRecord)
00049 {
00050     coords = new double[dim];
00051     for (uint32_t i = 0; i < dim; ++i)
00052         coords[i] = nodeRecord.coords[i];
00053 }
00054 
00055 NodeRecord& NodeRecord::operator=(const NodeRecord& nodeRecord)
00056 {
00057     delete[] coords;
00058     coords = new double[dim];
00059     for (uint32_t i = 0; i < dim; ++i)
00060         coords[i] = nodeRecord.coords[i];
00061 
00062     return *this;
00063 }
00064 
00065 SimpleNodeEntry::SimpleNodeEntry(cModule* node,
00066                                  cChannelType* typeRx,
00067                                  cChannelType* typeTx,
00068                                  uint32_t sendQueueLength,
00069                                  uint32_t fieldSize)
00070 {
00071     assert(NodeRecord::dim == 2);
00072     ingate = node->getSubmodule("udp")->gate("network_in");
00073 
00074     nodeRecord = new NodeRecord;
00075     index = -1;
00076 
00077     //use random values as coordinates
00078     nodeRecord->coords[0] = uniform(0, fieldSize) - fieldSize / 2;
00079     nodeRecord->coords[1] = uniform(0, fieldSize) - fieldSize / 2;
00080 
00081     cDatarateChannel* tempRx = dynamic_cast<cDatarateChannel*>(typeRx->create("temp"));
00082     cDatarateChannel* tempTx = dynamic_cast<cDatarateChannel*>(typeTx->create("temp"));
00083 
00084     rx.bandwidth = tempRx->par("datarate");
00085     rx.errorRate = tempRx->par("ber");
00086     rx.accessDelay = tempRx->par("delay");
00087     rx.maxQueueTime = 0;
00088     rx.finished = simTime();
00089 
00090     tx.bandwidth = tempTx->par("datarate");
00091     tx.errorRate = tempTx->par("ber");
00092     tx.accessDelay = tempTx->par("delay");
00093     tx.maxQueueTime = (sendQueueLength * 8.) / tx.bandwidth;
00094     tx.finished = simTime();
00095 
00096     delete tempRx;
00097     delete tempTx;
00098 }
00099 
00100 SimpleNodeEntry::SimpleNodeEntry(cModule* node,
00101                                  cChannelType* typeRx,
00102                                  cChannelType* typeTx,
00103                                  uint32_t sendQueueLength,
00104                                  NodeRecord* nodeRecord, int index)
00105 {
00106     ingate = node->getSubmodule("udp")->gate("network_in");
00107 
00108     this->nodeRecord = nodeRecord;
00109     this->index = index;
00110 
00111     cDatarateChannel* tempRx = dynamic_cast<cDatarateChannel*>(typeRx->create("temp"));
00112     cDatarateChannel* tempTx = dynamic_cast<cDatarateChannel*>(typeTx->create("temp"));
00113 
00114     rx.bandwidth = tempRx->par("datarate");
00115     rx.errorRate = tempRx->par("ber");
00116     rx.accessDelay = tempRx->par("delay");
00117     rx.maxQueueTime = 0;
00118     rx.finished = simTime();
00119 
00120     tx.bandwidth = tempTx->par("datarate");
00121     tx.errorRate = tempTx->par("ber");
00122     tx.accessDelay = tempTx->par("delay");
00123     tx.maxQueueTime = (sendQueueLength * 8.) / tx.bandwidth;
00124     tx.finished = simTime();
00125 
00126     delete tempRx;
00127     delete tempTx;
00128 }
00129 
00130 float SimpleNodeEntry::operator-(const SimpleNodeEntry& entry) const
00131 {
00132     double sum_of_squares = 0;
00133     for (uint32_t i = 0; i < nodeRecord->dim; i++) {
00134         sum_of_squares += pow(nodeRecord->coords[i] -
00135                               entry.nodeRecord->coords[i], 2);
00136     }
00137     return sqrt(sum_of_squares);
00138 }
00139 
00140 SimpleNodeEntry::SimpleDelay SimpleNodeEntry::calcDelay(SimpleUDPPacket* msg,
00141                                                         const SimpleNodeEntry& dest,
00142                                                         bool faultyDelay)
00143 {
00144     if ((pow(1 - tx.errorRate, msg->getByteLength() * 8) <= uniform(0, 1)) ||
00145         (pow(1 - dest.rx.errorRate, msg->getByteLength() * 8) <= uniform(0, 1))) {
00146         msg->setBitError(true);
00147     }
00148 
00149     simtime_t now = simTime();
00150     simtime_t bandwidthDelay= ((msg->getByteLength() * 8) / tx.bandwidth);
00151     simtime_t newTxFinished = std::max(tx.finished, now) + bandwidthDelay;
00152 
00153     // send queue
00154     if ((newTxFinished > now + tx.maxQueueTime) && (tx.maxQueueTime != 0)) {
00155         EV << "[SimpleNodeEntry::calcDelay()]\n"
00156            << "    Send queue overrun"
00157            << "\n    newTxFinished = fmax(txFinished, now) + bandwidthDelay"
00158            << "\n    newTxFinished = " << newTxFinished
00159            << "\n    tx.finished = " << tx.finished
00160            << "\n    now = " << now
00161            << "\n    bandwidthDelay = " << bandwidthDelay
00162            << "\n    (newTxFinished > now + txMaxQueueTime) == true"
00163            << "\n    tx.maxQueueTime = " << tx.maxQueueTime
00164            << endl;
00165         return SimpleDelay(0, false);
00166     }
00167 
00168     tx.finished = newTxFinished;
00169 
00170     simtime_t destBandwidthDelay = (msg->getByteLength() * 8) / dest.rx.bandwidth;
00171     simtime_t coordDelay = 0.001 * (*this - dest);
00172 
00173     if (faultyDelay /*&& SimpleUDP::delayFaultTypeString.length() > 0*/)
00174         coordDelay = getFaultyDelay(coordDelay);
00175 
00176     return SimpleDelay(tx.finished - now
00177                        + tx.accessDelay
00178                        + coordDelay
00179                        + destBandwidthDelay + dest.rx.accessDelay, true);
00180 }
00181 
00182 simtime_t SimpleNodeEntry::getFaultyDelay(simtime_t oldDelay) {
00183 
00184     // hash over string of oldDelay
00185     char delaystring[35];
00186     sprintf(delaystring, "%.30f", SIMTIME_DBL(oldDelay));
00187 
00188     CSHA1 sha1;
00189     uint8_t hashOverDelays[20];
00190     sha1.Reset();
00191     sha1.Update((uint8_t*)delaystring, 32);
00192     sha1.Final();
00193     sha1.GetHash(hashOverDelays);
00194 
00195     // get the hash's first 4 bytes == 32 bits as one unsigned integer
00196     unsigned int decimalhash = 0;
00197     for (int i = 0; i < 4; i++) {
00198         decimalhash += (unsigned int) hashOverDelays[i] * (2 << (8*(3 - i) - 1));
00199     }
00200 
00201     // normalize decimal hash value onto 0..1 (decimal number / 2^32-1)
00202     double fraction = (double) decimalhash / (unsigned int) ((2 << 31) - 1);
00203 
00204     // flip a coin if faulty rtt is larger or smaller
00205     char sign = (decimalhash % 2 == 0) ? 1 : -1;
00206 
00207     // get the error ratio according to the distributions in
00208     // "Network Coordinates in the Wild", Figure 7
00209     double errorRatio = 0;
00210     switch (SimpleUDP::delayFaultTypeMap[SimpleUDP::delayFaultTypeString]) {
00211         case SimpleUDP::delayFaultLiveAll:
00212             // Kumaraswamy, a=2.03, b=14, moved by 0.04 to the right
00213             errorRatio = pow((1.0 - pow(fraction, 1.0/14.0)), 1.0/2.03) + 0.04;
00214             break;
00215 
00216         case SimpleUDP::delayFaultLivePlanetlab:
00217             // Kumaraswamy, a=1.95, b=50, moved by 0.105 to the right
00218             errorRatio = pow((1.0 - pow(fraction, 1.0/50.0)), 1.0/1.95) + 0.105;
00219             break;
00220 
00221         case SimpleUDP::delayFaultSimulation:
00222             // Kumaraswamy, a=1.96, b=23, moved by 0.02 to the right
00223             errorRatio = pow((1.0 - pow(fraction, 1.0/23.0)), 1.0/1.96) + 0.02;
00224             std::cout << "ErrorRatio: " << errorRatio << std::endl;
00225             break;
00226 
00227         default:
00228             break;
00229     }
00230     /*
00231     std::cout << "decimalhash: " << decimalhash << " -- fraction: " << fraction << " -- errorRatio: " << errorRatio << std::endl;
00232     std::cout << SimpleUDP::delayFaultTypeString << " -- " << "old: " << oldDelay << " -- new: " << oldDelay + sign * errorRatio * oldDelay << std::endl;
00233     */
00234 
00235     // If faulty rtt is smaller, set errorRatio to max 0.6
00236     errorRatio = (sign == -1 && errorRatio > 0.6) ? 0.6 : errorRatio;
00237 
00238     return oldDelay + sign * errorRatio * oldDelay;
00239 }
00240 
00241 std::string SimpleNodeEntry::info() const
00242 {
00243     std::ostringstream str;
00244     str << *this;
00245     return str.str();
00246 }
00247 
00248 std::ostream& operator<<(std::ostream& out, const SimpleNodeEntry& entry)
00249 {
00250     out << "(";
00251     for (uint8_t i = 0; i < NodeRecord::dim; i++) {
00252         out << "dim" << i <<": " << entry.nodeRecord->coords[i];
00253         out << ", ";
00254     }
00255     // out << ", y:" << entry.nodeRecord->coords[1]
00256     out << ")\n[rx]"
00257         << "\nbandwidth = " << entry.rx.bandwidth
00258         << ",\ndelay = " << entry.rx.accessDelay
00259         << ",\nerrorRate = " << entry.rx.errorRate
00260         << ",\ntxMaxQueueTime = " << entry.rx.maxQueueTime
00261         << ",\ntxFinished = " << entry.rx.finished;
00262     out << "\n[tx]"
00263         << "\nbandwidth = " << entry.tx.bandwidth
00264         << ",\ndelay = " << entry.tx.accessDelay
00265         << ",\nerrorRate = " << entry.tx.errorRate
00266         << ",\ntxMaxQueueTime = " << entry.tx.maxQueueTime
00267         << ",\ntxFinished = " << entry.tx.finished;
00268 
00269     return out;
00270 }
Generated on Wed May 26 16:21:15 2010 for OverSim by  doxygen 1.6.3