src/devices/wifi/dca-txop.cc
changeset 2146 40ad60ac9912
parent 2094 ba3caa8ee26d
child 2159 20f882e85b4a
equal deleted inserted replaced
2145:8f3c8ef34b0a 2146:40ad60ac9912
    19  */
    19  */
    20 
    20 
    21 #include "ns3/assert.h"
    21 #include "ns3/assert.h"
    22 #include "ns3/packet.h"
    22 #include "ns3/packet.h"
    23 #include "ns3/log.h"
    23 #include "ns3/log.h"
       
    24 #include "ns3/simulator.h"
       
    25 #include "ns3/net-device.h"
       
    26 #include "ns3/node.h"
    24 
    27 
    25 #include "dca-txop.h"
    28 #include "dca-txop.h"
    26 #include "dcf.h"
    29 #include "dcf-manager.h"
    27 #include "mac-parameters.h"
    30 #include "mac-parameters.h"
    28 #include "mac-low.h"
    31 #include "mac-low.h"
    29 #include "wifi-mac-queue.h"
    32 #include "wifi-mac-queue.h"
    30 #include "mac-tx-middle.h"
    33 #include "mac-tx-middle.h"
    31 #include "wifi-phy.h"
    34 #include "wifi-phy.h"
       
    35 #include "random-stream.h"
    32 
    36 
    33 NS_LOG_COMPONENT_DEFINE ("DcaTxop");
    37 NS_LOG_COMPONENT_DEFINE ("DcaTxop");
    34 
    38 
       
    39 #define MY_DEBUG(x) \
       
    40   NS_LOG_DEBUG (Simulator::Now () << " " << m_low->GetDevice ()->GetNode ()->GetId () << ":" << \
       
    41                 m_low->GetDevice ()->GetIfIndex () << " " << x)
       
    42 
    35 
    43 
    36 namespace ns3 {
    44 namespace ns3 {
    37 
    45 
    38 class DcaTxop::NavListener : public ns3::MacLowNavListener {
    46 class DcaTxop::Dcf : public DcfState
       
    47 {
    39 public:
    48 public:
    40   NavListener (ns3::Dcf *dcf)
    49   Dcf (DcaTxop *txop)
    41     : m_dcf (dcf) {}
    50     : m_txop (txop)
    42   virtual ~NavListener () {}
    51   {}
    43   virtual void NavStart (Time now, Time duration) {
       
    44     m_dcf->NotifyNavStart (now, duration);
       
    45   }
       
    46   virtual void NavContinue (Time now, Time duration) {
       
    47     m_dcf->NotifyNavContinue (now, duration);
       
    48   }
       
    49   virtual void NavReset (Time now, Time duration) {
       
    50     m_dcf->NotifyNavReset (now, duration);
       
    51   }
       
    52 private:
    52 private:
    53   ns3::Dcf *m_dcf;
    53   virtual void DoNotifyAccessGranted (void) {
    54 };
    54     m_txop->NotifyAccessGranted ();
    55 class DcaTxop::PhyListener : public ns3::WifiPhyListener {
    55   }
    56 public:
    56   virtual void DoNotifyInternalCollision (void) {
    57   PhyListener (ns3::Dcf *dcf)
    57     m_txop->NotifyInternalCollision ();
    58     : m_dcf (dcf) {}
    58   }
    59   virtual ~PhyListener () {}
    59   virtual void DoNotifyCollision (void) {
    60   virtual void NotifyRxStart (Time duration) {
    60     m_txop->NotifyCollision ();
    61     m_dcf->NotifyRxStartNow (duration);
    61   }
    62   }
    62 
    63   virtual void NotifyRxEndOk (void) {
       
    64     m_dcf->NotifyRxEndOkNow ();
       
    65   }
       
    66   virtual void NotifyRxEndError (void) {
       
    67     m_dcf->NotifyRxEndErrorNow ();
       
    68   }
       
    69   virtual void NotifyTxStart (Time duration) {
       
    70     m_dcf->NotifyTxStartNow (duration);
       
    71   }
       
    72   virtual void NotifyCcaBusyStart (Time duration) {
       
    73     m_dcf->NotifyCcaBusyStartNow (duration);
       
    74   }
       
    75 private:
       
    76   ns3::Dcf *m_dcf;
       
    77 };
       
    78 
       
    79 
       
    80 class DcaTxop::AccessListener : public DcfAccessListener {
       
    81 public:
       
    82   AccessListener (DcaTxop *txop)
       
    83     : DcfAccessListener (),
       
    84       m_txop (txop) {}
       
    85 
       
    86   virtual ~AccessListener () {}
       
    87 
       
    88   virtual void AccessGrantedNow (void)
       
    89   {
       
    90     m_txop->AccessGrantedNow ();
       
    91   }
       
    92   virtual bool AccessNeeded (void)
       
    93   {
       
    94     return m_txop->AccessNeeded ();
       
    95   }
       
    96   virtual bool AccessingAndWillNotify (void)
       
    97   {
       
    98     return m_txop->AccessingAndWillNotify ();
       
    99   }
       
   100 
       
   101 private:
       
   102   DcaTxop *m_txop;
    63   DcaTxop *m_txop;
   103 };
    64 };
   104 
    65 
   105 class DcaTxop::TransmissionListener : public MacLowTransmissionListener {
    66 class DcaTxop::TransmissionListener : public MacLowTransmissionListener {
   106 public:
    67 public:
   131 
    92 
   132 private:
    93 private:
   133   DcaTxop *m_txop;
    94   DcaTxop *m_txop;
   134 };
    95 };
   135 
    96 
   136 DcaTxop::DcaTxop (uint32_t minCw, uint32_t maxCw)
    97 DcaTxop::DcaTxop (uint32_t minCw, uint32_t maxCw, uint32_t aifsn, DcfManager *manager)
   137   : m_accessListener (0),
    98   : m_manager (manager),
   138     m_hasCurrent (false),
    99     m_hasCurrent (false),
   139     m_ssrc (0),
   100     m_ssrc (0),
   140     m_slrc (0)
   101     m_slrc (0)
       
   102 
   141 {
   103 {
   142   m_transmissionListener = new DcaTxop::TransmissionListener (this);
   104   m_transmissionListener = new DcaTxop::TransmissionListener (this);
   143   m_dcf = new Dcf (minCw, maxCw);
   105   m_dcf = new DcaTxop::Dcf (this);
   144   m_accessListener = new DcaTxop::AccessListener (this);
   106   m_dcf->SetCwBounds (minCw, maxCw);
   145   m_dcf->RegisterAccessListener (m_accessListener);
   107   m_dcf->SetAifsn (aifsn);
       
   108   m_manager->Add (m_dcf);
   146   m_queue = new WifiMacQueue ();
   109   m_queue = new WifiMacQueue ();
       
   110   m_rng = new RealRandomStream ();
   147 }
   111 }
   148 
   112 
   149 DcaTxop::~DcaTxop ()
   113 DcaTxop::~DcaTxop ()
   150 {
   114 {
   151   delete m_accessListener;
       
   152   delete m_transmissionListener;
   115   delete m_transmissionListener;
   153   delete m_navListener;
       
   154   delete m_phyListener;
       
   155   delete m_queue;
   116   delete m_queue;
   156   delete m_dcf;
   117   delete m_dcf;
   157   m_accessListener = 0;
       
   158   m_transmissionListener = 0;
   118   m_transmissionListener = 0;
   159   m_navListener = 0;
       
   160   m_phyListener = 0;
       
   161   m_queue = 0;
   119   m_queue = 0;
   162   m_dcf = 0;
   120   m_dcf = 0;
   163 }
   121 }
   164 
   122 
   165 void 
   123 void 
   166 DcaTxop::SetLow (MacLow *low)
   124 DcaTxop::SetLow (MacLow *low)
   167 {
   125 {
   168   m_low = low;
   126   m_low = low;
   169   m_navListener = new DcaTxop::NavListener (m_dcf);
   127 }
   170   m_low->RegisterNavListener (m_navListener);
   128 void 
   171 }
   129 DcaTxop::SetParameters (MacParameters *parameters)
       
   130 {
       
   131   m_parameters = parameters;
       
   132 }
       
   133 void 
       
   134 DcaTxop::SetTxMiddle (MacTxMiddle *txMiddle)
       
   135 {
       
   136   m_txMiddle = txMiddle;
       
   137 }
       
   138 void 
       
   139 DcaTxop::SetTxOkCallback (TxOk callback)
       
   140 {
       
   141   m_txOkCallback = callback;
       
   142 }
       
   143 void 
       
   144 DcaTxop::SetTxFailedCallback (TxFailed callback)
       
   145 {
       
   146   m_txFailedCallback = callback;
       
   147 }
       
   148 
       
   149 void 
       
   150 DcaTxop::SetMaxQueueSize (uint32_t size)
       
   151 {
       
   152   m_queue->SetMaxSize (size);
       
   153 }
       
   154 void 
       
   155 DcaTxop::SetMaxQueueDelay (Time delay)
       
   156 {
       
   157   m_queue->SetMaxDelay (delay);
       
   158 }
       
   159 
       
   160 void 
       
   161 DcaTxop::Queue (Packet packet, WifiMacHeader const &hdr)
       
   162 {
       
   163   m_queue->Enqueue (packet, hdr);
       
   164   StartAccessIfNeeded ();
       
   165 }
       
   166 
   172 void
   167 void
   173 DcaTxop::SetPhy (Ptr<WifiPhy> phy)
   168 DcaTxop::RestartAccessIfNeeded (void)
   174 {
   169 {
   175   m_phyListener = new DcaTxop::PhyListener (m_dcf);
   170   if ((m_hasCurrent ||
   176   phy->RegisterListener (m_phyListener);
   171        !m_queue->IsEmpty ()) &&
   177 }
   172       !m_dcf->IsAccessRequested ())
   178 void 
   173     {
   179 DcaTxop::SetParameters (MacParameters *parameters)
   174       m_manager->RequestAccess (m_dcf);
   180 {
   175     }
   181   m_parameters = parameters;
   176 }
   182   m_dcf->SetParameters (parameters);
   177 
   183 }
   178 void
   184 void 
   179 DcaTxop::StartAccessIfNeeded (void)
   185 DcaTxop::SetTxMiddle (MacTxMiddle *txMiddle)
   180 {
   186 {
   181   if (!m_hasCurrent &&
   187   m_txMiddle = txMiddle;
   182       !m_queue->IsEmpty () &&
   188 }
   183       !m_dcf->IsAccessRequested ())
   189 void 
   184     {
   190 DcaTxop::SetTxOkCallback (TxOk callback)
   185       m_manager->RequestAccess (m_dcf);
   191 {
   186     }
   192   m_txOkCallback = callback;
       
   193 }
       
   194 void 
       
   195 DcaTxop::SetTxFailedCallback (TxFailed callback)
       
   196 {
       
   197   m_txFailedCallback = callback;
       
   198 }
       
   199 
       
   200 void 
       
   201 DcaTxop::SetDifs (Time difs)
       
   202 {
       
   203   m_dcf->SetDifs (difs);
       
   204 }
       
   205 void 
       
   206 DcaTxop::SetEifs (Time eifs)
       
   207 {
       
   208   m_dcf->SetEifs (eifs);
       
   209 }
       
   210 void 
       
   211 DcaTxop::SetCwBounds (uint32_t min, uint32_t max)
       
   212 {
       
   213   m_dcf->SetCwBounds (min, max);
       
   214 }
       
   215 void 
       
   216 DcaTxop::SetMaxQueueSize (uint32_t size)
       
   217 {
       
   218   m_queue->SetMaxSize (size);
       
   219 }
       
   220 void 
       
   221 DcaTxop::SetMaxQueueDelay (Time delay)
       
   222 {
       
   223   m_queue->SetMaxDelay (delay);
       
   224 }
       
   225 
       
   226 void 
       
   227 DcaTxop::Queue (Packet packet, WifiMacHeader const &hdr)
       
   228 {
       
   229   m_queue->Enqueue (packet, hdr);
       
   230   m_dcf->RequestAccess ();
       
   231 }
   187 }
   232 
   188 
   233 
   189 
   234 MacLow *
   190 MacLow *
   235 DcaTxop::Low (void)
   191 DcaTxop::Low (void)
   348     }
   304     }
   349   return fragment;
   305   return fragment;
   350 }
   306 }
   351 
   307 
   352 bool 
   308 bool 
   353 DcaTxop::AccessingAndWillNotify (void)
   309 DcaTxop::NeedsAccess (void) const
   354 {
   310 {
   355   if (m_hasCurrent) 
   311   return !m_queue->IsEmpty () || m_hasCurrent;
   356     {
   312 }
   357       return true;
   313 void 
   358     } 
   314 DcaTxop::NotifyAccessGranted (void)
   359   else 
       
   360     {
       
   361       return false;
       
   362     }
       
   363 }
       
   364 
       
   365 bool 
       
   366 DcaTxop::AccessNeeded (void)
       
   367 {
       
   368   if (!m_queue->IsEmpty () ||
       
   369       m_hasCurrent) 
       
   370     {
       
   371       NS_LOG_DEBUG ("access needed here");
       
   372       return true;
       
   373     } 
       
   374   else 
       
   375     {
       
   376       NS_LOG_DEBUG ("no access needed here");
       
   377       return false;
       
   378     }
       
   379 }
       
   380 
       
   381 void
       
   382 DcaTxop::AccessGrantedNow (void)
       
   383 {
   315 {
   384   if (!m_hasCurrent) 
   316   if (!m_hasCurrent) 
   385     {
   317     {
   386       if (m_queue->IsEmpty ()) 
   318       if (m_queue->IsEmpty ()) 
   387         {
   319         {
   388           NS_LOG_DEBUG ("queue empty");
   320           MY_DEBUG ("queue empty");
   389           return;
   321           return;
   390         }
   322         }
   391       bool found;
   323       bool found;
   392       m_currentPacket = m_queue->Dequeue (&m_currentHdr, &found);
   324       m_currentPacket = m_queue->Dequeue (&m_currentHdr, &found);
   393       NS_ASSERT (found);
   325       NS_ASSERT (found);
   398       m_currentHdr.SetFragmentNumber (0);
   330       m_currentHdr.SetFragmentNumber (0);
   399       m_currentHdr.SetNoMoreFragments ();
   331       m_currentHdr.SetNoMoreFragments ();
   400       m_ssrc = 0;
   332       m_ssrc = 0;
   401       m_slrc = 0;
   333       m_slrc = 0;
   402       m_fragmentNumber = 0;
   334       m_fragmentNumber = 0;
   403       NS_LOG_DEBUG ("dequeued size="<<m_currentPacket.GetSize ()<<
   335       MY_DEBUG ("dequeued size="<<m_currentPacket.GetSize ()<<
   404                     ", to="<<m_currentHdr.GetAddr1 ()<<
   336                     ", to="<<m_currentHdr.GetAddr1 ()<<
   405                     ", seq="<<m_currentHdr.GetSequenceControl ()); 
   337                     ", seq="<<m_currentHdr.GetSequenceControl ()); 
   406     }
   338     }
   407   MacLowTransmissionParameters params;
   339   MacLowTransmissionParameters params;
   408   params.DisableOverrideDurationId ();
   340   params.DisableOverrideDurationId ();
   415                                  &m_currentHdr,
   347                                  &m_currentHdr,
   416                                  params,
   348                                  params,
   417                                  m_transmissionListener);
   349                                  m_transmissionListener);
   418       m_hasCurrent = false;
   350       m_hasCurrent = false;
   419       m_dcf->ResetCw ();
   351       m_dcf->ResetCw ();
   420       m_dcf->StartBackoff ();
   352       m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
   421       NS_LOG_DEBUG ("tx broadcast");
   353       MY_DEBUG ("tx broadcast");
   422     } 
   354     } 
   423   else 
   355   else 
   424     {
   356     {
   425       params.EnableAck ();
   357       params.EnableAck ();
   426       
   358       
   429           params.DisableRts ();
   361           params.DisableRts ();
   430           WifiMacHeader hdr;
   362           WifiMacHeader hdr;
   431           Packet fragment = GetFragmentPacket (&hdr);
   363           Packet fragment = GetFragmentPacket (&hdr);
   432           if (IsLastFragment ()) 
   364           if (IsLastFragment ()) 
   433             {
   365             {
   434               NS_LOG_DEBUG ("fragmenting last fragment size="<<fragment.GetSize ());
   366               MY_DEBUG ("fragmenting last fragment size="<<fragment.GetSize ());
   435               params.DisableNextData ();
   367               params.DisableNextData ();
   436             } 
   368             } 
   437           else 
   369           else 
   438             {
   370             {
   439               NS_LOG_DEBUG ("fragmenting size="<<fragment.GetSize ());
   371               MY_DEBUG ("fragmenting size="<<fragment.GetSize ());
   440               params.EnableNextData (GetNextFragmentSize ());
   372               params.EnableNextData (GetNextFragmentSize ());
   441             }
   373             }
   442           Low ()->StartTransmission (fragment, &hdr, params, 
   374           Low ()->StartTransmission (fragment, &hdr, params, 
   443                                      m_transmissionListener);
   375                                      m_transmissionListener);
   444         } 
   376         } 
   445       else 
   377       else 
   446         {
   378         {
   447           if (NeedRts ()) 
   379           if (NeedRts ()) 
   448             {
   380             {
   449               params.EnableRts ();
   381               params.EnableRts ();
   450               NS_LOG_DEBUG ("tx unicast rts");
   382               MY_DEBUG ("tx unicast rts");
   451             } 
   383             } 
   452           else 
   384           else 
   453             {
   385             {
   454               params.DisableRts ();
   386               params.DisableRts ();
   455               NS_LOG_DEBUG ("tx unicast");
   387               MY_DEBUG ("tx unicast");
   456             }
   388             }
   457           params.DisableNextData ();
   389           params.DisableNextData ();
   458           // We need to make a copy in case we need to 
   390           // We need to make a copy in case we need to 
   459           // retransmit the packet: the MacLow modifies the input
   391           // retransmit the packet: the MacLow modifies the input
   460           // Packet so, we would retransmit a modified packet
   392           // Packet so, we would retransmit a modified packet
   466                                      params, m_transmissionListener);
   398                                      params, m_transmissionListener);
   467         }
   399         }
   468     }
   400     }
   469 }
   401 }
   470 
   402 
       
   403 void 
       
   404 DcaTxop::NotifyInternalCollision (void)
       
   405 {
       
   406   NotifyCollision ();
       
   407 }
       
   408 void 
       
   409 DcaTxop::NotifyCollision (void)
       
   410 {
       
   411   MY_DEBUG ("collision");
       
   412   m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
       
   413   RestartAccessIfNeeded ();
       
   414 }
   471 
   415 
   472 void 
   416 void 
   473 DcaTxop::GotCts (double snr, WifiMode txMode)
   417 DcaTxop::GotCts (double snr, WifiMode txMode)
   474 {
   418 {
   475   NS_LOG_DEBUG ("got cts");
   419   MY_DEBUG ("got cts");
   476   m_ssrc = 0;
   420   m_ssrc = 0;
   477 }
   421 }
   478 void 
   422 void 
   479 DcaTxop::MissedCts (void)
   423 DcaTxop::MissedCts (void)
   480 {
   424 {
   481   NS_LOG_DEBUG ("missed cts");
   425   MY_DEBUG ("missed cts");
   482   m_ssrc++;
   426   m_ssrc++;
   483   m_ctstimeoutTrace (m_ssrc);
   427   m_ctstimeoutTrace (m_ssrc);
   484   if (m_ssrc > Parameters ()->GetMaxSsrc ()) 
   428   if (m_ssrc > Parameters ()->GetMaxSsrc ()) 
   485     {
   429     {
   486       // to reset the dcf.
   430       // to reset the dcf.
       
   431       m_hasCurrent = false;
   487       m_dcf->ResetCw ();
   432       m_dcf->ResetCw ();
   488       m_dcf->StartBackoff ();
       
   489       m_hasCurrent = false;
       
   490     } 
   433     } 
   491   else 
   434   else 
   492     {
   435     {
   493       m_dcf->UpdateFailedCw ();
   436       m_dcf->UpdateFailedCw ();
   494       m_dcf->StartBackoff ();
   437     }
   495     }
   438   m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
       
   439   RestartAccessIfNeeded ();
   496 }
   440 }
   497 void 
   441 void 
   498 DcaTxop::GotAck (double snr, WifiMode txMode)
   442 DcaTxop::GotAck (double snr, WifiMode txMode)
   499 {
   443 {
   500   m_slrc = 0;
   444   m_slrc = 0;
   501   if (!NeedFragmentation () ||
   445   if (!NeedFragmentation () ||
   502       IsLastFragment ()) 
   446       IsLastFragment ()) 
   503     {
   447     {
   504       NS_LOG_DEBUG ("got ack. tx done.");
   448       MY_DEBUG ("got ack. tx done.");
   505       if (!m_txOkCallback.IsNull ()) 
   449       if (!m_txOkCallback.IsNull ()) 
   506         {
   450         {
   507           m_txOkCallback (m_currentHdr);
   451           m_txOkCallback (m_currentHdr);
   508         }
   452         }
   509 
   453 
   510       /* we are not fragmenting or we are done fragmenting
   454       /* we are not fragmenting or we are done fragmenting
   511        * so we can get rid of that packet now.
   455        * so we can get rid of that packet now.
   512        */
   456        */
   513       m_hasCurrent = false;
   457       m_hasCurrent = false;
   514       m_dcf->ResetCw ();
   458       m_dcf->ResetCw ();
   515       m_dcf->StartBackoff ();
   459       m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
   516     } 
   460       RestartAccessIfNeeded ();
   517   else 
   461     } 
   518     {
   462   else 
   519       NS_LOG_DEBUG ("got ack. tx not done, size="<<m_currentPacket.GetSize ());
   463     {
       
   464       MY_DEBUG ("got ack. tx not done, size="<<m_currentPacket.GetSize ());
   520     }
   465     }
   521 }
   466 }
   522 void 
   467 void 
   523 DcaTxop::MissedAck (void)
   468 DcaTxop::MissedAck (void)
   524 {
   469 {
   525   NS_LOG_DEBUG ("missed ack");
   470   MY_DEBUG ("missed ack");
   526   m_slrc++;
   471   m_slrc++;
   527   m_acktimeoutTrace (m_slrc);
   472   m_acktimeoutTrace (m_slrc);
   528   if (m_slrc > Parameters ()->GetMaxSlrc ()) 
   473   if (m_slrc > Parameters ()->GetMaxSlrc ()) 
   529     {
   474     {
   530       // to reset the dcf.    
   475       // to reset the dcf.    
       
   476       m_hasCurrent = false;
   531       m_dcf->ResetCw ();
   477       m_dcf->ResetCw ();
   532       m_dcf->StartBackoff ();
       
   533       m_hasCurrent = false;
       
   534     } 
   478     } 
   535   else 
   479   else 
   536     {
   480     {
   537       m_currentHdr.SetRetry ();
   481       m_currentHdr.SetRetry ();
   538       if (!m_txFailedCallback.IsNull ()) 
   482       if (!m_txFailedCallback.IsNull ()) 
   539         {
   483         {
   540           m_txFailedCallback (m_currentHdr);
   484           m_txFailedCallback (m_currentHdr);
   541         }
   485         }
   542       m_dcf->UpdateFailedCw ();
   486       m_dcf->UpdateFailedCw ();
   543       m_dcf->StartBackoff ();
   487     }
   544     }
   488   m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
   545   
   489   RestartAccessIfNeeded ();
   546 }
   490 }
   547 void 
   491 void 
   548 DcaTxop::StartNext (void)
   492 DcaTxop::StartNext (void)
   549 {
   493 {
   550   NS_LOG_DEBUG ("start next packet fragment");
   494   MY_DEBUG ("start next packet fragment");
   551   /* this callback is used only for fragments. */
   495   /* this callback is used only for fragments. */
   552   NextFragment ();
   496   NextFragment ();
   553   WifiMacHeader hdr;
   497   WifiMacHeader hdr;
   554   Packet fragment = GetFragmentPacket (&hdr);
   498   Packet fragment = GetFragmentPacket (&hdr);
   555   MacLowTransmissionParameters params;
   499   MacLowTransmissionParameters params;
   568 }
   512 }
   569 
   513 
   570 void
   514 void
   571 DcaTxop::Cancel (void)
   515 DcaTxop::Cancel (void)
   572 {
   516 {
   573   NS_LOG_DEBUG ("transmission cancelled");
   517   MY_DEBUG ("transmission cancelled");
   574   /**
   518   /**
   575    * This happens in only one case: in an AP, you have two DcaTxop:
   519    * This happens in only one case: in an AP, you have two DcaTxop:
   576    *   - one is used exclusively for beacons and has a high priority.
   520    *   - one is used exclusively for beacons and has a high priority.
   577    *   - the other is used for everything else and has a normal
   521    *   - the other is used for everything else and has a normal
   578    *     priority.
   522    *     priority.
   580    * If the normal queue tries to send a unicast data frame, but 
   524    * If the normal queue tries to send a unicast data frame, but 
   581    * if the tx fails (ack timeout), it starts a backoff. If the beacon
   525    * if the tx fails (ack timeout), it starts a backoff. If the beacon
   582    * queue gets a tx oportunity during this backoff, it will trigger
   526    * queue gets a tx oportunity during this backoff, it will trigger
   583    * a call to this Cancel function.
   527    * a call to this Cancel function.
   584    *
   528    *
   585    * Since we are already doing a backoff, so we will get access to
   529    * Since we are already doing a backoff, we will get access to
   586    * the medium when we can, we have nothing to do here. We just 
   530    * the medium when we can, we have nothing to do here. We just 
   587    * ignore the cancel event and wait until we are given again a 
   531    * ignore the cancel event and wait until we are given again a 
   588    * tx oportunity.
   532    * tx oportunity.
   589    *
   533    *
   590    * Note that this is really non-trivial because each of these
   534    * Note that this is really non-trivial because each of these