37 |
37 |
38 NS_LOG_COMPONENT_DEFINE ("YansWifiPhy"); |
38 NS_LOG_COMPONENT_DEFINE ("YansWifiPhy"); |
39 |
39 |
40 namespace ns3 { |
40 namespace ns3 { |
41 |
41 |
42 /**************************************************************** |
|
43 * Phy event class |
|
44 ****************************************************************/ |
|
45 |
|
46 class RxEvent |
|
47 { |
|
48 public: |
|
49 RxEvent (uint32_t size, WifiMode payloadMode, |
|
50 enum WifiPreamble preamble, |
|
51 Time duration, double rxPower) |
|
52 : m_size (size), |
|
53 m_payloadMode (payloadMode), |
|
54 m_preamble (preamble), |
|
55 m_startTime (Simulator::Now ()), |
|
56 m_endTime (m_startTime + duration), |
|
57 m_rxPowerW (rxPower), |
|
58 m_refCount (1) |
|
59 {} |
|
60 ~RxEvent () |
|
61 { |
|
62 NS_ASSERT (m_refCount == 0); |
|
63 } |
|
64 |
|
65 void Ref (void) const { |
|
66 m_refCount++; |
|
67 } |
|
68 void Unref (void) const { |
|
69 m_refCount--; |
|
70 if (m_refCount == 0) { |
|
71 delete this; |
|
72 } |
|
73 } |
|
74 Time GetDuration (void) const { |
|
75 return m_endTime - m_startTime; |
|
76 } |
|
77 Time GetStartTime (void) const { |
|
78 return m_startTime; |
|
79 } |
|
80 Time GetEndTime (void) const { |
|
81 return m_endTime; |
|
82 } |
|
83 bool Overlaps (Time time) const { |
|
84 if (m_startTime <= time && |
|
85 m_endTime >= time) { |
|
86 return true; |
|
87 } else { |
|
88 return false; |
|
89 } |
|
90 } |
|
91 double GetRxPowerW (void) const { |
|
92 return m_rxPowerW; |
|
93 } |
|
94 uint32_t GetSize (void) const { |
|
95 return m_size; |
|
96 } |
|
97 WifiMode GetPayloadMode (void) const { |
|
98 return m_payloadMode; |
|
99 } |
|
100 enum WifiPreamble GetPreambleType (void) const { |
|
101 return m_preamble; |
|
102 } |
|
103 |
|
104 private: |
|
105 uint32_t m_size; |
|
106 WifiMode m_payloadMode; |
|
107 enum WifiPreamble m_preamble; |
|
108 Time m_startTime; |
|
109 Time m_endTime; |
|
110 double m_rxPowerW; |
|
111 mutable int m_refCount; |
|
112 }; |
|
113 |
|
114 |
|
115 /**************************************************************** |
|
116 * Class which records SNIR change events for a |
|
117 * short period of time. |
|
118 ****************************************************************/ |
|
119 |
|
120 YansWifiPhy::NiChange::NiChange (Time time, double delta) |
|
121 : m_time (time), m_delta (delta) |
|
122 {} |
|
123 Time |
|
124 YansWifiPhy::NiChange::GetTime (void) const |
|
125 { |
|
126 return m_time; |
|
127 } |
|
128 double |
|
129 YansWifiPhy::NiChange::GetDelta (void) const |
|
130 { |
|
131 return m_delta; |
|
132 } |
|
133 bool |
|
134 YansWifiPhy::NiChange::operator < (YansWifiPhy::NiChange const &o) const |
|
135 { |
|
136 return (m_time < o.m_time)?true:false; |
|
137 } |
|
138 |
|
139 |
|
140 |
|
141 /**************************************************************** |
|
142 * The actual YansWifiPhy class |
|
143 ****************************************************************/ |
|
144 |
|
145 NS_OBJECT_ENSURE_REGISTERED (YansWifiPhy); |
42 NS_OBJECT_ENSURE_REGISTERED (YansWifiPhy); |
146 |
43 |
147 TypeId |
44 TypeId |
148 YansWifiPhy::GetTypeId (void) |
45 YansWifiPhy::GetTypeId (void) |
149 { |
46 { |
154 "The energy of a received signal should be higher than " |
51 "The energy of a received signal should be higher than " |
155 "this threshold (dbm) to allow the PHY layer to detect the signal.", |
52 "this threshold (dbm) to allow the PHY layer to detect the signal.", |
156 DoubleValue (-140.0), |
53 DoubleValue (-140.0), |
157 MakeDoubleAccessor (&YansWifiPhy::SetEdThreshold, |
54 MakeDoubleAccessor (&YansWifiPhy::SetEdThreshold, |
158 &YansWifiPhy::GetEdThreshold), |
55 &YansWifiPhy::GetEdThreshold), |
|
56 MakeDoubleChecker<double> ()) |
|
57 .AddAttribute ("CcaMode1Threshold", |
|
58 "The energy of a received signal should be higher than " |
|
59 "this threshold (dbm) to allow the PHY layer to declare CCA BUSY state", |
|
60 DoubleValue (-140.0), |
|
61 MakeDoubleAccessor (&YansWifiPhy::SetCcaMode1Threshold, |
|
62 &YansWifiPhy::GetCcaMode1Threshold), |
159 MakeDoubleChecker<double> ()) |
63 MakeDoubleChecker<double> ()) |
160 .AddAttribute ("TxGain", |
64 .AddAttribute ("TxGain", |
161 "Transmission gain (dB).", |
65 "Transmission gain (dB).", |
162 DoubleValue (1.0), |
66 DoubleValue (1.0), |
163 MakeDoubleAccessor (&YansWifiPhy::SetTxGain, |
67 MakeDoubleAccessor (&YansWifiPhy::SetTxGain, |
345 { |
276 { |
346 m_state->SetReceiveErrorCallback (callback); |
277 m_state->SetReceiveErrorCallback (callback); |
347 } |
278 } |
348 void |
279 void |
349 YansWifiPhy::StartReceivePacket (Ptr<Packet> packet, |
280 YansWifiPhy::StartReceivePacket (Ptr<Packet> packet, |
350 double rxPowerDbm, |
281 double rxPowerDbm, |
351 WifiMode txMode, |
282 WifiMode txMode, |
352 enum WifiPreamble preamble) |
283 enum WifiPreamble preamble) |
353 { |
284 { |
354 NS_LOG_FUNCTION (this << packet << rxPowerDbm << txMode << preamble); |
285 NS_LOG_FUNCTION (this << packet << rxPowerDbm << txMode << preamble); |
355 rxPowerDbm += m_rxGainDb; |
286 rxPowerDbm += m_rxGainDb; |
356 double rxPowerW = DbmToW (rxPowerDbm); |
287 double rxPowerW = DbmToW (rxPowerDbm); |
357 Time rxDuration = CalculateTxDuration (packet->GetSize (), txMode, preamble); |
288 Time rxDuration = CalculateTxDuration (packet->GetSize (), txMode, preamble); |
358 Time endRx = Simulator::Now () + rxDuration; |
289 Time endRx = Simulator::Now () + rxDuration; |
359 |
290 |
360 Ptr<RxEvent> event = Create<RxEvent> (packet->GetSize (), |
291 Ptr<InterferenceHelper::Event> event; |
361 txMode, |
292 event = m_interference.Add (packet->GetSize (), |
362 preamble, |
293 txMode, |
363 rxDuration, |
294 preamble, |
364 rxPowerW); |
295 rxDuration, |
365 AppendEvent (event); |
296 rxPowerW); |
366 |
297 |
367 switch (m_state->GetState ()) { |
298 switch (m_state->GetState ()) { |
368 case YansWifiPhy::SYNC: |
299 case YansWifiPhy::SYNC: |
369 NS_LOG_DEBUG ("drop packet because already in Sync (power="<< |
300 NS_LOG_DEBUG ("drop packet because already in Sync (power="<< |
370 rxPowerW<<"W)"); |
301 rxPowerW<<"W)"); |
473 YansWifiPhy::GetNTxPower (void) const |
386 YansWifiPhy::GetNTxPower (void) const |
474 { |
387 { |
475 return m_nTxPower; |
388 return m_nTxPower; |
476 } |
389 } |
477 |
390 |
478 double |
|
479 YansWifiPhy::CalculateSnr (WifiMode txMode, double ber) const |
|
480 { |
|
481 double low, high, precision; |
|
482 low = 1e-25; |
|
483 high = 1e25; |
|
484 precision = 1e-12; |
|
485 while (high - low > precision) |
|
486 { |
|
487 NS_ASSERT (high >= low); |
|
488 double middle = low + (high - low) / 2; |
|
489 if ((1 - m_errorRateModel->GetChunkSuccessRate (txMode, middle, 1)) > ber) |
|
490 { |
|
491 low = middle; |
|
492 } |
|
493 else |
|
494 { |
|
495 high = middle; |
|
496 } |
|
497 } |
|
498 return low; |
|
499 } |
|
500 |
|
501 void |
|
502 YansWifiPhy::Configure80211aParameters (void) |
|
503 { |
|
504 NS_LOG_FUNCTION (this); |
|
505 m_plcpLongPreambleDelayUs = 16; |
|
506 m_plcpShortPreambleDelayUs = 16; |
|
507 m_longPlcpHeaderMode = g_6mba; |
|
508 m_shortPlcpHeaderMode = g_6mba; |
|
509 m_plcpHeaderLength = 4 + 1 + 12 + 1 + 6; |
|
510 /* 4095 bytes at a 6Mb/s rate with a 1/2 coding rate. */ |
|
511 m_maxPacketDuration = CalculateTxDuration (4095, g_6mba, WIFI_PREAMBLE_LONG); |
|
512 } |
|
513 |
|
514 void |
|
515 YansWifiPhy::PrintModes (void) const |
|
516 { |
|
517 #if 0 |
|
518 for (double db = -10; db < 30; db+= 0.5) { |
|
519 double snr = DbToRatio (db); |
|
520 std::cout <<snr<<" "; |
|
521 for (uint8_t i = 0; i < GetNModes (); i++) { |
|
522 WifiMode mode = GetMode (i); |
|
523 double ber = 1-m_errorRateModel->GetChunkSuccessRate (mode,snr, 2000*8); |
|
524 std::cout <<ber<< " "; |
|
525 } |
|
526 std::cout << std::endl; |
|
527 } |
|
528 #endif |
|
529 } |
|
530 |
|
531 void |
391 void |
532 YansWifiPhy::Configure80211a (void) |
392 YansWifiPhy::Configure80211a (void) |
533 { |
393 { |
534 NS_LOG_FUNCTION (this); |
394 NS_LOG_FUNCTION (this); |
535 Configure80211aParameters (); |
395 m_interference.Configure80211aParameters (); |
536 m_modes.push_back (g_6mba); |
396 m_modes.push_back (g_6mba); |
537 m_modes.push_back (g_9mba); |
397 m_modes.push_back (g_9mba); |
538 m_modes.push_back (g_12mba); |
398 m_modes.push_back (g_12mba); |
539 m_modes.push_back (g_18mba); |
399 m_modes.push_back (g_18mba); |
540 m_modes.push_back (g_24mba); |
400 m_modes.push_back (g_24mba); |
541 m_modes.push_back (g_36mba); |
401 m_modes.push_back (g_36mba); |
542 m_modes.push_back (g_48mba); |
402 m_modes.push_back (g_48mba); |
543 m_modes.push_back (g_54mba); |
403 m_modes.push_back (g_54mba); |
544 |
|
545 PrintModes (); |
|
546 } |
404 } |
547 |
405 |
548 void |
406 void |
549 YansWifiPhy::ConfigureHolland (void) |
407 YansWifiPhy::ConfigureHolland (void) |
550 { |
408 { |
551 NS_LOG_FUNCTION (this); |
409 NS_LOG_FUNCTION (this); |
552 Configure80211aParameters (); |
410 m_interference.Configure80211aParameters (); |
553 m_modes.push_back (g_6mba); |
411 m_modes.push_back (g_6mba); |
554 m_modes.push_back (g_12mba); |
412 m_modes.push_back (g_12mba); |
555 m_modes.push_back (g_18mba); |
413 m_modes.push_back (g_18mba); |
556 m_modes.push_back (g_36mba); |
414 m_modes.push_back (g_36mba); |
557 m_modes.push_back (g_54mba); |
415 m_modes.push_back (g_54mba); |
558 |
|
559 PrintModes (); |
|
560 } |
416 } |
561 |
417 |
562 void |
418 void |
563 YansWifiPhy::RegisterListener (WifiPhyListener *listener) |
419 YansWifiPhy::RegisterListener (WifiPhyListener *listener) |
564 { |
420 { |
676 NS_ASSERT (m_nTxPower > 0); |
510 NS_ASSERT (m_nTxPower > 0); |
677 double dbm = m_txPowerBaseDbm + power * (m_txPowerEndDbm - m_txPowerBaseDbm) / m_nTxPower; |
511 double dbm = m_txPowerBaseDbm + power * (m_txPowerEndDbm - m_txPowerBaseDbm) / m_nTxPower; |
678 return dbm; |
512 return dbm; |
679 } |
513 } |
680 |
514 |
681 |
|
682 void |
|
683 YansWifiPhy::AppendEvent (Ptr<RxEvent> event) |
|
684 { |
|
685 /* attempt to remove the events which are |
|
686 * not useful anymore. |
|
687 * i.e.: all events which end _before_ |
|
688 * now - m_maxPacketDuration |
|
689 */ |
|
690 |
|
691 if (Simulator::Now () > GetMaxPacketDuration ()) |
|
692 { |
|
693 Time end = Simulator::Now () - GetMaxPacketDuration (); |
|
694 Events::iterator i = m_events.begin (); |
|
695 while (i != m_events.end () && |
|
696 (*i)->GetEndTime () <= end) |
|
697 { |
|
698 i++; |
|
699 } |
|
700 m_events.erase (m_events.begin (), i); |
|
701 } |
|
702 m_events.push_back (event); |
|
703 } |
|
704 |
|
705 |
|
706 double |
|
707 YansWifiPhy::CalculateSnr (double signal, double noiseInterference, WifiMode mode) const |
|
708 { |
|
709 // thermal noise at 290K in J/s = W |
|
710 static const double BOLTZMANN = 1.3803e-23; |
|
711 double Nt = BOLTZMANN * 290.0 * mode.GetBandwidth (); |
|
712 // receiver noise Floor (W) |
|
713 double noiseFloor = m_rxNoiseRatio * Nt; |
|
714 double noise = noiseFloor + noiseInterference; |
|
715 double snr = signal / noise; |
|
716 return snr; |
|
717 } |
|
718 |
|
719 double |
|
720 YansWifiPhy::CalculateNoiseInterferenceW (Ptr<RxEvent> event, NiChanges *ni) const |
|
721 { |
|
722 Events::const_iterator i = m_events.begin (); |
|
723 double noiseInterference = 0.0; |
|
724 while (i != m_events.end ()) |
|
725 { |
|
726 if (event == (*i)) |
|
727 { |
|
728 i++; |
|
729 continue; |
|
730 } |
|
731 if (event->Overlaps ((*i)->GetStartTime ())) |
|
732 { |
|
733 ni->push_back (NiChange ((*i)->GetStartTime (), (*i)->GetRxPowerW ())); |
|
734 } |
|
735 if (event->Overlaps ((*i)->GetEndTime ())) |
|
736 { |
|
737 ni->push_back (NiChange ((*i)->GetEndTime (), -(*i)->GetRxPowerW ())); |
|
738 } |
|
739 if ((*i)->Overlaps (event->GetStartTime ())) |
|
740 { |
|
741 noiseInterference += (*i)->GetRxPowerW (); |
|
742 } |
|
743 i++; |
|
744 } |
|
745 ni->push_back (NiChange (event->GetStartTime (), noiseInterference)); |
|
746 ni->push_back (NiChange (event->GetEndTime (), 0)); |
|
747 |
|
748 /* quicksort vector of NI changes by time. */ |
|
749 std::sort (ni->begin (), ni->end (), std::less<NiChange> ()); |
|
750 |
|
751 return noiseInterference; |
|
752 } |
|
753 |
|
754 double |
|
755 YansWifiPhy::CalculateChunkSuccessRate (double snir, Time duration, WifiMode mode) const |
|
756 { |
|
757 if (duration == NanoSeconds (0)) { |
|
758 return 1.0; |
|
759 } |
|
760 uint32_t rate = mode.GetPhyRate (); |
|
761 uint64_t nbits = (uint64_t)(rate * duration.GetSeconds ()); |
|
762 double csr = m_errorRateModel->GetChunkSuccessRate (mode, snir, (uint32_t)nbits); |
|
763 return csr; |
|
764 } |
|
765 |
|
766 double |
|
767 YansWifiPhy::CalculatePer (Ptr<const RxEvent> event, NiChanges *ni) const |
|
768 { |
|
769 double psr = 1.0; /* Packet Success Rate */ |
|
770 NiChanges::iterator j = ni->begin (); |
|
771 Time previous = (*j).GetTime (); |
|
772 uint64_t plcpPreambleDelayUs; |
|
773 WifiMode payloadMode = event->GetPayloadMode (); |
|
774 WifiMode headerMode; |
|
775 switch (event->GetPreambleType ()) { |
|
776 case WIFI_PREAMBLE_LONG: |
|
777 plcpPreambleDelayUs = m_plcpLongPreambleDelayUs; |
|
778 headerMode = m_longPlcpHeaderMode; |
|
779 break; |
|
780 case WIFI_PREAMBLE_SHORT: |
|
781 plcpPreambleDelayUs = m_plcpShortPreambleDelayUs; |
|
782 headerMode = m_shortPlcpHeaderMode; |
|
783 break; |
|
784 default: |
|
785 NS_ASSERT (false); |
|
786 // only to quiet compiler. Really stupid. |
|
787 plcpPreambleDelayUs = 0; |
|
788 headerMode = m_shortPlcpHeaderMode; |
|
789 break; |
|
790 } |
|
791 Time plcpHeaderStart = (*j).GetTime () + MicroSeconds (plcpPreambleDelayUs); |
|
792 Time plcpPayloadStart = plcpHeaderStart + |
|
793 Seconds ((m_plcpHeaderLength + 0.0) / headerMode.GetDataRate ()); |
|
794 double noiseInterferenceW = (*j).GetDelta (); |
|
795 double powerW = event->GetRxPowerW (); |
|
796 |
|
797 j++; |
|
798 while (ni->end () != j) |
|
799 { |
|
800 Time current = (*j).GetTime (); |
|
801 NS_ASSERT (current >= previous); |
|
802 |
|
803 if (previous >= plcpPayloadStart) |
|
804 { |
|
805 psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, |
|
806 noiseInterferenceW, |
|
807 payloadMode), |
|
808 current - previous, |
|
809 payloadMode); |
|
810 } |
|
811 else if (previous >= plcpHeaderStart) |
|
812 { |
|
813 if (current >= plcpPayloadStart) |
|
814 { |
|
815 psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, |
|
816 noiseInterferenceW, |
|
817 headerMode), |
|
818 plcpPayloadStart - previous, |
|
819 headerMode); |
|
820 psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, |
|
821 noiseInterferenceW, |
|
822 payloadMode), |
|
823 current - plcpPayloadStart, |
|
824 payloadMode); |
|
825 } |
|
826 else |
|
827 { |
|
828 NS_ASSERT (current >= plcpHeaderStart); |
|
829 psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, |
|
830 noiseInterferenceW, |
|
831 headerMode), |
|
832 current - previous, |
|
833 headerMode); |
|
834 } |
|
835 } |
|
836 else |
|
837 { |
|
838 if (current >= plcpPayloadStart) |
|
839 { |
|
840 psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, |
|
841 noiseInterferenceW, |
|
842 headerMode), |
|
843 plcpPayloadStart - plcpHeaderStart, |
|
844 headerMode); |
|
845 psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, |
|
846 noiseInterferenceW, |
|
847 payloadMode), |
|
848 current - plcpPayloadStart, |
|
849 payloadMode); |
|
850 } |
|
851 else if (current >= plcpHeaderStart) |
|
852 { |
|
853 psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, |
|
854 noiseInterferenceW, |
|
855 headerMode), |
|
856 current - plcpHeaderStart, |
|
857 headerMode); |
|
858 } |
|
859 } |
|
860 |
|
861 noiseInterferenceW += (*j).GetDelta (); |
|
862 previous = (*j).GetTime (); |
|
863 j++; |
|
864 } |
|
865 |
|
866 double per = 1 - psr; |
|
867 return per; |
|
868 } |
|
869 |
|
870 |
|
871 void |
515 void |
872 YansWifiPhy::EndSync (Ptr<Packet> packet, Ptr<RxEvent> event) |
516 YansWifiPhy::EndSync (Ptr<Packet> packet, Ptr<InterferenceHelper::Event> event) |
873 { |
517 { |
874 NS_LOG_FUNCTION (this << packet << event); |
518 NS_LOG_FUNCTION (this << packet << event); |
875 NS_ASSERT (IsStateSync ()); |
519 NS_ASSERT (IsStateSync ()); |
876 NS_ASSERT (event->GetEndTime () == Simulator::Now ()); |
520 NS_ASSERT (event->GetEndTime () == Simulator::Now ()); |
877 |
521 |
878 NiChanges ni; |
522 struct InterferenceHelper::SnrPer snrPer; |
879 double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni); |
523 snrPer = m_interference.CalculateSnrPer (event); |
880 double snr = CalculateSnr (event->GetRxPowerW (), |
524 |
881 noiseInterferenceW, |
525 NS_LOG_DEBUG ("mode="<<(event->GetPayloadMode ().GetDataRate ())<< |
882 event->GetPayloadMode ()); |
526 ", snr="<<snrPer.snr<<", per="<<snrPer.per<<", size="<<packet->GetSize ()); |
883 |
527 |
884 /* calculate the SNIR at the start of the packet and accumulate |
528 if (m_random.GetValue () > snrPer.per) |
885 * all SNIR changes in the snir vector. |
|
886 */ |
|
887 double per = CalculatePer (event, &ni); |
|
888 NS_LOG_DEBUG ("mode="<<(event->GetPayloadMode ().GetDataRate ())<< |
|
889 ", ber="<<(1-m_errorRateModel->GetChunkSuccessRate (event->GetPayloadMode (), snr, 1))<< |
|
890 ", snr="<<snr<<", per="<<per<<", size="<<packet->GetSize ()); |
|
891 |
|
892 if (m_random.GetValue () > per) |
|
893 { |
529 { |
894 m_state->SwitchFromSyncEndOk (packet, snr, event->GetPayloadMode (), event->GetPreambleType ()); |
530 m_state->SwitchFromSyncEndOk (packet, snrPer.snr, event->GetPayloadMode (), event->GetPreambleType ()); |
895 } |
531 } |
896 else |
532 else |
897 { |
533 { |
898 /* failure. */ |
534 /* failure. */ |
899 m_state->SwitchFromSyncEndError (packet, snr); |
535 m_state->SwitchFromSyncEndError (packet, snrPer.snr); |
900 } |
536 } |
901 } |
537 } |
902 |
538 |
903 |
539 |
904 |
540 |