diff --git a/coretk/coretk/coreclient.py b/coretk/coretk/coreclient.py index 5369b829..564c13fe 100644 --- a/coretk/coretk/coreclient.py +++ b/coretk/coretk/coreclient.py @@ -3,11 +3,11 @@ Incorporate grpc into python tkinter GUI """ import logging import os -from collections import OrderedDict from core.api.grpc import client, core_pb2 from coretk.coretocanvas import CoreToCanvasMapping from coretk.dialogs.sessions import SessionsDialog +from coretk.emaneodelnodeconfig import EmaneModelNodeConfig from coretk.images import Images from coretk.interface import Interface, InterfaceManager from coretk.mobilitynodeconfig import MobilityNodeConfig @@ -102,6 +102,7 @@ class CoreClient: self.core_mapping = CoreToCanvasMapping() self.wlanconfig_management = WlanNodeConfig() self.mobilityconfig_management = MobilityNodeConfig() + self.emaneconfig_management = EmaneModelNodeConfig(app) self.emane_config = None def read_config(self): @@ -189,6 +190,8 @@ class CoreClient: logging.info("emane config: %s", response) self.emane_config = response.config + # get emane model config + # determine next node id and reusable nodes max_id = 1 for node in session.nodes: @@ -321,6 +324,8 @@ class CoreClient: hooks=list(self.hooks.values()), wlan_configs=wlan_configs, emane_config=emane_config, + emane_model_configs=emane_model_configs, + mobility_configs=mobility_configs, ) logging.debug("Start session %s, result: %s", self.session_id, response.result) @@ -328,22 +333,22 @@ class CoreClient: response = self.client.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): - """ - Grpc client request add link - - :param int session_id: session id - :param int id1: node 1 core id - :param core_pb2.NodeType type1: node 1 core node type - :param int id2: node 2 core id - :param core_pb2.NodeType type2: node 2 core node type - :return: nothing - """ - if1 = self.create_interface(type1, edge.interface_1) - if2 = self.create_interface(type2, edge.interface_2) - response = self.client.add_link(self.session_id, id1, id2, if1, if2) - logging.info("created link: %s", response) + # # TODO no need, might get rid of this + # def add_link(self, id1, id2, type1, type2, edge): + # """ + # Grpc client request add link + # + # :param int session_id: session id + # :param int id1: node 1 core id + # :param core_pb2.NodeType type1: node 1 core node type + # :param int id2: node 2 core id + # :param core_pb2.NodeType type2: node 2 core node type + # :return: nothing + # """ + # if1 = self.create_interface(type1, edge.interface_1) + # if2 = self.create_interface(type2, edge.interface_2) + # response = self.client.add_link(self.session_id, id1, id2, if1, if2) + # logging.info("created link: %s", response) def launch_terminal(self, node_id): response = self.client.get_node_terminal(self.session_id, node_id) @@ -406,22 +411,22 @@ class CoreClient: else: return self.reusable.pop(0) - def add_node(self, node_type, model, x, y, name, node_id): - position = core_pb2.Position(x=x, y=y) - node = core_pb2.Node(id=node_id, type=node_type, position=position, model=model) - self.node_ids.append(node_id) - response = self.client.add_node(self.session_id, node) - logging.info("created node: %s", response) - if node_type == core_pb2.NodeType.WIRELESS_LAN: - d = OrderedDict() - d["basic_range"] = "275" - d["bandwidth"] = "54000000" - d["jitter"] = "0" - d["delay"] = "20000" - d["error"] = "0" - r = self.client.set_wlan_config(self.session_id, node_id, d) - logging.debug("set wlan config %s", r) - return response.node_id + # def add_node(self, node_type, model, x, y, name, node_id): + # position = core_pb2.Position(x=x, y=y) + # node = core_pb2.Node(id=node_id, type=node_type, position=position, model=model) + # self.node_ids.append(node_id) + # response = self.client.add_node(self.session_id, node) + # logging.info("created node: %s", response) + # if node_type == core_pb2.NodeType.WIRELESS_LAN: + # d = OrderedDict() + # d["basic_range"] = "275" + # d["bandwidth"] = "54000000" + # d["jitter"] = "0" + # d["delay"] = "20000" + # d["error"] = "0" + # r = self.client.set_wlan_config(self.session_id, node_id, d) + # logging.debug("set wlan config %s", r) + # return response.node_id def add_graph_node(self, session_id, canvas_id, x, y, name): """ @@ -449,6 +454,8 @@ class CoreClient: node_type = core_pb2.NodeType.EMANE elif name == "tunnel": node_type = core_pb2.NodeType.TUNNEL + elif name == "emane": + node_type = core_pb2.NodeType.EMANE elif name in network_layer_nodes: node_type = core_pb2.NodeType.DEFAULT node_model = name @@ -461,6 +468,10 @@ class CoreClient: self.wlanconfig_management.set_default_config(node_type, nid) self.mobilityconfig_management.set_default_configuration(node_type, nid) + # set default emane configuration for emane node + if node_type == core_pb2.NodeType.EMANE: + self.emaneconfig_management.set_default_config(nid) + self.nodes[canvas_id] = create_node self.core_mapping.map_core_id_to_canvas_id(nid, canvas_id) logging.debug( @@ -617,44 +628,50 @@ class CoreClient: :return: nothing """ + node_one = self.nodes[canvas_id_1] + node_two = self.nodes[canvas_id_2] if canvas_id_1 in self.nodes and canvas_id_2 in self.nodes: edge = Edge( session_id, - self.nodes[canvas_id_1].node_id, - self.nodes[canvas_id_1].type, - self.nodes[canvas_id_2].node_id, - self.nodes[canvas_id_2].type, + node_one.node_id, + node_one.type, + node_two.node_id, + node_two.type, ) self.edges[token] = edge src_interface, dst_interface = self.create_edge_interface( edge, canvas_id_1, canvas_id_2 ) - node_one_id = self.nodes[canvas_id_1].node_id - node_two_id = self.nodes[canvas_id_2].node_id + node_one_id = node_one.node_id + node_two_id = node_two.node_id # provide a way to get an edge from a core node and an interface id if src_interface is not None: self.core_mapping.map_node_and_interface_to_canvas_edge( node_one_id, src_interface.id, token ) - logging.debug( - "map node id %s, interface_id %s to edge token %s", - node_one_id, - src_interface.id, - token, - ) if dst_interface is not None: self.core_mapping.map_node_and_interface_to_canvas_edge( node_two_id, dst_interface.id, token ) - logging.debug( - "map node id %s, interface_id %s to edge token %s", - node_two_id, - dst_interface.id, - token, - ) - logging.debug("Adding edge to grpc manager...") + 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, dst_interface.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, src_interface.id + ) + else: logging.error("grpcmanagement.py INVALID CANVAS NODE ID") diff --git a/coretk/coretk/coretoolbarhelp.py b/coretk/coretk/coretoolbarhelp.py index 915d3b80..c650a5bc 100644 --- a/coretk/coretk/coretoolbarhelp.py +++ b/coretk/coretk/coretoolbarhelp.py @@ -34,14 +34,6 @@ class CoreToolbarHelp: for edge in self.app.core.edges.values(): interface_one = self.app.core.create_interface(edge.type1, edge.interface_1) interface_two = self.app.core.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, @@ -80,20 +72,41 @@ class CoreToolbarHelp: configs.append(cnf) return configs + def get_emane_configuration_list(self): + """ + form a list of emane configuration for the nodes + + :return: nothing + """ + configs = [] + manager_configs = self.app.core.emaneconfig_management.configurations + for key, value in manager_configs.items(): + config = {x: value[1][x].value for x in value[1]} + configs.append( + core_pb2.EmaneModelConfig( + node_id=key[0], interface_id=key[1], model=value[0], config=config + ) + ) + return configs + def gui_start_session(self): nodes = self.get_node_list() links = self.get_link_list() wlan_configs = self.get_wlan_configuration_list() mobility_configs = self.get_mobility_configuration_list() - # get emane config + # get emane config (global configuration) pb_emane_config = self.app.core.emane_config emane_config = {x: pb_emane_config[x].value for x in pb_emane_config} + # get emane configuration list + emane_model_configs = self.get_emane_configuration_list() + self.app.core.start_session( nodes, links, wlan_configs=wlan_configs, mobility_configs=mobility_configs, emane_config=emane_config, + emane_model_configs=emane_model_configs, ) diff --git a/coretk/coretk/dialogs/emaneconfig.py b/coretk/coretk/dialogs/emaneconfig.py index d90a970c..6950dc10 100644 --- a/coretk/coretk/dialogs/emaneconfig.py +++ b/coretk/coretk/dialogs/emaneconfig.py @@ -131,6 +131,11 @@ class EmaneConfiguration(Dialog): response, ) + # store the change locally + self.app.core.emaneconfig_management.set_custom_emane_cloud_config( + self.canvas_node.core_id, "emane_" + model_name + ) + self.emane_model_dialog.destroy() def draw_model_options(self): diff --git a/coretk/coretk/emaneodelnodeconfig.py b/coretk/coretk/emaneodelnodeconfig.py new file mode 100644 index 00000000..e3a9cc33 --- /dev/null +++ b/coretk/coretk/emaneodelnodeconfig.py @@ -0,0 +1,78 @@ +""" +emane model configurations +""" +import logging + + +class EmaneModelNodeConfig: + def __init__(self, app): + """ + create an instance for EmaneModelNodeConfig + + :param app: application + """ + # dict(tuple(node_id, interface_id, model) : config) + self.configurations = {} + + # dict(int, list(int)) stores emane node maps to mdr nodes that are linked to that emane node + self.links = {} + + self.app = app + + def set_default_config(self, node_id): + """ + set a default emane configuration for a newly created emane + + :param int node_id: node id + :return: nothing + """ + session_id = self.app.core.session_id + client = self.app.core.client + default_emane_model = client.get_emane_models(session_id).models[0] + response = client.get_emane_model_config( + session_id, node_id, default_emane_model + ) + logging.info( + "emanemodelnodeconfig.py get emane model config (%s), result: %s", + node_id, + response, + ) + self.configurations[tuple([node_id, None])] = tuple( + [default_emane_model, response.config] + ) + self.links[node_id] = [] + + def set_default_for_mdr(self, emane_node_id, mdr_node_id, interface_id): + """ + set emane configuration of an mdr node on the correct interface + + :param int emane_node_id: emane node id + :param int mdr_node_id: mdr node id + :param int interface_id: interface id + :return: nothing + """ + self.configurations[tuple([mdr_node_id, interface_id])] = self.configurations[ + tuple([emane_node_id, None]) + ] + self.links[emane_node_id].append(tuple([mdr_node_id, interface_id])) + + def set_custom_emane_cloud_config(self, emane_node_id, model_name): + """ + set custom configuration for an emane node, if model is changed, update the nodes connected to that emane node + + :param int emane_node_id: emane node id + :param str model_name: model name + :return: nothing + """ + prev_model_name = self.configurations[tuple([emane_node_id, None])][0] + session_id = self.app.core.session_id + response = self.app.core.client.get_emane_model_config( + session_id, emane_node_id, model_name + ) + self.configurations[tuple([emane_node_id, None])] = tuple( + [model_name, response.config] + ) + + if prev_model_name != model_name: + for k in self.links[emane_node_id]: + self.configurations[k] = tuple([model_name, response.config]) diff --git a/daemon/data/logging.conf b/daemon/data/logging.conf index 46de6e92..7f3d496f 100644 --- a/daemon/data/logging.conf +++ b/daemon/data/logging.conf @@ -14,7 +14,7 @@ } }, "root": { - "level": "DEBUG", + "level": "INFO", "handlers": ["console"] } }