src/devices/wifi/nqap-wifi-mac.cc
changeset 2524 db72c0e7743e
parent 2350 0b54480c4fd1
child 2528 a527ec47b756
equal deleted inserted replaced
2523:58182a1561cc 2524:db72c0e7743e
       
     1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
       
     2 /*
       
     3  * Copyright (c) 2005,2006 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 #include "ns3/assert.h"
       
    21 #include "ns3/log.h"
       
    22 #include "ns3/simulator.h"
       
    23 #include "ns3/node.h"
       
    24 
       
    25 #include "nqap-wifi-mac.h"
       
    26 #include "dca-txop.h"
       
    27 #include "wifi-mac-header.h"
       
    28 #include "mgt-headers.h"
       
    29 #include "wifi-phy.h"
       
    30 #include "dcf-manager.h"
       
    31 #include "mac-rx-middle.h"
       
    32 #include "mac-low.h"
       
    33 
       
    34 NS_LOG_COMPONENT_DEFINE ("NqapWifiMac");
       
    35 
       
    36 #define TRACE(x) \
       
    37   NS_LOG_DEBUG(Simulator::Now () << " " << GetAddress () << " " << x);
       
    38 
       
    39 namespace ns3 {
       
    40 
       
    41 NS_OBJECT_ENSURE_REGISTERED (NqapWifiMac);
       
    42 
       
    43 TypeId 
       
    44 NqapWifiMac::GetTypeId (void)
       
    45 {
       
    46   static TypeId tid = TypeId ("NqapWifiMac")
       
    47     .SetParent<WifiMac> ()
       
    48     .AddConstructor<NqapWifiMac> ()
       
    49     .AddAttribute ("BeaconInterval", "Delay between two beacons",
       
    50                    Seconds (1.0),
       
    51                    MakeTimeAccessor (&NqapWifiMac::m_beaconInterval),
       
    52                    MakeTimeChecker ())
       
    53     ;
       
    54   return tid;
       
    55 }
       
    56 
       
    57 NqapWifiMac::NqapWifiMac ()
       
    58 {
       
    59   m_dcfManager = new DcfManager ();
       
    60 
       
    61   m_rxMiddle = new MacRxMiddle ();
       
    62   m_rxMiddle->SetForwardCallback (MakeCallback (&NqapWifiMac::Receive, this));
       
    63 
       
    64   m_low = new MacLow ();
       
    65   m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
       
    66 
       
    67   m_dca = CreateObject<DcaTxop> ();
       
    68   m_dca->SetLow (m_low);
       
    69   m_dca->SetManager (m_dcfManager);
       
    70   m_dca->SetTxOkCallback (MakeCallback (&NqapWifiMac::TxOk, this));
       
    71   m_dca->SetTxFailedCallback (MakeCallback (&NqapWifiMac::TxFailed, this));
       
    72 
       
    73   m_beaconDca = CreateObject<DcaTxop> ();
       
    74   m_beaconDca->SetLow (m_low);
       
    75   m_beaconDca->SetManager (m_dcfManager);
       
    76 }
       
    77 NqapWifiMac::~NqapWifiMac ()
       
    78 {}
       
    79 
       
    80 void
       
    81 NqapWifiMac::DoDispose (void)
       
    82 {
       
    83   delete m_rxMiddle;
       
    84   delete m_low;
       
    85   m_rxMiddle = 0;
       
    86   m_low = 0;
       
    87   m_phy = 0;
       
    88   m_dca = 0;
       
    89   m_beaconDca = 0;
       
    90   WifiMac::DoDispose ();
       
    91 }
       
    92 
       
    93 
       
    94 void 
       
    95 NqapWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
       
    96 {
       
    97   m_phy = phy;
       
    98 }
       
    99 void 
       
   100 NqapWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
       
   101 {
       
   102   m_stationManager = stationManager;
       
   103 }
       
   104 void 
       
   105 NqapWifiMac::SetForwardUpCallback (Callback<void,Ptr<Packet>, const Mac48Address &> upCallback)
       
   106 {
       
   107   m_upCallback = upCallback;
       
   108 }
       
   109 void 
       
   110 NqapWifiMac::SetLinkUpCallback (Callback<void> linkUp)
       
   111 {
       
   112 
       
   113 }
       
   114 void 
       
   115 NqapWifiMac::SetLinkDownCallback (Callback<void> linkDown)
       
   116 {
       
   117 
       
   118 }
       
   119 Mac48Address 
       
   120 NqapWifiMac::GetAddress (void) const
       
   121 {
       
   122   return m_address;
       
   123 }
       
   124 Ssid 
       
   125 NqapWifiMac::GetSsid (void) const
       
   126 {
       
   127   return m_ssid;
       
   128 }
       
   129 Mac48Address 
       
   130 NqapWifiMac::GetBssid (void) const
       
   131 {
       
   132   return m_address;
       
   133 }
       
   134 void 
       
   135 NqapWifiMac::SetAddress (Mac48Address address)
       
   136 {
       
   137   m_address = address;
       
   138 }
       
   139 void 
       
   140 NqapWifiMac::SetSsid (Ssid ssid)
       
   141 {
       
   142   m_ssid = ssid;
       
   143 }
       
   144 
       
   145 
       
   146 void 
       
   147 NqapWifiMac::SetBeaconInterval (Time interval)
       
   148 {
       
   149   m_beaconInterval = interval;
       
   150 }
       
   151 void
       
   152 NqapWifiMac::StartBeaconing (void)
       
   153 {
       
   154   SendOneBeacon ();
       
   155 }
       
   156 void 
       
   157 NqapWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address from)
       
   158 {
       
   159   m_upCallback (packet, from);
       
   160 }
       
   161 void 
       
   162 NqapWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to)
       
   163 {
       
   164   WifiMacHeader hdr;
       
   165   hdr.SetTypeData ();
       
   166   hdr.SetAddr1 (to);
       
   167   hdr.SetAddr2 (GetAddress ());
       
   168   hdr.SetAddr3 (from);
       
   169   hdr.SetDsFrom ();
       
   170   hdr.SetDsNotTo ();
       
   171   m_dca->Queue (packet, hdr);  
       
   172 }
       
   173 void 
       
   174 NqapWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
       
   175 {
       
   176   ForwardDown (packet, GetAddress (), to);
       
   177 }
       
   178 SupportedRates
       
   179 NqapWifiMac::GetSupportedRates (void) const
       
   180 {
       
   181   // send the set of supported rates and make sure that we indicate
       
   182   // the Basic Rate set in this set of supported rates.
       
   183   SupportedRates rates;
       
   184   for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
       
   185     {
       
   186       WifiMode mode = m_phy->GetMode (i);
       
   187       rates.AddSupportedRate (mode.GetDataRate ());
       
   188     }
       
   189   // set the basic rates
       
   190   for (uint32_t j = 0; j < m_stationManager->GetNBasicModes (); j++)
       
   191     {
       
   192       WifiMode mode = m_stationManager->GetBasicMode (j);
       
   193       rates.SetBasicRate (mode.GetDataRate ());
       
   194     }
       
   195   return rates;
       
   196 }
       
   197 void
       
   198 NqapWifiMac::SendProbeResp (Mac48Address to)
       
   199 {
       
   200   TRACE ("send probe response to="<<to);
       
   201   WifiMacHeader hdr;
       
   202   hdr.SetProbeResp ();
       
   203   hdr.SetAddr1 (to);
       
   204   hdr.SetAddr2 (GetAddress ());
       
   205   hdr.SetAddr3 (GetAddress ());
       
   206   hdr.SetDsNotFrom ();
       
   207   hdr.SetDsNotTo ();
       
   208   Ptr<Packet> packet = Create<Packet> ();
       
   209   MgtProbeResponseHeader probe;
       
   210   probe.SetSsid (GetSsid ());
       
   211   probe.SetSupportedRates (GetSupportedRates ());
       
   212   probe.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
       
   213   packet->AddHeader (probe);
       
   214 
       
   215   m_dca->Queue (packet, hdr);
       
   216 }
       
   217 void
       
   218 NqapWifiMac::SendAssocResp (Mac48Address to, bool success)
       
   219 {
       
   220   TRACE ("send assoc response to="<<to);
       
   221   WifiMacHeader hdr;
       
   222   hdr.SetAssocResp ();
       
   223   hdr.SetAddr1 (to);
       
   224   hdr.SetAddr2 (GetAddress ());
       
   225   hdr.SetAddr3 (GetAddress ());
       
   226   hdr.SetDsNotFrom ();
       
   227   hdr.SetDsNotTo ();
       
   228   Ptr<Packet> packet = Create<Packet> ();
       
   229   MgtAssocResponseHeader assoc;
       
   230   StatusCode code;
       
   231   if (success)
       
   232     {
       
   233       code.SetSuccess ();
       
   234     }
       
   235   else
       
   236     {
       
   237       code.SetFailure ();
       
   238     }
       
   239   assoc.SetSupportedRates (GetSupportedRates ());
       
   240   assoc.SetStatusCode (code);
       
   241   packet->AddHeader (assoc);
       
   242   
       
   243   m_dca->Queue (packet, hdr);
       
   244 }
       
   245 void
       
   246 NqapWifiMac::SendOneBeacon (void)
       
   247 {
       
   248   TRACE ("send beacon to="<<Mac48Address::GetBroadcast ());
       
   249   WifiMacHeader hdr;
       
   250   hdr.SetBeacon ();
       
   251   hdr.SetAddr1 (Mac48Address::GetBroadcast ());
       
   252   hdr.SetAddr2 (GetAddress ());
       
   253   hdr.SetAddr3 (GetAddress ());
       
   254   hdr.SetDsNotFrom ();
       
   255   hdr.SetDsNotTo ();
       
   256   Ptr<Packet> packet = Create<Packet> ();
       
   257   MgtBeaconHeader beacon;
       
   258   beacon.SetSsid (GetSsid ());
       
   259   beacon.SetSupportedRates (GetSupportedRates ());
       
   260   beacon.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
       
   261   packet->AddHeader (beacon);
       
   262 
       
   263   m_beaconDca->Queue (packet, hdr);
       
   264   Simulator::Schedule (m_beaconInterval, &NqapWifiMac::SendOneBeacon, this);
       
   265 }
       
   266 void 
       
   267 NqapWifiMac::TxOk (WifiMacHeader const &hdr)
       
   268 {
       
   269   WifiRemoteStation *station = m_stationManager->Lookup (hdr.GetAddr1 ());
       
   270   if (hdr.IsAssocResp () && 
       
   271       station->IsWaitAssocTxOk ()) 
       
   272     {
       
   273       TRACE ("associated with sta="<<hdr.GetAddr1 ());
       
   274       station->RecordGotAssocTxOk ();
       
   275     }
       
   276 }
       
   277 void 
       
   278 NqapWifiMac::TxFailed (WifiMacHeader const &hdr)
       
   279 {
       
   280   WifiRemoteStation *station = m_stationManager->Lookup (hdr.GetAddr1 ());
       
   281   if (hdr.IsAssocResp () && 
       
   282       station->IsWaitAssocTxOk ()) 
       
   283     {
       
   284       TRACE ("assoc failed with sta="<<hdr.GetAddr1 ());
       
   285       station->RecordGotAssocTxFailed ();
       
   286     }
       
   287 }
       
   288 void 
       
   289 NqapWifiMac::Receive (Ptr<Packet> packet, WifiMacHeader const *hdr)
       
   290 {
       
   291   WifiRemoteStation *station = m_stationManager->Lookup (hdr->GetAddr2 ());
       
   292 
       
   293   if (hdr->IsData ()) 
       
   294     {
       
   295       if (!hdr->IsFromDs () && 
       
   296           hdr->IsToDs () &&
       
   297           hdr->GetAddr1 () == GetAddress () &&
       
   298           station->IsAssociated ()) 
       
   299         {
       
   300           if (hdr->GetAddr3 () == GetAddress ()) 
       
   301             {
       
   302               TRACE ("frame for me from="<<hdr->GetAddr2 ());
       
   303               ForwardUp (packet, hdr->GetAddr2 ());
       
   304             } 
       
   305           else 
       
   306             {
       
   307               TRACE ("forwarding frame from="<<hdr->GetAddr2 ()<<", to="<<hdr->GetAddr3 ());
       
   308               Ptr<Packet> copy = packet->Copy ();
       
   309               ForwardDown (packet,
       
   310                            hdr->GetAddr2 (), 
       
   311                            hdr->GetAddr3 ());
       
   312               ForwardUp (copy, hdr->GetAddr2 ());
       
   313             }
       
   314         } 
       
   315       else if (hdr->IsFromDs () &&
       
   316                hdr->IsToDs ()) 
       
   317         {
       
   318           // this is an AP-to-AP frame
       
   319           // we ignore for now.
       
   320         } 
       
   321       else 
       
   322         {
       
   323           // we can ignore these frames since 
       
   324           // they are not targeted at the AP
       
   325         }
       
   326     } 
       
   327   else if (hdr->IsMgt ()) 
       
   328     {
       
   329       if (hdr->IsProbeReq ()) 
       
   330         {
       
   331           NS_ASSERT (hdr->GetAddr1 ().IsBroadcast ());
       
   332           SendProbeResp (hdr->GetAddr2 ());
       
   333         } 
       
   334       else if (hdr->GetAddr1 () == GetAddress ()) 
       
   335         {
       
   336           if (hdr->IsAssocReq ()) 
       
   337             {
       
   338               // first, verify that the the station's supported
       
   339               // rate set is compatible with our Basic Rate set
       
   340               MgtAssocRequestHeader assocReq;
       
   341               packet->RemoveHeader (assocReq);
       
   342               SupportedRates rates = assocReq.GetSupportedRates ();
       
   343               bool problem = false;
       
   344               for (uint32_t i = 0; i < m_stationManager->GetNBasicModes (); i++)
       
   345                 {
       
   346                   WifiMode mode = m_stationManager->GetBasicMode (i);
       
   347                   if (!rates.IsSupportedRate (mode.GetDataRate ()))
       
   348                     {
       
   349                       problem = true;
       
   350                       break;
       
   351                     }
       
   352                 }
       
   353               if (problem)
       
   354                 {
       
   355                   // one of the Basic Rate set mode is not
       
   356                   // supported by the station. So, we return an assoc
       
   357                   // response with an error status.
       
   358                   SendAssocResp (hdr->GetAddr2 (), false);
       
   359                 }
       
   360               else
       
   361                 {
       
   362                   // station supports all rates in Basic Rate Set.
       
   363                   // record all its supported modes in its associated WifiRemoteStation
       
   364                   for (uint32_t j = 0; j < m_phy->GetNModes (); j++)
       
   365                     {
       
   366                       WifiMode mode = m_phy->GetMode (j);
       
   367                       if (rates.IsSupportedRate (mode.GetDataRate ()))
       
   368                         {
       
   369                           station->AddSupportedMode (mode);
       
   370                         }
       
   371                     }
       
   372                   station->RecordWaitAssocTxOk ();
       
   373                   // send assoc response with success status.
       
   374                   SendAssocResp (hdr->GetAddr2 (), true);
       
   375                 }
       
   376             } 
       
   377           else if (hdr->IsDisassociation ()) 
       
   378             {
       
   379               station->RecordDisassociated ();
       
   380             } 
       
   381           else if (hdr->IsReassocReq ()) 
       
   382             {
       
   383               /* we don't support reassoc frames for now */
       
   384             } 
       
   385           else if (hdr->IsAuthentication () ||
       
   386                    hdr->IsDeauthentication ()) 
       
   387             {
       
   388               /*
       
   389                */
       
   390             } 
       
   391           else 
       
   392             {
       
   393               /* unknown mgt frame
       
   394                */
       
   395             }
       
   396         }
       
   397     } 
       
   398   else 
       
   399     {
       
   400     /* damn, what could this be ? a control frame ?
       
   401      * control frames should never reach the MacHigh so,
       
   402      * this is likely to be a bug. assert.
       
   403      */
       
   404       NS_ASSERT (false);
       
   405     }  
       
   406 }
       
   407 
       
   408 } // namespace ns3