LEFT | RIGHT |
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ | 1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ |
2 /* | 2 /* |
3 * Copyright (c) 2006, 2009 INRIA | 3 * Copyright (c) 2006, 2009 INRIA |
4 * Copyright (c) 2009 MIRKO BANCHI | 4 * Copyright (c) 2009 MIRKO BANCHI |
5 * | 5 * |
6 * This program is free software; you can redistribute it and/or modify | 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· | 7 * it under the terms of the GNU General Public License version 2 as· |
8 * published by the Free Software Foundation; | 8 * published by the Free Software Foundation; |
9 * | 9 * |
10 * This program is distributed in the hope that it will be useful, | 10 * This program is distributed in the hope that it will be useful, |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "edca-txop-n.h" | 25 #include "edca-txop-n.h" |
26 #include "mac-low.h" | 26 #include "mac-low.h" |
27 #include "dcf-manager.h" | 27 #include "dcf-manager.h" |
28 #include "mac-tx-middle.h" | 28 #include "mac-tx-middle.h" |
29 #include "wifi-mac-trailer.h" | 29 #include "wifi-mac-trailer.h" |
30 #include "wifi-mac.h" | 30 #include "wifi-mac.h" |
31 #include "random-stream.h" | 31 #include "random-stream.h" |
32 #include "wifi-mac-queue.h" | 32 #include "wifi-mac-queue.h" |
33 #include "msdu-aggregator.h" | 33 #include "msdu-aggregator.h" |
34 #include "mgt-headers.h" | 34 #include "mgt-headers.h" |
| 35 #include "qos-blocked-destinations.h" |
35 #include "block-ack-manager.h" | 36 #include "block-ack-manager.h" |
36 | 37 |
37 NS_LOG_COMPONENT_DEFINE ("EdcaTxopN"); | 38 NS_LOG_COMPONENT_DEFINE ("EdcaTxopN"); |
38 | 39 |
39 #define MY_DEBUG(x) \ | 40 #define MY_DEBUG(x) \ |
40 NS_LOG_DEBUG (m_low->GetAddress () << " " << x) | 41 NS_LOG_DEBUG (m_low->GetAddress () << " " << x) |
41 | 42 |
42 namespace ns3 { | 43 namespace ns3 { |
43 | 44 |
44 class EdcaTxopN::Dcf : public DcfState | 45 class EdcaTxopN::Dcf : public DcfState |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 } | 78 } |
78 virtual void MissedCts (void) { | 79 virtual void MissedCts (void) { |
79 m_txop->MissedCts (); | 80 m_txop->MissedCts (); |
80 } | 81 } |
81 virtual void GotAck (double snr, WifiMode txMode) { | 82 virtual void GotAck (double snr, WifiMode txMode) { |
82 m_txop->GotAck (snr, txMode); | 83 m_txop->GotAck (snr, txMode); |
83 } | 84 } |
84 virtual void MissedAck (void) { | 85 virtual void MissedAck (void) { |
85 m_txop->MissedAck (); | 86 m_txop->MissedAck (); |
86 } | 87 } |
87 virtual void GotBlockAck (CtrlBAckResponseHeader const *blockAck, Mac48Address
source) { | 88 virtual void GotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address
source) { |
88 m_txop->GotBlockAck (blockAck, source); | 89 m_txop->GotBlockAck (blockAck, source); |
89 } | 90 } |
90 virtual void MissedBlockAck (void) { | 91 virtual void MissedBlockAck (void) { |
91 m_txop->MissedBlockAck (); | 92 m_txop->MissedBlockAck (); |
92 } | 93 } |
93 virtual void StartNext (void) { | 94 virtual void StartNext (void) { |
94 m_txop->StartNext (); | 95 m_txop->StartNext (); |
95 } | 96 } |
96 virtual void Cancel (void) { | 97 virtual void Cancel (void) { |
97 m_txop->Cancel (); | 98 m_txop->Cancel (); |
98 } | 99 } |
99 | 100 |
100 private: | 101 private: |
101 EdcaTxopN *m_txop; | 102 EdcaTxopN *m_txop; |
102 }; | 103 }; |
103 | 104 |
104 class EdcaTxopN::BlockAckEventListener : public MacLowBlockAckEventListener | 105 class EdcaTxopN::BlockAckEventListener : public MacLowBlockAckEventListener |
105 { | 106 { |
106 public: | 107 public: |
107 BlockAckEventListener (EdcaTxopN *txop) | 108 BlockAckEventListener (EdcaTxopN *txop) |
108 : MacLowBlockAckEventListener (), | 109 : MacLowBlockAckEventListener (), |
109 m_txop (txop) {} | 110 m_txop (txop) {} |
110 virtual ~BlockAckEventListener () {} | 111 virtual ~BlockAckEventListener () {} |
111 | 112 |
112 virtual void BlockAckInactivityTimeout (Mac48Address address, uint8_t tid) { | 113 virtual void BlockAckInactivityTimeout (Mac48Address address, uint8_t tid) { |
113 m_txop->SendDelbaFrame (address, tid, true); | 114 m_txop->SendDelbaFrame (address, tid, false); |
114 } | 115 } |
115 | 116 |
116 private: | 117 private: |
117 EdcaTxopN *m_txop; | 118 EdcaTxopN *m_txop; |
118 }; | 119 }; |
119 | 120 |
120 NS_OBJECT_ENSURE_REGISTERED (EdcaTxopN); | 121 NS_OBJECT_ENSURE_REGISTERED (EdcaTxopN); |
121 | 122 |
122 TypeId | 123 TypeId |
123 EdcaTxopN::GetTypeId (void) | 124 EdcaTxopN::GetTypeId (void) |
(...skipping 23 matching lines...) Expand all Loading... |
147 m_currentPacket(0), | 148 m_currentPacket(0), |
148 m_aggregator (0), | 149 m_aggregator (0), |
149 m_blockAckType (COMPRESSED_BLOCK_ACK) | 150 m_blockAckType (COMPRESSED_BLOCK_ACK) |
150 { | 151 { |
151 NS_LOG_FUNCTION (this); | 152 NS_LOG_FUNCTION (this); |
152 m_transmissionListener = new EdcaTxopN::TransmissionListener (this); | 153 m_transmissionListener = new EdcaTxopN::TransmissionListener (this); |
153 m_blockAckListener = new EdcaTxopN::BlockAckEventListener (this); | 154 m_blockAckListener = new EdcaTxopN::BlockAckEventListener (this); |
154 m_dcf = new EdcaTxopN::Dcf (this); | 155 m_dcf = new EdcaTxopN::Dcf (this); |
155 m_queue = CreateObject<WifiMacQueue> (); | 156 m_queue = CreateObject<WifiMacQueue> (); |
156 m_rng = new RealRandomStream (); | 157 m_rng = new RealRandomStream (); |
| 158 m_qosBlockedDestinations = new QosBlockedDestinations (); |
157 m_baManager = new BlockAckManager (); | 159 m_baManager = new BlockAckManager (); |
158 m_baManager->SetQueue (m_queue); | 160 m_baManager->SetQueue (m_queue); |
159 m_baManager->SetBlockAckType (m_blockAckType); | 161 m_baManager->SetBlockAckType (m_blockAckType); |
| 162 m_baManager->SetBlockDestinationCallback (MakeCallback (&QosBlockedDestination
s::Block, m_qosBlockedDestinations)); |
| 163 m_baManager->SetUnblockDestinationCallback (MakeCallback (&QosBlockedDestinati
ons::Unblock, m_qosBlockedDestinations)); |
| 164 m_baManager->SetMaxPacketDelay (m_queue->GetMaxDelay ()); |
160 } | 165 } |
161 | 166 |
162 EdcaTxopN::~EdcaTxopN () | 167 EdcaTxopN::~EdcaTxopN () |
163 { | 168 { |
164 NS_LOG_FUNCTION (this); | 169 NS_LOG_FUNCTION (this); |
165 } | 170 } |
166 | 171 |
167 void | 172 void |
168 EdcaTxopN::DoDispose (void) | 173 EdcaTxopN::DoDispose (void) |
169 { | 174 { |
170 NS_LOG_FUNCTION (this); | 175 NS_LOG_FUNCTION (this); |
171 m_queue = 0; | 176 m_queue = 0; |
172 m_low = 0; | 177 m_low = 0; |
173 m_stationManager = 0; | 178 m_stationManager = 0; |
174 delete m_transmissionListener; | 179 delete m_transmissionListener; |
175 delete m_blockAckListener; | |
176 delete m_dcf; | 180 delete m_dcf; |
177 delete m_rng; | 181 delete m_rng; |
| 182 delete m_qosBlockedDestinations; |
178 delete m_baManager; | 183 delete m_baManager; |
| 184 delete m_blockAckListener; |
179 m_transmissionListener = 0; | 185 m_transmissionListener = 0; |
180 m_blockAckListener = 0; | |
181 m_dcf = 0; | 186 m_dcf = 0; |
182 m_rng = 0; | 187 m_rng = 0; |
| 188 m_qosBlockedDestinations = 0; |
183 m_baManager = 0; | 189 m_baManager = 0; |
| 190 m_blockAckListener = 0; |
184 m_txMiddle = 0; | 191 m_txMiddle = 0; |
185 m_aggregator = 0; | 192 m_aggregator = 0; |
186 } | 193 } |
187 | 194 |
188 void | 195 void |
189 EdcaTxopN::SetManager (DcfManager *manager) | 196 EdcaTxopN::SetManager (DcfManager *manager) |
190 { | 197 { |
191 NS_LOG_FUNCTION (this << manager); | 198 NS_LOG_FUNCTION (this << manager); |
192 m_manager = manager; | 199 m_manager = manager; |
193 m_manager->Add (m_dcf); | 200 m_manager->Add (m_dcf); |
(...skipping 23 matching lines...) Expand all Loading... |
217 NS_LOG_FUNCTION (this << type); | 224 NS_LOG_FUNCTION (this << type); |
218 m_typeOfStation = type; | 225 m_typeOfStation = type; |
219 } | 226 } |
220 | 227 |
221 enum TypeOfStation | 228 enum TypeOfStation |
222 EdcaTxopN::GetTypeOfStation (void) const | 229 EdcaTxopN::GetTypeOfStation (void) const |
223 { | 230 { |
224 return m_typeOfStation; | 231 return m_typeOfStation; |
225 } | 232 } |
226 | 233 |
227 const MacTxMiddle* | |
228 EdcaTxopN::GetTxMiddle (void) const | |
229 { | |
230 return m_txMiddle; | |
231 } | |
232 | |
233 void· | 234 void· |
234 EdcaTxopN::SetMaxQueueSize (uint32_t size) | 235 EdcaTxopN::SetMaxQueueSize (uint32_t size) |
235 { | 236 { |
236 NS_LOG_FUNCTION (this << size); | 237 NS_LOG_FUNCTION (this << size); |
237 m_queue->SetMaxSize (size); | 238 m_queue->SetMaxSize (size); |
238 } | 239 } |
239 | 240 |
240 void | 241 void |
241 EdcaTxopN::SetMaxQueueDelay (Time delay) | 242 EdcaTxopN::SetMaxQueueDelay (Time delay) |
242 { | 243 { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 void | 312 void |
312 EdcaTxopN::NotifyAccessGranted (void) | 313 EdcaTxopN::NotifyAccessGranted (void) |
313 { | 314 { |
314 NS_LOG_FUNCTION (this); | 315 NS_LOG_FUNCTION (this); |
315 if (m_currentPacket == 0) | 316 if (m_currentPacket == 0) |
316 { | 317 { |
317 if (m_queue->IsEmpty () && !m_baManager->HasPackets ()) | 318 if (m_queue->IsEmpty () && !m_baManager->HasPackets ()) |
318 { | 319 { |
319 MY_DEBUG ("queue is empty"); | 320 MY_DEBUG ("queue is empty"); |
320 return;· | 321 return;· |
| 322 } |
| 323 struct Bar bar; |
| 324 if (m_baManager->HasBar (bar)) |
| 325 { |
| 326 SendBlockAckRequest (bar); |
| 327 return; |
321 } | 328 } |
322 /* check if packets need retransmission are stored in BlockAckManager */ | 329 /* check if packets need retransmission are stored in BlockAckManager */ |
323 m_currentPacket = m_baManager->GetNextPacket (m_currentHdr); | 330 m_currentPacket = m_baManager->GetNextPacket (m_currentHdr); |
324 if (m_currentPacket == 0) | 331 if (m_currentPacket == 0) |
325 { | 332 { |
326 if (m_queue->PeekFirstAvailable (&m_currentHdr, m_currentPacketTimesta
mp) == 0) | 333 if (m_queue->PeekFirstAvailable (&m_currentHdr, m_currentPacketTimesta
mp, m_qosBlockedDestinations) == 0) |
327 { | 334 { |
328 MY_DEBUG ("no available packets in the queue"); | 335 MY_DEBUG ("no available packets in the queue"); |
329 return; | 336 return; |
330 } | 337 } |
331 if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast
() && | 338 if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast
() && |
332 m_blockAckThreshold > 0 && | 339 m_blockAckThreshold > 0 && |
333 !m_baManager->ExistsAgreement (m_currentHdr.GetAddr1 (), m_current
Hdr.GetQosTid ()) && | 340 !m_baManager->ExistsAgreement (m_currentHdr.GetAddr1 (), m_current
Hdr.GetQosTid ()) && |
334 SetupBlockAckIfNeeded ()) | 341 SetupBlockAckIfNeeded ()) |
335 { | 342 { |
336 return; | 343 return; |
337 } | 344 } |
338 m_currentPacket = m_queue->DequeueFirstAvailable (&m_currentHdr, m_cur
rentPacketTimestamp); | 345 m_currentPacket = m_queue->DequeueFirstAvailable (&m_currentHdr, m_cur
rentPacketTimestamp, m_qosBlockedDestinations); |
339 NS_ASSERT (m_currentPacket != 0); | 346 NS_ASSERT (m_currentPacket != 0); |
340 if (!m_currentHdr.IsBlockAckReq ()) | 347 |
341 { | 348 uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&m_currentHd
r); |
342 uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&m_curre
ntHdr); | 349 m_currentHdr.SetSequenceNumber (sequence); |
343 m_currentHdr.SetSequenceNumber (sequence); | 350 m_currentHdr.SetFragmentNumber (0); |
344 m_currentHdr.SetFragmentNumber (0); | 351 m_currentHdr.SetNoMoreFragments (); |
345 m_currentHdr.SetNoMoreFragments (); | 352 m_currentHdr.SetNoRetry (); |
346 m_currentHdr.SetNoRetry (); | 353 m_fragmentNumber = 0; |
347 } | 354 MY_DEBUG ("dequeued size="<<m_currentPacket->GetSize ()<< |
| 355 ", to="<<m_currentHdr.GetAddr1 ()<< |
| 356 ", seq="<<m_currentHdr.GetSequenceControl ()); |
348 if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast
()) | 357 if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast
()) |
349 { | 358 { |
350 VerifyBlockAck (); | 359 VerifyBlockAck (); |
351 } | 360 } |
352 m_fragmentNumber = 0; | |
353 MY_DEBUG ("dequeued size="<<m_currentPacket->GetSize ()<< | |
354 ", to="<<m_currentHdr.GetAddr1 ()<< | |
355 ", seq="<<m_currentHdr.GetSequenceControl ()); | |
356 } | 361 } |
357 } | 362 } |
358 MacLowTransmissionParameters params; | 363 MacLowTransmissionParameters params; |
359 params.DisableOverrideDurationId (); | 364 params.DisableOverrideDurationId (); |
360 if (m_currentHdr.IsBlockAckReq ()) | 365 if (m_currentHdr.GetAddr1 ().IsBroadcast ())· |
361 { | |
362 SendBlockAckRequest (); | |
363 } | |
364 else if (m_currentHdr.GetAddr1 ().IsBroadcast ())· | |
365 { | 366 { |
366 params.DisableRts (); | 367 params.DisableRts (); |
367 params.DisableAck (); | 368 params.DisableAck (); |
368 params.DisableNextData (); | 369 params.DisableNextData (); |
369 m_low->StartTransmission (m_currentPacket, | 370 m_low->StartTransmission (m_currentPacket, |
370 &m_currentHdr, | 371 &m_currentHdr, |
371 params, | 372 params, |
372 m_transmissionListener); | 373 m_transmissionListener); |
373 ······ | 374 ······ |
374 m_currentPacket = 0; | 375 m_currentPacket = 0; |
(...skipping 27 matching lines...) Expand all Loading... |
402 MY_DEBUG ("fragmenting last fragment size=" << fragment->GetSize (
)); | 403 MY_DEBUG ("fragmenting last fragment size=" << fragment->GetSize (
)); |
403 params.DisableNextData (); | 404 params.DisableNextData (); |
404 }· | 405 }· |
405 else· | 406 else· |
406 { | 407 { |
407 MY_DEBUG ("fragmenting size=" << fragment->GetSize ()); | 408 MY_DEBUG ("fragmenting size=" << fragment->GetSize ()); |
408 params.EnableNextData (GetNextFragmentSize ()); | 409 params.EnableNextData (GetNextFragmentSize ()); |
409 } | 410 } |
410 m_low->StartTransmission (fragment, &hdr, params,· | 411 m_low->StartTransmission (fragment, &hdr, params,· |
411 m_transmissionListener); | 412 m_transmissionListener); |
412 if (m_currentHdr.IsQosData () && m_currentHdr.IsQosBlockAck ()) | |
413 { | |
414 m_baManager->StorePacket (fragment, hdr, m_currentPacketTimestamp)
; | |
415 } | |
416 } | 413 } |
417 else | 414 else |
418 { | 415 { |
419 WifiMacHeader peekedHdr; | 416 WifiMacHeader peekedHdr; |
420 if (m_currentHdr.IsQosData () && | 417 if (m_currentHdr.IsQosData () && |
421 m_queue->PeekByTidAndAddress (&peekedHdr, m_currentHdr.GetQosTid (
),· | 418 m_queue->PeekByTidAndAddress (&peekedHdr, m_currentHdr.GetQosTid (
),· |
422 WifiMacHeader::ADDR1, m_currentHdr.G
etAddr1 ()) && | 419 WifiMacHeader::ADDR1, m_currentHdr.G
etAddr1 ()) && |
423 !m_currentHdr.GetAddr1 ().IsBroadcast () && | 420 !m_currentHdr.GetAddr1 ().IsBroadcast () && |
424 m_aggregator != 0 && !m_currentHdr.IsRetry ()) | 421 m_aggregator != 0 && !m_currentHdr.IsRetry ()) |
425 { | 422 { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 } | 522 } |
526 | 523 |
527 void· | 524 void· |
528 EdcaTxopN::NotifyChannelSwitching (void) | 525 EdcaTxopN::NotifyChannelSwitching (void) |
529 { | 526 { |
530 m_queue->Flush(); | 527 m_queue->Flush(); |
531 m_currentPacket = 0; | 528 m_currentPacket = 0; |
532 } | 529 } |
533 | 530 |
534 void | 531 void |
535 EdcaTxopN::Queue (Ptr<const Packet> packet, WifiMacHeader const &hdr) | 532 EdcaTxopN::Queue (Ptr<const Packet> packet, const WifiMacHeader &hdr) |
536 { | 533 { |
537 NS_LOG_FUNCTION (this << packet << &hdr); | 534 NS_LOG_FUNCTION (this << packet << &hdr); |
538 WifiMacTrailer fcs; | 535 WifiMacTrailer fcs; |
539 uint32_t fullPacketSize = hdr.GetSerializedSize () + packet->GetSize () + fcs.
GetSerializedSize (); | 536 uint32_t fullPacketSize = hdr.GetSerializedSize () + packet->GetSize () + fcs.
GetSerializedSize (); |
540 WifiRemoteStation *station = GetStation (hdr.GetAddr1 ()); | 537 WifiRemoteStation *station = GetStation (hdr.GetAddr1 ()); |
541 station->PrepareForQueue (packet, fullPacketSize); | 538 station->PrepareForQueue (packet, fullPacketSize); |
542 m_queue->Enqueue (packet, hdr); | 539 m_queue->Enqueue (packet, hdr); |
543 StartAccessIfNeeded (); | 540 StartAccessIfNeeded (); |
544 } | 541 } |
545 | 542 |
546 void | 543 void |
547 EdcaTxopN::GotAck (double snr, WifiMode txMode) | 544 EdcaTxopN::GotAck (double snr, WifiMode txMode) |
548 { | 545 { |
549 NS_LOG_FUNCTION (this << snr << txMode); | 546 NS_LOG_FUNCTION (this << snr << txMode); |
550 if (!NeedFragmentation () || | 547 if (!NeedFragmentation () || |
551 IsLastFragment () || | 548 IsLastFragment () || |
552 m_currentHdr.IsQosAmsdu ())· | 549 m_currentHdr.IsQosAmsdu ())· |
553 { | 550 { |
554 MY_DEBUG ("got ack. tx done."); | 551 MY_DEBUG ("got ack. tx done."); |
555 if (!m_txOkCallback.IsNull ()) | 552 if (!m_txOkCallback.IsNull ()) |
556 { | 553 { |
557 m_txOkCallback (m_currentHdr); | 554 m_txOkCallback (m_currentHdr); |
558 } | 555 } |
559 ······ | 556 ······ |
560 if (m_currentHdr.IsAction ()) | 557 if (m_currentHdr.IsAction ()) |
561 { | 558 { |
562 MgtActionFrameHeader actHdr; | 559 WifiActionHeader actionHdr; |
563 m_currentPacket->PeekHeader (actHdr); | 560 Ptr<Packet> p = m_currentPacket->Copy (); |
564 if (actHdr.IsDelBa ()) | 561 p->RemoveHeader (actionHdr); |
| 562 if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK && |
| 563 actionHdr.GetAction ().blockAck == WifiActionHeader::BLOCK_ACK_DEL
BA) |
565 { | 564 { |
566 MgtDelBaHeader delBa; | 565 MgtDelBaHeader delBa; |
567 m_currentPacket->PeekHeader (delBa); | 566 p->PeekHeader (delBa); |
568 if (delBa.IsByOriginator ()) | 567 if (delBa.IsByOriginator ()) |
569 { | 568 { |
570 m_baManager->TearDownBlockAck (m_currentHdr.GetAddr1 (), delBa
.GetTid ()); | 569 m_baManager->TearDownBlockAck (m_currentHdr.GetAddr1 (), delBa
.GetTid ()); |
571 } | 570 } |
572 else | 571 else |
573 { | 572 { |
574 m_low->DestroyBlockAckAgreement (m_currentHdr.GetAddr1 (), del
Ba.GetTid ()); | 573 m_low->DestroyBlockAckAgreement (m_currentHdr.GetAddr1 (), del
Ba.GetTid ()); |
575 } | 574 } |
576 } | 575 } |
577 } | 576 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 m_dcf->UpdateFailedCw (); | 611 m_dcf->UpdateFailedCw (); |
613 } | 612 } |
614 m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ())); | 613 m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ())); |
615 RestartAccessIfNeeded (); | 614 RestartAccessIfNeeded (); |
616 } | 615 } |
617 | 616 |
618 void | 617 void |
619 EdcaTxopN::MissedBlockAck (void) | 618 EdcaTxopN::MissedBlockAck (void) |
620 { | 619 { |
621 NS_LOG_FUNCTION (this); | 620 NS_LOG_FUNCTION (this); |
622 MY_DEBUG ("missed block ack"); | 621 MY_DEBUG ("missed block ack"); |
623 //should i report this to station addressed by ADDR1? | 622 //should i report this to station addressed by ADDR1? |
624 MY_DEBUG ("Retransmit block ack request"); | 623 MY_DEBUG ("Retransmit block ack request"); |
625 m_currentHdr.SetRetry (); | 624 m_currentHdr.SetRetry (); |
626 m_dcf->UpdateFailedCw (); | 625 m_dcf->UpdateFailedCw (); |
627 ·· | 626 ·· |
628 m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ())); | 627 m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ())); |
629 RestartAccessIfNeeded (); | 628 RestartAccessIfNeeded (); |
630 } | 629 } |
631 | 630 |
632 Ptr<MsduAggregator> | 631 Ptr<MsduAggregator> |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 return fragment; | 777 return fragment; |
779 } | 778 } |
780 | 779 |
781 void | 780 void |
782 EdcaTxopN::SetAccessClass (enum AccessClass ac) | 781 EdcaTxopN::SetAccessClass (enum AccessClass ac) |
783 { | 782 { |
784 m_ac = ac; | 783 m_ac = ac; |
785 } | 784 } |
786 | 785 |
787 Mac48Address | 786 Mac48Address |
788 EdcaTxopN::MapSrcAddressForAggregation (WifiMacHeader const &hdr) | 787 EdcaTxopN::MapSrcAddressForAggregation (const WifiMacHeader &hdr) |
789 { | 788 { |
790 Mac48Address retval; | 789 Mac48Address retval; |
791 if (m_typeOfStation == STA || m_typeOfStation == ADHOC_STA) | 790 if (m_typeOfStation == STA || m_typeOfStation == ADHOC_STA) |
792 { | 791 { |
793 retval = hdr.GetAddr2 (); | 792 retval = hdr.GetAddr2 (); |
794 } | 793 } |
795 else | 794 else |
796 { | 795 { |
797 retval = hdr.GetAddr3 (); | 796 retval = hdr.GetAddr3 (); |
798 } | 797 } |
799 return retval; | 798 return retval; |
800 } | 799 } |
801 | 800 |
802 Mac48Address | 801 Mac48Address |
803 EdcaTxopN::MapDestAddressForAggregation (WifiMacHeader const &hdr) | 802 EdcaTxopN::MapDestAddressForAggregation (const WifiMacHeader &hdr) |
804 { | 803 { |
805 Mac48Address retval; | 804 Mac48Address retval; |
806 if (m_typeOfStation == AP || m_typeOfStation == ADHOC_STA) | 805 if (m_typeOfStation == AP || m_typeOfStation == ADHOC_STA) |
807 { | 806 { |
808 retval = hdr.GetAddr1 (); | 807 retval = hdr.GetAddr1 (); |
809 } | 808 } |
810 else | 809 else |
811 { | 810 { |
812 retval = hdr.GetAddr3 (); | 811 retval = hdr.GetAddr3 (); |
813 } | 812 } |
814 return retval; | 813 return retval; |
815 } | 814 } |
816 | 815 |
817 void | 816 void |
818 EdcaTxopN::SetMsduAggregator (Ptr<MsduAggregator> aggr) | 817 EdcaTxopN::SetMsduAggregator (Ptr<MsduAggregator> aggr) |
819 { | 818 { |
820 m_aggregator = aggr; | 819 m_aggregator = aggr; |
821 } | 820 } |
822 | 821 |
823 void | 822 void |
824 EdcaTxopN::PushFront (Ptr<const Packet> packet, WifiMacHeader const &hdr) | 823 EdcaTxopN::PushFront (Ptr<const Packet> packet, const WifiMacHeader &hdr) |
825 { | 824 { |
826 NS_LOG_FUNCTION (this << packet << &hdr); | 825 NS_LOG_FUNCTION (this << packet << &hdr); |
827 WifiMacTrailer fcs; | 826 WifiMacTrailer fcs; |
828 uint32_t fullPacketSize = hdr.GetSerializedSize () + packet->GetSize () + fcs.
GetSerializedSize (); | 827 uint32_t fullPacketSize = hdr.GetSerializedSize () + packet->GetSize () + fcs.
GetSerializedSize (); |
829 WifiRemoteStation *station = GetStation (hdr.GetAddr1 ()); | 828 WifiRemoteStation *station = GetStation (hdr.GetAddr1 ()); |
830 station->PrepareForQueue (packet, fullPacketSize); | 829 station->PrepareForQueue (packet, fullPacketSize); |
831 m_queue->PushFront (packet, hdr); | 830 m_queue->PushFront (packet, hdr); |
832 StartAccessIfNeeded (); | 831 StartAccessIfNeeded (); |
833 } | 832 } |
834 | 833 |
835 void | 834 void |
836 EdcaTxopN::GotAddBaResponse (MgtAddBaResponseHeader const *respHdr, Mac48Address
recipient) | 835 EdcaTxopN::GotAddBaResponse (const MgtAddBaResponseHeader *respHdr, Mac48Address
recipient) |
837 { | 836 { |
838 NS_LOG_FUNCTION (this); | 837 NS_LOG_FUNCTION (this); |
839 MY_DEBUG ("received ADDBA response from "<<recipient); | 838 MY_DEBUG ("received ADDBA response from "<<recipient); |
840 uint8_t tid = respHdr->GetTid (); | 839 uint8_t tid = respHdr->GetTid (); |
841 if (m_baManager->ExistsAgreementInState (recipient, tid, BlockAckAgreement::PE
NDING)) | 840 if (m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgr
eement::PENDING)) |
842 { | 841 { |
843 if (respHdr->GetStatusCode ().IsSuccess ()) | 842 if (respHdr->GetStatusCode ().IsSuccess ()) |
844 { | 843 { |
845 MY_DEBUG ("block ack agreement established with "<<recipient); | 844 MY_DEBUG ("block ack agreement established with "<<recipient); |
846 m_baManager->UpdateAgreement (respHdr, recipient); | 845 m_baManager->UpdateAgreement (respHdr, recipient); |
847 } | 846 } |
848 else | 847 else |
849 { | 848 { |
850 MY_DEBUG ("discard ADDBA response"<<recipient); | 849 MY_DEBUG ("discard ADDBA response"<<recipient); |
851 m_baManager->NotifyAgreementUnsuccessful (recipient, tid); | 850 m_baManager->NotifyAgreementUnsuccessful (recipient, tid); |
852 } | 851 } |
853 } | 852 } |
854 RestartAccessIfNeeded (); | 853 RestartAccessIfNeeded (); |
855 } | 854 } |
856 | 855 |
857 void | 856 void |
858 EdcaTxopN::GotDelBaFrame (const MgtDelBaHeader *delBaHdr, Mac48Address recipient
) | 857 EdcaTxopN::GotDelBaFrame (const MgtDelBaHeader *delBaHdr, Mac48Address recipient
) |
859 { | 858 { |
860 NS_LOG_FUNCTION (this); | 859 NS_LOG_FUNCTION (this); |
861 MY_DEBUG ("received DELBA frame from="<<recipient); | 860 MY_DEBUG ("received DELBA frame from="<<recipient); |
862 m_baManager->TearDownBlockAck (recipient, delBaHdr->GetTid ()); | 861 m_baManager->TearDownBlockAck (recipient, delBaHdr->GetTid ()); |
863 } | 862 } |
864 | 863 |
865 void | 864 void |
866 EdcaTxopN::GotBlockAck (CtrlBAckResponseHeader const *blockAck, Mac48Address rec
ipient) | 865 EdcaTxopN::GotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address rec
ipient) |
867 { | 866 { |
868 MY_DEBUG ("got block ack from="<<recipient); | 867 MY_DEBUG ("got block ack from="<<recipient); |
869 m_baManager->NotifyGotBlockAck (blockAck, recipient); | 868 m_baManager->NotifyGotBlockAck (blockAck, recipient); |
870 m_currentPacket = 0; | 869 m_currentPacket = 0; |
871 m_dcf->ResetCw (); | 870 m_dcf->ResetCw (); |
872 m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ())); | 871 m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ())); |
873 RestartAccessIfNeeded (); | 872 RestartAccessIfNeeded (); |
874 } | 873 } |
875 | 874 |
876 void | 875 void |
877 EdcaTxopN::VerifyBlockAck (void) | 876 EdcaTxopN::VerifyBlockAck (void) |
878 { | 877 { |
879 NS_LOG_FUNCTION (this); | 878 NS_LOG_FUNCTION (this); |
880 uint8_t tid = m_currentHdr.GetQosTid (); | 879 uint8_t tid = m_currentHdr.GetQosTid (); |
881 Mac48Address recipient = m_currentHdr.GetAddr1 (); | 880 Mac48Address recipient = m_currentHdr.GetAddr1 (); |
882 uint16_t sequence = m_currentHdr.GetSequenceNumber (); | 881 uint16_t sequence = m_currentHdr.GetSequenceNumber (); |
883 if (m_baManager->ExistsAgreementInState (recipient, tid, BlockAckAgreement::IN
ACTIVE)) | 882 if (m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgr
eement::INACTIVE)) |
884 { | 883 { |
885 m_baManager->SwitchToBlockAckIfNeeded (recipient, tid, sequence); | 884 m_baManager->SwitchToBlockAckIfNeeded (recipient, tid, sequence); |
886 } | 885 } |
887 if (m_baManager->ExistsAgreementInState (recipient, tid, BlockAckAgreement::ES
TABLISHED)) | 886 if (m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgr
eement::ESTABLISHED)) |
888 { | 887 { |
889 m_currentHdr.SetQosAckPolicy (WifiMacHeader::BLOCK_ACK); | 888 m_currentHdr.SetQosAckPolicy (WifiMacHeader::BLOCK_ACK); |
890 } | 889 } |
891 } | 890 } |
892 | 891 |
893 void | 892 void |
894 EdcaTxopN::CompleteTx (void) | 893 EdcaTxopN::CompleteTx (void) |
895 { | 894 { |
896 if (m_currentHdr.IsQosData () && m_currentHdr.IsQosBlockAck ()) | 895 if (m_currentHdr.IsQosData () && m_currentHdr.IsQosBlockAck ()) |
897 { | 896 { |
898 if (!m_currentHdr.IsRetry ()) | 897 if (!m_currentHdr.IsRetry ()) |
899 { | 898 { |
900 m_baManager->StorePacket (m_currentPacket, m_currentHdr, m_currentPack
etTimestamp); | 899 m_baManager->StorePacket (m_currentPacket, m_currentHdr, m_currentPack
etTimestamp); |
901 } | 900 } |
902 Ptr<Packet> bar = m_baManager->NotifyMpduTransmission (m_currentHdr.GetAdd
r1 (), m_currentHdr.GetQosTid ()); | 901 m_baManager->NotifyMpduTransmission (m_currentHdr.GetAddr1 (), m_currentHd
r.GetQosTid ()); |
903 if (bar != 0) | |
904 { | |
905 QueueBlockAckRequest (bar, m_currentHdr.GetAddr1 ()); | |
906 } | |
907 //we are not waiting for an ack: transmission is completed | 902 //we are not waiting for an ack: transmission is completed |
908 m_currentPacket = 0; | 903 m_currentPacket = 0; |
909 m_dcf->ResetCw (); | 904 m_dcf->ResetCw (); |
910 m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ())); | 905 m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ())); |
911 StartAccessIfNeeded (); | 906 StartAccessIfNeeded (); |
912 } | 907 } |
913 } | 908 } |
914 | 909 |
915 bool | 910 bool |
916 EdcaTxopN::SetupBlockAckIfNeeded () | 911 EdcaTxopN::SetupBlockAckIfNeeded () |
917 { | 912 { |
918 uint8_t tid = m_currentHdr.GetQosTid (); | 913 uint8_t tid = m_currentHdr.GetQosTid (); |
919 Mac48Address recipient = m_currentHdr.GetAddr1 (); | 914 Mac48Address recipient = m_currentHdr.GetAddr1 (); |
920 | 915 |
921 uint32_t packets = m_queue->GetNPacketsByTidAndAddress (tid, WifiMacHeader::AD
DR1, recipient); | 916 uint32_t packets = m_queue->GetNPacketsByTidAndAddress (tid, WifiMacHeader::AD
DR1, recipient); |
922 | 917 |
923 if (packets >= m_blockAckThreshold) | 918 if (packets >= m_blockAckThreshold) |
924 { | 919 { |
925 /* Block ack setup */ | 920 /* Block ack setup */ |
926 uint16_t startingSequence = m_txMiddle->GetNextSeqNumberByTidAndAddress (t
id, recipient); | 921 uint16_t startingSequence = m_txMiddle->GetNextSeqNumberByTidAndAddress (t
id, recipient); |
927 SendAddBaRequest (recipient, tid, startingSequence, m_blockAckInactivityTi
meout, true); | 922 SendAddBaRequest (recipient, tid, startingSequence, m_blockAckInactivityTi
meout, true); |
928 return true; | 923 return true; |
929 } | 924 } |
930 return false; | 925 return false; |
931 } | 926 } |
932 | 927 |
933 void | 928 void |
934 EdcaTxopN::SendBlockAckRequest (void) | 929 EdcaTxopN::SendBlockAckRequest (const struct Bar &bar) |
935 { | 930 { |
936 NS_LOG_FUNCTION (this); | 931 NS_LOG_FUNCTION (this); |
937 //For now assume immediate block ack. In the future, with delayed block ack | |
938 //support a control is needed. | |
939 bool immediate = true; | |
940 ·· | |
941 MacLowTransmissionParameters params; | |
942 params.DisableRts (); | |
943 params.DisableNextData (); | |
944 params.DisableOverrideDurationId (); | |
945 if (immediate) | |
946 { | |
947 if (m_blockAckType == BASIC_BLOCK_ACK) | |
948 { | |
949 params.EnableBasicBlockAck (); | |
950 } | |
951 else if (m_blockAckType == COMPRESSED_BLOCK_ACK) | |
952 { | |
953 params.EnableCompressedBlockAck (); | |
954 } | |
955 else if (m_blockAckType == MULTI_TID_BLOCK_ACK) | |
956 { | |
957 NS_FATAL_ERROR ("Multi-tid block ack is not supported"); | |
958 } | |
959 } | |
960 else | |
961 { | |
962 params.EnableAck (); | |
963 } | |
964 m_low->StartTransmission (m_currentPacket, &m_currentHdr, params, m_transmissi
onListener); | |
965 } | |
966 | |
967 void | |
968 EdcaTxopN::CompleteConfig (void) | |
969 { | |
970 NS_LOG_FUNCTION (this); | |
971 m_baManager->SetTxMiddle (m_txMiddle); | |
972 m_baManager->SetBlockPacketCallback (MakeCallback (&WifiMacQueue::BlockQosPack
et, PeekPointer (m_queue))); | |
973 m_baManager->SetUnblockPacketCallback (MakeCallback (&WifiMacQueue::UnblockQos
Packet, PeekPointer (m_queue))); | |
974 m_baManager->SetMaxPacketDelay (m_queue->GetMaxDelay ()); | |
975 m_low->RegisterBlockAckListenerForAc (m_ac, m_blockAckListener); | |
976 m_baManager->SetBlockAckInactivityCallback (MakeCallback (&EdcaTxopN::SendDelb
aFrame, this)); | |
977 } | |
978 | |
979 void | |
980 EdcaTxopN::SetBlockAckThreshold (uint8_t threshold) | |
981 { | |
982 m_blockAckThreshold = threshold; | |
983 m_baManager->SetBlockAckThreshold (threshold); | |
984 } | |
985 | |
986 uint8_t | |
987 EdcaTxopN::GetBlockAckThreshold (void) const | |
988 { | |
989 return m_blockAckThreshold; | |
990 } | |
991 | |
992 void | |
993 EdcaTxopN::QueueBlockAckRequest (Ptr<const Packet> bar, Mac48Address recipient) | |
994 { | |
995 WifiMacHeader hdr; | 932 WifiMacHeader hdr; |
996 hdr.SetType (WIFI_MAC_CTL_BACKREQ); | 933 hdr.SetType (WIFI_MAC_CTL_BACKREQ); |
997 hdr.SetAddr1 (recipient); | 934 hdr.SetAddr1 (bar.recipient); |
998 hdr.SetAddr2 (m_low->GetAddress ()); | 935 hdr.SetAddr2 (m_low->GetAddress ()); |
999 hdr.SetAddr3 (m_low->GetBssid ()); | 936 hdr.SetAddr3 (m_low->GetBssid ()); |
1000 hdr.SetDsNotTo (); | 937 hdr.SetDsNotTo (); |
1001 hdr.SetDsNotFrom (); | 938 hdr.SetDsNotFrom (); |
1002 hdr.SetNoRetry (); | 939 hdr.SetNoRetry (); |
1003 hdr.SetNoMoreFragments (); | 940 hdr.SetNoMoreFragments (); |
1004 ·· | 941 |
1005 PushFront (bar, hdr); | 942 m_currentPacket = bar.bar; |
| 943 m_currentHdr = hdr; |
| 944 |
| 945 MacLowTransmissionParameters params; |
| 946 params.DisableRts (); |
| 947 params.DisableNextData (); |
| 948 params.DisableOverrideDurationId (); |
| 949 if (bar.immediate) |
| 950 { |
| 951 if (m_blockAckType == BASIC_BLOCK_ACK) |
| 952 { |
| 953 params.EnableBasicBlockAck (); |
| 954 } |
| 955 else if (m_blockAckType == COMPRESSED_BLOCK_ACK) |
| 956 { |
| 957 params.EnableCompressedBlockAck (); |
| 958 } |
| 959 else if (m_blockAckType == MULTI_TID_BLOCK_ACK) |
| 960 { |
| 961 NS_FATAL_ERROR ("Multi-tid block ack is not supported"); |
| 962 } |
| 963 } |
| 964 else |
| 965 { |
| 966 //Delayed block ack |
| 967 params.EnableAck (); |
| 968 } |
| 969 m_low->StartTransmission (m_currentPacket, &m_currentHdr, params, m_transmissi
onListener); |
| 970 } |
| 971 |
| 972 void |
| 973 EdcaTxopN::CompleteConfig (void) |
| 974 { |
| 975 NS_LOG_FUNCTION (this); |
| 976 m_baManager->SetTxMiddle (m_txMiddle); |
| 977 m_low->RegisterBlockAckListenerForAc (m_ac, m_blockAckListener); |
| 978 m_baManager->SetBlockAckInactivityCallback (MakeCallback (&EdcaTxopN::SendDelb
aFrame, this)); |
| 979 } |
| 980 |
| 981 void |
| 982 EdcaTxopN::SetBlockAckThreshold (uint8_t threshold) |
| 983 { |
| 984 m_blockAckThreshold = threshold; |
| 985 m_baManager->SetBlockAckThreshold (threshold); |
| 986 } |
| 987 |
| 988 uint8_t |
| 989 EdcaTxopN::GetBlockAckThreshold (void) const |
| 990 { |
| 991 return m_blockAckThreshold; |
1006 } | 992 } |
1007 | 993 |
1008 void | 994 void |
1009 EdcaTxopN::SendAddBaRequest (Mac48Address dest, uint8_t tid, uint16_t startSeq,· | 995 EdcaTxopN::SendAddBaRequest (Mac48Address dest, uint8_t tid, uint16_t startSeq,· |
1010 uint16_t timeout, bool immediateBAck) | 996 uint16_t timeout, bool immediateBAck) |
1011 { | 997 { |
1012 NS_LOG_FUNCTION (this); | 998 NS_LOG_FUNCTION (this); |
1013 MY_DEBUG ("sent ADDBA request to "<<dest); | 999 MY_DEBUG ("sent ADDBA request to "<<dest); |
1014 WifiMacHeader hdr; | 1000 WifiMacHeader hdr; |
1015 hdr.SetAction (); | 1001 hdr.SetAction (); |
1016 hdr.SetAddr1 (dest); | 1002 hdr.SetAddr1 (dest); |
1017 hdr.SetAddr2 (m_low->GetAddress ()); | 1003 hdr.SetAddr2 (m_low->GetAddress ()); |
1018 hdr.SetAddr3 (m_low->GetBssid ()); | 1004 hdr.SetAddr3 (m_low->GetAddress ()); |
1019 hdr.SetDsNotTo (); | 1005 hdr.SetDsNotTo (); |
1020 hdr.SetDsNotFrom (); | 1006 hdr.SetDsNotFrom (); |
| 1007 ·· |
| 1008 WifiActionHeader actionHdr; |
| 1009 WifiActionHeader::ActionValue action; |
| 1010 action.blockAck = WifiActionHeader::BLOCK_ACK_ADDBA_REQUEST; |
| 1011 actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action); |
| 1012 |
1021 Ptr<Packet> packet = Create<Packet> (); | 1013 Ptr<Packet> packet = Create<Packet> (); |
1022 /*Setting ADDBARequest header*/ | 1014 /*Setting ADDBARequest header*/ |
1023 MgtAddBaRequestHeader reqHdr; | 1015 MgtAddBaRequestHeader reqHdr; |
1024 reqHdr.SetAmsduSupport (true); | 1016 reqHdr.SetAmsduSupport (true); |
1025 if (immediateBAck) | 1017 if (immediateBAck) |
1026 { | 1018 { |
1027 reqHdr.SetImmediateBlockAck (); | 1019 reqHdr.SetImmediateBlockAck (); |
1028 } | 1020 } |
1029 else | 1021 else |
1030 { | 1022 { |
1031 reqHdr.SetDelayedBlockAck (); | 1023 reqHdr.SetDelayedBlockAck (); |
1032 } | 1024 } |
1033 reqHdr.SetTid (tid); | 1025 reqHdr.SetTid (tid); |
1034 /* For now we don't use buffer size field in the ADDBA request frame. The reci
pient | 1026 /* For now we don't use buffer size field in the ADDBA request frame. The reci
pient |
1035 * will choose how many packets it can receive under block ack. | 1027 * will choose how many packets it can receive under block ack. |
1036 */ | 1028 */ |
1037 reqHdr.SetBufferSize (0); | 1029 reqHdr.SetBufferSize (0); |
1038 reqHdr.SetTimeout (timeout); | 1030 reqHdr.SetTimeout (timeout); |
1039 reqHdr.SetStartingSequence (startSeq); | 1031 reqHdr.SetStartingSequence (startSeq); |
1040 | 1032 |
1041 m_baManager->CreateAgreement (&reqHdr, dest); | 1033 m_baManager->CreateAgreement (&reqHdr, dest); |
1042 ·· | 1034 ·· |
1043 packet->AddHeader (reqHdr); | 1035 packet->AddHeader (reqHdr); |
| 1036 packet->AddHeader (actionHdr); |
1044 ·· | 1037 ·· |
1045 m_currentPacket = packet; | 1038 m_currentPacket = packet; |
1046 m_currentHdr = hdr; | 1039 m_currentHdr = hdr; |
1047 | 1040 |
1048 uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&m_currentHdr); | 1041 uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&m_currentHdr); |
1049 m_currentHdr.SetSequenceNumber (sequence); | 1042 m_currentHdr.SetSequenceNumber (sequence); |
1050 m_currentHdr.SetFragmentNumber (0); | 1043 m_currentHdr.SetFragmentNumber (0); |
1051 m_currentHdr.SetNoMoreFragments (); | 1044 m_currentHdr.SetNoMoreFragments (); |
1052 m_currentHdr.SetNoRetry (); | 1045 m_currentHdr.SetNoRetry (); |
1053 ·· | 1046 ·· |
1054 MacLowTransmissionParameters params; | 1047 MacLowTransmissionParameters params; |
1055 params.EnableAck (); | 1048 params.EnableAck (); |
1056 params.DisableRts (); | 1049 params.DisableRts (); |
1057 params.DisableNextData (); | 1050 params.DisableNextData (); |
1058 params.DisableOverrideDurationId (); | 1051 params.DisableOverrideDurationId (); |
1059 ·· | 1052 ·· |
1060 m_low->StartTransmission (m_currentPacket, &m_currentHdr, params,· | 1053 m_low->StartTransmission (m_currentPacket, &m_currentHdr, params,· |
1061 m_transmissionListener); | 1054 m_transmissionListener); |
1062 } | 1055 } |
1063 | 1056 |
1064 void | 1057 void |
1065 EdcaTxopN::SendDelbaFrame (Mac48Address addr, uint8_t tid, bool byOriginator) | 1058 EdcaTxopN::SendDelbaFrame (Mac48Address addr, uint8_t tid, bool byOriginator) |
1066 { | 1059 { |
1067 WifiMacHeader hdr; | 1060 WifiMacHeader hdr; |
1068 hdr.SetAction (); | 1061 hdr.SetAction (); |
1069 hdr.SetAddr1 (addr); | 1062 hdr.SetAddr1 (addr); |
1070 hdr.SetAddr2 (m_low->GetAddress ()); | 1063 hdr.SetAddr2 (m_low->GetAddress ()); |
1071 hdr.SetAddr3 (m_low->GetBssid ()); | 1064 hdr.SetAddr3 (m_low->GetAddress ()); |
1072 hdr.SetDsNotTo (); | 1065 hdr.SetDsNotTo (); |
1073 hdr.SetDsNotFrom (); | 1066 hdr.SetDsNotFrom (); |
1074 | 1067 |
1075 MgtDelBaHeader delbaHdr; | 1068 MgtDelBaHeader delbaHdr; |
1076 delbaHdr.SetTid (tid); | 1069 delbaHdr.SetTid (tid); |
1077 if (byOriginator) | 1070 if (byOriginator) |
1078 { | 1071 { |
1079 delbaHdr.SetByOriginator (); | 1072 delbaHdr.SetByOriginator (); |
1080 } | 1073 } |
1081 else | 1074 else |
1082 { | 1075 { |
1083 delbaHdr.SetByRecipient (); | 1076 delbaHdr.SetByRecipient (); |
1084 } | 1077 } |
| 1078 |
| 1079 WifiActionHeader actionHdr; |
| 1080 WifiActionHeader::ActionValue action; |
| 1081 action.blockAck = WifiActionHeader::BLOCK_ACK_DELBA; |
| 1082 actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action); |
| 1083 ·· |
1085 Ptr<Packet> packet = Create<Packet> (); | 1084 Ptr<Packet> packet = Create<Packet> (); |
1086 packet->AddHeader (delbaHdr); | 1085 packet->AddHeader (delbaHdr); |
| 1086 packet->AddHeader (actionHdr); |
1087 | 1087 |
1088 PushFront (packet, hdr); | 1088 PushFront (packet, hdr); |
1089 } | 1089 } |
1090 | 1090 |
1091 } //namespace ns3 | 1091 } //namespace ns3 |
LEFT | RIGHT |