merged latest from coretk

This commit is contained in:
bharnden 2019-11-01 11:34:38 -07:00
commit 5369694797
15 changed files with 991 additions and 168 deletions

View file

@ -0,0 +1,43 @@
"""
canvas graph action
"""
# import tkinter as tk
from core.api.grpc import core_pb2
from coretk.nodeconfigtable import NodeConfig
from coretk.wlanconfiguration import WlanConfiguration
# TODO, finish classifying node types
NODE_TO_TYPE = {
"router": core_pb2.NodeType.DEFAULT,
"wlan": core_pb2.NodeType.WIRELESS_LAN,
}
class CanvasAction:
def __init__(self, master, canvas):
self.master = master
self.canvas = canvas
self.node_to_show_config = None
def display_configuration(self, canvas_node):
pb_type = NODE_TO_TYPE[canvas_node.node_type]
self.node_to_show_config = canvas_node
if pb_type == core_pb2.NodeType.DEFAULT:
self.display_node_configuration()
elif pb_type == core_pb2.NodeType.WIRELESS_LAN:
self.display_wlan_configuration(canvas_node)
def display_node_configuration(self):
NodeConfig(self.canvas, self.node_to_show_config)
self.node_to_show_config = None
def display_wlan_configuration(self, canvas_node):
# print(self.canvas.grpc_manager.wlanconfig_management.configurations)
wlan_config = self.canvas.grpc_manager.wlanconfig_management.configurations[
canvas_node.core_id
]
WlanConfiguration(self.canvas, self.node_to_show_config, wlan_config)
self.node_to_show_config = None

View file

@ -64,7 +64,7 @@ class CoreGrpc:
self.manager.reusable.append(i) self.manager.reusable.append(i)
# draw session # draw session
self.app.canvas.draw_existing_component(session) self.app.canvas.canvas_reset_and_redraw(session)
def create_new_session(self): def create_new_session(self):
""" """
@ -213,6 +213,54 @@ class CoreGrpc:
) )
logging.info("delete links %s", response) logging.info("delete links %s", response)
def create_interface(self, node_type, gui_interface):
"""
create a protobuf interface given the interface object stored by the programmer
:param core_bp2.NodeType type: node type
:param coretk.interface.Interface gui_interface: the programmer's interface object
:rtype: core_bp2.Interface
:return: protobuf interface object
"""
if node_type != core_pb2.NodeType.DEFAULT:
return None
else:
interface = core_pb2.Interface(
id=gui_interface.id,
name=gui_interface.name,
mac=gui_interface.mac,
ip4=gui_interface.ipv4,
ip4mask=gui_interface.ip4prefix,
)
logging.debug("create interface 1 %s", interface)
return interface
# TODO add location, hooks, emane_config, etc...
def start_session(
self,
nodes,
links,
location=None,
hooks=None,
emane_config=None,
emane_model_configs=None,
wlan_configs=None,
mobility_configs=None,
):
response = self.core.start_session(
session_id=self.session_id,
nodes=nodes,
links=links,
wlan_configs=wlan_configs,
)
logging.debug("Start session %s, result: %s", self.session_id, response.result)
def stop_session(self):
response = self.core.stop_session(session_id=self.session_id)
logging.debug("coregrpc.py Stop session, result: %s", response.result)
# TODO no need, might get rid of this
def add_link(self, id1, id2, type1, type2, edge): def add_link(self, id1, id2, type1, type2, edge):
""" """
Grpc client request add link Grpc client request add link
@ -224,30 +272,30 @@ class CoreGrpc:
:param core_pb2.NodeType type2: node 2 core node type :param core_pb2.NodeType type2: node 2 core node type
:return: nothing :return: nothing
""" """
if1 = None if1 = self.create_interface(type1, edge.interface_1)
if2 = None if2 = self.create_interface(type2, edge.interface_2)
if type1 == core_pb2.NodeType.DEFAULT: # if type1 == core_pb2.NodeType.DEFAULT:
interface = edge.interface_1 # interface = edge.interface_1
if1 = core_pb2.Interface( # if1 = core_pb2.Interface(
id=interface.id, # id=interface.id,
name=interface.name, # name=interface.name,
mac=interface.mac, # mac=interface.mac,
ip4=interface.ipv4, # ip4=interface.ipv4,
ip4mask=interface.ip4prefix, # ip4mask=interface.ip4prefix,
) # )
logging.debug("create interface 1 %s", if1) # logging.debug("create interface 1 %s", if1)
# interface1 = self.interface_helper.create_interface(id1, 0) # # interface1 = self.interface_helper.create_interface(id1, 0)
#
if type2 == core_pb2.NodeType.DEFAULT: # if type2 == core_pb2.NodeType.DEFAULT:
interface = edge.interface_2 # interface = edge.interface_2
if2 = core_pb2.Interface( # if2 = core_pb2.Interface(
id=interface.id, # id=interface.id,
name=interface.name, # name=interface.name,
mac=interface.mac, # mac=interface.mac,
ip4=interface.ipv4, # ip4=interface.ipv4,
ip4mask=interface.ip4prefix, # ip4mask=interface.ip4prefix,
) # )
logging.debug("create interface 2: %s", if2) # logging.debug("create interface 2: %s", if2)
response = self.core.add_link(self.session_id, id1, id2, if1, if2) response = self.core.add_link(self.session_id, id1, id2, if1, if2)
logging.info("created link: %s", response) logging.info("created link: %s", response)
@ -276,8 +324,8 @@ class CoreGrpc:
:return: session id :return: session id
""" """
response = self.core.open_xml(file_path) response = self.core.open_xml(file_path)
self.session_id = response.session_id logging.debug("open xml: %s", response)
logging.debug("coreprgc.py open_xml(): %s", response.result) self.join_session(response.session_id)
def close(self): def close(self):
""" """

View file

@ -1,22 +1,23 @@
import logging import logging
import tkinter as tk import tkinter as tk
from enum import Enum
from core.api.grpc import core_pb2 # from core.api.grpc import core_pb2
from coretk.coretoolbarhelp import CoreToolbarHelp from coretk.coretoolbarhelp import CoreToolbarHelp
from coretk.graph import GraphMode from coretk.graph import GraphMode
from coretk.images import ImageEnum, Images from coretk.images import ImageEnum, Images
from coretk.tooltip import CreateToolTip from coretk.tooltip import CreateToolTip
# from enum import Enum
class SessionStateEnum(Enum):
NONE = "none" # class SessionStateEnum(Enum):
DEFINITION = "definition" # NONE = "none"
CONFIGURATION = "configuration" # DEFINITION = "definition"
RUNTIME = "runtime" # CONFIGURATION = "configuration"
DATACOLLECT = "datacollect" # RUNTIME = "runtime"
SHUTDOWN = "shutdown" # DATACOLLECT = "datacollect"
INSTANTIATION = "instantiation" # SHUTDOWN = "shutdown"
# INSTANTIATION = "instantiation"
class CoreToolbar(object): class CoreToolbar(object):
@ -161,21 +162,22 @@ class CoreToolbar(object):
""" """
logging.debug("Click START STOP SESSION button") logging.debug("Click START STOP SESSION button")
helper = CoreToolbarHelp(self.application) helper = CoreToolbarHelp(self.application)
# self.destroy_children_widgets(self.edit_frame)
self.destroy_children_widgets() self.destroy_children_widgets()
self.canvas.mode = GraphMode.SELECT self.canvas.mode = GraphMode.SELECT
# set configuration state # set configuration state
state = self.canvas.core_grpc.get_session_state() # state = self.canvas.core_grpc.get_session_state()
# if state == core_pb2.SessionState.SHUTDOWN or self.application.is_open_xml:
# self.canvas.core_grpc.set_session_state(SessionStateEnum.DEFINITION.value)
# self.application.is_open_xml = False
#
# self.canvas.core_grpc.set_session_state(SessionStateEnum.CONFIGURATION.value)
# helper.add_nodes()
# helper.add_edges()
# self.canvas.core_grpc.set_session_state(SessionStateEnum.INSTANTIATION.value)
helper.gui_start_session()
self.create_runtime_toolbar()
if state == core_pb2.SessionState.SHUTDOWN or self.application.is_open_xml:
self.canvas.core_grpc.set_session_state(SessionStateEnum.DEFINITION.value)
self.application.is_open_xml = False
self.canvas.core_grpc.set_session_state(SessionStateEnum.CONFIGURATION.value)
helper.add_nodes()
helper.add_edges()
# for node in self.canvas.grpc_manager.nodes.values(): # for node in self.canvas.grpc_manager.nodes.values():
# print(node.type, node.model, int(node.x), int(node.y), node.name, node.node_id) # print(node.type, node.model, int(node.x), int(node.y), node.name, node.node_id)
# self.canvas.core_grpc.add_node( # self.canvas.core_grpc.add_node(
@ -188,10 +190,8 @@ class CoreToolbar(object):
# self.canvas.core_grpc.add_link( # self.canvas.core_grpc.add_link(
# edge.id1, edge.id2, edge.type1, edge.type2, edge # edge.id1, edge.id2, edge.type1, edge.type2, edge
# ) # )
self.canvas.core_grpc.set_session_state(SessionStateEnum.INSTANTIATION.value)
# self.canvas.core_grpc.get_session() # self.canvas.core_grpc.get_session()
# self.application.is_open_xml = False # self.application.is_open_xml = False
self.create_runtime_toolbar()
def click_link_tool(self): def click_link_tool(self):
logging.debug("Click LINK button") logging.debug("Click LINK button")
@ -366,6 +366,13 @@ class CoreToolbar(object):
self.canvas.draw_node_image = Images.get(ImageEnum.TUNNEL) self.canvas.draw_node_image = Images.get(ImageEnum.TUNNEL)
self.canvas.draw_node_name = "tunnel" self.canvas.draw_node_name = "tunnel"
def pick_emane(self, main_button):
self.link_layer_option_menu.destroy()
main_button.configure(image=Images.get(ImageEnum.EMANE.value))
self.canvas.mode = GraphMode.PICKNODE
self.canvas.draw_node_image = Images.get(ImageEnum.EMANE.value)
self.canvas.draw_node_name = "emane"
def draw_link_layer_options(self, link_layer_button): def draw_link_layer_options(self, link_layer_button):
""" """
Draw the options for link-layer button Draw the options for link-layer button
@ -380,6 +387,7 @@ class CoreToolbar(object):
Images.get(ImageEnum.HUB), Images.get(ImageEnum.HUB),
Images.get(ImageEnum.SWITCH), Images.get(ImageEnum.SWITCH),
Images.get(ImageEnum.WLAN), Images.get(ImageEnum.WLAN),
Images.get(ImageEnum.EMANE),
Images.get(ImageEnum.RJ45), Images.get(ImageEnum.RJ45),
Images.get(ImageEnum.TUNNEL), Images.get(ImageEnum.TUNNEL),
] ]
@ -387,6 +395,7 @@ class CoreToolbar(object):
self.pick_hub, self.pick_hub,
self.pick_switch, self.pick_switch,
self.pick_wlan, self.pick_wlan,
self.pick_emane,
self.pick_rj45, self.pick_rj45,
self.pick_tunnel, self.pick_tunnel,
] ]
@ -394,6 +403,7 @@ class CoreToolbar(object):
"ethernet hub", "ethernet hub",
"ethernet switch", "ethernet switch",
"wireless LAN", "wireless LAN",
"emane",
"rj45 physical interface tool", "rj45 physical interface tool",
"tunnel tool", "tunnel tool",
] ]
@ -582,12 +592,12 @@ class CoreToolbar(object):
:return: nothing :return: nothing
""" """
logging.debug("Click on STOP button ") logging.debug("Click on STOP button ")
# self.destroy_children_widgets(self.edit_frame)
self.destroy_children_widgets() self.destroy_children_widgets()
self.canvas.core_grpc.set_session_state(SessionStateEnum.DATACOLLECT.value) # self.canvas.core_grpc.set_session_state(SessionStateEnum.DATACOLLECT.value)
self.canvas.core_grpc.delete_links() # self.canvas.core_grpc.delete_links()
self.canvas.core_grpc.delete_nodes() # self.canvas.core_grpc.delete_nodes()
self.canvas.core_grpc.stop_session()
self.create_toolbar() self.create_toolbar()
def click_run_button(self): def click_run_button(self):

View file

@ -1,30 +1,116 @@
""" """
CoreToolbar help to draw on canvas, and make grpc client call CoreToolbar help to draw on canvas, and make grpc client call
""" """
from core.api.grpc.client import core_pb2
class CoreToolbarHelp: class CoreToolbarHelp:
def __init__(self, app): def __init__(self, app):
self.app = app self.app = app
def add_nodes(self): def get_node_list(self):
""" """
add the nodes stored in grpc manager form a list node protobuf nodes to pass in start_session in grpc
:return: nothing :return: nothing
""" """
nodes = []
manager = self.app.core_grpc.manager manager = self.app.core_grpc.manager
for node in manager.nodes.values(): for node in manager.nodes.values():
self.app.core_grpc.add_node( pos = core_pb2.Position(x=int(node.x), y=int(node.y))
node.type, node.model, int(node.x), int(node.y), node.name, node.node_id n = core_pb2.Node(
id=node.node_id, type=node.type, position=pos, model=node.model
) )
nodes.append(n)
return nodes
def add_edges(self): def get_link_list(self):
""" """
add the edges stored in grpc manager form a list of links to pass into grpc start session
:return:
:rtype: list(core_pb2.Link)
:return: list of protobuf links
""" """
links = []
manager = self.app.core_grpc.manager manager = self.app.core_grpc.manager
for edge in manager.edges.values(): for edge in manager.edges.values():
self.app.core_grpc.add_link( interface_one = self.app.core_grpc.create_interface(
edge.id1, edge.id2, edge.type1, edge.type2, edge edge.type1, edge.interface_1
) )
interface_two = self.app.core_grpc.create_interface(
edge.type2, edge.interface_2
)
# TODO for now only consider the basic cases
if (
edge.type1 == core_pb2.NodeType.WIRELESS_LAN
or edge.type2 == core_pb2.NodeType.WIRELESS_LAN
):
link_type = core_pb2.LinkType.WIRELESS
else:
link_type = core_pb2.LinkType.WIRED
link = core_pb2.Link(
node_one_id=edge.id1,
node_two_id=edge.id2,
type=link_type,
interface_one=interface_one,
interface_two=interface_two,
)
links.append(link)
# self.id1 = edge.id1
# self.id2 = edge.id2
# self.type = link_type
# self.if1 = interface_one
# self.if2 = interface_two
return links
def get_wlan_configuration_list(self):
configs = []
manager = self.app.core_grpc.manager
manager_configs = manager.wlanconfig_management.configurations
for key in manager_configs:
cnf = core_pb2.WlanConfig(node_id=key, config=manager_configs[key])
configs.append(cnf)
return configs
def gui_start_session(self):
# list(core_pb2.Node)
nodes = self.get_node_list()
# list(core_bp2.Link)
links = self.get_link_list()
# print(links[0])
wlan_configs = self.get_wlan_configuration_list()
# print(wlan_configs)
self.app.core_grpc.start_session(nodes, links, wlan_configs=wlan_configs)
# self.core_grpc.core.add_link(self.core_grpc.session_id, self.id1, self.id2, self.if1, self.if2)
# res = self.core_grpc.core.get_wlan_config(self.core_grpc.session_id, 1)
# res = self.core_grpc.core.get_session(self.core_grpc.session_id).session
# print(res)
# res = self.core_grpc.core.get_wlan_config(self.core_grpc.session_id, 1)
# print(res)
# def add_nodes(self):
# """
# add the nodes stored in grpc manager
# :return: nothing
# """
# grpc_manager = self.application.canvas.grpc_manager
# for node in grpc_manager.nodes.values():
# self.application.core_grpc.add_node(
# node.type, node.model, int(node.x), int(node.y), node.name, node.node_id
# )
#
# def add_edges(self):
# """
# add the edges stored in grpc manager
# :return:
# """
# grpc_manager = self.application.canvas.grpc_manager
# for edge in grpc_manager.edges.values():
# self.application.core_grpc.add_link(
# edge.id1, edge.id2, edge.type1, edge.type2, edge
# )

View file

@ -3,11 +3,11 @@ import logging
import tkinter as tk import tkinter as tk
from core.api.grpc import core_pb2 from core.api.grpc import core_pb2
from coretk.canvasaction import CanvasAction
from coretk.graph_helper import GraphHelper, WlanAntennaManager from coretk.graph_helper import GraphHelper, WlanAntennaManager
from coretk.images import Images from coretk.images import Images
from coretk.interface import Interface from coretk.interface import Interface
from coretk.linkinfo import LinkInfo, Throughput from coretk.linkinfo import LinkInfo, Throughput
from coretk.nodeconfigtable import NodeConfig
from coretk.wirelessconnection import WirelessConnection from coretk.wirelessconnection import WirelessConnection
@ -19,6 +19,12 @@ class GraphMode(enum.Enum):
OTHER = 4 OTHER = 4
CORE_NODES = ["router"]
CORE_WIRED_NETWORK_NODES = []
CORE_WIRELESS_NODE = ["wlan"]
CORE_EMANE = ["emane"]
class CanvasGraph(tk.Canvas): class CanvasGraph(tk.Canvas):
def __init__(self, master, core_grpc, cnf=None, **kwargs): def __init__(self, master, core_grpc, cnf=None, **kwargs):
if cnf is None: if cnf is None:
@ -35,6 +41,7 @@ class CanvasGraph(tk.Canvas):
self.drawing_edge = None self.drawing_edge = None
self.grid = None self.grid = None
self.meters_per_pixel = 1.5 self.meters_per_pixel = 1.5
self.canvas_action = CanvasAction(master, self)
self.setup_menus() self.setup_menus()
self.setup_bindings() self.setup_bindings()
self.draw_grid() self.draw_grid()
@ -42,23 +49,33 @@ class CanvasGraph(tk.Canvas):
self.helper = GraphHelper(self, core_grpc) self.helper = GraphHelper(self, core_grpc)
self.throughput_draw = Throughput(self, core_grpc) self.throughput_draw = Throughput(self, core_grpc)
self.wireless_draw = WirelessConnection(self, core_grpc) self.wireless_draw = WirelessConnection(self, core_grpc)
self.is_node_context_opened = False
def setup_menus(self): def setup_menus(self):
self.node_context = tk.Menu(self.master) self.node_context = tk.Menu(self.master)
self.node_context.add_command(label="One") self.node_context.add_command(
self.node_context.add_command(label="Two") label="Configure", command=self.canvas_action.display_node_configuration
self.node_context.add_command(label="Three") )
self.node_context.add_command(label="Select adjacent")
self.node_context.add_command(label="Create link to")
self.node_context.add_command(label="Assign to")
self.node_context.add_command(label="Move to")
self.node_context.add_command(label="Cut")
self.node_context.add_command(label="Copy")
self.node_context.add_command(label="Paste")
self.node_context.add_command(label="Delete")
self.node_context.add_command(label="Hide")
self.node_context.add_command(label="Services")
def canvas_reset_and_redraw(self, new_grpc): def canvas_reset_and_redraw(self, session):
""" """
Reset the private variables CanvasGraph object, redraw nodes given the new grpc Reset the private variables CanvasGraph object, redraw nodes given the new grpc
client. client.
:param new_grpc: :param core.api.grpc.core_pb2.Session session: session to draw
:return: :return: nothing
""" """
# delete any existing drawn items # delete any existing drawn items
# self.delete_components()
self.helper.delete_canvas_components() self.helper.delete_canvas_components()
# set the private variables to default value # set the private variables to default value
@ -70,11 +87,7 @@ class CanvasGraph(tk.Canvas):
self.nodes = {} self.nodes = {}
self.edges = {} self.edges = {}
self.drawing_edge = None self.drawing_edge = None
# new grpc self.draw_existing_component(session)
self.core_grpc = new_grpc
print("grpah.py draw existing component")
self.draw_existing_component()
print(self.core_grpc.manager.edges)
def setup_bindings(self): def setup_bindings(self):
""" """
@ -123,7 +136,6 @@ class CanvasGraph(tk.Canvas):
for node in session.nodes: for node in session.nodes:
# peer to peer node is not drawn on the GUI # peer to peer node is not drawn on the GUI
if node.type != core_pb2.NodeType.PEER_TO_PEER: if node.type != core_pb2.NodeType.PEER_TO_PEER:
# draw nodes on the canvas # draw nodes on the canvas
image, name = Images.convert_type_and_model_to_image( image, name = Images.convert_type_and_model_to_image(
node.type, node.model node.type, node.model
@ -206,8 +218,6 @@ class CanvasGraph(tk.Canvas):
].interfaces.append(if2) ].interfaces.append(if2)
# lift the nodes so they on top of the links # lift the nodes so they on top of the links
# for i in core_id_to_canvas_id.values():
# self.lift(i)
for i in self.find_withtag("node"): for i in self.find_withtag("node"):
self.lift(i) self.lift(i)
@ -260,6 +270,10 @@ class CanvasGraph(tk.Canvas):
:param event: mouse event :param event: mouse event
:return: nothing :return: nothing
""" """
if self.is_node_context_opened:
self.node_context.unpost()
self.is_node_context_opened = False
else:
self.focus_set() self.focus_set()
self.selected = self.get_selected(event) self.selected = self.get_selected(event)
logging.debug(f"click release selected: {self.selected}") logging.debug(f"click release selected: {self.selected}")
@ -355,11 +369,17 @@ class CanvasGraph(tk.Canvas):
self.coords(self.drawing_edge.id, x1, y1, x2, y2) self.coords(self.drawing_edge.id, x1, y1, x2, y2)
def context(self, event): def context(self, event):
if not self.is_node_context_opened:
selected = self.get_selected(event) selected = self.get_selected(event)
nodes = self.find_withtag("node") nodes = self.find_withtag("node")
if selected in nodes: if selected in nodes:
logging.debug(f"node context: {selected}") logging.debug(f"node context: {selected}")
self.node_context.post(event.x_root, event.y_root) self.node_context.post(event.x_root, event.y_root)
self.canvas_action.node_to_show_config = self.nodes[selected]
self.is_node_context_opened = True
else:
self.node_context.unpost()
self.is_node_context_opened = False
def add_node(self, x, y, image, node_name): def add_node(self, x, y, image, node_name):
plot_id = self.find_all()[0] plot_id = self.find_all()[0]
@ -470,8 +490,15 @@ class CanvasNode:
if state == core_pb2.SessionState.RUNTIME: if state == core_pb2.SessionState.RUNTIME:
self.canvas.core_grpc.launch_terminal(node_id) self.canvas.core_grpc.launch_terminal(node_id)
else: else:
print("config table show up") self.canvas.canvas_action.display_configuration(self)
NodeConfig(self, self.image, self.node_type, self.name) # if self.node_type in CORE_NODES:
# self.canvas.canvas_action.node_to_show_config = self
# self.canvas.canvas_action.display_node_configuration()
# elif self.node_type in CORE_WIRED_NETWORK_NODES:
# return
# elif self.node_type in CORE_WIRELESS_NODE:
# return
# elif self
def update_coords(self): def update_coords(self):
self.x_coord, self.y_coord = self.canvas.coords(self.id) self.x_coord, self.y_coord = self.canvas.coords(self.id)

View file

@ -7,6 +7,7 @@ import logging
from core.api.grpc import core_pb2 from core.api.grpc import core_pb2
from coretk.coretocanvas import CoreToCanvasMapping from coretk.coretocanvas import CoreToCanvasMapping
from coretk.interface import Interface, InterfaceManager from coretk.interface import Interface, InterfaceManager
from coretk.wlannodeconfig import WlanNodeConfig
link_layer_nodes = ["switch", "hub", "wlan", "rj45", "tunnel"] link_layer_nodes = ["switch", "hub", "wlan", "rj45", "tunnel"]
network_layer_nodes = ["router", "host", "PC", "mdr", "prouter", "OVS"] network_layer_nodes = ["router", "host", "PC", "mdr", "prouter", "OVS"]
@ -68,6 +69,7 @@ class GrpcManager:
# map tuple(core_node_id, interface_id) to and edge # map tuple(core_node_id, interface_id) to and edge
# self.node_id_and_interface_to_edge_token = {} # self.node_id_and_interface_to_edge_token = {}
self.core_mapping = CoreToCanvasMapping() self.core_mapping = CoreToCanvasMapping()
self.wlanconfig_management = WlanNodeConfig()
def update_preexisting_ids(self): def update_preexisting_ids(self):
""" """
@ -142,6 +144,10 @@ class GrpcManager:
logging.error("grpcmanagemeny.py INVALID node name") logging.error("grpcmanagemeny.py INVALID node name")
nid = self.get_id() nid = self.get_id()
create_node = Node(session_id, nid, node_type, node_model, x, y, name) create_node = Node(session_id, nid, node_type, node_model, x, y, name)
# set default configuration for wireless node
self.wlanconfig_management.set_default_config(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
@ -166,7 +172,6 @@ class GrpcManager:
# update the next available id # update the next available id
core_id = core_node.id core_id = core_node.id
print(core_id)
if self.id is None or core_id >= self.id: if self.id is None or core_id >= self.id:
self.id = core_id + 1 self.id = core_id + 1
self.preexisting.add(core_id) self.preexisting.add(core_id)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,91 @@
"""
node image modification
"""
import os
import tkinter as tk
from tkinter import filedialog
from PIL import Image, ImageTk
PATH = os.path.abspath(os.path.dirname(__file__))
ICONS_DIR = os.path.join(PATH, "icons")
class ImageModification:
def __init__(self, canvas, canvas_node, node_config):
"""
create an instance of ImageModification
:param coretk.graph.CanvasGraph canvas: canvas object
:param coretk.graph.CanvasNode canvas_node: node object
:param coretk.nodeconfigtable.NodeConfig node_config: node configuration object
"""
self.canvas = canvas
self.image = canvas_node.image
self.node_type = canvas_node.node_type
self.name = canvas_node.name
self.canvas_node = canvas_node
self.node_configuration = node_config
self.p_top = node_config.top
self.top = tk.Toplevel()
self.top.title(self.name + " image")
self.image_modification()
def open_icon_dir(self, toplevel, entry_text):
filename = filedialog.askopenfilename(
initialdir=ICONS_DIR,
title="Open",
filetypes=(
("images", "*.gif *.jpg *.png *.bmp *pcx *.tga ..."),
("All Files", "*"),
),
)
if len(filename) > 0:
img = Image.open(filename)
tk_img = ImageTk.PhotoImage(img)
lb = toplevel.grid_slaves(1, 0)[0]
lb.configure(image=tk_img)
lb.image = tk_img
entry_text.set(filename)
def click_apply(self, toplevel, entry_text):
imgfile = entry_text.get()
if imgfile:
img = Image.open(imgfile)
tk_img = ImageTk.PhotoImage(img)
f = self.p_top.grid_slaves(row=0, column=0)[0]
lb = f.grid_slaves(row=0, column=3)[0]
lb.configure(image=tk_img)
lb.image = tk_img
self.image = tk_img
self.node_configuration.image = tk_img
toplevel.destroy()
def image_modification(self):
f = tk.Frame(self.top)
entry_text = tk.StringVar()
image_file_label = tk.Label(f, text="Image file: ")
image_file_label.grid(row=0, column=0)
image_file_entry = tk.Entry(f, textvariable=entry_text, width=32, bg="white")
image_file_entry.grid(row=0, column=1)
image_file_button = tk.Button(
f, text="...", command=lambda: self.open_icon_dir(self.top, entry_text)
)
image_file_button.grid(row=0, column=2)
f.grid()
img = tk.Label(self.top, image=self.image)
img.grid()
f = tk.Frame(self.top)
apply_button = tk.Button(
f, text="Apply", command=lambda: self.click_apply(self.top, entry_text)
)
apply_button.grid(row=0, column=0)
apply_to_multiple_button = tk.Button(f, text="Apply to multiple...")
apply_to_multiple_button.grid(row=0, column=1)
cancel_button = tk.Button(f, text="Cancel", command=self.top.destroy)
cancel_button.grid(row=0, column=2)
f.grid()

View file

@ -46,7 +46,10 @@ class Images:
if node_type == core_pb2.NodeType.HUB: if node_type == core_pb2.NodeType.HUB:
return Images.get(ImageEnum.HUB), "hub" return Images.get(ImageEnum.HUB), "hub"
if node_type == core_pb2.NodeType.WIRELESS_LAN: if node_type == core_pb2.NodeType.WIRELESS_LAN:
return Images.get(ImageEnum.WLAN), "wlan" return Images.get(ImageEnum.WLAN.value), "wlan"
if node_type == core_pb2.NodeType.EMANE:
return Images.get(ImageEnum.EMANE.value), "emane"
if node_type == core_pb2.NodeType.RJ45: if node_type == core_pb2.NodeType.RJ45:
return Images.get(ImageEnum.RJ45), "rj45" return Images.get(ImageEnum.RJ45), "rj45"
if node_type == core_pb2.NodeType.TUNNEL: if node_type == core_pb2.NodeType.TUNNEL:
@ -78,6 +81,7 @@ class ImageEnum(Enum):
LINK = "link" LINK = "link"
HUB = "hub" HUB = "hub"
WLAN = "wlan" WLAN = "wlan"
EMANE = "emane"
RJ45 = "rj45" RJ45 = "rj45"
TUNNEL = "tunnel" TUNNEL = "tunnel"
OVAL = "oval" OVAL = "oval"

View file

@ -51,7 +51,7 @@ class InterfaceManager:
ipaddress.ip_network("10.0.0.0/12").subnets(prefixlen_diff=12) ipaddress.ip_network("10.0.0.0/12").subnets(prefixlen_diff=12)
) )
self.subnet_index = 0 self.subnet_index = 0
self.address_index = None self.address_index = 0
# self.network = ipaddress.ip_network("10.0.0.0/24") # self.network = ipaddress.ip_network("10.0.0.0/24")
# self.addresses = list(self.network.hosts()) # self.addresses = list(self.network.hosts())
@ -81,9 +81,9 @@ class InterfaceManager:
def new_subnet(self): def new_subnet(self):
self.network = self.core_subnets[self.subnet_index] self.network = self.core_subnets[self.subnet_index]
self.subnet_index = self.subnet_index + 1 # self.subnet_index = self.subnet_index + 1
self.addresses = list(self.network.hosts()) self.addresses = list(self.network.hosts())
self.address_index = 0 # self.address_index = 0
# def new_subnet(self): # def new_subnet(self):
# """ # """

View file

@ -326,7 +326,7 @@ class MenuAction:
self.application = application self.application = application
self.core_grpc = application.core_grpc self.core_grpc = application.core_grpc
def clean_nodes_links_and_set_configuarations(self): def prompt_save_running_session(self):
""" """
Prompt use to stop running session before application is closed Prompt use to stop running session before application is closed
@ -343,21 +343,13 @@ class MenuAction:
or state == core_pb2.SessionState.DEFINITION or state == core_pb2.SessionState.DEFINITION
): ):
grpc.delete_session() grpc.delete_session()
grpc.core.close()
# self.application.quit()
else: else:
msgbox = messagebox.askyesnocancel("stop", "Stop the running session?") msgbox = messagebox.askyesnocancel("stop", "Stop the running session?")
if msgbox or msgbox is False: if msgbox or msgbox is False:
if msgbox: if msgbox:
grpc.set_session_state("datacollect") grpc.stop_session()
grpc.delete_links()
grpc.delete_nodes()
grpc.delete_session() grpc.delete_session()
# else:
# grpc.set_session_state("definition")
grpc.core.close()
# self.application.quit()
def on_quit(self): def on_quit(self):
""" """
@ -365,7 +357,7 @@ class MenuAction:
:return: nothing :return: nothing
""" """
self.clean_nodes_links_and_set_configuarations() self.prompt_save_running_session()
# self.application.core_grpc.close() # self.application.core_grpc.close()
self.application.quit() self.application.quit()
@ -378,8 +370,6 @@ class MenuAction:
filetypes=(("EmulationScript XML files", "*.xml"), ("All files", "*")), filetypes=(("EmulationScript XML files", "*.xml"), ("All files", "*")),
defaultextension=".xml", defaultextension=".xml",
) )
# with open("prev_saved_xml.txt", "a") as file:
# file.write(file_path + "\n")
grpc.save_xml(file_path) grpc.save_xml(file_path)
def file_open_xml(self): def file_open_xml(self):
@ -391,30 +381,12 @@ class MenuAction:
filetypes=(("EmulationScript XML File", "*.xml"), ("All Files", "*")), filetypes=(("EmulationScript XML File", "*.xml"), ("All Files", "*")),
) )
# clean up before opening a new session # clean up before opening a new session
self.clean_nodes_links_and_set_configuarations() self.prompt_save_running_session()
# grpc = CoreGrpc(self.application.master) self.application.core_grpc.open_xml(file_path)
# grpc.core.connect()
core_grpc = self.application.core_grpc
core_grpc.core.connect()
# session_id = core_grpc.open_xml(file_path)
# core_grpc.session_id = session_id
core_grpc.open_xml(file_path)
# print("Print session state")
# print(grpc.get_session_state())
self.application.canvas.canvas_reset_and_redraw(core_grpc)
# Todo might not need # Todo might not need
self.application.core_grpc = core_grpc # self.application.core_editbar.destroy_children_widgets()
# self.application.core_editbar.create_toolbar()
self.application.core_editbar.destroy_children_widgets()
self.application.core_editbar.create_toolbar()
# self.application.is_open_xml = False
# self.application.core_editbar.create_runtime_toolbar()
# self.application.canvas.draw_existing_component()
# t1 = time.clock()
# print(t1 - t0)
def canvas_size_and_scale(self): def canvas_size_and_scale(self):
self.application.size_and_scale = SizeAndScale(self.application) self.application.size_and_scale = SizeAndScale(self.application)

View file

@ -8,6 +8,9 @@ from tkinter import filedialog
from PIL import Image, ImageTk from PIL import Image, ImageTk
from coretk.imagemodification import ImageModification
from coretk.nodeservice import NodeServices
PATH = os.path.abspath(os.path.dirname(__file__)) PATH = os.path.abspath(os.path.dirname(__file__))
ICONS_DIR = os.path.join(PATH, "icons") ICONS_DIR = os.path.join(PATH, "icons")
@ -16,14 +19,21 @@ DEFAULTNODES = ["router", "host", "PC"]
class NodeConfig: class NodeConfig:
def __init__(self, canvas_node, image, node_type, name): def __init__(self, canvas, canvas_node):
self.image = image """
self.node_type = node_type create an instance of node configuration
self.name = name
:param coretk.graph.CanvasGraph canvas: canvas object
:param coretk.graph.CanvasNode canvas_node: canvas node object
"""
self.canvas = canvas
self.image = canvas_node.image
self.node_type = canvas_node.node_type
self.name = canvas_node.name
self.canvas_node = canvas_node self.canvas_node = canvas_node
self.top = tk.Toplevel() self.top = tk.Toplevel()
self.top.title(node_type + " configuration") self.top.title(canvas_node.node_type + " configuration")
self.namevar = tk.StringVar(self.top, value="default name") self.namevar = tk.StringVar(self.top, value="default name")
self.name_and_image_definition() self.name_and_image_definition()
self.type_and_service_definition() self.type_and_service_definition()
@ -58,65 +68,69 @@ class NodeConfig:
toplevel.destroy() toplevel.destroy()
def img_modification(self): def img_modification(self):
print("image modification")
t = tk.Toplevel() t = tk.Toplevel()
t.title(self.name + " image") t.title(self.name + " image")
f = tk.Frame(t) f = tk.Frame(t)
entry_text = tk.StringVar() entry_text = tk.StringVar()
image_file_label = tk.Label(f, text="Image file: ") image_file_label = tk.Label(f, text="Image file: ")
image_file_label.pack(side=tk.LEFT, padx=2, pady=2) image_file_label.grid(row=0, column=0)
image_file_entry = tk.Entry(f, textvariable=entry_text, width=60) image_file_entry = tk.Entry(f, textvariable=entry_text, width=32, bg="white")
image_file_entry.pack(side=tk.LEFT, padx=2, pady=2) image_file_entry.grid(row=0, column=1)
image_file_button = tk.Button( image_file_button = tk.Button(
f, text="...", command=lambda: self.open_icon_dir(t, entry_text) f, text="...", command=lambda: self.open_icon_dir(t, entry_text)
) )
image_file_button.pack(side=tk.LEFT, padx=2, pady=2) image_file_button.grid(row=0, column=2)
f.grid(sticky=tk.W + tk.E) f.grid()
img = tk.Label(t, image=self.image) img = tk.Label(t, image=self.image)
img.grid(sticky=tk.W + tk.E) img.grid()
f = tk.Frame(t) f = tk.Frame(t)
apply_button = tk.Button( apply_button = tk.Button(
f, text="Apply", command=lambda: self.click_apply(t, entry_text) f, text="Apply", command=lambda: self.click_apply(t, entry_text)
) )
apply_button.pack(side=tk.LEFT, padx=2, pady=2) apply_button.grid(row=0, column=0)
apply_to_multiple_button = tk.Button(f, text="Apply to multiple...") apply_to_multiple_button = tk.Button(f, text="Apply to multiple...")
apply_to_multiple_button.pack(side=tk.LEFT, padx=2, pady=2) apply_to_multiple_button.grid(row=0, column=1)
cancel_button = tk.Button(f, text="Cancel", command=t.destroy) cancel_button = tk.Button(f, text="Cancel", command=t.destroy)
cancel_button.pack(side=tk.LEFT, padx=2, pady=2) cancel_button.grid(row=0, column=2)
f.grid(sticky=tk.E + tk.W) f.grid()
def name_and_image_definition(self): def name_and_image_definition(self):
name_label = tk.Label(self.top, text="Node name: ") f = tk.Frame(self.top, bg="#d9d9d9")
name_label.grid() name_label = tk.Label(f, text="Node name: ", bg="#d9d9d9")
name_entry = tk.Entry(self.top, textvariable=self.namevar) name_label.grid(padx=2, pady=2)
name_entry.grid(row=0, column=1) name_entry = tk.Entry(f, textvariable=self.namevar)
name_entry.grid(row=0, column=1, padx=2, pady=2)
core_button = tk.Button(self.top, text="None") core_button = tk.Button(f, text="None")
core_button.grid(row=0, column=2) core_button.grid(row=0, column=2, padx=2, pady=2)
img_button = tk.Button( img_button = tk.Button(
self.top, f,
image=self.image, image=self.image,
width=40, width=40,
height=40, height=40,
command=self.img_modification, command=lambda: ImageModification(self.canvas, self.canvas_node, self),
bg="#d9d9d9",
) )
img_button.grid(row=0, column=3) img_button.grid(row=0, column=3, padx=4, pady=4)
f.grid(padx=4, pady=4)
def type_and_service_definition(self): def type_and_service_definition(self):
f = tk.Frame(self.top) f = tk.Frame(self.top)
type_label = tk.Label(f, text="Type: ") type_label = tk.Label(f, text="Type: ")
type_label.pack(side=tk.LEFT) type_label.grid(row=0, column=0)
type_button = tk.Button(f, text="None") type_button = tk.Button(f, text="None")
type_button.pack(side=tk.LEFT) type_button.grid(row=0, column=1)
service_button = tk.Button(f, text="Services...") service_button = tk.Button(
service_button.pack(side=tk.LEFT) f, text="Services...", command=lambda: NodeServices()
)
service_button.grid(row=0, column=2)
f.grid(row=1, column=1, columnspan=2, sticky=tk.W) f.grid(padx=2, pady=2)
def config_apply(self): def config_apply(self):
""" """
@ -140,10 +154,10 @@ class NodeConfig:
def select_definition(self): def select_definition(self):
f = tk.Frame(self.top) f = tk.Frame(self.top)
apply_button = tk.Button(f, text="Apply", command=self.config_apply) apply_button = tk.Button(f, text="Apply", command=self.config_apply)
apply_button.pack(side=tk.LEFT) apply_button.grid(row=0, column=0)
cancel_button = tk.Button(f, text="Cancel", command=self.config_cancel) cancel_button = tk.Button(f, text="Cancel", command=self.config_cancel)
cancel_button.pack(side=tk.LEFT) cancel_button.grid(row=0, column=1)
f.grid(row=3, column=1, sticky=tk.W) f.grid()
def network_node_config(self): def network_node_config(self):
self.name_and_image_definition() self.name_and_image_definition()

View file

@ -0,0 +1,195 @@
"""
core node services
"""
import tkinter as tk
from tkinter import messagebox
CORE_DEFAULT_GROUPS = ["EMANE", "FRR", "ProtoSvc", "Quagga", "Security", "Utility"]
DEFAULT_GROUP_RADIO_VALUE = {
"EMANE": 1,
"FRR": 2,
"ProtoSvc": 3,
"Quagga": 4,
"Security": 5,
"Utility": 6,
}
DEFAULT_GROUP_SERVICES = {
"EMANE": ["transportd"],
"FRR": [
"FRRBable",
"FRRBGP",
"FRROSPFv2",
"FRROSPFv3",
"FRRpimd",
"FRRRIP",
"FRRRIPNG",
"FRRzebra",
],
"ProtoSvc": ["MGEN_Sink", "MgenActor", "SMF"],
"Quagga": [
"Babel",
"BGP",
"OSPFv2",
"OSPFv3",
"OSPFv3MDR",
"RIP",
"RIPNG",
"Xpimd",
"zebra",
],
"Security": ["Firewall", "IPsec", "NAT", "VPNClient", "VPNServer"],
"Utility": [
"atd",
"DefaultMulticastRoute",
"DefaultRoute",
"DHCP",
"DHCPClient",
"FTP",
"HTTP",
"IPForward ",
"pcap",
"radvd",
"SSH",
"StaticRoute",
"ucarp",
"UserDefined",
],
}
class NodeServices:
def __init__(self):
self.core_groups = []
self.service_to_config = None
self.top = tk.Toplevel()
self.top.title("Node services")
self.config_frame = tk.Frame(self.top)
self.config_frame.grid()
self.draw_group()
self.group_services()
self.current_services()
self.node_service_options()
def display_group_services(self, group_name):
group_services_frame = self.config_frame.grid_slaves(row=0, column=1)[0]
listbox = group_services_frame.grid_slaves(row=1, column=0)[0]
listbox.delete(0, tk.END)
for s in DEFAULT_GROUP_SERVICES[group_name]:
listbox.insert(tk.END, s)
for i in range(listbox.size()):
listbox.itemconfig(i, selectbackground="white")
def group_select(self, event):
listbox = event.widget
cur_selection = listbox.curselection()
if cur_selection:
s = listbox.get(listbox.curselection())
self.display_group_services(s)
def draw_group(self):
"""
draw the group tab
:return: nothing
"""
f = tk.Frame(self.config_frame)
lbl = tk.Label(f, text="Group")
lbl.grid()
sb = tk.Scrollbar(f, orient=tk.VERTICAL)
sb.grid(row=1, column=1, sticky=tk.S + tk.N)
listbox = tk.Listbox(
f,
selectmode=tk.SINGLE,
yscrollcommand=sb.set,
relief=tk.FLAT,
highlightbackground="#b3b3b3",
highlightcolor="#b3b3b3",
highlightthickness=0.5,
bd=0,
)
for grp in CORE_DEFAULT_GROUPS:
listbox.insert(tk.END, grp)
for i in range(0, listbox.size()):
listbox.itemconfig(i, selectbackground="white")
listbox.grid(row=1, column=0)
sb.config(command=listbox.yview)
f.grid(padx=3, pady=3)
listbox.bind("<<ListboxSelect>>", self.group_select)
def group_service_select(self, event):
print("select group service")
listbox = event.widget
cur_selection = listbox.curselection()
if cur_selection:
s = listbox.get(listbox.curselection())
self.service_to_config = s
else:
self.service_to_config = None
def group_services(self):
f = tk.Frame(self.config_frame)
lbl = tk.Label(f, text="Group services")
lbl.grid()
sb = tk.Scrollbar(f, orient=tk.VERTICAL)
sb.grid(row=1, column=1, sticky=tk.S + tk.N)
listbox = tk.Listbox(
f,
selectmode=tk.SINGLE,
yscrollcommand=sb.set,
relief=tk.FLAT,
highlightbackground="#b3b3b3",
highlightcolor="#b3b3b3",
highlightthickness=0.5,
bd=0,
)
listbox.grid(row=1, column=0)
sb.config(command=listbox.yview)
f.grid(padx=3, pady=3, row=0, column=1)
listbox.bind("<<ListboxSelect>>", self.group_service_select)
def current_services(self):
f = tk.Frame(self.config_frame)
lbl = tk.Label(f, text="Current services")
lbl.grid()
sb = tk.Scrollbar(f, orient=tk.VERTICAL)
sb.grid(row=1, column=1, sticky=tk.S + tk.N)
listbox = tk.Listbox(
f,
selectmode=tk.MULTIPLE,
yscrollcommand=sb.set,
relief=tk.FLAT,
highlightbackground="#b3b3b3",
highlightcolor="#b3b3b3",
highlightthickness=0.5,
bd=0,
)
listbox.grid(row=1, column=0)
sb.config(command=listbox.yview)
f.grid(padx=3, pady=3, row=0, column=2)
def config_service(self):
if self.service_to_config is None:
messagebox.showinfo("CORE info", "Choose a service to configure.")
else:
print(self.service_to_config)
def node_service_options(self):
f = tk.Frame(self.top)
b = tk.Button(f, text="Connfigure", command=self.config_service)
b.grid(row=0, column=0)
b = tk.Button(f, text="Apply")
b.grid(row=0, column=1)
b = tk.Button(f, text="Cancel", command=self.top.destroy)
b.grid(row=0, column=2)
f.grid(sticky=tk.E)

View file

@ -0,0 +1,299 @@
"""
wlan configuration
"""
import tkinter as tk
from functools import partial
from coretk.imagemodification import ImageModification
class WlanConfiguration:
def __init__(self, canvas, canvas_node, config):
"""
create an instance of WlanConfiguration
:param coretk.grpah.CanvasGraph canvas: canvas object
:param coretk.graph.CanvasNode canvas_node: canvas node object
"""
self.canvas = canvas
self.image = canvas_node.image
self.node_type = canvas_node.node_type
self.name = canvas_node.name
self.canvas_node = canvas_node
self.top = tk.Toplevel()
self.top.title("wlan configuration")
self.node_name = tk.StringVar()
# self.range_var = tk.DoubleVar()
# self.range_var.set(275.0)
self.config = config
self.range_var = tk.StringVar()
self.range_var.set(config["basic_range"])
# self.bandwidth_var = tk.IntVar()
self.bandwidth_var = tk.StringVar()
self.bandwidth_var.set(config["bandwidth"])
self.delay_var = tk.StringVar()
self.image_modification()
self.wlan_configuration()
self.subnet()
self.wlan_options()
self.config_option()
def image_modification(self):
"""
draw image modification part
:return: nothing
"""
f = tk.Frame(self.top, bg="#d9d9d9")
lbl = tk.Label(f, text="Node name: ", bg="#d9d9d9")
lbl.grid(row=0, column=0, padx=3, pady=3)
e = tk.Entry(f, textvariable=self.node_name, bg="white")
e.grid(row=0, column=1, padx=3, pady=3)
b = tk.Button(f, text="None")
b.grid(row=0, column=2, padx=3, pady=3)
b = tk.Button(
f,
image=self.image,
command=lambda: ImageModification(
canvas=self.canvas, canvas_node=self.canvas_node, node_config=self
),
)
b.grid(row=0, column=3, padx=3, pady=3)
f.grid(padx=2, pady=2, ipadx=2, ipady=2)
def create_string_var(self, val):
"""
create string variable for convenience
:param str val: text value
:return: nothing
"""
v = tk.StringVar()
v.set(val)
return v
def scrollbar_command(self, entry_widget, delta, event):
"""
change text in entry based on scrollbar action (click up or down)
:param tkinter.Entry entry_widget: entry needed for changing text
:param int or float delta: the amount to change
:param event: scrollbar event
:return: nothing
"""
try:
value = int(entry_widget.get())
except ValueError:
value = float(entry_widget.get())
entry_widget.delete(0, tk.END)
if event == "-1":
entry_widget.insert(tk.END, str(round(value + delta, 1)))
elif event == "1":
entry_widget.insert(tk.END, str(round(value - delta, 1)))
def wlan_configuration(self):
"""
create wireless configuration table
:return: nothing
"""
lbl = tk.Label(self.top, text="Wireless")
lbl.grid(sticky=tk.W, padx=3, pady=3)
f = tk.Frame(
self.top,
highlightbackground="#b3b3b3",
highlightcolor="#b3b3b3",
highlightthickness=0.5,
bd=0,
bg="#d9d9d9",
)
lbl = tk.Label(
f,
text="The basic range model calculates on/off connectivity based on pixel distance between nodes.",
bg="#d9d9d9",
)
lbl.grid(padx=4, pady=4)
f1 = tk.Frame(f, bg="#d9d9d9")
lbl = tk.Label(f1, text="Range: ", bg="#d9d9d9")
lbl.grid(row=0, column=0)
e = tk.Entry(
f1,
textvariable=self.create_string_var(self.config["basic_range"]),
width=5,
bg="white",
)
e.grid(row=0, column=1)
lbl = tk.Label(f1, text="Bandwidth (bps): ", bg="#d9d9d9")
lbl.grid(row=0, column=2)
f11 = tk.Frame(f1, bg="#d9d9d9")
sb = tk.Scrollbar(f11, orient=tk.VERTICAL)
e = tk.Entry(
f11,
textvariable=self.create_string_var(self.config["bandwidth"]),
width=10,
bg="white",
)
sb.config(command=partial(self.scrollbar_command, e, 1000000))
e.grid()
sb.grid(row=0, column=1)
f11.grid(row=0, column=3)
# e = tk.Entry(f1, textvariable=self.bandwidth_var, width=10)
# e.grid(row=0, column=4)
f1.grid(sticky=tk.W, padx=4, pady=4)
f2 = tk.Frame(f, bg="#d9d9d9")
lbl = tk.Label(f2, text="Delay (us): ", bg="#d9d9d9")
lbl.grid(row=0, column=0)
f21 = tk.Frame(f2, bg="#d9d9d9")
sb = tk.Scrollbar(f21, orient=tk.VERTICAL)
e = tk.Entry(
f21, textvariable=self.create_string_var(self.config["delay"]), bg="white"
)
sb.config(command=partial(self.scrollbar_command, e, 5000))
e.grid()
sb.grid(row=0, column=1)
f21.grid(row=0, column=1)
lbl = tk.Label(f2, text="Loss (%): ", bg="#d9d9d9")
lbl.grid(row=0, column=2)
f22 = tk.Frame(f2, bg="#d9d9d9")
sb = tk.Scrollbar(f22, orient=tk.VERTICAL)
e = tk.Entry(
f22, textvariable=self.create_string_var(self.config["error"]), bg="white"
)
sb.config(command=partial(self.scrollbar_command, e, 0.1))
e.grid()
sb.grid(row=0, column=1)
f22.grid(row=0, column=3)
# e = tk.Entry(f2, textvariable=self.create_string_var(0))
# e.grid(row=0, column=3)
f2.grid(sticky=tk.W, padx=4, pady=4)
f3 = tk.Frame(f, bg="#d9d9d9")
lbl = tk.Label(f3, text="Jitter (us): ", bg="#d9d9d9")
lbl.grid()
f31 = tk.Frame(f3, bg="#d9d9d9")
sb = tk.Scrollbar(f31, orient=tk.VERTICAL)
e = tk.Entry(
f31, textvariable=self.create_string_var(self.config["jitter"]), bg="white"
)
sb.config(command=partial(self.scrollbar_command, e, 5000))
e.grid()
sb.grid(row=0, column=1)
f31.grid(row=0, column=1)
f3.grid(sticky=tk.W, padx=4, pady=4)
f.grid(padx=3, pady=3)
def subnet(self):
"""
create the entries for ipv4 subnet and ipv6 subnet
:return: nothing
"""
f = tk.Frame(self.top)
f1 = tk.Frame(f)
lbl = tk.Label(f1, text="IPv4 subnet")
lbl.grid()
e = tk.Entry(f1, width=30, bg="white", textvariable=self.create_string_var(""))
e.grid(row=0, column=1)
f1.grid()
f2 = tk.Frame(f)
lbl = tk.Label(f2, text="IPv6 subnet")
lbl.grid()
e = tk.Entry(f2, width=30, bg="white", textvariable=self.create_string_var(""))
e.grid(row=0, column=1)
f2.grid()
f.grid(sticky=tk.W, padx=3, pady=3)
def wlan_options(self):
"""
create wireless node options
:return:
"""
f = tk.Frame(self.top)
b = tk.Button(f, text="ns-2 mobility script...")
b.pack(side=tk.LEFT, padx=1)
b = tk.Button(f, text="Link to all routers")
b.pack(side=tk.LEFT, padx=1)
b = tk.Button(f, text="Choose WLAN members")
b.pack(side=tk.LEFT, padx=1)
f.grid(sticky=tk.W)
def wlan_config_apply(self):
"""
retrieve user's wlan configuration and store the new configuration values
:return: nothing
"""
config_frame = self.top.grid_slaves(row=2, column=0)[0]
range_and_bandwidth_frame = config_frame.grid_slaves(row=1, column=0)[0]
range_val = range_and_bandwidth_frame.grid_slaves(row=0, column=1)[0].get()
bandwidth = (
range_and_bandwidth_frame.grid_slaves(row=0, column=3)[0]
.grid_slaves(row=0, column=0)[0]
.get()
)
delay_and_loss_frame = config_frame.grid_slaves(row=2, column=0)[0]
delay = (
delay_and_loss_frame.grid_slaves(row=0, column=1)[0]
.grid_slaves(row=0, column=0)[0]
.get()
)
loss = (
delay_and_loss_frame.grid_slaves(row=0, column=3)[0]
.grid_slaves(row=0, column=0)[0]
.get()
)
jitter_frame = config_frame.grid_slaves(row=3, column=0)[0]
jitter_val = (
jitter_frame.grid_slaves(row=0, column=1)[0]
.grid_slaves(row=0, column=0)[0]
.get()
)
# set wireless node configuration here
wlanconfig_manager = self.canvas.grpc_manager.wlanconfig_management
wlanconfig_manager.set_custom_config(
node_id=self.canvas_node.core_id,
range=range_val,
bandwidth=bandwidth,
jitter=jitter_val,
delay=delay,
error=loss,
)
self.top.destroy()
def config_option(self):
"""
create node configuration options
:return: nothing
"""
f = tk.Frame(self.top, bg="#d9d9d9")
b = tk.Button(f, text="Apply", bg="#d9d9d9", command=self.wlan_config_apply)
b.grid(padx=2, pady=2)
b = tk.Button(f, text="Cancel", bg="#d9d9d9", command=self.top.destroy)
b.grid(row=0, column=1, padx=2, pady=2)
f.grid(padx=4, pady=4)

View file

@ -0,0 +1,29 @@
"""
wireless node configuration for all the wireless node
"""
from collections import OrderedDict
from core.api.grpc import core_pb2
class WlanNodeConfig:
def __init__(self):
# maps node id to wlan configuration
self.configurations = {}
def set_default_config(self, node_type, node_id):
if node_type == core_pb2.NodeType.WIRELESS_LAN:
config = OrderedDict()
config["basic_range"] = "275"
config["bandwidth"] = "54000000"
config["jitter"] = "0"
config["delay"] = "20000"
config["error"] = "0"
self.configurations[node_id] = config
def set_custom_config(self, node_id, range, bandwidth, jitter, delay, error):
self.configurations[node_id]["basic_range"] = range
self.configurations[node_id]["bandwidth"] = bandwidth
self.configurations[node_id]["jitter"] = jitter
self.configurations[node_id]["delay"] = delay
self.configurations[node_id]["error"] = error