diff options
12 files changed, 707 insertions, 557 deletions
diff --git a/applications/luci-olsr/luasrc/controller/olsr.lua b/applications/luci-olsr/luasrc/controller/olsr.lua index fc44820dc9..c1b6ed9f44 100644 --- a/applications/luci-olsr/luasrc/controller/olsr.lua +++ b/applications/luci-olsr/luasrc/controller/olsr.lua @@ -5,11 +5,23 @@ function index() return end + require("luci.model.uci") + local uci = luci.model.uci.cursor_state() + + uci:foreach("olsrd", "olsrd", function(s) + if s.SmartGateway and s.SmartGateway == "yes" then has_smartgw = true end + end) + local page = node("admin", "status", "olsr") page.target = template("status-olsr/overview") page.title = _("OLSR") page.subindex = true + local page = node("admin", "status", "olsr", "json") + page.target = call("action_json") + page.title = nil + page.leaf = true + local page = node("admin", "status", "olsr", "neighbors") page.target = call("action_neigh") page.title = _("Neighbours") @@ -36,10 +48,12 @@ function index() page.title = _("MID") page.order = 50 - local page = node("admin", "status", "olsr", "smartgw") - page.target = call("action_smartgw") - page.title = _("SmartGW") - page.order = 60 + if has_smartgw then + local page = node("admin", "status", "olsr", "smartgw") + page.target = call("action_smartgw") + page.title = _("SmartGW") + page.order = 60 + end local page = node("admin", "status", "olsr", "interfaces") page.target = call("action_interfaces") @@ -88,286 +102,231 @@ function index() ) end -local function compare_links(a, b) - local c = tonumber(a.Cost) - local d = tonumber(b.Cost) +function action_json() + local http = require "luci.http" + local utl = require "luci.util" - if not c or c == 0 then - return false - end + local jsonreq4 = utl.exec("echo /status | nc 127.0.0.1 9090") + local jsonreq6 = utl.exec("echo /status | nc ::1 9090") - if not d or d == 0 then - return true - end - return c < d + http.prepare_content("application/json") + http.write("{v4:" .. jsonreq4 .. ", v6:" .. jsonreq6 .. "}") end function action_neigh(json) - local data = fetch_txtinfo("links") + local data, has_v4, has_v6, error = fetch_jsoninfo('links') - if not data or not data.Links then - luci.template.render("status-olsr/error_olsr") - return nil + if error then + return + end + + local uci = require "luci.model.uci".cursor_state() + local resolve = uci:get("luci_olsr", "general", "resolve") + luci.sys.net.routes(function(r) if r.dest:prefix() == 0 then defaultgw = r.gateway:string() end end) + + local function compare(a,b) + if a.proto == b.proto then + return a.linkCost < b.linkCost + else + return a.proto < b.proto + end end - table.sort(data.Links, compare_links) + for k, v in ipairs(data) do + if resolve == "1" then + hostname = nixio.getnameinfo(v.remoteIP) + if hostname then + v.hostname = hostname + end + end + if defaultgw == v.remoteIP then + v.defaultgw = 1 + end + end - luci.template.render("status-olsr/neighbors", {links=data.Links}) + table.sort(data, compare) + luci.template.render("status-olsr/neighbors", {links=data, has_v4=has_v4, has_v6=has_v6}) end function action_routes() - local data = fetch_txtinfo("routes") - - if not data or not data.Routes then - luci.template.render("status-olsr/error_olsr") - return nil + local data, has_v4, has_v6, error = fetch_jsoninfo('routes') + if error then + return end - local function compare(a, b) - local c = tonumber(a.ETX) - local d = tonumber(b.ETX) + local uci = require "luci.model.uci".cursor_state() + local resolve = uci:get("luci_olsr", "general", "resolve") - if not c or c == 0 then - return false + for k, v in ipairs(data) do + if resolve == "1" then + local hostname = nixio.getnameinfo(v.gateway) + if hostname then + v.hostname = hostname + end end + end - if not d or d == 0 then - return true + local function compare(a,b) + if a.proto == b.proto then + return a.rtpMetricCost < b.rtpMetricCost + else + return a.proto < b.proto end - - return c < d end - table.sort(data.Routes, compare) - - luci.template.render("status-olsr/routes", {routes=data.Routes}) + table.sort(data, compare) + luci.template.render("status-olsr/routes", {routes=data, has_v4=has_v4, has_v6=has_v6}) end function action_topology() - local data = fetch_txtinfo("topology") - - if not data or not data.Topology then - luci.template.render("status-olsr/error_olsr") - return nil + local data, has_v4, has_v6, error = fetch_jsoninfo('topology') + if error then + return end - local function compare(a, b) - return a["Dest. IP"] < b["Dest. IP"] + local function compare(a,b) + if a.proto == b.proto then + return a.tcEdgeCost < b.tcEdgeCost + else + return a.proto < b.proto + end end - table.sort(data.Topology, compare) - - luci.template.render("status-olsr/topology", {routes=data.Topology}) + table.sort(data, compare) + luci.template.render("status-olsr/topology", {routes=data, has_v4=has_v4, has_v6=has_v6}) end function action_hna() - local data = fetch_txtinfo("hna") - - if not data or not data.HNA then - luci.template.render("status-olsr/error_olsr") - return nil + local data, has_v4, has_v6, error = fetch_jsoninfo('hna') + if error then + return end - local function compare(a, b) - return a.Destination < b.Destination + local uci = require "luci.model.uci".cursor_state() + local resolve = uci:get("luci_olsr", "general", "resolve") + + local function compare(a,b) + if a.proto == b.proto then + return a.genmask < b.genmask + else + return a.proto < b.proto + end end - table.sort(data.HNA, compare) + for k, v in ipairs(data) do + if resolve == "1" then + hostname = nixio.getnameinfo(v.gateway) + if hostname then + v.hostname = hostname + end + end + if v.validityTime then + v.validityTime = tonumber(string.format("%.0f", v.validityTime / 1000)) + end + end - luci.template.render("status-olsr/hna", {routes=data.HNA}) + table.sort(data, compare) + luci.template.render("status-olsr/hna", {hna=data, has_v4=has_v4, has_v6=has_v6}) end function action_mid() - local data = fetch_txtinfo("mid") - - if not data or not data.MID then - luci.template.render("status-olsr/error_olsr") - return nil + local data, has_v4, has_v6, error = fetch_jsoninfo('mid') + if error then + return end - local function compare(a, b) - return a["IP address"] < b["IP address"] + local function compare(a,b) + if a.proto == b.proto then + return a.ipAddress < b.ipAddress + else + return a.proto < b.proto + end end - table.sort(data.MID, compare) - - luci.template.render("status-olsr/mid", {mids=data.MID}) + table.sort(data, compare) + luci.template.render("status-olsr/mid", {mids=data, has_v4=has_v4, has_v6=has_v6}) end function action_smartgw() - local data = fetch_txtinfo("gateways") - - if not data or not data.Gateways then - luci.template.render("status-olsr/error_olsr") - return nil - end - - local function compare(a, b) - return a["ETX"] < b["ETX"] - end + local data, has_v4, has_v6, error = fetch_jsoninfo('gateways') + if error then + return + end - table.sort(data.Gateways, compare) + local function compare(a,b) + if a.proto == b.proto then + return a.tcPathCost < b.tcPathCost + else + return a.proto < b.proto + end + end - luci.template.render("status-olsr/smartgw", {gws=data.Gateways}) + table.sort(data, compare) + luci.template.render("status-olsr/smartgw", {gws=data, has_v4=has_v4, has_v6=has_v6}) end function action_interfaces() - local data = fetch_txtinfo("interfaces") + local data, has_v4, has_v6, error = fetch_jsoninfo('interfaces') + if error then + return + end - if not data or not data.Interfaces then - luci.template.render("status-olsr/error_olsr") - return nil - end + local function compare(a,b) + return a.proto < b.proto + end - luci.template.render("status-olsr/interfaces", {iface=data.Interfaces}) + table.sort(data, compare) + luci.template.render("status-olsr/interfaces", {iface=data, has_v4=has_v4, has_v6=has_v6}) end -- Internal -function fetch_txtinfo(otable) - require("luci.sys") - local uci = require "luci.model.uci".cursor_state() - local resolve = uci:get("luci_olsr", "general", "resolve") - otable = otable or "" - local rawdata = luci.sys.httpget("http://127.0.0.1:2006/"..otable) - local rawdatav6 = luci.sys.httpget("http://[::1]:2006/"..otable) - local data = {} - local dataindex = 0 - local name = "" - local defaultgw - - if #rawdata ~= 0 then - local tables = luci.util.split(luci.util.trim(rawdata), "\r?\n\r?\n", nil, true) - - if otable == "links" then - local route = {} - luci.sys.net.routes(function(r) if r.dest:prefix() == 0 then defaultgw = r.gateway:string() end end) - end - - for i, tbl in ipairs(tables) do - local lines = luci.util.split(tbl, "\r?\n", nil, true) - name = table.remove(lines, 1):sub(8) - local keys = luci.util.split(table.remove(lines, 1), "\t") - local split = #keys - 1 - if not data[name] then - data[name] = {} - end - - for j, line in ipairs(lines) do - dataindex = ( dataindex + 1 ) - di = dataindex - local fields = luci.util.split(line, "\t", split) - data[name][di] = {} - for k, key in pairs(keys) do - if key == "Remote IP" or key == "Dest. IP" or key == "Gateway IP" or key == "Gateway" then - data[name][di][key] = fields[k] - if resolve == "1" then - hostname = nixio.getnameinfo(fields[k], "inet") - if hostname then - data[name][di]["Hostname"] = hostname - end - end - if key == "Remote IP" and defaultgw then - if defaultgw == fields[k] then - data[name][di]["defaultgw"] = 1 - end - end - elseif key == "Local IP" then - data[name][di][key] = fields[k] - data[name][di]['Local Device'] = fields[k] - uci:foreach("network", "interface", - function(s) - localip = string.gsub(fields[k], ' ', '') - if s.ipaddr == localip then - data[name][di]['Local Device'] = s['.name'] or interface - end - end) - elseif key == "Interface" then - data[name][di][key] = fields[k] - uci:foreach("network", "interface", - function(s) - interface = string.gsub(fields[k], ' ', '') - if s.ifname == interface then - data[name][di][key] = s['.name'] or interface - end - end) - else - data[name][di][key] = fields[k] - end - end - if data[name][di].Linkcost then - data[name][di].LinkQuality, - data[name][di].NLQ, - data[name][di].ETX = - data[name][di].Linkcost:match("([%w.]+)/([%w.]+)[%s]+([%w.]+)") - end - end - end +function fetch_jsoninfo(otable) + local utl = require "luci.util" + local json = require "luci.json" + local jsonreq4 = utl.exec("echo /" .. otable .. " | nc 127.0.0.1 9090") + local jsondata4 = {} + local jsonreq6 = utl.exec("echo /" .. otable .. " | nc ::1 9090") + local jsondata6 = {} + local data4 = {} + local data6 = {} + local has_v4 = False + local has_v6 = False + + if jsonreq4 == '' and jsonreq6 == '' then + luci.template.render("status-olsr/error_olsr") + return nil, 0, 0, true end - if #rawdatav6 ~= 0 then - local tables = luci.util.split(luci.util.trim(rawdatav6), "\r?\n\r?\n", nil, true) - for i, tbl in ipairs(tables) do - local lines = luci.util.split(tbl, "\r?\n", nil, true) - name = table.remove(lines, 1):sub(8) - local keys = luci.util.split(table.remove(lines, 1), "\t") - local split = #keys - 1 - if not data[name] then - data[name] = {} - end - for j, line in ipairs(lines) do - dataindex = ( dataindex + 1 ) - di = dataindex - local fields = luci.util.split(line, "\t", split) - data[name][di] = {} - for k, key in pairs(keys) do - if key == "Remote IP" then - data[name][di][key] = "[" .. fields[k] .. "]" - if resolve == "1" then - hostname = nixio.getnameinfo(fields[k], "inet6") - if hostname then - data[name][di]["Hostname"] = hostname - end - end - elseif key == "Local IP" then - data[name][di][key] = fields[k] - data[name][di]['Local Device'] = fields[k] - uci:foreach("network", "interface", - function(s) - local localip = string.gsub(fields[k], ' ', ''):upper() - localip = luci.ip.IPv6(localip):string() - if s.ip6addr then - s.ip6addr = luci.ip.IPv6(s.ip6addr):string() - local ip6addr = string.gsub(s.ip6addr, '\/.*', ''):upper() - if ip6addr == localip then - data[name][di]['Local Device'] = s['.name'] or s.interface - end - end - end) - elseif key == "Dest. IP" then - data[name][di][key] = "[" .. fields[k] .. "]" - elseif key == "Last hop IP" then - data[name][di][key] = "[" .. fields[k] .. "]" - elseif key == "IP address" then - data[name][di][key] = "[" .. fields[k] .. "]" - elseif key == "Gateway" then - data[name][di][key] = "[" .. fields[k] .. "]" - else - data[name][di][key] = fields[k] - end - end - - if data[name][di].Linkcost then - data[name][di].LinkQuality, - data[name][di].NLQ, - data[name][di].ETX = - data[name][di].Linkcost:match("([%w.]+)/([%w.]+)[%s]+([%w.]+)") - end - end + if #jsonreq4 ~= 0 then + has_v4 = 1 + jsondata4 = json.decode(jsonreq4) + if otable == 'status' then + data4 = jsondata4 + else + data4 = jsondata4[otable] end - end + for k, v in ipairs(data4) do + data4[k]['proto'] = '4' + end + end + if #jsonreq6 ~= 0 then + has_v6 = 1 + jsondata6 = json.decode(jsonreq6) + if otable == 'status' then + data6 = jsondata6 + else + data6 = jsondata6[otable] + end + for k, v in ipairs(data6) do + data6[k]['proto'] = '6' + end + end - if data then - return data + for k, v in ipairs(data6) do + table.insert(data4, v) end + + return data4, has_v4, has_v6, false end + diff --git a/applications/luci-olsr/luasrc/view/status-olsr/common_js.htm b/applications/luci-olsr/luasrc/view/status-olsr/common_js.htm new file mode 100644 index 0000000000..1ee763e119 --- /dev/null +++ b/applications/luci-olsr/luasrc/view/status-olsr/common_js.htm @@ -0,0 +1,35 @@ +<% if has_v4 and has_v6 then %> +<script type="text/javascript">//<![CDATA[ + +function css(selector, property, value) { + for (var i=0; i<document.styleSheets.length;i++) { + try { document.styleSheets[i].insertRule(selector+ ' {'+property+':'+value+'}', document.styleSheets[i].cssRules.length); + } catch(err) {try { document.styleSheets[i].addRule(selector, property+':'+value);} catch(err) {}}//IE + } +} + +window.onload = function() { + buttons = '<input type="button" name="show-proto-4" id="show-proto-4" class="cbi-button cbi-button-apply" style="margin-right: 5px" value="<%:Hide IPv4%>">' + buttons += '<input type="button" name="show-proto-6" id="show-proto-6" class="cbi-button cbi-button-apply" value="<%:Hide IPv6%>">' + + document.getElementById('togglebuttons').innerHTML = buttons; + + var visible = true; + document.getElementById('show-proto-4').onclick = function() { + visible = !visible; + document.getElementById('show-proto-4').value = visible ? '<%:Hide IPv4%>' : '<%:Show IPv4%>'; + document.getElementById('show-proto-4').className = visible ? 'cbi-button cbi-button-apply' : 'cbi-button cbi-button-reset'; + css('.proto-4', 'display', visible ? 'table-row' : 'none') + }; + + var visible6 = true; + document.getElementById('show-proto-6').onclick = function() { + visible6 = !visible6; + document.getElementById('show-proto-6').value = visible6 ? '<%:Hide IPv6%>' : '<%:Show IPv6%>'; + document.getElementById('show-proto-6').className = visible6 ? 'cbi-button cbi-button-apply' : 'cbi-button cbi-button-reset'; + css('.proto-6', 'display', visible6 ? 'table-row' : 'none') + }; + +} +//]]></script> +<%end %> diff --git a/applications/luci-olsr/luasrc/view/status-olsr/error_olsr.htm b/applications/luci-olsr/luasrc/view/status-olsr/error_olsr.htm index 97142a689a..2c872fa5a2 100644 --- a/applications/luci-olsr/luasrc/view/status-olsr/error_olsr.htm +++ b/applications/luci-olsr/luasrc/view/status-olsr/error_olsr.htm @@ -9,11 +9,9 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -$Id$ - -%> <%+header%> <h2><a id="content" name="content"><%:OLSR Daemon%></a></h2> <p class="error"><%:Unable to connect to the OLSR daemon!%></p> -<p><%:Make sure that OLSRd is running, the "txtinfo" plugin is loaded, configured on port 2006 and accepts connections from "127.0.0.1".%></p> +<p><%:Make sure that OLSRd is running, the "jsoninfo" plugin is loaded, configured on port 9090 and accepts connections from "127.0.0.1".%></p> <%+footer%> diff --git a/applications/luci-olsr/luasrc/view/status-olsr/hna.htm b/applications/luci-olsr/luasrc/view/status-olsr/hna.htm index bde1f009b5..689bafdfae 100644 --- a/applications/luci-olsr/luasrc/view/status-olsr/hna.htm +++ b/applications/luci-olsr/luasrc/view/status-olsr/hna.htm @@ -10,39 +10,120 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -$Id$ - -%> + <% local i = 1 + +if luci.http.formvalue("status") == "1" then + local rv = {} + for k, hna in ipairs(hna) do + rv[#rv+1] = { + proto = hna["proto"], + destination = hna["destination"], + genmask = hna["genmask"], + gateway = hna["gateway"], + hostname = hna["hostname"], + validityTime = hna["validityTime"] + } + end + luci.http.prepare_content("application/json") + luci.http.write_json(rv) + return +end %> <%+header%> +<script type="text/javascript" src="<%=resource%>/cbi.js"></script> +<script type="text/javascript">//<![CDATA[ +XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 }, + function(x, info) + { + var hnadiv = document.getElementById('olsrd_hna'); + if (hnadiv) + { + var s = ''; + for (var idx = 0; idx < info.length; idx++) + { + var hna = info[idx]; + var linkgw = '' + s += '<tr class="cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+' proto-' + hna.proto + '">' + if (hna.proto == '6') { + linkgw = '<a href="http://[' + hna.gateway + ']/cgi-bin-status.html">' + hna.gateway + '</a>' + } else { + linkgw = '<a href="http://' + hna.gateway + '/cgi-bin-status.html">' + hna.gateway + '</a>' + } + + if (hna.validityTime != undefined) { + validity = hna.validityTime + 's' + } else { + validity = '-' + } + + if (hna.hostname != undefined) { + hostname = ' / <a href="http://' + hna.hostname + '/cgi-bin-status.html">' + hna.hostname + '</a>' + } else { + hostname = '' + } + + s += String.format( + '<td class="cbi-section-table-cell">%s</td>' + + '<td class="cbi-section-table-cell">%s</td>' + + '<td class="cbi-section-table-cell">%s</td>', hna.destination + '/' + hna.genmask, linkgw + hostname, validity + ) + s += '</tr>' + } + hnadiv.innerHTML = s; + } +} +); +//]]></script> + <h2><a id="content" name="content"><%:Active host net announcements%></a></h2> +<div id="togglebuttons"></div> <fieldset class="cbi-section"> + <legend><%:Overview of currently active OLSR host net announcements%></legend> <table class="cbi-section-table"> + <thead> <tr class="cbi-section-table-titles"> <th class="cbi-section-table-cell"><%:Announced network%></th> <th class="cbi-section-table-cell"><%:OLSR gateway%></th> + <th class="cbi-section-table-cell"><%:Validity Time%></th> </tr> - <% for k, route in ipairs(routes) do %> + </thead> + <tbody id="olsrd_hna"> + <% for k, route in ipairs(hna) do %> - <tr class="cbi-section-table-row cbi-rowstyle-<%=i%>"> - <td class="cbi-section-table-cell"><%=route.Destination%></td> + <tr class="cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=hna[k].proto%>"> + <td class="cbi-section-table-cell"><%=hna[k].destination%>/<%=hna[k].genmask%> </td> <td class="cbi-section-table-cell"> - <a href="http://<%=route.Gateway%>/cgi-bin-status.html"><%=route.Gateway%></a> - <% if route.Hostname then %> - / <a href="http://<%=route.Hostname%>/cgi-bin-status.html"><%=route.Hostname%></a> + <% if hna[k].proto == '6' then %> + <a href="http://[<%=hna[k].gateway%>]/cgi-bin-status.html"><%=hna[k].gateway%></a> + <% else %> + <a href="http://<%=hna[k].gateway%>/cgi-bin-status.html"><%=hna[k].gateway%></a> + <% end %> + <% if hna[k].hostname then %> + / <a href="http://<%=hna[k].hostname%>/cgi-bin-status.html"><%=hna[k].hostname%></a> <% end %> </td> + <% if hna[k].validityTime then + validity = hna[k].validityTime .. 's' + else + validity = '-' + end %> + + <td class="cbi-section-table-cell"><%=validity%></td> </tr> <% i = ((i % 2) + 1) end %> + </tbody> </table> </fieldset> + +<%+status-olsr/common_js%> <%+footer%> diff --git a/applications/luci-olsr/luasrc/view/status-olsr/interfaces.htm b/applications/luci-olsr/luasrc/view/status-olsr/interfaces.htm index 17090ff4aa..dd1a21ea6d 100644 --- a/applications/luci-olsr/luasrc/view/status-olsr/interfaces.htm +++ b/applications/luci-olsr/luasrc/view/status-olsr/interfaces.htm @@ -10,8 +10,6 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -$Id: mid.htm 5448 2009-10-31 15:54:11Z jow $ - -%> <% @@ -22,6 +20,8 @@ local i = 1 <h2><a id="content" name="content"><%:Interfaces%></a></h2> +<div id="togglebuttons"></div> + <fieldset class="cbi-section"> <legend><%:Overview of interfaces where OLSR is running%></legend> @@ -38,17 +38,20 @@ local i = 1 <% for k, iface in ipairs(iface) do %> - <tr class="cbi-section-table-row cbi-rowstyle-<%=i%>"> - <td class="cbi-section-table-cell"><%=iface.Name%></td> - <td class="cbi-section-table-cell"><%=iface.State%></td> - <td class="cbi-section-table-cell"><%=iface.MTU%></td> - <td class="cbi-section-table-cell"><%=iface.WLAN%></td> - <td class="cbi-section-table-cell"><%=iface["Src-Adress"]%></td> - <td class="cbi-section-table-cell"><%=iface.Mask%></td> - <td class="cbi-section-table-cell"><%=iface["Dst-Adress"]%></td> + <tr class="cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=iface.proto%>"> + <td class="cbi-section-table-cell"><%=iface.name%></td> + <td class="cbi-section-table-cell"><%=iface.state%></td> + <td class="cbi-section-table-cell"><%=iface.olsrMTU%></td> + <td class="cbi-section-table-cell"><%=iface.wireless and luci.i18n.translate('yes') or luci.i18n.translate('no')%></td> + <td class="cbi-section-table-cell"><%=iface.ipv4Address or iface.ipv6Address%></td> + <td class="cbi-section-table-cell"><%=iface.netmask%></td> + <td class="cbi-section-table-cell"><%=iface.broadcast or iface.multicast%></td> </tr> <% i = ((i % 2) + 1) end %> </table> </fieldset> +<%+status-olsr/common_js%> <%+footer%> + + diff --git a/applications/luci-olsr/luasrc/view/status-olsr/legend.htm b/applications/luci-olsr/luasrc/view/status-olsr/legend.htm new file mode 100644 index 0000000000..55b839f52f --- /dev/null +++ b/applications/luci-olsr/luasrc/view/status-olsr/legend.htm @@ -0,0 +1,11 @@ +<h3><%:Legend%>:</h3> +<ul> + <li><strong>LQ: </strong><%:Success rate of packages received from the neighbour%></li> + <li><strong>NLQ: </strong><%:Success rate of packages sent to the neighbour%></li> + <li><strong>ETX: </strong><%:Expected retransmission count%></li> + <li><strong><span style="color:#00cc00"><%:Green%></span></strong>:<%:Very good (ETX < 2)%></li> + <li><strong><span style="color:#ffcb05"><%:Yellow%></span></strong>:<%:Good (2 < ETX < 4)%></li> + <li><strong><span style="color:#ff6600"><%:Orange%></span></strong>:<%:Still usable (4 < ETX < 10)%></li> + <li><strong><span style="color:#bb3333"><%:Red%></span></strong>:<%:Bad (ETX > 10)%></li> +</ul> + diff --git a/applications/luci-olsr/luasrc/view/status-olsr/mid.htm b/applications/luci-olsr/luasrc/view/status-olsr/mid.htm index 48823b5bc1..ec5caaa953 100644 --- a/applications/luci-olsr/luasrc/view/status-olsr/mid.htm +++ b/applications/luci-olsr/luasrc/view/status-olsr/mid.htm @@ -20,6 +20,7 @@ local i = 1 <%+header%> <h2><a id="content" name="content"><%:Active MID announcements%></a></h2> +<div id="togglebuttons"></div> <fieldset class="cbi-section"> <legend><%:Overview of known multiple interface announcements%></legend> <table class="cbi-section-table"> @@ -28,15 +29,30 @@ local i = 1 <th class="cbi-section-table-cell" ><%:Secondary OLSR interfaces%></th> </tr> - <% for k, mid in ipairs(mids) do %> - - <tr class="cbi-section-table-row cbi-rowstyle-<%=i%>"> - <td class="cbi-section-table-cell"><a href="http://<%=mid["IP address"]%>/cgi-bin-status.html"><%=mid["IP address"]%></a></td> - <td class="cbi-section-table-cell"><%=mid.Aliases%></td> + <% for k, mid in ipairs(mids) do + local aliases = '' + for k,v in ipairs(mid.aliases) do + if aliases == '' then + sep = '' + else + sep = ', ' + end + aliases = v.ipAddress .. sep .. aliases + end + local host = mid.ipAddress + if mid.proto == '6' then + host = '[' .. mid.ipAddress .. ']' + end + %> + + <tr class="cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=mid.proto%>"> + <td class="cbi-section-table-cell"><a href="http://<%=host%>/cgi-bin-status.html"><%=mid.ipAddress%></a></td> + <td class="cbi-section-table-cell"><%=aliases%></td> </tr> <% i = ((i % 2) + 1) end %> </table> </fieldset> +<%+status-olsr/common_js%> <%+footer%> diff --git a/applications/luci-olsr/luasrc/view/status-olsr/neighbors.htm b/applications/luci-olsr/luasrc/view/status-olsr/neighbors.htm index 669ddc20cf..4d84241fbd 100644 --- a/applications/luci-olsr/luasrc/view/status-olsr/neighbors.htm +++ b/applications/luci-olsr/luasrc/view/status-olsr/neighbors.htm @@ -19,23 +19,26 @@ local i = 1 if luci.http.formvalue("status") == "1" then local rv = {} for k, link in ipairs(links) do - link.Cost = tonumber(link.Cost) or 0 - local color = olsrtools.etx_color(link.Cost) + link.linkCost = tonumber(link.linkCost)/1024 or 0 + if link.linkCost == 4096 then + link.linkCost = 0 + end + local color = olsrtools.etx_color(link.linkCost) defaultgw_color = "" if link.defaultgw == 1 then defaultgw_color = "#ffff99" end rv[#rv+1] = { - rip = link["Remote IP"], - hn = link["Hostname"], - lip = link["Local IP"], - dev = link["Local Device"], - lq = link.LQ, - nlq = link.NLQ, - cost = string.format("%.3f", link.Cost), + rip = link.remoteIP, + hn = link.hostname, + lip = link.localIP, + lq = string.format("%.3f", link.linkQuality), + nlq = string.format("%.3f",link.neighborLinkQuality), + cost = string.format("%.3f", link.linkCost), color = color, - dfgcolor = defaultgw_color + dfgcolor = defaultgw_color, + proto = link.proto } end luci.http.prepare_content("application/json") @@ -60,11 +63,19 @@ end { var neigh = info[idx]; - s += String.format( - '<tr class="cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+'">' + - '<td class="cbi-section-table-cell" style="background-color:%s"><a href="http://%s/cgi-bin-status.html">%s</a></td>', - neigh.dfgcolor, neigh.rip, neigh.rip - ); + if (neigh.proto == '6') { + s += String.format( + '<tr class="cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+' proto-%s">' + + '<td class="cbi-section-table-cell" style="background-color:%s"><a href="http://[%s]/cgi-bin-status.html">%s</a></td>', + neigh.proto, neigh.dfgcolor, neigh.rip, neigh.rip + ); + } else { + s += String.format( + '<tr class="cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+' proto-%s">' + + '<td class="cbi-section-table-cell" style="background-color:%s"><a href="http://%s/cgi-bin-status.html">%s</a></td>', + neigh.proto, neigh.dfgcolor, neigh.rip, neigh.rip + ); + } if (neigh.hn) { s += String.format( '<td class="cbi-section-table-cell" style="background-color:%s"><a href="http://%s/cgi-bin-status.html">%s</a></td>', @@ -82,10 +93,9 @@ end '<td class="cbi-section-table-cell" style="background-color:%s">%s</td>' + '<td class="cbi-section-table-cell" style="background-color:%s">%s</td>' + '<td class="cbi-section-table-cell" style="background-color:%s">%s</td>' + - '<td class="cbi-section-table-cell" style="background-color:%s">%s</td>' + '</tr>', - neigh.dfgcolor, neigh.lip, neigh.dfgcolor, neigh.dev, neigh.dfgcolor, neigh.lq, neigh.dfgcolor, neigh.nlq, neigh.color, neigh.cost || '?' + neigh.dfgcolor, neigh.lip, neigh.dfgcolor, neigh.lq, neigh.dfgcolor, neigh.nlq, neigh.color, neigh.cost || '?' ); } @@ -98,6 +108,8 @@ end <h2><a id="content" name="content"><%:OLSR connections%></a></h2> +<div id="togglebuttons"></div> + <fieldset class="cbi-section"> <legend><%:Overview of currently established OLSR connections%></legend> @@ -107,7 +119,6 @@ end <th class="cbi-section-table-cell"><%:Neighbour IP%></th> <th class="cbi-section-table-cell"><%:Hostname%></th> <th class="cbi-section-table-cell"><%:Local interface IP%></th> - <th class="cbi-section-table-cell"><%:Device%></th> <th class="cbi-section-table-cell">LQ</th> <th class="cbi-section-table-cell">NLQ</th> <th class="cbi-section-table-cell">ETX</th> @@ -117,8 +128,12 @@ end <tbody id="olsr_neigh_table"> <% local i = 1 for k, link in ipairs(links) do - link.Cost = tonumber(link.Cost) or 0 - color = olsrtools.etx_color(link.Cost) + link.linkCost = tonumber(link.linkCost)/1024 or 0 + if link.linkCost == 4096 then + link.linkCost = 0 + end + + color = olsrtools.etx_color(link.linkCost) defaultgw_color = "" if link.defaultgw == 1 then @@ -126,14 +141,17 @@ end end %> - <tr class="cbi-section-table-row cbi-rowstyle-<%=i%>"> - <td class="cbi-section-table-cell" style="background-color:<%=defaultgw_color%>"><a href="http://<%=link["Remote IP"]%>/cgi-bin-status.html"><%=link["Remote IP"]%></a></td> - <td class="cbi-section-table-cell" style="background-color:<%=defaultgw_color%>"><a href="http://<%=link["Hostname"]%>/cgi-bin-status.html"><%=link["Hostname"]%></a></td> - <td class="cbi-section-table-cell" style="background-color:<%=defaultgw_color%>"><%=link["Local IP"]%></td> - <td class="cbi-section-table-cell" style="background-color:<%=defaultgw_color%>"><%=link["Local Device"]%></td> - <td class="cbi-section-table-cell" style="background-color:<%=defaultgw_color%>"><%=link.LQ%></td> - <td class="cbi-section-table-cell" style="background-color:<%=defaultgw_color%>"><%=link.NLQ%></td> - <td class="cbi-section-table-cell" style="background-color:<%=color%>"><%=string.format("%.3f", link.Cost)%></td> + <tr class="cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=link.proto%>"> + <% if link.proto == "6" then %> + <td class="cbi-section-table-cell" style="background-color:<%=defaultgw_color%>"><a href="http://[<%=link.remoteIP%>]/cgi-bin-status.html"><%=link.remoteIP%></a></td> + <% else %> + <td class="cbi-section-table-cell" style="background-color:<%=defaultgw_color%>"><a href="http://<%=link.remoteIP%>/cgi-bin-status.html"><%=link.remoteIP%></a></td> + <% end %> + <td class="cbi-section-table-cell" style="background-color:<%=defaultgw_color%>"><a href="http://<%=link.hostname%>/cgi-bin-status.html"><%=link.hostname%></a></td> + <td class="cbi-section-table-cell" style="background-color:<%=defaultgw_color%>"><%=link.localIP%></td> + <td class="cbi-section-table-cell" style="background-color:<%=defaultgw_color%>"><%=string.format("%.3f", link.linkQuality)%></td> + <td class="cbi-section-table-cell" style="background-color:<%=defaultgw_color%>"><%=string.format("%.3f", link.neighborLinkQuality)%></td> + <td class="cbi-section-table-cell" style="background-color:<%=color%>"><%=string.format("%.3f", link.linkCost)%></td> </tr> <% i = ((i % 2) + 1) @@ -142,15 +160,7 @@ end </table> <br /> -<h3><%:Legend%>:</h3> -<ul> - <li><strong>LQ: </strong><%:Success rate of packages received from the neighbour%></li> - <li><strong>NLQ: </strong><%:Success rate of packages sent to the neighbour%></li> - <li><strong>ETX: </strong><%:Expected retransmission count%></li> - <li><strong><span style="color:#00cc00"><%:Green%></span></strong>:<%:Very good (ETX < 2)%></li> - <li><strong><span style="color:#ffcb05"><%:Yellow%></span></strong>:<%:Good (2 < ETX < 4)%></li> - <li><strong><span style="color:#ff6600"><%:Orange%></span></strong>:<%:Still usable (4 < ETX < 10)%></li> - <li><strong><span style="color:#bb3333"><%:Red%></span></strong>:<%:Bad (ETX > 10)%></li> -</ul> +<%+status-olsr/legend%> </fieldset> +<%+status-olsr/common_js%> <%+footer%> diff --git a/applications/luci-olsr/luasrc/view/status-olsr/overview.htm b/applications/luci-olsr/luasrc/view/status-olsr/overview.htm index 294af7b3a6..3af5490d1b 100644 --- a/applications/luci-olsr/luasrc/view/status-olsr/overview.htm +++ b/applications/luci-olsr/luasrc/view/status-olsr/overview.htm @@ -12,83 +12,10 @@ You may obtain a copy of the License at -%> <% -local sys = require "luci.sys" -local utl = require "luci.util" -local fs = require "luci.fs" - -function get_version() - local data = utl.split((utl.trim(sys.exec("/usr/sbin/olsrd -v")))) - local buildfull = utl.trim(utl.split(data[2],": ")[2]) - local ver = { - version = utl.trim(utl.split(data[1]," - ")[2]), - date = utl.trim(utl.split(buildfull, " ")[1]), - time = utl.trim(utl.split(buildfull, " ")[2]), - host = utl.trim(utl.split(buildfull, " ")[4]) - } - return ver -end -local ver = get_version() - -local ifaces = fetch_txtinfo("int") -if not ifaces or not ifaces.Interfaces then - luci.template.render("status-olsr/error_olsr") - return nil -end -local interfaces = "" -for k,v in pairs(ifaces.Interfaces) do - interfaces = utl.trim(interfaces.." "..v.Name) -end -interfaces = string.gsub(interfaces, " ", ", ") -local nr_ifaces = #ifaces.Interfaces - -local links = fetch_txtinfo("links") -local nr_neigh = #links.Links -local neighbors = "" -for k,v in pairs(links.Links) do - local link - if v.Hostname then - link = v.Hostname - else - link = v["Remote IP"] - end - neighbors = utl.trim("<a href=http://"..link.."/cgi-bin-status.html>"..link.."</a> "..neighbors) -end - -local data = fetch_txtinfo("topology") -local nr_topo = #data.Topology -local utable = {} -for k,v in pairs(data.Topology) do - if utl.contains(utable, v["Dest. IP"]) == false then - table.insert(utable, v["Dest. IP"]) - end -end -local nr_nodes = #utable - -local data = fetch_txtinfo("hna") -local nr_hna = #data.HNA - -local meshfactor = string.format("%.2f", nr_topo / nr_nodes) - -if luci.http.formvalue("status") == "1" then - rv = { - nr_neighbors = nr_neigbors, - neighbors = neighbors, - interfaces = interfaces, - nr_ifaces = nr_ifaces, - nr_links = nr_links, - nr_topo = nr_topo, - nr_nodes = nr_nodes, - meshfactor = meshfactor - } - luci.http.prepare_content("application/json") - luci.http.write_json(rv) - return -end - - local ipv = luci.model.uci.cursor():get_first("olsrd", "olsrd", "IpVersion", "4") function write_conf(conf, file) + local fs = require "luci.fs" if fs.access(conf) then luci.http.header("Content-Disposition", "attachment; filename="..file) luci.http.prepare_content("text/plain") @@ -125,169 +52,161 @@ end <script type="text/javascript" src="<%=resource%>/cbi.js"></script> <script type="text/javascript">//<![CDATA[ -XHR.poll(30, '<%=REQUEST_URI%>', { status: 1 }, +XHR.poll(10, '<%=REQUEST_URI%>/json', { }, function(x, info) { var e; - if (e = document.getElementById('nr_neighbors')) - e.innerHTML = info.nr_neighbors; + if (! info) { + document.getElementById('error').innerHTML = '<%:Could not get any data. Make sure the jsoninfo plugin is installed and allows connections from localhost.%>'; + return + } + document.getElementById('error').innerHTML = ''; + + if (e = document.getElementById('version')) + var version; + var date; + if (info.v4.config.olsrdVersion != undefined) { + version = info.v4.config.olsrdVersion + date = info.v4.config.olsrdBuildDate + } else if (info.v6.config.olsrdVersion != undefined) { + version = info.v6.config.olsrdVersion + date = info.v6.config.olsrdBuildDate + + } else { + version = 'unknown' + date = 'unknown' + } + e.innerHTML = version + '<br />' + date; + + if (e = document.getElementById('nr_neigh')) + var neigh = 0; + if (info.v4.links.length != undefined) { + neigh = neigh + info.v4.links.length + } + if (info.v6.links.length != undefined) { + neigh = neigh + info.v6.links.length + } + e.innerHTML = neigh; + + + if (e = document.getElementById('nr_hna')) + var hna = 0; + if (info.v4.hna.length != undefined) { + hna = hna + info.v4.hna.length + } + if (info.v6.hna.length != undefined) { + hna = hna + info.v6.hna.length + } + e.innerHTML = hna; - if (e = document.getElementById('neighbors')) - e.innerHTML = info.neighbors; if (e = document.getElementById('nr_ifaces')) - e.innerHTML = info.nr_ifaces; + var nrint = 0 + if (info.v4.interfaces.length != undefined) { + nrint = nrint + info.v4.interfaces.length + } + if (info.v6.interfaces.length != undefined) { + nrint = nrint + info.v6.interfaces.length + } + e.innerHTML = nrint - if (e = document.getElementById('interfaces')) - e.innerHTML = info.interfaces; - - if (e = document.getElementById('nr_links')) - e.innerHTML = info.nr_links; if (e = document.getElementById('nr_topo')) - e.innerHTML = info.nr_topo; - - if (e = document.getElementById('nr_nodes')) - e.innerHTML = info.nr_nodes; - - if (e = document.getElementById('meshfactor')) - e.innerHTML = info.meshfactor; + var topo = 0; + var nodes = []; + + Array.prototype.contains = function (element) { + for (var i = 0; i < this.length; i++) { + if (this[i] == element) { + return true; + } + } + return false; + } + + if (info.v4.topology.length != undefined) { + topo = topo + info.v4.topology.length; + for (var i = 0; i < info.v4.topology.length; i++) { + var destip = info.v4.topology[i].destinationIP + if (! nodes.contains(destip) ) { + nodes.push(destip) + } + } + } + + if (info.v6.topology.length != undefined) { + topo = topo + info.v6.topology.length + for (var i = 0; i < info.v6.topology.length; i++) { + var destip = info.v6.topology[i].destinationIP + if (! nodes.contains(destip) ) { + nodes.push(destip) + } + } + + } + e.innerHTML = topo; + + if (e = document.getElementById('nr_nodes')) + e.innerHTML = nodes.length; + + if (e = document.getElementById('meshfactor')) + var meshfactor = topo / nodes.length + e.innerHTML = meshfactor.toFixed(2) } ); //]]></script> +<div id="error" class="error"></div> + <h2><a id="content" name="content">OLSR <%:Overview%></a></h2> -<div class="cbi-map"> - <div class="cbi-section-node"> - <div class="cbi-value"> - <div style="width: 15em; float:left;"> - <label class="cbi-value-title"><%:Interfaces%></label> - </div> - <div class="cbi-value-field"> - <div style="width: 6em; float:left;"> - <a href="<%=REQUEST_URI%>/interfaces"> - <span id="nr_ifaces"> - <%=nr_ifaces%> - <span> - </a> - </div> - <div style="padding-left: 21em;"> - <span id="interfaces"> - <%=interfaces%> - </span> - </div> - </div> - <br/> - </div> - - <div class="cbi-value"> - <div style="width: 15em; float:left;"> - <%:Neighbors%> - </div> - <div class="cbi-value-field"> - <div style="width: 6em; float:left;"> - <a href="<%=REQUEST_URI%>/neighbors"> - <span id="nr_neigh"> - <%=nr_neigh%> - </span> - </a> - </div> - <div style="padding-left: 21em;"> - <span id="neighbors"> - <%=neighbors%> - </span> - </div> - </div> - <br/> - </div> - - <div class="cbi-value"> - <div style="width: 15em; float:left;"> - <%:Nodes%> - </div> - <div class="cbi-value-field"> - <div style="width: 6em; float:left;"> - <a href="<%=REQUEST_URI%>/topology"> - <span id="nr_nodes"> - <%=nr_nodes%> - </span> - </a> - </div> - </div> - <br/> - </div> - - <div class="cbi-value"> - <div style="width: 15em; float:left;"> - <%:HNA%> - </div> - <div class="cbi-value-field"> - <div style="width: 6em; float:left;"> - <a href="<%=REQUEST_URI%>/hna"> - <span id="nr_hna"> - <%=nr_hna%> - </span> - </a> - </div> - </div> - <br/> - </div> - - <div class="cbi-value"> - <div style="width: 15em; float:left;"> - <%:Links total%> - </div> - <div class="cbi-value-field"> - <div style="width: 6em; float:left;"> - <a href="<%=REQUEST_URI%>/topology"> - <span id="nr_topo"> - <%=nr_topo%> - </span> - </a> - </div> - </div> - <br/> - </div> - - <div class="cbi-value"> - <div style="width: 15em; float:left;"> - <%:Links per node (average)%> - </div> - <div class="cbi-value-field"> - <div style="width: 6em; float:left;"> - <span id="meshfactor"> - <%=meshfactor%> - </span> - </div> - </div> - <br/> - </div> - </div> -</div> -<br/> - -<h2><a id="content" name="content">OLSR <%:Configuration%></a></h2> - -<div class="cbi-map"> - <div class="cbi-section-node"> - <div class="cbi-value"> - <div style="width: 15em; float:left;"> - <%:Version%> - </div> - <div class="cbi-value-field"> - <%=ver.version%> (built <%=ver.date%> on <%=ver.host%>) - </div> - <br/> - </div> - - <div class="cbi-value"> - <div style="width: 15em; float:left;"> - <%:Download Config%> - </div> - <div class="cbi-value-field"> +<fieldset class="cbi-section"> + <legend><%:Network%></legend> + + <table width="100%" cellspacing="10"> + <tr><td width="33%"><%:Interfaces%></td><td> + <a href="<%=REQUEST_URI%>/interfaces"> + <span id="nr_ifaces">-<span> + </a> + </td></tr> + <tr><td width="33%"><%:Neighbors%></td><td> + <a href="<%=REQUEST_URI%>/neighbors"> + <span id="nr_neigh">-</span> + </a> + </td></tr> + <tr><td width="33%"><%:Nodes%></td><td> + <a href="<%=REQUEST_URI%>/topology"> + <span id="nr_nodes">-</span> + </a> + </td></tr> + <tr><td width="33%"><%:HNA%></td><td> + <a href="<%=REQUEST_URI%>/hna"> + <span id="nr_hna">-</span> + </a> + </td></tr> + <tr><td width="33%"><%:Links total%></td><td> + <a href="<%=REQUEST_URI%>/topology"> + <span id="nr_topo">-</span> + </a> + </td></tr> + <tr><td width="33%"><%:Links per node (average)%></td><td> + <span id="meshfactor">-</span> + </td></tr> + + + </table> +</fieldset> + + +<fieldset class="cbi-section"> + <legend>OLSR <%:Configuration%></legend> + <table width="100%" cellspacing="10"> + <tr><td width="33%"><%:Version%></td><td> + <span id="version">-<span> + </td></tr> + <tr><td width="33%"><%:Download Config%></td><td> <a href="<%=REQUEST_URI%>?openwrt">OpenWrt</a>, <% if ipv == "6and4" then %> <a href="<%=REQUEST_URI%>?conf_v4">OLSRD IPv4</a>, @@ -295,10 +214,8 @@ XHR.poll(30, '<%=REQUEST_URI%>', { status: 1 }, <% else %> <a href="<%=REQUEST_URI%>?conf">OLSRD</a> <% end %> - </div> - <br/> - </div> - </div> -</div> + </td></tr> + </table> +</fieldset> <%+footer%> diff --git a/applications/luci-olsr/luasrc/view/status-olsr/routes.htm b/applications/luci-olsr/luasrc/view/status-olsr/routes.htm index e32b696d58..76e1b1078b 100644 --- a/applications/luci-olsr/luasrc/view/status-olsr/routes.htm +++ b/applications/luci-olsr/luasrc/view/status-olsr/routes.htm @@ -19,14 +19,16 @@ local i = 1 if luci.http.formvalue("status") == "1" then local rv = {} for k, route in ipairs(routes) do + local ETX = string.format("%.3f", tonumber(route.rtpMetricCost)/1024 or 0) rv[#rv+1] = { - hostname = route.Hostname, - dest = route.Destination, - gw = route["Gateway IP"], - interface = route.Interface, - metric = route.Metric, - etx = tonumber(route.ETX), - color = olsrtools.etx_color(tonumber(route.ETX)), + hostname = route.hostname, + dest = route.destination, + genmask = route.genmask, + gw = route.gateway, + interface = route.networkInterface, + metric = route.metric, + etx = ETX, + color = olsrtools.etx_color(tonumber(ETX)) } end luci.http.prepare_content("application/json") @@ -54,20 +56,27 @@ XHR.poll(20, '<%=REQUEST_URI%>', { status: 1 }, var route = info[idx]; s += String.format( - '<tr class="cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+'">' + - '<td class="cbi-section-table-cell">%s</td>' + + '<tr class="cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+' proto-%s">' + + '<td class="cbi-section-table-cell">%s/%s</td>' + '<td class="cbi-section-table-cell">' + '<a href="http://%s/cgi-bin-status.html">%s</a>', - route.dest, route.gw, route.gw + route.proto, route.dest, route.genmask, route.gw, route.gw ) - if (route.hostname) - { - s += String.format( + if (route.hostname) { + if (hna.proto == '6') { + s += String.format( + ' / <a href="http://[%s]/cgi-bin-status.html">%s</a>', + route.hostname, route.hostname || '?' + ); + } else { + s += String.format( ' / <a href="http://%s/cgi-bin-status.html">%s</a>', route.hostname, route.hostname || '?' ); } + + } s += String.format( '</td>' + '<td class="cbi-section-table-cell">%s</td>' + @@ -88,6 +97,8 @@ XHR.poll(20, '<%=REQUEST_URI%>', { status: 1 }, <h2><a id="content" name="content"><%:Known OLSR routes%></a></h2> +<div id="togglebuttons"></div> + <fieldset class="cbi-section"> <legend><%:Overview of currently known routes to other OLSR nodes%></legend> @@ -105,20 +116,25 @@ XHR.poll(20, '<%=REQUEST_URI%>', { status: 1 }, <tbody id="olsrd_routes"> <% for k, route in ipairs(routes) do - color = olsrtools.etx_color(tonumber(route.ETX)) + ETX = tonumber(route.rtpMetricCost)/1024 or '0' + color = olsrtools.etx_color(ETX) %> - <tr class="cbi-section-table-row cbi-rowstyle-<%=i%>"> - <td class="cbi-section-table-cell"><%=route.Destination%></td> + <tr class="cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=route.proto%>"> + <td class="cbi-section-table-cell"><%=route.destination%>/<%=route.genmask%></td> <td class="cbi-section-table-cell"> - <a href="http://<%=route["Gateway IP"]%>/cgi-bin-status.html"><%=route["Gateway IP"]%></a> - <% if route.Hostname then %> - / <a href="http://<%=route.Hostname%>/cgi-bin-status.html"><%=route.Hostname%></a> + <% if route.proto == '6' then %> + <a href="http://[<%=route.gateway%>]/cgi-bin-status.html"><%=route.gateway%></a> + <% else %> + <a href="http://<%=route.gateway%>/cgi-bin-status.html"><%=route.gateway%></a> + <% end %> + <% if route.hostname then %> + / <a href="http://<%=route.Hostname%>/cgi-bin-status.html"><%=route.hostname%></a> <% end %> </td> - <td class="cbi-section-table-cell"><%=route.Interface%></td> - <td class="cbi-section-table-cell"><%=route.Metric%></td> - <td class="cbi-section-table-cell" style="background-color:<%=color%>"><%=string.format("%.3f", tonumber(route.ETX) or 0)%></td> + <td class="cbi-section-table-cell"><%=route.networkInterface%></td> + <td class="cbi-section-table-cell"><%=route.metric%></td> + <td class="cbi-section-table-cell" style="background-color:<%=color%>"><%=string.format("%.3f", ETX)%></td> </tr> <% i = ((i % 2) + 1) @@ -126,5 +142,7 @@ XHR.poll(20, '<%=REQUEST_URI%>', { status: 1 }, </tbody> </table> +<%+status-olsr/legend%> </fieldset> +<%+status-olsr/common_js%> <%+footer%> diff --git a/applications/luci-olsr/luasrc/view/status-olsr/smartgw.htm b/applications/luci-olsr/luasrc/view/status-olsr/smartgw.htm index 7fa8730423..75d0c1c2fb 100644 --- a/applications/luci-olsr/luasrc/view/status-olsr/smartgw.htm +++ b/applications/luci-olsr/luasrc/view/status-olsr/smartgw.htm @@ -19,17 +19,89 @@ local uci = luci.model.uci.cursor_state() uci:foreach("olsrd", "olsrd", function(s) if s.SmartGateway and s.SmartGateway == "yes" then has_smartgw = true end end) + + +if luci.http.formvalue("status") == "1" then + local rv = {} + for k, gw in ipairs(gws) do + gw.tcPathCost = tonumber(gw.tcPathCost)/1024 or 0 + if gw.tcPathCost == 4096 then + gw.tcPathCost = 0 + end + + rv[#rv+1] = { + proto = gw.proto, + ipAddress = gw.ipAddress, + status = gw.ipv4Status or gw.ipv6Status, + tcPathCost = string.format("%.3f", gw.tcPathCost), + hopCount = gw.hopCount, + uplinkSpeed = gw.uplinkSpeed, + downlinkSpeed = gw.downlinkSpeed, + v4 = gw.ipv4 and luci.i18n.translate('yes') or luci.i18n.translate('no'), + v6 = gw.ipv6 and luci.i18n.translate('yes') or luci.i18n.translate('no'), + externalPrefix = gw.externalPrefix + } + end + luci.http.prepare_content("application/json") + luci.http.write_json(rv) + return +end %> <%+header%> +<script type="text/javascript" src="<%=resource%>/cbi.js"></script> +<script type="text/javascript">//<![CDATA[ +XHR.poll(10, '<%=REQUEST_URI%>', { status: 1 }, + function(x, info) + { + var smartgwdiv = document.getElementById('olsrd_smartgw'); + if (smartgwdiv) + { + var s = ''; + for (var idx = 0; idx < info.length; idx++) + { + var smartgw = info[idx]; + s += '<tr class="cbi-section-table-row cbi-rowstyle-'+(1 + (idx % 2))+' proto-' + smartgw.proto + '">' + if (smartgw.proto == '6') { + linkgw = '<a href="http://[' + smartgw.ipAddress + ']/cgi-bin-status.html">' + smartgw.ipAddress + '</a>' + } else { + linkgw = '<a href="http://' + smartgw.ipAddress + '/cgi-bin-status.html">' + smartgw.ipAddress + '</a>' + } + + s += String.format( + '<td class="cbi-section-table-cell">%s</td>' + + '<td class="cbi-section-table-cell">%s</td>' + + '<td class="cbi-section-table-cell">%s</td>' + + '<td class="cbi-section-table-cell">%s</td>' + + '<td class="cbi-section-table-cell">%s</td>' + + '<td class="cbi-section-table-cell">%s</td>' + + '<td class="cbi-section-table-cell">%s</td>' + + '<td class="cbi-section-table-cell">%s</td>' + + '<td class="cbi-section-table-cell">%s</td>', + linkgw, smartgw.status, smartgw.tcPathCost, smartgw.hopCount, smartgw.uplinkSpeed, smartgw.downlinkSpeed, smartgw.v4, smartgw.v6, smartgw.externalPrefix + ) + s += '</tr>' + } + smartgwdiv.innerHTML = s; + } +} +); +//]]></script> + + +<%+header%> + <h2><a id="content" name="content"><%:SmartGW announcements%></a></h2> +<div id="togglebuttons"></div> + <% if has_smartgw then %> <fieldset class="cbi-section"> <legend><%:Overview of smart gateways in this network%></legend> <table class="cbi-section-table"> + <thead> <tr class="cbi-section-table-titles"> <th class="cbi-section-table-cell"><%:Gateway%></th> <th class="cbi-section-table-cell"><%:Status%></th> @@ -42,23 +114,37 @@ end) <th class="cbi-section-table-cell"><%:Prefix%></th> </tr> - - <% for k, gw in ipairs(gws) do %> - - <tr class="cbi-section-table-row cbi-rowstyle-<%=i%>"> - <td class="cbi-section-table-cell"><a href="http://<%=gw["Gateway IP"]%>/cgi-bin-status.html"><%=gw["Gateway IP"]%></a></td> - <td class="cbi-section-table-cell"><%=gw.Status%></td> - <td class="cbi-section-table-cell"><%=gw.ETX%></td> - <td class="cbi-section-table-cell"><%=gw.Hopcnt%></td> - <td class="cbi-section-table-cell"><%=gw.Uplink%></td> - <td class="cbi-section-table-cell"><%=gw.Downlnk%></td> - <td class="cbi-section-table-cell"><%=gw.IPv4%></td> - <td class="cbi-section-table-cell"><%=gw.IPv6%></td> - <td class="cbi-section-table-cell"><%=gw.Prefix%></td> + </thead> + + <tbody id="olsrd_smartgw"> + <% for k, gw in ipairs(gws) do + + gw.tcPathCost = tonumber(gw.tcPathCost)/1024 or 0 + if gw.tcPathCost == 4096 then + gw.tcPathCost = 0 + end + %> + + <tr class="cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=proto%>"> + <% if gw.proto == '6' then %> + <td class="cbi-section-table-cell"><a href="http://[<%=gw.ipAddress%>]/cgi-bin-status.html"><%=gw.ipAddress%></a></td> + <% else %> + <td class="cbi-section-table-cell"><a href="http://<%=gw.ipAddress%>/cgi-bin-status.html"><%=gw.ipAddress%></a></td> + <% end %> + + <td class="cbi-section-table-cell"><%=gw.ipv4Status or gw.ipv6Status or '-' %></td> + <td class="cbi-section-table-cell"><%=string.format("%.3f", gw.tcPathCost)%></td> + <td class="cbi-section-table-cell"><%=gw.hopCount%></td> + <td class="cbi-section-table-cell"><%=gw.uplinkSpeed%></td> + <td class="cbi-section-table-cell"><%=gw.downlinkSpeed%></td> + <td class="cbi-section-table-cell"><%=gw.ipv4 and luci.i18n.translate('yes') or luci.i18n.translate('no')%></td> + <td class="cbi-section-table-cell"><%=gw.ipv6 and luci.i18n.translate('yes') or luci.i18n.translate('no')%></td> + <td class="cbi-section-table-cell"><%=gw.externalPrefix%></td> </tr> <% i = ((i % 2) + 1) end %> + </tbody> </table> </fieldset> @@ -68,4 +154,5 @@ end) <% end %> +<%+status-olsr/common_js%> <%+footer%> diff --git a/applications/luci-olsr/luasrc/view/status-olsr/topology.htm b/applications/luci-olsr/luasrc/view/status-olsr/topology.htm index d0e85280e2..eb3df5ff51 100644 --- a/applications/luci-olsr/luasrc/view/status-olsr/topology.htm +++ b/applications/luci-olsr/luasrc/view/status-olsr/topology.htm @@ -10,8 +10,6 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -$Id$ - -%> <% local i = 1 @@ -21,6 +19,8 @@ local olsrtools = require "luci.tools.olsr" <%+header%> <h2><a id="content" name="content"><%:Active OLSR nodes%></a></h2> +<div id="togglebuttons"></div> + <fieldset class="cbi-section"> <legend><%:Overview of currently known OLSR nodes%></legend> <table class="cbi-section-table"> @@ -33,21 +33,36 @@ local olsrtools = require "luci.tools.olsr" </tr> <% for k, route in ipairs(routes) do - local cost = string.format("%.3f", tonumber(route.Cost) or 0) + local cost = string.format("%.3f", tonumber(route.tcEdgeCost/1024) or 0) local color = olsrtools.etx_color(tonumber(cost)) + local lq = string.format("%.3f", tonumber(route.linkQuality) or 0) + local nlq = string.format("%.3f", tonumber(route.neighborLinkQuality) or 0) %> - <tr class="cbi-section-table-row cbi-rowstyle-<%=i%>"> - <td class="cbi-section-table-cell"><a href="http://<%=route["Dest. IP"]%>/cgi-bin-status.html"><%=route["Dest. IP"]%></a></td> - <td class="cbi-section-table-cell"><a href="http://<%=route["Last hop IP"]%>/cgi-bin-status.html"><%=route["Last hop IP"]%></a></td> - <td class="cbi-section-table-cell"><%=route.LQ%></td> - <td class="cbi-section-table-cell"><%=route.NLQ%></td> + <tr class="cbi-section-table-row cbi-rowstyle-<%=i%> proto-<%=route.proto%>"> + + <% if route.proto == "6" then %> + + <td class="cbi-section-table-cell"><a href="http://[<%=route.destinationIP%>]/cgi-bin-status.html"><%=route.destinationIP%></a></td> + <td class="cbi-section-table-cell"><a href="http://[<%=route.lastHopIP%>]/cgi-bin-status.html"><%=route.lastHopIP%></a></td> + + <% else %> + + <td class="cbi-section-table-cell"><a href="http://<%=route.destinationIP%>/cgi-bin-status.html"><%=route.destinationIP%></a></td> + <td class="cbi-section-table-cell"><a href="http://<%=route.lastHopIP%>/cgi-bin-status.html"><%=route.lastHopIP%></a></td> + + <%end%> + + <td class="cbi-section-table-cell"><%=lq%></td> + <td class="cbi-section-table-cell"><%=nlq%></td> <td class="cbi-section-table-cell" style="background-color:<%=color%>"><%=cost%></td> </tr> <% i = ((i % 2) + 1) end %> </table> +<%+status-olsr/legend%> </fieldset> +<%+status-olsr/common_js%> <%+footer%> |