3 Copyright 2017 Openthread authors. All rights reserved.
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.
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.
28 <html lang="en" ng-app="StarterApp">
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>
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">
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">
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">
52 <link rel="shortcut icon" href="res/img/favicon.png">
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 -->
56 <link rel="canonical" href="http://www.example.com/">
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">
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">
85 <div class="demo-drawer mdl-layout__drawer mdl-color--cyan-600 mdl-color-text--blue-grey-50">
86 <header class="demo-drawer-header">
88 <h4 style="margin: 18px 12px 12px 24px">OT Border Router</h4>
90 <nav class="demo-navigation mdl-navigation mdl-color--blue-grey-800">
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}}
97 <div class="mdl-layout-spacer"></div>
100 <main class="mdl-layout__content mdl-color--grey-100">
101 <div class="mdl-grid demo-content">
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%">
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>
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%">
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">
127 <th class="mdl-data-table__cell--non-numeric">No.</th>
128 <th>Network Name</th>
129 <th>Extended PAN ID</th>
132 <th>Hardware Address</th>
138 <tr ng-repeat="item in networksInfo track by $index">
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>
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>
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">
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 Netowork Name must be no more than 16 characters long.</div>
170 </md-input-container>
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>
179 </md-input-container>
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>
190 </md-input-container>
192 <md-input-container flex="50">
193 <label>Passphrase</label>
194 <input required name="passphrase" ng-model="thread.passphrase">
195 <div ng-messages="threadForm.passphrase.$error">
196 <div ng-message="required">This is required.</div>
198 </md-input-container>
202 <md-input-container flex="50">
203 <label>Master Key</label>
204 <input required minlength="32" maxlength="32" ng-pattern="/^[0-9a-fA-F]{32}$/" name="masterKey" ng-model="thread.masterKey">
205 <div ng-messages="threadForm.MasterKey.$error">
206 <div ng-message-exp="['required', 'minlength', 'maxlength', 'pattern']">
207 Master Key must be 32 hexadecimal digits long.
210 </md-input-container>
212 <md-input-container flex="50">
213 <label>Channel</label>
214 <input required name="channel" type="number" min="11" max="26" ng-model="thread.channel">
215 <div ng-messages="threadForm.channel.$error">
216 <div ng-message-exp="['required', 'min', 'max']">Channel must be in 11~26.</div>
218 </md-input-container>
222 <md-input-container flex="100">
223 <label>On-Mesh Prefix</label>
224 <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]?))?$/">
225 <div ng-messages="threadForm.prefix.$error">
226 <div ng-message-exp="['required', 'pattern']">
227 On-Mesh Prefix must match valid IPv6 prefix pattern.
230 </md-input-container>
233 <md-input-container class="md-block">
234 <md-checkbox name="defaultRoute" ng-model="thread.defaultRoute" required>
237 </md-input-container>
239 <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 &&
240 threadForm.panId.$valid && threadForm.passphrase.$valid && threadForm.masterKey.$valid &&
241 threadForm.channel.$valid && threadForm.prefix.$valid))">Form</md-button>
247 <div class="demo-charts mdl-color--white mdl-cell mdl-cell--12-col mdl-shadow--2dp mdl-grid" ng-show="menu[3].show">
249 <md-list class="md-dense" flex=100>
250 <md-list-item class="md-3-line" ng-repeat="item in status">
251 <img ng-src="{{item.icon}}" class="md-avatar" alt="" />
252 <div class="md-list-item-text" layout="column">
253 <h3>{{ item.name }}</h3>
254 <h4>{{ item.value }}</h4>
256 <md-divider></md-divider>
261 <div class="demo-charts mdl-color--white mdl-cell mdl-cell--12-col mdl-shadow--2dp mdl-grid" ng-show="menu[4].show">
263 <md-content layout-padding flex="100">
264 <form name="settingForm">
266 <md-input-container flex="100">
267 <label>On-Mesh Prefix</label>
268 <input required name="prefix" ng-model="setting.prefix">
269 <div ng-messages="settingForm.prefix.$error">
270 <div ng-message="required">This is required.</div>
272 </md-input-container>
275 <md-input-container class="md-block">
276 <md-checkbox name="defaultRoute" ng-model="setting.defaultRoute" required>
279 </md-input-container>
281 <md-button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored" type="submit" ng-click="showAddConfirm($event)">Add</md-button>
282 <md-button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored" type="submit" ng-click="showDeleteConfirm($event)">Delete</md-button>
287 <div class="demo-charts mdl-color--white mdl-cell mdl-cell--12-col mdl-shadow--2dp mdl-grid" ng-show="menu[5].show">
289 <md-content layout-padding flex="100">
290 <form name="commissionForm">
292 <md-input-container flex="100">
293 <label>Network Passphrase</label>
294 <input required name="passphrase" ng-model="commission.passphrase">
295 <div ng-messages="commissionForm.passphrase.$error">
296 <div ng-message="required">This is required.</div>
298 </md-input-container>
302 <md-input-container flex="100">
303 <label>Joiner PSKd</label>
304 <input required name="pskd" ng-model="commission.pskd">
305 <div ng-messages="commissionForm.pskd.$error">
306 <div ng-message="required">This is required.</div>
308 </md-input-container>
312 <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>
317 <div class="demo-charts mdl-color--white mdl-shadow--2dp mdl-cell mdl-cell--12-col mdl-grid" ng-show="menu[6].show">
320 <span class="status-title">  Network Name: 
322 <span class="status-content" ng-if="basicInfo.NetworkName"> {{ basicInfo.NetworkName }}</span>
323 <span class="status-title">  Leader: 
325 <span class="status-content" ng-if="basicInfo.LeaderData"> {{ basicInfo.LeaderData.LeaderRouterId }}  
328 <span class="status-title">  #Router: 
331 <span class="status-content"> {{ NumOfRouter }}  
332 </span>     
337 <button ng-disabled="!graphisReady" class="mdl-button mdl-js-button mdl-button--raised" ng-click="showTopology()">Reload</button>
345 <div class="mdl-graphs mdl-shadow--1dp mdl-cell mdl-cell--9-col" ng-show="menu[6].show">
346 <div ng-show="graphisReady" class="d3graph" id="topograph">
350 <div ng-show="!graphisReady" class="load_content">
351 <div class="mdl-spinner mdl-js-spinner is-active"></div>
357 <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">
358 <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">
359 <div class="detailContainer">
360 <div class="detailElement" ng-if="isObject(detailList) && isObject(nodeDetailInfo) "ng-repeat="(key, data) in detailList track by $index">
362 <button ng-show="data.title" ng-click="clickList(key)" type="button" class="collapsible">{{ key }}</button>
363 <div ng-show="data.content" ng-if= "data.title" class="detailContentContainer">
365 <span class=detailContentValue ng-if=" !isObject(nodeDetailInfo[key])&&!isArray(nodeDetailInfo[key])">  {{ nodeDetailInfo[key] }}</span>
368 <ul class="a" ng-if="isArray(nodeDetailInfo[key])" ng-repeat="value in nodeDetailInfo[key] track by $index ">
371 <span ng-if="!isObject(value)&&!isArray(value )" class=detailContentValue>{{ value }}</span>
373 <ul ng-if="isObject(value)" ng-repeat="(k1,v1) in value">
375 <span class="detailContentKey">{{ k1 }}: </span>
377 <ul ng-if="isObject(v1)" ng-repeat="(k2,v2) in v1 track by $index">
379 <span class="detailContentKey"> {{ k2 }}: </span>
380 <span class="detailContentValue">{{ v2 }} </span>
385 <span ng-if="!isObject(v1)&&!isArray(v1)" class="detailContentValue"> {{ v1 }}</span>
394 <ul class="a" ng-if="isObject(nodeDetailInfo[key])" ng-repeat="(k,v) in nodeDetailInfo[key] track by $index">
396 <span class="detailContentKey">{{ k }}: </span>
398 <span ng-if="!isObject(v)&&!isArray(v)" class="detailContentValue"> {{ v }}</span>
399 <ul ng-if="isArray(v)" ng-repeat="v3 in v track by $index">
401 <ul ng-if="isObject(v3)" ng-repeat="(k4,v4) in v3 track by $index">
404 <span class="detailContentKey"> {{ k4 }}: </span>
405 <span class="detailContentValue">{{ v4 }} </span>
410 <span ng-if="!isObject(v3)&&!isArray(v3)" class="detailContentValue"> {{ v1 }}</span>
433 <script src="res/js/material.min.js"></script>
434 <script src="res/js/angular.min.js"></script>
435 <script src="res/js/angular-animate.min.js"></script>
436 <script src="res/js/angular-aria.min.js"></script>
437 <script src="res/js/angular-material.min.js"></script>
438 <script src="res/js/angular-messages.min.js"></script>
439 <script src="res/js/app.js"></script>
440 <script src="res/js/d3.min.js"></script>