Merge branch 'coretk' of https://github.com/coreemu/core into coretk
|
@ -1,10 +1,8 @@
|
||||||
"""
|
"""
|
||||||
canvas graph action
|
canvas graph action
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# import tkinter as tk
|
|
||||||
|
|
||||||
from core.api.grpc import core_pb2
|
from core.api.grpc import core_pb2
|
||||||
|
from coretk.dialogs.emaneconfig import EmaneConfiguration
|
||||||
from coretk.dialogs.nodeconfig import NodeConfigDialog
|
from coretk.dialogs.nodeconfig import NodeConfigDialog
|
||||||
from coretk.dialogs.wlanconfig import WlanConfigDialog
|
from coretk.dialogs.wlanconfig import WlanConfigDialog
|
||||||
|
|
||||||
|
@ -12,6 +10,7 @@ from coretk.dialogs.wlanconfig import WlanConfigDialog
|
||||||
NODE_TO_TYPE = {
|
NODE_TO_TYPE = {
|
||||||
"router": core_pb2.NodeType.DEFAULT,
|
"router": core_pb2.NodeType.DEFAULT,
|
||||||
"wlan": core_pb2.NodeType.WIRELESS_LAN,
|
"wlan": core_pb2.NodeType.WIRELESS_LAN,
|
||||||
|
"emane": core_pb2.NodeType.EMANE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,6 +27,8 @@ class CanvasAction:
|
||||||
self.display_node_configuration()
|
self.display_node_configuration()
|
||||||
elif pb_type == core_pb2.NodeType.WIRELESS_LAN:
|
elif pb_type == core_pb2.NodeType.WIRELESS_LAN:
|
||||||
self.display_wlan_configuration(canvas_node)
|
self.display_wlan_configuration(canvas_node)
|
||||||
|
elif pb_type == core_pb2.NodeType.EMANE:
|
||||||
|
self.display_emane_configuration()
|
||||||
|
|
||||||
def display_node_configuration(self):
|
def display_node_configuration(self):
|
||||||
dialog = NodeConfigDialog(self.master, self.master, self.node_to_show_config)
|
dialog = NodeConfigDialog(self.master, self.master, self.node_to_show_config)
|
||||||
|
@ -35,6 +36,7 @@ class CanvasAction:
|
||||||
self.node_to_show_config = None
|
self.node_to_show_config = None
|
||||||
|
|
||||||
def display_wlan_configuration(self, canvas_node):
|
def display_wlan_configuration(self, canvas_node):
|
||||||
|
|
||||||
# print(self.canvas.grpc_manager.wlanconfig_management.configurations)
|
# print(self.canvas.grpc_manager.wlanconfig_management.configurations)
|
||||||
wlan_config = self.master.core.wlanconfig_management.configurations[
|
wlan_config = self.master.core.wlanconfig_management.configurations[
|
||||||
canvas_node.core_id
|
canvas_node.core_id
|
||||||
|
@ -44,3 +46,8 @@ class CanvasAction:
|
||||||
)
|
)
|
||||||
dialog.show()
|
dialog.show()
|
||||||
self.node_to_show_config = None
|
self.node_to_show_config = None
|
||||||
|
|
||||||
|
def display_emane_configuration(self):
|
||||||
|
app = self.canvas.core.app
|
||||||
|
dialog = EmaneConfiguration(self.master, app, self.node_to_show_config)
|
||||||
|
dialog.show()
|
||||||
|
|
|
@ -7,6 +7,7 @@ from tkinter import ttk
|
||||||
class ConfigType(enum.Enum):
|
class ConfigType(enum.Enum):
|
||||||
STRING = 10
|
STRING = 10
|
||||||
BOOL = 11
|
BOOL = 11
|
||||||
|
EMANECONFIG = 7
|
||||||
|
|
||||||
|
|
||||||
def create_config(master, config, padx=2, pady=2):
|
def create_config(master, config, padx=2, pady=2):
|
||||||
|
@ -52,8 +53,13 @@ def create_config(master, config, padx=2, pady=2):
|
||||||
else:
|
else:
|
||||||
value.set("Off")
|
value.set("Off")
|
||||||
elif config_type == ConfigType.STRING:
|
elif config_type == ConfigType.STRING:
|
||||||
|
value.set(option.value)
|
||||||
entry = tk.Entry(frame, textvariable=value)
|
entry = tk.Entry(frame, textvariable=value)
|
||||||
entry.grid(row=index, column=1, sticky="ew", pady=pady)
|
entry.grid(row=index, column=1, sticky="ew", pady=pady)
|
||||||
|
elif config_type == ConfigType.EMANECONFIG:
|
||||||
|
value.set(option.value)
|
||||||
|
entry = tk.Entry(frame, textvariable=value, bg="white")
|
||||||
|
entry.grid(row=index, column=1, sticky="ew", pady=pady)
|
||||||
else:
|
else:
|
||||||
logging.error("unhandled config option type: %s", config_type)
|
logging.error("unhandled config option type: %s", config_type)
|
||||||
values[key] = value
|
values[key] = value
|
||||||
|
@ -68,7 +74,6 @@ def create_config(master, config, padx=2, pady=2):
|
||||||
canvas.bind(
|
canvas.bind(
|
||||||
"<Configure>", lambda event: canvas.itemconfig(frame_id, width=event.width)
|
"<Configure>", lambda event: canvas.itemconfig(frame_id, width=event.width)
|
||||||
)
|
)
|
||||||
|
|
||||||
return values
|
return values
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ from core.api.grpc import client, core_pb2
|
||||||
from coretk.coretocanvas import CoreToCanvasMapping
|
from coretk.coretocanvas import CoreToCanvasMapping
|
||||||
from coretk.dialogs.sessions import SessionsDialog
|
from coretk.dialogs.sessions import SessionsDialog
|
||||||
from coretk.interface import Interface, InterfaceManager
|
from coretk.interface import Interface, InterfaceManager
|
||||||
|
from coretk.mobilitynodeconfig import MobilityNodeConfig
|
||||||
from coretk.wlannodeconfig import WlanNodeConfig
|
from coretk.wlannodeconfig import WlanNodeConfig
|
||||||
|
|
||||||
link_layer_nodes = ["switch", "hub", "wlan", "rj45", "tunnel"]
|
link_layer_nodes = ["switch", "hub", "wlan", "rj45", "tunnel"]
|
||||||
|
@ -94,6 +95,8 @@ class CoreClient:
|
||||||
self.interfaces_manager = InterfaceManager()
|
self.interfaces_manager = InterfaceManager()
|
||||||
self.core_mapping = CoreToCanvasMapping()
|
self.core_mapping = CoreToCanvasMapping()
|
||||||
self.wlanconfig_management = WlanNodeConfig()
|
self.wlanconfig_management = WlanNodeConfig()
|
||||||
|
self.mobilityconfig_management = MobilityNodeConfig()
|
||||||
|
self.emane_config = None
|
||||||
|
|
||||||
def handle_events(self, event):
|
def handle_events(self, event):
|
||||||
logging.info("event: %s", event)
|
logging.info("event: %s", event)
|
||||||
|
@ -124,11 +127,15 @@ class CoreClient:
|
||||||
self.nodes.clear()
|
self.nodes.clear()
|
||||||
self.edges.clear()
|
self.edges.clear()
|
||||||
self.hooks.clear()
|
self.hooks.clear()
|
||||||
|
self.wlanconfig_management.configurations.clear()
|
||||||
|
self.mobilityconfig_management.configurations.clear()
|
||||||
|
self.emane_config = None
|
||||||
|
|
||||||
# get session data
|
# get session data
|
||||||
response = self.client.get_session(self.session_id)
|
response = self.client.get_session(self.session_id)
|
||||||
logging.info("joining session(%s): %s", self.session_id, response)
|
logging.info("joining session(%s): %s", self.session_id, response)
|
||||||
session = response.session
|
session = response.session
|
||||||
|
session_state = session.state
|
||||||
self.client.events(self.session_id, self.handle_events)
|
self.client.events(self.session_id, self.handle_events)
|
||||||
|
|
||||||
# get hooks
|
# get hooks
|
||||||
|
@ -137,6 +144,28 @@ class CoreClient:
|
||||||
for hook in response.hooks:
|
for hook in response.hooks:
|
||||||
self.hooks[hook.file] = hook
|
self.hooks[hook.file] = hook
|
||||||
|
|
||||||
|
# get wlan configs
|
||||||
|
for node in session.nodes:
|
||||||
|
if node.type == core_pb2.NodeType.WIRELESS_LAN:
|
||||||
|
response = self.client.get_wlan_config(self.session_id, node.id)
|
||||||
|
logging.info("wlan config(%s): %s", node.id, response)
|
||||||
|
node_config = response.config
|
||||||
|
config = {x: node_config[x].value for x in node_config}
|
||||||
|
self.wlanconfig_management.configurations[node.id] = config
|
||||||
|
|
||||||
|
# get mobility configs
|
||||||
|
response = self.client.get_mobility_configs(self.session_id)
|
||||||
|
logging.info("mobility configs: %s", response)
|
||||||
|
for node_id in response.configs:
|
||||||
|
node_config = response.configs[node_id].config
|
||||||
|
config = {x: node_config[x].value for x in node_config}
|
||||||
|
self.mobilityconfig_management.configurations[node_id] = config
|
||||||
|
|
||||||
|
# get emane config
|
||||||
|
response = self.client.get_emane_config(self.session_id)
|
||||||
|
logging.info("emane config: %s", response)
|
||||||
|
self.emane_config = response.config
|
||||||
|
|
||||||
# determine next node id and reusable nodes
|
# determine next node id and reusable nodes
|
||||||
max_id = 1
|
max_id = 1
|
||||||
for node in session.nodes:
|
for node in session.nodes:
|
||||||
|
@ -151,6 +180,14 @@ class CoreClient:
|
||||||
# draw session
|
# draw session
|
||||||
self.app.canvas.canvas_reset_and_redraw(session)
|
self.app.canvas.canvas_reset_and_redraw(session)
|
||||||
|
|
||||||
|
# draw tool bar appropritate with session state
|
||||||
|
if session_state == core_pb2.SessionState.RUNTIME:
|
||||||
|
self.app.core_editbar.destroy_children_widgets()
|
||||||
|
self.app.core_editbar.create_runtime_toolbar()
|
||||||
|
else:
|
||||||
|
self.app.core_editbar.destroy_children_widgets()
|
||||||
|
self.app.core_editbar.create_toolbar()
|
||||||
|
|
||||||
def create_new_session(self):
|
def create_new_session(self):
|
||||||
"""
|
"""
|
||||||
Create a new session
|
Create a new session
|
||||||
|
@ -302,6 +339,7 @@ class CoreClient:
|
||||||
links,
|
links,
|
||||||
hooks=list(self.hooks.values()),
|
hooks=list(self.hooks.values()),
|
||||||
wlan_configs=wlan_configs,
|
wlan_configs=wlan_configs,
|
||||||
|
emane_config=emane_config,
|
||||||
)
|
)
|
||||||
logging.debug("Start session %s, result: %s", self.session_id, response.result)
|
logging.debug("Start session %s, result: %s", self.session_id, response.result)
|
||||||
|
|
||||||
|
@ -439,6 +477,8 @@ class CoreClient:
|
||||||
# set default configuration for wireless node
|
# set default configuration for wireless node
|
||||||
self.wlanconfig_management.set_default_config(node_type, nid)
|
self.wlanconfig_management.set_default_config(node_type, nid)
|
||||||
|
|
||||||
|
self.mobilityconfig_management.set_default_configuration(node_type, nid)
|
||||||
|
|
||||||
self.nodes[canvas_id] = create_node
|
self.nodes[canvas_id] = create_node
|
||||||
self.core_mapping.map_core_id_to_canvas_id(nid, canvas_id)
|
self.core_mapping.map_core_id_to_canvas_id(nid, canvas_id)
|
||||||
# self.core_id_to_canvas_id[nid] = canvas_id
|
# self.core_id_to_canvas_id[nid] = canvas_id
|
||||||
|
@ -543,7 +583,7 @@ class CoreClient:
|
||||||
"""
|
"""
|
||||||
Create the interface for the two end of an edge, add a copy to node's interfaces
|
Create the interface for the two end of an edge, add a copy to node's interfaces
|
||||||
|
|
||||||
:param coretk.grpcmanagement.Edge edge: edge to add interfaces to
|
:param coretk.coreclient.Edge edge: edge to add interfaces to
|
||||||
:param int src_canvas_id: canvas id for the source node
|
:param int src_canvas_id: canvas id for the source node
|
||||||
:param int dst_canvas_id: canvas id for the destination node
|
:param int dst_canvas_id: canvas id for the destination node
|
||||||
:return: nothing
|
:return: nothing
|
||||||
|
|
|
@ -357,9 +357,9 @@ class CoreToolbar(object):
|
||||||
|
|
||||||
def pick_emane(self, main_button):
|
def pick_emane(self, main_button):
|
||||||
self.link_layer_option_menu.destroy()
|
self.link_layer_option_menu.destroy()
|
||||||
main_button.configure(image=Images.get(ImageEnum.EMANE.value))
|
main_button.configure(image=Images.get(ImageEnum.EMANE))
|
||||||
self.canvas.mode = GraphMode.PICKNODE
|
self.canvas.mode = GraphMode.PICKNODE
|
||||||
self.canvas.draw_node_image = Images.get(ImageEnum.EMANE.value)
|
self.canvas.draw_node_image = Images.get(ImageEnum.EMANE)
|
||||||
self.canvas.draw_node_name = "emane"
|
self.canvas.draw_node_name = "emane"
|
||||||
|
|
||||||
def draw_link_layer_options(self, link_layer_button):
|
def draw_link_layer_options(self, link_layer_button):
|
||||||
|
|
|
@ -35,17 +35,17 @@ class CoreToolbarHelp:
|
||||||
interface_one = self.app.core.create_interface(edge.type1, edge.interface_1)
|
interface_one = self.app.core.create_interface(edge.type1, edge.interface_1)
|
||||||
interface_two = self.app.core.create_interface(edge.type2, edge.interface_2)
|
interface_two = self.app.core.create_interface(edge.type2, edge.interface_2)
|
||||||
# TODO for now only consider the basic cases
|
# TODO for now only consider the basic cases
|
||||||
if (
|
# if (
|
||||||
edge.type1 == core_pb2.NodeType.WIRELESS_LAN
|
# edge.type1 == core_pb2.NodeType.WIRELESS_LAN
|
||||||
or edge.type2 == core_pb2.NodeType.WIRELESS_LAN
|
# or edge.type2 == core_pb2.NodeType.WIRELESS_LAN
|
||||||
):
|
# ):
|
||||||
link_type = core_pb2.LinkType.WIRELESS
|
# link_type = core_pb2.LinkType.WIRELESS
|
||||||
else:
|
# else:
|
||||||
link_type = core_pb2.LinkType.WIRED
|
# link_type = core_pb2.LinkType.WIRED
|
||||||
link = core_pb2.Link(
|
link = core_pb2.Link(
|
||||||
node_one_id=edge.id1,
|
node_one_id=edge.id1,
|
||||||
node_two_id=edge.id2,
|
node_two_id=edge.id2,
|
||||||
type=link_type,
|
type=core_pb2.LinkType.WIRED,
|
||||||
interface_one=interface_one,
|
interface_one=interface_one,
|
||||||
interface_two=interface_two,
|
interface_two=interface_two,
|
||||||
)
|
)
|
||||||
|
@ -54,6 +54,11 @@ class CoreToolbarHelp:
|
||||||
return links
|
return links
|
||||||
|
|
||||||
def get_wlan_configuration_list(self):
|
def get_wlan_configuration_list(self):
|
||||||
|
"""
|
||||||
|
form a list of wlan configuration to pass to start_session
|
||||||
|
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
configs = []
|
configs = []
|
||||||
manager_configs = self.app.core.wlanconfig_management.configurations
|
manager_configs = self.app.core.wlanconfig_management.configurations
|
||||||
for key in manager_configs:
|
for key in manager_configs:
|
||||||
|
@ -61,8 +66,34 @@ class CoreToolbarHelp:
|
||||||
configs.append(cnf)
|
configs.append(cnf)
|
||||||
return configs
|
return configs
|
||||||
|
|
||||||
|
def get_mobility_configuration_list(self):
|
||||||
|
"""
|
||||||
|
form a list of mobility configuration to pass to start_session
|
||||||
|
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
configs = []
|
||||||
|
core = self.app.canvas.core
|
||||||
|
manager_configs = core.mobilityconfig_management.configurations
|
||||||
|
for key in manager_configs:
|
||||||
|
cnf = core_pb2.MobilityConfig(node_id=key, config=manager_configs[key])
|
||||||
|
configs.append(cnf)
|
||||||
|
return configs
|
||||||
|
|
||||||
def gui_start_session(self):
|
def gui_start_session(self):
|
||||||
nodes = self.get_node_list()
|
nodes = self.get_node_list()
|
||||||
links = self.get_link_list()
|
links = self.get_link_list()
|
||||||
wlan_configs = self.get_wlan_configuration_list()
|
wlan_configs = self.get_wlan_configuration_list()
|
||||||
self.app.core.start_session(nodes, links, wlan_configs=wlan_configs)
|
mobility_configs = self.get_mobility_configuration_list()
|
||||||
|
|
||||||
|
# get emane config
|
||||||
|
pb_emane_config = self.app.core.emane_config
|
||||||
|
emane_config = {x: pb_emane_config[x].value for x in pb_emane_config}
|
||||||
|
|
||||||
|
self.app.core.start_session(
|
||||||
|
nodes,
|
||||||
|
links,
|
||||||
|
wlan_configs=wlan_configs,
|
||||||
|
mobility_configs=mobility_configs,
|
||||||
|
emane_config=emane_config,
|
||||||
|
)
|
||||||
|
|
340
coretk/coretk/dialogs/emaneconfig.py
Normal file
|
@ -0,0 +1,340 @@
|
||||||
|
"""
|
||||||
|
emane configuration
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import tkinter as tk
|
||||||
|
import webbrowser
|
||||||
|
from tkinter import ttk
|
||||||
|
|
||||||
|
from coretk import configutils
|
||||||
|
from coretk.dialogs.dialog import Dialog
|
||||||
|
from coretk.images import ImageEnum, Images
|
||||||
|
|
||||||
|
PAD_X = 2
|
||||||
|
PAD_Y = 2
|
||||||
|
|
||||||
|
|
||||||
|
class EmaneConfiguration(Dialog):
|
||||||
|
def __init__(self, master, app, canvas_node):
|
||||||
|
super().__init__(master, app, "emane configuration", modal=False)
|
||||||
|
self.app = app
|
||||||
|
self.canvas_node = canvas_node
|
||||||
|
self.radiovar = tk.IntVar()
|
||||||
|
self.radiovar.set(1)
|
||||||
|
self.columnconfigure(0, weight=1)
|
||||||
|
|
||||||
|
# list(string) of emane models
|
||||||
|
self.emane_models = None
|
||||||
|
|
||||||
|
self.emane_dialog = Dialog(self, app, "emane configuration", modal=False)
|
||||||
|
self.emane_model_dialog = None
|
||||||
|
self.emane_model_combobox = None
|
||||||
|
|
||||||
|
# draw
|
||||||
|
self.node_name_and_image()
|
||||||
|
self.emane_configuration()
|
||||||
|
self.draw_ip_subnets()
|
||||||
|
self.emane_options()
|
||||||
|
self.draw_apply_and_cancel()
|
||||||
|
|
||||||
|
self.values = None
|
||||||
|
self.options = app.core.emane_config
|
||||||
|
self.model_options = None
|
||||||
|
self.model_values = None
|
||||||
|
|
||||||
|
def create_text_variable(self, val):
|
||||||
|
"""
|
||||||
|
create a string variable for convenience
|
||||||
|
|
||||||
|
:param str val: entry text
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
var = tk.StringVar()
|
||||||
|
var.set(val)
|
||||||
|
return var
|
||||||
|
|
||||||
|
def choose_core(self):
|
||||||
|
print("not implemented")
|
||||||
|
|
||||||
|
def node_name_and_image(self):
|
||||||
|
f = tk.Frame(self, bg="#d9d9d9")
|
||||||
|
|
||||||
|
lbl = tk.Label(f, text="Node name:", bg="#d9d9d9")
|
||||||
|
lbl.grid(row=0, column=0, padx=2, pady=2)
|
||||||
|
e = tk.Entry(f, textvariable=self.create_text_variable(""), bg="white")
|
||||||
|
e.grid(row=0, column=1, padx=2, pady=2)
|
||||||
|
|
||||||
|
cbb = ttk.Combobox(f, values=["(none)", "core1", "core2"], state="readonly")
|
||||||
|
cbb.current(0)
|
||||||
|
cbb.grid(row=0, column=2, padx=2, pady=2)
|
||||||
|
|
||||||
|
b = tk.Button(f, image=self.canvas_node.image)
|
||||||
|
b.grid(row=0, column=3, padx=2, pady=2)
|
||||||
|
|
||||||
|
f.grid(row=0, column=0, sticky="nsew")
|
||||||
|
|
||||||
|
def save_emane_option(self):
|
||||||
|
configutils.parse_config(self.options, self.values)
|
||||||
|
self.emane_dialog.destroy()
|
||||||
|
|
||||||
|
def draw_emane_options(self):
|
||||||
|
if not self.emane_dialog.winfo_exists():
|
||||||
|
self.emane_dialog = Dialog(
|
||||||
|
self, self.app, "emane configuration", modal=False
|
||||||
|
)
|
||||||
|
b1 = tk.Button(self.emane_dialog, text="Appy", command=self.save_emane_option)
|
||||||
|
b2 = tk.Button(
|
||||||
|
self.emane_dialog, text="Cancel", command=self.emane_dialog.destroy
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.options is None:
|
||||||
|
session_id = self.app.core.session_id
|
||||||
|
response = self.app.core.client.get_emane_config(session_id)
|
||||||
|
logging.info("emane config: %s", response)
|
||||||
|
self.options = response.config
|
||||||
|
self.values = configutils.create_config(
|
||||||
|
self.emane_dialog, self.options, PAD_X, PAD_Y
|
||||||
|
)
|
||||||
|
b1.grid(row=1, column=0)
|
||||||
|
b2.grid(row=1, column=1)
|
||||||
|
self.emane_dialog.show()
|
||||||
|
|
||||||
|
def save_emane_model_options(self):
|
||||||
|
"""
|
||||||
|
configure the node's emane model on the fly
|
||||||
|
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
# get model name
|
||||||
|
model_name = self.emane_models[self.emane_model_combobox.current()]
|
||||||
|
|
||||||
|
# parse configuration
|
||||||
|
configutils.parse_config(self.model_options, self.model_values)
|
||||||
|
config = {x: self.model_options[x].value for x in self.model_options}
|
||||||
|
|
||||||
|
# add string emane_ infront for grpc call
|
||||||
|
response = self.app.core.client.set_emane_model_config(
|
||||||
|
self.app.core.session_id,
|
||||||
|
self.canvas_node.core_id,
|
||||||
|
"emane_" + model_name,
|
||||||
|
config,
|
||||||
|
)
|
||||||
|
logging.info(
|
||||||
|
"emaneconfig.py config emane model (%s), result: %s",
|
||||||
|
self.canvas_node.core_id,
|
||||||
|
response,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.emane_model_dialog.destroy()
|
||||||
|
|
||||||
|
def draw_model_options(self):
|
||||||
|
"""
|
||||||
|
draw emane model configuration
|
||||||
|
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
# get model name
|
||||||
|
model_name = self.emane_models[self.emane_model_combobox.current()]
|
||||||
|
|
||||||
|
# create the dialog and the necessry widget
|
||||||
|
if not self.emane_model_dialog or not self.emane_model_dialog.winfo_exists():
|
||||||
|
self.emane_model_dialog = Dialog(
|
||||||
|
self, self.app, model_name + " configuration", modal=False
|
||||||
|
)
|
||||||
|
|
||||||
|
b1 = tk.Button(
|
||||||
|
self.emane_model_dialog, text="Apply", command=self.save_emane_model_options
|
||||||
|
)
|
||||||
|
b2 = tk.Button(
|
||||||
|
self.emane_model_dialog,
|
||||||
|
text="Cancel",
|
||||||
|
command=self.emane_model_dialog.destroy,
|
||||||
|
)
|
||||||
|
|
||||||
|
# query for configurations
|
||||||
|
session_id = self.app.core.session_id
|
||||||
|
# add string emane_ before model name for grpc call
|
||||||
|
response = self.app.core.client.get_emane_model_config(
|
||||||
|
session_id, self.canvas_node.core_id, "emane_" + model_name
|
||||||
|
)
|
||||||
|
logging.info("emane model config %s", response)
|
||||||
|
|
||||||
|
self.model_options = response.config
|
||||||
|
self.model_values = configutils.create_config(
|
||||||
|
self.emane_model_dialog, self.model_options, PAD_X, PAD_Y
|
||||||
|
)
|
||||||
|
|
||||||
|
b1.grid(row=1, column=0, sticky="nsew")
|
||||||
|
b2.grid(row=1, column=1, sticky="nsew")
|
||||||
|
self.emane_model_dialog.show()
|
||||||
|
|
||||||
|
def draw_option_buttons(self, parent):
|
||||||
|
f = tk.Frame(parent, bg="#d9d9d9")
|
||||||
|
f.columnconfigure(0, weight=1)
|
||||||
|
f.columnconfigure(1, weight=1)
|
||||||
|
b = tk.Button(
|
||||||
|
f,
|
||||||
|
text=self.emane_models[0] + " options",
|
||||||
|
image=Images.get(ImageEnum.EDITNODE),
|
||||||
|
compound=tk.RIGHT,
|
||||||
|
bg="#d9d9d9",
|
||||||
|
command=self.draw_model_options,
|
||||||
|
)
|
||||||
|
b.grid(row=0, column=0, padx=10, pady=2, sticky="nsew")
|
||||||
|
b = tk.Button(
|
||||||
|
f,
|
||||||
|
text="EMANE options",
|
||||||
|
image=Images.get(ImageEnum.EDITNODE),
|
||||||
|
compound=tk.RIGHT,
|
||||||
|
bg="#d9d9d9",
|
||||||
|
command=self.draw_emane_options,
|
||||||
|
)
|
||||||
|
b.grid(row=0, column=1, padx=10, pady=2, sticky="nsew")
|
||||||
|
f.grid(row=4, column=0, sticky="nsew")
|
||||||
|
|
||||||
|
def combobox_select(self, event):
|
||||||
|
"""
|
||||||
|
update emane model options button
|
||||||
|
|
||||||
|
:param event:
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
# get model name
|
||||||
|
model_name = self.emane_models[self.emane_model_combobox.current()]
|
||||||
|
|
||||||
|
# get the button and configure button text
|
||||||
|
config_frame = self.grid_slaves(row=2, column=0)[0]
|
||||||
|
option_button_frame = config_frame.grid_slaves(row=4, column=0)[0]
|
||||||
|
b = option_button_frame.grid_slaves(row=0, column=0)[0]
|
||||||
|
b.config(text=model_name + " options")
|
||||||
|
|
||||||
|
def draw_emane_models(self, parent):
|
||||||
|
"""
|
||||||
|
create a combobox that has all the known emane models
|
||||||
|
|
||||||
|
:param parent: parent
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
# query for all the known model names
|
||||||
|
session_id = self.app.core.session_id
|
||||||
|
response = self.app.core.client.get_emane_models(session_id)
|
||||||
|
self.emane_models = [x.split("_")[1] for x in response.models]
|
||||||
|
|
||||||
|
# create combo box and its binding
|
||||||
|
f = tk.Frame(
|
||||||
|
parent,
|
||||||
|
bg="#d9d9d9",
|
||||||
|
highlightbackground="#b3b3b3",
|
||||||
|
highlightcolor="#b3b3b3",
|
||||||
|
highlightthickness=0.5,
|
||||||
|
bd=0,
|
||||||
|
)
|
||||||
|
self.emane_model_combobox = ttk.Combobox(
|
||||||
|
f, values=self.emane_models, state="readonly"
|
||||||
|
)
|
||||||
|
self.emane_model_combobox.grid()
|
||||||
|
self.emane_model_combobox.current(0)
|
||||||
|
self.emane_model_combobox.bind("<<ComboboxSelected>>", self.combobox_select)
|
||||||
|
f.grid(row=3, column=0, sticky=tk.W + tk.E)
|
||||||
|
|
||||||
|
def draw_text_label_and_entry(self, parent, label_text, entry_text):
|
||||||
|
"""
|
||||||
|
draw a label and an entry on a single row
|
||||||
|
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
var = tk.StringVar()
|
||||||
|
var.set(entry_text)
|
||||||
|
f = tk.Frame(parent)
|
||||||
|
lbl = tk.Label(f, text=label_text)
|
||||||
|
lbl.grid(row=0, column=0)
|
||||||
|
e = tk.Entry(f, textvariable=var, bg="white")
|
||||||
|
e.grid(row=0, column=1)
|
||||||
|
f.grid(stick=tk.W, padx=2, pady=2)
|
||||||
|
|
||||||
|
def emane_configuration(self):
|
||||||
|
"""
|
||||||
|
draw the main frame for emane configuration
|
||||||
|
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
# draw label
|
||||||
|
lbl = tk.Label(self, text="Emane")
|
||||||
|
lbl.grid(row=1, column=0)
|
||||||
|
|
||||||
|
# main frame that has emane wiki, a short description, emane models and the configure buttons
|
||||||
|
f = tk.Frame(
|
||||||
|
self,
|
||||||
|
bg="#d9d9d9",
|
||||||
|
highlightbackground="#b3b3b3",
|
||||||
|
highlightcolor="#b3b3b3",
|
||||||
|
highlightthickness=0.5,
|
||||||
|
bd=0,
|
||||||
|
relief=tk.RAISED,
|
||||||
|
)
|
||||||
|
f.columnconfigure(0, weight=1)
|
||||||
|
|
||||||
|
b = tk.Button(
|
||||||
|
f,
|
||||||
|
image=Images.get(ImageEnum.EDITNODE),
|
||||||
|
text="EMANE Wiki",
|
||||||
|
compound=tk.RIGHT,
|
||||||
|
relief=tk.RAISED,
|
||||||
|
bg="#d9d9d9",
|
||||||
|
command=lambda: webbrowser.open_new(
|
||||||
|
"https://github.com/adjacentlink/emane/wiki"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
b.grid(row=0, column=0, sticky=tk.W)
|
||||||
|
|
||||||
|
lbl = tk.Label(
|
||||||
|
f,
|
||||||
|
text="The EMANE emulation system provides more complex wireless radio emulation "
|
||||||
|
"\nusing pluggable MAC and PHY modules. Refer to the wiki for configuration option details",
|
||||||
|
bg="#d9d9d9",
|
||||||
|
)
|
||||||
|
lbl.grid(row=1, column=0, sticky="nsew")
|
||||||
|
|
||||||
|
lbl = tk.Label(f, text="EMANE Models", bg="#d9d9d9")
|
||||||
|
lbl.grid(row=2, column=0, sticky=tk.W)
|
||||||
|
|
||||||
|
self.draw_emane_models(f)
|
||||||
|
self.draw_option_buttons(f)
|
||||||
|
|
||||||
|
f.grid(row=2, column=0, sticky="nsew")
|
||||||
|
|
||||||
|
def draw_ip_subnets(self):
|
||||||
|
self.draw_text_label_and_entry(self, "IPv4 subnet", "")
|
||||||
|
self.draw_text_label_and_entry(self, "IPv6 subnet", "")
|
||||||
|
|
||||||
|
def emane_options(self):
|
||||||
|
"""
|
||||||
|
create wireless node options
|
||||||
|
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
f = tk.Frame(self, bg="#d9d9d9")
|
||||||
|
f.columnconfigure(0, weight=1)
|
||||||
|
f.columnconfigure(1, weight=1)
|
||||||
|
b = tk.Button(f, text="Link to all routers", bg="#d9d9d9")
|
||||||
|
b.grid(row=0, column=0, padx=10, pady=2, sticky="nsew")
|
||||||
|
b = tk.Button(f, text="Choose WLAN members", bg="#d9d9d9")
|
||||||
|
b.grid(row=0, column=1, padx=10, pady=2, sticky="nsew")
|
||||||
|
f.grid(row=5, column=0, sticky="nsew")
|
||||||
|
|
||||||
|
def apply(self):
|
||||||
|
# save emane configuration
|
||||||
|
self.app.core.emane_config = self.options
|
||||||
|
self.destroy()
|
||||||
|
|
||||||
|
def draw_apply_and_cancel(self):
|
||||||
|
f = tk.Frame(self, bg="#d9d9d9")
|
||||||
|
f.columnconfigure(0, weight=1)
|
||||||
|
f.columnconfigure(1, weight=1)
|
||||||
|
b = tk.Button(f, text="Apply", bg="#d9d9d9", command=self.apply)
|
||||||
|
b.grid(row=0, column=0, padx=10, pady=2, sticky="nsew")
|
||||||
|
b = tk.Button(f, text="Cancel", bg="#d9d9d9", command=self.destroy)
|
||||||
|
b.grid(row=0, column=1, padx=10, pady=2, sticky="nsew")
|
||||||
|
|
||||||
|
f.grid(sticky="nsew")
|
238
coretk/coretk/dialogs/mobilityconfig.py
Normal file
|
@ -0,0 +1,238 @@
|
||||||
|
"""
|
||||||
|
mobility configuration
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import tkinter as tk
|
||||||
|
from pathlib import Path
|
||||||
|
from tkinter import filedialog
|
||||||
|
|
||||||
|
from coretk.dialogs.dialog import Dialog
|
||||||
|
|
||||||
|
|
||||||
|
class MobilityConfiguration(Dialog):
|
||||||
|
def __init__(self, master, app, canvas_node):
|
||||||
|
"""
|
||||||
|
create an instance of mobility configuration
|
||||||
|
|
||||||
|
:param app: core application
|
||||||
|
:param root.master master:
|
||||||
|
"""
|
||||||
|
super().__init__(master, app, "ns2script configuration", modal=True)
|
||||||
|
self.canvas_node = canvas_node
|
||||||
|
print(app.canvas.core.mobilityconfig_management.configurations)
|
||||||
|
self.node_config = app.canvas.core.mobilityconfig_management.configurations[
|
||||||
|
canvas_node.core_id
|
||||||
|
]
|
||||||
|
|
||||||
|
self.mobility_script_parameters()
|
||||||
|
self.ns2script_options()
|
||||||
|
self.loop = "On"
|
||||||
|
|
||||||
|
def create_string_var(self, val):
|
||||||
|
"""
|
||||||
|
create string variable for entry widget
|
||||||
|
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
var = tk.StringVar()
|
||||||
|
var.set(val)
|
||||||
|
return var
|
||||||
|
|
||||||
|
def open_file(self, entry):
|
||||||
|
configs_dir = os.path.join(Path.home(), ".core/configs")
|
||||||
|
if os.path.isdir(configs_dir):
|
||||||
|
filename = filedialog.askopenfilename(initialdir=configs_dir, title="Open")
|
||||||
|
if filename:
|
||||||
|
entry.delete(0, tk.END)
|
||||||
|
entry.insert(0, filename)
|
||||||
|
|
||||||
|
def set_loop_value(self, value):
|
||||||
|
"""
|
||||||
|
set loop value when user changes the option
|
||||||
|
:param value:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
self.loop = value
|
||||||
|
|
||||||
|
def create_label_entry_filebrowser(
|
||||||
|
self, parent_frame, text_label, entry_text, filebrowser=False
|
||||||
|
):
|
||||||
|
f = tk.Frame(parent_frame, bg="#d9d9d9")
|
||||||
|
lbl = tk.Label(f, text=text_label, bg="#d9d9d9")
|
||||||
|
lbl.grid(padx=3, pady=3)
|
||||||
|
# f.grid()
|
||||||
|
e = tk.Entry(f, textvariable=self.create_string_var(entry_text), bg="#ffffff")
|
||||||
|
e.grid(row=0, column=1, padx=3, pady=3)
|
||||||
|
if filebrowser:
|
||||||
|
b = tk.Button(f, text="...", command=lambda: self.open_file(e))
|
||||||
|
b.grid(row=0, column=2, padx=3, pady=3)
|
||||||
|
f.grid(sticky=tk.E)
|
||||||
|
|
||||||
|
def mobility_script_parameters(self):
|
||||||
|
lbl = tk.Label(self, text="node ns2script")
|
||||||
|
lbl.grid(sticky=tk.W + tk.E)
|
||||||
|
|
||||||
|
sb = tk.Scrollbar(self, orient=tk.VERTICAL)
|
||||||
|
sb.grid(row=1, column=1, sticky=tk.N + tk.S + tk.E)
|
||||||
|
|
||||||
|
f = tk.Frame(self, bg="#d9d9d9")
|
||||||
|
lbl = tk.Label(
|
||||||
|
f, text="ns-2 Mobility Scripts Parameters", bg="#d9d9d9", relief=tk.RAISED
|
||||||
|
)
|
||||||
|
lbl.grid(row=0, column=0, sticky=tk.W)
|
||||||
|
|
||||||
|
f1 = tk.Canvas(
|
||||||
|
f,
|
||||||
|
yscrollcommand=sb.set,
|
||||||
|
bg="#d9d9d9",
|
||||||
|
relief=tk.RAISED,
|
||||||
|
highlightbackground="#b3b3b3",
|
||||||
|
highlightcolor="#b3b3b3",
|
||||||
|
highlightthickness=0.5,
|
||||||
|
bd=0,
|
||||||
|
)
|
||||||
|
self.create_label_entry_filebrowser(
|
||||||
|
f1, "mobility script file", self.node_config["file"], filebrowser=True
|
||||||
|
)
|
||||||
|
self.create_label_entry_filebrowser(
|
||||||
|
f1, "Refresh time (ms)", self.node_config["refresh_ms"]
|
||||||
|
)
|
||||||
|
|
||||||
|
# f12 = tk.Frame(f1)
|
||||||
|
#
|
||||||
|
# lbl = tk.Label(f12, text="Refresh time (ms)")
|
||||||
|
# lbl.grid()
|
||||||
|
#
|
||||||
|
# e = tk.Entry(f12, textvariable=self.create_string_var("50"))
|
||||||
|
# e.grid(row=0, column=1)
|
||||||
|
# f12.grid()
|
||||||
|
|
||||||
|
f13 = tk.Frame(f1)
|
||||||
|
|
||||||
|
lbl = tk.Label(f13, text="loop")
|
||||||
|
lbl.grid()
|
||||||
|
|
||||||
|
om = tk.OptionMenu(
|
||||||
|
f13, self.create_string_var("On"), "On", "Off", command=self.set_loop_value
|
||||||
|
)
|
||||||
|
om.grid(row=0, column=1)
|
||||||
|
|
||||||
|
f13.grid(sticky=tk.E)
|
||||||
|
|
||||||
|
self.create_label_entry_filebrowser(
|
||||||
|
f1, "auto-start seconds (0.0 for runtime)", self.node_config["autostart"]
|
||||||
|
)
|
||||||
|
# f14 = tk.Frame(f1)
|
||||||
|
#
|
||||||
|
# lbl = tk.Label(f14, text="auto-start seconds (0.0 for runtime)")
|
||||||
|
# lbl.grid()
|
||||||
|
#
|
||||||
|
# e = tk.Entry(f14, textvariable=self.create_string_var(""))
|
||||||
|
# e.grid(row=0, column=1)
|
||||||
|
#
|
||||||
|
# f14.grid()
|
||||||
|
self.create_label_entry_filebrowser(
|
||||||
|
f1, "node mapping (optional, e.g. 0:1, 1:2, 2:3)", self.node_config["map"]
|
||||||
|
)
|
||||||
|
# f15 = tk.Frame(f1)
|
||||||
|
#
|
||||||
|
# lbl = tk.Label(f15, text="node mapping (optional, e.g. 0:1, 1:2, 2:3)")
|
||||||
|
# lbl.grid()
|
||||||
|
#
|
||||||
|
# e = tk.Entry(f15, textvariable=self.create_string_var(""))
|
||||||
|
# e.grid(row=0, column=1)
|
||||||
|
#
|
||||||
|
# f15.grid()
|
||||||
|
|
||||||
|
self.create_label_entry_filebrowser(
|
||||||
|
f1,
|
||||||
|
"script file to run upon start",
|
||||||
|
self.node_config["script_start"],
|
||||||
|
filebrowser=True,
|
||||||
|
)
|
||||||
|
self.create_label_entry_filebrowser(
|
||||||
|
f1,
|
||||||
|
"script file to run upon pause",
|
||||||
|
self.node_config["script_pause"],
|
||||||
|
filebrowser=True,
|
||||||
|
)
|
||||||
|
self.create_label_entry_filebrowser(
|
||||||
|
f1,
|
||||||
|
"script file to run upon stop",
|
||||||
|
self.node_config["script_stop"],
|
||||||
|
filebrowser=True,
|
||||||
|
)
|
||||||
|
f1.grid()
|
||||||
|
sb.config(command=f1.yview)
|
||||||
|
f.grid(row=1, column=0)
|
||||||
|
|
||||||
|
def ns2script_apply(self):
|
||||||
|
"""
|
||||||
|
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
config_frame = self.grid_slaves(row=1, column=0)[0]
|
||||||
|
canvas = config_frame.grid_slaves(row=1, column=0)[0]
|
||||||
|
file = (
|
||||||
|
canvas.grid_slaves(row=0, column=0)[0].grid_slaves(row=0, column=1)[0].get()
|
||||||
|
)
|
||||||
|
|
||||||
|
refresh_time = (
|
||||||
|
canvas.grid_slaves(row=1, column=0)[0].grid_slaves(row=0, column=1)[0].get()
|
||||||
|
)
|
||||||
|
auto_start_seconds = (
|
||||||
|
canvas.grid_slaves(row=3, column=0)[0].grid_slaves(row=0, column=1)[0].get()
|
||||||
|
)
|
||||||
|
|
||||||
|
node_mapping = (
|
||||||
|
canvas.grid_slaves(row=4, column=0)[0].grid_slaves(row=0, column=1)[0].get()
|
||||||
|
)
|
||||||
|
|
||||||
|
file_upon_start = (
|
||||||
|
canvas.grid_slaves(row=5, column=0)[0].grid_slaves(row=0, column=1)[0].get()
|
||||||
|
)
|
||||||
|
file_upon_pause = (
|
||||||
|
canvas.grid_slaves(row=6, column=0)[0].grid_slaves(row=0, column=1)[0].get()
|
||||||
|
)
|
||||||
|
file_upon_stop = (
|
||||||
|
canvas.grid_slaves(row=7, column=0)[0].grid_slaves(row=0, column=1)[0].get()
|
||||||
|
)
|
||||||
|
|
||||||
|
# print("mobility script file: ", file)
|
||||||
|
# print("refresh time: ", refresh_time)
|
||||||
|
# print("auto start seconds: ", auto_start_seconds)
|
||||||
|
# print("node mapping: ", node_mapping)
|
||||||
|
# print("script file to run upon start: ", file_upon_start)
|
||||||
|
# print("file upon pause: ", file_upon_pause)
|
||||||
|
# print("file upon stop: ", file_upon_stop)
|
||||||
|
if self.loop == "On":
|
||||||
|
loop = "1"
|
||||||
|
else:
|
||||||
|
loop = "0"
|
||||||
|
self.app.canvas.core.mobilityconfig_management.set_custom_configuration(
|
||||||
|
node_id=self.canvas_node.core_id,
|
||||||
|
file=file,
|
||||||
|
refresh_ms=refresh_time,
|
||||||
|
loop=loop,
|
||||||
|
autostart=auto_start_seconds,
|
||||||
|
node_mapping=node_mapping,
|
||||||
|
script_start=file_upon_start,
|
||||||
|
script_pause=file_upon_pause,
|
||||||
|
script_stop=file_upon_stop,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.destroy()
|
||||||
|
|
||||||
|
def ns2script_options(self):
|
||||||
|
"""
|
||||||
|
create the options for ns2script configuration
|
||||||
|
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
f = tk.Frame(self)
|
||||||
|
b = tk.Button(f, text="Apply", command=self.ns2script_apply)
|
||||||
|
b.grid()
|
||||||
|
b = tk.Button(f, text="Cancel", command=self.destroy)
|
||||||
|
b.grid(row=0, column=1)
|
||||||
|
f.grid()
|
|
@ -22,6 +22,7 @@ class WlanConfigDialog(Dialog):
|
||||||
self.image = canvas_node.image
|
self.image = canvas_node.image
|
||||||
self.canvas_node = canvas_node
|
self.canvas_node = canvas_node
|
||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
self.name = tk.StringVar(value=canvas_node.name)
|
self.name = tk.StringVar(value=canvas_node.name)
|
||||||
self.range_var = tk.StringVar(value=config["basic_range"])
|
self.range_var = tk.StringVar(value=config["basic_range"])
|
||||||
self.bandwidth_var = tk.StringVar(value=config["bandwidth"])
|
self.bandwidth_var = tk.StringVar(value=config["bandwidth"])
|
||||||
|
@ -111,6 +112,7 @@ class WlanConfigDialog(Dialog):
|
||||||
|
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
|
|
||||||
frame = tk.Frame(self)
|
frame = tk.Frame(self)
|
||||||
frame.grid(pady=3, sticky="ew")
|
frame.grid(pady=3, sticky="ew")
|
||||||
frame.columnconfigure(1, weight=1)
|
frame.columnconfigure(1, weight=1)
|
||||||
|
@ -132,6 +134,7 @@ class WlanConfigDialog(Dialog):
|
||||||
|
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
frame = tk.Frame(self)
|
frame = tk.Frame(self)
|
||||||
frame.grid(pady=2, sticky="ew")
|
frame.grid(pady=2, sticky="ew")
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
|
@ -183,6 +186,7 @@ class WlanConfigDialog(Dialog):
|
||||||
jitter = self.jitter_var.get()
|
jitter = self.jitter_var.get()
|
||||||
|
|
||||||
# set wireless node configuration here
|
# set wireless node configuration here
|
||||||
|
|
||||||
wlanconfig_manager = self.app.core.wlanconfig_management
|
wlanconfig_manager = self.app.core.wlanconfig_management
|
||||||
wlanconfig_manager.set_custom_config(
|
wlanconfig_manager.set_custom_config(
|
||||||
node_id=self.canvas_node.core_id,
|
node_id=self.canvas_node.core_id,
|
||||||
|
|
|
@ -84,11 +84,13 @@ class CanvasGraph(tk.Canvas):
|
||||||
self.draw_node_name = None
|
self.draw_node_name = None
|
||||||
self.selected = None
|
self.selected = None
|
||||||
self.node_context = None
|
self.node_context = None
|
||||||
self.nodes = {}
|
self.nodes.clear()
|
||||||
self.edges = {}
|
self.edges.clear()
|
||||||
self.drawing_edge = None
|
self.drawing_edge = None
|
||||||
self.draw_existing_component(session)
|
self.draw_existing_component(session)
|
||||||
|
|
||||||
|
# self.grpc_manager.wlanconfig_management.load_wlan_configurations(self.core_grpc)
|
||||||
|
|
||||||
def setup_bindings(self):
|
def setup_bindings(self):
|
||||||
"""
|
"""
|
||||||
Bind any mouse events or hot keys to the matching action
|
Bind any mouse events or hot keys to the matching action
|
||||||
|
@ -221,12 +223,6 @@ class CanvasGraph(tk.Canvas):
|
||||||
for i in self.find_withtag("node"):
|
for i in self.find_withtag("node"):
|
||||||
self.lift(i)
|
self.lift(i)
|
||||||
|
|
||||||
# def delete_components(self):
|
|
||||||
# tags = ["node", "edge", "linkinfo", "nodename"]
|
|
||||||
# for i in tags:
|
|
||||||
# for id in self.find_withtag(i):
|
|
||||||
# self.delete(id)
|
|
||||||
|
|
||||||
def canvas_xy(self, event):
|
def canvas_xy(self, event):
|
||||||
"""
|
"""
|
||||||
Convert window coordinate to canvas coordinate
|
Convert window coordinate to canvas coordinate
|
||||||
|
|
71
coretk/coretk/mobilitynodeconfig.py
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
"""
|
||||||
|
mobility configurations for all the nodes
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
from core.api.grpc import core_pb2
|
||||||
|
|
||||||
|
|
||||||
|
class MobilityNodeConfig:
|
||||||
|
def __init__(self):
|
||||||
|
self.configurations = {}
|
||||||
|
|
||||||
|
def set_default_configuration(self, node_type, node_id):
|
||||||
|
"""
|
||||||
|
set default mobility configuration for a node
|
||||||
|
|
||||||
|
:param core_pb2.NodeType node_type: protobuf node type
|
||||||
|
:param int node_id: node id
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
if node_type == core_pb2.NodeType.WIRELESS_LAN:
|
||||||
|
config = OrderedDict()
|
||||||
|
config["autostart"] = ""
|
||||||
|
config["file"] = ""
|
||||||
|
config["loop"] = "1"
|
||||||
|
config["map"] = ""
|
||||||
|
config["refresh_ms"] = "50"
|
||||||
|
config["script_pause"] = ""
|
||||||
|
config["script_start"] = ""
|
||||||
|
config["script_stop"] = ""
|
||||||
|
self.configurations[node_id] = config
|
||||||
|
|
||||||
|
def set_custom_configuration(
|
||||||
|
self,
|
||||||
|
node_id,
|
||||||
|
file,
|
||||||
|
refresh_ms,
|
||||||
|
loop,
|
||||||
|
autostart,
|
||||||
|
node_mapping,
|
||||||
|
script_start,
|
||||||
|
script_pause,
|
||||||
|
script_stop,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
set custom mobility configuration for a node
|
||||||
|
|
||||||
|
:param int node_id: node id
|
||||||
|
:param str file: path to mobility script file
|
||||||
|
:param str refresh_ms: refresh time
|
||||||
|
:param str loop: loop option
|
||||||
|
:param str autostart: auto-start seconds value
|
||||||
|
:param str node_mapping: node mapping
|
||||||
|
:param str script_start: path to script to run upon start
|
||||||
|
:param str script_pause: path to script to run upon pause
|
||||||
|
:param str script_stop: path to script to run upon stop
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
if node_id in self.configurations:
|
||||||
|
self.configurations[node_id]["autostart"] = autostart
|
||||||
|
self.configurations[node_id]["file"] = file
|
||||||
|
self.configurations[node_id]["loop"] = loop
|
||||||
|
self.configurations[node_id]["map"] = node_mapping
|
||||||
|
self.configurations[node_id]["refresh_ms"] = refresh_ms
|
||||||
|
self.configurations[node_id]["script_pause"] = script_pause
|
||||||
|
self.configurations[node_id]["script_start"] = script_start
|
||||||
|
self.configurations[node_id]["script_stop"] = script_stop
|
||||||
|
else:
|
||||||
|
logging.error("mobilitynodeconfig.py invalid node_id")
|
Before Width: | Height: | Size: 744 B |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 635 B |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 719 B |
Before Width: | Height: | Size: 744 B |
Before Width: | Height: | Size: 86 B |
Before Width: | Height: | Size: 375 B |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 174 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 265 B |
Before Width: | Height: | Size: 160 B |
Before Width: | Height: | Size: 755 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 753 B |
Before Width: | Height: | Size: 324 B |
Before Width: | Height: | Size: 925 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 127 B |
Before Width: | Height: | Size: 799 B |
Before Width: | Height: | Size: 220 B |
Before Width: | Height: | Size: 146 B |
|
@ -14,7 +14,7 @@ class WlanNodeConfig:
|
||||||
def set_default_config(self, node_type, node_id):
|
def set_default_config(self, node_type, node_id):
|
||||||
if node_type == core_pb2.NodeType.WIRELESS_LAN:
|
if node_type == core_pb2.NodeType.WIRELESS_LAN:
|
||||||
config = OrderedDict()
|
config = OrderedDict()
|
||||||
config["basic_range"] = "275"
|
config["range"] = "275"
|
||||||
config["bandwidth"] = "54000000"
|
config["bandwidth"] = "54000000"
|
||||||
config["jitter"] = "0"
|
config["jitter"] = "0"
|
||||||
config["delay"] = "20000"
|
config["delay"] = "20000"
|
||||||
|
@ -22,8 +22,16 @@ class WlanNodeConfig:
|
||||||
self.configurations[node_id] = config
|
self.configurations[node_id] = config
|
||||||
|
|
||||||
def set_custom_config(self, node_id, range, bandwidth, jitter, delay, error):
|
def set_custom_config(self, node_id, range, bandwidth, jitter, delay, error):
|
||||||
self.configurations[node_id]["basic_range"] = range
|
self.configurations[node_id]["range"] = range
|
||||||
self.configurations[node_id]["bandwidth"] = bandwidth
|
self.configurations[node_id]["bandwidth"] = bandwidth
|
||||||
self.configurations[node_id]["jitter"] = jitter
|
self.configurations[node_id]["jitter"] = jitter
|
||||||
self.configurations[node_id]["delay"] = delay
|
self.configurations[node_id]["delay"] = delay
|
||||||
self.configurations[node_id]["error"] = error
|
self.configurations[node_id]["error"] = error
|
||||||
|
|
||||||
|
def delete_node_config(self, node_id):
|
||||||
|
"""
|
||||||
|
not implemented
|
||||||
|
:param node_id:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
return
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"level": "INFO",
|
"level": "DEBUG",
|
||||||
"handlers": ["console"]
|
"handlers": ["console"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|