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 2020/10/21 13:42:26 UTC

[plc4x] 08/08: Simotion String

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

jfeinauer pushed a commit to branch rel/0.6
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit b6ee1613c5bbf08e7e912c5a2f540dcfd0d0f819
Author: vemmert <v....@pragmaticminds.de>
AuthorDate: Wed Oct 21 15:27:27 2020 +0200

    Simotion String
---
 .../base/messages/items/BaseDefaultFieldItem.java  |  9 +++++
 .../messages/items/DefaultDurationFieldItem.java   | 47 ++++++++++++++++++++++
 .../org/apache/plc4x/java/s7/model/S7Field.java    |  5 +--
 .../plc4x/java/s7/netty/Plc4XS7Protocol.java       | 30 +++++++++++---
 .../org/apache/plc4x/java/s7/netty/S7Protocol.java |  3 +-
 .../s7/netty/model/types/DataTransportSize.java    |  3 +-
 .../java/s7/netty/model/types/TransportSize.java   |  5 ++-
 7 files changed, 90 insertions(+), 12 deletions(-)

diff --git a/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/items/BaseDefaultFieldItem.java b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/items/BaseDefaultFieldItem.java
index 4abcda5..f09495e 100644
--- a/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/items/BaseDefaultFieldItem.java
+++ b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/items/BaseDefaultFieldItem.java
@@ -23,6 +23,7 @@ import org.apache.plc4x.java.api.exceptions.PlcIncompatibleDatatypeException;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.time.Duration;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
@@ -139,6 +140,14 @@ public abstract class BaseDefaultFieldItem<T> {
         throw new PlcIncompatibleDatatypeException(LocalDate.class, index);
     }
 
+    public boolean isValidDuration(int index) {
+        return false;
+    }
+
+    public Duration getDuration(int index) {
+        throw new PlcIncompatibleDatatypeException(Duration.class, index);
+    }
+
     public boolean isValidDateTime(int index) {
         return false;
     }
diff --git a/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/items/DefaultDurationFieldItem.java b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/items/DefaultDurationFieldItem.java
new file mode 100644
index 0000000..8e44819
--- /dev/null
+++ b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/items/DefaultDurationFieldItem.java
@@ -0,0 +1,47 @@
+/*
+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.base.messages.items;
+
+import org.apache.plc4x.java.api.exceptions.PlcIncompatibleDatatypeException;
+
+import java.time.Duration;
+
+public class DefaultDurationFieldItem extends BaseDefaultFieldItem<Duration> {
+    public DefaultDurationFieldItem(Duration[] values) {
+        super(values);
+    }
+
+    @Override
+    public Object getObject(int index) {
+        return getValue(index);
+    }
+
+    @Override
+    public boolean isValidDuration(int index) {
+        return getValue(index) != null;
+    }
+
+    @Override
+    public Duration getDuration(int index) {
+        if (!isValidDuration(index)) {
+            throw new PlcIncompatibleDatatypeException(Duration.class, index);
+        }
+        return getValue(index);
+    }
+}
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7Field.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7Field.java
index 6662615..c5eb11f 100644
--- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7Field.java
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7Field.java
@@ -238,12 +238,11 @@ public class S7Field implements PlcField {
                 final short numberOfElements = (short)rb.readUnsignedInt(16);
                 final short dbNumber = (short)rb.readUnsignedInt(16);
                 final MemoryArea memoryArea = MemoryArea.valueOf(rb.readByte(8));
-                assert 0x00 == rb.readUnsignedShort(5);
+                rb.readUnsignedShort(5);
                 final short byteAddress = (short)rb.readUnsignedInt(16);
                 final byte bitAddress = rb.readUnsignedByte(3);
 
-                return new S7Field(transportSize, memoryArea, dbNumber, byteAddress, bitAddress,
-                    numberOfElements);
+                return new S7Field(transportSize, memoryArea, dbNumber, byteAddress, bitAddress, numberOfElements);
             } catch (ParseException | DecoderException e) {
                 throw new PlcInvalidFieldException("Unable to parse address: " + fieldString);
             }
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java
index 6c789dd..42b5096 100644
--- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java
@@ -53,6 +53,7 @@ import java.lang.reflect.Array;
 import java.math.BigInteger;
 import java.nio.ByteBuffer;
 import java.nio.charset.StandardCharsets;
+import java.time.Duration;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
@@ -526,11 +527,15 @@ public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequ
                             fieldItem = decodeReadResponseFixedLengthStringField(1, true, data);
                             break;
                         case STRING:
-                            fieldItem = decodeReadResponseVarLengthStringField(false, data);
+                            fieldItem = decodeReadResponseVarLengthStringField(false, false, data);
                             break;
                         case WSTRING:
-                            fieldItem = decodeReadResponseVarLengthStringField(true, data);
+                            fieldItem = decodeReadResponseVarLengthStringField(true, false, data);
                             break;
+                        case SIMOTIONSTRING:
+                            fieldItem = decodeReadResponseVarLengthStringField(false, true, data);
+                            break;
+
                         // -----------------------------------------
                         // TIA Date-Formats
                         // -----------------------------------------
@@ -543,6 +548,9 @@ public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequ
                         case DATE:
                             fieldItem = decodeReadResponseDate(field, data);
                             break;
+                        case TIME:
+                            fieldItem = decodeReadResponseTime(field, data);
+                            break;
                         default:
                             throw new PlcProtocolException("Unsupported type " + field.getDataType());
                     }
@@ -659,9 +667,11 @@ public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequ
         return new DefaultStringFieldItem(stringValue);
     }
 
-    BaseDefaultFieldItem decodeReadResponseVarLengthStringField(boolean isUtf16, ByteBuf data) {
-        // Max length ... ignored.
-        data.skipBytes(1);
+    BaseDefaultFieldItem decodeReadResponseVarLengthStringField(boolean isUtf16, boolean isSimotion, ByteBuf data) {
+        // In standard S7 the first byte contains the max length, Simotion string doesn't
+        if (!isSimotion) {
+            data.skipBytes(1);
+        }
 
         //reading out byte and transforming that to an unsigned byte within an integer, otherwise longer strings are failing
         byte currentLengthByte = data.readByte();
@@ -684,6 +694,11 @@ public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequ
         return new DefaultLocalDateFieldItem(localTimes);
     }
 
+    BaseDefaultFieldItem decodeReadResponseTime(S7Field field, ByteBuf data) {
+        Duration[] duration = readAllValues(Duration.class,field, i -> readDuration(data));;
+        return new DefaultDurationFieldItem(duration);
+    }
+
     // Returns a 32 bit unsigned value : from 0 to 4294967295 (2^32-1)
     public static int getUDIntAt(byte[] buffer, int pos) {
         int result;
@@ -831,6 +846,11 @@ public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequ
 
     }
 
+    Duration readDuration(ByteBuf data) {
+        // 4 bytes, duration in milliseconds
+        return Duration.ofMillis(data.readInt());
+    }
+
     /**
      * converts incoming byte to an integer regarding used BCD format
      * @param incomingByte
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/S7Protocol.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/S7Protocol.java
index f8a670a..85f3a00 100644
--- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/S7Protocol.java
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/S7Protocol.java
@@ -647,7 +647,8 @@ public class S7Protocol extends ChannelDuplexHandler {
             }
             // This is a response to a READ_VAR request.
             else if ((readWriteVarParameter.getType() == ParameterType.READ_VAR) && isResponse) {
-                DataTransportSize dataTransportSize = DataTransportSize.valueOf(userData.readByte());
+                byte bbb = userData.readByte();
+                DataTransportSize dataTransportSize = DataTransportSize.valueOf(bbb);
                 short length = dataTransportSize.isSizeInBits() ?
                     (short) Math.ceil(userData.readShort() / 8.0) : userData.readShort();
                 byte[] data = new byte[length];
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/model/types/DataTransportSize.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/model/types/DataTransportSize.java
index e93a34e..0d8f9d0 100644
--- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/model/types/DataTransportSize.java
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/model/types/DataTransportSize.java
@@ -31,7 +31,8 @@ public enum DataTransportSize {
     INTEGER((byte) 0x05, true),
     DINTEGER((byte) 0x06, false),
     REAL((byte) 0x07, false),
-    OCTET_STRING((byte) 0x09, false);
+    OCTET_STRING((byte) 0x09, false),
+    TIME((byte) 0x32, false);
 
     private static final Map<Byte, DataTransportSize> map;
     static {
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/model/types/TransportSize.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/model/types/TransportSize.java
index 2f806ed..8ecfc46 100644
--- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/model/types/TransportSize.java
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/model/types/TransportSize.java
@@ -108,8 +108,9 @@ public enum TransportSize {
     STRING(0x03, "X", 1, null, DataTransportSize.BYTE_WORD_DWORD, S7ControllerType.ANY),
     // Variable-length double-byte character string
     // TODO: Find the code (Perhaps 0x13)
-    WSTRING(0x00, "X", 1, null, null, S7ControllerType.S7_1200, S7ControllerType.S7_1500);
-
+    WSTRING(0x00, "X", 1, null, null, S7ControllerType.S7_1200, S7ControllerType.S7_1500),
+    // String in Simotion PLCs
+    SIMOTIONSTRING(0x33, "X", 1, null, DataTransportSize.BYTE_WORD_DWORD, S7ControllerType.ANY);
     /* TO BE CONTINUED */
 
     // Codes and their types: