Repository navigation
Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Repository files navigation
# Dmn: Distributed Messaging & Synchronization Dmn is a C++ library for distributed messaging and data synchronization. It provides building blocks for networking, message exchange, concurrency control, and conflict resolution, with an emphasis on delegation and integration into existing applications. ## Documentation Generated documentation: <https://cheebinhoh.github.io/Dmn/> ## Build and test on Linux The project uses CMake and fetches its third-party dependencies during configuration when they are not available locally. ICU development files are required. On Ubuntu, install the native build prerequisites with: ```bash sudo apt-get update sudo apt-get install build-essential cmake git libicu-dev ``` Then configure, build, and run the regular unit tests: ```bash cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug cmake --build build -j2 ctest --test-dir build -L dmn --output-on-failure ``` ### Valgrind tests Install Valgrind (on Ubuntu, `sudo apt-get install valgrind`) and enable its test variants at configure time: ```bash cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DENABLE_VALGRIND=ON cmake --build build -j2 ctest --test-dir build -L 'dmn|valgrind' --output-on-failure ``` This runs the regular tests plus their Valgrind variants. The `valgrind` variants are only registered when `ENABLE_VALGRIND=ON`. ### Kafka integration tests Kafka tests are optional and require a broker available at `localhost:9092`. Either start a broker and create the `timer_counter` topic yourself, or enable `BUILD_KAFKA_TEST=ON` and use the staged project helper. For example, with Kafka's command-line tools: ```bash kafka-topics.sh --create --topic timer_counter --bootstrap-server localhost:9092 ``` Then configure, build, and run the Kafka tests: ```bash cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DBUILD_KAFKA_TEST=ON cmake --build build -j2 ./build/scripts/run-bookstrap-dmn.sh ctest --test-dir build -L kafka --output-on-failure ./build/scripts/run-bookstrap-dmn.sh stop ``` The helper downloads and verifies the pinned Kafka distribution when needed; it requires Java and network access on first use. The Docker entrypoint starts Kafka and creates this topic automatically. ### D-Bus extension The optional D-Bus extension provides byte-oriented input/output adapters that send and receive D-Bus signals, plus a typed generic client for method calls, properties, and signal subscriptions. The signal adapters can carry serialized DMesg messages through `Dmn_DMesgNet` or other application payloads using a configured signal routing tuple. The extension is intended for inter-process communication on one host and does not provide cross-host transport. The core `dmn` library does not depend on D-Bus; the extension is built separately as `dmn-dbus` and is disabled by default. `Dmn_DMesgDbus` is the DMesg-specific composition facade for applications that do not need to construct the underlying D-Bus endpoints directly; advanced callers can continue to inject `Dmn_DbusInput` and `Dmn_DbusOutput` into `Dmn_DMesgNet`. When an application links `dmn-dbus`, the target defines `DMN_ENABLE_DBUS`, so `dmn.hpp` also includes the D-Bus configuration, endpoint, and facade headers. Generic clients include `dmn-dbus-client.hpp` and `dmn-dbus-value.hpp` directly; BlueZ clients include `dmn-bluez-client.hpp`. Without the optional target and its compile definitions, the umbrella header does not include the optional D-Bus API. The `dmn-fault-injection.hpp` header is included by `dmn.hpp` only when `ENABLE_FAULT_INJECTION=ON` defines `FIU_ENABLE`; its CMake target-source registration is gated by the same option. On Ubuntu, install the libdbus development files, pkg-config, and daemon used by the private-bus unit test: ```bash sudo apt-get install libdbus-1-dev pkg-config dbus-daemon ``` Enable the extension and run its test (registered under the regular `dmn` CTest label): ```bash cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DENABLE_DBUS=ON cmake --build build -j2 ctest --test-dir build -R '^dmn-test-dbus-io$' --output-on-failure ctest --test-dir build -R '^dmn-test-dbus-facade$' --output-on-failure ``` ### BlueZ discovery CLI On Linux, the optional `dmn-bluez-cli` program prints BlueZ's known adapter/device inventory and can explicitly start a scan on one powered adapter. It depends on the Dmn D-Bus extension, but not on GATT or ANCS. Install the D-Bus development package and daemon as above, then configure and build both optional Bluetooth CLIs: ```bash cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug \ -DENABLE_APP_BLUEZ_DISCOVERY=ON -DENABLE_APP_BLUETOOTH=ON cmake --build build --target dmn-bluez-cli dmn-bluetooth-cli -j2 ``` Install the built libraries, CLIs, headers, and their manual pages (use `sudo` if installing to a system prefix): ```bash cmake --install build --prefix "$HOME/.local" export PATH="$HOME/.local/bin:$PATH" man -M "$HOME/.local/share/man" dmn-bluez-cli man -M "$HOME/.local/share/man" dmn-bluetooth-cli ``` Print the current known-device inventory as CSV without starting discovery: ```bash ./build/src/app/dmn-bluez-cli ``` The CSV includes the adapter address and path needed to select a scan target. Start an explicit scan with either selector; if exactly one powered adapter exists, `--adapter` may be omitted: ```bash ./build/src/app/dmn-bluez-cli --discovery \ --adapter 'B8:F7:75:BF:F3:C3' ``` The CLI prints initial known devices, then live add/change/remove rows until Ctrl-C or SIGTERM. It stops only the discovery session it started. It does not pair, connect, change trust, or power an adapter. Scanning requires a working BlueZ system service and local system-bus policy that permits the discovery calls; the CLI does not fall back to the session bus. For argument syntax, run `./build/src/app/dmn-bluez-cli --help`. The private-bus integration coverage can be run with: ```bash ctest --test-dir build -R '^dmn-test-bluez-device-list$' \ --output-on-failure ``` ### Bluetooth ANCS monitor CLI The optional `dmn-bluetooth-cli` command pairs/connects one selected device as needed and monitors its ANCS notifications: ```bash ./build/src/app/dmn-bluetooth-cli monitor "iPhone Genghis" ``` See `man dmn-bluetooth-cli` for its options, output, failure handling, and recovery guidance. This CLI requires a working BlueZ system service and does not provide a graphical interface. ### GTK Bluetooth application On Linux desktops, the optional `dmn-bluetooth-gtk` app provides a graphical interface for browsing BlueZ devices, saving a device selection, connecting and disconnecting, and explicitly starting or stopping ANCS monitoring. The GTK application and CLI are separate frontends to the same BlueZ/ANCS functionality; enabling the GTK build does not build or replace the CLI. The app never connects automatically. **Start monitoring** is an explicit choice saved per device, so the app can restore that intent on later launches. It starts the monitor only after the device is saved, paired, and BlueZ confirms it is connected; if disconnected, it waits for you to connect it. **Stop monitoring** clears the saved intent. Disconnecting or exiting stops the live monitor but preserves the intent, so monitoring can resume after reconnection or relaunch. The newest-first event feed contains only notifications received while the app process is running; it is not a persistent notification archive or a desktop notification-history reader. Search and device, event-kind, and category filters compose; activating a row shows available details. The feed is capped at 1,000 in-memory events, with older-event eviction reported in the interface. Hovering over notification text shows its full value wrapped to the available feed width. The GTK app requires a running BlueZ system service and a graphical desktop session. Install the additional development dependencies on Ubuntu: ```bash sudo apt-get install libgtk-4-dev libadwaita-1-dev ``` GTK 4 4.14 or newer and libadwaita 1.5 or newer are required. Configure and build the app without enabling the CLI: ```bash cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug \ -DENABLE_APP_BLUETOOTH_GTK=ON cmake --build build --target dmn-bluetooth-gtk -j2 ./build/src/app/dmn-bluetooth-gtk ``` The GTK option enables the required ANCS, BlueZ, and D-Bus libraries but remains off in default/headless builds. To install the application, desktop launcher, AppStream metadata, icons, and settings schema into a user prefix: ```bash cmake --install build --prefix "$HOME/.local" ``` For the implemented UI, remaining features, and current design details, see the [GTK application specification](docs/specs/dmn-bluetooth-gtk-app-spec.md) and its [UI storyboard](docs/specs/dmn-bluetooth-gtk-ui-storyboard.md). ## Fault-injection tests Fault-injection support is optional and disabled by default. Enabling it links libfiu into the fault-injection build. CMake uses an installed libfiu package found through pkg-config when available; otherwise it fetches and builds libfiu 1.2 and its `fiu-run` launcher. ```bash cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DENABLE_FAULT_INJECTION=ON cmake --build build --target fault-injection-tests -j2 ctest --test-dir build -L fault-injection --output-on-failure ``` Fault-injection tests are GoogleTest executables invoked by CTest through `fiu-run`. They use the separate `fault-injection` label and are not included in the regular `dmn` test group. To run one test by name: ```bash ctest --test-dir build -R '^dmn-test-fi-timer-thread-start-failure$' \ --output-on-failure ``` The recurring-reschedule failure test can be run individually with: ```bash ctest --test-dir build -R '^dmn-test-fi-timer-reschedule-failure$' \ --output-on-failure ``` ## Docker From the repository root, build the image: ```bash docker build -t dmn . ``` Start it interactively with its normal entrypoint: ```bash docker run -it --rm dmn ``` The image enables its non-hardware CMake options (the GTK desktop app is not included). On startup, the entrypoint bootstraps the Kafka topic and runs the `dmn`, `kafka`, `valgrind`, and `fault-injection` CTest groups. If they pass, it opens a Bash prompt in the container; if they fail, the entrypoint exits without opening the prompt. The run command removes the container when you exit because it uses `--rm`. To enter a shell immediately without starting Kafka or running tests, bypass the entrypoint: ```bash docker run -it --rm --entrypoint /bin/bash dmn ``` The image is built with `BUILD_NDEBUG=ON`, which disables assertions. Use a native build with `BUILD_NDEBUG=OFF` when assertions are needed. To build with Docker Buildx and load the image into the local Docker engine: ```bash docker buildx build -t dmn:latest --load . ``` Remove the image when it is no longer needed: ```bash docker rmi dmn ``` ## CMake options | Option | Default | Purpose | | --- | --- | --- | | `BUILD_NDEBUG` | `OFF` | Define `NDEBUG` for the build. | | `BUILD_KAFKA_TEST` | `OFF` | Build the additional Kafka integration tests. | | `ENABLE_DBUS` | `OFF` | Build the optional D-Bus signal I/O extension and generic D-Bus client. Requires libdbus development files and pkg-config; private-bus tests require `dbus-daemon`. | | `ENABLE_BLUEZ` | `OFF` | Build the Linux BlueZ library; automatically enables its `ENABLE_DBUS` dependency. | | `ENABLE_ANCS` | `OFF` | Build the backend-neutral ANCS protocol library. | | `ENABLE_APP_BLUEZ_DISCOVERY` | `OFF` | Build and install `dmn-bluez-cli`; automatically enables `ENABLE_BLUEZ` and `ENABLE_DBUS`. | | `ENABLE_APP_BLUETOOTH` | `OFF` | Build and install `dmn-bluetooth-cli`; automatically enables `ENABLE_ANCS`, `ENABLE_BLUEZ`, and `ENABLE_DBUS`. | | `ENABLE_APP_BLUETOOTH_GTK` | `OFF` | Build and install the Linux GTK 4/libadwaita `dmn-bluetooth-gtk` desktop app; automatically enables `ENABLE_ANCS`, `ENABLE_BLUEZ`, and `ENABLE_DBUS`. Requires GTK 4 4.14+, libadwaita 1.5+, and GLib schema tools. | | `ENABLE_ANCS_HARDWARE_TESTS` | `OFF` | Register the opt-in physical-iPhone test; requires `ENABLE_APP_BLUETOOTH=ON`. | | `ENABLE_VALGRIND` | `OFF` | Register Valgrind test variants; requires Valgrind. | | `ENABLE_FAULT_INJECTION` | `OFF` | Build libfiu support and register tests run through `fiu-run`. | The options are cached in the build directory. Reconfigure that directory with the desired options before building. The `dmn` CTest label selects the regular unit tests; `kafka`, `fault-injection`, and `valgrind` select their respective optional test groups. On Linux, to enable the non-hardware CMake options used in the example below, including Kafka, D-Bus, BlueZ, ANCS, both Bluetooth CLI programs, Valgrind, and fault injection, configure and build as shown. The optional GTK app has separate GTK/libadwaita dependencies described above. BlueZ tests use a private bus and do not require a physical adapter; the physical-iPhone test remains opt-in: ```bash cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug \ -DBUILD_NDEBUG=ON \ -DBUILD_KAFKA_TEST=ON \ -DENABLE_DBUS=ON \ -DENABLE_BLUEZ=ON \ -DENABLE_ANCS=ON \ -DENABLE_APP_BLUEZ_DISCOVERY=ON \ -DENABLE_APP_BLUETOOTH=ON \ -DENABLE_VALGRIND=ON \ -DENABLE_FAULT_INJECTION=ON cmake --build build -j2 ``` This configuration requires libdbus development files, pkg-config, `dbus-daemon`, Valgrind, and Java plus network access to bootstrap Kafka on first use. Run the Kafka helper before its tests, then run every registered test group with: ```bash ./build/scripts/run-bookstrap-dmn.sh ctest --test-dir build -L 'dmn|kafka|valgrind|fault-injection' \ --output-on-failure ./build/scripts/run-bookstrap-dmn.sh stop ``` `BUILD_NDEBUG=ON` disables assertions, so use `OFF` if you want assertions enabled while running the full test groups.