This is an automated email from the ASF dual-hosted git repository.

ldywicki pushed a commit to branch feature/can-stack-tunning
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit a4ad63119d12e6d052a3da67ddf07a1115bcf1d7
Author: Ɓukasz Dywicki <[email protected]>
AuthorDate: Tue Apr 20 01:49:18 2021 +0200

    PLC4X-294 / PLC4X-296 Work in progress.
---
 .../apache/plc4x/java/api/EventPlcConnection.java} |  17 ++-
 .../api/listener/ConnectionStateListener.java}     |  15 +-
 .../plc4x/java/api/listener/EventListener.java}    |  16 +--
 .../api/listener/MessageExchangeListener.java}     |  15 +-
 .../org/apache/plc4x/java/abeth/AbEthDriver.java   |   5 +-
 .../org/apache/plc4x/java/ads/ADSPlcDriver.java    |   5 +-
 .../plc4x/java/canopen/CANOpenPlcDriver.java       |   5 +-
 .../apache/plc4x/java/eip/readwrite/EIPDriver.java |   5 +-
 .../java/firmata/readwrite/FirmataDriver.java      |   5 +-
 .../apache/plc4x/java/knxnetip/KnxNetIpDriver.java |   5 +-
 .../org/apache/plc4x/java/modbus/ModbusDriver.java |   5 +-
 .../apache/plc4x/java/s7/readwrite/S7Driver.java   |   5 +-
 .../plc4x/java/spi/EventListenerMessageCodec.java  |  64 +++++++++
 .../spi/connection/DefaultNettyPlcConnection.java  |  34 +++--
 .../java/spi/connection/GeneratedDriverBase.java   |  13 +-
 .../spi/connection/ProtocolStackConfigurer.java    |   6 +-
 .../connection/SingleProtocolStackConfigurer.java  | 154 ++++++++++++++-------
 .../apache/plc4x/java/bacnetip/BacNetIpDriver.java |   6 +-
 .../org/apache/plc4x/java/df1/DF1PlcDriver.java    |   6 +-
 19 files changed, 262 insertions(+), 124 deletions(-)

diff --git 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
 b/plc4j/api/src/main/java/org/apache/plc4x/java/api/EventPlcConnection.java
similarity index 65%
copy from 
plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
copy to 
plc4j/api/src/main/java/org/apache/plc4x/java/api/EventPlcConnection.java
index aa4a0ab..9df38d0 100644
--- 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/EventPlcConnection.java
@@ -16,16 +16,19 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+package org.apache.plc4x.java.api;
 
-package org.apache.plc4x.java.spi.connection;
+import org.apache.plc4x.java.api.listener.EventListener;
 
-import io.netty.channel.ChannelPipeline;
-import org.apache.plc4x.java.spi.Plc4xProtocolBase;
-import org.apache.plc4x.java.spi.configuration.Configuration;
-import org.apache.plc4x.java.spi.generation.Message;
+/**
+ * An extended kind of connection which can broadcast events.
+ *
+ * Particular type of event might vary, it might be a connection state or 
message exchange.
+ */
+public interface EventPlcConnection extends PlcConnection {
 
-public interface ProtocolStackConfigurer<T extends Message> {
+    void addEventListener(EventListener listener);
 
-    Plc4xProtocolBase<T> configurePipeline(Configuration configuration, 
ChannelPipeline pipeline, boolean passive);
+    void removeEventListener(EventListener listener);
 
 }
diff --git 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
 
b/plc4j/api/src/main/java/org/apache/plc4x/java/api/listener/ConnectionStateListener.java
similarity index 65%
copy from 
plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
copy to 
plc4j/api/src/main/java/org/apache/plc4x/java/api/listener/ConnectionStateListener.java
index aa4a0ab..8ab8282 100644
--- 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
+++ 
b/plc4j/api/src/main/java/org/apache/plc4x/java/api/listener/ConnectionStateListener.java
@@ -16,16 +16,15 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+package org.apache.plc4x.java.api.listener;
 
-package org.apache.plc4x.java.spi.connection;
-
-import io.netty.channel.ChannelPipeline;
-import org.apache.plc4x.java.spi.Plc4xProtocolBase;
-import org.apache.plc4x.java.spi.configuration.Configuration;
-import org.apache.plc4x.java.spi.generation.Message;
+/**
+ * Additional helper for tracking connection state.
+ */
+public interface ConnectionStateListener extends EventListener {
 
-public interface ProtocolStackConfigurer<T extends Message> {
+    void connected();
 
-    Plc4xProtocolBase<T> configurePipeline(Configuration configuration, 
ChannelPipeline pipeline, boolean passive);
+    void disconnected();
 
 }
diff --git 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
 b/plc4j/api/src/main/java/org/apache/plc4x/java/api/listener/EventListener.java
similarity index 65%
copy from 
plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
copy to 
plc4j/api/src/main/java/org/apache/plc4x/java/api/listener/EventListener.java
index aa4a0ab..7dcc34a 100644
--- 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
+++ 
b/plc4j/api/src/main/java/org/apache/plc4x/java/api/listener/EventListener.java
@@ -16,16 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+package org.apache.plc4x.java.api.listener;
 
-package org.apache.plc4x.java.spi.connection;
-
-import io.netty.channel.ChannelPipeline;
-import org.apache.plc4x.java.spi.Plc4xProtocolBase;
-import org.apache.plc4x.java.spi.configuration.Configuration;
-import org.apache.plc4x.java.spi.generation.Message;
-
-public interface ProtocolStackConfigurer<T extends Message> {
-
-    Plc4xProtocolBase<T> configurePipeline(Configuration configuration, 
ChannelPipeline pipeline, boolean passive);
-
+/**
+ * High level definition for event listeners.
+ */
+public interface EventListener {
 }
diff --git 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
 
b/plc4j/api/src/main/java/org/apache/plc4x/java/api/listener/MessageExchangeListener.java
similarity index 65%
copy from 
plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
copy to 
plc4j/api/src/main/java/org/apache/plc4x/java/api/listener/MessageExchangeListener.java
index aa4a0ab..6793345 100644
--- 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
+++ 
b/plc4j/api/src/main/java/org/apache/plc4x/java/api/listener/MessageExchangeListener.java
@@ -16,16 +16,15 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+package org.apache.plc4x.java.api.listener;
 
-package org.apache.plc4x.java.spi.connection;
-
-import io.netty.channel.ChannelPipeline;
-import org.apache.plc4x.java.spi.Plc4xProtocolBase;
-import org.apache.plc4x.java.spi.configuration.Configuration;
-import org.apache.plc4x.java.spi.generation.Message;
+/**
+ * Additional helper to propagate events.
+ */
+public interface MessageExchangeListener extends EventListener {
 
-public interface ProtocolStackConfigurer<T extends Message> {
+    void received(Object message);
 
-    Plc4xProtocolBase<T> configurePipeline(Configuration configuration, 
ChannelPipeline pipeline, boolean passive);
+    void sending(Object message);
 
 }
diff --git 
a/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/AbEthDriver.java
 
b/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/AbEthDriver.java
index d12b791..699bb74 100644
--- 
a/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/AbEthDriver.java
+++ 
b/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/AbEthDriver.java
@@ -26,6 +26,7 @@ import 
org.apache.plc4x.java.abeth.protocol.AbEthProtocolLogic;
 import org.apache.plc4x.java.abeth.readwrite.CIPEncapsulationPacket;
 import org.apache.plc4x.java.abeth.readwrite.io.CIPEncapsulationPacketIO;
 import org.apache.plc4x.java.api.model.PlcField;
+import org.apache.plc4x.java.spi.transport.Transport;
 import org.apache.plc4x.java.spi.values.IEC61131ValueHandler;
 import org.apache.plc4x.java.api.value.PlcValueHandler;
 import org.apache.plc4x.java.spi.configuration.Configuration;
@@ -80,8 +81,8 @@ public class AbEthDriver extends 
GeneratedDriverBase<CIPEncapsulationPacket> {
     }
 
     @Override
-    protected ProtocolStackConfigurer<CIPEncapsulationPacket> 
getStackConfigurer() {
-        return 
SingleProtocolStackConfigurer.builder(CIPEncapsulationPacket.class, 
CIPEncapsulationPacketIO.class)
+    protected ProtocolStackConfigurer<CIPEncapsulationPacket> 
getStackConfigurer(Configuration configuration, Transport transport) {
+        return 
SingleProtocolStackConfigurer.builder(CIPEncapsulationPacket.class, 
CIPEncapsulationPacketIO.class, configuration)
             .withProtocol(AbEthProtocolLogic.class)
             .withPacketSizeEstimator(ByteLengthEstimator.class)
             .build();
diff --git 
a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/ADSPlcDriver.java 
b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/ADSPlcDriver.java
index 9161ce4..9379799 100644
--- 
a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/ADSPlcDriver.java
+++ 
b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/ADSPlcDriver.java
@@ -24,6 +24,7 @@ import org.apache.plc4x.java.ads.field.AdsFieldHandler;
 import org.apache.plc4x.java.ads.protocol.AdsProtocolLogic;
 import org.apache.plc4x.java.ads.readwrite.AmsTCPPacket;
 import org.apache.plc4x.java.ads.readwrite.io.AmsTCPPacketIO;
+import org.apache.plc4x.java.spi.transport.Transport;
 import org.apache.plc4x.java.spi.values.IEC61131ValueHandler;
 import org.apache.plc4x.java.api.value.PlcValueHandler;
 import org.apache.plc4x.java.spi.configuration.Configuration;
@@ -93,8 +94,8 @@ public class ADSPlcDriver extends 
GeneratedDriverBase<AmsTCPPacket> {
     }
 
     @Override
-    protected ProtocolStackConfigurer<AmsTCPPacket> getStackConfigurer() {
-        return SingleProtocolStackConfigurer.builder(AmsTCPPacket.class, 
AmsTCPPacketIO.class)
+    protected ProtocolStackConfigurer<AmsTCPPacket> 
getStackConfigurer(Configuration configuration, Transport transport) {
+        return SingleProtocolStackConfigurer.builder(AmsTCPPacket.class, 
AmsTCPPacketIO.class, configuration)
             .withPacketSizeEstimator(ByteLengthEstimator.class)
             .withProtocol(AdsProtocolLogic.class)
             .littleEndian()
diff --git 
a/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/CANOpenPlcDriver.java
 
b/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/CANOpenPlcDriver.java
index 36774a2..dd75d16 100644
--- 
a/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/CANOpenPlcDriver.java
+++ 
b/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/CANOpenPlcDriver.java
@@ -34,6 +34,7 @@ import 
org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.optimizer.BaseOptimizer;
 import org.apache.plc4x.java.spi.optimizer.SingleFieldOptimizer;
+import org.apache.plc4x.java.spi.transport.Transport;
 import org.apache.plc4x.java.spi.values.IEC61131ValueHandler;
 import org.apache.plc4x.java.spi.values.PlcList;
 
@@ -111,8 +112,8 @@ public class CANOpenPlcDriver extends 
GeneratedDriverBase<CANOpenFrame> {
     }
 
     @Override
-    protected ProtocolStackConfigurer<CANOpenFrame> getStackConfigurer() {
-        return SingleProtocolStackConfigurer.builder(CANOpenFrame.class, 
CANOpenSocketCANFrameIO.class)
+    protected ProtocolStackConfigurer<CANOpenFrame> 
getStackConfigurer(Configuration configuration, Transport transport) {
+        return SingleProtocolStackConfigurer.builder(CANOpenFrame.class, 
CANOpenSocketCANFrameIO.class, configuration)
             .withProtocol(CANOpenProtocolLogic.class)
             .withDriverContext(CANOpenDriverContext.class)
             .withPacketSizeEstimator(CANEstimator.class)
diff --git 
a/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/readwrite/EIPDriver.java
 
b/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/readwrite/EIPDriver.java
index 3fcb65d..c4fc664 100644
--- 
a/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/readwrite/EIPDriver.java
+++ 
b/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/readwrite/EIPDriver.java
@@ -24,6 +24,7 @@ import org.apache.plc4x.java.eip.readwrite.field.EipField;
 import org.apache.plc4x.java.eip.readwrite.field.EipFieldHandler;
 import org.apache.plc4x.java.eip.readwrite.io.EipPacketIO;
 import org.apache.plc4x.java.eip.readwrite.protocol.EipProtocolLogic;
+import org.apache.plc4x.java.spi.transport.Transport;
 import org.apache.plc4x.java.spi.values.IEC61131ValueHandler;
 import org.apache.plc4x.java.api.value.PlcValueHandler;
 import org.apache.plc4x.java.spi.configuration.Configuration;
@@ -87,8 +88,8 @@ public class EIPDriver extends GeneratedDriverBase<EipPacket> 
{
     }
 
     @Override
-    protected ProtocolStackConfigurer<EipPacket> getStackConfigurer() {
-        return SingleProtocolStackConfigurer.builder(EipPacket.class, 
EipPacketIO.class)
+    protected ProtocolStackConfigurer<EipPacket> 
getStackConfigurer(Configuration configuration, Transport transport) {
+        return SingleProtocolStackConfigurer.builder(EipPacket.class, 
EipPacketIO.class, configuration)
             .withProtocol(EipProtocolLogic.class)
             .withPacketSizeEstimator(ByteLengthEstimator.class)
             .littleEndian()
diff --git 
a/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/FirmataDriver.java
 
b/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/FirmataDriver.java
index 923d7cc..aeba67e 100644
--- 
a/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/FirmataDriver.java
+++ 
b/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/FirmataDriver.java
@@ -26,6 +26,7 @@ import 
org.apache.plc4x.java.firmata.readwrite.field.FirmataField;
 import org.apache.plc4x.java.firmata.readwrite.field.FirmataFieldHandler;
 import org.apache.plc4x.java.firmata.readwrite.io.FirmataMessageIO;
 import org.apache.plc4x.java.firmata.readwrite.protocol.FirmataProtocolLogic;
+import org.apache.plc4x.java.spi.transport.Transport;
 import org.apache.plc4x.java.spi.values.IEC61131ValueHandler;
 import org.apache.plc4x.java.api.value.PlcValueHandler;
 import org.apache.plc4x.java.spi.configuration.Configuration;
@@ -89,8 +90,8 @@ public class FirmataDriver extends 
GeneratedDriverBase<FirmataMessage> {
     }
 
     @Override
-    protected ProtocolStackConfigurer<FirmataMessage> getStackConfigurer() {
-        return SingleProtocolStackConfigurer.builder(FirmataMessage.class, 
FirmataMessageIO.class)
+    protected ProtocolStackConfigurer<FirmataMessage> 
getStackConfigurer(Configuration configuration, Transport transport) {
+        return SingleProtocolStackConfigurer.builder(FirmataMessage.class, 
FirmataMessageIO.class, configuration)
             .withProtocol(FirmataProtocolLogic.class)
             .withDriverContext(FirmataDriverContext.class)
             .withPacketSizeEstimator(ByteLengthEstimator.class)
diff --git 
a/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/KnxNetIpDriver.java
 
b/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/KnxNetIpDriver.java
index e1a5348..e7148c6 100644
--- 
a/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/KnxNetIpDriver.java
+++ 
b/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/KnxNetIpDriver.java
@@ -27,6 +27,7 @@ import 
org.apache.plc4x.java.knxnetip.readwrite.io.KnxNetIpMessageIO;
 import org.apache.plc4x.java.spi.configuration.Configuration;
 import org.apache.plc4x.java.knxnetip.field.KnxNetIpFieldHandler;
 import org.apache.plc4x.java.knxnetip.protocol.KnxNetIpProtocolLogic;
+import org.apache.plc4x.java.spi.transport.Transport;
 import org.apache.plc4x.java.spi.values.IEC61131ValueHandler;
 import org.apache.plc4x.java.api.value.PlcValueHandler;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
@@ -96,8 +97,8 @@ public class KnxNetIpDriver extends 
GeneratedDriverBase<KnxNetIpMessage> {
     protected boolean awaitDisconnectComplete() { return true; }
 
     @Override
-    protected ProtocolStackConfigurer<KnxNetIpMessage> getStackConfigurer() {
-        return SingleProtocolStackConfigurer.builder(KnxNetIpMessage.class, 
KnxNetIpMessageIO.class)
+    protected ProtocolStackConfigurer<KnxNetIpMessage> 
getStackConfigurer(Configuration configuration, Transport transport) {
+        return SingleProtocolStackConfigurer.builder(KnxNetIpMessage.class, 
KnxNetIpMessageIO.class, configuration)
             .withProtocol(KnxNetIpProtocolLogic.class)
             .withDriverContext(KnxNetIpDriverContext.class)
             .withPacketSizeEstimator(PacketSizeEstimator.class)
diff --git 
a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ModbusDriver.java
 
b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ModbusDriver.java
index 673ca18..11fdded 100644
--- 
a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ModbusDriver.java
+++ 
b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ModbusDriver.java
@@ -25,6 +25,7 @@ import org.apache.plc4x.java.modbus.field.ModbusFieldHandler;
 import org.apache.plc4x.java.modbus.protocol.ModbusProtocolLogic;
 import org.apache.plc4x.java.modbus.readwrite.ModbusTcpADU;
 import org.apache.plc4x.java.modbus.readwrite.io.ModbusTcpADUIO;
+import org.apache.plc4x.java.spi.transport.Transport;
 import org.apache.plc4x.java.spi.values.IEC61131ValueHandler;
 import org.apache.plc4x.java.api.value.PlcValueHandler;
 import org.apache.plc4x.java.spi.configuration.Configuration;
@@ -102,8 +103,8 @@ public class ModbusDriver extends 
GeneratedDriverBase<ModbusTcpADU> {
     }
 
     @Override
-    protected ProtocolStackConfigurer<ModbusTcpADU> getStackConfigurer() {
-        return SingleProtocolStackConfigurer.builder(ModbusTcpADU.class, 
ModbusTcpADUIO.class)
+    protected ProtocolStackConfigurer<ModbusTcpADU> 
getStackConfigurer(Configuration configuration, Transport transport) {
+        return SingleProtocolStackConfigurer.builder(ModbusTcpADU.class, 
ModbusTcpADUIO.class, configuration)
             .withProtocol(ModbusProtocolLogic.class)
             .withPacketSizeEstimator(ByteLengthEstimator.class)
             // Every incoming message is to be treated as a response.
diff --git 
a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/S7Driver.java
 
b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/S7Driver.java
index dd90664..e6c56b8 100644
--- 
a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/S7Driver.java
+++ 
b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/S7Driver.java
@@ -32,6 +32,7 @@ import 
org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
 import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.optimizer.BaseOptimizer;
+import org.apache.plc4x.java.spi.transport.Transport;
 import org.apache.plc4x.java.spi.values.IEC61131ValueHandler;
 
 import java.util.function.Consumer;
@@ -96,8 +97,8 @@ public class S7Driver extends GeneratedDriverBase<TPKTPacket> 
{
     }
 
     @Override
-    protected ProtocolStackConfigurer<TPKTPacket> getStackConfigurer() {
-        return SingleProtocolStackConfigurer.builder(TPKTPacket.class, 
TPKTPacketIO.class)
+    protected ProtocolStackConfigurer<TPKTPacket> 
getStackConfigurer(Configuration configuration, Transport transport) {
+        return SingleProtocolStackConfigurer.builder(TPKTPacket.class, 
TPKTPacketIO.class, configuration)
             .withProtocol(S7ProtocolLogic.class)
             .withDriverContext(S7DriverContext.class)
             .withPacketSizeEstimator(ByteLengthEstimator.class)
diff --git 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/EventListenerMessageCodec.java
 
b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/EventListenerMessageCodec.java
new file mode 100644
index 0000000..7ab8d4f
--- /dev/null
+++ 
b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/EventListenerMessageCodec.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.plc4x.java.spi;
+
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToMessageCodec;
+import org.apache.plc4x.java.api.listener.EventListener;
+import org.apache.plc4x.java.api.listener.MessageExchangeListener;
+import org.apache.plc4x.java.spi.generation.Message;
+
+import java.util.List;
+
+/**
+ * Codec which propagate received or sent messages to connection event 
listeners.
+ */
+public class EventListenerMessageCodec extends MessageToMessageCodec<Message, 
Message> {
+
+    private final List<EventListener> listeners;
+
+    public EventListenerMessageCodec(List<EventListener> listeners) {
+        this.listeners = listeners;
+    }
+
+    @Override
+    protected void encode(ChannelHandlerContext ctx, Message msg, List<Object> 
out) throws Exception {
+        if (msg instanceof Message) {
+            for (EventListener listener : listeners) {
+                if (listener instanceof MessageExchangeListener) {
+                    ((MessageExchangeListener) listener).sending(msg);
+                }
+            }
+        }
+        out.add(msg);
+    }
+
+    @Override
+    protected void decode(ChannelHandlerContext ctx, Message msg, List<Object> 
out) throws Exception {
+        if (msg instanceof Message) {
+            for (EventListener listener : listeners) {
+                if (listener instanceof MessageExchangeListener) {
+                    ((MessageExchangeListener) listener).received(msg);
+                }
+            }
+        }
+        out.add(msg);
+    }
+
+}
diff --git 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java
 
b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java
index 177ef71..8ca6d76 100644
--- 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java
+++ 
b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java
@@ -21,21 +21,27 @@ package org.apache.plc4x.java.spi.connection;
 import io.netty.channel.*;
 import io.netty.util.HashedWheelTimer;
 import io.netty.util.Timer;
+import org.apache.plc4x.java.api.EventPlcConnection;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
 import org.apache.plc4x.java.api.exceptions.PlcIoException;
+import org.apache.plc4x.java.api.listener.ConnectionStateListener;
+import org.apache.plc4x.java.api.listener.EventListener;
+import org.apache.plc4x.java.api.value.PlcValueHandler;
 import org.apache.plc4x.java.spi.configuration.Configuration;
 import org.apache.plc4x.java.spi.configuration.ConfigurationFactory;
 import org.apache.plc4x.java.spi.events.*;
 import org.apache.plc4x.java.spi.optimizer.BaseOptimizer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.apache.plc4x.java.api.value.PlcValueHandler;
 
+import java.util.List;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
 
-public class DefaultNettyPlcConnection extends AbstractPlcConnection 
implements ChannelExposingConnection {
+public class DefaultNettyPlcConnection extends AbstractPlcConnection 
implements ChannelExposingConnection, EventPlcConnection {
 
     /**
      * a {@link HashedWheelTimer} shall be only instantiated once.
@@ -45,22 +51,21 @@ public class DefaultNettyPlcConnection extends 
AbstractPlcConnection implements
     protected final static long DEFAULT_DISCONNECT_WAIT_TIME = 10000L;
     private static final Logger logger = 
LoggerFactory.getLogger(DefaultNettyPlcConnection.class);
 
-    protected final Configuration configuration;
     protected final ChannelFactory channelFactory;
     protected final boolean awaitSessionSetupComplete;
     protected final boolean awaitSessionDisconnectComplete;
     protected final ProtocolStackConfigurer stackConfigurer;
+    protected final List<EventListener> listeners = new 
CopyOnWriteArrayList<>();
     protected final CompletableFuture<Void> sessionDisconnectCompleteFuture = 
new CompletableFuture<>();
 
     protected Channel channel;
     protected boolean connected;
 
     public DefaultNettyPlcConnection(boolean canRead, boolean canWrite, 
boolean canSubscribe,
-                                     PlcFieldHandler fieldHandler, 
PlcValueHandler valueHandler, Configuration configuration,
+                                     PlcFieldHandler fieldHandler, 
PlcValueHandler valueHandler,
                                      ChannelFactory channelFactory, boolean 
awaitSessionSetupComplete,
                                      boolean awaitSessionDisconnectComplete, 
ProtocolStackConfigurer stackConfigurer, BaseOptimizer optimizer) {
         super(canRead, canWrite, canSubscribe, fieldHandler, valueHandler, 
optimizer);
-        this.configuration = configuration;
         this.channelFactory = channelFactory;
         this.awaitSessionSetupComplete = awaitSessionSetupComplete;
         //Used to signal that a disconnect has completed while closing a 
connection.
@@ -82,9 +87,6 @@ public class DefaultNettyPlcConnection extends 
AbstractPlcConnection implements
                 throw new PlcConnectionException("No channel factory 
provided");
             }
 
-            // Inject the configuration
-            ConfigurationFactory.configure(configuration, channelFactory);
-
             // Have the channel factory create a new channel instance.
             channel = 
channelFactory.createChannel(getChannelHandler(sessionSetupCompleteFuture, 
sessionDisconnectCompleteFuture));
             channel.closeFuture().addListener(future -> {
@@ -170,10 +172,14 @@ public class DefaultNettyPlcConnection extends 
AbstractPlcConnection implements
                 pipeline.addLast(new ChannelInboundHandlerAdapter() {
                     @Override
                     public void userEventTriggered(ChannelHandlerContext ctx, 
Object evt) throws Exception {
+                        Stream<ConnectionStateListener> eventListeners = 
listeners.stream().filter(ConnectionStateListener.class::isInstance)
+                            .map(ConnectionStateListener.class::cast);
                         if (evt instanceof ConnectedEvent) {
                             sessionSetupCompleteFuture.complete(null);
+                            
eventListeners.forEach(ConnectionStateListener::connected);
                         } else if (evt instanceof DisconnectedEvent) {
                             sessionDisconnectCompleteFuture.complete(null);
+                            
eventListeners.forEach(ConnectionStateListener::disconnected);
                         } else {
                             super.userEventTriggered(ctx, evt);
                         }
@@ -182,7 +188,7 @@ public class DefaultNettyPlcConnection extends 
AbstractPlcConnection implements
                 // Initialize via Transport Layer
                 channelFactory.initializePipeline(pipeline);
                 // Initialize Protocol Layer
-                setProtocol(stackConfigurer.configurePipeline(configuration, 
pipeline, channelFactory.isPassive()));
+                setProtocol(stackConfigurer.configurePipeline(pipeline, 
channelFactory.isPassive(), listeners));
             }
         };
     }
@@ -193,4 +199,14 @@ public class DefaultNettyPlcConnection extends 
AbstractPlcConnection implements
         channel.pipeline().fireUserEventTriggered(new ConnectEvent());
     }
 
+    @Override
+    public void addEventListener(EventListener listener) {
+        listeners.add(listener);
+    }
+
+    @Override
+    public void removeEventListener(EventListener listener) {
+        listeners.remove(listener);
+    }
+
 }
diff --git 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java
 
b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java
index 6c58d71..78dc459 100644
--- 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java
+++ 
b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java
@@ -77,7 +77,7 @@ public abstract class GeneratedDriverBase<BASE_PACKET extends 
Message> implement
 
     protected abstract String getDefaultTransport();
 
-    protected abstract ProtocolStackConfigurer<BASE_PACKET> 
getStackConfigurer();
+    protected abstract ProtocolStackConfigurer<BASE_PACKET> 
getStackConfigurer(Configuration configuration, Transport transport);
 
     protected void initializePipeline(ChannelFactory channelFactory) {
         // Override in derived drivers.
@@ -98,7 +98,7 @@ public abstract class GeneratedDriverBase<BASE_PACKET extends 
Message> implement
         final String paramString = matcher.group("paramString");
 
         // Check if the protocol code matches this driver.
-        if(!protocolCode.equals(getProtocolCode())) {
+        if (!protocolCode.equals(getProtocolCode())) {
             // Actually this shouldn't happen as the DriverManager should have 
not used this driver in the first place.
             throw new PlcConnectionException(
                 "This driver is not suited to handle this connection string");
@@ -107,7 +107,7 @@ public abstract class GeneratedDriverBase<BASE_PACKET 
extends Message> implement
         // Create the configuration object.
         Configuration configuration = new 
ConfigurationFactory().createConfiguration(
             getConfigurationType(), paramString);
-        if(configuration == null) {
+        if (configuration == null) {
             throw new PlcConnectionException("Unsupported configuration");
         }
 
@@ -116,12 +116,12 @@ public abstract class GeneratedDriverBase<BASE_PACKET 
extends Message> implement
         ServiceLoader<Transport> transportLoader = ServiceLoader.load(
             Transport.class, Thread.currentThread().getContextClassLoader());
         for (Transport curTransport : transportLoader) {
-            if(curTransport.getTransportCode().equals(transportCode)) {
+            if (curTransport.getTransportCode().equals(transportCode)) {
                 transport = curTransport;
                 break;
             }
         }
-        if(transport == null) {
+        if (transport == null) {
             throw new PlcConnectionException("Unsupported transport " + 
transportCode);
         }
 
@@ -154,11 +154,10 @@ public abstract class GeneratedDriverBase<BASE_PACKET 
extends Message> implement
             canRead(), canWrite(), canSubscribe(),
             getFieldHandler(),
             getValueHandler(),
-            configuration,
             channelFactory,
             awaitSetupComplete,
             awaitDisconnectComplete,
-            getStackConfigurer(),
+            getStackConfigurer(configuration, transport),
             getOptimizer());
     }
 
diff --git 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
 
b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
index aa4a0ab..163161b 100644
--- 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
+++ 
b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/ProtocolStackConfigurer.java
@@ -20,12 +20,14 @@
 package org.apache.plc4x.java.spi.connection;
 
 import io.netty.channel.ChannelPipeline;
+import org.apache.plc4x.java.api.listener.EventListener;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
-import org.apache.plc4x.java.spi.configuration.Configuration;
 import org.apache.plc4x.java.spi.generation.Message;
 
+import java.util.List;
+
 public interface ProtocolStackConfigurer<T extends Message> {
 
-    Plc4xProtocolBase<T> configurePipeline(Configuration configuration, 
ChannelPipeline pipeline, boolean passive);
+    Plc4xProtocolBase<T> configurePipeline(ChannelPipeline pipeline, boolean 
passive, List<EventListener> listeners);
 
 }
diff --git 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/SingleProtocolStackConfigurer.java
 
b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/SingleProtocolStackConfigurer.java
index 54b1747..a6ae4f8 100644
--- 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/SingleProtocolStackConfigurer.java
+++ 
b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/SingleProtocolStackConfigurer.java
@@ -25,15 +25,20 @@ import io.netty.buffer.ByteBuf;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelPipeline;
 import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
+import org.apache.plc4x.java.api.listener.EventListener;
+import org.apache.plc4x.java.spi.EventListenerMessageCodec;
 import org.apache.plc4x.java.spi.Plc4xNettyWrapper;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.configuration.Configuration;
 import org.apache.plc4x.java.spi.context.DriverContext;
+import org.apache.plc4x.java.spi.context.ToolingContext;
 import org.apache.plc4x.java.spi.generation.Message;
 import org.apache.plc4x.java.spi.generation.MessageIO;
 
 import java.lang.reflect.InvocationTargetException;
+import java.util.List;
 import java.util.function.Consumer;
+import java.util.function.Supplier;
 import java.util.function.ToIntFunction;
 
 /**
@@ -42,69 +47,57 @@ import java.util.function.ToIntFunction;
 public class SingleProtocolStackConfigurer<BASE_PACKET_CLASS extends Message> 
implements ProtocolStackConfigurer<BASE_PACKET_CLASS> {
 
     private final Class<BASE_PACKET_CLASS> basePacketClass;
-    private boolean bigEndian = true;
-    private final Class<? extends Plc4xProtocolBase<BASE_PACKET_CLASS>> 
protocolClass;
-    private final Class<? extends DriverContext> driverContextClass;
+    private final boolean bigEndian;
+    private final Supplier<? extends Plc4xProtocolBase<BASE_PACKET_CLASS>> 
protocolSupplier;
+    private final Supplier<? extends DriverContext> driverContextSupplier;
     private final MessageIO<BASE_PACKET_CLASS, BASE_PACKET_CLASS> protocolIO;
-    private final Class<? extends ToIntFunction<ByteBuf>> 
packetSizeEstimatorClass;
-    private final Class<? extends Consumer<ByteBuf>> corruptPacketRemoverClass;
+    private final Supplier<? extends ToIntFunction<ByteBuf>> 
packetSizeEstimatorSupplier;
+    private final Supplier<? extends Consumer<ByteBuf>> 
corruptPacketRemoverSupplier;
     private final Object[] parserArgs;
 
-    public static <BPC extends Message> SingleProtocolStackBuilder<BPC> 
builder(Class<BPC> basePacketClass, Class<? extends MessageIO<BPC, BPC>> 
messageIoClass) {
-        return new SingleProtocolStackBuilder<>(basePacketClass, 
messageIoClass);
+    public static <BPC extends Message> SingleProtocolStackBuilder<BPC> 
builder(Class<BPC> basePacketClass, Class<? extends MessageIO<BPC, BPC>> 
messageIoClass, Configuration configuration) {
+        return new SingleProtocolStackBuilder<>(basePacketClass, 
messageIoClass, configuration);
     }
 
     /** Only accessible via Builder */
     SingleProtocolStackConfigurer(Class<BASE_PACKET_CLASS> basePacketClass,
                                   boolean bigEndian,
                                   Object[] parserArgs,
-                                  Class<? extends 
Plc4xProtocolBase<BASE_PACKET_CLASS>> protocol,
-                                  Class<? extends DriverContext> 
driverContextClass,
+                                  Supplier<? extends 
Plc4xProtocolBase<BASE_PACKET_CLASS>> protocolSupplier,
+                                  Supplier<? extends DriverContext> 
driverContextSupplier,
                                   MessageIO<BASE_PACKET_CLASS, 
BASE_PACKET_CLASS> protocolIO,
-                                  Class<? extends ToIntFunction<ByteBuf>> 
packetSizeEstimatorClass,
-                                  Class<? extends Consumer<ByteBuf>> 
corruptPacketRemoverClass) {
+                                  Supplier<? extends ToIntFunction<ByteBuf>> 
packetSizeEstimatorSupplier,
+                                  Supplier<? extends Consumer<ByteBuf>> 
corruptPacketRemoverSupplier) {
         this.basePacketClass = basePacketClass;
         this.bigEndian = bigEndian;
         this.parserArgs = parserArgs;
-        this.protocolClass = protocol;
-        this.driverContextClass = driverContextClass;
+        this.protocolSupplier = protocolSupplier;
+        this.driverContextSupplier = driverContextSupplier;
         this.protocolIO = protocolIO;
-        this.packetSizeEstimatorClass = packetSizeEstimatorClass;
-        this.corruptPacketRemoverClass = corruptPacketRemoverClass;
+        this.packetSizeEstimatorSupplier = packetSizeEstimatorSupplier;
+        this.corruptPacketRemoverSupplier = corruptPacketRemoverSupplier;
     }
 
-    private ChannelHandler getMessageCodec(Configuration configuration) {
+    private ChannelHandler getMessageCodec() {
         return new GeneratedProtocolMessageCodec<>(basePacketClass, 
protocolIO, bigEndian, parserArgs,
-            packetSizeEstimatorClass != null ? configure(configuration, 
createInstance(packetSizeEstimatorClass)) : null,
-            corruptPacketRemoverClass != null ? configure(configuration, 
createInstance(corruptPacketRemoverClass)) : null);
+            packetSizeEstimatorSupplier.get(), 
corruptPacketRemoverSupplier.get());
     }
 
     /** Applies the given Stack to the Pipeline */
     @Override
-    public Plc4xProtocolBase<BASE_PACKET_CLASS> configurePipeline(
-            Configuration configuration, ChannelPipeline pipeline, boolean 
passive) {
-        pipeline.addLast(getMessageCodec(configuration));
-        Plc4xProtocolBase<BASE_PACKET_CLASS> protocol = 
configure(configuration, createInstance(protocolClass));
-        if(driverContextClass != null) {
-            protocol.setDriverContext(configure(configuration, 
createInstance(driverContextClass)));
+    public Plc4xProtocolBase<BASE_PACKET_CLASS> 
configurePipeline(ChannelPipeline pipeline, boolean passive, 
List<EventListener> listeners) {
+        pipeline.addLast(getMessageCodec());
+        pipeline.addLast(new EventListenerMessageCodec(listeners));
+        Plc4xProtocolBase<BASE_PACKET_CLASS> protocol = protocolSupplier.get();
+        DriverContext driverContext = driverContextSupplier.get();
+        if (driverContext != null) {
+            protocol.setDriverContext(driverContext);
         }
         Plc4xNettyWrapper<BASE_PACKET_CLASS> context = new 
Plc4xNettyWrapper<>(pipeline, passive, protocol, basePacketClass);
         pipeline.addLast(context);
         return protocol;
     }
 
-    private <T> T createInstance(Class<T> clazz, Object... args) {
-        try {
-            Class<?>[] parameterTypes = new Class<?>[args.length];
-            for(int i = 0; i < args.length; i++) {
-                parameterTypes[i] = args[i].getClass();
-            }
-            return 
clazz.getDeclaredConstructor(parameterTypes).newInstance(args);
-        } catch (InstantiationException | IllegalAccessException | 
InvocationTargetException | NoSuchMethodException  e) {
-            throw new PlcRuntimeException("Error creating instance of class " 
+ clazz.getName());
-        }
-    }
-
     /**
      * Used to Build Instances of {@link SingleProtocolStackConfigurer}.
      *
@@ -114,20 +107,26 @@ public class 
SingleProtocolStackConfigurer<BASE_PACKET_CLASS extends Message> im
 
         private final Class<BASE_PACKET_CLASS> basePacketClass;
         private final Class<? extends MessageIO<BASE_PACKET_CLASS, 
BASE_PACKET_CLASS>> messageIoClass;
-        private Class<? extends DriverContext> driverContextClass;
+        private final Configuration configuration;
+        private Supplier<? extends DriverContext> driverContextSupplier = () 
-> null;
         private boolean bigEndian = true;
         private Object[] parserArgs;
-        private Class<? extends Plc4xProtocolBase<BASE_PACKET_CLASS>> protocol;
-        private Class<? extends ToIntFunction<ByteBuf>> packetSizeEstimator;
-        private Class<? extends Consumer<ByteBuf>> corruptPacketRemover;
+        private Supplier<? extends Plc4xProtocolBase<BASE_PACKET_CLASS>> 
protocolSupplier;
+        private Supplier<? extends ToIntFunction<ByteBuf>> packetSizeEstimator 
= () -> null;
+        private Supplier<? extends Consumer<ByteBuf>> corruptPacketRemover = 
() -> null;
 
-        public SingleProtocolStackBuilder(Class<BASE_PACKET_CLASS> 
basePacketClass, Class<? extends MessageIO<BASE_PACKET_CLASS, 
BASE_PACKET_CLASS>> messageIoClass) {
+        public SingleProtocolStackBuilder(Class<BASE_PACKET_CLASS> 
basePacketClass, Class<? extends MessageIO<BASE_PACKET_CLASS, 
BASE_PACKET_CLASS>> messageIoClass, Configuration configuration) {
             this.basePacketClass = basePacketClass;
             this.messageIoClass = messageIoClass;
+            this.configuration = configuration;
         }
 
         public SingleProtocolStackBuilder<BASE_PACKET_CLASS> 
withDriverContext(Class<? extends DriverContext> driverContextClass) {
-            this.driverContextClass = driverContextClass;
+            return withDriverContext(configuredType(driverContextClass));
+        }
+
+        public SingleProtocolStackBuilder<BASE_PACKET_CLASS> 
withDriverContext(Supplier<? extends DriverContext> driverContextClass) {
+            this.driverContextSupplier = driverContextClass;
             return this;
         }
 
@@ -142,31 +141,86 @@ public class 
SingleProtocolStackConfigurer<BASE_PACKET_CLASS extends Message> im
         }
 
         public SingleProtocolStackBuilder<BASE_PACKET_CLASS> 
withProtocol(Class<? extends Plc4xProtocolBase<BASE_PACKET_CLASS>> protocol) {
-            this.protocol = protocol;
+            return withProtocol(configuredType(protocol));
+        }
+
+        public SingleProtocolStackBuilder<BASE_PACKET_CLASS> 
withProtocol(Supplier<? extends Plc4xProtocolBase<BASE_PACKET_CLASS>> protocol) 
{
+            this.protocolSupplier = protocol;
             return this;
         }
 
         public SingleProtocolStackBuilder<BASE_PACKET_CLASS> 
withPacketSizeEstimator(Class<? extends ToIntFunction<ByteBuf>> 
packetSizeEstimator) {
+            return 
withPacketSizeEstimator(configuredType(packetSizeEstimator));
+        }
+
+        public SingleProtocolStackBuilder<BASE_PACKET_CLASS> 
withPacketSizeEstimator(Supplier<? extends ToIntFunction<ByteBuf>> 
packetSizeEstimator) {
             this.packetSizeEstimator = packetSizeEstimator;
             return this;
         }
 
         public SingleProtocolStackBuilder<BASE_PACKET_CLASS> 
withCorruptPacketRemover(Class<? extends Consumer<ByteBuf>> 
corruptPacketRemover) {
+            return 
withCorruptPacketRemover(configuredType(corruptPacketRemover));
+        }
+
+        public SingleProtocolStackBuilder<BASE_PACKET_CLASS> 
withCorruptPacketRemover(Supplier<? extends Consumer<ByteBuf>> 
corruptPacketRemover) {
             this.corruptPacketRemover = corruptPacketRemover;
             return this;
         }
 
         public SingleProtocolStackConfigurer<BASE_PACKET_CLASS> build() {
-            assert this.protocol != null;
+            assert this.protocolSupplier != null;
+            return new SingleProtocolStackConfigurer<>(
+                basePacketClass, bigEndian, parserArgs, protocolSupplier,
+                driverContextSupplier,
+                new SimpleTypeSupplier<>(messageIoClass).get(),
+                packetSizeEstimator,
+                corruptPacketRemover
+            );
+        }
+
+        protected final <T> Supplier<T> configuredType(Class<T> protocol) {
+            return new ConfiguringSupplier<>(() -> configuration, new 
SimpleTypeSupplier<>(protocol));
+        }
+
+    }
+
+    protected static class SimpleTypeSupplier<T> implements Supplier<T> {
+
+        private final Class<T> type;
+
+        public SimpleTypeSupplier(Class<T> type) {
+            this.type = type;
+        }
+
+        @Override
+        public T get() {
             try {
-                final MessageIO messageIo = 
messageIoClass.getDeclaredConstructor().newInstance();
-                return new SingleProtocolStackConfigurer<>(
-                    basePacketClass, bigEndian, parserArgs, protocol, 
driverContextClass, messageIo, packetSizeEstimator, corruptPacketRemover);
-            } catch (InstantiationException | InvocationTargetException | 
NoSuchMethodException | IllegalAccessException e) {
-                throw new PlcRuntimeException("Error initializing MessageIO 
instance", e);
+                return type.getDeclaredConstructor().newInstance();
+            } catch (InstantiationException | IllegalAccessException | 
NoSuchMethodException e) {
+                throw new PlcRuntimeException("Could not construct instance of 
" + type.getName(), e);
+            } catch (InvocationTargetException e) {
+                throw new PlcRuntimeException("Initialization of " + 
type.getName() + " instance raised an error", e);
             }
         }
-
     }
 
+    protected static class ConfiguringSupplier<T> implements Supplier<T> {
+
+        private final Supplier<Configuration> configuration;
+        private final Supplier<T> delegate;
+
+        public ConfiguringSupplier(Supplier<Configuration> configuration, 
Supplier<T> delegate) {
+            this.configuration = configuration;
+            this.delegate = delegate;
+        }
+
+        @Override
+        public T get() {
+            if (configuration == null) {
+                return delegate.get();
+            }
+
+            return configure(configuration.get(), delegate.get());
+        }
+    }
 }
diff --git 
a/sandbox/test-java-bacnetip-driver/src/main/java/org/apache/plc4x/java/bacnetip/BacNetIpDriver.java
 
b/sandbox/test-java-bacnetip-driver/src/main/java/org/apache/plc4x/java/bacnetip/BacNetIpDriver.java
index ff97be5..9d475b8 100644
--- 
a/sandbox/test-java-bacnetip-driver/src/main/java/org/apache/plc4x/java/bacnetip/BacNetIpDriver.java
+++ 
b/sandbox/test-java-bacnetip-driver/src/main/java/org/apache/plc4x/java/bacnetip/BacNetIpDriver.java
@@ -19,7 +19,6 @@ under the License.
 package org.apache.plc4x.java.bacnetip;
 
 import io.netty.buffer.ByteBuf;
-import org.apache.plc4x.java.api.PlcDriver;
 import org.apache.plc4x.java.api.value.PlcValueHandler;
 import org.apache.plc4x.java.bacnetip.configuration.BacNetIpConfiguration;
 import org.apache.plc4x.java.bacnetip.field.BacNetIpFieldHandler;
@@ -30,6 +29,7 @@ import org.apache.plc4x.java.spi.configuration.Configuration;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
 import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
+import org.apache.plc4x.java.spi.transport.Transport;
 import org.apache.plc4x.java.spi.values.IEC61131ValueHandler;
 
 import java.util.function.Consumer;
@@ -85,8 +85,8 @@ public class BacNetIpDriver extends GeneratedDriverBase<BVLC> 
{
     }
 
     @Override
-    protected ProtocolStackConfigurer<BVLC> getStackConfigurer() {
-        return SingleProtocolStackConfigurer.builder(BVLC.class, BVLCIO.class)
+    protected ProtocolStackConfigurer<BVLC> getStackConfigurer(Configuration 
configuration, Transport transport) {
+        return SingleProtocolStackConfigurer.builder(BVLC.class, BVLCIO.class, 
configuration)
             .withProtocol(BacNetIpProtocolLogic.class)
             .withPacketSizeEstimator(ByteLengthEstimator.class)
             .withCorruptPacketRemover(CorruptPackageCleaner.class)
diff --git 
a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/DF1PlcDriver.java
 
b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/DF1PlcDriver.java
index 41be49a..e776710 100644
--- 
a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/DF1PlcDriver.java
+++ 
b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/DF1PlcDriver.java
@@ -18,7 +18,6 @@
  */
 package org.apache.plc4x.java.df1;
 
-import org.apache.plc4x.java.api.PlcDriver;
 import org.apache.plc4x.java.api.value.PlcValueHandler;
 import org.apache.plc4x.java.df1.configuration.Df1Configuration;
 import org.apache.plc4x.java.df1.field.Df1FieldHandler;
@@ -29,6 +28,7 @@ import org.apache.plc4x.java.spi.configuration.Configuration;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
 import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
+import org.apache.plc4x.java.spi.transport.Transport;
 import org.apache.plc4x.java.spi.values.IEC61131ValueHandler;
 
 public class DF1PlcDriver extends GeneratedDriverBase<DF1Command> {
@@ -64,8 +64,8 @@ public class DF1PlcDriver extends 
GeneratedDriverBase<DF1Command> {
     }
 
     @Override
-    protected ProtocolStackConfigurer<DF1Command> getStackConfigurer() {
-        return SingleProtocolStackConfigurer.builder(DF1Command.class, 
DF1CommandIO.class)
+    protected ProtocolStackConfigurer<DF1Command> 
getStackConfigurer(Configuration configuration, Transport transport) {
+        return SingleProtocolStackConfigurer.builder(DF1Command.class, 
DF1CommandIO.class, configuration)
             .withProtocol(Df1ProtocolLogic.class)
             .build();
     }

Reply via email to