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 } |
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 |
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 { |
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 ()) |