src/devices/wifi/edca-txop-n.cc
changeset 4408 76a169b3db3d
child 4434 5e3d1c06662f
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/log.h"
       
    23 #include "ns3/assert.h"
       
    24 
       
    25 #include "edca-txop-n.h"
       
    26 #include "mac-low.h"
       
    27 #include "dcf-manager.h"
       
    28 #include "mac-tx-middle.h"
       
    29 #include "wifi-mac-trailer.h"
       
    30 #include "wifi-mac.h"
       
    31 #include "random-stream.h"
       
    32 #include "wifi-mac-queue.h"
       
    33 #include "msdu-aggregator.h"
       
    34 
       
    35 NS_LOG_COMPONENT_DEFINE ("EdcaTxopN");
       
    36 
       
    37 #define MY_DEBUG(x) \
       
    38   NS_LOG_DEBUG (m_low->GetAddress () << " " << x)
       
    39 
       
    40 namespace ns3 {
       
    41 
       
    42 class EdcaTxopN::Dcf : public DcfState
       
    43 {
       
    44 public:
       
    45   Dcf (EdcaTxopN *txop)
       
    46     : m_txop (txop)
       
    47   {}
       
    48 private:
       
    49   virtual void DoNotifyAccessGranted (void) {
       
    50     m_txop->NotifyAccessGranted ();
       
    51   }
       
    52   virtual void DoNotifyInternalCollision (void) {
       
    53     m_txop->NotifyInternalCollision ();
       
    54   }
       
    55   virtual void DoNotifyCollision (void) {
       
    56     m_txop->NotifyCollision ();
       
    57   }
       
    58   EdcaTxopN *m_txop;
       
    59 };
       
    60 
       
    61 class EdcaTxopN::TransmissionListener : public MacLowTransmissionListener
       
    62 {
       
    63 public:
       
    64   TransmissionListener (EdcaTxopN *txop)
       
    65     : MacLowTransmissionListener (),
       
    66       m_txop (txop) {}
       
    67       
       
    68   virtual ~TransmissionListener () {}
       
    69 
       
    70   virtual void GotCts (double snr, WifiMode txMode) {
       
    71     m_txop->GotCts (snr, txMode);
       
    72   }
       
    73   virtual void MissedCts (void) {
       
    74     m_txop->MissedCts ();
       
    75   }
       
    76   virtual void GotAck (double snr, WifiMode txMode) {
       
    77     m_txop->GotAck (snr, txMode);
       
    78   }
       
    79   virtual void MissedAck (void) {
       
    80     m_txop->MissedAck ();
       
    81   }
       
    82   virtual void StartNext (void) {
       
    83     m_txop->StartNext ();
       
    84   }
       
    85   virtual void Cancel (void) {
       
    86     m_txop->Cancel ();
       
    87   }
       
    88 
       
    89 private:
       
    90   EdcaTxopN *m_txop;
       
    91 };
       
    92 
       
    93 NS_OBJECT_ENSURE_REGISTERED (EdcaTxopN);
       
    94 
       
    95 TypeId
       
    96 EdcaTxopN::GetTypeId (void)
       
    97 {
       
    98   static TypeId tid = TypeId ("ns3::EdcaTxopN")
       
    99     .SetParent<Object> ()
       
   100     .AddConstructor<EdcaTxopN> ()
       
   101     .AddAttribute ("MinCw", "The minimun value of the contention window.",
       
   102                    UintegerValue (31),
       
   103                    MakeUintegerAccessor (&EdcaTxopN::SetMinCw,
       
   104                                          &EdcaTxopN::GetMinCw),
       
   105                    MakeUintegerChecker<uint32_t> ())
       
   106     .AddAttribute ("MaxCw", "The maximum value of the contention window.",
       
   107                    UintegerValue (1023),
       
   108                    MakeUintegerAccessor (&EdcaTxopN::SetMaxCw,
       
   109                                          &EdcaTxopN::GetMaxCw),
       
   110                    MakeUintegerChecker<uint32_t> ())
       
   111     .AddAttribute ("Aifsn", "The AIFSN: the default value conforms to simple DCA.",
       
   112                    UintegerValue (3),
       
   113                    MakeUintegerAccessor (&EdcaTxopN::SetAifsn,
       
   114                                          &EdcaTxopN::GetAifsn),
       
   115                    MakeUintegerChecker<uint32_t> ())
       
   116     ;
       
   117   return tid;
       
   118 }
       
   119 
       
   120 EdcaTxopN::EdcaTxopN ()
       
   121   : m_manager (0),
       
   122     m_currentPacket(0),
       
   123     m_aggregator (0)
       
   124 {
       
   125   NS_LOG_FUNCTION (this);
       
   126   m_transmissionListener = new EdcaTxopN::TransmissionListener (this);
       
   127   m_dcf = new EdcaTxopN::Dcf (this);
       
   128   m_queue = CreateObject<WifiMacQueue> ();
       
   129   m_rng = new RealRandomStream ();
       
   130 }
       
   131 
       
   132 EdcaTxopN::~EdcaTxopN ()
       
   133 {
       
   134   NS_LOG_FUNCTION (this);
       
   135 }
       
   136 
       
   137 void
       
   138 EdcaTxopN::DoDispose (void)
       
   139 {
       
   140   NS_LOG_FUNCTION (this);
       
   141   m_queue = 0;
       
   142   m_low = 0;
       
   143   m_stationManager = 0;
       
   144   delete m_transmissionListener;
       
   145   delete m_dcf;
       
   146   delete m_rng;
       
   147   m_transmissionListener = 0;
       
   148   m_dcf = 0;
       
   149   m_rng = 0;
       
   150   m_txMiddle = 0;
       
   151   m_aggregator = 0;
       
   152 }
       
   153 
       
   154 void
       
   155 EdcaTxopN::SetManager (DcfManager *manager)
       
   156 {
       
   157   NS_LOG_FUNCTION (this << manager);
       
   158   m_manager = manager;
       
   159   m_manager->Add (m_dcf);
       
   160 }
       
   161 
       
   162 void
       
   163 EdcaTxopN::SetTxOkCallback (TxOk callback)
       
   164 {
       
   165   m_txOkCallback = callback;
       
   166 }
       
   167 
       
   168 void 
       
   169 EdcaTxopN::SetTxFailedCallback (TxFailed callback)
       
   170 {
       
   171   m_txFailedCallback = callback;
       
   172 }
       
   173 
       
   174 void
       
   175 EdcaTxopN::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> remoteManager)
       
   176 {
       
   177   NS_LOG_FUNCTION (this << remoteManager);
       
   178   m_stationManager = remoteManager;
       
   179 }
       
   180 void
       
   181 EdcaTxopN::SetTypeOfStation (enum TypeOfStation type)
       
   182 {
       
   183   NS_LOG_FUNCTION (this << type);
       
   184   m_typeOfStation = type;
       
   185 }
       
   186 
       
   187 enum TypeOfStation
       
   188 EdcaTxopN::GetTypeOfStation (void) const
       
   189 {
       
   190   return m_typeOfStation;
       
   191 }
       
   192 
       
   193 void 
       
   194 EdcaTxopN::SetMaxQueueSize (uint32_t size)
       
   195 {
       
   196   NS_LOG_FUNCTION (this << size);
       
   197   m_queue->SetMaxSize (size);
       
   198 }
       
   199 
       
   200 void
       
   201 EdcaTxopN::SetMaxQueueDelay (Time delay)
       
   202 {
       
   203   NS_LOG_FUNCTION (this << delay);
       
   204   m_queue->SetMaxDelay (delay);
       
   205 }
       
   206 
       
   207 void 
       
   208 EdcaTxopN::SetMinCw (uint32_t minCw)
       
   209 {
       
   210   NS_LOG_FUNCTION (this << minCw);
       
   211   m_dcf->SetCwMin (minCw);
       
   212 }
       
   213 
       
   214 void 
       
   215 EdcaTxopN::SetMaxCw (uint32_t maxCw)
       
   216 {
       
   217   NS_LOG_FUNCTION (this << maxCw);
       
   218   m_dcf->SetCwMax (maxCw);
       
   219 }
       
   220 
       
   221 void 
       
   222 EdcaTxopN::SetAifsn (uint32_t aifsn)
       
   223 {
       
   224   NS_LOG_FUNCTION (this << aifsn);
       
   225   m_dcf->SetAifsn (aifsn);
       
   226 }
       
   227 
       
   228 uint32_t 
       
   229 EdcaTxopN::GetMinCw (void) const
       
   230 {
       
   231   return m_dcf->GetCwMin ();
       
   232 }
       
   233 
       
   234 uint32_t 
       
   235 EdcaTxopN::GetMaxCw (void) const
       
   236 {
       
   237   return m_dcf->GetCwMax ();
       
   238 }
       
   239 
       
   240 uint32_t 
       
   241 EdcaTxopN::GetAifsn (void) const
       
   242 {
       
   243   return m_dcf->GetAifsn ();
       
   244 }
       
   245 
       
   246 void
       
   247 EdcaTxopN::SetTxMiddle (MacTxMiddle *txMiddle)
       
   248 {
       
   249   m_txMiddle = txMiddle;
       
   250 }
       
   251 
       
   252 Ptr<MacLow>
       
   253 EdcaTxopN::Low (void)
       
   254 {
       
   255   return m_low;
       
   256 }
       
   257 
       
   258 void
       
   259 EdcaTxopN::SetLow(Ptr<MacLow> low)
       
   260 {
       
   261   NS_LOG_FUNCTION (this << low);
       
   262   m_low = low;
       
   263 }
       
   264 
       
   265 bool
       
   266 EdcaTxopN::NeedsAccess (void) const
       
   267 {
       
   268   return !m_queue->IsEmpty () || m_currentPacket != 0;
       
   269 }
       
   270 
       
   271 void
       
   272 EdcaTxopN::NotifyAccessGranted (void)
       
   273 {
       
   274   NS_LOG_FUNCTION (this);
       
   275   if (m_currentPacket == 0)
       
   276     {
       
   277       if (m_queue->IsEmpty ())
       
   278         {
       
   279           MY_DEBUG ("queue is empty");
       
   280           return; 
       
   281         }
       
   282       m_currentPacket = m_queue->Dequeue (&m_currentHdr);
       
   283       NS_ASSERT (m_currentPacket != 0);
       
   284       
       
   285       uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&m_currentHdr);
       
   286       m_currentHdr.SetSequenceNumber (sequence);
       
   287       m_currentHdr.SetFragmentNumber (0);
       
   288       m_currentHdr.SetNoMoreFragments ();
       
   289       m_currentHdr.SetNoRetry ();
       
   290       m_fragmentNumber = 0;
       
   291       MY_DEBUG ("dequeued size="<<m_currentPacket->GetSize ()<<
       
   292                 ", to="<<m_currentHdr.GetAddr1 ()<<
       
   293                 ", seq="<<m_currentHdr.GetSequenceControl ());
       
   294     }
       
   295   MacLowTransmissionParameters params;
       
   296   params.DisableOverrideDurationId ();
       
   297   if (m_currentHdr.GetAddr1 ().IsBroadcast ()) 
       
   298     {
       
   299       params.DisableRts ();
       
   300       params.DisableAck ();
       
   301       params.DisableNextData ();
       
   302       m_low->StartTransmission (m_currentPacket,
       
   303                                  &m_currentHdr,
       
   304                                  params,
       
   305                                  m_transmissionListener);
       
   306       
       
   307       m_currentPacket = 0;
       
   308       m_dcf->ResetCw ();
       
   309       m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
       
   310       StartAccessIfNeeded ();
       
   311       MY_DEBUG ("tx broadcast");
       
   312     }
       
   313   else
       
   314     {
       
   315       params.EnableAck ();
       
   316       if (NeedFragmentation () && ((m_currentHdr.IsQosData () &&
       
   317                                     !m_currentHdr.IsQosAmsdu ()) ||
       
   318                                     m_currentHdr.IsData ()))
       
   319         {
       
   320           params.DisableRts ();
       
   321           WifiMacHeader hdr;
       
   322           Ptr<Packet> fragment = GetFragmentPacket (&hdr);
       
   323           if (IsLastFragment ()) 
       
   324             {
       
   325               MY_DEBUG ("fragmenting last fragment size=" << fragment->GetSize ());
       
   326               params.DisableNextData ();
       
   327             } 
       
   328           else 
       
   329             {
       
   330               MY_DEBUG ("fragmenting size=" << fragment->GetSize ());
       
   331               params.EnableNextData (GetNextFragmentSize ());
       
   332             }
       
   333           m_low->StartTransmission (fragment, &hdr, params, 
       
   334                                      m_transmissionListener);
       
   335         }
       
   336       else
       
   337         {
       
   338           WifiMacHeader peekedHdr;
       
   339           if (m_currentHdr.IsQosData () &&
       
   340               m_queue->PeekByTidAndAddress (&peekedHdr, m_currentHdr.GetQosTid (), 
       
   341                                             WifiMacHeader::ADDR1, m_currentHdr.GetAddr1 ()) &&
       
   342               !m_currentHdr.GetAddr1 ().IsBroadcast () &&
       
   343               m_aggregator != 0)
       
   344             {
       
   345               /* here is performed aggregation */
       
   346               Ptr<Packet> currentAggregatedPacket = Create<Packet> ();
       
   347               m_aggregator->Aggregate (m_currentPacket, currentAggregatedPacket,
       
   348                                        MapSrcAddressForAggregation (peekedHdr),
       
   349                                        MapDestAddressForAggregation (peekedHdr));
       
   350               bool aggregated = false;
       
   351               bool isAmsdu = false;
       
   352               Ptr<const Packet> peekedPacket = m_queue->PeekByTidAndAddress (&peekedHdr, m_currentHdr.GetQosTid (), 
       
   353                                                                        WifiMacHeader::ADDR1, 
       
   354                                                                        m_currentHdr.GetAddr1 ());
       
   355               while (peekedPacket != 0)
       
   356                 {
       
   357                   aggregated = m_aggregator->Aggregate (peekedPacket, currentAggregatedPacket,
       
   358                                                         MapSrcAddressForAggregation (peekedHdr),
       
   359                                                         MapDestAddressForAggregation (peekedHdr));
       
   360                   if (aggregated) 
       
   361                     {
       
   362                       isAmsdu = true;
       
   363                       m_queue->Remove (peekedPacket);
       
   364                     }
       
   365                   else
       
   366                     {
       
   367                       break;
       
   368                     }
       
   369                   peekedPacket = m_queue->PeekByTidAndAddress (&peekedHdr, m_currentHdr.GetQosTid (), 
       
   370                                                                WifiMacHeader::ADDR1, m_currentHdr.GetAddr1 ());
       
   371                 }
       
   372               if (isAmsdu)
       
   373                 {
       
   374                   m_currentHdr.SetQosAmsdu ();
       
   375                   m_currentHdr.SetAddr3 (m_low->GetBssid ());
       
   376                   m_currentPacket = currentAggregatedPacket;
       
   377                   currentAggregatedPacket = 0;
       
   378                   MY_DEBUG ("tx unicast A-MSDU");
       
   379                 }
       
   380             }
       
   381           if (NeedRts ())
       
   382             {
       
   383               params.EnableRts ();
       
   384               MY_DEBUG ("tx unicast rts");
       
   385             } 
       
   386           else 
       
   387             {
       
   388               params.DisableRts ();
       
   389               MY_DEBUG ("tx unicast");
       
   390             }
       
   391           params.DisableNextData ();
       
   392           m_low->StartTransmission (m_currentPacket, &m_currentHdr,
       
   393                                     params, m_transmissionListener);
       
   394         }
       
   395     }
       
   396 }
       
   397 
       
   398 void EdcaTxopN::NotifyInternalCollision (void)
       
   399 {
       
   400   NS_LOG_FUNCTION (this);
       
   401   NotifyCollision ();
       
   402 }
       
   403 
       
   404 void
       
   405 EdcaTxopN::NotifyCollision (void)
       
   406 {
       
   407   NS_LOG_FUNCTION (this);
       
   408   m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
       
   409   RestartAccessIfNeeded ();
       
   410 }
       
   411 
       
   412 void 
       
   413 EdcaTxopN::GotCts (double snr, WifiMode txMode)
       
   414 {
       
   415   NS_LOG_FUNCTION (this << snr << txMode);
       
   416   MY_DEBUG ("got cts");
       
   417 }
       
   418 
       
   419 void 
       
   420 EdcaTxopN::MissedCts (void)
       
   421 {
       
   422   NS_LOG_FUNCTION (this);
       
   423   MY_DEBUG ("missed cts");
       
   424   if (!NeedRtsRetransmission ())
       
   425     {
       
   426       MY_DEBUG ("Cts Fail");
       
   427       WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
       
   428       station->ReportFinalRtsFailed ();
       
   429       if (!m_txFailedCallback.IsNull ()) 
       
   430         {
       
   431           m_txFailedCallback (m_currentHdr);
       
   432         }
       
   433       // to reset the dcf.
       
   434       m_currentPacket = 0;
       
   435       m_dcf->ResetCw ();
       
   436     } 
       
   437   else 
       
   438     {
       
   439       m_dcf->UpdateFailedCw ();
       
   440     }
       
   441   m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
       
   442   RestartAccessIfNeeded ();
       
   443 }
       
   444 
       
   445 void
       
   446 EdcaTxopN::Queue (Ptr<const Packet> packet, WifiMacHeader const &hdr)
       
   447 {
       
   448   NS_LOG_FUNCTION (this << packet << &hdr);
       
   449   WifiMacTrailer fcs;
       
   450   uint32_t fullPacketSize = hdr.GetSerializedSize () + packet->GetSize () + fcs.GetSerializedSize ();
       
   451   WifiRemoteStation *station = GetStation (hdr.GetAddr1 ());
       
   452   station->PrepareForQueue (packet, fullPacketSize);
       
   453   m_queue->Enqueue (packet, hdr);
       
   454   StartAccessIfNeeded ();
       
   455 }
       
   456 
       
   457 void
       
   458 EdcaTxopN::GotAck (double snr, WifiMode txMode)
       
   459 {
       
   460   NS_LOG_FUNCTION (this << snr << txMode);
       
   461   if (!NeedFragmentation () ||
       
   462       IsLastFragment () ||
       
   463       m_currentHdr.IsQosAmsdu ()) 
       
   464     {
       
   465       MY_DEBUG ("got ack. tx done.");
       
   466       if (!m_txOkCallback.IsNull ())
       
   467         {
       
   468            m_txOkCallback (m_currentHdr);
       
   469         }
       
   470       m_currentPacket = 0;
       
   471          
       
   472       m_dcf->ResetCw ();
       
   473       m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
       
   474       RestartAccessIfNeeded ();
       
   475     } 
       
   476   else 
       
   477     {
       
   478       MY_DEBUG ("got ack. tx not done, size="<<m_currentPacket->GetSize ());
       
   479     }
       
   480 }
       
   481 
       
   482 void
       
   483 EdcaTxopN::MissedAck (void)
       
   484 {
       
   485   NS_LOG_FUNCTION (this);
       
   486   MY_DEBUG ("missed ack");
       
   487   if (!NeedDataRetransmission ()) 
       
   488     {
       
   489       MY_DEBUG ("Ack Fail");
       
   490       WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
       
   491       station->ReportFinalDataFailed ();
       
   492       if (!m_txFailedCallback.IsNull ()) 
       
   493         {
       
   494           m_txFailedCallback (m_currentHdr);
       
   495         }
       
   496       // to reset the dcf.
       
   497       m_currentPacket = 0;
       
   498       m_dcf->ResetCw ();
       
   499     } 
       
   500   else 
       
   501     {
       
   502       MY_DEBUG ("Retransmit");
       
   503       m_currentHdr.SetRetry ();
       
   504       m_dcf->UpdateFailedCw ();
       
   505     }
       
   506   m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
       
   507   RestartAccessIfNeeded ();
       
   508 }
       
   509 
       
   510 Ptr<MsduAggregator>
       
   511 EdcaTxopN::GetMsduAggregator (void) const
       
   512 {
       
   513   return m_aggregator;
       
   514 }
       
   515 
       
   516 void
       
   517 EdcaTxopN::RestartAccessIfNeeded (void)
       
   518 {
       
   519   NS_LOG_FUNCTION (this);
       
   520   if ((m_currentPacket != 0 ||
       
   521        !m_queue->IsEmpty ()) &&
       
   522        !m_dcf->IsAccessRequested ())
       
   523     {
       
   524       m_manager->RequestAccess (m_dcf);
       
   525     }
       
   526 }
       
   527 
       
   528 void
       
   529 EdcaTxopN::StartAccessIfNeeded (void)
       
   530 {
       
   531   NS_LOG_FUNCTION (this);
       
   532   if (m_currentPacket == 0 &&
       
   533       !m_queue->IsEmpty () &&
       
   534       !m_dcf->IsAccessRequested ())
       
   535     {
       
   536       m_manager->RequestAccess (m_dcf);
       
   537     }
       
   538 }
       
   539 
       
   540 bool
       
   541 EdcaTxopN::NeedRts (void)
       
   542 {
       
   543   WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
       
   544   return station->NeedRts (m_currentPacket);
       
   545 }
       
   546 
       
   547 bool
       
   548 EdcaTxopN::NeedRtsRetransmission (void)
       
   549 {
       
   550   WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
       
   551   return station->NeedRtsRetransmission (m_currentPacket);
       
   552 }
       
   553 
       
   554 bool
       
   555 EdcaTxopN::NeedDataRetransmission (void)
       
   556 {
       
   557   WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
       
   558   return station->NeedDataRetransmission (m_currentPacket);
       
   559 }
       
   560 
       
   561 void
       
   562 EdcaTxopN::NextFragment (void)
       
   563 {
       
   564   m_fragmentNumber++;
       
   565 }
       
   566 
       
   567 void 
       
   568 EdcaTxopN::StartNext (void)
       
   569 {
       
   570   NS_LOG_FUNCTION (this);
       
   571   MY_DEBUG ("start next packet fragment");
       
   572   /* this callback is used only for fragments. */
       
   573   NextFragment ();
       
   574   WifiMacHeader hdr;
       
   575   Ptr<Packet> fragment = GetFragmentPacket (&hdr);
       
   576   MacLowTransmissionParameters params;
       
   577   params.EnableAck ();
       
   578   params.DisableRts ();
       
   579   params.DisableOverrideDurationId ();
       
   580   if (IsLastFragment ()) 
       
   581     {
       
   582       params.DisableNextData ();
       
   583     } 
       
   584   else 
       
   585     {
       
   586       params.EnableNextData (GetNextFragmentSize ());
       
   587     }
       
   588   Low ()->StartTransmission (fragment, &hdr, params, m_transmissionListener);
       
   589 }
       
   590 
       
   591 void
       
   592 EdcaTxopN::Cancel (void)
       
   593 {
       
   594   NS_LOG_FUNCTION (this);
       
   595   MY_DEBUG ("transmission cancelled");
       
   596 }
       
   597 
       
   598 bool
       
   599 EdcaTxopN::NeedFragmentation (void) const
       
   600 {
       
   601   WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
       
   602   return station->NeedFragmentation (m_currentPacket);
       
   603 }
       
   604 
       
   605 uint32_t
       
   606 EdcaTxopN::GetFragmentSize (void)
       
   607 {
       
   608   WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
       
   609   return station->GetFragmentSize (m_currentPacket, m_fragmentNumber);
       
   610 }
       
   611 
       
   612 uint32_t
       
   613 EdcaTxopN::GetNextFragmentSize (void) 
       
   614 {
       
   615   WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
       
   616   return station->GetFragmentSize (m_currentPacket, m_fragmentNumber + 1);
       
   617 }
       
   618 
       
   619 uint32_t
       
   620 EdcaTxopN::GetFragmentOffset (void) 
       
   621 {
       
   622   WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
       
   623   return station->GetFragmentOffset (m_currentPacket, m_fragmentNumber);
       
   624 }
       
   625 
       
   626 WifiRemoteStation *
       
   627 EdcaTxopN::GetStation (Mac48Address ad) const
       
   628 {
       
   629   return m_stationManager->Lookup (ad);
       
   630 }
       
   631 
       
   632 bool
       
   633 EdcaTxopN::IsLastFragment (void) const
       
   634 {
       
   635   WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
       
   636   return station->IsLastFragment (m_currentPacket, m_fragmentNumber);
       
   637 }
       
   638 
       
   639 Ptr<Packet>
       
   640 EdcaTxopN::GetFragmentPacket (WifiMacHeader *hdr)
       
   641 {
       
   642   *hdr = m_currentHdr;
       
   643   hdr->SetFragmentNumber (m_fragmentNumber);
       
   644   uint32_t startOffset = GetFragmentOffset ();
       
   645   Ptr<Packet> fragment;
       
   646   if (IsLastFragment ()) 
       
   647     {
       
   648       hdr->SetNoMoreFragments ();
       
   649     } 
       
   650   else 
       
   651     {
       
   652       hdr->SetMoreFragments ();
       
   653     }
       
   654   fragment = m_currentPacket->CreateFragment (startOffset, 
       
   655                                               GetFragmentSize ());
       
   656   return fragment;
       
   657 }
       
   658 
       
   659 Mac48Address
       
   660 EdcaTxopN::MapSrcAddressForAggregation (WifiMacHeader const &hdr)
       
   661 {
       
   662   if (m_typeOfStation == STA || m_typeOfStation == ADHOC_STA)
       
   663     {
       
   664       return hdr.GetAddr2 ();
       
   665     }
       
   666   else
       
   667     {
       
   668       return hdr.GetAddr3 ();
       
   669     }
       
   670 }
       
   671 
       
   672 Mac48Address
       
   673 EdcaTxopN::MapDestAddressForAggregation (WifiMacHeader const &hdr)
       
   674 {
       
   675   if (m_typeOfStation == AP || m_typeOfStation == ADHOC_STA)
       
   676     {
       
   677       return hdr.GetAddr1 ();
       
   678     }
       
   679   else
       
   680     {
       
   681       return hdr.GetAddr3 ();
       
   682     }
       
   683 }
       
   684 
       
   685 void
       
   686 EdcaTxopN::SetMsduAggregator (Ptr<MsduAggregator> aggr)
       
   687 {
       
   688   m_aggregator = aggr;
       
   689 }
       
   690 
       
   691 } //namespace ns3