0
0
mirror of https://github.com/Doodle3D/doodle3d-firmware.git synced 2024-06-26 03:21:22 +02:00

First attempt to add a post response function queue

This commit is contained in:
peteruithoven 2013-09-02 15:01:16 +02:00
parent a732e4890f
commit 3c59322cf7
4 changed files with 113 additions and 66 deletions

View File

@ -20,20 +20,20 @@ local function setupAutoWifiMode()
end
return nil
end
local wifiState = wifi.getDeviceState()
local netName, netMode = wifiState.ssid, wifiState.mode
local apSsid = wifi.getSubstitutedSsid(settings.get('network.ap.ssid'))
local apMode = (apSsid == netName) and netMode == 'ap'
local scanList,msg = wifi.getScanInfo()
local knownSsids = wifi.getConfigs()
if not scanList then
return nil, "autowifi: could not scan wifi networks (" .. msg .. ")"
end
log:info("current wifi name/mode: " .. (netName or "<nil>") .. "/" .. netMode .. ", ssid of self: " .. apSsid)
local visNet, knownNet = {}, {}
for _,sn in ipairs(scanList) do
@ -44,12 +44,12 @@ local function setupAutoWifiMode()
end
log:info("visible networks: " .. table.concat(visNet, ", "))
log:info("known networks: " .. table.concat(knownNet, ", "))
-- if the currently active network is client mode and is also visible, do nothing since it will connect automatically further along the boot process
if netMode == 'sta' and netName ~= nil and netName ~= "" and findSsidInList(scanList, netName) then
return true, "autowifi: no action - existing configuration found for currently wifi visible network (" .. netName .. ")"
end
-- try to find a known network which is also visible (ordered by known network definitions)
local connectWith = nil
for _,kn in ipairs(knownSsids) do
@ -58,7 +58,7 @@ local function setupAutoWifiMode()
break
end
end
if connectWith then
local rv,msg = netconf.associateSsid(connectWith)
if rv then
@ -76,18 +76,18 @@ local function setupAutoWifiMode()
else
return true, "autowifi: no action - no known networks found, already in access point mode"
end
return nil, "autowifi: uh oh - bad situation in autowifi function"
end
local function setupLogger()
local logStream = io.stderr -- use stderr as hard-coded default target
local logLevel = log.LEVEL.debug -- use debug logging as hard-coded default level
local logTargetSetting = settings.getSystemKey('logfile')
local logLevelSetting = settings.getSystemKey('loglevel')
local logTargetError, logLevelError = nil, nil
if type(logTargetSetting) == 'string' then
local specialTarget = logTargetSetting:match('^<(.*)>$')
if specialTarget then
@ -96,13 +96,13 @@ local function setupLogger()
end
elseif logTargetSetting:sub(1, 1) == '/' then
local f,msg = io.open(logTargetSetting, 'a+')
if f then logStream = f
else logTargetError = msg
end
end
end
if type(logLevelSetting) == 'string' and logLevelSetting:len() > 0 then
local valid = false
for idx,lvl in ipairs(log.LEVEL) do
@ -113,59 +113,59 @@ local function setupLogger()
end
if not valid then logLevelError = true end
end
log:init(logLevel)
log:setStream(logStream)
local rv = true
if logTargetError then
log:error("could not open logfile '" .. logTargetSetting .. "', using stderr as fallback (" .. logTargetError .. ")")
rv = false
end
if logLevelError then
log:error("uci config specifies invalid log level '" .. logLevelSetting .. "', using debug level as fallback")
rv = false
end
return rv
end
local function init(environment)
setupLogger()
local dbgText = ""
if confDefaults.DEBUG_API and confDefaults.DEBUG_PCALLS then dbgText = "pcall and api"
elseif confDefaults.DEBUG_API then dbgText = "api"
elseif confDefaults.DEBUG_PCALL then dbgText = "pcall"
end
if dbgText ~= "" then dbgText = " (" .. dbgText .. " debugging enabled)" end
log:info("Wifibox CGI handler started" .. dbgText)
if (environment['REQUEST_METHOD'] == 'POST') then
local n = tonumber(environment['CONTENT_LENGTH'])
postData = io.read(n)
end
local s, msg
s, msg = wifi.init()
if not s then return s, msg end
s, msg = netconf.init(wifi, true)
if not s then return s, msg end
return true
end
local function main(environment)
local rq = RequestClass.new(environment, postData, confDefaults.DEBUG_API)
if rq:getRequestMethod() == 'CMDLINE' and rq:get('autowifi') ~= nil then
log:info("running in autowifi mode")
local rv,msg = setupAutoWifiMode()
if rv then
log:info("autowifi setup done (" .. msg .. ")")
else
@ -180,11 +180,19 @@ end
log:info("remote IP/port: " .. rq:getRemoteHost() .. "/" .. rq:getRemotePort())
log:debug("user agent: " .. rq:getUserAgent())
end
local response, err = rq:handle()
local utils = require('util.utils')
local log = require('util.logger')
log:info("Main (request handled")
log:info(" response.postResponseQueue: "..utils.dump(response.postResponseQueue))
if err ~= nil then log:error(err) end
response:send()
response:executePostResponseQueue()
else
log:info("Nothing to do...bye.\n")
end
@ -199,15 +207,15 @@ end
-- @treturn number A Z+ return value suitable to return from wrapper script. Note that this value is ignored by uhttpd-mod-lua.
function handle_request(env)
local s, msg = init(env)
if s == false then
local resp = ResponseClass.new()
local errSuffix = msg and " (" .. msg .. ")" or ""
resp:setError("initialization failed" .. errSuffix)
resp:send()
log:error("initialization failed" .. errSuffix) --NOTE: this assumes the logger has been initialized properly, despite init() having failed
return 1
else
main(env)

View File

@ -43,7 +43,7 @@ end
-- and additionally: wifiiface/add, network/reload
function M.switchConfiguration(components)
local dirtyList = {} -- laundry list, add config/script name as key with value c (commit), r (reload) or b (both)
for k,v in pairs(components) do
local fname = k .. '_' .. v
if type(reconf[fname]) == 'function' then
@ -53,7 +53,7 @@ function M.switchConfiguration(components)
log:warn("unknown component or action '" .. fname .. "' skipped")
end
end
-- first run all commits, then perform reloads
for k,v in pairs(dirtyList) do
if v == 'c' or v == 'b' then M.commitComponent(k) end
@ -105,7 +105,7 @@ function reconf.apnet_add(dirtyList, noReload)
if s.ssid == ourSsid then sname = s['.name']; return false end
end)
if sname == nil then sname = uci:add('wireless', 'wifi-iface') end
M.uciTableSet('wireless', sname, {
network = wifi.NET,
ssid = ourSsid,
@ -113,7 +113,7 @@ function reconf.apnet_add(dirtyList, noReload)
device = 'radio0',
mode = 'ap',
})
commitBit(dirtyList, 'wireless')
if noReload == nil or noReload == false then reloadBit(dirtyList, 'network') end
end
@ -189,14 +189,14 @@ function reconf.dnsredir_add(dirtyList)
local sname = utils.getUciSectionName('dhcp', 'dnsmasq')
if sname == nil then return log:error("dhcp config does not contain a dnsmasq section") end
if uci:get('dhcp', sname, 'address') ~= nil then return log:debug("DNS address redirection already in place, not re-adding", false) end
uci:set('dhcp', sname, 'address', {redirText})
commitBit(dirtyList, 'dhcp'); reloadBit(dirtyList, 'dnsmasq')
end
function reconf.dnsredir_rm(dirtyList)
local sname = utils.getUciSectionName('dhcp', 'dnsmasq')
if sname == nil then return log:error("dhcp config does not contain a dnsmasq section") end
uci:delete('dhcp', sname, 'address')
commitBit(dirtyList, 'dhcp'); reloadBit(dirtyList, 'dnsmasq')
end
@ -254,7 +254,7 @@ function M.setupAccessPoint(ssid)
-- NOTE: dnsmasq must be reloaded after network or it will be unable to serve IP addresses
M.switchConfiguration{ wifiiface="add", network="reload", staticaddr="add", dhcppool="add_noreload", wwwredir="add", dnsredir="add" }
M.switchConfiguration{dhcp="reload"}
return true
end
@ -274,7 +274,7 @@ function M.associateSsid(ssid, passphrase, recreate)
break
end
end
-- if not, or if newly created configuration is requested, create a new configuration
if cfg == nil or recreate ~= nil then
local scanResult = wifi.getScanInfo(ssid)
@ -285,18 +285,18 @@ function M.associateSsid(ssid, passphrase, recreate)
return nil,"no wireless network with requested SSID is available"
end
end
-- try to associate with the network
wifi.activateConfig(ssid)
--M.switchConfiguration{ wifiiface="add", apnet="rm", staticaddr="rm", dhcppool="rm", wwwredir="rm", dnsredir="rm", wwwcaptive="rm", wireless="reload" }
M.switchConfiguration{ wifiiface="add", apnet="rm", staticaddr="rm", dhcppool="rm", wwwredir="rm", dnsredir="rm", wireless="reload" }
-- check if we are actually associated
local status = wifi.getDeviceState()
local status = wifi.getDeviceState()
if not status.ssid or status.ssid ~= ssid then
return nil,"could not associate with network (incorrect passphrase?)"
end
return true
end

View File

@ -20,14 +20,14 @@ function M.scan(request, response)
local withRaw = utils.toboolean(request:get("with_raw"))
local sr = wifi.getScanInfo()
local si, se
if sr and #sr > 0 then
response:setSuccess("")
local netInfoList = {}
for _, se in ipairs(sr) do
if noFilter or se.mode ~= "ap" and se.ssid ~= wifi.getSubstitutedSsid(settings.get('network.ap.ssid')) then
local netInfo = {}
netInfo["ssid"] = se.ssid
netInfo["bssid"] = se.bssid
netInfo["channel"] = se.channel
@ -37,7 +37,7 @@ function M.scan(request, response)
netInfo["quality"] = se.quality
netInfo["quality_max"] = se.quality_max
if withRaw then netInfo["_raw"] = utils.dump(se) end
table.insert(netInfoList, netInfo)
end
end
@ -53,7 +53,7 @@ end
function M.known(request, response)
local noFilter = utils.toboolean(request:get("nofilter"))
local withRaw = utils.toboolean(request:get("with_raw"))
response:setSuccess()
local netInfoList = {}
for _, net in ipairs(wifi.getConfigs()) do
@ -75,7 +75,7 @@ end
function M.status(request, response)
local withRaw = utils.toboolean(request:get("with_raw"))
local ds = wifi.getDeviceState()
response:setSuccess()
response:addData("ssid", ds.ssid or "")
response:addData("bssid", ds.bssid or "")
@ -92,23 +92,43 @@ end
--requires ssid(string), accepts phrase(string), recreate(bool)
function M.associate_POST(request, response)
local utils = require('util.utils')
local log = require('util.logger')
log:info("API:Network:associate")
local argSsid = request:get("ssid")
local argPhrase = request:get("phrase")
local argRecreate = request:get("recreate")
if argSsid == nil or argSsid == "" then
response:setError("missing ssid argument")
return
end
local rv,msg = netconf.associateSsid(argSsid, argPhrase, argRecreate)
response:addData("ssid", argSsid)
local associate = function()
local rv,msg = netconf.associateSsid(argSsid, argPhrase, argRecreate)
end
--response:addPostResponseFunction(associate)
local helloA = function()
local log = require('util.logger')
log:info("HELLO A")
end
response:addPostResponseFunction(helloA)
local helloB = function()
local log = require('util.logger')
log:info("HELLO B")
end
response:addPostResponseFunction(helloB)
--[[response:addData("ssid", argSsid)
if rv then
response:setSuccess("wlan associated")
else
response:setFail(msg)
end
end]]--
response:setSuccess("wlan is trying to associate")
end
function M.disassociate_POST(request, response)
@ -121,7 +141,7 @@ end
function M.openap_POST(request, response)
local ssid = wifi.getSubstitutedSsid(settings.get('network.ap.ssid'))
local rv,msg = netconf.setupAccessPoint(ssid)
response:addData("ssid", ssid)
if rv then
response:setSuccess("switched to Access Point mode")
@ -134,12 +154,12 @@ end
--requires ssid(string)
function M.remove_POST(request, response)
local argSsid = request:get("ssid")
if argSsid == nil or argSsid == "" then
response:setError("missing ssid argument")
return
end
if wifi.removeConfig(argSsid) then
response:setSuccess("removed wireless network with requested SSID")
response:addData("ssid", argSsid)

View File

@ -24,22 +24,25 @@ setmetatable(M, {
--requestObject should always be passed (except on init failure, when it is not yet available)
function M.new(requestObject)
local self = setmetatable({}, M)
self.body = { status = nil, data = {} }
self:setHttpStatus(200, 'OK')
self:setContentType('text/plain;charset=UTF-8')
--self:setContentType('application/json;charset=UTF-8')
-- a queue for functions to be executed when the response has bin given
-- needed for api calls like network/associate, which requires a restart of the webserver
self.postResponseQueue = {}
if requestObject ~= nil then
local rqId = requestObject:get(REQUEST_ID_ARGUMENT)
if rqId ~= nil then self.body[REQUEST_ID_ARGUMENT] = rqId end
if settings.API_INCLUDE_ENDPOINT_INFO == true then
self.body['module'] = requestObject:getRequestedApiModule()
self.body['function'] = requestObject:getRealApiFunctionName() or ''
end
end
return self
end
@ -65,7 +68,7 @@ end
function M:setError(msg)
self.body.status = 'error'
if msg ~= '' then self.body.msg = msg end
self:addData('more_info', 'http://' .. defaults.API_BASE_URL_PATH .. '/wiki/wiki/communication-api')
end
@ -76,6 +79,22 @@ function M:addData(k, v)
self.binaryData = nil
end
function M:addPostResponseFunction(fn)
local utils = require('util.utils')
local log = require('util.logger')
log:info("Response:addPostResponseFunction: " .. utils.dump(fn))
table.insert(self.postResponseQueue, fn)
log:info(" self.postResponseQueue: " .. utils.dump(self.postResponseQueue))
end
function M:executePostResponseQueue()
local utils = require('util.utils')
local log = require('util.logger')
log:info("Response:executePostResponseQueue: " .. utils.dump(self.postResponseQueue))
for i,fn in ipairs(self.postResponseQueue) do fn() end
end
function M:apiURL(mod, func)
if not mod then return nil end
if func then func = '/' .. func else func = "" end
@ -103,17 +122,17 @@ end
function M:setBinaryFileData(rFile, saveName, contentType)
if type(rFile) ~= 'string' or rFile:len() == 0 then return false end
local f,msg = io.open(rFile, "rb")
if not f then return nil,msg end
self.binaryData = f:read("*all")
f:close()
self.binarySavename = saveName
self:setContentType(contentType)
return true
end