Skip to content

OpenIPC/devourer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

175 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

devourer

The Realtek 11ac driver that simply devours its competitors.

Devourer is a userspace Wi-Fi driver for Realtek's 802.11ac USB adapters — the cheap, everywhere-available dongles that power most long-range FPV video links. It talks to the chip directly over libusb: no kernel module, no DKMS tree to patch every time your kernel updates, no root filesystem to taint. Build one static library, link it, and you have raw monitor-mode RX and packet injection on three generations of Realtek silicon, from a single API.

It is the OpenIPC project's driver of choice for long-range digital video links.

Why devourer

  • No kernel driver, no driver hell. Everything runs in your process via libusb. The same code works on Linux, macOS, Windows, and Android (Termux) — including platforms the vendor drivers never supported.
  • Faster on-air than the kernel driver. Ready-to-receive and ready-to-transmit come up quicker than the vendor .ko on every supported chip (numbers).
  • Per-packet control. Every injected frame carries its own radiotap header: rate, bandwidth, guard interval, coding, STBC — even TX power and channel — can change frame by frame. That turns one dongle into an adaptive-link engine: unequal error protection for video layers, live power control, per-packet frequency hopping.
  • Frequency hopping at FHSS speed. A channel hop costs ~0.5–2.5 ms depending on chip — fast enough to hop on every packet (how).
  • Narrowband modes the kernel can't do. 5 and 10 MHz channels on the newest chips — half/quarter the bandwidth, more range from the same power.
  • A radio lab in a dongle. Channel sounding, per-antenna signal quality, beamforming report capture (enough to do motion sensing), spectrum sweeps, link-health diagnosis that tells you whether to add or back off power.
  • Clean library API. One DeviceConfig struct at construction, runtime setters for everything that changes mid-flight, zero environment-variable magic inside the library.

New to low-level RF? Start with the visual RF primer — eight short animations that make the rest click.

Supported hardware

Bandwidth cells are devourer's measured on-air TX throughput (Mbps, HT MCS7, 20 MHz) per band:

Part RF / streams 2.4 GHz (ch6) UNII-1 (ch36) UNII-2/3 (ch149) Notes
RTL8812AU 2T2R 56 52 52 CHANEVE CHW50L (0bda:8812)
RTL8811AU 1T1R 1T1R cut of 8812 silicon; rides the 8812 code path. Not benchmarked
RTL8814AU 4T4R, 3-SS max 65 †(32) †(32) 0bda:8813; tested on COMFAST CF-938AC and CF-960AC — antenna builds differ in realised RX diversity
RTL8821AU 1T1R AC + BT 54 32 28 TP-Link Archer T2U Plus (2357:0120)
RTL8822BU 2T2R + BT 52 50 49 TP-Link Archer T3U (2357:012d)
RTL8812BU 1T1R + BT 1T1R cut of 8822B silicon; rides the 8822BU code path. Not benchmarked
RTL8811CU 1T1R + BT 36 29 28 COMFAST CF-811AC (0bda:c811)
RTL8812CU 2T2R 65 60 60 LB-LINK WDN1300H (0bda:c812)
RTL8822CU 2T2R + BT not benchmarked (0bda:c82c)
RTL8812EU 2T2R 8 51 47 LB-LINK BL-M8812EU2 (0bda:a81a); bare 5 GHz FPV module. 5/10 MHz capable
RTL8822EU 2T2R + BT not benchmarked. 5/10 MHz capable

= works on-air but the reading varies run-to-run (bracketed = best clean reading).

Out of scope: the PCIe siblings (e.g. 8822BE) and the 11ax "Kestrel" generation — same branding, different bus or baseband.

Heads up — some Realtek sticks ship in "ZeroCD" mode and first enumerate as a USB flash drive holding a Windows installer (0bda:1a2b is the canonical offender). If the device won't open, check lsusb; usb_modeswitch flips it to the real NIC.

Quick start

Toolchain: CMake ≥ 3.15, a C++20 compiler, libusb-1.0.

# Debian/Ubuntu
sudo apt install build-essential cmake pkg-config libusb-1.0-0-dev
# macOS (Homebrew)
brew install cmake pkg-config libusb

cmake -S . -B build
cmake --build build -j

On Windows, install libusb via vcpkg (vcpkg install libusb) and set VCPKG_ROOT before configuring.

Then, with a supported dongle plugged in:

sudo ./build/rxdemo                    # receive: monitor mode, prints frames
sudo ./build/txdemo                    # transmit: injects a test beacon
DEVOURER_CHANNEL=100 DEVOURER_TX_RATE=MCS7/40 sudo -E ./build/txdemo

The demos find the first supported adapter automatically; DEVOURER_PID / DEVOURER_VID pin a specific one. Every configuration knob the demos accept is an environment variable — the complete catalogue, with value grammar, is the env: tags in src/DeviceConfig.h.

Example binaries

binary what it shows
rxdemo monitor-mode RX loop with per-frame signal telemetry
txdemo packet injection, rate/power/channel control, hopping
streamtx / duplex stdin-driven TX / full-duplex packet link
svctx per-video-layer rate ladders (unequal error protection)
txpower runtime TX-power API walkthrough
sense Wi-Fi motion sensing from beamforming reports
precoder OFDM subcarrier shaping proof-of-concept

All chips compile in by default; per-chip CMake options (DEVOURER_JAGUAR1, DEVOURER_8814, DEVOURER_JAGUAR2_8822B, DEVOURER_JAGUAR2_8821C, DEVOURER_JAGUAR3_8822C, DEVOURER_JAGUAR3_8822E) drop unneeded firmware and tables — an 8812AU-only rxdemo is ~1.0 MB versus ~2.6 MB with everything on.

Using the library

You own libusb: init it, open the device, detach any kernel driver, claim interface 0 — then hand the handle to the factory. examples/rx/main.cpp is the full boilerplate; the minimal RX path is:

auto logger = std::make_shared<Logger>();
WiFiDriver driver(logger);
auto dev = driver.CreateRtlDevice(handle);     // handle is already claimed
dev->Init(packetProcessor, SelectedChannel{
    .Channel      = 36,
    .ChannelOffset = 0,
    .ChannelWidth = CHANNEL_WIDTH_20,
});

packetProcessor is your void(const Packet&) callback. For TX, call InitWrite and then send_packet(buffer, len), where the buffer starts with a radiotap header describing how the frame should fly.

Construction-time options travel in a devourer::DeviceConfig (src/DeviceConfig.h documents every field):

devourer::DeviceConfig cfg;
cfg.rx.keep_corrupted = true;                  // deliver CRC-failed frames too
auto dev = driver.CreateRtlDevice(handle, ctx, lock, cfg);

Anything that changes mid-session is a runtime setter on the device: SetTxMode, SetTxPowerOffsetQdb, SetRxPathMask, FastRetune, ... The device class is chosen automatically from the chip behind the handle; one IRtlDevice interface covers all three generations.

Going deeper

Testing

Headless selftests run with ctest. Hardware regression is tests/regress.py: a TX/RX matrix between devourer and the kernel driver across plugged-in adapters, with optional full-pair, encoding-sweep, and third-adapter-sniffer modes — see tests/README.md.

License

GPL-2.0. See LICENSE.

About

The Realtek 11ac userspace driver.

Topics

Resources

License

Code of conduct

Stars

37 stars

Watchers

1 watching

Forks

Sponsor this project

Contributors