From 387d94b4cee0b75d7bb399b1d69d84501014865a Mon Sep 17 00:00:00 2001 From: Jakob Ketterl Date: Tue, 22 Aug 2023 19:59:00 +0200 Subject: [PATCH] add dump1090 demodulator (raw message only for now) --- csdr/chain/dump1090.py | 18 +++++++++++++++++ owrx/adsb/dump1090.py | 46 ++++++++++++++++++++++++++++++++++++++++++ owrx/dsp.py | 3 +++ owrx/feature.py | 4 ++++ owrx/modes.py | 8 ++++++++ 5 files changed, 79 insertions(+) diff --git a/csdr/chain/dump1090.py b/csdr/chain/dump1090.py index e69de29b..0eaf609f 100644 --- a/csdr/chain/dump1090.py +++ b/csdr/chain/dump1090.py @@ -0,0 +1,18 @@ +from pycsdr.modules import Convert +from pycsdr.types import Format +from csdr.chain.demodulator import ServiceDemodulator +from owrx.adsb.dump1090 import Dump1090Module + + +class Dump1090(ServiceDemodulator): + def __init__(self): + workers = [ + Convert(Format.COMPLEX_FLOAT, Format.COMPLEX_SHORT), + Dump1090Module() + ] + + super().__init__(workers) + pass + + def getFixedAudioRate(self) -> int: + return 2400000 diff --git a/owrx/adsb/dump1090.py b/owrx/adsb/dump1090.py index e69de29b..3032999e 100644 --- a/owrx/adsb/dump1090.py +++ b/owrx/adsb/dump1090.py @@ -0,0 +1,46 @@ +from pycsdr.modules import ExecModule, Writer, TcpSource +from pycsdr.types import Format +from csdr.module import LogWriter +from owrx.socket import getAvailablePort +import time + +import logging + +logger = logging.getLogger(__name__) + + +class Dump1090Module(ExecModule): + def __init__(self): + self.tcpSource = None + self.writer = None + self.port = getAvailablePort() + + super().__init__( + Format.COMPLEX_SHORT, + Format.CHAR, + ["dump1090", "--ifile", "-", "--iformat", "SC16", "--quiet", "--net-ro-port", str(self.port)] + ) + super().setWriter(LogWriter(__name__)) + + self.start() + + def start(self): + delay = 0.5 + retries = 0 + while True: + try: + self.tcpSource = TcpSource(self.port, Format.CHAR) + if self.writer: + self.tcpSource.setWriter(self.writer) + break + except ConnectionError: + if retries > 20: + logger.error("maximum number of connection attempts reached. did dump1090 start up correctly?") + raise + retries += 1 + time.sleep(delay) + + def setWriter(self, writer: Writer) -> None: + self.writer = writer + if self.tcpSource is not None: + self.tcpSource.setWriter(writer) diff --git a/owrx/dsp.py b/owrx/dsp.py index b112b38a..c2776672 100644 --- a/owrx/dsp.py +++ b/owrx/dsp.py @@ -612,6 +612,9 @@ class DspManager(SdrSourceEventClient, ClientDemodulatorSecondaryDspEventClient) elif mod == "rtty85": from csdr.chain.digimodes import RttyDemodulator return RttyDemodulator(50, 85, invert=True) + elif mod == "adsb": + from csdr.chain.dump1090 import Dump1090 + return Dump1090() def setSecondaryDemodulator(self, mod): demodulator = self._getSecondaryDemodulator(mod) diff --git a/owrx/feature.py b/owrx/feature.py index 036a17f8..3b8a77f7 100644 --- a/owrx/feature.py +++ b/owrx/feature.py @@ -84,6 +84,7 @@ class FeatureDetector(object): "pocsag": ["digiham"], "js8call": ["js8", "js8py"], "drm": ["dream"], + "dump1090": ["dump1090"], } def feature_availability(self): @@ -564,3 +565,6 @@ class FeatureDetector(object): except RuntimeError as e: logger.exception("Codecserver error while checking for AMBE support:") return False + + def has_dump1090(self): + return self.command_is_runnable("dump1090") diff --git a/owrx/modes.py b/owrx/modes.py index 1b262ec1..92e4b93d 100644 --- a/owrx/modes.py +++ b/owrx/modes.py @@ -149,6 +149,14 @@ class Modes(object): requirements=["pocsag"], squelch=False, ), + DigitalMode( + "adsb", + "ADS-B", + underlying=["none"], + bandpass=Bandpass(-1e6, 1e6), + requirements=["dump1090"], + squelch=False, + ), ] @staticmethod