* luci/app-olsr: fix olsr status pages
[project/luci.git] / applications / luci-olsr / luasrc / controller / olsr.lua
1 module("luci.controller.olsr", package.seeall)
2
3 function index()
4         if not luci.fs.isfile("/etc/config/olsrd") then
5                 return
6         end
7
8         require("luci.i18n").loadc("olsr")
9         local i18n = luci.i18n.translate
10
11         local page  = node("admin", "status", "olsr")
12         page.target = call("action_index")
13         page.title  = "OLSR"
14         page.i18n   = "olsr"
15
16         local page  = node("admin", "status", "olsr", "routes")
17         page.target = call("action_routes")
18         page.title  = i18n("olsr_routes", "Routen")
19         page.order  = 10
20
21         local page  = node("admin", "status", "olsr", "topology")
22         page.target = call("action_topology")
23         page.title  = i18n("olsr_topology", "Topologie")
24         page.order  = 20
25
26         local page  = node("admin", "status", "olsr", "hna")
27         page.target = call("action_hna")
28         page.title  = "HNA"
29         page.order  = 30
30
31         local page  = node("admin", "status", "olsr", "mid")
32         page.target = call("action_mid")
33         page.title  = "MID"
34         page.order  = 50
35
36         entry(
37                 {"admin", "services", "olsrd"},
38                 cbi("olsr/olsrd"), "OLSR"
39         ).i18n = "olsr"
40
41         entry(
42                 {"admin", "services", "olsrd", "hna"},
43                 cbi("olsr/olsrdhna"), "HNA Announcements"
44         ).i18n = "olsr"
45
46         oplg = entry(
47                 {"admin", "services", "olsrd", "plugins"},
48                 cbi("olsr/olsrdplugins"), "Plugins"
49         )
50         oplg.i18n = "olsr"
51         oplg.leaf = true
52
53         local uci = require("luci.model.uci").cursor()
54         uci:foreach("olsrd", "LoadPlugin",
55                 function (section)
56                         local lib = section.library
57                         entry(
58                                 {"admin", "services", "olsrd", "plugins", lib },
59                                 cbi("olsr/olsrdplugins"),
60                                 nil --'Plugin "%s"' % lib:gsub("^olsrd_",""):gsub("%.so.+$","")
61                         )
62                 end
63         )
64 end
65
66 function action_index()
67         local data = fetch_txtinfo("links")
68
69         if not data or not data.Links then
70                 luci.template.render("status-olsr/error_olsr")
71                 return nil
72         end
73
74         local function compare(a, b)
75                 local c = tonumber(a.Cost)
76                 local d = tonumber(b.Cost)
77
78                 if not c or c == 0 then
79                         return false
80                 end
81
82                 if not d or d == 0 then
83                         return true
84                 end
85
86                 return c < d
87         end
88
89         table.sort(data.Links, compare)
90
91         luci.template.render("status-olsr/index", {links=data.Links})
92 end
93
94 function action_routes()
95         local data = fetch_txtinfo("routes")
96
97         if not data or not data.Routes then
98                 luci.template.render("status-olsr/error_olsr")
99                 return nil
100         end
101
102         local function compare(a, b)
103                 local c = tonumber(a.ETX)
104                 local d = tonumber(b.ETX)
105
106                 if not c or c == 0 then
107                         return false
108                 end
109
110                 if not d or d == 0 then
111                         return true
112                 end
113
114                 return c < d
115         end
116
117         table.sort(data.Routes, compare)
118
119         luci.template.render("status-olsr/routes", {routes=data.Routes})
120 end
121
122 function action_topology()
123         local data = fetch_txtinfo("topology")
124
125         if not data or not data.Topology then
126                 luci.template.render("status-olsr/error_olsr")
127                 return nil
128         end
129
130         local function compare(a, b)
131                 return a["Dest. IP"] < b["Dest. IP"]
132         end
133
134         table.sort(data.Topology, compare)
135
136         luci.template.render("status-olsr/topology", {routes=data.Topology})
137 end
138
139 function action_hna()
140         local data = fetch_txtinfo("hna")
141
142         if not data or not data.HNA then
143                 luci.template.render("status-olsr/error_olsr")
144                 return nil
145         end
146
147         local function compare(a, b)
148                 return a.Destination < b.Destination
149         end
150
151         table.sort(data.HNA, compare)
152
153         luci.template.render("status-olsr/hna", {routes=data.HNA})
154 end
155
156 function action_mid()
157         local data = fetch_txtinfo("mid")
158
159         if not data or not data.MID then
160                 luci.template.render("status-olsr/error_olsr")
161                 return nil
162         end
163
164         local function compare(a, b)
165                 return a["IP address"] < b["IP address"]
166         end
167
168         table.sort(data.MID, compare)
169
170         luci.template.render("status-olsr/mid", {mids=data.MID})
171 end
172
173
174 -- Internal
175 function fetch_txtinfo(otable)
176         require("luci.sys")
177         otable = otable or ""
178         local rawdata = luci.sys.httpget("http://127.0.0.1:2006/"..otable)
179
180         if #rawdata == 0 then
181                 return nil
182         end
183
184         local data = {}
185
186         local tables = luci.util.split(luci.util.trim(rawdata), "\r?\n\r?\n", nil, true)
187
188
189         for i, tbl in ipairs(tables) do
190                 local lines = luci.util.split(tbl, "\r?\n", nil, true)
191                 local name  = table.remove(lines, 1):sub(8)
192                 local keys  = luci.util.split(table.remove(lines, 1), "\t")
193                 local split = #keys - 1
194
195                 data[name] = {}
196
197                 for j, line in ipairs(lines) do
198                         local fields = luci.util.split(line, "\t", split)
199                         data[name][j] = {}
200                         for k, key in pairs(keys) do
201                                 data[name][j][key] = fields[k]
202                         end
203
204                         if data[name][j].Linkcost then
205                                 data[name][j].LinkQuality,
206                                 data[name][j].NLQ,
207                                 data[name][j].ETX =
208                                 data[name][j].Linkcost:match("([%w.]+)/([%w.]+)[%s]+([%w.]+)")
209                         end
210                 end
211         end
212
213         return data
214 end