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">  Network Name:  312 </span> 313 <span class="status-content" ng-if="basicInfo.NetworkName"> {{ basicInfo.NetworkName }}</span> 314 <span class="status-title">  Leader:  315 </span> 316 <span class="status-content" ng-if="basicInfo.LeaderData"> {{ basicInfo.LeaderData.LeaderRouterId }}   317 </span> 318 319 <span class="status-title">  #Router:  320 </span> 321 322 <span class="status-content"> {{ NumOfRouter }}   323 </span>      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])">  {{ 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"> {{ 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"> {{ 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