#include "evb-lan9668.h" #include "ns3/names.h" #include "ns3/drop-tail-queue.h" #include "ns3/cbs.h" #include "ns3/tas.h" namespace ns3 { NS_LOG_COMPONENT_DEFINE("EvbLan9668"); NS_OBJECT_ENSURE_REGISTERED(EvbLan9668); TypeId EvbLan9668::GetTypeId() { static TypeId tid = TypeId("ns3::EvbLan9668") .SetParent() .SetGroupName("real-device") .AddConstructor(); return tid; } EvbLan9668::EvbLan9668() { NS_LOG_FUNCTION(this); m_node = CreateObject(); m_node->AddClock(CreateObject()); //Add perfect clock for (int i=0; i net = CreateObject(); for (int j=0; j> q = CreateObject>(); q->SetAttribute("MaxSize", QueueSizeValue(m_fifoSize)); net->SetQueue(q); } m_node->AddDevice(net); m_net_devices.insert(m_net_devices.end(), net); } m_switch_net_device = CreateObject(); m_switch_net_device->SetAddress(Mac48Address::Allocate()); m_node->AddDevice(m_switch_net_device); for (int i = 0; i < (int)m_net_devices.size(); i++){ m_switch_net_device->AddSwitchPort(m_net_devices[i]); } m_node->AddDevice(m_switch_net_device); SetHardwareLimits(); } EvbLan9668::EvbLan9668(std::string name): EvbLan9668() { NS_LOG_FUNCTION(this); Names::Add(name, m_node); for (int i = 0; i < (int)m_net_devices.size(); i++){ Names::Add(name + "-" + std::to_string(i) , m_net_devices[i]); } } EvbLan9668::~EvbLan9668() { NS_LOG_FUNCTION(this); } void EvbLan9668::SetHardwareLimits() { NS_LOG_FUNCTION(this); //FDB m_switch_net_device->SetAttribute("MaxPortNumber", UintegerValue(m_portNumber)); m_switch_net_device->SetAttribute("MaxFdbEntryNumber", UintegerValue(m_maxFdbEntryNumber)); m_switch_net_device->SetAttribute("MinForwardingLatency", TimeValue(m_minForwardingLatency)); m_switch_net_device->SetAttribute("MaxForwardingLatency", TimeValue(m_maxForwardingLatency)); //TAS for (int i = 0; i < (int)m_net_devices.size(); i++){ m_net_devices[i]->GetTas()->SetAttribute("MaxGclEntryNumber", UintegerValue(m_maxGclEntryNumber)); m_net_devices[i]->GetTas()->SetAttribute("MaxGclCycleDuration", TimeValue(m_maxGclCycleDuration)); m_net_devices[i]->GetTas()->SetAttribute("MaxGclTimeInterval", TimeValue(m_maxGclTimeInterval)); } //Stream identification m_node->SetAttribute("MaxSidEntryNumber", UintegerValue(m_maxSidEntryNumber)); //PSFP m_node->SetAttribute("MaxPsfpFilterEntryNumber", UintegerValue(m_maxPsfpFilterEntryNumber)); m_node->SetAttribute("MaxPsfpStreamGateEntryNumber", UintegerValue(m_maxPsfpStreamGateEntryNumber)); m_node->SetAttribute("MaxPsfpFlowMeterEntryNumber", UintegerValue(m_maxPsfpFlowMeterEntryNumber)); //FRER m_node->SetAttribute("MaxFrerSeqGenEntryNumber", UintegerValue(m_maxFrerSeqGenEntryNumber)); m_node->SetAttribute("MaxFrerSeqRcvyEntryNumber", UintegerValue(m_maxFrerSeqRcvyEntryNumber)); m_node->SetAttribute("MaxFrerSeqEncEntryNumber", UintegerValue(m_maxFrerSeqEncEntryNumber)); } Ptr EvbLan9668::GetPort(int port_id) { NS_LOG_FUNCTION(this); NS_ASSERT(port_id < (int) m_net_devices.size()); return m_net_devices[port_id]; } void EvbLan9668::SetPortDatarate(int port_id, DataRate d) { NS_LOG_FUNCTION(this); NS_ASSERT_MSG(d == DataRate("10Mb/s") || d == DataRate("100Mb/s") || d == DataRate("1Gb/s"), "Trying to use a datarate not supported on this device (i.e 10Mb/s, 100Mb/s and 1Gb/s)"); GetPort(port_id)->SetAttribute("DataRate", DataRateValue(d)); } void EvbLan9668::AddForwardingTableEntry(Mac48Address dest, uint16_t vlan_id, std::vector output_port_ids){ NS_LOG_FUNCTION(this); std::vector> output_ports = {}; for (int i = 0; i < (int)output_port_ids.size(); i++){ output_ports.insert(output_ports.end(), GetPort(output_port_ids[i])); } m_switch_net_device->AddForwardingTableEntry(dest, vlan_id, output_ports); } void EvbLan9668::AddCbs(uint32_t port_id, uint32_t queue_id, DataRate iddle_slope, DataRate port_transmit_rate) { NS_LOG_FUNCTION(this); NS_ASSERT(queue_id < m_queuesPerPort); Ptr cbs = CreateObject(); cbs->SetTsnNetDevice(GetPort(port_id)); cbs->SetAttribute("IdleSlope", DataRateValue(iddle_slope)); cbs->SetAttribute("MaxIdleSlope", DataRateValue(m_maxIddleSlope)); cbs->SetAttribute("portTransmitRate", DataRateValue(port_transmit_rate)); cbs->SetAttribute("MinLatencyOverhead", TimeValue(m_minCBSLatencyOverhead)); cbs->SetAttribute("MaxLatencyOverhead", TimeValue(m_maxCBSLatencyOverhead)); Ptr> q = CreateObject>(); q->SetAttribute("MaxSize", QueueSizeValue(m_fifoSize)); GetPort(port_id)->UpdateQueue(queue_id, q, cbs); } void EvbLan9668::AddGclEntry(uint32_t port_id, Time interval, uint8_t state) { NS_LOG_FUNCTION(this); GetPort(port_id)->AddGclEntry(interval, state); } void EvbLan9668::StartTas() { NS_LOG_FUNCTION(this); for (int i = 0; i < (int)m_net_devices.size(); i++){ m_net_devices[i]->StartTas(); } } void EvbLan9668::AddNullStreamIdentificationFunction( uint32_t streamHandle, Ptr streamIdentificationFunction, std::vector outFacInputPortIds, std::vector inFacInputPortIds, std::vector inFacOutputPortIds, std::vector outFacOutputPortIds) { NS_LOG_FUNCTION(this); std::vector> outFacInputPortList = {}; for (int i = 0; i < (int)outFacInputPortIds.size(); i++){ outFacInputPortList.insert(outFacInputPortList.end(), GetPort(outFacInputPortIds[i])); } std::vector> inFacInputPortList = {}; for (int i = 0; i < (int)inFacInputPortIds.size(); i++){ inFacInputPortList.insert(inFacInputPortList.end(), GetPort(inFacInputPortIds[i])); } std::vector> inFacOutputPortList = {}; for (int i = 0; i < (int)inFacOutputPortIds.size(); i++){ inFacOutputPortList.insert(inFacOutputPortList.end(), GetPort(inFacOutputPortIds[i])); } std::vector> outFacOutputPortList = {}; for (int i = 0; i < (int)outFacOutputPortIds.size(); i++){ outFacOutputPortList.insert(outFacOutputPortList.end(), GetPort(outFacOutputPortIds[i])); } streamIdentificationFunction->SetAttribute("MinLatencyOverhead", TimeValue(m_minNullSIDLatencyOverhead)); streamIdentificationFunction->SetAttribute("MaxLatencyOverhead", TimeValue(m_maxNullSIDLatencyOverhead)); m_node->AddStreamIdentificationFunction( streamHandle, streamIdentificationFunction, outFacInputPortList, inFacInputPortList, inFacOutputPortList, outFacOutputPortList); } void EvbLan9668::AddStreamFilter(Ptr streamFilterInstance) { NS_LOG_FUNCTION(this); m_node->AddStreamFilter(streamFilterInstance); } uint16_t EvbLan9668::AddFlowMeter(Ptr flowMeterInstance) { NS_LOG_FUNCTION(this); return m_node->AddFlowMeter(flowMeterInstance); } void EvbLan9668::AddSequenceGenerationFunction(Ptr entry) { NS_LOG_FUNCTION(this); m_node->AddSequenceGenerationFunction(entry); } void EvbLan9668::AddSequenceRecoveryFunction(Ptr rcvy, Ptr algo, Ptr lat, std::vector port_ids) { NS_LOG_FUNCTION(this); rcvy->SetAttribute("MinLatencyOverhead", TimeValue(m_minFrerRcvyLatencyOverhead)); rcvy->SetAttribute("MaxLatencyOverhead", TimeValue(m_maxFrerRcvyLatencyOverhead)); algo->SetAttribute("MinResetTimer", TimeValue(m_minFrerSeqRcvyResetDuration)); algo->SetAttribute("MaxResetTimer", TimeValue(m_maxFrerSeqRcvyResetDuration)); lat->SetAttribute("MinTestTimer", TimeValue(m_minFrerLatErrorTestDuration)); lat->SetAttribute("MaxTestTimer", TimeValue(m_maxFrerLatErrorTestDuration)); lat->SetAttribute("MinResetTimer", TimeValue(m_minFrerLatErrorResetDuration)); lat->SetAttribute("MaxResetTimer", TimeValue(m_maxFrerLatErrorResetDuration)); std::vector> ports = {}; for (int i = 0; i < (int)port_ids.size(); i++){ ports.insert(ports.end(), GetPort(port_ids[i])); } rcvy->SetPorts(ports); rcvy->SetRecoveryFunction(algo); lat->SetRecoveryFunction(algo); rcvy->SetLatentErrorDetectionFunction(lat); m_node->AddSequenceRecoveryFunction(rcvy); } void EvbLan9668::AddSequenceEncodeDecodeFunction(Ptr entry, uint32_t port_id) { NS_LOG_FUNCTION(this); entry->SetPort(GetPort(port_id)); m_node->AddSequenceEncodeDecodeFunction(entry); } }