[ONOS-4159] PCE Web GUI implementation: Tunnel highlight and defect fixes

Change-Id: I385c00d4654e746133f0d9757511e3a8821fad7a
(cherry picked from commit 45a1e9ac48f14cbe875e09c635bd8c940b2735c2)
diff --git a/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovMessageHandler.java b/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovMessageHandler.java
index 16ce224..1aa0f1d 100644
--- a/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovMessageHandler.java
+++ b/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovMessageHandler.java
@@ -36,8 +36,11 @@
 import org.onosproject.ui.UiMessageHandler;
 import org.onosproject.ui.topo.DeviceHighlight;
 import org.onosproject.ui.topo.Highlights;
+import org.onosproject.ui.topo.LinkHighlight;
+import org.onosproject.ui.topo.Mod;
 import org.onosproject.ui.topo.NodeBadge;
 import org.onosproject.ui.topo.TopoJson;
+import org.onosproject.ui.topo.TopoUtils;
 import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.intent.Constraint;
 import org.onosproject.pce.pceservice.LspType;
@@ -53,6 +56,7 @@
 import org.onosproject.incubator.net.tunnel.TunnelId;
 import org.onosproject.incubator.net.tunnel.TunnelListener;
 import org.onosproject.incubator.net.tunnel.TunnelService;
+import static org.onosproject.ui.topo.LinkHighlight.Flavor.*;
 import static org.onosproject.incubator.net.tunnel.Tunnel.Type.MPLS;
 
 import com.fasterxml.jackson.databind.node.ArrayNode;
@@ -68,8 +72,6 @@
 public class PceWebTopovMessageHandler extends UiMessageHandler {
 
     private static final String PCEWEB_CLEAR = "pceTopovClear";
-    private static final String PCEWEB_SET_SRC = "pceTopovSetSrc";
-    private static final String PCEWEB_SET_DST = "pceTopovSetDst";
     private static final String PCEWEB_SET_PATH = "pceTopovSetMode";
     private static final String PCEWEB_UPDATE_PATH_QUERY = "pceTopovUpdateQuery";
     private static final String PCEWEB_UPDATE_PATH = "pceTopovUpdate";
@@ -78,11 +80,10 @@
     private static final String PCEWEB_QUERY_TUNNELS = "pceTopovTunnelDisplay";
     private static final String PCEWEB_SHOW_TUNNEL = "pceTopovShowTunnels";
     private static final String PCEWEB_SHOW_TUNNEL_REMOVE = "pceTopovShowTunnelsRem";
-    private static final String ID = "id";
-    private static final String TYPE = "type";
-    private static final String ROUTER = "router";
-    private static final String DST = "Egress";
-    private static final String SRC = "Ingress";
+    private static final String PCEWEB_TUNNEL_UPDATE_INFO = "updatePathmsgInfo";
+    private static final String PCEWEB_TUNNEL_UPDATE_INFO_REPLY = "pceTopovShowTunnelsUpdate";
+    private static final String DST = "DST";
+    private static final String SRC = "SRC";
     private static final String BANDWIDTH = "bw";
     private static final String BANDWIDTHTYPE = "bwtype";
     private static final String COSTTYPE = "ctype";
@@ -94,6 +95,7 @@
     private static final String COST_TYPE_IGP = "igp";
     private static final String COST_TYPE_TE = "te";
     private static final String BANDWIDTH_TYPE_KBPS = "kbps";
+    private static final String BANDWIDTH_TYPE_MBPS = "kbps";
     private static final String BUFFER_ARRAY = "a";
     private static final String BANDWIDTH_BPS = "BPS";
     private static final String LSP_TYPE_CR = "cr";
@@ -105,9 +107,11 @@
     private static final int DELAY_MS = 1100;
     private static final double BANDWIDTH_KBPS = 1_000;
     private static final double BANDWIDTH_MBPS = 1_000_000;
-
+    private static String[] linkColor = {"pCol1", "pCol2", "pCol3", "pCol4", "pCol5",
+                                               "pCol6", "pCol7", "pCol8", "pCol9", "pCol10",
+                                               "pCol11", "pCol12", "pCol13", "pCol14", "pCol15"};
+    private static final int LINK_COLOR_MAX = 15;
     private Set<Link> allPathLinks;
-    private int highlightDelay;
     private ElementId src, dst;
     private List<Path> paths = new LinkedList<>();
     private int pathIndex;
@@ -141,6 +145,7 @@
                 new UpdatePathHandler(),
                 new RemovePathQueryHandler(),
                 new RemovePathHandler(),
+                new UpdatePathInfoHandler(),
                 new ShowTunnelHandler());
     }
 
@@ -276,6 +281,50 @@
     }
 
     /**
+     * Handles the 'update path' event received from the client.
+     */
+    private final class UpdatePathInfoHandler extends RequestHandler {
+
+        public UpdatePathInfoHandler() {
+            super(PCEWEB_TUNNEL_UPDATE_INFO);
+        }
+
+        @Override
+        public void process(long sid, ObjectNode payload) {
+            String tunnelIdStr = string(payload, TUNNEL_ID);
+
+            if (tunnelIdStr == null) {
+                log.error("PCE update path is failed.");
+            }
+
+            if (tunnelIdStr.equals(STRING_NULL)) {
+                log.error("PCE update path is failed.");
+                return;
+            }
+
+            if (pceService == null) {
+                log.error("PCE service is not active");
+                return;
+            }
+
+            TunnelId tunnelId = TunnelId.valueOf(tunnelIdStr);
+            Tunnel tunnel = tunnelService.queryTunnel(tunnelId);
+            ObjectNode result = objectNode();
+            ArrayNode arrayNode = arrayNode();
+
+            arrayNode.add("Tunnel");
+            arrayNode.add(tunnelIdStr);
+            arrayNode.add("BandWidth");
+            arrayNode.add(tunnel.annotations().value("bandwidth"));
+            arrayNode.add("CostType");
+            arrayNode.add(tunnel.annotations().value("costType"));
+
+            result.putArray(BUFFER_ARRAY).addAll(arrayNode);
+            sendMessage(PCEWEB_TUNNEL_UPDATE_INFO_REPLY, sid, result);
+        }
+    }
+
+    /**
      * Handles the 'remove path query' event received from the client.
      */
     private final class RemovePathQueryHandler extends RequestHandler {
@@ -484,7 +533,7 @@
         }
         if (bandWidthType.equals(BANDWIDTH_TYPE_KBPS)) {
             bwValue = bwValue * BANDWIDTH_KBPS;
-        } else {
+        } else if (bandWidthType.equals(BANDWIDTH_TYPE_MBPS)) {
             bwValue = bwValue * BANDWIDTH_MBPS;
         }
 
@@ -516,20 +565,20 @@
      * Handles the highlights of selected path.
      */
     private void hilightAndSendPaths(Highlights highlights) {
-        PceWebLinkMap linkMap = new PceWebLinkMap();
-        allPathLinks.forEach(linkMap::add);
-        Set<Link> selectedPathLinks;
-
-        selectedPathLinks = paths.isEmpty() ?
-                ImmutableSet.of() : ImmutableSet.copyOf(paths.get(pathIndex).links());
-
-        if (highlightDelay > 0) {
-            highlights.delay(highlightDelay);
+        LinkHighlight lh;
+        int linkclr = 0;
+        for (Path path : paths) {
+            for (Link link : path.links()) {
+                lh = new LinkHighlight(TopoUtils.compactLinkString(link), PRIMARY_HIGHLIGHT)
+                         .addMod(new Mod(linkColor[linkclr]));
+                highlights.add(lh);
+            }
+            linkclr = linkclr + 1;
+            if (linkclr == LINK_COLOR_MAX) {
+                linkclr = 0;
+            }
         }
-        for (PceWebLink plink : linkMap.biLinks()) {
-            plink.computeHilight(selectedPathLinks, allPathLinks);
-            highlights.add(plink.highlight(null));
-        }
+
         sendMessage(TopoJson.highlightsMessage(highlights));
     }
 
@@ -578,9 +627,7 @@
     private class InternalTopologyListener implements TopologyListener {
         @Override
         public void event(TopologyEvent event) {
-            highlightDelay = DELAY_MS;
             findTunnelAndHighlights();
-            highlightDelay = 0;
         }
     }
 
@@ -592,9 +639,7 @@
         public void event(TunnelEvent event) {
             Tunnel tunnel = event.subject();
             if (tunnel.type() == MPLS) {
-                highlightDelay = DELAY_MS;
                 findTunnelAndHighlights();
-                highlightDelay = 0;
             }
         }
     }
@@ -604,17 +649,19 @@
     */
     private void findTunnelAndHighlights() {
         Collection<Tunnel> tunnelSet = null;
+        Highlights highlights = new Highlights();
+        paths.removeAll(paths);
         tunnelSet = tunnelService.queryTunnel(MPLS);
         if (tunnelSet.size() == 0) {
             log.warn("Tunnel does not exist");
+            sendMessage(TopoJson.highlightsMessage(highlights));
             return;
         }
 
-        paths.removeAll(paths);
-        Highlights highlights = new Highlights();
         for (Tunnel tunnel : tunnelSet) {
             if (tunnel.path() == null) {
                 log.error("path does not exist");
+                sendMessage(TopoJson.highlightsMessage(highlights));
                 return;
             }
             Link firstLink = tunnel.path().links().get(0);
diff --git a/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopov.css b/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopov.css
index 705f891..8e414c0 100644
--- a/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopov.css
+++ b/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopov.css
@@ -2,3 +2,153 @@
 .radioButtonSpace {

     margin-left:20px;

 }

+/* color:1 */

+#ov-topo svg .link.primary.pCol1 {

+    stroke-width: 6px;

+}

+.light #ov-topo svg .link.primary.pCol1 {

+    stroke: #FF00CE;

+}

+.dark #ov-topo svg .link.primary.pCol1 {

+    stroke: #FF00CE;

+}

+/* color:2 */

+#ov-topo svg .link.primary.pCol2 {

+    stroke-width: 6px;

+}

+.light #ov-topo svg .link.primary.pCol2 {

+    stroke: #ff4000;

+}

+.dark #ov-topo svg .link.primary.pCol2 {

+    stroke: #ff4000;

+}

+/* color:3 */

+#ov-topo svg .link.primary.pCol3 {

+    stroke-width: 6px;

+}

+.light #ov-topo svg .link.primary.pCol3 {

+    stroke: #ffb400;

+}

+.dark #ov-topo svg .link.primary.pCol3 {

+    stroke: #ffb400;

+}

+/* color:4 */

+#ov-topo svg .link.primary.pCol4 {

+    stroke-width: 6px;

+}

+.light #ov-topo svg .link.primary.pCol4 {

+    stroke: #89ff00;

+}

+.dark #ov-topo svg .link.primary.pCol4 {

+    stroke: #89ff00;

+}

+/* color:5 */

+#ov-topo svg .link.primary.pCol5 {

+    stroke-width: 6px;

+}

+.light #ov-topo svg .link.primary.pCol5 {

+    stroke: #00FF2B;

+}

+.dark #ov-topo svg .link.primary.pCol5 {

+    stroke: #00FF2B;

+}

+/* color:6 */

+#ov-topo svg .link.primary.pCol6 {

+    stroke-width: 6px;

+}

+.light #ov-topo svg .link.primary.pCol6 {

+    stroke: #00ffec;

+}

+.dark #ov-topo svg .link.primary.pCol6 {

+    stroke: #00ffec;

+}

+/* color:7 */

+#ov-topo svg .link.primary.pCol7 {

+    stroke-width: 6px;

+}

+.light #ov-topo svg .link.primary.pCol7 {

+    stroke: #00abff;

+}

+.dark #ov-topo svg .link.primary.pCol7 {

+    stroke: #00abff;

+}

+/* color:8 */

+#ov-topo svg .link.primary.pCol8 {

+    stroke-width: 6px;

+}

+.light #ov-topo svg .link.primary.pCol8 {

+    stroke: #005eff;

+}

+.dark #ov-topo svg .link.primary.pCol8 {

+    stroke: #005eff;

+}

+/* color:9 */

+#ov-topo svg .link.primary.pCol9 {

+    stroke-width: 6px;

+}

+.light #ov-topo svg .link.primary.pCol9 {

+    stroke: #0011ff;

+}

+.dark #ov-topo svg .link.primary.pCol9 {

+    stroke: #0011ff;

+}

+/* color:10 */

+#ov-topo svg .link.primary.pCol10 {

+    stroke-width: 6px;

+}

+.light #ov-topo svg .link.primary.pCol10 {

+    stroke: #7c00ff;

+}

+.dark #ov-topo svg .link.primary.pCol10 {

+    stroke: #7c00ff;

+}

+/* color:11 */

+#ov-topo svg .link.primary.pCol11 {

+    stroke-width: 6px;

+}

+.light #ov-topo svg .link.primary.pCol11 {

+    stroke: #ffe700;

+}

+.dark #ov-topo svg .link.primary.pCol11 {

+    stroke: #ffe700;

+}

+/* color:12 */

+#ov-topo svg .link.primary.pCol12 {

+    stroke-width: 6px;

+}

+.light #ov-topo svg .link.primary.pCol12 {

+    stroke: #00ffec;

+}

+.dark #ov-topo svg .link.primary.pCol12 {

+    stroke: #00ffec;

+}

+/* color:13 */

+#ov-topo svg .link.primary.pCol13 {

+    stroke-width: 6px;

+}

+.light #ov-topo svg .link.primary.pCol13 {

+    stroke: #c900ff;

+}

+.dark #ov-topo svg .link.primary.pCol13 {

+    stroke: #c900ff;

+}

+/* color:14 */

+#ov-topo svg .link.primary.pCol14 {

+    stroke-width: 6px;

+}

+.light #ov-topo svg .link.primary.pCol14 {

+    stroke: #ff00e7;

+}

+.dark #ov-topo svg .link.primary.pCol14 {

+    stroke: #ff00e7;

+}

+/* color:15 */

+#ov-topo svg .link.primary.pCol15 {

+    stroke-width: 6px;

+}

+.light #ov-topo svg .link.primary.pCol15 {

+    stroke: #3c00ff;

+}

+.dark #ov-topo svg .link.primary.pCol15 {

+    stroke: #3c00ff;

+}

diff --git a/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovDemo.js b/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovDemo.js
index bf7723d..06d6771 100644
--- a/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovDemo.js
+++ b/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovDemo.js
@@ -21,7 +21,7 @@
 
     // injected refs
     var $log, fs, flash, wss, tps, ns, tds, ds;
-    var tunnelNameData, tunnelNameDataRemove;
+    var tunnelNameData, tunnelNameDataRemove, tunnelDataUpdateInfo, tunnelIdUpd;
    // constants
     var srcMessage = 'pceTopovSetSrc',
         dstMessage = 'pceTopovSetDst',
@@ -30,14 +30,17 @@
         updatePathmsgQuery = 'pceTopovUpdateQuery',
         remPathmsgQuery = 'pceTopovRemQuery',
         updatePathmsg = 'pceTopovUpdate',
+        updatePathmsgInfo = 'updatePathmsgInfo',
         remPathmsg = 'pceTopovRem',
         showTunnelInfoMsg = 'pceTopovShowTunnels',
         queryDisplayTunnelMsg = 'pceTopovTunnelDisplay',
-        showTunnelInfoRemoveMsg = 'pceTopovShowTunnelsRem';
+        showTunnelInfoRemoveMsg = 'pceTopovShowTunnelsRem',
+        showTunnelInfoUpdateMsg = 'pceTopovShowTunnelsUpdate';
     // internal state
     var currentMode = null;
     var handlerMap = {},
-        handlerMapRem = {};
+        handlerMapRem = {},
+        handlerMapShowUpdate = {};
     // === ---------------------------
     // === Helper functions
 
@@ -89,8 +92,6 @@
                     id: id
                 });
             }
-
-
             p.append('span').text(nameField);
             p.append('br');
         }
@@ -100,6 +101,7 @@
         addAttribute('band-width-value-name', 'band-width-value', null, 'number');
         addAttribute('pce-band-type', 'band-kpbs-val', 'kbps', 'radio');
         addAttribute('pce-band-type', 'band-mpbs-val', 'mbps', 'radio');
+        addAttribute('pce-band-type', 'band-bps-val', 'bps', 'radio');
         //Add the cost type related inputs.
         addAttribute('pce-cost-type-name', 'pce-cost-type', 'Cost Type', 'checkbox');
         addAttribute('pce-cost-type-valname', 'pce-cost-type-igp', 'IGP', 'radio');
@@ -139,10 +141,11 @@
         return content;
     }
 
-    function createUserTextUpdatePathEvent() {
+    function createUserTextUpdatePathEvent(data) {
         var content = ds.createDiv(),
             form = content.append('form'),
             p = form.append('p');
+        var constType;
 
         function addAttribute(name, id, nameField, type) {
             if (type == 'radio') {
@@ -165,15 +168,79 @@
             p.append('br');
         }
 
-        //Add the bandwidth related inputs.
-        addAttribute('band-width-name', 'update-band-width-box', 'Band Width', 'checkbox');
-        addAttribute('band-width-value-name', 'update-band-width-value', null, 'number');
-        addAttribute('pce-band-type', 'update-band-kpbs-val', 'kbps', 'radio');
-        addAttribute('pce-band-type', 'update-band-mpbs-val', 'mbps', 'radio');
-        //Add the cost type related inputs.
-        addAttribute('pce-cost-type', 'update-pce-cost-type', 'Cost Type', 'checkbox');
-        addAttribute('pce-cost-type-value', 'update-pce-cost-type-igp', 'IGP', 'radio');
-        addAttribute('pce-cost-type-value', 'update-pce-cost-type-te', 'TE', 'radio');
+        data.a.forEach( function (val, idx) {
+            if (val == 'Tunnel') {
+                constType = 'TUNNEL';
+                return;
+            }
+
+            if (val == 'BandWidth') {
+                constType = 'BW';
+                return;
+            }
+
+            if (val == 'CostType') {
+                constType = 'CT';
+                return;
+            }
+
+            if (constType == 'TUNNEL') {
+                p.append('span').text('Tunnel Id: ');
+                p.append('span').text(val);
+                p.append('br');
+                tunnelIdUpd = val;
+            }
+
+            if (constType == 'BW') {
+                addAttribute('band-width-name', 'update-band-width-box', 'Band Width', 'checkbox');
+                p.append('input').attr({
+                    id: 'update-band-width-value',
+                    type: 'number',
+                    name: 'band-width-value-name',
+                    value: val
+                });
+                p.append('br');
+                p.append('input').attr({
+                    id: 'update-band-bps-val',
+                    type: 'radio',
+                    name: 'pce-band-type',
+                    checked: 'checked',
+                    class: 'radioButtonSpace'
+                });
+                p.append('span').text('bps');
+                p.append('br');
+                addAttribute('pce-band-type', 'update-band-kbps-val', 'kbps', 'radio');
+                addAttribute('pce-band-type', 'update-band-mbps-val', 'mbps', 'radio');
+            }
+
+            if (constType == 'CT') {
+                addAttribute('pce-cost-type', 'update-pce-cost-type', 'Cost Type', 'checkbox');
+                if (val == 'COST') {
+                    p.append('input').attr({
+                        id: 'update-pce-cost-type-igp',
+                        type: 'radio',
+                        name: 'pce-cost-type-value',
+                        checked: 'checked',
+                        class: 'radioButtonSpace'
+                    });
+                    p.append('span').text('IGP');
+                    p.append('br');
+                    addAttribute('pce-cost-type-value', 'update-pce-cost-type-te', 'TE', 'radio');
+ 
+                } else {
+                    addAttribute('pce-cost-type-value', 'update-pce-cost-type-igp', 'IGP', 'radio');
+                    p.append('input').attr({
+                        id: 'update-pce-cost-type-te',
+                        type: 'radio',
+                        name: 'pce-cost-type-value',
+                        checked: 'checked',
+                        class: 'radioButtonSpace'
+                    });
+                    p.append('span').text('TE');
+                    p.append('br');
+                }
+            }
+        } );
 
         return content;
     }
@@ -222,66 +289,65 @@
                     tdString = val;
                 }
             } );
+            //send event to server for getting the tunnel information.
+            if (tdString != null) {
+                handlerMapShowUpdate[showTunnelInfoUpdateMsg] = showTunnelInfoUpdateMsgHandle;
+                wss.bindHandlers(handlerMapShowUpdate);
 
-            constraintsUpdateDialog(tdString);
+                wss.sendEvent(updatePathmsgInfo, {
+                    tunnelid: tdString
+                });
+            }
+            //constraintsUpdateDialog(tdString);
             $log.debug('Dialog OK button clicked');
         }
 
         tds.openDialog()
             .setTitle('Available LSPs with selected device')
             .addContent(createUserTextUpdate(data))
-            .addOkChained(dOkUpdate, 'OK')
+            .addOk(dOkUpdate, 'OK')
             .addCancel(dClose, 'Close')
             .bindKeys();
     }
 
-    function constraintsUpdateDialog(tunnelId) {
+    function dOkUpdateEvent() {
+        $log.debug('Select constraints for update path Dialog OK button pressed');
 
-        // invoked when the OK button is pressed on this dialog
-        function dOkUpdateEvent() {
-            $log.debug('Select constraints for update path Dialog OK button pressed');
+        var bandWidth = isChecked('update-band-width-box'),
+            bandValue = null,
+            bandType = null;
 
-            var bandWidth = isChecked('update-band-width-box'),
-                bandValue = null,
-                bandType = null;
+        if (bandWidth) {
+            bandValue = getCheckedValue('update-band-width-value');
 
-            if (bandWidth) {
-                bandValue = d3.select('#update-band-width-value');
-
-                if (isChecked('update-band-kpbs-val')) {
+            if (isChecked('update-band-kbps-val')) {
                     bandType = 'kbps';
-                } else if (isChecked('update-band-mpbs-val')) {
+            } else if (isChecked('update-band-mbps-val')) {
                     bandType = 'mbps';
-                }
+            } else if (isChecked('update-band-bps-val')) {
+                    bandType = 'bps';
             }
-
-            var costType = isChecked('update-pce-cost-type'),
-                costTypeVal = null;
-
-            if (costType) {
-                if (isChecked('update-pce-cost-type-igp')) {
-                    costTypeVal = 'igp';
-                } else if (isChecked('update-pce-cost-type-te')) {
-                   costTypeVal = 'te';
-                }
-            }
-
-            wss.sendEvent(updatePathmsg, {
-                    bw: bandValue,
-                    ctype: costTypeVal,
-                    tunnelname: tunnelId
-            });
-
-            flash.flash('update path message');
-
         }
 
-        tds.openDialog()
-            .setTitle('Select constraints for update path')
-            .addContent(createUserTextUpdatePathEvent())
-            .addCancel()
-            .addOk(dOkUpdateEvent, 'OK')     // NOTE: NOT the "chained" version!
-            .bindKeys();
+        var costType = isChecked('update-pce-cost-type'),
+            costTypeVal = null;
+
+        if (costType) {
+            if (isChecked('update-pce-cost-type-igp')) {
+                costTypeVal = 'igp';
+            } else if (isChecked('update-pce-cost-type-te')) {
+                costTypeVal = 'te';
+            }
+        }
+
+        wss.sendEvent(updatePathmsg, {
+                bw: bandValue,
+                bwtype: bandType,
+                ctype: costTypeVal,
+                tunnelname: tunnelIdUpd
+        });
+
+        flash.flash('update path message');
 
     }
 
@@ -297,6 +363,18 @@
             .bindKeys();
     }
 
+    function showTunnelInfoUpdateMsgHandle(data) {
+
+        wss.unbindHandlers(handlerMapShowUpdate);
+        tunnelDataUpdateInfo = data;
+        tds.openDialog()
+            .setTitle('Constrainst selection for update')
+            .addContent(createUserTextUpdatePathEvent(data))
+            .addOk(dOkUpdateEvent, 'OK')
+            .addCancel(dClose, 'Close')
+            .bindKeys();
+    }
+
     //setup path
     function setMode(node) {
 
@@ -312,6 +390,8 @@
                     bandType = 'kbps';
                 } else if (isChecked('band-mpbs-val')) {
                     bandType = 'mbps';
+                } else if (isChecked('band-bps-val')) {
+                    bandType = 'bps';
                 }
             }