small cleanup to emane config dialog, fixed default service storage to just use names
This commit is contained in:
parent
471c5eb7e1
commit
b983a09ae7
4 changed files with 209 additions and 314 deletions
|
@ -50,6 +50,7 @@ class CoreClient:
|
|||
self.master = app.master
|
||||
self.interface_helper = None
|
||||
self.services = {}
|
||||
self.emane_models = []
|
||||
self.observer = None
|
||||
|
||||
# loaded configuration data
|
||||
|
@ -70,6 +71,7 @@ class CoreClient:
|
|||
self.interfaces_manager = InterfaceManager()
|
||||
self.wlan_configs = {}
|
||||
self.mobility_configs = {}
|
||||
self.emane_model_configs = {}
|
||||
self.emaneconfig_management = EmaneModelNodeConfig(app)
|
||||
self.emane_config = None
|
||||
self.serviceconfig_manager = ServiceNodeConfig(app)
|
||||
|
@ -145,6 +147,10 @@ class CoreClient:
|
|||
self.state = session.state
|
||||
self.client.events(self.session_id, self.handle_events)
|
||||
|
||||
# get emane models
|
||||
response = self.client.get_emane_models(self.session_id)
|
||||
self.emane_models = response.models
|
||||
|
||||
# get hooks
|
||||
response = self.client.get_hooks(self.session_id)
|
||||
logging.info("joined session hooks: %s", response)
|
||||
|
@ -240,8 +246,8 @@ class CoreClient:
|
|||
# get service information
|
||||
response = self.client.get_services()
|
||||
for service in response.services:
|
||||
group_services = self.services.setdefault(service.group, [])
|
||||
group_services.append(service)
|
||||
group_services = self.services.setdefault(service.group, set())
|
||||
group_services.add(service.name)
|
||||
|
||||
# if there are no sessions, create a new session, else join a session
|
||||
response = self.client.get_sessions()
|
||||
|
@ -443,6 +449,9 @@ class CoreClient:
|
|||
image = None
|
||||
if NodeUtils.is_image_node(node_type):
|
||||
image = "ubuntu:latest"
|
||||
emane = None
|
||||
if node_type == core_pb2.NodeType.EMANE:
|
||||
emane = self.emane_models[0]
|
||||
node = core_pb2.Node(
|
||||
id=node_id,
|
||||
type=node_type,
|
||||
|
@ -450,6 +459,7 @@ class CoreClient:
|
|||
model=model,
|
||||
position=position,
|
||||
image=image,
|
||||
emane=emane,
|
||||
)
|
||||
|
||||
# set default emane configuration for emane node
|
||||
|
@ -571,25 +581,6 @@ class CoreClient:
|
|||
if interface_two is not None:
|
||||
self.interface_to_edge[(node_two.id, interface_two.id)] = token
|
||||
|
||||
# emane setup
|
||||
# TODO: determine if this is needed
|
||||
if (
|
||||
node_one.type == core_pb2.NodeType.EMANE
|
||||
and node_two.type == core_pb2.NodeType.DEFAULT
|
||||
):
|
||||
if node_two.model == "mdr":
|
||||
self.emaneconfig_management.set_default_for_mdr(
|
||||
node_one.node_id, node_two.node_id, interface_two.id
|
||||
)
|
||||
elif (
|
||||
node_two.type == core_pb2.NodeType.EMANE
|
||||
and node_one.type == core_pb2.NodeType.DEFAULT
|
||||
):
|
||||
if node_one.model == "mdr":
|
||||
self.emaneconfig_management.set_default_for_mdr(
|
||||
node_two.node_id, node_one.node_id, interface_one.id
|
||||
)
|
||||
|
||||
link = core_pb2.Link(
|
||||
type=core_pb2.LinkType.WIRED,
|
||||
node_one_id=node_one.id,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
"""
|
||||
emane configuration
|
||||
"""
|
||||
|
||||
import logging
|
||||
import tkinter as tk
|
||||
import webbrowser
|
||||
|
@ -11,271 +10,122 @@ from coretk.dialogs.dialog import Dialog
|
|||
from coretk.images import ImageEnum, Images
|
||||
from coretk.widgets import ConfigFrame
|
||||
|
||||
PAD_X = 2
|
||||
PAD_Y = 2
|
||||
PAD = 5
|
||||
|
||||
|
||||
class EmaneConfiguration(Dialog):
|
||||
class GlobalEmaneDialog(Dialog):
|
||||
def __init__(self, master, app):
|
||||
super().__init__(master, app, "EMANE Configuration", modal=True)
|
||||
self.config_frame = None
|
||||
self.draw()
|
||||
|
||||
def draw(self):
|
||||
self.top.columnconfigure(0, weight=1)
|
||||
self.top.rowconfigure(0, weight=1)
|
||||
self.config_frame = ConfigFrame(
|
||||
self.top, self.app, self.app.core.emane_config, borderwidth=0
|
||||
)
|
||||
self.config_frame.draw_config()
|
||||
self.config_frame.grid(sticky="nsew", pady=PAD)
|
||||
self.draw_buttons()
|
||||
|
||||
def draw_buttons(self):
|
||||
frame = ttk.Frame(self.top)
|
||||
frame.grid(sticky="ew")
|
||||
for i in range(2):
|
||||
frame.columnconfigure(i, weight=1)
|
||||
button = ttk.Button(frame, text="Apply", command=self.click_apply)
|
||||
button.grid(row=0, column=0, sticky="ew", padx=PAD)
|
||||
|
||||
button = ttk.Button(frame, text="Cancel", command=self.destroy)
|
||||
button.grid(row=0, column=1, sticky="ew")
|
||||
|
||||
def click_apply(self):
|
||||
self.config_frame.parse_config()
|
||||
self.destroy()
|
||||
|
||||
|
||||
class EmaneModelDialog(Dialog):
|
||||
def __init__(self, master, app, node, model):
|
||||
super().__init__(master, app, f"{node.name} {model} Configuration", modal=True)
|
||||
self.node = node
|
||||
self.model = f"emane_{model}"
|
||||
self.config_frame = None
|
||||
session_id = self.app.core.session_id
|
||||
response = self.app.core.client.get_emane_model_config(
|
||||
session_id, self.node.id, self.model
|
||||
)
|
||||
self.config = response.config
|
||||
self.draw()
|
||||
|
||||
def draw(self):
|
||||
self.top.columnconfigure(0, weight=1)
|
||||
self.top.rowconfigure(0, weight=1)
|
||||
self.config_frame = ConfigFrame(self.top, self.app, self.config, borderwidth=0)
|
||||
self.config_frame.draw_config()
|
||||
self.config_frame.grid(sticky="nsew", pady=PAD)
|
||||
self.draw_buttons()
|
||||
|
||||
def draw_buttons(self):
|
||||
frame = ttk.Frame(self.top)
|
||||
frame.grid(sticky="ew")
|
||||
for i in range(2):
|
||||
frame.columnconfigure(i, weight=1)
|
||||
button = ttk.Button(frame, text="Apply", command=self.click_apply)
|
||||
button.grid(row=0, column=0, sticky="ew", padx=PAD)
|
||||
|
||||
button = ttk.Button(frame, text="Cancel", command=self.destroy)
|
||||
button.grid(row=0, column=1, sticky="ew")
|
||||
|
||||
def click_apply(self):
|
||||
self.config_frame.parse_config()
|
||||
self.app.core.emaneconfig_management.set_custom_emane_cloud_config(
|
||||
self.node.id, self.model
|
||||
)
|
||||
self.destroy()
|
||||
|
||||
|
||||
class EmaneConfigDialog(Dialog):
|
||||
def __init__(self, master, app, canvas_node):
|
||||
super().__init__(master, app, "emane configuration", modal=False)
|
||||
super().__init__(
|
||||
master, app, f"{canvas_node.core_node.name} EMANE Configuration", modal=True
|
||||
)
|
||||
self.app = app
|
||||
self.canvas_node = canvas_node
|
||||
self.node = canvas_node.core_node
|
||||
self.radiovar = tk.IntVar()
|
||||
self.radiovar.set(1)
|
||||
self.columnconfigure(0, weight=1)
|
||||
self.emane_models = [x.split("_")[1] for x in self.app.core.emane_models]
|
||||
emane_model = None
|
||||
if self.emane_models:
|
||||
emane_model = self.emane_models[0]
|
||||
self.emane_model = tk.StringVar(value=emane_model)
|
||||
self.emane_model_button = None
|
||||
self.draw()
|
||||
|
||||
# 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()
|
||||
def draw(self):
|
||||
self.top.columnconfigure(0, weight=1)
|
||||
self.draw_emane_configuration()
|
||||
self.draw_emane_models()
|
||||
self.draw_emane_buttons()
|
||||
self.draw_apply_and_cancel()
|
||||
|
||||
self.emane_config_frame = None
|
||||
self.options = app.core.emane_config
|
||||
self.model_options = None
|
||||
self.model_config_frame = 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):
|
||||
logging.info("not implemented")
|
||||
|
||||
def node_name_and_image(self):
|
||||
f = ttk.Frame(self.top)
|
||||
|
||||
lbl = ttk.Label(f, text="Node name:")
|
||||
lbl.grid(row=0, column=0, padx=2, pady=2)
|
||||
e = ttk.Entry(f, textvariable=self.create_text_variable(""))
|
||||
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 = ttk.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):
|
||||
self.emane_config_frame.parse_config()
|
||||
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
|
||||
)
|
||||
|
||||
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.emane_dialog.top.columnconfigure(0, weight=1)
|
||||
self.emane_dialog.top.rowconfigure(0, weight=1)
|
||||
self.emane_config_frame = ConfigFrame(
|
||||
self.emane_dialog.top, self.app, config=self.options
|
||||
)
|
||||
self.emane_config_frame.draw_config()
|
||||
self.emane_config_frame.grid(sticky="nsew")
|
||||
|
||||
frame = ttk.Frame(self.emane_dialog.top)
|
||||
frame.grid(sticky="ew")
|
||||
for i in range(2):
|
||||
frame.columnconfigure(i, weight=1)
|
||||
b1 = ttk.Button(frame, text="Appy", command=self.save_emane_option)
|
||||
b1.grid(row=0, column=0, sticky="ew")
|
||||
b2 = ttk.Button(frame, text="Cancel", command=self.emane_dialog.destroy)
|
||||
b2.grid(row=0, column=1, sticky="ew")
|
||||
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
|
||||
config = self.model_config_frame.parse_config()
|
||||
|
||||
# add string emane_ infront for grpc call
|
||||
response = self.app.core.client.set_emane_model_config(
|
||||
self.app.core.session_id, self.node.id, f"emane_{model_name}", config
|
||||
)
|
||||
logging.info(
|
||||
"emaneconfig.py config emane model (%s), result: %s", self.node.id, response
|
||||
)
|
||||
|
||||
# store the change locally
|
||||
self.app.core.emaneconfig_management.set_custom_emane_cloud_config(
|
||||
self.node.id, f"emane_{model_name}"
|
||||
)
|
||||
|
||||
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, f"{model_name} configuration", modal=False
|
||||
)
|
||||
self.emane_model_dialog.top.columnconfigure(0, weight=1)
|
||||
self.emane_model_dialog.top.rowconfigure(0, weight=1)
|
||||
|
||||
# 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.node.id, f"emane_{model_name}"
|
||||
)
|
||||
logging.info("emane model config %s", response)
|
||||
|
||||
self.model_options = response.config
|
||||
self.model_config_frame = ConfigFrame(
|
||||
self.emane_model_dialog.top, self.app, config=self.model_options
|
||||
)
|
||||
self.model_config_frame.grid(sticky="nsew")
|
||||
self.model_config_frame.draw_config()
|
||||
|
||||
frame = ttk.Frame(self.emane_model_dialog.top)
|
||||
frame.grid(sticky="ew")
|
||||
for i in range(2):
|
||||
frame.columnconfigure(i, weight=1)
|
||||
b1 = ttk.Button(frame, text="Apply", command=self.save_emane_model_options)
|
||||
b1.grid(row=0, column=0, sticky="ew")
|
||||
b2 = ttk.Button(frame, text="Cancel", command=self.emane_model_dialog.destroy)
|
||||
b2.grid(row=0, column=1, sticky="ew")
|
||||
self.emane_model_dialog.show()
|
||||
|
||||
def draw_option_buttons(self, parent):
|
||||
f = ttk.Frame(parent)
|
||||
f.grid(row=4, column=0, sticky="nsew")
|
||||
f.columnconfigure(0, weight=1)
|
||||
f.columnconfigure(1, weight=1)
|
||||
|
||||
image = Images.get(ImageEnum.EDITNODE, 16)
|
||||
b = ttk.Button(
|
||||
f,
|
||||
text=self.emane_models[0] + " options",
|
||||
image=image,
|
||||
compound=tk.RIGHT,
|
||||
command=self.draw_model_options,
|
||||
)
|
||||
b.image = image
|
||||
b.grid(row=0, column=0, padx=10, pady=2, sticky="nsew")
|
||||
|
||||
image = Images.get(ImageEnum.EDITNODE, 16)
|
||||
b = ttk.Button(
|
||||
f,
|
||||
text="EMANE options",
|
||||
image=image,
|
||||
compound=tk.RIGHT,
|
||||
command=self.draw_emane_options,
|
||||
)
|
||||
b.image = image
|
||||
b.grid(row=0, column=1, padx=10, pady=2, 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 = ttk.Frame(parent)
|
||||
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="ew")
|
||||
|
||||
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 = ttk.Frame(parent)
|
||||
lbl = ttk.Label(f, text=label_text)
|
||||
lbl.grid(row=0, column=0)
|
||||
e = ttk.Entry(f, textvariable=var)
|
||||
e.grid(row=0, column=1)
|
||||
f.grid(stick=tk.W, padx=2, pady=2)
|
||||
|
||||
def emane_configuration(self):
|
||||
def draw_emane_configuration(self):
|
||||
"""
|
||||
draw the main frame for emane configuration
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
# draw label
|
||||
lbl = ttk.Label(self.top, text="Emane")
|
||||
lbl.grid(row=1, column=0)
|
||||
|
||||
# main frame that has emane wiki, a short description, emane models and the configure buttons
|
||||
f = ttk.Frame(self.top)
|
||||
f.columnconfigure(0, weight=1)
|
||||
label = ttk.Label(
|
||||
self.top,
|
||||
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",
|
||||
)
|
||||
label.grid(sticky="ew", pady=PAD)
|
||||
|
||||
image = Images.get(ImageEnum.EDITNODE, 16)
|
||||
b = ttk.Button(
|
||||
f,
|
||||
button = ttk.Button(
|
||||
self.top,
|
||||
image=image,
|
||||
text="EMANE Wiki",
|
||||
compound=tk.RIGHT,
|
||||
|
@ -283,55 +133,99 @@ class EmaneConfiguration(Dialog):
|
|||
"https://github.com/adjacentlink/emane/wiki"
|
||||
),
|
||||
)
|
||||
b.image = image
|
||||
b.grid(row=0, column=0, sticky="w")
|
||||
button.image = image
|
||||
button.grid(sticky="ew", pady=PAD)
|
||||
|
||||
lbl = ttk.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",
|
||||
def draw_emane_models(self):
|
||||
"""
|
||||
create a combobox that has all the known emane models
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
frame = ttk.Frame(self.top)
|
||||
frame.grid(sticky="ew", pady=PAD)
|
||||
frame.columnconfigure(1, weight=1)
|
||||
|
||||
label = ttk.Label(frame, text="Model")
|
||||
label.grid(row=0, column=0, sticky="w")
|
||||
|
||||
# create combo box and its binding
|
||||
combobox = ttk.Combobox(
|
||||
frame,
|
||||
textvariable=self.emane_model,
|
||||
values=self.emane_models,
|
||||
state="readonly",
|
||||
)
|
||||
lbl.grid(row=1, column=0, sticky="nsew")
|
||||
combobox.grid(row=0, column=1, sticky="ew")
|
||||
combobox.bind("<<ComboboxSelected>>", self.emane_model_change)
|
||||
|
||||
lbl = ttk.Label(f, text="EMANE Models")
|
||||
lbl.grid(row=2, column=0, sticky="w")
|
||||
def draw_emane_buttons(self):
|
||||
frame = ttk.Frame(self.top)
|
||||
frame.grid(sticky="ew", pady=PAD)
|
||||
for i in range(2):
|
||||
frame.columnconfigure(i, weight=1)
|
||||
|
||||
self.draw_emane_models(f)
|
||||
self.draw_option_buttons(f)
|
||||
image = Images.get(ImageEnum.EDITNODE, 16)
|
||||
self.emane_model_button = ttk.Button(
|
||||
frame,
|
||||
text=f"{self.emane_model.get()} options",
|
||||
image=image,
|
||||
compound=tk.RIGHT,
|
||||
command=self.click_model_config,
|
||||
)
|
||||
self.emane_model_button.image = image
|
||||
self.emane_model_button.grid(row=0, column=0, padx=PAD, sticky="ew")
|
||||
|
||||
f.grid(row=2, column=0, sticky="nsew")
|
||||
|
||||
def draw_ip_subnets(self):
|
||||
self.draw_text_label_and_entry(self.top, "IPv4 subnet", "")
|
||||
self.draw_text_label_and_entry(self.top, "IPv6 subnet", "")
|
||||
|
||||
def emane_options(self):
|
||||
"""
|
||||
create wireless node options
|
||||
|
||||
:return:
|
||||
"""
|
||||
f = ttk.Frame(self.top)
|
||||
f.columnconfigure(0, weight=1)
|
||||
f.columnconfigure(1, weight=1)
|
||||
b = ttk.Button(f, text="Link to all routers")
|
||||
b.grid(row=0, column=0, padx=10, pady=2, sticky="nsew")
|
||||
b = ttk.Button(f, text="Choose WLAN members")
|
||||
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()
|
||||
image = Images.get(ImageEnum.EDITNODE, 16)
|
||||
button = ttk.Button(
|
||||
frame,
|
||||
text="EMANE options",
|
||||
image=image,
|
||||
compound=tk.RIGHT,
|
||||
command=self.click_emane_config,
|
||||
)
|
||||
button.image = image
|
||||
button.grid(row=0, column=1, sticky="ew")
|
||||
|
||||
def draw_apply_and_cancel(self):
|
||||
f = ttk.Frame(self.top)
|
||||
f.columnconfigure(0, weight=1)
|
||||
f.columnconfigure(1, weight=1)
|
||||
b = ttk.Button(f, text="Apply", command=self.apply)
|
||||
b.grid(row=0, column=0, padx=10, pady=2, sticky="nsew")
|
||||
b = ttk.Button(f, text="Cancel", command=self.destroy)
|
||||
b.grid(row=0, column=1, padx=10, pady=2, sticky="nsew")
|
||||
frame = ttk.Frame(self.top)
|
||||
frame.grid(sticky="ew")
|
||||
for i in range(2):
|
||||
frame.columnconfigure(i, weight=1)
|
||||
|
||||
f.grid(sticky="nsew")
|
||||
button = ttk.Button(frame, text="Apply", command=self.click_apply)
|
||||
button.grid(row=0, column=0, padx=PAD, sticky="ew")
|
||||
|
||||
button = ttk.Button(frame, text="Cancel", command=self.destroy)
|
||||
button.grid(row=0, column=1, sticky="ew")
|
||||
|
||||
def click_emane_config(self):
|
||||
dialog = GlobalEmaneDialog(self, self.app)
|
||||
dialog.show()
|
||||
|
||||
def click_model_config(self):
|
||||
"""
|
||||
draw emane model configuration
|
||||
|
||||
:return: nothing
|
||||
"""
|
||||
model_name = self.emane_model.get()
|
||||
logging.info("configuring emane model: %s", model_name)
|
||||
dialog = EmaneModelDialog(
|
||||
self, self.app, self.canvas_node.core_node, model_name
|
||||
)
|
||||
dialog.show()
|
||||
|
||||
def emane_model_change(self, event):
|
||||
"""
|
||||
update emane model options button
|
||||
|
||||
:param event:
|
||||
:return: nothing
|
||||
"""
|
||||
model_name = self.emane_model.get()
|
||||
self.emane_model_button.config(text=f"{model_name} options")
|
||||
|
||||
def click_apply(self):
|
||||
self.node.emane = f"emane_{self.emane_model.get()}"
|
||||
self.destroy()
|
||||
|
|
|
@ -28,7 +28,7 @@ class EmaneModelNodeConfig:
|
|||
"""
|
||||
session_id = self.app.core.session_id
|
||||
client = self.app.core.client
|
||||
default_emane_model = client.get_emane_models(session_id).models[0]
|
||||
default_emane_model = self.app.core.emane_models[0]
|
||||
response = client.get_emane_model_config(
|
||||
session_id, node_id, default_emane_model
|
||||
)
|
||||
|
|
|
@ -7,6 +7,7 @@ from PIL import ImageTk
|
|||
from core.api.grpc import core_pb2
|
||||
from core.api.grpc.core_pb2 import NodeType
|
||||
from coretk.canvastooltip import CanvasTooltip
|
||||
from coretk.dialogs.emaneconfig import EmaneConfigDialog
|
||||
from coretk.dialogs.mobilityconfig import MobilityConfigDialog
|
||||
from coretk.dialogs.nodeconfig import NodeConfigDialog
|
||||
from coretk.dialogs.wlanconfig import WlanConfigDialog
|
||||
|
@ -77,6 +78,10 @@ class CanvasGraph(tk.Canvas):
|
|||
context.add_command(
|
||||
label="Mobility Config", command=canvas_node.show_mobility_config
|
||||
)
|
||||
if node.type == NodeType.EMANE:
|
||||
context.add_command(
|
||||
label="EMANE Config", command=canvas_node.show_emane_config
|
||||
)
|
||||
context.add_command(label="Select adjacent", state=tk.DISABLED)
|
||||
context.add_command(label="Create link to", state=tk.DISABLED)
|
||||
context.add_command(label="Assign to", state=tk.DISABLED)
|
||||
|
@ -711,3 +716,8 @@ class CanvasNode:
|
|||
self.canvas.context = None
|
||||
dialog = MobilityConfigDialog(self.app, self.app, self)
|
||||
dialog.show()
|
||||
|
||||
def show_emane_config(self):
|
||||
self.canvas.context = None
|
||||
dialog = EmaneConfigDialog(self.app, self.app, self)
|
||||
dialog.show()
|
||||
|
|
Loading…
Add table
Reference in a new issue