Merge branch 'coretk' into coretk-color
This commit is contained in:
commit
ea2bfad591
13 changed files with 160 additions and 78 deletions
|
@ -183,8 +183,7 @@ class CoreClient:
|
||||||
)
|
)
|
||||||
|
|
||||||
def handle_exception_event(self, event):
|
def handle_exception_event(self, event):
|
||||||
print(event)
|
logging.info("exception event: %s", event)
|
||||||
print(event.node_id)
|
|
||||||
self.app.statusbar.core_alarms.append(event)
|
self.app.statusbar.core_alarms.append(event)
|
||||||
|
|
||||||
def join_session(self, session_id, query_location=True):
|
def join_session(self, session_id, query_location=True):
|
||||||
|
@ -229,26 +228,25 @@ class CoreClient:
|
||||||
|
|
||||||
# get emane model config
|
# get emane model config
|
||||||
response = self.client.get_emane_model_configs(self.session_id)
|
response = self.client.get_emane_model_configs(self.session_id)
|
||||||
for _id in response.configs:
|
for config in response.configs:
|
||||||
config = response.configs[_id]
|
|
||||||
interface = None
|
interface = None
|
||||||
node_id = _id
|
if config.interface != -1:
|
||||||
if _id >= 1000:
|
interface = config.interface
|
||||||
interface = _id % 1000
|
|
||||||
node_id = int(_id / 1000)
|
|
||||||
self.set_emane_model_config(
|
self.set_emane_model_config(
|
||||||
node_id, config.model, config.config, interface
|
config.node_id, config.model, config.config, interface
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# get wlan configurations
|
||||||
|
response = self.client.get_wlan_configs(self.session_id)
|
||||||
|
for _id in response.configs:
|
||||||
|
mapped_config = response.configs[_id]
|
||||||
|
self.wlan_configs[_id] = mapped_config.config
|
||||||
|
|
||||||
# save and retrieve data, needed for session nodes
|
# save and retrieve data, needed for session nodes
|
||||||
for node in session.nodes:
|
for node in session.nodes:
|
||||||
# get node service config and file config
|
# get node service config and file config
|
||||||
# get wlan configs for wlan nodes
|
|
||||||
if node.type == core_pb2.NodeType.WIRELESS_LAN:
|
|
||||||
response = self.client.get_wlan_config(self.session_id, node.id)
|
|
||||||
self.wlan_configs[node.id] = response.config
|
|
||||||
# retrieve service configurations data for default nodes
|
# retrieve service configurations data for default nodes
|
||||||
elif node.type == core_pb2.NodeType.DEFAULT:
|
if node.type == core_pb2.NodeType.DEFAULT:
|
||||||
for service in node.services:
|
for service in node.services:
|
||||||
response = self.client.get_node_service(
|
response = self.client.get_node_service(
|
||||||
self.session_id, node.id, service
|
self.session_id, node.id, service
|
||||||
|
|
|
@ -46,6 +46,7 @@ class NodeConfigDialog(Dialog):
|
||||||
self.canvas_node = canvas_node
|
self.canvas_node = canvas_node
|
||||||
self.node = canvas_node.core_node
|
self.node = canvas_node.core_node
|
||||||
self.image = canvas_node.image
|
self.image = canvas_node.image
|
||||||
|
self.image_file = None
|
||||||
self.image_button = None
|
self.image_button = None
|
||||||
self.name = tk.StringVar(value=self.node.name)
|
self.name = tk.StringVar(value=self.node.name)
|
||||||
self.type = tk.StringVar(value=self.node.model)
|
self.type = tk.StringVar(value=self.node.model)
|
||||||
|
@ -201,6 +202,7 @@ class NodeConfigDialog(Dialog):
|
||||||
if file_path:
|
if file_path:
|
||||||
self.image = Images.create(file_path, nodeutils.ICON_SIZE)
|
self.image = Images.create(file_path, nodeutils.ICON_SIZE)
|
||||||
self.image_button.config(image=self.image)
|
self.image_button.config(image=self.image)
|
||||||
|
self.image_file = file_path
|
||||||
|
|
||||||
def config_apply(self):
|
def config_apply(self):
|
||||||
# update core node
|
# update core node
|
||||||
|
@ -211,6 +213,10 @@ class NodeConfigDialog(Dialog):
|
||||||
if NodeUtils.is_container_node(self.node.type) and server != "localhost":
|
if NodeUtils.is_container_node(self.node.type) and server != "localhost":
|
||||||
self.node.server = server
|
self.node.server = server
|
||||||
|
|
||||||
|
# set custom icon
|
||||||
|
if self.image_file:
|
||||||
|
self.node.icon = self.image_file
|
||||||
|
|
||||||
# update canvas node
|
# update canvas node
|
||||||
self.canvas_node.image = self.image
|
self.canvas_node.image = self.image
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import tkinter as tk
|
||||||
from PIL import Image, ImageTk
|
from PIL import Image, ImageTk
|
||||||
|
|
||||||
from core.api.grpc import core_pb2
|
from core.api.grpc import core_pb2
|
||||||
|
from coretk import nodeutils
|
||||||
from coretk.dialogs.shapemod import ShapeDialog
|
from coretk.dialogs.shapemod import ShapeDialog
|
||||||
from coretk.graph import tags
|
from coretk.graph import tags
|
||||||
from coretk.graph.edges import CanvasEdge, CanvasWirelessEdge
|
from coretk.graph.edges import CanvasEdge, CanvasWirelessEdge
|
||||||
|
@ -12,6 +13,7 @@ from coretk.graph.linkinfo import LinkInfo, Throughput
|
||||||
from coretk.graph.node import CanvasNode
|
from coretk.graph.node import CanvasNode
|
||||||
from coretk.graph.shape import Shape
|
from coretk.graph.shape import Shape
|
||||||
from coretk.graph.shapeutils import ShapeType, is_draw_shape
|
from coretk.graph.shapeutils import ShapeType, is_draw_shape
|
||||||
|
from coretk.images import Images
|
||||||
from coretk.nodeutils import NodeUtils
|
from coretk.nodeutils import NodeUtils
|
||||||
|
|
||||||
ZOOM_IN = 1.1
|
ZOOM_IN = 1.1
|
||||||
|
@ -136,6 +138,11 @@ class CanvasGraph(tk.Canvas):
|
||||||
valid_y = y1 <= y <= y2
|
valid_y = y1 <= y <= y2
|
||||||
return valid_x and valid_y
|
return valid_x and valid_y
|
||||||
|
|
||||||
|
def valid_position(self, x1, y1, x2, y2):
|
||||||
|
valid_topleft = self.inside_canvas(x1, y1)
|
||||||
|
valid_bottomright = self.inside_canvas(x2, y2)
|
||||||
|
return valid_topleft and valid_bottomright
|
||||||
|
|
||||||
def draw_grid(self):
|
def draw_grid(self):
|
||||||
"""
|
"""
|
||||||
Create grid.
|
Create grid.
|
||||||
|
@ -186,12 +193,19 @@ class CanvasGraph(tk.Canvas):
|
||||||
"""
|
"""
|
||||||
# draw existing nodes
|
# draw existing nodes
|
||||||
for core_node in session.nodes:
|
for core_node in session.nodes:
|
||||||
|
logging.info("drawing core node: %s", core_node)
|
||||||
# peer to peer node is not drawn on the GUI
|
# peer to peer node is not drawn on the GUI
|
||||||
if NodeUtils.is_ignore_node(core_node.type):
|
if NodeUtils.is_ignore_node(core_node.type):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# draw nodes on the canvas
|
# draw nodes on the canvas
|
||||||
image = NodeUtils.node_icon(core_node.type, core_node.model)
|
image = NodeUtils.node_icon(core_node.type, core_node.model)
|
||||||
|
if core_node.icon:
|
||||||
|
try:
|
||||||
|
image = Images.create(core_node.icon, nodeutils.ICON_SIZE)
|
||||||
|
except OSError:
|
||||||
|
logging.error("invalid icon: %s", core_node.icon)
|
||||||
|
|
||||||
x = core_node.position.x
|
x = core_node.position.x
|
||||||
y = core_node.position.y
|
y = core_node.position.y
|
||||||
node = CanvasNode(self.master, x, y, core_node, image)
|
node = CanvasNode(self.master, x, y, core_node, image)
|
||||||
|
@ -530,6 +544,13 @@ class CanvasGraph(tk.Canvas):
|
||||||
"""
|
"""
|
||||||
x, y = self.canvas_xy(event)
|
x, y = self.canvas_xy(event)
|
||||||
if not self.inside_canvas(x, y):
|
if not self.inside_canvas(x, y):
|
||||||
|
if self.select_box:
|
||||||
|
self.select_box.delete()
|
||||||
|
self.select_box = None
|
||||||
|
if is_draw_shape(self.annotation_type) and self.shape_drawing:
|
||||||
|
shape = self.shapes.pop(self.selected)
|
||||||
|
shape.delete()
|
||||||
|
self.shape_drawing = False
|
||||||
return
|
return
|
||||||
|
|
||||||
x_offset = x - self.cursor[0]
|
x_offset = x - self.cursor[0]
|
||||||
|
@ -595,10 +616,7 @@ class CanvasGraph(tk.Canvas):
|
||||||
if self.selected is None or self.selected in self.shapes:
|
if self.selected is None or self.selected in self.shapes:
|
||||||
actual_x, actual_y = self.get_actual_coords(x, y)
|
actual_x, actual_y = self.get_actual_coords(x, y)
|
||||||
core_node = self.core.create_node(
|
core_node = self.core.create_node(
|
||||||
int(actual_x),
|
actual_x, actual_y, self.node_draw.node_type, self.node_draw.model
|
||||||
int(actual_y),
|
|
||||||
self.node_draw.node_type,
|
|
||||||
self.node_draw.model,
|
|
||||||
)
|
)
|
||||||
node = CanvasNode(self.master, x, y, core_node, self.node_draw.image)
|
node = CanvasNode(self.master, x, y, core_node, self.node_draw.image)
|
||||||
self.core.canvas_nodes[core_node.id] = node
|
self.core.canvas_nodes[core_node.id] = node
|
||||||
|
|
|
@ -103,10 +103,19 @@ class CanvasNode:
|
||||||
self.motion(x_offset, y_offset, update=False)
|
self.motion(x_offset, y_offset, update=False)
|
||||||
|
|
||||||
def motion(self, x_offset, y_offset, update=True):
|
def motion(self, x_offset, y_offset, update=True):
|
||||||
|
original_position = self.canvas.coords(self.id)
|
||||||
self.canvas.move(self.id, x_offset, y_offset)
|
self.canvas.move(self.id, x_offset, y_offset)
|
||||||
|
x, y = self.canvas.coords(self.id)
|
||||||
|
|
||||||
|
# check new position
|
||||||
|
bbox = self.canvas.bbox(self.id)
|
||||||
|
if not self.canvas.valid_position(*bbox):
|
||||||
|
self.canvas.coords(self.id, original_position)
|
||||||
|
return
|
||||||
|
|
||||||
|
# move test and selection box
|
||||||
self.canvas.move(self.text_id, x_offset, y_offset)
|
self.canvas.move(self.text_id, x_offset, y_offset)
|
||||||
self.canvas.move_selection(self.id, x_offset, y_offset)
|
self.canvas.move_selection(self.id, x_offset, y_offset)
|
||||||
x, y = self.canvas.coords(self.id)
|
|
||||||
|
|
||||||
# move antennae
|
# move antennae
|
||||||
for antenna_id in self.antennae:
|
for antenna_id in self.antennae:
|
||||||
|
@ -131,8 +140,8 @@ class CanvasNode:
|
||||||
|
|
||||||
# set actual coords for node and update core is running
|
# set actual coords for node and update core is running
|
||||||
real_x, real_y = self.canvas.get_actual_coords(x, y)
|
real_x, real_y = self.canvas.get_actual_coords(x, y)
|
||||||
self.core_node.position.x = int(real_x)
|
self.core_node.position.x = real_x
|
||||||
self.core_node.position.y = int(real_y)
|
self.core_node.position.y = real_y
|
||||||
if self.app.core.is_runtime() and update:
|
if self.app.core.is_runtime() and update:
|
||||||
self.app.core.edit_node(self.core_node)
|
self.app.core.edit_node(self.core_node)
|
||||||
|
|
||||||
|
@ -155,11 +164,6 @@ class CanvasNode:
|
||||||
else:
|
else:
|
||||||
self.show_config()
|
self.show_config()
|
||||||
|
|
||||||
def update_coords(self):
|
|
||||||
x, y = self.canvas.coords(self.id)
|
|
||||||
self.core_node.position.x = int(x)
|
|
||||||
self.core_node.position.y = int(y)
|
|
||||||
|
|
||||||
def create_context(self):
|
def create_context(self):
|
||||||
is_wlan = self.core_node.type == NodeType.WIRELESS_LAN
|
is_wlan = self.core_node.type == NodeType.WIRELESS_LAN
|
||||||
is_emane = self.core_node.type == NodeType.EMANE
|
is_emane = self.core_node.type == NodeType.EMANE
|
||||||
|
@ -169,6 +173,8 @@ class CanvasNode:
|
||||||
context.add_command(label="Configure", command=self.show_config)
|
context.add_command(label="Configure", command=self.show_config)
|
||||||
if NodeUtils.is_container_node(self.core_node.type):
|
if NodeUtils.is_container_node(self.core_node.type):
|
||||||
context.add_command(label="Services", state=tk.DISABLED)
|
context.add_command(label="Services", state=tk.DISABLED)
|
||||||
|
if is_wlan:
|
||||||
|
context.add_command(label="WLAN Config", command=self.show_wlan_config)
|
||||||
if is_wlan and self.core_node.id in self.app.core.mobility_players:
|
if is_wlan and self.core_node.id in self.app.core.mobility_players:
|
||||||
context.add_command(
|
context.add_command(
|
||||||
label="Mobility Player", command=self.show_mobility_player
|
label="Mobility Player", command=self.show_mobility_player
|
||||||
|
|
|
@ -136,7 +136,13 @@ class Shape:
|
||||||
self.canvas.delete(self.id)
|
self.canvas.delete(self.id)
|
||||||
|
|
||||||
def motion(self, x_offset, y_offset):
|
def motion(self, x_offset, y_offset):
|
||||||
|
original_position = self.canvas.coords(self.id)
|
||||||
self.canvas.move(self.id, x_offset, y_offset)
|
self.canvas.move(self.id, x_offset, y_offset)
|
||||||
|
coords = self.canvas.coords(self.id)
|
||||||
|
if not self.canvas.valid_position(*coords):
|
||||||
|
self.canvas.coords(self.id, original_position)
|
||||||
|
return
|
||||||
|
|
||||||
self.canvas.move_selection(self.id, x_offset, y_offset)
|
self.canvas.move_selection(self.id, x_offset, y_offset)
|
||||||
if self.text_id is not None:
|
if self.text_id is not None:
|
||||||
self.canvas.move(self.text_id, x_offset, y_offset)
|
self.canvas.move(self.text_id, x_offset, y_offset)
|
||||||
|
|
|
@ -827,6 +827,18 @@ class CoreGrpcClient:
|
||||||
)
|
)
|
||||||
return self.stub.ServiceAction(request)
|
return self.stub.ServiceAction(request)
|
||||||
|
|
||||||
|
def get_wlan_configs(self, session_id):
|
||||||
|
"""
|
||||||
|
Get all wlan configurations.
|
||||||
|
|
||||||
|
:param int session_id: session id
|
||||||
|
:return: response with a dict of node ids to wlan configurations
|
||||||
|
:rtype: core_pb2.GetWlanConfigsResponse
|
||||||
|
:raises grpc.RpcError: when session doesn't exist
|
||||||
|
"""
|
||||||
|
request = core_pb2.GetWlanConfigsRequest(session_id=session_id)
|
||||||
|
return self.stub.GetWlanConfigs(request)
|
||||||
|
|
||||||
def get_wlan_config(self, session_id, node_id):
|
def get_wlan_config(self, session_id, node_id):
|
||||||
"""
|
"""
|
||||||
Get wlan configuration for a node.
|
Get wlan configuration for a node.
|
||||||
|
|
|
@ -221,6 +221,22 @@ def get_emane_model_id(node_id, interface_id):
|
||||||
return node_id
|
return node_id
|
||||||
|
|
||||||
|
|
||||||
|
def parse_emane_model_id(_id):
|
||||||
|
"""
|
||||||
|
Parses EMANE model id to get true node id and interface id.
|
||||||
|
|
||||||
|
:param _id: id to parse
|
||||||
|
:return: node id and interface id
|
||||||
|
:rtype: tuple
|
||||||
|
"""
|
||||||
|
interface = -1
|
||||||
|
node_id = _id
|
||||||
|
if _id >= 1000:
|
||||||
|
interface = _id % 1000
|
||||||
|
node_id = int(_id / 1000)
|
||||||
|
return node_id, interface
|
||||||
|
|
||||||
|
|
||||||
def convert_link(session, link_data):
|
def convert_link(session, link_data):
|
||||||
"""
|
"""
|
||||||
Convert link_data into core protobuf Link
|
Convert link_data into core protobuf Link
|
||||||
|
|
|
@ -393,15 +393,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
||||||
position = core_pb2.Position(
|
position = core_pb2.Position(
|
||||||
x=node.position.x, y=node.position.y, z=node.position.z
|
x=node.position.x, y=node.position.y, z=node.position.z
|
||||||
)
|
)
|
||||||
|
|
||||||
services = getattr(node, "services", [])
|
services = getattr(node, "services", [])
|
||||||
if services is None:
|
if services is None:
|
||||||
services = []
|
services = []
|
||||||
services = [x.name for x in services]
|
services = [x.name for x in services]
|
||||||
|
|
||||||
emane_model = None
|
emane_model = None
|
||||||
if isinstance(node, EmaneNet):
|
if isinstance(node, EmaneNet):
|
||||||
emane_model = node.model.name
|
emane_model = node.model.name
|
||||||
|
image = getattr(node, "image", None)
|
||||||
|
|
||||||
node_proto = core_pb2.Node(
|
node_proto = core_pb2.Node(
|
||||||
id=node.id,
|
id=node.id,
|
||||||
|
@ -411,6 +410,8 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
||||||
type=node_type.value,
|
type=node_type.value,
|
||||||
position=position,
|
position=position,
|
||||||
services=services,
|
services=services,
|
||||||
|
icon=node.icon,
|
||||||
|
image=image,
|
||||||
)
|
)
|
||||||
if isinstance(node, (DockerNode, LxcNode)):
|
if isinstance(node, (DockerNode, LxcNode)):
|
||||||
node_proto.image = node.image
|
node_proto.image = node.image
|
||||||
|
@ -488,13 +489,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
||||||
:return: node event that contains node id, name, model, position, and services
|
:return: node event that contains node id, name, model, position, and services
|
||||||
:rtype: core.api.grpc.core_pb2.NodeEvent
|
:rtype: core.api.grpc.core_pb2.NodeEvent
|
||||||
"""
|
"""
|
||||||
x = None
|
position = core_pb2.Position(x=event.x_position, y=event.y_position)
|
||||||
if event.x_position is not None:
|
|
||||||
x = int(event.x_position)
|
|
||||||
y = None
|
|
||||||
if event.y_position is not None:
|
|
||||||
y = int(event.y_position)
|
|
||||||
position = core_pb2.Position(x=x, y=y)
|
|
||||||
services = event.services or ""
|
services = event.services or ""
|
||||||
services = services.split("|")
|
services = services.split("|")
|
||||||
node_proto = core_pb2.Node(
|
node_proto = core_pb2.Node(
|
||||||
|
@ -1163,13 +1158,6 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
||||||
logging.debug("get node service file: %s", request)
|
logging.debug("get node service file: %s", request)
|
||||||
session = self.get_session(request.session_id, context)
|
session = self.get_session(request.session_id, context)
|
||||||
node = self.get_node(session, request.node_id, context)
|
node = self.get_node(session, request.node_id, context)
|
||||||
service = None
|
|
||||||
for current_service in node.services:
|
|
||||||
if current_service.name == request.service:
|
|
||||||
service = current_service
|
|
||||||
break
|
|
||||||
if not service:
|
|
||||||
context.abort(grpc.StatusCode.NOT_FOUND, "service not found")
|
|
||||||
file_data = session.services.get_service_file(
|
file_data = session.services.get_service_file(
|
||||||
node, request.service, request.file
|
node, request.service, request.file
|
||||||
)
|
)
|
||||||
|
@ -1248,6 +1236,31 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
||||||
|
|
||||||
return core_pb2.ServiceActionResponse(result=result)
|
return core_pb2.ServiceActionResponse(result=result)
|
||||||
|
|
||||||
|
def GetWlanConfigs(self, request, context):
|
||||||
|
"""
|
||||||
|
Retrieve all wireless-lan configurations.
|
||||||
|
|
||||||
|
:param core.api.grpc.core_pb2.GetWlanConfigsRequest request: request
|
||||||
|
:param context: core.api.grpc.core_pb2.GetWlanConfigResponse
|
||||||
|
:return: all wlan configurations
|
||||||
|
:rtype: core.api.grpc.core_pb2.GetWlanConfigsResponse
|
||||||
|
"""
|
||||||
|
logging.debug("get wlan configs: %s", request)
|
||||||
|
session = self.get_session(request.session_id, context)
|
||||||
|
response = core_pb2.GetWlanConfigsResponse()
|
||||||
|
for node_id in session.mobility.node_configurations:
|
||||||
|
model_config = session.mobility.node_configurations[node_id]
|
||||||
|
if node_id == -1:
|
||||||
|
continue
|
||||||
|
for model_name in model_config:
|
||||||
|
if model_name != BasicRangeModel.name:
|
||||||
|
continue
|
||||||
|
current_config = session.mobility.get_model_config(node_id, model_name)
|
||||||
|
config = get_config_options(current_config, BasicRangeModel)
|
||||||
|
mapped_config = core_pb2.MappedConfig(config=config)
|
||||||
|
response.configs[node_id].CopyFrom(mapped_config)
|
||||||
|
return response
|
||||||
|
|
||||||
def GetWlanConfig(self, request, context):
|
def GetWlanConfig(self, request, context):
|
||||||
"""
|
"""
|
||||||
Retrieve wireless-lan configuration of a node
|
Retrieve wireless-lan configuration of a node
|
||||||
|
@ -1381,21 +1394,26 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
||||||
"""
|
"""
|
||||||
logging.debug("get emane model configs: %s", request)
|
logging.debug("get emane model configs: %s", request)
|
||||||
session = self.get_session(request.session_id, context)
|
session = self.get_session(request.session_id, context)
|
||||||
response = core_pb2.GetEmaneModelConfigsResponse()
|
|
||||||
for node_id in session.emane.node_configurations:
|
configs = []
|
||||||
model_config = session.emane.node_configurations[node_id]
|
for _id in session.emane.node_configurations:
|
||||||
if node_id == -1:
|
if _id == -1:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for model_name in model_config:
|
model_configs = session.emane.node_configurations[_id]
|
||||||
|
for model_name in model_configs:
|
||||||
model = session.emane.models[model_name]
|
model = session.emane.models[model_name]
|
||||||
current_config = session.emane.get_model_config(node_id, model_name)
|
current_config = session.emane.get_model_config(_id, model_name)
|
||||||
config = get_config_options(current_config, model)
|
config = get_config_options(current_config, model)
|
||||||
|
node_id, interface = grpcutils.parse_emane_model_id(_id)
|
||||||
model_config = core_pb2.GetEmaneModelConfigsResponse.ModelConfig(
|
model_config = core_pb2.GetEmaneModelConfigsResponse.ModelConfig(
|
||||||
model=model_name, config=config
|
node_id=node_id,
|
||||||
|
model=model_name,
|
||||||
|
interface=interface,
|
||||||
|
config=config,
|
||||||
)
|
)
|
||||||
response.configs[node_id].CopyFrom(model_config)
|
configs.append(model_config)
|
||||||
return response
|
return core_pb2.GetEmaneModelConfigsResponse(configs=configs)
|
||||||
|
|
||||||
def SaveXml(self, request, context):
|
def SaveXml(self, request, context):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -5,7 +5,6 @@ import signal
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import core.services
|
import core.services
|
||||||
from core.emulator.emudata import IdGen
|
|
||||||
from core.emulator.session import Session
|
from core.emulator.session import Session
|
||||||
from core.services.coreservices import ServiceManager
|
from core.services.coreservices import ServiceManager
|
||||||
|
|
||||||
|
@ -49,7 +48,6 @@ class CoreEmu:
|
||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
# session management
|
# session management
|
||||||
self.session_id_gen = IdGen()
|
|
||||||
self.sessions = {}
|
self.sessions = {}
|
||||||
|
|
||||||
# load services
|
# load services
|
||||||
|
@ -79,7 +77,6 @@ class CoreEmu:
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
logging.info("shutting down all sessions")
|
logging.info("shutting down all sessions")
|
||||||
self.session_id_gen.id = 0
|
|
||||||
sessions = self.sessions.copy()
|
sessions = self.sessions.copy()
|
||||||
self.sessions.clear()
|
self.sessions.clear()
|
||||||
for _id in sessions:
|
for _id in sessions:
|
||||||
|
@ -96,11 +93,9 @@ class CoreEmu:
|
||||||
:rtype: EmuSession
|
:rtype: EmuSession
|
||||||
"""
|
"""
|
||||||
if not _id:
|
if not _id:
|
||||||
while True:
|
_id = 1
|
||||||
_id = self.session_id_gen.next()
|
while _id in self.sessions:
|
||||||
if _id not in self.sessions:
|
_id += 1
|
||||||
break
|
|
||||||
|
|
||||||
session = _cls(_id, config=self.config)
|
session = _cls(_id, config=self.config)
|
||||||
logging.info("created session: %s", _id)
|
logging.info("created session: %s", _id)
|
||||||
self.sessions[_id] = session
|
self.sessions[_id] = session
|
||||||
|
|
|
@ -396,7 +396,7 @@ class CoreServices:
|
||||||
"""
|
"""
|
||||||
Add services to a node.
|
Add services to a node.
|
||||||
|
|
||||||
:param core.coreobj.PyCoreNode node: node to add services to
|
:param core.nodes.base.CoreNode node: node to add services to
|
||||||
:param str node_type: node type to add services to
|
:param str node_type: node type to add services to
|
||||||
:param list[str] services: names of services to add to node
|
:param list[str] services: names of services to add to node
|
||||||
:return: nothing
|
:return: nothing
|
||||||
|
|
|
@ -117,14 +117,8 @@ class NodeElement:
|
||||||
|
|
||||||
def add_position(self):
|
def add_position(self):
|
||||||
x = self.node.position.x
|
x = self.node.position.x
|
||||||
if x is not None:
|
|
||||||
x = int(x)
|
|
||||||
y = self.node.position.y
|
y = self.node.position.y
|
||||||
if y is not None:
|
|
||||||
y = int(y)
|
|
||||||
z = self.node.position.z
|
z = self.node.position.z
|
||||||
if z is not None:
|
|
||||||
z = int(z)
|
|
||||||
lat, lon, alt = None, None, None
|
lat, lon, alt = None, None, None
|
||||||
if x is not None and y is not None:
|
if x is not None and y is not None:
|
||||||
lat, lon, alt = self.session.location.getgeo(x, y, z)
|
lat, lon, alt = self.session.location.getgeo(x, y, z)
|
||||||
|
@ -751,8 +745,8 @@ class CoreXmlReader:
|
||||||
|
|
||||||
position_element = device_element.find("position")
|
position_element = device_element.find("position")
|
||||||
if position_element is not None:
|
if position_element is not None:
|
||||||
x = get_int(position_element, "x")
|
x = get_float(position_element, "x")
|
||||||
y = get_int(position_element, "y")
|
y = get_float(position_element, "y")
|
||||||
if all([x, y]):
|
if all([x, y]):
|
||||||
options.set_position(x, y)
|
options.set_position(x, y)
|
||||||
|
|
||||||
|
@ -773,8 +767,8 @@ class CoreXmlReader:
|
||||||
|
|
||||||
position_element = network_element.find("position")
|
position_element = network_element.find("position")
|
||||||
if position_element is not None:
|
if position_element is not None:
|
||||||
x = get_int(position_element, "x")
|
x = get_float(position_element, "x")
|
||||||
y = get_int(position_element, "y")
|
y = get_float(position_element, "y")
|
||||||
if all([x, y]):
|
if all([x, y]):
|
||||||
options.set_position(x, y)
|
options.set_position(x, y)
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,8 @@ service CoreApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
// wlan rpc
|
// wlan rpc
|
||||||
|
rpc GetWlanConfigs (GetWlanConfigsRequest) returns (GetWlanConfigsResponse) {
|
||||||
|
}
|
||||||
rpc GetWlanConfig (GetWlanConfigRequest) returns (GetWlanConfigResponse) {
|
rpc GetWlanConfig (GetWlanConfigRequest) returns (GetWlanConfigResponse) {
|
||||||
}
|
}
|
||||||
rpc SetWlanConfig (SetWlanConfigRequest) returns (SetWlanConfigResponse) {
|
rpc SetWlanConfig (SetWlanConfigRequest) returns (SetWlanConfigResponse) {
|
||||||
|
@ -585,6 +587,14 @@ message ServiceActionResponse {
|
||||||
bool result = 1;
|
bool result = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message GetWlanConfigsRequest {
|
||||||
|
int32 session_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetWlanConfigsResponse {
|
||||||
|
map<int32, MappedConfig> configs = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message GetWlanConfigRequest {
|
message GetWlanConfigRequest {
|
||||||
int32 session_id = 1;
|
int32 session_id = 1;
|
||||||
int32 node_id = 2;
|
int32 node_id = 2;
|
||||||
|
@ -654,10 +664,12 @@ message GetEmaneModelConfigsRequest {
|
||||||
|
|
||||||
message GetEmaneModelConfigsResponse {
|
message GetEmaneModelConfigsResponse {
|
||||||
message ModelConfig {
|
message ModelConfig {
|
||||||
string model = 1;
|
int32 node_id = 1;
|
||||||
map<string, ConfigOption> config = 2;
|
string model = 2;
|
||||||
|
int32 interface = 3;
|
||||||
|
map<string, ConfigOption> config = 4;
|
||||||
}
|
}
|
||||||
map<int32, ModelConfig> configs = 1;
|
repeated ModelConfig configs = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SaveXmlRequest {
|
message SaveXmlRequest {
|
||||||
|
@ -949,9 +961,9 @@ message SessionLocation {
|
||||||
}
|
}
|
||||||
|
|
||||||
message Position {
|
message Position {
|
||||||
int32 x = 1;
|
float x = 1;
|
||||||
int32 y = 2;
|
float y = 2;
|
||||||
int32 z = 3;
|
float z = 3;
|
||||||
float lat = 4;
|
float lat = 4;
|
||||||
float lon = 5;
|
float lon = 5;
|
||||||
float alt = 6;
|
float alt = 6;
|
||||||
|
|
|
@ -708,10 +708,11 @@ class TestGrpc:
|
||||||
|
|
||||||
# then
|
# then
|
||||||
assert len(response.configs) == 1
|
assert len(response.configs) == 1
|
||||||
assert emane_network.id in response.configs
|
model_config = response.configs[0]
|
||||||
model_config = response.configs[emane_network.id]
|
assert emane_network.id == model_config.node_id
|
||||||
assert model_config.model == EmaneIeee80211abgModel.name
|
assert model_config.model == EmaneIeee80211abgModel.name
|
||||||
assert len(model_config.config) > 0
|
assert len(model_config.config) > 0
|
||||||
|
assert model_config.interface == -1
|
||||||
|
|
||||||
def test_set_emane_model_config(self, grpc_server):
|
def test_set_emane_model_config(self, grpc_server):
|
||||||
# given
|
# given
|
||||||
|
|
Loading…
Add table
Reference in a new issue