22 #include "sta-wifi-mac.h"
25 #include "ns3/simulator.h"
26 #include "ns3/string.h"
27 #include "ns3/pointer.h"
28 #include "ns3/boolean.h"
29 #include "ns3/trace-source-accessor.h"
33 #include "dcf-manager.h"
34 #include "mac-rx-middle.h"
35 #include "mac-tx-middle.h"
36 #include "wifi-mac-header.h"
37 #include "msdu-aggregator.h"
38 #include "amsdu-subframe-header.h"
39 #include "mgt-headers.h"
62 NS_OBJECT_ENSURE_REGISTERED (StaWifiMac);
65 StaWifiMac::GetTypeId (
void)
67 static TypeId tid = TypeId (
"ns3::StaWifiMac")
68 .SetParent<RegularWifiMac> ()
69 .AddConstructor<StaWifiMac> ()
70 .AddAttribute (
"ProbeRequestTimeout",
"The interval between two consecutive probe request attempts.",
72 MakeTimeAccessor (&StaWifiMac::m_probeRequestTimeout),
74 .AddAttribute (
"AssocRequestTimeout",
"The interval between two consecutive assoc request attempts.",
76 MakeTimeAccessor (&StaWifiMac::m_assocRequestTimeout),
78 .AddAttribute (
"MaxMissedBeacons",
79 "Number of beacons which much be consecutively missed before "
80 "we attempt to restart association.",
82 MakeUintegerAccessor (&StaWifiMac::m_maxMissedBeacons),
83 MakeUintegerChecker<uint32_t> ())
84 .AddAttribute (
"ActiveProbing",
"If true, we send probe requests. If false, we don't. NOTE: if more than one STA in your simulation is using active probing, you should enable it at a different simulation time for each STA, otherwise all the STAs will start sending probes at the same time resulting in collisions. See bug 1060 for more info.",
86 MakeBooleanAccessor (&StaWifiMac::SetActiveProbing),
87 MakeBooleanChecker ())
88 .AddTraceSource (
"Assoc",
"Associated with an access point.",
90 .AddTraceSource (
"DeAssoc",
"Association with an access point lost.",
96 StaWifiMac::StaWifiMac ()
97 : m_state (BEACON_MISSED),
98 m_probeRequestEvent (),
99 m_assocRequestEvent (),
100 m_beaconWatchdogEnd (
Seconds (0.0))
106 SetTypeOfStation (STA);
109 StaWifiMac::~StaWifiMac ()
118 m_maxMissedBeacons = missed;
125 m_probeRequestTimeout = timeout;
132 m_assocRequestTimeout = timeout;
139 TryToEnsureAssociated ();
143 StaWifiMac::SetActiveProbing (
bool enable)
152 m_probeRequestEvent.
Cancel ();
157 StaWifiMac::SendProbeRequest (
void)
167 Ptr<Packet> packet = Create<Packet> ();
168 MgtProbeRequestHeader probe;
170 probe.SetSupportedRates (GetSupportedRates ());
171 packet->AddHeader (probe);
177 m_dca->Queue (packet, hdr);
180 &StaWifiMac::ProbeRequestTimeout,
this);
184 StaWifiMac::SendAssociationRequest (
void)
194 Ptr<Packet> packet = Create<Packet> ();
195 MgtAssocRequestHeader assoc;
197 assoc.SetSupportedRates (GetSupportedRates ());
198 packet->AddHeader (assoc);
204 m_dca->Queue (packet, hdr);
207 &StaWifiMac::AssocRequestTimeout,
this);
211 StaWifiMac::TryToEnsureAssociated (
void)
219 case WAIT_PROBE_RESP:
232 SetState (WAIT_PROBE_RESP);
235 case WAIT_ASSOC_RESP:
252 StaWifiMac::AssocRequestTimeout (
void)
255 SetState (WAIT_ASSOC_RESP);
256 SendAssociationRequest ();
260 StaWifiMac::ProbeRequestTimeout (
void)
263 SetState (WAIT_PROBE_RESP);
268 StaWifiMac::MissedBeacons (
void)
274 &StaWifiMac::MissedBeacons,
this);
278 SetState (BEACON_MISSED);
279 TryToEnsureAssociated ();
283 StaWifiMac::RestartBeaconWatchdog (Time delay)
286 m_beaconWatchdogEnd = std::max (
Simulator::Now () + delay, m_beaconWatchdogEnd);
296 StaWifiMac::IsAssociated (
void)
const
298 return m_state == ASSOCIATED;
302 StaWifiMac::IsWaitAssocResp (
void)
const
304 return m_state == WAIT_ASSOC_RESP;
311 if (!IsAssociated ())
314 TryToEnsureAssociated ();
331 hdr.SetType (WIFI_MAC_QOSDATA);
332 hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
334 hdr.SetQosNoAmsdu ();
337 hdr.SetQosTxopLimit (0);
356 hdr.SetAddr2 (m_low->GetAddress ());
369 m_dca->Queue (packet, hdr);
384 && !hdr->GetAddr1 ().
IsGroup ())
390 else if (hdr->IsData ())
392 if (!IsAssociated ())
394 NS_LOG_LOGIC (
"Received data frame while not associated: ignore");
398 if (!(hdr->IsFromDs () && !hdr->IsToDs ()))
400 NS_LOG_LOGIC (
"Received data frame not from the DS: ignore");
404 if (hdr->GetAddr2 () !=
GetBssid ())
406 NS_LOG_LOGIC (
"Received data frame not from the BSS we are associated with: ignore");
411 if (hdr->IsQosData ())
413 if (hdr->IsQosAmsdu ())
421 ForwardUp (packet, hdr->GetAddr3 (), hdr->GetAddr1 ());
426 ForwardUp (packet, hdr->GetAddr3 (), hdr->GetAddr1 ());
430 else if (hdr->IsProbeReq ()
431 || hdr->IsAssocReq ())
437 else if (hdr->IsBeacon ())
441 bool goodBeacon =
false;
443 || beacon.GetSsid ().IsEqual (
GetSsid ()))
447 if ((IsWaitAssocResp () || IsAssociated ()) && hdr->GetAddr3 () !=
GetBssid ())
453 Time delay =
MicroSeconds (beacon.GetBeaconIntervalUs () * m_maxMissedBeacons);
454 RestartBeaconWatchdog (delay);
457 if (goodBeacon && m_state == BEACON_MISSED)
459 SetState (WAIT_ASSOC_RESP);
460 SendAssociationRequest ();
464 else if (hdr->IsProbeResp ())
466 if (m_state == WAIT_PROBE_RESP)
470 if (!probeResp.GetSsid ().IsEqual (
GetSsid ()))
476 Time delay =
MicroSeconds (probeResp.GetBeaconIntervalUs () * m_maxMissedBeacons);
477 RestartBeaconWatchdog (delay);
480 m_probeRequestEvent.
Cancel ();
482 SetState (WAIT_ASSOC_RESP);
483 SendAssociationRequest ();
487 else if (hdr->IsAssocResp ())
489 if (m_state == WAIT_ASSOC_RESP)
495 m_assocRequestEvent.
Cancel ();
497 if (assocResp.GetStatusCode ().IsSuccess ())
499 SetState (ASSOCIATED);
502 for (uint32_t i = 0; i < m_phy->
GetNModes (); i++)
507 m_stationManager->AddSupportedMode (hdr->GetAddr2 (), mode);
510 m_stationManager->AddBasicMode (mode);
514 if (!m_linkUp.IsNull ())
535 StaWifiMac::GetSupportedRates (
void)
const
538 for (uint32_t i = 0; i < m_phy->
GetNModes (); i++)
547 StaWifiMac::SetState (MacState value)
549 if (value == ASSOCIATED
550 && m_state != ASSOCIATED)
554 else if (value != ASSOCIATED
555 && m_state == ASSOCIATED)
static Time GetDelayLeft(const EventId &id)
uint32_t RemoveHeader(Header &header)
virtual void Receive(Ptr< Packet > packet, const WifiMacHeader *hdr)
#define NS_LOG_FUNCTION(parameters)
virtual uint32_t GetNModes(void) const =0
void SetProbeRequestTimeout(Time timeout)
#define NS_ASSERT(condition)
#define NS_LOG_COMPONENT_DEFINE(name)
void NotifyRxDrop(Ptr< const Packet > packet)
bool IsRunning(void) const
virtual void DeaggregateAmsduAndForward(Ptr< Packet > aggregatedPacket, const WifiMacHeader *hdr)
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
virtual Ssid GetSsid(void) const
The Supported Rates Information ElementThis class knows how to serialise and deserialise the Supporte...
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
void SetAssocRequestTimeout(Time timeout)
virtual void Receive(Ptr< Packet > packet, const WifiMacHeader *hdr)
uint8_t QosUtilsGetTidForPacket(Ptr< const Packet > packet)
virtual void SetBssid(Mac48Address bssid)
void NotifyTxDrop(Ptr< const Packet > packet)
AcIndex QosUtilsMapTidToAc(uint8_t tid)
static Mac48Address GetBroadcast(void)
#define NS_LOG_LOGIC(msg)
void StartActiveAssociation(void)
void SetMaxMissedBeacons(uint32_t missed)
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
virtual WifiMode GetMode(uint32_t mode) const =0
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
virtual Mac48Address GetBssid(void) const
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
#define NS_LOG_DEBUG(msg)
virtual Mac48Address GetAddress(void) const
virtual void Enqueue(Ptr< const Packet > packet, Mac48Address to)
bool IsExpired(void) const
uint64_t GetDataRate(void) const
Time MicroSeconds(uint64_t us)
create ns3::Time instances in units of microseconds.