Add a WPA2/CCMP station-mode client (APFPV)#335
Open
GingerFluffyCat wants to merge 7 commits into
Open
Conversation
Confirmed by research: Wpa2Supplicant/Dot11Frames/Wpa2Crypto/crypto/* have zero coupling to the driver layer (pure byte-buffer logic behind a SendFn callback) -- ported byte-for-byte with zero code changes, only new build wiring (apfpv CMake target) + the already-proven android/log.h host-build compat shim reused from WiFiDriver. ApfpvDhcp, LqFeedback, Wpa2Authenticator: same story, built clean. ApfpvStation.cpp/h and RxDeframe.cpp/h are copied onto the tree but NOT yet wired into the build -- these need real porting work against upstream's restructured driver API (IRtlDevice/RtlJaguarDevice, new H2C/station convenience wrappers that don't exist upstream yet) before they'll compile. Next commit.
…nto RtlAdapter Zero logic changes -- these only ever used rtw_read<T>/rtw_write<T> (same template signatures upstream) and hardcoded/named H2C mailbox register offsets (REG_HMETFR/REG_HMEBOX_0..3/REG_HMEBOX_EXT_0..3, confirmed present in hal/hal_com_reg.h). reset_device() needed one small new addition: upstream's transport layer had no USB-reset concept at all (no station client flow existed there to need reconnect recovery) -- added a virtual int reset() to IRtlTransport (default no-op, e.g. for a future PCIe transport) with a real libusb_reset_device() override in UsbTransport. Verified: devourer library builds clean (Jaguar1-only config).
Zero logic changes -- confirmed hw_var_rcr_config() (the actual register write) and every RCR_*/REG_RXFLTMAP* constant this function needs already exist upstream, used the same way in its own _InitWMACSetting_8812A(). This is the kernel-exact station RCR fix: RCR_AAP (promiscuous) bypasses the HW auto-Block-Ack engine for A-MPDU aggregates entirely (ADDBA/DELBA/single- frame-fallback ~25Mbps ceiling); APM+CBSSID_DATA routes through the real station RX path so the chip auto-BAs aggregates instead. Verified: devourer library builds clean.
…not yet wired) Mechanical port of the accessors + backing state (_lastRfCh, _scanMode) from the pre-rebuild WiFiDriver. Honest caveat, flagged in the code: the actual BEHAVIOR (reading RF 0x18 back into _lastRfCh after a tune, skipping IQK when _scanMode is set) lives inside set_channel_bwmode and is NOT yet wired up -- these always report "not wedged"/have no IQK-suppression effect until that integration lands. Tracked as follow-up work. Verified: builds clean.
- RF-verify-read (BB 0x834 + RF 0x18 readback -> _lastRfCh) added to PHY_HandleSwChnlAndSetBW8812, Android-gated, same placement/behavior as the pre-rebuild WiFiDriver -- confirmed phy_query_bb_reg/phy_query_rf_reg exist upstream with matching signatures (this code path is skipped on the host/non-Android build, so verified by symbol lookup rather than compile here; will compile-check for real on the next Android/Gradle build). - _scanMode now actually suppresses the IQK trigger (fast unsettled retunes across a scan sweep wedge the RF synth if IQK runs mid-sweep). rf_wedged()/setScanMode() are no longer inert -- both declared AND wired. Verified: devourer library builds clean.
Kept the proven default behavior exactly (concurrent IN/OUT, ACK-driven TXPKT_EMPTY drain check, opt-in clear_halt for the WSL/vhci wedge case, _txFastPath skipping the drain diagnostic once streaming). Dropped the legacy DEVOURER_TX_USE_PAUSE fallback: it paused/resumed a per-adapter async-RX worker that doesn't exist in this form anymore (RX-loop ownership moved to whoever calls bulk_read_async_loop, i.e. RtlJaguarDevice:: StartRxLoop/StopRxLoop) -- that branch was already documented as legacy/ non-default in the pre-rebuild code, so it's dropped rather than force-fit onto a different architecture, not silently lost functionality. Adapted bulk_out_eps[0]/libusb_clear_halt(_dev_handle,...) to this class's own first_bulk_out_ep()/bulk_clear_halt() equivalents. Verified: devourer library builds clean.
…tream base - PhydmWatchdog: restore the close-range DIG-saturation fix (RSSI-tracked IGI floor/ceiling once linked) that upstream's monitor-only DigTick had no equivalent for. - StationTxDesc: port the unicast TX descriptor (BMC=0 ACK-handshake fix). - ApfpvStation: replace every StartMonitorAsyncRx/StopAsyncRx call site with upstream's blocking StartRxLoop/StopRxLoop run on a dedicated thread (RtlJaguarDevice::Init/StartRxLoop no longer return until stopped, unlike the old async URB-pool contract). - AP mode: wire onto upstream's IRtlDevice::StartBeacon/StopBeacon (real HW TBTT beacon + ACK-engine arming) instead of the old manual register pokes + software beacon-poll loop; fix apSend() calling send_packet synchronously from the RX callback thread (returns BUSY per docs/ap-mode.md) by queuing to a separate TX-pump thread. - RadioManagementModule: port prime_offset_40mhz (40 MHz primary-channel offset) and add no-op pauseAsyncRx/resumeAsyncRx to RtlAdapter (RX ownership moved out of the adapter, so there's no in-adapter pump left to pause). apfpv_station now builds clean against upstream's rebuilt base.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
devourer currently has no way to be a WPA2 client — it injects/receives in
monitor mode, and the AP-mode test harnesses under
tests/play the AP roleagainst a real station. This adds the missing piece: a full station-mode
client that scans, authenticates, associates, runs the WPA2 4-way handshake,
gets an IP over DHCP, and streams data — usable as a real Wi-Fi uplink for an
RTL8812AU-family dongle, not just a monitor/injection tool.
New library surface (mirrors the existing
devourer/chip-family targetpattern): two new CMake targets,
apfpv(driver-independent: WPA2supplicant, 802.11 frame builders, CCMP crypto, beacon/scan parsing) and
apfpv_station(the driver-dependent orchestrator + RX pipeline).What's included
src/apfpv/—Wpa2Supplicant(4-way handshake, client side),Dot11Frames(auth/assoc/probe request builders),Wpa2Crypto+crypto/{AesCcm,AesCmac,Sha1Hmac}(own CCMP/PBKDF2/PRF implementation, noexternal crypto dependency),
ScanProbe(beacon parsing for APdiscovery),
StationMode(the arming sequence: MACID → MSR=STATION →BSSID → RCR filter, ported from the kernel's
hw_var_set_opmodeSTATIONpath),
StationTxDesc(the unicast TX descriptor — BMC=0 enables theACK handshake, the fix that made auth/assoc frames actually get ACKed).
ApfpvStation— the top-level orchestrator:connect()runs thegated scan→arm→auth→assoc→4-way→DHCP→stream chain; a driver-level
supervisor thread auto-reconnects on link loss (deauth or an RX/beacon
timeout), re-arming on the known channel rather than a full rescan.
Also exposes a general-IP bridge (arbitrary IPv4 over the CCMP link, not
just an RTP/video assumption) and a minimal in-order TCP stack over it.
RxDeframe— the station RX pipeline: CCMP decrypt, A-MPDU RXreorder (kernel
recv_indicatepkt_reorderequivalent — required once theAP aggregates; without it, out-of-order subframes are dropped), BlockAck
request handling, and RTP-sequence reordering for the video use case this
was built for.
ApfpvDhcp/LqFeedback— a DHCP client and a link-qualitytelemetry feed.
RtlAdapter):fillH2CCmd/sendH2CPacket(firmware mailbox),setSecCamKey/enableHwSec(securityCAM programming for the PTK/GTK),
sendStationFrameSync(concurrentIN/OUT unicast TX with an ACK-drain check, validated against the
worst-case USB/IP transport),
reset_device.RadioManagementModule/PhydmWatchdog):SetStationRxFilter— the kernel-matched RCR/RXFLTMAPconfiguration station mode needs (the prior permissive filter dropped
management frames the auth/assoc handshake needs); and a close-range
DIG-saturation fix — once linked, track the receiver's gain floor/ceiling
off the live beacon RSSI instead of the always-monitor-mode bounds, or a
strong/close signal storms the false-alarm counter and the front-end goes
deaf (no RX at all) even though the link should be trivially strong.
Caveats / what's not claimed
the one active connection).
ApfpvStation.cppalso contains AP-mode (SoftAP) scaffolding —beaconing, RSSI tracking, and a WPA2 4-way authenticator (the AP side) —
wired onto this repo's own
StartBeacon/StopBeacon. It's explicitlymarked work-in-progress in its own comments: association completion and
the data plane (ARP/ICMP/DHCP responding to an associated client) aren't
there yet, unlike this repo's own
tests/ap_wpa2.cpp/ap_responder.cppharnesses, which do have a working data plane. Happy to split it out of
this PR if you'd rather review the station-mode work on its own — say the
word and I'll drop those commits/functions.
tested against Jaguar2/3/Kestrel chips.
Testing
Built cleanly as a standalone CMake target (
apfpv_station) against thisbranch; also integrated and building end-to-end in a downstream Android app
(PixelPilot) alongside the existing WFB-ng monitor-mode path.