A Discrete-Event Network Simulator
API
 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"
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 
43  : m_mobility (0),
44  m_netDevice (0),
45  m_channel (0),
46  m_txPsd (0),
47  m_state (IDLE)
48 {
49  m_interference.SetErrorModel (CreateObject<ShannonSpectrumErrorModel> ());
50 }
51 
52 
54 {
55 }
56 
57 void
59 {
60  NS_LOG_FUNCTION (this);
61  m_mobility = 0;
62  m_netDevice = 0;
63  m_channel = 0;
64  m_txPsd = 0;
65  m_rxPsd = 0;
66  m_txPacket = 0;
67  m_rxPacket = 0;
68  m_phyMacTxEndCallback = MakeNullCallback< void, Ptr<const Packet> > ();
69  m_phyMacRxStartCallback = MakeNullCallback< void > ();
70  m_phyMacRxEndErrorCallback = MakeNullCallback< void > ();
71  m_phyMacRxEndOkCallback = MakeNullCallback< void, Ptr<Packet> > ();
73 }
74 
75 std::ostream& operator<< (std::ostream& os, HalfDuplexIdealPhy::State s)
76 {
77  switch (s)
78  {
80  os << "IDLE";
81  break;
83  os << "RX";
84  break;
86  os << "TX";
87  break;
88  default:
89  os << "UNKNOWN";
90  break;
91  }
92  return os;
93 }
94 
95 
96 TypeId
98 {
99  static TypeId tid = TypeId ("ns3::HalfDuplexIdealPhy")
101  .AddConstructor<HalfDuplexIdealPhy> ()
102  .AddAttribute ("Rate",
103  "The PHY rate used by this device",
104  DataRateValue (DataRate ("1Mbps")),
105  MakeDataRateAccessor (&HalfDuplexIdealPhy::SetRate,
107  MakeDataRateChecker ())
108  .AddTraceSource ("TxStart",
109  "Trace fired when a new transmission is started",
111  .AddTraceSource ("TxEnd",
112  "Trace fired when a previosuly started transmission is finished",
114  .AddTraceSource ("RxStart",
115  "Trace fired when the start of a signal is detected",
117  .AddTraceSource ("RxAbort",
118  "Trace fired when a previously started RX is aborted before time",
120  .AddTraceSource ("RxEndOk",
121  "Trace fired when a previosuly started RX terminates successfully",
123  .AddTraceSource ("RxEndError",
124  "Trace fired when a previosuly started RX terminates with an error (packet is corrupted)",
126  ;
127  return tid;
128 }
129 
130 
131 
134 {
135  NS_LOG_FUNCTION (this);
136  return m_netDevice;
137 }
138 
139 
142 {
143  NS_LOG_FUNCTION (this);
144  return m_mobility;
145 }
146 
147 
148 void
150 {
151  NS_LOG_FUNCTION (this << d);
152  m_netDevice = d;
153 }
154 
155 
156 void
158 {
159  NS_LOG_FUNCTION (this << m);
160  m_mobility = m;
161 }
162 
163 
164 void
166 {
167  NS_LOG_FUNCTION (this << c);
168  m_channel = c;
169 }
170 
173 {
174  if (m_txPsd)
175  {
176  return m_txPsd->GetSpectrumModel ();
177  }
178  else
179  {
180  return 0;
181  }
182 }
183 
184 void
186 {
187  NS_LOG_FUNCTION (this << txPsd);
188  NS_ASSERT (txPsd);
189  m_txPsd = txPsd;
190  NS_LOG_INFO ( *txPsd << *m_txPsd);
191 }
192 
193 void
195 {
196  NS_LOG_FUNCTION (this << noisePsd);
197  NS_ASSERT (noisePsd);
199 }
200 
201 void
203 {
204  NS_LOG_FUNCTION (this << rate);
205  m_rate = rate;
206 }
207 
208 DataRate
210 {
211  NS_LOG_FUNCTION (this);
212  return m_rate;
213 }
214 
215 
216 void
218 {
219  NS_LOG_FUNCTION (this);
221 }
222 
223 void
225 {
226  NS_LOG_FUNCTION (this);
228 }
229 
230 
231 void
233 {
234  NS_LOG_FUNCTION (this);
236 }
237 
238 
239 void
241 {
242  NS_LOG_FUNCTION (this);
244 }
245 
248 {
249  NS_LOG_FUNCTION (this);
250  return m_antenna;
251 }
252 
253 void
255 {
256  NS_LOG_FUNCTION (this << a);
257  m_antenna = a;
258 }
259 
260 void
262 {
263  NS_LOG_LOGIC (this << " state: " << m_state << " -> " << newState);
264  m_state = newState;
265 }
266 
267 bool
269 {
270  NS_LOG_FUNCTION (this << p);
271  NS_LOG_LOGIC (this << "state: " << m_state);
272 
273  m_phyTxStartTrace (p);
274 
275  switch (m_state)
276  {
277  case RX:
278  AbortRx ();
279  // fall through
280 
281  case IDLE:
282  {
283  m_txPacket = p;
284  ChangeState (TX);
285  Ptr<HalfDuplexIdealPhySignalParameters> txParams = Create<HalfDuplexIdealPhySignalParameters> ();
286  double txTimeSeconds = m_rate.CalculateTxTime (p->GetSize ());
287  txParams->duration = Seconds (txTimeSeconds);
288  txParams->txPhy = GetObject<SpectrumPhy> ();
289  txParams->txAntenna = m_antenna;
290  txParams->psd = m_txPsd;
291  txParams->data = m_txPacket;
292 
293  NS_LOG_LOGIC (this << " tx power: " << 10 * std::log10 (Integral (*(txParams->psd))) + 30 << " dBm");
294  m_channel->StartTx (txParams);
295  Simulator::Schedule (Seconds (txTimeSeconds), &HalfDuplexIdealPhy::EndTx, this);
296  }
297  break;
298 
299  case TX:
300 
301  return true;
302  break;
303  }
304  return false;
305 }
306 
307 
308 void
310 {
311  NS_LOG_FUNCTION (this);
312  NS_LOG_LOGIC (this << " state: " << m_state);
313 
314  NS_ASSERT (m_state == TX);
315 
317 
319  {
321  }
322 
323  m_txPacket = 0;
324  ChangeState (IDLE);
325 }
326 
327 
328 void
330 {
331  NS_LOG_FUNCTION (this << spectrumParams);
332  NS_LOG_LOGIC (this << " state: " << m_state);
333  NS_LOG_LOGIC (this << " rx power: " << 10 * std::log10 (Integral (*(spectrumParams->psd))) + 30 << " dBm");
334 
335  // interference will happen regardless of the state of the receiver
336  m_interference.AddSignal (spectrumParams->psd, spectrumParams->duration);
337 
338  // the device might start RX only if the signal is of a type understood by this device
339  // this corresponds in real devices to preamble detection
340  Ptr<HalfDuplexIdealPhySignalParameters> rxParams = DynamicCast<HalfDuplexIdealPhySignalParameters> (spectrumParams);
341  if (rxParams != 0)
342  {
343  // signal is of known type
344  switch (m_state)
345  {
346  case TX:
347  // the PHY will not notice this incoming signal
348  break;
349 
350  case RX:
351  // we should check if we should re-sync on a new incoming signal and discard the old one
352  // (somebody calls this the "capture" effect)
353  // criteria considered to do might include the following:
354  // 1) signal strength (e.g., as returned by rxPsd.Norm ())
355  // 2) how much time has passed since previous RX attempt started
356  // if re-sync (capture) is done, then we should call AbortRx ()
357  break;
358 
359  case IDLE:
360  // preamble detection and synchronization is supposed to be always successful.
361 
362  Ptr<Packet> p = rxParams->data;
363  m_phyRxStartTrace (p);
364  m_rxPacket = p;
365  m_rxPsd = rxParams->psd;
366  ChangeState (RX);
368  {
369  NS_LOG_LOGIC (this << " calling m_phyMacRxStartCallback");
371  }
372  else
373  {
374  NS_LOG_LOGIC (this << " m_phyMacRxStartCallback is NULL");
375  }
376  m_interference.StartRx (p, rxParams->psd);
377  NS_LOG_LOGIC (this << " scheduling EndRx with delay " << rxParams->duration);
378  m_endRxEventId = Simulator::Schedule (rxParams->duration, &HalfDuplexIdealPhy::EndRx, this);
379 
380  break;
381 
382  }
383  }
384  else // rxParams == 0
385  {
386  NS_LOG_LOGIC (this << " signal of unknown type");
387  }
388 
389  NS_LOG_LOGIC (this << " state: " << m_state);
390 }
391 
392 
393 void
395 {
396  NS_LOG_FUNCTION (this);
397  NS_LOG_LOGIC (this << "state: " << m_state);
398 
399  NS_ASSERT (m_state == RX);
403  m_rxPacket = 0;
404  ChangeState (IDLE);
405 }
406 
407 
408 void
410 {
411  NS_LOG_FUNCTION (this);
412  NS_LOG_LOGIC (this << " state: " << m_state);
413 
414  NS_ASSERT (m_state == RX);
415 
416  bool rxOk = m_interference.EndRx ();
417 
418  if (rxOk)
419  {
422  {
423  NS_LOG_LOGIC (this << " calling m_phyMacRxEndOkCallback");
425  }
426  else
427  {
428  NS_LOG_LOGIC (this << " m_phyMacRxEndOkCallback is NULL");
429  }
430  }
431  else
432  {
435  {
436  NS_LOG_LOGIC (this << " calling m_phyMacRxEndErrorCallback");
438  }
439  else
440  {
441  NS_LOG_LOGIC (this << " m_phyMacRxEndErrorCallback is NULL");
442  }
443  }
444 
445  ChangeState (IDLE);
446  m_rxPacket = 0;
447  m_rxPsd = 0;
448 }
449 
450 
451 
452 } // namespace ns3
void SetRate(DataRate rate)
set the PHY rate to be used by this PHY.
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:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
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.
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1014
#define NS_ASSERT(condition)
Definition: assert.h:64
void SetNoisePowerSpectralDensity(Ptr< const SpectrumValue > noisePsd)
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
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
SpectrumInterference m_interference
uint32_t GetSize(void) const
Definition: packet.h:650
GenericPhyRxEndErrorCallback m_phyMacRxEndErrorCallback
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:336
#define NS_LOG_INFO(msg)
Definition: log.h:298
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:824
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
Class for representing data rates.
Definition: data-rate.h:71
TracedCallback< Ptr< const Packet > > m_phyTxStartTrace
double CalculateTxTime(uint32_t bytes) const
Calculate transmission time.
Definition: data-rate.cc:229
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< SampleEmitter > s
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Ptr< AntennaModel > GetRxAntenna()
get the AntennaModel used by the NetDevice for reception
Ptr< SpectrumChannel > m_channel
NS_LOG_COMPONENT_DEFINE("HalfDuplexIdealPhy")
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
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:43
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
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
hold objects of type ns3::DataRate
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:47
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:49
Ptr< const SpectrumModel > GetRxSpectrumModel() const
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611