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 @@
+