A Discrete-Event Network Simulator
API
simple-ofdm-wimax-phy.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007,2008, 2009 INRIA, UDcast
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
18  * <amine.ismail@udcast.com>
19  */
20 
21 #include "simple-ofdm-wimax-phy.h"
22 
24 #include "wimax-channel.h"
25 #include "wimax-mac-header.h"
26 #include "wimax-net-device.h"
27 
28 #include "ns3/double.h"
29 #include "ns3/node.h"
30 #include "ns3/packet-burst.h"
31 #include "ns3/packet.h"
32 #include "ns3/simulator.h"
33 #include "ns3/string.h"
34 #include "ns3/trace-source-accessor.h"
35 #include "ns3/uinteger.h"
36 
37 #include <cmath>
38 #include <string>
39 
40 namespace ns3
41 {
42 
43 NS_LOG_COMPONENT_DEFINE("SimpleOfdmWimaxPhy");
44 
45 NS_OBJECT_ENSURE_REGISTERED(SimpleOfdmWimaxPhy);
46 
47 TypeId
49 {
50  static TypeId tid =
51  TypeId("ns3::SimpleOfdmWimaxPhy")
53  .SetGroupName("Wimax")
54 
55  .AddConstructor<SimpleOfdmWimaxPhy>()
56 
57  .AddAttribute(
58  "NoiseFigure",
59  "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver.",
60  DoubleValue(5),
63  MakeDoubleChecker<double>())
64 
65  .AddAttribute("TxPower",
66  "Transmission power (dB).",
67  DoubleValue(30),
70  MakeDoubleChecker<double>())
71 
72  .AddAttribute("G",
73  "This is the ratio of CP time to useful time.",
74  DoubleValue(0.25),
77  MakeDoubleChecker<double>())
78 
79  .AddAttribute(
80  "TxGain",
81  "Transmission gain (dB).",
82  DoubleValue(0),
84  MakeDoubleChecker<double>())
85 
86  .AddAttribute(
87  "RxGain",
88  "Reception gain (dB).",
89  DoubleValue(0),
91  MakeDoubleChecker<double>())
92 
93  .AddAttribute("Nfft",
94  "FFT size",
95  UintegerValue(256),
98  MakeUintegerChecker<uint16_t>(256, 1024))
99 
100  .AddAttribute("TraceFilePath",
101  "Path to the directory containing SNR to block error rate files",
102  StringValue(""),
106 
107  .AddTraceSource("Rx",
108  "Receive trace",
110  "ns3::PacketBurst::TracedCallback")
111  .AddTraceSource("Tx",
112  "Transmit trace",
114  "ns3::PacketBurst::TracedCallback")
115 
116  .AddTraceSource(
117  "PhyTxBegin",
118  "Trace source indicating a packet has begun transmitting over the channel medium",
120  "ns3::PacketBurst::TracedCallback")
121 
122  .AddTraceSource(
123  "PhyTxEnd",
124  "Trace source indicating a packet has been completely transmitted over the channel",
126  "ns3::PacketBurst::TracedCallback")
127 
128  .AddTraceSource("PhyTxDrop",
129  "Trace source indicating a packet has been dropped by the device "
130  "during transmission",
132  "ns3::PacketBurst::TracedCallback")
133 
134  .AddTraceSource("PhyRxBegin",
135  "Trace source indicating a packet has begun being received from the "
136  "channel medium by the device",
138  "ns3::PacketBurst::TracedCallback")
139 
140  .AddTraceSource("PhyRxEnd",
141  "Trace source indicating a packet has been completely received from "
142  "the channel medium by the device",
144  "ns3::PacketBurst::TracedCallback")
145 
146  .AddTraceSource(
147  "PhyRxDrop",
148  "Trace source indicating a packet has been dropped by the device during reception",
150  "ns3::PacketBurst::TracedCallback");
151  return tid;
152 }
153 
154 void
156 {
157  m_fecBlockSize = 0;
158  m_nrFecBlocksSent = 0;
159  m_dataRateBpsk12 = 0;
160  m_dataRateQpsk12 = 0;
161  m_dataRateQpsk34 = 0;
162  m_dataRateQam16_12 = 0;
163 
164  m_dataRateQam16_34 = 0;
165  m_dataRateQam64_23 = 0;
166  m_dataRateQam64_34 = 0;
167 
168  m_nrBlocks = 0;
169  m_blockSize = 0;
170  m_paddingBits = 0;
171  m_rxGain = 0;
172  m_txGain = 0;
173  m_nfft = 256;
174  m_g = 1.0 / 4;
175  SetNrCarriers(192);
176  m_fecBlocks = new std::list<Bvec>;
177  m_receivedFecBlocks = new std::list<Bvec>;
178  m_currentBurstSize = 0;
179  m_noiseFigure = 5; // dB
180  m_txPower = 30; // dBm
181  SetBandwidth(10000000); // 10Mhz
182  m_nbErroneousBlock = 0;
185 }
186 
188 {
189  m_URNG = CreateObject<UniformRandomVariable>();
190 
194 }
195 
197 {
201 }
202 
204 {
205 }
206 
207 void
209 {
211 }
212 
213 void
215 {
218 }
219 
220 uint32_t
222 {
224 }
225 
226 void
228 {
230 }
231 
232 double
234 {
235  return m_txPower;
236 }
237 
238 void
240 {
241  m_txPower = txPower;
242 }
243 
244 double
246 {
247  return m_noiseFigure;
248 }
249 
250 void
252 {
253  m_noiseFigure = noiseFigure;
254 }
255 
256 void
258 {
259  delete m_receivedFecBlocks;
260  delete m_fecBlocks;
261  m_receivedFecBlocks = nullptr;
262  m_fecBlocks = nullptr;
265 }
266 
267 void
269 {
270  GetChannel()->Attach(this);
271 }
272 
273 void
275 {
276  auto o_params = dynamic_cast<OfdmSendParams*>(params);
277  NS_ASSERT(o_params != nullptr);
278  Send(o_params->GetBurst(),
279  (WimaxPhy::ModulationType)o_params->GetModulationType(),
280  o_params->GetDirection());
281 }
282 
285 {
287 }
288 
289 void
291  WimaxPhy::ModulationType modulationType,
292  uint8_t direction)
293 {
294  if (GetState() != PHY_STATE_TX)
295  {
296  m_currentBurstSize = burst->GetSize();
297  m_nrFecBlocksSent = 0;
298  m_currentBurst = burst;
299  SetBlockParameters(burst->GetSize(), modulationType);
301  StartSendDummyFecBlock(true, modulationType, direction);
302  m_traceTx(burst);
303  }
304 }
305 
306 void
308  WimaxPhy::ModulationType modulationType,
309  uint8_t direction)
310 {
312  bool isLastFecBlock = false;
313  if (isFirstBlock)
314  {
315  m_blockTime = GetBlockTransmissionTime(modulationType);
316  }
317 
319  dynamic_cast<SimpleOfdmWimaxChannel*>(PeekPointer(GetChannel()));
320  NS_ASSERT(channel != nullptr);
321 
322  isLastFecBlock = (m_nrRemainingBlocksToSend == 1);
323  channel->Send(m_blockTime,
325  this,
326  isFirstBlock,
327  isLastFecBlock,
328  GetTxFrequency(),
329  modulationType,
330  direction,
331  m_txPower,
333 
337  this,
338  modulationType,
339  direction);
340 }
341 
342 void
344 {
347 
349  {
350  // this is the last FEC block of the burst
351  NS_ASSERT_MSG(m_nrRemainingBlocksToSend == 0, "Error while sending a burst");
353  }
354  else
355  {
356  StartSendDummyFecBlock(false, modulationType, direction);
357  }
358 }
359 
360 void
362 {
364 }
365 
366 void
368  bool isFirstBlock,
369  uint64_t frequency,
370  WimaxPhy::ModulationType modulationType,
371  uint8_t direction,
372  double rxPower,
373  Ptr<PacketBurst> burst)
374 {
375  bool drop = false;
376  double Nwb = -114 + m_noiseFigure + 10 * std::log(GetBandwidth() / 1000000000.0) / 2.303;
377  double SNR = rxPower - Nwb;
378 
379  SNRToBlockErrorRateRecord* record =
381  double I1 = record->GetI1();
382  double I2 = record->GetI2();
383 
384  double blockErrorRate = m_URNG->GetValue(I1, I2);
385 
386  double rand = m_URNG->GetValue(0.0, 1.0);
387 
388  if (rand < blockErrorRate)
389  {
390  drop = true;
391  }
392  if (rand > blockErrorRate)
393  {
394  drop = false;
395  }
396 
397  if (blockErrorRate == 1.0)
398  {
399  drop = true;
400  }
401  if (blockErrorRate == 0.0)
402  {
403  drop = false;
404  }
405  delete record;
406 
407  NS_LOG_INFO("PHY: Receive rxPower=" << rxPower << ", Nwb=" << Nwb << ", SNR=" << SNR
408  << ", Modulation=" << modulationType << ", BlockErrorRate="
409  << blockErrorRate << ", drop=" << std::boolalpha << drop);
410 
411  switch (GetState())
412  {
413  case PHY_STATE_SCANNING:
414  if (frequency == GetScanningFrequency())
415  {
418  SetSimplex(frequency);
420  }
421  break;
422  case PHY_STATE_IDLE:
423  if (frequency == GetRxFrequency())
424  {
425  if (isFirstBlock)
426  {
427  NotifyRxBegin(burst);
428  m_receivedFecBlocks->clear();
430  SetBlockParameters(burstSize, modulationType);
431  m_blockTime = GetBlockTransmissionTime(modulationType);
432  }
433 
436  this,
437  burstSize,
438  modulationType,
439  direction,
440  drop,
441  burst);
442 
444  }
445  break;
446  case PHY_STATE_RX:
447  // drop
448  break;
449  case PHY_STATE_TX:
450  if (IsDuplex() && frequency == GetRxFrequency())
451  {
452  }
453  break;
454  }
455 }
456 
457 void
459  WimaxPhy::ModulationType modulationType,
460  uint8_t direction,
461  bool drop,
462  Ptr<PacketBurst> burst)
463 {
466 
467  if (drop)
468  {
470  }
471 
472  if ((uint32_t)m_nrReceivedFecBlocks * m_blockSize == burstSize * 8 + m_paddingBits)
473  {
474  NotifyRxEnd(burst);
475  if (m_nbErroneousBlock == 0)
476  {
478  }
479  else
480  {
481  NotifyRxDrop(burst);
482  }
483  m_nbErroneousBlock = 0;
485  }
486 }
487 
488 void
490 {
491  Ptr<PacketBurst> b = burst->Copy();
492  GetReceiveCallback()(b);
493  m_traceRx(burst);
494 }
495 
496 Bvec
498 {
499  Bvec buffer(burst->GetSize() * 8, false);
500 
501  std::list<Ptr<Packet>> packets = burst->GetPackets();
502 
503  uint32_t j = 0;
504  for (auto iter = packets.begin(); iter != packets.end(); ++iter)
505  {
506  Ptr<Packet> packet = *iter;
507  auto pstart = (uint8_t*)std::malloc(packet->GetSize());
508  std::memset(pstart, 0, packet->GetSize());
509  packet->CopyData(pstart, packet->GetSize());
510  Bvec temp(8);
511  temp.resize(0, false);
512  temp.resize(8, false);
513  for (uint32_t i = 0; i < packet->GetSize(); i++)
514  {
515  for (uint8_t l = 0; l < 8; l++)
516  {
517  temp[l] = (bool)((((uint8_t)pstart[i]) >> (7 - l)) & 0x01);
518  buffer.at(j * 8 + l) = temp[l];
519  }
520  j++;
521  }
522  std::free(pstart);
523  }
524 
525  return buffer;
526 }
527 
528 /*
529  Converts back the bit buffer (Bvec) to the actual burst.
530  Actually creates byte buffer from the Bvec and resets the buffer
531  of each packet in the copy of the original burst stored before transmitting.
532  By doing this it preserves the metadata and tags in the packet.
533  Function could also be named DeserializeBurst because actually it
534  copying to the burst's byte buffer.
535  */
538 {
539  uint8_t init[buffer.size() / 8];
540  uint8_t* pstart = init;
541  uint8_t temp;
542  int32_t j = 0;
543  // recreating byte buffer from bit buffer (Bvec)
544  for (uint32_t i = 0; i < buffer.size(); i += 8)
545  {
546  temp = 0;
547  for (int l = 0; l < 8; l++)
548  {
549  bool bin = buffer.at(i + l);
550  temp |= (bin << (7 - l));
551  }
552 
553  *(pstart + j) = temp;
554  j++;
555  }
556  uint16_t bufferSize = buffer.size() / 8;
557  uint16_t pos = 0;
558  Ptr<PacketBurst> RecvBurst = Create<PacketBurst>();
559  while (pos < bufferSize)
560  {
561  uint16_t packetSize = 0;
562  // Get the header type: first bit
563  uint8_t ht = (pstart[pos] >> 7) & 0x01;
564  if (ht == 1)
565  {
566  // BW request header. Size is always 8 bytes
567  packetSize = 6;
568  }
569  else
570  {
571  // Read the size
572  uint8_t Len_MSB = pstart[pos + 1] & 0x07;
573  packetSize = (uint16_t)((uint16_t)(Len_MSB << 8) | (uint16_t)(pstart[pos + 2]));
574  if (packetSize == 0)
575  {
576  break; // padding
577  }
578  }
579 
580  Ptr<Packet> p = Create<Packet>(&(pstart[pos]), packetSize);
581  RecvBurst->AddPacket(p);
582  pos += packetSize;
583  }
584  return RecvBurst;
585 }
586 
587 void
589 {
590  Bvec fecBlock(m_blockSize);
591  for (uint32_t i = 0, j = m_nrBlocks; j > 0; i += m_blockSize, j--)
592  {
593  if (j == 1 && m_paddingBits > 0) // last block can be smaller than block size
594  {
595  fecBlock = Bvec(buffer.begin() + i, buffer.end());
596  fecBlock.resize(m_blockSize, false);
597  }
598  else
599  {
600  fecBlock = Bvec(buffer.begin() + i, buffer.begin() + i + m_blockSize);
601  }
602 
603  m_fecBlocks->push_back(fecBlock);
604  }
605 }
606 
607 Bvec
609 {
610  Bvec buffer(m_blockSize * (unsigned long)m_nrBlocks);
611  Bvec block(m_blockSize);
612  uint32_t i = 0;
613  for (uint32_t j = 0; j < m_nrBlocks; j++)
614  {
615  Bvec tmpRecFecBlock = m_receivedFecBlocks->front();
616  buffer.insert(buffer.begin() + i, tmpRecFecBlock.begin(), tmpRecFecBlock.end());
617  m_receivedFecBlocks->pop_front();
618  i += m_blockSize;
619  }
620  return buffer;
621 }
622 
623 void
625 {
633 }
634 
635 void
637  uint8_t& bitsPerSymbol,
638  double& fecCode) const
639 {
640  switch (modulationType)
641  {
643  bitsPerSymbol = 1;
644  fecCode = 1.0 / 2;
645  break;
647  bitsPerSymbol = 2;
648  fecCode = 1.0 / 2;
649  break;
651  bitsPerSymbol = 2;
652  fecCode = 3.0 / 4;
653  break;
655  bitsPerSymbol = 4;
656  fecCode = 1.0 / 2;
657  break;
659  bitsPerSymbol = 4;
660  fecCode = 3.0 / 4;
661  break;
663  bitsPerSymbol = 6;
664  fecCode = 2.0 / 3;
665  break;
667  bitsPerSymbol = 6;
668  fecCode = 0.75;
669  break;
670  }
671 }
672 
673 uint32_t
675 {
676  uint8_t bitsPerSymbol = 0;
677  double fecCode = 0;
678  GetModulationFecParams(modulationType, bitsPerSymbol, fecCode);
679  double symbolsPerSecond = 1 / GetSymbolDuration().GetSeconds();
680  auto bitsTransmittedPerSymbol = (uint16_t)(bitsPerSymbol * GetNrCarriers() * fecCode);
681  // 96, 192, 288, 384, 576, 767 and 864 bits per symbol for the seven modulations, respectively
682 
683  return (uint32_t)symbolsPerSecond * bitsTransmittedPerSymbol;
684 }
685 
686 uint32_t
688 {
689  switch (modulationType)
690  {
692  return m_dataRateBpsk12;
694  return m_dataRateQpsk12;
696  return m_dataRateQpsk34;
698  return m_dataRateQam16_12;
700  return m_dataRateQam16_34;
702  return m_dataRateQam64_23;
704  return m_dataRateQam64_34;
705  }
706  NS_FATAL_ERROR("Invalid modulation type");
707  return 0;
708 }
709 
710 Time
712 {
713  return Seconds((double)GetFecBlockSize(modulationType) / DoGetDataRate(modulationType));
714 }
715 
716 Time
718  WimaxPhy::ModulationType modulationType) const
719 {
720  /*adding 3 extra nano second to cope with the loss of precision problem.
721  the time is internally stored in a 64 bit hence a floating-point time would loss
722  precision, e.g., 0.00001388888888888889 seconds will become 13888888888 femtoseconds.*/
723  return Seconds(DoGetNrSymbols(size, modulationType) * GetSymbolDuration().GetSeconds()) +
724  NanoSeconds(3);
725 }
726 
727 uint64_t
729 {
730  Time transmissionTime =
731  Seconds((double)(GetNrBlocks(size, modulationType) * GetFecBlockSize(modulationType)) /
732  DoGetDataRate(modulationType));
733  return (uint64_t)std::ceil(transmissionTime.GetSeconds() / GetSymbolDuration().GetSeconds());
734 }
735 
736 uint64_t
737 SimpleOfdmWimaxPhy::DoGetNrBytes(uint32_t symbols, WimaxPhy::ModulationType modulationType) const
738 {
739  Time transmissionTime = Seconds(symbols * GetSymbolDuration().GetSeconds());
740  return (uint64_t)std::floor((transmissionTime.GetSeconds() * DoGetDataRate(modulationType)) /
741  8);
742 }
743 
744 uint32_t
746 {
747  uint32_t blockSize = 0;
748  switch (modulationType)
749  {
751  blockSize = 12;
752  break;
754  blockSize = 24;
755  break;
757  blockSize = 36;
758  break;
760  blockSize = 48;
761  break;
763  blockSize = 72;
764  break;
766  blockSize = 96;
767  break;
769  blockSize = 108;
770  break;
771  default:
772  NS_FATAL_ERROR("Invalid modulation type");
773  break;
774  }
775  return blockSize * 8; // in bits
776 }
777 
778 // Channel coding block size, Table 215, page 434
779 uint32_t
781 {
782  uint32_t blockSize = 0;
783  switch (modulationType)
784  {
786  blockSize = 24;
787  break;
789  blockSize = 48;
790  break;
792  blockSize = 48;
793  break;
795  blockSize = 96;
796  break;
798  blockSize = 96;
799  break;
801  blockSize = 144;
802  break;
804  blockSize = 144;
805  break;
806  default:
807  NS_FATAL_ERROR("Invalid modulation type");
808  break;
809  }
810  return blockSize * 8; // in bits
811 }
812 
813 void
815 {
816  m_blockSize = GetFecBlockSize(modulationType);
817  m_nrBlocks = GetNrBlocks(burstSize, modulationType);
818  m_paddingBits = (m_nrBlocks * m_blockSize) - (burstSize * 8);
820  NS_ASSERT_MSG(static_cast<uint32_t>(m_nrBlocks * m_blockSize) >= (burstSize * 8),
821  "Size of padding bytes < 0");
822 }
823 
824 uint16_t
826 {
827  // assumed equal to 2 symbols
828  return 2 * GetPsPerSymbol();
829 }
830 
831 uint16_t
833 {
834  // assumed equal to 2 symbols
835  return 2 * GetPsPerSymbol();
836 }
837 
838 uint8_t
840 {
841  uint16_t duration = 0;
842  duration = (uint16_t)(GetFrameDuration().GetSeconds() * 10000);
843  uint8_t retval = 0;
844  switch (duration)
845  {
846  case 25: {
848  break;
849  }
850  case 40: {
851  retval = FRAME_DURATION_4_MS;
852  break;
853  }
854  case 50: {
855  retval = FRAME_DURATION_5_MS;
856  break;
857  }
858  case 80: {
859  retval = FRAME_DURATION_8_MS;
860  break;
861  }
862  case 100: {
863  retval = FRAME_DURATION_10_MS;
864  break;
865  }
866  case 125: {
868  break;
869  }
870  case 200: {
871  retval = FRAME_DURATION_20_MS;
872  break;
873  }
874  default: {
875  NS_FATAL_ERROR("Invalid frame duration = " << duration);
876  retval = 0;
877  }
878  }
879  return retval;
880 }
881 
882 Time
883 SimpleOfdmWimaxPhy::DoGetFrameDuration(uint8_t frameDurationCode) const
884 {
885  switch (frameDurationCode)
886  {
888  return Seconds(2.5);
889  case FRAME_DURATION_4_MS:
890  return Seconds(4);
891  case FRAME_DURATION_5_MS:
892  return Seconds(5);
893  case FRAME_DURATION_8_MS:
894  return Seconds(8);
896  return Seconds(10);
898  return Seconds(12.5);
900  return Seconds(20);
901  default:
902  NS_FATAL_ERROR("Invalid modulation type");
903  }
904  return Seconds(0);
905 }
906 
907 /*
908  Returns number of blocks (FEC blocks) the burst will be split in.
909  The size of the block is specific for each modulation type.
910  */
911 uint16_t
912 SimpleOfdmWimaxPhy::GetNrBlocks(uint32_t burstSize, WimaxPhy::ModulationType modulationType) const
913 {
914  uint32_t blockSize = GetFecBlockSize(modulationType);
915  uint16_t nrBlocks = (burstSize * 8) / blockSize;
916 
917  if ((burstSize * 8) % blockSize > 0)
918  {
919  nrBlocks += 1;
920  }
921 
922  return nrBlocks;
923 }
924 
925 /*---------------------PHY parameters functions-----------------------*/
926 
927 void
929 {
930  /*Calculations as per section 8.3.2.
931  Currently assuming license-exempt 5 GHz band. For channel bandwidth 20 MHz (Table B.28, page
932  812) and frame duration 10 ms (Table 232, page 460) i.e, 100 frames per second, sampling
933  frequency is 23040000, symbol (OFDM symbol) duration is 1.388888888888889e-05 seconds, PS
934  duration is 1.7361111111111112e-07 seconds. Hence PSs per frame is 57600, symbols per frame is
935  720 and PSs per symbol is 80. Note that defining these parameters (symbol and PS duration) as
936  Time may not result in exactly these values therefore lrint has been used (otherwise should be
937  defined as double). For licensed bands set channel bandwidth according to Table B.26, page
938  810.*/
939 
940  double samplingFrequency = DoGetSamplingFrequency();
941  Time psDuration = Seconds(4.0 / samplingFrequency);
942 
943  SetPsDuration(psDuration);
944  uint16_t psPerFrame = (uint16_t)(GetFrameDuration().GetSeconds() / psDuration.GetSeconds());
945  SetPsPerFrame(psPerFrame);
946  double subcarrierSpacing = samplingFrequency / DoGetNfft();
947  double tb = 1.0 / subcarrierSpacing; // Tb (useful symbol time)
948  double tg = DoGetGValue() * tb; // Tg (cyclic prefix time)
949  Time symbolDuration = Seconds(tb + tg); // OFDM Symbol Time
950  SetSymbolDuration(symbolDuration);
951  uint16_t psPerSymbol = lrint(symbolDuration.GetSeconds() / psDuration.GetSeconds());
952  SetPsPerSymbol(psPerSymbol);
953  uint32_t symbolsPerFrame = lrint(GetFrameDuration().GetSeconds() / symbolDuration.GetSeconds());
954  SetSymbolsPerFrame(symbolsPerFrame);
955 }
956 
957 void
959 {
960  m_nfft = nfft;
961 }
962 
963 uint16_t
965 {
966  return m_nfft;
967 }
968 
969 double
971 {
972  // sampling factor (n), see Table 213, page 429
973 
974  uint32_t channelBandwidth = GetChannelBandwidth();
975 
976  if (channelBandwidth % 1750000 == 0)
977  {
978  return 8.0 / 7;
979  }
980  else if (channelBandwidth % 1500000 == 0)
981  {
982  return 86.0 / 75;
983  }
984  else if (channelBandwidth % 1250000 == 0)
985  {
986  return 144.0 / 125;
987  }
988  else if (channelBandwidth % 2750000 == 0)
989  {
990  return 316.0 / 275;
991  }
992  else if (channelBandwidth % 2000000 == 0)
993  {
994  return 57.0 / 50;
995  }
996  else
997  {
998  NS_LOG_DEBUG("Oops may be wrong channel bandwidth for OFDM PHY!");
999  NS_FATAL_ERROR("wrong channel bandwidth for OFDM PHY");
1000  }
1001 
1002  return 8.0 / 7;
1003 }
1004 
1005 double
1007 {
1008  // sampling frequency (Fs), see 8.3.2.2
1009 
1010  return (DoGetSamplingFactor() * GetChannelBandwidth() / 8000) * 8000;
1011 }
1012 
1013 double
1015 {
1016  return m_g;
1017 }
1018 
1019 void
1021 {
1022  m_g = g;
1023 }
1024 
1025 void
1027 {
1028  m_txGain = txGain;
1029 }
1030 
1031 void
1033 {
1034  m_rxGain = txRain;
1035 }
1036 
1037 double
1039 {
1040  return m_txGain;
1041 }
1042 
1043 double
1045 {
1046  return m_rxGain;
1047 }
1048 
1049 std::string
1051 {
1053 }
1054 
1055 void
1057 {
1058  m_snrToBlockErrorRateManager->SetTraceFilePath((char*)path.c_str());
1060 }
1061 
1062 void
1064 {
1065  m_phyTxBeginTrace(burst);
1066 }
1067 
1068 void
1070 {
1071  m_phyTxEndTrace(burst);
1072 }
1073 
1074 void
1076 {
1077  m_phyTxDropTrace(burst);
1078 }
1079 
1080 void
1082 {
1083  m_phyRxBeginTrace(burst);
1084 }
1085 
1086 void
1088 {
1089  m_phyRxEndTrace(burst);
1090 }
1091 
1092 void
1094 {
1095  m_phyRxDropTrace(burst);
1096 }
1097 
1098 int64_t
1100 {
1101  NS_LOG_FUNCTION(this << stream);
1102  m_URNG->SetStream(stream);
1103  return 1;
1104 }
1105 
1106 } // namespace ns3
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
OfdmSendParams class.
Definition: send-params.h:68
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:400
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
This class handles the SNR to BlcER traces.
void ActivateLoss(bool loss)
If activate loss is called with false, all the returned BlcER will be 0 (no losses)
void LoadTraces()
Loads the traces form the repository specified in the constructor or set by SetTraceFilePath function...
SNRToBlockErrorRateRecord * GetSNRToBlockErrorRateRecord(double SNR, uint8_t modulation)
returns a record of type SNRToBlockErrorRateRecord corresponding to a given modulation and SNR value
void SetTraceFilePath(char *traceFilePath)
Set the path of the repository containing the traces.
This class represents a record (handled by SnrToBlockErrorRate manager) that keeps a mapping between ...
The SendParams class defines the parameters with which Send() function of a particular PHY is called.
Definition: send-params.h:42
SimpleOfdmWimaxChannel class.
SimpleOfdmWimaxPhy class.
std::string GetTraceFilePath() const
Get trace file path.
void GetModulationFecParams(WimaxPhy::ModulationType modulationType, uint8_t &bitsPerSymbol, double &fecCode) const
Get moduleation FEC parameters.
void NotifyRxBegin(Ptr< PacketBurst > burst)
Public method used to fire a PhyRxBegin trace.
double GetTxGain() const
Get transmit gain.
double DoGetSamplingFrequency() const override
Get sampling frequency.
void CreateFecBlocks(const Bvec &buffer, WimaxPhy::ModulationType modulationType)
Create FEC blocks.
static TypeId GetTypeId()
Get the type ID.
void NotifyRxEnd(Ptr< PacketBurst > burst)
Public method used to fire a PhyRxEnd trace.
TracedCallback< Ptr< PacketBurst > > m_phyRxBeginTrace
The trace source fired when a packet begins the reception process from the medium.
uint32_t m_dataRateQpsk12
data rate
double m_txPower
transmit power
void EndReceiveFecBlock(uint32_t burstSize, WimaxPhy::ModulationType modulationType, uint8_t direction, bool drop, Ptr< PacketBurst > burst)
End receive FEC block.
void EndReceive(Ptr< const PacketBurst > burst)
End receive.
double DoGetGValue() const override
Get G value.
void DoSetGValue(double g)
Set G value.
uint32_t CalculateDataRate(WimaxPhy::ModulationType modulationType) const
Calculate data rate.
void StartSendDummyFecBlock(bool isFirstBlock, WimaxPhy::ModulationType modulationType, uint8_t direction)
Start end dummy FEC block.
void DoAttach(Ptr< WimaxChannel > channel) override
Attach the physical layer to a channel.
uint16_t DoGetTtg() const override
Get TTG.
uint8_t DoGetFrameDurationCode() const override
Get frame duration code.
int64_t AssignStreams(int64_t stream) override
Assign a fixed random variable stream number to the random variables used by this model.
double m_txGain
transmit gain
void ActivateLoss(bool loss)
if called with true it will enable the loss model
uint32_t m_dataRateQam16_34
data rate
uint16_t m_nbErroneousBlock
erroneous blocks
uint16_t m_nrBlocks
number of blocks
WimaxPhy::PhyType GetPhyType() const override
returns the type this physical layer
uint16_t m_blockSize
block size
void SetTraceFilePath(std::string path)
Set trace file path.
void SetNoiseFigure(double nf)
set the noise figure of the device
uint16_t m_nrReceivedFecBlocks
number received FEC blocks
void SetRxGain(double rxgain)
Set receive gsain.
Ptr< PacketBurst > ConvertBitsToBurst(Bvec buffer)
Convert bits to burst.
void EndSendFecBlock(WimaxPhy::ModulationType modulationType, uint8_t direction)
End send FEC block.
uint32_t m_dataRateQpsk34
data rate
Ptr< PacketBurst > m_currentBurst
current burst
Ptr< UniformRandomVariable > m_URNG
Provides uniform random variables.
void DoSetNfft(uint16_t nfft)
Set NFFT.
void NotifyRxDrop(Ptr< PacketBurst > burst)
Public method used to fire a PhyRxDrop trace.
uint16_t GetNrBlocks(uint32_t burstSize, WimaxPhy::ModulationType modulationType) const
Get number of blocks.
Bvec RecreateBuffer()
Recreate buffer.
TracedCallback< Ptr< PacketBurst > > m_phyRxEndTrace
The trace source fired when a packet ends the reception process from the medium.
TracedCallback< Ptr< PacketBurst > > m_phyTxBeginTrace
The trace source fired when a packet begins the transmission process on the medium.
void NotifyTxEnd(Ptr< PacketBurst > burst)
Public method used to fire a PhyTxEnd trace.
double m_noiseFigure
noise figure
void SetBlockParameters(uint32_t burstSize, WimaxPhy::ModulationType modulationType)
Set block parameters.
uint32_t m_dataRateQam64_34
data rate
uint32_t m_dataRateBpsk12
data rate
double DoGetSamplingFactor() const override
Get sampling factor.
void SetTxPower(double txPower)
set the transmission power
uint64_t DoGetNrBytes(uint32_t symbols, WimaxPhy::ModulationType modulationType) const override
Get number of bytes.
SNRToBlockErrorRateManager * m_snrToBlockErrorRateManager
SNR to block error rate manager.
TracedCallback< Ptr< const PacketBurst > > m_traceTx
trace transmit callback
void DoSetDataRates() override
Set data rates.
uint16_t DoGetNfft() const override
Get NFFT.
void DoSetPhyParameters() override
Set Phy parameters.
uint32_t m_dataRateQam16_12
data rate
uint16_t DoGetRtg() const override
Get RTG.
uint32_t GetCodedFecBlockSize(WimaxPhy::ModulationType modulationType) const
Get coded FEC block size.
std::list< Bvec > * m_receivedFecBlocks
a list of received FEC blocks until they are combined to recreate the full burst buffer
uint32_t GetFecBlockSize(WimaxPhy::ModulationType type) const
Get FEC block size.
void SetTxGain(double txgain)
Set transmit gain.
uint16_t m_nrRemainingBlocksToSend
number of remaining blocks to send
void SetBandwidth(uint32_t BW)
Set the bandwidth.
TracedCallback< Ptr< PacketBurst > > m_phyTxEndTrace
The trace source fired when a packet ends the transmission process on the medium.
Time GetBlockTransmissionTime(WimaxPhy::ModulationType modulationType) const
Get block transmission time.
void Send(Ptr< PacketBurst > burst, WimaxPhy::ModulationType modulationType, uint8_t direction)
Sends a burst on the channel.
Time DoGetTransmissionTime(uint32_t size, WimaxPhy::ModulationType modulationType) const override
Get transmission time.
TracedCallback< Ptr< PacketBurst > > m_phyRxDropTrace
The trace source fired when the phy layer drops a packet it has received.
Time DoGetFrameDuration(uint8_t frameDurationCode) const override
Get frame duration.
void SetSNRToBlockErrorRateTracesPath(char *tracesPath)
Set the path of the repository containing the traces.
uint32_t m_currentBurstSize
current burst size
uint32_t DoGetDataRate(WimaxPhy::ModulationType modulationType) const override
Get data rate.
void NotifyTxDrop(Ptr< PacketBurst > burst)
Public method used to fire a PhyTxDrop trace.
uint64_t DoGetNrSymbols(uint32_t size, WimaxPhy::ModulationType modulationType) const override
Get number of symbols.
void InitSimpleOfdmWimaxPhy()
Initialize simple OFDM WIMAX Phy.
void NotifyTxBegin(Ptr< PacketBurst > burst)
Public method used to fire a PhyTxBegin trace.
TracedCallback< Ptr< PacketBurst > > m_phyTxDropTrace
The trace source fired when the phy layer drops a packet as it tries to transmit it.
uint32_t m_paddingBits
padding bits
std::list< Bvec > * m_fecBlocks
the FEC blocks
double GetRxGain() const
Get receive gain.
uint16_t m_fecBlockSize
in bits, size of FEC block transmitted after PHY operations
TracedCallback< Ptr< const PacketBurst > > m_traceRx
trace receive callback
Bvec ConvertBurstToBits(Ptr< const PacketBurst > burst)
Convert burst to bits.
uint32_t m_dataRateQam64_23
data rate
void DoDispose() override
Destructor implementation.
void StartReceive(uint32_t burstSize, bool isFirstBlock, uint64_t frequency, WimaxPhy::ModulationType modulationType, uint8_t direction, double rxPower, Ptr< PacketBurst > burst)
start the reception of a fec block
uint32_t m_nrFecBlocksSent
counting the number of FEC blocks sent (within a burst)
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition: simulator.cc:285
Hold variables of type string.
Definition: string.h:56
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
Hold an unsigned integer type.
Definition: uinteger.h:45
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
WiMAX PHY entity.
Definition: wimax-phy.h:50
Time GetFrameDuration() const
Get the frame duration.
Definition: wimax-phy.cc:308
ModulationType
ModulationType enumeration.
Definition: wimax-phy.h:54
@ MODULATION_TYPE_QPSK_12
Definition: wimax-phy.h:56
@ MODULATION_TYPE_QAM16_12
Definition: wimax-phy.h:58
@ MODULATION_TYPE_QAM64_34
Definition: wimax-phy.h:61
@ MODULATION_TYPE_QAM16_34
Definition: wimax-phy.h:59
@ MODULATION_TYPE_QAM64_23
Definition: wimax-phy.h:60
@ MODULATION_TYPE_QPSK_34
Definition: wimax-phy.h:57
@ MODULATION_TYPE_BPSK_12
Definition: wimax-phy.h:55
void SetSymbolDuration(Time symbolDuration)
set the OFDM symbol duration
Definition: wimax-phy.cc:374
Ptr< WimaxChannel > GetChannel() const
Definition: wimax-phy.cc:117
void SetChannelBandwidth(uint32_t channelBandwidth)
Set the channel bandwidth.
Definition: wimax-phy.cc:332
uint64_t GetRxFrequency() const
Get the reception frequency.
Definition: wimax-phy.cc:180
PhyType
PhyType enumeration.
Definition: wimax-phy.h:75
@ simpleOfdmWimaxPhy
Definition: wimax-phy.h:77
Time GetSymbolDuration() const
Get the OFDM symbol duration.
Definition: wimax-phy.cc:380
uint8_t GetNrCarriers() const
Get the number of carriers in the physical frame.
Definition: wimax-phy.cc:296
PhyState GetState() const
Get the state of the device.
Definition: wimax-phy.cc:204
void SetSymbolsPerFrame(uint32_t symbolsPerFrame)
set the number of symbols per frame
Definition: wimax-phy.cc:416
void SetScanningCallback() const
calls the scanning call back function
Definition: wimax-phy.cc:222
void SetNrCarriers(uint8_t nrCarriers)
Set the number of carriers in the physical frame.
Definition: wimax-phy.cc:290
void DoDispose() override
Destructor implementation.
Definition: wimax-phy.cc:103
void SetPsPerFrame(uint16_t psPerFrame)
set the number of physical slots per frame
Definition: wimax-phy.cc:404
@ PHY_STATE_SCANNING
Definition: wimax-phy.h:68
void SetSimplex(uint64_t frequency)
configure the physical layer in simplex mode
Definition: wimax-phy.cc:173
uint64_t GetScanningFrequency() const
Get the scanning frequency.
Definition: wimax-phy.cc:192
void SetPsDuration(Time psDuration)
set the physical slot duration
Definition: wimax-phy.cc:362
uint16_t GetPsPerSymbol() const
Get the number of physical slots per symbol.
Definition: wimax-phy.cc:398
void SetState(PhyState state)
set the state of the device
Definition: wimax-phy.cc:198
uint32_t GetChannelBandwidth() const
Get the channel bandwidth.
Definition: wimax-phy.cc:338
EventId GetChnlSrchTimeoutEvent() const
Get channel search timeout event.
Definition: wimax-phy.cc:216
bool IsDuplex() const
Check if configured in duplex mode.
Definition: wimax-phy.cc:210
Callback< void, Ptr< const PacketBurst > > GetReceiveCallback() const
Definition: wimax-phy.cc:160
void SetPsPerSymbol(uint16_t psPerSymbol)
set the number of physical slots per symbol
Definition: wimax-phy.cc:392
uint64_t GetTxFrequency() const
Get the transmission frequency.
Definition: wimax-phy.cc:186
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1362
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::vector< bool > Bvec
boolean vector typedef
Definition: bvec.h:29
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
Ptr< const AttributeChecker > MakeStringChecker()
Definition: string.cc:30
Ptr< const AttributeAccessor > MakeStringAccessor(T1 a1)
Definition: string.h:57
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:449
channel
Definition: third.py:88
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
constexpr double BW
static const uint32_t packetSize
Packet size generated at the AP.