diff --git a/java_console/PCANBasic.dll b/java_console/PCANBasic.dll new file mode 100644 index 0000000000..abbe45033b Binary files /dev/null and b/java_console/PCANBasic.dll differ diff --git a/java_console/PCANBasic_JNI.dll b/java_console/PCANBasic_JNI.dll new file mode 100644 index 0000000000..bd64adf6e3 Binary files /dev/null and b/java_console/PCANBasic_JNI.dll differ diff --git a/java_console/io/src/main/java/com/opensr5/io/DataListener.java b/java_console/io/src/main/java/com/opensr5/io/DataListener.java index db0b4d7ef8..2ea939351b 100644 --- a/java_console/io/src/main/java/com/opensr5/io/DataListener.java +++ b/java_console/io/src/main/java/com/opensr5/io/DataListener.java @@ -5,5 +5,5 @@ package com.opensr5.io; * 3/3/14 */ public interface DataListener { - void onDataArrived(byte freshData[]); + void onDataArrived(byte[] freshData); } diff --git a/java_console/io/src/main/java/com/rusefi/binaryprotocol/IncomingDataBuffer.java b/java_console/io/src/main/java/com/rusefi/binaryprotocol/IncomingDataBuffer.java index 9516c37633..b18fa36cd8 100644 --- a/java_console/io/src/main/java/com/rusefi/binaryprotocol/IncomingDataBuffer.java +++ b/java_console/io/src/main/java/com/rusefi/binaryprotocol/IncomingDataBuffer.java @@ -26,6 +26,10 @@ import static com.rusefi.binaryprotocol.IoHelper.*; public class IncomingDataBuffer { private static final Logging log = getLogging(IoStream.class); + static { + log.configureDebugEnabled(false); + } + private static final int BUFFER_SIZE = 32768; private static String loggingPrefix; /** @@ -98,7 +102,6 @@ public class IncomingDataBuffer { } public void addData(byte[] freshData) { - //log.info("IncomingDataBuffer: " + freshData.length + " byte(s) arrived"); synchronized (cbb) { if (cbb.size() - cbb.length() < freshData.length) { log.error("IncomingDataBuffer: buffer overflow not expected"); @@ -107,6 +110,8 @@ public class IncomingDataBuffer { cbb.put(freshData); cbb.notifyAll(); } + if (log.debugEnabled()) + log.debug("IncomingDataBuffer: " + freshData.length + " byte(s) arrived, total " + cbb.length()); } /** diff --git a/java_console/io/src/main/java/com/rusefi/io/can/IsoTpCanDecoder.java b/java_console/io/src/main/java/com/rusefi/io/can/IsoTpCanDecoder.java index e87cc53fb5..a15e8d6c4a 100644 --- a/java_console/io/src/main/java/com/rusefi/io/can/IsoTpCanDecoder.java +++ b/java_console/io/src/main/java/com/rusefi/io/can/IsoTpCanDecoder.java @@ -44,6 +44,7 @@ public class IsoTpCanDecoder { numBytesAvailable = Math.min(this.waitingForNumBytes, 6); waitingForNumBytes -= numBytesAvailable; dataOffset = 2; + onTpFirstFrame(); break; case ISO_TP_FRAME_CONSECUTIVE: frameIdx = data[0] & 0xf; @@ -72,4 +73,7 @@ public class IsoTpCanDecoder { log.debug(numBytesAvailable + " bytes(s) arrived in this packet: " + IoStream.printByteArray(bytes)); return bytes; } + + protected void onTpFirstFrame() { + } } diff --git a/java_console/io/src/main/java/com/rusefi/io/can/IsoTpConnector.java b/java_console/io/src/main/java/com/rusefi/io/can/IsoTpConnector.java index e07f023add..dcd68ae7cc 100644 --- a/java_console/io/src/main/java/com/rusefi/io/can/IsoTpConnector.java +++ b/java_console/io/src/main/java/com/rusefi/io/can/IsoTpConnector.java @@ -1,16 +1,16 @@ package com.rusefi.io.can; import com.devexperts.logging.Logging; +import com.rusefi.io.IoStream; public abstract class IsoTpConnector { private final static Logging log = Logging.getLogging(Elm327Connector.class); public static void sendStrategy(byte[] bytes, IsoTpConnector connector) { - log.info("-------sendBytesToSerial " + bytes.length + " byte(s):"); + log.info("-------sendBytesToCan " + bytes.length + " byte(s):"); + + System.out.println(IoStream.printHexBinary(bytes)); - for (int i = 0; i < bytes.length; i++) { - log.info("[index=" + i + "] " + ((int) bytes[i] & 0xff)); - } // 1 frame if (bytes.length <= 7) { diff --git a/java_console/io/src/test/java/com/rusefi/binaryprotocol/test/Elm327Sandbox.java b/java_console/io/src/test/java/com/rusefi/binaryprotocol/test/Elm327Sandbox.java index b7429a5533..a4b20fba08 100644 --- a/java_console/io/src/test/java/com/rusefi/binaryprotocol/test/Elm327Sandbox.java +++ b/java_console/io/src/test/java/com/rusefi/binaryprotocol/test/Elm327Sandbox.java @@ -65,9 +65,9 @@ public class Elm327Sandbox { } Elm327Connector.whyDoWeNeedToSleepBetweenCommands(); - System.out.println("***********************************"); - System.out.println("***** LOOKS GREAT ************"); - System.out.println("***********************************"); + System.out.println("****************************************"); + System.out.println("******** ELM327 LOOKS GREAT **********"); + System.out.println("****************************************"); System.exit(-1); /* diff --git a/java_console/io/src/test/java/com/rusefi/binaryprotocol/test/PCanIoStream.java b/java_console/io/src/test/java/com/rusefi/binaryprotocol/test/PCanIoStream.java new file mode 100644 index 0000000000..ba23403989 --- /dev/null +++ b/java_console/io/src/test/java/com/rusefi/binaryprotocol/test/PCanIoStream.java @@ -0,0 +1,104 @@ +package com.rusefi.binaryprotocol.test; + +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 peak.can.basic.PCANBasic; +import peak.can.basic.TPCANMsg; +import peak.can.basic.TPCANStatus; + +import java.io.IOException; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +import static peak.can.basic.TPCANMessageType.PCAN_MESSAGE_STANDARD; + +public class PCanIoStream extends AbstractIoStream { + private final IncomingDataBuffer dataBuffer; + private final PCANBasic can; + private final IsoTpCanDecoder canDecoder = new IsoTpCanDecoder() { + @Override + protected void onTpFirstFrame() { + sendCanPacket(new byte[]{0x30, 0, 0, 0, 0, 0, 0, 0}); + } + }; + + private final IsoTpConnector isoTpConnector = new IsoTpConnector() { + @Override + public void sendCanData(byte[] hdr, byte[] data, int offset, int len) { + byte[] total = new byte[hdr.length + len]; + System.arraycopy(hdr, 0, total, 0, hdr.length); + System.arraycopy(data, offset, total, hdr.length, len); + + log.info("-------sendIsoTp " + total.length + " byte(s):"); + + System.out.println(IoStream.printHexBinary(total)); + + sendCanPacket(total); + } + + @Override + public void receiveData() { + System.out.println("empty receiveData"); + } + }; + + private void sendCanPacket(byte[] payLoad) { + TPCANMsg msg = new TPCANMsg(Fields.CAN_ECU_SERIAL_RX_ID, PCAN_MESSAGE_STANDARD.getValue(), + (byte) payLoad.length, payLoad); + TPCANStatus status = can.Write(PCanSandbox.CHANNEL, msg); + if (status != TPCANStatus.PCAN_ERROR_OK) { + System.out.println("Unable to write the CAN message: " + status); + System.exit(0); + } +// System.out.println("Send OK! length=" + payLoad.length); + } + + private DataListener listener; + + public PCanIoStream(PCANBasic can) { + this.can = can; + this.dataBuffer = IncomingDataBuffer.createDataBuffer("", this); + } + + @Override + public void write(byte[] bytes) throws IOException { + IsoTpConnector.sendStrategy(bytes, isoTpConnector); + } + + @Override + public void setInputListener(DataListener listener) { + this.listener = listener; + Executor threadExecutor = Executors.newSingleThreadExecutor(BinaryProtocolServer.getThreadFactory("PCAN reader")); + threadExecutor.execute(() -> { + while (!isClosed()) { + readOnePacket(); + } + }); + } + + public void readOnePacket() { + // todo: can we reuse instance? + TPCANMsg rx = new TPCANMsg(); + TPCANStatus status = can.Read(PCanSandbox.CHANNEL, rx, null); + if (status == TPCANStatus.PCAN_ERROR_OK) { + System.out.println(rx + " id=" + rx.getID() + " len=" + rx.getLength() + ": " + IoStream.printByteArray(rx.getData())); + byte[] decode = canDecoder.decodePacket(rx.getData()); + listener.onDataArrived(decode); + + System.out.println("Decoded " + IoStream.printByteArray(decode)); + } else { +// System.out.println(new Date() + ": Receive " + status); + } + } + + @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 new file mode 100644 index 0000000000..d96558b739 --- /dev/null +++ b/java_console/io/src/test/java/com/rusefi/binaryprotocol/test/PCanSandbox.java @@ -0,0 +1,45 @@ +package com.rusefi.binaryprotocol.test; + +import com.rusefi.binaryprotocol.BinaryProtocol; +import com.rusefi.config.generated.Fields; +import peak.can.basic.*; + +import java.io.IOException; + +public class PCanSandbox { + + public static final TPCANHandle CHANNEL = TPCANHandle.PCAN_USBBUS1; + + public static void main(String[] args) throws IOException, InterruptedException { + PCANBasic can = new PCANBasic(); + can.initializeAPI(); + TPCANStatus status = can.Initialize(CHANNEL, TPCANBaudrate.PCAN_BAUD_500K, TPCANType.PCAN_TYPE_NONE, 0, (short) 0); + if (status != TPCANStatus.PCAN_ERROR_OK) { + System.out.println(status); + return; + } + System.out.println("Hello PCAN " + can); + + PCanIoStream tsStream = new PCanIoStream(can); + + + { + String signature = BinaryProtocol.getSignature(tsStream); + System.out.println("Got " + signature + " signature via PCAN"); + if (signature == null || !signature.startsWith(Fields.PROTOCOL_SIGNATURE_PREFIX)) + throw new IllegalStateException("Unexpected S " + signature); + } + + { + String signature = BinaryProtocol.getSignature(tsStream); + System.out.println("AGAIN, got " + signature + " signature via PCAN"); + if (signature == null || !signature.startsWith(Fields.PROTOCOL_SIGNATURE_PREFIX)) + throw new IllegalStateException("Unexpected S " + signature); + } + + + System.out.println("****************************************"); + System.out.println("********* PCAN LOOKS GREAT ***********"); + System.out.println("****************************************"); + } +}