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/10/21 08:43:20 UTC

[plc4x] 20/21: Support for NMT subscriptions.

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 13ebb2aabcd838238b3178c066026c7d94b2c6a3
Author: Ɓukasz Dywicki <lu...@code-house.org>
AuthorDate: Mon Oct 19 00:33:20 2020 +0200

    Support for NMT subscriptions.
---
 ...ndle.java => CANOpenPDOSubscriptionHandle.java} |  6 +--
 .../java/can/protocol/CANOpenProtocolLogic.java    | 56 +++++++++++++++-------
 2 files changed, 43 insertions(+), 19 deletions(-)

diff --git a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/protocol/CANOpenSubscriptionHandle.java b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/protocol/CANOpenPDOSubscriptionHandle.java
similarity index 71%
rename from sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/protocol/CANOpenSubscriptionHandle.java
rename to sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/protocol/CANOpenPDOSubscriptionHandle.java
index 9bfd688..80876c6 100644
--- a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/protocol/CANOpenSubscriptionHandle.java
+++ b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/protocol/CANOpenPDOSubscriptionHandle.java
@@ -5,11 +5,11 @@ import org.apache.plc4x.java.canopen.readwrite.types.CANOpenService;
 import org.apache.plc4x.java.spi.messages.PlcSubscriber;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionHandle;
 
-public class CANOpenSubscriptionHandle extends DefaultPlcSubscriptionHandle {
+public class CANOpenPDOSubscriptionHandle extends DefaultPlcSubscriptionHandle {
     private final String name;
     private final CANOpenPDOField field;
 
-    public CANOpenSubscriptionHandle(PlcSubscriber subscriber, String name, CANOpenPDOField field) {
+    public CANOpenPDOSubscriptionHandle(PlcSubscriber subscriber, String name, CANOpenPDOField field) {
         super(subscriber);
         this.name = name;
         this.field = field;
@@ -31,7 +31,7 @@ public class CANOpenSubscriptionHandle extends DefaultPlcSubscriptionHandle {
     }
 
     public String toString() {
-        return "CANOpenSubscriptionHandle [service=" + field.getService() + ", node=" + intAndHex(field.getNodeId()) + ", cob=" + intAndHex(field.getService().getMin() + field.getNodeId()) + "]";
+        return "CANOpenPDOSubscriptionHandle [service=" + field.getService() + ", node=" + intAndHex(field.getNodeId()) + ", cob=" + intAndHex(field.getService().getMin() + field.getNodeId()) + "]";
     }
 
     private static String intAndHex(int val) {
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 96488ec..5285b16 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
@@ -19,28 +19,27 @@ under the License.
 package org.apache.plc4x.java.can.protocol;
 
 import org.apache.commons.codec.binary.Hex;
-import org.apache.plc4x.java.api.exceptions.PlcException;
-import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
 import org.apache.plc4x.java.api.messages.*;
 import org.apache.plc4x.java.api.model.PlcConsumerRegistration;
 import org.apache.plc4x.java.api.model.PlcField;
 import org.apache.plc4x.java.api.model.PlcSubscriptionHandle;
 import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.api.types.PlcSubscriptionType;
-import org.apache.plc4x.java.api.value.PlcList;
 import org.apache.plc4x.java.api.value.PlcNull;
+import org.apache.plc4x.java.api.value.PlcStruct;
+import org.apache.plc4x.java.api.value.PlcUSINT;
 import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.can.canopen.CANOpenFrame;
 import org.apache.plc4x.java.can.api.conversation.canopen.CANConversation;
 import org.apache.plc4x.java.can.api.conversation.canopen.CANOpenConversation;
 import org.apache.plc4x.java.can.api.conversation.canopen.SDODownloadConversation;
 import org.apache.plc4x.java.can.api.conversation.canopen.SDOUploadConversation;
-import org.apache.plc4x.java.can.canopen.CANOpenFrameBuilder;
 import org.apache.plc4x.java.can.canopen.CANOpenFrameBuilderFactory;
 import org.apache.plc4x.java.can.canopen.socketcan.CANOpenSocketCANFrameBuilder;
 import org.apache.plc4x.java.can.configuration.CANConfiguration;
 import org.apache.plc4x.java.can.context.CANOpenDriverContext;
 import org.apache.plc4x.java.can.field.CANOpenField;
+import org.apache.plc4x.java.can.field.CANOpenNMTField;
 import org.apache.plc4x.java.can.field.CANOpenPDOField;
 import org.apache.plc4x.java.can.field.CANOpenSDOField;
 import org.apache.plc4x.java.can.socketcan.SocketCANConversation;
@@ -49,7 +48,6 @@ import org.apache.plc4x.java.canopen.readwrite.io.CANOpenPayloadIO;
 import org.apache.plc4x.java.canopen.readwrite.io.DataItemIO;
 import org.apache.plc4x.java.canopen.readwrite.types.CANOpenService;
 import org.apache.plc4x.java.canopen.readwrite.types.NMTState;
-import org.apache.plc4x.java.socketcan.readwrite.SocketCANFrame;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.configuration.HasConfiguration;
@@ -60,6 +58,7 @@ import org.apache.plc4x.java.spi.generation.WriteBuffer;
 import org.apache.plc4x.java.spi.messages.*;
 import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
 import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration;
+import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionHandle;
 import org.apache.plc4x.java.spi.model.InternalPlcSubscriptionHandle;
 import org.apache.plc4x.java.spi.model.SubscriptionPlcField;
 import org.apache.plc4x.java.spi.transaction.RequestTransactionManager;
@@ -72,7 +71,6 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.Timer;
 import java.util.TimerTask;
@@ -251,12 +249,16 @@ public class CANOpenProtocolLogic extends Plc4xProtocolBase<CANOpenFrame> implem
             SubscriptionPlcField subscription = entry.getValue();
             if (subscription.getPlcSubscriptionType() != PlcSubscriptionType.EVENT) {
                 answers.put(entry.getKey(), new ResponseItem<>(PlcResponseCode.UNSUPPORTED, null));
-            } else if (!(subscription.getPlcField() instanceof CANOpenPDOField)) {
-                answers.put(entry.getKey(), new ResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null));
-            } else {
+            } else if ((subscription.getPlcField() instanceof CANOpenPDOField)) {
+                answers.put(entry.getKey(), new ResponseItem<>(PlcResponseCode.OK,
+                    new CANOpenPDOSubscriptionHandle(this, entry.getKey(), (CANOpenPDOField) subscription.getPlcField())
+                ));
+            } else if ((subscription.getPlcField() instanceof CANOpenNMTField)) {
                 answers.put(entry.getKey(), new ResponseItem<>(PlcResponseCode.OK,
-                    new CANOpenSubscriptionHandle(this, entry.getKey(), (CANOpenPDOField) subscription.getPlcField())
+                    new CANOpenNMTSubscriptionHandle(this, entry.getKey(), (CANOpenNMTField) subscription.getPlcField())
                 ));
+            } else {
+                answers.put(entry.getKey(), new ResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null));
             }
         }
 
@@ -295,6 +297,8 @@ public class CANOpenProtocolLogic extends Plc4xProtocolBase<CANOpenFrame> implem
         if (service != null) {
             if (service.getPdo() && payload instanceof CANOpenPDOPayload) {
                 publishEvent(service, nodeId, (CANOpenPDOPayload) payload);
+            } else if (service == CANOpenService.NMT && payload instanceof CANOpenNetworkPayload) {
+                publishEvent(service, nodeId, (CANOpenNetworkPayload) payload);
             } else {
                 String hex = "";
                 if (logger.isInfoEnabled()) {
@@ -320,22 +324,22 @@ public class CANOpenProtocolLogic extends Plc4xProtocolBase<CANOpenFrame> implem
 //        }
     }
 
-    private void publishEvent(CANOpenService service, int nodeId, CANOpenPDOPayload payload) {
-        CANOpenSubscriptionHandle dispatchedHandle = null;
+    private void publishEvent(CANOpenService service, int nodeId, CANOpenPayload payload) {
+        DefaultPlcSubscriptionHandle dispatchedHandle = null;
         for (Map.Entry<DefaultPlcConsumerRegistration, Consumer<PlcSubscriptionEvent>> entry : consumers.entrySet()) {
             DefaultPlcConsumerRegistration registration = entry.getKey();
             Consumer<PlcSubscriptionEvent> consumer = entry.getValue();
 
             for (InternalPlcSubscriptionHandle handler : registration.getAssociatedHandles()) {
-                if (handler instanceof CANOpenSubscriptionHandle) {
-                    CANOpenSubscriptionHandle handle = (CANOpenSubscriptionHandle) handler;
+                if (handler instanceof CANOpenPDOSubscriptionHandle && payload instanceof CANOpenPDOPayload) {
+                    CANOpenPDOSubscriptionHandle handle = (CANOpenPDOSubscriptionHandle) handler;
 
                     if (handle.matches(service, nodeId)) {
                         logger.trace("Dispatching notification {} for node {} to {}", service, nodeId, handle);
                         dispatchedHandle = handle;
 
                         CANOpenPDOField field = handle.getField();
-                        byte[] data = payload.getPdo().getData();
+                        byte[] data = ((CANOpenPDOPayload) payload).getPdo().getData();
                         try {
                             PlcValue value = DataItemIO.staticParse(new ReadBuffer(data, true), field.getCanOpenDataType(), data.length);
                             DefaultPlcSubscriptionEvent event = new DefaultPlcSubscriptionEvent(
@@ -357,7 +361,27 @@ public class CANOpenProtocolLogic extends Plc4xProtocolBase<CANOpenFrame> implem
                             );
                             consumer.accept(event);
                         }
-                    } else {
+                    }
+                } else if (handler instanceof CANOpenPDOSubscriptionHandle && payload instanceof CANOpenHeartbeatPayload) {
+                    CANOpenNMTSubscriptionHandle handle = (CANOpenNMTSubscriptionHandle) handler;
+
+                    if (handle.matches(service, nodeId)) {
+                        logger.trace("Dispatching notification {} for node {} to {}", service, nodeId, handle);
+                        dispatchedHandle = handle;
+
+                        final NMTState state = ((CANOpenHeartbeatPayload) payload).getState();
+                        Map<String, PlcValue> fields = new HashMap<>();
+                        fields.put("state", new PlcUSINT(state.getValue()));
+                        fields.put("node", new PlcUSINT(nodeId));
+                        PlcStruct struct = new PlcStruct(fields);
+                        DefaultPlcSubscriptionEvent event = new DefaultPlcSubscriptionEvent(
+                            Instant.now(),
+                            Collections.singletonMap(
+                                handle.getName(),
+                                new ResponseItem<>(PlcResponseCode.OK, struct)
+                            )
+                        );
+                        consumer.accept(event);
                     }
                 }
             }