View | Details | Raw Unified | Return to bug 2552
Collapse All | Expand All

(-)a/src/wifi/model/spectrum-wifi-phy.cc (-518 / +5 lines)
 Lines 33-43    Link Here 
33
#include "ns3/log.h"
33
#include "ns3/log.h"
34
#include "ns3/double.h"
34
#include "ns3/double.h"
35
#include "ns3/boolean.h"
35
#include "ns3/boolean.h"
36
#include "ampdu-tag.h"
37
#include "wifi-spectrum-signal-parameters.h"
36
#include "wifi-spectrum-signal-parameters.h"
38
#include "wifi-phy-tag.h"
39
#include "ns3/antenna-model.h"
37
#include "ns3/antenna-model.h"
40
#include <cmath>
38
#include "wifi-utils.h"
41
39
42
namespace ns3 {
40
namespace ns3 {
43
41
 Lines 98-209    Link Here 
98
    }
96
    }
99
}
97
}
100
98
101
bool
102
SpectrumWifiPhy::DoChannelSwitch (uint16_t nch)
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
111
  NS_ASSERT (!IsStateSwitching ());
112
  switch (m_state->GetState ())
113
    {
114
    case SpectrumWifiPhy::RX:
115
      NS_LOG_DEBUG ("drop packet because of channel switching while reception");
116
      m_endPlcpRxEvent.Cancel ();
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");
122
      Simulator::Schedule (GetDelayUntilIdle (), &WifiPhy::SetChannelNumber, this, nch);
123
      break;
124
    case SpectrumWifiPhy::CCA_BUSY:
125
    case SpectrumWifiPhy::IDLE:
126
      goto switchChannel;
127
      break;
128
    case SpectrumWifiPhy::SLEEP:
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);
141
  m_rxSpectrumModel = WifiSpectrumValueHelper::GetSpectrumModel (GetFrequency (), GetChannelWidth ());
142
  m_state->SwitchToChannelSwitching (GetChannelSwitchDelay ());
143
  m_interference.EraseEvents ();
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
155
SpectrumWifiPhy::DoFrequencySwitch (uint32_t frequency)
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
164
  NS_ASSERT (!IsStateSwitching ());
165
  switch (m_state->GetState ())
166
    {
167
    case SpectrumWifiPhy::RX:
168
      NS_LOG_DEBUG ("drop packet because of channel/frequency switching while reception");
169
      m_endPlcpRxEvent.Cancel ();
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");
175
      Simulator::Schedule (GetDelayUntilIdle (), &WifiPhy::SetFrequency, this, frequency);
176
      break;
177
    case SpectrumWifiPhy::CCA_BUSY:
178
    case SpectrumWifiPhy::IDLE:
179
      goto switchFrequency;
180
      break;
181
    case SpectrumWifiPhy::SLEEP:
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);
194
  m_rxSpectrumModel = WifiSpectrumValueHelper::GetSpectrumModel (GetFrequency (), GetChannelWidth ());
195
  m_state->SwitchToChannelSwitching (GetChannelSwitchDelay ());
196
  m_interference.EraseEvents ();
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
207
Ptr<const SpectrumModel>
99
Ptr<const SpectrumModel>
208
SpectrumWifiPhy::GetRxSpectrumModel () const
100
SpectrumWifiPhy::GetRxSpectrumModel () const
209
{
101
{
 Lines 241-252    Link Here 
241
}
133
}
242
134
243
void
135
void
244
SpectrumWifiPhy::SetPacketReceivedCallback (RxCallback callback)
245
{
246
  m_rxCallback = callback;
247
}
248
249
void
250
SpectrumWifiPhy::AddOperationalChannel (uint16_t channelNumber)
136
SpectrumWifiPhy::AddOperationalChannel (uint16_t channelNumber)
251
{
137
{
252
  m_operationalChannelList.push_back (channelNumber);
138
  m_operationalChannelList.push_back (channelNumber);
 Lines 274-353    Link Here 
274
}
160
}
275
161
276
void
162
void
277
SpectrumWifiPhy::SetSleepMode (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");
284
      Simulator::Schedule (GetDelayUntilIdle (), &SpectrumWifiPhy::SetSleepMode, this);
285
      break;
286
    case SpectrumWifiPhy::RX:
287
      NS_LOG_DEBUG ("setting sleep mode postponed until end of current reception");
288
      Simulator::Schedule (GetDelayUntilIdle (), &SpectrumWifiPhy::SetSleepMode, this);
289
      break;
290
    case SpectrumWifiPhy::SWITCHING:
291
      NS_LOG_DEBUG ("setting sleep mode postponed until end of channel switching");
292
      Simulator::Schedule (GetDelayUntilIdle (), &SpectrumWifiPhy::SetSleepMode, this);
293
      break;
294
    case SpectrumWifiPhy::CCA_BUSY:
295
    case SpectrumWifiPhy::IDLE:
296
      NS_LOG_DEBUG ("setting sleep mode");
297
      m_state->SwitchToSleep ();
298
      break;
299
    case SpectrumWifiPhy::SLEEP:
300
      NS_LOG_DEBUG ("already in sleep mode");
301
      break;
302
    default:
303
      NS_ASSERT (false);
304
      break;
305
    }
306
}
307
308
void
309
SpectrumWifiPhy::ResumeFromSleep (void)
310
{
311
  NS_LOG_FUNCTION (this);
312
  switch (m_state->GetState ())
313
    {
314
    case SpectrumWifiPhy::TX:
315
    case SpectrumWifiPhy::RX:
316
    case SpectrumWifiPhy::IDLE:
317
    case SpectrumWifiPhy::CCA_BUSY:
318
    case SpectrumWifiPhy::SWITCHING:
319
      {
320
        NS_LOG_DEBUG ("not in sleep mode, there is nothing to resume");
321
        break;
322
      }
323
    case SpectrumWifiPhy::SLEEP:
324
      {
325
        NS_LOG_DEBUG ("resuming from sleep mode");
326
        Time delayUntilCcaEnd = m_interference.GetEnergyDuration (DbmToW (GetCcaMode1Threshold ()));
327
        m_state->SwitchFromSleep (delayUntilCcaEnd);
328
        break;
329
      }
330
    default:
331
      {
332
        NS_ASSERT (false);
333
        break;
334
      }
335
    }
336
}
337
338
void
339
SpectrumWifiPhy::SetReceiveOkCallback (RxOkCallback callback)
340
{
341
  m_state->SetReceiveOkCallback (callback);
342
}
343
344
void
345
SpectrumWifiPhy::SetReceiveErrorCallback (RxErrorCallback callback)
346
{
347
  m_state->SetReceiveErrorCallback (callback);
348
}
349
350
void
351
SpectrumWifiPhy::StartRx (Ptr<SpectrumSignalParameters> rxParams)
163
SpectrumWifiPhy::StartRx (Ptr<SpectrumSignalParameters> rxParams)
352
{
164
{
353
  NS_LOG_FUNCTION (this << rxParams);
165
  NS_LOG_FUNCTION (this << rxParams);
 Lines 391-597    Link Here 
391
203
392
  NS_LOG_INFO ("Received Wi-Fi signal");
204
  NS_LOG_INFO ("Received Wi-Fi signal");
393
  Ptr<Packet> packet = wifiRxParams->packet->Copy ();
205
  Ptr<Packet> packet = wifiRxParams->packet->Copy ();
394
  WifiPhyTag tag;
206
  StartReceivePreambleAndHeader (packet, rxPowerW, rxDuration);
395
  bool found = packet->PeekPacketTag (tag);
396
  if (!found)
397
    {
398
      NS_FATAL_ERROR ("Received Wi-Fi Spectrum Signal with no WifiPhyTag");
399
      return;
400
    }
401
    
402
  WifiTxVector txVector = tag.GetWifiTxVector ();
403
404
  if (txVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HT
405
      && (txVector.GetNss () != (1 + (txVector.GetMode ().GetMcsValue () / 8))))
406
    {
407
      NS_FATAL_ERROR ("MCS value does not match NSS value: MCS = " << (uint16_t)txVector.GetMode ().GetMcsValue () << ", NSS = " << (uint16_t)txVector.GetNss ());
408
    }
409
410
  if (txVector.GetNss () > GetMaxSupportedRxSpatialStreams ())
411
    {
412
      NS_FATAL_ERROR ("Reception ends in failure because of an unsupported number of spatial streams");
413
    }
414
415
  WifiPreamble preamble = txVector.GetPreambleType ();
416
  MpduType mpdutype = tag.GetMpduType ();
417
418
  // At this point forward, processing parallels that of
419
  // YansWifiPhy::StartReceivePreambleAndHeader ()
420
421
  AmpduTag ampduTag;
422
  Time endRx = Simulator::Now () + rxDuration;
423
  Time preambleAndHeaderDuration = CalculatePlcpPreambleAndHeaderDuration (txVector);
424
425
  Ptr<InterferenceHelper::Event> event;
426
  event = m_interference.Add (packet->GetSize (),
427
                              txVector,
428
                              rxDuration,
429
                              rxPowerW);
430
431
  switch (m_state->GetState ())
432
    {
433
    case SpectrumWifiPhy::SWITCHING:
434
      NS_LOG_DEBUG ("drop packet because of channel switching");
435
      NotifyRxDrop (packet);
436
      m_plcpSuccess = false;
437
      /*
438
       * Packets received on the upcoming channel are added to the event list
439
       * during the switching state. This way the medium can be correctly sensed
440
       * when the device listens to the channel for the first time after the
441
       * switching e.g. after channel switching, the channel may be sensed as
442
       * busy due to other devices' tramissions started before the end of
443
       * the switching.
444
       */
445
      if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
446
        {
447
          //that packet will be noise _after_ the completion of the
448
          //channel switching.
449
          SwitchMaybeToCcaBusy ();
450
          return;
451
        }
452
      break;
453
    case SpectrumWifiPhy::RX:
454
      NS_LOG_DEBUG ("drop packet because already in Rx (power=" <<
455
                    rxPowerW << "W)");
456
      NotifyRxDrop (packet);
457
      if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
458
        {
459
          //that packet will be noise _after_ the reception of the
460
          //currently-received packet.
461
          SwitchMaybeToCcaBusy ();
462
          return;
463
        }
464
      break;
465
    case SpectrumWifiPhy::TX:
466
      NS_LOG_DEBUG ("drop packet because already in Tx (power=" <<
467
                    rxPowerW << "W)");
468
      NotifyRxDrop (packet);
469
      if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
470
        {
471
          //that packet will be noise _after_ the transmission of the
472
          //currently-transmitted packet.
473
          SwitchMaybeToCcaBusy ();
474
          return;
475
        }
476
      break;
477
    case SpectrumWifiPhy::CCA_BUSY:
478
    case SpectrumWifiPhy::IDLE:
479
      if (rxPowerW > GetEdThresholdW ()) //checked here, no need to check in the payload reception (current implementation assumes constant rx power over the packet duration)
480
        {
481
          if (preamble == WIFI_PREAMBLE_NONE && m_mpdusNum == 0)
482
            {
483
              NS_LOG_DEBUG ("drop packet because no preamble has been received");
484
              NotifyRxDrop (packet);
485
              SwitchMaybeToCcaBusy ();
486
              return;
487
            }
488
          else if (preamble == WIFI_PREAMBLE_NONE && m_plcpSuccess == false) //A-MPDU reception fails
489
            {
490
              NS_LOG_DEBUG ("Drop MPDU because no plcp has been received");
491
              NotifyRxDrop (packet);
492
              SwitchMaybeToCcaBusy ();
493
              return;
494
            }
495
          else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum == 0)
496
            {
497
              //received the first MPDU in an MPDU
498
              m_mpdusNum = ampduTag.GetRemainingNbOfMpdus () - 1;
499
              m_rxMpduReferenceNumber++;
500
            }
501
          else if (preamble == WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0)
502
            {
503
              //received the other MPDUs that are part of the A-MPDU
504
              if (ampduTag.GetRemainingNbOfMpdus () < m_mpdusNum)
505
                {
506
                  NS_LOG_DEBUG ("Missing MPDU from the A-MPDU " << m_mpdusNum - ampduTag.GetRemainingNbOfMpdus ());
507
                  m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
508
                }
509
              else
510
                {
511
                  m_mpdusNum--;
512
                }
513
            }
514
          else if (preamble != WIFI_PREAMBLE_NONE && m_mpdusNum > 0 )
515
            {
516
              NS_LOG_DEBUG ("Didn't receive the last MPDUs from an A-MPDU " << m_mpdusNum);
517
              m_mpdusNum = 0;
518
            }
519
520
          NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)");
521
          //sync to signal
522
          m_state->SwitchToRx (rxDuration);
523
          NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
524
          NotifyRxBegin (packet);
525
          m_interference.NotifyRxStart ();
526
527
          if (preamble != WIFI_PREAMBLE_NONE)
528
            {
529
              NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
530
              m_endPlcpRxEvent = Simulator::Schedule (preambleAndHeaderDuration, &SpectrumWifiPhy::StartReceivePacket, this,
531
                                                      packet, txVector, mpdutype, event);
532
            }
533
534
          NS_ASSERT (m_endRxEvent.IsExpired ());
535
          m_endRxEvent = Simulator::Schedule (rxDuration, &SpectrumWifiPhy::EndReceive, this,
536
                                              packet, preamble, mpdutype, event);
537
        }
538
      else
539
        {
540
          NS_LOG_DEBUG ("drop packet because signal power too Small (" <<
541
                        rxPowerW << "<" << GetEdThresholdW () << ")");
542
          NotifyRxDrop (packet);
543
          m_plcpSuccess = false;
544
          SwitchMaybeToCcaBusy ();
545
          return;
546
        }
547
      break;
548
    case SpectrumWifiPhy::SLEEP:
549
      NS_LOG_DEBUG ("drop packet because in sleep mode");
550
      NotifyRxDrop (packet);
551
      m_plcpSuccess = false;
552
      break;
553
    }
554
555
  return;
556
}
557
558
void
559
SpectrumWifiPhy::StartReceivePacket (Ptr<Packet> packet,
560
                                     WifiTxVector txVector,
561
                                     MpduType mpdutype,
562
                                     Ptr<InterferenceHelper::Event> event)
563
{
564
  NS_LOG_FUNCTION (this << packet << txVector.GetMode () << txVector.GetPreambleType () << (uint32_t)mpdutype);
565
  NS_ASSERT (IsStateRx ());
566
  NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
567
  AmpduTag ampduTag;
568
  WifiMode txMode = txVector.GetMode ();
569
570
  InterferenceHelper::SnrPer snrPer;
571
  snrPer = m_interference.CalculatePlcpHeaderSnrPer (event);
572
573
  NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per);
574
575
  if (m_random->GetValue () > snrPer.per) //plcp reception succeeded
576
    {
577
      if (IsModeSupported (txMode) || IsMcsSupported (txMode))
578
        {
579
          NS_LOG_DEBUG ("receiving plcp payload"); //endReceive is already scheduled
580
          m_plcpSuccess = true;
581
        }
582
      else //mode is not allowed
583
        {
584
          NS_LOG_DEBUG ("drop packet because it was sent using an unsupported mode (" << txMode << ")");
585
          NotifyRxDrop (packet);
586
          m_plcpSuccess = false;
587
        }
588
    }
589
  else //plcp reception failed
590
    {
591
      NS_LOG_DEBUG ("drop packet because plcp preamble/header reception failed");
592
      NotifyRxDrop (packet);
593
      m_plcpSuccess = false;
594
    }
595
}
207
}
596
208
597
Ptr<WifiSpectrumPhyInterface>
209
Ptr<WifiSpectrumPhyInterface>
 Lines 652-716    Link Here 
652
}
264
}
653
265
654
void
266
void
655
SpectrumWifiPhy::SendPacket (Ptr<const Packet> packet, WifiTxVector txVector, MpduType mpdutype)
267
SpectrumWifiPhy::StartTx (Ptr<Packet> packet, WifiTxVector txVector, Time txDuration)
656
{
268
{
657
  NS_LOG_FUNCTION (this << packet << txVector.GetMode ()
269
  NS_LOG_DEBUG ("Start transmission: signal power before antenna gain=" << GetPowerDbm (txVector.GetTxPowerLevel ()) << "dBm");
658
                        << txVector.GetMode ().GetDataRate (txVector)
659
                        << txVector.GetPreambleType ()
660
                        << (uint32_t)txVector.GetTxPowerLevel ()
661
                        << (uint32_t)mpdutype);
662
  /* Transmission can happen if:
663
   *  - we are syncing on a packet. It is the responsability of the
664
   *    MAC layer to avoid doing this but the PHY does nothing to
665
   *    prevent it.
666
   *  - we are idle
667
   */
668
  NS_ASSERT (!m_state->IsStateTx () && !m_state->IsStateSwitching ());
669
  
670
  if (txVector.GetNss () > GetMaxSupportedTxSpatialStreams ())
671
    {
672
      NS_FATAL_ERROR ("Unsupported number of spatial streams!");
673
    }
674
675
  if (m_state->IsStateSleep ())
676
    {
677
      NS_LOG_DEBUG ("Dropping packet because in sleep mode");
678
      NotifyTxDrop (packet);
679
      return;
680
    }
681
682
  Time txDuration = CalculateTxDuration (packet->GetSize (), txVector, GetFrequency (), mpdutype, 1);
683
  NS_ASSERT (txDuration > NanoSeconds (0));
684
685
  if (m_state->IsStateRx ())
686
    {
687
      m_endPlcpRxEvent.Cancel ();
688
      m_endRxEvent.Cancel ();
689
      m_interference.NotifyRxEnd ();
690
    }
691
  NotifyTxBegin (packet);
692
  if ((mpdutype == MPDU_IN_AGGREGATE) && (txVector.GetPreambleType () != WIFI_PREAMBLE_NONE))
693
    {
694
      //send the first MPDU in an MPDU
695
      m_txMpduReferenceNumber++;
696
    }
697
  MpduInfo aMpdu;
698
  aMpdu.type = mpdutype;
699
  aMpdu.mpduRefNumber = m_txMpduReferenceNumber;
700
  NotifyMonitorSniffTx (packet, (uint16_t) GetFrequency (), GetChannelNumber (), txVector, aMpdu);
701
  m_state->SwitchToTx (txDuration, packet, GetPowerDbm (txVector.GetTxPowerLevel ()), txVector);
702
  //
703
  // Spectrum elements added here
704
  //
705
  Ptr<Packet> newPacket = packet->Copy (); // obtain non-const Packet
706
  WifiPhyTag oldtag;
707
  newPacket->RemovePacketTag (oldtag);
708
  WifiPhyTag tag (txVector, mpdutype);
709
  newPacket->AddPacketTag (tag);
710
711
  NS_LOG_DEBUG ("Transmission signal power before antenna gain: " << GetPowerDbm (txVector.GetTxPowerLevel ()) << " dBm");
712
  double txPowerWatts = DbmToW (GetPowerDbm (txVector.GetTxPowerLevel ()) + GetTxGain ());
270
  double txPowerWatts = DbmToW (GetPowerDbm (txVector.GetTxPowerLevel ()) + GetTxGain ());
713
714
  Ptr<SpectrumValue> txPowerSpectrum = GetTxPowerSpectralDensity (GetFrequency (), GetChannelWidth (), txPowerWatts);
271
  Ptr<SpectrumValue> txPowerSpectrum = GetTxPowerSpectralDensity (GetFrequency (), GetChannelWidth (), txPowerWatts);
715
  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
272
  Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
716
  txParams->duration = txDuration;
273
  txParams->duration = txDuration;
 Lines 718-797    Link Here 
718
  NS_ASSERT_MSG (m_wifiSpectrumPhyInterface, "SpectrumPhy() is not set; maybe forgot to call CreateWifiSpectrumPhyInterface?");
275
  NS_ASSERT_MSG (m_wifiSpectrumPhyInterface, "SpectrumPhy() is not set; maybe forgot to call CreateWifiSpectrumPhyInterface?");
719
  txParams->txPhy = m_wifiSpectrumPhyInterface->GetObject<SpectrumPhy> ();
276
  txParams->txPhy = m_wifiSpectrumPhyInterface->GetObject<SpectrumPhy> ();
720
  txParams->txAntenna = m_antenna;
277
  txParams->txAntenna = m_antenna;
721
  txParams->packet = newPacket;
278
  txParams->packet = packet;
722
  NS_LOG_DEBUG ("Starting transmission with power " << WToDbm (txPowerWatts) << " dBm on channel " << GetChannelNumber ());
279
  NS_LOG_DEBUG ("Starting transmission with power " << WToDbm (txPowerWatts) << " dBm on channel " << GetChannelNumber ());
723
  NS_LOG_DEBUG ("Starting transmission with integrated spectrum power " << WToDbm (Integral (*txPowerSpectrum)) << " dBm; spectrum model Uid: " << txPowerSpectrum->GetSpectrumModel ()->GetUid ());
280
  NS_LOG_DEBUG ("Starting transmission with integrated spectrum power " << WToDbm (Integral (*txPowerSpectrum)) << " dBm; spectrum model Uid: " << txPowerSpectrum->GetSpectrumModel ()->GetUid ());
724
  m_channel->StartTx (txParams);
281
  m_channel->StartTx (txParams);
725
}
282
}
726
283
727
void
728
SpectrumWifiPhy::RegisterListener (WifiPhyListener *listener)
729
{
730
  m_state->RegisterListener (listener);
731
}
732
733
void
734
SpectrumWifiPhy::UnregisterListener (WifiPhyListener *listener)
735
{
736
  m_state->UnregisterListener (listener);
737
}
738
739
void
740
SpectrumWifiPhy::EndReceive (Ptr<Packet> packet, WifiPreamble preamble, MpduType mpdutype, Ptr<InterferenceHelper::Event> event)
741
{
742
  NS_LOG_FUNCTION (this << packet << event);
743
  NS_ASSERT (IsStateRx ());
744
  NS_ASSERT (event->GetEndTime () == Simulator::Now ());
745
746
  InterferenceHelper::SnrPer snrPer;
747
  snrPer = m_interference.CalculatePlcpPayloadSnrPer (event);
748
  m_interference.NotifyRxEnd ();
749
  bool rxSucceeded;
750
751
  if (m_plcpSuccess == true)
752
    {
753
      NS_LOG_DEBUG ("mode=" << (event->GetPayloadMode ().GetDataRate (event->GetTxVector ())) <<
754
                    ", snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per << ", size=" << packet->GetSize ());
755
756
      if (m_random->GetValue () > snrPer.per)
757
        {
758
          NotifyRxEnd (packet);
759
          SignalNoiseDbm signalNoise;
760
          signalNoise.signal = RatioToDb (event->GetRxPowerW ()) + 30;
761
          signalNoise.noise = RatioToDb (event->GetRxPowerW () / snrPer.snr) - GetRxNoiseFigure () + 30;
762
          MpduInfo aMpdu;
763
          aMpdu.type = mpdutype;
764
          aMpdu.mpduRefNumber = m_rxMpduReferenceNumber;
765
          NotifyMonitorSniffRx (packet, (uint16_t) GetFrequency (), GetChannelNumber (), event->GetTxVector (), aMpdu, signalNoise);
766
          m_state->SwitchFromRxEndOk (packet, snrPer.snr, event->GetTxVector ());
767
          rxSucceeded = true;
768
        }
769
      else
770
        {
771
          /* failure. */
772
          NotifyRxDrop (packet);
773
          m_state->SwitchFromRxEndError (packet, snrPer.snr);
774
          rxSucceeded = false;
775
        }
776
      if (!m_rxCallback.IsNull ())
777
        {
778
          m_rxCallback (rxSucceeded);
779
        }
780
    }
781
  else
782
    {
783
      m_state->SwitchFromRxEndError (packet, snrPer.snr);
784
      if (!m_rxCallback.IsNull ())
785
        {
786
          m_rxCallback (false);
787
        }
788
    }
789
790
  if (preamble == WIFI_PREAMBLE_NONE && mpdutype == LAST_MPDU_IN_AGGREGATE)
791
    {
792
      m_plcpSuccess = false;
793
    }
794
795
}
796
797
} //namespace ns3
284
} //namespace ns3
(-)a/src/wifi/model/spectrum-wifi-phy.h (-46 / +12 lines)
 Lines 81-105    Link Here 
81
  void ClearOperationalChannelList (void);
81
  void ClearOperationalChannelList (void);
82
82
83
  /**
83
  /**
84
   * Starting receiving the payload of a packet (i.e. the first bit of the packet has arrived).
85
   *
86
   * \param packet the arriving packet
87
   * \param txVector the TXVECTOR of the arriving packet
88
   * \param mpdutype the type of the MPDU as defined in WifiPhy::MpduType.
89
   * \param event the corresponding event of the first time the packet arrives
90
   */
91
  void StartReceivePacket (Ptr<Packet> packet,
92
                           WifiTxVector txVector,
93
                           MpduType mpdutype,
94
                           Ptr<InterferenceHelper::Event> event);
95
96
  /**
97
   * Input method for delivering a signal from the spectrum channel
84
   * Input method for delivering a signal from the spectrum channel
98
   * and low-level Phy interface to this SpectrumWifiPhy instance.
85
   * and low-level Phy interface to this SpectrumWifiPhy instance.
99
   *
86
   *
100
   * \param rxParams Input signal parameters
87
   * \param rxParams Input signal parameters
101
   */
88
   */
102
  void StartRx (Ptr<SpectrumSignalParameters> rxParams);
89
  void StartRx (Ptr<SpectrumSignalParameters> rxParams);
90
  
91
  /**
92
   * \param packet the packet to send
93
   * \param txVector the TXVECTOR that has tx parameters such as mode, the transmission mode to use to send
94
   *        this packet, and txPowerLevel, a power level to use to send this packet. The real transmission
95
   *        power is calculated as txPowerMin + txPowerLevel * (txPowerMax - txPowerMin) / nTxLevels
96
   * \param txDuration duration of the transmission.
97
   */
98
  void StartTx (Ptr<Packet> packet, WifiTxVector txVector, Time txDuration);
99
  
103
  /**
100
  /**
104
   * Method to encapsulate the creation of the WifiSpectrumPhyInterface
101
   * Method to encapsulate the creation of the WifiSpectrumPhyInterface
105
   * object (used to bind the WifiSpectrumPhy to a SpectrumChannel) and
102
   * object (used to bind the WifiSpectrumPhy to a SpectrumChannel) and
 Lines 136-154    Link Here 
136
   * returned, it means that any model will be accepted.
133
   * returned, it means that any model will be accepted.
137
   */
134
   */
138
  Ptr<const SpectrumModel> GetRxSpectrumModel () const;
135
  Ptr<const SpectrumModel> GetRxSpectrumModel () const;
139
  /**
140
   * Callback invoked at the end of a frame reception, to notify whether
141
   * the frame was received successfully (true) or not (false)
142
   */
143
  typedef Callback<void,bool> RxCallback;
144
  /**
145
   * Set the packet received callback (invoked at the end of a frame
146
   * reception), to notify whether the frame was received successfully
147
   * or not.
148
   *
149
   * \param callback the function to hook to the callback
150
   */
151
  void SetPacketReceivedCallback (RxCallback callback);
152
136
153
  /**
137
  /**
154
   * Callback invoked when the Phy model starts to process a signal
138
   * Callback invoked when the Phy model starts to process a signal
 Lines 160-193    Link Here 
160
   */
144
   */
161
  typedef void (* SignalArrivalCallback) (bool signalType, uint32_t senderNodeId, double rxPower, Time duration);
145
  typedef void (* SignalArrivalCallback) (bool signalType, uint32_t senderNodeId, double rxPower, Time duration);
162
146
163
  virtual void SetReceiveOkCallback (WifiPhy::RxOkCallback callback);
164
  virtual void SetReceiveErrorCallback (WifiPhy::RxErrorCallback callback);
165
  virtual void SendPacket (Ptr<const Packet> packet, WifiTxVector txVector, MpduType mpdutype = NORMAL_MPDU);
166
  virtual void RegisterListener (WifiPhyListener *listener);
167
  virtual void UnregisterListener (WifiPhyListener *listener);
168
  virtual void SetSleepMode (void);
169
  virtual void ResumeFromSleep (void);
170
  virtual Ptr<WifiChannel> GetChannel (void) const;
147
  virtual Ptr<WifiChannel> GetChannel (void) const;
171
148
149
172
protected:
150
protected:
173
  // Inherited
151
  // Inherited
174
  virtual void DoDispose (void);
152
  virtual void DoDispose (void);
175
  virtual void DoInitialize (void);
153
  virtual void DoInitialize (void);
176
  virtual bool DoChannelSwitch (uint16_t id);
154
177
  virtual bool DoFrequencySwitch (uint32_t frequency);
178
155
179
private:
156
private:
180
  /**
157
  /**
181
   * The last bit of the packet has arrived.
182
   *
183
   * \param packet the packet that the last bit has arrived
184
   * \param preamble the preamble of the arriving packet
185
   * \param mpdutype the type of the MPDU as defined in WifiPhy::MpduType.
186
   * \param event the corresponding event of the first time the packet arrives
187
   */
188
  void EndReceive (Ptr<Packet> packet, WifiPreamble preamble, MpduType mpdutype, Ptr<InterferenceHelper::Event> event);
189
190
  /**
191
   * \param centerFrequency center frequency (MHz)
158
   * \param centerFrequency center frequency (MHz)
192
   * \param channelWidth channel width (MHz) of the channel
159
   * \param channelWidth channel width (MHz) of the channel
193
   * \param txPowerW power in W to spread across the bands
160
   * \param txPowerW power in W to spread across the bands
 Lines 204-210    Link Here 
204
  Ptr<WifiSpectrumPhyInterface> m_wifiSpectrumPhyInterface;
171
  Ptr<WifiSpectrumPhyInterface> m_wifiSpectrumPhyInterface;
205
  Ptr<AntennaModel> m_antenna;
172
  Ptr<AntennaModel> m_antenna;
206
  mutable Ptr<const SpectrumModel> m_rxSpectrumModel;
173
  mutable Ptr<const SpectrumModel> m_rxSpectrumModel;
207
  RxCallback m_rxCallback;
208
  bool m_disableWifiReception;          //!< forces this Phy to fail to sync on any signal
174
  bool m_disableWifiReception;          //!< forces this Phy to fail to sync on any signal
209
  TracedCallback<bool, uint32_t, double, Time> m_signalCb;
175
  TracedCallback<bool, uint32_t, double, Time> m_signalCb;
210
176
(-)a/src/wifi/model/wifi-phy.cc (-27 / +498 lines)
 Lines 34-40    Link Here 
34
#include "ns3/pointer.h"
34
#include "ns3/pointer.h"
35
#include "ns3/trace-source-accessor.h"
35
#include "ns3/trace-source-accessor.h"
36
#include "ns3/fatal-error.h"
36
#include "ns3/fatal-error.h"
37
#include <cmath>
37
#include "wifi-phy-tag.h"
38
#include "ampdu-tag.h"
39
#include "wifi-utils.h"
38
40
39
namespace ns3 {
41
namespace ns3 {
40
42
 Lines 416-421    Link Here 
416
}
418
}
417
419
418
void
420
void
421
WifiPhy::SetReceiveOkCallback (RxOkCallback callback)
422
{
423
  m_state->SetReceiveOkCallback (callback);
424
}
425
426
void
427
WifiPhy::SetReceiveErrorCallback (RxErrorCallback callback)
428
{
429
  m_state->SetReceiveErrorCallback (callback);
430
}
431
432
void
433
WifiPhy::RegisterListener (WifiPhyListener *listener)
434
{
435
  m_state->RegisterListener (listener);
436
}
437
438
void
439
WifiPhy::UnregisterListener (WifiPhyListener *listener)
440
{
441
  m_state->UnregisterListener (listener);
442
}
443
444
void
419
WifiPhy::InitializeFrequencyChannelNumber (void)
445
WifiPhy::InitializeFrequencyChannelNumber (void)
420
{
446
{
421
  NS_LOG_FUNCTION (this);
447
  NS_LOG_FUNCTION (this);
 Lines 1364-1378    Link Here 
1364
bool
1390
bool
1365
WifiPhy::DoChannelSwitch (uint16_t nch)
1391
WifiPhy::DoChannelSwitch (uint16_t nch)
1366
{
1392
{
1393
  if (!IsInitialized ())
1394
    {
1395
      //this is not channel switch, this is initialization
1396
      NS_LOG_DEBUG ("initialize to channel " << nch);
1397
      return true;
1398
    }
1399
1400
  NS_ASSERT (!IsStateSwitching ());
1401
  switch (m_state->GetState ())
1402
    {
1403
    case WifiPhy::RX:
1404
      NS_LOG_DEBUG ("drop packet because of channel switching while reception");
1405
      m_endPlcpRxEvent.Cancel ();
1406
      m_endRxEvent.Cancel ();
1407
      goto switchChannel;
1408
      break;
1409
    case WifiPhy::TX:
1410
      NS_LOG_DEBUG ("channel switching postponed until end of current transmission");
1411
      Simulator::Schedule (GetDelayUntilIdle (), &WifiPhy::SetChannelNumber, this, nch);
1412
      break;
1413
    case WifiPhy::CCA_BUSY:
1414
    case WifiPhy::IDLE:
1415
      goto switchChannel;
1416
      break;
1417
    case WifiPhy::SLEEP:
1418
      NS_LOG_DEBUG ("channel switching ignored in sleep mode");
1419
      break;
1420
    default:
1421
      NS_ASSERT (false);
1422
      break;
1423
    }
1424
1425
  return false;
1426
1427
switchChannel:
1428
1429
  NS_LOG_DEBUG ("switching channel " << GetChannelNumber () << " -> " << nch);
1430
  m_state->SwitchToChannelSwitching (GetChannelSwitchDelay ());
1431
  m_interference.EraseEvents ();
1432
  /*
1433
   * Needed here to be able to correctly sensed the medium for the first
1434
   * time after the switching. The actual switching is not performed until
1435
   * after m_channelSwitchDelay. Packets received during the switching
1436
   * state are added to the event list and are employed later to figure
1437
   * out the state of the medium after the switching.
1438
   */
1367
  return true;
1439
  return true;
1368
}
1440
}
1369
1441
1370
bool
1442
bool
1371
WifiPhy::DoFrequencySwitch (uint32_t frequency)
1443
WifiPhy::DoFrequencySwitch (uint32_t frequency)
1372
{
1444
{
1445
  if (!IsInitialized ())
1446
    {
1447
      //this is not channel switch, this is initialization
1448
      NS_LOG_DEBUG ("start at frequency " << frequency);
1449
      return true;
1450
    }
1451
1452
  NS_ASSERT (!IsStateSwitching ());
1453
  switch (m_state->GetState ())
1454
    {
1455
    case WifiPhy::RX:
1456
      NS_LOG_DEBUG ("drop packet because of channel/frequency switching while reception");
1457
      m_endPlcpRxEvent.Cancel ();
1458
      m_endRxEvent.Cancel ();
1459
      goto switchFrequency;
1460
      break;
1461
    case WifiPhy::TX:
1462
      NS_LOG_DEBUG ("channel/frequency switching postponed until end of current transmission");
1463
      Simulator::Schedule (GetDelayUntilIdle (), &WifiPhy::SetFrequency, this, frequency);
1464
      break;
1465
    case WifiPhy::CCA_BUSY:
1466
    case WifiPhy::IDLE:
1467
      goto switchFrequency;
1468
      break;
1469
    case WifiPhy::SLEEP:
1470
      NS_LOG_DEBUG ("frequency switching ignored in sleep mode");
1471
      break;
1472
    default:
1473
      NS_ASSERT (false);
1474
      break;
1475
    }
1476
1477
  return false;
1478
1479
switchFrequency:
1480
1481
  NS_LOG_DEBUG ("switching frequency " << GetFrequency () << " -> " << frequency);
1482
  m_state->SwitchToChannelSwitching (GetChannelSwitchDelay ());
1483
  m_interference.EraseEvents ();
1484
  /*
1485
   * Needed here to be able to correctly sensed the medium for the first
1486
   * time after the switching. The actual switching is not performed until
1487
   * after m_channelSwitchDelay. Packets received during the switching
1488
   * state are added to the event list and are employed later to figure
1489
   * out the state of the medium after the switching.
1490
   */
1373
  return true;
1491
  return true;
1374
}
1492
}
1375
1493
1494
void
1495
WifiPhy::SetSleepMode (void)
1496
{
1497
  NS_LOG_FUNCTION (this);
1498
  switch (m_state->GetState ())
1499
    {
1500
    case WifiPhy::TX:
1501
      NS_LOG_DEBUG ("setting sleep mode postponed until end of current transmission");
1502
      Simulator::Schedule (GetDelayUntilIdle (), &WifiPhy::SetSleepMode, this);
1503
      break;
1504
    case WifiPhy::RX:
1505
      NS_LOG_DEBUG ("setting sleep mode postponed until end of current reception");
1506
      Simulator::Schedule (GetDelayUntilIdle (), &WifiPhy::SetSleepMode, this);
1507
      break;
1508
    case WifiPhy::SWITCHING:
1509
      NS_LOG_DEBUG ("setting sleep mode postponed until end of channel switching");
1510
      Simulator::Schedule (GetDelayUntilIdle (), &WifiPhy::SetSleepMode, this);
1511
      break;
1512
    case WifiPhy::CCA_BUSY:
1513
    case WifiPhy::IDLE:
1514
      NS_LOG_DEBUG ("setting sleep mode");
1515
      m_state->SwitchToSleep ();
1516
      break;
1517
    case WifiPhy::SLEEP:
1518
      NS_LOG_DEBUG ("already in sleep mode");
1519
      break;
1520
    default:
1521
      NS_ASSERT (false);
1522
      break;
1523
    }
1524
}
1525
1526
void
1527
WifiPhy::ResumeFromSleep (void)
1528
{
1529
  NS_LOG_FUNCTION (this);
1530
  switch (m_state->GetState ())
1531
    {
1532
    case WifiPhy::TX:
1533
    case WifiPhy::RX:
1534
    case WifiPhy::IDLE:
1535
    case WifiPhy::CCA_BUSY:
1536
    case WifiPhy::SWITCHING:
1537
      {
1538
        NS_LOG_DEBUG ("not in sleep mode, there is nothing to resume");
1539
        break;
1540
      }
1541
    case WifiPhy::SLEEP:
1542
      {
1543
        NS_LOG_DEBUG ("resuming from sleep mode");
1544
        Time delayUntilCcaEnd = m_interference.GetEnergyDuration (DbmToW (GetCcaMode1Threshold ()));
1545
        m_state->SwitchFromSleep (delayUntilCcaEnd);
1546
        break;
1547
      }
1548
    default:
1549
      {
1550
        NS_ASSERT (false);
1551
        break;
1552
      }
1553
    }
1554
}
1555
1376
WifiMode
1556
WifiMode
1377
WifiPhy::GetHtPlcpHeaderMode (WifiMode payloadMode)
1557
WifiPhy::GetHtPlcpHeaderMode (WifiMode payloadMode)
1378
{
1558
{
 Lines 2026-2031    Link Here 
2026
  m_phyMonitorSniffTxTrace (packet, channelFreqMhz, channelNumber, txVector, aMpdu);
2206
  m_phyMonitorSniffTxTrace (packet, channelFreqMhz, channelNumber, txVector, aMpdu);
2027
}
2207
}
2028
2208
2209
void
2210
WifiPhy::SendPacket (Ptr<const Packet> packet, WifiTxVector txVector, MpduType mpdutype)
2211
{
2212
  NS_LOG_FUNCTION (this << packet << txVector.GetMode ()
2213
                        << txVector.GetMode ().GetDataRate (txVector)
2214
                        << txVector.GetPreambleType ()
2215
                        << (uint32_t)txVector.GetTxPowerLevel ()
2216
                        << (uint32_t)mpdutype);
2217
  /* Transmission can happen if:
2218
   *  - we are syncing on a packet. It is the responsability of the
2219
   *    MAC layer to avoid doing this but the PHY does nothing to
2220
   *    prevent it.
2221
   *  - we are idle
2222
   */
2223
  NS_ASSERT (!m_state->IsStateTx () && !m_state->IsStateSwitching ());
2224
  
2225
  if (txVector.GetNss () > GetMaxSupportedTxSpatialStreams ())
2226
    {
2227
      NS_FATAL_ERROR ("Unsupported number of spatial streams!");
2228
    }
2229
2230
  if (m_state->IsStateSleep ())
2231
    {
2232
      NS_LOG_DEBUG ("Dropping packet because in sleep mode");
2233
      NotifyTxDrop (packet);
2234
      return;
2235
    }
2236
2237
  Time txDuration = CalculateTxDuration (packet->GetSize (), txVector, GetFrequency (), mpdutype, 1);
2238
  NS_ASSERT (txDuration > NanoSeconds (0));
2239
2240
  if (m_state->IsStateRx ())
2241
    {
2242
      m_endPlcpRxEvent.Cancel ();
2243
      m_endRxEvent.Cancel ();
2244
      m_interference.NotifyRxEnd ();
2245
    }
2246
  NotifyTxBegin (packet);
2247
  if ((mpdutype == MPDU_IN_AGGREGATE) && (txVector.GetPreambleType () != WIFI_PREAMBLE_NONE))
2248
    {
2249
      //send the first MPDU in an MPDU
2250
      m_txMpduReferenceNumber++;
2251
    }
2252
  MpduInfo aMpdu;
2253
  aMpdu.type = mpdutype;
2254
  aMpdu.mpduRefNumber = m_txMpduReferenceNumber;
2255
  NotifyMonitorSniffTx (packet, (uint16_t) GetFrequency (), GetChannelNumber (), txVector, aMpdu);
2256
  m_state->SwitchToTx (txDuration, packet, GetPowerDbm (txVector.GetTxPowerLevel ()), txVector);
2257
2258
  Ptr<Packet> newPacket = packet->Copy (); // obtain non-const Packet
2259
  WifiPhyTag oldtag;
2260
  newPacket->RemovePacketTag (oldtag);
2261
  WifiPhyTag tag (txVector, mpdutype);
2262
  newPacket->AddPacketTag (tag);
2263
  
2264
  StartTx (newPacket, txVector, txDuration);
2265
}
2266
2267
void
2268
WifiPhy::StartReceivePreambleAndHeader (Ptr<Packet> packet, double rxPowerW, Time rxDuration)
2269
{
2270
  //This function should be later split to check separately whether plcp preamble and plcp header can be successfully received.
2271
  //Note: plcp preamble reception is not yet modeled.
2272
  NS_LOG_FUNCTION (this << packet << WToDbm (rxPowerW) << rxDuration);
2273
  AmpduTag ampduTag;
2274
  Time endRx = Simulator::Now () + rxDuration;
2275
  
2276
  WifiPhyTag tag;
2277
  bool found = packet->RemovePacketTag (tag);
2278
  if (!found)
2279
    {
2280
      NS_FATAL_ERROR ("Received Wi-Fi Signal with no WifiPhyTag");
2281
      return;
2282
    }
2283
2284
  WifiTxVector txVector = tag.GetWifiTxVector ();
2285
  
2286
  if (txVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HT
2287
      && (txVector.GetNss () != (1 + (txVector.GetMode ().GetMcsValue () / 8))))
2288
    {
2289
      NS_FATAL_ERROR ("MCS value does not match NSS value: MCS = " << (uint16_t)txVector.GetMode ().GetMcsValue () << ", NSS = " << (uint16_t)txVector.GetNss ());
2290
    }
2291
  
2292
  if (txVector.GetNss () > GetMaxSupportedRxSpatialStreams ())
2293
     {
2294
      NS_FATAL_ERROR ("Reception ends in failure because of an unsupported number of spatial streams");
2295
     }
2296
2297
  WifiPreamble preamble = txVector.GetPreambleType ();
2298
  MpduType mpdutype = tag.GetMpduType ();
2299
  Time preambleAndHeaderDuration = CalculatePlcpPreambleAndHeaderDuration (txVector);
2300
2301
  Ptr<InterferenceHelper::Event> event;
2302
  event = m_interference.Add (packet->GetSize (),
2303
                              txVector,
2304
                              rxDuration,
2305
                              rxPowerW);
2306
2307
  switch (m_state->GetState ())
2308
    {
2309
    case WifiPhy::SWITCHING:
2310
      NS_LOG_DEBUG ("drop packet because of channel switching");
2311
      NotifyRxDrop (packet);
2312
      m_plcpSuccess = false;
2313
      /*
2314
       * Packets received on the upcoming channel are added to the event list
2315
       * during the switching state. This way the medium can be correctly sensed
2316
       * when the device listens to the channel for the first time after the
2317
       * switching e.g. after channel switching, the channel may be sensed as
2318
       * busy due to other devices' tramissions started before the end of
2319
       * the switching.
2320
       */
2321
      if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
2322
        {
2323
          //that packet will be noise _after_ the completion of the
2324
          //channel switching.
2325
          goto maybeCcaBusy;
2326
        }
2327
      break;
2328
    case WifiPhy::RX:
2329
      NS_LOG_DEBUG ("drop packet because already in Rx (power=" <<
2330
                    rxPowerW << "W)");
2331
      NotifyRxDrop (packet);
2332
      if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
2333
        {
2334
          //that packet will be noise _after_ the reception of the
2335
          //currently-received packet.
2336
          goto maybeCcaBusy;
2337
        }
2338
      break;
2339
    case WifiPhy::TX:
2340
      NS_LOG_DEBUG ("drop packet because already in Tx (power=" <<
2341
                    rxPowerW << "W)");
2342
      NotifyRxDrop (packet);
2343
      if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
2344
        {
2345
          //that packet will be noise _after_ the transmission of the
2346
          //currently-transmitted packet.
2347
          goto maybeCcaBusy;
2348
        }
2349
      break;
2350
    case WifiPhy::CCA_BUSY:
2351
    case WifiPhy::IDLE:
2352
      if (rxPowerW > GetEdThresholdW ()) //checked here, no need to check in the payload reception (current implementation assumes constant rx power over the packet duration)
2353
        {
2354
          if (preamble == WIFI_PREAMBLE_NONE && (m_mpdusNum == 0 || m_plcpSuccess == false))
2355
            {
2356
              m_plcpSuccess = false;
2357
              m_mpdusNum = 0;
2358
              NS_LOG_DEBUG ("drop packet because no PLCP preamble/header has been received");
2359
              NotifyRxDrop (packet);
2360
              goto maybeCcaBusy;
2361
            }
2362
          else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum == 0)
2363
            {
2364
              //received the first MPDU in an MPDU
2365
              m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
2366
              m_rxMpduReferenceNumber++;
2367
            }
2368
          else if (preamble == WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0)
2369
            {
2370
              //received the other MPDUs that are part of the A-MPDU
2371
              if (ampduTag.GetRemainingNbOfMpdus () < (m_mpdusNum - 1))
2372
                {
2373
                  NS_LOG_DEBUG ("Missing MPDU from the A-MPDU " << m_mpdusNum - ampduTag.GetRemainingNbOfMpdus ());
2374
                  m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
2375
                }
2376
              else
2377
                {
2378
                  m_mpdusNum--;
2379
                }
2380
            }
2381
          else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0)
2382
            {
2383
              NS_LOG_DEBUG ("New A-MPDU started while " << m_mpdusNum << " MPDUs from previous are lost");
2384
              m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
2385
            }
2386
          else if (preamble != WIFI_PREAMBLE_NONE && m_mpdusNum > 0 )
2387
            {
2388
              NS_LOG_DEBUG ("Didn't receive the last MPDUs from an A-MPDU " << m_mpdusNum);
2389
              m_mpdusNum = 0;
2390
            }
2391
2392
          NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)");
2393
          //sync to signal
2394
          m_state->SwitchToRx (rxDuration);
2395
          NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
2396
          NotifyRxBegin (packet);
2397
          m_interference.NotifyRxStart ();
2398
2399
          if (preamble != WIFI_PREAMBLE_NONE)
2400
            {
2401
              NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
2402
              m_endPlcpRxEvent = Simulator::Schedule (preambleAndHeaderDuration, &WifiPhy::StartReceivePacket, this,
2403
                                                      packet, txVector, mpdutype, event);
2404
            }
2405
2406
          NS_ASSERT (m_endRxEvent.IsExpired ());
2407
          m_endRxEvent = Simulator::Schedule (rxDuration, &WifiPhy::EndReceive, this,
2408
                                              packet, preamble, mpdutype, event);
2409
        }
2410
      else
2411
        {
2412
          NS_LOG_DEBUG ("drop packet because signal power too Small (" <<
2413
                        rxPowerW << "<" << GetEdThresholdW () << ")");
2414
          NotifyRxDrop (packet);
2415
          m_plcpSuccess = false;
2416
          goto maybeCcaBusy;
2417
        }
2418
      break;
2419
    case WifiPhy::SLEEP:
2420
      NS_LOG_DEBUG ("drop packet because in sleep mode");
2421
      NotifyRxDrop (packet);
2422
      m_plcpSuccess = false;
2423
      break;
2424
    }
2425
2426
  return;
2427
2428
maybeCcaBusy:
2429
  //We are here because we have received the first bit of a packet and we are
2430
  //not going to be able to synchronize on it
2431
  //In this model, CCA becomes busy when the aggregation of all signals as
2432
  //tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
2433
2434
  Time delayUntilCcaEnd = m_interference.GetEnergyDuration (DbmToW (GetCcaMode1Threshold ()));
2435
  if (!delayUntilCcaEnd.IsZero ())
2436
    {
2437
      m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
2438
    }
2439
}
2440
2441
void
2442
WifiPhy::StartReceivePacket (Ptr<Packet> packet,
2443
                             WifiTxVector txVector,
2444
                             MpduType mpdutype,
2445
                             Ptr<InterferenceHelper::Event> event)
2446
{
2447
  NS_LOG_FUNCTION (this << packet << txVector.GetMode () << txVector.GetPreambleType () << (uint32_t)mpdutype);
2448
  NS_ASSERT (IsStateRx ());
2449
  NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
2450
  WifiMode txMode = txVector.GetMode ();
2451
2452
  InterferenceHelper::SnrPer snrPer;
2453
  snrPer = m_interference.CalculatePlcpHeaderSnrPer (event);
2454
2455
  NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per);
2456
2457
  if (m_random->GetValue () > snrPer.per) //plcp reception succeeded
2458
    {
2459
      if (IsModeSupported (txMode) || IsMcsSupported (txMode))
2460
        {
2461
          NS_LOG_DEBUG ("receiving plcp payload"); //endReceive is already scheduled
2462
          m_plcpSuccess = true;
2463
        }
2464
      else //mode is not allowed
2465
        {
2466
          NS_LOG_DEBUG ("drop packet because it was sent using an unsupported mode (" << txMode << ")");
2467
          NotifyRxDrop (packet);
2468
          m_plcpSuccess = false;
2469
        }
2470
    }
2471
  else //plcp reception failed
2472
    {
2473
      NS_LOG_DEBUG ("drop packet because plcp preamble/header reception failed");
2474
      NotifyRxDrop (packet);
2475
      m_plcpSuccess = false;
2476
    }
2477
}
2478
2479
void
2480
WifiPhy::EndReceive (Ptr<Packet> packet, WifiPreamble preamble, MpduType mpdutype, Ptr<InterferenceHelper::Event> event)
2481
{
2482
  NS_LOG_FUNCTION (this << packet << event);
2483
  NS_ASSERT (IsStateRx ());
2484
  NS_ASSERT (event->GetEndTime () == Simulator::Now ());
2485
2486
  InterferenceHelper::SnrPer snrPer;
2487
  snrPer = m_interference.CalculatePlcpPayloadSnrPer (event);
2488
  m_interference.NotifyRxEnd ();
2489
2490
  if (m_plcpSuccess == true)
2491
    {
2492
      NS_LOG_DEBUG ("mode=" << (event->GetPayloadMode ().GetDataRate (event->GetTxVector ())) <<
2493
                    ", snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per << ", size=" << packet->GetSize ());
2494
2495
      if (m_random->GetValue () > snrPer.per)
2496
        {
2497
          NotifyRxEnd (packet);
2498
          SignalNoiseDbm signalNoise;
2499
          signalNoise.signal = RatioToDb (event->GetRxPowerW ()) + 30;
2500
          signalNoise.noise = RatioToDb (event->GetRxPowerW () / snrPer.snr) - GetRxNoiseFigure () + 30;
2501
          MpduInfo aMpdu;
2502
          aMpdu.type = mpdutype;
2503
          aMpdu.mpduRefNumber = m_rxMpduReferenceNumber;
2504
          NotifyMonitorSniffRx (packet, (uint16_t) GetFrequency (), GetChannelNumber (), event->GetTxVector (), aMpdu, signalNoise);
2505
          m_state->SwitchFromRxEndOk (packet, snrPer.snr, event->GetTxVector ());
2506
        }
2507
      else
2508
        {
2509
          /* failure. */
2510
          NotifyRxDrop (packet);
2511
          m_state->SwitchFromRxEndError (packet, snrPer.snr);
2512
        }
2513
    }
2514
  else
2515
    {
2516
      m_state->SwitchFromRxEndError (packet, snrPer.snr);
2517
    }
2518
2519
  if (preamble == WIFI_PREAMBLE_NONE && mpdutype == LAST_MPDU_IN_AGGREGATE)
2520
    {
2521
      m_plcpSuccess = false;
2522
    }
2523
2524
}
2525
2029
2526
2030
// Clause 15 rates (DSSS)
2527
// Clause 15 rates (DSSS)
2031
2528
 Lines 2904-2935    Link Here 
2904
  return m_deviceMcsSet[mcs];
3401
  return m_deviceMcsSet[mcs];
2905
}
3402
}
2906
3403
2907
double
2908
WifiPhy::DbToRatio (double dB) const
2909
{
2910
  double ratio = std::pow (10.0, dB / 10.0);
2911
  return ratio;
2912
}
2913
2914
double
2915
WifiPhy::DbmToW (double dBm) const
2916
{
2917
  double mW = std::pow (10.0, dBm / 10.0);
2918
  return mW / 1000.0;
2919
}
2920
2921
double
2922
WifiPhy::WToDbm (double w) const
2923
{
2924
  return 10.0 * std::log10 (w * 1000.0);
2925
}
2926
2927
double
2928
WifiPhy::RatioToDb (double ratio) const
2929
{
2930
  return 10.0 * std::log10 (ratio);
2931
}
2932
2933
bool
3404
bool
2934
WifiPhy::IsStateCcaBusy (void)
3405
WifiPhy::IsStateCcaBusy (void)
2935
{
3406
{
(-)a/src/wifi/model/wifi-phy.h (-51 / +63 lines)
 Lines 215-227    Link Here 
215
   * \param callback the callback to invoke
215
   * \param callback the callback to invoke
216
   *        upon successful packet reception.
216
   *        upon successful packet reception.
217
   */
217
   */
218
  virtual void SetReceiveOkCallback (RxOkCallback callback) = 0;
218
  void SetReceiveOkCallback (RxOkCallback callback);
219
  /**
219
  /**
220
   * \param callback the callback to invoke
220
   * \param callback the callback to invoke
221
   *        upon erroneous packet reception.
221
   *        upon erroneous packet reception.
222
   */
222
   */
223
  virtual void SetReceiveErrorCallback (RxErrorCallback callback) = 0;
223
  void SetReceiveErrorCallback (RxErrorCallback callback);
224
224
  
225
  /**
226
   * \param listener the new listener
227
   *
228
   * Add the input listener to the list of objects to be notified of
229
   * PHY-level events.
230
   */
231
  void RegisterListener (WifiPhyListener *listener);
232
  /**
233
   * \param listener the listener to be unregistered
234
   *
235
   * Remove the input listener from the list of objects to be notified of
236
   * PHY-level events.
237
   */
238
  void UnregisterListener (WifiPhyListener *listener);
239
  
240
  /**
241
   * Starting receiving the plcp of a packet (i.e. the first bit of the preamble has arrived).
242
   *
243
   * \param packet the arriving packet
244
   * \param rxPowerW the receive power in W
245
   * \param rxDuration the duration needed for the reception of the packet
246
   */
247
  void StartReceivePreambleAndHeader (Ptr<Packet> packet,
248
                                      double rxPowerW,
249
                                      Time rxDuration);
250
  
251
  /**
252
   * Starting receiving the payload of a packet (i.e. the first bit of the packet has arrived).
253
   *
254
   * \param packet the arriving packet
255
   * \param txVector the TXVECTOR of the arriving packet
256
   * \param mpdutype the type of the MPDU as defined in WifiPhy::MpduType.
257
   * \param event the corresponding event of the first time the packet arrives
258
   */
259
  void StartReceivePacket (Ptr<Packet> packet,
260
                           WifiTxVector txVector,
261
                           MpduType mpdutype,
262
                           Ptr<InterferenceHelper::Event> event);
263
    
264
  /**
265
   * The last bit of the packet has arrived.
266
   *
267
   * \param packet the packet that the last bit has arrived
268
   * \param preamble the preamble of the arriving packet
269
   * \param mpdutype the type of the MPDU as defined in WifiPhy::MpduType.
270
   * \param event the corresponding event of the first time the packet arrives
271
   */
272
  void EndReceive (Ptr<Packet> packet, WifiPreamble preamble, MpduType mpdutype, Ptr<InterferenceHelper::Event> event);
273
    
225
  /**
274
  /**
226
   * \param packet the packet to send
275
   * \param packet the packet to send
227
   * \param txVector the TXVECTOR that has tx parameters such as mode, the transmission mode to use to send
276
   * \param txVector the TXVECTOR that has tx parameters such as mode, the transmission mode to use to send
 Lines 229-259    Link Here 
229
   *        power is calculated as txPowerMin + txPowerLevel * (txPowerMax - txPowerMin) / nTxLevels
278
   *        power is calculated as txPowerMin + txPowerLevel * (txPowerMax - txPowerMin) / nTxLevels
230
   * \param mpdutype the type of the MPDU as defined in WifiPhy::MpduType.
279
   * \param mpdutype the type of the MPDU as defined in WifiPhy::MpduType.
231
   */
280
   */
232
  virtual void SendPacket (Ptr<const Packet> packet, WifiTxVector txVector, MpduType mpdutype = NORMAL_MPDU) = 0;
281
  void SendPacket (Ptr<const Packet> packet, WifiTxVector txVector, MpduType mpdutype = NORMAL_MPDU);
233
282
  
234
  /**
283
  /**
235
   * \param listener the new listener
284
   * \param packet the packet to send
236
   *
285
   * \param txVector the TXVECTOR that has tx parameters such as mode, the transmission mode to use to send
237
   * Add the input listener to the list of objects to be notified of
286
   *        this packet, and txPowerLevel, a power level to use to send this packet. The real transmission
238
   * PHY-level events.
287
   *        power is calculated as txPowerMin + txPowerLevel * (txPowerMax - txPowerMin) / nTxLevels
288
   * \param txDuration duration of the transmission.
239
   */
289
   */
240
  virtual void RegisterListener (WifiPhyListener *listener) = 0;
290
  virtual void StartTx (Ptr<Packet> packet, WifiTxVector txVector, Time txDuration) = 0;
241
  /**
242
   * \param listener the listener to be unregistered
243
   *
244
   * Remove the input listener from the list of objects to be notified of
245
   * PHY-level events.
246
   */
247
  virtual void UnregisterListener (WifiPhyListener *listener) = 0;
248
291
249
  /**
292
  /**
250
   * Put in sleep mode.
293
   * Put in sleep mode.
251
   */
294
   */
252
  virtual void SetSleepMode (void) = 0;
295
  virtual void SetSleepMode (void);
253
  /**
296
  /**
254
   * Resume from sleep mode.
297
   * Resume from sleep mode.
255
   */
298
   */
256
  virtual void ResumeFromSleep (void) = 0;
299
  virtual void ResumeFromSleep (void);
257
300
258
  /**
301
  /**
259
   * \return true of the current state of the PHY layer is WifiPhy::IDLE, false otherwise.
302
   * \return true of the current state of the PHY layer is WifiPhy::IDLE, false otherwise.
 Lines 1490-1527    Link Here 
1490
   * \return a vector containing the supported channel widths, values in MHz
1533
   * \return a vector containing the supported channel widths, values in MHz
1491
   */
1534
   */
1492
  virtual std::vector<uint32_t> GetSupportedChannelWidthSet (void) const;
1535
  virtual std::vector<uint32_t> GetSupportedChannelWidthSet (void) const;
1493
  /**
1536
1494
   * Convert from dBm to Watts.
1495
   *
1496
   * \param dbm the power in dBm
1497
   *
1498
   * \return the equivalent Watts for the given dBm
1499
   */
1500
  double DbmToW (double dbm) const;
1501
  /**
1502
   * Convert from dB to ratio.
1503
   *
1504
   * \param db
1505
   *
1506
   * \return ratio
1507
   */
1508
  double DbToRatio (double db) const;
1509
  /**
1510
   * Convert from Watts to dBm.
1511
   *
1512
   * \param w the power in Watts
1513
   *
1514
   * \return the equivalent dBm for the given Watts
1515
   */
1516
  double WToDbm (double w) const;
1517
  /**
1518
   * Convert from ratio to dB.
1519
   *
1520
   * \param ratio
1521
   *
1522
   * \return dB
1523
   */
1524
  double RatioToDb (double ratio) const;
1525
1537
1526
protected:
1538
protected:
1527
  // Inherited
1539
  // Inherited
(-)4af746543f8d (+52 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2016
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
 * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
19
 */
20
21
#include "wifi-utils.h"
22
#include <cmath>
23
24
namespace ns3 {
25
26
double
27
DbToRatio (double dB)
28
{
29
  double ratio = std::pow (10.0, dB / 10.0);
30
  return ratio;
31
}
32
33
double
34
DbmToW (double dBm)
35
{
36
  double mW = std::pow (10.0, dBm / 10.0);
37
  return mW / 1000.0;
38
}
39
40
double
41
WToDbm (double w)
42
{
43
  return 10.0 * std::log10 (w * 1000.0);
44
}
45
46
double
47
RatioToDb (double ratio)
48
{
49
  return 10.0 * std::log10 (ratio);
50
}
51
52
} //namespace ns3
(-)4af746543f8d (+61 lines)
Added Link Here 
1
/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2016
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
 * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
19
 */
20
21
#ifndef WIFI_UTILS_H
22
#define WIFI_UTILS_H
23
24
namespace ns3 {
25
26
  /**
27
   * Convert from dBm to Watts.
28
   *
29
   * \param dbm the power in dBm
30
   *
31
   * \return the equivalent Watts for the given dBm
32
   */
33
  double DbmToW (double dbm);
34
  /**
35
   * Convert from dB to ratio.
36
   *
37
   * \param db
38
   *
39
   * \return ratio
40
   */
41
  double DbToRatio (double db);
42
  /**
43
   * Convert from Watts to dBm.
44
   *
45
   * \param w the power in Watts
46
   *
47
   * \return the equivalent dBm for the given Watts
48
   */
49
  double WToDbm (double w);
50
  /**
51
   * Convert from ratio to dB.
52
   *
53
   * \param ratio
54
   *
55
   * \return dB
56
   */
57
  double RatioToDb (double ratio);
58
59
} // namespace ns3
60
61
#endif /* WIFI_UTILS_H */
(-)a/src/wifi/model/yans-wifi-channel.cc (-1 / +2 lines)
 Lines 29-34    Link Here 
29
#include "yans-wifi-channel.h"
29
#include "yans-wifi-channel.h"
30
#include "ns3/propagation-loss-model.h"
30
#include "ns3/propagation-loss-model.h"
31
#include "ns3/propagation-delay-model.h"
31
#include "ns3/propagation-delay-model.h"
32
#include "wifi-utils.h"
32
33
33
namespace ns3 {
34
namespace ns3 {
34
35
 Lines 120-126    Link Here 
120
void
121
void
121
YansWifiChannel::Receive (uint32_t i, Ptr<Packet> packet, double rxPowerDbm, Time duration) const
122
YansWifiChannel::Receive (uint32_t i, Ptr<Packet> packet, double rxPowerDbm, Time duration) const
122
{
123
{
123
  m_phyList[i]->StartReceivePreambleAndHeader (packet, rxPowerDbm, duration);
124
  m_phyList[i]->StartReceivePreambleAndHeader (packet, DbmToW (rxPowerDbm + m_phyList[i]->GetRxGain ()), duration);
124
}
125
}
125
126
126
uint32_t
127
uint32_t
(-)a/src/wifi/model/yans-wifi-phy.cc (-498 / +4 lines)
 Lines 28-36    Link Here 
28
#include "ns3/assert.h"
28
#include "ns3/assert.h"
29
#include "ns3/log.h"
29
#include "ns3/log.h"
30
#include "ns3/double.h"
30
#include "ns3/double.h"
31
#include "ampdu-tag.h"
31
#include "wifi-utils.h"
32
#include "wifi-phy-tag.h"
33
#include <cmath>
34
32
35
namespace ns3 {
33
namespace ns3 {
36
34
 Lines 66-175    Link Here 
66
  m_channel = 0;
64
  m_channel = 0;
67
}
65
}
68
66
69
bool
70
YansWifiPhy::DoChannelSwitch (uint16_t nch)
71
{
72
  if (!IsInitialized ())
73
    {
74
      //this is not channel switch, this is initialization
75
      NS_LOG_DEBUG ("initialize to channel " << nch);
76
      return true;
77
    }
78
79
  NS_ASSERT (!IsStateSwitching ());
80
  switch (m_state->GetState ())
81
    {
82
    case YansWifiPhy::RX:
83
      NS_LOG_DEBUG ("drop packet because of channel switching while reception");
84
      m_endPlcpRxEvent.Cancel ();
85
      m_endRxEvent.Cancel ();
86
      goto switchChannel;
87
      break;
88
    case YansWifiPhy::TX:
89
      NS_LOG_DEBUG ("channel switching postponed until end of current transmission");
90
      Simulator::Schedule (GetDelayUntilIdle (), &WifiPhy::SetChannelNumber, this, nch);
91
      break;
92
    case YansWifiPhy::CCA_BUSY:
93
    case YansWifiPhy::IDLE:
94
      goto switchChannel;
95
      break;
96
    case YansWifiPhy::SLEEP:
97
      NS_LOG_DEBUG ("channel switching ignored in sleep mode");
98
      break;
99
    default:
100
      NS_ASSERT (false);
101
      break;
102
    }
103
104
  return false;
105
106
switchChannel:
107
108
  NS_LOG_DEBUG ("switching channel " << GetChannelNumber () << " -> " << nch);
109
  m_state->SwitchToChannelSwitching (GetChannelSwitchDelay ());
110
  m_interference.EraseEvents ();
111
  /*
112
   * Needed here to be able to correctly sensed the medium for the first
113
   * time after the switching. The actual switching is not performed until
114
   * after m_channelSwitchDelay. Packets received during the switching
115
   * state are added to the event list and are employed later to figure
116
   * out the state of the medium after the switching.
117
   */
118
  return true;
119
}
120
121
bool
122
YansWifiPhy::DoFrequencySwitch (uint32_t frequency)
123
{
124
  if (!IsInitialized ())
125
    {
126
      //this is not channel switch, this is initialization
127
      NS_LOG_DEBUG ("start at frequency " << frequency);
128
      return true;
129
    }
130
131
  NS_ASSERT (!IsStateSwitching ());
132
  switch (m_state->GetState ())
133
    {
134
    case YansWifiPhy::RX:
135
      NS_LOG_DEBUG ("drop packet because of channel/frequency switching while reception");
136
      m_endPlcpRxEvent.Cancel ();
137
      m_endRxEvent.Cancel ();
138
      goto switchFrequency;
139
      break;
140
    case YansWifiPhy::TX:
141
      NS_LOG_DEBUG ("channel/frequency switching postponed until end of current transmission");
142
      Simulator::Schedule (GetDelayUntilIdle (), &WifiPhy::SetFrequency, this, frequency);
143
      break;
144
    case YansWifiPhy::CCA_BUSY:
145
    case YansWifiPhy::IDLE:
146
      goto switchFrequency;
147
      break;
148
    case YansWifiPhy::SLEEP:
149
      NS_LOG_DEBUG ("frequency switching ignored in sleep mode");
150
      break;
151
    default:
152
      NS_ASSERT (false);
153
      break;
154
    }
155
156
  return false;
157
158
switchFrequency:
159
160
  NS_LOG_DEBUG ("switching frequency " << GetFrequency () << " -> " << frequency);
161
  m_state->SwitchToChannelSwitching (GetChannelSwitchDelay ());
162
  m_interference.EraseEvents ();
163
  /*
164
   * Needed here to be able to correctly sensed the medium for the first
165
   * time after the switching. The actual switching is not performed until
166
   * after m_channelSwitchDelay. Packets received during the switching
167
   * state are added to the event list and are employed later to figure
168
   * out the state of the medium after the switching.
169
   */
170
  return true;
171
}
172
173
Ptr<WifiChannel>
67
Ptr<WifiChannel>
174
YansWifiPhy::GetChannel (void) const
68
YansWifiPhy::GetChannel (void) const
175
{
69
{
 Lines 184-581    Link Here 
184
}
78
}
185
79
186
void
80
void
187
YansWifiPhy::SetSleepMode (void)
81
YansWifiPhy::StartTx (Ptr<Packet> packet, WifiTxVector txVector, Time txDuration)
188
{
189
  NS_LOG_FUNCTION (this);
190
  switch (m_state->GetState ())
191
    {
192
    case YansWifiPhy::TX:
193
      NS_LOG_DEBUG ("setting sleep mode postponed until end of current transmission");
194
      Simulator::Schedule (GetDelayUntilIdle (), &YansWifiPhy::SetSleepMode, this);
195
      break;
196
    case YansWifiPhy::RX:
197
      NS_LOG_DEBUG ("setting sleep mode postponed until end of current reception");
198
      Simulator::Schedule (GetDelayUntilIdle (), &YansWifiPhy::SetSleepMode, this);
199
      break;
200
    case YansWifiPhy::SWITCHING:
201
      NS_LOG_DEBUG ("setting sleep mode postponed until end of channel switching");
202
      Simulator::Schedule (GetDelayUntilIdle (), &YansWifiPhy::SetSleepMode, this);
203
      break;
204
    case YansWifiPhy::CCA_BUSY:
205
    case YansWifiPhy::IDLE:
206
      NS_LOG_DEBUG ("setting sleep mode");
207
      m_state->SwitchToSleep ();
208
      break;
209
    case YansWifiPhy::SLEEP:
210
      NS_LOG_DEBUG ("already in sleep mode");
211
      break;
212
    default:
213
      NS_ASSERT (false);
214
      break;
215
    }
216
}
217
218
void
219
YansWifiPhy::ResumeFromSleep (void)
220
{
221
  NS_LOG_FUNCTION (this);
222
  switch (m_state->GetState ())
223
    {
224
    case YansWifiPhy::TX:
225
    case YansWifiPhy::RX:
226
    case YansWifiPhy::IDLE:
227
    case YansWifiPhy::CCA_BUSY:
228
    case YansWifiPhy::SWITCHING:
229
      {
230
        NS_LOG_DEBUG ("not in sleep mode, there is nothing to resume");
231
        break;
232
      }
233
    case YansWifiPhy::SLEEP:
234
      {
235
        NS_LOG_DEBUG ("resuming from sleep mode");
236
        Time delayUntilCcaEnd = m_interference.GetEnergyDuration (DbmToW (GetCcaMode1Threshold ()));
237
        m_state->SwitchFromSleep (delayUntilCcaEnd);
238
        break;
239
      }
240
    default:
241
      {
242
        NS_ASSERT (false);
243
        break;
244
      }
245
    }
246
}
247
248
void
249
YansWifiPhy::SetReceiveOkCallback (RxOkCallback callback)
250
{
251
  m_state->SetReceiveOkCallback (callback);
252
}
253
254
void
255
YansWifiPhy::SetReceiveErrorCallback (RxErrorCallback callback)
256
{
257
  m_state->SetReceiveErrorCallback (callback);
258
}
259
260
void
261
YansWifiPhy::StartReceivePreambleAndHeader (Ptr<Packet> packet, double rxPowerDbm, Time rxDuration)
262
{
82
{
263
  //This function should be later split to check separately whether plcp preamble and plcp header can be successfully received.
83
  NS_LOG_DEBUG ("Start transmission: signal power before antenna gain=" << GetPowerDbm (txVector.GetTxPowerLevel ()) << "dBm");
264
  //Note: plcp preamble reception is not yet modeled.
84
  m_channel->Send (this, packet, GetPowerDbm (txVector.GetTxPowerLevel ()) + GetTxGain (), txDuration);
265
  NS_LOG_FUNCTION (this << packet << rxPowerDbm << rxDuration);
266
  AmpduTag ampduTag;
267
  rxPowerDbm += GetRxGain ();
268
  double rxPowerW = DbmToW (rxPowerDbm);
269
  Time endRx = Simulator::Now () + rxDuration;
270
  
271
  WifiPhyTag tag;
272
  packet->RemovePacketTag (tag);
273
  WifiTxVector txVector = tag.GetWifiTxVector ();
274
  
275
  if (txVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HT
276
      && (txVector.GetNss () != (1 + (txVector.GetMode ().GetMcsValue () / 8))))
277
    {
278
      NS_FATAL_ERROR ("MCS value does not match NSS value: MCS = " << (uint16_t)txVector.GetMode ().GetMcsValue () << ", NSS = " << (uint16_t)txVector.GetNss ());
279
    }
280
  
281
  if (txVector.GetNss () > GetMaxSupportedRxSpatialStreams ())
282
    {
283
      NS_FATAL_ERROR ("Reception ends in failure because of an unsupported number of spatial streams");
284
    }
285
286
  WifiPreamble preamble = txVector.GetPreambleType ();
287
  MpduType mpdutype = tag.GetMpduType ();
288
  Time preambleAndHeaderDuration = CalculatePlcpPreambleAndHeaderDuration (txVector);
289
290
  Ptr<InterferenceHelper::Event> event;
291
  event = m_interference.Add (packet->GetSize (),
292
                              txVector,
293
                              rxDuration,
294
                              rxPowerW);
295
296
  switch (m_state->GetState ())
297
    {
298
    case YansWifiPhy::SWITCHING:
299
      NS_LOG_DEBUG ("drop packet because of channel switching");
300
      NotifyRxDrop (packet);
301
      m_plcpSuccess = false;
302
      /*
303
       * Packets received on the upcoming channel are added to the event list
304
       * during the switching state. This way the medium can be correctly sensed
305
       * when the device listens to the channel for the first time after the
306
       * switching e.g. after channel switching, the channel may be sensed as
307
       * busy due to other devices' tramissions started before the end of
308
       * the switching.
309
       */
310
      if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
311
        {
312
          //that packet will be noise _after_ the completion of the
313
          //channel switching.
314
          goto maybeCcaBusy;
315
        }
316
      break;
317
    case YansWifiPhy::RX:
318
      NS_LOG_DEBUG ("drop packet because already in Rx (power=" <<
319
                    rxPowerW << "W)");
320
      NotifyRxDrop (packet);
321
      if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
322
        {
323
          //that packet will be noise _after_ the reception of the
324
          //currently-received packet.
325
          goto maybeCcaBusy;
326
        }
327
      break;
328
    case YansWifiPhy::TX:
329
      NS_LOG_DEBUG ("drop packet because already in Tx (power=" <<
330
                    rxPowerW << "W)");
331
      NotifyRxDrop (packet);
332
      if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
333
        {
334
          //that packet will be noise _after_ the transmission of the
335
          //currently-transmitted packet.
336
          goto maybeCcaBusy;
337
        }
338
      break;
339
    case YansWifiPhy::CCA_BUSY:
340
    case YansWifiPhy::IDLE:
341
      if (rxPowerW > GetEdThresholdW ()) //checked here, no need to check in the payload reception (current implementation assumes constant rx power over the packet duration)
342
        {
343
          if (preamble == WIFI_PREAMBLE_NONE && (m_mpdusNum == 0 || m_plcpSuccess == false))
344
            {
345
              m_plcpSuccess = false;
346
              m_mpdusNum = 0;
347
              NS_LOG_DEBUG ("drop packet because no PLCP preamble/header has been received");
348
              NotifyRxDrop (packet);
349
              goto maybeCcaBusy;
350
            }
351
          else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum == 0)
352
            {
353
              //received the first MPDU in an MPDU
354
              m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
355
              m_rxMpduReferenceNumber++;
356
            }
357
          else if (preamble == WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0)
358
            {
359
              //received the other MPDUs that are part of the A-MPDU
360
              if (ampduTag.GetRemainingNbOfMpdus () < (m_mpdusNum - 1))
361
                {
362
                  NS_LOG_DEBUG ("Missing MPDU from the A-MPDU " << m_mpdusNum - ampduTag.GetRemainingNbOfMpdus ());
363
                  m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
364
                }
365
              else
366
                {
367
                  m_mpdusNum--;
368
                }
369
            }
370
          else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0)
371
            {
372
              NS_LOG_DEBUG ("New A-MPDU started while " << m_mpdusNum << " MPDUs from previous are lost");
373
              m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
374
            }
375
          else if (preamble != WIFI_PREAMBLE_NONE && m_mpdusNum > 0 )
376
            {
377
              NS_LOG_DEBUG ("Didn't receive the last MPDUs from an A-MPDU " << m_mpdusNum);
378
              m_mpdusNum = 0;
379
            }
380
381
          NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)");
382
          //sync to signal
383
          m_state->SwitchToRx (rxDuration);
384
          NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
385
          NotifyRxBegin (packet);
386
          m_interference.NotifyRxStart ();
387
388
          if (preamble != WIFI_PREAMBLE_NONE)
389
            {
390
              NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
391
              m_endPlcpRxEvent = Simulator::Schedule (preambleAndHeaderDuration, &YansWifiPhy::StartReceivePacket, this,
392
                                                      packet, txVector, mpdutype, event);
393
            }
394
395
          NS_ASSERT (m_endRxEvent.IsExpired ());
396
          m_endRxEvent = Simulator::Schedule (rxDuration, &YansWifiPhy::EndReceive, this,
397
                                              packet, preamble, mpdutype, event);
398
        }
399
      else
400
        {
401
          NS_LOG_DEBUG ("drop packet because signal power too Small (" <<
402
                        rxPowerW << "<" << GetEdThresholdW () << ")");
403
          NotifyRxDrop (packet);
404
          m_plcpSuccess = false;
405
          goto maybeCcaBusy;
406
        }
407
      break;
408
    case YansWifiPhy::SLEEP:
409
      NS_LOG_DEBUG ("drop packet because in sleep mode");
410
      NotifyRxDrop (packet);
411
      m_plcpSuccess = false;
412
      break;
413
    }
414
415
  return;
416
417
maybeCcaBusy:
418
  //We are here because we have received the first bit of a packet and we are
419
  //not going to be able to synchronize on it
420
  //In this model, CCA becomes busy when the aggregation of all signals as
421
  //tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
422
423
  Time delayUntilCcaEnd = m_interference.GetEnergyDuration (DbmToW (GetCcaMode1Threshold ()));
424
  if (!delayUntilCcaEnd.IsZero ())
425
    {
426
      m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
427
    }
428
}
429
430
void
431
YansWifiPhy::StartReceivePacket (Ptr<Packet> packet,
432
                                 WifiTxVector txVector,
433
                                 MpduType mpdutype,
434
                                 Ptr<InterferenceHelper::Event> event)
435
{
436
  NS_LOG_FUNCTION (this << packet << txVector.GetMode () << txVector.GetPreambleType () << (uint32_t)mpdutype);
437
  NS_ASSERT (IsStateRx ());
438
  NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
439
  WifiMode txMode = txVector.GetMode ();
440
441
  InterferenceHelper::SnrPer snrPer;
442
  snrPer = m_interference.CalculatePlcpHeaderSnrPer (event);
443
444
  NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per);
445
446
  if (m_random->GetValue () > snrPer.per) //plcp reception succeeded
447
    {
448
      if (IsModeSupported (txMode) || IsMcsSupported (txMode))
449
        {
450
          NS_LOG_DEBUG ("receiving plcp payload"); //endReceive is already scheduled
451
          m_plcpSuccess = true;
452
        }
453
      else //mode is not allowed
454
        {
455
          NS_LOG_DEBUG ("drop packet because it was sent using an unsupported mode (" << txMode << ")");
456
          NotifyRxDrop (packet);
457
          m_plcpSuccess = false;
458
        }
459
    }
460
  else //plcp reception failed
461
    {
462
      NS_LOG_DEBUG ("drop packet because plcp preamble/header reception failed");
463
      NotifyRxDrop (packet);
464
      m_plcpSuccess = false;
465
    }
466
}
467
468
void
469
YansWifiPhy::SendPacket (Ptr<const Packet> packet, WifiTxVector txVector, MpduType mpdutype)
470
{
471
  NS_LOG_FUNCTION (this << packet << txVector.GetMode () 
472
    << txVector.GetMode ().GetDataRate (txVector) << txVector.GetPreambleType ()
473
    << (uint32_t)txVector.GetTxPowerLevel () << (uint32_t)mpdutype);
474
  /* Transmission can happen if:
475
   *  - we are syncing on a packet. It is the responsability of the
476
   *    MAC layer to avoid doing this but the PHY does nothing to
477
   *    prevent it.
478
   *  - we are idle
479
   */
480
  NS_ASSERT (!m_state->IsStateTx () && !m_state->IsStateSwitching ());
481
  
482
  if (txVector.GetNss () > GetMaxSupportedTxSpatialStreams ())
483
    {
484
      NS_FATAL_ERROR ("Unsupported number of spatial streams!");
485
    }
486
487
  if (m_state->IsStateSleep ())
488
    {
489
      NS_LOG_DEBUG ("Dropping packet because in sleep mode");
490
      NotifyTxDrop (packet);
491
      return;
492
    }
493
494
  Time txDuration = CalculateTxDuration (packet->GetSize (), txVector, GetFrequency (), mpdutype, 1);
495
  NS_ASSERT (txDuration > NanoSeconds (0));
496
497
  if (m_state->IsStateRx ())
498
    {
499
      m_endPlcpRxEvent.Cancel ();
500
      m_endRxEvent.Cancel ();
501
      m_interference.NotifyRxEnd ();
502
    }
503
  NotifyTxBegin (packet);
504
  if ((mpdutype == MPDU_IN_AGGREGATE) && (txVector.GetPreambleType () != WIFI_PREAMBLE_NONE))
505
    {
506
      //send the first MPDU in an MPDU
507
      m_txMpduReferenceNumber++;
508
    }
509
  MpduInfo aMpdu;
510
  aMpdu.type = mpdutype;
511
  aMpdu.mpduRefNumber = m_txMpduReferenceNumber;
512
  NotifyMonitorSniffTx (packet, (uint16_t)GetFrequency (), GetChannelNumber (), txVector, aMpdu);
513
  m_state->SwitchToTx (txDuration, packet, GetPowerDbm (txVector.GetTxPowerLevel ()), txVector);
514
  
515
  Ptr<Packet> newPacket = packet->Copy (); // obtain non-const Packet
516
  WifiPhyTag oldtag;
517
  newPacket->RemovePacketTag (oldtag);
518
  WifiPhyTag tag (txVector, mpdutype);
519
  newPacket->AddPacketTag (tag);
520
  m_channel->Send (this, newPacket, GetPowerDbm (txVector.GetTxPowerLevel ()) + GetTxGain (), txDuration);
521
}
522
523
void
524
YansWifiPhy::RegisterListener (WifiPhyListener *listener)
525
{
526
  m_state->RegisterListener (listener);
527
}
528
529
void
530
YansWifiPhy::UnregisterListener (WifiPhyListener *listener)
531
{
532
  m_state->UnregisterListener (listener);
533
}
534
535
void
536
YansWifiPhy::EndReceive (Ptr<Packet> packet, WifiPreamble preamble, MpduType mpdutype, Ptr<InterferenceHelper::Event> event)
537
{
538
  NS_LOG_FUNCTION (this << packet << event);
539
  NS_ASSERT (IsStateRx ());
540
  NS_ASSERT (event->GetEndTime () == Simulator::Now ());
541
542
  InterferenceHelper::SnrPer snrPer;
543
  snrPer = m_interference.CalculatePlcpPayloadSnrPer (event);
544
  m_interference.NotifyRxEnd ();
545
546
  if (m_plcpSuccess == true)
547
    {
548
      NS_LOG_DEBUG ("mode=" << (event->GetPayloadMode ().GetDataRate (event->GetTxVector ())) <<
549
                    ", snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per << ", size=" << packet->GetSize ());
550
551
      if (m_random->GetValue () > snrPer.per)
552
        {
553
          NotifyRxEnd (packet);
554
          SignalNoiseDbm signalNoise;
555
          signalNoise.signal = RatioToDb (event->GetRxPowerW ()) + 30;
556
          signalNoise.noise = RatioToDb (event->GetRxPowerW () / snrPer.snr) - GetRxNoiseFigure () + 30;
557
          MpduInfo aMpdu;
558
          aMpdu.type = mpdutype;
559
          aMpdu.mpduRefNumber = m_rxMpduReferenceNumber;
560
          NotifyMonitorSniffRx (packet, (uint16_t)GetFrequency (), GetChannelNumber (), event->GetTxVector (), aMpdu, signalNoise);
561
          m_state->SwitchFromRxEndOk (packet, snrPer.snr, event->GetTxVector ());
562
        }
563
      else
564
        {
565
          /* failure. */
566
          NotifyRxDrop (packet);
567
          m_state->SwitchFromRxEndError (packet, snrPer.snr);
568
        }
569
    }
570
  else
571
    {
572
      m_state->SwitchFromRxEndError (packet, snrPer.snr);
573
    }
574
575
  if (preamble == WIFI_PREAMBLE_NONE && mpdutype == LAST_MPDU_IN_AGGREGATE)
576
    {
577
      m_plcpSuccess = false;
578
    }
579
}
85
}
580
86
581
} //namespace ns3
87
} //namespace ns3
(-)a/src/wifi/model/yans-wifi-phy.h (-39 / +8 lines)
 Lines 60-113    Link Here 
60
  void SetChannel (Ptr<YansWifiChannel> channel);
60
  void SetChannel (Ptr<YansWifiChannel> channel);
61
61
62
  /**
62
  /**
63
   * Starting receiving the plcp of a packet (i.e. the first bit of the preamble has arrived).
63
   * \param packet the packet to send
64
   *
64
   * \param txVector the TXVECTOR that has tx parameters such as mode, the transmission mode to use to send
65
   * \param packet the arriving packet
65
   *        this packet, and txPowerLevel, a power level to use to send this packet. The real transmission
66
   * \param rxPowerDbm the receive power in dBm
66
   *        power is calculated as txPowerMin + txPowerLevel * (txPowerMax - txPowerMin) / nTxLevels
67
   * \param rxDuration the duration needed for the reception of the packet
67
   * \param txDuration duration of the transmission.
68
   */
68
   */
69
  void StartReceivePreambleAndHeader (Ptr<Packet> packet,
69
  void StartTx (Ptr<Packet> packet, WifiTxVector txVector, Time txDuration);
70
                                      double rxPowerDbm,
71
                                      Time rxDuration);
72
  /**
73
   * Starting receiving the payload of a packet (i.e. the first bit of the packet has arrived).
74
   *
75
   * \param packet the arriving packet
76
   * \param txVector the TXVECTOR of the arriving packet
77
   * \param mpdutype the type of the MPDU as defined in WifiPhy::MpduType.
78
   * \param event the corresponding event of the first time the packet arrives
79
   */
80
  void StartReceivePacket (Ptr<Packet> packet,
81
                           WifiTxVector txVector,
82
                           MpduType mpdutype,
83
                           Ptr<InterferenceHelper::Event> event);
84
70
85
  virtual void SetReceiveOkCallback (WifiPhy::RxOkCallback callback);
86
  virtual void SetReceiveErrorCallback (WifiPhy::RxErrorCallback callback);
87
  virtual void SendPacket (Ptr<const Packet> packet, WifiTxVector txVector, MpduType mpdutype = NORMAL_MPDU);
88
  virtual void RegisterListener (WifiPhyListener *listener);
89
  virtual void UnregisterListener (WifiPhyListener *listener);
90
  virtual void SetSleepMode (void);
91
  virtual void ResumeFromSleep (void);
92
  virtual Ptr<WifiChannel> GetChannel (void) const;
71
  virtual Ptr<WifiChannel> GetChannel (void) const;
93
72
73
94
protected:
74
protected:
95
  // Inherited
75
  // Inherited
96
  virtual void DoDispose (void);
76
  virtual void DoDispose (void);
97
  virtual bool DoChannelSwitch (uint16_t id);
77
98
  virtual bool DoFrequencySwitch (uint32_t frequency);
99
78
100
private:
79
private:
101
  /**
102
   * The last bit of the packet has arrived.
103
   *
104
   * \param packet the packet that the last bit has arrived
105
   * \param preamble the preamble of the arriving packet
106
   * \param mpdutype the type of the MPDU as defined in WifiPhy::MpduType.
107
   * \param event the corresponding event of the first time the packet arrives
108
   */
109
  void EndReceive (Ptr<Packet> packet, WifiPreamble preamble, MpduType mpdutype, Ptr<InterferenceHelper::Event> event);
110
111
  Ptr<YansWifiChannel> m_channel; //!< YansWifiChannel that this YansWifiPhy is connected to
80
  Ptr<YansWifiChannel> m_channel; //!< YansWifiChannel that this YansWifiPhy is connected to
112
};
81
};
113
82
(-)a/src/wifi/test/spectrum-wifi-phy-test.cc (-3 / +11 lines)
 Lines 48-54    Link Here 
48
  Ptr<SpectrumWifiPhy> m_phy;
48
  Ptr<SpectrumWifiPhy> m_phy;
49
  Ptr<SpectrumSignalParameters> MakeSignal (double txPowerWatts);
49
  Ptr<SpectrumSignalParameters> MakeSignal (double txPowerWatts);
50
  void SendSignal (double txPowerWatts);
50
  void SendSignal (double txPowerWatts);
51
  void SpectrumWifiPhyReceiver (bool rxSucceeded);
51
  void SpectrumWifiPhyRxSuccess (Ptr<Packet> p, double snr, WifiTxVector txVector);
52
  void SpectrumWifiPhyRxFailure (Ptr<Packet> p, double snr);
52
  uint32_t m_count;
53
  uint32_t m_count;
53
private:
54
private:
54
  virtual void DoRun (void);
55
  virtual void DoRun (void);
 Lines 104-110    Link Here 
104
}
105
}
105
106
106
void
107
void
107
SpectrumWifiPhyBasicTest::SpectrumWifiPhyReceiver (bool rxSucceeded)
108
SpectrumWifiPhyBasicTest::SpectrumWifiPhyRxSuccess (Ptr<Packet> p, double snr, WifiTxVector txVector)
109
{
110
  m_count++;
111
}
112
113
void
114
SpectrumWifiPhyBasicTest::SpectrumWifiPhyRxFailure (Ptr<Packet> p, double snr)
108
{
115
{
109
  m_count++;
116
  m_count++;
110
}
117
}
 Lines 124-130    Link Here 
124
  m_phy->SetErrorRateModel (error);
131
  m_phy->SetErrorRateModel (error);
125
  m_phy->SetChannelNumber (CHANNEL_NUMBER);
132
  m_phy->SetChannelNumber (CHANNEL_NUMBER);
126
  m_phy->SetFrequency (FREQUENCY);
133
  m_phy->SetFrequency (FREQUENCY);
127
  m_phy->SetPacketReceivedCallback (MakeCallback (&SpectrumWifiPhyBasicTest::SpectrumWifiPhyReceiver, this));
134
  m_phy->SetReceiveOkCallback (MakeCallback (&SpectrumWifiPhyBasicTest::SpectrumWifiPhyRxSuccess, this));
135
  m_phy->SetReceiveErrorCallback (MakeCallback (&SpectrumWifiPhyBasicTest::SpectrumWifiPhyRxFailure, this));
128
  //Bug 2460: CcaMode1Threshold default should be set to -62 dBm when using Spectrum
136
  //Bug 2460: CcaMode1Threshold default should be set to -62 dBm when using Spectrum
129
  m_phy->SetCcaMode1Threshold (-62.0);
137
  m_phy->SetCcaMode1Threshold (-62.0);
130
}
138
}
(-)a/src/wifi/wscript (+2 lines)
 Lines 3-8    Link Here 
3
def build(bld):
3
def build(bld):
4
    obj = bld.create_ns3_module('wifi', ['network', 'propagation', 'energy', 'spectrum', 'antenna', 'mobility'])
4
    obj = bld.create_ns3_module('wifi', ['network', 'propagation', 'energy', 'spectrum', 'antenna', 'mobility'])
5
    obj.source = [
5
    obj.source = [
6
        'model/wifi-utils.cc',
6
        'model/wifi-information-element.cc',
7
        'model/wifi-information-element.cc',
7
        'model/wifi-information-element-vector.cc',
8
        'model/wifi-information-element-vector.cc',
8
        'model/wifi-channel.cc',
9
        'model/wifi-channel.cc',
 Lines 107-112    Link Here 
107
    headers = bld(features='ns3header')
108
    headers = bld(features='ns3header')
108
    headers.module = 'wifi'
109
    headers.module = 'wifi'
109
    headers.source = [
110
    headers.source = [
111
        'model/wifi-utils.h',
110
        'model/wifi-information-element.h',
112
        'model/wifi-information-element.h',
111
        'model/wifi-information-element-vector.h',
113
        'model/wifi-information-element-vector.h',
112
        'model/wifi-net-device.h',
114
        'model/wifi-net-device.h',

Return to bug 2552