I want to send list of APs back to the user with a script file "get_nw.lua", however whenever the callback that is defined in the argument of function wifi.sta.getap(), the system reboots with below output:
Requested URL: /nw.html
Method: GET
File: nw.html
Begin sending: nw.html
Sent nw.html 1024
Sent nw.html 2048
Sent nw.html 3072
Sent nw.html 4096
Sent nw.html 5120
Sent nw.html 5426
Finished sending: nw.html
Requested URL: /get_nw.lua
Method: GET
File: get_nw.lua
Begin sending: get_nw.lua
Finished sending: get_nw.lua
ets Jan 8 2013,rst cause:4, boot mode:(3,7)
wdt reset
load 0x40100000, len 28608, room 16
tail 0
chksum 0x5b
load 0x3ffe8000, len 3020, room 8
tail 4
chksum 0x61
load 0x3ffe8bcc, len 8, room 4
tail 4
chksum 0xb1
csum 0xb1
rL
I have tried various things with the callback function including the function in the examples of nodemcu wiki. All the things I've tried works when run in a standalone script file or somewhere else in the program. However, it creates problem when called within the function in "get_nw.lua"
Here are the various files:
init.lua:
tmr.delay(4000000)
print("Started nodeMCU...")
-- Set UART Configuration
uart.setup(0,115200,8,0,1)
-- Work at 160 MHz
node.setcpufreq(node.CPU160MHZ)
-- Begin WiFi configuration
local wifiConfig = {}
-- wifi.STATION -- station: join a WiFi network
-- wifi.SOFTAP -- access point: create a WiFi network
-- wifi.wifi.STATIONAP -- both station and access point
wifiConfig.mode = wifi.STATIONAP -- both station and access point
wifiConfig.accessPointConfig = {}
wifiConfig.accessPointConfig.ssid = "ahsa-IOT-node-"..node.chipid() -- Name of the SSID you want to create
wifiConfig.accessPointConfig.pwd = "abdullah12345" -- WiFi password - at least 8 characters
wifiConfig.accessPointIpConfig = {}
wifiConfig.accessPointIpConfig.ip = "192.168.25.1"
wifiConfig.accessPointIpConfig.netmask = "255.255.255.0"
wifiConfig.accessPointIpConfig.gateway = "192.168.25.1"
wifiConfig.stationPointConfig = {}
wifiConfig.stationPointConfig.ssid = "ahsa-wireles" -- Name of the WiFi network you want to join
wifiConfig.stationPointConfig.pwd = "ikizdere12345" -- Password for the WiFi network
-- Tell the chip to connect to the access point
wifi.setmode(wifiConfig.mode)
print('set (mode='..wifi.getmode()..')')
if (wifiConfig.mode == wifi.SOFTAP) or (wifiConfig.mode == wifi.STATIONAP) then
print('AP MAC: ',wifi.ap.getmac())
wifi.ap.config(wifiConfig.accessPointConfig)
wifi.ap.setip(wifiConfig.accessPointIpConfig)
end
if (wifiConfig.mode == wifi.STATION) or (wifiConfig.mode == wifi.STATIONAP) then
print('Client MAC: ',wifi.sta.getmac())
wifi.sta.config(wifiConfig.stationPointConfig.ssid, wifiConfig.stationPointConfig.pwd, 1)
end
print('chip: ',node.chipid())
print('heap: ',node.heap())
wifiConfig = nil
-- End WiFi configuration
-- Compile server code and remove original .lua files.
-- This only happens the first time afer the .lua files are uploaded.
local compileAndRemoveIfNeeded = function(f)
if file.open(f) then
file.close()
print('Compiling:', f)
node.compile(f)
file.remove(f)
end
end
local serverFiles = {'httpserver.lua', 'httpserver-request.lua', 'httpserver-static.lua', 'httpserver-header.lua', 'httpserver-error.lua'}
for i, f in ipairs(serverFiles) do compileAndRemoveIfNeeded(f) end
compileAndRemoveIfNeeded = nil
serverFiles = nil
-- Connect to the WiFi access point.
-- Once the device is connected, you may start the HTTP server.
if (wifi.getmode() == wifi.STATION) or (wifi.getmode() == wifi.STATIONAP) then
local joinCounter = 0
local joinMaxAttempts = 5
tmr.alarm(0, 3000, 1, function()
local ip = wifi.sta.getip()
if ip == nil and joinCounter < joinMaxAttempts then
print('Connecting to WiFi Access Point ...')
joinCounter = joinCounter +1
else
if joinCounter == joinMaxAttempts then
print('Failed to connect to WiFi Access Point.')
else
print('IP: ',ip)
end
tmr.stop(0)
joinCounter = nil
joinMaxAttempts = nil
end
end)
end
-- Uncomment to automatically start the server in port 80
if (not not wifi.sta.getip()) or (not not wifi.ap.getip()) then
dofile("httpserver.lc")(80)
end
httpserver.lua:
-- httpserver
-- Author: Marcos Kirsch
-- Starts web server in the specified port.
return function (port)
local s = net.createServer(net.TCP, 10) -- 10 seconds client timeout
s:listen(
port,
function (connection)
-- This variable holds the thread used for sending data back to the user.
-- We do it in a separate thread because we need to yield when sending lots
-- of data in order to avoid overflowing the mcu's buffer.
local connectionThread
local function onRequest(connection, req)
collectgarbage()
local method = req.method
local uri = req.uri
local fileServeFunction = nil
print("Method: " .. method)
print("File: " .. uri.file)
if #(uri.file) > 32 then
-- nodemcu-firmware cannot handle long filenames.
uri.args = {code = 400, errorString = "Bad Request"}
fileServeFunction = dofile("httpserver-error.lc")
else
local fileExists = file.open(uri.file, "r")
file.close()
if not fileExists then
uri.args = {code = 404, errorString = "Not Found"}
fileServeFunction = dofile("httpserver-error.lc")
else
uri.args = {file = uri.file, ext = uri.ext, args = uri.args}
fileServeFunction = dofile("httpserver-static.lc")
end
end
connectionThread = coroutine.create(fileServeFunction)
coroutine.resume(connectionThread, connection, req, uri.args)
-- print(uri.args.file, uri.args.ext, uri.args.args)
-- fileServeFunction(connection, req, uri.args)
-- connection:close()
end
local function onReceive(connection, payload)
collectgarbage()
-- parse payload and decide what to serve.
local req = dofile("httpserver-request.lc")(payload)
print("Requested URL: " .. req.request)
onRequest(connection, req)
end
local function onSent(connection, payload)
collectgarbage()
if connectionThread then
local connectionThreadStatus = coroutine.status(connectionThread)
if connectionThreadStatus == "suspended" then
-- Not finished sending file, resume.
coroutine.resume(connectionThread)
elseif connectionThreadStatus == "dead" then
-- We're done sending file.
connection:close()
connectionThread = nil
end
end
end
connection:on("receive", onReceive)
connection:on("sent", onSent)
end
)
-- false and nil evaluate as false
local ip = wifi.sta.getip()
if not ip then ip = wifi.ap.getip() end
print("nodemcu-httpserver running at http://" .. ip .. ":" .. port)
return s
end
httpserver-static.lua:
-- Part of nodemcu-httpserver, handles sending static files to client.
-- Author: Marcos Kirsch
return function (connection, req, args)
print("Begin sending:", args.file)
-- Send file in little chunks
local continue = true
local bytesSent = 0
if args.ext == "lua" then
dofile(args.file)(connection, req, args.args)
continue = false
end
if continue then
dofile("httpserver-header.lc")(connection, 200, args.ext)
end
while continue do
collectgarbage()
-- NodeMCU file API lets you open 1 file at a time.
-- So we need to open, seek, close each time in order
-- to support multiple simultaneous clients.
file.open(args.file)
file.seek("set", bytesSent)
local chunk = file.read(1024)
file.close()
if chunk == nil then
continue = false
else
coroutine.yield()
connection:send(chunk)
bytesSent = bytesSent + #chunk
chunk = nil
print("Sent", args.file, bytesSent)
end
end
print("Finished sending:", args.file)
print(" ")
bytesSent = nil
continue = nil
end
get_nw.lua:
return function (connection, req, args)
collectgarbage()
local fin = 0
local info_table = {}
local json_string = '{';
info_table.ssid, info_table.pwd = wifi.sta.getconfig()
info_table.ip,
info_table.netmask,
info_table.gateway = wifi.sta.getip()
if (wifi.sta.status() == 5) then
info_table.connected = "true"
else
info_table.connected = "false"
end
for key, val in pairs(info_table) do
json_string = json_string .. '"' .. tostring(key) .. '" : "' .. tostring(val) .. '", '
end
wifi.sta.getap(print)
json_string = string.sub(json_string, 1, -3)
json_string = json_string .. '}'
connection:send("HTTP/1.0 200 OK\r\nContent-Type: application/json\r\nCache-Control: private, no-store\r\n\r\n")
connection:send(json_string)
fin = nil
info_table = nil
json_string = nil
end