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


The following commit(s) were added to refs/heads/master by this push:
     new 8e19212  several small fixes on ads protocol
8e19212 is described below

commit 8e192122734bda4882f126fb69822d5aa4cf4454
Author: Sebastian Rühl <sru...@apache.org>
AuthorDate: Thu Apr 26 15:24:19 2018 +0200

    several small fixes on ads protocol
---
 .../api/commands/AdsDeviceNotificationRequest.java |  2 +-
 .../java/ads/api/commands/types/AdsReturnCode.java |  2 +-
 .../java/ads/api/commands/types/TimeStamp.java     |  4 +--
 .../plc4x/java/ads/api/generic/types/AmsPort.java  | 21 ++++++-------
 .../plc4x/java/ads/api/generic/types/Command.java  |  6 ++--
 .../java/ads/api/util/UnsignedIntLEByteValue.java  | 14 ++++-----
 .../ads/api/util/UnsignedShortLEByteValue.java     | 14 +++++----
 .../ads/connection/AdsSerialPlcConnection.java     |  4 +--
 .../java/ads/protocol/Ads2PayloadProtocol.java     |  3 +-
 .../plc4x/java/ads/protocol/Plc4x2AdsProtocol.java | 34 +++++++++++++++++++---
 .../ads/protocol/util/LittleEndianDecoder.java     |  5 ++--
 .../ads/protocol/util/LittleEndianEncoder.java     |  1 +
 12 files changed, 69 insertions(+), 41 deletions(-)

diff --git 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/AdsDeviceNotificationRequest.java
 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/AdsDeviceNotificationRequest.java
index 6b75109..583673c 100644
--- 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/AdsDeviceNotificationRequest.java
+++ 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/AdsDeviceNotificationRequest.java
@@ -75,7 +75,7 @@ public class AdsDeviceNotificationRequest extends 
AdsAbstractRequest {
             for (LengthSupplier supplier : adsStampHeaders) {
                 aggregateLength += supplier.getCalculatedLength();
             }
-            return aggregateLength;
+            return aggregateLength + Stamps.NUM_BYTES;
         };
     }
 
diff --git 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/types/AdsReturnCode.java
 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/types/AdsReturnCode.java
index 6c6c982..edadf21 100644
--- 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/types/AdsReturnCode.java
+++ 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/types/AdsReturnCode.java
@@ -33,7 +33,7 @@ public enum AdsReturnCode {
     ADS_CODE_3(0x3, 3, "Allocation locked memory error"),
     ADS_CODE_4(0x4, 4, "Insert mailbox error", "No ADS mailbox was available 
to process this message.", "Reduce the number of ADS calls (e.g ADS-Sum 
commands or Max Delay Parameter)"),
     ADS_CODE_5(0x5, 5, "Wrong receive HMSG"),
-    ADS_CODE_6(0x6, 6, "target port not foundADS ", "Server not started"),
+    ADS_CODE_6(0x6, 6, "target port not found", "ADS Server not started"),
     ADS_CODE_7(0x7, 7, "target machine not found", "Missing ADS routes"),
     ADS_CODE_8(0x8, 8, "Unknown command ID"),
     ADS_CODE_9(0x9, 9, "Bad task ID"),
diff --git 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/types/TimeStamp.java
 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/types/TimeStamp.java
index c0ce2f0..fc283b5 100644
--- 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/types/TimeStamp.java
+++ 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/types/TimeStamp.java
@@ -121,11 +121,11 @@ public class TimeStamp extends ByteValue {
         return of(values);
     }
 
-    private BigInteger getBigIntegerValue() {
+    public BigInteger getBigIntegerValue() {
         return bigIntegerValue;
     }
 
-    private Date getAsDate() {
+    public Date getAsDate() {
         return new Date(winTimeToJava(bigIntegerValue).longValue());
     }
 
diff --git 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/types/AmsPort.java
 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/types/AmsPort.java
index 9346b9f..5ae3123 100644
--- 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/types/AmsPort.java
+++ 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/types/AmsPort.java
@@ -19,9 +19,8 @@
 package org.apache.plc4x.java.ads.api.generic.types;
 
 import io.netty.buffer.ByteBuf;
-import org.apache.plc4x.java.ads.api.util.ByteValue;
+import org.apache.plc4x.java.ads.api.util.UnsignedShortLEByteValue;
 
-import java.nio.ByteBuffer;
 import java.util.regex.Pattern;
 
 /**
@@ -30,15 +29,18 @@ import java.util.regex.Pattern;
  * @see <a 
href="https://infosys.beckhoff.com/content/1033/tcadscommon/html/tcadscommon_identadsdevice.htm?id=3991659524769593444";>ADS
 device identification</a>
  */
 @SuppressWarnings("unused") // Due to predefined ports
-public class AmsPort extends ByteValue {
+public class AmsPort extends UnsignedShortLEByteValue {
 
     public static final Pattern AMS_PORT_PATTERN = Pattern.compile("\\d+");
 
-    public static final int NUM_BYTES = 2;
+    public static final int NUM_BYTES = 
UnsignedShortLEByteValue.UNSIGNED_SHORT_LE_NUM_BYTES;
 
     private AmsPort(byte... value) {
         super(value);
-        assertLength(NUM_BYTES);
+    }
+
+    private AmsPort(int value) {
+        super(value);
     }
 
     public static AmsPort of(byte... values) {
@@ -46,12 +48,7 @@ public class AmsPort extends ByteValue {
     }
 
     public static AmsPort of(int port) {
-        checkUnsignedBounds(port, NUM_BYTES);
-        return new AmsPort(ByteBuffer.allocate(NUM_BYTES)
-            // LE
-            .put((byte) (port & 0xff))
-            .put((byte) (port >> 8 & 0xff))
-            .array());
+        return new AmsPort(port);
     }
 
     public static AmsPort of(String port) {
@@ -67,7 +64,7 @@ public class AmsPort extends ByteValue {
 
     @Override
     public String toString() {
-        return Integer.toString(getBytes()[1] << 8 | getBytes()[0] & 0xff);
+        return String.valueOf(getAsInt());
     }
 
     public static class ReservedPorts {
diff --git 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/types/Command.java
 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/types/Command.java
index 9a5a2a7..779a15e 100644
--- 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/types/Command.java
+++ 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/types/Command.java
@@ -24,6 +24,7 @@ import org.apache.plc4x.java.ads.api.util.ByteReadable;
 import org.apache.plc4x.java.ads.api.util.ByteValue;
 
 import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.util.Arrays;
 
 import static java.lang.Integer.toHexString;
@@ -60,9 +61,8 @@ public enum Command implements ByteReadable {
         ByteValue.checkUnsignedBounds(value, NUM_BYTES);
         this.intValue = value;
         this.value = ByteBuffer.allocate(NUM_BYTES)
-            // LE
-            .put((byte) (value & 0xff))
-            .put((byte) (value >> 8 & 0xff))
+            .order(ByteOrder.LITTLE_ENDIAN)
+            .putShort((short) (value & 0xffff))
             .array();
     }
 
diff --git 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/util/UnsignedIntLEByteValue.java
 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/util/UnsignedIntLEByteValue.java
index db477b9..1740c3e 100644
--- 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/util/UnsignedIntLEByteValue.java
+++ 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/util/UnsignedIntLEByteValue.java
@@ -21,6 +21,7 @@ package org.apache.plc4x.java.ads.api.util;
 import io.netty.buffer.ByteBuf;
 
 import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 
 import static java.lang.Long.toHexString;
 import static org.apache.commons.lang3.StringUtils.leftPad;
@@ -34,12 +35,13 @@ public abstract class UnsignedIntLEByteValue extends 
ByteValue {
     protected UnsignedIntLEByteValue(byte... value) {
         super(value);
         assertLength(UNSIGNED_INT_LE_NUM_BYTES);
-        longValue = getBytes()[3] << 24 | getBytes()[2] << 16 | getBytes()[1] 
<< 8 | getBytes()[0];
+        longValue = ByteBuffer.wrap(value)
+            .order(ByteOrder.LITTLE_ENDIAN)
+            .getInt();
     }
 
     protected UnsignedIntLEByteValue(long value) {
         super(ofLong(value));
-        checkUnsignedBounds(value, UNSIGNED_INT_LE_NUM_BYTES);
         longValue = value;
     }
 
@@ -52,12 +54,10 @@ public abstract class UnsignedIntLEByteValue extends 
ByteValue {
     }
 
     private static byte[] ofLong(long value) {
+        checkUnsignedBounds(value, UNSIGNED_INT_LE_NUM_BYTES);
         return ByteBuffer.allocate(UNSIGNED_INT_LE_NUM_BYTES)
-            // LE
-            .put((byte) (value & 0xff))
-            .put((byte) (value >> 8 & 0xff))
-            .put((byte) (value >> 16 & 0xff))
-            .put((byte) (value >> 24 & 0xff))
+            .order(ByteOrder.LITTLE_ENDIAN)
+            .putInt((int) (value & 0xffff_ffff))
             .array();
     }
 
diff --git 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/util/UnsignedShortLEByteValue.java
 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/util/UnsignedShortLEByteValue.java
index 9a43332..70b59f0 100644
--- 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/util/UnsignedShortLEByteValue.java
+++ 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/util/UnsignedShortLEByteValue.java
@@ -21,6 +21,7 @@ package org.apache.plc4x.java.ads.api.util;
 import io.netty.buffer.ByteBuf;
 
 import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 
 import static java.lang.Integer.toHexString;
 import static org.apache.commons.lang3.StringUtils.leftPad;
@@ -34,12 +35,13 @@ public abstract class UnsignedShortLEByteValue extends 
ByteValue {
     protected UnsignedShortLEByteValue(byte... value) {
         super(value);
         assertLength(UNSIGNED_SHORT_LE_NUM_BYTES);
-        intValue = getBytes()[1] << 8 | getBytes()[0] & 0xff;
+        intValue = ByteBuffer.wrap(value)
+            .order(ByteOrder.LITTLE_ENDIAN)
+            .getShort();
     }
 
     protected UnsignedShortLEByteValue(int value) {
         super(ofInt(value));
-        checkUnsignedBounds(value, UNSIGNED_SHORT_LE_NUM_BYTES);
         intValue = value;
     }
 
@@ -51,11 +53,11 @@ public abstract class UnsignedShortLEByteValue extends 
ByteValue {
         this(byteBuf.readUnsignedShortLE());
     }
 
-    private static byte[] ofInt(long value) {
+    private static byte[] ofInt(int value) {
+        checkUnsignedBounds(value, UNSIGNED_SHORT_LE_NUM_BYTES);
         return ByteBuffer.allocate(UNSIGNED_SHORT_LE_NUM_BYTES)
-            // LE
-            .put((byte) (value & 0xff))
-            .put((byte) (value >> 8 & 0xff))
+            .order(ByteOrder.LITTLE_ENDIAN)
+            .putShort((short) (value & 0xffff))
             .array();
     }
 
diff --git 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/connection/AdsSerialPlcConnection.java
 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/connection/AdsSerialPlcConnection.java
index 8b68e6e..f322847 100644
--- 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/connection/AdsSerialPlcConnection.java
+++ 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/connection/AdsSerialPlcConnection.java
@@ -56,9 +56,9 @@ public class AdsSerialPlcConnection extends 
AdsAbstractPlcConnection {
             protected void initChannel(Channel channel) {
                 // Build the protocol stack for communicating with the ads 
protocol.
                 ChannelPipeline pipeline = channel.pipeline();
-                pipeline.addLast(new Plc4x2AdsProtocol(targetAmsNetId, 
targetAmsPort, sourceAmsNetId, sourceAmsPort));
-                pipeline.addLast(new Ads2PayloadProtocol());
                 pipeline.addLast(new Payload2SerialProtocol());
+                pipeline.addLast(new Ads2PayloadProtocol());
+                pipeline.addLast(new Plc4x2AdsProtocol(targetAmsNetId, 
targetAmsPort, sourceAmsNetId, sourceAmsPort));
             }
         };
     }
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 0cfc43d..3b7633c 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
@@ -261,7 +261,8 @@ public class Ads2PayloadProtocol extends 
MessageToMessageCodec<ByteBuf, AmsPacke
             if (stamps.getAsLong() > Integer.MAX_VALUE) {
                 throw new IllegalStateException("Overflow in datalength: " + 
stamps.getAsLong());
             }
-            ByteBuf adsDeviceNotificationBuffer = 
commandBuffer.readBytes((int) length.getAsLong());
+            // Note: the length includes the 4 Bytes of stamps which we read 
already so we substract.
+            ByteBuf adsDeviceNotificationBuffer = 
commandBuffer.readBytes((int) length.getAsLong() - Stamps.NUM_BYTES);
             List<AdsStampHeader> adsStampHeaders = new ArrayList<>((int) 
stamps.getAsLong());
             for (int i = 1; i <= stamps.getAsLong(); i++) {
                 AdsStampHeader adsStampHeader = 
handleStampHeader(adsDeviceNotificationBuffer);
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 2f4ef45..c11c819 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
@@ -20,10 +20,7 @@ package org.apache.plc4x.java.ads.protocol;
 
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.MessageToMessageCodec;
-import org.apache.plc4x.java.ads.api.commands.AdsReadRequest;
-import org.apache.plc4x.java.ads.api.commands.AdsReadResponse;
-import org.apache.plc4x.java.ads.api.commands.AdsWriteRequest;
-import org.apache.plc4x.java.ads.api.commands.AdsWriteResponse;
+import org.apache.plc4x.java.ads.api.commands.*;
 import org.apache.plc4x.java.ads.api.commands.types.*;
 import org.apache.plc4x.java.ads.api.generic.AmsPacket;
 import org.apache.plc4x.java.ads.api.generic.types.AmsNetId;
@@ -49,10 +46,12 @@ import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
 import java.util.Collections;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.Consumer;
 
 import static 
org.apache.plc4x.java.ads.protocol.util.LittleEndianDecoder.decodeData;
 import static 
org.apache.plc4x.java.ads.protocol.util.LittleEndianEncoder.encodeData;
@@ -65,6 +64,8 @@ public class Plc4x2AdsProtocol extends 
MessageToMessageCodec<AmsPacket, PlcReque
 
     private final ConcurrentMap<Long, PlcRequestContainer<PlcRequest, 
PlcResponse>> requests;
 
+    private List<Consumer<AdsDeviceNotificationRequest>> 
deviceNotificationListeners;
+
     private final AmsNetId targetAmsNetId;
     private final AmsPort targetAmsPort;
     private final AmsNetId sourceAmsNetId;
@@ -76,6 +77,7 @@ public class Plc4x2AdsProtocol extends 
MessageToMessageCodec<AmsPacket, PlcReque
         this.sourceAmsNetId = sourceAmsNetId;
         this.sourceAmsPort = sourceAmsPort;
         this.requests = new ConcurrentHashMap<>();
+        this.deviceNotificationListeners = new LinkedList<>();
     }
 
     @Override
@@ -165,6 +167,11 @@ public class Plc4x2AdsProtocol extends 
MessageToMessageCodec<AmsPacket, PlcReque
 
     @Override
     protected void decode(ChannelHandlerContext channelHandlerContext, 
AmsPacket amsPacket, List<Object> out) throws Exception {
+        if (amsPacket instanceof AdsDeviceNotificationRequest) {
+            LOGGER.debug("Received notification {}", amsPacket);
+            handleAdsDeviceNotificationRequest((AdsDeviceNotificationRequest) 
amsPacket);
+            return;
+        }
         PlcRequestContainer<PlcRequest, PlcResponse> plcRequestContainer = 
requests.remove(amsPacket.getAmsHeader().getInvokeId().getAsLong());
         if (plcRequestContainer == null) {
             LOGGER.info("Unmapped packet received {}", amsPacket);
@@ -196,6 +203,25 @@ public class Plc4x2AdsProtocol extends 
MessageToMessageCodec<AmsPacket, PlcReque
         }
     }
 
+    private void 
handleAdsDeviceNotificationRequest(AdsDeviceNotificationRequest 
adsDeviceNotificationRequest) {
+        for (Consumer<AdsDeviceNotificationRequest> deviceNotificationListener 
: deviceNotificationListeners) {
+            try {
+                
deviceNotificationListener.accept(adsDeviceNotificationRequest);
+            } catch (RuntimeException e) {
+                LOGGER.error("Exception received from {} while handling {}", 
deviceNotificationListener, adsDeviceNotificationRequest, e);
+            }
+        }
+    }
+
+    public boolean addConsumer(Consumer<AdsDeviceNotificationRequest> 
adsDeviceNotificationRequestConsumer) {
+        return 
deviceNotificationListeners.add(adsDeviceNotificationRequestConsumer);
+    }
+
+    public boolean removeConsumer(Consumer<AdsDeviceNotificationRequest> 
adsDeviceNotificationRequestConsumer) {
+        return 
deviceNotificationListeners.remove(adsDeviceNotificationRequestConsumer);
+    }
+
+
     @SuppressWarnings("unchecked")
     private PlcResponse decodeWriteResponse(AdsWriteResponse responseMessage, 
PlcRequestContainer<PlcRequest, PlcResponse> requestContainer) {
         PlcWriteRequest plcWriteRequest = (PlcWriteRequest) 
requestContainer.getRequest();
diff --git 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/util/LittleEndianDecoder.java
 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/util/LittleEndianDecoder.java
index 3362b15..8394cdf 100644
--- 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/util/LittleEndianDecoder.java
+++ 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/util/LittleEndianDecoder.java
@@ -27,6 +27,7 @@ import java.util.Date;
 import java.util.LinkedList;
 import java.util.List;
 
+// TODO: we might user 
ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).putInt(port).asArray() 
etc
 public class LittleEndianDecoder {
 
     private LittleEndianDecoder() {
@@ -49,7 +50,7 @@ public class LittleEndianDecoder {
             } else if (datatype == Byte.class) {
                 result.add(byteOne);
                 i += 1;
-            } else  if (datatype == Short.class) {
+            } else if (datatype == Short.class) {
                 decodeShort(adsData, i, result);
                 i += 2;
             } else if (datatype == Integer.class) {
@@ -82,7 +83,7 @@ public class LittleEndianDecoder {
 
     private static void decodeShort(byte[] adsData, int i, List<Object> 
result) {
         byte byteOne = adsData[i];
-        byte byteTwo = adsData[i+1];
+        byte byteTwo = adsData[i + 1];
         result.add((short) ((byteOne & 0xff) | ((byteTwo & 0xff) << 8)));
     }
 
diff --git 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/util/LittleEndianEncoder.java
 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/util/LittleEndianEncoder.java
index f196e2e..7ee8cbe 100644
--- 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/util/LittleEndianEncoder.java
+++ 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/util/LittleEndianEncoder.java
@@ -32,6 +32,7 @@ import java.util.Calendar;
 import java.util.Date;
 import java.util.stream.Stream;
 
+// TODO: we might user 
ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).putInt(port).asArray() 
etc
 public class LittleEndianEncoder {
 
     private LittleEndianEncoder() {

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

Reply via email to