# Path: mlat/geodesy.py
# WGS84_A = 6378137.0
# WGS84_F = 1.0/298.257223563
# WGS84_B = WGS84_A * (1 - WGS84_F)
# WGS84_ECC_SQ = 1 - WGS84_B * WGS84_B / (WGS84_A * WGS84_A)
# WGS84_ECC = math.sqrt(WGS84_ECC_SQ)
# SPHERICAL_R = 6371e3
#     N = WGS84_A / math.sqrt(1 - WGS84_ECC_SQ * math.sin(lat)**2)
# def llh2ecef(llh):
# def ecef2llh(ecef):
# def greatcircle(p0, p1):
# def ecef_distance(p0, p1):
# 
# Path: mlat/profile.py
# def trackcpu(f, **kwargs):
# def dump_cpu_profiles(tofile=None):
# def trackcpu(f, name=None, **kwargs):
#     def cpu_measurement_wrapper(*args, **kwargs):
# def dump_cpu_profiles(tofile=sys.stderr):
# 
# Path: mlat/server/clocksync.py
# class Clock(object):
# class ClockPairing(object):
#     def __init__(self, epoch, freq, max_freq_error, jitter):
# def make_clock(clock_type):
#     def __init__(self, base, peer):
#     def is_new(self, base_ts):
#     def variance(self):
#     def error(self):
#     def valid(self):
#     def update(self, address, base_ts, peer_ts, base_interval, peer_interval):
#     def _prune_old_data(self, latest_base_ts):
#     def _update_drift(self, address, base_interval, peer_interval):
#     def _update_offset(self, address, base_ts, peer_ts, prediction_error):
#     def predict_peer(self, base_ts):
#     def predict_base(self, peer_ts):
#     def __str__(self):
#     KP = 0.05
#     KI = 0.01
# 
# Path: mlat/server/config.py
# MIN_NUC = 6
# MAX_RANGE = 500e3
# MAX_INTERMESSAGE_RANGE = 10e3
# MAX_ALT = 50000 * constants.FTOM
# MLAT_DELAY = 2.5
# SOLVER_MAXFEV = 50


import asyncio
import functools
import time
import logging
import modes.message
from mlat import geodesy, constants, profile
from mlat.server import clocksync, config
            return

        if abs(even_message.altitude - odd_message.altitude) > 5000:
            return

        # find global positions
        try:
            even_lat, even_lon, odd_lat, odd_lon = modes.cpr.decode(even_message.LAT,
                                                                    even_message.LON,
                                                                    odd_message.LAT,
                                                                    odd_message.LON)
        except ValueError:
            # CPR failed
            return

        # convert to ECEF, do range checks
        even_ecef = geodesy.llh2ecef((even_lat,
                                      even_lon,
                                      even_message.altitude * constants.FTOM))
        if geodesy.ecef_distance(even_ecef, receiver.position) > config.MAX_RANGE:
            logging.info("{a:06X}: receiver range check (even) failed".format(a=even_message.address))
            return

        odd_ecef = geodesy.llh2ecef((odd_lat,
                                     odd_lon,
                                     odd_message.altitude * constants.FTOM))
        if geodesy.ecef_distance(odd_ecef, receiver.position) > config.MAX_RANGE:
            logging.info("{a:06X}: receiver range check (odd) failed".format(a=odd_message.address))
            return


# Path: mlat/geodesy.py
# WGS84_A = 6378137.0
# WGS84_F = 1.0/298.257223563
# WGS84_B = WGS84_A * (1 - WGS84_F)
# WGS84_ECC_SQ = 1 - WGS84_B * WGS84_B / (WGS84_A * WGS84_A)
# WGS84_ECC = math.sqrt(WGS84_ECC_SQ)
# SPHERICAL_R = 6371e3
#     N = WGS84_A / math.sqrt(1 - WGS84_ECC_SQ * math.sin(lat)**2)
# def llh2ecef(llh):
# def ecef2llh(ecef):
# def greatcircle(p0, p1):
# def ecef_distance(p0, p1):
# 
# Path: mlat/profile.py
# def trackcpu(f, **kwargs):
# def dump_cpu_profiles(tofile=None):
# def trackcpu(f, name=None, **kwargs):
#     def cpu_measurement_wrapper(*args, **kwargs):
# def dump_cpu_profiles(tofile=sys.stderr):
# 
# Path: mlat/server/clocksync.py
# class Clock(object):
# class ClockPairing(object):
#     def __init__(self, epoch, freq, max_freq_error, jitter):
# def make_clock(clock_type):
#     def __init__(self, base, peer):
#     def is_new(self, base_ts):
#     def variance(self):
#     def error(self):
#     def valid(self):
#     def update(self, address, base_ts, peer_ts, base_interval, peer_interval):
#     def _prune_old_data(self, latest_base_ts):
#     def _update_drift(self, address, base_interval, peer_interval):
#     def _update_offset(self, address, base_ts, peer_ts, prediction_error):
#     def predict_peer(self, base_ts):
#     def predict_base(self, peer_ts):
#     def __str__(self):
#     KP = 0.05
#     KI = 0.01
# 
# Path: mlat/server/config.py
# MIN_NUC = 6
# MAX_RANGE = 500e3
# MAX_INTERMESSAGE_RANGE = 10e3
# MAX_ALT = 50000 * constants.FTOM
# MLAT_DELAY = 2.5
# SOLVER_MAXFEV = 50


# Path: mlat/server/clocktrack.py
import asyncio
import functools
import time
import logging
import modes.message
from mlat import geodesy, constants, profile
from mlat.server import clocksync, config

            return

        if abs(even_message.altitude - odd_message.altitude) > 5000:
            return

        # find global positions
        try:
            even_lat, even_lon, odd_lat, odd_lon = modes.cpr.decode(even_message.LAT,
                                                                    even_message.LON,
                                                                    odd_message.LAT,
                                                                    odd_message.LON)
        except ValueError:
            # CPR failed
            return

        # convert to ECEF, do range checks
        even_ecef = geodesy.llh2ecef((even_lat,
                                      even_lon,
                                      even_message.altitude * constants.FTOM))
        if geodesy.ecef_distance(even_ecef, receiver.position) > config.MAX_RANGE:
            logging.info("{a:06X}: receiver range check (even) failed".format(a=even_message.address))
            return

        odd_ecef = geodesy.llh2ecef((odd_lat,
                                     odd_lon,
                                     odd_message.altitude * constants.FTOM))
        if geodesy.ecef_distance(odd_ecef, receiver.position) > config.MAX_RANGE:
            logging.info("{a:06X}: receiver range check (odd) failed".format(a=odd_message.address))
            return


        if geodesy.ecef_distance(even_ecef, odd_ecef) > config.MAX_INTERMESSAGE_RANGE: