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
dcf-manager.cc
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2005,2006 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/log.h"
23
#include "ns3/simulator.h"
24
#include <cmath>
25
26
#include "
dcf-manager.h
"
27
#include "
wifi-phy.h
"
28
#include "
wifi-mac.h
"
29
#include "
mac-low.h
"
30
31
NS_LOG_COMPONENT_DEFINE
(
"DcfManager"
);
32
33
#define MY_DEBUG(x) \
34
NS_LOG_DEBUG (Simulator::Now () << " " << this << " " << x)
35
36
namespace
ns3 {
37
38
/****************************************************************
39
* Implement the DCF state holder
40
****************************************************************/
41
42
DcfState::DcfState
()
43
: m_backoffSlots (0),
44
m_backoffStart (
Seconds
(0.0)),
45
m_cwMin (0),
46
m_cwMax (0),
47
m_cw (0),
48
m_accessRequested (false)
49
{
50
}
51
52
DcfState::~DcfState
()
53
{
54
}
55
56
void
57
DcfState::SetAifsn
(uint32_t aifsn)
58
{
59
m_aifsn
= aifsn;
60
}
61
void
62
DcfState::SetCwMin
(uint32_t minCw)
63
{
64
m_cwMin
= minCw;
65
ResetCw
();
66
}
67
void
68
DcfState::SetCwMax
(uint32_t maxCw)
69
{
70
m_cwMax
= maxCw;
71
ResetCw
();
72
}
73
uint32_t
74
DcfState::GetAifsn
(
void
)
const
75
{
76
return
m_aifsn
;
77
}
78
uint32_t
79
DcfState::GetCwMin
(
void
)
const
80
{
81
return
m_cwMin
;
82
}
83
uint32_t
84
DcfState::GetCwMax
(
void
)
const
85
{
86
return
m_cwMax
;
87
}
88
89
void
90
DcfState::ResetCw
(
void
)
91
{
92
m_cw
=
m_cwMin
;
93
}
94
void
95
DcfState::UpdateFailedCw
(
void
)
96
{
97
// see 802.11-2007, section 9.9.1.5
98
m_cw
= std::min ( 2 * (
m_cw
+ 1) - 1,
m_cwMax
);
99
}
100
void
101
DcfState::UpdateBackoffSlotsNow
(uint32_t nSlots,
Time
backoffUpdateBound)
102
{
103
m_backoffSlots
-= nSlots;
104
m_backoffStart
= backoffUpdateBound;
105
MY_DEBUG
(
"update slots="
<< nSlots <<
" slots, backoff="
<<
m_backoffSlots
);
106
}
107
108
void
109
DcfState::StartBackoffNow
(uint32_t nSlots)
110
{
111
NS_ASSERT
(
m_backoffSlots
== 0);
112
MY_DEBUG
(
"start backoff="
<< nSlots <<
" slots"
);
113
m_backoffSlots
= nSlots;
114
m_backoffStart
=
Simulator::Now
();
115
}
116
117
uint32_t
118
DcfState::GetCw
(
void
)
const
119
{
120
return
m_cw
;
121
}
122
uint32_t
123
DcfState::GetBackoffSlots
(
void
)
const
124
{
125
return
m_backoffSlots
;
126
}
127
Time
128
DcfState::GetBackoffStart
(
void
)
const
129
{
130
return
m_backoffStart
;
131
}
132
bool
133
DcfState::IsAccessRequested
(
void
)
const
134
{
135
return
m_accessRequested
;
136
}
137
void
138
DcfState::NotifyAccessRequested
(
void
)
139
{
140
m_accessRequested
=
true
;
141
}
142
void
143
DcfState::NotifyAccessGranted
(
void
)
144
{
145
NS_ASSERT
(
m_accessRequested
);
146
m_accessRequested
=
false
;
147
DoNotifyAccessGranted
();
148
}
149
void
150
DcfState::NotifyCollision
(
void
)
151
{
152
DoNotifyCollision
();
153
}
154
void
155
DcfState::NotifyInternalCollision
(
void
)
156
{
157
DoNotifyInternalCollision
();
158
}
159
void
160
DcfState::NotifyChannelSwitching
(
void
)
161
{
162
DoNotifyChannelSwitching
();
163
}
164
165
166
/***************************************************************
167
* Listener for Nav events. Forwards to DcfManager
168
***************************************************************/
169
170
class
LowDcfListener
:
public
ns3::MacLowDcfListener
171
{
172
public
:
173
LowDcfListener
(
ns3::DcfManager
*dcf)
174
:
m_dcf
(dcf)
175
{
176
}
177
virtual
~LowDcfListener
()
178
{
179
}
180
virtual
void
NavStart
(
Time
duration)
181
{
182
m_dcf
->
NotifyNavStartNow
(duration);
183
}
184
virtual
void
NavReset
(
Time
duration)
185
{
186
m_dcf
->
NotifyNavResetNow
(duration);
187
}
188
virtual
void
AckTimeoutStart
(
Time
duration)
189
{
190
m_dcf
->
NotifyAckTimeoutStartNow
(duration);
191
}
192
virtual
void
AckTimeoutReset
()
193
{
194
m_dcf
->
NotifyAckTimeoutResetNow
();
195
}
196
virtual
void
CtsTimeoutStart
(
Time
duration)
197
{
198
m_dcf
->
NotifyCtsTimeoutStartNow
(duration);
199
}
200
virtual
void
CtsTimeoutReset
()
201
{
202
m_dcf
->
NotifyCtsTimeoutResetNow
();
203
}
204
private
:
205
ns3::DcfManager
*
m_dcf
;
206
};
207
208
/***************************************************************
209
* Listener for PHY events. Forwards to DcfManager
210
***************************************************************/
211
212
class
PhyListener
:
public
ns3::WifiPhyListener
213
{
214
public
:
215
PhyListener
(
ns3::DcfManager
*dcf)
216
:
m_dcf
(dcf)
217
{
218
}
219
virtual
~PhyListener
()
220
{
221
}
222
virtual
void
NotifyRxStart
(
Time
duration)
223
{
224
m_dcf
->
NotifyRxStartNow
(duration);
225
}
226
virtual
void
NotifyRxEndOk
(
void
)
227
{
228
m_dcf
->
NotifyRxEndOkNow
();
229
}
230
virtual
void
NotifyRxEndError
(
void
)
231
{
232
m_dcf
->
NotifyRxEndErrorNow
();
233
}
234
virtual
void
NotifyTxStart
(
Time
duration)
235
{
236
m_dcf
->
NotifyTxStartNow
(duration);
237
}
238
virtual
void
NotifyMaybeCcaBusyStart
(
Time
duration)
239
{
240
m_dcf
->
NotifyMaybeCcaBusyStartNow
(duration);
241
}
242
virtual
void
NotifySwitchingStart
(
Time
duration)
243
{
244
m_dcf
->
NotifySwitchingStartNow
(duration);
245
}
246
private
:
247
ns3::DcfManager
*
m_dcf
;
248
};
249
250
/****************************************************************
251
* Implement the DCF manager of all DCF state holders
252
****************************************************************/
253
254
DcfManager::DcfManager
()
255
: m_lastAckTimeoutEnd (
MicroSeconds
(0)),
256
m_lastCtsTimeoutEnd (
MicroSeconds
(0)),
257
m_lastNavStart (
MicroSeconds
(0)),
258
m_lastNavDuration (
MicroSeconds
(0)),
259
m_lastRxStart (
MicroSeconds
(0)),
260
m_lastRxDuration (
MicroSeconds
(0)),
261
m_lastRxReceivedOk (true),
262
m_lastRxEnd (
MicroSeconds
(0)),
263
m_lastTxStart (
MicroSeconds
(0)),
264
m_lastTxDuration (
MicroSeconds
(0)),
265
m_lastBusyStart (
MicroSeconds
(0)),
266
m_lastBusyDuration (
MicroSeconds
(0)),
267
m_lastSwitchingStart (
MicroSeconds
(0)),
268
m_lastSwitchingDuration (
MicroSeconds
(0)),
269
m_rxing (false),
270
m_slotTimeUs (0),
271
m_sifs (
Seconds
(0.0)),
272
m_phyListener (0),
273
m_lowListener (0)
274
{
275
}
276
277
DcfManager::~DcfManager
()
278
{
279
delete
m_phyListener
;
280
delete
m_lowListener
;
281
m_phyListener
= 0;
282
m_lowListener
= 0;
283
}
284
285
void
286
DcfManager::SetupPhyListener
(
Ptr<WifiPhy>
phy)
287
{
288
m_phyListener
=
new
PhyListener
(
this
);
289
phy->
RegisterListener
(
m_phyListener
);
290
}
291
void
292
DcfManager::SetupLowListener
(
Ptr<MacLow>
low)
293
{
294
m_lowListener
=
new
LowDcfListener
(
this
);
295
low->
RegisterDcfListener
(
m_lowListener
);
296
}
297
298
void
299
DcfManager::SetSlot
(
Time
slotTime)
300
{
301
m_slotTimeUs
= slotTime.
GetMicroSeconds
();
302
}
303
void
304
DcfManager::SetSifs
(
Time
sifs)
305
{
306
m_sifs
= sifs;
307
}
308
void
309
DcfManager::SetEifsNoDifs
(
Time
eifsNoDifs)
310
{
311
m_eifsNoDifs
= eifsNoDifs;
312
}
313
Time
314
DcfManager::GetEifsNoDifs
()
const
315
{
316
return
m_eifsNoDifs
;
317
}
318
319
void
320
DcfManager::Add
(
DcfState
*dcf)
321
{
322
m_states
.push_back (dcf);
323
}
324
325
Time
326
DcfManager::MostRecent
(
Time
a,
Time
b)
const
327
{
328
return
Max
(a, b);
329
}
330
Time
331
DcfManager::MostRecent
(
Time
a,
Time
b,
Time
c)
const
332
{
333
Time
retval;
334
retval =
Max
(a, b);
335
retval =
Max
(retval, c);
336
return
retval;
337
}
338
Time
339
DcfManager::MostRecent
(
Time
a,
Time
b,
Time
c,
Time
d)
const
340
{
341
Time
e =
Max
(a, b);
342
Time
f =
Max
(c, d);
343
Time
retval =
Max
(e, f);
344
return
retval;
345
}
346
Time
347
DcfManager::MostRecent
(
Time
a,
Time
b,
Time
c,
Time
d,
Time
e,
Time
f)
const
348
{
349
Time
g =
Max
(a, b);
350
Time
h =
Max
(c, d);
351
Time
i =
Max
(e, f);
352
Time
k =
Max
(g, h);
353
Time
retval =
Max
(k, i);
354
return
retval;
355
}
356
357
Time
358
DcfManager::MostRecent
(
Time
a,
Time
b,
Time
c,
Time
d,
Time
e,
Time
f,
Time
g)
const
359
{
360
Time
h =
Max
(a, b);
361
Time
i =
Max
(c, d);
362
Time
j =
Max
(e, f);
363
Time
k =
Max
(h, i);
364
Time
l =
Max
(j, g);
365
Time
retval =
Max
(k, l);
366
return
retval;
367
}
368
369
bool
370
DcfManager::IsBusy
(
void
)
const
371
{
372
// PHY busy
373
if
(
m_rxing
)
374
{
375
return
true
;
376
}
377
Time
lastTxEnd =
m_lastTxStart
+
m_lastTxDuration
;
378
if
(lastTxEnd >
Simulator::Now
())
379
{
380
return
true
;
381
}
382
// NAV busy
383
Time
lastNavEnd =
m_lastNavStart
+
m_lastNavDuration
;
384
if
(lastNavEnd >
Simulator::Now
())
385
{
386
return
true
;
387
}
388
return
false
;
389
}
390
391
392
void
393
DcfManager::RequestAccess
(
DcfState
*state)
394
{
395
UpdateBackoff
();
396
NS_ASSERT
(!state->
IsAccessRequested
());
397
state->
NotifyAccessRequested
();
402
if
(state->
GetBackoffSlots
() == 0
403
&&
IsBusy
())
404
{
405
MY_DEBUG
(
"medium is busy: collision"
);
406
/* someone else has accessed the medium.
407
* generate a backoff.
408
*/
409
state->
NotifyCollision
();
410
}
411
DoGrantAccess
();
412
DoRestartAccessTimeoutIfNeeded
();
413
}
414
415
void
416
DcfManager::DoGrantAccess
(
void
)
417
{
418
uint32_t k = 0;
419
for
(States::const_iterator i =
m_states
.begin (); i !=
m_states
.end (); k++)
420
{
421
DcfState
*state = *i;
422
if
(state->
IsAccessRequested
()
423
&&
GetBackoffEndFor
(state) <=
Simulator::Now
() )
424
{
429
MY_DEBUG
(
"dcf "
<< k <<
" needs access. backoff expired. access granted. slots="
<< state->
GetBackoffSlots
());
430
i++;
// go to the next item in the list.
431
k++;
432
std::vector<DcfState *> internalCollisionStates;
433
for
(States::const_iterator j = i; j !=
m_states
.end (); j++, k++)
434
{
435
DcfState
*otherState = *j;
436
if
(otherState->
IsAccessRequested
()
437
&&
GetBackoffEndFor
(otherState) <=
Simulator::Now
())
438
{
439
MY_DEBUG
(
"dcf "
<< k <<
" needs access. backoff expired. internal collision. slots="
<<
440
otherState->
GetBackoffSlots
());
446
internalCollisionStates.push_back (otherState);
447
}
448
}
449
457
state->
NotifyAccessGranted
();
458
for
(std::vector<DcfState *>::const_iterator k = internalCollisionStates.begin ();
459
k != internalCollisionStates.end (); k++)
460
{
461
(*k)->NotifyInternalCollision ();
462
}
463
break
;
464
}
465
i++;
466
}
467
}
468
469
void
470
DcfManager::AccessTimeout
(
void
)
471
{
472
UpdateBackoff
();
473
DoGrantAccess
();
474
DoRestartAccessTimeoutIfNeeded
();
475
}
476
477
Time
478
DcfManager::GetAccessGrantStart
(
void
)
const
479
{
480
Time
rxAccessStart;
481
if
(!
m_rxing
)
482
{
483
rxAccessStart =
m_lastRxEnd
+
m_sifs
;
484
if
(!
m_lastRxReceivedOk
)
485
{
486
rxAccessStart +=
m_eifsNoDifs
;
487
}
488
}
489
else
490
{
491
rxAccessStart =
m_lastRxStart
+
m_lastRxDuration
+
m_sifs
;
492
}
493
Time
busyAccessStart =
m_lastBusyStart
+
m_lastBusyDuration
+
m_sifs
;
494
Time
txAccessStart =
m_lastTxStart
+
m_lastTxDuration
+
m_sifs
;
495
Time
navAccessStart =
m_lastNavStart
+
m_lastNavDuration
+
m_sifs
;
496
Time
ackTimeoutAccessStart =
m_lastAckTimeoutEnd
+
m_sifs
;
497
Time
ctsTimeoutAccessStart =
m_lastCtsTimeoutEnd
+
m_sifs
;
498
Time
switchingAccessStart =
m_lastSwitchingStart
+
m_lastSwitchingDuration
+
m_sifs
;
499
Time
accessGrantedStart =
MostRecent
(rxAccessStart,
500
busyAccessStart,
501
txAccessStart,
502
navAccessStart,
503
ackTimeoutAccessStart,
504
ctsTimeoutAccessStart,
505
switchingAccessStart
506
);
507
NS_LOG_INFO
(
"access grant start="
<< accessGrantedStart <<
508
", rx access start="
<< rxAccessStart <<
509
", busy access start="
<< busyAccessStart <<
510
", tx access start="
<< txAccessStart <<
511
", nav access start="
<< navAccessStart);
512
return
accessGrantedStart;
513
}
514
515
Time
516
DcfManager::GetBackoffStartFor
(
DcfState
*state)
517
{
518
Time
mostRecentEvent =
MostRecent
(state->
GetBackoffStart
(),
519
GetAccessGrantStart
() +
MicroSeconds
(state->
GetAifsn
() *
m_slotTimeUs
));
520
521
return
mostRecentEvent;
522
}
523
524
Time
525
DcfManager::GetBackoffEndFor
(
DcfState
*state)
526
{
527
return
GetBackoffStartFor
(state) +
MicroSeconds
(state->
GetBackoffSlots
() *
m_slotTimeUs
);
528
}
529
530
void
531
DcfManager::UpdateBackoff
(
void
)
532
{
533
uint32_t k = 0;
534
for
(States::const_iterator i =
m_states
.begin (); i !=
m_states
.end (); i++, k++)
535
{
536
DcfState
*state = *i;
537
538
Time
backoffStart =
GetBackoffStartFor
(state);
539
if
(backoffStart <=
Simulator::Now
())
540
{
541
uint32_t nus = (
Simulator::Now
() - backoffStart).GetMicroSeconds ();
542
uint32_t nIntSlots = nus /
m_slotTimeUs
;
543
uint32_t n = std::min (nIntSlots, state->
GetBackoffSlots
());
544
MY_DEBUG
(
"dcf "
<< k <<
" dec backoff slots="
<< n);
545
Time
backoffUpdateBound = backoffStart +
MicroSeconds
(n *
m_slotTimeUs
);
546
state->
UpdateBackoffSlotsNow
(n, backoffUpdateBound);
547
}
548
}
549
}
550
551
void
552
DcfManager::DoRestartAccessTimeoutIfNeeded
(
void
)
553
{
558
bool
accessTimeoutNeeded =
false
;
559
Time
expectedBackoffEnd =
Simulator::GetMaximumSimulationTime
();
560
for
(States::const_iterator i =
m_states
.begin (); i !=
m_states
.end (); i++)
561
{
562
DcfState
*state = *i;
563
if
(state->
IsAccessRequested
())
564
{
565
Time
tmp =
GetBackoffEndFor
(state);
566
if
(tmp >
Simulator::Now
())
567
{
568
accessTimeoutNeeded =
true
;
569
expectedBackoffEnd = std::min (expectedBackoffEnd, tmp);
570
}
571
}
572
}
573
if
(accessTimeoutNeeded)
574
{
575
MY_DEBUG
(
"expected backoff end="
<< expectedBackoffEnd);
576
Time
expectedBackoffDelay = expectedBackoffEnd -
Simulator::Now
();
577
if
(
m_accessTimeout
.
IsRunning
()
578
&&
Simulator::GetDelayLeft
(
m_accessTimeout
) > expectedBackoffDelay)
579
{
580
m_accessTimeout
.
Cancel
();
581
}
582
if
(
m_accessTimeout
.
IsExpired
())
583
{
584
m_accessTimeout
=
Simulator::Schedule
(expectedBackoffDelay,
585
&
DcfManager::AccessTimeout
,
this
);
586
}
587
}
588
}
589
590
void
591
DcfManager::NotifyRxStartNow
(
Time
duration)
592
{
593
MY_DEBUG
(
"rx start for="
<< duration);
594
UpdateBackoff
();
595
m_lastRxStart
=
Simulator::Now
();
596
m_lastRxDuration
= duration;
597
m_rxing
=
true
;
598
}
599
void
600
DcfManager::NotifyRxEndOkNow
(
void
)
601
{
602
MY_DEBUG
(
"rx end ok"
);
603
m_lastRxEnd
=
Simulator::Now
();
604
m_lastRxReceivedOk
=
true
;
605
m_rxing
=
false
;
606
}
607
void
608
DcfManager::NotifyRxEndErrorNow
(
void
)
609
{
610
MY_DEBUG
(
"rx end error"
);
611
m_lastRxEnd
=
Simulator::Now
();
612
m_lastRxReceivedOk
=
false
;
613
m_rxing
=
false
;
614
}
615
void
616
DcfManager::NotifyTxStartNow
(
Time
duration)
617
{
618
if
(
m_rxing
)
619
{
620
//this may be caused only if PHY has started to receive a packet
621
//inside SIFS, so, we check that lastRxStart was maximum a SIFS
622
//ago
623
NS_ASSERT
(
Simulator::Now
() -
m_lastRxStart
<=
m_sifs
);
624
m_lastRxEnd
=
Simulator::Now
();
625
m_lastRxDuration
=
m_lastRxEnd
-
m_lastRxStart
;
626
m_lastRxReceivedOk
=
true
;
627
m_rxing
=
false
;
628
}
629
MY_DEBUG
(
"tx start for "
<< duration);
630
UpdateBackoff
();
631
m_lastTxStart
=
Simulator::Now
();
632
m_lastTxDuration
= duration;
633
}
634
void
635
DcfManager::NotifyMaybeCcaBusyStartNow
(
Time
duration)
636
{
637
MY_DEBUG
(
"busy start for "
<< duration);
638
UpdateBackoff
();
639
m_lastBusyStart
=
Simulator::Now
();
640
m_lastBusyDuration
= duration;
641
}
642
643
644
void
645
DcfManager::NotifySwitchingStartNow
(
Time
duration)
646
{
647
Time
now =
Simulator::Now
();
648
NS_ASSERT
(
m_lastTxStart
+
m_lastTxDuration
<= now);
649
NS_ASSERT
(
m_lastSwitchingStart
+
m_lastSwitchingDuration
<= now);
650
651
if
(
m_rxing
)
652
{
653
// channel switching during packet reception
654
m_lastRxEnd
=
Simulator::Now
();
655
m_lastRxDuration
=
m_lastRxEnd
-
m_lastRxStart
;
656
m_lastRxReceivedOk
=
true
;
657
m_rxing
=
false
;
658
}
659
if
(
m_lastNavStart
+
m_lastNavDuration
> now)
660
{
661
m_lastNavDuration
= now -
m_lastNavStart
;
662
}
663
if
(
m_lastBusyStart
+
m_lastBusyDuration
> now)
664
{
665
m_lastBusyDuration
= now -
m_lastBusyStart
;
666
}
667
if
(
m_lastAckTimeoutEnd
> now)
668
{
669
m_lastAckTimeoutEnd
= now;
670
}
671
if
(
m_lastCtsTimeoutEnd
> now)
672
{
673
m_lastCtsTimeoutEnd
= now;
674
}
675
676
// Cancel timeout
677
if
(
m_accessTimeout
.
IsRunning
())
678
{
679
m_accessTimeout
.
Cancel
();
680
}
681
682
// Reset backoffs
683
for
(States::iterator i =
m_states
.begin (); i !=
m_states
.end (); i++)
684
{
685
DcfState
*state = *i;
686
uint32_t remainingSlots = state->
GetBackoffSlots
();
687
if
(remainingSlots > 0)
688
{
689
state->
UpdateBackoffSlotsNow
(remainingSlots, now);
690
NS_ASSERT
(state->
GetBackoffSlots
() == 0);
691
}
692
state->
ResetCw
();
693
state->
m_accessRequested
=
false
;
694
state->
NotifyChannelSwitching
();
695
}
696
697
MY_DEBUG
(
"switching start for "
<< duration);
698
m_lastSwitchingStart
=
Simulator::Now
();
699
m_lastSwitchingDuration
= duration;
700
701
}
702
703
void
704
DcfManager::NotifyNavResetNow
(
Time
duration)
705
{
706
MY_DEBUG
(
"nav reset for="
<< duration);
707
UpdateBackoff
();
708
m_lastNavStart
=
Simulator::Now
();
709
m_lastNavDuration
= duration;
710
UpdateBackoff
();
717
DoRestartAccessTimeoutIfNeeded
();
718
}
719
void
720
DcfManager::NotifyNavStartNow
(
Time
duration)
721
{
722
NS_ASSERT
(
m_lastNavStart
<
Simulator::Now
());
723
MY_DEBUG
(
"nav start for="
<< duration);
724
UpdateBackoff
();
725
Time
newNavEnd =
Simulator::Now
() + duration;
726
Time
lastNavEnd =
m_lastNavStart
+
m_lastNavDuration
;
727
if
(newNavEnd > lastNavEnd)
728
{
729
m_lastNavStart
=
Simulator::Now
();
730
m_lastNavDuration = duration;
731
}
732
}
733
void
734
DcfManager::NotifyAckTimeoutStartNow
(
Time
duration)
735
{
736
NS_ASSERT
(
m_lastAckTimeoutEnd
<
Simulator::Now
());
737
m_lastAckTimeoutEnd
=
Simulator::Now
() + duration;
738
}
739
void
740
DcfManager::NotifyAckTimeoutResetNow
()
741
{
742
m_lastAckTimeoutEnd
=
Simulator::Now
();
743
DoRestartAccessTimeoutIfNeeded
();
744
}
745
void
746
DcfManager::NotifyCtsTimeoutStartNow
(
Time
duration)
747
{
748
m_lastCtsTimeoutEnd
=
Simulator::Now
() + duration;
749
}
750
void
751
DcfManager::NotifyCtsTimeoutResetNow
()
752
{
753
m_lastCtsTimeoutEnd
=
Simulator::Now
();
754
DoRestartAccessTimeoutIfNeeded
();
755
}
756
}
// namespace ns3
src
wifi
model
dcf-manager.cc
Generated on Fri Dec 21 2012 19:00:48 for ns-3 by
1.8.1.2