#include "ethernet-channel.h" #include "ethernet-net-device.h" #include "ns3/log.h" #include "ns3/packet.h" #include "ns3/simulator.h" #include "ns3/trace-source-accessor.h" namespace ns3 { NS_LOG_COMPONENT_DEFINE("EthernetChannel"); NS_OBJECT_ENSURE_REGISTERED(EthernetChannel); TypeId EthernetChannel::GetTypeId() { static TypeId tid = TypeId("ns3::EthernetChannel") .SetParent() .SetGroupName("Ethernet") .AddConstructor() .AddAttribute("Delay", "Propagation delay through the channel", TimeValue(NanoSeconds(25)), MakeTimeAccessor(&EthernetChannel::m_delay), MakeTimeChecker()) .AddTraceSource("TxRxEthernet", "Trace source indicating transmission of packet " "from the EthernetChannel, used by the Animation " "interface.", MakeTraceSourceAccessor(&EthernetChannel::m_txrxEthernet), "ns3::EthernetChannel::TxRxAnimationCallback"); return tid; } EthernetChannel::EthernetChannel() : Channel(), m_nDevices(0) { NS_LOG_FUNCTION_NOARGS(); } void EthernetChannel::Attach(Ptr device) { NS_LOG_FUNCTION(this << device); NS_ASSERT_MSG(m_nDevices < N_DEVICES, "Only two devices permitted"); NS_ASSERT(device); m_wire[m_nDevices++].m_src = device; // // If we have both devices connected to the channel, then finish introducing // the two halves and set the links to IDLE. // if (m_nDevices == N_DEVICES) { m_wire[0].m_dst = m_wire[1].m_src; m_wire[1].m_dst = m_wire[0].m_src; m_wire[0].m_state = IDLE; m_wire[1].m_state = IDLE; } } bool EthernetChannel::TransmitStart(Ptr p, Ptr src, Time txTime) { NS_LOG_FUNCTION(this << p << src); NS_LOG_LOGIC("UID is " << p->GetUid() << ")"); NS_ASSERT(m_wire[0].m_state != INITIALIZING); NS_ASSERT(m_wire[1].m_state != INITIALIZING); uint32_t wire = src == m_wire[0].m_src ? 0 : 1; Simulator::ScheduleWithContext(m_wire[wire].m_dst->GetNode()->GetId(), txTime + m_delay, &EthernetNetDevice::Receive, m_wire[wire].m_dst, p->Copy()); // Call the tx anim callback on the net device m_txrxEthernet(p, src, m_wire[wire].m_dst, txTime, txTime + m_delay); return true; } std::size_t EthernetChannel::GetNDevices() const { NS_LOG_FUNCTION_NOARGS(); return m_nDevices; } Ptr EthernetChannel::GetEthernetDevice(std::size_t i) const { NS_LOG_FUNCTION_NOARGS(); NS_ASSERT(i < 2); return m_wire[i].m_src; } Ptr EthernetChannel::GetDevice(std::size_t i) const { NS_LOG_FUNCTION_NOARGS(); return GetEthernetDevice(i); } Time EthernetChannel::GetDelay() const { return m_delay; } Ptr EthernetChannel::GetSource(uint32_t i) const { return m_wire[i].m_src; } Ptr EthernetChannel::GetDestination(uint32_t i) const { return m_wire[i].m_dst; } bool EthernetChannel::IsInitialized() const { NS_ASSERT(m_wire[0].m_state != INITIALIZING); NS_ASSERT(m_wire[1].m_state != INITIALIZING); return true; } }