Merge pull request #2007 from dibdot/travelmate

luci-app-travelmate: sync with travelmate 1.2.1
This commit is contained in:
Dirk Brenken 2018-07-29 21:30:26 +02:00 committed by GitHub
commit af961f84ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 605 additions and 295 deletions

View file

@ -3,9 +3,12 @@
module("luci.controller.travelmate", package.seeall) module("luci.controller.travelmate", package.seeall)
local util = require("luci.util") local sys = require("luci.sys")
local i18n = require("luci.i18n") local util = require("luci.util")
local templ = require("luci.template") local http = require("luci.http")
local i18n = require("luci.i18n")
local json = require("luci.jsonc")
local uci = require("luci.model.uci").cursor()
function index() function index()
if not nixio.fs.access("/etc/config/travelmate") then if not nixio.fs.access("/etc/config/travelmate") then
@ -14,13 +17,16 @@ function index()
entry({"admin", "services", "travelmate"}, firstchild(), _("Travelmate"), 40).dependent = false entry({"admin", "services", "travelmate"}, firstchild(), _("Travelmate"), 40).dependent = false
entry({"admin", "services", "travelmate", "tab_from_cbi"}, cbi("travelmate/overview_tab", {hideresetbtn=true, hidesavebtn=true}), _("Overview"), 10).leaf = true entry({"admin", "services", "travelmate", "tab_from_cbi"}, cbi("travelmate/overview_tab", {hideresetbtn=true, hidesavebtn=true}), _("Overview"), 10).leaf = true
entry({"admin", "services", "travelmate", "stations"}, template("travelmate/stations"), _("Wireless Stations"), 20).leaf = true entry({"admin", "services", "travelmate", "stations"}, template("travelmate/stations"), _("Wireless Stations"), 20).leaf = true
entry({"admin", "services", "travelmate", "logfile"}, call("logread"), _("View Logfile"), 30).leaf = true entry({"admin", "services", "travelmate", "log"}, template("travelmate/logread"), _("View Logfile"), 30).leaf = true
entry({"admin", "services", "travelmate", "advanced"}, firstchild(), _("Advanced"), 100) entry({"admin", "services", "travelmate", "advanced"}, firstchild(), _("Advanced"), 100)
entry({"admin", "services", "travelmate", "advanced", "configuration"}, form("travelmate/configuration_tab"), _("Edit Travelmate Configuration"), 110).leaf = true entry({"admin", "services", "travelmate", "advanced", "configuration"}, form("travelmate/configuration_tab"), _("Edit Travelmate Configuration"), 110).leaf = true
entry({"admin", "services", "travelmate", "advanced", "cfg_wireless"}, form("travelmate/cfg_wireless_tab"), _("Edit Wireless Configuration"), 120).leaf = true entry({"admin", "services", "travelmate", "advanced", "cfg_wireless"}, form("travelmate/cfg_wireless_tab"), _("Edit Wireless Configuration"), 120).leaf = true
entry({"admin", "services", "travelmate", "advanced", "cfg_network"}, form("travelmate/cfg_network_tab"), _("Edit Network Configuration"), 130).leaf = true entry({"admin", "services", "travelmate", "advanced", "cfg_network"}, form("travelmate/cfg_network_tab"), _("Edit Network Configuration"), 130).leaf = true
entry({"admin", "services", "travelmate", "advanced", "cfg_firewall"}, form("travelmate/cfg_firewall_tab"), _("Edit Firewall Configuration"), 140).leaf = true entry({"admin", "services", "travelmate", "advanced", "cfg_firewall"}, form("travelmate/cfg_firewall_tab"), _("Edit Firewall Configuration"), 140).leaf = true
entry({"admin", "services", "travelmate", "logread"}, call("logread"), nil).leaf = true
entry({"admin", "services", "travelmate", "status"}, call("status_update"), nil).leaf = true
entry({"admin", "services", "travelmate", "action"}, call("trm_action"), nil).leaf = true
entry({"admin", "services", "travelmate", "apqr"}, template("travelmate/ap_qr")).leaf = true entry({"admin", "services", "travelmate", "apqr"}, template("travelmate/ap_qr")).leaf = true
entry({"admin", "services", "travelmate", "wifiscan"}, template("travelmate/wifi_scan")).leaf = true entry({"admin", "services", "travelmate", "wifiscan"}, template("travelmate/wifi_scan")).leaf = true
entry({"admin", "services", "travelmate", "wifiadd"}, form("travelmate/wifi_add", {hideresetbtn=true, hidesavebtn=true})).leaf = true entry({"admin", "services", "travelmate", "wifiadd"}, form("travelmate/wifi_add", {hideresetbtn=true, hidesavebtn=true})).leaf = true
@ -29,13 +35,38 @@ function index()
entry({"admin", "services", "travelmate", "wifiorder"}, form("travelmate/wifi_order", {hideresetbtn=true, hidesavebtn=true})).leaf = true entry({"admin", "services", "travelmate", "wifiorder"}, form("travelmate/wifi_order", {hideresetbtn=true, hidesavebtn=true})).leaf = true
end end
function trm_action(name)
if name == "do_restart" then
luci.sys.call("/etc/init.d/travelmate restart >/dev/null 2>&1")
end
luci.http.prepare_content("text/plain")
luci.http.write("0")
end
function status_update()
local rt_file
local content
rt_file = uci:get("travelmate", "global", "trm_rtfile") or "/tmp/trm_runtime.json"
if nixio.fs.access(rt_file) then
content = json.parse(nixio.fs.readfile(rt_file) or "")
http.prepare_content("application/json")
http.write_json(content)
end
end
function logread() function logread()
local logfile = "" local content
if nixio.fs.access("/var/log/messages") then if nixio.fs.access("/var/log/messages") then
logfile = util.trim(util.exec("grep -F 'travelmate-' /var/log/messages")) content = util.trim(util.exec("grep -F 'travelmate-' /var/log/messages"))
elseif nixio.fs.access("/sbin/logread") then else
logfile = util.trim(util.exec("logread -e 'travelmate-'")) content = util.trim(util.exec("logread -e 'travelmate-'"))
end end
templ.render("travelmate/logread", {title = i18n.translate("Travelmate Logfile"), content = logfile})
if content == "" then
content = "No travelmate related logs yet!"
end
http.write(content)
end end

View file

@ -1,11 +1,11 @@
-- Copyright 2017 Dirk Brenken (dev@brenken.org) -- Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
-- This is free software, licensed under the Apache License, Version 2.0 -- This is free software, licensed under the Apache License, Version 2.0
local fs = require("nixio.fs") local fs = require("nixio.fs")
local util = require("luci.util") local util = require("luci.util")
local trminput = "/etc/config/firewall" local input = "/etc/config/firewall"
if not nixio.fs.access(trminput) then if not fs.access(input) then
m = SimpleForm("error", nil, translate("Input file not found, please check your configuration.")) m = SimpleForm("error", nil, translate("Input file not found, please check your configuration."))
return m return m
end end
@ -23,11 +23,15 @@ f.rows = 20
f.rmempty = true f.rmempty = true
function f.cfgvalue() function f.cfgvalue()
return nixio.fs.readfile(trminput) or "" return fs.readfile(input) or ""
end end
function f.write(self, section, data) function f.write(self, section, data)
return nixio.fs.writefile(trminput, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n") return fs.writefile(input, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
end
function f.remove(self, section, value)
return fs.writefile(input, "")
end end
function s.handle(self, state, data) function s.handle(self, state, data)

View file

@ -1,11 +1,11 @@
-- Copyright 2017 Dirk Brenken (dev@brenken.org) -- Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
-- This is free software, licensed under the Apache License, Version 2.0 -- This is free software, licensed under the Apache License, Version 2.0
local fs = require("nixio.fs") local fs = require("nixio.fs")
local util = require("luci.util") local util = require("luci.util")
local trminput = "/etc/config/network" local input = "/etc/config/network"
if not nixio.fs.access(trminput) then if not fs.access(input) then
m = SimpleForm("error", nil, translate("Input file not found, please check your configuration.")) m = SimpleForm("error", nil, translate("Input file not found, please check your configuration."))
return m return m
end end
@ -23,11 +23,15 @@ f.rows = 20
f.rmempty = true f.rmempty = true
function f.cfgvalue() function f.cfgvalue()
return nixio.fs.readfile(trminput) or "" return fs.readfile(input) or ""
end end
function f.write(self, section, data) function f.write(self, section, data)
return nixio.fs.writefile(trminput, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n") return fs.writefile(input, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
end
function f.remove(self, section, value)
return fs.writefile(input, "")
end end
function s.handle(self, state, data) function s.handle(self, state, data)

View file

@ -1,11 +1,11 @@
-- Copyright 2017 Dirk Brenken (dev@brenken.org) -- Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
-- This is free software, licensed under the Apache License, Version 2.0 -- This is free software, licensed under the Apache License, Version 2.0
local fs = require("nixio.fs") local fs = require("nixio.fs")
local util = require("luci.util") local util = require("luci.util")
local trminput = "/etc/config/wireless" local input = "/etc/config/wireless"
if not nixio.fs.access(trminput) then if not fs.access(input) then
m = SimpleForm("error", nil, translate("Input file not found, please check your configuration.")) m = SimpleForm("error", nil, translate("Input file not found, please check your configuration."))
return m return m
end end
@ -23,11 +23,15 @@ f.rows = 20
f.rmempty = true f.rmempty = true
function f.cfgvalue() function f.cfgvalue()
return nixio.fs.readfile(trminput) or "" return fs.readfile(input) or ""
end end
function f.write(self, section, data) function f.write(self, section, data)
return nixio.fs.writefile(trminput, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n") return fs.writefile(input, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
end
function f.remove(self, section, value)
return fs.writefile(input, "")
end end
function s.handle(self, state, data) function s.handle(self, state, data)

View file

@ -1,11 +1,11 @@
-- Copyright 2017 Dirk Brenken (dev@brenken.org) -- Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
-- This is free software, licensed under the Apache License, Version 2.0 -- This is free software, licensed under the Apache License, Version 2.0
local fs = require("nixio.fs") local fs = require("nixio.fs")
local util = require("luci.util") local util = require("luci.util")
local trminput = "/etc/config/travelmate" local input = "/etc/config/travelmate"
if not nixio.fs.access(trminput) then if not fs.access(input) then
m = SimpleForm("error", nil, translate("Input file not found, please check your configuration.")) m = SimpleForm("error", nil, translate("Input file not found, please check your configuration."))
m.reset = false m.reset = false
m.submit = false m.submit = false
@ -25,11 +25,15 @@ f.rows = 20
f.rmempty = true f.rmempty = true
function f.cfgvalue() function f.cfgvalue()
return nixio.fs.readfile(trminput) or "" return fs.readfile(input) or ""
end end
function f.write(self, section, data) function f.write(self, section, data)
return nixio.fs.writefile(trminput, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n") return fs.writefile(input, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
end
function f.remove(self, section, value)
return fs.writefile(input, "")
end end
function s.handle(self, state, data) function s.handle(self, state, data)

View file

@ -3,15 +3,12 @@
local fs = require("nixio.fs") local fs = require("nixio.fs")
local uci = require("luci.model.uci").cursor() local uci = require("luci.model.uci").cursor()
local json = require("luci.jsonc")
local util = require("luci.util") local util = require("luci.util")
local nw = require("luci.model.network").init() local nw = require("luci.model.network").init()
local fw = require("luci.model.firewall").init() local fw = require("luci.model.firewall").init()
local dump = util.ubus("network.interface", "dump", {}) local dump = util.ubus("network.interface", "dump", {})
local trmiface = uci:get("travelmate", "global", "trm_iface") or "trm_wwan" local trmiface = uci:get("travelmate", "global", "trm_iface") or "trm_wwan"
local trminput = uci:get("travelmate", "global", "trm_rtfile") or "/tmp/trm_runtime.json"
local uplink = uci:get("network", trmiface) or "" local uplink = uci:get("network", trmiface) or ""
local parse = json.parse(fs.readfile(trminput) or "")
m = Map("travelmate", translate("Travelmate"), m = Map("travelmate", translate("Travelmate"),
translate("Configuration of the travelmate package to to enable travel router functionality. ") translate("Configuration of the travelmate package to to enable travel router functionality. ")
@ -20,11 +17,9 @@ m = Map("travelmate", translate("Travelmate"),
.. "see online documentation</a>", "https://github.com/openwrt/packages/blob/master/net/travelmate/files/README.md")) .. "see online documentation</a>", "https://github.com/openwrt/packages/blob/master/net/travelmate/files/README.md"))
m:chain("network") m:chain("network")
m:chain("firewall") m:chain("firewall")
m.apply_on_parse = true
function m.on_apply(self) function m.on_apply(self)
luci.sys.call("env -i /etc/init.d/travelmate restart >/dev/null 2>&1") luci.sys.call("env -i /etc/init.d/travelmate restart >/dev/null 2>&1")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "travelmate"))
end end
-- Interface Wizard -- Interface Wizard
@ -33,7 +28,7 @@ if uplink == "" then
ds = m:section(NamedSection, "global", "travelmate", translate("Interface Wizard")) ds = m:section(NamedSection, "global", "travelmate", translate("Interface Wizard"))
o = ds:option(Value, "trm_iface", translate("Create Uplink interface"), o = ds:option(Value, "trm_iface", translate("Create Uplink interface"),
translate("Create a new wireless wan uplink interface, configure it to use dhcp and ") translate("Create a new wireless wan uplink interface, configure it to use dhcp and ")
.. translate("add it to the wan zone of the firewall.<br />") .. translate("add it to the wan zone of the firewall. ")
.. translate("This step has only to be done once.")) .. translate("This step has only to be done once."))
o.datatype = "and(uciname,rangelength(3,15))" o.datatype = "and(uciname,rangelength(3,15))"
o.default = trmiface o.default = trmiface
@ -96,55 +91,8 @@ end
-- Runtime information -- Runtime information
ds = m:section(NamedSection, "global", "travelmate", translate("Runtime Information")) ds = s:option(DummyValue, "_dummy")
ds.template = "travelmate/runtime"
dv1 = ds:option(DummyValue, "status", translate("Travelmate Status (Quality)"))
dv1.template = "travelmate/runtime"
if parse ~= nil then
dv1.value = parse.data.travelmate_status or translate("n/a")
else
dv1.value = translate("n/a")
end
dv2 = ds:option(DummyValue, "travelmate_version", translate("Travelmate Version"))
dv2.template = "travelmate/runtime"
if parse ~= nil then
dv2.value = parse.data.travelmate_version or translate("n/a")
else
dv2.value = translate("n/a")
end
dv3 = ds:option(DummyValue, "station_id", translate("Station ID (SSID/BSSID)"))
dv3.template = "travelmate/runtime"
if parse ~= nil then
dv3.value = parse.data.station_id or translate("n/a")
else
dv3.value = translate("n/a")
end
dv4 = ds:option(DummyValue, "station_interface", translate("Station Interface"))
dv4.template = "travelmate/runtime"
if parse ~= nil then
dv4.value = parse.data.station_interface or translate("n/a")
else
dv4.value = translate("n/a")
end
dv5 = ds:option(DummyValue, "station_radio", translate("Station Radio"))
dv5.template = "travelmate/runtime"
if parse ~= nil then
dv5.value = parse.data.station_radio or translate("n/a")
else
dv5.value = translate("n/a")
end
dv6 = ds:option(DummyValue, "last_rundate", translate("Last rundate"))
dv6.template = "travelmate/runtime"
if parse ~= nil then
dv6.value = parse.data.last_rundate or translate("n/a")
else
dv6.value = translate("n/a")
end
-- Extra options -- Extra options

View file

@ -6,60 +6,61 @@ This is free software, licensed under the Apache License, Version 2.0
<%+header%> <%+header%>
<div class="cbi-map"> <div class="cbi-map">
<div class="cbi-map-descr"> <div class="cbi-map-descr">
<%=translate("Here you'll find the QR codes from all of your configured Access Points. It allows you to connect your Android or iOS devices to your router's WiFi using the QR code shown below.")%> <%=translate("Here you'll find the QR codes from all of your configured Access Points. It allows you to connect your Android or iOS devices to your router's WiFi using the QR code shown below.")%>
</div> </div>
<%- <%- local uci = require("luci.model.uci").cursor()
local write = io.write
local uci = require("luci.model.uci").cursor()
uci:foreach("wireless", "wifi-iface", function(s) uci:foreach("wireless", "wifi-iface", function(s)
local device = s.device or "" local device = s.device or ""
local mode = s.mode or "" local mode = s.mode or ""
local ssid = s.ssid or "" local ssid = s.ssid or ""
local enc = s.encryption or "" local enc = s.encryption or ""
local key = s.key or "" local key = s.key or ""
local hidden = s.hidden or "false" local hidden = s.hidden or "false"
local disabled = s.disabled or "" local disabled = s.disabled or ""
local wep_slots = {s.key1 or "", s.key2 or "", s.key3 or "", s.key4 or ""} local wep_slots = {s.key1 or "", s.key2 or "", s.key3 or "", s.key4 or ""}
if device and mode == "ap" and disabled ~= "1" then if device and mode == "ap" and disabled ~= "1" then
if string.match(enc, '^psk') then if string.match(enc, '^psk') then
enc = "WPA" enc = "WPA"
elseif string.match(enc, '^wep') then elseif string.match(enc, '^wep') then
enc = "WEP" enc = "WEP"
if tonumber(key) then if tonumber(key) then
key = wep_slots[tonumber(key)] key = wep_slots[tonumber(key)]
end end
elseif enc == "none" then elseif enc == "none" then
enc = "nopass" enc = "nopass"
key = "nokey" key = "nokey"
else else
enc = "" enc = ""
end end
if hidden == "1" then
hidden = "true" if hidden == "1" then
end hidden = "true"
if ssid and enc and key then end
local e_ssid = string.gsub(ssid,"[\"\\';:, ]",[[\\\%1]])
local e_key = string.gsub(key,"[\"\\';:, ]",[[\\\%1]]) if ssid and enc and key then
local qrcode = "" local e_ssid = string.gsub(ssid,"[\"\\';:, ]",[[\\\%1]])
qrcode = luci.sys.exec("/usr/bin/qrencode --inline --8bit --type=SVG --output=- 'WIFI:S:\"'" .. e_ssid .. "'\";T:'" .. enc .. "';P:\"'" .. e_key .. "'\";H:'" .. hidden .. "';'") local e_key = string.gsub(key,"[\"\\';:, ]",[[\\\%1]])
-%> local qrcode = ""
<fieldset class="cbi-section">
<legend>AP on <%=device%> with SSID "<%=ssid%>"</legend> qrcode = luci.sys.exec("/usr/bin/qrencode --inline --8bit --type=SVG --output=- 'WIFI:S:\"'" .. e_ssid .. "'\";T:'" .. enc .. "';P:\"'" .. e_key .. "'\";H:'" .. hidden .. "';'")
<h3 name="content"><%=qrcode%></h3> -%>
</fieldset> <div class="cbi-section">
<%- <h3>AP on <%=device%> with SSID "<%=ssid%>"</h3>
end <h3><%=qrcode%></h3>
end </div>
end) <%-
%> end
end
end)
-%>
</div> </div>
<div class="cbi-page-actions right"> <div class="cbi-page-actions right">
<form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/tab_from_cbi')%>" method="post"> <form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/tab_from_cbi')%>" method="post">
<input class="cbi-button cbi-button-reset" type="submit" value="<%:Back to overview%>"/> <input class="cbi-button cbi-button-reset" type="submit" value="<%:Back to overview%>" />
</form> </form>
</div> </div>
<%+footer%> <%+footer%>

View file

@ -5,16 +5,47 @@ This is free software, licensed under the Apache License, Version 2.0
<%+header%> <%+header%>
<style type="text/css">
select[readonly],
textarea[readonly]
{
width: 100%;
height: 450px;
border: 1px solid #cccccc;
padding: 5px;
font-size: 12px;
font-family: monospace;
resize: none;
pointer-events: auto;
cursor: auto;
}
</style>
<script type="text/javascript">
//<![CDATA[
function log_update()
{
XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "services", "travelmate", "logread")%>', null,
function(x)
{
if (!x)
{
return;
}
var view = document.getElementById("view_id");
view.value = x.responseText;
view.scrollTop = view.scrollHeight;
});
}
window.onload = log_update();
//]]>
</script>
<div class="cbi-map"> <div class="cbi-map">
<div class="cbi-section"> <div class="cbi-section">
<div class="cbi-section-descr"><%:This form shows the syslog output, pre-filtered for travelmate related messages only.%></div> <div class="cbi-section-descr"><%:The syslog output, pre-filtered for travelmate related messages only.%></div>
<textarea id="logread_id" style="width: 100%; height: 450px; border: 1px solid #cccccc; padding: 5px; font-size: 12px; font-family: monospace; resize: none;" readonly="readonly" wrap="off" rows="<%=content:cmatch("\n")+2%>"><%=content:pcdata()%></textarea> <textarea id="view_id" readonly="readonly" wrap="off" value=""></textarea>
</div> </div>
</div> </div>
<script type="text/javascript">
var textarea = document.getElementById('logread_id');
textarea.scrollTop = textarea.scrollHeight;
</script>
<%+footer%> <%+footer%>

View file

@ -3,8 +3,143 @@ Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
This is free software, licensed under the Apache License, Version 2.0 This is free software, licensed under the Apache License, Version 2.0
-%> -%>
<%+cbi/valueheader%> <style type="text/css">
.runtime
{
color: #37c;
//#0069d6;
font-weight: bold;
display: inline-block;
width: 100%;
padding-top: 0.5rem;
}
</style>
<input name="runtime" id="runtime" type="text" class="cbi-input-text" style="outline:none;border:none;box-shadow:none;background:transparent;color:#0069d6;font-weight:bold;line-height:30px;height:30px;width:50em;" value="<%=self:cfgvalue(section)%>" disabled="disabled" /> <script type="text/javascript">
//<![CDATA[
function status_update(json)
{
var btn1 = document.getElementById("btn1");
var view = document.getElementById("value_1");
var input = json.data.travelmate_status;
btn1.value = "<%:Restart%>";
btn1.name = "do_restart";
view.innerHTML = input || "-";
view = document.getElementById("value_2");
input = json.data.travelmate_version;
view.innerHTML = input || "-";
view = document.getElementById("value_3");
input = json.data.station_id;
view.innerHTML = input || "-";
view = document.getElementById("value_4");
input = json.data.station_interface;
view.innerHTML = input || "-";
view = document.getElementById("value_5");
input = json.data.faulty_stations;
view.innerHTML = input || "-";
view = document.getElementById("value_6");
input = json.data.last_rundate;
view.innerHTML = input || "-";
btn1.disabled = false;
running(btn1_running, 0);
}
<%+cbi/valuefooter%> function btn_action(action)
{
var btn1 = document.getElementById("btn1");
var btn1_running = document.getElementById("btn1_running");
btn1.disabled = true;
running(btn1_running, 1);
new XHR.get('<%=luci.dispatcher.build_url("admin", "services", "travelmate")%>/action/' + action.name, null,
function(x)
{
if (!x)
{
return;
}
});
}
function running(element, state)
{
if (state === 1)
{
var running_html = '<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" width="16" height="16" style="vertical-align:middle" />';
element.innerHTML = running_html;
}
else
{
element.innerHTML = '';
}
}
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "travelmate", "status")%>', null,
function(x, json_info)
{
if (!x || !json_info)
{
return;
}
status_update(json_info)
});
XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "services", "travelmate", "status")%>', null,
function(x, json_info)
{
if (!x || !json_info)
{
return;
}
status_update(json_info)
});
//]]>
</script>
<h3><%:Runtime Information%></h3>
<div class="cbi-value" id="status_1">
<label class="cbi-value-title" for="status_1"><%:Travelmate Status (Quality)%></label>
<div class="cbi-value-field">
<span class="runtime" id="value_1">-</span>
</div>
</div>
<div class="cbi-value" id="status_2">
<label class="cbi-value-title" for="status_2"><%:Travelmate Version%></label>
<div class="cbi-value-field">
<span class="runtime" id="value_2">-</span>
</div>
</div>
<div class="cbi-value" id="status_3">
<label class="cbi-value-title" for="status_3"><%:Station ID (RADIO/SSID/BSSID)%></label>
<div class="cbi-value-field">
<span class="runtime" id="value_3">-</span>
</div>
</div>
<div class="cbi-value" id="status_4">
<label class="cbi-value-title" for="status_4"><%:Station Interface%></label>
<div class="cbi-value-field">
<span class="runtime" id="value_4">-</span>
</div>
</div>
<div class="cbi-value" id="status_5">
<label class="cbi-value-title" for="status_5"><%:Faulty Stations%></label>
<div class="cbi-value-field">
<span class="runtime" id="value_5">-</span>
</div>
</div>
<div class="cbi-value" id="status_6">
<label class="cbi-value-title" for="status_6"><%:Last Run%></label>
<div class="cbi-value-field">
<span class="runtime" id="value_6">-</span>
</div>
</div>
<hr />
<div class="cbi-value" id="button_1">
<label class="cbi-value-title" for="button_1"><%:Restart Travelmate%></label>
<div class="cbi-value-field">
<input class="cbi-button cbi-button-reset" id="btn1" type="button" value="" onclick="btn_action(this)" />
<span id="btn1_running" style="display:inline-block; width:16px; height:16px; margin:0 5px"></span>
</div>
</div>

View file

@ -4,75 +4,151 @@ This is free software, licensed under the Apache License, Version 2.0
-%> -%>
<%- <%-
local write = io.write local uci = require("luci.model.uci").cursor()
local uci = require("luci.model.uci").cursor() local trmiface = uci:get("travelmate", "global", "trm_iface") or "trm_wwan"
local trmiface = uci:get("travelmate", "global", "trm_iface") or "trm_wwan"
-%> -%>
<%+header%> <%+header%>
<script type="text/javascript">
//<![CDATA[
function status_update(json)
{
var i;
var j;
var search;
var view;
var list;
var status = json.data.travelmate_status;
var faulty = json.data.faulty_stations;
if (faulty)
{
var faulty_array = faulty.split(' ');
for (i = 0; i < faulty_array.length; i++)
{
for (j = 1; j <= 5; j++)
{
search = j + "_" + faulty_array[i];
view = document.getElementById(search);
if (view)
{
view.setAttribute("name", "station_nok");
view.setAttribute("style", "color: #a22; font-weight: bold");
}
}
}
}
else
{
list = document.getElementsByName("station_nok");
if (list.length > 0)
{
for (i = 0; i < list.length; i++)
{
list[i].removeAttribute("style");
}
}
}
if (status.startsWith("connected"))
{
for (i = 1; i <= 5; i++)
{
search = i + "_" + json.data.station_id;
view = document.getElementById(search);
if (view)
{
view.setAttribute("style", "color: #37c; font-weight: bold");
}
}
}
else
{
list = document.getElementsByName("station_ok");
if (list.length > 0)
{
for (i = 0; i < list.length; i++)
{
list[i].removeAttribute("style");
}
}
}
}
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "travelmate", "status")%>', null,
function(x, json_info)
{
if (!x || !json_info)
{
return;
}
status_update(json_info)
});
XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "services", "travelmate", "status")%>', null,
function(x, json_info)
{
if (!x || !json_info)
{
return;
}
status_update(json_info)
});
//]]>
</script>
<div class="cbi-map"> <div class="cbi-map">
<div class="cbi-map-descr"> <div class="cbi-map-descr">
<%=translatef("Provides an overview of all configured uplinks for the travelmate interface (%s). You can edit, delete or re-order existing uplinks or scan for a new one. The currently used uplink is emphasized in blue.", trmiface)%> <%=translatef("Provides an overview of all configured uplinks for the travelmate interface (%s). You can edit, delete or re-order existing uplinks or scan for a new one. The currently used uplink is emphasized in blue, faulty stations in red.", trmiface)%>
</div> </div>
<div class="cbi-section"> <div class="cbi-section">
<div class="table cbi-section-table"> <div class="table cbi-section-table">
<div class="tr cbi-section-table-titles"> <div class="tr cbi-section-table-titles">
<div class="th left"><%:Device%></div> <div class="th left"><%:Device%></div>
<div class="th left"><%:SSID%></div> <div class="th left"><%:SSID%></div>
<div class="th left"><%:BSSID%></div> <div class="th left"><%:BSSID%></div>
<div class="th left"><%:Encryption%></div> <div class="th left"><%:Encryption%></div>
<div class="th center">&#160;</div> <div class="th center"><%:Action%></div>
</div> </div>
<% <%- uci:foreach("wireless", "wifi-iface", function(s)
uci:foreach("wireless", "wifi-iface", function(s) local iface = s.network or ""
local iface = s.network or "" if iface == trmiface then
if iface == trmiface then local section = s['.name'] or ""
local section = s['.name'] or "" local device = s.device or "-"
local device = s.device or "-" local ssid = s.ssid or "-"
local ssid = s.ssid or "-" local bssid = s.bssid or "-"
local bssid = s.bssid or "-" local encr = s.encryption or "-"
local encryption = s.encryption or "-" -%>
local disabled = s.disabled or "" <div class="tr cbi-section-table-row cbi-rowstyle-1" name="station_ok" id="1_<%=device%>/<%=ssid%>/<%=bssid%>">
local style = "text-align:left;color:#000000" <div class="td left" name="station_ok" id="2_<%=device%>/<%=ssid%>/<%=bssid%>"><%=device%></div>
if disabled == "0" then <div class="td left" name="station_ok" id="3_<%=device%>/<%=ssid%>/<%=bssid%>"><%=ssid%></div>
style = "text-align:left;color:#0069d6;font-weight:bold" <div class="td left" name="station_ok" id="4_<%=device%>/<%=ssid%>/<%=bssid%>"><%=bssid%></div>
end <div class="td left" name="station_ok" id="5_<%=device%>/<%=ssid%>/<%=bssid%>"><%=encr%></div>
%> <div class="td middle cbi-section-actions">
<div class="tr cbi-section-table-row cbi-rowstyle-1" style="<%=style%>"> <div>
<div class="td" style="<%=style%>"><%=device%></div> <input class="cbi-button cbi-button-up" type="button" value="<%:Up%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiorder')%>?cfg=<%=section%>&amp;dir=up'" alt="<%:Move up%>" title="<%:Move up%>" />
<div class="td" style="<%=style%>"><%=ssid%></div> <input class="cbi-button cbi-button-down" type="button" value="<%:Down%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiorder')%>?cfg=<%=section%>&amp;dir=down'" alt="<%:Move down%>" title="<%:Move down%>" />
<div class="td" style="<%=style%>"><%=bssid%></div> <input class="cbi-button cbi-button-edit" type="button" value="<%:Edit%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiedit')%>?cfg=<%=section%>'" title="<%:Edit this Uplink%>" />
<div class="td" style="<%=style%>"><%=encryption%></div> <input class="cbi-button cbi-button-remove" type="button" value="<%:Delete%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifidelete')%>?cfg=<%=section%>'" title="<%:Delete this Uplink%>" />
<div class="td cbi-section-actions"> </div>
<input class="cbi-button cbi-button-up" type="button" value="<%:Up%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiorder')%>?cfg=<%=section%>&amp;dir=up'" alt="<%:Move up%>" title="<%:Move up%>"/> </div>
<input class="cbi-button cbi-button-down" type="button" value="<%:Down%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiorder')%>?cfg=<%=section%>&amp;dir=down'" alt="<%:Move down%>" title="<%:Move down%>"/> </div>
<input type="button" class="cbi-button cbi-button-edit" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiedit')%>?cfg=<%=section%>'" title="<%:Edit this Uplink%>" value="<%:Edit%>"/> <%- end; end) -%>
<input type="button" class="cbi-button cbi-button-remove" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifidelete')%>?cfg=<%=section%>'" title="<%:Delete this Uplink%>" value="<%:Delete%>"/> </div>
</div> </div>
</div> <div class="cbi-page-actions right">
<% <%- uci:foreach("wireless", "wifi-device", function(s)
end local device = s[".name"]
end) local hwmode = s.hwmode or "-" -%>
%> <form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/wifiscan')%>" method="post">
</div> <input type="hidden" name="device" value="<%=device%>" />
</div> <input type="hidden" name="token" value="<%=token%>" />
<div class="cbi-page-actions right"> <input type="submit" class="cbi-button cbi-button-action important" title="<%:Find and join network on%> <%=device%>" value="<%:Scan%> <%=device%> (<%=hwmode%>)" />
<% </form>
uci:foreach("wireless", "wifi-device", function(s) <%- end) -%>
local device = s[".name"] </div>
%>
<form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/wifiscan')%>" method="post">
<input type="hidden" name="device" value="<%=device%>"/>
<input type="hidden" name="token" value="<%=token%>"/>
<input type="submit" class="cbi-button cbi-button-action important" title="<%:Find and join network on%> <%=device%>" value="<%:Scan%> <%=device%>"/>
</form>
<%
end)
%>
</div>
</div> </div>
<%+footer%> <%+footer%>

View file

@ -0,0 +1,70 @@
<%#
Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
This is free software, licensed under the Apache License, Version 2.0
-%>
<%-
local uci = require("luci.model.uci").cursor()
local trmiface = uci:get("travelmate", "global", "trm_iface") or "trm_wwan"
-%>
<%+header%>
<div class="cbi-map">
<div class="cbi-map-descr">
<%=translatef("Provides an overview of all configured uplinks for the travelmate interface (%s). You can edit, delete or re-order existing uplinks or scan for a new one. The currently used uplink is emphasized in blue.", trmiface)%>
</div>
<div class="cbi-section">
<div class="table cbi-section-table">
<div class="tr cbi-section-table-titles">
<div class="th left"><%:Device%></div>
<div class="th left"><%:SSID%></div>
<div class="th left"><%:BSSID%></div>
<div class="th left"><%:Encryption%></div>
<div class="th center"><%:Action%></div>
</div>
<%- uci:foreach("wireless", "wifi-iface", function(s)
local iface = s.network or ""
if iface == trmiface then
local section = s['.name'] or ""
local device = s.device or "-"
local ssid = s.ssid or "-"
local bssid = s.bssid or "-"
local encr = s.encryption or "-"
local disabled = s.disabled or ""
local style = "text-align:left;color:#000000"
if disabled == "0" then
style = "text-align:left;color:#0069d6;font-weight:bold"
end -%>
<div class="tr cbi-section-table-row cbi-rowstyle-1" style="<%=style%>">
<div class="td" style="<%=style%>"><%=device%></div>
<div class="td" style="<%=style%>"><%=ssid%></div>
<div class="td" style="<%=style%>"><%=bssid%></div>
<div class="td" style="<%=style%>"><%=encr%></div>
<div class="td middle cbi-section-actions">
<div>
<input class="cbi-button cbi-button-up" type="button" value="<%:Up%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiorder')%>?cfg=<%=section%>&amp;dir=up'" alt="<%:Move up%>" title="<%:Move up%>" />
<input class="cbi-button cbi-button-down" type="button" value="<%:Down%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiorder')%>?cfg=<%=section%>&amp;dir=down'" alt="<%:Move down%>" title="<%:Move down%>" />
<input class="cbi-button cbi-button-edit" type="button" value="<%:Edit%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifiedit')%>?cfg=<%=section%>'" title="<%:Edit this Uplink%>" />
<input class="cbi-button cbi-button-remove" type="button" value="<%:Delete%>" onclick="location.href='<%=luci.dispatcher.build_url('admin/services/travelmate/wifidelete')%>?cfg=<%=section%>'" title="<%:Delete this Uplink%>" />
</div>
</div>
</div>
<%- end; end) -%>
</div>
</div>
<div class="cbi-page-actions right">
<%- uci:foreach("wireless", "wifi-device", function(s)
local device = s[".name"]
local hwmode = s.hwmode or "-" -%>
<form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/wifiscan')%>" method="post">
<input type="hidden" name="device" value="<%=device%>" />
<input type="hidden" name="token" value="<%=token%>" />
<input type="submit" class="cbi-button cbi-button-action important" title="<%:Find and join network on%> <%=device%>" value="<%:Scan%> <%=device%> (<%=hwmode%>)" />
</form>
<%- end) -%>
</div>
</div>
<%+footer%>

View file

@ -1,97 +1,99 @@
<%# <%#
Copyright 2017 Dirk Brenken (dev@brenken.org) Copyright 2017-2018 Dirk Brenken (dev@brenken.org)
This is free software, licensed under the Apache License, Version 2.0 This is free software, licensed under the Apache License, Version 2.0
-%> -%>
<%- <%-
local sys = require("luci.sys") local sys = require("luci.sys")
local utl = require("luci.util") local utl = require("luci.util")
local dev = luci.http.formvalue("device") local dev = luci.http.formvalue("device")
local iw = luci.sys.wifi.getiwinfo(dev) local iw = luci.sys.wifi.getiwinfo(dev)
local wpa_label = {translate("WPA"), translate("WPA2"), translate("WPA/WPA2")} local label = {translate("WPA"), translate("WPA2"), translate("WPA/WPA2")}
if not iw then if not iw then
luci.http.redirect(luci.dispatcher.build_url("admin/services/travelmate/stations")) luci.http.redirect(luci.dispatcher.build_url("admin/services/travelmate/stations"))
end end
function format_wifi_encryption(info) function format_wifi_encryption(info)
if info.wep == true then if info.wep == true then
return translate("WEP") return translate("WEP")
elseif info.wpa > 0 then elseif info.wpa > 0 then
return "%s (%s/%s)" %{wpa_label[info.wpa], table.concat(info.auth_suites), table.concat(info.group_ciphers)} return "%s (%s/%s)" %{label[info.wpa], table.concat(info.auth_suites), table.concat(info.group_ciphers)}
elseif info.enabled then elseif info.enabled then
return translate("Unknown") return translate("Unknown")
else else
return translate("Open") return translate("Open")
end end
end end
function percent_wifi_signal(info) function percent_wifi_signal(info)
local qc = info.quality or 0 local qc = info.quality or 0
local qm = info.quality_max or 0 local qm = info.quality_max or 0
if info.bssid and qc > 0 and qm > 0 then if info.bssid and qc > 0 and qm > 0 then
return math.floor((100 / qm) * qc) return math.floor((100 / qm) * qc)
else else
return 0 return 0
end end
end end
-%> -%>
<%+header%> <%+header%>
<div class="cbi-map"> <div class="cbi-map">
<h2 name="content"><%:Wireless Scan%></h2> <h3><%:Wireless Scan%></h3>
<div class="cbi-section"> <div class="cbi-section">
<div class="table cbi-section-table"> <div class="table cbi-section-table">
<div class="tr cbi-section-table-titles"> <div class="tr cbi-section-table-titles">
<div class="th left"><%:Uplink SSID%></div> <div class="th left"><%:Uplink SSID%></div>
<div class="th left"><%:Uplink BSSID%></div> <div class="th left"><%:Uplink BSSID%></div>
<div class="th left"><%:Encryption%></div> <div class="th left"><%:Encryption%></div>
<div class="th left"><%:Signal strength%></div> <div class="th left"><%:Signal strength%></div>
</div> <div class="th center"><%:Action%></div>
<% for i, net in ipairs(iw.scanlist or { }) do %> </div>
<div class="tr cbi-section-table-row cbi-rowstyle-1"> <%- for i, net in ipairs(iw.scanlist or { }) do -%>
<div class="td left"> <div class="tr cbi-section-table-row cbi-rowstyle-1">
<%=net.ssid and utl.pcdata(net.ssid) or "<em>%s</em>" % translate("hidden")%> <div class="td left">
</div> <%=net.ssid and utl.pcdata(net.ssid) or "<em>%s</em>" % translate("hidden")%>
<div class="td left"> </div>
<%=net.bssid and utl.pcdata(net.bssid)%> <div class="td left">
</div> <%=net.bssid and utl.pcdata(net.bssid)%>
<div class="td left"> </div>
<%=format_wifi_encryption(net.encryption)%> <div class="td left">
</div> <%=format_wifi_encryption(net.encryption)%>
<div class="td left"> </div>
<%=percent_wifi_signal(net)%> % <div class="td left">
</div> <%=percent_wifi_signal(net)%> %
<div class="td cbi-section-actions"> </div>
<form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/wifiadd')%>" method="post"> <div class="td cbi-section-actions">
<input type="hidden" name="token" value="<%=token%>"/> <form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/wifiadd')%>" method="post">
<input type="hidden" name="device" value="<%=utl.pcdata(dev)%>"/> <input type="hidden" name="token" value="<%=token%>"/>
<input type="hidden" name="ssid" value="<%=utl.pcdata(net.ssid)%>"/> <input type="hidden" name="device" value="<%=utl.pcdata(dev)%>"/>
<input type="hidden" name="bssid" value="<%=utl.pcdata(net.bssid)%>"/> <input type="hidden" name="ssid" value="<%=utl.pcdata(net.ssid)%>"/>
<input type="hidden" name="wep" value="<%=net.encryption.wep and 1 or 0%>"/> <input type="hidden" name="bssid" value="<%=utl.pcdata(net.bssid)%>"/>
<% if net.encryption.wpa then %> <input type="hidden" name="wep" value="<%=net.encryption.wep and 1 or 0%>"/>
<input type="hidden" name="wpa_version" value="<%=net.encryption.wpa%>"/> <%- if net.encryption.wpa then -%>
<% for _, v in ipairs(net.encryption.auth_suites) do %><input type="hidden" name="wpa_suites" value="<%=v%>"/><% end %> <input type="hidden" name="wpa_version" value="<%=net.encryption.wpa%>"/>
<% end %> <%- for _, v in ipairs(net.encryption.auth_suites) do -%>
<input class="cbi-button cbi-button-apply" type="submit" value="<%:Add Uplink%>"/> <input type="hidden" name="wpa_suites" value="<%=v%>"/>
</form> <%- end -%>
</div> <%- end -%>
</div> <input class="cbi-button cbi-button-apply" type="submit" value="<%:Add Uplink%>"/>
<% end %> </form>
</div> </div>
</div> </div>
<div class="cbi-page-actions right"> <%- end -%>
<form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/stations')%>" method="get"> </div>
<input class="cbi-button cbi-button-reset" type="submit" value="<%:Back to overview%>"/> </div>
</form> <div class="cbi-page-actions right">
<form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/wifiscan')%>" method="post"> <form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/stations')%>" method="get">
<input type="hidden" name="token" value="<%=token%>"/> <input class="cbi-button cbi-button-reset" type="submit" value="<%:Back to overview%>"/>
<input type="hidden" name="device" value="<%=utl.pcdata(dev)%>"/> </form>
<input class="cbi-button cbi-input-find" type="submit" value="<%:Repeat scan%>"/> <form class="inline" action="<%=luci.dispatcher.build_url('admin/services/travelmate/wifiscan')%>" method="post">
</form> <input type="hidden" name="token" value="<%=token%>"/>
</div> <input type="hidden" name="device" value="<%=utl.pcdata(dev)%>"/>
<input class="cbi-button cbi-input-find" type="submit" value="<%:Repeat scan%>"/>
</form>
</div>
</div> </div>
<%+footer%> <%+footer%>