// Case Study · 03 · Flutter App
Off-Grid. Encrypted. Forever.
// The Problem
WhatsApp, Telegram, Signal — all require internet to function. In a disaster, a remote area, or a network outage, communication collapses completely. Emergency responders, trekkers, event coordinators — all face this gap. There was no solution that worked truly off-grid.
Near Chat uses Bluetooth Low Energy and Wi-Fi Direct to create a mesh network between phones in range. Messages hop device-to-device. Every byte is AES-256-GCM encrypted with a fresh per-message nonce. No cell towers. No routers. No servers. Just phones talking directly — and securely.
// Architecture
The entire network is built on Google's Nearby Connections API in P2P_CLUSTER mode. Room discovery uses a SHA-256 hashed Room Code over BLE — peers that don't know the code can't even see the endpoint. Once discovered, a lexicographic tie-breaker resolves simultaneous connection requests and Wi-Fi Direct handles the high-bandwidth socket.
// Features
Google Nearby Connections in cluster mode. BLE for discovery, Wi-Fi Direct for payloads. Extends mesh range with every new node in range.
Every message encrypted end-to-end. Keys derived via PBKDF2 with HMAC-SHA256 at 100,000 iterations from the Room Code. Zero key exchange over the air.
BLE scanning finds nearby Near Chat devices in under 1 second. SHA-256 hashed room codes prevent passive discovery of active rooms.
Skip manual code entry. Display your Room QR or scan a peer's using the integrated camera scanner. Session formed in under a second.
Record, encrypt (AES-256), and transmit M4A voice notes over Wi-Fi Direct. Custom waveform player with playback progress and duration tracker.
WhatsApp-style double-tick system. Grey clock → single tick (sent) → double tick (delivered). Silent receipt frames auto-sent on message decryption.
Real-time typing status broadcast across the mesh. 2-second debounce to minimize traffic, 5-second auto-clear timeout on inactivity.
Messages queued locally when peers disconnect. Auto-flushes in order on reconnection. Mesh-wide pending queue for zero-peer states.
Custom WAV beep generator for sent/received tones. Haptic feedback on message delivery, reactions, and button taps via HapticFeedback API.
// Tech Stack
This wasn't a tutorial project. Every component required reading Android and Flutter low-level documentation, understanding the hardware BLE/Wi-Fi layer, and resolving platform-specific quirks on MIUI/Android 12.
// Engineering Decisions
Near Chat could have been native Kotlin. But the Flutter Nearby Connections plugin wraps Google's Nearby API cleanly, and Dart's async/await model is perfect for event-driven mesh networking. An iOS port becomes possible later without a full rewrite.
CBC mode has no authentication — a man-in-the-middle on the local BLE radio can flip bits without detection. GCM provides both confidentiality and integrity in one primitive, and forces a unique nonce per message so identical plaintexts produce different ciphertexts.
Early builds padded the Room Code to 32 bytes with zeros — effectively a 4-character password with zero hashing cost. PBKDF2 with 100,000 iterations and a static salt makes brute-force enumeration of short codes computationally expensive.
The original design broadcast userName|roomCode in plaintext over BLE. Anyone with a BLE scanner could read active Room Codes. Broadcasting SHA256(roomCode + serviceId) instead means only devices that already know the code can recognize the match.
The mesh state — nodes discovered, connections active, messages in-flight, typing statuses, offline queues — is highly reactive. Riverpod's stream providers map naturally to the event stream from the Nearby Connections API without setState spaghetti.
// Lessons learned
Flutter Nearby Connections handled the heavy BLE/Wi-Fi Direct complexity. The abstraction let us focus on the mesh routing logic rather than raw hardware quirks.
Android permission hell — BLE scanning requires FINE_LOCATION, BLUETOOTH_SCAN, BLUETOOTH_CONNECT, BLUETOOTH_ADVERTISE — all changed in Android 12/13. MIUI adds a layer of unpredictability on top.
Proper cryptography from day one. Designing PBKDF2 + AES-GCM into the protocol early meant we never had to retrofit security, which would have required a full architecture rethink.
STATUS_ENDPOINT_IO_ERROR (8012) — when two devices call requestConnection() simultaneously, Google Play Services throws a race condition error. Lexicographic tie-breaker logic solved it completely.
Near Chat proves the most. Shipping it demonstrates low-level networking knowledge, security engineering, and the ability to build complex distributed systems — not just CRUD apps.
Message hop routing and multi-hop relaying. Right now each device connects directly. A proper relay protocol would let messages hop through intermediate nodes, extending the real mesh range.
No internet · No SIM · No servers · Just phones