Index: src/devices/uan/uan-phy-dual.cc |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/src/devices/uan/uan-phy-dual.cc |
@@ -0,0 +1,636 @@ |
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ |
+/* |
+ * Copyright (c) 2009 University of Washington |
+ * |
+ * This program is free software; you can redistribute it and/or modify |
+ * it under the terms of the GNU General Public License version 2 as |
+ * published by the Free Software Foundation; |
+ * |
+ * This program is distributed in the hope that it will be useful, |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ * GNU General Public License for more details. |
+ * |
+ * You should have received a copy of the GNU General Public License |
+ * along with this program; if not, write to the Free Software |
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
+ * |
+ * Author: Leonard Tracy <lentracy@gmail.com> |
+ */ |
+ |
+#include "uan-phy.h" |
+#include "uan-phy-dual.h" |
+#include "uan-phy-gen.h" |
+#include "uan-tx-mode.h" |
+#include "uan-net-device.h" |
+#include "uan-channel.h" |
+#include "ns3/double.h" |
+#include "ns3/log.h" |
+#include "ns3/ptr.h" |
+#include "ns3/traced-callback.h" |
+#include "ns3/trace-source-accessor.h" |
+#include "ns3/simulator.h" |
+#include "uan-header-common.h" |
+#include "uan-mac-rc.h" |
+ |
+#include <cmath> |
+ |
+ |
+NS_LOG_COMPONENT_DEFINE ("UanPhyDual"); |
+ |
+namespace ns3 { |
+ |
+NS_OBJECT_ENSURE_REGISTERED (UanPhyDual); |
+NS_OBJECT_ENSURE_REGISTERED (UanPhyCalcSinrDual); |
+ |
+UanPhyCalcSinrDual::UanPhyCalcSinrDual () |
+{ |
+ |
+} |
+UanPhyCalcSinrDual::~UanPhyCalcSinrDual () |
+{ |
+ |
+} |
+ |
+TypeId |
+UanPhyCalcSinrDual::GetTypeId (void) |
+{ |
+ static TypeId tid = TypeId ("ns3::UanPhyCalcSinrDual") |
+ .SetParent<Object> () |
+ .AddConstructor<UanPhyCalcSinrDual> () |
+ ; |
+ return tid; |
+} |
+ |
+double |
+UanPhyCalcSinrDual::CalcSinrDb (Ptr<Packet> pkt, |
+ Time arrTime, |
+ double rxPowerDb, |
+ double ambNoiseDb, |
+ UanTxMode mode, |
+ UanPdp pdp, |
+ const UanTransducer::ArrivalList &arrivalList) const |
+{ |
+ |
+ if (mode.GetModType () != UanTxMode::OTHER) |
+ { |
+ NS_LOG_WARN ("Calculating SINR for unsupported modulation type"); |
+ } |
+ |
+ double intKp = -DbToKp (rxPowerDb); // This packet is in the arrivalList |
+ UanTransducer::ArrivalList::const_iterator it = arrivalList.begin (); |
+ for (; it != arrivalList.end (); it++) |
+ { |
+ // Only count interference if there is overlap in incoming frequency |
+ if (std::abs ( (double) it->GetTxMode ().GetCenterFreqHz () - (double) mode.GetCenterFreqHz ()) |
+ < (double)(it->GetTxMode ().GetBandwidthHz () / 2 + mode.GetBandwidthHz () / 2) - 0.5) |
+ { |
+ UanHeaderCommon ch, ch2; |
+ if (pkt) |
+ { |
+ pkt->PeekHeader (ch); |
+ } |
+ it->GetPacket ()->PeekHeader (ch2); |
+ |
+ if (pkt) |
+ { |
+ if (ch.GetType () == UanMacRc::TYPE_DATA) |
+ { |
+ NS_LOG_DEBUG ("Adding interferer from " << ch2.GetSrc () << " against " << ch.GetSrc () << ": PktRxMode: " |
+ << mode.GetName () << " Int mode: " << it->GetTxMode ().GetName () << " Separation: " |
+ << std::abs ( (double) it->GetTxMode ().GetCenterFreqHz () - (double) mode.GetCenterFreqHz ()) |
+ << " Combined bandwidths: " << (double)(it->GetTxMode ().GetBandwidthHz () / 2 + mode.GetBandwidthHz () / 2) - 0.5); |
+ } |
+ } |
+ intKp += DbToKp (it->GetRxPowerDb ()); |
+ } |
+ } |
+ |
+ double totalIntDb = KpToDb (intKp + DbToKp (ambNoiseDb)); |
+ |
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Calculating SINR: RxPower = " << rxPowerDb << " dB. Number of interferers = " << arrivalList.size () << " Interference + noise power = " << totalIntDb << " dB. SINR = " << rxPowerDb - totalIntDb << " dB."); |
+ return rxPowerDb - totalIntDb; |
+} |
+ |
+UanPhyDual::UanPhyDual () |
+{ |
+ |
+ m_phy1 = CreateObject<UanPhyGen> (); |
+ m_phy2 = CreateObject<UanPhyGen> (); |
+ |
+ m_phy1->SetReceiveOkCallback (m_recOkCb); |
+ m_phy2->SetReceiveOkCallback (m_recOkCb); |
+ |
+ m_phy1->SetReceiveErrorCallback (m_recErrCb); |
+ m_phy2->SetReceiveErrorCallback (m_recErrCb); |
+ |
+} |
+ |
+UanPhyDual::~UanPhyDual () |
+{ |
+} |
+ |
+void |
+UanPhyDual::DoDispose () |
+{ |
+ // m_phy1->Dispose (); |
+ m_phy1 = 0; |
+ // m_phy2->Dispose (); |
+ m_phy2 = 0; |
+ // UanPhy::DoDispose (); |
+} |
+TypeId |
+UanPhyDual::GetTypeId (void) |
+{ |
+ static TypeId tid = TypeId ("ns3::UanPhyDual") |
+ .SetParent<UanPhy> () |
+ .AddConstructor<UanPhyDual> () |
+ .AddAttribute ("CcaThresholdPhy1", |
+ "Aggregate energy of incoming signals to move to CCA Busy state dB of Phy1", |
+ DoubleValue (10), |
+ MakeDoubleAccessor (&UanPhyDual::GetCcaThresholdPhy1, &UanPhyDual::SetCcaThresholdPhy1), |
+ MakeDoubleChecker<double> ()) |
+ .AddAttribute ("CcaThresholdPhy2", |
+ "Aggregate energy of incoming signals to move to CCA Busy state dB of Phy2", |
+ DoubleValue (10), |
+ MakeDoubleAccessor (&UanPhyDual::GetCcaThresholdPhy2, &UanPhyDual::SetCcaThresholdPhy2), |
+ MakeDoubleChecker<double> ()) |
+ .AddAttribute ("TxPowerPhy1", |
+ "Transmission output power in dB of Phy1", |
+ DoubleValue (190), |
+ MakeDoubleAccessor (&UanPhyDual::GetTxPowerDbPhy1, &UanPhyDual::SetTxPowerDbPhy1), |
+ MakeDoubleChecker<double> ()) |
+ .AddAttribute ("TxPowerPhy2", |
+ "Transmission output power in dB of Phy2", |
+ DoubleValue (190), |
+ MakeDoubleAccessor (&UanPhyDual::GetTxPowerDbPhy2, &UanPhyDual::SetTxPowerDbPhy2), |
+ MakeDoubleChecker<double> ()) |
+ .AddAttribute ("RxGainPhy1", |
+ "Gain added to incoming signal at receiver of Phy1", |
+ DoubleValue (0), |
+ MakeDoubleAccessor (&UanPhyDual::GetRxGainDbPhy1, &UanPhyDual::SetRxGainDbPhy1), |
+ MakeDoubleChecker<double> ()) |
+ .AddAttribute ("RxGainPhy2", |
+ "Gain added to incoming signal at receiver of Phy2", |
+ DoubleValue (0), |
+ MakeDoubleAccessor (&UanPhyDual::GetRxGainDbPhy2, &UanPhyDual::SetRxGainDbPhy2), |
+ MakeDoubleChecker<double> ()) |
+ .AddAttribute ("SupportedModesPhy1", |
+ "List of modes supported by Phy1", |
+ UanModesListValue (UanPhyGen::GetDefaultModes ()), |
+ MakeUanModesListAccessor (&UanPhyDual::GetModesPhy1, &UanPhyDual::SetModesPhy1), |
+ MakeUanModesListChecker () ) |
+ .AddAttribute ("SupportedModesPhy2", |
+ "List of modes supported by Phy2", |
+ UanModesListValue (UanPhyGen::GetDefaultModes ()), |
+ MakeUanModesListAccessor (&UanPhyDual::GetModesPhy2, &UanPhyDual::SetModesPhy2), |
+ MakeUanModesListChecker () ) |
+ .AddAttribute ("PerModelPhy1", |
+ "Functor to calculate PER based on SINR and TxMode for Phy1", |
+ PointerValue (CreateObject<UanPhyPerGenDefault> ()), |
+ MakePointerAccessor (&UanPhyDual::GetPerModelPhy1, &UanPhyDual::SetPerModelPhy1), |
+ MakePointerChecker<UanPhyPer> ()) |
+ .AddAttribute ("PerModelPhy2", |
+ "Functor to calculate PER based on SINR and TxMode for Phy2", |
+ PointerValue (CreateObject<UanPhyPerGenDefault> ()), |
+ MakePointerAccessor (&UanPhyDual::GetPerModelPhy2, &UanPhyDual::SetPerModelPhy2), |
+ MakePointerChecker<UanPhyPer> ()) |
+ .AddAttribute ("SinrModelPhy1", |
+ "Functor to calculate SINR based on pkt arrivals and modes for Phy1", |
+ PointerValue (CreateObject<UanPhyCalcSinrDual> ()), |
+ MakePointerAccessor (&UanPhyDual::GetSinrModelPhy1, &UanPhyDual::SetSinrModelPhy1), |
+ MakePointerChecker<UanPhyCalcSinr> ()) |
+ .AddAttribute ("SinrModelPhy2", |
+ "Functor to calculate SINR based on pkt arrivals and modes for Phy2", |
+ PointerValue (CreateObject<UanPhyCalcSinrDual> ()), |
+ MakePointerAccessor (&UanPhyDual::GetSinrModelPhy2, &UanPhyDual::SetSinrModelPhy2), |
+ MakePointerChecker<UanPhyCalcSinr> ()) |
+ .AddTraceSource ("RxOk", |
+ "A packet was received successfully", |
+ MakeTraceSourceAccessor (&UanPhyDual::m_rxOkLogger)) |
+ .AddTraceSource ("RxError", |
+ "A packet was received unsuccessfully", |
+ MakeTraceSourceAccessor (&UanPhyDual::m_rxErrLogger)) |
+ .AddTraceSource ("Tx", |
+ "Packet transmission beginning", |
+ MakeTraceSourceAccessor (&UanPhyDual::m_txLogger)) |
+ |
+ ; |
+ |
+ return tid; |
+} |
+ |
+void |
+UanPhyDual::SendPacket (Ptr<Packet> pkt, uint32_t modeNum) |
+{ |
+ if (modeNum <= m_phy1->GetNModes () - 1) |
+ { |
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Sending packet on Phy1 with mode number " << modeNum); |
+ m_txLogger (pkt, m_phy1->GetTxPowerDb (), m_phy1->GetMode (modeNum)); |
+ m_phy1->SendPacket (pkt, modeNum); |
+ |
+ } |
+ else |
+ { |
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Sending packet on Phy2 with mode number " << modeNum - m_phy1->GetNModes ()); |
+ m_txLogger (pkt, m_phy2->GetTxPowerDb (), m_phy2->GetMode (modeNum - m_phy1->GetNModes ())); |
+ m_phy2->SendPacket (pkt, modeNum - m_phy1->GetNModes ()); |
+ } |
+} |
+void |
+UanPhyDual::RegisterListener (UanPhyListener *listener) |
+{ |
+ m_phy1->RegisterListener (listener); |
+ m_phy2->RegisterListener (listener); |
+} |
+ |
+void |
+UanPhyDual::StartRxPacket (Ptr<Packet> pkt, double rxPowerDb, UanTxMode txMode, UanPdp pdp) |
+{ |
+ // Not called. StartRxPacket in m_phy1 and m_phy2 are called directly from Transducer. |
+} |
+ |
+void |
+UanPhyDual::SetReceiveOkCallback (RxOkCallback cb) |
+{ |
+ m_phy1->SetReceiveOkCallback (cb); |
+ m_phy2->SetReceiveOkCallback (cb); |
+} |
+ |
+void |
+UanPhyDual::SetReceiveErrorCallback (RxErrCallback cb) |
+{ |
+ m_phy1->SetReceiveErrorCallback (cb); |
+ m_phy2->SetReceiveErrorCallback (cb); |
+} |
+ |
+void |
+UanPhyDual::SetRxGainDb (double gain) |
+{ |
+ m_phy1->SetRxGainDb (gain); |
+ m_phy2->SetRxGainDb (gain); |
+} |
+void |
+UanPhyDual::SetRxGainDbPhy1 (double gain) |
+{ |
+ m_phy1->SetRxGainDb (gain); |
+} |
+ |
+void |
+UanPhyDual::SetRxGainDbPhy2 (double gain) |
+{ |
+ m_phy2->SetRxGainDb (gain); |
+} |
+ |
+void |
+UanPhyDual::SetTxPowerDb (double txpwr) |
+{ |
+ m_phy1->SetTxPowerDb (txpwr); |
+ m_phy2->SetTxPowerDb (txpwr); |
+} |
+ |
+void |
+UanPhyDual::SetTxPowerDbPhy1 (double txpwr) |
+{ |
+ m_phy1->SetTxPowerDb (txpwr); |
+} |
+void |
+UanPhyDual::SetTxPowerDbPhy2 (double txpwr) |
+{ |
+ m_phy2->SetTxPowerDb (txpwr); |
+} |
+ |
+void |
+UanPhyDual::SetRxThresholdDb (double thresh) |
+{ |
+ NS_LOG_WARN ("SetRxThresholdDb is deprecated and has no effect. Look at PER Functor attribute"); |
+ m_phy1->SetRxThresholdDb (thresh); |
+ m_phy2->SetRxThresholdDb (thresh); |
+} |
+void |
+UanPhyDual::SetCcaThresholdDb (double thresh) |
+{ |
+ m_phy1->SetCcaThresholdDb (thresh); |
+ m_phy2->SetCcaThresholdDb (thresh); |
+} |
+ |
+void |
+UanPhyDual::SetCcaThresholdPhy1 (double thresh) |
+{ |
+ m_phy1->SetCcaThresholdDb (thresh); |
+} |
+void |
+UanPhyDual::SetCcaThresholdPhy2 (double thresh) |
+{ |
+ m_phy2->SetCcaThresholdDb (thresh); |
+} |
+ |
+double |
+UanPhyDual::GetRxGainDb (void) |
+{ |
+ NS_LOG_WARN ("Warning: UanPhyDual::GetRxGainDb returns RxGain of Phy 1"); |
+ return m_phy1->GetRxGainDb (); |
+} |
+double |
+UanPhyDual::GetRxGainDbPhy1 (void) const |
+{ |
+ return m_phy1->GetRxGainDb (); |
+} |
+double |
+UanPhyDual::GetRxGainDbPhy2 (void) const |
+{ |
+ return m_phy2->GetRxGainDb (); |
+} |
+ |
+double |
+UanPhyDual::GetTxPowerDb (void) |
+{ |
+ NS_LOG_WARN ("Warning: Dual Phy only returns TxPowerDb of Phy 1"); |
+ return m_phy1->GetTxPowerDb (); |
+} |
+ |
+double |
+UanPhyDual::GetTxPowerDbPhy1 (void) const |
+{ |
+ return m_phy1->GetTxPowerDb (); |
+} |
+ |
+double |
+UanPhyDual::GetTxPowerDbPhy2 (void) const |
+{ |
+ return m_phy2->GetTxPowerDb (); |
+} |
+ |
+double |
+UanPhyDual::GetRxThresholdDb (void) |
+{ |
+ return m_phy1->GetRxThresholdDb (); |
+} |
+ |
+double |
+UanPhyDual::GetCcaThresholdDb (void) |
+{ |
+ NS_LOG_WARN ("Dual Phy only returns CCAThreshold of Phy 1"); |
+ return m_phy1->GetCcaThresholdDb (); |
+} |
+double |
+UanPhyDual::GetCcaThresholdPhy1 (void) const |
+{ |
+ return m_phy1->GetCcaThresholdDb (); |
+} |
+double |
+UanPhyDual::GetCcaThresholdPhy2 (void) const |
+{ |
+ return m_phy2->GetCcaThresholdDb (); |
+} |
+ |
+bool |
+UanPhyDual::IsPhy1Idle (void) |
+{ |
+ return m_phy1->IsStateIdle (); |
+} |
+bool |
+UanPhyDual::IsPhy2Idle (void) |
+{ |
+ return m_phy2->IsStateIdle (); |
+} |
+ |
+bool |
+UanPhyDual::IsPhy1Rx (void) |
+{ |
+ return m_phy1->IsStateRx (); |
+} |
+ |
+bool |
+UanPhyDual::IsPhy2Rx (void) |
+{ |
+ return m_phy2->IsStateRx (); |
+} |
+ |
+bool |
+UanPhyDual::IsPhy1Tx (void) |
+{ |
+ return m_phy1->IsStateTx (); |
+} |
+ |
+Ptr<Packet> |
+UanPhyDual::GetPhy1PacketRx (void) const |
+{ |
+ return m_phy1->GetPacketRx (); |
+} |
+ |
+Ptr<Packet> |
+UanPhyDual::GetPhy2PacketRx (void) const |
+{ |
+ return m_phy2->GetPacketRx (); |
+} |
+ |
+bool |
+UanPhyDual::IsPhy2Tx (void) |
+{ |
+ return m_phy2->IsStateTx (); |
+} |
+ |
+bool |
+UanPhyDual::IsStateIdle (void) |
+{ |
+ return m_phy1->IsStateIdle () && m_phy2->IsStateIdle (); |
+} |
+bool |
+UanPhyDual::IsStateBusy (void) |
+{ |
+ return !IsStateIdle (); |
+} |
+bool |
+UanPhyDual::IsStateRx (void) |
+{ |
+ return m_phy1->IsStateRx () || m_phy2->IsStateRx (); |
+} |
+bool |
+UanPhyDual::IsStateTx (void) |
+{ |
+ return m_phy1->IsStateTx () || m_phy2->IsStateTx (); |
+} |
+bool |
+UanPhyDual::IsStateCcaBusy (void) |
+{ |
+ return m_phy1->IsStateCcaBusy () || m_phy2->IsStateCcaBusy (); |
+} |
+Ptr<UanChannel> |
+UanPhyDual::GetChannel (void) const |
+{ |
+ return m_phy1->GetChannel (); |
+} |
+Ptr<UanNetDevice> |
+UanPhyDual::GetDevice (void) |
+{ |
+ return m_phy1->GetDevice (); |
+} |
+void |
+UanPhyDual::SetChannel (Ptr<UanChannel> channel) |
+{ |
+ m_phy1->SetChannel (channel); |
+ m_phy2->SetChannel (channel); |
+} |
+void |
+UanPhyDual::SetDevice (Ptr<UanNetDevice> device) |
+{ |
+ m_phy1->SetDevice (device); |
+ m_phy2->SetDevice (device); |
+} |
+void |
+UanPhyDual::SetMac (Ptr<UanMac> mac) |
+{ |
+ m_phy1->SetMac (mac); |
+ m_phy2->SetMac (mac); |
+} |
+void |
+UanPhyDual::NotifyTransStartTx (Ptr<Packet> packet, double txPowerDb, UanTxMode txMode) |
+{ |
+ |
+} |
+void |
+UanPhyDual::NotifyIntChange (void) |
+{ |
+ m_phy1->NotifyIntChange (); |
+ m_phy2->NotifyIntChange (); |
+ |
+} |
+void |
+UanPhyDual::SetTransducer (Ptr<UanTransducer> trans) |
+{ |
+ m_phy1->SetTransducer (trans); |
+ m_phy2->SetTransducer (trans); |
+} |
+Ptr<UanTransducer> |
+UanPhyDual::GetTransducer (void) |
+{ |
+ NS_LOG_WARN ("DualPhy Returning transducer of Phy1"); |
+ return m_phy1->GetTransducer (); |
+} |
+uint32_t |
+UanPhyDual::GetNModes (void) |
+{ |
+ return m_phy1->GetNModes () + m_phy2->GetNModes (); |
+} |
+UanTxMode |
+UanPhyDual::GetMode (uint32_t n) |
+{ |
+ if (n < m_phy1->GetNModes ()) |
+ { |
+ return m_phy1->GetMode (n); |
+ } |
+ else |
+ { |
+ return m_phy2->GetMode (n - m_phy1->GetNModes ()); |
+ } |
+} |
+ |
+UanModesList |
+UanPhyDual::GetModesPhy1 (void) const |
+{ |
+ |
+ UanModesListValue modeValue; |
+ m_phy1->GetAttribute ("SupportedModes", modeValue); |
+ return modeValue.Get (); |
+} |
+ |
+UanModesList |
+UanPhyDual::GetModesPhy2 (void) const |
+{ |
+ UanModesListValue modeValue; |
+ m_phy2->GetAttribute ("SupportedModes", modeValue); |
+ return modeValue.Get (); |
+} |
+ |
+void |
+UanPhyDual::SetModesPhy1 (UanModesList modes) |
+{ |
+ m_phy1->SetAttribute ("SupportedModes", UanModesListValue (modes)); |
+} |
+ |
+void |
+UanPhyDual::SetModesPhy2 (UanModesList modes) |
+{ |
+ m_phy2->SetAttribute ("SupportedModes", UanModesListValue (modes)); |
+} |
+ |
+Ptr<UanPhyPer> |
+UanPhyDual::GetPerModelPhy1 (void) const |
+{ |
+ PointerValue perValue; |
+ m_phy1->GetAttribute ("PerModel", perValue); |
+ return perValue; |
+} |
+ |
+Ptr<UanPhyPer> |
+UanPhyDual::GetPerModelPhy2 (void) const |
+{ |
+ PointerValue perValue; |
+ m_phy2->GetAttribute ("PerModel", perValue); |
+ return perValue; |
+} |
+ |
+void |
+UanPhyDual::SetPerModelPhy1 (Ptr<UanPhyPer> per) |
+{ |
+ m_phy1->SetAttribute ("PerModel", PointerValue (per)); |
+} |
+ |
+void |
+UanPhyDual::SetPerModelPhy2 (Ptr<UanPhyPer> per) |
+{ |
+ m_phy2->SetAttribute ("PerModel", PointerValue (per)); |
+} |
+ |
+Ptr<UanPhyCalcSinr> |
+UanPhyDual::GetSinrModelPhy1 (void) const |
+{ |
+ PointerValue sinrValue; |
+ m_phy1->GetAttribute ("SinrModel", sinrValue); |
+ return sinrValue; |
+} |
+ |
+Ptr<UanPhyCalcSinr> |
+UanPhyDual::GetSinrModelPhy2 (void) const |
+{ |
+ PointerValue sinrValue; |
+ m_phy2->GetAttribute ("SinrModel", sinrValue); |
+ return sinrValue; |
+} |
+ |
+void |
+UanPhyDual::SetSinrModelPhy1 (Ptr<UanPhyCalcSinr> sinr) |
+{ |
+ m_phy1->SetAttribute ("SinrModel", PointerValue (sinr)); |
+} |
+ |
+void |
+UanPhyDual::SetSinrModelPhy2 (Ptr<UanPhyCalcSinr> sinr) |
+{ |
+ m_phy2->SetAttribute ("SinrModel", PointerValue (sinr)); |
+} |
+ |
+void |
+UanPhyDual::RxOkFromSubPhy (Ptr<Packet> pkt, double sinr, UanTxMode mode) |
+{ |
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Received packet"); |
+ m_recOkCb (pkt, sinr, mode); |
+ m_rxOkLogger (pkt, sinr, mode); |
+} |
+ |
+void |
+UanPhyDual::RxErrFromSubPhy (Ptr<Packet> pkt, double sinr) |
+{ |
+ m_recErrCb (pkt, sinr); |
+ m_rxErrLogger (pkt, sinr, m_phy1->GetMode (0)); |
+} |
+ |
+Ptr<Packet> |
+UanPhyDual::GetPacketRx (void) const |
+{ |
+ NS_FATAL_ERROR ("GetPacketRx not valid for UanPhyDual. Must specify GetPhy1PacketRx or GetPhy2PacketRx"); |
+ return Create<Packet> (); |
+} |
+ |
+} |