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  OfdmSendParams* o_params = dynamic_cast<OfdmSendParams*>(params);
277  NS_ASSERT(o_params != nullptr);
278  Send(o_params->GetBurst(),
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 = 0;
313  if (isFirstBlock)
314  {
315  m_blockTime = GetBlockTransmissionTime(modulationType);
316  }
317 
319  dynamic_cast<SimpleOfdmWimaxChannel*>(PeekPointer(GetChannel()));
320  NS_ASSERT(channel != nullptr);
321 
322  if (m_nrRemainingBlocksToSend == 1)
323  {
324  isLastFecBlock = true;
325  }
326  else
327  {
328  isLastFecBlock = false;
329  }
330  channel->Send(m_blockTime,
332  this,
333  isFirstBlock,
334  isLastFecBlock,
335  GetTxFrequency(),
336  modulationType,
337  direction,
338  m_txPower,
340 
344  this,
345  modulationType,
346  direction);
347 }
348 
349 void
351 {
354 
356  {
357  // this is the last FEC block of the burst
358  NS_ASSERT_MSG(m_nrRemainingBlocksToSend == 0, "Error while sending a burst");
360  }
361  else
362  {
363  StartSendDummyFecBlock(false, modulationType, direction);
364  }
365 }
366 
367 void
369 {
371 }
372 
373 void
375  bool isFirstBlock,
376  uint64_t frequency,
377  WimaxPhy::ModulationType modulationType,
378  uint8_t direction,
379  double rxPower,
380  Ptr<PacketBurst> burst)
381 {
382  bool drop = false;
383  double Nwb = -114 + m_noiseFigure + 10 * std::log(GetBandwidth() / 1000000000.0) / 2.303;
384  double SNR = rxPower - Nwb;
385 
386  SNRToBlockErrorRateRecord* record =
388  double I1 = record->GetI1();
389  double I2 = record->GetI2();
390 
391  double blockErrorRate = m_URNG->GetValue(I1, I2);
392 
393  double rand = m_URNG->GetValue(0.0, 1.0);
394 
395  if (rand < blockErrorRate)
396  {
397  drop = true;
398  }
399  if (rand > blockErrorRate)
400  {
401  drop = false;
402  }
403 
404  if (blockErrorRate == 1.0)
405  {
406  drop = true;
407  }
408  if (blockErrorRate == 0.0)
409  {
410  drop = false;
411  }
412  delete record;
413 
414  NS_LOG_INFO("PHY: Receive rxPower=" << rxPower << ", Nwb=" << Nwb << ", SNR=" << SNR
415  << ", Modulation=" << modulationType << ", BlocErrorRate="
416  << blockErrorRate << ", drop=" << std::boolalpha << drop);
417 
418  switch (GetState())
419  {
420  case PHY_STATE_SCANNING:
421  if (frequency == GetScanningFrequency())
422  {
425  SetSimplex(frequency);
427  }
428  break;
429  case PHY_STATE_IDLE:
430  if (frequency == GetRxFrequency())
431  {
432  if (isFirstBlock)
433  {
434  NotifyRxBegin(burst);
435  m_receivedFecBlocks->clear();
437  SetBlockParameters(burstSize, modulationType);
438  m_blockTime = GetBlockTransmissionTime(modulationType);
439  }
440 
443  this,
444  burstSize,
445  modulationType,
446  direction,
447  drop,
448  burst);
449 
451  }
452  break;
453  case PHY_STATE_RX:
454  // drop
455  break;
456  case PHY_STATE_TX:
457  if (IsDuplex() && frequency == GetRxFrequency())
458  {
459  }
460  break;
461  }
462 }
463 
464 void
466  WimaxPhy::ModulationType modulationType,
467  uint8_t direction,
468  bool drop,
469  Ptr<PacketBurst> burst)
470 {
473 
474  if (drop == true)
475  {
477  }
478 
479  if ((uint32_t)m_nrRecivedFecBlocks * m_blockSize == burstSize * 8 + m_paddingBits)
480  {
481  NotifyRxEnd(burst);
482  if (m_nbErroneousBlock == 0)
483  {
485  }
486  else
487  {
488  NotifyRxDrop(burst);
489  }
490  m_nbErroneousBlock = 0;
492  }
493 }
494 
495 void
497 {
498  Ptr<PacketBurst> b = burst->Copy();
499  GetReceiveCallback()(b);
500  m_traceRx(burst);
501 }
502 
503 Bvec
505 {
506  Bvec buffer(burst->GetSize() * 8, 0);
507 
508  std::list<Ptr<Packet>> packets = burst->GetPackets();
509 
510  uint32_t j = 0;
511  for (std::list<Ptr<Packet>>::iterator iter = packets.begin(); iter != packets.end(); ++iter)
512  {
513  Ptr<Packet> packet = *iter;
514  uint8_t* pstart = (uint8_t*)std::malloc(packet->GetSize());
515  std::memset(pstart, 0, packet->GetSize());
516  packet->CopyData(pstart, packet->GetSize());
517  Bvec temp(8);
518  temp.resize(0, 0);
519  temp.resize(8, 0);
520  for (uint32_t i = 0; i < packet->GetSize(); i++)
521  {
522  for (uint8_t l = 0; l < 8; l++)
523  {
524  temp[l] = (bool)((((uint8_t)pstart[i]) >> (7 - l)) & 0x01);
525  buffer.at(j * 8 + l) = temp[l];
526  }
527  j++;
528  }
529  std::free(pstart);
530  }
531 
532  return buffer;
533 }
534 
535 /*
536  Converts back the bit buffer (Bvec) to the actual burst.
537  Actually creates byte buffer from the Bvec and resets the buffer
538  of each packet in the copy of the original burst stored before transmitting.
539  By doing this it preserves the metadata and tags in the packet.
540  Function could also be named DeserializeBurst because actually it
541  copying to the burst's byte buffer.
542  */
545 {
546  uint8_t init[buffer.size() / 8];
547  uint8_t* pstart = init;
548  uint8_t temp;
549  int32_t j = 0;
550  // recreating byte buffer from bit buffer (Bvec)
551  for (uint32_t i = 0; i < buffer.size(); i += 8)
552  {
553  temp = 0;
554  for (int l = 0; l < 8; l++)
555  {
556  bool bin = buffer.at(i + l);
557  temp += (uint8_t)(bin * std::pow(2.0, (7 - l)));
558  }
559 
560  *(pstart + j) = temp;
561  j++;
562  }
563  uint16_t bufferSize = buffer.size() / 8;
564  uint16_t pos = 0;
565  Ptr<PacketBurst> RecvBurst = Create<PacketBurst>();
566  while (pos < bufferSize)
567  {
568  uint16_t packetSize = 0;
569  // Get the header type: first bit
570  uint8_t ht = (pstart[pos] >> 7) & 0x01;
571  if (ht == 1)
572  {
573  // BW request header. Size is always 8 bytes
574  packetSize = 6;
575  }
576  else
577  {
578  // Read the size
579  uint8_t Len_MSB = pstart[pos + 1] & 0x07;
580  packetSize = (uint16_t)((uint16_t)(Len_MSB << 8) | (uint16_t)(pstart[pos + 2]));
581  if (packetSize == 0)
582  {
583  break; // padding
584  }
585  }
586 
587  Ptr<Packet> p = Create<Packet>(&(pstart[pos]), packetSize);
588  RecvBurst->AddPacket(p);
589  pos += packetSize;
590  }
591  return RecvBurst;
592 }
593 
594 void
596 {
597  Bvec fecBlock(m_blockSize);
598  for (uint32_t i = 0, j = m_nrBlocks; j > 0; i += m_blockSize, j--)
599  {
600  if (j == 1 && m_paddingBits > 0) // last block can be smaller than block size
601  {
602  fecBlock = Bvec(buffer.begin() + i, buffer.end());
603  fecBlock.resize(m_blockSize, 0);
604  }
605  else
606  {
607  fecBlock = Bvec(buffer.begin() + i, buffer.begin() + i + m_blockSize);
608  }
609 
610  m_fecBlocks->push_back(fecBlock);
611  }
612 }
613 
614 Bvec
616 {
617  Bvec buffer(m_blockSize * (unsigned long)m_nrBlocks);
618  Bvec block(m_blockSize);
619  uint32_t i = 0;
620  for (uint32_t j = 0; j < m_nrBlocks; j++)
621  {
622  Bvec tmpRecFecBloc = m_receivedFecBlocks->front();
623  buffer.insert(buffer.begin() + i, tmpRecFecBloc.begin(), tmpRecFecBloc.end());
624  m_receivedFecBlocks->pop_front();
625  i += m_blockSize;
626  }
627  return buffer;
628 }
629 
630 void
632 {
640 }
641 
642 void
644  uint8_t& bitsPerSymbol,
645  double& fecCode) const
646 {
647  switch (modulationType)
648  {
650  bitsPerSymbol = 1;
651  fecCode = 1.0 / 2;
652  break;
654  bitsPerSymbol = 2;
655  fecCode = 1.0 / 2;
656  break;
658  bitsPerSymbol = 2;
659  fecCode = 3.0 / 4;
660  break;
662  bitsPerSymbol = 4;
663  fecCode = 1.0 / 2;
664  break;
666  bitsPerSymbol = 4;
667  fecCode = 3.0 / 4;
668  break;
670  bitsPerSymbol = 6;
671  fecCode = 2.0 / 3;
672  break;
674  bitsPerSymbol = 6;
675  fecCode = 0.75;
676  break;
677  }
678 }
679 
680 uint32_t
682 {
683  uint8_t bitsPerSymbol = 0;
684  double fecCode = 0;
685  GetModulationFecParams(modulationType, bitsPerSymbol, fecCode);
686  double symbolsPerSecond = 1 / GetSymbolDuration().GetSeconds();
687  uint16_t bitsTransmittedPerSymbol = (uint16_t)(bitsPerSymbol * GetNrCarriers() * fecCode);
688  // 96, 192, 288, 384, 576, 767 and 864 bits per symbol for the seven modulations, respectively
689 
690  return (uint32_t)symbolsPerSecond * bitsTransmittedPerSymbol;
691 }
692 
693 uint32_t
695 {
696  switch (modulationType)
697  {
699  return m_dataRateBpsk12;
700  break;
702  return m_dataRateQpsk12;
703  break;
705  return m_dataRateQpsk34;
706  break;
708  return m_dataRateQam16_12;
709  break;
711  return m_dataRateQam16_34;
712  break;
714  return m_dataRateQam64_23;
715  break;
717  return m_dataRateQam64_34;
718  break;
719  }
720  NS_FATAL_ERROR("Invalid modulation type");
721  return 0;
722 }
723 
724 Time
726 {
727  return Seconds((double)GetFecBlockSize(modulationType) / DoGetDataRate(modulationType));
728 }
729 
730 Time
732  WimaxPhy::ModulationType modulationType) const
733 {
734  /*adding 3 extra nano second to cope with the loss of precision problem.
735  the time is internally stored in a 64 bit hence a floating-point time would loss
736  precision, e.g., 0.00001388888888888889 seconds will become 13888888888 femtoseconds.*/
737  return Seconds(DoGetNrSymbols(size, modulationType) * GetSymbolDuration().GetSeconds()) +
738  NanoSeconds(3);
739 }
740 
741 uint64_t
743 {
744  Time transmissionTime =
745  Seconds((double)(GetNrBlocks(size, modulationType) * GetFecBlockSize(modulationType)) /
746  DoGetDataRate(modulationType));
747  return (uint64_t)std::ceil(transmissionTime.GetSeconds() / GetSymbolDuration().GetSeconds());
748 }
749 
750 uint64_t
751 SimpleOfdmWimaxPhy::DoGetNrBytes(uint32_t symbols, WimaxPhy::ModulationType modulationType) const
752 {
753  Time transmissionTime = Seconds(symbols * GetSymbolDuration().GetSeconds());
754  return (uint64_t)std::floor((transmissionTime.GetSeconds() * DoGetDataRate(modulationType)) /
755  8);
756 }
757 
758 uint32_t
760 {
761  uint32_t blockSize = 0;
762  switch (modulationType)
763  {
765  blockSize = 12;
766  break;
768  blockSize = 24;
769  break;
771  blockSize = 36;
772  break;
774  blockSize = 48;
775  break;
777  blockSize = 72;
778  break;
780  blockSize = 96;
781  break;
783  blockSize = 108;
784  break;
785  default:
786  NS_FATAL_ERROR("Invalid modulation type");
787  break;
788  }
789  return blockSize * 8; // in bits
790 }
791 
792 // Channel coding block size, Table 215, page 434
793 uint32_t
795 {
796  uint32_t blockSize = 0;
797  switch (modulationType)
798  {
800  blockSize = 24;
801  break;
803  blockSize = 48;
804  break;
806  blockSize = 48;
807  break;
809  blockSize = 96;
810  break;
812  blockSize = 96;
813  break;
815  blockSize = 144;
816  break;
818  blockSize = 144;
819  break;
820  default:
821  NS_FATAL_ERROR("Invalid modulation type");
822  break;
823  }
824  return blockSize * 8; // in bits
825 }
826 
827 void
829 {
830  m_blockSize = GetFecBlockSize(modulationType);
831  m_nrBlocks = GetNrBlocks(burstSize, modulationType);
832  m_paddingBits = (m_nrBlocks * m_blockSize) - (burstSize * 8);
834  NS_ASSERT_MSG(static_cast<uint32_t>(m_nrBlocks * m_blockSize) >= (burstSize * 8),
835  "Size of padding bytes < 0");
836 }
837 
838 uint16_t
840 {
841  // assumed equal to 2 symbols
842  return 2 * GetPsPerSymbol();
843 }
844 
845 uint16_t
847 {
848  // assumed equal to 2 symbols
849  return 2 * GetPsPerSymbol();
850 }
851 
852 uint8_t
854 {
855  uint16_t duration = 0;
856  duration = (uint16_t)(GetFrameDuration().GetSeconds() * 10000);
857  uint8_t retval = 0;
858  switch (duration)
859  {
860  case 25: {
862  break;
863  }
864  case 40: {
865  retval = FRAME_DURATION_4_MS;
866  break;
867  }
868  case 50: {
869  retval = FRAME_DURATION_5_MS;
870  break;
871  }
872  case 80: {
873  retval = FRAME_DURATION_8_MS;
874  break;
875  }
876  case 100: {
877  retval = FRAME_DURATION_10_MS;
878  break;
879  }
880  case 125: {
882  break;
883  }
884  case 200: {
885  retval = FRAME_DURATION_20_MS;
886  break;
887  }
888  default: {
889  NS_FATAL_ERROR("Invalid frame duration = " << duration);
890  retval = 0;
891  }
892  }
893  return retval;
894 }
895 
896 Time
897 SimpleOfdmWimaxPhy::DoGetFrameDuration(uint8_t frameDurationCode) const
898 {
899  switch (frameDurationCode)
900  {
902  return Seconds(2.5);
903  break;
904  case FRAME_DURATION_4_MS:
905  return Seconds(4);
906  break;
907  case FRAME_DURATION_5_MS:
908  return Seconds(5);
909  break;
910  case FRAME_DURATION_8_MS:
911  return Seconds(8);
912  break;
914  return Seconds(10);
915  break;
917  return Seconds(12.5);
918  break;
920  return Seconds(20);
921  break;
922  default:
923  NS_FATAL_ERROR("Invalid modulation type");
924  }
925  return Seconds(0);
926 }
927 
928 /*
929  Returns number of blocks (FEC blocks) the burst will be split in.
930  The size of the block is specific for each modulation type.
931  */
932 uint16_t
933 SimpleOfdmWimaxPhy::GetNrBlocks(uint32_t burstSize, WimaxPhy::ModulationType modulationType) const
934 {
935  uint32_t blockSize = GetFecBlockSize(modulationType);
936  uint16_t nrBlocks = (burstSize * 8) / blockSize;
937 
938  if ((burstSize * 8) % blockSize > 0)
939  {
940  nrBlocks += 1;
941  }
942 
943  return nrBlocks;
944 }
945 
946 /*---------------------PHY parameters functions-----------------------*/
947 
948 void
950 {
951  /*Calculations as per section 8.3.2.
952  Currently assuming license-exempt 5 GHz band. For channel bandwidth 20 MHz (Table B.28, page
953  812) and frame duration 10 ms (Table 232, page 460) i.e, 100 frames per second, sampling
954  frequency is 23040000, symbol (OFDM symbol) duration is 1.388888888888889e-05 seconds, PS
955  duration is 1.7361111111111112e-07 seconds. Hence PSs per frame is 57600, symbols per frame is
956  720 and PSs per symbol is 80. Note that defining these parameters (symbol and PS duration) as
957  Time may not result in exactly these values therefore lrint has been used (otherwise should be
958  defined as double). For licensed bands set channel bandwidth according to Table B.26, page
959  810.*/
960 
961  double samplingFrequency = DoGetSamplingFrequency();
962  Time psDuration = Seconds(4.0 / samplingFrequency);
963 
964  SetPsDuration(psDuration);
965  uint16_t psPerFrame = (uint16_t)(GetFrameDuration().GetSeconds() / psDuration.GetSeconds());
966  SetPsPerFrame(psPerFrame);
967  double subcarrierSpacing = samplingFrequency / DoGetNfft();
968  double tb = 1.0 / subcarrierSpacing; // Tb (useful symbol time)
969  double tg = DoGetGValue() * tb; // Tg (cyclic prefix time)
970  Time symbolDuration = Seconds(tb + tg); // OFDM Symbol Time
971  SetSymbolDuration(symbolDuration);
972  uint16_t psPerSymbol = lrint(symbolDuration.GetSeconds() / psDuration.GetSeconds());
973  SetPsPerSymbol(psPerSymbol);
974  uint32_t symbolsPerFrame = lrint(GetFrameDuration().GetSeconds() / symbolDuration.GetSeconds());
975  SetSymbolsPerFrame(symbolsPerFrame);
976 }
977 
978 void
980 {
981  m_nfft = nfft;
982 }
983 
984 uint16_t
986 {
987  return m_nfft;
988 }
989 
990 double
992 {
993  // sampling factor (n), see Table 213, page 429
994 
995  uint32_t channelBandwidth = GetChannelBandwidth();
996 
997  if (channelBandwidth % 1750000 == 0)
998  {
999  return 8.0 / 7;
1000  }
1001  else if (channelBandwidth % 1500000 == 0)
1002  {
1003  return 86.0 / 75;
1004  }
1005  else if (channelBandwidth % 1250000 == 0)
1006  {
1007  return 144.0 / 125;
1008  }
1009  else if (channelBandwidth % 2750000 == 0)
1010  {
1011  return 316.0 / 275;
1012  }
1013  else if (channelBandwidth % 2000000 == 0)
1014  {
1015  return 57.0 / 50;
1016  }
1017  else
1018  {
1019  NS_LOG_DEBUG("Oops may be wrong channel bandwidth for OFDM PHY!");
1020  NS_FATAL_ERROR("wrong channel bandwidth for OFDM PHY");
1021  }
1022 
1023  return 8.0 / 7;
1024 }
1025 
1026 double
1028 {
1029  // sampling frequency (Fs), see 8.3.2.2
1030 
1031  return (DoGetSamplingFactor() * GetChannelBandwidth() / 8000) * 8000;
1032 }
1033 
1034 double
1036 {
1037  return m_g;
1038 }
1039 
1040 void
1042 {
1043  m_g = g;
1044 }
1045 
1046 void
1048 {
1049  m_txGain = txGain;
1050 }
1051 
1052 void
1054 {
1055  m_rxGain = txRain;
1056 }
1057 
1058 double
1060 {
1061  return m_txGain;
1062 }
1063 
1064 double
1066 {
1067  return m_rxGain;
1068 }
1069 
1070 std::string
1072 {
1074 }
1075 
1076 void
1078 {
1081 }
1082 
1083 void
1085 {
1086  m_phyTxBeginTrace(burst);
1087 }
1088 
1089 void
1091 {
1092  m_phyTxEndTrace(burst);
1093 }
1094 
1095 void
1097 {
1098  m_phyTxDropTrace(burst);
1099 }
1100 
1101 void
1103 {
1104  m_phyRxBeginTrace(burst);
1105 }
1106 
1107 void
1109 {
1110  m_phyRxEndTrace(burst);
1111 }
1112 
1113 void
1115 {
1116  m_phyRxDropTrace(burst);
1117 }
1118 
1119 int64_t
1121 {
1122  NS_LOG_FUNCTION(this << stream);
1123  m_URNG->SetStream(stream);
1124  return 1;
1125 }
1126 
1127 } // 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
Ptr< PacketBurst > GetBurst() const
Definition: send-params.h:83
uint8_t GetModulationType() const
Definition: send-params.h:91
uint8_t GetDirection() const
Definition: send-params.h:99
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
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:78
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
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.
uint16_t m_nrRecivedFecBlocks
number received FEC blocks
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:568
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:276
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:402
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
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:309
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:375
Ptr< WimaxChannel > GetChannel() const
Definition: wimax-phy.cc:118
void SetChannelBandwidth(uint32_t channelBandwidth)
Set the channel bandwidth.
Definition: wimax-phy.cc:333
uint64_t GetRxFrequency() const
Get the reception frequency.
Definition: wimax-phy.cc:181
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:381
uint8_t GetNrCarriers() const
Get the number of carriers in the physical frame.
Definition: wimax-phy.cc:297
PhyState GetState() const
Get the state of the device.
Definition: wimax-phy.cc:205
void SetSymbolsPerFrame(uint32_t symbolsPerFrame)
set the number of symbols per frame
Definition: wimax-phy.cc:417
void SetScanningCallback() const
calls the scanning call back function
Definition: wimax-phy.cc:223
void SetNrCarriers(uint8_t nrCarriers)
Set the number of carriers in the physical frame.
Definition: wimax-phy.cc:291
void DoDispose() override
Destructor implementation.
Definition: wimax-phy.cc:104
void SetPsPerFrame(uint16_t psPerFrame)
set the number of physical slots per frame
Definition: wimax-phy.cc:405
@ PHY_STATE_SCANNING
Definition: wimax-phy.h:68
void SetSimplex(uint64_t frequency)
configure the physical layer in simplex mode
Definition: wimax-phy.cc:174
uint64_t GetScanningFrequency() const
Get the scanning frequency.
Definition: wimax-phy.cc:193
void SetPsDuration(Time psDuration)
set the physical slot duration
Definition: wimax-phy.cc:363
uint16_t GetPsPerSymbol() const
Get the number of physical slots per symbol.
Definition: wimax-phy.cc:399
void SetState(PhyState state)
set the state of the device
Definition: wimax-phy.cc:199
uint32_t GetChannelBandwidth() const
Get the channel bandwidth.
Definition: wimax-phy.cc:339
EventId GetChnlSrchTimeoutEvent() const
Get channel search timeout event.
Definition: wimax-phy.cc:217
bool IsDuplex() const
Check if configured in duplex mode.
Definition: wimax-phy.cc:211
Callback< void, Ptr< const PacketBurst > > GetReceiveCallback() const
Definition: wimax-phy.cc:161
void SetPsPerSymbol(uint16_t psPerSymbol)
set the number of physical slots per symbol
Definition: wimax-phy.cc:393
uint64_t GetTxFrequency() const
Get the transmission frequency.
Definition: wimax-phy.cc:187
#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
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: double.h:43
Ptr< const AttributeChecker > MakeStringChecker()
Definition: string.cc:30
Ptr< const AttributeAccessor > MakeStringAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: string.h:57
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:46
#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:1372
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
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
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:488
channel
Definition: third.py:81
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
#define list
constexpr double BW
static const uint32_t packetSize
Packet size generated at the AP.