src/devices/wifi/mac-stations.cc
changeset 2545 7a38029a2e5b
parent 2544 2e6e1a6e0d94
child 2546 3fc951966b1b
equal deleted inserted replaced
2544:2e6e1a6e0d94 2545:7a38029a2e5b
     1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
       
     2 /*
       
     3  * Copyright (c) 2005,2006,2007 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 
       
    21 #include "mac-stations.h"
       
    22 #include "wifi-default-parameters.h"
       
    23 #include "wifi-mac-parameters.h"
       
    24 #include "ns3/assert.h"
       
    25 #include "ns3/log.h"
       
    26 #include "ns3/tag.h"
       
    27 
       
    28 NS_LOG_COMPONENT_DEFINE ("MacStations");
       
    29 
       
    30 namespace ns3 {
       
    31 
       
    32 /**
       
    33  * _all_ broadcast and multicast frames are transmitted
       
    34  * at the same constant default rate because since we don't
       
    35  * have any kind of feedback from their transmission,
       
    36  * we cannot adjust the rate, so, we pick one which ensures
       
    37  * that all frames reach destination.
       
    38  */
       
    39 class NonUnicastMacStation : public MacStation
       
    40 {
       
    41 public:
       
    42   NonUnicastMacStation (MacStations *stations);
       
    43   virtual void ReportRxOk (double rxSnr, WifiMode txMode);
       
    44   virtual void ReportRtsFailed (void);
       
    45   virtual void ReportDataFailed (void);
       
    46   virtual void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
       
    47   virtual void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
       
    48   virtual void ReportFinalRtsFailed (void);
       
    49   virtual void ReportFinalDataFailed (void);
       
    50 
       
    51 private:
       
    52   virtual MacStations *GetStations (void) const;
       
    53   virtual WifiMode DoGetDataMode (uint32_t size);
       
    54   virtual WifiMode DoGetRtsMode (void);
       
    55   MacStations *m_stations;
       
    56 };
       
    57 
       
    58 NonUnicastMacStation::NonUnicastMacStation (MacStations *stations)
       
    59   : m_stations (stations)
       
    60 {
       
    61   RecordDisassociated ();
       
    62 }
       
    63 void 
       
    64 NonUnicastMacStation::ReportRxOk (double rxSnr, WifiMode txMode)
       
    65 {
       
    66   NS_ASSERT (false);
       
    67 }
       
    68 void 
       
    69 NonUnicastMacStation::ReportRtsFailed (void)
       
    70 {
       
    71   NS_ASSERT (false);
       
    72 }
       
    73 void 
       
    74 NonUnicastMacStation::ReportDataFailed (void)
       
    75 {
       
    76   NS_ASSERT (false);
       
    77 }
       
    78 void 
       
    79 NonUnicastMacStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
       
    80 {
       
    81   NS_ASSERT (false);
       
    82 }
       
    83 void 
       
    84 NonUnicastMacStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
       
    85 {
       
    86   NS_ASSERT (false);
       
    87 }
       
    88 void 
       
    89 NonUnicastMacStation::ReportFinalRtsFailed (void)
       
    90 {}
       
    91 void 
       
    92 NonUnicastMacStation::ReportFinalDataFailed (void)
       
    93 {}
       
    94 
       
    95 WifiMode 
       
    96 NonUnicastMacStation::DoGetDataMode (uint32_t size)
       
    97 {
       
    98   WifiMode mode = m_stations->GetBasicMode (0);
       
    99   NS_LOG_DEBUG ("non-unicast size="<<size<<", mode="<<mode);
       
   100   return mode;
       
   101 }
       
   102 WifiMode 
       
   103 NonUnicastMacStation::DoGetRtsMode (void)
       
   104 {
       
   105   NS_ASSERT (false);
       
   106   // theoretically, no rts for broadcast/multicast packets.
       
   107   return m_stations->GetBasicMode (0);
       
   108 }
       
   109 MacStations *
       
   110 NonUnicastMacStation::GetStations (void) const
       
   111 {
       
   112   return m_stations;
       
   113 }
       
   114 
       
   115 
       
   116 } // namespace ns3
       
   117 
       
   118 namespace ns3 {
       
   119 
       
   120 MacStations::MacStations (WifiMode defaultTxMode)
       
   121   : m_defaultTxMode (defaultTxMode),
       
   122     m_nonUnicast (new NonUnicastMacStation (this)),
       
   123     m_isLowLatency (WifiDefaultParameters::GetIsLowLatency ())
       
   124 {
       
   125   Reset ();
       
   126 }
       
   127 
       
   128 MacStations::~MacStations ()
       
   129 {
       
   130   for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++) 
       
   131     {
       
   132       delete (*i).second;
       
   133     }
       
   134   m_stations.clear ();
       
   135   delete m_nonUnicast;
       
   136 }
       
   137 
       
   138 MacStation *
       
   139 MacStations::Lookup (Mac48Address address)
       
   140 {
       
   141   if (address.IsBroadcast () ||
       
   142       address.IsMulticast ())
       
   143     {
       
   144       return m_nonUnicast;
       
   145     }
       
   146   for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++) 
       
   147     {
       
   148       if ((*i).first == address)
       
   149         {
       
   150           return (*i).second;
       
   151         }
       
   152     }
       
   153   MacStation *station = CreateStation ();
       
   154   station->Reset ();
       
   155   station->SetParameters (m_parameters);
       
   156   m_stations.push_back (std::make_pair (address, station));
       
   157   return station;
       
   158 }
       
   159 
       
   160 MacStation *
       
   161 MacStations::LookupNonUnicast (void)
       
   162 {
       
   163   return m_nonUnicast;
       
   164 }
       
   165 
       
   166 WifiMode 
       
   167 MacStations::GetDefaultMode (void) const
       
   168 {
       
   169   return m_defaultTxMode;
       
   170 }
       
   171 void
       
   172 MacStations::Reset (void)
       
   173 {
       
   174   for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++)
       
   175     {
       
   176       delete i->second;
       
   177     }
       
   178   m_stations.clear ();
       
   179   m_basicModes.clear ();
       
   180   m_basicModes.push_back (m_defaultTxMode);
       
   181   NS_ASSERT (m_defaultTxMode.IsMandatory ());
       
   182 }
       
   183 void 
       
   184 MacStations::AddBasicMode (WifiMode mode)
       
   185 {
       
   186   for (uint32_t i = 0; i < GetNBasicModes (); i++)
       
   187     {
       
   188       if (GetBasicMode (i) == mode)
       
   189         {
       
   190           return;
       
   191         }
       
   192     }
       
   193   m_basicModes.push_back (mode);
       
   194 }
       
   195 uint32_t 
       
   196 MacStations::GetNBasicModes (void) const
       
   197 {
       
   198   return m_basicModes.size ();
       
   199 }
       
   200 WifiMode 
       
   201 MacStations::GetBasicMode (uint32_t i) const
       
   202 {
       
   203   NS_ASSERT (i < m_basicModes.size ());
       
   204   return m_basicModes[i];
       
   205 }
       
   206 MacStations::BasicModesIterator 
       
   207 MacStations::BeginBasicModes (void) const
       
   208 {
       
   209   return m_basicModes.begin ();
       
   210 }
       
   211 MacStations::BasicModesIterator 
       
   212 MacStations::EndBasicModes (void) const
       
   213 {
       
   214   return m_basicModes.end ();
       
   215 }
       
   216 bool
       
   217 MacStations::IsLowLatency (void) const
       
   218 {
       
   219   return m_isLowLatency;
       
   220 }
       
   221 void 
       
   222 MacStations::SetParameters (WifiMacParameters *parameters)
       
   223 {
       
   224   m_parameters = parameters;
       
   225 }
       
   226 
       
   227 
       
   228 } // namespace ns3
       
   229 
       
   230 /***************************************************************
       
   231  *           Packet Mode Tagger
       
   232  ***************************************************************/ 
       
   233 
       
   234 namespace ns3 {
       
   235 
       
   236 class TxModeTag : public Tag
       
   237 {
       
   238 public:
       
   239   TxModeTag ();
       
   240   TxModeTag (WifiMode rtsMode, WifiMode dataMode);
       
   241   WifiMode GetRtsMode (void) const;
       
   242   WifiMode GetDataMode (void) const;
       
   243 
       
   244   static uint32_t GetUid (void);
       
   245   void Print (std::ostream &os) const;
       
   246   void Serialize (ns3::Buffer::Iterator start) const;
       
   247   uint32_t Deserialize (ns3::Buffer::Iterator start);
       
   248   uint32_t GetSerializedSize (void) const;
       
   249 private:
       
   250   WifiMode m_rtsMode;
       
   251   WifiMode m_dataMode;
       
   252 };
       
   253 
       
   254 TxModeTag::TxModeTag ()
       
   255 {}
       
   256 TxModeTag::TxModeTag (WifiMode rtsMode, WifiMode dataMode)
       
   257   : m_rtsMode (rtsMode),
       
   258     m_dataMode (dataMode)
       
   259 {}
       
   260 WifiMode 
       
   261 TxModeTag::GetRtsMode (void) const
       
   262 {
       
   263   return m_rtsMode;
       
   264 }
       
   265 WifiMode 
       
   266 TxModeTag::GetDataMode (void) const
       
   267 {
       
   268   return m_dataMode;
       
   269 }
       
   270 
       
   271 uint32_t 
       
   272 TxModeTag::GetUid (void)
       
   273 {
       
   274   static uint32_t uid = Tag::AllocateUid<TxModeTag> ("ns3.wifi.TxModeTag");
       
   275   return uid;
       
   276 }
       
   277 void 
       
   278 TxModeTag::Print (std::ostream &os) const
       
   279 {
       
   280   os << "rts="<<m_rtsMode<<" data="<<m_dataMode;
       
   281 }
       
   282 void 
       
   283 TxModeTag::Serialize (ns3::Buffer::Iterator start) const
       
   284 {}
       
   285 uint32_t 
       
   286 TxModeTag::Deserialize (ns3::Buffer::Iterator start)
       
   287 {
       
   288   return 0;
       
   289 }
       
   290 uint32_t 
       
   291 TxModeTag::GetSerializedSize (void) const
       
   292 {
       
   293   return 0;
       
   294 }
       
   295 
       
   296 } // namespace ns3
       
   297 
       
   298 
       
   299 /***************************************************************
       
   300  *           MacStation below.
       
   301  ***************************************************************/ 
       
   302 
       
   303 namespace ns3 {
       
   304 
       
   305 MacStation::MacStation ()
       
   306   : m_state (BRAND_NEW)
       
   307 {}
       
   308 MacStation::~MacStation ()
       
   309 {}
       
   310 
       
   311 void 
       
   312 MacStation::SetParameters (WifiMacParameters *parameters)
       
   313 {
       
   314   m_parameters = parameters;
       
   315 }
       
   316 
       
   317 bool
       
   318 MacStation::IsBrandNew (void) const
       
   319 {
       
   320   return m_state == BRAND_NEW;
       
   321 }
       
   322 
       
   323 bool 
       
   324 MacStation::IsAssociated (void) const
       
   325 {
       
   326   return m_state == GOT_ASSOC_TX_OK;
       
   327 }
       
   328 bool 
       
   329 MacStation::IsWaitAssocTxOk (void) const
       
   330 {
       
   331   return m_state == WAIT_ASSOC_TX_OK;
       
   332 }
       
   333 void 
       
   334 MacStation::RecordWaitAssocTxOk (void)
       
   335 {
       
   336   m_state = WAIT_ASSOC_TX_OK;
       
   337 }
       
   338 void 
       
   339 MacStation::RecordGotAssocTxOk (void)
       
   340 {
       
   341   m_state = GOT_ASSOC_TX_OK;
       
   342 }
       
   343 void 
       
   344 MacStation::RecordGotAssocTxFailed (void)
       
   345 {
       
   346   m_state = DISASSOC;
       
   347 }
       
   348 void 
       
   349 MacStation::RecordDisassociated (void)
       
   350 {
       
   351   m_state = DISASSOC;
       
   352 }
       
   353 
       
   354 void 
       
   355 MacStation::Reset (void)
       
   356 {
       
   357   m_modes.clear ();
       
   358   AddSupportedMode (GetStations ()->GetDefaultMode ());
       
   359 }
       
   360 void 
       
   361 MacStation::AddSupportedMode (WifiMode mode)
       
   362 {
       
   363   if (IsIn (mode))
       
   364     {
       
   365       return;
       
   366     }
       
   367   m_modes.push_back (mode);
       
   368 }
       
   369 
       
   370 bool
       
   371 MacStation::IsIn (WifiMode mode) const
       
   372 {
       
   373   for (SupportedModes::const_iterator i = m_modes.begin (); i != m_modes.end (); i++)
       
   374     {
       
   375       if ((*i) == mode)
       
   376         {
       
   377           return true;
       
   378         }
       
   379     }
       
   380   return false;
       
   381 }
       
   382 
       
   383 WifiMode
       
   384 MacStation::GetControlAnswerMode (WifiMode reqMode)
       
   385 {
       
   386   /**
       
   387    * see ieee 802.11e, section 9.6:
       
   388    * 
       
   389    * To allow the transmitting STA to calculate the contents of 
       
   390    * the Duration/ID field, a STA responding to a received frame 
       
   391    * shall transmit its Control Response frame (either CTS or ACK) 
       
   392    * frames, other than the Block-Ack control frame, at the highest 
       
   393    * rate in the BSSBasicRateSet parameter that is less than or equal 
       
   394    * to the rate of the immediately previous frame in the frame 
       
   395    * exchange sequence (as defined in 9.79.12) and that is of the
       
   396    * same modulation type as the received frame. If no rate in the 
       
   397    * basic rate set meets these conditions, then the control frame 
       
   398    * sent in response to a received frame shall be transmitted at 
       
   399    * the highest mandatory rate of the PHY that is less than or equal 
       
   400    * to the rate of the received frame, and that is of the same 
       
   401    * modulation type as the received frame. In addition, the Control 
       
   402    * Response frame shall be sent using the same PHY options as the
       
   403    * received frame, unless they conflict with the requirement to use 
       
   404    * the BSSBasicRateSet parameter.
       
   405    */
       
   406   WifiMode mode = GetStations ()->GetDefaultMode ();
       
   407   bool found = false;
       
   408 
       
   409   // First, search the BSS Basic Rate set
       
   410   for (MacStations::BasicModesIterator i = GetStations ()->BeginBasicModes (); 
       
   411        i != GetStations ()->EndBasicModes (); i++)
       
   412     {
       
   413       if (i->GetPhyRate () > mode.GetPhyRate () &&
       
   414           i->GetPhyRate () <= reqMode.GetPhyRate () &&
       
   415           i->GetModulationType () == reqMode.GetModulationType ())
       
   416         {
       
   417           mode = *i;
       
   418           found = true;
       
   419         }
       
   420     }
       
   421   // no need to search Mandatory rate set because it is included
       
   422   // within the Basic rate set.
       
   423   return mode;
       
   424 }
       
   425 
       
   426 WifiMode 
       
   427 MacStation::GetCtsMode (WifiMode rtsMode)
       
   428 {
       
   429   return GetControlAnswerMode (rtsMode);
       
   430 }
       
   431 WifiMode 
       
   432 MacStation::GetAckMode (WifiMode dataMode)
       
   433 {
       
   434   return GetControlAnswerMode (dataMode);
       
   435 }
       
   436 
       
   437 uint32_t 
       
   438 MacStation::GetNSupportedModes (void) const
       
   439 {
       
   440   return m_modes.size ();
       
   441 }
       
   442 WifiMode 
       
   443 MacStation::GetSupportedMode (uint32_t i) const
       
   444 {
       
   445   NS_ASSERT (i < m_modes.size ());
       
   446   return m_modes[i];
       
   447 }
       
   448 void 
       
   449 MacStation::PrepareForQueue (Ptr<const Packet> packet, uint32_t fullPacketSize)
       
   450 {
       
   451   if (GetStations ()->IsLowLatency ())
       
   452     {
       
   453       return;
       
   454     }
       
   455   TxModeTag tag = TxModeTag (DoGetRtsMode (), DoGetDataMode (fullPacketSize));
       
   456   packet->AddTag (tag);
       
   457 }
       
   458 WifiMode 
       
   459 MacStation::GetDataMode (Ptr<const Packet> packet, uint32_t fullPacketSize)
       
   460 {
       
   461   if (GetStations ()->IsLowLatency ())
       
   462     {
       
   463       return DoGetDataMode (fullPacketSize);
       
   464     }
       
   465   TxModeTag tag;
       
   466   bool found;
       
   467   found = packet->PeekTag (tag);
       
   468   NS_ASSERT (found);
       
   469   return tag.GetDataMode ();
       
   470 }
       
   471 WifiMode 
       
   472 MacStation::GetRtsMode (Ptr<const Packet> packet)
       
   473 {
       
   474   if (GetStations ()->IsLowLatency ())
       
   475     {
       
   476       return DoGetRtsMode ();
       
   477     }
       
   478   TxModeTag tag;
       
   479   bool found;
       
   480   found = packet->PeekTag (tag);
       
   481   NS_ASSERT (found);
       
   482   return tag.GetRtsMode ();
       
   483 }
       
   484 
       
   485 bool
       
   486 MacStation::NeedRts (Ptr<const Packet> packet)
       
   487 {
       
   488   if (packet->GetSize () > m_parameters->GetRtsCtsThreshold ()) 
       
   489     {
       
   490       return true;
       
   491     } 
       
   492   else 
       
   493     {
       
   494       return false;
       
   495     }
       
   496 }
       
   497 uint32_t 
       
   498 MacStation::GetMaxSsrc (Ptr<const Packet> packet)
       
   499 {
       
   500   return m_parameters->GetMaxSsrc ();
       
   501 }
       
   502 
       
   503 uint32_t 
       
   504 MacStation::GetMaxSlrc (Ptr<const Packet> packet)
       
   505 {
       
   506   return m_parameters->GetMaxSlrc ();
       
   507 }
       
   508 
       
   509 bool
       
   510 MacStation::NeedFragmentation (Ptr<const Packet> packet)
       
   511 {
       
   512   if (packet->GetSize () > m_parameters->GetFragmentationThreshold ()) 
       
   513     {
       
   514       return true;
       
   515     } 
       
   516   else 
       
   517     {
       
   518       return false;
       
   519     }
       
   520 }
       
   521 uint32_t
       
   522 MacStation::GetNFragments (Ptr<const Packet> packet)
       
   523 {
       
   524   uint32_t nFragments = packet->GetSize () / m_parameters->GetFragmentationThreshold () + 1;
       
   525   return nFragments;
       
   526 }
       
   527 
       
   528 uint32_t
       
   529 MacStation::GetFragmentSize (Ptr<const Packet> packet, uint32_t fragmentNumber)
       
   530 {
       
   531   uint32_t nFragment = GetNFragments (packet);
       
   532   if (fragmentNumber >= nFragment)
       
   533     {
       
   534       return 0;
       
   535     }
       
   536   if (fragmentNumber == nFragment - 1)
       
   537     {
       
   538       uint32_t lastFragmentSize = packet->GetSize () % m_parameters->GetFragmentationThreshold ();
       
   539       return lastFragmentSize;
       
   540     }
       
   541   else
       
   542     {
       
   543       return m_parameters->GetFragmentationThreshold ();
       
   544     }
       
   545 }
       
   546 
       
   547 bool
       
   548 MacStation::IsLastFragment (Ptr<const Packet> packet, uint32_t fragmentNumber) 
       
   549 {
       
   550   if (fragmentNumber == (GetNFragments (packet) - 1)) 
       
   551     {
       
   552       return true;
       
   553     } 
       
   554   else 
       
   555     {
       
   556       return false;
       
   557     }
       
   558 }
       
   559 
       
   560 } // namespace ns3
       
   561