1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006,2007 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #include "ns3/log.h"
22 #include "ns3/boolean.h"
23 #include "ns3/uinteger.h"
24 #include "ns3/enum.h"
25 #include "ns3/simulator.h"
26 #include "wifi-remote-station-manager.h"
27 #include "wifi-phy.h"
28 #include "ap-wifi-mac.h"
29 #include "sta-wifi-mac.h"
30 #include "wifi-mac-header.h"
31 #include "wifi-mac-queue-item.h"
32 #include "wifi-mac-trailer.h"
33 #include "ns3/ht-configuration.h"
34 #include "ns3/ht-phy.h"
35 #include "ns3/vht-configuration.h"
36 #include "ns3/he-configuration.h"
37 #include "wifi-net-device.h"
38 
39 namespace ns3 {
40 
41 NS_LOG_COMPONENT_DEFINE ("WifiRemoteStationManager");
42 
43 NS_OBJECT_ENSURE_REGISTERED (WifiRemoteStationManager);
44 
45 TypeId
GetTypeId(void)46 WifiRemoteStationManager::GetTypeId (void)
47 {
48   static TypeId tid = TypeId ("ns3::WifiRemoteStationManager")
49     .SetParent<Object> ()
50     .SetGroupName ("Wifi")
51     .AddAttribute ("MaxSsrc",
52                    "The maximum number of retransmission attempts for any packet with size <= RtsCtsThreshold. "
53                    "This value will not have any effect on some rate control algorithms.",
54                    UintegerValue (7),
55                    MakeUintegerAccessor (&WifiRemoteStationManager::SetMaxSsrc),
56                    MakeUintegerChecker<uint32_t> ())
57     .AddAttribute ("MaxSlrc",
58                    "The maximum number of retransmission attempts for any packet with size > RtsCtsThreshold. "
59                    "This value will not have any effect on some rate control algorithms.",
60                    UintegerValue (4),
61                    MakeUintegerAccessor (&WifiRemoteStationManager::SetMaxSlrc),
62                    MakeUintegerChecker<uint32_t> ())
63     .AddAttribute ("RtsCtsThreshold",
64                    "If the size of the PSDU is bigger than this value, we use an RTS/CTS handshake before sending the data frame."
65                    "This value will not have any effect on some rate control algorithms.",
66                    UintegerValue (65535),
67                    MakeUintegerAccessor (&WifiRemoteStationManager::SetRtsCtsThreshold),
68                    MakeUintegerChecker<uint32_t> ())
69     .AddAttribute ("FragmentationThreshold",
70                    "If the size of the PSDU is bigger than this value, we fragment it such that the size of the fragments are equal or smaller. "
71                    "This value does not apply when it is carried in an A-MPDU. "
72                    "This value will not have any effect on some rate control algorithms.",
73                    UintegerValue (65535),
74                    MakeUintegerAccessor (&WifiRemoteStationManager::DoSetFragmentationThreshold,
75                                          &WifiRemoteStationManager::DoGetFragmentationThreshold),
76                    MakeUintegerChecker<uint32_t> ())
77     .AddAttribute ("NonUnicastMode",
78                    "Wifi mode used for non-unicast transmissions.",
79                    WifiModeValue (),
80                    MakeWifiModeAccessor (&WifiRemoteStationManager::m_nonUnicastMode),
81                    MakeWifiModeChecker ())
82     .AddAttribute ("DefaultTxPowerLevel",
83                    "Default power level to be used for transmissions. "
84                    "This is the power level that is used by all those WifiManagers that do not implement TX power control.",
85                    UintegerValue (0),
86                    MakeUintegerAccessor (&WifiRemoteStationManager::m_defaultTxPowerLevel),
87                    MakeUintegerChecker<uint8_t> ())
88     .AddAttribute ("ErpProtectionMode",
89                    "Protection mode used when non-ERP STAs are connected to an ERP AP: Rts-Cts or Cts-To-Self",
90                    EnumValue (WifiRemoteStationManager::CTS_TO_SELF),
91                    MakeEnumAccessor (&WifiRemoteStationManager::m_erpProtectionMode),
92                    MakeEnumChecker (WifiRemoteStationManager::RTS_CTS, "Rts-Cts",
93                                     WifiRemoteStationManager::CTS_TO_SELF, "Cts-To-Self"))
94     .AddAttribute ("HtProtectionMode",
95                    "Protection mode used when non-HT STAs are connected to a HT AP: Rts-Cts or Cts-To-Self",
96                    EnumValue (WifiRemoteStationManager::CTS_TO_SELF),
97                    MakeEnumAccessor (&WifiRemoteStationManager::m_htProtectionMode),
98                    MakeEnumChecker (WifiRemoteStationManager::RTS_CTS, "Rts-Cts",
99                                     WifiRemoteStationManager::CTS_TO_SELF, "Cts-To-Self"))
100     .AddTraceSource ("MacTxRtsFailed",
101                      "The transmission of a RTS by the MAC layer has failed",
102                      MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxRtsFailed),
103                      "ns3::Mac48Address::TracedCallback")
104     .AddTraceSource ("MacTxDataFailed",
105                      "The transmission of a data packet by the MAC layer has failed",
106                      MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxDataFailed),
107                      "ns3::Mac48Address::TracedCallback")
108     .AddTraceSource ("MacTxFinalRtsFailed",
109                      "The transmission of a RTS has exceeded the maximum number of attempts",
110                      MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxFinalRtsFailed),
111                      "ns3::Mac48Address::TracedCallback")
112     .AddTraceSource ("MacTxFinalDataFailed",
113                      "The transmission of a data packet has exceeded the maximum number of attempts",
114                      MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxFinalDataFailed),
115                      "ns3::Mac48Address::TracedCallback")
116   ;
117   return tid;
118 }
119 
WifiRemoteStationManager()120 WifiRemoteStationManager::WifiRemoteStationManager ()
121   : m_useNonErpProtection (false),
122     m_useNonHtProtection (false),
123     m_shortPreambleEnabled (false),
124     m_shortSlotTimeEnabled (false)
125 {
126   NS_LOG_FUNCTION (this);
127 }
128 
~WifiRemoteStationManager()129 WifiRemoteStationManager::~WifiRemoteStationManager ()
130 {
131   NS_LOG_FUNCTION (this);
132 }
133 
134 void
DoDispose(void)135 WifiRemoteStationManager::DoDispose (void)
136 {
137   NS_LOG_FUNCTION (this);
138   Reset ();
139 }
140 
141 void
SetupPhy(const Ptr<WifiPhy> phy)142 WifiRemoteStationManager::SetupPhy (const Ptr<WifiPhy> phy)
143 {
144   NS_LOG_FUNCTION (this << phy);
145   //We need to track our PHY because it is the object that knows the
146   //full set of transmit rates that are supported. We need to know
147   //this in order to find the relevant mandatory rates when choosing a
148   //transmit rate for automatic control responses like
149   //acknowledgments.
150   m_wifiPhy = phy;
151   m_defaultTxMode = phy->GetDefaultMode ();
152   NS_ASSERT (m_defaultTxMode.IsMandatory ());
153   if (GetHtSupported ())
154     {
155       m_defaultTxMcs = HtPhy::GetHtMcs (0);
156     }
157   Reset ();
158 }
159 
160 void
SetupMac(const Ptr<WifiMac> mac)161 WifiRemoteStationManager::SetupMac (const Ptr<WifiMac> mac)
162 {
163   NS_LOG_FUNCTION (this << mac);
164   //We need to track our MAC because it is the object that knows the
165   //full set of interframe spaces.
166   m_wifiMac = mac;
167   Reset ();
168 }
169 
170 int64_t
AssignStreams(int64_t stream)171 WifiRemoteStationManager::AssignStreams (int64_t stream)
172 {
173   NS_LOG_FUNCTION (this << stream);
174   return 0;
175 }
176 
177 void
SetMaxSsrc(uint32_t maxSsrc)178 WifiRemoteStationManager::SetMaxSsrc (uint32_t maxSsrc)
179 {
180   NS_LOG_FUNCTION (this << maxSsrc);
181   m_maxSsrc = maxSsrc;
182 }
183 
184 void
SetMaxSlrc(uint32_t maxSlrc)185 WifiRemoteStationManager::SetMaxSlrc (uint32_t maxSlrc)
186 {
187   NS_LOG_FUNCTION (this << maxSlrc);
188   m_maxSlrc = maxSlrc;
189 }
190 
191 void
SetRtsCtsThreshold(uint32_t threshold)192 WifiRemoteStationManager::SetRtsCtsThreshold (uint32_t threshold)
193 {
194   NS_LOG_FUNCTION (this << threshold);
195   m_rtsCtsThreshold = threshold;
196 }
197 
198 void
SetFragmentationThreshold(uint32_t threshold)199 WifiRemoteStationManager::SetFragmentationThreshold (uint32_t threshold)
200 {
201   NS_LOG_FUNCTION (this << threshold);
202   DoSetFragmentationThreshold (threshold);
203 }
204 
205 void
SetShortPreambleEnabled(bool enable)206 WifiRemoteStationManager::SetShortPreambleEnabled (bool enable)
207 {
208   NS_LOG_FUNCTION (this << enable);
209   m_shortPreambleEnabled = enable;
210 }
211 
212 void
SetShortSlotTimeEnabled(bool enable)213 WifiRemoteStationManager::SetShortSlotTimeEnabled (bool enable)
214 {
215   NS_LOG_FUNCTION (this << enable);
216   m_shortSlotTimeEnabled = enable;
217 }
218 
219 bool
GetShortSlotTimeEnabled(void) const220 WifiRemoteStationManager::GetShortSlotTimeEnabled (void) const
221 {
222   return m_shortSlotTimeEnabled;
223 }
224 
225 bool
GetShortPreambleEnabled(void) const226 WifiRemoteStationManager::GetShortPreambleEnabled (void) const
227 {
228   return m_shortPreambleEnabled;
229 }
230 
231 bool
GetHtSupported(void) const232 WifiRemoteStationManager::GetHtSupported (void) const
233 {
234   Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ());
235   Ptr<HtConfiguration> htConfiguration = device->GetHtConfiguration ();
236   if (htConfiguration)
237     {
238       return true;
239     }
240   return false;
241 }
242 
243 bool
GetVhtSupported(void) const244 WifiRemoteStationManager::GetVhtSupported (void) const
245 {
246   Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ());
247   Ptr<VhtConfiguration> vhtConfiguration = device->GetVhtConfiguration ();
248   if (vhtConfiguration)
249     {
250       return true;
251     }
252   return false;
253 }
254 
255 bool
GetHeSupported(void) const256 WifiRemoteStationManager::GetHeSupported (void) const
257 {
258   Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ());
259   Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration ();
260   if (heConfiguration)
261     {
262       return true;
263     }
264   return false;
265 }
266 
267 bool
GetLdpcSupported(void) const268 WifiRemoteStationManager::GetLdpcSupported (void) const
269 {
270   if (GetHtSupported ())
271     {
272       Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ());
273       Ptr<HtConfiguration> htConfiguration = device->GetHtConfiguration ();
274       NS_ASSERT (htConfiguration); //If HT is supported, we should have a HT configuration attached
275       return htConfiguration->GetLdpcSupported ();
276     }
277   return false;
278 }
279 
280 bool
GetShortGuardIntervalSupported(void) const281 WifiRemoteStationManager::GetShortGuardIntervalSupported (void) const
282 {
283   if (GetHtSupported ())
284     {
285       Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ());
286       Ptr<HtConfiguration> htConfiguration = device->GetHtConfiguration ();
287       NS_ASSERT (htConfiguration); //If HT is supported, we should have a HT configuration attached
288       if (htConfiguration->GetShortGuardIntervalSupported ())
289         {
290           return true;
291         }
292     }
293   return false;
294 }
295 
296 uint16_t
GetGuardInterval(void) const297 WifiRemoteStationManager::GetGuardInterval (void) const
298 {
299   uint16_t gi = 0;
300   if (GetHeSupported ())
301     {
302       Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ());
303       Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration ();
304       NS_ASSERT (heConfiguration); //If HE is supported, we should have a HE configuration attached
305       gi = static_cast<uint16_t>(heConfiguration->GetGuardInterval ().GetNanoSeconds ());
306     }
307   return gi;
308 }
309 
310 uint32_t
GetFragmentationThreshold(void) const311 WifiRemoteStationManager::GetFragmentationThreshold (void) const
312 {
313   return DoGetFragmentationThreshold ();
314 }
315 
316 void
AddSupportedPhyPreamble(Mac48Address address,bool isShortPreambleSupported)317 WifiRemoteStationManager::AddSupportedPhyPreamble (Mac48Address address, bool isShortPreambleSupported)
318 {
319   NS_LOG_FUNCTION (this << address << isShortPreambleSupported);
320   NS_ASSERT (!address.IsGroup ());
321   WifiRemoteStationState *state = LookupState (address);
322   state->m_shortPreamble = isShortPreambleSupported;
323 }
324 
325 void
AddSupportedErpSlotTime(Mac48Address address,bool isShortSlotTimeSupported)326 WifiRemoteStationManager::AddSupportedErpSlotTime (Mac48Address address, bool isShortSlotTimeSupported)
327 {
328   NS_LOG_FUNCTION (this << address << isShortSlotTimeSupported);
329   NS_ASSERT (!address.IsGroup ());
330   WifiRemoteStationState *state = LookupState (address);
331   state->m_shortSlotTime = isShortSlotTimeSupported;
332 }
333 
334 void
AddSupportedMode(Mac48Address address,WifiMode mode)335 WifiRemoteStationManager::AddSupportedMode (Mac48Address address, WifiMode mode)
336 {
337   NS_LOG_FUNCTION (this << address << mode);
338   NS_ASSERT (!address.IsGroup ());
339   WifiRemoteStationState *state = LookupState (address);
340   for (WifiModeListIterator i = state->m_operationalRateSet.begin (); i != state->m_operationalRateSet.end (); i++)
341     {
342       if ((*i) == mode)
343         {
344           //already in.
345           return;
346         }
347     }
348   if ((mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS) || (mode.GetModulationClass () == WIFI_MOD_CLASS_HR_DSSS))
349     {
350       state->m_dsssSupported = true;
351     }
352   else if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
353     {
354       state->m_erpOfdmSupported = true;
355     }
356   else if (mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM)
357     {
358       state->m_ofdmSupported = true;
359     }
360   state->m_operationalRateSet.push_back (mode);
361 }
362 
363 void
AddAllSupportedModes(Mac48Address address)364 WifiRemoteStationManager::AddAllSupportedModes (Mac48Address address)
365 {
366   NS_LOG_FUNCTION (this << address);
367   NS_ASSERT (!address.IsGroup ());
368   WifiRemoteStationState *state = LookupState (address);
369   state->m_operationalRateSet.clear ();
370   for (const auto & mode : m_wifiPhy->GetModeList ())
371     {
372       state->m_operationalRateSet.push_back (mode);
373       if (mode.IsMandatory ())
374         {
375           AddBasicMode (mode);
376         }
377     }
378 }
379 
380 void
AddAllSupportedMcs(Mac48Address address)381 WifiRemoteStationManager::AddAllSupportedMcs (Mac48Address address)
382 {
383   NS_LOG_FUNCTION (this << address);
384   NS_ASSERT (!address.IsGroup ());
385   WifiRemoteStationState *state = LookupState (address);
386   state->m_operationalMcsSet.clear ();
387   for (const auto & mcs : m_wifiPhy->GetMcsList ())
388     {
389       state->m_operationalMcsSet.push_back (mcs);
390     }
391 }
392 
393 void
RemoveAllSupportedMcs(Mac48Address address)394 WifiRemoteStationManager::RemoveAllSupportedMcs (Mac48Address address)
395 {
396   NS_LOG_FUNCTION (this << address);
397   NS_ASSERT (!address.IsGroup ());
398   WifiRemoteStationState *state = LookupState (address);
399   state->m_operationalMcsSet.clear ();
400 }
401 
402 void
AddSupportedMcs(Mac48Address address,WifiMode mcs)403 WifiRemoteStationManager::AddSupportedMcs (Mac48Address address, WifiMode mcs)
404 {
405   NS_LOG_FUNCTION (this << address << mcs);
406   NS_ASSERT (!address.IsGroup ());
407   WifiRemoteStationState *state = LookupState (address);
408   for (WifiModeListIterator i = state->m_operationalMcsSet.begin (); i != state->m_operationalMcsSet.end (); i++)
409     {
410       if ((*i) == mcs)
411         {
412           //already in.
413           return;
414         }
415     }
416   state->m_operationalMcsSet.push_back (mcs);
417 }
418 
419 bool
GetShortPreambleSupported(Mac48Address address) const420 WifiRemoteStationManager::GetShortPreambleSupported (Mac48Address address) const
421 {
422   return LookupState (address)->m_shortPreamble;
423 }
424 
425 bool
GetShortSlotTimeSupported(Mac48Address address) const426 WifiRemoteStationManager::GetShortSlotTimeSupported (Mac48Address address) const
427 {
428   return LookupState (address)->m_shortSlotTime;
429 }
430 
431 bool
GetQosSupported(Mac48Address address) const432 WifiRemoteStationManager::GetQosSupported (Mac48Address address) const
433 {
434   return LookupState (address)->m_qosSupported;
435 }
436 
437 bool
IsBrandNew(Mac48Address address) const438 WifiRemoteStationManager::IsBrandNew (Mac48Address address) const
439 {
440   if (address.IsGroup ())
441     {
442       return false;
443     }
444   return LookupState (address)->m_state == WifiRemoteStationState::BRAND_NEW;
445 }
446 
447 bool
IsAssociated(Mac48Address address) const448 WifiRemoteStationManager::IsAssociated (Mac48Address address) const
449 {
450   if (address.IsGroup ())
451     {
452       return true;
453     }
454   return LookupState (address)->m_state == WifiRemoteStationState::GOT_ASSOC_TX_OK;
455 }
456 
457 bool
IsWaitAssocTxOk(Mac48Address address) const458 WifiRemoteStationManager::IsWaitAssocTxOk (Mac48Address address) const
459 {
460   if (address.IsGroup ())
461     {
462       return false;
463     }
464   return LookupState (address)->m_state == WifiRemoteStationState::WAIT_ASSOC_TX_OK;
465 }
466 
467 void
RecordWaitAssocTxOk(Mac48Address address)468 WifiRemoteStationManager::RecordWaitAssocTxOk (Mac48Address address)
469 {
470   NS_ASSERT (!address.IsGroup ());
471   LookupState (address)->m_state = WifiRemoteStationState::WAIT_ASSOC_TX_OK;
472 }
473 
474 void
RecordGotAssocTxOk(Mac48Address address)475 WifiRemoteStationManager::RecordGotAssocTxOk (Mac48Address address)
476 {
477   NS_ASSERT (!address.IsGroup ());
478   LookupState (address)->m_state = WifiRemoteStationState::GOT_ASSOC_TX_OK;
479 }
480 
481 void
RecordGotAssocTxFailed(Mac48Address address)482 WifiRemoteStationManager::RecordGotAssocTxFailed (Mac48Address address)
483 {
484   NS_ASSERT (!address.IsGroup ());
485   LookupState (address)->m_state = WifiRemoteStationState::DISASSOC;
486 }
487 
488 void
RecordDisassociated(Mac48Address address)489 WifiRemoteStationManager::RecordDisassociated (Mac48Address address)
490 {
491   NS_ASSERT (!address.IsGroup ());
492   LookupState (address)->m_state = WifiRemoteStationState::DISASSOC;
493 }
494 
495 uint16_t
GetAssociationId(Mac48Address remoteAddress) const496 WifiRemoteStationManager::GetAssociationId (Mac48Address remoteAddress) const
497 {
498   WifiRemoteStationState* state;
499   if (!remoteAddress.IsGroup ()
500       && (state = LookupState (remoteAddress))->m_state == WifiRemoteStationState::GOT_ASSOC_TX_OK)
501     {
502       return state->m_aid;
503     }
504   return SU_STA_ID;
505 }
506 
507 uint16_t
GetStaId(Mac48Address address,const WifiTxVector & txVector) const508 WifiRemoteStationManager::GetStaId (Mac48Address address, const WifiTxVector& txVector) const
509 {
510   NS_LOG_FUNCTION (this << address << txVector);
511 
512   uint16_t staId = SU_STA_ID;
513 
514   if (txVector.IsMu ())
515     {
516       if (m_wifiMac->GetTypeOfStation () == AP)
517         {
518           staId = GetAssociationId (address);
519         }
520       else if (m_wifiMac->GetTypeOfStation () == STA)
521         {
522           Ptr<StaWifiMac> staMac = StaticCast<StaWifiMac> (m_wifiMac);
523           if (staMac->IsAssociated ())
524             {
525               staId = staMac->GetAssociationId ();
526             }
527         }
528     }
529 
530   NS_LOG_DEBUG ("Returning STAID = " << staId);
531   return staId;
532 }
533 
534 WifiTxVector
GetDataTxVector(const WifiMacHeader & header)535 WifiRemoteStationManager::GetDataTxVector (const WifiMacHeader &header)
536 {
537   NS_LOG_FUNCTION (this << header);
538   Mac48Address address = header.GetAddr1 ();
539   if (!header.IsMgt () && address.IsGroup ())
540     {
541       WifiMode mode = GetNonUnicastMode ();
542       WifiTxVector v;
543       v.SetMode (mode);
544       v.SetPreambleType (GetPreambleForTransmission (mode.GetModulationClass (), GetShortPreambleEnabled ()));
545       v.SetTxPowerLevel (m_defaultTxPowerLevel);
546       v.SetChannelWidth (GetChannelWidthForTransmission (mode, m_wifiPhy->GetChannelWidth ()));
547       v.SetGuardInterval (ConvertGuardIntervalToNanoSeconds (mode, DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ())));
548       v.SetNTx (GetNumberOfAntennas ());
549       v.SetNss (1);
550       v.SetNess (0);
551       return v;
552     }
553   WifiTxVector txVector;
554   if (header.IsMgt ())
555     {
556       //Use the lowest basic rate for management frames
557       WifiMode mgtMode;
558       if (GetNBasicModes () > 0)
559         {
560           mgtMode = GetBasicMode (0);
561         }
562       else
563         {
564           mgtMode = GetDefaultMode ();
565         }
566       txVector.SetMode (mgtMode);
567       txVector.SetPreambleType (GetPreambleForTransmission (mgtMode.GetModulationClass (), GetShortPreambleEnabled ()));
568       txVector.SetTxPowerLevel (m_defaultTxPowerLevel);
569       txVector.SetChannelWidth (GetChannelWidthForTransmission (mgtMode, m_wifiPhy->GetChannelWidth ()));
570       txVector.SetGuardInterval (ConvertGuardIntervalToNanoSeconds (mgtMode, DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ())));
571     }
572   else
573     {
574       txVector = DoGetDataTxVector (Lookup (address));
575       txVector.SetLdpc (txVector.GetMode ().GetModulationClass () < WIFI_MOD_CLASS_HT ? 0 : UseLdpcForDestination (address));
576     }
577   Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ());
578   Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration ();
579   if (heConfiguration)
580     {
581       txVector.SetBssColor (heConfiguration->GetBssColor ());
582     }
583   return txVector;
584 }
585 
586 WifiTxVector
GetCtsToSelfTxVector(void)587 WifiRemoteStationManager::GetCtsToSelfTxVector (void)
588 {
589   WifiMode defaultMode = GetDefaultMode ();
590   WifiPreamble defaultPreamble;
591   if (defaultMode.GetModulationClass () == WIFI_MOD_CLASS_HE)
592     {
593       defaultPreamble = WIFI_PREAMBLE_HE_SU;
594     }
595   else if (defaultMode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
596     {
597       defaultPreamble = WIFI_PREAMBLE_VHT_SU;
598     }
599   else if (defaultMode.GetModulationClass () == WIFI_MOD_CLASS_HT)
600     {
601       defaultPreamble = WIFI_PREAMBLE_HT_MF;
602     }
603   else
604     {
605       defaultPreamble = WIFI_PREAMBLE_LONG;
606     }
607 
608   return WifiTxVector (defaultMode,
609                        GetDefaultTxPowerLevel (),
610                        defaultPreamble,
611                        ConvertGuardIntervalToNanoSeconds (defaultMode, DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ())),
612                        GetNumberOfAntennas (),
613                        1,
614                        0,
615                        GetChannelWidthForTransmission (defaultMode, m_wifiPhy->GetChannelWidth ()),
616                        false);
617 }
618 
619 WifiTxVector
GetRtsTxVector(Mac48Address address)620 WifiRemoteStationManager::GetRtsTxVector (Mac48Address address)
621 {
622   NS_LOG_FUNCTION (this << address);
623   if (address.IsGroup ())
624     {
625         WifiMode mode = GetNonUnicastMode ();
626         WifiTxVector v;
627         v.SetMode (mode);
628         v.SetPreambleType (GetPreambleForTransmission (mode.GetModulationClass (), GetShortPreambleEnabled ()));
629         v.SetTxPowerLevel (m_defaultTxPowerLevel);
630         v.SetChannelWidth (GetChannelWidthForTransmission (mode, m_wifiPhy->GetChannelWidth ()));
631         v.SetGuardInterval (ConvertGuardIntervalToNanoSeconds (mode, DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ())));
632         v.SetNTx (GetNumberOfAntennas ());
633         v.SetNss (1);
634         v.SetNess (0);
635         return v;
636     }
637   return DoGetRtsTxVector (Lookup (address));
638 }
639 
640 WifiTxVector
GetCtsTxVector(Mac48Address to,WifiMode rtsTxMode) const641 WifiRemoteStationManager::GetCtsTxVector (Mac48Address to, WifiMode rtsTxMode) const
642 {
643   NS_ASSERT (!to.IsGroup ());
644   WifiMode ctsMode = GetControlAnswerMode (rtsTxMode);
645   WifiTxVector v;
646   v.SetMode (ctsMode);
647   v.SetPreambleType (GetPreambleForTransmission (ctsMode.GetModulationClass (), GetShortPreambleEnabled ()));
648   v.SetTxPowerLevel (GetDefaultTxPowerLevel ());
649   v.SetChannelWidth (GetChannelWidthForTransmission (ctsMode, m_wifiPhy->GetChannelWidth ()));
650   uint16_t ctsTxGuardInterval = ConvertGuardIntervalToNanoSeconds (ctsMode, DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ()));
651   v.SetGuardInterval (ctsTxGuardInterval);
652   v.SetNss (1);
653   return v;
654 }
655 
656 WifiTxVector
GetAckTxVector(Mac48Address to,const WifiTxVector & dataTxVector) const657 WifiRemoteStationManager::GetAckTxVector (Mac48Address to, const WifiTxVector& dataTxVector) const
658 {
659   NS_ASSERT (!to.IsGroup ());
660   WifiMode ackMode = GetControlAnswerMode (dataTxVector.GetMode (GetStaId (to, dataTxVector)));
661   WifiTxVector v;
662   v.SetMode (ackMode);
663   v.SetPreambleType (GetPreambleForTransmission (ackMode.GetModulationClass (), GetShortPreambleEnabled ()));
664   v.SetTxPowerLevel (GetDefaultTxPowerLevel ());
665   v.SetChannelWidth (GetChannelWidthForTransmission (ackMode, m_wifiPhy->GetChannelWidth ()));
666   uint16_t ackTxGuardInterval = ConvertGuardIntervalToNanoSeconds (ackMode, DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ()));
667   v.SetGuardInterval (ackTxGuardInterval);
668   v.SetNss (1);
669   return v;
670 }
671 
672 WifiTxVector
GetBlockAckTxVector(Mac48Address to,const WifiTxVector & dataTxVector) const673 WifiRemoteStationManager::GetBlockAckTxVector (Mac48Address to, const WifiTxVector& dataTxVector) const
674 {
675   NS_ASSERT (!to.IsGroup ());
676   WifiMode blockAckMode = GetControlAnswerMode (dataTxVector.GetMode (GetStaId (to, dataTxVector)));
677   WifiTxVector v;
678   v.SetMode (blockAckMode);
679   v.SetPreambleType (GetPreambleForTransmission (blockAckMode.GetModulationClass (), GetShortPreambleEnabled ()));
680   v.SetTxPowerLevel (GetDefaultTxPowerLevel ());
681   v.SetChannelWidth (GetChannelWidthForTransmission (blockAckMode, m_wifiPhy->GetChannelWidth ()));
682   uint16_t blockAckTxGuardInterval = ConvertGuardIntervalToNanoSeconds (blockAckMode, DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ()));
683   v.SetGuardInterval (blockAckTxGuardInterval);
684   v.SetNss (1);
685   return v;
686 }
687 
688 WifiMode
GetControlAnswerMode(WifiMode reqMode) const689 WifiRemoteStationManager::GetControlAnswerMode (WifiMode reqMode) const
690 {
691   /**
692    * The standard has relatively unambiguous rules for selecting a
693    * control response rate (the below is quoted from IEEE 802.11-2012,
694    * Section 9.7):
695    *
696    * To allow the transmitting STA to calculate the contents of the
697    * Duration/ID field, a STA responding to a received frame shall
698    * transmit its Control Response frame (either CTS or Ack), other
699    * than the BlockAck control frame, at the highest rate in the
700    * BSSBasicRateSet parameter that is less than or equal to the
701    * rate of the immediately previous frame in the frame exchange
702    * sequence (as defined in Annex G) and that is of the same
703    * modulation class (see Section 9.7.8) as the received frame...
704    */
705   NS_LOG_FUNCTION (this << reqMode);
706   WifiMode mode = GetDefaultMode ();
707   bool found = false;
708   //First, search the BSS Basic Rate set
709   for (uint8_t i = 0; i < GetNBasicModes (); i++)
710     {
711       WifiMode testMode = GetBasicMode (i);
712       if ((!found || testMode.IsHigherDataRate (mode))
713           && (!testMode.IsHigherDataRate (reqMode))
714           && (IsAllowedControlAnswerModulationClass (reqMode.GetModulationClass (), testMode.GetModulationClass ())))
715         {
716           mode = testMode;
717           //We've found a potentially-suitable transmit rate, but we
718           //need to continue and consider all the basic rates before
719           //we can be sure we've got the right one.
720           found = true;
721         }
722     }
723   if (GetHtSupported ())
724     {
725       if (!found)
726         {
727           mode = GetDefaultMcs ();
728           for (uint8_t i = 0; i != GetNBasicMcs (); i++)
729             {
730               WifiMode testMode = GetBasicMcs (i);
731               if ((!found || testMode.IsHigherDataRate (mode))
732                   && (!testMode.IsHigherDataRate (reqMode))
733                   && (testMode.GetModulationClass () == reqMode.GetModulationClass ()))
734                 {
735                   mode = testMode;
736                   //We've found a potentially-suitable transmit rate, but we
737                   //need to continue and consider all the basic rates before
738                   //we can be sure we've got the right one.
739                   found = true;
740                 }
741             }
742         }
743     }
744   //If we found a suitable rate in the BSSBasicRateSet, then we are
745   //done and can return that mode.
746   if (found)
747     {
748       NS_LOG_DEBUG ("WifiRemoteStationManager::GetControlAnswerMode returning " << mode);
749       return mode;
750     }
751 
752   /**
753    * If no suitable basic rate was found, we search the mandatory
754    * rates. The standard (IEEE 802.11-2007, Section 9.6) says:
755    *
756    *   ...If no rate contained in the BSSBasicRateSet parameter meets
757    *   these conditions, then the control frame sent in response to a
758    *   received frame shall be transmitted at the highest mandatory
759    *   rate of the PHY that is less than or equal to the rate of the
760    *   received frame, and that is of the same modulation class as the
761    *   received frame. In addition, the Control Response frame shall
762    *   be sent using the same PHY options as the received frame,
763    *   unless they conflict with the requirement to use the
764    *   BSSBasicRateSet parameter.
765    *
766    * \todo Note that we're ignoring the last sentence for now, because
767    * there is not yet any manipulation here of PHY options.
768    */
769   for (const auto & thismode : m_wifiPhy->GetModeList ())
770     {
771       /* If the rate:
772        *
773        *  - is a mandatory rate for the PHY, and
774        *  - is equal to or faster than our current best choice, and
775        *  - is less than or equal to the rate of the received frame, and
776        *  - is of the same modulation class as the received frame
777        *
778        * ...then it's our best choice so far.
779        */
780       if (thismode.IsMandatory ()
781           && (!found || thismode.IsHigherDataRate (mode))
782           && (!thismode.IsHigherDataRate (reqMode))
783           && (IsAllowedControlAnswerModulationClass (reqMode.GetModulationClass (), thismode.GetModulationClass ())))
784         {
785           mode = thismode;
786           //As above; we've found a potentially-suitable transmit
787           //rate, but we need to continue and consider all the
788           //mandatory rates before we can be sure we've got the right one.
789           found = true;
790         }
791     }
792   if (GetHtSupported () )
793     {
794       for (const auto & thismode : m_wifiPhy->GetMcsList ())
795         {
796           if (thismode.IsMandatory ()
797               && (!found || thismode.IsHigherDataRate (mode))
798               && (!thismode.IsHigherCodeRate (reqMode))
799               && (thismode.GetModulationClass () == reqMode.GetModulationClass ()))
800             {
801               mode = thismode;
802               //As above; we've found a potentially-suitable transmit
803               //rate, but we need to continue and consider all the
804               //mandatory rates before we can be sure we've got the right one.
805               found = true;
806             }
807         }
808     }
809 
810   /**
811    * If we still haven't found a suitable rate for the response then
812    * someone has messed up the simulation configuration. This probably means
813    * that the WifiPhyStandard is not set correctly, or that a rate that
814    * is not supported by the PHY has been explicitly requested.
815    *
816    * Either way, it is serious - we can either disobey the standard or
817    * fail, and I have chosen to do the latter...
818    */
819   if (!found)
820     {
821       NS_FATAL_ERROR ("Can't find response rate for " << reqMode);
822     }
823 
824   NS_LOG_DEBUG ("WifiRemoteStationManager::GetControlAnswerMode returning " << mode);
825   return mode;
826 }
827 
828 void
ReportRtsFailed(const WifiMacHeader & header)829 WifiRemoteStationManager::ReportRtsFailed (const WifiMacHeader& header)
830 {
831   NS_LOG_FUNCTION (this << header);
832   NS_ASSERT (!header.GetAddr1 ().IsGroup ());
833   AcIndex ac = QosUtilsMapTidToAc ((header.IsQosData ()) ? header.GetQosTid () : 0);
834   m_ssrc[ac]++;
835   m_macTxRtsFailed (header.GetAddr1 ());
836   DoReportRtsFailed (Lookup (header.GetAddr1 ()));
837 }
838 
839 void
ReportDataFailed(Ptr<const WifiMacQueueItem> mpdu)840 WifiRemoteStationManager::ReportDataFailed (Ptr<const WifiMacQueueItem> mpdu)
841 {
842   NS_LOG_FUNCTION (this << *mpdu);
843   NS_ASSERT (!mpdu->GetHeader ().GetAddr1 ().IsGroup ());
844   AcIndex ac = QosUtilsMapTidToAc ((mpdu->GetHeader ().IsQosData ()) ? mpdu->GetHeader ().GetQosTid () : 0);
845   bool longMpdu = (mpdu->GetSize () > m_rtsCtsThreshold);
846   if (longMpdu)
847     {
848       m_slrc[ac]++;
849     }
850   else
851     {
852       m_ssrc[ac]++;
853     }
854   m_macTxDataFailed (mpdu->GetHeader ().GetAddr1 ());
855   DoReportDataFailed (Lookup (mpdu->GetHeader ().GetAddr1 ()));
856 }
857 
858 void
ReportRtsOk(const WifiMacHeader & header,double ctsSnr,WifiMode ctsMode,double rtsSnr)859 WifiRemoteStationManager::ReportRtsOk (const WifiMacHeader& header,
860                                        double ctsSnr, WifiMode ctsMode, double rtsSnr)
861 {
862   NS_LOG_FUNCTION (this << header << ctsSnr << ctsMode << rtsSnr);
863   NS_ASSERT (!header.GetAddr1 ().IsGroup ());
864   WifiRemoteStation *station = Lookup (header.GetAddr1 ());
865   AcIndex ac = QosUtilsMapTidToAc ((header.IsQosData ()) ? header.GetQosTid () : 0);
866   station->m_state->m_info.NotifyTxSuccess (m_ssrc[ac]);
867   m_ssrc[ac] = 0;
868   DoReportRtsOk (station, ctsSnr, ctsMode, rtsSnr);
869 }
870 
871 void
ReportDataOk(Ptr<const WifiMacQueueItem> mpdu,double ackSnr,WifiMode ackMode,double dataSnr,WifiTxVector dataTxVector)872 WifiRemoteStationManager::ReportDataOk (Ptr<const WifiMacQueueItem> mpdu, double ackSnr,
873                                         WifiMode ackMode, double dataSnr, WifiTxVector dataTxVector)
874 {
875   NS_LOG_FUNCTION (this << *mpdu << ackSnr << ackMode << dataSnr << dataTxVector);
876   const WifiMacHeader& hdr = mpdu->GetHeader ();
877   NS_ASSERT (!hdr.GetAddr1 ().IsGroup ());
878   WifiRemoteStation *station = Lookup (hdr.GetAddr1 ());
879   AcIndex ac = QosUtilsMapTidToAc ((hdr.IsQosData ()) ? hdr.GetQosTid () : 0);
880   bool longMpdu = (mpdu->GetSize () > m_rtsCtsThreshold);
881   if (longMpdu)
882     {
883       station->m_state->m_info.NotifyTxSuccess (m_slrc[ac]);
884       m_slrc[ac] = 0;
885     }
886   else
887     {
888       station->m_state->m_info.NotifyTxSuccess (m_ssrc[ac]);
889       m_ssrc[ac] = 0;
890     }
891   DoReportDataOk (station, ackSnr, ackMode, dataSnr, dataTxVector.GetChannelWidth (),
892                   dataTxVector.GetNss (GetStaId (hdr.GetAddr1 (), dataTxVector)));
893 }
894 
895 void
ReportFinalRtsFailed(const WifiMacHeader & header)896 WifiRemoteStationManager::ReportFinalRtsFailed (const WifiMacHeader& header)
897 {
898   NS_LOG_FUNCTION (this << header);
899   NS_ASSERT (!header.GetAddr1 ().IsGroup ());
900   WifiRemoteStation *station = Lookup (header.GetAddr1 ());
901   AcIndex ac = QosUtilsMapTidToAc ((header.IsQosData ()) ? header.GetQosTid () : 0);
902   station->m_state->m_info.NotifyTxFailed ();
903   m_ssrc[ac] = 0;
904   m_macTxFinalRtsFailed (header.GetAddr1 ());
905   DoReportFinalRtsFailed (station);
906 }
907 
908 void
ReportFinalDataFailed(Ptr<const WifiMacQueueItem> mpdu)909 WifiRemoteStationManager::ReportFinalDataFailed (Ptr<const WifiMacQueueItem> mpdu)
910 {
911   NS_LOG_FUNCTION (this << *mpdu);
912   NS_ASSERT (!mpdu->GetHeader ().GetAddr1 ().IsGroup ());
913   WifiRemoteStation *station = Lookup (mpdu->GetHeader ().GetAddr1 ());
914   AcIndex ac = QosUtilsMapTidToAc ((mpdu->GetHeader ().IsQosData ()) ? mpdu->GetHeader ().GetQosTid () : 0);
915   station->m_state->m_info.NotifyTxFailed ();
916   bool longMpdu = (mpdu->GetSize () > m_rtsCtsThreshold);
917   if (longMpdu)
918     {
919       m_slrc[ac] = 0;
920     }
921   else
922     {
923       m_ssrc[ac] = 0;
924     }
925   m_macTxFinalDataFailed (mpdu->GetHeader ().GetAddr1 ());
926   DoReportFinalDataFailed (station);
927 }
928 
929 void
ReportRxOk(Mac48Address address,RxSignalInfo rxSignalInfo,WifiTxVector txVector)930 WifiRemoteStationManager::ReportRxOk (Mac48Address address, RxSignalInfo rxSignalInfo, WifiTxVector txVector)
931 {
932   NS_LOG_FUNCTION (this << address << rxSignalInfo << txVector);
933   if (address.IsGroup ())
934     {
935       return;
936     }
937   WifiRemoteStation *station = Lookup (address);
938   DoReportRxOk (station, rxSignalInfo.snr, txVector.GetMode (GetStaId (address, txVector)));
939   station->m_rssiAndUpdateTimePair = std::make_pair (rxSignalInfo.rssi, Simulator::Now ());
940 }
941 
942 void
ReportAmpduTxStatus(Mac48Address address,uint16_t nSuccessfulMpdus,uint16_t nFailedMpdus,double rxSnr,double dataSnr,WifiTxVector dataTxVector)943 WifiRemoteStationManager::ReportAmpduTxStatus (Mac48Address address,
944                                                uint16_t nSuccessfulMpdus, uint16_t nFailedMpdus,
945                                                double rxSnr, double dataSnr, WifiTxVector dataTxVector)
946 {
947   NS_LOG_FUNCTION (this << address << nSuccessfulMpdus << nFailedMpdus << rxSnr << dataSnr << dataTxVector);
948   NS_ASSERT (!address.IsGroup ());
949   for (uint8_t i = 0; i < nFailedMpdus; i++)
950     {
951       m_macTxDataFailed (address);
952     }
953   DoReportAmpduTxStatus (Lookup (address), nSuccessfulMpdus, nFailedMpdus, rxSnr, dataSnr, dataTxVector.GetChannelWidth (), dataTxVector.GetNss (GetStaId (address, dataTxVector)));
954 }
955 
956 bool
NeedRts(const WifiMacHeader & header,uint32_t size)957 WifiRemoteStationManager::NeedRts (const WifiMacHeader &header, uint32_t size)
958 {
959   NS_LOG_FUNCTION (this << header << size);
960   Mac48Address address = header.GetAddr1 ();
961   WifiTxVector txVector = GetDataTxVector (header);
962   WifiMode mode = txVector.GetMode ();
963   if (address.IsGroup ())
964     {
965       return false;
966     }
967   if (m_erpProtectionMode == RTS_CTS
968       && ((mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
969           || (mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
970           || (mode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
971           || (mode.GetModulationClass () == WIFI_MOD_CLASS_HE))
972       && m_useNonErpProtection)
973     {
974       NS_LOG_DEBUG ("WifiRemoteStationManager::NeedRTS returning true to protect non-ERP stations");
975       return true;
976     }
977   else if (m_htProtectionMode == RTS_CTS
978            && ((mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
979                || (mode.GetModulationClass () == WIFI_MOD_CLASS_VHT))
980            && m_useNonHtProtection
981            && !(m_erpProtectionMode != RTS_CTS && m_useNonErpProtection))
982     {
983       NS_LOG_DEBUG ("WifiRemoteStationManager::NeedRTS returning true to protect non-HT stations");
984       return true;
985     }
986   bool normally = (size > m_rtsCtsThreshold);
987   return DoNeedRts (Lookup (address), size, normally);
988 }
989 
990 bool
NeedCtsToSelf(WifiTxVector txVector)991 WifiRemoteStationManager::NeedCtsToSelf (WifiTxVector txVector)
992 {
993   WifiMode mode = txVector.GetMode ();
994   NS_LOG_FUNCTION (this << mode);
995   if (m_erpProtectionMode == CTS_TO_SELF
996       && ((mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
997           || (mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
998           || (mode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
999           || (mode.GetModulationClass () == WIFI_MOD_CLASS_HE))
1000       && m_useNonErpProtection)
1001     {
1002       NS_LOG_DEBUG ("WifiRemoteStationManager::NeedCtsToSelf returning true to protect non-ERP stations");
1003       return true;
1004     }
1005   else if (m_htProtectionMode == CTS_TO_SELF
1006            && ((mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
1007                || (mode.GetModulationClass () == WIFI_MOD_CLASS_VHT))
1008            && m_useNonHtProtection
1009            && !(m_erpProtectionMode != CTS_TO_SELF && m_useNonErpProtection))
1010     {
1011       NS_LOG_DEBUG ("WifiRemoteStationManager::NeedCtsToSelf returning true to protect non-HT stations");
1012       return true;
1013     }
1014   else if (!m_useNonErpProtection)
1015     {
1016       //search for the BSS Basic Rate set, if the used mode is in the basic set then there is no need for CTS To Self
1017       for (WifiModeListIterator i = m_bssBasicRateSet.begin (); i != m_bssBasicRateSet.end (); i++)
1018         {
1019           if (mode == *i)
1020             {
1021               NS_LOG_DEBUG ("WifiRemoteStationManager::NeedCtsToSelf returning false");
1022               return false;
1023             }
1024         }
1025       if (GetHtSupported ())
1026         {
1027           //search for the BSS Basic MCS set, if the used mode is in the basic set then there is no need for CTS To Self
1028           for (WifiModeListIterator i = m_bssBasicMcsSet.begin (); i != m_bssBasicMcsSet.end (); i++)
1029             {
1030               if (mode == *i)
1031                 {
1032                   NS_LOG_DEBUG ("WifiRemoteStationManager::NeedCtsToSelf returning false");
1033                   return false;
1034                 }
1035             }
1036         }
1037       NS_LOG_DEBUG ("WifiRemoteStationManager::NeedCtsToSelf returning true");
1038       return true;
1039     }
1040   return false;
1041 }
1042 
1043 void
SetUseNonErpProtection(bool enable)1044 WifiRemoteStationManager::SetUseNonErpProtection (bool enable)
1045 {
1046   NS_LOG_FUNCTION (this << enable);
1047   m_useNonErpProtection = enable;
1048 }
1049 
1050 bool
GetUseNonErpProtection(void) const1051 WifiRemoteStationManager::GetUseNonErpProtection (void) const
1052 {
1053   return m_useNonErpProtection;
1054 }
1055 
1056 void
SetUseNonHtProtection(bool enable)1057 WifiRemoteStationManager::SetUseNonHtProtection (bool enable)
1058 {
1059   NS_LOG_FUNCTION (this << enable);
1060   m_useNonHtProtection = enable;
1061 }
1062 
1063 bool
GetUseNonHtProtection(void) const1064 WifiRemoteStationManager::GetUseNonHtProtection (void) const
1065 {
1066   return m_useNonHtProtection;
1067 }
1068 
1069 bool
NeedRetransmission(Ptr<const WifiMacQueueItem> mpdu)1070 WifiRemoteStationManager::NeedRetransmission (Ptr<const WifiMacQueueItem> mpdu)
1071 {
1072   NS_LOG_FUNCTION (this << *mpdu);
1073   NS_ASSERT (!mpdu->GetHeader ().GetAddr1 ().IsGroup ());
1074   AcIndex ac = QosUtilsMapTidToAc ((mpdu->GetHeader ().IsQosData ()) ? mpdu->GetHeader ().GetQosTid () : 0);
1075   bool longMpdu = (mpdu->GetSize () > m_rtsCtsThreshold);
1076   uint32_t retryCount, maxRetryCount;
1077   if (longMpdu)
1078     {
1079       retryCount = m_slrc[ac];
1080       maxRetryCount = m_maxSlrc;
1081     }
1082   else
1083     {
1084       retryCount = m_ssrc[ac];
1085       maxRetryCount = m_maxSsrc;
1086     }
1087   bool normally = retryCount < maxRetryCount;
1088   NS_LOG_DEBUG ("WifiRemoteStationManager::NeedRetransmission count: " << retryCount << " result: " << std::boolalpha << normally);
1089   return DoNeedRetransmission (Lookup (mpdu->GetHeader ().GetAddr1 ()), mpdu->GetPacket (), normally);
1090 }
1091 
1092 bool
NeedFragmentation(Ptr<const WifiMacQueueItem> mpdu)1093 WifiRemoteStationManager::NeedFragmentation (Ptr<const WifiMacQueueItem> mpdu)
1094 {
1095   NS_LOG_FUNCTION (this << *mpdu);
1096   if (mpdu->GetHeader ().GetAddr1 ().IsGroup ())
1097     {
1098       return false;
1099     }
1100   bool normally = mpdu->GetSize () > GetFragmentationThreshold ();
1101   NS_LOG_DEBUG ("WifiRemoteStationManager::NeedFragmentation result: " << std::boolalpha << normally);
1102   return DoNeedFragmentation (Lookup (mpdu->GetHeader ().GetAddr1 ()), mpdu->GetPacket (), normally);
1103 }
1104 
1105 void
DoSetFragmentationThreshold(uint32_t threshold)1106 WifiRemoteStationManager::DoSetFragmentationThreshold (uint32_t threshold)
1107 {
1108   NS_LOG_FUNCTION (this << threshold);
1109   if (threshold < 256)
1110     {
1111       /*
1112        * ASN.1 encoding of the MAC and PHY MIB (256 ... 8000)
1113        */
1114       NS_LOG_WARN ("Fragmentation threshold should be larger than 256. Setting to 256.");
1115       m_fragmentationThreshold = 256;
1116     }
1117   else
1118     {
1119       /*
1120        * The length of each fragment shall be an even number of octets, except for the last fragment if an MSDU or
1121        * MMPDU, which may be either an even or an odd number of octets.
1122        */
1123       if (threshold % 2 != 0)
1124         {
1125           NS_LOG_WARN ("Fragmentation threshold should be an even number. Setting to " << threshold - 1);
1126           m_fragmentationThreshold = threshold - 1;
1127         }
1128       else
1129         {
1130           m_fragmentationThreshold = threshold;
1131         }
1132     }
1133 }
1134 
1135 uint32_t
DoGetFragmentationThreshold(void) const1136 WifiRemoteStationManager::DoGetFragmentationThreshold (void) const
1137 {
1138   return m_fragmentationThreshold;
1139 }
1140 
1141 uint32_t
GetNFragments(Ptr<const WifiMacQueueItem> mpdu)1142 WifiRemoteStationManager::GetNFragments (Ptr<const WifiMacQueueItem> mpdu)
1143 {
1144   NS_LOG_FUNCTION (this << *mpdu);
1145   //The number of bytes a fragment can support is (Threshold - WIFI_HEADER_SIZE - WIFI_FCS).
1146   uint32_t nFragments = (mpdu->GetPacket ()->GetSize () / (GetFragmentationThreshold () - mpdu->GetHeader ().GetSize () - WIFI_MAC_FCS_LENGTH));
1147 
1148   //If the size of the last fragment is not 0.
1149   if ((mpdu->GetPacket ()->GetSize () % (GetFragmentationThreshold () - mpdu->GetHeader ().GetSize () - WIFI_MAC_FCS_LENGTH)) > 0)
1150     {
1151       nFragments++;
1152     }
1153   NS_LOG_DEBUG ("WifiRemoteStationManager::GetNFragments returning " << nFragments);
1154   return nFragments;
1155 }
1156 
1157 uint32_t
GetFragmentSize(Ptr<const WifiMacQueueItem> mpdu,uint32_t fragmentNumber)1158 WifiRemoteStationManager::GetFragmentSize (Ptr<const WifiMacQueueItem> mpdu, uint32_t fragmentNumber)
1159 {
1160   NS_LOG_FUNCTION (this << *mpdu << fragmentNumber);
1161   NS_ASSERT (!mpdu->GetHeader ().GetAddr1 ().IsGroup ());
1162   uint32_t nFragment = GetNFragments (mpdu);
1163   if (fragmentNumber >= nFragment)
1164     {
1165       NS_LOG_DEBUG ("WifiRemoteStationManager::GetFragmentSize returning 0");
1166       return 0;
1167     }
1168   //Last fragment
1169   if (fragmentNumber == nFragment - 1)
1170     {
1171       uint32_t lastFragmentSize = mpdu->GetPacket ()->GetSize () - (fragmentNumber * (GetFragmentationThreshold () - mpdu->GetHeader ().GetSize () - WIFI_MAC_FCS_LENGTH));
1172       NS_LOG_DEBUG ("WifiRemoteStationManager::GetFragmentSize returning " << lastFragmentSize);
1173       return lastFragmentSize;
1174     }
1175   //All fragments but the last, the number of bytes is (Threshold - WIFI_HEADER_SIZE - WIFI_FCS).
1176   else
1177     {
1178       uint32_t fragmentSize = GetFragmentationThreshold () - mpdu->GetHeader ().GetSize () - WIFI_MAC_FCS_LENGTH;
1179       NS_LOG_DEBUG ("WifiRemoteStationManager::GetFragmentSize returning " << fragmentSize);
1180       return fragmentSize;
1181     }
1182 }
1183 
1184 uint32_t
GetFragmentOffset(Ptr<const WifiMacQueueItem> mpdu,uint32_t fragmentNumber)1185 WifiRemoteStationManager::GetFragmentOffset (Ptr<const WifiMacQueueItem> mpdu, uint32_t fragmentNumber)
1186 {
1187   NS_LOG_FUNCTION (this << *mpdu << fragmentNumber);
1188   NS_ASSERT (!mpdu->GetHeader ().GetAddr1 ().IsGroup ());
1189   NS_ASSERT (fragmentNumber < GetNFragments (mpdu));
1190   uint32_t fragmentOffset = fragmentNumber * (GetFragmentationThreshold () - mpdu->GetHeader ().GetSize () - WIFI_MAC_FCS_LENGTH);
1191   NS_LOG_DEBUG ("WifiRemoteStationManager::GetFragmentOffset returning " << fragmentOffset);
1192   return fragmentOffset;
1193 }
1194 
1195 bool
IsLastFragment(Ptr<const WifiMacQueueItem> mpdu,uint32_t fragmentNumber)1196 WifiRemoteStationManager::IsLastFragment (Ptr<const WifiMacQueueItem> mpdu, uint32_t fragmentNumber)
1197 {
1198   NS_LOG_FUNCTION (this << *mpdu << fragmentNumber);
1199   NS_ASSERT (!mpdu->GetHeader ().GetAddr1 ().IsGroup ());
1200   bool isLast = fragmentNumber == (GetNFragments (mpdu) - 1);
1201   NS_LOG_DEBUG ("WifiRemoteStationManager::IsLastFragment returning " << std::boolalpha << isLast);
1202   return isLast;
1203 }
1204 
1205 uint8_t
GetDefaultTxPowerLevel(void) const1206 WifiRemoteStationManager::GetDefaultTxPowerLevel (void) const
1207 {
1208   return m_defaultTxPowerLevel;
1209 }
1210 
1211 WifiRemoteStationInfo
GetInfo(Mac48Address address)1212 WifiRemoteStationManager::GetInfo (Mac48Address address)
1213 {
1214   WifiRemoteStationState *state = LookupState (address);
1215   return state->m_info;
1216 }
1217 
1218 double
GetMostRecentRssi(Mac48Address address) const1219 WifiRemoteStationManager::GetMostRecentRssi (Mac48Address address) const
1220 {
1221   auto stationIt = m_stations.find (address);
1222   NS_ASSERT_MSG (stationIt != m_stations.end(), "Address: " << address << " not found");
1223   auto station = stationIt->second;
1224   auto rssi = station->m_rssiAndUpdateTimePair.first;
1225   auto ts = station->m_rssiAndUpdateTimePair.second;
1226   NS_ASSERT_MSG (ts.IsStrictlyPositive(), "address: " << address << " ts:" << ts);
1227   return rssi;
1228 }
1229 
1230 WifiRemoteStationState *
LookupState(Mac48Address address) const1231 WifiRemoteStationManager::LookupState (Mac48Address address) const
1232 {
1233   NS_LOG_FUNCTION (this << address);
1234   auto stateIt = m_states.find (address);
1235 
1236   if (stateIt != m_states.end ())
1237     {
1238       NS_LOG_DEBUG ("WifiRemoteStationManager::LookupState returning existing state");
1239       return stateIt->second;
1240     }
1241 
1242   WifiRemoteStationState *state = new WifiRemoteStationState ();
1243   state->m_state = WifiRemoteStationState::BRAND_NEW;
1244   state->m_address = address;
1245   state->m_aid = 0;
1246   state->m_operationalRateSet.push_back (GetDefaultMode ());
1247   state->m_operationalMcsSet.push_back (GetDefaultMcs ());
1248   state->m_dsssSupported = false;
1249   state->m_erpOfdmSupported = false;
1250   state->m_ofdmSupported = false;
1251   state->m_htCapabilities = 0;
1252   state->m_vhtCapabilities = 0;
1253   state->m_heCapabilities = 0;
1254   state->m_channelWidth = m_wifiPhy->GetChannelWidth ();
1255   state->m_guardInterval = GetGuardInterval ();
1256   state->m_ness = 0;
1257   state->m_aggregation = false;
1258   state->m_qosSupported = false;
1259   const_cast<WifiRemoteStationManager *> (this)->m_states.insert ({address, state});
1260   NS_LOG_DEBUG ("WifiRemoteStationManager::LookupState returning new state");
1261   return state;
1262 }
1263 
1264 WifiRemoteStation *
Lookup(Mac48Address address) const1265 WifiRemoteStationManager::Lookup (Mac48Address address) const
1266 {
1267   NS_LOG_FUNCTION (this << address);
1268   auto stationIt = m_stations.find (address);
1269 
1270   if (stationIt != m_stations.end ())
1271     {
1272       return stationIt->second;
1273     }
1274 
1275   WifiRemoteStationState *state = LookupState (address);
1276 
1277   WifiRemoteStation *station = DoCreateStation ();
1278   station->m_state = state;
1279   station->m_rssiAndUpdateTimePair = std::make_pair (0, Seconds (0));
1280   const_cast<WifiRemoteStationManager *> (this)->m_stations.insert ({address, station});
1281   return station;
1282 }
1283 
1284 void
SetAssociationId(Mac48Address remoteAddress,uint16_t aid)1285 WifiRemoteStationManager::SetAssociationId (Mac48Address remoteAddress, uint16_t aid)
1286 {
1287   NS_LOG_FUNCTION (this << remoteAddress << aid);
1288   LookupState (remoteAddress)->m_aid = aid;
1289 }
1290 
1291 void
SetQosSupport(Mac48Address from,bool qosSupported)1292 WifiRemoteStationManager::SetQosSupport (Mac48Address from, bool qosSupported)
1293 {
1294   NS_LOG_FUNCTION (this << from << qosSupported);
1295   WifiRemoteStationState *state;
1296   state = LookupState (from);
1297   state->m_qosSupported = qosSupported;
1298 }
1299 
1300 void
AddStationHtCapabilities(Mac48Address from,HtCapabilities htCapabilities)1301 WifiRemoteStationManager::AddStationHtCapabilities (Mac48Address from, HtCapabilities htCapabilities)
1302 {
1303   //Used by all stations to record HT capabilities of remote stations
1304   NS_LOG_FUNCTION (this << from << htCapabilities);
1305   WifiRemoteStationState *state;
1306   state = LookupState (from);
1307   if (htCapabilities.GetSupportedChannelWidth () == 1)
1308     {
1309       state->m_channelWidth = 40;
1310     }
1311   else
1312     {
1313       state->m_channelWidth = 20;
1314     }
1315   SetQosSupport (from, true);
1316   for (const auto & mcs : m_wifiPhy->GetMcsList (WIFI_MOD_CLASS_HT))
1317     {
1318       if (htCapabilities.IsSupportedMcs (mcs.GetMcsValue ()))
1319         {
1320           AddSupportedMcs (from, mcs);
1321         }
1322     }
1323   state->m_htCapabilities = Create<const HtCapabilities> (htCapabilities);
1324 }
1325 
1326 void
AddStationVhtCapabilities(Mac48Address from,VhtCapabilities vhtCapabilities)1327 WifiRemoteStationManager::AddStationVhtCapabilities (Mac48Address from, VhtCapabilities vhtCapabilities)
1328 {
1329   //Used by all stations to record VHT capabilities of remote stations
1330   NS_LOG_FUNCTION (this << from << vhtCapabilities);
1331   WifiRemoteStationState *state;
1332   state = LookupState (from);
1333   if (vhtCapabilities.GetSupportedChannelWidthSet () == 1)
1334     {
1335       state->m_channelWidth = 160;
1336     }
1337   else
1338     {
1339       state->m_channelWidth = 80;
1340     }
1341   //This is a workaround to enable users to force a 20 or 40 MHz channel for a VHT-compliant device,
1342   //since IEEE 802.11ac standard says that 20, 40 and 80 MHz channels are mandatory.
1343   if (m_wifiPhy->GetChannelWidth () < state->m_channelWidth)
1344     {
1345       state->m_channelWidth = m_wifiPhy->GetChannelWidth ();
1346     }
1347   for (uint8_t i = 1; i <= m_wifiPhy->GetMaxSupportedTxSpatialStreams (); i++)
1348     {
1349       for (const auto & mcs : m_wifiPhy->GetMcsList (WIFI_MOD_CLASS_VHT))
1350         {
1351           if (vhtCapabilities.IsSupportedMcs (mcs.GetMcsValue (), i))
1352             {
1353               AddSupportedMcs (from, mcs);
1354             }
1355         }
1356     }
1357   state->m_vhtCapabilities = Create<const VhtCapabilities> (vhtCapabilities);
1358 }
1359 
1360 void
AddStationHeCapabilities(Mac48Address from,HeCapabilities heCapabilities)1361 WifiRemoteStationManager::AddStationHeCapabilities (Mac48Address from, HeCapabilities heCapabilities)
1362 {
1363   //Used by all stations to record HE capabilities of remote stations
1364   NS_LOG_FUNCTION (this << from << heCapabilities);
1365   WifiRemoteStationState *state;
1366   state = LookupState (from);
1367   if ((m_wifiPhy->GetPhyBand () == WIFI_PHY_BAND_5GHZ) || (m_wifiPhy->GetPhyBand () == WIFI_PHY_BAND_6GHZ))
1368     {
1369       if (heCapabilities.GetChannelWidthSet () & 0x04)
1370         {
1371           state->m_channelWidth = 160;
1372         }
1373       else if (heCapabilities.GetChannelWidthSet () & 0x02)
1374         {
1375           state->m_channelWidth = 80;
1376         }
1377       //For other cases at 5 GHz, the supported channel width is set by the VHT capabilities
1378     }
1379   else if (m_wifiPhy->GetPhyBand () == WIFI_PHY_BAND_2_4GHZ)
1380     {
1381       if (heCapabilities.GetChannelWidthSet () & 0x01)
1382         {
1383           state->m_channelWidth = 40;
1384         }
1385       else
1386         {
1387           state->m_channelWidth = 20;
1388         }
1389     }
1390   if (heCapabilities.GetHeLtfAndGiForHePpdus () >= 2)
1391     {
1392       state->m_guardInterval = 800;
1393     }
1394   else if (heCapabilities.GetHeLtfAndGiForHePpdus () == 1)
1395     {
1396       state->m_guardInterval = 1600;
1397     }
1398   else
1399     {
1400       state->m_guardInterval = 3200;
1401     }
1402   for (uint8_t i = 1; i <= m_wifiPhy->GetMaxSupportedTxSpatialStreams (); i++)
1403     {
1404       for (const auto & mcs : m_wifiPhy->GetMcsList (WIFI_MOD_CLASS_HE))
1405         {
1406           if (heCapabilities.GetHighestNssSupported () >= i
1407               && heCapabilities.GetHighestMcsSupported () >= mcs.GetMcsValue ())
1408             {
1409               AddSupportedMcs (from, mcs);
1410             }
1411         }
1412     }
1413   state->m_heCapabilities = Create<const HeCapabilities> (heCapabilities);
1414   SetQosSupport (from, true);
1415 }
1416 
1417 Ptr<const HtCapabilities>
GetStationHtCapabilities(Mac48Address from)1418 WifiRemoteStationManager::GetStationHtCapabilities (Mac48Address from)
1419 {
1420   return LookupState (from)->m_htCapabilities;
1421 }
1422 
1423 Ptr<const VhtCapabilities>
GetStationVhtCapabilities(Mac48Address from)1424 WifiRemoteStationManager::GetStationVhtCapabilities (Mac48Address from)
1425 {
1426   return LookupState (from)->m_vhtCapabilities;
1427 }
1428 
1429 Ptr<const HeCapabilities>
GetStationHeCapabilities(Mac48Address from)1430 WifiRemoteStationManager::GetStationHeCapabilities (Mac48Address from)
1431 {
1432   return LookupState (from)->m_heCapabilities;
1433 }
1434 
1435 bool
GetLdpcSupported(Mac48Address address) const1436 WifiRemoteStationManager::GetLdpcSupported (Mac48Address address) const
1437 {
1438   Ptr<const HtCapabilities> htCapabilities = LookupState (address)->m_htCapabilities;
1439   Ptr<const VhtCapabilities> vhtCapabilities = LookupState (address)->m_vhtCapabilities;
1440   Ptr<const HeCapabilities> heCapabilities = LookupState (address)->m_heCapabilities;
1441   bool supported = false;
1442   if (htCapabilities)
1443     {
1444       supported |= htCapabilities->GetLdpc ();
1445     }
1446   if (vhtCapabilities)
1447     {
1448       supported |= vhtCapabilities->GetRxLdpc ();
1449     }
1450   if (heCapabilities)
1451     {
1452       supported |= heCapabilities->GetLdpcCodingInPayload ();
1453     }
1454   return supported;
1455 }
1456 
1457 WifiMode
GetDefaultMode(void) const1458 WifiRemoteStationManager::GetDefaultMode (void) const
1459 {
1460   return m_defaultTxMode;
1461 }
1462 
1463 WifiMode
GetDefaultMcs(void) const1464 WifiRemoteStationManager::GetDefaultMcs (void) const
1465 {
1466   return m_defaultTxMcs;
1467 }
1468 
1469 void
Reset(void)1470 WifiRemoteStationManager::Reset (void)
1471 {
1472   NS_LOG_FUNCTION (this);
1473   for (auto& state : m_states)
1474     {
1475       delete (state.second);
1476     }
1477   m_states.clear ();
1478   for (auto& state: m_stations)
1479     {
1480       delete (state.second);
1481     }
1482   m_stations.clear ();
1483   m_bssBasicRateSet.clear ();
1484   m_bssBasicMcsSet.clear ();
1485   m_ssrc.fill (0);
1486   m_slrc.fill (0);
1487 }
1488 
1489 void
AddBasicMode(WifiMode mode)1490 WifiRemoteStationManager::AddBasicMode (WifiMode mode)
1491 {
1492   NS_LOG_FUNCTION (this << mode);
1493   if (mode.GetModulationClass () >= WIFI_MOD_CLASS_HT)
1494     {
1495       NS_FATAL_ERROR ("It is not allowed to add a HT rate in the BSSBasicRateSet!");
1496     }
1497   for (uint8_t i = 0; i < GetNBasicModes (); i++)
1498     {
1499       if (GetBasicMode (i) == mode)
1500         {
1501           return;
1502         }
1503     }
1504   m_bssBasicRateSet.push_back (mode);
1505 }
1506 
1507 uint8_t
GetNBasicModes(void) const1508 WifiRemoteStationManager::GetNBasicModes (void) const
1509 {
1510   return static_cast<uint8_t> (m_bssBasicRateSet.size ());
1511 }
1512 
1513 WifiMode
GetBasicMode(uint8_t i) const1514 WifiRemoteStationManager::GetBasicMode (uint8_t i) const
1515 {
1516   NS_ASSERT (i < GetNBasicModes ());
1517   return m_bssBasicRateSet[i];
1518 }
1519 
1520 uint32_t
GetNNonErpBasicModes(void) const1521 WifiRemoteStationManager::GetNNonErpBasicModes (void) const
1522 {
1523   uint32_t size = 0;
1524   for (WifiModeListIterator i = m_bssBasicRateSet.begin (); i != m_bssBasicRateSet.end (); i++)
1525     {
1526       if (i->GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
1527         {
1528           continue;
1529         }
1530       size++;
1531     }
1532   return size;
1533 }
1534 
1535 WifiMode
GetNonErpBasicMode(uint8_t i) const1536 WifiRemoteStationManager::GetNonErpBasicMode (uint8_t i) const
1537 {
1538   NS_ASSERT (i < GetNNonErpBasicModes ());
1539   uint32_t index = 0;
1540   bool found = false;
1541   for (WifiModeListIterator j = m_bssBasicRateSet.begin (); j != m_bssBasicRateSet.end (); )
1542     {
1543       if (i == index)
1544         {
1545           found = true;
1546         }
1547       if (j->GetModulationClass () != WIFI_MOD_CLASS_ERP_OFDM)
1548         {
1549           if (found)
1550             {
1551               break;
1552             }
1553         }
1554       index++;
1555       j++;
1556     }
1557   return m_bssBasicRateSet[index];
1558 }
1559 
1560 void
AddBasicMcs(WifiMode mcs)1561 WifiRemoteStationManager::AddBasicMcs (WifiMode mcs)
1562 {
1563   NS_LOG_FUNCTION (this << +mcs.GetMcsValue ());
1564   for (uint8_t i = 0; i < GetNBasicMcs (); i++)
1565     {
1566       if (GetBasicMcs (i) == mcs)
1567         {
1568           return;
1569         }
1570     }
1571   m_bssBasicMcsSet.push_back (mcs);
1572 }
1573 
1574 uint8_t
GetNBasicMcs(void) const1575 WifiRemoteStationManager::GetNBasicMcs (void) const
1576 {
1577   return static_cast<uint8_t> (m_bssBasicMcsSet.size ());
1578 }
1579 
1580 WifiMode
GetBasicMcs(uint8_t i) const1581 WifiRemoteStationManager::GetBasicMcs (uint8_t i) const
1582 {
1583   NS_ASSERT (i < GetNBasicMcs ());
1584   return m_bssBasicMcsSet[i];
1585 }
1586 
1587 WifiMode
GetNonUnicastMode(void) const1588 WifiRemoteStationManager::GetNonUnicastMode (void) const
1589 {
1590   if (m_nonUnicastMode == WifiMode ())
1591     {
1592       if (GetNBasicModes () > 0)
1593         {
1594           return GetBasicMode (0);
1595         }
1596       else
1597         {
1598           return GetDefaultMode ();
1599         }
1600     }
1601   else
1602     {
1603       return m_nonUnicastMode;
1604     }
1605 }
1606 
1607 bool
DoNeedRts(WifiRemoteStation * station,uint32_t size,bool normally)1608 WifiRemoteStationManager::DoNeedRts (WifiRemoteStation *station,
1609                                      uint32_t size, bool normally)
1610 {
1611   return normally;
1612 }
1613 
1614 bool
DoNeedRetransmission(WifiRemoteStation * station,Ptr<const Packet> packet,bool normally)1615 WifiRemoteStationManager::DoNeedRetransmission (WifiRemoteStation *station,
1616                                                 Ptr<const Packet> packet, bool normally)
1617 {
1618   return normally;
1619 }
1620 
1621 bool
DoNeedFragmentation(WifiRemoteStation * station,Ptr<const Packet> packet,bool normally)1622 WifiRemoteStationManager::DoNeedFragmentation (WifiRemoteStation *station,
1623                                                Ptr<const Packet> packet, bool normally)
1624 {
1625   return normally;
1626 }
1627 
1628 void
DoReportAmpduTxStatus(WifiRemoteStation * station,uint16_t nSuccessfulMpdus,uint16_t nFailedMpdus,double rxSnr,double dataSnr,uint16_t dataChannelWidth,uint8_t dataNss)1629 WifiRemoteStationManager::DoReportAmpduTxStatus (WifiRemoteStation *station, uint16_t nSuccessfulMpdus, uint16_t nFailedMpdus, double rxSnr, double dataSnr, uint16_t dataChannelWidth, uint8_t dataNss)
1630 {
1631   NS_LOG_DEBUG ("DoReportAmpduTxStatus received but the manager does not handle A-MPDUs!");
1632 }
1633 
1634 WifiMode
GetSupported(const WifiRemoteStation * station,uint8_t i) const1635 WifiRemoteStationManager::GetSupported (const WifiRemoteStation *station, uint8_t i) const
1636 {
1637   NS_ASSERT (i < GetNSupported (station));
1638   return station->m_state->m_operationalRateSet[i];
1639 }
1640 
1641 WifiMode
GetMcsSupported(const WifiRemoteStation * station,uint8_t i) const1642 WifiRemoteStationManager::GetMcsSupported (const WifiRemoteStation *station, uint8_t i) const
1643 {
1644   NS_ASSERT (i < GetNMcsSupported (station));
1645   return station->m_state->m_operationalMcsSet[i];
1646 }
1647 
1648 WifiMode
GetNonErpSupported(const WifiRemoteStation * station,uint8_t i) const1649 WifiRemoteStationManager::GetNonErpSupported (const WifiRemoteStation *station, uint8_t i) const
1650 {
1651   NS_ASSERT (i < GetNNonErpSupported (station));
1652   //IEEE 802.11g standard defines that if the protection mechanism is enabled, RTS, CTS and CTS-To-Self
1653   //frames should select a rate in the BSSBasicRateSet that corresponds to an 802.11b basic rate.
1654   //This is a implemented here to avoid changes in every RAA, but should maybe be moved in case it breaks standard rules.
1655   uint32_t index = 0;
1656   bool found = false;
1657   for (WifiModeListIterator j = station->m_state->m_operationalRateSet.begin (); j != station->m_state->m_operationalRateSet.end (); )
1658     {
1659       if (i == index)
1660         {
1661           found = true;
1662         }
1663       if (j->GetModulationClass () != WIFI_MOD_CLASS_ERP_OFDM)
1664         {
1665           if (found)
1666             {
1667               break;
1668             }
1669         }
1670       index++;
1671       j++;
1672     }
1673   return station->m_state->m_operationalRateSet[index];
1674 }
1675 
1676 Mac48Address
GetAddress(const WifiRemoteStation * station) const1677 WifiRemoteStationManager::GetAddress (const WifiRemoteStation *station) const
1678 {
1679   return station->m_state->m_address;
1680 }
1681 
1682 uint16_t
GetChannelWidth(const WifiRemoteStation * station) const1683 WifiRemoteStationManager::GetChannelWidth (const WifiRemoteStation *station) const
1684 {
1685   return station->m_state->m_channelWidth;
1686 }
1687 
1688 bool
GetShortGuardIntervalSupported(const WifiRemoteStation * station) const1689 WifiRemoteStationManager::GetShortGuardIntervalSupported (const WifiRemoteStation *station) const
1690 {
1691   Ptr<const HtCapabilities> htCapabilities = station->m_state->m_htCapabilities;
1692 
1693   if (!htCapabilities)
1694     {
1695       return false;
1696     }
1697   return htCapabilities->GetShortGuardInterval20 ();
1698 }
1699 
1700 uint16_t
GetGuardInterval(const WifiRemoteStation * station) const1701 WifiRemoteStationManager::GetGuardInterval (const WifiRemoteStation *station) const
1702 {
1703   return station->m_state->m_guardInterval;
1704 }
1705 
1706 bool
GetAggregation(const WifiRemoteStation * station) const1707 WifiRemoteStationManager::GetAggregation (const WifiRemoteStation *station) const
1708 {
1709   return station->m_state->m_aggregation;
1710 }
1711 
1712 uint8_t
GetNumberOfSupportedStreams(const WifiRemoteStation * station) const1713 WifiRemoteStationManager::GetNumberOfSupportedStreams (const WifiRemoteStation *station) const
1714 {
1715   Ptr<const HtCapabilities> htCapabilities = station->m_state->m_htCapabilities;
1716 
1717   if (!htCapabilities)
1718     {
1719       return 1;
1720     }
1721   return htCapabilities->GetRxHighestSupportedAntennas ();
1722 }
1723 
1724 uint8_t
GetNess(const WifiRemoteStation * station) const1725 WifiRemoteStationManager::GetNess (const WifiRemoteStation *station) const
1726 {
1727   return station->m_state->m_ness;
1728 }
1729 
1730 Ptr<WifiPhy>
GetPhy(void) const1731 WifiRemoteStationManager::GetPhy (void) const
1732 {
1733   return m_wifiPhy;
1734 }
1735 
1736 Ptr<WifiMac>
GetMac(void) const1737 WifiRemoteStationManager::GetMac (void) const
1738 {
1739   return m_wifiMac;
1740 }
1741 
1742 uint8_t
GetNSupported(const WifiRemoteStation * station) const1743 WifiRemoteStationManager::GetNSupported (const WifiRemoteStation *station) const
1744 {
1745   return static_cast<uint8_t> (station->m_state->m_operationalRateSet.size ());
1746 }
1747 
1748 bool
GetQosSupported(const WifiRemoteStation * station) const1749 WifiRemoteStationManager::GetQosSupported (const WifiRemoteStation *station) const
1750 {
1751   return station->m_state->m_qosSupported;
1752 }
1753 
1754 bool
GetHtSupported(const WifiRemoteStation * station) const1755 WifiRemoteStationManager::GetHtSupported (const WifiRemoteStation *station) const
1756 {
1757   return (station->m_state->m_htCapabilities != 0);
1758 }
1759 
1760 bool
GetVhtSupported(const WifiRemoteStation * station) const1761 WifiRemoteStationManager::GetVhtSupported (const WifiRemoteStation *station) const
1762 {
1763   return (station->m_state->m_vhtCapabilities != 0);
1764 }
1765 
1766 bool
GetHeSupported(const WifiRemoteStation * station) const1767 WifiRemoteStationManager::GetHeSupported (const WifiRemoteStation *station) const
1768 {
1769   return (station->m_state->m_heCapabilities != 0);
1770 }
1771 
1772 uint8_t
GetNMcsSupported(const WifiRemoteStation * station) const1773 WifiRemoteStationManager::GetNMcsSupported (const WifiRemoteStation *station) const
1774 {
1775   return static_cast<uint8_t> (station->m_state->m_operationalMcsSet.size ());
1776 }
1777 
1778 uint32_t
GetNNonErpSupported(const WifiRemoteStation * station) const1779 WifiRemoteStationManager::GetNNonErpSupported (const WifiRemoteStation *station) const
1780 {
1781   uint32_t size = 0;
1782   for (WifiModeListIterator i = station->m_state->m_operationalRateSet.begin (); i != station->m_state->m_operationalRateSet.end (); i++)
1783     {
1784       if (i->GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
1785         {
1786           continue;
1787         }
1788       size++;
1789     }
1790   return size;
1791 }
1792 
1793 uint16_t
GetChannelWidthSupported(Mac48Address address) const1794 WifiRemoteStationManager::GetChannelWidthSupported (Mac48Address address) const
1795 {
1796   return LookupState (address)->m_channelWidth;
1797 }
1798 
1799 bool
GetShortGuardIntervalSupported(Mac48Address address) const1800 WifiRemoteStationManager::GetShortGuardIntervalSupported (Mac48Address address) const
1801 {
1802   Ptr<const HtCapabilities> htCapabilities = LookupState (address)->m_htCapabilities;
1803 
1804   if (!htCapabilities)
1805     {
1806       return false;
1807     }
1808   return htCapabilities->GetShortGuardInterval20 ();
1809 }
1810 
1811 uint8_t
GetNumberOfSupportedStreams(Mac48Address address) const1812 WifiRemoteStationManager::GetNumberOfSupportedStreams (Mac48Address address) const
1813 {
1814   Ptr<const HtCapabilities> htCapabilities = LookupState (address)->m_htCapabilities;
1815 
1816   if (!htCapabilities)
1817     {
1818       return 1;
1819     }
1820   return htCapabilities->GetRxHighestSupportedAntennas ();
1821 }
1822 
1823 uint8_t
GetNMcsSupported(Mac48Address address) const1824 WifiRemoteStationManager::GetNMcsSupported (Mac48Address address) const
1825 {
1826   return static_cast<uint8_t> (LookupState (address)->m_operationalMcsSet.size ());
1827 }
1828 
1829 bool
GetDsssSupported(const Mac48Address & address) const1830 WifiRemoteStationManager::GetDsssSupported (const Mac48Address& address) const
1831 {
1832   return (LookupState (address)->m_dsssSupported);
1833 }
1834 
1835 bool
GetErpOfdmSupported(const Mac48Address & address) const1836 WifiRemoteStationManager::GetErpOfdmSupported (const Mac48Address& address) const
1837 {
1838   return (LookupState (address)->m_erpOfdmSupported);
1839 }
1840 
1841 bool
GetOfdmSupported(const Mac48Address & address) const1842 WifiRemoteStationManager::GetOfdmSupported (const Mac48Address& address) const
1843 {
1844   return (LookupState (address)->m_ofdmSupported);
1845 }
1846 
1847 bool
GetHtSupported(Mac48Address address) const1848 WifiRemoteStationManager::GetHtSupported (Mac48Address address) const
1849 {
1850   return (LookupState (address)->m_htCapabilities != 0);
1851 }
1852 
1853 bool
GetVhtSupported(Mac48Address address) const1854 WifiRemoteStationManager::GetVhtSupported (Mac48Address address) const
1855 {
1856   return (LookupState (address)->m_vhtCapabilities != 0);
1857 }
1858 
1859 bool
GetHeSupported(Mac48Address address) const1860 WifiRemoteStationManager::GetHeSupported (Mac48Address address) const
1861 {
1862   return (LookupState (address)->m_heCapabilities != 0);
1863 }
1864 
1865 void
SetDefaultTxPowerLevel(uint8_t txPower)1866 WifiRemoteStationManager::SetDefaultTxPowerLevel (uint8_t txPower)
1867 {
1868   m_defaultTxPowerLevel = txPower;
1869 }
1870 
1871 uint8_t
GetNumberOfAntennas(void) const1872 WifiRemoteStationManager::GetNumberOfAntennas (void) const
1873 {
1874   return m_wifiPhy->GetNumberOfAntennas ();
1875 }
1876 
1877 uint8_t
GetMaxNumberOfTransmitStreams(void) const1878 WifiRemoteStationManager::GetMaxNumberOfTransmitStreams (void) const
1879 {
1880   return m_wifiPhy->GetMaxSupportedTxSpatialStreams ();
1881 }
1882 
1883 bool
UseLdpcForDestination(Mac48Address dest) const1884 WifiRemoteStationManager::UseLdpcForDestination (Mac48Address dest) const
1885 {
1886   return (GetLdpcSupported () && GetLdpcSupported (dest));
1887 }
1888 
1889 } //namespace ns3
1890