You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2019/10/10 09:22:24 UTC

[plc4x] branch develop updated (99532a7 -> f9c8818)

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

cdutz pushed a change to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git.


    from 99532a7  Revised OSGi bundling
     new 6e048af  - Made the java pojo template safe for null arrays - Added enum fileds to the getLengthInBytes method
     new 9caeb4e  - Continued working on the s7 mspec, especially regarding SZL sublists - Introduced enum types
     new f9c8818  - Initiated a plc simulator module - Started working on a s7 server module for the simulator

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../resources/templates/java/pojo-template.ftlh    |  11 +-
 .../s7/src/main/resources/protocols/s7/s7.mspec    | 140 +++++++++++---
 .../pom.xml                                        |  51 +++--
 .../org/apache/plc4x/simulator/PlcSimulator.java   |  88 +++++++++
 .../plc4x/simulator/server/ServerModule.java       |  13 +-
 .../apache/plc4x/simulator/server/s7/S7Server.java |  61 ++++++
 .../plc4x/simulator/server/s7/S7ServerModule.java} |  20 +-
 .../server/s7/protocol/S7Step7Protocol.java}       |  38 ++--
 .../server/s7/protocol/S7Step7ServerProtocol.java  | 207 +++++++++++++++++++++
 .../simulator/simulation/SimulationModule.java     |  25 +--
 .../watertank/WaterTankSimulationModule.java       |  60 ++++++
 .../org.apache.plc4x.simulator.server.ServerModule |   3 +-
 ...che.plc4x.simulator.simulation.SimulationModule |   3 +-
 .../plc-simulator}/src/main/resources/logback.xml  |   0
 14 files changed, 639 insertions(+), 81 deletions(-)
 copy sandbox/{test-java-passive-s7-driver => plc-simulator}/pom.xml (66%)
 create mode 100644 sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/PlcSimulator.java
 copy plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/model/params/S7Parameter.java => sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/ServerModule.java (79%)
 create mode 100644 sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7Server.java
 copy sandbox/{code-gen/src/main/java/org/apache/plc4x/codegen/ast/ExceptionType.java => plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7ServerModule.java} (72%)
 copy sandbox/{test-java-bacnetip-driver/src/main/java/org/apache/plc4x/java/bacnetip/protocol/BacNetIpProtocol.java => plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/protocol/S7Step7Protocol.java} (54%)
 create mode 100644 sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/protocol/S7Step7ServerProtocol.java
 copy plc4j/api/src/main/java/org/apache/plc4x/java/api/metadata/PlcConnectionMetadata.java => sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/simulation/SimulationModule.java (57%)
 create mode 100644 sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/simulation/watertank/WaterTankSimulationModule.java
 copy plc4j/api/src/test/resources/META-INF/services/org.apache.plc4x.java.spi.PlcDriver => sandbox/plc-simulator/src/main/resources/META-INF/services/org.apache.plc4x.simulator.server.ServerModule (93%)
 copy plc4j/api/src/test/resources/META-INF/services/org.apache.plc4x.java.spi.PlcDriver => sandbox/plc-simulator/src/main/resources/META-INF/services/org.apache.plc4x.simulator.simulation.SimulationModule (91%)
 copy {plc4j/examples/hello-world-plc4x => sandbox/plc-simulator}/src/main/resources/logback.xml (100%)


[plc4x] 03/03: - Initiated a plc simulator module - Started working on a s7 server module for the simulator

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit f9c8818b701a9d63711ffd8a6c68a32673247a0e
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Thu Oct 10 11:22:11 2019 +0200

    - Initiated a plc simulator module
    - Started working on a s7 server module for the simulator
---
 sandbox/plc-simulator/pom.xml                      | 129 +++++++++++++
 .../org/apache/plc4x/simulator/PlcSimulator.java   |  88 +++++++++
 .../plc4x/simulator/server/ServerModule.java       |  32 ++++
 .../apache/plc4x/simulator/server/s7/S7Server.java |  61 ++++++
 .../plc4x/simulator/server/s7/S7ServerModule.java  |  40 ++++
 .../server/s7/protocol/S7Step7Protocol.java        |  76 ++++++++
 .../server/s7/protocol/S7Step7ServerProtocol.java  | 207 +++++++++++++++++++++
 .../simulator/simulation/SimulationModule.java     |  43 +++++
 .../watertank/WaterTankSimulationModule.java       |  60 ++++++
 .../org.apache.plc4x.simulator.server.ServerModule |  20 ++
 ...che.plc4x.simulator.simulation.SimulationModule |  20 ++
 .../plc-simulator/src/main/resources/logback.xml   |  36 ++++
 12 files changed, 812 insertions(+)

diff --git a/sandbox/plc-simulator/pom.xml b/sandbox/plc-simulator/pom.xml
new file mode 100644
index 0000000..e853987
--- /dev/null
+++ b/sandbox/plc-simulator/pom.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.plc4x.sandbox</groupId>
+    <artifactId>plc4x-sandbox</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>plc-simulator</artifactId>
+
+  <name>Sandbox: PLC-Simulator</name>
+
+  <build>
+    <plugins>
+      <!-- Generate the code for parsing and serializing S7 packets -->
+      <plugin>
+        <groupId>org.apache.plc4x.plugins</groupId>
+        <artifactId>plc4x-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>test</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>generate-driver</goal>
+            </goals>
+            <configuration>
+              <protocolName>s7</protocolName>
+              <languageName>java</languageName>
+              <outputFlavor>read-write</outputFlavor>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <!-- Build a fat jar containing all dependencies -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-shade-plugin</artifactId>
+        <version>3.2.1</version>
+        <executions>
+          <execution>
+            <id>generate-uber-jar</id>
+            <phase>package</phase>
+            <goals>
+              <goal>shade</goal>
+            </goals>
+            <configuration>
+              <transformers combine.children="append">
+                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+                  <mainClass>org.apache.plc4x.simulator.PlcSimulator</mainClass>
+                </transformer>
+              </transformers>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-utils-driver-base-java</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-protocol-driver-base</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-all</artifactId>
+      <version>${netty.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-annotations</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-classic</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-core</artifactId>
+      <scope>compile</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-build-utils-language-java</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+      <!-- Scope is 'provided' as this way it's not shipped with the driver -->
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-protocols-s7</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+      <!-- Scope is 'provided' as this way it's not shipped with the driver -->
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/PlcSimulator.java b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/PlcSimulator.java
new file mode 100644
index 0000000..9553c02
--- /dev/null
+++ b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/PlcSimulator.java
@@ -0,0 +1,88 @@
+/*
+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.simulator;
+
+import org.apache.plc4x.simulator.server.ServerModule;
+import org.apache.plc4x.simulator.simulation.SimulationModule;
+
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.TreeMap;
+import java.util.concurrent.TimeUnit;
+
+public class PlcSimulator {
+
+    private boolean running;
+    private static Map<String, ServerModule> serverModules;
+    private static Map<String, SimulationModule> simulationModules;
+
+    public PlcSimulator() {
+        this(Thread.currentThread().getContextClassLoader());
+    }
+
+    public PlcSimulator(ClassLoader classLoader) {
+        // Initialize all the server modules.
+        serverModules = new TreeMap<>();
+        ServiceLoader<ServerModule> serverModuleLoader = ServiceLoader.load(ServerModule.class, classLoader);
+        for (ServerModule serverModule : serverModuleLoader) {
+            serverModules.put(serverModule.getName(), serverModule);
+        }
+
+        // Initialize all the simulation modules.
+        simulationModules = new TreeMap<>();
+        ServiceLoader<SimulationModule> simulationModuleLoader = ServiceLoader.load(SimulationModule.class, classLoader);
+        for (SimulationModule simulationModule : simulationModuleLoader) {
+            simulationModules.put(simulationModule.getName(), simulationModule);
+        }
+
+        running = true;
+    }
+
+    public void stop() {
+        running = false;
+    }
+
+    public void run() throws Exception {
+        // Start all server modules.
+        for (ServerModule serverModule : serverModules.values()) {
+            serverModule.start();
+        }
+
+        try {
+            while (running) {
+                // Give all the simulation modules the chance to do something.
+                for (SimulationModule simulationModule : simulationModules.values()) {
+                    simulationModule.loop();
+                }
+                // Sleep 100 ms to not run the simulation too eagerly.
+                TimeUnit.MILLISECONDS.sleep(100);
+            }
+        } finally {
+            // Start all server modules.
+            for (ServerModule serverModule : serverModules.values()) {
+                serverModule.stop();
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        new PlcSimulator().run();
+    }
+
+}
diff --git a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/ServerModule.java b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/ServerModule.java
new file mode 100644
index 0000000..41aecac
--- /dev/null
+++ b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/ServerModule.java
@@ -0,0 +1,32 @@
+/*
+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.simulator.server;
+
+public interface ServerModule {
+
+    /**
+     * @return the name of the server module
+     */
+    String getName();
+
+    void start();
+
+    void stop();
+
+}
diff --git a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7Server.java b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7Server.java
new file mode 100644
index 0000000..16cb8a8
--- /dev/null
+++ b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7Server.java
@@ -0,0 +1,61 @@
+/*
+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.simulator.server.s7;
+
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.*;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import org.apache.plc4x.simulator.server.s7.protocol.S7Step7Protocol;
+import org.apache.plc4x.simulator.server.s7.protocol.S7Step7ServerProtocol;
+
+public class S7Server {
+
+    private static final int ISO_ON_TCP_PORT = 102;
+
+    public void run() throws Exception {
+        EventLoopGroup loopGroup = new NioEventLoopGroup();
+        EventLoopGroup workerGroup = new NioEventLoopGroup();
+        try {
+            ServerBootstrap bootstrap = new ServerBootstrap();
+            bootstrap.group(loopGroup, workerGroup)
+                .channel(NioServerSocketChannel.class)
+                .childHandler(new ChannelInitializer<SocketChannel>() {
+                    @Override
+                    public void initChannel(SocketChannel channel) {
+                        ChannelPipeline pipeline = channel.pipeline();
+                        pipeline.addLast(new S7Step7Protocol());
+                        pipeline.addLast(new S7Step7ServerProtocol());
+                    }
+                }).option(ChannelOption.SO_BACKLOG, 128)
+                .childOption(ChannelOption.SO_KEEPALIVE, true);
+
+            ChannelFuture future = bootstrap.bind(ISO_ON_TCP_PORT).sync();
+
+            // Wait till it ends ...
+            // TODO: Remove this ...
+            future.channel().closeFuture().sync();
+        } finally {
+            workerGroup.shutdownGracefully();
+            loopGroup.shutdownGracefully();
+        }
+    }
+
+}
diff --git a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7ServerModule.java b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7ServerModule.java
new file mode 100644
index 0000000..e9ca944
--- /dev/null
+++ b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7ServerModule.java
@@ -0,0 +1,40 @@
+/*
+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.simulator.server.s7;
+
+import org.apache.plc4x.simulator.server.ServerModule;
+
+public class S7ServerModule implements ServerModule {
+
+    @Override
+    public String getName() {
+        return "S7-STEP7";
+    }
+
+    @Override
+    public void start() {
+
+    }
+
+    @Override
+    public void stop() {
+
+    }
+
+}
diff --git a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/protocol/S7Step7Protocol.java b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/protocol/S7Step7Protocol.java
new file mode 100644
index 0000000..f79b3bd
--- /dev/null
+++ b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/protocol/S7Step7Protocol.java
@@ -0,0 +1,76 @@
+/*
+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.simulator.server.s7.protocol;
+
+import io.netty.buffer.ByteBuf;
+import org.apache.plc4x.java.base.GeneratedDriverByteToMessageCodec;
+import org.apache.plc4x.java.s7.readwrite.TPKTPacket;
+import org.apache.plc4x.java.s7.readwrite.io.TPKTPacketIO;
+import org.apache.plc4x.java.utils.MessageIO;
+import org.apache.plc4x.java.utils.ParseException;
+import org.apache.plc4x.java.utils.ReadBuffer;
+import org.apache.plc4x.java.utils.WriteBuffer;
+
+public class S7Step7Protocol extends GeneratedDriverByteToMessageCodec<TPKTPacket> {
+
+    public S7Step7Protocol() {
+        super(new MessageIO<TPKTPacket, TPKTPacket>() {
+            @Override
+            public TPKTPacket parse(ReadBuffer io) throws ParseException {
+                try {
+                    return TPKTPacketIO.parse(io);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    throw new ParseException("Error parsing message", e);
+                }
+            }
+
+            @Override
+            public void serialize(WriteBuffer io, TPKTPacket value) throws ParseException {
+                try {
+                    TPKTPacketIO.serialize(io, value);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    throw new ParseException("Error serializing message", e);
+                }
+            }
+        });
+    }
+
+    @Override
+    protected int getPacketSize(ByteBuf byteBuf) {
+        if(byteBuf.readableBytes() >= 4) {
+            if (byteBuf.getByte(0) != TPKTPacket.PROTOCOLID) {
+                return -1;
+            }
+            // Byte 1 is a reserved byte set to 0x00
+            return byteBuf.getShort(2);
+        }
+        return -1;
+    }
+
+    @Override
+    protected void removeRestOfCorruptPackage(ByteBuf byteBuf) {
+        while (byteBuf.getUnsignedByte(0) != TPKTPacket.PROTOCOLID) {
+            // Just consume the bytes till the next possible start position.
+            byteBuf.readByte();
+        }
+    }
+
+}
diff --git a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/protocol/S7Step7ServerProtocol.java b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/protocol/S7Step7ServerProtocol.java
new file mode 100644
index 0000000..d5dd6f8
--- /dev/null
+++ b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/protocol/S7Step7ServerProtocol.java
@@ -0,0 +1,207 @@
+/*
+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.simulator.server.s7.protocol;
+
+import io.netty.channel.*;
+import org.apache.plc4x.java.s7.readwrite.*;
+import org.apache.plc4x.java.s7.readwrite.types.COTPProtocolClass;
+import org.apache.plc4x.java.s7.readwrite.types.COTPTpduSize;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class S7Step7ServerProtocol extends ChannelInboundHandlerAdapter {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(S7Step7ServerProtocol.class);
+
+    private State state = State.INITIAL;
+
+    // COTP parameters
+    private static final int localReference = 42;
+    private int remoteReference = -1;
+    private COTPProtocolClass protocolClass;
+    private static final int localTsapId = 1;
+    private int remoteTsapId = -1;
+    private static final COTPTpduSize maxTpduSize = COTPTpduSize.SIZE_256;
+    private COTPTpduSize tpduSize;
+    // S7 parameters
+    // Set this to 1 as we don't want to handle stuff in parallel
+    private static final int maxAmqCaller = 1;
+    private int amqCaller;
+    // Set this to 1 as we don't want to handle stuff in parallel
+    private static final int maxAmqCallee = 1;
+    private int amqCallee;
+    private static final int maxPduLength = 240;
+    private int pduLength;
+
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        if(msg instanceof TPKTPacket) {
+            TPKTPacket packet = (TPKTPacket) msg;
+            switch (state) {
+                case INITIAL: {
+                    final COTPPacket cotpPacket = packet.getPayload();
+                    if (!(cotpPacket instanceof COTPPacketConnectionRequest)) {
+                        LOGGER.error("Expecting COTP Connection-Request");
+                        return;
+                    }
+
+                    COTPTpduSize proposedTpduSize = null;
+                    COTPPacketConnectionRequest cotpConnectionRequest = (COTPPacketConnectionRequest) cotpPacket;
+                    for (COTPParameter parameter : cotpConnectionRequest.getParameters()) {
+                        if (parameter instanceof COTPParameterCalledTsap) {
+                            COTPParameterCalledTsap calledTsapParameter = (COTPParameterCalledTsap) parameter;
+                        } else if (parameter instanceof COTPParameterCallingTsap) {
+                            COTPParameterCallingTsap callingTsapParameter = (COTPParameterCallingTsap) parameter;
+                            remoteTsapId = callingTsapParameter.getTsapId();
+                        } else if (parameter instanceof COTPParameterTpduSize) {
+                            COTPParameterTpduSize tpduSizeParameter = (COTPParameterTpduSize) parameter;
+                            proposedTpduSize = tpduSizeParameter.getTpduSize();
+                        } else {
+                            LOGGER.error(
+                                "Unexpected COTP Connection-Request Parameter " + parameter.getClass().getName());
+                            return;
+                        }
+                    }
+
+                    remoteReference = cotpConnectionRequest.getSourceReference();
+                    protocolClass = cotpConnectionRequest.getProtocolClass();
+                    tpduSize = (proposedTpduSize.getSizeInBytes() > maxTpduSize.getSizeInBytes()) ? maxTpduSize : proposedTpduSize;
+
+                    // Prepare a response and send it back to the remote.
+                    COTPParameter[] parameters = new COTPParameter[3];
+                    parameters[0] = new COTPParameterCalledTsap(remoteTsapId);
+                    parameters[1] = new COTPParameterCallingTsap(localTsapId);
+                    parameters[2] = new COTPParameterTpduSize(tpduSize);
+                    COTPPacketConnectionResponse response = new COTPPacketConnectionResponse(
+                        parameters, null, remoteReference, localReference, protocolClass);
+                    ctx.writeAndFlush(new TPKTPacket(response));
+
+                    state = State.COTP_CONNECTED;
+                    break;
+                }
+                case COTP_CONNECTED: {
+                    final COTPPacket cotpPacket = packet.getPayload();
+                    if (!(cotpPacket instanceof COTPPacketData)) {
+                        LOGGER.error("Expecting COTP Data packet");
+                        return;
+                    }
+
+                    COTPPacketData packetData = (COTPPacketData) cotpPacket;
+                    final short cotpTpduRef = packetData.getTpduRef();
+                    final S7Message payload = packetData.getPayload();
+                    if(!(payload instanceof S7MessageRequest)) {
+                        LOGGER.error("Expecting S7 Message Request");
+                        return;
+                    }
+                    S7MessageRequest s7MessageRequest = (S7MessageRequest) payload;
+                    final int s7TpduReference = s7MessageRequest.getTpduReference();
+                    final S7Parameter s7Parameter = s7MessageRequest.getParameter();
+                    if(!(s7Parameter instanceof S7ParameterSetupCommunication)) {
+                        LOGGER.error("Expecting S7 Message Request containing a S7 Setup Communication Parameter");
+                        return;
+                    }
+                    S7ParameterSetupCommunication s7ParameterSetupCommunication =
+                        (S7ParameterSetupCommunication) s7Parameter;
+
+                    amqCaller = Math.min(s7ParameterSetupCommunication.getMaxAmqCaller(), maxAmqCaller);
+                    amqCallee = Math.min(s7ParameterSetupCommunication.getMaxAmqCallee(), maxAmqCallee);
+                    pduLength = Math.min(s7ParameterSetupCommunication.getPduLength(), maxPduLength);
+
+                    S7ParameterSetupCommunication s7ParameterSetupCommunicationResponse =
+                        new S7ParameterSetupCommunication(amqCaller, amqCallee, pduLength);
+                    S7MessageResponse s7MessageResponse = new S7MessageResponse(
+                        s7TpduReference, s7ParameterSetupCommunicationResponse, new S7PayloadSetupCommunication(),
+                        (short) 0, (short) 0);
+                    ctx.writeAndFlush(new TPKTPacket(new COTPPacketData(null, s7MessageResponse, true, cotpTpduRef)));
+
+                    state = State.S7_CONNECTED;
+                    break;
+                }
+                case S7_CONNECTED: {
+                    final COTPPacket cotpPacket = packet.getPayload();
+                    if (!(cotpPacket instanceof COTPPacketData)) {
+                        LOGGER.error("Expecting COTP Data packet");
+                        return;
+                    }
+
+                    COTPPacketData packetData = (COTPPacketData) cotpPacket;
+                    final short cotpTpduRef = packetData.getTpduRef();
+                    final S7Message payload = packetData.getPayload();
+                    if(payload instanceof S7MessageUserData) {
+                        S7MessageUserData s7MessageUserData = (S7MessageUserData) payload;
+                        final int s7TpduReference = s7MessageUserData.getTpduReference();
+                        final S7Parameter s7Parameter = s7MessageUserData.getParameter();
+                        if(s7Parameter instanceof S7ParameterUserData) {
+                            S7ParameterUserData userData = (S7ParameterUserData) s7Parameter;
+                            for (S7ParameterUserDataItem item : userData.getItems()) {
+                                if(item instanceof S7ParameterUserDataItemCPUFunctions) {
+                                    S7ParameterUserDataItemCPUFunctions function = (S7ParameterUserDataItemCPUFunctions) item;
+                                    /*s7MessageUserData.getParameter()
+                                    final S7ParameterUserDataItemCpuFunctionsItem cpuFunction = function.getCpuFunction();
+                                    if(cpuFunction instanceof S7ParameterUserDataItemCpuFunctionReadSzlRequest) {
+                                        S7ParameterUserDataItemCpuFunctionReadSzlRequest readSzlRequest =
+                                            (S7ParameterUserDataItemCpuFunctionReadSzlRequest) cpuFunction;
+                                        final SzlId szlId = readSzlRequest.getSzlId();
+                                        // This is a request to list the type of device
+                                        if((szlId.getTypeClass() == SzlModuleTypeClass.CPU) &&
+                                            (szlId.getSublistList() == SzlSublist.MODULE_IDENTIFICATION)) {
+
+                                            SzlDataTreeItem[] items = new SzlDataTreeItem[1];
+                                            items[0] = new SzlDataTreeItem((short) 0x0001, new byte[20],
+                                                0x2020, 0x0001, 0x2020);
+                                            S7ParameterUserDataItemCpuFunctionReadSzlResponse readSzlResponse =
+                                                new S7ParameterUserDataItemCpuFunctionReadSzlResponse(
+                                                    readSzlRequest.getCpuFunctionType(), readSzlRequest.getCpuFunctionGroup(),
+                                                    readSzlRequest.getCpuSubfunction(), (short) 1, (short) 0, (short) 0,
+                                                    (short) 0, (short) 0xFF, (short) 0x09, readSzlRequest.getSzlId(),
+                                                    readSzlRequest.getSzlIndex(), items);
+                                            S7ParameterUserDataItem[] responseItems = new S7ParameterUserDataItem[1];
+                                            responseItems[0] = new S7ParameterUserDataItemCPUFunctions((short) 0x12, readSzlResponse);
+                                            S7ParameterUserData responseUserData = new S7ParameterUserData(responseItems);
+                                            S7Message s7ResponseMessage = new S7MessageResponse(s7TpduReference, responseUserData, new S7PayloadUserData());
+                                            ctx.writeAndFlush(new TPKTPacket(new COTPPacketData(null, responseUserData, true, cotpTpduRef)));
+                                        } else {
+                                            LOGGER.error("Not able to respond to the given request Read SZL with SZL type class " +
+                                                szlId.getTypeClass().name() + " and SZL sublise " + szlId.getSublistList().name());
+                                        }
+                                    }*/
+                                }
+                            }
+                        } else {
+                            LOGGER.error("Unsupported type of S7MessageUserData parameter " +
+                                s7Parameter.getClass().getName());
+                            return;
+                        }
+                    } else {
+                        LOGGER.error("Unsupported type of message " + payload.getClass().getName());
+                        return;
+                    }
+                    break;
+                }
+            }
+        }
+    }
+
+    private enum State {
+        INITIAL,
+        COTP_CONNECTED,
+        S7_CONNECTED
+    }
+
+}
diff --git a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/simulation/SimulationModule.java b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/simulation/SimulationModule.java
new file mode 100644
index 0000000..f08b082
--- /dev/null
+++ b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/simulation/SimulationModule.java
@@ -0,0 +1,43 @@
+/*
+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.simulator.simulation;
+
+import java.util.Map;
+
+public interface SimulationModule {
+
+    /**
+     * @return the name of the simulation module
+     */
+    String getName();
+
+    /**
+     * Gives access to the internal simulations context.
+     * This is an immutable map of named properties that should contain only simple data-types.
+     * @return reference to the simulations context
+     */
+    Map<String, Object> getContext();
+
+    /**
+     * Method for doing the actual processing inside the simulation.
+     * In this method the simulation can do calculations and update it's context variables.
+     */
+    void loop();
+
+}
diff --git a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/simulation/watertank/WaterTankSimulationModule.java b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/simulation/watertank/WaterTankSimulationModule.java
new file mode 100644
index 0000000..996076d
--- /dev/null
+++ b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/simulation/watertank/WaterTankSimulationModule.java
@@ -0,0 +1,60 @@
+/*
+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.simulator.simulation.watertank;
+
+import org.apache.plc4x.simulator.simulation.SimulationModule;
+
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.TimeUnit;
+
+public class WaterTankSimulationModule implements SimulationModule {
+
+    private static final String PROP_WATER_LEVEL = "waterLevel";
+
+    private final Map<String, Object> context;
+
+    public WaterTankSimulationModule() {
+        context = new TreeMap<>();
+        context.put(PROP_WATER_LEVEL, 0);
+    }
+
+    @Override
+    public String getName() {
+        return "Water Tank";
+    }
+
+    @Override
+    public Map<String, Object> getContext() {
+        return context;
+    }
+
+    @Override
+    public void loop() {
+        // TODO: Do something sensible ;-)
+        try {
+            // Just increase the level by 1 (Whatever this means ...
+            context.put(PROP_WATER_LEVEL, ((Integer) context.get(context)) + 1);
+            TimeUnit.MILLISECONDS.sleep(100);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+}
diff --git a/sandbox/plc-simulator/src/main/resources/META-INF/services/org.apache.plc4x.simulator.server.ServerModule b/sandbox/plc-simulator/src/main/resources/META-INF/services/org.apache.plc4x.simulator.server.ServerModule
new file mode 100644
index 0000000..9392a75
--- /dev/null
+++ b/sandbox/plc-simulator/src/main/resources/META-INF/services/org.apache.plc4x.simulator.server.ServerModule
@@ -0,0 +1,20 @@
+#
+# 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.
+#
+
+org.apache.plc4x.simulator.server.s7.S7ServerModule
\ No newline at end of file
diff --git a/sandbox/plc-simulator/src/main/resources/META-INF/services/org.apache.plc4x.simulator.simulation.SimulationModule b/sandbox/plc-simulator/src/main/resources/META-INF/services/org.apache.plc4x.simulator.simulation.SimulationModule
new file mode 100644
index 0000000..bb5db94
--- /dev/null
+++ b/sandbox/plc-simulator/src/main/resources/META-INF/services/org.apache.plc4x.simulator.simulation.SimulationModule
@@ -0,0 +1,20 @@
+#
+# 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.
+#
+
+org.apache.plc4x.simulator.simulation.watertank.WaterTankSimulationModule
\ No newline at end of file
diff --git a/sandbox/plc-simulator/src/main/resources/logback.xml b/sandbox/plc-simulator/src/main/resources/logback.xml
new file mode 100644
index 0000000..27d40c0
--- /dev/null
+++ b/sandbox/plc-simulator/src/main/resources/logback.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+  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.
+
+-->
+<configuration xmlns="http://ch.qos.logback/xml/ns/logback"
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+               xsi:schemaLocation="http://ch.qos.logback/xml/ns/logback https://raw.githubusercontent.com/enricopulatzo/logback-XSD/master/src/main/xsd/logback.xsd">
+
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <!-- encoders are assigned the type
+         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
+    <encoder>
+      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+    </encoder>
+  </appender>
+
+  <root level="info">
+    <appender-ref ref="STDOUT" />
+  </root>
+
+</configuration>
\ No newline at end of file


[plc4x] 02/03: - Continued working on the s7 mspec, especially regarding SZL sublists - Introduced enum types

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 9caeb4e582d4ec6f8e0a7ae39ef8d362266e2144
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Thu Oct 10 11:21:26 2019 +0200

    - Continued working on the s7 mspec, especially regarding SZL sublists
    - Introduced enum types
---
 .../s7/src/main/resources/protocols/s7/s7.mspec    | 140 +++++++++++++++++----
 1 file changed, 113 insertions(+), 27 deletions(-)

diff --git a/protocols/s7/src/main/resources/protocols/s7/s7.mspec b/protocols/s7/src/main/resources/protocols/s7/s7.mspec
index c87b93f..af14ad2 100644
--- a/protocols/s7/src/main/resources/protocols/s7/s7.mspec
+++ b/protocols/s7/src/main/resources/protocols/s7/s7.mspec
@@ -33,7 +33,7 @@
 ////////////////////////////////////////////////////////////////
 
 [discriminatedType 'COTPPacket' [uint 16 'cotpLen']
-    [implicit      uint 8 'headerLength' 'lengthInBytes - (payload.lengthInBytes + 1)']
+    [implicit      uint 8 'headerLength' 'lengthInBytes - (((payload != null) ? payload.lengthInBytes : 0) + 1)']
     [discriminator uint 8 'tpduCode']
     [typeSwitch 'tpduCode'
         ['0xF0' COTPPacketData
@@ -41,19 +41,19 @@
             [simple uint 7 'tpduRef']
         ]
         ['0xE0' COTPPacketConnectionRequest
-            [simple uint 16 'destinationReference']
-            [simple uint 16 'sourceReference']
-            [simple uint 8  'protocolClass']
+            [simple uint 16           'destinationReference']
+            [simple uint 16           'sourceReference']
+            [enum   COTPProtocolClass 'protocolClass']
         ]
         ['0xD0' COTPPacketConnectionResponse
-            [simple uint 16 'destinationReference']
-            [simple uint 16 'sourceReference']
-            [simple uint 8  'protocolClass']
+            [simple uint 16           'destinationReference']
+            [simple uint 16           'sourceReference']
+            [enum   COTPProtocolClass 'protocolClass']
         ]
         ['0x80' COTPPacketDisconnectRequest
-            [simple uint 16 'destinationReference']
-            [simple uint 16 'sourceReference']
-            [simple uint 8  'protocolClass']
+            [simple uint 16           'destinationReference']
+            [simple uint 16           'sourceReference']
+            [enum   COTPProtocolClass 'protocolClass']
         ]
         ['0xC0' COTPPacketDisconnectResponse
             [simple uint 16 'destinationReference']
@@ -73,7 +73,7 @@
     [implicit      uint 8 'parameterLength' 'lengthInBytes - 2']
     [typeSwitch 'parameterType'
         ['0xC0' COTPParameterTpduSize
-            [simple uint 8 'tpduSize']
+            [enum COTPTpduSize 'tpduSize']
         ]
         ['0xC1' COTPParameterCallingTsap
             [simple uint 16 'tsapId']
@@ -142,17 +142,17 @@
             [simple uint 8 'numItems']
         ]
         ['0x00','0x07' S7ParameterUserData
-            [implicit uint 8       'numItems' 'COUNT(items)']
-            [array    UserDataItem 'items' count 'numItems']
+            [implicit uint 8                  'numItems' 'COUNT(items)']
+            [array    S7ParameterUserDataItem 'items' count 'numItems']
         ]
     ]
 ]
 
 [discriminatedType 'S7VarRequestParameterItem'
-    [discriminator uint 8 'parameterItemType']
-    [typeSwitch 'parameterItemType'
+    [discriminator uint 8 'itemType']
+    [typeSwitch 'itemType'
         ['0x12' S7VarRequestParameterItemAddress
-            [implicit uint 8    'addressLength' 'address.lengthInBytes']
+            [implicit uint 8    'itemLength' 'address.lengthInBytes']
             [simple   S7Address 'address']
         ]
     ]
@@ -173,22 +173,40 @@
     ]
 ]
 
-// TODO: CPUFunctions still need some love ...
-[discriminatedType 'UserDataItem'
+[discriminatedType 'S7ParameterUserDataItem'
     [discriminator uint 8 'itemType']
     [typeSwitch 'itemType'
-        ['0x12' UserDataItemCPUFunctions
-            [implicit uint 8  'parameterLength' 'lengthInBytes']
-            [simple   uint 16 'cpuFunctionType']
-            [simple   uint 8  'subFunctionGroup']
-            [simple   uint 8  'sequenceNumber']
-            [optional uint 8  'dataUnitReferenceNumber' 'parameterLength == 8']
-            [optional uint 8  'lastDataUnit' 'parameterLength == 8']
-            [optional uint 8  'errorCode' 'parameterLength == 8']
+        ['0x12' S7ParameterUserDataItemCPUFunctions
+            [implicit uint 8 'itemLength' 'lengthInBytes']
+            [simple   uint 8 'method']
+            [simple   uint 4 'cpuFunctionType']
+            [simple   uint 4 'cpuFunctionGroup']
+            [simple   uint 8 'cpuSubfunction']
+            [simple   uint 8 'sequenceNumber']
+            [optional uint 8 'dataUnitReferenceNumber' 'cpuFunctionType == 8']
+            [optional uint 8 'lastDataUnit' 'cpuFunctionType == 8']
+            [optional uint 8 'errorCode' 'cpuFunctionType == 8']
         ]
     ]
 ]
 
+// This part is actually specified: http://www.kleissler-online.de/Siemens/SFCs.pdf
+// http://www.efesotomasyon.com/html/siemens/OP-Liste_en.pdf
+// https://cache.industry.siemens.com/dl/files/697/101906697/att_118286/v1/net_s7-300_s7-400_di_do_drahtbruch_en.pdf
+[type 'SzlId'
+    [enum SzlModuleTypeClass 'typeClass']
+    [simple uint 4           'sublistExtract']
+    [enum SzlSublist         'sublistList']
+]
+
+[type 'SzlDataTreeItem'
+    [simple uint 16 'itemIndex']
+    [array  int 8 'mlfb' count '20']
+    [simple uint 16 'moduleTypeId']
+    [simple uint 16 'ausbg']
+    [simple uint 16 'ausbe']
+]
+
 ////////////////////////////////////////////////////////////////
 // Payloads
 
@@ -206,6 +224,7 @@
             [array S7VarPayloadStatusItem 'items' count 'CAST(parameter, S7ParameterWriteVarResponse).numItems']
         ]
         ['0x00','0x07' S7PayloadUserData
+            [array S7PayloadUserDataItem 'items' count 'COUNT(CAST(parameter, S7ParameterUserData).items)']
         ]
     ]
 ]
@@ -223,6 +242,42 @@
     [simple uint 8 'returnCode']
 ]
 
+[discriminatedType 'S7PayloadUserDataItem'
+    [simple   uint 8 'returnCode']
+    [simple   uint 8 'transportSize']
+    [implicit uint 16 'dataLength' 'lengthInBytes - 4']
+    [simple   SzlId   'szlId']
+    [simple   uint 16 'szlIndex']
+    [typeSwitch ''
+        ['' S7PayloadUserDataItemCpuFunctionReadSzlRequest
+        ]
+        ['' S7PayloadUserDataItemCpuFunctionReadSzlResponse
+            [const    uint 16 'szlItemLength' '28']
+            [implicit uint 16 'szlItemCount'  'COUNT(items)']
+            [array SzlDataTreeItem 'items' count 'szlItemCount']
+        ]
+    ]
+]
+
+
+[enum uint 8 'COTPTpduSize' [uint 8 'sizeInBytes']
+    ['0x07' SIZE_128 ['128']]
+    ['0x08' SIZE_256 ['256']]
+    ['0x09' SIZE_512 ['512']]
+    ['0x0a' SIZE_1024 ['1024']]
+    ['0x0b' SIZE_2048 ['2048']]
+    ['0x0c' SIZE_4096 ['4096']]
+    ['0x0d' SIZE_8192 ['8192']]
+]
+
+[enum uint 8 'COTPProtocolClass'
+    ['0x00' CLASS_0]
+    ['0x10' CLASS_1]
+    ['0x20' CLASS_2]
+    ['0x30' CLASS_3]
+    ['0x40' CLASS_4]
+]
+
 [enum uint 8 'DataTransportSize' [bit 'sizeInBits']
     ['0x00' NULL            ['false']]
     ['0x03' BIT             ['true']]
@@ -249,7 +304,7 @@
     ['0x00' ULINT            ['X'              , '16'                , 'INT'                   , 'null']]
     ['0x08' REAL             ['D'              , '4'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD']]
     ['0x00' LREAL            ['X'              , '8'                 , 'REAL'                  , 'null']]
-    ['0x0B' TIME             ['X'              , '4'                 , 'null'                  , 'null']
+    ['0x0B' TIME             ['X'              , '4'                 , 'null'                  , 'null']]
     ['0x00' LTIME            ['X'              , '8'                 , 'TIME'                  , 'null']]
     ['0x02' DATE             ['X'              , '2'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD']]
     ['0x02' TIME_OF_DAY      ['X'              , '4'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD']]
@@ -260,3 +315,34 @@
     ['0x00' WSTRING          ['X'              , '1'                 , 'null'                  , 'null']]
 ]
 
+[enum uint 4 'SzlModuleTypeClass'
+    ['0x0' CPU]
+    ['0x4' IM]
+    ['0x8' FM]
+    ['0xC' CP]
+]
+
+[enum uint 8 'SzlSublist'
+    ['0x11' MODULE_IDENTIFICATION]
+    ['0x12' CPU_FEATURES]
+    ['0x13' USER_MEMORY_AREA]
+    ['0x14' SYSTEM_AREAS]
+    ['0x15' BLOCK_TYPES]
+    ['0x19' STATUS_MODULE_LEDS]
+    ['0x1C' COMPONENT_IDENTIFICATION]
+    ['0x22' INTERRUPT_STATUS]
+    ['0x25' ASSIGNMENT_BETWEEN_PROCESS_IMAGE_PARTITIONS_AND_OBS]
+    ['0x32' COMMUNICATION_STATUS_DATA]
+    ['0x74' STATUS_SINGLE_MODULE_LED]
+    ['0x90' DP_MASTER_SYSTEM_INFORMATION]
+    ['0x91' MODULE_STATUS_INFORMATION]
+    ['0x92' RACK_OR_STATION_STATUS_INFORMATION]
+    ['0x94' RACK_OR_STATION_STATUS_INFORMATION_2]
+    ['0x95' ADDITIONAL_DP_MASTER_SYSTEM_OR_PROFINET_IO_SYSTEM_INFORMATION]
+    ['0x96' MODULE_STATUS_INFORMATION_PROFINET_IO_AND_PROFIBUS_DP]
+    ['0xA0' DIAGNOSTIC_BUFFER]
+    ['0xB1' MODULE_DIAGNOSTIC_DATA]
+]
+
+
+


[plc4x] 01/03: - Made the java pojo template safe for null arrays - Added enum fileds to the getLengthInBytes method

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 6e048afe51fdace30935c5c20f1c21639889e0b6
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Thu Oct 10 11:20:19 2019 +0200

    - Made the java pojo template safe for null arrays
    - Added enum fileds to the getLengthInBytes method
---
 .../src/main/resources/templates/java/pojo-template.ftlh      | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh b/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh
index 45b4545..a5c1e60 100644
--- a/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh
+++ b/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh
@@ -118,8 +118,10 @@ public<#if type.abstract> abstract</#if> class ${typeName}<#if type.parentType??
         <#if helper.isSimpleType(field.type)>
         lengthInBits += ${field.type.size} * ${field.name}.length;
         <#else>
-        for(Message element : ${field.name}) {
-            lengthInBits += element.getLengthInBytes() * 8;
+        if(${field.name} != null) {
+            for(Message element : ${field.name}) {
+                lengthInBits += element.getLengthInBytes() * 8;
+            }
         }
         </#if>
         <#break>
@@ -138,6 +140,11 @@ public<#if type.abstract> abstract</#if> class ${typeName}<#if type.parentType??
         // Discriminator Field (${field.name})
         lengthInBits += ${field.type.size};
         <#break>
+    <#case "enum">
+
+        // Enum Field (${field.name})
+        lengthInBits += ${helper.getEnumBaseType(field.type).size};
+        <#break>
     <#case "implicit">
 
         // Implicit Field (${field.name})