This is an automated email from the ASF dual-hosted git repository.
sruehl pushed a commit to branch feature/Beckhoff_ADS_protocol
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git
The following commit(s) were added to refs/heads/feature/Beckhoff_ADS_protocol
by this push:
new 1833df7 + continued on plc protocol layer + added readable error
codes from specification.
1833df7 is described below
commit 1833df73d4b59da430b2bfe27f956b262f92460d
Author: Sebastian Rühl <[email protected]>
AuthorDate: Wed Feb 7 22:42:59 2018 +0100
+ continued on plc protocol layer
+ added readable error codes from specification.
---
.../java/ads/api/commands/ADSReadResponse.java | 11 ++
.../java/ads/api/commands/ADSWriteResponse.java | 3 +
.../java/ads/api/commands/types/AdsReturnCode.java | 199 +++++++++++++++++++++
.../plc4x/java/ads/api/commands/types/Result.java | 9 +
.../plc4x/java/ads/api/generic/AMSTCPPaket.java | 6 +-
.../generic/calculated/CalculatedAMSTCPHeader.java | 2 +-
.../plc4x/java/ads/api/generic/types/AMSError.java | 10 ++
.../plc4x/java/ads/api/util/ByteReadable.java | 2 +-
.../plc4x/java/ads/api/util/LengthSupplier.java | 2 +-
.../apache/plc4x/java/ads/netty/ADSProtocol.java | 16 +-
.../plc4x/java/ads/netty/Plc4XADSProtocol.java | 106 ++++++++---
11 files changed, 334 insertions(+), 32 deletions(-)
diff --git
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/ADSReadResponse.java
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/ADSReadResponse.java
index 7bc9b2a..479d48e 100644
---
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/ADSReadResponse.java
+++
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/ADSReadResponse.java
@@ -58,4 +58,15 @@ public class ADSReadResponse extends AMSTCPPaket {
return buildADSData(result, length, data);
}
+ public Result getResult() {
+ return result;
+ }
+
+ public Length getLength() {
+ return length;
+ }
+
+ public Data getData() {
+ return data;
+ }
}
diff --git
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/ADSWriteResponse.java
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/ADSWriteResponse.java
index a9c4188..97a5f90 100644
---
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/ADSWriteResponse.java
+++
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/ADSWriteResponse.java
@@ -46,4 +46,7 @@ public class ADSWriteResponse extends AMSTCPPaket {
return buildADSData(result);
}
+ public Result getResult() {
+ return result;
+ }
}
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
new file mode 100644
index 0000000..0809d66
--- /dev/null
+++
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/types/AdsReturnCode.java
@@ -0,0 +1,199 @@
+/*
+ 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.ads.api.commands.types;
+
+/**
+ * Based on spec from:
https://infosys.beckhoff.com/content/1033/tcadscommon/html/ads_returncodes.htm
+ */
+// TODO: give the codes useful names
+// Error codes: 0x000..., 0x500..., 0x700..., 0x1000..., 0x274C...
+public enum AdsReturnCode {
+ // Global Error Codes
+ ADS_CODE_0(0x0, 0, "no error", "", ""),
+ ADS_CODE_1(0x1, 1, "Internal error", "", ""),
+ ADS_CODE_2(0x2, 2, "No Rtime", "", ""),
+ 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_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", "", ""),
+ ADS_CODE_10(0xA, 10, "No IO", "", ""),
+ ADS_CODE_11(0xB, 11, "Unknown ADS command", "", ""),
+ ADS_CODE_12(0xC, 12, "Win 32 error", "", ""),
+ ADS_CODE_13(0xD, 13, "Port not connected", "", ""),
+ ADS_CODE_14(0xE, 14, "Invalid ADS length", "", ""),
+ ADS_CODE_15(0xF, 15, "Invalid ADS Net ID", "", ""),
+ ADS_CODE_16(0x10, 16, "Low Installation level", "", ""),
+ ADS_CODE_17(0x11, 17, "No debug available", "", ""),
+ ADS_CODE_18(0x12, 18, "Port disabled", "", ""),
+ ADS_CODE_19(0x13, 19, "Port already connected", "", ""),
+ ADS_CODE_20(0x14, 20, "ADS Sync Win32 error", "", ""),
+ ADS_CODE_21(0x15, 21, "ADS Sync Timeout", "", ""),
+ ADS_CODE_22(0x16, 22, "ADS Sync AMS error", "", ""),
+ ADS_CODE_23(0x17, 23, "ADS Sync no index map", "", ""),
+ ADS_CODE_24(0x18, 24, "Invalid ADS port", "", ""),
+ ADS_CODE_25(0x19, 25, "No memory", "", ""),
+ ADS_CODE_26(0x1A, 26, "TCP send error", "", ""),
+ ADS_CODE_27(0x1B, 27, "Host unreachable", "", ""),
+ ADS_CODE_28(0x1C, 28, "Invalid AMS fragment", "", ""),
+
+
+ // Router Error Codes
+ ADS_CODE_1280(0x500, 1280, "ROUTERERR_NOLOCKEDMEMORY", "No locked memory
can be allocated", ""),
+ ADS_CODE_1281(0x501, 1281, "ROUTERERR_RESIZEMEMORY", "The size of the
router memory could not be changed", ""),
+ ADS_CODE_1282(0x502, 1282, "ROUTERERR_MAILBOXFULL", "The mailbox has
reached the maximum number of possible messages. The current sent message was
rejected", "Check the connection between the communication partners"),
+ ADS_CODE_1283(0x503, 1283, "ROUTERERR_DEBUGBOXFULL ", "The mailbox has
reached the maximum number of possible messages.The sent message will not be
displayed in the debug monitor", "Check the connection to the debug monitor"),
+ ADS_CODE_1284(0x504, 1284, "ROUTERERR_UNKNOWNPORTTYPE ", "The port type is
unknown", ""),
+ ADS_CODE_1285(0x505, 1285, "ROUTERERR_NOTINITIALIZED", "Router is not
initialised", ""),
+ ADS_CODE_1286(0x506, 1286, "ROUTERERR_PORTALREADYINUSE ", "The desired
port number is already assigned", ""),
+ ADS_CODE_1287(0x507, 1287, "ROUTERERR_NOTREGISTERED ", "Port not
registered", ""),
+ ADS_CODE_1288(0x508, 1288, "ROUTERERR_NOMOREQUEUES", "The maximum number
of Ports reached", ""),
+ ADS_CODE_1289(0x509, 1289, "ROUTERERR_INVALIDPORT ", "The port is
invalid.", ""),
+ ADS_CODE_1290(0x50A, 1290, "ROUTERERR_NOTACTIVATED ", "TwinCAT Router not
active", ""),
+ ADS_CODE_1291(0x50B, 1291, "ROUTERERR_FRAGMENTBOXFULL", "", ""),
+ ADS_CODE_1292(0x50C, 1292, "ROUTERERR_FRAGMENTTIMEOUT", "", ""),
+ ADS_CODE_1293(0x50D, 1293, "ROUTERERR_TOBEREMOVED", "", ""),
+
+
+ // General ADS Error Codes
+ ADS_CODE_1792(0x700, 1792, "error class <device error>", "", ""),
+ ADS_CODE_1793(0x701, 1793, "Service is not supported by server", "", ""),
+ ADS_CODE_1794(0x702, 1794, "invalid index group", "", ""),
+ ADS_CODE_1795(0x703, 1795, "invalid index offset", "", ""),
+ ADS_CODE_1796(0x704, 1796, "reading/writing not permitted", "", ""),
+ ADS_CODE_1797(0x705, 1797, "parameter size not correct", "", ""),
+ ADS_CODE_1798(0x706, 1798, "invalid parameter value(s)", "", ""),
+ ADS_CODE_1799(0x707, 1799, "device is not in a ready state", "", ""),
+ ADS_CODE_1800(0x708, 1800, "device is busy", "", ""),
+ ADS_CODE_1801(0x709, 1801, "invalid context (must be in Windows)", "", ""),
+ ADS_CODE_1802(0x70A, 1802, "out of memory", "", ""),
+ ADS_CODE_1803(0x70B, 1803, "invalid parameter value(s)", "", ""),
+ ADS_CODE_1804(0x70C, 1804, "not found (files, ...)", "", ""),
+ ADS_CODE_1805(0x70D, 1805, "syntax error in command or file", "", ""),
+ ADS_CODE_1806(0x70E, 1806, "objects do not match", "", ""),
+ ADS_CODE_1807(0x70F, 1807, "object already exists", "", ""),
+ ADS_CODE_1808(0x710, 1808, "symbol not found", "", ""),
+ ADS_CODE_1809(0x711, 1809, "symbol version invalid", "Onlinechange",
"Release handle and get a new one"),
+ ADS_CODE_1810(0x712, 1810, "server is in invalid state", "", ""),
+ ADS_CODE_1811(0x713, 1811, "AdsTransMode not supported", "", ""),
+ ADS_CODE_1812(0x714, 1812, "Notification handle is invalid",
"Onlinechange", "Release handle and get a new one"),
+ ADS_CODE_1813(0x715, 1813, "Notification client not registered", "", ""),
+ ADS_CODE_1814(0x716, 1814, "no more notification handles", "", ""),
+ ADS_CODE_1815(0x717, 1815, "size for watch too big", "", ""),
+ ADS_CODE_1816(0x718, 1816, "device not initialized", "", ""),
+ ADS_CODE_1817(0x719, 1817, "device has a timeout", "", ""),
+ ADS_CODE_1818(0x71A, 1818, "query interface failed", "", ""),
+ ADS_CODE_1819(0x71B, 1819, "wrong interface required", "", ""),
+ ADS_CODE_1820(0x71C, 1820, "class ID is invalid", "", ""),
+ ADS_CODE_1821(0x71D, 1821, "object ID is invalid", "", ""),
+ ADS_CODE_1822(0x71E, 1822, "request is pending", "", ""),
+ ADS_CODE_1823(0x71F, 1823, "request is aborted", "", ""),
+ ADS_CODE_1824(0x720, 1824, "signal warning", "", ""),
+ ADS_CODE_1825(0x721, 1825, "invalid array index", "", ""),
+ ADS_CODE_1826(0x722, 1826, "symbol not active", "Onlinechange", "Release
handle and get a new one"),
+ ADS_CODE_1827(0x723, 1827, "access denied", "", ""),
+ ADS_CODE_1828(0x724, 1828, "missing license ", "", "Activate license for
TwinCAT 3 function"),
+ ADS_CODE_1836(0x72c, 1836, "exception occured during system start", "",
"Check each device transistions"),
+ ADS_CODE_1856(0x740, 1856, "Error class <client error>", "", ""),
+ ADS_CODE_1857(0x741, 1857, "invalid parameter at service", "", ""),
+ ADS_CODE_1858(0x742, 1858, "polling list is empty", "", ""),
+ ADS_CODE_1859(0x743, 1859, "var connection already in use", "", ""),
+ ADS_CODE_1860(0x744, 1860, "invoke ID in use", "", ""),
+ ADS_CODE_1861(0x745, 1861, "timeout elapsedCheck ADS routes of sender and
receiver and your firewall setting", "", ""),
+ ADS_CODE_1862(0x746, 1862, "error in win32 subsystem", "", ""),
+ ADS_CODE_1863(0x747, 1863, "Invalid client timeout value", "", ""),
+ ADS_CODE_1864(0x748, 1864, "ads-port not opened", "", ""),
+ ADS_CODE_1872(0x750, 1872, "internal error in ads sync", "", ""),
+ ADS_CODE_1873(0x751, 1873, "hash table overflow", "", ""),
+ ADS_CODE_1874(0x752, 1874, "key not found in hash", "", ""),
+ ADS_CODE_1875(0x753, 1875, "no more symbols in cache", "", ""),
+ ADS_CODE_1876(0x754, 1876, "invalid response received", "", ""),
+ ADS_CODE_1877(0x755, 1877, "sync port is locked", "", ""),
+
+
+ // RTime Error Codes
+ ADS_CODE_4096(0x1000, 4096, "RTERR_INTERNAL ", "Internal fatal error in
the TwinCAT real-time system", ""),
+ ADS_CODE_4097(0x1001, 4097, "RTERR_BADTIMERPERIODS", "Timer value not
vaild", ""),
+ ADS_CODE_4098(0x1002, 4098, "RTERR_INVALIDTASKPTR", "Task pointer has the
invalid value ZERO", ""),
+ ADS_CODE_4099(0x1003, 4099, "RTERR_INVALIDSTACKPTR", "Task stack pointer
has the invalid value ZERO", ""),
+ ADS_CODE_4100(0x1004, 4100, "RTERR_PRIOEXISTS", "The demand task priority
is already assigned", ""),
+ ADS_CODE_4101(0x1005, 4101, "RTERR_NOMORETCB", "No more free TCB (Task
Control Block) available. Maximum number of TCBs is 64", ""),
+ ADS_CODE_4102(0x1006, 4102, "RTERR_NOMORESEMAS", "No more free semaphores
available. Maximum number of semaphores is 64", ""),
+ ADS_CODE_4103(0x1007, 4103, "RTERR_NOMOREQUEUES", "No more free queue
available. Maximum number of queue is 64", ""),
+ ADS_CODE_4104(0x1008, 4104, "TwinCAT ", "reserved.", ""),
+ ADS_CODE_4105(0x1009, 4105, "TwinCAT ", "reserved.", ""),
+ ADS_CODE_4106(0x100A, 4106, "TwinCAT ", "reserved.", ""),
+ ADS_CODE_4107(0x100B, 4107, "TwinCAT ", "reserved.", ""),
+ ADS_CODE_4108(0x100C, 4108, "TwinCAT ", "reserved.", ""),
+ ADS_CODE_4109(0x100D, 4109, "RTERR_EXTIRQALREADYDEF", "An external
synchronisation interrupt is already applied", ""),
+ ADS_CODE_4110(0x100E, 4110, "RTERR_EXTIRQNOTDEF", "No external
synchronsiation interrupt applied", ""),
+ ADS_CODE_4111(0x100F, 4111, "RTERR_EXTIRQINSTALLFAILED", "The apply of the
external synchronisation interrupt failed", ""),
+ ADS_CODE_4112(0x1010, 4112, "RTERR_IRQLNOTLESSOREQUAL", "Call of a service
function in the wrong context", ""),
+ ADS_CODE_4119(0x1017, 4119, "RTERR_VMXNOTSUPPORTED", "Intel VT-x extension
is not supported.", ""),
+ ADS_CODE_4120(0x1018, 4120, "RTERR_VMXDISABLED", "Intel VT-x extension is
not enabled in BIOS.", ""),
+ ADS_CODE_4121(0x1019, 4121, "RTERR_VMXCONTROLSMISSING", "Missing feature
in Intel VT-x extension.", ""),
+ ADS_CODE_4122(0x101A, 4122, "RTERR_VMXENABLEFAILS", "Enabling Intel VT-x
fails.", ""),
+
+
+ // TCP Winsock Error Codes
+ ADS_CODE_10060(0x274c, 10060, "A socket operation was attempted to an
unreachable host", "Host unreachable", "Check network connection via ping"),
+ ADS_CODE_10061(0x274d, 10061, "A connection attempt failed because the
connected party did not properly respond after a period of time,or established
connection failed because connected host has failed to respond.", "Host
unreachable", "Check network connection via ping"),
+ ADS_CODE_10065(0x2751, 10065, "No connection could be made because the
target machine actively refused it", "", ""),
+ UNKNOWN(0, 0, "", "", "");
+
+ long hex;
+ long dec;
+ String description;
+ String possibleCauses;
+ String solution;
+
+ AdsReturnCode(long hex, long dec, String description, String
possibleCauses, String solution) {
+ this.hex = hex;
+ this.dec = dec;
+ if (hex != dec) {
+ throw new IllegalArgumentException("hex " + hex + " is different
from dec " + dec);
+ }
+ this.description = description;
+ this.possibleCauses = possibleCauses;
+ this.solution = solution;
+ }
+
+ // TODO: optimize with map
+ public static AdsReturnCode of(long hex) {
+ for (AdsReturnCode adsReturnCode : values()) {
+ if (adsReturnCode.hex == hex) {
+ return adsReturnCode;
+ }
+ }
+ return UNKNOWN;
+ }
+
+ @Override
+ public String toString() {
+ return "AdsReturnCode{\n" +
+ "hex=" + hex +
+ ",\n dec=" + dec +
+ ",\n description='" + description + '\'' +
+ ",\n possibleCauses='" + possibleCauses + '\'' +
+ ",\n solution='" + solution + '\'' +
+ '}';
+ }
+}
diff --git
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/types/Result.java
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/types/Result.java
index 402bca5..5a3dd68 100644
---
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/types/Result.java
+++
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/commands/types/Result.java
@@ -49,4 +49,13 @@ public class Result extends UnsignedIntLEByteValue {
public static Result of(ByteBuf byteBuf) {
return new Result(byteBuf);
}
+
+ public AdsReturnCode toAdsReturnCode() {
+ return AdsReturnCode.of(getAsLong());
+ }
+
+ @Override
+ public String toString() {
+ return "Result{" + toAdsReturnCode() + "}";
+ }
}
diff --git
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/AMSTCPPaket.java
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/AMSTCPPaket.java
index 933e4af..85ba515 100644
---
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/AMSTCPPaket.java
+++
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/AMSTCPPaket.java
@@ -40,7 +40,7 @@ public abstract class AMSTCPPaket implements ByteReadable {
public AMSTCPPaket(AMSHeader amsHeader) {
// It is important that we wrap the ads data call as this will
initialized in the constructor
// so this value will be null if we call adsData now.
- this.amstcpHeader = CalculatedAMSTCPHeader.of(amsHeader, () ->
getAdsData().getLength());
+ this.amstcpHeader = CalculatedAMSTCPHeader.of(amsHeader, () ->
getAdsData().getCalculatedLength());
this.amsHeader = amsHeader;
}
@@ -55,9 +55,9 @@ public abstract class AMSTCPPaket implements ByteReadable {
sourceAmsPort,
getClass().getAnnotation(ADSCommandType.class).value(),
State.DEFAULT,
- () -> DataLength.of(getAdsData().getLength()),
+ () -> DataLength.of(getAdsData().getCalculatedLength()),
invokeId);
- this.amstcpHeader = CalculatedAMSTCPHeader.of(amsHeader, () ->
getAdsData().getLength());
+ this.amstcpHeader = CalculatedAMSTCPHeader.of(amsHeader, () ->
getAdsData().getCalculatedLength());
}
public AMSTCPHeader getAmstcpHeader() {
diff --git
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/calculated/CalculatedAMSTCPHeader.java
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/calculated/CalculatedAMSTCPHeader.java
index ddbf615..94c033b 100644
---
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/calculated/CalculatedAMSTCPHeader.java
+++
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/calculated/CalculatedAMSTCPHeader.java
@@ -46,7 +46,7 @@ public class CalculatedAMSTCPHeader extends AMSTCPHeader {
public ByteBuf getByteBuf() {
long aggregateLength = 0;
for (LengthSupplier supplier : lengthSupplier) {
- aggregateLength += supplier.getLength();
+ aggregateLength += supplier.getCalculatedLength();
}
return buildByteBuff(reserved, Length.of(aggregateLength));
}
diff --git
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/types/AMSError.java
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/types/AMSError.java
index 672b34e..d829933 100644
---
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/types/AMSError.java
+++
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/generic/types/AMSError.java
@@ -19,6 +19,7 @@
package org.apache.plc4x.java.ads.api.generic.types;
import io.netty.buffer.ByteBuf;
+import org.apache.plc4x.java.ads.api.commands.types.AdsReturnCode;
import org.apache.plc4x.java.ads.api.util.UnsignedIntLEByteValue;
public class AMSError extends UnsignedIntLEByteValue {
@@ -51,4 +52,13 @@ public class AMSError extends UnsignedIntLEByteValue {
public static AMSError of(ByteBuf byteBuf) {
return new AMSError(byteBuf);
}
+
+ public AdsReturnCode toAdsReturnCode() {
+ return AdsReturnCode.of(getAsLong());
+ }
+
+ @Override
+ public String toString() {
+ return "AMSError{" + toAdsReturnCode() + "}";
+ }
}
diff --git
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/util/ByteReadable.java
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/util/ByteReadable.java
index 39e08aa..9c3bd97 100644
---
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/util/ByteReadable.java
+++
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/util/ByteReadable.java
@@ -29,7 +29,7 @@ public interface ByteReadable extends LengthSupplier {
ByteBuf getByteBuf();
- default long getLength() {
+ default long getCalculatedLength() {
return getBytes().length;
}
diff --git
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/util/LengthSupplier.java
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/util/LengthSupplier.java
index 3401054..082d017 100644
---
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/util/LengthSupplier.java
+++
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/api/util/LengthSupplier.java
@@ -21,5 +21,5 @@ package org.apache.plc4x.java.ads.api.util;
@FunctionalInterface
public interface LengthSupplier {
- long getLength();
+ long getCalculatedLength();
}
diff --git
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/netty/ADSProtocol.java
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/netty/ADSProtocol.java
index f7d8ac8..c98ce36 100644
---
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/netty/ADSProtocol.java
+++
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/netty/ADSProtocol.java
@@ -31,16 +31,20 @@ import org.apache.plc4x.java.ads.api.generic.types.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
public class ADSProtocol extends MessageToMessageCodec<ByteBuf, AMSTCPPaket> {
private static final Logger LOGGER =
LoggerFactory.getLogger(ADSProtocol.class);
- private Map<Invoke, AMSTCPPaket> requests;
+ private ConcurrentMap<Invoke, AMSTCPPaket> requests;
public ADSProtocol() {
- this.requests = new HashMap<>();
+ this.requests = new ConcurrentHashMap<>();
}
@Override
@@ -68,8 +72,10 @@ public class ADSProtocol extends
MessageToMessageCodec<ByteBuf, AMSTCPPaket> {
DataLength dataLength = DataLength.of(byteBuf);
AMSError errorCode = AMSError.of(byteBuf);
Invoke invoke = Invoke.of(byteBuf);
- AMSTCPPaket correlatedAmstcpPacket = requests.get(invoke);
- LOGGER.debug("Correlated packet received {}", correlatedAmstcpPacket);
+ AMSTCPPaket correlatedAmstcpPacket = requests.remove(invoke);
+ if (correlatedAmstcpPacket != null) {
+ LOGGER.debug("Correlated packet received {}",
correlatedAmstcpPacket);
+ }
if (dataLength.getAsLong() > Integer.MAX_VALUE) {
throw new IllegalStateException("Overflow in datalength: " +
dataLength.getAsLong());
}
diff --git
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/netty/Plc4XADSProtocol.java
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/netty/Plc4XADSProtocol.java
index 192af39..9430e91 100644
---
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/netty/Plc4XADSProtocol.java
+++
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/netty/Plc4XADSProtocol.java
@@ -24,10 +24,7 @@ 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.types.Data;
-import org.apache.plc4x.java.ads.api.commands.types.IndexGroup;
-import org.apache.plc4x.java.ads.api.commands.types.IndexOffset;
-import org.apache.plc4x.java.ads.api.commands.types.Length;
+import org.apache.plc4x.java.ads.api.commands.types.*;
import org.apache.plc4x.java.ads.api.generic.AMSTCPPaket;
import org.apache.plc4x.java.ads.api.generic.types.AMSNetId;
import org.apache.plc4x.java.ads.api.generic.types.AMSPort;
@@ -35,24 +32,33 @@ import org.apache.plc4x.java.ads.api.generic.types.Invoke;
import org.apache.plc4x.java.ads.model.ADSAddress;
import org.apache.plc4x.java.api.exceptions.PlcException;
import org.apache.plc4x.java.api.exceptions.PlcProtocolException;
-import org.apache.plc4x.java.api.messages.PlcReadRequest;
-import org.apache.plc4x.java.api.messages.PlcRequest;
-import org.apache.plc4x.java.api.messages.PlcRequestContainer;
-import org.apache.plc4x.java.api.messages.PlcWriteRequest;
+import org.apache.plc4x.java.api.messages.*;
import org.apache.plc4x.java.api.messages.items.ReadRequestItem;
+import org.apache.plc4x.java.api.messages.items.ReadResponseItem;
import org.apache.plc4x.java.api.messages.items.WriteRequestItem;
+import org.apache.plc4x.java.api.messages.items.WriteResponseItem;
+import org.apache.plc4x.java.api.messages.specific.TypeSafePlcReadRequest;
+import org.apache.plc4x.java.api.messages.specific.TypeSafePlcReadResponse;
+import org.apache.plc4x.java.api.messages.specific.TypeSafePlcWriteRequest;
+import org.apache.plc4x.java.api.messages.specific.TypeSafePlcWriteResponse;
import org.apache.plc4x.java.api.model.Address;
+import org.apache.plc4x.java.api.types.ResponseCode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import java.util.HashMap;
+import java.util.Collections;
import java.util.List;
-import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
public class Plc4XADSProtocol extends MessageToMessageCodec<AMSTCPPaket,
PlcRequestContainer> {
+ private static final Logger LOGGER =
LoggerFactory.getLogger(Plc4XADSProtocol.class);
+
private static final AtomicLong correlationBuilder = new AtomicLong(1);
- private Map<Short, PlcRequestContainer> requests;
+ private ConcurrentMap<Long, PlcRequestContainer<PlcRequest, PlcResponse>>
requests;
private final AMSNetId targetAmsNetId;
private final AMSPort targetAmsPort;
@@ -64,7 +70,7 @@ public class Plc4XADSProtocol extends
MessageToMessageCodec<AMSTCPPaket, PlcRequ
this.targetAmsPort = targetAmsPort;
this.sourceAmsNetId = sourceAmsNetId;
this.sourceAmsPort = sourceAmsPort;
- this.requests = new HashMap<>();
+ this.requests = new ConcurrentHashMap<>();
}
@Override
@@ -77,14 +83,6 @@ public class Plc4XADSProtocol extends
MessageToMessageCodec<AMSTCPPaket, PlcRequ
}
}
- @Override
- protected void decode(ChannelHandlerContext channelHandlerContext,
AMSTCPPaket amstcpPaket, List<Object> out) throws Exception {
- if (amstcpPaket instanceof ADSReadResponse) {
- // TODO: implement me
- } else if (amstcpPaket instanceof ADSWriteResponse) {
- // TODO: implement me
- }
- }
private void encodeWriteRequest(PlcRequestContainer msg, List<Object> out)
throws PlcException {
PlcWriteRequest writeRequest = (PlcWriteRequest) msg.getRequest();
@@ -100,7 +98,7 @@ public class Plc4XADSProtocol extends
MessageToMessageCodec<AMSTCPPaket, PlcRequ
Invoke invokeId = Invoke.of(correlationBuilder.incrementAndGet());
IndexGroup indexGroup = IndexGroup.of(adsAddress.getIndexGroup());
IndexOffset indexOffset = IndexOffset.of(adsAddress.getIndexOffset());
- // TODO: how to get length and data. Serialization of plc is the
problem here
+ // TODO: implement serialization
Length length = Length.of(1);
Data data = Data.of(new byte[]{0x42});
AMSTCPPaket amstcpPaket = new ADSWriteRequest(targetAmsNetId,
targetAmsPort, sourceAmsNetId, sourceAmsPort, invokeId, indexGroup,
indexOffset, length, data);
@@ -127,4 +125,70 @@ public class Plc4XADSProtocol extends
MessageToMessageCodec<AMSTCPPaket, PlcRequ
out.add(amstcpPaket);
}
+ @Override
+ protected void decode(ChannelHandlerContext channelHandlerContext,
AMSTCPPaket amstcpPaket, List<Object> out) throws Exception {
+ PlcRequestContainer<PlcRequest, PlcResponse> plcRequestContainer =
requests.remove(amstcpPaket.getAmsHeader().getInvokeId().getAsLong());
+ if (plcRequestContainer == null) {
+ LOGGER.info("Unmapped packet received {}", amstcpPaket);
+ return;
+ }
+ PlcRequest request = plcRequestContainer.getRequest();
+ PlcResponse response = null;
+
+ // Handle the response to a read request.
+ if (request instanceof PlcReadRequest) {
+ if (amstcpPaket instanceof ADSReadResponse) {
+ response = decodeReadResponse((ADSReadResponse) amstcpPaket,
plcRequestContainer);
+ } else {
+ throw new PlcProtocolException("Wrong type correlated " +
amstcpPaket);
+ }
+ } else if (request instanceof PlcWriteRequest) {
+ if (amstcpPaket instanceof ADSWriteResponse) {
+ response = decodeWriteResponse((ADSWriteResponse) amstcpPaket,
plcRequestContainer);
+ } else {
+ throw new PlcProtocolException("Wrong type correlated " +
amstcpPaket);
+ }
+ }
+
+ // Confirm the response being handled.
+ if (response != null) {
+ plcRequestContainer.getResponseFuture().complete(response);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private PlcResponse decodeWriteResponse(ADSWriteResponse responseMessage,
PlcRequestContainer<PlcRequest, PlcResponse> requestContainer) throws
PlcProtocolException {
+ PlcWriteRequest plcWriteRequest = (PlcWriteRequest)
requestContainer.getRequest();
+ WriteRequestItem requestItem =
plcWriteRequest.getRequestItems().get(0);
+
+ ResponseCode responseCode =
decodeResponseCode(responseMessage.getResult());
+
+ if (plcWriteRequest instanceof TypeSafePlcWriteRequest) {
+ return new TypeSafePlcWriteResponse((TypeSafePlcWriteRequest)
plcWriteRequest, Collections.singletonList(new WriteResponseItem<>(requestItem,
responseCode)));
+ } else {
+ return new PlcWriteResponse(plcWriteRequest,
Collections.singletonList(new WriteResponseItem<>(requestItem, responseCode)));
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private PlcResponse decodeReadResponse(ADSReadResponse responseMessage,
PlcRequestContainer<PlcRequest, PlcResponse> requestContainer) throws
PlcProtocolException {
+ PlcReadRequest plcReadRequest = (PlcReadRequest)
requestContainer.getRequest();
+ ReadRequestItem requestItem = plcReadRequest.getRequestItems().get(0);
+
+ ResponseCode responseCode =
decodeResponseCode(responseMessage.getResult());
+ byte[] bytes = responseMessage.getData().getBytes();
+
+ // TODO: implement deserialization
+ if (plcReadRequest instanceof TypeSafePlcReadRequest) {
+ return new TypeSafePlcReadResponse((TypeSafePlcReadRequest)
plcReadRequest, Collections.singletonList(new ReadResponseItem<>(requestItem,
responseCode, Collections.singletonList(bytes))));
+ } else {
+ return new PlcReadResponse(plcReadRequest,
Collections.singletonList(new ReadResponseItem<>(requestItem, responseCode,
Collections.singletonList(bytes))));
+ }
+ }
+
+ private ResponseCode decodeResponseCode(Result result) {
+ // TODO: complete mapping
+ return result.getAsLong() == 0 ? ResponseCode.OK :
ResponseCode.INTERNAL_ERROR;
+ }
+
}
--
To stop receiving notification emails like this one, please contact
[email protected].