static const char *failMessage = "Unable to %s";

#define SEND_UBX_PACKET(TYPE, ID, DATA, ERRMSG, TIMEOUT)                                                                         \
    do {                                                                                                                         \
        msglen = makeUBXPacket(TYPE, ID, sizeof(DATA), DATA);                                                                    \
        _serial_gps->write(UBXscratch, msglen);                                                                                  \
        if (getACK(TYPE, ID, TIMEOUT) != GNSS_RESPONSE_OK) {                                                                     \
            LOG_WARN(failMessage, #ERRMSG);                                                                                      \
        }                                                                                                                        \
    } while (0)

// Power Management

static uint8_t _message_PMREQ[] PROGMEM = {
    0x00, 0x00, 0x00, 0x00, // 4 bytes duration of request task (milliseconds)
    0x02, 0x00, 0x00, 0x00  // Bitfield, set backup = 1
};

static uint8_t _message_PMREQ_10[] PROGMEM = {
    0x00,                   // version (0 for this version)
    0x00, 0x00, 0x00,       // Reserved 1
    0x00, 0x00, 0x00, 0x00, // 4 bytes duration of request task (milliseconds)
    0x06, 0x00, 0x00, 0x00, // Bitfield, set backup =1 and force =1
    0x08, 0x00, 0x00, 0x00  // wakeupSources Wake on uartrx
};

static const uint8_t _message_CFG_RXM_PSM[] PROGMEM = {
    0x08, // Reserved
    0x01  // Power save mode
};

// only for Neo-6
static const uint8_t _message_CFG_RXM_ECO[] PROGMEM = {
    0x08, // Reserved
    0x04  // eco mode
};

static const uint8_t _message_CFG_PM2[] PROGMEM = {
    0x01,                   // version
    0x00,                   // Reserved 1, set to 0x06 by u-Center
    0x00,                   // Reserved 2
    0x00,                   // Reserved 1
    0x00, 0x11, 0x03, 0x00, // flags-> cyclic mode, wait for normal fix ok, do not wake to update RTC, doNotEnterOff,
                            // LimitPeakCurrent
    0xE8, 0x03, 0x00, 0x00, // update period 1000 ms
    0x10, 0x27, 0x00, 0x00, // search period 10s
    0x00, 0x00, 0x00, 0x00, // Grid offset 0
    0x01, 0x00,             // onTime 1 second
    0x00, 0x00,             // min search time 0
    0x00, 0x00,             // 0x2C, 0x01,  // reserved 4
    0x00, 0x00,             // 0x00, 0x00,  // reserved 5
    0x00, 0x00, 0x00, 0x00, // 0x4F, 0xC1, 0x03, 0x00, // reserved 6
    0x00, 0x00, 0x00, 0x00, // 0x87, 0x02, 0x00, 0x00, // reserved 7
    0x00,                   // 0xFF,        // reserved 8
    0x00,                   // 0x00,        // reserved 9
    0x00, 0x00,             // 0x00, 0x00,  // reserved 10
    0x00, 0x00, 0x00, 0x00  // 0x64, 0x40, 0x01, 0x00  // reserved 11
};

// Constallation setup, none required for Neo-6

// For Neo-7 GPS & SBAS
static const uint8_t _message_GNSS_7[] = {
    0x00, // msgVer (0 for this version)
    0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0)
    0xff, // numTrkChUse (max number of channels to use, 0xff = max available)
    0x02, // numConfigBlocks (number of GNSS systems), most modules support maximum 3 GNSS systems
    // GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags
    0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x00, 0x01, // GPS
    0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x01  // SBAS
};

// It's not critical if the module doesn't acknowledge this configuration.
// The module should operate adequately with its factory or previously saved settings.
// It appears that there is a firmware bug in some GPS modules: When an attempt is made
// to overwrite a saved state with identical values, no ACK/NAK is received, contrary to
// what is specified in the Ublox documentation.
// There is also a possibility that the module may be GPS-only.

// For M8 GPS, GLONASS, Galileo, SBAS, QZSS
static const uint8_t _message_GNSS_8[] = {
    0x00,                                           // msgVer (0 for this version)
    0x00,                                           // numTrkChHw (max number of hardware channels, read only, so it's always 0)
    0xff,                                           // numTrkChUse (max number of channels to use, 0xff = max available)
    0x05,                                           // numConfigBlocks (number of GNSS systems)
                                                    // GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags
    0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, // GPS
    0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0x01, // SBAS
    0x02, 0x04, 0x08, 0x00, 0x01, 0x00, 0x01, 0x01, // Galileo
    0x05, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x01, // QZSS
    0x06, 0x08, 0x0E, 0x00, 0x01, 0x00, 0x01, 0x01  // GLONASS
};
/*
// For M8 GPS, GLONASS, BeiDou, SBAS, QZSS
static const uint8_t _message_GNSS_8_B[] = {
 0x00, // msgVer (0 for this version)
 0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0)
 0xff, // numTrkChUse (max number of channels to use, 0xff = max available) read only for protocol >23
 0x05, // numConfigBlocks (number of GNSS systems)
       // GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags
 0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, // GPS
 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0x01, // SBAS
 0x03, 0x08, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, // BeiDou
 0x05, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x01, // QZSS
 0x06, 0x08, 0x0E, 0x00, 0x01, 0x00, 0x01, 0x01  // GLONASS
};
*/

// For M8 we want to enable NMEA version 4.10 messages to allow for Galileo and or BeiDou
static const uint8_t _message_NMEA[]{
    0x00,                              // filter flags
    0x41,                              // NMEA Version
    0x00,                              // Max number of SVs to report per TaklerId
    0x02,                              // flags
    0x00, 0x00, 0x00, 0x00,            // gnssToFilter
    0x00,                              // svNumbering
    0x00,                              // mainTalkerId
    0x00,                              // gsvTalkerId
    0x01,                              // Message version
    0x00, 0x00,                        // bdsTalkerId 2 chars 0=default
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Reserved
};
// Enable jamming/interference monitor

// For Neo-6, Max-7 and Neo-7
static const uint8_t _message_JAM_6_7[] = {
    0xf3, 0xac, 0x62, 0xad, // config1 bbThreshold = 3, cwThreshold = 15, enable = 1, reserved bits 0x16B156
    0x1e, 0x03, 0x00, 0x00  // config2 antennaSetting Unknown = 0, reserved 3, = 0x00,0x00, reserved 2 = 0x31E
};

// For M8
static const uint8_t _message_JAM_8[] = {
    0xf3, 0xac, 0x62, 0xad, // config1 bbThreshold = 3, cwThreshold = 15, enable1 = 1, reserved bits 0x16B156
    0x1e, 0x43, 0x00, 0x00  // config2 antennaSetting Unknown = 0, enable2 = 1, generalBits = 0x31E
};

// Configure navigation engine expert settings:
// there are many variations of what were Reserved fields for the Neo-6 in later versions
// ToDo: check UBX-MON-VER for module type and protocol version

// For the Neo-6
static const uint8_t _message_NAVX5[] = {
    0x00, 0x00,             // msgVer (0 for this version)
    0x4c, 0x66,             // mask1
    0x00, 0x00, 0x00, 0x00, // Reserved 0
    0x00,                   // Reserved 1
    0x00,                   // Reserved 2
    0x03,                   // minSVs (Minimum number of satellites for navigation) = 3
    0x10,                   // maxSVs (Maximum number of satellites for navigation) = 16
    0x06,                   // minCNO (Minimum satellite signal level for navigation) = 6 dBHz
    0x00,                   // Reserved 5
    0x00,                   // iniFix3D (Initial fix must be 3D) (0 = false 1 = true)
    0x00,                   // Reserved 6
    0x00,                   // Reserved 7
    0x00,                   // Reserved 8
    0x00, 0x00,             // wknRollover 0 = firmware default
    0x00, 0x00, 0x00, 0x00, // Reserved 9
    0x00,                   // Reserved 10
    0x00,                   // Reserved 11
    0x00,                   // usePPP (Precice Point Positioning) (0 = false, 1 = true)
    0x01,                   // useAOP  (AssistNow Autonomous configuration) = 1 (enabled)
    0x00,                   // Reserved 12
    0x00,                   // Reserved 13
    0x00, 0x00,             // aopOrbMaxErr = 0 to reset to firmware default
    0x00,                   // Reserved 14
    0x00,                   // Reserved 15
    0x00, 0x00,             // Reserved 3
    0x00, 0x00, 0x00, 0x00  // Reserved 4
};
// For the M8
static const uint8_t _message_NAVX5_8[] = {
    0x02, 0x00,             // msgVer (2 for this version)
    0x4c, 0x66,             // mask1
    0x00, 0x00, 0x00, 0x00, // mask2
    0x00, 0x00,             // Reserved 1
    0x03,                   // minSVs (Minimum number of satellites for navigation) = 3
    0x10,                   // maxSVs (Maximum number of satellites for navigation) = 16
    0x06,                   // minCNO (Minimum satellite signal level for navigation) = 6 dBHz
    0x00,                   // Reserved 2
    0x00,                   // iniFix3D (Initial fix must be 3D) (0 = false 1 = true)
    0x00, 0x00,             // Reserved 3
    0x00,                   // ackAiding
    0x00, 0x00,             // wknRollover 0 = firmware default
    0x00,                   // sigAttenCompMode
    0x00,                   // Reserved 4
    0x00, 0x00,             // Reserved 5
    0x00, 0x00,             // Reserved 6
    0x00,                   // usePPP (Precice Point Positioning) (0 = false, 1 = true)
    0x01,                   // aopCfg  (AssistNow Autonomous configuration) = 1 (enabled)
    0x00, 0x00,             // Reserved 7
    0x00, 0x00,             // aopOrbMaxErr = 0 to reset to firmware default
    0x00, 0x00, 0x00, 0x00, // Reserved 8
    0x00, 0x00, 0x00,       // Reserved 9
    0x00                    // useAdr
};

// Set GPS update rate to 1Hz
// Lowering the update rate helps to save power.
// Additionally, for some new modules like the M9/M10, an update rate lower than 5Hz
// is recommended to avoid a known issue with satellites disappearing.
// The module defaults for M8, M9, M10 are the same as we use here so no update is necessary
static const uint8_t _message_1HZ[] = {
    0xE8, 0x03, // Measurement Rate (1000ms for 1Hz)
    0x01, 0x00, // Navigation rate, always 1 in GPS mode
    0x01, 0x00  // Time reference
};

// Disable GLL. GLL - Geographic position (latitude and longitude), which provides the current geographical
// coordinates.
static const uint8_t _message_GLL[] = {
    0xF0, 0x01, // NMEA ID for GLL
    0x00,       // Rate for DDC
    0x00,       // Rate for UART1
    0x00,       // Rate for UART2
    0x00,       // Rate for USB
    0x00,       // Rate for SPI
    0x00        // Reserved
};

// Disable GSA. GSA - GPS DOP and active satellites, used for detailing the satellites used in the positioning and
// the DOP (Dilution of Precision)
static const uint8_t _message_GSA[] = {
    0xF0, 0x02, // NMEA ID for GSA
    0x00,       // Rate for DDC
    0x00,       // Rate for UART1
    0x00,       // Rate for UART2
    0x00,       // Rate for USB useful for native linux
    0x00,       // Rate for SPI
    0x00        // Reserved
};

// Disable GSV. GSV - Satellites in view, details the number and location of satellites in view.
static const uint8_t _message_GSV[] = {
    0xF0, 0x03, // NMEA ID for GSV
    0x00,       // Rate for DDC
    0x00,       // Rate for UART1
    0x00,       // Rate for UART2
    0x00,       // Rate for USB
    0x00,       // Rate for SPI
    0x00        // Reserved
};

// Disable VTG. VTG - Track made good and ground speed, which provides course and speed information relative to
// the ground.
static const uint8_t _message_VTG[] = {
    0xF0, 0x05, // NMEA ID for VTG
    0x00,       // Rate for DDC
    0x00,       // Rate for UART1
    0x00,       // Rate for UART2
    0x00,       // Rate for USB
    0x00,       // Rate for SPI
    0x00        // Reserved
};

// Enable RMC. RMC - Recommended Minimum data, the essential gps pvt (position, velocity, time) data.
static const uint8_t _message_RMC[] = {
    0xF0, 0x04, // NMEA ID for RMC
    0x00,       // Rate for DDC
    0x01,       // Rate for UART1
    0x00,       // Rate for UART2
    0x01,       // Rate for USB useful for native linux
    0x00,       // Rate for SPI
    0x00        // Reserved
};

// Enable GGA. GGA - Global Positioning System Fix Data, which provides 3D location and accuracy data.
static const uint8_t _message_GGA[] = {
    0xF0, 0x00, // NMEA ID for GGA
    0x00,       // Rate for DDC
    0x01,       // Rate for UART1
    0x00,       // Rate for UART2
    0x01,       // Rate for USB, useful for native linux
    0x00,       // Rate for SPI
    0x00        // Reserved
};

// Disable UBX-AID-ALPSRV as it may confuse TinyGPS. The Neo-6 seems to send this message
// whether the AID Autonomous is enabled or not
static const uint8_t _message_AID[] = {
    0x0B, 0x32, // NMEA ID for UBX-AID-ALPSRV
    0x00,       // Rate for DDC
    0x00,       // Rate for UART1
    0x00,       // Rate for UART2
    0x00,       // Rate for USB
    0x00,       // Rate for SPI
    0x00        // Reserved
};

// Turn off TEXT INFO Messages for all but M10 series

// B5 62 06 02 0A 00 01 00 00 00 03 03 00 03 03 00 1F 20
static const uint8_t _message_DISABLE_TXT_INFO[] = {
    0x01,             // Protocol ID for NMEA
    0x00, 0x00, 0x00, // Reserved
    0x03,             // I2C
    0x03,             // I/O Port 1
    0x00,             // I/O Port 2
    0x03,             // USB
    0x03,             // SPI
    0x00              // Reserved
};

// The Power Management configuration allows the GPS module to operate in different power modes for optimized
// power consumption. The modes supported are: 0x00 = Full power: The module operates at full power with no power
// saving. 0x01 = Balanced: The module dynamically adjusts the tracking behavior to balance power consumption.
// 0x02 = Interval: The module operates in a periodic mode, cycling between tracking and power saving states.
// 0x03 = Aggressive with 1 Hz: The module operates in a power saving mode with a 1 Hz update rate.
// 0x04 = Aggressive with 2 Hz: The module operates in a power saving mode with a 2 Hz update rate.
// 0x05 = Aggressive with 4 Hz: The module operates in a power saving mode with a 4 Hz update rate.
// The 'period' field specifies the position update and search period. It is only valid when the powerSetupValue
// is set to Interval; otherwise, it must be set to '0'. The 'onTime' field specifies the duration of the ON phase
// and must be smaller than the period. It is only valid when the powerSetupValue is set to Interval; otherwise,
// it must be set to '0'.
// This command applies to M8 products
static const uint8_t _message_PMS[] = {
    0x00,       // Version (0)
    0x03,       // Power setup value 3 = Agresssive 1Hz
    0x00, 0x00, // period: not applicable, set to 0
    0x00, 0x00, // onTime: not applicable, set to 0
    0x00, 0x00  // reserved, generated by u-center
};

static const uint8_t _message_SAVE[] = {
    0x00, 0x00, 0x00, 0x00, // clearMask: no sections cleared
    0xFF, 0xFF, 0x00, 0x00, // saveMask: save all sections
    0x00, 0x00, 0x00, 0x00, // loadMask: no sections loaded
    0x17                    // deviceMask: BBR, Flash, EEPROM, and SPI Flash
};

static const uint8_t _message_SAVE_10[] = {
    0x00, 0x00, 0x00, 0x00, // clearMask: no sections cleared
    0xFF, 0xFF, 0x00, 0x00, // saveMask: save all sections
    0x00, 0x00, 0x00, 0x00, // loadMask: no sections loaded
    0x01                    // deviceMask: only save to BBR
};

// As the M10 has no flash, the best we can do to preserve the config is to set it in RAM and BBR.
// BBR will survive a restart, and power off for a while, but modules with small backup
// batteries or super caps will not retain the config for a long power off time.
// for all configurations using sleep / low power modes, V_BCKP needs to be hooked to permanent power for fast aquisition after
// sleep

// VALSET Commands for M10
// Please refer to the M10 Protocol Specification:
// https://content.u-blox.com/sites/default/files/u-blox-M10-SPG-5.10_InterfaceDescription_UBX-21035062.pdf
// Where the VALSET/VALGET/VALDEL commands are described in detail.
// and:
// https://content.u-blox.com/sites/default/files/u-blox-M10-ROM-5.10_ReleaseNotes_UBX-22001426.pdf
// for interesting insights.
//
// Integration manual:
// https://content.u-blox.com/sites/default/files/documents/SAM-M10Q_IntegrationManual_UBX-22020019.pdf
// has details on low-power modes

/*
OPERATEMODE E1 2 (0 | 1 | 2)
POSUPDATEPERIOD U4 5
ACQPERIOD U4 10
GRIDOFFSET U4 0
ONTIME U2 1
MINACQTIME U1 0
MAXACQTIME U1 0
DONOTENTEROFF L 1
WAITTIMEFIX  L 1
UPDATEEPH L 1
EXTINTWAKE L 0 no ext ints
EXTINTBACKUP L 0 no ext ints
EXTINTINACTIVE L 0 no ext ints
EXTINTACTIVITY U4 0 no ext ints
LIMITPEAKCURRENT L 1

// Ram layer config message:
// b5 62 06 8a 26 00 00 01 00 00 01 00 d0 20 02 02 00 d0 40 05 00 00 00 05 00 d0 30 01 00 08 00 d0 10 01 09 00 d0 10 01 10 00 d0
// 10 01 8b de

// BBR layer config message:
// b5 62 06 8a 26 00 00 02 00 00 01 00 d0 20 02 02 00 d0 40 05 00 00 00 05 00 d0 30 01 00 08 00 d0 10 01 09 00 d0 10 01 10 00 d0
// 10 01 8c 03
*/
static const uint8_t _message_VALSET_PM_RAM[] = {0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0xd0, 0x20, 0x02, 0x02, 0x00, 0xd0, 0x40,
                                                 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xd0, 0x30, 0x01, 0x00, 0x08, 0x00, 0xd0,
                                                 0x10, 0x01, 0x09, 0x00, 0xd0, 0x10, 0x01, 0x10, 0x00, 0xd0, 0x10, 0x01};
static const uint8_t _message_VALSET_PM_BBR[] = {0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0xd0, 0x20, 0x02, 0x02, 0x00, 0xd0, 0x40,
                                                 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xd0, 0x30, 0x01, 0x00, 0x08, 0x00, 0xd0,
                                                 0x10, 0x01, 0x09, 0x00, 0xd0, 0x10, 0x01, 0x10, 0x00, 0xd0, 0x10, 0x01};

/*
CFG-ITFM replaced by 5 valset messages which can be combined into one for RAM and one for BBR

20410001 bbthreshold U1 3
20410002 cwthreshold U1 15
1041000d enable L        0 -> 1
20410010 ant E1          0
10410013 enable aux L    0 -> 1


b5 62 06 8a 0e 00 00 01 00 00 0d 00 41 10 01 13 00 41 10 01 63 c6
*/
static const uint8_t _message_VALSET_ITFM_RAM[] = {0x00, 0x01, 0x00, 0x00, 0x0d, 0x00, 0x41,
                                                   0x10, 0x01, 0x13, 0x00, 0x41, 0x10, 0x01};
static const uint8_t _message_VALSET_ITFM_BBR[] = {0x00, 0x02, 0x00, 0x00, 0x0d, 0x00, 0x41,
                                                   0x10, 0x01, 0x13, 0x00, 0x41, 0x10, 0x01};

// Turn off all NMEA messages:
// Ram layer config message:
// b5 62 06 8a 22 00 00 01 00 00 c0 00 91 20 00 ca 00 91 20 00 c5 00 91 20 00 ac 00 91 20 00 b1 00 91 20 00 bb 00 91 20 00 40 8f

// Disable GLL, GSV, VTG messages in BBR layer
// BBR layer config message:
// b5 62 06 8a 13 00 00 02 00 00 ca 00 91 20 00 c5 00 91 20 00 b1 00 91 20 00 f8 4e

static const uint8_t _message_VALSET_DISABLE_NMEA_RAM[] = {
    /*0x00, 0x01, 0x00, 0x00, 0xca, 0x00, 0x91, 0x20, 0x00, 0xc5, 0x00, 0x91, 0x20, 0x00, 0xb1, 0x00, 0x91, 0x20, 0x00 */
    0x00, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x91, 0x20, 0x00, 0xca, 0x00, 0x91, 0x20, 0x00, 0xc5, 0x00, 0x91,
    0x20, 0x00, 0xac, 0x00, 0x91, 0x20, 0x00, 0xb1, 0x00, 0x91, 0x20, 0x00, 0xbb, 0x00, 0x91, 0x20, 0x00};

static const uint8_t _message_VALSET_DISABLE_NMEA_BBR[] = {0x00, 0x02, 0x00, 0x00, 0xca, 0x00, 0x91, 0x20, 0x00, 0xc5,
                                                           0x00, 0x91, 0x20, 0x00, 0xb1, 0x00, 0x91, 0x20, 0x00};

// Turn off text info messages:
// Ram layer config message:
// b5 62 06 8a 09 00 00 01 00 00 07 00 92 20 06 59 50

// BBR layer config message:
// b5 62 06 8a 09 00 00 02 00 00 07 00 92 20 06 5a 58

// Turn NMEA GGA, RMC messages on:
// Layer config messages:
// RAM:
// b5 62 06 8a 0e 00 00 01 00 00 bb 00 91 20 01 ac 00 91 20 01 6a 8f
// BBR:
// b5 62 06 8a 0e 00 00 02 00 00 bb 00 91 20 01 ac 00 91 20 01 6b 9c
// FLASH:
// b5 62 06 8a 0e 00 00 04 00 00 bb 00 91 20 01 ac 00 91 20 01 6d b6
// Doing this for the FLASH layer isn't really required since we save the config to flash later

static const uint8_t _message_VALSET_DISABLE_TXT_INFO_RAM[] = {0x00, 0x01, 0x00, 0x00, 0x07, 0x00, 0x92, 0x20, 0x03};
static const uint8_t _message_VALSET_DISABLE_TXT_INFO_BBR[] = {0x00, 0x02, 0x00, 0x00, 0x07, 0x00, 0x92, 0x20, 0x03};

static const uint8_t _message_VALSET_ENABLE_NMEA_RAM[] = {0x00, 0x01, 0x00, 0x00, 0xbb, 0x00, 0x91,
                                                          0x20, 0x01, 0xac, 0x00, 0x91, 0x20, 0x01};
static const uint8_t _message_VALSET_ENABLE_NMEA_BBR[] = {0x00, 0x02, 0x00, 0x00, 0xbb, 0x00, 0x91,
                                                          0x20, 0x01, 0xac, 0x00, 0x91, 0x20, 0x01};
static const uint8_t _message_VALSET_DISABLE_SBAS_RAM[] = {0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x31,
                                                           0x10, 0x00, 0x05, 0x00, 0x31, 0x10, 0x00};
static const uint8_t _message_VALSET_DISABLE_SBAS_BBR[] = {0x00, 0x02, 0x00, 0x00, 0x20, 0x00, 0x31,
                                                           0x10, 0x00, 0x05, 0x00, 0x31, 0x10, 0x00};

/*
Operational issues with the M10:

PowerSave doesn't work with SBAS, seems like you can have SBAS enabled, but it will never lock
onto the SBAS sats.
PowerSave doesn't work with BDS B1C, u-blox says use B1l instead.
BDS B1l cannot be enabled with BDS B1C or GLONASS L1OF, so GLONASS will work with B1C, but not B1l
So no powersave with GLONASS and BDS B1l enabled.
So disable GLONASS and use BDS B1l, which is part of the default M10 config.

GNSS configuration:

Default GNSS configuration is: GPS, Galileo, BDS B1l, with QZSS and SBAS enabled.
The PMREQ puts the receiver to sleep and wakeup re-acquires really fast and seems to not need
the PM config. Lets try without it.
PMREQ sort of works with SBAS, but the awake time is too short to re-acquire any SBAS sats.
The defination of "Got Fix" doesn't seem to include SBAS. Much more too this...
Even if it was, it can take minutes (up to 12.5),
even under good sat visibility conditions to re-acquire the SBAS data.

Another effect fo the quick transition to sleep is that no other sats will be acquired so the
sat count will tend to remain at what the initial fix was.
*/

// GNSS disable SBAS as recommended by u-blox if using GNSS defaults and power save mode
/*
Ram layer config message:
b5 62 06 8a 0e 00 00 01 00 00 20 00 31 10 00 05 00 31 10 00 46 87

BBR layer config message:
b5 62 06 8a 0e 00 00 02 00 00 20 00 31 10 00 05 00 31 10 00 47 94
*/
