You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by ld...@apache.org on 2021/08/25 09:49:49 UTC

[plc4x] 01/01: PLC4X-311 Handling of compact answers for read requests.

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

ldywicki pushed a commit to branch issue/PLC4X-311
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit b51282360097a0171ffe937631d6370a70a8e6f0
Author: Ɓukasz Dywicki <lu...@code-house.org>
AuthorDate: Wed Aug 25 11:48:45 2021 +0200

    PLC4X-311 Handling of compact answers for read requests.
---
 .../plc4x/java/ads/protocol/AdsProtocolLogic.java  |  31 +++--
 .../ads/src/main/resources/protocols/ads/ads.mspec |  30 +++--
 .../resources/protocols/ads/DriverTestsuite.xml    | 134 ++++++++++++---------
 .../protocols/ads/ParserSerializerTestsuite.xml    |  40 +++---
 4 files changed, 147 insertions(+), 88 deletions(-)

diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java
index ba52724..0ff5511 100644
--- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java
+++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java
@@ -196,14 +196,21 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
             .onError((p, e) -> future.completeExceptionally(e))
             .check(responseAmsPacket -> responseAmsPacket.getUserdata().getInvokeId() == amsPacket.getInvokeId())
             .unwrap(response -> (AdsReadResponse) response.getUserdata().getData())
-            .handle(responseAdsData -> {
-                if (responseAdsData.getResult() == ReturnCode.OK) {
-                    final PlcReadResponse plcReadResponse = convertToPlc4xReadResponse(readRequest, responseAdsData);
-                    // Convert the response from the PLC into a PLC4X Response ...
+            .handle(readResponse -> {
+                AdsResponseData payload = readResponse.getPayload();
+                if (payload instanceof AdsReadFullResponse) {
+                    AdsReadFullResponse responseAdsData = (AdsReadFullResponse) payload;
+                    if (responseAdsData.getResult() == ReturnCode.OK) {
+                        final PlcReadResponse plcReadResponse = convertToPlc4xReadResponse(readRequest, responseAdsData);
+                        // Convert the response from the PLC into a PLC4X Response ...
+                        future.complete(plcReadResponse);
+                    } else {
+                        // TODO: Implement this correctly.
+                        future.completeExceptionally(new PlcException("Result is " + responseAdsData.getResult()));
+                    }
+                } else if (payload instanceof AdsReadCompactResponse) {
+                    final PlcReadResponse plcReadResponse = convertToPlc4xReadResponse(readRequest, payload);
                     future.complete(plcReadResponse);
-                } else {
-                    // TODO: Implement this correctly.
-                    future.completeExceptionally(new PlcException("Result is " + responseAdsData.getResult()));
                 }
                 // Finish the request-transaction.
                 transaction.endRequest();
@@ -274,14 +281,18 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
         return future;
     }
 
-    protected PlcReadResponse convertToPlc4xReadResponse(PlcReadRequest readRequest, AdsData adsData) {
+    protected PlcReadResponse convertToPlc4xReadResponse(PlcReadRequest readRequest, Object adsData) {
         ReadBuffer readBuffer = null;
         Map<String, PlcResponseCode> responseCodes = new HashMap<>();
-        if (adsData instanceof AdsReadResponse) {
-            AdsReadResponse adsReadResponse = (AdsReadResponse) adsData;
+        if (adsData instanceof AdsReadFullResponse) {
+            AdsReadFullResponse adsReadResponse = (AdsReadFullResponse) adsData;
             readBuffer = new ReadBufferByteBased(adsReadResponse.getData(), true);
             responseCodes.put(readRequest.getFieldNames().stream().findFirst().orElse(""),
                 parsePlcResponseCode(adsReadResponse.getResult()));
+        } else if (adsData instanceof AdsReadCompactResponse) {
+            AdsReadCompactResponse adsReadResponse = (AdsReadCompactResponse) adsData;
+            readBuffer = new ReadBufferByteBased(adsReadResponse.getData(), true);
+            responseCodes.put(readRequest.getFieldNames().stream().findFirst().orElse(""), PlcResponseCode.OK);
         } else if (adsData instanceof AdsReadWriteResponse) {
             AdsReadWriteResponse adsReadWriteResponse = (AdsReadWriteResponse) adsData;
             readBuffer = new ReadBufferByteBased(adsReadWriteResponse.getData(), true);
diff --git a/protocols/ads/src/main/resources/protocols/ads/ads.mspec b/protocols/ads/src/main/resources/protocols/ads/ads.mspec
index 808b2f3..59158f7 100644
--- a/protocols/ads/src/main/resources/protocols/ads/ads.mspec
+++ b/protocols/ads/src/main/resources/protocols/ads/ads.mspec
@@ -133,7 +133,7 @@
     // 4 bytes	Free usable 32 bit array. Usually this array serves to send an Id. This Id makes is possible to assign a received response to a request, which was sent before.
     [simple      uint        32  'invokeId'                                 ]
     // The payload
-    [simple     AdsData    'data'   ['commandId', 'state.response']         ]
+    [simple     AdsData    'data'   ['commandId', 'state.response', 'length']         ]
 ]
 
 [enum uint 16 'CommandId'
@@ -190,7 +190,24 @@
     [simple     uint        8   'octet6'            ]
 ]
 
-[discriminatedType 'AdsData' [CommandId 'commandId', bit 'response']
+[discriminatedType 'AdsResponseData' [int 32 'dataSize', bit 'compactAnswer']
+    [typeSwitch 'compactAnswer', 'dataSize'
+        ['true' AdsReadCompactResponse [int 32 'dataSize']
+            [array int 8 'data' count 'dataSize']
+        ]
+        ['false' AdsReadFullResponse
+            // 4 bytes	ADS error number
+            [simple ReturnCode 'result']
+            // 4 bytes	Length of data which are supplied back.
+            [implicit uint 32 'length' 'COUNT(data)']
+            // n bytes	Data which are supplied back.
+            [array int 8 'data' count 'length']
+        ]
+    ]
+]
+
+
+[discriminatedType 'AdsData' [CommandId 'commandId', bit 'response', int 32 'dataSize']
     [typeSwitch 'commandId', 'response'
         ['INVALID', 'false' AdsInvalidRequest]
         ['INVALID', 'true' AdsInvalidResponse]
@@ -217,13 +234,8 @@
             // 4 bytes	Length of the data (in bytes) which should be read.
             [simple uint 32 'length']
         ]
-        ['ADS_READ', 'true' AdsReadResponse
-            // 4 bytes	ADS error number
-            [simple ReturnCode 'result']
-            // 4 bytes	Length of data which are supplied back.
-            [implicit uint 32 'length' 'COUNT(data)']
-            // n bytes	Data which are supplied back.
-            [array int 8 'data' count 'length']
+        ['ADS_READ', 'true' AdsReadResponse [int 32 'dataSize']
+            [simple AdsResponseData 'payload' ['CAST(dataSize, Integer)', 'dataSize <= 8'] ]
         ]
 
         ['ADS_WRITE', 'false' AdsWriteRequest
diff --git a/protocols/ads/src/test/resources/protocols/ads/DriverTestsuite.xml b/protocols/ads/src/test/resources/protocols/ads/DriverTestsuite.xml
index b10a23f..5a49b2a 100644
--- a/protocols/ads/src/test/resources/protocols/ads/DriverTestsuite.xml
+++ b/protocols/ads/src/test/resources/protocols/ads/DriverTestsuite.xml
@@ -174,13 +174,19 @@
               <data>
                 <AdsData>
                   <AdsReadResponse>
-                    <result>
-                      <ReturnCode dataType="uint" bitLength="32">0</ReturnCode>
-                    </result>
-                    <length dataType="uint" bitLength="32">1</length>
-                    <data isList="true">
-                      <value dataType="int" bitLength="8">1</value>
-                    </data>
+                    <payload>
+                      <AdsResponseData>
+                        <AdsReadFullResponse>
+                          <result>
+                            <ReturnCode dataType="uint" bitLength="32">0</ReturnCode>
+                          </result>
+                          <length dataType="uint" bitLength="32">1</length>
+                          <data isList="true">
+                            <value dataType="int" bitLength="8">1</value>
+                          </data>
+                        </AdsReadFullResponse>
+                      </AdsResponseData>
+                    </payload>
                   </AdsReadResponse>
                 </AdsData>
               </data>
@@ -724,22 +730,28 @@
               <data>
                 <AdsData>
                   <AdsReadResponse>
-                    <result>
-                      <ReturnCode dataType="uint" bitLength="32">0</ReturnCode>
-                    </result>
-                    <length dataType="uint" bitLength="32">10</length>
-                    <data isList="true">
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">1</value>
-                      <value dataType="int" bitLength="8">1</value>
-                    </data>
+                    <payload>
+                      <AdsResponseData>
+                        <AdsReadFullResponse>
+                          <result>
+                            <ReturnCode dataType="uint" bitLength="32">0</ReturnCode>
+                          </result>
+                          <length dataType="uint" bitLength="32">10</length>
+                          <data isList="true">
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">1</value>
+                            <value dataType="int" bitLength="8">1</value>
+                          </data>
+                        </AdsReadFullResponse>
+                      </AdsResponseData>
+                    </payload>
                   </AdsReadResponse>
                 </AdsData>
               </data>
@@ -1064,22 +1076,28 @@
               <data>
                 <AdsData>
                   <AdsReadResponse>
-                    <result>
-                      <ReturnCode dataType="uint" bitLength="32">0</ReturnCode>
-                    </result>
-                    <length dataType="uint" bitLength="32">10</length>
-                    <data isList="true">
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">1</value>
-                      <value dataType="int" bitLength="8">1</value>
-                    </data>
+                    <payload>
+                      <AdsResponseData>
+                        <AdsReadFullResponse>
+                          <result>
+                            <ReturnCode dataType="uint" bitLength="32">0</ReturnCode>
+                          </result>
+                          <length dataType="uint" bitLength="32">10</length>
+                          <data isList="true">
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">1</value>
+                            <value dataType="int" bitLength="8">1</value>
+                          </data>
+                        </AdsReadFullResponse>
+                      </AdsResponseData>
+                    </payload>
                   </AdsReadResponse>
                 </AdsData>
               </data>
@@ -1234,22 +1252,28 @@
               <data>
                 <AdsData>
                   <AdsReadResponse>
-                    <result>
-                      <ReturnCode dataType="uint" bitLength="32">0</ReturnCode>
-                    </result>
-                    <length dataType="uint" bitLength="32">10</length>
-                    <data isList="true">
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">0</value>
-                      <value dataType="int" bitLength="8">1</value>
-                      <value dataType="int" bitLength="8">1</value>
-                    </data>
+                    <payload>
+                      <AdsResponseData>
+                        <AdsReadFullResponse>
+                          <result>
+                            <ReturnCode dataType="uint" bitLength="32">0</ReturnCode>
+                          </result>
+                          <length dataType="uint" bitLength="32">10</length>
+                          <data isList="true">
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">0</value>
+                            <value dataType="int" bitLength="8">1</value>
+                            <value dataType="int" bitLength="8">1</value>
+                          </data>
+                        </AdsReadFullResponse>
+                      </AdsResponseData>
+                    </payload>
                   </AdsReadResponse>
                 </AdsData>
               </data>
diff --git a/protocols/ads/src/test/resources/protocols/ads/ParserSerializerTestsuite.xml b/protocols/ads/src/test/resources/protocols/ads/ParserSerializerTestsuite.xml
index 6fcac92..4b5376f 100644
--- a/protocols/ads/src/test/resources/protocols/ads/ParserSerializerTestsuite.xml
+++ b/protocols/ads/src/test/resources/protocols/ads/ParserSerializerTestsuite.xml
@@ -147,13 +147,19 @@
             <data>
               <AdsData>
                 <AdsReadResponse>
-                  <result>
-                    <ReturnCode dataType="uint" bitLength="32" stringRepresentation="OK">0</ReturnCode>
-                  </result>
-                  <length dataType="uint" bitLength="32">1</length>
-                  <data isList="true">
-                    <value dataType="int" bitLength="8">1</value>
-                  </data>
+                  <payload>
+                    <AdsResponseData>
+                      <AdsReadFullResponse>
+                        <result>
+                          <ReturnCode dataType="uint" bitLength="32" stringRepresentation="OK">0</ReturnCode>
+                        </result>
+                        <length dataType="uint" bitLength="32">1</length>
+                        <data isList="true">
+                          <value dataType="int" bitLength="8">1</value>
+                        </data>
+                      </AdsReadFullResponse>
+                    </AdsResponseData>
+                  </payload>
                 </AdsReadResponse>
               </AdsData>
             </data>
@@ -457,13 +463,19 @@
             <data>
               <AdsData>
                 <AdsReadResponse>
-                  <result>
-                    <ReturnCode dataType="uint" bitLength="32" stringRepresentation="OK">0</ReturnCode>
-                  </result>
-                  <length dataType="uint" bitLength="32">1</length>
-                  <data isList="true">
-                    <value dataType="int" bitLength="8">1</value>
-                  </data>
+                  <payload>
+                    <AdsResponseData>
+                      <AdsReadFullResponse>
+                        <result>
+                          <ReturnCode dataType="uint" bitLength="32" stringRepresentation="OK">0</ReturnCode>
+                        </result>
+                        <length dataType="uint" bitLength="32">1</length>
+                        <data isList="true">
+                          <value dataType="int" bitLength="8">1</value>
+                        </data>
+                      </AdsReadFullResponse>
+                    </AdsResponseData>
+                  </payload>
                 </AdsReadResponse>
               </AdsData>
             </data>