Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ddb4fe356 | ||
|
|
915a192b16 | ||
|
|
3e0a481c13 |
@@ -1,313 +1,241 @@
|
|||||||
# AGENTS.md
|
# Repository Guidelines
|
||||||
|
|
||||||
Guide for agents working in the MARTe2 Integrated Components repository. Read
|
Guide for AI assistants working in the MARTe2 Integrated Components repository.
|
||||||
`ARCHITECTURE.md` and `CLAUDE.md` for deeper detail; this file focuses on
|
Focuses on non-obvious facts: commands, conventions, cross-module contracts, and
|
||||||
non-obvious knowledge, commands, and conventions that are not self-evident from
|
gotchas that are not self-evident from a single file read.
|
||||||
a single file read.
|
|
||||||
|
|
||||||
---
|
## Project Overview
|
||||||
|
|
||||||
## Repository at a glance
|
MARTe2 component library with **two independent real-time data paths** sharing
|
||||||
|
one binary wire protocol (`Common/UDP/UDPSProtocol.h`):
|
||||||
|
|
||||||
MARTe2 component library with two independent real-time data paths:
|
1. **Streaming path** — `UDPStreamer` DataSource serialises DDB signals into UDPS
|
||||||
|
binary packets on UDP → `StreamHub` (headless C++ hub: ring buffers, LTTB
|
||||||
1. **Streaming path** — `UDPStreamer` DataSource (serialises signals to UDPS
|
decimation, trigger FSM, history writer, binary recorder) → WebSocket 8090 →
|
||||||
binary packets on UDP 44500) → `StreamHub` (headless C++ hub: ring buffers,
|
clients (browser SPA, native ImGui, native Qt).
|
||||||
LTTB decimation, trigger FSM, history writer) → WebSocket 8090 → clients
|
2. **Debug path** — `DebugService` patches `ClassRegistryDatabase` at
|
||||||
(browser SPA, native ImGui, native Qt).
|
|
||||||
2. **Debug path** — `DebugService` Interface patches `ClassRegistryDatabase` at
|
|
||||||
`Initialise()` so `ConfigureApplication()` wraps all `MemoryMap*Broker` types
|
`Initialise()` so `ConfigureApplication()` wraps all `MemoryMap*Broker` types
|
||||||
with `DebugBrokerWrapper<T>`. Zero application code changes. Exposes TCP 8080
|
with `DebugBrokerWrapper<T>` — **zero application code changes**. Exposes
|
||||||
(text commands), UDP 8081 (trace telemetry), TCP 8082 (`TcpLogger`).
|
TCP 8080 (text commands), UDP 8081 (UDPS trace telemetry), TCP 8082
|
||||||
|
(`TcpLogger` log forward).
|
||||||
|
|
||||||
Key shared artefact: `Common/UDP/UDPSProtocol.h` — the UDPS binary wire format
|
## Architecture & Data Flow
|
||||||
(17-byte packed header, 136-byte signal descriptors, little-endian). It is
|
|
||||||
deliberately MARTe2-free and is mirrored across **four** codebases that must stay
|
|
||||||
in sync: C++ producers (`UDPStreamer`, `DebugService`), C++ consumer
|
|
||||||
(`Source/Components/Interfaces/UDPStream/UDPSClient`), Go decoder
|
|
||||||
(`Common/Client/go/udpsprotocol`), and the JS client parsers. Any protocol
|
|
||||||
change must be mirrored in all of them.
|
|
||||||
|
|
||||||
StreamHub WebSocket protocol: JSON text frames for commands/events, binary
|
```
|
||||||
frames for data pushes (spec in `ARCHITECTURE.md` §6). The Go hub
|
[SineArrayGAM/TimeArrayGAM] → DDB → UDPStreamer (UDPS over UDP)
|
||||||
(`Client/udpstreamer`) and the C++ StreamHub implement the identical protocol;
|
├─→ UDPStreamerClient (input DS back into a MARTe2 RT app, round-trip)
|
||||||
browser JS, ImGui, and Qt clients must stay compatible with both.
|
└─→ StreamHub: UDPSourceSession (receive thread → SignalRingBuffer)
|
||||||
|
→ push loop @30Hz: LTTB decimate temporal sigs → WS binary frames → clients
|
||||||
|
DebugService: patches broker builders at Initialise(); TCP 8080 commands,
|
||||||
|
UDP 8081 telemetry, TcpLogger 8082 (REPORT_ERROR → "LOG <LEVEL> <desc>" lines)
|
||||||
|
```
|
||||||
|
|
||||||
---
|
- **Wire protocol**: `Common/UDP/UDPSProtocol.h` is the canonical spec (17-byte
|
||||||
|
packed header, magic `0x53504455` 'UDPS', 136-byte signal descriptors,
|
||||||
|
CONFIG/DATA/ACK/CONNECT/DISCONNECT packet types, quant/time/publish modes).
|
||||||
|
Deliberately MARTe2-free so Go clients reuse it. **Mirrored across four
|
||||||
|
codebases that must stay in sync**: C++ producers (UDPStreamer, DebugService),
|
||||||
|
C++ consumer (`Source/Components/Interfaces/UDPStream/UDPSClient`), Go decoder
|
||||||
|
(`Common/Client/go/udpsprotocol/protocol.go`), and JS parsers
|
||||||
|
(`Client/udpstreamer/static/`, `Client/debugger/static/`). Any protocol change
|
||||||
|
must be mirrored in all of them.
|
||||||
|
- **WS protocol** has two implementations — Go hub (`Common/Client/go/wshub`) and
|
||||||
|
C++ StreamHub — that must behave identically; every client (SPA, ImGui, Qt)
|
||||||
|
must satisfy both. JSON text frames for commands/events (`addSource`,
|
||||||
|
`removeSource`, `setTrigger`, `arm`, `zoom`, `historyZoom`, `recStart`…), binary
|
||||||
|
frames for data pushes (live v1 + trigger capture v2).
|
||||||
|
- **Threading model**: RT threads only spinlock+memcpy (`FastPollingMutexSem`);
|
||||||
|
all socket I/O, fragmentation, and reassembly lives on background
|
||||||
|
`SingleThreadService` threads. StreamHub: per-session UDPSClient receive
|
||||||
|
threads + WS accept/read threads + one push loop.
|
||||||
|
- **DebugService patching**: `PatchRegistry()` replaces the ObjectBuilder for 11
|
||||||
|
`MemoryMap*Broker` classes; runs only when `ControlPort > 0`; static guard
|
||||||
|
against double-patching; wrappers persist for process lifetime.
|
||||||
|
|
||||||
## Environment setup (do this first, always)
|
## Key Directories
|
||||||
|
|
||||||
`source env.sh` is **required** before building *or* running anything. It sets:
|
| Path | Purpose |
|
||||||
|
|---|---|
|
||||||
|
| `Source/Components/DataSources/UDPStreamer/` | Output DataSource; UDP I/O on bg thread, RT thread only spinlock+memcpy in `Synchronise()` |
|
||||||
|
| `Source/Components/DataSources/UDPStreamerClient/` | Input DataSource (shared `UDPSClient`), double-buffered ready/scratch |
|
||||||
|
| `Source/Components/GAMs/` | `SineArrayGAM` (float32 sine, continuous phase), `TimeArrayGAM` (us-timer → per-sample timestamp array) |
|
||||||
|
| `Source/Components/Interfaces/DebugService/` | Registry patching, `DebugBrokerWrapper.h`, TCP/UDP services |
|
||||||
|
| `Source/Components/Interfaces/TCPLogger/` | `LoggerConsumerI` forwarding `REPORT_ERROR` to ≤8 TCP clients |
|
||||||
|
| `Source/Components/Interfaces/UDPStream/` | Plain-C++ helpers (not MARTe2 Objects): `UDPSClient` (auto-reconnect + fragment reassembly), `UDPSServer` (not thread-safe — owner's Execute thread only) |
|
||||||
|
| `Source/Applications/StreamHub/` | Standalone app (links MARTe2 core): `StreamHub`, `UDPSourceSession`, `WSServer`, `TriggerEngine`, `HistoryWriter`, `BinaryRecorder`, `LTTB`, `SignalRingBuffer` |
|
||||||
|
| `Common/UDP/` | Canonical wire protocol (header-only, MARTe2-free) |
|
||||||
|
| `Common/Client/go/` | Go mirror: `udpsprotocol` (decoder), `wshub` (WS hub client) |
|
||||||
|
| `Client/udpstreamer/` | Go legacy direct-UDP oscilloscope web UI (connects straight to UDPStreamer, no StreamHub) |
|
||||||
|
| `Client/webui/` | Go thin static server; SPA talks WS directly to C++ StreamHub (discovers via `GET /hub`) |
|
||||||
|
| `Client/debugger/` | Go debug web UI for DebugService |
|
||||||
|
| `Client/streamhub/` | Native ImGui+SDL2+OpenGL oscilloscope (C++17, no MARTe2) |
|
||||||
|
| `Client/streamhub-qt/` | Native Qt Widgets oscilloscope (Qt6 preferred, Qt5 fallback) |
|
||||||
|
| `Test/` | GTest, legacy Integration tests, Configurations (.cfg), E2E suite |
|
||||||
|
| `Docs/` | Per-component reference: `Protocol.md`, `UDPStreamer.md`, `StreamHub-{API,UserGuide,Developer}.md`, `DebugService.md`, `WebUI.md`, `Tutorial.md`, `E2E-Suite.md` |
|
||||||
|
|
||||||
- `MARTe2_DIR` (default `~/workspace/MARTe2`) and `MARTe2_Components_DIR`
|
## Development Commands
|
||||||
(default `~/workspace/MARTe2-components`) — external dependencies, not in
|
|
||||||
this repo. Edit `env.sh` if your MARTe2 install lives elsewhere.
|
|
||||||
- `TARGET=x86-linux`
|
|
||||||
- `LD_LIBRARY_PATH` — prepends MARTe2 Core, MARTe2-components (LinuxTimer,
|
|
||||||
FileDataSource), and this repo's built `.so`s (UDPStreamer, SineArrayGAM,
|
|
||||||
TimeArrayGAM, DebugService, TCPLogger).
|
|
||||||
|
|
||||||
Without sourcing `env.sh`, builds fail (can't find `MakeDefaults`) and binaries
|
`source env.sh` is **mandatory** before any MARTe2 build or run (sets
|
||||||
fail to load shared libs. The E2E scripts source it themselves, but a bare
|
`MARTe2_DIR`, `MARTe2_Components_DIR`, `TARGET=x86-linux`, `LD_LIBRARY_PATH`).
|
||||||
`make` or `./MainGTest.ex` from a fresh shell will not.
|
The E2E scripts source it themselves; a bare `make` from a fresh shell will not
|
||||||
|
work. `run_streamhub.sh` hard-errors if `MARTe2_DIR` is unset.
|
||||||
---
|
|
||||||
|
|
||||||
## Build commands
|
|
||||||
|
|
||||||
All C++ builds use the MARTe2 `Makefile.gcc` wrapper system. There is one
|
|
||||||
top-level `Makefile.gcc` and one per component directory. `TARGET` defaults to
|
|
||||||
`x86-linux`; pass `TARGET=x86-linux` explicitly when invoking `make -C` from
|
|
||||||
elsewhere.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
source env.sh
|
source env.sh
|
||||||
|
|
||||||
make -f Makefile.gcc core # all C++ MARTe2 components (UDPStreamer, GAMs, DebugService, TCPLogger, UDPStream)
|
make -f Makefile.gcc core # 7 components (UDPStream interface FIRST, then UDPStreamer, UDPStreamerClient, GAMs, TCPLogger, DebugService)
|
||||||
make -f Makefile.gcc apps # StreamHub standalone app
|
make -f Makefile.gcc apps # StreamHub standalone app → Build/x86-linux/StreamHub/StreamHub.ex
|
||||||
make -f Makefile.gcc test # build GTest + Integration test binaries
|
make -f Makefile.gcc test # GTest + Integration test binaries + component test libs
|
||||||
|
make -f Makefile.gcc all # core + apps + test
|
||||||
make -f Makefile.gcc clean
|
make -f Makefile.gcc clean
|
||||||
make -f Makefile.gcc # = all: core apps test
|
|
||||||
|
|
||||||
# Build a single component (each component dir has its own Makefile.gcc):
|
# Single component:
|
||||||
make -C Source/Components/DataSources/UDPStreamer -f Makefile.gcc
|
make -C Source/Components/GAMs/SineArrayGAM -f Makefile.gcc
|
||||||
make -C Source/Applications/StreamHub -f Makefile.gcc
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Build output goes to `Build/x86-linux/` — shared libs under
|
Build output → `Build/x86-linux/` mirroring `PACKAGE` paths (both `libX.so` and
|
||||||
`Build/x86-linux/Components/<...>/`, the StreamHub executable at
|
`X.so` are produced). `compile_commands.json` (repo root, gitignored) feeds
|
||||||
`Build/x86-linux/StreamHub/StreamHub.ex`, test binaries under
|
LSP/clangd; CMake clients export their own into `Client/*/build/`.
|
||||||
`Build/x86-linux/GTest/` and `Build/x86-linux/Test/Integration/`.
|
|
||||||
|
|
||||||
`compile_commands.json` is generated at the repo root (gitignored) for LSP /
|
### Non-MARTe2 clients (no env.sh needed)
|
||||||
clangd. The CMake-based clients (ImGui, Qt) also export it into their `build/`.
|
|
||||||
|
|
||||||
### Non-MARTe2 clients (separate build systems, no env.sh needed)
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Go clients (UDPS web client, debug client, E2E chain-client)
|
|
||||||
cd Common/Client/go && go build ./...
|
cd Common/Client/go && go build ./...
|
||||||
cd Client/debugger && go build ./...
|
cd Client/debugger && go build ./...
|
||||||
cd Client/udpstreamer && go build ./... # or: cd Client/webui && go build
|
|
||||||
cd Test/E2E/suite/client && go build ./... # chain-client (E2E driver) + its tests
|
|
||||||
|
|
||||||
# ImGui desktop client (needs SDL2; fetches Dear ImGui + ImPlot via FetchContent)
|
|
||||||
cd Client/streamhub && cmake -B build -DCMAKE_BUILD_TYPE=Release && cmake --build build
|
cd Client/streamhub && cmake -B build -DCMAKE_BUILD_TYPE=Release && cmake --build build
|
||||||
|
|
||||||
# Qt desktop client (Qt5 or Qt6 Widgets + WebSockets; autodetects, prefers Qt6)
|
|
||||||
cd Client/streamhub-qt && cmake -B build && cmake --build build
|
cd Client/streamhub-qt && cmake -B build && cmake --build build
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
### Key scripts
|
||||||
|
|
||||||
## Run / test commands
|
| Script | Purpose |
|
||||||
|
|
||||||
### Unit & integration tests (C++)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./Build/x86-linux/GTest/MainGTest.ex # UDPStreamer unit tests
|
|
||||||
./Build/x86-linux/GTest/MainGTest.ex --gtest_filter='Name*' # single test
|
|
||||||
./Build/x86-linux/Test/Integration/Integration/IntegrationTests.ex # DebugService integration tests
|
|
||||||
```
|
|
||||||
|
|
||||||
### Go tests
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd Test/E2E/suite/client && go test ./...
|
|
||||||
```
|
|
||||||
|
|
||||||
### Python framework tests (E2E framework logic, no live stack needed)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd Test/E2E/suite && python3 -m unittest tests_py
|
|
||||||
```
|
|
||||||
|
|
||||||
### E2E / demo scripts (build + launch the full stack)
|
|
||||||
|
|
||||||
| Script | What it does |
|
|
||||||
|---|---|
|
|---|---|
|
||||||
| `./run_streamhub.sh` | Launch MARTe2 app (UDPStreamer) + StreamHub, optionally web UI (`-w`) and ImGui client (`-g`). Ports documented in its header. |
|
| `./run_streamhub.sh` | Demo stack: build + launch MARTe2 app + StreamHub, optional web (`-w`) / ImGui (`-g`) clients. Flags `-m/-c` MARTe2 dirs, `-b TARGET`, `-p WS_PORT`, `-n MAX_POINTS` (actual default 1000000, header says 10000), `-s` skip build. Generates temp hub cfg with `+History`/`+Recorder` blocks in `/tmp`. Ctrl-C kills all. |
|
||||||
| `./Test/E2E/suite/run_e2e.sh` | **Unified E2E suite**: per-scenario generates data + cfgs, runs MARTe2+StreamHub, drives the Go `chain-client` (live/zoom/window/trigger) for `chain` scenarios plus `direct`/`recorder`/`debug`/`tcplogger` scenario kinds, runs a stress matrix, unit suites + coverage, builds a Typst PDF report. Flags: `--skip-build`, `--only <id>`, `--pdf-only`, `--cpp-coverage`, `--skip-coverage`, `--skip-stress`, `--skip-datasources`, `--skip-recorder`, `--skip-debug`, `--skip-tcplogger`. |
|
| `./Test/E2E/suite/run_e2e.sh` | Full E2E: 57-scenario matrix + stress + unit suites + gcov coverage + Typst PDF report. Flags: `--skip-build`, `--only <id>`, `--pdf-only`, `--skip-coverage`, `--skip-stress`, `--skip-datasources`, `--skip-recorder`, `--skip-debug`, `--skip-tcplogger` |
|
||||||
| `./Test/E2E/suite/run_stress.sh` | **Capacity/stress harness**: sweeps one load axis at a time (signal size/count, subscriber fan-out, source count, WS-client count, zoom rate), gates on survival+liveness (hard) and RSS+zoom-p95 latency (soft). Flags: `--skip-build`, `--only <id>`, `--axis <axis>`. |
|
| `./Test/E2E/suite/run_stress.sh` | Capacity harness: sweeps one load axis at a time (`--axis`), hard gates survival+liveness, soft gates RSS+zoom-p95 |
|
||||||
|
|
||||||
The E2E suite produces `Build/x86-linux/E2E/chain/` artifacts: `report_data.json`,
|
## Code Conventions & Common Patterns
|
||||||
`history.jsonl` (per-run headline metrics for trend/regression tracking),
|
|
||||||
`trend_*.png` plots, and `E2E_Report.pdf` (compiled from `E2E_Report.typ` via
|
|
||||||
`typst`). `--cpp-coverage` triggers an instrumented `--coverage` rebuild, captures
|
|
||||||
with `lcov` (restricted to `Source/*` + `Test/*`), then restores a clean build.
|
|
||||||
|
|
||||||
---
|
- **No STL in `Source/Components/**` (and StreamHub)**: use `StreamString` (not
|
||||||
|
`std::string`), `FastPollingMutexSem`/`EventSem` (not `std::mutex`/threads),
|
||||||
|
fixed arrays / MARTe2 `Vector<T>` (not `std::vector`), `REPORT_ERROR` /
|
||||||
|
`REPORT_ERROR_STATIC` macros (no exceptions). C stdlib is fine. Heap
|
||||||
|
`new`/`delete[]` is normal. STL/C++17 is fine in `Client/streamhub/` and
|
||||||
|
`Client/streamhub-qt/`.
|
||||||
|
- **RT hot-path rule**: `FastPollingMutexSem` on real-time hot paths, never OS
|
||||||
|
mutexes; RT cycle must not block on the scheduler.
|
||||||
|
- **Class registration**: `CLASS_REGISTER_DECLARATION()` in the class `public:`
|
||||||
|
section of the header; `CLASS_REGISTER(Name, "1.0")` at the end of the `.cpp`
|
||||||
|
inside `namespace MARTe`. Every component `.cpp` ends with it.
|
||||||
|
- **EUPL v1.1 license headers** on all C++ sources and `Makefile.inc` — preserve
|
||||||
|
on new files.
|
||||||
|
- **Per-component build**: each dir has one-line `Makefile.gcc` wrapper
|
||||||
|
(`include Makefile.inc`) + `Makefile.inc` declaring `OBJSX`, `PACKAGE`,
|
||||||
|
`ROOT_DIR`, `INCLUDES` (re-declared per file, ~12 MARTe2 layer dirs),
|
||||||
|
`LIBRARIES`, including `MakeStdLibDefs.$(TARGET)` then
|
||||||
|
`MakeStdLibRules.$(TARGET)`. Generated `depends.x86-linux` (gcc -MM) is
|
||||||
|
committed but **never hand-edited** — delete to regenerate.
|
||||||
|
- **Qt client**: `QT_NO_KEYWORDS` is required (reused `Protocol.h` structs have
|
||||||
|
members named `signals`); Qt classes use `Q_SIGNALS`/`Q_SLOTS`/`Q_EMIT`. Run
|
||||||
|
with long options: `--host HOST --port 8090` (single-dash misparsed). Single
|
||||||
|
GUI thread, 60 Hz QTimer repaint.
|
||||||
|
- **StreamHub config** is *not* a MARTe2 `RealTimeApplication`: `Hub = { WSPort
|
||||||
|
MaxPoints PushRate MaxPushPoints RingTemporal RingScalar +Recorder{...}
|
||||||
|
Sources={id={Label Addr Port}} }`. `+History` keys: `Directory` (required),
|
||||||
|
`DurationHours` (1), `Decimation` (1), `FlushIntervalSec` (5),
|
||||||
|
`MinDiskFreeMB` (500). `.shist` files: 64-byte header ('SHR1') + circular
|
||||||
|
(t,v) float64 pairs.
|
||||||
|
- **UDPStreamer config**: `Port` (44500; multicast data = `DataPort`, default
|
||||||
|
`Port+1`), `MaxPayloadSize` (1400), `PublishingMode` `Strict`/`Accumulate`,
|
||||||
|
per-signal `Signals={Name={Type,Unit,NumberOfDimensions,NumberOfElements,
|
||||||
|
TimeMode}}` with `TimeMode` `PacketTime`/`FirstSample`/`LastSample`/`FullArray`;
|
||||||
|
multicast needs `MulticastGroup` + `Interface`.
|
||||||
|
|
||||||
## Code organization
|
## Important Files
|
||||||
|
|
||||||
```
|
- `env.sh` — environment; source first, always.
|
||||||
Common/
|
- `Makefile.gcc` / `Makefile.inc` (root) — build orchestration.
|
||||||
UDP/UDPSProtocol.h # shared UDPS binary protocol (header-only, MARTe2-free)
|
- `Common/UDP/UDPSProtocol.h` — canonical wire format; changing it triggers the
|
||||||
Client/go/ # Go packages: udpsprotocol (decoder), wshub (WS hub client)
|
4-way mirror checklist above.
|
||||||
Source/
|
- `Source/Applications/StreamHub/main.cpp` — hub entry (`[-cfg file.cfg]
|
||||||
Components/ # MARTe2 components — NO STL allowed here
|
[-port N] [-maxPoints N]`); hub **must be heap-allocated** (~128 MB, exceeds
|
||||||
DataSources/UDPStreamer/ # real-time UDP signal streaming DataSource
|
the 8 MB stack).
|
||||||
DataSources/UDPStreamerClient/ # (MARTe2-side UDPS client DataSource)
|
- `Test/Configurations/*.cfg` — MARTe2 app configs (`$App = { Class =
|
||||||
GAMs/SineArrayGAM/ # sine-wave array generator GAM
|
RealTimeApplication }` with `+Functions`, `+DataSources`, `+States`, `+Timings`
|
||||||
GAMs/TimeArrayGAM/ # time-reference array GAM
|
blocks); `streamhub_demo.cfg` and `TestApp.cfg` are good templates.
|
||||||
Interfaces/DebugService/ # tracing/forcing/breakpoint Interface (registry-patched brokers)
|
- `Test/E2E/suite/{scenarios,gen_data,gen_cfg,validate_waveform,stress}.py` —
|
||||||
Interfaces/TCPLogger/ # REPORT_ERROR → TCP forwarder (LoggerConsumerI)
|
declarative scenario matrix and generators consumed identically by the Go
|
||||||
Interfaces/UDPStream/ # UDPSClient/UDPSServer (C++ consumer/producer of UDPS)
|
chain-client and validators.
|
||||||
Applications/StreamHub/ # headless C++ hub app (links MARTe2 core but follows MARTe2 style)
|
- `Client/debugger/main.go` — `-addr :7777` default, `-enable-dangerous-commands`
|
||||||
Client/
|
safety gate (CR-4) for FORCE/PAUSE/RESUME/STEP/BREAK/MSG.
|
||||||
debugger/ # Go web client for DebugService (browser UI in static/)
|
|
||||||
udpstreamer/ # Go web server + static SPA for UDPStreamer (legacy direct-UDP path)
|
## Runtime/Tooling Preferences
|
||||||
webui/ # Go StreamHub WebSocket web UI (newer, hub-based)
|
|
||||||
streamhub/ # native ImGui desktop client (SDL2 + OpenGL + ImPlot, C++17, no MARTe2)
|
- **OS**: Linux x86_64 (`TARGET=x86-linux`). External deps live outside this
|
||||||
streamhub-qt/ # native Qt Widgets desktop client (C++17, Qt5/Qt6, no MARTe2)
|
repo: `MARTe2_DIR` (default `~/workspace/MARTe2`) and
|
||||||
Test/
|
`MARTe2_Components_DIR` (default `~/workspace/MARTe2-components`) — edit
|
||||||
GTest/ # GTest harness (MainGTest.cpp) for UDPStreamer unit tests
|
`env.sh` if they differ. `env.sh`'s `LD_LIBRARY_PATH` does **not** cover
|
||||||
Integration/ # DebugService integration tests (link against DebugService .so)
|
UDPStreamerClient/UDPStream lib dirs.
|
||||||
Components/DataSources/UDPStreamer/ # UDPStreamer unit test sources
|
- **C++**: MARTe2 `Makefile.gcc` wrapper system, gtest-1.7.0 for tests.
|
||||||
Configurations/ # MARTe2 .cfg files for tests and demos
|
- **Go**: `go 1.21`; modules use `replace marte2/common => ../../Common/Client/go`
|
||||||
E2E/
|
(`gorilla/websocket` v1.5.1). Go binaries are gitignored.
|
||||||
chain/ # streaming-chain E2E + stress suite (Python orchestrator + Go client)
|
- **ImGui client**: needs SDL2; CMake FetchContent pins Dear ImGui **v1.91.8** +
|
||||||
datasources/ recorder/ streamhub/ # older per-component E2E scripts
|
ImPlot **v0.17** (`implot_items.cpp` is a slow -O3 TU, ~2 min rebuild).
|
||||||
Docs/ # per-component reference docs (Protocol, UDPStreamer, StreamHub-*, DebugService, ...)
|
- **Qt client**: Qt6 preferred, Qt5 fallback, Widgets + WebSockets, custom
|
||||||
docs/superpowers/{specs,plans}/ # design specs + implementation plans (dated)
|
QPainter plotting (no QtCharts).
|
||||||
ARCHITECTURE.md # full architecture (data flow diagrams, protocol tables, WS protocol)
|
- **E2E report**: `typst compile E2E_Report.typ`; Python 3 + numpy for the suite.
|
||||||
|
- Remove `vgore.*` core dumps when you see them; they are not gitignored.
|
||||||
|
|
||||||
|
## Testing & QA
|
||||||
|
|
||||||
|
Four test layers; `env.sh` + built stack required for all but the standalone
|
||||||
|
ones. Only `tests_py.py`, Go tests, and the built C++ test binaries run
|
||||||
|
standalone.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./Build/x86-linux/GTest/MainGTest.ex --gtest_filter='Name*' # C++ GTest
|
||||||
|
./Build/x86-linux/Test/Integration/Integration/IntegrationTests.ex # legacy DebugService runtime tests
|
||||||
|
cd Test/E2E/suite/client && go test ./... # Go chain-client unit tests
|
||||||
|
cd Test/E2E/suite && python3 -m unittest tests_py # framework logic, standalone
|
||||||
```
|
```
|
||||||
|
|
||||||
### Component layout convention
|
- **GTest**: `MainGTest.ex` currently holds only `DebugServiceGTest`
|
||||||
|
(TraceRingBuffer SPSC, DebugSignalInfo, BreakOp). Component GTests
|
||||||
|
(`UDPStreamerGTest.cpp` ~46 cases, `StreamHubTest.a`, `UDPStreamerClientTest.a`)
|
||||||
|
compile **as libraries only — no standalone executable**.
|
||||||
|
- **Legacy IntegrationTests.ex**: 9 printf-narrated DebugService runtime tests,
|
||||||
|
always returns 0; `collect.py` parses stdout blocks.
|
||||||
|
- **E2E suite** (`run_e2e.sh`): 57 curated scenarios (s01–s57) across kinds
|
||||||
|
`chain`/`direct`/`recorder`/`debug`/`debug_pause_resume`/`tcplogger`, driven
|
||||||
|
against live MARTeApp.ex + StreamHub.ex + Go chain-client. `scenarios.py` is a
|
||||||
|
curated covering set: **every configurable UDPStreamer option value appears in
|
||||||
|
≥1 scenario** — add a scenario when adding an option.
|
||||||
|
- **Oracle gates** (`validate_waveform.py`): **fidelity** (every received value
|
||||||
|
within `tol` of ground truth; 0 for un-quantised ints, float epsilon for
|
||||||
|
un-quantised floats, `quant_step/2 + 1e-6·range` for quantised) is the
|
||||||
|
**correctness gate**. **Shape** is a *gross* sanity gate + tracked metric
|
||||||
|
(`corr >= 0.5`, `nRMSE <= 0.30` relaxed by quant step, frequency searched
|
||||||
|
±5% band); a correct sinusoid yields corr ~0.82–0.98, wrong frequency
|
||||||
|
collapses to ~0.00. Do **not** tighten shape into a correctness gate —
|
||||||
|
timestamp calibration (Phase-A) is pending.
|
||||||
|
- **Stress** (`run_stress.sh`): 7 axes (signal size/count/fan-out/sources/WS
|
||||||
|
clients/zoom rate), hard gates survival+liveness, soft gates RSS+zoom-p95.
|
||||||
|
- **Coverage**: `--cpp-coverage` rebuilds with gcov, captures via `lcov`
|
||||||
|
restricted to `Source/*` + `Test/*`, then restores a clean build.
|
||||||
|
- Artifacts → `Build/x86-linux/E2E/chain/`: `results.json` (XFAIL/XPASS for
|
||||||
|
`known_issue` markers), `report_data.json`, `history.jsonl`, `trend_*.png`,
|
||||||
|
`E2E_Report.pdf`; stress → `stress/stress_results.json`.
|
||||||
|
|
||||||
Every MARTe2 component directory contains:
|
## Ports Reference (defaults)
|
||||||
|
|
||||||
- `Makefile.gcc` — thin wrapper (`TARGET = x86-linux` then `include Makefile.inc`).
|
|
||||||
- `Makefile.inc` — real build definition: `OBJSX`, `PACKAGE`, `INCLUDES`,
|
|
||||||
`LIBRARIES`, includes `$(MARTe2_DIR)/MakeDefaults/MakeStdLibDefs.$(TARGET)`
|
|
||||||
and `MakeStdLibRules.$(TARGET)`, and `depends.$(TARGET)`.
|
|
||||||
- `depends.x86-linux` / `dependsRaw.x86-linux` — generated header dependency
|
|
||||||
files (committed; regenerated by the build). Do not hand-edit.
|
|
||||||
- `<ClassName>.{h,cpp}` — the implementation, with `CLASS_REGISTER(ClassName,
|
|
||||||
"1.0")` at the bottom of the `.cpp` (MARTe2 class-registration macro).
|
|
||||||
|
|
||||||
To add a new component, copy an existing one and adapt `Makefile.inc`'s
|
|
||||||
`OBJSX` / `PACKAGE` / `INCLUDES` / `LIBRARIES`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Conventions and gotchas
|
|
||||||
|
|
||||||
### No STL in MARTe2 components
|
|
||||||
|
|
||||||
`Source/Components/**` must not use the C++ standard library. Use MARTe2 types:
|
|
||||||
`StreamString` (not `std::string`), `FastPollingMutexSem` (not `std::mutex`),
|
|
||||||
fixed arrays / `StaticList` (not `std::vector`), MARTe2 error macros
|
|
||||||
(`REPORT_ERROR`, `REPORT_ERROR_STATIC`) instead of exceptions. Includes come
|
|
||||||
from `$(MARTe2_DIR)/Source/Core/...` (BareMetal, Scheduler, FileSystem).
|
|
||||||
|
|
||||||
`Source/Applications/StreamHub/` links MARTe2 core and follows the same
|
|
||||||
no-STL-on-RT-paths style, but is a standalone app (not a loadable component).
|
|
||||||
|
|
||||||
STL / C++17 is **fine** in `Client/streamhub/` and `Client/streamhub-qt/`
|
|
||||||
(framework-free C++17, no MARTe2 dependency).
|
|
||||||
|
|
||||||
### RT hot-path mutex rule
|
|
||||||
|
|
||||||
Use `FastPollingMutexSem` on real-time hot paths — never OS mutexes
|
|
||||||
(`pthread_mutex`, `std::mutex`). The RT cycle must not block on the scheduler.
|
|
||||||
|
|
||||||
### Protocol change checklist
|
|
||||||
|
|
||||||
Changing `Common/UDP/UDPSProtocol.h` (or the Go mirror) requires mirroring
|
|
||||||
across all four consumers listed in §1, plus the JS client parsers in
|
|
||||||
`Client/udpstreamer/static/`. The Go decoder lives in
|
|
||||||
`Common/Client/go/udpsprotocol/protocol.go` and re-declares the constants
|
|
||||||
(`HeaderSize`, `SigDescSize`, packet types, quant types, time modes) — it does
|
|
||||||
**not** include the C header.
|
|
||||||
|
|
||||||
### Qt client: `QT_NO_KEYWORDS`
|
|
||||||
|
|
||||||
`Client/streamhub-qt/` reuses `../streamhub/Protocol.{h,cpp}` and
|
|
||||||
`SignalBuffer.h` verbatim. Those structs have members named `signals`, which
|
|
||||||
collide with Qt's `signals`/`slots`/`emit` macros. The Qt build sets
|
|
||||||
`QT_NO_KEYWORDS` and all Qt classes use `Q_SIGNALS:`/`Q_SLOTS:`/`Q_EMIT`. Do
|
|
||||||
not remove that define, and do not use the lowercase Qt keywords in Qt-client
|
|
||||||
code. Single GUI thread — `QWebSocket` signals arrive on the GUI thread, no
|
|
||||||
locks; a 60 Hz `QTimer` drives repaint. Run with long options:
|
|
||||||
`./build/StreamHubQtClient --host HOST --port 8090` (single-dash `-host` is
|
|
||||||
misparsed as clustered short flags).
|
|
||||||
|
|
||||||
### StreamHub history
|
|
||||||
|
|
||||||
`HistoryWriter` (`Source/Applications/StreamHub/HistoryWriter.{h,cpp}`) does
|
|
||||||
disk-backed circular storage: per-signal `.shist` files with a 64-byte header
|
|
||||||
and a pre-allocated circular region of `(float64 time, float64 value)` pairs.
|
|
||||||
Configured via a `+History` block (`Directory` required; `DurationHours`
|
|
||||||
default 1, `Decimation` default 1, `FlushIntervalSec` default 5,
|
|
||||||
`MinDiskFreeMB` default 500). WS commands: `historyInfo`, `historyZoom`.
|
|
||||||
|
|
||||||
### E2E scenario / stress matrix
|
|
||||||
|
|
||||||
`Test/E2E/suite/scenarios.py` is a *curated covering set*: every configurable
|
|
||||||
UDPStreamer option value appears in at least one scenario, plus high-risk
|
|
||||||
interactions. `stress.py` is the capacity sibling — it sweeps one load axis at
|
|
||||||
a time and records survival/liveness (hard gates) and RSS/zoom-p95 latency
|
|
||||||
(soft gates). Both feed the same `gen_data.py` / `gen_cfg.py` generators. When
|
|
||||||
adding a new UDPStreamer option, add a scenario that exercises it and update
|
|
||||||
`validate_scenario` / the stress matrix accordingly.
|
|
||||||
|
|
||||||
`validate_waveform.py` has two gates: **fidelity** (every received value within
|
|
||||||
`tol` of some ground-truth value; `tol` is 0 for un-quantised ints, a float
|
|
||||||
epsilon for un-quantised floats, `quant_step/2 + 1e-6·range` for quantised
|
|
||||||
floats) — this is the **correctness** gate. **Shape** (least-squares sine fit,
|
|
||||||
correlation ≥ 0.99) is a gross-sanity gate + tracked metric, pending Phase-A
|
|
||||||
timestamp calibration. Do not tighten the shape gate to a correctness gate.
|
|
||||||
|
|
||||||
### Gitignored build artefacts
|
|
||||||
|
|
||||||
`Build/`, `compile_commands.json`, `*.gcov`/`*.gcda`/`*.gcno` (coverage), Go
|
|
||||||
binaries (`Client/*/marte2debugger`, `udpstreamer-webui`, `streamhub-e2e`,
|
|
||||||
`Client/*/bin/`), and the `udp_standalone_webui/` scratch dir are all
|
|
||||||
gitignored. `vgore.*` core dumps (e.g. `vgcore.26968`) are not — remove them.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Documentation map
|
|
||||||
|
|
||||||
- `ARCHITECTURE.md` — full architecture: data-flow diagrams, UDPS packet/header
|
|
||||||
tables, CONFIG payload, StreamHub WebSocket protocol (commands, events,
|
|
||||||
binary frames), threading model.
|
|
||||||
- `Docs/` — per-component reference docs (`Protocol.md`, `UDPStreamer.md`,
|
|
||||||
`SineArrayGAM.md`, `DebugService.md`, `StreamHub-{UserGuide,API,Developer}.md`,
|
|
||||||
`Tutorial.md`, `WebUI.md`).
|
|
||||||
- `docs/superpowers/specs/` — design specs (dated, e.g.
|
|
||||||
`2026-06-26-stress-suite-report-integration-design.md`).
|
|
||||||
- `docs/superpowers/plans/` — implementation plans paired with specs.
|
|
||||||
- `.superpowers/sdd/` — task briefs, reports, and a `progress.md` ledger for
|
|
||||||
in-flight feature work (not always present; per-branch).
|
|
||||||
- `README.md` — high-level overview + quick-start config snippets.
|
|
||||||
- `CLAUDE.md` — condensed agent guidance (overlaps with this file).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Ports reference (defaults)
|
|
||||||
|
|
||||||
| Port | Protocol | Component | Purpose |
|
| Port | Protocol | Component | Purpose |
|
||||||
|------|----------|-----------|---------|
|
|---|---|---|---|
|
||||||
| 44500 | UDP | UDPStreamer | scalar signals (unicast control) |
|
| 44500 | UDP | UDPStreamer | scalar signals (unicast control + data) |
|
||||||
| 44501 | UDP | UDPStreamer | packed arrays (FirstSample/LastSample) |
|
| 44501/44502 | UDP | UDPStreamer | packed arrays (FirstSample/LastSample, FullArray) |
|
||||||
| 44502 | UDP | UDPStreamer | packed arrays (FullArray) |
|
|
||||||
| 44503 | UDP | UDPStreamer | multicast data (group 239.0.0.1) |
|
| 44503 | UDP | UDPStreamer | multicast data (group 239.0.0.1) |
|
||||||
| 8080 | TCP | DebugService | text command channel |
|
| 8080 | TCP | DebugService | text command channel (one client at a time, newline-terminated) |
|
||||||
| 8081 | UDP | DebugService | trace telemetry stream |
|
| 8081 | UDP | DebugService | trace telemetry (UDPS format) |
|
||||||
| 8082 | TCP | TcpLogger | REPORT_ERROR log forward |
|
| 8082 | TCP | TcpLogger | REPORT_ERROR log forward |
|
||||||
| 8090 | TCP/WS | StreamHub | WebSocket (commands + binary data) |
|
| 8090 | TCP/WS | StreamHub | WebSocket (commands + binary data) |
|
||||||
| 8080 | TCP | udpstreamer-webui | web UI listen (legacy direct-UDP path) |
|
| 7777 | TCP | Client/debugger | debug web UI (older docs say 9090; current flag is `-addr`) |
|
||||||
| 9090 | TCP | debugger | debug web UI listen |
|
| 8080 | TCP | Client/udpstreamer, Client/webui | web UI listen (collides with DebugService in combined demos — scripts adjust) |
|
||||||
|
|
||||||
Note the 8080 collision: DebugService control vs. the legacy web UI listen port.
|
|
||||||
In combined demos that run both, the scripts adjust one of them — check the
|
|
||||||
script header before assuming.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
EUPL v1.1 — license headers are present on all C++ sources. Preserve them on
|
|
||||||
new files; do not relicense.
|
|
||||||
|
|||||||
@@ -39,7 +39,38 @@ cd Client/streamhub-qt && cmake -B build && cmake --build build
|
|||||||
|
|
||||||
End-to-end demo script (build + launch full stack, see header for ports/options): `./run_streamhub.sh`.
|
End-to-end demo script (build + launch full stack, see header for ports/options): `./run_streamhub.sh`.
|
||||||
|
|
||||||
**Streaming-chain E2E suite** (`Test/E2E/suite/`): `./run_e2e.sh [--skip-build] [--only <id>] [--cpp-coverage]` drives the full chain per scenario (`scenarios.py`) — generates typed/shaped input + both cfgs, runs MARTe2+StreamHub, records via the Go `chain-client` (live/zoom/window/trigger), and validates the recorded waveform against an analytic/fed oracle (`validate_waveform.py`: fidelity gates correctness, sine shape-fit is a gross-sanity gate + tracked metric pending Phase-A timestamp calibration). It then runs the unit suites + coverage (`collect.py`: C++ GTest, Go, Python; `--cpp-coverage` does an instrumented `--coverage` rebuild, captures with lcov restricted to `Source/*` (the `Test/` harness itself is excluded — it executes every line by construction and would just inflate the number), then restores the clean build), consolidates everything into `report_data.json` with per-field progression/regression vs the previous run and trend plots (`report_build.py`, history in `Build/x86-linux/E2E/chain/history.jsonl`), and compiles a Typst PDF (`E2E_Report.typ`). Python framework unit tests: `python3 -m unittest tests_py` (in `Test/E2E/suite/`).
|
**Streaming-chain E2E suite** (`Test/E2E/suite/`):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./Test/E2E/suite/run_e2e.sh [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
|
||||||
|
| Flag | Effect |
|
||||||
|
|---|---|
|
||||||
|
| `--skip-build` | Skip C++ component rebuild |
|
||||||
|
| `--only <id>` | Run a single scenario by ID |
|
||||||
|
| `--pdf-only` | Just compile the Typst PDF report |
|
||||||
|
| `--cpp-coverage` | Instrumented gcov rebuild + lcov capture (on by default) |
|
||||||
|
| `--skip-coverage` | Disable the coverage pass |
|
||||||
|
| `--skip-stress` | Skip the stress matrix |
|
||||||
|
| `--skip-datasources` | Skip `direct` scenarios |
|
||||||
|
| `--skip-recorder` | Skip `recorder` scenarios |
|
||||||
|
| `--skip-debug` | Skip `debug` and `debug_pause_resume` scenarios |
|
||||||
|
| `--skip-tcplogger` | Skip `tcplogger` scenarios |
|
||||||
|
|
||||||
|
Scenario kinds (defined in `scenarios.py`):
|
||||||
|
|
||||||
|
- **chain** — full streaming pipeline: MARTe2 → UDPStreamer → StreamHub → Go `chain-client` (live/zoom/window/trigger). Validates recorded waveform against analytic/fed oracle (`validate_waveform.py`: fidelity gates correctness, sine shape-fit is a gross-sanity gate + tracked metric).
|
||||||
|
- **direct** — MARTe2 FileReader → FileWriter round-trip, validates binary output.
|
||||||
|
- **recorder** — MARTe2 → StreamHub with history recorder, validates recorded `.bin` file.
|
||||||
|
- **debug / debug_pause_resume** — DebugService scenarios via the Go `debugclient`.
|
||||||
|
- **tcplogger** — TcpLogger scenarios via the Go `debugclient`.
|
||||||
|
|
||||||
|
After scenarios, the suite runs unit tests + coverage (`collect.py`: C++ GTest, Go, Python; coverage uses lcov restricted to `Source/*` — the `Test/` harness is excluded), consolidates everything into `report_data.json` with per-field progression/regression vs the previous run and trend plots (`report_build.py`, history in `Build/x86-linux/E2E/chain/history.jsonl`), and compiles a Typst PDF (`E2E_Report.typ`). Artifacts go to `Build/x86-linux/E2E/chain/` (report, logs, PDF) and `/tmp/chain_e2e/` (scratch). Results are aggregated into `results.json` with XFAIL/XPASS handling for known issues.
|
||||||
|
|
||||||
|
Python framework unit tests: `python3 -m unittest tests_py` (in `Test/E2E/suite/`).
|
||||||
|
|
||||||
Build output goes to `Build/x86-linux/` (shared libs per component, `.ex` executables).
|
Build output goes to `Build/x86-linux/` (shared libs per component, `.ex` executables).
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,20 @@ func BuildDisconnectPacket() []byte {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BuildAckPacket returns a 17-byte ACK datagram. Unicast clients send it
|
||||||
|
// periodically as a keepalive: UDPSServer refreshes the client's last-seen
|
||||||
|
// without re-sending CONFIG (which a repeated CONNECT would trigger).
|
||||||
|
func BuildAckPacket() []byte {
|
||||||
|
return buildHeader(PacketHeader{
|
||||||
|
Magic: MagicUDPS,
|
||||||
|
Type: PktACK,
|
||||||
|
Counter: 0,
|
||||||
|
FragmentIdx: 0,
|
||||||
|
TotalFragments: 1,
|
||||||
|
PayloadBytes: 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// ─── Signal descriptor (136 bytes) ───────────────────────────────────────────
|
// ─── Signal descriptor (136 bytes) ───────────────────────────────────────────
|
||||||
|
|
||||||
// SignalInfo holds the parsed metadata for one signal.
|
// SignalInfo holds the parsed metadata for one signal.
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package wshub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"marte2/common/udpsprotocol"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestUDPClientSendsPeriodicKeepAliveAcks verifies that a unicast UDPClient
|
||||||
|
// re-sends ACK datagrams from the SAME socket at keepAliveInterval. The
|
||||||
|
// UDPSServer refreshes a unicast client's last-seen only on client->server
|
||||||
|
// traffic; without this keepalive it evicts the client after ClientTimeout
|
||||||
|
// (default 30 s) and the stream dies.
|
||||||
|
func TestUDPClientSendsPeriodicKeepAliveAcks(t *testing.T) {
|
||||||
|
srv, err := net.ListenUDP("udp4", &net.UDPAddr{IP: net.ParseIP("127.0.0.1")})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer srv.Close()
|
||||||
|
|
||||||
|
c := NewUDPClient(srv.LocalAddr().String(), "ka1", NewHub(), "", 0)
|
||||||
|
c.keepAliveInterval = 150 * time.Millisecond
|
||||||
|
go c.Run()
|
||||||
|
defer c.Stop()
|
||||||
|
|
||||||
|
buf := make([]byte, 512)
|
||||||
|
|
||||||
|
// 1) CONNECT from the client's ephemeral socket.
|
||||||
|
srv.SetReadDeadline(time.Now().Add(3 * time.Second))
|
||||||
|
n, clientAddr, err := srv.ReadFromUDP(buf)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected CONNECT: %v", err)
|
||||||
|
}
|
||||||
|
hdr, err := udpsprotocol.ParseHeader(buf[:n])
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("parse CONNECT: %v", err)
|
||||||
|
}
|
||||||
|
if hdr.Type != udpsprotocol.PktConnect {
|
||||||
|
t.Fatalf("first packet type = %d, want CONNECT (%d)", hdr.Type, udpsprotocol.PktConnect)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) Collect ACKs for ~1 s: must be periodic and from the SAME socket
|
||||||
|
// (a new ephemeral socket would be registered as a new client).
|
||||||
|
deadline := time.Now().Add(time.Second)
|
||||||
|
acks := 0
|
||||||
|
for time.Now().Before(deadline) {
|
||||||
|
srv.SetReadDeadline(deadline)
|
||||||
|
n, addr, err := srv.ReadFromUDP(buf)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
hdr, err := udpsprotocol.ParseHeader(buf[:n])
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if hdr.Type != udpsprotocol.PktACK {
|
||||||
|
t.Fatalf("unexpected packet type %d from %s", hdr.Type, addr)
|
||||||
|
}
|
||||||
|
if addr.String() != clientAddr.String() {
|
||||||
|
t.Fatalf("ACK from %s, want same socket as CONNECT (%s)", addr, clientAddr)
|
||||||
|
}
|
||||||
|
acks++
|
||||||
|
}
|
||||||
|
if acks < 3 {
|
||||||
|
t.Fatalf("expected >= 3 keepalive ACKs in 1 s, got %d", acks)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -172,27 +172,34 @@ const (
|
|||||||
reconnectDelay = 2 * time.Second
|
reconnectDelay = 2 * time.Second
|
||||||
readBufSize = 65536
|
readBufSize = 65536
|
||||||
udpRcvBufSize = 8 * 1024 * 1024
|
udpRcvBufSize = 8 * 1024 * 1024
|
||||||
|
// keepAliveInterval is the unicast keepalive period. The UDPStreamer
|
||||||
|
// server evicts silent unicast clients after its ClientTimeout (default
|
||||||
|
// 30 s); an ACK from the same socket refreshes its last-seen without
|
||||||
|
// triggering a CONFIG resend (a CONNECT would).
|
||||||
|
keepAliveInterval = 15 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
// UDPClient manages the connection to one MARTe2 streamer source.
|
// UDPClient manages the connection to one MARTe2 streamer source.
|
||||||
type UDPClient struct {
|
type UDPClient struct {
|
||||||
serverAddr string
|
serverAddr string
|
||||||
sourceID string
|
sourceID string
|
||||||
hub *Hub
|
hub *Hub
|
||||||
multicastGroup string
|
multicastGroup string
|
||||||
dataPort int
|
dataPort int
|
||||||
stopCh chan struct{}
|
keepAliveInterval time.Duration
|
||||||
|
stopCh chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewUDPClient creates a UDPClient bound to a specific source ID.
|
// NewUDPClient creates a UDPClient bound to a specific source ID.
|
||||||
func NewUDPClient(serverAddr, sourceID string, hub *Hub, multicastGroup string, dataPort int) *UDPClient {
|
func NewUDPClient(serverAddr, sourceID string, hub *Hub, multicastGroup string, dataPort int) *UDPClient {
|
||||||
return &UDPClient{
|
return &UDPClient{
|
||||||
serverAddr: serverAddr,
|
serverAddr: serverAddr,
|
||||||
sourceID: sourceID,
|
sourceID: sourceID,
|
||||||
hub: hub,
|
hub: hub,
|
||||||
multicastGroup: multicastGroup,
|
multicastGroup: multicastGroup,
|
||||||
dataPort: dataPort,
|
dataPort: dataPort,
|
||||||
stopCh: make(chan struct{}),
|
keepAliveInterval: keepAliveInterval,
|
||||||
|
stopCh: make(chan struct{}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,6 +260,20 @@ func (u *UDPClient) runSession() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Printf("[%s] udp: sent CONNECT", u.sourceID)
|
log.Printf("[%s] udp: sent CONNECT", u.sourceID)
|
||||||
|
lastData := time.Now()
|
||||||
|
lastKeepAlive := time.Now()
|
||||||
|
// sendKeepAliveIfDue sends an ACK if the keepalive interval has elapsed.
|
||||||
|
// ACK refreshes the server's last-seen without re-sending CONFIG (which a
|
||||||
|
// repeated CONNECT would trigger).
|
||||||
|
sendKeepAliveIfDue := func() error {
|
||||||
|
if u.keepAliveInterval > 0 && time.Since(lastKeepAlive) >= u.keepAliveInterval {
|
||||||
|
if _, err := conn.WriteToUDP(udpsprotocol.BuildAckPacket(), serverAddr); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
lastKeepAlive = time.Now()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
reassembler := udpsprotocol.NewReassembler(2 * time.Second)
|
reassembler := udpsprotocol.NewReassembler(2 * time.Second)
|
||||||
buf := make([]byte, readBufSize)
|
buf := make([]byte, readBufSize)
|
||||||
@@ -260,14 +281,34 @@ func (u *UDPClient) runSession() error {
|
|||||||
var currentPublishMode uint8
|
var currentPublishMode uint8
|
||||||
|
|
||||||
for {
|
for {
|
||||||
conn.SetReadDeadline(time.Now().Add(silenceTimeout))
|
// Wake up at least every keepalive interval so ACKs are sent even
|
||||||
|
// when the server is idle; the read deadline also doubles as the
|
||||||
|
// silence detector (no data for silenceTimeout = server gone).
|
||||||
|
wakeup := silenceTimeout
|
||||||
|
if u.keepAliveInterval > 0 && u.keepAliveInterval < wakeup {
|
||||||
|
wakeup = u.keepAliveInterval
|
||||||
|
}
|
||||||
|
conn.SetReadDeadline(time.Now().Add(wakeup))
|
||||||
|
|
||||||
n, _, err := conn.ReadFromUDP(buf)
|
n, _, err := conn.ReadFromUDP(buf)
|
||||||
arrivalTime := time.Now()
|
arrivalTime := time.Now()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if ne, ok := err.(net.Error); ok && ne.Timeout() {
|
||||||
|
if time.Since(lastData) >= silenceTimeout {
|
||||||
|
// True silence: stream is dead — Run() reconnects.
|
||||||
|
conn.WriteToUDP(udpsprotocol.BuildDisconnectPacket(), serverAddr)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Short wakeup: keepalive if due, then keep waiting.
|
||||||
|
if kaErr := sendKeepAliveIfDue(); kaErr != nil {
|
||||||
|
return kaErr
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
conn.WriteToUDP(udpsprotocol.BuildDisconnectPacket(), serverAddr)
|
conn.WriteToUDP(udpsprotocol.BuildDisconnectPacket(), serverAddr)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
lastData = arrivalTime
|
||||||
|
|
||||||
if n < udpsprotocol.HeaderSize {
|
if n < udpsprotocol.HeaderSize {
|
||||||
log.Printf("[%s] udp: short datagram (%d bytes), skipping", u.sourceID, n)
|
log.Printf("[%s] udp: short datagram (%d bytes), skipping", u.sourceID, n)
|
||||||
@@ -334,6 +375,10 @@ func (u *UDPClient) runSession() error {
|
|||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if kaErr := sendKeepAliveIfDue(); kaErr != nil {
|
||||||
|
return kaErr
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,282 @@
|
|||||||
|
# E2E Test Suite
|
||||||
|
|
||||||
|
The streaming-chain end-to-end suite (`Test/E2E/suite/`) validates the full data path from
|
||||||
|
MARTe2 real-time application through the UDPS wire protocol to StreamHub and client consumers.
|
||||||
|
It also covers the debug/trace path (DebugService, TCPLogger) and the direct
|
||||||
|
UDPStreamer-to-UDPStreamerClient round-trip.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The suite is driven by a single orchestrator script:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source env.sh
|
||||||
|
./Test/E2E/suite/run_e2e.sh [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
For each scenario defined in `scenarios.py`, the orchestrator:
|
||||||
|
|
||||||
|
1. **Generates input data** (`gen_data.py`) — deterministic typed/shaped binary in MARTe2
|
||||||
|
FileReader format, plus a ground-truth dict for the validator.
|
||||||
|
2. **Generates configs** (`gen_cfg.py`) — MARTe2 app config (LinuxTimer + FileReader + IOGAM +
|
||||||
|
UDPStreamer) and StreamHub config, per scenario.
|
||||||
|
3. **Launches the server stack** — MARTe2 app + StreamHub (for chain/recorder scenarios) or
|
||||||
|
MARTe2 app alone (for direct/debug scenarios).
|
||||||
|
4. **Drives mock clients** — the Go `chain-client` (chain scenarios) or `debugclient`
|
||||||
|
(debug/tcplogger scenarios) connects, records data, and runs behavioural checks.
|
||||||
|
5. **Validates** (`validate_waveform.py`) — compares the recorded stream against the analytic
|
||||||
|
ground truth and/or the fed-reference tap file.
|
||||||
|
6. **Renders plots** (`plots.py`) — waveform, trigger, and zoom overlay PNGs per scenario.
|
||||||
|
7. **Runs unit tests + coverage** (`collect.py`) — C++ GTest, Go, and Python suites with
|
||||||
|
optional lcov C++ line coverage.
|
||||||
|
8. **Runs stress matrix** (`stress_run.py` / `stress.py`) — capacity sweeps (signal size,
|
||||||
|
count, fan-out, zoom rate) with survival/liveness/RSS/latency gates.
|
||||||
|
9. **Builds the report** (`report_build.py`) — consolidates everything into
|
||||||
|
`report_data.json` with regression tracking against the previous run, trend plots, and a
|
||||||
|
Typst PDF (`E2E_Report.typ`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Flags
|
||||||
|
|
||||||
|
| Flag | Effect |
|
||||||
|
| -------------------- | -------------------------------------------------------- |
|
||||||
|
| `--skip-build` | Skip C++ component rebuild |
|
||||||
|
| `--only <id>` | Run a single scenario by ID |
|
||||||
|
| `--pdf-only` | Just compile the Typst PDF report (no tests) |
|
||||||
|
| `--cpp-coverage` | Instrumented gcov rebuild + lcov capture (on by default) |
|
||||||
|
| `--skip-coverage` | Disable the coverage pass |
|
||||||
|
| `--skip-stress` | Skip the stress matrix |
|
||||||
|
| `--skip-datasources` | Skip `direct` scenarios |
|
||||||
|
| `--skip-recorder` | Skip `recorder` scenarios |
|
||||||
|
| `--skip-debug` | Skip `debug` and `debug_pause_resume` scenarios |
|
||||||
|
| `--skip-tcplogger` | Skip `tcplogger` scenarios |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Scenario Kinds
|
||||||
|
|
||||||
|
### chain
|
||||||
|
|
||||||
|
Full streaming pipeline: MARTe2 (FileReader -> IOGAM -> UDPStreamer) -> StreamHub -> Go
|
||||||
|
`chain-client`. The client records the live binary stream and runs behavioural checks
|
||||||
|
(live, zoom, window, trigger). The validator compares the recording against the analytic
|
||||||
|
ground truth (fidelity, sine shape fit, continuity) and optionally a fed-reference tap.
|
||||||
|
|
||||||
|
### direct
|
||||||
|
|
||||||
|
MARTe2 FileReader -> UDPStreamer -> UDPStreamerClient -> FileWriter round-trip. Validates that
|
||||||
|
the written binary matches the input binary (bit-exact for each signal type).
|
||||||
|
|
||||||
|
### recorder
|
||||||
|
|
||||||
|
MARTe2 -> UDPStreamer -> StreamHub with BinaryRecorder enabled. Validates the `.bin` file
|
||||||
|
written to disk by the recorder against the original input.
|
||||||
|
|
||||||
|
### debug / debug_pause_resume
|
||||||
|
|
||||||
|
DebugService scenarios exercising FORCE, TRACE, and BREAK commands over TCP (port 8080) with
|
||||||
|
trace telemetry on UDP (port 8081). The Go `debugclient` scripts a fixed command sequence and
|
||||||
|
verifies real acknowledgements. The `debug_pause_resume` variant additionally verifies that
|
||||||
|
PAUSE halts the RT loop and RESUME restarts it via live VALUE polling.
|
||||||
|
|
||||||
|
### tcplogger
|
||||||
|
|
||||||
|
TCPLogger delivery: verifies that a triggered DebugService event produces a log line on the
|
||||||
|
TCPLogger TCP port (8082/9090).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Validation Oracles
|
||||||
|
|
||||||
|
Each chain scenario specifies an `oracle` mode:
|
||||||
|
|
||||||
|
- **analytic** — ground truth is reconstructed from `gen_data.py`'s deterministic formulas
|
||||||
|
(sine, ramp, counter, time_us, time_ns). No reference file needed.
|
||||||
|
- **fed** — a second IOGAM branch in the MARTe config taps the same signals into a FileWriter
|
||||||
|
("tap file"). The validator compares recordings against this tap.
|
||||||
|
- **both** — both oracles are applied.
|
||||||
|
|
||||||
|
Per-signal checks (`validate_waveform.py`):
|
||||||
|
|
||||||
|
| Check | Description |
|
||||||
|
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| **Fidelity** | Every received value within tolerance of some ground-truth value. Tolerance is 0 for raw integers, float epsilon for raw floats, `quant_step/2 + 1e-6*range` for quantised floats. |
|
||||||
|
| **Shape** | Sine signals (>= 8 points): least-squares fit of `a*sin(wt)+b*cos(wt)+c`. Requires correlation >= 0.99 and low normalised RMSE (relaxed by quant step). |
|
||||||
|
| **Fed reference** | When `--tap` is given, each received value must also match the tap. |
|
||||||
|
| **Continuity** | Flags inter-sample gaps > 10x median spacing. Fails when summed gap duration exceeds 5% of capture span. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Client Checks
|
||||||
|
|
||||||
|
The Go `chain-client` (`Test/E2E/suite/client/`) performs behavioural checks specified per
|
||||||
|
scenario in `client_checks`:
|
||||||
|
|
||||||
|
| Check | What it verifies |
|
||||||
|
| --------- | ----------------------------------------------------------------------------------------------- |
|
||||||
|
| `live` | WebSocket connection succeeds and live binary pushes arrive with monotonic timestamps. |
|
||||||
|
| `zoom` | A `zoom` WS command returns a valid binary response covering the requested time range. |
|
||||||
|
| `window` | A `window` WS command returns data within the specified time bounds. |
|
||||||
|
| `trigger` | A `trigger` WS command on the specified signal fires and returns data around the trigger point. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stress Matrix
|
||||||
|
|
||||||
|
The stress module (`stress.py` + `stress_run.py`) exercises capacity by sweeping one load axis
|
||||||
|
at a time:
|
||||||
|
|
||||||
|
| Axis | What is scaled |
|
||||||
|
| ------------------ | ------------------------------------------------------------ |
|
||||||
|
| Signal size | Bytes per packet (array element count) |
|
||||||
|
| Signal count | Number of signals per source |
|
||||||
|
| Subscriber fan-out | Number of StreamHub instances subscribing to one UDPStreamer |
|
||||||
|
| WS client count | Parallel WebSocket clients on one StreamHub |
|
||||||
|
| Zoom request rate | Concurrent zoom queries per second per client |
|
||||||
|
|
||||||
|
Gates:
|
||||||
|
|
||||||
|
- **Survival** (hard) — neither server crashed or hung.
|
||||||
|
- **Liveness** (hard) — every client received monotonic, timestamped pushes.
|
||||||
|
- **Peak RSS** (soft) — MARTe and StreamHub memory stayed under case ceilings.
|
||||||
|
- **Zoom p95 latency** (soft) — round-trip zoom query latency under load.
|
||||||
|
|
||||||
|
Results are written to `stress_results.json` with axis/level for scaling-curve plots.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Artifacts
|
||||||
|
|
||||||
|
| Path | Content |
|
||||||
|
| -------------------------------------------- | ------------------------------------------------------------------- |
|
||||||
|
| `Build/x86-linux/E2E/chain/results.json` | Per-scenario status (PASS/FAIL/SKIP/XFAIL/XPASS) + waveform metrics |
|
||||||
|
| `Build/x86-linux/E2E/chain/report_data.json` | Full report data including regression diffs |
|
||||||
|
| `Build/x86-linux/E2E/chain/history.jsonl` | One-line-per-run headline metrics for trend tracking |
|
||||||
|
| `Build/x86-linux/E2E/chain/trend_*.png` | Pass-rate / coverage / fidelity / memory trend plots |
|
||||||
|
| `Build/x86-linux/E2E/chain/E2E_Report.pdf` | Compiled Typst PDF report |
|
||||||
|
| `Build/x86-linux/E2E/chain/unit_tests.json` | Per-suite test results (GTest, Go, Python) |
|
||||||
|
| `Build/x86-linux/E2E/chain/coverage.json` | Per-language coverage percentages |
|
||||||
|
| `Build/x86-linux/E2E/chain/stress/` | Stress matrix results |
|
||||||
|
| `Build/x86-linux/E2E/chain/hub_<id>.log` | StreamHub stdout/stderr per scenario |
|
||||||
|
| `Build/x86-linux/E2E/chain/marte_<id>.log` | MARTe2 app stdout/stderr per scenario |
|
||||||
|
| `Build/x86-linux/E2E/chain/client_<id>.log` | Client stdout/stderr per scenario |
|
||||||
|
| `/tmp/chain_e2e/` | Scratch: input binaries, configs, recordings, metrics, plots |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## XFAIL / XPASS Handling
|
||||||
|
|
||||||
|
Scenarios may carry a `known_issue` marker (a human-readable string describing a documented,
|
||||||
|
not-yet-fixed chain gap). When present:
|
||||||
|
|
||||||
|
- A raw **FAIL** is reclassified as **XFAIL** (expected failure) — does not break the green
|
||||||
|
baseline.
|
||||||
|
- A raw **PASS** becomes **XPASS** (unexpectedly fixed) — surfaced as a failure to prompt
|
||||||
|
removal of the stale marker.
|
||||||
|
|
||||||
|
Overall status is PASS when there are no hard FAILs and no XPASSes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Framework Files
|
||||||
|
|
||||||
|
| File | Role |
|
||||||
|
| ---------------------- | --------------------------------------------------------------- |
|
||||||
|
| `run_e2e.sh` | Top-level orchestrator (build, run scenarios, coverage, report) |
|
||||||
|
| `scenarios.py` | Declarative scenario matrix + validation |
|
||||||
|
| `gen_data.py` | Deterministic input binary generator |
|
||||||
|
| `gen_cfg.py` | MARTe2 + StreamHub config generator |
|
||||||
|
| `validate_waveform.py` | Waveform comparison (fidelity, shape, continuity) |
|
||||||
|
| `plots.py` | Per-scenario PNG figure renderer |
|
||||||
|
| `collect.py` | Unit test runner + coverage collector (GTest, Go, Python, lcov) |
|
||||||
|
| `report_build.py` | Report data consolidator + trend plots + history |
|
||||||
|
| `stress.py` | Declarative stress case matrix |
|
||||||
|
| `stress_run.py` | Stress matrix orchestrator |
|
||||||
|
| `proc_perf.py` | Live-process CPU/RSS snapshot from `/proc` |
|
||||||
|
| `E2E_Report.typ` | Typst template for the PDF report |
|
||||||
|
| `tests_py.py` | Python framework unit tests (`python3 -m unittest tests_py`) |
|
||||||
|
| `client/main.go` | Go chain-client (live record + zoom/window/trigger checks) |
|
||||||
|
| `debugclient/main.go` | Go debug/tcplogger client (command scripting + verification) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Scenario Matrix
|
||||||
|
|
||||||
|
| ID | Kind | Description |
|
||||||
|
| ----------------------------- | ------------------ | ---------------------------------------------------------------------------------------- |
|
||||||
|
| `s01_scalar_uint32` | chain | Single uint32 scalar counter, Strict unicast (type fidelity) |
|
||||||
|
| `s02_array_float32_fullarray` | chain | 100-elem float32 array, FullArray time mode, uint64 ns time array |
|
||||||
|
| `s03_quant_uint16` | chain | float32 scalar quantised to uint16 over [-5,5], Strict unicast |
|
||||||
|
| `s04_int8_scalar` | chain | int8 scalar counter, type fidelity |
|
||||||
|
| `s05_uint8_scalar` | chain | uint8 scalar counter, type fidelity |
|
||||||
|
| `s06_int16_scalar` | chain | int16 scalar ramp, type fidelity |
|
||||||
|
| `s07_uint16_scalar` | chain | uint16 scalar ramp, type fidelity |
|
||||||
|
| `s08_int32_scalar` | chain | int32 scalar counter, type fidelity |
|
||||||
|
| `s09_int64_scalar` | chain | int64 scalar counter, type fidelity |
|
||||||
|
| `s10_uint64_scalar` | chain | uint64 scalar counter, type fidelity |
|
||||||
|
| `s11_float64_scalar` | chain | float64 scalar sine 5 Hz (double-precision path) |
|
||||||
|
| `s12_f32_arr8` | chain | float32 8-elem array sine 5 Hz |
|
||||||
|
| `s13_f32_arr32` | chain | float32 32-elem array sine 10 Hz |
|
||||||
|
| `s14_f64_arr64` | chain | float64 64-elem array ramp |
|
||||||
|
| `s15_i16_arr16` | chain | int16 16-elem array counter |
|
||||||
|
| `s16_f32_arr256` | chain | float32 256-elem array sine 5 Hz (large frame) |
|
||||||
|
| `s17_lastsample` | chain | float32 8-elem LastSample, uint64 ns scalar anchor |
|
||||||
|
| `s18_firstsample` | chain | float32 8-elem FirstSample, uint32 us scalar anchor |
|
||||||
|
| `s19_fullarray_f64` | chain | float64 50-elem FullArray sine 5 Hz, uint64 ns time |
|
||||||
|
| `s20_quant_uint8` | chain | float32 scalar quant uint8 [-1,1] sine 5 Hz |
|
||||||
|
| `s21_quant_int8` | chain | float32 scalar quant int8 [-10,10] sine 5 Hz |
|
||||||
|
| `s22_quant_int16` | chain | float32 scalar quant int16 [-100,100] ramp |
|
||||||
|
| `s23_quant_f64_arr` | chain | float64 16-elem quant uint16 [-2,2] sine 5 Hz |
|
||||||
|
| `s24_accumulate` | chain | float32 scalar sine 5 Hz, Accumulate @50 Hz refresh |
|
||||||
|
| `s25_decimate4` | chain | float32 scalar sine 5 Hz, Decimate ratio 4 |
|
||||||
|
| `s26_decimate10_arr` | chain | float32 8-elem counter, Decimate ratio 10 |
|
||||||
|
| `s27_frag_f64_128` | chain | float64 128-elem ramp, MaxPayload 512 (fragmented) |
|
||||||
|
| `s28_frag_f32_100` | chain | float32 100-elem sine 5 Hz, MaxPayload 256 (fragmented) |
|
||||||
|
| `s29_mcast_scalar` | chain | multicast float32 scalar sine 5 Hz |
|
||||||
|
| `s30_mcast_arr_fullarray` | chain | multicast float32 32-elem FullArray sine 5 Hz |
|
||||||
|
| `s31_two_src` | chain | two unicast sources: float32 sine + uint32 counter |
|
||||||
|
| `s32_three_src` | chain | three unicast sources: int16 ramp / float64 sine / uint8 counter |
|
||||||
|
| `s33_dec_arr_quant` | chain | Decimate 2 + 16-elem quant uint16 sine 5 Hz |
|
||||||
|
| `s34_acc_fullarray` | chain | Accumulate @100 Hz: accumulated scalar + 32-elem FullArray sine passenger |
|
||||||
|
| `s35_mcast_decimate` | chain | multicast + Decimate ratio 5, float32 scalar sine 5 Hz |
|
||||||
|
| `s36_big_frag_dec` | chain | float64 64-elem ramp, MaxPayload 256 + Decimate 4 |
|
||||||
|
| `s37_trig_ramp_i32` | chain | trigger on int32 ramp scalar |
|
||||||
|
| `s38_trig_f64_sine` | chain | trigger on float64 sine 5 Hz scalar |
|
||||||
|
| `s39_uint8_arr32` | chain | uint8 32-elem array counter (wrap fidelity) |
|
||||||
|
| `s40_int8_arr16` | chain | int8 16-elem array counter (wrap fidelity) |
|
||||||
|
| `s41_f32_unit` | chain | float32 scalar ramp with Unit=V |
|
||||||
|
| `s42_f64_counter` | chain | float64 scalar counter (large integer values) |
|
||||||
|
| `s43_fullarray_quant` | chain | float32 16-elem FullArray quant uint16 sine 5 Hz |
|
||||||
|
| `s44_window_check` | chain | float32 sine 5 Hz scalar, window time-range check |
|
||||||
|
| `s45_decimate_multisig` | chain | Decimate ratio 2 over a 2-signal source |
|
||||||
|
| `s46_accumulate_arr` | chain | Accumulate @200 Hz: accumulated scalar sine + 16-elem array passenger |
|
||||||
|
| `s47_mcast_multisrc` | chain | multicast, two sources (scalar each) |
|
||||||
|
| `s48_f64_arr_big_payload` | chain | float64 100-elem ramp, MaxPayload 65490 (single frame) |
|
||||||
|
| `s49_mixed_quant_raw` | chain | one source: quant uint8 sine + raw float32 sine |
|
||||||
|
| `s50_trig_quant` | chain | trigger on quantised uint16 sine 10 Hz |
|
||||||
|
| `s51_8x1msps_100hz` | chain | 8x float32 10k-elem arrays @1 MSps, FirstSample, 100 Hz packets (~32 MB/s) |
|
||||||
|
| `s52_direct_unicast` | direct | Direct UDPStreamer->UDPStreamerClient round-trip, unicast |
|
||||||
|
| `s53_direct_multicast` | direct | Direct UDPStreamer->UDPStreamerClient round-trip, multicast |
|
||||||
|
| `s54_recorder` | recorder | StreamHub BinaryRecorder disk-output round-trip |
|
||||||
|
| `s55_debug_force_trace_break` | debug | DebugService FORCE/TRACE/BREAK over real TCP 8080 + UDP 8081 |
|
||||||
|
| `s56_tcplogger_delivery` | tcplogger | TCPLogger delivers a log line for a triggered DebugService event |
|
||||||
|
| `s57_debug_pause_resume` | debug_pause_resume | DebugService PAUSE/RESUME halts and resumes the RT loop, verified via live VALUE polling |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Coverage Goals
|
||||||
|
|
||||||
|
The chain scenario matrix is a curated covering set: every configurable UDPStreamer option
|
||||||
|
value appears in at least one scenario:
|
||||||
|
|
||||||
|
- **All 10 MARTe2 types**: int8, uint8, int16, uint16, int32, uint32, int64, uint64, float32, float64
|
||||||
|
- **Scalar and array shapes**: elements 1, 8, 16, 32, 50, 64, 100, 128, 256, 1000, 10000
|
||||||
|
- **All four TimeModes**: PacketTime, FullArray, FirstSample, LastSample
|
||||||
|
- **All five QuantizedTypes**: none, uint8, int8, uint16, int16
|
||||||
|
- **All three PublishingModes**: Strict, Accumulate, Decimate
|
||||||
|
- **Both network modes**: unicast and multicast
|
||||||
|
- **Fragmentation**: small MaxPayloadSize forcing multi-fragment datagrams
|
||||||
|
- **Multi-source**: 1, 2, and 3 independent UDPStreamer feeds into one StreamHub
|
||||||
|
- **High-risk interactions**: decimate+quant+array, accumulate+fullarray, multicast+decimate,
|
||||||
|
fragmentation+decimate, mixed quant+raw signals
|
||||||
+145
-31
@@ -8,7 +8,9 @@ thread.
|
|||||||
## Key Features
|
## Key Features
|
||||||
|
|
||||||
- **Zero-copy RT path** — `Synchronise()` only locks, copies signal memory, and posts a semaphore.
|
- **Zero-copy RT path** — `Synchronise()` only locks, copies signal memory, and posts a semaphore.
|
||||||
- **Single-client model** — one client at a time; a new CONNECT replaces the previous session.
|
- **Unicast and multicast** — unicast (default): single client at a time, new CONNECT replaces
|
||||||
|
the previous session. Multicast: multiple clients receive data simultaneously by joining
|
||||||
|
a multicast group; control traffic uses a TCP listener.
|
||||||
- **Packet fragmentation** — large payloads are split into ≤ `MaxPayloadSize`-byte datagrams,
|
- **Packet fragmentation** — large payloads are split into ≤ `MaxPayloadSize`-byte datagrams,
|
||||||
each with a header carrying fragment index and total count so the client can reassemble them.
|
each with a header carrying fragment index and total count so the client can reassemble them.
|
||||||
- **Signal quantization** — `float32`/`float64` signals can be linearly quantized to
|
- **Signal quantization** — `float32`/`float64` signals can be linearly quantized to
|
||||||
@@ -16,6 +18,8 @@ thread.
|
|||||||
- **Temporal arrays** — signals with `NumberOfElements > 1` can carry per-sample time
|
- **Temporal arrays** — signals with `NumberOfElements > 1` can carry per-sample time
|
||||||
metadata via `TimeMode` and `TimeSignal`, enabling high-frequency burst transmission
|
metadata via `TimeMode` and `TimeSignal`, enabling high-frequency burst transmission
|
||||||
(e.g. 1 000 samples per RT cycle at 1 MSps).
|
(e.g. 1 000 samples per RT cycle at 1 MSps).
|
||||||
|
- **Publishing modes** — `Strict` (one packet per RT cycle), `Accumulate` (batch N snapshots
|
||||||
|
then flush on size or time limit), `Decimate` (send every Nth cycle).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -26,10 +30,22 @@ thread.
|
|||||||
Class = UDPStreamer
|
Class = UDPStreamer
|
||||||
|
|
||||||
// Network
|
// Network
|
||||||
Port = 44500 // UDP port the server listens on (default: 44500)
|
Port = 44500 // UDP port (unicast) or TCP control port (multicast)
|
||||||
MaxPayloadSize = 1400 // Maximum bytes per UDP datagram (default: 1400)
|
MaxPayloadSize = 1400 // Maximum bytes per UDP datagram (default: 1400)
|
||||||
// Must be > 17 (header size). Tune for MTU.
|
// Must be > 17 (header size). Tune for MTU.
|
||||||
|
|
||||||
|
// Multicast (optional — omit for unicast mode)
|
||||||
|
MulticastGroup = "239.0.0.1" // IPv4 multicast address (224.0.0.0/4)
|
||||||
|
Interface = "eth0" // Multicast-bound interface (mandatory when MulticastGroup is set)
|
||||||
|
DataPort = 44501 // UDP port for multicast DATA (default: Port+1)
|
||||||
|
|
||||||
|
// Publishing mode (optional)
|
||||||
|
PublishingMode = "Strict" // Strict | Accumulate | Decimate
|
||||||
|
// For Accumulate mode:
|
||||||
|
MinRefreshRate = 120.0 // Flush frequency in Hz (required for Accumulate)
|
||||||
|
// For Decimate mode:
|
||||||
|
Ratio = 10 // Send 1 packet every N RT cycles (required for Decimate)
|
||||||
|
|
||||||
// Background thread (optional)
|
// Background thread (optional)
|
||||||
CPUMask = 0x2 // CPU affinity mask for the network thread
|
CPUMask = 0x2 // CPU affinity mask for the network thread
|
||||||
StackSize = 1048576 // Stack size in bytes (default: 1 MiB)
|
StackSize = 1048576 // Stack size in bytes (default: 1 MiB)
|
||||||
@@ -66,34 +82,40 @@ thread.
|
|||||||
|
|
||||||
### Top-level Parameters
|
### Top-level Parameters
|
||||||
|
|
||||||
| Parameter | Type | Default | Description |
|
| Parameter | Type | Default | Description |
|
||||||
|-----------|------|---------|-------------|
|
| ---------------- | ------ | ---------------- | --------------------------------------------------------------------------- |
|
||||||
| `Port` | uint16 | 44500 | UDP server port |
|
| `Port` | uint16 | 44500 | UDP server port (unicast) or TCP control port (multicast). Values ≤ 1024 produce a warning. |
|
||||||
| `MaxPayloadSize` | uint32 | 1400 | Max payload bytes per UDP datagram (min 18) |
|
| `MaxPayloadSize` | uint32 | 1400 | Max payload bytes per UDP datagram (min 18) |
|
||||||
| `CPUMask` | uint32 | 0 (any) | Background thread CPU affinity |
|
| `MulticastGroup` | string | *(absent)* | IPv4 multicast address (e.g. `"239.0.0.1"`). Must be in 224.0.0.0/4. Absent or empty = unicast mode. |
|
||||||
| `StackSize` | uint32 | 1 048 576 | Background thread stack size in bytes |
|
| `Interface` | string | *(absent)* | Network interface for multicast binding (e.g. `"eth0"`). **Mandatory** when `MulticastGroup` is set. |
|
||||||
|
| `DataPort` | uint16 | Port+1 | UDP port for multicast DATA datagrams. Ignored in unicast mode. |
|
||||||
|
| `PublishingMode` | string | Strict | `Strict`: send every RT cycle. `Accumulate`: batch until size/time limit. `Decimate`: send every Nth cycle. |
|
||||||
|
| `MinRefreshRate` | float64| — | Flush frequency in Hz. **Required** when `PublishingMode` = `Accumulate`. |
|
||||||
|
| `Ratio` | uint32 | — | Send 1 packet every `Ratio` RT cycles. **Required** when `PublishingMode` = `Decimate`. |
|
||||||
|
| `CPUMask` | uint32 | 0xFFFFFFFF (any) | Background thread CPU affinity bitmask |
|
||||||
|
| `StackSize` | uint32 | MARTe2 default | Background thread stack size in bytes |
|
||||||
|
|
||||||
### Per-signal Parameters
|
### Per-signal Parameters
|
||||||
|
|
||||||
| Parameter | Type | Default | Applies to |
|
| Parameter | Type | Default | Applies to |
|
||||||
|-----------|------|---------|------------|
|
| --------------- | ------- | ------------ | -------------------------------------------------------- |
|
||||||
| `Unit` | string | `""` | Any type — informational, forwarded to client in CONFIG |
|
| `Unit` | string | `""` | Any type — informational, forwarded to client in CONFIG |
|
||||||
| `RangeMin` | float64 | 0.0 | float32/float64 with `QuantizedType` |
|
| `RangeMin` | float64 | 0.0 | float32/float64 with `QuantizedType` |
|
||||||
| `RangeMax` | float64 | 1.0 | float32/float64 with `QuantizedType` |
|
| `RangeMax` | float64 | 1.0 | float32/float64 with `QuantizedType` |
|
||||||
| `QuantizedType` | string | `none` | float32/float64 only |
|
| `QuantizedType` | string | `none` | float32/float64 only |
|
||||||
| `TimeMode` | string | `PacketTime` | Signals with `NumberOfElements > 1` |
|
| `TimeMode` | string | `PacketTime` | Signals with `NumberOfElements > 1` |
|
||||||
| `TimeSignal` | string | — | Required when `TimeMode` ≠ `PacketTime` |
|
| `TimeSignal` | string | — | Required when `TimeMode` ≠ `PacketTime` |
|
||||||
| `SamplingRate` | float64 | 0.0 | Required when `TimeMode` = `FirstSample` or `LastSample` |
|
| `SamplingRate` | float64 | 0.0 | Required when `TimeMode` = `FirstSample` or `LastSample` |
|
||||||
|
|
||||||
### Quantization Types
|
### Quantization Types
|
||||||
|
|
||||||
| Value | Wire type | Bit depth | Notes |
|
| Value | Wire type | Bit depth | Notes |
|
||||||
|-------|-----------|-----------|-------|
|
| -------- | -------------- | --------- | ------------------------------------------------- |
|
||||||
| `none` | same as source | — | Raw copy, no quantization |
|
| `none` | same as source | — | Raw copy, no quantization |
|
||||||
| `uint8` | uint8 | 8-bit | Maps `[RangeMin, RangeMax]` → `[0, 255]` |
|
| `uint8` | uint8 | 8-bit | Maps `[RangeMin, RangeMax]` → `[0, 255]` |
|
||||||
| `int8` | int8 | 8-bit | Maps `[RangeMin, RangeMax]` → `[-127, 127]` |
|
| `int8` | int8 | 8-bit | Maps `[RangeMin, RangeMax]` → `[-127, 127]` |
|
||||||
| `uint16` | uint16 | 16-bit | Maps `[RangeMin, RangeMax]` → `[0, 65 535]` |
|
| `uint16` | uint16 | 16-bit | Maps `[RangeMin, RangeMax]` → `[0, 65 535]` |
|
||||||
| `int16` | int16 | 16-bit | Maps `[RangeMin, RangeMax]` → `[-32 767, 32 767]` |
|
| `int16` | int16 | 16-bit | Maps `[RangeMin, RangeMax]` → `[-32 767, 32 767]` |
|
||||||
|
|
||||||
Quantization formula (unsigned, e.g. uint16):
|
Quantization formula (unsigned, e.g. uint16):
|
||||||
|
|
||||||
@@ -104,12 +126,68 @@ wire_value = (uint16)(normalized × 65535)
|
|||||||
|
|
||||||
### Time Modes
|
### Time Modes
|
||||||
|
|
||||||
| Value | Meaning | Requirements |
|
| Value | Meaning | Requirements |
|
||||||
|-------|---------|--------------|
|
| ------------- | ------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
|
||||||
| `PacketTime` | The HRT counter captured at `Synchronise()` time is used as the packet timestamp. No per-signal time metadata. | — |
|
| `PacketTime` | The HRT counter captured at `Synchronise()` time is used as the packet timestamp. No per-signal time metadata. | — |
|
||||||
| `FullArray` | `TimeSignal` carries one timestamp per element (same `NumberOfElements`). | `TimeSignal` must have the same `NumberOfElements`. |
|
| `FullArray` | `TimeSignal` carries one timestamp per element (same `NumberOfElements`). | `TimeSignal` must have the same `NumberOfElements`. |
|
||||||
| `FirstSample` | `TimeSignal` is a scalar giving the timestamp of element `[0]`. Elements `[1..N-1]` are inferred at `1/SamplingRate` intervals. | Scalar `TimeSignal`; `SamplingRate > 0`. |
|
| `FirstSample` | `TimeSignal` is a scalar giving the timestamp of element `[0]`. Elements `[1..N-1]` are inferred at `1/SamplingRate` intervals. | Scalar `TimeSignal`; `SamplingRate > 0`. |
|
||||||
| `LastSample` | Same as `FirstSample` but `TimeSignal` is the timestamp of element `[N-1]`. | Scalar `TimeSignal`; `SamplingRate > 0`. |
|
| `LastSample` | Same as `FirstSample` but `TimeSignal` is the timestamp of element `[N-1]`. | Scalar `TimeSignal`; `SamplingRate > 0`. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Network Modes
|
||||||
|
|
||||||
|
### Unicast (default)
|
||||||
|
|
||||||
|
The server opens a single UDP socket on `Port`. The client initiates the session by sending a
|
||||||
|
CONNECT packet to that port. The server replies with a CONFIG packet on the same socket and
|
||||||
|
subsequently sends DATA packets directly to the client's address. One client at a time; a new
|
||||||
|
CONNECT evicts the previous client.
|
||||||
|
|
||||||
|
### Multicast
|
||||||
|
|
||||||
|
Enabled by setting `MulticastGroup` to a valid IPv4 multicast address (224.0.0.0/4).
|
||||||
|
The `Interface` parameter is **mandatory** and specifies the network interface to bind.
|
||||||
|
|
||||||
|
The server opens a TCP listener on `Port` for control traffic and a UDP socket aimed at
|
||||||
|
`MulticastGroup:DataPort` for data traffic. The client:
|
||||||
|
|
||||||
|
1. Connects to `Port` via TCP and sends a CONNECT packet.
|
||||||
|
2. Receives the CONFIG packet over TCP.
|
||||||
|
3. Joins the multicast group (`MulticastGroup:DataPort`) to receive DATA packets.
|
||||||
|
|
||||||
|
Multiple clients may receive data simultaneously by joining the same group.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Publishing Modes
|
||||||
|
|
||||||
|
### Strict (default)
|
||||||
|
|
||||||
|
Sends one DATA packet for every `Synchronise()` call (every RT cycle). Simplest and lowest
|
||||||
|
latency.
|
||||||
|
|
||||||
|
### Accumulate
|
||||||
|
|
||||||
|
Batches multiple RT-cycle snapshots into a single DATA packet. All signals (scalars and arrays)
|
||||||
|
are accumulated: one full snapshot per RT cycle. The batch is flushed when either:
|
||||||
|
|
||||||
|
- **Size condition**: adding one more sample would exceed `MaxPayloadSize`.
|
||||||
|
- **Time condition**: `1/MinRefreshRate` seconds have elapsed since the last flush.
|
||||||
|
|
||||||
|
The maximum batch count is computed automatically from `MaxPayloadSize` and the total wire size
|
||||||
|
of all signals. Scalar signals with `Unit="us"` or `"ns"` are auto-promoted as the per-sample
|
||||||
|
FullArray time reference for all other scalars.
|
||||||
|
|
||||||
|
Requires `MinRefreshRate` (Hz) to be set.
|
||||||
|
|
||||||
|
### Decimate
|
||||||
|
|
||||||
|
Sends one DATA packet every `Ratio` RT cycles, dropping intermediate cycles. Only the most
|
||||||
|
recent snapshot at the Nth cycle is sent.
|
||||||
|
|
||||||
|
Requires `Ratio` (≥ 1) to be set. `Ratio = 1` is equivalent to `Strict` mode (a warning is
|
||||||
|
logged).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -151,7 +229,7 @@ PrepareNextState() ← opens UDP server socket, starts background threa
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Example: minimal scalar streaming
|
## Example: minimal scalar streaming (unicast)
|
||||||
|
|
||||||
```
|
```
|
||||||
+Data = {
|
+Data = {
|
||||||
@@ -168,6 +246,26 @@ PrepareNextState() ← opens UDP server socket, starts background threa
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Example: multicast with accumulation
|
||||||
|
|
||||||
|
```
|
||||||
|
+Streamer = {
|
||||||
|
Class = UDPStreamer
|
||||||
|
Port = 44500 // TCP control port
|
||||||
|
MulticastGroup = "239.0.0.1" // Enables multicast mode
|
||||||
|
Interface = "eth0" // Mandatory for multicast
|
||||||
|
DataPort = 44501 // UDP data port (default: Port+1)
|
||||||
|
MaxPayloadSize = 1400
|
||||||
|
PublishingMode = "Accumulate"
|
||||||
|
MinRefreshRate = 60.0 // Flush at least 60 times/s
|
||||||
|
|
||||||
|
Signals = {
|
||||||
|
Time = { Type = uint32; Unit = "us" }
|
||||||
|
Voltage = { Type = float32; Unit = "V"; RangeMin = -10.0; RangeMax = 10.0; QuantizedType = uint16 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Example: high-frequency burst
|
## Example: high-frequency burst
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -198,3 +296,19 @@ With `MaxPayloadSize = 1400`, a single 1000-element float32 signal produces:
|
|||||||
payload = 8 B (HRT timestamp) + 4 B (T0/uint32) + 4000 B (float32×1000) = 4012 B
|
payload = 8 B (HRT timestamp) + 4 B (T0/uint32) + 4000 B (float32×1000) = 4012 B
|
||||||
fragments = ceil(4012 / 1383) = 3
|
fragments = ceil(4012 / 1383) = 3
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Example: decimated output
|
||||||
|
|
||||||
|
```
|
||||||
|
+Streamer = {
|
||||||
|
Class = UDPStreamer
|
||||||
|
Port = 44500
|
||||||
|
PublishingMode = "Decimate"
|
||||||
|
Ratio = 10 // Send 1 packet every 10 RT cycles
|
||||||
|
|
||||||
|
Signals = {
|
||||||
|
Time = { Type = uint32; Unit = "us" }
|
||||||
|
Position = { Type = float64; Unit = "mm" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
@@ -9,15 +9,15 @@ for control applications built with [MARTe2](https://vcis.f4e.europa.eu/marte2-d
|
|||||||
|
|
||||||
This repository integrates two complementary capabilities:
|
This repository integrates two complementary capabilities:
|
||||||
|
|
||||||
| Capability | Component | Purpose |
|
| Capability | Component | Purpose |
|
||||||
|---|---|---|
|
| --------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------- |
|
||||||
| **Signal streaming** | `UDPStreamer` DataSource | Continuously stream selected signals to a browser-based oscilloscope over UDP |
|
| **Signal streaming** | `UDPStreamer` DataSource | Continuously stream selected signals to a browser-based oscilloscope over UDP |
|
||||||
| **Signal debugging** | `DebugService` Interface | On-demand signal tracing, value forcing, and conditional breakpoints — zero application code changes required |
|
| **Signal debugging** | `DebugService` Interface | On-demand signal tracing, value forcing, and conditional breakpoints — zero application code changes required |
|
||||||
| **Sine generation** | `SineArrayGAM` | Generate continuous sine-wave arrays for testing and simulation |
|
| **Sine generation** | `SineArrayGAM` | Generate continuous sine-wave arrays for testing and simulation |
|
||||||
| **Time stamping** | `TimeArrayGAM` | Provide time-reference arrays aligned to an RT cycle |
|
| **Time stamping** | `TimeArrayGAM` | Provide time-reference arrays aligned to an RT cycle |
|
||||||
| **Log forwarding** | `TCPLogger` Interface | Forward `REPORT_ERROR` log events to TCP clients in real time |
|
| **Log forwarding** | `TCPLogger` Interface | Forward `REPORT_ERROR` log events to TCP clients in real time |
|
||||||
| **Integrated client** | `Common/Client/go` | Go packages for UDPS protocol and WebSocket hub |
|
| **Integrated client** | `Common/Client/go` | Go packages for UDPS protocol and WebSocket hub |
|
||||||
| **Debug web client** | `Client/debugger` | Browser-based debug UI communicating with `DebugService` |
|
| **Debug web client** | `Client/debugger` | Browser-based debug UI communicating with `DebugService` |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -49,9 +49,9 @@ MARTe_Integrated_components/
|
|||||||
|
|
||||||
### UDPStreamer DataSource
|
### UDPStreamer DataSource
|
||||||
|
|
||||||
Streams MARTe2 signals over UDP using the UDPS binary protocol. Clients register by
|
Streams MARTe2 signals over UDP using the UDPS binary protocol. Clients register by
|
||||||
sending a `CONNECT` packet; the server then sends `CONFIG` (signal metadata) and continuous
|
sending a `CONNECT` packet; the server then sends `CONFIG` (signal metadata) and continuous
|
||||||
`DATA` packets. Features:
|
`DATA` packets. Features:
|
||||||
|
|
||||||
- Optional 16-bit quantization (configurable per signal: `QuantizedType`)
|
- Optional 16-bit quantization (configurable per signal: `QuantizedType`)
|
||||||
- Packed high-frequency bursts (`NumberOfElements > 1` with `SamplingRate`)
|
- Packed high-frequency bursts (`NumberOfElements > 1` with `SamplingRate`)
|
||||||
@@ -61,8 +61,8 @@ See `Docs/UDPStreamer.md` and `Docs/Protocol.md`.
|
|||||||
|
|
||||||
### SineArrayGAM
|
### SineArrayGAM
|
||||||
|
|
||||||
Generates a continuous float32 sine-wave array every RT cycle. Used as a signal
|
Generates a continuous float32 sine-wave array every RT cycle. Used as a signal
|
||||||
source for testing and demo applications. Configurable: `Frequency`, `Amplitude`,
|
source for testing and demo applications. Configurable: `Frequency`, `Amplitude`,
|
||||||
`Phase`, `SamplingRate`, `NumberOfElements`.
|
`Phase`, `SamplingRate`, `NumberOfElements`.
|
||||||
|
|
||||||
See `Docs/SineArrayGAM.md`.
|
See `Docs/SineArrayGAM.md`.
|
||||||
@@ -75,12 +75,13 @@ configured `SamplingRate`.
|
|||||||
|
|
||||||
### DebugService Interface
|
### DebugService Interface
|
||||||
|
|
||||||
Instruments a running MARTe2 application **without modifying its source code**. On
|
Instruments a running MARTe2 application **without modifying its source code**. On
|
||||||
`Initialise()` it patches the `ClassRegistryDatabase` to wrap all standard
|
`Initialise()` it patches the `ClassRegistryDatabase` to wrap all standard
|
||||||
`MemoryMap*Broker` types. When `RealTimeApplication::ConfigureApplication()` runs
|
`MemoryMap*Broker` types. When `RealTimeApplication::ConfigureApplication()` runs
|
||||||
afterward the application transparently uses the wrapped brokers.
|
afterward the application transparently uses the wrapped brokers.
|
||||||
|
|
||||||
Capabilities accessible over TCP (port 8080 by default):
|
Capabilities accessible over TCP (port 8080 by default):
|
||||||
|
|
||||||
- `DISCOVER` — enumerate all signals with type and alias metadata
|
- `DISCOVER` — enumerate all signals with type and alias metadata
|
||||||
- `TRACE` — enable/disable high-speed UDP telemetry per signal (with decimation)
|
- `TRACE` — enable/disable high-speed UDP telemetry per signal (with decimation)
|
||||||
- `FORCE` / `UNFORCE` — inject persistent values into signals on the RT path
|
- `FORCE` / `UNFORCE` — inject persistent values into signals on the RT path
|
||||||
@@ -98,7 +99,7 @@ See `Docs/DebugService.md`.
|
|||||||
### TCPLogger Interface
|
### TCPLogger Interface
|
||||||
|
|
||||||
A `LoggerConsumerI` that forwards every MARTe2 `REPORT_ERROR` call to up to 8 TCP
|
A `LoggerConsumerI` that forwards every MARTe2 `REPORT_ERROR` call to up to 8 TCP
|
||||||
clients on a configurable port. Works as a sidecar to `DebugService`.
|
clients on a configurable port. Works as a sidecar to `DebugService`.
|
||||||
|
|
||||||
### StreamHub Application
|
### StreamHub Application
|
||||||
|
|
||||||
@@ -116,7 +117,7 @@ See `Docs/StreamHub-UserGuide.md`, `Docs/StreamHub-API.md` and
|
|||||||
### UDPS Protocol
|
### UDPS Protocol
|
||||||
|
|
||||||
The `Common/UDP/UDPSProtocol.h` header defines the shared binary wire format used by
|
The `Common/UDP/UDPSProtocol.h` header defines the shared binary wire format used by
|
||||||
both `UDPStreamer` and `DebugService`. It is intentionally free of MARTe2-specific
|
both `UDPStreamer` and `DebugService`. It is intentionally free of MARTe2-specific
|
||||||
dependencies so it can also be used by Go clients (via `Common/Client/go/udpsprotocol`).
|
dependencies so it can also be used by Go clients (via `Common/Client/go/udpsprotocol`).
|
||||||
|
|
||||||
See `Docs/Protocol.md`.
|
See `Docs/Protocol.md`.
|
||||||
@@ -224,18 +225,18 @@ Open `http://localhost:9090`, explore the object tree, trace signals, force valu
|
|||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
| Document | Contents |
|
| Document | Contents |
|
||||||
|---|---|
|
| ----------------------------- | -------------------------------------------------------------- |
|
||||||
| `Docs/Protocol.md` | UDPS binary wire protocol specification |
|
| `Docs/Protocol.md` | UDPS binary wire protocol specification |
|
||||||
| `Docs/UDPStreamer.md` | UDPStreamer DataSource configuration reference |
|
| `Docs/UDPStreamer.md` | UDPStreamer DataSource configuration reference |
|
||||||
| `Docs/SineArrayGAM.md` | SineArrayGAM configuration reference |
|
| `Docs/SineArrayGAM.md` | SineArrayGAM configuration reference |
|
||||||
| `Docs/DebugService.md` | DebugService TCP API and architecture |
|
| `Docs/DebugService.md` | DebugService TCP API and architecture |
|
||||||
| `Docs/Tutorial.md` | Step-by-step tutorial covering both components |
|
| `Docs/Tutorial.md` | Step-by-step tutorial covering both components |
|
||||||
| `Docs/WebUI.md` | Web client user guide |
|
| `Docs/WebUI.md` | Web client user guide |
|
||||||
| `Docs/StreamHub-UserGuide.md` | StreamHub oscilloscope user guide (web + ImGui clients) |
|
| `Docs/StreamHub-UserGuide.md` | StreamHub oscilloscope user guide (web + ImGui clients) |
|
||||||
| `Docs/StreamHub-API.md` | StreamHub WebSocket protocol (commands, events, binary frames) |
|
| `Docs/StreamHub-API.md` | StreamHub WebSocket protocol (commands, events, binary frames) |
|
||||||
| `Docs/StreamHub-Developer.md` | StreamHub internals, threading, time base, build & E2E tests |
|
| `Docs/StreamHub-Developer.md` | StreamHub internals, threading, time base, build & E2E tests |
|
||||||
| `ARCHITECTURE.md` | System architecture overview |
|
| `ARCHITECTURE.md` | System architecture overview |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -140,16 +140,17 @@ struct UDPStreamerSignalInfo {
|
|||||||
* fragmented into multiple datagrams if payload exceeds MaxPayloadSize).
|
* fragmented into multiple datagrams if payload exceeds MaxPayloadSize).
|
||||||
*
|
*
|
||||||
* @par Top-level configuration parameters
|
* @par Top-level configuration parameters
|
||||||
* | Parameter | Type | Default | Description |
|
* | Parameter | Type | Default | Description |
|
||||||
* |-----------------|---------|---------|-------------|
|
* |-----------------|---------|------------------|-------------|
|
||||||
* | Port | uint16 | 44500 | TCP control port (multicast) or UDP server port (unicast). Values ≤ 1024 produce a warning. |
|
* | Port | uint16 | 44500 | TCP control port (multicast) or UDP server port (unicast). Values ≤ 1024 produce a warning. |
|
||||||
* | MulticastGroup | string | *(absent)* | **Enables multicast mode.** IPv4 multicast address, e.g. `"239.0.0.1"`. Must be in 224.0.0.0/4. Absent or empty = unicast. |
|
* | MulticastGroup | string | *(absent)* | **Enables multicast mode.** IPv4 multicast address, e.g. `"239.0.0.1"`. Must be in 224.0.0.0/4. Absent or empty = unicast. |
|
||||||
* | DataPort | uint16 | Port+1 | UDP port for multicast DATA datagrams. Ignored in unicast mode. Must be non-zero and differ from Port. |
|
* | Interface | string | *(absent)* | Multicast binded interface **ONLY FOR MULTICAST** |
|
||||||
* | MaxPayloadSize | uint32 | 1400 | Maximum bytes of signal payload per UDP datagram (excluding the 17-byte header). Larger signals are fragmented. |
|
* | DataPort | uint16 | Port+1 | UDP port for multicast DATA datagrams. Ignored in unicast mode. Must be non-zero and differ from Port. |
|
||||||
* | PublishingMode | string | Strict | `Strict`: send one packet every Synchronise() call. `Auto`: rate-limited; flush only when MinRefreshRate interval has elapsed. |
|
* | MaxPayloadSize | uint32 | 1400 | Maximum bytes of signal payload per UDP datagram (excluding the 17-byte header). Larger signals are fragmented. |
|
||||||
* | MinRefreshRate | float64 | — | Required when PublishingMode = Auto. Flush frequency in Hz (e.g. 120.0). |
|
* | PublishingMode | string | Strict | `Strict`: send one packet every Synchronise() call. `Auto`: rate-limited; flush only when MinRefreshRate interval has elapsed. |
|
||||||
* | MaxBatchSize | uint32 | 1 | Optional when PublishingMode = Auto. Number of RT cycles to accumulate before flushing one packet. Scalar signals are expanded to arrays of MaxBatchSize elements; the first scalar with Unit="us" or "ns" is auto-promoted as the per-sample FullArray timestamp reference for all other scalars. When omitted or 1, the most-recent single value is sent at MinRefreshRate. |
|
* | MinRefreshRate | float64 | — | Required when PublishingMode = Auto. Flush frequency in Hz (e.g. 120.0). |
|
||||||
* | CPUMask | uint32 | 0xFFFFFFFF | CPU affinity bitmask for the background thread. |
|
* | MaxBatchSize | uint32 | 1 | Optional when PublishingMode = Auto. Number of RT cycles to accumulate before flushing one packet. Scalar signals are expanded to arrays of MaxBatchSize elements; the first scalar with Unit="us" or "ns" is auto-promoted as the per-sample FullArray timestamp reference for all other scalars. When omitted or 1, the most-recent single value is sent at MinRefreshRate. |
|
||||||
|
* | CPUMask | uint32 | 0xFFFFFFFF | CPU affinity bitmask for the background thread. |
|
||||||
* | StackSize | uint32 | (MARTe2 default) | Stack size in bytes for the background thread. |
|
* | StackSize | uint32 | (MARTe2 default) | Stack size in bytes for the background thread. |
|
||||||
*
|
*
|
||||||
* @par Per-signal configuration parameters
|
* @par Per-signal configuration parameters
|
||||||
|
|||||||
@@ -1,48 +1,48 @@
|
|||||||
../../../..//Build/x86-linux/Components/DataSources/UDPStreamer/UDPStreamer.o: UDPStreamer.cpp \
|
../../../..//Build/x86-linux/Components/DataSources/UDPStreamer/UDPStreamer.o: UDPStreamer.cpp \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/AdvancedErrorManagement.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ErrorType.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassProperties.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Architecture/x86_gcc/CompilerTypes.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Architecture/x86_gcc/CompilerTypes.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/GeneralDefinitions.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TemplateParametersVerificator.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TemplateParametersVerificator.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamString.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/GeneralDefinitions.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapManager.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorInformation.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorInformation.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ErrorType.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/HighResolutionTimerA.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/HighResolutionTimerA.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimer.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimer.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HighResolutionTimer.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HighResolutionTimer.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimerCalibrator.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimerCalibrator.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../GeneralDefinitions.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../GeneralDefinitions.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamMemoryReference.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/CharBuffer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/BufferedStreamI.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/BufferedStreamI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassProperties.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassProperties.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryDatabase.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryDatabase.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectsDatabase.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectsDatabase.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectI.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/StandardHeap.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/StandardHeap.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HeapI.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HeapI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../ErrorManagement.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../GeneralDefinitions.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../Generic/StandardHeap_Generic.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../Generic/StandardHeap_Generic.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FastPollingMutexSem.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FastPollingMutexSem.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Atomic.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Atomic.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/AtomicA.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/AtomicA.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItem.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItem.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CString.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CString.h \
|
||||||
@@ -53,7 +53,6 @@
|
|||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BasicType.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BasicType.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolderT.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolderT.h \
|
||||||
@@ -70,17 +69,18 @@
|
|||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticListHolder.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticListHolder.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Matrix.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Matrix.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapManager.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/MemoryOperationsHelper.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/MemoryOperationsHelper.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FormatDescriptor.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FormatDescriptor.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/IOBuffer.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/IOBuffer.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/CharBuffer.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StringHelper.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamStringIOBuffer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/AdvancedErrorManagement.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassProperties.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamMemoryReference.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/ConfigurationDatabase.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/ConfigurationDatabase.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/AnyObject.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/AnyObject.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StringHelper.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/CLASSREGISTER.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/CLASSREGISTER.h \
|
||||||
@@ -104,8 +104,6 @@
|
|||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/TypeConversion.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/TypeConversion.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamString.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamStringIOBuffer.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThreadI.h \
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThreadI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/ExecutionInfo.h \
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/ExecutionInfo.h \
|
||||||
@@ -116,18 +114,12 @@
|
|||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitSet.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitSet.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderT.h \
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderT.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/MemoryMapSynchronisedOutputBroker.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/MemoryMapOutputBroker.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/MemoryMapBroker.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/BrokerI.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/DataSourceI.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/StatefulI.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/ExecutableI.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
|
|
||||||
UDPStreamer.h \
|
UDPStreamer.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L1Portability/EventSem.h \
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L1Portability/EventSem.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/MemoryDataSourceI.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/MemoryDataSourceI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/DataSourceI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/StatefulI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/SingleThreadService.h \
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/SingleThreadService.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceI.h \
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThreadI.h \
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThreadI.h \
|
||||||
@@ -141,5 +133,6 @@
|
|||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HandleI.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HandleI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/Environment/Linux/SocketCore.h \
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/Environment/Linux/SocketCore.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/BasicUDPSocket.h \
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/BasicUDPSocket.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/InternetHost.h \
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/InternetHost.h \
|
||||||
../../../..//Common/UDP/UDPSProtocol.h
|
../../../..//Common/UDP/UDPSProtocol.h
|
||||||
|
|||||||
@@ -1,48 +1,48 @@
|
|||||||
UDPStreamer.o: UDPStreamer.cpp \
|
UDPStreamer.o: UDPStreamer.cpp \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/AdvancedErrorManagement.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ErrorType.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassProperties.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Architecture/x86_gcc/CompilerTypes.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Architecture/x86_gcc/CompilerTypes.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/GeneralDefinitions.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TemplateParametersVerificator.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TemplateParametersVerificator.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamString.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/GeneralDefinitions.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapManager.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorInformation.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorInformation.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ErrorType.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/HighResolutionTimerA.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/HighResolutionTimerA.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimer.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimer.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HighResolutionTimer.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HighResolutionTimer.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimerCalibrator.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimerCalibrator.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../GeneralDefinitions.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../GeneralDefinitions.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamMemoryReference.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/CharBuffer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/BufferedStreamI.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/BufferedStreamI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassProperties.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassProperties.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryDatabase.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryDatabase.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectsDatabase.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectsDatabase.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectI.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/StandardHeap.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/StandardHeap.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HeapI.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HeapI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../ErrorManagement.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../GeneralDefinitions.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../Generic/StandardHeap_Generic.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../Generic/StandardHeap_Generic.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FastPollingMutexSem.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FastPollingMutexSem.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Atomic.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Atomic.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/AtomicA.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/AtomicA.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItem.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItem.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CString.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CString.h \
|
||||||
@@ -53,7 +53,6 @@ UDPStreamer.o: UDPStreamer.cpp \
|
|||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BasicType.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BasicType.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolderT.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolderT.h \
|
||||||
@@ -70,17 +69,18 @@ UDPStreamer.o: UDPStreamer.cpp \
|
|||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticListHolder.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticListHolder.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Matrix.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Matrix.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapManager.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/MemoryOperationsHelper.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/MemoryOperationsHelper.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FormatDescriptor.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FormatDescriptor.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/IOBuffer.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/IOBuffer.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/CharBuffer.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StringHelper.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamStringIOBuffer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/AdvancedErrorManagement.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassProperties.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamMemoryReference.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/ConfigurationDatabase.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/ConfigurationDatabase.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/AnyObject.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/AnyObject.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StringHelper.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/CLASSREGISTER.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/CLASSREGISTER.h \
|
||||||
@@ -104,8 +104,6 @@ UDPStreamer.o: UDPStreamer.cpp \
|
|||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/TypeConversion.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/TypeConversion.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamString.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamStringIOBuffer.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThreadI.h \
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThreadI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/ExecutionInfo.h \
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/ExecutionInfo.h \
|
||||||
@@ -116,18 +114,12 @@ UDPStreamer.o: UDPStreamer.cpp \
|
|||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitSet.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitSet.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderT.h \
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderT.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/MemoryMapSynchronisedOutputBroker.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/MemoryMapOutputBroker.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/MemoryMapBroker.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/BrokerI.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/DataSourceI.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/StatefulI.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/ExecutableI.h \
|
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
|
|
||||||
UDPStreamer.h \
|
UDPStreamer.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L1Portability/EventSem.h \
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L1Portability/EventSem.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/MemoryDataSourceI.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/MemoryDataSourceI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/DataSourceI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L5GAMs/StatefulI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/SingleThreadService.h \
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/SingleThreadService.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceI.h \
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThreadI.h \
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThreadI.h \
|
||||||
@@ -141,5 +133,6 @@ UDPStreamer.o: UDPStreamer.cpp \
|
|||||||
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HandleI.h \
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HandleI.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/Environment/Linux/SocketCore.h \
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/Environment/Linux/SocketCore.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/BasicUDPSocket.h \
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/BasicUDPSocket.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
|
||||||
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/InternetHost.h \
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/InternetHost.h \
|
||||||
../../../..//Common/UDP/UDPSProtocol.h
|
../../../..//Common/UDP/UDPSProtocol.h
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ static const uint16 UDPS_CLIENT_DEFAULT_DP_OFFSET = 1u;
|
|||||||
/** Default max payload per UDP datagram (bytes). */
|
/** Default max payload per UDP datagram (bytes). */
|
||||||
static const uint32 UDPS_CLIENT_DEFAULT_MAX_PAYLOAD = 1400u;
|
static const uint32 UDPS_CLIENT_DEFAULT_MAX_PAYLOAD = 1400u;
|
||||||
|
|
||||||
|
/** Default unicast keepalive interval (seconds); 0 disables. */
|
||||||
|
static const uint32 UDPS_CLIENT_DEFAULT_KEEPALIVE_INTERVAL_S = 15u;
|
||||||
|
|
||||||
/** Bytes prepended to each DATA payload for the HRT packet timestamp. */
|
/** Bytes prepended to each DATA payload for the HRT packet timestamp. */
|
||||||
static const uint32 UDPS_CLIENT_TIMESTAMP_BYTES = 8u;
|
static const uint32 UDPS_CLIENT_TIMESTAMP_BYTES = 8u;
|
||||||
|
|
||||||
@@ -129,6 +132,7 @@ UDPStreamerClient::UDPStreamerClient() :
|
|||||||
serverAddress = UDPS_CLIENT_DEFAULT_ADDR;
|
serverAddress = UDPS_CLIENT_DEFAULT_ADDR;
|
||||||
port = UDPS_CLIENT_DEFAULT_PORT;
|
port = UDPS_CLIENT_DEFAULT_PORT;
|
||||||
maxPayloadSize = UDPS_CLIENT_DEFAULT_MAX_PAYLOAD;
|
maxPayloadSize = UDPS_CLIENT_DEFAULT_MAX_PAYLOAD;
|
||||||
|
keepAliveInterval = UDPS_CLIENT_DEFAULT_KEEPALIVE_INTERVAL_S;
|
||||||
cpuMask = 0xFFFFFFFFu;
|
cpuMask = 0xFFFFFFFFu;
|
||||||
stackSize = THREADS_DEFAULT_STACKSIZE;
|
stackSize = THREADS_DEFAULT_STACKSIZE;
|
||||||
dataPort = UDPS_CLIENT_DEFAULT_PORT + UDPS_CLIENT_DEFAULT_DP_OFFSET;
|
dataPort = UDPS_CLIENT_DEFAULT_PORT + UDPS_CLIENT_DEFAULT_DP_OFFSET;
|
||||||
@@ -201,6 +205,12 @@ bool UDPStreamerClient::Initialise(StructuredDataI &data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
|
if (!data.Read("KeepAliveInterval", keepAliveInterval)) {
|
||||||
|
keepAliveInterval = UDPS_CLIENT_DEFAULT_KEEPALIVE_INTERVAL_S;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
if (!data.Read("CPUMask", cpuMask)) {
|
if (!data.Read("CPUMask", cpuMask)) {
|
||||||
cpuMask = 0xFFFFFFFFu;
|
cpuMask = 0xFFFFFFFFu;
|
||||||
@@ -245,6 +255,7 @@ bool UDPStreamerClient::Initialise(StructuredDataI &data) {
|
|||||||
if (ok) { ok = cdb.Write("DataPort", static_cast<uint32>(dataPort)); }
|
if (ok) { ok = cdb.Write("DataPort", static_cast<uint32>(dataPort)); }
|
||||||
}
|
}
|
||||||
if (ok) { ok = cdb.Write("MaxPayloadSize", maxPayloadSize); }
|
if (ok) { ok = cdb.Write("MaxPayloadSize", maxPayloadSize); }
|
||||||
|
if (ok) { ok = cdb.Write("KeepAliveInterval", keepAliveInterval); }
|
||||||
if (ok) { ok = cdb.Write("CPUMask", cpuMask); }
|
if (ok) { ok = cdb.Write("CPUMask", cpuMask); }
|
||||||
if (ok) { ok = cdb.Write("StackSize", stackSize); }
|
if (ok) { ok = cdb.Write("StackSize", stackSize); }
|
||||||
if (ok) { ok = cdb.MoveToRoot(); }
|
if (ok) { ok = cdb.MoveToRoot(); }
|
||||||
|
|||||||
@@ -174,11 +174,12 @@ private:
|
|||||||
StreamString serverAddress; /**< Server IP address. */
|
StreamString serverAddress; /**< Server IP address. */
|
||||||
uint16 port; /**< Server port. */
|
uint16 port; /**< Server port. */
|
||||||
uint32 maxPayloadSize; /**< Max payload bytes per datagram. */
|
uint32 maxPayloadSize; /**< Max payload bytes per datagram. */
|
||||||
|
uint32 keepAliveInterval; /**< Seconds between unicast keepalive ACKs (0 disables). */
|
||||||
uint32 cpuMask; /**< Background thread CPU affinity. */
|
uint32 cpuMask; /**< Background thread CPU affinity. */
|
||||||
uint32 stackSize; /**< Background thread stack size. */
|
uint32 stackSize; /**< Background thread stack size. */
|
||||||
StreamString multicastGroup; /**< Multicast group IP; empty = unicast. */
|
StreamString multicastGroup; /**< Multicast group IP; empty = unicast. */
|
||||||
uint16 dataPort; /**< UDP port for DATA datagrams (multicast). */
|
uint16 dataPort; /**< UDP port for DATA datagrams (multicast). */
|
||||||
bool useMulticast; /**< True when MulticastGroup is set. */
|
bool useMulticast; /**< True when MulticastGroup is set. */
|
||||||
|
|
||||||
/* Signal metadata */
|
/* Signal metadata */
|
||||||
uint32 numSigs; /**< Number of signals. */
|
uint32 numSigs; /**< Number of signals. */
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ UDPSClient::UDPSClient()
|
|||||||
useMulticast(false),
|
useMulticast(false),
|
||||||
silenceTimeoutTicks(0u),
|
silenceTimeoutTicks(0u),
|
||||||
reconnectDelayTicks(0u),
|
reconnectDelayTicks(0u),
|
||||||
|
keepAliveIntervalTicks(0u),
|
||||||
maxPayloadSize(UDPS_CLIENT_DEFAULT_MAX_PAYLOAD),
|
maxPayloadSize(UDPS_CLIENT_DEFAULT_MAX_PAYLOAD),
|
||||||
cpuMask(0xFFFFFFFFu),
|
cpuMask(0xFFFFFFFFu),
|
||||||
stackSize(65536u),
|
stackSize(65536u),
|
||||||
@@ -33,6 +34,7 @@ UDPSClient::UDPSClient()
|
|||||||
connected(false),
|
connected(false),
|
||||||
lastDataTicks(0u),
|
lastDataTicks(0u),
|
||||||
disconnectTick(0u),
|
disconnectTick(0u),
|
||||||
|
lastKeepAliveTicks(0u),
|
||||||
localPort(0u),
|
localPort(0u),
|
||||||
lastGcTicks(0u) {
|
lastGcTicks(0u) {
|
||||||
|
|
||||||
@@ -93,6 +95,10 @@ bool UDPSClient::Initialise(StructuredDataI &data) {
|
|||||||
(void) data.Read("ReconnectDelay", reconnectS);
|
(void) data.Read("ReconnectDelay", reconnectS);
|
||||||
reconnectDelayTicks = static_cast<uint64>(reconnectS) * HighResolutionTimer::Frequency();
|
reconnectDelayTicks = static_cast<uint64>(reconnectS) * HighResolutionTimer::Frequency();
|
||||||
|
|
||||||
|
uint32 keepAliveS = UDPS_CLIENT_DEFAULT_KEEPALIVE_INTERVAL_S;
|
||||||
|
(void) data.Read("KeepAliveInterval", keepAliveS);
|
||||||
|
keepAliveIntervalTicks = static_cast<uint64>(keepAliveS) * HighResolutionTimer::Frequency();
|
||||||
|
|
||||||
uint32 mps = UDPS_CLIENT_DEFAULT_MAX_PAYLOAD;
|
uint32 mps = UDPS_CLIENT_DEFAULT_MAX_PAYLOAD;
|
||||||
(void) data.Read("MaxPayloadSize", mps);
|
(void) data.Read("MaxPayloadSize", mps);
|
||||||
maxPayloadSize = mps;
|
maxPayloadSize = mps;
|
||||||
@@ -185,6 +191,18 @@ ErrorManagement::ErrorType UDPSClient::Execute(ExecutionInfo &info) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unicast keepalive: UDPSServer evicts silent unicast clients after its
|
||||||
|
// ClientTimeout (default 30 s). Re-sending CONNECT would also re-trigger
|
||||||
|
// a CONFIG resend; an ACK refreshes the server's last-seen with no side
|
||||||
|
// effects, so it is the keepalive packet of choice. Multicast clients
|
||||||
|
// hold a persistent TCP control connection and need no keepalive.
|
||||||
|
if (!useMulticast && (keepAliveIntervalTicks > 0u)) {
|
||||||
|
if ((now - lastKeepAliveTicks) >= keepAliveIntervalTicks) {
|
||||||
|
SendKeepAlive();
|
||||||
|
lastKeepAliveTicks = now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Periodic GC of stale reassembly slots (~every 1 s)
|
// Periodic GC of stale reassembly slots (~every 1 s)
|
||||||
uint64 gcFreq = HighResolutionTimer::Frequency();
|
uint64 gcFreq = HighResolutionTimer::Frequency();
|
||||||
if ((now - lastGcTicks) >= gcFreq) {
|
if ((now - lastGcTicks) >= gcFreq) {
|
||||||
@@ -204,6 +222,7 @@ bool UDPSClient::Connect() {
|
|||||||
if (ok) {
|
if (ok) {
|
||||||
connected = true;
|
connected = true;
|
||||||
lastDataTicks = HighResolutionTimer::Counter();
|
lastDataTicks = HighResolutionTimer::Counter();
|
||||||
|
lastKeepAliveTicks = lastDataTicks;
|
||||||
if (listener != NULL_PTR(UDPSClientListener *)) {
|
if (listener != NULL_PTR(UDPSClientListener *)) {
|
||||||
listener->OnUDPSConnected();
|
listener->OnUDPSConnected();
|
||||||
}
|
}
|
||||||
@@ -378,6 +397,25 @@ void UDPSClient::Disconnect() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Private: SendKeepAlive
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void UDPSClient::SendKeepAlive() {
|
||||||
|
if (useMulticast || !recvSocket.IsValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint8 ackPkt[UDPS_HEADER_SIZE];
|
||||||
|
UDPSBuildHeader(ackPkt, UDPS_TYPE_ACK, 0u, 0u, 1u, 0u);
|
||||||
|
InternetHost serverDest(serverPort, serverAddr.Buffer());
|
||||||
|
(void) recvSocket.SetDestination(serverDest);
|
||||||
|
uint32 sendSize = UDPS_HEADER_SIZE;
|
||||||
|
if (!recvSocket.Write(reinterpret_cast<const char8 *>(ackPkt), sendSize)) {
|
||||||
|
/* Non-fatal: if the server is truly gone, the silence timeout
|
||||||
|
* triggers the usual disconnect + reconnect. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Private: ReceiveAndProcess
|
// Private: ReceiveAndProcess
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -92,6 +92,11 @@ public:
|
|||||||
/** Default delay between reconnect attempts (seconds). */
|
/** Default delay between reconnect attempts (seconds). */
|
||||||
static const uint32 UDPS_CLIENT_DEFAULT_RECONNECT_DELAY_S = 2u;
|
static const uint32 UDPS_CLIENT_DEFAULT_RECONNECT_DELAY_S = 2u;
|
||||||
|
|
||||||
|
/** Default unicast keepalive interval (seconds). UDPSServer evicts silent
|
||||||
|
* unicast clients after its ClientTimeout (default 30 s); the client
|
||||||
|
* re-sends an ACK on this interval to stay registered. 0 disables. */
|
||||||
|
static const uint32 UDPS_CLIENT_DEFAULT_KEEPALIVE_INTERVAL_S = 15u;
|
||||||
|
|
||||||
/** Default maximum payload size (bytes, excluding 17-byte header). */
|
/** Default maximum payload size (bytes, excluding 17-byte header). */
|
||||||
static const uint32 UDPS_CLIENT_DEFAULT_MAX_PAYLOAD = 1400u;
|
static const uint32 UDPS_CLIENT_DEFAULT_MAX_PAYLOAD = 1400u;
|
||||||
|
|
||||||
@@ -111,9 +116,11 @@ public:
|
|||||||
* - ServerAddr (char*) Server IPv4 address. Required.
|
* - ServerAddr (char*) Server IPv4 address. Required.
|
||||||
* - Port (uint16) Server UDP port (unicast) or TCP listen port (multicast). Required.
|
* - Port (uint16) Server UDP port (unicast) or TCP listen port (multicast). Required.
|
||||||
* - MulticastGroup (char*) IPv4 multicast address; presence enables multicast mode.
|
* - MulticastGroup (char*) IPv4 multicast address; presence enables multicast mode.
|
||||||
|
* - Interface (char*) Network interface for multicast join (e.g. "lo"). Required when MulticastGroup is set.
|
||||||
* - DataPort (uint16) UDP multicast data port (defaults to Port+1).
|
* - DataPort (uint16) UDP multicast data port (defaults to Port+1).
|
||||||
* - SilenceTimeout (uint32) Seconds of no data before reconnect. Default 5.
|
* - SilenceTimeout (uint32) Seconds of no data before reconnect. Default 5.
|
||||||
* - ReconnectDelay (uint32) Seconds to wait between reconnect attempts. Default 2.
|
* - ReconnectDelay (uint32) Seconds to wait between reconnect attempts. Default 2.
|
||||||
|
* - KeepAliveInterval (uint32) Seconds between unicast keepalive ACKs. Default 15. 0 disables.
|
||||||
* - MaxPayloadSize (uint32) Max payload bytes per datagram, excluding header. Default 1400.
|
* - MaxPayloadSize (uint32) Max payload bytes per datagram, excluding header. Default 1400.
|
||||||
* - CPUMask (uint32) CPU affinity mask for the receive thread. Default 0xFFFFFFFF.
|
* - CPUMask (uint32) CPU affinity mask for the receive thread. Default 0xFFFFFFFF.
|
||||||
* - StackSize (uint32) Stack size for the receive thread. Default 65536.
|
* - StackSize (uint32) Stack size for the receive thread. Default 65536.
|
||||||
@@ -167,6 +174,8 @@ private:
|
|||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
bool Connect();
|
bool Connect();
|
||||||
void Disconnect();
|
void Disconnect();
|
||||||
|
/** Send a keepalive ACK to the server (unicast only, same socket). */
|
||||||
|
void SendKeepAlive();
|
||||||
bool ReceiveAndProcess();
|
bool ReceiveAndProcess();
|
||||||
|
|
||||||
bool ConnectUnicast();
|
bool ConnectUnicast();
|
||||||
@@ -195,6 +204,7 @@ private:
|
|||||||
bool useMulticast;
|
bool useMulticast;
|
||||||
uint64 silenceTimeoutTicks;
|
uint64 silenceTimeoutTicks;
|
||||||
uint64 reconnectDelayTicks;
|
uint64 reconnectDelayTicks;
|
||||||
|
uint64 keepAliveIntervalTicks; ///< 0 = keepalive disabled
|
||||||
uint32 maxPayloadSize;
|
uint32 maxPayloadSize;
|
||||||
uint32 cpuMask;
|
uint32 cpuMask;
|
||||||
uint32 stackSize;
|
uint32 stackSize;
|
||||||
@@ -208,6 +218,7 @@ private:
|
|||||||
bool connected;
|
bool connected;
|
||||||
uint64 lastDataTicks; ///< Ticks at last received DATA/CONFIG
|
uint64 lastDataTicks; ///< Ticks at last received DATA/CONFIG
|
||||||
uint64 disconnectTick; ///< Ticks when we disconnected (for delay)
|
uint64 disconnectTick; ///< Ticks when we disconnected (for delay)
|
||||||
|
uint64 lastKeepAliveTicks; ///< Ticks at last keepalive ACK sent
|
||||||
|
|
||||||
// Unicast
|
// Unicast
|
||||||
BasicUDPSocket recvSocket; ///< Bound to ephemeral port; receives DATA
|
BasicUDPSocket recvSocket; ///< Bound to ephemeral port; receives DATA
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -235,6 +235,7 @@ private:
|
|||||||
uint16 port;
|
uint16 port;
|
||||||
uint32 maxPayloadSize;
|
uint32 maxPayloadSize;
|
||||||
StreamString multicastGroup;
|
StreamString multicastGroup;
|
||||||
|
StreamString interface;
|
||||||
uint16 dataPort;
|
uint16 dataPort;
|
||||||
bool useMulticast;
|
bool useMulticast;
|
||||||
uint64 clientTimeoutTicks; ///< 0 = disabled
|
uint64 clientTimeoutTicks; ///< 0 = disabled
|
||||||
|
|||||||
@@ -424,6 +424,7 @@ $TestApp = {
|
|||||||
Port = 44500
|
Port = 44500
|
||||||
MulticastGroup = "239.0.0.1"
|
MulticastGroup = "239.0.0.1"
|
||||||
DataPort = 44503
|
DataPort = 44503
|
||||||
|
Interface = "127.0.0.1"
|
||||||
MaxPayloadSize = 1400
|
MaxPayloadSize = 1400
|
||||||
PublishingMode = "Accumulate"
|
PublishingMode = "Accumulate"
|
||||||
MinRefreshRate = 100
|
MinRefreshRate = 100
|
||||||
|
|||||||
@@ -279,6 +279,7 @@ $App = {
|
|||||||
Port = 44500
|
Port = 44500
|
||||||
MulticastGroup = "239.0.0.1"
|
MulticastGroup = "239.0.0.1"
|
||||||
DataPort = 44503
|
DataPort = 44503
|
||||||
|
Interface = "127.0.0.1"
|
||||||
MaxPayloadSize = 1400
|
MaxPayloadSize = 1400
|
||||||
PublishingMode = "Accumulate"
|
PublishingMode = "Accumulate"
|
||||||
MinRefreshRate = 100
|
MinRefreshRate = 100
|
||||||
|
|||||||
@@ -411,6 +411,7 @@ $App = {
|
|||||||
Port = 44500
|
Port = 44500
|
||||||
MulticastGroup = "239.0.0.1"
|
MulticastGroup = "239.0.0.1"
|
||||||
DataPort = 44503
|
DataPort = 44503
|
||||||
|
Interface = "127.0.0.1"
|
||||||
MaxPayloadSize = 1400
|
MaxPayloadSize = 1400
|
||||||
PublishingMode = "Accumulate"
|
PublishingMode = "Accumulate"
|
||||||
MinRefreshRate = 100
|
MinRefreshRate = 100
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ $E2EMulticastTest = {
|
|||||||
Port = 44600
|
Port = 44600
|
||||||
MulticastGroup = "239.0.0.1"
|
MulticastGroup = "239.0.0.1"
|
||||||
DataPort = 44610
|
DataPort = 44610
|
||||||
|
Interface = "127.0.0.1"
|
||||||
MaxPayloadSize = 65507
|
MaxPayloadSize = 65507
|
||||||
PublishingMode = "Strict"
|
PublishingMode = "Strict"
|
||||||
Signals = {
|
Signals = {
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -17,6 +17,8 @@ expected, not an error.
|
|||||||
"""
|
"""
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||||
@@ -25,6 +27,41 @@ import scenarios as S # noqa: E402
|
|||||||
PRODUCER_HZ = 1000 # LinuxTimer frequency (Hz)
|
PRODUCER_HZ = 1000 # LinuxTimer frequency (Hz)
|
||||||
|
|
||||||
|
|
||||||
|
def _iface_to_ip(name):
|
||||||
|
"""Resolve a network interface name (e.g. ``"wlan0"``) to its first IPv4
|
||||||
|
address via ``ip -4 addr show <name>``. Returns ``"127.0.0.1"`` on failure."""
|
||||||
|
try:
|
||||||
|
out = subprocess.check_output(
|
||||||
|
["ip", "-4", "addr", "show", name],
|
||||||
|
stderr=subprocess.DEVNULL, text=True)
|
||||||
|
m = re.search(r"inet\s+(\d+\.\d+\.\d+\.\d+)", out)
|
||||||
|
if m:
|
||||||
|
return m.group(1)
|
||||||
|
except (subprocess.CalledProcessError, FileNotFoundError, OSError):
|
||||||
|
pass
|
||||||
|
return "127.0.0.1"
|
||||||
|
|
||||||
|
|
||||||
|
def _mcast_interface_ip(group):
|
||||||
|
"""Return the IPv4 address of the OS-selected interface for a multicast
|
||||||
|
group. MARTe2's ``BasicUDPSocket::Join`` expects an IP address (passed to
|
||||||
|
``inet_addr``), not an interface name.
|
||||||
|
|
||||||
|
Uses ``ip route get <group>`` to find the outgoing device, then resolves
|
||||||
|
its IP. Falls back to ``"127.0.0.1"`` if the route or device lookup fails.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
out = subprocess.check_output(
|
||||||
|
["ip", "route", "get", group],
|
||||||
|
stderr=subprocess.DEVNULL, text=True)
|
||||||
|
m = re.search(r"dev\s+(\S+)", out)
|
||||||
|
if m:
|
||||||
|
return _iface_to_ip(m.group(1))
|
||||||
|
except (subprocess.CalledProcessError, FileNotFoundError, OSError):
|
||||||
|
pass
|
||||||
|
return "127.0.0.1"
|
||||||
|
|
||||||
|
|
||||||
def _ndims(elements):
|
def _ndims(elements):
|
||||||
return 0 if elements == 1 else 1
|
return 0 if elements == 1 else 1
|
||||||
|
|
||||||
@@ -78,6 +115,8 @@ def _streamer_block(src, scenario):
|
|||||||
if scenario["network"] == "multicast":
|
if scenario["network"] == "multicast":
|
||||||
parts.append(f'MulticastGroup = "{src["multicast_group"]}"')
|
parts.append(f'MulticastGroup = "{src["multicast_group"]}"')
|
||||||
parts.append(f"DataPort = {src['data_port']}")
|
parts.append(f"DataPort = {src['data_port']}")
|
||||||
|
iface = src.get("interface") or _mcast_interface_ip(src["multicast_group"])
|
||||||
|
parts.append(f'Interface = "{iface}"')
|
||||||
sigs = " ".join(_streamer_sig(sig) for sig in s)
|
sigs = " ".join(_streamer_sig(sig) for sig in s)
|
||||||
return (f" +Streamer_{src['id']} = {{ Class = UDPStreamer "
|
return (f" +Streamer_{src['id']} = {{ Class = UDPStreamer "
|
||||||
f"{' '.join(parts)} Signals = {{ {sigs} }} }}")
|
f"{' '.join(parts)} Signals = {{ {sigs} }} }}")
|
||||||
|
|||||||
@@ -46,9 +46,10 @@ INCLUDES += -I$(ROOT_DIR)/Common/UDP
|
|||||||
INCLUDES += -I$(ROOT_DIR)/Source/Components/DataSources/UDPStreamer
|
INCLUDES += -I$(ROOT_DIR)/Source/Components/DataSources/UDPStreamer
|
||||||
INCLUDES += -I$(ROOT_DIR)/Source/Components/Interfaces/DebugService
|
INCLUDES += -I$(ROOT_DIR)/Source/Components/Interfaces/DebugService
|
||||||
INCLUDES += -I$(ROOT_DIR)/Source/Components/Interfaces/TCPLogger
|
INCLUDES += -I$(ROOT_DIR)/Source/Components/Interfaces/TCPLogger
|
||||||
|
INCLUDES += -I$(ROOT_DIR)/Source/Components/Interfaces/UDPStream
|
||||||
INCLUDES += -I$(ROOT_DIR)/Test/Components/DataSources/UDPStreamer
|
INCLUDES += -I$(ROOT_DIR)/Test/Components/DataSources/UDPStreamer
|
||||||
|
|
||||||
OBJSX = DebugServiceGTest.x
|
OBJSX = DebugServiceGTest.x UDPSClientGTest.x
|
||||||
|
|
||||||
all: $(BUILD_DIR)/MainGTest$(EXEEXT)
|
all: $(BUILD_DIR)/MainGTest$(EXEEXT)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,296 @@
|
|||||||
|
/**
|
||||||
|
* @file UDPSClientGTest.cpp
|
||||||
|
* @brief GTest coverage for UDPSClient unicast keepalive.
|
||||||
|
*
|
||||||
|
* UDPSServer evicts silent unicast clients after its ClientTimeout (default
|
||||||
|
* 30 s). UDPSClient must therefore re-send a keepalive ACK from the same
|
||||||
|
* socket on KeepAliveInterval so the server refreshes its last-seen without
|
||||||
|
* re-sending CONFIG. These tests drive a real UDPSClient against a local
|
||||||
|
* UDP socket acting as the server and assert the wire behaviour; a final
|
||||||
|
* pair runs the REAL UDPSServer + UDPSClient past the eviction deadline to
|
||||||
|
* lock the fix in against regression.
|
||||||
|
*
|
||||||
|
* @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
|
||||||
|
* the Development of Fusion Energy ('Fusion for Energy').
|
||||||
|
* Licensed under the EUPL, Version 1.1 or - as soon they will be approved
|
||||||
|
* by the European Commission - subsequent versions of the EUPL (the "Licence")
|
||||||
|
* You may not use this work except in compliance with the Licence.
|
||||||
|
* You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
|
||||||
|
*
|
||||||
|
* @warning Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the Licence is distributed on an "AS IS"
|
||||||
|
* basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
|
* or implied. See the Licence permissions and limitations under the Licence.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DLL_API
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Standard header includes */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Project header includes */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#include "BasicUDPSocket.h"
|
||||||
|
#include "ConfigurationDatabase.h"
|
||||||
|
#include "InternetHost.h"
|
||||||
|
#include "Sleep.h"
|
||||||
|
#include "UDPSClient.h"
|
||||||
|
#include "UDPSProtocol.h"
|
||||||
|
#include "UDPSServer.h"
|
||||||
|
|
||||||
|
using namespace MARTe;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
/** @return the bound local port of @p sock, or 0 on failure. */
|
||||||
|
uint16 GetBoundPort(BasicUDPSocket &sock) {
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
socklen_t len = sizeof(addr);
|
||||||
|
if (getsockname(sock.GetReadHandle(),
|
||||||
|
reinterpret_cast<struct sockaddr *>(&addr), &len) != 0) {
|
||||||
|
return 0u;
|
||||||
|
}
|
||||||
|
return ntohs(addr.sin_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read one datagram from @p sock within @p timeoutMs.
|
||||||
|
* @return true and fills @p type/@p srcPort on a valid UDPS datagram; false
|
||||||
|
* on timeout or malformed packet.
|
||||||
|
*/
|
||||||
|
bool WaitDatagram(BasicUDPSocket &sock, int timeoutMs, uint8 &type,
|
||||||
|
uint16 &srcPort) {
|
||||||
|
int fd = sock.GetReadHandle();
|
||||||
|
if (fd < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fd_set rset;
|
||||||
|
FD_ZERO(&rset);
|
||||||
|
FD_SET(fd, &rset);
|
||||||
|
struct timeval tv;
|
||||||
|
tv.tv_sec = timeoutMs / 1000;
|
||||||
|
tv.tv_usec = (timeoutMs % 1000) * 1000;
|
||||||
|
int nready = select(fd + 1, &rset, NULL, NULL, &tv);
|
||||||
|
if (nready <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uint8 buf[UDPS_HEADER_SIZE];
|
||||||
|
uint32 size = UDPS_HEADER_SIZE;
|
||||||
|
if (!sock.Read(reinterpret_cast<char8 *>(buf), size)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (size < UDPS_HEADER_SIZE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const UDPSPacketHeader *hdr = reinterpret_cast<const UDPSPacketHeader *>(buf);
|
||||||
|
if (hdr->magic != UDPS_MAGIC) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
type = hdr->type;
|
||||||
|
InternetHost src = sock.GetSource();
|
||||||
|
srcPort = src.GetPort();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pump the UDPSServer service loop for @p durationMs, like UDPStreamer
|
||||||
|
* does from its background thread.
|
||||||
|
*/
|
||||||
|
void PumpServer(UDPSServer &server, uint32 durationMs) {
|
||||||
|
uint32 elapsed = 0u;
|
||||||
|
while (elapsed < durationMs) {
|
||||||
|
server.ServiceClients();
|
||||||
|
Sleep::MSec(20u);
|
||||||
|
elapsed += 20u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pump the server loop until a client registers (or timeout).
|
||||||
|
* @return true if at least one client connected.
|
||||||
|
*/
|
||||||
|
bool WaitForClient(UDPSServer &server, uint32 timeoutMs) {
|
||||||
|
uint32 elapsed = 0u;
|
||||||
|
while (elapsed < timeoutMs) {
|
||||||
|
server.ServiceClients();
|
||||||
|
if (server.GetClientCount() > 0u) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Sleep::MSec(20u);
|
||||||
|
elapsed += 20u;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Method definitions */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
TEST(UDPSClientGTest, TestUnicastKeepAliveSendsPeriodicAck) {
|
||||||
|
/* Fake server socket (ephemeral port) */
|
||||||
|
BasicUDPSocket server;
|
||||||
|
ASSERT_TRUE(server.Open());
|
||||||
|
ASSERT_TRUE(server.Listen(0u));
|
||||||
|
uint16 serverPort = GetBoundPort(server);
|
||||||
|
ASSERT_NE(serverPort, 0u);
|
||||||
|
|
||||||
|
ConfigurationDatabase cfg;
|
||||||
|
ASSERT_TRUE(cfg.Write("ServerAddr", "127.0.0.1"));
|
||||||
|
ASSERT_TRUE(cfg.Write("Port", static_cast<uint32>(serverPort)));
|
||||||
|
ASSERT_TRUE(cfg.Write("KeepAliveInterval", 1u));
|
||||||
|
/* SilenceTimeout=0 keeps the session stable for the whole test */
|
||||||
|
ASSERT_TRUE(cfg.Write("SilenceTimeout", 0u));
|
||||||
|
|
||||||
|
UDPSClient client;
|
||||||
|
ASSERT_TRUE(client.Initialise(cfg));
|
||||||
|
ASSERT_TRUE(client.Start());
|
||||||
|
|
||||||
|
/* 1) CONNECT from the client's ephemeral socket */
|
||||||
|
uint8 type = 0xFFu;
|
||||||
|
uint16 clientPort = 0u;
|
||||||
|
ASSERT_TRUE(WaitDatagram(server, 3000, type, clientPort));
|
||||||
|
EXPECT_EQ(type, UDPS_TYPE_CONNECT);
|
||||||
|
ASSERT_NE(clientPort, 0u);
|
||||||
|
|
||||||
|
/* 2) Keepalive ACKs arrive periodically from the SAME socket */
|
||||||
|
uint32 acks = 0u;
|
||||||
|
uint32 elapsedMs = 0u;
|
||||||
|
while ((acks < 2u) && (elapsedMs < 3500u)) {
|
||||||
|
uint8 t = 0xFFu;
|
||||||
|
uint16 port = 0u;
|
||||||
|
bool got = WaitDatagram(server, 1000, t, port);
|
||||||
|
elapsedMs += 1000u;
|
||||||
|
if (!got) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((t == UDPS_TYPE_ACK) && (port == clientPort)) {
|
||||||
|
acks++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPECT_GE(acks, 2u);
|
||||||
|
|
||||||
|
client.Stop();
|
||||||
|
server.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(UDPSClientGTest, TestKeepAliveDisabledWhenIntervalZero) {
|
||||||
|
BasicUDPSocket server;
|
||||||
|
ASSERT_TRUE(server.Open());
|
||||||
|
ASSERT_TRUE(server.Listen(0u));
|
||||||
|
uint16 serverPort = GetBoundPort(server);
|
||||||
|
ASSERT_NE(serverPort, 0u);
|
||||||
|
|
||||||
|
ConfigurationDatabase cfg;
|
||||||
|
ASSERT_TRUE(cfg.Write("ServerAddr", "127.0.0.1"));
|
||||||
|
ASSERT_TRUE(cfg.Write("Port", static_cast<uint32>(serverPort)));
|
||||||
|
ASSERT_TRUE(cfg.Write("KeepAliveInterval", 0u));
|
||||||
|
ASSERT_TRUE(cfg.Write("SilenceTimeout", 0u));
|
||||||
|
|
||||||
|
UDPSClient client;
|
||||||
|
ASSERT_TRUE(client.Initialise(cfg));
|
||||||
|
ASSERT_TRUE(client.Start());
|
||||||
|
|
||||||
|
uint8 type = 0xFFu;
|
||||||
|
uint16 clientPort = 0u;
|
||||||
|
ASSERT_TRUE(WaitDatagram(server, 3000, type, clientPort));
|
||||||
|
EXPECT_EQ(type, UDPS_TYPE_CONNECT);
|
||||||
|
|
||||||
|
/* No keepalive configured: nothing else must arrive */
|
||||||
|
EXPECT_FALSE(WaitDatagram(server, 2000, type, clientPort));
|
||||||
|
|
||||||
|
client.Stop();
|
||||||
|
server.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(UDPSClientGTest, TestKeepAlivePreventsServerEviction) {
|
||||||
|
/* Regression test for the 30 s unicast disconnect: UDPSServer evicts a
|
||||||
|
* silent client after ClientTimeout; the client's periodic ACKs must
|
||||||
|
* keep it registered. Drive the REAL server + client pair, like
|
||||||
|
* UDPStreamer + StreamHub do, past the eviction deadline. */
|
||||||
|
|
||||||
|
/* Free-port probe (UDP has no TIME_WAIT) */
|
||||||
|
BasicUDPSocket probe;
|
||||||
|
ASSERT_TRUE(probe.Open());
|
||||||
|
ASSERT_TRUE(probe.Listen(0u));
|
||||||
|
uint16 serverPort = GetBoundPort(probe);
|
||||||
|
probe.Close();
|
||||||
|
ASSERT_NE(serverPort, 0u);
|
||||||
|
|
||||||
|
/* Server with a short eviction timeout so the test is fast */
|
||||||
|
ConfigurationDatabase serverCfg;
|
||||||
|
ASSERT_TRUE(serverCfg.Write("Port", static_cast<uint32>(serverPort)));
|
||||||
|
ASSERT_TRUE(serverCfg.Write("ClientTimeout", 3u));
|
||||||
|
UDPSServer server;
|
||||||
|
ASSERT_TRUE(server.Initialise(serverCfg));
|
||||||
|
ASSERT_TRUE(server.Start());
|
||||||
|
|
||||||
|
/* Client: keepalive every 1 s (< server timeout), silence disabled */
|
||||||
|
ConfigurationDatabase clientCfg;
|
||||||
|
ASSERT_TRUE(clientCfg.Write("ServerAddr", "127.0.0.1"));
|
||||||
|
ASSERT_TRUE(clientCfg.Write("Port", static_cast<uint32>(serverPort)));
|
||||||
|
ASSERT_TRUE(clientCfg.Write("KeepAliveInterval", 1u));
|
||||||
|
ASSERT_TRUE(clientCfg.Write("SilenceTimeout", 0u));
|
||||||
|
UDPSClient client;
|
||||||
|
ASSERT_TRUE(client.Initialise(clientCfg));
|
||||||
|
ASSERT_TRUE(client.Start());
|
||||||
|
|
||||||
|
ASSERT_TRUE(WaitForClient(server, 3000)); /* CONNECT registered */
|
||||||
|
EXPECT_EQ(server.GetClientCount(), 1u);
|
||||||
|
|
||||||
|
/* Pump well past ClientTimeout: keepalive ACKs must prevent eviction */
|
||||||
|
PumpServer(server, 5000);
|
||||||
|
EXPECT_EQ(server.GetClientCount(), 1u);
|
||||||
|
|
||||||
|
client.Stop();
|
||||||
|
server.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(UDPSClientGTest, TestServerEvictsWithoutKeepAlive) {
|
||||||
|
/* Negative control: without keepalive the same harness MUST evict, which
|
||||||
|
* proves TestKeepAlivePreventsServerEviction passes because of the ACKs
|
||||||
|
* and not because eviction is broken. */
|
||||||
|
|
||||||
|
BasicUDPSocket probe;
|
||||||
|
ASSERT_TRUE(probe.Open());
|
||||||
|
ASSERT_TRUE(probe.Listen(0u));
|
||||||
|
uint16 serverPort = GetBoundPort(probe);
|
||||||
|
probe.Close();
|
||||||
|
ASSERT_NE(serverPort, 0u);
|
||||||
|
|
||||||
|
ConfigurationDatabase serverCfg;
|
||||||
|
ASSERT_TRUE(serverCfg.Write("Port", static_cast<uint32>(serverPort)));
|
||||||
|
ASSERT_TRUE(serverCfg.Write("ClientTimeout", 3u));
|
||||||
|
UDPSServer server;
|
||||||
|
ASSERT_TRUE(server.Initialise(serverCfg));
|
||||||
|
ASSERT_TRUE(server.Start());
|
||||||
|
|
||||||
|
ConfigurationDatabase clientCfg;
|
||||||
|
ASSERT_TRUE(clientCfg.Write("ServerAddr", "127.0.0.1"));
|
||||||
|
ASSERT_TRUE(clientCfg.Write("Port", static_cast<uint32>(serverPort)));
|
||||||
|
ASSERT_TRUE(clientCfg.Write("KeepAliveInterval", 0u));
|
||||||
|
ASSERT_TRUE(clientCfg.Write("SilenceTimeout", 0u));
|
||||||
|
UDPSClient client;
|
||||||
|
ASSERT_TRUE(client.Initialise(clientCfg));
|
||||||
|
ASSERT_TRUE(client.Start());
|
||||||
|
|
||||||
|
ASSERT_TRUE(WaitForClient(server, 3000)); /* CONNECT registered */
|
||||||
|
EXPECT_EQ(server.GetClientCount(), 1u);
|
||||||
|
|
||||||
|
/* No ACKs: the server must evict after ClientTimeout */
|
||||||
|
PumpServer(server, 5000);
|
||||||
|
EXPECT_EQ(server.GetClientCount(), 0u);
|
||||||
|
|
||||||
|
client.Stop();
|
||||||
|
server.Stop();
|
||||||
|
}
|
||||||
@@ -195,3 +195,151 @@
|
|||||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-test-part.h \
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-test-part.h \
|
||||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-typed-test.h \
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-typed-test.h \
|
||||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest_pred_impl.h
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest_pred_impl.h
|
||||||
|
../../Build/x86-linux//GTest/UDPSClientGTest.o: UDPSClientGTest.cpp \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-internal.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-port.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-message.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-string.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-filepath.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-type-util.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-death-test.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-death-test-internal.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-param-test.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-param-util.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-linked_ptr.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-printers.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest_prod.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-test-part.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-typed-test.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest_pred_impl.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/BasicUDPSocket.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/BasicSocket.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/InternetHost.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamString.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Architecture/x86_gcc/CompilerTypes.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/GeneralDefinitions.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapManager.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorInformation.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ErrorType.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TemplateParametersVerificator.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/HighResolutionTimerA.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HighResolutionTimer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimerCalibrator.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../GeneralDefinitions.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/CharBuffer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/BufferedStreamI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassProperties.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryDatabase.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectsDatabase.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/StandardHeap.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HeapI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../Generic/StandardHeap_Generic.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FastPollingMutexSem.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Atomic.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/AtomicA.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItem.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CString.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Introspection.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/IntrospectionEntry.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TypeDescriptor.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BasicType.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolderT.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/IteratorT.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Iterator.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolder.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/SortFilter.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/SearchFilter.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/LoadableLibrary.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ObjectBuilder.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticList.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticListHolder.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Matrix.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/MemoryOperationsHelper.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FormatDescriptor.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/IOBuffer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StringHelper.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamStringIOBuffer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/Environment/Linux/InternetHostCore.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/Environment/Linux/InternetMulticastCore.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HandleI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/Environment/Linux/SocketCore.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/ConfigurationDatabase.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/AnyObject.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/CLASSREGISTER.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItemT.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ObjectBuilderT.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/ConfigurationDatabaseNode.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Fnv1aHashFunction.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/HashFunction.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolder.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Reference.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainerFilter.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainerNode.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceT.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/UnorderedMap.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapManager.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StringHelper.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainerFilterObjectName.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/TypeConversion.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/InternetHost.h \
|
||||||
|
../../Source/Components/Interfaces/UDPStream/UDPSClient.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/BasicTCPSocket.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/ExecutionInfo.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L1Portability/Threads.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ThreadsB.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L1Portability/ExceptionHandler.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ProcessorType.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitSet.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/ExecutionInfo.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/SingleThreadService.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderT.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThreadI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThread.h \
|
||||||
|
../../Common/UDP/UDPSProtocol.h
|
||||||
|
|||||||
@@ -195,3 +195,151 @@ MainGTest.o: MainGTest.cpp \
|
|||||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-test-part.h \
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-test-part.h \
|
||||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-typed-test.h \
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-typed-test.h \
|
||||||
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest_pred_impl.h
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest_pred_impl.h
|
||||||
|
UDPSClientGTest.o: UDPSClientGTest.cpp \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-internal.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-port.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-message.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-string.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-filepath.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-type-util.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-death-test.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-death-test-internal.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-param-test.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-param-util.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-linked_ptr.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-printers.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest_prod.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-test-part.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest-typed-test.h \
|
||||||
|
/home/martino/workspace/MARTe2/Lib/gtest-1.7.0/include/gtest/gtest_pred_impl.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/BasicUDPSocket.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/BasicSocket.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/InternetHost.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamString.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Architecture/x86_gcc/CompilerTypes.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/GeneralDefinitions.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapManager.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorInformation.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ErrorType.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TemplateParametersVerificator.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/TypeCharacteristics.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GeneralDefinitions.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/HighResolutionTimerA.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CompilerTypes.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HighResolutionTimer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/HighResolutionTimerCalibrator.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../GeneralDefinitions.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeStamp.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/CharBuffer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitBoolean.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ErrorManagement.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/BufferedStreamI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TimeoutType.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassProperties.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryDatabase.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectsDatabase.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/GlobalObjectI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/StandardHeap.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../../HeapI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Environment/Linux/../Generic/StandardHeap_Generic.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FastPollingMutexSem.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Atomic.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Architecture/x86_gcc/AtomicA.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItem.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/CString.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Introspection.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/IntrospectionEntry.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/TypeDescriptor.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BasicType.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/FractionalInteger.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitRange.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/ZeroTerminatedArray.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolderT.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/IteratorT.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Iterator.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListable.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolder.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/SortFilter.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/SearchFilter.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/LoadableLibrary.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ObjectBuilder.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticList.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StaticListHolder.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Matrix.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/MemoryOperationsHelper.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/FormatDescriptor.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/IOBuffer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StreamI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StringHelper.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L3Streams/StreamStringIOBuffer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/Environment/Linux/InternetHostCore.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/Environment/Linux/InternetMulticastCore.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HandleI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/Environment/Linux/SocketCore.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/Sleep.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/ConfigurationDatabase.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/AnyObject.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/AnyType.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/CLASSREGISTER.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ClassRegistryItemT.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ObjectBuilderT.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/ConfigurationDatabaseNode.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Fnv1aHashFunction.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/HashFunction.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/LinkedListHolder.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Object.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/Reference.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainerFilter.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainerNode.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceT.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/UnorderedMap.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HeapManager.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/StringHelper.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainerFilterObjectName.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/ReferenceContainer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L2Objects/StructuredDataI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L4Configuration/TypeConversion.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/Vector.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/InternetHost.h \
|
||||||
|
../../Source/Components/Interfaces/UDPStream/UDPSClient.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/FileSystem/L1Portability/BasicTCPSocket.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/ExecutionInfo.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L1Portability/Threads.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ThreadsB.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L1Portability/ExceptionHandler.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/ProcessorType.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L0Types/BitSet.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/ExecutionInfo.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/BareMetal/L1Portability/HighResolutionTimer.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/SingleThreadService.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedServiceMethodBinderT.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThreadI.h \
|
||||||
|
/home/martino/workspace/MARTe2/Source/Core/Scheduler/L3Services/EmbeddedThread.h \
|
||||||
|
../../Common/UDP/UDPSProtocol.h
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user