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
115
private
:
116
EdcaTxopN
*
m_txop
;
117
};
118
119
class
EdcaTxopN::BlockAckEventListener
:
public
MacLowBlockAckEventListener
120
{
121
public
:
122
BlockAckEventListener
(
EdcaTxopN
* txop)
123
:
MacLowBlockAckEventListener
(),
124
m_txop
(txop) {
125
}
126
virtual
~BlockAckEventListener
() {}
127
128
virtual
void
BlockAckInactivityTimeout
(
Mac48Address
address, uint8_t tid)
129
{
130
m_txop
->
SendDelbaFrame
(address, tid,
false
);
131
}
132
133
private
:
134
EdcaTxopN
*
m_txop
;
135
};
136
137
NS_OBJECT_ENSURE_REGISTERED
(
EdcaTxopN
);
138
139
TypeId
140
EdcaTxopN::GetTypeId
(
void
)
141
{
142
static
TypeId
tid =
TypeId
(
"ns3::EdcaTxopN"
)
143
.
SetParent
(
ns3::Dcf::GetTypeId
())
144
.
AddConstructor
<
EdcaTxopN
> ()
145
.AddAttribute (
"BlockAckThreshold"
,
"If number of packets in this queue reaches this value,\
146
block ack mechanism is used. If this value is 0, block ack is never used."
,
147
UintegerValue
(0),
148
MakeUintegerAccessor (&
EdcaTxopN::SetBlockAckThreshold
,
149
&
EdcaTxopN::GetBlockAckThreshold
),
150
MakeUintegerChecker<uint8_t> (0, 64))
151
.AddAttribute (
"BlockAckInactivityTimeout"
,
"Represents max time (blocks of 1024 micro seconds) allowed for block ack\
152
inactivity. If this value isn't equal to 0 a timer start after that a\
153
block ack setup is completed and will be reset every time that a block\
154
ack frame is received. If this value is 0, block ack inactivity timeout won't be used."
,
155
UintegerValue
(0),
156
MakeUintegerAccessor (&
EdcaTxopN::SetBlockAckInactivityTimeout
),
157
MakeUintegerChecker<uint16_t> ())
158
.AddAttribute (
"Queue"
,
"The WifiMacQueue object"
,
159
PointerValue
(),
160
MakePointerAccessor (&
EdcaTxopN::GetQueue
),
161
MakePointerChecker<WifiMacQueue> ())
162
;
163
return
tid;
164
}
165
166
EdcaTxopN::EdcaTxopN
()
167
: m_manager (0),
168
m_currentPacket (0),
169
m_aggregator (0),
170
m_blockAckType (
COMPRESSED_BLOCK_ACK
)
171
{
172
NS_LOG_FUNCTION
(
this
);
173
m_transmissionListener
=
new
EdcaTxopN::TransmissionListener
(
this
);
174
m_blockAckListener
=
new
EdcaTxopN::BlockAckEventListener
(
this
);
175
m_dcf
=
new
EdcaTxopN::Dcf
(
this
);
176
m_queue
= CreateObject<WifiMacQueue> ();
177
m_rng
=
new
RealRandomStream
();
178
m_qosBlockedDestinations
=
new
QosBlockedDestinations
();
179
m_baManager
=
new
BlockAckManager
();
180
m_baManager
->
SetQueue
(
m_queue
);
181
m_baManager
->
SetBlockAckType
(
m_blockAckType
);
182
m_baManager
->
SetBlockDestinationCallback
(
MakeCallback
(&
QosBlockedDestinations::Block
,
m_qosBlockedDestinations
));
183
m_baManager
->
SetUnblockDestinationCallback
(
MakeCallback
(&
QosBlockedDestinations::Unblock
,
m_qosBlockedDestinations
));
184
m_baManager
->
SetMaxPacketDelay
(
m_queue
->
GetMaxDelay
());
185
}
186
187
EdcaTxopN::~EdcaTxopN
()
188
{
189
NS_LOG_FUNCTION
(
this
);
190
}
191
192
void
193
EdcaTxopN::DoDispose
(
void
)
194
{
195
NS_LOG_FUNCTION
(
this
);
196
m_queue
= 0;
197
m_low
= 0;
198
m_stationManager
= 0;
199
delete
m_transmissionListener
;
200
delete
m_dcf
;
201
delete
m_rng
;
202
delete
m_qosBlockedDestinations
;
203
delete
m_baManager
;
204
delete
m_blockAckListener
;
205
m_transmissionListener
= 0;
206
m_dcf
= 0;
207
m_rng
= 0;
208
m_qosBlockedDestinations
= 0;
209
m_baManager
= 0;
210
m_blockAckListener
= 0;
211
m_txMiddle
= 0;
212
m_aggregator
= 0;
213
}
214
215
void
216
EdcaTxopN::SetManager
(
DcfManager
*manager)
217
{
218
NS_LOG_FUNCTION
(
this
<< manager);
219
m_manager
= manager;
220
m_manager
->
Add
(
m_dcf
);
221
}
222
223
void
224
EdcaTxopN::SetTxOkCallback
(
TxOk
callback)
225
{
226
m_txOkCallback
= callback;
227
}
228
229
void
230
EdcaTxopN::SetTxFailedCallback
(
TxFailed
callback)
231
{
232
m_txFailedCallback
= callback;
233
}
234
235
void
236
EdcaTxopN::SetWifiRemoteStationManager
(
Ptr<WifiRemoteStationManager>
remoteManager)
237
{
238
NS_LOG_FUNCTION
(
this
<< remoteManager);
239
m_stationManager
= remoteManager;
240
}
241
void
242
EdcaTxopN::SetTypeOfStation
(
enum
TypeOfStation
type)
243
{
244
NS_LOG_FUNCTION
(
this
<< type);
245
m_typeOfStation
= type;
246
}
247
248
enum
TypeOfStation
249
EdcaTxopN::GetTypeOfStation
(
void
)
const
250
{
251
return
m_typeOfStation
;
252
}
253
254
Ptr<WifiMacQueue >
255
EdcaTxopN::GetQueue
()
const
256
{
257
NS_LOG_FUNCTION
(
this
);
258
return
m_queue
;
259
}
260
261
void
262
EdcaTxopN::SetMinCw
(uint32_t minCw)
263
{
264
NS_LOG_FUNCTION
(
this
<< minCw);
265
m_dcf
->
SetCwMin
(minCw);
266
}
267
268
void
269
EdcaTxopN::SetMaxCw
(uint32_t maxCw)
270
{
271
NS_LOG_FUNCTION
(
this
<< maxCw);
272
m_dcf
->
SetCwMax
(maxCw);
273
}
274
275
void
276
EdcaTxopN::SetAifsn
(uint32_t aifsn)
277
{
278
NS_LOG_FUNCTION
(
this
<< aifsn);
279
m_dcf
->
SetAifsn
(aifsn);
280
}
281
282
uint32_t
283
EdcaTxopN::GetMinCw
(
void
)
const
284
{
285
return
m_dcf
->
GetCwMin
();
286
}
287
288
uint32_t
289
EdcaTxopN::GetMaxCw
(
void
)
const
290
{
291
return
m_dcf
->
GetCwMax
();
292
}
293
294
uint32_t
295
EdcaTxopN::GetAifsn
(
void
)
const
296
{
297
return
m_dcf
->
GetAifsn
();
298
}
299
300
void
301
EdcaTxopN::SetTxMiddle
(
MacTxMiddle
*txMiddle)
302
{
303
m_txMiddle
= txMiddle;
304
}
305
306
Ptr<MacLow>
307
EdcaTxopN::Low
(
void
)
308
{
309
return
m_low
;
310
}
311
312
void
313
EdcaTxopN::SetLow
(
Ptr<MacLow>
low)
314
{
315
NS_LOG_FUNCTION
(
this
<< low);
316
m_low
= low;
317
}
318
319
bool
320
EdcaTxopN::NeedsAccess
(
void
)
const
321
{
322
return
!
m_queue
->
IsEmpty
() ||
m_currentPacket
!= 0 ||
m_baManager
->
HasPackets
();
323
}
324
325
void
326
EdcaTxopN::NotifyAccessGranted
(
void
)
327
{
328
NS_LOG_FUNCTION
(
this
);
329
if
(
m_currentPacket
== 0)
330
{
331
if
(
m_queue
->
IsEmpty
() && !
m_baManager
->
HasPackets
())
332
{
333
NS_LOG_DEBUG
(
"queue is empty"
);
334
return
;
335
}
336
if
(
m_baManager
->
HasBar
(
m_currentBar
))
337
{
338
SendBlockAckRequest
(
m_currentBar
);
339
return
;
340
}
341
/* check if packets need retransmission are stored in BlockAckManager */
342
m_currentPacket
=
m_baManager
->
GetNextPacket
(
m_currentHdr
);
343
if
(
m_currentPacket
== 0)
344
{
345
if
(
m_queue
->
PeekFirstAvailable
(&
m_currentHdr
,
m_currentPacketTimestamp
,
m_qosBlockedDestinations
) == 0)
346
{
347
NS_LOG_DEBUG
(
"no available packets in the queue"
);
348
return
;
349
}
350
if
(
m_currentHdr
.
IsQosData
() && !
m_currentHdr
.
GetAddr1
().
IsBroadcast
()
351
&&
m_blockAckThreshold
> 0
352
&& !
m_baManager
->
ExistsAgreement
(
m_currentHdr
.
GetAddr1
(),
m_currentHdr
.
GetQosTid
())
353
&&
SetupBlockAckIfNeeded
())
354
{
355
return
;
356
}
357
m_currentPacket
=
m_queue
->
DequeueFirstAvailable
(&
m_currentHdr
,
m_currentPacketTimestamp
,
m_qosBlockedDestinations
);
358
NS_ASSERT
(
m_currentPacket
!= 0);
359
360
uint16_t sequence =
m_txMiddle
->
GetNextSequenceNumberfor
(&
m_currentHdr
);
361
m_currentHdr
.
SetSequenceNumber
(sequence);
362
m_currentHdr
.
SetFragmentNumber
(0);
363
m_currentHdr
.
SetNoMoreFragments
();
364
m_currentHdr
.
SetNoRetry
();
365
m_fragmentNumber
= 0;
366
NS_LOG_DEBUG
(
"dequeued size="
<<
m_currentPacket
->
GetSize
() <<
367
", to="
<<
m_currentHdr
.
GetAddr1
() <<
368
", seq="
<<
m_currentHdr
.
GetSequenceControl
());
369
if
(
m_currentHdr
.
IsQosData
() && !
m_currentHdr
.
GetAddr1
().
IsBroadcast
())
370
{
371
VerifyBlockAck
();
372
}
373
}
374
}
375
MacLowTransmissionParameters
params;
376
params.
DisableOverrideDurationId
();
377
if
(
m_currentHdr
.
GetAddr1
().
IsGroup
())
378
{
379
params.
DisableRts
();
380
params.
DisableAck
();
381
params.
DisableNextData
();
382
m_low
->
StartTransmission
(
m_currentPacket
,
383
&
m_currentHdr
,
384
params,
385
m_transmissionListener
);
386
387
m_currentPacket
= 0;
388
m_dcf
->
ResetCw
();
389
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
390
StartAccessIfNeeded
();
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
bool
734
EdcaTxopN::NeedFragmentation
(
void
)
const
735
{
736
return
m_stationManager
->
NeedFragmentation
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
737
m_currentPacket
);
738
}
739
740
uint32_t
741
EdcaTxopN::GetFragmentSize
(
void
)
742
{
743
return
m_stationManager
->
GetFragmentSize
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
744
m_currentPacket
,
m_fragmentNumber
);
745
}
746
747
uint32_t
748
EdcaTxopN::GetNextFragmentSize
(
void
)
749
{
750
return
m_stationManager
->
GetFragmentSize
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
751
m_currentPacket
,
m_fragmentNumber
+ 1);
752
}
753
754
uint32_t
755
EdcaTxopN::GetFragmentOffset
(
void
)
756
{
757
return
m_stationManager
->
GetFragmentOffset
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
758
m_currentPacket
,
m_fragmentNumber
);
759
}
760
761
762
bool
763
EdcaTxopN::IsLastFragment
(
void
)
const
764
{
765
return
m_stationManager
->
IsLastFragment
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
766
m_currentPacket
,
m_fragmentNumber
);
767
}
768
769
Ptr<Packet>
770
EdcaTxopN::GetFragmentPacket
(
WifiMacHeader
*hdr)
771
{
772
*hdr =
m_currentHdr
;
773
hdr->
SetFragmentNumber
(
m_fragmentNumber
);
774
uint32_t startOffset =
GetFragmentOffset
();
775
Ptr<Packet>
fragment;
776
if
(
IsLastFragment
())
777
{
778
hdr->
SetNoMoreFragments
();
779
}
780
else
781
{
782
hdr->
SetMoreFragments
();
783
}
784
fragment =
m_currentPacket
->
CreateFragment
(startOffset,
785
GetFragmentSize
());
786
return
fragment;
787
}
788
789
void
790
EdcaTxopN::SetAccessCategory
(
enum
AcIndex
ac)
791
{
792
m_ac
= ac;
793
}
794
795
Mac48Address
796
EdcaTxopN::MapSrcAddressForAggregation
(
const
WifiMacHeader
&hdr)
797
{
798
Mac48Address
retval;
799
if
(
m_typeOfStation
==
STA
||
m_typeOfStation
==
ADHOC_STA
)
800
{
801
retval = hdr.
GetAddr2
();
802
}
803
else
804
{
805
retval = hdr.
GetAddr3
();
806
}
807
return
retval;
808
}
809
810
Mac48Address
811
EdcaTxopN::MapDestAddressForAggregation
(
const
WifiMacHeader
&hdr)
812
{
813
Mac48Address
retval;
814
if
(
m_typeOfStation
==
AP
||
m_typeOfStation
==
ADHOC_STA
)
815
{
816
retval = hdr.
GetAddr1
();
817
}
818
else
819
{
820
retval = hdr.
GetAddr3
();
821
}
822
return
retval;
823
}
824
825
void
826
EdcaTxopN::SetMsduAggregator
(
Ptr<MsduAggregator>
aggr)
827
{
828
m_aggregator
= aggr;
829
}
830
831
void
832
EdcaTxopN::PushFront
(
Ptr<const Packet>
packet,
const
WifiMacHeader
&hdr)
833
{
834
NS_LOG_FUNCTION
(
this
<< packet << &hdr);
835
WifiMacTrailer
fcs;
836
uint32_t fullPacketSize = hdr.
GetSerializedSize
() + packet->
GetSize
() + fcs.
GetSerializedSize
();
837
m_stationManager
->
PrepareForQueue
(hdr.
GetAddr1
(), &hdr,
838
packet, fullPacketSize);
839
m_queue
->
PushFront
(packet, hdr);
840
StartAccessIfNeeded
();
841
}
842
843
void
844
EdcaTxopN::GotAddBaResponse
(
const
MgtAddBaResponseHeader
*respHdr,
Mac48Address
recipient)
845
{
846
NS_LOG_FUNCTION
(
this
);
847
NS_LOG_DEBUG
(
"received ADDBA response from "
<< recipient);
848
uint8_t tid = respHdr->
GetTid
();
849
if
(
m_baManager
->
ExistsAgreementInState
(recipient, tid,
OriginatorBlockAckAgreement::PENDING
))
850
{
851
if
(respHdr->
GetStatusCode
().
IsSuccess
())
852
{
853
NS_LOG_DEBUG
(
"block ack agreement established with "
<< recipient);
854
m_baManager
->
UpdateAgreement
(respHdr, recipient);
855
}
856
else
857
{
858
NS_LOG_DEBUG
(
"discard ADDBA response"
<< recipient);
859
m_baManager
->
NotifyAgreementUnsuccessful
(recipient, tid);
860
}
861
}
862
RestartAccessIfNeeded
();
863
}
864
865
void
866
EdcaTxopN::GotDelBaFrame
(
const
MgtDelBaHeader
*delBaHdr,
Mac48Address
recipient)
867
{
868
NS_LOG_FUNCTION
(
this
);
869
NS_LOG_DEBUG
(
"received DELBA frame from="
<< recipient);
870
m_baManager
->
TearDownBlockAck
(recipient, delBaHdr->
GetTid
());
871
}
872
873
void
874
EdcaTxopN::GotBlockAck
(
const
CtrlBAckResponseHeader
*blockAck,
Mac48Address
recipient)
875
{
876
NS_LOG_DEBUG
(
"got block ack from="
<< recipient);
877
m_baManager
->
NotifyGotBlockAck
(blockAck, recipient);
878
m_currentPacket
= 0;
879
m_dcf
->
ResetCw
();
880
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
881
RestartAccessIfNeeded
();
882
}
883
884
void
885
EdcaTxopN::VerifyBlockAck
(
void
)
886
{
887
NS_LOG_FUNCTION
(
this
);
888
uint8_t tid =
m_currentHdr
.
GetQosTid
();
889
Mac48Address
recipient =
m_currentHdr
.
GetAddr1
();
890
uint16_t sequence =
m_currentHdr
.
GetSequenceNumber
();
891
if
(
m_baManager
->
ExistsAgreementInState
(recipient, tid,
OriginatorBlockAckAgreement::INACTIVE
))
892
{
893
m_baManager
->
SwitchToBlockAckIfNeeded
(recipient, tid, sequence);
894
}
895
if
(
m_baManager
->
ExistsAgreementInState
(recipient, tid,
OriginatorBlockAckAgreement::ESTABLISHED
))
896
{
897
m_currentHdr
.
SetQosAckPolicy
(
WifiMacHeader::BLOCK_ACK
);
898
}
899
}
900
901
void
902
EdcaTxopN::CompleteTx
(
void
)
903
{
904
if
(
m_currentHdr
.
IsQosData
() &&
m_currentHdr
.
IsQosBlockAck
())
905
{
906
if
(!
m_currentHdr
.
IsRetry
())
907
{
908
m_baManager
->
StorePacket
(
m_currentPacket
,
m_currentHdr
,
m_currentPacketTimestamp
);
909
}
910
m_baManager
->
NotifyMpduTransmission
(
m_currentHdr
.
GetAddr1
(),
m_currentHdr
.
GetQosTid
(),
911
m_txMiddle
->
GetNextSeqNumberByTidAndAddress
(
m_currentHdr
.
GetQosTid
(),
912
m_currentHdr
.
GetAddr1
()));
913
//we are not waiting for an ack: transmission is completed
914
m_currentPacket
= 0;
915
m_dcf
->
ResetCw
();
916
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
917
StartAccessIfNeeded
();
918
}
919
}
920
921
bool
922
EdcaTxopN::SetupBlockAckIfNeeded
()
923
{
924
uint8_t tid =
m_currentHdr
.
GetQosTid
();
925
Mac48Address
recipient =
m_currentHdr
.
GetAddr1
();
926
927
uint32_t packets =
m_queue
->
GetNPacketsByTidAndAddress
(tid,
WifiMacHeader::ADDR1
, recipient);
928
929
if
(packets >=
m_blockAckThreshold
)
930
{
931
/* Block ack setup */
932
uint16_t startingSequence =
m_txMiddle
->
GetNextSeqNumberByTidAndAddress
(tid, recipient);
933
SendAddBaRequest
(recipient, tid, startingSequence,
m_blockAckInactivityTimeout
,
true
);
934
return
true
;
935
}
936
return
false
;
937
}
938
939
void
940
EdcaTxopN::SendBlockAckRequest
(
const
struct
Bar
&bar)
941
{
942
NS_LOG_FUNCTION
(
this
);
943
WifiMacHeader
hdr;
944
hdr.
SetType
(
WIFI_MAC_CTL_BACKREQ
);
945
hdr.
SetAddr1
(bar.
recipient
);
946
hdr.
SetAddr2
(
m_low
->
GetAddress
());
947
hdr.
SetAddr3
(
m_low
->
GetBssid
());
948
hdr.
SetDsNotTo
();
949
hdr.
SetDsNotFrom
();
950
hdr.
SetNoRetry
();
951
hdr.
SetNoMoreFragments
();
952
953
m_currentPacket
= bar.
bar
;
954
m_currentHdr
= hdr;
955
956
MacLowTransmissionParameters
params;
957
params.
DisableRts
();
958
params.
DisableNextData
();
959
params.
DisableOverrideDurationId
();
960
if
(bar.
immediate
)
961
{
962
if
(
m_blockAckType
==
BASIC_BLOCK_ACK
)
963
{
964
params.
EnableBasicBlockAck
();
965
}
966
else
if
(
m_blockAckType
==
COMPRESSED_BLOCK_ACK
)
967
{
968
params.
EnableCompressedBlockAck
();
969
}
970
else
if
(
m_blockAckType
==
MULTI_TID_BLOCK_ACK
)
971
{
972
NS_FATAL_ERROR
(
"Multi-tid block ack is not supported"
);
973
}
974
}
975
else
976
{
977
//Delayed block ack
978
params.
EnableAck
();
979
}
980
m_low
->
StartTransmission
(
m_currentPacket
, &
m_currentHdr
, params,
m_transmissionListener
);
981
}
982
983
void
984
EdcaTxopN::CompleteConfig
(
void
)
985
{
986
NS_LOG_FUNCTION
(
this
);
987
m_baManager
->
SetTxMiddle
(
m_txMiddle
);
988
m_low
->
RegisterBlockAckListenerForAc
(
m_ac
,
m_blockAckListener
);
989
m_baManager
->
SetBlockAckInactivityCallback
(
MakeCallback
(&
EdcaTxopN::SendDelbaFrame
,
this
));
990
}
991
992
void
993
EdcaTxopN::SetBlockAckThreshold
(uint8_t threshold)
994
{
995
m_blockAckThreshold
= threshold;
996
m_baManager
->
SetBlockAckThreshold
(threshold);
997
}
998
999
void
1000
EdcaTxopN::SetBlockAckInactivityTimeout
(uint16_t
timeout
)
1001
{
1002
m_blockAckInactivityTimeout
=
timeout
;
1003
}
1004
1005
uint8_t
1006
EdcaTxopN::GetBlockAckThreshold
(
void
)
const
1007
{
1008
return
m_blockAckThreshold
;
1009
}
1010
1011
void
1012
EdcaTxopN::SendAddBaRequest
(
Mac48Address
dest, uint8_t tid, uint16_t startSeq,
1013
uint16_t
timeout
,
bool
immediateBAck)
1014
{
1015
NS_LOG_FUNCTION
(
this
);
1016
NS_LOG_DEBUG
(
"sent ADDBA request to "
<< dest);
1017
WifiMacHeader
hdr;
1018
hdr.
SetAction
();
1019
hdr.
SetAddr1
(dest);
1020
hdr.
SetAddr2
(
m_low
->
GetAddress
());
1021
hdr.
SetAddr3
(
m_low
->
GetAddress
());
1022
hdr.
SetDsNotTo
();
1023
hdr.
SetDsNotFrom
();
1024
1025
WifiActionHeader
actionHdr;
1026
WifiActionHeader::ActionValue
action;
1027
action.
blockAck
=
WifiActionHeader::BLOCK_ACK_ADDBA_REQUEST
;
1028
actionHdr.
SetAction
(
WifiActionHeader::BLOCK_ACK
, action);
1029
1030
Ptr<Packet>
packet = Create<Packet> ();
1031
/*Setting ADDBARequest header*/
1032
MgtAddBaRequestHeader
reqHdr;
1033
reqHdr.
SetAmsduSupport
(
true
);
1034
if
(immediateBAck)
1035
{
1036
reqHdr.SetImmediateBlockAck ();
1037
}
1038
else
1039
{
1040
reqHdr.SetDelayedBlockAck ();
1041
}
1042
reqHdr.SetTid (tid);
1043
/* For now we don't use buffer size field in the ADDBA request frame. The recipient
1044
* will choose how many packets it can receive under block ack.
1045
*/
1046
reqHdr.SetBufferSize (0);
1047
reqHdr.SetTimeout (timeout);
1048
reqHdr.SetStartingSequence (startSeq);
1049
1050
m_baManager
->
CreateAgreement
(&reqHdr, dest);
1051
1052
packet->
AddHeader
(reqHdr);
1053
packet->
AddHeader
(actionHdr);
1054
1055
m_currentPacket
= packet;
1056
m_currentHdr
= hdr;
1057
1058
uint16_t sequence =
m_txMiddle
->
GetNextSequenceNumberfor
(&
m_currentHdr
);
1059
m_currentHdr
.
SetSequenceNumber
(sequence);
1060
m_currentHdr
.
SetFragmentNumber
(0);
1061
m_currentHdr
.
SetNoMoreFragments
();
1062
m_currentHdr
.
SetNoRetry
();
1063
1064
MacLowTransmissionParameters
params;
1065
params.
EnableAck
();
1066
params.
DisableRts
();
1067
params.
DisableNextData
();
1068
params.
DisableOverrideDurationId
();
1069
1070
m_low
->
StartTransmission
(
m_currentPacket
, &
m_currentHdr
, params,
1071
m_transmissionListener
);
1072
}
1073
1074
void
1075
EdcaTxopN::SendDelbaFrame
(
Mac48Address
addr, uint8_t tid,
bool
byOriginator)
1076
{
1077
WifiMacHeader
hdr;
1078
hdr.
SetAction
();
1079
hdr.
SetAddr1
(addr);
1080
hdr.
SetAddr2
(
m_low
->
GetAddress
());
1081
hdr.
SetAddr3
(
m_low
->
GetAddress
());
1082
hdr.
SetDsNotTo
();
1083
hdr.
SetDsNotFrom
();
1084
1085
MgtDelBaHeader
delbaHdr;
1086
delbaHdr.
SetTid
(tid);
1087
if
(byOriginator)
1088
{
1089
delbaHdr.
SetByOriginator
();
1090
}
1091
else
1092
{
1093
delbaHdr.
SetByRecipient
();
1094
}
1095
1096
WifiActionHeader
actionHdr;
1097
WifiActionHeader::ActionValue
action;
1098
action.
blockAck
=
WifiActionHeader::BLOCK_ACK_DELBA
;
1099
actionHdr.
SetAction
(
WifiActionHeader::BLOCK_ACK
, action);
1100
1101
Ptr<Packet>
packet = Create<Packet> ();
1102
packet->
AddHeader
(delbaHdr);
1103
packet->
AddHeader
(actionHdr);
1104
1105
PushFront
(packet, hdr);
1106
}
1107
1108
int64_t
1109
EdcaTxopN::AssignStreams
(int64_t stream)
1110
{
1111
NS_LOG_FUNCTION
(
this
<< stream);
1112
m_rng
->
AssignStreams
(stream);
1113
return
1;
1114
}
1115
1116
void
1117
EdcaTxopN::DoStart
()
1118
{
1119
m_dcf
->
ResetCw
();
1120
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
1121
ns3::Dcf::DoStart
();
1122
}
1123
}
// namespace ns3
src
wifi
model
edca-txop-n.cc
Generated on Tue Oct 9 2012 16:45:48 for ns-3 by
1.8.1.2