Files
2026-05-07 10:49:24 +02:00

282 lines
8.2 KiB
Markdown

# API Documentation
This document covers both transport implementations. The command text protocol is identical
for both; only the carrier differs.
---
## 1. DebugService — TCP Command Interface (default port 8080)
Commands are newline-terminated (`\n`) UTF-8 text strings sent over a persistent TCP
connection. One client is served at a time; concurrent connections queue.
A client sending more than **100 commands per second** is disconnected (rate limit).
A client that sends no data for **30 seconds** is disconnected (idle timeout).
### 1.1 `DISCOVER`
List all registered signals with full metadata.
- **Request:** `DISCOVER\n`
- **Response:**
```
{"Signals":[{"id":<n>,"name":"…","alias":"…","type":"…","elements":<n>},...]}
OK DISCOVER
```
### 1.2 `TREE`
Return the full live `ObjectRegistryDatabase` hierarchy as JSON.
- **Request:** `TREE\n`
- **Response:**
```json
{"name":"Root","children":[…]}
OK TREE
```
### 1.3 `INFO <path>`
Return metadata for a specific ORD node. Response is enriched with config fields
(Frequency, Units, PVNames, …) when a full config has been provided via `SetFullConfig`.
- **Request:** `INFO App.Functions.GAM1\n`
- **Response:**
```
{"path":"…","class":"…","signals":[…],"config":{…}}
OK INFO
```
### 1.4 `LS [path]`
List the immediate children of an ORD node.
- **Request:** `LS App.Data\n`
- **Response:**
```
{"nodes":["Timer","DDB"]}
OK LS
```
### 1.5 `TRACE <name> <0|1> [decimation]`
Enable or disable high-speed tracing for a signal. Optional `decimation` controls
how many RT cycles are skipped between samples (default 1 = every cycle).
- **Request:** `TRACE App.Data.DDB.Counter 1\n`
- **Request:** `TRACE App.Data.DDB.Counter 1 10\n` *(every 10th sample)*
- **Response:** `OK TRACE <match_count>\n`
### 1.6 `FORCE <name> <value>`
Inject a persistent value into a signal's memory location. The RT broker will copy
the forced value on every cycle until `UNFORCE` is called.
- **Request:** `FORCE App.Data.DDB.Counter 9999\n`
- **Response:** `OK FORCE <match_count>\n`
### 1.7 `UNFORCE <name>`
Remove a forced value; the signal resumes its normal data-flow value.
- **Request:** `UNFORCE App.Data.DDB.Counter\n`
- **Response:** `OK UNFORCE <match_count>\n`
### 1.8 `BREAK <name> <op> <threshold>`
Set a conditional breakpoint on a signal. When the condition fires, the application
pauses and execution stepping becomes available. Supported operators:
| `op` string | Condition |
|---|---|
| `>` | signal > threshold |
| `<` | signal < threshold |
| `==` | signal == threshold |
| `>=` | signal >= threshold |
| `<=` | signal <= threshold |
| `!=` | signal != threshold |
| `OFF` | disable break (same as `BREAK <name> OFF`) |
- **Request:** `BREAK App.Data.DDB.Counter > 1000\n`
- **Response:** `OK BREAK <match_count>\n`
### 1.9 `BREAK <name> OFF`
Clear the breakpoint on a signal (equivalent to `BREAK <name> OFF 0`).
- **Request:** `BREAK App.Data.DDB.Counter OFF\n`
- **Response:** `OK BREAK <match_count>\n`
### 1.10 `PAUSE`
Halt all patched RT threads at the start of their next Execute cycle.
- **Request:** `PAUSE\n`
- **Response:** `OK\n`
### 1.11 `RESUME`
Release paused RT threads.
- **Request:** `RESUME\n`
- **Response:** `OK\n`
### 1.12 `STEP <n> [thread]`
Resume execution for exactly `n` RT output-broker cycles then pause again.
Optional `thread` (OS thread name) restricts counting to one thread.
- **Request:** `STEP 5\n`
- **Request:** `STEP 1 RealTimeThread1\n`
- **Response:** `OK STEP\n`
### 1.13 `STEP_STATUS`
Query current pause and stepping state.
- **Request:** `STEP_STATUS\n`
- **Response:**
```json
{"paused":true,"gam":"App.Functions.GAM1","remaining":3}
OK STEP_STATUS
```
### 1.14 `VALUE <name>`
Read the current raw value of a signal from its memory address. Arrays are
capped at 256 elements; larger signals include `"truncated":true`.
- **Request:** `VALUE App.Data.DDB.Counter\n`
- **Response:**
```json
{"name":"App.Data.DDB.Counter","type":"uint32","elements":1,"values":[42]}
OK VALUE
```
### 1.15 `MONITOR SIGNAL <name> <periodMs>`
Register a signal for slow-rate polling. The service reads the signal directly
from its `DataSourceI` and sends the value at the specified period.
- **Request:** `MONITOR SIGNAL App.Data.DDB.Counter 500\n`
- **Response:** `OK MONITOR <id>\n`
On `DebugService`, monitored values are pushed over UDP with signal ID = internal monitor ID.
On `WebDebugService`, they are broadcast as `{"type":"monitor",…}` SSE events.
### 1.16 `UNMONITOR SIGNAL <name>`
Stop polling a monitored signal.
- **Request:** `UNMONITOR SIGNAL App.Data.DDB.Counter\n`
- **Response:** `OK UNMONITOR\n`
### 1.17 `CONFIG`
Return the full application configuration as JSON. Requires that `SetFullConfig()` was
called after `ConfigureApplication()`.
- **Request:** `CONFIG\n`
- **Response:**
```json
{"App":{"Class":"RealTimeApplication",…}}
OK CONFIG
```
### 1.18 `MSG <object> <function> [key=value …]`
Send a MARTe2 `Message` to any object in the ORD.
- **Request:** `MSG App.Functions.GAM1 Reset\n`
- **Request:** `MSG App.StateMachine GOTOSTATE NewState=Running\n`
- **Response:** `OK MSG\n` or `ERROR MSG <reason>\n`
### 1.19 `SERVICE_INFO`
Return metadata about the debug service itself.
- **Request:** `SERVICE_INFO\n`
- **Response:**
```json
{"transport":"TCP","controlPort":8080,"udpPort":8081,"logPort":8082}
```
---
## 2. WebDebugService — HTTP Interface (default port 8090)
### 2.1 `GET /`
Returns the embedded single-page application. Open in any web browser.
### 2.2 `POST /api/command`
Execute any command from Section 1. The request body is the command text
(without a trailing newline). CORS headers are included.
- **Request headers:** `Content-Type: text/plain`
- **Request body:** e.g. `TRACE App.Data.DDB.Counter 1`
- **Response:** Plain text; same content as the TCP response.
### 2.3 `GET /api/events`
Long-lived Server-Sent Events stream. Up to 8 simultaneous clients.
Each event is formatted as:
```
event: message
data: <json>
```
(blank line terminates each event per SSE spec)
#### SSE event types
| `type` field | Additional fields | Description |
|---|---|---|
| `trace` | `name`, `ts` (ns), `value` (f64) | One traced signal sample |
| `monitor` | `name`, `ts` (ns), `value` (f64) | One slow-rate monitor sample |
| `log` | `level`, `msg` | Forwarded `REPORT_ERROR` log entry |
| `status` | `paused` (bool), `gam`, `remaining` | Pause/step state heartbeat (every 500 ms) |
| `discover` | `signals` (array) | Full signal list (sent on SSE connect) |
| `tree` | `tree` (object) | Full ORD tree (sent on SSE connect) |
Example trace event:
```
event: message
data: {"type":"trace","name":"App.Data.DDB.Counter","ts":1234567890,"value":42.0}
```
---
## 3. UDP Telemetry Format (DebugService, default port 8081)
Packets are little-endian and packed (`#pragma pack(1)`).
### 3.1 `TraceHeader` (20 bytes)
| Offset | Type | Field | Description |
|---|---|---|---|
| 0 | uint32 | `magic` | Always `0xDA7A57AD` |
| 4 | uint32 | `seq` | Monotonically incrementing sequence number |
| 8 | uint64 | `timestamp` | High-resolution hardware timestamp |
| 16 | uint32 | `count` | Number of samples in this datagram |
### 3.2 Sample Entry (per signal)
| Offset | Type | Field | Description |
|---|---|---|---|
| 0 | uint32 | `id` | Signal ID from `DISCOVER` |
| 4 | uint64 | `timestamp` | Per-sample RT timestamp |
| 12 | uint32 | `size` | Payload size in bytes |
| 16 | bytes | `data` | Raw signal memory (`size` bytes) |
Multiple samples may be packed into one datagram up to `STREAMER_MTU = 1400` bytes.
A new datagram is started when the next sample would overflow the MTU.
---
## 4. Log Forwarding (DebugService, default port 8082)
The `TcpLogger` component (`Source/Components/Interfaces/TCPLogger/`) connects to the
MARTe2 global `LoggerI` and forwards every `REPORT_ERROR` call as a text line:
```
<level>|<object>|<function>|<message>\n
```
Up to 8 simultaneous log clients are supported. If no client is connected, log events
are silently discarded.
To enable:
```text
+Logger = {
Class = TcpLogger
Port = 8082
MaxClients = 8
}
```
On `WebDebugService`, logs are forwarded to SSE clients as `{"type":"log","level":"…","msg":"…"}`
events — no separate `TcpLogger` instance is required.