- Rust 83.5%
- Shell 14%
- Kotlin 1.8%
- C++ 0.7%
| .github/workflows | ||
| app | ||
| docs | ||
| external | ||
| patches | ||
| scripts | ||
| .gitignore | ||
| .gitmodules | ||
| README.md | ||
| rust-toolchain.toml | ||
pixdr
pixdr is a pure-Rust Android NativeActivity SDR app for using an Ettus/NI USRP B210 from an Android phone over USB host mode.
Current target setup:
- Android NativeActivity, no Java/Kotlin app code
- Rust UI with
egui/eframe/wgpu - FutureSDR flowgraph backend with a custom UHD B210 source block
- UHD 4.10 built for Android arm64
- B200/B210 Android USB fd handoff flow inspired by GNU Radio's GrHardwareService
- B210 firmware/FPGA loading through UHD
Repository layout
pixdr/
app/ Rust NativeActivity app, AndroidManifest, assets, resources
external/ External dependencies (git submodules in release)
uhd/ m4tsuri/uhd, branch pixdr-android-uhd-4.10
libusb/ upstream libusb, tag v1.0.27
uhd-rs/ m4tsuri/uhd-rust, branch pixdr-android
boost-android/ m4tsuri/Boost-for-Android, branch pixdr-android
FutureSDR/ FutureSDR runtime used for the receive flowgraph
build/ Generated native build/toolchain workspace (ignored)
docs/ Project notes and architecture notes
patches/ format-patch exports of fork changes
scripts/ Supported build/install/log entrypoints
Important app files:
app/src/lib.rs— egui UI and B210 worker orchestrationapp/src/futuresdr_backend.rs— FutureSDR UHD source block and spectrum sink blockapp/src/usb.rs— Android USB permission andUsbDeviceConnectionfd acquisition via JNIapp/src/uhd_wrapper.rs— UHD init/open using injected Android USB contextapp/AndroidManifest.xml— NativeActivity declaration
Prerequisites
Host tools:
- Linux host
- Android SDK with platform 29+ and build-tools 35.x
- Android NDK r27d extracted to
build/native/android-ndk-r27dor provided viaPIXDR_NDK=/path/to/ndk - Rust nightly +
cargo-ndk cmake,make,wget,tar,zip,keytooladb
Install Rust pieces:
rustup target add aarch64-linux-android
cargo install cargo-ndk
Android SDK defaults to $HOME/Android/Sdk. Override with:
export ANDROID_HOME=/path/to/Android/Sdk
Checkout
git clone --recursive https://github.com/m4tsuri/pixdr.git
cd pixdr
If already cloned:
git submodule update --init --recursive
Build
1. Build native dependencies from scratch
This builds Boost, libusb, and UHD into build/native/toolchain/arm64-v8a:
scripts/build-native.sh
This step is slow and assumes external/ has been initialized with the pixdr fork branches plus upstream libusb.
2. Fetch B200/B210 runtime images
scripts/fetch-uhd-images.sh
This populates app/assets/ with the three files packaged into the APK. They
are intentionally ignored by git until redistribution licensing is decided.
3. Build the APK
scripts/build-apk.sh
Output:
app/pixdr-debug.apk
4. Install and run
scripts/install-run.sh
5. Follow logs
scripts/logcat.sh
Fast rebuild during development
If native dependency build directories already exist:
scripts/rebuild-all.sh
This rebuilds native dependencies/UHD, builds the Rust app, packages the APK, installs it, and starts the app.
Environment overrides
All scripts source scripts/env.sh. Useful overrides:
export ANDROID_HOME=/path/to/Android/Sdk
export PIXDR_NDK=/path/to/android-ndk-r27d
export PIXDR_ANDROID_API=29
export PIXDR_PREFIX=/path/to/android/uhd/prefix
Android/B210 notes
Use a powered USB-C hub/dock. The B210 can brown out or fail to re-enumerate after FX3 firmware jump if powered directly from a phone.
Expected successful flow:
- Android grants USB permission for the B210/FX3 device.
- App obtains
UsbDeviceConnectionfd. - UHD loads FX3 firmware if needed.
- Android re-enumerates the B210 as
Ettus Research LLC / USRP B200. - App obtains a new fd.
- UHD opens the B210 and loads FPGA.
- A FutureSDR flowgraph runs a custom UHD B210 source block into the spectrum sink.
- UI shows live FFT/waterfall when RX streamer is active.
If the UI says B210 opened; RX stream failed, UHD opened the device but RX streamer setup failed. Replugging or restarting the app is often enough while this Android USB path is still being hardened.
Architecture notes
- Android USB context injection into UHD:
docs/android-uhd-injection.md
Fork branches
Patched dependencies are maintained as fork branches:
https://github.com/m4tsuri/uhd, branchpixdr-android-uhd-4.10https://github.com/m4tsuri/uhd-rust, branchpixdr-androidhttps://github.com/m4tsuri/Boost-for-Android, branchpixdr-android
Unpatched dependency:
https://github.com/libusb/libusb, tagv1.0.27
patches/ contains git format-patch exports for review/auditing.