Files
eden-sim/contrib/tsn/model/tsn-multidrop-channel.cc

155 lines
3.7 KiB
C++
Raw Normal View History

2025-12-01 15:56:02 +01:00
#include "tsn-multidrop-channel.h"
#include "tsn-multidrop-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("TsnMultidropChannel");
NS_OBJECT_ENSURE_REGISTERED(TsnMultidropChannel);
TypeId
TsnMultidropChannel::GetTypeId()
{
static TypeId tid =
TypeId("ns3::TsnMultidropChannel")
.SetParent<Channel>()
.SetGroupName("Tsn")
.AddConstructor<TsnMultidropChannel>()
.AddAttribute("Delay",
"Propagation delay through the channel",
TimeValue(NanoSeconds(25)),
MakeTimeAccessor(&TsnMultidropChannel::m_delay),
MakeTimeChecker())
.AddTraceSource("TxRxEthernet",
"Trace source indicating transmission of packet "
"from the TsnMultidropChannel, used by the Animation "
"interface.",
MakeTraceSourceAccessor(&TsnMultidropChannel::m_txrxEthernet),
"ns3::TsnMultidropChannel::TxRxAnimationCallback");
return tid;
}
TsnMultidropChannel::TsnMultidropChannel()
: Channel()
{
NS_LOG_FUNCTION_NOARGS();
}
void
TsnMultidropChannel::Attach(Ptr<TsnMultidropNetDevice> device)
{
NS_LOG_FUNCTION(this << device);
NS_ASSERT(device);
NS_ASSERT(m_netDevices.size() < 255); //Limitation from IEEE802.3cg-2019
m_netDevices.insert(m_netDevices.end(), device);
//If we have two devices connected to the channel, the channel is usable
if (m_netDevices.size() >= 2)
{
m_wireState = IDLE;
}
}
bool
TsnMultidropChannel::TransmitStart(Ptr<const Packet> p, Ptr<TsnNetDevice> src, Time txTime)
{
NS_LOG_FUNCTION(this << p << src);
NS_LOG_LOGIC("UID is " << p->GetUid() << ")");
NS_ASSERT(m_wireState == IDLE);
for (std::size_t i = 0; i < m_netDevices.size(); ++i)
{
if(m_netDevices[i]!=src)
{
//Start of reception => Change PLCA state
m_netDevices[i]->StartReception();
//Schedule reception a the end of the transmission
Simulator::ScheduleWithContext(m_netDevices[i]->GetNode()->GetId(),
txTime + m_delay,
&TsnMultidropNetDevice::Receive,
m_netDevices[i],
p->Copy());
NS_LOG_INFO(txTime + m_delay);
}
}
// 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
TsnMultidropChannel::GetNDevices() const
{
NS_LOG_FUNCTION_NOARGS();
return m_netDevices.size();
}
Ptr<TsnNetDevice>
TsnMultidropChannel::GetEthernetDevice(std::size_t i) const
{
NS_LOG_FUNCTION_NOARGS();
NS_ASSERT(i < m_netDevices.size());
return m_netDevices[i];
}
Ptr<NetDevice>
TsnMultidropChannel::GetDevice(std::size_t i) const
{
NS_LOG_FUNCTION_NOARGS();
return GetEthernetDevice(i);
}
Time
TsnMultidropChannel::GetDelay() const
{
return m_delay;
}
bool
TsnMultidropChannel::IsInitialized() const
{
NS_ASSERT(m_wireState != INITIALIZING);
return true;
}
void
TsnMultidropChannel::StartBeaconTransmission()
{
NS_LOG_FUNCTION(this);
NS_ASSERT(m_wireState == IDLE);
m_wireState = TRANSMITTING;
for (std::size_t i = 0; i < m_netDevices.size(); ++i)
{
m_netDevices[i]->StartBeaconReception();
}
}
void
TsnMultidropChannel::StopBeaconTransmission()
{
NS_LOG_FUNCTION(this);
NS_ASSERT(m_wireState == TRANSMITTING);
m_wireState = IDLE;
for (std::size_t i = 0; i < m_netDevices.size(); ++i)
{
m_netDevices[i]->StopBeaconReception();
}
}
}