A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
uan-phy-gen.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 University of Washington
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: Leonard Tracy <lentracy@gmail.com>
19  * Andrea Sacco <andrea.sacco85@gmail.com>
20  */
21 
22 #include "uan-phy-gen.h"
23 #include "uan-transducer.h"
24 #include "uan-channel.h"
25 #include "uan-net-device.h"
26 #include "ns3/simulator.h"
27 #include "ns3/traced-callback.h"
28 #include "ns3/ptr.h"
29 #include "ns3/trace-source-accessor.h"
30 #include "ns3/double.h"
31 #include "ns3/log.h"
32 #include "ns3/uan-tx-mode.h"
33 #include "ns3/node.h"
34 #include "ns3/uinteger.h"
35 #include "ns3/energy-source-container.h"
36 #include "ns3/acoustic-modem-energy-model.h"
37 
38 
39 NS_LOG_COMPONENT_DEFINE ("UanPhyGen");
40 
41 namespace ns3 {
42 
43 NS_OBJECT_ENSURE_REGISTERED (UanPhyGen);
44 NS_OBJECT_ENSURE_REGISTERED (UanPhyPerGenDefault);
45 NS_OBJECT_ENSURE_REGISTERED (UanPhyCalcSinrDefault);
46 NS_OBJECT_ENSURE_REGISTERED (UanPhyCalcSinrFhFsk);
47 NS_OBJECT_ENSURE_REGISTERED (UanPhyPerUmodem);
48 
49 
50 /*************** UanPhyCalcSinrDefault definition *****************/
51 UanPhyCalcSinrDefault::UanPhyCalcSinrDefault ()
52 {
53 
54 }
55 UanPhyCalcSinrDefault::~UanPhyCalcSinrDefault ()
56 {
57 
58 }
59 
60 TypeId
61 UanPhyCalcSinrDefault::GetTypeId (void)
62 {
63  static TypeId tid = TypeId ("ns3::UanPhyCalcSinrDefault")
64  .SetParent<Object> ()
65  .AddConstructor<UanPhyCalcSinrDefault> ()
66  ;
67  return tid;
68 }
69 
70 double
72  Time arrTime,
73  double rxPowerDb,
74  double ambNoiseDb,
75  UanTxMode mode,
76  UanPdp pdp,
77  const UanTransducer::ArrivalList &arrivalList) const
78 {
79  if (mode.GetModType () == UanTxMode::OTHER)
80  {
81  NS_LOG_WARN ("Calculating SINR for unsupported modulation type");
82  }
83 
84  double intKp = -DbToKp (rxPowerDb); // This packet is in the arrivalList
85  UanTransducer::ArrivalList::const_iterator it = arrivalList.begin ();
86  for (; it != arrivalList.end (); it++)
87  {
88  intKp += DbToKp (it->GetRxPowerDb ());
89  }
90 
91  double totalIntDb = KpToDb (intKp + DbToKp (ambNoiseDb));
92 
93  NS_LOG_DEBUG ("Calculating SINR: RxPower = " << rxPowerDb << " dB. Number of interferers = " << arrivalList.size () << " Interference + noise power = " << totalIntDb << " dB. SINR = " << rxPowerDb - totalIntDb << " dB.");
94  return rxPowerDb - totalIntDb;
95 }
96 
97 /*************** UanPhyCalcSinrFhFsk definition *****************/
98 UanPhyCalcSinrFhFsk::UanPhyCalcSinrFhFsk ()
99 {
100 
101 }
102 UanPhyCalcSinrFhFsk::~UanPhyCalcSinrFhFsk ()
103 {
104 
105 }
106 
107 TypeId
108 UanPhyCalcSinrFhFsk::GetTypeId (void)
109 {
110  static TypeId tid = TypeId ("ns3::UanPhyCalcSinrFhFsk")
111  .SetParent<Object> ()
112  .AddConstructor<UanPhyCalcSinrFhFsk> ()
113  .AddAttribute ("NumberOfHops",
114  "Number of frequencies in hopping pattern",
115  UintegerValue (13),
116  MakeUintegerAccessor (&UanPhyCalcSinrFhFsk::m_hops),
117  MakeUintegerChecker<uint32_t> ())
118  ;
119  return tid;
120 }
121 double
123  Time arrTime,
124  double rxPowerDb,
125  double ambNoiseDb,
126  UanTxMode mode,
127  UanPdp pdp,
128  const UanTransducer::ArrivalList &arrivalList) const
129 {
130  if (mode.GetModType () != UanTxMode::FSK)
131  {
132  NS_LOG_WARN ("Calculating SINR for unsupported mode type");
133  }
134 
135 
136 
137  double ts = 1.0 / mode.GetPhyRateSps ();
138  double clearingTime = (m_hops - 1.0) * ts;
139  double csp = pdp.SumTapsFromMaxNc (Seconds (0), Seconds (ts));
140 
141  // Get maximum arrival offset
142  double maxAmp = -1;
143  double maxTapDelay = 0.0;
144  UanPdp::Iterator pit = pdp.GetBegin ();
145  for (; pit != pdp.GetEnd (); pit++)
146  {
147  if (std::abs (pit->GetAmp ()) > maxAmp)
148  {
149  maxAmp = std::abs (pit->GetAmp ());
150  maxTapDelay = pit->GetDelay ().GetSeconds ();
151  }
152  }
153 
154 
155  double effRxPowerDb = rxPowerDb + KpToDb (csp);
156 
157  double isiUpa = rxPowerDb * pdp.SumTapsFromMaxNc (Seconds (ts + clearingTime), Seconds (ts));
158  UanTransducer::ArrivalList::const_iterator it = arrivalList.begin ();
159  double intKp = -DbToKp (effRxPowerDb);
160  for (; it != arrivalList.end (); it++)
161  {
162  UanPdp intPdp = it->GetPdp ();
163  double tDelta = std::abs (arrTime.GetSeconds () + maxTapDelay - it->GetArrivalTime ().GetSeconds ());
164  // We want tDelta in terms of a single symbol (i.e. if tDelta = 7.3 symbol+clearing
165  // times, the offset in terms of the arriving symbol power is
166  // 0.3 symbol+clearing times.
167 
168  int32_t syms = (uint32_t)( (double) tDelta / (ts + clearingTime));
169  tDelta = tDelta - syms * (ts + clearingTime);
170 
171  // Align to pktRx
172  if (arrTime + Seconds (maxTapDelay) > it->GetArrivalTime ())
173  {
174  tDelta = ts + clearingTime - tDelta;
175  }
176 
177  double intPower = 0.0;
178  if (tDelta < ts)
179  {
180  intPower += intPdp.SumTapsNc (Seconds (0), Seconds (ts - tDelta));
181  intPower += intPdp.SumTapsNc (Seconds (ts - tDelta + clearingTime),
182  Seconds (2 * ts - tDelta + clearingTime));
183  }
184  else
185  {
186  Time start = Seconds (ts + clearingTime - tDelta);
187  Time end = start + Seconds (ts);
188  intPower += intPdp.SumTapsNc (start, end);
189 
190  start = start + Seconds (ts + clearingTime);
191  end = start + Seconds (ts);
192  intPower += intPdp.SumTapsNc (start, end);
193  }
194  intKp += DbToKp (it->GetRxPowerDb ()) * intPower;
195  }
196 
197  double totalIntDb = KpToDb (isiUpa + intKp + DbToKp (ambNoiseDb));
198 
199  NS_LOG_DEBUG ("Calculating SINR: RxPower = " << rxPowerDb << " dB. Effective Rx power " << effRxPowerDb << " dB. Number of interferers = " << arrivalList.size () << " Interference + noise power = " << totalIntDb << " dB. SINR = " << effRxPowerDb - totalIntDb << " dB.");
200  return effRxPowerDb - totalIntDb;
201 }
202 
203 /*************** UanPhyPerGenDefault definition *****************/
204 UanPhyPerGenDefault::UanPhyPerGenDefault ()
205 {
206 
207 }
208 
209 UanPhyPerGenDefault::~UanPhyPerGenDefault ()
210 {
211 
212 }
213 TypeId
214 UanPhyPerGenDefault::GetTypeId (void)
215 {
216  static TypeId tid = TypeId ("ns3::UanPhyPerGenDefault")
217  .SetParent<Object> ()
218  .AddConstructor<UanPhyPerGenDefault> ()
219  .AddAttribute ("Threshold", "SINR cutoff for good packet reception",
220  DoubleValue (8),
221  MakeDoubleAccessor (&UanPhyPerGenDefault::m_thresh),
222  MakeDoubleChecker<double> ());
223  return tid;
224 }
225 
226 
227 // Default PER calculation simply compares SINR to a threshold which is configurable
228 // via an attribute.
229 double
231 {
232  if (sinrDb >= m_thresh)
233  {
234  return 0;
235  }
236  else
237  {
238  return 1;
239  }
240 }
241 
242 /*************** UanPhyPerUmodem definition *****************/
243 UanPhyPerUmodem::UanPhyPerUmodem ()
244 {
245 
246 }
247 UanPhyPerUmodem::~UanPhyPerUmodem ()
248 {
249 
250 }
251 
252 TypeId UanPhyPerUmodem::GetTypeId (void)
253 {
254  static TypeId tid = TypeId ("ns3::UanPhyPerUmodem")
255  .SetParent<Object> ()
256  .AddConstructor<UanPhyPerUmodem> ()
257  ;
258  return tid;
259 }
260 
261 double
262 UanPhyPerUmodem::NChooseK (uint32_t n, uint32_t k)
263 {
264  double result;
265 
266  result = 1.0;
267 
268  for (uint32_t i = std::max (k,n - k) + 1; i <= n; ++i)
269  {
270  result *= i;
271  }
272 
273  for (uint32_t i = 2; i <= std::min (k,n - k); ++i)
274  {
275  result /= i;
276  }
277 
278  return result;
279 }
280 
281 double
283 {
284  uint32_t d[] =
285  { 12, 14, 16, 18, 20, 22, 24, 26, 28 };
286  double Bd[] =
287  {
288  33, 281, 2179, 15035LLU, 105166LLU, 692330LLU, 4580007LLU, 29692894LLU,
289  190453145LLU
290  };
291 
292  // double Rc = 1.0 / 2.0;
293  double ebno = std::pow (10.0, sinr / 10.0);
294  double perror = 1.0 / (2.0 + ebno);
295  double P[9];
296 
297  if (sinr >= 10)
298  {
299  return 0;
300  }
301  if (sinr <= 6)
302  {
303  return 1;
304  }
305 
306  for (uint32_t r = 0; r < 9; r++)
307  {
308  double sumd = 0;
309  for (uint32_t k = 0; k < d[r]; k++)
310  {
311  sumd = sumd + NChooseK (d[r] - 1 + k, k) * std::pow (1 - perror, (double) k);
312  }
313  P[r] = std::pow (perror, (double) d[r]) * sumd;
314 
315  }
316 
317  double Pb = 0;
318  for (uint32_t r = 0; r < 8; r++)
319  {
320  Pb = Pb + Bd[r] * P[r];
321  }
322 
323  // cout << "Pb = " << Pb << endl;
324  uint32_t bits = pkt->GetSize () * 8;
325 
326  double Ppacket = 1;
327  double temp = NChooseK (bits, 0);
328  temp *= std::pow ( (1 - Pb), (double) bits);
329  Ppacket -= temp;
330  temp = NChooseK (288, 1) * Pb * std::pow ( (1 - Pb), bits - 1.0);
331  Ppacket -= temp;
332 
333  if (Ppacket > 1)
334  {
335  return 1;
336  }
337  else
338  {
339  return Ppacket;
340  }
341 }
342 
343 /*************** UanPhyGen definition *****************/
344 UanPhyGen::UanPhyGen ()
345  : UanPhy (),
346  m_state (IDLE),
347  m_channel (0),
348  m_transducer (0),
349  m_device (0),
350  m_mac (0),
351  m_rxGainDb (0),
352  m_txPwrDb (0),
353  m_rxThreshDb (0),
354  m_ccaThreshDb (0),
355  m_pktRx (0),
356  m_cleared (false),
357  m_disabled (false)
358 {
359  m_pg = CreateObject<UniformRandomVariable> ();
360 
361  m_energyCallback.Nullify ();
362 }
363 
364 UanPhyGen::~UanPhyGen ()
365 {
366 
367 }
368 
369 void
371 {
372  if (m_cleared)
373  {
374  return;
375  }
376  m_cleared = true;
377  m_listeners.clear ();
378  if (m_channel)
379  {
380  m_channel->Clear ();
381  m_channel = 0;
382  }
383  if (m_transducer)
384  {
385  m_transducer->Clear ();
386  m_transducer = 0;
387  }
388  if (m_device)
389  {
390  m_device->Clear ();
391  m_device = 0;
392  }
393  if (m_mac)
394  {
395  m_mac->Clear ();
396  m_mac = 0;
397  }
398  if (m_per)
399  {
400  m_per->Clear ();
401  m_per = 0;
402  }
403  if (m_sinr)
404  {
405  m_sinr->Clear ();
406  m_sinr = 0;
407  }
408  m_pktRx = 0;
409 }
410 
411 void
413 {
414  Clear ();
415  m_energyCallback.Nullify ();
417 }
418 
421 {
422  UanModesList l;
423  l.AppendMode (UanTxModeFactory::CreateMode (UanTxMode::FSK,80,80,22000,4000,13,"FSK"));
424  l.AppendMode (UanTxModeFactory::CreateMode (UanTxMode::PSK,200, 200, 22000, 4000, 4, "QPSK"));
425  return l;
426 }
427 TypeId
428 UanPhyGen::GetTypeId (void)
429 {
430 
431  static TypeId tid = TypeId ("ns3::UanPhyGen")
432  .SetParent<UanPhy> ()
433  .AddConstructor<UanPhyGen> ()
434  .AddAttribute ("CcaThreshold",
435  "Aggregate energy of incoming signals to move to CCA Busy state dB",
436  DoubleValue (10),
437  MakeDoubleAccessor (&UanPhyGen::m_ccaThreshDb),
438  MakeDoubleChecker<double> ())
439  .AddAttribute ("RxThreshold",
440  "Required SNR for signal acquisition in dB",
441  DoubleValue (10),
442  MakeDoubleAccessor (&UanPhyGen::m_rxThreshDb),
443  MakeDoubleChecker<double> ())
444  .AddAttribute ("TxPower",
445  "Transmission output power in dB",
446  DoubleValue (190),
447  MakeDoubleAccessor (&UanPhyGen::m_txPwrDb),
448  MakeDoubleChecker<double> ())
449  .AddAttribute ("RxGain",
450  "Gain added to incoming signal at receiver",
451  DoubleValue (0),
452  MakeDoubleAccessor (&UanPhyGen::m_rxGainDb),
453  MakeDoubleChecker<double> ())
454  .AddAttribute ("SupportedModes",
455  "List of modes supported by this PHY",
456  UanModesListValue (UanPhyGen::GetDefaultModes ()),
457  MakeUanModesListAccessor (&UanPhyGen::m_modes),
458  MakeUanModesListChecker () )
459  .AddAttribute ("PerModel",
460  "Functor to calculate PER based on SINR and TxMode",
461  PointerValue (CreateObject<UanPhyPerGenDefault> ()),
462  MakePointerAccessor (&UanPhyGen::m_per),
463  MakePointerChecker<UanPhyPer> ())
464  .AddAttribute ("SinrModel",
465  "Functor to calculate SINR based on pkt arrivals and modes",
466  PointerValue (CreateObject<UanPhyCalcSinrDefault> ()),
467  MakePointerAccessor (&UanPhyGen::m_sinr),
468  MakePointerChecker<UanPhyCalcSinr> ())
469  .AddTraceSource ("RxOk",
470  "A packet was received successfully",
471  MakeTraceSourceAccessor (&UanPhyGen::m_rxOkLogger))
472  .AddTraceSource ("RxError",
473  "A packet was received unsuccessfully",
474  MakeTraceSourceAccessor (&UanPhyGen::m_rxErrLogger))
475  .AddTraceSource ("Tx",
476  "Packet transmission beginning",
477  MakeTraceSourceAccessor (&UanPhyGen::m_txLogger))
478  ;
479  return tid;
480 
481 }
482 
483 void
485 {
486  NS_LOG_FUNCTION (this);
487  m_energyCallback = cb;
488 }
489 
490 void
491 UanPhyGen::UpdatePowerConsumption (const State state)
492 {
493  NS_LOG_FUNCTION (this);
494 
495  if (!m_energyCallback.IsNull ())
496  {
497  m_energyCallback (state);
498  }
499 }
500 
501 void
503 {
504  NS_LOG_FUNCTION (this);
505  NS_LOG_DEBUG ("Energy depleted at node " << m_device->GetNode ()->GetId () <<
506  ", stopping rx/tx activities");
507 
508  m_disabled = true;
509 }
510 
511 void
512 UanPhyGen::SendPacket (Ptr<Packet> pkt, uint32_t modeNum)
513 {
514  NS_LOG_DEBUG ("PHY " << m_mac->GetAddress () << ": Transmitting packet");
515  if (m_disabled)
516  {
517  NS_LOG_DEBUG ("Energy depleted, node cannot transmit any packet. Dropping.");
518  return;
519  }
520 
521  if (m_state == TX)
522  {
523  NS_LOG_DEBUG ("PHY requested to TX while already Transmitting. Dropping packet.");
524  return;
525  }
526  else if (m_state == SLEEP)
527  {
528  NS_LOG_DEBUG ("PHY requested to TX while sleeping. Dropping packet.");
529  return;
530  }
531 
532  UanTxMode txMode = GetMode (modeNum);
533 
534  if (m_pktRx != 0)
535  {
536  m_minRxSinrDb = -1e30;
537  m_pktRx = 0;
538  }
539 
540  m_transducer->Transmit (Ptr<UanPhy> (this), pkt, m_txPwrDb, txMode);
541  m_state = TX;
542  UpdatePowerConsumption (TX);
543  double txdelay = pkt->GetSize () * 8.0 / txMode.GetDataRateBps ();
544  Simulator::Schedule (Seconds (txdelay), &UanPhyGen::TxEndEvent, this);
545  NS_LOG_DEBUG ("PHY " << m_mac->GetAddress () << " notifying listeners");
546  NotifyListenersTxStart (Seconds (txdelay));
547  m_txLogger (pkt, m_txPwrDb, txMode);
548 }
549 
550 void
551 UanPhyGen::TxEndEvent ()
552 {
553  if (m_state == SLEEP || m_disabled == true)
554  {
555  NS_LOG_DEBUG ("Transmission ended but node sleeping or dead");
556  return;
557  }
558 
559  NS_ASSERT (m_state == TX);
560  if (GetInterferenceDb ( (Ptr<Packet>) 0) > m_ccaThreshDb)
561  {
562  m_state = CCABUSY;
563  NotifyListenersCcaStart ();
564  }
565  else
566  {
567  m_state = IDLE;
568  }
569  UpdatePowerConsumption (IDLE);
570 }
571 
572 void
574 {
575  m_listeners.push_back (listener);
576 }
577 
578 
579 void
580 UanPhyGen::StartRxPacket (Ptr<Packet> pkt, double rxPowerDb, UanTxMode txMode, UanPdp pdp)
581 {
582  if (m_disabled)
583  {
584  NS_LOG_DEBUG ("Energy depleted, node cannot receive any packet. Dropping.");
585  NotifyRxDrop(pkt); // traced source netanim
586  return;
587  }
588 
589  switch (m_state)
590  {
591  case TX:
592  NotifyRxDrop(pkt); // traced source netanim
593  NS_ASSERT (false);
594  break;
595  case RX:
596  {
597  NS_ASSERT (m_pktRx);
598  double newSinrDb = CalculateSinrDb (m_pktRx, m_pktRxArrTime, m_rxRecvPwrDb, m_pktRxMode, m_pktRxPdp);
599  m_minRxSinrDb = (newSinrDb < m_minRxSinrDb) ? newSinrDb : m_minRxSinrDb;
600  NS_LOG_DEBUG ("PHY " << m_mac->GetAddress () << ": Starting RX in RX mode. SINR of pktRx = " << m_minRxSinrDb);
601  NotifyRxBegin(pkt); // traced source netanim
602  }
603  break;
604 
605  case CCABUSY:
606  case IDLE:
607  {
608  NS_ASSERT (!m_pktRx);
609  bool hasmode = false;
610  for (uint32_t i = 0; i < GetNModes (); i++)
611  {
612  if (txMode.GetUid () == GetMode (i).GetUid ())
613  {
614  hasmode = true;
615  break;
616  }
617  }
618  if (!hasmode)
619  {
620  break;
621  }
622 
623 
624  double newsinr = CalculateSinrDb (pkt, Simulator::Now (), rxPowerDb, txMode, pdp);
625  NS_LOG_DEBUG ("PHY " << m_mac->GetAddress () << ": Starting RX in IDLE mode. SINR = " << newsinr);
626  if (newsinr > m_rxThreshDb)
627  {
628  m_state = RX;
629  UpdatePowerConsumption (RX);
630  NotifyRxBegin(pkt); // traced source netanim
631  m_rxRecvPwrDb = rxPowerDb;
632  m_minRxSinrDb = newsinr;
633  m_pktRx = pkt;
634  m_pktRxArrTime = Simulator::Now ();
635  m_pktRxMode = txMode;
636  m_pktRxPdp = pdp;
637  double txdelay = pkt->GetSize () * 8.0 / txMode.GetDataRateBps ();
638  Simulator::Schedule (Seconds (txdelay), &UanPhyGen::RxEndEvent, this, pkt, rxPowerDb, txMode);
639  NotifyListenersRxStart ();
640  }
641 
642  }
643  break;
644  case SLEEP:
645  NS_LOG_DEBUG ("Sleep mode. Dropping packet.");
646  NotifyRxDrop(pkt); // traced source netanim
647  break;
648  }
649 
650  if (m_state == IDLE && GetInterferenceDb ( (Ptr<Packet>) 0) > m_ccaThreshDb)
651  {
652  m_state = CCABUSY;
653  NotifyListenersCcaStart ();
654  }
655 
656 }
657 
658 void
659 UanPhyGen::RxEndEvent (Ptr<Packet> pkt, double rxPowerDb, UanTxMode txMode)
660 {
661  if (pkt != m_pktRx)
662  {
663  return;
664  }
665 
666  if (m_disabled || m_state == SLEEP)
667  {
668  NS_LOG_DEBUG ("Sleep mode or dead. Dropping packet");
669  m_pktRx = 0;
670  NotifyRxDrop(pkt); // traced source netanim
671  return;
672  }
673 
674  NotifyRxEnd(pkt); // traced source netanim
675  if (GetInterferenceDb ( (Ptr<Packet>) 0) > m_ccaThreshDb)
676  {
677  m_state = CCABUSY;
678  NotifyListenersCcaStart ();
679  }
680  else
681  {
682  m_state = IDLE;
683  UpdatePowerConsumption (IDLE);
684  }
685 
686  if (m_pg->GetValue (0, 1) > m_per->CalcPer (m_pktRx, m_minRxSinrDb, txMode))
687  {
688  m_rxOkLogger (pkt, m_minRxSinrDb, txMode);
689  NotifyListenersRxGood ();
690  if (!m_recOkCb.IsNull ())
691  {
692  m_recOkCb (pkt, m_minRxSinrDb, txMode);
693  }
694 
695  }
696  else
697  {
698  m_rxErrLogger (pkt, m_minRxSinrDb, txMode);
699  NotifyListenersRxBad ();
700  if (!m_recErrCb.IsNull ())
701  {
702  m_recErrCb (pkt, m_minRxSinrDb);
703  }
704  }
705 
706  m_pktRx = 0;
707 }
708 
709 void
711 {
712  m_recOkCb = cb;
713 }
714 
715 void
717 {
718  m_recErrCb = cb;
719 }
720 bool
722 {
723  return m_state == SLEEP;
724 }
725 bool
727 {
728  return m_state == IDLE;
729 }
730 bool
732 {
733  return !IsStateIdle () && !IsStateSleep ();
734 }
735 bool
737 {
738  return m_state == RX;
739 }
740 bool
742 {
743  return m_state == TX;
744 }
745 
746 bool
748 {
749  return m_state == CCABUSY;
750 }
751 
752 
753 void
755 {
756  m_rxGainDb = gain;
757 
758 }
759 void
761 {
762  m_txPwrDb = txpwr;
763 }
764 void
766 {
767  m_rxThreshDb = thresh;
768 }
769 void
771 {
772  m_ccaThreshDb = thresh;
773 }
774 double
776 {
777  return m_rxGainDb;
778 }
779 double
781 {
782  return m_txPwrDb;
783 
784 }
785 double
787 {
788  return m_rxThreshDb;
789 }
790 double
792 {
793  return m_ccaThreshDb;
794 }
795 
798 {
799  return m_channel;
800 }
801 
804 {
805  return m_device;
806 }
807 
810 {
811  return m_transducer;
812 }
813 void
815 {
816  m_channel = channel;
817 }
818 
819 void
821 {
822  m_device = device;
823 }
824 
825 void
827 {
828  m_mac = mac;
829 }
830 
831 void
833 {
834  m_transducer = trans;
835  m_transducer->AddPhy (this);
836 }
837 
838 void
839 UanPhyGen::SetSleepMode (bool sleep)
840 {
841  if (sleep)
842  {
843  m_state = SLEEP;
844  if (!m_energyCallback.IsNull ())
845  {
846  m_energyCallback (SLEEP);
847  }
848  }
849  else if (m_state == SLEEP)
850  {
851  if (GetInterferenceDb ((Ptr<Packet>) 0) > m_ccaThreshDb)
852  {
853  m_state = CCABUSY;
854  NotifyListenersCcaStart ();
855  }
856  else
857  {
858  m_state = IDLE;
859  }
860 
861  if (!m_energyCallback.IsNull ())
862  {
863  m_energyCallback (IDLE);
864  }
865  }
866 }
867 
868 int64_t
869 UanPhyGen::AssignStreams (int64_t stream)
870 {
871  NS_LOG_FUNCTION (this << stream);
872  m_pg->SetStream (stream);
873  return 1;
874 }
875 
876 void
877 UanPhyGen::NotifyTransStartTx (Ptr<Packet> packet, double txPowerDb, UanTxMode txMode)
878 {
879  if (m_pktRx)
880  {
881  m_minRxSinrDb = -1e30;
882  }
883 }
884 
885 void
887 {
888  if (m_state == CCABUSY && GetInterferenceDb (Ptr<Packet> ()) < m_ccaThreshDb)
889  {
890  m_state = IDLE;
891  NotifyListenersCcaEnd ();
892  }
893 }
894 
895 double
896 UanPhyGen::CalculateSinrDb (Ptr<Packet> pkt, Time arrTime, double rxPowerDb, UanTxMode mode, UanPdp pdp)
897 {
898  double noiseDb = m_channel->GetNoiseDbHz ( (double) mode.GetCenterFreqHz () / 1000.0) + 10 * std::log10 (mode.GetBandwidthHz ());
899  return m_sinr->CalcSinrDb (pkt, arrTime, rxPowerDb, noiseDb, mode, pdp, m_transducer->GetArrivalList ());
900 }
901 
902 double
903 UanPhyGen::GetInterferenceDb (Ptr<Packet> pkt)
904 {
905 
906  const UanTransducer::ArrivalList &arrivalList = m_transducer->GetArrivalList ();
907 
908  UanTransducer::ArrivalList::const_iterator it = arrivalList.begin ();
909 
910  double interfPower = 0;
911 
912  for (; it != arrivalList.end (); it++)
913  {
914  if (pkt != it->GetPacket ())
915  {
916  interfPower += DbToKp (it->GetRxPowerDb ());
917  }
918  }
919 
920  return KpToDb (interfPower);
921 
922 }
923 
924 double
925 UanPhyGen::DbToKp (double db)
926 {
927  return std::pow (10, db / 10.0);
928 }
929 double
930 UanPhyGen::KpToDb (double kp)
931 {
932  return 10 * std::log10 (kp);
933 }
934 
935 void
936 UanPhyGen::NotifyListenersRxStart (void)
937 {
938  ListenerList::const_iterator it = m_listeners.begin ();
939  for (; it != m_listeners.end (); it++)
940  {
941  (*it)->NotifyRxStart ();
942  }
943 
944 }
945 void
946 UanPhyGen::NotifyListenersRxGood (void)
947 {
948  ListenerList::const_iterator it = m_listeners.begin ();
949  for (; it != m_listeners.end (); it++)
950  {
951  (*it)->NotifyRxEndOk ();
952  }
953 }
954 void
955 UanPhyGen::NotifyListenersRxBad (void)
956 {
957  ListenerList::const_iterator it = m_listeners.begin ();
958  for (; it != m_listeners.end (); it++)
959  {
960  (*it)->NotifyRxEndError ();
961  }
962 }
963 void
964 UanPhyGen::NotifyListenersCcaStart (void)
965 {
966  ListenerList::const_iterator it = m_listeners.begin ();
967  for (; it != m_listeners.end (); it++)
968  {
969  (*it)->NotifyCcaStart ();
970  }
971 }
972 void
973 UanPhyGen::NotifyListenersCcaEnd (void)
974 {
975  ListenerList::const_iterator it = m_listeners.begin ();
976  for (; it != m_listeners.end (); it++)
977  {
978  (*it)->NotifyCcaEnd ();
979  }
980 }
981 
982 void
983 UanPhyGen::NotifyListenersTxStart (Time duration)
984 {
985  ListenerList::const_iterator it = m_listeners.begin ();
986  for (; it != m_listeners.end (); it++)
987  {
988  (*it)->NotifyTxStart (duration);
989  }
990 }
991 
992 uint32_t
994 {
995  return m_modes.GetNModes ();
996 }
997 
998 UanTxMode
999 UanPhyGen::GetMode (uint32_t n)
1000 {
1001  NS_ASSERT (n < m_modes.GetNModes ());
1002 
1003  return m_modes[n];
1004 }
1005 
1008 {
1009  return m_pktRx;
1010 }
1011 
1012 
1013 } // namespace ns3
virtual void NotifyTransStartTx(Ptr< Packet > packet, double txPowerDb, UanTxMode txMode)
Definition: uan-phy-gen.cc:877
virtual bool IsStateBusy(void)
Definition: uan-phy-gen.cc:731
virtual Ptr< UanTransducer > GetTransducer(void)
Definition: uan-phy-gen.cc:809
virtual double GetRxThresholdDb(void)
Definition: uan-phy-gen.cc:786
keep track of time unit.
Definition: nstime.h:149
uint32_t GetNModes(void) const
Definition: uan-tx-mode.cc:259
std::vector< Tap >::const_iterator Iterator
Iterator is a standard template library constant interator.
virtual bool IsStateRx(void)
Definition: uan-phy-gen.cc:736
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
virtual void SetEnergyModelCallback(DeviceEnergyModel::ChangeStateCallback cb)
Definition: uan-phy-gen.cc:484
void NotifyRxDrop(Ptr< const Packet > packet)
Definition: uan-phy.cc:127
virtual void SetReceiveErrorCallback(RxErrCallback cb)
Definition: uan-phy-gen.cc:716
virtual void EnergyDepletionHandler(void)
Definition: uan-phy-gen.cc:502
virtual void SetTransducer(Ptr< UanTransducer > trans)
Definition: uan-phy-gen.cc:832
#define NS_ASSERT(condition)
Definition: assert.h:64
Ptr< UniformRandomVariable > m_pg
Provides uniform random variables.
Definition: uan-phy-gen.h:251
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
double SumTapsFromMaxNc(Time delay, Time duration) const
uint32_t GetSize(void) const
Definition: packet.h:620
virtual void StartRxPacket(Ptr< Packet > pkt, double rxPowerDb, UanTxMode txMode, UanPdp pdp)
Packet arriving from channel: i.e. leading bit of packet has arrived.
Definition: uan-phy-gen.cc:580
virtual uint32_t GetNModes(void)
Definition: uan-phy-gen.cc:993
virtual void DoDispose(void)
Definition: object.cc:335
Container for UanTxModes.
Definition: uan-tx-mode.h:162
virtual double GetTxPowerDb(void)
Definition: uan-phy-gen.cc:780
virtual double GetCcaThresholdDb(void)
Definition: uan-phy-gen.cc:791
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
ModulationType GetModType(void) const
Definition: uan-tx-mode.cc:39
void NotifyRxEnd(Ptr< const Packet > packet)
Definition: uan-phy.cc:121
static UanTxMode CreateMode(UanTxMode::ModulationType type, uint32_t dataRateBps, uint32_t phyRateSps, uint32_t cfHz, uint32_t bwHz, uint32_t constSize, std::string name)
Definition: uan-tx-mode.cc:132
virtual void DoDispose()
Definition: uan-phy-gen.cc:412
double GetSeconds(void) const
Definition: nstime.h:262
virtual double CalcSinrDb(Ptr< Packet > pkt, Time arrTime, double rxPowerDb, double ambNoiseDb, UanTxMode mode, UanPdp pdp, const UanTransducer::ArrivalList &arrivalList) const
Definition: uan-phy-gen.cc:71
virtual bool IsStateTx(void)
Definition: uan-phy-gen.cc:741
virtual void SetDevice(Ptr< UanNetDevice > device)
Definition: uan-phy-gen.cc:820
int64_t AssignStreams(int64_t stream)
Definition: uan-phy-gen.cc:869
uint32_t GetDataRateBps(void) const
Definition: uan-tx-mode.cc:45
double KpToDb(double kp) const
Converts kilopascals to dB re 1 uPa.
Definition: uan-phy.h:87
virtual Ptr< Packet > GetPacketRx(void) const
Abstraction of packet modulation information.
Definition: uan-tx-mode.h:36
std::list< UanPacketArrival > ArrivalList
Arrival list is a standard template library list of UanPacketArrivals objects.
virtual void SetCcaThresholdDb(double thresh)
Definition: uan-phy-gen.cc:770
virtual void NotifyIntChange(void)
Definition: uan-phy-gen.cc:886
virtual double CalcSinrDb(Ptr< Packet > pkt, Time arrTime, double rxPowerDb, double ambNoiseDb, UanTxMode mode, UanPdp pdp, const UanTransducer::ArrivalList &arrivalList) const
Definition: uan-phy-gen.cc:122
virtual Ptr< UanChannel > GetChannel(void) const
Definition: uan-phy-gen.cc:797
virtual UanTxMode GetMode(uint32_t n)
Definition: uan-phy-gen.cc:999
virtual void SetRxThresholdDb(double thresh)
Definition: uan-phy-gen.cc:765
void NotifyRxBegin(Ptr< const Packet > packet)
Definition: uan-phy.cc:115
hold objects of type Ptr<T>
Definition: pointer.h:33
virtual void SetRxGainDb(double gain)
Definition: uan-phy-gen.cc:754
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
uint32_t GetCenterFreqHz(void) const
Definition: uan-tx-mode.cc:57
Interface for PHY event listener A class which implements this interface may register with Phy object...
Definition: uan-phy.h:128
double GetValue(double min, double max)
Returns a random double from the uniform distribution with the specified range.
virtual double CalcPer(Ptr< Packet > pkt, double sinrDb, UanTxMode mode)
Definition: uan-phy-gen.cc:282
double DbToKp(double db) const
Converts dB re 1 uPa to kilopascals.
Definition: uan-phy.h:78
static Time Now(void)
Definition: simulator.cc:179
virtual void SetChannel(Ptr< UanChannel > channel)
Definition: uan-phy-gen.cc:814
Iterator GetEnd(void) const
Base class for UAN Phy models.
Definition: uan-phy.h:166
uint32_t GetPhyRateSps(void) const
Definition: uan-tx-mode.cc:51
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
#define NS_LOG_WARN(msg)
Definition: log.h:246
virtual bool IsStateIdle(void)
Definition: uan-phy-gen.cc:726
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
void AppendMode(UanTxMode mode)
Definition: uan-tx-mode.cc:232
uint32_t GetBandwidthHz(void) const
Definition: uan-tx-mode.cc:63
virtual void SendPacket(Ptr< Packet > pkt, uint32_t modeNum)
Definition: uan-phy-gen.cc:512
Iterator GetBegin(void) const
virtual bool IsStateCcaBusy(void)
Definition: uan-phy-gen.cc:747
virtual void RegisterListener(UanPhyListener *listener)
Definition: uan-phy-gen.cc:573
virtual double GetRxGainDb(void)
Definition: uan-phy-gen.cc:775
Hold an floating point type.
Definition: double.h:41
virtual bool IsStateSleep(void)
Definition: uan-phy-gen.cc:721
virtual void SetMac(Ptr< UanMac > mac)
Definition: uan-phy-gen.cc:826
virtual void SetReceiveOkCallback(RxOkCallback cb)
Definition: uan-phy-gen.cc:710
uint32_t GetUid(void) const
Definition: uan-tx-mode.cc:81
double SumTapsNc(Time begin, Time end) const
static UanModesList GetDefaultModes(void)
Definition: uan-phy-gen.cc:420
a unique identifier for an interface.
Definition: type-id.h:44
virtual double CalcPer(Ptr< Packet > pkt, double sinrDb, UanTxMode mode)
Definition: uan-phy-gen.cc:230
virtual Ptr< UanNetDevice > GetDevice(void)
Definition: uan-phy-gen.cc:803
TypeId SetParent(TypeId tid)
Definition: type-id.cc:471
virtual void Clear(void)
Definition: uan-phy-gen.cc:370
virtual void SetTxPowerDb(double txpwr)
Definition: uan-phy-gen.cc:760