I would like to integrate two sample codes (TAS and gPTP) into the One Master Clock network environment. The following are the .ini and .ned codes.
simpleGptp.ini
[General]
network = OneMasterClockGptpShowcase
**.displayGateSchedules = true
**.gateFilter = "**.eth[1].**"
**.gateScheduleVisualizer.height = 16
**.gateScheduleVisualizer.placementHint = "top"
# client applications
*.tsnDevice1.numApps = 2
*.tsnDevice1.app[*].typename = "UdpSourceApp"
*.tsnDevice1.app[0].display-name = "best effort"
*.tsnDevice1.app[1].display-name = "video"
*.tsnDevice1.app[*].io.destAddress = "tsnDevice2"
*.tsnDevice1.app[0].io.destPort = 1000
*.tsnDevice1.app[1].io.destPort = 1001
*.tsnDevice1.app[*].source.packetLength = 1000B - 54B # 42B = 8B (UDP) + 20B (IP) + 14B (ETH MAC) + 4B (ETH FCS) + 8B (ETH PHY)
*.tsnDevice1.app[0].source.productionInterval = exponential(200us) # ~40Mbps
*.tsnDevice1.app[1].source.productionInterval = exponential(400us) # ~20Mbps
# server applications
*.tsnDevice2.numApps = 2
*.tsnDevice2.app[*].typename = "UdpSinkApp"
*.tsnDevice2.app[0].io.localPort = 1000
*.tsnDevice2.app[1].io.localPort = 1001
# enable outgoing streams
*.tsnDevice1.hasOutgoingStreams = true
# client stream identification
*.tsnDevice1.bridging.streamIdentifier.identifier.mapping = [{stream: "best effort", packetFilter: expr(udp.destPort == 1000)},
{stream: "video", packetFilter: expr(udp.destPort == 1001)}]
# client stream encoding
*.tsnDevice1.bridging.streamCoder.encoder.mapping = [{stream: "best effort", pcp: 0},
{stream: "video", pcp: 4}]
# enable egress traffic shaping
*.tsnSwitch.hasEgressTrafficShaping = true
# time-aware traffic shaping
*.tsnSwitch.eth[*].macLayer.queue.numTrafficClasses = 2
*.tsnSwitch.eth[*].macLayer.queue.*[0].display-name = "best effort"
*.tsnSwitch.eth[*].macLayer.queue.*[1].display-name = "video"
*.tsnSwitch.eth[*].macLayer.queue.transmissionGate[0].offset = 0ms
*.tsnSwitch.eth[*].macLayer.queue.transmissionGate[0].durations = [4ms, 6ms] # period is 10 # length of periods
*.tsnSwitch.eth[*].macLayer.queue.transmissionGate[1].offset = 6ms
*.tsnSwitch.eth[*].macLayer.queue.transmissionGate[1].durations = [2ms, 8ms]
# enable time synchronization in all network nodes
*.*.hasTimeSynchronization = true
# all oscillators have a random constant drift
**.oscillator.typename = "ConstantDriftOscillator"
**.oscillator.driftRate = uniform(-100ppm, 100ppm)
# all Ethernet interfaces have 100 Mbps speed
*.*.eth[*].bitrate = 100Mbps
*.visualizer.typename = "IntegratedMultiCanvasVisualizer"
*.visualizer.infoVisualizer.displayInfos = true
# TSN clock gPTP master ports
*.tsnClock.gptp.masterPorts = ["eth0"]
# TSN switch gPTP bridge master ports
*.tsnSwitch.gptp.masterPorts = ["eth1", "eth2"]
# Set all reference clocks to master clock so the time difference can be visualized
**.referenceClock = "tsnClock.clock"
# data link visualizer displays gPTP time synchronization packets
*.visualizer.dataLinkVisualizer[0].displayLinks = true
*.visualizer.dataLinkVisualizer[0].activityLevel = "protocol"
*.visualizer.dataLinkVisualizer[0].packetFilter = "GptpSync"
*.visualizer.dataLinkVisualizer[0].lineColor = "blue2"
*.visualizer.numInfoVisualizers = 3
*.visualizer.infoVisualizer[0].modules = "*.tsnClock.clock"
*.tsnClock.clock.displayStringTextFormat = "time: %T"
*.visualizer.infoVisualizer[1].modules = "*.tsnSwitch.clock"
*.visualizer.infoVisualizer[1].placementHint = "topLeft"
*.visualizer.infoVisualizer[2].modules = "*.tsnDevice*.clock"
*.visualizer.infoVisualizer[2].placementHint = "bottom"
*.tsnDevice*.clock.displayStringTextFormat = "diff: %d"
*.tsnSwitch.clock.displayStringTextFormat = "diff: %d"
simpleGptp.ned
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//
package tsn_scalability.simulations;
import inet.common.scenario.ScenarioManager;
import inet.networks.base.TsnNetworkBase;
import inet.node.ethernet.EthernetLink;
import inet.node.tsn.TsnClock;
import inet.node.tsn.TsnDevice;
import inet.node.tsn.TsnSwitch;
network OneMasterClockGptpShowcase extends TsnNetworkBase
{
submodules:
tsnClock: TsnClock {
@display("p=500,150");
}
tsnSwitch: TsnSwitch {
@display("p=500,300");
}
tsnDevice1: TsnDevice {
@display("p=400,450");
}
tsnDevice2: TsnDevice {
@display("p=600,450");
}
connections:
tsnClock.ethg++ <--> EthernetLink <--> tsnSwitch.ethg++;
tsnSwitch.ethg++ <--> EthernetLink <--> tsnDevice1.ethg++;
tsnSwitch.ethg++ <--> EthernetLink <--> tsnDevice2.ethg++;
}
omnetpp::common::expression::ExprNode::eval_error: Object nullptr has no member named 'destPort' -- in module (inet::queueing::PacketMultiplexer) OneMasterClockGptpShowcase.tsnDevice1.bridging.directionReverser.join (id=337), at t=0s, event #13
The problem happened when the tsnDevice1 sent the GptpPdelayReq packet passing through the bridging module. If you have any ideas, please let me know. Thank you.
The gPTP packet doesn't contain a UDP header, so you should avoid dereferencing the UDP header if there's none.
For example:
expr(has(udp) && udp.destPort == 1000)
Ideally the gPTP packet is neither part of the video nor the best effort streams.