155 lines
3.7 KiB
C++
155 lines
3.7 KiB
C++
|
|
#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();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|