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
NS_LOG_FUNCTION
(
this
);
276
}
277
278
DcfManager::~DcfManager
()
279
{
280
delete
m_phyListener
;
281
delete
m_lowListener
;
282
m_phyListener
= 0;
283
m_lowListener
= 0;
284
}
285
286
void
287
DcfManager::SetupPhyListener
(
Ptr<WifiPhy>
phy)
288
{
289
NS_LOG_FUNCTION
(
this
<< phy);
290
m_phyListener
=
new
PhyListener
(
this
);
291
phy->
RegisterListener
(
m_phyListener
);
292
}
293
void
294
DcfManager::SetupLowListener
(
Ptr<MacLow>
low)
295
{
296
NS_LOG_FUNCTION
(
this
<< low);
297
m_lowListener
=
new
LowDcfListener
(
this
);
298
low->
RegisterDcfListener
(
m_lowListener
);
299
}
300
301
void
302
DcfManager::SetSlot
(
Time
slotTime)
303
{
304
NS_LOG_FUNCTION
(
this
<< slotTime);
305
m_slotTimeUs
= slotTime.
GetMicroSeconds
();
306
}
307
void
308
DcfManager::SetSifs
(
Time
sifs)
309
{
310
NS_LOG_FUNCTION
(
this
<< sifs);
311
m_sifs
= sifs;
312
}
313
void
314
DcfManager::SetEifsNoDifs
(
Time
eifsNoDifs)
315
{
316
NS_LOG_FUNCTION
(
this
<< eifsNoDifs);
317
m_eifsNoDifs
= eifsNoDifs;
318
}
319
Time
320
DcfManager::GetEifsNoDifs
()
const
321
{
322
NS_LOG_FUNCTION
(
this
);
323
return
m_eifsNoDifs
;
324
}
325
326
void
327
DcfManager::Add
(
DcfState
*dcf)
328
{
329
NS_LOG_FUNCTION
(
this
<< dcf);
330
m_states
.push_back (dcf);
331
}
332
333
Time
334
DcfManager::MostRecent
(
Time
a,
Time
b)
const
335
{
336
NS_LOG_FUNCTION
(
this
<< a << b);
337
return
Max
(a, b);
338
}
339
Time
340
DcfManager::MostRecent
(
Time
a,
Time
b,
Time
c)
const
341
{
342
NS_LOG_FUNCTION
(
this
<< a << b << c);
343
Time
retval;
344
retval =
Max
(a, b);
345
retval =
Max
(retval, c);
346
return
retval;
347
}
348
Time
349
DcfManager::MostRecent
(
Time
a,
Time
b,
Time
c,
Time
d)
const
350
{
351
NS_LOG_FUNCTION
(
this
<< a << b << c << d);
352
Time
e =
Max
(a, b);
353
Time
f =
Max
(c, d);
354
Time
retval =
Max
(e, f);
355
return
retval;
356
}
357
Time
358
DcfManager::MostRecent
(
Time
a,
Time
b,
Time
c,
Time
d,
Time
e,
Time
f)
const
359
{
360
NS_LOG_FUNCTION
(
this
<< a << b << c << d << e << f);
361
Time
g =
Max
(a, b);
362
Time
h =
Max
(c, d);
363
Time
i =
Max
(e, f);
364
Time
k =
Max
(g, h);
365
Time
retval =
Max
(k, i);
366
return
retval;
367
}
368
369
Time
370
DcfManager::MostRecent
(
Time
a,
Time
b,
Time
c,
Time
d,
Time
e,
Time
f,
Time
g)
const
371
{
372
NS_LOG_FUNCTION
(
this
<< a << b << c << d << e << f << g);
373
Time
h =
Max
(a, b);
374
Time
i =
Max
(c, d);
375
Time
j =
Max
(e, f);
376
Time
k =
Max
(h, i);
377
Time
l =
Max
(j, g);
378
Time
retval =
Max
(k, l);
379
return
retval;
380
}
381
382
bool
383
DcfManager::IsBusy
(
void
)
const
384
{
385
NS_LOG_FUNCTION
(
this
);
386
// PHY busy
387
if
(
m_rxing
)
388
{
389
return
true
;
390
}
391
Time
lastTxEnd =
m_lastTxStart
+
m_lastTxDuration
;
392
if
(lastTxEnd >
Simulator::Now
())
393
{
394
return
true
;
395
}
396
// NAV busy
397
Time
lastNavEnd =
m_lastNavStart
+
m_lastNavDuration
;
398
if
(lastNavEnd >
Simulator::Now
())
399
{
400
return
true
;
401
}
402
return
false
;
403
}
404
405
406
void
407
DcfManager::RequestAccess
(
DcfState
*state)
408
{
409
NS_LOG_FUNCTION
(
this
<< state);
410
UpdateBackoff
();
411
NS_ASSERT
(!state->
IsAccessRequested
());
412
state->
NotifyAccessRequested
();
417
if
(state->
GetBackoffSlots
() == 0
418
&&
IsBusy
())
419
{
420
MY_DEBUG
(
"medium is busy: collision"
);
421
/* someone else has accessed the medium.
422
* generate a backoff.
423
*/
424
state->
NotifyCollision
();
425
}
426
DoGrantAccess
();
427
DoRestartAccessTimeoutIfNeeded
();
428
}
429
430
void
431
DcfManager::DoGrantAccess
(
void
)
432
{
433
NS_LOG_FUNCTION
(
this
);
434
uint32_t k = 0;
435
for
(States::const_iterator i =
m_states
.begin (); i !=
m_states
.end (); k++)
436
{
437
DcfState
*state = *i;
438
if
(state->
IsAccessRequested
()
439
&&
GetBackoffEndFor
(state) <=
Simulator::Now
() )
440
{
445
MY_DEBUG
(
"dcf "
<< k <<
" needs access. backoff expired. access granted. slots="
<< state->
GetBackoffSlots
());
446
i++;
// go to the next item in the list.
447
k++;
448
std::vector<DcfState *> internalCollisionStates;
449
for
(States::const_iterator j = i; j !=
m_states
.end (); j++, k++)
450
{
451
DcfState
*otherState = *j;
452
if
(otherState->
IsAccessRequested
()
453
&&
GetBackoffEndFor
(otherState) <=
Simulator::Now
())
454
{
455
MY_DEBUG
(
"dcf "
<< k <<
" needs access. backoff expired. internal collision. slots="
<<
456
otherState->
GetBackoffSlots
());
462
internalCollisionStates.push_back (otherState);
463
}
464
}
465
473
state->
NotifyAccessGranted
();
474
for
(std::vector<DcfState *>::const_iterator k = internalCollisionStates.begin ();
475
k != internalCollisionStates.end (); k++)
476
{
477
(*k)->NotifyInternalCollision ();
478
}
479
break
;
480
}
481
i++;
482
}
483
}
484
485
void
486
DcfManager::AccessTimeout
(
void
)
487
{
488
NS_LOG_FUNCTION
(
this
);
489
UpdateBackoff
();
490
DoGrantAccess
();
491
DoRestartAccessTimeoutIfNeeded
();
492
}
493
494
Time
495
DcfManager::GetAccessGrantStart
(
void
)
const
496
{
497
NS_LOG_FUNCTION
(
this
);
498
Time
rxAccessStart;
499
if
(!
m_rxing
)
500
{
501
rxAccessStart =
m_lastRxEnd
+
m_sifs
;
502
if
(!
m_lastRxReceivedOk
)
503
{
504
rxAccessStart +=
m_eifsNoDifs
;
505
}
506
}
507
else
508
{
509
rxAccessStart =
m_lastRxStart
+
m_lastRxDuration
+
m_sifs
;
510
}
511
Time
busyAccessStart =
m_lastBusyStart
+
m_lastBusyDuration
+
m_sifs
;
512
Time
txAccessStart =
m_lastTxStart
+
m_lastTxDuration
+
m_sifs
;
513
Time
navAccessStart =
m_lastNavStart
+
m_lastNavDuration
+
m_sifs
;
514
Time
ackTimeoutAccessStart =
m_lastAckTimeoutEnd
+
m_sifs
;
515
Time
ctsTimeoutAccessStart =
m_lastCtsTimeoutEnd
+
m_sifs
;
516
Time
switchingAccessStart =
m_lastSwitchingStart
+
m_lastSwitchingDuration
+
m_sifs
;
517
Time
accessGrantedStart =
MostRecent
(rxAccessStart,
518
busyAccessStart,
519
txAccessStart,
520
navAccessStart,
521
ackTimeoutAccessStart,
522
ctsTimeoutAccessStart,
523
switchingAccessStart
524
);
525
NS_LOG_INFO
(
"access grant start="
<< accessGrantedStart <<
526
", rx access start="
<< rxAccessStart <<
527
", busy access start="
<< busyAccessStart <<
528
", tx access start="
<< txAccessStart <<
529
", nav access start="
<< navAccessStart);
530
return
accessGrantedStart;
531
}
532
533
Time
534
DcfManager::GetBackoffStartFor
(
DcfState
*state)
535
{
536
NS_LOG_FUNCTION
(
this
<< state);
537
Time
mostRecentEvent =
MostRecent
(state->
GetBackoffStart
(),
538
GetAccessGrantStart
() +
MicroSeconds
(state->
GetAifsn
() *
m_slotTimeUs
));
539
540
return
mostRecentEvent;
541
}
542
543
Time
544
DcfManager::GetBackoffEndFor
(
DcfState
*state)
545
{
546
return
GetBackoffStartFor
(state) +
MicroSeconds
(state->
GetBackoffSlots
() *
m_slotTimeUs
);
547
}
548
549
void
550
DcfManager::UpdateBackoff
(
void
)
551
{
552
NS_LOG_FUNCTION
(
this
);
553
uint32_t k = 0;
554
for
(States::const_iterator i =
m_states
.begin (); i !=
m_states
.end (); i++, k++)
555
{
556
DcfState
*state = *i;
557
558
Time
backoffStart =
GetBackoffStartFor
(state);
559
if
(backoffStart <=
Simulator::Now
())
560
{
561
uint32_t nus = (
Simulator::Now
() - backoffStart).GetMicroSeconds ();
562
uint32_t nIntSlots = nus /
m_slotTimeUs
;
563
uint32_t n = std::min (nIntSlots, state->
GetBackoffSlots
());
564
MY_DEBUG
(
"dcf "
<< k <<
" dec backoff slots="
<< n);
565
Time
backoffUpdateBound = backoffStart +
MicroSeconds
(n *
m_slotTimeUs
);
566
state->
UpdateBackoffSlotsNow
(n, backoffUpdateBound);
567
}
568
}
569
}
570
571
void
572
DcfManager::DoRestartAccessTimeoutIfNeeded
(
void
)
573
{
574
NS_LOG_FUNCTION
(
this
);
579
bool
accessTimeoutNeeded =
false
;
580
Time
expectedBackoffEnd =
Simulator::GetMaximumSimulationTime
();
581
for
(States::const_iterator i =
m_states
.begin (); i !=
m_states
.end (); i++)
582
{
583
DcfState
*state = *i;
584
if
(state->
IsAccessRequested
())
585
{
586
Time
tmp =
GetBackoffEndFor
(state);
587
if
(tmp >
Simulator::Now
())
588
{
589
accessTimeoutNeeded =
true
;
590
expectedBackoffEnd = std::min (expectedBackoffEnd, tmp);
591
}
592
}
593
}
594
if
(accessTimeoutNeeded)
595
{
596
MY_DEBUG
(
"expected backoff end="
<< expectedBackoffEnd);
597
Time
expectedBackoffDelay = expectedBackoffEnd -
Simulator::Now
();
598
if
(
m_accessTimeout
.
IsRunning
()
599
&&
Simulator::GetDelayLeft
(
m_accessTimeout
) > expectedBackoffDelay)
600
{
601
m_accessTimeout
.
Cancel
();
602
}
603
if
(
m_accessTimeout
.
IsExpired
())
604
{
605
m_accessTimeout
=
Simulator::Schedule
(expectedBackoffDelay,
606
&
DcfManager::AccessTimeout
,
this
);
607
}
608
}
609
}
610
611
void
612
DcfManager::NotifyRxStartNow
(
Time
duration)
613
{
614
NS_LOG_FUNCTION
(
this
<< duration);
615
MY_DEBUG
(
"rx start for="
<< duration);
616
UpdateBackoff
();
617
m_lastRxStart
=
Simulator::Now
();
618
m_lastRxDuration
= duration;
619
m_rxing
=
true
;
620
}
621
void
622
DcfManager::NotifyRxEndOkNow
(
void
)
623
{
624
NS_LOG_FUNCTION
(
this
);
625
MY_DEBUG
(
"rx end ok"
);
626
m_lastRxEnd
=
Simulator::Now
();
627
m_lastRxReceivedOk
=
true
;
628
m_rxing
=
false
;
629
}
630
void
631
DcfManager::NotifyRxEndErrorNow
(
void
)
632
{
633
NS_LOG_FUNCTION
(
this
);
634
MY_DEBUG
(
"rx end error"
);
635
m_lastRxEnd
=
Simulator::Now
();
636
m_lastRxReceivedOk
=
false
;
637
m_rxing
=
false
;
638
}
639
void
640
DcfManager::NotifyTxStartNow
(
Time
duration)
641
{
642
NS_LOG_FUNCTION
(
this
<< duration);
643
if
(
m_rxing
)
644
{
645
//this may be caused only if PHY has started to receive a packet
646
//inside SIFS, so, we check that lastRxStart was maximum a SIFS
647
//ago
648
NS_ASSERT
(
Simulator::Now
() -
m_lastRxStart
<=
m_sifs
);
649
m_lastRxEnd
=
Simulator::Now
();
650
m_lastRxDuration
=
m_lastRxEnd
-
m_lastRxStart
;
651
m_lastRxReceivedOk
=
true
;
652
m_rxing
=
false
;
653
}
654
MY_DEBUG
(
"tx start for "
<< duration);
655
UpdateBackoff
();
656
m_lastTxStart
=
Simulator::Now
();
657
m_lastTxDuration
= duration;
658
}
659
void
660
DcfManager::NotifyMaybeCcaBusyStartNow
(
Time
duration)
661
{
662
NS_LOG_FUNCTION
(
this
<< duration);
663
MY_DEBUG
(
"busy start for "
<< duration);
664
UpdateBackoff
();
665
m_lastBusyStart
=
Simulator::Now
();
666
m_lastBusyDuration
= duration;
667
}
668
669
670
void
671
DcfManager::NotifySwitchingStartNow
(
Time
duration)
672
{
673
NS_LOG_FUNCTION
(
this
<< duration);
674
Time
now =
Simulator::Now
();
675
NS_ASSERT
(
m_lastTxStart
+
m_lastTxDuration
<= now);
676
NS_ASSERT
(
m_lastSwitchingStart
+
m_lastSwitchingDuration
<= now);
677
678
if
(
m_rxing
)
679
{
680
// channel switching during packet reception
681
m_lastRxEnd
=
Simulator::Now
();
682
m_lastRxDuration
=
m_lastRxEnd
-
m_lastRxStart
;
683
m_lastRxReceivedOk
=
true
;
684
m_rxing
=
false
;
685
}
686
if
(
m_lastNavStart
+
m_lastNavDuration
> now)
687
{
688
m_lastNavDuration
= now -
m_lastNavStart
;
689
}
690
if
(
m_lastBusyStart
+
m_lastBusyDuration
> now)
691
{
692
m_lastBusyDuration
= now -
m_lastBusyStart
;
693
}
694
if
(
m_lastAckTimeoutEnd
> now)
695
{
696
m_lastAckTimeoutEnd
= now;
697
}
698
if
(
m_lastCtsTimeoutEnd
> now)
699
{
700
m_lastCtsTimeoutEnd
= now;
701
}
702
703
// Cancel timeout
704
if
(
m_accessTimeout
.
IsRunning
())
705
{
706
m_accessTimeout
.
Cancel
();
707
}
708
709
// Reset backoffs
710
for
(States::iterator i =
m_states
.begin (); i !=
m_states
.end (); i++)
711
{
712
DcfState
*state = *i;
713
uint32_t remainingSlots = state->
GetBackoffSlots
();
714
if
(remainingSlots > 0)
715
{
716
state->
UpdateBackoffSlotsNow
(remainingSlots, now);
717
NS_ASSERT
(state->
GetBackoffSlots
() == 0);
718
}
719
state->
ResetCw
();
720
state->
m_accessRequested
=
false
;
721
state->
NotifyChannelSwitching
();
722
}
723
724
MY_DEBUG
(
"switching start for "
<< duration);
725
m_lastSwitchingStart
=
Simulator::Now
();
726
m_lastSwitchingDuration
= duration;
727
728
}
729
730
void
731
DcfManager::NotifyNavResetNow
(
Time
duration)
732
{
733
NS_LOG_FUNCTION
(
this
<< duration);
734
MY_DEBUG
(
"nav reset for="
<< duration);
735
UpdateBackoff
();
736
m_lastNavStart
=
Simulator::Now
();
737
m_lastNavDuration
= duration;
738
UpdateBackoff
();
745
DoRestartAccessTimeoutIfNeeded
();
746
}
747
void
748
DcfManager::NotifyNavStartNow
(
Time
duration)
749
{
750
NS_LOG_FUNCTION
(
this
<< duration);
751
NS_ASSERT
(
m_lastNavStart
<
Simulator::Now
());
752
MY_DEBUG
(
"nav start for="
<< duration);
753
UpdateBackoff
();
754
Time
newNavEnd =
Simulator::Now
() + duration;
755
Time
lastNavEnd =
m_lastNavStart
+
m_lastNavDuration
;
756
if
(newNavEnd > lastNavEnd)
757
{
758
m_lastNavStart
=
Simulator::Now
();
759
m_lastNavDuration = duration;
760
}
761
}
762
void
763
DcfManager::NotifyAckTimeoutStartNow
(
Time
duration)
764
{
765
NS_LOG_FUNCTION
(
this
<< duration);
766
NS_ASSERT
(
m_lastAckTimeoutEnd
<
Simulator::Now
());
767
m_lastAckTimeoutEnd
=
Simulator::Now
() + duration;
768
}
769
void
770
DcfManager::NotifyAckTimeoutResetNow
()
771
{
772
NS_LOG_FUNCTION
(
this
);
773
m_lastAckTimeoutEnd
=
Simulator::Now
();
774
DoRestartAccessTimeoutIfNeeded
();
775
}
776
void
777
DcfManager::NotifyCtsTimeoutStartNow
(
Time
duration)
778
{
779
NS_LOG_FUNCTION
(
this
<< duration);
780
m_lastCtsTimeoutEnd
=
Simulator::Now
() + duration;
781
}
782
void
783
DcfManager::NotifyCtsTimeoutResetNow
()
784
{
785
NS_LOG_FUNCTION
(
this
);
786
m_lastCtsTimeoutEnd
=
Simulator::Now
();
787
DoRestartAccessTimeoutIfNeeded
();
788
}
789
}
// namespace ns3
src
wifi
model
dcf-manager.cc
Generated on Tue May 14 2013 11:08:35 for ns-3 by
1.8.1.2