From 7536f3ca4517513f9064cfe4c3749bfb0a81b70e Mon Sep 17 00:00:00 2001 From: c4ch3c4d3 Date: Tue, 18 Aug 2026 08:08:50 -0500 Subject: [PATCH] fix: self-heal radio1 AP after stock daemon wireless writes --- .../user/remote_access/pager-webui/server.py | 6 ++++ tests/test_pineap_bands.py | 29 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/payload/user/remote_access/pager-webui/server.py b/payload/user/remote_access/pager-webui/server.py index 6339ba8..0044a4d 100644 --- a/payload/user/remote_access/pager-webui/server.py +++ b/payload/user/remote_access/pager-webui/server.py @@ -1682,6 +1682,11 @@ def h_pineap_wifi_get_ap(ctx): pinecfg = data2 if status2 == 200 and isinstance(data2, dict) else {} pool = _uci_section('pineapd.@ssidpool[0]') radio1 = _uci_wifi_iface('radio1') + for name in ('wlan1open', 'wlan1wpa'): + cfg = _uci_wifi_iface(name) + if cfg and cfg.get('disabled') != '1' and not os.path.exists('/sys/class/net/%s' % name): + device_run(['wifi', 'reload']) + break return 200, { 'open': { 'enabled': open_cfg.get('disabled') == '0', @@ -1793,6 +1798,7 @@ def _apply_radio1_ap(openap, wpa): device_run(['uci', 'set', 'wireless.%s=wifi-iface' % iface]) device_run(['uci', 'set', 'wireless.%s.device=radio1' % iface]) device_run(['uci', 'set', 'wireless.%s.mode=ap' % iface]) + device_run(['uci', 'set', 'wireless.%s.ifname=%s' % (iface, iface)]) device_run(['uci', 'set', 'wireless.%s.ssid=%s' % (iface, cfg.get('ssid') or '')]) device_run(['uci', 'set', 'wireless.%s.hidden=%d' % (iface, 1 if cfg.get('hidden') else 0)]) device_run(['uci', 'set', 'wireless.%s.channel=%d' % (iface, int(cfg.get('channel')))]) diff --git a/tests/test_pineap_bands.py b/tests/test_pineap_bands.py index f9d24f0..cda5a26 100644 --- a/tests/test_pineap_bands.py +++ b/tests/test_pineap_bands.py @@ -292,5 +292,34 @@ class GetApRadioChannelFallbackTest(unittest.TestCase): self.assertEqual(payload['wpa']['channel'], 11) +class GetApReconcileTest(unittest.TestCase): + def setUp(self): + self.uci = {'wlan1wpa': {'device': 'radio1', 'mode': 'ap', 'ssid': 'Corp', + 'disabled': '0', 'encryption': 'sae', 'channel': '36'}} + self.runs = [] + server._uci_wifi_iface = lambda name: dict(self.uci.get(name, {})) + server._uci_section = lambda name: {} + server.daemon_sock_call = lambda method, path, body=None, timeout=10: ( + 404, {'error': 'not found'}) + server.device_run = lambda args, timeout=20, input_data=None: ( + self.runs.append(list(args)) or (0, '', '')) + + def test_missing_netdev_triggers_wifi_reload(self): + server.os.path.exists = lambda p: False + server.h_pineap_wifi_get_ap(ctx()) + self.assertIn(['wifi', 'reload'], self.runs) + + def test_present_netdev_skips_reload(self): + server.os.path.exists = lambda p: True + server.h_pineap_wifi_get_ap(ctx()) + self.assertNotIn(['wifi', 'reload'], self.runs) + + def test_disabled_section_skips_reload(self): + self.uci['wlan1wpa']['disabled'] = '1' + server.os.path.exists = lambda p: False + server.h_pineap_wifi_get_ap(ctx()) + self.assertNotIn(['wifi', 'reload'], self.runs) + + if __name__ == '__main__': unittest.main()