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/07 10:02:03 UTC

[plc4x] 08/19: Focus on payloads and not frames.

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 d60b64a21a0ca88d1b9b024634b4bd1216fde549
Author: Ɓukasz Dywicki <lu...@code-house.org>
AuthorDate: Fri Aug 28 00:14:16 2020 +0200

    Focus on payloads and not frames.
---
 .../src/main/resources/protocols/can/canopen.mspec |  41 +++++----
 .../apache/plc4x/java/can/CANOpenPlcDriver.java    | 102 +++++++++++++++++++++
 .../java/can/protocol/CANOpenProtocolLogic.java    |  62 +++++++++++++
 .../{CANOpenTest.java => CANOpenPayloadTest.java}  |   6 +-
 ...enTestSuite.xml => CANOpenPayloadTestSuite.xml} |  11 ++-
 5 files changed, 198 insertions(+), 24 deletions(-)

diff --git a/protocols/can/src/main/resources/protocols/can/canopen.mspec b/protocols/can/src/main/resources/protocols/can/canopen.mspec
index 553d12a..54337b4 100644
--- a/protocols/can/src/main/resources/protocols/can/canopen.mspec
+++ b/protocols/can/src/main/resources/protocols/can/canopen.mspec
@@ -17,28 +17,35 @@
  * under the License.
  */
 
-[type 'CANOpenFrame'
-    [enum CANOpenService 'function']
-    [simple int 11 'identifier']
-    [reserved int 9 '0x0'] // filling gap used by extended frame, and extended marker which should always be 0
-    [simple bit 'remote']
-    [simple bit 'error']
-    [reserved int 5 '0x0']  // filling gap used by extended frame
-    [implicit uint 8 'size' 'COUNT(payload)']
-    [reserved uint 8 '0x0'] // in case of fd frame these are flags
-    [reserved uint 8 '0x0'] // padding 1
-    [reserved uint 8 '0x0'] // padding 2
-    [simple CANOpenPayload 'payload' ['function', 'size']]
+[enum uint 4 'CANOpenService'
+    ['0x00' BROADCAST]
+    ['0x07' NMT]
 ]
 
-[enum uint 4 'CANOpenService'
-    ['0b1110' NMT]
+[enum uint 8 'NMTStateRequest'
+    ['0x01' OPERATIONAL]
+    ['0x02' STOP]
+    ['0x80' PRE_OPERATIONAL]
+    ['0x81' RESET_NODE]
+    ['0x82' RESET_COMMUNICATION]
 ]
 
-[discriminatedType 'CANOpenPayload' [CANOpenService 'function', uint 8 'size']
+[enum uint 8 'NMTState'
+    ['0x00' BOOTED_UP]
+    ['0x04' STOPPED]
+    ['0x05' OPERATIONAL]
+    ['0x7f' PRE_OPERATIONAL]
+]
+
+[discriminatedType 'CANOpenPayload' [CANOpenService 'function']
     [typeSwitch 'function'
-        ['CANOpenService.NMT' CANOpenNetworkPayload [uint 8 'size']
-            [array int 8 'data' COUNT 'size']
+        ['CANOpenService.BROADCAST' CANOpenBroadcastPayload
+            [enum NMTStateRequest 'request']
+            [reserved uint 1 '0x0']
+            [simple uint 7 'node']
+        ]
+        ['CANOpenService.NMT' CANOpenNetworkPayload
+            [enum NMTState 'state']
         ]
     ]
 ]
\ No newline at end of file
diff --git a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/CANOpenPlcDriver.java b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/CANOpenPlcDriver.java
new file mode 100644
index 0000000..b1c6fe6
--- /dev/null
+++ b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/CANOpenPlcDriver.java
@@ -0,0 +1,102 @@
+/*
+ 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.can;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import org.apache.plc4x.java.can.configuration.CANConfiguration;
+import org.apache.plc4x.java.can.context.CANDriverContext;
+import org.apache.plc4x.java.can.field.CANFieldHandler;
+import org.apache.plc4x.java.can.protocol.CANOpenProtocolLogic;
+import org.apache.plc4x.java.can.protocol.CANProtocolLogic;
+import org.apache.plc4x.java.socketcan.readwrite.SocketCANFrame;
+import org.apache.plc4x.java.socketcan.readwrite.io.SocketCANFrameIO;
+import org.apache.plc4x.java.spi.configuration.Configuration;
+import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
+import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
+import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
+import tel.schich.javacan.CanFrame;
+
+import java.util.function.Consumer;
+import java.util.function.ToIntFunction;
+
+/**
+ */
+public class CANOpenPlcDriver extends GeneratedDriverBase<SocketCANFrame> {
+
+    @Override
+    public String getProtocolCode() {
+        return "can";
+    }
+
+    @Override
+    public String getProtocolName() {
+        return "Controller Area Network";
+    }
+
+    @Override
+    protected Class<? extends Configuration> getConfigurationType() {
+        return CANConfiguration.class;
+    }
+
+    @Override
+    protected String getDefaultTransport() {
+        return "javacan";
+    }
+
+    @Override
+    protected CANFieldHandler getFieldHandler() {
+        return new CANFieldHandler();
+    }
+
+    @Override
+    protected ProtocolStackConfigurer<SocketCANFrame> getStackConfigurer() {
+        return SingleProtocolStackConfigurer.builder(SocketCANFrame.class, SocketCANFrameIO.class)
+            .withProtocol(CANOpenProtocolLogic.class)
+            .withDriverContext(CANDriverContext.class)
+            .withPacketSizeEstimator(CANEstimator.class)
+            .build();
+    }
+
+    public static class CANEstimator implements ToIntFunction<ByteBuf> {
+        @Override
+        public int applyAsInt(ByteBuf byteBuf) {
+            if (byteBuf.readableBytes() >= 5) {
+
+                System.out.println(ByteBufUtil.prettyHexDump(byteBuf));
+                byte len = byteBuf.getByte(4);
+                System.out.println("Length " + (int) len);
+
+                CanFrame frame = CanFrame.create(byteBuf.nioBuffer());
+                System.out.println(frame);
+
+                return len + 8 /* overhead */;
+            }
+            return -1; //discard
+        }
+    }
+
+    public class CANCleaner implements Consumer<ByteBuf> {
+        @Override
+        public void accept(ByteBuf byteBuf) {
+            System.out.println("Discard");
+            byteBuf.readByte();
+        }
+    }
+}
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
new file mode 100644
index 0000000..e6f18ca
--- /dev/null
+++ b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/protocol/CANOpenProtocolLogic.java
@@ -0,0 +1,62 @@
+/*
+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.can.protocol;
+
+import org.apache.plc4x.java.canopen.readwrite.CANOpenPayload;
+import org.apache.plc4x.java.canopen.readwrite.io.CANOpenPayloadIO;
+import org.apache.plc4x.java.canopen.readwrite.types.CANOpenService;
+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.generation.ReadBuffer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CANOpenProtocolLogic extends Plc4xProtocolBase<SocketCANFrame> {
+
+    private Logger logger = LoggerFactory.getLogger(CANOpenProtocolLogic.class);
+
+    @Override
+    public void onConnect(ConversationContext<SocketCANFrame> context) {
+        context.fireConnected();
+    }
+
+    @Override
+    protected void decode(ConversationContext<SocketCANFrame> context, SocketCANFrame msg) throws Exception {
+        logger.info("Decode CAN message {}", msg);
+
+        int identifier = msg.getIdentifier();
+        CANOpenService service = CANOpenService.valueOf((byte) (identifier >> 7));
+        if (service != null) {
+            ReadBuffer buffer = new ReadBuffer(msg.getData());
+            CANOpenPayload payload = CANOpenPayloadIO.staticParse(buffer, service);
+        }
+    }
+
+    @Override
+    public void close(ConversationContext<SocketCANFrame> context) {
+
+    }
+
+    @Override
+    public void onDisconnect(ConversationContext<SocketCANFrame> context) {
+
+    }
+
+}
diff --git a/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/CANOpenTest.java b/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/CANOpenPayloadTest.java
similarity index 84%
rename from sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/CANOpenTest.java
rename to sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/CANOpenPayloadTest.java
index a97a1eb..8af4f2b 100644
--- a/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/CANOpenTest.java
+++ b/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/CANOpenPayloadTest.java
@@ -21,10 +21,10 @@ package org.apache.plc4x.java.can;
 
 import org.apache.plc4x.test.parserserializer.ParserSerializerTestsuiteRunner;
 
-public class CANOpenTest extends ParserSerializerTestsuiteRunner {
+public class CANOpenPayloadTest extends ParserSerializerTestsuiteRunner {
 
-    public CANOpenTest() {
-        super("/testsuite/CANOpenTestSuite.xml");
+    public CANOpenPayloadTest() {
+        super("/testsuite/CANOpenPayloadTestSuite.xml");
     }
 
 }
diff --git a/sandbox/test-java-can-driver/src/test/resources/testsuite/CANOpenTestSuite.xml b/sandbox/test-java-can-driver/src/test/resources/testsuite/CANOpenPayloadTestSuite.xml
similarity index 85%
rename from sandbox/test-java-can-driver/src/test/resources/testsuite/CANOpenTestSuite.xml
rename to sandbox/test-java-can-driver/src/test/resources/testsuite/CANOpenPayloadTestSuite.xml
index b99128d..b5676d9 100644
--- a/sandbox/test-java-can-driver/src/test/resources/testsuite/CANOpenTestSuite.xml
+++ b/sandbox/test-java-can-driver/src/test/resources/testsuite/CANOpenPayloadTestSuite.xml
@@ -22,11 +22,14 @@
   <name>Tests of socketcan/CANopen frames.</name>
 
   <testcase>
-    <name>Network heartbeat frame: 728#05</name>
-    <raw>280700000100000005</raw>
-    <root-type>CANOpenFrame</root-type>
+    <name>Network heartbeat payload: 0000</name>
+    <raw>0000</raw>
+    <root-type>CANOpenPayload</root-type>
+    <parser-arguments>
+      <arg1>NMT</arg1>
+    </parser-arguments>
     <xml>
-      <SocketCANFrame className="org.apache.plc4x.java.canopen.readwrite.CANOpenFrame">
+      <SocketCANFrame className="org.apache.plc4x.java.canopen.readwrite.CANOpenPayload">
         <function>15</function>
         <identifier>5</identifier>
         <extended>false</extended>