8000 GitHub - idrees-mahmood/BLE-HMS: Offline-first hospital management research prototype using Flutter and ESP32 BLE mesh relays · GitHub
[go: up one dir, main page]

Skip to content
idrees-mahmoodPublic

About

Offline-first hospital management research prototype using Flutter and ESP32 BLE mesh relays

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

HMS Offline

Offline-first electronic patient records over a small ESP32 Bluetooth Low Energy relay mesh.

Warning

Research prototype only. HMS Offline is not clinically certified, production-ready, or approved for patient care. Do not use it with real patient data or as the basis for clinical decisions.

Why this exists

Hospitals and field clinics cannot assume continuous internet access. HMS Offline explores whether several phones can keep a small electronic patient record (EPR) dataset available and eventually consistent using local storage and inexpensive BLE relay nodes, without a central server.

What was built

  • A Flutter mobile app for iOS and Android with a local SQLite database managed by Drift (schema version 9).
  • ESP32 firmware that accepts phone connections and forwards framed sync traffic across a small multi-hop BLE relay mesh.
  • Conflict-aware replication that preserves concurrent edits for manual, field-level resolution instead of silently choosing a winner.
  • A Dart evaluation harness, macOS site runner, Swift CoreBluetooth proxy, and physical BLE smoke-test utility.

Architecture

flowchart LR
    subgraph A[Phone A]
        AUI[Flutter EPR]
        ADB[(Drift / SQLite v9)]
        AUI --- ADB
    end

    subgraph Mesh[Small ESP32 BLE relay mesh]
        R1[ESP32 relay]
        R2[ESP32 relay]
        R3[ESP32 relay]
        R1 <--> R2
        R2 <--> R3
        R1 <--> R3
    end

    subgraph B[Phone B]
        BUI[Flutter EPR]
        BDB[(Drift / SQLite v9)]
        BUI --- BDB
    end

    AUI <-->|BLE framed messages| R1
    R3 <-->|BLE framed messages| BUI
Loading

Phones own the durable patient data. ESP32 nodes are bounded, store-and-forward transports: they queue, deduplicate, and flood messages but do not maintain the EPR database. Each protocol payload is wrapped in an 8-byte header containing magic, version, flags, payload length, and CRC16.

Synchronisation and conflict handling

Mutable patient and medical-record rows carry the Lamport timestamp and content hash of the version their editor saw. An incoming edit fast-forwards only when that (parentLamport, parentRowHash) matches the receiver's current row. A mismatch preserves the incoming version as a conflict branch for manual field-level merge. Lamport clocks still provide logical ordering; the content parent hash prevents equal-clock versions from being mistaken for the same parent.

Vital observations are immutable. Corrections create a new vital linked to the original, giving the table grow-only-set semantics instead of in-place edits.

Periodic Merkle roots cheaply detect that two datasets differ. The live repair path then exchanges cursor-paginated (rowId, leafHash) manifests, computes a keyed set difference, and requests only missing or divergent rows. The older positional Merkle walk remains in the codebase but is dormant because tree shape can differ when peers hold different row sets.

See the protocol reference and conflict-resilience design for the wire formats and decision rules.

Repository layout

Path Purpose
mobile-app/ Flutter EPR application and sync engine
embedded/ESP32-Mesh-Node/ ESP32 relay and mesh firmware
harness/ Distributed scenarios, orchestration, assertions, and site runners
hardware-test/ Physical macOS BLE smoke utility using virtual phones and a real relay
tools/ble-proxy/ Swift CoreBluetooth bridge used by simulated phones
docs/ Architecture, protocol, design history, setup, and evaluation material

Prerequisites

  • Verified release toolchain: Flutter 3.41.6 (stable) with its bundled Dart 3.11.4. Other versions are not part of the reproducibility baseline.
  • PlatformIO 6.x and an ESP32 development board for firmware.
  • Android Studio or Xcode for a mobile build; device signing is platform specific.
  • macOS 12 or later with Xcode command-line tools and Bluetooth for the Swift proxy and physical BLE utilities.

See the development guide for device setup and troubleshooting.

Executable Dart/Flutter packages commit pubspec.lock so pub get reuses the validated dependency versions. Reusable library packages harness/shared and harness/scenarios intentionally do not commit locks.

Build and test

Mobile app:

cd mobile-app
flutter pub get
flutter test

# Optional Android build
flutter build apk

ESP32 firmware:

cd embedded/ESP32-Mesh-Node
pio test -e native_test
pio run -e mesh

Dart director:

cd harness/director
dart pub get
dart test
export HOME_PC_TOKEN="$(openssl rand -hex 32)"
dart run bin/director.dart serve --port 8080 \
  --scenarios-dir ../scenarios/example

The director listens on 0.0.0.0; run it only on a trusted private network behind a firewall and configure every client with the same HOME_PC_TOKEN.

macOS BLE proxy:

cd tools/ble-proxy
swift build -c release

Hardware validation

Simulation and physical evidence are kept distinct:

  • Automated simulation exercises convergence, partitions, concurrent edits, anti-entropy, and bounded-ripple assertions without claiming radio behavior.
  • Physical testing validated two phones through one relay, including convergence and empty-phone backfill.
  • A two-phone, two-relay chain validated multi-hop reconciliation in both directions.
  • A three-relay triangle formed and converged under light incremental load.

Heavy bulk traffic over the triangle has not been validated. It can exhaust the constrained BLE buffer pool on a redundant edge, so the light-load result must not be read as a throughput or production-scale claim. Reproduction procedures and empty result tables are in the evaluation runbook and results template.

Known limitations and security boundary

  • Direct phone-to-phone transport is deferred; deployed sync paths assume an ESP32 relay.
  • iOS background sync is not implemented, so iOS sync is foreground-only.
  • Relays have no peer authentication, messages have no application-layer encryption, and the app has no role-based access control (RBAC). The current threat model assumes trusted lab devices and is unsuitable for clinical data.
  • Flood routing and the current lock-based firmware design target a small mesh of roughly four relays or fewer. Larger deployments need a different routing and ownership model.
  • Hardware results cover the specific topologies and loads listed above, not reliability, safety, or performance in a clinical deployment.

Additional constraints are tracked in the architecture and sync design evolution.

Documentation

Copyright

Copyright (c) 2026 Idrees Mahmood. All rights reserved. This repository is available for viewing and evaluation only; see LICENSE.

About

Offline-first hospital management research prototype using Flutter and ESP32 BLE mesh relays

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

0