A Discrete-Event Network Simulator
API
wave-helper.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 as
5  * published by the Free Software Foundation;
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15  *
16  * Author: Junling Bu <linlinjavaer@gmail.com>
17  */
18 #include "ns3/wifi-mac.h"
19 #include "ns3/wifi-phy.h"
20 #include "ns3/log.h"
21 #include "ns3/pointer.h"
22 #include "ns3/string.h"
23 #include "ns3/wifi-mode.h"
24 #include "ns3/config.h"
25 #include "ns3/names.h"
26 #include "ns3/abort.h"
27 #include "ns3/ampdu-subframe-header.h"
28 #include "ns3/wave-net-device.h"
29 #include "ns3/minstrel-wifi-manager.h"
30 #include "ns3/radiotap-header.h"
31 #include "ns3/unused.h"
32 #include "wave-mac-helper.h"
33 #include "wave-helper.h"
34 
35 NS_LOG_COMPONENT_DEFINE ("WaveHelper");
36 
37 namespace ns3 {
38 
39 static void
42  std::string context,
44  WifiMode mode,
45  WifiPreamble preamble,
46  uint8_t txLevel)
47 {
48  NS_LOG_FUNCTION (stream << context << p << mode << preamble << txLevel);
49  *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl;
50 }
51 
52 static void
56  WifiMode mode,
57  WifiPreamble preamble,
58  uint8_t txLevel)
59 {
60  NS_LOG_FUNCTION (stream << p << mode << preamble << txLevel);
61  *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
62 }
63 
64 static void
67  std::string context,
69  double snr,
70  WifiMode mode,
71  enum WifiPreamble preamble)
72 {
73  NS_LOG_FUNCTION (stream << context << p << snr << mode << preamble);
74  *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl;
75 }
76 
77 static void
81  double snr,
82  WifiMode mode,
83  enum WifiPreamble preamble)
84 {
85  NS_LOG_FUNCTION (stream << p << snr << mode << preamble);
86  *stream->GetStream () << "r " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
87 }
88 
89 static void
92  Ptr<const Packet> packet,
93  uint16_t channelFreqMhz,
94  uint16_t channelNumber,
95  uint32_t rate,
96  WifiPreamble preamble,
97  WifiTxVector txVector,
98  struct mpduInfo aMpdu)
99 {
100  uint32_t dlt = file->GetDataLinkType ();
101 
102  switch (dlt)
103  {
105  file->Write (Simulator::Now (), packet);
106  return;
108  {
109  NS_FATAL_ERROR ("PcapSniffTxEvent(): DLT_PRISM_HEADER not implemented");
110  return;
111  }
113  {
114  Ptr<Packet> p = packet->Copy ();
115  RadiotapHeader header;
116  uint8_t frameFlags = RadiotapHeader::FRAME_FLAG_NONE;
117  header.SetTsft (Simulator::Now ().GetMicroSeconds ());
118 
119  //Our capture includes the FCS, so we set the flag to say so.
121 
122  if (preamble == WIFI_PREAMBLE_SHORT)
123  {
125  }
126 
127  if (txVector.IsShortGuardInterval ())
128  {
130  }
131 
132  header.SetFrameFlags (frameFlags);
133  header.SetRate (rate);
134 
135  uint16_t channelFlags = 0;
136  switch (rate)
137  {
138  case 2: //1Mbps
139  case 4: //2Mbps
140  case 10: //5Mbps
141  case 22: //11Mbps
142  channelFlags |= RadiotapHeader::CHANNEL_FLAG_CCK;
143  break;
144 
145  default:
146  channelFlags |= RadiotapHeader::CHANNEL_FLAG_OFDM;
147  break;
148  }
149 
150  if (channelFreqMhz < 2500)
151  {
153  }
154  else
155  {
157  }
158 
159  header.SetChannelFrequencyAndFlags (channelFreqMhz, channelFlags);
160 
161  if (preamble == WIFI_PREAMBLE_HT_MF || preamble == WIFI_PREAMBLE_HT_GF || preamble == WIFI_PREAMBLE_NONE)
162  {
163  uint8_t mcsRate = 0;
164  uint8_t mcsKnown = RadiotapHeader::MCS_KNOWN_NONE;
165  uint8_t mcsFlags = RadiotapHeader::MCS_FLAGS_NONE;
166 
168  mcsRate = rate - 128;
169 
171  if (txVector.GetChannelWidth () == 40)
172  {
174  }
175 
177  if (txVector.IsShortGuardInterval ())
178  {
180  }
181 
183  if (preamble == WIFI_PREAMBLE_HT_GF)
184  {
186  }
187 
188  mcsKnown |= RadiotapHeader::MCS_KNOWN_NESS;
189  if (txVector.GetNess () & 0x01) //bit 1
190  {
192  }
193  if (txVector.GetNess () & 0x02) //bit 2
194  {
196  }
197 
198  mcsKnown |= RadiotapHeader::MCS_KNOWN_FEC_TYPE; //only BCC is currently supported
199 
200  mcsKnown |= RadiotapHeader::MCS_KNOWN_STBC;
201  if (txVector.IsStbc ())
202  {
204  }
205 
206  header.SetMcsFields (mcsKnown, mcsFlags, mcsRate);
207  }
208 
209  if (txVector.IsAggregation ())
210  {
211  uint16_t ampduStatusFlags = RadiotapHeader::A_MPDU_STATUS_NONE;
212  ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST_KNOWN;
213  /* For PCAP file, MPDU Delimiter and Padding should be removed by the MAC Driver */
215  uint32_t extractedLength;
216  p->RemoveHeader (hdr);
217  extractedLength = hdr.GetLength ();
218  p = p->CreateFragment (0, static_cast<uint32_t> (extractedLength));
219  if (aMpdu.type == LAST_MPDU_IN_AGGREGATE || (hdr.GetEof () == true && hdr.GetLength () > 0))
220  {
221  ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST;
222  }
223  header.SetAmpduStatus (aMpdu.mpduRefNumber, ampduStatusFlags, hdr.GetCrc ());
224  }
225 
226  if (preamble == WIFI_PREAMBLE_VHT)
227  {
228  uint16_t vhtKnown = RadiotapHeader::VHT_KNOWN_NONE;
229  uint8_t vhtFlags = RadiotapHeader::VHT_FLAGS_NONE;
230  uint8_t vhtBandwidth = 0;
231  uint8_t vhtMcsNss[4] = {0,0,0,0};
232  uint8_t vhtCoding = 0;
233  uint8_t vhtGroupId = 0;
234  uint16_t vhtPartialAid = 0;
235 
236  vhtKnown |= RadiotapHeader::VHT_KNOWN_STBC;
237  if (txVector.IsStbc ())
238  {
239  vhtFlags |= RadiotapHeader::VHT_FLAGS_STBC;
240  }
241 
243  if (txVector.IsShortGuardInterval ())
244  {
246  }
247 
248  vhtKnown |= RadiotapHeader::VHT_KNOWN_BEAMFORMED; //Beamforming is currently not supported
249 
251  //not all bandwidth values are currently supported
252  if (txVector.GetChannelWidth () == 40)
253  {
254  vhtBandwidth = 1;
255  }
256  else if (txVector.GetChannelWidth () == 80)
257  {
258  vhtBandwidth = 4;
259  }
260  else if (txVector.GetChannelWidth () == 160)
261  {
262  vhtBandwidth = 11;
263  }
264 
265  //only SU PPDUs are currently supported
266  vhtMcsNss[0] |= (txVector.GetNss () & 0x0f);
267  vhtMcsNss[0] |= (((rate - 128) << 4) & 0xf0);
268 
269  header.SetVhtFields (vhtKnown, vhtFlags, vhtBandwidth, vhtMcsNss, vhtCoding, vhtGroupId, vhtPartialAid);
270  }
271 
272  p->AddHeader (header);
273  file->Write (Simulator::Now (), p);
274  return;
275  }
276  default:
277  NS_ABORT_MSG ("PcapSniffTxEvent(): Unexpected data link type " << dlt);
278  }
279 }
280 
281 static void
284  Ptr<const Packet> packet,
285  uint16_t channelFreqMhz,
286  uint16_t channelNumber,
287  uint32_t rate,
288  WifiPreamble preamble,
289  WifiTxVector txVector,
290  struct mpduInfo aMpdu,
291  struct signalNoiseDbm signalNoise)
292 {
293  uint32_t dlt = file->GetDataLinkType ();
294 
295  switch (dlt)
296  {
298  file->Write (Simulator::Now (), packet);
299  return;
301  {
302  NS_FATAL_ERROR ("PcapSniffRxEvent(): DLT_PRISM_HEADER not implemented");
303  return;
304  }
306  {
307  Ptr<Packet> p = packet->Copy ();
308  RadiotapHeader header;
309  uint8_t frameFlags = RadiotapHeader::FRAME_FLAG_NONE;
310  header.SetTsft (Simulator::Now ().GetMicroSeconds ());
311 
312  //Our capture includes the FCS, so we set the flag to say so.
314 
315  if (preamble == WIFI_PREAMBLE_SHORT)
316  {
318  }
319 
320  if (txVector.IsShortGuardInterval ())
321  {
323  }
324 
325  header.SetFrameFlags (frameFlags);
326  header.SetRate (rate);
327 
328  uint16_t channelFlags = 0;
329  switch (rate)
330  {
331  case 2: //1Mbps
332  case 4: //2Mbps
333  case 10: //5Mbps
334  case 22: //11Mbps
335  channelFlags |= RadiotapHeader::CHANNEL_FLAG_CCK;
336  break;
337 
338  default:
339  channelFlags |= RadiotapHeader::CHANNEL_FLAG_OFDM;
340  break;
341  }
342 
343  if (channelFreqMhz < 2500)
344  {
346  }
347  else
348  {
350  }
351 
352  header.SetChannelFrequencyAndFlags (channelFreqMhz, channelFlags);
353 
354  header.SetAntennaSignalPower (signalNoise.signal);
355  header.SetAntennaNoisePower (signalNoise.noise);
356 
357  if (preamble == WIFI_PREAMBLE_HT_MF || preamble == WIFI_PREAMBLE_HT_GF || preamble == WIFI_PREAMBLE_NONE)
358  {
359  uint8_t mcsRate = 0;
360  uint8_t mcsKnown = RadiotapHeader::MCS_KNOWN_NONE;
361  uint8_t mcsFlags = RadiotapHeader::MCS_FLAGS_NONE;
362 
364  mcsRate = rate - 128;
365 
367  if (txVector.GetChannelWidth () == 40)
368  {
370  }
371 
373  if (txVector.IsShortGuardInterval ())
374  {
376  }
377 
379  if (preamble == WIFI_PREAMBLE_HT_GF)
380  {
382  }
383 
384  mcsKnown |= RadiotapHeader::MCS_KNOWN_NESS;
385  if (txVector.GetNess () & 0x01) //bit 1
386  {
388  }
389  if (txVector.GetNess () & 0x02) //bit 2
390  {
392  }
393 
394  mcsKnown |= RadiotapHeader::MCS_KNOWN_FEC_TYPE; //only BCC is currently supported
395 
396  mcsKnown |= RadiotapHeader::MCS_KNOWN_STBC;
397  if (txVector.IsStbc ())
398  {
400  }
401 
402  header.SetMcsFields (mcsKnown, mcsFlags, mcsRate);
403  }
404 
405  if (txVector.IsAggregation ())
406  {
407  uint16_t ampduStatusFlags = RadiotapHeader::A_MPDU_STATUS_NONE;
409  ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST_KNOWN;
410  /* For PCAP file, MPDU Delimiter and Padding should be removed by the MAC Driver */
412  uint32_t extractedLength;
413  p->RemoveHeader (hdr);
414  extractedLength = hdr.GetLength ();
415  p = p->CreateFragment (0, static_cast<uint32_t> (extractedLength));
416  if (aMpdu.type == LAST_MPDU_IN_AGGREGATE || (hdr.GetEof () == true && hdr.GetLength () > 0))
417  {
418  ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST;
419  }
420  header.SetAmpduStatus (aMpdu.mpduRefNumber, ampduStatusFlags, hdr.GetCrc ());
421  }
422 
423  if (preamble == WIFI_PREAMBLE_VHT)
424  {
425  uint16_t vhtKnown = RadiotapHeader::VHT_KNOWN_NONE;
426  uint8_t vhtFlags = RadiotapHeader::VHT_FLAGS_NONE;
427  uint8_t vhtBandwidth = 0;
428  uint8_t vhtMcsNss[4] = {0,0,0,0};
429  uint8_t vhtCoding = 0;
430  uint8_t vhtGroupId = 0;
431  uint16_t vhtPartialAid = 0;
432 
433  vhtKnown |= RadiotapHeader::VHT_KNOWN_STBC;
434  if (txVector.IsStbc ())
435  {
436  vhtFlags |= RadiotapHeader::VHT_FLAGS_STBC;
437  }
438 
440  if (txVector.IsShortGuardInterval ())
441  {
443  }
444 
445  vhtKnown |= RadiotapHeader::VHT_KNOWN_BEAMFORMED; //Beamforming is currently not supported
446 
448  //not all bandwidth values are currently supported
449  if (txVector.GetChannelWidth () == 40)
450  {
451  vhtBandwidth = 1;
452  }
453  else if (txVector.GetChannelWidth () == 80)
454  {
455  vhtBandwidth = 4;
456  }
457  else if (txVector.GetChannelWidth () == 160)
458  {
459  vhtBandwidth = 11;
460  }
461 
462  //only SU PPDUs are currently supported
463  vhtMcsNss[0] |= (txVector.GetNss () & 0x0f);
464  vhtMcsNss[0] |= (((rate - 128) << 4) & 0xf0);
465 
466  header.SetVhtFields (vhtKnown, vhtFlags, vhtBandwidth, vhtMcsNss, vhtCoding, vhtGroupId, vhtPartialAid);
467  }
468 
469  p->AddHeader (header);
470  file->Write (Simulator::Now (), p);
471  return;
472  }
473  default:
474  NS_ABORT_MSG ("PcapSniffRxEvent(): Unexpected data link type " << dlt);
475  }
476 }
477 
478 /****************************** YansWavePhyHelper ***********************************/
479 YansWavePhyHelper
481 {
482  YansWavePhyHelper helper;
483  helper.SetErrorRateModel ("ns3::NistErrorRateModel");
484  return helper;
485 }
486 
487 void
488 YansWavePhyHelper::EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous, bool explicitFilename)
489 {
490  //
491  // All of the Pcap enable functions vector through here including the ones
492  // that are wandering through all of devices on perhaps all of the nodes in
493  // the system. We can only deal with devices of type WaveNetDevice.
494  //
495  Ptr<WaveNetDevice> device = nd->GetObject<WaveNetDevice> ();
496  if (device == 0)
497  {
498  NS_LOG_INFO ("YansWavePhyHelper::EnablePcapInternal(): Device " << &device << " not of type ns3::WaveNetDevice");
499  return;
500  }
501 
502  std::vector<Ptr<WifiPhy> > phys = device->GetPhys ();
503  NS_ABORT_MSG_IF (phys.size () == 0, "EnablePcapInternal(): Phy layer in WaveNetDevice must be set");
504 
505  PcapHelper pcapHelper;
506 
507  std::string filename;
508  if (explicitFilename)
509  {
510  filename = prefix;
511  }
512  else
513  {
514  filename = pcapHelper.GetFilenameFromDevice (prefix, device);
515  }
516 
517  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out, GetPcapDataLinkType ());
518 
519  std::vector<Ptr<WifiPhy> >::iterator i;
520  for (i = phys.begin (); i != phys.end (); ++i)
521  {
522  Ptr<WifiPhy> phy = (*i);
523  phy->TraceConnectWithoutContext ("MonitorSnifferTx", MakeBoundCallback (&PcapSniffTxEvent, file));
524  phy->TraceConnectWithoutContext ("MonitorSnifferRx", MakeBoundCallback (&PcapSniffRxEvent, file));
525  }
526 }
527 
528 void
531  std::string prefix,
532  Ptr<NetDevice> nd,
533  bool explicitFilename)
534 {
535  //
536  // All of the ascii enable functions vector through here including the ones
537  // that are wandering through all of devices on perhaps all of the nodes in
538  // the system. We can only deal with devices of type WaveNetDevice.
539  //
540  Ptr<WaveNetDevice> device = nd->GetObject<WaveNetDevice> ();
541  if (device == 0)
542  {
543  NS_LOG_INFO ("EnableAsciiInternal(): Device " << device << " not of type ns3::WaveNetDevice");
544  return;
545  }
546 
547  //
548  // Our trace sinks are going to use packet printing, so we have to make sure
549  // that is turned on.
550  //
552 
553  uint32_t nodeid = nd->GetNode ()->GetId ();
554  uint32_t deviceid = nd->GetIfIndex ();
555  std::ostringstream oss;
556 
557  //
558  // If we are not provided an OutputStreamWrapper, we are expected to create
559  // one using the usual trace filename conventions and write our traces
560  // without a context since there will be one file per context and therefore
561  // the context would be redundant.
562  //
563  if (stream == 0)
564  {
565  //
566  // Set up an output stream object to deal with private ofstream copy
567  // constructor and lifetime issues. Let the helper decide the actual
568  // name of the file given the prefix.
569  //
570  AsciiTraceHelper asciiTraceHelper;
571 
572  std::string filename;
573  if (explicitFilename)
574  {
575  filename = prefix;
576  }
577  else
578  {
579  filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device);
580  }
581 
582  Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);
583  //
584  // We could go poking through the phy and the state looking for the
585  // correct trace source, but we can let Config deal with that with
586  // some search cost. Since this is presumably happening at topology
587  // creation time, it doesn't seem much of a price to pay.
588  //
589  oss.str ("");
590  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WaveNetDevice/PhyEntities/*/$ns3::WifiPhy/State/RxOk";
592 
593  oss.str ("");
594  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WaveNetDevice/PhyEntities/*/$ns3::WifiPhy/State/Tx";
596 
597  return;
598  }
599 
600  //
601  // If we are provided an OutputStreamWrapper, we are expected to use it, and
602  // to provide a context. We are free to come up with our own context if we
603  // want, and use the AsciiTraceHelper Hook*WithContext functions, but for
604  // compatibility and simplicity, we just use Config::Connect and let it deal
605  // with coming up with a context.
606  //
607  oss.str ("");
608  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WaveNetDevice/PhyEntities/*/$ns3::WifiPhy/RxOk";
610 
611  oss.str ("");
612  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WaveNetDevice/PhyEntities/*/$ns3::WifiPhy/State/Tx";
614 }
615 
616 /********************************** WaveHelper ******************************************/
618 {
619 }
620 
622 {
623 }
624 
627 {
628  WaveHelper helper;
629  // default 7 MAC entities and single PHY device.
631  helper.CreatePhys (1);
632  helper.SetChannelScheduler ("ns3::DefaultChannelScheduler");
633  helper.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
634  "DataMode", StringValue ("OfdmRate6MbpsBW10MHz"),
635  "ControlMode",StringValue ("OfdmRate6MbpsBW10MHz"),
636  "NonUnicastMode", StringValue ("OfdmRate6MbpsBW10MHz"));
637  return helper;
638 }
639 
640 void
641 WaveHelper::CreateMacForChannel (std::vector<uint32_t> channelNumbers)
642 {
643  if (channelNumbers.size () == 0)
644  {
645  NS_FATAL_ERROR ("the WAVE MAC entities is at least one");
646  }
647  for (std::vector<uint32_t>::iterator i = channelNumbers.begin (); i != channelNumbers.end (); ++i)
648  {
650  {
651  NS_FATAL_ERROR ("the channel number " << (*i) << " is not a valid WAVE channel number");
652  }
653  }
654  m_macsForChannelNumber = channelNumbers;
655 }
656 
657 void
658 WaveHelper::CreatePhys (uint32_t phys)
659 {
660  if (phys == 0)
661  {
662  NS_FATAL_ERROR ("the WAVE PHY entities is at least one");
663  }
665  {
666  NS_FATAL_ERROR ("the number of assigned WAVE PHY entities is more than the number of valid WAVE channels");
667  }
668  m_physNumber = phys;
669 }
670 
671 void
673  std::string n0, const AttributeValue &v0,
674  std::string n1, const AttributeValue &v1,
675  std::string n2, const AttributeValue &v2,
676  std::string n3, const AttributeValue &v3,
677  std::string n4, const AttributeValue &v4,
678  std::string n5, const AttributeValue &v5,
679  std::string n6, const AttributeValue &v6,
680  std::string n7, const AttributeValue &v7)
681 {
684  m_stationManager.Set (n0, v0);
685  m_stationManager.Set (n1, v1);
686  m_stationManager.Set (n2, v2);
687  m_stationManager.Set (n3, v3);
688  m_stationManager.Set (n4, v4);
689  m_stationManager.Set (n5, v5);
690  m_stationManager.Set (n6, v6);
691  m_stationManager.Set (n7, v7);
692 }
693 
694 void
696  std::string n0, const AttributeValue &v0,
697  std::string n1, const AttributeValue &v1,
698  std::string n2, const AttributeValue &v2,
699  std::string n3, const AttributeValue &v3,
700  std::string n4, const AttributeValue &v4,
701  std::string n5, const AttributeValue &v5,
702  std::string n6, const AttributeValue &v6,
703  std::string n7, const AttributeValue &v7)
704 {
707  m_channelScheduler.Set (n0, v0);
708  m_channelScheduler.Set (n1, v1);
709  m_channelScheduler.Set (n2, v2);
710  m_channelScheduler.Set (n3, v3);
711  m_channelScheduler.Set (n4, v4);
712  m_channelScheduler.Set (n5, v5);
713  m_channelScheduler.Set (n6, v6);
714  m_channelScheduler.Set (n7, v7);
715 }
716 
718 WaveHelper::Install (const WifiPhyHelper &phyHelper, const WifiMacHelper &macHelper, NodeContainer c) const
719 {
720  try
721  {
722  const QosWaveMacHelper& qosMac = dynamic_cast<const QosWaveMacHelper&> (macHelper);
723  NS_UNUSED (qosMac);
724  }
725  catch (const std::bad_cast &)
726  {
727  NS_FATAL_ERROR ("WifiMacHelper should be the class or subclass of QosWaveMacHelper");
728  }
729 
731  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
732  {
733  Ptr<Node> node = *i;
734  Ptr<WaveNetDevice> device = CreateObject<WaveNetDevice> ();
735 
736  device->SetChannelManager (CreateObject<ChannelManager> ());
737  device->SetChannelCoordinator (CreateObject<ChannelCoordinator> ());
738  device->SetVsaManager (CreateObject<VsaManager> ());
740 
741  for (uint32_t j = 0; j != m_physNumber; ++j)
742  {
743  Ptr<WifiPhy> phy = phyHelper.Create (node, device);
746  device->AddPhy (phy);
747  }
748 
749  for (std::vector<uint32_t>::const_iterator k = m_macsForChannelNumber.begin ();
750  k != m_macsForChannelNumber.end (); ++k)
751  {
752  Ptr<WifiMac> wifiMac = macHelper.Create ();
753  Ptr<OcbWifiMac> ocbMac = DynamicCast<OcbWifiMac> (wifiMac);
754  // we use WaveMacLow to replace original MacLow
755  ocbMac->EnableForWave (device);
758  device->AddMac (*k, ocbMac);
759  }
760 
761  device->SetAddress (Mac48Address::Allocate ());
762 
763  node->AddDevice (device);
764  devices.Add (device);
765  }
766  return devices;
767 }
768 
771 {
772  return Install (phy, mac, NodeContainer (node));
773 }
774 
776 WaveHelper::Install (const WifiPhyHelper &phy, const WifiMacHelper &mac, std::string nodeName) const
777 {
778  Ptr<Node> node = Names::Find<Node> (nodeName);
779  return Install (phy, mac, NodeContainer (node));
780 }
781 
782 void
784 {
786 
787  LogComponentEnable ("WaveNetDevice", LOG_LEVEL_ALL);
788  LogComponentEnable ("ChannelCoordinator", LOG_LEVEL_ALL);
789  LogComponentEnable ("ChannelManager", LOG_LEVEL_ALL);
790  LogComponentEnable ("ChannelScheduler", LOG_LEVEL_ALL);
791  LogComponentEnable ("DefaultChannelScheduler", LOG_LEVEL_ALL);
792  LogComponentEnable ("VsaManager", LOG_LEVEL_ALL);
793  LogComponentEnable ("OcbWifiMac", LOG_LEVEL_ALL);
794  LogComponentEnable ("VendorSpecificAction", LOG_LEVEL_ALL);
795  LogComponentEnable ("WaveMacLow", LOG_LEVEL_ALL);
796  LogComponentEnable ("HigherLayerTxVectorTag", LOG_LEVEL_ALL);
797 }
798 
799 int64_t
801 {
802  int64_t currentStream = stream;
803  Ptr<NetDevice> netDevice;
804  for (NetDeviceContainer::Iterator i = c.Begin (); i != c.End (); ++i)
805  {
806  netDevice = (*i);
807  Ptr<WaveNetDevice> wave = DynamicCast<WaveNetDevice> (netDevice);
808  if (wave)
809  {
810  // Handle any random numbers in the PHY objects.
811  std::vector<Ptr<WifiPhy> > phys = wave->GetPhys ();
812  for (std::vector<Ptr<WifiPhy> >::iterator j = phys.begin (); j != phys.end (); ++i)
813  {
814  currentStream += (*j)->AssignStreams (currentStream);
815  }
816 
817  // Handle any random numbers in the MAC objects.
818  std::map<uint32_t, Ptr<OcbWifiMac> > macs = wave->GetMacs ();
819  for ( std::map<uint32_t, Ptr<OcbWifiMac> >::iterator k = macs.begin (); k != macs.end (); ++k)
820  {
821  Ptr<RegularWifiMac> rmac = DynamicCast<RegularWifiMac> (k->second);
822 
823  // Handle any random numbers in the station managers.
824  Ptr<WifiRemoteStationManager> manager = rmac->GetWifiRemoteStationManager ();
825  Ptr<MinstrelWifiManager> minstrel = DynamicCast<MinstrelWifiManager> (manager);
826  if (minstrel)
827  {
828  currentStream += minstrel->AssignStreams (currentStream);
829  }
830 
831  PointerValue ptr;
832  rmac->GetAttribute ("DcaTxop", ptr);
833  Ptr<DcaTxop> dcaTxop = ptr.Get<DcaTxop> ();
834  currentStream += dcaTxop->AssignStreams (currentStream);
835 
836  rmac->GetAttribute ("VO_EdcaTxopN", ptr);
837  Ptr<EdcaTxopN> vo_edcaTxopN = ptr.Get<EdcaTxopN> ();
838  currentStream += vo_edcaTxopN->AssignStreams (currentStream);
839 
840  rmac->GetAttribute ("VI_EdcaTxopN", ptr);
841  Ptr<EdcaTxopN> vi_edcaTxopN = ptr.Get<EdcaTxopN> ();
842  currentStream += vi_edcaTxopN->AssignStreams (currentStream);
843 
844  rmac->GetAttribute ("BE_EdcaTxopN", ptr);
845  Ptr<EdcaTxopN> be_edcaTxopN = ptr.Get<EdcaTxopN> ();
846  currentStream += be_edcaTxopN->AssignStreams (currentStream);
847 
848  rmac->GetAttribute ("BK_EdcaTxopN", ptr);
849  Ptr<EdcaTxopN> bk_edcaTxopN = ptr.Get<EdcaTxopN> ();
850  currentStream += bk_edcaTxopN->AssignStreams (currentStream);
851  }
852  }
853  }
854  return (currentStream - stream);
855 }
856 } // namespace ns3
uint16_t GetLength(void) const
Return the length field.
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
uint32_t GetPcapDataLinkType(void) const
Get the data link type of PCAP traces to be used.
static void EnableLogComponents(void)
Helper to enable all WaveNetDevice log components with one statement.
Definition: wave-helper.cc:783
Iterator Begin(void) const
Get an iterator which refers to the first NetDevice in the container.
void CreateMacForChannel(std::vector< uint32_t > channelNumbers)
Definition: wave-helper.cc:641
ObjectFactory m_channelScheduler
Definition: wave-helper.h:246
Ptr< T > Get(void) const
Definition: pointer.h:194
Manage ASCII trace files for device models.
Definition: trace-helper.h:155
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
static std::vector< uint32_t > GetWaveChannels(void)
void SetErrorRateModel(std::string name, std::string n0="", const AttributeValue &v0=EmptyAttributeValue(), std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue())
tuple devices
Definition: first.py:32
virtual void ConfigureStandard(enum WifiPhyStandard standard)=0
Configure the PHY-level parameters for different Wi-Fi standard.
int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used by the Phy and Mac aspects ...
Definition: wave-helper.cc:800
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
bool IsAggregation(void) const
Checks whether the PSDU contains A-MPDU.
static void AsciiPhyReceiveSinkWithoutContext(Ptr< OutputStreamWrapper > stream, Ptr< const Packet > p, double snr, WifiMode mode, enum WifiPreamble preamble)
Definition: wave-helper.cc:78
virtual void SetWifiRemoteStationManager(Ptr< WifiRemoteStationManager > stationManager)
std::vector< Ptr< Node > >::const_iterator Iterator
Node container iterator.
Radiotap header implementation.
Hold variables of type string.
Definition: string.h:41
Hold a value for an Attribute.
Definition: attribute.h:68
enum mpduType type
Definition: wifi-phy.h:63
Manage pcap files for device models.
Definition: trace-helper.h:38
create PHY objects
Definition: wifi-helper.h:47
void Write(Time t, Ptr< const Packet > p)
Write the next packet to file.
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
Definition: callback.h:1677
void ConfigureStandard(enum WifiPhyStandard standard)
Definition: wifi-mac.cc:290
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
static bool IsWaveChannel(uint32_t channelNumber)
This frame is the last subframe.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
bool IsShortGuardInterval(void) const
#define NS_UNUSED(x)
Mark a local variable as unused.
Definition: unused.h:36
OFDM PHY for the 5 GHz band (Clause 17 with 10 MHz channel bandwidth)
This class holds together multiple, ns3::WifiPhy, and ns3::OcbWifiMac (including ns3::WifiRemoteStati...
Iterator End(void) const
Get an iterator which indicates past-the-last Node in the container.
static void AsciiPhyReceiveSinkWithContext(Ptr< OutputStreamWrapper > stream, std::string context, Ptr< const Packet > p, double snr, WifiMode mode, enum WifiPreamble preamble)
Definition: wave-helper.cc:65
static WaveHelper Default(void)
Definition: wave-helper.cc:626
void EnableForWave(Ptr< WaveNetDevice > device)
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:145
Ptr< OutputStreamWrapper > CreateFileStream(std::string filename, std::ios::openmode filemode=std::ios::out)
Create and initialize an output stream object we'll use to write the traced bits. ...
void SetAntennaNoisePower(double noise)
Set the RF noise power at the antenna as a decibel difference from an arbitrary, fixed reference...
std::string GetFilenameFromDevice(std::string prefix, Ptr< NetDevice > device, bool useObjectNames=true)
Let the ascii trace helper figure out a reasonable filename to use for an ascii trace file associated...
virtual NetDeviceContainer Install(const WifiPhyHelper &phy, const WifiMacHelper &mac, NodeContainer c) const
Definition: wave-helper.cc:718
void SetTsft(uint64_t tsft)
Set the Time Synchronization Function Timer (TSFT) value.
virtual void SetAddress(Address address)
Set the address of this interface.
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:99
Set if all spatial streams of all users have space-time block coding.
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
Definition: wifi-preamble.h:30
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
Definition: packet.cc:228
Frame sent/received with short preamble.
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
void SetRemoteStationManager(std::string type, std::string n0="", const AttributeValue &v0=EmptyAttributeValue(), std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue())
Definition: wave-helper.cc:672
This queue contains packets for a particular access class.
Definition: edca-txop-n.h:85
static uint32_t GetNumberOfWaveChannels(void)
std::string GetFilenameFromDevice(std::string prefix, Ptr< NetDevice > device, bool useObjectNames=true)
Let the pcap helper figure out a reasonable filename to use for a pcap file associated with a device...
Definition: trace-helper.cc:80
uint32_t GetDataLinkType(void)
Returns the data link type field of the pcap file as defined by the network field in the pcap global ...
std::vector< uint32_t > m_macsForChannelNumber
Definition: wave-helper.h:247
void LogComponentEnable(char const *name, enum LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:351
tuple phy
Definition: third.py:86
static Mac48Address Allocate(void)
Allocate a new Mac48Address.
static void EnablePrinting(void)
Enable printing packets metadata.
Definition: packet.cc:535
virtual void EnablePcapInternal(std::string prefix, Ptr< NetDevice > nd, bool promiscuous, bool explicitFilename)
Enable pcap output the indicated net device.
Definition: wave-helper.cc:488
uint32_t mpduRefNumber
Definition: wifi-phy.h:64
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
void SetChannelScheduler(Ptr< ChannelScheduler > channelScheduler)
helps to create WaveNetDevice objects
Definition: wave-helper.h:110
void SetChannelFrequencyAndFlags(uint16_t frequency, uint16_t flags)
Set the transmit/receive channel frequency and flags.
virtual ~WaveHelper()
Definition: wave-helper.cc:621
void SetChannelManager(Ptr< ChannelManager > channelManager)
holds a vector of ns3::NetDevice pointers
uint8_t GetNess(void) const
uint32_t GetChannelWidth(void) const
uint8_t GetCrc(void) const
Return the CRC field.
Introspection did not find any typical Config paths.
void SetChannelScheduler(std::string type, std::string n0="", const AttributeValue &v0=EmptyAttributeValue(), std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue())
Definition: wave-helper.cc:695
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:824
Ness known (Number of extension spatial streams)
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
Beamformed known/applicable (this flag should be set to zero for MU PPDUs).
tuple mac
Definition: third.py:92
bool IsStbc(void) const
Check if STBC is used or not.
hold a list of per-remote-station state.
virtual void EnableAsciiInternal(Ptr< OutputStreamWrapper > stream, std::string prefix, Ptr< NetDevice > nd, bool explicitFilename)
Enable ascii trace output on the indicated net device.
Definition: wave-helper.cc:529
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:835
void SetFrameFlags(uint8_t flags)
Set the frame flags of the transmitted or received frame.
Ness data - bit 1 (MSB) of Number of extension spatial streams.
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
void SetRate(uint8_t rate)
Set the transmit/receive channel frequency in units of megahertz.
Space-time block coding (1 if all spatial streams of all users have STBC, 0 otherwise).
static void PcapSniffRxEvent(Ptr< PcapFileWrapper > file, Ptr< const Packet > packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, WifiPreamble preamble, WifiTxVector txVector, struct mpduInfo aMpdu, struct signalNoiseDbm signalNoise)
Definition: wave-helper.cc:282
static uint32_t GetCch(void)
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:299
std::map< uint32_t, Ptr< OcbWifiMac > > GetMacs(void) const
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
Hold objects of type Ptr.
Definition: pointer.h:36
void CreatePhys(uint32_t phys)
Definition: wave-helper.cc:658
Iterator Begin(void) const
Get an iterator which refers to the first Node in the container.
Delimiter CRC value known: the delimiter CRC value field is valid.
Frame used short guard interval (HT)
Last subframe is known (should be set for all subframes in an A-MPDU)
void SetMcsFields(uint8_t known, uint8_t flags, uint8_t mcs)
Set the MCS fields.
void Set(std::string name, const AttributeValue &value)
Set an attribute to be set during construction.
create MAC layers for a ns3::WifiNetDevice.
To trace WaveNetDevice, we have to overwrite the trace functions of class YansWifiPhyHelper.
Definition: wave-helper.h:39
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:223
virtual void SetChannelNumber(uint16_t id)=0
Set channel number.
virtual Ptr< WifiMac > Create(void) const
std::vector< Ptr< WifiPhy > > GetPhys(void) const
void AddPhy(Ptr< WifiPhy > phy)
ObjectFactory m_stationManager
Definition: wave-helper.h:245
void SetVhtFields(uint16_t known, uint8_t flags, uint8_t bandwidth, uint8_t mcs_nss[4], uint8_t coding, uint8_t group_id, uint16_t partial_aid)
Set the VHT fields.
Instantiate subclasses of ns3::Object.
static void EnableLogComponents(void)
Helper to enable all WifiNetDevice log components with one statement.
Definition: wifi-helper.cc:140
uint8_t GetNss(void) const
virtual Ptr< WifiPhy > Create(Ptr< Node > node, Ptr< NetDevice > device) const =0
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:128
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
static YansWavePhyHelper Default(void)
Create a phy helper in a default working state.
Definition: wave-helper.cc:480
void SetVsaManager(Ptr< VsaManager > vsaManager)
std::vector< Ptr< NetDevice > >::const_iterator Iterator
NetDevice container iterator.
void AddMac(uint32_t channelNumber, Ptr< OcbWifiMac > mac)
Default: 20 MHz, long guard interval, mixed HT format and BCC FEC type.
Print everything.
Definition: log.h:112
static void PcapSniffTxEvent(Ptr< PcapFileWrapper > file, Ptr< const Packet > packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, WifiPreamble preamble, WifiTxVector txVector, struct mpduInfo aMpdu)
Definition: wave-helper.cc:90
Ness - bit 0 (LSB) of Number of extension spatial streams.
void SetChannelCoordinator(Ptr< ChannelCoordinator > channelCoordinator)
Iterator End(void) const
Get an iterator which indicates past-the-last NetDevice in the container.
handle packet fragmentation and retransmissions.
Definition: dca-txop.h:67
void SetAmpduStatus(uint32_t referenceNumber, uint16_t flags, uint8_t crc)
Set the A-MPDU status fields.
bool GetEof(void) const
Return the EOF field.
static void AsciiPhyTransmitSinkWithContext(Ptr< OutputStreamWrapper > stream, std::string context, Ptr< const Packet > p, WifiMode mode, WifiPreamble preamble, uint8_t txLevel)
Definition: wave-helper.cc:40
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:257
This class will assign channel access for requests from higher layers.
uint32_t m_physNumber
Definition: wave-helper.h:248
void SetAntennaSignalPower(double signal)
Set the RF signal power at the antenna as a decibel difference from an arbitrary, fixed reference...
The MPDU is the last aggregate in an A-MPDU.
Definition: wifi-phy.h:52
static void AsciiPhyTransmitSinkWithoutContext(Ptr< OutputStreamWrapper > stream, Ptr< const Packet > p, WifiMode mode, WifiPreamble preamble, uint8_t txLevel)
Definition: wave-helper.cc:53