A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
edca-txop-n.cc
Go to the documentation of this file.
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
#include "ns3/pointer.h"
25
26
#include "
edca-txop-n.h
"
27
#include "
mac-low.h
"
28
#include "
dcf-manager.h
"
29
#include "
mac-tx-middle.h
"
30
#include "
wifi-mac-trailer.h
"
31
#include "
wifi-mac.h
"
32
#include "
random-stream.h
"
33
#include "
wifi-mac-queue.h
"
34
#include "
msdu-aggregator.h
"
35
#include "
mgt-headers.h
"
36
#include "
qos-blocked-destinations.h
"
37
38
NS_LOG_COMPONENT_DEFINE
(
"EdcaTxopN"
);
39
40
#undef NS_LOG_APPEND_CONTEXT
41
#define NS_LOG_APPEND_CONTEXT if (m_low != 0) { std::clog << "[mac=" << m_low->GetAddress () << "] "; }
42
43
namespace
ns3 {
44
45
class
EdcaTxopN::Dcf
:
public
DcfState
46
{
47
public
:
48
Dcf
(
EdcaTxopN
* txop)
49
:
m_txop
(txop)
50
{
51
}
52
private
:
53
virtual
void
DoNotifyAccessGranted
(
void
)
54
{
55
m_txop
->
NotifyAccessGranted
();
56
}
57
virtual
void
DoNotifyInternalCollision
(
void
)
58
{
59
m_txop
->
NotifyInternalCollision
();
60
}
61
virtual
void
DoNotifyCollision
(
void
)
62
{
63
m_txop
->
NotifyCollision
();
64
}
65
virtual
void
DoNotifyChannelSwitching
(
void
)
66
{
67
m_txop
->
NotifyChannelSwitching
();
68
}
69
EdcaTxopN
*
m_txop
;
70
};
71
72
class
EdcaTxopN::TransmissionListener
:
public
MacLowTransmissionListener
73
{
74
public
:
75
TransmissionListener
(
EdcaTxopN
* txop)
76
:
MacLowTransmissionListener
(),
77
m_txop
(txop) {
78
}
79
80
virtual
~TransmissionListener
() {}
81
82
virtual
void
GotCts
(
double
snr,
WifiMode
txMode)
83
{
84
m_txop
->
GotCts
(snr, txMode);
85
}
86
virtual
void
MissedCts
(
void
)
87
{
88
m_txop
->
MissedCts
();
89
}
90
virtual
void
GotAck
(
double
snr,
WifiMode
txMode)
91
{
92
m_txop
->
GotAck
(snr, txMode);
93
}
94
virtual
void
MissedAck
(
void
)
95
{
96
m_txop
->
MissedAck
();
97
}
98
virtual
void
GotBlockAck
(
const
CtrlBAckResponseHeader
*blockAck,
Mac48Address
source)
99
{
100
m_txop
->
GotBlockAck
(blockAck, source);
101
}
102
virtual
void
MissedBlockAck
(
void
)
103
{
104
m_txop
->
MissedBlockAck
();
105
}
106
virtual
void
StartNext
(
void
)
107
{
108
m_txop
->
StartNext
();
109
}
110
virtual
void
Cancel
(
void
)
111
{
112
m_txop
->
Cancel
();
113
}
114
virtual
void
EndTxNoAck
(
void
)
115
{
116
m_txop
->
EndTxNoAck
();
117
}
118
119
private
:
120
EdcaTxopN
*
m_txop
;
121
};
122
123
class
EdcaTxopN::BlockAckEventListener
:
public
MacLowBlockAckEventListener
124
{
125
public
:
126
BlockAckEventListener
(
EdcaTxopN
* txop)
127
:
MacLowBlockAckEventListener
(),
128
m_txop
(txop) {
129
}
130
virtual
~BlockAckEventListener
() {}
131
132
virtual
void
BlockAckInactivityTimeout
(
Mac48Address
address, uint8_t tid)
133
{
134
m_txop
->
SendDelbaFrame
(address, tid,
false
);
135
}
136
137
private
:
138
EdcaTxopN
*
m_txop
;
139
};
140
141
NS_OBJECT_ENSURE_REGISTERED
(
EdcaTxopN
);
142
143
TypeId
144
EdcaTxopN::GetTypeId
(
void
)
145
{
146
static
TypeId
tid =
TypeId
(
"ns3::EdcaTxopN"
)
147
.
SetParent
(
ns3::Dcf::GetTypeId
())
148
.
AddConstructor
<
EdcaTxopN
> ()
149
.AddAttribute (
"BlockAckThreshold"
,
"If number of packets in this queue reaches this value,\
150
block ack mechanism is used. If this value is 0, block ack is never used."
,
151
UintegerValue
(0),
152
MakeUintegerAccessor (&
EdcaTxopN::SetBlockAckThreshold
,
153
&
EdcaTxopN::GetBlockAckThreshold
),
154
MakeUintegerChecker<uint8_t> (0, 64))
155
.AddAttribute (
"BlockAckInactivityTimeout"
,
"Represents max time (blocks of 1024 micro seconds) allowed for block ack\
156
inactivity. If this value isn't equal to 0 a timer start after that a\
157
block ack setup is completed and will be reset every time that a block\
158
ack frame is received. If this value is 0, block ack inactivity timeout won't be used."
,
159
UintegerValue
(0),
160
MakeUintegerAccessor (&
EdcaTxopN::SetBlockAckInactivityTimeout
),
161
MakeUintegerChecker<uint16_t> ())
162
.AddAttribute (
"Queue"
,
"The WifiMacQueue object"
,
163
PointerValue
(),
164
MakePointerAccessor (&
EdcaTxopN::GetQueue
),
165
MakePointerChecker<WifiMacQueue> ())
166
;
167
return
tid;
168
}
169
170
EdcaTxopN::EdcaTxopN
()
171
: m_manager (0),
172
m_currentPacket (0),
173
m_aggregator (0),
174
m_blockAckType (
COMPRESSED_BLOCK_ACK
)
175
{
176
NS_LOG_FUNCTION
(
this
);
177
m_transmissionListener
=
new
EdcaTxopN::TransmissionListener
(
this
);
178
m_blockAckListener
=
new
EdcaTxopN::BlockAckEventListener
(
this
);
179
m_dcf
=
new
EdcaTxopN::Dcf
(
this
);
180
m_queue
= CreateObject<WifiMacQueue> ();
181
m_rng
=
new
RealRandomStream
();
182
m_qosBlockedDestinations
=
new
QosBlockedDestinations
();
183
m_baManager
=
new
BlockAckManager
();
184
m_baManager
->
SetQueue
(
m_queue
);
185
m_baManager
->
SetBlockAckType
(
m_blockAckType
);
186
m_baManager
->
SetBlockDestinationCallback
(
MakeCallback
(&
QosBlockedDestinations::Block
,
m_qosBlockedDestinations
));
187
m_baManager
->
SetUnblockDestinationCallback
(
MakeCallback
(&
QosBlockedDestinations::Unblock
,
m_qosBlockedDestinations
));
188
m_baManager
->
SetMaxPacketDelay
(
m_queue
->
GetMaxDelay
());
189
}
190
191
EdcaTxopN::~EdcaTxopN
()
192
{
193
NS_LOG_FUNCTION
(
this
);
194
}
195
196
void
197
EdcaTxopN::DoDispose
(
void
)
198
{
199
NS_LOG_FUNCTION
(
this
);
200
m_queue
= 0;
201
m_low
= 0;
202
m_stationManager
= 0;
203
delete
m_transmissionListener
;
204
delete
m_dcf
;
205
delete
m_rng
;
206
delete
m_qosBlockedDestinations
;
207
delete
m_baManager
;
208
delete
m_blockAckListener
;
209
m_transmissionListener
= 0;
210
m_dcf
= 0;
211
m_rng
= 0;
212
m_qosBlockedDestinations
= 0;
213
m_baManager
= 0;
214
m_blockAckListener
= 0;
215
m_txMiddle
= 0;
216
m_aggregator
= 0;
217
}
218
219
void
220
EdcaTxopN::SetManager
(
DcfManager
*manager)
221
{
222
NS_LOG_FUNCTION
(
this
<< manager);
223
m_manager
= manager;
224
m_manager
->
Add
(
m_dcf
);
225
}
226
227
void
228
EdcaTxopN::SetTxOkCallback
(
TxOk
callback)
229
{
230
m_txOkCallback
= callback;
231
}
232
233
void
234
EdcaTxopN::SetTxFailedCallback
(
TxFailed
callback)
235
{
236
m_txFailedCallback
= callback;
237
}
238
239
void
240
EdcaTxopN::SetWifiRemoteStationManager
(
Ptr<WifiRemoteStationManager>
remoteManager)
241
{
242
NS_LOG_FUNCTION
(
this
<< remoteManager);
243
m_stationManager
= remoteManager;
244
}
245
void
246
EdcaTxopN::SetTypeOfStation
(
enum
TypeOfStation
type)
247
{
248
NS_LOG_FUNCTION
(
this
<< type);
249
m_typeOfStation
= type;
250
}
251
252
enum
TypeOfStation
253
EdcaTxopN::GetTypeOfStation
(
void
)
const
254
{
255
return
m_typeOfStation
;
256
}
257
258
Ptr<WifiMacQueue >
259
EdcaTxopN::GetQueue
()
const
260
{
261
NS_LOG_FUNCTION
(
this
);
262
return
m_queue
;
263
}
264
265
void
266
EdcaTxopN::SetMinCw
(uint32_t minCw)
267
{
268
NS_LOG_FUNCTION
(
this
<< minCw);
269
m_dcf
->
SetCwMin
(minCw);
270
}
271
272
void
273
EdcaTxopN::SetMaxCw
(uint32_t maxCw)
274
{
275
NS_LOG_FUNCTION
(
this
<< maxCw);
276
m_dcf
->
SetCwMax
(maxCw);
277
}
278
279
void
280
EdcaTxopN::SetAifsn
(uint32_t aifsn)
281
{
282
NS_LOG_FUNCTION
(
this
<< aifsn);
283
m_dcf
->
SetAifsn
(aifsn);
284
}
285
286
uint32_t
287
EdcaTxopN::GetMinCw
(
void
)
const
288
{
289
return
m_dcf
->
GetCwMin
();
290
}
291
292
uint32_t
293
EdcaTxopN::GetMaxCw
(
void
)
const
294
{
295
return
m_dcf
->
GetCwMax
();
296
}
297
298
uint32_t
299
EdcaTxopN::GetAifsn
(
void
)
const
300
{
301
return
m_dcf
->
GetAifsn
();
302
}
303
304
void
305
EdcaTxopN::SetTxMiddle
(
MacTxMiddle
*txMiddle)
306
{
307
m_txMiddle
= txMiddle;
308
}
309
310
Ptr<MacLow>
311
EdcaTxopN::Low
(
void
)
312
{
313
return
m_low
;
314
}
315
316
void
317
EdcaTxopN::SetLow
(
Ptr<MacLow>
low)
318
{
319
NS_LOG_FUNCTION
(
this
<< low);
320
m_low
= low;
321
}
322
323
bool
324
EdcaTxopN::NeedsAccess
(
void
)
const
325
{
326
return
!
m_queue
->
IsEmpty
() ||
m_currentPacket
!= 0 ||
m_baManager
->
HasPackets
();
327
}
328
329
void
330
EdcaTxopN::NotifyAccessGranted
(
void
)
331
{
332
NS_LOG_FUNCTION
(
this
);
333
if
(
m_currentPacket
== 0)
334
{
335
if
(
m_queue
->
IsEmpty
() && !
m_baManager
->
HasPackets
())
336
{
337
NS_LOG_DEBUG
(
"queue is empty"
);
338
return
;
339
}
340
if
(
m_baManager
->
HasBar
(
m_currentBar
))
341
{
342
SendBlockAckRequest
(
m_currentBar
);
343
return
;
344
}
345
/* check if packets need retransmission are stored in BlockAckManager */
346
m_currentPacket
=
m_baManager
->
GetNextPacket
(
m_currentHdr
);
347
if
(
m_currentPacket
== 0)
348
{
349
if
(
m_queue
->
PeekFirstAvailable
(&
m_currentHdr
,
m_currentPacketTimestamp
,
m_qosBlockedDestinations
) == 0)
350
{
351
NS_LOG_DEBUG
(
"no available packets in the queue"
);
352
return
;
353
}
354
if
(
m_currentHdr
.
IsQosData
() && !
m_currentHdr
.
GetAddr1
().
IsBroadcast
()
355
&&
m_blockAckThreshold
> 0
356
&& !
m_baManager
->
ExistsAgreement
(
m_currentHdr
.
GetAddr1
(),
m_currentHdr
.
GetQosTid
())
357
&&
SetupBlockAckIfNeeded
())
358
{
359
return
;
360
}
361
m_currentPacket
=
m_queue
->
DequeueFirstAvailable
(&
m_currentHdr
,
m_currentPacketTimestamp
,
m_qosBlockedDestinations
);
362
NS_ASSERT
(
m_currentPacket
!= 0);
363
364
uint16_t sequence =
m_txMiddle
->
GetNextSequenceNumberfor
(&
m_currentHdr
);
365
m_currentHdr
.
SetSequenceNumber
(sequence);
366
m_currentHdr
.
SetFragmentNumber
(0);
367
m_currentHdr
.
SetNoMoreFragments
();
368
m_currentHdr
.
SetNoRetry
();
369
m_fragmentNumber
= 0;
370
NS_LOG_DEBUG
(
"dequeued size="
<<
m_currentPacket
->
GetSize
() <<
371
", to="
<<
m_currentHdr
.
GetAddr1
() <<
372
", seq="
<<
m_currentHdr
.
GetSequenceControl
());
373
if
(
m_currentHdr
.
IsQosData
() && !
m_currentHdr
.
GetAddr1
().
IsBroadcast
())
374
{
375
VerifyBlockAck
();
376
}
377
}
378
}
379
MacLowTransmissionParameters
params;
380
params.
DisableOverrideDurationId
();
381
if
(
m_currentHdr
.
GetAddr1
().
IsGroup
())
382
{
383
params.
DisableRts
();
384
params.
DisableAck
();
385
params.
DisableNextData
();
386
m_low
->
StartTransmission
(
m_currentPacket
,
387
&
m_currentHdr
,
388
params,
389
m_transmissionListener
);
390
391
NS_LOG_DEBUG
(
"tx broadcast"
);
392
}
393
else
if
(
m_currentHdr
.
GetType
() ==
WIFI_MAC_CTL_BACKREQ
)
394
{
395
SendBlockAckRequest
(
m_currentBar
);
396
}
397
else
398
{
399
if
(
m_currentHdr
.
IsQosData
() &&
m_currentHdr
.
IsQosBlockAck
())
400
{
401
params.
DisableAck
();
402
}
403
else
404
{
405
params.
EnableAck
();
406
}
407
if
(
NeedFragmentation
() && ((
m_currentHdr
.
IsQosData
()
408
&& !
m_currentHdr
.
IsQosAmsdu
())
409
||
m_currentHdr
.
IsData
())
410
&& (
m_blockAckThreshold
== 0
411
||
m_blockAckType
==
BASIC_BLOCK_ACK
))
412
{
413
//With COMPRESSED_BLOCK_ACK fragmentation must be avoided.
414
params.
DisableRts
();
415
WifiMacHeader
hdr;
416
Ptr<Packet>
fragment =
GetFragmentPacket
(&hdr);
417
if
(
IsLastFragment
())
418
{
419
NS_LOG_DEBUG
(
"fragmenting last fragment size="
<< fragment->
GetSize
());
420
params.
DisableNextData
();
421
}
422
else
423
{
424
NS_LOG_DEBUG
(
"fragmenting size="
<< fragment->
GetSize
());
425
params.
EnableNextData
(
GetNextFragmentSize
());
426
}
427
m_low
->
StartTransmission
(fragment, &hdr, params,
428
m_transmissionListener
);
429
}
430
else
431
{
432
WifiMacHeader
peekedHdr;
433
if
(
m_currentHdr
.
IsQosData
()
434
&&
m_queue
->
PeekByTidAndAddress
(&peekedHdr,
m_currentHdr
.
GetQosTid
(),
435
WifiMacHeader::ADDR1
,
m_currentHdr
.
GetAddr1
())
436
&& !
m_currentHdr
.
GetAddr1
().
IsBroadcast
()
437
&&
m_aggregator
!= 0 && !
m_currentHdr
.
IsRetry
())
438
{
439
/* here is performed aggregation */
440
Ptr<Packet>
currentAggregatedPacket = Create<Packet> ();
441
m_aggregator
->
Aggregate
(
m_currentPacket
, currentAggregatedPacket,
442
MapSrcAddressForAggregation
(peekedHdr),
443
MapDestAddressForAggregation
(peekedHdr));
444
bool
aggregated =
false
;
445
bool
isAmsdu =
false
;
446
Ptr<const Packet>
peekedPacket =
m_queue
->
PeekByTidAndAddress
(&peekedHdr,
m_currentHdr
.
GetQosTid
(),
447
WifiMacHeader::ADDR1
,
448
m_currentHdr
.
GetAddr1
());
449
while
(peekedPacket != 0)
450
{
451
aggregated =
m_aggregator
->
Aggregate
(peekedPacket, currentAggregatedPacket,
452
MapSrcAddressForAggregation
(peekedHdr),
453
MapDestAddressForAggregation
(peekedHdr));
454
if
(aggregated)
455
{
456
isAmsdu =
true
;
457
m_queue
->
Remove
(peekedPacket);
458
}
459
else
460
{
461
break
;
462
}
463
peekedPacket =
m_queue
->
PeekByTidAndAddress
(&peekedHdr,
m_currentHdr
.
GetQosTid
(),
464
WifiMacHeader::ADDR1
,
m_currentHdr
.
GetAddr1
());
465
}
466
if
(isAmsdu)
467
{
468
m_currentHdr
.
SetQosAmsdu
();
469
m_currentHdr
.
SetAddr3
(
m_low
->
GetBssid
());
470
m_currentPacket
= currentAggregatedPacket;
471
currentAggregatedPacket = 0;
472
NS_LOG_DEBUG
(
"tx unicast A-MSDU"
);
473
}
474
}
475
if
(
NeedRts
())
476
{
477
params.
EnableRts
();
478
NS_LOG_DEBUG
(
"tx unicast rts"
);
479
}
480
else
481
{
482
params.
DisableRts
();
483
NS_LOG_DEBUG
(
"tx unicast"
);
484
}
485
params.
DisableNextData
();
486
m_low
->
StartTransmission
(
m_currentPacket
, &
m_currentHdr
,
487
params,
m_transmissionListener
);
488
CompleteTx
();
489
}
490
}
491
}
492
493
void
EdcaTxopN::NotifyInternalCollision
(
void
)
494
{
495
NS_LOG_FUNCTION
(
this
);
496
NotifyCollision
();
497
}
498
499
void
500
EdcaTxopN::NotifyCollision
(
void
)
501
{
502
NS_LOG_FUNCTION
(
this
);
503
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
504
RestartAccessIfNeeded
();
505
}
506
507
void
508
EdcaTxopN::GotCts
(
double
snr,
WifiMode
txMode)
509
{
510
NS_LOG_FUNCTION
(
this
<< snr << txMode);
511
NS_LOG_DEBUG
(
"got cts"
);
512
}
513
514
void
515
EdcaTxopN::MissedCts
(
void
)
516
{
517
NS_LOG_FUNCTION
(
this
);
518
NS_LOG_DEBUG
(
"missed cts"
);
519
if
(!
NeedRtsRetransmission
())
520
{
521
NS_LOG_DEBUG
(
"Cts Fail"
);
522
m_stationManager
->
ReportFinalRtsFailed
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
);
523
if
(!
m_txFailedCallback
.
IsNull
())
524
{
525
m_txFailedCallback
(
m_currentHdr
);
526
}
527
// to reset the dcf.
528
m_currentPacket
= 0;
529
m_dcf
->
ResetCw
();
530
}
531
else
532
{
533
m_dcf
->
UpdateFailedCw
();
534
}
535
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
536
RestartAccessIfNeeded
();
537
}
538
539
void
540
EdcaTxopN::NotifyChannelSwitching
(
void
)
541
{
542
m_queue
->
Flush
();
543
m_currentPacket
= 0;
544
}
545
546
void
547
EdcaTxopN::Queue
(
Ptr<const Packet>
packet,
const
WifiMacHeader
&hdr)
548
{
549
NS_LOG_FUNCTION
(
this
<< packet << &hdr);
550
WifiMacTrailer
fcs;
551
uint32_t fullPacketSize = hdr.
GetSerializedSize
() + packet->
GetSize
() + fcs.
GetSerializedSize
();
552
m_stationManager
->
PrepareForQueue
(hdr.
GetAddr1
(), &hdr,
553
packet, fullPacketSize);
554
m_queue
->
Enqueue
(packet, hdr);
555
StartAccessIfNeeded
();
556
}
557
558
void
559
EdcaTxopN::GotAck
(
double
snr,
WifiMode
txMode)
560
{
561
NS_LOG_FUNCTION
(
this
<< snr << txMode);
562
if
(!
NeedFragmentation
()
563
||
IsLastFragment
()
564
||
m_currentHdr
.
IsQosAmsdu
())
565
{
566
NS_LOG_DEBUG
(
"got ack. tx done."
);
567
if
(!
m_txOkCallback
.
IsNull
())
568
{
569
m_txOkCallback
(
m_currentHdr
);
570
}
571
572
if
(
m_currentHdr
.
IsAction
())
573
{
574
WifiActionHeader
actionHdr;
575
Ptr<Packet>
p =
m_currentPacket
->
Copy
();
576
p->
RemoveHeader
(actionHdr);
577
if
(actionHdr.
GetCategory
() ==
WifiActionHeader::BLOCK_ACK
578
&& actionHdr.
GetAction
().
blockAck
==
WifiActionHeader::BLOCK_ACK_DELBA
)
579
{
580
MgtDelBaHeader
delBa;
581
p->
PeekHeader
(delBa);
582
if
(delBa.
IsByOriginator
())
583
{
584
m_baManager
->
TearDownBlockAck
(
m_currentHdr
.
GetAddr1
(), delBa.
GetTid
());
585
}
586
else
587
{
588
m_low
->
DestroyBlockAckAgreement
(
m_currentHdr
.
GetAddr1
(), delBa.
GetTid
());
589
}
590
}
591
}
592
m_currentPacket
= 0;
593
594
m_dcf
->
ResetCw
();
595
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
596
RestartAccessIfNeeded
();
597
}
598
else
599
{
600
NS_LOG_DEBUG
(
"got ack. tx not done, size="
<<
m_currentPacket
->
GetSize
());
601
}
602
}
603
604
void
605
EdcaTxopN::MissedAck
(
void
)
606
{
607
NS_LOG_FUNCTION
(
this
);
608
NS_LOG_DEBUG
(
"missed ack"
);
609
if
(!
NeedDataRetransmission
())
610
{
611
NS_LOG_DEBUG
(
"Ack Fail"
);
612
m_stationManager
->
ReportFinalDataFailed
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
);
613
if
(!
m_txFailedCallback
.
IsNull
())
614
{
615
m_txFailedCallback
(
m_currentHdr
);
616
}
617
// to reset the dcf.
618
m_currentPacket
= 0;
619
m_dcf
->
ResetCw
();
620
}
621
else
622
{
623
NS_LOG_DEBUG
(
"Retransmit"
);
624
m_currentHdr
.
SetRetry
();
625
m_dcf
->
UpdateFailedCw
();
626
}
627
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
628
RestartAccessIfNeeded
();
629
}
630
631
void
632
EdcaTxopN::MissedBlockAck
(
void
)
633
{
634
NS_LOG_FUNCTION
(
this
);
635
NS_LOG_DEBUG
(
"missed block ack"
);
636
//should i report this to station addressed by ADDR1?
637
NS_LOG_DEBUG
(
"Retransmit block ack request"
);
638
m_currentHdr
.
SetRetry
();
639
m_dcf
->
UpdateFailedCw
();
640
641
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
642
RestartAccessIfNeeded
();
643
}
644
645
Ptr<MsduAggregator>
646
EdcaTxopN::GetMsduAggregator
(
void
)
const
647
{
648
return
m_aggregator
;
649
}
650
651
void
652
EdcaTxopN::RestartAccessIfNeeded
(
void
)
653
{
654
NS_LOG_FUNCTION
(
this
);
655
if
((
m_currentPacket
!= 0
656
|| !
m_queue
->
IsEmpty
() ||
m_baManager
->
HasPackets
())
657
&& !
m_dcf
->
IsAccessRequested
())
658
{
659
m_manager
->
RequestAccess
(
m_dcf
);
660
}
661
}
662
663
void
664
EdcaTxopN::StartAccessIfNeeded
(
void
)
665
{
666
NS_LOG_FUNCTION
(
this
);
667
if
(
m_currentPacket
== 0
668
&& (!
m_queue
->
IsEmpty
() ||
m_baManager
->
HasPackets
())
669
&& !
m_dcf
->
IsAccessRequested
())
670
{
671
m_manager
->
RequestAccess
(
m_dcf
);
672
}
673
}
674
675
bool
676
EdcaTxopN::NeedRts
(
void
)
677
{
678
return
m_stationManager
->
NeedRts
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
679
m_currentPacket
);
680
}
681
682
bool
683
EdcaTxopN::NeedRtsRetransmission
(
void
)
684
{
685
return
m_stationManager
->
NeedRtsRetransmission
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
686
m_currentPacket
);
687
}
688
689
bool
690
EdcaTxopN::NeedDataRetransmission
(
void
)
691
{
692
return
m_stationManager
->
NeedDataRetransmission
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
693
m_currentPacket
);
694
}
695
696
void
697
EdcaTxopN::NextFragment
(
void
)
698
{
699
m_fragmentNumber
++;
700
}
701
702
void
703
EdcaTxopN::StartNext
(
void
)
704
{
705
NS_LOG_FUNCTION
(
this
);
706
NS_LOG_DEBUG
(
"start next packet fragment"
);
707
/* this callback is used only for fragments. */
708
NextFragment
();
709
WifiMacHeader
hdr;
710
Ptr<Packet>
fragment =
GetFragmentPacket
(&hdr);
711
MacLowTransmissionParameters
params;
712
params.
EnableAck
();
713
params.
DisableRts
();
714
params.
DisableOverrideDurationId
();
715
if
(
IsLastFragment
())
716
{
717
params.
DisableNextData
();
718
}
719
else
720
{
721
params.
EnableNextData
(
GetNextFragmentSize
());
722
}
723
Low
()->
StartTransmission
(fragment, &hdr, params,
m_transmissionListener
);
724
}
725
726
void
727
EdcaTxopN::Cancel
(
void
)
728
{
729
NS_LOG_FUNCTION
(
this
);
730
NS_LOG_DEBUG
(
"transmission cancelled"
);
731
}
732
733
void
734
EdcaTxopN::EndTxNoAck
(
void
)
735
{
736
NS_LOG_FUNCTION
(
this
);
737
NS_LOG_DEBUG
(
"a transmission that did not require an ACK just finished"
);
738
m_currentPacket
= 0;
739
m_dcf
->
ResetCw
();
740
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
741
StartAccessIfNeeded
();
742
}
743
744
bool
745
EdcaTxopN::NeedFragmentation
(
void
)
const
746
{
747
return
m_stationManager
->
NeedFragmentation
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
748
m_currentPacket
);
749
}
750
751
uint32_t
752
EdcaTxopN::GetFragmentSize
(
void
)
753
{
754
return
m_stationManager
->
GetFragmentSize
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
755
m_currentPacket
,
m_fragmentNumber
);
756
}
757
758
uint32_t
759
EdcaTxopN::GetNextFragmentSize
(
void
)
760
{
761
return
m_stationManager
->
GetFragmentSize
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
762
m_currentPacket
,
m_fragmentNumber
+ 1);
763
}
764
765
uint32_t
766
EdcaTxopN::GetFragmentOffset
(
void
)
767
{
768
return
m_stationManager
->
GetFragmentOffset
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
769
m_currentPacket
,
m_fragmentNumber
);
770
}
771
772
773
bool
774
EdcaTxopN::IsLastFragment
(
void
)
const
775
{
776
return
m_stationManager
->
IsLastFragment
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
777
m_currentPacket
,
m_fragmentNumber
);
778
}
779
780
Ptr<Packet>
781
EdcaTxopN::GetFragmentPacket
(
WifiMacHeader
*hdr)
782
{
783
*hdr =
m_currentHdr
;
784
hdr->
SetFragmentNumber
(
m_fragmentNumber
);
785
uint32_t startOffset =
GetFragmentOffset
();
786
Ptr<Packet>
fragment;
787
if
(
IsLastFragment
())
788
{
789
hdr->
SetNoMoreFragments
();
790
}
791
else
792
{
793
hdr->
SetMoreFragments
();
794
}
795
fragment =
m_currentPacket
->
CreateFragment
(startOffset,
796
GetFragmentSize
());
797
return
fragment;
798
}
799
800
void
801
EdcaTxopN::SetAccessCategory
(
enum
AcIndex
ac)
802
{
803
m_ac
= ac;
804
}
805
806
Mac48Address
807
EdcaTxopN::MapSrcAddressForAggregation
(
const
WifiMacHeader
&hdr)
808
{
809
Mac48Address
retval;
810
if
(
m_typeOfStation
==
STA
||
m_typeOfStation
==
ADHOC_STA
)
811
{
812
retval = hdr.
GetAddr2
();
813
}
814
else
815
{
816
retval = hdr.
GetAddr3
();
817
}
818
return
retval;
819
}
820
821
Mac48Address
822
EdcaTxopN::MapDestAddressForAggregation
(
const
WifiMacHeader
&hdr)
823
{
824
Mac48Address
retval;
825
if
(
m_typeOfStation
==
AP
||
m_typeOfStation
==
ADHOC_STA
)
826
{
827
retval = hdr.
GetAddr1
();
828
}
829
else
830
{
831
retval = hdr.
GetAddr3
();
832
}
833
return
retval;
834
}
835
836
void
837
EdcaTxopN::SetMsduAggregator
(
Ptr<MsduAggregator>
aggr)
838
{
839
m_aggregator
= aggr;
840
}
841
842
void
843
EdcaTxopN::PushFront
(
Ptr<const Packet>
packet,
const
WifiMacHeader
&hdr)
844
{
845
NS_LOG_FUNCTION
(
this
<< packet << &hdr);
846
WifiMacTrailer
fcs;
847
uint32_t fullPacketSize = hdr.
GetSerializedSize
() + packet->
GetSize
() + fcs.
GetSerializedSize
();
848
m_stationManager
->
PrepareForQueue
(hdr.
GetAddr1
(), &hdr,
849
packet, fullPacketSize);
850
m_queue
->
PushFront
(packet, hdr);
851
StartAccessIfNeeded
();
852
}
853
854
void
855
EdcaTxopN::GotAddBaResponse
(
const
MgtAddBaResponseHeader
*respHdr,
Mac48Address
recipient)
856
{
857
NS_LOG_FUNCTION
(
this
);
858
NS_LOG_DEBUG
(
"received ADDBA response from "
<< recipient);
859
uint8_t tid = respHdr->
GetTid
();
860
if
(
m_baManager
->
ExistsAgreementInState
(recipient, tid,
OriginatorBlockAckAgreement::PENDING
))
861
{
862
if
(respHdr->
GetStatusCode
().
IsSuccess
())
863
{
864
NS_LOG_DEBUG
(
"block ack agreement established with "
<< recipient);
865
m_baManager
->
UpdateAgreement
(respHdr, recipient);
866
}
867
else
868
{
869
NS_LOG_DEBUG
(
"discard ADDBA response"
<< recipient);
870
m_baManager
->
NotifyAgreementUnsuccessful
(recipient, tid);
871
}
872
}
873
RestartAccessIfNeeded
();
874
}
875
876
void
877
EdcaTxopN::GotDelBaFrame
(
const
MgtDelBaHeader
*delBaHdr,
Mac48Address
recipient)
878
{
879
NS_LOG_FUNCTION
(
this
);
880
NS_LOG_DEBUG
(
"received DELBA frame from="
<< recipient);
881
m_baManager
->
TearDownBlockAck
(recipient, delBaHdr->
GetTid
());
882
}
883
884
void
885
EdcaTxopN::GotBlockAck
(
const
CtrlBAckResponseHeader
*blockAck,
Mac48Address
recipient)
886
{
887
NS_LOG_DEBUG
(
"got block ack from="
<< recipient);
888
m_baManager
->
NotifyGotBlockAck
(blockAck, recipient);
889
m_currentPacket
= 0;
890
m_dcf
->
ResetCw
();
891
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
892
RestartAccessIfNeeded
();
893
}
894
895
void
896
EdcaTxopN::VerifyBlockAck
(
void
)
897
{
898
NS_LOG_FUNCTION
(
this
);
899
uint8_t tid =
m_currentHdr
.
GetQosTid
();
900
Mac48Address
recipient =
m_currentHdr
.
GetAddr1
();
901
uint16_t sequence =
m_currentHdr
.
GetSequenceNumber
();
902
if
(
m_baManager
->
ExistsAgreementInState
(recipient, tid,
OriginatorBlockAckAgreement::INACTIVE
))
903
{
904
m_baManager
->
SwitchToBlockAckIfNeeded
(recipient, tid, sequence);
905
}
906
if
(
m_baManager
->
ExistsAgreementInState
(recipient, tid,
OriginatorBlockAckAgreement::ESTABLISHED
))
907
{
908
m_currentHdr
.
SetQosAckPolicy
(
WifiMacHeader::BLOCK_ACK
);
909
}
910
}
911
912
void
913
EdcaTxopN::CompleteTx
(
void
)
914
{
915
if
(
m_currentHdr
.
IsQosData
() &&
m_currentHdr
.
IsQosBlockAck
())
916
{
917
if
(!
m_currentHdr
.
IsRetry
())
918
{
919
m_baManager
->
StorePacket
(
m_currentPacket
,
m_currentHdr
,
m_currentPacketTimestamp
);
920
}
921
m_baManager
->
NotifyMpduTransmission
(
m_currentHdr
.
GetAddr1
(),
m_currentHdr
.
GetQosTid
(),
922
m_txMiddle
->
GetNextSeqNumberByTidAndAddress
(
m_currentHdr
.
GetQosTid
(),
923
m_currentHdr
.
GetAddr1
()));
924
//we are not waiting for an ack: transmission is completed
925
m_currentPacket
= 0;
926
m_dcf
->
ResetCw
();
927
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
928
StartAccessIfNeeded
();
929
}
930
}
931
932
bool
933
EdcaTxopN::SetupBlockAckIfNeeded
()
934
{
935
uint8_t tid =
m_currentHdr
.
GetQosTid
();
936
Mac48Address
recipient =
m_currentHdr
.
GetAddr1
();
937
938
uint32_t packets =
m_queue
->
GetNPacketsByTidAndAddress
(tid,
WifiMacHeader::ADDR1
, recipient);
939
940
if
(packets >=
m_blockAckThreshold
)
941
{
942
/* Block ack setup */
943
uint16_t startingSequence =
m_txMiddle
->
GetNextSeqNumberByTidAndAddress
(tid, recipient);
944
SendAddBaRequest
(recipient, tid, startingSequence,
m_blockAckInactivityTimeout
,
true
);
945
return
true
;
946
}
947
return
false
;
948
}
949
950
void
951
EdcaTxopN::SendBlockAckRequest
(
const
struct
Bar
&bar)
952
{
953
NS_LOG_FUNCTION
(
this
);
954
WifiMacHeader
hdr;
955
hdr.
SetType
(
WIFI_MAC_CTL_BACKREQ
);
956
hdr.
SetAddr1
(bar.
recipient
);
957
hdr.
SetAddr2
(
m_low
->
GetAddress
());
958
hdr.
SetAddr3
(
m_low
->
GetBssid
());
959
hdr.
SetDsNotTo
();
960
hdr.
SetDsNotFrom
();
961
hdr.
SetNoRetry
();
962
hdr.
SetNoMoreFragments
();
963
964
m_currentPacket
= bar.
bar
;
965
m_currentHdr
= hdr;
966
967
MacLowTransmissionParameters
params;
968
params.
DisableRts
();
969
params.
DisableNextData
();
970
params.
DisableOverrideDurationId
();
971
if
(bar.
immediate
)
972
{
973
if
(
m_blockAckType
==
BASIC_BLOCK_ACK
)
974
{
975
params.
EnableBasicBlockAck
();
976
}
977
else
if
(
m_blockAckType
==
COMPRESSED_BLOCK_ACK
)
978
{
979
params.
EnableCompressedBlockAck
();
980
}
981
else
if
(
m_blockAckType
==
MULTI_TID_BLOCK_ACK
)
982
{
983
NS_FATAL_ERROR
(
"Multi-tid block ack is not supported"
);
984
}
985
}
986
else
987
{
988
//Delayed block ack
989
params.
EnableAck
();
990
}
991
m_low
->
StartTransmission
(
m_currentPacket
, &
m_currentHdr
, params,
m_transmissionListener
);
992
}
993
994
void
995
EdcaTxopN::CompleteConfig
(
void
)
996
{
997
NS_LOG_FUNCTION
(
this
);
998
m_baManager
->
SetTxMiddle
(
m_txMiddle
);
999
m_low
->
RegisterBlockAckListenerForAc
(
m_ac
,
m_blockAckListener
);
1000
m_baManager
->
SetBlockAckInactivityCallback
(
MakeCallback
(&
EdcaTxopN::SendDelbaFrame
,
this
));
1001
}
1002
1003
void
1004
EdcaTxopN::SetBlockAckThreshold
(uint8_t threshold)
1005
{
1006
m_blockAckThreshold
= threshold;
1007
m_baManager
->
SetBlockAckThreshold
(threshold);
1008
}
1009
1010
void
1011
EdcaTxopN::SetBlockAckInactivityTimeout
(uint16_t
timeout
)
1012
{
1013
m_blockAckInactivityTimeout
=
timeout
;
1014
}
1015
1016
uint8_t
1017
EdcaTxopN::GetBlockAckThreshold
(
void
)
const
1018
{
1019
return
m_blockAckThreshold
;
1020
}
1021
1022
void
1023
EdcaTxopN::SendAddBaRequest
(
Mac48Address
dest, uint8_t tid, uint16_t startSeq,
1024
uint16_t
timeout
,
bool
immediateBAck)
1025
{
1026
NS_LOG_FUNCTION
(
this
);
1027
NS_LOG_DEBUG
(
"sent ADDBA request to "
<< dest);
1028
WifiMacHeader
hdr;
1029
hdr.
SetAction
();
1030
hdr.
SetAddr1
(dest);
1031
hdr.
SetAddr2
(
m_low
->
GetAddress
());
1032
hdr.
SetAddr3
(
m_low
->
GetAddress
());
1033
hdr.
SetDsNotTo
();
1034
hdr.
SetDsNotFrom
();
1035
1036
WifiActionHeader
actionHdr;
1037
WifiActionHeader::ActionValue
action;
1038
action.
blockAck
=
WifiActionHeader::BLOCK_ACK_ADDBA_REQUEST
;
1039
actionHdr.
SetAction
(
WifiActionHeader::BLOCK_ACK
, action);
1040
1041
Ptr<Packet>
packet = Create<Packet> ();
1042
/*Setting ADDBARequest header*/
1043
MgtAddBaRequestHeader
reqHdr;
1044
reqHdr.
SetAmsduSupport
(
true
);
1045
if
(immediateBAck)
1046
{
1047
reqHdr.SetImmediateBlockAck ();
1048
}
1049
else
1050
{
1051
reqHdr.SetDelayedBlockAck ();
1052
}
1053
reqHdr.SetTid (tid);
1054
/* For now we don't use buffer size field in the ADDBA request frame. The recipient
1055
* will choose how many packets it can receive under block ack.
1056
*/
1057
reqHdr.SetBufferSize (0);
1058
reqHdr.SetTimeout (timeout);
1059
reqHdr.SetStartingSequence (startSeq);
1060
1061
m_baManager
->
CreateAgreement
(&reqHdr, dest);
1062
1063
packet->
AddHeader
(reqHdr);
1064
packet->
AddHeader
(actionHdr);
1065
1066
m_currentPacket
= packet;
1067
m_currentHdr
= hdr;
1068
1069
uint16_t sequence =
m_txMiddle
->
GetNextSequenceNumberfor
(&
m_currentHdr
);
1070
m_currentHdr
.
SetSequenceNumber
(sequence);
1071
m_currentHdr
.
SetFragmentNumber
(0);
1072
m_currentHdr
.
SetNoMoreFragments
();
1073
m_currentHdr
.
SetNoRetry
();
1074
1075
MacLowTransmissionParameters
params;
1076
params.
EnableAck
();
1077
params.
DisableRts
();
1078
params.
DisableNextData
();
1079
params.
DisableOverrideDurationId
();
1080
1081
m_low
->
StartTransmission
(
m_currentPacket
, &
m_currentHdr
, params,
1082
m_transmissionListener
);
1083
}
1084
1085
void
1086
EdcaTxopN::SendDelbaFrame
(
Mac48Address
addr, uint8_t tid,
bool
byOriginator)
1087
{
1088
WifiMacHeader
hdr;
1089
hdr.
SetAction
();
1090
hdr.
SetAddr1
(addr);
1091
hdr.
SetAddr2
(
m_low
->
GetAddress
());
1092
hdr.
SetAddr3
(
m_low
->
GetAddress
());
1093
hdr.
SetDsNotTo
();
1094
hdr.
SetDsNotFrom
();
1095
1096
MgtDelBaHeader
delbaHdr;
1097
delbaHdr.
SetTid
(tid);
1098
if
(byOriginator)
1099
{
1100
delbaHdr.
SetByOriginator
();
1101
}
1102
else
1103
{
1104
delbaHdr.
SetByRecipient
();
1105
}
1106
1107
WifiActionHeader
actionHdr;
1108
WifiActionHeader::ActionValue
action;
1109
action.
blockAck
=
WifiActionHeader::BLOCK_ACK_DELBA
;
1110
actionHdr.
SetAction
(
WifiActionHeader::BLOCK_ACK
, action);
1111
1112
Ptr<Packet>
packet = Create<Packet> ();
1113
packet->
AddHeader
(delbaHdr);
1114
packet->
AddHeader
(actionHdr);
1115
1116
PushFront
(packet, hdr);
1117
}
1118
1119
int64_t
1120
EdcaTxopN::AssignStreams
(int64_t stream)
1121
{
1122
NS_LOG_FUNCTION
(
this
<< stream);
1123
m_rng
->
AssignStreams
(stream);
1124
return
1;
1125
}
1126
1127
void
1128
EdcaTxopN::DoStart
()
1129
{
1130
m_dcf
->
ResetCw
();
1131
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
1132
ns3::Dcf::DoStart
();
1133
}
1134
}
// namespace ns3
src
wifi
model
edca-txop-n.cc
Generated on Fri Dec 21 2012 19:00:48 for ns-3 by
1.8.1.2