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

(-)9b2e4c04466e (+77 lines)
Added Link Here 
1
/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) Crash Avoidance Metrics Partnership (CAMP) VSC3
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: Bin Cheng <cb3974@winlab.rutgers.edu>
19
 */
20
21
// This script is to generate two figures showing the frame capture models,
22
// one for preamble capture, one for payload capture. The generated figures
23
// can be used to compare with Fig 6 in paper
24
// "Experience: accurate simulation of dense scenarios with hundreds of vehicular transmitters",
25
// in proceeding of the 22nd Annual International Conference on Mobile Computing
26
// and Networking (MobiCom '16).
27
28
// The simulation performance with and without frame capture effect is also
29
// shown in Fig. 9 of the same paper.
30
31
32
#include "ns3/core-module.h"
33
#include "ns3/frame-capture-model.h"
34
#include "ns3/gnuplot.h"
35
36
using namespace ns3;
37
38
int main (int argc, char *argv[])
39
{
40
  std::ofstream preambleCaptureFile ("preamble-capture-success-rate.plt");
41
  std::ofstream payloadCaptureFile ("payload-capture-success-rate.plt");
42
43
  Gnuplot preambleCapturePlot = Gnuplot ("preamble-capture-success-rate.eps");
44
  Gnuplot payloadCapturePlot = Gnuplot ("payload-capture-success-rate.eps");
45
46
  Ptr<FrameCaptureModel> captureModel = CreateObject<FrameCaptureModel> ();
47
  Gnuplot2dDataset preambleCaptureData ("Preamble-Capture");
48
  Gnuplot2dDataset payloadCaptureData ("Payload-Capture");
49
50
  for (double sinr = 0.0; sinr <= 15.0; sinr += 0.1)
51
    {
52
      double preambleRate = captureModel->CalculatePreambleCaptureProbability (std::pow (10.0, sinr / 10.0));
53
      preambleCaptureData.Add (sinr, preambleRate);
54
      double payloadRate = captureModel->CalculatePayloadCaptureProbability (std::pow (10.0, sinr / 10.0));
55
      payloadCaptureData.Add (sinr, payloadRate);
56
    }
57
58
  preambleCapturePlot.AddDataset (preambleCaptureData);
59
  payloadCapturePlot.AddDataset (payloadCaptureData);
60
61
  preambleCapturePlot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
62
  preambleCapturePlot.SetLegend ("SINR(dB)", "Preamble Capture Success Rate");
63
  preambleCapturePlot.SetExtra  ("set xrange [0:15]\n\
64
set yrange [0:1.1]\n\
65
set style line 1 linewidth 8"                                                                                                                                                                                                                                                                                                                                   );
66
  preambleCapturePlot.GenerateOutput (preambleCaptureFile);
67
  preambleCaptureFile.close ();
68
69
  payloadCapturePlot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
70
  payloadCapturePlot.SetLegend ("SNR(dB)", "Payload Capture Success Rate");
71
  payloadCapturePlot.SetExtra  ("set xrange [0:15]\n\
72
set yrange [0:1.1]\n\
73
set style line 1 linewidth 8"                                                                                                                                                                                                                                                                                                                                   );
74
75
  payloadCapturePlot.GenerateOutput (payloadCaptureFile);
76
  payloadCaptureFile.close ();
77
}
(-)a/src/wifi/examples/test-interference-helper.cc (-8 / +167 lines)
 Lines 56-61    Link Here 
56
#include "ns3/yans-error-rate-model.h"
56
#include "ns3/yans-error-rate-model.h"
57
#include "ns3/constant-position-mobility-model.h"
57
#include "ns3/constant-position-mobility-model.h"
58
58
59
#define PREAMBLE_RECOVERY_TEST 1
60
#define PAYLOAD_RECOVERY_TEST 2
61
#define PREAMBLE_CAPTURE_TEST 3
62
#define PAYLOAD_CAPTURE_TEST 4
63
59
using namespace ns3;
64
using namespace ns3;
60
65
61
class InterferenceExperiment
66
class InterferenceExperiment
 Lines 71-80    Link Here 
71
    std::string txModeB;
76
    std::string txModeB;
72
    uint32_t txPowerLevelA;
77
    uint32_t txPowerLevelA;
73
    uint32_t txPowerLevelB;
78
    uint32_t txPowerLevelB;
79
    double txPowerA;
80
    double txPowerB;
74
    uint32_t packetSizeA;
81
    uint32_t packetSizeA;
75
    uint32_t packetSizeB;
82
    uint32_t packetSizeB;
76
    WifiPhyStandard standard;
83
    WifiPhyStandard standard;
77
    WifiPreamble preamble;
84
    WifiPreamble preamble;
85
    bool enablePreambleCapture;
86
    bool enablePayloadCapture;
87
    int numSentPackets;
78
  };
88
  };
79
89
80
  InterferenceExperiment ();
90
  InterferenceExperiment ();
 Lines 96-101    Link Here 
96
  txVector.SetTxPowerLevel (m_input.txPowerLevelA);
106
  txVector.SetTxPowerLevel (m_input.txPowerLevelA);
97
  txVector.SetMode (WifiMode (m_input.txModeA));
107
  txVector.SetMode (WifiMode (m_input.txModeA));
98
  txVector.SetPreambleType (m_input.preamble);
108
  txVector.SetPreambleType (m_input.preamble);
109
  m_txA->SetTxPowerStart (m_input.txPowerA);
110
  m_txA->SetTxPowerEnd (m_input.txPowerA);
99
  m_txA->SendPacket (p, txVector);
111
  m_txA->SendPacket (p, txVector);
100
}
112
}
101
113
 Lines 107-112    Link Here 
107
  txVector.SetTxPowerLevel (m_input.txPowerLevelB);
119
  txVector.SetTxPowerLevel (m_input.txPowerLevelB);
108
  txVector.SetMode (WifiMode (m_input.txModeB));
120
  txVector.SetMode (WifiMode (m_input.txModeB));
109
  txVector.SetPreambleType (m_input.preamble);
121
  txVector.SetPreambleType (m_input.preamble);
122
  m_txB->SetTxPowerStart (m_input.txPowerB);
123
  m_txB->SetTxPowerEnd (m_input.txPowerB);
110
  m_txB->SendPacket (p, txVector);
124
  m_txB->SendPacket (p, txVector);
111
}
125
}
112
126
 Lines 121-130    Link Here 
121
    txModeB ("OfdmRate54Mbps"),
135
    txModeB ("OfdmRate54Mbps"),
122
    txPowerLevelA (0),
136
    txPowerLevelA (0),
123
    txPowerLevelB (0),
137
    txPowerLevelB (0),
138
    txPowerA (20),
139
    txPowerB (20),
124
    packetSizeA (1500),
140
    packetSizeA (1500),
125
    packetSizeB (1500),
141
    packetSizeB (1500),
126
    standard (WIFI_PHY_STANDARD_80211a),
142
    standard (WIFI_PHY_STANDARD_80211a),
127
    preamble (WIFI_PREAMBLE_LONG)
143
    preamble (WIFI_PREAMBLE_LONG),
144
    enablePreambleCapture (false),
145
    enablePayloadCapture (false),
146
    numSentPackets (1)
128
{
147
{
129
}
148
}
130
149
 Lines 167-174    Link Here 
167
  m_txB->ConfigureStandard (input.standard);
186
  m_txB->ConfigureStandard (input.standard);
168
  rx->ConfigureStandard (input.standard);
187
  rx->ConfigureStandard (input.standard);
169
188
170
  Simulator::Schedule (Seconds (0), &InterferenceExperiment::SendA, this);
189
  m_txA->SetAttribute ("PreambleCaptureEnabled", BooleanValue (input.enablePreambleCapture));
171
  Simulator::Schedule (Seconds (0) + input.interval, &InterferenceExperiment::SendB, this);
190
  m_txB->SetAttribute ("PreambleCaptureEnabled", BooleanValue (input.enablePreambleCapture));
191
  rx->SetAttribute ("PreambleCaptureEnabled", BooleanValue (input.enablePreambleCapture));
192
  m_txA->SetAttribute ("PayloadCaptureEnabled", BooleanValue (input.enablePayloadCapture));
193
  m_txB->SetAttribute ("PayloadCaptureEnabled", BooleanValue (input.enablePayloadCapture));
194
  rx->SetAttribute ("PayloadCaptureEnabled", BooleanValue (input.enablePayloadCapture));
195
196
  for (int n = 0; n < input.numSentPackets; ++n)
197
    {
198
      double start = 0.1 * n;
199
      Simulator::Schedule (Seconds (start), &InterferenceExperiment::SendA, this);
200
      Simulator::Schedule (Seconds (start) + input.interval, &InterferenceExperiment::SendB, this);
201
    }
172
202
173
  Simulator::Run ();
203
  Simulator::Run ();
174
  Simulator::Destroy ();
204
  Simulator::Destroy ();
 Lines 181-186    Link Here 
181
  std::string str_standard = "WIFI_PHY_STANDARD_80211a";
211
  std::string str_standard = "WIFI_PHY_STANDARD_80211a";
182
  std::string str_preamble = "WIFI_PREAMBLE_LONG";
212
  std::string str_preamble = "WIFI_PREAMBLE_LONG";
183
  double delay = 0; //microseconds
213
  double delay = 0; //microseconds
214
  bool testDifferentPacketCollisionScenarios = false; // If this is true, run tests for different frame capture cases
184
215
185
  CommandLine cmd;
216
  CommandLine cmd;
186
  cmd.AddValue ("delay", "Delay in microseconds between frame transmission from sender A and frame transmission from sender B", delay);
217
  cmd.AddValue ("delay", "Delay in microseconds between frame transmission from sender A and frame transmission from sender B", delay);
 Lines 188-202    Link Here 
188
  cmd.AddValue ("xB", "The position of transmitter B (> 0)", input.xB);
219
  cmd.AddValue ("xB", "The position of transmitter B (> 0)", input.xB);
189
  cmd.AddValue ("packetSizeA", "Packet size in bytes of transmitter A", input.packetSizeA);
220
  cmd.AddValue ("packetSizeA", "Packet size in bytes of transmitter A", input.packetSizeA);
190
  cmd.AddValue ("packetSizeB", "Packet size in bytes of transmitter B", input.packetSizeB);
221
  cmd.AddValue ("packetSizeB", "Packet size in bytes of transmitter B", input.packetSizeB);
191
  cmd.AddValue ("txPowerA", "TX power level of transmitter A", input.txPowerLevelA);
222
  cmd.AddValue ("txPowerLevelA", "TX power level of transmitter A", input.txPowerLevelA);
192
  cmd.AddValue ("txPowerB", "TX power level of transmitter B", input.txPowerLevelB);
223
  cmd.AddValue ("txPowerLevelB", "TX power level of transmitter B", input.txPowerLevelB);
224
  cmd.AddValue ("txPowerA", "Tx power of transmitter A", input.txPowerA);
225
  cmd.AddValue ("txPowerB", "Tx power of transmitter B", input.txPowerB);
193
  cmd.AddValue ("txModeA", "Wifi mode used for payload transmission of sender A", input.txModeA);
226
  cmd.AddValue ("txModeA", "Wifi mode used for payload transmission of sender A", input.txModeA);
194
  cmd.AddValue ("txModeB", "Wifi mode used for payload transmission of sender B", input.txModeB);
227
  cmd.AddValue ("txModeB", "Wifi mode used for payload transmission of sender B", input.txModeB);
195
  cmd.AddValue ("standard", "IEEE 802.11 flavor", str_standard);
228
  cmd.AddValue ("standard", "IEEE 802.11 flavor", str_standard);
196
  cmd.AddValue ("preamble", "Type of preamble", str_preamble);
229
  cmd.AddValue ("preamble", "Type of preamble", str_preamble);
230
  cmd.AddValue ("enablePreambleCapture", "Enable frame capture capability at preamble portion", input.enablePreambleCapture);
231
  cmd.AddValue ("enablePayloadCapture", "Enable frame capture capability at payload portion", input.enablePayloadCapture);
232
  cmd.AddValue ("testDifferentPacketCollisionScenarios", "Test frame reception/capture behaviors in different frame collision scenarios",
233
		testDifferentPacketCollisionScenarios);
197
  cmd.Parse (argc, argv);
234
  cmd.Parse (argc, argv);
198
235
199
  LogComponentEnable ("YansWifiPhy", LOG_LEVEL_ALL);
236
  LogComponentEnable ("WifiPhy", LOG_LEVEL_ALL);
200
  LogComponentEnable ("InterferenceHelper", LOG_LEVEL_ALL);
237
  LogComponentEnable ("InterferenceHelper", LOG_LEVEL_ALL);
201
238
202
  input.interval = MicroSeconds (delay);
239
  input.interval = MicroSeconds (delay);
 Lines 258-265    Link Here 
258
      return 0;
295
      return 0;
259
    }
296
    }
260
297
261
  InterferenceExperiment experiment;
298
  if (testDifferentPacketCollisionScenarios)
262
  experiment.Run (input);
299
    {
300
      InterferenceExperiment experiment;
263
301
302
      // There are two categories, 4 different packet collision scenarios. Two categories are the recovery
303
      // and the capture.
304
      //   Packet A arrives first
305
      // |-------------------------|
306
      // 	      Packet B arrives later
307
      //           |-------------------------|
308
      // The recovery means that the earlier arrived packet trends to be received. With
309
      // newly arrived packet as interference, the recovery probability is calculated, which determines whether
310
      // the reception of this packet can be continued.
311
312
      // The capture means the later arrived packet tends to be received. A capture probability is calculated
313
      // to determine whether the receiver can switch to this newly arrived packet.
314
315
      // For each category, two packets may collides at the preamble portion or the payload portion.
316
      // Note that different txPower of packet A and B can generate different SINR situations at the receiver
317
318
      int testName = PREAMBLE_CAPTURE_TEST;  // define what test to run
319
320
      switch (testName)
321
        {
322
323
        case PREAMBLE_RECOVERY_TEST:
324
          // PREAMBLE_RECOVERY_TEST 1: gradually increase the tx power of the first sent packet (packet A)
325
          // in order to check: with newly arrived interference, under what condition, the packet
326
          // can still be recovery at the receiver.
327
328
          // Two packets collide at the preamble portion of the packet
329
          // In this test, with and without frame capture capability will not generate differences.
330
          input.interval = MicroSeconds (10); // two packets collides at the preamble portion of the first packet
331
          input.numSentPackets = 1000;
332
          for (double powerGap = 0.0; powerGap <= 15.0; powerGap += 0.2)
333
            {
334
              input.txPowerA = input.txPowerB + powerGap;
335
              experiment.Run (input);
336
            }
337
          break;
338
339
        case PAYLOAD_RECOVERY_TEST:
340
          // PAYLOAD_RECOVERY_TEST: gradually increase the tx power of the first sent packet (packet A)
341
          // in order to check: with newly arrived interference, under what condition, the packet
342
          // can still be recovery at the receiver.
343
344
          // Two packets collide at the payload portion of the packet
345
          // In this test, with and without frame capture capability will not generate differences.
346
347
          input.interval = MicroSeconds (100); // two packets collides at the payload portion of the first packet
348
          input.numSentPackets = 1000;
349
          for (double powerGap = 0.0; powerGap <= 15.0; powerGap += 0.2)
350
            {
351
              input.txPowerA = input.txPowerB + powerGap;
352
              experiment.Run (input);
353
            }
354
          break;
355
356
        case PREAMBLE_CAPTURE_TEST:
357
          // PREAMBLE_CAPTURE_TEST: gradually increase the tx power of the late sent packet (packet B)
358
          // in order to check: under what condition, the receiver can switch to the new packet,
359
360
          // In this test, without frame capture capability, the reception of both packets fails.
361
          // However, with frame capture capability, packet B can be received with certain probability
362
          // Two packets collide at the preamble portion of the packet
363
364
          if (!input.enablePreambleCapture)
365
            {
366
              std::cout << "Running PREAMBLE_CAPTURE_TEST. However, preamble capture is not enabled. "
367
                        << "Should expect no packets can be received successfully!"
368
                        << std::endl;
369
            }
370
          else
371
            {
372
              std::cout << "Running PREAMBLE_CAPTURE_TEST. The payload capture is enabled. "
373
                        << "Should expect packets from node B can be received successfully, "
374
                        << "once the tx power of B is large enough!"
375
                        << std::endl;
376
377
            }
378
          input.interval = MicroSeconds (10); // two packets collides at the preamble portion of the first packet
379
          input.numSentPackets = 1000;
380
          for (double powerGap = 0.0; powerGap <= 15.0; powerGap += 0.2)
381
            {
382
              input.txPowerB = input.txPowerA + powerGap;
383
              experiment.Run (input);
384
            }
385
          break;
386
387
        case PAYLOAD_CAPTURE_TEST:
388
          // PAYLOAD_CAPTURE_TEST: gradually increase the tx power of the late sent packet (packet B)
389
          // in order to check: under what condition, the receiver can switch to the new packet.
390
391
          // In this test, without frame capture capability, the reception of both packets fails.
392
          // However, with frame capture capability, packet B can be received with certain probability
393
          // Two packets collide at the payload portion of the packet
394
395
          if (!input.enablePayloadCapture)
396
            {
397
              std::cout << "Run PAYLOAD_CAPTURE_TEST. However, the payload capture is not enabled. "
398
                        << "Should expect no packets can be received successfully!"
399
                        << std::endl;
400
            }
401
          else
402
            {
403
              std::cout << "Run PAYLOAD_CAPTURE_TEST. The payload capture is enabled. "
404
                        << "Should expect packets from node B can be received successfully, "
405
                        << "once the tx power of B is large enough!"
406
                        << std::endl;
407
            }
408
          input.interval = MicroSeconds (100); // two packets collides at the payload portion of the first packet
409
          input.numSentPackets = 1000;
410
          for (double powerGap = 0.0; powerGap <= 15.0; powerGap += 0.2)
411
            {
412
              input.txPowerB = input.txPowerA + powerGap;
413
              experiment.Run (input);
414
            }
415
          break;
416
        }
417
    }
418
  else
419
    {
420
      InterferenceExperiment experiment;
421
      experiment.Run (input);
422
    }
264
  return 0;
423
  return 0;
265
}
424
}
(-)a/src/wifi/examples/wscript (-1 / +6 lines)
 Lines 11-17    Link Here 
11
    obj = bld.create_ns3_program('test-interference-helper',
11
    obj = bld.create_ns3_program('test-interference-helper',
12
        ['core', 'mobility', 'network', 'wifi'])
12
        ['core', 'mobility', 'network', 'wifi'])
13
    obj.source = 'test-interference-helper.cc'
13
    obj.source = 'test-interference-helper.cc'
14
14
    
15
    obj = bld.create_ns3_program('ideal-wifi-manager-example',
15
    obj = bld.create_ns3_program('ideal-wifi-manager-example',
16
        ['core', 'network', 'wifi', 'stats', 'mobility', 'propagation'])
16
        ['core', 'network', 'wifi', 'stats', 'mobility', 'propagation'])
17
    obj.source = 'ideal-wifi-manager-example.cc'
17
    obj.source = 'ideal-wifi-manager-example.cc'
 Lines 23-25    Link Here 
23
    obj = bld.create_ns3_program('wifi-phy-configuration',
23
    obj = bld.create_ns3_program('wifi-phy-configuration',
24
        ['core', 'network', 'config-store', 'wifi'])
24
        ['core', 'network', 'config-store', 'wifi'])
25
    obj.source = 'wifi-phy-configuration.cc'
25
    obj.source = 'wifi-phy-configuration.cc'
26
27
    obj = bld.create_ns3_program('frame-capture-model-validation',
28
        ['core', 'wifi'])
29
    obj.source = 'frame-capture-model-validation.cc'    
30
    
(-)9b2e4c04466e (+106 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) Crash Avoidance Metrics Partnership (CAMP) VSC3
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: Bin Cheng <cb3974@winlab.rutgers.edu>
19
 */
20
21
// This file contains two models for implementing the frame capture effect in the ns-3
22
// simulator, i.e., the preamble capture model and the payload capture model.
23
24
// The payload capture model was calibrated based on the results of a set of hardware tests
25
// conducted by the CAMP research team for IEEE 802.11p OFDM signals with 6 Mbps
26
// bandwidth on 10 MHz channel.
27
// The lab test results show a relationship between the probability of successfully
28
// capturing a strong signal and required SINR values.
29
30
// The preamble capture model was calibrated by shifting an theoretical error model (based the default
31
// ns-3 NIST model to decode a OFDM 6 Mbps signal with 40 us transmission duration).
32
// The obtained model was able to generate the best match between the simulation results and the
33
// the field test results.
34
35
// For more details of the model choices, please refer to paper:
36
// "Experience: accurate simulation of dense scenarios with hundreds of vehicular transmitters",
37
// in proceeding of the 22nd Annual International Conference on Mobile Computing
38
// and Networking (MobiCom '16).
39
40
#include "frame-capture-model.h"
41
#include <algorithm>
42
#include <cmath>
43
#include "wifi-utils.h"
44
45
namespace ns3 {
46
47
NS_OBJECT_ENSURE_REGISTERED (FrameCaptureModel);
48
49
TypeId
50
FrameCaptureModel::GetTypeId (void)
51
{
52
  static TypeId tid = TypeId ("ns3::FrameCaptureModel")
53
    .SetParent<Object> ()
54
    .SetGroupName ("Wifi")
55
    .AddConstructor<FrameCaptureModel> ()
56
  ;
57
  return tid;
58
}
59
60
FrameCaptureModel::FrameCaptureModel ()
61
{
62
}
63
64
double
65
FrameCaptureModel::CalculatePreambleCaptureProbability (double sinr)
66
{
67
  double z = std::sqrt (sinr / 4.0);
68
  double p = 0.5 * erfc (z);
69
  if (p == 0.0)
70
    {
71
      return 1.0;
72
    }
73
  double pe = CalculatePe (p);
74
  pe = std::min (pe, 1.0);
75
  double prob = std::pow (1 - pe, 240);
76
  return prob;
77
}
78
79
double
80
FrameCaptureModel::CalculatePayloadCaptureProbability (double sinr)
81
{
82
  double sinrDb = RatioToDb (sinr);
83
  double prob = 0.4989 * erf ((sinrDb - 9.356) / 0.8722) + 0.4989;
84
  prob = std::max (prob, 0.0);
85
  prob = std::min (prob, 1.0);
86
  return prob;
87
}
88
89
double
90
FrameCaptureModel::CalculatePe (double p)
91
{
92
  double D = std::sqrt (4.0 * p * (1.0 - p));
93
  double pe = 1.0;
94
  pe = 0.5 * (36.0 * std::pow (D, 10)
95
              + 211.0 * std::pow (D, 12)
96
              + 1404.0 * std::pow (D, 14)
97
              + 11633.0 * std::pow (D, 16)
98
              + 77433.0 * std::pow (D, 18)
99
              + 502690.0 * std::pow (D, 20)
100
              + 3322763.0 * std::pow (D, 22)
101
              + 21292910.0 * std::pow (D, 24)
102
              + 134365911.0 * std::pow (D, 26));
103
  return pe;
104
}
105
106
} // //namespace ns3
(-)9b2e4c04466e (+72 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) Crash Avoidance Metrics Partnership (CAMP) VSC3
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: Bin Cheng <cb3974@winlab.rutgers.edu>
19
 *
20
 */
21
22
23
#ifndef FRAME_CAPTURE_MODEL_H
24
#define FRAME_CAPTURE_MODEL_H
25
26
#include "ns3/object.h"
27
28
namespace ns3 {
29
30
/**
31
 * \ingroup wifi
32
 * \brief models for switching between two receptions
33
 */
34
class FrameCaptureModel : public Object
35
{
36
public:
37
  static TypeId GetTypeId (void);
38
  FrameCaptureModel ();
39
40
  /**
41
   * Given a sinr value, calculate the probability of a successful
42
   * reception switch at the preamble/header portion of a packet
43
   *
44
   * \param the current sinr value
45
   *
46
   * \return the successful probability of the reception switch
47
   */
48
  double CalculatePreambleCaptureProbability (double sinr);
49
50
  /**
51
   * Given a sinr value, calculate the probability of a successful
52
   * reception switch at the payload portion of a packet
53
   *
54
   * \param the current sinr value
55
   *
56
   * \return the successful probability of the reception switch
57
   */
58
  double CalculatePayloadCaptureProbability (double sinr);
59
private:
60
  /**
61
   * Calculate a coded bit error rate
62
   *
63
   * \param p
64
   *
65
   * \return BER
66
   */
67
  double CalculatePe (double p);
68
};
69
70
} //namespace ns3
71
72
#endif /* FRAME_CAPTURE_MODEL_H */
(-)a/src/wifi/model/interference-helper.cc (-11 / +54 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 842-848    Link Here 
842
InterferenceHelper::NiChanges::iterator
873
InterferenceHelper::NiChanges::iterator
843
InterferenceHelper::GetPosition (Time moment)
874
InterferenceHelper::GetPosition (Time moment)
844
{
875
{
845
  return std::upper_bound (m_niChanges.begin (), m_niChanges.end (), NiChange (moment, 0));
876
  return std::upper_bound (m_niChanges.begin (), m_niChanges.end (), NiChange (moment, 0, NULL));
846
}
877
}
847
878
848
void
879
void
 Lines 865-868    Link Here 
865
  m_rxing = false;
896
  m_rxing = false;
866
}
897
}
867
898
899
double
900
InterferenceHelper::CalculatePreambleCaptureProbability (double sinr)
901
{
902
  return m_frameCaptureModel->CalculatePreambleCaptureProbability (sinr);
903
}
904
905
double
906
InterferenceHelper::CalculatePayloadCaptureProbability (double sinr)
907
{
908
  return m_frameCaptureModel->CalculatePayloadCaptureProbability (sinr);
909
}
910
868
} //namespace ns3
911
} //namespace ns3
(-)a/src/wifi/model/interference-helper.h (-2 / +27 lines)
 Lines 24-29    Link Here 
24
#include "ns3/nstime.h"
24
#include "ns3/nstime.h"
25
#include "wifi-tx-vector.h"
25
#include "wifi-tx-vector.h"
26
#include "error-rate-model.h"
26
#include "error-rate-model.h"
27
#include "frame-capture-model.h"
27
28
28
namespace ns3 {
29
namespace ns3 {
29
30
 Lines 206-212    Link Here 
206
   * Erase all events.
207
   * Erase all events.
207
   */
208
   */
208
  void EraseEvents (void);
209
  void EraseEvents (void);
209
210
  /**
211
   * Calculate the successful probability for preamble capture
212
   * \param sinr the sinr value at the current time
213
   *
214
   * \return the probability of the successful preamble capture with the given sinr
215
   */
216
  double CalculatePreambleCaptureProbability (double sinr);
217
  /**
218
   * Calculate the successful probability for payload capture
219
   * \param sinr the sinr value at the current time
220
   *
221
   * \return the probability of the successful payload capture with the given sinr
222
   */
223
  double CalculatePayloadCaptureProbability (double sinr);
210
224
211
private:
225
private:
212
  /**
226
  /**
 Lines 220-227    Link Here 
220
     *
234
     *
221
     * \param time time of the event
235
     * \param time time of the event
222
     * \param delta the power
236
     * \param delta the power
237
     * \param event causes this NI change
223
     */
238
     */
224
    NiChange (Time time, double delta);
239
    NiChange (Time time, double delta, Ptr<InterferenceHelper::Event> event);
225
    /**
240
    /**
226
     * Return the event time.
241
     * Return the event time.
227
     *
242
     *
 Lines 235-240    Link Here 
235
     */
250
     */
236
    double GetDelta (void) const;
251
    double GetDelta (void) const;
237
    /**
252
    /**
253
     * Return the event causes the corresponding NI change
254
     *
255
     * \return the event
256
     */
257
    Ptr<InterferenceHelper::Event> GetEvent (void) const;
258
    /**
238
     * Compare the event time of two NiChange objects (a < o).
259
     * Compare the event time of two NiChange objects (a < o).
239
     *
260
     *
240
     * \param o
261
     * \param o
 Lines 246-251    Link Here 
246
private:
267
private:
247
    Time m_time;
268
    Time m_time;
248
    double m_delta;
269
    double m_delta;
270
    Ptr<InterferenceHelper::Event> m_event;
249
  };
271
  };
250
  /**
272
  /**
251
   * typedef for a vector of NiChanges
273
   * typedef for a vector of NiChanges
 Lines 322-327    Link Here 
322
  NiChanges m_niChanges;
344
  NiChanges m_niChanges;
323
  double m_firstPower;
345
  double m_firstPower;
324
  bool m_rxing;
346
  bool m_rxing;
347
348
  Ptr<FrameCaptureModel> m_frameCaptureModel;
349
325
  /// Returns an iterator to the first nichange, which is later than moment
350
  /// Returns an iterator to the first nichange, which is later than moment
326
  NiChanges::iterator GetPosition (Time moment);
351
  NiChanges::iterator GetPosition (Time moment);
327
  /**
352
  /**
(-)a/src/wifi/model/wifi-phy-state-helper.cc (+15 lines)
 Lines 541-544    Link Here 
541
    }
541
    }
542
}
542
}
543
543
544
void
545
WifiPhyStateHelper::SwitchFromRxAbort (Ptr<Packet> packet, double snr)
546
{
547
  NS_ASSERT (IsStateRx ());
548
  NS_ASSERT (m_rxing);
549
  m_rxErrorTrace (packet, snr);
550
  NotifyRxEndError ();
551
  m_endRx = Simulator::Now ();
552
  DoSwitchFromRx ();
553
  NS_ASSERT (!IsStateRx ());
554
  if (!m_rxErrorCallback.IsNull ())
555
    {
556
      m_rxErrorCallback (packet, snr);
557
    }
558
}
544
} //namespace ns3
559
} //namespace ns3
(-)a/src/wifi/model/wifi-phy-state-helper.h (-1 / +4 lines)
 Lines 181-187    Link Here 
181
   * \param duration the duration of CCA busy state
181
   * \param duration the duration of CCA busy state
182
   */
182
   */
183
  void SwitchFromSleep (Time duration);
183
  void SwitchFromSleep (Time duration);
184
184
  /**
185
   * Abort current reception
186
   */
187
  void SwitchFromRxAbort (Ptr<Packet> packet, double snr);
185
  /** \todo Why is this public? */
188
  /** \todo Why is this public? */
186
  TracedCallback<Time, Time, WifiPhy::State> m_stateLogger;
189
  TracedCallback<Time, Time, WifiPhy::State> m_stateLogger;
187
190
(-)a/src/wifi/model/wifi-phy.cc (-40 / +221 lines)
 Lines 308-313    Link Here 
308
                   MakeBooleanAccessor (&WifiPhy::GetShortPlcpPreambleSupported,
308
                   MakeBooleanAccessor (&WifiPhy::GetShortPlcpPreambleSupported,
309
                                        &WifiPhy::SetShortPlcpPreambleSupported),
309
                                        &WifiPhy::SetShortPlcpPreambleSupported),
310
                   MakeBooleanChecker ())
310
                   MakeBooleanChecker ())
311
    .AddAttribute ("PreambleCaptureEnabled",
312
                   "Whether or not to enable capture at the preamble portion of the packet.",
313
                   BooleanValue (false),
314
                   MakeBooleanAccessor (&WifiPhy::m_doPreambleCapture),
315
                   MakeBooleanChecker ())
316
    .AddAttribute ("PayloadCaptureEnabled",
317
                   "Whether or not to enable capture at the payload portion of the packet",
318
                   BooleanValue (false),
319
                   MakeBooleanAccessor (&WifiPhy::m_doPayloadCapture),
320
                   MakeBooleanChecker ())
311
    .AddTraceSource ("PhyTxBegin",
321
    .AddTraceSource ("PhyTxBegin",
312
                     "Trace source indicating a packet "
322
                     "Trace source indicating a packet "
313
                     "has begun transmitting over the channel medium",
323
                     "has begun transmitting over the channel medium",
 Lines 883-891    Link Here 
883
    {
893
    {
884
      // erase all HtMcs modes from deviceMcsSet
894
      // erase all HtMcs modes from deviceMcsSet
885
      size_t index = m_deviceMcsSet.size () - 1;
895
      size_t index = m_deviceMcsSet.size () - 1;
886
      for (std::vector<WifiMode>::reverse_iterator rit = m_deviceMcsSet.rbegin (); rit != m_deviceMcsSet.rend(); ++rit, --index)
896
      for (std::vector<WifiMode>::reverse_iterator rit = m_deviceMcsSet.rbegin (); rit != m_deviceMcsSet.rend (); ++rit, --index)
887
        {
897
        {
888
          if (m_deviceMcsSet[index].GetModulationClass ()== WIFI_MOD_CLASS_HT)
898
          if (m_deviceMcsSet[index].GetModulationClass () == WIFI_MOD_CLASS_HT)
889
            {
899
            {
890
              m_deviceMcsSet.erase (m_deviceMcsSet.begin () + index);
900
              m_deviceMcsSet.erase (m_deviceMcsSet.begin () + index);
891
            }
901
            }
 Lines 999-1006    Link Here 
999
    {
1009
    {
1000
      if (it->second == f)
1010
      if (it->second == f)
1001
        {
1011
        {
1002
           found = true;
1012
          found = true;
1003
           break;
1013
          break;
1004
        }
1014
        }
1005
      ++it;
1015
      ++it;
1006
    }
1016
    }
 Lines 1945-1956    Link Here 
1945
        //check tables 20-35 and 20-36 in the .11n standard to get cases when nes = 2
1955
        //check tables 20-35 and 20-36 in the .11n standard to get cases when nes = 2
1946
        double Nes = 1;
1956
        double Nes = 1;
1947
        if (payloadMode.GetUniqueName () == "HtMcs21"
1957
        if (payloadMode.GetUniqueName () == "HtMcs21"
1948
           || payloadMode.GetUniqueName () == "HtMcs22"
1958
            || payloadMode.GetUniqueName () == "HtMcs22"
1949
           || payloadMode.GetUniqueName () == "HtMcs23"
1959
            || payloadMode.GetUniqueName () == "HtMcs23"
1950
           || payloadMode.GetUniqueName () == "HtMcs28"
1960
            || payloadMode.GetUniqueName () == "HtMcs28"
1951
           || payloadMode.GetUniqueName () == "HtMcs29"
1961
            || payloadMode.GetUniqueName () == "HtMcs29"
1952
           || payloadMode.GetUniqueName () == "HtMcs30"
1962
            || payloadMode.GetUniqueName () == "HtMcs30"
1953
           || payloadMode.GetUniqueName () == "HtMcs31")
1963
            || payloadMode.GetUniqueName () == "HtMcs31")
1954
          {
1964
          {
1955
            Nes = 2;
1965
            Nes = 2;
1956
          }
1966
          }
 Lines 2125-2131    Link Here 
2125
Time
2135
Time
2126
WifiPhy::CalculatePlcpPreambleAndHeaderDuration (WifiTxVector txVector)
2136
WifiPhy::CalculatePlcpPreambleAndHeaderDuration (WifiTxVector txVector)
2127
{
2137
{
2128
  WifiPreamble preamble = txVector.GetPreambleType();
2138
  WifiPreamble preamble = txVector.GetPreambleType ();
2129
  Time duration = GetPlcpPreambleDuration (txVector)
2139
  Time duration = GetPlcpPreambleDuration (txVector)
2130
    + GetPlcpHeaderDuration (txVector)
2140
    + GetPlcpHeaderDuration (txVector)
2131
    + GetPlcpHtSigHeaderDuration (preamble)
2141
    + GetPlcpHtSigHeaderDuration (preamble)
 Lines 2213-2219    Link Here 
2213
   *  - we are idle
2223
   *  - we are idle
2214
   */
2224
   */
2215
  NS_ASSERT (!m_state->IsStateTx () && !m_state->IsStateSwitching ());
2225
  NS_ASSERT (!m_state->IsStateTx () && !m_state->IsStateSwitching ());
2216
  
2226
2217
  if (txVector.GetNss () > GetMaxSupportedTxSpatialStreams ())
2227
  if (txVector.GetNss () > GetMaxSupportedTxSpatialStreams ())
2218
    {
2228
    {
2219
      NS_FATAL_ERROR ("Unsupported number of spatial streams!");
2229
      NS_FATAL_ERROR ("Unsupported number of spatial streams!");
 Lines 2252-2258    Link Here 
2252
  newPacket->RemovePacketTag (oldtag);
2262
  newPacket->RemovePacketTag (oldtag);
2253
  WifiPhyTag tag (txVector, mpdutype);
2263
  WifiPhyTag tag (txVector, mpdutype);
2254
  newPacket->AddPacketTag (tag);
2264
  newPacket->AddPacketTag (tag);
2255
  
2265
2256
  StartTx (newPacket, txVector, txDuration);
2266
  StartTx (newPacket, txVector, txDuration);
2257
}
2267
}
2258
2268
 Lines 2264-2270    Link Here 
2264
  NS_LOG_FUNCTION (this << packet << WToDbm (rxPowerW) << rxDuration);
2274
  NS_LOG_FUNCTION (this << packet << WToDbm (rxPowerW) << rxDuration);
2265
  AmpduTag ampduTag;
2275
  AmpduTag ampduTag;
2266
  Time endRx = Simulator::Now () + rxDuration;
2276
  Time endRx = Simulator::Now () + rxDuration;
2267
  
2277
2268
  WifiPhyTag tag;
2278
  WifiPhyTag tag;
2269
  bool found = packet->RemovePacketTag (tag);
2279
  bool found = packet->RemovePacketTag (tag);
2270
  if (!found)
2280
  if (!found)
 Lines 2274-2290    Link Here 
2274
    }
2284
    }
2275
2285
2276
  WifiTxVector txVector = tag.GetWifiTxVector ();
2286
  WifiTxVector txVector = tag.GetWifiTxVector ();
2277
  
2287
2278
  if (txVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HT
2288
  if (txVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HT
2279
      && (txVector.GetNss () != (1 + (txVector.GetMode ().GetMcsValue () / 8))))
2289
      && (txVector.GetNss () != (1 + (txVector.GetMode ().GetMcsValue () / 8))))
2280
    {
2290
    {
2281
      NS_FATAL_ERROR ("MCS value does not match NSS value: MCS = " << (uint16_t)txVector.GetMode ().GetMcsValue () << ", NSS = " << (uint16_t)txVector.GetNss ());
2291
      NS_FATAL_ERROR ("MCS value does not match NSS value: MCS = " << (uint16_t)txVector.GetMode ().GetMcsValue () << ", NSS = " << (uint16_t)txVector.GetNss ());
2282
    }
2292
    }
2283
  
2293
2284
  if (txVector.GetNss () > GetMaxSupportedRxSpatialStreams ())
2294
  if (txVector.GetNss () > GetMaxSupportedRxSpatialStreams ())
2285
     {
2295
    {
2286
      NS_FATAL_ERROR ("Reception ends in failure because of an unsupported number of spatial streams");
2296
      NS_FATAL_ERROR ("Reception ends in failure because of an unsupported number of spatial streams");
2287
     }
2297
    }
2288
2298
2289
  WifiPreamble preamble = txVector.GetPreambleType ();
2299
  WifiPreamble preamble = txVector.GetPreambleType ();
2290
  MpduType mpdutype = tag.GetMpduType ();
2300
  MpduType mpdutype = tag.GetMpduType ();
 Lines 2314-2333    Link Here 
2314
        {
2324
        {
2315
          //that packet will be noise _after_ the completion of the
2325
          //that packet will be noise _after_ the completion of the
2316
          //channel switching.
2326
          //channel switching.
2317
          goto maybeCcaBusy;
2327
          CalculateCcaBusyDuration ();
2318
        }
2328
        }
2319
      break;
2329
      break;
2320
    case WifiPhy::RX:
2330
    case WifiPhy::RX:
2321
      NS_LOG_DEBUG ("drop packet because already in Rx (power=" <<
2331
      {
2322
                    rxPowerW << "W)");
2332
        NS_ASSERT (m_rxPacketEvent != NULL);
2323
      NotifyRxDrop (packet);
2333
        if (m_doPreambleCapture == false
2324
      if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
2334
            || m_doPayloadCapture == false
2325
        {
2335
            || preamble == WIFI_PREAMBLE_NONE)
2326
          //that packet will be noise _after_ the reception of the
2336
          {
2327
          //currently-received packet.
2337
            NotifyRxDrop (packet);
2328
          goto maybeCcaBusy;
2338
            if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
2329
        }
2339
              {
2330
      break;
2340
                CalculateCcaBusyDuration ();
2341
              }
2342
            break;
2343
          }
2344
2345
        Time currentRxStage = Simulator::Now () - m_rxPacketEvent->GetStartTime ();
2346
        bool doReceptionSwitch = false;
2347
        if (m_rxPreambleType != WIFI_PREAMBLE_NONE
2348
            && currentRxStage < preambleAndHeaderDuration) // still receiving the preamble and plcp header portion of the old packet
2349
          {
2350
            doReceptionSwitch = CheckPreambleCapture (packet, event);
2351
          }
2352
        else
2353
          {
2354
            doReceptionSwitch = CheckPayloadCapture (packet, event);
2355
          }
2356
        if (doReceptionSwitch)
2357
          {
2358
            NS_LOG_INFO ("The receiver switches to the new packet (rxPowerDbm " << WToDbm (event->GetRxPowerW ()) << ")");
2359
            m_endPlcpRxEvent = Simulator::Schedule (preambleAndHeaderDuration, &WifiPhy::StartReceivePacket, this,
2360
                                                    packet, txVector, mpdutype, event);
2361
            m_endRxEvent = Simulator::Schedule (rxDuration, &WifiPhy::EndReceive, this,
2362
                                                packet, preamble, mpdutype, event);
2363
            m_rxPreambleType = preamble;
2364
          }
2365
        break;
2366
      }
2331
    case WifiPhy::TX:
2367
    case WifiPhy::TX:
2332
      NS_LOG_DEBUG ("drop packet because already in Tx (power=" <<
2368
      NS_LOG_DEBUG ("drop packet because already in Tx (power=" <<
2333
                    rxPowerW << "W)");
2369
                    rxPowerW << "W)");
 Lines 2336-2342    Link Here 
2336
        {
2372
        {
2337
          //that packet will be noise _after_ the transmission of the
2373
          //that packet will be noise _after_ the transmission of the
2338
          //currently-transmitted packet.
2374
          //currently-transmitted packet.
2339
          goto maybeCcaBusy;
2375
          CalculateCcaBusyDuration ();
2340
        }
2376
        }
2341
      break;
2377
      break;
2342
    case WifiPhy::CCA_BUSY:
2378
    case WifiPhy::CCA_BUSY:
 Lines 2349-2355    Link Here 
2349
              m_mpdusNum = 0;
2385
              m_mpdusNum = 0;
2350
              NS_LOG_DEBUG ("drop packet because no PLCP preamble/header has been received");
2386
              NS_LOG_DEBUG ("drop packet because no PLCP preamble/header has been received");
2351
              NotifyRxDrop (packet);
2387
              NotifyRxDrop (packet);
2352
              goto maybeCcaBusy;
2388
              CalculateCcaBusyDuration ();
2353
            }
2389
            }
2354
          else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum == 0)
2390
          else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum == 0)
2355
            {
2391
            {
 Lines 2387-2392    Link Here 
2387
          NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
2423
          NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
2388
          NotifyRxBegin (packet);
2424
          NotifyRxBegin (packet);
2389
          m_interference.NotifyRxStart ();
2425
          m_interference.NotifyRxStart ();
2426
          m_rxPacket = packet;
2427
          m_rxPacketEvent = event;
2428
          m_rxPreambleType = preamble;
2390
2429
2391
          if (preamble != WIFI_PREAMBLE_NONE)
2430
          if (preamble != WIFI_PREAMBLE_NONE)
2392
            {
2431
            {
 Lines 2405-2411    Link Here 
2405
                        rxPowerW << "<" << GetEdThresholdW () << ")");
2444
                        rxPowerW << "<" << GetEdThresholdW () << ")");
2406
          NotifyRxDrop (packet);
2445
          NotifyRxDrop (packet);
2407
          m_plcpSuccess = false;
2446
          m_plcpSuccess = false;
2408
          goto maybeCcaBusy;
2447
          CalculateCcaBusyDuration ();
2409
        }
2448
        }
2410
      break;
2449
      break;
2411
    case WifiPhy::SLEEP:
2450
    case WifiPhy::SLEEP:
 Lines 2416-2428    Link Here 
2416
    }
2455
    }
2417
2456
2418
  return;
2457
  return;
2419
2458
}
2420
maybeCcaBusy:
2459
2421
  //We are here because we have received the first bit of a packet and we are
2460
void
2422
  //not going to be able to synchronize on it
2461
WifiPhy::CalculateCcaBusyDuration ()
2423
  //In this model, CCA becomes busy when the aggregation of all signals as
2462
{
2424
  //tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
2463
// maybeCcaBusy:
2425
2464
// We are here because we have received the first bit of a packet and we are
2465
// not going to be able to synchronize on it
2466
// In this model, CCA becomes busy when the aggregation of all signals as
2467
// tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
2426
  Time delayUntilCcaEnd = m_interference.GetEnergyDuration (DbmToW (GetCcaMode1Threshold ()));
2468
  Time delayUntilCcaEnd = m_interference.GetEnergyDuration (DbmToW (GetCcaMode1Threshold ()));
2427
  if (!delayUntilCcaEnd.IsZero ())
2469
  if (!delayUntilCcaEnd.IsZero ())
2428
    {
2470
    {
 Lines 2430-2435    Link Here 
2430
    }
2472
    }
2431
}
2473
}
2432
2474
2475
bool
2476
WifiPhy::CheckPreambleCapture (Ptr<Packet> packet, Ptr<InterferenceHelper::Event> event)
2477
{
2478
  NS_LOG_FUNCTION (this << packet << event);
2479
  NS_LOG_DEBUG (Simulator::Now () << ", preamble capture check: old reception event start at "
2480
                                  << m_rxPacketEvent->GetStartTime ()
2481
                                  << ", old preamble type " << m_rxPreambleType
2482
                                  << ", end at " << m_rxPacketEvent->GetEndTime ()
2483
                                  << ", old rxPower " << m_rxPacketEvent->GetRxPowerW ());
2484
  bool result = false;
2485
  Time endRx = event->GetEndTime ();
2486
  InterferenceHelper::SnrPer snrPer;
2487
  snrPer = m_interference.CalculatePlcpHeaderSnrPer (m_rxPacketEvent); // check whether the plcp header can still decoded
2488
  NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per);
2489
  if (m_random->GetValue () > snrPer.per)  // the reception of the old packet can be continued
2490
    {
2491
      NS_ASSERT (m_endPlcpRxEvent.IsRunning ());
2492
      NS_LOG_INFO (Simulator::Now () << " preamble capture check: dropping newly arrived packet"
2493
                                     << ", because already sync to a stronger enough signal");
2494
      NotifyRxDrop (packet);
2495
      if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
2496
        {
2497
          CalculateCcaBusyDuration ();
2498
        }
2499
    }
2500
  else // the reception of the old packet cannot be continued
2501
    {
2502
      NS_LOG_INFO (Simulator::Now () << " preamble capture check: dropping currently received packet");
2503
      AbortCurrentReception (m_rxPacket, snrPer.snr);
2504
2505
      NS_ASSERT (m_endPlcpRxEvent.IsExpired () && m_endRxEvent.IsExpired ());
2506
      NS_LOG_INFO (Simulator::Now () << " preamble capture check: switch to new packet");
2507
2508
      InterferenceHelper::SnrPer snrPerForNewPkt;
2509
      snrPerForNewPkt = m_interference.CalculatePlcpHeaderSnrPer (event);
2510
      double prob = m_interference.CalculatePreambleCaptureProbability (snrPerForNewPkt.snr);
2511
      if (m_random->GetValue () < prob)
2512
        {
2513
          SwitchReception (packet, event);
2514
          result = true;
2515
        }
2516
      else
2517
        {
2518
          NS_LOG_INFO (Simulator::Now () << " preamble capture: signal is too low for capture");
2519
          NotifyRxDrop (packet);
2520
          if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
2521
            {
2522
              CalculateCcaBusyDuration ();
2523
            }
2524
        }
2525
    }
2526
  return result;
2527
}
2528
2529
bool
2530
WifiPhy::CheckPayloadCapture (Ptr<Packet> packet, Ptr<InterferenceHelper::Event> event)
2531
{
2532
  NS_LOG_FUNCTION (this << packet << event);
2533
  NS_LOG_DEBUG (Simulator::Now () << ", payload capture check: old reception event start at "
2534
                                  << m_rxPacketEvent->GetStartTime ()
2535
                                  << ", end at " << m_rxPacketEvent->GetEndTime ()
2536
                                  << ", old rxPower " << m_rxPacketEvent->GetRxPowerW ());
2537
  bool result = false;
2538
  Time endRx = event->GetEndTime ();
2539
  InterferenceHelper::SnrPer snrPer;
2540
  snrPer = m_interference.CalculatePlcpPayloadSnrPer (m_rxPacketEvent); // check whether the plcp header can still decoded
2541
  NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per);
2542
  if (m_random->GetValue () > snrPer.per)  // the reception of the old packet can be continued
2543
    {
2544
      NS_ASSERT (m_endRxEvent.IsRunning ());
2545
      NS_LOG_INFO (Simulator::Now () << " payload capture check: dropping newly arrived packet"
2546
                                     << ", because already sync to a stronger enough signal");
2547
      NotifyRxDrop (packet);
2548
      if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
2549
        {
2550
          CalculateCcaBusyDuration ();
2551
        }
2552
    }
2553
  else // the reception of the old packet cannot be continued
2554
    {
2555
      NS_LOG_INFO (Simulator::Now () << " preamble capture check: dropping currently received packet");
2556
      AbortCurrentReception (m_rxPacket, snrPer.snr);
2557
2558
      NS_ASSERT (m_endPlcpRxEvent.IsExpired () && m_endRxEvent.IsExpired ());
2559
      NS_LOG_INFO (Simulator::Now () << " payload capture check: switch to new packet");
2560
2561
      InterferenceHelper::SnrPer snrPerForNewPkt;
2562
      snrPerForNewPkt = m_interference.CalculatePlcpPayloadSnrPer (event);
2563
      double prob = m_interference.CalculatePayloadCaptureProbability (snrPerForNewPkt.snr);
2564
      if (m_random->GetValue () < prob)
2565
        {
2566
          SwitchReception (packet, event);
2567
          result = true;
2568
        }
2569
      else
2570
        {
2571
          NS_LOG_INFO (Simulator::Now () << " payload capture: signal is too low for capture");
2572
          NotifyRxDrop (packet);
2573
          if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
2574
            {
2575
              CalculateCcaBusyDuration ();
2576
            }
2577
        }
2578
    }
2579
  return result;
2580
}
2581
2582
void
2583
WifiPhy::AbortCurrentReception (Ptr<Packet> packet, double sinr)
2584
{
2585
  NS_LOG_FUNCTION (this << packet << sinr);
2586
  if (m_endPlcpRxEvent.IsRunning ())
2587
    {
2588
      m_endPlcpRxEvent.Cancel ();
2589
    }
2590
  if (m_endRxEvent.IsRunning ())
2591
    {
2592
      m_endRxEvent.Cancel ();
2593
    }
2594
  m_interference.NotifyRxEnd ();
2595
  m_state->SwitchFromRxAbort (packet, sinr);
2596
  m_rxPacket = NULL;
2597
  m_rxPacketEvent = NULL;
2598
  m_rxPreambleType = WIFI_PREAMBLE_NONE;
2599
}
2600
2601
void
2602
WifiPhy::SwitchReception (Ptr<Packet> packet, Ptr<InterferenceHelper::Event> event)
2603
{
2604
  NS_LOG_FUNCTION (this << packet << event);
2605
  m_rxPacket = packet;
2606
  m_rxPacketEvent = event;
2607
  m_state->SwitchToRx (event->GetDuration ());
2608
  NotifyRxBegin (packet);
2609
  m_interference.NotifyRxStart ();
2610
}
2611
2433
void
2612
void
2434
WifiPhy::StartReceivePacket (Ptr<Packet> packet,
2613
WifiPhy::StartReceivePacket (Ptr<Packet> packet,
2435
                             WifiTxVector txVector,
2614
                             WifiTxVector txVector,
 Lines 2452-2457    Link Here 
2452
        {
2631
        {
2453
          NS_LOG_DEBUG ("receiving plcp payload"); //endReceive is already scheduled
2632
          NS_LOG_DEBUG ("receiving plcp payload"); //endReceive is already scheduled
2454
          m_plcpSuccess = true;
2633
          m_plcpSuccess = true;
2634
          NS_LOG_INFO ("decode plcp successfully (rxPowerDbm " << WToDbm (event->GetRxPowerW ()) << ")");
2455
        }
2635
        }
2456
      else //mode is not allowed
2636
      else //mode is not allowed
2457
        {
2637
        {
 Lines 2495-2500    Link Here 
2495
          aMpdu.mpduRefNumber = m_rxMpduReferenceNumber;
2675
          aMpdu.mpduRefNumber = m_rxMpduReferenceNumber;
2496
          NotifyMonitorSniffRx (packet, GetFrequency (), event->GetTxVector (), aMpdu, signalNoise);
2676
          NotifyMonitorSniffRx (packet, GetFrequency (), event->GetTxVector (), aMpdu, signalNoise);
2497
          m_state->SwitchFromRxEndOk (packet, snrPer.snr, event->GetTxVector ());
2677
          m_state->SwitchFromRxEndOk (packet, snrPer.snr, event->GetTxVector ());
2678
          NS_LOG_INFO ("decode payload successfully (rxPowerDbm " << WToDbm (event->GetRxPowerW ()) << ")");
2498
        }
2679
        }
2499
      else
2680
      else
2500
        {
2681
        {
 Lines 3311-3317    Link Here 
3311
WifiPhy::IsValidTxVector (WifiTxVector txVector)
3492
WifiPhy::IsValidTxVector (WifiTxVector txVector)
3312
{
3493
{
3313
  uint8_t chWidth = txVector.GetChannelWidth ();
3494
  uint8_t chWidth = txVector.GetChannelWidth ();
3314
  uint8_t nss = txVector.GetNss();
3495
  uint8_t nss = txVector.GetNss ();
3315
  std::string modeName = txVector.GetMode ().GetUniqueName ();
3496
  std::string modeName = txVector.GetMode ().GetUniqueName ();
3316
3497
3317
  if (chWidth == 20)
3498
  if (chWidth == 20)
(-)a/src/wifi/model/wifi-phy.h (-2 / +48 lines)
 Lines 1516-1522    Link Here 
1516
   */
1516
   */
1517
  virtual std::vector<uint8_t> GetSupportedChannelWidthSet (void) const;
1517
  virtual std::vector<uint8_t> GetSupportedChannelWidthSet (void) const;
1518
1518
1519
1520
protected:
1519
protected:
1521
  // Inherited
1520
  // Inherited
1522
  virtual void DoInitialize (void);
1521
  virtual void DoInitialize (void);
 Lines 1733-1739    Link Here 
1733
   * of its size.
1732
   * of its size.
1734
   */
1733
   */
1735
  TracedCallback<Ptr<const Packet>, uint16_t, WifiTxVector, MpduInfo> m_phyMonitorSniffTxTrace;
1734
  TracedCallback<Ptr<const Packet>, uint16_t, WifiTxVector, MpduInfo> m_phyMonitorSniffTxTrace;
1736
    
1735
1736
  /**
1737
   * Due to newly arrived signal, the old reception cannot be continued and has to be abort
1738
   *
1739
   * \param packet, the packet which has to be aborted
1740
   * \param sinr, the sinr of the aborted packet
1741
   */
1742
  void AbortCurrentReception (Ptr<Packet> packet, double sinr);
1743
1744
  /**
1745
   * Calculate the duration of CCA busy
1746
   */
1747
  void CalculateCcaBusyDuration (void);
1748
1749
  /**
1750
   * Check whether preamble capture can be triggered
1751
   *
1752
   * \param packet the newly arrived packet which needs to be check for capture
1753
   * \param event the receiving event associated with the receiving packet
1754
   *
1755
   * \return whether the capture, i.e., reception switching, has been successful
1756
   */
1757
  bool CheckPreambleCapture (Ptr<Packet> packet, Ptr<InterferenceHelper::Event> event);
1758
1759
  /**
1760
   * Check whether payload capture can be triggered
1761
   *
1762
   * \param packet the newly arrived packet which needs to be check for capture
1763
   * \param event the receiving event associated with the receiving packet
1764
   *
1765
   * \return whether the capture, i.e., reception switching, has been successful
1766
   */
1767
  bool CheckPayloadCapture (Ptr<Packet> packet, Ptr<InterferenceHelper::Event> event);
1768
1769
  /**
1770
   * The new packet passes the check and the receiver is going to switch to the new packet
1771
   *
1772
   * \param packet the packet will be switched to
1773
   * \param event receiving event associated with the packet
1774
   */
1775
  void SwitchReception (Ptr<Packet> packet, Ptr<InterferenceHelper::Event> event);
1776
1737
  /**
1777
  /**
1738
   * This vector holds the set of transmission modes that this
1778
   * This vector holds the set of transmission modes that this
1739
   * WifiPhy(-derived class) can support. In conversation we call this
1779
   * WifiPhy(-derived class) can support. In conversation we call this
 Lines 1816-1821    Link Here 
1816
  
1856
  
1817
  Ptr<NetDevice>     m_device;   //!< Pointer to the device
1857
  Ptr<NetDevice>     m_device;   //!< Pointer to the device
1818
  Ptr<MobilityModel> m_mobility; //!< Pointer to the mobility model
1858
  Ptr<MobilityModel> m_mobility; //!< Pointer to the mobility model
1859
1860
  Ptr<Packet> m_rxPacket;                         // The packet that is currently being received by the receiver
1861
  Ptr<InterferenceHelper::Event> m_rxPacketEvent; // The event that indicates the current receiving event
1862
  bool m_doPreambleCapture;                       // The flag indicates whether the capture at the preamble portion of the packet is enabled or not
1863
  bool m_doPayloadCapture;                        // The flag indicates whether the capture at the payload(data) portion of the packet is enabled or not
1864
  WifiPreamble m_rxPreambleType;                  // The preamble type of the currently receiving frame
1819
};
1865
};
1820
1866
1821
/**
1867
/**
(-)a/src/wifi/wscript (+2 lines)
 Lines 82-87    Link Here 
82
        'model/vht-operation.cc',
82
        'model/vht-operation.cc',
83
        'model/dsss-parameter-set.cc',
83
        'model/dsss-parameter-set.cc',
84
        'model/edca-parameter-set.cc',
84
        'model/edca-parameter-set.cc',
85
        'model/frame-capture-model.cc',
85
        'helper/wifi-radio-energy-model-helper.cc',
86
        'helper/wifi-radio-energy-model-helper.cc',
86
        'helper/vht-wifi-mac-helper.cc',
87
        'helper/vht-wifi-mac-helper.cc',
87
        'helper/ht-wifi-mac-helper.cc',
88
        'helper/ht-wifi-mac-helper.cc',
 Lines 188-193    Link Here 
188
        'model/vht-operation.h',
189
        'model/vht-operation.h',
189
        'model/dsss-parameter-set.h',
190
        'model/dsss-parameter-set.h',
190
        'model/edca-parameter-set.h',
191
        'model/edca-parameter-set.h',
192
        'model/frame-capture-model.h',
191
        'helper/wifi-radio-energy-model-helper.h',
193
        'helper/wifi-radio-energy-model-helper.h',
192
        'helper/vht-wifi-mac-helper.h',
194
        'helper/vht-wifi-mac-helper.h',
193
        'helper/ht-wifi-mac-helper.h',
195
        'helper/ht-wifi-mac-helper.h',

Return to bug 2368