Merge pull request #409 from coreemu/enhancement/enum-cleanup
Enhancement/enum cleanup
This commit is contained in:
commit
fd7db64f6d
32 changed files with 543 additions and 559 deletions
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
)
|
||||||
|
|
212
daemon/core/api/tlv/enumerations.py
Normal file
212
daemon/core/api/tlv/enumerations.py
Normal 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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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__()
|
||||||
|
|
|
@ -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:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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__(
|
||||||
|
|
|
@ -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])
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]
|
||||||
|
|
Loading…
Add table
Reference in a new issue