Update README and add contrib dir
This commit is contained in:
24
contrib/real-device/CMakeLists.txt
Normal file
24
contrib/real-device/CMakeLists.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
check_include_file_cxx(stdint.h HAVE_STDINT_H)
|
||||
if(HAVE_STDINT_H)
|
||||
add_definitions(-DHAVE_STDINT_H)
|
||||
endif()
|
||||
|
||||
set(examples_as_tests_sources)
|
||||
if(${ENABLE_EXAMPLES})
|
||||
set(examples_as_tests_sources
|
||||
#test/real-device-examples-test-suite.cc
|
||||
)
|
||||
endif()
|
||||
|
||||
build_lib(
|
||||
LIBNAME real-device
|
||||
SOURCE_FILES model/evb-lan9668.cc
|
||||
helper/real-device-helper.cc
|
||||
HEADER_FILES model/evb-lan9668.h
|
||||
helper/real-device-helper.h
|
||||
LIBRARIES_TO_LINK ${libcore}
|
||||
${libethernet}
|
||||
${libtsn}
|
||||
TEST_SOURCES test/real-device-test-suite.cc
|
||||
${examples_as_tests_sources}
|
||||
)
|
||||
22
contrib/real-device/examples/CMakeLists.txt
Normal file
22
contrib/real-device/examples/CMakeLists.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
set(base_examples
|
||||
evb-lan9668-sp
|
||||
evb-lan9668-cbs
|
||||
evb-lan9668-tas
|
||||
evb-lan9668-psfp
|
||||
evb-lan9668-frer
|
||||
)
|
||||
foreach(
|
||||
example
|
||||
${base_examples}
|
||||
)
|
||||
build_lib_example(
|
||||
NAME ${example}
|
||||
SOURCE_FILES ${example}.cc
|
||||
LIBRARIES_TO_LINK ${libtsn}
|
||||
${libcore}
|
||||
${libnetwork}
|
||||
${libtraffic-generator}
|
||||
${libethernet}
|
||||
${libreal-device}
|
||||
)
|
||||
endforeach()
|
||||
158
contrib/real-device/examples/evb-lan9668-cbs.cc
Normal file
158
contrib/real-device/examples/evb-lan9668-cbs.cc
Normal file
@@ -0,0 +1,158 @@
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/applications-module.h"
|
||||
#include "ns3/command-line.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/drop-tail-queue.h"
|
||||
#include "ns3/timestamp-tag.h"
|
||||
#include "ns3/trace-helper.h"
|
||||
#include <fstream>
|
||||
|
||||
#include "ns3/tsn-node.h"
|
||||
#include "ns3/tsn-net-device.h"
|
||||
#include "ns3/switch-net-device.h"
|
||||
#include "ns3/ethernet-channel.h"
|
||||
#include "ns3/ethernet-generator.h"
|
||||
#include "ns3/ethernet-header2.h"
|
||||
|
||||
#include "ns3/evb-lan9668.h"
|
||||
#include "ns3/stream-identification-function-null.h"
|
||||
#include "ns3/frer-match-recovery-function.h"
|
||||
#include "ns3/frer-vector-recovery-function.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Example with 4ES connected to 1SW in a 1Gb/s full duplex link as follow.
|
||||
* ES1 === \ / === ES2
|
||||
* SW
|
||||
* ES3 === / \ === ES4
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE("Example");
|
||||
|
||||
|
||||
//A callback to log the pkt reception
|
||||
static void
|
||||
MacRxCallback(std::string context, Ptr<const Packet> p)
|
||||
{
|
||||
NS_LOG_INFO((Simulator::Now()).As(Time::S) << " \t" << context << " : Pkt #" << p->GetUid() << " received !");
|
||||
}
|
||||
|
||||
//A callback to log the pkt emission
|
||||
static void
|
||||
PhyTxCallback(std::string context, Ptr<const Packet> p)
|
||||
{
|
||||
NS_LOG_INFO((Simulator::Now()).As(Time::S) << " \t" << context << " : Pkt #" << p->GetUid() << " begin transmission !");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
//Enable logging
|
||||
LogComponentEnable("Example", LOG_LEVEL_INFO);
|
||||
LogComponentEnable("EthernetGenerator", LOG_LEVEL_INFO);
|
||||
LogComponentEnable("EvbLan9668", LOG_LEVEL_INFO);
|
||||
LogComponentEnable("TsnNetDevice", LOG_LEVEL_INFO);
|
||||
|
||||
CommandLine cmd(__FILE__);
|
||||
cmd.Parse(argc, argv);
|
||||
|
||||
//Create four end stations
|
||||
Ptr<TsnNode> n1 = CreateObject<TsnNode>();
|
||||
Names::Add("ES1", n1);
|
||||
Ptr<TsnNode> n2 = CreateObject<TsnNode>();
|
||||
Names::Add("ES2", n2);
|
||||
Ptr<TsnNode> n3 = CreateObject<TsnNode>();
|
||||
Names::Add("ES3", n3);
|
||||
Ptr<TsnNode> n4 = CreateObject<TsnNode>();
|
||||
Names::Add("ES4", n4);
|
||||
|
||||
//Create and add a netDevices to each end station
|
||||
Ptr<TsnNetDevice> net1 = CreateObject<TsnNetDevice>();
|
||||
n1->AddDevice(net1);
|
||||
Names::Add("ES1e#01", net1);
|
||||
Ptr<TsnNetDevice> net2 = CreateObject<TsnNetDevice>();
|
||||
n2->AddDevice(net2);
|
||||
Names::Add("ES2#01", net2);
|
||||
Ptr<TsnNetDevice> net3 = CreateObject<TsnNetDevice>();
|
||||
n3->AddDevice(net3);
|
||||
Names::Add("ES3#01", net3);
|
||||
Ptr<TsnNetDevice> net4 = CreateObject<TsnNetDevice>();
|
||||
n4->AddDevice(net4);
|
||||
Names::Add("ES4#01", net4);
|
||||
|
||||
//Allocate a Mac address to the end station
|
||||
net1->SetAddress(Mac48Address::Allocate());
|
||||
net2->SetAddress(Mac48Address::Allocate());
|
||||
net3->SetAddress(Mac48Address::Allocate());
|
||||
net4->SetAddress(Mac48Address::Allocate());
|
||||
|
||||
//Create the switch
|
||||
Ptr<EvbLan9668> lan9668 = CreateObject<EvbLan9668>("SW");
|
||||
lan9668->AddCbs(2, 4, DataRate("1Mb/s"), DataRate("1Gb/s")); //(uint32_t port_id, uint32_t queue_id, DataRate iddle_slope, DataRate port_transmit_rate)
|
||||
|
||||
|
||||
//Create Ethernet Channels and attach it to the netDevices
|
||||
Ptr<EthernetChannel> l0 = CreateObject<EthernetChannel>();
|
||||
l0->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net1->Attach(l0);
|
||||
lan9668->GetPort(1)->Attach(l0);
|
||||
Ptr<EthernetChannel> l1 = CreateObject<EthernetChannel>();
|
||||
l1->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net2->Attach(l1);
|
||||
lan9668->GetPort(2)->Attach(l1);
|
||||
Ptr<EthernetChannel> l2 = CreateObject<EthernetChannel>();
|
||||
l2->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net3->Attach(l2);
|
||||
lan9668->GetPort(3)->Attach(l2);
|
||||
Ptr<EthernetChannel> l3 = CreateObject<EthernetChannel>();
|
||||
l3->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net4->Attach(l3);
|
||||
lan9668->GetPort(4)->Attach(l3);
|
||||
|
||||
|
||||
//Create and add eight FIFO on each end station net device
|
||||
for (int i=0; i<8; i++)
|
||||
{
|
||||
net1->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
net2->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
net3->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
net4->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
}
|
||||
|
||||
//Add forwarding table entry
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net2->GetAddress()), 10, {2});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address("ff:ff:ff:ff:ff:ff"), 10, {2, 3, 4});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net1->GetAddress()), 11, {1});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net4->GetAddress()), 12, {4});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net2->GetAddress()), 13, {2});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net2->GetAddress()), 14, {2});
|
||||
|
||||
//Application description
|
||||
Ptr<EthernetGenerator> app0 = CreateObject<EthernetGenerator>();
|
||||
app0->Setup(net1);
|
||||
app0->SetAttribute("BurstSize", UintegerValue(3));
|
||||
app0->SetAttribute("PayloadSize", UintegerValue(1478));
|
||||
app0->SetAttribute("Period", TimeValue(MilliSeconds(100)));
|
||||
app0->SetAttribute("PCP", UintegerValue(4));
|
||||
app0->SetAttribute("VlanID", UintegerValue(10));
|
||||
app0->SetAttribute("Address", AddressValue(Mac48Address::ConvertFrom(net2->GetAddress())));
|
||||
n1->AddApplication(app0);
|
||||
app0->SetStartTime(MilliSeconds(0));
|
||||
app0->SetStopTime(MilliSeconds(200));
|
||||
|
||||
//Callback to display the packet transmitted and received log
|
||||
net1->TraceConnectWithoutContext("PhyTxBegin", MakeBoundCallback(&PhyTxCallback, Names::FindName(n1) + ":" + Names::FindName(net1)));
|
||||
net2->TraceConnectWithoutContext("MacRx", MakeBoundCallback(&MacRxCallback, Names::FindName(n2) + ":" + Names::FindName(net2)));
|
||||
|
||||
//Execute the simulation
|
||||
Simulator::Stop(MilliSeconds(300));
|
||||
Simulator::Run();
|
||||
Simulator::Destroy();
|
||||
return 0;
|
||||
}
|
||||
217
contrib/real-device/examples/evb-lan9668-frer.cc
Normal file
217
contrib/real-device/examples/evb-lan9668-frer.cc
Normal file
@@ -0,0 +1,217 @@
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/applications-module.h"
|
||||
#include "ns3/command-line.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/drop-tail-queue.h"
|
||||
#include "ns3/timestamp-tag.h"
|
||||
#include "ns3/trace-helper.h"
|
||||
#include <fstream>
|
||||
|
||||
#include "ns3/tsn-node.h"
|
||||
#include "ns3/tsn-net-device.h"
|
||||
#include "ns3/switch-net-device.h"
|
||||
#include "ns3/ethernet-channel.h"
|
||||
#include "ns3/ethernet-generator.h"
|
||||
#include "ns3/ethernet-header2.h"
|
||||
|
||||
#include "ns3/evb-lan9668.h"
|
||||
#include "ns3/stream-identification-function-null.h"
|
||||
#include "ns3/frer-match-recovery-function.h"
|
||||
#include "ns3/frer-vector-recovery-function.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Example with 4ES connected to 2SW in a 1Gb/s full duplex link as follow.
|
||||
* ES1 === \ /===\ / === ES2
|
||||
* SW1 SW2
|
||||
* ES3 === / \===/ \ === ES4
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE("Example");
|
||||
|
||||
|
||||
//A callback to log the pkt reception
|
||||
static void
|
||||
MacRxCallback(std::string context, Ptr<const Packet> p)
|
||||
{
|
||||
NS_LOG_INFO((Simulator::Now()).As(Time::S) << " \t" << context << " : Pkt #" << p->GetUid() << " received !");
|
||||
}
|
||||
|
||||
//A callback to log the pkt emission
|
||||
static void
|
||||
PhyTxCallback(std::string context, Ptr<const Packet> p)
|
||||
{
|
||||
NS_LOG_INFO((Simulator::Now()).As(Time::S) << " \t" << context << " : Pkt #" << p->GetUid() << " begin transmission !");
|
||||
}
|
||||
|
||||
//A callback to log pkt elimination due to FRER
|
||||
static void
|
||||
FrerDrop(std::string context, Ptr<const Packet> p)
|
||||
{
|
||||
NS_LOG_INFO(context << " : An instance of Packet #"<< p->GetUid() <<" was dropped by FRER recovery function");
|
||||
}
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
//Enable logging
|
||||
LogComponentEnable("Example", LOG_LEVEL_INFO);
|
||||
LogComponentEnable("EthernetGenerator", LOG_LEVEL_INFO);
|
||||
LogComponentEnable("EvbLan9668", LOG_LEVEL_INFO);
|
||||
LogComponentEnable("TsnNetDevice", LOG_LEVEL_INFO);
|
||||
|
||||
CommandLine cmd(__FILE__);
|
||||
cmd.Parse(argc, argv);
|
||||
|
||||
//Create four end stations
|
||||
Ptr<TsnNode> n1 = CreateObject<TsnNode>();
|
||||
Names::Add("ES1", n1);
|
||||
Ptr<TsnNode> n2 = CreateObject<TsnNode>();
|
||||
Names::Add("ES2", n2);
|
||||
Ptr<TsnNode> n3 = CreateObject<TsnNode>();
|
||||
Names::Add("ES3", n3);
|
||||
Ptr<TsnNode> n4 = CreateObject<TsnNode>();
|
||||
Names::Add("ES4", n4);
|
||||
|
||||
//Create and add a netDevices to each end station
|
||||
Ptr<TsnNetDevice> net1 = CreateObject<TsnNetDevice>();
|
||||
n1->AddDevice(net1);
|
||||
Names::Add("ES1e#01", net1);
|
||||
Ptr<TsnNetDevice> net2 = CreateObject<TsnNetDevice>();
|
||||
n2->AddDevice(net2);
|
||||
Names::Add("ES2#01", net2);
|
||||
Ptr<TsnNetDevice> net3 = CreateObject<TsnNetDevice>();
|
||||
n3->AddDevice(net3);
|
||||
Names::Add("ES3#01", net3);
|
||||
Ptr<TsnNetDevice> net4 = CreateObject<TsnNetDevice>();
|
||||
n4->AddDevice(net4);
|
||||
Names::Add("ES4#01", net4);
|
||||
|
||||
//Allocate a Mac address to the end station
|
||||
net1->SetAddress(Mac48Address::Allocate());
|
||||
net2->SetAddress(Mac48Address::Allocate());
|
||||
net3->SetAddress(Mac48Address::Allocate());
|
||||
net4->SetAddress(Mac48Address::Allocate());
|
||||
|
||||
//Create the switch
|
||||
Ptr<EvbLan9668> lan9668_1 = CreateObject<EvbLan9668>("SW1");
|
||||
Ptr<EvbLan9668> lan9668_2 = CreateObject<EvbLan9668>("SW2");
|
||||
|
||||
//Create Ethernet Channels and attach it to the netDevices
|
||||
Ptr<EthernetChannel> l0 = CreateObject<EthernetChannel>();
|
||||
l0->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net1->Attach(l0);
|
||||
lan9668_1->GetPort(1)->Attach(l0);
|
||||
Ptr<EthernetChannel> l1 = CreateObject<EthernetChannel>();
|
||||
l1->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net2->Attach(l1);
|
||||
lan9668_2->GetPort(2)->Attach(l1);
|
||||
Ptr<EthernetChannel> l2 = CreateObject<EthernetChannel>();
|
||||
l2->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net3->Attach(l2);
|
||||
lan9668_2->GetPort(1)->Attach(l2);
|
||||
Ptr<EthernetChannel> l3 = CreateObject<EthernetChannel>();
|
||||
l3->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net4->Attach(l3);
|
||||
lan9668_1->GetPort(2)->Attach(l3);
|
||||
Ptr<EthernetChannel> l4 = CreateObject<EthernetChannel>();
|
||||
l4->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
lan9668_1->GetPort(3)->Attach(l4);
|
||||
lan9668_2->GetPort(3)->Attach(l4);
|
||||
Ptr<EthernetChannel> l5 = CreateObject<EthernetChannel>();
|
||||
l5->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
lan9668_1->GetPort(4)->Attach(l5);
|
||||
lan9668_2->GetPort(4)->Attach(l5);
|
||||
|
||||
|
||||
//Create and add eight FIFO on each end station net device
|
||||
for (int i=0; i<8; i++)
|
||||
{
|
||||
net1->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
net2->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
net3->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
net4->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
}
|
||||
|
||||
//Add forwarding table entry
|
||||
lan9668_1->AddForwardingTableEntry(Mac48Address::ConvertFrom(net2->GetAddress()), 10, {3,4});
|
||||
lan9668_2->AddForwardingTableEntry(Mac48Address::ConvertFrom(net2->GetAddress()), 10, {2});
|
||||
|
||||
|
||||
//SW1 Stream identification and FRER configuration (replication)
|
||||
//Stream identification
|
||||
uint32_t streamHandle = 1;
|
||||
Ptr<NullStreamIdentificationFunction> sif0 = CreateObject<NullStreamIdentificationFunction>();
|
||||
sif0->SetAttribute("VlanID", UintegerValue(10));
|
||||
sif0->SetAttribute("Address", AddressValue(Mac48Address::ConvertFrom(net2->GetAddress())));
|
||||
lan9668_1->AddNullStreamIdentificationFunction(streamHandle, sif0, {1}, {}, {}, {});
|
||||
//Sequencing : Sequence generation
|
||||
Ptr<SequenceGenerationFunction> seqf0 = CreateObject<SequenceGenerationFunction>();
|
||||
seqf0->SetAttribute("Direction", BooleanValue(false)); //in-facing
|
||||
seqf0->SetStreamHandle({streamHandle});
|
||||
lan9668_1->AddSequenceGenerationFunction(seqf0);
|
||||
//Sequence encode
|
||||
Ptr<SequenceEncodeDecodeFunction> seqEnc0 = CreateObject<SequenceEncodeDecodeFunction>();
|
||||
seqEnc0->SetAttribute("Direction", BooleanValue(false)); //in-facing
|
||||
seqEnc0->SetAttribute("Active", BooleanValue(true));
|
||||
seqEnc0->SetStreamHandle({streamHandle});
|
||||
lan9668_1->AddSequenceEncodeDecodeFunction(seqEnc0, 1);
|
||||
|
||||
|
||||
//SW2 Stream identification adn FRER configuration (elimination)
|
||||
//Stream identification
|
||||
Ptr<NullStreamIdentificationFunction> sif1 = CreateObject<NullStreamIdentificationFunction>();
|
||||
sif1->SetAttribute("VlanID", UintegerValue(10));
|
||||
sif1->SetAttribute("Address", AddressValue(Mac48Address::ConvertFrom(net2->GetAddress())));
|
||||
lan9668_2->AddNullStreamIdentificationFunction(streamHandle, sif1, {}, {}, {2}, {});
|
||||
//Sequence Decode
|
||||
Ptr<SequenceEncodeDecodeFunction> seqEnc1 = CreateObject<SequenceEncodeDecodeFunction>();
|
||||
seqEnc1->SetAttribute("Direction", BooleanValue(false)); //in-facing
|
||||
seqEnc1->SetAttribute("Active", BooleanValue(false));
|
||||
seqEnc1->SetStreamHandle({streamHandle});
|
||||
lan9668_2->AddSequenceEncodeDecodeFunction(seqEnc1, 2);
|
||||
//Sequencing : Sequence recovery
|
||||
Ptr<SequenceRecoveryFunction> seqfreco0 = CreateObject<SequenceRecoveryFunction>();
|
||||
seqfreco0->SetAttribute("Direction", BooleanValue(false)); //in-facing
|
||||
seqfreco0->SetAttribute("TakeNoSequence", BooleanValue(false));
|
||||
seqfreco0->SetAttribute("IndividualRecovery", BooleanValue(false));
|
||||
seqfreco0->SetStreamHandle({streamHandle});
|
||||
//Sequencing : Sequence recovery : recovery function
|
||||
Ptr<MatchRecoveryFunction> recf0 = CreateObject<MatchRecoveryFunction>();
|
||||
recf0->SetAttribute("ResetTimer", TimeValue(Seconds(1)));
|
||||
//Sequencing : Sequence recovery : latent error detection function
|
||||
Ptr<LatentErrorDetectionFunction> latf0 = CreateObject<LatentErrorDetectionFunction>();
|
||||
latf0->SetAttribute("LatentErrorPaths", UintegerValue(2));
|
||||
lan9668_2->AddSequenceRecoveryFunction(seqfreco0, recf0, latf0, {2});
|
||||
|
||||
//Application description
|
||||
Ptr<EthernetGenerator> app0 = CreateObject<EthernetGenerator>();
|
||||
app0->Setup(net1);
|
||||
app0->SetAttribute("BurstSize", UintegerValue(1));
|
||||
app0->SetAttribute("PayloadSize", UintegerValue(1478));
|
||||
app0->SetAttribute("Period", TimeValue(MilliSeconds(100)));
|
||||
app0->SetAttribute("PCP", UintegerValue(4));
|
||||
app0->SetAttribute("VlanID", UintegerValue(10));
|
||||
app0->SetAttribute("Address", AddressValue(Mac48Address::ConvertFrom(net2->GetAddress())));
|
||||
n1->AddApplication(app0);
|
||||
app0->SetStartTime(MilliSeconds(0));
|
||||
app0->SetStopTime(MilliSeconds(200));
|
||||
|
||||
//Callback to display the packet transmitted and received log
|
||||
net1->TraceConnectWithoutContext("PhyTxBegin", MakeBoundCallback(&PhyTxCallback, Names::FindName(n1) + ":" + Names::FindName(net1)));
|
||||
net2->TraceConnectWithoutContext("MacRx", MakeBoundCallback(&MacRxCallback, Names::FindName(n2) + ":" + Names::FindName(net2)));
|
||||
|
||||
//Callback to display elimination event
|
||||
lan9668_2->GetPort(2)->TraceConnectWithoutContext("FrerDrop", MakeBoundCallback(&FrerDrop, Names::FindName(lan9668_2->GetPort(2))));
|
||||
|
||||
//Execute the simulation
|
||||
Simulator::Stop(MilliSeconds(300));
|
||||
Simulator::Run();
|
||||
Simulator::Destroy();
|
||||
return 0;
|
||||
}
|
||||
194
contrib/real-device/examples/evb-lan9668-psfp.cc
Normal file
194
contrib/real-device/examples/evb-lan9668-psfp.cc
Normal file
@@ -0,0 +1,194 @@
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/applications-module.h"
|
||||
#include "ns3/command-line.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/drop-tail-queue.h"
|
||||
#include "ns3/timestamp-tag.h"
|
||||
#include "ns3/trace-helper.h"
|
||||
#include <fstream>
|
||||
|
||||
#include "ns3/tsn-node.h"
|
||||
#include "ns3/tsn-net-device.h"
|
||||
#include "ns3/switch-net-device.h"
|
||||
#include "ns3/ethernet-channel.h"
|
||||
#include "ns3/ethernet-generator.h"
|
||||
#include "ns3/ethernet-header2.h"
|
||||
|
||||
#include "ns3/evb-lan9668.h"
|
||||
#include "ns3/stream-identification-function-null.h"
|
||||
#include "ns3/frer-match-recovery-function.h"
|
||||
#include "ns3/frer-vector-recovery-function.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Example with 4ES connected to 1SW in a 1Gb/s full duplex link as follow.
|
||||
* ES1 === \ / === ES2
|
||||
* SW
|
||||
* ES3 === / \ === ES4
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE("Example");
|
||||
|
||||
|
||||
//A callback to log the pkt reception
|
||||
static void
|
||||
MacRxCallback(std::string context, Ptr<const Packet> p)
|
||||
{
|
||||
NS_LOG_INFO((Simulator::Now()).As(Time::S) << " \t" << context << " : Pkt #" << p->GetUid() << " received !");
|
||||
}
|
||||
|
||||
//A callback to log the pkt emission
|
||||
static void
|
||||
PhyTxCallback(std::string context, Ptr<const Packet> p)
|
||||
{
|
||||
NS_LOG_INFO((Simulator::Now()).As(Time::S) << " \t" << context << " : Pkt #" << p->GetUid() << " begin transmission !");
|
||||
}
|
||||
|
||||
//Callbacks to log pkt drop
|
||||
static void
|
||||
MaxSDUSizeFilterDrop(std::string context, Ptr<const Packet> p)
|
||||
{
|
||||
NS_LOG_INFO(context << " : Packet #"<< p->GetUid() <<" was dropped by MaxSDUSizeFilter");
|
||||
}
|
||||
|
||||
static void
|
||||
REDFrameDrop(std::string context, Ptr<const Packet> p)
|
||||
{
|
||||
NS_LOG_INFO(context << " : Packet #"<< p->GetUid() <<" was dropped by Flow Meter");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
//Enable logging
|
||||
LogComponentEnable("Example", LOG_LEVEL_INFO);
|
||||
LogComponentEnable("EthernetGenerator", LOG_LEVEL_INFO);
|
||||
LogComponentEnable("EvbLan9668", LOG_LEVEL_INFO);
|
||||
LogComponentEnable("TsnNetDevice", LOG_LEVEL_INFO);
|
||||
|
||||
CommandLine cmd(__FILE__);
|
||||
cmd.Parse(argc, argv);
|
||||
|
||||
//Create four end stations
|
||||
Ptr<TsnNode> n1 = CreateObject<TsnNode>();
|
||||
Names::Add("ES1", n1);
|
||||
Ptr<TsnNode> n2 = CreateObject<TsnNode>();
|
||||
Names::Add("ES2", n2);
|
||||
Ptr<TsnNode> n3 = CreateObject<TsnNode>();
|
||||
Names::Add("ES3", n3);
|
||||
Ptr<TsnNode> n4 = CreateObject<TsnNode>();
|
||||
Names::Add("ES4", n4);
|
||||
|
||||
//Create and add a netDevices to each end station
|
||||
Ptr<TsnNetDevice> net1 = CreateObject<TsnNetDevice>();
|
||||
n1->AddDevice(net1);
|
||||
Names::Add("ES1e#01", net1);
|
||||
Ptr<TsnNetDevice> net2 = CreateObject<TsnNetDevice>();
|
||||
n2->AddDevice(net2);
|
||||
Names::Add("ES2#01", net2);
|
||||
Ptr<TsnNetDevice> net3 = CreateObject<TsnNetDevice>();
|
||||
n3->AddDevice(net3);
|
||||
Names::Add("ES3#01", net3);
|
||||
Ptr<TsnNetDevice> net4 = CreateObject<TsnNetDevice>();
|
||||
n4->AddDevice(net4);
|
||||
Names::Add("ES4#01", net4);
|
||||
|
||||
//Allocate a Mac address to the end station
|
||||
net1->SetAddress(Mac48Address::Allocate());
|
||||
net2->SetAddress(Mac48Address::Allocate());
|
||||
net3->SetAddress(Mac48Address::Allocate());
|
||||
net4->SetAddress(Mac48Address::Allocate());
|
||||
|
||||
//Create the switch
|
||||
Ptr<EvbLan9668> lan9668 = CreateObject<EvbLan9668>("SW");
|
||||
|
||||
//Create Ethernet Channels and attach it to the netDevices
|
||||
Ptr<EthernetChannel> l0 = CreateObject<EthernetChannel>();
|
||||
l0->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net1->Attach(l0);
|
||||
lan9668->GetPort(1)->Attach(l0);
|
||||
Ptr<EthernetChannel> l1 = CreateObject<EthernetChannel>();
|
||||
l1->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net2->Attach(l1);
|
||||
lan9668->GetPort(2)->Attach(l1);
|
||||
Ptr<EthernetChannel> l2 = CreateObject<EthernetChannel>();
|
||||
l2->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net3->Attach(l2);
|
||||
lan9668->GetPort(3)->Attach(l2);
|
||||
Ptr<EthernetChannel> l3 = CreateObject<EthernetChannel>();
|
||||
l3->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net4->Attach(l3);
|
||||
lan9668->GetPort(4)->Attach(l3);
|
||||
|
||||
|
||||
//Create and add eight FIFO on each end station net device
|
||||
for (int i=0; i<8; i++)
|
||||
{
|
||||
net1->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
net2->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
net3->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
net4->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
}
|
||||
|
||||
//Add forwarding table entry
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net2->GetAddress()), 10, {2});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address("ff:ff:ff:ff:ff:ff"), 10, {2, 3, 4});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net1->GetAddress()), 11, {1});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net4->GetAddress()), 12, {4});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net2->GetAddress()), 13, {2});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net2->GetAddress()), 14, {2});
|
||||
|
||||
|
||||
//Add a null stream identification function on the switch for psfp
|
||||
Ptr<NullStreamIdentificationFunction> sif = CreateObject<NullStreamIdentificationFunction>();
|
||||
sif->SetAttribute("VlanID", UintegerValue(10));
|
||||
sif->SetAttribute("Address", AddressValue(Mac48Address::ConvertFrom(net2->GetAddress())));
|
||||
lan9668->AddNullStreamIdentificationFunction(112, sif, {1}, {}, {}, {});
|
||||
|
||||
//Configure PSFP on the switch
|
||||
Ptr<StreamFilterInstance> sfi0 = CreateObject<StreamFilterInstance>();
|
||||
sfi0->SetAttribute("StreamHandle", IntegerValue(112));
|
||||
sfi0->SetAttribute("Priority", IntegerValue(-1)); //-1 = wildcard (like in PSFP MIB)
|
||||
sfi0->SetAttribute("MaxSDUSize", UintegerValue(1500));
|
||||
lan9668->AddStreamFilter(sfi0);
|
||||
Ptr<FlowMeterInstance> fm0 = CreateObject<FlowMeterInstance>();
|
||||
fm0->SetAttribute("CIR", DataRateValue(DataRate("40Mb/s")));
|
||||
fm0->SetAttribute("CBS", UintegerValue(1500));
|
||||
fm0->SetAttribute("DropOnYellow", BooleanValue(true));
|
||||
fm0->SetAttribute("MarkAllFramesRedEnable", BooleanValue(false));
|
||||
uint16_t fmid = lan9668->AddFlowMeter(fm0);
|
||||
sfi0->AddFlowMeterInstanceId(fmid);
|
||||
|
||||
//Application description
|
||||
Ptr<EthernetGenerator> app0 = CreateObject<EthernetGenerator>();
|
||||
app0->Setup(net1);
|
||||
app0->SetAttribute("BurstSize", UintegerValue(1));
|
||||
app0->SetAttribute("PayloadSize", UintegerValue(1478));
|
||||
app0->SetAttribute("Period", TimeValue(MilliSeconds(100)));
|
||||
app0->SetAttribute("PCP", UintegerValue(4));
|
||||
app0->SetAttribute("VlanID", UintegerValue(10));
|
||||
app0->SetAttribute("Address", AddressValue(Mac48Address::ConvertFrom(net2->GetAddress())));
|
||||
n1->AddApplication(app0);
|
||||
app0->SetStartTime(MilliSeconds(0));
|
||||
app0->SetStopTime(MilliSeconds(200));
|
||||
|
||||
//Callback to display the packet transmitted and received log
|
||||
net1->TraceConnectWithoutContext("PhyTxBegin", MakeBoundCallback(&PhyTxCallback, Names::FindName(n1) + ":" + Names::FindName(net1)));
|
||||
net2->TraceConnectWithoutContext("MacRx", MakeBoundCallback(&MacRxCallback, Names::FindName(n2) + ":" + Names::FindName(net2)));
|
||||
|
||||
//Callback related to PSFP event
|
||||
lan9668->GetPort(1)->TraceConnectWithoutContext("MaxSDUSizeFilterDrop", MakeBoundCallback(&MaxSDUSizeFilterDrop, Names::FindName(lan9668->GetPort(1))));
|
||||
lan9668->GetPort(1)->TraceConnectWithoutContext("REDFrameDrop", MakeBoundCallback(&REDFrameDrop, Names::FindName(lan9668->GetPort(1))));
|
||||
|
||||
//Execute the simulation
|
||||
Simulator::Stop(MilliSeconds(300));
|
||||
Simulator::Run();
|
||||
Simulator::Destroy();
|
||||
return 0;
|
||||
}
|
||||
156
contrib/real-device/examples/evb-lan9668-sp.cc
Normal file
156
contrib/real-device/examples/evb-lan9668-sp.cc
Normal file
@@ -0,0 +1,156 @@
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/applications-module.h"
|
||||
#include "ns3/command-line.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/drop-tail-queue.h"
|
||||
#include "ns3/timestamp-tag.h"
|
||||
#include "ns3/trace-helper.h"
|
||||
#include <fstream>
|
||||
|
||||
#include "ns3/tsn-node.h"
|
||||
#include "ns3/tsn-net-device.h"
|
||||
#include "ns3/switch-net-device.h"
|
||||
#include "ns3/ethernet-channel.h"
|
||||
#include "ns3/ethernet-generator.h"
|
||||
#include "ns3/ethernet-header2.h"
|
||||
|
||||
#include "ns3/evb-lan9668.h"
|
||||
#include "ns3/stream-identification-function-null.h"
|
||||
#include "ns3/frer-match-recovery-function.h"
|
||||
#include "ns3/frer-vector-recovery-function.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Example with 4ES connected to 1SW in a 1Gb/s full duplex link as follow.
|
||||
* ES1 === \ / === ES2
|
||||
* SW
|
||||
* ES3 === / \ === ES4
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE("Example");
|
||||
|
||||
|
||||
//A callback to log the pkt reception
|
||||
static void
|
||||
MacRxCallback(std::string context, Ptr<const Packet> p)
|
||||
{
|
||||
NS_LOG_INFO((Simulator::Now()).As(Time::S) << " \t" << context << " : Pkt #" << p->GetUid() << " received !");
|
||||
}
|
||||
|
||||
//A callback to log the pkt emission
|
||||
static void
|
||||
PhyTxCallback(std::string context, Ptr<const Packet> p)
|
||||
{
|
||||
NS_LOG_INFO((Simulator::Now()).As(Time::S) << " \t" << context << " : Pkt #" << p->GetUid() << " begin transmission !");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
//Enable logging
|
||||
LogComponentEnable("Example", LOG_LEVEL_INFO);
|
||||
LogComponentEnable("EthernetGenerator", LOG_LEVEL_INFO);
|
||||
LogComponentEnable("EvbLan9668", LOG_LEVEL_INFO);
|
||||
LogComponentEnable("TsnNetDevice", LOG_LEVEL_INFO);
|
||||
|
||||
CommandLine cmd(__FILE__);
|
||||
cmd.Parse(argc, argv);
|
||||
|
||||
//Create four end stations
|
||||
Ptr<TsnNode> n1 = CreateObject<TsnNode>();
|
||||
Names::Add("ES1", n1);
|
||||
Ptr<TsnNode> n2 = CreateObject<TsnNode>();
|
||||
Names::Add("ES2", n2);
|
||||
Ptr<TsnNode> n3 = CreateObject<TsnNode>();
|
||||
Names::Add("ES3", n3);
|
||||
Ptr<TsnNode> n4 = CreateObject<TsnNode>();
|
||||
Names::Add("ES4", n4);
|
||||
|
||||
//Create and add a netDevices to each end station
|
||||
Ptr<TsnNetDevice> net1 = CreateObject<TsnNetDevice>();
|
||||
n1->AddDevice(net1);
|
||||
Names::Add("ES1e#01", net1);
|
||||
Ptr<TsnNetDevice> net2 = CreateObject<TsnNetDevice>();
|
||||
n2->AddDevice(net2);
|
||||
Names::Add("ES2#01", net2);
|
||||
Ptr<TsnNetDevice> net3 = CreateObject<TsnNetDevice>();
|
||||
n3->AddDevice(net3);
|
||||
Names::Add("ES3#01", net3);
|
||||
Ptr<TsnNetDevice> net4 = CreateObject<TsnNetDevice>();
|
||||
n4->AddDevice(net4);
|
||||
Names::Add("ES4#01", net4);
|
||||
|
||||
//Allocate a Mac address to the end station
|
||||
net1->SetAddress(Mac48Address::Allocate());
|
||||
net2->SetAddress(Mac48Address::Allocate());
|
||||
net3->SetAddress(Mac48Address::Allocate());
|
||||
net4->SetAddress(Mac48Address::Allocate());
|
||||
|
||||
//Create the switch
|
||||
Ptr<EvbLan9668> lan9668 = CreateObject<EvbLan9668>("SW");
|
||||
|
||||
//Create Ethernet Channels and attach it to the netDevices
|
||||
Ptr<EthernetChannel> l0 = CreateObject<EthernetChannel>();
|
||||
l0->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net1->Attach(l0);
|
||||
lan9668->GetPort(1)->Attach(l0);
|
||||
Ptr<EthernetChannel> l1 = CreateObject<EthernetChannel>();
|
||||
l1->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net2->Attach(l1);
|
||||
lan9668->GetPort(2)->Attach(l1);
|
||||
Ptr<EthernetChannel> l2 = CreateObject<EthernetChannel>();
|
||||
l2->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net3->Attach(l2);
|
||||
lan9668->GetPort(3)->Attach(l2);
|
||||
Ptr<EthernetChannel> l3 = CreateObject<EthernetChannel>();
|
||||
l3->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net4->Attach(l3);
|
||||
lan9668->GetPort(4)->Attach(l3);
|
||||
|
||||
|
||||
//Create and add eight FIFO on each end station net device
|
||||
for (int i=0; i<8; i++)
|
||||
{
|
||||
net1->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
net2->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
net3->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
net4->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
}
|
||||
|
||||
//Add forwarding table entry
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net2->GetAddress()), 10, {2});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address("ff:ff:ff:ff:ff:ff"), 10, {2, 3, 4});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net1->GetAddress()), 11, {1});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net4->GetAddress()), 12, {4});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net2->GetAddress()), 13, {2});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net2->GetAddress()), 14, {2});
|
||||
|
||||
//Application description
|
||||
Ptr<EthernetGenerator> app0 = CreateObject<EthernetGenerator>();
|
||||
app0->Setup(net1);
|
||||
app0->SetAttribute("BurstSize", UintegerValue(1));
|
||||
app0->SetAttribute("PayloadSize", UintegerValue(1478));
|
||||
app0->SetAttribute("Period", TimeValue(MilliSeconds(100)));
|
||||
app0->SetAttribute("PCP", UintegerValue(4));
|
||||
app0->SetAttribute("VlanID", UintegerValue(10));
|
||||
app0->SetAttribute("Address", AddressValue(Mac48Address::ConvertFrom(net2->GetAddress())));
|
||||
n1->AddApplication(app0);
|
||||
app0->SetStartTime(MilliSeconds(0));
|
||||
app0->SetStopTime(MilliSeconds(200));
|
||||
|
||||
//Callback to display the packet transmitted and received log
|
||||
net1->TraceConnectWithoutContext("PhyTxBegin", MakeBoundCallback(&PhyTxCallback, Names::FindName(n1) + ":" + Names::FindName(net1)));
|
||||
net2->TraceConnectWithoutContext("MacRx", MakeBoundCallback(&MacRxCallback, Names::FindName(n2) + ":" + Names::FindName(net2)));
|
||||
|
||||
//Execute the simulation
|
||||
Simulator::Stop(MilliSeconds(300));
|
||||
Simulator::Run();
|
||||
Simulator::Destroy();
|
||||
return 0;
|
||||
}
|
||||
160
contrib/real-device/examples/evb-lan9668-tas.cc
Normal file
160
contrib/real-device/examples/evb-lan9668-tas.cc
Normal file
@@ -0,0 +1,160 @@
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/applications-module.h"
|
||||
#include "ns3/command-line.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/drop-tail-queue.h"
|
||||
#include "ns3/timestamp-tag.h"
|
||||
#include "ns3/trace-helper.h"
|
||||
#include <fstream>
|
||||
|
||||
#include "ns3/tsn-node.h"
|
||||
#include "ns3/tsn-net-device.h"
|
||||
#include "ns3/switch-net-device.h"
|
||||
#include "ns3/ethernet-channel.h"
|
||||
#include "ns3/ethernet-generator.h"
|
||||
#include "ns3/ethernet-header2.h"
|
||||
|
||||
#include "ns3/evb-lan9668.h"
|
||||
#include "ns3/stream-identification-function-null.h"
|
||||
#include "ns3/frer-match-recovery-function.h"
|
||||
#include "ns3/frer-vector-recovery-function.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Example with 4ES connected to 1SW in a 1Gb/s full duplex link as follow.
|
||||
* ES1 === \ / === ES2
|
||||
* SW
|
||||
* ES3 === / \ === ES4
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE("Example");
|
||||
|
||||
|
||||
//A callback to log the pkt reception
|
||||
static void
|
||||
MacRxCallback(std::string context, Ptr<const Packet> p)
|
||||
{
|
||||
NS_LOG_INFO((Simulator::Now()).As(Time::S) << " \t" << context << " : Pkt #" << p->GetUid() << " received !");
|
||||
}
|
||||
|
||||
//A callback to log the pkt emission
|
||||
static void
|
||||
PhyTxCallback(std::string context, Ptr<const Packet> p)
|
||||
{
|
||||
NS_LOG_INFO((Simulator::Now()).As(Time::S) << " \t" << context << " : Pkt #" << p->GetUid() << " begin transmission !");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
//Enable logging
|
||||
LogComponentEnable("Example", LOG_LEVEL_INFO);
|
||||
LogComponentEnable("EthernetGenerator", LOG_LEVEL_INFO);
|
||||
LogComponentEnable("EvbLan9668", LOG_LEVEL_INFO);
|
||||
LogComponentEnable("TsnNetDevice", LOG_LEVEL_INFO);
|
||||
|
||||
CommandLine cmd(__FILE__);
|
||||
cmd.Parse(argc, argv);
|
||||
|
||||
//Create four end stations
|
||||
Ptr<TsnNode> n1 = CreateObject<TsnNode>();
|
||||
Names::Add("ES1", n1);
|
||||
Ptr<TsnNode> n2 = CreateObject<TsnNode>();
|
||||
Names::Add("ES2", n2);
|
||||
Ptr<TsnNode> n3 = CreateObject<TsnNode>();
|
||||
Names::Add("ES3", n3);
|
||||
Ptr<TsnNode> n4 = CreateObject<TsnNode>();
|
||||
Names::Add("ES4", n4);
|
||||
|
||||
//Create and add a netDevices to each end station
|
||||
Ptr<TsnNetDevice> net1 = CreateObject<TsnNetDevice>();
|
||||
n1->AddDevice(net1);
|
||||
Names::Add("ES1e#01", net1);
|
||||
Ptr<TsnNetDevice> net2 = CreateObject<TsnNetDevice>();
|
||||
n2->AddDevice(net2);
|
||||
Names::Add("ES2#01", net2);
|
||||
Ptr<TsnNetDevice> net3 = CreateObject<TsnNetDevice>();
|
||||
n3->AddDevice(net3);
|
||||
Names::Add("ES3#01", net3);
|
||||
Ptr<TsnNetDevice> net4 = CreateObject<TsnNetDevice>();
|
||||
n4->AddDevice(net4);
|
||||
Names::Add("ES4#01", net4);
|
||||
|
||||
//Allocate a Mac address to the end station
|
||||
net1->SetAddress(Mac48Address::Allocate());
|
||||
net2->SetAddress(Mac48Address::Allocate());
|
||||
net3->SetAddress(Mac48Address::Allocate());
|
||||
net4->SetAddress(Mac48Address::Allocate());
|
||||
|
||||
//Create the switch
|
||||
Ptr<EvbLan9668> lan9668 = CreateObject<EvbLan9668>("SW");
|
||||
lan9668->AddGclEntry(2,MilliSeconds(200), 1); //uint32_t port_id, Time interval, uint8_t state
|
||||
lan9668->AddGclEntry(2,MilliSeconds(200), 16);
|
||||
lan9668->StartTas();
|
||||
|
||||
|
||||
//Create Ethernet Channels and attach it to the netDevices
|
||||
Ptr<EthernetChannel> l0 = CreateObject<EthernetChannel>();
|
||||
l0->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net1->Attach(l0);
|
||||
lan9668->GetPort(1)->Attach(l0);
|
||||
Ptr<EthernetChannel> l1 = CreateObject<EthernetChannel>();
|
||||
l1->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net2->Attach(l1);
|
||||
lan9668->GetPort(2)->Attach(l1);
|
||||
Ptr<EthernetChannel> l2 = CreateObject<EthernetChannel>();
|
||||
l2->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net3->Attach(l2);
|
||||
lan9668->GetPort(3)->Attach(l2);
|
||||
Ptr<EthernetChannel> l3 = CreateObject<EthernetChannel>();
|
||||
l3->SetAttribute("Delay", TimeValue(MicroSeconds(0)));
|
||||
net4->Attach(l3);
|
||||
lan9668->GetPort(4)->Attach(l3);
|
||||
|
||||
|
||||
//Create and add eight FIFO on each end station net device
|
||||
for (int i=0; i<8; i++)
|
||||
{
|
||||
net1->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
net2->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
net3->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
net4->SetQueue(CreateObject<DropTailQueue<Packet>>());
|
||||
}
|
||||
|
||||
//Add forwarding table entry
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net2->GetAddress()), 10, {2});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address("ff:ff:ff:ff:ff:ff"), 10, {2, 3, 4});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net1->GetAddress()), 11, {1});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net4->GetAddress()), 12, {4});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net2->GetAddress()), 13, {2});
|
||||
lan9668->AddForwardingTableEntry(Mac48Address::ConvertFrom(net2->GetAddress()), 14, {2});
|
||||
|
||||
//Application description
|
||||
Ptr<EthernetGenerator> app0 = CreateObject<EthernetGenerator>();
|
||||
app0->Setup(net1);
|
||||
app0->SetAttribute("BurstSize", UintegerValue(1));
|
||||
app0->SetAttribute("PayloadSize", UintegerValue(1478));
|
||||
app0->SetAttribute("Period", TimeValue(MilliSeconds(100)));
|
||||
app0->SetAttribute("PCP", UintegerValue(4));
|
||||
app0->SetAttribute("VlanID", UintegerValue(10));
|
||||
app0->SetAttribute("Address", AddressValue(Mac48Address::ConvertFrom(net2->GetAddress())));
|
||||
n1->AddApplication(app0);
|
||||
app0->SetStartTime(MilliSeconds(0));
|
||||
app0->SetStopTime(MilliSeconds(200));
|
||||
|
||||
//Callback to display the packet transmitted and received log
|
||||
net1->TraceConnectWithoutContext("PhyTxBegin", MakeBoundCallback(&PhyTxCallback, Names::FindName(n1) + ":" + Names::FindName(net1)));
|
||||
net2->TraceConnectWithoutContext("MacRx", MakeBoundCallback(&MacRxCallback, Names::FindName(n2) + ":" + Names::FindName(net2)));
|
||||
|
||||
//Execute the simulation
|
||||
Simulator::Stop(MilliSeconds(300));
|
||||
Simulator::Run();
|
||||
Simulator::Destroy();
|
||||
return 0;
|
||||
}
|
||||
8
contrib/real-device/helper/real-device-helper.cc
Normal file
8
contrib/real-device/helper/real-device-helper.cc
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "real-device-helper.h"
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
|
||||
/* ... */
|
||||
|
||||
}
|
||||
16
contrib/real-device/helper/real-device-helper.h
Normal file
16
contrib/real-device/helper/real-device-helper.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef REAL_DEVICE_HELPER_H
|
||||
#define REAL_DEVICE_HELPER_H
|
||||
|
||||
#include "ns3/evb-lan9668.h"
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
|
||||
// Each class should be documented using Doxygen,
|
||||
// and have an \ingroup real-device directive
|
||||
|
||||
/* ... */
|
||||
|
||||
}
|
||||
|
||||
#endif /* REAL_DEVICE_HELPER_H */
|
||||
267
contrib/real-device/model/evb-lan9668.cc
Normal file
267
contrib/real-device/model/evb-lan9668.cc
Normal file
@@ -0,0 +1,267 @@
|
||||
#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<Object>()
|
||||
.SetGroupName("real-device")
|
||||
.AddConstructor<EvbLan9668>();
|
||||
return tid;
|
||||
}
|
||||
|
||||
EvbLan9668::EvbLan9668()
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
m_node = CreateObject<TsnNode>();
|
||||
m_node->AddClock(CreateObject<Clock>()); //Add perfect clock
|
||||
|
||||
for (int i=0; i<m_portNumber; ++i){
|
||||
Ptr<TsnNetDevice> net = CreateObject<TsnNetDevice>();
|
||||
for (int j=0; j<m_queuesPerPort; ++j){
|
||||
Ptr<DropTailQueue<Packet>> q = CreateObject<DropTailQueue<Packet>>();
|
||||
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<SwitchNetDevice>();
|
||||
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<TsnNetDevice>
|
||||
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<uint32_t> output_port_ids){
|
||||
NS_LOG_FUNCTION(this);
|
||||
std::vector<Ptr<NetDevice>> 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> cbs = CreateObject<Cbs>();
|
||||
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<DropTailQueue<Packet>> q = CreateObject<DropTailQueue<Packet>>();
|
||||
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<NullStreamIdentificationFunction> streamIdentificationFunction,
|
||||
std::vector<uint32_t> outFacInputPortIds,
|
||||
std::vector<uint32_t> inFacInputPortIds,
|
||||
std::vector<uint32_t> inFacOutputPortIds,
|
||||
std::vector<uint32_t> outFacOutputPortIds)
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
|
||||
std::vector<Ptr<TsnNetDevice>> outFacInputPortList = {};
|
||||
for (int i = 0; i < (int)outFacInputPortIds.size(); i++){
|
||||
outFacInputPortList.insert(outFacInputPortList.end(), GetPort(outFacInputPortIds[i]));
|
||||
}
|
||||
|
||||
std::vector<Ptr<TsnNetDevice>> inFacInputPortList = {};
|
||||
for (int i = 0; i < (int)inFacInputPortIds.size(); i++){
|
||||
inFacInputPortList.insert(inFacInputPortList.end(), GetPort(inFacInputPortIds[i]));
|
||||
}
|
||||
|
||||
std::vector<Ptr<TsnNetDevice>> inFacOutputPortList = {};
|
||||
for (int i = 0; i < (int)inFacOutputPortIds.size(); i++){
|
||||
inFacOutputPortList.insert(inFacOutputPortList.end(), GetPort(inFacOutputPortIds[i]));
|
||||
}
|
||||
|
||||
std::vector<Ptr<TsnNetDevice>> 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> streamFilterInstance)
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
m_node->AddStreamFilter(streamFilterInstance);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
EvbLan9668::AddFlowMeter(Ptr<FlowMeterInstance> flowMeterInstance)
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
return m_node->AddFlowMeter(flowMeterInstance);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
EvbLan9668::AddSequenceGenerationFunction(Ptr<SequenceGenerationFunction> entry)
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
m_node->AddSequenceGenerationFunction(entry);
|
||||
}
|
||||
|
||||
void
|
||||
EvbLan9668::AddSequenceRecoveryFunction(Ptr<SequenceRecoveryFunction> rcvy, Ptr<BaseRecoveryFunction> algo, Ptr<LatentErrorDetectionFunction> lat, std::vector<uint32_t> 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<Ptr<TsnNetDevice>> 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<SequenceEncodeDecodeFunction> entry, uint32_t port_id)
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
entry->SetPort(GetPort(port_id));
|
||||
m_node->AddSequenceEncodeDecodeFunction(entry);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
220
contrib/real-device/model/evb-lan9668.h
Normal file
220
contrib/real-device/model/evb-lan9668.h
Normal file
@@ -0,0 +1,220 @@
|
||||
#ifndef EVB_LAN9668_H
|
||||
#define EVB_LAN9668_H
|
||||
|
||||
#include "ns3/object.h"
|
||||
|
||||
#include "ns3/tsn-node.h"
|
||||
#include "ns3/tsn-net-device.h"
|
||||
#include "ns3/stream-identification-function-null.h"
|
||||
|
||||
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
|
||||
/**
|
||||
* \ingroup real-device
|
||||
*
|
||||
* \brief A object to simulate EVB-LAN9668 switch.
|
||||
*/
|
||||
class EvbLan9668: public Object
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Get the TypeId
|
||||
*
|
||||
* \return The TypeId for this class
|
||||
*/
|
||||
static TypeId GetTypeId();
|
||||
|
||||
/**
|
||||
* \brief Create a EvbLan9668
|
||||
*/
|
||||
EvbLan9668();
|
||||
|
||||
/**
|
||||
* \brief Create a EvbLan9668
|
||||
*/
|
||||
EvbLan9668(std::string name);
|
||||
|
||||
/**
|
||||
* Destroy a EvbLan9668
|
||||
*
|
||||
* This is the destructor for the TsnNode.
|
||||
*/
|
||||
~EvbLan9668();
|
||||
|
||||
// Delete copy constructor and assignment operator to avoid misuse
|
||||
EvbLan9668& operator=(const EvbLan9668&) = delete;
|
||||
EvbLan9668(const EvbLan9668&) = delete;
|
||||
|
||||
/**
|
||||
* \brief Set most of the hardware limits
|
||||
*/
|
||||
void SetHardwareLimits();
|
||||
|
||||
/**
|
||||
* \brief Get a TsnNetDevice from its port id
|
||||
* \param id the port id
|
||||
* \return The TsnNetDevice
|
||||
*/
|
||||
Ptr<TsnNetDevice> GetPort(int id);
|
||||
|
||||
/**
|
||||
* \brief Add a entry in the forwarding database
|
||||
* \param dest the mac address destination
|
||||
* \param vlan_id the vlan id
|
||||
* \param output_port_ids a vector of output port id
|
||||
*/
|
||||
void AddForwardingTableEntry(
|
||||
Mac48Address dest,
|
||||
uint16_t vlan_id,
|
||||
std::vector<uint32_t> output_port_ids);
|
||||
|
||||
/**
|
||||
* \brief Set the datarate of a port
|
||||
* \param id the port id
|
||||
* \param d the datarate
|
||||
*/
|
||||
void SetPortDatarate(int id, DataRate d);
|
||||
|
||||
/**
|
||||
* \brief Add a CBS instance to a port and queue
|
||||
* \para the port id
|
||||
* \param the queue id
|
||||
* \param the iddle_slope
|
||||
* \param the port_transmit_rate
|
||||
*/
|
||||
void AddCbs(uint32_t port_id, uint32_t queue_id, DataRate iddle_slope, DataRate port_transmit_rate);
|
||||
|
||||
/**
|
||||
* \brief Add a GCL entry to a port
|
||||
* \para the port id
|
||||
* \param the GCL entry duration
|
||||
* \param the GCL entry state
|
||||
*/
|
||||
void AddGclEntry(uint32_t port_id, Time interval, uint8_t state);
|
||||
|
||||
/**
|
||||
* \brief Start TAS operation
|
||||
*/
|
||||
void StartTas();
|
||||
|
||||
/**
|
||||
* \brief Add a null stream identification function
|
||||
* \para streamHandle
|
||||
* \param stream Identification Function
|
||||
* \param out-facing input port ids
|
||||
* \param in-facing input port ids
|
||||
* \param in-facing output port ids
|
||||
* \param out-facing output port ids
|
||||
*/
|
||||
void
|
||||
AddNullStreamIdentificationFunction(
|
||||
uint32_t streamHandle,
|
||||
Ptr<NullStreamIdentificationFunction> streamIdentificationFunction,
|
||||
std::vector<uint32_t> outFacInputPortIds,
|
||||
std::vector<uint32_t> inFacInputPortIds,
|
||||
std::vector<uint32_t> inFacOutputPortIds,
|
||||
std::vector<uint32_t> outFacOutputPortIds);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Add a stream filter to the node
|
||||
* \param the stream filter instance
|
||||
*/
|
||||
void
|
||||
AddStreamFilter(Ptr<StreamFilterInstance> streamFilterInstance);
|
||||
|
||||
/**
|
||||
* \brief Add a flow meter to the node
|
||||
* \param the flow meter instance
|
||||
*/
|
||||
uint16_t
|
||||
AddFlowMeter(Ptr<FlowMeterInstance> flowMeterInstance);
|
||||
|
||||
/**
|
||||
* \brief Add generation function to the node
|
||||
* \param the genertation function
|
||||
*/
|
||||
void
|
||||
AddSequenceGenerationFunction(Ptr<SequenceGenerationFunction> entry);
|
||||
|
||||
/**
|
||||
* \brief Add recovery function to the node
|
||||
* \param the recovery function
|
||||
* \param the recovery algo (match or vector)
|
||||
* \param the latent error detection function
|
||||
* \param the port ids
|
||||
*/
|
||||
void
|
||||
AddSequenceRecoveryFunction(Ptr<SequenceRecoveryFunction> rcvy, Ptr<BaseRecoveryFunction> algo, Ptr<LatentErrorDetectionFunction> lat, std::vector<uint32_t> port_ids);
|
||||
|
||||
/**
|
||||
* \brief Add encode/decode function to the node
|
||||
* \param the encode/decode function
|
||||
* \param the port id
|
||||
*/
|
||||
void
|
||||
AddSequenceEncodeDecodeFunction(Ptr<SequenceEncodeDecodeFunction> entry, uint32_t port_id);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
Ptr<TsnNode> m_node;
|
||||
std::vector<Ptr<TsnNetDevice>> m_net_devices;
|
||||
Ptr<SwitchNetDevice> m_switch_net_device;
|
||||
|
||||
|
||||
//Hardware limits
|
||||
uint16_t m_portNumber = 8;
|
||||
uint16_t m_queuesPerPort = 8;
|
||||
uint16_t m_maxFdbEntryNumber = 64;
|
||||
QueueSize m_fifoSize = QueueSize("102p");
|
||||
Time m_minForwardingLatency = NanoSeconds(2660); //2660
|
||||
Time m_maxForwardingLatency = NanoSeconds(2370); //2370
|
||||
|
||||
//CBS
|
||||
DataRate m_maxIddleSlope = DataRate("3.282Gb/s");
|
||||
Time m_minCBSLatencyOverhead = NanoSeconds(0); //-25ns
|
||||
Time m_maxCBSLatencyOverhead = NanoSeconds(0); //-9ns
|
||||
|
||||
//Tas
|
||||
uint32_t m_maxGclEntryNumber = 256;
|
||||
Time m_maxGclCycleDuration = NanoSeconds(999999999);
|
||||
Time m_maxGclTimeInterval = NanoSeconds(999999999);
|
||||
Time m_minTASLatencyOverhead = NanoSeconds(0);
|
||||
Time m_maxTASLatencyOverhead = NanoSeconds(0);
|
||||
|
||||
//Stream identification
|
||||
uint32_t m_maxSidEntryNumber = 127;
|
||||
Time m_minNullSIDLatencyOverhead = NanoSeconds(0); //-9ns
|
||||
Time m_maxNullSIDLatencyOverhead = NanoSeconds(0); //-13ns
|
||||
Time m_minSourceMacSIDLatencyOverhead = NanoSeconds(0);
|
||||
Time m_maxSourceMacSIDLatencyOverhead = NanoSeconds(0);
|
||||
|
||||
//PSFP
|
||||
uint32_t m_maxPsfpFilterEntryNumber = 176;
|
||||
uint32_t m_maxPsfpStreamGateEntryNumber = 176;
|
||||
uint32_t m_maxPsfpFlowMeterEntryNumber = 240;
|
||||
|
||||
//FRER
|
||||
uint32_t m_maxFrerSeqGenEntryNumber = 99;
|
||||
uint32_t m_maxFrerSeqRcvyEntryNumber = 99;
|
||||
uint32_t m_maxFrerSeqEncEntryNumber = 99;
|
||||
Time m_minFrerSeqRcvyResetDuration = MilliSeconds(1);
|
||||
Time m_maxFrerSeqRcvyResetDuration = Seconds(4.095);
|
||||
Time m_minFrerLatErrorTestDuration = Seconds(1);
|
||||
Time m_maxFrerLatErrorTestDuration = Seconds(86400);
|
||||
Time m_minFrerLatErrorResetDuration = Seconds(1);
|
||||
Time m_maxFrerLatErrorResetDuration = Seconds(86400);
|
||||
Time m_minFrerRcvyLatencyOverhead = NanoSeconds(40); //40ns
|
||||
Time m_maxFrerRcvyLatencyOverhead = NanoSeconds(40); //40ns
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* EVB_LAN9668_H */
|
||||
23
contrib/real-device/test/examples-to-run.py
Normal file
23
contrib/real-device/test/examples-to-run.py
Normal file
@@ -0,0 +1,23 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
# A list of C++ examples to run in order to ensure that they remain
|
||||
# buildable and runnable over time. Each tuple in the list contains
|
||||
#
|
||||
# (example_name, do_run, do_valgrind_run).
|
||||
#
|
||||
# See test.py for more information.
|
||||
cpp_examples = [
|
||||
("evb-lan9668-sp", "True", "True"),
|
||||
("evb-lan9668-cbs", "True", "True"),
|
||||
("evb-lan9668-tas", "True", "True"),
|
||||
("evb-lan9668-psfp", "True", "True"),
|
||||
("evb-lan9668-frer", "True", "True"),
|
||||
]
|
||||
|
||||
# A list of Python examples to run in order to ensure that they remain
|
||||
# runnable over time. Each tuple in the list contains
|
||||
#
|
||||
# (example_name, do_run).
|
||||
#
|
||||
# See test.py for more information.
|
||||
python_examples = []
|
||||
86
contrib/real-device/test/real-device-test-suite.cc
Normal file
86
contrib/real-device/test/real-device-test-suite.cc
Normal file
@@ -0,0 +1,86 @@
|
||||
|
||||
// Include a header file from your module to test.
|
||||
#include "ns3/evb-lan9668.h"
|
||||
|
||||
// An essential include is test.h
|
||||
#include "ns3/test.h"
|
||||
|
||||
// Do not put your test classes in namespace ns3. You may find it useful
|
||||
// to use the using directive to access the ns3 namespace directly
|
||||
using namespace ns3;
|
||||
|
||||
// Add a doxygen group for tests.
|
||||
// If you have more than one test, this should be in only one of them.
|
||||
/**
|
||||
* \defgroup real-device-tests Tests for real-device
|
||||
* \ingroup real-device
|
||||
* \ingroup tests
|
||||
*/
|
||||
|
||||
// This is an example TestCase.
|
||||
/**
|
||||
* \ingroup real-device-tests
|
||||
* Test case for feature 1
|
||||
*/
|
||||
class RealDeviceTestCase1 : public TestCase
|
||||
{
|
||||
public:
|
||||
RealDeviceTestCase1();
|
||||
virtual ~RealDeviceTestCase1();
|
||||
|
||||
private:
|
||||
void DoRun() override;
|
||||
};
|
||||
|
||||
// Add some help text to this case to describe what it is intended to test
|
||||
RealDeviceTestCase1::RealDeviceTestCase1()
|
||||
: TestCase("RealDevice test case (does nothing)")
|
||||
{
|
||||
}
|
||||
|
||||
// This destructor does nothing but we include it as a reminder that
|
||||
// the test case should clean up after itself
|
||||
RealDeviceTestCase1::~RealDeviceTestCase1()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// This method is the pure virtual method from class TestCase that every
|
||||
// TestCase must implement
|
||||
//
|
||||
void
|
||||
RealDeviceTestCase1::DoRun()
|
||||
{
|
||||
// A wide variety of test macros are available in src/core/test.h
|
||||
NS_TEST_ASSERT_MSG_EQ(true, true, "true doesn't equal true for some reason");
|
||||
// Use this one for floating point comparisons
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL(0.01, 0.01, 0.001, "Numbers are not equal within tolerance");
|
||||
}
|
||||
|
||||
// The TestSuite class names the TestSuite, identifies what type of TestSuite,
|
||||
// and enables the TestCases to be run. Typically, only the constructor for
|
||||
// this class must be defined
|
||||
|
||||
/**
|
||||
* \ingroup real-device-tests
|
||||
* TestSuite for module real-device
|
||||
*/
|
||||
class RealDeviceTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
RealDeviceTestSuite();
|
||||
};
|
||||
|
||||
RealDeviceTestSuite::RealDeviceTestSuite()
|
||||
: TestSuite("real-device", UNIT)
|
||||
{
|
||||
// TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER
|
||||
AddTestCase(new RealDeviceTestCase1, TestCase::QUICK);
|
||||
}
|
||||
|
||||
// Do not forget to allocate an instance of this TestSuite
|
||||
/**
|
||||
* \ingroup real-device-tests
|
||||
* Static variable for test initialization
|
||||
*/
|
||||
static RealDeviceTestSuite srealDeviceTestSuite;
|
||||
Reference in New Issue
Block a user