Merge pull request #463 from coreemu/enhancement/grpc-emane-pathloss

grpc: implemened initial support for streaming emane pathloss events
This commit is contained in:
bharnden 2020-06-03 14:51:46 -07:00 committed by GitHub
commit e74481df34
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 85 additions and 3 deletions

View file

@ -31,6 +31,8 @@ from core.api.grpc.emane_pb2 import (
EmaneLinkRequest,
EmaneLinkResponse,
EmaneModelConfig,
EmanePathlossesRequest,
EmanePathlossesResponse,
GetEmaneConfigRequest,
GetEmaneConfigResponse,
GetEmaneEventChannelRequest,
@ -1229,6 +1231,17 @@ class CoreGrpcClient:
)
return self.stub.WlanLink(request)
def emane_pathlosses(
self, pathloss_iter: Iterable[EmanePathlossesRequest]
) -> EmanePathlossesResponse:
"""
Stream EMANE pathloss events.
:param pathloss_iter: iterator for sending EMANE pathloss events
:return: EMANE pathloss response
"""
return self.stub.EmanePathlosses(pathloss_iter)
def connect(self) -> None:
"""
Open connection to server, must be closed manually.

View file

@ -2,7 +2,9 @@ import logging
import time
from typing import Any, Dict, List, Tuple, Type
import grpc
import netaddr
from grpc import ServicerContext
from core import utils
from core.api.grpc import common_pb2, core_pb2
@ -13,7 +15,7 @@ from core.emulator.data import LinkData
from core.emulator.emudata import InterfaceData, LinkOptions, NodeOptions
from core.emulator.enumerations import LinkTypes, NodeTypes
from core.emulator.session import Session
from core.nodes.base import NodeBase
from core.nodes.base import CoreNode, NodeBase
from core.nodes.interface import CoreInterface
from core.services.coreservices import CoreService
@ -478,3 +480,23 @@ def interface_to_proto(interface: CoreInterface) -> core_pb2.Interface:
ip6=ip6,
ip6mask=ip6mask,
)
def get_nem_id(node: CoreNode, netif_id: int, context: ServicerContext) -> int:
"""
Get nem id for a given node and interface id.
:param node: node to get nem id for
:param netif_id: id of interface on node to get nem id for
:param context: request context
:return: nem id
"""
netif = node.netif(netif_id)
if not netif:
message = f"{node.name} missing interface {netif_id}"
context.abort(grpc.StatusCode.NOT_FOUND, message)
net = netif.net
if not isinstance(net, EmaneNet):
message = f"{node.name} interface {netif_id} is not an EMANE network"
context.abort(grpc.StatusCode.INVALID_ARGUMENT, message)
return net.getnemid(netif)

View file

@ -6,7 +6,7 @@ import tempfile
import threading
import time
from concurrent import futures
from typing import Type
from typing import Iterable, Type
import grpc
from grpc import ServicerContext
@ -39,6 +39,8 @@ from core.api.grpc.core_pb2 import ExecuteScriptResponse
from core.api.grpc.emane_pb2 import (
EmaneLinkRequest,
EmaneLinkResponse,
EmanePathlossesRequest,
EmanePathlossesResponse,
GetEmaneConfigRequest,
GetEmaneConfigResponse,
GetEmaneEventChannelRequest,
@ -1751,3 +1753,17 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
wlan.model.sendlinkmsg(n1_netif, n2_netif, unlink=not request.linked)
result = True
return WlanLinkResponse(result=result)
def EmanePathlosses(
self,
request_iterator: Iterable[EmanePathlossesRequest],
context: ServicerContext,
) -> EmanePathlossesResponse:
for request in request_iterator:
session = self.get_session(request.session_id, context)
n1 = self.get_node(session, request.node_one, context, CoreNode)
nem1 = grpcutils.get_nem_id(n1, request.interface_one_id, context)
n2 = self.get_node(session, request.node_two, context, CoreNode)
nem2 = grpcutils.get_nem_id(n2, request.interface_two_id, context)
session.emane.publish_pathloss(nem1, nem2, request.rx_one, request.rx_two)
return EmanePathlossesResponse()

View file

@ -37,7 +37,7 @@ if TYPE_CHECKING:
from core.emulator.session import Session
try:
from emane.events import EventService
from emane.events import EventService, PathlossEvent
from emane.events import LocationEvent
from emane.events.eventserviceexception import EventServiceException
except ImportError:
@ -48,6 +48,7 @@ except ImportError:
except ImportError:
EventService = None
LocationEvent = None
PathlossEvent = None
EventServiceException = None
logging.debug("compatible emane python bindings not installed")
@ -868,6 +869,21 @@ class EmaneManager(ModelManager):
result = False
return result
def publish_pathloss(self, nem1: int, nem2: int, rx1: float, rx2: float) -> None:
"""
Publish pathloss events between provided nems, using provided rx power.
:param nem1: interface one for pathloss
:param nem2: interface two for pathloss
:param rx1: received power from nem2 to nem1
:param rx2: received power from nem1 to nem2
:return: nothing
"""
event = PathlossEvent()
event.append(nem1, forward=rx1)
event.append(nem2, forward=rx2)
self.service.publish(nem1, event)
self.service.publish(nem2, event)
class EmaneGlobalModel:
"""

View file

@ -149,6 +149,8 @@ service CoreApi {
}
rpc GetEmaneEventChannel (emane.GetEmaneEventChannelRequest) returns (emane.GetEmaneEventChannelResponse) {
}
rpc EmanePathlosses (stream emane.EmanePathlossesRequest) returns (emane.EmanePathlossesResponse) {
}
// xml rpc
rpc SaveXml (SaveXmlRequest) returns (SaveXmlResponse) {

View file

@ -90,3 +90,16 @@ message EmaneModelConfig {
string model = 3;
map<string, string> config = 4;
}
message EmanePathlossesRequest {
int32 session_id = 1;
int32 node_one = 2;
float rx_one = 3;
int32 interface_one_id = 4;
int32 node_two = 5;
float rx_two = 6;
int32 interface_two_id = 7;
}
message EmanePathlossesResponse {
}