Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include <sstream>
00025 #include <cassert>
00026
00027 #include "SimpleNodeEntry.h"
00028 #include "SimpleUDP.h"
00029 #include "SimpleTCP.h"
00030 #include "SHA1.h"
00031 #include "OverlayKey.h"
00032 #include "BinaryValue.h"
00033 #include "IPAddressResolver.h"
00034
00035
00036 uint8_t NodeRecord::dim;
00037
00038 NodeRecord::NodeRecord()
00039 {
00040 coords = new double[dim];
00041 }
00042
00043 NodeRecord::~NodeRecord()
00044 {
00045 delete[] coords;
00046 coords = NULL;
00047 }
00048
00049 NodeRecord::NodeRecord(const NodeRecord& nodeRecord)
00050 {
00051 coords = new double[dim];
00052 for (uint32_t i = 0; i < dim; ++i)
00053 coords[i] = nodeRecord.coords[i];
00054 }
00055
00056 NodeRecord& NodeRecord::operator=(const NodeRecord& nodeRecord)
00057 {
00058 delete[] coords;
00059 coords = new double[dim];
00060 for (uint32_t i = 0; i < dim; ++i)
00061 coords[i] = nodeRecord.coords[i];
00062
00063 return *this;
00064 }
00065
00066 SimpleNodeEntry::SimpleNodeEntry(cModule* node,
00067 cChannelType* typeRx,
00068 cChannelType* typeTx,
00069 uint32_t sendQueueLength,
00070 uint32_t fieldSize)
00071 {
00072 assert(NodeRecord::dim == 2);
00073 cModule* udpModule = node->getSubmodule("udp");
00074 UdpIPv4ingate = udpModule->gate("ipIn");
00075 UdpIPv6ingate = udpModule->gate("ipv6In");
00076 cModule* tcpModule = node->getSubmodule("tcp", 0);
00077 if (tcpModule) {
00078 TcpIPv4ingate = tcpModule->gate("ipIn");
00079 TcpIPv6ingate = tcpModule->gate("ipv6In");
00080 }
00081
00082 nodeRecord = new NodeRecord;
00083 index = -1;
00084
00085
00086 nodeRecord->coords[0] = uniform(0, fieldSize) - fieldSize / 2;
00087 nodeRecord->coords[1] = uniform(0, fieldSize) - fieldSize / 2;
00088
00089 cDatarateChannel* tempRx = dynamic_cast<cDatarateChannel*>(typeRx->create("temp"));
00090 cDatarateChannel* tempTx = dynamic_cast<cDatarateChannel*>(typeTx->create("temp"));
00091
00092 rx.bandwidth = tempRx->par("datarate");
00093 rx.errorRate = tempRx->par("ber");
00094 rx.accessDelay = tempRx->par("delay");
00095 rx.maxQueueTime = 0;
00096 rx.finished = simTime();
00097
00098 tx.bandwidth = tempTx->par("datarate");
00099 tx.errorRate = tempTx->par("ber");
00100 tx.accessDelay = tempTx->par("delay");
00101 tx.maxQueueTime = (sendQueueLength * 8.) / tx.bandwidth;
00102 tx.finished = simTime();
00103
00104 delete tempRx;
00105 delete tempTx;
00106 }
00107
00108 SimpleNodeEntry::SimpleNodeEntry(cModule* node,
00109 cChannelType* typeRx,
00110 cChannelType* typeTx,
00111 uint32_t sendQueueLength,
00112 NodeRecord* nodeRecord, int index)
00113 {
00114 cModule* udpModule = node->getSubmodule("udp");
00115 UdpIPv4ingate = udpModule->gate("ipIn");
00116 UdpIPv6ingate = udpModule->gate("ipv6In");
00117 cModule* tcpModule = node->getSubmodule("tcp", 0);
00118 if (tcpModule) {
00119 TcpIPv4ingate = tcpModule->gate("ipIn");
00120 TcpIPv6ingate = tcpModule->gate("ipv6In");
00121 }
00122
00123 this->nodeRecord = nodeRecord;
00124 this->index = index;
00125
00126 cDatarateChannel* tempRx = dynamic_cast<cDatarateChannel*>(typeRx->create("temp"));
00127 cDatarateChannel* tempTx = dynamic_cast<cDatarateChannel*>(typeTx->create("temp"));
00128
00129 rx.bandwidth = tempRx->par("datarate");
00130 rx.errorRate = tempRx->par("ber");
00131 rx.accessDelay = tempRx->par("delay");
00132 rx.maxQueueTime = 0;
00133 rx.finished = simTime();
00134
00135 tx.bandwidth = tempTx->par("datarate");
00136 tx.errorRate = tempTx->par("ber");
00137 tx.accessDelay = tempTx->par("delay");
00138 tx.maxQueueTime = (sendQueueLength * 8.) / tx.bandwidth;
00139 tx.finished = simTime();
00140
00141 delete tempRx;
00142 delete tempTx;
00143 }
00144
00145 float SimpleNodeEntry::operator-(const SimpleNodeEntry& entry) const
00146 {
00147 double sum_of_squares = 0;
00148 for (uint32_t i = 0; i < nodeRecord->dim; i++) {
00149 sum_of_squares += pow(nodeRecord->coords[i] -
00150 entry.nodeRecord->coords[i], 2);
00151 }
00152 return sqrt(sum_of_squares);
00153 }
00154
00155 SimpleNodeEntry::SimpleDelay SimpleNodeEntry::calcDelay(cPacket* msg,
00156 const SimpleNodeEntry& dest,
00157 bool faultyDelay)
00158 {
00159 if ((pow(1 - tx.errorRate, msg->getByteLength() * 8) <= uniform(0, 1)) ||
00160 (pow(1 - dest.rx.errorRate, msg->getByteLength() * 8) <= uniform(0, 1))) {
00161 msg->setBitError(true);
00162 }
00163
00164 simtime_t now = simTime();
00165 simtime_t bandwidthDelay= ((msg->getByteLength() * 8) / tx.bandwidth);
00166 simtime_t newTxFinished = std::max(tx.finished, now) + bandwidthDelay;
00167
00168
00169 if ((newTxFinished > now + tx.maxQueueTime) && (tx.maxQueueTime != 0)) {
00170 EV << "[SimpleNodeEntry::calcDelay()]\n"
00171 << " Send queue overrun"
00172 << "\n newTxFinished = fmax(txFinished, now) + bandwidthDelay"
00173 << "\n newTxFinished = " << newTxFinished
00174 << "\n tx.finished = " << tx.finished
00175 << "\n now = " << now
00176 << "\n bandwidthDelay = " << bandwidthDelay
00177 << "\n (newTxFinished > now + txMaxQueueTime) == true"
00178 << "\n tx.maxQueueTime = " << tx.maxQueueTime
00179 << endl;
00180 return SimpleDelay(0, false);
00181 }
00182
00183 tx.finished = newTxFinished;
00184
00185 simtime_t destBandwidthDelay = (msg->getByteLength() * 8) / dest.rx.bandwidth;
00186 simtime_t coordDelay = 0.001 * (*this - dest);
00187
00188 if (faultyDelay)
00189 coordDelay = getFaultyDelay(coordDelay);
00190
00191 return SimpleDelay(tx.finished - now
00192 + tx.accessDelay
00193 + coordDelay
00194 + destBandwidthDelay + dest.rx.accessDelay, true);
00195 }
00196
00197 simtime_t SimpleNodeEntry::getFaultyDelay(simtime_t oldDelay) {
00198
00199
00200 char delaystring[35];
00201 sprintf(delaystring, "%.30f", SIMTIME_DBL(oldDelay));
00202
00203 CSHA1 sha1;
00204 uint8_t hashOverDelays[20];
00205 sha1.Reset();
00206 sha1.Update((uint8_t*)delaystring, 32);
00207 sha1.Final();
00208 sha1.GetHash(hashOverDelays);
00209
00210
00211 unsigned int decimalhash = 0;
00212 for (int i = 0; i < 4; i++) {
00213 decimalhash += (unsigned int) hashOverDelays[i] * (2 << (8*(3 - i) - 1));
00214 }
00215
00216
00217 double fraction = (double) decimalhash / (unsigned int) ((2 << 31) - 1);
00218
00219
00220 char sign = (decimalhash % 2 == 0) ? 1 : -1;
00221
00222
00223
00224 double errorRatio = 0;
00225 switch (SimpleUDP::delayFaultTypeMap[SimpleUDP::delayFaultTypeString]) {
00226 case SimpleUDP::delayFaultLiveAll:
00227
00228 errorRatio = pow((1.0 - pow(fraction, 1.0/14.0)), 1.0/2.03) + 0.04;
00229 break;
00230
00231 case SimpleUDP::delayFaultLivePlanetlab:
00232
00233 errorRatio = pow((1.0 - pow(fraction, 1.0/50.0)), 1.0/1.95) + 0.105;
00234 break;
00235
00236 case SimpleUDP::delayFaultSimulation:
00237
00238 errorRatio = pow((1.0 - pow(fraction, 1.0/23.0)), 1.0/1.96) + 0.02;
00239 std::cout << "ErrorRatio: " << errorRatio << std::endl;
00240 break;
00241
00242 default:
00243 break;
00244 }
00245
00246
00247
00248
00249
00250
00251 errorRatio = (sign == -1 && errorRatio > 0.6) ? 0.6 : errorRatio;
00252
00253 return oldDelay + sign * errorRatio * oldDelay;
00254 }
00255
00256 std::string SimpleNodeEntry::info() const
00257 {
00258 std::ostringstream str;
00259 str << *this;
00260 return str.str();
00261 }
00262
00263 std::ostream& operator<<(std::ostream& out, const SimpleNodeEntry& entry)
00264 {
00265 out << "(";
00266 for (uint8_t i = 0; i < NodeRecord::dim; i++) {
00267 out << "dim" << i <<": " << entry.nodeRecord->coords[i];
00268 out << ", ";
00269 }
00270
00271 out << ")\n[rx]"
00272 << "\nbandwidth = " << entry.rx.bandwidth
00273 << ",\ndelay = " << entry.rx.accessDelay
00274 << ",\nerrorRate = " << entry.rx.errorRate
00275 << ",\ntxMaxQueueTime = " << entry.rx.maxQueueTime
00276 << ",\ntxFinished = " << entry.rx.finished;
00277 out << "\n[tx]"
00278 << "\nbandwidth = " << entry.tx.bandwidth
00279 << ",\ndelay = " << entry.tx.accessDelay
00280 << ",\nerrorRate = " << entry.tx.errorRate
00281 << ",\ntxMaxQueueTime = " << entry.tx.maxQueueTime
00282 << ",\ntxFinished = " << entry.tx.finished;
00283
00284 return out;
00285 }