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
NS_LOG_FUNCTION
(
this
<< &callback);
231
m_txOkCallback
= callback;
232
}
233
234
void
235
EdcaTxopN::SetTxFailedCallback
(
TxFailed
callback)
236
{
237
NS_LOG_FUNCTION
(
this
<< &callback);
238
m_txFailedCallback
= callback;
239
}
240
241
void
242
EdcaTxopN::SetWifiRemoteStationManager
(
Ptr<WifiRemoteStationManager>
remoteManager)
243
{
244
NS_LOG_FUNCTION
(
this
<< remoteManager);
245
m_stationManager
= remoteManager;
246
}
247
void
248
EdcaTxopN::SetTypeOfStation
(
enum
TypeOfStation
type)
249
{
250
NS_LOG_FUNCTION
(
this
<< static_cast<uint32_t> (type));
251
m_typeOfStation
= type;
252
}
253
254
enum
TypeOfStation
255
EdcaTxopN::GetTypeOfStation
(
void
)
const
256
{
257
NS_LOG_FUNCTION
(
this
);
258
return
m_typeOfStation
;
259
}
260
261
Ptr<WifiMacQueue >
262
EdcaTxopN::GetQueue
()
const
263
{
264
NS_LOG_FUNCTION
(
this
);
265
return
m_queue
;
266
}
267
268
void
269
EdcaTxopN::SetMinCw
(uint32_t minCw)
270
{
271
NS_LOG_FUNCTION
(
this
<< minCw);
272
m_dcf
->
SetCwMin
(minCw);
273
}
274
275
void
276
EdcaTxopN::SetMaxCw
(uint32_t maxCw)
277
{
278
NS_LOG_FUNCTION
(
this
<< maxCw);
279
m_dcf
->
SetCwMax
(maxCw);
280
}
281
282
void
283
EdcaTxopN::SetAifsn
(uint32_t aifsn)
284
{
285
NS_LOG_FUNCTION
(
this
<< aifsn);
286
m_dcf
->
SetAifsn
(aifsn);
287
}
288
289
uint32_t
290
EdcaTxopN::GetMinCw
(
void
)
const
291
{
292
NS_LOG_FUNCTION
(
this
);
293
return
m_dcf
->
GetCwMin
();
294
}
295
296
uint32_t
297
EdcaTxopN::GetMaxCw
(
void
)
const
298
{
299
NS_LOG_FUNCTION
(
this
);
300
return
m_dcf
->
GetCwMax
();
301
}
302
303
uint32_t
304
EdcaTxopN::GetAifsn
(
void
)
const
305
{
306
NS_LOG_FUNCTION
(
this
);
307
return
m_dcf
->
GetAifsn
();
308
}
309
310
void
311
EdcaTxopN::SetTxMiddle
(
MacTxMiddle
*txMiddle)
312
{
313
NS_LOG_FUNCTION
(
this
<< txMiddle);
314
m_txMiddle
= txMiddle;
315
}
316
317
Ptr<MacLow>
318
EdcaTxopN::Low
(
void
)
319
{
320
NS_LOG_FUNCTION
(
this
);
321
return
m_low
;
322
}
323
324
void
325
EdcaTxopN::SetLow
(
Ptr<MacLow>
low)
326
{
327
NS_LOG_FUNCTION
(
this
<< low);
328
m_low
= low;
329
}
330
331
bool
332
EdcaTxopN::NeedsAccess
(
void
)
const
333
{
334
NS_LOG_FUNCTION
(
this
);
335
return
!
m_queue
->
IsEmpty
() ||
m_currentPacket
!= 0 ||
m_baManager
->
HasPackets
();
336
}
337
338
void
339
EdcaTxopN::NotifyAccessGranted
(
void
)
340
{
341
NS_LOG_FUNCTION
(
this
);
342
if
(
m_currentPacket
== 0)
343
{
344
if
(
m_queue
->
IsEmpty
() && !
m_baManager
->
HasPackets
())
345
{
346
NS_LOG_DEBUG
(
"queue is empty"
);
347
return
;
348
}
349
if
(
m_baManager
->
HasBar
(
m_currentBar
))
350
{
351
SendBlockAckRequest
(
m_currentBar
);
352
return
;
353
}
354
/* check if packets need retransmission are stored in BlockAckManager */
355
m_currentPacket
=
m_baManager
->
GetNextPacket
(
m_currentHdr
);
356
if
(
m_currentPacket
== 0)
357
{
358
if
(
m_queue
->
PeekFirstAvailable
(&
m_currentHdr
,
m_currentPacketTimestamp
,
m_qosBlockedDestinations
) == 0)
359
{
360
NS_LOG_DEBUG
(
"no available packets in the queue"
);
361
return
;
362
}
363
if
(
m_currentHdr
.
IsQosData
() && !
m_currentHdr
.
GetAddr1
().
IsBroadcast
()
364
&&
m_blockAckThreshold
> 0
365
&& !
m_baManager
->
ExistsAgreement
(
m_currentHdr
.
GetAddr1
(),
m_currentHdr
.
GetQosTid
())
366
&&
SetupBlockAckIfNeeded
())
367
{
368
return
;
369
}
370
m_currentPacket
=
m_queue
->
DequeueFirstAvailable
(&
m_currentHdr
,
m_currentPacketTimestamp
,
m_qosBlockedDestinations
);
371
NS_ASSERT
(
m_currentPacket
!= 0);
372
373
uint16_t sequence =
m_txMiddle
->
GetNextSequenceNumberfor
(&
m_currentHdr
);
374
m_currentHdr
.
SetSequenceNumber
(sequence);
375
m_currentHdr
.
SetFragmentNumber
(0);
376
m_currentHdr
.
SetNoMoreFragments
();
377
m_currentHdr
.
SetNoRetry
();
378
m_fragmentNumber
= 0;
379
NS_LOG_DEBUG
(
"dequeued size="
<<
m_currentPacket
->
GetSize
() <<
380
", to="
<<
m_currentHdr
.
GetAddr1
() <<
381
", seq="
<<
m_currentHdr
.
GetSequenceControl
());
382
if
(
m_currentHdr
.
IsQosData
() && !
m_currentHdr
.
GetAddr1
().
IsBroadcast
())
383
{
384
VerifyBlockAck
();
385
}
386
}
387
}
388
MacLowTransmissionParameters
params;
389
params.
DisableOverrideDurationId
();
390
if
(
m_currentHdr
.
GetAddr1
().
IsGroup
())
391
{
392
params.
DisableRts
();
393
params.
DisableAck
();
394
params.
DisableNextData
();
395
m_low
->
StartTransmission
(
m_currentPacket
,
396
&
m_currentHdr
,
397
params,
398
m_transmissionListener
);
399
400
NS_LOG_DEBUG
(
"tx broadcast"
);
401
}
402
else
if
(
m_currentHdr
.
GetType
() ==
WIFI_MAC_CTL_BACKREQ
)
403
{
404
SendBlockAckRequest
(
m_currentBar
);
405
}
406
else
407
{
408
if
(
m_currentHdr
.
IsQosData
() &&
m_currentHdr
.
IsQosBlockAck
())
409
{
410
params.
DisableAck
();
411
}
412
else
413
{
414
params.
EnableAck
();
415
}
416
if
(
NeedFragmentation
() && ((
m_currentHdr
.
IsQosData
()
417
&& !
m_currentHdr
.
IsQosAmsdu
())
418
||
419
(
m_currentHdr
.
IsData
()
420
&& !
m_currentHdr
.
IsQosData
() &&
m_currentHdr
.
IsQosAmsdu
()))
421
&& (
m_blockAckThreshold
== 0
422
||
m_blockAckType
==
BASIC_BLOCK_ACK
))
423
{
424
//With COMPRESSED_BLOCK_ACK fragmentation must be avoided.
425
params.
DisableRts
();
426
WifiMacHeader
hdr;
427
Ptr<Packet>
fragment =
GetFragmentPacket
(&hdr);
428
if
(
IsLastFragment
())
429
{
430
NS_LOG_DEBUG
(
"fragmenting last fragment size="
<< fragment->
GetSize
());
431
params.
DisableNextData
();
432
}
433
else
434
{
435
NS_LOG_DEBUG
(
"fragmenting size="
<< fragment->
GetSize
());
436
params.
EnableNextData
(
GetNextFragmentSize
());
437
}
438
m_low
->
StartTransmission
(fragment, &hdr, params,
439
m_transmissionListener
);
440
}
441
else
442
{
443
WifiMacHeader
peekedHdr;
444
if
(
m_currentHdr
.
IsQosData
()
445
&&
m_queue
->
PeekByTidAndAddress
(&peekedHdr,
m_currentHdr
.
GetQosTid
(),
446
WifiMacHeader::ADDR1
,
m_currentHdr
.
GetAddr1
())
447
&& !
m_currentHdr
.
GetAddr1
().
IsBroadcast
()
448
&&
m_aggregator
!= 0 && !
m_currentHdr
.
IsRetry
())
449
{
450
/* here is performed aggregation */
451
Ptr<Packet>
currentAggregatedPacket = Create<Packet> ();
452
m_aggregator
->
Aggregate
(
m_currentPacket
, currentAggregatedPacket,
453
MapSrcAddressForAggregation
(peekedHdr),
454
MapDestAddressForAggregation
(peekedHdr));
455
bool
aggregated =
false
;
456
bool
isAmsdu =
false
;
457
Ptr<const Packet>
peekedPacket =
m_queue
->
PeekByTidAndAddress
(&peekedHdr,
m_currentHdr
.
GetQosTid
(),
458
WifiMacHeader::ADDR1
,
459
m_currentHdr
.
GetAddr1
());
460
while
(peekedPacket != 0)
461
{
462
aggregated =
m_aggregator
->
Aggregate
(peekedPacket, currentAggregatedPacket,
463
MapSrcAddressForAggregation
(peekedHdr),
464
MapDestAddressForAggregation
(peekedHdr));
465
if
(aggregated)
466
{
467
isAmsdu =
true
;
468
m_queue
->
Remove
(peekedPacket);
469
}
470
else
471
{
472
break
;
473
}
474
peekedPacket =
m_queue
->
PeekByTidAndAddress
(&peekedHdr,
m_currentHdr
.
GetQosTid
(),
475
WifiMacHeader::ADDR1
,
m_currentHdr
.
GetAddr1
());
476
}
477
if
(isAmsdu)
478
{
479
m_currentHdr
.
SetQosAmsdu
();
480
m_currentHdr
.
SetAddr3
(
m_low
->
GetBssid
());
481
m_currentPacket
= currentAggregatedPacket;
482
currentAggregatedPacket = 0;
483
NS_LOG_DEBUG
(
"tx unicast A-MSDU"
);
484
}
485
}
486
if
(
NeedRts
())
487
{
488
params.
EnableRts
();
489
NS_LOG_DEBUG
(
"tx unicast rts"
);
490
}
491
else
492
{
493
params.
DisableRts
();
494
NS_LOG_DEBUG
(
"tx unicast"
);
495
}
496
params.
DisableNextData
();
497
m_low
->
StartTransmission
(
m_currentPacket
, &
m_currentHdr
,
498
params,
m_transmissionListener
);
499
CompleteTx
();
500
}
501
}
502
}
503
504
void
EdcaTxopN::NotifyInternalCollision
(
void
)
505
{
506
NS_LOG_FUNCTION
(
this
);
507
NotifyCollision
();
508
}
509
510
void
511
EdcaTxopN::NotifyCollision
(
void
)
512
{
513
NS_LOG_FUNCTION
(
this
);
514
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
515
RestartAccessIfNeeded
();
516
}
517
518
void
519
EdcaTxopN::GotCts
(
double
snr,
WifiMode
txMode)
520
{
521
NS_LOG_FUNCTION
(
this
<< snr << txMode);
522
NS_LOG_DEBUG
(
"got cts"
);
523
}
524
525
void
526
EdcaTxopN::MissedCts
(
void
)
527
{
528
NS_LOG_FUNCTION
(
this
);
529
NS_LOG_DEBUG
(
"missed cts"
);
530
if
(!
NeedRtsRetransmission
())
531
{
532
NS_LOG_DEBUG
(
"Cts Fail"
);
533
m_stationManager
->
ReportFinalRtsFailed
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
);
534
if
(!
m_txFailedCallback
.
IsNull
())
535
{
536
m_txFailedCallback
(
m_currentHdr
);
537
}
538
// to reset the dcf.
539
m_currentPacket
= 0;
540
m_dcf
->
ResetCw
();
541
}
542
else
543
{
544
m_dcf
->
UpdateFailedCw
();
545
}
546
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
547
RestartAccessIfNeeded
();
548
}
549
550
void
551
EdcaTxopN::NotifyChannelSwitching
(
void
)
552
{
553
NS_LOG_FUNCTION
(
this
);
554
m_queue
->
Flush
();
555
m_currentPacket
= 0;
556
}
557
558
void
559
EdcaTxopN::Queue
(
Ptr<const Packet>
packet,
const
WifiMacHeader
&hdr)
560
{
561
NS_LOG_FUNCTION
(
this
<< packet << &hdr);
562
WifiMacTrailer
fcs;
563
uint32_t fullPacketSize = hdr.
GetSerializedSize
() + packet->
GetSize
() + fcs.
GetSerializedSize
();
564
m_stationManager
->
PrepareForQueue
(hdr.
GetAddr1
(), &hdr,
565
packet, fullPacketSize);
566
m_queue
->
Enqueue
(packet, hdr);
567
StartAccessIfNeeded
();
568
}
569
570
void
571
EdcaTxopN::GotAck
(
double
snr,
WifiMode
txMode)
572
{
573
NS_LOG_FUNCTION
(
this
<< snr << txMode);
574
if
(!
NeedFragmentation
()
575
||
IsLastFragment
()
576
||
m_currentHdr
.
IsQosAmsdu
())
577
{
578
NS_LOG_DEBUG
(
"got ack. tx done."
);
579
if
(!
m_txOkCallback
.
IsNull
())
580
{
581
m_txOkCallback
(
m_currentHdr
);
582
}
583
584
if
(
m_currentHdr
.
IsAction
())
585
{
586
WifiActionHeader
actionHdr;
587
Ptr<Packet>
p =
m_currentPacket
->
Copy
();
588
p->
RemoveHeader
(actionHdr);
589
if
(actionHdr.
GetCategory
() ==
WifiActionHeader::BLOCK_ACK
590
&& actionHdr.
GetAction
().
blockAck
==
WifiActionHeader::BLOCK_ACK_DELBA
)
591
{
592
MgtDelBaHeader
delBa;
593
p->
PeekHeader
(delBa);
594
if
(delBa.
IsByOriginator
())
595
{
596
m_baManager
->
TearDownBlockAck
(
m_currentHdr
.
GetAddr1
(), delBa.
GetTid
());
597
}
598
else
599
{
600
m_low
->
DestroyBlockAckAgreement
(
m_currentHdr
.
GetAddr1
(), delBa.
GetTid
());
601
}
602
}
603
}
604
m_currentPacket
= 0;
605
606
m_dcf
->
ResetCw
();
607
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
608
RestartAccessIfNeeded
();
609
}
610
else
611
{
612
NS_LOG_DEBUG
(
"got ack. tx not done, size="
<<
m_currentPacket
->
GetSize
());
613
}
614
}
615
616
void
617
EdcaTxopN::MissedAck
(
void
)
618
{
619
NS_LOG_FUNCTION
(
this
);
620
NS_LOG_DEBUG
(
"missed ack"
);
621
if
(!
NeedDataRetransmission
())
622
{
623
NS_LOG_DEBUG
(
"Ack Fail"
);
624
m_stationManager
->
ReportFinalDataFailed
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
);
625
if
(!
m_txFailedCallback
.
IsNull
())
626
{
627
m_txFailedCallback
(
m_currentHdr
);
628
}
629
// to reset the dcf.
630
m_currentPacket
= 0;
631
m_dcf
->
ResetCw
();
632
}
633
else
634
{
635
NS_LOG_DEBUG
(
"Retransmit"
);
636
m_currentHdr
.
SetRetry
();
637
m_dcf
->
UpdateFailedCw
();
638
}
639
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
640
RestartAccessIfNeeded
();
641
}
642
643
void
644
EdcaTxopN::MissedBlockAck
(
void
)
645
{
646
NS_LOG_FUNCTION
(
this
);
647
NS_LOG_DEBUG
(
"missed block ack"
);
648
//should i report this to station addressed by ADDR1?
649
NS_LOG_DEBUG
(
"Retransmit block ack request"
);
650
m_currentHdr
.
SetRetry
();
651
m_dcf
->
UpdateFailedCw
();
652
653
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
654
RestartAccessIfNeeded
();
655
}
656
657
Ptr<MsduAggregator>
658
EdcaTxopN::GetMsduAggregator
(
void
)
const
659
{
660
return
m_aggregator
;
661
}
662
663
void
664
EdcaTxopN::RestartAccessIfNeeded
(
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
void
676
EdcaTxopN::StartAccessIfNeeded
(
void
)
677
{
678
NS_LOG_FUNCTION
(
this
);
679
if
(
m_currentPacket
== 0
680
&& (!
m_queue
->
IsEmpty
() ||
m_baManager
->
HasPackets
())
681
&& !
m_dcf
->
IsAccessRequested
())
682
{
683
m_manager
->
RequestAccess
(
m_dcf
);
684
}
685
}
686
687
bool
688
EdcaTxopN::NeedRts
(
void
)
689
{
690
NS_LOG_FUNCTION
(
this
);
691
return
m_stationManager
->
NeedRts
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
692
m_currentPacket
);
693
}
694
695
bool
696
EdcaTxopN::NeedRtsRetransmission
(
void
)
697
{
698
NS_LOG_FUNCTION
(
this
);
699
return
m_stationManager
->
NeedRtsRetransmission
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
700
m_currentPacket
);
701
}
702
703
bool
704
EdcaTxopN::NeedDataRetransmission
(
void
)
705
{
706
NS_LOG_FUNCTION
(
this
);
707
return
m_stationManager
->
NeedDataRetransmission
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
708
m_currentPacket
);
709
}
710
711
void
712
EdcaTxopN::NextFragment
(
void
)
713
{
714
NS_LOG_FUNCTION
(
this
);
715
m_fragmentNumber
++;
716
}
717
718
void
719
EdcaTxopN::StartNext
(
void
)
720
{
721
NS_LOG_FUNCTION
(
this
);
722
NS_LOG_DEBUG
(
"start next packet fragment"
);
723
/* this callback is used only for fragments. */
724
NextFragment
();
725
WifiMacHeader
hdr;
726
Ptr<Packet>
fragment =
GetFragmentPacket
(&hdr);
727
MacLowTransmissionParameters
params;
728
params.
EnableAck
();
729
params.
DisableRts
();
730
params.
DisableOverrideDurationId
();
731
if
(
IsLastFragment
())
732
{
733
params.
DisableNextData
();
734
}
735
else
736
{
737
params.
EnableNextData
(
GetNextFragmentSize
());
738
}
739
Low
()->
StartTransmission
(fragment, &hdr, params,
m_transmissionListener
);
740
}
741
742
void
743
EdcaTxopN::Cancel
(
void
)
744
{
745
NS_LOG_FUNCTION
(
this
);
746
NS_LOG_DEBUG
(
"transmission cancelled"
);
747
}
748
749
void
750
EdcaTxopN::EndTxNoAck
(
void
)
751
{
752
NS_LOG_FUNCTION
(
this
);
753
NS_LOG_DEBUG
(
"a transmission that did not require an ACK just finished"
);
754
m_currentPacket
= 0;
755
m_dcf
->
ResetCw
();
756
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
757
StartAccessIfNeeded
();
758
}
759
760
bool
761
EdcaTxopN::NeedFragmentation
(
void
)
const
762
{
763
NS_LOG_FUNCTION
(
this
);
764
return
m_stationManager
->
NeedFragmentation
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
765
m_currentPacket
);
766
}
767
768
uint32_t
769
EdcaTxopN::GetFragmentSize
(
void
)
770
{
771
NS_LOG_FUNCTION
(
this
);
772
return
m_stationManager
->
GetFragmentSize
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
773
m_currentPacket
,
m_fragmentNumber
);
774
}
775
776
uint32_t
777
EdcaTxopN::GetNextFragmentSize
(
void
)
778
{
779
NS_LOG_FUNCTION
(
this
);
780
return
m_stationManager
->
GetFragmentSize
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
781
m_currentPacket
,
m_fragmentNumber
+ 1);
782
}
783
784
uint32_t
785
EdcaTxopN::GetFragmentOffset
(
void
)
786
{
787
NS_LOG_FUNCTION
(
this
);
788
return
m_stationManager
->
GetFragmentOffset
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
789
m_currentPacket
,
m_fragmentNumber
);
790
}
791
792
793
bool
794
EdcaTxopN::IsLastFragment
(
void
)
const
795
{
796
NS_LOG_FUNCTION
(
this
);
797
return
m_stationManager
->
IsLastFragment
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
798
m_currentPacket
,
m_fragmentNumber
);
799
}
800
801
Ptr<Packet>
802
EdcaTxopN::GetFragmentPacket
(
WifiMacHeader
*hdr)
803
{
804
NS_LOG_FUNCTION
(
this
<< hdr);
805
*hdr =
m_currentHdr
;
806
hdr->
SetFragmentNumber
(
m_fragmentNumber
);
807
uint32_t startOffset =
GetFragmentOffset
();
808
Ptr<Packet>
fragment;
809
if
(
IsLastFragment
())
810
{
811
hdr->
SetNoMoreFragments
();
812
}
813
else
814
{
815
hdr->
SetMoreFragments
();
816
}
817
fragment =
m_currentPacket
->
CreateFragment
(startOffset,
818
GetFragmentSize
());
819
return
fragment;
820
}
821
822
void
823
EdcaTxopN::SetAccessCategory
(
enum
AcIndex
ac)
824
{
825
NS_LOG_FUNCTION
(
this
<< static_cast<uint32_t> (ac));
826
m_ac
= ac;
827
}
828
829
Mac48Address
830
EdcaTxopN::MapSrcAddressForAggregation
(
const
WifiMacHeader
&hdr)
831
{
832
NS_LOG_FUNCTION
(
this
<< &hdr);
833
Mac48Address
retval;
834
if
(
m_typeOfStation
==
STA
||
m_typeOfStation
==
ADHOC_STA
)
835
{
836
retval = hdr.
GetAddr2
();
837
}
838
else
839
{
840
retval = hdr.
GetAddr3
();
841
}
842
return
retval;
843
}
844
845
Mac48Address
846
EdcaTxopN::MapDestAddressForAggregation
(
const
WifiMacHeader
&hdr)
847
{
848
NS_LOG_FUNCTION
(
this
<< &hdr);
849
Mac48Address
retval;
850
if
(
m_typeOfStation
==
AP
||
m_typeOfStation
==
ADHOC_STA
)
851
{
852
retval = hdr.
GetAddr1
();
853
}
854
else
855
{
856
retval = hdr.
GetAddr3
();
857
}
858
return
retval;
859
}
860
861
void
862
EdcaTxopN::SetMsduAggregator
(
Ptr<MsduAggregator>
aggr)
863
{
864
NS_LOG_FUNCTION
(
this
<< aggr);
865
m_aggregator
= aggr;
866
}
867
868
void
869
EdcaTxopN::PushFront
(
Ptr<const Packet>
packet,
const
WifiMacHeader
&hdr)
870
{
871
NS_LOG_FUNCTION
(
this
<< packet << &hdr);
872
WifiMacTrailer
fcs;
873
uint32_t fullPacketSize = hdr.
GetSerializedSize
() + packet->
GetSize
() + fcs.
GetSerializedSize
();
874
m_stationManager
->
PrepareForQueue
(hdr.
GetAddr1
(), &hdr,
875
packet, fullPacketSize);
876
m_queue
->
PushFront
(packet, hdr);
877
StartAccessIfNeeded
();
878
}
879
880
void
881
EdcaTxopN::GotAddBaResponse
(
const
MgtAddBaResponseHeader
*respHdr,
Mac48Address
recipient)
882
{
883
NS_LOG_FUNCTION
(
this
<< respHdr << recipient);
884
NS_LOG_DEBUG
(
"received ADDBA response from "
<< recipient);
885
uint8_t tid = respHdr->
GetTid
();
886
if
(
m_baManager
->
ExistsAgreementInState
(recipient, tid,
OriginatorBlockAckAgreement::PENDING
))
887
{
888
if
(respHdr->
GetStatusCode
().
IsSuccess
())
889
{
890
NS_LOG_DEBUG
(
"block ack agreement established with "
<< recipient);
891
m_baManager
->
UpdateAgreement
(respHdr, recipient);
892
}
893
else
894
{
895
NS_LOG_DEBUG
(
"discard ADDBA response"
<< recipient);
896
m_baManager
->
NotifyAgreementUnsuccessful
(recipient, tid);
897
}
898
}
899
RestartAccessIfNeeded
();
900
}
901
902
void
903
EdcaTxopN::GotDelBaFrame
(
const
MgtDelBaHeader
*delBaHdr,
Mac48Address
recipient)
904
{
905
NS_LOG_FUNCTION
(
this
<< delBaHdr << recipient);
906
NS_LOG_DEBUG
(
"received DELBA frame from="
<< recipient);
907
m_baManager
->
TearDownBlockAck
(recipient, delBaHdr->
GetTid
());
908
}
909
910
void
911
EdcaTxopN::GotBlockAck
(
const
CtrlBAckResponseHeader
*blockAck,
Mac48Address
recipient)
912
{
913
NS_LOG_FUNCTION
(
this
<< blockAck << recipient);
914
NS_LOG_DEBUG
(
"got block ack from="
<< recipient);
915
m_baManager
->
NotifyGotBlockAck
(blockAck, recipient);
916
m_currentPacket
= 0;
917
m_dcf
->
ResetCw
();
918
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
919
RestartAccessIfNeeded
();
920
}
921
922
void
923
EdcaTxopN::VerifyBlockAck
(
void
)
924
{
925
NS_LOG_FUNCTION
(
this
);
926
uint8_t tid =
m_currentHdr
.
GetQosTid
();
927
Mac48Address
recipient =
m_currentHdr
.
GetAddr1
();
928
uint16_t sequence =
m_currentHdr
.
GetSequenceNumber
();
929
if
(
m_baManager
->
ExistsAgreementInState
(recipient, tid,
OriginatorBlockAckAgreement::INACTIVE
))
930
{
931
m_baManager
->
SwitchToBlockAckIfNeeded
(recipient, tid, sequence);
932
}
933
if
(
m_baManager
->
ExistsAgreementInState
(recipient, tid,
OriginatorBlockAckAgreement::ESTABLISHED
))
934
{
935
m_currentHdr
.
SetQosAckPolicy
(
WifiMacHeader::BLOCK_ACK
);
936
}
937
}
938
939
void
940
EdcaTxopN::CompleteTx
(
void
)
941
{
942
NS_LOG_FUNCTION
(
this
);
943
if
(
m_currentHdr
.
IsQosData
() &&
m_currentHdr
.
IsQosBlockAck
())
944
{
945
if
(!
m_currentHdr
.
IsRetry
())
946
{
947
m_baManager
->
StorePacket
(
m_currentPacket
,
m_currentHdr
,
m_currentPacketTimestamp
);
948
}
949
m_baManager
->
NotifyMpduTransmission
(
m_currentHdr
.
GetAddr1
(),
m_currentHdr
.
GetQosTid
(),
950
m_txMiddle
->
GetNextSeqNumberByTidAndAddress
(
m_currentHdr
.
GetQosTid
(),
951
m_currentHdr
.
GetAddr1
()));
952
}
953
}
954
955
bool
956
EdcaTxopN::SetupBlockAckIfNeeded
()
957
{
958
NS_LOG_FUNCTION
(
this
);
959
uint8_t tid =
m_currentHdr
.
GetQosTid
();
960
Mac48Address
recipient =
m_currentHdr
.
GetAddr1
();
961
962
uint32_t packets =
m_queue
->
GetNPacketsByTidAndAddress
(tid,
WifiMacHeader::ADDR1
, recipient);
963
964
if
(packets >=
m_blockAckThreshold
)
965
{
966
/* Block ack setup */
967
uint16_t startingSequence =
m_txMiddle
->
GetNextSeqNumberByTidAndAddress
(tid, recipient);
968
SendAddBaRequest
(recipient, tid, startingSequence,
m_blockAckInactivityTimeout
,
true
);
969
return
true
;
970
}
971
return
false
;
972
}
973
974
void
975
EdcaTxopN::SendBlockAckRequest
(
const
struct
Bar
&bar)
976
{
977
NS_LOG_FUNCTION
(
this
<< &bar);
978
WifiMacHeader
hdr;
979
hdr.
SetType
(
WIFI_MAC_CTL_BACKREQ
);
980
hdr.
SetAddr1
(bar.
recipient
);
981
hdr.
SetAddr2
(
m_low
->
GetAddress
());
982
hdr.
SetAddr3
(
m_low
->
GetBssid
());
983
hdr.
SetDsNotTo
();
984
hdr.
SetDsNotFrom
();
985
hdr.
SetNoRetry
();
986
hdr.
SetNoMoreFragments
();
987
988
m_currentPacket
= bar.
bar
;
989
m_currentHdr
= hdr;
990
991
MacLowTransmissionParameters
params;
992
params.
DisableRts
();
993
params.
DisableNextData
();
994
params.
DisableOverrideDurationId
();
995
if
(bar.
immediate
)
996
{
997
if
(
m_blockAckType
==
BASIC_BLOCK_ACK
)
998
{
999
params.
EnableBasicBlockAck
();
1000
}
1001
else
if
(
m_blockAckType
==
COMPRESSED_BLOCK_ACK
)
1002
{
1003
params.
EnableCompressedBlockAck
();
1004
}
1005
else
if
(
m_blockAckType
==
MULTI_TID_BLOCK_ACK
)
1006
{
1007
NS_FATAL_ERROR
(
"Multi-tid block ack is not supported"
);
1008
}
1009
}
1010
else
1011
{
1012
//Delayed block ack
1013
params.
EnableAck
();
1014
}
1015
m_low
->
StartTransmission
(
m_currentPacket
, &
m_currentHdr
, params,
m_transmissionListener
);
1016
}
1017
1018
void
1019
EdcaTxopN::CompleteConfig
(
void
)
1020
{
1021
NS_LOG_FUNCTION
(
this
);
1022
m_baManager
->
SetTxMiddle
(
m_txMiddle
);
1023
m_low
->
RegisterBlockAckListenerForAc
(
m_ac
,
m_blockAckListener
);
1024
m_baManager
->
SetBlockAckInactivityCallback
(
MakeCallback
(&
EdcaTxopN::SendDelbaFrame
,
this
));
1025
}
1026
1027
void
1028
EdcaTxopN::SetBlockAckThreshold
(uint8_t threshold)
1029
{
1030
NS_LOG_FUNCTION
(
this
<< static_cast<uint32_t> (threshold));
1031
m_blockAckThreshold
= threshold;
1032
m_baManager
->
SetBlockAckThreshold
(threshold);
1033
}
1034
1035
void
1036
EdcaTxopN::SetBlockAckInactivityTimeout
(uint16_t
timeout
)
1037
{
1038
NS_LOG_FUNCTION
(
this
<< timeout);
1039
m_blockAckInactivityTimeout
=
timeout
;
1040
}
1041
1042
uint8_t
1043
EdcaTxopN::GetBlockAckThreshold
(
void
)
const
1044
{
1045
NS_LOG_FUNCTION
(
this
);
1046
return
m_blockAckThreshold
;
1047
}
1048
1049
void
1050
EdcaTxopN::SendAddBaRequest
(
Mac48Address
dest, uint8_t tid, uint16_t startSeq,
1051
uint16_t
timeout
,
bool
immediateBAck)
1052
{
1053
NS_LOG_FUNCTION
(
this
<< dest << static_cast<uint32_t> (tid) << startSeq << timeout << immediateBAck);
1054
NS_LOG_DEBUG
(
"sent ADDBA request to "
<< dest);
1055
WifiMacHeader
hdr;
1056
hdr.
SetAction
();
1057
hdr.
SetAddr1
(dest);
1058
hdr.
SetAddr2
(
m_low
->
GetAddress
());
1059
hdr.
SetAddr3
(
m_low
->
GetAddress
());
1060
hdr.
SetDsNotTo
();
1061
hdr.
SetDsNotFrom
();
1062
1063
WifiActionHeader
actionHdr;
1064
WifiActionHeader::ActionValue
action;
1065
action.
blockAck
=
WifiActionHeader::BLOCK_ACK_ADDBA_REQUEST
;
1066
actionHdr.
SetAction
(
WifiActionHeader::BLOCK_ACK
, action);
1067
1068
Ptr<Packet>
packet = Create<Packet> ();
1069
/*Setting ADDBARequest header*/
1070
MgtAddBaRequestHeader
reqHdr;
1071
reqHdr.
SetAmsduSupport
(
true
);
1072
if
(immediateBAck)
1073
{
1074
reqHdr.SetImmediateBlockAck ();
1075
}
1076
else
1077
{
1078
reqHdr.SetDelayedBlockAck ();
1079
}
1080
reqHdr.SetTid (tid);
1081
/* For now we don't use buffer size field in the ADDBA request frame. The recipient
1082
* will choose how many packets it can receive under block ack.
1083
*/
1084
reqHdr.SetBufferSize (0);
1085
reqHdr.SetTimeout (timeout);
1086
reqHdr.SetStartingSequence (startSeq);
1087
1088
m_baManager
->
CreateAgreement
(&reqHdr, dest);
1089
1090
packet->
AddHeader
(reqHdr);
1091
packet->
AddHeader
(actionHdr);
1092
1093
m_currentPacket
= packet;
1094
m_currentHdr
= hdr;
1095
1096
uint16_t sequence =
m_txMiddle
->
GetNextSequenceNumberfor
(&
m_currentHdr
);
1097
m_currentHdr
.
SetSequenceNumber
(sequence);
1098
m_currentHdr
.
SetFragmentNumber
(0);
1099
m_currentHdr
.
SetNoMoreFragments
();
1100
m_currentHdr
.
SetNoRetry
();
1101
1102
MacLowTransmissionParameters
params;
1103
params.
EnableAck
();
1104
params.
DisableRts
();
1105
params.
DisableNextData
();
1106
params.
DisableOverrideDurationId
();
1107
1108
m_low
->
StartTransmission
(
m_currentPacket
, &
m_currentHdr
, params,
1109
m_transmissionListener
);
1110
}
1111
1112
void
1113
EdcaTxopN::SendDelbaFrame
(
Mac48Address
addr, uint8_t tid,
bool
byOriginator)
1114
{
1115
NS_LOG_FUNCTION
(
this
<< addr << static_cast<uint32_t> (tid) << byOriginator);
1116
WifiMacHeader
hdr;
1117
hdr.
SetAction
();
1118
hdr.
SetAddr1
(addr);
1119
hdr.
SetAddr2
(
m_low
->
GetAddress
());
1120
hdr.
SetAddr3
(
m_low
->
GetAddress
());
1121
hdr.
SetDsNotTo
();
1122
hdr.
SetDsNotFrom
();
1123
1124
MgtDelBaHeader
delbaHdr;
1125
delbaHdr.
SetTid
(tid);
1126
if
(byOriginator)
1127
{
1128
delbaHdr.
SetByOriginator
();
1129
}
1130
else
1131
{
1132
delbaHdr.
SetByRecipient
();
1133
}
1134
1135
WifiActionHeader
actionHdr;
1136
WifiActionHeader::ActionValue
action;
1137
action.
blockAck
=
WifiActionHeader::BLOCK_ACK_DELBA
;
1138
actionHdr.
SetAction
(
WifiActionHeader::BLOCK_ACK
, action);
1139
1140
Ptr<Packet>
packet = Create<Packet> ();
1141
packet->
AddHeader
(delbaHdr);
1142
packet->
AddHeader
(actionHdr);
1143
1144
PushFront
(packet, hdr);
1145
}
1146
1147
int64_t
1148
EdcaTxopN::AssignStreams
(int64_t stream)
1149
{
1150
NS_LOG_FUNCTION
(
this
<< stream);
1151
m_rng
->
AssignStreams
(stream);
1152
return
1;
1153
}
1154
1155
void
1156
EdcaTxopN::DoInitialize
()
1157
{
1158
NS_LOG_FUNCTION
(
this
);
1159
m_dcf
->
ResetCw
();
1160
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
1161
ns3::Dcf::DoInitialize
();
1162
}
1163
}
// namespace ns3
src
wifi
model
edca-txop-n.cc
Generated on Tue May 14 2013 11:08:35 for ns-3 by
1.8.1.2