Merge pull request #409 from coreemu/enhancement/enum-cleanup

Enhancement/enum cleanup
This commit is contained in:
bharnden 2020-03-22 15:19:06 -07:00 committed by GitHub
commit fd7db64f6d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 543 additions and 559 deletions

View file

@ -80,14 +80,14 @@ def handle_link_event(event: LinkData) -> core_pb2.LinkEvent:
unidirectional=event.unidirectional, unidirectional=event.unidirectional,
) )
link = core_pb2.Link( link = core_pb2.Link(
type=event.link_type, type=event.link_type.value,
node_one_id=event.node1_id, node_one_id=event.node1_id,
node_two_id=event.node2_id, node_two_id=event.node2_id,
interface_one=interface_one, interface_one=interface_one,
interface_two=interface_two, interface_two=interface_two,
options=options, options=options,
) )
return core_pb2.LinkEvent(message_type=event.message_type, link=link) return core_pb2.LinkEvent(message_type=event.message_type.value, link=link)
def handle_session_event(event: EventData) -> core_pb2.SessionEvent: def handle_session_event(event: EventData) -> core_pb2.SessionEvent:
@ -102,7 +102,7 @@ def handle_session_event(event: EventData) -> core_pb2.SessionEvent:
event_time = float(event_time) event_time = float(event_time)
return core_pb2.SessionEvent( return core_pb2.SessionEvent(
node_id=event.node, node_id=event.node,
event=event.event_type, event=event.event_type.value,
name=event.name, name=event.name,
data=event.data, data=event.data,
time=event_time, time=event_time,
@ -158,7 +158,7 @@ def handle_file_event(event: FileData) -> core_pb2.FileEvent:
:return: file event :return: file event
""" """
return core_pb2.FileEvent( return core_pb2.FileEvent(
message_type=event.message_type, message_type=event.message_type.value,
node_id=event.node, node_id=event.node,
name=event.name, name=event.name,
mode=event.mode, mode=event.mode,

View file

@ -26,11 +26,7 @@ def add_node_data(node_proto: core_pb2.Node) -> Tuple[NodeTypes, int, NodeOption
:return: node type, id, and options :return: node type, id, and options
""" """
_id = node_proto.id _id = node_proto.id
_type = node_proto.type _type = NodeTypes(node_proto.type)
if _type is None:
_type = NodeTypes.DEFAULT.value
_type = NodeTypes(_type)
options = NodeOptions(name=node_proto.name, model=node_proto.model) options = NodeOptions(name=node_proto.name, model=node_proto.model)
options.icon = node_proto.icon options.icon = node_proto.icon
options.opaque = node_proto.opaque options.opaque = node_proto.opaque
@ -233,7 +229,7 @@ def get_links(session: Session, node: NodeBase):
:return: [core.api.grpc.core_pb2.Link] :return: [core.api.grpc.core_pb2.Link]
""" """
links = [] links = []
for link_data in node.all_link_data(0): for link_data in node.all_link_data():
link = convert_link(session, link_data) link = convert_link(session, link_data)
links.append(link) links.append(link)
return links return links
@ -325,7 +321,7 @@ def convert_link(session: Session, link_data: LinkData) -> core_pb2.Link:
) )
return core_pb2.Link( return core_pb2.Link(
type=link_data.link_type, type=link_data.link_type.value,
node_one_id=link_data.node1_id, node_one_id=link_data.node1_id,
node_two_id=link_data.node2_id, node_two_id=link_data.node2_id,
interface_one=interface_one, interface_one=interface_one,

View file

@ -173,7 +173,8 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
# add all hooks # add all hooks
for hook in request.hooks: for hook in request.hooks:
session.add_hook(hook.state, hook.file, None, hook.data) state = EventTypes(hook.state)
session.add_hook(state, hook.file, None, hook.data)
# create nodes # create nodes
_, exceptions = grpcutils.create_nodes(session, request.nodes) _, exceptions = grpcutils.create_nodes(session, request.nodes)
@ -279,7 +280,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
session.location.setrefgeo(47.57917, -122.13232, 2.0) session.location.setrefgeo(47.57917, -122.13232, 2.0)
session.location.refscale = 150000.0 session.location.refscale = 150000.0
return core_pb2.CreateSessionResponse( return core_pb2.CreateSessionResponse(
session_id=session.id, state=session.state session_id=session.id, state=session.state.value
) )
def DeleteSession( def DeleteSession(
@ -312,7 +313,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
session = self.coreemu.sessions[session_id] session = self.coreemu.sessions[session_id]
session_summary = core_pb2.SessionSummary( session_summary = core_pb2.SessionSummary(
id=session_id, id=session_id,
state=session.state, state=session.state.value,
nodes=session.get_node_count(), nodes=session.get_node_count(),
file=session.file_name, file=session.file_name,
) )
@ -521,7 +522,9 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
node_links = get_links(session, node) node_links = get_links(session, node)
links.extend(node_links) links.extend(node_links)
session_proto = core_pb2.Session(state=session.state, nodes=nodes, links=links) session_proto = core_pb2.Session(
state=session.state.value, nodes=nodes, links=links
)
return core_pb2.GetSessionResponse(session=session_proto) return core_pb2.GetSessionResponse(session=session_proto)
def AddSessionServer( def AddSessionServer(
@ -718,7 +721,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
if request.source: if request.source:
source = request.source source = request.source
if not has_geo: if not has_geo:
node_data = node.data(0, source=source) node_data = node.data(source=source)
session.broadcast_node(node_data) session.broadcast_node(node_data)
except CoreError: except CoreError:
result = False result = False
@ -895,7 +898,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
for state in session._hooks: for state in session._hooks:
state_hooks = session._hooks[state] state_hooks = session._hooks[state]
for file_name, file_data in state_hooks: for file_name, file_data in state_hooks:
hook = core_pb2.Hook(state=state, file=file_name, data=file_data) hook = core_pb2.Hook(state=state.value, file=file_name, data=file_data)
hooks.append(hook) hooks.append(hook)
return core_pb2.GetHooksResponse(hooks=hooks) return core_pb2.GetHooksResponse(hooks=hooks)
@ -912,7 +915,8 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
logging.debug("add hook: %s", request) logging.debug("add hook: %s", request)
session = self.get_session(request.session_id, context) session = self.get_session(request.session_id, context)
hook = request.hook hook = request.hook
session.add_hook(hook.state, hook.file, None, hook.data) state = EventTypes(hook.state)
session.add_hook(state, hook.file, None, hook.data)
return core_pb2.AddHookResponse(result=True) return core_pb2.AddHookResponse(result=True)
def GetMobilityConfigs( def GetMobilityConfigs(
@ -1266,7 +1270,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
session.mobility.set_model_config( session.mobility.set_model_config(
wlan_config.node_id, BasicRangeModel.name, wlan_config.config wlan_config.node_id, BasicRangeModel.name, wlan_config.config
) )
if session.state == EventTypes.RUNTIME_STATE.value: if session.state == EventTypes.RUNTIME_STATE:
node = self.get_node(session, wlan_config.node_id, context) node = self.get_node(session, wlan_config.node_id, context)
node.updatemodel(wlan_config.config) node.updatemodel(wlan_config.config)
return core_pb2.SetWlanConfigResponse(result=True) return core_pb2.SetWlanConfigResponse(result=True)
@ -1491,12 +1495,12 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
if emane_one.id == emane_two.id: if emane_one.id == emane_two.id:
if request.linked: if request.linked:
flag = MessageFlags.ADD.value flag = MessageFlags.ADD
else: else:
flag = MessageFlags.DELETE.value flag = MessageFlags.DELETE
link = LinkData( link = LinkData(
message_type=flag, message_type=flag,
link_type=LinkTypes.WIRELESS.value, link_type=LinkTypes.WIRELESS,
node1_id=node_one.id, node1_id=node_one.id,
node2_id=node_two.id, node2_id=node_two.id,
network_id=emane_one.id, network_id=emane_one.id,

View file

@ -13,7 +13,7 @@ from enum import Enum
import netaddr import netaddr
from core.api.tlv import structutils from core.api.tlv import structutils
from core.emulator.enumerations import ( from core.api.tlv.enumerations import (
ConfigTlvs, ConfigTlvs,
EventTlvs, EventTlvs,
ExceptionTlvs, ExceptionTlvs,
@ -21,12 +21,11 @@ from core.emulator.enumerations import (
FileTlvs, FileTlvs,
InterfaceTlvs, InterfaceTlvs,
LinkTlvs, LinkTlvs,
MessageFlags,
MessageTypes, MessageTypes,
NodeTlvs, NodeTlvs,
RegisterTlvs,
SessionTlvs, SessionTlvs,
) )
from core.emulator.enumerations import MessageFlags, RegisterTlvs
class CoreTlvData: class CoreTlvData:

View file

@ -15,26 +15,28 @@ from queue import Empty, Queue
from core import utils from core import utils
from core.api.tlv import coreapi, dataconversion, structutils from core.api.tlv import coreapi, dataconversion, structutils
from core.config import ConfigShim from core.api.tlv.dataconversion import ConfigShim
from core.emulator.data import ConfigData, EventData, ExceptionData, FileData from core.api.tlv.enumerations import (
from core.emulator.emudata import InterfaceData, LinkOptions, NodeOptions
from core.emulator.enumerations import (
ConfigDataTypes,
ConfigFlags, ConfigFlags,
ConfigTlvs, ConfigTlvs,
EventTlvs, EventTlvs,
EventTypes,
ExceptionTlvs, ExceptionTlvs,
ExecuteTlvs, ExecuteTlvs,
FileTlvs, FileTlvs,
LinkTlvs, LinkTlvs,
LinkTypes,
MessageFlags,
MessageTypes, MessageTypes,
NodeTlvs, NodeTlvs,
SessionTlvs,
)
from core.emulator.data import ConfigData, EventData, ExceptionData, FileData
from core.emulator.emudata import InterfaceData, LinkOptions, NodeOptions
from core.emulator.enumerations import (
ConfigDataTypes,
EventTypes,
LinkTypes,
MessageFlags,
NodeTypes, NodeTypes,
RegisterTlvs, RegisterTlvs,
SessionTlvs,
) )
from core.errors import CoreCommandError, CoreError from core.errors import CoreCommandError, CoreError
from core.location.mobility import BasicRangeModel from core.location.mobility import BasicRangeModel
@ -228,7 +230,7 @@ class CoreHandler(socketserver.BaseRequestHandler):
coreapi.CoreEventTlv, coreapi.CoreEventTlv,
[ [
(EventTlvs.NODE, event_data.node), (EventTlvs.NODE, event_data.node),
(EventTlvs.TYPE, event_data.event_type), (EventTlvs.TYPE, event_data.event_type.value),
(EventTlvs.NAME, event_data.name), (EventTlvs.NAME, event_data.name),
(EventTlvs.DATA, event_data.data), (EventTlvs.DATA, event_data.data),
(EventTlvs.TIME, event_data.time), (EventTlvs.TIME, event_data.time),
@ -265,7 +267,7 @@ class CoreHandler(socketserver.BaseRequestHandler):
(FileTlvs.COMPRESSED_DATA, file_data.compressed_data), (FileTlvs.COMPRESSED_DATA, file_data.compressed_data),
], ],
) )
message = coreapi.CoreFileMessage.pack(file_data.message_type, tlv_data) message = coreapi.CoreFileMessage.pack(file_data.message_type.value, tlv_data)
try: try:
self.sendall(message) self.sendall(message)
@ -356,7 +358,7 @@ class CoreHandler(socketserver.BaseRequestHandler):
(LinkTlvs.BURST, link_data.burst), (LinkTlvs.BURST, link_data.burst),
(LinkTlvs.SESSION, link_data.session), (LinkTlvs.SESSION, link_data.session),
(LinkTlvs.MBURST, link_data.mburst), (LinkTlvs.MBURST, link_data.mburst),
(LinkTlvs.TYPE, link_data.link_type), (LinkTlvs.TYPE, link_data.link_type.value),
(LinkTlvs.GUI_ATTRIBUTES, link_data.gui_attributes), (LinkTlvs.GUI_ATTRIBUTES, link_data.gui_attributes),
(LinkTlvs.UNIDIRECTIONAL, link_data.unidirectional), (LinkTlvs.UNIDIRECTIONAL, link_data.unidirectional),
(LinkTlvs.EMULATION_ID, link_data.emulation_id), (LinkTlvs.EMULATION_ID, link_data.emulation_id),
@ -380,7 +382,7 @@ class CoreHandler(socketserver.BaseRequestHandler):
], ],
) )
message = coreapi.CoreLinkMessage.pack(link_data.message_type, tlv_data) message = coreapi.CoreLinkMessage.pack(link_data.message_type.value, tlv_data)
try: try:
self.sendall(message) self.sendall(message)
@ -396,7 +398,6 @@ class CoreHandler(socketserver.BaseRequestHandler):
logging.info( logging.info(
"GUI has connected to session %d at %s", self.session.id, time.ctime() "GUI has connected to session %d at %s", self.session.id, time.ctime()
) )
tlv_data = b"" tlv_data = b""
tlv_data += coreapi.CoreRegisterTlv.pack( tlv_data += coreapi.CoreRegisterTlv.pack(
RegisterTlvs.EXECUTE_SERVER.value, "core-daemon" RegisterTlvs.EXECUTE_SERVER.value, "core-daemon"
@ -406,29 +407,29 @@ class CoreHandler(socketserver.BaseRequestHandler):
) )
tlv_data += coreapi.CoreRegisterTlv.pack(RegisterTlvs.UTILITY.value, "broker") tlv_data += coreapi.CoreRegisterTlv.pack(RegisterTlvs.UTILITY.value, "broker")
tlv_data += coreapi.CoreRegisterTlv.pack( tlv_data += coreapi.CoreRegisterTlv.pack(
self.session.location.config_type, self.session.location.name self.session.location.config_type.value, self.session.location.name
) )
tlv_data += coreapi.CoreRegisterTlv.pack( tlv_data += coreapi.CoreRegisterTlv.pack(
self.session.mobility.config_type, self.session.mobility.name self.session.mobility.config_type.value, self.session.mobility.name
) )
for model_name in self.session.mobility.models: for model_name in self.session.mobility.models:
model_class = self.session.mobility.models[model_name] model_class = self.session.mobility.models[model_name]
tlv_data += coreapi.CoreRegisterTlv.pack( tlv_data += coreapi.CoreRegisterTlv.pack(
model_class.config_type, model_class.name model_class.config_type.value, model_class.name
) )
tlv_data += coreapi.CoreRegisterTlv.pack( tlv_data += coreapi.CoreRegisterTlv.pack(
self.session.services.config_type, self.session.services.name self.session.services.config_type.value, self.session.services.name
) )
tlv_data += coreapi.CoreRegisterTlv.pack( tlv_data += coreapi.CoreRegisterTlv.pack(
self.session.emane.config_type, self.session.emane.name self.session.emane.config_type.value, self.session.emane.name
) )
for model_name in self.session.emane.models: for model_name in self.session.emane.models:
model_class = self.session.emane.models[model_name] model_class = self.session.emane.models[model_name]
tlv_data += coreapi.CoreRegisterTlv.pack( tlv_data += coreapi.CoreRegisterTlv.pack(
model_class.config_type, model_class.name model_class.config_type.value, model_class.name
) )
tlv_data += coreapi.CoreRegisterTlv.pack( tlv_data += coreapi.CoreRegisterTlv.pack(
self.session.options.config_type, self.session.options.name self.session.options.config_type.value, self.session.options.name
) )
tlv_data += coreapi.CoreRegisterTlv.pack(RegisterTlvs.UTILITY.value, "metadata") tlv_data += coreapi.CoreRegisterTlv.pack(RegisterTlvs.UTILITY.value, "metadata")
@ -723,7 +724,7 @@ class CoreHandler(socketserver.BaseRequestHandler):
if message.flags & MessageFlags.STRING.value: if message.flags & MessageFlags.STRING.value:
self.node_status_request[node.id] = True self.node_status_request[node.id] = True
if self.session.state == EventTypes.RUNTIME_STATE.value: if self.session.state == EventTypes.RUNTIME_STATE:
self.send_node_emulation_id(node.id) self.send_node_emulation_id(node.id)
elif message.flags & MessageFlags.DELETE.value: elif message.flags & MessageFlags.DELETE.value:
with self._shutdown_lock: with self._shutdown_lock:
@ -966,7 +967,7 @@ class CoreHandler(socketserver.BaseRequestHandler):
retries = 10 retries = 10
# wait for session to enter RUNTIME state, to prevent GUI from # wait for session to enter RUNTIME state, to prevent GUI from
# connecting while nodes are still being instantiated # connecting while nodes are still being instantiated
while session.state != EventTypes.RUNTIME_STATE.value: while session.state != EventTypes.RUNTIME_STATE:
logging.debug( logging.debug(
"waiting for session %d to enter RUNTIME state", sid "waiting for session %d to enter RUNTIME state", sid
) )
@ -1375,7 +1376,7 @@ class CoreHandler(socketserver.BaseRequestHandler):
parsed_config = ConfigShim.str_to_dict(values_str) parsed_config = ConfigShim.str_to_dict(values_str)
self.session.mobility.set_model_config(node_id, object_name, parsed_config) self.session.mobility.set_model_config(node_id, object_name, parsed_config)
if self.session.state == EventTypes.RUNTIME_STATE.value and parsed_config: if self.session.state == EventTypes.RUNTIME_STATE and parsed_config:
try: try:
node = self.session.get_node(node_id) node = self.session.get_node(node_id)
if object_name == BasicRangeModel.name: if object_name == BasicRangeModel.name:
@ -1502,6 +1503,7 @@ class CoreHandler(socketserver.BaseRequestHandler):
logging.error("error setting hook having state '%s'", state) logging.error("error setting hook having state '%s'", state)
return () return ()
state = int(state) state = int(state)
state = EventTypes(state)
self.session.add_hook(state, file_name, source_name, data) self.session.add_hook(state, file_name, source_name, data)
return () return ()
@ -1538,9 +1540,11 @@ class CoreHandler(socketserver.BaseRequestHandler):
:return: reply messages :return: reply messages
:raises core.CoreError: when event type <= SHUTDOWN_STATE and not a known node id :raises core.CoreError: when event type <= SHUTDOWN_STATE and not a known node id
""" """
event_type_value = message.get_tlv(EventTlvs.TYPE.value)
event_type = EventTypes(event_type_value)
event_data = EventData( event_data = EventData(
node=message.get_tlv(EventTlvs.NODE.value), node=message.get_tlv(EventTlvs.NODE.value),
event_type=message.get_tlv(EventTlvs.TYPE.value), event_type=event_type,
name=message.get_tlv(EventTlvs.NAME.value), name=message.get_tlv(EventTlvs.NAME.value),
data=message.get_tlv(EventTlvs.DATA.value), data=message.get_tlv(EventTlvs.DATA.value),
time=message.get_tlv(EventTlvs.TIME.value), time=message.get_tlv(EventTlvs.TIME.value),
@ -1549,7 +1553,6 @@ class CoreHandler(socketserver.BaseRequestHandler):
if event_data.event_type is None: if event_data.event_type is None:
raise NotImplementedError("Event message missing event type") raise NotImplementedError("Event message missing event type")
event_type = EventTypes(event_data.event_type)
node_id = event_data.node node_id = event_data.node
logging.debug("handling event %s at %s", event_type.name, time.ctime()) logging.debug("handling event %s at %s", event_type.name, time.ctime())
@ -1667,25 +1670,19 @@ class CoreHandler(socketserver.BaseRequestHandler):
unknown.append(service_name) unknown.append(service_name)
continue continue
if ( if event_type in [EventTypes.STOP, EventTypes.RESTART]:
event_type == EventTypes.STOP.value
or event_type == EventTypes.RESTART.value
):
status = self.session.services.stop_service(node, service) status = self.session.services.stop_service(node, service)
if status: if status:
fail += f"Stop {service.name}," fail += f"Stop {service.name},"
if ( if event_type in [EventTypes.START, EventTypes.RESTART]:
event_type == EventTypes.START.value
or event_type == EventTypes.RESTART.value
):
status = self.session.services.startup_service(node, service) status = self.session.services.startup_service(node, service)
if status: if status:
fail += f"Start ({service.name})," fail += f"Start ({service.name}),"
if event_type == EventTypes.PAUSE.value: if event_type == EventTypes.PAUSE:
status = self.session.services.validate_service(node, service) status = self.session.services.validate_service(node, service)
if status: if status:
fail += f"{service.name}," fail += f"{service.name},"
if event_type == EventTypes.RECONFIGURE.value: if event_type == EventTypes.RECONFIGURE:
self.session.services.service_reconfigure(node, service) self.session.services.service_reconfigure(node, service)
fail_data = "" fail_data = ""
@ -1845,11 +1842,11 @@ class CoreHandler(socketserver.BaseRequestHandler):
with self.session._nodes_lock: with self.session._nodes_lock:
for node_id in self.session.nodes: for node_id in self.session.nodes:
node = self.session.nodes[node_id] node = self.session.nodes[node_id]
node_data = node.data(message_type=MessageFlags.ADD.value) node_data = node.data(message_type=MessageFlags.ADD)
if node_data: if node_data:
nodes_data.append(node_data) nodes_data.append(node_data)
node_links = node.all_link_data(flags=MessageFlags.ADD.value) node_links = node.all_link_data(flags=MessageFlags.ADD)
for link_data in node_links: for link_data in node_links:
links_data.append(link_data) links_data.append(link_data)
@ -1917,7 +1914,7 @@ class CoreHandler(socketserver.BaseRequestHandler):
for file_name, config_data in self.session.services.all_files(service): for file_name, config_data in self.session.services.all_files(service):
file_data = FileData( file_data = FileData(
message_type=MessageFlags.ADD.value, message_type=MessageFlags.ADD,
node=node_id, node=node_id,
name=str(file_name), name=str(file_name),
type=opaque, type=opaque,
@ -1931,7 +1928,7 @@ class CoreHandler(socketserver.BaseRequestHandler):
for state in sorted(self.session._hooks.keys()): for state in sorted(self.session._hooks.keys()):
for file_name, config_data in self.session._hooks[state]: for file_name, config_data in self.session._hooks[state]:
file_data = FileData( file_data = FileData(
message_type=MessageFlags.ADD.value, message_type=MessageFlags.ADD,
name=str(file_name), name=str(file_name),
type=f"hook:{state}", type=f"hook:{state}",
data=str(config_data), data=str(config_data),
@ -2052,7 +2049,7 @@ class CoreUdpHandler(CoreHandler):
current_session = self.server.mainserver.coreemu.sessions[session_id] current_session = self.server.mainserver.coreemu.sessions[session_id]
current_node_count = current_session.get_node_count() current_node_count = current_session.get_node_count()
if ( if (
current_session.state == EventTypes.RUNTIME_STATE.value current_session.state == EventTypes.RUNTIME_STATE
and current_node_count > node_count and current_node_count > node_count
): ):
node_count = current_node_count node_count = current_node_count

View file

@ -1,9 +1,14 @@
""" """
Converts CORE data objects into legacy API messages. Converts CORE data objects into legacy API messages.
""" """
import logging
from collections import OrderedDict
from typing import Dict, List
from core.api.tlv import coreapi, structutils from core.api.tlv import coreapi, structutils
from core.emulator.enumerations import ConfigTlvs, NodeTlvs from core.api.tlv.enumerations import ConfigTlvs, NodeTlvs
from core.config import ConfigGroup, ConfigurableOptions
from core.emulator.data import ConfigData
def convert_node(node_data): def convert_node(node_data):
@ -17,7 +22,7 @@ def convert_node(node_data):
coreapi.CoreNodeTlv, coreapi.CoreNodeTlv,
[ [
(NodeTlvs.NUMBER, node_data.id), (NodeTlvs.NUMBER, node_data.id),
(NodeTlvs.TYPE, node_data.node_type), (NodeTlvs.TYPE, node_data.node_type.value),
(NodeTlvs.NAME, node_data.name), (NodeTlvs.NAME, node_data.name),
(NodeTlvs.IP_ADDRESS, node_data.ip_address), (NodeTlvs.IP_ADDRESS, node_data.ip_address),
(NodeTlvs.MAC_ADDRESS, node_data.mac_address), (NodeTlvs.MAC_ADDRESS, node_data.mac_address),
@ -38,7 +43,7 @@ def convert_node(node_data):
(NodeTlvs.OPAQUE, node_data.opaque), (NodeTlvs.OPAQUE, node_data.opaque),
], ],
) )
return coreapi.CoreNodeMessage.pack(node_data.message_type, tlv_data) return coreapi.CoreNodeMessage.pack(node_data.message_type.value, tlv_data)
def convert_config(config_data): def convert_config(config_data):
@ -67,3 +72,102 @@ def convert_config(config_data):
], ],
) )
return coreapi.CoreConfMessage.pack(config_data.message_type, tlv_data) return coreapi.CoreConfMessage.pack(config_data.message_type, tlv_data)
class ConfigShim:
"""
Provides helper methods for converting newer configuration values into TLV
compatible formats.
"""
@classmethod
def str_to_dict(cls, key_values: str) -> Dict[str, str]:
"""
Converts a TLV key/value string into an ordered mapping.
:param key_values:
:return: ordered mapping of key/value pairs
"""
key_values = key_values.split("|")
values = OrderedDict()
for key_value in key_values:
key, value = key_value.split("=", 1)
values[key] = value
return values
@classmethod
def groups_to_str(cls, config_groups: List[ConfigGroup]) -> str:
"""
Converts configuration groups to a TLV formatted string.
:param config_groups: configuration groups to format
:return: TLV configuration group string
"""
group_strings = []
for config_group in config_groups:
group_string = (
f"{config_group.name}:{config_group.start}-{config_group.stop}"
)
group_strings.append(group_string)
return "|".join(group_strings)
@classmethod
def config_data(
cls,
flags: int,
node_id: int,
type_flags: int,
configurable_options: ConfigurableOptions,
config: Dict[str, str],
) -> ConfigData:
"""
Convert this class to a Config API message. Some TLVs are defined
by the class, but node number, conf type flags, and values must
be passed in.
:param flags: message flags
:param node_id: node id
:param type_flags: type flags
:param configurable_options: options to create config data for
:param config: configuration values for options
:return: configuration data object
"""
key_values = None
captions = None
data_types = []
possible_values = []
logging.debug("configurable: %s", configurable_options)
logging.debug("configuration options: %s", configurable_options.configurations)
logging.debug("configuration data: %s", config)
for configuration in configurable_options.configurations():
if not captions:
captions = configuration.label
else:
captions += f"|{configuration.label}"
data_types.append(configuration.type.value)
options = ",".join(configuration.options)
possible_values.append(options)
_id = configuration.id
config_value = config.get(_id, configuration.default)
key_value = f"{_id}={config_value}"
if not key_values:
key_values = key_value
else:
key_values += f"|{key_value}"
groups_str = cls.groups_to_str(configurable_options.config_groups())
return ConfigData(
message_type=flags,
node=node_id,
object=configurable_options.name,
type=type_flags,
data_types=tuple(data_types),
data_values=key_values,
captions=captions,
possible_values="|".join(possible_values),
bitmap=configurable_options.bitmap,
groups=groups_str,
)

View file

@ -0,0 +1,212 @@
"""
Enumerations specific to the CORE TLV API.
"""
from enum import Enum
CORE_API_PORT = 4038
class MessageTypes(Enum):
"""
CORE message types.
"""
NODE = 0x01
LINK = 0x02
EXECUTE = 0x03
REGISTER = 0x04
CONFIG = 0x05
FILE = 0x06
INTERFACE = 0x07
EVENT = 0x08
SESSION = 0x09
EXCEPTION = 0x0A
class NodeTlvs(Enum):
"""
Node type, length, value enumerations.
"""
NUMBER = 0x01
TYPE = 0x02
NAME = 0x03
IP_ADDRESS = 0x04
MAC_ADDRESS = 0x05
IP6_ADDRESS = 0x06
MODEL = 0x07
EMULATION_SERVER = 0x08
SESSION = 0x0A
X_POSITION = 0x20
Y_POSITION = 0x21
CANVAS = 0x22
EMULATION_ID = 0x23
NETWORK_ID = 0x24
SERVICES = 0x25
LATITUDE = 0x30
LONGITUDE = 0x31
ALTITUDE = 0x32
ICON = 0x42
OPAQUE = 0x50
class LinkTlvs(Enum):
"""
Link type, length, value enumerations.
"""
N1_NUMBER = 0x01
N2_NUMBER = 0x02
DELAY = 0x03
BANDWIDTH = 0x04
PER = 0x05
DUP = 0x06
JITTER = 0x07
MER = 0x08
BURST = 0x09
SESSION = 0x0A
MBURST = 0x10
TYPE = 0x20
GUI_ATTRIBUTES = 0x21
UNIDIRECTIONAL = 0x22
EMULATION_ID = 0x23
NETWORK_ID = 0x24
KEY = 0x25
INTERFACE1_NUMBER = 0x30
INTERFACE1_IP4 = 0x31
INTERFACE1_IP4_MASK = 0x32
INTERFACE1_MAC = 0x33
INTERFACE1_IP6 = 0x34
INTERFACE1_IP6_MASK = 0x35
INTERFACE2_NUMBER = 0x36
INTERFACE2_IP4 = 0x37
INTERFACE2_IP4_MASK = 0x38
INTERFACE2_MAC = 0x39
INTERFACE2_IP6 = 0x40
INTERFACE2_IP6_MASK = 0x41
INTERFACE1_NAME = 0x42
INTERFACE2_NAME = 0x43
OPAQUE = 0x50
class ExecuteTlvs(Enum):
"""
Execute type, length, value enumerations.
"""
NODE = 0x01
NUMBER = 0x02
TIME = 0x03
COMMAND = 0x04
RESULT = 0x05
STATUS = 0x06
SESSION = 0x0A
class ConfigTlvs(Enum):
"""
Configuration type, length, value enumerations.
"""
NODE = 0x01
OBJECT = 0x02
TYPE = 0x03
DATA_TYPES = 0x04
VALUES = 0x05
CAPTIONS = 0x06
BITMAP = 0x07
POSSIBLE_VALUES = 0x08
GROUPS = 0x09
SESSION = 0x0A
INTERFACE_NUMBER = 0x0B
NETWORK_ID = 0x24
OPAQUE = 0x50
class ConfigFlags(Enum):
"""
Configuration flags.
"""
NONE = 0x00
REQUEST = 0x01
UPDATE = 0x02
RESET = 0x03
class FileTlvs(Enum):
"""
File type, length, value enumerations.
"""
NODE = 0x01
NAME = 0x02
MODE = 0x03
NUMBER = 0x04
TYPE = 0x05
SOURCE_NAME = 0x06
SESSION = 0x0A
DATA = 0x10
COMPRESSED_DATA = 0x11
class InterfaceTlvs(Enum):
"""
Interface type, length, value enumerations.
"""
NODE = 0x01
NUMBER = 0x02
NAME = 0x03
IP_ADDRESS = 0x04
MASK = 0x05
MAC_ADDRESS = 0x06
IP6_ADDRESS = 0x07
IP6_MASK = 0x08
TYPE = 0x09
SESSION = 0x0A
STATE = 0x0B
EMULATION_ID = 0x23
NETWORK_ID = 0x24
class EventTlvs(Enum):
"""
Event type, length, value enumerations.
"""
NODE = 0x01
TYPE = 0x02
NAME = 0x03
DATA = 0x04
TIME = 0x05
SESSION = 0x0A
class SessionTlvs(Enum):
"""
Session type, length, value enumerations.
"""
NUMBER = 0x01
NAME = 0x02
FILE = 0x03
NODE_COUNT = 0x04
DATE = 0x05
THUMB = 0x06
USER = 0x07
OPAQUE = 0x0A
class ExceptionTlvs(Enum):
"""
Exception type, length, value enumerations.
"""
NODE = 0x01
SESSION = 0x02
LEVEL = 0x03
SOURCE = 0x04
DATE = 0x05
TEXT = 0x06
OPAQUE = 0x0A

View file

@ -7,7 +7,6 @@ from collections import OrderedDict
from typing import TYPE_CHECKING, Dict, List, Tuple, Type, Union from typing import TYPE_CHECKING, Dict, List, Tuple, Type, Union
from core.emane.nodes import EmaneNet from core.emane.nodes import EmaneNet
from core.emulator.data import ConfigData
from core.emulator.enumerations import ConfigDataTypes from core.emulator.enumerations import ConfigDataTypes
from core.nodes.network import WlanNode from core.nodes.network import WlanNode
@ -110,104 +109,6 @@ class ConfigurableOptions:
) )
class ConfigShim:
"""
Provides helper methods for converting newer configuration values into TLV compatible formats.
"""
@classmethod
def str_to_dict(cls, key_values: str) -> Dict[str, str]:
"""
Converts a TLV key/value string into an ordered mapping.
:param key_values:
:return: ordered mapping of key/value pairs
"""
key_values = key_values.split("|")
values = OrderedDict()
for key_value in key_values:
key, value = key_value.split("=", 1)
values[key] = value
return values
@classmethod
def groups_to_str(cls, config_groups: List[ConfigGroup]) -> str:
"""
Converts configuration groups to a TLV formatted string.
:param config_groups: configuration groups to format
:return: TLV configuration group string
"""
group_strings = []
for config_group in config_groups:
group_string = (
f"{config_group.name}:{config_group.start}-{config_group.stop}"
)
group_strings.append(group_string)
return "|".join(group_strings)
@classmethod
def config_data(
cls,
flags: int,
node_id: int,
type_flags: int,
configurable_options: ConfigurableOptions,
config: Dict[str, str],
) -> ConfigData:
"""
Convert this class to a Config API message. Some TLVs are defined
by the class, but node number, conf type flags, and values must
be passed in.
:param flags: message flags
:param node_id: node id
:param type_flags: type flags
:param configurable_options: options to create config data for
:param config: configuration values for options
:return: configuration data object
"""
key_values = None
captions = None
data_types = []
possible_values = []
logging.debug("configurable: %s", configurable_options)
logging.debug("configuration options: %s", configurable_options.configurations)
logging.debug("configuration data: %s", config)
for configuration in configurable_options.configurations():
if not captions:
captions = configuration.label
else:
captions += f"|{configuration.label}"
data_types.append(configuration.type.value)
options = ",".join(configuration.options)
possible_values.append(options)
_id = configuration.id
config_value = config.get(_id, configuration.default)
key_value = f"{_id}={config_value}"
if not key_values:
key_values = key_value
else:
key_values += f"|{key_value}"
groups_str = cls.groups_to_str(configurable_options.config_groups())
return ConfigData(
message_type=flags,
node=node_id,
object=configurable_options.name,
type=type_flags,
data_types=tuple(data_types),
data_values=key_values,
captions=captions,
possible_values="|".join(possible_values),
bitmap=configurable_options.bitmap,
groups=groups_str,
)
class ConfigurableManager: class ConfigurableManager:
""" """
Provides convenience methods for storing and retrieving configuration options for Provides convenience methods for storing and retrieving configuration options for

View file

@ -60,7 +60,7 @@ class EmaneManager(ModelManager):
""" """
name = "emane" name = "emane"
config_type = RegisterTlvs.EMULATION_SERVER.value config_type = RegisterTlvs.EMULATION_SERVER
SUCCESS, NOT_NEEDED, NOT_READY = (0, 1, 2) SUCCESS, NOT_NEEDED, NOT_READY = (0, 1, 2)
EVENTCFGVAR = "LIBEMANEEVENTSERVICECONFIG" EVENTCFGVAR = "LIBEMANEEVENTSERVICECONFIG"
DEFAULT_LOG_LEVEL = 3 DEFAULT_LOG_LEVEL = 3
@ -806,7 +806,7 @@ class EmaneManager(ModelManager):
# don"t use node.setposition(x,y,z) which generates an event # don"t use node.setposition(x,y,z) which generates an event
node.position.set(x, y, z) node.position.set(x, y, z)
node.position.set_geo(lon, lat, alt) node.position.set_geo(lon, lat, alt)
node_data = node.data(message_type=0, lat=lat, lon=lon, alt=alt) node_data = node.data(lat=lat, lon=lon, alt=alt)
self.session.broadcast_node(node_data) self.session.broadcast_node(node_data)
return True return True

View file

@ -33,8 +33,8 @@ class EmaneNet(CoreNetworkBase):
Emane controller object that exists in a session. Emane controller object that exists in a session.
""" """
apitype = NodeTypes.EMANE.value apitype = NodeTypes.EMANE
linktype = LinkTypes.WIRED.value linktype = LinkTypes.WIRED
type = "wlan" type = "wlan"
is_emane = True is_emane = True
@ -103,12 +103,12 @@ class EmaneNet(CoreNetworkBase):
set the EmaneModel associated with this node set the EmaneModel associated with this node
""" """
logging.info("adding model: %s", model.name) logging.info("adding model: %s", model.name)
if model.config_type == RegisterTlvs.WIRELESS.value: if model.config_type == RegisterTlvs.WIRELESS:
# EmaneModel really uses values from ConfigurableManager # EmaneModel really uses values from ConfigurableManager
# when buildnemxml() is called, not during init() # when buildnemxml() is called, not during init()
self.model = model(session=self.session, _id=self.id) self.model = model(session=self.session, _id=self.id)
self.model.update_config(config) self.model.update_config(config)
elif model.config_type == RegisterTlvs.MOBILITY.value: elif model.config_type == RegisterTlvs.MOBILITY:
self.mobility = model(session=self.session, _id=self.id) self.mobility = model(session=self.session, _id=self.id)
self.mobility.update_config(config) self.mobility.update_config(config)

View file

@ -1,35 +1,16 @@
""" """
Contains all legacy enumerations for interacting with legacy CORE code. Common enumerations used within CORE.
""" """
from enum import Enum from enum import Enum
CORE_API_VERSION = "1.23"
CORE_API_PORT = 4038
class MessageTypes(Enum):
"""
CORE message types.
"""
NODE = 0x01
LINK = 0x02
EXECUTE = 0x03
REGISTER = 0x04
CONFIG = 0x05
FILE = 0x06
INTERFACE = 0x07
EVENT = 0x08
SESSION = 0x09
EXCEPTION = 0x0A
class MessageFlags(Enum): class MessageFlags(Enum):
""" """
CORE message flags. CORE message flags.
""" """
NONE = 0x00
ADD = 0x01 ADD = 0x01
DELETE = 0x02 DELETE = 0x02
CRI = 0x04 CRI = 0x04
@ -39,33 +20,6 @@ class MessageFlags(Enum):
TTY = 0x40 TTY = 0x40
class NodeTlvs(Enum):
"""
Node type, length, value enumerations.
"""
NUMBER = 0x01
TYPE = 0x02
NAME = 0x03
IP_ADDRESS = 0x04
MAC_ADDRESS = 0x05
IP6_ADDRESS = 0x06
MODEL = 0x07
EMULATION_SERVER = 0x08
SESSION = 0x0A
X_POSITION = 0x20
Y_POSITION = 0x21
CANVAS = 0x22
EMULATION_ID = 0x23
NETWORK_ID = 0x24
SERVICES = 0x25
LATITUDE = 0x30
LONGITUDE = 0x31
ALTITUDE = 0x32
ICON = 0x42
OPAQUE = 0x50
class NodeTypes(Enum): class NodeTypes(Enum):
""" """
Node types. Node types.
@ -86,56 +40,6 @@ class NodeTypes(Enum):
LXC = 16 LXC = 16
class Rj45Models(Enum):
"""
RJ45 model types.
"""
LINKED = 0
WIRELESS = 1
INSTALLED = 2
# Link Message TLV Types
class LinkTlvs(Enum):
"""
Link type, length, value enumerations.
"""
N1_NUMBER = 0x01
N2_NUMBER = 0x02
DELAY = 0x03
BANDWIDTH = 0x04
PER = 0x05
DUP = 0x06
JITTER = 0x07
MER = 0x08
BURST = 0x09
SESSION = 0x0A
MBURST = 0x10
TYPE = 0x20
GUI_ATTRIBUTES = 0x21
UNIDIRECTIONAL = 0x22
EMULATION_ID = 0x23
NETWORK_ID = 0x24
KEY = 0x25
INTERFACE1_NUMBER = 0x30
INTERFACE1_IP4 = 0x31
INTERFACE1_IP4_MASK = 0x32
INTERFACE1_MAC = 0x33
INTERFACE1_IP6 = 0x34
INTERFACE1_IP6_MASK = 0x35
INTERFACE2_NUMBER = 0x36
INTERFACE2_IP4 = 0x37
INTERFACE2_IP4_MASK = 0x38
INTERFACE2_MAC = 0x39
INTERFACE2_IP6 = 0x40
INTERFACE2_IP6_MASK = 0x41
INTERFACE1_NAME = 0x42
INTERFACE2_NAME = 0x43
OPAQUE = 0x50
class LinkTypes(Enum): class LinkTypes(Enum):
""" """
Link types. Link types.
@ -145,20 +49,6 @@ class LinkTypes(Enum):
WIRED = 1 WIRED = 1
class ExecuteTlvs(Enum):
"""
Execute type, length, value enumerations.
"""
NODE = 0x01
NUMBER = 0x02
TIME = 0x03
COMMAND = 0x04
RESULT = 0x05
STATUS = 0x06
SESSION = 0x0A
class RegisterTlvs(Enum): class RegisterTlvs(Enum):
""" """
Register type, length, value enumerations. Register type, length, value enumerations.
@ -173,37 +63,6 @@ class RegisterTlvs(Enum):
SESSION = 0x0A SESSION = 0x0A
class ConfigTlvs(Enum):
"""
Configuration type, length, value enumerations.
"""
NODE = 0x01
OBJECT = 0x02
TYPE = 0x03
DATA_TYPES = 0x04
VALUES = 0x05
CAPTIONS = 0x06
BITMAP = 0x07
POSSIBLE_VALUES = 0x08
GROUPS = 0x09
SESSION = 0x0A
INTERFACE_NUMBER = 0x0B
NETWORK_ID = 0x24
OPAQUE = 0x50
class ConfigFlags(Enum):
"""
Configuration flags.
"""
NONE = 0x00
REQUEST = 0x01
UPDATE = 0x02
RESET = 0x03
class ConfigDataTypes(Enum): class ConfigDataTypes(Enum):
""" """
Configuration data types. Configuration data types.
@ -222,55 +81,6 @@ class ConfigDataTypes(Enum):
BOOL = 0x0B BOOL = 0x0B
class FileTlvs(Enum):
"""
File type, length, value enumerations.
"""
NODE = 0x01
NAME = 0x02
MODE = 0x03
NUMBER = 0x04
TYPE = 0x05
SOURCE_NAME = 0x06
SESSION = 0x0A
DATA = 0x10
COMPRESSED_DATA = 0x11
class InterfaceTlvs(Enum):
"""
Interface type, length, value enumerations.
"""
NODE = 0x01
NUMBER = 0x02
NAME = 0x03
IP_ADDRESS = 0x04
MASK = 0x05
MAC_ADDRESS = 0x06
IP6_ADDRESS = 0x07
IP6_MASK = 0x08
TYPE = 0x09
SESSION = 0x0A
STATE = 0x0B
EMULATION_ID = 0x23
NETWORK_ID = 0x24
class EventTlvs(Enum):
"""
Event type, length, value enumerations.
"""
NODE = 0x01
TYPE = 0x02
NAME = 0x03
DATA = 0x04
TIME = 0x05
SESSION = 0x0A
class EventTypes(Enum): class EventTypes(Enum):
""" """
Event types. Event types.
@ -293,34 +103,8 @@ class EventTypes(Enum):
RECONFIGURE = 14 RECONFIGURE = 14
INSTANTIATION_COMPLETE = 15 INSTANTIATION_COMPLETE = 15
def should_start(self) -> bool:
class SessionTlvs(Enum): return self.value > self.DEFINITION_STATE.value
"""
Session type, length, value enumerations.
"""
NUMBER = 0x01
NAME = 0x02
FILE = 0x03
NODE_COUNT = 0x04
DATE = 0x05
THUMB = 0x06
USER = 0x07
OPAQUE = 0x0A
class ExceptionTlvs(Enum):
"""
Exception type, length, value enumerations.
"""
NODE = 0x01
SESSION = 0x02
LEVEL = 0x03
SOURCE = 0x04
DATE = 0x05
TEXT = 0x06
OPAQUE = 0x0A
class ExceptionLevels(Enum): class ExceptionLevels(Enum):

View file

@ -112,8 +112,7 @@ class Session:
self.nodes = {} self.nodes = {}
self._nodes_lock = threading.Lock() self._nodes_lock = threading.Lock()
# TODO: should the default state be definition? self.state = EventTypes.DEFINITION_STATE
self.state = EventTypes.NONE.value
self._state_time = time.monotonic() self._state_time = time.monotonic()
self._state_file = os.path.join(self.session_dir, "state") self._state_file = os.path.join(self.session_dir, "state")
@ -121,7 +120,7 @@ class Session:
self._hooks = {} self._hooks = {}
self._state_hooks = {} self._state_hooks = {}
self.add_state_hook( self.add_state_hook(
state=EventTypes.RUNTIME_STATE.value, hook=self.runtime_state_hook state=EventTypes.RUNTIME_STATE, hook=self.runtime_state_hook
) )
# handlers for broadcasting information # handlers for broadcasting information
@ -345,7 +344,7 @@ class Session:
node_one.name, node_one.name,
node_two.name, node_two.name,
) )
start = self.state > EventTypes.DEFINITION_STATE.value start = self.state.should_start()
net_one = self.create_node(cls=PtpNet, start=start) net_one = self.create_node(cls=PtpNet, start=start)
# node to network # node to network
@ -578,7 +577,7 @@ class Session:
try: try:
# wireless link # wireless link
if link_options.type == LinkTypes.WIRELESS.value: if link_options.type == LinkTypes.WIRELESS:
raise CoreError("cannot update wireless link") raise CoreError("cannot update wireless link")
else: else:
if not node_one and not node_two: if not node_one and not node_two:
@ -680,7 +679,7 @@ class Session:
node_class = _cls node_class = _cls
# set node start based on current session state, override and check when rj45 # set node start based on current session state, override and check when rj45
start = self.state > EventTypes.DEFINITION_STATE.value start = self.state.should_start()
enable_rj45 = self.options.get_config("enablerj45") == "1" enable_rj45 = self.options.get_config("enablerj45") == "1"
if _type == NodeTypes.RJ45 and not enable_rj45: if _type == NodeTypes.RJ45 and not enable_rj45:
start = False start = False
@ -755,7 +754,7 @@ class Session:
# boot nodes after runtime, CoreNodes, Physical, and RJ45 are all nodes # boot nodes after runtime, CoreNodes, Physical, and RJ45 are all nodes
is_boot_node = isinstance(node, CoreNodeBase) and not isinstance(node, Rj45Node) is_boot_node = isinstance(node, CoreNodeBase) and not isinstance(node, Rj45Node)
if self.state == EventTypes.RUNTIME_STATE.value and is_boot_node: if self.state == EventTypes.RUNTIME_STATE and is_boot_node:
self.write_nodes() self.write_nodes()
self.add_remove_control_interface(node=node, remove=False) self.add_remove_control_interface(node=node, remove=False)
self.services.boot_services(node) self.services.boot_services(node)
@ -851,10 +850,7 @@ class Session:
:return: True if active, False otherwise :return: True if active, False otherwise
""" """
result = self.state in { result = self.state in {EventTypes.RUNTIME_STATE, EventTypes.DATACOLLECT_STATE}
EventTypes.RUNTIME_STATE.value,
EventTypes.DATACOLLECT_STATE.value,
}
logging.info("session(%s) checking if active: %s", self.id, result) logging.info("session(%s) checking if active: %s", self.id, result)
return result return result
@ -895,7 +891,9 @@ class Session:
""" """
CoreXmlWriter(self).write(file_name) CoreXmlWriter(self).write(file_name)
def add_hook(self, state: int, file_name: str, source_name: str, data: str) -> None: def add_hook(
self, state: EventTypes, file_name: str, source_name: str, data: str
) -> None:
""" """
Store a hook from a received file message. Store a hook from a received file message.
@ -905,9 +903,17 @@ class Session:
:param data: hook data :param data: hook data
:return: nothing :return: nothing
""" """
# hack to conform with old logic until updated logging.info(
state = f":{state}" "setting state hook: %s - %s from %s", state, file_name, source_name
self.set_hook(state, file_name, source_name, data) )
hook = file_name, data
state_hooks = self._hooks.setdefault(state, [])
state_hooks.append(hook)
# immediately run a hook if it is in the current state
if self.state == state:
logging.info("immediately running new state hook")
self.run_hook(hook)
def add_node_file( def add_node_file(
self, node_id: int, source_name: str, file_name: str, data: str self, node_id: int, source_name: str, file_name: str, data: str
@ -1072,10 +1078,8 @@ class Session:
:param send_event: if true, generate core API event messages :param send_event: if true, generate core API event messages
:return: nothing :return: nothing
""" """
state_value = state.value
state_name = state.name state_name = state.name
if self.state == state:
if self.state == state_value:
logging.info( logging.info(
"session(%s) is already in state: %s, skipping change", "session(%s) is already in state: %s, skipping change",
self.id, self.id,
@ -1083,33 +1087,32 @@ class Session:
) )
return return
self.state = state_value self.state = state
self._state_time = time.monotonic() self._state_time = time.monotonic()
logging.info("changing session(%s) to state %s", self.id, state_name) logging.info("changing session(%s) to state %s", self.id, state_name)
self.write_state(state)
self.write_state(state_value) self.run_hooks(state)
self.run_hooks(state_value) self.run_state_hooks(state)
self.run_state_hooks(state_value)
if send_event: if send_event:
event_data = EventData(event_type=state_value, time=str(time.monotonic())) event_data = EventData(event_type=state, time=str(time.monotonic()))
self.broadcast_event(event_data) self.broadcast_event(event_data)
def write_state(self, state: int) -> None: def write_state(self, state: EventTypes) -> None:
""" """
Write the current state to a state file in the session dir. Write the state to a state file in the session dir.
:param state: state to write to file :param state: state to write to file
:return: nothing :return: nothing
""" """
try: try:
state_file = open(self._state_file, "w") state_file = open(self._state_file, "w")
state_file.write(f"{state} {EventTypes(self.state).name}\n") state_file.write(f"{state.value} {state.name}\n")
state_file.close() state_file.close()
except IOError: except IOError:
logging.exception("error writing state file: %s", state) logging.exception("error writing state file: %s", state.name)
def run_hooks(self, state: int) -> None: def run_hooks(self, state: EventTypes) -> None:
""" """
Run hook scripts upon changing states. If hooks is not specified, run all hooks Run hook scripts upon changing states. If hooks is not specified, run all hooks
in the given state. in the given state.
@ -1213,7 +1216,7 @@ class Session:
except (OSError, subprocess.CalledProcessError): except (OSError, subprocess.CalledProcessError):
logging.exception("error running hook: %s", file_name) logging.exception("error running hook: %s", file_name)
def run_state_hooks(self, state: int) -> None: def run_state_hooks(self, state: EventTypes) -> None:
""" """
Run state hooks. Run state hooks.
@ -1224,16 +1227,17 @@ class Session:
try: try:
hook(state) hook(state)
except Exception: except Exception:
state_name = EventTypes(self.state).name
message = ( message = (
f"exception occured when running {state_name} state hook: {hook}" f"exception occured when running {state.name} state hook: {hook}"
) )
logging.exception(message) logging.exception(message)
self.exception( self.exception(
ExceptionLevels.ERROR, "Session.run_state_hooks", None, message ExceptionLevels.ERROR, "Session.run_state_hooks", None, message
) )
def add_state_hook(self, state: int, hook: Callable[[int], None]) -> None: def add_state_hook(
self, state: EventTypes, hook: Callable[[EventTypes], None]
) -> None:
""" """
Add a state hook. Add a state hook.
@ -1260,14 +1264,14 @@ class Session:
hooks = self._state_hooks.setdefault(state, []) hooks = self._state_hooks.setdefault(state, [])
hooks.remove(hook) hooks.remove(hook)
def runtime_state_hook(self, state: int) -> None: def runtime_state_hook(self, state: EventTypes) -> None:
""" """
Runtime state hook check. Runtime state hook check.
:param state: state to check :param state: state to check
:return: nothing :return: nothing
""" """
if state == EventTypes.RUNTIME_STATE.value: if state == EventTypes.RUNTIME_STATE:
self.emane.poststartup() self.emane.poststartup()
# create session deployed xml # create session deployed xml
@ -1511,7 +1515,7 @@ class Session:
self.mobility.startup() self.mobility.startup()
# notify listeners that instantiation is complete # notify listeners that instantiation is complete
event = EventData(event_type=EventTypes.INSTANTIATION_COMPLETE.value) event = EventData(event_type=EventTypes.INSTANTIATION_COMPLETE)
self.broadcast_event(event) self.broadcast_event(event)
# assume either all nodes have booted already, or there are some # assume either all nodes have booted already, or there are some
@ -1554,9 +1558,9 @@ class Session:
logging.debug( logging.debug(
"session(%s) checking if not in runtime state, current state: %s", "session(%s) checking if not in runtime state, current state: %s",
self.id, self.id,
EventTypes(self.state).name, self.state.name,
) )
if self.state == EventTypes.RUNTIME_STATE.value: if self.state == EventTypes.RUNTIME_STATE:
logging.info("valid runtime state found, returning") logging.info("valid runtime state found, returning")
return return
@ -1893,7 +1897,7 @@ class Session:
Return the current time we have been in the runtime state, or zero Return the current time we have been in the runtime state, or zero
if not in runtime. if not in runtime.
""" """
if self.state == EventTypes.RUNTIME_STATE.value: if self.state == EventTypes.RUNTIME_STATE:
return time.monotonic() - self._state_time return time.monotonic() - self._state_time
else: else:
return 0.0 return 0.0

View file

@ -57,7 +57,7 @@ class SessionConfig(ConfigurableManager, ConfigurableOptions):
label="SDT3D URL", label="SDT3D URL",
), ),
] ]
config_type = RegisterTlvs.UTILITY.value config_type = RegisterTlvs.UTILITY
def __init__(self) -> None: def __init__(self) -> None:
super().__init__() super().__init__()

View file

@ -21,7 +21,7 @@ class GeoLocation:
""" """
name = "location" name = "location"
config_type = RegisterTlvs.UTILITY.value config_type = RegisterTlvs.UTILITY
def __init__(self) -> None: def __init__(self) -> None:
""" """

View file

@ -36,7 +36,7 @@ class MobilityManager(ModelManager):
""" """
name = "MobilityManager" name = "MobilityManager"
config_type = RegisterTlvs.WIRELESS.value config_type = RegisterTlvs.WIRELESS
def __init__(self, session: "Session") -> None: def __init__(self, session: "Session") -> None:
""" """
@ -121,10 +121,7 @@ class MobilityManager(ModelManager):
logging.warning("Ignoring event for unknown model '%s'", model) logging.warning("Ignoring event for unknown model '%s'", model)
continue continue
if cls.config_type in [ if cls.config_type in [RegisterTlvs.WIRELESS, RegisterTlvs.MOBILITY]:
RegisterTlvs.WIRELESS.value,
RegisterTlvs.MOBILITY.value,
]:
model = node.mobility model = node.mobility
else: else:
continue continue
@ -142,17 +139,11 @@ class MobilityManager(ModelManager):
) )
continue continue
if ( if event_type in [EventTypes.STOP, EventTypes.RESTART]:
event_type == EventTypes.STOP.value
or event_type == EventTypes.RESTART.value
):
model.stop(move_initial=True) model.stop(move_initial=True)
if ( if event_type in [EventTypes.START, EventTypes.RESTART]:
event_type == EventTypes.START.value
or event_type == EventTypes.RESTART.value
):
model.start() model.start()
if event_type == EventTypes.PAUSE.value: if event_type == EventTypes.PAUSE:
model.pause() model.pause()
def sendevent(self, model: "WayPointMobility") -> None: def sendevent(self, model: "WayPointMobility") -> None:
@ -163,13 +154,13 @@ class MobilityManager(ModelManager):
:param model: mobility model to send event for :param model: mobility model to send event for
:return: nothing :return: nothing
""" """
event_type = EventTypes.NONE.value event_type = EventTypes.NONE
if model.state == model.STATE_STOPPED: if model.state == model.STATE_STOPPED:
event_type = EventTypes.STOP.value event_type = EventTypes.STOP
elif model.state == model.STATE_RUNNING: elif model.state == model.STATE_RUNNING:
event_type = EventTypes.START.value event_type = EventTypes.START
elif model.state == model.STATE_PAUSED: elif model.state == model.STATE_PAUSED:
event_type = EventTypes.PAUSE.value event_type = EventTypes.PAUSE
start_time = int(model.lasttime - model.timezero) start_time = int(model.lasttime - model.timezero)
end_time = int(model.endtime) end_time = int(model.endtime)
@ -212,7 +203,7 @@ class WirelessModel(ConfigurableOptions):
Used for managing arbitrary configuration parameters. Used for managing arbitrary configuration parameters.
""" """
config_type = RegisterTlvs.WIRELESS.value config_type = RegisterTlvs.WIRELESS
bitmap = None bitmap = None
position_callback = None position_callback = None
@ -226,7 +217,7 @@ class WirelessModel(ConfigurableOptions):
self.session = session self.session = session
self.id = _id self.id = _id
def all_link_data(self, flags: int) -> List: def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List:
""" """
May be used if the model can populate the GUI with wireless (green) May be used if the model can populate the GUI with wireless (green)
link lines. link lines.
@ -486,7 +477,10 @@ class BasicRangeModel(WirelessModel):
return True return True
def create_link_data( def create_link_data(
self, interface1: CoreInterface, interface2: CoreInterface, message_type: int self,
interface1: CoreInterface,
interface2: CoreInterface,
message_type: MessageFlags,
) -> LinkData: ) -> LinkData:
""" """
Create a wireless link/unlink data message. Create a wireless link/unlink data message.
@ -501,7 +495,7 @@ class BasicRangeModel(WirelessModel):
node1_id=interface1.node.id, node1_id=interface1.node.id,
node2_id=interface2.node.id, node2_id=interface2.node.id,
network_id=self.wlan.id, network_id=self.wlan.id,
link_type=LinkTypes.WIRELESS.value, link_type=LinkTypes.WIRELESS,
) )
def sendlinkmsg( def sendlinkmsg(
@ -516,14 +510,14 @@ class BasicRangeModel(WirelessModel):
:return: nothing :return: nothing
""" """
if unlink: if unlink:
message_type = MessageFlags.DELETE.value message_type = MessageFlags.DELETE
else: else:
message_type = MessageFlags.ADD.value message_type = MessageFlags.ADD
link_data = self.create_link_data(netif, netif2, message_type) link_data = self.create_link_data(netif, netif2, message_type)
self.session.broadcast_link(link_data) self.session.broadcast_link(link_data)
def all_link_data(self, flags: int) -> List[LinkData]: def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
""" """
Return a list of wireless link messages for when the GUI reconnects. Return a list of wireless link messages for when the GUI reconnects.
@ -578,7 +572,7 @@ class WayPointMobility(WirelessModel):
""" """
name = "waypoint" name = "waypoint"
config_type = RegisterTlvs.MOBILITY.value config_type = RegisterTlvs.MOBILITY
STATE_STOPPED = 0 STATE_STOPPED = 0
STATE_RUNNING = 1 STATE_RUNNING = 1
@ -818,7 +812,7 @@ class WayPointMobility(WirelessModel):
:return: nothing :return: nothing
""" """
node.position.set(x, y, z) node.position.set(x, y, z)
node_data = node.data(message_type=0) node_data = node.data()
self.session.broadcast_node(node_data) self.session.broadcast_node(node_data)
def setendtime(self) -> None: def setendtime(self) -> None:

View file

@ -14,7 +14,7 @@ from core import utils
from core.configservice.dependencies import ConfigServiceDependencies from core.configservice.dependencies import ConfigServiceDependencies
from core.constants import MOUNT_BIN, VNODED_BIN from core.constants import MOUNT_BIN, VNODED_BIN
from core.emulator.data import LinkData, NodeData from core.emulator.data import LinkData, NodeData
from core.emulator.enumerations import LinkTypes, NodeTypes from core.emulator.enumerations import LinkTypes, MessageFlags, NodeTypes
from core.errors import CoreCommandError, CoreError from core.errors import CoreCommandError, CoreError
from core.nodes import client from core.nodes import client
from core.nodes.interface import CoreInterface, TunTap, Veth from core.nodes.interface import CoreInterface, TunTap, Veth
@ -193,7 +193,7 @@ class NodeBase:
def data( def data(
self, self,
message_type: int, message_type: MessageFlags = MessageFlags.NONE,
lat: float = None, lat: float = None,
lon: float = None, lon: float = None,
alt: float = None, alt: float = None,
@ -244,7 +244,7 @@ class NodeBase:
return node_data return node_data
def all_link_data(self, flags: int) -> List: def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
""" """
Build CORE Link data for this object. There is no default Build CORE Link data for this object. There is no default
method for PyCoreObjs as PyCoreNodes do not implement this but method for PyCoreObjs as PyCoreNodes do not implement this but
@ -472,7 +472,7 @@ class CoreNode(CoreNodeBase):
Provides standard core node logic. Provides standard core node logic.
""" """
apitype = NodeTypes.DEFAULT.value apitype = NodeTypes.DEFAULT
valid_address_types = {"inet", "inet6", "inet6link"} valid_address_types = {"inet", "inet6", "inet6link"}
def __init__( def __init__(
@ -982,7 +982,7 @@ class CoreNetworkBase(NodeBase):
Base class for networks Base class for networks
""" """
linktype = LinkTypes.WIRED.value linktype = LinkTypes.WIRED
is_emane = False is_emane = False
def __init__( def __init__(
@ -1069,7 +1069,7 @@ class CoreNetworkBase(NodeBase):
with self._linked_lock: with self._linked_lock:
del self._linked[netif] del self._linked[netif]
def all_link_data(self, flags: int) -> List[LinkData]: def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
""" """
Build link data objects for this network. Each link object describes a link Build link data objects for this network. Each link object describes a link
between this network and a node. between this network and a node.

View file

@ -72,7 +72,7 @@ class DockerClient:
class DockerNode(CoreNode): class DockerNode(CoreNode):
apitype = NodeTypes.DOCKER.value apitype = NodeTypes.DOCKER
def __init__( def __init__(
self, self,

View file

@ -7,6 +7,7 @@ import time
from typing import TYPE_CHECKING, Callable, Dict, List, Tuple from typing import TYPE_CHECKING, Callable, Dict, List, Tuple
from core import utils from core import utils
from core.emulator.enumerations import MessageFlags
from core.errors import CoreCommandError from core.errors import CoreCommandError
from core.nodes.netclient import get_net_client from core.nodes.netclient import get_net_client
@ -552,7 +553,7 @@ class GreTap(CoreInterface):
""" """
return None return None
def all_link_data(self, flags: int) -> List: def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List:
""" """
Retrieve link data. Retrieve link data.

View file

@ -66,7 +66,7 @@ class LxdClient:
class LxcNode(CoreNode): class LxcNode(CoreNode):
apitype = NodeTypes.LXC.value apitype = NodeTypes.LXC
def __init__( def __init__(
self, self,

View file

@ -12,7 +12,7 @@ import netaddr
from core import utils from core import utils
from core.constants import EBTABLES_BIN, TC_BIN from core.constants import EBTABLES_BIN, TC_BIN
from core.emulator.data import LinkData, NodeData from core.emulator.data import LinkData, NodeData
from core.emulator.enumerations import LinkTypes, NodeTypes, RegisterTlvs from core.emulator.enumerations import LinkTypes, MessageFlags, NodeTypes, RegisterTlvs
from core.errors import CoreCommandError, CoreError from core.errors import CoreCommandError, CoreError
from core.nodes.base import CoreNetworkBase from core.nodes.base import CoreNetworkBase
from core.nodes.interface import CoreInterface, GreTap, Veth from core.nodes.interface import CoreInterface, GreTap, Veth
@ -848,7 +848,7 @@ class CtrlNet(CoreNetwork):
super().shutdown() super().shutdown()
def all_link_data(self, flags: int) -> List[LinkData]: def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
""" """
Do not include CtrlNet in link messages describing this session. Do not include CtrlNet in link messages describing this session.
@ -899,7 +899,7 @@ class PtpNet(CoreNetwork):
""" """
return None return None
def all_link_data(self, flags: int) -> List[LinkData]: def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
""" """
Build CORE API TLVs for a point-to-point link. One Link message Build CORE API TLVs for a point-to-point link. One Link message
describes this network. describes this network.
@ -999,7 +999,7 @@ class SwitchNode(CoreNetwork):
Provides switch functionality within a core node. Provides switch functionality within a core node.
""" """
apitype = NodeTypes.SWITCH.value apitype = NodeTypes.SWITCH
policy = "ACCEPT" policy = "ACCEPT"
type = "lanswitch" type = "lanswitch"
@ -1010,7 +1010,7 @@ class HubNode(CoreNetwork):
ports by turning off MAC address learning. ports by turning off MAC address learning.
""" """
apitype = NodeTypes.HUB.value apitype = NodeTypes.HUB
policy = "ACCEPT" policy = "ACCEPT"
type = "hub" type = "hub"
@ -1029,8 +1029,8 @@ class WlanNode(CoreNetwork):
Provides wireless lan functionality within a core node. Provides wireless lan functionality within a core node.
""" """
apitype = NodeTypes.WIRELESS_LAN.value apitype = NodeTypes.WIRELESS_LAN
linktype = LinkTypes.WIRED.value linktype = LinkTypes.WIRED
policy = "DROP" policy = "DROP"
type = "wlan" type = "wlan"
@ -1090,13 +1090,13 @@ class WlanNode(CoreNetwork):
:return: nothing :return: nothing
""" """
logging.debug("node(%s) setting model: %s", self.name, model.name) logging.debug("node(%s) setting model: %s", self.name, model.name)
if model.config_type == RegisterTlvs.WIRELESS.value: if model.config_type == RegisterTlvs.WIRELESS:
self.model = model(session=self.session, _id=self.id) self.model = model(session=self.session, _id=self.id)
for netif in self.netifs(): for netif in self.netifs():
netif.poshook = self.model.position_callback netif.poshook = self.model.position_callback
netif.setposition() netif.setposition()
self.updatemodel(config) self.updatemodel(config)
elif model.config_type == RegisterTlvs.MOBILITY.value: elif model.config_type == RegisterTlvs.MOBILITY:
self.mobility = model(session=self.session, _id=self.id) self.mobility = model(session=self.session, _id=self.id)
self.mobility.update_config(config) self.mobility.update_config(config)
@ -1115,7 +1115,7 @@ class WlanNode(CoreNetwork):
for netif in self.netifs(): for netif in self.netifs():
netif.setposition() netif.setposition()
def all_link_data(self, flags: int) -> List[LinkData]: def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
""" """
Retrieve all link data. Retrieve all link data.
@ -1133,6 +1133,6 @@ class TunnelNode(GreTapBridge):
Provides tunnel functionality in a core node. Provides tunnel functionality in a core node.
""" """
apitype = NodeTypes.TUNNEL.value apitype = NodeTypes.TUNNEL
policy = "ACCEPT" policy = "ACCEPT"
type = "tunnel" type = "tunnel"

View file

@ -264,7 +264,7 @@ class Rj45Node(CoreNodeBase, CoreInterface):
network. network.
""" """
apitype = NodeTypes.RJ45.value apitype = NodeTypes.RJ45
type = "rj45" type = "rj45"
def __init__( def __init__(

View file

@ -24,7 +24,7 @@ if TYPE_CHECKING:
def link_data_params(link_data: LinkData) -> Tuple[int, int, bool]: def link_data_params(link_data: LinkData) -> Tuple[int, int, bool]:
node_one = link_data.node1_id node_one = link_data.node1_id
node_two = link_data.node2_id node_two = link_data.node2_id
is_wireless = link_data.link_type == LinkTypes.WIRELESS.value is_wireless = link_data.link_type == LinkTypes.WIRELESS
return node_one, node_two, is_wireless return node_one, node_two, is_wireless
@ -90,7 +90,7 @@ class Sdt:
self.address = (self.url.hostname, self.url.port) self.address = (self.url.hostname, self.url.port)
self.protocol = self.url.scheme self.protocol = self.url.scheme
def connect(self, flags: int = 0) -> bool: def connect(self) -> bool:
""" """
Connect to the SDT address/port if enabled. Connect to the SDT address/port if enabled.
@ -100,7 +100,7 @@ class Sdt:
return False return False
if self.connected: if self.connected:
return True return True
if self.session.state == EventTypes.SHUTDOWN_STATE.value: if self.session.state == EventTypes.SHUTDOWN_STATE:
return False return False
self.seturl() self.seturl()
@ -122,7 +122,7 @@ class Sdt:
self.connected = True self.connected = True
# refresh all objects in SDT3D when connecting after session start # refresh all objects in SDT3D when connecting after session start
if not flags & MessageFlags.ADD.value and not self.sendobjs(): if not self.sendobjs():
return False return False
return True return True
@ -210,7 +210,7 @@ class Sdt:
self.add_node(node) self.add_node(node)
for net in nets: for net in nets:
all_links = net.all_link_data(flags=MessageFlags.ADD.value) all_links = net.all_link_data(flags=MessageFlags.ADD)
for link_data in all_links: for link_data in all_links:
is_wireless = isinstance(net, (WlanNode, EmaneNet)) is_wireless = isinstance(net, (WlanNode, EmaneNet))
if is_wireless and link_data.node1_id == net.id: if is_wireless and link_data.node1_id == net.id:
@ -302,7 +302,7 @@ class Sdt:
return return
# delete node # delete node
if node_data.message_type == MessageFlags.DELETE.value: if node_data.message_type == MessageFlags.DELETE:
self.cmd(f"delete node,{node_data.id}") self.cmd(f"delete node,{node_data.id}")
else: else:
x = node_data.x_position x = node_data.x_position
@ -375,9 +375,9 @@ class Sdt:
:param link_data: link data to handle :param link_data: link data to handle
:return: nothing :return: nothing
""" """
if link_data.message_type == MessageFlags.ADD.value: if link_data.message_type == MessageFlags.ADD:
params = link_data_params(link_data) params = link_data_params(link_data)
self.add_link(*params) self.add_link(*params)
elif link_data.message_type == MessageFlags.DELETE.value: elif link_data.message_type == MessageFlags.DELETE:
params = link_data_params(link_data) params = link_data_params(link_data)
self.delete_link(*params[:2]) self.delete_link(*params[:2])

View file

@ -315,7 +315,7 @@ class CoreServices:
""" """
name = "services" name = "services"
config_type = RegisterTlvs.UTILITY.value config_type = RegisterTlvs.UTILITY
def __init__(self, session: "Session") -> None: def __init__(self, session: "Session") -> None:
""" """
@ -672,7 +672,7 @@ class CoreServices:
filetypestr = "service:%s" % service.name filetypestr = "service:%s" % service.name
return FileData( return FileData(
message_type=MessageFlags.ADD.value, message_type=MessageFlags.ADD,
node=node.id, node=node.id,
name=filename, name=filename,
type=filetypestr, type=filetypestr,

View file

@ -551,7 +551,7 @@ class Babel(QuaggaService):
@classmethod @classmethod
def generatequaggaifcconfig(cls, node, ifc): def generatequaggaifcconfig(cls, node, ifc):
if ifc.net and ifc.net.linktype == LinkTypes.WIRELESS.value: if ifc.net and ifc.net.linktype == LinkTypes.WIRELESS:
return " babel wireless\n no babel split-horizon\n" return " babel wireless\n no babel split-horizon\n"
else: else:
return " babel wired\n babel split-horizon\n" return " babel wired\n babel split-horizon\n"

View file

@ -8,7 +8,7 @@ import core.nodes.physical
from core.emane.nodes import EmaneNet from core.emane.nodes import EmaneNet
from core.emulator.data import LinkData from core.emulator.data import LinkData
from core.emulator.emudata import InterfaceData, LinkOptions, NodeOptions from core.emulator.emudata import InterfaceData, LinkOptions, NodeOptions
from core.emulator.enumerations import NodeTypes from core.emulator.enumerations import EventTypes, NodeTypes
from core.nodes.base import CoreNetworkBase, CoreNodeBase, NodeBase from core.nodes.base import CoreNetworkBase, CoreNodeBase, NodeBase
from core.nodes.docker import DockerNode from core.nodes.docker import DockerNode
from core.nodes.lxd import LxcNode from core.nodes.lxd import LxcNode
@ -260,7 +260,7 @@ class NetworkElement(NodeElement):
def add_type(self) -> None: def add_type(self) -> None:
if self.node.apitype: if self.node.apitype:
node_type = NodeTypes(self.node.apitype).name node_type = self.node.apitype.name
else: else:
node_type = self.node.__class__.__name__ node_type = self.node.__class__.__name__
add_attribute(self.element, "type", node_type) add_attribute(self.element, "type", node_type)
@ -324,7 +324,7 @@ class CoreXmlWriter:
for file_name, data in self.session._hooks[state]: for file_name, data in self.session._hooks[state]:
hook = etree.SubElement(hooks, "hook") hook = etree.SubElement(hooks, "hook")
add_attribute(hook, "name", file_name) add_attribute(hook, "name", file_name)
add_attribute(hook, "state", state) add_attribute(hook, "state", state.value)
hook.text = data hook.text = data
if hooks.getchildren(): if hooks.getchildren():
@ -476,7 +476,7 @@ class CoreXmlWriter:
self.write_device(node) self.write_device(node)
# add known links # add known links
links.extend(node.all_link_data(0)) links.extend(node.all_link_data())
return links return links
@ -666,13 +666,11 @@ class CoreXmlReader:
for hook in session_hooks.iterchildren(): for hook in session_hooks.iterchildren():
name = hook.get("name") name = hook.get("name")
state = hook.get("state") state = get_int(hook, "state")
state = EventTypes(state)
data = hook.text data = hook.text
hook_type = f"hook:{state}"
logging.info("reading hook: state(%s) name(%s)", state, name) logging.info("reading hook: state(%s) name(%s)", state, name)
self.session.set_hook( self.session.add_hook(state, name, None, data)
hook_type, file_name=name, source_name=None, data=data
)
def read_session_origin(self) -> None: def read_session_origin(self) -> None:
session_origin = self.scenario.find("session_origin") session_origin = self.scenario.find("session_origin")

View file

@ -17,8 +17,8 @@ from core import constants
from core.api.grpc.server import CoreGrpcServer from core.api.grpc.server import CoreGrpcServer
from core.api.tlv.corehandlers import CoreHandler, CoreUdpHandler from core.api.tlv.corehandlers import CoreHandler, CoreUdpHandler
from core.api.tlv.coreserver import CoreServer, CoreUdpServer from core.api.tlv.coreserver import CoreServer, CoreUdpServer
from core.api.tlv.enumerations import CORE_API_PORT
from core.constants import CORE_CONF_DIR, COREDPY_VERSION from core.constants import CORE_CONF_DIR, COREDPY_VERSION
from core.emulator.enumerations import CORE_API_PORT
from core.utils import close_onexec, load_logging_config from core.utils import close_onexec, load_logging_config

View file

@ -9,12 +9,8 @@ import socket
import sys import sys
from core.api.tlv import coreapi from core.api.tlv import coreapi
from core.emulator.enumerations import ( from core.api.tlv.enumerations import CORE_API_PORT, MessageTypes, SessionTlvs
CORE_API_PORT, from core.emulator.enumerations import MessageFlags
MessageFlags,
MessageTypes,
SessionTlvs,
)
def print_available_tlvs(t, tlv_class): def print_available_tlvs(t, tlv_class):

View file

@ -114,7 +114,7 @@ class TestCore:
session.instantiate() session.instantiate()
# check link data gets generated # check link data gets generated
assert ptp_node.all_link_data(MessageFlags.ADD.value) assert ptp_node.all_link_data(MessageFlags.ADD)
# check common nets exist between linked nodes # check common nets exist between linked nodes
assert node_one.commonnets(node_two) assert node_one.commonnets(node_two)

View file

@ -7,16 +7,12 @@ from mock import patch
from core.api.grpc import core_pb2 from core.api.grpc import core_pb2
from core.api.grpc.client import CoreGrpcClient, InterfaceHelper from core.api.grpc.client import CoreGrpcClient, InterfaceHelper
from core.config import ConfigShim from core.api.tlv.dataconversion import ConfigShim
from core.api.tlv.enumerations import ConfigFlags
from core.emane.ieee80211abg import EmaneIeee80211abgModel from core.emane.ieee80211abg import EmaneIeee80211abgModel
from core.emulator.data import EventData from core.emulator.data import EventData
from core.emulator.emudata import NodeOptions from core.emulator.emudata import NodeOptions
from core.emulator.enumerations import ( from core.emulator.enumerations import EventTypes, ExceptionLevels, NodeTypes
ConfigFlags,
EventTypes,
ExceptionLevels,
NodeTypes,
)
from core.errors import CoreError from core.errors import CoreError
from core.location.mobility import BasicRangeModel, Ns2ScriptedMobility from core.location.mobility import BasicRangeModel, Ns2ScriptedMobility
from core.xml.corexml import CoreXmlWriter from core.xml.corexml import CoreXmlWriter
@ -127,7 +123,7 @@ class TestGrpc:
assert wlan_node.id in session.nodes assert wlan_node.id in session.nodes
assert session.nodes[node_one.id].netif(0) is not None assert session.nodes[node_one.id].netif(0) is not None
assert session.nodes[node_two.id].netif(0) is not None assert session.nodes[node_two.id].netif(0) is not None
hook_file, hook_data = session._hooks[core_pb2.SessionState.RUNTIME][0] hook_file, hook_data = session._hooks[EventTypes.RUNTIME_STATE][0]
assert hook_file == hook.file assert hook_file == hook.file
assert hook_data == hook.data assert hook_data == hook.data
assert session.location.refxyz == (location_x, location_y, location_z) assert session.location.refxyz == (location_x, location_y, location_z)
@ -169,7 +165,7 @@ class TestGrpc:
assert isinstance(response.state, int) assert isinstance(response.state, int)
session = grpc_server.coreemu.sessions.get(response.session_id) session = grpc_server.coreemu.sessions.get(response.session_id)
assert session is not None assert session is not None
assert session.state == response.state assert session.state == EventTypes(response.state)
if session_id is not None: if session_id is not None:
assert response.session_id == session_id assert response.session_id == session_id
assert session.id == session_id assert session.id == session_id
@ -341,7 +337,7 @@ class TestGrpc:
# then # then
assert response.result is True assert response.result is True
assert session.state == core_pb2.SessionState.DEFINITION assert session.state == EventTypes.DEFINITION_STATE
def test_add_node(self, grpc_server): def test_add_node(self, grpc_server):
# given # given
@ -447,7 +443,7 @@ class TestGrpc:
session = grpc_server.coreemu.create_session() session = grpc_server.coreemu.create_session()
file_name = "test" file_name = "test"
file_data = "echo hello" file_data = "echo hello"
session.add_hook(EventTypes.RUNTIME_STATE.value, file_name, None, file_data) session.add_hook(EventTypes.RUNTIME_STATE, file_name, None, file_data)
# then # then
with client.context_connect(): with client.context_connect():
@ -540,7 +536,7 @@ class TestGrpc:
session = grpc_server.coreemu.create_session() session = grpc_server.coreemu.create_session()
switch = session.add_node(_type=NodeTypes.SWITCH) switch = session.add_node(_type=NodeTypes.SWITCH)
node = session.add_node() node = session.add_node()
assert len(switch.all_link_data(0)) == 0 assert len(switch.all_link_data()) == 0
# then # then
interface = interface_helper.create_interface(node.id, 0) interface = interface_helper.create_interface(node.id, 0)
@ -549,7 +545,7 @@ class TestGrpc:
# then # then
assert response.result is True assert response.result is True
assert len(switch.all_link_data(0)) == 1 assert len(switch.all_link_data()) == 1
def test_add_link_exception(self, grpc_server, interface_helper): def test_add_link_exception(self, grpc_server, interface_helper):
# given # given
@ -572,7 +568,7 @@ class TestGrpc:
interface = ip_prefixes.create_interface(node) interface = ip_prefixes.create_interface(node)
session.add_link(node.id, switch.id, interface) session.add_link(node.id, switch.id, interface)
options = core_pb2.LinkOptions(bandwidth=30000) options = core_pb2.LinkOptions(bandwidth=30000)
link = switch.all_link_data(0)[0] link = switch.all_link_data()[0]
assert options.bandwidth != link.bandwidth assert options.bandwidth != link.bandwidth
# then # then
@ -583,7 +579,7 @@ class TestGrpc:
# then # then
assert response.result is True assert response.result is True
link = switch.all_link_data(0)[0] link = switch.all_link_data()[0]
assert options.bandwidth == link.bandwidth assert options.bandwidth == link.bandwidth
def test_delete_link(self, grpc_server, ip_prefixes): def test_delete_link(self, grpc_server, ip_prefixes):
@ -986,7 +982,7 @@ class TestGrpc:
client = CoreGrpcClient() client = CoreGrpcClient()
session = grpc_server.coreemu.create_session() session = grpc_server.coreemu.create_session()
node = session.add_node() node = session.add_node()
node_data = node.data(message_type=0) node_data = node.data()
queue = Queue() queue = Queue()
def handle_event(event_data): def handle_event(event_data):
@ -1011,7 +1007,7 @@ class TestGrpc:
node = session.add_node() node = session.add_node()
interface = ip_prefixes.create_interface(node) interface = ip_prefixes.create_interface(node)
session.add_link(node.id, wlan.id, interface) session.add_link(node.id, wlan.id, interface)
link_data = wlan.all_link_data(0)[0] link_data = wlan.all_link_data()[0]
queue = Queue() queue = Queue()
def handle_event(event_data): def handle_event(event_data):
@ -1065,7 +1061,7 @@ class TestGrpc:
client.events(session.id, handle_event) client.events(session.id, handle_event)
time.sleep(0.1) time.sleep(0.1)
event = EventData( event = EventData(
event_type=EventTypes.RUNTIME_STATE.value, time=str(time.monotonic()) event_type=EventTypes.RUNTIME_STATE, time=str(time.monotonic())
) )
session.broadcast_event(event) session.broadcast_event(event)

View file

@ -10,21 +10,18 @@ import pytest
from mock import MagicMock from mock import MagicMock
from core.api.tlv import coreapi from core.api.tlv import coreapi
from core.emane.ieee80211abg import EmaneIeee80211abgModel from core.api.tlv.enumerations import (
from core.emulator.enumerations import (
ConfigFlags, ConfigFlags,
ConfigTlvs, ConfigTlvs,
EventTlvs, EventTlvs,
EventTypes,
ExecuteTlvs, ExecuteTlvs,
FileTlvs, FileTlvs,
LinkTlvs, LinkTlvs,
MessageFlags,
NodeTlvs, NodeTlvs,
NodeTypes,
RegisterTlvs,
SessionTlvs, SessionTlvs,
) )
from core.emane.ieee80211abg import EmaneIeee80211abgModel
from core.emulator.enumerations import EventTypes, MessageFlags, NodeTypes, RegisterTlvs
from core.errors import CoreError from core.errors import CoreError
from core.location.mobility import BasicRangeModel from core.location.mobility import BasicRangeModel
@ -117,7 +114,7 @@ class TestGui:
coretlv.handle_message(message) coretlv.handle_message(message)
switch_node = coretlv.session.get_node(switch) switch_node = coretlv.session.get_node(switch)
all_links = switch_node.all_link_data(0) all_links = switch_node.all_link_data()
assert len(all_links) == 1 assert len(all_links) == 1
def test_link_add_net_to_node(self, coretlv): def test_link_add_net_to_node(self, coretlv):
@ -141,7 +138,7 @@ class TestGui:
coretlv.handle_message(message) coretlv.handle_message(message)
switch_node = coretlv.session.get_node(switch) switch_node = coretlv.session.get_node(switch)
all_links = switch_node.all_link_data(0) all_links = switch_node.all_link_data()
assert len(all_links) == 1 assert len(all_links) == 1
def test_link_add_node_to_node(self, coretlv): def test_link_add_node_to_node(self, coretlv):
@ -171,7 +168,7 @@ class TestGui:
all_links = [] all_links = []
for node_id in coretlv.session.nodes: for node_id in coretlv.session.nodes:
node = coretlv.session.nodes[node_id] node = coretlv.session.nodes[node_id]
all_links += node.all_link_data(0) all_links += node.all_link_data()
assert len(all_links) == 1 assert len(all_links) == 1
def test_link_update(self, coretlv): def test_link_update(self, coretlv):
@ -193,7 +190,7 @@ class TestGui:
) )
coretlv.handle_message(message) coretlv.handle_message(message)
switch_node = coretlv.session.get_node(switch) switch_node = coretlv.session.get_node(switch)
all_links = switch_node.all_link_data(0) all_links = switch_node.all_link_data()
assert len(all_links) == 1 assert len(all_links) == 1
link = all_links[0] link = all_links[0]
assert link.bandwidth is None assert link.bandwidth is None
@ -211,7 +208,7 @@ class TestGui:
coretlv.handle_message(message) coretlv.handle_message(message)
switch_node = coretlv.session.get_node(switch) switch_node = coretlv.session.get_node(switch)
all_links = switch_node.all_link_data(0) all_links = switch_node.all_link_data()
assert len(all_links) == 1 assert len(all_links) == 1
link = all_links[0] link = all_links[0]
assert link.bandwidth == bandwidth assert link.bandwidth == bandwidth
@ -240,7 +237,7 @@ class TestGui:
all_links = [] all_links = []
for node_id in coretlv.session.nodes: for node_id in coretlv.session.nodes:
node = coretlv.session.nodes[node_id] node = coretlv.session.nodes[node_id]
all_links += node.all_link_data(0) all_links += node.all_link_data()
assert len(all_links) == 1 assert len(all_links) == 1
message = coreapi.CoreLinkMessage.create( message = coreapi.CoreLinkMessage.create(
@ -257,7 +254,7 @@ class TestGui:
all_links = [] all_links = []
for node_id in coretlv.session.nodes: for node_id in coretlv.session.nodes:
node = coretlv.session.nodes[node_id] node = coretlv.session.nodes[node_id]
all_links += node.all_link_data(0) all_links += node.all_link_data()
assert len(all_links) == 0 assert len(all_links) == 0
def test_link_delete_node_to_net(self, coretlv): def test_link_delete_node_to_net(self, coretlv):
@ -279,7 +276,7 @@ class TestGui:
) )
coretlv.handle_message(message) coretlv.handle_message(message)
switch_node = coretlv.session.get_node(switch) switch_node = coretlv.session.get_node(switch)
all_links = switch_node.all_link_data(0) all_links = switch_node.all_link_data()
assert len(all_links) == 1 assert len(all_links) == 1
message = coreapi.CoreLinkMessage.create( message = coreapi.CoreLinkMessage.create(
@ -293,7 +290,7 @@ class TestGui:
coretlv.handle_message(message) coretlv.handle_message(message)
switch_node = coretlv.session.get_node(switch) switch_node = coretlv.session.get_node(switch)
all_links = switch_node.all_link_data(0) all_links = switch_node.all_link_data()
assert len(all_links) == 0 assert len(all_links) == 0
def test_link_delete_net_to_node(self, coretlv): def test_link_delete_net_to_node(self, coretlv):
@ -315,7 +312,7 @@ class TestGui:
) )
coretlv.handle_message(message) coretlv.handle_message(message)
switch_node = coretlv.session.get_node(switch) switch_node = coretlv.session.get_node(switch)
all_links = switch_node.all_link_data(0) all_links = switch_node.all_link_data()
assert len(all_links) == 1 assert len(all_links) == 1
message = coreapi.CoreLinkMessage.create( message = coreapi.CoreLinkMessage.create(
@ -329,7 +326,7 @@ class TestGui:
coretlv.handle_message(message) coretlv.handle_message(message)
switch_node = coretlv.session.get_node(switch) switch_node = coretlv.session.get_node(switch)
all_links = switch_node.all_link_data(0) all_links = switch_node.all_link_data()
assert len(all_links) == 0 assert len(all_links) == 0
def test_session_update(self, coretlv): def test_session_update(self, coretlv):
@ -376,14 +373,14 @@ class TestGui:
assert len(coretlv.coreemu.sessions) == 0 assert len(coretlv.coreemu.sessions) == 0
def test_file_hook_add(self, coretlv): def test_file_hook_add(self, coretlv):
state = EventTypes.DATACOLLECT_STATE.value state = EventTypes.DATACOLLECT_STATE
assert coretlv.session._hooks.get(state) is None assert coretlv.session._hooks.get(state) is None
file_name = "test.sh" file_name = "test.sh"
file_data = "echo hello" file_data = "echo hello"
message = coreapi.CoreFileMessage.create( message = coreapi.CoreFileMessage.create(
MessageFlags.ADD.value, MessageFlags.ADD.value,
[ [
(FileTlvs.TYPE, f"hook:{state}"), (FileTlvs.TYPE, f"hook:{state.value}"),
(FileTlvs.NAME, file_name), (FileTlvs.NAME, file_name),
(FileTlvs.DATA, file_data), (FileTlvs.DATA, file_data),
], ],
@ -514,7 +511,7 @@ class TestGui:
coretlv.handle_message(message) coretlv.handle_message(message)
assert coretlv.session.state == state.value assert coretlv.session.state == state
def test_event_schedule(self, coretlv): def test_event_schedule(self, coretlv):
coretlv.session.add_event = mock.MagicMock() coretlv.session.add_event = mock.MagicMock()

View file

@ -43,7 +43,7 @@ class TestLinks:
session.add_link(node_one.id, node_two.id, interface_one) session.add_link(node_one.id, node_two.id, interface_one)
# then # then
assert node_two.all_link_data(0) assert node_two.all_link_data()
assert node_one.netif(interface_one.id) assert node_one.netif(interface_one.id)
def test_net_to_node(self, session, ip_prefixes): def test_net_to_node(self, session, ip_prefixes):
@ -56,7 +56,7 @@ class TestLinks:
session.add_link(node_one.id, node_two.id, interface_two=interface_two) session.add_link(node_one.id, node_two.id, interface_two=interface_two)
# then # then
assert node_one.all_link_data(0) assert node_one.all_link_data()
assert node_two.netif(interface_two.id) assert node_two.netif(interface_two.id)
def test_net_to_net(self, session): def test_net_to_net(self, session):
@ -68,7 +68,7 @@ class TestLinks:
session.add_link(node_one.id, node_two.id) session.add_link(node_one.id, node_two.id)
# then # then
assert node_one.all_link_data(0) assert node_one.all_link_data()
def test_link_update(self, session, ip_prefixes): def test_link_update(self, session, ip_prefixes):
# given # given

View file

@ -3,7 +3,7 @@ from xml.etree import ElementTree
import pytest import pytest
from core.emulator.emudata import LinkOptions, NodeOptions from core.emulator.emudata import LinkOptions, NodeOptions
from core.emulator.enumerations import NodeTypes from core.emulator.enumerations import EventTypes, NodeTypes
from core.errors import CoreError from core.errors import CoreError
from core.location.mobility import BasicRangeModel from core.location.mobility import BasicRangeModel
from core.services.utility import SshService from core.services.utility import SshService
@ -20,7 +20,8 @@ class TestXml:
# create hook # create hook
file_name = "runtime_hook.sh" file_name = "runtime_hook.sh"
data = "#!/bin/sh\necho hello" data = "#!/bin/sh\necho hello"
session.set_hook("hook:4", file_name, None, data) state = EventTypes.RUNTIME_STATE
session.add_hook(state, file_name, None, data)
# save xml # save xml
xml_file = tmpdir.join("session.xml") xml_file = tmpdir.join("session.xml")
@ -38,7 +39,7 @@ class TestXml:
session.open_xml(file_path, start=True) session.open_xml(file_path, start=True)
# verify nodes have been recreated # verify nodes have been recreated
runtime_hooks = session._hooks.get(4) runtime_hooks = session._hooks.get(state)
assert runtime_hooks assert runtime_hooks
runtime_hook = runtime_hooks[0] runtime_hook = runtime_hooks[0]
assert file_name == runtime_hook[0] assert file_name == runtime_hook[0]
@ -269,7 +270,7 @@ class TestXml:
switch_two = session.get_node(n2_id) switch_two = session.get_node(n2_id)
assert switch_one assert switch_one
assert switch_two assert switch_two
assert len(switch_one.all_link_data(0) + switch_two.all_link_data(0)) == 1 assert len(switch_one.all_link_data() + switch_two.all_link_data()) == 1
def test_link_options(self, session, tmpdir, ip_prefixes): def test_link_options(self, session, tmpdir, ip_prefixes):
""" """
@ -329,7 +330,7 @@ class TestXml:
links = [] links = []
for node_id in session.nodes: for node_id in session.nodes:
node = session.nodes[node_id] node = session.nodes[node_id]
links += node.all_link_data(0) links += node.all_link_data()
link = links[0] link = links[0]
assert link_options.per == link.per assert link_options.per == link.per
assert link_options.bandwidth == link.bandwidth assert link_options.bandwidth == link.bandwidth
@ -396,7 +397,7 @@ class TestXml:
links = [] links = []
for node_id in session.nodes: for node_id in session.nodes:
node = session.nodes[node_id] node = session.nodes[node_id]
links += node.all_link_data(0) links += node.all_link_data()
link = links[0] link = links[0]
assert link_options.per == link.per assert link_options.per == link.per
assert link_options.bandwidth == link.bandwidth assert link_options.bandwidth == link.bandwidth
@ -478,7 +479,7 @@ class TestXml:
links = [] links = []
for node_id in session.nodes: for node_id in session.nodes:
node = session.nodes[node_id] node = session.nodes[node_id]
links += node.all_link_data(0) links += node.all_link_data()
assert len(links) == 2 assert len(links) == 2
link_one = links[0] link_one = links[0]
link_two = links[1] link_two = links[1]