diff --git a/src/skyweave.lua b/src/skyweave.lua index 1516d61..34e5b31 100755 --- a/src/skyweave.lua +++ b/src/skyweave.lua @@ -451,15 +451,10 @@ function handlers.set_connect_wifi(params) local bssid = params.bssid local encryption_type = params.encryption -- maps to UCI 'encryption' option local key = params.key - local sta_device = params.device or "radio0" -- The physical radio for the STA interface (e.g., radio0) + local sta_device = params.device or "radio0" -- The physical radio for the STA interface (e.g., radio0) - -- The UCI section for the Wi-Fi STA interface is typically 'wwan' in your config. - -- If it's a dynamically generated section name like 'cfgXYZ', this would need adjustment, - -- but 'wireless.wwan' is a common convention for the primary client interface. - local sta_uci_section = "wireless.wwan" - -- The ifname for this STA section, often 'vif-sta0' or derived. - -- Your uci_show.txt uses 'vif-sta0' for wireless.wwan.ifname. - local sta_ifname = "vif-sta0" + local sta_uci_section = "wireless.wwan" -- The UCI section for the Wi-Fi STA interface is typically 'wwan' + local sta_ifname = "vif-sta0" -- The ifname for this STA section, often 'vif-sta0' or derived. if not ssid or ssid == "" then return { errCode = -30, errMsg = "SSID is required for Wi-Fi connection.", configDone = false } @@ -501,16 +496,8 @@ function handlers.set_connect_wifi(params) elseif encryption_type == "wep-open" or encryption_type == "wep-shared" or encryption_type == "wep" then uci_run("uci set " .. sta_uci_section .. ".encryption=" .. (encryption_type == "wep" and "wep-open" or encryption_type)) -- Default WEP to wep-open uci_run("uci set " .. sta_uci_section .. ".key='" .. (key or "") .. "'") - -- For WEP, you might need to set 'key' if specific key index is used. - -- uci_run("uci set " .. sta_uci_section .. ".key1='" .. (key or "") .. "'") -- Example if key1 is used - -- uci_run("uci set " .. sta_uci_section .. ".key_index=1") else - -- Unknown encryption type, default to 'none' or return an error - -- For safety, defaulting to 'none' and no key. - uci_run("uci set " .. sta_uci_section .. ".encryption=none") - uci_run("uci delete " .. sta_uci_section .. ".key") - -- Optionally, return an error for unsupported types: - -- return { errCode = -31, errMsg = "Unsupported encryption type: " .. tostring(encryption_type), configDone = false } + return { errCode = -31, errMsg = "Unsupported encryption type: " .. tostring(encryption_type) } end -- 2. Configure the Network WAN Interface @@ -530,16 +517,15 @@ function handlers.set_connect_wifi(params) uci_run("uci commit network") -- 4. Apply Changes by Reloading Services - -- This sequence generally works well. - uci_run("wifi reload") -- Reloads wireless configuration and drivers - os.execute("sleep 3") -- Brief pause to allow wifi to settle (optional but can help) - uci_run("/etc/init.d/network reload") -- Reloads network configuration, brings WAN up + -- uci_run("wifi reload") -- Reloads wireless configuration and drivers + -- os.execute("sleep 3") -- Brief pause to allow wifi to settle (optional but can help) + -- uci_run("/etc/init.d/network reload") -- Reloads network configuration, brings WAN up + uci_run("/etc/init.d/network restartall") -- Return success return { errCode = 0, - errMsg = "OK (Wi-Fi connection process initiated for SSID: " .. ssid .. ")", - configDone = true -- Indicates a configuration change was made and applied + errMsg = "OK (Wi-Fi connection process initiated for SSID: " .. ssid .. ")" } end @@ -548,64 +534,98 @@ end ----------------------------------------------------------------------- -- Get request method and query string -local request_method = os.getenv("REQUEST_METHOD") +local http_method = os.getenv("REQUEST_METHOD") local query_string = os.getenv("QUERY_STRING") local request_params = {} +local post_params = {} if query_string then request_params = parse_query_string(query_string) end +-- Parse POST body if it's a POST request +if http_method == "POST" then + local post_data_str = io.stdin:read("*a") + if post_data_str and post_data_str ~= "" then + -- Assuming JSON payload for POST as per your API design + local status, decoded_data = pcall(json.decode, post_data_str) + if status then + post_params = decoded_data + else + send_error_response("Invalid JSON in POST body: " .. tostring(decoded_data), -50, "400 Bad Request") + return -- Stop script execution + end + else + -- Some POST actions might not have a body, or you might require one. + -- send_error_response("Empty POST body.", -51, "400 Bad Request") + -- return + end +end --- Determine the main action and the specific section/command -local main_action_key = nil -local requested_endpoint_name = nil --- Example: Prioritize 'get_config', then 'set_config', etc. -if request_params.get_config then - main_action_key = "get_" .. request_params.get_config - requested_endpoint_name = request_params.get_config -elseif request_params.set_config then - main_action_key = "set_" .. request_params.set_config - requested_endpoint_name = request_params.set_config - -- Add more top-level actions like 'get_status', 'run_action' -elseif request_params.method == "GET" and request_params.section then -- For compatibility with mbox-config style - main_action_key = "get_" .. request_params.section -- You might prefix it like handlers.get_guide_config - requested_endpoint_name = request_params.section - -- Potentially map "get_guide_config" to a function named "handlers.get_guide_config" - -- Or simply use request_params.section as the key if your handlers are named that way. +local handler_name_to_call = nil +local params_for_handler = {} + +if http_method == "GET" then + if request_params.get_config then + handler_name_to_call = "get_" .. request_params.get_config + params_for_handler = request_params + elseif request_params.get_status then -- Example for another GET type + handler_name_to_call = "get_" .. request_params.get_status + params_for_handler = request_params + elseif request_params.get_log then -- For your get_system_log_parsed + handler_name_to_call = "get_system_log_parsed" -- Or construct as "get_log_" .. request_params.get_log + params_for_handler = request_params + elseif request_params.action == "get_wifi_scan" and request_params.ifname then -- For wifi_scan + handler_name_to_call = "get_wifi_scan" + params_for_handler = request_params + -- Legacy mbox-config style GET + elseif request_params.method == "GET" and request_params.section then + handler_name_to_call = "get_" .. request_params.section + params_for_handler = request_params + else + send_error_response("No valid GET action/parameters specified.", -1, "400 Bad Request") + return + end +elseif http_method == "POST" then + -- For POST, you need a way to determine which action to perform. + -- This could be a field in the JSON body, or part of the query string even for POST. + -- Let's assume the client will POST to /skyweave.lua?set_action=connect_wifi + -- and the body will contain the ssid, bssid, encryption, key. + + if request_params.set_action == "connect_wifi" then + handler_name_to_call = "set_connect_wifi" + -- The C code expected parameters within a "motorhome" table. + -- If your client sends data directly, use post_params. + -- If your client sends {"motorhome": {ssid:..., key:...}}, use post_params.motorhome + if post_params.motorhome and type(post_params.motorhome) == "table" then + params_for_handler = post_params.motorhome + else + params_for_handler = post_params -- Assume direct parameters + end + -- Add other POST actions here + -- elseif request_params.set_action == "reboot_device" then + -- handler_name_to_call = "set_reboot_device" + -- params_for_handler = post_params + else + send_error_response("No valid POST action specified.", -52, "400 Bad Request") + return + end else - send_error_response("No valid action specified.", -1, "400 Bad Request") - return -- Stop script execution + send_error_response("Unsupported HTTP method: " .. tostring(http_method), -53, "405 Method Not Allowed") + return end -- Dispatch to the appropriate handler --- You might want to make the handler key more specific if needed, e.g., "get_guide_config" --- For this example, let's assume handlers are named like "get_guide_config", "get_lte_status" --- And your query might be ?get_config=guide_config or ?get_status=lte --- So, main_action_key would be, for example, `get_guide_config` - --- A more direct mapping if your handler table keys match the value of get_config/get_status: --- Example: ?get_config=guide_config --> handler_key = "guide_config" --- function_to_call = handlers[handler_key] - -local actual_handler_key_parts = {} -if request_params.get_config then - actual_handler_key_parts[#actual_handler_key_parts + 1] = "get" - actual_handler_key_parts[#actual_handler_key_parts + 1] = request_params.get_config -elseif request_params.get_status then - actual_handler_key_parts[#actual_handler_key_parts + 1] = "get" - actual_handler_key_parts[#actual_handler_key_parts + 1] = request_params.get_status -end --- Add other primary actions (set_config, run_action) - --- Construct the handler name, e.g. "get_guide_config" -local handler_name_to_call = table.concat(actual_handler_key_parts, "_") - - -if handlers[handler_name_to_call] then - local result_data = handlers[handler_name_to_call](request_params) - send_json_response(result_data) +if handler_name_to_call and handlers[handler_name_to_call] then + local result_data = handlers[handler_name_to_call](params_for_handler) + if result_data then -- Ensure handler returned something + send_json_response(result_data) + else + -- This case occurs if a handler doesn't return anything (or returns nil explicitly) + -- which usually indicates an internal error or an unhandled path in the handler. + send_error_response("Handler executed but returned no data: " .. handler_name_to_call, -5, "500 Internal Server Error") + end else - send_error_response("Endpoint not found: " .. (handler_name_to_call or "N/A"), -2, "404 Not Found") + send_error_response("Endpoint not found or action not supported: " .. (handler_name_to_call or "N/A"), -2, "404 Not Found") end \ No newline at end of file