Skip to content

trancee/MeshLink-old

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

555 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MeshLink

A Kotlin Multiplatform (KMP) BLE mesh messaging library for Android, iOS, macOS, Linux, and JVM. MeshLink enables secure, multi-hop peer-to-peer communication over Bluetooth Low Energy with ~85% shared code across platforms.

Features

  • Multi-hop mesh routing — Babel-based routing (RFC 8966 adapted for BLE) with proactive route propagation, composite cost metrics, and loop-free convergence
  • Two-layer encryption — Hop-by-hop (Noise XX) and end-to-end (Noise K) using Noise_XX_25519_ChaChaPoly_SHA256
  • Zero external crypto dependencies — Pure Kotlin Ed25519/X25519, platform-native SHA-256 and ChaCha20-Poly1305
  • Large message transfer — Chunking, selective ACKs (SACK), AIMD congestion control, byte-offset resume
  • Power-aware operation — Automatic tuning of scan duty cycle, advertising interval, and chunk sizes based on battery level
  • L2CAP support — High-throughput data plane with automatic GATT fallback
  • Real-time diagnostics — 22 diagnostic event codes, health snapshots, and Flow-based event streams
  • Identity rotation — Rotate keys with signed broadcast announcements and configurable grace periods

How It Works

flowchart LR
    subgraph Sender["Sender Device"]
        App1["App"] --> ML1["MeshLink"]
    end

    subgraph Relay["Relay Peer"]
        ML2["MeshLink\nDecrypt hop → Re-encrypt hop\nE2E payload stays sealed"]
    end

    subgraph Recipient["Recipient Device"]
        ML3["MeshLink"] --> App2["App"]
    end

    ML1 -->|"Noise XX\nhop-by-hop"| ML2
    ML2 -->|"Noise XX\nhop-by-hop"| ML3
    ML1 -.->|"Noise K\nend-to-end sealed payload"| ML3

    style Sender fill:#e8f5e9,stroke:#388e3c
    style Relay fill:#fff3e0,stroke:#f57c00
    style Recipient fill:#e3f2fd,stroke:#1976d2
Loading

Messages are encrypted twice: Noise K seals the payload end-to-end (only the recipient can read it), while Noise XX encrypts each BLE hop independently. Relay peers forward opaque ciphertext — they never see plaintext. Routes are discovered automatically via Babel (RFC 8966). See Design and Diagrams for full details.

Platform Support

Target Min Version Details
Android API 26 Pure Kotlin crypto (API 26–32), JCA (API 33+)
iOS arm64, simulatorArm64 CoreBluetooth, Keychain
macOS arm64 CoreBluetooth, Keychain
Linux arm64, x64 Raw HCI/L2CAP sockets via BlueZ kernel API
JVM Java 21 Java native JCA crypto

Tech Stack

Category Technology Version
Language Kotlin (Multiplatform) 2.3.20
Build System Gradle (Kotlin DSL) 9.4.1
JVM Java (Zulu recommended) 21
Android Android Gradle Plugin 9.1.1
compileSdk / minSdk 36 / 26
Apple Xcode / Swift (CryptoKit bridge) 15+
Linux BlueZ (HCI/L2CAP/D-Bus) kernel API
Concurrency kotlinx-coroutines 1.10.2
Encryption Noise XX (hop-by-hop) + Noise K (end-to-end) 25519_ChaChaPoly_SHA256
Crypto primitives Pure-Kotlin Ed25519/X25519, platform-native SHA-256 & ChaCha20-Poly1305
Compression Raw DEFLATE (RFC 1951)
Wire format Custom binary protocol (TLV-extensible)
Linting detekt 1.23.8
Testing kotlin.test + Power Assert plugin
UI tests Maestro
iOS/macOS distribution XCFramework via Swift Package Manager
Publishing Maven Central (Sonatype)

Quick Start

val mesh = MeshLink(
    transport = bleTransport,
    config = meshLinkConfig { maxMessageSize = 50_000 },
    crypto = CryptoProvider(),
    cryptoDispatcher = Dispatchers.Default, // offload crypto to background threads
)
mesh.start()

See the Integration Guide for complete setup, configuration presets, and platform-specific examples.

Configuration Presets

MeshLink ships with four presets — smallPayloadLowLatency, largePayloadHighThroughput, minimalResourceUsage, and minimalOverhead — see the API Reference for details.

Security

MeshLink uses two-layer Noise protocol encryption — Noise XX (Noise_XX_25519_ChaChaPoly_SHA256) for hop-by-hop confidentiality between neighbors and Noise K (Noise_K_25519_ChaChaPoly_SHA256) for end-to-end authentication between sender and recipient. Identity is Ed25519 with TOFU (Trust-On-First-Discover) key pinning. See the Threat Model and Integration Guide § Encryption & Trust for details.

Project Structure

MeshLink/
├── meshlink/                    # Core KMP library
│   └── src/
│       ├── commonMain/          # ~85% shared code
│       ├── appleMain/           # Shared Apple (CoreBluetooth, Keychain)
│       ├── iosMain/             # iOS-specific (UIKit battery)
│       ├── macosMain/           # macOS-specific (battery stub)
│       ├── linuxMain/           # Linux-specific (POSIX time, battery stub)
│       ├── androidMain/         # Android BLE, storage, services
│       ├── jvmMain/             # JVM crypto provider
│       └── commonTest/          # 1,500+ tests
├── meshlink-sample/
│   ├── android/                 # Jetpack Compose reference app
│   ├── ios/                     # SwiftUI reference app
│   ├── macos/                   # SwiftUI macOS reference app
│   ├── jvm/                     # JVM console app
│   └── linux/                   # Linux console app (arm64, x64)
├── docs/                        # Architecture, API, wire format spec
├── Package.swift                # SPM manifest (iOS + macOS)
└── UBIQUITOUS_LANGUAGE.md       # Domain glossary

Documentation

Tutorial · Integration Guide · How to Monitor · Best Practices · Design · Wire Format Spec · API Reference · Threat Model · Diagrams

Building

Prerequisites

  • Java 21 (e.g., Zulu, Temurin)
  • Gradle 9.4+ (wrapper included)
  • Android SDK with compileSdk 36 (for Android target)
  • Xcode 15+ (for iOS/macOS targets, macOS only)

Library

# Run all JVM tests
./gradlew :meshlink:jvmTest

# Run integration tests only (50+ end-to-end scenarios)
./gradlew :meshlink:jvmTest --tests "io.meshlink.MeshIntegrationTest" --parallel

# Compile Android AAR
./gradlew :meshlink:compileAndroidMain

# Run iOS simulator tests (requires macOS + Xcode)
./gradlew :meshlink:iosSimulatorArm64Test

# Run macOS tests
./gradlew :meshlink:macosArm64Test

# Compile Linux targets (cross-compiles from macOS)
./gradlew :meshlink:compileKotlinLinuxX64
./gradlew :meshlink:compileKotlinLinuxArm64

# Build XCFramework for Swift Package Manager (iOS + macOS)
./gradlew :meshlink:assembleMeshLinkXCFramework

Sample Apps

JVM (console)

./gradlew :meshlink-sample:jvm:run

Android (Jetpack Compose)

With Android Studio:

  1. Open the root MeshLink/ directory in Android Studio (File → Open)
  2. Wait for Gradle sync to complete
  3. In the Run Configurations dropdown, select meshlink-sample.android
  4. Select a device or emulator (API 26+)
  5. Click ▶ Run
  6. Grant Bluetooth and Location permissions when prompted

Tip: If the run configuration doesn't appear, go to Run → Edit Configurations → + → Android App, set module to MeshLink.meshlink-sample.android.main and launch activity to io.meshlink.sample.MainActivity.

From the command line:

# Build debug APK
./gradlew :meshlink-sample:android:assembleDebug

# APK location:
# meshlink-sample/android/build/outputs/apk/debug/android-debug.apk

# Install on connected device
adb install meshlink-sample/android/build/outputs/apk/debug/android-debug.apk

The app has four screens: Chat (start/stop mesh, send messages), Mesh Visualizer (peer topology graph), Diagnostics (filterable event log), and Settings (config presets, MTU).

The sample uses the real AndroidBleTransport — it will advertise, scan, and connect to other MeshLink devices over BLE. Runtime permissions (Bluetooth Scan/Connect/Advertise + Location) are requested on launch.

UI Tests (Maestro)

Both the Android and iOS sample apps include Maestro UI automation flows covering navigation, lifecycle, messaging, settings, and diagnostics (10 flows each).

# Android (emulator or device required)
maestro test maestro/flows/android/

# iOS (Simulator required)
maestro --platform=ios test maestro/flows/ios/

# Smoke tests only
maestro test maestro/flows/android/ --include-tags=smoke

See maestro/flows/ for the full flow listing and shared subflows. Install Maestro CLI with curl -fsSL "https://get.maestro.mobile.dev" | bash.

iOS (SwiftUI)

./gradlew :meshlink:assembleMeshLinkXCFramework
open meshlink-sample/ios/MeshLinkSample.xcodeproj

Build the XCFramework, open the pre-configured Xcode project, and hit ⌘R. See meshlink-sample/ios/README.md for details.

macOS (SwiftUI)

./gradlew :meshlink:assembleMeshLinkXCFramework
open meshlink-sample/macos/MeshLinkSample.xcodeproj

Build the XCFramework, open the pre-configured Xcode project, and hit ⌘R. See meshlink-sample/macos/README.md for details.

Linux (console, native)

# Cross-compile from macOS
./gradlew :meshlink-sample:linux:linkReleaseExecutableLinuxX64
./gradlew :meshlink-sample:linux:linkReleaseExecutableLinuxArm64

# Executable locations:
# meshlink-sample/linux/build/bin/linuxX64/releaseExecutable/linux.kexe
# meshlink-sample/linux/build/bin/linuxArm64/releaseExecutable/linux.kexe

# Copy to target Linux machine and run:
# ./linux.kexe

To use real BLE hardware on Linux, edit Main.kt to use LinuxBleTransport instead of DemoTransport. Requires CAP_NET_RAW or root.

CI

GitHub Actions runs on every push and PR (when relevant files change):

  • JVM tests (Ubuntu)
  • Android compilation (Ubuntu)
  • iOS simulator tests (macOS, Apple Silicon)
  • macOS native tests (macOS, Apple Silicon)
  • Linux native compilation (Ubuntu)

License

Unlicense — Public domain.

About

MeshLink is a **library-first SDK** that enables developers to embed encrypted, serverless, offline-capable messaging into their Android and iOS apps. Communication happens entirely over BLE mesh — no internet, no servers, no accounts.

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors