Modified logic for /network_config to return currently associated BSSID instead of pulling from UCI. Added /SOS GET endpoint for easily directing the unit to connect to any campground wireless AP in a pinch.
This commit is contained in:
@@ -50,6 +50,7 @@ local success, load_result = pcall(function()
|
|||||||
|
|
||||||
router:add_route("GET", "/network_config", network_handlers.get_network_config)
|
router:add_route("GET", "/network_config", network_handlers.get_network_config)
|
||||||
router:add_route("POST", "/connect_wifi", network_handlers.set_connect_wifi)
|
router:add_route("POST", "/connect_wifi", network_handlers.set_connect_wifi)
|
||||||
|
router:add_route("GET", "/SOS", network_handlers.set_connect_wifi_sos)
|
||||||
router:add_route("GET", "/wifi_scan", wifi_handlers.get_wifi_scan)
|
router:add_route("GET", "/wifi_scan", wifi_handlers.get_wifi_scan)
|
||||||
router:add_route("GET", "/system_log_parsed", system_handlers.get_system_log_parsed)
|
router:add_route("GET", "/system_log_parsed", system_handlers.get_system_log_parsed)
|
||||||
|
|
||||||
|
|||||||
@@ -15,14 +15,19 @@ function network_handler.get_network_config(request_context)
|
|||||||
-- get_live_interface_info returns: address, mask, device, leasetime, error_message
|
-- get_live_interface_info returns: address, mask, device, leasetime, error_message
|
||||||
local live_wan_ip, live_wan_netmask, ifname, dhcp_lease_time, err_msg_live_info = utils.get_live_interface_info(iface)
|
local live_wan_ip, live_wan_netmask, ifname, dhcp_lease_time, err_msg_live_info = utils.get_live_interface_info(iface)
|
||||||
|
|
||||||
|
local station_info, err = utils.get_station_dump_info("vif-sta0")
|
||||||
|
|
||||||
-- Handle potential error from get_live_interface_info if needed, e.g. log err_msg_live_info
|
-- Handle potential error from get_live_interface_info if needed, e.g. log err_msg_live_info
|
||||||
|
|
||||||
local response_data = { errCode = 0, errMsg = "OK"}
|
local response_data = { errCode = 0, errMsg = "OK"}
|
||||||
response_data.wwan = {
|
response_data.wwan = {
|
||||||
ssid = utils.uci_get("wireless.wwan.ssid") or "",
|
ssid = utils.uci_get("wireless.wwan.ssid") or "",
|
||||||
bssid = utils.uci_get("wireless.wwan.bssid") or "",
|
bssid = station_info.bssid or "",
|
||||||
|
tx_rate = station_info["tx bitrate"],
|
||||||
|
rx_rate = station_info["rx bitrate"],
|
||||||
|
expected_throughput = station_info["expected throughput"],
|
||||||
encryption = utils.uci_get("wireless.wwan.encryption") or "",
|
encryption = utils.uci_get("wireless.wwan.encryption") or "",
|
||||||
key = utils.uci_get("wireless.wwan.key") or "", -- Consider redacting this for a GET
|
key = utils.uci_get("wireless.wwan.key") or "",
|
||||||
device = utils.uci_get("wireless.wwan.device") or "",
|
device = utils.uci_get("wireless.wwan.device") or "",
|
||||||
wan_dns1 = live_dns_list and live_dns_list[1] or "",
|
wan_dns1 = live_dns_list and live_dns_list[1] or "",
|
||||||
wan_dns2 = live_dns_list and live_dns_list[2] or "",
|
wan_dns2 = live_dns_list and live_dns_list[2] or "",
|
||||||
@@ -46,6 +51,33 @@ function network_handler.get_network_config(request_context)
|
|||||||
return response_data
|
return response_data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- =============================================================================
|
||||||
|
-- The Litany of Safe Return (SOS Function)
|
||||||
|
-- Invokes the standard connect function with a predefined, known-good network.
|
||||||
|
-- This is a GET endpoint for easy invocation from a browser in an emergency.
|
||||||
|
-- =============================================================================
|
||||||
|
function network_handler.set_connect_wifi_sos(request_context)
|
||||||
|
-- This function acts as a "panic" button to revert to a known-good WiFi network.
|
||||||
|
-- It simulates a request to the set_connect_wifi function with hardcoded values.
|
||||||
|
|
||||||
|
local sos_defaults = {
|
||||||
|
ssid = "NittanyMtnKOA",
|
||||||
|
bssid = "", -- Leave blank to connect to the strongest signal
|
||||||
|
encryption = "none",
|
||||||
|
key = "",
|
||||||
|
device = "radio0"
|
||||||
|
}
|
||||||
|
|
||||||
|
-- We must construct a mock 'request_context' to pass to the original function.
|
||||||
|
local mock_request_context = {
|
||||||
|
body = sos_defaults,
|
||||||
|
query = {}, -- Not used by set_connect_wifi
|
||||||
|
headers = {} -- Not used by set_connect_wifi
|
||||||
|
}
|
||||||
|
|
||||||
|
return network_handler.set_connect_wifi(mock_request_context)
|
||||||
|
end
|
||||||
|
|
||||||
-- Original: function handlers.set_connect_wifi(params) -> params was POST data
|
-- Original: function handlers.set_connect_wifi(params) -> params was POST data
|
||||||
function network_handler.set_connect_wifi(request_context)
|
function network_handler.set_connect_wifi(request_context)
|
||||||
-- Parameters from POST body
|
-- Parameters from POST body
|
||||||
|
|||||||
@@ -251,4 +251,61 @@ function utils.get_default_gateway_from_route()
|
|||||||
return gateway_ip, interface_name
|
return gateway_ip, interface_name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- =============================================================================
|
||||||
|
-- A new litany to parse the data-psalms of 'iw dev station dump'
|
||||||
|
-- Transmutes the raw text into a structured Lua table.
|
||||||
|
-- @param interface_name (string) The wireless interface to query (e.g., "vif-sta0")
|
||||||
|
-- @return (table) A table of the parsed station data, or (nil, string) on failure.
|
||||||
|
-- =============================================================================
|
||||||
|
function utils.get_station_dump_info(interface_name)
|
||||||
|
-- The cogitator must be told which interface to query.
|
||||||
|
if not interface_name or interface_name == "" then
|
||||||
|
return nil, "Interface name not provided to get_station_dump_info"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Invoke the 'iw' command to receive the data-psalm.
|
||||||
|
local command = "iw dev " .. interface_name .. " station dump"
|
||||||
|
-- This assumes the existence of your self.execute_command function.
|
||||||
|
local output = utils.execute_command(command)
|
||||||
|
|
||||||
|
-- If the machine spirit offers no response, we can proceed no further.
|
||||||
|
if not output or output == "" then
|
||||||
|
return nil, "No output from station dump command for interface: " .. interface_name
|
||||||
|
end
|
||||||
|
|
||||||
|
-- A table to hold the sacred data extracted from the psalm.
|
||||||
|
local station_data = {}
|
||||||
|
|
||||||
|
-- A local incantation to cleanse data of superfluous void-space (whitespace).
|
||||||
|
local function trim(s)
|
||||||
|
return s:match("^%s*(.-)%s*$")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Process the data-psalm, one verse at a time.
|
||||||
|
for line in string.gmatch(output, "([^\n]*)\n?") do
|
||||||
|
-- This verse is unique, a declaration of the Station's primary sigil (BSSID).
|
||||||
|
if line:find("^Station") then
|
||||||
|
local bssid = line:match("Station (%x%x:%x%x:%x%x:%x%x:%x%x:%x%x)")
|
||||||
|
if bssid then
|
||||||
|
station_data["bssid"] = bssid
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- All other verses follow the 'Key: Value' doctrine.
|
||||||
|
local key, value = line:match("^%s*(.-):%s*(.*)$")
|
||||||
|
if key and value then
|
||||||
|
-- Inscribe the cleansed key and value into our data table.
|
||||||
|
station_data[trim(key)] = trim(value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If, after parsing, no data was sanctified, the process has failed.
|
||||||
|
if not next(station_data) then
|
||||||
|
return nil, "Failed to parse any valid data from station dump output."
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Return the blessed table of structured data.
|
||||||
|
return station_data
|
||||||
|
end
|
||||||
|
|
||||||
return utils
|
return utils
|
||||||
|
|||||||
Reference in New Issue
Block a user