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: