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
wifi-phy-state-helper.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
#include "
wifi-phy-state-helper.h
"
21
#include "ns3/log.h"
22
#include "ns3/simulator.h"
23
#include "ns3/trace-source-accessor.h"
24
25
NS_LOG_COMPONENT_DEFINE
(
"WifiPhyStateHelper"
);
26
27
namespace
ns3 {
28
29
NS_OBJECT_ENSURE_REGISTERED
(WifiPhyStateHelper);
30
31
TypeId
32
WifiPhyStateHelper::GetTypeId
(
void
)
33
{
34
static
TypeId
tid =
TypeId
(
"ns3::WifiPhyStateHelper"
)
35
.
SetParent
<
Object
> ()
36
.AddConstructor<WifiPhyStateHelper> ()
37
.AddTraceSource (
"State"
,
38
"The state of the PHY layer"
,
39
MakeTraceSourceAccessor
(&
WifiPhyStateHelper::m_stateLogger
))
40
.AddTraceSource (
"RxOk"
,
41
"A packet has been received successfully."
,
42
MakeTraceSourceAccessor
(&
WifiPhyStateHelper::m_rxOkTrace
))
43
.AddTraceSource (
"RxError"
,
44
"A packet has been received unsuccessfully."
,
45
MakeTraceSourceAccessor
(&
WifiPhyStateHelper::m_rxErrorTrace
))
46
.AddTraceSource (
"Tx"
,
"Packet transmission is starting."
,
47
MakeTraceSourceAccessor
(&
WifiPhyStateHelper::m_txTrace
))
48
;
49
return
tid;
50
}
51
52
WifiPhyStateHelper::WifiPhyStateHelper
()
53
: m_rxing (false),
54
m_endTx (
Seconds
(0)),
55
m_endRx (
Seconds
(0)),
56
m_endCcaBusy (
Seconds
(0)),
57
m_endSwitching (
Seconds
(0)),
58
m_startTx (
Seconds
(0)),
59
m_startRx (
Seconds
(0)),
60
m_startCcaBusy (
Seconds
(0)),
61
m_startSwitching (
Seconds
(0)),
62
m_previousStateChangeTime (
Seconds
(0))
63
{
64
NS_LOG_FUNCTION
(
this
);
65
}
66
67
void
68
WifiPhyStateHelper::SetReceiveOkCallback
(
WifiPhy::RxOkCallback
callback)
69
{
70
m_rxOkCallback
= callback;
71
}
72
void
73
WifiPhyStateHelper::SetReceiveErrorCallback
(
WifiPhy::RxErrorCallback
callback)
74
{
75
m_rxErrorCallback
= callback;
76
}
77
void
78
WifiPhyStateHelper::RegisterListener
(
WifiPhyListener
*listener)
79
{
80
m_listeners
.push_back (listener);
81
}
82
83
bool
84
WifiPhyStateHelper::IsStateIdle
(
void
)
85
{
86
return
(
GetState
() ==
WifiPhy::IDLE
);
87
}
88
bool
89
WifiPhyStateHelper::IsStateBusy
(
void
)
90
{
91
return
(
GetState
() !=
WifiPhy::IDLE
);
92
}
93
bool
94
WifiPhyStateHelper::IsStateCcaBusy
(
void
)
95
{
96
return
(
GetState
() ==
WifiPhy::CCA_BUSY
);
97
}
98
bool
99
WifiPhyStateHelper::IsStateRx
(
void
)
100
{
101
return
(
GetState
() ==
WifiPhy::RX
);
102
}
103
bool
104
WifiPhyStateHelper::IsStateTx
(
void
)
105
{
106
return
(
GetState
() ==
WifiPhy::TX
);
107
}
108
bool
109
WifiPhyStateHelper::IsStateSwitching
(
void
)
110
{
111
return
(
GetState
() ==
WifiPhy::SWITCHING
);
112
}
113
114
115
116
Time
117
WifiPhyStateHelper::GetStateDuration
(
void
)
118
{
119
return
Simulator::Now
() -
m_previousStateChangeTime
;
120
}
121
122
Time
123
WifiPhyStateHelper::GetDelayUntilIdle
(
void
)
124
{
125
Time
retval;
126
127
switch
(
GetState
())
128
{
129
case
WifiPhy::RX
:
130
retval =
m_endRx
-
Simulator::Now
();
131
break
;
132
case
WifiPhy::TX
:
133
retval =
m_endTx
-
Simulator::Now
();
134
break
;
135
case
WifiPhy::CCA_BUSY
:
136
retval =
m_endCcaBusy
-
Simulator::Now
();
137
break
;
138
case
WifiPhy::SWITCHING
:
139
retval =
m_endSwitching
-
Simulator::Now
();
140
break
;
141
case
WifiPhy::IDLE
:
142
retval =
Seconds
(0);
143
break
;
144
default
:
145
NS_FATAL_ERROR
(
"Invalid WifiPhy state."
);
146
retval =
Seconds
(0);
147
break
;
148
}
149
retval =
Max
(retval,
Seconds
(0));
150
return
retval;
151
}
152
153
Time
154
WifiPhyStateHelper::GetLastRxStartTime
(
void
)
const
155
{
156
return
m_startRx
;
157
}
158
159
enum
WifiPhy::State
160
WifiPhyStateHelper::GetState
(
void
)
161
{
162
if
(
m_endTx
>
Simulator::Now
())
163
{
164
return
WifiPhy::TX
;
165
}
166
else
if
(
m_rxing
)
167
{
168
return
WifiPhy::RX
;
169
}
170
else
if
(
m_endSwitching
>
Simulator::Now
())
171
{
172
return
WifiPhy::SWITCHING
;
173
}
174
else
if
(
m_endCcaBusy
>
Simulator::Now
())
175
{
176
return
WifiPhy::CCA_BUSY
;
177
}
178
else
179
{
180
return
WifiPhy::IDLE
;
181
}
182
}
183
184
185
void
186
WifiPhyStateHelper::NotifyTxStart
(
Time
duration)
187
{
188
for
(Listeners::const_iterator i =
m_listeners
.begin (); i !=
m_listeners
.end (); i++)
189
{
190
(*i)->NotifyTxStart (duration);
191
}
192
}
193
void
194
WifiPhyStateHelper::NotifyRxStart
(
Time
duration)
195
{
196
for
(Listeners::const_iterator i =
m_listeners
.begin (); i !=
m_listeners
.end (); i++)
197
{
198
(*i)->NotifyRxStart (duration);
199
}
200
}
201
void
202
WifiPhyStateHelper::NotifyRxEndOk
(
void
)
203
{
204
for
(Listeners::const_iterator i =
m_listeners
.begin (); i !=
m_listeners
.end (); i++)
205
{
206
(*i)->NotifyRxEndOk ();
207
}
208
}
209
void
210
WifiPhyStateHelper::NotifyRxEndError
(
void
)
211
{
212
for
(Listeners::const_iterator i =
m_listeners
.begin (); i !=
m_listeners
.end (); i++)
213
{
214
(*i)->NotifyRxEndError ();
215
}
216
}
217
void
218
WifiPhyStateHelper::NotifyMaybeCcaBusyStart
(
Time
duration)
219
{
220
for
(Listeners::const_iterator i =
m_listeners
.begin (); i !=
m_listeners
.end (); i++)
221
{
222
(*i)->NotifyMaybeCcaBusyStart (duration);
223
}
224
}
225
void
226
WifiPhyStateHelper::NotifySwitchingStart
(
Time
duration)
227
{
228
for
(Listeners::const_iterator i =
m_listeners
.begin (); i !=
m_listeners
.end (); i++)
229
{
230
(*i)->NotifySwitchingStart (duration);
231
}
232
}
233
234
void
235
WifiPhyStateHelper::LogPreviousIdleAndCcaBusyStates
(
void
)
236
{
237
Time
now =
Simulator::Now
();
238
Time
idleStart =
Max
(
m_endCcaBusy
,
m_endRx
);
239
idleStart =
Max
(idleStart,
m_endTx
);
240
idleStart =
Max
(idleStart,
m_endSwitching
);
241
NS_ASSERT
(idleStart <= now);
242
if
(
m_endCcaBusy
>
m_endRx
243
&&
m_endCcaBusy
>
m_endSwitching
244
&&
m_endCcaBusy
>
m_endTx
)
245
{
246
Time
ccaBusyStart =
Max
(
m_endTx
,
m_endRx
);
247
ccaBusyStart =
Max
(ccaBusyStart,
m_startCcaBusy
);
248
ccaBusyStart =
Max
(ccaBusyStart,
m_endSwitching
);
249
m_stateLogger
(ccaBusyStart, idleStart - ccaBusyStart,
WifiPhy::CCA_BUSY
);
250
}
251
m_stateLogger
(idleStart, now - idleStart,
WifiPhy::IDLE
);
252
}
253
254
void
255
WifiPhyStateHelper::SwitchToTx
(
Time
txDuration,
Ptr<const Packet>
packet,
WifiMode
txMode,
256
WifiPreamble
preamble, uint8_t txPower)
257
{
258
m_txTrace
(packet, txMode, preamble, txPower);
259
NotifyTxStart
(txDuration);
260
Time
now =
Simulator::Now
();
261
switch
(
GetState
())
262
{
263
case
WifiPhy::RX
:
264
/* The packet which is being received as well
265
* as its endRx event are cancelled by the caller.
266
*/
267
m_rxing
=
false
;
268
m_stateLogger
(
m_startRx
, now -
m_startRx
,
WifiPhy::RX
);
269
m_endRx
= now;
270
break
;
271
case
WifiPhy::CCA_BUSY
:
272
{
273
Time
ccaStart =
Max
(
m_endRx
,
m_endTx
);
274
ccaStart =
Max
(ccaStart,
m_startCcaBusy
);
275
ccaStart =
Max
(ccaStart,
m_endSwitching
);
276
m_stateLogger
(ccaStart, now - ccaStart,
WifiPhy::CCA_BUSY
);
277
}
break
;
278
case
WifiPhy::IDLE
:
279
LogPreviousIdleAndCcaBusyStates
();
280
break
;
281
case
WifiPhy::SWITCHING
:
282
default
:
283
NS_FATAL_ERROR
(
"Invalid WifiPhy state."
);
284
break
;
285
}
286
m_stateLogger
(now, txDuration,
WifiPhy::TX
);
287
m_previousStateChangeTime
= now;
288
m_endTx
= now + txDuration;
289
m_startTx
= now;
290
}
291
void
292
WifiPhyStateHelper::SwitchToRx
(
Time
rxDuration)
293
{
294
NS_ASSERT
(
IsStateIdle
() ||
IsStateCcaBusy
());
295
NS_ASSERT
(!
m_rxing
);
296
NotifyRxStart
(rxDuration);
297
Time
now =
Simulator::Now
();
298
switch
(
GetState
())
299
{
300
case
WifiPhy::IDLE
:
301
LogPreviousIdleAndCcaBusyStates
();
302
break
;
303
case
WifiPhy::CCA_BUSY
:
304
{
305
Time
ccaStart =
Max
(
m_endRx
,
m_endTx
);
306
ccaStart =
Max
(ccaStart,
m_startCcaBusy
);
307
ccaStart =
Max
(ccaStart,
m_endSwitching
);
308
m_stateLogger
(ccaStart, now - ccaStart,
WifiPhy::CCA_BUSY
);
309
}
break
;
310
case
WifiPhy::SWITCHING
:
311
case
WifiPhy::RX
:
312
case
WifiPhy::TX
:
313
NS_FATAL_ERROR
(
"Invalid WifiPhy state."
);
314
break
;
315
}
316
m_previousStateChangeTime
= now;
317
m_rxing
=
true
;
318
m_startRx
= now;
319
m_endRx
= now + rxDuration;
320
NS_ASSERT
(
IsStateRx
());
321
}
322
323
void
324
WifiPhyStateHelper::SwitchToChannelSwitching
(
Time
switchingDuration)
325
{
326
NotifySwitchingStart
(switchingDuration);
327
Time
now =
Simulator::Now
();
328
switch
(
GetState
())
329
{
330
case
WifiPhy::RX
:
331
/* The packet which is being received as well
332
* as its endRx event are cancelled by the caller.
333
*/
334
m_rxing
=
false
;
335
m_stateLogger
(
m_startRx
, now -
m_startRx
,
WifiPhy::RX
);
336
m_endRx
= now;
337
break
;
338
case
WifiPhy::CCA_BUSY
:
339
{
340
Time
ccaStart =
Max
(
m_endRx
,
m_endTx
);
341
ccaStart =
Max
(ccaStart,
m_startCcaBusy
);
342
ccaStart =
Max
(ccaStart,
m_endSwitching
);
343
m_stateLogger
(ccaStart, now - ccaStart,
WifiPhy::CCA_BUSY
);
344
}
break
;
345
case
WifiPhy::IDLE
:
346
LogPreviousIdleAndCcaBusyStates
();
347
break
;
348
case
WifiPhy::TX
:
349
case
WifiPhy::SWITCHING
:
350
default
:
351
NS_FATAL_ERROR
(
"Invalid WifiPhy state."
);
352
break
;
353
}
354
355
if
(now <
m_endCcaBusy
)
356
{
357
m_endCcaBusy
= now;
358
}
359
360
m_stateLogger
(now, switchingDuration,
WifiPhy::SWITCHING
);
361
m_previousStateChangeTime
= now;
362
m_startSwitching
= now;
363
m_endSwitching
= now + switchingDuration;
364
NS_ASSERT
(
IsStateSwitching
());
365
}
366
367
void
368
WifiPhyStateHelper::SwitchFromRxEndOk
(
Ptr<Packet>
packet,
double
snr,
WifiMode
mode,
enum
WifiPreamble
preamble)
369
{
370
m_rxOkTrace
(packet, snr, mode, preamble);
371
NotifyRxEndOk
();
372
DoSwitchFromRx
();
373
if
(!
m_rxOkCallback
.
IsNull
())
374
{
375
m_rxOkCallback
(packet, snr, mode, preamble);
376
}
377
378
}
379
void
380
WifiPhyStateHelper::SwitchFromRxEndError
(
Ptr<const Packet>
packet,
double
snr)
381
{
382
m_rxErrorTrace
(packet, snr);
383
NotifyRxEndError
();
384
DoSwitchFromRx
();
385
if
(!
m_rxErrorCallback
.
IsNull
())
386
{
387
m_rxErrorCallback
(packet, snr);
388
}
389
}
390
391
void
392
WifiPhyStateHelper::DoSwitchFromRx
(
void
)
393
{
394
NS_ASSERT
(
IsStateRx
());
395
NS_ASSERT
(
m_rxing
);
396
397
Time
now =
Simulator::Now
();
398
m_stateLogger
(
m_startRx
, now -
m_startRx
,
WifiPhy::RX
);
399
m_previousStateChangeTime
= now;
400
m_rxing
=
false
;
401
402
NS_ASSERT
(
IsStateIdle
() ||
IsStateCcaBusy
());
403
}
404
void
405
WifiPhyStateHelper::SwitchMaybeToCcaBusy
(
Time
duration)
406
{
407
NotifyMaybeCcaBusyStart
(duration);
408
Time
now =
Simulator::Now
();
409
switch
(
GetState
())
410
{
411
case
WifiPhy::SWITCHING
:
412
break
;
413
case
WifiPhy::IDLE
:
414
LogPreviousIdleAndCcaBusyStates
();
415
break
;
416
case
WifiPhy::CCA_BUSY
:
417
break
;
418
case
WifiPhy::RX
:
419
break
;
420
case
WifiPhy::TX
:
421
break
;
422
}
423
m_startCcaBusy
= now;
424
m_endCcaBusy
= std::max (
m_endCcaBusy
, now + duration);
425
}
426
427
}
// namespace ns3
src
wifi
model
wifi-phy-state-helper.cc
Generated on Tue Oct 9 2012 16:45:49 for ns-3 by
1.8.1.2