|
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 |