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
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)
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)
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