SimpleNodeEntry.cc
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 "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
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
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 )
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
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
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
00202 double fraction = (double) decimalhash / (unsigned int) ((2 << 31) - 1);
00203
00204
00205 char sign = (decimalhash % 2 == 0) ? 1 : -1;
00206
00207
00208
00209 double errorRatio = 0;
00210 switch (SimpleUDP::delayFaultTypeMap[SimpleUDP::delayFaultTypeString]) {
00211 case SimpleUDP::delayFaultLiveAll:
00212
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
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
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
00232
00233
00234
00235
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
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 }