daemon: abstracted out iface specific configuration generation and parsing to common utilities, to avoid duplicate logic and potential differences that may arise
This commit is contained in:
parent
e775ad4c5d
commit
a80fda11f5
7 changed files with 54 additions and 63 deletions
|
@ -306,35 +306,6 @@ def get_links(node: NodeBase):
|
|||
return links
|
||||
|
||||
|
||||
def get_emane_model_id(node_id: int, iface_id: int) -> int:
|
||||
"""
|
||||
Get EMANE model id
|
||||
|
||||
:param node_id: node id
|
||||
:param iface_id: interface id
|
||||
:return: EMANE model id
|
||||
"""
|
||||
if iface_id >= 0:
|
||||
return node_id * 1000 + iface_id
|
||||
else:
|
||||
return node_id
|
||||
|
||||
|
||||
def parse_emane_model_id(_id: int) -> Tuple[int, int]:
|
||||
"""
|
||||
Parses EMANE model id to get true node id and interface id.
|
||||
|
||||
:param _id: id to parse
|
||||
:return: node id and interface id
|
||||
"""
|
||||
iface_id = -1
|
||||
node_id = _id
|
||||
if _id >= 1000:
|
||||
iface_id = _id % 1000
|
||||
node_id = int(_id / 1000)
|
||||
return node_id, iface_id
|
||||
|
||||
|
||||
def convert_iface(iface_data: InterfaceData) -> core_pb2.Interface:
|
||||
return core_pb2.Interface(
|
||||
id=iface_data.id,
|
||||
|
@ -559,7 +530,8 @@ def get_emane_model_configs(session: Session) -> List[GetEmaneModelConfig]:
|
|||
model = session.emane.models[model_name]
|
||||
current_config = session.emane.get_model_config(_id, model_name)
|
||||
config = get_config_options(current_config, model)
|
||||
node_id, iface_id = parse_emane_model_id(_id)
|
||||
node_id, iface_id = utils.parse_iface_config_id(_id)
|
||||
iface_id = iface_id if iface_id is not None else -1
|
||||
model_config = GetEmaneModelConfig(
|
||||
node_id=node_id, model=model_name, iface_id=iface_id, config=config
|
||||
)
|
||||
|
|
|
@ -56,12 +56,7 @@ from core.api.grpc.emane_pb2 import (
|
|||
SetEmaneModelConfigResponse,
|
||||
)
|
||||
from core.api.grpc.events import EventStreamer
|
||||
from core.api.grpc.grpcutils import (
|
||||
get_config_options,
|
||||
get_emane_model_id,
|
||||
get_links,
|
||||
get_net_stats,
|
||||
)
|
||||
from core.api.grpc.grpcutils import get_config_options, get_links, get_net_stats
|
||||
from core.api.grpc.mobility_pb2 import (
|
||||
GetMobilityConfigRequest,
|
||||
GetMobilityConfigResponse,
|
||||
|
@ -249,7 +244,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
config = session.emane.get_configs()
|
||||
config.update(request.emane_config)
|
||||
for config in request.emane_model_configs:
|
||||
_id = get_emane_model_id(config.node_id, config.iface_id)
|
||||
_id = utils.iface_config_id(config.node_id, config.iface_id)
|
||||
session.emane.set_model_config(_id, config.model, config.config)
|
||||
|
||||
# wlan configs
|
||||
|
@ -1441,7 +1436,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
model = session.emane.models.get(request.model)
|
||||
if not model:
|
||||
raise CoreError(f"invalid emane model: {request.model}")
|
||||
_id = get_emane_model_id(request.node_id, request.iface_id)
|
||||
_id = utils.iface_config_id(request.node_id, request.iface_id)
|
||||
current_config = session.emane.get_model_config(_id, request.model)
|
||||
config = get_config_options(current_config, model)
|
||||
return GetEmaneModelConfigResponse(config=config)
|
||||
|
@ -1460,7 +1455,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
logging.debug("set emane model config: %s", request)
|
||||
session = self.get_session(request.session_id, context)
|
||||
model_config = request.emane_model_config
|
||||
_id = get_emane_model_id(model_config.node_id, model_config.iface_id)
|
||||
_id = utils.iface_config_id(model_config.node_id, model_config.iface_id)
|
||||
session.emane.set_model_config(_id, model_config.model, model_config.config)
|
||||
return SetEmaneModelConfigResponse(result=True)
|
||||
|
||||
|
|
|
@ -1331,9 +1331,7 @@ class CoreHandler(socketserver.BaseRequestHandler):
|
|||
iface_id = config_data.iface_id
|
||||
values_str = config_data.data_values
|
||||
|
||||
if iface_id is not None:
|
||||
node_id = node_id * 1000 + iface_id
|
||||
|
||||
node_id = utils.iface_config_id(node_id, iface_id)
|
||||
logging.debug(
|
||||
"received configure message for %s nodenum: %s", object_name, node_id
|
||||
)
|
||||
|
@ -1381,9 +1379,7 @@ class CoreHandler(socketserver.BaseRequestHandler):
|
|||
iface_id = config_data.iface_id
|
||||
values_str = config_data.data_values
|
||||
|
||||
if iface_id is not None:
|
||||
node_id = node_id * 1000 + iface_id
|
||||
|
||||
node_id = utils.iface_config_id(node_id, iface_id)
|
||||
logging.debug(
|
||||
"received configure message for %s nodenum: %s", object_name, node_id
|
||||
)
|
||||
|
@ -1413,9 +1409,7 @@ class CoreHandler(socketserver.BaseRequestHandler):
|
|||
iface_id = config_data.iface_id
|
||||
values_str = config_data.data_values
|
||||
|
||||
if iface_id is not None:
|
||||
node_id = node_id * 1000 + iface_id
|
||||
|
||||
node_id = utils.iface_config_id(node_id, iface_id)
|
||||
logging.debug(
|
||||
"received configure message for %s nodenum: %s", object_name, node_id
|
||||
)
|
||||
|
|
|
@ -140,12 +140,12 @@ class EmaneManager(ModelManager):
|
|||
# Adamson change: first check for iface config keyed by "node:iface.name"
|
||||
# (so that nodes w/ multiple interfaces of same conftype can have
|
||||
# different configs for each separate interface)
|
||||
key = 1000 * iface.node.id
|
||||
config = None
|
||||
# try to retrieve interface specific configuration
|
||||
if iface.node_id is not None:
|
||||
key += iface.node_id
|
||||
# try retrieve interface specific configuration, avoid getting defaults
|
||||
config = self.get_configs(node_id=key, config_type=model_name)
|
||||
# attempt to retrieve node specific conifg, when iface config is not present
|
||||
key = utils.iface_config_id(iface.node.id, iface.node_id)
|
||||
config = self.get_configs(node_id=key, config_type=model_name)
|
||||
# attempt to retrieve node specific config, when iface config is not present
|
||||
if not config:
|
||||
config = self.get_configs(node_id=iface.node.id, config_type=model_name)
|
||||
# attempt to get emane net specific config, when node config is not present
|
||||
|
|
|
@ -41,6 +41,7 @@ if TYPE_CHECKING:
|
|||
T = TypeVar("T")
|
||||
|
||||
DEVNULL = open(os.devnull, "wb")
|
||||
IFACE_CONFIG_FACTOR: int = 1000
|
||||
|
||||
|
||||
def execute_file(
|
||||
|
@ -430,3 +431,34 @@ def random_mac() -> str:
|
|||
value |= 0x00163E << 24
|
||||
mac = netaddr.EUI(value, dialect=netaddr.mac_unix_expanded)
|
||||
return str(mac)
|
||||
|
||||
|
||||
def iface_config_id(node_id: int, iface_id: int = None) -> int:
|
||||
"""
|
||||
Common utility to generate a configuration id, in case an interface is being
|
||||
targeted.
|
||||
|
||||
:param node_id: node for config id
|
||||
:param iface_id: interface for config id
|
||||
:return: generated config id when interface is present, node id otherwise
|
||||
"""
|
||||
if iface_id is not None and iface_id >= 0:
|
||||
return node_id * IFACE_CONFIG_FACTOR + iface_id
|
||||
else:
|
||||
return node_id
|
||||
|
||||
|
||||
def parse_iface_config_id(config_id: int) -> Tuple[int, Optional[int]]:
|
||||
"""
|
||||
Parses configuration id, that may be potentially derived from an interface for a
|
||||
node.
|
||||
|
||||
:param config_id: configuration id to parse
|
||||
:return:
|
||||
"""
|
||||
iface_id = None
|
||||
node_id = config_id
|
||||
if config_id >= IFACE_CONFIG_FACTOR:
|
||||
iface_id = config_id % IFACE_CONFIG_FACTOR
|
||||
node_id = config_id // IFACE_CONFIG_FACTOR
|
||||
return node_id, iface_id
|
||||
|
|
|
@ -5,6 +5,7 @@ from lxml import etree
|
|||
|
||||
import core.nodes.base
|
||||
import core.nodes.physical
|
||||
from core import utils
|
||||
from core.emane.nodes import EmaneNet
|
||||
from core.emulator.data import InterfaceData, LinkData, LinkOptions, NodeOptions
|
||||
from core.emulator.enumerations import EventTypes, NodeTypes
|
||||
|
@ -382,10 +383,7 @@ class CoreXmlWriter:
|
|||
all_configs = self.session.emane.get_all_configs(node_id)
|
||||
if not all_configs:
|
||||
continue
|
||||
iface_id = None
|
||||
if node_id >= 1000:
|
||||
iface_id = node_id % 1000
|
||||
node_id = node_id // 1000
|
||||
node_id, iface_id = utils.parse_iface_config_id(node_id)
|
||||
for model_name in all_configs:
|
||||
config = all_configs[model_name]
|
||||
logging.debug(
|
||||
|
@ -796,10 +794,8 @@ class CoreXmlReader:
|
|||
logging.info(
|
||||
"reading emane configuration node(%s) model(%s)", node_id, model_name
|
||||
)
|
||||
key = node_id
|
||||
if iface_id is not None:
|
||||
key = node_id * 1000 + iface_id
|
||||
self.session.emane.set_model_config(key, model_name, configs)
|
||||
node_id = utils.iface_config_id(node_id, iface_id)
|
||||
self.session.emane.set_model_config(node_id, model_name, configs)
|
||||
|
||||
def read_mobility_configs(self) -> None:
|
||||
mobility_configurations = self.scenario.find("mobility_configurations")
|
||||
|
|
|
@ -8,6 +8,7 @@ from xml.etree import ElementTree
|
|||
|
||||
import pytest
|
||||
|
||||
from core import utils
|
||||
from core.emane.bypass import EmaneBypassModel
|
||||
from core.emane.commeffect import EmaneCommEffectModel
|
||||
from core.emane.emanemodel import EmaneModel
|
||||
|
@ -244,8 +245,9 @@ class TestEmane:
|
|||
|
||||
# set node specific conifg
|
||||
datarate = "101"
|
||||
config_id = utils.iface_config_id(node1.id, iface1_data.id)
|
||||
session.emane.set_model_config(
|
||||
node1.id * 1000, EmaneRfPipeModel.name, {"datarate": datarate}
|
||||
config_id, EmaneRfPipeModel.name, {"datarate": datarate}
|
||||
)
|
||||
|
||||
# instantiate session
|
||||
|
@ -283,5 +285,5 @@ class TestEmane:
|
|||
node = session.nodes[node_id]
|
||||
links += node.links()
|
||||
assert len(links) == 2
|
||||
config = session.emane.get_model_config(node1.id * 1000, EmaneRfPipeModel.name)
|
||||
config = session.emane.get_model_config(config_id, EmaneRfPipeModel.name)
|
||||
assert config["datarate"] == datarate
|
||||
|
|
Loading…
Reference in a new issue