Beispiel #1
0
    def __init__(self, stream, *args, **kwargs):
        """Constructor.

        :param stream stream: input data stream
        :param bool ubxonly (kwarg): check for non-UBX data (False (ignore - default), True (reject))
        :param int validate (kwarg): validate checksum (VALCKSUM (1)=True (default), VALNONE (0)=False)
        :param int msgmode (kwarg): message mode (0=GET (default), 1=SET, 2=POLL)
        :raises: UBXStreamError (if mode is invalid)

        """

        ubx_only = kwargs.get("ubxonly", False)
        msgmode = kwargs.get("msgmode", 0)
        validate = kwargs.get("validate", VALCKSUM)

        # accept args for backwards compatibility if no kwargs
        if len(kwargs) == 0:
            if len(args) > 0:
                ubx_only = args[0]
            if len(args) > 1:
                msgmode = args[1]

        if msgmode not in (0, 1, 2):
            raise ube.UBXStreamError(
                f"Invalid stream mode {msgmode} - must be 0, 1 or 2")

        self._stream = stream
        self._ubx_only = ubx_only
        self._validate = validate
        self._mode = msgmode
Beispiel #2
0
    def read(self) -> (bytes, UBXMessage):
        """
        Read the binary data from the stream buffer.

        :return: tuple of (raw_data as bytes, parsed_data as UBXMessage)
        :rtype: tuple
        :raises: UBXStreamError (if ubxonly=True and stream includes non-UBX data)

        """

        reading = True
        raw_data = None
        parsed_data = None

        byte1 = self._stream.read(1)  # read the first byte

        while reading:
            is_ubx = False
            is_nmea = False
            if len(byte1) < 1:  # EOF
                break
            if byte1 == b"\xb5":
                byte2 = self._stream.read(1)
                if len(byte2) < 1:  # EOF
                    break
                if byte2 == b"\x62":
                    is_ubx = True
            if is_ubx:  # it's a UBX message
                byten = self._stream.read(4)
                if len(byten) < 4:  # EOF
                    break
                clsid = byten[0:1]
                msgid = byten[1:2]
                lenb = byten[2:4]
                leni = int.from_bytes(lenb, "little", signed=False)
                byten = self._stream.read(leni + 2)
                if len(byten) < leni + 2:  # EOF
                    break
                plb = byten[0:leni]
                cksum = byten[leni:leni + 2]
                raw_data = ubt.UBX_HDR + clsid + msgid + lenb + plb + cksum
                parsed_data = self.parse(raw_data,
                                         validate=self._validate,
                                         msgmode=self._mode)
                reading = False
            else:  # it's not a UBX message (NMEA or something else)
                prevbyte = byte1
                byte1 = self._stream.read(1)
                if prevbyte == b"\x24" and byte1 in (b"\x47",
                                                     b"\x50"):  # "$G" or "$P"
                    is_nmea = True  # looks like an NMEA message
                if self._ubx_only:  # raise error and quit
                    nmeawarn = NMEAMSG if is_nmea else ""
                    raise ube.UBXStreamError(
                        f"Unknown data header {prevbyte + byte1}. {nmeawarn}")

        return (raw_data, parsed_data)
Beispiel #3
0
    def __init__(self, stream, ubx_only: bool = False, mode: int = 0):
        """Constructor.

        :param stream stream: input data stream
        :param bool ubx_only: check for non-UBX data (False (ignore - default), True (reject))
        :param int mode: message mode (0=GET (default), 1=SET, 2=POLL)
        :raises: UBXStreamError (if mode is invalid)

        """

        if mode not in (0, 1, 2):
            raise ube.UBXStreamError(
                f"Invalid stream mode {mode} - must be 0, 1 or 2")

        self._stream = stream
        self._ubx_only = ubx_only
        self._mode = mode
Beispiel #4
0
    def __init__(self, datastream, **kwargs):
        """Constructor.

        :param datastream stream: input data stream
        :param int quitonerror: (kwarg) 0 = ignore errors,  1 = log errors and continue, 2 = (re)raise errors (1)
        :param int protfilter: (kwarg) protocol filter 1 = NMEA, 2 = UBX, 4 = RTCM3 (3)
        :param int validate: (kwarg) 0 = ignore invalid checksum, 1 = validate checksum (1)
        :param int msgmode: (kwarg) 0=GET, 1=SET, 2=POLL (0)
        :param bool parsebitfield: (kwarg) 1 = parse bitfields, 0 = leave as bytes (1)
        :raises: UBXStreamError (if mode is invalid)

        """

        self._stream = datastream
        self._protfilter = int(
            kwargs.get("protfilter", ubt.NMEA_PROTOCOL | ubt.UBX_PROTOCOL))
        self._quitonerror = int(kwargs.get("quitonerror", ubt.ERR_LOG))
        self._validate = int(kwargs.get("validate", ubt.VALCKSUM))
        self._parsebf = int(kwargs.get("parsebitfield", True))
        self._msgmode = int(kwargs.get("msgmode", 0))

        if self._msgmode not in (0, 1, 2):
            raise ube.UBXStreamError(
                f"Invalid stream mode {self._msgmode} - must be 0, 1 or 2")
Beispiel #5
0
    def __init__(self, stream, *args, **kwargs):
        """Constructor.

        :param stream stream: input data stream
        :param bool ubxonly: (kwarg) check non-UBX data (False (ignore - default), True (reject))
        :param int validate: (kwarg) validate cksum (VALCKSUM (1)=True (default), VALNONE (0)=False)
        :param int msgmode: (kwarg) message mode (0=GET (default), 1=SET, 2=POLL)
        :param bool parsebitfield: (kwarg) parse bitfields True/false
        :raises: UBXStreamError (if mode is invalid)

        """

        ubx_only = kwargs.get("ubxonly", False)
        validate = kwargs.get("validate", VALCKSUM)
        parsebf = kwargs.get("parsebitfield", True)
        decodenavdata = kwargs.get("decodenavdata",
                                   True)  # TODO make default false in final
        msgmode = kwargs.get("msgmode", 0)

        # accept args for backwards compatibility if no kwargs
        if len(kwargs) == 0:
            if len(args) > 0:
                ubx_only = args[0]
            if len(args) > 1:
                msgmode = args[1]

        if msgmode not in (0, 1, 2):
            raise ube.UBXStreamError(
                f"Invalid stream mode {msgmode} - must be 0, 1 or 2")

        self._stream = stream
        self._ubx_only = ubx_only
        self._validate = validate
        self._mode = msgmode
        self._parsebf = parsebf
        self._decodenavdata = decodenavdata
Beispiel #6
0
    def read(self) -> tuple:
        """
        Read a single NMEA or UBX message from the stream buffer
        and return both raw and parsed data.

        'protfilter' determines which protocols are parsed.
        'quitonerror' determines whether to raise, log or ignore parsing errors.

        :return: tuple of (raw_data as bytes, parsed_data as UBXMessage or NMEAMessage)
        :rtype: tuple
        :raises: UBXStreamError (if unrecognised protocol in data stream)
        """

        parsing = True

        try:
            while parsing:  # loop until end of valid message or EOF
                raw_data = None
                parsed_data = None
                byte1 = self._read_bytes(1)  # read the first byte
                # if not UBX, NMEA or RTCM3, discard and continue
                if byte1 not in (b"\xb5", b"\x24", b"\xd3"):
                    continue
                byte2 = self._read_bytes(1)
                bytehdr = byte1 + byte2
                # if it's a UBX message (b'\xb5\x62')
                if bytehdr == ubt.UBX_HDR:
                    (raw_data, parsed_data) = self._parse_ubx(bytehdr)
                    # if protocol filter passes UBX, return message,
                    # otherwise discard and continue
                    if self._protfilter & ubt.UBX_PROTOCOL:
                        parsing = False
                    else:
                        continue
                # if it's an NMEA message ('$G' or '$P')
                elif bytehdr in ubt.NMEA_HDR:
                    (raw_data, parsed_data) = self._parse_nmea(bytehdr)
                    # if protocol filter passes NMEA, return message,
                    # otherwise discard and continue
                    if self._protfilter & ubt.NMEA_PROTOCOL:
                        parsing = False
                    else:
                        continue
                # if it's a RTCM3 message
                # (byte1 = 0xd3; byte2 = 0b000000**)
                elif byte1 == b"\xd3" and (byte2[0] & ~0x03) == 0:
                    (raw_data, parsed_data) = self._parse_rtcm3(bytehdr)
                    # if protocol filter passes RTCM, return message,
                    # otherwise discard and continue
                    if self._protfilter & ubt.RTCM3_PROTOCOL:
                        parsing = False
                    else:
                        continue
                # unrecognised protocol header
                else:
                    if self._quitonerror == ubt.ERR_RAISE:
                        raise ube.UBXStreamError(
                            f"Unknown protocol {bytehdr}.")
                    elif self._quitonerror == ubt.ERR_LOG:
                        return (bytehdr,
                                f"<UNKNOWN PROTOCOL(header={bytehdr})>")
                    else:  # ignore unknown protocol and continue
                        continue

        except EOFError:
            return (None, None)

        return (raw_data, parsed_data)