End-to-end encrypted messaging plus voice and video calls while you're online. When networks collapse, the same app keeps sending messages, voice notes, and location to nearby phones over Bluetooth —
SocialKotlin · SwiftGitHub @emirhan-dumanOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Loading comments.
Checking sign-in status.
Offline-first disaster communication platform. End-to-end encrypted messaging, voice and video calls, and rescue coordination — over Bluetooth with zero infrastructure, and over the internet when a network is reachable. Available on Google Play and App Store.
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
When networks fail, we connect.
Open-source, offline-first communication platform for disaster response.
End-to-end encrypted messaging, voice and video calls, and rescue coordination.
The Bluetooth layer needs no infrastructure at all. When a network is reachable,
an end-to-end encrypted internet layer extends the same conversation.Read the full README ↗When disaster strikes, communication infrastructure is the first thing to fail. Cell towers collapse. Power grids go offline. Internet becomes unreachable. The very tools people depend on for coordination -- messaging apps, phone calls, maps -- stop working at the exact moment they are needed most.
This is not a hypothetical scenario. After the 2023 earthquakes in Turkey and Syria, cellular networks were down for days across entire provinces. During Hurricane Maria in Puerto Rico, 95% of cell sites were knocked out. In the 2011 Japan earthquake and tsunami, millions lost all connectivity.
Every major disaster exposes the same gap: there is no widely available communication tool designed to keep working when infrastructure does not.
Existing solutions either require specialized radio hardware (walkie-talkies, satellite phones) that most people don't carry, or depend on mesh networking protocols that still assume some form of internet backhaul.
Crisis Connect was built to close that gap. A communication tool that runs on the phone already in your pocket, works over Bluetooth with zero infrastructure dependency, and encrypts everything end-to-end by default.
Crisis Connect is offline-first: the Bluetooth stack is the foundation, and everything else is layered on top of it. Devices talk directly to each other using the Bluetooth hardware already present in every modern smartphone -- no cell tower, no router, no server.
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Device A │◄──BLE──►│ Device B │◄──BLE──►│ Device C │
└──────────┘ └──────────┘ └──────────┘
│ │ │
│ QR Key Exchange │ GATT Mesh Relay │
│ ECDH + AES-256 │ Multi-hop Forward │
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────┐
│ All messages E2E encrypted │
│ Stored only on sender & receiver │
│ No server ever sees plaintext │
└─────────────────────────────────────────────────────┘
The offline stack operates across three layers:
Discovery -- BLE advertising and scanning find nearby devices automatically. No pairing menu, no Bluetooth settings. The app handles everything.
Secure Channel -- Before any communication, devices exchange cryptographic keys through QR code scanning or a SPAKE2 short-code pairing session. This creates a verified, encrypted channel between two specific devices.
Communication -- Messages, voice, images, and files flow through this encrypted channel. If the recipient is not in direct range, the GATT mesh protocol relays data through intermediate devices -- each hop maintaining end-to-end encryption.
When a network is reachable, the same contacts, the same conversations and the same identity carry over to an internet transport that is also end-to-end encrypted -- using the Signal Protocol -- and that adds long-range voice and video calls, attachments and push notifications. The two transports are interchangeable per contact: a chat that started over Bluetooth continues over the internet and vice versa, and messages queue and drain on whichever link comes back first.
Neither layer depends on the other. The app is fully functional in airplane mode with Bluetooth enabled.
Everything in this table works with zero internet connectivity. Messages are stored locally on-device and never pass through any server.
| Feature | Description | Transport |
|---|---|---|
| Text Messaging | End-to-end encrypted text messages with read receipts and timestamps | BLE GATT / RFCOMM |
| Voice Calls | Real-time Opus-encoded voice calls, working cross-platform between Android and iOS | GATT audio link (0xCD00) / RFCOMM |
| Voice Messages | Record, send, and play back voice messages with waveform visualization | BLE GATT (chunked) |
| Image Transfer | Send photos with automatic compression, chunked transfer, and progress tracking | BLE GATT (chunked) |
| File Transfer | Share documents, offline map bundles and files with delivery receipts | BLE GATT (chunked) |
| Mesh Relay | Messages hop through intermediate devices when sender and receiver aren't in direct range | GATT mesh protocol |
| QR Pairing | Scan a QR code to add a contact and establish an encrypted channel | Camera + ECDH |
| Nearby Pairing | Add a nearby contact by short code without exposing a harvestable identifier | SPAKE2 (RFC 9382) over BLE |
| SOS Broadcast | Emergency broadcast visible to all nearby devices running Crisis Connect, surviving a background kill | BLE advertising |
| Agency Bridge | Field responders relay agency channel messages, media and calls to nearby offline devices | BLE bridge |
When connectivity exists, Crisis Connect adds a second transport. It is end-to-end encrypted with the Signal Protocol and carries the same conversations as the Bluetooth layer.
| Feature | Description |
|---|---|
| E2E Internet Messaging | Signal Protocol sessions (libsignal, PQXDH) with forward secrecy, per-message ratcheting and anti-downgrade pinning |
| Voice & Video Calls | 1:1 WebRTC calls with native call UI (CallKit on iOS, Telecom on Android), lock-screen ringing and PushKit/FCM wake-up |
| Screen Sharing | Full-device screen share during a call, via a ReplayKit broadcast extension on iOS |
| Attachments | Encrypted images, documents and voice notes, byte-compatible across Android, iOS and the web dashboard |
| Contact Discovery | Opt-in, phone-number-based discovery gated behind phone verification, with safety numbers and TOFU identity-change warnings |
| Agency Channels | Responder-to-agency and cross-agency ("hierarchy") conversations with roles, receipts and deep-linked notifications |
| Store & Forward | Undelivered messages queue on-device and drain automatically when either transport comes back |
An in-app assistant for disaster scenarios, built to work without a network:
Crisis Connect includes a dedicated rescue module designed for emergency response teams (AFAD, Red Cross, field teams):
Role-Based Access Control -- Rescue team members are assigned admin or fieldteam roles through Firebase custom claims. Roles are cryptographically verified even when offline through ECDSA-signed role certificates.
Role Certificates -- When a rescue device is online, it requests a signed certificate from Firebase Cloud Functions. This certificate (ECDSA P-256, 72-hour TTL) can be verified by any other device offline, proving the holder's rescue team identity without needing to contact a server. Certificates renew in the background and are checked against a server-side revocation list when online.
Victim ↔ Field Team Link -- Live rescuer-to-victim voice calls, medical information hand-off, a remote signal feed and sightings that survive going offline.
Live Location Sharing -- Rescue devices share real-time GPS coordinates during active operations, with configurable update intervals and battery-aware policies.
CrisisLink Sync -- A background sync engine that maintains rescue session state across all team devices, handling merge conflicts and offline queue reconciliation.
Agency Routing -- Firestore security rules scope data access by agency, ensuring that different rescue organizations see only their own operational data.
Dynamic Feature Module -- On Android, rescue features are delivered as a dynamic feature module through Play Feature Delivery, keeping the base app lightweight for civilian users.
Beyond communication, the app includes tools designed for disaster scenarios:
| Tool | Description | Platform |
|---|---|---|
| Offline Maps | Download map regions for offline use. Navigate without internet using MapLibre vector tiles. | Android + iOS |
| Compass | Sensor-fused directional compass with heading, pitch, and roll readings. | Android + iOS |
| Signal Finder | Scans for cellular, Wi-Fi, and Bluetooth signals in the area. Helps locate zones with potential connectivity. | Android + iOS |
| Metal Detector | Uses the device magnetometer to detect metallic objects. Visual and audio feedback with adjustable sensitivity. | Android + iOS |
| Emergency Whistle | High-volume acoustic signals with Siren Sweep and Rescue modes at configurable frequencies. | Android + iOS |
| Sensor Dashboard | Real-time readouts from all device sensors: accelerometer, gyroscope, magnetometer, barometer, ambient light. | Android + iOS |
| Survival Guide | Step-by-step emergency checklists for earthquakes, floods, fires, and other scenarios. Available offline. | Android + iOS |
| LiDAR Scanner | Uses LiDAR depth sensor for obstacle awareness in dark, smoky, or low-visibility environments. | iOS (LiDAR devices) |
| Night Vision | Camera-assisted obstacle detection for low-light conditions using LiDAR point cloud. | iOS (LiDAR devices) |
Reaching SOS should never require unlocking the phone and hunting for an app icon.
| Integration | Android | iOS |
|---|---|---|
| SOS widget | Home-screen widget with live SOS status | WidgetKit SOS widget |
| Recent disasters widget | Home-screen widget with a background refresh worker | WidgetKit widget |
| One-tap SOS | Quick Settings tile -- from the shade straight into the SOS countdown | iOS 18 Control Center control, lock screen, Action Button |
| Live status | Ongoing notification during an active broadcast | SOS Live Activity |
SOS arms with a 5-second countdown before it broadcasts, so an accidental tap does not declare an emergency.
Security is not a feature layer added on top -- it is foundational to the architecture. Every design decision assumes an adversarial environment where devices may be compromised, networks may be monitored, and identities may be spoofed.
All offline messages are encrypted with AES-256-GCM before leaving the sending device. The key is derived from the ECDH shared secret established during pairing.
| Platform | Encryption Library | Algorithm |
|---|---|---|
| Android | Google Tink | AES-256-GCM |
| iOS | Apple CryptoKit | AES-256-GCM |
Messages are encrypted before entering the BLE transport layer. Even if Bluetooth traffic is intercepted, the attacker sees only ciphertext. The GATT mesh relay nodes forward encrypted payloads without being able to read them.
Internet messaging runs the Signal Protocol through libsignal -- the same library Signal ships -- on both platforms:
AGREE_KEY / iOS Keychain)The relay server stores only ciphertext, and expired envelopes are purged server-side.
Two offline paths establish a verified channel:
QR pairing uses Elliptic-Curve Diffie-Hellman (ECDH) over the P-256 curve:
Nearby pairing uses SPAKE2 (RFC 9382) over P-256: a password-authenticated key exchange driven by a short code, so a device never advertises a harvestable phone number or identifier in order to be addable.
Both happen entirely offline. No certificate authority, no key server, no internet connection.
For rescue team identity verification, Crisis Connect uses a custom certificate chain:
Firebase Cloud Functions (trusted signer)
│
│── Signs certificate with ECDSA P-256
│ using server-held private key
│
▼
┌─────────────────────────────────────────┐
│ Role Certificate │
├─────────────────────────────────────────┤
│ Owner UID │
│ Role (admin / fieldteam) │
│ Public Key (Base64) │
│ Issued At (timestamp) │
│ Expires At (issued + 72 hours) │
│ ECDSA Signature (DER-encoded) │
│ Algorithm: SHA256withECDSA │
│ Curve: P-256 │
└─────────────────────────────────────────┘
Any device can verify a role certificate offline using the embedded public key of the signing authority. This allows rescue teams to prove their identity to civilian devices without internet connectivity. Issuance is gated behind platform attestation (Play Integrity on Android, App Attest on iOS).
| Data | Android | iOS |
|---|---|---|
| Messages | SQLCipher encrypted Room database | Keychain-backed local storage |
| Signal sessions | Room, inside the SQLCipher database | Keychain-backed store |
| Credentials | Android Keystore (hardware-backed) | iOS Keychain (Secure Enclave) |
| Preferences | EncryptedSharedPreferences | Keychain-backed preferences |
| Media blobs | Encrypted on-device cache for offline viewing | Encrypted on-device cache |
P2P messages are stored only on the two communicating devices. Internet messages transit the relay as ciphertext and are deleted after delivery. Deleting the app removes all local messages and keys permanently.
When internet is available, all Firebase API calls are protected by:
Being explicit about the boundaries matters more than a marketing claim:
Crisis-Connect/
│
├── Android/ Kotlin · Jetpack Compose · Material 3
│ ├── app/ Main application module
│ │ ├── src/main/java/.../
│ │ │ ├── ai/ Crisis Sentinel offline + online engines
│ │ │ ├── core/ Crypto primitives, chunking, media processing
│ │ │ ├── data/ Room DB, Signal stores, Firestore repos, offline maps
│ │ │ ├── messaging/ Internet transport, Signal sessions, relay, receipts
│ │ │ ├── navigation/ Compose navigation, deep links, route resolution
│ │ │ ├── nearby/ SPAKE2 pairing sessions, nearby discovery
│ │ │ ├── screens/ UI: Chat, Tools, Settings, QR, SOS, Guide, Profile
│ │ │ ├── security/ ECDSA certs, role proofs, keystore, crypto helpers
│ │ │ ├── service/ BLE GATT server/client, RFCOMM, mesh, voice, files
│ │ │ ├── telecom/ Android Telecom integration for call management
│ │ │ ├── ui/ Theme, design system, shared components
│ │ │ └── widget/ Home-screen SOS + Recent Disasters widgets
│ │ ├── src/test/ Unit tests
│ │ └── src/androidTest/ Instrumented tests (device or emulator)
│ │
│ ├── feature_rescue/ Dynamic feature module (rescue mesh, CrisisLink sync)
│ ├── baselineprofile/ Baseline profile generator for startup/jank
│ ├── functions/ Firebase Cloud Functions (TypeScript)
│ │ └── src/ Certificates, attestation, messaging relay, SOS, push
│ │
│ ├── firestore.rules Firestore security rules
│ ├── firebase.json Firebase deployment config
│ ├── build.gradle.kts Project-level build config
│ └── settings.gradle.kts Module definitions
│
├── iOS/ Swift · SwiftUI
│ ├── Crisis Connect/
│ │ ├── App/ App entry point, root navigation, splash
│ │ ├── Features/ Chat, Contacts, SOS, Rescue, Sentinel, Settings,
│ │ │ Compass, LiDAR, MetalDetector, OfflineMap,
│ │ │ SignalScanner, SurvivalGuide, Whistle, …
│ │ ├── Security/ Keychain, certs, role verification
│ │ ├── Services/ BLE / GATT mesh / P2P, internet messaging, calls,
│ │ │ Firebase, background refresh
│ │ └── Shared/ Design system, utilities, media
│ │
│ ├── WidgetExtension/ WidgetKit widgets, SOS control, Live Activity
│ ├── BroadcastExtension/ ReplayKit screen-share upload extension
│ ├── Packages/ Vendored LibSignalClient and LiteRT-LM
│ ├── Config/ Info.plist, entitlements
│ └── Crisis ConnectTests/ Unit tests
│
├── docs/ Screenshots and design notes
├── LICENSE AGPL-3.0
└── README.md
Note on prebuilt binaries. The
.xcframeworkstatic libraries underiOS/Packages/LibSignalClientandiOS/Frameworksare not committed to this mirror -- together they are ~375 MB of build output. The Swift sources, headers and module maps are here, andiOS/README.mddocuments how to rebuild or fetch them.
Android release assets are published with keyless Sigstore bundles, a CycloneDX SBOM, SHA-256 checksums, and a GitHub artifact attestation. See Release verification before pilot distribution.
Pilot operators should assign the private on-call roster and exercise the Security incident response plan before handling live data.
| Layer | Android | iOS |
|---|---|---|
| Language | Kotlin | Swift |
| UI Framework | Jetpack Compose + Material 3 | SwiftUI |
| Bluetooth | Android BLE GATT / RFCOMM | CoreBluetooth |
| Mesh Protocol | Custom GATT mesh protocol | GATT mesh |
| Offline Encryption | Google Tink · SQLCipher | CryptoKit · Keychain |
| Internet Encryption | libsignal (Signal Protocol) | libsignal (vendored LibSignalClient) |
| Database | Room (SQLCipher encrypted) | SwiftData / Keychain-backed storage |
| Maps | MapLibre GL Native | MapLibre (tile-based offline) |
| Voice Codec | Opus (native .aar) | Opus · AVFoundation |
| Calls | WebRTC · Android Telecom | WebRTC · CallKit · PushKit |
| On-device AI | Google AI Edge LiteRT-LM | LiteRT-LM (vendored package) |
| Auth | Firebase Auth · Google Sign-In · phone | Firebase Auth · Google Sign-In · phone |
| Backend | Firestore · Cloud Functions | Firestore · Cloud Functions |
| App Security | Play Integrity · App Check | App Attest · App Check |
The BLE communication stack operates as follows:
┌─────────────────────────────────────────────────────────────┐
│ Application Layer │
│ Text messages · Voice messages · Images · Files · Location │
├─────────────────────────────────────────────────────────────┤
│ Encryption Layer │
│ AES-256-GCM envelope (Tink / CryptoKit) │
│ Per-message nonce · HKDF-derived session keys │
├─────────────────────────────────────────────────────────────┤
│ Framing Layer │
│ Chunking (BLE MTU ~512 bytes) · Reassembly · Sequencing │
│ Delivery receipts · Retry with exponential backoff │
├─────────────────────────────────────────────────────────────┤
│ Transport Layer │
│ BLE GATT (messages, images, files) │
│ GATT audio link 0xCD00 / RFCOMM (voice calls) │
│ GATT mesh (multi-hop relay) │
└─────────────────────────────────────────────────────────────┘
When two devices are not in direct BLE range, the GATT mesh protocol routes messages through intermediate devices:
Device A ──(encrypted)──► Device B ──(encrypted)──► Device C
(relay node)
• Device B forwards the encrypted payload without decryption
• TTL-based hop limit prevents infinite relay loops
• Each device maintains a seen-message cache for deduplication
• Mesh operates at the GATT service level (no special hardware)
The mesh protocol is transport-agnostic -- the encrypted payload is the same regardless of how many hops it takes. Relay nodes never have access to plaintext.
Offline voice calls use a dedicated pipeline over Bluetooth, and work cross-platform between Android and iOS:
Microphone ──► PCM 16kHz ──► Opus Encoder ──► BT link ──► Opus Decoder ──► Speaker
│
Jitter Buffer
(adaptive, 60-200ms)
Firebase is used for identity, coordination and the internet transport. None of it is required for offline messaging:
| Service | Purpose | Required? |
|---|---|---|
| Firebase Auth | User identity, phone verification, rescue roles | Only for internet + rescue features |
| Cloud Firestore | Ciphertext relay, agency coordination, SOS reports | Only for internet + rescue features |
| Cloud Functions | Certificate issuance, attestation, push, prekeys, TURN credentials | Only for internet + rescue features |
| Cloud Messaging / APNs | Message, call and SOS notifications | Only when online |
| App Check | API abuse prevention | Only when online |
| Crashlytics | Crash reporting for production stability | Optional |
Cloud Functions live under Android/functions and cover role certificate issuance, Play Integrity / App Attest verification, the encrypted messaging relay and prekey pool, VoIP push (APNs HTTP/2 + FCM), SOS signal reporting and short-lived TURN credentials.
Android provides three build types:
| Variant | Purpose | Signing | App Check |
|---|---|---|---|
debug | Development | Debug keystore | Debug provider |
internal | QA / testing | Release keystore | Debug provider |
release | Production (Play Store) | Release keystore | Play Integrity |
iOS public-source builds use Xcode 16+ with code signing disabled. Production signing, App Attest credentials and App Store distribution configuration are intentionally maintained outside this public mirror.
The easiest way to use Crisis Connect is to download it from the app stores. Android users can also install the exact universal APK generated and signed by Google Play for release 1.1.9:
The direct APK is com.auralis.crisisconnect version 1.1.9 (versionCode 64), supports
Android 7.0+ and is signed with the Google Play app-signing certificate. Verify its SHA-256 before
installing: f690576ab7a1dd5d6266247a469bd5893bfbd082307d994982d918d69c3124e8.
| Platform | Requirements |
|---|---|
| Android | Android Studio Ladybug+ · JDK 21 · Android SDK 36 |
| iOS | Xcode 16+ · iOS 17+ deployment target · macOS Sequoia+ · Rust toolchain (to build the vendored native libraries) |
| Backend | Node.js 20+ · Firebase CLI · Firebase project (Firestore, Auth, Functions) |
Important: BLE features require a physical device. Simulators and emulators do not support Bluetooth.
git clone https://github.com/emirhan-duman/Crisis-Connect.git
cd Crisis-Connect/Android
# Set up configuration files
cp app/google-services.json.example app/google-services.json
cp local.properties.example local.properties
cp keystore.properties.example keystore.properties
google-services.json from Firebase Console > Project Settings > Your Apps > Android app, and replace the example filelocal.properties -- every key is documented in local.properties.example. The required ones are:
sdk.dir=/path/to/your/Android/sdk
MOBILE_SYNC_BASE_URL=https://your-dashboard-deployment
GOOGLE_WEB_CLIENT_ID=your-client-id.apps.googleusercontent.com
MAPLIBRE_API_KEY=your_maplibre_api_key
Missing keys resolve to an empty string rather than failing the build. In particular, without
MOBILE_SYNC_BASE_URLevery agency and cross-agency messaging call fails at runtime.
keystore.properties with your signing configurationgit clone https://github.com/emirhan-duman/Crisis-Connect.git
cd Crisis-Connect/iOS
# Set up configuration
cp "Crisis Connect/GoogleService-Info.plist.example" "Crisis Connect/GoogleService-Info.plist"
GoogleService-Info.plist from Firebase Console > Project Settings > Your Apps > iOS app, and replace the example fileConfig/Info.plist with your reversed Google client ID.xcframework static libraries are not committed to this repository.Crisis Connect.xcodeproj in Xcode# Install Firebase CLI if not already installed
npm install -g firebase-tools
firebase login
# Deploy Firestore security rules
firebase deploy --only firestore:rules
# Deploy Cloud Functions
cd Android/functions
npm install
firebase deploy --only functions
After deployment, configure App Check in the Firebase Console:
Every figure below is produced by tokei against this repository. Code excludes comments and blank lines -- the numbers are not inflated by whitespace. Vendored dependencies, generated build artifacts and dependency lockfiles are counted separately, not as first-party code.
685 files · 206,994 lines of code
| Language | Files | Code | Comments | Blank | Share | |
|---|---|---|---|---|---|---|
| Kotlin | 516 | 160,594 | 7,081 | 11,602 | 77.58% | ████████████████ |
| XML (resources, manifests) | 115 | 38,031 | 235 | 124 | 18.37% | ████ |
| TypeScript (Cloud Functions) | 39 | 5,709 | 866 | 590 | 2.76% | ▌ |
| Firestore Rules | 1 | 1,647 | 0 | 71 | 0.80% | ▏ |
| Shell | 2 | 275 | 38 | 49 | 0.14% | ▏ |
| C++ (MLS frame crypto, JNI) | 1 | 168 | 46 | 29 | 0.08% | ▏ |
| JavaScript | 2 | 161 | 0 | 21 | 0.08% | ▏ |
| TSX | 1 | 145 | 0 | 4 | 0.07% | ▏ |
| JSON (config) | 3 |
312 files · 93,880 lines of code
| Language | Files | Code | Comments | Blank | Share | |
|---|---|---|---|---|---|---|
| Swift | 287 | 92,095 | 5,983 | 9,524 | 98.10% | ████████████████████ |
| HTML + inline CSS | 3 | 875 | 6 | 48 | 0.93% | ▏ |
| JSON (asset catalogs, config) | 10 | 261 | 0 | 0 | 0.28% | ▏ |
| Shell | 2 | 230 | 39 | 44 | 0.24% | ▏ |
| Objective-C++ (MLS frame crypto) | 1 | 188 | 61 | 33 | 0.20% | ▏ |
| C Header (bridging and MLS) | 4 | 105 | 32 | 23 | 0.11% | ▏ |
| Metal (LiDAR night-vision shaders) | 1 | 95 | 0 | 11 | 0.10% | ▏ |
| SVG | 4 | 31 | 0 | 0 | 0.04% | ▏ |
| Total |
| What | Files | Lines | Why |
|---|---|---|---|
iOS/Packages/LibSignalClient | 136 | 22,853 | Vendored from signalapp/libsignal |
Android/app/src/release/generated/baselineProfiles | 2 | 96,874 | Generated by the baseline profile module |
Android/functions/package-lock.json | 1 | 14,378 | npm dependency lockfile |
.xcframework static libraries | 4 | -- | Prebuilt binaries, not committed (iOS/README.md) |
tokei Android iOS --exclude Packages --sort code
Three tokei labels are corrected in the tables above:
firestore.rulesis detected as Snakemake,proguard-rules.proas Prolog, and the generatedbaseline-prof.txt/startup-prof.txtprofiles as Plain Text.
This section is the single place in this README that describes test scope. It intentionally does not state test totals: counts drift as suites change, and a meaningful number needs a reproducible counting method, a commit, a platform scope, and a distinction between tests that exist and tests that a given run actually executed.
The workflow definitions are the source of truth for what runs automatically. The descriptions below summarize their configured steps; they do not claim that any particular run passed. Check the Actions tab for run results.
| Workflow | Triggers | Configured steps | Not run |
|---|---|---|---|
| Android CI | Every pull request; pushes to main that touch Android/ or .github/workflows/android-ci.yml | Native frame fuzz-target smoke run (-runs=10000) · :app:lintDebug · :app:assembleDebug · :app:testDebugUnitTest · :feature_rescue:testDebugUnitTest | Instrumented tests (connectedDebugAndroidTest) |
| iOS CI | Pull requests that touch iOS/ or .github/workflows/ios-ci.yml; pushes to main with those same paths; manual dispatch | iOS/Scripts/ci-validate.sh: Xcode project, shared scheme, test plan and local Swift package manifest validation, a syntax check of every Swift source file, and a check that no App Check debug token is committed in the shared scheme | App build, xcodebuild test, unit and UI tests |
Android CI uses the public google-services.json.example configuration, so it exercises the
build and JVM unit tests without real Firebase credentials.
iOS CI is source and project validation, not build-and-test execution. A clean public
checkout cannot currently link or run the Xcode test plan because the vendored
SignalFfi.xcframework and OrangeMlsWorker.xcframework static libraries are not committed. See
iOS/README.md -- Continuous integration for details.
These commands are available to contributors but, unless noted in the table above, are not executed by public CI.
Android -- requires JDK 21 and Android SDK 36, plus the configuration files from
Build From Source (app/google-services.json can be the example file for
local unit tests):
cd Android
./gradlew :app:lintDebug # Static analysis (also run in CI)
./gradlew :app:testDebugUnitTest # App unit tests (also run in CI)
./gradlew :feature_rescue:testDebugUnitTest # Rescue module unit tests (also run in CI)
./gradlew :app:connectedDebugAndroidTest # Instrumented tests -- manual only, needs a connected device or emulator
Instrumented tests that touch Bluetooth need a physical device; emulators have no BLE radio.
iOS -- the validation that CI runs needs macOS with Xcode 16+, but does not build the app or need the vendored native libraries:
cd iOS
./Scripts/ci-validate.sh # Project + Swift syntax validation (same as CI)
Running the XCTest suites is manual and requires the vendored native libraries to be built first (Xcode 16+ and a Rust toolchain; see iOS/README.md):
cd iOS
xcodebuild test \
-scheme "Crisis Connect" \
-destination "platform=iOS Simulator,name=iPhone 16"
The suites include tests for the following areas. This list describes intent, not a measured coverage percentage:
Crisis Connect is designed with privacy as a core principle:
Crisis Connect requests only the permissions necessary for its features. Every permission maps to a specific user-facing capability:
| Permission | Why It's Needed |
|---|---|
| Bluetooth (scan, advertise, connect) | Core P2P messaging and device discovery |
| Camera | QR code scanning, video calls |
| Microphone | Voice calls and voice message recording |
| Location | Offline maps centering, location sharing, rescue live location |
| Internet | Internet messaging and calls, auth, rescue sync, crash reporting |
| Notifications | Message, call and SOS notifications |
| Foreground Service | Maintaining BLE connections, active calls and SOS broadcasts |
| Sensors | Compass, metal detector, sensor dashboard |
| Wi-Fi State | Signal finder tool |
All permissions are requested at runtime with clear explanations. The app is functional with only Bluetooth permission granted -- all other permissions are optional and tied to specific features.
Crisis Connect ships in 19 languages on both platforms:
Arabic · Bengali · Chinese (Simplified) · English · Filipino · French · German · Hindi · Indonesian · Japanese · Kurdish · Persian · Portuguese · Russian · Spanish · Turkish · Ukrainian · Urdu · Vietnamese
The UI, the Survival Guide and the sensor tooling are localized.
Crisis Connect uses Hosted Weblate for community translations. The project maintainer approves the use of Weblate for this repository.
To contribute, sign in to Weblate, choose your language and an Android or iOS component, and translate or review the available strings. English is the source language. Preserve format placeholders (such as %1$s, %d and %@), markup, escape sequences and line breaks. Keep emergency instructions clear and accurate; leave a comment for maintainer review if safety-related wording is uncertain.
Translations are kept alongside the source code in this repository and are covered by its GNU Affero General Public License v3.0. Maintainers review translation changes before including them in releases. Contributions for additional languages are welcome -- see Contributing.
See the localization maintenance guide for the component map, widget resource format, terminology, and validation steps.
We welcome contributions from developers, security researchers, translators, and anyone who cares about resilient communication.
git checkout -b feature/your-feature)| Area | Description | Difficulty |
|---|---|---|
| Security Audit | Review crypto implementation, key management, certificate verification | Advanced |
| BLE Protocol | Edge-case handling, connection stability, MTU negotiation | Advanced |
| Mesh Improvements | Routing efficiency, hop optimization, relay reliability | Advanced |
| Localization | Translate UI strings and survival guide content to new languages | Beginner |
| Accessibility | Screen reader support, dynamic type, high contrast | Intermediate |
| Test Coverage | Add unit and integration tests for uncovered code paths | Intermediate |
| Documentation | Protocol specs, architecture docs, API documentation | Intermediate |
| Bug Reports | Report issues with clear reproduction steps | Beginner |
For bugs and feature requests, open an issue.
If you discover a security vulnerability in Crisis Connect, please do not open a public issue. Instead, report it responsibly:
We take security reports seriously and will respond as quickly as possible.
The project's external interface reference and secure development policy document the boundaries, common vulnerability classes, cryptographic baseline, and verification process used for releases.
Crisis Connect is in production on both app stores and under active development. The roadmap reflects what has been shipped and what comes next.
Offline core
Internet layer
Assistant, tools and platform
| Website | crisisconnect.network |
| Website (TR) | crisisconnect.com.tr |
| Google Play | Download for Android |
| Android APK | Google Play-signed 1.1.9 universal APK |
| App Store | Download for iOS |
| X (Twitter) | @CrisisConnectHQ |
| @crisisconnecthq | |
| Crisis Connect | |
| Source Code | github.com/emirhan-duman/Crisis-Connect |
Codemagic supports Crisis Connect with free native Android and iOS CI builds through its non-profit program.
Clemta supports Crisis Connect by covering U.S. company formation and incorporation fees.
BrowserStack supports Crisis Connect through its Open Source Program with sponsored Live, Automate, App Live, App Automate, and Percy access (active through 19 October 2027) for mobile app testing, browser compatibility, web automation, and visual regression testing.
BrowserStack's required README verification statement: This project is tested with BrowserStack.
Hosted Weblate supports Crisis Connect with free translation hosting through its Libre plan for open-source projects, helping the community translate and review the Android and iOS apps.
BetterQA supports Crisis Connect with a complimentary security assessment of the Android and iOS apps, including automated scanning, engineer validation of findings, remediation guidance, and one retest. The assessment has been agreed; results are pending.
This project is licensed under the GNU Affero General Public License v3.0.
You are free to use, modify, and distribute this software. Any modified version made available over a network must also be open-sourced under the same license.
Crisis Connect vendors libsignal (AGPL-3.0-only) under iOS/Packages/LibSignalClient and consumes it as a Maven dependency on Android.
| Crash Reporting | Firebase Crashlytics | Firebase Crashlytics |
| Public CI | GitHub Actions: lint, debug build, unit tests (scope) | GitHub Actions: project and Swift syntax validation (scope) |
| Min Version | Android 7.0 (API 24) | iOS 17.0 |
| Target Version | Android 16 (API 36) | iOS 18 |
| Test Frameworks | JUnit · Espresso · MockK · Robolectric | XCTest |
| 86 |
| 0 |
| 0 |
| 0.04% |
▏ |
| Batch | 1 | 68 | 0 | 21 | 0.03% | ▏ |
| ProGuard | 1 | 48 | 0 | 9 | 0.02% | ▏ |
| TOML | 1 | 48 | 5 | 2 | 0.02% | ▏ |
| CMake | 1 | 11 | 9 | 4 | 0.01% | ▏ |
| SVG | 1 | 3 | 0 | 0 | 0.00% | ▏ |
| Total | 685 | 206,994 | 8,280 | 12,526 |
| 93,880 |
| 6,121 |
| 9,683 |