diff --git a/showcases/tsn/trafficshaping/underthehood/PeekingUnderTheHoodShowcase.anf b/showcases/tsn/trafficshaping/underthehood/PeekingUnderTheHoodShowcase.anf
index c6a032fe204..807255e6553 100644
--- a/showcases/tsn/trafficshaping/underthehood/PeekingUnderTheHoodShowcase.anf
+++ b/showcases/tsn/trafficshaping/underthehood/PeekingUnderTheHoodShowcase.anf
@@ -5,7 +5,1919 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -88,7 +3225,7 @@ utils.export_data_if_needed(df, props)
]]>
-
+
@@ -182,7 +3319,7 @@ utils.export_data_if_needed(df, props)
]]>
-
+
@@ -305,13 +3442,6 @@ utils.export_data_if_needed(df, props)
-
-
-
-
-
-
-
@@ -347,7 +3477,74 @@ utils.export_data_if_needed(df, props)
]]>
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
@@ -458,7 +3655,7 @@ utils.export_data_if_needed(df, props)
]]>
-
+
@@ -478,7 +3675,7 @@ utils.export_data_if_needed(df, props)
]]>
-
+
@@ -534,16 +3731,20 @@ utils.export_data_if_needed(df, props)
]]>
+
-
-
+
+
+
+
-
+
+
-
+
@@ -553,31 +3754,33 @@ utils.export_data_if_needed(df, props)
-
+
-
+
-
-
+
+
-
+
+
-
+
-
+
-
+
+
-
+
-
+
@@ -658,7 +3867,7 @@ utils.export_data_if_needed(df, props)
]]>
-
+
@@ -752,7 +3961,7 @@ utils.export_data_if_needed(df, props)
]]>
-
+
@@ -875,13 +4084,6 @@ utils.export_data_if_needed(df, props)
-
-
-
-
-
-
-
@@ -917,7 +4119,74 @@ utils.export_data_if_needed(df, props)
]]>
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
+
@@ -1028,7 +4297,7 @@ utils.export_data_if_needed(df, props)
]]>
-
+
@@ -1048,7 +4317,7 @@ utils.export_data_if_needed(df, props)
]]>
-
+
@@ -1104,16 +4373,20 @@ utils.export_data_if_needed(df, props)
]]>
+
-
-
+
+
+
+
-
+
+
-
+
@@ -1123,27 +4396,29 @@ utils.export_data_if_needed(df, props)
-
+
-
+
-
-
+
+
-
+
+
-
+
-
+
-
+
+
diff --git a/showcases/tsn/trafficshaping/underthehood/PeekingUnderTheHoodShowcase.ned b/showcases/tsn/trafficshaping/underthehood/PeekingUnderTheHoodShowcase.ned
index f92c1996827..3878d587dd0 100644
--- a/showcases/tsn/trafficshaping/underthehood/PeekingUnderTheHoodShowcase.ned
+++ b/showcases/tsn/trafficshaping/underthehood/PeekingUnderTheHoodShowcase.ned
@@ -9,11 +9,13 @@ import inet.protocolelement.shaper.EligibilityTimeFilter;
import inet.protocolelement.shaper.EligibilityTimeGate;
import inet.protocolelement.shaper.EligibilityTimeMeter;
import inet.protocolelement.shaper.EligibilityTimeQueue;
+import inet.queueing.classifier.ContentBasedClassifier;
import inet.queueing.common.PacketMultiplexer;
import inet.queueing.server.PacketServer;
import inet.queueing.sink.PassivePacketSink;
import inet.queueing.source.ActivePacketSource;
+
network PeekingUnderTheHoodShowcase
{
parameters:
@@ -40,9 +42,12 @@ network PeekingUnderTheHoodShowcase
server: PacketServer {
@display("p=1300,100");
}
- sink: PassivePacketSink {
+ classifier: ContentBasedClassifier {
@display("p=1500,100");
}
+ sink[numSources]: PassivePacketSink {
+ @display("p=1700,100,col,150");
+ }
connections:
for i=0..numSources-1 {
source[i].out --> meter[i].in;
@@ -52,5 +57,8 @@ network PeekingUnderTheHoodShowcase
filter.out --> queue.in;
queue.out --> gate.in;
gate.out --> server.in;
- server.out --> sink.in;
+ server.out --> classifier.in;
+ for i=0..numSources-1 {
+ classifier.out++ --> sink[i].in;
+ }
}
diff --git a/showcases/tsn/trafficshaping/underthehood/doc/index.rst b/showcases/tsn/trafficshaping/underthehood/doc/index.rst
index 209375e4020..c38bf33e925 100644
--- a/showcases/tsn/trafficshaping/underthehood/doc/index.rst
+++ b/showcases/tsn/trafficshaping/underthehood/doc/index.rst
@@ -1,52 +1,206 @@
-Peeking Under the Hood
-======================
+Using Traffic Shapers Independently
+===================================
Goals
-----
-This showcase demonstrates that the scheduling and traffic shaping modules can
-work outside the context of a network node. Doing so may facilitate assembling
-and validating specific complex scheduling and traffic shaping behaviors which
-can be difficult to replicate in a complete network.
+Within the INET framework, scheduling and traffic shaping modules can operate
+independently from a network node. Leveraging these modules in this manner
+offers the advantage of easily constructing and verifying intricate scheduling
+and traffic shaping behaviors that may be challenging to replicate within a
+comprehensive network setup.
+
+In this showcase, we demonstrate the creation of a fully operational
+Asynchronous Traffic Shaper (ATS) by directly interconnecting its individual
+components. Next, we construct a straightforward queueing network by linking the
+ATS to traffic sources and traffic sinks. The key highlight is the observation
+of traffic shaping within the network, achieved by plotting the generated
+traffic both before and after the shaping process.
| INET version: ``4.4``
| Source files location: `inet/showcases/tsn/trafficshaping/underthehood `__
+Asynchronous Traffic Shaping in INET
+------------------------------------
+
+The Asynchronous Traffic Shaper, as defined in the IEEE 802.1Qcr standard,
+effectively smooths traffic flow by capping the data rate to a nominal value
+while permitting certain bursts. In INET, this mechanism is realized through
+four essential modules:
+
+- :ned:`EligibilityTimeMeter`: Calculates the transmission eligibility time, determining when a packet becomes eligible for transmission.
+- :ned:`EligibilityTimeFilter`: Filters out expired packets, those that would wait excessively before becoming eligible for transmission.
+- :ned:`EligibilityTimeQueue`: Stores packets in order of their transmission eligibility time.
+- :ned:`EligibilityTimeGate`: Opens at the transmission eligibility time for the next packet
+
+In a complete network setup, these modules are typically distributed across
+various components of a network node, such as an Ethernet switch. Specifically,
+the meter and filter modules are positioned within the ingress filter of the
+bridging layer, while the queue and gate modules reside in the network
+interfaces. Refer to the annotated image of a :ned:`TsnSwitch` below for a visual
+representation of their locations:
+
+.. figure:: media/TsnSwitch3.png
+ :align: center
+
+The next image displays an internal view of the ingress filter module in the bridging layer of the switch, with the :ned:`EligibilityTimeQueue` and the :ned:`EligibilityTimeFilter`
+modules highlighted:
+
+.. figure:: media/filter2.png
+ :align: center
+
+The following image displays an internal view of the queue module in the Ethernet interface's MAC layer, with the :ned:`EligibilityTimeQueue`
+and :ned:`EligibilityTimeGate` modules highlighted:
+
+.. figure:: media/tas2.png
+ :align: center
+
+.. note:: For more comprehensive information on ATS in a complete network and additional details about ATS configuration,
+ please refer to the :doc:`/showcases/tsn/trafficshaping/asynchronousshaper/doc/index` showcase.
+
The Model
---------
-TODO incomplete
-
-The network contains three independent packet sources which are connected to a
-single asynchronous traffic shaper using a packet multiplexer.
+In the next sections, we present a simulation model, which demonstrates how ATS components can be
+used outside INET network nodes. The network is depicted in the following image:
-.. figure:: media/Network.png
+.. figure:: media/network3.png
:align: center
-The three sources generate the same stochastic traffic. The traffic shaper is
-driven by an active packet server module with a constant processing time.
+The queueing network includes three independent packet sources, each linked to an
+:ned:`EligibilityTimeMeter`, ensuring individual data rate metering for each packet
+stream. These meters are then connected to a single :ned:`EligibilityTimeFilter`
+module that drops expired packets.
+
+Subsequently, the filter is linked to an :ned:`EligibilityTimeQueue`, effectively
+organizing packets based on their transmission eligibility time. From there, the
+queue is connected to an :ned:`EligibilityTimeGate`, which opens to allow packets through in
+accordance with their transmission eligibility time.
+
+Finally, the gate connects to a server responsible for periodically pulling
+packets from the queue while the gate is open. The server then sends these
+packets to one of the packet sinks via a classifier, which separates the three streams.
+
+.. note:: Although there is only one filter, queue, and gate module, the three packet streams are still individually shaped. This is made possible because the transmission eligibility time is calculated per-stream by the three meters.
+
+Traffic
+~~~~~~~
+
+The packet sources generate traffic with different sinusoidal production
+rates:
.. literalinclude:: ../omnetpp.ini
+ :start-at: numSources
+ :end-before: meter
:language: ini
+Traffic Shaping
+~~~~~~~~~~~~~~~
+
+To configure the traffic shaping, we specify the committed information rate and
+burst size parameters in the meter modules. Additionally, we set a maximum residence time
+in the meter, which enables the filter to discard packets that would otherwise
+wait excessively in the queue before becoming eligible for transmission.
+
+The active server module pulls packets from the traffic shaper when the gate
+allows it. We set a constant processing time for each packet in the server, so
+the server tries to pull packets every 0.1ms:
+
+.. literalinclude:: ../omnetpp.ini
+ :start-at: meter
+ :end-at: server
+ :language: ini
+
+Classifying
+~~~~~~~~~~~
+
+To measure and plot the post-shaping data rates of the individual streams,
+we need to separate them.
+To that end, we set up the classifier to
+make traffic flow from each source to its sink counterpart (i.e. ``source[0]`` ->
+``sink[0]`` and so on). The classifier is a :ned:`ContentBasedClassifier`.
+It classifies packets by name, which contains the name of the source
+module:
+
+To measure and plot the post-shaping data rates of individual
+streams, we require their separation. For this purpose, we configure the
+classifier to route traffic from each source to its corresponding sink (e.g.,
+``source[0]`` -> ``sink[0]``, ``source[1]`` -> ``sink[1]``, and so on). Utilizing the
+:ned:`ContentBasedClassifier`, we classify packets based on their names, which include
+the source module's name:
+
+.. literalinclude:: ../omnetpp.ini
+ :start-at: classifier
+ :end-at: classifier
+ :language: ini
+
+.. note:: In a complete network setup, managing streams involves several features, such as stream identification, encoding, and decoding.
+ Typically, packets would be assigned to specific streams using VLAN IDs or PCP (Priority Code Point) numbers.
+
Results
-------
-TODO
+Let's examine the data rate of the corresponding source-sink pairs. We'll
+observe the traffic from the sources and compare it to the traffic arriving at
+the sinks after the shaping process:
+
+.. figure:: media/datarate.png
+ :align: center
+
+The data rate of the sinusoidal source traffic occasionally exceeds the 16Mbps
+per-stream shaper limit. However, the shaper does allow a brief burst before
+limiting the traffic to the configured limit.
+
+Next, we'll examine the relationship between traffic before and after
+shaping, as well as the packet drop rate. Due to having only one filter, we are
+limited to presenting the sum of dropped packets for all streams. Consequently,
+we will display the same data as on the earlier plots but consolidate all streams
+onto a single chart. Additionally, we will include the packet drop rate of the
+filter module to provide a comprehensive overview of the shaping process.
+
+.. figure:: media/drop.png
+ :align: center
+
+Despite the presence of a single combined shaper in the network (comprising one
+filter, queue, and gate), each stream is individually limited to 16Mbps due to
+separate metering. Notably, we can observe a higher packet drop rate when the
+source traffic exceeds the per-stream shaper limit.
+
+Note that as traffic increases above the shaper limit, first some packets are
+stored in the queue to be sent later. If the traffic stays above the shaper
+limit, some packets would have to wait in the queue for longer than the max
+residence time, so the filter drops these excess packets. The drop rate roughly
+follows the incoming traffic rate.
+
+The next chart shows how the queueing time changes:
.. figure:: media/QueueingTime.png
:align: center
-TODO
+The maximum of the queueing time is 10ms, which is due to the max residence time
+set in the filter. Packets that would wait longer in the queue are dropped by
+the filter before getting there.
+
+.. note:: The chart above might give the appearance of three data series
+ plotted with the same color. This is because the streams are metered separately,
+ but the filter doesn't distinguish them.
+
+The next chart shows the queue length:
.. figure:: media/QueueLength.png
:align: center
+The maximum number of packets that can accumulate in the queue from each stream
+is 20, calculated as follows: `average production interval / max residence time
+= 10ms / 0.5ms = 20`. Since the traffic pattern is different for the three
+streams, the 20 packets/stream limit is reached at different times for each of
+them. We can observe on the chart as the queue becomes satured for each stream
+individually. The maximum of the queue length is 60, when all streams reach
+their maximum packet count in the queue.
Sources: :download:`omnetpp.ini <../omnetpp.ini>`, :download:`PeekingUnderTheHoodShowcase.ned <../PeekingUnderTheHoodShowcase.ned>`
Discussion
----------
-Use `this `__ page in the GitHub issue tracker for commenting on this showcase.
-
+Use `this `__ page in the GitHub issue tracker for commenting on this showcase.
\ No newline at end of file
diff --git a/showcases/tsn/trafficshaping/underthehood/omnetpp.ini b/showcases/tsn/trafficshaping/underthehood/omnetpp.ini
index 36b0729255e..b89c929576a 100644
--- a/showcases/tsn/trafficshaping/underthehood/omnetpp.ini
+++ b/showcases/tsn/trafficshaping/underthehood/omnetpp.ini
@@ -1,14 +1,17 @@
[General]
network = PeekingUnderTheHoodShowcase
-sim-time-limit = 1s
+sim-time-limit = 10s
description = "Traffic shaping several packet sources directly"
*.numSources = 3
*.source[*].packetLength = 1000B
-*.source[*].productionInterval = exponential(0.5ms)
+*.source[0].productionInterval = replaceUnit(sin(dropUnit(simTime() * 2)) + 5, "ms") / 10
+*.source[1].productionInterval = replaceUnit(sin(dropUnit(simTime() * 3)) + 5, "ms") / 10
+*.source[2].productionInterval = replaceUnit(sin(dropUnit(simTime() * 1)) + sin(dropUnit(simTime() * 8)) + 5, "ms") / 10
-*.meter[*].committedInformationRate = 8Mbps
+*.meter[*].committedInformationRate = 16Mbps
*.meter[*].committedBurstSize = 10kB
*.meter[*].maxResidenceTime = 10ms
*.server.processingTime = 0.1ms
+*.classifier.packetFilters = ["source[0]*", "source[1]*", "source[2]*"]