diff --git a/README.md b/README.md index b1e0042..ed06ab5 100644 --- a/README.md +++ b/README.md @@ -102,9 +102,11 @@ Then, in order: 1. Start iMotions, or the mock server, first, so that something is listening. 2. Launch the relay. The IPC listener that the plugin connects to starts automatically. You do not need to press `Connect IPC`. That button exists only to reconnect after you have pressed `Disconnect IPC`. -3. Type the iMotions address into the text box, for example `127.0.0.1:9999`. - - There is no default value. The greyed-out `127.0.0.1:9999` is placeholder text, not a setting. - - A literal IP address and port are required. `localhost:9999` is rejected. +3. Type the iMotions address into the text box. + - There is no default value. The greyed-out `:5050` is placeholder text, not a setting, and not an address that works. + - The IP is the machine running iMotions. In the lab that is a different computer from the one running the relay, so `127.0.0.1` only applies if both are on the same machine. + - 5050 is the port iMotions was listening on in the lab. It is a setting, not a fixed default, so check it on the machine you are using (see below). + - A literal IP address and port are required. A host name such as `localhost:5050` is rejected. - Addresses that connect successfully are remembered in the `Saved IPs` dropdown (stored on Windows at `%APPDATA%\PilotDataSynchronization\relay_ips.json`). 4. Press `Connect TCP`. 5. Press `Check TCP Connection Status` to refresh the status line. It does not update by itself. This button is the only thing that changes it. @@ -139,7 +141,15 @@ E;1;PilotDataSync;;;;;AltitudeSync;1250.5;1250.5 Packets are semicolon-delimited and CRLF-terminated. The value appears twice because each sample carries both a `FlightModel*` and a `Pilot*` field. -> Needs verification. How `iMotions.xml` is imported into iMotions, and which port iMotions actually listens on, are not documented anywhere in this repository. `127.0.0.1:9999` appears only as placeholder text in the relay's UI. Nothing confirms it is iMotions' real port. If you have iMotions access, please confirm both and update this section. +### Which port iMotions listens on + +Read it off the iMotions machine: `Global Settings`, `API` tab, `Event Receiving`. The relay needs `Enable event reception` ticked and `Use TCP` ticked, and the port in that box is the one to type into the relay. On the lab machine it is 5050. + +The same panel lists the registered event sources. Ours shows as `Id: PilotDataSync`, version 1, `Positional Flight Data`, which is what the generated `iMotions.xml` defines. If it is missing, iMotions will drop our packets. + +Three other ports appear on that tab and none of them are ours: `Remote Control`, and the `Destination Server` ports under `Event Forwarding` and `Replay Event Forwarding`. Those are for iMotions sending data out, not receiving it. + +> Still needs verification. How the generated `iMotions.xml` is imported into iMotions is not documented anywhere in this repository, and nobody on the team has done the import themselves. It was already registered on the lab machine. See #195. ### No iMotions? Use the mock server @@ -155,6 +165,8 @@ Enter `127.0.0.1:9999` in the relay and press `Connect TCP`. The mock server prints every packet it receives, numbered, until the relay disconnects. It does not reply to the relay. +9999 is this mock's own port, picked for local testing. It is not iMotions' port and never was. + ## Verifying it works In the relay's terminal, you should see roughly this sequence: diff --git a/docs/client_meeting_notes.md b/docs/client_meeting_notes.md index 7656ab5..a7f62dd 100644 --- a/docs/client_meeting_notes.md +++ b/docs/client_meeting_notes.md @@ -59,6 +59,7 @@ Vocabulary follows [GLOSSARY.md](../GLOSSARY.md). ## Network port - The X-Plane plugin sent to a placeholder port in the code. A new port was set, but it is **still unverified** that it matches the port iMotions listens on. The client, who handles the iMotions machine, will check. See [README.md](../README.md) for the open question. + - Answered since this meeting: iMotions listens on 5050, read off the machine under Global Settings, API, Event Receiving. See the comment on #195. - Whether developers get administrator rights on the simulator machine was not settled. ## Open items diff --git a/relay/src/state.rs b/relay/src/state.rs index 18976ce..23b261f 100644 --- a/relay/src/state.rs +++ b/relay/src/state.rs @@ -34,6 +34,13 @@ use std::sync::{OnceLock, Mutex}; /// a future `log_event` call lands on a hot path, as happened before #203. pub(crate) const EVENT_LOG_CAPACITY: usize = 200; +/// What to type into the relay's address box. Deliberately not a working +/// address: iMotions runs on its own machine in the lab, so the IP has to come +/// from there. 5050 is the port it was listening on, read from Global Settings, +/// API tab, Event Receiving, and that is a setting rather than a fixed default. +/// The placeholder text and the validation message both come from here. +pub(crate) const IMOTIONS_ADDR_HINT: &str = ":5050"; + // --- State definition ------------------------------------------------------- #[allow(unused)] pub(crate) struct State { @@ -346,7 +353,9 @@ impl State { let _parsed = address .trim() .parse::() - .map_err(|_| anyhow!("Invalid IP address. Use format: 127.0.0.1:9999"))?; + .map_err(|_| { + anyhow!("Invalid address. Enter a literal IP and port, for example {IMOTIONS_ADDR_HINT}") + })?; Ok(()) } diff --git a/relay/src/view.rs b/relay/src/view.rs index 9371601..3732a13 100644 --- a/relay/src/view.rs +++ b/relay/src/view.rs @@ -7,12 +7,11 @@ use iced::widget::{button, column, container, pick_list, row, text, text_input, use iced::{Element, Length}; use iced_aw::{helpers::card, style}; +use crate::state::IMOTIONS_ADDR_HINT; use crate::{Message, State}; type UIElement<'a> = Element<'a, Message>; -const DEFAULT_TCP_PLACEHOLDER: &str = "127.0.0.1:9999"; - /// How many of the most recent `event_log` entries the GUI renders. const EVENT_LOG_VISIBLE: usize = 5; @@ -174,7 +173,7 @@ fn ipc_disconnect_button() -> UIElement<'static> { /// Build the TCP address input widget wired to `Message::TcpAddrFieldUpdate`. fn tcp_addr_input(state: &State) -> UIElement { - text_input(DEFAULT_TCP_PLACEHOLDER, &state.tcp_addr_field) + text_input(IMOTIONS_ADDR_HINT, &state.tcp_addr_field) .on_input(|addr| Message::TcpAddrFieldUpdate(addr)) .into() } diff --git a/src/server/src/main.rs b/src/server/src/main.rs index 670a798..cfd154a 100644 --- a/src/server/src/main.rs +++ b/src/server/src/main.rs @@ -4,7 +4,9 @@ use std::net::{TcpListener, TcpStream}; use std::process; use std::thread; -// Matches the relay's placeholder address, 127.0.0.1:9999 +// A local testing port, not iMotions'. iMotions listens on whatever its Event +// Receiving setting says, 5050 on the lab machine. Keeping this one distinct +// means running the mock can never be mistaken for talking to iMotions. const DEFAULT_PORT: u16 = 9999; // Reads newline-terminated packets until the peer closes the connection, @@ -49,13 +51,16 @@ fn main() -> std::io::Result<()> { Ok(port) => port, Err(e) => { eprintln!("{e}"); - eprintln!("Usage: cargo run -- [port] (default {DEFAULT_PORT})"); + eprintln!( + "Usage: cargo run -- [port] (default {DEFAULT_PORT}, a local testing port, not iMotions')" + ); process::exit(2); } }; let listener = TcpListener::bind(("127.0.0.1", port))?; - println!("Server listening on {}", listener.local_addr()?); + println!("Mock server listening on {}", listener.local_addr()?); + println!("This stands in for iMotions. The port is local to this mock, not iMotions'."); // Listen for incoming connections for stream in listener.incoming() {