# BitChat BLE Architecture V3: The Four Layers Explained

> Explore the BitChat BLE architecture V3. Understand its four key layers BLELinkLayer, Mesh Engine, Feature Modules, and App Boundary for robust communication and deterministic testing.

- Repository: [permissionlesstech/bitchat](https://github.com/permissionlesstech/bitchat)
- Tags: architecture
- Published: 2026-08-23

---

**The BitChat V3 Bluetooth Low Energy transport implements four distinct architectural layers—BLELinkLayer, Mesh Engine, Feature Modules, and App Boundary—that enforce strict concurrency contracts and enable deterministic testing without I/O dependencies.**

BitChat is an open-source peer-to-peer messaging protocol designed for permissionless, offline-first communication. The BitChat BLE architecture V3, documented in [`docs/BLE-ARCHITECTURE-V3.md`](https://github.com/permissionlesstech/bitchat/blob/main/docs/BLE-ARCHITECTURE-V3.md), reorganizes the stack into isolated layers that separate CoreBluetooth primitives from mesh protocol logic and application-facing interfaces.

## The Four Layers of the BitChat BLE Stack

The architecture establishes clear boundaries between hardware abstraction, protocol state, feature logic, and application integration. Each layer operates under specific confinement rules that prevent deadlock and enable unit testing.

### 1. BLELinkLayer

The **BLELinkLayer** serves as the sole interface to CoreBluetooth. It owns all scanning and advertising operations, duty-cycle management, connection scheduling, MTU negotiation, and write/notification back-pressure buffers. This layer emits `LinkEvent` instances (link-up/down, bytes-in, writable state changes) and consumes `LinkCommand` directives (send bytes, adjust scan/advertise policies).

Critically, no packet parsing, peer management, or Noise protocol logic exists here. The layer is **Ble-queue confined**, meaning it is the only component in the codebase that imports CoreBluetooth, ensuring that all hardware interactions remain isolated from business logic.

### 2. Mesh Engine

The **Mesh Engine** functions as the serial-queue-confined core of the mesh protocol. It manages the wire codec, packet fragmentation, deduplication, relay policy, peer registry, topology maintenance, gossip synchronization, and Noise handshake orchestration. 

All state mutations occur on a single serial engine queue through a deterministic `handle(event:now:) -> [Effect]` function signature. This design renders the engine pure-logic and fully testable without I/O dependencies, as defined in [`BLEEngineCore.swift`](https://github.com/permissionlesstech/bitchat/blob/main/BLEEngineCore.swift) and [`BLEEnginePolicy.swift`](https://github.com/permissionlesstech/bitchat/blob/main/BLEEnginePolicy.swift).

### 3. Feature Modules

**Feature Modules** implement individual capabilities such as courier messaging, public boards, pre-keys, private media, file transfer, voice, diagnostics, groups, and verification. Each module maintains its own isolated state and registers for specific message types it handles.

This modular approach means adding new transport capabilities requires implementing a new module rather than modifying the engine. Examples include [`BLEMeshPingTracker.swift`](https://github.com/permissionlesstech/bitchat/blob/main/BLEMeshPingTracker.swift) for latency tracking and [`BLEPrivateMediaSessionStore.swift`](https://github.com/permissionlesstech/bitchat/blob/main/BLEPrivateMediaSessionStore.swift) for encrypted media handling.

### 4. App Boundary

The **App Boundary** provides the thin transport façade that applications consume. It exposes a minimal `Transport` core alongside capability-discovery protocols such as `MeshBridgingTransport` and `PanicResettingTransport`. 

This layer replaces the previous monolithic "god-protocol" design with clean, composable interfaces defined in [`Transport.swift`](https://github.com/permissionlesstech/bitchat/blob/main/Transport.swift) and [`MeshBridgingTransport.swift`](https://github.com/permissionlesstech/bitchat/blob/main/MeshBridgingTransport.swift), isolating the application from BLE internals while allowing runtime transport selection.

## Concurrency Contracts

The BitChat BLE architecture enforces three strict confinement rules that guarantee deadlock-free synchronization:

- **Engine-confined**: Only the mesh engine mutates its internal state on the serial engine queue
- **Ble-queue-confined**: The link layer's buffers and CoreBluetooth objects live exclusively on the BLE queue  
- **Lock-backed stores**: Cross-domain readers access the peer registry, identity stores, and traffic statistics through locks, never blocking either queue

Communication flows unidirectionally from engine to BLE queue, never reversing, which eliminates circular wait conditions.

## Implementation Examples

The following Swift snippets demonstrate typical interactions with each architectural layer.

### BLELinkLayer Command Issuance

```swift
let linkLayer = BLELinkLayer()
linkLayer.sendCommand(.startScanning)

```

This emits a `LinkCommand` that translates to CoreBluetooth operations within the Ble-queue confined context.

### Mesh Engine Event Processing

```swift
engineQueue.async {
    let effects = meshEngine.handle(event: .packetReceived(packet, linkID), now: Date())
    effects.forEach { $0.apply() }
}

```

The `handle(event:now:)` method processes inputs deterministically on the engine queue, returning effects that modify state or trigger I/O.

### Feature Module Registration

```swift
privateMediaModule.register { packet in
    processPrivateMedia(packet)
}

```

Feature modules expose registration APIs that bind message types to isolated handling logic without engine modification.

### App Boundary Transport Usage

```swift
transport.sendMessage(
    payload: .text("Hello world"),
    to: recipient,
    preferredTransport: .bluetoothFirst
)

```

The `Transport` façade selects BLE first with automatic fallback to Nostr, hiding complexity behind the App Boundary interface.

## Key Source Files

The following files implement the four-layer architecture:

| Layer | Source Files | Responsibility |
|-------|--------------|----------------|
| BLELinkLayer | [`BLELinkLayer.swift`](https://github.com/permissionlesstech/bitchat/blob/main/BLELinkLayer.swift) | CoreBluetooth abstraction and queue management |
| Mesh Engine | [`BLEEngineCore.swift`](https://github.com/permissionlesstech/bitchat/blob/main/BLEEngineCore.swift), [`BLEEnginePolicy.swift`](https://github.com/permissionlesstech/bitchat/blob/main/BLEEnginePolicy.swift) | Serial queue execution and protocol policies |
| Feature Modules | [`BLEMeshPingTracker.swift`](https://github.com/permissionlesstech/bitchat/blob/main/BLEMeshPingTracker.swift), [`BLEPrivateMediaSessionStore.swift`](https://github.com/permissionlesstech/bitchat/blob/main/BLEPrivateMediaSessionStore.swift) | Isolated capability implementations |
| App Boundary | [`Transport.swift`](https://github.com/permissionlesstech/bitchat/blob/main/Transport.swift), [`MeshBridgingTransport.swift`](https://github.com/permissionlesstech/bitchat/blob/main/MeshBridgingTransport.swift) | Application-facing interface definitions |

## Summary

- The BitChat BLE architecture V3 separates concerns into four distinct layers: BLELinkLayer, Mesh Engine, Feature Modules, and App Boundary
- **BLELinkLayer** isolates all CoreBluetooth interactions within a Ble-queue confined context
- The **Mesh Engine** provides deterministic, testable protocol logic through a serial queue and pure effect-based state management
- **Feature Modules** enable extensibility without engine modification, each owning isolated state for specific capabilities
- The **App Boundary** exposes minimal, composable interfaces that hide transport complexity from applications
- Strict concurrency contracts prevent deadlocks by enforcing unidirectional data flow and lock-backed cross-domain access

## Frequently Asked Questions

### What is the purpose of separating BLELinkLayer from the Mesh Engine?

BLELinkLayer isolates all hardware-specific CoreBluetooth operations, allowing the Mesh Engine to remain platform-agnostic and fully testable without actual Bluetooth hardware. This separation ensures that protocol bugs can be reproduced and fixed in the engine without involving iOS Bluetooth stack complexity.

### How does the App Boundary differ from previous BitChat transport implementations?

Earlier versions used a monolithic "god-protocol" that exposed all transport capabilities through a single massive interface. The V3 App Boundary replaces this with capability-discovery protocols like `MeshBridgingTransport` and `PanicResettingTransport`, allowing applications to compose only the transport features they need while maintaining binary compatibility.

### Why does the Mesh Engine use an effect-based architecture?

The `handle(event:now:) -> [Effect]` pattern makes the engine deterministic and side-effect free. Because all state changes are returned as effects rather than applied immediately, the engine can be unit tested by asserting on the returned effect collections without executing actual I/O operations or threading code.

### Can Feature Modules communicate directly with BLELinkLayer?

No. Feature Modules operate above the Mesh Engine and communicate through the engine's serial queue. Direct BLELinkLayer access is restricted to the engine, maintaining the concurrency contract that prevents Ble-queue blocking and ensures deadlock-free operation across the stack.