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 
74 std::ostream& operator<< (std::ostream& os, HalfDuplexIdealPhy::State s)
75 {
76  switch (s)
77  {
79  os << "IDLE";
80  break;
82  os << "RX";
83  break;
85  os << "TX";
86  break;
87  default:
88  os << "UNKNOWN";
89  break;
90  }
91  return os;
92 }
93 
94 
95 TypeId
97 {
98  static TypeId tid = TypeId ("ns3::HalfDuplexIdealPhy")
100  .AddConstructor<HalfDuplexIdealPhy> ()
101  .AddAttribute ("Rate",
102  "The PHY rate used by this device",
103  DataRateValue (DataRate ("1Mbps")),
107  .AddTraceSource ("TxStart",
108  "Trace fired when a new transmission is started",
110  "ns3::Packet::TraceCallback")
111  .AddTraceSource ("TxEnd",
112  "Trace fired when a previosuly started transmission is finished",
114  "ns3::Packet::TraceCallback")
115  .AddTraceSource ("RxStart",
116  "Trace fired when the start of a signal is detected",
118  "ns3::Packet::TraceCallback")
119  .AddTraceSource ("RxAbort",
120  "Trace fired when a previously started RX is aborted before time",
122  "ns3::Packet::TraceCallback")
123  .AddTraceSource ("RxEndOk",
124  "Trace fired when a previosuly started RX terminates successfully",
126  "ns3::Packet::TraceCallback")
127  .AddTraceSource ("RxEndError",
128  "Trace fired when a previosuly started RX terminates with an error (packet is corrupted)",
130  "ns3::Packet::TraceCallback")
131  ;
132  return tid;
133 }
134 
135 
136 
139 {
140  NS_LOG_FUNCTION (this);
141  return m_netDevice;
142 }
143 
144 
147 {
148  NS_LOG_FUNCTION (this);
149  return m_mobility;
150 }
151 
152 
153 void
155 {
156  NS_LOG_FUNCTION (this << d);
157  m_netDevice = d;
158 }
159 
160 
161 void
163 {
164  NS_LOG_FUNCTION (this << m);
165  m_mobility = m;
166 }
167 
168 
169 void
171 {
172  NS_LOG_FUNCTION (this << c);
173  m_channel = c;
174 }
175 
178 {
179  if (m_txPsd)
180  {
181  return m_txPsd->GetSpectrumModel ();
182  }
183  else
184  {
185  return 0;
186  }
187 }
188 
189 void
191 {
192  NS_LOG_FUNCTION (this << txPsd);
193  NS_ASSERT (txPsd);
194  m_txPsd = txPsd;
195  NS_LOG_INFO ( *txPsd << *m_txPsd);
196 }
197 
198 void
200 {
201  NS_LOG_FUNCTION (this << noisePsd);
202  NS_ASSERT (noisePsd);
204 }
205 
206 void
208 {
209  NS_LOG_FUNCTION (this << rate);
210  m_rate = rate;
211 }
212 
213 DataRate
215 {
216  NS_LOG_FUNCTION (this);
217  return m_rate;
218 }
219 
220 
221 void
223 {
224  NS_LOG_FUNCTION (this);
226 }
227 
228 void
230 {
231  NS_LOG_FUNCTION (this);
233 }
234 
235 
236 void
238 {
239  NS_LOG_FUNCTION (this);
241 }
242 
243 
244 void
246 {
247  NS_LOG_FUNCTION (this);
249 }
250 
253 {
254  NS_LOG_FUNCTION (this);
255  return m_antenna;
256 }
257 
258 void
260 {
261  NS_LOG_FUNCTION (this << a);
262  m_antenna = a;
263 }
264 
265 void
267 {
268  NS_LOG_LOGIC (this << " state: " << m_state << " -> " << newState);
269  m_state = newState;
270 }
271 
272 bool
274 {
275  NS_LOG_FUNCTION (this << p);
276  NS_LOG_LOGIC (this << "state: " << m_state);
277 
278  m_phyTxStartTrace (p);
279 
280  switch (m_state)
281  {
282  case RX:
283  AbortRx ();
284  // fall through
285 
286  case IDLE:
287  {
288  m_txPacket = p;
289  ChangeState (TX);
290  Ptr<HalfDuplexIdealPhySignalParameters> txParams = Create<HalfDuplexIdealPhySignalParameters> ();
291  Time txTimeSeconds = m_rate.CalculateBytesTxTime (p->GetSize ());
292  txParams->duration = txTimeSeconds;
293  txParams->txPhy = GetObject<SpectrumPhy> ();
294  txParams->txAntenna = m_antenna;
295  txParams->psd = m_txPsd;
296  txParams->data = m_txPacket;
297 
298  NS_LOG_LOGIC (this << " tx power: " << 10 * std::log10 (Integral (*(txParams->psd))) + 30 << " dBm");
299  m_channel->StartTx (txParams);
300  Simulator::Schedule (txTimeSeconds, &HalfDuplexIdealPhy::EndTx, this);
301  }
302  break;
303 
304  case TX:
305 
306  return true;
307  break;
308  }
309  return false;
310 }
311 
312 
313 void
315 {
316  NS_LOG_FUNCTION (this);
317  NS_LOG_LOGIC (this << " state: " << m_state);
318 
319  NS_ASSERT (m_state == TX);
320 
322 
324  {
326  }
327 
328  m_txPacket = 0;
329  ChangeState (IDLE);
330 }
331 
332 
333 void
335 {
336  NS_LOG_FUNCTION (this << spectrumParams);
337  NS_LOG_LOGIC (this << " state: " << m_state);
338  NS_LOG_LOGIC (this << " rx power: " << 10 * std::log10 (Integral (*(spectrumParams->psd))) + 30 << " dBm");
339 
340  // interference will happen regardless of the state of the receiver
341  m_interference.AddSignal (spectrumParams->psd, spectrumParams->duration);
342 
343  // the device might start RX only if the signal is of a type understood by this device
344  // this corresponds in real devices to preamble detection
345  Ptr<HalfDuplexIdealPhySignalParameters> rxParams = DynamicCast<HalfDuplexIdealPhySignalParameters> (spectrumParams);
346  if (rxParams != 0)
347  {
348  // signal is of known type
349  switch (m_state)
350  {
351  case TX:
352  // the PHY will not notice this incoming signal
353  break;
354 
355  case RX:
356  // we should check if we should re-sync on a new incoming signal and discard the old one
357  // (somebody calls this the "capture" effect)
358  // criteria considered to do might include the following:
359  // 1) signal strength (e.g., as returned by rxPsd.Norm ())
360  // 2) how much time has passed since previous RX attempt started
361  // if re-sync (capture) is done, then we should call AbortRx ()
362  break;
363 
364  case IDLE:
365  // preamble detection and synchronization is supposed to be always successful.
366 
367  Ptr<Packet> p = rxParams->data;
368  m_phyRxStartTrace (p);
369  m_rxPacket = p;
370  m_rxPsd = rxParams->psd;
371  ChangeState (RX);
373  {
374  NS_LOG_LOGIC (this << " calling m_phyMacRxStartCallback");
376  }
377  else
378  {
379  NS_LOG_LOGIC (this << " m_phyMacRxStartCallback is NULL");
380  }
381  m_interference.StartRx (p, rxParams->psd);
382  NS_LOG_LOGIC (this << " scheduling EndRx with delay " << rxParams->duration);
383  m_endRxEventId = Simulator::Schedule (rxParams->duration, &HalfDuplexIdealPhy::EndRx, this);
384 
385  break;
386 
387  }
388  }
389  else // rxParams == 0
390  {
391  NS_LOG_LOGIC (this << " signal of unknown type");
392  }
393 
394  NS_LOG_LOGIC (this << " state: " << m_state);
395 }
396 
397 
398 void
400 {
401  NS_LOG_FUNCTION (this);
402  NS_LOG_LOGIC (this << "state: " << m_state);
403 
404  NS_ASSERT (m_state == RX);
408  m_rxPacket = 0;
409  ChangeState (IDLE);
410 }
411 
412 
413 void
415 {
416  NS_LOG_FUNCTION (this);
417  NS_LOG_LOGIC (this << " state: " << m_state);
418 
419  NS_ASSERT (m_state == RX);
420 
421  bool rxOk = m_interference.EndRx ();
422 
423  if (rxOk)
424  {
427  {
428  NS_LOG_LOGIC (this << " calling m_phyMacRxEndOkCallback");
430  }
431  else
432  {
433  NS_LOG_LOGIC (this << " m_phyMacRxEndOkCallback is NULL");
434  }
435  }
436  else
437  {
440  {
441  NS_LOG_LOGIC (this << " calling m_phyMacRxEndErrorCallback");
443  }
444  else
445  {
446  NS_LOG_LOGIC (this << " m_phyMacRxEndErrorCallback is NULL");
447  }
448  }
449 
450  ChangeState (IDLE);
451  m_rxPacket = 0;
452  m_rxPsd = 0;
453 }
454 
455 
456 
457 } // namespace ns3
void SetRate(DataRate rate)
set the PHY rate to be used by this PHY.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
void SetGenericPhyTxEndCallback(GenericPhyTxEndCallback c)
set the callback for the end of a TX, as part of the interconnections betweenthe PHY and the MAC ...
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Ptr< MobilityModel > m_mobility
Abstract base class for Spectrum-aware PHY layers.
Definition: spectrum-phy.h:45
double Integral(const SpectrumValue &arg)
bool StartTx(Ptr< Packet > p)
Start a transmission.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
Time CalculateBytesTxTime(uint32_t bytes) const
Calculate transmission time.
Definition: data-rate.cc:235
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1078
#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
void SetNoisePowerSpectralDensity(Ptr< const SpectrumValue > noisePsd)
void SetGenericPhyRxStartCallback(GenericPhyRxStartCallback c)
set the callback for the start of RX, as part of the interconnections betweenthe PHY and the MAC ...
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:62
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
SpectrumInterference m_interference
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:766
GenericPhyRxEndErrorCallback m_phyMacRxEndErrorCallback
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:339
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
void AddSignal(Ptr< const SpectrumValue > spd, const Time duration)
notify that a new signal is being perceived in the medium.
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:819
Ptr< MobilityModel > GetMobility()
get the associated MobilityModel instance
Ptr< const SpectrumValue > m_rxPsd
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
void AbortRx()
notify that the PHY has aborted RX
void StartRx(Ptr< SpectrumSignalParameters > params)
Notify the SpectrumPhy instance of an incoming signal.
void StartRx(Ptr< const Packet > p, Ptr< const SpectrumValue > rxPsd)
notify that the PHY is starting a RX attempt
TracedCallback< Ptr< const Packet > > m_phyRxStartTrace
TracedCallback< Ptr< const Packet > > m_phyRxAbortTrace
Ptr< const AttributeChecker > MakeDataRateChecker(void)
Definition: data-rate.cc:30
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Class for representing data rates.
Definition: data-rate.h:88
TracedCallback< Ptr< const Packet > > m_phyTxStartTrace
void SetDevice(Ptr< NetDevice > d)
set the associated NetDevice instance
void SetAntenna(Ptr< AntennaModel > a)
set the AntennaModel to be used
Ptr< SpectrumValue > m_txPsd
void SetGenericPhyRxEndOkCallback(GenericPhyRxEndOkCallback c)
set the callback for the successful end of a RX, as part of the interconnections betweenthe PHY and t...
GenericPhyRxEndOkCallback m_phyMacRxEndOkCallback
Ptr< const SpectrumModel > GetSpectrumModel() const
virtual void DoDispose(void)
Destructor implementation.
Ptr< AntennaModel > GetRxAntenna()
get the AntennaModel used by the NetDevice for reception
Ptr< SpectrumChannel > m_channel
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:238
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
void SetNoisePowerSpectralDensity(Ptr< const SpectrumValue > noisePsd)
Ptr< NetDevice > GetDevice()
get the associated NetDevice instance
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:42
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void ChangeState(State newState)
bool EndRx()
notify that the RX attempt has ended.
void SetGenericPhyRxEndErrorCallback(GenericPhyRxEndErrorCallback c)
set the callback for the end of a RX in error, as part of the interconnections betweenthe PHY and the...
Ptr< AntennaModel > m_antenna
TracedCallback< Ptr< const Packet > > m_phyRxEndErrorTrace
AttributeValue implementation for DataRate.
Definition: data-rate.h:238
GenericPhyRxStartCallback m_phyMacRxStartCallback
static TypeId GetTypeId(void)
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
void SetChannel(Ptr< SpectrumChannel > c)
Set the channel attached to this device.
void SetErrorModel(Ptr< SpectrumErrorModel > e)
set the SpectrumErrorModel to be used.
TracedCallback< Ptr< const Packet > > m_phyRxEndOkTrace
void SetMobility(Ptr< MobilityModel > m)
Set the mobility model associated with this device.
GenericPhyTxEndCallback m_phyMacTxEndCallback
void SetTxPowerSpectralDensity(Ptr< SpectrumValue > txPsd)
set the Power Spectral Density of outgoing signals in power units (Watt, Pascal...) per Hz.
a unique identifier for an interface.
Definition: type-id.h:57
Ptr< const SpectrumModel > GetRxSpectrumModel() const
TypeId SetParent(TypeId tid)
Definition: type-id.cc:638