/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ #include #include #include #include #include #include #include "mock-channel.h" namespace ns3 { NS_LOG_COMPONENT_DEFINE ("MockChannel"); NS_OBJECT_ENSURE_REGISTERED (MockChannel); TypeId MockChannel::GetTypeId (void) { static TypeId tid = TypeId ("ns3::MockChannel") .SetParent () .SetGroupName ("Leo") .AddAttribute ("PropagationDelay", "A propagation delay model for the channel.", PointerValue (), MakePointerAccessor (&MockChannel::m_propagationDelay), MakePointerChecker ()) .AddAttribute ("PropagationLoss", "A propagation loss model for the channel.", PointerValue (), MakePointerAccessor (&MockChannel::m_propagationLoss), MakePointerChecker ()) .AddTraceSource ("TxRxMockChannel", "Trace source indicating transmission of packet " "from the MockChannel, used by the Animation " "interface.", MakeTraceSourceAccessor (&MockChannel::m_txrxMock), "ns3::MockChannel::TxRxAnimationCallback") ; return tid; } // // By default, you get a channel that // has an "infitely" fast transmission speed and zero processing delay. MockChannel::MockChannel() : Channel (), m_link (0) { NS_LOG_FUNCTION_NOARGS (); } MockChannel::~MockChannel() { } bool MockChannel::Detach (uint32_t deviceId) { NS_LOG_FUNCTION (this << deviceId); if (deviceId < m_link.size ()) { if (!m_link[deviceId]->IsLinkUp ()) { NS_LOG_WARN ("MockChannel::Detach(): Device is already detached (" << deviceId << ")"); return false; } m_link[deviceId]->NotifyLinkDown (); } else { return false; } return true; } int32_t MockChannel::Attach (Ptr device) { NS_LOG_FUNCTION (this << device); NS_ASSERT (device != 0); m_link.push_back(device); return m_link.size() - 1; } std::size_t MockChannel::GetNDevices (void) const { NS_LOG_FUNCTION_NOARGS (); return m_link.size (); } Ptr MockChannel::GetDevice (std::size_t i) const { NS_LOG_FUNCTION_NOARGS (); return m_link[i]; } Time MockChannel::GetPropagationDelay (Ptr srcMob, Ptr dstMob, Time txTime) const { NS_LOG_FUNCTION (this << srcMob << dstMob << txTime); if (GetPropagationDelay ()) { Time propagationDelay = m_propagationDelay->GetDelay (srcMob, dstMob); return propagationDelay; } else { return Time (0); } } // TODO optimize Ptr MockChannel::GetDevice (Address &addr) const { for (Ptr dev : m_link) { if (dev->GetAddress () == addr) { return dev; } } return 0; } Ptr MockChannel::GetPropagationDelay () const { return m_propagationDelay; } Ptr MockChannel::GetPropagationLoss () const { return m_propagationLoss; } void MockChannel::SetPropagationLoss (Ptr model) { m_propagationLoss = model; } bool MockChannel::Deliver ( Ptr p, Ptr src, Ptr dst, Time txTime) { NS_LOG_FUNCTION (this << p << src->GetAddress () << dst->GetAddress () << txTime); Time delay = txTime; Ptr srcMob = src->GetNode ()->GetObject (); Ptr dstMob = dst->GetNode ()->GetObject (); double txPower = src->GetTxPower (); double rxPower = txPower; if (srcMob != 0 && dstMob != 0) { Ptr pLoss = GetPropagationLoss (); if (pLoss != 0) { // check if signal reaches destination rxPower = pLoss->CalcRxPower (txPower, srcMob, dstMob); if (rxPower < -900.0) { NS_LOG_WARN (this << "unable to reach destination " << dst->GetNode ()->GetId () << " from " << src->GetNode ()->GetId ()); return false; } } delay = GetPropagationDelay (srcMob, dstMob, txTime); NS_LOG_DEBUG ("delay = "<GetNode ()->GetId (), delay, &MockNetDevice::Receive, dst, p->Copy (), src, rxPower); // Call the tx anim callback on the net device m_txrxMock (p, src, dst, txTime, delay); return true; } void MockChannel::SetPropagationDelay (Ptr delay) { m_propagationDelay = delay; } } // namespace ns3