|
|
| 27 |
#include "wifi-mac.h" |
27 |
#include "wifi-mac.h" |
| 28 |
#include "mac-low.h" |
28 |
#include "mac-low.h" |
| 29 |
|
29 |
|
| 30 |
#define MY_DEBUG(x) \ |
|
|
| 31 |
NS_LOG_DEBUG (Simulator::Now () << " " << this << " " << x) |
| 32 |
|
| 33 |
namespace ns3 { |
30 |
namespace ns3 { |
| 34 |
|
31 |
|
| 35 |
NS_LOG_COMPONENT_DEFINE ("DcfManager"); |
32 |
NS_LOG_COMPONENT_DEFINE ("DcfManager"); |
|
|
| 55 |
void |
52 |
void |
| 56 |
DcfState::SetAifsn (uint32_t aifsn) |
53 |
DcfState::SetAifsn (uint32_t aifsn) |
| 57 |
{ |
54 |
{ |
|
|
55 |
NS_LOG_FUNCTION (this << aifsn); |
| 58 |
m_aifsn = aifsn; |
56 |
m_aifsn = aifsn; |
| 59 |
} |
57 |
} |
| 60 |
|
58 |
|
| 61 |
void |
59 |
void |
| 62 |
DcfState::SetTxopLimit (Time txopLimit) |
60 |
DcfState::SetTxopLimit (Time txopLimit) |
| 63 |
{ |
61 |
{ |
|
|
62 |
NS_LOG_FUNCTION (this << txopLimit); |
| 64 |
NS_ASSERT_MSG ((txopLimit.GetMicroSeconds () % 32 == 0), "The TXOP limit must be expressed in multiple of 32 microseconds!"); |
63 |
NS_ASSERT_MSG ((txopLimit.GetMicroSeconds () % 32 == 0), "The TXOP limit must be expressed in multiple of 32 microseconds!"); |
| 65 |
m_txopLimit = txopLimit; |
64 |
m_txopLimit = txopLimit; |
| 66 |
} |
65 |
} |
|
|
| 68 |
void |
67 |
void |
| 69 |
DcfState::SetCwMin (uint32_t minCw) |
68 |
DcfState::SetCwMin (uint32_t minCw) |
| 70 |
{ |
69 |
{ |
|
|
70 |
NS_LOG_FUNCTION (this << minCw); |
| 71 |
bool changed = (m_cwMin != minCw); |
71 |
bool changed = (m_cwMin != minCw); |
| 72 |
m_cwMin = minCw; |
72 |
m_cwMin = minCw; |
| 73 |
if (changed == true) |
73 |
if (changed == true) |
|
|
| 79 |
void |
79 |
void |
| 80 |
DcfState::SetCwMax (uint32_t maxCw) |
80 |
DcfState::SetCwMax (uint32_t maxCw) |
| 81 |
{ |
81 |
{ |
|
|
82 |
NS_LOG_FUNCTION (this << maxCw); |
| 82 |
bool changed = (m_cwMax != maxCw); |
83 |
bool changed = (m_cwMax != maxCw); |
| 83 |
m_cwMax = maxCw; |
84 |
m_cwMax = maxCw; |
| 84 |
if (changed == true) |
85 |
if (changed == true) |
|
|
| 114 |
void |
115 |
void |
| 115 |
DcfState::ResetCw (void) |
116 |
DcfState::ResetCw (void) |
| 116 |
{ |
117 |
{ |
|
|
118 |
NS_LOG_FUNCTION (this << m_cwMin); |
| 117 |
m_cw = m_cwMin; |
119 |
m_cw = m_cwMin; |
| 118 |
} |
120 |
} |
| 119 |
|
121 |
|
|
|
| 122 |
{ |
124 |
{ |
| 123 |
//see 802.11-2012, section 9.19.2.5 |
125 |
//see 802.11-2012, section 9.19.2.5 |
| 124 |
m_cw = std::min ( 2 * (m_cw + 1) - 1, m_cwMax); |
126 |
m_cw = std::min ( 2 * (m_cw + 1) - 1, m_cwMax); |
|
|
127 |
NS_LOG_DEBUG ("updated failed CW=" << m_cw); |
| 125 |
} |
128 |
} |
| 126 |
|
129 |
|
| 127 |
void |
130 |
void |
|
|
| 129 |
{ |
132 |
{ |
| 130 |
m_backoffSlots -= nSlots; |
133 |
m_backoffSlots -= nSlots; |
| 131 |
m_backoffStart = backoffUpdateBound; |
134 |
m_backoffStart = backoffUpdateBound; |
| 132 |
MY_DEBUG ("update slots=" << nSlots << " slots, backoff=" << m_backoffSlots); |
135 |
NS_LOG_DEBUG ("update slots=" << nSlots << " slots, backoff=" << m_backoffSlots); |
| 133 |
} |
136 |
} |
| 134 |
|
137 |
|
| 135 |
void |
138 |
void |
|
|
| 137 |
{ |
140 |
{ |
| 138 |
if (m_backoffSlots != 0) |
141 |
if (m_backoffSlots != 0) |
| 139 |
{ |
142 |
{ |
| 140 |
MY_DEBUG ("reset backoff from " << m_backoffSlots << " to " << nSlots << " slots"); |
143 |
NS_LOG_DEBUG ("reset backoff from " << m_backoffSlots << " to " << nSlots << " slots"); |
| 141 |
} |
144 |
} |
| 142 |
else |
145 |
else |
| 143 |
{ |
146 |
{ |
| 144 |
MY_DEBUG ("start backoff=" << nSlots << " slots"); |
147 |
NS_LOG_DEBUG ("start backoff=" << nSlots << " slots"); |
| 145 |
} |
148 |
} |
| 146 |
m_backoffSlots = nSlots; |
149 |
m_backoffSlots = nSlots; |
| 147 |
m_backoffStart = Simulator::Now (); |
150 |
m_backoffStart = Simulator::Now (); |
|
|
| 168 |
bool |
171 |
bool |
| 169 |
DcfState::IsAccessRequested (void) const |
172 |
DcfState::IsAccessRequested (void) const |
| 170 |
{ |
173 |
{ |
|
|
174 |
NS_LOG_FUNCTION (this << m_accessRequested); |
| 171 |
return m_accessRequested; |
175 |
return m_accessRequested; |
| 172 |
} |
176 |
} |
| 173 |
void |
177 |
void |
| 174 |
DcfState::NotifyAccessRequested (void) |
178 |
DcfState::NotifyAccessRequested (void) |
| 175 |
{ |
179 |
{ |
|
|
180 |
NS_LOG_FUNCTION (this); |
| 176 |
m_accessRequested = true; |
181 |
m_accessRequested = true; |
| 177 |
} |
182 |
} |
| 178 |
|
183 |
|
| 179 |
void |
184 |
void |
| 180 |
DcfState::NotifyAccessGranted (void) |
185 |
DcfState::NotifyAccessGranted (void) |
| 181 |
{ |
186 |
{ |
|
|
187 |
NS_LOG_FUNCTION (this); |
| 182 |
NS_ASSERT (m_accessRequested); |
188 |
NS_ASSERT (m_accessRequested); |
| 183 |
m_accessRequested = false; |
189 |
m_accessRequested = false; |
| 184 |
DoNotifyAccessGranted (); |
190 |
DoNotifyAccessGranted (); |
|
|
| 187 |
void |
193 |
void |
| 188 |
DcfState::NotifyCollision (void) |
194 |
DcfState::NotifyCollision (void) |
| 189 |
{ |
195 |
{ |
|
|
196 |
NS_LOG_FUNCTION (this); |
| 190 |
DoNotifyCollision (); |
197 |
DoNotifyCollision (); |
| 191 |
} |
198 |
} |
| 192 |
|
199 |
|
| 193 |
void |
200 |
void |
| 194 |
DcfState::NotifyInternalCollision (void) |
201 |
DcfState::NotifyInternalCollision (void) |
| 195 |
{ |
202 |
{ |
|
|
203 |
NS_LOG_FUNCTION (this); |
| 196 |
DoNotifyInternalCollision (); |
204 |
DoNotifyInternalCollision (); |
| 197 |
} |
205 |
} |
| 198 |
|
206 |
|
| 199 |
void |
207 |
void |
| 200 |
DcfState::NotifyChannelSwitching (void) |
208 |
DcfState::NotifyChannelSwitching (void) |
| 201 |
{ |
209 |
{ |
|
|
210 |
NS_LOG_FUNCTION (this); |
| 202 |
DoNotifyChannelSwitching (); |
211 |
DoNotifyChannelSwitching (); |
| 203 |
} |
212 |
} |
| 204 |
|
213 |
|
| 205 |
void |
214 |
void |
| 206 |
DcfState::NotifySleep (void) |
215 |
DcfState::NotifySleep (void) |
| 207 |
{ |
216 |
{ |
|
|
217 |
NS_LOG_FUNCTION (this); |
| 208 |
DoNotifySleep (); |
218 |
DoNotifySleep (); |
| 209 |
} |
219 |
} |
| 210 |
|
220 |
|
| 211 |
void |
221 |
void |
| 212 |
DcfState::NotifyWakeUp (void) |
222 |
DcfState::NotifyWakeUp (void) |
| 213 |
{ |
223 |
{ |
|
|
224 |
NS_LOG_FUNCTION (this); |
| 214 |
DoNotifyWakeUp (); |
225 |
DoNotifyWakeUp (); |
| 215 |
} |
226 |
} |
| 216 |
|
227 |
|
|
|
| 552 |
{ |
563 |
{ |
| 553 |
if (IsBusy ()) |
564 |
if (IsBusy ()) |
| 554 |
{ |
565 |
{ |
| 555 |
MY_DEBUG ("medium is busy: collision"); |
566 |
NS_LOG_DEBUG ("medium is busy: collision"); |
| 556 |
// someone else has accessed the medium; generate a backoff. |
567 |
// someone else has accessed the medium; generate a backoff. |
| 557 |
state->NotifyCollision (); |
568 |
state->NotifyCollision (); |
| 558 |
DoRestartAccessTimeoutIfNeeded (); |
569 |
DoRestartAccessTimeoutIfNeeded (); |
|
|
| 560 |
} |
571 |
} |
| 561 |
else if (IsWithinAifs (state)) |
572 |
else if (IsWithinAifs (state)) |
| 562 |
{ |
573 |
{ |
| 563 |
MY_DEBUG ("busy within AIFS"); |
574 |
NS_LOG_DEBUG ("busy within AIFS"); |
| 564 |
state->NotifyCollision (); |
575 |
state->NotifyCollision (); |
| 565 |
DoRestartAccessTimeoutIfNeeded (); |
576 |
DoRestartAccessTimeoutIfNeeded (); |
| 566 |
return; |
577 |
return; |
|
|
| 585 |
* This is the first dcf we find with an expired backoff and which |
596 |
* This is the first dcf we find with an expired backoff and which |
| 586 |
* needs access to the medium. i.e., it has data to send. |
597 |
* needs access to the medium. i.e., it has data to send. |
| 587 |
*/ |
598 |
*/ |
| 588 |
MY_DEBUG ("dcf " << k << " needs access. backoff expired. access granted. slots=" << state->GetBackoffSlots ()); |
599 |
NS_LOG_DEBUG ("dcf " << k << " needs access. backoff expired. access granted. slots=" << state->GetBackoffSlots ()); |
| 589 |
i++; //go to the next item in the list. |
600 |
i++; //go to the next item in the list. |
| 590 |
k++; |
601 |
k++; |
| 591 |
std::vector<DcfState *> internalCollisionStates; |
602 |
std::vector<DcfState *> internalCollisionStates; |
|
|
| 595 |
if (otherState->IsAccessRequested () |
606 |
if (otherState->IsAccessRequested () |
| 596 |
&& GetBackoffEndFor (otherState) <= Simulator::Now ()) |
607 |
&& GetBackoffEndFor (otherState) <= Simulator::Now ()) |
| 597 |
{ |
608 |
{ |
| 598 |
MY_DEBUG ("dcf " << k << " needs access. backoff expired. internal collision. slots=" << |
609 |
NS_LOG_DEBUG ("dcf " << k << " needs access. backoff expired. internal collision. slots=" << |
| 599 |
otherState->GetBackoffSlots ()); |
610 |
otherState->GetBackoffSlots ()); |
| 600 |
/** |
611 |
/** |
| 601 |
* all other dcfs with a lower priority whose backoff |
612 |
* all other dcfs with a lower priority whose backoff |
|
|
| 723 |
nIntSlots++; |
734 |
nIntSlots++; |
| 724 |
} |
735 |
} |
| 725 |
uint32_t n = std::min (nIntSlots, state->GetBackoffSlots ()); |
736 |
uint32_t n = std::min (nIntSlots, state->GetBackoffSlots ()); |
| 726 |
MY_DEBUG ("dcf " << k << " dec backoff slots=" << n); |
737 |
NS_LOG_DEBUG ("dcf " << k << " dec backoff slots=" << n); |
| 727 |
Time backoffUpdateBound = backoffStart + MicroSeconds (n * m_slotTimeUs); |
738 |
Time backoffUpdateBound = backoffStart + MicroSeconds (n * m_slotTimeUs); |
| 728 |
state->UpdateBackoffSlotsNow (n, backoffUpdateBound); |
739 |
state->UpdateBackoffSlotsNow (n, backoffUpdateBound); |
| 729 |
} |
740 |
} |
|
|
| 756 |
NS_LOG_DEBUG ("Access timeout needed: " << accessTimeoutNeeded); |
767 |
NS_LOG_DEBUG ("Access timeout needed: " << accessTimeoutNeeded); |
| 757 |
if (accessTimeoutNeeded) |
768 |
if (accessTimeoutNeeded) |
| 758 |
{ |
769 |
{ |
| 759 |
MY_DEBUG ("expected backoff end=" << expectedBackoffEnd); |
770 |
NS_LOG_DEBUG ("expected backoff end=" << expectedBackoffEnd); |
| 760 |
Time expectedBackoffDelay = expectedBackoffEnd - Simulator::Now (); |
771 |
Time expectedBackoffDelay = expectedBackoffEnd - Simulator::Now (); |
| 761 |
if (m_accessTimeout.IsRunning () |
772 |
if (m_accessTimeout.IsRunning () |
| 762 |
&& Simulator::GetDelayLeft (m_accessTimeout) > expectedBackoffDelay) |
773 |
&& Simulator::GetDelayLeft (m_accessTimeout) > expectedBackoffDelay) |
|
|
| 775 |
DcfManager::NotifyRxStartNow (Time duration) |
786 |
DcfManager::NotifyRxStartNow (Time duration) |
| 776 |
{ |
787 |
{ |
| 777 |
NS_LOG_FUNCTION (this << duration); |
788 |
NS_LOG_FUNCTION (this << duration); |
| 778 |
MY_DEBUG ("rx start for=" << duration); |
789 |
NS_LOG_DEBUG ("rx start for=" << duration); |
| 779 |
UpdateBackoff (); |
790 |
UpdateBackoff (); |
| 780 |
m_lastRxStart = Simulator::Now (); |
791 |
m_lastRxStart = Simulator::Now (); |
| 781 |
m_lastRxDuration = duration; |
792 |
m_lastRxDuration = duration; |
|
|
| 786 |
DcfManager::NotifyRxEndOkNow (void) |
797 |
DcfManager::NotifyRxEndOkNow (void) |
| 787 |
{ |
798 |
{ |
| 788 |
NS_LOG_FUNCTION (this); |
799 |
NS_LOG_FUNCTION (this); |
| 789 |
MY_DEBUG ("rx end ok"); |
800 |
NS_LOG_DEBUG ("rx end ok"); |
| 790 |
m_lastRxEnd = Simulator::Now (); |
801 |
m_lastRxEnd = Simulator::Now (); |
| 791 |
m_lastRxReceivedOk = true; |
802 |
m_lastRxReceivedOk = true; |
| 792 |
m_rxing = false; |
803 |
m_rxing = false; |
|
|
| 796 |
DcfManager::NotifyRxEndErrorNow (void) |
807 |
DcfManager::NotifyRxEndErrorNow (void) |
| 797 |
{ |
808 |
{ |
| 798 |
NS_LOG_FUNCTION (this); |
809 |
NS_LOG_FUNCTION (this); |
| 799 |
MY_DEBUG ("rx end error"); |
810 |
NS_LOG_DEBUG ("rx end error"); |
| 800 |
m_lastRxEnd = Simulator::Now (); |
811 |
m_lastRxEnd = Simulator::Now (); |
| 801 |
m_lastRxReceivedOk = false; |
812 |
m_lastRxReceivedOk = false; |
| 802 |
m_rxing = false; |
813 |
m_rxing = false; |
|
|
| 830 |
m_rxing = false; |
841 |
m_rxing = false; |
| 831 |
} |
842 |
} |
| 832 |
} |
843 |
} |
| 833 |
MY_DEBUG ("tx start for " << duration); |
844 |
NS_LOG_DEBUG ("tx start for " << duration); |
| 834 |
UpdateBackoff (); |
845 |
UpdateBackoff (); |
| 835 |
m_lastTxStart = Simulator::Now (); |
846 |
m_lastTxStart = Simulator::Now (); |
| 836 |
m_lastTxDuration = duration; |
847 |
m_lastTxDuration = duration; |
|
|
| 840 |
DcfManager::NotifyMaybeCcaBusyStartNow (Time duration) |
851 |
DcfManager::NotifyMaybeCcaBusyStartNow (Time duration) |
| 841 |
{ |
852 |
{ |
| 842 |
NS_LOG_FUNCTION (this << duration); |
853 |
NS_LOG_FUNCTION (this << duration); |
| 843 |
MY_DEBUG ("busy start for " << duration); |
854 |
NS_LOG_DEBUG ("busy start for " << duration); |
| 844 |
UpdateBackoff (); |
855 |
UpdateBackoff (); |
| 845 |
m_lastBusyStart = Simulator::Now (); |
856 |
m_lastBusyStart = Simulator::Now (); |
| 846 |
m_lastBusyDuration = duration; |
857 |
m_lastBusyDuration = duration; |
|
|
| 900 |
state->NotifyChannelSwitching (); |
911 |
state->NotifyChannelSwitching (); |
| 901 |
} |
912 |
} |
| 902 |
|
913 |
|
| 903 |
MY_DEBUG ("switching start for " << duration); |
914 |
NS_LOG_DEBUG ("switching start for " << duration); |
| 904 |
m_lastSwitchingStart = Simulator::Now (); |
915 |
m_lastSwitchingStart = Simulator::Now (); |
| 905 |
m_lastSwitchingDuration = duration; |
916 |
m_lastSwitchingDuration = duration; |
| 906 |
|
917 |
|
|
|
| 949 |
DcfManager::NotifyNavResetNow (Time duration) |
960 |
DcfManager::NotifyNavResetNow (Time duration) |
| 950 |
{ |
961 |
{ |
| 951 |
NS_LOG_FUNCTION (this << duration); |
962 |
NS_LOG_FUNCTION (this << duration); |
| 952 |
MY_DEBUG ("nav reset for=" << duration); |
963 |
NS_LOG_DEBUG ("nav reset for=" << duration); |
| 953 |
UpdateBackoff (); |
964 |
UpdateBackoff (); |
| 954 |
m_lastNavStart = Simulator::Now (); |
965 |
m_lastNavStart = Simulator::Now (); |
| 955 |
m_lastNavDuration = duration; |
966 |
m_lastNavDuration = duration; |
|
|
| 967 |
{ |
978 |
{ |
| 968 |
NS_LOG_FUNCTION (this << duration); |
979 |
NS_LOG_FUNCTION (this << duration); |
| 969 |
NS_ASSERT (m_lastNavStart <= Simulator::Now ()); |
980 |
NS_ASSERT (m_lastNavStart <= Simulator::Now ()); |
| 970 |
MY_DEBUG ("nav start for=" << duration); |
981 |
NS_LOG_DEBUG ("nav start for=" << duration); |
| 971 |
UpdateBackoff (); |
982 |
UpdateBackoff (); |
| 972 |
Time newNavEnd = Simulator::Now () + duration; |
983 |
Time newNavEnd = Simulator::Now () + duration; |
| 973 |
Time lastNavEnd = m_lastNavStart + m_lastNavDuration; |
984 |
Time lastNavEnd = m_lastNavStart + m_lastNavDuration; |