Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / ot-br-posix / repo / src / openwrt / view / admin_thread / thread_view.htm
1 <%-
2         local ubus = require "ubus"
3         local sys = require "luci.sys"
4         local utl = require "luci.util"
5
6         function connect_ubus(methods)
7                 local result
8                 local conn = ubus.connect()
9
10                 if not conn then
11                         error("Failed to connect to ubusd")
12                 end
13
14                 result = conn:call("otbr", methods, {})
15
16                 return result
17         end
18
19         function threadget(action)
20                 local result = connect_ubus(action)
21
22                 return result
23         end
24 -%>
25
26 <%+header%>
27
28 <h2><%:Thread View: %><%=threadget("networkname").NetworkName%><%: (wpan0)%></h2>
29 <div>This is the list and topograph of your thread network.</div>
30 <br />
31
32 <ul class="cbi-tabmenu">
33         <li class="cbi-tab" id="listtab" style="width:15%;text-align:center;"><a href="javascript:showlist();"><%:List%></a></li>
34         <li class="cbi-tab-disabled" id="graphtab" style="width:15%;text-align:center;"><a href="javascript:showgraph();"><%:Topology Graph%></a></li>
35 </ul>
36
37 <!-- list div -->
38 <div style="width:100%;" id="listdiv">
39         <!-- leader list -->
40         <h3><%: Leader Situation of Network%></h3><br />
41         <div class="cbi-map" style="width:90%;margin-left:5%;">
42                 <div class="cbi-section">
43                         <div class="table">
44                                 <div class="tr table-titles" style="background-color:#eee;">
45                                         <div class="th col-3 center"><%:Leader Router Id%></div>
46                                         <div class="th col-3 center"><%:Partition Id%></div>
47                                         <div class="th col-2 center"><%:Weighting%></div>
48                                         <div class="th col-2 center"><%:Data Version%></div>
49                                         <div class="th col-2 center"><%:Stable Data Version%></div>
50                                 </div>
51
52                                 <!-- leader situatioin -->
53                                 <% leader = threadget("leaderdata").leaderdata %>
54                                 <div class="tr cbi-rowstyle-2%>" style="border:solid 1px #ddd; border-top:hidden;">
55                                         <div class="td col-3 center"><%=leader.LeaderRouterId%></div>
56                                         <div class="td col-3 center"><%=leader.PartitionId%></div>
57                                         <div class="td col-2 center"><%=leader.Weighting%></div>
58                                         <div class="td col-2 center"><%=leader.DataVersion%></div>
59                                         <div class="td col-2 center"><%=leader.StableDataVersion%></div>
60
61                                 </div>
62                         </div>
63                 </div>
64         </div>
65         <br />
66         <h3><%: Neighbor Situation of Network%></h3><br />
67         <!-- neighbor list -->
68         <div class="table" id="neighbors" style="width:90%;margin-left:5%;">
69                 <div class="tr table-titles" style="background-color:#eee;">
70                         <div class="th col-2 center"><%:RLOC16%></div>
71                         <div class="th col-2 center"><%:Role%></div>
72                         <div class="th col-2 center"><%:Age%></div>
73                         <div class="th col-2 center"><%:Avg RSSI%></div>
74                         <div class="th col-2 center"><%:Last RSSI%></div>
75                         <div class="th col-2 center"><%:Mode%></div>
76                         <div class="th col-4 center"><%:Extended MAC%></div>
77                         <div class="th cbi-section-actions">&#160;</div>
78                 </div>
79                 <div class="tr placeholder">
80                         <div class="td"><em><%:Collecting data...%></em></div>
81                 </div>
82         </div>
83         <!--/neighbor list-->
84
85         <!-- parent list -->
86         <div class="table" id="parent" style="width:90%;margin-left:5%;display:none;">
87                 <div class="tr table-titles" style="background-color:#eee;">
88                         <div class="th col-2 center"><%:RLOC16%></div>
89                         <div class="th col-2 center"><%:Role%></div>
90                         <div class="th col-2 center"><%:Age%></div>
91                         <div class="th col-2 center"><%:LinkQualityIn%></div>
92                         <div class="th col-4 center"><%:ExtAddress%></div>
93                         <div class="th cbi-section-actions">&#160;</div>
94                 </div>
95                 <div class="tr placeholder">
96                         <div class="td"><em><%:Collecting data...%></em></div>
97                 </div>
98         </div>
99         <!--/parent list-->
100 </div>
101
102 <!-- graph div -->
103 <div style="width:100%;margin-left:5%;display:none;" id="graphdiv">
104         <div style="width:20%"><svg id="topologyLegend"></svg></div>
105         <svg width="960" height="500" id="graph"></svg>
106 </div>
107
108 <div class="cbi-page-actions right" style="margin-top:10%;">
109         <form class="inline" action="<%=url('admin/network/thread')%>" method="get">
110                 <input class="cbi-button cbi-button-neutral" type="submit" value="<%:Back to overview%>" />
111         </form>
112         <form class="inline" action="<%=url('admin/network/thread_add')%>" method="post">
113                 <input type="hidden" name="token" value="<%=token%>" />
114                 <input class="cbi-button cbi-button-add" type="submit" value="<%:Add%>" />
115         </form>
116 </div>
117 <%+footer%>
118
119 <script src='http://d3js.org/d3.v4.min.js'></script>
120 <script type="text/javascript" src="/luci-static/resources/handle_error.js"></script>
121 <script type="text/javascript">//<![CDATA[
122         handle_error(GetURLParameter('error'));
123
124         var svg = d3.select("#graph"),
125                 width = +svg.attr("width"),
126                 height = +svg.attr("height"),
127                 color = d3.scaleOrdinal(d3.schemeCategory10);
128
129         function getRloc(rloc, localrloc) {
130                 if(rloc == localrloc) return rloc + " ( your device )";
131                 else return rloc;
132         }
133         function getColor(role) {
134                 if(role == 'ftd') return "#90EE90";
135                 else if(role == 'mtd') return "#FFDAB9";
136                 else if(role == 'router') return "#87CEFA";
137                 else if(role == 'leader') return "#FFA07A";
138                 else if(role == 'joiner') return "#778899";
139         }
140         var nodes, links;
141         var simulation = d3.forceSimulation(nodes)
142                 .force("charge", d3.forceManyBody().strength(-1000))
143                 .force("link", d3.forceLink(links).distance(200))
144                 .force("x", d3.forceX())
145                 .force("y", d3.forceY())
146                 .alphaTarget(1)
147                 .on("tick", ticked);
148
149         var g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"),
150                 link = g.append("g").attr("stroke", "#eee").attr("stroke-width", 1.5).selectAll(".link"),
151                 node = g.append("g").attr("stroke", "#fff").attr("stroke-width", 1.5).selectAll(".node"),
152                 text = g.append("g").selectAll(".text");
153
154         var legend = d3.select("#topologyLegend");
155
156         legend.append("circle").attr("cx",50).attr("cy",30).attr("r", 6).style("fill", getColor("leader"));
157         legend.append("circle").attr("cx",50).attr("cy",50).attr("r", 6).style("fill", getColor("router"));
158         legend.append("circle").attr("cx",50).attr("cy",70).attr("r", 4).style("fill", getColor("ftd"));
159         legend.append("circle").attr("cx",50).attr("cy",90).attr("r", 4).style("fill", getColor("mtd"));
160         legend.append("circle").attr("cx",50).attr("cy",110).attr("r", 4).style("fill", getColor("joiner"));
161         legend.append("text").attr("x", 60).attr("y", 35).text("leader").style("font-size", "15px").attr("alignment-baseline","middle");
162         legend.append("text").attr("x", 60).attr("y", 55).text("router").style("font-size", "15px").attr("alignment-baseline","middle");
163         legend.append("text").attr("x", 60).attr("y", 75).text("FTD child").style("font-size", "15px").attr("alignment-baseline","middle");
164         legend.append("text").attr("x", 60).attr("y", 95).text("MTD child").style("font-size", "15px").attr("alignment-baseline","middle");
165         legend.append("text").attr("x", 60).attr("y", 115).text("new joiner").style("font-size", "15px").attr("alignment-baseline","middle");
166
167         function update_graph(nodes, links, localrloc) {
168                 node = node.data(nodes, function(d) { return d.rloc;});
169                 node.exit().remove();
170                 node = node.enter().append("circle")
171                                 .attr("fill", function(d) { return getColor(d.role); })
172                                 .attr("r", function(d) {
173                                                 return (d.role == 'router' || d.role == 'leader' ? 10 : 7);
174                                 })
175                                 .merge(node);
176
177                 link = link.data(links, function(d) { return d.source.rloc + "-" + d.target.rloc; });
178                 link.exit().remove();
179                 link = link.enter().append("line").merge(link);
180
181                 text = text.data(nodes, function(d) { return getRloc(d.rloc, localrloc); });
182                 text.exit().remove();
183                 text = text.enter().append('text')
184                         .attr("fill", "black")
185                         .attr("dx", 20)
186                         .attr("dy", 8)
187                         .text(function(d) { return getRloc(d.rloc, localrloc); })
188                         .merge(text);
189
190                 simulation.nodes(nodes);
191                 simulation.force("link").links(links);
192                 simulation.alpha(1).restart();
193         }
194
195         function ticked() {
196                 node.attr("cx", function(d) { return d.x; })
197                                 .attr("cy", function(d) { return d.y; })
198                 link.attr("x1", function(d) { return d.source.x; })
199                                 .attr("y1", function(d) { return d.source.y; })
200                                 .attr("x2", function(d) { return d.target.x; })
201                                 .attr("y2", function(d) { return d.target.y; });
202                 text.attr("x",function(d){ return d.x; })
203                                 .attr("y",function(d){ return d.y; });
204         }
205
206         function showlist() {
207                 document.getElementById('listdiv').style.display = "block";
208                 document.getElementById('graphdiv').style.display = "none";
209                 document.getElementById('listtab').className = "cbi-tab";
210                 document.getElementById('graphtab').className = "cbi-tab-disabled";
211         }
212
213         function showgraph() {
214                 document.getElementById('listdiv').style.display = "none";
215                 document.getElementById('graphdiv').style.display = "block";
216                 document.getElementById('listtab').className = "cbi-tab-disabled";
217                 document.getElementById('graphtab').className = "cbi-tab";
218         }
219
220         function getRole(rloc, leader) {
221                 if(parseInt(rloc) == leader) return 'leader';
222                 else if((parseInt(rloc) & 0xff) == 0) return 'router';
223                 else return 'ftd';
224         }
225
226         XHR.poll(5, '<%=url('admin/network/thread_graph')%>', null,
227                 function(x, st)
228                 {
229                         if(st)
230                         {
231                                 nodes = [];
232                                 links = [];
233
234                                 var leaderRloc = st.leader << 10;
235                                 var localrloc = st.rloc16;
236                                 // get local informatioin
237                                 st.connect.forEach(function(bss) {
238                                         var localIndex = getNodesIndex(bss.rloc);
239                                         if(localIndex == -1)
240                                         {
241                                                 nodes.push( {
242                                                         rloc: bss.rloc,
243                                                         role: getRole(bss.rloc, leaderRloc)
244                                                 } );
245                                                 localIndex = getNodesIndex(bss.rloc);
246                                         }
247                                         bss.childdata.forEach(function(child) {
248                                                 if(getNodesIndex(child.rloc) == -1)
249                                                 {
250                                                         nodes.push( {
251                                                                 rloc: child.rloc,
252                                                                 role: (((child.mode & 0x2) >> 1 == 1) ? 'ftd' : 'mtd')
253                                                         } );
254                                                 }
255                                                 links.push( {
256                                                         source: localIndex,
257                                                         target: getNodesIndex(child.rloc)
258                                                 } );
259                                         });
260                                         bss.routedata.forEach(function(router) {
261                                                 if(getNodesIndex(router.rloc) == -1)
262                                                 {
263                                                         nodes.push( {
264                                                                 rloc: router.rloc,
265                                                                 role: getRole(router.rloc, leaderRloc)
266                                                         } );
267                                                 }
268                                                 links.push( {
269                                                         source: localIndex,
270                                                         target: getNodesIndex(router.rloc)
271                                                 } );
272                                         });
273                                 });
274
275                                 var i;
276                                 for(i = 0;i < st.joinernum;i++) {
277                                         nodes.push( {
278                                                 rloc: "new joiner" + i.toString(),
279                                                 role: 'joiner'
280                                         } );
281                                 }
282
283                                 update_graph(nodes, links, localrloc);
284                         }
285                 });
286
287         function getNodesIndex(targetRloc)
288         {
289                 var i;
290                 for (i = 0; i < nodes.length; i++)
291                 {
292                         if(nodes[i].rloc == targetRloc)
293                                 return Number(i);
294                 }
295                 return Number(-1);
296         }
297
298         XHR.poll(2, '<%=url('admin/network/thread_neighbors')%>', null,
299                 function(x, st)
300                 {
301                         if (st && st.state == 'child')
302                         {
303                                 var tb = document.getElementById('parent');
304                                 document.getElementById('neighbors').style.display = "none";
305                                 if(tb)
306                                 {
307                                         var rows = [];
308
309                                         st.neighbor.forEach(function(bss) {
310                                                 rows.push([
311                                                 '<div class="col-2 center"> %s </div>'.format(bss.Rloc16),
312                                                 '<div class="col-2 center"> %s </div>'.format(transRole(bss.Role)),
313                                                 '<div class="col-2 center"> %s </div>'.format(bss.Age),
314                                                 '<div class="col-2 center"> %s </div>'.format(bss.LinkQualityIn),
315                                                 '<div class="col-4 center"> %s </div>'.format(bss.ExtAddress),
316                                                 ]);
317                                         });
318                                         var joiner;
319                                         for (joiner = 0; joiner < st.joinernum; joiner++) {
320                                                 rows.push([
321                                                 '<div class="col-2 center"> Pending </div>',
322                                                 '<div class="col-2 center"> New Joiner </div>',
323                                                 '<div class="col-2 center"> Pending </div>',
324                                                 '<div class="col-2 center"> Pending </div>',
325                                                 '<div class="col-4 center"> %s </div>'.format(st.joinerlist[joiner].isAny ? "*" : st.joinerlist[joiner].eui64),
326                                                 '<div class="th cbi-section-actions">' +
327                                                 '<form action="<%=url('admin/network/joiner_remove')%>" method="post">' +
328                                                         '<input type="hidden" name="token" value="<%=token%>" />' +
329                                                         '<input type="hidden" name="isAny" value="%d" />'.format(st.joinerlist[joiner].isAny) +
330                                                         '<input type="hidden" name="eui64" value="%s" />'.format(st.joinerlist[joiner].isAny ? "*" : st.joinerlist[joiner].eui64) +
331                                                         '<input class="cbi-button cbi-button-reset" type="submit" value="<%:Remove%>" />' +
332                                                 '</form>' +
333                                                 '</div>'
334                                                 ]);
335                                         }
336                                         cbi_update_table(tb, rows, '<center><em><%:No information available%></em></center>');
337                                         tb.style.display = "table";
338                                 }
339                         }
340                         else if(st)
341                         {
342                                 var tb = document.getElementById('neighbors');
343                                 document.getElementById('parent').style.display = "none";
344                                 if(tb)
345                                 {
346                                         var rows = [];
347
348                                         st.neighbor.forEach(function(bss) {
349                                                 rows.push([
350                                                 '<div class="col-2 center"> %s </div>'.format(bss.Rloc16),
351                                                 '<div class="col-2 center"> %s </div>'.format(transRole(bss.Role)),
352                                                 '<div class="col-2 center"> %s </div>'.format(bss.Age),
353                                                 '<div class="col-2 center"> %s </div>'.format(bss.AvgRssi),
354                                                 '<div class="col-2 center"> %s </div>'.format(bss.LastRssi),
355                                                 '<div class="col-2 center"> %s </div>'.format(bss.Mode),
356                                                 '<div class="col-4 center"> %s </div>'.format(bss.ExtAddress)
357                                                 ]);
358                                         });
359                                         var joiner;
360                                         for (joiner = 0; joiner < st.joinernum; joiner++) {
361                                                 rows.push([
362                                                 '<div class="col-2 center"> Pending </div>',
363                                                 '<div class="col-2 center"> New Joiner </div>',
364                                                 '<div class="col-2 center"> Pending </div>',
365                                                 '<div class="col-2 center"> Pending </div>',
366                                                 '<div class="col-2 center"> Pending </div>',
367                                                 '<div class="col-2 center"> Pending </div>',
368                                                 '<div class="col-4 center"> %s </div>'.format(st.joinerlist[joiner].isAny ? "*" : st.joinerlist[joiner].eui64),
369                                                 '<div class="th cbi-section-actions">' +
370                                                 '<form action="<%=url('admin/network/joiner_remove')%>" method="post">' +
371                                                         '<input type="hidden" name="token" value="<%=token%>" />' +
372                                                         '<input type="hidden" name="isAny" value="%d" />'.format(st.joinerlist[joiner].isAny) +
373                                                         '<input type="hidden" name="eui64" value="%s" />'.format(st.joinerlist[joiner].isAny ? "*" : st.joinerlist[joiner].eui64) +
374                                                         '<input class="cbi-button cbi-button-reset" type="submit" value="<%:Remove%>" />' +
375                                                 '</form>' +
376                                                 '</div>'
377                                                 ]);
378                                         }
379                                         cbi_update_table(tb, rows, '<center><em><%:No information available%></em></center>');
380                                         tb.style.display = "table";
381                                 }
382                         }
383                 });
384
385         function transRole(info) {
386                 if(info == "C") return 'Child';
387                 else if(info == "R") return "Router";
388                 else return "Pending";
389         }
390 //]]></script>