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 6d69c221fe28c48e08e765cf133c48bf0c47b5e4 Author: Ćukasz Dywicki <[email protected]> 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
