diff --git a/java_console/.idea/libraries/javacan_core.xml b/java_console/.idea/libraries/javacan_core.xml new file mode 100644 index 0000000000..efa4e797f8 --- /dev/null +++ b/java_console/.idea/libraries/javacan_core.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java_console/.idea/runConfigurations/Launcher_socketcan_connector.xml b/java_console/.idea/runConfigurations/Launcher_socketcan_connector.xml new file mode 100644 index 0000000000..b425983c49 --- /dev/null +++ b/java_console/.idea/runConfigurations/Launcher_socketcan_connector.xml @@ -0,0 +1,11 @@ + + + + \ No newline at end of file diff --git a/java_console/build.xml b/java_console/build.xml index d8d5c920d1..e99c9fd286 100644 --- a/java_console/build.xml +++ b/java_console/build.xml @@ -3,6 +3,7 @@ + lib/mockito-all-1.10.19.jar ../java_tools/configuration_definition/lib/snakeyaml.jar @@ -31,8 +32,10 @@ lib/miglayout-4.0.jar lib/surfaceplotter-2.0.1.jar ../java_tools/configuration_definition/lib/antlr-4.9.3-complete.jar + lib/javacan-core.jar + @@ -201,6 +204,10 @@ + + + + diff --git a/java_console/io/build.gradle b/java_console/io/build.gradle index 2ab8d0a091..1db55d5cca 100644 --- a/java_console/io/build.gradle +++ b/java_console/io/build.gradle @@ -22,6 +22,7 @@ dependencies { implementation project(':logging') implementation group: 'com.fazecast', name: 'jSerialComm', version: '2.9.0' + implementation group: 'tel.schich', name: 'javacan-core', version: '3.2.0' implementation group: 'net.jcip', name: 'jcip-annotations', version: '1.0' implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1' implementation group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.12' diff --git a/java_console/io/io.iml b/java_console/io/io.iml index 1dcb215c5a..61dae13d6f 100644 --- a/java_console/io/io.iml +++ b/java_console/io/io.iml @@ -17,5 +17,6 @@ + \ No newline at end of file diff --git a/java_console/io/src/main/java/com/rusefi/io/stream/SocketCANIoStream.java b/java_console/io/src/main/java/com/rusefi/io/stream/SocketCANIoStream.java new file mode 100644 index 0000000000..c642f80728 --- /dev/null +++ b/java_console/io/src/main/java/com/rusefi/io/stream/SocketCANIoStream.java @@ -0,0 +1,112 @@ +package com.rusefi.io.stream; + +import com.devexperts.logging.Logging; +import com.opensr5.io.DataListener; +import com.rusefi.binaryprotocol.IncomingDataBuffer; +import com.rusefi.config.generated.Fields; +import com.rusefi.io.IoStream; +import com.rusefi.io.can.IsoTpCanDecoder; +import com.rusefi.io.can.IsoTpConnector; +import com.rusefi.io.serial.AbstractIoStream; +import com.rusefi.io.tcp.BinaryProtocolServer; +import org.jetbrains.annotations.Nullable; +import tel.schich.javacan.CanChannels; +import tel.schich.javacan.CanFrame; +import tel.schich.javacan.NetworkDevice; +import tel.schich.javacan.RawCanChannel; + +import java.io.IOException; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +import static com.devexperts.logging.Logging.getLogging; +import static com.rusefi.config.generated.Fields.CAN_ECU_SERIAL_TX_ID; +import static tel.schich.javacan.CanFrame.FD_NO_FLAGS; +import static tel.schich.javacan.CanSocketOptions.RECV_OWN_MSGS; + +public class SocketCANIoStream extends AbstractIoStream { + static Logging log = getLogging(SocketCANIoStream.class); + private final IncomingDataBuffer dataBuffer; + private final RawCanChannel socket; + + private final IsoTpCanDecoder canDecoder = new IsoTpCanDecoder(); + + private final IsoTpConnector isoTpConnector = new IsoTpConnector() { + @Override + public void sendCanData(byte[] hdr, byte[] data, int dataOffset, int dataLength) { + byte[] total = combineArrays(hdr, data, dataOffset, dataLength); + + log.info("-------sendIsoTp " + total.length + " byte(s):"); + + log.info("Sending " + IoStream.printHexBinary(total)); + + CanFrame packet = CanFrame.create(Fields.CAN_ECU_SERIAL_RX_ID, FD_NO_FLAGS, total); + try { + socket.write(packet); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + @Override + public void receiveData() { + } + }; + + public SocketCANIoStream() { + try { + NetworkDevice canInterface = NetworkDevice.lookup("can0"); + socket = CanChannels.newRawChannel(); + socket.bind(canInterface); + + socket.configureBlocking(true); // we want reader thread to wait for messages + socket.setOption(RECV_OWN_MSGS, true); + } catch (IOException e) { + throw new IllegalStateException("Error looking up", e); + } + // buffer could only be created once socket variable is not null due to callback + dataBuffer = createDataBuffer("[SocketCAN] "); + } + + @Nullable + public static SocketCANIoStream create() { + return new SocketCANIoStream(); + } + + @Override + public void write(byte[] bytes) throws IOException { + IsoTpConnector.sendStrategy(bytes, isoTpConnector); + } + + @Override + public void setInputListener(DataListener listener) { + Executor threadExecutor = Executors.newSingleThreadExecutor(BinaryProtocolServer.getThreadFactory("SocketCAN reader")); + threadExecutor.execute(() -> { + while (!isClosed()) { + readOnePacket(listener); + } + }); + } + + private void readOnePacket(DataListener listener) { + try { + CanFrame rx = socket.read(); + log.info("GOT " + rx); + if (rx.getId() != CAN_ECU_SERIAL_TX_ID) { + log.info("Skipping non " + CAN_ECU_SERIAL_TX_ID + " packet"); + return; + } + byte[] raw = new byte[rx.getDataLength()]; + rx.getData(raw, 0, raw.length); + byte[] decode = canDecoder.decodePacket(raw); + listener.onDataArrived(decode); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + @Override + public IncomingDataBuffer getDataBuffer() { + return dataBuffer; + } +} diff --git a/java_console/io/src/test/java/com/rusefi/binaryprotocol/test/PCanSandbox.java b/java_console/io/src/test/java/com/rusefi/binaryprotocol/test/PCanSandbox.java index 44e90bee31..76ce667a75 100644 --- a/java_console/io/src/test/java/com/rusefi/binaryprotocol/test/PCanSandbox.java +++ b/java_console/io/src/test/java/com/rusefi/binaryprotocol/test/PCanSandbox.java @@ -3,7 +3,6 @@ package com.rusefi.binaryprotocol.test; import com.devexperts.logging.Logging; import com.opensr5.ConfigurationImage; import com.rusefi.binaryprotocol.BinaryProtocol; -import com.rusefi.config.generated.Fields; import com.rusefi.io.LinkManager; import com.rusefi.io.serial.AbstractIoStream; import com.rusefi.io.stream.PCanIoStream; @@ -42,12 +41,9 @@ public class PCanSandbox { */ BinaryProtocol bp = new BinaryProtocol(linkManager, tsStream); - linkManager.submit(new Runnable() { - @Override - public void run() { - boolean response = bp.requestOutputChannels(); - log.info("requestOutputChannels " + response); - } + linkManager.submit(() -> { + boolean response = bp.requestOutputChannels(); + log.info("requestOutputChannels " + response); }); ConfigurationImage ci = SandboxCommon.readImage(tsStream, linkManager); diff --git a/java_console/io/src/test/java/com/rusefi/binaryprotocol/test/SocketCANSandbox.java b/java_console/io/src/test/java/com/rusefi/binaryprotocol/test/SocketCANSandbox.java new file mode 100644 index 0000000000..04f52f9432 --- /dev/null +++ b/java_console/io/src/test/java/com/rusefi/binaryprotocol/test/SocketCANSandbox.java @@ -0,0 +1,52 @@ +package com.rusefi.binaryprotocol.test; + +import com.devexperts.logging.Logging; +import com.opensr5.ConfigurationImage; +import com.rusefi.binaryprotocol.BinaryProtocol; +import com.rusefi.io.LinkManager; +import com.rusefi.io.serial.AbstractIoStream; +import com.rusefi.io.stream.SocketCANIoStream; + +import java.io.IOException; + +import static com.devexperts.logging.Logging.getLogging; + +public class SocketCANSandbox { + private static final Logging log = getLogging(PCanSandbox.class); + + public static void main(String[] args) throws IOException, InterruptedException { + AbstractIoStream tsStream = SocketCANIoStream.create(); + if (tsStream == null) + throw new IOException("No SocketCAN"); + +/* + for (int i = 0; i < 17; i++) { + String signature = BinaryProtocol.getSignature(tsStream); + System.out.println("Got " + i + " " + signature + " signature via PCAN"); + if (signature == null || !signature.startsWith(Fields.PROTOCOL_SIGNATURE_PREFIX)) + throw new IllegalStateException("Unexpected S " + signature); + } + log.info("****************************************"); + log.info("****** SocketCAN LOOKS GREAT *********"); + log.info("****************************************"); +*/ + LinkManager linkManager = new LinkManager(); +/* + for (int i = 0; i < 4; i++) { + SandboxCommon.verifyCrcNoPending(tsStream, linkManager); + } +*/ + + BinaryProtocol bp = new BinaryProtocol(linkManager, tsStream); + linkManager.submit(() -> { + boolean response = bp.requestOutputChannels(); + log.info("requestOutputChannels " + response); + }); + + ConfigurationImage ci = SandboxCommon.readImage(tsStream, linkManager); + log.info("Got ConfigurationImage " + ci); + +// System.out.println("We are done"); +// System.exit(0); + } +} diff --git a/java_console/lib/JavaCAN-javacan.zip b/java_console/lib/JavaCAN-javacan.zip new file mode 100644 index 0000000000..5b5cd390b5 Binary files /dev/null and b/java_console/lib/JavaCAN-javacan.zip differ diff --git a/java_console/lib/javacan-core-x86_64.jar b/java_console/lib/javacan-core-x86_64.jar new file mode 100644 index 0000000000..163777ff40 Binary files /dev/null and b/java_console/lib/javacan-core-x86_64.jar differ diff --git a/java_console/lib/javacan-core.jar b/java_console/lib/javacan-core.jar new file mode 100644 index 0000000000..01965bcd13 Binary files /dev/null and b/java_console/lib/javacan-core.jar differ diff --git a/java_console/lib/slf4j-api.jar b/java_console/lib/slf4j-api.jar new file mode 100644 index 0000000000..7d3ce68d25 Binary files /dev/null and b/java_console/lib/slf4j-api.jar differ diff --git a/java_console/lib/slf4j-simple.jar b/java_console/lib/slf4j-simple.jar new file mode 100644 index 0000000000..ef831a8a33 Binary files /dev/null and b/java_console/lib/slf4j-simple.jar differ diff --git a/java_tools/ts_plugin/build.xml b/java_tools/ts_plugin/build.xml index 149f38351a..721dff5d68 100644 --- a/java_tools/ts_plugin/build.xml +++ b/java_tools/ts_plugin/build.xml @@ -11,9 +11,16 @@ + + lib/mockito-all-1.10.19.jar + ${console_path}/../java_tools/configuration_definition/lib/snakeyaml.jar + ${console_path}/lib/javacan-core.jar + + + @@ -55,6 +62,7 @@ +