#!/usr/bin/env python import glob import os import sys import time import zmq import zmq.auth from aman.com import Communication_pb2 from aman.config.Server import Server from threading import Thread class ComThread(Thread): def __init__(self, com, aman): Thread.__init__(self) self.Com = com self.AMAN = aman def run(self): while True: try: msg = self.Com.Socket.recv(zmq.NOBLOCK) # parse the received message report = Communication_pb2.AircraftUpdate() report.ParseFromString(msg) # try to associate the received aircrafts to airports for inbound in report.reports: self.AMAN.updateAircraftReport(inbound) # get the sequence of the airport if None != report.airport: airport = self.AMAN.findAirport(report.airport) if None != airport: self.Com.sendSequence(report.airport, airport.inboundSequence(), airport.WeatherModel) except zmq.ZMQError as error: if zmq.EAGAIN == error.errno: time.sleep(0.1) continue else: return # @brief Receives and sends messages to EuroScope plugins class Euroscope: def __init__(self, configPath : str, config : Server, aman): self.Context = None self.Socket = None self.Thread = None self.Context = zmq.Context() # find the key directories serverKeyPath = os.path.join(os.path.join(configPath, 'keys'), 'server') if False == os.path.isdir(serverKeyPath): sys.stderr.write('No directory for the server key found') sys.exit(-1) print('Path to the server key: ' + serverKeyPath) clientKeyPath = os.path.join(os.path.join(configPath, 'keys'), 'clients') if False == os.path.isdir(clientKeyPath): sys.stderr.write('No directory for the client keys found') sys.exit(-1) print('Path to the client keys: ' + clientKeyPath) # read the certificates keyPairPath = glob.glob(os.path.join(serverKeyPath, '*.key_secret')) if 1 != len(keyPairPath): sys.stderr.write('No public-private keypair found for the server certificate') sys.exit(-1) keyPair = zmq.auth.load_certificate(keyPairPath[0]) # initialize the receiver self.Socket = zmq.Socket(self.Context, zmq.REP) self.Socket.setsockopt(zmq.CURVE_PUBLICKEY, keyPair[0]) self.Socket.setsockopt(zmq.CURVE_SECRETKEY, keyPair[1]) self.Socket.setsockopt(zmq.CURVE_SERVER, True) self.Socket.bind('tcp://' + config.Address + ':' + str(config.PortReceiver)) #self.Socket.setsockopt(zmq.SUBSCRIBE, b'') self.Thread = ComThread(self, aman) self.Thread.setDaemon(True) self.Thread.start() print('Listening to tcp://' + config.Address + ':' + str(config.PortReceiver)) def sendSequence(self, airport : str, inbounds, weather): if None == self.Socket: return sequence = Communication_pb2.AircraftSequence() sequence.airport = airport # convert the wind data if None != weather.Altitudes: for i in range(0, len(weather.Altitudes)): entry = sequence.windData.add() entry.altitude = int(weather.Altitudes[i]) entry.direction = int(weather.Directions[i]) entry.speed = int(weather.Windspeeds[i]) # convert the inbound sequence for inbound in inbounds: entry = sequence.sequence.add() entry.callsign = inbound.Callsign entry.fixed = inbound.FixedSequence if None != inbound.PlannedStar: entry.arrivalRoute = inbound.PlannedStar.Name if None != inbound.PlannedRunway: entry.arrivalRunway = inbound.PlannedRunway.Name if None != inbound.PerformanceData: entry.performance.iasAboveFL240 = int(round(inbound.PerformanceData.SpeedAboveFL240)) entry.performance.iasAboveFL100 = int(round(inbound.PerformanceData.SpeedAboveFL100)) entry.performance.iasBelowFL100 = int(round(inbound.PerformanceData.SpeedBelowFL100)) entry.performance.iasApproach = int(round(inbound.PerformanceData.SpeedApproach)) if None != inbound.PlannedArrivalRoute: for waypoint in inbound.PlannedArrivalRoute: wp = entry.waypoints.add() wp.name = waypoint.Waypoint.Name wp.altitude = int(round(waypoint.Altitude)) wp.indicatedAirspeed = int(round(waypoint.IndicatedAirspeed)) wp.groundSpeed = int(round(waypoint.GroundSpeed)) pta = str(waypoint.PTA) delimiter = pta.find('.') if -1 == delimiter: delimiter = pta.find('+') wp.pta = pta[0:delimiter] message = sequence.SerializeToString() self.Socket.send(message)