Example #1
0
    def parse(message: bytes, validate: bool = False, mode: int = 0) -> object:
        """
        Parse UBX byte stream to UBXMessage object.

        Includes option to validate incoming payload length and checksum
        (the UBXMessage constructor can calculate and assign its own values anyway).

        :param bytes message: binary message to parse
        :param bool validate: validate message length and checksum (False (default), True)
        :param int mode: message mode (0=GET (default), 1=SET, 2=POLL)
        :return: UBXMessage object
        :rtype: UBXMessage
        :raises: UBXParseError (if data stream contains invalid data or unknown message type)

        """

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

        lenm = len(message)
        hdr = message[0:2]
        clsid = message[2:3]
        msgid = message[3:4]
        lenb = message[4:6]
        if lenb == b"\x00\x00":
            payload = None
            leni = 0
        else:
            payload = message[6:lenm - 2]
            leni = len(payload)
        ckm = message[lenm - 2:lenm]
        if payload is not None:
            ckv = calc_checksum(clsid + msgid + lenb + payload)
        else:
            ckv = calc_checksum(clsid + msgid + lenb)
        if validate:
            if hdr != ubt.UBX_HDR:
                raise ube.UBXParseError((f"Invalid message header {hdr}"
                                         f" - should be {ubt.UBX_HDR}"))
            if leni != UBXMessage.bytes2val(lenb, ubt.U2):
                raise ube.UBXParseError(
                    (f"Invalid payload length {lenb}"
                     f" - should be {UBXMessage.val2bytes(leni, ubt.U2)}"))
            if ckm != ckv:
                raise ube.UBXParseError((f"Message checksum {ckm}"
                                         f" invalid - should be {ckv}"))
        try:
            if payload is None:
                return UBXMessage(clsid, msgid, mode)
            return UBXMessage(clsid, msgid, mode, payload=payload)
        except KeyError as err:
            modestr = ["GET", "SET", "POLL"][mode]
            raise ube.UBXParseError((
                f"Unknown message type clsid {clsid}, msgid {msgid}, mode {modestr}"
            )) from err
Example #2
0
    def parse(message: bytes, validate: bool = False) -> object:
        """
        Parse UBX byte stream to UBXMessage object.

        Includes option to validate incoming payload length and checksum
        (UXBMessage will calculate and assign it's own values anyway).

        :param bytes message
        :param bool validate: Default value = False
        :return UBXMessage object
        :rtype UBXMessage
        :raise UBXParseError
        """

        lenm = len(message)
        hdr = message[0:2]
        clsid = message[2:3]
        msgid = message[3:4]
        lenb = message[4:6]
        if lenb == b"\x00\x00":
            payload = None
            leni = 0
        else:
            payload = message[6:lenm - 2]
            leni = len(payload)
        ckm = message[lenm - 2:lenm]
        if payload is not None:
            ckv = UBXMessage.calc_checksum(clsid + msgid + lenb + payload)
        else:
            ckv = UBXMessage.calc_checksum(clsid + msgid + lenb)
        if validate:
            if hdr != ubt.UBX_HDR:
                raise ube.UBXParseError((f"Invalid message header {hdr}"
                                         f" - should be {ubt.UBX_HDR}"))
            if leni != UBXMessage.bytes2val(lenb, ubt.U2):
                raise ube.UBXParseError(
                    (f"Invalid payload length {lenb}"
                     f" - should be {UBXMessage.val2bytes(leni, ubt.U2)}"))
            if ckm != ckv:
                raise ube.UBXParseError((f"Message checksum {ckm}"
                                         f" invalid - should be {ckv}"))
        if payload is None:
            return UBXMessage(clsid, msgid, ubt.GET)
        return UBXMessage(clsid, msgid, ubt.GET, payload=payload)
Example #3
0
    def _parse_rtcm3(self, hdr: bytes, **kwargs) -> tuple:
        """
        Parse any RTCM3 data in the stream.
        NB: pyubx2 does not decode RTCM3 data; the
        RTCMMessage object is simply a stub.

        :param bytes hdr: first 2 bytes of RTCM3 header
        :param bool validate: (kwarg) validate crc Y/N
        :return: tuple of (raw_data as bytes, parsed_stub as RTCMMessage)
        :rtype: tuple
        """

        hdr3 = self._read_bytes(1)
        size = hdr3[0] | (hdr[1] << 8)
        payload = self._read_bytes(size)
        crc = self._read_bytes(3)
        raw_data = hdr + hdr3 + payload + crc
        if self._validate & ubt.VALCKSUM:
            if calc_crc24q(raw_data):
                raise ube.UBXParseError(
                    f"RTCM3 message invalid - failed CRC: {crc}")
        parsed_data = RTCMMessage(payload)
        return (raw_data, parsed_data)
Example #4
0
    def parse(message: bytes, *args, **kwargs) -> object:
        """
        Parse UBX byte stream to UBXMessage object.

        Includes option to validate incoming payload length and checksum
        (the UBXMessage constructor can calculate and assign its own values anyway).

        :param bytes message: binary message to parse
        :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)
        :return: UBXMessage object
        :rtype: UBXMessage
        :raises: UBXParseError (if data stream contains invalid data or unknown message type)

        """

        msgmode = kwargs.get("msgmode", ubt.GET)
        validate = kwargs.get("validate", VALCKSUM)
        parsebf = kwargs.get("parsebitfield", True)
        decnavdat = kwargs.get("deocdenavdata", False)

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

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

        lenm = len(message)
        hdr = message[0:2]
        clsid = message[2:3]
        msgid = message[3:4]
        lenb = message[4:6]
        if lenb == b"\x00\x00":
            payload = None
            leni = 0
        else:
            payload = message[6:lenm - 2]
            leni = len(payload)
        ckm = message[lenm - 2:lenm]
        if payload is not None:
            ckv = calc_checksum(clsid + msgid + lenb + payload)
        else:
            ckv = calc_checksum(clsid + msgid + lenb)
        if validate & VALCKSUM:
            if hdr != ubt.UBX_HDR:
                raise ube.UBXParseError((f"Invalid message header {hdr}"
                                         f" - should be {ubt.UBX_HDR}"))
            if leni != UBXMessage.bytes2val(lenb, ubt.U2):
                raise ube.UBXParseError(
                    (f"Invalid payload length {lenb}"
                     f" - should be {UBXMessage.val2bytes(leni, ubt.U2)}"))
            if ckm != ckv:
                raise ube.UBXParseError((f"Message checksum {ckm}"
                                         f" invalid - should be {ckv}"))
        try:
            if payload is None:
                return UBXMessage(clsid, msgid, msgmode)
            return UBXMessage(clsid,
                              msgid,
                              msgmode,
                              payload=payload,
                              parsebitfield=parsebf,
                              decodenavdata=decnavdat)
        except KeyError as err:
            modestr = ["GET", "SET", "POLL"][msgmode]
            raise ube.UBXParseError((
                f"Unknown message type clsid {clsid}, msgid {msgid}, mode {modestr}"
            )) from err