|
|
| 46 |
NS_OBJECT_ENSURE_REGISTERED (UanPhyCalcSinrDefault); |
46 |
NS_OBJECT_ENSURE_REGISTERED (UanPhyCalcSinrDefault); |
| 47 |
NS_OBJECT_ENSURE_REGISTERED (UanPhyCalcSinrFhFsk); |
47 |
NS_OBJECT_ENSURE_REGISTERED (UanPhyCalcSinrFhFsk); |
| 48 |
NS_OBJECT_ENSURE_REGISTERED (UanPhyPerUmodem); |
48 |
NS_OBJECT_ENSURE_REGISTERED (UanPhyPerUmodem); |
|
|
49 |
NS_OBJECT_ENSURE_REGISTERED (UanPhyPerCommonModes); |
| 49 |
|
50 |
|
| 50 |
|
51 |
|
| 51 |
/*************** UanPhyCalcSinrDefault definition *****************/ |
52 |
/*************** UanPhyCalcSinrDefault definition *****************/ |
|
|
| 130 |
UanPdp pdp, |
131 |
UanPdp pdp, |
| 131 |
const UanTransducer::ArrivalList &arrivalList) const |
132 |
const UanTransducer::ArrivalList &arrivalList) const |
| 132 |
{ |
133 |
{ |
| 133 |
if (mode.GetModType () != UanTxMode::FSK) |
134 |
if ((mode.GetModType () != UanTxMode::FSK) && (mode.GetConstellationSize () != 13)) |
| 134 |
{ |
135 |
{ |
| 135 |
NS_LOG_WARN ("Calculating SINR for unsupported mode type"); |
136 |
NS_FATAL_ERROR ("Calculating SINR for unsupported mode type"); |
| 136 |
} |
137 |
} |
| 137 |
|
138 |
|
| 138 |
|
|
|
| 139 |
|
| 140 |
double ts = 1.0 / mode.GetPhyRateSps (); |
139 |
double ts = 1.0 / mode.GetPhyRateSps (); |
| 141 |
double clearingTime = (m_hops - 1.0) * ts; |
140 |
double clearingTime = (m_hops - 1.0) * ts; |
| 142 |
double csp = pdp.SumTapsFromMaxNc (Seconds (0), Seconds (ts)); |
141 |
double csp = pdp.SumTapsFromMaxNc (Seconds (0), Seconds (ts)); |
|
|
| 243 |
} |
242 |
} |
| 244 |
} |
243 |
} |
| 245 |
|
244 |
|
|
|
245 |
/*************** UanPhyPerCommonModes definition *****************/ |
| 246 |
UanPhyPerCommonModes::UanPhyPerCommonModes () |
| 247 |
: UanPhyPer () |
| 248 |
{ |
| 249 |
|
| 250 |
} |
| 251 |
|
| 252 |
UanPhyPerCommonModes::~UanPhyPerCommonModes () |
| 253 |
{ |
| 254 |
|
| 255 |
} |
| 256 |
|
| 257 |
TypeId |
| 258 |
UanPhyPerCommonModes::GetTypeId (void) |
| 259 |
{ |
| 260 |
static TypeId tid = TypeId ("ns3::UanPhyPerCommonModes") |
| 261 |
.SetParent<UanPhyPer> () |
| 262 |
.SetGroupName ("Uan") |
| 263 |
.AddConstructor<UanPhyPerCommonModes> (); |
| 264 |
|
| 265 |
return tid; |
| 266 |
} |
| 267 |
|
| 268 |
double |
| 269 |
UanPhyPerCommonModes::CalcPer (Ptr<Packet> pkt, double sinrDb, UanTxMode mode) |
| 270 |
{ |
| 271 |
NS_LOG_FUNCTION (this); |
| 272 |
|
| 273 |
double EbNo = std::pow (10.0, sinrDb / 10.0); |
| 274 |
double BER = 1.0; |
| 275 |
double PER = 0.0; |
| 276 |
|
| 277 |
switch (mode.GetModType ()) |
| 278 |
{ |
| 279 |
case UanTxMode::PSK: |
| 280 |
switch (mode.GetConstellationSize ()) |
| 281 |
{ |
| 282 |
case 2: // BPSK |
| 283 |
{ |
| 284 |
BER = 0.5 * erfc (sqrt (EbNo)); |
| 285 |
break; |
| 286 |
} |
| 287 |
case 4: // QPSK, half BPSK EbNo |
| 288 |
{ |
| 289 |
BER = 0.5 * erfc (sqrt (0.5 * EbNo)); |
| 290 |
break; |
| 291 |
} |
| 292 |
|
| 293 |
default: |
| 294 |
NS_FATAL_ERROR ("constellation " << mode.GetConstellationSize () << " not supported"); |
| 295 |
break; |
| 296 |
} |
| 297 |
|
| 298 |
// taken from Ronell B. Sicat, "Bit Error Probability Computations for M-ary Quadrature Amplitude Modulation", |
| 299 |
// EE 242 Digital Communications and Codings, 2009 |
| 300 |
case UanTxMode::QAM: |
| 301 |
{ |
| 302 |
// generic EbNo |
| 303 |
EbNo *= mode.GetDataRateBps () / mode.GetBandwidthHz (); |
| 304 |
|
| 305 |
double M = (double) mode.GetConstellationSize (); |
| 306 |
|
| 307 |
// standard squared quantized QAM, even number of bits per symbol supported |
| 308 |
int log2sqrtM = (int) ::std::log2 ( sqrt (M)); |
| 309 |
|
| 310 |
double log2M = ::std::log2 (M); |
| 311 |
|
| 312 |
if ((int)log2M % 2) |
| 313 |
{ |
| 314 |
NS_FATAL_ERROR ("constellation " << M << " not supported"); |
| 315 |
} |
| 316 |
|
| 317 |
double sqrtM = ::std::sqrt (M); |
| 318 |
|
| 319 |
NS_LOG_DEBUG ("M=" << M << "; log2sqrtM=" << log2sqrtM << "; log2M=" << log2M << "; sqrtM=" << sqrtM); |
| 320 |
|
| 321 |
BER = 0.0; |
| 322 |
|
| 323 |
// Eq (75) |
| 324 |
for (int k = 0; k < log2sqrtM; k++) |
| 325 |
{ |
| 326 |
int sum_items = (int) ((1.0 - ::std::pow ( 2.0, (-1.0) * (double) k)) * ::std::sqrt (M) - 1.0); |
| 327 |
double pow2k = ::std::pow (2.0, (double) k - 1.0); |
| 328 |
|
| 329 |
NS_LOG_DEBUG ("k=" << k << "; sum_items=" << sum_items << "; pow2k=" << pow2k); |
| 330 |
|
| 331 |
double PbK = 0; |
| 332 |
|
| 333 |
// Eq (74) |
| 334 |
for (int j = 0; j < sum_items; ++j) |
| 335 |
{ |
| 336 |
PbK += ::std::pow (-1.0, (double) j * pow2k / sqrtM) |
| 337 |
* (pow2k - ::std::floor ( (double) (j * pow2k / sqrtM) - 0.5)) |
| 338 |
* erfc ((2.0 * (double)j + 1.0) * ::std::sqrt (3.0 * (log2M * EbNo) / (2.0 * (M - 1.0)))); |
| 339 |
|
| 340 |
NS_LOG_DEBUG ("j=" << j << "; PbK=" << PbK); |
| 341 |
|
| 342 |
} |
| 343 |
PbK *= 1.0 / sqrtM; |
| 344 |
|
| 345 |
BER += PbK; |
| 346 |
|
| 347 |
NS_LOG_DEBUG ("k=" << k << "; PbK=" << PbK << "; BER=" << BER); |
| 348 |
} |
| 349 |
|
| 350 |
BER *= 1.0 / (double) log2sqrtM; |
| 351 |
|
| 352 |
break; |
| 353 |
} |
| 354 |
|
| 355 |
case UanTxMode::FSK: |
| 356 |
switch (mode.GetConstellationSize ()) |
| 357 |
{ |
| 358 |
case 2: |
| 359 |
{ |
| 360 |
BER = 0.5 * erfc (sqrt (0.5 * EbNo)); |
| 361 |
break; |
| 362 |
} |
| 363 |
|
| 364 |
default: |
| 365 |
NS_FATAL_ERROR ("constellation " << mode.GetConstellationSize () << " not supported"); |
| 366 |
break; |
| 367 |
} |
| 368 |
|
| 369 |
default: // OTHER and error |
| 370 |
NS_FATAL_ERROR ("Mode " << mode.GetModType () << " not supported"); |
| 371 |
break; |
| 372 |
} |
| 373 |
|
| 374 |
PER = (1.0 - pow (1.0 - BER, (double) pkt->GetSize () * 8.0)); |
| 375 |
|
| 376 |
NS_LOG_DEBUG ("BER=" << BER << "; PER=" << PER); |
| 377 |
|
| 378 |
return PER; |
| 379 |
} |
| 380 |
|
| 246 |
/*************** UanPhyPerUmodem definition *****************/ |
381 |
/*************** UanPhyPerUmodem definition *****************/ |
| 247 |
UanPhyPerUmodem::UanPhyPerUmodem () |
382 |
UanPhyPerUmodem::UanPhyPerUmodem () |
| 248 |
{ |
383 |
{ |
|
|
| 299 |
double perror = 1.0 / (2.0 + ebno); |
434 |
double perror = 1.0 / (2.0 + ebno); |
| 300 |
double P[9]; |
435 |
double P[9]; |
| 301 |
|
436 |
|
|
|
437 |
if ((mode.GetModType () != UanTxMode::FSK) && (mode.GetConstellationSize () != 13)) |
| 438 |
{ |
| 439 |
NS_FATAL_ERROR ("Calculating SINR for unsupported mode type"); |
| 440 |
} |
| 302 |
if (sinr >= 10) |
441 |
if (sinr >= 10) |
| 303 |
{ |
442 |
{ |
| 304 |
return 0; |
443 |
return 0; |
|
|
| 425 |
UanPhyGen::GetDefaultModes (void) |
564 |
UanPhyGen::GetDefaultModes (void) |
| 426 |
{ |
565 |
{ |
| 427 |
UanModesList l; |
566 |
UanModesList l; |
| 428 |
l.AppendMode (UanTxModeFactory::CreateMode (UanTxMode::FSK,80,80,22000,4000,13,"FSK")); |
567 |
l.AppendMode (UanTxModeFactory::CreateMode (UanTxMode::FSK, 80, 80, 22000, 4000, 13, "FH-FSK")); // micromodem only |
| 429 |
l.AppendMode (UanTxModeFactory::CreateMode (UanTxMode::PSK,200, 200, 22000, 4000, 4, "QPSK")); |
568 |
l.AppendMode (UanTxModeFactory::CreateMode (UanTxMode::PSK, 200, 200, 22000, 4000, 4, "QPSK")); |
|
|
569 |
l.AppendMode (UanTxModeFactory::CreateMode (UanTxMode::PSK, 5000, 5000, 25000, 5000, 4, "QPSK")); // micromodem2 |
| 570 |
|
| 430 |
return l; |
571 |
return l; |
| 431 |
} |
572 |
} |
|
|
573 |
|
| 432 |
TypeId |
574 |
TypeId |
| 433 |
UanPhyGen::GetTypeId (void) |
575 |
UanPhyGen::GetTypeId (void) |
| 434 |
{ |
576 |
{ |
|
|
| 513 |
NS_LOG_FUNCTION (this); |
655 |
NS_LOG_FUNCTION (this); |
| 514 |
NS_LOG_DEBUG ("Energy depleted at node " << m_device->GetNode ()->GetId () << |
656 |
NS_LOG_DEBUG ("Energy depleted at node " << m_device->GetNode ()->GetId () << |
| 515 |
", stopping rx/tx activities"); |
657 |
", stopping rx/tx activities"); |
| 516 |
|
658 |
|
| 517 |
m_state = DISABLED; |
659 |
m_state = DISABLED; |
| 518 |
if(m_txEndEvent.IsRunning ()) |
660 |
if (m_txEndEvent.IsRunning ()) |
| 519 |
{ |
661 |
{ |
| 520 |
Simulator::Cancel (m_txEndEvent); |
662 |
Simulator::Cancel (m_txEndEvent); |
| 521 |
NotifyTxDrop (m_pktTx); |
663 |
NotifyTxDrop (m_pktTx); |
| 522 |
m_pktTx = 0; |
664 |
m_pktTx = 0; |
| 523 |
} |
665 |
} |
| 524 |
if(m_rxEndEvent.IsRunning ()) |
666 |
if (m_rxEndEvent.IsRunning ()) |
| 525 |
{ |
667 |
{ |
| 526 |
Simulator::Cancel (m_rxEndEvent); |
668 |
Simulator::Cancel (m_rxEndEvent); |
| 527 |
NotifyRxDrop (m_pktRx); |
669 |
NotifyRxDrop (m_pktRx); |
|
|
| 602 |
} |
744 |
} |
| 603 |
|
745 |
|
| 604 |
void |
746 |
void |
| 605 |
UanPhyGen::RegisterListener (UanPhyListener *listener) |
747 |
UanPhyGen::RegisterListener (UanPhyListener * listener) |
| 606 |
{ |
748 |
{ |
| 607 |
m_listeners.push_back (listener); |
749 |
m_listeners.push_back (listener); |
| 608 |
} |
750 |
} |
|
|
| 618 |
{ |
760 |
{ |
| 619 |
case DISABLED: |
761 |
case DISABLED: |
| 620 |
NS_LOG_DEBUG ("Energy depleted, node cannot receive any packet. Dropping."); |
762 |
NS_LOG_DEBUG ("Energy depleted, node cannot receive any packet. Dropping."); |
| 621 |
NotifyRxDrop(pkt); // traced source netanim |
763 |
NotifyRxDrop (pkt); // traced source netanim |
| 622 |
return; |
764 |
return; |
| 623 |
case TX: |
765 |
case TX: |
| 624 |
NotifyRxDrop(pkt); // traced source netanim |
766 |
NotifyRxDrop (pkt); // traced source netanim |
| 625 |
NS_ASSERT (false); |
767 |
NS_ASSERT (false); |
| 626 |
break; |
768 |
break; |
| 627 |
case RX: |
769 |
case RX: |
|
|
| 630 |
double newSinrDb = CalculateSinrDb (m_pktRx, m_pktRxArrTime, m_rxRecvPwrDb, m_pktRxMode, m_pktRxPdp); |
772 |
double newSinrDb = CalculateSinrDb (m_pktRx, m_pktRxArrTime, m_rxRecvPwrDb, m_pktRxMode, m_pktRxPdp); |
| 631 |
m_minRxSinrDb = (newSinrDb < m_minRxSinrDb) ? newSinrDb : m_minRxSinrDb; |
773 |
m_minRxSinrDb = (newSinrDb < m_minRxSinrDb) ? newSinrDb : m_minRxSinrDb; |
| 632 |
NS_LOG_DEBUG ("PHY " << m_mac->GetAddress () << ": Starting RX in RX mode. SINR of pktRx = " << m_minRxSinrDb); |
774 |
NS_LOG_DEBUG ("PHY " << m_mac->GetAddress () << ": Starting RX in RX mode. SINR of pktRx = " << m_minRxSinrDb); |
| 633 |
NotifyRxBegin(pkt); // traced source netanim |
775 |
NotifyRxBegin (pkt); // traced source netanim |
| 634 |
} |
776 |
} |
| 635 |
break; |
777 |
break; |
| 636 |
|
778 |
|
|
|
| 659 |
{ |
801 |
{ |
| 660 |
m_state = RX; |
802 |
m_state = RX; |
| 661 |
UpdatePowerConsumption (RX); |
803 |
UpdatePowerConsumption (RX); |
| 662 |
NotifyRxBegin(pkt); // traced source netanim |
804 |
NotifyRxBegin (pkt); // traced source netanim |
| 663 |
m_rxRecvPwrDb = rxPowerDb; |
805 |
m_rxRecvPwrDb = rxPowerDb; |
| 664 |
m_minRxSinrDb = newsinr; |
806 |
m_minRxSinrDb = newsinr; |
| 665 |
m_pktRx = pkt; |
807 |
m_pktRx = pkt; |
|
|
| 675 |
break; |
817 |
break; |
| 676 |
case SLEEP: |
818 |
case SLEEP: |
| 677 |
NS_LOG_DEBUG ("Sleep mode. Dropping packet."); |
819 |
NS_LOG_DEBUG ("Sleep mode. Dropping packet."); |
| 678 |
NotifyRxDrop(pkt); // traced source netanim |
820 |
NotifyRxDrop (pkt); // traced source netanim |
| 679 |
break; |
821 |
break; |
| 680 |
} |
822 |
} |
| 681 |
|
823 |
|
|
|
| 699 |
{ |
841 |
{ |
| 700 |
NS_LOG_DEBUG ("Sleep mode or dead. Dropping packet"); |
842 |
NS_LOG_DEBUG ("Sleep mode or dead. Dropping packet"); |
| 701 |
m_pktRx = 0; |
843 |
m_pktRx = 0; |
| 702 |
NotifyRxDrop(pkt); // traced source netanim |
844 |
NotifyRxDrop (pkt); // traced source netanim |
| 703 |
return; |
845 |
return; |
| 704 |
} |
846 |
} |
| 705 |
|
847 |
|
| 706 |
NotifyRxEnd(pkt); // traced source netanim |
848 |
NotifyRxEnd (pkt); // traced source netanim |
| 707 |
if (GetInterferenceDb ( (Ptr<Packet>) 0) > m_ccaThreshDb) |
849 |
if (GetInterferenceDb ( (Ptr<Packet>) 0) > m_ccaThreshDb) |
| 708 |
{ |
850 |
{ |
| 709 |
m_state = CCABUSY; |
851 |
m_state = CCABUSY; |
|
|
| 868 |
} |
1010 |
} |
| 869 |
|
1011 |
|
| 870 |
void |
1012 |
void |
| 871 |
UanPhyGen::SetSleepMode (bool sleep) |
1013 |
UanPhyGen::SetSleepMode (bool sleep ) |
| 872 |
{ |
1014 |
{ |
| 873 |
if (sleep) |
1015 |
if (sleep ) |
| 874 |
{ |
1016 |
{ |
| 875 |
m_state = SLEEP; |
1017 |
m_state = SLEEP; |
| 876 |
if (!m_energyCallback.IsNull ()) |
1018 |
if (!m_energyCallback.IsNull ()) |
| 877 |
{ |
1019 |
{ |
| 878 |
m_energyCallback (SLEEP); |
1020 |
m_energyCallback (SLEEP); |
| 879 |
} |
1021 |
} |
| 880 |
} |
1022 |
} |
| 881 |
else if (m_state == SLEEP) |
1023 |
else if (m_state == SLEEP) |
| 882 |
{ |
1024 |
{ |
| 883 |
if (GetInterferenceDb ((Ptr<Packet>) 0) > m_ccaThreshDb) |
1025 |
if (GetInterferenceDb ((Ptr<Packet>) 0) > m_ccaThreshDb) |