[General]
network = GptpAndTasShowcase
sim-time-limit = 4s
#abstract-config = true (requires omnet 7)
**.displayInterfaceTables = true
# all Ethernet interfaces have 100 Mbps speed
*.*.eth[*].bitrate = 100Mbps
# source application
*.tsnDevice1.numApps = 1
*.tsnDevice1.app[0].typename = "UdpSourceApp"
*.tsnDevice1.app[0].source.packetLength = 10B
*.tsnDevice1.app[0].source.productionInterval = 1ms
*.tsnDevice1.app[0].io.destAddress = "tsnDevice4"
*.tsnDevice1.app[0].io.destPort = 1000
*.tsnDevice1.app[0].source.clockModule = "^.^.clock"
# sink application
*.tsnDevice4.numApps = 1
*.tsnDevice4.app[0].typename = "UdpSinkApp"
*.tsnDevice4.app[0].io.localPort = 1000
# TSN switches have time-aware shapers with two traffic classes
*.tsnSwitch*.hasEgressTrafficShaping = true
*.tsnSwitch*.eth[*].macLayer.queue.numTrafficClasses = 2
*.tsnSwitch*.eth[*].macLayer.queue.classifier.typename = "ContentBasedClassifier"
*.tsnSwitch*.eth[*].macLayer.queue.queue[*].typename = "DropTailQueue"
*.tsnSwitch*.eth[*].macLayer.queue.classifier.packetFilters = ["app*", "Gptp*"]
*.tsnSwitch*.eth[*].macLayer.queue.transmissionGate[0].durations = [100us, 900us]
*.tsnSwitch*.eth[*].macLayer.queue.transmissionGate[0].clockModule = "^.^.^.^.clock"
*.tsnSwitch*.eth[*].macLayer.queue.transmissionGate[1].initiallyOpen = false
*.tsnSwitch*.eth[*].macLayer.queue.transmissionGate[1].durations = [100us, 900us]
*.tsnSwitch*.eth[*].macLayer.queue.transmissionGate[1].clockModule = "^.^.^.^.clock"
# enable time synchronization in all network nodes
*.*.hasTimeSynchronization = true
# all oscillators have a random constant drift
# except clocks in tsnClock2, where we specify constant drift rate to make failover effect more visible
**.oscillator.typename = "RandomDriftOscillator"
*.tsnClock2.clock.clock[*].oscillator.initialDriftRate = -30ppm
**.oscillator.initialDriftRate = uniform(-50ppm, 50ppm)
**.oscillator.driftRateChange = uniform(-20ppm, 20ppm)
**.oscillator.changeInterval = uniform(10ms, 50ms)
**.oscillator.driftRateChangeLowerLimit = -50ppm
**.oscillator.driftRateChangeUpperLimit = 50ppm
# TSN clock2 has multiple clocks
*.tsnClock2.clock.typename = "MultiClock"
*.tsnClock2.clock.numClocks = 2
# TSN clocks have multiple gPTP time synchronization domains
*.tsnClock*.gptp.typename = "MultiDomainGptp"
*.tsnClock1.gptp.numDomains = 2
*.tsnClock1.gptp.domain[0..1].clockModule = "tsnClock1.clock"
*.tsnClock1.gptp.domain[0].masterPorts = ["eth0"]
*.tsnClock1.gptp.domain[1].masterPorts = ["eth0"]
*.tsnClock2.gptp.numDomains = 4
*.tsnClock2.gptp.domain[2..3].clockModule = "tsnClock2.clock"
*.tsnClock2.gptp.domain[0].gptpNodeType = "SLAVE_NODE"
*.tsnClock2.gptp.domain[0].slavePort = "eth0"
*.tsnClock2.gptp.domain[1].gptpNodeType = "SLAVE_NODE"
*.tsnClock2.gptp.domain[1].slavePort = "eth0"
*.tsnClock2.gptp.domain[2].gptpNodeType = "MASTER_NODE"
*.tsnClock2.gptp.domain[2].masterPorts = ["eth0"]
*.tsnClock2.gptp.domain[3].gptpNodeType = "MASTER_NODE"
*.tsnClock2.gptp.domain[3].masterPorts = ["eth0"]
# TSN switches have multiple clocks
*.tsnSwitch*.clock.typename = "MultiClock"
*.tsnSwitch*.clock.numClocks = 4
# TSN switches have multiple gPTP time synchronization domains
*.tsnSwitch*.gptp.typename = "MultiDomainGptp"
*.tsnSwitch*.gptp.numDomains = 4
# TSN switch 1
*.tsnSwitch1.gptp.domain[0].masterPorts = ["eth1"]
*.tsnSwitch1.gptp.domain[0].slavePort = "eth0"
*.tsnSwitch1.gptp.domain[1].masterPorts = ["eth2"]
*.tsnSwitch1.gptp.domain[1].slavePort = "eth0"
*.tsnSwitch1.gptp.domain[2].masterPorts = ["eth1"]
*.tsnSwitch1.gptp.domain[2].slavePort = "eth2"
*.tsnSwitch1.gptp.domain[3].masterPorts = ["eth2"]
*.tsnSwitch1.gptp.domain[3].slavePort = "eth1"
# TSN switch 2
*.tsnSwitch2.gptp.domain[0].masterPorts = ["eth1", "eth2"]
*.tsnSwitch2.gptp.domain[0].slavePort = "eth0"
*.tsnSwitch2.gptp.domain[1].masterPorts = ["eth2"]
*.tsnSwitch2.gptp.domain[1].slavePort = "eth1"
*.tsnSwitch2.gptp.domain[2].masterPorts = ["eth1", "eth2"]
*.tsnSwitch2.gptp.domain[2].slavePort = "eth0"
*.tsnSwitch2.gptp.domain[3].masterPorts = ["eth0", "eth2"]
*.tsnSwitch2.gptp.domain[3].slavePort = "eth1"
# TSN switch 3
*.tsnSwitch3.gptp.domain[0].masterPorts = ["eth1", "eth2"]
*.tsnSwitch3.gptp.domain[0].slavePort = "eth0"
*.tsnSwitch3.gptp.domain[1].masterPorts = ["eth0", "eth2"]
*.tsnSwitch3.gptp.domain[1].slavePort = "eth1"
*.tsnSwitch3.gptp.domain[2].masterPorts = ["eth2"]
*.tsnSwitch3.gptp.domain[2].slavePort = "eth0"
*.tsnSwitch3.gptp.domain[3].masterPorts = ["eth0", "eth2"]
*.tsnSwitch3.gptp.domain[3].slavePort = "eth1"
# TSN switch 4
*.tsnSwitch4.gptp.domain[0].masterPorts = ["eth0", "eth2"]
*.tsnSwitch4.gptp.domain[0].slavePort = "eth1"
*.tsnSwitch4.gptp.domain[1].masterPorts = ["eth0", "eth1"]
*.tsnSwitch4.gptp.domain[1].slavePort = "eth2"
*.tsnSwitch4.gptp.domain[2].masterPorts = ["eth2"]
*.tsnSwitch4.gptp.domain[2].slavePort = "eth0"
*.tsnSwitch4.gptp.domain[3].masterPorts = ["eth1"]
*.tsnSwitch4.gptp.domain[3].slavePort = "eth0"
# TSN switch 5
*.tsnSwitch5.gptp.domain[0].masterPorts = ["eth1", "eth2"]
*.tsnSwitch5.gptp.domain[0].slavePort = "eth0"
*.tsnSwitch5.gptp.domain[1].masterPorts = ["eth0", "eth2"]
*.tsnSwitch5.gptp.domain[1].slavePort = "eth1"
*.tsnSwitch5.gptp.domain[2].masterPorts = ["eth1", "eth2"]
*.tsnSwitch5.gptp.domain[2].slavePort = "eth0"
*.tsnSwitch5.gptp.domain[3].masterPorts = ["eth2"]
*.tsnSwitch5.gptp.domain[3].slavePort = "eth1"
# TSN switch 6
*.tsnSwitch6.gptp.domain[0].masterPorts = ["eth2"]
*.tsnSwitch6.gptp.domain[0].slavePort = "eth0"
*.tsnSwitch6.gptp.domain[1].masterPorts = ["eth0", "eth2"]
*.tsnSwitch6.gptp.domain[1].slavePort = "eth1"
*.tsnSwitch6.gptp.domain[2].masterPorts = ["eth1", "eth2"]
*.tsnSwitch6.gptp.domain[2].slavePort = "eth0"
*.tsnSwitch6.gptp.domain[3].masterPorts = ["eth0", "eth2"]
*.tsnSwitch6.gptp.domain[3].slavePort = "eth1"
# TSN devices have multiple clocks
*.tsnDevice*.clock.typename = "MultiClock"
*.tsnDevice*.clock.numClocks = 4
# TSN devices have multiple gPTP time synchronization domains
*.tsnDevice*.gptp.typename = "MultiDomainGptp"
*.tsnDevice*.gptp.numDomains = 4
*.tsnDevice1.gptp.clockModule = "tsnDevice1.clock"
*.tsnDevice2.gptp.clockModule = "tsnDevice2.clock"
*.tsnDevice3.gptp.clockModule = "tsnDevice3.clock"
*.tsnDevice4.gptp.clockModule = "tsnDevice4.clock"
*.tsnDevice*.gptp.domain[*].slavePort = "eth0"
# different initial gPTP pdelay measurement and time synchronization offsets
**.pdelayInitialOffset = 0.1ms
*.*.gptp.domain[0].syncInitialOffset = syncInterval * 1 / 4
*.*.gptp.domain[1].syncInitialOffset = syncInterval * 2 / 4
*.*.gptp.domain[2].syncInitialOffset = syncInterval * 3 / 4
*.*.gptp.domain[3].syncInitialOffset = syncInterval * 4 / 4
# multiple data link visualizers display different gPTP time synchronization domain packets
*.visualizer.typename = "IntegratedMultiCanvasVisualizer"
*.visualizer.numDataLinkVisualizers = 5
*.visualizer.dataLinkVisualizer[*].displayLinks = true
*.visualizer.dataLinkVisualizer[*].activityLevel = "protocol"
*.visualizer.dataLinkVisualizer[0].packetFilter = expr(has(GptpSync) && GptpSync.domainNumber == 0)
*.visualizer.dataLinkVisualizer[1].packetFilter = expr(has(GptpSync) && GptpSync.domainNumber == 1)
*.visualizer.dataLinkVisualizer[2].packetFilter = expr(has(GptpSync) && GptpSync.domainNumber == 2)
*.visualizer.dataLinkVisualizer[3].packetFilter = expr(has(GptpSync) && GptpSync.domainNumber == 3)
*.visualizer.dataLinkVisualizer[0].tags = "primary GM domain0"
*.visualizer.dataLinkVisualizer[1].tags = "primary GM domain1"
*.visualizer.dataLinkVisualizer[2].tags = "hot-standby GM domain0"
*.visualizer.dataLinkVisualizer[3].tags = "hot-standby GM domain1"
*.visualizer.dataLinkVisualizer[0].lineColor = "blue4"
*.visualizer.dataLinkVisualizer[1].lineColor = "blue1"
*.visualizer.dataLinkVisualizer[2].lineColor = "red4"
*.visualizer.dataLinkVisualizer[3].lineColor = "red1"
*.visualizer.dataLinkVisualizer[0..3].fadeOutMode = "realTime"
*.visualizer.dataLinkVisualizer[0..3].fadeOutTime = 5s
# additional data link visualizer displays application packets
*.visualizer.dataLinkVisualizer[4].packetFilter = "source*"
*.visualizer.dataLinkVisualizer[4].tags = "application"
*.visualizer.dataLinkVisualizer[4].lineColor = "black"
# visualize packet drops
*.visualizer.packetDropVisualizer[0].displayPacketDrops = true
# visualize gate schedules
*.visualizer.gateScheduleVisualizer[0].displayGateSchedules = true
*.visualizer.gateScheduleVisualizer[0].gateFilter = "**.eth[1].**"
*.visualizer.gateScheduleVisualizer[0].height = 16
*.visualizer.gateScheduleVisualizer[0].placementHint = "top"
[Config NormalOperation]
description = "Normal operation of time-aware shaping with time synchronization"
[Config LinkFailure]
description = "Master clock link failure effects on time-aware shaping"
extends = NormalOperation
# TSN clock1 disconnects from the network at 2 seconds
*.scenarioManager.script = xml(" \
\
\
\
")
[Config Failover]
description = "Hot-standby master clock takes over time synchronization"
extends = LinkFailure
# TSN clock1 disconnects from the network at 2 seconds
# all multi clocks switch to the 2nd clock submodule
*.scenarioManager.script = xml(" \
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
")