From 8889d121c03e0dbe6ee8af4dabbb6f1a812fd8fc Mon Sep 17 00:00:00 2001 From: "Blake J. Harnden" Date: Wed, 16 May 2018 15:45:46 -0700 Subject: [PATCH] web app, added emane node, got basic emane networks working and joining existing emane network --- webapp/app.py | 42 +++++++++++++++ webapp/static/corenetwork.js | 38 ++++++++++--- webapp/static/corerest.js | 6 ++- webapp/static/coreui.js | 80 ++++++++++++++++++++++------ webapp/templates/index.html | 22 ++++---- webapp/templates/nodeedit_modal.html | 2 + 6 files changed, 157 insertions(+), 33 deletions(-) diff --git a/webapp/app.py b/webapp/app.py index 3e2f7b67..6cf2d622 100644 --- a/webapp/app.py +++ b/webapp/app.py @@ -143,6 +143,11 @@ def get_sessions(): def create_session(): session = coreemu.create_session() session.set_state(EventTypes.CONFIGURATION_STATE) + + # set session location + session.location.setrefgeo(47.57917, -122.13232, 2.0) + session.location.refscale = 150.0 + response_data = jsonify( id=session.session_id, state=session.state, @@ -169,6 +174,10 @@ def get_session(session_id): nodes = [] for node in session.objects.itervalues(): + emane_model = None + if nodeutils.is_node(node, NodeTypes.EMANE): + emane_model = node.model.name + services = [x._name for x in getattr(node, "services", [])] nodes.append({ "id": node.objid, @@ -181,6 +190,7 @@ def get_session(session_id): "z": node.position.z }, "services": services, + "emane": emane_model, "url": "/sessions/%s/nodes/%s" % (session_id, node.objid) }) @@ -190,6 +200,21 @@ def get_session(session_id): ) +@app.route("/sessions//emane") +def get_emane_models(session_id): + session = coreemu.sessions.get(session_id) + if not session: + return jsonify(error="session does not exist"), 404 + + models = [] + for model in session.emane._modelclsmap.keys(): + if len(model.split("_")) != 2: + continue + models.append(model) + + return jsonify(models=models) + + @app.route("/sessions//nodes", methods=["POST"]) @synchronized def create_node(session_id): @@ -213,6 +238,17 @@ def create_node(session_id): node_options.set_position(data.get("x"), data.get("y")) node_options.set_location(data.get("lat"), data.get("lon"), data.get("alt")) node = session.add_node(_type=node_type, _id=node_id, node_options=node_options) + + # configure emane if provided + emane_model = data.get("emane") + if emane_model: + config_data = ConfigData( + node=node_id, + object=emane_model, + type=2 + ) + session.config_object(config_data) + return jsonify( id=node.objid, url="/sessions/%s/nodes/%s" % (session_id, node.objid) @@ -278,10 +314,16 @@ def get_node(session_id, node_id): }) services = [x._name for x in getattr(node, "services", [])] + + emane_model = None + if nodeutils.is_node(node, NodeTypes.EMANE): + emane_model = node.model.name + return jsonify( name=node.name, type=nodeutils.get_node_type(node.__class__).value, services=services, + emane=emane_model, model=node.type, interfaces=interfaces, linksurl="/sessions/%s/nodes/%s/links" % (session_id, node.objid) diff --git a/webapp/static/corenetwork.js b/webapp/static/corenetwork.js index 25e21755..96c4cc08 100644 --- a/webapp/static/corenetwork.js +++ b/webapp/static/corenetwork.js @@ -25,6 +25,12 @@ class NodeHelper { name: 'wlan', display: 'WLAN' }, + // emane + 10: { + name: 'emane', + display: 'EMANE' + }, + // ptp 12: { name: 'ptp', display: 'PTP' @@ -38,16 +44,31 @@ class NodeHelper { mdr: 'static/mdr.svg', switch: 'static/lanswitch.svg', hub: 'static/hub.svg', - wlan: 'static/wlan.svg' + wlan: 'static/wlan.svg', + emane: 'static/wlan.svg' }; this.defaultNode = 0; - this.ptpNode = 12; + this.switchNode = 4; + this.hubNode = 5; this.wlanNode = 6; + this.emaneNode = 10; + this.ptpNode = 12; + this.controlNet = 13; } isNetworkNode(node) { - return [4, 5, 6, 12].includes(node.type); + return [ + this.switchNode, + this.hubNode, + this.wlanNode, + this.emaneNode, + this.ptpNode + ].includes(node.type); + } + + isSkipNode(node) { + return [CoreNodeHelper.ptpNode, CoreNodeHelper.controlNet].includes(node.type); } getDisplay(nodeType) { @@ -82,6 +103,7 @@ class CoreNode { this.emulation_id = null; this.emulation_server = null; this.interfaces = {}; + this.emane = null; } getNetworkNode() { @@ -93,7 +115,6 @@ class CoreNode { y: this.y, label: this.name, coreNode: this, - //color: '#FFF', shape: 'image', image: icon }; @@ -110,7 +131,8 @@ class CoreNode { lat: this.lat, lon: this.lon, alt: this.alt, - services: this.services + services: this.services, + emane: this.emane } } } @@ -194,6 +216,7 @@ class CoreNetwork { const session = await this.coreRest.createSession(); this.coreRest.currentSession = session.id; this.reset(); + toastr.success(`Created ${session.id}`, 'Session'); return session; } @@ -260,6 +283,7 @@ class CoreNetwork { const coreNode = new CoreNode(node.id, node.type, node.name, position.x, position.y); coreNode.model = node.model; coreNode.services = node.services; + coreNode.emane = node.emane; this.nodes.add(coreNode.getNetworkNode()); } @@ -286,7 +310,7 @@ class CoreNetwork { const nodeIds = [0]; for (let node of nodes) { - if (node.type === CoreNodeHelper.ptpNode) { + if (CoreNodeHelper.isSkipNode(node)) { continue; } @@ -319,6 +343,8 @@ class CoreNetwork { this.network.fit(); + toastr.success(`Joined ${sessionId}`, 'Session'); + return { id: sessionId, state: session.state diff --git a/webapp/static/corerest.js b/webapp/static/corerest.js index 85c25d9f..3de0b8f8 100644 --- a/webapp/static/corerest.js +++ b/webapp/static/corerest.js @@ -62,7 +62,11 @@ class CoreRest { } async setSessionState(state) { - return await putJson(`/sessions/${this.currentSession}/state`, {state}) + return await putJson(`/sessions/${this.currentSession}/state`, {state}); + } + + async getEmaneModels() { + return await $.getJSON(`/sessions/${this.currentSession}/emane`); } async createNode(node) { diff --git a/webapp/static/coreui.js b/webapp/static/coreui.js index 4d1e7d5b..45ac6476 100644 --- a/webapp/static/coreui.js +++ b/webapp/static/coreui.js @@ -1,3 +1,32 @@ +function createRadio(name, value, label, checked = false) { + const $formCheck = $('
', {class: 'form-check'}); + const $input = $('', { + class: 'form-check-input', + type: 'radio', + name: name, + checked, + value + }); + const $label = $('