merged latest from develop
This commit is contained in:
commit
c264634b5f
10 changed files with 78 additions and 62 deletions
|
@ -2,7 +2,7 @@
|
||||||
# Process this file with autoconf to produce a configure script.
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
# this defines the CORE version number, must be static for AC_INIT
|
# this defines the CORE version number, must be static for AC_INIT
|
||||||
AC_INIT(core, 6.1.0)
|
AC_INIT(core, 6.2.0)
|
||||||
|
|
||||||
# autoconf and automake initialization
|
# autoconf and automake initialization
|
||||||
AC_CONFIG_SRCDIR([netns/version.h.in])
|
AC_CONFIG_SRCDIR([netns/version.h.in])
|
||||||
|
|
|
@ -708,7 +708,6 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
||||||
x = request.position.x
|
x = request.position.x
|
||||||
y = request.position.y
|
y = request.position.y
|
||||||
options.set_position(x, y)
|
options.set_position(x, y)
|
||||||
lat, lon, alt = None, None, None
|
|
||||||
has_geo = request.HasField("geo")
|
has_geo = request.HasField("geo")
|
||||||
if has_geo:
|
if has_geo:
|
||||||
lat = request.geo.lat
|
lat = request.geo.lat
|
||||||
|
|
|
@ -369,8 +369,7 @@ class EmaneManager(ModelManager):
|
||||||
)
|
)
|
||||||
emane_node.model.post_startup()
|
emane_node.model.post_startup()
|
||||||
for netif in emane_node.netifs():
|
for netif in emane_node.netifs():
|
||||||
x, y, z = netif.node.position.get()
|
netif.setposition()
|
||||||
emane_node.setnemposition(netif, x, y, z)
|
|
||||||
|
|
||||||
def reset(self) -> None:
|
def reset(self) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -806,6 +805,7 @@ class EmaneManager(ModelManager):
|
||||||
|
|
||||||
# don"t use node.setposition(x,y,z) which generates an event
|
# don"t use node.setposition(x,y,z) which generates an event
|
||||||
node.position.set(x, y, z)
|
node.position.set(x, y, z)
|
||||||
|
node.position.set_geo(lon, lat, alt)
|
||||||
node_data = node.data(lat=lat, lon=lon, alt=alt)
|
node_data = node.data(lat=lat, lon=lon, alt=alt)
|
||||||
self.session.broadcast_node(node_data)
|
self.session.broadcast_node(node_data)
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -4,7 +4,7 @@ share the same MAC+PHY model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from typing import TYPE_CHECKING, Dict, List, Optional, Type
|
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Type
|
||||||
|
|
||||||
from core.emulator.distributed import DistributedServer
|
from core.emulator.distributed import DistributedServer
|
||||||
from core.emulator.enumerations import LinkTypes, NodeTypes, RegisterTlvs
|
from core.emulator.enumerations import LinkTypes, NodeTypes, RegisterTlvs
|
||||||
|
@ -172,8 +172,7 @@ class EmaneNet(CoreNetworkBase):
|
||||||
# at this point we register location handlers for generating
|
# at this point we register location handlers for generating
|
||||||
# EMANE location events
|
# EMANE location events
|
||||||
netif.poshook = self.setnemposition
|
netif.poshook = self.setnemposition
|
||||||
x, y, z = netif.node.position.get()
|
netif.setposition()
|
||||||
self.setnemposition(netif, x, y, z)
|
|
||||||
|
|
||||||
def deinstallnetifs(self) -> None:
|
def deinstallnetifs(self) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -186,26 +185,43 @@ class EmaneNet(CoreNetworkBase):
|
||||||
netif.shutdown()
|
netif.shutdown()
|
||||||
netif.poshook = None
|
netif.poshook = None
|
||||||
|
|
||||||
def setnemposition(
|
def _nem_position(
|
||||||
self, netif: CoreInterface, x: float, y: float, z: float
|
self, netif: CoreInterface
|
||||||
) -> None:
|
) -> Optional[Tuple[int, float, float, float]]:
|
||||||
"""
|
"""
|
||||||
Publish a NEM location change event using the EMANE event service.
|
Creates nem position for emane event for a given interface.
|
||||||
|
|
||||||
|
:param netif: interface to get nem emane position for
|
||||||
|
:return: nem position tuple, None otherwise
|
||||||
"""
|
"""
|
||||||
if self.session.emane.service is None:
|
|
||||||
logging.info("position service not available")
|
|
||||||
return
|
|
||||||
nemid = self.getnemid(netif)
|
nemid = self.getnemid(netif)
|
||||||
ifname = netif.localname
|
ifname = netif.localname
|
||||||
if nemid is None:
|
if nemid is None:
|
||||||
logging.info("nemid for %s is unknown", ifname)
|
logging.info("nemid for %s is unknown", ifname)
|
||||||
return
|
return
|
||||||
|
node = netif.node
|
||||||
|
x, y, z = node.getposition()
|
||||||
lat, lon, alt = self.session.location.getgeo(x, y, z)
|
lat, lon, alt = self.session.location.getgeo(x, y, z)
|
||||||
event = LocationEvent()
|
if node.position.alt is not None:
|
||||||
|
alt = node.position.alt
|
||||||
# altitude must be an integer or warning is printed
|
# altitude must be an integer or warning is printed
|
||||||
# unused: yaw, pitch, roll, azimuth, elevation, velocity
|
|
||||||
alt = int(round(alt))
|
alt = int(round(alt))
|
||||||
|
return nemid, lon, lat, alt
|
||||||
|
|
||||||
|
def setnemposition(self, netif: CoreInterface) -> None:
|
||||||
|
"""
|
||||||
|
Publish a NEM location change event using the EMANE event service.
|
||||||
|
|
||||||
|
:param netif: interface to set nem position for
|
||||||
|
"""
|
||||||
|
if self.session.emane.service is None:
|
||||||
|
logging.info("position service not available")
|
||||||
|
return
|
||||||
|
|
||||||
|
position = self._nem_position(netif)
|
||||||
|
if position:
|
||||||
|
nemid, lon, lat, alt = position
|
||||||
|
event = LocationEvent()
|
||||||
event.append(nemid, latitude=lat, longitude=lon, altitude=alt)
|
event.append(nemid, latitude=lat, longitude=lon, altitude=alt)
|
||||||
self.session.emane.service.publish(0, event)
|
self.session.emane.service.publish(0, event)
|
||||||
|
|
||||||
|
@ -223,18 +239,9 @@ class EmaneNet(CoreNetworkBase):
|
||||||
return
|
return
|
||||||
|
|
||||||
event = LocationEvent()
|
event = LocationEvent()
|
||||||
i = 0
|
|
||||||
for netif in moved_netifs:
|
for netif in moved_netifs:
|
||||||
nemid = self.getnemid(netif)
|
position = self._nem_position(netif)
|
||||||
ifname = netif.localname
|
if position:
|
||||||
if nemid is None:
|
nemid, lon, lat, alt = position
|
||||||
logging.info("nemid for %s is unknown", ifname)
|
|
||||||
continue
|
|
||||||
x, y, z = netif.node.getposition()
|
|
||||||
lat, lon, alt = self.session.location.getgeo(x, y, z)
|
|
||||||
# altitude must be an integer or warning is printed
|
|
||||||
alt = int(round(alt))
|
|
||||||
event.append(nemid, latitude=lat, longitude=lon, altitude=alt)
|
event.append(nemid, latitude=lat, longitude=lon, altitude=alt)
|
||||||
i += 1
|
|
||||||
|
|
||||||
self.session.emane.service.publish(0, event)
|
self.session.emane.service.publish(0, event)
|
||||||
|
|
|
@ -805,6 +805,7 @@ class Session:
|
||||||
using_lat_lon_alt = has_empty_position and has_lat_lon_alt
|
using_lat_lon_alt = has_empty_position and has_lat_lon_alt
|
||||||
if using_lat_lon_alt:
|
if using_lat_lon_alt:
|
||||||
x, y, _ = self.location.getxyz(lat, lon, alt)
|
x, y, _ = self.location.getxyz(lat, lon, alt)
|
||||||
|
node.position.set_geo(lon, lat, alt)
|
||||||
|
|
||||||
# set position and broadcast
|
# set position and broadcast
|
||||||
if None not in [x, y]:
|
if None not in [x, y]:
|
||||||
|
|
|
@ -364,20 +364,16 @@ class BasicRangeModel(WirelessModel):
|
||||||
with self._netifslock:
|
with self._netifslock:
|
||||||
return self._netifs[netif]
|
return self._netifs[netif]
|
||||||
|
|
||||||
def set_position(
|
def set_position(self, netif: CoreInterface) -> None:
|
||||||
self, netif: CoreInterface, x: float = None, y: float = None, z: float = None
|
|
||||||
) -> None:
|
|
||||||
"""
|
"""
|
||||||
A node has moved; given an interface, a new (x,y,z) position has
|
A node has moved; given an interface, a new (x,y,z) position has
|
||||||
been set; calculate the new distance between other nodes and link or
|
been set; calculate the new distance between other nodes and link or
|
||||||
unlink node pairs based on the configured range.
|
unlink node pairs based on the configured range.
|
||||||
|
|
||||||
:param netif: network interface to set position for
|
:param netif: network interface to set position for
|
||||||
:param x: x position
|
|
||||||
:param y: y position
|
|
||||||
:param z: z position
|
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
|
x, y, z = netif.node.position.get()
|
||||||
self._netifslock.acquire()
|
self._netifslock.acquire()
|
||||||
self._netifs[netif] = (x, y, z)
|
self._netifs[netif] = (x, y, z)
|
||||||
if x is None or y is None:
|
if x is None or y is None:
|
||||||
|
|
|
@ -422,7 +422,7 @@ class CoreNodeBase(NodeBase):
|
||||||
changed = super().setposition(x, y, z)
|
changed = super().setposition(x, y, z)
|
||||||
if changed:
|
if changed:
|
||||||
for netif in self.netifs(sort=True):
|
for netif in self.netifs(sort=True):
|
||||||
netif.setposition(x, y, z)
|
netif.setposition()
|
||||||
|
|
||||||
def commonnets(
|
def commonnets(
|
||||||
self, obj: "CoreNodeBase", want_ctrl: bool = False
|
self, obj: "CoreNodeBase", want_ctrl: bool = False
|
||||||
|
@ -1173,11 +1173,13 @@ class Position:
|
||||||
:param x: x position
|
:param x: x position
|
||||||
:param y: y position
|
:param y: y position
|
||||||
:param z: z position
|
:param z: z position
|
||||||
:return:
|
|
||||||
"""
|
"""
|
||||||
self.x = x
|
self.x = x
|
||||||
self.y = y
|
self.y = y
|
||||||
self.z = z
|
self.z = z
|
||||||
|
self.lon = None
|
||||||
|
self.lat = None
|
||||||
|
self.alt = None
|
||||||
|
|
||||||
def set(self, x: float = None, y: float = None, z: float = None) -> bool:
|
def set(self, x: float = None, y: float = None, z: float = None) -> bool:
|
||||||
"""
|
"""
|
||||||
|
@ -1202,3 +1204,24 @@ class Position:
|
||||||
:return: x,y,z position tuple
|
:return: x,y,z position tuple
|
||||||
"""
|
"""
|
||||||
return self.x, self.y, self.z
|
return self.x, self.y, self.z
|
||||||
|
|
||||||
|
def set_geo(self, lon: float, lat: float, alt: float) -> None:
|
||||||
|
"""
|
||||||
|
Set geo position lon, lat, alt.
|
||||||
|
|
||||||
|
:param lon: longitude value
|
||||||
|
:param lat: latitude value
|
||||||
|
:param alt: altitude value
|
||||||
|
:return: nothing
|
||||||
|
"""
|
||||||
|
self.lon = lon
|
||||||
|
self.lat = lat
|
||||||
|
self.alt = alt
|
||||||
|
|
||||||
|
def get_geo(self) -> Tuple[float, float, float]:
|
||||||
|
"""
|
||||||
|
Retrieve current geo position lon, lat, alt.
|
||||||
|
|
||||||
|
:return: lon, lat, alt position tuple
|
||||||
|
"""
|
||||||
|
return self.lon, self.lat, self.alt
|
||||||
|
|
|
@ -51,7 +51,7 @@ class CoreInterface:
|
||||||
self.addrlist = []
|
self.addrlist = []
|
||||||
self.hwaddr = None
|
self.hwaddr = None
|
||||||
# placeholder position hook
|
# placeholder position hook
|
||||||
self.poshook = lambda a, b, c, d: None
|
self.poshook = lambda x: None
|
||||||
# used with EMANE
|
# used with EMANE
|
||||||
self.transport_type = None
|
self.transport_type = None
|
||||||
# node interface index
|
# node interface index
|
||||||
|
@ -210,16 +210,14 @@ class CoreInterface:
|
||||||
self._params = getattr(self, name)
|
self._params = getattr(self, name)
|
||||||
setattr(self, name, tmp)
|
setattr(self, name, tmp)
|
||||||
|
|
||||||
def setposition(self, x: float, y: float, z: float) -> None:
|
def setposition(self) -> None:
|
||||||
"""
|
"""
|
||||||
Dispatch position hook handler.
|
Dispatch position hook handler when possible.
|
||||||
|
|
||||||
:param x: x position
|
|
||||||
:param y: y position
|
|
||||||
:param z: z position
|
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
self.poshook(self, x, y, z)
|
if self.poshook and self.node:
|
||||||
|
self.poshook(self)
|
||||||
|
|
||||||
def __lt__(self, other: "CoreInterface") -> bool:
|
def __lt__(self, other: "CoreInterface") -> bool:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1067,6 +1067,7 @@ class WlanNode(CoreNetwork):
|
||||||
"""
|
"""
|
||||||
super().startup()
|
super().startup()
|
||||||
self.net_client.disable_mac_learning(self.brname)
|
self.net_client.disable_mac_learning(self.brname)
|
||||||
|
ebq.ebchange(self)
|
||||||
|
|
||||||
def attach(self, netif: CoreInterface) -> None:
|
def attach(self, netif: CoreInterface) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -1078,11 +1079,7 @@ class WlanNode(CoreNetwork):
|
||||||
super().attach(netif)
|
super().attach(netif)
|
||||||
if self.model:
|
if self.model:
|
||||||
netif.poshook = self.model.position_callback
|
netif.poshook = self.model.position_callback
|
||||||
if netif.node is None:
|
netif.setposition()
|
||||||
return
|
|
||||||
x, y, z = netif.node.position.get()
|
|
||||||
# invokes any netif.poshook
|
|
||||||
netif.setposition(x, y, z)
|
|
||||||
|
|
||||||
def setmodel(self, model: "WirelessModelType", config: Dict[str, str]):
|
def setmodel(self, model: "WirelessModelType", config: Dict[str, str]):
|
||||||
"""
|
"""
|
||||||
|
@ -1097,9 +1094,7 @@ class WlanNode(CoreNetwork):
|
||||||
self.model = model(session=self.session, _id=self.id)
|
self.model = model(session=self.session, _id=self.id)
|
||||||
for netif in self.netifs():
|
for netif in self.netifs():
|
||||||
netif.poshook = self.model.position_callback
|
netif.poshook = self.model.position_callback
|
||||||
if netif.poshook and netif.node:
|
netif.setposition()
|
||||||
x, y, z = netif.node.position.get()
|
|
||||||
netif.poshook(netif, x, y, z)
|
|
||||||
self.updatemodel(config)
|
self.updatemodel(config)
|
||||||
elif model.config_type == RegisterTlvs.MOBILITY.value:
|
elif model.config_type == RegisterTlvs.MOBILITY.value:
|
||||||
self.mobility = model(session=self.session, _id=self.id)
|
self.mobility = model(session=self.session, _id=self.id)
|
||||||
|
@ -1118,9 +1113,7 @@ class WlanNode(CoreNetwork):
|
||||||
)
|
)
|
||||||
self.model.update_config(config)
|
self.model.update_config(config)
|
||||||
for netif in self.netifs():
|
for netif in self.netifs():
|
||||||
if netif.poshook and netif.node:
|
netif.setposition()
|
||||||
x, y, z = netif.node.position.get()
|
|
||||||
netif.poshook(netif, x, y, z)
|
|
||||||
|
|
||||||
def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
|
def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -517,7 +517,7 @@ class Rj45Node(CoreNodeBase, CoreInterface):
|
||||||
if self.old_up:
|
if self.old_up:
|
||||||
self.net_client.device_up(self.localname)
|
self.net_client.device_up(self.localname)
|
||||||
|
|
||||||
def setposition(self, x: float = None, y: float = None, z: float = None) -> bool:
|
def setposition(self, x: float = None, y: float = None, z: float = None) -> None:
|
||||||
"""
|
"""
|
||||||
Uses setposition from both parent classes.
|
Uses setposition from both parent classes.
|
||||||
|
|
||||||
|
@ -526,9 +526,8 @@ class Rj45Node(CoreNodeBase, CoreInterface):
|
||||||
:param z: z position
|
:param z: z position
|
||||||
:return: True if position changed, False otherwise
|
:return: True if position changed, False otherwise
|
||||||
"""
|
"""
|
||||||
result = CoreNodeBase.setposition(self, x, y, z)
|
CoreNodeBase.setposition(self, x, y, z)
|
||||||
CoreInterface.setposition(self, x, y, z)
|
CoreInterface.setposition(self)
|
||||||
return result
|
|
||||||
|
|
||||||
def termcmdstring(self, sh: str) -> str:
|
def termcmdstring(self, sh: str) -> str:
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in a new issue