mirror of
https://github.com/Doodle3D/doodle3d-firmware.git
synced 2024-12-21 10:33:48 +01:00
Initial checkin of Doodle3D WiFi-box project. Files in src directory belong in /usr/share/lua/autowifi on the device and needs several symlinks as described in the readme.
This commit is contained in:
commit
b67d67eb91
4
.buildpath
Normal file
4
.buildpath
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<buildpath>
|
||||
<buildpathentry kind="src" path="src"/>
|
||||
</buildpath>
|
17
.project
Normal file
17
.project
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>d3d-box-wifi</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.dltk.core.scriptbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.koneki.ldt.nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
8
src/README
Normal file
8
src/README
Normal file
@ -0,0 +1,8 @@
|
||||
Installation:
|
||||
- place the autowifi directory in /usr/share/lua
|
||||
- create a symlink to ext/wfcf in /www/cgi-bin (make sure the file is executable)
|
||||
- create a symlink to ext/autowifi.html in /www
|
||||
- create a symlink to ext/autowifi.css in /www
|
||||
- create a symlink to ext/autowifi.js in /www
|
||||
- create a symlink to ext/autowifi_init in /etc/rc.d and name it S19autowifi_init
|
||||
- enable init script by calling it with 'enable' argument?
|
42
src/admin/autowifi.css
Normal file
42
src/admin/autowifi.css
Normal file
@ -0,0 +1,42 @@
|
||||
body {
|
||||
width: 80%;
|
||||
background-color: #ffe;
|
||||
}
|
||||
|
||||
.catgroup {
|
||||
border: 1px solid black;
|
||||
padding: 0.5em;
|
||||
margin-bottom: 10px;
|
||||
background-color: white;
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.cattitle {
|
||||
display: block;
|
||||
margin-left: 3em;
|
||||
margin-bottom: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
table.known_nets {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table.known_nets th, table.known_nets td {
|
||||
width: 33%;
|
||||
}
|
||||
|
||||
.result_success {
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.result_error {
|
||||
font-weight: normal;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
37
src/admin/autowifi.html
Normal file
37
src/admin/autowifi.html
Normal file
@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
|
||||
<title>Doodle3D</title>
|
||||
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
|
||||
<script type="text/javascript" src="autowifi.js"></script>
|
||||
<link href="autowifi.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="catgroup hidden">
|
||||
<div id="op_result"></div>
|
||||
</div>
|
||||
|
||||
<div class="catgroup">
|
||||
<span class="cattitle">WiFi mode</span>
|
||||
<div id="wlan_state"></div>
|
||||
</div>
|
||||
|
||||
<div class="catgroup">
|
||||
<span class="cattitle">Available networks</span>
|
||||
<form>
|
||||
<select id="wlan_networks">
|
||||
<option value="" disabled selected>Scanning for networks...</option>
|
||||
</select>
|
||||
<input id="wlan_passphrase" placeholder="passphrase" value="" type="password" />
|
||||
<input id="wlan_btn_connect" disabled type="button" value="Connect" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="catgroup">
|
||||
<span class="cattitle">Known networks</span>
|
||||
<div id="wlan_known_container"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
149
src/admin/autowifi.js
Normal file
149
src/admin/autowifi.js
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* TODO
|
||||
* - finish network creation
|
||||
* - finish auto operation
|
||||
* - call auto op from init script
|
||||
* - in AP mode, route all addresses to the autowifi page
|
||||
* - escape text where necessary (e.g. in getKnown, '<unknown SSID>' is currently interpreted as html...)
|
||||
* - why is $.trim() required in string comparison? do we need to strip newlines in the parse functions?
|
||||
* - add hidden field to remember encryption (so we know whether or not a passphrase should be entered)
|
||||
* - instead of showing alerts on missing ssid/phrase in connect, disable the button until contraints have been satisfied
|
||||
* (this is also cleaner in case no networks are present)
|
||||
* - use json for communication
|
||||
* - local all functions (see: http://stackoverflow.com/questions/4643814/why-would-this-lua-optimization-hack-help)
|
||||
*/
|
||||
|
||||
animSpeed = 200;
|
||||
cgiBase = "../cgi-bin/wfcf";
|
||||
|
||||
function setResultNeutral(text) {
|
||||
c = $("#op_result"); p = c.parent();
|
||||
c.removeClass("result_success").removeClass("result_error").html(text);
|
||||
if (text == "") p.hide(animSpeed);
|
||||
else p.show(animSpeed);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets div#op_result content to text, assigns appropiate class based on isError and display: block or, with empty text, display:none.
|
||||
*/
|
||||
function setResult(text, isError) {
|
||||
container = $("#op_result");
|
||||
parent = container.parent();
|
||||
if (isError) container.removeClass("result_success").addClass("result_error");
|
||||
else container.removeClass("result_error").addClass("result_success");
|
||||
|
||||
if (isError) title = "<i>Error</i><br />\n";
|
||||
else title = "<i>Success</i><br />\n";
|
||||
container.html(title + text);
|
||||
|
||||
if (text == "") parent.hide(animSpeed);
|
||||
else parent.show(animSpeed);
|
||||
}
|
||||
|
||||
//Returns an array with key 'status' (OK/WARN/ERR), 'msg' (can be empty) and 'status' (remainder of data)
|
||||
function parseResponse(response) {
|
||||
var r = {};
|
||||
var lines = response.split("\n");
|
||||
var st = lines[0].trim().split(',');
|
||||
lines = lines.slice(1);
|
||||
|
||||
r['status'] = st[0];
|
||||
r['msg'] = st.slice(1).join(",");
|
||||
r['payload'] = lines.join("\n");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
function parseNetLine(line) {
|
||||
var r = {};
|
||||
line = line.trim().split(",");
|
||||
r.ssid = line[0];
|
||||
r.bssid = line[1];
|
||||
r.channel = line[2];
|
||||
r.mode = line[3];
|
||||
return r;
|
||||
}
|
||||
|
||||
function fetchNetworkState() {
|
||||
$.get(cgiBase + "?op=getstate", function(data) {
|
||||
data = parseResponse(data);
|
||||
if (data.status == "ERR") setResult(data.msg, true);
|
||||
var net = parseNetLine(data.payload);
|
||||
if (net.mode == "ap") {
|
||||
$("#wlan_state").text("Access point mode (SSID: " + net.ssid + "; BSSID: " + net.bssid + "; channel: " + net.channel + ")");
|
||||
} else {
|
||||
$("#wlan_state").text("Client mode (SSID: " + net.ssid + "; BSSID: " + net.bssid + "; channel: " + net.channel + ")");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fetchAvailableNetworks() {
|
||||
$.get(cgiBase + "?op=getavl", function(data) {
|
||||
data = parseResponse(data);
|
||||
if (data.status == "ERR") setResult(data.msg, true);
|
||||
// else setResult(data.msg, false);
|
||||
|
||||
data = data.payload.split("\n");
|
||||
var options = $("#wlan_networks");
|
||||
options.empty();
|
||||
$.each(data, function(index,value) {
|
||||
if (value != "") {
|
||||
var ssid = parseNetLine(value).ssid;
|
||||
options.append($("<option />").val(ssid).text(ssid));
|
||||
}
|
||||
});
|
||||
$("#wlan_btn_connect").prop('disabled', false);
|
||||
});
|
||||
}
|
||||
|
||||
function fetchKnownNetworks() {
|
||||
$.get(cgiBase + "?op=getknown", function(data) {
|
||||
data = parseResponse(data);
|
||||
if (data.status == "ERR") setResult(data.msg, true);
|
||||
|
||||
data = data.payload.split("\n");
|
||||
var container = $("#wlan_known_container");
|
||||
container.empty();
|
||||
container.append("<table class=\"known_nets\"><tr><th>SSID</th><th>BSSID</th><th>channel</th></tr>");
|
||||
$.each(data, function(index,value) {
|
||||
if (value != "") {
|
||||
net = parseNetLine(value);
|
||||
console.log(net);
|
||||
container.append("<tr><td>" + net.ssid + "</td><td>" + net.bssid + "</td><td>" + net.channel + "</td></tr>");
|
||||
}
|
||||
});
|
||||
container.append("</table>");
|
||||
});
|
||||
}
|
||||
|
||||
function connectBtnHandler() {
|
||||
setResultNeutral("Associating with network...");
|
||||
ssid = $("#wlan_networks").find(":selected").text();
|
||||
phrase = $("#wlan_passphrase").val();
|
||||
|
||||
if (ssid == "") {
|
||||
alert("Please select a network");
|
||||
return;
|
||||
}
|
||||
|
||||
$.get(cgiBase + "?op=assoc&ssid=" + ssid + "&passphrase=" + phrase, function(data) {
|
||||
data = parseResponse(data);
|
||||
if (data.status == "ERR") {
|
||||
setResult(data.msg, true);
|
||||
} else {
|
||||
if (data.msg != "") setResult(data.msg, false);
|
||||
else setResult("Associated! (or are we?)", false);
|
||||
}
|
||||
|
||||
fetchKnownNetworks();
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
fetchNetworkState();
|
||||
fetchAvailableNetworks();
|
||||
fetchKnownNetworks();
|
||||
$("#wlan_btn_connect").click(connectBtnHandler);
|
||||
});
|
7
src/admin/index.html
Normal file
7
src/admin/index.html
Normal file
@ -0,0 +1,7 @@
|
||||
<head>
|
||||
<title>temp admin index</title>
|
||||
</head>
|
||||
<html><body>
|
||||
<a href="updater.html">Updates</a><br />
|
||||
<a href="autowifi.html">Wireless network management</a><br />
|
||||
</body></html>
|
156
src/autowifi.lua
Normal file
156
src/autowifi.lua
Normal file
@ -0,0 +1,156 @@
|
||||
--[[
|
||||
Response format:
|
||||
["OK" | "WARN" | "ERR"]<,{message}>
|
||||
{comma-separated line 1}
|
||||
...
|
||||
{comma-separated line n}
|
||||
|
||||
- see autowifi.js for TODO
|
||||
- general info on wireless config: http://wiki.openwrt.org/doc/uci/wireless
|
||||
- uci docs: http://wiki.openwrt.org/doc/techref/uci
|
||||
- parse/generate urls: https://github.com/keplerproject/cgilua/blob/master/src/cgilua/urlcode.lua
|
||||
- utility functions: http://luci.subsignal.org/trac/browser/luci/trunk/libs/sys/luasrc/sys.lua
|
||||
- iwinfo tool source: http://luci.subsignal.org/trac/browser/luci/trunk/contrib/package/iwinfo/src/iwinfo.lua?rev=7919
|
||||
- captive portal -> redirect all web traffic to one page for auth (or network selection)
|
||||
http://wiki.openwrt.org/doc/howto/wireless.hotspot
|
||||
]]
|
||||
--print ("HTTP/1.0 200 OK")
|
||||
print ("Content-type: text/plain\r\n")
|
||||
|
||||
local util = require("util")
|
||||
local wifi = require("wifihelper")
|
||||
local uci = require("uci").cursor()
|
||||
local urlcode = require("urlcode")
|
||||
local iwinfo = require("iwinfo")
|
||||
|
||||
local argOperation, argDevice, argSsid, argPhrase, argRecreate
|
||||
local errortext = nil
|
||||
|
||||
function init()
|
||||
local qs = os.getenv("QUERY_STRING")
|
||||
local urlargs = {}
|
||||
urlcode.parsequery(qs, urlargs)
|
||||
|
||||
--supplement urlargs with arguments from the command-line
|
||||
for _, v in ipairs(arg) do
|
||||
local split = v:find("=")
|
||||
if split ~= nil then
|
||||
urlargs[v:sub(1, split - 1)] = v:sub(split + 1)
|
||||
end
|
||||
end
|
||||
|
||||
argOperation = urlargs["op"]
|
||||
argDevice = urlargs["dev"] or DFL_DEVICE
|
||||
argSsid = urlargs["ssid"]
|
||||
argPhrase = urlargs["phrase"]
|
||||
argRecreate = urlargs["recreate"]
|
||||
|
||||
if urlargs["echo"] ~= nil then
|
||||
print("[[echo: '"..qs.."']]");
|
||||
end
|
||||
|
||||
if argOperation == nil then
|
||||
errortext = "Missing operation specifier"
|
||||
return false
|
||||
end
|
||||
|
||||
return wifi.init()
|
||||
end
|
||||
|
||||
|
||||
function main()
|
||||
if argOperation == "getavl" then
|
||||
local sr = wifi.getScanInfo()
|
||||
local si, se
|
||||
|
||||
if sr and #sr > 0 then
|
||||
for _, se in ipairs(sr) do
|
||||
--print("[[ " .. util.dump(se) .. " ]]") --TEMP
|
||||
util.printWithSuccess(#sr .. " network(s) found");
|
||||
print(se.ssid .. "," .. se.bssid .. "," .. se.channel .. "," .. wifi.mapDeviceMode(se.mode))
|
||||
end
|
||||
else
|
||||
util.exitWithError("No scan results or scanning not possible")
|
||||
end
|
||||
|
||||
elseif argOperation == "getknown" then
|
||||
for _, net in ipairs(wifi.getConfigs()) do
|
||||
if net.mode == "sta" then
|
||||
local bssid = net.bssid or "<unknown BSSID>"
|
||||
local channel = net.channel or "<unknown channel>"
|
||||
util.printWithSuccess("")
|
||||
print(net.ssid .. "," .. bssid .. "," .. channel)
|
||||
end
|
||||
end
|
||||
|
||||
elseif argOperation == "getstate" then
|
||||
local ds = wifi.getDeviceState()
|
||||
local ssid = ds.ssid or "<unknown SSID>"
|
||||
local bssid = ds.bssid or "<unknown BSSID>"
|
||||
local channel = ds.channel or "<unknown channel>"
|
||||
util.printWithSuccess("");
|
||||
print(ssid .. "," .. bssid .. "," .. channel .. "," .. ds.mode)
|
||||
|
||||
elseif argOperation == "assoc" then
|
||||
if argSsid == nil or argSsid == "" then util.exitWithError("Please supply an SSID to associate with") end
|
||||
|
||||
local cfg = nil
|
||||
for _, net in ipairs(wifi.getConfigs()) do
|
||||
if net.mode ~= "ap" and net.ssid == argSsid then
|
||||
cfg = net
|
||||
break
|
||||
end
|
||||
end
|
||||
if cfg == nil or argRecreate ~= nil then
|
||||
scanResult = wifi.getScanInfo(argSsid)
|
||||
if scanResult ~= nil then
|
||||
wifi.createConfigFromScanInfo(scanResult)
|
||||
else
|
||||
--check for error
|
||||
util.exitWithError("No wireless network with SSID '" .. argSsid .. "' is available")
|
||||
end
|
||||
end
|
||||
wifi.activateConfig(argSsid)
|
||||
--restartWlan()
|
||||
util.printWithSuccess("");
|
||||
print("Wlan associated with network "..argSsid.."! (dummy mode, not restarting)")
|
||||
|
||||
elseif argOperation == "disassoc" then
|
||||
wifi.activateConfig()
|
||||
--restartWlan()
|
||||
exitWithSuccess("Deactivated all wireless networks (dummy mode, not restarting)")
|
||||
|
||||
elseif argOperation == "rm" then
|
||||
if argSsid == nil or argSsid == "" then util.exitWithError("Please supply an SSID to remove") end
|
||||
if wifi.removeConfig(argSsid) then
|
||||
exitWithSuccess("Removed wireless network with SSID " .. argSsid)
|
||||
else
|
||||
exitWithWarning("No wireless network with SSID " .. argSsid)
|
||||
end
|
||||
|
||||
elseif argOperation == "auto" then
|
||||
exitWithWarning("Not implemented");
|
||||
--scan nets
|
||||
--take union of scan and known
|
||||
--connect to first if not empty; setup ap otherwise
|
||||
|
||||
else
|
||||
util.exitWithError("Unknown operation: '" .. argOperation .. "'")
|
||||
end
|
||||
|
||||
os.exit(0)
|
||||
end
|
||||
|
||||
|
||||
|
||||
--[[ START OF CODE ]]--
|
||||
|
||||
if init() == false then
|
||||
util.exitWithError(errortext)
|
||||
end
|
||||
|
||||
if wifi.createOrReplaceApConfig() == false then
|
||||
util.exitWithError(errortext)
|
||||
end
|
||||
|
||||
main()
|
148
src/ext/autowifi.js
Normal file
148
src/ext/autowifi.js
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* TODO
|
||||
* - finish network creation
|
||||
* - finish auto operation
|
||||
* - call auto op from init script
|
||||
* - in AP mode, route all addresses to the autowifi page
|
||||
* - escape text where necessary (e.g. in getKnown, '<unknown SSID>' is currently interpreted as html...)
|
||||
* - why is $.trim() required in string comparison? do we need to strip newlines in the parse functions?
|
||||
* - add hidden field to remember encryption (so we know whether or not a passphrase should be entered)
|
||||
* - instead of showing alerts on missing ssid/phrase in connect, disable the button until contraints have been satisfied
|
||||
* (this is also cleaner in case no networks are present)
|
||||
* - use json for communication
|
||||
*/
|
||||
|
||||
animSpeed = 200;
|
||||
cgiPath = "asdasd/cgi-bin/wfcf";
|
||||
|
||||
function setResultNeutral(text) {
|
||||
c = $("#op_result"); p = c.parent();
|
||||
c.removeClass("result_success").removeClass("result_error").html(text);
|
||||
if (text == "") p.hide(animSpeed);
|
||||
else p.show(animSpeed);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets div#op_result content to text, assigns appropiate class based on isError and display: block or, with empty text, display:none.
|
||||
*/
|
||||
function setResult(text, isError) {
|
||||
container = $("#op_result");
|
||||
parent = container.parent();
|
||||
if (isError) container.removeClass("result_success").addClass("result_error");
|
||||
else container.removeClass("result_error").addClass("result_success");
|
||||
|
||||
if (isError) title = "<i>Error</i><br />\n";
|
||||
else title = "<i>Success</i><br />\n";
|
||||
container.html(title + text);
|
||||
|
||||
if (text == "") parent.hide(animSpeed);
|
||||
else parent.show(animSpeed);
|
||||
}
|
||||
|
||||
//Returns an array with key 'status' (OK/WARN/ERR), 'msg' (can be empty) and 'status' (remainder of data)
|
||||
function parseResponse(response) {
|
||||
var r = {};
|
||||
var lines = response.split("\n");
|
||||
var st = lines[0].trim().split(',');
|
||||
lines = lines.slice(1);
|
||||
|
||||
r['status'] = st[0];
|
||||
r['msg'] = st.slice(1).join(",");
|
||||
r['payload'] = lines.join("\n");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
function parseNetLine(line) {
|
||||
var r = {};
|
||||
line = line.trim().split(",");
|
||||
r.ssid = line[0];
|
||||
r.bssid = line[1];
|
||||
r.channel = line[2];
|
||||
r.mode = line[3];
|
||||
return r;
|
||||
}
|
||||
|
||||
function fetchNetworkState() {
|
||||
$.get(cgiBase + "?op=getstate", function(data) {
|
||||
data = parseResponse(data);
|
||||
if (data.status == "ERR") setResult(data.msg, true);
|
||||
var net = parseNetLine(data.payload);
|
||||
if (net.mode == "ap") {
|
||||
$("#wlan_state").text("Access point mode (SSID: " + net.ssid + "; BSSID: " + net.bssid + "; channel: " + net.channel + ")");
|
||||
} else {
|
||||
$("#wlan_state").text("Client mode (SSID: " + net.ssid + "; BSSID: " + net.bssid + "; channel: " + net.channel + ")");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fetchAvailableNetworks() {
|
||||
$.get(cgiPath + "?op=getavl", function(data) {
|
||||
data = parseResponse(data);
|
||||
if (data.status == "ERR") setResult(data.msg, true);
|
||||
// else setResult(data.msg, false);
|
||||
|
||||
data = data.payload.split("\n");
|
||||
var options = $("#wlan_networks");
|
||||
options.empty();
|
||||
$.each(data, function(index,value) {
|
||||
if (value != "") {
|
||||
var ssid = parseNetLine(value).ssid;
|
||||
options.append($("<option />").val(ssid).text(ssid));
|
||||
}
|
||||
});
|
||||
$("#wlan_btn_connect").prop('disabled', false);
|
||||
});
|
||||
}
|
||||
|
||||
function fetchKnownNetworks() {
|
||||
$.get(cgiPath + "?op=getknown", function(data) {
|
||||
data = parseResponse(data);
|
||||
if (data.status == "ERR") setResult(data.msg, true);
|
||||
|
||||
data = data.payload.split("\n");
|
||||
var container = $("#wlan_known_container");
|
||||
container.empty();
|
||||
container.append("<table class=\"known_nets\"><tr><th>SSID</th><th>BSSID</th><th>channel</th></tr>");
|
||||
$.each(data, function(index,value) {
|
||||
if (value != "") {
|
||||
net = parseNetLine(value);
|
||||
console.log(net);
|
||||
container.append("<tr><td>" + net.ssid + "</td><td>" + net.bssid + "</td><td>" + net.channel + "</td></tr>");
|
||||
}
|
||||
});
|
||||
container.append("</table>");
|
||||
});
|
||||
}
|
||||
|
||||
function connectBtnHandler() {
|
||||
setResultNeutral("Associating with network...");
|
||||
ssid = $("#wlan_networks").find(":selected").text();
|
||||
phrase = $("#wlan_passphrase").val();
|
||||
|
||||
if (ssid == "") {
|
||||
alert("Please select a network");
|
||||
return;
|
||||
}
|
||||
|
||||
$.get(cgiPath + "?op=assoc&ssid=" + ssid + "&passphrase=" + phrase, function(data) {
|
||||
data = parseResponse(data);
|
||||
if (data.status == "ERR") {
|
||||
setResult(data.msg, true);
|
||||
} else {
|
||||
if (data.msg != "") setResult(data.msg, false);
|
||||
else setResult("Associated! (or are we?)", false);
|
||||
}
|
||||
|
||||
fetchKnownNetworks();
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
fetchNetworkState();
|
||||
fetchAvailableNetworks();
|
||||
fetchKnownNetworks();
|
||||
$("#wlan_btn_connect").click(connectBtnHandler);
|
||||
});
|
12
src/ext/autowifi_init
Executable file
12
src/ext/autowifi_init
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=19
|
||||
|
||||
start() {
|
||||
echo "dummy auto wifi init"
|
||||
#/www/cgi-bin/wfcf op=auto
|
||||
}
|
||||
|
||||
stop() {
|
||||
echo "dummy auto wifi deinit"
|
||||
}
|
10
src/ext/wfcf
Executable file
10
src/ext/wfcf
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
#chmod 755 /www/cgi-bin/wfcf
|
||||
|
||||
LUA=lua
|
||||
SCRIPT_PATH=/usr/share/lua/autowifi
|
||||
|
||||
cd $SCRIPT_PATH
|
||||
$LUA ./autowifi.lua $@
|
||||
|
||||
#$LUA $SCRIPT_PATH/autowifi.lua $@
|
12
src/misc/old/post
Executable file
12
src/misc/old/post
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
read QUERY_STRING
|
||||
eval $(echo "$QUERY_STRING"|awk -F'&' '{for(i=1;i<=NF;i++){print $i}}')
|
||||
|
||||
#escaped
|
||||
#echo $txtOutput
|
||||
|
||||
#unescaped
|
||||
txtOutput=`uhttpd -d $txtOutput`
|
||||
echo $txtOutput
|
9
src/misc/old/test
Executable file
9
src/misc/old/test
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
echo "Sample CGI Output"
|
||||
echo ""
|
||||
echo ""
|
||||
env
|
||||
echo ""
|
||||
echo ""
|
63
src/misc/old/wifi-list.html
Normal file
63
src/misc/old/wifi-list.html
Normal file
@ -0,0 +1,63 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Doodle3D</title>
|
||||
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
$.get("cgi-bin/wifi-scan", function(data) {
|
||||
data = data.split("\n");
|
||||
console.log(data.length);
|
||||
var options = $("#boxNetwork");
|
||||
options.empty();
|
||||
$.each(data, function(index,value) {
|
||||
console.log(value);
|
||||
if (value!="") options.append($("<option />").val(value).text(value));
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
body {
|
||||
width: 80%;
|
||||
background-color: #ffe;
|
||||
}
|
||||
|
||||
.catgroup {
|
||||
border: 1px solid black;
|
||||
padding: 0.5em;
|
||||
margin-bottom: 10px;
|
||||
background-color: white;
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.cattitle {
|
||||
display: block;
|
||||
margin-left: 3em;
|
||||
margin-bottom: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="catgroup">
|
||||
<span class="cattitle">WiFi mode</span>
|
||||
</div>
|
||||
|
||||
<div class="catgroup">
|
||||
<span class="cattitle">Available networks</span>
|
||||
<select id="boxNetwork">
|
||||
<option value="" disabled selected>Scanning for neworks...</option>
|
||||
</select>
|
||||
<input id="txtPassword" placeholder="password" value="" type="password">
|
||||
<input id="btnConnect" type="button" value="Connect">
|
||||
</div>
|
||||
|
||||
<div class="catgroup">
|
||||
<span class="cattitle">Known networks</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
19
src/misc/old/wifi-scan
Executable file
19
src/misc/old/wifi-scan
Executable file
@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
|
||||
# avoiding "Device or resource busy" error as per https://forum.openwrt.org/viewtopic.php?pid=121485#p121485
|
||||
# note that iwinfo takes care of this internally
|
||||
|
||||
echo "Content-type: text/plain"
|
||||
echo ""
|
||||
|
||||
DEV="${1:-wlan0}"
|
||||
|
||||
ifconfig $DEV down
|
||||
iw dev $DEV interface add scan.$DEV type station
|
||||
ifconfig scan.$DEV up
|
||||
|
||||
iwlist scan.$DEV scan | grep ESSID | cut -c 27- | tr -d '"'
|
||||
|
||||
ifconfig scan.$DEV down
|
||||
iw dev scan.$DEV del
|
||||
ifconfig $DEV up
|
33
src/misc/temp
Normal file
33
src/misc/temp
Normal file
@ -0,0 +1,33 @@
|
||||
[[1: { ["encryption"] =
|
||||
{ ["enabled"] = true,
|
||||
["auth_algs"] = { } ,
|
||||
["description"] = mixed WPA/WPA2 PSK (TKIP),
|
||||
["wep"] = false,
|
||||
["auth_suites"] =
|
||||
{ [1] = PSK,} ,
|
||||
["wpa"] = 3,
|
||||
["pair_ciphers"] =
|
||||
{ [1] = TKIP,
|
||||
[2] = CCMP,
|
||||
} ,
|
||||
["group_ciphers"] =
|
||||
{ [1] = TKIP,} ,
|
||||
} ,
|
||||
["quality_max"] = 70,
|
||||
["ssid"] = happiesnappie2,
|
||||
["channel"] = 9,
|
||||
["signal"] = -35,
|
||||
["bssid"] = 00:22:6B:EF:BB:99,
|
||||
["mode"] = Master,
|
||||
["quality"] = 70,
|
||||
} ]]
|
||||
|
||||
config wifi-iface
|
||||
option network 'lan'
|
||||
option ssid 'happiesnappie2'
|
||||
option encryption 'psk2'
|
||||
option device 'radio0'
|
||||
option mode 'sta'
|
||||
option bssid '00:22:6B:EF:BB:99'
|
||||
option key 'pr4ppal4trappa'
|
||||
option disabled '1'
|
45
src/misc/wireless.org
Normal file
45
src/misc/wireless.org
Normal file
@ -0,0 +1,45 @@
|
||||
|
||||
config wifi-device 'radio0'
|
||||
option type 'mac80211'
|
||||
option hwmode '11ng'
|
||||
option path 'platform/ar933x_wmac'
|
||||
option htmode 'HT20'
|
||||
list ht_capab 'SHORT-GI-20'
|
||||
list ht_capab 'SHORT-GI-40'
|
||||
list ht_capab 'RX-STBC1'
|
||||
list ht_capab 'DSSS_CCK-40'
|
||||
option channel '9'
|
||||
option country 'NL'
|
||||
option txpower '20'
|
||||
option disabled '0'
|
||||
|
||||
config wifi-iface
|
||||
option network 'lan'
|
||||
option ssid 'happiesnappie2'
|
||||
option encryption 'psk2'
|
||||
option device 'radio0'
|
||||
option mode 'sta'
|
||||
option bssid '00:22:6B:EF:BB:99'
|
||||
option key 'pr4ppal4trappa'
|
||||
option disabled '1'
|
||||
|
||||
config wifi-iface
|
||||
option device 'radio0'
|
||||
option encryption 'none'
|
||||
option ssid 'non-existing'
|
||||
option mode 'sta'
|
||||
option network 'lan'
|
||||
option disabled '0'
|
||||
|
||||
config wifi-iface
|
||||
option encryption 'none'
|
||||
option device 'radio0'
|
||||
option mode 'ap'
|
||||
option ssid 'd3d-ap'
|
||||
option network 'lan'
|
||||
option disabled '1'
|
||||
|
||||
Content-type: text/plain
|
||||
|
||||
[[1: { ["encryption"] = { ["enabled"] = true,["auth_algs"] = { } ,["description"] = mixed WPA/WPA2 PSK (TKIP),["wep"] = false,["auth_suites"] = { [1] = PSK,} ,["wpa"] = 3,["pair_ciphers"] = { [1] = TKIP,[2] = CCMP,} ,["group_ciphers"] = { [1] = TKIP,} ,} ,["quality_max"] = 70,["ssid"] = happiesnappie2,["channel"] = 9,["signal"] = -35,["bssid"] = 00:22:6B:EF:BB:99,["mode"] = Master,["quality"] = 70,} ]]
|
||||
happiesnappie2
|
114
src/urlcode.lua
Normal file
114
src/urlcode.lua
Normal file
@ -0,0 +1,114 @@
|
||||
----------------------------------------------------------------------------
|
||||
-- Utility functions for encoding/decoding of URLs.
|
||||
--
|
||||
-- @release $Id: urlcode.lua,v 1.10 2008/01/21 16:11:32 carregal Exp $
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
local ipairs, next, pairs, tonumber, type = ipairs, next, pairs, tonumber, type
|
||||
local string = require"string"
|
||||
local gsub = string.gsub
|
||||
local strbyte, strchar, strformat, strsub = string.byte, string.char, string.format, string.sub
|
||||
local tinsert = require"table".insert
|
||||
|
||||
--module ("cgilua.urlcode")
|
||||
local _M = {}
|
||||
|
||||
-- Converts an hexadecimal code in the form %XX to a character
|
||||
local function hexcode2char (h)
|
||||
return strchar(tonumber(h,16))
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
-- Decode an URL-encoded string (see RFC 2396)
|
||||
----------------------------------------------------------------------------
|
||||
function _M.unescape (str)
|
||||
str = gsub (str, "+", " ")
|
||||
str = gsub (str, "%%(%x%x)", hexcode2char)
|
||||
str = gsub (str, "\r\n", "\n")
|
||||
return str
|
||||
end
|
||||
|
||||
-- Converts a character to an hexadecimal code in the form %XX
|
||||
local function char2hexcode (c)
|
||||
return strformat ("%%%02X", strbyte(c))
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
-- URL-encode a string (see RFC 2396)
|
||||
----------------------------------------------------------------------------
|
||||
function _M.escape (str)
|
||||
str = gsub (str, "\n", "\r\n")
|
||||
str = gsub (str, "([^0-9a-zA-Z ])", char2hexcode) -- locale independent
|
||||
str = gsub (str, " ", "+")
|
||||
return str
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
-- Insert a (name=value) pair into table [[args]]
|
||||
-- @param args Table to receive the result.
|
||||
-- @param name Key for the table.
|
||||
-- @param value Value for the key.
|
||||
-- Multi-valued names will be represented as tables with numerical indexes
|
||||
-- (in the order they came).
|
||||
----------------------------------------------------------------------------
|
||||
function _M.insertfield (args, name, value)
|
||||
if not args[name] then
|
||||
args[name] = value
|
||||
else
|
||||
local t = type (args[name])
|
||||
if t == "string" then
|
||||
args[name] = {
|
||||
args[name],
|
||||
value,
|
||||
}
|
||||
elseif t == "table" then
|
||||
tinsert (args[name], value)
|
||||
else
|
||||
error ("CGILua fatal error (invalid args table)!")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
-- Parse url-encoded request data
|
||||
-- (the query part of the script URL or url-encoded post data)
|
||||
--
|
||||
-- Each decoded (name=value) pair is inserted into table [[args]]
|
||||
-- @param query String to be parsed.
|
||||
-- @param args Table where to store the pairs.
|
||||
----------------------------------------------------------------------------
|
||||
function _M.parsequery (query, args)
|
||||
if type(query) == "string" then
|
||||
local insertfield, unescape = _M.insertfield, _M.unescape
|
||||
gsub (query, "([^&=]+)=([^&=]*)&?",
|
||||
function (key, val)
|
||||
_M.insertfield (args, unescape(key), unescape(val))
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
-- URL-encode the elements of a table creating a string to be used in a
|
||||
-- URL for passing data/parameters to another script
|
||||
-- @param args Table where to extract the pairs (name=value).
|
||||
-- @return String with the resulting encoding.
|
||||
----------------------------------------------------------------------------
|
||||
function _M.encodetable (args)
|
||||
if args == nil or next(args) == nil then -- no args or empty args?
|
||||
return ""
|
||||
end
|
||||
local escape = _M.escape
|
||||
local strp = ""
|
||||
for key, vals in pairs(args) do
|
||||
if type(vals) ~= "table" then
|
||||
vals = {vals}
|
||||
end
|
||||
for i,val in ipairs(vals) do
|
||||
strp = strp.."&"..escape(key).."="..escape(val)
|
||||
end
|
||||
end
|
||||
-- remove first &
|
||||
return strsub(strp,2)
|
||||
end
|
||||
|
||||
return _M
|
36
src/util.lua
Normal file
36
src/util.lua
Normal file
@ -0,0 +1,36 @@
|
||||
local M = {}
|
||||
|
||||
function M.dump(o)
|
||||
if type(o) == 'table' then
|
||||
local s = '{ '
|
||||
for k,v in pairs(o) do
|
||||
if type(k) ~= 'number' then k = '"'..k..'"' end
|
||||
s = s .. '['..k..'] = ' .. M.dump(v) .. ','
|
||||
end
|
||||
return s .. '} '
|
||||
else
|
||||
return tostring(o)
|
||||
end
|
||||
end
|
||||
|
||||
function M.printWithSuccess(msg)
|
||||
if msg ~= nil and msg ~= "" then print("OK," .. msg)
|
||||
else print("OK") end
|
||||
end
|
||||
function M.exitWithSuccess(msg)
|
||||
if msg ~= nil and msg ~= "" then print("OK," .. msg)
|
||||
else print("OK") end
|
||||
os.exit(0)
|
||||
end
|
||||
function M.exitWithWarning(msg)
|
||||
if msg ~= nil and msg ~= "" then print("WARN," .. msg)
|
||||
else print("OK") end
|
||||
os.exit(0)
|
||||
end
|
||||
function M.exitWithError(msg)
|
||||
if msg ~= nil and msg ~= "" then print("ERR," .. msg)
|
||||
else print("OK") end
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
return M
|
172
src/wifihelper.lua
Normal file
172
src/wifihelper.lua
Normal file
@ -0,0 +1,172 @@
|
||||
local util = require("util")
|
||||
local uci = require("uci").cursor()
|
||||
local iwinfo = require("iwinfo")
|
||||
|
||||
local M = {}
|
||||
|
||||
M.DFL_AP_SSID = "d3d-ap"
|
||||
M.DFL_DEVICE = "radio0" -- was wlan0
|
||||
|
||||
local dev, dev_api
|
||||
|
||||
|
||||
--- Map device mode as reported by iwinfo to device mode as required by UCI
|
||||
-- Note that this function is quite naive.
|
||||
-- @param mode mode text as reported by iwinfo
|
||||
-- @param masterIsAp set to true to map 'Master' to 'ap' instead of 'sta' (optional)
|
||||
function M.mapDeviceMode(mode, masterIsAp)
|
||||
local modeMap = {
|
||||
["Master"] = masterIsAp and "ap" or "sta",
|
||||
["Ad-Hoc"] = "adhoc"
|
||||
}
|
||||
return modeMap[mode]
|
||||
end
|
||||
|
||||
|
||||
--- Initialize WiFi helper library
|
||||
-- @param device wireless device to operate on (optional, defaults to DFL_DEVICE)
|
||||
-- @return true on success or false+error on failure
|
||||
function M.init(device)
|
||||
-- iwinfo = pcall(require, "iwinfo")
|
||||
dev = device or M.DFL_DEVICE
|
||||
dev_api = iwinfo.type(dev)
|
||||
if not dev_api then
|
||||
return false, "No such wireless device: '"..dev.."'"
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
function M.getDeviceState()
|
||||
local iw = iwinfo[dev_api]
|
||||
local result = {
|
||||
["mode"] = M.mapDeviceMode(iw.mode(dev), true),
|
||||
["ssid"] = iw.ssid(dev),
|
||||
["bssid"] = iw.bssid(dev)
|
||||
}
|
||||
return result
|
||||
end
|
||||
|
||||
--- Return one or all available wifi networks resulting from an iwinfo scan
|
||||
-- @param ssid return data for given SSID or for all networks if SSID not given
|
||||
-- @return data for all or requested network; false+error on failure or nil when requested network not found
|
||||
function M.getScanInfo(ssid)
|
||||
local iw = iwinfo[dev_api]
|
||||
local sr = iw.scanlist(dev)
|
||||
local si, se
|
||||
|
||||
if ssid == nil then
|
||||
return sr
|
||||
else
|
||||
if sr and #sr > 0 then
|
||||
for _, se in ipairs(sr) do
|
||||
if se.ssid == ssid then
|
||||
return se
|
||||
end
|
||||
end
|
||||
else
|
||||
return false, "No scan results or scanning not possible"
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Return all wireless networks configured in UCI
|
||||
function M.getConfigs()
|
||||
local l = {}
|
||||
uci.foreach("wireless", "wifi-iface", function(s) table.insert(l, s) end)
|
||||
return l
|
||||
end
|
||||
|
||||
--- Remove UCI config for network with given SSID
|
||||
-- @return true if successfully removed, false if no such config exists
|
||||
function M.removeConfig(ssid)
|
||||
local rv = false
|
||||
uci:foreach("wireless", "wifi-iface", function(s)
|
||||
if s.ssid == ssid then
|
||||
uci:delete("wireless", s[".name"])
|
||||
rv = true
|
||||
return false
|
||||
end
|
||||
end)
|
||||
uci:commit("wireless")
|
||||
return rv
|
||||
end
|
||||
|
||||
--- Activate wireless section for given SSID and disable all others
|
||||
-- @param ssid SSID of config to enable, or nil to disable all network configs
|
||||
function M.activateConfig(ssid)
|
||||
uci:foreach("wireless", "wifi-iface", function(s)
|
||||
local disabled = s.ssid ~= ssid and "1" or "0"
|
||||
uci:set("wireless", s[".name"], "disabled", disabled)
|
||||
end)
|
||||
uci:commit("wireless")
|
||||
end
|
||||
|
||||
--- Create a new UCI network from the given iwinfo data
|
||||
-- http://luci.subsignal.org/trac/browser/luci/trunk/libs/iwinfo/src/iwinfo_wext.c?rev=5645 (outdated?)
|
||||
-- TODO: configure encryption correctly (how?)
|
||||
-- @param info iwinfo data to create a network from
|
||||
-- @param passphrase passphrase to use (optional)
|
||||
-- @param disabled immediately disable the network (optional)
|
||||
function M.createConfigFromScanInfo(info, passphrase, disabled)
|
||||
local mode = M.mapDeviceMode(info.mode)
|
||||
|
||||
local apconfig = {
|
||||
network = "lan",
|
||||
device = "radio0",
|
||||
ssid = info.ssid,
|
||||
bssid = info.bssid,
|
||||
--encryption = "none",
|
||||
mode = mode,
|
||||
}
|
||||
if passphrase ~= nil then apconfig.key = passphrase end
|
||||
apconfig.disabled = disabled ~= nil and disabled and 1 or 0
|
||||
|
||||
local sname = uci:add("wireless", "wifi-iface");
|
||||
for k, v in pairs(apconfig) do
|
||||
uci:set("wireless", sname, k, v)
|
||||
end
|
||||
uci:commit("wireless")
|
||||
end
|
||||
|
||||
--- Ensure a suitable config section for the access point network exists
|
||||
-- @param disabled flag the network as disabled (optional)
|
||||
function M.createOrReplaceApConfig(disabled)
|
||||
local sname = nil
|
||||
uci:foreach("wireless", "wifi-iface", function(s)
|
||||
if s.ssid == M.AP_SSID then
|
||||
sname = s[".name"]
|
||||
return false
|
||||
end
|
||||
end)
|
||||
if sname == nil then sname = uci:add("wireless", "wifi-iface") end
|
||||
|
||||
local apconfig = {
|
||||
network = "lan",
|
||||
ssid = M.AP_SSID,
|
||||
encryption = "none",
|
||||
device = "radio0",
|
||||
mode = "ap",
|
||||
}
|
||||
apconfig.disabled = disabled ~= nil and disabled and 1 or 0
|
||||
|
||||
for k, v in pairs(apconfig) do
|
||||
uci:set("wireless", sname, k, v)
|
||||
end
|
||||
uci:commit("wireless")
|
||||
end
|
||||
|
||||
--- Reload network config to reflect contents of config
|
||||
-- @see http://wiki.openwrt.org/doc/techref/netifd)
|
||||
-- * Network reload only restarts interfaces which need to be restarted so no
|
||||
-- unneccesary interruptions there.
|
||||
-- * ubus does not seem to work -- local c=ubus.connect();
|
||||
-- c:call("network.interface.wlan", "down"); c:call("network.interface.wlan", "up"); c:close()
|
||||
function M.restart()
|
||||
local rv = os.execute("/etc/init.d/network reload")
|
||||
end
|
||||
|
||||
return M
|
Loading…
Reference in New Issue
Block a user