26 #include "ns3/simulator.h"
27 #include "ns3/traced-callback.h"
29 #include "ns3/trace-source-accessor.h"
30 #include "ns3/double.h"
32 #include "ns3/uan-tx-mode.h"
34 #include "ns3/uinteger.h"
35 #include "ns3/energy-source-container.h"
36 #include "ns3/acoustic-modem-energy-model.h"
63 static TypeId tid =
TypeId (
"ns3::UanPhyCalcSinrDefault")
65 .AddConstructor<UanPhyCalcSinrDefault> ()
81 NS_LOG_WARN (
"Calculating SINR for unsupported modulation type");
84 double intKp = -
DbToKp (rxPowerDb);
85 UanTransducer::ArrivalList::const_iterator it = arrivalList.begin ();
86 for (; it != arrivalList.end (); it++)
88 intKp +=
DbToKp (it->GetRxPowerDb ());
91 double totalIntDb =
KpToDb (intKp +
DbToKp (ambNoiseDb));
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;
112 .AddConstructor<UanPhyCalcSinrFhFsk> ()
113 .AddAttribute (
"NumberOfHops",
114 "Number of frequencies in hopping pattern",
117 MakeUintegerChecker<uint32_t> ())
132 NS_LOG_WARN (
"Calculating SINR for unsupported mode type");
138 double clearingTime = (
m_hops - 1.0) * ts;
143 double maxTapDelay = 0.0;
145 for (; pit != pdp.
GetEnd (); pit++)
147 if (abs (pit->GetAmp ()) > maxAmp)
149 maxAmp = abs (pit->GetAmp ());
150 maxTapDelay = pit->GetDelay ().GetSeconds ();
155 double effRxPowerDb = rxPowerDb +
KpToDb (csp);
158 UanTransducer::ArrivalList::const_iterator it = arrivalList.begin ();
159 double intKp = -
DbToKp (effRxPowerDb);
160 for (; it != arrivalList.end (); it++)
162 UanPdp intPdp = it->GetPdp ();
163 double tDelta = std::abs (arrTime.
GetSeconds () + maxTapDelay - it->GetArrivalTime ().GetSeconds ());
168 int32_t syms = (uint32_t)( (
double) tDelta / (ts + clearingTime));
169 tDelta = tDelta - syms * (ts + clearingTime);
172 if (arrTime +
Seconds (maxTapDelay) > it->GetArrivalTime ())
174 tDelta = ts + clearingTime - tDelta;
177 double intPower = 0.0;
182 Seconds (2 * ts - tDelta + clearingTime));
188 intPower += intPdp.
SumTapsNc (start, end);
190 start = start +
Seconds (ts + clearingTime);
192 intPower += intPdp.
SumTapsNc (start, end);
194 intKp +=
DbToKp (it->GetRxPowerDb ()) * intPower;
197 double totalIntDb =
KpToDb (isiUpa + intKp +
DbToKp (ambNoiseDb));
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;
218 .AddConstructor<UanPhyPerGenDefault> ()
219 .AddAttribute (
"Threshold",
"SINR cutoff for good packet reception",
222 MakeDoubleChecker<double> ());
256 .AddConstructor<UanPhyPerUmodem> ()
268 for (uint32_t i = std::max (k,n - k) + 1; i <= n; ++i)
273 for (uint32_t i = 2; i <= std::min (k,n - k); ++i)
285 { 12, 14, 16, 18, 20, 22, 24, 26, 28 };
288 33, 281, 2179, 15035LLU, 105166LLU, 692330LLU, 4580007LLU, 29692894LLU,
293 double ebno = std::pow (10.0, sinr / 10.0);
294 double perror = 1.0 / (2.0 + ebno);
306 for (uint32_t r = 0; r < 9; r++)
309 for (uint32_t k = 0; k < d[r]; k++)
311 sumd = sumd +
NChooseK (d[r] - 1 + k, k) * std::pow (1 - perror, (
double) k);
313 P[r] = std::pow (perror, (
double) d[r]) * sumd;
318 for (uint32_t r = 0; r < 8; r++)
320 Pb = Pb + Bd[r] * P[r];
324 uint32_t bits = pkt->
GetSize () * 8;
328 temp *= std::pow ( (1 - Pb), (
double) bits);
330 temp =
NChooseK (288, 1) * Pb * std::pow ( (1 - Pb), bits - 1.0);
359 m_pg = CreateObject<UniformRandomVariable> ();
433 .AddConstructor<UanPhyGen> ()
434 .AddAttribute (
"CcaThreshold",
435 "Aggregate energy of incoming signals to move to CCA Busy state dB",
438 MakeDoubleChecker<double> ())
439 .AddAttribute (
"RxThreshold",
440 "Required SNR for signal acquisition in dB",
443 MakeDoubleChecker<double> ())
444 .AddAttribute (
"TxPower",
445 "Transmission output power in dB",
448 MakeDoubleChecker<double> ())
449 .AddAttribute (
"RxGain",
450 "Gain added to incoming signal at receiver",
453 MakeDoubleChecker<double> ())
454 .AddAttribute (
"SupportedModes",
455 "List of modes supported by this PHY",
458 MakeUanModesListChecker () )
459 .AddAttribute (
"PerModel",
460 "Functor to calculate PER based on SINR and TxMode",
463 MakePointerChecker<UanPhyPer> ())
464 .AddAttribute (
"SinrModel",
465 "Functor to calculate SINR based on pkt arrivals and modes",
468 MakePointerChecker<UanPhyCalcSinr> ())
469 .AddTraceSource (
"RxOk",
470 "A packet was received successfully",
472 .AddTraceSource (
"RxError",
473 "A packet was received unsuccessfully",
475 .AddTraceSource (
"Tx",
476 "Packet transmission beginning",
506 ", stopping rx/tx activities");
517 NS_LOG_DEBUG (
"Energy depleted, node cannot transmit any packet. Dropping.");
523 NS_LOG_DEBUG (
"PHY requested to TX while already Transmitting. Dropping packet.");
528 NS_LOG_DEBUG (
"PHY requested to TX while sleeping. Dropping packet.");
555 NS_LOG_DEBUG (
"Transmission ended but node sleeping or dead");
584 NS_LOG_DEBUG (
"Energy depleted, node cannot receive any packet. Dropping.");
609 bool hasmode =
false;
610 for (uint32_t i = 0; i <
GetNModes (); i++)
908 UanTransducer::ArrivalList::const_iterator it = arrivalList.begin ();
910 double interfPower = 0;
912 for (; it != arrivalList.end (); it++)
914 if (pkt != it->GetPacket ())
916 interfPower +=
DbToKp (it->GetRxPowerDb ());
920 return KpToDb (interfPower);
927 return pow (10, db / 10.0);
932 return 10 * log10 (kp);
938 ListenerList::const_iterator it =
m_listeners.begin ();
941 (*it)->NotifyRxStart ();
948 ListenerList::const_iterator it =
m_listeners.begin ();
951 (*it)->NotifyRxEndOk ();
957 ListenerList::const_iterator it =
m_listeners.begin ();
960 (*it)->NotifyRxEndError ();
966 ListenerList::const_iterator it =
m_listeners.begin ();
969 (*it)->NotifyCcaStart ();
975 ListenerList::const_iterator it =
m_listeners.begin ();
978 (*it)->NotifyCcaEnd ();
985 ListenerList::const_iterator it =
m_listeners.begin ();
988 (*it)->NotifyTxStart (duration);