Bug Summary

File:/tmp/asd-nat/home/nat/Work/ns-3-dev-git/build/../src/wimax/model/simple-ofdm-wimax-phy.cc
Location:line 552, column 33
Description:The left operand of '>>' is a garbage value

Annotated Source Code

1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2007,2008, 2009 INRIA, UDcast
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
19 * <amine.ismail@udcast.com>
20 */
21
22#include "ns3/simulator.h"
23#include "ns3/packet.h"
24#include "ns3/node.h"
25#include "ns3/uinteger.h"
26#include "ns3/double.h"
27#include "ns3/string.h"
28#include "wimax-net-device.h"
29#include "simple-ofdm-wimax-phy.h"
30#include "wimax-channel.h"
31#include "ns3/packet-burst.h"
32#include "wimax-mac-header.h"
33#include "simple-ofdm-wimax-channel.h"
34#include "ns3/trace-source-accessor.h"
35#include <string>
36#include <cmath>
37
38namespace ns3 {
39
40NS_LOG_COMPONENT_DEFINE ("SimpleOfdmWimaxPhy")static ns3::LogComponent g_log = ns3::LogComponent ("SimpleOfdmWimaxPhy"
, "../src/wimax/model/simple-ofdm-wimax-phy.cc")
;
41
42NS_OBJECT_ENSURE_REGISTERED (SimpleOfdmWimaxPhy)static struct ObjectSimpleOfdmWimaxPhyRegistrationClass { ObjectSimpleOfdmWimaxPhyRegistrationClass
() { ns3::TypeId tid = SimpleOfdmWimaxPhy::GetTypeId (); tid
.SetSize (sizeof (SimpleOfdmWimaxPhy)); tid.GetParent (); } }
ObjectSimpleOfdmWimaxPhyRegistrationVariable
;
43
44TypeId SimpleOfdmWimaxPhy::GetTypeId (void)
45{
46 static TypeId tid = TypeId ("ns3::SimpleOfdmWimaxPhy")
47 .SetParent<WimaxPhy> ()
48 .SetGroupName ("Wimax")
49
50 .AddConstructor<SimpleOfdmWimaxPhy> ()
51
52 .AddAttribute ("NoiseFigure",
53 "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver.",
54 DoubleValue (5),
55 MakeDoubleAccessor (&SimpleOfdmWimaxPhy::SetNoiseFigure, &SimpleOfdmWimaxPhy::GetNoiseFigure),
56 MakeDoubleChecker<double> ())
57
58 .AddAttribute ("TxPower",
59 "Transmission power (dB).",
60 DoubleValue (30),
61 MakeDoubleAccessor (&SimpleOfdmWimaxPhy::SetTxPower, &SimpleOfdmWimaxPhy::GetTxPower),
62 MakeDoubleChecker<double> ())
63
64 .AddAttribute ("G",
65 "This is the ratio of CP time to useful time.",
66 DoubleValue (0.25),
67 MakeDoubleAccessor (&SimpleOfdmWimaxPhy::DoSetGValue, &SimpleOfdmWimaxPhy::DoGetGValue),
68 MakeDoubleChecker<double> ())
69
70 .AddAttribute ("TxGain",
71 "Transmission gain (dB).",
72 DoubleValue (0),
73 MakeDoubleAccessor (&SimpleOfdmWimaxPhy::SetTxGain, &SimpleOfdmWimaxPhy::GetTxGain),
74 MakeDoubleChecker<double> ())
75
76 .AddAttribute ("RxGain",
77 "Reception gain (dB).",
78 DoubleValue (0),
79 MakeDoubleAccessor (&SimpleOfdmWimaxPhy::SetRxGain, &SimpleOfdmWimaxPhy::GetRxGain),
80 MakeDoubleChecker<double> ())
81
82 .AddAttribute ("Nfft",
83 "FFT size",
84 UintegerValue (256),
85 MakeUintegerAccessor (&SimpleOfdmWimaxPhy::DoSetNfft, &SimpleOfdmWimaxPhy::DoGetNfft),
86 MakeUintegerChecker<uint16_t> (256, 1024))
87
88 .AddAttribute ("TraceFilePath",
89 "Path to the directory containing SNR to block error rate files",
90 StringValue (""),
91 MakeStringAccessor (&SimpleOfdmWimaxPhy::GetTraceFilePath,
92 &SimpleOfdmWimaxPhy::SetTraceFilePath),
93 MakeStringChecker ())
94
95 .AddTraceSource ("Rx", "Receive trace",
96 MakeTraceSourceAccessor (&SimpleOfdmWimaxPhy::m_traceRx),
97 "ns3::PacketBurst::TracedCallback")
98 .AddTraceSource ("Tx", "Transmit trace",
99 MakeTraceSourceAccessor (&SimpleOfdmWimaxPhy::m_traceTx),
100 "ns3::PacketBurst::TracedCallback")
101
102 .AddTraceSource ("PhyTxBegin",
103 "Trace source indicating a packet has begun transmitting over the channel medium",
104 MakeTraceSourceAccessor (&SimpleOfdmWimaxPhy::m_phyTxBeginTrace),
105 "ns3::PacketBurst::TracedCallback")
106
107 .AddTraceSource ("PhyTxEnd",
108 "Trace source indicating a packet has been completely transmitted over the channel",
109 MakeTraceSourceAccessor (&SimpleOfdmWimaxPhy::m_phyTxEndTrace),
110 "ns3::PacketBurst::TracedCallback")
111
112 .AddTraceSource ("PhyTxDrop",
113 "Trace source indicating a packet has been dropped by the device during transmission",
114 MakeTraceSourceAccessor (&SimpleOfdmWimaxPhy::m_phyTxDropTrace),
115 "ns3::PacketBurst::TracedCallback")
116
117 .AddTraceSource ("PhyRxBegin",
118 "Trace source indicating a packet has begun being received from the channel medium by the device",
119 MakeTraceSourceAccessor (&SimpleOfdmWimaxPhy::m_phyRxBeginTrace),
120 "ns3::PacketBurst::TracedCallback")
121
122 .AddTraceSource ("PhyRxEnd",
123 "Trace source indicating a packet has been completely received from the channel medium by the device",
124 MakeTraceSourceAccessor (&SimpleOfdmWimaxPhy::m_phyRxEndTrace),
125 "ns3::PacketBurst::TracedCallback")
126
127 .AddTraceSource ("PhyRxDrop",
128 "Trace source indicating a packet has been dropped by the device during reception",
129 MakeTraceSourceAccessor (&SimpleOfdmWimaxPhy::m_phyRxDropTrace),
130 "ns3::PacketBurst::TracedCallback");
131 return tid;
132}
133
134void
135SimpleOfdmWimaxPhy::InitSimpleOfdmWimaxPhy (void)
136{
137 m_fecBlockSize = 0;
138 m_nrFecBlocksSent = 0;
139 m_dataRateBpsk12 = 0;
140 m_dataRateQpsk12 = 0;
141 m_dataRateQpsk34 = 0;
142 m_dataRateQam16_12 = 0;
143
144 m_dataRateQam16_34 = 0;
145 m_dataRateQam64_23 = 0;
146 m_dataRateQam64_34 = 0;
147
148 m_nrBlocks = 0;
149 m_blockSize = 0;
150 m_paddingBits = 0;
151 m_rxGain = 0;
152 m_txGain = 0;
153 m_nfft = 256;
154 m_g = (double) 1 / 4;
155 SetNrCarriers (192);
156 m_fecBlocks = new std::list<bvec>;
157 m_receivedFecBlocks = new std::list<bvec>;
158 m_currentBurstSize = 0;
159 m_noiseFigure = 5; // dB
160 m_txPower = 30; // dBm
161 SetBandwidth (10000000); // 10Mhz
162 m_nbErroneousBlock = 0;
163 m_nrRecivedFecBlocks = 0;
164 m_snrToBlockErrorRateManager = new SNRToBlockErrorRateManager ();
165}
166
167SimpleOfdmWimaxPhy::SimpleOfdmWimaxPhy (void)
168{
169 m_URNG = CreateObject<UniformRandomVariable> ();
170
171 InitSimpleOfdmWimaxPhy ();
172 m_snrToBlockErrorRateManager->SetTraceFilePath ((char*) "");
173 m_snrToBlockErrorRateManager->LoadTraces ();
174}
175
176SimpleOfdmWimaxPhy::SimpleOfdmWimaxPhy (char * tracesPath)
177{
178 InitSimpleOfdmWimaxPhy ();
179 m_snrToBlockErrorRateManager->SetTraceFilePath (tracesPath);
180 m_snrToBlockErrorRateManager->LoadTraces ();
181}
182
183SimpleOfdmWimaxPhy::~SimpleOfdmWimaxPhy (void)
184{
185
186}
187
188void
189SimpleOfdmWimaxPhy::ActivateLoss (bool loss)
190{
191 m_snrToBlockErrorRateManager->ActivateLoss (loss);
192}
193
194void
195SimpleOfdmWimaxPhy::SetSNRToBlockErrorRateTracesPath (char * tracesPath)
196{
197 m_snrToBlockErrorRateManager->SetTraceFilePath (tracesPath);
198 m_snrToBlockErrorRateManager->ReLoadTraces ();
199}
200
201uint32_t
202SimpleOfdmWimaxPhy::GetBandwidth (void) const
203{
204 return WimaxPhy::GetChannelBandwidth ();
205}
206
207void
208SimpleOfdmWimaxPhy::SetBandwidth (uint32_t BW)
209{
210 WimaxPhy::SetChannelBandwidth (BW);
211}
212
213double
214SimpleOfdmWimaxPhy::GetTxPower (void) const
215{
216 return m_txPower;
217}
218void
219SimpleOfdmWimaxPhy::SetTxPower (double txPower)
220{
221 m_txPower = txPower;
222}
223
224double
225SimpleOfdmWimaxPhy::GetNoiseFigure (void) const
226{
227 return m_noiseFigure;
228}
229void
230SimpleOfdmWimaxPhy::SetNoiseFigure (double noiseFigure)
231{
232 m_noiseFigure = noiseFigure;
233}
234
235void
236SimpleOfdmWimaxPhy::DoDispose (void)
237{
238 delete m_receivedFecBlocks;
239 delete m_fecBlocks;
240 m_receivedFecBlocks = 0;
241 m_fecBlocks = 0;
242 delete m_snrToBlockErrorRateManager;
243 WimaxPhy::DoDispose ();
244}
245
246void
247SimpleOfdmWimaxPhy::DoAttach (Ptr<WimaxChannel> channel)
248{
249 GetChannel ()->Attach (this);
250}
251
252void
253SimpleOfdmWimaxPhy::Send (SendParams *params)
254{
255 OfdmSendParams *o_params = dynamic_cast<OfdmSendParams*> (params);
256 NS_ASSERT (o_params !=0)do { if (!(o_params !=0)) { std::cerr << "assert failed. cond=\""
<< "o_params !=0" << "\", "; do { std::cerr <<
"file=" << "../src/wimax/model/simple-ofdm-wimax-phy.cc"
<< ", line=" << 256 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } } while (false)
;
257 Send (o_params->GetBurst (),
258 (WimaxPhy::ModulationType) o_params->GetModulationType (),
259 o_params->GetDirection ());
260
261}
262
263WimaxPhy::PhyType
264SimpleOfdmWimaxPhy::GetPhyType (void) const
265{
266 return WimaxPhy::simpleOfdmWimaxPhy;
267}
268
269void
270SimpleOfdmWimaxPhy::Send (Ptr<PacketBurst> burst,
271 WimaxPhy::ModulationType modulationType,
272 uint8_t direction)
273{
274
275 if (GetState () != PHY_STATE_TX)
276 {
277 m_currentBurstSize = burst->GetSize ();
278 m_nrFecBlocksSent = 0;
279 m_currentBurst = burst;
280 SetBlockParameters (burst->GetSize (), modulationType);
281 NotifyTxBegin (m_currentBurst);
282 StartSendDummyFecBlock (true, modulationType, direction);
283 m_traceTx (burst);
284 }
285}
286
287void
288SimpleOfdmWimaxPhy::StartSendDummyFecBlock (bool isFirstBlock,
289 WimaxPhy::ModulationType modulationType,
290 uint8_t direction)
291{
292 SetState (PHY_STATE_TX);
293 bool isLastFecBlock = 0;
294 if (isFirstBlock)
295 {
296 m_blockTime = GetBlockTransmissionTime (modulationType);
297 }
298
299 SimpleOfdmWimaxChannel *channel = dynamic_cast<SimpleOfdmWimaxChannel*> (PeekPointer (GetChannel ()));
300 NS_ASSERT (channel != 0)do { if (!(channel != 0)) { std::cerr << "assert failed. cond=\""
<< "channel != 0" << "\", "; do { std::cerr <<
"file=" << "../src/wimax/model/simple-ofdm-wimax-phy.cc"
<< ", line=" << 300 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } } while (false)
;
301
302 if (m_nrRemainingBlocksToSend==1)
303 {
304 isLastFecBlock = true;
305 }
306 else
307 {
308 isLastFecBlock = false;
309 }
310 channel->Send (m_blockTime,
311 m_currentBurstSize,
312 this,
313 isFirstBlock,
314 isLastFecBlock,
315 GetTxFrequency (),
316 modulationType,
317 direction,
318 m_txPower,
319 m_currentBurst);
320
321 m_nrRemainingBlocksToSend--;
322 Simulator::Schedule (m_blockTime, &SimpleOfdmWimaxPhy::EndSendFecBlock, this, modulationType, direction);
323}
324
325
326void
327SimpleOfdmWimaxPhy::EndSendFecBlock (WimaxPhy::ModulationType modulationType,
328 uint8_t direction)
329{
330 m_nrFecBlocksSent++;
331 SetState (PHY_STATE_IDLE);
332
333 if (m_nrFecBlocksSent * m_blockSize == m_currentBurstSize * 8 + m_paddingBits)
334 {
335 // this is the last FEC block of the burst
336 NS_ASSERT_MSG (m_nrRemainingBlocksToSend == 0, "Error while sending a burst")do { if (!(m_nrRemainingBlocksToSend == 0)) { std::cerr <<
"assert failed. cond=\"" << "m_nrRemainingBlocksToSend == 0"
<< "\", "; do { std::cerr << "msg=\"" << "Error while sending a burst"
<< "\", "; do { std::cerr << "file=" << "../src/wimax/model/simple-ofdm-wimax-phy.cc"
<< ", line=" << 336 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
337 NotifyTxEnd (m_currentBurst);
338 }
339 else
340 {
341 StartSendDummyFecBlock (false,modulationType,direction);
342 }
343}
344
345void
346SimpleOfdmWimaxPhy::EndSend (void)
347{
348 SetState (PHY_STATE_IDLE);
349}
350
351void
352SimpleOfdmWimaxPhy::StartReceive (uint32_t burstSize,
353 bool isFirstBlock,
354 uint64_t frequency,
355 WimaxPhy::ModulationType modulationType,
356 uint8_t direction,
357 double rxPower,
358 Ptr<PacketBurst> burst)
359{
360
361 uint8_t drop = 0;
362 double Nwb = -114 + m_noiseFigure + 10 * std::log (GetBandwidth () / 1000000000.0) / 2.303;
363 double SNR = rxPower - Nwb;
364
365 SNRToBlockErrorRateRecord * record = m_snrToBlockErrorRateManager->GetSNRToBlockErrorRateRecord (SNR, modulationType);
366 double I1 = record->GetI1 ();
367 double I2 = record->GetI2 ();
368
369 double blockErrorRate = m_URNG->GetValue (I1, I2);
370
371 double rand = m_URNG->GetValue (0.0, 1.0);
372
373 if (rand < blockErrorRate)
374 {
375 drop = 1;
376 }
377 if (rand > blockErrorRate)
378 {
379 drop = 0;
380 }
381
382 if (blockErrorRate == 1.0)
383 {
384 drop = 1;
385 }
386 if (blockErrorRate == 0.0)
387 {
388 drop = 0;
389 }
390 delete record;
391
392 NS_LOG_INFO ("PHY: Receive rxPower=" << rxPower << ", Nwb=" << Nwb << ", SNR=" << SNR << ", Modulation="do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "PHY: Receive rxPower="
<< rxPower << ", Nwb=" << Nwb << ", SNR="
<< SNR << ", Modulation=" << modulationType
<< ", BlocErrorRate=" << blockErrorRate <<
", drop=" << (int) drop << std::endl; } } while (
false)
393 << modulationType << ", BlocErrorRate=" << blockErrorRate << ", drop=" << (int) drop)do { if (g_log.IsEnabled (ns3::LOG_INFO)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_INFO) << "] "; }; std::clog << "PHY: Receive rxPower="
<< rxPower << ", Nwb=" << Nwb << ", SNR="
<< SNR << ", Modulation=" << modulationType
<< ", BlocErrorRate=" << blockErrorRate <<
", drop=" << (int) drop << std::endl; } } while (
false)
;
394
395 switch (GetState ())
396 {
397 case PHY_STATE_SCANNING:
398 if (frequency == GetScanningFrequency ())
399 {
400 Simulator::Cancel (GetChnlSrchTimeoutEvent ());
401 SetScanningCallback ();
402 SetSimplex (frequency);
403 SetState (PHY_STATE_IDLE);
404 }
405 break;
406 case PHY_STATE_IDLE:
407 if (frequency == GetRxFrequency ())
408 {
409 if (isFirstBlock)
410 {
411 NotifyRxBegin (burst);
412 m_receivedFecBlocks->clear ();
413 m_nrRecivedFecBlocks=0;
414 SetBlockParameters (burstSize, modulationType);
415 m_blockTime = GetBlockTransmissionTime (modulationType);
416 }
417
418 Simulator::Schedule (m_blockTime,
419 &SimpleOfdmWimaxPhy::EndReceiveFecBlock,
420 this,
421 burstSize,
422 modulationType,
423 direction,
424 drop,
425 burst);
426
427 SetState (PHY_STATE_RX);
428 }
429 break;
430 case PHY_STATE_RX:
431 // drop
432 break;
433 case PHY_STATE_TX:
434 if (IsDuplex () && frequency == GetRxFrequency ())
435 {
436
437 }
438 break;
439 }
440}
441
442void
443SimpleOfdmWimaxPhy::EndReceiveFecBlock (uint32_t burstSize,
444 WimaxPhy::ModulationType modulationType,
445 uint8_t direction,
446 uint8_t drop,
447 Ptr<PacketBurst> burst)
448{
449 SetState (PHY_STATE_IDLE);
450 m_nrRecivedFecBlocks++;
451
452 if (drop == true)
453 {
454 m_nbErroneousBlock++;
455 }
456
457 if ((uint32_t) m_nrRecivedFecBlocks * m_blockSize == burstSize * 8 + m_paddingBits)
458 {
459 NotifyRxEnd (burst);
460 if (m_nbErroneousBlock == 0)
461 {
462 Simulator::Schedule (Seconds (0),
463 &SimpleOfdmWimaxPhy::EndReceive,
464 this,
465 burst);
466 }
467 else
468 {
469 NotifyRxDrop (burst);
470 }
471 m_nbErroneousBlock = 0;
472 m_nrRecivedFecBlocks = 0;
473 }
474}
475
476void
477SimpleOfdmWimaxPhy::EndReceive (Ptr<const PacketBurst> burst)
478{
479 Ptr<PacketBurst> b = burst->Copy ();
480 GetReceiveCallback () (b);
481 m_traceRx (burst);
482}
483
484bvec
485SimpleOfdmWimaxPhy::ConvertBurstToBits (Ptr<const PacketBurst> burst)
486{
487 bvec buffer (burst->GetSize () * 8, 0);
488
489 std::list<Ptr<Packet> > packets = burst->GetPackets ();
490
491 uint32_t j = 0;
492 for (std::list<Ptr<Packet> >::iterator iter = packets.begin (); iter != packets.end (); ++iter)
493 {
494 Ptr<Packet> packet = *iter;
495 uint8_t *pstart = (uint8_t*) std::malloc (packet->GetSize ());
496 std::memset (pstart, 0, packet->GetSize ());
497 packet->CopyData (pstart, packet->GetSize ());
498 bvec temp (8);
499 temp.resize (0, 0);
500 temp.resize (8, 0);
501 for (uint32_t i = 0; i < packet->GetSize (); i++)
502 {
503 for (uint8_t l = 0; l < 8; l++)
504 {
505 temp[l] = (bool)((((uint8_t) pstart[i]) >> (7 - l)) & 0x01);
506 buffer.at (j * 8 + l) = temp[l];
507 }
508 j++;
509 }
510 std::free (pstart);
511 }
512
513 return buffer;
514}
515
516/*
517 Converts back the bit buffer (bvec) to the actual burst.
518 Actually creates byte buffer from the bvec and resets the buffer
519 of each packet in the copy of the orifinal burst stored before transmitting.
520 By doing this it preserves the metadata and tags in the packet.
521 Function could also be named DeserializeBurst because actually it
522 copying to the burst's byte buffer.
523 */
524Ptr<PacketBurst>
525SimpleOfdmWimaxPhy::ConvertBitsToBurst (bvec buffer)
526{
527 uint8_t init[buffer.size () / 8];
528 uint8_t *pstart = init;
529 uint8_t temp;
530 int32_t j = 0;
531 // recreating byte buffer from bit buffer (bvec)
532 for (uint32_t i = 0; i < buffer.size (); i += 8)
1
Loop condition is false. Execution continues on line 545
533 {
534
535 temp = 0;
536 for (int l = 0; l < 8; l++)
537 {
538 bool bin = buffer.at (i + l);
539 temp += (uint8_t)(bin * std::pow (2.0, (7 - l)));
540 }
541
542 *(pstart + j) = temp;
543 j++;
544 }
545 uint16_t bufferSize = buffer.size () / 8;
546 uint16_t pos = 0;
547 Ptr<PacketBurst> RecvBurst = Create<PacketBurst> ();
548 while (pos < bufferSize)
2
Assuming 'pos' is < 'bufferSize'
3
Loop condition is true. Entering loop body
549 {
550 uint16_t packetSize = 0;
551 // Get the header type: first bit
552 uint8_t ht = (pstart[pos] >> 7) & 0x01;
4
The left operand of '>>' is a garbage value
553 if (ht == 1)
554 {
555 // BW request header. Size is always 8 bytes
556 packetSize = 6;
557 }
558 else
559 {
560 // Read the size
561 uint8_t Len_MSB = pstart[pos + 1] & 0x07;
562 packetSize = (uint16_t)((uint16_t)(Len_MSB << 8) | (uint16_t)(pstart[pos + 2]));
563 if (packetSize == 0)
564 {
565 break; // padding
566 }
567 }
568
569 Ptr<Packet> p = Create<Packet> (&(pstart[pos]), packetSize);
570 RecvBurst->AddPacket (p);
571 pos += packetSize;
572 }
573 return RecvBurst;
574}
575
576void
577SimpleOfdmWimaxPhy::CreateFecBlocks (const bvec &buffer, WimaxPhy::ModulationType modulationType)
578{
579
580 bvec fecBlock (m_blockSize);
581 for (uint32_t i = 0, j = m_nrBlocks; j > 0; i += m_blockSize, j--)
582 {
583
584 if (j == 1 && m_paddingBits > 0) // last block can be smaller than block size
585 {
586 fecBlock = bvec (buffer.begin () + i, buffer.end ());
587 fecBlock.resize (m_blockSize, 0);
588 }
589 else
590 {
591 fecBlock = bvec (buffer.begin () + i, buffer.begin () + i + m_blockSize);
592 }
593
594 m_fecBlocks->push_back (fecBlock);
595 }
596}
597
598bvec
599SimpleOfdmWimaxPhy::RecreateBuffer ()
600{
601
602 bvec buffer (m_blockSize * (unsigned long)m_nrBlocks);
603 bvec block (m_blockSize);
604 uint32_t i = 0;
605 for (uint32_t j = 0; j < m_nrBlocks; j++)
606 {
607 bvec tmpRecFecBloc = m_receivedFecBlocks->front ();
608 buffer.insert (buffer.begin () + i, tmpRecFecBloc.begin (), tmpRecFecBloc.end ());
609 m_receivedFecBlocks->pop_front ();
610 i += m_blockSize;
611 }
612 return buffer;
613}
614
615void
616SimpleOfdmWimaxPhy::DoSetDataRates (void)
617{
618 m_dataRateBpsk12 = CalculateDataRate (MODULATION_TYPE_BPSK_12); // 6912000 bps
619 m_dataRateQpsk12 = CalculateDataRate (MODULATION_TYPE_QPSK_12); // 13824000
620 m_dataRateQpsk34 = CalculateDataRate (MODULATION_TYPE_QPSK_34); // 20736000
621 m_dataRateQam16_12 = CalculateDataRate (MODULATION_TYPE_QAM16_12); // 27648000
622 m_dataRateQam16_34 = CalculateDataRate (MODULATION_TYPE_QAM16_34); // 41472000
623 m_dataRateQam64_23 = CalculateDataRate (MODULATION_TYPE_QAM64_23); // 55224000
624 m_dataRateQam64_34 = CalculateDataRate (MODULATION_TYPE_QAM64_34); // 62208000
625}
626
627void
628SimpleOfdmWimaxPhy::GetModulationFecParams (WimaxPhy::ModulationType modulationType,
629 uint8_t &bitsPerSymbol,
630 double &fecCode) const
631{
632 switch (modulationType)
633 {
634 case MODULATION_TYPE_BPSK_12:
635 bitsPerSymbol = 1;
636 fecCode = (double) 1 / 2;
637 break;
638 case MODULATION_TYPE_QPSK_12:
639 bitsPerSymbol = 2;
640 fecCode = (double) 1 / 2;
641 break;
642 case MODULATION_TYPE_QPSK_34:
643 bitsPerSymbol = 2;
644 fecCode = (double) 3 / 4;
645 break;
646 case MODULATION_TYPE_QAM16_12:
647 bitsPerSymbol = 4;
648 fecCode = (double) 1 / 2;
649 break;
650 case MODULATION_TYPE_QAM16_34:
651 bitsPerSymbol = 4;
652 fecCode = (double) 3 / 4;
653 break;
654 case MODULATION_TYPE_QAM64_23:
655 bitsPerSymbol = 6;
656 fecCode = (double) 2 / 3;
657 break;
658 case MODULATION_TYPE_QAM64_34:
659 bitsPerSymbol = 6;
660 fecCode = 0.75;
661 break;
662 }
663}
664
665uint32_t
666SimpleOfdmWimaxPhy::CalculateDataRate (WimaxPhy::ModulationType modulationType) const
667{
668 uint8_t bitsPerSymbol = 0;
669 double fecCode = 0;
670 GetModulationFecParams (modulationType, bitsPerSymbol, fecCode);
671 double symbolsPerSecond = 1 / GetSymbolDuration ().GetSeconds ();
672 uint16_t bitsTransmittedPerSymbol = (uint16_t)(bitsPerSymbol * GetNrCarriers () * fecCode);
673 // 96, 192, 288, 384, 576, 767 and 864 bits per symbol for the seven modulations, respectively
674
675 return (uint32_t) symbolsPerSecond * bitsTransmittedPerSymbol;
676}
677
678uint32_t
679SimpleOfdmWimaxPhy::DoGetDataRate (WimaxPhy::ModulationType modulationType) const
680{
681 switch (modulationType)
682 {
683 case MODULATION_TYPE_BPSK_12:
684 return m_dataRateBpsk12;
685 break;
686 case MODULATION_TYPE_QPSK_12:
687 return m_dataRateQpsk12;
688 break;
689 case MODULATION_TYPE_QPSK_34:
690 return m_dataRateQpsk34;
691 break;
692 case MODULATION_TYPE_QAM16_12:
693 return m_dataRateQam16_12;
694 break;
695 case MODULATION_TYPE_QAM16_34:
696 return m_dataRateQam16_34;
697 break;
698 case MODULATION_TYPE_QAM64_23:
699 return m_dataRateQam64_23;
700 break;
701 case MODULATION_TYPE_QAM64_34:
702 return m_dataRateQam64_34;
703 break;
704 }
705 NS_FATAL_ERROR ("Invalid modulation type")do { std::cerr << "msg=\"" << "Invalid modulation type"
<< "\", "; do { std::cerr << "file=" << "../src/wimax/model/simple-ofdm-wimax-phy.cc"
<< ", line=" << 705 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false)
;
706 return 0;
707}
708
709Time
710SimpleOfdmWimaxPhy::GetBlockTransmissionTime (WimaxPhy::ModulationType modulationType) const
711{
712 return Seconds ((double) GetFecBlockSize (modulationType) / DoGetDataRate (modulationType));
713}
714
715Time
716SimpleOfdmWimaxPhy::DoGetTransmissionTime (uint32_t size, WimaxPhy::ModulationType modulationType) const
717{
718 /*adding 3 extra nano second to cope with the loss of precision problem.
719 the time is internally stored in a 64 bit hence a floating-point time would loss
720 precision, e.g., 0.00001388888888888889 seconds will become 13888888888 femtoseconds.*/
721 return Seconds (DoGetNrSymbols (size, modulationType) * GetSymbolDuration ().GetSeconds ()) + NanoSeconds (3);
722}
723
724uint64_t
725SimpleOfdmWimaxPhy::DoGetNrSymbols (uint32_t size, WimaxPhy::ModulationType modulationType) const
726{
727 Time transmissionTime = Seconds ((double)(GetNrBlocks (size, modulationType) * GetFecBlockSize (modulationType))
728 / DoGetDataRate (modulationType));
729 return (uint64_t) std::ceil (transmissionTime.GetSeconds () / GetSymbolDuration ().GetSeconds ());
730}
731
732uint64_t
733SimpleOfdmWimaxPhy::DoGetNrBytes (uint32_t symbols, WimaxPhy::ModulationType modulationType) const
734{
735 Time transmissionTime = Seconds (symbols * GetSymbolDuration ().GetSeconds ());
736 return (uint64_t) std::floor ((transmissionTime.GetSeconds () * DoGetDataRate (modulationType)) / 8);
737}
738
739uint32_t
740SimpleOfdmWimaxPhy::GetFecBlockSize (WimaxPhy::ModulationType modulationType) const
741{
742 uint32_t blockSize = 0;
743 switch (modulationType)
744 {
745 case MODULATION_TYPE_BPSK_12:
746 blockSize = 12;
747 break;
748 case MODULATION_TYPE_QPSK_12:
749 blockSize = 24;
750 break;
751 case MODULATION_TYPE_QPSK_34:
752 blockSize = 36;
753 break;
754 case MODULATION_TYPE_QAM16_12:
755 blockSize = 48;
756 break;
757 case MODULATION_TYPE_QAM16_34:
758 blockSize = 72;
759 break;
760 case MODULATION_TYPE_QAM64_23:
761 blockSize = 96;
762 break;
763 case MODULATION_TYPE_QAM64_34:
764 blockSize = 108;
765 break;
766 default:
767 NS_FATAL_ERROR ("Invalid modulation type")do { std::cerr << "msg=\"" << "Invalid modulation type"
<< "\", "; do { std::cerr << "file=" << "../src/wimax/model/simple-ofdm-wimax-phy.cc"
<< ", line=" << 767 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false)
;
768 break;
769 }
770 return blockSize * 8; // in bits
771}
772
773// Channel coding block size, Table 215, page 434
774uint32_t
775SimpleOfdmWimaxPhy::GetCodedFecBlockSize (WimaxPhy::ModulationType modulationType) const
776{
777 uint32_t blockSize = 0;
778 switch (modulationType)
779 {
780 case MODULATION_TYPE_BPSK_12:
781 blockSize = 24;
782 break;
783 case MODULATION_TYPE_QPSK_12:
784 blockSize = 48;
785 break;
786 case MODULATION_TYPE_QPSK_34:
787 blockSize = 48;
788 break;
789 case MODULATION_TYPE_QAM16_12:
790 blockSize = 96;
791 break;
792 case MODULATION_TYPE_QAM16_34:
793 blockSize = 96;
794 break;
795 case MODULATION_TYPE_QAM64_23:
796 blockSize = 144;
797 break;
798 case MODULATION_TYPE_QAM64_34:
799 blockSize = 144;
800 break;
801 default:
802 NS_FATAL_ERROR ("Invalid modulation type")do { std::cerr << "msg=\"" << "Invalid modulation type"
<< "\", "; do { std::cerr << "file=" << "../src/wimax/model/simple-ofdm-wimax-phy.cc"
<< ", line=" << 802 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false)
;
803 break;
804 }
805 return blockSize * 8; // in bits
806}
807
808void
809SimpleOfdmWimaxPhy::SetBlockParameters (uint32_t burstSize, WimaxPhy::ModulationType modulationType)
810{
811 m_blockSize = GetFecBlockSize (modulationType);
812 m_nrBlocks = GetNrBlocks (burstSize, modulationType);
813 m_paddingBits = (m_nrBlocks * m_blockSize) - (burstSize * 8);
814 m_nrRemainingBlocksToSend = m_nrBlocks;
815 NS_ASSERT_MSG (static_cast<uint32_t> (m_nrBlocks * m_blockSize) >= (burstSize * 8), "Size of padding bytes < 0")do { if (!(static_cast<uint32_t> (m_nrBlocks * m_blockSize
) >= (burstSize * 8))) { std::cerr << "assert failed. cond=\""
<< "static_cast<uint32_t> (m_nrBlocks * m_blockSize) >= (burstSize * 8)"
<< "\", "; do { std::cerr << "msg=\"" << "Size of padding bytes < 0"
<< "\", "; do { std::cerr << "file=" << "../src/wimax/model/simple-ofdm-wimax-phy.cc"
<< ", line=" << 815 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false); } } while (false)
;
816}
817
818uint16_t
819SimpleOfdmWimaxPhy::DoGetTtg (void) const
820{
821 // assumed equal to 2 symbols
822 return 2 * GetPsPerSymbol ();
823}
824
825uint16_t
826SimpleOfdmWimaxPhy::DoGetRtg (void) const
827{
828 // assumed equal to 2 symbols
829 return 2 * GetPsPerSymbol ();
830}
831
832uint8_t
833SimpleOfdmWimaxPhy::DoGetFrameDurationCode (void) const
834{
835 uint16_t duration = 0;
836 duration = (uint16_t)(GetFrameDuration ().GetSeconds () * 10000);
837 uint8_t retval = 0;
838 switch (duration)
839 {
840 case 25:
841 {
842 retval = FRAME_DURATION_2_POINT_5_MS;
843 break;
844 }
845 case 40:
846 {
847 retval = FRAME_DURATION_4_MS;
848 break;
849 }
850 case 50:
851 {
852 retval = FRAME_DURATION_5_MS;
853 break;
854 }
855 case 80:
856 {
857 retval = FRAME_DURATION_8_MS;
858 break;
859 }
860 case 100:
861 {
862 retval = FRAME_DURATION_10_MS;
863 break;
864 }
865 case 125:
866 {
867 retval = FRAME_DURATION_12_POINT_5_MS;
868 break;
869 }
870 case 200:
871 {
872 retval = FRAME_DURATION_20_MS;
873 break;
874 }
875 default:
876 {
877 NS_FATAL_ERROR ("Invalid frame duration = " << duration)do { std::cerr << "msg=\"" << "Invalid frame duration = "
<< duration << "\", "; do { std::cerr << "file="
<< "../src/wimax/model/simple-ofdm-wimax-phy.cc" <<
", line=" << 877 << std::endl; ::ns3::FatalImpl::
FlushStreams (); if (true) std::terminate (); } while (false)
; } while (false)
;
878 retval = 0;
879 }
880 }
881 return retval;
882}
883
884Time
885SimpleOfdmWimaxPhy::DoGetFrameDuration (uint8_t frameDurationCode) const
886{
887 switch (frameDurationCode)
888 {
889 case FRAME_DURATION_2_POINT_5_MS:
890 return Seconds (2.5);
891 break;
892 case FRAME_DURATION_4_MS:
893 return Seconds (4);
894 break;
895 case FRAME_DURATION_5_MS:
896 return Seconds (5);
897 break;
898 case FRAME_DURATION_8_MS:
899 return Seconds (8);
900 break;
901 case FRAME_DURATION_10_MS:
902 return Seconds (10);
903 break;
904 case FRAME_DURATION_12_POINT_5_MS:
905 return Seconds (12.5);
906 break;
907 case FRAME_DURATION_20_MS:
908 return Seconds (20);
909 break;
910 default:
911 NS_FATAL_ERROR ("Invalid modulation type")do { std::cerr << "msg=\"" << "Invalid modulation type"
<< "\", "; do { std::cerr << "file=" << "../src/wimax/model/simple-ofdm-wimax-phy.cc"
<< ", line=" << 911 << std::endl; ::ns3::FatalImpl
::FlushStreams (); if (true) std::terminate (); } while (false
); } while (false)
;
912 }
913 return Seconds (0);
914}
915
916/*
917 Retruns number of blocks (FEC blocks) the burst will be splitted in.
918 The size of the block is specific for each modulation type.
919 */
920uint16_t
921SimpleOfdmWimaxPhy::GetNrBlocks (uint32_t burstSize, WimaxPhy::ModulationType modulationType) const
922{
923 uint32_t blockSize = GetFecBlockSize (modulationType);
924 uint16_t nrBlocks = (burstSize * 8) / blockSize;
925
926 if ((burstSize * 8) % blockSize > 0)
927 {
928 nrBlocks += 1;
929 }
930
931 return nrBlocks;
932}
933/*---------------------PHY parameters functions-----------------------*/
934
935void
936SimpleOfdmWimaxPhy::DoSetPhyParameters (void)
937{
938 /*Calculations as per section 8.3.2.
939 Currently assuming license-exempt 5 GHz band. For channel bandwidth 20 MHz (Table B.28, page 812) and frame duration 10 ms
940 (Table 232, page 460) i.e, 100 frames per second, sampling frequency is 23040000, symbol (OFDM symbol) duration is
941 1.388888888888889e-05 seconds, PS duration is 1.7361111111111112e-07 seconds. Hence PSs per frame is 57600, symbols per frame
942 is 720 and PSs per symbol is 80. Note that defining these parameters (symbol and PS duration) as Time may not result in exaclty
943 these values therefore lrint has been used (otherwise should be defined as double).
944 For licensed bands set channel bandwidth according to Table B.26, page 810.*/
945
946 double samplingFrequency = DoGetSamplingFrequency ();
947 Time psDuration = Seconds ((double) 4 / samplingFrequency);
948
949 SetPsDuration (psDuration);
950 uint16_t psPerFrame = (uint16_t)(GetFrameDuration ().GetSeconds () / psDuration.GetSeconds ());
951 SetPsPerFrame (psPerFrame);
952 double subcarrierSpacing = samplingFrequency / DoGetNfft ();
953 double tb = (double) 1 / subcarrierSpacing; // Tb (useful symbol time)
954 double tg = DoGetGValue () * tb; // Tg (cyclic prefix time)
955 Time symbolDuration = Seconds (tb + tg); // OFDM Symbol Time
956 SetSymbolDuration (symbolDuration);
957 uint16_t psPerSymbol = lrint (symbolDuration.GetSeconds () / psDuration.GetSeconds ());
958 SetPsPerSymbol (psPerSymbol);
959 uint32_t symbolsPerFrame = lrint (GetFrameDuration ().GetSeconds () / symbolDuration.GetSeconds ());
960 SetSymbolsPerFrame (symbolsPerFrame);
961}
962
963void
964SimpleOfdmWimaxPhy::DoSetNfft (uint16_t nfft)
965{
966 m_nfft = nfft;
967
968}
969
970uint16_t
971SimpleOfdmWimaxPhy::DoGetNfft (void) const
972{
973 return m_nfft;
974
975}
976
977double
978SimpleOfdmWimaxPhy::DoGetSamplingFactor (void) const
979{
980 // sampling factor (n), see Table 213, page 429
981
982 uint32_t channelBandwidth = GetChannelBandwidth ();
983
984 if (channelBandwidth % 1750000 == 0)
985 {
986 return (double) 8 / 7;
987 }
988 else if (channelBandwidth % 1500000 == 0)
989 {
990 return (double) 86 / 75;
991 }
992 else if (channelBandwidth % 1250000 == 0)
993 {
994 return (double) 144 / 125;
995 }
996 else if (channelBandwidth % 2750000 == 0)
997 {
998 return (double) 316 / 275;
999 }
1000 else if (channelBandwidth % 2000000 == 0)
1001 {
1002 return (double) 57 / 50;
1003 }
1004 else
1005 {
1006 NS_LOG_DEBUG ("Oops may be wrong channel bandwidth for OFDM PHY!")do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std
::clog << g_log.Name () << ":" << __FUNCTION__
<< "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL
)) { std::clog << "[" << g_log.GetLevelLabel (ns3
::LOG_DEBUG) << "] "; }; std::clog << "Oops may be wrong channel bandwidth for OFDM PHY!"
<< std::endl; } } while (false)
;
1007 NS_FATAL_ERROR ("wrong channel bandwidth for OFDM PHY")do { std::cerr << "msg=\"" << "wrong channel bandwidth for OFDM PHY"
<< "\", "; do { std::cerr << "file=" << "../src/wimax/model/simple-ofdm-wimax-phy.cc"
<< ", line=" << 1007 << std::endl; ::ns3::
FatalImpl::FlushStreams (); if (true) std::terminate (); } while
(false); } while (false)
;
1008 }
1009
1010 return (double) 8 / 7;
1011}
1012
1013double
1014SimpleOfdmWimaxPhy::DoGetSamplingFrequency (void) const
1015{
1016 // sampling frequency (Fs), see 8.3.2.2
1017
1018 return (DoGetSamplingFactor () * GetChannelBandwidth () / 8000) * 8000;
1019}
1020
1021double
1022SimpleOfdmWimaxPhy::DoGetGValue (void) const
1023{
1024
1025 return m_g;
1026}
1027
1028void
1029SimpleOfdmWimaxPhy::DoSetGValue (double g)
1030{
1031 m_g = g;
1032
1033}
1034
1035void
1036SimpleOfdmWimaxPhy::SetTxGain (double txGain)
1037{
1038 m_txGain = txGain;
1039}
1040
1041void
1042SimpleOfdmWimaxPhy::SetRxGain (double txRain)
1043{
1044 m_rxGain = txRain;
1045}
1046
1047double
1048SimpleOfdmWimaxPhy::GetTxGain (void) const
1049{
1050 return m_txGain;
1051}
1052
1053double
1054SimpleOfdmWimaxPhy::GetRxGain (void) const
1055{
1056 return m_rxGain;
1057}
1058
1059std::string
1060SimpleOfdmWimaxPhy::GetTraceFilePath (void) const
1061{
1062 return (m_snrToBlockErrorRateManager->GetTraceFilePath ());
1063}
1064
1065void
1066SimpleOfdmWimaxPhy::SetTraceFilePath (std::string path)
1067{
1068
1069 m_snrToBlockErrorRateManager->SetTraceFilePath ((char*) path.c_str ());
1070 m_snrToBlockErrorRateManager->LoadTraces ();
1071}
1072
1073void
1074SimpleOfdmWimaxPhy::NotifyTxBegin (Ptr<PacketBurst> burst)
1075{
1076 m_phyTxBeginTrace (burst);
1077}
1078
1079void
1080SimpleOfdmWimaxPhy::NotifyTxEnd (Ptr<PacketBurst> burst)
1081{
1082 m_phyTxEndTrace (burst);
1083}
1084
1085void
1086SimpleOfdmWimaxPhy::NotifyTxDrop (Ptr<PacketBurst> burst)
1087{
1088 m_phyTxDropTrace (burst);
1089}
1090
1091void
1092SimpleOfdmWimaxPhy::NotifyRxBegin (Ptr<PacketBurst> burst)
1093{
1094 m_phyRxBeginTrace (burst);
1095}
1096
1097void
1098SimpleOfdmWimaxPhy::NotifyRxEnd (Ptr<PacketBurst> burst)
1099{
1100 m_phyRxEndTrace (burst);
1101}
1102
1103void
1104SimpleOfdmWimaxPhy::NotifyRxDrop (Ptr<PacketBurst> burst)
1105{
1106 m_phyRxDropTrace (burst);
1107}
1108
1109int64_t
1110SimpleOfdmWimaxPhy::AssignStreams (int64_t stream)
1111{
1112 NS_LOG_FUNCTION (this << stream)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled
(ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3::
LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog
); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE
)) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter ();
if (printer != 0) { (*printer)(std::clog); std::clog <<
" "; } }; ; std::clog << g_log.Name () << ":" <<
__FUNCTION__ << "("; ns3::ParameterLogger (std::clog) <<
this << stream; std::clog << ")" << std::endl
; } } while (false)
;
1113 m_URNG->SetStream (stream);
1114 return 1;
1115}
1116
1117} // namespace ns3