changes to move sdt calls internal to core interactions, which allows it to work with both guis
This commit is contained in:
parent
20e3fbc7d9
commit
67da3e5c22
3 changed files with 156 additions and 295 deletions
|
@ -526,11 +526,6 @@ class CoreHandler(socketserver.BaseRequestHandler):
|
|||
logging.debug(
|
||||
"%s handling message:\n%s", threading.currentThread().getName(), message
|
||||
)
|
||||
|
||||
# provide to sdt, if enabled
|
||||
if self.session and self.session.sdt.is_enabled():
|
||||
self.session.sdt.handle_distributed(message)
|
||||
|
||||
if message.message_type not in self.message_handlers:
|
||||
logging.error("no handler for message type: %s", message.type_str())
|
||||
return
|
||||
|
@ -2042,7 +2037,6 @@ class CoreUdpHandler(CoreHandler):
|
|||
logging.debug("session handling message: %s", session.session_id)
|
||||
self.session = session
|
||||
self.handle_message(message)
|
||||
self.session.sdt.handle_distributed(message)
|
||||
self.broadcast(message)
|
||||
else:
|
||||
logging.error(
|
||||
|
@ -2067,7 +2061,6 @@ class CoreUdpHandler(CoreHandler):
|
|||
if session or message.message_type == MessageTypes.REGISTER.value:
|
||||
self.session = session
|
||||
self.handle_message(message)
|
||||
self.session.sdt.handle_distributed(message)
|
||||
self.broadcast(message)
|
||||
else:
|
||||
logging.error(
|
||||
|
|
|
@ -432,6 +432,7 @@ class Session:
|
|||
if node_two:
|
||||
node_two.lock.release()
|
||||
|
||||
self.sdt.add_link(node_one_id, node_two_id, is_wireless=False)
|
||||
return node_one_interface, node_two_interface
|
||||
|
||||
def delete_link(
|
||||
|
@ -540,6 +541,8 @@ class Session:
|
|||
if node_two:
|
||||
node_two.lock.release()
|
||||
|
||||
self.sdt.delete_link(node_one_id, node_two_id)
|
||||
|
||||
def update_link(
|
||||
self,
|
||||
node_one_id: int,
|
||||
|
@ -757,6 +760,7 @@ class Session:
|
|||
self.add_remove_control_interface(node=node, remove=False)
|
||||
self.services.boot_services(node)
|
||||
|
||||
self.sdt.add_node(node)
|
||||
return node
|
||||
|
||||
def edit_node(self, node_id: int, options: NodeOptions) -> None:
|
||||
|
@ -765,7 +769,7 @@ class Session:
|
|||
|
||||
:param node_id: id of node to update
|
||||
:param options: data to update node with
|
||||
:return: True if node updated, False otherwise
|
||||
:return: nothing
|
||||
:raises core.CoreError: when node to update does not exist
|
||||
"""
|
||||
# get node to update
|
||||
|
@ -778,6 +782,8 @@ class Session:
|
|||
node.canvas = options.canvas
|
||||
node.icon = options.icon
|
||||
|
||||
self.sdt.edit_node(node)
|
||||
|
||||
def set_node_position(self, node: NodeBase, options: NodeOptions) -> None:
|
||||
"""
|
||||
Set position for a node, use lat/lon/alt if needed.
|
||||
|
@ -1402,6 +1408,7 @@ class Session:
|
|||
if node:
|
||||
node.shutdown()
|
||||
self.check_shutdown()
|
||||
self.sdt.delete_node(_id)
|
||||
|
||||
return node is not None
|
||||
|
||||
|
@ -1413,6 +1420,7 @@ class Session:
|
|||
funcs = []
|
||||
while self.nodes:
|
||||
_, node = self.nodes.popitem()
|
||||
self.sdt.delete_node(node.id)
|
||||
funcs.append((node.shutdown, [], {}))
|
||||
utils.threadpool(funcs)
|
||||
self.node_id_gen.id = 0
|
||||
|
|
|
@ -4,22 +4,15 @@ sdt.py: Scripted Display Tool (SDT3D) helper
|
|||
|
||||
import logging
|
||||
import socket
|
||||
from typing import TYPE_CHECKING, Any, Optional
|
||||
import threading
|
||||
from typing import TYPE_CHECKING, Optional, Tuple
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from core import constants
|
||||
from core.api.tlv.coreapi import CoreLinkMessage, CoreMessage, CoreNodeMessage
|
||||
from core.constants import CORE_DATA_DIR
|
||||
from core.emane.nodes import EmaneNet
|
||||
from core.emulator.data import LinkData, NodeData
|
||||
from core.emulator.enumerations import (
|
||||
EventTypes,
|
||||
LinkTlvs,
|
||||
LinkTypes,
|
||||
MessageFlags,
|
||||
NodeTlvs,
|
||||
NodeTypes,
|
||||
)
|
||||
from core.emulator.enumerations import EventTypes, LinkTypes, MessageFlags
|
||||
from core.errors import CoreError
|
||||
from core.nodes.base import CoreNetworkBase, NodeBase
|
||||
from core.nodes.network import WlanNode
|
||||
|
@ -28,19 +21,11 @@ if TYPE_CHECKING:
|
|||
from core.emulator.session import Session
|
||||
|
||||
|
||||
# TODO: A named tuple may be more appropriate, than abusing a class dict like this
|
||||
class Bunch:
|
||||
"""
|
||||
Helper class for recording a collection of attributes.
|
||||
"""
|
||||
|
||||
def __init__(self, **kwargs: Any) -> None:
|
||||
"""
|
||||
Create a Bunch instance.
|
||||
|
||||
:param kwargs: keyword arguments
|
||||
"""
|
||||
self.__dict__.update(kwargs)
|
||||
def link_data_params(link_data: LinkData) -> Tuple[int, int, bool]:
|
||||
node_one = link_data.node1_id
|
||||
node_two = link_data.node2_id
|
||||
is_wireless = link_data.link_type == LinkTypes.WIRELESS.value
|
||||
return node_one, node_two, is_wireless
|
||||
|
||||
|
||||
class Sdt:
|
||||
|
@ -74,53 +59,16 @@ class Sdt:
|
|||
:param session: session this manager is tied to
|
||||
"""
|
||||
self.session = session
|
||||
self.lock = threading.Lock()
|
||||
self.sock = None
|
||||
self.connected = False
|
||||
self.showerror = True
|
||||
self.url = self.DEFAULT_SDT_URL
|
||||
# node information for remote nodes not in session._objs
|
||||
# local nodes also appear here since their obj may not exist yet
|
||||
self.remotes = {}
|
||||
|
||||
# add handler for node updates
|
||||
self.address = None
|
||||
self.protocol = None
|
||||
self.session.node_handlers.append(self.handle_node_update)
|
||||
|
||||
# add handler for link updates
|
||||
self.session.link_handlers.append(self.handle_link_update)
|
||||
|
||||
def handle_node_update(self, node_data: NodeData) -> None:
|
||||
"""
|
||||
Handler for node updates, specifically for updating their location.
|
||||
|
||||
:param node_data: node data being updated
|
||||
:return: nothing
|
||||
"""
|
||||
x = node_data.x_position
|
||||
y = node_data.y_position
|
||||
lat = node_data.latitude
|
||||
lon = node_data.longitude
|
||||
alt = node_data.altitude
|
||||
if all([lat is not None, lon is not None, alt is not None]):
|
||||
self.updatenodegeo(node_data.id, lat, lon, alt)
|
||||
elif node_data.message_type == 0:
|
||||
# TODO: z is not currently supported by node messages
|
||||
self.updatenode(node_data.id, 0, x, y, 0)
|
||||
|
||||
def handle_link_update(self, link_data: LinkData) -> None:
|
||||
"""
|
||||
Handler for link updates, checking for wireless link/unlink messages.
|
||||
|
||||
:param link_data: link data being updated
|
||||
:return: nothing
|
||||
"""
|
||||
if link_data.link_type == LinkTypes.WIRELESS.value:
|
||||
self.updatelink(
|
||||
link_data.node1_id,
|
||||
link_data.node2_id,
|
||||
link_data.message_type,
|
||||
wireless=True,
|
||||
)
|
||||
|
||||
def is_enabled(self) -> bool:
|
||||
"""
|
||||
Check for "enablesdt" session option. Return False by default if
|
||||
|
@ -137,9 +85,7 @@ class Sdt:
|
|||
|
||||
:return: nothing
|
||||
"""
|
||||
url = self.session.options.get_config("stdurl")
|
||||
if not url:
|
||||
url = self.DEFAULT_SDT_URL
|
||||
url = self.session.options.get_config("stdurl", default=self.DEFAULT_SDT_URL)
|
||||
self.url = urlparse(url)
|
||||
self.address = (self.url.hostname, self.url.port)
|
||||
self.protocol = self.url.scheme
|
||||
|
@ -178,7 +124,6 @@ class Sdt:
|
|||
# refresh all objects in SDT3D when connecting after session start
|
||||
if not flags & MessageFlags.ADD.value and not self.sendobjs():
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def initialize(self) -> bool:
|
||||
|
@ -234,8 +179,10 @@ class Sdt:
|
|||
"""
|
||||
if self.sock is None:
|
||||
return False
|
||||
|
||||
try:
|
||||
cmd = f"{cmdstr}\n".encode()
|
||||
logging.debug("sdt cmd: %s", cmd)
|
||||
self.sock.sendall(cmd)
|
||||
return True
|
||||
except IOError:
|
||||
|
@ -244,91 +191,6 @@ class Sdt:
|
|||
self.connected = False
|
||||
return False
|
||||
|
||||
def updatenode(
|
||||
self,
|
||||
nodenum: int,
|
||||
flags: int,
|
||||
x: Optional[float],
|
||||
y: Optional[float],
|
||||
z: Optional[float],
|
||||
name: str = None,
|
||||
node_type: str = None,
|
||||
icon: str = None,
|
||||
) -> None:
|
||||
"""
|
||||
Node is updated from a Node Message or mobility script.
|
||||
|
||||
:param nodenum: node id to update
|
||||
:param flags: update flags
|
||||
:param x: x position
|
||||
:param y: y position
|
||||
:param z: z position
|
||||
:param name: node name
|
||||
:param node_type: node type
|
||||
:param icon: node icon
|
||||
:return: nothing
|
||||
"""
|
||||
if not self.connect():
|
||||
return
|
||||
if flags & MessageFlags.DELETE.value:
|
||||
self.cmd(f"delete node,{nodenum}")
|
||||
return
|
||||
if x is None or y is None:
|
||||
return
|
||||
lat, lon, alt = self.session.location.getgeo(x, y, z)
|
||||
pos = f"pos {lon:.6f},{lat:.6f},{alt:.6f}"
|
||||
if flags & MessageFlags.ADD.value:
|
||||
if icon is not None:
|
||||
node_type = name
|
||||
icon = icon.replace("$CORE_DATA_DIR", constants.CORE_DATA_DIR)
|
||||
icon = icon.replace("$CORE_CONF_DIR", constants.CORE_CONF_DIR)
|
||||
self.cmd(f"sprite {node_type} image {icon}")
|
||||
self.cmd(f'node {nodenum} type {node_type} label on,"{name}" {pos}')
|
||||
else:
|
||||
self.cmd(f"node {nodenum} {pos}")
|
||||
|
||||
def updatenodegeo(self, nodenum: int, lat: float, lon: float, alt: float) -> None:
|
||||
"""
|
||||
Node is updated upon receiving an EMANE Location Event.
|
||||
|
||||
:param nodenum: node id to update geospatial for
|
||||
:param lat: latitude
|
||||
:param lon: longitude
|
||||
:param alt: altitude
|
||||
:return: nothing
|
||||
"""
|
||||
|
||||
# TODO: received Node Message with lat/long/alt.
|
||||
if not self.connect():
|
||||
return
|
||||
pos = f"pos {lon:.6f},{lat:.6f},{alt:.6f}"
|
||||
self.cmd(f"node {nodenum} {pos}")
|
||||
|
||||
def updatelink(
|
||||
self, node1num: int, node2num: int, flags: int, wireless: bool = False
|
||||
) -> None:
|
||||
"""
|
||||
Link is updated from a Link Message or by a wireless model.
|
||||
|
||||
:param node1num: node one id
|
||||
:param node2num: node two id
|
||||
:param flags: link flags
|
||||
:param wireless: flag to check if wireless or not
|
||||
:return: nothing
|
||||
"""
|
||||
if node1num is None or node2num is None:
|
||||
return
|
||||
if not self.connect():
|
||||
return
|
||||
if flags & MessageFlags.DELETE.value:
|
||||
self.cmd(f"delete link,{node1num},{node2num}")
|
||||
elif flags & MessageFlags.ADD.value:
|
||||
if wireless:
|
||||
attr = " line green,2"
|
||||
else:
|
||||
attr = " line red,2"
|
||||
self.cmd(f"link {node1num},{node2num}{attr}")
|
||||
|
||||
def sendobjs(self) -> None:
|
||||
"""
|
||||
Session has already started, and the SDT3D GUI later connects.
|
||||
|
@ -345,171 +207,169 @@ class Sdt:
|
|||
nets.append(node)
|
||||
if not isinstance(node, NodeBase):
|
||||
continue
|
||||
(x, y, z) = node.getposition()
|
||||
if x is None or y is None:
|
||||
continue
|
||||
self.updatenode(
|
||||
node.id,
|
||||
MessageFlags.ADD.value,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
node.name,
|
||||
node.type,
|
||||
node.icon,
|
||||
)
|
||||
for nodenum in sorted(self.remotes.keys()):
|
||||
r = self.remotes[nodenum]
|
||||
x, y, z = r.pos
|
||||
self.updatenode(
|
||||
nodenum, MessageFlags.ADD.value, x, y, z, r.name, r.type, r.icon
|
||||
)
|
||||
self.add_node(node)
|
||||
|
||||
for net in nets:
|
||||
all_links = net.all_link_data(flags=MessageFlags.ADD.value)
|
||||
for link_data in all_links:
|
||||
is_wireless = isinstance(net, (WlanNode, EmaneNet))
|
||||
wireless_link = link_data.message_type == LinkTypes.WIRELESS.value
|
||||
if is_wireless and link_data.node1_id == net.id:
|
||||
continue
|
||||
params = link_data_params(link_data)
|
||||
self.add_link(*params)
|
||||
|
||||
self.updatelink(
|
||||
link_data.node1_id,
|
||||
link_data.node2_id,
|
||||
MessageFlags.ADD.value,
|
||||
wireless_link,
|
||||
)
|
||||
|
||||
for n1num in sorted(self.remotes.keys()):
|
||||
r = self.remotes[n1num]
|
||||
for n2num, wireless_link in r.links:
|
||||
self.updatelink(n1num, n2num, MessageFlags.ADD.value, wireless_link)
|
||||
|
||||
def handle_distributed(self, message: CoreMessage) -> None:
|
||||
def get_node_position(self, node: NodeBase) -> Optional[str]:
|
||||
"""
|
||||
Broker handler for processing CORE API messages as they are
|
||||
received. This is used to snoop the Node messages and update
|
||||
node positions.
|
||||
Convenience to generate an SDT position string, given a node.
|
||||
|
||||
:param message: message to handle
|
||||
:param node:
|
||||
:return:
|
||||
"""
|
||||
x, y, z = node.position.get()
|
||||
if x is None or y is None:
|
||||
return None
|
||||
lat, lon, alt = self.session.location.getgeo(x, y, z)
|
||||
return f"pos {lon:.6f},{lat:.6f},{alt:.6f}"
|
||||
|
||||
def add_node(self, node: NodeBase) -> None:
|
||||
"""
|
||||
Handle adding a node in SDT.
|
||||
|
||||
:param node: node to add
|
||||
:return: nothing
|
||||
"""
|
||||
if isinstance(message, CoreLinkMessage):
|
||||
self.handlelinkmsg(message)
|
||||
elif isinstance(message, CoreNodeMessage):
|
||||
self.handlenodemsg(message)
|
||||
logging.debug("sdt add node: %s - %s", node.id, node.name)
|
||||
if not self.connect():
|
||||
return
|
||||
pos = self.get_node_position(node)
|
||||
if not pos:
|
||||
return
|
||||
node_type = node.type
|
||||
if node_type is None:
|
||||
node_type = type(node).type
|
||||
icon = node.icon
|
||||
if icon:
|
||||
node_type = node.name
|
||||
icon = icon.replace("$CORE_DATA_DIR", constants.CORE_DATA_DIR)
|
||||
icon = icon.replace("$CORE_CONF_DIR", constants.CORE_CONF_DIR)
|
||||
self.cmd(f"sprite {node_type} image {icon}")
|
||||
self.cmd(f'node {node.id} type {node_type} label on,"{node.name}" {pos}')
|
||||
|
||||
def handlenodemsg(self, msg: CoreNodeMessage) -> None:
|
||||
def edit_node(self, node: NodeBase) -> None:
|
||||
"""
|
||||
Process a Node Message to add/delete or move a node on
|
||||
the SDT display. Node properties are found in a session or
|
||||
self.remotes for remote nodes (or those not yet instantiated).
|
||||
Handle updating a node in SDT.
|
||||
|
||||
:param msg: node message to handle
|
||||
:param node: node to update
|
||||
:return: nothing
|
||||
"""
|
||||
# for distributed sessions to work properly, the SDT option should be
|
||||
# enabled prior to starting the session
|
||||
if not self.is_enabled():
|
||||
logging.debug("sdt update node: %s - %s", node.id, node.name)
|
||||
if not self.connect():
|
||||
return
|
||||
# node.(_id, type, icon, name) are used.
|
||||
nodenum = msg.get_tlv(NodeTlvs.NUMBER.value)
|
||||
if not nodenum:
|
||||
pos = self.get_node_position(node)
|
||||
if not pos:
|
||||
return
|
||||
x = msg.get_tlv(NodeTlvs.X_POSITION.value)
|
||||
y = msg.get_tlv(NodeTlvs.Y_POSITION.value)
|
||||
z = None
|
||||
name = msg.get_tlv(NodeTlvs.NAME.value)
|
||||
self.cmd(f"node {node.id} {pos}")
|
||||
|
||||
nodetype = msg.get_tlv(NodeTlvs.TYPE.value)
|
||||
model = msg.get_tlv(NodeTlvs.MODEL.value)
|
||||
icon = msg.get_tlv(NodeTlvs.ICON.value)
|
||||
def delete_node(self, node_id: int) -> None:
|
||||
"""
|
||||
Handle deleting a node in SDT.
|
||||
|
||||
net = False
|
||||
if nodetype == NodeTypes.DEFAULT.value or nodetype == NodeTypes.PHYSICAL.value:
|
||||
if model is None:
|
||||
model = "router"
|
||||
nodetype = model
|
||||
elif nodetype is not None:
|
||||
nodetype = NodeTypes(nodetype)
|
||||
nodetype = self.session.get_node_class(nodetype).type
|
||||
net = True
|
||||
:param node_id: node id to delete
|
||||
:return: nothing
|
||||
"""
|
||||
logging.debug("sdt delete node: %s", node_id)
|
||||
if not self.connect():
|
||||
return
|
||||
self.cmd(f"delete node,{node_id}")
|
||||
|
||||
def handle_node_update(self, node_data: NodeData) -> None:
|
||||
"""
|
||||
Handler for node updates, specifically for updating their location.
|
||||
|
||||
:param node_data: node data being updated
|
||||
:return: nothing
|
||||
"""
|
||||
logging.debug("sdt handle node update: %s - %s", node_data.id, node_data.name)
|
||||
if not self.connect():
|
||||
return
|
||||
|
||||
# delete node
|
||||
if node_data.message_type == MessageFlags.DELETE.value:
|
||||
self.cmd(f"delete node,{node_data.id}")
|
||||
else:
|
||||
nodetype = None
|
||||
x = node_data.x_position
|
||||
y = node_data.y_position
|
||||
lat = node_data.latitude
|
||||
lon = node_data.longitude
|
||||
alt = node_data.altitude
|
||||
if all([lat is not None, lon is not None, alt is not None]):
|
||||
pos = f"pos {lon:.6f},{lat:.6f},{alt:.6f}"
|
||||
self.cmd(f"node {node_data.id} {pos}")
|
||||
elif node_data.message_type == 0:
|
||||
lat, lon, alt = self.session.location.getgeo(x, y, 0)
|
||||
pos = f"pos {lon:.6f},{lat:.6f},{alt:.6f}"
|
||||
self.cmd(f"node {node_data.id} {pos}")
|
||||
|
||||
def wireless_net_check(self, node_id: int) -> bool:
|
||||
"""
|
||||
Determines if a node is either a wireless node type.
|
||||
|
||||
:param node_id: node id to check
|
||||
:return: True is a wireless node type, False otherwise
|
||||
"""
|
||||
result = False
|
||||
try:
|
||||
node = self.session.get_node(nodenum)
|
||||
node = self.session.get_node(node_id)
|
||||
result = isinstance(node, (WlanNode, EmaneNet))
|
||||
except CoreError:
|
||||
node = None
|
||||
if node:
|
||||
self.updatenode(
|
||||
node.id, msg.flags, x, y, z, node.name, node.type, node.icon
|
||||
)
|
||||
else:
|
||||
if nodenum in self.remotes:
|
||||
remote = self.remotes[nodenum]
|
||||
if name is None:
|
||||
name = remote.name
|
||||
if nodetype is None:
|
||||
nodetype = remote.type
|
||||
if icon is None:
|
||||
icon = remote.icon
|
||||
else:
|
||||
remote = Bunch(
|
||||
_id=nodenum,
|
||||
type=nodetype,
|
||||
icon=icon,
|
||||
name=name,
|
||||
net=net,
|
||||
links=set(),
|
||||
)
|
||||
self.remotes[nodenum] = remote
|
||||
remote.pos = (x, y, z)
|
||||
self.updatenode(nodenum, msg.flags, x, y, z, name, nodetype, icon)
|
||||
pass
|
||||
return result
|
||||
|
||||
def handlelinkmsg(self, msg: CoreLinkMessage) -> None:
|
||||
def add_link(self, node_one: int, node_two: int, is_wireless: bool) -> None:
|
||||
"""
|
||||
Process a Link Message to add/remove links on the SDT display.
|
||||
Links are recorded in the remotes[nodenum1].links set for updating
|
||||
the SDT display at a later time.
|
||||
Handle adding a link in SDT.
|
||||
|
||||
:param msg: link message to handle
|
||||
:param node_one: node one id
|
||||
:param node_two: node two id
|
||||
:param is_wireless: True if link is wireless, False otherwise
|
||||
:return: nothing
|
||||
"""
|
||||
if not self.is_enabled():
|
||||
logging.debug("sdt add link: %s, %s, %s", node_one, node_two, is_wireless)
|
||||
if not self.connect():
|
||||
return
|
||||
nodenum1 = msg.get_tlv(LinkTlvs.N1_NUMBER.value)
|
||||
nodenum2 = msg.get_tlv(LinkTlvs.N2_NUMBER.value)
|
||||
link_msg_type = msg.get_tlv(LinkTlvs.TYPE.value)
|
||||
# this filters out links to WLAN and EMANE nodes which are not drawn
|
||||
if self.wlancheck(nodenum1):
|
||||
if self.wireless_net_check(node_one) or self.wireless_net_check(node_two):
|
||||
return
|
||||
wl = link_msg_type == LinkTypes.WIRELESS.value
|
||||
if nodenum1 in self.remotes:
|
||||
r = self.remotes[nodenum1]
|
||||
if msg.flags & MessageFlags.DELETE.value:
|
||||
if (nodenum2, wl) in r.links:
|
||||
r.links.remove((nodenum2, wl))
|
||||
else:
|
||||
r.links.add((nodenum2, wl))
|
||||
self.updatelink(nodenum1, nodenum2, msg.flags, wireless=wl)
|
||||
|
||||
def wlancheck(self, nodenum: int) -> bool:
|
||||
"""
|
||||
Helper returns True if a node number corresponds to a WLAN or EMANE node.
|
||||
|
||||
:param nodenum: node id to check
|
||||
:return: True if node is wlan or emane, False otherwise
|
||||
"""
|
||||
if nodenum in self.remotes:
|
||||
node_type = self.remotes[nodenum].type
|
||||
if node_type in ("wlan", "emane"):
|
||||
return True
|
||||
if is_wireless:
|
||||
attr = "green,2"
|
||||
else:
|
||||
try:
|
||||
n = self.session.get_node(nodenum)
|
||||
except CoreError:
|
||||
return False
|
||||
if isinstance(n, (WlanNode, EmaneNet)):
|
||||
return True
|
||||
return False
|
||||
attr = "red,2"
|
||||
self.cmd(f"link {node_one},{node_two} line {attr}")
|
||||
|
||||
def delete_link(self, node_one: int, node_two: int) -> None:
|
||||
"""
|
||||
Handle deleting a node in SDT.
|
||||
|
||||
:param node_one: node one id
|
||||
:param node_two: node two id
|
||||
:return: nothing
|
||||
"""
|
||||
logging.debug("sdt delete link: %s, %s", node_one, node_two)
|
||||
if not self.connect():
|
||||
return
|
||||
if self.wireless_net_check(node_one) or self.wireless_net_check(node_two):
|
||||
return
|
||||
self.cmd(f"delete link,{node_one},{node_two}")
|
||||
|
||||
def handle_link_update(self, link_data: LinkData) -> None:
|
||||
"""
|
||||
Handle link broadcast messages and push changes to SDT.
|
||||
|
||||
:param link_data: link data to handle
|
||||
:return: nothing
|
||||
"""
|
||||
if link_data.message_type == MessageFlags.ADD.value:
|
||||
params = link_data_params(link_data)
|
||||
self.add_link(*params)
|
||||
elif link_data.message_type == MessageFlags.DELETE.value:
|
||||
params = link_data_params(link_data)
|
||||
self.delete_link(*params[:2])
|
||||
|
|
Loading…
Reference in a new issue