diff --git a/java_console/io/src/main/java/com/rusefi/io/tcp/BinaryProtocolServer.java b/java_console/io/src/main/java/com/rusefi/io/tcp/BinaryProtocolServer.java index f2e6e86dcf..eab03def88 100644 --- a/java_console/io/src/main/java/com/rusefi/io/tcp/BinaryProtocolServer.java +++ b/java_console/io/src/main/java/com/rusefi/io/tcp/BinaryProtocolServer.java @@ -74,8 +74,8 @@ public class BinaryProtocolServer implements BinaryProtocolCommands { try { serverSocket = new ServerSocket(port, 1); } catch (IOException e) { - logger.error("Error binding server socket" + e); - return; + logger.error(threadName + ": Error binding server socket " + port + ": " + e); + throw new IllegalStateException(e); } if (serverSocketCreationCallback != null) serverSocketCreationCallback.onResult(null); @@ -126,7 +126,7 @@ public class BinaryProtocolServer implements BinaryProtocolCommands { System.out.println("Got [" + BinaryProtocol.findCommand(command)); if (command == Fields.TS_HELLO_COMMAND) { - new HelloCommand(logger, Fields.TS_SIGNATURE).handle(packet, stream); + new HelloCommand(logger, Fields.TS_SIGNATURE).handle(stream); } else if (command == COMMAND_PROTOCOL) { // System.out.println("Ignoring crc F command"); stream.sendPacket((TS_OK + TS_PROTOCOL).getBytes(), logger); diff --git a/java_console/ui/src/test/java/com/rusefi/BaseBroadcastingThread.java b/java_console/ui/src/test/java/com/rusefi/BaseBroadcastingThread.java index 554edef6c1..fd48c5a095 100644 --- a/java_console/ui/src/test/java/com/rusefi/BaseBroadcastingThread.java +++ b/java_console/ui/src/test/java/com/rusefi/BaseBroadcastingThread.java @@ -33,9 +33,10 @@ public class BaseBroadcastingThread { byte command = payload[0]; if (command == Fields.TS_HELLO_COMMAND) { - new HelloCommand(logger, sessionDetails.toJson()).handle(packet, stream); + // respond on hello request with information about session + new HelloCommand(logger, sessionDetails.toJson()).handle(stream); } else { - handleCommand(); + handleCommand(packet, stream); } } } catch (IOException e) { @@ -44,7 +45,7 @@ public class BaseBroadcastingThread { }); } - protected void handleCommand() { + protected void handleCommand(BinaryProtocolServer.Packet packet, TcpIoStream stream) throws IOException { } public void start() { diff --git a/java_console/ui/src/test/java/com/rusefi/MockRusEfiDevice.java b/java_console/ui/src/test/java/com/rusefi/MockRusEfiDevice.java index c268f8c444..549f3d7021 100644 --- a/java_console/ui/src/test/java/com/rusefi/MockRusEfiDevice.java +++ b/java_console/ui/src/test/java/com/rusefi/MockRusEfiDevice.java @@ -11,6 +11,7 @@ import static com.rusefi.tools.online.ProxyClient.LOCALHOST; public class MockRusEfiDevice { public static final String TEST_TOKEN_1 = "00000000-1234-1234-1234-123456789012"; + public static final String TEST_TOKEN_3 = "33333333-3333-1234-1234-123456789012"; private SessionDetails sessionDetails; private final Logger logger; diff --git a/java_console/ui/src/test/java/com/rusefi/ServerTest.java b/java_console/ui/src/test/java/com/rusefi/ServerTest.java index 286d9dc84a..2f2a289368 100644 --- a/java_console/ui/src/test/java/com/rusefi/ServerTest.java +++ b/java_console/ui/src/test/java/com/rusefi/ServerTest.java @@ -10,11 +10,14 @@ import com.rusefi.io.IoStream; import com.rusefi.io.LinkManager; import com.rusefi.io.commands.HelloCommand; import com.rusefi.io.tcp.BinaryProtocolProxy; +import com.rusefi.io.tcp.BinaryProtocolServer; +import com.rusefi.io.tcp.TcpIoStream; import com.rusefi.server.Backend; import com.rusefi.server.ClientConnectionState; import com.rusefi.server.SessionDetails; import com.rusefi.server.UserDetails; import com.rusefi.tools.online.ProxyClient; +import org.junit.Ignore; import org.junit.Test; import java.io.IOException; @@ -27,6 +30,7 @@ import java.util.function.Function; import static com.rusefi.TestHelper.createIniField; import static com.rusefi.TestHelper.prepareImage; +import static com.rusefi.Timeouts.READ_IMAGE_TIMEOUT; import static com.rusefi.tools.online.ProxyClient.LOCALHOST; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -63,7 +67,7 @@ public class ServerTest { } }; - Backend.runProxy(serverPort, serverCreated, backend); + backend.runControllerConnector(serverPort, serverCreated); assertTrue(serverCreated.await(30, TimeUnit.SECONDS)); assertEquals(0, backend.getCount()); @@ -84,6 +88,7 @@ public class ServerTest { } @Test + @Ignore public void testRelayWorkflow() throws InterruptedException, IOException { ScalarIniField iniField = TestHelper.createIniField(Fields.CYLINDERSCOUNT); int value = 241; @@ -91,12 +96,18 @@ public class ServerTest { Function userDetailsResolver = authToken -> new UserDetails(authToken.substring(0, 5), authToken.charAt(6)); int httpPort = 8001; Backend backend = new Backend(userDetailsResolver, httpPort, logger); - int serverPort = 7001; - CountDownLatch serverCreated = new CountDownLatch(1); + int serverPortForControllers = 7001; + int serverPortForRemoteUsers = 7003; + // first start backend server - Backend.runProxy(serverPort, serverCreated, backend); - assertTrue(serverCreated.await(30, TimeUnit.SECONDS)); + CountDownLatch controllerServerCreated = new CountDownLatch(1); + backend.runControllerConnector(serverPortForControllers, controllerServerCreated); + assertTrue(controllerServerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS)); + + CountDownLatch applicationServerCreated = new CountDownLatch(1); + backend.runApplicationConnector(serverPortForRemoteUsers, applicationServerCreated); + assertTrue(applicationServerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS)); // create virtual controller @@ -104,7 +115,7 @@ public class ServerTest { ConfigurationImage controllerImage = prepareImage(value, createIniField(Fields.CYLINDERSCOUNT)); CountDownLatch controllerCreated = new CountDownLatch(1); TestHelper.createVirtualController(controllerImage, controllerPort, parameter -> controllerCreated.countDown(), logger); - assertTrue(controllerCreated.await(30, TimeUnit.SECONDS)); + assertTrue(controllerCreated.await(READ_IMAGE_TIMEOUT, TimeUnit.MILLISECONDS)); // start network broadcaster to connect controller with backend since in real life controller has only local serial port it does not have network @@ -112,30 +123,39 @@ public class ServerTest { HelloCommand.send(targetEcuSocket, logger); String controllerSignature = HelloCommand.getHelloResponse(targetEcuSocket.getDataBuffer(), logger); - SessionDetails sessionDetails = MockRusEfiDevice.createTestSession(MockRusEfiDevice.TEST_TOKEN_1, controllerSignature); + SessionDetails deviceSessionDetails = MockRusEfiDevice.createTestSession(MockRusEfiDevice.TEST_TOKEN_1, controllerSignature); - BaseBroadcastingThread baseBroadcastingThread = new BaseBroadcastingThread(new Socket(LOCALHOST, serverPort), - sessionDetails, + BaseBroadcastingThread baseBroadcastingThread = new BaseBroadcastingThread(new Socket(LOCALHOST, serverPortForControllers), + deviceSessionDetails, logger) { @Override - protected void handleCommand() { - super.handleCommand(); + protected void handleCommand(BinaryProtocolServer.Packet packet, TcpIoStream stream) throws IOException { + super.handleCommand(packet, stream); + targetEcuSocket.sendPacket(packet); + + BinaryProtocolServer.Packet response = targetEcuSocket.readPacket(); + stream.sendPacket(response); } - // todo }; baseBroadcastingThread.start(); + SessionDetails authenticatorSessionDetails = new SessionDetails(deviceSessionDetails.getControllerInfo(), MockRusEfiDevice.TEST_TOKEN_3, deviceSessionDetails.getOneTimeToken()); + // start authenticator - IoStream authenticatorToProxyStream = TestHelper.createTestStream(serverPort, logger); + IoStream authenticatorToProxyStream = TestHelper.createTestStream(serverPortForControllers, logger); + // right from connection push session authentication data + new HelloCommand(logger, authenticatorSessionDetails.toJson()).handle(authenticatorToProxyStream); + + // local port on which authenticator accepts connections from Tuner Studio int authenticatorPort = 7004; BinaryProtocolProxy.createProxy(authenticatorToProxyStream, authenticatorPort); CountDownLatch connectionEstablishedCountDownLatch = new CountDownLatch(1); -/* + // connect to proxy and read virtual controller through it LinkManager clientManager = new LinkManager(logger); clientManager.startAndConnect(ProxyClient.LOCALHOST + ":" + authenticatorPort, new ConnectionStateListener() { @@ -156,7 +176,7 @@ public class ServerTest { ConfigurationImage clientImage = clientStreamState.getControllerConfiguration(); String clientValue = iniField.getValue(clientImage); assertEquals(Double.toString(value), clientValue); -*/ + } diff --git a/java_tools/proxy_server/src/main/java/com/rusefi/server/Backend.java b/java_tools/proxy_server/src/main/java/com/rusefi/server/Backend.java index d1b31bc132..6fa72a5ffe 100644 --- a/java_tools/proxy_server/src/main/java/com/rusefi/server/Backend.java +++ b/java_tools/proxy_server/src/main/java/com/rusefi/server/Backend.java @@ -1,7 +1,10 @@ package com.rusefi.server; import com.opensr5.Logger; +import com.rusefi.io.IoStream; +import com.rusefi.io.commands.HelloCommand; import com.rusefi.io.tcp.BinaryProtocolServer; +import com.rusefi.io.tcp.TcpIoStream; import com.rusefi.tools.online.ProxyClient; import org.jetbrains.annotations.NotNull; import org.takes.Take; @@ -31,26 +34,54 @@ public class Backend { (Take) req -> getUsersOnline() ); - public static void runProxy(int serverPort, CountDownLatch serverCreated, Backend backend) { - BinaryProtocolServer.tcpServerSocket(serverPort, "Server", new Function() { + public void runApplicationConnector(int serverPortForApplications, CountDownLatch serverCreated) { + BinaryProtocolServer.tcpServerSocket(serverPortForApplications, "ApplicationServer", new Function() { @Override - public Runnable apply(Socket clientSocket) { + public Runnable apply(Socket applicationSocket) { return new Runnable() { @Override public void run() { - ClientConnectionState clientConnectionState = new ClientConnectionState(clientSocket, backend.logger, backend.getUserDetailsResolver()); + IoStream stream = null; try { - clientConnectionState.requestControllerInfo(); + stream = new TcpIoStream(logger, applicationSocket); + + // authenticator pushed hello packet on connect + String jsonString = HelloCommand.getHelloResponse(stream.getDataBuffer(), logger); + if (jsonString == null) + return; + SessionDetails applicationSession = SessionDetails.valueOf(jsonString); + logger.info("Application Connected: " + applicationSession); - backend.register(clientConnectionState); - clientConnectionState.runEndlessLoop(); } catch (IOException e) { - backend.close(clientConnectionState); + if (stream != null) + stream.close(); } } }; } - }, backend.logger, parameter -> serverCreated.countDown()); + }, logger, parameter -> serverCreated.countDown()); + } + + public void runControllerConnector(int serverPortForControllers, CountDownLatch serverCreated) { + BinaryProtocolServer.tcpServerSocket(serverPortForControllers, "ControllerServer", new Function() { + @Override + public Runnable apply(Socket controllerSocket) { + return new Runnable() { + @Override + public void run() { + ClientConnectionState clientConnectionState = new ClientConnectionState(controllerSocket, logger, getUserDetailsResolver()); + try { + clientConnectionState.requestControllerInfo(); + + register(clientConnectionState); + clientConnectionState.runEndlessLoop(); + } catch (IOException e) { + close(clientConnectionState); + } + } + }; + } + }, logger, parameter -> serverCreated.countDown()); } @NotNull