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

(-)a/src/wifi/examples/test-interference-helper.cc (-5 / +18 lines)
 Lines 71-82    Link Here 
71
    double xB; ///< x B
71
    double xB; ///< x B
72
    std::string txModeA; ///< transmit mode A
72
    std::string txModeA; ///< transmit mode A
73
    std::string txModeB; ///< transmit mode B
73
    std::string txModeB; ///< transmit mode B
74
    uint32_t txPowerLevelA; ///< transmit power level A
74
    double txPowerLevelA; ///< transmit power level A
75
    uint32_t txPowerLevelB; ///< transmit power level B
75
    double txPowerLevelB; ///< transmit power level B
76
    uint32_t packetSizeA; ///< packet size A
76
    uint32_t packetSizeA; ///< packet size A
77
    uint32_t packetSizeB; ///< packet size B
77
    uint32_t packetSizeB; ///< packet size B
78
    WifiPhyStandard standard; ///< standard
78
    WifiPhyStandard standard; ///< standard
79
    WifiPreamble preamble; ///< preamble
79
    WifiPreamble preamble; ///< preamble
80
    bool captureEnabled; ///< whether physical layer capture is enabled
81
    double captureMargin; ///< margin used for physical layer capture
80
  };
82
  };
81
83
82
  InterferenceExperiment ();
84
  InterferenceExperiment ();
 Lines 127-138    Link Here 
127
    xB (5),
129
    xB (5),
128
    txModeA ("OfdmRate54Mbps"),
130
    txModeA ("OfdmRate54Mbps"),
129
    txModeB ("OfdmRate54Mbps"),
131
    txModeB ("OfdmRate54Mbps"),
130
    txPowerLevelA (0),
132
    txPowerLevelA (16.0206),
131
    txPowerLevelB (0),
133
    txPowerLevelB (16.0206),
132
    packetSizeA (1500),
134
    packetSizeA (1500),
133
    packetSizeB (1500),
135
    packetSizeB (1500),
134
    standard (WIFI_PHY_STANDARD_80211a),
136
    standard (WIFI_PHY_STANDARD_80211a),
135
    preamble (WIFI_PREAMBLE_LONG)
137
    preamble (WIFI_PREAMBLE_LONG),
138
    captureEnabled (false),
139
    captureMargin (0)
136
{
140
{
137
}
141
}
138
142
 Lines 157-164    Link Here 
157
  posRx->SetPosition (Vector (0.0, 0.0, 0.0));
161
  posRx->SetPosition (Vector (0.0, 0.0, 0.0));
158
162
159
  m_txA = CreateObject<YansWifiPhy> ();
163
  m_txA = CreateObject<YansWifiPhy> ();
164
  m_txA->SetTxPowerStart (input.txPowerLevelA);
165
  m_txA->SetTxPowerEnd (input.txPowerLevelA);
160
  m_txB = CreateObject<YansWifiPhy> ();
166
  m_txB = CreateObject<YansWifiPhy> ();
167
  m_txB->SetTxPowerStart (input.txPowerLevelB);
168
  m_txB->SetTxPowerEnd (input.txPowerLevelB);
161
  Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> ();
169
  Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> ();
170
  rx->SetPhysicalLayerCaptureEnabled (input.captureEnabled);
171
  rx->SetPhysicalLayerCaptureMargin (input.captureMargin);
162
172
163
  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
173
  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
164
  m_txA->SetErrorRateModel (error);
174
  m_txA->SetErrorRateModel (error);
 Lines 202-209    Link Here 
202
  cmd.AddValue ("txModeB", "Wifi mode used for payload transmission of sender B", input.txModeB);
212
  cmd.AddValue ("txModeB", "Wifi mode used for payload transmission of sender B", input.txModeB);
203
  cmd.AddValue ("standard", "IEEE 802.11 flavor", str_standard);
213
  cmd.AddValue ("standard", "IEEE 802.11 flavor", str_standard);
204
  cmd.AddValue ("preamble", "Type of preamble", str_preamble);
214
  cmd.AddValue ("preamble", "Type of preamble", str_preamble);
215
  cmd.AddValue ("enableCapture", "Enable/disable physical layer capture", input.captureEnabled);
216
  cmd.AddValue ("captureMargin", "Margin used for physical layer capture", input.captureMargin);
205
  cmd.Parse (argc, argv);
217
  cmd.Parse (argc, argv);
206
218
219
  LogComponentEnable ("WifiPhy", LOG_LEVEL_ALL);
207
  LogComponentEnable ("YansWifiPhy", LOG_LEVEL_ALL);
220
  LogComponentEnable ("YansWifiPhy", LOG_LEVEL_ALL);
208
  LogComponentEnable ("InterferenceHelper", LOG_LEVEL_ALL);
221
  LogComponentEnable ("InterferenceHelper", LOG_LEVEL_ALL);
209
222
(-)a/src/wifi/model/interference-helper.cc (-11 / +42 lines)
 Lines 94-102    Link Here 
94
 *       short period of time.
94
 *       short period of time.
95
 ****************************************************************/
95
 ****************************************************************/
96
96
97
InterferenceHelper::NiChange::NiChange (Time time, double delta)
97
InterferenceHelper::NiChange::NiChange (Time time, double delta, Ptr<InterferenceHelper::Event> event)
98
  : m_time (time),
98
  : m_time (time),
99
    m_delta (delta)
99
    m_delta (delta),
100
    m_event (event)
100
{
101
{
101
}
102
}
102
103
 Lines 112-117    Link Here 
112
  return m_delta;
113
  return m_delta;
113
}
114
}
114
115
116
Ptr<InterferenceHelper::Event>
117
InterferenceHelper::NiChange::GetEvent (void) const
118
{
119
  return m_event;
120
}
121
115
bool
122
bool
116
InterferenceHelper::NiChange::operator < (const InterferenceHelper::NiChange& o) const
123
InterferenceHelper::NiChange::operator < (const InterferenceHelper::NiChange& o) const
117
{
124
{
 Lines 221-233    Link Here 
221
          m_firstPower += i->GetDelta ();
228
          m_firstPower += i->GetDelta ();
222
        }
229
        }
223
      m_niChanges.erase (m_niChanges.begin (), nowIterator);
230
      m_niChanges.erase (m_niChanges.begin (), nowIterator);
224
      m_niChanges.insert (m_niChanges.begin (), NiChange (event->GetStartTime (), event->GetRxPowerW ()));
231
      m_niChanges.insert (m_niChanges.begin (), NiChange (event->GetStartTime (), event->GetRxPowerW (), event));
225
    }
232
    }
226
  else
233
  else
227
    {
234
    {
228
      AddNiChangeEvent (NiChange (event->GetStartTime (), event->GetRxPowerW ()));
235
      AddNiChangeEvent (NiChange (event->GetStartTime (), event->GetRxPowerW (), event));
229
    }
236
    }
230
  AddNiChangeEvent (NiChange (event->GetEndTime (), -event->GetRxPowerW ()));
237
  AddNiChangeEvent (NiChange (event->GetEndTime (), -event->GetRxPowerW (), event));
231
238
232
}
239
}
233
240
 Lines 251-267    Link Here 
251
InterferenceHelper::CalculateNoiseInterferenceW (Ptr<InterferenceHelper::Event> event, NiChanges *ni) const
258
InterferenceHelper::CalculateNoiseInterferenceW (Ptr<InterferenceHelper::Event> event, NiChanges *ni) const
252
{
259
{
253
  double noiseInterference = m_firstPower;
260
  double noiseInterference = m_firstPower;
254
  NS_ASSERT (m_rxing);
261
  NiChanges::const_iterator eventIterator = m_niChanges.begin ();
255
  for (NiChanges::const_iterator i = m_niChanges.begin () + 1; i != m_niChanges.end (); i++)
262
  while (eventIterator != m_niChanges.end ())
256
    {
263
    {
257
      if ((event->GetEndTime () == i->GetTime ()) && event->GetRxPowerW () == -i->GetDelta ())
264
      // Iterate the NI change list from the beginning to the end
265
      // until find the position of the event in the NI change list
266
      // The reason of using the event that causes the NI change to identify
267
      // different NI changes is because in some special cases
268
      // different NI changes happen at the same time with the same delta
269
      // value. Therefore, it may be impossible to identify a NI change that belongs
270
      // to which event based on just the NI time and NI delta value
271
      if (eventIterator->GetEvent () != event)
272
        {
273
          // The NI changes which happen before the event should be considered
274
          // as the interference. This considers the case that the receiving event
275
          // arrives while another receiving event is going on. The SINR of
276
          // the newly arrived event is calculated for checking the possibility of frame capture
277
          noiseInterference += eventIterator->GetDelta ();
278
        }
279
      else
280
        {
281
          break;
282
        }
283
      ++eventIterator;
284
    }
285
286
  for (NiChanges::const_iterator i = eventIterator + 1; i != m_niChanges.end (); ++i)
287
    {
288
      if (event->GetEndTime () == i->GetTime () && event == i->GetEvent ())
258
        {
289
        {
259
          break;
290
          break;
260
        }
291
        }
261
      ni->push_back (*i);
292
      ni->push_back (*i);
262
    }
293
    }
263
  ni->insert (ni->begin (), NiChange (event->GetStartTime (), noiseInterference));
294
  ni->insert (ni->begin (), NiChange (event->GetStartTime (), noiseInterference, event));
264
  ni->push_back (NiChange (event->GetEndTime (), 0));
295
  ni->push_back (NiChange (event->GetEndTime (), 0, event));
265
  return noiseInterference;
296
  return noiseInterference;
266
}
297
}
267
298
 Lines 846-852    Link Here 
846
InterferenceHelper::NiChanges::iterator
877
InterferenceHelper::NiChanges::iterator
847
InterferenceHelper::GetPosition (Time moment)
878
InterferenceHelper::GetPosition (Time moment)
848
{
879
{
849
  return std::upper_bound (m_niChanges.begin (), m_niChanges.end (), NiChange (moment, 0));
880
  return std::upper_bound (m_niChanges.begin (), m_niChanges.end (), NiChange (moment, 0, NULL));
850
}
881
}
851
882
852
void
883
void
(-)a/src/wifi/model/interference-helper.h (-1 / +10 lines)
 Lines 220-227    Link Here 
220
     *
220
     *
221
     * \param time time of the event
221
     * \param time time of the event
222
     * \param delta the power
222
     * \param delta the power
223
     * \param event causes this NI change
223
     */
224
     */
224
    NiChange (Time time, double delta);
225
    NiChange (Time time, double delta, Ptr<InterferenceHelper::Event> event);
225
    /**
226
    /**
226
     * Return the event time.
227
     * Return the event time.
227
     *
228
     *
 Lines 235-240    Link Here 
235
     */
236
     */
236
    double GetDelta (void) const;
237
    double GetDelta (void) const;
237
    /**
238
    /**
239
     * Return the event causes the corresponding NI change
240
     *
241
     * \return the event
242
     */
243
    Ptr<InterferenceHelper::Event> GetEvent (void) const;
244
    /**
238
     * Compare the event time of two NiChange objects (a < o).
245
     * Compare the event time of two NiChange objects (a < o).
239
     *
246
     *
240
     * \param o
247
     * \param o
 Lines 246-251    Link Here 
246
private:
253
private:
247
    Time m_time; ///< time
254
    Time m_time; ///< time
248
    double m_delta; ///< delta
255
    double m_delta; ///< delta
256
    Ptr<InterferenceHelper::Event> m_event;
249
  };
257
  };
250
  /**
258
  /**
251
   * typedef for a vector of NiChanges
259
   * typedef for a vector of NiChanges
 Lines 322-327    Link Here 
322
  NiChanges m_niChanges;
330
  NiChanges m_niChanges;
323
  double m_firstPower; ///< first power
331
  double m_firstPower; ///< first power
324
  bool m_rxing; ///< flag whether it is in receiving state
332
  bool m_rxing; ///< flag whether it is in receiving state
333
325
  /// Returns an iterator to the first nichange, which is later than moment
334
  /// Returns an iterator to the first nichange, which is later than moment
326
  NiChanges::iterator GetPosition (Time moment);
335
  NiChanges::iterator GetPosition (Time moment);
327
  /**
336
  /**
(-)a/src/wifi/model/wifi-phy-state-helper.cc (+29 lines)
 Lines 221-226    Link Here 
221
void
221
void
222
WifiPhyStateHelper::NotifyTxStart (Time duration, double txPowerDbm)
222
WifiPhyStateHelper::NotifyTxStart (Time duration, double txPowerDbm)
223
{
223
{
224
  NS_LOG_FUNCTION (this);
224
  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
225
  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
225
    {
226
    {
226
      (*i)->NotifyTxStart (duration, txPowerDbm);
227
      (*i)->NotifyTxStart (duration, txPowerDbm);
 Lines 230-235    Link Here 
230
void
231
void
231
WifiPhyStateHelper::NotifyRxStart (Time duration)
232
WifiPhyStateHelper::NotifyRxStart (Time duration)
232
{
233
{
234
  NS_LOG_FUNCTION (this);
233
  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
235
  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
234
    {
236
    {
235
      (*i)->NotifyRxStart (duration);
237
      (*i)->NotifyRxStart (duration);
 Lines 239-244    Link Here 
239
void
241
void
240
WifiPhyStateHelper::NotifyRxEndOk (void)
242
WifiPhyStateHelper::NotifyRxEndOk (void)
241
{
243
{
244
  NS_LOG_FUNCTION (this);
242
  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
245
  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
243
    {
246
    {
244
      (*i)->NotifyRxEndOk ();
247
      (*i)->NotifyRxEndOk ();
 Lines 248-253    Link Here 
248
void
251
void
249
WifiPhyStateHelper::NotifyRxEndError (void)
252
WifiPhyStateHelper::NotifyRxEndError (void)
250
{
253
{
254
  NS_LOG_FUNCTION (this);
251
  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
255
  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
252
    {
256
    {
253
      (*i)->NotifyRxEndError ();
257
      (*i)->NotifyRxEndError ();
 Lines 257-262    Link Here 
257
void
261
void
258
WifiPhyStateHelper::NotifyMaybeCcaBusyStart (Time duration)
262
WifiPhyStateHelper::NotifyMaybeCcaBusyStart (Time duration)
259
{
263
{
264
  NS_LOG_FUNCTION (this);
260
  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
265
  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
261
    {
266
    {
262
      (*i)->NotifyMaybeCcaBusyStart (duration);
267
      (*i)->NotifyMaybeCcaBusyStart (duration);
 Lines 266-271    Link Here 
266
void
271
void
267
WifiPhyStateHelper::NotifySwitchingStart (Time duration)
272
WifiPhyStateHelper::NotifySwitchingStart (Time duration)
268
{
273
{
274
  NS_LOG_FUNCTION (this);
269
  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
275
  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
270
    {
276
    {
271
      (*i)->NotifySwitchingStart (duration);
277
      (*i)->NotifySwitchingStart (duration);
 Lines 275-280    Link Here 
275
void
281
void
276
WifiPhyStateHelper::NotifySleep (void)
282
WifiPhyStateHelper::NotifySleep (void)
277
{
283
{
284
  NS_LOG_FUNCTION (this);
278
  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
285
  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
279
    {
286
    {
280
      (*i)->NotifySleep ();
287
      (*i)->NotifySleep ();
 Lines 284-289    Link Here 
284
void
291
void
285
WifiPhyStateHelper::NotifyWakeup (void)
292
WifiPhyStateHelper::NotifyWakeup (void)
286
{
293
{
294
  NS_LOG_FUNCTION (this);
287
  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
295
  for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
288
    {
296
    {
289
      (*i)->NotifyWakeup ();
297
      (*i)->NotifyWakeup ();
 Lines 293-298    Link Here 
293
void
301
void
294
WifiPhyStateHelper::LogPreviousIdleAndCcaBusyStates (void)
302
WifiPhyStateHelper::LogPreviousIdleAndCcaBusyStates (void)
295
{
303
{
304
  NS_LOG_FUNCTION (this);
296
  Time now = Simulator::Now ();
305
  Time now = Simulator::Now ();
297
  Time idleStart = Max (m_endCcaBusy, m_endRx);
306
  Time idleStart = Max (m_endCcaBusy, m_endRx);
298
  idleStart = Max (idleStart, m_endTx);
307
  idleStart = Max (idleStart, m_endTx);
 Lines 314-319    Link Here 
314
WifiPhyStateHelper::SwitchToTx (Time txDuration, Ptr<const Packet> packet, double txPowerDbm,
323
WifiPhyStateHelper::SwitchToTx (Time txDuration, Ptr<const Packet> packet, double txPowerDbm,
315
                                WifiTxVector txVector)
324
                                WifiTxVector txVector)
316
{
325
{
326
  NS_LOG_FUNCTION (this << txDuration << packet << txPowerDbm << txVector);
317
  m_txTrace (packet, txVector.GetMode (), txVector.GetPreambleType (), txVector.GetTxPowerLevel ());
327
  m_txTrace (packet, txVector.GetMode (), txVector.GetPreambleType (), txVector.GetTxPowerLevel ());
318
  Time now = Simulator::Now ();
328
  Time now = Simulator::Now ();
319
  switch (GetState ())
329
  switch (GetState ())
 Lines 352-357    Link Here 
352
void
362
void
353
WifiPhyStateHelper::SwitchToRx (Time rxDuration)
363
WifiPhyStateHelper::SwitchToRx (Time rxDuration)
354
{
364
{
365
  NS_LOG_FUNCTION (this << rxDuration);
355
  NS_ASSERT (IsStateIdle () || IsStateCcaBusy ());
366
  NS_ASSERT (IsStateIdle () || IsStateCcaBusy ());
356
  NS_ASSERT (!m_rxing);
367
  NS_ASSERT (!m_rxing);
357
  Time now = Simulator::Now ();
368
  Time now = Simulator::Now ();
 Lines 385-390    Link Here 
385
void
396
void
386
WifiPhyStateHelper::SwitchToChannelSwitching (Time switchingDuration)
397
WifiPhyStateHelper::SwitchToChannelSwitching (Time switchingDuration)
387
{
398
{
399
  NS_LOG_FUNCTION (this << switchingDuration);
388
  Time now = Simulator::Now ();
400
  Time now = Simulator::Now ();
389
  switch (GetState ())
401
  switch (GetState ())
390
    {
402
    {
 Lines 430-435    Link Here 
430
void
442
void
431
WifiPhyStateHelper::SwitchFromRxEndOk (Ptr<Packet> packet, double snr, WifiTxVector txVector)
443
WifiPhyStateHelper::SwitchFromRxEndOk (Ptr<Packet> packet, double snr, WifiTxVector txVector)
432
{
444
{
445
  NS_LOG_FUNCTION (this << packet << snr << txVector);
433
  m_rxOkTrace (packet, snr, txVector.GetMode (), txVector.GetPreambleType ());
446
  m_rxOkTrace (packet, snr, txVector.GetMode (), txVector.GetPreambleType ());
434
  NotifyRxEndOk ();
447
  NotifyRxEndOk ();
435
  DoSwitchFromRx ();
448
  DoSwitchFromRx ();
 Lines 443-448    Link Here 
443
void
456
void
444
WifiPhyStateHelper::SwitchFromRxEndError (Ptr<Packet> packet, double snr)
457
WifiPhyStateHelper::SwitchFromRxEndError (Ptr<Packet> packet, double snr)
445
{
458
{
459
  NS_LOG_FUNCTION (this << packet << snr);
446
  m_rxErrorTrace (packet, snr);
460
  m_rxErrorTrace (packet, snr);
447
  NotifyRxEndError ();
461
  NotifyRxEndError ();
448
  DoSwitchFromRx ();
462
  DoSwitchFromRx ();
 Lines 455-460    Link Here 
455
void
469
void
456
WifiPhyStateHelper::DoSwitchFromRx (void)
470
WifiPhyStateHelper::DoSwitchFromRx (void)
457
{
471
{
472
  NS_LOG_FUNCTION (this);
458
  NS_ASSERT (IsStateRx ());
473
  NS_ASSERT (IsStateRx ());
459
  NS_ASSERT (m_rxing);
474
  NS_ASSERT (m_rxing);
460
475
 Lines 469-474    Link Here 
469
void
484
void
470
WifiPhyStateHelper::SwitchMaybeToCcaBusy (Time duration)
485
WifiPhyStateHelper::SwitchMaybeToCcaBusy (Time duration)
471
{
486
{
487
  NS_LOG_FUNCTION (this << duration);
472
  NotifyMaybeCcaBusyStart (duration);
488
  NotifyMaybeCcaBusyStart (duration);
473
  Time now = Simulator::Now ();
489
  Time now = Simulator::Now ();
474
  switch (GetState ())
490
  switch (GetState ())
 Lines 497-502    Link Here 
497
void
513
void
498
WifiPhyStateHelper::SwitchToSleep (void)
514
WifiPhyStateHelper::SwitchToSleep (void)
499
{
515
{
516
  NS_LOG_FUNCTION (this);
500
  Time now = Simulator::Now ();
517
  Time now = Simulator::Now ();
501
  switch (GetState ())
518
  switch (GetState ())
502
    {
519
    {
 Lines 527-532    Link Here 
527
void
544
void
528
WifiPhyStateHelper::SwitchFromSleep (Time duration)
545
WifiPhyStateHelper::SwitchFromSleep (Time duration)
529
{
546
{
547
  NS_LOG_FUNCTION (this << duration);
530
  NS_ASSERT (IsStateSleep ());
548
  NS_ASSERT (IsStateSleep ());
531
  Time now = Simulator::Now ();
549
  Time now = Simulator::Now ();
532
  m_stateLogger (m_startSleep, now - m_startSleep, WifiPhy::SLEEP);
550
  m_stateLogger (m_startSleep, now - m_startSleep, WifiPhy::SLEEP);
 Lines 541-544    Link Here 
541
    }
559
    }
542
}
560
}
543
561
562
void
563
WifiPhyStateHelper::SwitchFromRxAbort (void)
564
{
565
  NS_LOG_FUNCTION (this);
566
  NS_ASSERT (IsStateRx ());
567
  NS_ASSERT (m_rxing);
568
  m_endRx = Simulator::Now ();
569
  DoSwitchFromRx ();
570
  NS_ASSERT (!IsStateRx ());
571
}
572
544
} //namespace ns3
573
} //namespace ns3
(-)a/src/wifi/model/wifi-phy-state-helper.h (+4 lines)
 Lines 185-190    Link Here 
185
   * \param duration the duration of CCA busy state
185
   * \param duration the duration of CCA busy state
186
   */
186
   */
187
  void SwitchFromSleep (Time duration);
187
  void SwitchFromSleep (Time duration);
188
  /**
189
   * Abort current reception
190
   */
191
  void SwitchFromRxAbort (void);
188
192
189
  /**
193
  /**
190
   * TracedCallback signature for state changes.
194
   * TracedCallback signature for state changes.
(-)a/src/wifi/model/wifi-phy.cc (-85 / +168 lines)
 Lines 314-319    Link Here 
314
                   MakeBooleanAccessor (&WifiPhy::GetShortPlcpPreambleSupported,
314
                   MakeBooleanAccessor (&WifiPhy::GetShortPlcpPreambleSupported,
315
                                        &WifiPhy::SetShortPlcpPreambleSupported),
315
                                        &WifiPhy::SetShortPlcpPreambleSupported),
316
                   MakeBooleanChecker ())
316
                   MakeBooleanChecker ())
317
    .AddAttribute ("PhysicalLayerCaptureEnabled",
318
                   "Whether or not physical layer capture mode is enabled.",
319
                   BooleanValue (false),
320
                   MakeBooleanAccessor (&WifiPhy::GetPhysicalLayerCaptureEnabled,
321
                                        &WifiPhy::SetPhysicalLayerCaptureEnabled),
322
                   MakeBooleanChecker ())
323
    .AddAttribute ("PhysicalLayerCaptureMargin",
324
                   "If physical layer capture mode is enabled, reception is switched "
325
                   "if the newly arrived frame has a power higher than this value "
326
                   "above the frame currently being received (expressed in dB).",
327
                   DoubleValue (10),
328
                   MakeDoubleAccessor (&WifiPhy::GetPhysicalLayerCaptureMargin,
329
                                       &WifiPhy::SetPhysicalLayerCaptureMargin),
330
                   MakeDoubleChecker<double> ())
317
    .AddTraceSource ("PhyTxBegin",
331
    .AddTraceSource ("PhyTxBegin",
318
                     "Trace source indicating a packet "
332
                     "Trace source indicating a packet "
319
                     "has begun transmitting over the channel medium",
333
                     "has begun transmitting over the channel medium",
 Lines 378-384    Link Here 
378
    m_channelNumber (0),
392
    m_channelNumber (0),
379
    m_initialChannelNumber (0),
393
    m_initialChannelNumber (0),
380
    m_totalAmpduSize (0),
394
    m_totalAmpduSize (0),
381
    m_totalAmpduNumSymbols (0)
395
    m_totalAmpduNumSymbols (0),
396
    m_currentEvent (0)
382
{
397
{
383
  NS_LOG_FUNCTION (this);
398
  NS_LOG_FUNCTION (this);
384
  NS_UNUSED (m_numberOfTransmitters);
399
  NS_UNUSED (m_numberOfTransmitters);
 Lines 580-585    Link Here 
580
}
595
}
581
596
582
void
597
void
598
WifiPhy::SetPhysicalLayerCaptureEnabled (bool enable)
599
{
600
  NS_LOG_FUNCTION (this << enable);
601
  m_physicalLayerCaptureEnabled = enable;
602
}
603
604
bool
605
WifiPhy::GetPhysicalLayerCaptureEnabled (void) const
606
{
607
  return m_physicalLayerCaptureEnabled;
608
}
609
610
void
611
WifiPhy::SetPhysicalLayerCaptureMargin (double margin)
612
{
613
  NS_LOG_FUNCTION (this << margin);
614
  m_physicalLayerCaptureMargin = margin;
615
}
616
617
double
618
WifiPhy::GetPhysicalLayerCaptureMargin (void) const
619
{
620
  return m_physicalLayerCaptureMargin;
621
}
622
623
void
583
WifiPhy::SetLdpc (bool ldpc)
624
WifiPhy::SetLdpc (bool ldpc)
584
{
625
{
585
  NS_LOG_FUNCTION (this << ldpc);
626
  NS_LOG_FUNCTION (this << ldpc);
 Lines 2356-2362    Link Here 
2356
  //This function should be later split to check separately whether plcp preamble and plcp header can be successfully received.
2397
  //This function should be later split to check separately whether plcp preamble and plcp header can be successfully received.
2357
  //Note: plcp preamble reception is not yet modeled.
2398
  //Note: plcp preamble reception is not yet modeled.
2358
  NS_LOG_FUNCTION (this << packet << WToDbm (rxPowerW) << rxDuration);
2399
  NS_LOG_FUNCTION (this << packet << WToDbm (rxPowerW) << rxDuration);
2359
  AmpduTag ampduTag;
2360
  Time endRx = Simulator::Now () + rxDuration;
2400
  Time endRx = Simulator::Now () + rxDuration;
2361
2401
2362
  WifiPhyTag tag;
2402
  WifiPhyTag tag;
 Lines 2380-2395    Link Here 
2380
      NS_FATAL_ERROR ("Reception ends in failure because of an unsupported number of spatial streams");
2420
      NS_FATAL_ERROR ("Reception ends in failure because of an unsupported number of spatial streams");
2381
    }
2421
    }
2382
2422
2383
  WifiPreamble preamble = txVector.GetPreambleType ();
2384
  MpduType mpdutype = tag.GetMpduType ();
2385
  Time preambleAndHeaderDuration = CalculatePlcpPreambleAndHeaderDuration (txVector);
2386
2387
  Ptr<InterferenceHelper::Event> event;
2423
  Ptr<InterferenceHelper::Event> event;
2388
  event = m_interference.Add (packet->GetSize (),
2424
  event = m_interference.Add (packet->GetSize (),
2389
                              txVector,
2425
                              txVector,
2390
                              rxDuration,
2426
                              rxDuration,
2391
                              rxPowerW);
2427
                              rxPowerW);
2392
2428
2429
  MpduType mpdutype = tag.GetMpduType ();
2393
  switch (m_state->GetState ())
2430
  switch (m_state->GetState ())
2394
    {
2431
    {
2395
    case WifiPhy::SWITCHING:
2432
    case WifiPhy::SWITCHING:
 Lines 2408-2425    Link Here 
2408
        {
2445
        {
2409
          //that packet will be noise _after_ the completion of the
2446
          //that packet will be noise _after_ the completion of the
2410
          //channel switching.
2447
          //channel switching.
2411
          goto maybeCcaBusy;
2448
          MaybeCcaBusyDuration ();
2449
          return;
2412
        }
2450
        }
2413
      break;
2451
      break;
2414
    case WifiPhy::RX:
2452
    case WifiPhy::RX:
2415
      NS_LOG_DEBUG ("drop packet because already in Rx (power=" <<
2453
      NS_ASSERT (m_currentEvent != 0);
2416
                    rxPowerW << "W)");
2454
      if (m_physicalLayerCaptureEnabled
2417
      NotifyRxDrop (packet);
2455
          && txVector.GetPreambleType () != WIFI_PREAMBLE_NONE
2418
      if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
2456
          && WToDbm (m_currentEvent->GetRxPowerW ()) + m_physicalLayerCaptureMargin < WToDbm (rxPowerW)
2457
          && m_currentEvent->GetStartTime () + GetPlcpPreambleDuration (m_currentEvent->GetTxVector ()) < Simulator::Now ())
2419
        {
2458
        {
2420
          //that packet will be noise _after_ the reception of the
2459
          AbortCurrentReception ();
2421
          //currently-received packet.
2460
          NS_LOG_DEBUG ("Switch to new packet");
2422
          goto maybeCcaBusy;
2461
          StartRx (packet, txVector, mpdutype, rxPowerW, rxDuration, event);
2462
        }
2463
      else
2464
        {
2465
          NS_LOG_DEBUG ("drop packet because already in Rx (power=" <<
2466
                        rxPowerW << "W)");
2467
          NotifyRxDrop (packet);
2468
          if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
2469
            {
2470
              //that packet will be noise _after_ the reception of the
2471
              //currently-received packet.
2472
              MaybeCcaBusyDuration ();
2473
              return;
2474
            }
2423
        }
2475
        }
2424
      break;
2476
      break;
2425
    case WifiPhy::TX:
2477
    case WifiPhy::TX:
 Lines 2430-2506    Link Here 
2430
        {
2482
        {
2431
          //that packet will be noise _after_ the transmission of the
2483
          //that packet will be noise _after_ the transmission of the
2432
          //currently-transmitted packet.
2484
          //currently-transmitted packet.
2433
          goto maybeCcaBusy;
2485
          MaybeCcaBusyDuration ();
2486
          return;
2434
        }
2487
        }
2435
      break;
2488
      break;
2436
    case WifiPhy::CCA_BUSY:
2489
    case WifiPhy::CCA_BUSY:
2437
    case WifiPhy::IDLE:
2490
    case WifiPhy::IDLE:
2438
      if (rxPowerW > GetEdThresholdW ()) //checked here, no need to check in the payload reception (current implementation assumes constant rx power over the packet duration)
2491
      StartRx (packet, txVector, mpdutype, rxPowerW, rxDuration, event);
2439
        {
2440
          if (preamble == WIFI_PREAMBLE_NONE && (m_mpdusNum == 0 || m_plcpSuccess == false))
2441
            {
2442
              m_plcpSuccess = false;
2443
              m_mpdusNum = 0;
2444
              NS_LOG_DEBUG ("drop packet because no PLCP preamble/header has been received");
2445
              NotifyRxDrop (packet);
2446
              goto maybeCcaBusy;
2447
            }
2448
          else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum == 0)
2449
            {
2450
              //received the first MPDU in an MPDU
2451
              m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
2452
              m_rxMpduReferenceNumber++;
2453
            }
2454
          else if (preamble == WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0)
2455
            {
2456
              //received the other MPDUs that are part of the A-MPDU
2457
              if (ampduTag.GetRemainingNbOfMpdus () < (m_mpdusNum - 1))
2458
                {
2459
                  NS_LOG_DEBUG ("Missing MPDU from the A-MPDU " << m_mpdusNum - ampduTag.GetRemainingNbOfMpdus ());
2460
                  m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
2461
                }
2462
              else
2463
                {
2464
                  m_mpdusNum--;
2465
                }
2466
            }
2467
          else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0)
2468
            {
2469
              NS_LOG_DEBUG ("New A-MPDU started while " << m_mpdusNum << " MPDUs from previous are lost");
2470
              m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
2471
            }
2472
          else if (preamble != WIFI_PREAMBLE_NONE && m_mpdusNum > 0 )
2473
            {
2474
              NS_LOG_DEBUG ("Didn't receive the last MPDUs from an A-MPDU " << m_mpdusNum);
2475
              m_mpdusNum = 0;
2476
            }
2477
2478
          NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)");
2479
          //sync to signal
2480
          m_state->SwitchToRx (rxDuration);
2481
          NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
2482
          NotifyRxBegin (packet);
2483
          m_interference.NotifyRxStart ();
2484
2485
          if (preamble != WIFI_PREAMBLE_NONE)
2486
            {
2487
              NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
2488
              m_endPlcpRxEvent = Simulator::Schedule (preambleAndHeaderDuration, &WifiPhy::StartReceivePacket, this,
2489
                                                      packet, txVector, mpdutype, event);
2490
            }
2491
2492
          NS_ASSERT (m_endRxEvent.IsExpired ());
2493
          m_endRxEvent = Simulator::Schedule (rxDuration, &WifiPhy::EndReceive, this,
2494
                                              packet, preamble, mpdutype, event);
2495
        }
2496
      else
2497
        {
2498
          NS_LOG_DEBUG ("drop packet because signal power too Small (" <<
2499
                        rxPowerW << "<" << GetEdThresholdW () << ")");
2500
          NotifyRxDrop (packet);
2501
          m_plcpSuccess = false;
2502
          goto maybeCcaBusy;
2503
        }
2504
      break;
2492
      break;
2505
    case WifiPhy::SLEEP:
2493
    case WifiPhy::SLEEP:
2506
      NS_LOG_DEBUG ("drop packet because in sleep mode");
2494
      NS_LOG_DEBUG ("drop packet because in sleep mode");
 Lines 2508-2517    Link Here 
2508
      m_plcpSuccess = false;
2496
      m_plcpSuccess = false;
2509
      break;
2497
      break;
2510
    }
2498
    }
2511
2499
}
2512
  return;
2500
2513
2501
void
2514
maybeCcaBusy:
2502
WifiPhy::MaybeCcaBusyDuration ()
2503
{
2515
  //We are here because we have received the first bit of a packet and we are
2504
  //We are here because we have received the first bit of a packet and we are
2516
  //not going to be able to synchronize on it
2505
  //not going to be able to synchronize on it
2517
  //In this model, CCA becomes busy when the aggregation of all signals as
2506
  //In this model, CCA becomes busy when the aggregation of all signals as
 Lines 2572-2577    Link Here 
2572
  InterferenceHelper::SnrPer snrPer;
2561
  InterferenceHelper::SnrPer snrPer;
2573
  snrPer = m_interference.CalculatePlcpPayloadSnrPer (event);
2562
  snrPer = m_interference.CalculatePlcpPayloadSnrPer (event);
2574
  m_interference.NotifyRxEnd ();
2563
  m_interference.NotifyRxEnd ();
2564
  m_currentEvent = 0;
2575
2565
2576
  if (m_plcpSuccess == true)
2566
  if (m_plcpSuccess == true)
2577
    {
2567
    {
 Lines 3662-3667    Link Here 
3662
    }
3652
    }
3663
}
3653
}
3664
3654
3655
void
3656
WifiPhy::AbortCurrentReception ()
3657
{
3658
  NS_LOG_FUNCTION (this);
3659
  if (m_endPlcpRxEvent.IsRunning ())
3660
    {
3661
      m_endPlcpRxEvent.Cancel ();
3662
    }
3663
  if (m_endRxEvent.IsRunning ())
3664
    {
3665
      m_endRxEvent.Cancel ();
3666
    }
3667
  m_interference.NotifyRxEnd ();
3668
  m_state->SwitchFromRxAbort ();
3669
  m_currentEvent = 0;
3670
}
3671
3672
void
3673
WifiPhy::StartRx (Ptr<Packet> packet, WifiTxVector txVector, MpduType mpdutype, double rxPowerW, Time rxDuration, Ptr<InterferenceHelper::Event> event)
3674
{
3675
  NS_LOG_FUNCTION (this << packet << txVector << (uint16_t)mpdutype << rxPowerW << rxDuration);
3676
  if (rxPowerW > GetEdThresholdW ()) //checked here, no need to check in the payload reception (current implementation assumes constant rx power over the packet duration)
3677
    {
3678
      AmpduTag ampduTag;
3679
      WifiPreamble preamble = txVector.GetPreambleType ();
3680
      if (preamble == WIFI_PREAMBLE_NONE && (m_mpdusNum == 0 || m_plcpSuccess == false))
3681
        {
3682
          m_plcpSuccess = false;
3683
          m_mpdusNum = 0;
3684
          NS_LOG_DEBUG ("drop packet because no PLCP preamble/header has been received");
3685
          NotifyRxDrop (packet);
3686
          MaybeCcaBusyDuration ();
3687
          return;
3688
        }
3689
      else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum == 0)
3690
        {
3691
          //received the first MPDU in an MPDU
3692
          m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
3693
          m_rxMpduReferenceNumber++;
3694
        }
3695
      else if (preamble == WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0)
3696
        {
3697
          //received the other MPDUs that are part of the A-MPDU
3698
          if (ampduTag.GetRemainingNbOfMpdus () < (m_mpdusNum - 1))
3699
            {
3700
              NS_LOG_DEBUG ("Missing MPDU from the A-MPDU " << m_mpdusNum - ampduTag.GetRemainingNbOfMpdus ());
3701
              m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
3702
            }
3703
          else
3704
            {
3705
              m_mpdusNum--;
3706
            }
3707
        }
3708
      else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0)
3709
        {
3710
          NS_LOG_DEBUG ("New A-MPDU started while " << m_mpdusNum << " MPDUs from previous are lost");
3711
          m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
3712
        }
3713
      else if (preamble != WIFI_PREAMBLE_NONE && m_mpdusNum > 0 )
3714
        {
3715
          NS_LOG_DEBUG ("Didn't receive the last MPDUs from an A-MPDU " << m_mpdusNum);
3716
          m_mpdusNum = 0;
3717
        }
3718
3719
      NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)");
3720
      m_currentEvent = event;
3721
      m_state->SwitchToRx (rxDuration);
3722
      NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
3723
      NotifyRxBegin (packet);
3724
      m_interference.NotifyRxStart ();
3725
    
3726
      if (preamble != WIFI_PREAMBLE_NONE)
3727
        {
3728
          NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
3729
          Time preambleAndHeaderDuration = CalculatePlcpPreambleAndHeaderDuration (txVector);
3730
          m_endPlcpRxEvent = Simulator::Schedule (preambleAndHeaderDuration, &WifiPhy::StartReceivePacket, this,
3731
                                                  packet, txVector, mpdutype, event);
3732
        }
3733
3734
      NS_ASSERT (m_endRxEvent.IsExpired ());
3735
      m_endRxEvent = Simulator::Schedule (rxDuration, &WifiPhy::EndReceive, this,
3736
                                          packet, preamble, mpdutype, event);
3737
    }
3738
  else
3739
    {
3740
      NS_LOG_DEBUG ("drop packet because signal power too Small (" <<
3741
                    rxPowerW << "<" << GetEdThresholdW () << ")");
3742
      NotifyRxDrop (packet);
3743
      m_plcpSuccess = false;
3744
      MaybeCcaBusyDuration ();
3745
    }
3746
}
3747
3665
int64_t
3748
int64_t
3666
WifiPhy::AssignStreams (int64_t stream)
3749
WifiPhy::AssignStreams (int64_t stream)
3667
{
3750
{
(-)a/src/wifi/model/wifi-phy.h (+59 lines)
 Lines 1445-1450    Link Here 
1445
   * \return the reception gain in dB
1445
   * \return the reception gain in dB
1446
   */
1446
   */
1447
  double GetRxGain (void) const;
1447
  double GetRxGain (void) const;
1448
1449
  /**
1450
   * Sets whether physical layer capture is enabled.
1451
   *
1452
   * \param enable enable or disable physical layer capture
1453
   */
1454
  void SetPhysicalLayerCaptureEnabled (bool enable);
1455
  /**
1456
   * Return whether physical layer capture is enabled.
1457
   *
1458
   * \return true if physical layer capture is enabled,
1459
   *         false otherwise
1460
   */
1461
  bool GetPhysicalLayerCaptureEnabled (void) const;
1462
  /**
1463
   * Sets the physical layer capture margin (dB).
1464
   *
1465
   * \param margin the physical layer capture margin in dB
1466
   */
1467
  void SetPhysicalLayerCaptureMargin (double margin);
1468
  /**
1469
   * Return the physical layer capture margin (dB).
1470
   *
1471
   * \return the physical layer capture margin in dB
1472
   */
1473
  double GetPhysicalLayerCaptureMargin (void) const;
1474
1448
  /**
1475
  /**
1449
   * Sets the device this PHY is associated with.
1476
   * Sets the device this PHY is associated with.
1450
   *
1477
   *
 Lines 1771-1776    Link Here 
1771
   * \return the FrequencyWidthPair found
1798
   * \return the FrequencyWidthPair found
1772
   */
1799
   */
1773
  FrequencyWidthPair GetFrequencyWidthForChannelNumberStandard (uint8_t channelNumber, WifiPhyStandard standard) const;
1800
  FrequencyWidthPair GetFrequencyWidthForChannelNumberStandard (uint8_t channelNumber, WifiPhyStandard standard) const;
1801
  
1802
  /**
1803
   * Due to newly arrived signal, the current reception cannot be continued and has to be aborted
1804
   *
1805
   */
1806
  void AbortCurrentReception (void);
1807
1808
  /**
1809
   * Eventually switch to CCA busy
1810
   */
1811
  void MaybeCcaBusyDuration (void);
1812
  
1813
  /**
1814
   * Starting receiving the packet after having detected the medium is idle or after a reception switch.
1815
   *
1816
   * \param packet the arriving packet
1817
   * \param txVector the TXVECTOR of the arriving packet
1818
   * \param mpdutype the type of the MPDU as defined in WifiPhy::MpduType.
1819
   * \param rxPowerW the receive power in W
1820
   * \param rxDuration the duration needed for the reception of the packet
1821
   * \param event the corresponding event of the first time the packet arrives
1822
   */
1823
  void StartRx (Ptr<Packet> packet,
1824
                WifiTxVector txVector,
1825
                MpduType mpdutype,
1826
                double rxPowerW,
1827
                Time rxDuration,
1828
                Ptr<InterferenceHelper::Event> event);
1774
1829
1775
  /**
1830
  /**
1776
   * The trace source fired when a packet begins the transmission process on
1831
   * The trace source fired when a packet begins the transmission process on
 Lines 1931-1936    Link Here 
1931
1986
1932
  Ptr<NetDevice>     m_device;   //!< Pointer to the device
1987
  Ptr<NetDevice>     m_device;   //!< Pointer to the device
1933
  Ptr<MobilityModel> m_mobility; //!< Pointer to the mobility model
1988
  Ptr<MobilityModel> m_mobility; //!< Pointer to the mobility model
1989
1990
  Ptr<InterferenceHelper::Event> m_currentEvent; //!< Hold the current event
1991
  bool m_physicalLayerCaptureEnabled; //!< Flag whether Physical Layer Capture mode is enabled
1992
  double m_physicalLayerCaptureMargin; //! Margin used for Physical Layer Capture mode
1934
};
1993
};
1935
1994
1936
/**
1995
/**

Return to bug 2368