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:02 UTC

[plc4x] 02/21: Tests for socketcan frames + manual parsing based on ReadBuffer api.

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 7447def9596ef3b5dba457e3065ce2f6828446c7
Author: Ɓukasz Dywicki <lu...@code-house.org>
AuthorDate: Thu Aug 20 21:46:34 2020 +0200

    Tests for socketcan frames + manual parsing based on ReadBuffer api.
---
 .../can/src/main/resources/protocols/can/can.mspec | 71 ++++++++++-------
 .../org/apache/plc4x/java/can/CANPlcDriver.java    | 10 +--
 .../apache/plc4x/java/can/helper/HeaderParser.java | 44 +++++++++++
 .../apache/plc4x/java/can/ManualParserTest.java    | 92 ++++++++++++++++++++++
 .../org/apache/plc4x/java/can/SocketCANTest.java   | 30 +++++++
 .../resources/testsuite/SocketCANTestSuite.xml     | 54 +++++++++++++
 6 files changed, 267 insertions(+), 34 deletions(-)

diff --git a/protocols/can/src/main/resources/protocols/can/can.mspec b/protocols/can/src/main/resources/protocols/can/can.mspec
index bbee418..113e304 100644
--- a/protocols/can/src/main/resources/protocols/can/can.mspec
+++ b/protocols/can/src/main/resources/protocols/can/can.mspec
@@ -18,22 +18,19 @@
  */
 
 [type 'CANFrame'
+    [simple CANHeader 'header']
     [simple uint 11 'identifier']
-    [simple bit 'remoteTransmissionRequest']
-    [discriminator bit 'extended']
-    [typeSwitch 'extended'
-        ['false' CANDataFrame
-            [reserved uint 1 '0x0']
-        ]
-        ['true' ExtendedCANFrame
-            [simple uint 18 'extensionId']
-            [simple bit 'extensionRemoteTransmissionRequest']
-            [reserved uint 2 '0x0']
-        ]
-    ]
-    [simple uint 4 'length']
-    [array uint 8 'data' count 'length']
-    [simple uint 15 'crc']
+    [simple bit 'extended']
+    [simple bit 'remote']
+    [simple bit 'error']
+]
+
+[type 'CANHeader'
+    [simple uint 11 'identifier']
+    [simple bit 'extended']
+    [simple bit 'remote']
+    [simple bit 'error']
+
 ]
 
 /* These are structures defined in linux kernel, provided here just for information purposes
@@ -55,23 +52,39 @@ struct canfd_frame {
 };
 */
 
+[type 'OtherSocketCANFrame'
+    [simple int 32 'rawId']
+    [virtual bit 'extended'
+        'STATIC_CALL("org.apache.plc4x.java.can.helper.HeaderParser.isRemote", rawId)'
+    ]
+    [virtual bit 'remote'
+        'STATIC_CALL("org.apache.plc4x.java.can.helper.HeaderParser.isRemote", rawId)'
+    ]
+    [virtual bit 'error'
+        'STATIC_CALL("org.apache.plc4x.java.can.helper.HeaderParser.isError", rawId)'
+    ]
+//    [typeSwitch 'extended'
+//        ['true' ExtendedOtherSocketCanFrame
+//            [simple uint 8 'flags']
+//        ]
+//        ['false' ExtendedOtherSocketCanFrame
+            [reserved uint 8 '0x0']
+//        ]
+//    ]
+    [reserved uint 8 '0x0']
+    [reserved uint 8 '0x0']
+    [implicit uint 8 'size' 'COUNT(data)']
+    [array int 8 'data' COUNT 'size']
+]
+
 [type 'SocketCANFrame'
-    [simple uint 29 'identifier']
     [simple bit 'extended']
     [simple bit 'remote']
     [simple bit 'error']
-    [implicit uint 8 'length' 'ARRAY_SIZE_IN_BYTES(data)']
-    [typeSwitch 'extended', 'identifier'
-        ['true' SocketCANFDFrame
-            [simple uint 8 'flags']
-            [reserved uint 8 '0x0']
-            [reserved uint 8 '0x0']
-        ]
-        ['false' ScoketCANFrame
-            [reserved uint 8 '0x0']
-            [reserved uint 8 '0x0']
-            [reserved uint 8 '0x0']
-        ]
-    ]
+    [simple uint 29 'identifier']
+    [implicit uint 8 'length' 'COUNT(data)']
+    [reserved uint 8 '0x0'] // flags
+    [reserved uint 8 '0x0'] // padding
+    [reserved uint 8 '0x0'] // padding
     [array int 8 'data' COUNT 'length']
 ]
diff --git a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/CANPlcDriver.java b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/CANPlcDriver.java
index 4b7eb16..e1a55ed 100644
--- a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/CANPlcDriver.java
+++ b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/CANPlcDriver.java
@@ -20,22 +20,17 @@ package org.apache.plc4x.java.can;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufUtil;
-import org.apache.plc4x.java.PlcDriverManager;
-import org.apache.plc4x.java.api.PlcConnection;
 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.CANProtocolLogic;
-import org.apache.plc4x.java.can.readwrite.CANFrame;
 import org.apache.plc4x.java.can.readwrite.SocketCANFrame;
-import org.apache.plc4x.java.can.readwrite.io.CANFrameIO;
 import org.apache.plc4x.java.can.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 tel.schich.javacan.CanId;
 
 import java.util.function.Consumer;
 import java.util.function.ToIntFunction;
@@ -83,9 +78,14 @@ public class CANPlcDriver extends GeneratedDriverBase<SocketCANFrame> {
         @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
diff --git a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/helper/HeaderParser.java b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/helper/HeaderParser.java
new file mode 100644
index 0000000..3ce7f0f
--- /dev/null
+++ b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/helper/HeaderParser.java
@@ -0,0 +1,44 @@
+package org.apache.plc4x.java.can.helper;
+
+import org.apache.plc4x.java.can.readwrite.SocketCANFrame;
+import org.apache.plc4x.java.spi.generation.ParseException;
+import org.apache.plc4x.java.spi.generation.ReadBuffer;
+import org.apache.plc4x.java.spi.generation.WriteBuffer;
+
+public class HeaderParser {
+
+    public static final int EXTENDED_FRAME_FORMAT_FLAG = 0x80000000;
+
+    public static final int REMOTE_TRANSMISSION_FLAG = 0x40000000;
+
+    public static final int ERROR_FRAME_FLAG = 0x20000000;
+
+    public static final int STANDARD_FORMAT_IDENTIFIER_MASK = 0x7ff;
+
+    public static final int EXTENDED_FORMAT_IDENTIFIER_MASK = 0x1fffffff;
+
+    public static int readIdentifier(ReadBuffer buffer) throws ParseException {
+        int identifier = buffer.readInt(32);
+        if ((identifier & EXTENDED_FORMAT_IDENTIFIER_MASK) == 0) {
+            return identifier & STANDARD_FORMAT_IDENTIFIER_MASK;
+        }
+        return identifier & EXTENDED_FORMAT_IDENTIFIER_MASK;
+    }
+
+    public static void writeIdentifier(WriteBuffer buffer, SocketCANFrame frame) throws ParseException {
+
+    }
+
+    public static boolean isExtended(int identifier) {
+        return (identifier & EXTENDED_FRAME_FORMAT_FLAG) != 0;
+    }
+
+    public static boolean isRemote(int identifier) {
+        return (identifier & REMOTE_TRANSMISSION_FLAG) != 0;
+    }
+
+    public static boolean isError(int identifier) {
+        return (identifier & ERROR_FRAME_FLAG) != 0;
+    }
+
+}
diff --git a/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/ManualParserTest.java b/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/ManualParserTest.java
new file mode 100644
index 0000000..11c6ca6
--- /dev/null
+++ b/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/ManualParserTest.java
@@ -0,0 +1,92 @@
+package org.apache.plc4x.java.can;
+
+import org.apache.commons.codec.binary.Hex;
+import org.apache.plc4x.java.spi.generation.ReadBuffer;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class ManualParserTest {
+
+    public static final int EXTENDED_FRAME_FORMAT_FLAG = 0b10000000_00000000_00000000_00000000;
+    public static final int REMOTE_TRANSMISSION_FLAG = 0b01000000_00000000_00000000_00000000;
+    public static final int ERROR_FRAME_FLAG = 0b00100000_00000000_00000000_00000000;
+
+    public static final int STANDARD_FORMAT_IDENTIFIER_MASK = 0b00000000_00000000_00000111_11111111;
+    public static final int EXTENDED_FORMAT_IDENTIFIER_MASK = 0b00011111_11111111_11111111_11111111;
+
+    // cansend 5A1#11.2233.44556677.88
+    String STANDARD = "a1050000080000001122334455667788";
+
+    // cansend 1E6EC676#05.05.1F.26.C3
+    String EXTENDED = "76c66e9e0500000005051f26c3000000";
+
+    @Test
+    public void readBufferTest() throws Exception {
+        ReadBuffer buffer = new ReadBuffer(new byte[]{(byte) 0xA1, 0x05, 0x00, 0x00}, true);
+        int value = buffer.readInt(32);
+
+        assertEquals(value, 0x5A1);
+    }
+
+    @Test
+    public void standardFrameParser() throws Exception {
+        SocketCanFrameStub frame = parse(STANDARD);
+        //System.out.println(frame);
+
+        assertEquals(frame.id, 0x5A1);
+        assertEquals(frame.extended, false);
+        assertEquals(frame.remote, false);
+        assertEquals(frame.error, false);
+        assertEquals(frame.data.length, 8);
+    }
+
+    @Test
+    public void extendedFrameParser() throws Exception {
+        SocketCanFrameStub frame = parse(EXTENDED);
+        //System.out.println(frame);
+
+        assertEquals(frame.id, 0x1e6ec676);
+        assertEquals(frame.extended, true);
+        assertEquals(frame.remote, false);
+        assertEquals(frame.error, false);
+        assertEquals(frame.data.length, 5);
+    }
+
+    public final static SocketCanFrameStub parse(String hex) throws Exception {
+        byte[] input = Hex.decodeHex(hex.toCharArray());
+
+        ReadBuffer readBuffer = new ReadBuffer(input, true);
+        int rawId = readBuffer.readInt(32);
+        boolean extended = (rawId & EXTENDED_FRAME_FORMAT_FLAG) != 0;
+        boolean remote = (rawId & REMOTE_TRANSMISSION_FLAG) != 0;
+        boolean error = (rawId & ERROR_FRAME_FLAG) != 0;
+        int id = extended ? (rawId & EXTENDED_FORMAT_IDENTIFIER_MASK) : (rawId & STANDARD_FORMAT_IDENTIFIER_MASK);
+        int length = readBuffer.readByte(8);
+        byte[] data = readBuffer.getBytes(8, 8 + length);
+
+        return new SocketCanFrameStub(
+            id, extended, remote, error, data
+        );
+    }
+
+    static class SocketCanFrameStub {
+        public int id;
+        public boolean extended;
+        public boolean remote;
+        public boolean error;
+        public byte[] data;
+
+        public SocketCanFrameStub(int id, boolean extended, boolean remote, boolean error, byte[] data) {
+            this.id = id;
+            this.extended = extended;
+            this.remote = remote;
+            this.error = error;
+            this.data = data;
+        }
+
+        public String toString() {
+            return "CAN Frame ID=" + Integer.toHexString(id) + ", extended=" + extended + ", remote=" + remote + ", error=" + error + ", data=" + Hex.encodeHexString(data);
+        }
+    }
+}
diff --git a/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/SocketCANTest.java b/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/SocketCANTest.java
new file mode 100644
index 0000000..270b45a
--- /dev/null
+++ b/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/SocketCANTest.java
@@ -0,0 +1,30 @@
+/*
+  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 org.apache.plc4x.test.parserserializer.ParserSerializerTestsuiteRunner;
+
+public class SocketCANTest extends ParserSerializerTestsuiteRunner {
+
+    public SocketCANTest() {
+        super("/testsuite/SocketCANTestSuite.xml");
+    }
+
+}
diff --git a/sandbox/test-java-can-driver/src/test/resources/testsuite/SocketCANTestSuite.xml b/sandbox/test-java-can-driver/src/test/resources/testsuite/SocketCANTestSuite.xml
new file mode 100644
index 0000000..774563b
--- /dev/null
+++ b/sandbox/test-java-can-driver/src/test/resources/testsuite/SocketCANTestSuite.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<test:testsuite xmlns:test="https://plc4x.apache.org/schemas/parser-serializer-testsuite.xsd">
+
+  <name>CAN Standard Format Frame</name>
+
+  <testcase>
+    <name>Extended frame 1E6EC676#05.05.1F.26.C3</name>
+    <raw>76c66e9e0500000005051f26c3000000</raw>
+    <root-type>SocketCANFrame</root-type>
+    <xml>
+      <SocketCANFDFrame className="org.apache.plc4x.java.can.readwrite.SocketCANFrame">
+        <identifier>510576246</identifier>
+        <extended>true</extended>
+        <remote>false</remote>
+        <error>true</error>
+        <data></data>
+      </SocketCANFDFrame>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>Standard frame 5A1#11.2233.44556677.88</name>
+    <raw>a1050000080000001122334455667788</raw>
+    <root-type>SocketCANFrame</root-type>
+    <xml>
+      <ScoketCANSFFrame className="org.apache.plc4x.java.can.readwrite.ScoketCANFrame">
+        <identifier>1441</identifier>
+        <extended>false</extended>
+        <remote>false</remote>
+        <error>false</error>
+        <data></data>
+      </ScoketCANSFFrame>
+    </xml>
+  </testcase>
+
+</test:testsuite>
\ No newline at end of file