A Discrete-Event Network Simulator
API
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"
32 #include "spectrum-error-model.h"
33 
34 
35 namespace ns3 {
36 
37 NS_LOG_COMPONENT_DEFINE ("HalfDuplexIdealPhy");
38 
39 NS_OBJECT_ENSURE_REGISTERED (HalfDuplexIdealPhy);
40 
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 
53 {
54 }
55 
56 void
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> > ();
72 }
73 
80 std::ostream& operator<< (std::ostream& os, HalfDuplexIdealPhy::State s)
81 {
82  switch (s)
83  {
85  os << "IDLE";
86  break;
88  os << "RX";
89  break;
91  os << "TX";
92  break;
93  default:
94  os << "UNKNOWN";
95  break;
96  }
97  return os;
98 }
99 
100 
101 TypeId
103 {
104  static TypeId tid = TypeId ("ns3::HalfDuplexIdealPhy")
106  .SetGroupName ("Spectrum")
107  .AddConstructor<HalfDuplexIdealPhy> ()
108  .AddAttribute ("Rate",
109  "The PHY rate used by this device",
110  DataRateValue (DataRate ("1Mbps")),
114  .AddTraceSource ("TxStart",
115  "Trace fired when a new transmission is started",
117  "ns3::Packet::TracedCallback")
118  .AddTraceSource ("TxEnd",
119  "Trace fired when a previously started transmission is finished",
121  "ns3::Packet::TracedCallback")
122  .AddTraceSource ("RxStart",
123  "Trace fired when the start of a signal is detected",
125  "ns3::Packet::TracedCallback")
126  .AddTraceSource ("RxAbort",
127  "Trace fired when a previously started RX is aborted before time",
129  "ns3::Packet::TracedCallback")
130  .AddTraceSource ("RxEndOk",
131  "Trace fired when a previously started RX terminates successfully",
133  "ns3::Packet::TracedCallback")
134  .AddTraceSource ("RxEndError",
135  "Trace fired when a previously started RX terminates with an error (packet is corrupted)",
137  "ns3::Packet::TracedCallback")
138  ;
139  return tid;
140 }
141 
142 
143 
146 {
147  NS_LOG_FUNCTION (this);
148  return m_netDevice;
149 }
150 
151 
154 {
155  NS_LOG_FUNCTION (this);
156  return m_mobility;
157 }
158 
159 
160 void
162 {
163  NS_LOG_FUNCTION (this << d);
164  m_netDevice = d;
165 }
166 
167 
168 void
170 {
171  NS_LOG_FUNCTION (this << m);
172  m_mobility = m;
173 }
174 
175 
176 void
178 {
179  NS_LOG_FUNCTION (this << c);
180  m_channel = c;
181 }
182 
185 {
186  if (m_txPsd)
187  {
188  return m_txPsd->GetSpectrumModel ();
189  }
190  else
191  {
192  return 0;
193  }
194 }
195 
196 void
198 {
199  NS_LOG_FUNCTION (this << txPsd);
200  NS_ASSERT (txPsd);
201  m_txPsd = txPsd;
202  NS_LOG_INFO ( *txPsd << *m_txPsd);
203 }
204 
205 void
207 {
208  NS_LOG_FUNCTION (this << noisePsd);
209  NS_ASSERT (noisePsd);
211 }
212 
213 void
215 {
216  NS_LOG_FUNCTION (this << rate);
217  m_rate = rate;
218 }
219 
220 DataRate
222 {
223  NS_LOG_FUNCTION (this);
224  return m_rate;
225 }
226 
227 
228 void
230 {
231  NS_LOG_FUNCTION (this);
233 }
234 
235 void
237 {
238  NS_LOG_FUNCTION (this);
240 }
241 
242 
243 void
245 {
246  NS_LOG_FUNCTION (this);
248 }
249 
250 
251 void
253 {
254  NS_LOG_FUNCTION (this);
256 }
257 
260 {
261  NS_LOG_FUNCTION (this);
262  return m_antenna;
263 }
264 
265 void
267 {
268  NS_LOG_FUNCTION (this << a);
269  m_antenna = a;
270 }
271 
272 void
274 {
275  NS_LOG_LOGIC (this << " state: " << m_state << " -> " << newState);
276  m_state = newState;
277 }
278 
279 bool
281 {
282  NS_LOG_FUNCTION (this << p);
283  NS_LOG_LOGIC (this << "state: " << m_state);
284 
285  m_phyTxStartTrace (p);
286 
287  switch (m_state)
288  {
289  case RX:
290  AbortRx ();
291  // fall through
292 
293  case IDLE:
294  {
295  m_txPacket = p;
296  ChangeState (TX);
297  Ptr<HalfDuplexIdealPhySignalParameters> txParams = Create<HalfDuplexIdealPhySignalParameters> ();
298  Time txTimeSeconds = m_rate.CalculateBytesTxTime (p->GetSize ());
299  txParams->duration = txTimeSeconds;
300  txParams->txPhy = GetObject<SpectrumPhy> ();
301  txParams->txAntenna = m_antenna;
302  txParams->psd = m_txPsd;
303  txParams->data = m_txPacket;
304 
305  NS_LOG_LOGIC (this << " tx power: " << 10 * std::log10 (Integral (*(txParams->psd))) + 30 << " dBm");
306  m_channel->StartTx (txParams);
307  Simulator::Schedule (txTimeSeconds, &HalfDuplexIdealPhy::EndTx, this);
308  }
309  break;
310 
311  case TX:
312 
313  return true;
314  break;
315  }
316  return false;
317 }
318 
319 
320 void
322 {
323  NS_LOG_FUNCTION (this);
324  NS_LOG_LOGIC (this << " state: " << m_state);
325 
326  NS_ASSERT (m_state == TX);
327 
329 
331  {
333  }
334 
335  m_txPacket = 0;
336  ChangeState (IDLE);
337 }
338 
339 
340 void
342 {
343  NS_LOG_FUNCTION (this << spectrumParams);
344  NS_LOG_LOGIC (this << " state: " << m_state);
345  NS_LOG_LOGIC (this << " rx power: " << 10 * std::log10 (Integral (*(spectrumParams->psd))) + 30 << " dBm");
346 
347  // interference will happen regardless of the state of the receiver
348  m_interference.AddSignal (spectrumParams->psd, spectrumParams->duration);
349 
350  // the device might start RX only if the signal is of a type understood by this device
351  // this corresponds in real devices to preamble detection
352  Ptr<HalfDuplexIdealPhySignalParameters> rxParams = DynamicCast<HalfDuplexIdealPhySignalParameters> (spectrumParams);
353  if (rxParams != 0)
354  {
355  // signal is of known type
356  switch (m_state)
357  {
358  case TX:
359  // the PHY will not notice this incoming signal
360  break;
361 
362  case RX:
363  // we should check if we should re-sync on a new incoming signal and discard the old one
364  // (somebody calls this the "capture" effect)
365  // criteria considered to do might include the following:
366  // 1) signal strength (e.g., as returned by rxPsd.Norm ())
367  // 2) how much time has passed since previous RX attempt started
368  // if re-sync (capture) is done, then we should call AbortRx ()
369  break;
370 
371  case IDLE:
372  // preamble detection and synchronization is supposed to be always successful.
373 
374  Ptr<Packet> p = rxParams->data;
375  m_phyRxStartTrace (p);
376  m_rxPacket = p;
377  m_rxPsd = rxParams->psd;
378  ChangeState (RX);
380  {
381  NS_LOG_LOGIC (this << " calling m_phyMacRxStartCallback");
383  }
384  else
385  {
386  NS_LOG_LOGIC (this << " m_phyMacRxStartCallback is NULL");
387  }
388  m_interference.StartRx (p, rxParams->psd);
389  NS_LOG_LOGIC (this << " scheduling EndRx with delay " << rxParams->duration);
390  m_endRxEventId = Simulator::Schedule (rxParams->duration, &HalfDuplexIdealPhy::EndRx, this);
391 
392  break;
393 
394  }
395  }
396  else // rxParams == 0
397  {
398  NS_LOG_LOGIC (this << " signal of unknown type");
399  }
400 
401  NS_LOG_LOGIC (this << " state: " << m_state);
402 }
403 
404 
405 void
407 {
408  NS_LOG_FUNCTION (this);
409  NS_LOG_LOGIC (this << "state: " << m_state);
410 
411  NS_ASSERT (m_state == RX);
415  m_rxPacket = 0;
416  ChangeState (IDLE);
417 }
418 
419 
420 void
422 {
423  NS_LOG_FUNCTION (this);
424  NS_LOG_LOGIC (this << " state: " << m_state);
425 
426  NS_ASSERT (m_state == RX);
427 
428  bool rxOk = m_interference.EndRx ();
429 
430  if (rxOk)
431  {
434  {
435  NS_LOG_LOGIC (this << " calling m_phyMacRxEndOkCallback");
437  }
438  else
439  {
440  NS_LOG_LOGIC (this << " m_phyMacRxEndOkCallback is NULL");
441  }
442  }
443  else
444  {
447  {
448  NS_LOG_LOGIC (this << " calling m_phyMacRxEndErrorCallback");
450  }
451  else
452  {
453  NS_LOG_LOGIC (this << " m_phyMacRxEndErrorCallback is NULL");
454  }
455  }
456 
457  ChangeState (IDLE);
458  m_rxPacket = 0;
459  m_rxPsd = 0;
460 }
461 
462 
463 
464 } // namespace ns3
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
Class for representing data rates.
Definition: data-rate.h:89
Time CalculateBytesTxTime(uint32_t bytes) const
Calculate transmission time.
Definition: data-rate.cc:275
AttributeValue implementation for DataRate.
Definition: data-rate.h:298
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
This PHY layer implementation realizes an ideal OFDM PHY which transmits half-duplex (i....
Ptr< MobilityModel > GetMobility() const
Get the associated MobilityModel instance.
TracedCallback< Ptr< const Packet > > m_phyRxEndOkTrace
Trace - Tx end (ok)
void SetGenericPhyTxEndCallback(GenericPhyTxEndCallback c)
Set the callback for the end of a TX, as part of the interconnections between the PHY and the MAC.
Ptr< const SpectrumValue > m_rxPsd
Rx power spectral density.
GenericPhyTxEndCallback m_phyMacTxEndCallback
Callback - Tx end.
void SetGenericPhyRxEndErrorCallback(GenericPhyRxEndErrorCallback c)
set the callback for the end of a RX in error, as part of the interconnections between the PHY and th...
void SetRate(DataRate rate)
Set the PHY rate to be used by this PHY.
void SetMobility(Ptr< MobilityModel > m)
Set the mobility model associated with this device.
SpectrumInterference m_interference
Received interference.
DataRate GetRate() const
Get the PHY rate to be used by this PHY.
Ptr< MobilityModel > m_mobility
Mobility model.
Ptr< NetDevice > GetDevice() const
Get the associated NetDevice instance.
TracedCallback< Ptr< const Packet > > m_phyRxStartTrace
Trace - Rx start.
Ptr< AntennaModel > m_antenna
Antenna model.
TracedCallback< Ptr< const Packet > > m_phyRxAbortTrace
Trace - Rx abort.
void SetAntenna(Ptr< AntennaModel > a)
set the AntennaModel to be used
TracedCallback< Ptr< const Packet > > m_phyTxStartTrace
Trace - Tx start.
void SetGenericPhyRxEndOkCallback(GenericPhyRxEndOkCallback c)
set the callback for the successful end of a RX, as part of the interconnections between the PHY and ...
GenericPhyRxStartCallback m_phyMacRxStartCallback
Callback - Rx start.
Ptr< const SpectrumModel > GetRxSpectrumModel() const
virtual void DoDispose(void)
Destructor implementation.
Ptr< SpectrumChannel > m_channel
Channel.
EventId m_endRxEventId
End Rx event.
void ChangeState(State newState)
Change the PHY state.
void EndRx()
End current Rx.
Ptr< Packet > m_rxPacket
Rx packet.
void SetNoisePowerSpectralDensity(Ptr< const SpectrumValue > noisePsd)
Set the Noise Power Spectral Density in power units (Watt, Pascal...) per Hz.
void StartRx(Ptr< SpectrumSignalParameters > params)
Notify the SpectrumPhy instance of an incoming signal.
GenericPhyRxEndErrorCallback m_phyMacRxEndErrorCallback
Callback - Rx error.
Ptr< NetDevice > m_netDevice
NetDevice connected to theis phy.
Ptr< Packet > m_txPacket
Tx packet.
Ptr< Object > GetAntenna() const
Get the AntennaModel used by this SpectrumPhy instance for transmission and/or reception.
void EndTx()
End the current Tx.
TracedCallback< Ptr< const Packet > > m_phyRxEndErrorTrace
Trace - Rx end (error)
void SetDevice(Ptr< NetDevice > d)
Set the associated NetDevice instance.
void AbortRx()
About current Rx.
void SetTxPowerSpectralDensity(Ptr< SpectrumValue > txPsd)
Set the Power Spectral Density of outgoing signals in power units (Watt, Pascal......
bool StartTx(Ptr< Packet > p)
Start a transmission.
Ptr< SpectrumValue > m_txPsd
Tx power spectral density.
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
Trace - Tx end.
static TypeId GetTypeId(void)
Get the type ID.
void SetGenericPhyRxStartCallback(GenericPhyRxStartCallback c)
Set the callback for the start of RX, as part of the interconnections between the PHY and the MAC.
GenericPhyRxEndOkCallback m_phyMacRxEndOkCallback
Callback - Rx end.
void SetChannel(Ptr< SpectrumChannel > c)
Set the channel attached to this device.
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
void AbortRx()
Notify that the PHY has aborted RX.
void SetNoisePowerSpectralDensity(Ptr< const SpectrumValue > noisePsd)
Set the Noise Power Spectral Density.
bool EndRx()
Notify that the RX attempt has ended.
void SetErrorModel(Ptr< SpectrumErrorModel > e)
Set the SpectrumErrorModel to be used.
void StartRx(Ptr< const Packet > p, Ptr< const SpectrumValue > rxPsd)
Notify that the PHY is starting a RX attempt.
void AddSignal(Ptr< const SpectrumValue > spd, const Time duration)
Notify that a new signal is being perceived in the medium.
Abstract base class for Spectrum-aware PHY layers.
Definition: spectrum-phy.h:47
Ptr< const SpectrumModel > GetSpectrumModel() const
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
Ptr< const AttributeAccessor > MakeDataRateAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: data-rate.h:298
Ptr< const AttributeChecker > MakeDataRateChecker(void)
Definition: data-rate.cc:30
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double Integral(const SpectrumValue &arg)
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:139
@ IDLE
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:75