daemon: refactoring to tracking wireless link information
This commit is contained in:
parent
440c06c040
commit
ea751727b4
1 changed files with 30 additions and 23 deletions
|
@ -33,11 +33,17 @@ def calc_distance(
|
||||||
return math.hypot(math.hypot(a, b), c)
|
return math.hypot(math.hypot(a, b), c)
|
||||||
|
|
||||||
|
|
||||||
|
def get_key(node1_id: int, node2_id: int) -> Tuple[int, int]:
|
||||||
|
return (node1_id, node2_id) if node1_id < node2_id else (node2_id, node1_id)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class WirelessLink:
|
class WirelessLink:
|
||||||
bridge1: str
|
bridge1: str
|
||||||
bridge2: str
|
bridge2: str
|
||||||
iface: CoreInterface
|
iface: CoreInterface
|
||||||
|
linked: bool
|
||||||
|
label: str = None
|
||||||
|
|
||||||
|
|
||||||
class WirelessNode(CoreNetworkBase):
|
class WirelessNode(CoreNetworkBase):
|
||||||
|
@ -53,7 +59,6 @@ class WirelessNode(CoreNetworkBase):
|
||||||
super().__init__(session, _id, name, server)
|
super().__init__(session, _id, name, server)
|
||||||
self.bridges: Dict[int, Tuple[CoreInterface, str]] = {}
|
self.bridges: Dict[int, Tuple[CoreInterface, str]] = {}
|
||||||
self.links: Dict[Tuple[int, int], WirelessLink] = {}
|
self.links: Dict[Tuple[int, int], WirelessLink] = {}
|
||||||
self.labels: Dict[Tuple[int, int], str] = {}
|
|
||||||
|
|
||||||
def startup(self) -> None:
|
def startup(self) -> None:
|
||||||
if self.up:
|
if self.up:
|
||||||
|
@ -117,7 +122,7 @@ class WirelessNode(CoreNetworkBase):
|
||||||
name2 = f"we{self.id}.{node2.id}.{node1.id}.{session_id}"
|
name2 = f"we{self.id}.{node2.id}.{node1.id}.{session_id}"
|
||||||
link_iface = CoreInterface(0, name1, name2, self.session.use_ovs())
|
link_iface = CoreInterface(0, name1, name2, self.session.use_ovs())
|
||||||
link_iface.startup()
|
link_iface.startup()
|
||||||
link = WirelessLink(bridge1, bridge2, link_iface)
|
link = WirelessLink(bridge1, bridge2, link_iface, True)
|
||||||
self.links[key] = link
|
self.links[key] = link
|
||||||
# assign ifaces to respective bridges
|
# assign ifaces to respective bridges
|
||||||
self.net_client.set_iface_master(bridge1, link_iface.name)
|
self.net_client.set_iface_master(bridge1, link_iface.name)
|
||||||
|
@ -148,27 +153,27 @@ class WirelessNode(CoreNetworkBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
def link_control(self, node1_id: int, node2_id: int, linked: bool) -> None:
|
def link_control(self, node1_id: int, node2_id: int, linked: bool) -> None:
|
||||||
key = (node1_id, node2_id) if node1_id < node2_id else (node2_id, node1_id)
|
key = get_key(node1_id, node2_id)
|
||||||
link = self.links.get(key)
|
link = self.links.get(key)
|
||||||
if not link:
|
if not link:
|
||||||
raise CoreError(f"invalid node links node1({node1_id}) node2({node2_id})")
|
raise CoreError(f"invalid node links node1({node1_id}) node2({node2_id})")
|
||||||
bridge1, bridge2 = link.bridge1, link.bridge2
|
bridge1, bridge2 = link.bridge1, link.bridge2
|
||||||
iface = link.iface
|
iface = link.iface
|
||||||
if linked:
|
if not link.linked and linked:
|
||||||
|
link.linked = True
|
||||||
self.net_client.set_iface_master(bridge1, iface.name)
|
self.net_client.set_iface_master(bridge1, iface.name)
|
||||||
self.net_client.set_iface_master(bridge2, iface.localname)
|
self.net_client.set_iface_master(bridge2, iface.localname)
|
||||||
message_type = MessageFlags.ADD
|
self.send_link(key[0], key[1], MessageFlags.ADD, link.label)
|
||||||
else:
|
elif link.linked and not linked:
|
||||||
|
link.linked = False
|
||||||
self.net_client.delete_iface(bridge1, iface.name)
|
self.net_client.delete_iface(bridge1, iface.name)
|
||||||
self.net_client.delete_iface(bridge2, iface.localname)
|
self.net_client.delete_iface(bridge2, iface.localname)
|
||||||
message_type = MessageFlags.DELETE
|
self.send_link(key[0], key[1], MessageFlags.DELETE, link.label)
|
||||||
label = self.labels.get(key)
|
|
||||||
self.send_link(key[0], key[1], message_type, label)
|
|
||||||
|
|
||||||
def link_config(
|
def link_config(
|
||||||
self, node1_id: int, node2_id: int, options1: LinkOptions, options2: LinkOptions
|
self, node1_id: int, node2_id: int, options1: LinkOptions, options2: LinkOptions
|
||||||
) -> None:
|
) -> None:
|
||||||
key = (node1_id, node2_id) if node1_id < node2_id else (node2_id, node1_id)
|
key = get_key(node1_id, node2_id)
|
||||||
link = self.links.get(key)
|
link = self.links.get(key)
|
||||||
if not link:
|
if not link:
|
||||||
raise CoreError(f"invalid node links node1({node1_id}) node2({node2_id})")
|
raise CoreError(f"invalid node links node1({node1_id}) node2({node2_id})")
|
||||||
|
@ -183,14 +188,13 @@ class WirelessNode(CoreNetworkBase):
|
||||||
iface.set_config()
|
iface.set_config()
|
||||||
iface.name, iface.localname = name, localname
|
iface.name, iface.localname = name, localname
|
||||||
if options1 == options2:
|
if options1 == options2:
|
||||||
label = f"{options1.loss:.2f}%/{options1.delay}us"
|
link.label = f"{options1.loss:.2f}%/{options1.delay}us"
|
||||||
else:
|
else:
|
||||||
label = (
|
link.label = (
|
||||||
f"({options1.loss:.2f}%/{options1.delay}us) "
|
f"({options1.loss:.2f}%/{options1.delay}us) "
|
||||||
f"({options2.loss:.2f}%/{options2.delay}us)"
|
f"({options2.loss:.2f}%/{options2.delay}us)"
|
||||||
)
|
)
|
||||||
self.labels[key] = label
|
self.send_link(key[0], key[1], MessageFlags.NONE, link.label)
|
||||||
self.send_link(key[0], key[1], MessageFlags.NONE, label)
|
|
||||||
|
|
||||||
def send_link(
|
def send_link(
|
||||||
self,
|
self,
|
||||||
|
@ -224,15 +228,18 @@ class WirelessNode(CoreNetworkBase):
|
||||||
for oiface, bridge_name in self.bridges.values():
|
for oiface, bridge_name in self.bridges.values():
|
||||||
if iface == oiface:
|
if iface == oiface:
|
||||||
continue
|
continue
|
||||||
point1 = iface.node.position.get()
|
self.calc_link(iface, oiface)
|
||||||
point2 = oiface.node.position.get()
|
|
||||||
distance = calc_distance(point1, point2) - 250
|
def calc_link(self, iface1: CoreInterface, iface2: CoreInterface) -> None:
|
||||||
distance = max(distance, 0.0)
|
point1 = iface1.node.position.get()
|
||||||
loss = min((distance / 500) * 100.0, 100.0)
|
point2 = iface2.node.position.get()
|
||||||
node1_id = iface.node.id
|
distance = calc_distance(point1, point2) - 250
|
||||||
node2_id = oiface.node.id
|
distance = max(distance, 0.0)
|
||||||
options = LinkOptions(loss=loss, delay=0)
|
loss = min((distance / 500) * 100.0, 100.0)
|
||||||
self.link_config(node1_id, node2_id, options, options)
|
node1_id = iface1.node.id
|
||||||
|
node2_id = iface2.node.id
|
||||||
|
options = LinkOptions(loss=loss, delay=0)
|
||||||
|
self.link_config(node1_id, node2_id, options, options)
|
||||||
|
|
||||||
def adopt_iface(self, iface: CoreInterface, name: str) -> None:
|
def adopt_iface(self, iface: CoreInterface, name: str) -> None:
|
||||||
raise CoreError(f"{type(self)} does not support adopt interface")
|
raise CoreError(f"{type(self)} does not support adopt interface")
|
||||||
|
|
Loading…
Reference in a new issue