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 2020/11/30 17:36:54 UTC

[plc4x] 25/28: Support for custom answer node identifiers (offsets in TRANSMIT_SDO).

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

ldywicki pushed a commit to branch feature/socketcan-0.8-preparations
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 728012dd6571d4f1e7b2e5b0dc1529dd41f37463
Author: Ɓukasz Dywicki <lu...@code-house.org>
AuthorDate: Fri Nov 6 12:41:13 2020 +0100

    Support for custom answer node identifiers (offsets in TRANSMIT_SDO).
---
 .../canopen/CANOpenConversationBase.java           |  6 +-
 .../canopen/SDODownloadConversation.java           |  4 +-
 .../canopen/SDOUploadConversation.java             |  4 +-
 .../plc4x/java/can/field/CANOpenSDOField.java      | 18 +++-
 .../java/can/protocol/CANOpenProtocolLogic.java    |  4 +-
 .../plc4x/java/can/field/CANOpenSDOFieldTest.java  | 12 +++
 .../resources/testsuite/CANOpenDriverSDOIT.xml     | 98 ++++++++++++++++++++++
 7 files changed, 137 insertions(+), 9 deletions(-)

diff --git a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/api/conversation/canopen/CANOpenConversationBase.java b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/api/conversation/canopen/CANOpenConversationBase.java
index 28a6941..d3a41ae 100644
--- a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/api/conversation/canopen/CANOpenConversationBase.java
+++ b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/api/conversation/canopen/CANOpenConversationBase.java
@@ -14,10 +14,12 @@ public abstract class CANOpenConversationBase {
 
     protected final CANConversation<CANOpenFrame> delegate;
     protected final int nodeId;
+    private final int answerNodeId;
 
-    public CANOpenConversationBase(CANConversation<CANOpenFrame> delegate, int nodeId) {
+    public CANOpenConversationBase(CANConversation<CANOpenFrame> delegate, int nodeId, int answerNodeId) {
         this.delegate = delegate;
         this.nodeId = nodeId;
+        this.answerNodeId = answerNodeId;
     }
 
     protected PlcValue decodeFrom(byte[] data, CANOpenDataType type, int length) throws ParseException {
@@ -25,7 +27,7 @@ public abstract class CANOpenConversationBase {
     }
 
     protected boolean isTransmitSDOFromReceiver(CANOpenFrame frame) {
-        return frame.getNodeId() == nodeId && frame.getService() == CANOpenService.TRANSMIT_SDO;
+        return frame.getNodeId() == answerNodeId && frame.getService() == CANOpenService.TRANSMIT_SDO;
     }
 
     protected CANOpenFrame createFrame(SDORequest rq) {
diff --git a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/api/conversation/canopen/SDODownloadConversation.java b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/api/conversation/canopen/SDODownloadConversation.java
index ba0bffb..689aec9 100644
--- a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/api/conversation/canopen/SDODownloadConversation.java
+++ b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/api/conversation/canopen/SDODownloadConversation.java
@@ -20,8 +20,8 @@ public class SDODownloadConversation extends CANOpenConversationBase {
     private final IndexAddress indexAddress;
     private final byte[] data;
 
-    public SDODownloadConversation(CANConversation<CANOpenFrame> delegate, int nodeId, IndexAddress indexAddress, PlcValue value, CANOpenDataType type) {
-        super(delegate, nodeId);
+    public SDODownloadConversation(CANConversation<CANOpenFrame> delegate, int nodeId, int answerNodeId, IndexAddress indexAddress, PlcValue value, CANOpenDataType type) {
+        super(delegate, nodeId, answerNodeId);
         this.delegate = delegate;
         this.indexAddress = indexAddress;
 
diff --git a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/api/conversation/canopen/SDOUploadConversation.java b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/api/conversation/canopen/SDOUploadConversation.java
index 6be036a..7e0b3b0 100644
--- a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/api/conversation/canopen/SDOUploadConversation.java
+++ b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/api/conversation/canopen/SDOUploadConversation.java
@@ -19,8 +19,8 @@ public class SDOUploadConversation extends CANOpenConversationBase {
     private final IndexAddress address;
     private final CANOpenDataType type;
 
-    public SDOUploadConversation(CANConversation<CANOpenFrame> delegate, int nodeId, IndexAddress address, CANOpenDataType type) {
-        super(delegate, nodeId);
+    public SDOUploadConversation(CANConversation<CANOpenFrame> delegate, int nodeId, int answerNodeId, IndexAddress address, CANOpenDataType type) {
+        super(delegate, nodeId, answerNodeId);
         this.address = address;
         this.type = type;
     }
diff --git a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/field/CANOpenSDOField.java b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/field/CANOpenSDOField.java
index 86882c0..0997087 100644
--- a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/field/CANOpenSDOField.java
+++ b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/field/CANOpenSDOField.java
@@ -26,18 +26,28 @@ import java.util.regex.Pattern;
 
 public class CANOpenSDOField extends CANOpenField {
 
-    public static final Pattern ADDRESS_PATTERN = Pattern.compile("SDO:" + CANOpenField.NODE_PATTERN + ":" + CANOpenField.ADDRESS_PATTERN);
+    public static final Pattern ADDRESS_PATTERN = Pattern.compile("SDO:" + CANOpenField.NODE_PATTERN + "(?:/(?<answerNodeId>\\d+))?:" + CANOpenField.ADDRESS_PATTERN);
+    private final int answerNode;
     private final short index;
     private final short subIndex;
     private final CANOpenDataType canOpenDataType;
 
     public CANOpenSDOField(int node, short index, short subIndex, CANOpenDataType canOpenDataType) {
+        this(node, node, index, subIndex, canOpenDataType);
+    }
+
+    public CANOpenSDOField(int node, int answerNode, short index, short subIndex, CANOpenDataType canOpenDataType) {
         super(node);
+        this.answerNode = answerNode;
         this.index = index;
         this.subIndex = subIndex;
         this.canOpenDataType = canOpenDataType;
     }
 
+    public int getAnswerNodeId() {
+        return answerNode;
+    }
+
     public short getIndex() {
         return index;
     }
@@ -73,6 +83,12 @@ public class CANOpenSDOField extends CANOpenField {
         String canDataTypeString = matcher.group("canDataType");
         CANOpenDataType canOpenDataType = CANOpenDataType.valueOf(canDataTypeString);
 
+        String answerNode = matcher.group("answerNodeId");
+        if (answerNode != null) {
+            int answerNodeId = Integer.parseInt(matcher.group("answerNodeId"));
+            return new CANOpenSDOField(nodeId, answerNodeId, index, subIndex, canOpenDataType);
+        }
+
         //String numberOfElementsString = matcher.group("numberOfElements");
         //Integer numberOfElements = numberOfElementsString != null ? Integer.valueOf(numberOfElementsString) : null;
 
diff --git a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/protocol/CANOpenProtocolLogic.java b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/protocol/CANOpenProtocolLogic.java
index f751b7c..830656d 100644
--- a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/protocol/CANOpenProtocolLogic.java
+++ b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/protocol/CANOpenProtocolLogic.java
@@ -185,7 +185,7 @@ public class CANOpenProtocolLogic extends Plc4xProtocolBase<CANOpenFrame> implem
         });
 
         PlcValue writeValue = writeRequest.getPlcValues().get(0);
-        SDODownloadConversation download = new SDODownloadConversation(conversation, field.getNodeId(), new IndexAddress(field.getIndex(), field.getSubIndex()), writeValue, field.getCanOpenDataType());
+        SDODownloadConversation download = new SDODownloadConversation(conversation, field.getNodeId(), field.getAnswerNodeId(), new IndexAddress(field.getIndex(), field.getSubIndex()), writeValue, field.getCanOpenDataType());
         transaction.submit(() -> download.execute(callback));
     }
 
@@ -283,7 +283,7 @@ public class CANOpenProtocolLogic extends Plc4xProtocolBase<CANOpenFrame> implem
             transaction.endRequest();
         });
 
-        SDOUploadConversation upload = new SDOUploadConversation(conversation, field.getNodeId(), new IndexAddress(field.getIndex(), field.getSubIndex()), field.getCanOpenDataType());
+        SDOUploadConversation upload = new SDOUploadConversation(conversation, field.getNodeId(), field.getAnswerNodeId(), new IndexAddress(field.getIndex(), field.getSubIndex()), field.getCanOpenDataType());
         transaction.submit(() -> upload.execute(callback));
     }
 
diff --git a/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/field/CANOpenSDOFieldTest.java b/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/field/CANOpenSDOFieldTest.java
index ddecd2b..8065bdc 100644
--- a/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/field/CANOpenSDOFieldTest.java
+++ b/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/field/CANOpenSDOFieldTest.java
@@ -13,6 +13,18 @@ class CANOpenSDOFieldTest {
         final CANOpenSDOField canField = CANOpenSDOField.of("SDO:20:0x10/0xAA:RECORD");
 
         assertEquals(20, canField.getNodeId());
+        assertEquals(20, canField.getAnswerNodeId());
+        assertEquals(0x10, canField.getIndex());
+        assertEquals(0xAA, canField.getSubIndex());
+        assertEquals(CANOpenDataType.RECORD, canField.getCanOpenDataType());
+    }
+
+    @Test
+    public void testAnswerNodeSyntax() {
+        final CANOpenSDOField canField = CANOpenSDOField.of("SDO:20/22:0x10/0xAA:RECORD");
+
+        assertEquals(20, canField.getNodeId());
+        assertEquals(22, canField.getAnswerNodeId());
         assertEquals(0x10, canField.getIndex());
         assertEquals(0xAA, canField.getSubIndex());
         assertEquals(CANOpenDataType.RECORD, canField.getCanOpenDataType());
diff --git a/sandbox/test-java-can-driver/src/test/resources/testsuite/CANOpenDriverSDOIT.xml b/sandbox/test-java-can-driver/src/test/resources/testsuite/CANOpenDriverSDOIT.xml
index 190f3be..f0e7e0d 100644
--- a/sandbox/test-java-can-driver/src/test/resources/testsuite/CANOpenDriverSDOIT.xml
+++ b/sandbox/test-java-can-driver/src/test/resources/testsuite/CANOpenDriverSDOIT.xml
@@ -110,6 +110,103 @@
               <index>1000</index>
               <subIndex>22</subIndex>
               <canOpenDataType>UNSIGNED32</canOpenDataType>
+              <answerNodeId>1</answerNodeId>
+            </sdo1>
+          </request>
+          <sdo1>
+            <code>OK</code>
+            <value className="org.apache.plc4x.java.api.value.PlcUDINT">
+              <object>java.lang.Long</object>
+              <object>1717859169</object>
+            </value>
+          </sdo1>
+        </DefaultPlcReadResponse>
+      </api-response>
+      <delay>1000</delay>
+    </steps>
+  </testcase>
+
+  <testcase>
+    <name>Expedited SDO read request - custom answer node id</name>
+    <description>
+      Single field read request which answers with 4 bytes of data.
+    </description>
+    <steps>
+      <api-request name="Receive Read Request from application">
+        <TestReadRequest className="org.apache.plc4x.test.driver.model.api.TestReadRequest">
+          <fields>
+            <field className="org.apache.plc4x.test.driver.model.api.TestField">
+              <name>sdo1</name>
+              <address>SDO:1/2:1000/22:UNSIGNED32</address>
+            </field>
+          </fields>
+        </TestReadRequest>
+      </api-request>
+      <outgoing-plc-message name="Send SDO Initialize Upload Request">
+        <CANOpenSocketCANFrame className="org.apache.plc4x.java.can.canopen.socketcan.CANOpenSocketCANFrame">
+          <nodeId>1</nodeId>
+          <service>RECEIVE_SDO</service>
+          <payload className="org.apache.plc4x.java.canopen.readwrite.CANOpenSDORequest">
+            <command>INITIATE_UPLOAD</command>
+            <request className="org.apache.plc4x.java.canopen.readwrite.SDOInitiateUploadRequest">
+              <address className="org.apache.plc4x.java.canopen.readwrite.IndexAddress">
+                <index>1000</index>
+                <subindex>22</subindex>
+              </address>
+            </request>
+          </payload>
+        </CANOpenSocketCANFrame>
+      </outgoing-plc-message>
+      <incoming-plc-message name="Receive SDO Initialize Upload Response for other node">
+        <!-- one unwanted frame -->
+        <CANOpenSocketCANFrame className="org.apache.plc4x.java.can.canopen.socketcan.CANOpenSocketCANFrame">
+          <nodeId>1</nodeId>
+          <service>TRANSMIT_SDO</service>
+          <payload className="org.apache.plc4x.java.canopen.readwrite.CANOpenSDOResponse">
+            <command>INITIATE_UPLOAD</command>
+            <response className="org.apache.plc4x.java.canopen.readwrite.SDOInitiateUploadResponse">
+              <expedited>true</expedited>
+              <indicated>true</indicated>
+              <address className="org.apache.plc4x.java.canopen.readwrite.IndexAddress">
+                <index>1001</index>
+                <subindex>22</subindex>
+              </address>
+              <payload className="org.apache.plc4x.java.canopen.readwrite.SDOInitiateExpeditedUploadResponse">
+                <data>YXNkZg==</data>
+              </payload>
+            </response>
+          </payload>
+        </CANOpenSocketCANFrame>
+      </incoming-plc-message>
+      <incoming-plc-message name="Receive SDO Initialize Upload Response for from requested node">
+        <CANOpenSocketCANFrame className="org.apache.plc4x.java.can.canopen.socketcan.CANOpenSocketCANFrame">
+          <nodeId>2</nodeId>
+          <service>TRANSMIT_SDO</service>
+          <payload className="org.apache.plc4x.java.canopen.readwrite.CANOpenSDOResponse">
+            <command>INITIATE_UPLOAD</command>
+            <response className="org.apache.plc4x.java.canopen.readwrite.SDOInitiateUploadResponse">
+              <expedited>true</expedited>
+              <indicated>true</indicated>
+              <address className="org.apache.plc4x.java.canopen.readwrite.IndexAddress">
+                <index>1000</index>
+                <subindex>22</subindex>
+              </address>
+              <payload className="org.apache.plc4x.java.canopen.readwrite.SDOInitiateExpeditedUploadResponse">
+                <data>YXNkZg==</data>
+              </payload>
+            </response>
+          </payload>
+        </CANOpenSocketCANFrame>
+      </incoming-plc-message>
+      <api-response name="Report Read Response to application">
+        <DefaultPlcReadResponse className="org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse">
+          <request className="org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest">
+            <sdo1 className="org.apache.plc4x.java.can.field.CANOpenSDOField">
+              <nodeId>1</nodeId>
+              <index>1000</index>
+              <subIndex>22</subIndex>
+              <canOpenDataType>UNSIGNED32</canOpenDataType>
+              <answerNodeId>2</answerNodeId>
             </sdo1>
           </request>
           <sdo1>
@@ -267,6 +364,7 @@
               <index>2000</index>
               <subIndex>44</subIndex>
               <canOpenDataType>RECORD</canOpenDataType>
+              <answerNodeId>2</answerNodeId>
             </sdo1>
           </request>
           <sdo1>