Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<iMotions IP>: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.
Expand Down Expand Up @@ -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

Expand All @@ -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:
Expand Down
1 change: 1 addition & 0 deletions docs/client_meeting_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 10 additions & 1 deletion relay/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "<iMotions IP>:5050";

// --- State definition -------------------------------------------------------
#[allow(unused)]
pub(crate) struct State {
Expand Down Expand Up @@ -346,7 +353,9 @@ impl State {
let _parsed = address
.trim()
.parse::<SocketAddr>()
.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(())
}

Expand Down
5 changes: 2 additions & 3 deletions relay/src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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()
}
Expand Down
11 changes: 8 additions & 3 deletions src/server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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() {
Expand Down
Loading