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:
+29
-2
@@ -30,6 +30,8 @@ struct ContentView: View {
|
||||
// Radio state polled from the background worker each tick; a change here
|
||||
// is what re-renders the debug section.
|
||||
@State private var radioState = XONE_STATE_IDLE
|
||||
// Connected controllers (MAC strings), refreshed each tick.
|
||||
@State private var controllers: [String] = []
|
||||
|
||||
private let timer = Timer.publish(every: 1.0, on: .main, in: .common)
|
||||
.autoconnect()
|
||||
@@ -84,6 +86,7 @@ struct ContentView: View {
|
||||
session = nil
|
||||
} else if let s = session {
|
||||
radioState = Int(xone_state(s))
|
||||
refreshControllers(s)
|
||||
}
|
||||
donglePresent = present
|
||||
}
|
||||
@@ -130,6 +133,19 @@ struct ContentView: View {
|
||||
return build.isEmpty ? "not loaded" : build
|
||||
}
|
||||
|
||||
// Query the C API for connected controllers and store their MACs.
|
||||
private func refreshControllers(_ session: OpaquePointer) {
|
||||
let count = Int(xone_controller_count(session))
|
||||
var list: [String] = []
|
||||
for i in 0..<count {
|
||||
var buf = [CChar](repeating: 0, count: 18)
|
||||
if xone_controller_mac(session, Int32(i), &buf, 18) == 0 {
|
||||
list.append(String(cString: buf))
|
||||
}
|
||||
}
|
||||
controllers = list
|
||||
}
|
||||
|
||||
private var statusView: some View {
|
||||
HStack(spacing: 8) {
|
||||
Circle()
|
||||
@@ -144,8 +160,19 @@ struct ContentView: View {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text("Controllers")
|
||||
.font(.headline)
|
||||
Text("No controllers connected.")
|
||||
.foregroundStyle(.secondary)
|
||||
if controllers.isEmpty {
|
||||
Text("No controllers connected.")
|
||||
.foregroundStyle(.secondary)
|
||||
} else {
|
||||
ForEach(controllers, id: \.self) { mac in
|
||||
HStack {
|
||||
Image(systemName: "gamecontroller")
|
||||
.foregroundStyle(.secondary)
|
||||
Text(mac)
|
||||
.font(.system(.body, design: .monospaced))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user