aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-03-24 17:25:03 +0100
committerThomas Vanbesien <tvanbesi@proton.me>2026-03-24 17:29:52 +0100
commite9d8a8b052150f42ea00da2c07e3f78a9b7d2061 (patch)
tree2124701ae0991ed854c1a94e58d64558b6f78b48 /README.md
parent8bcf948b76c9564cb38d3611228ccaf73890a548 (diff)
downloadQtXpl2-master.tar.gz
QtXpl2-master.zip
Add JettingProxy relay, convert Xpl2Client to active connection modelHEADmaster
Insert a transparent TCP proxy between the controller and N clients: - JettingProxy listens on 9110-9112 (controller) and 9210-9212 (clients) - Broadcasts controller frames to all clients, forwards client→controller - Independent KA_PING handling on both sides Convert Xpl2Client from passive QTcpServer listener to active QTcpSocket outbound connections with auto-retry. New QML API: host/commandPort properties, connectToProxy()/disconnectFromProxy() replacing startListening()/stopListening().
Diffstat (limited to 'README.md')
-rw-r--r--README.md62
1 files changed, 44 insertions, 18 deletions
diff --git a/README.md b/README.md
index d0f089c..518acbc 100644
--- a/README.md
+++ b/README.md
@@ -15,46 +15,63 @@ qt-cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug
cmake --build build --parallel
```
-Produces three targets:
+Produces four targets:
| Target | Binary | Description |
|---|---|---|
| `QtXpl2` | `libQtXpl2.a` | Static library + QML module (`import Xpl2`) |
+| `JettingProxy` | `bin/JettingProxy` | TCP relay between one controller and N clients |
| `JettingInterfaceDemo` | `bin/JettingInterfaceDemo` | Interactive demo app |
| `MockJettingController` | `bin/MockJettingController` | Mock JI2 server for development |
## Quick start
```bash
-# Terminal 1 — start the mock server
+# Terminal 1 — start the proxy
+./build/bin/JettingProxy
+
+# Terminal 2 — start the mock server (connects to proxy on 9110-9112)
./build/bin/MockJettingController
-# Terminal 2 — run the demo
+# Terminal 3 — run the demo (connects to proxy on 9210-9212)
./build/bin/JettingInterfaceDemo
```
-The demo connects to `127.0.0.1` by default. Click **Connect**, then explore the **Commands** and **Status** tabs.
+Click **Connect** in the demo, then explore the **Commands** and **Status** tabs. Multiple demo instances can connect simultaneously.
### CLI flags
-| Flag | Description |
-|---|---|
-| `--printheads N` | Number of printheads in the demo UI (default 10) |
-| `--wire-debug` | Log raw wire bytes for both client and mock server |
+| Binary | Flag | Description |
+|---|---|---|
+| `JettingInterfaceDemo` | `--printheads N` | Number of printheads in the demo UI (default 10) |
+| `JettingProxy` | `--controller-port P` | Base port for controller side (default 9110) |
+| `JettingProxy` | `--client-port P` | Base port for client side (default 9210) |
+| All | `--wire-debug` | Log raw wire bytes / forwarded frames |
## Architecture
-### Three-port TCP client
+### Proxy architecture
-The JI2 protocol uses three independent TCP sockets:
+A `JettingProxy` relay sits between the controller and N client instances:
-| Port | Name | Purpose |
-|---|---|---|
-| 9110 | Command | GS_, CN_, CF_ commands and responses |
-| 9111 | Imaging | m0-m6 image masks, m2/m4 start/stop, n replies |
-| 9112 | Status | KA_PING keepalive, EV_ events, status messaging |
+```
+MockController ──(9110/9111/9112)──→ JettingProxy ←──(9210/9211/9212)── Xpl2Client #1
+ ←──(9210/9211/9212)── Xpl2Client #2
+```
+
+The proxy broadcasts controller frames to all clients and forwards client frames to the controller. KA_PING is handled independently on both sides (never forwarded).
+
+### Three-port TCP protocol
-`Xpl2Client` manages all three connections as a QML singleton.
+The JI2 protocol uses three independent TCP channels:
+
+| Controller port | Client port | Name | Purpose |
+|---|---|---|---|
+| 9110 | 9210 | Command | GS_, CN_, CF_ commands and responses |
+| 9111 | 9211 | Imaging | m0-m6 image masks, m2/m4 start/stop, n replies |
+| 9112 | 9212 | Status | EV_ events, status messaging |
+
+`Xpl2Client` connects out to the proxy on the client ports as a QML singleton.
### Protocol implementation
@@ -90,7 +107,8 @@ Button {
text: "Connect"
onClicked: {
Xpl2Client.host = "192.168.1.100"
- Xpl2Client.connectToServer()
+ Xpl2Client.commandPort = 9210
+ Xpl2Client.connectToProxy()
}
}
@@ -146,6 +164,10 @@ QtXpl2/
DebugConsole.qml # Dark log panel
main.cpp
CMakeLists.txt
+ jetting-proxy/
+ JettingProxy.h/cpp # Transparent TCP relay (1 controller ↔ N clients)
+ main.cpp
+ CMakeLists.txt
mock-jetting-controller/
MockServer.h/cpp # Canned responses, periodic status emission
main.cpp
@@ -154,9 +176,13 @@ QtXpl2/
protocol.pdf # Alchemie JI2-JC protocol specification
```
+## Jetting proxy
+
+The proxy (`JettingProxy`) is a transparent TCP relay that enables multiple clients to share a single controller connection. It operates at the raw frame level — it reads LF-terminated lines and forwards them without parsing the protocol. KA_PING is handled independently on both sides to prevent N clients from each replying to the controller.
+
## Mock server
-The mock server responds to all 56 protocol tokens with canned data. When status messaging is started (`CN_JC_STATUS_MESSAGING_START` / `CN_PH_STATUS_MESSAGING_START`), it emits periodic `EV_STATUS_MSG_JC` / `EV_STATUS_MSG_PH` events at the requested interval, alternating between two value sets so updates are visually apparent in the demo.
+The mock server responds to all 56 protocol tokens with canned data. It connects to the proxy (or directly to a listening client) on ports 9110-9112. When status messaging is started (`CN_JC_STATUS_MESSAGING_START` / `CN_PH_STATUS_MESSAGING_START`), it emits periodic `EV_STATUS_MSG_JC` / `EV_STATUS_MSG_PH` events at the requested interval, alternating between two value sets so updates are visually apparent in the demo.
## Conventions