OLD | NEW |
(Empty) | |
| 1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ |
| 2 /* |
| 3 * Copyright (c) 2006, 2009 INRIA |
| 4 * Copyright (c) 2009 MIRKO BANCHI |
| 5 * |
| 6 * This program is free software; you can redistribute it and/or modify |
| 7 * it under the terms of the GNU General Public License version 2 as· |
| 8 * published by the Free Software Foundation; |
| 9 * |
| 10 * This program is distributed in the hope that it will be useful, |
| 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 * GNU General Public License for more details. |
| 14 * |
| 15 * You should have received a copy of the GNU General Public License |
| 16 * along with this program; if not, write to the Free Software |
| 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 18 * |
| 19 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> |
| 20 * Author: Mirko Banchi <mk.banchi@gmail.com> |
| 21 */ |
| 22 #include "ns3/log.h" |
| 23 #include "ns3/qos-tag.h" |
| 24 #include "ns3/simulator.h" |
| 25 #include "ns3/string.h" |
| 26 #include "ns3/pointer.h" |
| 27 |
| 28 #include "edca-txop-n.h" |
| 29 #include "qsta-wifi-mac.h" |
| 30 #include "mac-low.h" |
| 31 #include "dcf-manager.h" |
| 32 #include "mac-rx-middle.h" |
| 33 #include "mac-tx-middle.h" |
| 34 #include "wifi-mac-header.h" |
| 35 #include "msdu-aggregator.h" |
| 36 #include "amsdu-subframe-header.h" |
| 37 #include "mgt-headers.h" |
| 38 |
| 39 NS_LOG_COMPONENT_DEFINE ("QstaWifiMac"); |
| 40 |
| 41 namespace ns3 { |
| 42 |
| 43 NS_OBJECT_ENSURE_REGISTERED (QstaWifiMac); |
| 44 |
| 45 TypeId |
| 46 QstaWifiMac::GetTypeId (void) |
| 47 { |
| 48 static TypeId tid = TypeId ("ns3::QstaWifiMac") |
| 49 .SetParent<WifiMac> () |
| 50 .AddConstructor<QstaWifiMac> () |
| 51 .AddAttribute ("Mode", "Indicates current operating mode: .11e or .11n", |
| 52 StringValue(".11n"), |
| 53 MakeStringAccessor (&QstaWifiMac::m_currentMode), |
| 54 MakeStringChecker ()) |
| 55 .AddAttribute ("ProbeRequestTimeout", "The interval between two consecutive
probe request attempts.", |
| 56 TimeValue (Seconds (0.05)), |
| 57 MakeTimeAccessor (&QstaWifiMac::m_probeRequestTimeout), |
| 58 MakeTimeChecker ()) |
| 59 .AddAttribute ("AssocRequestTimeout", "The interval between two consecutive
assoc request attempts.", |
| 60 TimeValue (Seconds (0.5)), |
| 61 MakeTimeAccessor (&QstaWifiMac::m_assocRequestTimeout), |
| 62 MakeTimeChecker ()) |
| 63 .AddAttribute ("MaxMissedBeacons",· |
| 64 "Number of beacons which much be consecutively missed before
" |
| 65 "we attempt to restart association.", |
| 66 UintegerValue (10), |
| 67 MakeUintegerAccessor (&QstaWifiMac::m_maxMissedBeacons), |
| 68 MakeUintegerChecker<uint32_t> ()) |
| 69 .AddAttribute ("ActiveProbing", "If true, we send probe requests. If false,
we don't.", |
| 70 BooleanValue (false), |
| 71 MakeBooleanAccessor (&QstaWifiMac::SetActiveProbing), |
| 72 MakeBooleanChecker ()) |
| 73 .AddAttribute ("VO_EdcaTxopN", |
| 74 "Queue that manages packets belonging to AC_VO access class", |
| 75 PointerValue (), |
| 76 MakePointerAccessor(&QstaWifiMac::GetVOQueue, |
| 77 &QstaWifiMac::SetVOQueue), |
| 78 MakePointerChecker<EdcaTxopN> ()) |
| 79 .AddAttribute ("VI_EdcaTxopN", |
| 80 "Queue that manages packets belonging to AC_VI access class", |
| 81 PointerValue (), |
| 82 MakePointerAccessor(&QstaWifiMac::GetVIQueue, |
| 83 &QstaWifiMac::SetVIQueue), |
| 84 MakePointerChecker<EdcaTxopN> ()) |
| 85 .AddAttribute ("BE_EdcaTxopN", |
| 86 "Queue that manages packets belonging to AC_BE access class", |
| 87 PointerValue (), |
| 88 MakePointerAccessor(&QstaWifiMac::GetBEQueue, |
| 89 &QstaWifiMac::SetBEQueue), |
| 90 MakePointerChecker<EdcaTxopN> ()) |
| 91 .AddAttribute ("BK_EdcaTxopN", |
| 92 "Queue that manages packets belonging to AC_BK access class", |
| 93 PointerValue (), |
| 94 MakePointerAccessor(&QstaWifiMac::GetBKQueue, |
| 95 &QstaWifiMac::SetBKQueue), |
| 96 MakePointerChecker<EdcaTxopN> ()) |
| 97 ; |
| 98 return tid; |
| 99 } |
| 100 |
| 101 QstaWifiMac::QstaWifiMac () |
| 102 : m_state (BEACON_MISSED), |
| 103 m_probeRequestEvent (), |
| 104 m_assocRequestEvent (), |
| 105 m_beaconWatchdogEnd (Seconds (0.0)) |
| 106 { |
| 107 NS_LOG_FUNCTION (this); |
| 108 m_rxMiddle = new MacRxMiddle (); |
| 109 m_rxMiddle->SetForwardCallback (MakeCallback (&QstaWifiMac::Receive, this)); |
| 110 /*TxMiddle can be shared between all queues */ |
| 111 m_txMiddle= new MacTxMiddle (); |
| 112 ·· |
| 113 m_low = CreateObject<MacLow> (); |
| 114 m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle)); |
| 115 |
| 116 m_dcfManager = new DcfManager (); |
| 117 m_dcfManager->SetupLowListener (m_low); |
| 118 ·· |
| 119 //m_queues[i] = DcaFactory::GetDca (m_currentMode); |
| 120 } |
| 121 |
| 122 QstaWifiMac::~QstaWifiMac () |
| 123 { |
| 124 NS_LOG_FUNCTION (this); |
| 125 } |
| 126 |
| 127 void |
| 128 QstaWifiMac::DoDispose () |
| 129 { |
| 130 NS_LOG_FUNCTION (this); |
| 131 delete m_rxMiddle; |
| 132 delete m_txMiddle; |
| 133 m_rxMiddle = 0; |
| 134 m_txMiddle = 0; |
| 135 m_low = 0; |
| 136 m_phy = 0; |
| 137 m_dcfManager = 0; |
| 138 m_voEdca = 0; |
| 139 m_viEdca = 0; |
| 140 m_beEdca = 0; |
| 141 m_bkEdca = 0; |
| 142 m_stationManager = 0; |
| 143 std::map<AccessClass, Ptr<EdcaTxopN> >::iterator it = m_queues.begin (); |
| 144 for (;it != m_queues.end (); it++) |
| 145 { |
| 146 it->second = 0; |
| 147 } |
| 148 WifiMac::DoDispose (); |
| 149 } |
| 150 |
| 151 void |
| 152 QstaWifiMac::SetSlot (Time slotTime) |
| 153 { |
| 154 NS_LOG_FUNCTION (this << slotTime); |
| 155 m_dcfManager->SetSlot (slotTime); |
| 156 m_low->SetSlotTime (slotTime); |
| 157 } |
| 158 |
| 159 void· |
| 160 QstaWifiMac::SetSifs (Time sifs) |
| 161 { |
| 162 NS_LOG_FUNCTION (this << sifs); |
| 163 m_dcfManager->SetSifs (sifs); |
| 164 m_low->SetSifs (sifs); |
| 165 } |
| 166 |
| 167 void |
| 168 QstaWifiMac::SetEifsNoDifs (Time eifsNoDifs) |
| 169 { |
| 170 NS_LOG_FUNCTION (this << eifsNoDifs); |
| 171 m_dcfManager->SetEifsNoDifs (eifsNoDifs); |
| 172 m_eifsNoDifs = eifsNoDifs; |
| 173 } |
| 174 |
| 175 void |
| 176 QstaWifiMac::SetAckTimeout (Time ackTimeout) |
| 177 { |
| 178 m_low->SetAckTimeout (ackTimeout); |
| 179 } |
| 180 |
| 181 void |
| 182 QstaWifiMac::SetCtsTimeout (Time ctsTimeout) |
| 183 { |
| 184 m_low->SetCtsTimeout (ctsTimeout); |
| 185 } |
| 186 |
| 187 void |
| 188 QstaWifiMac::SetPifs (Time pifs) |
| 189 { |
| 190 m_low->SetPifs (pifs); |
| 191 } |
| 192 |
| 193 Time |
| 194 QstaWifiMac::GetSlot (void) const |
| 195 { |
| 196 return m_low->GetSlotTime (); |
| 197 } |
| 198 |
| 199 Time |
| 200 QstaWifiMac::GetSifs (void) const |
| 201 { |
| 202 return m_low->GetSifs (); |
| 203 } |
| 204 |
| 205 Time· |
| 206 QstaWifiMac::GetEifsNoDifs (void) const |
| 207 { |
| 208 return m_eifsNoDifs; |
| 209 } |
| 210 |
| 211 Time |
| 212 QstaWifiMac::GetAckTimeout (void) const |
| 213 { |
| 214 return m_low->GetAckTimeout (); |
| 215 } |
| 216 |
| 217 Time |
| 218 QstaWifiMac::GetCtsTimeout (void) const |
| 219 { |
| 220 return m_low->GetCtsTimeout (); |
| 221 } |
| 222 |
| 223 Time· |
| 224 QstaWifiMac::GetPifs (void) const |
| 225 { |
| 226 return m_low->GetPifs (); |
| 227 } |
| 228 |
| 229 void |
| 230 QstaWifiMac::SetWifiPhy (Ptr<WifiPhy> phy) |
| 231 { |
| 232 m_phy = phy; |
| 233 m_dcfManager->SetupPhyListener (phy); |
| 234 m_low->SetPhy (phy); |
| 235 } |
| 236 |
| 237 void |
| 238 QstaWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationM
anager) |
| 239 { |
| 240 m_stationManager = stationManager; |
| 241 m_queues[AC_VO]->SetWifiRemoteStationManager (stationManager); |
| 242 m_queues[AC_VI]->SetWifiRemoteStationManager (stationManager); |
| 243 m_queues[AC_BE]->SetWifiRemoteStationManager (stationManager); |
| 244 m_queues[AC_BK]->SetWifiRemoteStationManager (stationManager); |
| 245 m_low->SetWifiRemoteStationManager (stationManager); |
| 246 } |
| 247 |
| 248 void |
| 249 QstaWifiMac::SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac4
8Address> upCallback) |
| 250 { |
| 251 m_forwardUp = upCallback; |
| 252 } |
| 253 |
| 254 void |
| 255 QstaWifiMac::SetLinkUpCallback (Callback<void> linkUp) |
| 256 { |
| 257 m_linkUp = linkUp; |
| 258 } |
| 259 |
| 260 void |
| 261 QstaWifiMac::SetLinkDownCallback (Callback<void> linkDown) |
| 262 { |
| 263 m_linkDown = linkDown; |
| 264 } |
| 265 |
| 266 Mac48Address |
| 267 QstaWifiMac::GetAddress (void) const |
| 268 { |
| 269 return m_low->GetAddress (); |
| 270 } |
| 271 |
| 272 Ssid |
| 273 QstaWifiMac::GetSsid (void) const |
| 274 { |
| 275 return m_ssid; |
| 276 } |
| 277 |
| 278 Mac48Address |
| 279 QstaWifiMac::GetBssid () const |
| 280 { |
| 281 return m_low->GetBssid (); |
| 282 } |
| 283 |
| 284 void |
| 285 QstaWifiMac::SetAddress (Mac48Address address) |
| 286 { |
| 287 NS_LOG_FUNCTION (this << address); |
| 288 m_low->SetAddress (address); |
| 289 } |
| 290 |
| 291 void |
| 292 QstaWifiMac::SetSsid (Ssid ssid) |
| 293 { |
| 294 NS_LOG_FUNCTION (this << ssid); |
| 295 m_ssid = ssid; |
| 296 } |
| 297 |
| 298 void |
| 299 QstaWifiMac::SetMaxMissedBeacons (uint32_t missed) |
| 300 { |
| 301 NS_LOG_FUNCTION (this << missed); |
| 302 m_maxMissedBeacons = missed; |
| 303 } |
| 304 |
| 305 void |
| 306 QstaWifiMac::SetProbeRequestTimeout (Time timeout) |
| 307 { |
| 308 NS_LOG_FUNCTION (this << timeout); |
| 309 m_probeRequestTimeout = timeout; |
| 310 } |
| 311 |
| 312 void |
| 313 QstaWifiMac::SetAssocRequestTimeout (Time timeout) |
| 314 { |
| 315 NS_LOG_FUNCTION (this << timeout); |
| 316 m_assocRequestTimeout = timeout; |
| 317 } |
| 318 |
| 319 void |
| 320 QstaWifiMac::StartActiveAssociation (void) |
| 321 { |
| 322 NS_LOG_FUNCTION (this); |
| 323 TryToEnsureAssociated (); |
| 324 } |
| 325 |
| 326 Mac48Address |
| 327 QstaWifiMac::GetBroadcastBssid (void) |
| 328 { |
| 329 return Mac48Address::GetBroadcast (); |
| 330 } |
| 331 |
| 332 void· |
| 333 QstaWifiMac::SetBssid (Mac48Address bssid) |
| 334 { |
| 335 NS_LOG_FUNCTION (this << bssid); |
| 336 m_low->SetBssid (bssid); |
| 337 } |
| 338 |
| 339 void |
| 340 QstaWifiMac::SetActiveProbing (bool enable) |
| 341 { |
| 342 NS_LOG_FUNCTION (this << enable); |
| 343 if (enable) |
| 344 { |
| 345 TryToEnsureAssociated (); |
| 346 } |
| 347 else |
| 348 { |
| 349 m_probeRequestEvent.Cancel (); |
| 350 } |
| 351 } |
| 352 |
| 353 void |
| 354 QstaWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to) |
| 355 { |
| 356 NS_LOG_FUNCTION (this << packet << from << to); |
| 357 m_forwardUp (packet, from, to); |
| 358 } |
| 359 |
| 360 void |
| 361 QstaWifiMac::SendProbeRequest (void) |
| 362 { |
| 363 NS_LOG_FUNCTION (this); |
| 364 WifiMacHeader hdr; |
| 365 hdr.SetProbeReq (); |
| 366 hdr.SetAddr1 (GetBroadcastBssid ()); |
| 367 hdr.SetAddr2 (GetAddress ()); |
| 368 hdr.SetAddr3 (GetBroadcastBssid ()); |
| 369 hdr.SetDsNotFrom (); |
| 370 hdr.SetDsNotTo (); |
| 371 Ptr<Packet> packet = Create<Packet> (); |
| 372 MgtProbeRequestHeader probe; |
| 373 probe.SetSsid (GetSsid ()); |
| 374 probe.SetSupportedRates (GetSupportedRates ()); |
| 375 packet->AddHeader (probe); |
| 376 |
| 377 /* Which is correct queue for management frames ? */ |
| 378 m_queues[AC_VO]->Queue (packet, hdr); |
| 379 |
| 380 m_probeRequestEvent = Simulator::Schedule (m_probeRequestTimeout, |
| 381 &QstaWifiMac::ProbeRequestTimeout,
this); |
| 382 } |
| 383 |
| 384 void |
| 385 QstaWifiMac::SendAssociationRequest (void) |
| 386 { |
| 387 NS_LOG_FUNCTION (this << GetBssid ()); |
| 388 WifiMacHeader hdr; |
| 389 hdr.SetAssocReq (); |
| 390 hdr.SetAddr1 (GetBssid ()); |
| 391 hdr.SetAddr2 (GetAddress ()); |
| 392 hdr.SetAddr3 (GetBssid ()); |
| 393 hdr.SetDsNotFrom (); |
| 394 hdr.SetDsNotTo (); |
| 395 Ptr<Packet> packet = Create<Packet> (); |
| 396 MgtAssocRequestHeader assoc; |
| 397 assoc.SetSsid (GetSsid ()); |
| 398 assoc.SetSupportedRates (GetSupportedRates ()); |
| 399 packet->AddHeader (assoc); |
| 400 ·· |
| 401 /* Which is correct queue for management frames ? */ |
| 402 m_queues[AC_VO]->Queue (packet, hdr); |
| 403 |
| 404 m_assocRequestEvent = Simulator::Schedule (m_assocRequestTimeout, |
| 405 &QstaWifiMac::AssocRequestTimeout,
this); |
| 406 } |
| 407 |
| 408 void |
| 409 QstaWifiMac::TryToEnsureAssociated (void) |
| 410 { |
| 411 NS_LOG_FUNCTION (this); |
| 412 switch (m_state) { |
| 413 case ASSOCIATED: |
| 414 return; |
| 415 break; |
| 416 case WAIT_PROBE_RESP: |
| 417 /* we have sent a probe request earlier so we |
| 418 do not need to re-send a probe request immediately. |
| 419 We just need to wait until probe-request-timeout |
| 420 or until we get a probe response |
| 421 */ |
| 422 break; |
| 423 case BEACON_MISSED: |
| 424 /* we were associated but we missed a bunch of beacons |
| 425 * so we should assume we are not associated anymore. |
| 426 * We try to initiate a probe request now. |
| 427 */ |
| 428 m_linkDown (); |
| 429 m_state = WAIT_PROBE_RESP; |
| 430 SendProbeRequest (); |
| 431 break; |
| 432 case WAIT_ASSOC_RESP: |
| 433 /* we have sent an assoc request so we do not need to |
| 434 re-send an assoc request right now. We just need to |
| 435 wait until either assoc-request-timeout or until |
| 436 we get an assoc response. |
| 437 */ |
| 438 break; |
| 439 case REFUSED: |
| 440 /* we have sent an assoc request and received a negative |
| 441 assoc resp. We wait until someone restarts an· |
| 442 association with a given ssid. |
| 443 */ |
| 444 break; |
| 445 } |
| 446 } |
| 447 |
| 448 void |
| 449 QstaWifiMac::AssocRequestTimeout (void) |
| 450 { |
| 451 NS_LOG_FUNCTION (this); |
| 452 m_state = WAIT_ASSOC_RESP; |
| 453 SendAssociationRequest (); |
| 454 } |
| 455 |
| 456 void |
| 457 QstaWifiMac::ProbeRequestTimeout (void) |
| 458 { |
| 459 NS_LOG_FUNCTION (this); |
| 460 m_state = WAIT_PROBE_RESP; |
| 461 SendProbeRequest (); |
| 462 } |
| 463 |
| 464 void |
| 465 QstaWifiMac::MissedBeacons (void) |
| 466 { |
| 467 NS_LOG_FUNCTION (this); |
| 468 if (m_beaconWatchdogEnd > Simulator::Now ()) |
| 469 { |
| 470 m_beaconWatchdog = Simulator::Schedule (m_beaconWatchdogEnd - Simulator::N
ow (), |
| 471 &QstaWifiMac::MissedBeacons, this)
; |
| 472 return; |
| 473 } |
| 474 NS_LOG_DEBUG ("beacon missed"); |
| 475 m_state = BEACON_MISSED; |
| 476 TryToEnsureAssociated (); |
| 477 } |
| 478 |
| 479 void |
| 480 QstaWifiMac::RestartBeaconWatchdog (Time delay) |
| 481 { |
| 482 NS_LOG_FUNCTION (this << delay); |
| 483 m_beaconWatchdogEnd = std::max (Simulator::Now () + delay, m_beaconWatchdogEnd
); |
| 484 if (Simulator::GetDelayLeft (m_beaconWatchdog) < delay && |
| 485 m_beaconWatchdog.IsExpired ()) |
| 486 { |
| 487 NS_LOG_DEBUG ("really restart watchdog."); |
| 488 m_beaconWatchdog = Simulator::Schedule (delay, &QstaWifiMac::MissedBeacons
, this); |
| 489 } |
| 490 } |
| 491 |
| 492 bool |
| 493 QstaWifiMac::IsAssociated () |
| 494 { |
| 495 return (m_state == ASSOCIATED)?true:false; |
| 496 } |
| 497 |
| 498 void |
| 499 QstaWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to) |
| 500 { |
| 501 NS_LOG_FUNCTION (this << packet << to); |
| 502 if (!IsAssociated ())· |
| 503 { |
| 504 TryToEnsureAssociated (); |
| 505 return; |
| 506 } |
| 507 WifiMacHeader hdr; |
| 508 |
| 509 hdr.SetType (WIFI_MAC_QOSDATA); |
| 510 hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK); |
| 511 hdr.SetQosNoAmsdu (); |
| 512 hdr.SetQosNoEosp (); |
| 513 /* Transmission of multiple frames in the same· |
| 514 Txop is not supported for now */ |
| 515 hdr.SetQosTxopLimit (0); |
| 516 |
| 517 hdr.SetAddr1 (GetBssid ()); |
| 518 hdr.SetAddr2 (m_low->GetAddress ()); |
| 519 hdr.SetAddr3 (to); |
| 520 hdr.SetDsNotFrom (); |
| 521 hdr.SetDsTo (); |
| 522 ·· |
| 523 uint8_t tid = GetTidForPacket (packet); |
| 524 if (tid < 8) |
| 525 { |
| 526 hdr.SetQosTid (tid); |
| 527 AccessClass ac = MapTidToAc (tid); |
| 528 m_queues[ac]->Queue (packet, hdr); |
| 529 } |
| 530 else |
| 531 { |
| 532 //packet is considerated belonging to BestEffort Access Class (AC_BE) |
| 533 hdr.SetQosTid (0); |
| 534 m_queues[AC_BE]->Queue (packet, hdr); |
| 535 } |
| 536 } |
| 537 |
| 538 bool |
| 539 QstaWifiMac::SupportsSendFrom (void) const |
| 540 { |
| 541 return true; |
| 542 } |
| 543 |
| 544 void |
| 545 QstaWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr) |
| 546 { |
| 547 NS_LOG_FUNCTION (this); |
| 548 NS_ASSERT (!hdr->IsCtl ()); |
| 549 if (hdr->GetAddr1 () != GetAddress () && |
| 550 !hdr->GetAddr1 ().IsBroadcast ()) |
| 551 { |
| 552 NS_LOG_LOGIC ("packet is not for us"); |
| 553 } |
| 554 else if (hdr->IsData ()) |
| 555 { |
| 556 if (!IsAssociated ()) |
| 557 {· |
| 558 NS_LOG_LOGIC ("Received data frame while not associated: ignore"); |
| 559 return; |
| 560 } |
| 561 if (!(hdr->IsFromDs () && !hdr->IsToDs ())) |
| 562 { |
| 563 NS_LOG_LOGIC ("Received data frame not from the DS: ignore"); |
| 564 return; |
| 565 } |
| 566 if (hdr->GetAddr2 () != GetBssid ()) |
| 567 { |
| 568 NS_LOG_LOGIC ("Received data frame not from the BSS we are associated
with: ignore"); |
| 569 return; |
| 570 } |
| 571 if (hdr->GetAddr3 () != GetAddress ()) |
| 572 { |
| 573 if (hdr->IsQosData ()) |
| 574 { |
| 575 if (hdr->IsQosAmsdu ()) |
| 576 { |
| 577 NS_ASSERT (hdr->GetAddr3 () == GetBssid ()); |
| 578 DeaggregateAmsduAndForward (packet, hdr); |
| 579 packet = 0; |
| 580 } |
| 581 else |
| 582 { |
| 583 ForwardUp (packet, hdr->GetAddr3 (), hdr->GetAddr1 ()); |
| 584 } |
| 585 } |
| 586 else |
| 587 { |
| 588 ForwardUp (packet, hdr->GetAddr3 (), hdr->GetAddr1 ()); |
| 589 } |
| 590 } |
| 591 } |
| 592 else if (hdr->IsBeacon ())· |
| 593 { |
| 594 MgtBeaconHeader beacon; |
| 595 packet->RemoveHeader (beacon); |
| 596 bool goodBeacon = false; |
| 597 if (GetSsid ().IsBroadcast () || |
| 598 beacon.GetSsid ().IsEqual (GetSsid ())) |
| 599 { |
| 600 goodBeacon = true; |
| 601 } |
| 602 if (IsAssociated () && hdr->GetAddr3 () != GetBssid ()) |
| 603 { |
| 604 goodBeacon = false; |
| 605 } |
| 606 if (goodBeacon) |
| 607 { |
| 608 Time delay = MicroSeconds (beacon.GetBeaconIntervalUs () * m_maxMissed
Beacons); |
| 609 RestartBeaconWatchdog (delay); |
| 610 SetBssid (hdr->GetAddr3 ()); |
| 611 } |
| 612 if (goodBeacon && m_state == BEACON_MISSED)· |
| 613 { |
| 614 m_state = WAIT_ASSOC_RESP; |
| 615 SendAssociationRequest (); |
| 616 } |
| 617 } |
| 618 else if (hdr->IsProbeResp ())· |
| 619 { |
| 620 if (m_state == WAIT_PROBE_RESP)· |
| 621 { |
| 622 MgtProbeResponseHeader probeResp; |
| 623 packet->RemoveHeader (probeResp); |
| 624 if (!probeResp.GetSsid ().IsEqual (GetSsid ())) |
| 625 { |
| 626 //not a probe resp for our ssid. |
| 627 return; |
| 628 } |
| 629 SetBssid (hdr->GetAddr3 ()); |
| 630 Time delay = MicroSeconds (probeResp.GetBeaconIntervalUs () * m_maxMis
sedBeacons); |
| 631 RestartBeaconWatchdog (delay); |
| 632 if (m_probeRequestEvent.IsRunning ())· |
| 633 { |
| 634 m_probeRequestEvent.Cancel (); |
| 635 } |
| 636 m_state = WAIT_ASSOC_RESP; |
| 637 SendAssociationRequest (); |
| 638 } |
| 639 }· |
| 640 else if (hdr->IsAssocResp ())· |
| 641 { |
| 642 if (m_state == WAIT_ASSOC_RESP)· |
| 643 { |
| 644 MgtAssocResponseHeader assocResp; |
| 645 packet->RemoveHeader (assocResp); |
| 646 if (m_assocRequestEvent.IsRunning ())· |
| 647 { |
| 648 m_assocRequestEvent.Cancel (); |
| 649 } |
| 650 if (assocResp.GetStatusCode ().IsSuccess ())· |
| 651 { |
| 652 m_state = ASSOCIATED; |
| 653 NS_LOG_DEBUG ("assoc completed");· |
| 654 SupportedRates rates = assocResp.GetSupportedRates (); |
| 655 WifiRemoteStation *ap = m_stationManager->Lookup (hdr->GetAddr2 ()
); |
| 656 for (uint32_t i = 0; i < m_phy->GetNModes (); i++) |
| 657 { |
| 658 WifiMode mode = m_phy->GetMode (i); |
| 659 if (rates.IsSupportedRate (mode.GetDataRate ())) |
| 660 { |
| 661 ap->AddSupportedMode (mode); |
| 662 if (rates.IsBasicRate (mode.GetDataRate ())) |
| 663 { |
| 664 m_stationManager->AddBasicMode (mode); |
| 665 } |
| 666 } |
| 667 } |
| 668 if (!m_linkUp.IsNull ()) |
| 669 { |
| 670 m_linkUp (); |
| 671 } |
| 672 }· |
| 673 else· |
| 674 { |
| 675 NS_LOG_DEBUG ("assoc refused"); |
| 676 m_state = REFUSED; |
| 677 } |
| 678 } |
| 679 } |
| 680 } |
| 681 |
| 682 SupportedRates |
| 683 QstaWifiMac::GetSupportedRates (void) const |
| 684 { |
| 685 SupportedRates rates; |
| 686 for (uint32_t i = 0; i < m_phy->GetNModes (); i++) |
| 687 { |
| 688 WifiMode mode = m_phy->GetMode (i); |
| 689 rates.AddSupportedRate (mode.GetDataRate ()); |
| 690 } |
| 691 return rates; |
| 692 } |
| 693 |
| 694 uint8_t |
| 695 QstaWifiMac::GetTidForPacket (Ptr<const Packet> packet) |
| 696 { |
| 697 QosTag qos; |
| 698 uint8_t tid = 8; |
| 699 if (packet->FindFirstMatchingTag (qos)) |
| 700 { |
| 701 if (qos.Get() < 8) |
| 702 { |
| 703 tid = qos.Get (); |
| 704 } |
| 705 } |
| 706 return tid;···· |
| 707 } |
| 708 |
| 709 AccessClass |
| 710 QstaWifiMac::MapTidToAc (uint8_t tid) |
| 711 { |
| 712 /* This function maps UP (tid) in AC to determine correct queue */ |
| 713 switch (tid) { |
| 714 case 0 : |
| 715 return AC_BE; |
| 716 break; |
| 717 case 1 : |
| 718 return AC_BK; |
| 719 break; |
| 720 case 2 : |
| 721 return AC_BK; |
| 722 break; |
| 723 case 3 : |
| 724 return AC_BE; |
| 725 break; |
| 726 case 4 : |
| 727 return AC_VI; |
| 728 break; |
| 729 case 5 : |
| 730 return AC_VI; |
| 731 break; |
| 732 case 6 : |
| 733 return AC_VO; |
| 734 break; |
| 735 case 7 :· |
| 736 return AC_VO; |
| 737 break; |
| 738 } |
| 739 return AC_UNDEF; |
| 740 } |
| 741 |
| 742 void |
| 743 QstaWifiMac::DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket, WifiMacHe
ader const *hdr) |
| 744 { |
| 745 PacketSet packets = MsduAggregator::Deaggregate (aggregatedPacket); |
| 746 for (PacketSetCI i = packets.begin (); i != packets.end (); ++i) |
| 747 { |
| 748 ForwardUp ((*i).first, (*i).second.GetSourceAddr (), |
| 749 (*i).second.GetDestinationAddr ()); |
| 750 } |
| 751 } |
| 752 |
| 753 Ptr<EdcaTxopN> |
| 754 QstaWifiMac::GetVOQueue (void) const |
| 755 { |
| 756 return m_voEdca; |
| 757 } |
| 758 |
| 759 Ptr<EdcaTxopN> |
| 760 QstaWifiMac::GetVIQueue (void) const |
| 761 { |
| 762 return m_viEdca; |
| 763 } |
| 764 |
| 765 Ptr<EdcaTxopN> |
| 766 QstaWifiMac::GetBEQueue (void) const |
| 767 { |
| 768 return m_beEdca; |
| 769 } |
| 770 |
| 771 Ptr<EdcaTxopN> |
| 772 QstaWifiMac::GetBKQueue (void) const |
| 773 { |
| 774 return m_bkEdca; |
| 775 } |
| 776 |
| 777 void |
| 778 QstaWifiMac::SetVOQueue (Ptr<EdcaTxopN> voQueue) |
| 779 { |
| 780 m_voEdca = voQueue; |
| 781 m_queues.insert (std::make_pair(AC_VO, m_voEdca)); |
| 782 m_queues[AC_VO]->SetLow (m_low); |
| 783 m_queues[AC_VO]->SetManager (m_dcfManager); |
| 784 m_queues[AC_VO]->SetTypeOfStation (STA); |
| 785 m_queues[AC_VO]->SetTxMiddle (m_txMiddle); |
| 786 } |
| 787 |
| 788 void |
| 789 QstaWifiMac::SetVIQueue (Ptr<EdcaTxopN> viQueue) |
| 790 { |
| 791 m_viEdca = viQueue; |
| 792 m_queues.insert (std::make_pair(AC_VI, m_viEdca)); |
| 793 m_queues[AC_VI]->SetLow (m_low); |
| 794 m_queues[AC_VI]->SetManager (m_dcfManager); |
| 795 m_queues[AC_VI]->SetTypeOfStation (STA); |
| 796 m_queues[AC_VI]->SetTxMiddle (m_txMiddle); |
| 797 } |
| 798 |
| 799 void |
| 800 QstaWifiMac::SetBEQueue (Ptr<EdcaTxopN> beQueue) |
| 801 { |
| 802 m_beEdca = beQueue; |
| 803 m_queues.insert (std::make_pair(AC_BE, m_beEdca)); |
| 804 m_queues[AC_BE]->SetLow (m_low); |
| 805 m_queues[AC_BE]->SetManager (m_dcfManager); |
| 806 m_queues[AC_BE]->SetTypeOfStation (STA); |
| 807 m_queues[AC_BE]->SetTxMiddle (m_txMiddle); |
| 808 } |
| 809 |
| 810 void |
| 811 QstaWifiMac::SetBKQueue (Ptr<EdcaTxopN> bkQueue) |
| 812 { |
| 813 m_bkEdca = bkQueue; |
| 814 m_queues.insert (std::make_pair(AC_BK, m_bkEdca)); |
| 815 m_queues[AC_BK]->SetLow (m_low); |
| 816 m_queues[AC_BK]->SetManager (m_dcfManager); |
| 817 m_queues[AC_BK]->SetTypeOfStation (STA); |
| 818 m_queues[AC_BK]->SetTxMiddle (m_txMiddle); |
| 819 } |
| 820 |
| 821 } //namespace ns3 |
OLD | NEW |