Skip to content
aks-buildsPublic

About

Detects active RF jamming of cellular bands via on-device multi-signal fusion + local BLE peer corroboration. No backend, no telemetry.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

📡 jamwarden

Know when your cellular signal was jammed, not just lost.

An open-source Android app that detects active RF jamming of cellular bands — distinct from IMSI-catcher/fake-base-station attacks — by fusing on-device radio signals with local, serverless peer corroboration over Bluetooth. No backend, no telemetry, no account.

License: MIT Platform: Android Status: early development


How jamwarden works: monitor radio state, detect an abrupt signal drop, fuse five on-device signals, check for peer corroboration over BLE, resolve a confidence tier, and surface a calm-to-urgent on-screen alert

Why jamwarden

Cellular jammers block 3G/4G/5G broadband; 2.4GHz BLE/WiFi keeps working. That means offline-mesh apps stay usable through a jamming event — but only if you know it's happening and switch to one. A phone showing "no service" looks the same whether you're in a jammed zone or just standing in a basement.

Existing tools don't cover this. IMSI-catcher/StingRay detectors (AIMSICD, EFF Rayhunter) target a different attack — fake base stations, not RF jamming — and are largely unmaintained or need hardware/root access modern Android blocks. Generic consumer "jammer detector" apps exist but are closed-source and single-signal ("no bars = jammed"), which is indistinguishable from an ordinary dead zone.

Important: jamwarden reports a confidence tier, not a certainty. No detector running on non-rooted commodity hardware can distinguish a real jamming event from a sufficiently similar coincidental outage with 100% certainty — jamwarden says so, out loud, in the UI, rather than presenting a false binary "safe/jammed" signal.

How it works

Single-signal detection ("zero bars") is indistinguishable from walking into a basement, so jamwarden fuses five on-device signals, then checks for corroboration from nearby phones over a bare, unpaired BLE broadcast — no pairing, no identity, no relay, no server:

Monitor (TelephonyManager + WiFi/BLE)
        │
        ▼
Abrupt signal drop across visible carriers
        │
        ▼
Fuse: abruptness · breadth · neighbor-cell collapse · cross-radio contrast · baseline deviation
        │
        ▼
Broadcast + listen for nearby peers ("lost cellular, just now")
        │
        ▼
Confidence gate: local-only signals  vs.  corroborated by N nearby peers
        │
        ▼
Confidence tier + plain-language reason ── never a bare "you are jammed" claim
        │
        ▼
On-screen alert: calm styling at low confidence, distinct color/haptic at "likely active jamming"

Screenshots

jamwarden main screen after a real cold launch on a physical detection run, showing the 'Possible dead zone' tier in calm teal, the reason text 'no unusual signal pattern detected; no historical baseline recorded for this location yet; no nearby peer corroboration yet.', and 'Nearby peers confirming: 0'
Normal/idle state: the real SignalFusionEngine pipeline running end-to-end on a cold launch, nothing unusual detected.
jamwarden main screen showing the 'Likely active jamming' tier in distinct red/orange, the reason text 'Signal dropped abruptly across every visible carrier, neighbor cells collapsed, Wi-Fi/BLE stayed alive, and nearby peers confirmed the same loss just now.', and 'Nearby peers confirming: 3'
The app doing the thing it exists to do: highest-confidence tier, distinct alert color, plain-language reason, and peer corroboration count all visible.

The second screenshot's tier can't be produced organically on a bare emulator (no real jammer, no real nearby BLE peer to corroborate), so it was captured via a debug-build-only test seam in MainActivity that lets a debuggable build only render a forced ConfidenceTier from a launch Intent extra — see the seam's doc comment in app/src/main/kotlin/dev/jamwarden/app/MainActivity.kt for exactly how it's gated. It has no effect in a release build and makes no network call, same as everywhere else in this app. Full Maestro E2E flows covering both screenshots, the Settings screen, alert toggles, and baseline reset live in e2e/maestro/.

Zero backend, by design

No server, no analytics SDK, no crash reporting service, no ad network, no network egress of any kind — the app should not link an HTTP client at all. Detection state and the on-device location-signal baseline never leave the phone, and the peer-corroboration broadcast is local radio range only, un-relayed, with no persistence beyond a short TTL. This is an architectural constraint, not a settings toggle.

Privacy/permission trade-off (disclosed)

Reading cell-tower info on Android 10+ requires ACCESS_FINE_LOCATION — a real tension for a tool aimed at people who don't want to be tracked. jamwarden uses it only to compute a local signal-quality baseline per location; that data is never logged to a shareable file, never reverse-geocoded to a human-readable address, and never transmitted, because there is nowhere for it to be transmitted to. You can view and wipe all locally-stored baseline data from inside the app at any time.

Platform

Android only, for now. Android exposes real signal/cell telemetry (TelephonyManager/CellInfo) to normal apps; iOS has sandboxed that away from third-party access since iOS 13, so an iOS build could only ever offer a materially weaker "total service loss + peer corroboration" signal. Rather than ship an iOS app that visually mirrors this one while silently offering a fraction of its reliability, iOS support is deferred until it can be built and labeled honestly.

Repository layout

jamwarden/
├── app/                       Android application module (Kotlin, Jetpack Compose)
│   ├── src/main/kotlin/       Detection engine, BLE peer broadcast, Compose UI
│   └── src/test/kotlin/       Unit tests for the signal-fusion/confidence-tier logic
├── e2e/maestro/               Maestro E2E flows (cold launch, tiers, settings, baseline reset)
├── .github/
│   └── media/                 README diagrams and screenshots
├── CONTRIBUTING.md
├── LICENSE
├── README.md
└── SECURITY.md

Contributing

PRs and issues welcome — see CONTRIBUTING.md. Given the safety stakes, changes to the fusion/confidence-tier logic or anything touching permissions/network egress get an elevated review bar.

License

MIT — use this however you want, but this is a confidence signal, not a safety guarantee; verify it holds up for your own threat model before relying on it.

About

Detects active RF jamming of cellular bands via on-device multi-signal fusion + local BLE peer corroboration. No backend, no telemetry.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages