LEFT | RIGHT |
(no file at all) | |
| 1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ |
| 2 /* |
| 3 * Copyright (c) 2010 Network Security Lab, University of Washington, Seattle. |
| 4 * |
| 5 * This program is free software; you can redistribute it and/or modify |
| 6 * it under the terms of the GNU General Public License version 2 as |
| 7 * published by the Free Software Foundation; |
| 8 * |
| 9 * This program is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 * GNU General Public License for more details. |
| 13 * |
| 14 * You should have received a copy of the GNU General Public License |
| 15 * along with this program; if not, write to the Free Software |
| 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 17 * |
| 18 * Authors: Sidharth Nabar <snabar@uw.edu>, He Wu <mdzz@u.washington.edu> |
| 19 */ |
| 20 |
| 21 #include "wireless-module-utility.h" |
| 22 #include "ns3/simulator.h" |
| 23 #include "ns3/packet.h" |
| 24 #include "ns3/random-variable.h" |
| 25 #include "ns3/assert.h" |
| 26 #include "ns3/log.h" |
| 27 #include "ns3/double.h" |
| 28 #include "ns3/uinteger.h" |
| 29 #include "ns3/enum.h" |
| 30 #include "ns3/pointer.h" |
| 31 #include "ns3/net-device.h" |
| 32 #include "ns3/node.h" |
| 33 #include "ns3/trace-source-accessor.h" |
| 34 #include <math.h> |
| 35 |
| 36 NS_LOG_COMPONENT_DEFINE ("WirelessModuleUtility"); |
| 37 |
| 38 namespace ns3 { |
| 39 |
| 40 NS_OBJECT_ENSURE_REGISTERED (WirelessModuleUtility); |
| 41 |
| 42 TypeId |
| 43 WirelessModuleUtility::GetTypeId (void) |
| 44 { |
| 45 static TypeId tid = TypeId ("ns3::WirelessModuleUtility") |
| 46 .SetParent<Object> () |
| 47 .AddConstructor<WirelessModuleUtility> () |
| 48 .AddAttribute ("ThroughputUpdateInterval", |
| 49 "Time window for calculation of derivative of total bytes (th
roughput).", |
| 50 TimeValue (Seconds (1.0)), // default to 1.0 second |
| 51 MakeTimeAccessor (&WirelessModuleUtility::SetThroughputUpdate
Interval, |
| 52 &WirelessModuleUtility::GetThroughputUpdate
Interval), |
| 53 MakeTimeChecker ()) |
| 54 .AddAttribute ("PdrWindowSize", |
| 55 "Number of packets to be considered as a moving window for PD
R measurements.", |
| 56 UintegerValue (40), // default to 40 packets |
| 57 MakeUintegerAccessor (&WirelessModuleUtility::SetPdrWindowSiz
e, |
| 58 &WirelessModuleUtility::GetPdrWindowSiz
e), |
| 59 MakeUintegerChecker<uint32_t> ()) |
| 60 .AddAttribute ("RssUpdateInterval", |
| 61 "Update interval of RSS values.", |
| 62 TimeValue (Seconds (0.5)), // default to 0.5 second |
| 63 MakeTimeAccessor (&WirelessModuleUtility::SetRssUpdateInterva
l, |
| 64 &WirelessModuleUtility::GetRssUpdateInterva
l), |
| 65 MakeTimeChecker ()) |
| 66 .AddTraceSource ("TotalBytesRx", |
| 67 "Total bytes received at current node.", |
| 68 MakeTraceSourceAccessor (&WirelessModuleUtility::m_totalByt
esRx)) |
| 69 .AddTraceSource ("TotalBytesTx", |
| 70 "Total bytes sent at current node.", |
| 71 MakeTraceSourceAccessor (&WirelessModuleUtility::m_totalByt
esTx)) |
| 72 .AddTraceSource ("ThroughputRx", |
| 73 "RX throughput at current node.", |
| 74 MakeTraceSourceAccessor (&WirelessModuleUtility::m_throughp
utRx)) |
| 75 .AddTraceSource ("ThroughputTx", |
| 76 "TX throughput at current node.", |
| 77 MakeTraceSourceAccessor (&WirelessModuleUtility::m_throughp
utTx)) |
| 78 .AddTraceSource ("Pdr", |
| 79 "Packet Delivery Rate at current node.", |
| 80 MakeTraceSourceAccessor (&WirelessModuleUtility::m_Pdr)) |
| 81 .AddTraceSource ("Rss", |
| 82 "Received Signal Strength at current node.", |
| 83 MakeTraceSourceAccessor (&WirelessModuleUtility::m_nodeRssW
)) |
| 84 .AddTraceSource ("PacketRss", |
| 85 "Received Signal Strength per packet at current node.", |
| 86 MakeTraceSourceAccessor (&WirelessModuleUtility::m_avgPktRs
sW)) |
| 87 ; |
| 88 return tid; |
| 89 } |
| 90 |
| 91 WirelessModuleUtility::WirelessModuleUtility (void) |
| 92 : m_totalBytesRx (0), |
| 93 m_totalBytesTx (0), |
| 94 m_previousTotalBytesRx (0), |
| 95 m_previousTotalBytesTx (0), |
| 96 m_throughputRx (0), |
| 97 m_throughputTx (0), |
| 98 m_Pdr (0), |
| 99 m_numOfPktsRecvd (0), |
| 100 m_pdrArrayCurIndex (0), |
| 101 m_nodeRssW (0) |
| 102 { |
| 103 m_pktStatusRecord.clear (); |
| 104 m_rssMeasurementCallback.Nullify (); |
| 105 m_sendPacketCallback.Nullify (); |
| 106 m_startRxCallback.Nullify (); |
| 107 m_endRxCallback.Nullify (); |
| 108 m_channelSwitchCallback.Nullify (); |
| 109 } |
| 110 |
| 111 WirelessModuleUtility::~WirelessModuleUtility (void) |
| 112 { |
| 113 } |
| 114 |
| 115 void |
| 116 WirelessModuleUtility::SetThroughputUpdateInterval (Time updateInterval) |
| 117 { |
| 118 NS_LOG_FUNCTION (this << updateInterval); |
| 119 NS_ASSERT (updateInterval.GetSeconds () >= 0); |
| 120 m_throughputUpdateInterval = updateInterval; |
| 121 // cancel previously scheduled throughput update event |
| 122 m_throughputUpdateEvent.Cancel (); |
| 123 // update previous total bytes |
| 124 m_previousTotalBytesTx = m_totalBytesTx; |
| 125 m_previousTotalBytesRx = m_totalBytesRx; |
| 126 // schedule the next recording of throughput |
| 127 if (!Simulator::IsFinished ()) |
| 128 { |
| 129 m_throughputUpdateEvent = Simulator::Schedule (m_throughputUpdateInterval, |
| 130 &WirelessModuleUtility::Upd
ateThroughput, |
| 131 this); |
| 132 } |
| 133 } |
| 134 |
| 135 Time |
| 136 WirelessModuleUtility::GetThroughputUpdateInterval (void) const |
| 137 { |
| 138 NS_LOG_FUNCTION (this); |
| 139 return m_throughputUpdateInterval; |
| 140 } |
| 141 |
| 142 void |
| 143 WirelessModuleUtility::SetPdrWindowSize (uint32_t pdrWindowSize) |
| 144 { |
| 145 NS_LOG_FUNCTION (this << pdrWindowSize); |
| 146 NS_ASSERT (pdrWindowSize != 0); |
| 147 m_pdrWindowSize = pdrWindowSize; |
| 148 // allocate packet status record list upon changing PDR window size |
| 149 m_pktStatusRecord.clear (); |
| 150 m_pktStatusRecord.assign (m_pdrWindowSize, false); |
| 151 } |
| 152 |
| 153 uint32_t |
| 154 WirelessModuleUtility::GetPdrWindowSize (void) const |
| 155 { |
| 156 NS_LOG_FUNCTION (this); |
| 157 return m_pdrWindowSize; |
| 158 } |
| 159 |
| 160 void |
| 161 WirelessModuleUtility::SetRssUpdateInterval (Time updateInterval) |
| 162 { |
| 163 NS_LOG_FUNCTION (this << updateInterval); |
| 164 m_rssUpdateInterval = updateInterval; |
| 165 } |
| 166 |
| 167 Time |
| 168 WirelessModuleUtility::GetRssUpdateInterval (void) const |
| 169 { |
| 170 NS_LOG_FUNCTION (this); |
| 171 return m_rssUpdateInterval; |
| 172 } |
| 173 |
| 174 void |
| 175 WirelessModuleUtility::SetRssMeasurementCallback (UtilityRssCallback RssCallback
) |
| 176 { |
| 177 NS_LOG_FUNCTION (this); |
| 178 m_rssMeasurementCallback = RssCallback; |
| 179 } |
| 180 |
| 181 void |
| 182 WirelessModuleUtility::SetInclusionList (std::vector<std::string> list) |
| 183 { |
| 184 NS_LOG_FUNCTION (this); |
| 185 m_headerInclusionList = list; |
| 186 } |
| 187 |
| 188 void |
| 189 WirelessModuleUtility::SetExclusionList (std::vector<std::string> list) |
| 190 { |
| 191 NS_LOG_FUNCTION (this); |
| 192 m_headerExclusionList = list; |
| 193 } |
| 194 |
| 195 void |
| 196 WirelessModuleUtility::SetSendPacketCallback (UtilitySendPacketCallback sendPack
etCallback) |
| 197 { |
| 198 NS_LOG_FUNCTION (this); |
| 199 m_sendPacketCallback = sendPacketCallback; |
| 200 } |
| 201 |
| 202 void |
| 203 WirelessModuleUtility::SetChannelSwitchCallback (UtilityChannelSwitchCallback ch
annelSwitchCallback) |
| 204 { |
| 205 NS_LOG_FUNCTION (this); |
| 206 m_channelSwitchCallback = channelSwitchCallback; |
| 207 } |
| 208 |
| 209 void |
| 210 WirelessModuleUtility::SetStartTxCallback (UtilityTxCallback startTxCallback) |
| 211 { |
| 212 NS_LOG_FUNCTION (this); |
| 213 m_startTxCallback = startTxCallback; |
| 214 } |
| 215 |
| 216 void |
| 217 WirelessModuleUtility::SetEndTxCallback (UtilityTxCallback endTxCallback) |
| 218 { |
| 219 NS_LOG_FUNCTION (this); |
| 220 m_endTxCallback = endTxCallback; |
| 221 } |
| 222 |
| 223 void |
| 224 WirelessModuleUtility::SetStartRxCallback (UtilityRxCallback startRxCallback) |
| 225 { |
| 226 NS_LOG_FUNCTION (this); |
| 227 m_startRxCallback = startRxCallback; |
| 228 } |
| 229 |
| 230 void |
| 231 WirelessModuleUtility::SetEndRxCallback (UtilityRxCallback endRxCallback) |
| 232 { |
| 233 NS_LOG_FUNCTION (this); |
| 234 m_endRxCallback = endRxCallback; |
| 235 } |
| 236 |
| 237 void |
| 238 WirelessModuleUtility::SetPhyLayerInfo (PhyLayerInfo info) |
| 239 { |
| 240 NS_LOG_FUNCTION (this); |
| 241 m_phyLayerInfo = info; |
| 242 } |
| 243 |
| 244 WirelessModuleUtility::PhyLayerInfo |
| 245 WirelessModuleUtility::GetPhyLayerInfo (void) const |
| 246 { |
| 247 NS_LOG_FUNCTION (this); |
| 248 return m_phyLayerInfo; |
| 249 } |
| 250 |
| 251 bool |
| 252 WirelessModuleUtility::StartRxHandler (Ptr<Packet> packet, double startRssW) |
| 253 { |
| 254 NS_LOG_FUNCTION (this << packet << startRssW); |
| 255 |
| 256 UpdateRss (); |
| 257 |
| 258 // notify jammer or jamming mitigation |
| 259 if (!m_startRxCallback.IsNull ()) |
| 260 { |
| 261 return m_startRxCallback (packet, startRssW); |
| 262 } |
| 263 else |
| 264 { |
| 265 NS_LOG_DEBUG ("WirelessModuleUtility:StartRxHandler is not installed!"); |
| 266 return true; |
| 267 } |
| 268 } |
| 269 |
| 270 void |
| 271 WirelessModuleUtility::EndRxHandler (Ptr<Packet> packet, |
| 272 double averageRssW, |
| 273 const bool isSuccessfullyReceived) |
| 274 { |
| 275 NS_LOG_FUNCTION (this << packet << averageRssW << isSuccessfullyReceived); |
| 276 NS_LOG_DEBUG ("WirelessModuleUtility:Handling received packet from PHY!"); |
| 277 |
| 278 // Update the RSS since the value will change when the packet ends. |
| 279 UpdateRss(); |
| 280 ·· |
| 281 AnalyzeAndRecordIncomingPacket (packet, isSuccessfullyReceived); |
| 282 |
| 283 m_avgPktRssW = averageRssW; |
| 284 |
| 285 // notify jammer or mitigation module |
| 286 if (m_endRxCallback.IsNull ()) |
| 287 { |
| 288 NS_LOG_DEBUG ("WirelessModuleUtility:Brain is not installed!"); |
| 289 } |
| 290 else |
| 291 { |
| 292 if (isSuccessfullyReceived) |
| 293 { |
| 294 m_endRxCallback (packet, m_avgPktRssW); |
| 295 } |
| 296 else |
| 297 { |
| 298 m_endRxCallback (NULL, m_avgPktRssW); // pass NULL if packet is corrup
ted |
| 299 } |
| 300 } |
| 301 } |
| 302 |
| 303 void |
| 304 WirelessModuleUtility::StartTxHandler (Ptr<const Packet> packet, double txPower) |
| 305 { |
| 306 NS_LOG_FUNCTION (this << packet << txPower); |
| 307 AnalyzeAndRecordOutgoingPacket (packet); |
| 308 if (m_startTxCallback.IsNull ()) |
| 309 { |
| 310 NS_LOG_DEBUG ("WirelessModuleUtility:Start TX callback is not installed!")
; |
| 311 } |
| 312 else |
| 313 { |
| 314 Ptr<Packet> copy = packet->Copy (); |
| 315 m_startTxCallback (copy, txPower); |
| 316 } |
| 317 } |
| 318 |
| 319 void |
| 320 WirelessModuleUtility::EndTxHandler (Ptr<const Packet> packet, double txPower) |
| 321 { |
| 322 NS_LOG_FUNCTION (this << packet << txPower); |
| 323 |
| 324 if (m_endTxCallback.IsNull ()) |
| 325 { |
| 326 NS_LOG_DEBUG ("WirelessModuleUtility:End TX callback is not installed!"); |
| 327 } |
| 328 else |
| 329 { |
| 330 Ptr<Packet> copy = packet->Copy (); |
| 331 m_endTxCallback (copy, txPower); |
| 332 } |
| 333 } |
| 334 |
| 335 uint64_t |
| 336 WirelessModuleUtility::GetTotalBytesRx (void) const |
| 337 { |
| 338 NS_LOG_FUNCTION (this); |
| 339 return m_totalBytesRx; |
| 340 } |
| 341 |
| 342 uint64_t |
| 343 WirelessModuleUtility::GetTotalBytesTx (void) const |
| 344 { |
| 345 NS_LOG_FUNCTION (this); |
| 346 return m_totalBytesTx; |
| 347 } |
| 348 |
| 349 double |
| 350 WirelessModuleUtility::GetRxThroughput (void) const |
| 351 { |
| 352 NS_LOG_FUNCTION (this); |
| 353 return m_throughputRx; |
| 354 } |
| 355 |
| 356 double |
| 357 WirelessModuleUtility::GetTxThroughput (void) const |
| 358 { |
| 359 NS_LOG_FUNCTION (this); |
| 360 return m_throughputTx; |
| 361 } |
| 362 |
| 363 double |
| 364 WirelessModuleUtility::GetPdr (void) const |
| 365 { |
| 366 NS_LOG_FUNCTION (this); |
| 367 return m_Pdr; |
| 368 } |
| 369 |
| 370 double |
| 371 WirelessModuleUtility::GetRss (void) const |
| 372 { |
| 373 NS_LOG_FUNCTION (this); |
| 374 return m_nodeRssW; |
| 375 } |
| 376 |
| 377 /* |
| 378 * Private functions start here! |
| 379 */ |
| 380 |
| 381 void |
| 382 WirelessModuleUtility::DoStart (void) |
| 383 { |
| 384 NS_LOG_FUNCTION (this); |
| 385 UpdateRss (); // start RSS update at beginning of simulation |
| 386 UpdateThroughput (); // start throughput update at beginning of simulation |
| 387 } |
| 388 |
| 389 void |
| 390 WirelessModuleUtility::DoDispose (void) |
| 391 { |
| 392 NS_LOG_FUNCTION (this); |
| 393 // show total bytes at end of simulation |
| 394 NS_LOG_DEBUG ("WirelessModuleUtility:Total bytes RX = " << m_totalBytesRx); |
| 395 NS_LOG_DEBUG ("WirelessModuleUtility:Total bytes TX = " << m_totalBytesTx); |
| 396 } |
| 397 |
| 398 void |
| 399 WirelessModuleUtility::AnalyzeAndRecordIncomingPacket (const Ptr<Packet> packet, |
| 400 bool isSuccessfullyReceived) |
| 401 { |
| 402 NS_LOG_FUNCTION (this << packet << isSuccessfullyReceived); |
| 403 |
| 404 if (isSuccessfullyReceived) |
| 405 { |
| 406 if (FindHeaderInInclusionList (packet) && !FindHeaderInExclusionList (pack
et)) |
| 407 { |
| 408 m_totalBytesRx += packet->GetSize (); |
| 409 } |
| 410 UpdatePdr (true); // update PDR for successful delivery |
| 411 } |
| 412 else |
| 413 { |
| 414 UpdatePdr (false); // update PDR for delivery failure |
| 415 } |
| 416 } |
| 417 |
| 418 void |
| 419 WirelessModuleUtility::AnalyzeAndRecordOutgoingPacket (Ptr<const Packet> packet) |
| 420 { |
| 421 NS_LOG_FUNCTION (this << packet); |
| 422 |
| 423 if (FindHeaderInInclusionList (packet) && !FindHeaderInExclusionList (packet)) |
| 424 { |
| 425 m_totalBytesTx += packet->GetSize (); |
| 426 } |
| 427 } |
| 428 |
| 429 void WirelessModuleUtility::UpdateThroughput (void) |
| 430 { |
| 431 NS_LOG_FUNCTION (this); |
| 432 |
| 433 // cancel previously scheduled throughput update event |
| 434 m_throughputUpdateEvent.Cancel (); |
| 435 |
| 436 double throughputUpdateIntervalS = m_throughputUpdateInterval.GetSeconds (); |
| 437 uint64_t txChange = m_totalBytesTx - m_previousTotalBytesTx; |
| 438 uint64_t rxChange = m_totalBytesRx - m_previousTotalBytesRx; |
| 439 |
| 440 // calculate throughput in bits per seconds |
| 441 m_throughputTx = (double)(txChange * 8) / throughputUpdateIntervalS; |
| 442 m_throughputRx = (double)(rxChange * 8) / throughputUpdateIntervalS; |
| 443 |
| 444 // step to next update window |
| 445 m_previousTotalBytesTx = m_totalBytesTx; |
| 446 m_previousTotalBytesRx = m_totalBytesRx; |
| 447 |
| 448 // schedule next update |
| 449 m_throughputUpdateEvent = Simulator::Schedule (m_throughputUpdateInterval, |
| 450 &WirelessModuleUtility::UpdateT
hroughput, |
| 451 this); |
| 452 } |
| 453 |
| 454 uint32_t |
| 455 WirelessModuleUtility::FindHeader (Ptr<const Packet> packet, |
| 456 std::string headerName) const |
| 457 { |
| 458 NS_LOG_FUNCTION (this << packet); |
| 459 Packet copy = *packet; // make a copy of the header |
| 460 NS_LOG_DEBUG ("WirelessModuleUtility:Packet has the following headers/trailers
:" << |
| 461 "\n----------\n" << copy << "\n----------"); |
| 462 |
| 463 // iterate through all items in the header |
| 464 PacketMetadata::ItemIterator pktItemIterator = copy.BeginItem (); |
| 465 while (pktItemIterator.HasNext ()) |
| 466 { |
| 467 PacketMetadata::Item item = pktItemIterator.Next (); |
| 468 if (item.isFragment) |
| 469 { |
| 470 switch (item.type) |
| 471 { |
| 472 case PacketMetadata::Item::PAYLOAD: |
| 473 break; |
| 474 case PacketMetadata::Item::HEADER: |
| 475 case PacketMetadata::Item::TRAILER: |
| 476 std::string itemName = item.tid.GetName (); |
| 477 uint32_t size = item.currentSize; // obtain size of header/trailer |
| 478 // check if we found header string |
| 479 if (headerName.compare (itemName) == 0) |
| 480 { |
| 481 NS_LOG_DEBUG ("WirelessModuleUtility:" << itemName << |
| 482 " Found!" << " Size = " << size << " bytes"); |
| 483 return size; |
| 484 } |
| 485 break; |
| 486 } |
| 487 NS_LOG_DEBUG ("WirelessModuleUtility:" << " Fragment [" << |
| 488 item.currentTrimedFromStart <<":" << |
| 489 (item.currentTrimedFromStart + item.currentSize) << "]")
; |
| 490 } // end if |
| 491 else |
| 492 { |
| 493 switch (item.type) |
| 494 { |
| 495 case PacketMetadata::Item::PAYLOAD: |
| 496 NS_LOG_DEBUG ("WirelessModuleUtility:" << "Payload (size=" << |
| 497 item.currentSize << ")"); |
| 498 break; |
| 499 case PacketMetadata::Item::HEADER: |
| 500 case PacketMetadata::Item::TRAILER: |
| 501 std::string itemName = item.tid.GetName (); |
| 502 uint32_t size = item.currentSize; // obtain size of header/trailer |
| 503 // check if we found header string |
| 504 if (headerName.compare (itemName) == 0) |
| 505 { |
| 506 NS_LOG_DEBUG ("WirelessModuleUtility:" << itemName << |
| 507 " Found!" << " Size = " << size << " bytes"); |
| 508 return size; // header/trailer found |
| 509 } |
| 510 // skip checking of header/trailer contents |
| 511 break; |
| 512 } |
| 513 } // end else |
| 514 } // end while |
| 515 return 0; // return 0 if not found |
| 516 } |
| 517 |
| 518 bool |
| 519 WirelessModuleUtility::FindHeaderInInclusionList (Ptr<const Packet> packet) |
| 520 { |
| 521 NS_LOG_FUNCTION (this << packet); |
| 522 |
| 523 /* |
| 524 * Return true if list is empty. The inclusion list is default to be empty, |
| 525 * that is, we will include packets with any header/trailer. |
| 526 */ |
| 527 if (m_headerInclusionList.empty ()) |
| 528 { |
| 529 return true; |
| 530 } |
| 531 |
| 532 // iterate through the header/trailer inclusion list |
| 533 std::vector<std::string>::iterator listItr = m_headerInclusionList.begin (); |
| 534 while (listItr != m_headerInclusionList.end ()) |
| 535 { |
| 536 if (FindHeader (packet, *listItr) != 0) |
| 537 { |
| 538 return true; |
| 539 } |
| 540 listItr++; |
| 541 } |
| 542 return false; |
| 543 } |
| 544 |
| 545 bool |
| 546 WirelessModuleUtility::FindHeaderInExclusionList (Ptr<const Packet> packet) |
| 547 { |
| 548 NS_LOG_FUNCTION (this << packet); |
| 549 |
| 550 // iterate through the header/trailer exclusion list |
| 551 std::vector<std::string>::iterator listItr = m_headerExclusionList.begin (); |
| 552 while (listItr != m_headerExclusionList.end ()) |
| 553 { |
| 554 if (FindHeader (packet, *listItr) != 0) |
| 555 { |
| 556 return true; |
| 557 } |
| 558 listItr++; |
| 559 } |
| 560 return false; |
| 561 } |
| 562 |
| 563 void |
| 564 WirelessModuleUtility::UpdatePdr (const bool isPacketValid) |
| 565 { |
| 566 NS_LOG_FUNCTION (this << isPacketValid); |
| 567 uint32_t validPkts = 0; |
| 568 uint32_t totalPkts = 0; |
| 569 |
| 570 // create m_pktStatusRecord list ONLY if empty (initialization) |
| 571 if (m_pktStatusRecord.empty ()) |
| 572 { |
| 573 m_pktStatusRecord.assign (m_pdrWindowSize, false); |
| 574 } |
| 575 |
| 576 // insert current packet status into PDR status list |
| 577 InsertIntoPdrArray (isPacketValid); |
| 578 |
| 579 // calculate how many packets the PDR is to be calculated with. |
| 580 if (m_numOfPktsRecvd > m_pdrWindowSize) |
| 581 { |
| 582 totalPkts = m_pdrWindowSize; |
| 583 } |
| 584 else |
| 585 { |
| 586 totalPkts = m_numOfPktsRecvd; |
| 587 } |
| 588 |
| 589 // Count the number of valid packets in the array |
| 590 validPkts = 0; |
| 591 for (uint32_t i = 0; i < totalPkts ; i++) |
| 592 { |
| 593 if (m_pktStatusRecord[i]) |
| 594 { |
| 595 validPkts++; |
| 596 } |
| 597 } |
| 598 // calculate PDR |
| 599 m_Pdr = (double) validPkts / (double) totalPkts; |
| 600 |
| 601 NS_LOG_DEBUG ("WirelessModuleUtility:Updated PDR = " << m_Pdr << |
| 602 ", Total received packets = " << totalPkts << |
| 603 ", # of valid packets = "<< validPkts); |
| 604 } |
| 605 |
| 606 void |
| 607 WirelessModuleUtility::InsertIntoPdrArray (bool newPacketStatus) |
| 608 { |
| 609 NS_LOG_FUNCTION (this << newPacketStatus); |
| 610 /* |
| 611 * Insert the status of the latest packet at the current index of array and |
| 612 * increment the current index to be ready for next insertion. |
| 613 */ |
| 614 m_pktStatusRecord[m_pdrArrayCurIndex++] = newPacketStatus; |
| 615 m_numOfPktsRecvd++; |
| 616 |
| 617 // wrap around the array |
| 618 if (m_pdrArrayCurIndex == m_pdrWindowSize) |
| 619 { |
| 620 m_pdrArrayCurIndex = 0; |
| 621 } |
| 622 } |
| 623 |
| 624 void |
| 625 WirelessModuleUtility::UpdateRss (void) |
| 626 { |
| 627 NS_LOG_FUNCTION (this); |
| 628 |
| 629 m_updateRssEvent.Cancel (); // cancel event if exists |
| 630 |
| 631 if (m_rssMeasurementCallback.IsNull ()) |
| 632 { |
| 633 NS_LOG_ERROR ("WirelessModuleUtility:RSS measurement callback not set!"); |
| 634 return; |
| 635 } |
| 636 |
| 637 m_nodeRssW = m_rssMeasurementCallback (); // calculate & set RSS |
| 638 |
| 639 NS_LOG_DEBUG ("WirelessModuleUtility:At time = " << Simulator::Now().GetSecond
s () << |
| 640 " s" << ", Current RSS = " << m_nodeRssW << " W" << ", in dBm "
<< |
| 641 WToDbm (m_nodeRssW)); |
| 642 |
| 643 // schedule next update |
| 644 m_updateRssEvent = Simulator::Schedule (m_rssUpdateInterval, |
| 645 &WirelessModuleUtility::UpdateRss, |
| 646 this); |
| 647 } |
| 648 |
| 649 double |
| 650 WirelessModuleUtility::SendJammingSignal (double power, Time duration) |
| 651 { |
| 652 NS_LOG_FUNCTION (this << power << duration); |
| 653 |
| 654 // Check that the power is within allowed range of PHY layer |
| 655 if (power > m_phyLayerInfo.maxTxPowerW) |
| 656 { |
| 657 NS_LOG_ERROR ("WirelessModuleUtility:Power of "<< power << |
| 658 " W is not supported by PHY layer, max power = " << |
| 659 m_phyLayerInfo.maxTxPowerW << ", scaling to max power!"); |
| 660 power = m_phyLayerInfo.maxTxPowerW; |
| 661 } |
| 662 else if (power < m_phyLayerInfo.minTxPowerW) |
| 663 { |
| 664 NS_LOG_ERROR ("WirelessModuleUtility:Power of "<< power << |
| 665 " W is not supported by PHY layer, min power = " << |
| 666 m_phyLayerInfo.minTxPowerW << ", scaling to min power!"); |
| 667 power = m_phyLayerInfo.minTxPowerW; |
| 668 } |
| 669 |
| 670 /* |
| 671 * Convert the desired signal length into a packet of corresponding size for |
| 672 * sending through PHY layer. |
| 673 */ |
| 674 uint32_t numBytes = duration.GetSeconds() * m_phyLayerInfo.phyRate / 8 ; |
| 675 ·· |
| 676 if (m_sendPacketCallback.IsNull ()) |
| 677 { |
| 678 NS_FATAL_ERROR ("WirelessModuleUtility:Send packet callback is NOT set!"); |
| 679 } |
| 680 // send jamming signal |
| 681 m_sendPacketCallback (Create<Packet> (numBytes), power, SEND_AS_JAMMER); |
| 682 |
| 683 return power; |
| 684 } |
| 685 |
| 686 void |
| 687 WirelessModuleUtility::SwitchChannel (uint16_t channelNumber) |
| 688 { |
| 689 NS_LOG_FUNCTION (this << channelNumber); |
| 690 |
| 691 /* |
| 692 * Check if callback is setup. If PHY does not support channel switch, this |
| 693 * callback will be NULL. |
| 694 */ |
| 695 if (m_channelSwitchCallback.IsNull ()) |
| 696 { |
| 697 NS_FATAL_ERROR ("WirelessModuleUtility:Channel switch callback not set!"); |
| 698 } |
| 699 else |
| 700 { |
| 701 m_channelSwitchCallback (channelNumber); |
| 702 } |
| 703 } |
| 704 |
| 705 double |
| 706 WirelessModuleUtility::SendMitigationMessage (Ptr<Packet> packet, double power) |
| 707 { |
| 708 NS_LOG_FUNCTION (this << packet << power); |
| 709 |
| 710 // Check that the power is within allowed range of PHY layer |
| 711 if (power > m_phyLayerInfo.maxTxPowerW) |
| 712 { |
| 713 NS_LOG_ERROR ("WirelessModuleUtility:Power of "<< power << |
| 714 " W is not supported by PHY layer, max power = " << |
| 715 m_phyLayerInfo.maxTxPowerW << ", scaling to max power!"); |
| 716 power = m_phyLayerInfo.maxTxPowerW; |
| 717 } |
| 718 else if (power < m_phyLayerInfo.minTxPowerW) |
| 719 { |
| 720 NS_LOG_ERROR ("WirelessModuleUtility:Power of "<< power << |
| 721 " W is not supported by PHY layer, min power = " << |
| 722 m_phyLayerInfo.minTxPowerW << ", scaling to min power!"); |
| 723 power = m_phyLayerInfo.minTxPowerW; |
| 724 } |
| 725 |
| 726 // check if callback is installed |
| 727 if (m_sendPacketCallback.IsNull ()) |
| 728 { |
| 729 NS_FATAL_ERROR ("WirelessModuleUtility:Send packet callback is NOT set!"); |
| 730 } |
| 731 |
| 732 // send jamming signal |
| 733 m_sendPacketCallback (packet, power, SEND_AS_HONEST); |
| 734 |
| 735 return power; |
| 736 } |
| 737 |
| 738 double |
| 739 WirelessModuleUtility::DbmToW (double dBm) const |
| 740 { |
| 741 double mW = pow(10.0,dBm/10.0); |
| 742 return mW / 1000.0; |
| 743 } |
| 744 |
| 745 double |
| 746 WirelessModuleUtility::WToDbm (double w) const |
| 747 { |
| 748 return 10.0 * log10(w * 1000.0); |
| 749 } |
| 750 |
| 751 } // namespace ns3 |
LEFT | RIGHT |