SafeMesh — When the Network Goes Dark, We Don't
Inspiration
Communication is something most of us take for granted — until it's gone.
One of our team members grew up in Kashmir, where blackouts aren't rare edge cases. They're a lived reality. Power cuts, network shutdowns, and infrastructure failures have left entire communities isolated for days at a time — unable to call for help, unable to reach family, unable to know if the person two streets over is safe. You don't forget what that silence feels like.
More recently, events in the UAE brought this fear closer to home for others on our team. When infrastructure is disrupted — whether by natural disaster, political instability, or simply a downed tower — the first thing that fails is the very tool you need most: your phone's ability to connect to other people.
The statistics are sobering. In the United States alone, there are over 3,200 power outages per year, and the number is rising. During Hurricane Katrina, 90% of cell towers in the affected area went offline. During the 2023 Turkey-Syria earthquake, survivors waited hours — sometimes days — before rescuers could locate them, partly because no one could transmit their position.
We asked ourselves a simple question: what if the phone in your pocket didn't need a tower at all?
What We Built
SafeMesh turns every iPhone into a node in a peer-to-peer mesh network. Messages travel from device to device over Bluetooth and WiFi Direct — no towers, no internet, no infrastructure required. A message sent on one phone hops across every device in range until it reaches its destination, even if the sender and recipient are miles apart with no direct connection between them.
The core relay model follows a store-and-forward pattern. Each message carries a TTL (time-to-live) counter that decrements at every hop:
$$TTL_{n+1} = TTL_n - 1, \quad \text{relay if } TTL_{n+1} > 0$$
For a standard message with $TTL_0 = 5$, the theoretical maximum reach across a chain of devices is:
$$\text{Max Hops} = TTL_0 = 5 \quad \Rightarrow \quad \text{Range} \approx 5 \times 100\text{ft} = 500\text{ft}$$
SOS alerts are treated as priority packets with $TTL_0 = 10$, effectively doubling their propagation range through the mesh.
Deduplication ensures messages never loop infinitely. Every packet carries a UUID, and each device maintains a seen-ID set:
$$\text{relay}(p) = \begin{cases} \text{forward} & \text{if } p.\text{id} \notin \text{seenIDs} \ \text{discard} & \text{if } p.\text{id} \in \text{seenIDs} \end{cases}$$
How We Built It
We built SafeMesh entirely in Swift and SwiftUI, using Apple's native MultipeerConnectivity framework as the networking backbone. The decision to use zero third-party dependencies was deliberate — in a disaster scenario, you need software that has no external points of failure.
The architecture is straightforward:
- MeshManager handles all peer discovery, session management, packet encoding/decoding, relay logic, and deduplication
- LocationManager wraps CoreLocation for GPS coordinates embedded in SOS alerts
- SwiftUI views subscribe to MeshManager via
@Publishedproperties andObservableObject, keeping the UI reactive to mesh state changes in real time
The message model uses a tagged enum (MeshPacket) to unify all packet types — chat messages, SOS alerts, location pings, typing indicators, delivery acknowledgements, and resource broadcasts — into a single codable type that flows through the same relay pipeline regardless of content.
We also built a Resources tab that allows authorities or volunteers to broadcast shelter locations, water stations, medical aid points, and evacuation routes across the mesh. These broadcasts relay hop-by-hop just like messages, turning SafeMesh from a chat tool into a full emergency information lifeline.
Challenges We Faced
The reconnection bug was the hardest problem we solved. MultipeerConnectivity's MCSession enters a broken state after a peer disconnects — and reusing that session silently fails to reconnect. The fix required creating a completely fresh session on every reconnection cycle rather than attempting to reuse the existing one. Once we understood that the session itself was the corrupted object, the fix was clean.
iOS background behavior was a constant battle. Apple aggressively throttles Bluetooth scanning when an app is backgrounded, which kills the mesh the moment someone locks their screen. We mitigated this by implementing app lifecycle observers that restart the mesh when the app foregrounds, and a periodic discovery cycle that kicks in when no peers are found.
Cross-platform mesh is genuinely unsolved. Apple's MultipeerConnectivity and Google's Nearby Connections API are incompatible protocols — an iPhone and an Android phone cannot mesh directly. This is a real limitation of the current implementation and an open research problem in peer-to-peer networking.
Testing without infrastructure is harder than it sounds. You cannot test Bluetooth mesh on a simulator. Every iteration required physical iPhones, physical distance, and physical people — which made debugging slow and sometimes unpredictable.
What We Learned
We learned that the hardest part of building resilient systems isn't the technology — it's the assumptions baked into every layer of modern software. Almost every framework, every API, every service we reach for assumes a working internet connection. Building something that genuinely doesn't need one requires questioning those assumptions at every step.
We also learned that the people who need tools like this most are rarely the people building software. The communities most affected by blackouts, network shutdowns, and infrastructure failures are the ones least likely to have someone in the room advocating for them. That felt important to remember.
What's Next
- End-to-end encryption for all mesh packets
- Android support via a parallel implementation using Google's Nearby Connections API
- Background mesh relay that survives a locked screen
- Pre-cached offline map tiles so the map works without ever having connected to the internet
- A low-literacy icon-based SOS mode for global usability
Built at CheeseHacks. No servers were harmed in the making of this project.
Built With
- audiotoolbox-?-fully-offline
- bluetooth
- core-location
- mapkit
- multipeerconnectivity
- swift
- swiftui
- wifi
- zero-cloud-services
- zero-third-party-dependencies
Log in or sign up for Devpost to join the conversation.