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 ea86e840af619ae3b23699b3417c93038f8e200f Author: Ćukasz Dywicki <[email protected]> AuthorDate: Sat Aug 29 10:09:57 2020 +0200 Sketch of support for SDO operations. --- .../src/main/resources/protocols/can/canopen.mspec | 40 ++++++- .../apache/plc4x/java/can/CANOpenPlcDriver.java | 17 +-- .../java/can/configuration/CANConfiguration.java | 12 +++ .../java/can/protocol/CANOpenProtocolLogic.java | 58 ++++++----- .../test/java/org/apache/plc4x/java/can/Main.java | 2 +- .../testsuite/CANOpenPayloadTestSuite.xml | 115 ++++++++++++++++++++- 6 files changed, 196 insertions(+), 48 deletions(-) diff --git a/protocols/can/src/main/resources/protocols/can/canopen.mspec b/protocols/can/src/main/resources/protocols/can/canopen.mspec index 54337b4..d5160c6 100644 --- a/protocols/can/src/main/resources/protocols/can/canopen.mspec +++ b/protocols/can/src/main/resources/protocols/can/canopen.mspec @@ -18,8 +18,10 @@ */ [enum uint 4 'CANOpenService' - ['0x00' BROADCAST] - ['0x07' NMT] + ['0b0000' BROADCAST ] + ['0b1110' NMT ] + ['0b1100' SDO_REQUEST ] + ['0b1011' SDO_RESPONSE] ] [enum uint 8 'NMTStateRequest' @@ -41,11 +43,41 @@ [typeSwitch 'function' ['CANOpenService.BROADCAST' CANOpenBroadcastPayload [enum NMTStateRequest 'request'] - [reserved uint 1 '0x0'] + [reserved uint 1 '0x00'] [simple uint 7 'node'] ] ['CANOpenService.NMT' CANOpenNetworkPayload [enum NMTState 'state'] ] + ['CANOpenService.SDO_REQUEST' CANOpenSDORequest + [enum SDOCommand 'command'] + [reserved uint 1 '0x00'] + [implicit uint 2 'size' 'COUNT(data)'] + [simple bit 'expedited'] // segmented + [simple bit 'placement'] + [simple uint 16 'index'] + [simple uint 8 'subindex'] + [array uint 8 'data' COUNT 'size'] + ] + ['CANOpenService.SDO_RESPONSE' CANOpenSDOResponse + [enum SDOCommand 'command'] + [reserved uint 1 '0x00'] + [implicit uint 2 'size' 'COUNT(data)'] + [simple bit 'expedited'] // segmented + [simple bit 'placement'] + [simple uint 16 'index'] + [simple uint 8 'subindex'] + [array uint 8 'data' COUNT 'size'] + ] ] -] \ No newline at end of file +] + +[enum uint 3 'SDOCommand' + ['0x00' SEGMENT_DOWNLOAD] + ['0x01' INITIALIZE_DOWNLOAD] + ['0x02' INITIALIZE_UPLOAD] + ['0x03' SEGMENT_UPLOAD] + ['0x04' ABORT] + ['0x05' BLOCK_UPLOAD] + ['0x06' BLOCK_DOWNLOAD] +] 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 index 4255ff2..6acff67 100644 --- 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 @@ -78,25 +78,10 @@ public class CANOpenPlcDriver 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 16; // socketcan transport always returns 16 bytes padded with zeros; } 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/configuration/CANConfiguration.java b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/configuration/CANConfiguration.java index 925ca15..214794d 100644 --- a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/configuration/CANConfiguration.java +++ b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/configuration/CANConfiguration.java @@ -27,6 +27,9 @@ public class CANConfiguration implements Configuration, CANTransportConfiguratio @ConfigurationParameter private int nodeId; + @ConfigurationParameter + private boolean hearbeat; + public int getNodeId() { return nodeId; } @@ -34,4 +37,13 @@ public class CANConfiguration implements Configuration, CANTransportConfiguratio public void setNodeId(int nodeId) { this.nodeId = nodeId; } + + public boolean isHeartbeat() { + return hearbeat; + } + + public void setHearbeat(boolean hearbeat) { + this.hearbeat = hearbeat; + } + } 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 555ef92..9cc2fdb 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 @@ -45,6 +45,7 @@ public class CANOpenProtocolLogic extends Plc4xProtocolBase<SocketCANFrame> impl private CANConfiguration configuration; private RequestTransactionManager tm; + private Timer heartbeat; @Override public void setConfiguration(CANConfiguration configuration) { @@ -55,39 +56,46 @@ public class CANOpenProtocolLogic extends Plc4xProtocolBase<SocketCANFrame> impl @Override public void onConnect(ConversationContext<SocketCANFrame> context) { - CANOpenNetworkPayload state = new CANOpenNetworkPayload(NMTState.BOOTED_UP); - WriteBuffer buffer = new WriteBuffer(1); try { - CANOpenNetworkPayloadIO.staticSerialize(buffer, state); - context.sendToWire(new SocketCANFrame(cobId(CANOpenService.NMT), buffer.getData())); - context.fireConnected(); - - Timer heartbeat = new Timer(); - heartbeat.scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { - CANOpenNetworkPayload state = new CANOpenNetworkPayload(NMTState.OPERATIONAL); - WriteBuffer buffer = new WriteBuffer(1); - context.sendToWire(new SocketCANFrame(cobId(CANOpenService.NMT), buffer.getData())); - } - }, 5000, 5000); + if (configuration.isHeartbeat()) { + context.sendToWire(createFrame(new CANOpenNetworkPayload(NMTState.BOOTED_UP))); + context.fireConnected(); + + this.heartbeat = new Timer(); + this.heartbeat.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + try { + context.sendToWire(createFrame(new CANOpenNetworkPayload(NMTState.OPERATIONAL))); + } catch (ParseException e) { + e.printStackTrace(); + } + } + }, 5000, 5000); + } } catch (ParseException e) { e.printStackTrace(); } } + private SocketCANFrame createFrame(CANOpenNetworkPayload state) throws ParseException { + WriteBuffer buffer = new WriteBuffer(state.getLengthInBytes()); + CANOpenNetworkPayloadIO.staticSerialize(buffer, state); + return new SocketCANFrame(cobId(CANOpenService.NMT), buffer.getData()); + } + @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); - - - } +// 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 @@ -101,7 +109,9 @@ public class CANOpenProtocolLogic extends Plc4xProtocolBase<SocketCANFrame> impl } private int cobId(CANOpenService service) { - return service.getValue() & configuration.getNodeId(); + // form 32 bit socketcan identifier + return (configuration.getNodeId() << 24) & 0xff000000 | + (service.getValue() << 16 ) & 0x00ff0000; } } diff --git a/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/Main.java b/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/Main.java index e8279b6..8212bea 100644 --- a/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/Main.java +++ b/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/Main.java @@ -29,7 +29,7 @@ public class Main { public static void main(String[] args) throws Exception { PlcDriverManager driverManager = new PlcDriverManager(); - PlcConnection connection = driverManager.getConnection("canopen:javacan://vcan0?nodeId=15"); + PlcConnection connection = driverManager.getConnection("canopen:javacan://vcan0?nodeId=11"); } diff --git a/sandbox/test-java-can-driver/src/test/resources/testsuite/CANOpenPayloadTestSuite.xml b/sandbox/test-java-can-driver/src/test/resources/testsuite/CANOpenPayloadTestSuite.xml index 773f608..d7c1a33 100644 --- a/sandbox/test-java-can-driver/src/test/resources/testsuite/CANOpenPayloadTestSuite.xml +++ b/sandbox/test-java-can-driver/src/test/resources/testsuite/CANOpenPayloadTestSuite.xml @@ -19,10 +19,10 @@ --> <test:testsuite xmlns:test="https://plc4x.apache.org/schemas/parser-serializer-testsuite.xsd"> - <name>Tests of socketcan/CANopen frames.</name> + <name>Tests of CANopen frames payload.</name> <testcase> - <name>Network heartbeat payload: 00</name> + <name>Network heartbeat, payload: 00</name> <raw>00</raw> <root-type>CANOpenPayload</root-type> <parser-arguments> @@ -36,7 +36,7 @@ </testcase> <testcase> - <name>Network heartbeat payload: 7F</name> + <name>Network heartbeat, payload: 7F</name> <raw>7F</raw> <root-type>CANOpenPayload</root-type> <parser-arguments> @@ -49,4 +49,113 @@ </xml> </testcase> + <testcase> + <name>SDO request, payload: 4317100000000000</name> + <raw>4317100000000000</raw> + <root-type>CANOpenPayload</root-type> + <parser-arguments> + <arg1>SDO_REQUEST</arg1> + </parser-arguments> + <xml> + <CANOpenSDORequest className="org.apache.plc4x.java.canopen.readwrite.CANOpenSDORequest"> + <command>INITIALIZE_UPLOAD</command> + <expedited>true</expedited> + <placement>true</placement> + <index>4119</index> + <subindex>0</subindex> + <data/> + </CANOpenSDORequest> + </xml> + </testcase> + + <testcase> + <name>SDO request, payload: 00171000A00F0000</name> + <raw>00171000A00F0000</raw> + <root-type>CANOpenPayload</root-type> + <parser-arguments> + <arg1>SDO_REQUEST</arg1> + </parser-arguments> + <xml> + <CANOpenSDORequest className="org.apache.plc4x.java.canopen.readwrite.CANOpenSDORequest"> + <command>SEGMENT_DOWNLOAD</command> + <expedited>false</expedited> + <placement>false</placement> + <index>4119</index> + <subindex>0</subindex> + <data/> + </CANOpenSDORequest> + </xml> + </testcase> + + <testcase> + <name>SDO write request, payload: 2B171000D00F</name> + <raw>2B171000D00F</raw> + <root-type>CANOpenPayload</root-type> + <parser-arguments> + <arg1>SDO_REQUEST</arg1> + </parser-arguments> + <xml> + <CANOpenSDORequest className="org.apache.plc4x.java.canopen.readwrite.CANOpenSDORequest"> + <command>INITIALIZE_DOWNLOAD</command> + <expedited>true</expedited> + <placement>true</placement> + <index>4119</index> + <subindex>0</subindex> + <data> + <data>208</data> + <data>15</data> + </data> + </CANOpenSDORequest> + </xml> + </testcase> + + <testcase> + <name>SDO write result, payload: 60171000D0F00000</name> + <raw>00171000A00F0000</raw> + <root-type>CANOpenPayload</root-type> + <parser-arguments> + <arg1>SDO_REQUEST</arg1> + </parser-arguments> + <xml> + <CANOpenSDORequest className="org.apache.plc4x.java.canopen.readwrite.CANOpenSDORequest"> + <command>SEGMENT_DOWNLOAD</command> + <expedited>false</expedited> + <placement>false</placement> + <index>4119</index> + <subindex>0</subindex> + <data/> + </CANOpenSDORequest> + </xml> + </testcase> + + <!-- samples --> + <testcase> + <name>SDO response, payload: 6000200000</name> + <raw>6000200000</raw> + <root-type>CANOpenPayload</root-type> + <parser-arguments> + <arg1>SDO_RESPONSE</arg1> + </parser-arguments> + <xml> + <CANOpenNetworkPayload className="org.apache.plc4x.java.canopen.readwrite.CANOpenNetworkPayload"> + <state>PRE_OPERATIONAL</state> + </CANOpenNetworkPayload> + </xml> + </testcase> + + <testcase> + <name>PDO, payload: 78563412</name> + <raw>78563412</raw> + <root-type>CANOpenPayload</root-type> + <parser-arguments> + <arg1>SDO_RESPONSE</arg1> + </parser-arguments> + <xml> + <CANOpenNetworkPayload className="org.apache.plc4x.java.canopen.readwrite.CANOpenNetworkPayload"> + <state>PRE_OPERATIONAL</state> + </CANOpenNetworkPayload> + </xml> + + </testcase> + </test:testsuite> \ No newline at end of file
