Skip to content

Commit

Permalink
Apply AGPLv3.
Browse files Browse the repository at this point in the history
Docs.
  • Loading branch information
mutability committed May 1, 2015
1 parent b789757 commit 080eef2
Show file tree
Hide file tree
Showing 27 changed files with 1,419 additions and 19 deletions.
661 changes: 661 additions & 0 deletions COPYING

Large diffs are not rendered by default.

72 changes: 72 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# mlat-server

This is a Mode S multilateration server that is designed to operate with
clients that do _not_ have synchronized clocks.

It uses ADS-B aircraft that are transmitting DF17 extended squitter position
messages as reference beacons and uses the relative arrival times of those
messages to model the clock characteristics of each receiver.

Then it does multilateration of aircraft that are transmitting only Mode S
using the same receivers.

## License

It is important that you read this section before using or modifying the server!

The server code is licensed under the Affero GPL v3. This license is similar
to the GPL v3, but it has an additional requirement that you must provide
source code to _users who access the server over a network_.

So if you are planning to operate a copy of this server, you must release any
modifications you make to the source code to your users, even if you wouldn't
normally distribute it.

If you are not willing to distribute your changes, you have three options:

* Contact the copyright holder (Oliver) to discuss a separate license for
the server code; or
* Don't allow anyone else to connect to your server, i.e. run only your
own receivers; or
* Don't use this server as a basis for your work at all.

The server will automatically provide details of the AGPL license and a link
to the server code, to each client that connects. This is configured in
mlat/config.py. If you make modifications, the suggested process is:

* Put the modified source code somewhere public (github may be simplest).
* Update the URL configured in mlat/config.py to point to your modified code.

None of this requires that you make your server publically accessible. If you
want to run a private server with a closed user group, that's fine. But you
must still make the source code for your modified server available to your
users, and they may redistribute it further if they wish.

## Prerequisites

* Python 3.4 or later. You need the asyncio module which was introduced in 3.4.
* Numpy and Scipy
* pygraph (https://github.com/pmatiello/python-graph)
* pykalman (https://github.com/pykalman/pykalman)
* optionally, objgraph (https://mg.pov.lt/objgraph/) for leak checking

## Developer-ware

It's all poorly documented and you need to understand quite a bit of the
underlying mathematics of multilateration to make sense of it. Don't expect
to just fire this up and have it all work perfectly first time. You will have
to hack on the code.

## Running

$ mlat-server --help

## Clients

You need a bunch of receivers running mlat-client:
https://github.com/mutability/mlat-client

## Output

Results get passed back to the clients that contributed to the positions.
You can also emit all positions to a local feed, see the command-line help.
16 changes: 16 additions & 0 deletions mlat-server
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
#!/usr/bin/env python3.4
# -*- mode: python; indent-tabs-mode: nil -*-

# mlat-server: a Mode S multilateration server
# Copyright (C) 2015 Oliver Jowett <[email protected]>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import logging
import mlat.main

Expand Down
58 changes: 57 additions & 1 deletion mlat/clientio.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# -*- mode: python; indent-tabs-mode: nil -*-

# Part of mlat-server: a Mode S multilateration server
# Copyright (C) 2015 Oliver Jowett <[email protected]>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""
JSON client protocol implementation.
"""

import asyncio
import zlib
import logging
Expand All @@ -8,6 +28,8 @@
import time
import random
import socket
import inspect
import sys

import mlat.net
import mlat.util
Expand Down Expand Up @@ -354,13 +376,24 @@ def process_handshake(self, line):
self.write_raw(deny=[deny], reconnect_in=mlat.util.fuzzy(900))
return False

expanded_motd = """
{motd}
The multilateration server source code is available under
the terms of the Affero GPL (v3 or later). You may obtain
a copy of this server's source code at the following
location: {agpl_url}
""".format(agpl_url=mlat.config.AGPL_SERVER_CODE_URL,
motd=self.motd)

response = {"compress": self.compress,
"reconnect_in": mlat.util.fuzzy(15),
"selective_traffic": True,
"heartbeat": True,
"return_results": self.use_return_results,
"rate_reports": True,
"motd": self.motd}
"motd": expanded_motd}

if self.use_udp:
self._udp_key = self.udp_protocol.add_client(sync_handler=self.process_sync,
Expand Down Expand Up @@ -511,6 +544,8 @@ def process_message(self, line):
self.process_heartbeat_message(msg['heartbeat'])
elif 'rate_report' in msg:
self.process_rate_report_message(msg['rate_report'])
elif 'quine' in msg:
self.process_quine_message(msg['quine'])
else:
self.logger.info('Received an unexpected message: %s', msg)

Expand Down Expand Up @@ -543,6 +578,27 @@ def process_heartbeat_message(self, m):
def process_rate_report_message(self, m):
self.coordinator.receiver_rate_report(self.receiver, {int(k, 16): v for k, v in m.items()})

def process_quine_message(self, m):
if not m:
q = list(sys.modules.keys())
else:
_m = sys.modules.get(m)
if not _m:
q = None
elif not hasattr(_m, '__file__'):
q = '# builtin'
else:
try:
q = inspect.getsource(_m)
except OSError:
q = None
if not q:
try:
q = '# file: ' + inspect.getabsfile(_m)
except OSError:
q = '# unknown'
self.send(quine=[m, q])

# Connection interface

# For traffic management, we update the local set and schedule a task to write it out in a little while.
Expand Down
20 changes: 20 additions & 0 deletions mlat/clocknorm.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# -*- mode: python; indent-tabs-mode: nil -*-

# Part of mlat-server: a Mode S multilateration server
# Copyright (C) 2015 Oliver Jowett <[email protected]>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""
Clock normalization routines.
"""

import pygraph.classes.graph
import pygraph.algorithms.minmax

Expand Down
33 changes: 33 additions & 0 deletions mlat/clocksync.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,32 @@
# -*- mode: python; indent-tabs-mode: nil -*-

# Part of mlat-server: a Mode S multilateration server
# Copyright (C) 2015 Oliver Jowett <[email protected]>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""
Maintains clock synchronization between individual pairs of receivers.
"""

import math
import time
import bisect
import logging

__all__ = ('Clock', 'ClockPairing', 'make_clock')

glogger = logging.getLogger("clocksync")


Expand All @@ -28,6 +50,8 @@ def __init__(self, epoch, freq, max_freq_error, jitter):


def make_clock(clock_type):
"""Return a new Clock instance for the given clock type."""

if clock_type == 'radarcape_gps':
return Clock(epoch='gps_midnight', freq=1e9, max_freq_error=1e-6, jitter=15e-9)
if clock_type == 'beast':
Expand Down Expand Up @@ -214,6 +238,10 @@ def _update_offset(self, address, base_ts, peer_ts, prediction_error):
glogger.info("{r}: {a:06X}: step by {e:.1f}us".format(r=self, a=address, e=prediction_error*1e6))

def predict_peer(self, base_ts):
"""
Given a time from the base clock, predict the time of the peer clock.
"""

if self.n == 0:
return None

Expand All @@ -238,6 +266,11 @@ def predict_peer(self, base_ts):
(self.ts_base[i] - self.ts_base[i-1]))

def predict_base(self, peer_ts):
"""
Given a time from the peer clock, predict the time of the base
clock.
"""

if self.n == 0:
return None

Expand Down
23 changes: 23 additions & 0 deletions mlat/clocktrack.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
# -*- mode: python; indent-tabs-mode: nil -*-

# Part of mlat-server: a Mode S multilateration server
# Copyright (C) 2015 Oliver Jowett <[email protected]>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""
Manages the clock synchronization pairs between all receivers based on
DF17 position messages received by more than one receiver.
"""

__all__ = ('SyncPoint', 'ClockTracker')

import asyncio
import functools
import time
Expand Down
32 changes: 32 additions & 0 deletions mlat/config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,36 @@
# -*- mode: python; indent-tabs-mode: nil -*-

# Part of mlat-server: a Mode S multilateration server
# Copyright (C) 2015 Oliver Jowett <[email protected]>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""Poor man's configuration system, because I'm lazy.."""

import mlat.constants

# Location at which _this copy_ of the server code may be found. This URL will
# be sent to network clients. Remember to uncomment this after updating it.
#
# See COPYING and README.md - the AGPL requires that you make your
# modified version of the server source code available to users that interact
# with the server over a network.
#
# Please remember that this needs to be _the code that the server is running_.
#
# AGPL_SERVER_CODE_URL = "https://github.com/mutability/mlat-server"

# minimum NUCp value to accept as a sync message
MIN_NUC = 6

Expand All @@ -19,3 +48,6 @@

# maxfev (maximum function evaluations) for the solver
SOLVER_MAXFEV = 50

if 'AGPL_SERVER_CODE_URL' not in globals():
raise RuntimeError('Please update AGPL_SERVER_CODE_URL in mlat/config.py')
20 changes: 20 additions & 0 deletions mlat/connection.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# -*- mode: python; indent-tabs-mode: nil -*-

# Part of mlat-server: a Mode S multilateration server
# Copyright (C) 2015 Oliver Jowett <[email protected]>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""
Connection interface description.
"""


class Connection(object):
"""Interface for receiver connections.
Expand Down
Loading

0 comments on commit 080eef2

Please sign in to comment.