diff --git a/java_console/io/src/com/rusefi/binaryprotocol/BinaryProtocol.java b/java_console/io/src/com/rusefi/binaryprotocol/BinaryProtocol.java index d7525c3667..979b2051b5 100644 --- a/java_console/io/src/com/rusefi/binaryprotocol/BinaryProtocol.java +++ b/java_console/io/src/com/rusefi/binaryprotocol/BinaryProtocol.java @@ -603,4 +603,8 @@ public class BinaryProtocol implements BinaryProtocolCommands { public void setRange(byte[] src, int scrPos, int offset, int count) { state.setRange(src, scrPos, offset, count); } + + public BinaryProtocolState getBinaryProtocolState() { + return state; + } } diff --git a/java_console/io/src/com/rusefi/io/LinkConnector.java b/java_console/io/src/com/rusefi/io/LinkConnector.java index 6698bb381d..c11fb4eea8 100644 --- a/java_console/io/src/com/rusefi/io/LinkConnector.java +++ b/java_console/io/src/com/rusefi/io/LinkConnector.java @@ -1,6 +1,8 @@ package com.rusefi.io; import com.rusefi.binaryprotocol.BinaryProtocol; +import com.rusefi.binaryprotocol.BinaryProtocolState; +import org.jetbrains.annotations.NotNull; /** * @author Andrey Belomutskiy @@ -26,6 +28,36 @@ public interface LinkConnector extends LinkDecoder { } }; + @NotNull + static LinkConnector getDetachedConnector(BinaryProtocolState state) { + return new LinkConnector() { + @Override + public BinaryProtocolState getBinaryProtocolState() { + return state; + } + + @Override + public void connectAndReadConfiguration(ConnectionStateListener listener) { + throw new UnsupportedOperationException(); + } + + @Override + public void send(String command, boolean fireEvent) { + throw new UnsupportedOperationException(); + } + + @Override + public void restart() { + throw new UnsupportedOperationException(); + } + + @Override + public BinaryProtocol getBinaryProtocol() { + throw new UnsupportedOperationException(); + } + }; + } + void connectAndReadConfiguration(ConnectionStateListener listener); void send(String command, boolean fireEvent) throws InterruptedException; @@ -33,4 +65,8 @@ public interface LinkConnector extends LinkDecoder { void restart(); BinaryProtocol getBinaryProtocol(); + + default BinaryProtocolState getBinaryProtocolState() { + return getBinaryProtocol().getBinaryProtocolState(); + } } diff --git a/java_console/io/src/com/rusefi/io/LinkManager.java b/java_console/io/src/com/rusefi/io/LinkManager.java index 94ad2d4b8b..250b9ea0e0 100644 --- a/java_console/io/src/com/rusefi/io/LinkManager.java +++ b/java_console/io/src/com/rusefi/io/LinkManager.java @@ -4,6 +4,7 @@ import com.fazecast.jSerialComm.SerialPort; import com.rusefi.FileLog; import com.rusefi.NamedThreadFactory; import com.rusefi.binaryprotocol.BinaryProtocol; +import com.rusefi.binaryprotocol.BinaryProtocolState; import com.rusefi.core.EngineState; import com.rusefi.io.serial.SerialConnector; import com.rusefi.io.tcp.TcpConnector; @@ -77,6 +78,10 @@ public class LinkManager { return connector.getBinaryProtocol(); } + public BinaryProtocolState getBinaryProtocolState() { + return connector.getBinaryProtocolState(); + } + public CommandQueue getCommandQueue() { return commandQueue; } diff --git a/java_console/io/src/com/rusefi/io/tcp/BinaryProtocolServer.java b/java_console/io/src/com/rusefi/io/tcp/BinaryProtocolServer.java index 6d4075e4a3..23a2a753c2 100644 --- a/java_console/io/src/com/rusefi/io/tcp/BinaryProtocolServer.java +++ b/java_console/io/src/com/rusefi/io/tcp/BinaryProtocolServer.java @@ -1,8 +1,9 @@ package com.rusefi.io.tcp; +import com.opensr5.ConfigurationImage; import com.rusefi.FileLog; -import com.rusefi.binaryprotocol.BinaryProtocol; import com.rusefi.binaryprotocol.BinaryProtocolCommands; +import com.rusefi.binaryprotocol.BinaryProtocolState; import com.rusefi.binaryprotocol.IoHelper; import com.rusefi.config.generated.Fields; import com.rusefi.io.LinkManager; @@ -10,10 +11,11 @@ import com.rusefi.io.LinkManager; import java.io.*; import java.net.ServerSocket; import java.net.Socket; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicInteger; import static com.rusefi.binaryprotocol.IoHelper.swap16; -import static com.rusefi.config.generated.Fields.TS_PROTOCOL; -import static com.rusefi.config.generated.Fields.TS_RESPONSE_BURN_OK; +import static com.rusefi.config.generated.Fields.*; /** * This class makes rusEfi console a proxy for other tuning software, this way we can have two tools connected via same @@ -24,18 +26,24 @@ import static com.rusefi.config.generated.Fields.TS_RESPONSE_BURN_OK; */ public class BinaryProtocolServer implements BinaryProtocolCommands { - private static final int PROXY_PORT = 2390; + private static final int DEFAULT_PROXY_PORT = 2390; private static final String TS_OK = "\0"; - public static void start(LinkManager linkManager) { - FileLog.MAIN.logLine("BinaryProtocolServer on " + PROXY_PORT); + public AtomicInteger unknownCommands = new AtomicInteger(); + + public void start(LinkManager linkManager) { + start(linkManager, DEFAULT_PROXY_PORT); + } + + public void start(LinkManager linkManager, int port) { + FileLog.MAIN.logLine("BinaryProtocolServer on " + port); Runnable runnable = new Runnable() { @SuppressWarnings("InfiniteLoopStatement") @Override public void run() { ServerSocket serverSocket; try { - serverSocket = new ServerSocket(PROXY_PORT, 1); + serverSocket = new ServerSocket(port, 1); } catch (IOException e) { FileLog.MAIN.logException("Error binding server socket", e); return; @@ -66,7 +74,7 @@ public class BinaryProtocolServer implements BinaryProtocolCommands { } @SuppressWarnings("InfiniteLoopStatement") - private static void runProxy(LinkManager linkManager, Socket clientSocket) throws IOException { + private void runProxy(LinkManager linkManager, Socket clientSocket) throws IOException { DataInputStream in = new DataInputStream(clientSocket.getInputStream()); while (true) { @@ -118,6 +126,9 @@ public class BinaryProtocolServer implements BinaryProtocolCommands { handleWrite(linkManager, packet, dis, stream); } else if (command == Fields.TS_BURN_COMMAND) { stream.sendPacket(new byte[]{TS_RESPONSE_BURN_OK}, FileLog.LOGGER); + } else if (command == Fields.TS_GET_COMPOSITE_BUFFER_DONE_DIFFERENTLY) { + // todo: relay command + stream.sendPacket(TS_OK.getBytes(), FileLog.LOGGER); } else if (command == Fields.TS_OUTPUT_COMMAND) { int offset = swap16(dis.readShort()); int count = swap16(dis.readShort()); @@ -125,14 +136,15 @@ public class BinaryProtocolServer implements BinaryProtocolCommands { byte[] response = new byte[1 + count]; response[0] = (byte) TS_OK.charAt(0); - BinaryProtocol bp = linkManager.getCurrentStreamState(); - byte[] currentOutputs = bp.getCurrentOutputs(); + BinaryProtocolState binaryProtocolState = linkManager.getBinaryProtocolState(); + byte[] currentOutputs = binaryProtocolState.getCurrentOutputs(); if (currentOutputs != null) System.arraycopy(currentOutputs, 1 + offset , response, 1, count); stream.sendPacket(response, FileLog.LOGGER); } else { + unknownCommands.incrementAndGet(); new IllegalStateException().printStackTrace(); - FileLog.MAIN.logLine("Error: unknown command " + command); + FileLog.MAIN.logLine("Error: unknown command " + (char) command + "/" + command); } } } @@ -142,7 +154,7 @@ public class BinaryProtocolServer implements BinaryProtocolCommands { int offset = swap16(dis.readShort()); int count = swap16(dis.readShort()); FileLog.MAIN.logLine("TS_CHUNK_WRITE_COMMAND: offset=" + offset + " count=" + count); - BinaryProtocol bp = linkManager.getCurrentStreamState(); + BinaryProtocolState bp = linkManager.getBinaryProtocolState(); bp.setRange(packet, 7, offset, count); stream.sendPacket(TS_OK.getBytes(), FileLog.LOGGER); } @@ -155,17 +167,20 @@ public class BinaryProtocolServer implements BinaryProtocolCommands { FileLog.MAIN.logLine("Error: negative read request " + offset + "/" + count); } else { System.out.println("read " + page + "/" + offset + "/" + count); - BinaryProtocol bp = linkManager.getCurrentStreamState(); + BinaryProtocolState bp = linkManager.getBinaryProtocolState(); byte[] response = new byte[1 + count]; response[0] = (byte) TS_OK.charAt(0); - System.arraycopy(bp.getControllerConfiguration().getContent(), offset, response, 1, count); + Objects.requireNonNull(bp, "bp"); + ConfigurationImage configurationImage = bp.getControllerConfiguration(); + Objects.requireNonNull(configurationImage, "configurationImage"); + System.arraycopy(configurationImage.getContent(), offset, response, 1, count); stream.sendPacket(response, FileLog.LOGGER); } } private static void handleCrc(LinkManager linkManager, TcpIoStream stream) throws IOException { System.out.println("CRC check"); - BinaryProtocol bp = linkManager.getCurrentStreamState(); + BinaryProtocolState bp = linkManager.getBinaryProtocolState(); byte[] content = bp.getControllerConfiguration().getContent(); int result = IoHelper.getCrc32(content); ByteArrayOutputStream response = new ByteArrayOutputStream(); diff --git a/java_console/io/src/com/rusefi/io/tcp/test/BinaryProtocolServerSandbox.java b/java_console/io/src/com/rusefi/io/tcp/test/BinaryProtocolServerSandbox.java index 4220dc090f..33d73066c4 100644 --- a/java_console/io/src/com/rusefi/io/tcp/test/BinaryProtocolServerSandbox.java +++ b/java_console/io/src/com/rusefi/io/tcp/test/BinaryProtocolServerSandbox.java @@ -1,46 +1,20 @@ package com.rusefi.io.tcp.test; import com.opensr5.ConfigurationImage; -import com.rusefi.FileLog; -import com.rusefi.binaryprotocol.BinaryProtocol; +import com.rusefi.binaryprotocol.BinaryProtocolState; import com.rusefi.config.generated.Fields; -import com.rusefi.io.ConnectionStateListener; import com.rusefi.io.LinkConnector; import com.rusefi.io.LinkManager; import com.rusefi.io.tcp.BinaryProtocolServer; -import com.rusefi.io.tcp.TcpIoStream; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; class BinaryProtocolServerSandbox { public static void main(String[] args) { + BinaryProtocolState state = new BinaryProtocolState(); + state.setController(new ConfigurationImage(new byte[Fields.TOTAL_CONFIG_SIZE])); + state.setCurrentOutputs(new byte[1 + Fields.TS_OUTPUT_SIZE]); + LinkManager linkManager = new LinkManager(); - TcpIoStream stream = new TcpIoStream(linkManager, new ByteArrayInputStream(new byte[0]), new ByteArrayOutputStream()); - BinaryProtocol bp = new BinaryProtocol(linkManager, FileLog.LOGGER, stream); - linkManager.setConnector(new LinkConnector() { - @Override - public void connectAndReadConfiguration(ConnectionStateListener listener) { - throw new UnsupportedOperationException(); - } - - @Override - public void send(String command, boolean fireEvent) throws InterruptedException { - throw new UnsupportedOperationException(); - } - - @Override - public void restart() { - throw new UnsupportedOperationException(); - } - - @Override - public BinaryProtocol getBinaryProtocol() { - return bp; - } - }); - bp.setController(new ConfigurationImage(new byte[Fields.TOTAL_CONFIG_SIZE])); - bp.setCurrentOutputs(new byte[1 + Fields.TS_OUTPUT_SIZE]); - BinaryProtocolServer.start(linkManager); + linkManager.setConnector(LinkConnector.getDetachedConnector(state)); + new BinaryProtocolServer().start(linkManager); } } \ No newline at end of file diff --git a/java_console/models/src/com/rusefi/io/test/TcpCommunicationIntegrationTest.java b/java_console/models/src/com/rusefi/io/test/TcpCommunicationIntegrationTest.java deleted file mode 100644 index ec57216843..0000000000 --- a/java_console/models/src/com/rusefi/io/test/TcpCommunicationIntegrationTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.rusefi.io.test; - -import com.opensr5.ConfigurationImage; -import com.opensr5.ini.field.ScalarIniField; -import com.rusefi.config.Field; -import com.rusefi.config.generated.Fields; -import com.rusefi.tune.xml.Constant; -import org.junit.Test; - -public class TcpCommunicationIntegrationTest { - @Test - public void testConnect() { - ConfigurationImage ci = new ConfigurationImage(Fields.TOTAL_CONFIG_SIZE); - - Field field = Fields.CYLINDERSCOUNT; - - ScalarIniField scalarIniField = new ScalarIniField(field.getName(), field.getOffset(), "", field.getType(), 1); - int input = 239; - scalarIniField.setValue(ci, new Constant(field.getName(), "", Integer.toString(input))); - - - } -} diff --git a/java_console/ui/com/rusefi/io/test/TcpCommunicationIntegrationTest.java b/java_console/ui/com/rusefi/io/test/TcpCommunicationIntegrationTest.java new file mode 100644 index 0000000000..43e266532c --- /dev/null +++ b/java_console/ui/com/rusefi/io/test/TcpCommunicationIntegrationTest.java @@ -0,0 +1,68 @@ +package com.rusefi.io.test; + +import com.opensr5.ConfigurationImage; +import com.opensr5.ini.field.ScalarIniField; +import com.rusefi.binaryprotocol.BinaryProtocolState; +import com.rusefi.config.Field; +import com.rusefi.config.generated.Fields; +import com.rusefi.io.ConnectionStateListener; +import com.rusefi.io.LinkConnector; +import com.rusefi.io.LinkManager; +import com.rusefi.io.tcp.BinaryProtocolServer; +import com.rusefi.io.tcp.TcpConnector; +import com.rusefi.tune.xml.Constant; +import org.jetbrains.annotations.NotNull; +import org.junit.Test; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertEquals; + +public class TcpCommunicationIntegrationTest { + @Test + public void testConnect() throws InterruptedException { + ConfigurationImage ci = prepareImage(239); + + int port = 6100; + + BinaryProtocolState state = new BinaryProtocolState(); + state.setController(ci); + state.setCurrentOutputs(new byte[1 + Fields.TS_OUTPUT_SIZE]); + + LinkManager linkManager = new LinkManager(); + linkManager.setConnector(LinkConnector.getDetachedConnector(state)); + BinaryProtocolServer server = new BinaryProtocolServer(); + server.start(linkManager, port); + + CountDownLatch countDownLatch = new CountDownLatch(1); + + // todo: remove CONFIGURATION_RUSEFI_BINARY or nicer API to disable local file load + + LinkManager clientManager = new LinkManager(); + clientManager.startAndConnect(Integer.toString(port), new ConnectionStateListener() { + @Override + public void onConnectionEstablished() { + countDownLatch.countDown(); + } + + @Override + public void onConnectionFailed() { + System.out.println("Failed"); + } + }); + countDownLatch.await(30, TimeUnit.SECONDS); + assertEquals(0, server.unknownCommands.get()); + } + + @NotNull + private ConfigurationImage prepareImage(int input) { + ConfigurationImage ci = new ConfigurationImage(Fields.TOTAL_CONFIG_SIZE); + + Field field = Fields.CYLINDERSCOUNT; + + ScalarIniField scalarIniField = new ScalarIniField(field.getName(), field.getOffset(), "", field.getType(), 1); + scalarIniField.setValue(ci, new Constant(field.getName(), "", Integer.toString(input))); + return ci; + } +} diff --git a/java_console/ui/src/main/java/com/rusefi/tools/ConsoleTools.java b/java_console/ui/src/main/java/com/rusefi/tools/ConsoleTools.java index 5434b10bb4..a80e8dc44b 100644 --- a/java_console/ui/src/main/java/com/rusefi/tools/ConsoleTools.java +++ b/java_console/ui/src/main/java/com/rusefi/tools/ConsoleTools.java @@ -199,7 +199,7 @@ public class ConsoleTools { linkManager.startAndConnect(autoDetectedPort, new ConnectionStateListener() { @Override public void onConnectionEstablished() { - BinaryProtocolServer.start(linkManager); + new BinaryProtocolServer().start(linkManager); } @Override diff --git a/java_console/ui/src/main/java/com/rusefi/ui/console/MainFrame.java b/java_console/ui/src/main/java/com/rusefi/ui/console/MainFrame.java index 1502bcda45..919d331f47 100644 --- a/java_console/ui/src/main/java/com/rusefi/ui/console/MainFrame.java +++ b/java_console/ui/src/main/java/com/rusefi/ui/console/MainFrame.java @@ -80,7 +80,7 @@ public class MainFrame { tabbedPane.settingsTab.showContent(); tabbedPane.logsManager.showContent(); tabbedPane.fuelTunePane.showContent(); - BinaryProtocolServer.start(linkManager); + new BinaryProtocolServer().start(linkManager); } });