You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sr...@apache.org on 2018/06/07 14:50:33 UTC

[incubator-plc4x] branch master updated (dbdb331 -> bf508e3)

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

sruehl pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git.


    from dbdb331  Added another interesting link regarding the s7 comm plus protocol.
     new 87cf9d0  added toString(), equals() and hashCode() to PlcRequestContainer
     new 4ad7ea2  added ADS protocol Tracing
     new a2d2b4f  added output for cli input on example test
     new 3ef3922  added logging of retransmission
     new db58135  fixed wrong log category
     new bf508e3  updated serial ads-protocol: - removed thread blocking - only read on complete data

The 6 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:
 .../java/api/messages/PlcRequestContainer.java     |  24 +++
 .../java/ads/protocol/Ads2PayloadProtocol.java     |   2 +
 .../java/ads/protocol/Payload2SerialProtocol.java  |  63 +++-----
 .../java/ads/protocol/Payload2TcpProtocol.java     |   6 +-
 .../plc4x/java/ads/protocol/Plc4x2AdsProtocol.java |   2 +
 .../ads/adslib/ADSClientNotificationExample.java   |   1 +
 .../ads/connection/AdsSerialPlcConnectionTest.java | 177 ++++++++++++++++++++-
 7 files changed, 230 insertions(+), 45 deletions(-)

-- 
To stop receiving notification emails like this one, please contact
sruehl@apache.org.

[incubator-plc4x] 01/06: added toString(), equals() and hashCode() to PlcRequestContainer

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

sruehl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git

commit 87cf9d0995999b133e53f12d64fe8c381ad28e3e
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Thu Jun 7 09:16:57 2018 +0200

    added toString(), equals() and hashCode() to PlcRequestContainer
---
 .../java/api/messages/PlcRequestContainer.java     | 24 ++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcRequestContainer.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcRequestContainer.java
index 6443c36..4168246 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcRequestContainer.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcRequestContainer.java
@@ -51,4 +51,28 @@ public class PlcRequestContainer<T extends PlcRequest, R extends PlcResponse> im
         return null;
     }
 
+    @Override
+    public String toString() {
+        return "PlcRequestContainer{" +
+            "request=" + request +
+            '}';
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof PlcRequestContainer)) {
+            return false;
+        }
+        PlcRequestContainer<?, ?> that = (PlcRequestContainer<?, ?>) o;
+        return Objects.equals(request, that.request) &&
+            Objects.equals(responseFuture, that.responseFuture);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(request, responseFuture);
+    }
 }

-- 
To stop receiving notification emails like this one, please contact
sruehl@apache.org.

[incubator-plc4x] 04/06: added logging of retransmission

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

sruehl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git

commit 3ef3922d7c0667b33729db07f7287fe92d2d9cdf
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Thu Jun 7 12:05:21 2018 +0200

    added logging of retransmission
---
 .../java/org/apache/plc4x/java/ads/protocol/Payload2SerialProtocol.java  | 1 +
 1 file changed, 1 insertion(+)

diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2SerialProtocol.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2SerialProtocol.java
index d6411fd..aff68d4 100644
--- a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2SerialProtocol.java
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2SerialProtocol.java
@@ -72,6 +72,7 @@ public class Payload2SerialProtocol extends MessageToMessageCodec<ByteBuf, ByteB
             retryHandler = channelHandlerContext.executor().schedule(() -> {
                 try {
                     TimeUnit.SECONDS.sleep(2);
+                    LOGGER.info("Retransmitting {}", amsSerialFrame);
                     channelHandlerContext.channel().writeAndFlush(amsSerialFrame.getByteBuf());
                 } catch (InterruptedException e) {
                     LOGGER.debug("Interrupted", e);

-- 
To stop receiving notification emails like this one, please contact
sruehl@apache.org.

[incubator-plc4x] 02/06: added ADS protocol Tracing

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

sruehl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git

commit 4ad7ea20ca03a6bc1e6aff156c4303b335177961
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Thu Jun 7 09:39:17 2018 +0200

    added ADS protocol Tracing
---
 .../org/apache/plc4x/java/ads/protocol/Ads2PayloadProtocol.java     | 2 ++
 .../org/apache/plc4x/java/ads/protocol/Payload2SerialProtocol.java  | 2 ++
 .../org/apache/plc4x/java/ads/protocol/Payload2TcpProtocol.java     | 6 ++++--
 .../java/org/apache/plc4x/java/ads/protocol/Plc4x2AdsProtocol.java  | 2 ++
 4 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Ads2PayloadProtocol.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Ads2PayloadProtocol.java
index 6beae2e..d0d8468 100644
--- a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Ads2PayloadProtocol.java
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Ads2PayloadProtocol.java
@@ -66,6 +66,7 @@ public class Ads2PayloadProtocol extends MessageToMessageCodec<ByteBuf, AmsPacke
 
     @Override
     protected void encode(ChannelHandlerContext channelHandlerContext, AmsPacket amsPacket, List<Object> out) {
+        LOGGER.trace("(<--OUT): {}, {}, {}", channelHandlerContext, amsPacket, out);
         Invoke invokeId = amsPacket.getAmsHeader().getInvokeId();
         if (invokeId != Invoke.NONE) {
             requests.put(invokeId, amsPacket);
@@ -75,6 +76,7 @@ public class Ads2PayloadProtocol extends MessageToMessageCodec<ByteBuf, AmsPacke
 
     @Override
     protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> out) {
+        LOGGER.trace("(-->IN): {}, {}, {}", channelHandlerContext, byteBuf, out);
         AmsNetId targetAmsNetId = AmsNetId.of(byteBuf);
         AmsPort targetAmsPort = AmsPort.of(byteBuf);
         AmsNetId sourceAmsNetId = AmsNetId.of(byteBuf);
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2SerialProtocol.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2SerialProtocol.java
index 1fd4c42..d6411fd 100644
--- a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2SerialProtocol.java
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2SerialProtocol.java
@@ -54,6 +54,7 @@ public class Payload2SerialProtocol extends MessageToMessageCodec<ByteBuf, ByteB
 
     @Override
     protected void encode(ChannelHandlerContext channelHandlerContext, ByteBuf amsPacket, List<Object> out) throws Exception {
+        LOGGER.trace("(<--OUT): {}, {}, {}", channelHandlerContext, amsPacket, out);
         while (frameOnTheWay.get() || !lock.tryLock()) {
             // In this case we might not send it yet.
             TimeUnit.MILLISECONDS.sleep(10);
@@ -86,6 +87,7 @@ public class Payload2SerialProtocol extends MessageToMessageCodec<ByteBuf, ByteB
 
     @Override
     protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> out) throws Exception {
+        LOGGER.trace("(-->IN): {}, {}, {}", channelHandlerContext, byteBuf, out);
         MagicCookie magicCookie = MagicCookie.of(byteBuf);
         TransmitterAddress transmitterAddress = TransmitterAddress.of(byteBuf);
         ReceiverAddress receiverAddress = ReceiverAddress.of(byteBuf);
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2TcpProtocol.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2TcpProtocol.java
index b164368..c0e06fd 100644
--- a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2TcpProtocol.java
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2TcpProtocol.java
@@ -35,13 +35,15 @@ public class Payload2TcpProtocol extends MessageToMessageCodec<ByteBuf, ByteBuf>
     private static final Logger LOGGER = LoggerFactory.getLogger(Payload2TcpProtocol.class);
 
     @Override
-    protected void encode(ChannelHandlerContext channelHandlerContext, ByteBuf amsPacket, List<Object> out) throws Exception {
+    protected void encode(ChannelHandlerContext channelHandlerContext, ByteBuf amsPacket, List<Object> out) {
+        LOGGER.trace("(<--OUT): {}, {}, {}", channelHandlerContext, amsPacket, out);
         out.add(AmsTCPPacket.of(UserData.of(amsPacket)).getByteBuf());
     }
 
     @SuppressWarnings("unchecked")
     @Override
-    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> out) throws Exception {
+    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> out) {
+        LOGGER.trace("(-->IN): {}, {}, {}", channelHandlerContext, byteBuf, out);
         // Reserved
         byteBuf.skipBytes(AmsTcpHeader.Reserved.NUM_BYTES);
         TcpLength packetLength = TcpLength.of(byteBuf);
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Plc4x2AdsProtocol.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Plc4x2AdsProtocol.java
index 577c529..7e2c19e 100644
--- a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Plc4x2AdsProtocol.java
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Plc4x2AdsProtocol.java
@@ -86,6 +86,7 @@ public class Plc4x2AdsProtocol extends MessageToMessageCodec<AmsPacket, PlcReque
 
     @Override
     protected void encode(ChannelHandlerContext ctx, PlcRequestContainer<PlcRequest, PlcResponse> msg, List<Object> out) throws Exception {
+        LOGGER.trace("(<--OUT): {}, {}, {}", ctx, msg, out);
         PlcRequest request = msg.getRequest();
         if (request instanceof PlcReadRequest) {
             encodeReadRequest(msg, out);
@@ -187,6 +188,7 @@ public class Plc4x2AdsProtocol extends MessageToMessageCodec<AmsPacket, PlcReque
 
     @Override
     protected void decode(ChannelHandlerContext channelHandlerContext, AmsPacket amsPacket, List<Object> out) throws Exception {
+        LOGGER.trace("(-->IN): {}, {}, {}", channelHandlerContext, amsPacket, out);
         if (amsPacket instanceof AdsDeviceNotificationRequest) {
             LOGGER.debug("Received notification {}", amsPacket);
             handleAdsDeviceNotificationRequest((AdsDeviceNotificationRequest) amsPacket);

-- 
To stop receiving notification emails like this one, please contact
sruehl@apache.org.

[incubator-plc4x] 05/06: fixed wrong log category

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

sruehl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git

commit db5813586acc07b823e3b80768776ba5f5c22ec8
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Thu Jun 7 13:57:40 2018 +0200

    fixed wrong log category
---
 .../java/org/apache/plc4x/java/ads/protocol/Payload2SerialProtocol.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2SerialProtocol.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2SerialProtocol.java
index aff68d4..00f2250 100644
--- a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2SerialProtocol.java
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2SerialProtocol.java
@@ -42,7 +42,7 @@ import java.util.concurrent.locks.ReentrantLock;
 
 public class Payload2SerialProtocol extends MessageToMessageCodec<ByteBuf, ByteBuf> {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(Payload2TcpProtocol.class);
+    private static final Logger LOGGER = LoggerFactory.getLogger(Payload2SerialProtocol.class);
 
     private final AtomicInteger fragmentCounter = new AtomicInteger(0);
 

-- 
To stop receiving notification emails like this one, please contact
sruehl@apache.org.

[incubator-plc4x] 06/06: updated serial ads-protocol: - removed thread blocking - only read on complete data

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

sruehl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git

commit bf508e3e6876af4f06c5336fea1a445fea269be0
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Thu Jun 7 16:46:33 2018 +0200

    updated serial ads-protocol:
    - removed thread blocking
    - only read on complete data
---
 .../java/ads/protocol/Payload2SerialProtocol.java  |  60 +++----
 .../ads/connection/AdsSerialPlcConnectionTest.java | 177 ++++++++++++++++++++-
 2 files changed, 194 insertions(+), 43 deletions(-)

diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2SerialProtocol.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2SerialProtocol.java
index 00f2250..45edf8a 100644
--- a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2SerialProtocol.java
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/Payload2SerialProtocol.java
@@ -23,7 +23,6 @@ import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.MessageToMessageCodec;
 import io.netty.util.ReferenceCountUtil;
-import io.netty.util.concurrent.ScheduledFuture;
 import org.apache.plc4x.java.ads.api.serial.AmsSerialAcknowledgeFrame;
 import org.apache.plc4x.java.ads.api.serial.AmsSerialFrame;
 import org.apache.plc4x.java.ads.api.serial.AmsSerialResetFrame;
@@ -34,11 +33,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
 
 public class Payload2SerialProtocol extends MessageToMessageCodec<ByteBuf, ByteBuf> {
 
@@ -46,49 +41,27 @@ public class Payload2SerialProtocol extends MessageToMessageCodec<ByteBuf, ByteB
 
     private final AtomicInteger fragmentCounter = new AtomicInteger(0);
 
-    private final AtomicBoolean frameOnTheWay = new AtomicBoolean(false);
-
-    private volatile ScheduledFuture<ChannelFuture> retryHandler;
-
-    private final Lock lock = new ReentrantLock(true);
-
     @Override
-    protected void encode(ChannelHandlerContext channelHandlerContext, ByteBuf amsPacket, List<Object> out) throws Exception {
+    protected void encode(ChannelHandlerContext channelHandlerContext, ByteBuf amsPacket, List<Object> out) {
         LOGGER.trace("(<--OUT): {}, {}, {}", channelHandlerContext, amsPacket, out);
-        while (frameOnTheWay.get() || !lock.tryLock()) {
-            // In this case we might not send it yet.
-            TimeUnit.MILLISECONDS.sleep(10);
-        }
         int fragmentNumber = fragmentCounter.getAndIncrement();
         if (fragmentNumber > 255) {
             fragmentNumber = 0;
             fragmentCounter.set(fragmentNumber);
         }
-        try {
-            // TODO: we need to remember the fragment and maybe even need to spilt up the package
-            // TODO: if we exceed 255 byte
-            AmsSerialFrame amsSerialFrame = AmsSerialFrame.of(FragmentNumber.of((byte) fragmentNumber), UserData.of(amsPacket));
-            out.add(amsSerialFrame.getByteBuf());
-            retryHandler = channelHandlerContext.executor().schedule(() -> {
-                try {
-                    TimeUnit.SECONDS.sleep(2);
-                    LOGGER.info("Retransmitting {}", amsSerialFrame);
-                    channelHandlerContext.channel().writeAndFlush(amsSerialFrame.getByteBuf());
-                } catch (InterruptedException e) {
-                    LOGGER.debug("Interrupted", e);
-                    Thread.currentThread().interrupt();
-                }
-                return channelHandlerContext.voidPromise();
-            }, 0, TimeUnit.MILLISECONDS);
-            frameOnTheWay.set(true);
-        } finally {
-            lock.unlock();
-        }
+        LOGGER.debug("Using fragmentNumber {} for {}", fragmentNumber, amsPacket);
+        // TODO: we need to remember the fragment and maybe even need to spilt up the package
+        // TODO: if we exceed 255 byte
+        AmsSerialFrame amsSerialFrame = AmsSerialFrame.of(FragmentNumber.of((byte) fragmentNumber), UserData.of(amsPacket));
+        out.add(amsSerialFrame.getByteBuf());
     }
 
     @Override
     protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> out) throws Exception {
         LOGGER.trace("(-->IN): {}, {}, {}", channelHandlerContext, byteBuf, out);
+        if (byteBuf.readableBytes() < MagicCookie.NUM_BYTES + TransmitterAddress.NUM_BYTES + ReceiverAddress.NUM_BYTES + FragmentNumber.NUM_BYTES) {
+            return;
+        }
         MagicCookie magicCookie = MagicCookie.of(byteBuf);
         TransmitterAddress transmitterAddress = TransmitterAddress.of(byteBuf);
         ReceiverAddress receiverAddress = ReceiverAddress.of(byteBuf);
@@ -96,6 +69,9 @@ public class Payload2SerialProtocol extends MessageToMessageCodec<ByteBuf, ByteB
         UserDataLength userDataLength = UserDataLength.of(byteBuf);
         UserData userData;
         byte userDataLengthAsByte = userDataLength.getAsByte();
+        if (byteBuf.readableBytes() < userDataLengthAsByte) {
+            return;
+        }
         if (userDataLengthAsByte > 0) {
             byte[] userDataByteArray = new byte[userDataLengthAsByte];
             byteBuf.readBytes(userDataByteArray);
@@ -105,21 +81,20 @@ public class Payload2SerialProtocol extends MessageToMessageCodec<ByteBuf, ByteB
         }
         CRC crc = CRC.of(byteBuf);
 
+        Runnable postAction = null;
         switch (magicCookie.getAsInt()) {
             case AmsSerialFrame.ID:
                 AmsSerialFrame amsSerialFrame = AmsSerialFrame.of(magicCookie, transmitterAddress, receiverAddress, fragmentNumber, userDataLength, userData, crc);
                 LOGGER.debug("Ams Serial Frame received {}", amsSerialFrame);
                 // TODO: check if this is the right way to ack a package.
-                ChannelFuture channelFuture = channelHandlerContext.writeAndFlush(AmsSerialAcknowledgeFrame.of(transmitterAddress, receiverAddress, fragmentNumber));
+                ChannelFuture channelFuture = channelHandlerContext.writeAndFlush(AmsSerialAcknowledgeFrame.of(transmitterAddress, receiverAddress, fragmentNumber).getByteBuf());
                 // waiting for the ack-frame to be transmitted before we forward the package
                 channelFuture.await();
-                frameOnTheWay.set(false);
-                out.add(userData.getByteBuf());
+                postAction = () -> out.add(userData.getByteBuf());
                 break;
             case AmsSerialAcknowledgeFrame.ID:
                 AmsSerialAcknowledgeFrame amsSerialAcknowledgeFrame = AmsSerialAcknowledgeFrame.of(magicCookie, transmitterAddress, receiverAddress, fragmentNumber, userDataLength, crc);
                 LOGGER.debug("Ams Serial ACK Frame received {}", amsSerialAcknowledgeFrame);
-                retryHandler.cancel(true);
                 ReferenceCountUtil.release(byteBuf);
                 break;
             case AmsSerialResetFrame.ID:
@@ -134,9 +109,12 @@ public class Payload2SerialProtocol extends MessageToMessageCodec<ByteBuf, ByteB
             throw new PlcProtocolException("CRC checksum wrong. Got " + crc + " expected " + calculatedCrc);
         }
 
+        if (postAction != null) {
+            postAction.run();
+        }
+
         if (byteBuf.readableBytes() > 0) {
             throw new IllegalStateException("Unread bytes left: " + byteBuf.readableBytes());
         }
-
     }
 }
diff --git a/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/connection/AdsSerialPlcConnectionTest.java b/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/connection/AdsSerialPlcConnectionTest.java
index b59be5a..9bf767c 100644
--- a/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/connection/AdsSerialPlcConnectionTest.java
+++ b/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/connection/AdsSerialPlcConnectionTest.java
@@ -18,18 +18,39 @@
  */
 package org.apache.plc4x.java.ads.connection;
 
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.embedded.EmbeddedChannel;
+import org.apache.commons.lang3.reflect.FieldUtils;
 import org.apache.plc4x.java.ads.api.generic.types.AmsNetId;
 import org.apache.plc4x.java.ads.api.generic.types.AmsPort;
+import org.apache.plc4x.java.ads.api.serial.AmsSerialAcknowledgeFrame;
+import org.apache.plc4x.java.ads.api.serial.types.*;
 import org.apache.plc4x.java.ads.model.AdsAddress;
 import org.apache.plc4x.java.ads.model.SymbolicAdsAddress;
+import org.apache.plc4x.java.api.messages.PlcReadRequest;
+import org.apache.plc4x.java.api.messages.PlcReadResponse;
+import org.apache.plc4x.java.base.connection.AbstractPlcConnection;
+import org.apache.plc4x.java.base.connection.SerialChannelFactory;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Field;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
 
 import static org.junit.Assert.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
 
 public class AdsSerialPlcConnectionTest {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(AdsSerialPlcConnectionTest.class);
+
     private AdsSerialPlcConnection SUT;
 
     @Before
@@ -60,8 +81,8 @@ public class AdsSerialPlcConnectionTest {
     @Test
     public void parseAddress() {
         try {
-            AdsAddress address = (AdsAddress) SUT.parseAddress("1/1");
-            assertEquals(address.getIndexGroup(), 1);
+            AdsAddress address = (AdsAddress) SUT.parseAddress("0/1");
+            assertEquals(address.getIndexGroup(), 0);
             assertEquals(address.getIndexOffset(), 1);
         } catch (IllegalArgumentException exception) {
             fail("valid data block address");
@@ -77,4 +98,156 @@ public class AdsSerialPlcConnectionTest {
             fail("valid data block address");
         }
     }
+
+    @Test
+    public void testRead() throws Exception {
+        prepareSerialSimulator();
+        CompletableFuture<PlcReadResponse> read = SUT.read(new PlcReadRequest(String.class, SUT.parseAddress("0/0")));
+        PlcReadResponse plcReadResponse = read.get(30, TimeUnit.SECONDS);
+        assertNotNull(plcReadResponse);
+    }
+
+    private void prepareSerialSimulator() throws Exception {
+        Field channelFactoryField = FieldUtils.getField(AbstractPlcConnection.class, "channelFactory", true);
+        SerialChannelFactory serialChannelFactory = (SerialChannelFactory) channelFactoryField.get(SUT);
+        SerialChannelFactory serialChannelFactorySpied = spy(serialChannelFactory);
+        EmbeddedChannel embeddedChannel = new EmbeddedChannel(SUT.getChannelHandler(null));
+        doReturn(embeddedChannel).when(serialChannelFactorySpied).createChannel(any());
+        channelFactoryField.set(SUT, serialChannelFactorySpied);
+        SUT.connect();
+        new SerialSimulator(embeddedChannel).start();
+    }
+
+    private class SerialSimulator extends Thread {
+
+        private EmbeddedChannel embeddedChannel;
+
+        private SimulatorState state = SimulatorState.RECEIVE_REQUEST;
+
+        public SerialSimulator(EmbeddedChannel embeddedChannel) {
+            super("Serial Simulator");
+            this.embeddedChannel = embeddedChannel;
+        }
+
+        @Override
+        public void run() {
+            while (true) {
+                switch (state) {
+                    // Receiving state
+                    case RECEIVE_REQUEST: {
+                        LOGGER.info("Waiting for normal message");
+                        ByteBuf outputBuffer;
+                        while ((outputBuffer = embeddedChannel.readOutbound()) == null) {
+                            if (!trySleep()) {
+                                return;
+                            }
+                        }
+                        int headerBytes = MagicCookie.NUM_BYTES + TransmitterAddress.NUM_BYTES + ReceiverAddress.NUM_BYTES + FragmentNumber.NUM_BYTES;
+                        LOGGER.info("Skipping " + headerBytes + " bytes");
+                        outputBuffer.skipBytes(headerBytes);
+                        short dataLength = outputBuffer.readUnsignedByte();
+                        LOGGER.info("Expect at least " + dataLength + "bytes");
+                        while (outputBuffer.readableBytes() < dataLength) {
+                            if (!trySleep()) {
+                                return;
+                            }
+                        }
+                        byte[] bytes = new byte[dataLength];
+                        LOGGER.info("Read " + dataLength + "bytes. Having " + outputBuffer.readableBytes() + "bytes");
+                        outputBuffer.readBytes(bytes);
+                        outputBuffer.skipBytes(CRC.NUM_BYTES);
+                        LOGGER.info("Wrote Inbound");
+                        state = SimulatorState.ACK_MESSAGE;
+                        if (!trySleep()) {
+                            return;
+                        }
+                    }
+                    break;
+                    case ACK_MESSAGE: {
+                        ByteBuf byteBuf = AmsSerialAcknowledgeFrame.of(
+                            TransmitterAddress.of((byte) 0x0),
+                            ReceiverAddress.of((byte) 0x0),
+                            FragmentNumber.of((byte) 0)
+                        ).getByteBuf();
+                        embeddedChannel.writeOneInbound(byteBuf);
+                        LOGGER.info("Acked Message");
+                        state = SimulatorState.SEND_RESPONSE;
+                    }
+                    case SEND_RESPONSE: {
+                        LOGGER.info("Sending data message");
+                        embeddedChannel.writeOneInbound(Unpooled.wrappedBuffer(new byte[]{
+                            /*Magic Cookie     */    0x01, (byte) 0xA5,
+                            /*Sender           */    0x00,
+                            /*Empfaenger       */    0x00,
+                            /*Fragmentnummer   */    (byte) 0x00,
+                            /*Anzahl Daten     */    0x2A,
+                            /*NetID Empfaenger */    (byte) 0xC0, (byte) 0xA8, 0x64, (byte) 0x9C, 0x01, 0x01,
+                            /*Portnummer       */    0x01, (byte) 0x80,
+                            /*NetID Sender     */    (byte) 0xC0, (byte) 0xA8, 0x64, (byte) 0xAE, 0x01, 0x01,
+                            /*Portnummer       */    0x21, 0x03,
+                            /*Response Lesen   */    0x02, 0x00,
+                            /*Status           */    0x05, 0x00,
+                            /*Anzahl Daten     */    0x0A, 0x00, 0x00, 0x00,
+                            /*Fehlercode       */    0x00, 0x00, 0x00, 0x00,
+                            /*InvokeID         */    0x02, 0x00, 0x00, 0x00,
+                            /*Ergebnis         */    0x00, 0x00, 0x00, 0x00,
+                            /*Anzahl Daten     */    0x02, 0x00, 0x00, 0x00,
+                            /*Daten            */    (byte) 0xAF, 0x27,
+                            /*Checksumme       */    0x60, (byte) 0x0c,
+                        }));
+                        LOGGER.info("Wrote Inbound");
+                        state = SimulatorState.WAIT_FOR_ACK;
+                        if (!trySleep()) {
+                            return;
+                        }
+                    }
+                    break;
+                    case WAIT_FOR_ACK: {
+                        LOGGER.info("Waiting for ack message");
+                        ByteBuf outputBuffer;
+                        while ((outputBuffer = embeddedChannel.readOutbound()) == null) {
+                            if (!trySleep()) {
+                                return;
+                            }
+                        }
+                        int headerBytes = MagicCookie.NUM_BYTES + TransmitterAddress.NUM_BYTES + ReceiverAddress.NUM_BYTES + FragmentNumber.NUM_BYTES;
+                        LOGGER.info("Skipping " + headerBytes + " bytes");
+                        outputBuffer.skipBytes(headerBytes);
+                        short dataLength = outputBuffer.readUnsignedByte();
+                        LOGGER.info("Expect " + dataLength + "bytes");
+                        state = SimulatorState.DONE;
+                        if (!trySleep()) {
+                            return;
+                        }
+                    }
+                    case DONE: {
+                        LOGGER.info("Plc is Done. Goodbye");
+                        return;
+                    }
+                    default:
+                        throw new IllegalStateException("Illegal state number" + state);
+                }
+            }
+
+        }
+
+        private boolean trySleep() {
+            try {
+                TimeUnit.MILLISECONDS.sleep(10);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+                Thread.currentThread().interrupt();
+                return false;
+            }
+            return true;
+        }
+    }
+
+    private enum SimulatorState {
+        RECEIVE_REQUEST,
+        ACK_MESSAGE,
+        SEND_RESPONSE,
+        WAIT_FOR_ACK,
+        DONE
+    }
 }
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
sruehl@apache.org.

[incubator-plc4x] 03/06: added output for cli input on example test

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

sruehl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git

commit a2d2b4fbf7d9532e6826c7a2998c7f744b6c412a
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Thu Jun 7 09:41:48 2018 +0200

    added output for cli input on example test
---
 .../org/apache/plc4x/java/ads/adslib/ADSClientNotificationExample.java   | 1 +
 1 file changed, 1 insertion(+)

diff --git a/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/adslib/ADSClientNotificationExample.java b/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/adslib/ADSClientNotificationExample.java
index 08097cd..126d011 100644
--- a/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/adslib/ADSClientNotificationExample.java
+++ b/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/adslib/ADSClientNotificationExample.java
@@ -245,6 +245,7 @@ public class ADSClientNotificationExample {
         if (args.length == 2) {
             remoteIpV4 = args[0];
             remoteNetIdString = args[1];
+            System.out.println("Using supplied arguments " + remoteIpV4 + "/" + remoteNetIdString);
         }
         runExample(remoteNetIdString, remoteIpV4, System.out);
         System.exit(0);

-- 
To stop receiving notification emails like this one, please contact
sruehl@apache.org.