daemon: removed nem map from individual emane networks, all nems are stored and generated from the emane manager
This commit is contained in:
parent
fcda1f9f14
commit
5cc4d92760
9 changed files with 64 additions and 89 deletions
|
@ -491,10 +491,13 @@ def iface_to_proto(node_id: int, iface: CoreInterface) -> core_pb2.Interface:
|
|||
)
|
||||
|
||||
|
||||
def get_nem_id(node: CoreNode, iface_id: int, context: ServicerContext) -> int:
|
||||
def get_nem_id(
|
||||
session: Session, node: CoreNode, iface_id: int, context: ServicerContext
|
||||
) -> int:
|
||||
"""
|
||||
Get nem id for a given node and interface id.
|
||||
|
||||
:param session: session node belongs to
|
||||
:param node: node to get nem id for
|
||||
:param iface_id: id of interface on node to get nem id for
|
||||
:param context: request context
|
||||
|
@ -508,7 +511,7 @@ def get_nem_id(node: CoreNode, iface_id: int, context: ServicerContext) -> int:
|
|||
if not isinstance(net, EmaneNet):
|
||||
message = f"{node.name} interface {iface_id} is not an EMANE network"
|
||||
context.abort(grpc.StatusCode.INVALID_ARGUMENT, message)
|
||||
nem_id = net.getnemid(iface)
|
||||
nem_id = session.emane.get_nem_id(iface)
|
||||
if nem_id is None:
|
||||
message = f"{node.name} interface {iface_id} nem id does not exist"
|
||||
context.abort(grpc.StatusCode.INVALID_ARGUMENT, message)
|
||||
|
|
|
@ -1551,29 +1551,29 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
logging.debug("emane link: %s", request)
|
||||
session = self.get_session(request.session_id, context)
|
||||
nem1 = request.nem1
|
||||
emane1, iface = session.emane.nemlookup(nem1)
|
||||
if not emane1 or not iface:
|
||||
iface1 = session.emane.get_iface(nem1)
|
||||
if not iface1:
|
||||
context.abort(grpc.StatusCode.NOT_FOUND, f"nem one {nem1} not found")
|
||||
node1 = iface.node
|
||||
node1 = iface1.node
|
||||
|
||||
nem2 = request.nem2
|
||||
emane2, iface = session.emane.nemlookup(nem2)
|
||||
if not emane2 or not iface:
|
||||
iface2 = session.emane.get_iface(nem2)
|
||||
if not iface2:
|
||||
context.abort(grpc.StatusCode.NOT_FOUND, f"nem two {nem2} not found")
|
||||
node2 = iface.node
|
||||
node2 = iface2.node
|
||||
|
||||
if emane1.id == emane2.id:
|
||||
if iface1.net == iface2.net:
|
||||
if request.linked:
|
||||
flag = MessageFlags.ADD
|
||||
else:
|
||||
flag = MessageFlags.DELETE
|
||||
color = session.get_link_color(emane1.id)
|
||||
color = session.get_link_color(iface1.net.id)
|
||||
link = LinkData(
|
||||
message_type=flag,
|
||||
type=LinkTypes.WIRELESS,
|
||||
node1_id=node1.id,
|
||||
node2_id=node2.id,
|
||||
network_id=emane1.id,
|
||||
network_id=iface1.net.id,
|
||||
color=color,
|
||||
)
|
||||
session.broadcast_link(link)
|
||||
|
@ -1796,8 +1796,8 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
for request in request_iterator:
|
||||
session = self.get_session(request.session_id, context)
|
||||
node1 = self.get_node(session, request.node1_id, context, CoreNode)
|
||||
nem1 = grpcutils.get_nem_id(node1, request.iface1_id, context)
|
||||
nem1 = grpcutils.get_nem_id(session, node1, request.iface1_id, context)
|
||||
node2 = self.get_node(session, request.node2_id, context, CoreNode)
|
||||
nem2 = grpcutils.get_nem_id(node2, request.iface2_id, context)
|
||||
nem2 = grpcutils.get_nem_id(session, node2, request.iface2_id, context)
|
||||
session.emane.publish_pathloss(nem1, nem2, request.rx1, request.rx2)
|
||||
return EmanePathlossesResponse()
|
||||
|
|
|
@ -10,7 +10,6 @@ from lxml import etree
|
|||
|
||||
from core.config import ConfigGroup, Configuration
|
||||
from core.emane import emanemanifest, emanemodel
|
||||
from core.emane.nodes import EmaneNet
|
||||
from core.emulator.data import LinkOptions
|
||||
from core.nodes.interface import CoreInterface
|
||||
from core.xml import emanexml
|
||||
|
@ -124,12 +123,11 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
|
|||
# TODO: batch these into multiple events per transmission
|
||||
# TODO: may want to split out seconds portion of delay and jitter
|
||||
event = CommEffectEvent()
|
||||
emane_node = self.session.get_node(self.id, EmaneNet)
|
||||
nemid = emane_node.getnemid(iface)
|
||||
nemid2 = emane_node.getnemid(iface2)
|
||||
nem1 = self.session.emane.get_nem_id(iface)
|
||||
nem2 = self.session.emane.get_nem_id(iface2)
|
||||
logging.info("sending comm effect event")
|
||||
event.append(
|
||||
nemid,
|
||||
nem1,
|
||||
latency=convert_none(options.delay),
|
||||
jitter=convert_none(options.jitter),
|
||||
loss=convert_none(options.loss),
|
||||
|
@ -137,4 +135,4 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
|
|||
unicast=int(convert_none(options.bandwidth)),
|
||||
broadcast=int(convert_none(options.bandwidth)),
|
||||
)
|
||||
service.publish(nemid2, event)
|
||||
service.publish(nem2, event)
|
||||
|
|
|
@ -90,7 +90,8 @@ class EmaneManager(ModelManager):
|
|||
"""
|
||||
super().__init__()
|
||||
self.session: "Session" = session
|
||||
self.nems: Dict[int, CoreInterface] = {}
|
||||
self.nems_to_ifaces: Dict[int, CoreInterface] = {}
|
||||
self.ifaces_to_nems: Dict[CoreInterface, int] = {}
|
||||
self._emane_nets: Dict[int, EmaneNet] = {}
|
||||
self._emane_node_lock: threading.Lock = threading.Lock()
|
||||
# port numbers are allocated from these counters
|
||||
|
@ -117,7 +118,7 @@ class EmaneManager(ModelManager):
|
|||
|
||||
def next_nem_id(self) -> int:
|
||||
nem_id = int(self.get_config("nem_id_start"))
|
||||
while nem_id in self.nems:
|
||||
while nem_id in self.nems_to_ifaces:
|
||||
nem_id += 1
|
||||
return nem_id
|
||||
|
||||
|
@ -363,7 +364,7 @@ class EmaneManager(ModelManager):
|
|||
0, remove=False, conf_required=False
|
||||
)
|
||||
nem_id = self.next_nem_id()
|
||||
self.nems[nem_id] = iface
|
||||
self.set_nem(nem_id, iface)
|
||||
self.write_nem(iface, nem_id)
|
||||
emanexml.build_platform_xml(self, control_net, emane_net, iface, nem_id)
|
||||
config = self.get_iface_config(emane_net, iface)
|
||||
|
@ -371,6 +372,18 @@ class EmaneManager(ModelManager):
|
|||
self.start_daemon(iface)
|
||||
self.install_iface(emane_net, iface)
|
||||
|
||||
def set_nem(self, nem_id: int, iface: CoreInterface) -> None:
|
||||
if nem_id in self.nems_to_ifaces:
|
||||
raise CoreError(f"adding duplicate nem: {nem_id}")
|
||||
self.nems_to_ifaces[nem_id] = iface
|
||||
self.ifaces_to_nems[iface] = nem_id
|
||||
|
||||
def get_iface(self, nem_id: int) -> Optional[CoreInterface]:
|
||||
return self.nems_to_ifaces.get(nem_id)
|
||||
|
||||
def get_nem_id(self, iface: CoreInterface) -> Optional[int]:
|
||||
return self.ifaces_to_nems.get(iface)
|
||||
|
||||
def write_nem(self, iface: CoreInterface, nem_id: int) -> None:
|
||||
path = os.path.join(self.session.session_dir, "emane_nems")
|
||||
try:
|
||||
|
@ -405,7 +418,8 @@ class EmaneManager(ModelManager):
|
|||
"""
|
||||
with self._emane_node_lock:
|
||||
self._emane_nets.clear()
|
||||
self.nems.clear()
|
||||
self.nems_to_ifaces.clear()
|
||||
self.ifaces_to_nems.clear()
|
||||
|
||||
def shutdown(self) -> None:
|
||||
"""
|
||||
|
@ -448,42 +462,29 @@ class EmaneManager(ModelManager):
|
|||
model_class = self.models[model_name]
|
||||
emane_net.setmodel(model_class, config)
|
||||
|
||||
def nemlookup(self, nemid) -> Tuple[Optional[EmaneNet], Optional[CoreInterface]]:
|
||||
"""
|
||||
Look for the given numerical NEM ID and return the first matching
|
||||
EMANE network and NEM interface.
|
||||
"""
|
||||
emane_node = None
|
||||
iface = None
|
||||
for node_id in self._emane_nets:
|
||||
emane_node = self._emane_nets[node_id]
|
||||
iface = emane_node.get_nem_iface(nemid)
|
||||
if iface is not None:
|
||||
break
|
||||
else:
|
||||
emane_node = None
|
||||
return emane_node, iface
|
||||
|
||||
def get_nem_link(
|
||||
self, nem1: int, nem2: int, flags: MessageFlags = MessageFlags.NONE
|
||||
) -> Optional[LinkData]:
|
||||
emane1, iface = self.nemlookup(nem1)
|
||||
if not emane1 or not iface:
|
||||
iface1 = self.get_iface(nem1)
|
||||
if not iface1:
|
||||
logging.error("invalid nem: %s", nem1)
|
||||
return None
|
||||
node1 = iface.node
|
||||
emane2, iface = self.nemlookup(nem2)
|
||||
if not emane2 or not iface:
|
||||
node1 = iface1.node
|
||||
iface2 = self.get_iface(nem2)
|
||||
if not iface2:
|
||||
logging.error("invalid nem: %s", nem2)
|
||||
return None
|
||||
node2 = iface.node
|
||||
color = self.session.get_link_color(emane1.id)
|
||||
node2 = iface2.node
|
||||
if iface1.net != iface2.net:
|
||||
return None
|
||||
emane_net = iface1.net
|
||||
color = self.session.get_link_color(emane_net.id)
|
||||
return LinkData(
|
||||
message_type=flags,
|
||||
type=LinkTypes.WIRELESS,
|
||||
node1_id=node1.id,
|
||||
node2_id=node2.id,
|
||||
network_id=emane1.id,
|
||||
network_id=emane_net.id,
|
||||
color=color,
|
||||
)
|
||||
|
||||
|
@ -728,7 +729,7 @@ class EmaneManager(ModelManager):
|
|||
Returns True if successfully parsed and a Node Message was sent.
|
||||
"""
|
||||
# convert nemid to node number
|
||||
_emanenode, iface = self.nemlookup(nemid)
|
||||
iface = self.get_iface(nemid)
|
||||
if iface is None:
|
||||
logging.info("location event for unknown NEM %s", nemid)
|
||||
return False
|
||||
|
|
|
@ -52,7 +52,6 @@ class EmaneNet(CoreNetworkBase):
|
|||
) -> None:
|
||||
super().__init__(session, _id, name, server)
|
||||
self.conf: str = ""
|
||||
self.nemidmap: Dict[CoreInterface, int] = {}
|
||||
self.model: "OptionalEmaneModel" = None
|
||||
self.mobility: Optional[WayPointMobility] = None
|
||||
|
||||
|
@ -105,32 +104,6 @@ class EmaneNet(CoreNetworkBase):
|
|||
self.mobility = model(session=self.session, _id=self.id)
|
||||
self.mobility.update_config(config)
|
||||
|
||||
def setnemid(self, iface: CoreInterface, nemid: int) -> None:
|
||||
"""
|
||||
Record an interface to numerical ID mapping. The Emane controller
|
||||
object manages and assigns these IDs for all NEMs.
|
||||
"""
|
||||
self.nemidmap[iface] = nemid
|
||||
|
||||
def getnemid(self, iface: CoreInterface) -> Optional[int]:
|
||||
"""
|
||||
Given an interface, return its numerical ID.
|
||||
"""
|
||||
if iface not in self.nemidmap:
|
||||
return None
|
||||
else:
|
||||
return self.nemidmap[iface]
|
||||
|
||||
def get_nem_iface(self, nemid: int) -> Optional[CoreInterface]:
|
||||
"""
|
||||
Given a numerical NEM ID, return its interface. This returns the
|
||||
first interface that matches the given NEM ID.
|
||||
"""
|
||||
for iface in self.nemidmap:
|
||||
if self.nemidmap[iface] == nemid:
|
||||
return iface
|
||||
return None
|
||||
|
||||
def _nem_position(
|
||||
self, iface: CoreInterface
|
||||
) -> Optional[Tuple[int, float, float, float]]:
|
||||
|
@ -140,9 +113,9 @@ class EmaneNet(CoreNetworkBase):
|
|||
:param iface: interface to get nem emane position for
|
||||
:return: nem position tuple, None otherwise
|
||||
"""
|
||||
nemid = self.getnemid(iface)
|
||||
nem_id = self.session.emane.get_nem_id(iface)
|
||||
ifname = iface.localname
|
||||
if nemid is None:
|
||||
if nem_id is None:
|
||||
logging.info("nemid for %s is unknown", ifname)
|
||||
return
|
||||
node = iface.node
|
||||
|
@ -153,7 +126,7 @@ class EmaneNet(CoreNetworkBase):
|
|||
node.position.set_geo(lon, lat, alt)
|
||||
# altitude must be an integer or warning is printed
|
||||
alt = int(round(alt))
|
||||
return nemid, lon, lat, alt
|
||||
return nem_id, lon, lat, alt
|
||||
|
||||
def setnemposition(self, iface: CoreInterface) -> None:
|
||||
"""
|
||||
|
@ -164,7 +137,6 @@ class EmaneNet(CoreNetworkBase):
|
|||
if self.session.emane.service is None:
|
||||
logging.info("position service not available")
|
||||
return
|
||||
|
||||
position = self._nem_position(iface)
|
||||
if position:
|
||||
nemid, lon, lat, alt = position
|
||||
|
@ -195,9 +167,12 @@ class EmaneNet(CoreNetworkBase):
|
|||
|
||||
def links(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
|
||||
links = super().links(flags)
|
||||
# gather current emane links
|
||||
nem_ids = set(self.nemidmap.values())
|
||||
emane_manager = self.session.emane
|
||||
# gather current emane links
|
||||
nem_ids = set()
|
||||
for iface in self.get_ifaces():
|
||||
nem_id = emane_manager.get_nem_id(iface)
|
||||
nem_ids.add(nem_id)
|
||||
emane_links = emane_manager.link_monitor.links
|
||||
considered = set()
|
||||
for link_key in emane_links:
|
||||
|
|
|
@ -28,7 +28,7 @@ class EmaneTransportService(CoreService):
|
|||
emane_net = iface.net
|
||||
config = emane_manager.get_iface_config(emane_net, iface)
|
||||
if emanexml.is_external(config):
|
||||
nem_id = emane_net.getnemid(iface)
|
||||
nem_id = emane_manager.get_nem_id(iface)
|
||||
cfg += f"emanegentransportxml {iface.name}-platform.xml\n"
|
||||
cfg += f"emanetransportd -r -l 0 -d transportdaemon{nem_id}.xml\n"
|
||||
return cfg
|
||||
|
|
|
@ -501,8 +501,8 @@ class CoreXmlWriter:
|
|||
iface = node.get_iface(iface_data.id)
|
||||
# check if emane interface
|
||||
if isinstance(iface.net, EmaneNet):
|
||||
nem = iface.net.getnemid(iface)
|
||||
add_attribute(iface_element, "nem", nem)
|
||||
nem_id = self.session.emane.get_nem_id(iface)
|
||||
add_attribute(iface_element, "nem", nem_id)
|
||||
add_attribute(iface_element, "id", iface_data.id)
|
||||
add_attribute(iface_element, "name", iface_data.name)
|
||||
add_attribute(iface_element, "mac", iface_data.mac)
|
||||
|
|
|
@ -9,7 +9,6 @@ from core import utils
|
|||
from core.emane.nodes import EmaneNet
|
||||
from core.executables import IP
|
||||
from core.nodes.base import CoreNodeBase, NodeBase
|
||||
from core.nodes.interface import CoreInterface
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.emulator.session import Session
|
||||
|
@ -38,11 +37,10 @@ def add_mapping(parent_element: etree.Element, maptype: str, mapref: str) -> Non
|
|||
|
||||
def add_emane_iface(
|
||||
host_element: etree.Element,
|
||||
iface: CoreInterface,
|
||||
nem_id: int,
|
||||
platform_name: str = "p1",
|
||||
transport_name: str = "t1",
|
||||
) -> etree.Element:
|
||||
nem_id = iface.net.nemidmap[iface]
|
||||
host_id = host_element.get("id")
|
||||
|
||||
# platform data
|
||||
|
@ -158,7 +156,8 @@ class CoreXmlDeployment:
|
|||
for iface in node.get_ifaces():
|
||||
emane_element = None
|
||||
if isinstance(iface.net, EmaneNet):
|
||||
emane_element = add_emane_iface(host_element, iface)
|
||||
nem_id = self.session.emane.get_nem_id(iface)
|
||||
emane_element = add_emane_iface(host_element, nem_id)
|
||||
|
||||
parent_element = host_element
|
||||
if emane_element is not None:
|
||||
|
|
|
@ -193,7 +193,6 @@ def build_platform_xml(
|
|||
value = emane_manager.get_config(name)
|
||||
add_param(platform_element, name, value)
|
||||
platform_element.append(nem_element)
|
||||
emane_net.setnemid(iface, nem_id)
|
||||
mac = _MAC_PREFIX + ":00:00:"
|
||||
mac += f"{(nem_id >> 8) & 0xFF:02X}:{nem_id & 0xFF:02X}"
|
||||
iface.set_mac(mac)
|
||||
|
|
Loading…
Reference in a new issue