Implemented hearthbit client side + tests

This commit is contained in:
Martino Ferrari
2026-08-09 18:51:51 +02:00
parent 915a192b16
commit 1ddb4fe356
12 changed files with 994 additions and 285 deletions
+198 -270
View File
@@ -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 (s01s57) 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.820.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.
+14
View File
@@ -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.
+69
View File
@@ -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)
}
}
+46 -1
View File
@@ -172,6 +172,11 @@ 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.
@@ -181,6 +186,7 @@ type UDPClient struct {
hub *Hub hub *Hub
multicastGroup string multicastGroup string
dataPort int dataPort int
keepAliveInterval time.Duration
stopCh chan struct{} stopCh chan struct{}
} }
@@ -192,6 +198,7 @@ func NewUDPClient(serverAddr, sourceID string, hub *Hub, multicastGroup string,
hub: hub, hub: hub,
multicastGroup: multicastGroup, multicastGroup: multicastGroup,
dataPort: dataPort, dataPort: dataPort,
keepAliveInterval: keepAliveInterval,
stopCh: make(chan struct{}), 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) conn.WriteToUDP(udpsprotocol.BuildDisconnectPacket(), serverAddr)
return err return err
} }
// Short wakeup: keepalive if due, then keep waiting.
if kaErr := sendKeepAliveIfDue(); kaErr != nil {
return kaErr
}
continue
}
conn.WriteToUDP(udpsprotocol.BuildDisconnectPacket(), serverAddr)
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
}
} }
} }
@@ -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,6 +174,7 @@ 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. */
@@ -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;
@@ -115,6 +120,7 @@ public:
* - 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.
@@ -168,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();
@@ -196,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;
@@ -209,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
+2 -1
View File
@@ -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)
+296
View File
@@ -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();
}
+148
View File
@@ -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
+148
View File
@@ -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