feat: pair controllers and show them in the app

Port the MT76 client functions (send_wlan, associate_client,
pair_client, set_client_key, remove_client) and wire the RX dispatch
into the session: EP IN frames are parsed, ASSOC_REQ associates a
controller (WCID plus chip programming), PAIR_REQ replies with
PAIR_RESP, and DISASSOC or client-lost removes it. The C API exposes
connected controllers and the app lists them by MAC. Bumps
xone_cli/xone_app to C++23: they were falling back to the default
standard once mt76.hpp started using std::span. Adds a unit test pinning
the WCID regions, the 32-byte rxwi, and the new frame control values.

Co-Authored-By: qwen3.8-27b@q2_k_xl: client functions, RX dispatch, GUI list
This commit is contained in:
portersky
2026-08-17 20:40:47 +02:00
parent b3e747b900
commit dae51f085b
9 changed files with 682 additions and 7 deletions
+33 -1
View File
@@ -12,6 +12,7 @@
#include <array>
#include <cstddef>
#include <cstdint>
#include <span>
#include "mt76/mt76_defs.hpp"
@@ -55,7 +56,7 @@ public:
auto select_function(std::uint32_t func, std::uint32_t val) -> int;
auto set_power_mode(power_mode mode) -> int;
auto load_cr(cr_mode mode) -> int;
auto write_burst(std::uint32_t idx, void *data, std::size_t len) -> int;
auto write_burst(std::uint32_t idx, void const *data, std::size_t len) -> int;
auto send_ms_command(ms_command cmd, void *data, std::size_t len) -> int;
auto calibrate(calibration calib, std::uint32_t val) -> int;
@@ -69,6 +70,37 @@ public:
// Enter or leave pairing mode (port of xone_mt76_set_pairing).
auto set_pairing(bool enable) -> int;
// Controller association and data path (ports of the xone_mt76_* client
// functions). `addr` is a 6-byte controller MAC.
//
// send_wlan prepends a TXWI and frames the payload as an MCU message,
// then bulk-writes it to EP OUT.
auto send_wlan(std::span<std::uint8_t const> frame) -> int;
// Associate a controller: program its WCID MAC, ADD_CLIENT ms_command,
// and transmit an ASSOC_RESP mgmt frame.
auto associate_client(std::uint8_t wcid, std::span<std::uint8_t const> addr)
-> int;
// Reply to a pairing request with a PAIR_RESP mgmt frame.
auto pair_client(std::span<std::uint8_t const> addr) -> int;
// Send a reserved (0x70) management command to a client, waiting for an
// acknowledgment (port of xone_mt76_send_client_command).
auto send_client_command(std::uint8_t wcid,
std::span<std::uint8_t const> addr,
client_cmd cmd,
std::span<std::uint8_t const> data) -> int;
// Install the per-client AES-CCMP key (16 bytes) in the chip WCID
// registers (port of xone_mt76_set_client_key).
auto set_client_key(std::uint8_t wcid, std::span<std::uint8_t const> key)
-> int;
// Remove a client: REMOVE_CLIENT ms_command and zero its WCID regions
// (port of xone_mt76_remove_client).
auto remove_client(std::uint8_t wcid) -> int;
private:
// Send an MCU command (port of xone_mt76_send_command). `cmd` is the
// MT_MCU_MSG_CMD_TYPE field. Returns bytes written, or a negative errno.