daemon: changes to support providing emane wireless links in all_link_data, which makes it accessible over grpc

This commit is contained in:
Blake Harnden 2020-05-29 11:48:00 -07:00
parent 4ab415e37d
commit 183ffda570
3 changed files with 68 additions and 24 deletions

View file

@ -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.

View file

@ -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,

View file

@ -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