fix: never re-enable SSID pool broadcast (crash guard) + top-bar health chip

Mode 'active' and the advertise toggle could re-enable the SSID-pool
broadcast that segfaults pineapd. active preset now skips ssidpool/enable
(advertise stays false), the advertise endpoint refuses with an
explanation when the pool is disabled, get_ap reports the real pool
state, and the PineAP overview disables the toggle with a notice. Added
a top-bar health chip (PINEAP OK / POOL OFF / PINEAPD DOWN) polled every
15s.
This commit is contained in:
2026-08-18 20:16:41 -05:00
parent 0cd9956c4c
commit d10fba9d1b
6 changed files with 69 additions and 13 deletions
@@ -2581,7 +2581,8 @@ def h_pineap_wifi_get_ap(ctx):
'channel': _ent_summary()['channel'],
'live': _ent_summary()['live'],
},
'pool': {'disabled': None, 'collecting': bool(pinecfg.get('autossidpool'))},
'pool': {'disabled': pool.get('disable') == '1',
'collecting': bool(pinecfg.get('autossidpool'))},
'radios': {
'radio0': _radio_dict('radio0'),
'radio1': _radio_dict('radio1'),
@@ -2759,6 +2760,13 @@ def h_pineap_wifi_set_ap(ctx):
def h_pineap_advertise(ctx):
enable = bool((ctx.body or {}).get('enable'))
if enable:
# The SSID-pool broadcast segfaults pineapd on this firmware; the
# pool stays disabled or the crash-loop returns.
pool = _uci_section('pineapd.@ssidpool[0]')
if pool.get('disable') == '1':
return 400, {'error': 'SSID pool broadcast is disabled on this firmware '
'(pineapd SIGSEGV crash-loop) and cannot be re-enabled'}
status, data = _daemon_proxy('POST', 'ssidpool/enable' if enable else 'ssidpool/disable', {'enable': enable})
if status == 200:
update_pineap_state(mode='advanced', advertise=enable)
@@ -3911,16 +3919,16 @@ def h_pineap_mode_post(ctx):
(('enable' if enabled else 'disable') + ' PineAP response engine',
'PUT', 'hostapd/enable_pineap', {'enable': enabled}),
('enable SSID collection', 'POST', 'ssidpool/enable_collect', {'enable': True}),
(('enable' if mode == 'active' else 'disable') + ' SSID pool broadcasting',
'POST', 'ssidpool/enable' if mode == 'active' else 'ssidpool/disable',
{'enable': mode == 'active'}),
]
# NOTE: the SSID-pool broadcast step is intentionally omitted. The pool
# broadcast segfaults pineapd on this firmware (SIGSEGV crash-loop); the
# health monitor disables it and 'active' must not re-enable it.
for label, method, path, body in steps:
status, data = _daemon_proxy(method, path, body)
if status != 200:
return status, {'error': 'failed to ' + label, 'detail': data}
return 200, update_pineap_state(mode=mode, enabled=enabled, karma=enabled,
collect=True, advertise=(mode == 'active'))
collect=True, advertise=False)
def h_filter_get(ctx, kind):