Peer-to-peer Bluetooth mesh file sharing for thru-hikers — no internet required.
TrailMesh turns your phone into a trail-ready drop box. Drop a photo, a contact card, or a document into the shared folder, and nearby hikers can pull it over Bluetooth Low Energy (BLE). No cell signal, no Wi-Fi, no cloud, no browsing — just share.
On long-distance trails (PCT, AT, CDT), cell service is rare. Hikers still want to exchange photos, contact info, and trail documents with the people they meet. AirDrop requires proximity and iOS-to-iOS. TrailMesh works across platforms over BLE and treats every device as a node in a mesh.
- Drop-box sharing — Drop files into a public folder; nearby nodes can pull them
- BLE mesh — Files hop across intermediate nodes to reach devices beyond direct range
- Signal strength — Real-time RSSI display per connected node
- Transfer speed — Live throughput meter during file transfers
- Node list — See all visible mesh nodes and their hop distance
- No browsing — You can only pull files from the shared folder, not explore anyone's device
- Cross-platform — iOS (Swift + CoreBluetooth) and Android (Kotlin + BLE) from day one
- Offline — Zero internet dependency; everything runs over BLE
- AES-256-GCM encryption — File contents encrypted in transit via ECDH key exchange
- Transfer approval gate — Manually approve/deny each file request from peers
- Signed manifests — Ed25519 signatures verify file provenance and detect tampering
- Node blocklist/allowlist — Restrict which devices can connect to your node
- Auto-expire shared files — Configurable TTL (1h–3d) removes old shared files
- Receive size limits — Reject oversized files before transfer starts
- Encrypted storage at rest — Downloaded files encrypted on disk
- Rate limiting — 5 requests/minute per node prevents flood attacks
- Manifest integrity hash — SHA-256 tamper detection on all manifests
- Secure cancellation — Partial downloads wiped from memory and disk
- Adaptive chunk sizing — Chunk size, window size, and interval auto-adjust based on RSSI + packet loss
- Link quality monitor — 5 quality levels (Excellent→Critical) with real-time parameter recomputation
- File compression — Text-based files (vCard, PDF, txt) compressed with zlib before transfer
- Sliding window — Multiple chunks in-flight (up to 8 on excellent links) for higher throughput
- Per-chunk ACK/NACK — Selective retransmission only lost chunks, not the whole file
- Forward Error Correction — XOR parity chunks on poor links to recover lost data without retransmit
- Incremental disk writes — Chunks saved to disk as they arrive (not held in memory)
- Checkpoint persistence — Received-chunk bitmap persisted to disk after every chunk
- Resume on reconnect — On BLE reconnect, receiver tells sender which chunks it already has
- App restart recovery — Transfer state survives app kills; resume on next launch
- Trail-readable text — Dynamic Type with large, high-contrast fonts for outdoor use
- Color-coded transfer speed — Green (fast), yellow (moderate), red (slow)
- Battery saver mode — Reduces scan frequency and transfer speed for long trail days
- Image thumbnails — Photo previews in file lists
- Transfer history — Timestamps, duration, and source node for completed transfers
- VoiceOver accessibility — Full accessibility labels on all UI elements
- Category badges — Color-coded file type badges (Photos/Contacts/Documents)
- Connection quality badges — Visual quality indicator on each node row
- Storage usage indicator — Shows how much shared storage is in use
- Improved empty states — Helpful guidance when lists are empty
cd ios
# Open in Xcode (or use XcodeGen)
xcodegen generate
open TrailMesh.xcodeprojRequirements: Xcode 15+, iOS 17+, iPhone with Bluetooth.
cd android
# Open in Android Studio
studio .Requirements: Android Studio Hedgehog+, Android 10+ (API 29), Bluetooth + Location permissions.
- Discovery — Each device advertises a BLE service with its node ID
- Connection — Devices connect as peers (no central server)
- File drop — You add a file to your shared folder; it's advertised in your file manifest
- File pull — A connected peer requests a file from your manifest; you stream it over BLE characteristics
- Mesh relay — If node A wants a file from node C but only B can see C, B relays the transfer
See docs/ARCHITECTURE.md for the full design and docs/PROTOCOL.md for the BLE protocol specification.
- No browsing — Peers can only see file names + sizes in your shared folder, nothing else on your device
- Share-only — Files must be explicitly added to the shared folder; nothing is auto-shared
- No internet — No data leaves the BLE mesh
- No authentication — By design; trail mesh is an open, trust-based network. Don't share sensitive files.
See docs/SECURITY.md for the full security model.
trailmesh/
├── ios/ # iOS app (Swift + CoreBluetooth + SwiftUI)
│ └── TrailMesh/
│ ├── Models/ # MeshNode, SharedFile, TransferMetrics
│ ├── BLE/ # BLEManager, FileTransferService, BLEProtocol
│ ├── Security/ # SecurityManager, TransferApprovalManager, FileSecurityManager
│ ├── Transfer/ # AdaptiveTransferEngine, CompressionAndFEC, ResumableTransferManager
│ ├── Views/ # ContentView, DropZone, Network, SharedFiles, Transfers, Settings
│ └── Utils/ # UIHelpers (Dynamic Type, badges, thumbnails, empty states)
├── android/ # Android app (Kotlin + BLE)
│ └── app/src/main/java/com/trailmesh/
│ ├── ble/ # BLEManager, FileTransferService
│ ├── models/ # MeshNode, SharedFile
│ └── ui/ # Compose UI
├── shared/ # Platform-agnostic protocol spec
│ └── protocol-spec.json
├── docs/ # Architecture, protocol, security
│ ├── ARCHITECTURE.md
│ ├── PROTOCOL.md
│ └── SECURITY.md
└── README.md
MIT — see LICENSE.