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/05/22 15:43:16 UTC
[plc4x] branch feature/plc-simulator updated: [SIMULATED PLC]
Improved hadler to support nearly all INTEGER types.
This is an automated email from the ASF dual-hosted git repository.
jfeinauer pushed a commit to branch feature/plc-simulator
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/feature/plc-simulator by this push:
new 5410825 [SIMULATED PLC] Improved hadler to support nearly all INTEGER types.
5410825 is described below
commit 54108250e5ba4b27b50c5e965118072decac60e5
Author: julian <j....@pragmaticminds.de>
AuthorDate: Fri May 22 17:41:45 2020 +0200
[SIMULATED PLC] Improved hadler to support nearly all INTEGER types.
---
.../org/apache/plc4x/simulator/PlcSimulator.java | 9 ++-
.../plc4x/simulator/server/s7/S7PlcHandler.java | 2 +-
.../simulator/server/s7/S7PlcHandlerBase.java | 2 +-
.../server/s7/{S7Value.java => S7Type.java} | 14 +++--
.../apache/plc4x/simulator/server/s7/S7Value.java | 71 +++++++++++++++++++---
.../plc4x/simulator/server/s7/S7ValueFactory.java | 39 +++++++-----
.../server/s7/protocol/S7Step7ServerAdapter.java | 29 +++++----
7 files changed, 117 insertions(+), 49 deletions(-)
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
index bc7865d..a7273b4 100644
--- 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
@@ -30,8 +30,7 @@ import java.util.ServiceLoader;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
-import static org.apache.plc4x.simulator.server.s7.S7ValueFactory.INT;
-import static org.apache.plc4x.simulator.server.s7.S7ValueFactory.UINT;
+import static org.apache.plc4x.simulator.server.s7.S7ValueFactory.*;
public class PlcSimulator {
@@ -95,11 +94,15 @@ public class PlcSimulator {
((S7ServerModule) serverModule).setHandler(new S7PlcHandlerBase() {
@Override
- public S7Int readIntFromDataBlock(int dbNumber, int byteAddress, byte bitAddress) throws FieldReadException {
+ public S7Value readDB(int dbNumber, int byteAddress, byte bitAddress) throws FieldReadException {
if (byteAddress == 0) {
return INT((short) -42);
} else if (byteAddress == 2) {
return UINT(42);
+ } else if (byteAddress == 4) {
+ return LINT(-42);
+ } else if (byteAddress == 12) {
+ return DINT(-42);
} else {
throw new InvalidAddressException();
}
diff --git a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7PlcHandler.java b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7PlcHandler.java
index a672998..56d7a80 100644
--- a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7PlcHandler.java
+++ b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7PlcHandler.java
@@ -35,6 +35,6 @@ public interface S7PlcHandler {
void onConnectionClosed();
- S7Int readIntFromDataBlock(int dbNumber, int byteAddress, byte bitAddress) throws FieldReadException;
+ S7Value readDB(int dbNumber, int byteAddress, byte bitAddress) throws FieldReadException;
}
diff --git a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7PlcHandlerBase.java b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7PlcHandlerBase.java
index ada966b..ab90272 100644
--- a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7PlcHandlerBase.java
+++ b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7PlcHandlerBase.java
@@ -45,7 +45,7 @@ public abstract class S7PlcHandlerBase implements S7PlcHandler {
* Will always return invalid address.
*/
@Override
- public S7Int readIntFromDataBlock(int dbNumber, int byteAddress, byte bitAddress) throws FieldReadException {
+ public S7Value readDB(int dbNumber, int byteAddress, byte bitAddress) throws FieldReadException {
throw new InvalidAddressException();
}
}
diff --git a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7Value.java b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7Type.java
similarity index 80%
copy from sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7Value.java
copy to sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7Type.java
index 28a4ca9..09460d7 100644
--- a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7Value.java
+++ b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7Type.java
@@ -25,10 +25,16 @@ package org.apache.plc4x.simulator.server.s7;
* @author julian
* Created by julian on 22.05.20
*/
-public interface S7Value {
+public enum S7Type {
+ INT(short.class),
+ UINT(int.class),
+ DINT(int.class),
+ LINT(long.class),
+ REAL(float.class);
- void _int();
- void _uint();
- void _real();
+ private Class<?> javaType;
+ S7Type(Class<?> javaType) {
+ this.javaType = javaType;
+ }
}
diff --git a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7Value.java b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7Value.java
index 28a4ca9..6df01d7 100644
--- a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7Value.java
+++ b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7Value.java
@@ -19,16 +19,67 @@
package org.apache.plc4x.simulator.server.s7;
-/**
- * TODO write comment
- *
- * @author julian
- * Created by julian on 22.05.20
- */
-public interface S7Value {
+import org.apache.commons.lang3.NotImplementedException;
+import org.apache.plc4x.java.spi.generation.ParseException;
+import org.apache.plc4x.java.spi.generation.WriteBuffer;
+
+public class S7Value {
+
+ private final S7Type type;
+ private final Object value;
+
+ S7Value(S7Type type, Object value) {
+ this.type = type;
+ this.value = value;
+ }
+
+ public S7Type getType() {
+ return type;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ public byte[] getData() {
+ try {
+ WriteBuffer writeBuffer;
+ switch (type) {
+ case INT:
+ writeBuffer = new WriteBuffer(2, false);
+ writeBuffer.writeShort(16, ((short) value));
+ break;
+ case UINT:
+ writeBuffer = new WriteBuffer(2, false);
+ writeBuffer.writeUnsignedInt(16, ((int) value));
+ break;
+ case DINT:
+ writeBuffer = new WriteBuffer(4, false);
+ writeBuffer.writeInt(32, ((int) value));
+ break;
+ case LINT:
+ writeBuffer = new WriteBuffer(8, false);
+ writeBuffer.writeLong(64, ((long) value));
+ break;
+ case REAL:
+ writeBuffer = new WriteBuffer(4, false);
+ writeBuffer.writeFloat(32, ((float) value));
+ break;
+ default:
+ throw new NotImplementedException("Currently the type " + type + " is not implemented!");
+ }
+ return writeBuffer.getData();
+ } catch (ParseException e) {
+ throw new IllegalStateException("This should not happen!", e);
+ }
+ }
- void _int();
- void _uint();
- void _real();
+ @Override
+ public String toString() {
+ return "S7Value{" +
+ "type=" + type +
+ ", value=" + value +
+ '}';
+ }
}
diff --git a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7ValueFactory.java b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7ValueFactory.java
index 1f88e5c..d0d69b7 100644
--- a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7ValueFactory.java
+++ b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7ValueFactory.java
@@ -32,42 +32,51 @@ import java.math.BigInteger;
public class S7ValueFactory {
// Signed 2 Byte INT
- public static S7Int INT(short s) {
- return S7Int.INT(s);
+ public static S7Value INT(short s) {
+ return new S7Value(S7Type.INT, s);
}
// Unsigned 2 Byte INT
- public static S7Int UINT(int i) {
- return S7Int.UINT(i);
+ public static S7Value UINT(int i) {
+ checkUnsigned(i);
+ return new S7Value(S7Type.UINT, i);
}
// Signed 4 Byte INT
- public static S7Int DINT(int l) {
- throw new NotImplementedException("");
+ public static S7Value DINT(int i) {
+ return new S7Value(S7Type.DINT, i);
}
- // Signed 8 Byte Int
- public static S7Int LINT(long l) {
+ // Unsigned 4 Byte INT
+ public static S7Value UDINT(long l) {
+ checkUnsigned(l);
throw new NotImplementedException("");
}
- // Unsigned 4 Byte INT
- public static S7Int UDINT(long l) {
- throw new NotImplementedException("");
+ // Signed 8 Byte Int
+ public static S7Value LINT(long l) {
+ return new S7Value(S7Type.LINT, l);
}
// Unsigned 8 Byte INT
- public static S7Int ULINT(BigInteger bi) {
+ public static S7Value ULINT(BigInteger bi) {
+ checkUnsigned(bi.doubleValue());
throw new NotImplementedException("");
}
// 4 Byte floating point
- public static Object REAL(float f) {
- throw new NotImplementedException("");
+ public static S7Value REAL(float f) {
+ return new S7Value(S7Type.REAL, f);
}
// 8 Byte floating point
- public static Object LREAL(double d) {
+ public static S7Value LREAL(double d) {
throw new NotImplementedException("");
}
+
+ private static void checkUnsigned(double v) {
+ if (v < 0) {
+ throw new IllegalArgumentException("Unsigned Value cannot have negative value");
+ }
+ }
}
diff --git a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/protocol/S7Step7ServerAdapter.java b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/protocol/S7Step7ServerAdapter.java
index 8391d61..00f72f3 100644
--- a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/protocol/S7Step7ServerAdapter.java
+++ b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/protocol/S7Step7ServerAdapter.java
@@ -19,12 +19,14 @@ under the License.
package org.apache.plc4x.simulator.server.s7.protocol;
import io.netty.channel.*;
+import org.apache.commons.lang3.NotImplementedException;
import org.apache.plc4x.java.s7.readwrite.*;
import org.apache.plc4x.java.s7.readwrite.types.*;
import org.apache.plc4x.java.spi.generation.WriteBuffer;
import org.apache.plc4x.simulator.server.s7.InvalidAddressException;
import org.apache.plc4x.simulator.server.s7.S7Int;
import org.apache.plc4x.simulator.server.s7.S7PlcHandler;
+import org.apache.plc4x.simulator.server.s7.S7Value;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -267,34 +269,31 @@ public class S7Step7ServerAdapter extends ChannelInboundHandlerAdapter {
final byte bitAddress = addressAny.getBitAddress();
switch (addressAny.getTransportSize()) {
case INT: // These case should never happen. UINT will always be picked
+ case DINT:
+ case LINT:
+ case LTIME: // Is given for some transports LINT
+ case UDINT: // Is given for DINT
case UINT: {
// The value should be represented as Short
- S7Int s7Int;
+ S7Value value;
try {
- s7Int = handler.readIntFromDataBlock(addressAny.getDbNumber(), addressAny.getByteAddress(), addressAny.getBitAddress());
- } catch (InvalidAddressException e) {
- // Send a INVALID_ADDRESS response
- payloadItems[i] = new S7VarPayloadDataItem(DataTransportErrorCode.INVALID_ADDRESS, DataTransportSize.NULL, 0, new byte[0]);
- break;
+ value = handler.readDB(addressAny.getDbNumber(), addressAny.getByteAddress(), addressAny.getBitAddress());
} catch (Exception e) {
- // We have no idea, so just send INVALID_ADDRESS ?
+ // Send a INVALID_ADDRESS response
payloadItems[i] = new S7VarPayloadDataItem(DataTransportErrorCode.INVALID_ADDRESS, DataTransportSize.NULL, 0, new byte[0]);
break;
}
- WriteBuffer writeBuffer = new WriteBuffer(2, false);
- if (s7Int.isSigned()) {
- writeBuffer.writeShort(16, s7Int.getSigned());
- } else {
- writeBuffer.writeUnsignedInt(16, s7Int.getUnsigned());
- }
- byte[] data = writeBuffer.getData();
+
+ byte[] data = value.getData();
payloadItems[i] = new S7VarPayloadDataItem(DataTransportErrorCode.OK, DataTransportSize.BYTE_WORD_DWORD, 8 * data.length, data);
break;
}
default: {
- // TODO: Return invalid address.
+ LOGGER.warn("Got a request with unhandled type {}, returning INVALID_ADDRESS", addressAny.getTransportSize());
+ payloadItems[i] = new S7VarPayloadDataItem(DataTransportErrorCode.INVALID_ADDRESS, DataTransportSize.NULL, 0, new byte[0]);
+ break;
}
}
break;