From 7151cf49971de070c750e613f96a45efacb5bf5f Mon Sep 17 00:00:00 2001 From: Nourrisse Florian Date: Wed, 22 Apr 2026 18:38:19 +0200 Subject: [PATCH] fix(ios): wire Wi-Fi config characteristic + actually push creds on Confirm Two stub-level gaps in the open-source app prevented the pairing from ever completing: 1. AppState.swift never maps the E2E5E5E3 (Config) characteristic to BlufiUtil.writeWifiSetCharacteristic. Without the mapping, any attempt to sendWifiSetData() early-returns with "No writable characteristic". 2. BindingDevice.confirmWifi() only flipped the pairingStatus to DistributionNetwork and then ChangeTheName after a 1s delay, without ever writing anything over BLE. The firmware never received the Wi-Fi credentials, the StackChan stayed offline. Fix: - Assign writeWifiSetCharacteristic when the E2E5E5E3 characteristic is discovered during the GATT service scan. - Serialise {"ssid":..., "password":...} as JSON in confirmWifi and send it via BlufiUtil.sendWifiSetData before animating the UI progression. The firmware handler (hal_ble.cpp: _handle_ble_config_write) parses this exact shape. Both fixes live on self-host for now; they should also land upstream. --- app/StackChan/AppState.swift | 11 +++++++++-- app/StackChan/View/BindingDevice.swift | 23 +++++++++++++++++++---- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/app/StackChan/AppState.swift b/app/StackChan/AppState.swift index 974990b..9583db4 100644 --- a/app/StackChan/AppState.swift +++ b/app/StackChan/AppState.swift @@ -76,16 +76,23 @@ class AppState: ObservableObject { } BlufiUtil.shared.characteristicCallback = { characteristic in if characteristic.properties.contains(.write) || characteristic.properties.contains(.writeWithoutResponse) { - + if characteristic.uuid.uuidString == "E2E5E5E2-1234-5678-1234-56789ABCDEF0" { BlufiUtil.shared.writeExpressionCharacteristic = characteristic print("✏️ Expression writable characteristic assigned: \(characteristic.uuid)") } - + if characteristic.uuid.uuidString == "E2E5E5E1-1234-5678-1234-56789ABCDEF0" { BlufiUtil.shared.writeHeadCharacteristic = characteristic print("✏️ Head writable characteristic assigned: \(characteristic.uuid)") } + + // Config characteristic — used for Wi-Fi provisioning (SSID + password JSON) + // during pairing. Firmware handler is _handle_ble_config_write in hal_ble.cpp. + if characteristic.uuid.uuidString == "E2E5E5E3-1234-5678-1234-56789ABCDEF0" { + BlufiUtil.shared.writeWifiSetCharacteristic = characteristic + print("✏️ Config/Wifi writable characteristic assigned: \(characteristic.uuid)") + } } } } diff --git a/app/StackChan/View/BindingDevice.swift b/app/StackChan/View/BindingDevice.swift index fff7c02..dfdb60b 100644 --- a/app/StackChan/View/BindingDevice.swift +++ b/app/StackChan/View/BindingDevice.swift @@ -279,23 +279,38 @@ struct ScanningEquipment : View { } private func confirmWifi() { - + if !BlufiUtil.shared.blueSwitch { appState.alertTitle = "Please turn on Bluetooth" appState.showAlert = true return } - + if wifiName.isEmpty || wifiPassword.isEmpty { appState.alertTitle = "Please enter Wi-Fi name and password" appState.showAlert = true return } - + + // Push the Wi-Fi credentials to the StackChan over BLE. + // The firmware expects {"ssid":..., "password":...} on the Config + // characteristic (see hal_ble.cpp:_handle_ble_config_write). + let payload: [String: String] = [ + "ssid": wifiName, + "password": wifiPassword, + ] + if let data = try? JSONSerialization.data(withJSONObject: payload), + let json = String(data: data, encoding: .utf8) { + BlufiUtil.shared.sendWifiSetData(json) + print("➡️ Wi-Fi credentials sent to device") + } else { + print("⚠️ Failed to serialise Wi-Fi payload") + } + withAnimation{ pairingStatus = .DistributionNetwork } - + DispatchQueue.main.asyncAfter(deadline: .now() + 1) { withAnimation{ pairingStatus = .ChangeTheName