A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
uan-phy-dual.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 University of Washington
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Leonard Tracy <lentracy@gmail.com>
7 * Andrea Sacco <andrea.sacco85@gmail.com>
8 */
9
10#include "uan-phy-dual.h"
11
12#include "uan-channel.h"
13#include "uan-header-common.h"
14#include "uan-mac-rc.h"
15#include "uan-net-device.h"
16#include "uan-phy-gen.h"
17#include "uan-phy.h"
18#include "uan-tx-mode.h"
19
20#include "ns3/double.h"
21#include "ns3/log.h"
22#include "ns3/ptr.h"
23#include "ns3/simulator.h"
24#include "ns3/string.h"
25#include "ns3/trace-source-accessor.h"
26#include "ns3/traced-callback.h"
27
28#include <cmath>
29
30namespace ns3
31{
32
33NS_LOG_COMPONENT_DEFINE("UanPhyDual");
34
36NS_OBJECT_ENSURE_REGISTERED(UanPhyCalcSinrDual);
37
41
45
48{
49 static TypeId tid = TypeId("ns3::UanPhyCalcSinrDual")
51 .SetGroupName("Uan")
52 .AddConstructor<UanPhyCalcSinrDual>();
53 return tid;
54}
55
56double
58 Time arrTime,
59 double rxPowerDb,
60 double ambNoiseDb,
61 UanTxMode mode,
62 UanPdp pdp,
63 const UanTransducer::ArrivalList& arrivalList) const
64{
65 if (mode.GetModType() != UanTxMode::OTHER)
66 {
67 NS_LOG_WARN("Calculating SINR for unsupported modulation type");
68 }
69
70 double intKp = -DbToKp(rxPowerDb); // This packet is in the arrivalList
71 auto it = arrivalList.begin();
72 for (; it != arrivalList.end(); it++)
73 {
74 // Only count interference if there is overlap in incoming frequency
75 if (std::abs((double)it->GetTxMode().GetCenterFreqHz() - (double)mode.GetCenterFreqHz()) <
76 (double)(it->GetTxMode().GetBandwidthHz() / 2 + mode.GetBandwidthHz() / 2) - 0.5)
77 {
80 if (pkt)
81 {
82 pkt->PeekHeader(ch);
83 }
84 it->GetPacket()->PeekHeader(ch2);
85
86 if (pkt)
87 {
88 if (ch.GetType() == UanMacRc::TYPE_DATA)
89 {
90 NS_LOG_DEBUG("Adding interferer from "
91 << ch2.GetSrc() << " against " << ch.GetSrc()
92 << ": PktRxMode: " << mode.GetName()
93 << " Int mode: " << it->GetTxMode().GetName() << " Separation: "
94 << std::abs((double)it->GetTxMode().GetCenterFreqHz() -
95 (double)mode.GetCenterFreqHz())
96 << " Combined bandwidths: "
97 << (double)(it->GetTxMode().GetBandwidthHz() / 2 +
98 mode.GetBandwidthHz() / 2) -
99 0.5);
100 }
101 }
102 intKp += DbToKp(it->GetRxPowerDb());
103 }
104 }
105
106 double totalIntDb = KpToDb(intKp + DbToKp(ambNoiseDb));
107
108 NS_LOG_DEBUG(Now().As(Time::S) << " Calculating SINR: RxPower = " << rxPowerDb
109 << " dB. Number of interferers = " << arrivalList.size()
110 << " Interference + noise power = " << totalIntDb
111 << " dB. SINR = " << rxPowerDb - totalIntDb << " dB.");
112 return rxPowerDb - totalIntDb;
113}
114
116 : UanPhy()
117{
120
121 m_phy1->SetReceiveOkCallback(m_recOkCb);
122 m_phy2->SetReceiveOkCallback(m_recOkCb);
123
124 m_phy1->SetReceiveErrorCallback(m_recErrCb);
125 m_phy2->SetReceiveErrorCallback(m_recErrCb);
126}
127
131
132void
134{
135 if (m_phy1)
136 {
137 m_phy1->Clear();
138 m_phy1 = nullptr;
139 }
140 if (m_phy2)
141 {
142 m_phy2->Clear();
143 m_phy2 = nullptr;
144 }
145}
146
147void
153
154TypeId
156{
157 static TypeId tid =
158 TypeId("ns3::UanPhyDual")
159 .SetParent<UanPhy>()
160 .SetGroupName("Uan")
161 .AddConstructor<UanPhyDual>()
162 .AddAttribute(
163 "CcaThresholdPhy1",
164 "Aggregate energy of incoming signals to move to CCA Busy state dB of Phy1.",
165 DoubleValue(10),
169 .AddAttribute(
170 "CcaThresholdPhy2",
171 "Aggregate energy of incoming signals to move to CCA Busy state dB of Phy2.",
172 DoubleValue(10),
176 .AddAttribute(
177 "TxPowerPhy1",
178 "Transmission output power in dB of Phy1.",
179 DoubleValue(190),
182 .AddAttribute(
183 "TxPowerPhy2",
184 "Transmission output power in dB of Phy2.",
185 DoubleValue(190),
188 .AddAttribute(
189 "SupportedModesPhy1",
190 "List of modes supported by Phy1.",
194 .AddAttribute(
195 "SupportedModesPhy2",
196 "List of modes supported by Phy2.",
200 .AddAttribute(
201 "PerModelPhy1",
202 "Functor to calculate PER based on SINR and TxMode for Phy1.",
203 StringValue("ns3::UanPhyPerGenDefault"),
206 .AddAttribute(
207 "PerModelPhy2",
208 "Functor to calculate PER based on SINR and TxMode for Phy2.",
209 StringValue("ns3::UanPhyPerGenDefault"),
212 .AddAttribute(
213 "SinrModelPhy1",
214 "Functor to calculate SINR based on pkt arrivals and modes for Phy1.",
215 StringValue("ns3::UanPhyCalcSinrDual"),
218 .AddAttribute(
219 "SinrModelPhy2",
220 "Functor to calculate SINR based on pkt arrivals and modes for Phy2.",
221 StringValue("ns3::UanPhyCalcSinrDual"),
224 .AddTraceSource("RxOk",
225 "A packet was received successfully.",
227 "ns3::UanPhy::TracedCallback")
228 .AddTraceSource("RxError",
229 "A packet was received unsuccessfuly.",
231 "ns3::UanPhy::TracedCallback")
232 .AddTraceSource("Tx",
233 "Packet transmission beginning.",
235 "ns3::UanPhy::TracedCallback")
236
237 ;
238
239 return tid;
240}
241
242void
247
248void
250{
251 NS_LOG_DEBUG("Not Implemented");
252}
253
254void
256{
257 NS_LOG_DEBUG("Not Implemented");
258}
259
260void
262{
263 if (modeNum <= m_phy1->GetNModes() - 1)
264 {
265 NS_LOG_DEBUG(Now().As(Time::S) << " Sending packet on Phy1 with mode number " << modeNum);
266 m_txLogger(pkt, m_phy1->GetTxPowerDb(), m_phy1->GetMode(modeNum));
267 m_phy1->SendPacket(pkt, modeNum);
268 }
269 else
270 {
271 NS_LOG_DEBUG(Now().As(Time::S) << " Sending packet on Phy2 with mode number "
272 << modeNum - m_phy1->GetNModes());
273 m_txLogger(pkt, m_phy2->GetTxPowerDb(), m_phy2->GetMode(modeNum - m_phy1->GetNModes()));
274 m_phy2->SendPacket(pkt, modeNum - m_phy1->GetNModes());
275 }
276}
277
278void
280{
281 m_phy1->RegisterListener(listener);
282 m_phy2->RegisterListener(listener);
283}
284
285void
287 double /* rxPowerDb */,
288 UanTxMode /* txMode */,
289 UanPdp /* pdp */)
290{
291 // Not called. StartRxPacket in m_phy1 and m_phy2 are called directly from Transducer.
292}
293
294void
296{
297 m_phy1->SetReceiveOkCallback(cb);
298 m_phy2->SetReceiveOkCallback(cb);
299}
300
301void
303{
304 m_phy1->SetReceiveErrorCallback(cb);
305 m_phy2->SetReceiveErrorCallback(cb);
306}
307
308void
310{
311 m_phy1->SetTxPowerDb(txpwr);
312 m_phy2->SetTxPowerDb(txpwr);
313}
314
315void
317{
318 m_phy1->SetTxPowerDb(txpwr);
319}
320
321void
323{
324 m_phy2->SetTxPowerDb(txpwr);
325}
326
327void
329{
330 m_phy1->SetRxThresholdDb(thresh);
331 m_phy2->SetRxThresholdDb(thresh);
332}
333
334void
336{
337 m_phy1->SetCcaThresholdDb(thresh);
338 m_phy2->SetCcaThresholdDb(thresh);
339}
340
341void
343{
344 m_phy1->SetCcaThresholdDb(thresh);
345}
346
347void
349{
350 m_phy2->SetCcaThresholdDb(thresh);
351}
352
353double
355{
356 NS_LOG_WARN("Warning: Dual Phy only returns TxPowerDb of Phy 1");
357 return m_phy1->GetTxPowerDb();
358}
359
360double
362{
363 return m_phy1->GetTxPowerDb();
364}
365
366double
368{
369 return m_phy2->GetTxPowerDb();
370}
371
372double
374{
375 return m_phy1->GetRxThresholdDb();
376}
377
378double
380{
381 NS_LOG_WARN("Dual Phy only returns CCAThreshold of Phy 1");
382 return m_phy1->GetCcaThresholdDb();
383}
384
385double
387{
388 return m_phy1->GetCcaThresholdDb();
389}
390
391double
393{
394 return m_phy2->GetCcaThresholdDb();
395}
396
397bool
399{
400 return m_phy1->IsStateIdle();
401}
402
403bool
405{
406 return m_phy2->IsStateIdle();
407}
408
409bool
411{
412 return m_phy1->IsStateRx();
413}
414
415bool
417{
418 return m_phy2->IsStateRx();
419}
420
421bool
423{
424 return m_phy1->IsStateTx();
425}
426
429{
430 return m_phy1->GetPacketRx();
431}
432
435{
436 return m_phy2->GetPacketRx();
437}
438
439bool
441{
442 return m_phy2->IsStateTx();
443}
444
445bool
447{
448 return m_phy1->IsStateSleep() && m_phy2->IsStateSleep();
449}
450
451bool
453{
454 return m_phy1->IsStateIdle() && m_phy2->IsStateIdle();
455}
456
457bool
459{
460 return !IsStateIdle() || !IsStateSleep();
461}
462
463bool
465{
466 return m_phy1->IsStateRx() || m_phy2->IsStateRx();
467}
468
469bool
471{
472 return m_phy1->IsStateTx() || m_phy2->IsStateTx();
473}
474
475bool
477{
478 return m_phy1->IsStateCcaBusy() || m_phy2->IsStateCcaBusy();
479}
480
483{
484 return m_phy1->GetChannel();
485}
486
489{
490 return m_phy1->GetDevice();
491}
492
493void
495{
496 m_phy1->SetChannel(channel);
497 m_phy2->SetChannel(channel);
498}
499
500void
502{
503 m_phy1->SetDevice(device);
504 m_phy2->SetDevice(device);
505}
506
507void
509{
510 m_phy1->SetMac(mac);
511 m_phy2->SetMac(mac);
512}
513
514void
516 double /* txPowerDb */,
517 UanTxMode /* txMode */)
518{
519}
520
521void
523{
524 m_phy1->NotifyIntChange();
525 m_phy2->NotifyIntChange();
526}
527
528void
530{
531 m_phy1->SetTransducer(trans);
532 m_phy2->SetTransducer(trans);
533}
534
537{
538 NS_LOG_WARN("DualPhy Returning transducer of Phy1");
539 return m_phy1->GetTransducer();
540}
541
544{
545 return m_phy1->GetNModes() + m_phy2->GetNModes();
546}
547
550{
551 if (n < m_phy1->GetNModes())
552 {
553 return m_phy1->GetMode(n);
554 }
555 else
556 {
557 return m_phy2->GetMode(n - m_phy1->GetNModes());
558 }
559}
560
563{
564 UanModesListValue modeValue;
565 m_phy1->GetAttribute("SupportedModes", modeValue);
566 return modeValue.Get();
567}
568
571{
572 UanModesListValue modeValue;
573 m_phy2->GetAttribute("SupportedModes", modeValue);
574 return modeValue.Get();
575}
576
577void
579{
580 m_phy1->SetAttribute("SupportedModes", UanModesListValue(modes));
581}
582
583void
585{
586 m_phy2->SetAttribute("SupportedModes", UanModesListValue(modes));
587}
588
591{
592 PointerValue perValue;
593 m_phy1->GetAttribute("PerModel", perValue);
594 return perValue;
595}
596
599{
600 PointerValue perValue;
601 m_phy2->GetAttribute("PerModel", perValue);
602 return perValue;
603}
604
605void
607{
608 m_phy1->SetAttribute("PerModel", PointerValue(per));
609}
610
611void
613{
614 m_phy2->SetAttribute("PerModel", PointerValue(per));
615}
616
619{
620 PointerValue sinrValue;
621 m_phy1->GetAttribute("SinrModel", sinrValue);
622 return sinrValue;
623}
624
627{
628 PointerValue sinrValue;
629 m_phy2->GetAttribute("SinrModel", sinrValue);
630 return sinrValue;
631}
632
633void
635{
636 m_phy1->SetAttribute("SinrModel", PointerValue(sinr));
637}
638
639void
641{
642 m_phy2->SetAttribute("SinrModel", PointerValue(sinr));
643}
644
645void
647{
648 NS_LOG_DEBUG(Now().As(Time::S) << " Received packet");
649 m_recOkCb(pkt, sinr, mode);
650 m_rxOkLogger(pkt, sinr, mode);
651}
652
653void
655{
656 m_recErrCb(pkt, sinr);
657 m_rxErrLogger(pkt, sinr, m_phy1->GetMode(0));
658}
659
662{
664 "GetPacketRx not valid for UanPhyDual. Must specify GetPhy1PacketRx or GetPhy2PacketRx");
665 return Create<Packet>();
666}
667
668int64_t
670{
671 NS_LOG_FUNCTION(this << stream);
672 return 0;
673}
674
675} // namespace ns3
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
virtual void DoDispose()
Destructor implementation.
Definition object.cc:433
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
Hold variables of type string.
Definition string.h:45
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
@ S
second
Definition nstime.h:105
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Common packet header fields.
uint8_t GetType() const
Get the header type value.
Mac8Address GetSrc() const
Get the source address.
@ TYPE_DATA
Data.
Definition uan-mac-rc.h:157
Container for UanTxModes.
UanModesList Get() const
void SetChannel(Ptr< UanChannel > channel)
Attach a channel.
The power delay profile returned by propagation models.
Default SINR model for UanPhyDual.
UanPhyCalcSinrDual()
Constructor.
~UanPhyCalcSinrDual() override
Destructor.
static TypeId GetTypeId()
Register this type.
double CalcSinrDb(Ptr< Packet > pkt, Time arrTime, double rxPowerDb, double ambNoiseDb, UanTxMode mode, UanPdp pdp, const UanTransducer::ArrivalList &arrivalList) const override
Calculate the SINR value for a packet.
Class used for calculating SINR of packet in UanPhy.
Definition uan-phy.h:33
double DbToKp(double db) const
Convert dB re 1 uPa to kilopascals.
Definition uan-phy.h:69
double KpToDb(double kp) const
Convert kilopascals to dB re 1 uPa.
Definition uan-phy.h:80
Two channel Phy.
RxOkCallback m_recOkCb
Callback when packet received without errors.
Ptr< UanPhy > m_phy1
First Phy layer.
UanModesList GetModesPhy2() const
Get the list of available modes.
double GetCcaThresholdPhy1() const
Get the CCA threshold signal strength required to detect channel busy.
void RxOkFromSubPhy(Ptr< Packet > pkt, double sinr, UanTxMode mode)
Handle callback and logger for packets received without error.
bool IsStateRx() override
Ptr< UanChannel > GetChannel() const override
Get the attached channel.
~UanPhyDual() override
Dummy destructor.
void EnergyDepletionHandler() override
Handle the energy depletion event.
Ptr< Packet > GetPhy2PacketRx() const
Get the packet currently being received.
void NotifyIntChange() override
Called when there has been a change in the amount of interference this node is experiencing from othe...
Ptr< UanPhyCalcSinr > GetSinrModelPhy2() const
Get the SINR calculator.
int64_t AssignStreams(int64_t stream) override
Assign a fixed random variable stream number to the random variables used by this model.
void SetPerModelPhy1(Ptr< UanPhyPer > per)
Set the error probability model.
Ptr< UanPhy > m_phy2
Second Phy layer.
void SetTxPowerDbPhy1(double txpwr)
Set the transmit power.
void SetModesPhy2(UanModesList modes)
Set the available modes.
bool IsStateCcaBusy() override
UanModesList GetModesPhy1() const
Get the list of available modes.
bool IsStateBusy() override
Ptr< Packet > GetPacketRx() const override
Get the packet currently being received.
void Clear() override
Clear all pointer references.
void SetCcaThresholdDb(double thresh) override
Set the threshold for detecting channel busy.
bool IsStateIdle() override
uint32_t GetNModes() override
Get the number of transmission modes supported by this Phy.
UanTxMode GetMode(uint32_t n) override
Get a specific transmission mode.
double GetCcaThresholdDb() override
Get the CCA threshold signal strength required to detect channel busy.
void SetTransducer(Ptr< UanTransducer > trans) override
Attach a transducer to this Phy.
bool IsStateTx() override
double GetCcaThresholdPhy2() const
Get the CCA threshold signal strength required to detect channel busy.
void SetRxThresholdDb(double thresh) override
Set the minimum SINR threshold to receive a packet without errors.
void SetPerModelPhy2(Ptr< UanPhyPer > per)
Set the error probability model.
void SetChannel(Ptr< UanChannel > channel) override
Attach to a channel.
static TypeId GetTypeId()
Register this type.
void RegisterListener(UanPhyListener *listener) override
Register a UanPhyListener to be notified of common UanPhy events.
double GetRxThresholdDb() override
Get the minimum received signal strength required to receive a packet without errors.
bool IsStateSleep() override
void SetSinrModelPhy2(Ptr< UanPhyCalcSinr > calcSinr)
Set the SINR calculator.
ns3::TracedCallback< Ptr< const Packet >, double, UanTxMode > m_rxErrLogger
A packet was received unsuccessfuly.
void SetModesPhy1(UanModesList modes)
Set the available modes.
Ptr< UanPhyPer > GetPerModelPhy2() const
Get the error probability model.
double GetTxPowerDb() override
Get the current transmit power, in dB.
UanPhyDual()
Constructor.
ns3::TracedCallback< Ptr< const Packet >, double, UanTxMode > m_rxOkLogger
A packet was received successfully.
void NotifyTransStartTx(Ptr< Packet > packet, double txPowerDb, UanTxMode txMode) override
Called when a transmission is beginning on the attached transducer.
Ptr< UanPhyPer > GetPerModelPhy1() const
Get the error probability model.
void SendPacket(Ptr< Packet > pkt, uint32_t modeNum) override
Send a packet using a specific transmission mode.
void SetMac(Ptr< UanMac > mac) override
Set the MAC forwarding messages to this Phy.
void SetDevice(Ptr< UanNetDevice > device) override
Set the device hosting this Phy.
double GetTxPowerDbPhy2() const
Get the current transmit power, in dB.
void DoDispose() override
Destructor implementation.
void RxErrFromSubPhy(Ptr< Packet > pkt, double sinr)
Handle callback and logger for packets received with error.
void SetTxPowerDb(double txpwr) override
Set the transmit power.
void EnergyRechargeHandler() override
Handle the energy recharge event.
RxErrCallback m_recErrCb
Callback when packet received with errors.
double GetTxPowerDbPhy1() const
Get the current transmit power, in dB.
void SetCcaThresholdPhy1(double thresh)
Set the threshold for detecting channel busy.
Ptr< UanTransducer > GetTransducer() override
Get the attached transducer.
void SetReceiveErrorCallback(RxErrCallback cb) override
Set the callback to be used when a packet is received with errors.
ns3::TracedCallback< Ptr< const Packet >, double, UanTxMode > m_txLogger
A packet was sent from this Phy.
void SetSinrModelPhy1(Ptr< UanPhyCalcSinr > calcSinr)
Set the SINR calculator.
void SetTxPowerDbPhy2(double txpwr)
Set the transmit power.
Ptr< Packet > GetPhy1PacketRx() const
Get the packet currently being received.
Ptr< UanNetDevice > GetDevice() const override
Get the device hosting this Phy.
void SetEnergyModelCallback(energy::DeviceEnergyModel::ChangeStateCallback callback) override
Set the DeviceEnergyModel callback for UanPhy device.
void SetCcaThresholdPhy2(double thresh)
Set the threshold for detecting channel busy.
void SetReceiveOkCallback(RxOkCallback cb) override
Set the callback to be used when a packet is received without error.
void StartRxPacket(Ptr< Packet > pkt, double rxPowerDb, UanTxMode txMode, UanPdp pdp) override
Packet arriving from channel: i.e.
Ptr< UanPhyCalcSinr > GetSinrModelPhy1() const
Get the SINR calculator.
static UanModesList GetDefaultModes()
Get the default transmission modes.
Base class for UAN Phy models.
Definition uan-phy.h:167
Interface for PHY event listener.
Definition uan-phy.h:134
std::list< UanPacketArrival > ArrivalList
List of arriving packets overlapping in time.
Abstraction of packet modulation information.
Definition uan-tx-mode.h:32
@ OTHER
Unspecified/undefined.
Definition uan-tx-mode.h:45
uint32_t GetBandwidthHz() const
Get the transmission signal bandwidth.
std::string GetName() const
Get the mode name.
ModulationType GetModType() const
Get the modulation type of the mode.
uint32_t GetCenterFreqHz() const
Get the transmission center frequency.
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition pointer.h:248
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:269
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:250
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition simulator.cc:294
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.
Ptr< const AttributeChecker > MakeUanModesListChecker()
Ptr< const AttributeChecker > MakeDoubleChecker()
Definition double.h:82
Ptr< const AttributeAccessor > MakeUanModesListAccessor(T1 a1)
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition double.h:32