2013-07-17 08:06:04 +02:00
|
|
|
package.path = package.path .. ';/usr/share/lua/wifibox/?.lua'
|
|
|
|
|
2013-07-17 22:55:27 +02:00
|
|
|
local confDefaults = require('conf_defaults')
|
2013-07-24 18:49:07 +02:00
|
|
|
local log = require('util.logger')
|
2013-08-20 22:38:16 +02:00
|
|
|
local settings = require('util.settings')
|
|
|
|
local util = require('util.utils')
|
2013-07-17 08:25:24 +02:00
|
|
|
local wifi = require('network.wlanconfig')
|
|
|
|
local netconf = require('network.netconfig')
|
|
|
|
local RequestClass = require('rest.request')
|
|
|
|
local ResponseClass = require('rest.response')
|
2013-09-27 18:38:31 +02:00
|
|
|
local Signin = require('network.signin')
|
2013-04-04 10:18:08 +02:00
|
|
|
|
2013-07-08 13:34:27 +02:00
|
|
|
local postData = nil
|
2013-04-04 10:18:08 +02:00
|
|
|
|
|
|
|
|
2013-07-08 13:34:27 +02:00
|
|
|
local function setupAutoWifiMode()
|
2013-08-23 01:58:09 +02:00
|
|
|
-- expects list with tables containing 'ssid' key as values and returns index key if found or nil if not found
|
|
|
|
local function findSsidInList(list, name)
|
|
|
|
for k,v in ipairs(list) do
|
|
|
|
if v.ssid == name then return k end
|
|
|
|
end
|
|
|
|
return nil
|
|
|
|
end
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-20 22:38:16 +02:00
|
|
|
local wifiState = wifi.getDeviceState()
|
|
|
|
local netName, netMode = wifiState.ssid, wifiState.mode
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-20 22:38:16 +02:00
|
|
|
local apSsid = wifi.getSubstitutedSsid(settings.get('network.ap.ssid'))
|
|
|
|
local apMode = (apSsid == netName) and netMode == 'ap'
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-20 22:38:16 +02:00
|
|
|
local scanList,msg = wifi.getScanInfo()
|
|
|
|
local knownSsids = wifi.getConfigs()
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-20 22:38:16 +02:00
|
|
|
if not scanList then
|
|
|
|
return nil, "autowifi: could not scan wifi networks (" .. msg .. ")"
|
|
|
|
end
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-22 17:15:44 +02:00
|
|
|
log:info("current wifi name/mode: " .. (netName or "<nil>") .. "/" .. netMode .. ", ssid of self: " .. apSsid)
|
|
|
|
local visNet, knownNet = {}, {}
|
2013-08-20 22:38:16 +02:00
|
|
|
for _,sn in ipairs(scanList) do
|
2013-08-22 17:15:44 +02:00
|
|
|
table.insert(visNet, sn.ssid)
|
2013-08-20 22:38:16 +02:00
|
|
|
end
|
|
|
|
for _,kn in ipairs(knownSsids) do
|
2013-08-22 17:15:44 +02:00
|
|
|
table.insert(knownNet, kn.ssid .. "/" .. kn.mode)
|
2013-08-20 22:38:16 +02:00
|
|
|
end
|
2013-08-22 17:15:44 +02:00
|
|
|
log:info("visible networks: " .. table.concat(visNet, ", "))
|
|
|
|
log:info("known networks: " .. table.concat(knownNet, ", "))
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-20 22:38:16 +02:00
|
|
|
-- if the currently active network is client mode and is also visible, do nothing since it will connect automatically further along the boot process
|
2013-08-23 01:58:09 +02:00
|
|
|
if netMode == 'sta' and netName ~= nil and netName ~= "" and findSsidInList(scanList, netName) then
|
2013-08-20 22:38:16 +02:00
|
|
|
return true, "autowifi: no action - existing configuration found for currently wifi visible network (" .. netName .. ")"
|
|
|
|
end
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-20 22:38:16 +02:00
|
|
|
-- try to find a known network which is also visible (ordered by known network definitions)
|
|
|
|
local connectWith = nil
|
|
|
|
for _,kn in ipairs(knownSsids) do
|
2013-09-04 19:23:51 +02:00
|
|
|
if kn.mode == 'ap' and kn.ssid == apSsid then break end
|
2013-08-20 22:38:16 +02:00
|
|
|
if findSsidInList(scanList, kn.ssid) then
|
|
|
|
connectWith = kn.ssid
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-20 22:38:16 +02:00
|
|
|
if connectWith then
|
2013-08-22 17:15:44 +02:00
|
|
|
local rv,msg = netconf.associateSsid(connectWith)
|
|
|
|
if rv then
|
|
|
|
return true, "autowifi: associated -- client mode with ssid '" .. connectWith .. "'"
|
|
|
|
else
|
|
|
|
return nil, "autowifi: could not associate with ssid '" .. connectWith .. "' (" .. msg .. ")"
|
|
|
|
end
|
|
|
|
elseif netMode ~= 'ap' or netName ~= apSsid then
|
|
|
|
local rv,msg = netconf.setupAccessPoint(apSsid)
|
|
|
|
if rv then
|
|
|
|
return true, "autowifi: configured as access point with ssid '" .. apSsid .. "'"
|
|
|
|
else
|
|
|
|
return nil, "autowifi: failed to configure as access point with ssid '" .. apSsid .. "' (" .. msg .. ")"
|
|
|
|
end
|
2013-08-20 22:38:16 +02:00
|
|
|
else
|
|
|
|
return true, "autowifi: no action - no known networks found, already in access point mode"
|
|
|
|
end
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-20 22:38:16 +02:00
|
|
|
return nil, "autowifi: uh oh - bad situation in autowifi function"
|
2013-04-04 10:18:08 +02:00
|
|
|
end
|
|
|
|
|
2013-08-22 18:34:45 +02:00
|
|
|
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
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-22 18:34:45 +02:00
|
|
|
local logTargetSetting = settings.getSystemKey('logfile')
|
|
|
|
local logLevelSetting = settings.getSystemKey('loglevel')
|
|
|
|
local logTargetError, logLevelError = nil, nil
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-22 18:34:45 +02:00
|
|
|
if type(logTargetSetting) == 'string' then
|
|
|
|
local specialTarget = logTargetSetting:match('^<(.*)>$')
|
|
|
|
if specialTarget then
|
|
|
|
if specialTarget == 'stdout' then logStream = io.stdout
|
|
|
|
elseif specialTarget == 'stderr' then logStream = io.stderr
|
|
|
|
end
|
|
|
|
elseif logTargetSetting:sub(1, 1) == '/' then
|
|
|
|
local f,msg = io.open(logTargetSetting, 'a+')
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-22 18:34:45 +02:00
|
|
|
if f then logStream = f
|
|
|
|
else logTargetError = msg
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-22 18:34:45 +02:00
|
|
|
if type(logLevelSetting) == 'string' and logLevelSetting:len() > 0 then
|
|
|
|
local valid = false
|
|
|
|
for idx,lvl in ipairs(log.LEVEL) do
|
|
|
|
if logLevelSetting == lvl then
|
|
|
|
logLevel = idx
|
|
|
|
valid = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if not valid then logLevelError = true end
|
|
|
|
end
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-22 18:34:45 +02:00
|
|
|
log:init(logLevel)
|
|
|
|
log:setStream(logStream)
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-22 18:34:45 +02:00
|
|
|
local rv = true
|
|
|
|
if logTargetError then
|
|
|
|
log:error("could not open logfile '" .. logTargetSetting .. "', using stderr as fallback (" .. logTargetError .. ")")
|
|
|
|
rv = false
|
|
|
|
end
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-22 18:34:45 +02:00
|
|
|
if logLevelError then
|
|
|
|
log:error("uci config specifies invalid log level '" .. logLevelSetting .. "', using debug level as fallback")
|
|
|
|
rv = false
|
|
|
|
end
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-22 18:34:45 +02:00
|
|
|
return rv
|
|
|
|
end
|
|
|
|
|
2013-08-21 22:49:17 +02:00
|
|
|
local function init(environment)
|
2013-08-22 18:34:45 +02:00
|
|
|
setupLogger()
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-07-24 18:49:07 +02:00
|
|
|
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"
|
2013-07-08 13:34:27 +02:00
|
|
|
end
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-07-24 18:49:07 +02:00
|
|
|
if dbgText ~= "" then dbgText = " (" .. dbgText .. " debugging enabled)" end
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-07-24 18:49:07 +02:00
|
|
|
log:info("Wifibox CGI handler started" .. dbgText)
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-21 22:49:17 +02:00
|
|
|
if (environment['REQUEST_METHOD'] == 'POST') then
|
|
|
|
local n = tonumber(environment['CONTENT_LENGTH'])
|
2013-07-08 13:34:27 +02:00
|
|
|
postData = io.read(n)
|
|
|
|
end
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-07-08 19:02:20 +02:00
|
|
|
local s, msg
|
|
|
|
s, msg = wifi.init()
|
|
|
|
if not s then return s, msg end
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-07-08 19:02:20 +02:00
|
|
|
s, msg = netconf.init(wifi, true)
|
|
|
|
if not s then return s, msg end
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-07-08 19:02:20 +02:00
|
|
|
return true
|
2013-07-08 13:34:27 +02:00
|
|
|
end
|
2013-04-04 10:18:08 +02:00
|
|
|
|
2013-09-20 23:38:20 +02:00
|
|
|
local function main(environment)
|
2013-08-21 22:49:17 +02:00
|
|
|
local rq = RequestClass.new(environment, postData, confDefaults.DEBUG_API)
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-07-24 18:49:07 +02:00
|
|
|
if rq:getRequestMethod() == 'CMDLINE' and rq:get('autowifi') ~= nil then
|
2013-08-20 22:38:16 +02:00
|
|
|
log:info("running in autowifi mode")
|
|
|
|
local rv,msg = setupAutoWifiMode()
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-20 22:38:16 +02:00
|
|
|
if rv then
|
|
|
|
log:info("autowifi setup done (" .. msg .. ")")
|
|
|
|
else
|
|
|
|
log:error("autowifi setup failed (" .. msg .. ")")
|
|
|
|
end
|
2013-09-27 18:38:31 +02:00
|
|
|
elseif rq:getRequestMethod() == 'CMDLINE' and rq:get('signin') ~= nil then
|
|
|
|
log:info("running in signin mode")
|
|
|
|
|
|
|
|
local ds = wifi.getDeviceState()
|
|
|
|
if ds.mode == "sta" then
|
|
|
|
local rv,msg = Signin.signin()
|
|
|
|
end
|
|
|
|
|
|
|
|
--[[if rv then
|
|
|
|
log:info("autowifi setup done (" .. msg .. ")")
|
|
|
|
else
|
|
|
|
log:error("autowifi setup failed (" .. msg .. ")")
|
|
|
|
end]]--
|
2013-07-24 18:49:07 +02:00
|
|
|
elseif rq:getRequestMethod() ~= 'CMDLINE' or confDefaults.DEBUG_API then
|
2013-08-23 01:58:09 +02:00
|
|
|
-- log:info("received request of type " .. rq:getRequestMethod() .. " for " .. (rq:getRequestedApiModule() or "<unknown>")
|
|
|
|
-- .. "/" .. (rq:getRealApiFunctionName() or "<unknown>") .. " with arguments: " .. util.dump(rq:getAll()))
|
|
|
|
log:info("received request of type " .. rq:getRequestMethod() .. " for " .. (rq:getRequestedApiModule() or "<unknown>")
|
|
|
|
.. "/" .. (rq:getRealApiFunctionName() or "<unknown>"))
|
|
|
|
if rq:getRequestMethod() ~= 'CMDLINE' then
|
|
|
|
log:info("remote IP/port: " .. rq:getRemoteHost() .. "/" .. rq:getRemotePort())
|
|
|
|
log:debug("user agent: " .. rq:getUserAgent())
|
|
|
|
end
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-07-09 01:49:56 +02:00
|
|
|
local response, err = rq:handle()
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-07-24 18:49:07 +02:00
|
|
|
if err ~= nil then log:error(err) end
|
2013-07-09 01:49:56 +02:00
|
|
|
response:send()
|
2013-09-02 15:01:16 +02:00
|
|
|
|
|
|
|
response:executePostResponseQueue()
|
2013-07-24 18:49:07 +02:00
|
|
|
else
|
|
|
|
log:info("Nothing to do...bye.\n")
|
2013-04-04 10:18:08 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-08-21 22:49:17 +02:00
|
|
|
|
|
|
|
--- Main firmware entry point.
|
|
|
|
-- This is either used by uhttp-mod-lua directly, or by the d3dapi cgi-bin wrapper
|
|
|
|
-- script which builds the env table from the shell environment. The wrapper script
|
|
|
|
-- also handles command-line invocation.
|
|
|
|
-- @tparam table The CGI environment table.
|
|
|
|
-- @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)
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-21 22:49:17 +02:00
|
|
|
if s == false then
|
|
|
|
local resp = ResponseClass.new()
|
|
|
|
local errSuffix = msg and " (" .. msg .. ")" or ""
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-21 22:49:17 +02:00
|
|
|
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
|
2013-09-02 15:01:16 +02:00
|
|
|
|
2013-08-21 22:49:17 +02:00
|
|
|
return 1
|
|
|
|
else
|
|
|
|
main(env)
|
|
|
|
return 0
|
|
|
|
end
|
2013-07-08 16:53:45 +02:00
|
|
|
end
|