daemon: updated emane position hooks and updating nem position logic to live in emane manager

This commit is contained in:
Blake Harnden 2021-05-26 12:22:36 -07:00
parent 795a5f5865
commit 777097c85e
3 changed files with 78 additions and 80 deletions

View file

@ -321,19 +321,22 @@ class EmaneManager:
with self._emane_node_lock: with self._emane_node_lock:
logger.info("emane building xmls...") logger.info("emane building xmls...")
for emane_net, iface in self.get_ifaces(): for emane_net, iface in self.get_ifaces():
nem_id = self.next_nem_id(iface) self.start_iface(emane_net, iface)
nem_port = self.get_nem_port(iface)
logger.info( def start_iface(self, emane_net: EmaneNet, iface: CoreInterface) -> None:
"starting emane for node(%s) iface(%s) nem(%s)", nem_id = self.next_nem_id(iface)
iface.node.name, nem_port = self.get_nem_port(iface)
iface.name, logger.info(
nem_id, "starting emane for node(%s) iface(%s) nem(%s)",
) iface.node.name,
config = self.get_iface_config(emane_net, iface) iface.name,
self.setup_control_channels(nem_id, iface, config) nem_id,
emanexml.build_platform_xml(nem_id, nem_port, emane_net, iface, config) )
self.start_daemon(iface) config = self.get_iface_config(emane_net, iface)
self.install_iface(emane_net, iface, config) self.setup_control_channels(nem_id, iface, config)
emanexml.build_platform_xml(nem_id, nem_port, emane_net, iface, config)
self.start_daemon(iface)
self.install_iface(iface, config)
def get_ifaces(self) -> List[Tuple[EmaneNet, CoreInterface]]: def get_ifaces(self) -> List[Tuple[EmaneNet, CoreInterface]]:
ifaces = [] ifaces = []
@ -414,6 +417,64 @@ class EmaneManager:
nem_id = self.get_nem_id(iface) nem_id = self.get_nem_id(iface)
return int(f"47{nem_id:03}") return int(f"47{nem_id:03}")
def get_nem_position(
self, iface: CoreInterface
) -> Optional[Tuple[int, float, float, int]]:
"""
Retrieves nem position for a given interface.
:param iface: interface to get nem emane position for
:return: nem position tuple, None otherwise
"""
nem_id = self.get_nem_id(iface)
if nem_id is None:
logger.info("nem for %s is unknown", iface.localname)
return
node = iface.node
x, y, z = node.getposition()
lat, lon, alt = self.session.location.getgeo(x, y, z)
if node.position.alt is not None:
alt = node.position.alt
node.position.set_geo(lon, lat, alt)
# altitude must be an integer or warning is printed
alt = int(round(alt))
return nem_id, lon, lat, alt
def set_nem_position(self, iface: CoreInterface) -> None:
"""
Publish a NEM location change event using the EMANE event service.
:param iface: interface to set nem position for
"""
position = self.get_nem_position(iface)
if position:
nemid, lon, lat, alt = position
event = LocationEvent()
event.append(nemid, latitude=lat, longitude=lon, altitude=alt)
self.publish_event(nemid, event, send_all=True)
def set_nem_positions(self, moved_ifaces: List[CoreInterface]) -> None:
"""
Several NEMs have moved, from e.g. a WaypointMobilityModel
calculation. Generate an EMANE Location Event having several
entries for each interface that has moved.
"""
if not moved_ifaces:
return
services = {}
for iface in moved_ifaces:
position = self.get_nem_position(iface)
if not position:
continue
nem_id, lon, lat, alt = position
service = self.nem_service.get(nem_id)
if not service:
continue
event = services.setdefault(service, LocationEvent())
event.append(nem_id, latitude=lat, longitude=lon, altitude=alt)
for service, event in services.items():
service.events.publish(0, event)
def write_nem(self, iface: CoreInterface, nem_id: int) -> None: def write_nem(self, iface: CoreInterface, nem_id: int) -> None:
path = self.session.directory / "emane_nems" path = self.session.directory / "emane_nems"
try: try:
@ -566,16 +627,14 @@ class EmaneManager:
args = f"{emanecmd} -f {log_file} {platform_xml}" args = f"{emanecmd} -f {log_file} {platform_xml}"
node.host_cmd(args, cwd=self.session.directory) node.host_cmd(args, cwd=self.session.directory)
def install_iface( def install_iface(self, iface: CoreInterface, config: Dict[str, str]) -> None:
self, emane_net: EmaneNet, iface: CoreInterface, config: Dict[str, str]
) -> None:
external = config.get("external", "0") external = config.get("external", "0")
if isinstance(iface, TunTap) and external == "0": if isinstance(iface, TunTap) and external == "0":
iface.set_ips() iface.set_ips()
# at this point we register location handlers for generating # at this point we register location handlers for generating
# EMANE location events # EMANE location events
if self.genlocationevents(): if self.genlocationevents():
iface.poshook = emane_net.setnemposition iface.poshook = self.set_nem_position
iface.setposition() iface.setposition()
def doeventmonitor(self) -> bool: def doeventmonitor(self) -> bool:

View file

@ -7,7 +7,6 @@ from typing import Dict, List, Optional, Set
from core.config import ConfigGroup, Configuration from core.config import ConfigGroup, Configuration
from core.emane import emanemanifest from core.emane import emanemanifest
from core.emane.nodes import EmaneNet
from core.emulator.data import LinkOptions from core.emulator.data import LinkOptions
from core.emulator.enumerations import ConfigDataTypes from core.emulator.enumerations import ConfigDataTypes
from core.errors import CoreError from core.errors import CoreError
@ -153,8 +152,7 @@ class EmaneModel(WirelessModel):
:return: nothing :return: nothing
""" """
try: try:
emane_net = self.session.get_node(self.id, EmaneNet) self.session.emane.set_nem_positions(moved_ifaces)
emane_net.setnempositions(moved_ifaces)
except CoreError: except CoreError:
logger.exception("error during update") logger.exception("error during update")

View file

@ -4,7 +4,7 @@ share the same MAC+PHY model.
""" """
import logging import logging
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Type from typing import TYPE_CHECKING, Dict, List, Optional, Type
from core.emulator.data import InterfaceData, LinkData, LinkOptions from core.emulator.data import InterfaceData, LinkData, LinkOptions
from core.emulator.distributed import DistributedServer from core.emulator.distributed import DistributedServer
@ -110,65 +110,6 @@ class EmaneNet(CoreNetworkBase):
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)
def _nem_position(
self, iface: CoreInterface
) -> Optional[Tuple[int, float, float, float]]:
"""
Creates nem position for emane event for a given interface.
:param iface: interface to get nem emane position for
:return: nem position tuple, None otherwise
"""
nem_id = self.session.emane.get_nem_id(iface)
ifname = iface.localname
if nem_id is None:
logger.info("nemid for %s is unknown", ifname)
return
node = iface.node
x, y, z = node.getposition()
lat, lon, alt = self.session.location.getgeo(x, y, z)
if node.position.alt is not None:
alt = node.position.alt
node.position.set_geo(lon, lat, alt)
# altitude must be an integer or warning is printed
alt = int(round(alt))
return nem_id, lon, lat, alt
def setnemposition(self, iface: CoreInterface) -> None:
"""
Publish a NEM location change event using the EMANE event service.
:param iface: interface to set nem position for
"""
position = self._nem_position(iface)
if position:
nemid, lon, lat, alt = position
event = LocationEvent()
event.append(nemid, latitude=lat, longitude=lon, altitude=alt)
self.session.emane.publish_event(nemid, event, send_all=True)
def setnempositions(self, moved_ifaces: List[CoreInterface]) -> None:
"""
Several NEMs have moved, from e.g. a WaypointMobilityModel
calculation. Generate an EMANE Location Event having several
entries for each interface that has moved.
"""
if not moved_ifaces:
return
services = {}
for iface in moved_ifaces:
position = self._nem_position(iface)
if not position:
continue
nem_id, lon, lat, alt = position
service = self.session.emane.nem_service.get(nem_id)
if not service:
continue
event = services.setdefault(service, LocationEvent())
event.append(nem_id, latitude=lat, longitude=lon, altitude=alt)
for service, event in services.items():
service.events.publish(0, event)
def links(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]: def links(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
links = super().links(flags) links = super().links(flags)
emane_manager = self.session.emane emane_manager = self.session.emane