"""
MAVLink protocol implementation (auto-generated by mavgen.py)

Generated from: ('minimal.xml',)

Note: this file has been auto-generated. DO NOT EDIT
"""
import hashlib
import json
import logging
import os
import struct
import sys
import time
from builtins import object, range
from typing import Any, Callable, Dict, Iterable, List, Mapping, Optional, Sequence, Tuple, Type, Union, cast

WIRE_PROTOCOL_VERSION = "1.0"
DIALECT = "minimal"

PROTOCOL_MARKER_V1 = 0xFE
PROTOCOL_MARKER_V2 = 0xFD
HEADER_LEN_V1 = 6
HEADER_LEN_V2 = 10

MAVLINK_SIGNATURE_BLOCK_LEN = 13

MAVLINK_IFLAG_SIGNED = 0x01

logger = logging.getLogger(__name__)

# allow MAV_IGNORE_CRC=1 to ignore CRC, allowing some
# corrupted msgs to be seen
MAVLINK_IGNORE_CRC = os.environ.get("MAV_IGNORE_CRC", 0)

# some base types from mavlink_types.h
MAVLINK_TYPE_CHAR = 0
MAVLINK_TYPE_UINT8_T = 1
MAVLINK_TYPE_INT8_T = 2
MAVLINK_TYPE_UINT16_T = 3
MAVLINK_TYPE_INT16_T = 4
MAVLINK_TYPE_UINT32_T = 5
MAVLINK_TYPE_INT32_T = 6
MAVLINK_TYPE_UINT64_T = 7
MAVLINK_TYPE_INT64_T = 8
MAVLINK_TYPE_FLOAT = 9
MAVLINK_TYPE_DOUBLE = 10


class x25crc(object):
    """CRC-16/MCRF4XX - based on checksum.h from mavlink library"""

    def __init__(self, buf: Optional[Sequence[int]] = None) -> None:
        self.crc = 0xFFFF
        if buf is not None:
            self.accumulate(buf)

    def accumulate(self, buf: Sequence[int]) -> None:
        accum = self.crc
        for b in buf:
            tmp = b ^ (accum & 0xFF)
            tmp = (tmp ^ (tmp << 4)) & 0xFF
            accum = (accum >> 8) ^ (tmp << 8) ^ (tmp << 3) ^ (tmp >> 4)
        self.crc = accum


class MAVLink_header(object):
    """MAVLink message header"""

    def __init__(self, msgId: int, incompat_flags: int = 0, compat_flags: int = 0, mlen: int = 0, seq: int = 0, srcSystem: int = 0, srcComponent: int = 0) -> None:
        self.mlen = mlen
        self.seq = seq
        self.srcSystem = srcSystem
        self.srcComponent = srcComponent
        self.msgId = msgId
        self.incompat_flags = incompat_flags
        self.compat_flags = compat_flags

    def pack(self, force_mavlink1: bool = False) -> bytes:
        if float(WIRE_PROTOCOL_VERSION) == 2.0 and not force_mavlink1:
            return struct.pack(
                "<BBBBBBBHB",
                254,
                self.mlen,
                self.incompat_flags,
                self.compat_flags,
                self.seq,
                self.srcSystem,
                self.srcComponent,
                self.msgId & 0xFFFF,
                self.msgId >> 16,
            )
        return struct.pack(
            "<BBBBBB",
            PROTOCOL_MARKER_V1,
            self.mlen,
            self.seq,
            self.srcSystem,
            self.srcComponent,
            self.msgId,
        )


class MAVLink_message(object):
    """base MAVLink message class"""

    id = 0
    msgname = ""
    fieldnames: List[str] = []
    ordered_fieldnames: List[str] = []
    fieldtypes: List[str] = []
    fielddisplays_by_name: Dict[str, str] = {}
    fieldenums_by_name: Dict[str, str] = {}
    fieldunits_by_name: Dict[str, str] = {}
    native_format = bytearray(b"")
    orders: List[int] = []
    lengths: List[int] = []
    array_lengths: List[int] = []
    crc_extra = 0
    unpacker = struct.Struct("")
    instance_field: Optional[str] = None
    instance_offset = -1

    def __init__(self, msgId: int, name: str) -> None:
        self._header = MAVLink_header(msgId)
        self._payload: Optional[bytes] = None
        self._msgbuf = bytearray(b"")
        self._crc: Optional[int] = None
        self._fieldnames: List[str] = []
        self._type = name
        self._signed = False
        self._link_id: Optional[int] = None
        self._instances: Optional[Dict[str, str]] = None
        self._instance_field: Optional[str] = None

    def format_attr(self, field: str) -> Union[str, float, int]:
        """override field getter"""
        raw_attr = cast(Union[bytes, float, int], getattr(self, field))
        if isinstance(raw_attr, bytes):
            return raw_attr.decode(errors="backslashreplace").rstrip("\x00")
        return raw_attr

    def get_msgbuf(self) -> bytearray:
        return self._msgbuf

    def get_header(self) -> MAVLink_header:
        return self._header

    def get_payload(self) -> Optional[bytes]:
        return self._payload

    def get_crc(self) -> Optional[int]:
        return self._crc

    def get_fieldnames(self) -> List[str]:
        return self._fieldnames

    def get_type(self) -> str:
        return self._type

    def get_msgId(self) -> int:
        return self._header.msgId

    def get_srcSystem(self) -> int:
        return self._header.srcSystem

    def get_srcComponent(self) -> int:
        return self._header.srcComponent

    def get_seq(self) -> int:
        return self._header.seq

    def get_signed(self) -> bool:
        return self._signed

    def get_link_id(self) -> Optional[int]:
        return self._link_id

    def __str__(self) -> str:
        ret = "%s {" % self._type
        for a in self._fieldnames:
            v = self.format_attr(a)
            ret += "%s : %s, " % (a, v)
        ret = ret[0:-2] + "}"
        return ret

    def __ne__(self, other: object) -> bool:
        return not self.__eq__(other)

    def __eq__(self, other: object) -> bool:
        if other is None:
            return False

        if not isinstance(other, MAVLink_message):
            return False

        if self.get_type() != other.get_type():
            return False

        if self.get_crc() != other.get_crc():
            return False

        if self.get_seq() != other.get_seq():
            return False

        if self.get_srcSystem() != other.get_srcSystem():
            return False

        if self.get_srcComponent() != other.get_srcComponent():
            return False

        for a in self._fieldnames:
            if self.format_attr(a) != other.format_attr(a):
                return False

        return True

    def to_dict(self) -> Dict[str, Union[str, float, int]]:
        d: Dict[str, Union[str, float, int]] = {}
        d["mavpackettype"] = self._type
        for a in self._fieldnames:
            d[a] = self.format_attr(a)
        return d

    def to_json(self) -> str:
        return json.dumps(self.to_dict())

    def sign_packet(self, mav: "MAVLink") -> None:
        assert mav.signing.secret_key is not None

        h = hashlib.new("sha256")
        self._msgbuf += struct.pack("<BQ", mav.signing.link_id, mav.signing.timestamp)[:7]
        h.update(mav.signing.secret_key)
        h.update(self._msgbuf)
        sig = h.digest()[:6]
        self._msgbuf += sig
        mav.signing.timestamp += 1

    def _pack(self, mav: "MAVLink", crc_extra: int, payload: bytes, force_mavlink1: bool = False) -> bytes:
        plen = len(payload)
        if float(WIRE_PROTOCOL_VERSION) == 2.0 and not force_mavlink1:
            # in MAVLink2 we can strip trailing zeros off payloads. This allows for simple
            # variable length arrays and smaller packets
            nullbyte = 0
            while plen > 1 and payload[plen - 1] == nullbyte:
                plen -= 1
        self._payload = payload[:plen]
        incompat_flags = 0
        if mav.signing.sign_outgoing:
            incompat_flags |= MAVLINK_IFLAG_SIGNED
        self._header = MAVLink_header(
            self._header.msgId,
            incompat_flags=incompat_flags,
            compat_flags=0,
            mlen=len(self._payload),
            seq=mav.seq,
            srcSystem=mav.srcSystem,
            srcComponent=mav.srcComponent,
        )
        self._msgbuf = bytearray(self._header.pack(force_mavlink1=force_mavlink1))
        self._msgbuf += self._payload
        crc = x25crc(self._msgbuf[1:])
        if True:
            # we are using CRC extra
            crc.accumulate(struct.pack("B", crc_extra))
        self._crc = crc.crc
        self._msgbuf += struct.pack("<H", self._crc)
        if mav.signing.sign_outgoing and not force_mavlink1:
            self.sign_packet(mav)
        return bytes(self._msgbuf)

    def pack(self, mav: "MAVLink", force_mavlink1: bool = False) -> bytes:
        raise NotImplementedError("MAVLink_message cannot be serialized directly")

    def __getitem__(self, key: str) -> str:
        """support indexing, allowing for multi-instance sensors in one message"""
        if self._instances is None:
            raise IndexError()
        if key not in self._instances:
            raise IndexError()
        return self._instances[key]


class mavlink_msg_deprecated_name_property(object):
    """
    This handles the class variable name change from name to msgname for
    subclasses of MAVLink_message during a transition period.

    This is used by setting the class variable to
    `mavlink_msg_deprecated_name_property()`.
    """

    def __get__(self, instance: Optional[MAVLink_message], owner: Type[MAVLink_message]) -> str:
        if instance is not None:
            logger.error("Using .name on a MAVLink_message is not supported, use .get_type() instead.")
            raise AttributeError("Class {} has no attribute 'name'".format(owner.__name__))
        logger.warning(
            """Using .name on a MAVLink_message class is deprecated, consider using .msgname instead.
Note that if compatibility with pymavlink 2.4.30 and earlier is desired, use something like this:

msg_name =  msg.msgname if hasattr(msg, "msgname") else msg.name"""
        )
        return owner.msgname


# enums


class EnumEntry(object):
    def __init__(self, name: str, description: str) -> None:
        self.name = name
        self.description = description
        self.param: Dict[int, str] = {}
        self.has_location = False

class Enum(Dict[int, EnumEntry]):
    def __init__(self) -> None:
        self.bitmask = False

enums: Dict[str, Enum] = {}

# MAV_AUTOPILOT
enums["MAV_AUTOPILOT"] = Enum()
enums["MAV_AUTOPILOT"].bitmask = False
MAV_AUTOPILOT_GENERIC = 0
enums["MAV_AUTOPILOT"][0] = EnumEntry("MAV_AUTOPILOT_GENERIC", """Generic autopilot, full support for everything""")
MAV_AUTOPILOT_RESERVED = 1
enums["MAV_AUTOPILOT"][1] = EnumEntry("MAV_AUTOPILOT_RESERVED", """Reserved for future use.""")
MAV_AUTOPILOT_SLUGS = 2
enums["MAV_AUTOPILOT"][2] = EnumEntry("MAV_AUTOPILOT_SLUGS", """SLUGS autopilot, http://slugsuav.soe.ucsc.edu""")
MAV_AUTOPILOT_ARDUPILOTMEGA = 3
enums["MAV_AUTOPILOT"][3] = EnumEntry("MAV_AUTOPILOT_ARDUPILOTMEGA", """ArduPilot - Plane/Copter/Rover/Sub/Tracker, https://ardupilot.org""")
MAV_AUTOPILOT_OPENPILOT = 4
enums["MAV_AUTOPILOT"][4] = EnumEntry("MAV_AUTOPILOT_OPENPILOT", """OpenPilot, http://openpilot.org""")
MAV_AUTOPILOT_GENERIC_WAYPOINTS_ONLY = 5
enums["MAV_AUTOPILOT"][5] = EnumEntry("MAV_AUTOPILOT_GENERIC_WAYPOINTS_ONLY", """Generic autopilot only supporting simple waypoints""")
MAV_AUTOPILOT_GENERIC_WAYPOINTS_AND_SIMPLE_NAVIGATION_ONLY = 6
enums["MAV_AUTOPILOT"][6] = EnumEntry("MAV_AUTOPILOT_GENERIC_WAYPOINTS_AND_SIMPLE_NAVIGATION_ONLY", """Generic autopilot supporting waypoints and other simple navigation commands""")
MAV_AUTOPILOT_GENERIC_MISSION_FULL = 7
enums["MAV_AUTOPILOT"][7] = EnumEntry("MAV_AUTOPILOT_GENERIC_MISSION_FULL", """Generic autopilot supporting the full mission command set""")
MAV_AUTOPILOT_INVALID = 8
enums["MAV_AUTOPILOT"][8] = EnumEntry("MAV_AUTOPILOT_INVALID", """No valid autopilot, e.g. a GCS or other MAVLink component""")
MAV_AUTOPILOT_PPZ = 9
enums["MAV_AUTOPILOT"][9] = EnumEntry("MAV_AUTOPILOT_PPZ", """PPZ UAV - http://nongnu.org/paparazzi""")
MAV_AUTOPILOT_UDB = 10
enums["MAV_AUTOPILOT"][10] = EnumEntry("MAV_AUTOPILOT_UDB", """UAV Dev Board""")
MAV_AUTOPILOT_FP = 11
enums["MAV_AUTOPILOT"][11] = EnumEntry("MAV_AUTOPILOT_FP", """FlexiPilot""")
MAV_AUTOPILOT_PX4 = 12
enums["MAV_AUTOPILOT"][12] = EnumEntry("MAV_AUTOPILOT_PX4", """PX4 Autopilot - http://px4.io/""")
MAV_AUTOPILOT_SMACCMPILOT = 13
enums["MAV_AUTOPILOT"][13] = EnumEntry("MAV_AUTOPILOT_SMACCMPILOT", """SMACCMPilot - http://smaccmpilot.org""")
MAV_AUTOPILOT_AUTOQUAD = 14
enums["MAV_AUTOPILOT"][14] = EnumEntry("MAV_AUTOPILOT_AUTOQUAD", """AutoQuad -- http://autoquad.org""")
MAV_AUTOPILOT_ARMAZILA = 15
enums["MAV_AUTOPILOT"][15] = EnumEntry("MAV_AUTOPILOT_ARMAZILA", """Armazila -- http://armazila.com""")
MAV_AUTOPILOT_AEROB = 16
enums["MAV_AUTOPILOT"][16] = EnumEntry("MAV_AUTOPILOT_AEROB", """Aerob -- http://aerob.ru""")
MAV_AUTOPILOT_ASLUAV = 17
enums["MAV_AUTOPILOT"][17] = EnumEntry("MAV_AUTOPILOT_ASLUAV", """ASLUAV autopilot -- http://www.asl.ethz.ch""")
MAV_AUTOPILOT_SMARTAP = 18
enums["MAV_AUTOPILOT"][18] = EnumEntry("MAV_AUTOPILOT_SMARTAP", """SmartAP Autopilot - http://sky-drones.com""")
MAV_AUTOPILOT_AIRRAILS = 19
enums["MAV_AUTOPILOT"][19] = EnumEntry("MAV_AUTOPILOT_AIRRAILS", """AirRails - http://uaventure.com""")
MAV_AUTOPILOT_REFLEX = 20
enums["MAV_AUTOPILOT"][20] = EnumEntry("MAV_AUTOPILOT_REFLEX", """Fusion Reflex - https://fusion.engineering""")
MAV_AUTOPILOT_ENUM_END = 21
enums["MAV_AUTOPILOT"][21] = EnumEntry("MAV_AUTOPILOT_ENUM_END", """""")

# MAV_TYPE
enums["MAV_TYPE"] = Enum()
enums["MAV_TYPE"].bitmask = False
MAV_TYPE_GENERIC = 0
enums["MAV_TYPE"][0] = EnumEntry("MAV_TYPE_GENERIC", """Generic micro air vehicle""")
MAV_TYPE_FIXED_WING = 1
enums["MAV_TYPE"][1] = EnumEntry("MAV_TYPE_FIXED_WING", """Fixed wing aircraft.""")
MAV_TYPE_QUADROTOR = 2
enums["MAV_TYPE"][2] = EnumEntry("MAV_TYPE_QUADROTOR", """Quadrotor""")
MAV_TYPE_COAXIAL = 3
enums["MAV_TYPE"][3] = EnumEntry("MAV_TYPE_COAXIAL", """Coaxial helicopter""")
MAV_TYPE_HELICOPTER = 4
enums["MAV_TYPE"][4] = EnumEntry("MAV_TYPE_HELICOPTER", """Normal helicopter with tail rotor.""")
MAV_TYPE_ANTENNA_TRACKER = 5
enums["MAV_TYPE"][5] = EnumEntry("MAV_TYPE_ANTENNA_TRACKER", """Ground installation""")
MAV_TYPE_GCS = 6
enums["MAV_TYPE"][6] = EnumEntry("MAV_TYPE_GCS", """Operator control unit / ground control station""")
MAV_TYPE_AIRSHIP = 7
enums["MAV_TYPE"][7] = EnumEntry("MAV_TYPE_AIRSHIP", """Airship, controlled""")
MAV_TYPE_FREE_BALLOON = 8
enums["MAV_TYPE"][8] = EnumEntry("MAV_TYPE_FREE_BALLOON", """Free balloon, uncontrolled""")
MAV_TYPE_ROCKET = 9
enums["MAV_TYPE"][9] = EnumEntry("MAV_TYPE_ROCKET", """Rocket""")
MAV_TYPE_GROUND_ROVER = 10
enums["MAV_TYPE"][10] = EnumEntry("MAV_TYPE_GROUND_ROVER", """Ground rover""")
MAV_TYPE_SURFACE_BOAT = 11
enums["MAV_TYPE"][11] = EnumEntry("MAV_TYPE_SURFACE_BOAT", """Surface vessel, boat, ship""")
MAV_TYPE_SUBMARINE = 12
enums["MAV_TYPE"][12] = EnumEntry("MAV_TYPE_SUBMARINE", """Submarine""")
MAV_TYPE_HEXAROTOR = 13
enums["MAV_TYPE"][13] = EnumEntry("MAV_TYPE_HEXAROTOR", """Hexarotor""")
MAV_TYPE_OCTOROTOR = 14
enums["MAV_TYPE"][14] = EnumEntry("MAV_TYPE_OCTOROTOR", """Octorotor""")
MAV_TYPE_TRICOPTER = 15
enums["MAV_TYPE"][15] = EnumEntry("MAV_TYPE_TRICOPTER", """Tricopter""")
MAV_TYPE_FLAPPING_WING = 16
enums["MAV_TYPE"][16] = EnumEntry("MAV_TYPE_FLAPPING_WING", """Flapping wing""")
MAV_TYPE_KITE = 17
enums["MAV_TYPE"][17] = EnumEntry("MAV_TYPE_KITE", """Kite""")
MAV_TYPE_ONBOARD_CONTROLLER = 18
enums["MAV_TYPE"][18] = EnumEntry("MAV_TYPE_ONBOARD_CONTROLLER", """Onboard companion controller""")
MAV_TYPE_VTOL_TAILSITTER_DUOROTOR = 19
enums["MAV_TYPE"][19] = EnumEntry("MAV_TYPE_VTOL_TAILSITTER_DUOROTOR", """Two-rotor Tailsitter VTOL that additionally uses control surfaces in vertical operation. Note, value previously named MAV_TYPE_VTOL_DUOROTOR.""")
MAV_TYPE_VTOL_TAILSITTER_QUADROTOR = 20
enums["MAV_TYPE"][20] = EnumEntry("MAV_TYPE_VTOL_TAILSITTER_QUADROTOR", """Quad-rotor Tailsitter VTOL using a V-shaped quad config in vertical operation. Note: value previously named MAV_TYPE_VTOL_QUADROTOR.""")
MAV_TYPE_VTOL_TILTROTOR = 21
enums["MAV_TYPE"][21] = EnumEntry("MAV_TYPE_VTOL_TILTROTOR", """Tiltrotor VTOL. Fuselage and wings stay (nominally) horizontal in all flight phases. It able to tilt (some) rotors to provide thrust in cruise flight.""")
MAV_TYPE_VTOL_FIXEDROTOR = 22
enums["MAV_TYPE"][22] = EnumEntry("MAV_TYPE_VTOL_FIXEDROTOR", """VTOL with separate fixed rotors for hover and cruise flight. Fuselage and wings stay (nominally) horizontal in all flight phases.""")
MAV_TYPE_VTOL_TAILSITTER = 23
enums["MAV_TYPE"][23] = EnumEntry("MAV_TYPE_VTOL_TAILSITTER", """Tailsitter VTOL. Fuselage and wings orientation changes depending on flight phase: vertical for hover, horizontal for cruise. Use more specific VTOL MAV_TYPE_VTOL_DUOROTOR or MAV_TYPE_VTOL_QUADROTOR if appropriate.""")
MAV_TYPE_VTOL_TILTWING = 24
enums["MAV_TYPE"][24] = EnumEntry("MAV_TYPE_VTOL_TILTWING", """Tiltwing VTOL. Fuselage stays horizontal in all flight phases. The whole wing, along with any attached engine, can tilt between vertical and horizontal mode.""")
MAV_TYPE_VTOL_RESERVED5 = 25
enums["MAV_TYPE"][25] = EnumEntry("MAV_TYPE_VTOL_RESERVED5", """VTOL reserved 5""")
MAV_TYPE_GIMBAL = 26
enums["MAV_TYPE"][26] = EnumEntry("MAV_TYPE_GIMBAL", """Gimbal""")
MAV_TYPE_ADSB = 27
enums["MAV_TYPE"][27] = EnumEntry("MAV_TYPE_ADSB", """ADSB system""")
MAV_TYPE_PARAFOIL = 28
enums["MAV_TYPE"][28] = EnumEntry("MAV_TYPE_PARAFOIL", """Steerable, nonrigid airfoil""")
MAV_TYPE_DODECAROTOR = 29
enums["MAV_TYPE"][29] = EnumEntry("MAV_TYPE_DODECAROTOR", """Dodecarotor""")
MAV_TYPE_CAMERA = 30
enums["MAV_TYPE"][30] = EnumEntry("MAV_TYPE_CAMERA", """Camera""")
MAV_TYPE_CHARGING_STATION = 31
enums["MAV_TYPE"][31] = EnumEntry("MAV_TYPE_CHARGING_STATION", """Charging station""")
MAV_TYPE_FLARM = 32
enums["MAV_TYPE"][32] = EnumEntry("MAV_TYPE_FLARM", """FLARM collision avoidance system""")
MAV_TYPE_SERVO = 33
enums["MAV_TYPE"][33] = EnumEntry("MAV_TYPE_SERVO", """Servo""")
MAV_TYPE_ODID = 34
enums["MAV_TYPE"][34] = EnumEntry("MAV_TYPE_ODID", """Open Drone ID. See https://mavlink.io/en/services/opendroneid.html.""")
MAV_TYPE_DECAROTOR = 35
enums["MAV_TYPE"][35] = EnumEntry("MAV_TYPE_DECAROTOR", """Decarotor""")
MAV_TYPE_BATTERY = 36
enums["MAV_TYPE"][36] = EnumEntry("MAV_TYPE_BATTERY", """Battery""")
MAV_TYPE_PARACHUTE = 37
enums["MAV_TYPE"][37] = EnumEntry("MAV_TYPE_PARACHUTE", """Parachute""")
MAV_TYPE_LOG = 38
enums["MAV_TYPE"][38] = EnumEntry("MAV_TYPE_LOG", """Log""")
MAV_TYPE_OSD = 39
enums["MAV_TYPE"][39] = EnumEntry("MAV_TYPE_OSD", """OSD""")
MAV_TYPE_IMU = 40
enums["MAV_TYPE"][40] = EnumEntry("MAV_TYPE_IMU", """IMU""")
MAV_TYPE_GPS = 41
enums["MAV_TYPE"][41] = EnumEntry("MAV_TYPE_GPS", """GPS""")
MAV_TYPE_WINCH = 42
enums["MAV_TYPE"][42] = EnumEntry("MAV_TYPE_WINCH", """Winch""")
MAV_TYPE_ENUM_END = 43
enums["MAV_TYPE"][43] = EnumEntry("MAV_TYPE_ENUM_END", """""")

# MAV_MODE_FLAG
enums["MAV_MODE_FLAG"] = Enum()
enums["MAV_MODE_FLAG"].bitmask = True
MAV_MODE_FLAG_CUSTOM_MODE_ENABLED = 1
enums["MAV_MODE_FLAG"][1] = EnumEntry("MAV_MODE_FLAG_CUSTOM_MODE_ENABLED", """0b00000001 Reserved for future use.""")
MAV_MODE_FLAG_TEST_ENABLED = 2
enums["MAV_MODE_FLAG"][2] = EnumEntry("MAV_MODE_FLAG_TEST_ENABLED", """0b00000010 system has a test mode enabled. This flag is intended for temporary system tests and should not be used for stable implementations.""")
MAV_MODE_FLAG_AUTO_ENABLED = 4
enums["MAV_MODE_FLAG"][4] = EnumEntry("MAV_MODE_FLAG_AUTO_ENABLED", """0b00000100 autonomous mode enabled, system finds its own goal positions. Guided flag can be set or not, depends on the actual implementation.""")
MAV_MODE_FLAG_GUIDED_ENABLED = 8
enums["MAV_MODE_FLAG"][8] = EnumEntry("MAV_MODE_FLAG_GUIDED_ENABLED", """0b00001000 guided mode enabled, system flies waypoints / mission items.""")
MAV_MODE_FLAG_STABILIZE_ENABLED = 16
enums["MAV_MODE_FLAG"][16] = EnumEntry("MAV_MODE_FLAG_STABILIZE_ENABLED", """0b00010000 system stabilizes electronically its attitude (and optionally position). It needs however further control inputs to move around.""")
MAV_MODE_FLAG_HIL_ENABLED = 32
enums["MAV_MODE_FLAG"][32] = EnumEntry("MAV_MODE_FLAG_HIL_ENABLED", """0b00100000 hardware in the loop simulation. All motors / actuators are blocked, but internal software is full operational.""")
MAV_MODE_FLAG_MANUAL_INPUT_ENABLED = 64
enums["MAV_MODE_FLAG"][64] = EnumEntry("MAV_MODE_FLAG_MANUAL_INPUT_ENABLED", """0b01000000 remote control input is enabled.""")
MAV_MODE_FLAG_SAFETY_ARMED = 128
enums["MAV_MODE_FLAG"][128] = EnumEntry("MAV_MODE_FLAG_SAFETY_ARMED", """0b10000000 MAV safety set to armed. Motors are enabled / running / can start. Ready to fly. Additional note: this flag is to be ignore when sent in the command MAV_CMD_DO_SET_MODE and MAV_CMD_COMPONENT_ARM_DISARM shall be used instead. The flag can still be used to report the armed state.""")
MAV_MODE_FLAG_ENUM_END = 129
enums["MAV_MODE_FLAG"][129] = EnumEntry("MAV_MODE_FLAG_ENUM_END", """""")

# MAV_MODE_FLAG_DECODE_POSITION
enums["MAV_MODE_FLAG_DECODE_POSITION"] = Enum()
enums["MAV_MODE_FLAG_DECODE_POSITION"].bitmask = True
MAV_MODE_FLAG_DECODE_POSITION_CUSTOM_MODE = 1
enums["MAV_MODE_FLAG_DECODE_POSITION"][1] = EnumEntry("MAV_MODE_FLAG_DECODE_POSITION_CUSTOM_MODE", """Eighth bit: 00000001""")
MAV_MODE_FLAG_DECODE_POSITION_TEST = 2
enums["MAV_MODE_FLAG_DECODE_POSITION"][2] = EnumEntry("MAV_MODE_FLAG_DECODE_POSITION_TEST", """Seventh bit: 00000010""")
MAV_MODE_FLAG_DECODE_POSITION_AUTO = 4
enums["MAV_MODE_FLAG_DECODE_POSITION"][4] = EnumEntry("MAV_MODE_FLAG_DECODE_POSITION_AUTO", """Sixth bit:   00000100""")
MAV_MODE_FLAG_DECODE_POSITION_GUIDED = 8
enums["MAV_MODE_FLAG_DECODE_POSITION"][8] = EnumEntry("MAV_MODE_FLAG_DECODE_POSITION_GUIDED", """Fifth bit:  00001000""")
MAV_MODE_FLAG_DECODE_POSITION_STABILIZE = 16
enums["MAV_MODE_FLAG_DECODE_POSITION"][16] = EnumEntry("MAV_MODE_FLAG_DECODE_POSITION_STABILIZE", """Fourth bit: 00010000""")
MAV_MODE_FLAG_DECODE_POSITION_HIL = 32
enums["MAV_MODE_FLAG_DECODE_POSITION"][32] = EnumEntry("MAV_MODE_FLAG_DECODE_POSITION_HIL", """Third bit:  00100000""")
MAV_MODE_FLAG_DECODE_POSITION_MANUAL = 64
enums["MAV_MODE_FLAG_DECODE_POSITION"][64] = EnumEntry("MAV_MODE_FLAG_DECODE_POSITION_MANUAL", """Second bit: 01000000""")
MAV_MODE_FLAG_DECODE_POSITION_SAFETY = 128
enums["MAV_MODE_FLAG_DECODE_POSITION"][128] = EnumEntry("MAV_MODE_FLAG_DECODE_POSITION_SAFETY", """First bit:  10000000""")
MAV_MODE_FLAG_DECODE_POSITION_ENUM_END = 129
enums["MAV_MODE_FLAG_DECODE_POSITION"][129] = EnumEntry("MAV_MODE_FLAG_DECODE_POSITION_ENUM_END", """""")

# MAV_STATE
enums["MAV_STATE"] = Enum()
enums["MAV_STATE"].bitmask = False
MAV_STATE_UNINIT = 0
enums["MAV_STATE"][0] = EnumEntry("MAV_STATE_UNINIT", """Uninitialized system, state is unknown.""")
MAV_STATE_BOOT = 1
enums["MAV_STATE"][1] = EnumEntry("MAV_STATE_BOOT", """System is booting up.""")
MAV_STATE_CALIBRATING = 2
enums["MAV_STATE"][2] = EnumEntry("MAV_STATE_CALIBRATING", """System is calibrating and not flight-ready.""")
MAV_STATE_STANDBY = 3
enums["MAV_STATE"][3] = EnumEntry("MAV_STATE_STANDBY", """System is grounded and on standby. It can be launched any time.""")
MAV_STATE_ACTIVE = 4
enums["MAV_STATE"][4] = EnumEntry("MAV_STATE_ACTIVE", """System is active and might be already airborne. Motors are engaged.""")
MAV_STATE_CRITICAL = 5
enums["MAV_STATE"][5] = EnumEntry("MAV_STATE_CRITICAL", """System is in a non-normal flight mode. It can however still navigate.""")
MAV_STATE_EMERGENCY = 6
enums["MAV_STATE"][6] = EnumEntry("MAV_STATE_EMERGENCY", """System is in a non-normal flight mode. It lost control over parts or over the whole airframe. It is in mayday and going down.""")
MAV_STATE_POWEROFF = 7
enums["MAV_STATE"][7] = EnumEntry("MAV_STATE_POWEROFF", """System just initialized its power-down sequence, will shut down now.""")
MAV_STATE_FLIGHT_TERMINATION = 8
enums["MAV_STATE"][8] = EnumEntry("MAV_STATE_FLIGHT_TERMINATION", """System is terminating itself.""")
MAV_STATE_ENUM_END = 9
enums["MAV_STATE"][9] = EnumEntry("MAV_STATE_ENUM_END", """""")

# MAV_COMPONENT
enums["MAV_COMPONENT"] = Enum()
enums["MAV_COMPONENT"].bitmask = False
MAV_COMP_ID_ALL = 0
enums["MAV_COMPONENT"][0] = EnumEntry("MAV_COMP_ID_ALL", """Target id (target_component) used to broadcast messages to all components of the receiving system. Components should attempt to process messages with this component ID and forward to components on any other interfaces. Note: This is not a valid *source* component id for a message.""")
MAV_COMP_ID_AUTOPILOT1 = 1
enums["MAV_COMPONENT"][1] = EnumEntry("MAV_COMP_ID_AUTOPILOT1", """System flight controller component ("autopilot"). Only one autopilot is expected in a particular system.""")
MAV_COMP_ID_USER1 = 25
enums["MAV_COMPONENT"][25] = EnumEntry("MAV_COMP_ID_USER1", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER2 = 26
enums["MAV_COMPONENT"][26] = EnumEntry("MAV_COMP_ID_USER2", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER3 = 27
enums["MAV_COMPONENT"][27] = EnumEntry("MAV_COMP_ID_USER3", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER4 = 28
enums["MAV_COMPONENT"][28] = EnumEntry("MAV_COMP_ID_USER4", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER5 = 29
enums["MAV_COMPONENT"][29] = EnumEntry("MAV_COMP_ID_USER5", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER6 = 30
enums["MAV_COMPONENT"][30] = EnumEntry("MAV_COMP_ID_USER6", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER7 = 31
enums["MAV_COMPONENT"][31] = EnumEntry("MAV_COMP_ID_USER7", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER8 = 32
enums["MAV_COMPONENT"][32] = EnumEntry("MAV_COMP_ID_USER8", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER9 = 33
enums["MAV_COMPONENT"][33] = EnumEntry("MAV_COMP_ID_USER9", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER10 = 34
enums["MAV_COMPONENT"][34] = EnumEntry("MAV_COMP_ID_USER10", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER11 = 35
enums["MAV_COMPONENT"][35] = EnumEntry("MAV_COMP_ID_USER11", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER12 = 36
enums["MAV_COMPONENT"][36] = EnumEntry("MAV_COMP_ID_USER12", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER13 = 37
enums["MAV_COMPONENT"][37] = EnumEntry("MAV_COMP_ID_USER13", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER14 = 38
enums["MAV_COMPONENT"][38] = EnumEntry("MAV_COMP_ID_USER14", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER15 = 39
enums["MAV_COMPONENT"][39] = EnumEntry("MAV_COMP_ID_USER15", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER16 = 40
enums["MAV_COMPONENT"][40] = EnumEntry("MAV_COMP_ID_USER16", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER17 = 41
enums["MAV_COMPONENT"][41] = EnumEntry("MAV_COMP_ID_USER17", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER18 = 42
enums["MAV_COMPONENT"][42] = EnumEntry("MAV_COMP_ID_USER18", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER19 = 43
enums["MAV_COMPONENT"][43] = EnumEntry("MAV_COMP_ID_USER19", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER20 = 44
enums["MAV_COMPONENT"][44] = EnumEntry("MAV_COMP_ID_USER20", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER21 = 45
enums["MAV_COMPONENT"][45] = EnumEntry("MAV_COMP_ID_USER21", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER22 = 46
enums["MAV_COMPONENT"][46] = EnumEntry("MAV_COMP_ID_USER22", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER23 = 47
enums["MAV_COMPONENT"][47] = EnumEntry("MAV_COMP_ID_USER23", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER24 = 48
enums["MAV_COMPONENT"][48] = EnumEntry("MAV_COMP_ID_USER24", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER25 = 49
enums["MAV_COMPONENT"][49] = EnumEntry("MAV_COMP_ID_USER25", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER26 = 50
enums["MAV_COMPONENT"][50] = EnumEntry("MAV_COMP_ID_USER26", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER27 = 51
enums["MAV_COMPONENT"][51] = EnumEntry("MAV_COMP_ID_USER27", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER28 = 52
enums["MAV_COMPONENT"][52] = EnumEntry("MAV_COMP_ID_USER28", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER29 = 53
enums["MAV_COMPONENT"][53] = EnumEntry("MAV_COMP_ID_USER29", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER30 = 54
enums["MAV_COMPONENT"][54] = EnumEntry("MAV_COMP_ID_USER30", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER31 = 55
enums["MAV_COMPONENT"][55] = EnumEntry("MAV_COMP_ID_USER31", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER32 = 56
enums["MAV_COMPONENT"][56] = EnumEntry("MAV_COMP_ID_USER32", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER33 = 57
enums["MAV_COMPONENT"][57] = EnumEntry("MAV_COMP_ID_USER33", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER34 = 58
enums["MAV_COMPONENT"][58] = EnumEntry("MAV_COMP_ID_USER34", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER35 = 59
enums["MAV_COMPONENT"][59] = EnumEntry("MAV_COMP_ID_USER35", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER36 = 60
enums["MAV_COMPONENT"][60] = EnumEntry("MAV_COMP_ID_USER36", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER37 = 61
enums["MAV_COMPONENT"][61] = EnumEntry("MAV_COMP_ID_USER37", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER38 = 62
enums["MAV_COMPONENT"][62] = EnumEntry("MAV_COMP_ID_USER38", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER39 = 63
enums["MAV_COMPONENT"][63] = EnumEntry("MAV_COMP_ID_USER39", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER40 = 64
enums["MAV_COMPONENT"][64] = EnumEntry("MAV_COMP_ID_USER40", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER41 = 65
enums["MAV_COMPONENT"][65] = EnumEntry("MAV_COMP_ID_USER41", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER42 = 66
enums["MAV_COMPONENT"][66] = EnumEntry("MAV_COMP_ID_USER42", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER43 = 67
enums["MAV_COMPONENT"][67] = EnumEntry("MAV_COMP_ID_USER43", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_TELEMETRY_RADIO = 68
enums["MAV_COMPONENT"][68] = EnumEntry("MAV_COMP_ID_TELEMETRY_RADIO", """Telemetry radio (e.g. SiK radio, or other component that emits RADIO_STATUS messages).""")
MAV_COMP_ID_USER45 = 69
enums["MAV_COMPONENT"][69] = EnumEntry("MAV_COMP_ID_USER45", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER46 = 70
enums["MAV_COMPONENT"][70] = EnumEntry("MAV_COMP_ID_USER46", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER47 = 71
enums["MAV_COMPONENT"][71] = EnumEntry("MAV_COMP_ID_USER47", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER48 = 72
enums["MAV_COMPONENT"][72] = EnumEntry("MAV_COMP_ID_USER48", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER49 = 73
enums["MAV_COMPONENT"][73] = EnumEntry("MAV_COMP_ID_USER49", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER50 = 74
enums["MAV_COMPONENT"][74] = EnumEntry("MAV_COMP_ID_USER50", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER51 = 75
enums["MAV_COMPONENT"][75] = EnumEntry("MAV_COMP_ID_USER51", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER52 = 76
enums["MAV_COMPONENT"][76] = EnumEntry("MAV_COMP_ID_USER52", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER53 = 77
enums["MAV_COMPONENT"][77] = EnumEntry("MAV_COMP_ID_USER53", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER54 = 78
enums["MAV_COMPONENT"][78] = EnumEntry("MAV_COMP_ID_USER54", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER55 = 79
enums["MAV_COMPONENT"][79] = EnumEntry("MAV_COMP_ID_USER55", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER56 = 80
enums["MAV_COMPONENT"][80] = EnumEntry("MAV_COMP_ID_USER56", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER57 = 81
enums["MAV_COMPONENT"][81] = EnumEntry("MAV_COMP_ID_USER57", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER58 = 82
enums["MAV_COMPONENT"][82] = EnumEntry("MAV_COMP_ID_USER58", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER59 = 83
enums["MAV_COMPONENT"][83] = EnumEntry("MAV_COMP_ID_USER59", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER60 = 84
enums["MAV_COMPONENT"][84] = EnumEntry("MAV_COMP_ID_USER60", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER61 = 85
enums["MAV_COMPONENT"][85] = EnumEntry("MAV_COMP_ID_USER61", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER62 = 86
enums["MAV_COMPONENT"][86] = EnumEntry("MAV_COMP_ID_USER62", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER63 = 87
enums["MAV_COMPONENT"][87] = EnumEntry("MAV_COMP_ID_USER63", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER64 = 88
enums["MAV_COMPONENT"][88] = EnumEntry("MAV_COMP_ID_USER64", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER65 = 89
enums["MAV_COMPONENT"][89] = EnumEntry("MAV_COMP_ID_USER65", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER66 = 90
enums["MAV_COMPONENT"][90] = EnumEntry("MAV_COMP_ID_USER66", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER67 = 91
enums["MAV_COMPONENT"][91] = EnumEntry("MAV_COMP_ID_USER67", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER68 = 92
enums["MAV_COMPONENT"][92] = EnumEntry("MAV_COMP_ID_USER68", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER69 = 93
enums["MAV_COMPONENT"][93] = EnumEntry("MAV_COMP_ID_USER69", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER70 = 94
enums["MAV_COMPONENT"][94] = EnumEntry("MAV_COMP_ID_USER70", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER71 = 95
enums["MAV_COMPONENT"][95] = EnumEntry("MAV_COMP_ID_USER71", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER72 = 96
enums["MAV_COMPONENT"][96] = EnumEntry("MAV_COMP_ID_USER72", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER73 = 97
enums["MAV_COMPONENT"][97] = EnumEntry("MAV_COMP_ID_USER73", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER74 = 98
enums["MAV_COMPONENT"][98] = EnumEntry("MAV_COMP_ID_USER74", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_USER75 = 99
enums["MAV_COMPONENT"][99] = EnumEntry("MAV_COMP_ID_USER75", """Id for a component on privately managed MAVLink network. Can be used for any purpose but may not be published by components outside of the private network.""")
MAV_COMP_ID_CAMERA = 100
enums["MAV_COMPONENT"][100] = EnumEntry("MAV_COMP_ID_CAMERA", """Camera #1.""")
MAV_COMP_ID_CAMERA2 = 101
enums["MAV_COMPONENT"][101] = EnumEntry("MAV_COMP_ID_CAMERA2", """Camera #2.""")
MAV_COMP_ID_CAMERA3 = 102
enums["MAV_COMPONENT"][102] = EnumEntry("MAV_COMP_ID_CAMERA3", """Camera #3.""")
MAV_COMP_ID_CAMERA4 = 103
enums["MAV_COMPONENT"][103] = EnumEntry("MAV_COMP_ID_CAMERA4", """Camera #4.""")
MAV_COMP_ID_CAMERA5 = 104
enums["MAV_COMPONENT"][104] = EnumEntry("MAV_COMP_ID_CAMERA5", """Camera #5.""")
MAV_COMP_ID_CAMERA6 = 105
enums["MAV_COMPONENT"][105] = EnumEntry("MAV_COMP_ID_CAMERA6", """Camera #6.""")
MAV_COMP_ID_SERVO1 = 140
enums["MAV_COMPONENT"][140] = EnumEntry("MAV_COMP_ID_SERVO1", """Servo #1.""")
MAV_COMP_ID_SERVO2 = 141
enums["MAV_COMPONENT"][141] = EnumEntry("MAV_COMP_ID_SERVO2", """Servo #2.""")
MAV_COMP_ID_SERVO3 = 142
enums["MAV_COMPONENT"][142] = EnumEntry("MAV_COMP_ID_SERVO3", """Servo #3.""")
MAV_COMP_ID_SERVO4 = 143
enums["MAV_COMPONENT"][143] = EnumEntry("MAV_COMP_ID_SERVO4", """Servo #4.""")
MAV_COMP_ID_SERVO5 = 144
enums["MAV_COMPONENT"][144] = EnumEntry("MAV_COMP_ID_SERVO5", """Servo #5.""")
MAV_COMP_ID_SERVO6 = 145
enums["MAV_COMPONENT"][145] = EnumEntry("MAV_COMP_ID_SERVO6", """Servo #6.""")
MAV_COMP_ID_SERVO7 = 146
enums["MAV_COMPONENT"][146] = EnumEntry("MAV_COMP_ID_SERVO7", """Servo #7.""")
MAV_COMP_ID_SERVO8 = 147
enums["MAV_COMPONENT"][147] = EnumEntry("MAV_COMP_ID_SERVO8", """Servo #8.""")
MAV_COMP_ID_SERVO9 = 148
enums["MAV_COMPONENT"][148] = EnumEntry("MAV_COMP_ID_SERVO9", """Servo #9.""")
MAV_COMP_ID_SERVO10 = 149
enums["MAV_COMPONENT"][149] = EnumEntry("MAV_COMP_ID_SERVO10", """Servo #10.""")
MAV_COMP_ID_SERVO11 = 150
enums["MAV_COMPONENT"][150] = EnumEntry("MAV_COMP_ID_SERVO11", """Servo #11.""")
MAV_COMP_ID_SERVO12 = 151
enums["MAV_COMPONENT"][151] = EnumEntry("MAV_COMP_ID_SERVO12", """Servo #12.""")
MAV_COMP_ID_SERVO13 = 152
enums["MAV_COMPONENT"][152] = EnumEntry("MAV_COMP_ID_SERVO13", """Servo #13.""")
MAV_COMP_ID_SERVO14 = 153
enums["MAV_COMPONENT"][153] = EnumEntry("MAV_COMP_ID_SERVO14", """Servo #14.""")
MAV_COMP_ID_GIMBAL = 154
enums["MAV_COMPONENT"][154] = EnumEntry("MAV_COMP_ID_GIMBAL", """Gimbal #1.""")
MAV_COMP_ID_LOG = 155
enums["MAV_COMPONENT"][155] = EnumEntry("MAV_COMP_ID_LOG", """Logging component.""")
MAV_COMP_ID_ADSB = 156
enums["MAV_COMPONENT"][156] = EnumEntry("MAV_COMP_ID_ADSB", """Automatic Dependent Surveillance-Broadcast (ADS-B) component.""")
MAV_COMP_ID_OSD = 157
enums["MAV_COMPONENT"][157] = EnumEntry("MAV_COMP_ID_OSD", """On Screen Display (OSD) devices for video links.""")
MAV_COMP_ID_PERIPHERAL = 158
enums["MAV_COMPONENT"][158] = EnumEntry("MAV_COMP_ID_PERIPHERAL", """Generic autopilot peripheral component ID. Meant for devices that do not implement the parameter microservice.""")
MAV_COMP_ID_QX1_GIMBAL = 159
enums["MAV_COMPONENT"][159] = EnumEntry("MAV_COMP_ID_QX1_GIMBAL", """Gimbal ID for QX1.""")
MAV_COMP_ID_FLARM = 160
enums["MAV_COMPONENT"][160] = EnumEntry("MAV_COMP_ID_FLARM", """FLARM collision alert component.""")
MAV_COMP_ID_PARACHUTE = 161
enums["MAV_COMPONENT"][161] = EnumEntry("MAV_COMP_ID_PARACHUTE", """Parachute component.""")
MAV_COMP_ID_WINCH = 169
enums["MAV_COMPONENT"][169] = EnumEntry("MAV_COMP_ID_WINCH", """Winch component.""")
MAV_COMP_ID_GIMBAL2 = 171
enums["MAV_COMPONENT"][171] = EnumEntry("MAV_COMP_ID_GIMBAL2", """Gimbal #2.""")
MAV_COMP_ID_GIMBAL3 = 172
enums["MAV_COMPONENT"][172] = EnumEntry("MAV_COMP_ID_GIMBAL3", """Gimbal #3.""")
MAV_COMP_ID_GIMBAL4 = 173
enums["MAV_COMPONENT"][173] = EnumEntry("MAV_COMP_ID_GIMBAL4", """Gimbal #4""")
MAV_COMP_ID_GIMBAL5 = 174
enums["MAV_COMPONENT"][174] = EnumEntry("MAV_COMP_ID_GIMBAL5", """Gimbal #5.""")
MAV_COMP_ID_GIMBAL6 = 175
enums["MAV_COMPONENT"][175] = EnumEntry("MAV_COMP_ID_GIMBAL6", """Gimbal #6.""")
MAV_COMP_ID_BATTERY = 180
enums["MAV_COMPONENT"][180] = EnumEntry("MAV_COMP_ID_BATTERY", """Battery #1.""")
MAV_COMP_ID_BATTERY2 = 181
enums["MAV_COMPONENT"][181] = EnumEntry("MAV_COMP_ID_BATTERY2", """Battery #2.""")
MAV_COMP_ID_MAVCAN = 189
enums["MAV_COMPONENT"][189] = EnumEntry("MAV_COMP_ID_MAVCAN", """CAN over MAVLink client.""")
MAV_COMP_ID_MISSIONPLANNER = 190
enums["MAV_COMPONENT"][190] = EnumEntry("MAV_COMP_ID_MISSIONPLANNER", """Component that can generate/supply a mission flight plan (e.g. GCS or developer API).""")
MAV_COMP_ID_ONBOARD_COMPUTER = 191
enums["MAV_COMPONENT"][191] = EnumEntry("MAV_COMP_ID_ONBOARD_COMPUTER", """Component that lives on the onboard computer (companion computer) and has some generic functionalities, such as settings system parameters and monitoring the status of some processes that don't directly speak mavlink and so on.""")
MAV_COMP_ID_ONBOARD_COMPUTER2 = 192
enums["MAV_COMPONENT"][192] = EnumEntry("MAV_COMP_ID_ONBOARD_COMPUTER2", """Component that lives on the onboard computer (companion computer) and has some generic functionalities, such as settings system parameters and monitoring the status of some processes that don't directly speak mavlink and so on.""")
MAV_COMP_ID_ONBOARD_COMPUTER3 = 193
enums["MAV_COMPONENT"][193] = EnumEntry("MAV_COMP_ID_ONBOARD_COMPUTER3", """Component that lives on the onboard computer (companion computer) and has some generic functionalities, such as settings system parameters and monitoring the status of some processes that don't directly speak mavlink and so on.""")
MAV_COMP_ID_ONBOARD_COMPUTER4 = 194
enums["MAV_COMPONENT"][194] = EnumEntry("MAV_COMP_ID_ONBOARD_COMPUTER4", """Component that lives on the onboard computer (companion computer) and has some generic functionalities, such as settings system parameters and monitoring the status of some processes that don't directly speak mavlink and so on.""")
MAV_COMP_ID_PATHPLANNER = 195
enums["MAV_COMPONENT"][195] = EnumEntry("MAV_COMP_ID_PATHPLANNER", """Component that finds an optimal path between points based on a certain constraint (e.g. minimum snap, shortest path, cost, etc.).""")
MAV_COMP_ID_OBSTACLE_AVOIDANCE = 196
enums["MAV_COMPONENT"][196] = EnumEntry("MAV_COMP_ID_OBSTACLE_AVOIDANCE", """Component that plans a collision free path between two points.""")
MAV_COMP_ID_VISUAL_INERTIAL_ODOMETRY = 197
enums["MAV_COMPONENT"][197] = EnumEntry("MAV_COMP_ID_VISUAL_INERTIAL_ODOMETRY", """Component that provides position estimates using VIO techniques.""")
MAV_COMP_ID_PAIRING_MANAGER = 198
enums["MAV_COMPONENT"][198] = EnumEntry("MAV_COMP_ID_PAIRING_MANAGER", """Component that manages pairing of vehicle and GCS.""")
MAV_COMP_ID_IMU = 200
enums["MAV_COMPONENT"][200] = EnumEntry("MAV_COMP_ID_IMU", """Inertial Measurement Unit (IMU) #1.""")
MAV_COMP_ID_IMU_2 = 201
enums["MAV_COMPONENT"][201] = EnumEntry("MAV_COMP_ID_IMU_2", """Inertial Measurement Unit (IMU) #2.""")
MAV_COMP_ID_IMU_3 = 202
enums["MAV_COMPONENT"][202] = EnumEntry("MAV_COMP_ID_IMU_3", """Inertial Measurement Unit (IMU) #3.""")
MAV_COMP_ID_GPS = 220
enums["MAV_COMPONENT"][220] = EnumEntry("MAV_COMP_ID_GPS", """GPS #1.""")
MAV_COMP_ID_GPS2 = 221
enums["MAV_COMPONENT"][221] = EnumEntry("MAV_COMP_ID_GPS2", """GPS #2.""")
MAV_COMP_ID_ODID_TXRX_1 = 236
enums["MAV_COMPONENT"][236] = EnumEntry("MAV_COMP_ID_ODID_TXRX_1", """Open Drone ID transmitter/receiver (Bluetooth/WiFi/Internet).""")
MAV_COMP_ID_ODID_TXRX_2 = 237
enums["MAV_COMPONENT"][237] = EnumEntry("MAV_COMP_ID_ODID_TXRX_2", """Open Drone ID transmitter/receiver (Bluetooth/WiFi/Internet).""")
MAV_COMP_ID_ODID_TXRX_3 = 238
enums["MAV_COMPONENT"][238] = EnumEntry("MAV_COMP_ID_ODID_TXRX_3", """Open Drone ID transmitter/receiver (Bluetooth/WiFi/Internet).""")
MAV_COMP_ID_UDP_BRIDGE = 240
enums["MAV_COMPONENT"][240] = EnumEntry("MAV_COMP_ID_UDP_BRIDGE", """Component to bridge MAVLink to UDP (i.e. from a UART).""")
MAV_COMP_ID_UART_BRIDGE = 241
enums["MAV_COMPONENT"][241] = EnumEntry("MAV_COMP_ID_UART_BRIDGE", """Component to bridge to UART (i.e. from UDP).""")
MAV_COMP_ID_TUNNEL_NODE = 242
enums["MAV_COMPONENT"][242] = EnumEntry("MAV_COMP_ID_TUNNEL_NODE", """Component handling TUNNEL messages (e.g. vendor specific GUI of a component).""")
MAV_COMP_ID_SYSTEM_CONTROL = 250
enums["MAV_COMPONENT"][250] = EnumEntry("MAV_COMP_ID_SYSTEM_CONTROL", """Deprecated, don't use. Component for handling system messages (e.g. to ARM, takeoff, etc.).""")
MAV_COMPONENT_ENUM_END = 251
enums["MAV_COMPONENT"][251] = EnumEntry("MAV_COMPONENT_ENUM_END", """""")

# message IDs
MAVLINK_MSG_ID_BAD_DATA = -1
MAVLINK_MSG_ID_UNKNOWN = -2
MAVLINK_MSG_ID_HEARTBEAT = 0


class MAVLink_heartbeat_message(MAVLink_message):
    """
    The heartbeat message shows that a system or component is present
    and responding. The type and autopilot fields (along with the
    message component id), allow the receiving system to treat further
    messages from this system appropriately (e.g. by laying out the
    user interface based on the autopilot). This microservice is
    documented at https://mavlink.io/en/services/heartbeat.html
    """

    id = MAVLINK_MSG_ID_HEARTBEAT
    msgname = "HEARTBEAT"
    fieldnames = ["type", "autopilot", "base_mode", "custom_mode", "system_status", "mavlink_version"]
    ordered_fieldnames = ["custom_mode", "type", "autopilot", "base_mode", "system_status", "mavlink_version"]
    fieldtypes = ["uint8_t", "uint8_t", "uint8_t", "uint32_t", "uint8_t", "uint8_t"]
    fielddisplays_by_name: Dict[str, str] = {"base_mode": "bitmask"}
    fieldenums_by_name: Dict[str, str] = {"type": "MAV_TYPE", "autopilot": "MAV_AUTOPILOT", "base_mode": "MAV_MODE_FLAG", "system_status": "MAV_STATE"}
    fieldunits_by_name: Dict[str, str] = {}
    native_format = bytearray(b"<IBBBBB")
    orders = [1, 2, 3, 0, 4, 5]
    lengths = [1, 1, 1, 1, 1, 1]
    array_lengths = [0, 0, 0, 0, 0, 0]
    crc_extra = 50
    unpacker = struct.Struct("<IBBBBB")
    instance_field = None
    instance_offset = -1

    def __init__(self, type: int, autopilot: int, base_mode: int, custom_mode: int, system_status: int, mavlink_version: int):
        MAVLink_message.__init__(self, MAVLink_heartbeat_message.id, MAVLink_heartbeat_message.msgname)
        self._fieldnames = MAVLink_heartbeat_message.fieldnames
        self._instance_field = MAVLink_heartbeat_message.instance_field
        self._instance_offset = MAVLink_heartbeat_message.instance_offset
        self.type = type
        self.autopilot = autopilot
        self.base_mode = base_mode
        self.custom_mode = custom_mode
        self.system_status = system_status
        self.mavlink_version = mavlink_version

    def pack(self, mav: "MAVLink", force_mavlink1: bool = False) -> bytes:
        return self._pack(mav, self.crc_extra, self.unpacker.pack(self.custom_mode, self.type, self.autopilot, self.base_mode, self.system_status, self.mavlink_version), force_mavlink1=force_mavlink1)


# Define name on the class for backwards compatibility (it is now msgname).
# Done with setattr to hide the class variable from mypy.
setattr(MAVLink_heartbeat_message, "name", mavlink_msg_deprecated_name_property())


mavlink_map: Dict[int, Type[MAVLink_message]] = {
    MAVLINK_MSG_ID_HEARTBEAT: MAVLink_heartbeat_message,
}


class MAVError(Exception):
    """MAVLink error class"""

    def __init__(self, msg: str) -> None:
        Exception.__init__(self, msg)
        self.message = msg


class MAVLink_bad_data(MAVLink_message):
    """
    a piece of bad data in a mavlink stream
    """

    def __init__(self, data: bytes, reason: str) -> None:
        MAVLink_message.__init__(self, MAVLINK_MSG_ID_BAD_DATA, "BAD_DATA")
        self._fieldnames = ["data", "reason"]
        self.data = data
        self.reason = reason
        self._msgbuf = bytearray(data)
        self._instance_field = None

    def __str__(self) -> str:
        """Override the __str__ function from MAVLink_messages because non-printable characters are common in to be the reason for this message to exist."""
        hexstr = ["{:x}".format(i) for i in self.data]
        return "%s {%s, data:%s}" % (self._type, self.reason, hexstr)


class MAVLink_unknown(MAVLink_message):
    """
    a message that we don't have in the XML used when built
    """

    def __init__(self, msgid: int, data: bytes) -> None:
        MAVLink_message.__init__(self, MAVLINK_MSG_ID_UNKNOWN, "UNKNOWN_%u" % msgid)
        self._fieldnames = ["data"]
        self.data = data
        self._msgbuf = bytearray(data)
        self._instance_field = None

    def __str__(self) -> str:
        """Override the __str__ function from MAVLink_messages because non-printable characters are common."""
        hexstr = ["{:x}".format(i) for i in self.data]
        return "%s {data:%s}" % (self._type, hexstr)


class MAVLinkSigning(object):
    """MAVLink signing state class"""

    def __init__(self) -> None:
        self.secret_key: Optional[bytes] = None
        self.timestamp = 0
        self.link_id = 0
        self.sign_outgoing = False
        self.allow_unsigned_callback: Optional[Callable[["MAVLink", int], bool]] = None
        self.stream_timestamps: Dict[Tuple[int, int, int], int] = {}
        self.sig_count = 0
        self.badsig_count = 0
        self.goodsig_count = 0
        self.unsigned_count = 0
        self.reject_count = 0


class MAVLink(object):
    """MAVLink protocol handling class"""

    def __init__(self, file: Any, srcSystem: int = 0, srcComponent: int = 0, use_native: bool = False) -> None:
        self.seq = 0
        self.file = file
        self.srcSystem = srcSystem
        self.srcComponent = srcComponent
        self.callback: Optional[Callable[..., None]] = None
        self.callback_args: Optional[Iterable[Any]] = None
        self.callback_kwargs: Optional[Mapping[str, Any]] = None
        self.send_callback: Optional[Callable[..., None]] = None
        self.send_callback_args: Optional[Iterable[Any]] = None
        self.send_callback_kwargs: Optional[Mapping[str, Any]] = None
        self.buf = bytearray()
        self.buf_index = 0
        self.expected_length = HEADER_LEN_V1 + 2
        self.have_prefix_error = False
        self.robust_parsing = False
        self.protocol_marker = 254
        self.little_endian = True
        self.crc_extra = True
        self.sort_fields = True
        self.total_packets_sent = 0
        self.total_bytes_sent = 0
        self.total_packets_received = 0
        self.total_bytes_received = 0
        self.total_receive_errors = 0
        self.startup_time = time.time()
        self.signing = MAVLinkSigning()
        self.mav20_unpacker = struct.Struct("<cBBBBBBHB")
        self.mav10_unpacker = struct.Struct("<cBBBBB")
        self.mav20_h3_unpacker = struct.Struct("BBB")
        self.mav_csum_unpacker = struct.Struct("<H")
        self.mav_sign_unpacker = struct.Struct("<IH")

    def set_callback(self, callback: Callable[..., None], *args: Any, **kwargs: Any) -> None:
        self.callback = callback
        self.callback_args = args
        self.callback_kwargs = kwargs

    def set_send_callback(self, callback: Callable[..., None], *args: Any, **kwargs: Any) -> None:
        self.send_callback = callback
        self.send_callback_args = args
        self.send_callback_kwargs = kwargs

    def send(self, mavmsg: MAVLink_message, force_mavlink1: bool = False) -> None:
        """send a MAVLink message"""
        buf = mavmsg.pack(self, force_mavlink1=force_mavlink1)
        self.file.write(buf)
        self.seq = (self.seq + 1) % 256
        self.total_packets_sent += 1
        self.total_bytes_sent += len(buf)
        if self.send_callback is not None and self.send_callback_args is not None and self.send_callback_kwargs is not None:
            self.send_callback(mavmsg, *self.send_callback_args, **self.send_callback_kwargs)

    def buf_len(self) -> int:
        return len(self.buf) - self.buf_index

    def bytes_needed(self) -> int:
        """return number of bytes needed for next parsing stage"""
        ret = self.expected_length - self.buf_len()

        if ret <= 0:
            return 1
        return ret

    def __callbacks(self, msg: MAVLink_message) -> None:
        """this method exists only to make profiling results easier to read"""
        if self.callback is not None and self.callback_args is not None and self.callback_kwargs is not None:
            self.callback(msg, *self.callback_args, **self.callback_kwargs)

    def parse_char(self, c: Sequence[int]) -> Optional[MAVLink_message]:
        """input some data bytes, possibly returning a new message"""
        self.buf.extend(c)

        self.total_bytes_received += len(c)

        m = self.__parse_char_legacy()

        if m is not None:
            self.total_packets_received += 1
            self.__callbacks(m)
        else:
            # XXX The idea here is if we've read something and there's nothing left in
            # the buffer, reset it to 0 which frees the memory
            if self.buf_len() == 0 and self.buf_index != 0:
                self.buf = bytearray()
                self.buf_index = 0

        return m

    def __parse_char_legacy(self) -> Optional[MAVLink_message]:
        """input some data bytes, possibly returning a new message"""
        header_len = HEADER_LEN_V1
        if self.buf_len() >= 1 and self.buf[self.buf_index] == PROTOCOL_MARKER_V2:
            header_len = HEADER_LEN_V2

        m: Optional[MAVLink_message] = None
        if self.buf_len() >= 1 and self.buf[self.buf_index] != PROTOCOL_MARKER_V1 and self.buf[self.buf_index] != PROTOCOL_MARKER_V2:
            magic = self.buf[self.buf_index]
            self.buf_index += 1
            if self.robust_parsing:
                m = MAVLink_bad_data(bytearray([magic]), "Bad prefix")
                self.expected_length = header_len + 2
                self.total_receive_errors += 1
                return m
            if self.have_prefix_error:
                return None
            self.have_prefix_error = True
            self.total_receive_errors += 1
            raise MAVError("invalid MAVLink prefix '%s'" % magic)
        self.have_prefix_error = False
        if self.buf_len() >= 3:
            sbuf = self.buf[self.buf_index : 3 + self.buf_index]
            (magic, self.expected_length, incompat_flags) = cast(
                Tuple[int, int, int],
                self.mav20_h3_unpacker.unpack(sbuf),
            )
            if magic == PROTOCOL_MARKER_V2 and (incompat_flags & MAVLINK_IFLAG_SIGNED):
                self.expected_length += MAVLINK_SIGNATURE_BLOCK_LEN
            self.expected_length += header_len + 2
        if self.expected_length >= (header_len + 2) and self.buf_len() >= self.expected_length:
            mbuf = self.buf[self.buf_index : self.buf_index + self.expected_length]
            self.buf_index += self.expected_length
            self.expected_length = header_len + 2
            if self.robust_parsing:
                try:
                    if magic == PROTOCOL_MARKER_V2 and (incompat_flags & ~MAVLINK_IFLAG_SIGNED) != 0:
                        raise MAVError("invalid incompat_flags 0x%x 0x%x %u" % (incompat_flags, magic, self.expected_length))
                    m = self.decode(mbuf)
                except MAVError as reason:
                    m = MAVLink_bad_data(mbuf, reason.message)
                    self.total_receive_errors += 1
            else:
                if magic == PROTOCOL_MARKER_V2 and (incompat_flags & ~MAVLINK_IFLAG_SIGNED) != 0:
                    raise MAVError("invalid incompat_flags 0x%x 0x%x %u" % (incompat_flags, magic, self.expected_length))
                m = self.decode(mbuf)
            return m
        return None

    def parse_buffer(self, s: Sequence[int]) -> Optional[List[MAVLink_message]]:
        """input some data bytes, possibly returning a list of new messages"""
        m = self.parse_char(s)
        if m is None:
            return None
        ret = [m]
        while True:
            m = self.parse_char(b"")
            if m is None:
                return ret
            ret.append(m)

    def check_signature(self, msgbuf: bytearray, srcSystem: int, srcComponent: int) -> bool:
        """check signature on incoming message"""
        assert self.signing.secret_key is not None

        timestamp_buf = msgbuf[-12:-6]
        link_id = msgbuf[-13]
        (tlow, thigh) = cast(
            Tuple[int, int],
            self.mav_sign_unpacker.unpack(timestamp_buf),
        )
        timestamp = tlow + (thigh << 32)

        # see if the timestamp is acceptable
        stream_key = (link_id, srcSystem, srcComponent)
        if stream_key in self.signing.stream_timestamps:
            if timestamp <= self.signing.stream_timestamps[stream_key]:
                # reject old timestamp
                logger.info("old timestamp")
                return False
        else:
            # a new stream has appeared. Accept the timestamp if it is at most
            # one minute behind our current timestamp
            if timestamp + 6000 * 1000 < self.signing.timestamp:
                logger.info("bad new stream %s %s", timestamp / (100.0 * 1000 * 60 * 60 * 24 * 365), self.signing.timestamp / (100.0 * 1000 * 60 * 60 * 24 * 365))
                return False
            self.signing.stream_timestamps[stream_key] = timestamp
            logger.info("new stream")

        h = hashlib.new("sha256")
        h.update(self.signing.secret_key)
        h.update(msgbuf[:-6])
        sig1 = h.digest()[:6]
        sig2 = msgbuf[-6:]
        if sig1 != sig2:
            logger.info("sig mismatch")
            return False

        # the timestamp we next send with is the max of the received timestamp and
        # our current timestamp
        self.signing.timestamp = max(self.signing.timestamp, timestamp)
        return True

    def decode(self, msgbuf: bytearray) -> MAVLink_message:
        """decode a buffer as a MAVLink message"""
        # decode the header
        if msgbuf[0] != PROTOCOL_MARKER_V1:
            headerlen = 10
            try:
                magic, mlen, incompat_flags, compat_flags, seq, srcSystem, srcComponent, msgIdlow, msgIdhigh = cast(
                    Tuple[bytes, int, int, int, int, int, int, int, int],
                    self.mav20_unpacker.unpack(msgbuf[:headerlen]),
                )
            except struct.error as emsg:
                raise MAVError("Unable to unpack MAVLink header: %s" % emsg)
            msgId = msgIdlow | (msgIdhigh << 16)
            mapkey = msgId
        else:
            headerlen = 6
            try:
                magic, mlen, seq, srcSystem, srcComponent, msgId = cast(
                    Tuple[bytes, int, int, int, int, int],
                    self.mav10_unpacker.unpack(msgbuf[:headerlen]),
                )
                incompat_flags = 0
                compat_flags = 0
            except struct.error as emsg:
                raise MAVError("Unable to unpack MAVLink header: %s" % emsg)
            mapkey = msgId
        if (incompat_flags & MAVLINK_IFLAG_SIGNED) != 0:
            signature_len = MAVLINK_SIGNATURE_BLOCK_LEN
        else:
            signature_len = 0

        if ord(magic) != PROTOCOL_MARKER_V1 and ord(magic) != PROTOCOL_MARKER_V2:
            raise MAVError("invalid MAVLink prefix '{}'".format(hex(ord(magic))))
        if mlen != len(msgbuf) - (headerlen + 2 + signature_len):
            raise MAVError("invalid MAVLink message length. Got %u expected %u, msgId=%u headerlen=%u" % (len(msgbuf) - (headerlen + 2 + signature_len), mlen, msgId, headerlen))

        if mapkey not in mavlink_map:
            return MAVLink_unknown(msgId, msgbuf)

        # decode the payload
        msgtype = mavlink_map[mapkey]
        order_map = msgtype.orders
        len_map = msgtype.lengths
        crc_extra = msgtype.crc_extra

        # decode the checksum
        try:
            (crc,) = cast(
                Tuple[int],
                self.mav_csum_unpacker.unpack(msgbuf[-(2 + signature_len) :][:2]),
            )
        except struct.error as emsg:
            raise MAVError("Unable to unpack MAVLink CRC: %s" % emsg)
        crcbuf = msgbuf[1 : -(2 + signature_len)]
        if True:
            # using CRC extra
            crcbuf.append(crc_extra)
        crc2 = x25crc(crcbuf)
        if crc != crc2.crc and not MAVLINK_IGNORE_CRC:
            raise MAVError("invalid MAVLink CRC in msgID %u 0x%04x should be 0x%04x" % (msgId, crc, crc2.crc))

        sig_ok = False
        if signature_len == MAVLINK_SIGNATURE_BLOCK_LEN:
            self.signing.sig_count += 1
        if self.signing.secret_key is not None:
            accept_signature = False
            if signature_len == MAVLINK_SIGNATURE_BLOCK_LEN:
                sig_ok = self.check_signature(msgbuf, srcSystem, srcComponent)
                accept_signature = sig_ok
                if sig_ok:
                    self.signing.goodsig_count += 1
                else:
                    self.signing.badsig_count += 1
                if not accept_signature and self.signing.allow_unsigned_callback is not None:
                    accept_signature = self.signing.allow_unsigned_callback(self, msgId)
                    if accept_signature:
                        self.signing.unsigned_count += 1
                    else:
                        self.signing.reject_count += 1
            elif self.signing.allow_unsigned_callback is not None:
                accept_signature = self.signing.allow_unsigned_callback(self, msgId)
                if accept_signature:
                    self.signing.unsigned_count += 1
                else:
                    self.signing.reject_count += 1
            if not accept_signature:
                raise MAVError("Invalid signature")

        csize = msgtype.unpacker.size
        mbuf = msgbuf[headerlen : -(2 + signature_len)]
        if len(mbuf) < csize:
            # zero pad to give right size
            mbuf.extend([0] * (csize - len(mbuf)))
        if len(mbuf) < csize:
            raise MAVError("Bad message of type %s length %u needs %s" % (msgtype, len(mbuf), csize))
        mbuf = mbuf[:csize]
        try:
            t = cast(
                Tuple[Union[bytes, int, float], ...],
                msgtype.unpacker.unpack(mbuf),
            )
        except struct.error as emsg:
            raise MAVError("Unable to unpack MAVLink payload type=%s payloadLength=%u: %s" % (msgtype, len(mbuf), emsg))

        tlist: List[Union[bytes, float, int, Sequence[float], Sequence[int]]] = list(t)
        # handle sorted fields
        if True:
            if sum(len_map) == len(len_map):
                # message has no arrays in it
                for i in range(0, len(tlist)):
                    tlist[i] = t[order_map[i]]
            else:
                # message has some arrays
                tlist = []
                for i in range(0, len(order_map)):
                    order = order_map[i]
                    L = len_map[order]
                    tip = sum(len_map[:order])
                    field = t[tip]
                    if L == 1 or isinstance(field, bytes):
                        tlist.append(field)
                    else:
                        tlist.append(cast(Union[Sequence[int], Sequence[float]], list(t[tip : (tip + L)])))

        # terminate any strings
        for i, elem in enumerate(tlist):
            if isinstance(elem, bytes):
                tlist[i] = elem.rstrip(b"\x00")

        # construct the message object
        try:
            # Note that initializers don't follow the Liskov Substitution Principle
            # therefore it can't be typechecked
            m = msgtype(*tlist)  # type: ignore
        except Exception as emsg:
            raise MAVError("Unable to instantiate MAVLink message of type %s : %s" % (msgtype, emsg))
        m._signed = sig_ok
        if m._signed:
            m._link_id = msgbuf[-13]
        m._msgbuf = msgbuf
        m._payload = msgbuf[6 : -(2 + signature_len)]
        m._crc = crc
        m._header = MAVLink_header(msgId, incompat_flags, compat_flags, mlen, seq, srcSystem, srcComponent)
        return m

    def heartbeat_encode(self, type: int, autopilot: int, base_mode: int, custom_mode: int, system_status: int, mavlink_version: int = 3) -> MAVLink_heartbeat_message:
        """
        The heartbeat message shows that a system or component is present and
        responding. The type and autopilot fields (along with the
        message component id), allow the receiving system to treat
        further messages from this system appropriately (e.g. by
        laying out the user interface based on the autopilot). This
        microservice is documented at
        https://mavlink.io/en/services/heartbeat.html

        type                      : Vehicle or component type. For a flight controller component the vehicle type (quadrotor, helicopter, etc.). For other components the component type (e.g. camera, gimbal, etc.). This should be used in preference to component id for identifying the component type. (type:uint8_t, values:MAV_TYPE)
        autopilot                 : Autopilot type / class. Use MAV_AUTOPILOT_INVALID for components that are not flight controllers. (type:uint8_t, values:MAV_AUTOPILOT)
        base_mode                 : System mode bitmap. (type:uint8_t, values:MAV_MODE_FLAG)
        custom_mode               : A bitfield for use for autopilot-specific flags (type:uint32_t)
        system_status             : System status flag. (type:uint8_t, values:MAV_STATE)
        mavlink_version           : MAVLink version, not writable by user, gets added by protocol because of magic data type: uint8_t_mavlink_version (type:uint8_t)

        """
        return MAVLink_heartbeat_message(type, autopilot, base_mode, custom_mode, system_status, mavlink_version)

    def heartbeat_send(self, type: int, autopilot: int, base_mode: int, custom_mode: int, system_status: int, mavlink_version: int = 3, force_mavlink1: bool = False) -> None:
        """
        The heartbeat message shows that a system or component is present and
        responding. The type and autopilot fields (along with the
        message component id), allow the receiving system to treat
        further messages from this system appropriately (e.g. by
        laying out the user interface based on the autopilot). This
        microservice is documented at
        https://mavlink.io/en/services/heartbeat.html

        type                      : Vehicle or component type. For a flight controller component the vehicle type (quadrotor, helicopter, etc.). For other components the component type (e.g. camera, gimbal, etc.). This should be used in preference to component id for identifying the component type. (type:uint8_t, values:MAV_TYPE)
        autopilot                 : Autopilot type / class. Use MAV_AUTOPILOT_INVALID for components that are not flight controllers. (type:uint8_t, values:MAV_AUTOPILOT)
        base_mode                 : System mode bitmap. (type:uint8_t, values:MAV_MODE_FLAG)
        custom_mode               : A bitfield for use for autopilot-specific flags (type:uint32_t)
        system_status             : System status flag. (type:uint8_t, values:MAV_STATE)
        mavlink_version           : MAVLink version, not writable by user, gets added by protocol because of magic data type: uint8_t_mavlink_version (type:uint8_t)

        """
        self.send(self.heartbeat_encode(type, autopilot, base_mode, custom_mode, system_status, mavlink_version), force_mavlink1=force_mavlink1)
