src/devices/wifi/qap-wifi-mac.cc
changeset 4408 76a169b3db3d
child 4424 af26433b13bc
equal deleted inserted replaced
4407:ef566eeff84f 4408:76a169b3db3d
       
     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/assert.h"
       
    23 #include "ns3/log.h"
       
    24 #include "ns3/simulator.h"
       
    25 #include "ns3/string.h"
       
    26 #include "ns3/pointer.h"
       
    27 
       
    28 #include "qos-tag.h"
       
    29 #include "qap-wifi-mac.h"
       
    30 #include "dca-txop.h"
       
    31 #include "edca-txop-n.h"
       
    32 #include "wifi-phy.h"
       
    33 #include "dcf-manager.h"
       
    34 #include "mac-rx-middle.h"
       
    35 #include "mac-tx-middle.h"
       
    36 #include "mgt-headers.h"
       
    37 #include "mac-low.h"
       
    38 #include "amsdu-subframe-header.h"
       
    39 #include "msdu-aggregator.h"
       
    40 
       
    41 NS_LOG_COMPONENT_DEFINE ("QapWifiMac");
       
    42 
       
    43 namespace ns3 {
       
    44 
       
    45 NS_OBJECT_ENSURE_REGISTERED (QapWifiMac);
       
    46 
       
    47 TypeId
       
    48 QapWifiMac::GetTypeId (void)
       
    49 {
       
    50   static TypeId tid = TypeId ("ns3::QapWifiMac")
       
    51     .SetParent<WifiMac> ()
       
    52     .AddConstructor<QapWifiMac> ()
       
    53     .AddAttribute ("BeaconInterval", "Delay between two beacons",
       
    54                    TimeValue (Seconds (0.1)),
       
    55                    MakeTimeAccessor (&QapWifiMac::GetBeaconInterval,
       
    56                                      &QapWifiMac::SetBeaconInterval),
       
    57                    MakeTimeChecker ())
       
    58     .AddAttribute ("BeaconGeneration", "Whether or not beacons are generated.",
       
    59                    BooleanValue (true),
       
    60                    MakeBooleanAccessor (&QapWifiMac::SetBeaconGeneration,
       
    61                                         &QapWifiMac::GetBeaconGeneration),
       
    62                    MakeBooleanChecker ())
       
    63     .AddAttribute ("VO_EdcaTxopN",
       
    64                    "Queue that manages packets belonging to AC_VO access class",
       
    65                    PointerValue (),
       
    66                    MakePointerAccessor(&QapWifiMac::GetVOQueue,
       
    67                                        &QapWifiMac::SetVOQueue),
       
    68                    MakePointerChecker<EdcaTxopN> ())
       
    69     .AddAttribute ("VI_EdcaTxopN",
       
    70                    "Queue that manages packets belonging to AC_VI access class",
       
    71                    PointerValue (),
       
    72                    MakePointerAccessor(&QapWifiMac::GetVIQueue,
       
    73                                        &QapWifiMac::SetVIQueue),
       
    74                    MakePointerChecker<EdcaTxopN> ())
       
    75     .AddAttribute ("BE_EdcaTxopN",
       
    76                    "Queue that manages packets belonging to AC_BE access class",
       
    77                    PointerValue (),
       
    78                    MakePointerAccessor(&QapWifiMac::GetBEQueue,
       
    79                                        &QapWifiMac::SetBEQueue),
       
    80                    MakePointerChecker<EdcaTxopN> ())
       
    81     .AddAttribute ("BK_EdcaTxopN",
       
    82                    "Queue that manages packets belonging to AC_BK access class",
       
    83                    PointerValue (),
       
    84                    MakePointerAccessor(&QapWifiMac::GetBKQueue,
       
    85                                        &QapWifiMac::SetBKQueue),
       
    86                    MakePointerChecker<EdcaTxopN> ())
       
    87     ;  
       
    88   return tid;
       
    89 }
       
    90 
       
    91 QapWifiMac::QapWifiMac ()
       
    92 {
       
    93   NS_LOG_FUNCTION (this);
       
    94   m_rxMiddle = new MacRxMiddle ();
       
    95   m_rxMiddle->SetForwardCallback (MakeCallback (&QapWifiMac::Receive, this));
       
    96   
       
    97   m_txMiddle = new MacTxMiddle ();
       
    98 
       
    99   m_low = CreateObject<MacLow> ();
       
   100   m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
       
   101   
       
   102   m_dcfManager = new DcfManager ();
       
   103   m_dcfManager->SetupLowListener (m_low);
       
   104 
       
   105   m_beaconDca = CreateObject<DcaTxop> ();
       
   106   m_beaconDca->SetAifsn(1);
       
   107   m_beaconDca->SetMinCw(0);
       
   108   m_beaconDca->SetMaxCw(0);
       
   109   m_beaconDca->SetLow (m_low);
       
   110   m_beaconDca->SetManager (m_dcfManager);
       
   111 }
       
   112 
       
   113 QapWifiMac::~QapWifiMac ()
       
   114 {
       
   115   NS_LOG_FUNCTION (this);
       
   116 }
       
   117 
       
   118 void
       
   119 QapWifiMac::DoDispose ()
       
   120 {
       
   121   delete m_rxMiddle;
       
   122   m_rxMiddle = 0;
       
   123   delete m_txMiddle;
       
   124   m_txMiddle = 0;
       
   125   delete m_dcfManager;
       
   126   m_dcfManager = 0;
       
   127   m_low = 0;
       
   128   m_phy = 0;
       
   129   m_beaconDca = 0;
       
   130   m_beaconEvent.Cancel ();
       
   131   m_voEdca = 0;
       
   132   m_viEdca = 0;
       
   133   m_beEdca = 0;
       
   134   m_bkEdca = 0;
       
   135   m_stationManager = 0;
       
   136   std::map<AccessClass, Ptr<EdcaTxopN> >::iterator it = m_queues.begin ();
       
   137   for (;it != m_queues.end (); it++)
       
   138     {
       
   139       it->second = 0;
       
   140     }
       
   141   WifiMac::DoDispose ();
       
   142 }
       
   143 
       
   144 void
       
   145 QapWifiMac::SetBeaconGeneration (bool enable)
       
   146 {
       
   147   NS_LOG_FUNCTION (this << enable);
       
   148   if (enable)
       
   149     {
       
   150       m_beaconEvent = Simulator::ScheduleNow (&QapWifiMac::SendOneBeacon, this);
       
   151     }
       
   152   else
       
   153     {
       
   154       m_beaconEvent.Cancel ();
       
   155     }
       
   156 }
       
   157 
       
   158 bool
       
   159 QapWifiMac::GetBeaconGeneration (void) const
       
   160 {
       
   161   return m_beaconEvent.IsRunning ();
       
   162 }
       
   163 
       
   164 Time
       
   165 QapWifiMac::GetBeaconInterval (void) const
       
   166 {
       
   167   return m_beaconInterval;
       
   168 }
       
   169 
       
   170 void 
       
   171 QapWifiMac::SetSlot (Time slotTime)
       
   172 {
       
   173   NS_LOG_FUNCTION (this << slotTime);
       
   174   m_dcfManager->SetSlot (slotTime);
       
   175   m_low->SetSlotTime (slotTime);
       
   176 }
       
   177 
       
   178 void 
       
   179 QapWifiMac::SetSifs (Time sifs)
       
   180 {
       
   181   NS_LOG_FUNCTION (this << sifs);
       
   182   m_dcfManager->SetSifs (sifs);
       
   183   m_low->SetSifs (sifs);
       
   184 }
       
   185 
       
   186 void 
       
   187 QapWifiMac::SetEifsNoDifs (Time eifsNoDifs)
       
   188 {
       
   189   NS_LOG_FUNCTION (this << eifsNoDifs);
       
   190   m_dcfManager->SetEifsNoDifs (eifsNoDifs);
       
   191   m_eifsNoDifs = eifsNoDifs;
       
   192 }
       
   193 
       
   194 void 
       
   195 QapWifiMac::SetAckTimeout (Time ackTimeout)
       
   196 {
       
   197   m_low->SetAckTimeout (ackTimeout);
       
   198 }
       
   199 
       
   200 void 
       
   201 QapWifiMac::SetCtsTimeout (Time ctsTimeout)
       
   202 {
       
   203   m_low->SetCtsTimeout (ctsTimeout);
       
   204 }
       
   205 
       
   206 void 
       
   207 QapWifiMac::SetPifs (Time pifs)
       
   208 {
       
   209   m_low->SetPifs (pifs);
       
   210 }
       
   211 
       
   212 Time 
       
   213 QapWifiMac::GetSlot (void) const
       
   214 {
       
   215   return m_low->GetSlotTime ();
       
   216 }
       
   217 
       
   218 Time 
       
   219 QapWifiMac::GetSifs (void) const
       
   220 {
       
   221   return m_low->GetSifs ();
       
   222 }
       
   223 
       
   224 Time 
       
   225 QapWifiMac::GetEifsNoDifs (void) const
       
   226 {
       
   227   return m_eifsNoDifs;
       
   228 }
       
   229 
       
   230 Time 
       
   231 QapWifiMac::GetAckTimeout (void) const
       
   232 {
       
   233   return m_low->GetAckTimeout ();
       
   234 }
       
   235 
       
   236 Time 
       
   237 QapWifiMac::GetCtsTimeout (void) const
       
   238 {
       
   239   return m_low->GetCtsTimeout ();
       
   240 }
       
   241 
       
   242 Time 
       
   243 QapWifiMac::GetPifs (void) const
       
   244 {
       
   245   return m_low->GetPifs ();
       
   246 }
       
   247 
       
   248 void 
       
   249 QapWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
       
   250 {
       
   251   NS_LOG_FUNCTION (this << phy);
       
   252   m_phy = phy;
       
   253   m_dcfManager->SetupPhyListener (phy);
       
   254   m_low->SetPhy (phy);
       
   255 }
       
   256 
       
   257 void
       
   258 QapWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
       
   259 {
       
   260   NS_LOG_FUNCTION (this << stationManager);
       
   261   m_stationManager = stationManager;
       
   262   m_voEdca->SetWifiRemoteStationManager (stationManager);
       
   263   m_viEdca->SetWifiRemoteStationManager (stationManager);
       
   264   m_beEdca->SetWifiRemoteStationManager (stationManager);
       
   265   m_bkEdca->SetWifiRemoteStationManager (stationManager);
       
   266   m_beaconDca->SetWifiRemoteStationManager (stationManager);
       
   267   m_low->SetWifiRemoteStationManager (stationManager);
       
   268 }
       
   269 
       
   270 void 
       
   271 QapWifiMac::SetForwardUpCallback (Callback<void, Ptr<Packet>, Mac48Address, Mac48Address> upCallback)
       
   272 {
       
   273   NS_LOG_FUNCTION (this);
       
   274   m_forwardUp = upCallback;
       
   275 }
       
   276 
       
   277 void
       
   278 QapWifiMac::SetLinkUpCallback (Callback<void> linkUp)
       
   279 {
       
   280   NS_LOG_FUNCTION (this);
       
   281   if (!linkUp.IsNull ())
       
   282     {
       
   283       linkUp ();
       
   284     }
       
   285 }
       
   286 
       
   287 void 
       
   288 QapWifiMac::SetLinkDownCallback (Callback<void> linkDown)
       
   289 {
       
   290   NS_LOG_FUNCTION (this);
       
   291 }
       
   292 
       
   293 Mac48Address
       
   294 QapWifiMac::GetAddress () const
       
   295 {
       
   296   return m_low->GetAddress ();
       
   297 }
       
   298 
       
   299 Ssid 
       
   300 QapWifiMac::GetSsid (void) const
       
   301 {
       
   302   return m_ssid;
       
   303 }
       
   304 
       
   305 void
       
   306 QapWifiMac::SetAddress (Mac48Address address)
       
   307 {
       
   308   NS_LOG_FUNCTION (address);
       
   309   m_low->SetAddress (address);
       
   310   m_low->SetBssid (address);
       
   311 }
       
   312 
       
   313 void
       
   314 QapWifiMac::SetSsid (Ssid ssid)
       
   315 {
       
   316   NS_LOG_FUNCTION (this << ssid);
       
   317   m_ssid = ssid;
       
   318 }
       
   319 
       
   320 Mac48Address 
       
   321 QapWifiMac::GetBssid (void) const
       
   322 {
       
   323   return m_low->GetBssid ();
       
   324 }
       
   325 
       
   326 void
       
   327 QapWifiMac::SetBeaconInterval (Time interval)
       
   328 {
       
   329   NS_LOG_FUNCTION (this << interval);
       
   330   m_beaconInterval = interval;
       
   331 }
       
   332 
       
   333 void
       
   334 QapWifiMac::StartBeaconing (void)
       
   335 {
       
   336   NS_LOG_FUNCTION (this);
       
   337   SendOneBeacon ();
       
   338 }
       
   339 
       
   340 void
       
   341 QapWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to)
       
   342 {
       
   343   NS_LOG_FUNCTION (this << packet << from);
       
   344   m_forwardUp (packet, from, to);
       
   345 }
       
   346 
       
   347 void
       
   348 QapWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to)
       
   349 {
       
   350   /* For now Qos AP sends only Qos frame. In the future it should be able to 
       
   351      send frames also to Non-Qos Stas.
       
   352    */
       
   353   NS_LOG_FUNCTION (this << packet << from << to);
       
   354   WifiMacHeader hdr;
       
   355   hdr.SetType (WIFI_MAC_QOSDATA);
       
   356   hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
       
   357   hdr.SetQosNoEosp ();
       
   358   hdr.SetQosNoAmsdu ();
       
   359   /* Transmission of multiple frames in the same 
       
   360      Txop is not supported for now */
       
   361   hdr.SetQosTxopLimit (0);
       
   362 
       
   363   hdr.SetAddr1 (to);
       
   364   hdr.SetAddr2 (GetAddress ());
       
   365   hdr.SetAddr3 (from);
       
   366   hdr.SetDsFrom ();
       
   367   hdr.SetDsNotTo ();
       
   368   
       
   369   uint8_t tid = QosUtilsGetTidForPacket (packet);
       
   370   if (tid < 8)
       
   371     {
       
   372       hdr.SetQosTid (tid);
       
   373       AccessClass ac = QosUtilsMapTidToAc (tid);
       
   374       m_queues[ac]->Queue (packet, hdr);
       
   375     }
       
   376   else
       
   377     {
       
   378       //packet is considerated belonging to BestEffort AC
       
   379       hdr.SetQosTid (0);
       
   380       m_queues[AC_BE]->Queue (packet, hdr);
       
   381     }
       
   382 }
       
   383 
       
   384 void
       
   385 QapWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to,
       
   386                          WifiMacHeader const *oldHdr)
       
   387 {
       
   388   /* For now Qos AP sends only Qos frame. In the future it should be able to 
       
   389      send frames also to Non-Qos Stas.
       
   390    */
       
   391   NS_LOG_FUNCTION (this << packet << from << to);
       
   392   NS_ASSERT (oldHdr->IsQosData ());
       
   393   WifiMacHeader hdr;
       
   394   hdr.SetType (WIFI_MAC_QOSDATA);
       
   395   hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
       
   396   hdr.SetQosNoEosp ();
       
   397   hdr.SetQosNoAmsdu ();
       
   398   /* Transmission of multiple frames in the same 
       
   399      Txop is not supported for now */
       
   400   hdr.SetQosTxopLimit (0);
       
   401   hdr.SetQosTid (oldHdr->GetQosTid ());
       
   402 
       
   403   hdr.SetAddr1 (to);
       
   404   hdr.SetAddr2 (GetAddress ());
       
   405   hdr.SetAddr3 (from);
       
   406   hdr.SetDsFrom ();
       
   407   hdr.SetDsNotTo ();
       
   408 
       
   409   AccessClass ac = QosUtilsMapTidToAc (oldHdr->GetQosTid ());
       
   410   m_queues[ac]->Queue (packet, hdr);
       
   411 }
       
   412 
       
   413 void
       
   414 QapWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from)
       
   415 {
       
   416   NS_LOG_FUNCTION (this << packet << from << to);
       
   417   ForwardDown (packet, from, to);
       
   418 }
       
   419 
       
   420 void 
       
   421 QapWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
       
   422 {
       
   423   NS_LOG_FUNCTION (this << packet << to);
       
   424   ForwardDown (packet, m_low->GetAddress (), to);
       
   425 }
       
   426 
       
   427 bool 
       
   428 QapWifiMac::SupportsSendFrom (void) const
       
   429 {
       
   430   return true;
       
   431 }
       
   432 
       
   433 SupportedRates
       
   434 QapWifiMac::GetSupportedRates (void) const
       
   435 {
       
   436   // send the set of supported rates and make sure that we indicate
       
   437   // the Basic Rate set in this set of supported rates.
       
   438   SupportedRates rates;
       
   439   for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
       
   440     {
       
   441       WifiMode mode = m_phy->GetMode (i);
       
   442       rates.AddSupportedRate (mode.GetDataRate ());
       
   443     }
       
   444   // set the basic rates
       
   445   for (uint32_t j = 0; j < m_stationManager->GetNBasicModes (); j++)
       
   446     {
       
   447       WifiMode mode = m_stationManager->GetBasicMode (j);
       
   448       rates.SetBasicRate (mode.GetDataRate ());
       
   449     }
       
   450   return rates; 
       
   451 }
       
   452 
       
   453 void
       
   454 QapWifiMac::SendProbeResp (Mac48Address to)
       
   455 {
       
   456   NS_LOG_FUNCTION (this << to);
       
   457   WifiMacHeader hdr;
       
   458   hdr.SetProbeResp ();
       
   459   hdr.SetAddr1 (to);
       
   460   hdr.SetAddr2 (GetAddress ());
       
   461   hdr.SetAddr3 (GetAddress ());
       
   462   hdr.SetDsNotFrom ();
       
   463   hdr.SetDsNotTo ();
       
   464   Ptr<Packet> packet = Create<Packet> ();
       
   465   MgtProbeResponseHeader probe;
       
   466   probe.SetSsid (GetSsid ());
       
   467   probe.SetSupportedRates (GetSupportedRates ());
       
   468   probe.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
       
   469   packet->AddHeader (probe);
       
   470 
       
   471   /* Which is correct queue for management frames ? */
       
   472   m_queues[AC_VO]->Queue (packet, hdr);
       
   473 }
       
   474 
       
   475 void
       
   476 QapWifiMac::SendAssocResp (Mac48Address to, bool success)
       
   477 {
       
   478   NS_LOG_FUNCTION (this << to << success);
       
   479   WifiMacHeader hdr;
       
   480   hdr.SetAssocResp ();
       
   481   hdr.SetAddr1 (to);
       
   482   hdr.SetAddr2 (GetAddress ());
       
   483   hdr.SetAddr3 (GetAddress ());
       
   484   hdr.SetDsNotFrom ();
       
   485   hdr.SetDsNotTo ();
       
   486   Ptr<Packet> packet = Create<Packet> ();
       
   487   MgtAssocResponseHeader assoc;
       
   488   StatusCode code;
       
   489   if (success)
       
   490     {
       
   491       code.SetSuccess ();
       
   492     }
       
   493   else
       
   494     {
       
   495       code.SetFailure ();
       
   496     }
       
   497   assoc.SetSupportedRates (GetSupportedRates ());
       
   498   assoc.SetStatusCode (code);
       
   499   packet->AddHeader (assoc);
       
   500   
       
   501   /* Which is correct queue for management frames ? */
       
   502   m_queues[AC_VO]->Queue (packet, hdr);
       
   503 }
       
   504 
       
   505 void
       
   506 QapWifiMac::SendOneBeacon (void)
       
   507 {
       
   508   NS_LOG_FUNCTION (this);
       
   509   WifiMacHeader hdr;
       
   510   hdr.SetBeacon ();
       
   511   hdr.SetAddr1 (Mac48Address::GetBroadcast ());
       
   512   hdr.SetAddr2 (GetAddress ());
       
   513   hdr.SetAddr3 (GetAddress ());
       
   514   hdr.SetDsNotFrom ();
       
   515   hdr.SetDsNotTo ();
       
   516   Ptr<Packet> packet = Create<Packet> ();
       
   517   MgtBeaconHeader beacon;
       
   518   beacon.SetSsid (GetSsid ());
       
   519   beacon.SetSupportedRates (GetSupportedRates ());
       
   520   beacon.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
       
   521   
       
   522   packet->AddHeader (beacon);
       
   523 
       
   524   m_beaconDca->Queue (packet, hdr);
       
   525   m_beaconEvent = Simulator::Schedule (m_beaconInterval, &QapWifiMac::SendOneBeacon, this);  
       
   526 }
       
   527 
       
   528 void
       
   529 QapWifiMac::TxOk (WifiMacHeader const &hdr)
       
   530 {
       
   531   NS_LOG_FUNCTION (this);
       
   532   WifiRemoteStation *station = m_stationManager->Lookup (hdr.GetAddr1 ());
       
   533   if (hdr.IsAssocResp () && 
       
   534       station->IsWaitAssocTxOk ()) 
       
   535     {
       
   536       NS_LOG_DEBUG ("associated with sta="<<hdr.GetAddr1 ());
       
   537       station->RecordGotAssocTxOk ();
       
   538     }
       
   539 }
       
   540 
       
   541 void
       
   542 QapWifiMac::TxFailed (WifiMacHeader const &hdr)
       
   543 {
       
   544   NS_LOG_FUNCTION (this);
       
   545   WifiRemoteStation *station = m_stationManager->Lookup (hdr.GetAddr1 ());
       
   546   if (hdr.IsAssocResp () && 
       
   547       station->IsWaitAssocTxOk ()) 
       
   548     {
       
   549       NS_LOG_DEBUG ("assoc failed with sta="<<hdr.GetAddr1 ());
       
   550       station->RecordGotAssocTxFailed ();
       
   551     }
       
   552 }
       
   553 
       
   554 void
       
   555 QapWifiMac::Receive (Ptr<Packet> packet, WifiMacHeader const *hdr)
       
   556 {
       
   557   NS_LOG_FUNCTION (this << packet << hdr);
       
   558 
       
   559   Mac48Address from = hdr->GetAddr2 ();
       
   560   WifiRemoteStation *fromStation = m_stationManager->Lookup (from);
       
   561   
       
   562   if (hdr->IsData ())
       
   563     {
       
   564       Mac48Address bssid = hdr->GetAddr1 ();
       
   565       if (!hdr->IsFromDs () && 
       
   566           hdr->IsToDs () &&
       
   567           bssid == GetAddress () &&
       
   568           fromStation->IsAssociated ())
       
   569         {
       
   570           Mac48Address to = hdr->GetAddr3 ();
       
   571           WifiRemoteStation *toStation = m_stationManager->Lookup (to);
       
   572           
       
   573           if (to == GetAddress ())
       
   574             {
       
   575               NS_LOG_DEBUG ("frame for me (Qap) from="<<from);
       
   576               if (hdr->IsQosData ())
       
   577                 {
       
   578                   if (hdr->IsQosAmsdu ())
       
   579                     {
       
   580                       NS_LOG_DEBUG ("Received A-MSDU from="<<from<<", size="<<packet->GetSize ());
       
   581                       DeaggregateAmsduAndForward (packet, hdr);
       
   582                       packet = 0;
       
   583                     }
       
   584                   else
       
   585                     {
       
   586                       ForwardUp (packet, from, bssid);
       
   587                     }
       
   588                 }
       
   589               else
       
   590                 {
       
   591                   ForwardUp (packet, from, bssid);
       
   592                 }
       
   593             }
       
   594           else if (to.IsBroadcast () ||
       
   595                    to.IsMulticast () ||
       
   596                    toStation->IsAssociated ())
       
   597             {
       
   598               NS_LOG_DEBUG ("forwarding frame from="<<from<<", to="<<to);
       
   599               Ptr<Packet> copy = packet->Copy ();
       
   600               ForwardDown (packet, from, to, hdr);
       
   601               ForwardUp (copy, from, to);
       
   602             }
       
   603           else
       
   604             {
       
   605               ForwardUp (packet, from, to);
       
   606             }
       
   607         }
       
   608       else if (hdr->IsFromDs () &&
       
   609                hdr->IsToDs ()) 
       
   610         {
       
   611           // this is an AP-to-AP frame
       
   612           // we ignore for now.
       
   613         }
       
   614       else 
       
   615         {
       
   616           // we can ignore these frames since 
       
   617           // they are not targeted at the AP
       
   618         }
       
   619     }
       
   620   else if (hdr->IsMgt ())
       
   621     {
       
   622       if (hdr->IsProbeReq ()) 
       
   623         {
       
   624           NS_ASSERT (hdr->GetAddr1 ().IsBroadcast ());
       
   625           SendProbeResp (hdr->GetAddr2 ());
       
   626         }
       
   627       else if (hdr->GetAddr1 () == GetAddress ()) 
       
   628         {
       
   629           if (hdr->IsAssocReq ()) 
       
   630             {
       
   631               // first, verify that the the station's supported
       
   632               // rate set is compatible with our Basic Rate set
       
   633               MgtAssocRequestHeader assocReq;
       
   634               packet->RemoveHeader (assocReq);
       
   635               SupportedRates rates = assocReq.GetSupportedRates ();
       
   636               bool problem = false;
       
   637               for (uint32_t i = 0; i < m_stationManager->GetNBasicModes (); i++)
       
   638                 {
       
   639                   WifiMode mode = m_stationManager->GetBasicMode (i);
       
   640                   if (!rates.IsSupportedRate (mode.GetDataRate ()))
       
   641                    {
       
   642                      problem = true;
       
   643                      break;
       
   644                    }
       
   645                 }
       
   646              if (problem)
       
   647                {
       
   648                  // one of the Basic Rate set mode is not
       
   649                  // supported by the station. So, we return an assoc
       
   650                  // response with an error status.
       
   651                  SendAssocResp (hdr->GetAddr2 (), false);
       
   652                }
       
   653              else
       
   654                {
       
   655                  // station supports all rates in Basic Rate Set.
       
   656                  // record all its supported modes in its associated WifiRemoteStation
       
   657                  for (uint32_t j = 0; j < m_phy->GetNModes (); j++)
       
   658                    {
       
   659                      WifiMode mode = m_phy->GetMode (j);
       
   660                      if (rates.IsSupportedRate (mode.GetDataRate ()))
       
   661                        {
       
   662                          fromStation->AddSupportedMode (mode);
       
   663                        }
       
   664                     }
       
   665                   fromStation->RecordWaitAssocTxOk ();
       
   666                   // send assoc response with success status.
       
   667                   SendAssocResp (hdr->GetAddr2 (), true);
       
   668                 }
       
   669             }
       
   670           else if (hdr->IsDisassociation ()) 
       
   671             {
       
   672               fromStation->RecordDisassociated ();
       
   673             } 
       
   674           else if (hdr->IsReassocReq ()) 
       
   675             {
       
   676               /* we don't support reassoc frames for now */
       
   677             } 
       
   678           else if (hdr->IsAuthentication () ||
       
   679                    hdr->IsDeauthentication ()) 
       
   680                  {
       
   681                    /*
       
   682                    */
       
   683                  } 
       
   684           else 
       
   685             {
       
   686               /* unknown mgt frame
       
   687               */
       
   688             }
       
   689         }
       
   690     }
       
   691 }
       
   692 
       
   693 void
       
   694 QapWifiMac::DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket, WifiMacHeader const *hdr)
       
   695 {
       
   696   DeaggregatedMsdus packets = MsduAggregator::Deaggregate (aggregatedPacket);
       
   697   for (DeaggregatedMsdusCI i = packets.begin (); i != packets.end (); ++i)
       
   698     {
       
   699       if ((*i).second.GetDestinationAddr () == GetAddress ())
       
   700         {
       
   701           ForwardUp ((*i).first, (*i).second.GetSourceAddr (),
       
   702                      (*i).second.GetDestinationAddr ());
       
   703         }
       
   704       else
       
   705         {
       
   706           Mac48Address from = (*i).second.GetSourceAddr ();
       
   707           Mac48Address to = (*i).second.GetDestinationAddr ();
       
   708           NS_LOG_DEBUG ("forwarding QoS frame from="<<from<<", to="<<to);
       
   709           ForwardDown ((*i).first, from, to, hdr);
       
   710         }
       
   711     }
       
   712 }
       
   713 
       
   714 Ptr<EdcaTxopN>
       
   715 QapWifiMac::GetVOQueue (void) const
       
   716 {
       
   717   return m_voEdca;
       
   718 }
       
   719 
       
   720 Ptr<EdcaTxopN>
       
   721 QapWifiMac::GetVIQueue (void) const
       
   722 {
       
   723   return m_viEdca;
       
   724 }
       
   725 
       
   726 Ptr<EdcaTxopN>
       
   727 QapWifiMac::GetBEQueue (void) const
       
   728 {
       
   729   return m_beEdca;
       
   730 }
       
   731 
       
   732 Ptr<EdcaTxopN>
       
   733 QapWifiMac::GetBKQueue (void) const
       
   734 {
       
   735   return m_bkEdca;
       
   736 }
       
   737 
       
   738 void
       
   739 QapWifiMac::SetVOQueue (Ptr<EdcaTxopN> voQueue)
       
   740 {
       
   741   m_voEdca = voQueue;
       
   742   m_queues.insert (std::make_pair(AC_VO, m_voEdca));
       
   743   m_queues[AC_VO]->SetLow (m_low);
       
   744   m_queues[AC_VO]->SetManager (m_dcfManager);
       
   745   m_queues[AC_VO]->SetTypeOfStation (AP);
       
   746   m_queues[AC_VO]->SetTxMiddle (m_txMiddle);
       
   747   m_queues[AC_VO]->SetTxOkCallback (MakeCallback (&QapWifiMac::TxOk, this));
       
   748   m_queues[AC_VO]->SetTxFailedCallback (MakeCallback (&QapWifiMac::TxFailed, this));
       
   749 }
       
   750 
       
   751 void
       
   752 QapWifiMac::SetVIQueue (Ptr<EdcaTxopN> viQueue)
       
   753 {
       
   754   m_viEdca = viQueue;
       
   755   m_queues.insert (std::make_pair(AC_VI, m_viEdca));
       
   756   m_queues[AC_VI]->SetLow (m_low);
       
   757   m_queues[AC_VI]->SetManager (m_dcfManager);
       
   758   m_queues[AC_VI]->SetTypeOfStation (AP);
       
   759   m_queues[AC_VI]->SetTxMiddle (m_txMiddle);
       
   760   m_queues[AC_VI]->SetTxOkCallback (MakeCallback (&QapWifiMac::TxOk, this));
       
   761   m_queues[AC_VI]->SetTxFailedCallback (MakeCallback (&QapWifiMac::TxFailed, this));
       
   762 }
       
   763 
       
   764 void
       
   765 QapWifiMac::SetBEQueue (Ptr<EdcaTxopN> beQueue)
       
   766 {
       
   767   m_beEdca = beQueue;
       
   768   m_queues.insert (std::make_pair(AC_BE, m_beEdca));
       
   769   m_queues[AC_BE]->SetLow (m_low);
       
   770   m_queues[AC_BE]->SetManager (m_dcfManager);
       
   771   m_queues[AC_BE]->SetTypeOfStation (AP);
       
   772   m_queues[AC_BE]->SetTxMiddle (m_txMiddle);
       
   773   m_queues[AC_BE]->SetTxOkCallback (MakeCallback (&QapWifiMac::TxOk, this));
       
   774   m_queues[AC_BE]->SetTxFailedCallback (MakeCallback (&QapWifiMac::TxFailed, this));
       
   775 }
       
   776 
       
   777 void
       
   778 QapWifiMac::SetBKQueue (Ptr<EdcaTxopN> bkQueue)
       
   779 {
       
   780   m_bkEdca = bkQueue;
       
   781   m_queues.insert (std::make_pair(AC_BK, m_bkEdca));
       
   782   m_queues[AC_BK]->SetLow (m_low);
       
   783   m_queues[AC_BK]->SetManager (m_dcfManager);
       
   784   m_queues[AC_BK]->SetTypeOfStation (AP);
       
   785   m_queues[AC_BK]->SetTxMiddle (m_txMiddle);
       
   786   m_queues[AC_BK]->SetTxOkCallback (MakeCallback (&QapWifiMac::TxOk, this));
       
   787   m_queues[AC_BK]->SetTxFailedCallback (MakeCallback (&QapWifiMac::TxFailed, this));
       
   788 }
       
   789 
       
   790 }  //namespace ns3