You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by jf...@apache.org on 2019/12/19 12:17:29 UTC

[plc4x] branch next-gen-core updated: Introduced generic configuration

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

jfeinauer pushed a commit to branch next-gen-core
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/next-gen-core by this push:
     new d04359b  Introduced generic configuration
d04359b is described below

commit d04359b8a9af99d3a46fe593797a9c89ed7a7f76
Author: Julian Feinauer <j....@pragmaticminds.de>
AuthorDate: Thu Dec 19 13:17:13 2019 +0100

    Introduced generic configuration
---
 .../java/spi/connection/AbstractPlcConnection.java |   5 +-
 .../java/spi/parser/ConfigurationParameter.java    |  33 ++++++
 .../plc4x/java/spi/parser/ConnectionParser.java    | 114 +++++++++++++++++++++
 .../plc4x/java/spi/parser/IntDefaultValue.java     |  33 ++++++
 .../org/apache/plc4x/java/spi/parser/Required.java |  30 ++++++
 .../java/spi/parser/ConnectionParserTest.java      |  49 +++++++++
 .../s7/readwrite/connection/S7Configuration.java   |  50 +++++++++
 .../java/s7/readwrite/connection/S7Connection.java |  93 ++---------------
 .../s7/readwrite/protocol/Plc4xS7Protocol.java     |  42 ++++++--
 9 files changed, 352 insertions(+), 97 deletions(-)

diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/AbstractPlcConnection.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/AbstractPlcConnection.java
index 4b3d2ac..b9c24f3 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/AbstractPlcConnection.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/AbstractPlcConnection.java
@@ -18,6 +18,7 @@
  */
 package org.apache.plc4x.java.spi.connection;
 
+import org.apache.commons.lang3.NotImplementedException;
 import org.apache.plc4x.java.api.PlcConnection;
 import org.apache.plc4x.java.api.exceptions.PlcUnsupportedOperationException;
 import org.apache.plc4x.java.api.messages.PlcReadRequest;
@@ -160,11 +161,11 @@ public abstract class AbstractPlcConnection implements PlcConnection, PlcConnect
     }
 
     @Override public PlcConsumerRegistration register(Consumer<PlcSubscriptionEvent> consumer, Collection<PlcSubscriptionHandle> handles) {
-        return null;
+        throw new NotImplementedException("");
     }
 
     @Override public void unregister(PlcConsumerRegistration registration) {
-
+        throw new NotImplementedException("");
     }
 
     /**
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/ConfigurationParameter.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/ConfigurationParameter.java
new file mode 100644
index 0000000..cfe706d
--- /dev/null
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/ConfigurationParameter.java
@@ -0,0 +1,33 @@
+/*
+ * 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.parser;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ConfigurationParameter {
+
+    String value() default "";
+
+}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/ConnectionParser.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/ConnectionParser.java
new file mode 100644
index 0000000..278d7bc
--- /dev/null
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/ConnectionParser.java
@@ -0,0 +1,114 @@
+/*
+ * 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.parser;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.reflect.FieldUtils;
+
+import java.lang.reflect.Field;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static java.util.stream.Collectors.mapping;
+import static java.util.stream.Collectors.toList;
+
+public class ConnectionParser {
+
+    // TODO Respect Path Params
+    public static <T> T parse(String string, Class<T> pClazz) {
+        Map<String, Field> fieldMap = Arrays.stream(FieldUtils.getAllFields(pClazz))
+            .filter(field -> field.getAnnotation(ConfigurationParameter.class) != null)
+            .collect(Collectors.toMap(Field::getName, Function.identity()));
+
+        T instance;
+        try {
+            instance = pClazz.newInstance();
+        } catch (InstantiationException | IllegalAccessException e) {
+            throw new IllegalStateException();
+        }
+        try {
+            URI url = new URI(string);
+            Map<String, List<String>> stringListMap = splitQuery(url);
+
+            // TODO notify on umatched parameters
+
+            Iterator<Map.Entry<String, Field>> iterator = fieldMap.entrySet().iterator();
+            for (Iterator<Map.Entry<String, Field>> iter = iterator; iter.hasNext(); ) {
+                Map.Entry<String, Field> entry = iter.next();
+                // TODO field name also from annotation
+                if (stringListMap.containsKey(entry.getKey())) {
+                    fieldMap.get(entry.getKey()).setAccessible(true);
+                    fieldMap.get(entry.getKey()).setInt(instance, Integer.parseInt(stringListMap.get(entry.getKey()).get(0)));
+                    iter.remove();
+                } else {
+                    // TODO Implement other types
+                    IntDefaultValue intDefaultValue = fieldMap.get(entry.getKey()).getAnnotation(IntDefaultValue.class);
+                    if (intDefaultValue != null) {
+                        fieldMap.get(entry.getKey()).setAccessible(true);
+                        fieldMap.get(entry.getKey()).setInt(instance, intDefaultValue.value());
+                        iter.remove();
+                    }
+                }
+            }
+
+            List<String> missingFields = fieldMap.entrySet().stream()
+                .filter(entry -> entry.getValue().getAnnotation(Required.class) != null)
+                .map(entry -> entry.getValue().getAnnotation(ConfigurationParameter.class) != null ?
+                    (StringUtils.isBlank(entry.getValue().getAnnotation(ConfigurationParameter.class).value()) ? entry.getKey() : entry.getValue().getAnnotation(ConfigurationParameter.class).value()) : entry.getKey())
+                .collect(toList());
+
+            if (missingFields.size() > 0) {
+                throw new IllegalArgumentException("Missing required fields: " + missingFields);
+            }
+        } catch (URISyntaxException | IllegalAccessException e) {
+            e.printStackTrace();
+        }
+        return instance;
+    }
+
+    /**
+     * https://stackoverflow.com/questions/13592236/parse-a-uri-string-into-name-value-collection/13592567#13592567
+     */
+    public static Map<String, List<String>> splitQuery(URI url) {
+        if (StringUtils.isBlank(url.getQuery())) {
+            return Collections.emptyMap();
+        }
+        return Arrays.stream(url.getQuery().split("&"))
+            .map(ConnectionParser::splitQueryParameter)
+            .collect(Collectors.groupingBy(AbstractMap.SimpleImmutableEntry::getKey, LinkedHashMap::new, mapping(Map.Entry::getValue, toList())));
+    }
+
+    public static AbstractMap.SimpleImmutableEntry<String, String> splitQueryParameter(String it) {
+        final int idx = it.indexOf("=");
+        final String key = idx > 0 ? it.substring(0, idx) : it;
+        final String value = idx > 0 && it.length() > idx + 1 ? it.substring(idx + 1) : null;
+        return new AbstractMap.SimpleImmutableEntry<>(key, value);
+    }
+
+}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/IntDefaultValue.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/IntDefaultValue.java
new file mode 100644
index 0000000..c0ab142
--- /dev/null
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/IntDefaultValue.java
@@ -0,0 +1,33 @@
+/*
+ * 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.parser;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface IntDefaultValue {
+
+    int value();
+
+}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/Required.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/Required.java
new file mode 100644
index 0000000..600aeaa
--- /dev/null
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/parser/Required.java
@@ -0,0 +1,30 @@
+/*
+ * 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.parser;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Required {
+}
diff --git a/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/parser/ConnectionParserTest.java b/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/parser/ConnectionParserTest.java
new file mode 100644
index 0000000..36100fc
--- /dev/null
+++ b/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/parser/ConnectionParserTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.parser;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class ConnectionParserTest {
+
+    @Test
+    void parse() {
+        ConnectionParser parster = new ConnectionParser();
+        PropertiesDescriptor properties = parster.parse("s7://192.168.167.1?rackId=1", PropertiesDescriptor.class);
+
+        assertEquals(1, properties.rackId);
+        assertEquals(1, properties.slotId);
+    }
+
+    static class PropertiesDescriptor {
+
+        @ConfigurationParameter("rackId")
+        @IntDefaultValue(1)
+        private int rackId;
+
+        @ConfigurationParameter("slotId")
+        @IntDefaultValue(1)
+        @Required
+        private int slotId;
+
+    }
+}
\ No newline at end of file
diff --git a/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7Configuration.java b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7Configuration.java
new file mode 100644
index 0000000..ed9ef68
--- /dev/null
+++ b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7Configuration.java
@@ -0,0 +1,50 @@
+/*
+ * 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.s7.readwrite.connection;
+
+import org.apache.plc4x.java.spi.parser.ConfigurationParameter;
+import org.apache.plc4x.java.spi.parser.Required;
+
+public class S7Configuration {
+
+    @ConfigurationParameter("rackId")
+    public short rack = 1;
+    @ConfigurationParameter("slotId")
+    public short slot = 1;
+    @ConfigurationParameter
+    public short pduSize = 1024;
+    @ConfigurationParameter
+    public short maxAmqCaller = 8;
+    @ConfigurationParameter
+    public short maxAmqCallee = 8;
+    @ConfigurationParameter
+    public String controllerType;
+
+    @Override public String toString() {
+        return "Configuration{" +
+            "rack=" + rack +
+            ", slot=" + slot +
+            ", pduSize=" + pduSize +
+            ", maxAmqCaller=" + maxAmqCaller +
+            ", maxAmqCallee=" + maxAmqCallee +
+            ", controllerType='" + controllerType + '\'' +
+            '}';
+    }
+}
diff --git a/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7Connection.java b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7Connection.java
index dfbbcec..2a3abc3 100644
--- a/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7Connection.java
+++ b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7Connection.java
@@ -19,9 +19,7 @@ under the License.
 package org.apache.plc4x.java.s7.readwrite.connection;
 
 import io.netty.channel.*;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.plc4x.java.api.messages.PlcReadRequest;
-import org.apache.plc4x.java.api.messages.PlcReadResponse;
 import org.apache.plc4x.java.api.messages.PlcWriteRequest;
 import org.apache.plc4x.java.api.messages.PlcWriteResponse;
 import org.apache.plc4x.java.spi.connection.ChannelFactory;
@@ -31,22 +29,17 @@ import org.apache.plc4x.java.spi.events.ConnectedEvent;
 import org.apache.plc4x.java.s7.readwrite.TPKTPacket;
 import org.apache.plc4x.java.s7.readwrite.protocol.Plc4xS7Protocol;
 import org.apache.plc4x.java.s7.readwrite.protocol.S7Protocol;
-import org.apache.plc4x.java.s7.readwrite.types.COTPTpduSize;
-import org.apache.plc4x.java.s7.readwrite.types.DeviceGroup;
-import org.apache.plc4x.java.s7.readwrite.types.S7ControllerType;
 import org.apache.plc4x.java.s7.readwrite.utils.S7PlcFieldHandler;
-import org.apache.plc4x.java.s7.readwrite.utils.S7TsapIdEncoder;
 import org.apache.plc4x.java.spi.Plc4xNettyWrapper;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest;
 import org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest;
-import org.apache.plc4x.java.spi.messages.InternalPlcReadRequest;
-import org.apache.plc4x.java.spi.messages.InternalPlcReadResponse;
 import org.apache.plc4x.java.spi.messages.InternalPlcWriteRequest;
 import org.apache.plc4x.java.spi.messages.InternalPlcWriteResponse;
 import org.apache.plc4x.java.spi.messages.PlcReader;
 import org.apache.plc4x.java.spi.messages.PlcRequestContainer;
 import org.apache.plc4x.java.spi.messages.PlcWriter;
+import org.apache.plc4x.java.spi.parser.ConnectionParser;
 import org.apache.plc4x.java.tcp.connection.TcpSocketChannelFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -60,12 +53,7 @@ public class S7Connection extends NettyPlcConnection implements PlcReader, PlcWr
 
     private static final Logger logger = LoggerFactory.getLogger(S7Connection.class);
 
-    private final short rack;
-    private final short slot;
-    private final COTPTpduSize tpduSize;
-    private final short maxAmqCaller;
-    private final short maxAmqCallee;
-    private final S7ControllerType controllerType;
+    private final S7Configuration configuration;
 
     public S7Connection(InetAddress address, String params) {
         this(new TcpSocketChannelFactory(address, ISO_ON_TCP_PORT), params);
@@ -74,64 +62,11 @@ public class S7Connection extends NettyPlcConnection implements PlcReader, PlcWr
     public S7Connection(ChannelFactory channelFactory, String params) {
         super(channelFactory, true, new S7PlcFieldHandler());
 
-        short curRack = 1;
-        short curSlot = 1;
-        short curParamPduSize = 1024;
-        short curParamMaxAmqCaller = 8;
-        short curParamMaxAmqCallee = 8;
-        S7ControllerType curParamControllerType = S7ControllerType.ANY;
-
-        if (!StringUtils.isEmpty(params)) {
-            for (String param : params.split("&")) {
-                String[] paramElements = param.split("=");
-                String paramName = paramElements[0];
-                if (paramElements.length == 2) {
-                    String paramValue = paramElements[1];
-                    switch (paramName) {
-                        case "rack":
-                            curRack = Short.parseShort(paramValue);
-                            break;
-                        case "slot":
-                            curSlot = Short.parseShort(paramValue);
-                            break;
-                        case "pdu-size":
-                            curParamPduSize = Short.parseShort(paramValue);
-                            break;
-                        case "max-amq-caller":
-                            curParamMaxAmqCaller = Short.parseShort(paramValue);
-                            break;
-                        case "max-amq-callee":
-                            curParamMaxAmqCallee = Short.parseShort(paramValue);
-                            break;
-                        case "controller-type":
-                            curParamControllerType = S7ControllerType.valueOf(paramValue);
-                            break;
-                        default:
-                            logger.debug("Unknown parameter {} with value {}", paramName, paramValue);
-                    }
-                } else {
-                    logger.debug("Unknown no-value parameter {}", paramName);
-                }
-            }
-        }
+        configuration = ConnectionParser.parse("a://1.1.1.1/" + params, S7Configuration.class);
 
-        // It seems that the LOGO devices are a little picky about the pdu-size.
-        // Instead of handling this out, they just hang up without any error message.
-        // So in case of a LOGO controller, set this to a known working value.
-        if(curParamControllerType == S7ControllerType.LOGO && curParamPduSize == 1024) {
-            curParamPduSize = 480;
-        }
 
-        this.tpduSize = getNearestMatchingTpduSize(curParamPduSize);
 
-        this.rack = curRack;
-        this.slot = curSlot;
-        this.maxAmqCallee = curParamMaxAmqCallee;
-        this.maxAmqCaller = curParamMaxAmqCaller;
-        this.controllerType = curParamControllerType;
-
-        logger.info("Setting up S7 Connection with: rack {}, slot {}, tpdu-size {}, max-amq-caller {}, " +
-                "max-amq-callee {}", rack, slot, tpduSize, maxAmqCaller, maxAmqCallee);
+        logger.info("Setting up S7 Connection with Configuration: {}", configuration);
     }
 
     @Override
@@ -146,8 +81,7 @@ public class S7Connection extends NettyPlcConnection implements PlcReader, PlcWr
 
     @Override
     protected ChannelHandler getChannelHandler(CompletableFuture<Void> sessionSetupCompleteFuture) {
-        short calledTsapId = S7TsapIdEncoder.encodeS7TsapId(DeviceGroup.OS, 0, 0);
-        short callingTsapId = S7TsapIdEncoder.encodeS7TsapId(DeviceGroup.PG_OR_PC, rack, slot);
+
 
         return new ChannelInitializer<Channel>() {
             @Override
@@ -165,8 +99,7 @@ public class S7Connection extends NettyPlcConnection implements PlcReader, PlcWr
                     }
                 });
                 pipeline.addLast(new S7Protocol());
-                Plc4xProtocolBase<TPKTPacket> plc4xS7Protocol = new Plc4xS7Protocol(callingTsapId, calledTsapId, tpduSize,
-                    maxAmqCaller, maxAmqCallee, controllerType);
+                Plc4xProtocolBase<TPKTPacket> plc4xS7Protocol = new Plc4xS7Protocol(configuration);
                 setProtocol(plc4xS7Protocol);
                 Plc4xNettyWrapper<TPKTPacket> context = new Plc4xNettyWrapper<>(pipeline, plc4xS7Protocol, TPKTPacket.class);
                 pipeline.addLast(context);
@@ -206,18 +139,6 @@ public class S7Connection extends NettyPlcConnection implements PlcReader, PlcWr
         channel.pipeline().fireUserEventTriggered(new ConnectEvent());
     }
 
-    /**
-     * Iterate over all values until one is found that the given tpdu size will fit.
-     * @param tpduSizeParameter requested tpdu size.
-     * @return smallest {@link COTPTpduSize} which will fit a given size of tpdu.
-     */
-    protected COTPTpduSize getNearestMatchingTpduSize(short tpduSizeParameter) {
-        for (COTPTpduSize value : COTPTpduSize.values()) {
-            if(value.getSizeInBytes() >= tpduSizeParameter) {
-                return value;
-            }
-        }
-        return null;
-    }
+
 
 }
diff --git a/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/Plc4xS7Protocol.java b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/Plc4xS7Protocol.java
index 0105d65..0a0b7a3 100644
--- a/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/Plc4xS7Protocol.java
+++ b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/Plc4xS7Protocol.java
@@ -62,14 +62,17 @@ import org.apache.plc4x.java.s7.readwrite.S7VarRequestParameterItemAddress;
 import org.apache.plc4x.java.s7.readwrite.SzlDataTreeItem;
 import org.apache.plc4x.java.s7.readwrite.SzlId;
 import org.apache.plc4x.java.s7.readwrite.TPKTPacket;
+import org.apache.plc4x.java.s7.readwrite.connection.S7Configuration;
 import org.apache.plc4x.java.s7.readwrite.types.COTPProtocolClass;
 import org.apache.plc4x.java.s7.readwrite.types.COTPTpduSize;
 import org.apache.plc4x.java.s7.readwrite.types.DataTransportErrorCode;
 import org.apache.plc4x.java.s7.readwrite.types.DataTransportSize;
+import org.apache.plc4x.java.s7.readwrite.types.DeviceGroup;
 import org.apache.plc4x.java.s7.readwrite.types.S7ControllerType;
 import org.apache.plc4x.java.s7.readwrite.types.SzlModuleTypeClass;
 import org.apache.plc4x.java.s7.readwrite.types.SzlSublist;
 import org.apache.plc4x.java.s7.readwrite.utils.S7Field;
+import org.apache.plc4x.java.s7.readwrite.utils.S7TsapIdEncoder;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest;
@@ -124,15 +127,36 @@ public class Plc4xS7Protocol extends Plc4xProtocolBase<TPKTPacket> {
 
     private static final AtomicInteger tpduGenerator = new AtomicInteger(10);
 
-    public Plc4xS7Protocol(int callingTsapId, int calledTsapId, COTPTpduSize tpduSize,
-                           int maxAmqCaller, int maxAmqCallee, S7ControllerType controllerType) {
-        this.callingTsapId = callingTsapId;
-        this.calledTsapId = calledTsapId;
-        this.cotpTpduSize = tpduSize;
-        this.pduSize = tpduSize.getSizeInBytes() - 16;
-        this.maxAmqCaller = maxAmqCaller;
-        this.maxAmqCallee = maxAmqCallee;
-        this.controllerType = controllerType;
+    public Plc4xS7Protocol(S7Configuration configuration) {
+        this.callingTsapId = S7TsapIdEncoder.encodeS7TsapId(DeviceGroup.PG_OR_PC, configuration.rack, configuration.slot);
+        ;
+        this.calledTsapId = S7TsapIdEncoder.encodeS7TsapId(DeviceGroup.OS, 0, 0);
+
+        this.controllerType = configuration.controllerType == null ? S7ControllerType.ANY : S7ControllerType.valueOf(configuration.controllerType);
+        if (controllerType == S7ControllerType.LOGO && configuration.pduSize == 1024) {
+            configuration.pduSize = 480;
+        }
+
+        this.cotpTpduSize = getNearestMatchingTpduSize(configuration.pduSize);
+        ;
+        this.pduSize = cotpTpduSize.getSizeInBytes() - 16;
+        this.maxAmqCaller = configuration.maxAmqCaller;
+        this.maxAmqCallee = configuration.maxAmqCallee;
+    }
+
+    /**
+     * Iterate over all values until one is found that the given tpdu size will fit.
+     *
+     * @param tpduSizeParameter requested tpdu size.
+     * @return smallest {@link COTPTpduSize} which will fit a given size of tpdu.
+     */
+    protected COTPTpduSize getNearestMatchingTpduSize(short tpduSizeParameter) {
+        for (COTPTpduSize value : COTPTpduSize.values()) {
+            if (value.getSizeInBytes() >= tpduSizeParameter) {
+                return value;
+            }
+        }
+        return null;
     }
 
     @Override