00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "ns3/packet.h"
00022 #include "ns3/simulator.h"
00023 #include "ns3/assert.h"
00024 #include "ns3/log.h"
00025 #include "ns3/node.h"
00026 #include "ns3/uinteger.h"
00027
00028 #include "nqsta-wifi-mac.h"
00029 #include "wifi-mac-header.h"
00030 #include "mgt-headers.h"
00031 #include "wifi-phy.h"
00032 #include "dca-txop.h"
00033 #include "mac-low.h"
00034 #include "dcf-manager.h"
00035 #include "mac-rx-middle.h"
00036
00037 NS_LOG_COMPONENT_DEFINE ("NqstaWifiMac");
00038
00039 #undef NS_LOG_APPEND_CONTEXT
00040 #define NS_LOG_APPEND_CONTEXT if (m_low != 0) {std::clog << "[mac=" << m_low->GetAddress () << "] ";}
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 namespace ns3 {
00059
00060 NS_OBJECT_ENSURE_REGISTERED (NqstaWifiMac);
00061
00062 TypeId
00063 NqstaWifiMac::GetTypeId (void)
00064 {
00065 static TypeId tid = TypeId ("ns3::NqstaWifiMac")
00066 .SetParent<WifiMac> ()
00067 .AddConstructor<NqstaWifiMac> ()
00068 .AddAttribute ("ProbeRequestTimeout", "The interval between two consecutive probe request attempts.",
00069 TimeValue (Seconds (0.05)),
00070 MakeTimeAccessor (&NqstaWifiMac::m_probeRequestTimeout),
00071 MakeTimeChecker ())
00072 .AddAttribute ("AssocRequestTimeout", "The interval between two consecutive assoc request attempts.",
00073 TimeValue (Seconds (0.5)),
00074 MakeTimeAccessor (&NqstaWifiMac::m_assocRequestTimeout),
00075 MakeTimeChecker ())
00076 .AddAttribute ("MaxMissedBeacons",
00077 "Number of beacons which much be consecutively missed before "
00078 "we attempt to restart association.",
00079 UintegerValue (10),
00080 MakeUintegerAccessor (&NqstaWifiMac::m_maxMissedBeacons),
00081 MakeUintegerChecker<uint32_t> ())
00082 .AddAttribute ("ActiveProbing", "If true, we send probe requests. If false, we don't.",
00083 BooleanValue (false),
00084 MakeBooleanAccessor (&NqstaWifiMac::SetActiveProbing),
00085 MakeBooleanChecker ())
00086 ;
00087 return tid;
00088 }
00089
00090
00091 NqstaWifiMac::NqstaWifiMac ()
00092 : m_state (BEACON_MISSED),
00093 m_probeRequestEvent (),
00094 m_assocRequestEvent (),
00095 m_beaconWatchdogEnd (Seconds (0.0))
00096 {
00097 NS_LOG_FUNCTION (this);
00098 m_rxMiddle = new MacRxMiddle ();
00099 m_rxMiddle->SetForwardCallback (MakeCallback (&NqstaWifiMac::Receive, this));
00100
00101 m_low = CreateObject<MacLow> ();
00102 m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
00103
00104 m_dcfManager = new DcfManager ();
00105 m_dcfManager->SetupLowListener (m_low);
00106
00107 m_dca = CreateObject<DcaTxop> ();
00108 m_dca->SetLow (m_low);
00109 m_dca->SetManager (m_dcfManager);
00110 }
00111
00112 NqstaWifiMac::~NqstaWifiMac ()
00113 {
00114 NS_LOG_FUNCTION (this);
00115 }
00116
00117 void
00118 NqstaWifiMac::DoDispose (void)
00119 {
00120 NS_LOG_FUNCTION (this);
00121 delete m_rxMiddle;
00122 delete m_dcfManager;
00123 m_rxMiddle = 0;
00124 m_low = 0;
00125 m_dcfManager = 0;
00126 m_phy = 0;
00127 m_dca = 0;
00128 WifiMac::DoDispose ();
00129 }
00130
00131 void
00132 NqstaWifiMac::SetSlot (Time slotTime)
00133 {
00134 NS_LOG_FUNCTION (this << slotTime);
00135 m_dcfManager->SetSlot (slotTime);
00136 m_low->SetSlotTime (slotTime);
00137 }
00138 void
00139 NqstaWifiMac::SetSifs (Time sifs)
00140 {
00141 NS_LOG_FUNCTION (this << sifs);
00142 m_dcfManager->SetSifs (sifs);
00143 m_low->SetSifs (sifs);
00144 }
00145 void
00146 NqstaWifiMac::SetEifsNoDifs (Time eifsNoDifs)
00147 {
00148 NS_LOG_FUNCTION (this << eifsNoDifs);
00149 m_dcfManager->SetEifsNoDifs (eifsNoDifs);
00150 m_eifsNoDifs = eifsNoDifs;
00151 }
00152 void
00153 NqstaWifiMac::SetAckTimeout (Time ackTimeout)
00154 {
00155 m_low->SetAckTimeout (ackTimeout);
00156 }
00157 void
00158 NqstaWifiMac::SetCtsTimeout (Time ctsTimeout)
00159 {
00160 m_low->SetCtsTimeout (ctsTimeout);
00161 }
00162 void
00163 NqstaWifiMac::SetPifs (Time pifs)
00164 {
00165 m_low->SetPifs (pifs);
00166 }
00167 Time
00168 NqstaWifiMac::GetSlot (void) const
00169 {
00170 return m_low->GetSlotTime ();
00171 }
00172 Time
00173 NqstaWifiMac::GetSifs (void) const
00174 {
00175 return m_low->GetSifs ();
00176 }
00177 Time
00178 NqstaWifiMac::GetEifsNoDifs (void) const
00179 {
00180 return m_eifsNoDifs;
00181 }
00182 Time
00183 NqstaWifiMac::GetAckTimeout (void) const
00184 {
00185 return m_low->GetAckTimeout ();
00186 }
00187 Time
00188 NqstaWifiMac::GetCtsTimeout (void) const
00189 {
00190 return m_low->GetCtsTimeout ();
00191 }
00192 Time
00193 NqstaWifiMac::GetPifs (void) const
00194 {
00195 return m_low->GetPifs ();
00196 }
00197
00198 void
00199 NqstaWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
00200 {
00201 m_phy = phy;
00202 m_dcfManager->SetupPhyListener (phy);
00203 m_low->SetPhy (phy);
00204 }
00205 void
00206 NqstaWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
00207 {
00208 m_stationManager = stationManager;
00209 m_dca->SetWifiRemoteStationManager (stationManager);
00210 m_low->SetWifiRemoteStationManager (stationManager);
00211 }
00212 void
00213 NqstaWifiMac::SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback)
00214 {
00215 m_forwardUp = upCallback;
00216 }
00217 void
00218 NqstaWifiMac::SetLinkUpCallback (Callback<void> linkUp)
00219 {
00220 m_linkUp = linkUp;
00221 }
00222 void
00223 NqstaWifiMac::SetLinkDownCallback (Callback<void> linkDown)
00224 {
00225 m_linkDown = linkDown;
00226 }
00227 Mac48Address
00228 NqstaWifiMac::GetAddress (void) const
00229 {
00230 return m_low->GetAddress ();
00231 }
00232 Ssid
00233 NqstaWifiMac::GetSsid (void) const
00234 {
00235 return m_ssid;
00236 }
00237 Mac48Address
00238 NqstaWifiMac::GetBssid (void) const
00239 {
00240 return m_low->GetBssid ();
00241 }
00242 void
00243 NqstaWifiMac::SetAddress (Mac48Address address)
00244 {
00245 NS_LOG_FUNCTION (this << address);
00246 m_low->SetAddress (address);
00247 }
00248 void
00249 NqstaWifiMac::SetSsid (Ssid ssid)
00250 {
00251 NS_LOG_FUNCTION (this << ssid);
00252 m_ssid = ssid;
00253 }
00254 void
00255 NqstaWifiMac::SetMaxMissedBeacons (uint32_t missed)
00256 {
00257 NS_LOG_FUNCTION (this << missed);
00258 m_maxMissedBeacons = missed;
00259 }
00260 void
00261 NqstaWifiMac::SetProbeRequestTimeout (Time timeout)
00262 {
00263 NS_LOG_FUNCTION (this << timeout);
00264 m_probeRequestTimeout = timeout;
00265 }
00266 void
00267 NqstaWifiMac::SetAssocRequestTimeout (Time timeout)
00268 {
00269 NS_LOG_FUNCTION (this << timeout);
00270 m_assocRequestTimeout = timeout;
00271 }
00272
00273 void
00274 NqstaWifiMac::StartActiveAssociation (void)
00275 {
00276 NS_LOG_FUNCTION (this);
00277 TryToEnsureAssociated ();
00278 }
00279
00280 Mac48Address
00281 NqstaWifiMac::GetBroadcastBssid (void)
00282 {
00283 return Mac48Address::GetBroadcast ();
00284 }
00285
00286 void
00287 NqstaWifiMac::SetBssid (Mac48Address bssid)
00288 {
00289 NS_LOG_FUNCTION (this << bssid);
00290 m_low->SetBssid (bssid);
00291 }
00292 void
00293 NqstaWifiMac::SetActiveProbing (bool enable)
00294 {
00295 NS_LOG_FUNCTION (this << enable);
00296 if (enable)
00297 {
00298 TryToEnsureAssociated ();
00299 }
00300 else
00301 {
00302 m_probeRequestEvent.Cancel ();
00303 }
00304 }
00305 void
00306 NqstaWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to)
00307 {
00308 NS_LOG_FUNCTION (this << packet << from << to);
00309 m_forwardUp (packet, from, to);
00310 }
00311 void
00312 NqstaWifiMac::SendProbeRequest (void)
00313 {
00314 NS_LOG_FUNCTION (this);
00315 WifiMacHeader hdr;
00316 hdr.SetProbeReq ();
00317 hdr.SetAddr1 (GetBroadcastBssid ());
00318 hdr.SetAddr2 (GetAddress ());
00319 hdr.SetAddr3 (GetBroadcastBssid ());
00320 hdr.SetDsNotFrom ();
00321 hdr.SetDsNotTo ();
00322 Ptr<Packet> packet = Create<Packet> ();
00323 MgtProbeRequestHeader probe;
00324 probe.SetSsid (GetSsid ());
00325 probe.SetSupportedRates (GetSupportedRates ());
00326 packet->AddHeader (probe);
00327
00328 m_dca->Queue (packet, hdr);
00329
00330 m_probeRequestEvent = Simulator::Schedule (m_probeRequestTimeout,
00331 &NqstaWifiMac::ProbeRequestTimeout, this);
00332 }
00333
00334 void
00335 NqstaWifiMac::SendAssociationRequest (void)
00336 {
00337 NS_LOG_FUNCTION (this << GetBssid ());
00338 WifiMacHeader hdr;
00339 hdr.SetAssocReq ();
00340 hdr.SetAddr1 (GetBssid ());
00341 hdr.SetAddr2 (GetAddress ());
00342 hdr.SetAddr3 (GetBssid ());
00343 hdr.SetDsNotFrom ();
00344 hdr.SetDsNotTo ();
00345 Ptr<Packet> packet = Create<Packet> ();
00346 MgtAssocRequestHeader assoc;
00347 assoc.SetSsid (GetSsid ());
00348 assoc.SetSupportedRates (GetSupportedRates ());
00349 packet->AddHeader (assoc);
00350
00351 m_dca->Queue (packet, hdr);
00352
00353 m_assocRequestEvent = Simulator::Schedule (m_assocRequestTimeout,
00354 &NqstaWifiMac::AssocRequestTimeout, this);
00355 }
00356 void
00357 NqstaWifiMac::TryToEnsureAssociated (void)
00358 {
00359 NS_LOG_FUNCTION (this);
00360 switch (m_state) {
00361 case ASSOCIATED:
00362 return;
00363 break;
00364 case WAIT_PROBE_RESP:
00365
00366
00367
00368
00369
00370 break;
00371 case BEACON_MISSED:
00372
00373
00374
00375
00376 m_linkDown ();
00377 m_state = WAIT_PROBE_RESP;
00378 SendProbeRequest ();
00379 break;
00380 case WAIT_ASSOC_RESP:
00381
00382
00383
00384
00385
00386 break;
00387 case REFUSED:
00388
00389
00390
00391
00392 break;
00393 }
00394 }
00395
00396 void
00397 NqstaWifiMac::AssocRequestTimeout (void)
00398 {
00399 NS_LOG_FUNCTION (this);
00400 m_state = WAIT_ASSOC_RESP;
00401 SendAssociationRequest ();
00402 }
00403 void
00404 NqstaWifiMac::ProbeRequestTimeout (void)
00405 {
00406 NS_LOG_FUNCTION (this);
00407 m_state = WAIT_PROBE_RESP;
00408 SendProbeRequest ();
00409 }
00410 void
00411 NqstaWifiMac::MissedBeacons (void)
00412 {
00413 NS_LOG_FUNCTION (this);
00414 if (m_beaconWatchdogEnd > Simulator::Now ())
00415 {
00416 m_beaconWatchdog = Simulator::Schedule (m_beaconWatchdogEnd - Simulator::Now (),
00417 &NqstaWifiMac::MissedBeacons, this);
00418 return;
00419 }
00420 NS_LOG_DEBUG ("beacon missed");
00421 m_state = BEACON_MISSED;
00422 TryToEnsureAssociated ();
00423 }
00424 void
00425 NqstaWifiMac::RestartBeaconWatchdog (Time delay)
00426 {
00427 NS_LOG_FUNCTION (this << delay);
00428 m_beaconWatchdogEnd = std::max (Simulator::Now () + delay, m_beaconWatchdogEnd);
00429 if (Simulator::GetDelayLeft (m_beaconWatchdog) < delay &&
00430 m_beaconWatchdog.IsExpired ())
00431 {
00432 NS_LOG_DEBUG ("really restart watchdog.");
00433 m_beaconWatchdog = Simulator::Schedule (delay, &NqstaWifiMac::MissedBeacons, this);
00434 }
00435 }
00436 bool
00437 NqstaWifiMac::IsAssociated (void)
00438 {
00439 return (m_state == ASSOCIATED)?true:false;
00440 }
00441
00442 void
00443 NqstaWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from)
00444 {
00445 NS_FATAL_ERROR ("Qsta does not support enqueue");
00446 }
00447 void
00448 NqstaWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
00449 {
00450 NS_LOG_FUNCTION (this << packet << to);
00451 if (!IsAssociated ())
00452 {
00453 TryToEnsureAssociated ();
00454 return;
00455 }
00456
00457 WifiMacHeader hdr;
00458 hdr.SetTypeData ();
00459 hdr.SetAddr1 (GetBssid ());
00460 hdr.SetAddr2 (m_low->GetAddress ());
00461 hdr.SetAddr3 (to);
00462 hdr.SetDsNotFrom ();
00463 hdr.SetDsTo ();
00464 m_dca->Queue (packet, hdr);
00465 }
00466 bool
00467 NqstaWifiMac::SupportsSendFrom (void) const
00468 {
00469 return true;
00470 }
00471
00472
00473 void
00474 NqstaWifiMac::Receive (Ptr<Packet> packet, WifiMacHeader const *hdr)
00475 {
00476 NS_LOG_FUNCTION (this << packet << hdr);
00477 NS_ASSERT (!hdr->IsCtl ());
00478 if (hdr->GetAddr1 () != GetAddress () &&
00479 !hdr->GetAddr1 ().IsBroadcast ())
00480 {
00481 NS_LOG_LOGIC ("packet is not for us");
00482 }
00483 else if (hdr->IsData ())
00484 {
00485 if (!IsAssociated ())
00486 {
00487 NS_LOG_LOGIC ("Received data frame while not associated: ignore");
00488 return;
00489 }
00490 if (!(hdr->IsFromDs () && !hdr->IsToDs ()))
00491 {
00492 NS_LOG_LOGIC ("Received data frame not from the DS: ignore");
00493 return;
00494 }
00495 if (hdr->GetAddr2 () != GetBssid ())
00496 {
00497 NS_LOG_LOGIC ("Received data frame not from the the BSS we are associated with: ignore");
00498 return;
00499 }
00500 if (hdr->GetAddr3 () != GetAddress ())
00501 {
00502 ForwardUp (packet, hdr->GetAddr3 (), hdr->GetAddr1 ());
00503 }
00504 }
00505 else if (hdr->IsProbeReq () ||
00506 hdr->IsAssocReq ())
00507 {
00508
00509
00510
00511 }
00512 else if (hdr->IsBeacon ())
00513 {
00514 MgtBeaconHeader beacon;
00515 packet->RemoveHeader (beacon);
00516 bool goodBeacon = false;
00517 if (GetSsid ().IsBroadcast () ||
00518 beacon.GetSsid ().IsEqual (GetSsid ()))
00519 {
00520 goodBeacon = true;
00521 }
00522 if (IsAssociated () && hdr->GetAddr3 () != GetBssid ())
00523 {
00524 goodBeacon = false;
00525 }
00526 if (goodBeacon)
00527 {
00528 Time delay = MicroSeconds (beacon.GetBeaconIntervalUs () * m_maxMissedBeacons);
00529 RestartBeaconWatchdog (delay);
00530 SetBssid (hdr->GetAddr3 ());
00531 }
00532 if (goodBeacon && m_state == BEACON_MISSED)
00533 {
00534 m_state = WAIT_ASSOC_RESP;
00535 SendAssociationRequest ();
00536 }
00537 }
00538 else if (hdr->IsProbeResp ())
00539 {
00540 if (m_state == WAIT_PROBE_RESP)
00541 {
00542 MgtProbeResponseHeader probeResp;
00543 packet->RemoveHeader (probeResp);
00544 if (!probeResp.GetSsid ().IsEqual (GetSsid ()))
00545 {
00546
00547 return;
00548 }
00549 SetBssid (hdr->GetAddr3 ());
00550 Time delay = MicroSeconds (probeResp.GetBeaconIntervalUs () * m_maxMissedBeacons);
00551 RestartBeaconWatchdog (delay);
00552 if (m_probeRequestEvent.IsRunning ())
00553 {
00554 m_probeRequestEvent.Cancel ();
00555 }
00556 m_state = WAIT_ASSOC_RESP;
00557 SendAssociationRequest ();
00558 }
00559 }
00560 else if (hdr->IsAssocResp ())
00561 {
00562 if (m_state == WAIT_ASSOC_RESP)
00563 {
00564 MgtAssocResponseHeader assocResp;
00565 packet->RemoveHeader (assocResp);
00566 if (m_assocRequestEvent.IsRunning ())
00567 {
00568 m_assocRequestEvent.Cancel ();
00569 }
00570 if (assocResp.GetStatusCode ().IsSuccess ())
00571 {
00572 m_state = ASSOCIATED;
00573 NS_LOG_DEBUG ("assoc completed");
00574 SupportedRates rates = assocResp.GetSupportedRates ();
00575 WifiRemoteStation *ap = m_stationManager->Lookup (hdr->GetAddr2 ());
00576 for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
00577 {
00578 WifiMode mode = m_phy->GetMode (i);
00579 if (rates.IsSupportedRate (mode.GetDataRate ()))
00580 {
00581 ap->AddSupportedMode (mode);
00582 if (rates.IsBasicRate (mode.GetDataRate ()))
00583 {
00584 m_stationManager->AddBasicMode (mode);
00585 }
00586 }
00587 }
00588 if (!m_linkUp.IsNull ())
00589 {
00590 m_linkUp ();
00591 }
00592 }
00593 else
00594 {
00595 NS_LOG_DEBUG ("assoc refused");
00596 m_state = REFUSED;
00597 }
00598 }
00599 }
00600 }
00601
00602 SupportedRates
00603 NqstaWifiMac::GetSupportedRates (void) const
00604 {
00605 SupportedRates rates;
00606 for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
00607 {
00608 WifiMode mode = m_phy->GetMode (i);
00609 rates.AddSupportedRate (mode.GetDataRate ());
00610 }
00611 return rates;
00612 }
00613
00614 }