daemon: changes to support providing emane wireless links in all_link_data, which makes it accessible over grpc
This commit is contained in:
parent
4ab415e37d
commit
183ffda570
3 changed files with 68 additions and 24 deletions
|
@ -6,7 +6,7 @@ import logging
|
|||
import os
|
||||
import threading
|
||||
from collections import OrderedDict
|
||||
from typing import TYPE_CHECKING, Dict, List, Set, Tuple, Type
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple, Type
|
||||
|
||||
from core import utils
|
||||
from core.config import ConfigGroup, Configuration, ModelManager
|
||||
|
@ -19,7 +19,13 @@ from core.emane.linkmonitor import EmaneLinkMonitor
|
|||
from core.emane.nodes import EmaneNet
|
||||
from core.emane.rfpipe import EmaneRfPipeModel
|
||||
from core.emane.tdma import EmaneTdmaModel
|
||||
from core.emulator.enumerations import ConfigDataTypes, RegisterTlvs
|
||||
from core.emulator.data import LinkData
|
||||
from core.emulator.enumerations import (
|
||||
ConfigDataTypes,
|
||||
LinkTypes,
|
||||
MessageFlags,
|
||||
RegisterTlvs,
|
||||
)
|
||||
from core.errors import CoreCommandError, CoreError
|
||||
from core.nodes.base import CoreNode, NodeBase
|
||||
from core.nodes.interface import CoreInterface
|
||||
|
@ -458,7 +464,7 @@ class EmaneManager(ModelManager):
|
|||
model_class = self.models[model_name]
|
||||
emane_node.setmodel(model_class, config)
|
||||
|
||||
def nemlookup(self, nemid) -> Tuple[EmaneNet, CoreInterface]:
|
||||
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.
|
||||
|
@ -476,6 +482,29 @@ class EmaneManager(ModelManager):
|
|||
|
||||
return emane_node, netif
|
||||
|
||||
def get_nem_link(
|
||||
self, nem1: int, nem2: int, flags: MessageFlags = MessageFlags.NONE
|
||||
) -> Optional[LinkData]:
|
||||
emane1, netif = self.nemlookup(nem1)
|
||||
if not emane1 or not netif:
|
||||
logging.error("invalid nem: %s", nem1)
|
||||
return None
|
||||
node1 = netif.node
|
||||
emane2, netif = self.nemlookup(nem2)
|
||||
if not emane2 or not netif:
|
||||
logging.error("invalid nem: %s", nem2)
|
||||
return None
|
||||
node2 = netif.node
|
||||
color = self.session.get_link_color(emane1.id)
|
||||
return LinkData(
|
||||
message_type=flags,
|
||||
node1_id=node1.id,
|
||||
node2_id=node2.id,
|
||||
network_id=emane1.id,
|
||||
link_type=LinkTypes.WIRELESS,
|
||||
color=color,
|
||||
)
|
||||
|
||||
def numnems(self) -> int:
|
||||
"""
|
||||
Return the number of NEMs emulated locally.
|
||||
|
|
|
@ -285,26 +285,11 @@ class EmaneLinkMonitor:
|
|||
|
||||
def send_link(self, message_type: MessageFlags, link_id: Tuple[int, int]) -> None:
|
||||
nem_one, nem_two = link_id
|
||||
emane_one, netif = self.emane_manager.nemlookup(nem_one)
|
||||
if not emane_one or not netif:
|
||||
logging.error("invalid nem: %s", nem_one)
|
||||
return
|
||||
node_one = netif.node
|
||||
emane_two, netif = self.emane_manager.nemlookup(nem_two)
|
||||
if not emane_two or not netif:
|
||||
logging.error("invalid nem: %s", nem_two)
|
||||
return
|
||||
node_two = netif.node
|
||||
logging.debug(
|
||||
"%s emane link from %s(%s) to %s(%s)",
|
||||
message_type.name,
|
||||
node_one.name,
|
||||
nem_one,
|
||||
node_two.name,
|
||||
nem_two,
|
||||
)
|
||||
label = self.get_link_label(link_id)
|
||||
self.send_message(message_type, label, node_one.id, node_two.id, emane_one.id)
|
||||
link = self.emane_manager.get_nem_link(nem_one, nem_two, message_type)
|
||||
if link:
|
||||
label = self.get_link_label(link_id)
|
||||
link.label = label
|
||||
self.emane_manager.session.broadcast_link(link)
|
||||
|
||||
def send_message(
|
||||
self,
|
||||
|
|
|
@ -6,8 +6,9 @@ share the same MAC+PHY model.
|
|||
import logging
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Type
|
||||
|
||||
from core.emulator.data import LinkData
|
||||
from core.emulator.distributed import DistributedServer
|
||||
from core.emulator.enumerations import LinkTypes, NodeTypes, RegisterTlvs
|
||||
from core.emulator.enumerations import LinkTypes, MessageFlags, NodeTypes, RegisterTlvs
|
||||
from core.nodes.base import CoreNetworkBase
|
||||
from core.nodes.interface import CoreInterface
|
||||
|
||||
|
@ -236,3 +237,32 @@ class EmaneNet(CoreNetworkBase):
|
|||
nemid, lon, lat, alt = position
|
||||
event.append(nemid, latitude=lat, longitude=lon, altitude=alt)
|
||||
self.session.emane.service.publish(0, event)
|
||||
|
||||
def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
|
||||
logging.info("gathering emane links: %s", self.id)
|
||||
links = super().all_link_data(flags)
|
||||
# gather current emane links
|
||||
nem_ids = set(self.nemidmap.values())
|
||||
logging.info("known nems: %s", nem_ids)
|
||||
emane_manager = self.session.emane
|
||||
emane_links = emane_manager.link_monitor.links
|
||||
considered = set()
|
||||
for link_key in emane_links:
|
||||
considered_key = tuple(sorted(link_key))
|
||||
if considered_key in considered:
|
||||
continue
|
||||
considered.add(considered_key)
|
||||
logging.info("considering emane link: %s", considered_key)
|
||||
nem1, nem2 = considered_key
|
||||
# ignore links not related to this node
|
||||
if nem1 not in nem_ids and nem2 not in nem_ids:
|
||||
logging.info("ignore emane link not within network: %s", (nem1, nem2))
|
||||
continue
|
||||
# ignore incomplete links
|
||||
if (nem2, nem1) not in emane_links:
|
||||
logging.info("ignore emane link not complete: %s", (nem1, nem2))
|
||||
continue
|
||||
link = emane_manager.get_nem_link(nem1, nem2)
|
||||
if link:
|
||||
links.append(link)
|
||||
return links
|
||||
|
|
Loading…
Reference in a new issue