"""
UBX Protocol Output payload definitions

THESE ARE THE PAYLOAD DEFINITIONS FOR _GET_ MESSAGES _FROM_ THE RECEIVER
(i.e. Periodic Navigation Data, Poll Responses, Info messages)

NB: Attribute names must be unique within each message class/id

NB: Repeating groups must be defined as a tuple thus
    'group': ('numr', {dict})
    where
    - 'numr' is either:
       a) an integer representing a fixed number of repeats e.g 32
       b) a string representing the name of a preceding attribute
          containing the number of repeats e.g. 'numCh'
       c) 'None' for a 'variable by size' repeating group
          (only one such group is permitted per message type)
    - {dict} is the nested dictionary containing the repeating
      attributes

Created on 27 Sep 2020

@author: semuadmin
"""
# pylint: disable=too-many-lines, line-too-long

from pyubx2.ubxtypes_core import (
    C2,
    C6,
    C10,
    C30,
    C32,
    CH,
    I1,
    I2,
    I4,
    R4,
    R8,
    U1,
    U2,
    U3,
    U4,
    U5,
    U6,
    U8,
    U9,
    U12,
    U64,
    X1,
    X2,
    X4,
)

UBX_PAYLOADS_GET = {
    "ACK-ACK": {"clsID": U1, "msgID": U1},
    "ACK-NAK": {"clsID": U1, "msgID": U1},
    # ********************************************************************
    # AssistNow Aiding Messages: i.e. Ephemeris, Almanac, other A-GPS data input.
    # Messages in the AID class are used to send GPS aiding data to the receiver
    # AID messages are deprecated in favour of MGA messages in >=Gen8
    "AID-ALM": {"svid": U4, "week": U4, "optBlock": ("None", {"dwrd": U4})},
    "AID-AOP": {"gnssId": U1, "svId": U1, "reserved1": U2, "data": U64},
    "AID-EPH": {
        "svid": U4,
        "how": U4,
        "optBlock": (
            "None",
            {
                "sf1d1": U4,
                "sf1d2": U4,
                "sf1d3": U4,
                "sf1d4": U4,
                "sf1d5": U4,
                "sf1d6": U4,
                "sf1d7": U4,
                "sf1d8": U4,
                "sf2d1": U4,
                "sf2d2": U4,
                "sf2d3": U4,
                "sf2d4": U4,
                "sf2d5": U4,
                "sf2d6": U4,
                "sf2d7": U4,
                "sf2d8": U4,
                "sf3d1": U4,
                "sf3d2": U4,
                "sf3d3": U4,
                "sf3d4": U4,
                "sf3d5": U4,
                "sf3d6": U4,
                "sf3d7": U4,
                "sf3d8": U4,
            },
        ),
    },
    "AID-HUI": {
        "health": X4,
        "utcA0": R8,
        "utcA1": R8,
        "utcTOW": I4,
        "utcWNT": I2,
        "utcLS": I2,
        "utcWNF": I2,
        "utcDNs": I2,
        "utcLSF": I2,
        "utcSpare": I2,
        "klobA0": R4,
        "klobA1": R4,
        "klobA2": R4,
        "klobA3": R4,
        "klobB0": R4,
        "klobB1": R4,
        "klobB2": R4,
        "klobB3": R4,
        "flags": X4,
    },
    "AID-INI": {
        "ecefXOrLat": I4,
        "ecefYOrLon": I4,
        "ecefZOrAlt": I4,
        "posAcc": U4,
        "tmCfg": X2,
        "wn": U2,
        "tow": U4,
        "towNs": I4,
        "tAccMs": U4,
        "tAccNs": U4,
        "clkDOrFreq": I4,
        "clkDAccOrFreqAcc": U4,
        "flags": X4,
    },
    # ********************************************************************
    # Configuration Input Messages: i.e. Set Dynamic Model, Set DOP Mask, Set Baud Rate, etc..
    # Messages in the CFG class are used to configure the receiver and read out current configuration values. Any
    # messages in the CFG class sent to the receiver are either acknowledged (with message UBX-ACK-ACK) if
    # processed successfully or rejected (with message UBX-ACK-NAK) if processing unsuccessfully.
    "CFG-ANT": {"flags": X2, "pins": X2},
    "CFG-BATCH": {
        "version": U1,
        "flags": X1,
        "bufSize": U2,
        "notifThrs": U2,
        "pioId": U1,
        "reserved0": U1,
    },
    "CFG-CFG": {"clearMask": X4, "saveMask": X4, "loadMask": X4, "deviceMask": X1},
    "CFG-DAT": {
        "datumNum": U2,
        "datumName": C6,
        "majA": R8,
        "flat": R8,
        "dX": R4,
        "dY": R4,
        "dZ": R4,
        "rotX": R4,
        "rotY": R4,
        "rotZ": R4,
        "scale": R4,
    },
    "CFG-DGNSS": {
        "dgnssMode": U1,
        "reserved0": U3,
    },
    "CFG-DOSC": {
        "version": U1,
        "numOsc": U1,
        "reserved1": U2,
        "group": (
            "numOsc",
            {  # repeating group * numOsc
                "oscId": U1,
                "reserved2": U1,
                "flags": X2,
                "freq": U4,
                "phaseOffset": I4,
                "withTemp": U4,
                "withAge": U4,
                "timeToTemp": U2,
                "reserved3": U2,
                "gainVco": I4,
                "gainUncertainty": U1,
                "reserved4": U3,
            },
        ),
    },
    "CFG-DYNSEED": {"version": U1, "reserved1": U3, "seedHi": U4, "seedLo": U4},
    "CFG-ESRC": {
        "version": U1,
        "numSources": U1,
        "reserved1": U2,
        "group": (
            "numSources",
            {  # repeating group * numSources
                "extInt": U1,
                "flags": X2,
                "freq": U4,
                "reserved2": U4,
                "withTemp": U4,
                "withAge": U4,
                "timeToTemp": U2,
                "maxDevLifeTim": U2,
                "offset": I4,
                "offsetUncertainty": U4,
                "jitter": U4,
            },
        ),
    },
    "CFG-FIXSEED": {
        "version": U1,
        "length": U1,
        "reserved1": U2,
        "seedHi": U4,
        "seedLo": U4,
        "group": ("length", {"classId": U1, "msgId": U1}),  # repeating group * length
    },
    "CFG-GEOFENCE": {
        "version": U1,
        "numFences": U1,
        "confLvl": U1,
        "reserved1": U1,
        "pioEnabled": U1,
        "pinPolarity": U1,
        "pin": U1,
        "reserved2": U1,
        "group": (
            "numFences",
            {"lat": I4, "lon": I4, "radius": U4},  # repeating group * numFences
        ),
    },
    "CFG-GNSS": {
        "msgVer": U1,
        "numTrkChHw": U1,
        "numTrkChUse": U1,
        "numConfigBlocks": U1,
        "group": (
            "numConfigBlocks",
            {  # repeating group * numConfigBlocks
                "gnssId": U1,
                "resTrkCh": U1,
                "maxTrkCh": U1,
                "reserved1": U1,
                "flags": X4,
            },
        ),
    },
    "CFG-INF": {
        "protocolID": U1,
        "reserved1": U3,
        "infMsgMaskDDC": X1,
        "infMsgMaskUART1": X1,
        "infMsgMaskUART2": X1,
        "infMsgMaskUSB": X1,
        "infMsgMaskSPI": X1,
        "reserved2": X1,
    },
    "CFG-ITFM": {"config": X4, "config2": X4},
    "CFG-LOGFILTER": {
        "version": U1,
        "flags": X1,
        "minInterval": U2,
        "timeThreshold": U2,
        "speedThreshold": U2,
        "positionThreshold": U4,
    },
    "CFG-MSG": {
        "msgClass": U1,
        "msgID": U1,
        "rateDDC": U1,
        "rateUART1": U1,
        "rateUART2": U1,
        "rateUSB": U1,
        "rateSPI": U1,
        "reserved": U1,
    },
    "CFG-NAV5": {
        "mask": X2,
        "dynModel": U1,
        "fixMode": U1,
        "fixedAlt": I4,
        "fixedAltVar": U4,
        "minElev": I1,
        "drLimit": U1,
        "pDop": U2,
        "tDop": U2,
        "pAcc": U2,
        "tAcc": U2,
        "staticHoldThresh": U1,
        "dgpsTimeOut": U1,
        "reserved2": U4,
        "reserved3": U4,
        "reserved4": U4,
    },
    "CFG-NAVX5": {
        "mask1": X2,
        "reserved0": U4,
        "reserved1": U1,
        "reserved2": U1,
        "minSVs": U1,
        "maxSVs": U1,
        "minCNO": U1,
        "reserved5": U1,
        "iniFix3D": U1,
        "reserved6": U1,
        "reserved7": U1,
        "reserved8": U1,
        "wknRollover": U2,
        "reserved9": U1,
        "reserved10": U1,
        "reserved11": U1,
        "usePPP": U1,
        "useAOP": U1,
        "reserved12": U1,
        "reserved13": U1,
        "aopOrbMaxErr": U2,
        "reserved3": U4,
        "reserved4": U4,
    },
    "CFG-NMEAvX": {  # deprecated length 4
        "filter": X1,
        "nmeaVersion": U1,
        "numSV": U1,
        "flags": X1,
    },
    "CFG-NMEAv0": {  # v0 deprecated length 12
        "filter": X1,
        "nmeaVersion": U1,
        "numSV": U1,
        "flags": X1,
        "gnssToFilter": X4,
        "svNumbering": U1,
        "mainTalkerId": U1,
        "gsvTalkerId": U1,
        "version": U1,
    },
    "CFG-NMEA": {  # preferred version length 20
        "filter": X1,
        "nmeaVersion": U1,
        "numSV": U1,
        "flags": X1,
        "gnssToFilter": X4,
        "svNumbering": U1,
        "mainTalkerId": U1,
        "gsvTalkerId": U1,
        "version": U1,
        "bdsTalkerId": C2,
        "reserved1": U6,
    },
    "CFG-ODO": {
        "version": U1,
        "reserved1": U3,
        "flags": U1,
        "odoCfg": X1,
        "reserved2": U6,
        "cogMaxSpeed": U1,
        "cogMaxPosAcc": U1,
        "reserved3": U2,
        "velLpGain": U1,
        "cogLpGain": U1,
        "reserved4": U2,
    },
    "CFG-PM2": {
        "version": U1,
        "reserved1": U1,
        "reserved2": U1,
        "reserved3": U1,
        "flags": X4,
        "updatePeriod": U4,
        "searchPeriod": U4,
        "gridOffset": U4,
        "onTime": U2,
        "minAcqTime": U2,
        "reserved4": U2,
        "reserved5": U2,
        "reserved6": U4,
        "reserved7": U4,
        "reserved8": U1,
        "reserved9": U1,
        "reserved10": U2,
        "reserved11": U4,
    },
    "CFG-PMS": {
        "version": U1,
        "powerSetupValue": U1,
        "period": U2,
        "onTime": U2,
        "reserved1": U2,
    },
    "CFG-PRT": {
        "portID": U1,
        "reserved0": U1,
        "txReady": X2,
        "mode": X4,
        "baudRate": U4,
        "inProtoMask": X2,
        "outProtoMask": X2,
        "reserved4": U2,
        "reserved5": U2,
    },
    "CFG-PWR": {"version": U1, "reserved1": U3, "state": U4},
    "CFG-RATE": {"measRate": U2, "navRate": U2, "timeRef": U2},
    "CFG-RINV": {"flags": X1, "group": ("None", {"data": U1})},  # repeating group
    "CFG-RST": {"navBbrMask": X2, "resetMode": U1, "reserved1": U1},
    "CFG-RXM": {"reserved1": U1, "lpMode": U1},
    "CFG-SBAS": {
        "mode": X1,
        "usage": X1,
        "maxSBAS": U1,
        "scanmode2": X1,
        "scanmode1": X4,
    },
    "CFG-SMGR": {
        "minGNSSFix": U1,
        "maxFreqChange": U2,
        "maxPhaseCorrRate": U2,
        "reserved1": U2,
        "freqTolerance": U2,
        "timeTolerance": U2,
        "messageCfg": X2,
        "maxSlewRate": U2,
        "flags": X4,
    },
    "CFG-SPT": {
        "version": U1,
        "reserved0": U1,
        "sensorId": U2,
        "reserved1": U8,
    },
    "CFG-TMODE2": {
        "timeMode": U1,
        "reserved1": U1,
        "flags": X2,
        "ecefXOrLat": I4,
        "ecefYOrLon": I4,
        "ecefZOrAlt": I4,
        "fixedPosAcc": U4,
        "svinMinDur": U4,
        "svinAccLimit": U4,
    },
    "CFG-TMODE3": {
        "version": U1,
        "reserved0": U1,
        "flags": X2,
        "ecefXOrLat": I4,
        "ecefYOrLon": I4,
        "ecefZOrAlt": I4,
        "ecefXOrLatHP": I1,
        "ecefYOrLonHP": I1,
        "ecefZOrAltHP": I1,
        "reserved1": U1,
        "fixedPosAcc": U4,
        "svinMinDur": U4,
        "svinAccLimit": U4,
        "reserved2": U8,
    },
    "CFG-TP5": {
        "tpIdx": U1,
        "reserved0": U1,
        "reserved1": U2,
        "antCableDelay": I2,
        "rfGroupDelay": I2,
        "freqPeriod": U4,
        "freqPeriodLock": U4,
        "pulseLenRatio": U4,
        "pulseLenRatioLock": U4,
        "userConfigDelay": I4,
        "flags": X4,
    },
    "CFG-TXSLOT": {
        "version": U1,
        "enable": X1,
        "refTp": U1,
        "reserved1": U1,
        "end1": U4,
        "end2": U4,
        "end3": U4,
    },
    "CFG-USB": {
        "vendorID": U2,
        "productID": U2,
        "reserved1": U2,
        "reserved2": U2,
        "powerConsumpt": U2,
        "flags": X2,
        "vendorString": C32,
        "productString": C32,
        "serialNumber": C32,
    },
    "CFG-VALGET": {
        "version": U1,
        "layer": U1,
        "position": U2,
        "group": ("None", {"cfgData": U1}),  # repeating group
    },
    # ********************************************************************
    # External Sensor Fusion Messages: i.e. External Sensor Measurements and Status Information.
    # Messages in the ESF class are used to output external sensor fusion information from the receiver.
    "ESF-ALG": {
        "iTOW": U4,
        "version": U1,
        "flags": U1,
        "error": U1,
        "reserved1": U1,
        "yaw": U4,
        "pitch": I2,
        "roll": I2,
    },
    "ESF-INS": {
        "bitfield0": U4,
        "reserved1": U4,
        "iTOW": U4,
        "xAngRate": I4,
        "yAngRate": I4,
        "zAngRate": I4,
        "xAccel": I4,
        "yAccel": I4,
        "zAccel": I4,
    },
    "ESF-MEAS": {  # this version used when bit 3 of flags = 0
        "timeTag": U4,
        "flags": X2,
        "id": U2,
        "group": (
            "None",
            {  # repeating group * numMeas, which is bits 11..15 in flags
                "data": X4,
            },
        ),
    },
    "ESF-MEAS-CT": {  # this version used when bit 3 of flags = 1
        "timeTag": U4,
        "flags": X2,
        "id": U2,
        "group": (
            "ESF-MEAS-CT",  # specially named to cater for optional calibTtag attribute after repeating group
            {  # repeating group * numMeas, which is bits 11..15 of flags
                "data": X4,
            },
        ),
        "calibTtag": U4,
    },
    "ESF-RAW": {
        "reserved1": U4,
        "group": (
            "None",
            {  # repeating group
                "data": X4,
                "sTag": X4,
            },
        ),
    },
    "ESF-STATUS": {
        "iTOW": U4,
        "version": U1,
        "reserved1": U1,
        "reserved2": U2,
        "reserved3": U4,
        "status": U1,
        "reserved4": U1,
        "reserved5": U1,
        "numCh": U1,
        "group": (
            "numCh",
            {  # repeating group * numCh
                "sensStatus1": X1,
                "sensStatus2": X2,
                "freq": U1,
                "faults": X1,
            },
        ),
    },
    # ********************************************************************
    # High Rate Navigation Results Messages: i.e. High rate time, position, speed, heading.
    # Messages in the HNR class are used to output high rate navigation data for position, altitude,
    # velocity and their accuracies.
    "HNR-ATT": {
        "iTOW": U4,
        "version": U1,
        "reserved1": U3,
        "roll": I4,
        "pitch": I4,
        "heading": I4,
        "accRoll": U4,
        "accPitch": U4,
        "accHeading": U4,
    },
    "HNR-INS": {
        "bitfield0": X4,
        "reserved1": U4,
        "iTOW": U4,
        "xAngRate": I4,
        "yAngRate": I4,
        "zAngRate": I4,
        "xAccel": I4,
        "yAccel": I4,
        "zAccel": I4,
    },
    "HNR-PVT": {
        "iTOW": U4,
        "year": U2,
        "month": U1,
        "day": U1,
        "hour": U1,
        "min": U1,
        "second": U1,
        "valid": X1,
        "nano": I4,
        "flags": X1,
        "reserved1": U2,
        "lon": I4,
        "lat": I4,
        "height": I4,
        "hMSL": I4,
        "gSpeed": I4,
        "speed": I4,
        "headMot": I4,
        "headVeh": I4,
        "hAcc": U4,
        "vAcc": U4,
        "sAcc": U4,
        "headAcc": U4,
        "reserved2": U4,
    },
    # ********************************************************************
    # Information Messages: i.e. Printf-Style Messages, with IDs such as Error, Warning, Notice.
    # Messages in the INF class are used to output strings in a printf style from the firmware or application code. All
    # INF messages have an associated type to indicate the kind of message.
    "INF-DEBUG": {"message": CH},
    "INF-ERROR": {"message": CH},
    "INF-NOTICE": {"message": CH},
    "INF-TEST": {"message": CH},
    "INF-WARNING": {"message": CH},
    # ********************************************************************
    # Logging Messages: i.e. Log creation, deletion, info and retrieval.
    # Messages in the LOG class are used to configure and report status information of the logging feature.
    "LOG-BATCH": {
        "version": U1,
        "contentValid": X1,
        "msgCnt": U2,
        "iTOW": U4,
        "year": U2,
        "month": U1,
        "day": U1,
        "hour": U1,
        "min": U1,
        "sec": U1,
        "valid": X1,
        "tAcc": U4,
        "fracSec": I4,
        "fixType": U1,
        "flags": X1,
        "flags2": X1,
        "numSV": U1,
        "lon": I4,
        "lat": I4,
        "height": I4,
        "hMSL": I4,
        "hAcc": U4,
        "vAcc": U4,
        "velN": I4,
        "velE": I4,
        "velD": I4,
        "gSpeed": I4,
        "headMot": I4,
        "sAcc": U4,
        "headAcc": U4,
        "pDOP": U2,
        "reserved1": U2,
        "distance": U4,
        "totalDistance": U4,
        "distanceStd": U4,
        "reserved2": U4,
    },
    "LOG-FINDTIME": {"version": U1, "type": U1, "reserved1": U2, "entryNumber": U4},
    "LOG-INFO": {
        "version": U1,
        "reserved1": U3,
        "filestoreCapacity": U4,
        "reserved2": U8,
        "currentMaxLogSize": U4,
        "currentLogSize": U4,
        "entryCount": U4,
        "oldestYear": U2,
        "oldestMonth": U1,
        "oldestDay": U1,
        "oldestHour": U1,
        "oldestMinute": U1,
        "oldestSecond": U1,
        "reserved3": U1,
        "newestYear": U2,
        "newestMonth": U1,
        "newestDay": U1,
        "newestHour": U1,
        "newestMinute": U1,
        "newestSecond": U1,
        "reserved4": U1,
        "status": X1,
        "reserved5": U3,
    },
    "LOG-RETRIEVEPOS": {
        "entryIndex": U4,
        "lon": I4,
        "lat": I4,
        "hMSL": I4,
        "hAcc": U4,
        "gSpeed": U4,
        "heading": U4,
        "version": U1,
        "fixType": U1,
        "year": U2,
        "month": U1,
        "day": U1,
        "hour": U1,
        "minute": U1,
        "second": U1,
        "reserved1": U1,
        "numSV": U1,
        "reserved2": U1,
    },
    "LOG-RETRIEVEPOSEXTRA": {
        "entryIndex": U4,
        "version": U1,
        "reserved1": U1,
        "year": U2,
        "month": U1,
        "day": U1,
        "hour": U1,
        "minute": U1,
        "second": U1,
        "reserved2": U3,
        "distance": U4,
        "reserved3": U12,
    },
    "LOG-RETRIEVESTRING": {
        "entryIndex": U4,
        "version": U1,
        "reserved1": U1,
        "year": U2,
        "month": U1,
        "day": U1,
        "hour": U1,
        "minute": U1,
        "second": U1,
        "reserved2": U1,
        "byteCount": U2,
        "group": ("byteCount", {"data": U1}),  # repeating group * byteCount
    },
    # ********************************************************************
    # Multiple GNSS Assistance Messages: i.e. Assistance data for various GNSS.
    # Messages in the MGA class are used for GNSS aiding information from and to the receiver.
    "MGA-ACK-DATA0": {
        "type": U1,
        "version": U1,
        "infoCode": U1,
        "msgId": U1,
        "msgPayloadStart": U4,
    },
    "MGA-NAK-DATA0": {
        "type": U1,
        "version": U1,
        "infoCode": U1,
        "msgId": U1,
        "msgPayloadStart": U4,
    },
    "MGA-DBD": {"reserved1": U12, "group": ("None", {"data": U1})},  # repeating group
    "MGA-FLASH-ACK": {
        "type": U1,
        "version": U1,
        "ack": U1,
        "reserved1": U1,
        "sequence": U2,
    },
    # ********************************************************************
    # Monitoring Messages: i.e. Communication Status, CPU Load, Stack Usage, Task Status.
    # Messages in the MON class are used to report the receiver status, such as CPU load, stack usage, I/O subsystem
    # statistics etc.
    "MON-COMMS": {
        "version": U1,
        "nPorts": U1,
        "txErrors": X1,
        "reserved0": U1,
        "protIds1": U1,
        "protIds2": U1,
        "protIds3": U1,
        "protIds4": U1,
        "group": (
            "nPorts",
            {  # repeating group * nPorts
                "portId": U2,
                "txPending": U2,
                "txBytes": U4,
                "txUsage": U1,
                "txPeakUsage": U1,
                "rxPending": U2,
                "rxBytes": U4,
                "rxUsage": U1,
                "rxPeakUsage": U1,
                "overrunErrs": U2,
                "msgs1": U2,
                "msgs2": U2,
                "msgs3": U2,
                "msgs4": U2,
                "reserved1": U8,
                "skipped": U4,
            },
        ),
    },
    "MON-GNSS": {
        "version": U1,
        "supported": X1,
        "default": X1,
        "enabled": X1,
        "simultaneous": U1,
        "reserved1": U3,
    },
    "MON-HW": {
        "pinSel": X4,
        "pinBank": X4,
        "pinDir": X4,
        "pinVal": X4,
        "noisePerMS": U2,
        "agcCnt": U2,
        "aStatus": U1,
        "aPower": U1,
        "flags": X1,
        "reserved1": U1,
        "usedMask": X4,
        "groupVP": (
            25,
            {
                "VP": X1,
            },
        ),  # repeating group * 25
        "jamInd": U1,
        "reserved3": U2,
        "pinIrq": X4,
        "pullH": X4,
        "pullL": X4,
    },
    "MON-HW2": {
        "ofsI": I1,
        "magI": U1,
        "ofsQ": I1,
        "magQ": U1,
        "cfgSource": U1,
        "reserved0": U3,
        "lowLevCfg": X4,
        "reserved11": U4,
        "reserved12": U4,
        "postStatus": X4,
        "reserved2": U4,
    },
    "MON-HW3": {
        "version": U1,
        "nPins": U1,
        "flags": X1,
        "hwVersion": C10,
        "reserved0": U9,
        "pinId": U2,
        "pinMask": X2,
        "VP": U1,
        "reserved1": U1,
    },
    "MON-IO": {
        "rxBytes": U4,
        "txBytes": U4,
        "parityErrs": U2,
        "framingErrs": U2,
        "overrunErrs": U2,
        "breakCond": U2,
        "rxBusy": U1,
        "txBusy": U1,
        "reserved1": U2,
    },
    "MON-MSGPP": {
        "groupmsg1": (
            8,
            {
                "msg1": U2,
            },
        ),  # repeating group * 8
        "groupmsg2": (
            8,
            {
                "msg2": U2,
            },
        ),  # repeating group * 8
        "groupmsg3": (
            8,
            {
                "msg3": U2,
            },
        ),  # repeating group * 8
        "groupmsg4": (
            8,
            {
                "msg4": U2,
            },
        ),  # repeating group * 8
        "groupmsg5": (
            8,
            {
                "msg5": U2,
            },
        ),  # repeating group * 8
        "groupmsg6": (
            8,
            {
                "msg6": U2,
            },
        ),  # repeating group * 8
        "groupskipped": (
            6,
            {
                "skipped": U4,
            },
        ),  # repeating group * 6
    },
    "MON-PATCH": {
        "version": U2,
        "nEntries": U2,
        "group": (
            "nEntries",
            {  # repeating group * nEntries
                "patchInfo": X4,
                "comparatorNumber": U4,
                "patchAddress": U4,
                "patchData": U4,
            },
        ),
    },
    "MON-RF": {
        "version": U1,
        "nBlocks": U1,
        "reserved0": U2,
        "group": (
            "nBlocks",
            {  # repeating group * nBlocks
                "blockId": U1,
                "flags": X1,
                "antStatus": U1,
                "antPower": U1,
                "postStatus": U4,
                "reserved1": U4,
                "noisePerMS": U2,
                "agcCnt": U2,
                "jamInd": U1,
                "ofsI": I1,
                "magI": U1,
                "ofsQ": I1,
                "magQ": U1,
                "reserved2": U3,
            },
        ),
    },
    "MON-RXBUF": {
        "groupPending": (
            6,
            {
                "pending": U2,
            },
        ),  # repeating group * 6
        "groupUsage": (
            6,
            {
                "usage": U1,
            },
        ),  # repeating group * 6
        "groupPeakUsage": (
            6,
            {
                "peakUsage": U1,
            },
        ),  # repeating group * 6
    },
    "MON-RXR": {"flags": U1},
    "MON-SMGR": {
        "version": U1,
        "reserved1": U3,
        "iTOW": U4,
        "intOsc": X2,
        "extOsc": X2,
        "discSrc": U1,
        "gnss": X1,
        "extInt0": X1,
        "extInt1": X1,
    },
    "MON-SPAN": {
        "version": U1,
        "numRfBlocks": U1,
        "reserved0": U2,
        "group": (
            "numRfBlocks",
            {  # repeating group * numRfBlocks
                "groupSpan": (
                    256,
                    {
                        "spectrum": U1,
                    },
                ),  # nested repeating group * 256
                "span": U4,
                "res": U4,
                "center": U4,
                "pga": U1,
                "reserved1": U3,
            },
        ),
    },
    "MON-SPT": {
        "version": U1,
        "numSensor": U1,
        "numRes": U1,
        "reserved0": U1,
        "groupSensor": (
            "numSensor",
            {  # repeating group * numSensor
                "sensorId": U1,
                "drvVer": X1,
                "testState": U1,
                "drvFileName": U1,
            },
        ),
        "groupRes": (
            "numRes",
            {  # repeating group * numRes
                "sensorIdRes": U2,
                "sensorType": U2,
                "resType": U2,
                "reserved1": U2,
                "value": I4,
            },
        ),
    },
    "MON-TXBUF": {
        "groupPending": (
            6,
            {
                "pending": U2,
            },
        ),  # repeating group * 6
        "groupUsage": (
            6,
            {
                "usage": U1,
            },
        ),  # repeating group * 6
        "groupPeakUsage": (
            6,
            {
                "peakUsage": U1,
            },
        ),  # repeating group * 6
        "tUsage": U1,
        "tPeakUsage": U1,
        "errors": X1,
        "reserved1": U1,
    },
    "MON-VER": {
        "swVersion": C30,
        "hwVersion": C10,
        "group": ("None", {"extension": C30}),  # repeating group
    },
    # ********************************************************************
    # Navigation Results Messages: i.e. Position, Speed, Time, Acceleration, Heading, DOP, SVs used.
    # Messages in the NAV class are used to output navigation data such as position, altitude and velocity in a
    # number of formats. Additionally, status flags and accuracy figures are output. The messages are generated with
    # the configured navigation/measurement rate.
    "NAV-ATT": {
        "iTOW": U4,
        "version": U1,
        "reserved0": U3,
        "roll": I4,
        "pitch": I4,
        "heading": I4,
        "accRoll": U4,
        "accPitch": U4,
        "accHeading": U4,
    },
    "NAV-AOPSTATUS": {
        "iTOW": U4,
        "config": U1,
        "status": U1,
        "reserved0": U1,
        "reserved1": U1,
        "avail": U4,
        "reserved2": U4,
        "reserved3": U4,
    },
    "NAV-CLOCK": {"iTOW": U4, "clkB": I4, "clkD": I4, "tAcc": U4, "fAcc": U4},
    "NAV-COV": {
        "iTOW": U4,
        "version": U1,
        "posCovValid": U1,
        "velCovValid": U1,
        "reserved0": U9,
        "posCovNN": R4,
        "posCovNE": R4,
        "posCovND": R4,
        "posCovEE": R4,
        "posCovED": R4,
        "posCovDD": R4,
        "velCovNN": R4,
        "velCovNE": R4,
        "velCovND": R4,
        "velCovEE": R4,
        "velCovED": R4,
        "velCovDD": R4,
    },
    "NAV-DGPS": {
        "iTOW": U4,
        "age": I4,
        "baseId": I2,
        "baseHealth": I2,
        "numCh": U1,
        "status": U1,
        "reserved1": U2,
        "channels": (
            "numCh",
            {  # repeating group * numCh
                "svid": U1,
                "flags": U1,
                "ageC": U2,
                "prc": R4,
                "prrc": R4,
            },
        ),
    },
    "NAV-DOP": {
        "iTOW": U4,
        "gDOP": U2,
        "pDOP": U2,
        "tDOP": U2,
        "vDOP": U2,
        "hDOP": U2,
        "nDOP": U2,
        "eDOP": U2,
    },
    "NAV-EELL": {
        "iTOW": U4,
        "version": U1,
        "reserved1": U1,
        "errEllipseOrient": U2,
        "errEllipseMajor": U4,
        "errEllipseMinor": U4,
    },
    "NAV-EKFSTATUS": {
        "pulses": I4,
        "period": I4,
        "gyroMean": U4,
        "temperature": I2,
        "direction": I1,
    },
    "NAV-EOE": {"iTOW": U4},
    "NAV-GEOFENCE": {
        "iTOW": U4,
        "version": U1,
        "status": U1,
        "numFences": U1,
        "combState": U1,
        "group": (
            "numFences",
            {"state": U1, "reserved1": U1},  # repeating group * numFences
        ),
    },
    "NAV-HPPOSECEF": {
        "version": U1,
        "reserved1": U3,
        "iTOW": U4,
        "ecefX": I4,
        "ecefY": I4,
        "ecefZ": I4,
        "ecefXHp": I1,
        "ecefYHp": I1,
        "ecefZHp": I1,
        "reserved2": U1,
        "pAcc": U4,
    },
    "NAV-HPPOSLLH": {
        "version": U1,
        "reserved": U2,
        "flags": X1,
        "iTOW": U4,
        "lon": I4,
        "lat": I4,
        "height": I4,
        "hMSL": I4,
        "lonHp": I1,
        "latHp": I1,
        "heightHp": I1,
        "hMSLHp": I1,
        "hAcc": U4,
        "vAcc": U4,
    },
    "NAV-NMI": {
        "iTOW": U4,
        "version": U1,
        "reserved1": U4,
        "gpsNmiFlags": X1,
        "gpsLsFlags": X1,
        "galNmiFlags": X1,
        "galLsFlags": X1,
        "bdsNmiFlags": X1,
        "bdsLsFlags": X1,
        "gloNmiFlags": X1,
    },
    "NAV-ODO": {
        "version": U1,
        "reserved0": U3,
        "iTOW": U4,
        "distance": U4,
        "totalDistance": U4,
        "distanceStd": U4,
    },
    "NAV-ORB": {
        "iTOW": U4,
        "version": U1,
        "numSv": U1,
        "reserved1": U2,
        "group": (
            "numSv",
            {  # repeating group * numSv
                "gnssId": U1,
                "svId": U1,
                "svFlag": X1,
                "eph": X1,
                "alm": X1,
                "otherOrb": X1,
            },
        ),
    },
    "NAV-POSECEF": {"iTOW": U4, "ecefX": I4, "ecefY": I4, "ecefZ": I4, "pAcc": U4},
    "NAV-POSLLH": {
        "iTOW": U4,
        "lon": I4,
        "lat": I4,
        "height": I4,
        "hMSL": I4,
        "hAcc": U4,
        "vAcc": U4,
    },
    "NAV-PVT": {
        "iTOW": U4,
        "year": U2,
        "month": U1,
        "day": U1,
        "hour": U1,
        "min": U1,
        "second": U1,
        "valid": X1,
        "tAcc": U4,
        "nano": I4,
        "fixType": U1,
        "flags": X1,
        "flags2": X1,
        "numSV": U1,
        "lon": I4,
        "lat": I4,
        "height": I4,
        "hMSL": I4,
        "hAcc": U4,
        "vAcc": U4,
        "velN": I4,
        "velE": I4,
        "velD": I4,
        "gSpeed": I4,
        "headMot": I4,
        "sAcc": U4,
        "headAcc": U4,
        "pDOP": U2,
        "reserved1": U6,
        "headVeh": I4,
        "magDec": I2,
        "magAcc": U2,
    },
    "NAV-RELPOSNED": {
        "version": U1,
        "reserved1": U1,
        "refStationID": U2,
        "iTOW": U4,
        "relPosN": I4,
        "relPosE": I4,
        "relPosD": I4,
        "relPosHPN": I1,
        "relPosHPE": I1,
        "relPosHPD": I1,
        "reserved2": U1,
        "accN": U4,
        "accE": U4,
        "accD": U4,
        "flags": X4,
    },
    "NAV-SAT": {
        "iTOW": U4,
        "version": U1,
        "numCh": U1,
        "reserved11": I1,
        "reserved12": I1,
        "group": (
            "numCh",
            {  # repeating group * numCh
                "gnssId": U1,
                "svId": U1,
                "cno": U1,
                "elev": I1,
                "azim": I2,
                "prRes": I2,
                "flags": X4,
            },
        ),
    },
    "NAV-SBAS": {
        "iTOW": U4,
        "geo": U1,
        "mode:": U1,
        "sys": I1,
        "service": X1,
        "numCh": U1,
        "reserved0": U3,
        "channels": (
            "numCh",
            {  # repeating group * numCh
                "svid": U1,
                "flags": U1,
                "udre": U1,
                "svSys": U1,
                "svService": U1,
                "reserved1": U1,
                "prc": I2,
                "reserved2": U2,
                "ic": I2,
            },
        ),
    },
    "NAV-SIG": {
        "iTOW": U4,
        "version": U1,
        "numSigs": U1,
        "reserved0": U2,
        "group": (
            "numSigs",
            {  # repeating group * numSigs
                "gnssId": U1,
                "svId": U1,
                "sigId": U1,
                "freqId": U1,
                "prRes": I2,
                "cno": U1,
                "qualityInd": U1,
                "corrSource": U1,
                "ionoModel": U1,
                "sigFlags": X2,
                "reserved1": U4,
            },
        ),
    },
    "NAV-SLAS": {
        "iTOW": U4,
        "version": U1,
        "reserved1": U3,
        "gmsLon": I4,
        "gmsLat": I4,
        "gmsCode": U1,
        "qzssSvId": U1,
        "serviceFlags": X1,
        "cnt": U1,
        "group": (
            "cnt",
            {  # repeating group * cnt
                "gnssID": U1,
                "svId": U1,
                "reserved2": U1,
                "reserved3": U3,
                "prc": I2,
            },
        ),
    },
    "NAV-SOL": {
        "iTOW": U4,
        "fTOW": I4,
        "week": I2,
        "gpsFix": U1,
        "flags": X1,
        "ecefX": I4,
        "ecefY": I4,
        "ecefZ": I4,
        "pAcc": U4,
        "ecefVX": I4,
        "ecefVY": I4,
        "ecefVZ": I4,
        "sAcc": U4,
        "pDOP": U2,
        "reserved1": U1,
        "numSV": U1,
        "reserved2": U4,
    },
    "NAV-STATUS": {
        "iTOW": U4,
        "gpsFix": U1,
        "flags": X1,
        "fixStat": X1,
        "flags2": X1,
        "ttff": U4,
        "msss": U4,
    },
    "NAV-SVINFO": {  # deprecated - use NAV-SAT
        "iTOW": U4,
        "numCh": U1,
        "globalFlags": X1,
        "reserved2": U2,
        "channels": (
            "numCh",
            {  # repeating group * numCh
                "chn": U1,
                "svid": U1,
                "flags": X1,
                "quality": X1,
                "cno": U1,
                "elev": I1,
                "azim": I2,
                "prRes": I4,
            },
        ),
    },
    "NAV-SVIN": {
        "version": U1,
        "reserved1": U3,
        "iTOW": U4,
        "dur": U4,
        "meanX": I4,
        "meanY": I4,
        "meanZ": I4,
        "meanXHP": I1,
        "meanYHP": I1,
        "meanZHP": I1,
        "reserved2": U1,
        "meanAcc": U4,
        "obs": U4,
        "valid": U1,
        "active": U1,
        "reserved3": U2,
    },
    "NAV-TIMEBDS": {
        "iTOW": U4,
        "SOW": U4,
        "fSOW": I4,
        "week": I2,
        "leapS": I1,
        "valid": X1,
        "tAcc": U4,
    },
    "NAV-TIMEGAL": {
        "iTOW": U4,
        "galTow": U4,
        "fGalTow": I4,
        "galWno": I2,
        "leapS": I1,
        "valid": X1,
        "tAcc": U4,
    },
    "NAV-TIMEGLO": {
        "iTOW": U4,
        "TOD": U4,
        "fTOD": I4,
        "Nt": U2,
        "N4": U1,
        "valid": X1,
        "tAcc": U4,
    },
    "NAV-TIMEGPS": {
        "iTOW": U4,
        "fTOW": I4,
        "week": I2,
        "leapS": I1,
        "valid": X1,
        "tAcc": U4,
    },
    "NAV-TIMELS": {
        "iTOW": U4,
        "version": U1,
        "reserved1": U3,
        "srcOfCurrLs": U1,
        "currLs": I1,
        "srcOfLsChange": U1,
        "lsChange": I1,
        "timeToLsEvent": I4,
        "dateOfLsGpsWn": U2,
        "dateOfLsGpsDn": U2,
        "reserved2": U3,
        "valid": X1,
    },
    "NAV-TIMEQZSS": {
        "iTOW": U4,
        "qzssTow": U4,
        "fQzssTow": I4,
        "qzssWno": I2,
        "leapS": I1,
        "valid": X1,
        "tAcc": U4,
    },
    "NAV-TIMEUTC": {
        "iTOW": U4,
        "tAcc": U4,
        "nano": I4,
        "year": U2,
        "month": U1,
        "day": U1,
        "hour": U1,
        "min": U1,
        "sec": U1,
        "validflags": X1,
    },
    "NAV-VELECEF": {"iTOW": U4, "ecefVX": I4, "ecefVY": I4, "ecefVZ": I4, "sAcc": U4},
    "NAV-VELNED": {
        "iTOW": U4,
        "velN": I4,
        "velE": I4,
        "velD": I4,
        "speed": U4,
        "gSpeed": U4,
        "heading": I4,
        "sAcc": U4,
        "cAcc": U4,
    },
    # ********************************************************************
    # Receiver Manager Messages: i.e. Satellite Status, RTC Status.
    # Messages in the RXM class are used to output status and result data from the Receiver Manager. The output
    # rate is not bound to the navigation/measurement rate and messages can also be generated on events.
    "RXM-IMES": {
        "numTx": U1,
        "version": U1,
        "reserved1": U2,
        "group": (
            "numTx",
            {  # repeating group * numTx
                "reserved2": U1,
                "txId": U1,
                "reserved3": U3,
                "cno": U1,
                "reserved4": U2,
                "doppler": I4,
                "position1_1": X4,
                "position1_2": X4,
                "position2_1": X4,
                "lat": I4,
                "lon": I4,
                "shortIdFrame": X4,
                "mediumIdLSB": U4,
                "mediumId_2": X4,
            },
        ),
    },
    "RXM-MEASX": {
        "version": U1,
        "reserved0": U3,
        "gpsTOW": U4,
        "gloTOW": U4,
        "bdsTOW": U4,
        "reserved1": U4,
        "qzssTOW": U4,
        "gpsTOWacc": U2,
        "gloTOWacc": U2,
        "bdsTOWacc": U2,
        "reserved2": U2,
        "qzssTOWacc": U2,
        "numSv": U1,
        "flags": U1,
        "reserved3": U8,
        "group": (
            "numSv",
            {  # repeating group * numSv
                "gnssId": U1,
                "svId": U1,
                "cNo": U1,
                "mpathIndic": U1,
                "dopplerMS": I4,
                "dopplerHz": I4,
                "wholeChips": U2,
                "fracChips": U2,
                "codePhase": U4,
                "intCodePhase": U1,
                "pseuRangeRMSErr": U1,
                "reserved4": U2,
            },
        ),
    },
    "RXM-PMP-V0": {
        "version": U1,
        "reserved0": U1,
        "timeTag": U4,
        "uniqueWord1": U4,
        "uniqueWord2": U4,
        "serviceIdentifier": U2,
        "spare": U1,
        "uniqueWordBitErrors": U1,
        "groupUserData": (
            504,
            {
                "userData": U1,
            },
        ),  # repeating group * 504
        "fecBits": U2,
        "ebno": U1,
        "reserved1": U1,
    },
    "RXM-PMP-V1": {
        "version": U1,
        "reserved0": U1,
        "numBytesUserData": U2,
        "timeTag": U4,
        "uniqueWord1": U4,
        "uniqueWord2": U4,
        "serviceIdentifier": U2,
        "spare": U1,
        "uniqueWordBitErrors": U1,
        "fecBits": U2,
        "ebno": U1,
        "reserved1": U1,
        "groupUserData": (
            "numBytesUserData",
            {  # repeating group * numBytesUserData
                "userData": U1,
            },
        ),
    },
    "RXM-RAW": {
        "iTOW": I4,
        "week": I2,
        "numSV": U1,
        "reserved1": U1,
        "group": (
            "numSV",
            {  # repeating group * numSV
                "cpMes": R8,
                "prMes": R8,
                "doMes": R4,
                "sv": U1,
                "mesQI": I1,
                "cno": I1,
                "lli": U1,
            },
        ),
    },
    "RXM-RAWX": {
        "rcvTow": R8,
        "week": U2,
        "leapS": I1,
        "numMeas": U1,
        "recStat": X1,
        "reserved1": U3,
        "group": (
            "numMeas",
            {  # repeating group * numMeas
                "prMes": R8,
                "cpMes": R8,
                "doMes": R4,
                "gnssId": U1,
                "svId": U1,
                "reserved2": U1,
                "freqId": U1,
                "locktime": U2,
                "cno": U1,
                "prStdev": X1,
                "cpStdev": X1,
                "doStdev": X1,
                "trkStat": X1,
                "reserved3": U1,
            },
        ),
    },
    "RXM-RLM-S": {
        "version": U1,  # 0x00
        "type": U1,  # 0x01
        "svId": U1,
        "reserved0": U1,
        "groupBeacon": (
            8,
            {
                "beacon": U1,
            },
        ),
        "message": U1,
        "params1": U1,
        "params2": U1,
        "reserved1": U1,
    },
    "RXM-RLM-L": {
        "version": U1,  # 0x00
        "type": U1,  # 0x02
        "svId": U1,
        "reserved0": U1,
        "groupBeacon": (
            8,
            {
                "beacon": U1,
            },
        ),
        "message": U1,
        "groupParams": (
            12,
            {
                "params": U1,
            },
        ),
        "reserved1": U3,
    },
    "RXM-RTCM": {
        "version": U1,
        "flags": X1,
        "subType": U2,
        "refStation": U2,
        "msgType": U2,
    },
    "RXM-SFRBX": {
        "gnssId": U1,
        "svId": U1,
        "reserved0": U1,
        "freqId": U1,
        "numWords": U1,
        "chn": U1,
        "version": U1,
        "reserved1": U1,
        "group": ("numWords", {"dwrd": U4}),  # repeating group * numWords
    },
    "RXM-SVSI": {
        "iTOW": U4,
        "week": I2,
        "numVis": U1,
        "numSV": U1,
        "svid": U1,
        "svFlag": X1,
        "azim": I2,
        "elev": I1,
        "age": X1,
    },
    # ********************************************************************
    # Security Feature Messages
    # Messages in the SEC class are used for security features of the receiver.
    "SEC-UNIQID": {"version": U1, "reserved1": U3, "uniqueId": U5},
    # ********************************************************************
    # Timing Messages: i.e. Time Pulse Output, Time Mark Results.
    # Messages in the TIM class are used to output timing information from the receiver, like Time Pulse and Time
    # Mark measurements.
    "TIM-DOSC": {"version": U1, "reserved1": U3, "value": U4},
    "TIM-FCHG": {
        "version": U1,
        "reserved1": U3,
        "iTOW": U4,
        "intDeltaFreq": I4,
        "intDeltaFreqU": U4,
        "intRaw": U4,
        "extDeltaFreq": I4,
        "extDeltaFreqU": U4,
        "extRaw": U4,
    },
    "TIM-SMEAS": {
        "version": U1,
        "numMeas": U1,
        "reserved1": U2,
        "iTOW": U4,
        "reserved2": U4,
        "group": (
            "numMeas",
            {  # repeating group * numMeas
                "sourceId": U1,
                "flags": X1,
                "phaseOffsetFr": I1,
                "phaseUncFrac": U1,
                "phaseOffset": I4,
                "phaseUnc": U4,
                "reserved3": U4,
                "freqOffset": I4,
                "freqUnc": U4,
            },
        ),
    },
    "TIM-SVIN": {
        "dur": U4,
        "meanX": I4,
        "meanY": I4,
        "meanZ": I4,
        "meanV": U4,
        "obs": U4,
        "valid": U1,
        "active": U1,
        "reserved1": U2,
    },
    "TIM-TM2": {
        "ch": U1,
        "flags": X1,
        "count": U2,
        "wnR": U2,
        "wnF": U2,
        "towMsR": U4,
        "towSubMsR": U4,
        "towMsF": U4,
        "towSubMsF": U4,
        "accEst": U4,
    },
    "TIM-TOS": {
        "version": U1,
        "gnssId": U1,
        "reserved11": U2,
        "flags": X4,
        "year": U2,
        "month": U1,
        "day": U1,
        "hour": U1,
        "minute": U1,
        "second": U1,
        "utcStandard": U1,
        "utcOffset": I4,
        "utcUncertaint": U4,
        "week": U4,
        "TOW": U4,
        "gnssOffset": I4,
        "gnssUncertainty": U4,
        "intOscOffset": I4,
        "intOscUncertainty": U4,
        "extOscOffset": I4,
        "extOscUncertainty": U4,
    },
    "TIM-TP": {
        "towMS": U4,
        "towSubMS": U4,
        "qErr": I4,
        "week": U2,
        "flags": X1,
        "reserved1": U1,
    },
    "TIM-VCOCAL": {
        "type": U1,
        "version": U1,
        "oscId": U1,
        "reserved1": U3,
        "gainUncertainty": U2,
        "gainVco": I4,
    },
    "TIM-VRFY": {
        "itow": I4,
        "frac": I4,
        "deltaMs": I4,
        "deltaNs": I4,
        "wno": U2,
        "flags": X1,
        "reserved1": U1,
    },
    # ********************************************************************
    # Firmware Update Messages: i.e. Memory/Flash erase/write, Reboot, Flash identification, etc..
    # Messages in the UPD class are used to update the firmware and identify any attached flash device.
    "UPD-SOS": {  # System restored from backup
        "cmd": U1,
        "reserved1": U3,
        "response": U1,
        "reserved2": U3,
    },
    # ********************************************************************
    # Dummy message for error testing
    "FOO-BAR": {"spam": "Z2", "eggs": "Y1"},
}
