src/devices/wifi/dca-txop.cc
changeset 2159 20f882e85b4a
parent 2146 40ad60ac9912
child 2161 f5086fb78018
equal deleted inserted replaced
2158:1bae76be026d 2159:20f882e85b4a
    94   DcaTxop *m_txop;
    94   DcaTxop *m_txop;
    95 };
    95 };
    96 
    96 
    97 DcaTxop::DcaTxop (uint32_t minCw, uint32_t maxCw, uint32_t aifsn, DcfManager *manager)
    97 DcaTxop::DcaTxop (uint32_t minCw, uint32_t maxCw, uint32_t aifsn, DcfManager *manager)
    98   : m_manager (manager),
    98   : m_manager (manager),
    99     m_hasCurrent (false),
    99     m_currentPacket (0),
   100     m_ssrc (0),
   100     m_ssrc (0),
   101     m_slrc (0)
   101     m_slrc (0)
   102 
   102 
   103 {
   103 {
   104   m_transmissionListener = new DcaTxop::TransmissionListener (this);
   104   m_transmissionListener = new DcaTxop::TransmissionListener (this);
   156 {
   156 {
   157   m_queue->SetMaxDelay (delay);
   157   m_queue->SetMaxDelay (delay);
   158 }
   158 }
   159 
   159 
   160 void 
   160 void 
   161 DcaTxop::Queue (Packet packet, WifiMacHeader const &hdr)
   161 DcaTxop::Queue (Ptr<const Packet> packet, WifiMacHeader const &hdr)
   162 {
   162 {
   163   m_queue->Enqueue (packet, hdr);
   163   m_queue->Enqueue (packet, hdr);
   164   StartAccessIfNeeded ();
   164   StartAccessIfNeeded ();
   165 }
   165 }
   166 
   166 
   167 void
   167 void
   168 DcaTxop::RestartAccessIfNeeded (void)
   168 DcaTxop::RestartAccessIfNeeded (void)
   169 {
   169 {
   170   if ((m_hasCurrent ||
   170   if ((m_currentPacket != 0 ||
   171        !m_queue->IsEmpty ()) &&
   171        !m_queue->IsEmpty ()) &&
   172       !m_dcf->IsAccessRequested ())
   172       !m_dcf->IsAccessRequested ())
   173     {
   173     {
   174       m_manager->RequestAccess (m_dcf);
   174       m_manager->RequestAccess (m_dcf);
   175     }
   175     }
   176 }
   176 }
   177 
   177 
   178 void
   178 void
   179 DcaTxop::StartAccessIfNeeded (void)
   179 DcaTxop::StartAccessIfNeeded (void)
   180 {
   180 {
   181   if (!m_hasCurrent &&
   181   if (m_currentPacket == 0 &&
   182       !m_queue->IsEmpty () &&
   182       !m_queue->IsEmpty () &&
   183       !m_dcf->IsAccessRequested ())
   183       !m_dcf->IsAccessRequested ())
   184     {
   184     {
   185       m_manager->RequestAccess (m_dcf);
   185       m_manager->RequestAccess (m_dcf);
   186     }
   186     }
   201 
   201 
   202 
   202 
   203 bool
   203 bool
   204 DcaTxop::NeedRts (void)
   204 DcaTxop::NeedRts (void)
   205 {
   205 {
   206   if (m_currentPacket.GetSize () > Parameters ()->GetRtsCtsThreshold ()) 
   206   if (m_currentPacket->GetSize () > Parameters ()->GetRtsCtsThreshold ()) 
   207     {
   207     {
   208       return true;
   208       return true;
   209     } 
   209     } 
   210   else 
   210   else 
   211     {
   211     {
   214 }
   214 }
   215 
   215 
   216 bool
   216 bool
   217 DcaTxop::NeedFragmentation (void)
   217 DcaTxop::NeedFragmentation (void)
   218 {
   218 {
   219   if (m_currentPacket.GetSize () > Parameters ()->GetFragmentationThreshold ()) 
   219   if (m_currentPacket->GetSize () > Parameters ()->GetFragmentationThreshold ()) 
   220     {
   220     {
   221       return true;
   221       return true;
   222     } 
   222     } 
   223   else 
   223   else 
   224     {
   224     {
   227 }
   227 }
   228 
   228 
   229 uint32_t
   229 uint32_t
   230 DcaTxop::GetNFragments (void)
   230 DcaTxop::GetNFragments (void)
   231 {
   231 {
   232   uint32_t nFragments = m_currentPacket.GetSize () / Parameters ()->GetFragmentationThreshold () + 1;
   232   uint32_t nFragments = m_currentPacket->GetSize () / Parameters ()->GetFragmentationThreshold () + 1;
   233   return nFragments;
   233   return nFragments;
   234 }
   234 }
   235 void
   235 void
   236 DcaTxop::NextFragment (void)
   236 DcaTxop::NextFragment (void)
   237 {
   237 {
   239 }
   239 }
   240 
   240 
   241 uint32_t
   241 uint32_t
   242 DcaTxop::GetLastFragmentSize (void)
   242 DcaTxop::GetLastFragmentSize (void)
   243 {
   243 {
   244   uint32_t lastFragmentSize = m_currentPacket.GetSize () %
   244   uint32_t lastFragmentSize = m_currentPacket->GetSize () %
   245     Parameters ()->GetFragmentationThreshold ();
   245     Parameters ()->GetFragmentationThreshold ();
   246   return lastFragmentSize;
   246   return lastFragmentSize;
   247 }
   247 }
   248 
   248 
   249 uint32_t
   249 uint32_t
   281     {
   281     {
   282       return GetFragmentSize ();
   282       return GetFragmentSize ();
   283     }
   283     }
   284 }
   284 }
   285 
   285 
   286 Packet 
   286 Ptr<Packet>
   287 DcaTxop::GetFragmentPacket (WifiMacHeader *hdr)
   287 DcaTxop::GetFragmentPacket (WifiMacHeader *hdr)
   288 {
   288 {
   289   *hdr = m_currentHdr;
   289   *hdr = m_currentHdr;
   290   hdr->SetFragmentNumber (m_fragmentNumber);
   290   hdr->SetFragmentNumber (m_fragmentNumber);
   291   uint32_t startOffset = m_fragmentNumber * GetFragmentSize ();
   291   uint32_t startOffset = m_fragmentNumber * GetFragmentSize ();
   292   Packet fragment;
   292   Ptr<Packet> fragment;
   293   if (IsLastFragment ()) 
   293   if (IsLastFragment ()) 
   294     {
   294     {
   295       hdr->SetNoMoreFragments ();
   295       hdr->SetNoMoreFragments ();
   296       fragment = m_currentPacket.CreateFragment (startOffset, 
   296       fragment = m_currentPacket->CreateFragment (startOffset, 
   297                                                  GetLastFragmentSize ());
   297                                                  GetLastFragmentSize ());
   298     } 
   298     } 
   299   else 
   299   else 
   300     {
   300     {
   301       hdr->SetMoreFragments ();
   301       hdr->SetMoreFragments ();
   302       fragment = m_currentPacket.CreateFragment (startOffset, 
   302       fragment = m_currentPacket->CreateFragment (startOffset, 
   303                                                  GetFragmentSize ());
   303                                                  GetFragmentSize ());
   304     }
   304     }
   305   return fragment;
   305   return fragment;
   306 }
   306 }
   307 
   307 
   308 bool 
   308 bool 
   309 DcaTxop::NeedsAccess (void) const
   309 DcaTxop::NeedsAccess (void) const
   310 {
   310 {
   311   return !m_queue->IsEmpty () || m_hasCurrent;
   311   return !m_queue->IsEmpty () || m_currentPacket != 0;
   312 }
   312 }
   313 void 
   313 void 
   314 DcaTxop::NotifyAccessGranted (void)
   314 DcaTxop::NotifyAccessGranted (void)
   315 {
   315 {
   316   if (!m_hasCurrent) 
   316   if (m_currentPacket == 0) 
   317     {
   317     {
   318       if (m_queue->IsEmpty ()) 
   318       if (m_queue->IsEmpty ()) 
   319         {
   319         {
   320           MY_DEBUG ("queue empty");
   320           MY_DEBUG ("queue empty");
   321           return;
   321           return;
   322         }
   322         }
   323       bool found;
   323       m_currentPacket = m_queue->Dequeue (&m_currentHdr);
   324       m_currentPacket = m_queue->Dequeue (&m_currentHdr, &found);
   324       NS_ASSERT (m_currentPacket != 0);
   325       NS_ASSERT (found);
       
   326       m_hasCurrent = true;
       
   327       NS_ASSERT (m_hasCurrent);
       
   328       uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&m_currentHdr);
   325       uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&m_currentHdr);
   329       m_currentHdr.SetSequenceNumber (sequence);
   326       m_currentHdr.SetSequenceNumber (sequence);
   330       m_currentHdr.SetFragmentNumber (0);
   327       m_currentHdr.SetFragmentNumber (0);
   331       m_currentHdr.SetNoMoreFragments ();
   328       m_currentHdr.SetNoMoreFragments ();
   332       m_ssrc = 0;
   329       m_ssrc = 0;
   333       m_slrc = 0;
   330       m_slrc = 0;
   334       m_fragmentNumber = 0;
   331       m_fragmentNumber = 0;
   335       MY_DEBUG ("dequeued size="<<m_currentPacket.GetSize ()<<
   332       MY_DEBUG ("dequeued size="<<m_currentPacket->GetSize ()<<
   336                     ", to="<<m_currentHdr.GetAddr1 ()<<
   333                     ", to="<<m_currentHdr.GetAddr1 ()<<
   337                     ", seq="<<m_currentHdr.GetSequenceControl ()); 
   334                     ", seq="<<m_currentHdr.GetSequenceControl ()); 
   338     }
   335     }
   339   MacLowTransmissionParameters params;
   336   MacLowTransmissionParameters params;
   340   params.DisableOverrideDurationId ();
   337   params.DisableOverrideDurationId ();
   345       params.DisableNextData ();
   342       params.DisableNextData ();
   346       Low ()->StartTransmission (m_currentPacket,
   343       Low ()->StartTransmission (m_currentPacket,
   347                                  &m_currentHdr,
   344                                  &m_currentHdr,
   348                                  params,
   345                                  params,
   349                                  m_transmissionListener);
   346                                  m_transmissionListener);
   350       m_hasCurrent = false;
   347       m_currentPacket = 0;
   351       m_dcf->ResetCw ();
   348       m_dcf->ResetCw ();
   352       m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
   349       m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
   353       MY_DEBUG ("tx broadcast");
   350       MY_DEBUG ("tx broadcast");
   354     } 
   351     } 
   355   else 
   352   else 
   358       
   355       
   359       if (NeedFragmentation ()) 
   356       if (NeedFragmentation ()) 
   360         {
   357         {
   361           params.DisableRts ();
   358           params.DisableRts ();
   362           WifiMacHeader hdr;
   359           WifiMacHeader hdr;
   363           Packet fragment = GetFragmentPacket (&hdr);
   360           Ptr<Packet> fragment = GetFragmentPacket (&hdr);
   364           if (IsLastFragment ()) 
   361           if (IsLastFragment ()) 
   365             {
   362             {
   366               MY_DEBUG ("fragmenting last fragment size="<<fragment.GetSize ());
   363               MY_DEBUG ("fragmenting last fragment size="<<fragment->GetSize ());
   367               params.DisableNextData ();
   364               params.DisableNextData ();
   368             } 
   365             } 
   369           else 
   366           else 
   370             {
   367             {
   371               MY_DEBUG ("fragmenting size="<<fragment.GetSize ());
   368               MY_DEBUG ("fragmenting size="<<fragment->GetSize ());
   372               params.EnableNextData (GetNextFragmentSize ());
   369               params.EnableNextData (GetNextFragmentSize ());
   373             }
   370             }
   374           Low ()->StartTransmission (fragment, &hdr, params, 
   371           Low ()->StartTransmission (fragment, &hdr, params, 
   375                                      m_transmissionListener);
   372                                      m_transmissionListener);
   376         } 
   373         } 
   385             {
   382             {
   386               params.DisableRts ();
   383               params.DisableRts ();
   387               MY_DEBUG ("tx unicast");
   384               MY_DEBUG ("tx unicast");
   388             }
   385             }
   389           params.DisableNextData ();
   386           params.DisableNextData ();
   390           // We need to make a copy in case we need to 
   387           Low ()->StartTransmission (m_currentPacket, &m_currentHdr,
   391           // retransmit the packet: the MacLow modifies the input
       
   392           // Packet so, we would retransmit a modified packet
       
   393           // if we were not to make a copy.
       
   394           // XXX the comment above and the code below do not
       
   395           // make sense anymore. So, we should remove both.
       
   396           Packet copy = m_currentPacket;
       
   397           Low ()->StartTransmission (copy, &m_currentHdr,
       
   398                                      params, m_transmissionListener);
   388                                      params, m_transmissionListener);
   399         }
   389         }
   400     }
   390     }
   401 }
   391 }
   402 
   392 
   426   m_ssrc++;
   416   m_ssrc++;
   427   m_ctstimeoutTrace (m_ssrc);
   417   m_ctstimeoutTrace (m_ssrc);
   428   if (m_ssrc > Parameters ()->GetMaxSsrc ()) 
   418   if (m_ssrc > Parameters ()->GetMaxSsrc ()) 
   429     {
   419     {
   430       // to reset the dcf.
   420       // to reset the dcf.
   431       m_hasCurrent = false;
   421       m_currentPacket = 0;
   432       m_dcf->ResetCw ();
   422       m_dcf->ResetCw ();
   433     } 
   423     } 
   434   else 
   424   else 
   435     {
   425     {
   436       m_dcf->UpdateFailedCw ();
   426       m_dcf->UpdateFailedCw ();
   452         }
   442         }
   453 
   443 
   454       /* we are not fragmenting or we are done fragmenting
   444       /* we are not fragmenting or we are done fragmenting
   455        * so we can get rid of that packet now.
   445        * so we can get rid of that packet now.
   456        */
   446        */
   457       m_hasCurrent = false;
   447       m_currentPacket = 0;
   458       m_dcf->ResetCw ();
   448       m_dcf->ResetCw ();
   459       m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
   449       m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
   460       RestartAccessIfNeeded ();
   450       RestartAccessIfNeeded ();
   461     } 
   451     } 
   462   else 
   452   else 
   463     {
   453     {
   464       MY_DEBUG ("got ack. tx not done, size="<<m_currentPacket.GetSize ());
   454       MY_DEBUG ("got ack. tx not done, size="<<m_currentPacket->GetSize ());
   465     }
   455     }
   466 }
   456 }
   467 void 
   457 void 
   468 DcaTxop::MissedAck (void)
   458 DcaTxop::MissedAck (void)
   469 {
   459 {
   471   m_slrc++;
   461   m_slrc++;
   472   m_acktimeoutTrace (m_slrc);
   462   m_acktimeoutTrace (m_slrc);
   473   if (m_slrc > Parameters ()->GetMaxSlrc ()) 
   463   if (m_slrc > Parameters ()->GetMaxSlrc ()) 
   474     {
   464     {
   475       // to reset the dcf.    
   465       // to reset the dcf.    
   476       m_hasCurrent = false;
   466       m_currentPacket = 0;
   477       m_dcf->ResetCw ();
   467       m_dcf->ResetCw ();
   478     } 
   468     } 
   479   else 
   469   else 
   480     {
   470     {
   481       m_currentHdr.SetRetry ();
   471       m_currentHdr.SetRetry ();
   493 {
   483 {
   494   MY_DEBUG ("start next packet fragment");
   484   MY_DEBUG ("start next packet fragment");
   495   /* this callback is used only for fragments. */
   485   /* this callback is used only for fragments. */
   496   NextFragment ();
   486   NextFragment ();
   497   WifiMacHeader hdr;
   487   WifiMacHeader hdr;
   498   Packet fragment = GetFragmentPacket (&hdr);
   488   Ptr<Packet> fragment = GetFragmentPacket (&hdr);
   499   MacLowTransmissionParameters params;
   489   MacLowTransmissionParameters params;
   500   params.EnableAck ();
   490   params.EnableAck ();
   501   params.DisableRts ();
   491   params.DisableRts ();
   502   params.DisableOverrideDurationId ();
   492   params.DisableOverrideDurationId ();
   503   if (IsLastFragment ()) 
   493   if (IsLastFragment ())