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/08/07 08:48:02 UTC
[plc4x] 15/17: - Tweaked the mspec for the DF1 protocol - Started
implementing a PLC4X driver based on the generated code
This is an automated email from the ASF dual-hosted git repository.
cdutz pushed a commit to branch feature/implement-df1-driver
in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit 40dbc1bf73d239a6ab9d41e9ae75b5304b80b9ac
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Tue Aug 6 17:03:35 2019 +0200
- Tweaked the mspec for the DF1 protocol
- Started implementing a PLC4X driver based on the generated code
---
.../org/apache/plc4x/java/utils/WriteBuffer.java | 21 ++
.../main/resources/protocols/df1/protocol.mspec | 18 +-
sandbox/test-java-df1-driver/README.adoc | 35 +++
sandbox/test-java-df1-driver/pom.xml | 25 +++
.../org/apache/plc4x/java/df1/DF1PlcDriver.java | 73 ++++++
.../java/df1/connection/BaseDf1Connection.java | 34 +++
.../java/df1/connection/SerialDf1Connection.java | 112 ++++++++++
.../org/apache/plc4x/java/df1/fields/DataType.java | 17 ++
.../plc4x/java/df1/protocol/Df1Protocol.java | 143 ++++++++++++
.../plc4x/java/df1/protocol/Plc4XDf1Protocol.java | 40 ++++
.../plc4x/java/df1/util/Df1FieldHandler.java | 38 ++++
.../plc4x/protocol/df1/BenchmarkGeneratedDf1.java | 247 ---------------------
.../org/apache/plc4x/protocol/df1/DF1Utils.java | 58 ++++-
.../services/org.apache.plc4x.java.spi.PlcDriver | 19 ++
.../plc4x/protocol/df1/BenchmarkGeneratedDf1.java | 84 +++++++
.../plc4x/protocol/df1/BenchmarkManualDf1.java | 4 +-
16 files changed, 711 insertions(+), 257 deletions(-)
diff --git a/plc4j/utils/driver-base-java/src/main/java/org/apache/plc4x/java/utils/WriteBuffer.java b/plc4j/utils/driver-base-java/src/main/java/org/apache/plc4x/java/utils/WriteBuffer.java
index 35283c5..bc10358 100644
--- a/plc4j/utils/driver-base-java/src/main/java/org/apache/plc4x/java/utils/WriteBuffer.java
+++ b/plc4j/utils/driver-base-java/src/main/java/org/apache/plc4x/java/utils/WriteBuffer.java
@@ -33,11 +33,17 @@ public class WriteBuffer {
private ByteBuffer bb;
private BufferByteOutput bbo;
private BitOutput bo;
+ private boolean littleEndian;
public WriteBuffer(int size) {
+ this(size, true);
+ }
+
+ public WriteBuffer(int size, boolean littleEndian) {
bb = ByteBuffer.allocate(size);
bbo = new BufferByteOutput<>(bb);
bo = new DefaultBitOutput<>(bbo);
+ this.littleEndian = littleEndian;
}
public byte[] getData() {
@@ -88,6 +94,9 @@ public class WriteBuffer {
throw new ParseException("unsigned int can only contain max 16 bits");
}
try {
+ if(!littleEndian) {
+ value = Integer.reverseBytes(value) >> 16;
+ }
bo.writeInt(true, bitLength, value);
} catch (IOException e) {
throw new ParseException("Error reading", e);
@@ -102,6 +111,9 @@ public class WriteBuffer {
throw new ParseException("unsigned long can only contain max 32 bits");
}
try {
+ if(!littleEndian) {
+ value = Long.reverseBytes(value) >> 32;
+ }
bo.writeLong(true, bitLength, value);
} catch (IOException e) {
throw new ParseException("Error reading", e);
@@ -134,6 +146,9 @@ public class WriteBuffer {
throw new ParseException("short can only contain max 16 bits");
}
try {
+ if(!littleEndian) {
+ value = Short.reverseBytes(value);
+ }
bo.writeShort(false, bitLength, value);
} catch (IOException e) {
throw new ParseException("Error reading", e);
@@ -148,6 +163,9 @@ public class WriteBuffer {
throw new ParseException("int can only contain max 32 bits");
}
try {
+ if(!littleEndian) {
+ value = Integer.reverseBytes(value);
+ }
bo.writeInt(false, bitLength, value);
} catch (IOException e) {
throw new ParseException("Error reading", e);
@@ -162,6 +180,9 @@ public class WriteBuffer {
throw new ParseException("long can only contain max 64 bits");
}
try {
+ if(!littleEndian) {
+ value = Long.reverseBytes(value);
+ }
bo.writeLong(false, bitLength, value);
} catch (IOException e) {
throw new ParseException("Error reading", e);
diff --git a/protocols/df1/src/main/resources/protocols/df1/protocol.mspec b/protocols/df1/src/main/resources/protocols/df1/protocol.mspec
index ce5a8f5..d63974c 100644
--- a/protocols/df1/src/main/resources/protocols/df1/protocol.mspec
+++ b/protocols/df1/src/main/resources/protocols/df1/protocol.mspec
@@ -18,14 +18,18 @@
//
-[type 'DF1ReadRequest'
- [field DF1SymbolMessageFrameStart 'messageFrameStart' ['0', 'null']]
- [field DF1SymbolMessageFrameEnd 'messageFrameEnd' ['0', 'messageFrameStart']]
+[type 'ReadRequest'
+ [field DF1Symbol 'messageFrameStart' ['0', 'null']]
+ [field DF1Symbol 'messageFrameEnd' ['0', 'messageFrameStart']]
]
-[type 'DF1ReadResponse' [uint 8 'payloadSize']
- [field DF1SymbolMessageFrameStart 'messageFrameStart' ['payloadSize', 'null']]
- [field DF1SymbolMessageFrameEnd 'messageFrameEnd' ['0', 'messageFrameStart']]
+[type 'ReadResponse' [uint 8 'payloadSize']
+ [field DF1Symbol 'messageFrameStart' ['payloadSize', 'null']]
+ [field DF1Symbol 'messageFrameEnd' ['0', 'messageFrameStart']]
+]
+
+[type 'Result'
+ [field DF1Symbol 'result' ['0', 'null']]
]
[discriminatedType 'DF1Symbol' [uint 8 'payloadSize', DF1SymbolMessageFrameStart 'messageStartSymbol']
@@ -38,7 +42,7 @@
[field DF1Command 'command' ['payloadSize']]
]
['0x03' DF1SymbolMessageFrameEnd
- [implicit uint 16 'crc' 'STATIC_CALL("org.apache.plc4x.protocol.df1.DF1Utils.CRCCheck", messageStartSymbol.destinationAddress, messageStartSymbol.sourceAddress, messageStartSymbol.command.discriminatorValues, messageStartSymbol.command.status, messageStartSymbol.command.transactionCounter, discriminatorValues[0])']
+ [implicit uint 16 'crc' 'STATIC_CALL("org.apache.plc4x.protocol.df1.DF1Utils.CRCCheck", discriminatorValues[0], messageStartSymbol)']
]
['0x06' DF1SymbolMessageFrameACK
]
diff --git a/sandbox/test-java-df1-driver/README.adoc b/sandbox/test-java-df1-driver/README.adoc
new file mode 100644
index 0000000..d513383
--- /dev/null
+++ b/sandbox/test-java-df1-driver/README.adoc
@@ -0,0 +1,35 @@
+//
+// 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.
+//
+
+== Using the Driver in the hello-world example
+
+Add the driver to the pom.xml
+
+ <dependency>
+ <groupId>org.apache.plc4x.sandbox</groupId>
+ <artifactId>test-java-df1-driver</artifactId>
+ <version>0.5.0-SNAPSHOT</version>
+ <scope>runtime</scope>
+ </dependency>
+
+Then start the Hello world (Ideally in IntelliJ) with the following program arguments:
+
+ df1:serial///{com-port-name} {address}
+
+Currently the parsing of addresses is not implemented yet, so it will not work.
+
+But as soon as that's done, this should work.
\ No newline at end of file
diff --git a/sandbox/test-java-df1-driver/pom.xml b/sandbox/test-java-df1-driver/pom.xml
index 3ddc53b..1cccdd6 100644
--- a/sandbox/test-java-df1-driver/pom.xml
+++ b/sandbox/test-java-df1-driver/pom.xml
@@ -57,9 +57,34 @@
<dependencies>
<dependency>
<groupId>org.apache.plc4x</groupId>
+ <artifactId>plc4j-api</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>org.apache.plc4x</groupId>
+ <artifactId>plc4j-protocol-driver-base-tcp</artifactId>
+ <version>0.5.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.plc4x</groupId>
+ <artifactId>plc4j-protocol-driver-base-serial</artifactId>
+ <version>0.5.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.plc4x</groupId>
<artifactId>plc4j-utils-driver-base-java</artifactId>
<version>0.5.0-SNAPSHOT</version>
</dependency>
+
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-buffer</artifactId>
+ </dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/DF1PlcDriver.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/DF1PlcDriver.java
new file mode 100644
index 0000000..fd8e0c6
--- /dev/null
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/DF1PlcDriver.java
@@ -0,0 +1,73 @@
+/*
+ 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.df1;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.plc4x.java.api.PlcConnection;
+import org.apache.plc4x.java.api.authentication.PlcAuthentication;
+import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+import org.apache.plc4x.java.df1.connection.SerialDf1Connection;
+import org.apache.plc4x.java.spi.PlcDriver;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class DF1PlcDriver implements PlcDriver {
+
+ public static final Pattern INET_ADDRESS_PATTERN = Pattern.compile("tcp://(?<host>[\\w.]+)(:(?<port>\\d*))?");
+ public static final Pattern SERIAL_PATTERN = Pattern.compile("serial://(?<serialDefinition>((?!/\\d).)*)");
+ public static final Pattern DF1_URI_PATTERN = Pattern.compile("^df1:(" + INET_ADDRESS_PATTERN + "|" + SERIAL_PATTERN + ")/?" + "(?<params>\\?.*)?");
+
+ @Override
+ public String getProtocolCode() {
+ return "df1";
+ }
+
+ @Override
+ public String getProtocolName() {
+ return "Allen-Bradley DF1";
+ }
+
+ @Override
+ public PlcConnection connect(String url) throws PlcConnectionException {
+ Matcher matcher = DF1_URI_PATTERN.matcher(url);
+ if (!matcher.matches()) {
+ throw new PlcConnectionException(
+ "Connection url doesn't match the format 'df1:{type}//{port|host}'");
+ }
+
+ String host = matcher.group("host");
+ String serialDefinition = matcher.group("serialDefinition");
+ String portString = matcher.group("port");
+ Integer port = StringUtils.isNotBlank(portString) ? Integer.parseInt(portString) : null;
+ String params = matcher.group("params") != null ? matcher.group("params").substring(1) : null;
+
+ if (serialDefinition != null) {
+ return new SerialDf1Connection(serialDefinition, params);
+ } else {
+ throw new PlcConnectionException("TCP DF1 connections not implemented yet.");
+ }
+ }
+
+ @Override
+ public PlcConnection connect(String url, PlcAuthentication authentication) throws PlcConnectionException {
+ throw new PlcConnectionException("DF1 connections don't support authentication.");
+ }
+
+}
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/connection/BaseDf1Connection.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/connection/BaseDf1Connection.java
new file mode 100644
index 0000000..6f09c02
--- /dev/null
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/connection/BaseDf1Connection.java
@@ -0,0 +1,34 @@
+/*
+ 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.df1.connection;
+
+import org.apache.plc4x.java.base.connection.ChannelFactory;
+import org.apache.plc4x.java.base.connection.NettyPlcConnection;
+
+public abstract class BaseDf1Connection extends NettyPlcConnection {
+
+ public BaseDf1Connection(ChannelFactory channelFactory) {
+ super(channelFactory);
+ }
+
+ public BaseDf1Connection(ChannelFactory channelFactory, boolean awaitSessionSetupComplete) {
+ super(channelFactory, awaitSessionSetupComplete);
+ }
+
+}
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/connection/SerialDf1Connection.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/connection/SerialDf1Connection.java
new file mode 100644
index 0000000..de8803e
--- /dev/null
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/connection/SerialDf1Connection.java
@@ -0,0 +1,112 @@
+/*
+ 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.df1.connection;
+
+import io.netty.channel.*;
+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.base.connection.SerialChannelFactory;
+import org.apache.plc4x.java.base.events.ConnectedEvent;
+import org.apache.plc4x.java.base.messages.*;
+import org.apache.plc4x.java.df1.protocol.Df1Protocol;
+import org.apache.plc4x.java.df1.protocol.Plc4XDf1Protocol;
+import org.apache.plc4x.java.df1.util.Df1FieldHandler;
+
+import java.util.concurrent.CompletableFuture;
+
+public class SerialDf1Connection extends BaseDf1Connection implements PlcReader, PlcWriter {
+
+ public SerialDf1Connection(String comPortName, String params) {
+ super(new SerialChannelFactory(comPortName));
+ }
+
+ @Override
+ public boolean canRead() {
+ return true;
+ }
+
+ @Override
+ public boolean canWrite() {
+ return true;
+ }
+
+ @Override
+ protected ChannelHandler getChannelHandler(CompletableFuture<Void> sessionSetupCompleteFuture) {
+ return new ChannelInitializer() {
+ @Override
+ protected void initChannel(Channel channel) {
+ // Build the protocol stack for communicating with the s7 protocol.
+ ChannelPipeline pipeline = channel.pipeline();
+ pipeline.addLast(new ChannelInboundHandlerAdapter() {
+ @Override
+ public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
+ if (evt instanceof ConnectedEvent) {
+ sessionSetupCompleteFuture.complete(null);
+ } else {
+ super.userEventTriggered(ctx, evt);
+ }
+ }
+ });
+ pipeline.addLast(new Df1Protocol());
+ pipeline.addLast(new Plc4XDf1Protocol());
+ }
+ };
+ }
+
+ @Override
+ public PlcReadRequest.Builder readRequestBuilder() {
+ return new DefaultPlcReadRequest.Builder(this, new Df1FieldHandler());
+ }
+
+ @Override
+ public PlcWriteRequest.Builder writeRequestBuilder() {
+ return new DefaultPlcWriteRequest.Builder(this, new Df1FieldHandler());
+ }
+
+ @Override
+ public CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest) {
+ CompletableFuture<InternalPlcReadResponse> future = new CompletableFuture<>();
+ PlcRequestContainer<InternalPlcReadRequest, InternalPlcReadResponse> container =
+ new PlcRequestContainer<>((InternalPlcReadRequest) readRequest, future);
+ channel.writeAndFlush(container).addListener(f -> {
+ if (!f.isSuccess()) {
+ future.completeExceptionally(f.cause());
+ }
+ });
+ return future
+ .thenApply(PlcReadResponse.class::cast);
+ }
+
+ @Override
+ public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
+ CompletableFuture<InternalPlcWriteResponse> future = new CompletableFuture<>();
+ PlcRequestContainer<InternalPlcWriteRequest, InternalPlcWriteResponse> container =
+ new PlcRequestContainer<>((InternalPlcWriteRequest) writeRequest, future);
+ channel.writeAndFlush(container).addListener(f -> {
+ if (!f.isSuccess()) {
+ future.completeExceptionally(f.cause());
+ }
+ });
+ return future
+ .thenApply(PlcWriteResponse.class::cast);
+ }
+
+}
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/fields/DataType.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/fields/DataType.java
new file mode 100644
index 0000000..83322f7
--- /dev/null
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/fields/DataType.java
@@ -0,0 +1,17 @@
+package org.apache.plc4x.java.df1.fields;
+
+public enum DataType {
+
+ BIT,
+ BIT_STRING,
+ BYTE_STRING,
+ INTEGER,
+ TIMER,
+ COUNTER,
+ GENERAL_COUNT_STRUCTURE,
+ FLOAT,
+ ARRAY,
+ ADDRESS,
+ BINARY_CODED_DECIMAL
+
+}
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Df1Protocol.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Df1Protocol.java
new file mode 100644
index 0000000..bbeece2
--- /dev/null
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Df1Protocol.java
@@ -0,0 +1,143 @@
+/*
+ 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.df1.protocol;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.channel.ChannelHandlerContext;
+import org.apache.plc4x.java.api.exceptions.PlcProtocolException;
+import org.apache.plc4x.java.base.PlcByteToMessageCodec;
+import org.apache.plc4x.java.df1.DF1ReadRequest;
+import org.apache.plc4x.java.df1.DF1Symbol;
+import org.apache.plc4x.java.df1.DF1SymbolMessageFrameStart;
+import org.apache.plc4x.java.df1.io.DF1SymbolIO;
+import org.apache.plc4x.java.utils.ReadBuffer;
+import org.apache.plc4x.java.utils.WriteBuffer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Df1Protocol extends PlcByteToMessageCodec<DF1Symbol> {
+
+ private static final Logger logger = LoggerFactory.getLogger(Df1Protocol.class);
+
+ private final DF1SymbolIO df1SymbolIO;
+
+ private Map<Integer, Short> readRequestSizes;
+
+ public Df1Protocol() {
+ df1SymbolIO = new DF1SymbolIO();
+ readRequestSizes = new HashMap<>();
+ }
+
+ @Override
+ protected void encode(ChannelHandlerContext ctx, DF1Symbol msg, ByteBuf out) throws Exception {
+ // Remember the size of the request as we need this to decode the response.
+ if(msg instanceof DF1SymbolMessageFrameStart) {
+ DF1SymbolMessageFrameStart frameStart = (DF1SymbolMessageFrameStart) msg;
+ if(frameStart.getCommand() instanceof DF1ReadRequest) {
+ DF1ReadRequest readRequest = (DF1ReadRequest) frameStart.getCommand();
+ int transactionCounter = readRequest.getTransactionCounter();
+ readRequestSizes.put(transactionCounter, readRequest.getSize());
+ }
+ }
+
+ // Serialize the message
+ // TODO: Create the buffer with the correct size.
+ WriteBuffer writeBuffer = new WriteBuffer(100);
+ df1SymbolIO.serialize(writeBuffer, msg);
+ byte[] data = writeBuffer.getData();
+
+ // Send the serialized data
+ out.writeBytes(data);
+ }
+
+ @Override
+ protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
+ short size = 0x00;
+
+ // Yes, it's a little complicated, but we need to find out if we've got enough data.
+ if(in.readableBytes() > 2) {
+ if(in.getUnsignedByte(0) != (short) 0x10) {
+ logger.warn("Expecting DF1 magic number: {}", 0x10);
+ if (logger.isDebugEnabled()) {
+ logger.debug("Got Data: {}", ByteBufUtil.hexDump(in));
+ }
+ exceptionCaught(ctx, new PlcProtocolException(
+ String.format("Expecting DF1 magic number: %02X", 0x10)));
+ return;
+ }
+
+ short symbolType = in.getUnsignedByte(1);
+ switch (symbolType) {
+ case (short) 0x02: {
+ if(in.readableBytes() < 5) {
+ return;
+ }
+ short commandType = in.getUnsignedByte(4);
+ switch (commandType) {
+ case (short) 0x01: {
+ if(in.readableBytes() < 11) {
+ return;
+ }
+ break;
+ }
+ case (short) 0x41: {
+ int transactionCounter = in.getUnsignedShort(6);
+ if(!readRequestSizes.containsKey(transactionCounter)) {
+ logger.warn("Unknown transaction counter: {}", transactionCounter);
+ if (logger.isDebugEnabled()) {
+ logger.debug("Got Data: {}", ByteBufUtil.hexDump(in));
+ }
+ exceptionCaught(ctx, new PlcProtocolException(
+ String.format("Unknown transaction counte: %04X", transactionCounter)));
+ return;
+ }
+ size = readRequestSizes.remove(transactionCounter);
+ if(in.readableBytes() < 8 + size) {
+ return;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case (short) 0x03: {
+ if(in.readableBytes() < 4) {
+ return;
+ }
+ break;
+ }
+ }
+ }
+
+ // Parse the message received from the DF1 device
+ byte[] data = new byte[in.readableBytes()];
+ in.readBytes(data);
+ ReadBuffer readBuffer = new ReadBuffer(data);
+ DF1Symbol resp = df1SymbolIO.parse(readBuffer, size);
+
+ // Add the received message to the output
+ out.add(resp);
+ }
+
+}
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Plc4XDf1Protocol.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Plc4XDf1Protocol.java
new file mode 100644
index 0000000..9a35c53
--- /dev/null
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Plc4XDf1Protocol.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.java.df1.protocol;
+
+import io.netty.channel.ChannelHandlerContext;
+import org.apache.plc4x.java.base.PlcMessageToMessageCodec;
+import org.apache.plc4x.java.base.messages.PlcRequestContainer;
+import org.apache.plc4x.java.df1.DF1Symbol;
+
+import java.util.List;
+
+public class Plc4XDf1Protocol extends PlcMessageToMessageCodec<DF1Symbol, PlcRequestContainer> {
+
+ @Override
+ protected void encode(ChannelHandlerContext ctx, PlcRequestContainer msg, List<Object> out) throws Exception {
+
+ }
+
+ @Override
+ protected void decode(ChannelHandlerContext ctx, DF1Symbol msg, List<Object> out) throws Exception {
+
+ }
+
+}
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/util/Df1FieldHandler.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/util/Df1FieldHandler.java
new file mode 100644
index 0000000..52e8bfc
--- /dev/null
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/util/Df1FieldHandler.java
@@ -0,0 +1,38 @@
+/*
+ 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.df1.util;
+
+import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException;
+import org.apache.plc4x.java.api.model.PlcField;
+import org.apache.plc4x.java.base.connection.DefaultPlcFieldHandler;
+import org.apache.plc4x.java.base.messages.items.BaseDefaultFieldItem;
+
+public class Df1FieldHandler extends DefaultPlcFieldHandler {
+
+ @Override
+ public PlcField createField(String fieldQuery) throws PlcInvalidFieldException {
+ return null;
+ }
+
+ @Override
+ public BaseDefaultFieldItem encodeByte(PlcField field, Object[] values) {
+ return super.encodeByte(field, values);
+ }
+
+}
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/BenchmarkGeneratedDf1.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/BenchmarkGeneratedDf1.java
deleted file mode 100644
index cc292fa..0000000
--- a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/BenchmarkGeneratedDf1.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * 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.protocol.df1;
-
-import com.fazecast.jSerialComm.SerialPort;
-import org.apache.commons.codec.binary.Hex;
-//import org.apache.plc4x.java.df1.TPKTPacket;
-//import org.apache.plc4x.java.df1.io.TPKTPacketIO;
-import org.apache.plc4x.java.df1.DF1Command;
-import org.apache.plc4x.java.df1.DF1SymbolMessageFrameStart;
-import org.apache.plc4x.java.utils.ReadBuffer;
-import org.apache.plc4x.java.utils.WriteBuffer;
-import org.apache.plc4x.java.df1.DF1Symbol;
-import org.apache.plc4x.java.df1.io.DF1SymbolIO;
-import purejavacomm.CommPortIdentifier;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.BitSet;
-
-public class BenchmarkGeneratedDf1 {
-
- public static void main(String[] args) throws Exception {
-// byte[] rData = Hex.decodeHex("0300006702f080320100000001005600000407120a10060001032b84000160120a10020001032b840001a0120a10010001032b840001a9120a10050001032b84000150120a10020001032b84000198120a10040001032b84000140120a10020001032b84000190");
-// long start = System.currentTimeMillis();
-// int numRunsParse = 2000000;
-// TPKTPacketIO tpktPacketIO = new TPKTPacketIO();
-//
-//
-// CommPortIdentifier id = CommPortIdentifier.getPortIdentifier("");
-//
-//
-// // Benchmark the parsing code
-// TPKTPacket packet = null;
-// for(int i = 0; i < numRunsParse; i++) {
-// ReadBuffer rBuf = new ReadBuffer(rData);
-// packet = tpktPacketIO.parse(rBuf);
-// }
-// long endParsing = System.currentTimeMillis();
-//
-// System.out.println("Parsed " + numRunsParse + " packets in " + (endParsing - start) + "ms");
-// System.out.println("That's " + ((float) (endParsing - start) / numRunsParse) + "ms per packet");
-//
-// // Benchmark the serializing code
-// int numRunsSerialize = 2000000;
-// byte[] oData = null;
-// for(int i = 0; i < numRunsSerialize; i++) {
-// WriteBuffer wBuf = new WriteBuffer(packet.getLengthInBytes());
-// tpktPacketIO.serialize(wBuf, packet);
-// oData = wBuf.getData();
-// }
-// long endSerializing = System.currentTimeMillis();
-//
-// System.out.println("Serialized " + numRunsSerialize + " packets in " + (endSerializing - endParsing) + "ms");
-// System.out.println("That's " + ((float) (endSerializing - endParsing) / numRunsSerialize) + "ms per packet");
-// if(!Arrays.equals(rData, oData)) {
-// for(int i = 0; i < rData.length; i++) {
-// if(rData[i] != oData[i]) {
-// System.out.println("Difference in byte " + i);
-// }
-// }
-// System.out.println("Not equals");
-// } else {
-// System.out.println("Bytes equal");
-// }
-
-
- byte[] rData = {0x10, 0x02, 0x00, 0x09, 0x41, 0x00, 0x01, 0x00, 0x1F, 0x1F, 0x10, 0x03, 0x1A, 0x2B};
-
- DF1SymbolIO df1SymbolIO = new DF1SymbolIO();
- DF1Symbol packet;
- ReadBuffer rBuf = new ReadBuffer(rData);
- int statusWord = (rData[7]<<8) + rData[6];
- DF1Command messageCommand = new DF1Command((short)rData[5]); //,(short)statusWord);
- DF1SymbolMessageFrameStart messageStart = new DF1SymbolMessageFrameStart((short)rData[3],(short)rData[2], messageCommand);
- packet = df1SymbolIO.parse(rBuf, (short) (rData.length-12), messageStart);
-
- System.out.println("x: " + packet);
- System.exit(0);
-
-
-
- SerialPort comPort = SerialPort.getCommPorts()[0];
- comPort.openPort();
-
- comPort.setComPortParameters(19200, 8, SerialPort.ONE_STOP_BIT, SerialPort.NO_PARITY);
-// comPort.setComPortTimeouts(SerialPort.TIMEOUT_NONBLOCKING, 0, 0);
-
- System.out.print(comPort.getSystemPortName() + " | ");
- System.out.print(comPort.getPortDescription() + " | ");
- System.out.print(comPort.getDescriptivePortName() + " | Baud rate: ");
- System.out.println(comPort.getBaudRate());
-// System.out.println(comPort.getReadTimeout());
-// System.out.println(comPort.getWriteTimeout());
-
-
- DF1SymbolIO df1message = new DF1SymbolIO();
-
-
- byte[] c_STX = {0x02};
- byte[] c_SOH = {0x01};
- byte[] c_ETX = {0x03};
- byte[] c_EOT = {0x04};
- byte[] c_ENQ = {0x05};
- byte[] c_ACK = {0x06};
- byte[] c_DLE = {0x10};
- byte[] c_NAK = {0x0f};
-
- byte[] c_DST = {0x09};
- byte[] c_SRC = {0x00};
- byte[] c_CMD = {0x06};
- byte[] c_FNC = {0x03};
- byte[] c_STS = {0x00};
- byte[] c_TNS = {0x01, 0x00};
- byte[] c_ADR = {0x11, 0x00};
- byte[] c_SZE = {0x02};
-// byte[] c_BCC = {-30};
-
-// byte[] c_STN = {0x11};
-// byte[] c_DST = {0x01};
-// byte[] c_SRC = {0x00};
-// byte[] c_SZE = {0x0c};
-// byte[] c_TNS = {0x41, 0x00};
-// byte[] c_ADR = {0x12, 0x00};
-// byte[] c_CRC = {-49, 0x40};
-
-
-// byte[] message = {0x10, 0x01, 0x11, 0x10, 0x02, 0x09, 0x00, 0x01, 0x00, 0x41, 0x00, 0x12, 0x00, 0x0c, 0x10, 0x03}; // halfduplex msg
-// comPort.writeBytes(message, message.length);
-
-// byte[] message = {0x10, 0x05, 0x11, -17}; // halfduplex poll
-// comPort.writeBytes(message, message.length);
-
-
- comPort.writeBytes(c_DLE, 1); // fullduplex msg Seite 235
- comPort.writeBytes(c_STX, 1);
- comPort.writeBytes(c_DST, 1);
- comPort.writeBytes(c_SRC, 1);
- comPort.writeBytes(c_CMD, 1);
- comPort.writeBytes(c_STS, 1);
- comPort.writeBytes(c_TNS, 2);
- comPort.writeBytes(c_FNC, 1);
-// comPort.writeBytes(c_ADR, 2);
-// comPort.writeBytes(c_SZE, 1);
- comPort.writeBytes(c_DLE, 1);
- comPort.writeBytes(c_ETX, 1);
-
-
-// int[] crcmsg = {c_DST[0], c_SRC[0], c_CMD[0], c_STS[0], c_TNS[0], c_TNS[1], c_ADR[0], c_ADR[1], c_SZE[0], c_ETX[0]}; // fullduplex CRC
- int[] crcmsg = {c_DST[0], c_SRC[0], c_CMD[0], c_STS[0], c_TNS[0], c_TNS[1], c_FNC[0], c_ETX[0]}; // diagnostic status request
-// int[] crcmsg = {0x11, 0x02, 0x09, 0x00, 0x01, 0x00, 0x41, 0x00, 0x12, 0x00, 0x0c, 0x03}; // halfduplex CRC
-
- int[] c_CRC = CalcCRC(crcmsg);
- byte[] crc1 = {(byte)c_CRC[0]};
- byte[] crc2 = {(byte)c_CRC[1]};
- comPort.writeBytes(crc1, 1);
- comPort.writeBytes(crc2, 1);
-
-
- while (comPort.bytesAvailable() == 0) {
- Thread.sleep(22); }
-
- byte[] readBuffer = new byte[comPort.bytesAvailable()];
- int numRead = comPort.readBytes(readBuffer, readBuffer.length);
- System.out.println("Read " + numRead + " bytes.");
-
- for (byte c_RCV : readBuffer) {
- System.out.print(Integer.toHexString(c_RCV) + " | "); }
- System.out.println("");
-
-// if (numRead > 1) {
-// if (readBuffer[1] != 0x15) {
-// comPort.writeBytes(c_DLE, 1);
-// comPort.writeBytes(c_ACK, 1);
-// }
-// }
-
- while (comPort.bytesAvailable() == 0) {
- Thread.sleep(22); }
-
-
- byte[] readBuffer2 = new byte[comPort.bytesAvailable()];
- int numRead2 = comPort.readBytes(readBuffer2, readBuffer2.length);
- System.out.println("Read " + numRead2 + " bytes.");
-
- for (byte c_RCV2 : readBuffer2) {
- System.out.print(Integer.toHexString(c_RCV2) + " | "); }
- System.out.println("");
-
- comPort.closePort();
-
- }
-
- private static int[] CalcCRC(int[] crcBytes) {
- int tmp = 0;
- int crcL, crcR;
-
- for (int newByte : crcBytes ) {
- crcL = tmp >> 8;
- crcR = tmp & 0xFF;
- tmp = (crcL << 8) + (newByte ^ crcR);
- for (int j=0; j<8; j++)
- if (tmp % 2 == 1) { // check if LSB shifted out is 1 or 0
- tmp = tmp >> 1;
- tmp = tmp ^ 0xA001;
- } else {
- tmp = tmp >> 1;
- }
- }
-
-// return ((tmp & 0xFF) << 8) + (tmp >> 8); // returns lowbyte|highbyte as one number, change return to non-array
-
- int[] tmparray = {(tmp & 0xFF), (tmp >> 8)};
- return tmparray;
- }
-
- private static int CalcBCC(int[] crcBytes) {
- int tmp = 0;
- int j = 0;
-
- for (int newByte : crcBytes) {
- tmp = tmp + newByte;
- if (newByte == 0x10) {
- j = ++j; }
- }
- tmp = tmp - ((j/2) * 0x10); // get rid of double DLE
- return ((~tmp) & 0b11111111) + 1;
- }
-}
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/DF1Utils.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/DF1Utils.java
index d605293..a85ab8f 100644
--- a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/DF1Utils.java
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/DF1Utils.java
@@ -16,13 +16,69 @@
* specific language governing permissions and limitations
* under the License.
*/
+package org.apache.plc4x.protocol.df1;
+import org.apache.plc4x.java.df1.DF1ReadRequest;
+import org.apache.plc4x.java.df1.DF1Symbol;
+import org.apache.plc4x.java.df1.DF1SymbolMessageFrameStart;
+import org.apache.plc4x.java.utils.ParseException;
+import org.apache.plc4x.java.utils.WriteBuffer;
-package org.apache.plc4x.protocol.df1;
+import java.nio.ByteBuffer;
public class DF1Utils {
public static short CRCCheck(Object... args) {
+ DF1Symbol symbol = (DF1Symbol) args[1];
+ short messageType = (short) args[0];
+ if(symbol instanceof DF1SymbolMessageFrameStart) {
+ DF1SymbolMessageFrameStart messageFrameStart = (DF1SymbolMessageFrameStart) symbol;
+
+ short destinationAddress = messageFrameStart.getDestinationAddress();
+ short sourceAddress = messageFrameStart.getSourceAddress();
+ short commandDiscriminatorValues = (short) messageFrameStart.getCommand().getDiscriminatorValues()[0];
+ short status = messageFrameStart.getCommand().getStatus();
+ int counter = messageFrameStart.getCommand().getTransactionCounter();
+ if(messageFrameStart.getCommand() instanceof DF1ReadRequest) {
+ DF1ReadRequest readRequestCommand = (DF1ReadRequest) messageFrameStart.getCommand();
+
+ try {
+ WriteBuffer writeBuffer = new WriteBuffer(10, false);
+ writeBuffer.writeUnsignedShort(8, destinationAddress);
+ writeBuffer.writeUnsignedShort(8, sourceAddress);
+ writeBuffer.writeUnsignedShort(8, commandDiscriminatorValues);
+ writeBuffer.writeUnsignedShort(8, status);
+ writeBuffer.writeUnsignedInt(16, (short) counter);
+ writeBuffer.writeUnsignedInt(16, (short) readRequestCommand.getAddress());
+ writeBuffer.writeUnsignedShort(8, (byte) readRequestCommand.getSize());
+ writeBuffer.writeUnsignedShort(8, (byte) messageType);
+
+ byte[] data = writeBuffer.getData();
+
+ int tmp = 0;
+ int crcL, crcR;
+
+ for (int newByte : data) {
+ crcL = tmp >> 8;
+ crcR = tmp & 0xFF;
+ tmp = (crcL << 8) + (newByte ^ crcR);
+ for (int j=0; j<8; j++)
+ if (tmp % 2 == 1) { // check if LSB shifted out is 1 or 0
+ tmp = tmp >> 1;
+ tmp = tmp ^ 0xA001;
+ } else {
+ tmp = tmp >> 1;
+ }
+ }
+
+ return (short) tmp;
+ } catch (ParseException e) {
+ throw new RuntimeException("Something wen't wrong during the CRC check", e);
+ }
+ }
+ }
+
return 0;
}
+
}
diff --git a/sandbox/test-java-df1-driver/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.PlcDriver b/sandbox/test-java-df1-driver/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.PlcDriver
new file mode 100644
index 0000000..fddc33d
--- /dev/null
+++ b/sandbox/test-java-df1-driver/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.PlcDriver
@@ -0,0 +1,19 @@
+#
+# 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.java.df1.DF1PlcDriver
diff --git a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkGeneratedDf1.java b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkGeneratedDf1.java
new file mode 100644
index 0000000..e092cb6
--- /dev/null
+++ b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkGeneratedDf1.java
@@ -0,0 +1,84 @@
+/*
+ * 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.protocol.df1;
+
+import com.fazecast.jSerialComm.SerialPort;
+import org.apache.plc4x.java.df1.*;
+import org.apache.plc4x.java.df1.io.ReadRequestIO;
+import org.apache.plc4x.java.df1.io.ReadResponseIO;
+import org.apache.plc4x.java.df1.io.ResultIO;
+import org.apache.plc4x.java.utils.ReadBuffer;
+import org.apache.plc4x.java.utils.WriteBuffer;
+
+public class BenchmarkGeneratedDf1 {
+
+ public static void main(String[] args) throws Exception {
+ // Manually build a message
+ ReadRequest readRequest = new ReadRequest(new DF1SymbolMessageFrameStart((short) 0x09, (short) 0x00, new DF1ReadRequest((short) 0x00, 0x01, 0x0B, (short) 0x02)), new DF1SymbolMessageFrameEnd());
+
+ // Serialize the message
+ WriteBuffer writeBuffer = new WriteBuffer(100, false);
+ new ReadRequestIO().serialize(writeBuffer, readRequest);
+ byte[] data = writeBuffer.getData();
+
+ // Send the serialized message to the PLC via COM port
+ SerialPort comPort = SerialPort.getCommPort("/dev/cu.usbserial-AL065SUZ");
+ comPort.openPort();
+ comPort.setComPortParameters(19200, 8, SerialPort.ONE_STOP_BIT, SerialPort.NO_PARITY);
+ comPort.writeBytes(data, 20);
+
+ // Give the PLC some time to respond.
+ while (comPort.bytesAvailable() == 0) {
+ Thread.sleep(22);
+ }
+
+ // Read the response
+ byte[] readBytes = new byte[comPort.bytesAvailable()];
+ comPort.readBytes(readBytes, readBytes.length);
+
+ // Parse the ACK/NACK response
+ ReadBuffer readBuffer = new ReadBuffer(readBytes);
+ Result result = new ResultIO().parse(readBuffer);
+
+ // Check if the response was an ACK
+ if(result.getResult() instanceof DF1SymbolMessageFrameACK) {
+ // The actual result is sent with a little delay.
+ while (comPort.bytesAvailable() == 0) {
+ Thread.sleep(22);
+ }
+
+ // Read the actual response data
+ readBytes = new byte[comPort.bytesAvailable()];
+ comPort.readBytes(readBytes, readBytes.length);
+
+ // Parse the response
+ readBuffer = new ReadBuffer(readBytes);
+ ReadResponse readResponse = new ReadResponseIO().parse(readBuffer, (short) 0x02);
+
+ // So something senseless ;-)
+ System.out.println(readResponse);
+ } else {
+ System.out.println("Didn't get an ACK");
+ }
+
+ comPort.closePort();
+ }
+
+}
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/BenchmarkManualDf1.java b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkManualDf1.java
similarity index 99%
rename from sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/BenchmarkManualDf1.java
rename to sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkManualDf1.java
index 5fa447e..c2571fe 100644
--- a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/BenchmarkManualDf1.java
+++ b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkManualDf1.java
@@ -78,7 +78,7 @@ public class BenchmarkManualDf1 {
byte[] rData = {0x10, 0x02, 0x00, 0x09, 0x41, 0x00, 0x01, 0x00, 0x1F, 0x1F, 0x10, 0x03, 0x1A, 0x2B};
- DF1SymbolIO df1SymbolIO = new DF1SymbolIO();
+ /* DF1SymbolIO df1SymbolIO = new DF1SymbolIO();
DF1Symbol packet;
ReadBuffer rBuf = new ReadBuffer(rData);
int statusWord = (rData[7]<<8) + rData[6];
@@ -198,7 +198,7 @@ public class BenchmarkManualDf1 {
System.out.print(Integer.toHexString(c_RCV2) + " | "); }
System.out.println("");
- comPort.closePort();
+ comPort.closePort();*/
}