- IcmpProbe: attempt the echo on the default network AND each active network (Network.bindSocket + per-network DNS). Run 1's ping6 EAGAIN was topology (v6 only on cellular), not capability — now the report shows which networks carry which family instead of a bare ERROR. - New traceroute.udp4 (TracerouteProbe): actual UDP traceroute reading ICMP time-exceeded via Os.recvmsg(MSG_ERRQUEUE) with cmsg parsing — reflection per repo convention (API surface exists ~34+). If this returns hops, the C-over-JNI shim is unnecessary on that device. sock_extended_err layout constants documented in OsAbi. - MulticastProbe: 10 s window; meta-query PLUS concrete types (_http._tcp, _googlecast._tcp) — run 1 showed the meta-query alone returning 0 on a network with live services; capture names + failure codes as evidence. - ShizukuProbe: ip monitor window 2s -> 5s, gateway ping in background to provoke a NEIGH transition instead of hoping for ambient churn. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Echolot Capability Prober
A throwaway diagnostic app that runs the borderline no-root operations from the Echolot feasibility matrix on a real device and reports what actually works on that Android build. Its job is to turn "should work / needs verification" spec notes into observed facts before the production app hardens around them. Several probes naturally evolve into the tier-detection code the real app needs anyway.
Package / appId: app.echo_lot.prober (derived from the echo-lot.app domain; hyphen → underscore
because Android application IDs and Java packages cannot contain hyphens).
What it probes
| Probe | Question it answers | Expected result |
|---|---|---|
link.snapshot |
What does LinkProperties expose per active network? |
SUPPORTED |
icmp.ping4 / icmp.ping6 |
Does the unprivileged ICMP datagram socket work? | SUPPORTED (no root needed) |
sockopt.matrix |
Are IP_TTL, IP_TOS, IP_RECVERR, IP_MTU_DISCOVER accepted? | SUPPORTED / PARTIAL |
trace.errqueue_reachable |
Is errqueue traceroute reachable from the Os API? | likely PARTIAL → needs a small native shim |
multinetwork.request_and_bind |
Can we hold + bind Wi-Fi / cellular / ethernet concurrently? | SUPPORTED for links present now |
local.mdns_discover |
Does multicast reception / mDNS work with a MulticastLock? | SUPPORTED |
peer.ble_advertise |
Can this chipset advertise BLE (peer-mode channel)? | device-dependent |
shizuku.command_battery |
Does the Shizuku shell tier return neighbor table, RA routes, DHCP logs? | SUPPORTED if Shizuku running |
Each result carries a verdict (SUPPORTED / PARTIAL / UNSUPPORTED / INCONCLUSIVE / ERROR), a one-line summary, and raw evidence (sockopt return codes, addresses, timings, and the actual dump excerpts from the Shizuku commands — capturing the per-device format the real parsers must handle). Export the whole run as JSON with the Export button and share it anywhere.
Building
Needs Android Studio (Koala or newer) or a local Android SDK; this repo was scaffolded without network access to Google's Maven, so dependencies download on your first local build.
# Point the build at your SDK (or let Android Studio create local.properties):
echo "sdk.dir=/path/to/Android/sdk" > local.properties
./gradlew :app:assembleDebug
./gradlew :app:installDebug # with a device/emulator attached
The debug APK lands in app/build/outputs/apk/debug/.
Using the Shizuku tier
- Install Shizuku and start it via wireless ADB pairing (no root).
- Launch the prober, tap Run all probes. The Shizuku probe requests permission on first use.
- If Shizuku isn't running the probe reports INCONCLUSIVE (everything else still runs).
Notes / known gaps
- Errqueue traceroute (
MSG_ERRQUEUErecvmsg + cmsg parse) is expected to need a native C-over-JNI shim; this prober only confirms the sockopts + call-path availability. Wiring the shim is the next spike if the verdict is PARTIAL. - Multi-network probe can only bind transports physically present at run time. To exercise USB ethernet, attach an adapter first.
- BLE advertising support is genuinely chipset-dependent; a UNSUPPORTED here is a real finding.
License
GPL-3.0-or-later, like the rest of the Echolot code — see ../LICENSE. The specs in
../docs/ are CC-BY-4.0.
Relationship to the specs
Result IDs mirror the measurement-schema.md test-type registry where one exists, and the JSON
report shape is a stripped-down cousin of the full measurement document. The specs live in
../docs/ — feature-catalog-and-feasibility.md, measurement-schema.md,
probe-protocol.md.