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
half-duplex-ideal-phy.cc
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2009 CTTC
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: Nicola Baldo <nbaldo@cttc.es>
19
*/
20
21
#include <ns3/object-factory.h>
22
#include <ns3/log.h>
23
#include <cmath>
24
#include <ns3/simulator.h>
25
#include <ns3/trace-source-accessor.h>
26
#include <ns3/packet-burst.h>
27
#include <ns3/callback.h>
28
#include <ns3/antenna-model.h>
29
30
#include "
half-duplex-ideal-phy.h
"
31
#include "
half-duplex-ideal-phy-signal-parameters.h
"
32
#include "
spectrum-error-model.h
"
33
34
35
NS_LOG_COMPONENT_DEFINE
(
"HalfDuplexIdealPhy"
);
36
37
namespace
ns3 {
38
39
NS_OBJECT_ENSURE_REGISTERED
(HalfDuplexIdealPhy);
40
41
HalfDuplexIdealPhy::HalfDuplexIdealPhy
()
42
: m_mobility (0),
43
m_netDevice (0),
44
m_channel (0),
45
m_txPsd (0),
46
m_state (
IDLE
)
47
{
48
m_interference
.
SetErrorModel
(CreateObject<ShannonSpectrumErrorModel> ());
49
}
50
51
52
HalfDuplexIdealPhy::~HalfDuplexIdealPhy
()
53
{
54
}
55
56
void
57
HalfDuplexIdealPhy::DoDispose
()
58
{
59
NS_LOG_FUNCTION
(
this
);
60
m_mobility
= 0;
61
m_netDevice
= 0;
62
m_channel
= 0;
63
m_txPsd
= 0;
64
m_rxPsd
= 0;
65
m_txPacket
= 0;
66
m_rxPacket
= 0;
67
m_phyMacTxEndCallback
= MakeNullCallback< void, Ptr<const Packet> > ();
68
m_phyMacRxStartCallback
= MakeNullCallback< void > ();
69
m_phyMacRxEndErrorCallback
= MakeNullCallback< void > ();
70
m_phyMacRxEndOkCallback
= MakeNullCallback< void, Ptr<Packet> > ();
71
SpectrumPhy::DoDispose
();
72
}
73
74
std::ostream&
operator<<
(std::ostream& os,
HalfDuplexIdealPhy::State
s)
75
{
76
switch
(s)
77
{
78
case
HalfDuplexIdealPhy::IDLE
:
79
os <<
"IDLE"
;
80
break
;
81
case
HalfDuplexIdealPhy::RX
:
82
os <<
"RX"
;
83
break
;
84
case
HalfDuplexIdealPhy::TX
:
85
os <<
"TX"
;
86
break
;
87
default
:
88
os <<
"UNKNOWN"
;
89
break
;
90
}
91
return
os;
92
}
93
94
95
TypeId
96
HalfDuplexIdealPhy::GetTypeId
(
void
)
97
{
98
static
TypeId
tid =
TypeId
(
"ns3::HalfDuplexIdealPhy"
)
99
.
SetParent
<
SpectrumPhy
> ()
100
.AddConstructor<HalfDuplexIdealPhy> ()
101
.AddAttribute (
"Rate"
,
102
"The PHY rate used by this device"
,
103
DataRateValue
(
DataRate
(
"1Mbps"
)),
104
MakeDataRateAccessor (&
HalfDuplexIdealPhy::SetRate
,
105
&
HalfDuplexIdealPhy::GetRate
),
106
MakeDataRateChecker ())
107
.AddTraceSource (
"TxStart"
,
108
"Trace fired when a new transmission is started"
,
109
MakeTraceSourceAccessor
(&
HalfDuplexIdealPhy::m_phyTxStartTrace
))
110
.AddTraceSource (
"TxEnd"
,
111
"Trace fired when a previosuly started transmission is finished"
,
112
MakeTraceSourceAccessor
(&
HalfDuplexIdealPhy::m_phyTxEndTrace
))
113
.AddTraceSource (
"RxStart"
,
114
"Trace fired when the start of a signal is detected"
,
115
MakeTraceSourceAccessor
(&
HalfDuplexIdealPhy::m_phyRxStartTrace
))
116
.AddTraceSource (
"RxAbort"
,
117
"Trace fired when a previously started RX is aborted before time"
,
118
MakeTraceSourceAccessor
(&
HalfDuplexIdealPhy::m_phyRxAbortTrace
))
119
.AddTraceSource (
"RxEndOk"
,
120
"Trace fired when a previosuly started RX terminates successfully"
,
121
MakeTraceSourceAccessor
(&
HalfDuplexIdealPhy::m_phyRxEndOkTrace
))
122
.AddTraceSource (
"RxEndError"
,
123
"Trace fired when a previosuly started RX terminates with an error (packet is corrupted)"
,
124
MakeTraceSourceAccessor
(&
HalfDuplexIdealPhy::m_phyRxEndErrorTrace
))
125
;
126
return
tid;
127
}
128
129
130
131
Ptr<NetDevice>
132
HalfDuplexIdealPhy::GetDevice
()
133
{
134
NS_LOG_FUNCTION
(
this
);
135
return
m_netDevice
;
136
}
137
138
139
Ptr<MobilityModel>
140
HalfDuplexIdealPhy::GetMobility
()
141
{
142
NS_LOG_FUNCTION
(
this
);
143
return
m_mobility
;
144
}
145
146
147
void
148
HalfDuplexIdealPhy::SetDevice
(
Ptr<NetDevice>
d)
149
{
150
NS_LOG_FUNCTION
(
this
<< d);
151
m_netDevice
= d;
152
}
153
154
155
void
156
HalfDuplexIdealPhy::SetMobility
(
Ptr<MobilityModel>
m)
157
{
158
NS_LOG_FUNCTION
(
this
<< m);
159
m_mobility
= m;
160
}
161
162
163
void
164
HalfDuplexIdealPhy::SetChannel
(
Ptr<SpectrumChannel>
c)
165
{
166
NS_LOG_FUNCTION
(
this
<< c);
167
m_channel
= c;
168
}
169
170
Ptr<const SpectrumModel>
171
HalfDuplexIdealPhy::GetRxSpectrumModel
()
const
172
{
173
if
(
m_txPsd
)
174
{
175
return
m_txPsd
->
GetSpectrumModel
();
176
}
177
else
178
{
179
return
0;
180
}
181
}
182
183
void
184
HalfDuplexIdealPhy::SetTxPowerSpectralDensity
(
Ptr<SpectrumValue>
txPsd)
185
{
186
NS_LOG_FUNCTION
(
this
<< txPsd);
187
NS_ASSERT
(txPsd);
188
m_txPsd
= txPsd;
189
NS_LOG_INFO
( *txPsd << *
m_txPsd
);
190
}
191
192
void
193
HalfDuplexIdealPhy::SetNoisePowerSpectralDensity
(
Ptr<const SpectrumValue>
noisePsd)
194
{
195
NS_LOG_FUNCTION
(
this
<< noisePsd);
196
NS_ASSERT
(noisePsd);
197
m_interference
.
SetNoisePowerSpectralDensity
(noisePsd);
198
}
199
200
void
201
HalfDuplexIdealPhy::SetRate
(
DataRate
rate)
202
{
203
NS_LOG_FUNCTION
(
this
<< rate);
204
m_rate
= rate;
205
}
206
207
DataRate
208
HalfDuplexIdealPhy::GetRate
()
const
209
{
210
NS_LOG_FUNCTION
(
this
);
211
return
m_rate
;
212
}
213
214
215
void
216
HalfDuplexIdealPhy::SetGenericPhyTxEndCallback
(
GenericPhyTxEndCallback
c)
217
{
218
NS_LOG_FUNCTION
(
this
);
219
m_phyMacTxEndCallback
= c;
220
}
221
222
void
223
HalfDuplexIdealPhy::SetGenericPhyRxStartCallback
(
GenericPhyRxStartCallback
c)
224
{
225
NS_LOG_FUNCTION
(
this
);
226
m_phyMacRxStartCallback
= c;
227
}
228
229
230
void
231
HalfDuplexIdealPhy::SetGenericPhyRxEndErrorCallback
(
GenericPhyRxEndErrorCallback
c)
232
{
233
NS_LOG_FUNCTION
(
this
);
234
m_phyMacRxEndErrorCallback
= c;
235
}
236
237
238
void
239
HalfDuplexIdealPhy::SetGenericPhyRxEndOkCallback
(
GenericPhyRxEndOkCallback
c)
240
{
241
NS_LOG_FUNCTION
(
this
);
242
m_phyMacRxEndOkCallback
= c;
243
}
244
245
Ptr<AntennaModel>
246
HalfDuplexIdealPhy::GetRxAntenna
()
247
{
248
NS_LOG_FUNCTION
(
this
);
249
return
m_antenna
;
250
}
251
252
void
253
HalfDuplexIdealPhy::SetAntenna
(
Ptr<AntennaModel>
a)
254
{
255
NS_LOG_FUNCTION
(
this
<< a);
256
m_antenna
= a;
257
}
258
259
void
260
HalfDuplexIdealPhy::ChangeState
(
State
newState)
261
{
262
NS_LOG_LOGIC
(
this
<<
" state: "
<<
m_state
<<
" -> "
<< newState);
263
m_state
= newState;
264
}
265
266
bool
267
HalfDuplexIdealPhy::StartTx
(
Ptr<Packet>
p)
268
{
269
NS_LOG_FUNCTION
(
this
<< p);
270
NS_LOG_LOGIC
(
this
<<
"state: "
<<
m_state
);
271
272
m_phyTxStartTrace
(p);
273
274
switch
(
m_state
)
275
{
276
case
RX
:
277
AbortRx
();
278
// fall through
279
280
case
IDLE
:
281
{
282
m_txPacket
= p;
283
ChangeState
(
TX
);
284
Ptr<HalfDuplexIdealPhySignalParameters>
txParams = Create<HalfDuplexIdealPhySignalParameters> ();
285
double
txTimeSeconds =
m_rate
.
CalculateTxTime
(p->
GetSize
());
286
txParams->duration =
Seconds
(txTimeSeconds);
287
txParams->txPhy = GetObject<SpectrumPhy> ();
288
txParams->txAntenna =
m_antenna
;
289
txParams->psd =
m_txPsd
;
290
txParams->data =
m_txPacket
;
291
292
NS_LOG_LOGIC
(
this
<<
" tx power: "
<< 10 * std::log10 (
Integral
(*(txParams->psd))) + 30 <<
" dBm"
);
293
m_channel
->
StartTx
(txParams);
294
Simulator::Schedule
(
Seconds
(txTimeSeconds), &
HalfDuplexIdealPhy::EndTx
,
this
);
295
}
296
break
;
297
298
case
TX
:
299
300
return
true
;
301
break
;
302
}
303
return
false
;
304
}
305
306
307
void
308
HalfDuplexIdealPhy::EndTx
()
309
{
310
NS_LOG_FUNCTION
(
this
);
311
NS_LOG_LOGIC
(
this
<<
" state: "
<<
m_state
);
312
313
NS_ASSERT
(
m_state
==
TX
);
314
315
m_phyTxEndTrace
(
m_txPacket
);
316
317
if
(!
m_phyMacTxEndCallback
.
IsNull
())
318
{
319
m_phyMacTxEndCallback
(
m_txPacket
);
320
}
321
322
m_txPacket
= 0;
323
ChangeState
(
IDLE
);
324
}
325
326
327
void
328
HalfDuplexIdealPhy::StartRx
(
Ptr<SpectrumSignalParameters>
spectrumParams)
329
{
330
NS_LOG_FUNCTION
(
this
<< spectrumParams);
331
NS_LOG_LOGIC
(
this
<<
" state: "
<<
m_state
);
332
NS_LOG_LOGIC
(
this
<<
" rx power: "
<< 10 * std::log10 (
Integral
(*(spectrumParams->psd))) + 30 <<
" dBm"
);
333
334
// interference will happen regardless of the state of the receiver
335
m_interference
.
AddSignal
(spectrumParams->psd, spectrumParams->duration);
336
337
// the device might start RX only if the signal is of a type understood by this device
338
// this corresponds in real devices to preamble detection
339
Ptr<HalfDuplexIdealPhySignalParameters>
rxParams = DynamicCast<HalfDuplexIdealPhySignalParameters> (spectrumParams);
340
if
(rxParams != 0)
341
{
342
// signal is of known type
343
switch
(
m_state
)
344
{
345
case
TX
:
346
// the PHY will not notice this incoming signal
347
break
;
348
349
case
RX
:
350
// we should check if we should re-sync on a new incoming signal and discard the old one
351
// (somebody calls this the "capture" effect)
352
// criteria considered to do might include the following:
353
// 1) signal strength (e.g., as returned by rxPsd.Norm ())
354
// 2) how much time has passed since previous RX attempt started
355
// if re-sync (capture) is done, then we should call AbortRx ()
356
break
;
357
358
case
IDLE
:
359
// preamble detection and synchronization is supposed to be always successful.
360
361
Ptr<Packet>
p = rxParams->data;
362
m_phyRxStartTrace
(p);
363
m_rxPacket
= p;
364
m_rxPsd
= rxParams->psd;
365
ChangeState
(
RX
);
366
if
(!
m_phyMacRxStartCallback
.
IsNull
())
367
{
368
NS_LOG_LOGIC
(
this
<<
" calling m_phyMacRxStartCallback"
);
369
m_phyMacRxStartCallback
();
370
}
371
else
372
{
373
NS_LOG_LOGIC
(
this
<<
" m_phyMacRxStartCallback is NULL"
);
374
}
375
m_interference
.
StartRx
(p, rxParams->psd);
376
NS_LOG_LOGIC
(
this
<<
" scheduling EndRx with delay "
<< rxParams->duration);
377
m_endRxEventId
=
Simulator::Schedule
(rxParams->duration, &
HalfDuplexIdealPhy::EndRx
,
this
);
378
379
break
;
380
381
}
382
}
383
else
// rxParams == 0
384
{
385
NS_LOG_LOGIC
(
this
<<
" signal of unknown type"
);
386
}
387
388
NS_LOG_LOGIC
(
this
<<
" state: "
<<
m_state
);
389
}
390
391
392
void
393
HalfDuplexIdealPhy::AbortRx
()
394
{
395
NS_LOG_FUNCTION
(
this
);
396
NS_LOG_LOGIC
(
this
<<
"state: "
<<
m_state
);
397
398
NS_ASSERT
(
m_state
==
RX
);
399
m_interference
.
AbortRx
();
400
m_phyRxAbortTrace
(
m_rxPacket
);
401
m_endRxEventId
.
Cancel
();
402
m_rxPacket
= 0;
403
ChangeState
(
IDLE
);
404
}
405
406
407
void
408
HalfDuplexIdealPhy::EndRx
()
409
{
410
NS_LOG_FUNCTION
(
this
);
411
NS_LOG_LOGIC
(
this
<<
" state: "
<<
m_state
);
412
413
NS_ASSERT
(
m_state
==
RX
);
414
415
bool
rxOk =
m_interference
.
EndRx
();
416
417
if
(rxOk)
418
{
419
m_phyRxEndOkTrace
(
m_rxPacket
);
420
if
(!
m_phyMacRxEndOkCallback
.
IsNull
())
421
{
422
NS_LOG_LOGIC
(
this
<<
" calling m_phyMacRxEndOkCallback"
);
423
m_phyMacRxEndOkCallback
(
m_rxPacket
);
424
}
425
else
426
{
427
NS_LOG_LOGIC
(
this
<<
" m_phyMacRxEndOkCallback is NULL"
);
428
}
429
}
430
else
431
{
432
m_phyRxEndErrorTrace
(
m_rxPacket
);
433
if
(!
m_phyMacRxEndErrorCallback
.
IsNull
())
434
{
435
NS_LOG_LOGIC
(
this
<<
" calling m_phyMacRxEndErrorCallback"
);
436
m_phyMacRxEndErrorCallback
();
437
}
438
else
439
{
440
NS_LOG_LOGIC
(
this
<<
" m_phyMacRxEndErrorCallback is NULL"
);
441
}
442
}
443
444
ChangeState
(
IDLE
);
445
m_rxPacket
= 0;
446
m_rxPsd
= 0;
447
}
448
449
450
451
}
// namespace ns3
src
spectrum
model
half-duplex-ideal-phy.cc
Generated on Tue May 14 2013 11:08:32 for ns-3 by
1.8.1.2