2019-10-02 00:25:26 +01:00
|
|
|
"""
|
|
|
|
Incorporate grpc into python tkinter GUI
|
|
|
|
"""
|
|
|
|
import logging
|
2019-10-11 01:02:28 +01:00
|
|
|
import os
|
2019-10-19 00:42:00 +01:00
|
|
|
from collections import OrderedDict
|
2019-10-02 00:25:26 +01:00
|
|
|
|
|
|
|
from core.api.grpc import client, core_pb2
|
2019-11-01 06:17:26 +00:00
|
|
|
from coretk.dialogs.sessions import SessionsDialog
|
2019-11-01 17:45:47 +00:00
|
|
|
from coretk.grpcmanagement import GrpcManager
|
2019-10-02 00:25:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
class CoreGrpc:
|
2019-10-19 00:42:00 +01:00
|
|
|
def __init__(self, app, sid=None):
|
2019-10-02 00:25:26 +01:00
|
|
|
"""
|
|
|
|
Create a CoreGrpc instance
|
|
|
|
"""
|
|
|
|
self.core = client.CoreGrpcClient()
|
2019-10-19 00:42:00 +01:00
|
|
|
self.session_id = sid
|
2019-10-22 00:33:18 +01:00
|
|
|
self.node_ids = []
|
2019-11-01 06:17:26 +00:00
|
|
|
self.app = app
|
2019-10-19 00:42:00 +01:00
|
|
|
self.master = app.master
|
2019-10-04 00:50:49 +01:00
|
|
|
self.interface_helper = None
|
2019-11-01 17:45:47 +00:00
|
|
|
self.manager = GrpcManager(self)
|
2019-10-02 00:25:26 +01:00
|
|
|
|
2019-11-01 17:45:47 +00:00
|
|
|
def handle_events(self, event):
|
2019-10-02 00:25:26 +01:00
|
|
|
logging.info("event: %s", event)
|
2019-10-19 00:42:00 +01:00
|
|
|
if event.link_event is not None:
|
2019-11-01 17:45:47 +00:00
|
|
|
self.app.canvas.wireless_draw.hangle_link_event(event.link_event)
|
2019-10-19 00:42:00 +01:00
|
|
|
|
2019-11-01 17:45:47 +00:00
|
|
|
def handle_throughputs(self, event):
|
2019-10-19 00:42:00 +01:00
|
|
|
interface_throughputs = event.interface_throughputs
|
2019-10-25 00:50:24 +01:00
|
|
|
for i in interface_throughputs:
|
|
|
|
print("")
|
|
|
|
return
|
2019-10-22 00:33:18 +01:00
|
|
|
throughputs_belong_to_session = []
|
|
|
|
for if_tp in interface_throughputs:
|
|
|
|
if if_tp.node_id in self.node_ids:
|
|
|
|
throughputs_belong_to_session.append(if_tp)
|
2019-10-19 00:42:00 +01:00
|
|
|
# bridge_throughputs = event.bridge_throughputs
|
2019-10-22 00:33:18 +01:00
|
|
|
self.throughput_draw.process_grpc_throughput_event(
|
|
|
|
throughputs_belong_to_session
|
|
|
|
)
|
2019-10-02 00:25:26 +01:00
|
|
|
|
2019-11-01 17:45:47 +00:00
|
|
|
def join_session(self, session_id):
|
|
|
|
# query session and set as current session
|
|
|
|
self.session_id = session_id
|
|
|
|
response = self.core.get_session(self.session_id)
|
|
|
|
logging.info("joining session(%s): %s", self.session_id, response)
|
|
|
|
self.core.events(self.session_id, self.app.core_grpc.handle_events)
|
|
|
|
|
|
|
|
# determine next node id and reusable nodes
|
|
|
|
session = response.session
|
|
|
|
self.manager.reusable.clear()
|
|
|
|
self.manager.preexisting.clear()
|
|
|
|
max_id = 1
|
|
|
|
for node in session.nodes:
|
|
|
|
if node.id > max_id:
|
|
|
|
max_id = node.id
|
|
|
|
self.manager.preexisting.add(node.id)
|
|
|
|
self.manager.id = max_id
|
|
|
|
for i in range(1, self.manager.id):
|
|
|
|
if i not in self.manager.preexisting:
|
|
|
|
self.manager.reusable.append(i)
|
|
|
|
|
|
|
|
# draw session
|
2019-11-01 18:34:38 +00:00
|
|
|
self.app.canvas.canvas_reset_and_redraw(session)
|
2019-11-01 17:45:47 +00:00
|
|
|
|
2019-10-04 00:50:49 +01:00
|
|
|
def create_new_session(self):
|
2019-10-02 00:25:26 +01:00
|
|
|
"""
|
2019-10-04 00:50:49 +01:00
|
|
|
Create a new session
|
2019-10-02 00:25:26 +01:00
|
|
|
|
|
|
|
:return: nothing
|
|
|
|
"""
|
|
|
|
response = self.core.create_session()
|
|
|
|
logging.info("created session: %s", response)
|
|
|
|
|
|
|
|
# handle events session may broadcast
|
|
|
|
self.session_id = response.session_id
|
2019-10-25 00:50:24 +01:00
|
|
|
self.master.title("CORE Session ID " + str(self.session_id))
|
2019-11-01 17:45:47 +00:00
|
|
|
self.core.events(self.session_id, self.handle_events)
|
2019-10-25 00:50:24 +01:00
|
|
|
# self.core.throughputs(self.log_throughput)
|
2019-10-11 01:02:28 +01:00
|
|
|
|
2019-10-19 00:42:00 +01:00
|
|
|
def delete_session(self, custom_sid=None):
|
|
|
|
if custom_sid is None:
|
|
|
|
sid = self.session_id
|
|
|
|
else:
|
|
|
|
sid = custom_sid
|
|
|
|
response = self.core.delete_session(sid)
|
2019-10-05 00:52:07 +01:00
|
|
|
logging.info("Deleted session result: %s", response)
|
|
|
|
|
2019-10-19 00:42:00 +01:00
|
|
|
def terminate_session(self, custom_sid=None):
|
|
|
|
if custom_sid is None:
|
|
|
|
sid = self.session_id
|
|
|
|
else:
|
|
|
|
sid = custom_sid
|
|
|
|
s = self.core.get_session(sid).session
|
|
|
|
# delete links and nodes from running session
|
|
|
|
if s.state == core_pb2.SessionState.RUNTIME:
|
|
|
|
self.set_session_state("datacollect", sid)
|
|
|
|
self.delete_links(sid)
|
|
|
|
self.delete_nodes(sid)
|
|
|
|
self.delete_session(sid)
|
|
|
|
|
2019-10-04 00:50:49 +01:00
|
|
|
def set_up(self):
|
|
|
|
"""
|
2019-10-11 01:02:28 +01:00
|
|
|
Query sessions, if there exist any, prompt whether to join one
|
2019-10-04 00:50:49 +01:00
|
|
|
|
2019-10-11 01:02:28 +01:00
|
|
|
:return: existing sessions
|
2019-10-04 00:50:49 +01:00
|
|
|
"""
|
|
|
|
self.core.connect()
|
|
|
|
response = self.core.get_sessions()
|
|
|
|
|
|
|
|
# if there are no sessions, create a new session, else join a session
|
|
|
|
sessions = response.sessions
|
|
|
|
if len(sessions) == 0:
|
|
|
|
self.create_new_session()
|
|
|
|
else:
|
2019-11-01 06:17:26 +00:00
|
|
|
dialog = SessionsDialog(self.app, self.app)
|
|
|
|
dialog.show()
|
2019-10-04 00:50:49 +01:00
|
|
|
|
2019-10-05 00:52:07 +01:00
|
|
|
def get_session_state(self):
|
|
|
|
response = self.core.get_session(self.session_id)
|
2019-10-19 00:42:00 +01:00
|
|
|
# logging.info("get session: %s", response)
|
2019-10-05 00:52:07 +01:00
|
|
|
return response.session.state
|
|
|
|
|
2019-10-19 00:42:00 +01:00
|
|
|
def set_session_state(self, state, custom_session_id=None):
|
2019-10-05 00:52:07 +01:00
|
|
|
"""
|
|
|
|
Set session state
|
|
|
|
|
|
|
|
:param str state: session state to set
|
|
|
|
:return: nothing
|
|
|
|
"""
|
2019-10-19 00:42:00 +01:00
|
|
|
if custom_session_id is None:
|
|
|
|
sid = self.session_id
|
|
|
|
else:
|
|
|
|
sid = custom_session_id
|
|
|
|
|
2019-11-01 17:45:47 +00:00
|
|
|
response = None
|
2019-10-05 00:52:07 +01:00
|
|
|
if state == "configuration":
|
|
|
|
response = self.core.set_session_state(
|
2019-10-19 00:42:00 +01:00
|
|
|
sid, core_pb2.SessionState.CONFIGURATION
|
2019-10-05 00:52:07 +01:00
|
|
|
)
|
|
|
|
elif state == "instantiation":
|
|
|
|
response = self.core.set_session_state(
|
2019-10-19 00:42:00 +01:00
|
|
|
sid, core_pb2.SessionState.INSTANTIATION
|
2019-10-05 00:52:07 +01:00
|
|
|
)
|
|
|
|
elif state == "datacollect":
|
|
|
|
response = self.core.set_session_state(
|
2019-10-19 00:42:00 +01:00
|
|
|
sid, core_pb2.SessionState.DATACOLLECT
|
2019-10-05 00:52:07 +01:00
|
|
|
)
|
|
|
|
elif state == "shutdown":
|
2019-10-19 00:42:00 +01:00
|
|
|
response = self.core.set_session_state(sid, core_pb2.SessionState.SHUTDOWN)
|
2019-10-05 00:52:07 +01:00
|
|
|
elif state == "runtime":
|
2019-10-19 00:42:00 +01:00
|
|
|
response = self.core.set_session_state(sid, core_pb2.SessionState.RUNTIME)
|
2019-10-05 00:52:07 +01:00
|
|
|
elif state == "definition":
|
|
|
|
response = self.core.set_session_state(
|
2019-10-19 00:42:00 +01:00
|
|
|
sid, core_pb2.SessionState.DEFINITION
|
2019-10-05 00:52:07 +01:00
|
|
|
)
|
|
|
|
elif state == "none":
|
2019-10-19 00:42:00 +01:00
|
|
|
response = self.core.set_session_state(sid, core_pb2.SessionState.NONE)
|
2019-10-05 00:52:07 +01:00
|
|
|
else:
|
|
|
|
logging.error("coregrpc.py: set_session_state: INVALID STATE")
|
2019-10-02 00:25:26 +01:00
|
|
|
|
2019-10-04 00:50:49 +01:00
|
|
|
logging.info("set session state: %s", response)
|
|
|
|
|
2019-10-05 00:52:07 +01:00
|
|
|
def add_node(self, node_type, model, x, y, name, node_id):
|
2019-10-04 00:50:49 +01:00
|
|
|
position = core_pb2.Position(x=x, y=y)
|
2019-10-05 00:52:07 +01:00
|
|
|
node = core_pb2.Node(id=node_id, type=node_type, position=position, model=model)
|
2019-10-22 00:33:18 +01:00
|
|
|
self.node_ids.append(node_id)
|
2019-10-02 00:25:26 +01:00
|
|
|
response = self.core.add_node(self.session_id, node)
|
2019-10-04 00:50:49 +01:00
|
|
|
logging.info("created node: %s", response)
|
2019-10-19 00:42:00 +01:00
|
|
|
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.core.set_wlan_config(self.session_id, node_id, d)
|
|
|
|
logging.debug("set wlan config %s", r)
|
2019-10-02 00:25:26 +01:00
|
|
|
return response.node_id
|
|
|
|
|
2019-10-11 01:02:28 +01:00
|
|
|
def edit_node(self, node_id, x, y):
|
2019-10-02 00:25:26 +01:00
|
|
|
position = core_pb2.Position(x=x, y=y)
|
2019-10-11 01:02:28 +01:00
|
|
|
response = self.core.edit_node(self.session_id, node_id, position)
|
2019-10-02 00:25:26 +01:00
|
|
|
logging.info("updated node id %s: %s", node_id, response)
|
2019-10-19 00:42:00 +01:00
|
|
|
# self.core.events(self.session_id, self.log_event)
|
2019-10-02 00:25:26 +01:00
|
|
|
|
2019-10-19 00:42:00 +01:00
|
|
|
def delete_nodes(self, delete_session=None):
|
|
|
|
if delete_session is None:
|
|
|
|
sid = self.session_id
|
|
|
|
else:
|
|
|
|
sid = delete_session
|
|
|
|
for node in self.core.get_session(sid).session.nodes:
|
2019-10-05 00:52:07 +01:00
|
|
|
response = self.core.delete_node(self.session_id, node.id)
|
2019-10-19 00:42:00 +01:00
|
|
|
logging.info("delete nodes %s", response)
|
|
|
|
|
|
|
|
def delete_links(self, delete_session=None):
|
2019-10-29 16:04:16 +00:00
|
|
|
# sid = None
|
2019-10-19 00:42:00 +01:00
|
|
|
if delete_session is None:
|
|
|
|
sid = self.session_id
|
|
|
|
else:
|
|
|
|
sid = delete_session
|
2019-10-05 00:52:07 +01:00
|
|
|
|
2019-10-19 00:42:00 +01:00
|
|
|
for link in self.core.get_session(sid).session.links:
|
2019-10-05 00:52:07 +01:00
|
|
|
response = self.core.delete_link(
|
|
|
|
self.session_id,
|
|
|
|
link.node_one_id,
|
|
|
|
link.node_two_id,
|
|
|
|
link.interface_one.id,
|
|
|
|
link.interface_two.id,
|
|
|
|
)
|
2019-10-19 00:42:00 +01:00
|
|
|
logging.info("delete links %s", response)
|
2019-10-05 00:52:07 +01:00
|
|
|
|
2019-11-01 15:35:14 +00:00
|
|
|
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
|
2019-10-11 01:02:28 +01:00
|
|
|
def add_link(self, id1, id2, type1, type2, edge):
|
2019-10-04 00:50:49 +01:00
|
|
|
"""
|
|
|
|
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
|
|
|
|
"""
|
2019-11-01 15:35:14 +00:00
|
|
|
if1 = self.create_interface(type1, edge.interface_1)
|
|
|
|
if2 = self.create_interface(type2, edge.interface_2)
|
|
|
|
# if type1 == core_pb2.NodeType.DEFAULT:
|
|
|
|
# interface = edge.interface_1
|
|
|
|
# if1 = core_pb2.Interface(
|
|
|
|
# id=interface.id,
|
|
|
|
# name=interface.name,
|
|
|
|
# mac=interface.mac,
|
|
|
|
# ip4=interface.ipv4,
|
|
|
|
# ip4mask=interface.ip4prefix,
|
|
|
|
# )
|
|
|
|
# logging.debug("create interface 1 %s", if1)
|
|
|
|
# # interface1 = self.interface_helper.create_interface(id1, 0)
|
|
|
|
#
|
|
|
|
# if type2 == core_pb2.NodeType.DEFAULT:
|
|
|
|
# interface = edge.interface_2
|
|
|
|
# if2 = core_pb2.Interface(
|
|
|
|
# id=interface.id,
|
|
|
|
# name=interface.name,
|
|
|
|
# mac=interface.mac,
|
|
|
|
# ip4=interface.ipv4,
|
|
|
|
# ip4mask=interface.ip4prefix,
|
|
|
|
# )
|
|
|
|
# logging.debug("create interface 2: %s", if2)
|
2019-10-11 01:02:28 +01:00
|
|
|
|
|
|
|
response = self.core.add_link(self.session_id, id1, id2, if1, if2)
|
2019-10-04 00:50:49 +01:00
|
|
|
logging.info("created link: %s", response)
|
|
|
|
|
2019-10-11 01:02:28 +01:00
|
|
|
def launch_terminal(self, node_id):
|
|
|
|
response = self.core.get_node_terminal(self.session_id, node_id)
|
|
|
|
logging.info("get terminal %s", response.terminal)
|
|
|
|
os.system("xterm -e %s &" % response.terminal)
|
|
|
|
|
|
|
|
def save_xml(self, file_path):
|
|
|
|
"""
|
|
|
|
Save core session as to an xml file
|
|
|
|
|
|
|
|
:param str file_path: file path that user pick
|
|
|
|
:return: nothing
|
|
|
|
"""
|
|
|
|
response = self.core.save_xml(self.session_id, file_path)
|
|
|
|
logging.info("coregrpc.py save xml %s", response)
|
2019-11-01 17:45:47 +00:00
|
|
|
self.core.events(self.session_id, self.handle_events)
|
2019-10-11 01:02:28 +01:00
|
|
|
|
|
|
|
def open_xml(self, file_path):
|
|
|
|
"""
|
|
|
|
Open core xml
|
|
|
|
|
|
|
|
:param str file_path: file to open
|
|
|
|
:return: session id
|
|
|
|
"""
|
|
|
|
response = self.core.open_xml(file_path)
|
2019-11-01 18:34:38 +00:00
|
|
|
logging.debug("open xml: %s", response)
|
|
|
|
self.join_session(response.session_id)
|
2019-10-11 01:02:28 +01:00
|
|
|
|
2019-10-02 00:25:26 +01:00
|
|
|
def close(self):
|
|
|
|
"""
|
|
|
|
Clean ups when done using grpc
|
|
|
|
|
|
|
|
:return: nothing
|
|
|
|
"""
|
|
|
|
logging.debug("Close grpc")
|
|
|
|
self.core.close()
|