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/12 00:42:28 UTC
[plc4x] 25/26: 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
in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit 5655a5a6325c16ed8c3ea4245b373c509e0ff5cd
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>