Пример #1
0
    def enrich(self, meta):
        for key in ["lat", "lon"]:
            if key in meta:
                meta[key] = float(meta[key])
        if "ourcall" in meta and "lat" in meta and "lon" in meta:
            loc = LatLngLocation(meta["lat"], meta["lon"])
            Map.getSharedInstance().updateLocation(meta["ourcall"], loc, "D-Star", self.parser.getBand())
        if "dprs" in meta:
            try:
                # we can send the DPRS stuff through our APRS parser to extract the information
                # TODO: only third-party parsing accepts this format right now
                # TODO: we also need to pass a handler, which is not needed
                parser = AprsParser(None)
                dprsData = parser.parseThirdpartyAprsData(meta["dprs"])
                if "data" in dprsData:
                    data = dprsData["data"]
                    if "lat" in data and "lon" in data:
                        # TODO: we could actually get the symbols from the parsed APRS data and show that on the meta panel
                        meta["lat"] = data["lat"]
                        meta["lon"] = data["lon"]

                        if "ourcall" in meta:
                            # send location info to map as well (it will show up with the correct symbol there!)
                            loc = AprsLocation(data)
                            Map.getSharedInstance().updateLocation(meta["ourcall"], loc, "DPRS", self.parser.getBand())
            except Exception:
                logger.exception("Error while parsing DPRS data")

        return meta
Пример #2
0
 def __init__(self, service: bool = False):
     self.parser = AprsParser()
     workers = [
         FmDemod(),
         Convert(Format.FLOAT, Format.SHORT),
         DirewolfModule(service=service),
         KissDeframer(),
         Ax25Parser(),
         self.parser,
     ]
     super().__init__(workers)
Пример #3
0
class PacketDemodulator(ServiceDemodulator, DialFrequencyReceiver):
    def __init__(self, service: bool = False):
        self.parser = AprsParser()
        workers = [
            FmDemod(),
            Convert(Format.FLOAT, Format.SHORT),
            DirewolfModule(service=service),
            KissDeframer(),
            Ax25Parser(),
            self.parser,
        ]
        super().__init__(workers)

    def supportsSquelch(self) -> bool:
        return False

    def getFixedAudioRate(self) -> int:
        return 48000

    def setDialFrequency(self, frequency: int) -> None:
        self.parser.setDialFrequency(frequency)
Пример #4
0
    def parseDprs(self, meta):
        if "dprs" in meta:
            try:
                # we can send the DPRS stuff through our APRS parser to extract the information
                # TODO: only third-party parsing accepts this format right now
                parser = AprsParser()
                dprsData = parser.parseThirdpartyAprsData(meta["dprs"])
                if "data" in dprsData:
                    data = dprsData["data"]
                    if "lat" in data and "lon" in data:
                        # TODO: we could actually get the symbols from the parsed APRS data and show that on the meta panel
                        meta["lat"] = data["lat"]
                        meta["lon"] = data["lon"]

                        if "ourcall" in meta:
                            # send location info to map as well (it will show up with the correct symbol there!)
                            loc = AprsLocation(data)
                            Map.getSharedInstance().updateLocation(meta["ourcall"], loc, "DPRS", self.parser.getBand())
            except Exception:
                logger.exception("Error while parsing DPRS data")

        return meta
Пример #5
0
 def getParser(self):
     return AprsParser(AprsHandler())
Пример #6
0
    def __init__(self, handler, sdrSource):
        self.handler = handler
        self.sdrSource = sdrSource
        self.parsers = {
            "meta": MetaParser(self.handler),
            "wsjt_demod": WsjtParser(self.handler),
            "packet_demod": AprsParser(self.handler),
            "pocsag_demod": PocsagParser(self.handler),
            "js8_demod": Js8Parser(self.handler),
        }

        self.props = PropertyStack()

        # local demodulator properties not forwarded to the sdr
        # ensure strict validation since these can be set from the client
        # and are used to build executable commands
        validators = {
            "output_rate": "int",
            "hd_output_rate": "int",
            "squelch_level": "num",
            "secondary_mod": ModulationValidator(),
            "low_cut": "num",
            "high_cut": "num",
            "offset_freq": "int",
            "mod": ModulationValidator(),
            "secondary_offset_freq": "int",
            "dmr_filter": "int",
        }
        self.localProps = PropertyValidator(
            PropertyLayer().filter(*validators.keys()), validators)

        self.props.addLayer(0, self.localProps)
        # properties that we inherit from the sdr
        self.props.addLayer(
            1,
            self.sdrSource.getProps().filter(
                "audio_compression",
                "fft_compression",
                "digimodes_fft_size",
                "csdr_dynamic_bufsize",
                "csdr_print_bufsizes",
                "csdr_through",
                "digimodes_enable",
                "samp_rate",
                "digital_voice_unvoiced_quality",
                "temporary_directory",
                "center_freq",
                "start_mod",
                "start_freq",
                "wfm_deemphasis_tau",
            ))

        self.dsp = csdr.dsp(self)
        self.dsp.nc_port = self.sdrSource.getPort()

        def set_low_cut(cut):
            bpf = self.dsp.get_bpf()
            bpf[0] = cut
            self.dsp.set_bpf(*bpf)

        def set_high_cut(cut):
            bpf = self.dsp.get_bpf()
            bpf[1] = cut
            self.dsp.set_bpf(*bpf)

        def set_dial_freq(key, value):
            if self.props["center_freq"] is None or self.props[
                    "offset_freq"] is None:
                return
            freq = self.props["center_freq"] + self.props["offset_freq"]
            for parser in self.parsers.values():
                parser.setDialFrequency(freq)

        if "start_mod" in self.props:
            self.dsp.set_demodulator(self.props["start_mod"])
            mode = Modes.findByModulation(self.props["start_mod"])

            if mode and mode.bandpass:
                self.dsp.set_bpf(mode.bandpass.low_cut, mode.bandpass.high_cut)
            else:
                self.dsp.set_bpf(-4000, 4000)

        if "start_freq" in self.props and "center_freq" in self.props:
            self.dsp.set_offset_freq(self.props["start_freq"] -
                                     self.props["center_freq"])
        else:
            self.dsp.set_offset_freq(0)

        self.subscriptions = [
            self.props.wireProperty("audio_compression",
                                    self.dsp.set_audio_compression),
            self.props.wireProperty("fft_compression",
                                    self.dsp.set_fft_compression),
            self.props.wireProperty("digimodes_fft_size",
                                    self.dsp.set_secondary_fft_size),
            self.props.wireProperty("samp_rate", self.dsp.set_samp_rate),
            self.props.wireProperty("output_rate", self.dsp.set_output_rate),
            self.props.wireProperty("hd_output_rate",
                                    self.dsp.set_hd_output_rate),
            self.props.wireProperty("offset_freq", self.dsp.set_offset_freq),
            self.props.wireProperty("center_freq", self.dsp.set_center_freq),
            self.props.wireProperty("squelch_level",
                                    self.dsp.set_squelch_level),
            self.props.wireProperty("low_cut", set_low_cut),
            self.props.wireProperty("high_cut", set_high_cut),
            self.props.wireProperty("mod", self.dsp.set_demodulator),
            self.props.wireProperty("digital_voice_unvoiced_quality",
                                    self.dsp.set_unvoiced_quality),
            self.props.wireProperty("dmr_filter", self.dsp.set_dmr_filter),
            self.props.wireProperty("temporary_directory",
                                    self.dsp.set_temporary_directory),
            self.props.wireProperty("wfm_deemphasis_tau",
                                    self.dsp.set_wfm_deemphasis_tau),
            self.props.filter("center_freq",
                              "offset_freq").wire(set_dial_freq),
        ]

        self.dsp.csdr_dynamic_bufsize = self.props["csdr_dynamic_bufsize"]
        self.dsp.csdr_print_bufsizes = self.props["csdr_print_bufsizes"]
        self.dsp.csdr_through = self.props["csdr_through"]

        if self.props["digimodes_enable"]:

            def set_secondary_mod(mod):
                if mod == False:
                    mod = None
                self.dsp.set_secondary_demodulator(mod)
                if mod is not None:
                    self.handler.write_secondary_dsp_config({
                        "secondary_fft_size":
                        self.props["digimodes_fft_size"],
                        "if_samp_rate":
                        self.dsp.if_samp_rate(),
                        "secondary_bw":
                        self.dsp.secondary_bw(),
                    })

            self.subscriptions += [
                self.props.wireProperty("secondary_mod", set_secondary_mod),
                self.props.wireProperty("secondary_offset_freq",
                                        self.dsp.set_secondary_offset_freq),
            ]

        self.startOnAvailable = False

        self.sdrSource.addClient(self)

        super().__init__()
Пример #7
0
    def __init__(self, handler, sdrSource):
        self.handler = handler
        self.sdrSource = sdrSource
        self.parsers = {
            "meta": MetaParser(self.handler),
            "wsjt_demod": WsjtParser(self.handler),
            "packet_demod": AprsParser(self.handler),
            "pocsag_demod": PocsagParser(self.handler),
        }

        self.localProps = (self.sdrSource.getProps().collect(
            "audio_compression",
            "fft_compression",
            "digimodes_fft_size",
            "csdr_dynamic_bufsize",
            "csdr_print_bufsizes",
            "csdr_through",
            "digimodes_enable",
            "samp_rate",
            "digital_voice_unvoiced_quality",
            "dmr_filter",
            "temporary_directory",
            "center_freq",
        ).defaults(PropertyManager.getSharedInstance()))

        self.dsp = csdr.dsp(self)
        self.dsp.nc_port = self.sdrSource.getPort()

        def set_low_cut(cut):
            bpf = self.dsp.get_bpf()
            bpf[0] = cut
            self.dsp.set_bpf(*bpf)

        def set_high_cut(cut):
            bpf = self.dsp.get_bpf()
            bpf[1] = cut
            self.dsp.set_bpf(*bpf)

        def set_dial_freq(key, value):
            freq = self.localProps["center_freq"] + self.localProps[
                "offset_freq"]
            for parser in self.parsers.values():
                parser.setDialFrequency(freq)

        self.subscriptions = [
            self.localProps.getProperty("audio_compression").wire(
                self.dsp.set_audio_compression),
            self.localProps.getProperty("fft_compression").wire(
                self.dsp.set_fft_compression),
            self.localProps.getProperty("digimodes_fft_size").wire(
                self.dsp.set_secondary_fft_size),
            self.localProps.getProperty("samp_rate").wire(
                self.dsp.set_samp_rate),
            self.localProps.getProperty("output_rate").wire(
                self.dsp.set_output_rate),
            self.localProps.getProperty("offset_freq").wire(
                self.dsp.set_offset_freq),
            self.localProps.getProperty("squelch_level").wire(
                self.dsp.set_squelch_level),
            self.localProps.getProperty("low_cut").wire(set_low_cut),
            self.localProps.getProperty("high_cut").wire(set_high_cut),
            self.localProps.getProperty("mod").wire(self.dsp.set_demodulator),
            self.localProps.getProperty("digital_voice_unvoiced_quality").wire(
                self.dsp.set_unvoiced_quality),
            self.localProps.getProperty("dmr_filter").wire(
                self.dsp.set_dmr_filter),
            self.localProps.getProperty("temporary_directory").wire(
                self.dsp.set_temporary_directory),
            self.localProps.collect("center_freq",
                                    "offset_freq").wire(set_dial_freq),
        ]

        self.dsp.set_offset_freq(0)
        self.dsp.set_bpf(-4000, 4000)
        self.dsp.csdr_dynamic_bufsize = self.localProps["csdr_dynamic_bufsize"]
        self.dsp.csdr_print_bufsizes = self.localProps["csdr_print_bufsizes"]
        self.dsp.csdr_through = self.localProps["csdr_through"]

        if self.localProps["digimodes_enable"]:

            def set_secondary_mod(mod):
                if mod == False:
                    mod = None
                self.dsp.set_secondary_demodulator(mod)
                if mod is not None:
                    self.handler.write_secondary_dsp_config({
                        "secondary_fft_size":
                        self.localProps["digimodes_fft_size"],
                        "if_samp_rate":
                        self.dsp.if_samp_rate(),
                        "secondary_bw":
                        self.dsp.secondary_bw(),
                    })

            self.subscriptions += [
                self.localProps.getProperty("secondary_mod").wire(
                    set_secondary_mod),
                self.localProps.getProperty("secondary_offset_freq").wire(
                    self.dsp.set_secondary_offset_freq),
            ]

        self.sdrSource.addClient(self)

        super().__init__()