|
|
@@ -251,87 +251,49 @@ end
|
|
|
-- UBUS EVENT LISTENER (TRUE event-driven!)
|
|
|
-- ============================================================================
|
|
|
|
|
|
-local function start_ubus_listen()
|
|
|
+local function start_fast_checker()
|
|
|
if not luv_ok then
|
|
|
log_info("luv not available")
|
|
|
return false
|
|
|
end
|
|
|
|
|
|
- log_info("Starting ubus listen (event-driven)...")
|
|
|
+ log_info("Starting fast state checker (1s)...")
|
|
|
|
|
|
- -- Use ubus listen in background process - this is TRUE event-driven!
|
|
|
- -- ubus listen blocks and emits events when they happen
|
|
|
- local function ubus_listen_loop()
|
|
|
- -- Spawn ubus listen as background process
|
|
|
- -- It will emit JSON events to stdout when DHCP/WiFi events happen
|
|
|
- local pipe = io.popen("ubus listen dhcp ipv4leases network.interface.* hostapd.* 2>&1", "r")
|
|
|
-
|
|
|
- if not pipe then
|
|
|
- log_info("ubus listen failed")
|
|
|
- return false
|
|
|
+ -- Fast timer that checks for state changes
|
|
|
+ -- This is as close to event-driven as we can get without ubus listen
|
|
|
+ local timer = luv.new_timer()
|
|
|
+
|
|
|
+ local function check_changes()
|
|
|
+ -- Check DHCP
|
|
|
+ local current_dhcp = get_dhcp_leases()
|
|
|
+ for mac, info in pairs(current_dhcp) do
|
|
|
+ if not state.dhcp[mac] then
|
|
|
+ on_dhcp_event("add", mac, info.ip, info.hostname)
|
|
|
+ end
|
|
|
end
|
|
|
-
|
|
|
- log_info("ubus listen started - waiting for events...")
|
|
|
-
|
|
|
- -- Read events as they come (blocking but event-driven)
|
|
|
- while true do
|
|
|
- local line = pipe:read("*line")
|
|
|
- if not line then break end
|
|
|
-
|
|
|
- log_info("ubus event: " .. line:sub(1, 200))
|
|
|
-
|
|
|
- -- Parse and handle event
|
|
|
- local event_type = line:match('"type":"([^"]+)"') or "unknown"
|
|
|
-
|
|
|
- if event_type == "ipv4leases" or event_type == "dhcp" then
|
|
|
- -- DHCP event - check for changes
|
|
|
- local current_dhcp = get_dhcp_leases()
|
|
|
- for mac, info in pairs(current_dhcp) do
|
|
|
- if not state.dhcp[mac] then
|
|
|
- on_dhcp_event("add", mac, info.ip, info.hostname)
|
|
|
- end
|
|
|
- end
|
|
|
- for mac, info in pairs(state.dhcp) do
|
|
|
- if not current_dhcp[mac] then
|
|
|
- on_dhcp_event("del", mac, info.ip)
|
|
|
- end
|
|
|
- end
|
|
|
- elseif event_type:match("hostapd") then
|
|
|
- -- WiFi event
|
|
|
- local current_clients = get_wifi_clients()
|
|
|
- for mac, info in pairs(current_clients) do
|
|
|
- if not state.clients[mac] then
|
|
|
- on_wifi_event("connected", mac, info.iface)
|
|
|
- end
|
|
|
- end
|
|
|
- for mac, info in pairs(state.clients) do
|
|
|
- if not current_clients[mac] then
|
|
|
- on_wifi_event("disconnected", mac, info.iface)
|
|
|
- end
|
|
|
- end
|
|
|
+ for mac, info in pairs(state.dhcp) do
|
|
|
+ if not current_dhcp[mac] then
|
|
|
+ on_dhcp_event("del", mac, info.ip)
|
|
|
end
|
|
|
end
|
|
|
|
|
|
- pipe:close()
|
|
|
- log_info("ubus listen ended")
|
|
|
+ -- Check WiFi
|
|
|
+ local current_clients = get_wifi_clients()
|
|
|
+ for mac, info in pairs(current_clients) do
|
|
|
+ if not state.clients[mac] then
|
|
|
+ on_wifi_event("connected", mac, info.iface)
|
|
|
+ end
|
|
|
+ end
|
|
|
+ for mac, info in pairs(state.clients) do
|
|
|
+ if not current_clients[mac] then
|
|
|
+ on_wifi_event("disconnected", mac, info.iface)
|
|
|
+ end
|
|
|
+ end
|
|
|
end
|
|
|
|
|
|
- -- Run ubus listen in background (forked process)
|
|
|
- -- Use shell fork to run in background
|
|
|
- os.execute("ubus listen dhcp ipv4leases network.interface.* hostapd.* 2>&1 &>/dev/null & true")
|
|
|
-
|
|
|
- return true
|
|
|
-end
|
|
|
-
|
|
|
--- Alternative: simple fork without luv.new_task
|
|
|
-local function start_ubus_fork()
|
|
|
- log_info("Starting ubus listen in background...")
|
|
|
-
|
|
|
- -- Fork ubus listen to background
|
|
|
- local pid = io.popen("nohup ubus listen dhcp ipv4leases network.interface.* hostapd.* 2>&1 &", "w")
|
|
|
- if pid then pid:close() end
|
|
|
+ -- Run check every 1 second
|
|
|
+ luv.timer_start(timer, 1000, 1000, check_changes)
|
|
|
|
|
|
- log_info("ubus listen forked to background")
|
|
|
return true
|
|
|
end
|
|
|
|
|
|
@@ -361,10 +323,10 @@ function main()
|
|
|
send_event("router_online", '{"lease_count":' .. count .. '}')
|
|
|
|
|
|
if luv_ok then
|
|
|
- -- Start event-driven listeners
|
|
|
- start_ubus_listen()
|
|
|
+ -- Start fast checker
|
|
|
+ start_fast_checker()
|
|
|
|
|
|
- log_info("Running event loop - waiting for events...")
|
|
|
+ log_info("Running event loop...")
|
|
|
luv.run()
|
|
|
else
|
|
|
-- No luv - just wait
|