A Discrete-Event Network Simulator
API
spectrum-wifi-phy.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006 INRIA
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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  * Ghada Badawy <gbadawy@gmail.com>
20  * S├ębastien Deronne <sebastien.deronne@gmail.com>
21  *
22  * Ported from yans-wifi-phy.cc by several contributors starting
23  * with Nicola Baldo and Dean Armstrong
24  */
25 
26 #include "spectrum-wifi-phy.h"
27 #include "ns3/spectrum-channel.h"
28 #include "ns3/spectrum-value.h"
29 #include "ns3/wifi-spectrum-value-helper.h"
30 #include "wifi-phy-state-helper.h"
31 #include "ns3/simulator.h"
32 #include "ns3/assert.h"
33 #include "ns3/log.h"
34 #include "ns3/double.h"
35 #include "ns3/boolean.h"
36 #include "ampdu-tag.h"
38 #include "wifi-phy-tag.h"
39 #include "ns3/antenna-model.h"
40 #include <cmath>
41 
42 namespace ns3 {
43 
44 NS_LOG_COMPONENT_DEFINE ("SpectrumWifiPhy");
45 
46 NS_OBJECT_ENSURE_REGISTERED (SpectrumWifiPhy);
47 
48 TypeId
50 {
51  static TypeId tid = TypeId ("ns3::SpectrumWifiPhy")
52  .SetParent<WifiPhy> ()
53  .SetGroupName ("Wifi")
54  .AddConstructor<SpectrumWifiPhy> ()
55  .AddAttribute ("DisableWifiReception", "Prevent Wi-Fi frame sync from ever happening",
56  BooleanValue (false),
59  .AddTraceSource ("SignalArrival",
60  "Signal arrival",
62  "ns3::SpectrumWifiPhy::SignalArrivalCallback")
63  ;
64  return tid;
65 }
66 
68 {
69  NS_LOG_FUNCTION (this);
70 }
71 
73 {
74  NS_LOG_FUNCTION (this);
75 }
76 
77 void
79 {
80  NS_LOG_FUNCTION (this);
81  m_channel = 0;
83 }
84 
85 void
87 {
88  NS_LOG_FUNCTION (this);
90  // This connection is deferred until frequency and channel width are set
92  {
94  }
95  else
96  {
97  NS_FATAL_ERROR ("SpectrumWifiPhy misses channel and WifiSpectrumPhyInterface objects at initialization time");
98  }
99 }
100 
101 bool
103 {
104  if (IsInitialized () == false)
105  {
106  //this is not channel switch, this is initialization
107  NS_LOG_DEBUG ("start at channel " << nch);
108  return true;
109  }
110 
112  switch (m_state->GetState ())
113  {
114  case SpectrumWifiPhy::RX:
115  NS_LOG_DEBUG ("drop packet because of channel switching while reception");
117  m_endRxEvent.Cancel ();
118  goto switchChannel;
119  break;
120  case SpectrumWifiPhy::TX:
121  NS_LOG_DEBUG ("channel switching postponed until end of current transmission");
123  break;
126  goto switchChannel;
127  break;
129  NS_LOG_DEBUG ("channel switching ignored in sleep mode");
130  break;
131  default:
132  NS_ASSERT (false);
133  break;
134  }
135 
136  return false;
137 
138 switchChannel:
139 
140  NS_LOG_DEBUG ("switching channel " << GetChannelNumber () << " -> " << nch);
142  m_state->SwitchToChannelSwitching (GetChannelSwitchDelay ());
144  /*
145  * Needed here to be able to correctly sensed the medium for the first
146  * time after the switching. The actual switching is not performed until
147  * after m_channelSwitchDelay. Packets received during the switching
148  * state are added to the event list and are employed later to figure
149  * out the state of the medium after the switching.
150  */
151  return true;
152 }
153 
154 bool
156 {
157  if (IsInitialized () == false)
158  {
159  //this is not channel switch, this is initialization
160  NS_LOG_DEBUG ("start at frequency " << frequency);
161  return true;
162  }
163 
165  switch (m_state->GetState ())
166  {
167  case SpectrumWifiPhy::RX:
168  NS_LOG_DEBUG ("drop packet because of channel/frequency switching while reception");
170  m_endRxEvent.Cancel ();
171  goto switchFrequency;
172  break;
173  case SpectrumWifiPhy::TX:
174  NS_LOG_DEBUG ("channel/frequency switching postponed until end of current transmission");
176  break;
179  goto switchFrequency;
180  break;
182  NS_LOG_DEBUG ("frequency switching ignored in sleep mode");
183  break;
184  default:
185  NS_ASSERT (false);
186  break;
187  }
188 
189  return false;
190 
191 switchFrequency:
192 
193  NS_LOG_DEBUG ("switching frequency " << GetFrequency () << " -> " << frequency);
195  m_state->SwitchToChannelSwitching (GetChannelSwitchDelay ());
197  /*
198  * Needed here to be able to correctly sensed the medium for the first
199  * time after the switching. The actual switching is not performed until
200  * after m_channelSwitchDelay. Packets received during the switching
201  * state are added to the event list and are employed later to figure
202  * out the state of the medium after the switching.
203  */
204  return true;
205 }
206 
209 {
210  NS_LOG_FUNCTION (this);
211  if (m_rxSpectrumModel)
212  {
213  return m_rxSpectrumModel;
214  }
215  else
216  {
217  if (GetFrequency () == 0)
218  {
219  NS_LOG_DEBUG ("Frequency is not set; returning 0");
220  return 0;
221  }
222  else
223  {
224  NS_LOG_DEBUG ("Creating spectrum model from frequency/width pair of (" << GetFrequency () << ", " << GetChannelWidth () << ")");
226  }
227  }
228  return m_rxSpectrumModel;
229 }
230 
233 {
234  return Ptr<WifiChannel> (0);
235 }
236 
237 void
239 {
240  m_channel = channel;
241 }
242 
243 void
245 {
246  m_rxCallback = callback;
247 }
248 
249 void
251 {
252  m_operationalChannelList.push_back (channelNumber);
253 }
254 
255 std::vector<uint16_t>
257 {
258  std::vector<uint16_t> channelList;
259  channelList.push_back (GetChannelNumber ()); // first channel of list
260  for (std::vector<uint16_t>::size_type i = 0; i != m_operationalChannelList.size (); i++)
261  {
263  {
264  channelList.push_back (m_operationalChannelList[i]);
265  }
266  }
267  return channelList;
268 }
269 
270 void
272 {
273  m_operationalChannelList.clear ();
274 }
275 
276 void
278 {
279  NS_LOG_FUNCTION (this);
280  switch (m_state->GetState ())
281  {
282  case SpectrumWifiPhy::TX:
283  NS_LOG_DEBUG ("setting sleep mode postponed until end of current transmission");
285  break;
286  case SpectrumWifiPhy::RX:
287  NS_LOG_DEBUG ("setting sleep mode postponed until end of current reception");
289  break;
291  NS_LOG_DEBUG ("setting sleep mode postponed until end of channel switching");
293  break;
296  NS_LOG_DEBUG ("setting sleep mode");
297  m_state->SwitchToSleep ();
298  break;
300  NS_LOG_DEBUG ("already in sleep mode");
301  break;
302  default:
303  NS_ASSERT (false);
304  break;
305  }
306 }
307 
308 void
310 {
311  NS_LOG_FUNCTION (this);
312  switch (m_state->GetState ())
313  {
314  case SpectrumWifiPhy::TX:
315  case SpectrumWifiPhy::RX:
319  {
320  NS_LOG_DEBUG ("not in sleep mode, there is nothing to resume");
321  break;
322  }
324  {
325  NS_LOG_DEBUG ("resuming from sleep mode");
327  m_state->SwitchFromSleep (delayUntilCcaEnd);
328  break;
329  }
330  default:
331  {
332  NS_ASSERT (false);
333  break;
334  }
335  }
336 }
337 
338 void
340 {
341  m_state->SetReceiveOkCallback (callback);
342 }
343 
344 void
346 {
347  m_state->SetReceiveErrorCallback (callback);
348 }
349 
350 void
352 {
353  NS_LOG_FUNCTION (this);
354  //We are here because we have received the first bit of a packet and we are
355  //not going to be able to synchronize on it
356  //In this model, CCA becomes busy when the aggregation of all signals as
357  //tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
358 
360  if (!delayUntilCcaEnd.IsZero ())
361  {
362  NS_LOG_DEBUG ("Calling SwitchMaybeToCcaBusy for " << delayUntilCcaEnd.As (Time::S));
363  m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
364  }
365 }
366 
367 void
369 {
370  NS_LOG_FUNCTION (this << rxParams);
371  Time rxDuration = rxParams->duration;
372  Ptr<SpectrumValue> receivedSignalPsd = rxParams->psd;
373  NS_LOG_DEBUG ("Received signal with PSD " << *receivedSignalPsd << " and duration " << rxDuration.As (Time::NS));
374  uint32_t senderNodeId = 0;
375  if (rxParams->txPhy)
376  {
377  senderNodeId = rxParams->txPhy->GetDevice ()->GetNode ()->GetId ();
378  }
379  NS_LOG_DEBUG ("Received signal from " << senderNodeId << " with unfiltered power " << WToDbm (Integral (*receivedSignalPsd)) << " dBm");
380  // Integrate over our receive bandwidth (i.e., all that the receive
381  // spectral mask representing our filtering allows) to find the
382  // total energy apparent to the "demodulator".
384  SpectrumValue filteredSignal = (*filter) * (*receivedSignalPsd);
385  // Add receiver antenna gain
386  NS_LOG_DEBUG ("Signal power received (watts) before antenna gain: " << Integral (filteredSignal));
387  double rxPowerW = Integral (filteredSignal) * DbToRatio (GetRxGain ());
388  NS_LOG_DEBUG ("Signal power received after antenna gain: " << rxPowerW << " W (" << WToDbm (rxPowerW) << " dBm)");
389 
390  Ptr<WifiSpectrumSignalParameters> wifiRxParams = DynamicCast<WifiSpectrumSignalParameters> (rxParams);
391 
392  // Log the signal arrival to the trace source
393  m_signalCb (wifiRxParams ? true : false, senderNodeId, WToDbm (rxPowerW), rxDuration);
394  if (wifiRxParams == 0)
395  {
396  NS_LOG_INFO ("Received non Wi-Fi signal");
397  m_interference.AddForeignSignal (rxDuration, rxPowerW);
399  return;
400  }
401  if (wifiRxParams && m_disableWifiReception)
402  {
403  NS_LOG_INFO ("Received Wi-Fi signal but blocked from syncing");
404  m_interference.AddForeignSignal (rxDuration, rxPowerW);
406  return;
407  }
408 
409  NS_LOG_INFO ("Received Wi-Fi signal");
410  Ptr<Packet> packet = wifiRxParams->packet->Copy ();
411  WifiPhyTag tag;
412  bool found = packet->PeekPacketTag (tag);
413  if (!found)
414  {
415  NS_FATAL_ERROR ("Received Wi-Fi Spectrum Signal with no WifiPhyTag");
416  return;
417  }
418 
419  WifiTxVector txVector = tag.GetWifiTxVector ();
420  if (txVector.GetNss () > GetNumberOfReceiveAntennas ())
421  {
422  /* failure. */
423  NotifyRxDrop (packet);
424  NS_LOG_INFO ("Reception ends in failure because less RX antennas than number of spatial streams");
426  return;
427  }
428 
429  enum WifiPreamble preamble = tag.GetWifiPreamble ();
430  enum mpduType mpdutype = tag.GetMpduType ();
431 
432  // At this point forward, processing parallels that of
433  // YansWifiPhy::StartReceivePreambleAndHeader ()
434 
435  AmpduTag ampduTag;
436  Time endRx = Simulator::Now () + rxDuration;
437  Time preambleAndHeaderDuration = CalculatePlcpPreambleAndHeaderDuration (txVector, preamble);
438 
440  event = m_interference.Add (packet->GetSize (),
441  txVector,
442  preamble,
443  rxDuration,
444  rxPowerW);
445 
446  switch (m_state->GetState ())
447  {
449  NS_LOG_DEBUG ("drop packet because of channel switching");
450  NotifyRxDrop (packet);
451  m_plcpSuccess = false;
452  /*
453  * Packets received on the upcoming channel are added to the event list
454  * during the switching state. This way the medium can be correctly sensed
455  * when the device listens to the channel for the first time after the
456  * switching e.g. after channel switching, the channel may be sensed as
457  * busy due to other devices' tramissions started before the end of
458  * the switching.
459  */
460  if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
461  {
462  //that packet will be noise _after_ the completion of the
463  //channel switching.
465  return;
466  }
467  break;
468  case SpectrumWifiPhy::RX:
469  NS_LOG_DEBUG ("drop packet because already in Rx (power=" <<
470  rxPowerW << "W)");
471  NotifyRxDrop (packet);
472  if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
473  {
474  //that packet will be noise _after_ the reception of the
475  //currently-received packet.
477  return;
478  }
479  break;
480  case SpectrumWifiPhy::TX:
481  NS_LOG_DEBUG ("drop packet because already in Tx (power=" <<
482  rxPowerW << "W)");
483  NotifyRxDrop (packet);
484  if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
485  {
486  //that packet will be noise _after_ the transmission of the
487  //currently-transmitted packet.
489  return;
490  }
491  break;
494  if (rxPowerW > GetEdThresholdW ()) //checked here, no need to check in the payload reception (current implementation assumes constant rx power over the packet duration)
495  {
496  if (preamble == WIFI_PREAMBLE_NONE && m_mpdusNum == 0)
497  {
498  NS_LOG_DEBUG ("drop packet because no preamble has been received");
499  NotifyRxDrop (packet);
501  return;
502  }
503  else if (preamble == WIFI_PREAMBLE_NONE && m_plcpSuccess == false) //A-MPDU reception fails
504  {
505  NS_LOG_DEBUG ("Drop MPDU because no plcp has been received");
506  NotifyRxDrop (packet);
508  return;
509  }
510  else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum == 0)
511  {
512  //received the first MPDU in an MPDU
513  m_mpdusNum = ampduTag.GetRemainingNbOfMpdus () - 1;
515  }
516  else if (preamble == WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0)
517  {
518  //received the other MPDUs that are part of the A-MPDU
519  if (ampduTag.GetRemainingNbOfMpdus () < m_mpdusNum)
520  {
521  NS_LOG_DEBUG ("Missing MPDU from the A-MPDU " << m_mpdusNum - ampduTag.GetRemainingNbOfMpdus ());
522  m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
523  }
524  else
525  {
526  m_mpdusNum--;
527  }
528  }
529  else if (preamble != WIFI_PREAMBLE_NONE && m_mpdusNum > 0 )
530  {
531  NS_LOG_DEBUG ("Didn't receive the last MPDUs from an A-MPDU " << m_mpdusNum);
532  m_mpdusNum = 0;
533  }
534 
535  NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)");
536  //sync to signal
537  m_state->SwitchToRx (rxDuration);
539  NotifyRxBegin (packet);
541 
542  if (preamble != WIFI_PREAMBLE_NONE)
543  {
545  m_endPlcpRxEvent = Simulator::Schedule (preambleAndHeaderDuration, &SpectrumWifiPhy::StartReceivePacket, this,
546  packet, txVector, preamble, mpdutype, event);
547  }
548 
551  packet, preamble, mpdutype, event);
552  }
553  else
554  {
555  NS_LOG_DEBUG ("drop packet because signal power too Small (" <<
556  rxPowerW << "<" << GetEdThresholdW () << ")");
557  NotifyRxDrop (packet);
558  m_plcpSuccess = false;
560  return;
561  }
562  break;
564  NS_LOG_DEBUG ("drop packet because in sleep mode");
565  NotifyRxDrop (packet);
566  m_plcpSuccess = false;
567  break;
568  }
569 
570  return;
571 }
572 
573 void
575  WifiTxVector txVector,
576  enum WifiPreamble preamble,
577  enum mpduType mpdutype,
579 {
580  NS_LOG_FUNCTION (this << packet << txVector.GetMode () << preamble << (uint32_t)mpdutype);
581  NS_ASSERT (IsStateRx ());
583  AmpduTag ampduTag;
584  WifiMode txMode = txVector.GetMode ();
585 
586  struct InterferenceHelper::SnrPer snrPer;
587  snrPer = m_interference.CalculatePlcpHeaderSnrPer (event);
588 
589  NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per);
590 
591  if (m_random->GetValue () > snrPer.per) //plcp reception succeeded
592  {
593  if (IsModeSupported (txMode) || IsMcsSupported (txMode))
594  {
595  NS_LOG_DEBUG ("receiving plcp payload"); //endReceive is already scheduled
596  m_plcpSuccess = true;
597  }
598  else //mode is not allowed
599  {
600  NS_LOG_DEBUG ("drop packet because it was sent using an unsupported mode (" << txMode << ")");
601  NotifyRxDrop (packet);
602  m_plcpSuccess = false;
603  }
604  }
605  else //plcp reception failed
606  {
607  NS_LOG_DEBUG ("drop packet because plcp preamble/header reception failed");
608  NotifyRxDrop (packet);
609  m_plcpSuccess = false;
610  }
611 }
612 
615 {
617 }
618 
621 {
622  return m_antenna;
623 }
624 
625 void
627 {
628  NS_LOG_FUNCTION (this << a);
629  m_antenna = a;
630 }
631 
632 void
634 {
635  NS_LOG_FUNCTION (this << device);
636  m_wifiSpectrumPhyInterface = CreateObject<WifiSpectrumPhyInterface> ();
637  m_wifiSpectrumPhyInterface->SetSpectrumWifiPhy (this);
638  m_wifiSpectrumPhyInterface->SetDevice (device);
639 }
640 
641 void
643 {
644  SendPacket (packet, txVector, preamble, NORMAL_MPDU);
645 }
646 
648 SpectrumWifiPhy::GetTxPowerSpectralDensity (uint32_t centerFrequency, uint32_t channelWidth, double txPowerW) const
649 {
650  NS_LOG_FUNCTION (centerFrequency << channelWidth << txPowerW);
652  switch (GetStandard ())
653  {
659  v = WifiSpectrumValueHelper::CreateOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW);
660  break;
662  v = WifiSpectrumValueHelper::CreateDsssTxPowerSpectralDensity (centerFrequency, txPowerW);
663  break;
667  v = WifiSpectrumValueHelper::CreateHtOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW);
668  break;
669  default:
670  NS_FATAL_ERROR ("Standard unknown: " << GetStandard ());
671  break;
672  }
673  return v;
674 }
675 
676 void
678 {
679  NS_LOG_FUNCTION (this << packet << txVector.GetMode ()
680  << txVector.GetMode ().GetDataRate (txVector)
681  << preamble << (uint32_t)txVector.GetTxPowerLevel () << (uint32_t)mpdutype);
682  /* Transmission can happen if:
683  * - we are syncing on a packet. It is the responsability of the
684  * MAC layer to avoid doing this but the PHY does nothing to
685  * prevent it.
686  * - we are idle
687  */
688  NS_ASSERT (!m_state->IsStateTx () && !m_state->IsStateSwitching ());
689 
690  if (m_state->IsStateSleep ())
691  {
692  NS_LOG_DEBUG ("Dropping packet because in sleep mode");
693  NotifyTxDrop (packet);
694  return;
695  }
696 
697  Time txDuration = CalculateTxDuration (packet->GetSize (), txVector, preamble, GetFrequency (), mpdutype, 1);
698  NS_ASSERT (txDuration > NanoSeconds (0));
699 
700  if (m_state->IsStateRx ())
701  {
703  m_endRxEvent.Cancel ();
705  }
706  NotifyTxBegin (packet);
707  uint32_t dataRate500KbpsUnits;
709  {
710  dataRate500KbpsUnits = 128 + txVector.GetMode ().GetMcsValue ();
711  }
712  else
713  {
714  dataRate500KbpsUnits = txVector.GetMode ().GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1) * txVector.GetNss () / 500000;
715  }
716  if (mpdutype == MPDU_IN_AGGREGATE && preamble != WIFI_PREAMBLE_NONE)
717  {
718  //send the first MPDU in an MPDU
720  }
721  struct mpduInfo aMpdu;
722  aMpdu.type = mpdutype;
724  NotifyMonitorSniffTx (packet, (uint16_t) GetFrequency (), GetChannelNumber (), dataRate500KbpsUnits, preamble, txVector, aMpdu);
725  m_state->SwitchToTx (txDuration, packet, GetPowerDbm (txVector.GetTxPowerLevel ()), txVector, preamble);
726  //
727  // Spectrum elements added here
728  //
729  Ptr<Packet> newPacket = packet->Copy (); // obtain non-const Packet
730  WifiPhyTag oldtag;
731  newPacket->RemovePacketTag (oldtag);
732  WifiPhyTag tag (txVector, preamble, mpdutype);
733  newPacket->AddPacketTag (tag);
734 
735  NS_LOG_DEBUG ("Transmission signal power before antenna gain: " << GetPowerDbm (txVector.GetTxPowerLevel ()) << " dBm");
736  double txPowerWatts = DbmToW (GetPowerDbm (txVector.GetTxPowerLevel ()) + GetTxGain ());
737 
738  Ptr<SpectrumValue> txPowerSpectrum = GetTxPowerSpectralDensity (GetFrequency (), GetChannelWidth (), txPowerWatts);
739  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
740  txParams->duration = txDuration;
741  txParams->psd = txPowerSpectrum;
742  NS_ASSERT_MSG (m_wifiSpectrumPhyInterface, "SpectrumPhy() is not set; maybe forgot to call CreateWifiSpectrumPhyInterface?");
743  txParams->txPhy = m_wifiSpectrumPhyInterface->GetObject<SpectrumPhy> ();
744  txParams->txAntenna = m_antenna;
745  txParams->packet = newPacket;
746  NS_LOG_DEBUG ("Starting transmission with power " << WToDbm (txPowerWatts) << " dBm on channel " << GetChannelNumber ());
747  NS_LOG_DEBUG ("Starting transmission with integrated spectrum power " << WToDbm (Integral (*txPowerSpectrum)) << " dBm; spectrum model Uid: " << txPowerSpectrum->GetSpectrumModel ()->GetUid ());
748  m_channel->StartTx (txParams);
749 }
750 
751 void
753 {
754  m_state->RegisterListener (listener);
755 }
756 
757 void
759 {
760  m_state->UnregisterListener (listener);
761 }
762 
763 void
765 {
766  NS_LOG_FUNCTION (this << packet << event);
767  NS_ASSERT (IsStateRx ());
768  NS_ASSERT (event->GetEndTime () == Simulator::Now ());
769 
770  struct InterferenceHelper::SnrPer snrPer;
773  bool rxSucceeded;
774 
775  if (m_plcpSuccess == true)
776  {
777  NS_LOG_DEBUG ("mode=" << (event->GetPayloadMode ().GetDataRate (event->GetTxVector ())) <<
778  ", snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per << ", size=" << packet->GetSize ());
779 
780  if (m_random->GetValue () > snrPer.per)
781  {
782  NotifyRxEnd (packet);
783  uint32_t dataRate500KbpsUnits;
784  if ((event->GetPayloadMode ().GetModulationClass () == WIFI_MOD_CLASS_HT) || (event->GetPayloadMode ().GetModulationClass () == WIFI_MOD_CLASS_VHT))
785  {
786  dataRate500KbpsUnits = 128 + event->GetPayloadMode ().GetMcsValue ();
787  }
788  else
789  {
790  dataRate500KbpsUnits = event->GetPayloadMode ().GetDataRate (event->GetTxVector ().GetChannelWidth (), event->GetTxVector ().IsShortGuardInterval (), 1) * event->GetTxVector ().GetNss () / 500000;
791  }
792  struct signalNoiseDbm signalNoise;
793  signalNoise.signal = RatioToDb (event->GetRxPowerW ()) + 30;
794  signalNoise.noise = RatioToDb (event->GetRxPowerW () / snrPer.snr) - GetRxNoiseFigure () + 30;
795  struct mpduInfo aMpdu;
796  aMpdu.type = mpdutype;
798  NotifyMonitorSniffRx (packet, (uint16_t) GetFrequency (), GetChannelNumber (), dataRate500KbpsUnits, event->GetPreambleType (), event->GetTxVector (), aMpdu, signalNoise);
799  m_state->SwitchFromRxEndOk (packet, snrPer.snr, event->GetTxVector (), event->GetPreambleType ());
800  rxSucceeded = true;
801  }
802  else
803  {
804  /* failure. */
805  NotifyRxDrop (packet);
806  m_state->SwitchFromRxEndError (packet, snrPer.snr);
807  rxSucceeded = false;
808  }
809  if (!m_rxCallback.IsNull ())
810  {
811  m_rxCallback (rxSucceeded);
812  }
813  }
814  else
815  {
816  m_state->SwitchFromRxEndError (packet, snrPer.snr);
817  if (!m_rxCallback.IsNull ())
818  {
819  m_rxCallback (false);
820  }
821  }
822 
823  if (preamble == WIFI_PREAMBLE_NONE && mpdutype == LAST_MPDU_IN_AGGREGATE)
824  {
825  m_plcpSuccess = false;
826  }
827 
828 }
829 
830 } //namespace ns3
ERP-OFDM PHY (Clause 19, Section 19.5)
Ptr< SpectrumValue > GetTxPowerSpectralDensity(uint32_t centerFrequency, uint32_t channelWidth, double txPowerW) const
tuple channel
Definition: third.py:85
uint32_t m_txMpduReferenceNumber
A-MPDU reference number to identify all transmitted subframes belonging to the same received A-MPDU...
Definition: wifi-phy.h:1589
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
static Ptr< SpectrumModel > GetSpectrumModel(uint32_t centerFrequency, uint32_t channelWidth)
Return a SpectrumModel instance corresponding to the center frequency and channel width...
virtual bool DoChannelSwitch(uint16_t id)
The default implementation does nothing and returns true.
TracedCallback< bool, uint32_t, double, Time > m_signalCb
void AddForeignSignal(Time duration, double rxPower)
Add a non-Wifi signal to interference helper.
void NotifyMonitorSniffTx(Ptr< const Packet > packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, WifiPreamble preamble, WifiTxVector txVector, struct mpduInfo aMpdu)
Public method used to fire a MonitorSniffer trace for a wifi packet being transmitted.
Definition: wifi-phy.cc:1990
A struct for both SNR and PER.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
OFDM PHY for the 5 GHz band (Clause 17 with 5 MHz channel bandwidth)
double RatioToDb(double ratio) const
Convert from ratio to dB.
Definition: wifi-phy.cc:2894
Abstract base class for Spectrum-aware PHY layers.
Definition: spectrum-phy.h:45
double GetTxGain(void) const
Return the transmission gain (dB).
Definition: wifi-phy.cc:514
double GetRxNoiseFigure(void) const
Return the RX noise figure (dBm).
Definition: wifi-phy.cc:462
AttributeValue implementation for Boolean.
Definition: boolean.h:34
virtual bool IsMcsSupported(WifiMode mcs) const
Check if the given WifiMode is supported by the PHY.
Definition: wifi-phy.cc:2837
HT OFDM PHY for the 5 GHz band (clause 20)
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
double Integral(const SpectrumValue &arg)
uint8_t GetRemainingNbOfMpdus(void) const
Definition: ampdu-tag.cc:110
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
void StartReceivePacket(Ptr< Packet > packet, WifiTxVector txVector, WifiPreamble preamble, enum mpduType mpdutype, Ptr< InterferenceHelper::Event > event)
Starting receiving the payload of a packet (i.e.
virtual void SetReceiveErrorCallback(WifiPhy::RxErrorCallback callback)
void StartRx(Ptr< SpectrumSignalParameters > rxParams)
Input method for delivering a signal from the spectrum channel and low-level Phy interface to this Sp...
void SetChannel(Ptr< SpectrumChannel > channel)
Set the SpectrumChannel this SpectrumWifiPhy is to be connected to.
enum mpduType type
Definition: wifi-phy.h:74
802.11 PHY layer model
Definition: wifi-phy.h:162
The PHY layer has sense the medium busy through the CCA mechanism.
Definition: wifi-phy.h:177
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:81
bool IsZero(void) const
Definition: nstime.h:274
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:824
void SetAntenna(Ptr< AntennaModel > antenna)
enum WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:379
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1270
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
Time GetEnergyDuration(double energyW)
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
static TypeId GetTypeId(void)
bool IsShortGuardInterval(void) const
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:792
second
Definition: nstime.h:114
OFDM PHY for the 5 GHz band (Clause 17 with 10 MHz channel bandwidth)
bool m_disableWifiReception
forces this Phy to fail to sync on any signal
The PHY layer is sleeping.
Definition: wifi-phy.h:193
virtual Ptr< WifiChannel > GetChannel(void) const
Return the WifiChannel this WifiPhy is connected to.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
void NotifyTxDrop(Ptr< const Packet > packet)
Public method used to fire a PhyTxDrop trace.
Definition: wifi-phy.cc:1960
HT OFDM PHY for the 2.4 GHz band (clause 20)
VHT PHY (Clause 22)
Definition: wifi-mode.h:64
Ptr< const SpectrumModel > GetRxSpectrumModel() const
Ptr< WifiSpectrumPhyInterface > GetSpectrumPhy(void) const
void NotifyTxBegin(Ptr< const Packet > packet)
Public method used to fire a PhyTxBegin trace.
Definition: wifi-phy.cc:1948
virtual void UnregisterListener(WifiPhyListener *listener)
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:99
virtual bool IsModeSupported(WifiMode mode) const
Check if the given WifiMode is supported by the PHY.
Definition: wifi-phy.cc:2824
static Ptr< SpectrumValue > CreateHtOfdmTxPowerSpectralDensity(uint32_t centerFrequency, uint32_t channelWidth, double txPowerW)
Create a transmit power spectral density corresponding to OFDM High Throughput (HT) (802...
void NotifyMonitorSniffRx(Ptr< const Packet > packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, WifiPreamble preamble, WifiTxVector txVector, struct mpduInfo aMpdu, struct signalNoiseDbm signalNoise)
Public method used to fire a MonitorSniffer trace for a wifi packet being received.
Definition: wifi-phy.cc:1984
virtual void SetSleepMode(void)
Put in sleep mode.
uint8_t GetTxPowerLevel(void) const
virtual void DoInitialize(void)
Initialize() implementation.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
static Ptr< SpectrumValue > CreateDsssTxPowerSpectralDensity(uint32_t centerFrequency, double txPowerW)
Create a transmit power spectral density corresponding to DSSS.
Ptr< SpectrumChannel > m_channel
SpectrumChannel that this SpectrumWifiPhy is connected to.
uint16_t m_mpdusNum
carries the number of expected mpdus that are part of an A-MPDU
Definition: wifi-phy.h:1587
void NotifyRxDrop(Ptr< const Packet > packet)
Public method used to fire a PhyRxDrop trace.
Definition: wifi-phy.cc:1978
virtual uint32_t GetNumberOfReceiveAntennas(void) const
Definition: wifi-phy.cc:1182
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
Definition: wifi-preamble.h:30
double GetPowerDbm(uint8_t power) const
Get the power of the given power level in dBm.
Definition: wifi-phy.cc:641
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:846
std::vector< uint16_t > GetOperationalChannelList(void) const
Return a list of channels to which it may be possible to roam By default, this method will return the...
The MPDU is not part of an A-MPDU.
Definition: wifi-phy.h:59
virtual uint16_t GetChannelNumber(void) const
Return current channel number.
Definition: wifi-phy.cc:1329
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1238
Time CalculatePlcpPreambleAndHeaderDuration(WifiTxVector txVector, enum WifiPreamble preamble)
Definition: wifi-phy.cc:1921
Ptr< AntennaModel > GetRxAntenna(void) const
Get the antenna model used for reception.
uint32_t mpduRefNumber
Definition: wifi-phy.h:75
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:919
receive notifications about phy events.
Definition: wifi-phy.h:81
The PHY layer is IDLE.
Definition: wifi-phy.h:173
EventId m_endPlcpRxEvent
Definition: wifi-phy.h:1593
uint32_t GetChannelWidth(void) const
HT PHY (Clause 20)
Definition: wifi-mode.h:62
struct InterferenceHelper::SnrPer CalculatePlcpHeaderSnrPer(Ptr< InterferenceHelper::Event > event)
Calculate the SNIR at the start of the plcp header and accumulate all SNIR changes in the snir vector...
virtual Time GetDelayUntilIdle(void)
Definition: wifi-phy.cc:2948
uint8_t GetMcsValue(void) const
Definition: wifi-mode.cc:357
Time CalculateTxDuration(uint32_t size, WifiTxVector txVector, enum WifiPreamble preamble, double frequency)
Definition: wifi-phy.cc:1942
uint32_t m_rxMpduReferenceNumber
A-MPDU reference number to identify all received subframes belonging to the same received A-MPDU...
Definition: wifi-phy.h:1590
The PHY layer is receiving a packet.
Definition: wifi-phy.h:185
virtual uint32_t GetFrequency(void) const
Definition: wifi-phy.cc:1143
virtual void DoDispose(void)
Destructor implementation.
void SetPacketReceivedCallback(RxCallback callback)
Set the packet received callback (invoked at the end of a frame reception), to notify whether the fra...
The aim of the AmpduTag is to provide means for a MAC to specify that a packet includes A-MPDU since ...
Definition: ampdu-tag.h:38
802.11 PHY layer modelThis PHY implements a spectrum-aware enhancement of the 802.11 SpectrumWifiPhy model.
void NotifyRxBegin(Ptr< const Packet > packet)
Public method used to fire a PhyRxBegin trace.
Definition: wifi-phy.cc:1966
The PHY layer is sending a packet.
Definition: wifi-phy.h:181
virtual void RegisterListener(WifiPhyListener *listener)
virtual void SetChannelNumber(uint16_t id)
Set channel number.
Definition: wifi-phy.cc:1275
Ptr< const SpectrumModel > m_rxSpectrumModel
static Ptr< SpectrumValue > CreateRfFilter(uint32_t centerFrequency, uint32_t channelWidth)
The PHY layer is switching to other channel.
Definition: wifi-phy.h:189
The MPDU is part of an A-MPDU, but is not the last aggregate.
Definition: wifi-phy.h:61
This is intended to be the configuration used in this paper: Gavin Holland, Nitin Vaidya and Paramvir...
void AddOperationalChannel(uint16_t channelNumber)
Add a channel number to the list of operational channels.
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
virtual uint32_t GetChannelWidth(void) const
Definition: wifi-phy.cc:1157
struct InterferenceHelper::SnrPer CalculatePlcpPayloadSnrPer(Ptr< InterferenceHelper::Event > event)
Calculate the SNIR at the start of the plcp payload and accumulate all SNIR changes in the snir vecto...
OFDM PHY for the 5 GHz band (Clause 17)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void NotifyRxStart()
Notify that RX has started.
VHT OFDM PHY (clause 22)
void EraseEvents(void)
Erase all events.
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
Ptr< InterferenceHelper::Event > Add(uint32_t size, WifiTxVector txVector, enum WifiPreamble preamble, Time duration, double rxPower)
Add the packet-related signal to interference helper.
DSSS PHY (Clause 15) and HR/DSSS PHY (Clause 18)
bool IsInitialized(void) const
Check if the object has been initialized.
Definition: object.cc:208
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
uint64_t GetDataRate(uint32_t channelWidth, bool isShortGuardInterval, uint8_t nss) const
Definition: wifi-mode.cc:109
WifiPreamble GetWifiPreamble(void) const
Getter for WifiPreamble parameter.
Definition: wifi-phy-tag.cc:96
virtual void DoInitialize(void)
Initialize() implementation.
Definition: wifi-phy.cc:382
static Ptr< SpectrumValue > CreateOfdmTxPowerSpectralDensity(uint32_t centerFrequency, uint32_t channelWidth, double txPowerW)
Create a transmit power spectral density corresponding to OFDM (802.11a/g).
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:224
Ptr< UniformRandomVariable > m_random
Provides uniform random variables.
Definition: wifi-phy.h:1584
virtual void SetReceiveOkCallback(WifiPhy::RxOkCallback callback)
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:90
WifiTxVector GetWifiTxVector(void) const
Getter for WifiTxVector parameter.
Definition: wifi-phy-tag.cc:90
uint8_t GetNss(void) const
void EndReceive(Ptr< Packet > packet, enum WifiPreamble preamble, enum mpduType mpdutype, Ptr< InterferenceHelper::Event > event)
The last bit of the packet has arrived.
bool m_plcpSuccess
Flag if the PLCP of the packet or the first MPDU in an A-MPDU has been received.
Definition: wifi-phy.h:1588
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:388
EventId m_endRxEvent
Definition: wifi-phy.h:1592
Ptr< WifiPhyStateHelper > m_state
Pointer to WifiPhyStateHelper.
Definition: wifi-phy.h:1585
void NotifyRxEnd(Ptr< const Packet > packet)
Public method used to fire a PhyRxEnd trace.
Definition: wifi-phy.cc:1972
void NotifyRxEnd()
Notify that RX has ended.
virtual bool IsStateSwitching(void)
Definition: wifi-phy.cc:2930
virtual void SendPacket(Ptr< const Packet > packet, WifiTxVector txVector, enum WifiPreamble preamble)
InterferenceHelper m_interference
Pointer to InterferenceHelper.
Definition: wifi-phy.h:1583
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:831
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
Ptr< AntennaModel > m_antenna
enum mpduType GetMpduType(void) const
Getter for mpduType parameter.
void ClearOperationalChannelList(void)
Clear the list of operational channels.
virtual void SetFrequency(uint32_t freq)
Definition: wifi-phy.cc:1086
virtual Time GetChannelSwitchDelay(void) const
Definition: wifi-phy.cc:659
Ptr< WifiSpectrumPhyInterface > m_wifiSpectrumPhyInterface
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
Tag for WifiTxVector and WifiPreamble information to be embedded in outgoing transmissions as a Packe...
Definition: wifi-phy-tag.h:36
std::vector< uint16_t > m_operationalChannelList
List of possible channels.
double WToDbm(double w) const
Convert from Watts to dBm.
Definition: wifi-phy.cc:2888
void SwitchMaybeToCcaBusy(void)
Check if Phy state should move to CCA busy state based on current state of interference tracker...
double DbmToW(double dbm) const
Convert from dBm to Watts.
Definition: wifi-phy.cc:2881
nanosecond
Definition: nstime.h:117
virtual enum WifiPhyStandard GetStandard(void) const
Get the configured Wi-Fi standard.
Definition: wifi-phy.cc:1080
double GetEdThresholdW(void) const
Return the energy detection threshold.
Definition: wifi-phy.cc:430
WifiMode GetMode(void) const
virtual void ResumeFromSleep(void)
Resume from sleep mode.
virtual bool IsStateRx(void)
Definition: wifi-phy.cc:2918
Set of values corresponding to a given SpectrumModel.
double GetCcaMode1Threshold(void) const
Return the CCA threshold (dBm).
Definition: wifi-phy.cc:449
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:59
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:904
double DbToRatio(double db) const
Convert from dB to ratio.
Definition: wifi-phy.cc:2874
double GetRxGain(void) const
Return the reception gain (dB).
Definition: wifi-phy.cc:527
void CreateWifiSpectrumPhyInterface(Ptr< NetDevice > device)
Method to encapsulate the creation of the WifiSpectrumPhyInterface object (used to bind the WifiSpect...
mpduType
This enumeration defines the type of an MPDU.
Definition: wifi-phy.h:56
virtual bool DoFrequencySwitch(uint32_t frequency)
The default implementation does nothing and returns true.
The MPDU is the last aggregate in an A-MPDU.
Definition: wifi-phy.h:63