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,
)
link = core_pb2.Link(
type=event.link_type,
type=event.link_type.value,
node_one_id=event.node1_id,
node_two_id=event.node2_id,
interface_one=interface_one,
interface_two=interface_two,
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:
@ -102,7 +102,7 @@ def handle_session_event(event: EventData) -> core_pb2.SessionEvent:
event_time = float(event_time)
return core_pb2.SessionEvent(
node_id=event.node,
event=event.event_type,
event=event.event_type.value,
name=event.name,
data=event.data,
time=event_time,
@ -158,7 +158,7 @@ def handle_file_event(event: FileData) -> core_pb2.FileEvent:
:return: file event
"""
return core_pb2.FileEvent(
message_type=event.message_type,
message_type=event.message_type.value,
node_id=event.node,
name=event.name,
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
"""
_id = node_proto.id
_type = node_proto.type
if _type is None:
_type = NodeTypes.DEFAULT.value
_type = NodeTypes(_type)
_type = NodeTypes(node_proto.type)
options = NodeOptions(name=node_proto.name, model=node_proto.model)
options.icon = node_proto.icon
options.opaque = node_proto.opaque
@ -233,7 +229,7 @@ def get_links(session: Session, node: NodeBase):
:return: [core.api.grpc.core_pb2.Link]
"""
links = []
for link_data in node.all_link_data(0):
for link_data in node.all_link_data():
link = convert_link(session, link_data)
links.append(link)
return links
@ -325,7 +321,7 @@ def convert_link(session: Session, link_data: LinkData) -> 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_two_id=link_data.node2_id,
interface_one=interface_one,

View file

@ -173,7 +173,8 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
# add all 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
_, 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.refscale = 150000.0
return core_pb2.CreateSessionResponse(
session_id=session.id, state=session.state
session_id=session.id, state=session.state.value
)
def DeleteSession(
@ -312,7 +313,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
session = self.coreemu.sessions[session_id]
session_summary = core_pb2.SessionSummary(
id=session_id,
state=session.state,
state=session.state.value,
nodes=session.get_node_count(),
file=session.file_name,
)
@ -521,7 +522,9 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
node_links = get_links(session, node)
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)
def AddSessionServer(
@ -718,7 +721,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
if request.source:
source = request.source
if not has_geo:
node_data = node.data(0, source=source)
node_data = node.data(source=source)
session.broadcast_node(node_data)
except CoreError:
result = False
@ -895,7 +898,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
for state in session._hooks:
state_hooks = session._hooks[state]
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)
return core_pb2.GetHooksResponse(hooks=hooks)
@ -912,7 +915,8 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
logging.debug("add hook: %s", request)
session = self.get_session(request.session_id, context)
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)
def GetMobilityConfigs(
@ -1266,7 +1270,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
session.mobility.set_model_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.updatemodel(wlan_config.config)
return core_pb2.SetWlanConfigResponse(result=True)
@ -1491,12 +1495,12 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
if emane_one.id == emane_two.id:
if request.linked:
flag = MessageFlags.ADD.value
flag = MessageFlags.ADD
else:
flag = MessageFlags.DELETE.value
flag = MessageFlags.DELETE
link = LinkData(
message_type=flag,
link_type=LinkTypes.WIRELESS.value,
link_type=LinkTypes.WIRELESS,
node1_id=node_one.id,
node2_id=node_two.id,
network_id=emane_one.id,

View file

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

View file

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

View file

@ -1,9 +1,14 @@
"""
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.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):
@ -17,7 +22,7 @@ def convert_node(node_data):
coreapi.CoreNodeTlv,
[
(NodeTlvs.NUMBER, node_data.id),
(NodeTlvs.TYPE, node_data.node_type),
(NodeTlvs.TYPE, node_data.node_type.value),
(NodeTlvs.NAME, node_data.name),
(NodeTlvs.IP_ADDRESS, node_data.ip_address),
(NodeTlvs.MAC_ADDRESS, node_data.mac_address),
@ -38,7 +43,7 @@ def convert_node(node_data):
(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):
@ -67,3 +72,102 @@ def convert_config(config_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 core.emane.nodes import EmaneNet
from core.emulator.data import ConfigData
from core.emulator.enumerations import ConfigDataTypes
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:
"""
Provides convenience methods for storing and retrieving configuration options for

View file

@ -60,7 +60,7 @@ class EmaneManager(ModelManager):
"""
name = "emane"
config_type = RegisterTlvs.EMULATION_SERVER.value
config_type = RegisterTlvs.EMULATION_SERVER
SUCCESS, NOT_NEEDED, NOT_READY = (0, 1, 2)
EVENTCFGVAR = "LIBEMANEEVENTSERVICECONFIG"
DEFAULT_LOG_LEVEL = 3
@ -806,7 +806,7 @@ class EmaneManager(ModelManager):
# don"t use node.setposition(x,y,z) which generates an event
node.position.set(x, y, z)
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)
return True

View file

@ -33,8 +33,8 @@ class EmaneNet(CoreNetworkBase):
Emane controller object that exists in a session.
"""
apitype = NodeTypes.EMANE.value
linktype = LinkTypes.WIRED.value
apitype = NodeTypes.EMANE
linktype = LinkTypes.WIRED
type = "wlan"
is_emane = True
@ -103,12 +103,12 @@ class EmaneNet(CoreNetworkBase):
set the EmaneModel associated with this node
"""
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
# when buildnemxml() is called, not during init()
self.model = model(session=self.session, _id=self.id)
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.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
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):
"""
CORE message flags.
"""
NONE = 0x00
ADD = 0x01
DELETE = 0x02
CRI = 0x04
@ -39,33 +20,6 @@ class MessageFlags(Enum):
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):
"""
Node types.
@ -86,56 +40,6 @@ class NodeTypes(Enum):
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):
"""
Link types.
@ -145,20 +49,6 @@ class LinkTypes(Enum):
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):
"""
Register type, length, value enumerations.
@ -173,37 +63,6 @@ class RegisterTlvs(Enum):
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):
"""
Configuration data types.
@ -222,55 +81,6 @@ class ConfigDataTypes(Enum):
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):
"""
Event types.
@ -293,34 +103,8 @@ class EventTypes(Enum):
RECONFIGURE = 14
INSTANTIATION_COMPLETE = 15
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
def should_start(self) -> bool:
return self.value > self.DEFINITION_STATE.value
class ExceptionLevels(Enum):

View file

@ -112,8 +112,7 @@ class Session:
self.nodes = {}
self._nodes_lock = threading.Lock()
# TODO: should the default state be definition?
self.state = EventTypes.NONE.value
self.state = EventTypes.DEFINITION_STATE
self._state_time = time.monotonic()
self._state_file = os.path.join(self.session_dir, "state")
@ -121,7 +120,7 @@ class Session:
self._hooks = {}
self._state_hooks = {}
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
@ -345,7 +344,7 @@ class Session:
node_one.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)
# node to network
@ -578,7 +577,7 @@ class Session:
try:
# wireless link
if link_options.type == LinkTypes.WIRELESS.value:
if link_options.type == LinkTypes.WIRELESS:
raise CoreError("cannot update wireless link")
else:
if not node_one and not node_two:
@ -680,7 +679,7 @@ class Session:
node_class = _cls
# 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"
if _type == NodeTypes.RJ45 and not enable_rj45:
start = False
@ -755,7 +754,7 @@ class Session:
# boot nodes after runtime, CoreNodes, Physical, and RJ45 are all nodes
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.add_remove_control_interface(node=node, remove=False)
self.services.boot_services(node)
@ -851,10 +850,7 @@ class Session:
:return: True if active, False otherwise
"""
result = self.state in {
EventTypes.RUNTIME_STATE.value,
EventTypes.DATACOLLECT_STATE.value,
}
result = self.state in {EventTypes.RUNTIME_STATE, EventTypes.DATACOLLECT_STATE}
logging.info("session(%s) checking if active: %s", self.id, result)
return result
@ -895,7 +891,9 @@ class Session:
"""
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.
@ -905,9 +903,17 @@ class Session:
:param data: hook data
:return: nothing
"""
# hack to conform with old logic until updated
state = f":{state}"
self.set_hook(state, file_name, source_name, data)
logging.info(
"setting state hook: %s - %s from %s", state, file_name, source_name
)
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(
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
:return: nothing
"""
state_value = state.value
state_name = state.name
if self.state == state_value:
if self.state == state:
logging.info(
"session(%s) is already in state: %s, skipping change",
self.id,
@ -1083,33 +1087,32 @@ class Session:
)
return
self.state = state_value
self.state = state
self._state_time = time.monotonic()
logging.info("changing session(%s) to state %s", self.id, state_name)
self.write_state(state_value)
self.run_hooks(state_value)
self.run_state_hooks(state_value)
self.write_state(state)
self.run_hooks(state)
self.run_state_hooks(state)
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)
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
:return: nothing
"""
try:
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()
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
in the given state.
@ -1213,7 +1216,7 @@ class Session:
except (OSError, subprocess.CalledProcessError):
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.
@ -1224,16 +1227,17 @@ class Session:
try:
hook(state)
except Exception:
state_name = EventTypes(self.state).name
message = (
f"exception occured when running {state_name} state hook: {hook}"
f"exception occured when running {state.name} state hook: {hook}"
)
logging.exception(message)
self.exception(
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.
@ -1260,14 +1264,14 @@ class Session:
hooks = self._state_hooks.setdefault(state, [])
hooks.remove(hook)
def runtime_state_hook(self, state: int) -> None:
def runtime_state_hook(self, state: EventTypes) -> None:
"""
Runtime state hook check.
:param state: state to check
:return: nothing
"""
if state == EventTypes.RUNTIME_STATE.value:
if state == EventTypes.RUNTIME_STATE:
self.emane.poststartup()
# create session deployed xml
@ -1511,7 +1515,7 @@ class Session:
self.mobility.startup()
# 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)
# assume either all nodes have booted already, or there are some
@ -1554,9 +1558,9 @@ class Session:
logging.debug(
"session(%s) checking if not in runtime state, current state: %s",
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")
return
@ -1893,7 +1897,7 @@ class Session:
Return the current time we have been in the runtime state, or zero
if not in runtime.
"""
if self.state == EventTypes.RUNTIME_STATE.value:
if self.state == EventTypes.RUNTIME_STATE:
return time.monotonic() - self._state_time
else:
return 0.0

View file

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

View file

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

View file

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

View file

@ -14,7 +14,7 @@ from core import utils
from core.configservice.dependencies import ConfigServiceDependencies
from core.constants import MOUNT_BIN, VNODED_BIN
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.nodes import client
from core.nodes.interface import CoreInterface, TunTap, Veth
@ -193,7 +193,7 @@ class NodeBase:
def data(
self,
message_type: int,
message_type: MessageFlags = MessageFlags.NONE,
lat: float = None,
lon: float = None,
alt: float = None,
@ -244,7 +244,7 @@ class NodeBase:
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
method for PyCoreObjs as PyCoreNodes do not implement this but
@ -472,7 +472,7 @@ class CoreNode(CoreNodeBase):
Provides standard core node logic.
"""
apitype = NodeTypes.DEFAULT.value
apitype = NodeTypes.DEFAULT
valid_address_types = {"inet", "inet6", "inet6link"}
def __init__(
@ -982,7 +982,7 @@ class CoreNetworkBase(NodeBase):
Base class for networks
"""
linktype = LinkTypes.WIRED.value
linktype = LinkTypes.WIRED
is_emane = False
def __init__(
@ -1069,7 +1069,7 @@ class CoreNetworkBase(NodeBase):
with self._linked_lock:
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
between this network and a node.

View file

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

View file

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

View file

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

View file

@ -12,7 +12,7 @@ import netaddr
from core import utils
from core.constants import EBTABLES_BIN, TC_BIN
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.nodes.base import CoreNetworkBase
from core.nodes.interface import CoreInterface, GreTap, Veth
@ -848,7 +848,7 @@ class CtrlNet(CoreNetwork):
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.
@ -899,7 +899,7 @@ class PtpNet(CoreNetwork):
"""
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
describes this network.
@ -999,7 +999,7 @@ class SwitchNode(CoreNetwork):
Provides switch functionality within a core node.
"""
apitype = NodeTypes.SWITCH.value
apitype = NodeTypes.SWITCH
policy = "ACCEPT"
type = "lanswitch"
@ -1010,7 +1010,7 @@ class HubNode(CoreNetwork):
ports by turning off MAC address learning.
"""
apitype = NodeTypes.HUB.value
apitype = NodeTypes.HUB
policy = "ACCEPT"
type = "hub"
@ -1029,8 +1029,8 @@ class WlanNode(CoreNetwork):
Provides wireless lan functionality within a core node.
"""
apitype = NodeTypes.WIRELESS_LAN.value
linktype = LinkTypes.WIRED.value
apitype = NodeTypes.WIRELESS_LAN
linktype = LinkTypes.WIRED
policy = "DROP"
type = "wlan"
@ -1090,13 +1090,13 @@ class WlanNode(CoreNetwork):
:return: nothing
"""
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)
for netif in self.netifs():
netif.poshook = self.model.position_callback
netif.setposition()
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.update_config(config)
@ -1115,7 +1115,7 @@ class WlanNode(CoreNetwork):
for netif in self.netifs():
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.
@ -1133,6 +1133,6 @@ class TunnelNode(GreTapBridge):
Provides tunnel functionality in a core node.
"""
apitype = NodeTypes.TUNNEL.value
apitype = NodeTypes.TUNNEL
policy = "ACCEPT"
type = "tunnel"

View file

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

View file

@ -24,7 +24,7 @@ if TYPE_CHECKING:
def link_data_params(link_data: LinkData) -> Tuple[int, int, bool]:
node_one = link_data.node1_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
@ -90,7 +90,7 @@ class Sdt:
self.address = (self.url.hostname, self.url.port)
self.protocol = self.url.scheme
def connect(self, flags: int = 0) -> bool:
def connect(self) -> bool:
"""
Connect to the SDT address/port if enabled.
@ -100,7 +100,7 @@ class Sdt:
return False
if self.connected:
return True
if self.session.state == EventTypes.SHUTDOWN_STATE.value:
if self.session.state == EventTypes.SHUTDOWN_STATE:
return False
self.seturl()
@ -122,7 +122,7 @@ class Sdt:
self.connected = True
# 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 True
@ -210,7 +210,7 @@ class Sdt:
self.add_node(node)
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:
is_wireless = isinstance(net, (WlanNode, EmaneNet))
if is_wireless and link_data.node1_id == net.id:
@ -302,7 +302,7 @@ class Sdt:
return
# 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}")
else:
x = node_data.x_position
@ -375,9 +375,9 @@ class Sdt:
:param link_data: link data to handle
:return: nothing
"""
if link_data.message_type == MessageFlags.ADD.value:
if link_data.message_type == MessageFlags.ADD:
params = link_data_params(link_data)
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)
self.delete_link(*params[:2])

View file

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

View file

@ -551,7 +551,7 @@ class Babel(QuaggaService):
@classmethod
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"
else:
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.emulator.data import LinkData
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.docker import DockerNode
from core.nodes.lxd import LxcNode
@ -260,7 +260,7 @@ class NetworkElement(NodeElement):
def add_type(self) -> None:
if self.node.apitype:
node_type = NodeTypes(self.node.apitype).name
node_type = self.node.apitype.name
else:
node_type = self.node.__class__.__name__
add_attribute(self.element, "type", node_type)
@ -324,7 +324,7 @@ class CoreXmlWriter:
for file_name, data in self.session._hooks[state]:
hook = etree.SubElement(hooks, "hook")
add_attribute(hook, "name", file_name)
add_attribute(hook, "state", state)
add_attribute(hook, "state", state.value)
hook.text = data
if hooks.getchildren():
@ -476,7 +476,7 @@ class CoreXmlWriter:
self.write_device(node)
# add known links
links.extend(node.all_link_data(0))
links.extend(node.all_link_data())
return links
@ -666,13 +666,11 @@ class CoreXmlReader:
for hook in session_hooks.iterchildren():
name = hook.get("name")
state = hook.get("state")
state = get_int(hook, "state")
state = EventTypes(state)
data = hook.text
hook_type = f"hook:{state}"
logging.info("reading hook: state(%s) name(%s)", state, name)
self.session.set_hook(
hook_type, file_name=name, source_name=None, data=data
)
self.session.add_hook(state, name, None, data)
def read_session_origin(self) -> None:
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.tlv.corehandlers import CoreHandler, CoreUdpHandler
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.emulator.enumerations import CORE_API_PORT
from core.utils import close_onexec, load_logging_config

View file

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

View file

@ -114,7 +114,7 @@ class TestCore:
session.instantiate()
# 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
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.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.emulator.data import EventData
from core.emulator.emudata import NodeOptions
from core.emulator.enumerations import (
ConfigFlags,
EventTypes,
ExceptionLevels,
NodeTypes,
)
from core.emulator.enumerations import EventTypes, ExceptionLevels, NodeTypes
from core.errors import CoreError
from core.location.mobility import BasicRangeModel, Ns2ScriptedMobility
from core.xml.corexml import CoreXmlWriter
@ -127,7 +123,7 @@ class TestGrpc:
assert wlan_node.id in session.nodes
assert session.nodes[node_one.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_data == hook.data
assert session.location.refxyz == (location_x, location_y, location_z)
@ -169,7 +165,7 @@ class TestGrpc:
assert isinstance(response.state, int)
session = grpc_server.coreemu.sessions.get(response.session_id)
assert session is not None
assert session.state == response.state
assert session.state == EventTypes(response.state)
if session_id is not None:
assert response.session_id == session_id
assert session.id == session_id
@ -341,7 +337,7 @@ class TestGrpc:
# then
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):
# given
@ -447,7 +443,7 @@ class TestGrpc:
session = grpc_server.coreemu.create_session()
file_name = "test"
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
with client.context_connect():
@ -540,7 +536,7 @@ class TestGrpc:
session = grpc_server.coreemu.create_session()
switch = session.add_node(_type=NodeTypes.SWITCH)
node = session.add_node()
assert len(switch.all_link_data(0)) == 0
assert len(switch.all_link_data()) == 0
# then
interface = interface_helper.create_interface(node.id, 0)
@ -549,7 +545,7 @@ class TestGrpc:
# then
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):
# given
@ -572,7 +568,7 @@ class TestGrpc:
interface = ip_prefixes.create_interface(node)
session.add_link(node.id, switch.id, interface)
options = core_pb2.LinkOptions(bandwidth=30000)
link = switch.all_link_data(0)[0]
link = switch.all_link_data()[0]
assert options.bandwidth != link.bandwidth
# then
@ -583,7 +579,7 @@ class TestGrpc:
# then
assert response.result is True
link = switch.all_link_data(0)[0]
link = switch.all_link_data()[0]
assert options.bandwidth == link.bandwidth
def test_delete_link(self, grpc_server, ip_prefixes):
@ -986,7 +982,7 @@ class TestGrpc:
client = CoreGrpcClient()
session = grpc_server.coreemu.create_session()
node = session.add_node()
node_data = node.data(message_type=0)
node_data = node.data()
queue = Queue()
def handle_event(event_data):
@ -1011,7 +1007,7 @@ class TestGrpc:
node = session.add_node()
interface = ip_prefixes.create_interface(node)
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()
def handle_event(event_data):
@ -1065,7 +1061,7 @@ class TestGrpc:
client.events(session.id, handle_event)
time.sleep(0.1)
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)

View file

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

View file

@ -3,7 +3,7 @@ from xml.etree import ElementTree
import pytest
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.location.mobility import BasicRangeModel
from core.services.utility import SshService
@ -20,7 +20,8 @@ class TestXml:
# create hook
file_name = "runtime_hook.sh"
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
xml_file = tmpdir.join("session.xml")
@ -38,7 +39,7 @@ class TestXml:
session.open_xml(file_path, start=True)
# verify nodes have been recreated
runtime_hooks = session._hooks.get(4)
runtime_hooks = session._hooks.get(state)
assert runtime_hooks
runtime_hook = runtime_hooks[0]
assert file_name == runtime_hook[0]
@ -269,7 +270,7 @@ class TestXml:
switch_two = session.get_node(n2_id)
assert switch_one
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):
"""
@ -329,7 +330,7 @@ class TestXml:
links = []
for node_id in session.nodes:
node = session.nodes[node_id]
links += node.all_link_data(0)
links += node.all_link_data()
link = links[0]
assert link_options.per == link.per
assert link_options.bandwidth == link.bandwidth
@ -396,7 +397,7 @@ class TestXml:
links = []
for node_id in session.nodes:
node = session.nodes[node_id]
links += node.all_link_data(0)
links += node.all_link_data()
link = links[0]
assert link_options.per == link.per
assert link_options.bandwidth == link.bandwidth
@ -478,7 +479,7 @@ class TestXml:
links = []
for node_id in session.nodes:
node = session.nodes[node_id]
links += node.all_link_data(0)
links += node.all_link_data()
assert len(links) == 2
link_one = links[0]
link_two = links[1]