A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
uan-phy-gen.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 University of Washington
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: Leonard Tracy <lentracy@gmail.com>
18 * Andrea Sacco <andrea.sacco85@gmail.com>
19 */
20
21#include "uan-phy-gen.h"
22
24#include "uan-channel.h"
25#include "uan-net-device.h"
26#include "uan-transducer.h"
27#include "uan-tx-mode.h"
28
29#include "ns3/double.h"
30#include "ns3/energy-source-container.h"
31#include "ns3/log.h"
32#include "ns3/node.h"
33#include "ns3/ptr.h"
34#include "ns3/simulator.h"
35#include "ns3/string.h"
36#include "ns3/trace-source-accessor.h"
37#include "ns3/traced-callback.h"
38#include "ns3/uinteger.h"
39
40namespace ns3
41{
42
43NS_LOG_COMPONENT_DEFINE("UanPhyGen");
44
46NS_OBJECT_ENSURE_REGISTERED(UanPhyPerGenDefault);
47NS_OBJECT_ENSURE_REGISTERED(UanPhyCalcSinrDefault);
48NS_OBJECT_ENSURE_REGISTERED(UanPhyCalcSinrFhFsk);
49NS_OBJECT_ENSURE_REGISTERED(UanPhyPerUmodem);
50NS_OBJECT_ENSURE_REGISTERED(UanPhyPerCommonModes);
51
52/*************** UanPhyCalcSinrDefault definition *****************/
54{
55}
56
58{
59}
60
63{
64 static TypeId tid = TypeId("ns3::UanPhyCalcSinrDefault")
66 .SetGroupName("Uan")
67 .AddConstructor<UanPhyCalcSinrDefault>();
68 return tid;
69}
70
71double
73 Time arrTime,
74 double rxPowerDb,
75 double ambNoiseDb,
76 UanTxMode mode,
77 UanPdp pdp,
78 const UanTransducer::ArrivalList& arrivalList) const
79{
80 if (mode.GetModType() == UanTxMode::OTHER)
81 {
82 NS_LOG_WARN("Calculating SINR for unsupported modulation type");
83 }
84
85 double intKp = -DbToKp(rxPowerDb); // This packet is in the arrivalList
86 auto it = arrivalList.begin();
87 for (; it != arrivalList.end(); it++)
88 {
89 intKp += DbToKp(it->GetRxPowerDb());
90 }
91
92 double totalIntDb = KpToDb(intKp + DbToKp(ambNoiseDb));
93
94 NS_LOG_DEBUG("Calculating SINR: RxPower = "
95 << rxPowerDb << " dB. Number of interferers = " << arrivalList.size()
96 << " Interference + noise power = " << totalIntDb
97 << " dB. SINR = " << rxPowerDb - totalIntDb << " dB.");
98 return rxPowerDb - totalIntDb;
99}
100
101/*************** UanPhyCalcSinrFhFsk definition *****************/
103{
104}
105
107{
108}
109
110TypeId
112{
113 static TypeId tid = TypeId("ns3::UanPhyCalcSinrFhFsk")
115 .SetGroupName("Uan")
116 .AddConstructor<UanPhyCalcSinrFhFsk>()
117 .AddAttribute("NumberOfHops",
118 "Number of frequencies in hopping pattern.",
119 UintegerValue(13),
121 MakeUintegerChecker<uint32_t>());
122 return tid;
123}
124
125double
127 Time arrTime,
128 double rxPowerDb,
129 double ambNoiseDb,
130 UanTxMode mode,
131 UanPdp pdp,
132 const UanTransducer::ArrivalList& arrivalList) const
133{
134 if ((mode.GetModType() != UanTxMode::FSK) && (mode.GetConstellationSize() != 13))
135 {
136 NS_FATAL_ERROR("Calculating SINR for unsupported mode type");
137 }
138
139 Time ts = Seconds(1.0 / mode.GetPhyRateSps());
140 Time clearingTime = (m_hops - 1.0) * ts;
141 double csp = pdp.SumTapsFromMaxNc(Time(), ts);
142
143 // Get maximum arrival offset
144 double maxAmp = -1;
145 Time maxTapDelay(0);
146 auto pit = pdp.GetBegin();
147 for (; pit != pdp.GetEnd(); pit++)
148 {
149 if (std::abs(pit->GetAmp()) > maxAmp)
150 {
151 maxAmp = std::abs(pit->GetAmp());
152 // Modified in order to subtract delay of first tap (maxTapDelay appears to be used
153 // later in code as delay from first reception, not from TX time)
154 maxTapDelay = pit->GetDelay() - pdp.GetTap(0).GetDelay();
155 }
156 }
157
158 double effRxPowerDb = rxPowerDb + KpToDb(csp);
159 // It appears to be just the first elements of the sum in Parrish paper,
160 // "System Design Considerations for Undersea Networks: Link and Multiple Access Protocols",
161 // eq. 14
162 double isiUpa =
163 DbToKp(rxPowerDb) * pdp.SumTapsFromMaxNc(ts + clearingTime, ts); // added DpToKp()
164 auto it = arrivalList.begin();
165 double intKp = -DbToKp(effRxPowerDb);
166 for (; it != arrivalList.end(); it++)
167 {
168 UanPdp intPdp = it->GetPdp();
169 Time tDelta = Abs(arrTime + maxTapDelay - it->GetArrivalTime());
170 // We want tDelta in terms of a single symbol (i.e. if tDelta = 7.3 symbol+clearing
171 // times, the offset in terms of the arriving symbol power is
172 // 0.3 symbol+clearing times.
173
174 tDelta = Rem(tDelta, ts + clearingTime);
175
176 // Align to pktRx
177 if (arrTime + maxTapDelay > it->GetArrivalTime())
178 {
179 tDelta = ts + clearingTime - tDelta;
180 }
181
182 double intPower = 0.0;
183 if (tDelta < ts) // Case where there is overlap of a symbol due to interferer arriving just
184 // after desired signal
185 {
186 // Appears to be just the first two elements of the sum in Parrish paper, eq. 14
187 intPower += intPdp.SumTapsNc(Time(), ts - tDelta);
188 intPower +=
189 intPdp.SumTapsNc(ts - tDelta + clearingTime, 2 * ts - tDelta + clearingTime);
190 }
191 else // Account for case where there's overlap of a symbol due to interferer arriving with a
192 // tDelta of a symbol + clearing time later
193 {
194 // Appears to be just the first two elements of the sum in Parrish paper, eq. 14
195 Time start = ts + clearingTime - tDelta;
196 Time end =
197 /*start +*/ ts; // Should only sum over portion of ts that overlaps, not entire ts
198 intPower += intPdp.SumTapsNc(start, end);
199
200 start = start + ts + clearingTime;
201 // Should only sum over portion of ts that overlaps, not entire ts
202 end = end + ts + clearingTime; // start + Seconds (ts);
203 intPower += intPdp.SumTapsNc(start, end);
204 }
205 intKp += DbToKp(it->GetRxPowerDb()) * intPower;
206 }
207
208 double totalIntDb = KpToDb(isiUpa + intKp + DbToKp(ambNoiseDb));
209
210 NS_LOG_DEBUG("Calculating SINR: RxPower = "
211 << rxPowerDb << " dB. Effective Rx power " << effRxPowerDb
212 << " dB. Number of interferers = " << arrivalList.size()
213 << " Interference + noise power = " << totalIntDb
214 << " dB. SINR = " << effRxPowerDb - totalIntDb << " dB.");
215 return effRxPowerDb - totalIntDb;
216}
217
218/*************** UanPhyPerGenDefault definition *****************/
220{
221}
222
224{
225}
226
227TypeId
229{
230 static TypeId tid = TypeId("ns3::UanPhyPerGenDefault")
232 .SetGroupName("Uan")
233 .AddConstructor<UanPhyPerGenDefault>()
234 .AddAttribute("Threshold",
235 "SINR cutoff for good packet reception.",
236 DoubleValue(8),
238 MakeDoubleChecker<double>());
239 return tid;
240}
241
242// Default PER calculation simply compares SINR to a threshold which is configurable
243// via an attribute.
244double
246{
247 if (sinrDb >= m_thresh)
248 {
249 return 0;
250 }
251 else
252 {
253 return 1;
254 }
255}
256
257/*************** UanPhyPerCommonModes definition *****************/
259 : UanPhyPer()
260{
261}
262
264{
265}
266
267TypeId
269{
270 static TypeId tid = TypeId("ns3::UanPhyPerCommonModes")
272 .SetGroupName("Uan")
273 .AddConstructor<UanPhyPerCommonModes>();
274
275 return tid;
276}
277
278double
280{
281 NS_LOG_FUNCTION(this);
282
283 double EbNo = std::pow(10.0, sinrDb / 10.0);
284 double BER = 1.0;
285 double PER = 0.0;
286
287 switch (mode.GetModType())
288 {
289 case UanTxMode::PSK:
290 switch (mode.GetConstellationSize())
291 {
292 case 2: // BPSK
293 {
294 BER = 0.5 * erfc(sqrt(EbNo));
295 break;
296 }
297 case 4: // QPSK, half BPSK EbNo
298 {
299 BER = 0.5 * erfc(sqrt(0.5 * EbNo));
300 break;
301 }
302
303 default:
304 NS_FATAL_ERROR("constellation " << mode.GetConstellationSize() << " not supported");
305 break;
306 }
307 break;
308
309 // taken from Ronell B. Sicat, "Bit Error Probability Computations for M-ary Quadrature
310 // Amplitude Modulation", EE 242 Digital Communications and Codings, 2009
311 case UanTxMode::QAM: {
312 // generic EbNo
313 EbNo *= mode.GetDataRateBps() / mode.GetBandwidthHz();
314
315 auto M = (double)mode.GetConstellationSize();
316
317 // standard squared quantized QAM, even number of bits per symbol supported
318 int log2sqrtM = (int)::std::log2(sqrt(M));
319
320 double log2M = ::std::log2(M);
321
322 if ((int)log2M % 2)
323 {
324 NS_FATAL_ERROR("constellation " << M << " not supported");
325 }
326
327 double sqrtM = ::std::sqrt(M);
328
329 NS_LOG_DEBUG("M=" << M << "; log2sqrtM=" << log2sqrtM << "; log2M=" << log2M
330 << "; sqrtM=" << sqrtM);
331
332 BER = 0.0;
333
334 // Eq (75)
335 for (int k = 0; k < log2sqrtM; k++)
336 {
337 int sum_items =
338 (int)((1.0 - ::std::pow(2.0, (-1.0) * (double)k)) * ::std::sqrt(M) - 1.0);
339 double pow2k = ::std::pow(2.0, (double)k - 1.0);
340
341 NS_LOG_DEBUG("k=" << k << "; sum_items=" << sum_items << "; pow2k=" << pow2k);
342
343 double PbK = 0;
344
345 // Eq (74)
346 for (int j = 0; j < sum_items; ++j)
347 {
348 PbK += ::std::pow(-1.0, (double)j * pow2k / sqrtM) *
349 (pow2k - ::std::floor((double)(j * pow2k / sqrtM) - 0.5)) *
350 erfc((2.0 * (double)j + 1.0) *
351 ::std::sqrt(3.0 * (log2M * EbNo) / (2.0 * (M - 1.0))));
352
353 NS_LOG_DEBUG("j=" << j << "; PbK=" << PbK);
354 }
355 PbK *= 1.0 / sqrtM;
356
357 BER += PbK;
358
359 NS_LOG_DEBUG("k=" << k << "; PbK=" << PbK << "; BER=" << BER);
360 }
361
362 BER *= 1.0 / (double)log2sqrtM;
363
364 break;
365 }
366
367 case UanTxMode::FSK:
368 switch (mode.GetConstellationSize())
369 {
370 case 2: {
371 BER = 0.5 * erfc(sqrt(0.5 * EbNo));
372 break;
373 }
374
375 default:
376 NS_FATAL_ERROR("constellation " << mode.GetConstellationSize() << " not supported");
377 }
378 break;
379
380 default: // OTHER and error
381 NS_FATAL_ERROR("Mode " << mode.GetModType() << " not supported");
382 break;
383 }
384
385 PER = (1.0 - pow(1.0 - BER, (double)pkt->GetSize() * 8.0));
386
387 NS_LOG_DEBUG("BER=" << BER << "; PER=" << PER);
388
389 return PER;
390}
391
392/*************** UanPhyPerUmodem definition *****************/
394{
395}
396
398{
399}
400
401TypeId
403{
404 static TypeId tid = TypeId("ns3::UanPhyPerUmodem")
406 .SetGroupName("Uan")
407 .AddConstructor<UanPhyPerUmodem>();
408 return tid;
409}
410
411double
413{
414 double result;
415
416 result = 1.0;
417
418 for (uint32_t i = std::max(k, n - k) + 1; i <= n; ++i)
419 {
420 result *= i;
421 }
422
423 for (uint32_t i = 2; i <= std::min(k, n - k); ++i)
424 {
425 result /= i;
426 }
427
428 return result;
429}
430
431double
433{
434 uint32_t d[] = {12, 14, 16, 18, 20, 22, 24, 26, 28};
435 double Bd[] =
436 {33, 281, 2179, 15035LLU, 105166LLU, 692330LLU, 4580007LLU, 29692894LLU, 190453145LLU};
437
438 // double Rc = 1.0 / 2.0;
439 double ebno = std::pow(10.0, sinr / 10.0);
440 double perror = 1.0 / (2.0 + ebno);
441 double P[9];
442
443 if ((mode.GetModType() != UanTxMode::FSK) && (mode.GetConstellationSize() != 13))
444 {
445 NS_FATAL_ERROR("Calculating SINR for unsupported mode type");
446 }
447 if (sinr >= 10)
448 {
449 return 0;
450 }
451 if (sinr <= 6)
452 {
453 return 1;
454 }
455
456 for (uint32_t r = 0; r < 9; r++)
457 {
458 double sumd = 0;
459 for (uint32_t k = 0; k < d[r]; k++)
460 {
461 sumd = sumd + NChooseK(d[r] - 1 + k, k) * std::pow(1 - perror, (double)k);
462 }
463 P[r] = std::pow(perror, (double)d[r]) * sumd;
464 }
465
466 double Pb = 0;
467 for (uint32_t r = 0; r < 8; r++)
468 {
469 Pb = Pb + Bd[r] * P[r];
470 }
471
472 // cout << "Pb = " << Pb << endl;
473 uint32_t bits = pkt->GetSize() * 8;
474
475 double Ppacket = 1;
476 double temp = NChooseK(bits, 0);
477 temp *= std::pow((1 - Pb), (double)bits);
478 Ppacket -= temp;
479 temp = NChooseK(288, 1) * Pb * std::pow((1 - Pb), bits - 1.0);
480 Ppacket -= temp;
481
482 if (Ppacket > 1)
483 {
484 return 1;
485 }
486 else
487 {
488 return Ppacket;
489 }
490}
491
492/*************** UanPhyGen definition *****************/
494 : UanPhy(),
495 m_state(IDLE),
496 m_channel(nullptr),
497 m_transducer(nullptr),
498 m_device(nullptr),
499 m_mac(nullptr),
500 m_txPwrDb(0),
501 m_rxThreshDb(0),
502 m_ccaThreshDb(0),
503 m_pktRx(nullptr),
504 m_pktTx(nullptr),
505 m_cleared(false)
506{
507 m_pg = CreateObject<UniformRandomVariable>();
508
510}
511
513{
514}
515
516void
518{
519 if (m_cleared)
520 {
521 return;
522 }
523 m_cleared = true;
524 m_listeners.clear();
525 if (m_channel)
526 {
527 m_channel->Clear();
528 m_channel = nullptr;
529 }
530 if (m_transducer)
531 {
532 m_transducer->Clear();
533 m_transducer = nullptr;
534 }
535 if (m_device)
536 {
537 m_device->Clear();
538 m_device = nullptr;
539 }
540 if (m_mac)
541 {
542 m_mac->Clear();
543 m_mac = nullptr;
544 }
545 if (m_per)
546 {
547 m_per->Clear();
548 m_per = nullptr;
549 }
550 if (m_sinr)
551 {
552 m_sinr->Clear();
553 m_sinr = nullptr;
554 }
555 m_pktRx = nullptr;
556}
557
558void
560{
561 Clear();
564}
565
568{
569 UanModesList l;
570
571 // micromodem only
572 l.AppendMode(UanTxModeFactory::CreateMode(UanTxMode::FSK, 80, 80, 22000, 4000, 13, "FH-FSK"));
573 l.AppendMode(UanTxModeFactory::CreateMode(UanTxMode::PSK, 200, 200, 22000, 4000, 4, "QPSK"));
574 // micromodem2
575 l.AppendMode(UanTxModeFactory::CreateMode(UanTxMode::PSK, 5000, 5000, 25000, 5000, 4, "QPSK"));
576
577 return l;
578}
579
580TypeId
582{
583 static TypeId tid =
584 TypeId("ns3::UanPhyGen")
585 .SetParent<UanPhy>()
586 .SetGroupName("Uan")
587 .AddConstructor<UanPhyGen>()
588 .AddAttribute("CcaThreshold",
589 "Aggregate energy of incoming signals to move to CCA Busy state dB.",
590 DoubleValue(10),
592 MakeDoubleChecker<double>())
593 .AddAttribute("RxThreshold",
594 "Required SNR for signal acquisition in dB.",
595 DoubleValue(10),
597 MakeDoubleChecker<double>())
598 .AddAttribute("TxPower",
599 "Transmission output power in dB.",
600 DoubleValue(190),
602 MakeDoubleChecker<double>())
603 .AddAttribute("SupportedModes",
604 "List of modes supported by this PHY.",
608 .AddAttribute("PerModel",
609 "Functor to calculate PER based on SINR and TxMode.",
610 StringValue("ns3::UanPhyPerGenDefault"),
612 MakePointerChecker<UanPhyPer>())
613 .AddAttribute("SinrModel",
614 "Functor to calculate SINR based on pkt arrivals and modes.",
615 StringValue("ns3::UanPhyCalcSinrDefault"),
617 MakePointerChecker<UanPhyCalcSinr>())
618 .AddTraceSource("RxOk",
619 "A packet was received successfully.",
621 "ns3::UanPhy::TracedCallback")
622 .AddTraceSource("RxError",
623 "A packet was received unsuccessfuly.",
625 "ns3::UanPhy::TracedCallback")
626 .AddTraceSource("Tx",
627 "Packet transmission beginning.",
629 "ns3::UanPhy::TracedCallback");
630 return tid;
631}
632
633void
635{
636 NS_LOG_FUNCTION(this);
637 m_energyCallback = cb;
638}
639
640void
642{
643 NS_LOG_FUNCTION(this);
644
646 {
647 m_energyCallback(state);
648 }
649}
650
651void
653{
654 NS_LOG_FUNCTION(this);
655 NS_LOG_DEBUG("Energy depleted at node " << m_device->GetNode()->GetId()
656 << ", stopping rx/tx activities");
657
660 {
663 m_pktTx = nullptr;
664 }
666 {
669 m_pktRx = nullptr;
670 }
671}
672
673void
675{
676 NS_LOG_FUNCTION(this);
677 NS_LOG_DEBUG("Energy recharged at node " << m_device->GetNode()->GetId()
678 << ", restoring rx/tx activities");
679
680 m_state = IDLE;
681}
682
683void
685{
686 NS_LOG_DEBUG("PHY " << m_mac->GetAddress() << ": Transmitting packet");
687 if (m_state == DISABLED)
688 {
689 NS_LOG_DEBUG("Energy depleted, node cannot transmit any packet. Dropping.");
690 return;
691 }
692
693 if (m_state == TX)
694 {
695 NS_LOG_DEBUG("PHY requested to TX while already Transmitting. Dropping packet.");
696 return;
697 }
698 else if (m_state == SLEEP)
699 {
700 NS_LOG_DEBUG("PHY requested to TX while sleeping. Dropping packet.");
701 return;
702 }
703
704 UanTxMode txMode = GetMode(modeNum);
705
706 if (m_pktRx)
707 {
708 m_minRxSinrDb = -1e30;
709 m_pktRx = nullptr;
710 }
711
712 m_transducer->Transmit(Ptr<UanPhy>(this), pkt, m_txPwrDb, txMode);
713 m_state = TX;
715 double txdelay = pkt->GetSize() * 8.0 / txMode.GetDataRateBps();
716 m_pktTx = pkt;
718 NS_LOG_DEBUG("PHY " << m_mac->GetAddress() << " notifying listeners");
720 m_txLogger(pkt, m_txPwrDb, txMode);
721}
722
723void
725{
726 if (m_state == SLEEP || m_state == DISABLED)
727 {
728 NS_LOG_DEBUG("Transmission ended but node sleeping or dead");
729 return;
730 }
731
732 NS_ASSERT(m_state == TX);
734 {
737 }
738 else
739 {
740 m_state = IDLE;
741 }
743
745}
746
747void
749{
750 m_listeners.push_back(listener);
751}
752
753void
754UanPhyGen::StartRxPacket(Ptr<Packet> pkt, double rxPowerDb, UanTxMode txMode, UanPdp pdp)
755{
756 NS_LOG_DEBUG("PHY " << m_mac->GetAddress() << ": rx power after RX gain = " << rxPowerDb
757 << " dB re uPa");
758
759 switch (m_state)
760 {
761 case DISABLED:
762 NS_LOG_DEBUG("Energy depleted, node cannot receive any packet. Dropping.");
763 NotifyRxDrop(pkt); // traced source netanim
764 return;
765 case TX:
766 NotifyRxDrop(pkt); // traced source netanim
767 NS_ASSERT(false);
768 break;
769 case RX: {
771 double newSinrDb =
773 m_minRxSinrDb = (newSinrDb < m_minRxSinrDb) ? newSinrDb : m_minRxSinrDb;
774 NS_LOG_DEBUG("PHY " << m_mac->GetAddress()
775 << ": Starting RX in RX mode. SINR of pktRx = " << m_minRxSinrDb);
776 NotifyRxBegin(pkt); // traced source netanim
777 }
778 break;
779
780 case CCABUSY:
781 case IDLE: {
783 bool hasmode = false;
784 for (uint32_t i = 0; i < GetNModes(); i++)
785 {
786 if (txMode.GetUid() == GetMode(i).GetUid())
787 {
788 hasmode = true;
789 break;
790 }
791 }
792 if (!hasmode)
793 {
794 break;
795 }
796
797 double newsinr = CalculateSinrDb(pkt, Simulator::Now(), rxPowerDb, txMode, pdp);
798 NS_LOG_DEBUG("PHY " << m_mac->GetAddress()
799 << ": Starting RX in IDLE mode. SINR = " << newsinr);
800 if (newsinr > m_rxThreshDb)
801 {
802 m_state = RX;
804 NotifyRxBegin(pkt); // traced source netanim
805 m_rxRecvPwrDb = rxPowerDb;
806 m_minRxSinrDb = newsinr;
807 m_pktRx = pkt;
809 m_pktRxMode = txMode;
810 m_pktRxPdp = pdp;
811 double txdelay = pkt->GetSize() * 8.0 / txMode.GetDataRateBps();
814 this,
815 pkt,
816 rxPowerDb,
817 txMode);
819 }
820 }
821 break;
822 case SLEEP:
823 NS_LOG_DEBUG("Sleep mode. Dropping packet.");
824 NotifyRxDrop(pkt); // traced source netanim
825 break;
826 }
827
829 {
832 }
833}
834
835void
836UanPhyGen::RxEndEvent(Ptr<Packet> pkt, double /* rxPowerDb */, UanTxMode txMode)
837{
838 if (pkt != m_pktRx)
839 {
840 return;
841 }
842
843 if (m_state == DISABLED || m_state == SLEEP)
844 {
845 NS_LOG_DEBUG("Sleep mode or dead. Dropping packet");
846 m_pktRx = nullptr;
847 NotifyRxDrop(pkt); // traced source netanim
848 return;
849 }
850
851 NotifyRxEnd(pkt); // traced source netanim
853 {
856 }
857 else
858 {
859 m_state = IDLE;
861 }
862
863 if (m_pg->GetValue(0, 1) > m_per->CalcPer(m_pktRx, m_minRxSinrDb, txMode))
864 {
865 m_rxOkLogger(pkt, m_minRxSinrDb, txMode);
867 if (!m_recOkCb.IsNull())
868 {
869 m_recOkCb(pkt, m_minRxSinrDb, txMode);
870 }
871 }
872 else
873 {
874 m_rxErrLogger(pkt, m_minRxSinrDb, txMode);
876 if (!m_recErrCb.IsNull())
877 {
879 }
880 }
881
882 m_pktRx = nullptr;
883}
884
885void
887{
888 m_recOkCb = cb;
889}
890
891void
893{
894 m_recErrCb = cb;
895}
896
897bool
899{
900 return m_state == SLEEP;
901}
902
903bool
905{
906 return m_state == IDLE;
907}
908
909bool
911{
912 return !IsStateIdle() && !IsStateSleep();
913}
914
915bool
917{
918 return m_state == RX;
919}
920
921bool
923{
924 return m_state == TX;
925}
926
927bool
929{
930 return m_state == CCABUSY;
931}
932
933void
935{
936 m_txPwrDb = txpwr;
937}
938
939void
941{
942 m_rxThreshDb = thresh;
943}
944
945void
947{
948 m_ccaThreshDb = thresh;
949}
950
951double
953{
954 return m_txPwrDb;
955}
956
957double
959{
960 return m_rxThreshDb;
961}
962
963double
965{
966 return m_ccaThreshDb;
967}
968
971{
972 return m_channel;
973}
974
977{
978 return m_device;
979}
980
983{
984 return m_transducer;
985}
986
987void
989{
990 m_channel = channel;
991}
992
993void
995{
996 m_device = device;
997}
998
999void
1001{
1002 m_mac = mac;
1003}
1004
1005void
1007{
1008 m_transducer = trans;
1009 m_transducer->AddPhy(this);
1010}
1011
1012void
1014{
1015 if (sleep)
1016 {
1017 m_state = SLEEP;
1018 if (!m_energyCallback.IsNull())
1019 {
1021 }
1022 }
1023 else if (m_state == SLEEP)
1024 {
1026 {
1027 m_state = CCABUSY;
1029 }
1030 else
1031 {
1032 m_state = IDLE;
1033 }
1034
1035 if (!m_energyCallback.IsNull())
1036 {
1038 }
1039 }
1040}
1041
1042int64_t
1044{
1045 NS_LOG_FUNCTION(this << stream);
1046 m_pg->SetStream(stream);
1047 return 1;
1048}
1049
1050void
1052 double /* txPowerDb */,
1053 UanTxMode /* txMode */)
1054{
1055 if (m_pktRx)
1056 {
1057 m_minRxSinrDb = -1e30;
1058 }
1059}
1060
1061void
1063{
1065 {
1066 m_state = IDLE;
1068 }
1069}
1070
1071double
1073 Time arrTime,
1074 double rxPowerDb,
1075 UanTxMode mode,
1076 UanPdp pdp)
1077{
1078 double noiseDb = m_channel->GetNoiseDbHz((double)mode.GetCenterFreqHz() / 1000.0) +
1079 10 * std::log10(mode.GetBandwidthHz());
1080 return m_sinr
1081 ->CalcSinrDb(pkt, arrTime, rxPowerDb, noiseDb, mode, pdp, m_transducer->GetArrivalList());
1082}
1083
1084double
1086{
1087 const UanTransducer::ArrivalList& arrivalList = m_transducer->GetArrivalList();
1088
1089 auto it = arrivalList.begin();
1090
1091 double interfPower = 0;
1092
1093 for (; it != arrivalList.end(); it++)
1094 {
1095 if (pkt != it->GetPacket())
1096 {
1097 interfPower += DbToKp(it->GetRxPowerDb());
1098 }
1099 }
1100
1101 return KpToDb(interfPower);
1102}
1103
1104double
1106{
1107 return std::pow(10, db / 10.0);
1108}
1109
1110double
1112{
1113 return 10 * std::log10(kp);
1114}
1115
1116void
1118{
1119 auto it = m_listeners.begin();
1120 for (; it != m_listeners.end(); it++)
1121 {
1122 (*it)->NotifyRxStart();
1123 }
1124}
1125
1126void
1128{
1129 auto it = m_listeners.begin();
1130 for (; it != m_listeners.end(); it++)
1131 {
1132 (*it)->NotifyRxEndOk();
1133 }
1134}
1135
1136void
1138{
1139 auto it = m_listeners.begin();
1140 for (; it != m_listeners.end(); it++)
1141 {
1142 (*it)->NotifyRxEndError();
1143 }
1144}
1145
1146void
1148{
1149 auto it = m_listeners.begin();
1150 for (; it != m_listeners.end(); it++)
1151 {
1152 (*it)->NotifyCcaStart();
1153 }
1154}
1155
1156void
1158{
1159 auto it = m_listeners.begin();
1160 for (; it != m_listeners.end(); it++)
1161 {
1162 (*it)->NotifyCcaEnd();
1163 }
1164}
1165
1166void
1168{
1169 auto it = m_listeners.begin();
1170 for (; it != m_listeners.end(); it++)
1171 {
1172 (*it)->NotifyTxStart(duration);
1173 }
1174}
1175
1176void
1178{
1179 auto it = m_listeners.begin();
1180 for (; it != m_listeners.end(); it++)
1181 {
1182 (*it)->NotifyTxEnd();
1183 }
1184}
1185
1188{
1189 return m_modes.GetNModes();
1190}
1191
1194{
1196
1197 return m_modes[n];
1198}
1199
1202{
1203 return m_pktRx;
1204}
1205
1206} // namespace ns3
void Nullify()
Discard the implementation, set it to null.
Definition: callback.h:575
bool IsNull() const
Check for null implementation.
Definition: callback.h:569
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
bool IsRunning() const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:76
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:444
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition: simulator.cc:285
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
Hold variables of type string.
Definition: string.h:56
Time GetDelay() const
Get the delay time, usually from first arrival of signal.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
Container for UanTxModes.
Definition: uan-tx-mode.h:259
uint32_t GetNModes() const
Get the number of modes in this list.
Definition: uan-tx-mode.cc:256
void AppendMode(UanTxMode mode)
Add mode to this list.
Definition: uan-tx-mode.cc:230
AttributeValue implementation for UanModesList.
Definition: uan-tx-mode.h:314
The power delay profile returned by propagation models.
Iterator GetEnd() const
Get the end of the tap list (one beyond the last entry).
double SumTapsFromMaxNc(Time delay, Time duration) const
Compute the non-coherent sum of tap amplitudes starting after a delay from the maximum amplitude for ...
double SumTapsNc(Time begin, Time end) const
Compute the non-coherent sum of tap amplitudes between a start and end time.
const Tap & GetTap(uint32_t i) const
Get the Tap at the specified delay index.
Iterator GetBegin() const
Get the beginning of the tap vector.
Default SINR calculator for UanPhyGen.
Definition: uan-phy-gen.h:166
double CalcSinrDb(Ptr< Packet > pkt, Time arrTime, double rxPowerDb, double ambNoiseDb, UanTxMode mode, UanPdp pdp, const UanTransducer::ArrivalList &arrivalList) const override
Calculate the SINR value for a packet.
Definition: uan-phy-gen.cc:72
UanPhyCalcSinrDefault()
Constructor.
Definition: uan-phy-gen.cc:53
static TypeId GetTypeId()
Register this type.
Definition: uan-phy-gen.cc:62
~UanPhyCalcSinrDefault() override
Destructor.
Definition: uan-phy-gen.cc:57
WHOI Micromodem like FH-FSK model.
Definition: uan-phy-gen.h:224
UanPhyCalcSinrFhFsk()
Constructor.
Definition: uan-phy-gen.cc:102
double CalcSinrDb(Ptr< Packet > pkt, Time arrTime, double rxPowerDb, double ambNoiseDb, UanTxMode mode, UanPdp pdp, const UanTransducer::ArrivalList &arrivalList) const override
Calculate the SINR value for a packet.
Definition: uan-phy-gen.cc:126
static TypeId GetTypeId()
Register this type.
Definition: uan-phy-gen.cc:111
~UanPhyCalcSinrFhFsk() override
Destructor.
Definition: uan-phy-gen.cc:106
uint32_t m_hops
Number of hops.
Definition: uan-phy-gen.h:246
Class used for calculating SINR of packet in UanPhy.
Definition: uan-phy.h:44
double DbToKp(double db) const
Convert dB re 1 uPa to kilopascals.
Definition: uan-phy.h:80
double KpToDb(double kp) const
Convert kilopascals to dB re 1 uPa.
Definition: uan-phy.h:91
Generic PHY model.
Definition: uan-phy-gen.h:261
Ptr< UanChannel > GetChannel() const override
Get the attached channel.
Definition: uan-phy-gen.cc:970
bool IsStateSleep() override
Definition: uan-phy-gen.cc:898
void SetTxPowerDb(double txpwr) override
Set the transmit power.
Definition: uan-phy-gen.cc:934
double KpToDb(double kp)
Convert kilopascals to dB.
void NotifyTransStartTx(Ptr< Packet > packet, double txPowerDb, UanTxMode txMode) override
Called when a transmission is beginning on the attached transducer.
int64_t AssignStreams(int64_t stream) override
Assign a fixed random variable stream number to the random variables used by this model.
Ptr< UanPhyPer > m_per
Error model.
Definition: uan-phy-gen.h:331
UanPhyGen()
Constructor.
Definition: uan-phy-gen.cc:493
void SetRxThresholdDb(double thresh) override
Set the minimum SINR threshold to receive a packet without errors.
Definition: uan-phy-gen.cc:940
void EnergyDepletionHandler() override
Handle the energy depletion event.
Definition: uan-phy-gen.cc:652
void NotifyListenersTxStart(Time duration)
Call UanListener::NotifyTxStart on all listeners.
Time m_pktRxArrTime
Packet arrival time.
Definition: uan-phy-gen.h:342
UanTxMode GetMode(uint32_t n) override
Get a specific transmission mode.
void UpdatePowerConsumption(const State state)
Update energy source with new state.
Definition: uan-phy-gen.cc:641
double GetRxThresholdDb() override
Get the minimum received signal strength required to receive a packet without errors.
Definition: uan-phy-gen.cc:958
ListenerList m_listeners
List of listeners.
Definition: uan-phy-gen.h:324
void NotifyListenersCcaStart()
Call UanListener::NotifyCcaStart on all listeners.
void SetSleepMode(bool sleep) override
Set the Phy SLEEP mode.
~UanPhyGen() override
Dummy destructor, see DoDispose.
Definition: uan-phy-gen.cc:512
double m_rxRecvPwrDb
Receiver power.
Definition: uan-phy-gen.h:341
bool IsStateBusy() override
Definition: uan-phy-gen.cc:910
void NotifyListenersRxGood()
Call UanListener::NotifyRxEndOk on all listeners.
uint32_t GetNModes() override
Get the number of transmission modes supported by this Phy.
Ptr< UanPhyCalcSinr > m_sinr
SINR calculator.
Definition: uan-phy-gen.h:332
void NotifyListenersRxBad()
Call UanListener::NotifyRxEndError on all listeners.
double GetCcaThresholdDb() override
Get the CCA threshold signal strength required to detect channel busy.
Definition: uan-phy-gen.cc:964
Ptr< Packet > m_pktRx
Received packet.
Definition: uan-phy-gen.h:338
void SetReceiveErrorCallback(RxErrCallback cb) override
Set the callback to be used when a packet is received with errors.
Definition: uan-phy-gen.cc:892
Ptr< UanTransducer > GetTransducer() override
Get the attached transducer.
Definition: uan-phy-gen.cc:982
DeviceEnergyModel::ChangeStateCallback m_energyCallback
Energy model callback.
Definition: uan-phy-gen.h:355
Ptr< UanTransducer > m_transducer
Associated transducer.
Definition: uan-phy-gen.h:328
double m_rxThreshDb
Receive SINR threshold.
Definition: uan-phy-gen.h:335
EventId m_rxEndEvent
Rx event.
Definition: uan-phy-gen.h:349
void DoDispose() override
Destructor implementation.
Definition: uan-phy-gen.cc:559
double m_ccaThreshDb
CCA busy threshold.
Definition: uan-phy-gen.h:336
void SetTransducer(Ptr< UanTransducer > trans) override
Attach a transducer to this Phy.
RxOkCallback m_recOkCb
Callback for packets received without error.
Definition: uan-phy-gen.h:325
State m_state
Phy state.
Definition: uan-phy-gen.h:323
void NotifyListenersTxEnd()
Call UanListener::NotifyTxEnd on all listeners.
Ptr< UanMac > m_mac
MAC layer.
Definition: uan-phy-gen.h:330
Ptr< UanNetDevice > GetDevice() const override
Get the device hosting this Phy.
Definition: uan-phy-gen.cc:976
double GetInterferenceDb(Ptr< Packet > pkt)
Calculate interference power from overlapping packet arrivals, in dB.
double m_txPwrDb
Transmit power.
Definition: uan-phy-gen.h:334
double CalculateSinrDb(Ptr< Packet > pkt, Time arrTime, double rxPowerDb, UanTxMode mode, UanPdp pdp)
Calculate the SINR value for a packet.
void SetReceiveOkCallback(RxOkCallback cb) override
Set the callback to be used when a packet is received without error.
Definition: uan-phy-gen.cc:886
static UanModesList GetDefaultModes()
Get the default transmission modes.
Definition: uan-phy-gen.cc:567
bool IsStateTx() override
Definition: uan-phy-gen.cc:922
ns3::TracedCallback< Ptr< const Packet >, double, UanTxMode > m_rxOkLogger
A packet destined for this Phy was received without error.
Definition: uan-phy-gen.h:357
Ptr< UniformRandomVariable > m_pg
Provides uniform random variables.
Definition: uan-phy-gen.h:352
EventId m_txEndEvent
Tx event.
Definition: uan-phy-gen.h:348
void SendPacket(Ptr< Packet > pkt, uint32_t modeNum) override
Send a packet using a specific transmission mode.
Definition: uan-phy-gen.cc:684
void RegisterListener(UanPhyListener *listener) override
Register a UanPhyListener to be notified of common UanPhy events.
Definition: uan-phy-gen.cc:748
bool m_cleared
Flag when we've been cleared.
Definition: uan-phy-gen.h:346
bool IsStateRx() override
Definition: uan-phy-gen.cc:916
void SetMac(Ptr< UanMac > mac) override
Set the MAC forwarding messages to this Phy.
double m_minRxSinrDb
Minimum receive SINR during packet reception.
Definition: uan-phy-gen.h:340
static TypeId GetTypeId()
Register this type.
Definition: uan-phy-gen.cc:581
void SetCcaThresholdDb(double thresh) override
Set the threshold for detecting channel busy.
Definition: uan-phy-gen.cc:946
Ptr< UanChannel > m_channel
Attached channel.
Definition: uan-phy-gen.h:327
bool IsStateCcaBusy() override
Definition: uan-phy-gen.cc:928
void SetEnergyModelCallback(DeviceEnergyModel::ChangeStateCallback cb) override
Set the DeviceEnergyModel callback for UanPhy device.
Definition: uan-phy-gen.cc:634
void SetDevice(Ptr< UanNetDevice > device) override
Set the device hosting this Phy.
Definition: uan-phy-gen.cc:994
double DbToKp(double db)
Convert dB to kilopascals.
UanTxMode m_pktRxMode
Packet transmission mode at receiver.
Definition: uan-phy-gen.h:344
void TxEndEvent()
Event to process end of packet transmission.
Definition: uan-phy-gen.cc:724
void Clear() override
Clear all pointer references.
Definition: uan-phy-gen.cc:517
Ptr< Packet > GetPacketRx() const override
Get the packet currently being received.
RxErrCallback m_recErrCb
Callback for packets received with errors.
Definition: uan-phy-gen.h:326
void RxEndEvent(Ptr< Packet > pkt, double rxPowerDb, UanTxMode txMode)
Event to process end of packet reception.
Definition: uan-phy-gen.cc:836
Ptr< UanNetDevice > m_device
Device hosting this Phy.
Definition: uan-phy-gen.h:329
void StartRxPacket(Ptr< Packet > pkt, double rxPowerDb, UanTxMode txMode, UanPdp pdp) override
Packet arriving from channel: i.e.
Definition: uan-phy-gen.cc:754
Ptr< Packet > m_pktTx
Sent packet.
Definition: uan-phy-gen.h:339
void SetChannel(Ptr< UanChannel > channel) override
Attach to a channel.
Definition: uan-phy-gen.cc:988
ns3::TracedCallback< Ptr< const Packet >, double, UanTxMode > m_txLogger
A packet was sent from this Phy.
Definition: uan-phy-gen.h:361
void NotifyIntChange() override
Called when there has been a change in the amount of interference this node is experiencing from othe...
double GetTxPowerDb() override
Get the current transmit power, in dB.
Definition: uan-phy-gen.cc:952
bool IsStateIdle() override
Definition: uan-phy-gen.cc:904
UanPdp m_pktRxPdp
Power delay profile of packet.
Definition: uan-phy-gen.h:343
void NotifyListenersCcaEnd()
Call UanListener::NotifyCcaEnd on all listeners.
void EnergyRechargeHandler() override
Handle the energy recharge event.
Definition: uan-phy-gen.cc:674
void NotifyListenersRxStart()
Call UanListener::NotifyRxStart on all listeners.
ns3::TracedCallback< Ptr< const Packet >, double, UanTxMode > m_rxErrLogger
A packet destined for this Phy was received with error.
Definition: uan-phy-gen.h:359
UanModesList m_modes
List of modes supported by this PHY.
Definition: uan-phy-gen.h:321
Base class for UAN Phy models.
Definition: uan-phy.h:178
void NotifyTxDrop(Ptr< const Packet > packet)
Called when the transducer attempts to transmit a new packet while already transmitting a prior packe...
Definition: uan-phy.cc:122
void NotifyRxDrop(Ptr< const Packet > packet)
Called when the Phy drops a packet.
Definition: uan-phy.cc:140
void NotifyRxBegin(Ptr< const Packet > packet)
Called when the Phy begins to receive a packet.
Definition: uan-phy.cc:128
void NotifyRxEnd(Ptr< const Packet > packet)
Called when a packet is received without error.
Definition: uan-phy.cc:134
State
Enum defining possible Phy states.
Definition: uan-phy.h:182
@ RX
Receiving.
Definition: uan-phy.h:185
@ SLEEP
Sleeping.
Definition: uan-phy.h:187
@ IDLE
Idle state.
Definition: uan-phy.h:183
@ DISABLED
Disabled.
Definition: uan-phy.h:188
@ TX
Transmitting.
Definition: uan-phy.h:186
@ CCABUSY
Channel busy.
Definition: uan-phy.h:184
Interface for PHY event listener.
Definition: uan-phy.h:145
Packet error rate calculation for common tx modes based on UanPhyPerUmodem.
Definition: uan-phy-gen.h:127
~UanPhyPerCommonModes() override
Destructor.
Definition: uan-phy-gen.cc:263
double CalcPer(Ptr< Packet > pkt, double sinrDb, UanTxMode mode) override
Calculate the Packet ERror probability based on SINR at the receiver and a tx mode.
Definition: uan-phy-gen.cc:279
UanPhyPerCommonModes()
Constructor.
Definition: uan-phy-gen.cc:258
static TypeId GetTypeId()
Register this type.
Definition: uan-phy-gen.cc:268
Default Packet Error Rate calculator for UanPhyGen.
Definition: uan-phy-gen.h:46
UanPhyPerGenDefault()
Constructor.
Definition: uan-phy-gen.cc:219
~UanPhyPerGenDefault() override
Destructor.
Definition: uan-phy-gen.cc:223
double CalcPer(Ptr< Packet > pkt, double sinrDb, UanTxMode mode) override
Calculate the packet error probability based on SINR at the receiver and a tx mode.
Definition: uan-phy-gen.cc:245
static TypeId GetTypeId()
Register this type.
Definition: uan-phy-gen.cc:228
double m_thresh
SINR threshold.
Definition: uan-phy-gen.h:62
Calculate packet error probability, based on received SINR and modulation (mode).
Definition: uan-phy.h:110
Packet error rate calculation assuming WHOI Micromodem-like PHY (FH-FSK)
Definition: uan-phy-gen.h:76
double CalcPer(Ptr< Packet > pkt, double sinrDb, UanTxMode mode) override
Calculate the packet error probability based on SINR at the receiver and a tx mode.
Definition: uan-phy-gen.cc:432
static TypeId GetTypeId()
Register this type.
Definition: uan-phy-gen.cc:402
double NChooseK(uint32_t n, uint32_t k)
Binomial coefficient.
Definition: uan-phy-gen.cc:412
UanPhyPerUmodem()
Constructor.
Definition: uan-phy-gen.cc:393
~UanPhyPerUmodem() override
Destructor.
Definition: uan-phy-gen.cc:397
std::list< UanPacketArrival > ArrivalList
List of arriving packets overlapping in time.
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
Abstraction of packet modulation information.
Definition: uan-tx-mode.h:43
uint32_t GetUid() const
Get a unique id for the mode.
Definition: uan-tx-mode.cc:82
@ QAM
Quadrature amplitude modulation.
Definition: uan-tx-mode.h:54
@ OTHER
Unspecified/undefined.
Definition: uan-tx-mode.h:56
@ PSK
Phase shift keying.
Definition: uan-tx-mode.h:53
@ FSK
Frequency shift keying.
Definition: uan-tx-mode.h:55
uint32_t GetConstellationSize() const
Get the number of constellation points in the modulation scheme.
Definition: uan-tx-mode.cc:70
uint32_t GetPhyRateSps() const
Get the physical signaling rate.
Definition: uan-tx-mode.cc:52
uint32_t GetDataRateBps() const
Get the data rate of the transmit mode.
Definition: uan-tx-mode.cc:46
uint32_t GetBandwidthHz() const
Get the transmission signal bandwidth.
Definition: uan-tx-mode.cc:64
ModulationType GetModType() const
Get the modulation type of the mode.
Definition: uan-tx-mode.cc:40
uint32_t GetCenterFreqHz() const
Get the transmission center frequency.
Definition: uan-tx-mode.cc:58
Hold an unsigned integer type.
Definition: uinteger.h:45
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
#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
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:259
Ptr< const AttributeChecker > MakeUanModesListChecker()
Definition: uan-tx-mode.cc:300
Ptr< const AttributeAccessor > MakeUanModesListAccessor(T1 a1)
Definition: uan-tx-mode.h:314
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
int64x64_t Abs(const int64x64_t &value)
Absolute value.
Definition: int64x64.h:215
#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_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Time Rem(const Time &lhs, const Time &rhs)
Remainder (modulus) from the quotient of two Times.
Definition: nstime.h:1133
@ IDLE
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:76