xref: /aosp_15_r20/external/ot-br-posix/src/web/web-service/frontend/index.html (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
1<!DOCTYPE html>
2<!--
3  Copyright 2017 Openthread authors. All rights reserved.
4
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions are met:
7  1. Redistributions of source code must retain the above copyright
8     notice, this list of conditions and the following disclaimer.
9  2. Redistributions in binary form must reproduce the above copyright
10     notice, this list of conditions and the following disclaimer in the
11     documentation and/or other materials provided with the distribution.
12  3. Neither the name of the copyright holder nor the
13     names of its contributors may be used to endorse or promote products
14     derived from this software without specific prior written permission.
15
16  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  POSSIBILITY OF SUCH DAMAGE.
27-->
28<html lang="en" ng-app="StarterApp">
29
30<head>
31  <meta charset="utf-8">
32  <meta http-equiv="X-UA-Compatible" content="IE=edge">
33  <meta name="description" content="A front-end template that helps you build fast, modern mobile web apps.">
34  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
35  <title>OpenThread Border Router</title>
36
37  <!-- Add to homescreen for Chrome on Android -->
38  <meta name="mobile-web-app-capable" content="yes">
39  <link rel="icon" sizes="192x192" href="res/img/android-desktop.png">
40  <link rel="stylesheet" href="res/css/angular-material.min.css">
41
42  <!-- Add to homescreen for Safari on iOS -->
43  <meta name="apple-mobile-web-app-capable" content="yes">
44  <meta name="apple-mobile-web-app-status-bar-style" content="black">
45  <meta name="apple-mobile-web-app-title" content="Material Design Lite">
46  <link rel="apple-touch-icon-precomposed" href="res/img/ios-desktop.png">
47
48  <!-- Tile icon for Win8 (144x144 + tile color) -->
49  <meta name="msapplication-TileImage" content="images/touch/ms-touch-icon-144x144-precomposed.png">
50  <meta name="msapplication-TileColor" content="#3372DF">
51
52  <link rel="shortcut icon" href="res/img/favicon.png">
53
54  <!-- SEO: If your mobile URL is different from the desktop URL, add a canonical link to the desktop page https://developers.google.com/webmasters/smartphone-sites/feature-phones -->
55  <!--
56    <link rel="canonical" href="http://www.example.com/">
57    -->
58  <link rel="stylesheet" href="res/css/material.min.css">
59  <!-- <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> -->
60  <link rel="stylesheet" href="res/css/styles.css">
61  <style>
62    #view-source {
63      position: fixed;
64      display: block;
65      right: 0;
66      bottom: 0;
67      margin-right: 40px;
68      margin-bottom: 40px;
69      z-index: 900;
70    }
71  </style>
72</head>
73
74<body ng-controller="AppCtrl">
75  <div class="demo-layout mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
76    <header class="demo-header mdl-layout__header mdl-color--indego-900 mdl-color-text---600">
77      <div class="mdl-layout__header-row">
78        <span class="mdl-layout-title">{{headerTitle}}</span>
79        <div class="mdl-layout-spacer"></div>
80        <div class="mdl-textfield mdl-js-textfield mdl-textfield--expandable">
81
82        </div>
83      </div>
84    </header>
85    <div class="demo-drawer mdl-layout__drawer mdl-color--cyan-600 mdl-color-text--blue-grey-50">
86      <header class="demo-drawer-header">
87
88        <h4 style="margin: 18px 12px 12px 24px">OT Border Router</h4>
89      </header>
90      <nav class="demo-navigation mdl-navigation mdl-color--blue-grey-800">
91        <md-list flex>
92          <md-list-item md-ink-ripple class="mdl-navigation__link" ng-repeat="item in menu" ng-click="showPanels($index)" layout="row">
93            <div><i class="mdl-color-text--blue-grey-400 material-icons" role="presentation">{{item.icon}}</i>{{item.title}}
94            </div>
95          </md-list-item>
96        </md-list>
97        <div class="mdl-layout-spacer"></div>
98      </nav>
99    </div>
100    <main class="mdl-layout__content mdl-color--grey-100">
101      <div class="mdl-grid demo-content">
102
103        <div class="demo-charts mdl-color--white mdl-shadow--2dp mdl-cell mdl-cell--12-col mdl-grid" ng-show="menu[0].show">
104          <div class="demo-charts mdl-color--white mdl-shadow--2dp mdl-cell mdl-cell--12-col mdl-grid">
105            <img src="res/img/openthread_logo.png" height="100%" , width="100%">
106          </div>
107          <div class="demo-charts mdl-color--white  mdl-cell mdl-cell--12-col mdl-grid">
108            <h1>What is OpenThread?</h1>
109            <p><strong>...an open-source implementation of the Thread networking protocol.</strong>Nest has released OpenThread to make the technology used in Nest products more broadly available to developers to accelerate the development of products for the connected home.</p>
110            <p><strong>...OS and platform agnostic</strong>, with a narrow platform abstraction layer and a small memory footprint, making it highly portable.</p>
111            <p><strong>...a Thread Certified Component </strong>implementing all features defined in the Thread 1.1.1 specification. This specification defines an IPv6-based reliable, secure and low-power wireless device-to-device communication protocol for home applications.</p>
112          </div>
113
114          <div class="demo-charts mdl-color--white  mdl-cell mdl-cell--12-col mdl-grid">
115            <h4>What is OpenThread Border Router?</h4>
116            <p>In the context of a Thread Network, a Border Router is a device that provides connectivity of nodes in the Thread Network to other devices in external networks such as the wider Internet, local home and building IP networks, or virtual private networks (Figure 1).</p>
117            <img src="res/img/borderrouter.png" height="100%" , width="100%">
118          </div>
119        </div>
120
121        <div class="demo-charts mdl-color--white  mdl-cell mdl-cell--12-col mdl-shadow--2dp mdl-grid" ng-show="menu[1].show">
122          <h4>Available Thread Networks</h4>
123          <div class="mdl-cell--12-col">
124            <table class="mdl-data-table mdl-js-data-table" cellspacing="0" width="100%" ng-show="!isLoading">
125              <thead>
126                <tr>
127                  <th class="mdl-data-table__cell--non-numeric">No.</th>
128                  <th>Network Name</th>
129                  <th>Extended PAN ID</th>
130                  <th>PAN ID</th>
131                  <th>channel</th>
132                  <th>Hardware Address</th>
133                  <th>Action</th>
134
135                </tr>
136              </thead>
137              <tbody>
138                <tr ng-repeat="item in networksInfo track by $index">
139                  <td>{{$index}}</td>
140                  <td>{{item.nn}}</td>
141                  <td>{{item.xp}}</td>
142                  <td>{{item.pi}}</td>
143                  <td>{{item.ch}}</td>
144                  <td>{{item.ha}}</td>
145                  <td>
146                    <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-button show-modal" ng-click="showJoinDialog($event, $index, item)">Join</button>
147                  </td>
148                </tr>
149              </tbody>
150            </table>
151          </div>
152        </div>
153        <div class="mdl-cell--12-col" style="margin-top: 50px" ng-show="isLoading&&menu[1].show" layout="row" layout-align="center center" ng-show="menu[1].show">
154           <md-progress-circular md-mode="indeterminate" md-diameter="100"></md-progress-circular>
155        </div>
156
157        <div layout="column" class="demo-charts mdl-color--white  mdl-cell mdl-cell--12-col mdl-shadow--2dp mdl-grid" ng-cloak ng-show="menu[2].show">
158          <h4>Form Thread Networks</h4>
159          <md-progress-linear md-mode="indeterminate" ng-show="menu[2].show&&isForming"></md-progress-linear>
160          <md-content layout-padding flex="100">
161            <form name="threadForm">
162              <div layout="row">
163                <md-input-container flex="50">
164                  <label>Network Name</label>
165                  <input required md-maxlength="16" name="networkName" ng-model="thread.networkName">
166                  <div ng-messages="threadForm.networkName.$error">
167                    <div ng-message="required">This is required.</div>
168                    <div ng-message="md-maxlength">The Network Name must be no more than 16 characters long.</div>
169                  </div>
170                </md-input-container>
171
172                <md-input-container flex="50">
173                  <label>Network Extended PAN ID</label>
174                  <input required maxlength="16" minlength="16" ng-pattern="/^[0-9a-fA-F]{16}$/" name="extPanId" ng-model="thread.extPanId">
175                  <div ng-messages="threadForm.extPanId.$error">
176                    <div ng-message="required">This is required.</div>
177                    <div ng-message-exp="['maxlength', 'minlength', 'pattern']">The Extended PAN ID must be 16 characters long.</div>
178                  </div>
179                </md-input-container>
180              </div>
181
182              <div layout="row">
183                <md-input-container flex="50">
184                  <label>PAN ID</label>
185                  <input required name="panId" ng-model="thread.panId" ng-pattern="/^0x[0-9a-fA-F]{4}$/">
186                  <div ng-messages="threadForm.panId.$error">
187                    <div ng-message="required">This is required.</div>
188                    <div ng-message-exp="['pattern']">The PAN ID must be 4 hexadecimal digits long.</div>
189                  </div>
190                </md-input-container>
191
192                <md-input-container flex="50">
193                  <label>Passphrase/Commissioner Credential</label>
194                  <input required name="passphrase" ng-minlength="6" maxlength="255" ng-model="thread.passphrase">
195                  <div ng-messages="threadForm.passphrase.$error">
196                    <div ng-message="required">This is required.</div>
197                    <div ng-message="minlength">The Passphrase must be a string between 6 and 255 characters.</div>
198                  </div>
199                </md-input-container>
200              </div>
201
202              <div layout="row">
203                <md-input-container flex="50">
204                  <label>Network Key</label>
205                  <input required minlength="32" maxlength="32" ng-pattern="/^[0-9a-fA-F]{32}$/" name="networkKey" ng-model="thread.networkKey">
206                  <div ng-messages="threadForm.NetworkKey.$error">
207                    <div ng-message-exp="['required', 'minlength', 'maxlength', 'pattern']">
208                      Network Key must be 32 hexadecimal digits long.
209                    </div>
210                  </div>
211                </md-input-container>
212
213                <md-input-container flex="50">
214                  <label>Channel</label>
215                  <input required name="channel" type="number" min="11" max="26" ng-model="thread.channel">
216                  <div ng-messages="threadForm.channel.$error">
217                    <div ng-message-exp="['required', 'min', 'max']">Channel must be in 11~26.</div>
218                  </div>
219                </md-input-container>
220              </div>
221
222              <div layout="row">
223                <md-input-container flex="100">
224                  <label>On-Mesh Prefix</label>
225                  <input required name="prefix" ng-model="thread.prefix" ng-pattern="/^(?!(::1?)(/\d*)?$)(?!([fF][eE]80:|[fF]{2}[0-9a-fA-F][0-9a-fA-F]:))(\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*)(/(1([01][0-9]|2[0-8]))|/([0-9][0-9]?))?$/">
226                  <div ng-messages="threadForm.prefix.$error">
227                    <div ng-message-exp="['required', 'pattern']">
228                      On-Mesh Prefix must match valid IPv6 prefix pattern.
229                    </div>
230                  </div>
231                </md-input-container>
232              </div>
233
234              <md-input-container class="md-block">
235                <md-checkbox name="defaultRoute" ng-model="thread.defaultRoute" required>
236                  Default Route
237                </md-checkbox>
238              </md-input-container>
239              <div>
240                <md-button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored" type="submit" ng-click="showConfirm($event, (threadForm.networkName.$valid && threadForm.extPanId.$valid &&
241                threadForm.panId.$valid && threadForm.passphrase.$valid && threadForm.networkKey.$valid &&
242                threadForm.channel.$valid && threadForm.prefix.$valid))">Form</md-button>
243              </div>
244            </form>
245          </md-content>
246        </div>
247
248        <div class="demo-charts mdl-color--white  mdl-cell mdl-cell--12-col mdl-shadow--2dp mdl-grid" ng-show="menu[3].show">
249          <h4>Get Status</h4>
250          <md-list class="md-dense" flex=100>
251            <md-list-item class="md-3-line" ng-repeat="item in status">
252              <img ng-src="{{item.icon}}" class="md-avatar" alt="" />
253              <div class="md-list-item-text" layout="column">
254                <h3>{{ item.name }}</h3>
255                <h4>{{ item.value }}</h4>
256              </div>
257              <md-divider></md-divider>
258            </md-list-item>
259          </md-list>
260        </div>
261
262        <div class="demo-charts mdl-color--white  mdl-cell mdl-cell--12-col mdl-shadow--2dp mdl-grid" ng-show="menu[4].show">
263          <h4>Settings</h4>
264            <md-content layout-padding flex="100">
265              <form name="settingForm">
266                <div layout="row">
267                  <md-input-container flex="100">
268                    <label>On-Mesh Prefix</label>
269                    <input required name="prefix" ng-model="setting.prefix">
270                    <div ng-messages="settingForm.prefix.$error">
271                      <div ng-message="required">This is required.</div>
272                    </div>
273                  </md-input-container>
274                </div>
275
276                <md-input-container class="md-block">
277                  <md-checkbox name="defaultRoute" ng-model="setting.defaultRoute" required>
278                    Default Route
279                  </md-checkbox>
280                </md-input-container>
281                <div>
282                  <md-button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored" type="submit" ng-click="showAddConfirm($event)">Add</md-button>
283                  <md-button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored" type="submit" ng-click="showDeleteConfirm($event)">Delete</md-button>
284                </div>
285              </form>
286            </md-content>
287        </div>
288        <div class="demo-charts mdl-color--white  mdl-cell mdl-cell--12-col mdl-shadow--2dp mdl-grid" ng-show="menu[5].show">
289          <h4>Commission</h4>
290            <md-content layout-padding flex="100">
291              <form name="commissionForm">
292                <div layout="row">
293                  <md-input-container flex="100">
294                    <label>Joiner PSKd</label>
295                    <input required name="pskd" ng-model="commission.pskd">
296                    <div ng-messages="commissionForm.pskd.$error">
297                      <div ng-message="required">This is required.</div>
298                    </div>
299                  </md-input-container>
300                </div>
301
302                <div>
303                  <md-button name="commissionButton" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored" type="submit" ng-click="startCommission($event)">Start Commission</md-button>
304                </div>
305              </form>
306            </md-content>
307        </div>
308        <div class="demo-charts mdl-color--white mdl-shadow--2dp mdl-cell mdl-cell--12-col mdl-grid" ng-show="menu[6].show">
309          <div>
310
311            <span class="status-title">&nbsp&nbspNetwork Name:&nbsp
312            </span>
313            <span class="status-content" ng-if="basicInfo.NetworkName"> {{ basicInfo.NetworkName }}</span>
314            <span class="status-title">&nbsp&nbspLeader:&nbsp
315            </span>
316            <span class="status-content" ng-if="basicInfo.LeaderData"> {{ basicInfo.LeaderData.LeaderRouterId }}&nbsp&nbsp
317            </span>
318
319            <span class="status-title">&nbsp&nbsp#Router:&nbsp
320            </span>
321
322            <span class="status-content"> {{ NumOfRouter }}&nbsp&nbsp
323            </span> &nbsp&nbsp&nbsp&nbsp
324
325
326
327
328            <button ng-disabled="!graphisReady" class="mdl-button mdl-js-button mdl-button--raised" ng-click="showTopology()">Reload</button>
329
330
331          </div>
332
333
334        </div>
335
336        <div class="mdl-graphs mdl-shadow--1dp  mdl-cell mdl-cell--9-col" ng-show="menu[6].show">
337          <div ng-show="graphisReady" class="d3graph" id="topograph">
338          </div>
339
340
341          <div ng-show="!graphisReady" class="load_content">
342            <div class="mdl-spinner mdl-js-spinner is-active"></div>
343
344
345          </div>
346
347        </div>
348        <div ng-show="graphisReady && menu[6].show " class="demo-cards  mdl-cell  mdl-cell--top mdl-cell--3-col mdl-cell--8-col-tablet mdl-grid mdl-grid--no-spacing">
349          <div class="demo-updates mdl-card mdl-shadow--1dp mdl-cell mdl-cell--3-col mdl-cell--3-col-tablet mdl-cell--12-col-desktop">
350            <div class="detailContainer">
351                <div class="detailElement" ng-if="isObject(detailList) && isObject(nodeDetailInfo)  "ng-repeat="(key, data) in detailList track by $index">
352
353                  <button ng-show="data.title" ng-click="clickList(key)" type="button" class="collapsible">{{ key }}</button>
354                  <div ng-show="data.content" ng-if= "data.title" class="detailContentContainer">
355
356                    <span class=detailContentValue ng-if=" !isObject(nodeDetailInfo[key])&&!isArray(nodeDetailInfo[key])">&nbsp&nbsp{{ nodeDetailInfo[key] }}</span>
357
358
359                    <ul class="a" ng-if="isArray(nodeDetailInfo[key])" ng-repeat="value in nodeDetailInfo[key] track by $index ">
360                      <li>
361
362                        <span ng-if="!isObject(value)&&!isArray(value )" class=detailContentValue>{{ value }}</span>
363
364                        <ul ng-if="isObject(value)" ng-repeat="(k1,v1) in value">
365                          <li>
366                            <span class="detailContentKey">{{ k1 }}: </span>
367
368                            <ul ng-if="isObject(v1)" ng-repeat="(k2,v2) in v1 track by $index">
369                              <li>
370                                <span class="detailContentKey">&nbsp{{ k2 }}: </span>
371                                <span class="detailContentValue">{{ v2 }} </span>
372
373                              </li>
374                            </ul>
375
376                            <span ng-if="!isObject(v1)&&!isArray(v1)" class="detailContentValue"> {{ v1 }}</span>
377                          </li>
378                        </ul>
379
380                      </li>
381                    </ul>
382
383
384
385                    <ul class="a" ng-if="isObject(nodeDetailInfo[key])" ng-repeat="(k,v) in nodeDetailInfo[key] track by $index">
386                      <li>
387                        <span class="detailContentKey">{{ k }}: </span>
388
389                        <span ng-if="!isObject(v)&&!isArray(v)" class="detailContentValue"> {{ v }}</span>
390                        <ul ng-if="isArray(v)" ng-repeat="v3 in v track by $index">
391                          <li>
392                            <ul ng-if="isObject(v3)" ng-repeat="(k4,v4) in v3 track by $index">
393
394                              <li>
395                                <span class="detailContentKey">&nbsp{{ k4 }}: </span>
396                                <span class="detailContentValue">{{ v4 }} </span>
397
398                              </li>
399                            </ul>
400
401                            <span ng-if="!isObject(v3)&&!isArray(v3)" class="detailContentValue"> {{ v1 }}</span>
402                          </li>
403                        </ul>
404
405                      </li>
406                    </ul>
407
408
409
410
411                  </div>
412               </div>
413
414
415             </div>
416          </div>
417
418
419        </div>
420      </div>
421    </main>
422  </div>
423
424  <script src="res/js/material.min.js"></script>
425  <script src="res/js/angular.min.js"></script>
426  <script src="res/js/angular-animate.min.js"></script>
427  <script src="res/js/angular-aria.min.js"></script>
428  <script src="res/js/angular-material.min.js"></script>
429  <script src="res/js/angular-messages.min.js"></script>
430  <script src="res/js/app.js"></script>
431  <script src="res/js/d3.min.js"></script>
432</body>
433
434</html>
435