> For the complete documentation index, see [llms.txt](https://decentralabs-2.gitbook.io/decentralabs-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://decentralabs-2.gitbook.io/decentralabs-docs/lab-gateway/digital-twins/fmu-proxy-runtime-src.md).

# FMU proxy runtime source

This directory contains the source implementation for the native runtime that is packaged into generated `proxy.fmu` artifacts.

It is intentionally separate from `../fmu-proxy-runtime/`, which remains the binary drop location mounted into `fmu-runner`.

## Current decisions

* Transport: `WSS` from proxy runtime to Gateway
* FMI target: `FMI 2.0.x Co-Simulation` for the MVP, with current `win64` support extended to scalar/dimensioned `FMI 3.0 Co-Simulation`
* Implementation language: `C++17` with the FMI C ABI export layer
* Artifact model: generic runtime binaries plus reservation-specific `modelDescription.xml` and `resources/config.json`

## Current implementation status

The files here now implement a functional `win64` runtime:

* FMI 2 Co-Simulation export layer
* FMI 3 Co-Simulation export layer for scalar and dimensioned variables
* widened FMI 3 primitive type support in the runtime source and ABI: `Float32`, `Float64`, `Int8`, `UInt8`, `Int16`, `UInt16`, `Int32`, `UInt32`, `Int64`, `UInt64`, `Boolean`, `String`, `Binary`, `Clock`
* `resources/config.json` loading
* `modelDescription.xml` parsing for generated proxy metadata
* local runtime state, cached values and FMI call mapping
* Gateway protocol client with request/response correlation
* native `WSS` transport on Windows via WinHTTP
* native `WSS` transport on Linux via OpenSSL + raw sockets/WebSocket framing
* native POSIX/OpenSSL `WSS` source path shared by Linux and Darwin
* certificate-chain and hostname validation for every WSS connection (including loopback)
* self-contained C++ unit tests for parsing, protocol, transport and runtime lifecycle
* a compiled `win64` DLL build in `build-win64/`
* a reproducible `linux64` build in `build-linux64/`
* end-to-end validation against the live Lab Gateway stack with `fmpy` for both:
  * FMI 2 proxy generation/loading
  * FMI 3 scalar proxy generation/loading (`Stair.fmu`)
  * FMI 3 dimensioned-variable proxy generation/loading (`StateSpace.fmu`)
  * Linux-container loading of downloaded `proxy.fmu` artifacts for:
    * FMI 2 (`BouncingBall.fmu`)
    * FMI 3 with dimensioned outputs (`StateSpace.fmu`)

What still is not finished:

* `darwin64` is prepared at source/build level, but no real binary has been built yet
* `darwin64` is not validated end-to-end yet
* `Binary` and `Clock` are now implemented in the proxy generator, local Gateway path and runtime ABI, but they are not yet validated against a real sample FMU/tool pair in this environment
* full-range exact `Int64` / `UInt64` fidelity is preserved in the current Gateway/runtime path by transporting 64-bit integers as decimal strings where required
* FMI 3 support is still not validated across the full type matrix and tool matrix
* FMI 3 Model Exchange and Scheduled Execution are not supported

Promoted compiled binaries are copied into:

* `../fmu-proxy-runtime/binaries/linux64/decentralabs_proxy.so`
* `../fmu-proxy-runtime/binaries/win64/decentralabs_proxy.dll`
* `../fmu-proxy-runtime/binaries/darwin64/decentralabs_proxy.dylib`

## Reproducible linux64 build

From Windows with Docker Desktop running:

```powershell
pwsh .\fmu-proxy-runtime-src\build-linux64-runtime.ps1

# Build and promote the shared library to the runtime drop path
pwsh .\fmu-proxy-runtime-src\build-linux64-runtime.ps1 -Promote
```

This uses `docker/linux64-builder.Dockerfile` and produces:

* `build-linux64/libdecentralabs_proxy.so`
* optionally `../fmu-proxy-runtime/binaries/linux64/decentralabs_proxy.so`

## Native unit tests

The native runtime tests use CTest and do not require a live Gateway or an external test framework:

```bash
cmake -S . -B build-tests -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON
cmake --build build-tests
ctest --test-dir build-tests --output-on-failure
```

The suite exercises JSON/configuration parsing, FMI model metadata, protocol and session-state transitions, scripted transport behavior, Gateway request correlation and the complete local runtime lifecycle.

## Deploying the linux64 binary to a Lab Gateway server

The compiled binaries (`decentralabs_proxy.so`, `.dll`, `.dylib`) are committed to the repository. On a new or existing server a `git pull` is sufficient to get the latest binary:

```bash
cd /opt/Lab-Gateway
git pull
docker compose up -d --no-deps fmu-runner
```

> **Note:** The volume `./fmu-proxy-runtime:/app/fmu-proxy-runtime:ro` is mounted at container start. Any time the binary on the host changes you must restart (not just reload) the `fmu-runner` container so the new `.so` is visible inside.

### Rebuilding the binary after source changes

Run this once from your Windows dev machine whenever the source in `fmu-proxy-runtime-src/` changes:

```powershell
# Build inside Docker and promote the .so to the runtime drop path
pwsh .\fmu-proxy-runtime-src\build-linux64-runtime.ps1 -Promote
```

Then commit and push `fmu-proxy-runtime/binaries/linux64/decentralabs_proxy.so`. The server just needs a `git pull` + container restart as above.

If you need to rebuild directly on the server (e.g. no Windows machine available):

```bash
cd /opt/Lab-Gateway/fmu-proxy-runtime-src

docker build -f docker/linux64-builder.Dockerfile -t fmu-proxy-builder:local .

docker run --rm \
  -v "$(pwd):/workspace" \
  fmu-proxy-builder:local \
  bash -lc "cmake -S /workspace -B /workspace/build-linux64 -G Ninja \
            -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON && \
            cmake --build /workspace/build-linux64 -j && \
            ctest --test-dir /workspace/build-linux64 --output-on-failure"

cp build-linux64/libdecentralabs_proxy.so \
   /opt/Lab-Gateway/fmu-proxy-runtime/binaries/linux64/decentralabs_proxy.so

cd /opt/Lab-Gateway
docker compose up -d --no-deps fmu-runner
```

## Native darwin64 build

Run this on a real macOS machine with Xcode Command Line Tools, CMake, Ninja and OpenSSL 3 installed:

```bash
cd fmu-proxy-runtime-src
./build-darwin64-runtime.sh

# Build and promote the dylib to the runtime drop path
./build-darwin64-runtime.sh --promote
```

By default the script looks for OpenSSL at `OPENSSL_ROOT_DIR` and then falls back to `brew --prefix openssl@3`.

## Project layout

```
fmu-proxy-runtime-src/
|- ARCHITECTURE.md
|- CMakeLists.txt
|- include/decentralabs_proxy/
|  |- protocol.hpp
|  |- runtime_config.hpp
|  |- runtime.hpp
|  |- transport.hpp
|  `- session_state.hpp
|- src/
   |- fmi2_exports.cpp
   |- gateway_client.cpp
   |- json.cpp
   |- model_description.cpp
   |- protocol.cpp
   |- runtime.cpp
   |- runtime_config.cpp
   |- session_state.cpp
   |- transport.cpp
|  `- transport_linux.cpp
`- tests/
   `- unit_tests.cpp
```

## Remaining validation milestones

1. Produce and validate a real `darwin64` binary
2. Add dedicated automated regression coverage for FMI 2 and FMI 3 live proxy simulation
3. Validate `Binary` and `Clock` against real FMI 3 sample FMUs and tools
4. Extend FMI 3 support to Model Exchange and Scheduled Execution
5. Validate the exact `Int64` / `UInt64` transport path against more external FMI tools
