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
dca-txop.cc
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2005 INRIA
4
*
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License version 2 as
7
* published by the Free Software Foundation;
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
*
18
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19
*/
20
21
#include "ns3/assert.h"
22
#include "ns3/packet.h"
23
#include "ns3/log.h"
24
#include "ns3/simulator.h"
25
#include "ns3/node.h"
26
#include "ns3/uinteger.h"
27
#include "ns3/pointer.h"
28
29
#include "
dca-txop.h
"
30
#include "
dcf-manager.h
"
31
#include "
mac-low.h
"
32
#include "
wifi-mac-queue.h
"
33
#include "
mac-tx-middle.h
"
34
#include "
wifi-mac-trailer.h
"
35
#include "
wifi-mac.h
"
36
#include "
random-stream.h
"
37
38
NS_LOG_COMPONENT_DEFINE
(
"DcaTxop"
);
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
DcaTxop::Dcf
:
public
DcfState
46
{
47
public
:
48
Dcf
(
DcaTxop
* 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
DcaTxop
*
m_txop
;
70
};
71
72
class
DcaTxop::TransmissionListener
:
public
MacLowTransmissionListener
73
{
74
public
:
75
TransmissionListener
(
DcaTxop
* 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
StartNext
(
void
)
99
{
100
m_txop
->
StartNext
();
101
}
102
virtual
void
Cancel
(
void
)
103
{
104
m_txop
->
Cancel
();
105
}
106
107
private
:
108
DcaTxop
*
m_txop
;
109
};
110
111
NS_OBJECT_ENSURE_REGISTERED
(
DcaTxop
);
112
113
TypeId
114
DcaTxop::GetTypeId
(
void
)
115
{
116
static
TypeId
tid =
TypeId
(
"ns3::DcaTxop"
)
117
.
SetParent
(
ns3::Dcf::GetTypeId
())
118
.
AddConstructor
<
DcaTxop
> ()
119
.AddAttribute (
"Queue"
,
"The WifiMacQueue object"
,
120
PointerValue
(),
121
MakePointerAccessor (&
DcaTxop::GetQueue
),
122
MakePointerChecker<WifiMacQueue> ())
123
;
124
return
tid;
125
}
126
127
DcaTxop::DcaTxop
()
128
: m_manager (0),
129
m_currentPacket (0)
130
{
131
NS_LOG_FUNCTION
(
this
);
132
m_transmissionListener
=
new
DcaTxop::TransmissionListener
(
this
);
133
m_dcf
=
new
DcaTxop::Dcf
(
this
);
134
m_queue
= CreateObject<WifiMacQueue> ();
135
m_rng
=
new
RealRandomStream
();
136
m_txMiddle
=
new
MacTxMiddle
();
137
}
138
139
DcaTxop::~DcaTxop
()
140
{
141
NS_LOG_FUNCTION
(
this
);
142
}
143
144
void
145
DcaTxop::DoDispose
(
void
)
146
{
147
NS_LOG_FUNCTION
(
this
);
148
m_queue
= 0;
149
m_low
= 0;
150
m_stationManager
= 0;
151
delete
m_transmissionListener
;
152
delete
m_dcf
;
153
delete
m_rng
;
154
delete
m_txMiddle
;
155
m_transmissionListener
= 0;
156
m_dcf
= 0;
157
m_rng
= 0;
158
m_txMiddle
= 0;
159
}
160
161
void
162
DcaTxop::SetManager
(
DcfManager
*manager)
163
{
164
NS_LOG_FUNCTION
(
this
<< manager);
165
m_manager
= manager;
166
m_manager
->
Add
(
m_dcf
);
167
}
168
169
void
170
DcaTxop::SetLow
(
Ptr<MacLow>
low)
171
{
172
NS_LOG_FUNCTION
(
this
<< low);
173
m_low
= low;
174
}
175
void
176
DcaTxop::SetWifiRemoteStationManager
(
Ptr<WifiRemoteStationManager>
remoteManager)
177
{
178
NS_LOG_FUNCTION
(
this
<< remoteManager);
179
m_stationManager
= remoteManager;
180
}
181
void
182
DcaTxop::SetTxOkCallback
(
TxOk
callback)
183
{
184
m_txOkCallback
= callback;
185
}
186
void
187
DcaTxop::SetTxFailedCallback
(
TxFailed
callback)
188
{
189
m_txFailedCallback
= callback;
190
}
191
192
Ptr<WifiMacQueue >
193
DcaTxop::GetQueue
()
const
194
{
195
NS_LOG_FUNCTION
(
this
);
196
return
m_queue
;
197
}
198
199
void
200
DcaTxop::SetMinCw
(uint32_t minCw)
201
{
202
NS_LOG_FUNCTION
(
this
<< minCw);
203
m_dcf
->
SetCwMin
(minCw);
204
}
205
void
206
DcaTxop::SetMaxCw
(uint32_t maxCw)
207
{
208
NS_LOG_FUNCTION
(
this
<< maxCw);
209
m_dcf
->
SetCwMax
(maxCw);
210
}
211
void
212
DcaTxop::SetAifsn
(uint32_t aifsn)
213
{
214
NS_LOG_FUNCTION
(
this
<< aifsn);
215
m_dcf
->
SetAifsn
(aifsn);
216
}
217
uint32_t
218
DcaTxop::GetMinCw
(
void
)
const
219
{
220
return
m_dcf
->
GetCwMin
();
221
}
222
uint32_t
223
DcaTxop::GetMaxCw
(
void
)
const
224
{
225
return
m_dcf
->
GetCwMax
();
226
}
227
uint32_t
228
DcaTxop::GetAifsn
(
void
)
const
229
{
230
return
m_dcf
->
GetAifsn
();
231
}
232
233
void
234
DcaTxop::Queue
(
Ptr<const Packet>
packet,
const
WifiMacHeader
&hdr)
235
{
236
NS_LOG_FUNCTION
(
this
<< packet << &hdr);
237
WifiMacTrailer
fcs;
238
uint32_t fullPacketSize = hdr.
GetSerializedSize
() + packet->
GetSize
() + fcs.
GetSerializedSize
();
239
m_stationManager
->
PrepareForQueue
(hdr.
GetAddr1
(), &hdr,
240
packet, fullPacketSize);
241
m_queue
->
Enqueue
(packet, hdr);
242
StartAccessIfNeeded
();
243
}
244
245
int64_t
246
DcaTxop::AssignStreams
(int64_t stream)
247
{
248
NS_LOG_FUNCTION
(
this
<< stream);
249
m_rng
->
AssignStreams
(stream);
250
return
1;
251
}
252
253
void
254
DcaTxop::RestartAccessIfNeeded
(
void
)
255
{
256
NS_LOG_FUNCTION
(
this
);
257
if
((
m_currentPacket
!= 0
258
|| !
m_queue
->
IsEmpty
())
259
&& !
m_dcf
->
IsAccessRequested
())
260
{
261
m_manager
->
RequestAccess
(
m_dcf
);
262
}
263
}
264
265
void
266
DcaTxop::StartAccessIfNeeded
(
void
)
267
{
268
NS_LOG_FUNCTION
(
this
);
269
if
(
m_currentPacket
== 0
270
&& !
m_queue
->
IsEmpty
()
271
&& !
m_dcf
->
IsAccessRequested
())
272
{
273
m_manager
->
RequestAccess
(
m_dcf
);
274
}
275
}
276
277
278
Ptr<MacLow>
279
DcaTxop::Low
(
void
)
280
{
281
return
m_low
;
282
}
283
284
bool
285
DcaTxop::NeedRts
(
Ptr<const Packet>
packet,
const
WifiMacHeader
*header)
286
{
287
return
m_stationManager
->
NeedRts
(header->
GetAddr1
(), header,
288
packet);
289
}
290
291
void
292
DcaTxop::DoStart
()
293
{
294
m_dcf
->
ResetCw
();
295
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
296
ns3::Dcf::DoStart
();
297
}
298
bool
299
DcaTxop::NeedRtsRetransmission
(
void
)
300
{
301
return
m_stationManager
->
NeedRtsRetransmission
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
302
m_currentPacket
);
303
}
304
305
bool
306
DcaTxop::NeedDataRetransmission
(
void
)
307
{
308
return
m_stationManager
->
NeedDataRetransmission
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
309
m_currentPacket
);
310
}
311
bool
312
DcaTxop::NeedFragmentation
(
void
)
313
{
314
return
m_stationManager
->
NeedFragmentation
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
315
m_currentPacket
);
316
}
317
318
void
319
DcaTxop::NextFragment
(
void
)
320
{
321
m_fragmentNumber
++;
322
}
323
324
uint32_t
325
DcaTxop::GetFragmentSize
(
void
)
326
{
327
return
m_stationManager
->
GetFragmentSize
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
328
m_currentPacket
,
m_fragmentNumber
);
329
}
330
bool
331
DcaTxop::IsLastFragment
(
void
)
332
{
333
return
m_stationManager
->
IsLastFragment
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
334
m_currentPacket
,
m_fragmentNumber
);
335
}
336
337
uint32_t
338
DcaTxop::GetNextFragmentSize
(
void
)
339
{
340
return
m_stationManager
->
GetFragmentSize
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
341
m_currentPacket
,
m_fragmentNumber
+ 1);
342
}
343
344
uint32_t
345
DcaTxop::GetFragmentOffset
(
void
)
346
{
347
return
m_stationManager
->
GetFragmentOffset
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
,
348
m_currentPacket
,
m_fragmentNumber
);
349
}
350
351
Ptr<Packet>
352
DcaTxop::GetFragmentPacket
(
WifiMacHeader
*hdr)
353
{
354
*hdr =
m_currentHdr
;
355
hdr->
SetFragmentNumber
(
m_fragmentNumber
);
356
uint32_t startOffset =
GetFragmentOffset
();
357
Ptr<Packet>
fragment;
358
if
(
IsLastFragment
())
359
{
360
hdr->
SetNoMoreFragments
();
361
}
362
else
363
{
364
hdr->
SetMoreFragments
();
365
}
366
fragment =
m_currentPacket
->
CreateFragment
(startOffset,
367
GetFragmentSize
());
368
return
fragment;
369
}
370
371
bool
372
DcaTxop::NeedsAccess
(
void
)
const
373
{
374
return
!
m_queue
->
IsEmpty
() ||
m_currentPacket
!= 0;
375
}
376
void
377
DcaTxop::NotifyAccessGranted
(
void
)
378
{
379
NS_LOG_FUNCTION
(
this
);
380
if
(
m_currentPacket
== 0)
381
{
382
if
(
m_queue
->
IsEmpty
())
383
{
384
NS_LOG_DEBUG
(
"queue empty"
);
385
return
;
386
}
387
m_currentPacket
=
m_queue
->
Dequeue
(&
m_currentHdr
);
388
NS_ASSERT
(
m_currentPacket
!= 0);
389
uint16_t sequence =
m_txMiddle
->
GetNextSequenceNumberfor
(&
m_currentHdr
);
390
m_currentHdr
.
SetSequenceNumber
(sequence);
391
m_currentHdr
.
SetFragmentNumber
(0);
392
m_currentHdr
.
SetNoMoreFragments
();
393
m_currentHdr
.
SetNoRetry
();
394
m_fragmentNumber
= 0;
395
NS_LOG_DEBUG
(
"dequeued size="
<<
m_currentPacket
->
GetSize
() <<
396
", to="
<<
m_currentHdr
.
GetAddr1
() <<
397
", seq="
<<
m_currentHdr
.
GetSequenceControl
());
398
}
399
MacLowTransmissionParameters
params;
400
params.
DisableOverrideDurationId
();
401
if
(
m_currentHdr
.
GetAddr1
().
IsGroup
())
402
{
403
params.
DisableRts
();
404
params.
DisableAck
();
405
params.
DisableNextData
();
406
Low
()->
StartTransmission
(
m_currentPacket
,
407
&
m_currentHdr
,
408
params,
409
m_transmissionListener
);
410
m_currentPacket
= 0;
411
m_dcf
->
ResetCw
();
412
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
413
StartAccessIfNeeded
();
414
NS_LOG_DEBUG
(
"tx broadcast"
);
415
}
416
else
417
{
418
params.
EnableAck
();
419
420
if
(
NeedFragmentation
())
421
{
422
WifiMacHeader
hdr;
423
Ptr<Packet>
fragment =
GetFragmentPacket
(&hdr);
424
if
(
NeedRts
(fragment, &hdr))
425
{
426
params.
EnableRts
();
427
}
428
else
429
{
430
params.
DisableRts
();
431
}
432
if
(
IsLastFragment
())
433
{
434
NS_LOG_DEBUG
(
"fragmenting last fragment size="
<< fragment->
GetSize
());
435
params.
DisableNextData
();
436
}
437
else
438
{
439
NS_LOG_DEBUG
(
"fragmenting size="
<< fragment->
GetSize
());
440
params.
EnableNextData
(
GetNextFragmentSize
());
441
}
442
Low
()->
StartTransmission
(fragment, &hdr, params,
443
m_transmissionListener
);
444
}
445
else
446
{
447
if
(
NeedRts
(
m_currentPacket
, &
m_currentHdr
))
448
{
449
params.
EnableRts
();
450
NS_LOG_DEBUG
(
"tx unicast rts"
);
451
}
452
else
453
{
454
params.
DisableRts
();
455
NS_LOG_DEBUG
(
"tx unicast"
);
456
}
457
params.
DisableNextData
();
458
Low
()->
StartTransmission
(
m_currentPacket
, &
m_currentHdr
,
459
params,
m_transmissionListener
);
460
}
461
}
462
}
463
464
void
465
DcaTxop::NotifyInternalCollision
(
void
)
466
{
467
NS_LOG_FUNCTION
(
this
);
468
NotifyCollision
();
469
}
470
void
471
DcaTxop::NotifyCollision
(
void
)
472
{
473
NS_LOG_FUNCTION
(
this
);
474
NS_LOG_DEBUG
(
"collision"
);
475
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
476
RestartAccessIfNeeded
();
477
}
478
479
void
480
DcaTxop::NotifyChannelSwitching
(
void
)
481
{
482
m_queue
->
Flush
();
483
m_currentPacket
= 0;
484
}
485
486
void
487
DcaTxop::GotCts
(
double
snr,
WifiMode
txMode)
488
{
489
NS_LOG_FUNCTION
(
this
<< snr << txMode);
490
NS_LOG_DEBUG
(
"got cts"
);
491
}
492
void
493
DcaTxop::MissedCts
(
void
)
494
{
495
NS_LOG_FUNCTION
(
this
);
496
NS_LOG_DEBUG
(
"missed cts"
);
497
if
(!
NeedRtsRetransmission
())
498
{
499
NS_LOG_DEBUG
(
"Cts Fail"
);
500
m_stationManager
->
ReportFinalRtsFailed
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
);
501
if
(!
m_txFailedCallback
.
IsNull
())
502
{
503
m_txFailedCallback
(
m_currentHdr
);
504
}
505
// to reset the dcf.
506
m_currentPacket
= 0;
507
m_dcf
->
ResetCw
();
508
}
509
else
510
{
511
m_dcf
->
UpdateFailedCw
();
512
}
513
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
514
RestartAccessIfNeeded
();
515
}
516
void
517
DcaTxop::GotAck
(
double
snr,
WifiMode
txMode)
518
{
519
NS_LOG_FUNCTION
(
this
<< snr << txMode);
520
if
(!
NeedFragmentation
()
521
||
IsLastFragment
())
522
{
523
NS_LOG_DEBUG
(
"got ack. tx done."
);
524
if
(!
m_txOkCallback
.
IsNull
())
525
{
526
m_txOkCallback
(
m_currentHdr
);
527
}
528
529
/* we are not fragmenting or we are done fragmenting
530
* so we can get rid of that packet now.
531
*/
532
m_currentPacket
= 0;
533
m_dcf
->
ResetCw
();
534
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
535
RestartAccessIfNeeded
();
536
}
537
else
538
{
539
NS_LOG_DEBUG
(
"got ack. tx not done, size="
<<
m_currentPacket
->
GetSize
());
540
}
541
}
542
void
543
DcaTxop::MissedAck
(
void
)
544
{
545
NS_LOG_FUNCTION
(
this
);
546
NS_LOG_DEBUG
(
"missed ack"
);
547
if
(!
NeedDataRetransmission
())
548
{
549
NS_LOG_DEBUG
(
"Ack Fail"
);
550
m_stationManager
->
ReportFinalDataFailed
(
m_currentHdr
.
GetAddr1
(), &
m_currentHdr
);
551
if
(!
m_txFailedCallback
.
IsNull
())
552
{
553
m_txFailedCallback
(
m_currentHdr
);
554
}
555
// to reset the dcf.
556
m_currentPacket
= 0;
557
m_dcf
->
ResetCw
();
558
}
559
else
560
{
561
NS_LOG_DEBUG
(
"Retransmit"
);
562
m_currentHdr
.
SetRetry
();
563
m_dcf
->
UpdateFailedCw
();
564
}
565
m_dcf
->
StartBackoffNow
(
m_rng
->
GetNext
(0,
m_dcf
->
GetCw
()));
566
RestartAccessIfNeeded
();
567
}
568
void
569
DcaTxop::StartNext
(
void
)
570
{
571
NS_LOG_FUNCTION
(
this
);
572
NS_LOG_DEBUG
(
"start next packet fragment"
);
573
/* this callback is used only for fragments. */
574
NextFragment
();
575
WifiMacHeader
hdr;
576
Ptr<Packet>
fragment =
GetFragmentPacket
(&hdr);
577
MacLowTransmissionParameters
params;
578
params.
EnableAck
();
579
params.
DisableRts
();
580
params.
DisableOverrideDurationId
();
581
if
(
IsLastFragment
())
582
{
583
params.
DisableNextData
();
584
}
585
else
586
{
587
params.
EnableNextData
(
GetNextFragmentSize
());
588
}
589
Low
()->
StartTransmission
(fragment, &hdr, params,
m_transmissionListener
);
590
}
591
592
void
593
DcaTxop::Cancel
(
void
)
594
{
595
NS_LOG_FUNCTION
(
this
);
596
NS_LOG_DEBUG
(
"transmission cancelled"
);
622
}
623
624
}
// namespace ns3
src
wifi
model
dca-txop.cc
Generated on Tue Oct 9 2012 16:45:48 for ns-3 by
1.8.1.2