mirror of
https://github.com/meshtastic/firmware.git
synced 2025-09-19 16:29:31 +00:00
Merge branch 'meshtastic:master' into master
This commit is contained in:
commit
f1e3f42aa5
@ -1 +1 @@
|
||||
Subproject commit 388fd79bf78df2c59dd0bdd029a382fa91b1cd88
|
||||
Subproject commit 4432d3bfc155107e27079d96ddba16b52f2d9ea3
|
161
src/gps/GPS.cpp
161
src/gps/GPS.cpp
@ -358,87 +358,98 @@ bool GPS::setup()
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
// Disable Text Info messages
|
||||
msglen = makeUBXPacket(0x06, 0x02, sizeof(_message_DISABLE_TXT_INFO), _message_DISABLE_TXT_INFO);
|
||||
clearBuffer();
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x02, 500) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to disable text info messages.\n");
|
||||
}
|
||||
// ToDo add M10 tests for below
|
||||
if (strncmp(info.hwVersion, "00080000", 8) == 0) {
|
||||
msglen = makeUBXPacket(0x06, 0x39, sizeof(_message_JAM_8), _message_JAM_8);
|
||||
clearBuffer();
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x39, 300) != GNSS_RESPONSE_OK) {
|
||||
if (getACK(0x06, 0x39, 500) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable interference resistance.\n");
|
||||
}
|
||||
clearBuffer();
|
||||
|
||||
msglen = makeUBXPacket(0x06, 0x23, sizeof(_message_NAVX5_8), _message_NAVX5_8);
|
||||
clearBuffer();
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x23, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to configure extra settings.\n");
|
||||
if (getACK(0x06, 0x23, 500) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to configure NAVX5_8 settings.\n");
|
||||
}
|
||||
} else {
|
||||
msglen = makeUBXPacket(0x06, 0x39, sizeof(_message_JAM_6_7), _message_JAM_6_7);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x39, 300) != GNSS_RESPONSE_OK) {
|
||||
if (getACK(0x06, 0x39, 500) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable interference resistance.\n");
|
||||
}
|
||||
|
||||
msglen = makeUBXPacket(0x06, 0x23, sizeof(_message_NAVX5), _message_NAVX5);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x23, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to configure extra settings.\n");
|
||||
if (getACK(0x06, 0x23, 500) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to configure NAVX5 settings.\n");
|
||||
}
|
||||
}
|
||||
// ublox-M10S can be compatible with UBLOX traditional protocol, so the following sentence settings are also valid
|
||||
// Turn off unwanted NMEA messages, set update rate
|
||||
|
||||
msglen = makeUBXPacket(0x06, 0x08, sizeof(_message_1HZ), _message_1HZ);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x08, 400) != GNSS_RESPONSE_OK) {
|
||||
if (getACK(0x06, 0x08, 500) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to set GPS update rate.\n");
|
||||
}
|
||||
|
||||
msglen = makeUBXPacket(0x06, 0x01, sizeof(_message_GLL), _message_GLL);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) {
|
||||
if (getACK(0x06, 0x01, 500) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to disable NMEA GLL.\n");
|
||||
}
|
||||
|
||||
msglen = makeUBXPacket(0x06, 0x01, sizeof(_message_GSA), _message_GSA);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) {
|
||||
if (getACK(0x06, 0x01, 500) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to Enable NMEA GSA.\n");
|
||||
}
|
||||
|
||||
msglen = makeUBXPacket(0x06, 0x01, sizeof(_message_GSV), _message_GSV);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) {
|
||||
if (getACK(0x06, 0x01, 500) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to disable NMEA GSV.\n");
|
||||
}
|
||||
|
||||
msglen = makeUBXPacket(0x06, 0x01, sizeof(_message_VTG), _message_VTG);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) {
|
||||
if (getACK(0x06, 0x01, 500) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to disable NMEA VTG.\n");
|
||||
}
|
||||
|
||||
msglen = makeUBXPacket(0x06, 0x01, sizeof(_message_RMC), _message_RMC);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) {
|
||||
if (getACK(0x06, 0x01, 500) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable NMEA RMC.\n");
|
||||
}
|
||||
|
||||
msglen = makeUBXPacket(0x06, 0x01, sizeof(_message_GGA), _message_GGA);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) {
|
||||
if (getACK(0x06, 0x01, 500) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable NMEA GGA.\n");
|
||||
}
|
||||
clearBuffer();
|
||||
|
||||
if (uBloxProtocolVersion >= 18) {
|
||||
msglen = makeUBXPacket(0x06, 0x86, sizeof(_message_PMS), _message_PMS);
|
||||
clearBuffer();
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x86, 300) != GNSS_RESPONSE_OK) {
|
||||
if (getACK(0x06, 0x86, 500) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable powersaving for GPS.\n");
|
||||
}
|
||||
// For M8 we want to enable NMEA vserion 4.10 so we can see the additional sats.
|
||||
if (strncmp(info.hwVersion, "00080000", 8) == 0) {
|
||||
msglen = makeUBXPacket(0x06, 0x17, sizeof(_message_NMEA), _message_NMEA);
|
||||
clearBuffer();
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x17, 400) != GNSS_RESPONSE_OK) {
|
||||
if (getACK(0x06, 0x17, 500) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable NMEA 4.10.\n");
|
||||
}
|
||||
}
|
||||
@ -447,23 +458,23 @@ bool GPS::setup()
|
||||
if (strncmp(info.hwVersion, "00040007", 8) == 0) { // This PSM mode is only for Neo-6
|
||||
msglen = makeUBXPacket(0x06, 0x11, 0x2, _message_CFG_RXM_ECO);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x11, 300) != GNSS_RESPONSE_OK) {
|
||||
if (getACK(0x06, 0x11, 500) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable powersaving ECO mode for Neo-6.\n");
|
||||
}
|
||||
msglen = makeUBXPacket(0x06, 0x3B, 44, _message_CFG_PM2);
|
||||
msglen = makeUBXPacket(0x06, 0x3B, sizeof(_message_CFG_PM2), _message_CFG_PM2);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x3B, 300) != GNSS_RESPONSE_OK) {
|
||||
if (getACK(0x06, 0x3B, 500) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable powersaving details for GPS.\n");
|
||||
}
|
||||
msglen = makeUBXPacket(0x06, 0x01, sizeof(_message_AID), _message_AID);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x01, 300) != GNSS_RESPONSE_OK) {
|
||||
if (getACK(0x06, 0x01, 500) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to disable UBX-AID.\n");
|
||||
}
|
||||
} else {
|
||||
msglen = makeUBXPacket(0x06, 0x11, 0x2, _message_CFG_RXM_PSM);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x11, 300) != GNSS_RESPONSE_OK) {
|
||||
if (getACK(0x06, 0x11, 500) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable powersaving mode for GPS.\n");
|
||||
}
|
||||
}
|
||||
@ -477,7 +488,96 @@ bool GPS::setup()
|
||||
LOG_INFO("GNSS module configuration saved!\n");
|
||||
}
|
||||
} else {
|
||||
LOG_INFO("u-blox M10 hardware found, using defaults for now\n");
|
||||
// LOG_INFO("u-blox M10 hardware found.\n");
|
||||
delay(1000);
|
||||
// First disable all NMEA messages in RAM layer
|
||||
msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_DISABLE_NMEA_RAM), _message_VALSET_DISABLE_NMEA_RAM);
|
||||
clearBuffer();
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to disable NMEA messages for M10 GPS RAM.\n");
|
||||
}
|
||||
delay(250);
|
||||
// Next disable unwanted NMEA messages in BBR layer
|
||||
msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_DISABLE_NMEA_BBR), _message_VALSET_DISABLE_NMEA_BBR);
|
||||
clearBuffer();
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to disable NMEA messages for M10 GPS BBR.\n");
|
||||
}
|
||||
delay(250);
|
||||
// Disable Info txt messages in RAM layer
|
||||
msglen =
|
||||
makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_DISABLE_TXT_INFO_RAM), _message_VALSET_DISABLE_TXT_INFO_RAM);
|
||||
clearBuffer();
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to disable Info messages for M10 GPS RAM.\n");
|
||||
}
|
||||
delay(250);
|
||||
// Next disable Info txt messages in BBR layer
|
||||
msglen =
|
||||
makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_DISABLE_TXT_INFO_BBR), _message_VALSET_DISABLE_TXT_INFO_BBR);
|
||||
clearBuffer();
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to disable Info messages for M10 GPS BBR.\n");
|
||||
}
|
||||
// Do M10 configuration for Power Management.
|
||||
|
||||
msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_PM_RAM), _message_VALSET_PM_RAM);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable powersaving for M10 GPS RAM.\n");
|
||||
}
|
||||
msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_PM_BBR), _message_VALSET_PM_BBR);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable powersaving for M10 GPS BBR.\n");
|
||||
}
|
||||
|
||||
delay(250);
|
||||
msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_ITFM_RAM), _message_VALSET_ITFM_RAM);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable Jamming detection M10 GPS RAM.\n");
|
||||
}
|
||||
msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_ITFM_BBR), _message_VALSET_ITFM_BBR);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable Jamming detection M10 GPS BBR.\n");
|
||||
}
|
||||
|
||||
// Here is where the init commands should go to do further M10 initialization.
|
||||
delay(250);
|
||||
msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_DISABLE_SBAS_RAM), _message_VALSET_DISABLE_SBAS_RAM);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to disable SBAS M10 GPS RAM.\n");
|
||||
}
|
||||
delay(750); // will cause a receiver restart so wait a bit
|
||||
msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_DISABLE_SBAS_BBR), _message_VALSET_DISABLE_SBAS_BBR);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to disable SBAS M10 GPS BBR.\n");
|
||||
}
|
||||
delay(750); // will cause a receiver restart so wait a bit
|
||||
// Done with initialization, Now enable wanted NMEA messages in BBR layer so they will survive a periodic sleep.
|
||||
msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_ENABLE_NMEA_BBR), _message_VALSET_ENABLE_NMEA_BBR);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable messages for M10 GPS BBR.\n");
|
||||
}
|
||||
delay(250);
|
||||
// Next enable wanted NMEA messages in RAM layer
|
||||
msglen = makeUBXPacket(0x06, 0x8A, sizeof(_message_VALSET_ENABLE_NMEA_RAM), _message_VALSET_ENABLE_NMEA_RAM);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACK(0x06, 0x8A, 300) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("Unable to enable messages for M10 GPS RAM.\n");
|
||||
}
|
||||
// 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.
|
||||
}
|
||||
}
|
||||
didSerialInit = true;
|
||||
@ -547,10 +647,17 @@ void GPS::setGPSPower(bool on, bool standbyOnly, uint32_t sleepTime)
|
||||
if (gnssModel == GNSS_MODEL_UBLOX) {
|
||||
uint8_t msglen;
|
||||
LOG_DEBUG("Sleep Time: %i\n", sleepTime);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
gps->_message_PMREQ[0 + i] = sleepTime >> (i * 8); // Encode the sleep time in millis into the packet
|
||||
if (strncmp(info.hwVersion, "000A0000", 8) != 0) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
gps->_message_PMREQ[0 + i] = sleepTime >> (i * 8); // Encode the sleep time in millis into the packet
|
||||
}
|
||||
msglen = gps->makeUBXPacket(0x02, 0x41, sizeof(_message_PMREQ), gps->_message_PMREQ);
|
||||
} else {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
gps->_message_PMREQ_10[4 + i] = sleepTime >> (i * 8); // Encode the sleep time in millis into the packet
|
||||
}
|
||||
msglen = gps->makeUBXPacket(0x02, 0x41, sizeof(_message_PMREQ_10), gps->_message_PMREQ_10);
|
||||
}
|
||||
msglen = gps->makeUBXPacket(0x02, 0x41, 0x08, gps->_message_PMREQ);
|
||||
gps->_serial_gps->write(gps->UBXscratch, msglen);
|
||||
}
|
||||
} else {
|
||||
|
@ -106,6 +106,7 @@ class GPS : private concurrency::OSThread
|
||||
static const uint8_t _message_NAVX5[];
|
||||
static const uint8_t _message_NAVX5_8[];
|
||||
static const uint8_t _message_NMEA[];
|
||||
static const uint8_t _message_DISABLE_TXT_INFO[];
|
||||
static const uint8_t _message_1HZ[];
|
||||
static const uint8_t _message_GLL[];
|
||||
static const uint8_t _message_GSA[];
|
||||
@ -117,6 +118,21 @@ class GPS : private concurrency::OSThread
|
||||
static const uint8_t _message_PMS[];
|
||||
static const uint8_t _message_SAVE[];
|
||||
|
||||
// VALSET Commands for M10
|
||||
static const uint8_t _message_VALSET_PM[];
|
||||
static const uint8_t _message_VALSET_PM_RAM[];
|
||||
static const uint8_t _message_VALSET_PM_BBR[];
|
||||
static const uint8_t _message_VALSET_ITFM_RAM[];
|
||||
static const uint8_t _message_VALSET_ITFM_BBR[];
|
||||
static const uint8_t _message_VALSET_DISABLE_NMEA_RAM[];
|
||||
static const uint8_t _message_VALSET_DISABLE_NMEA_BBR[];
|
||||
static const uint8_t _message_VALSET_DISABLE_TXT_INFO_RAM[];
|
||||
static const uint8_t _message_VALSET_DISABLE_TXT_INFO_BBR[];
|
||||
static const uint8_t _message_VALSET_ENABLE_NMEA_RAM[];
|
||||
static const uint8_t _message_VALSET_ENABLE_NMEA_BBR[];
|
||||
static const uint8_t _message_VALSET_DISABLE_SBAS_RAM[];
|
||||
static const uint8_t _message_VALSET_DISABLE_SBAS_BBR[];
|
||||
|
||||
meshtastic_Position p = meshtastic_Position_init_default;
|
||||
|
||||
GPS() : concurrency::OSThread("GPS") {}
|
||||
|
175
src/gps/ubx.h
175
src/gps/ubx.h
@ -1,16 +1,16 @@
|
||||
// Power Management
|
||||
|
||||
uint8_t GPS::_message_PMREQ[] PROGMEM = {
|
||||
0x00, 0x00, // 4 bytes duration of request task
|
||||
0x00, 0x00, // (milliseconds)
|
||||
0x02, 0x00, // Task flag bitfield
|
||||
0x00, 0x00, // byte index 1 = sleep mode
|
||||
0x00, 0x00, 0x00, 0x00, // 4 bytes duration of request task (milliseconds)
|
||||
0x02, 0x00, 0x00, 0x00 // Bitfield, set backup = 1
|
||||
};
|
||||
|
||||
uint8_t GPS::_message_PMREQ_10[] PROGMEM = {
|
||||
0x00, 0x00, // 4 bytes duration of request task
|
||||
0x00, 0x00, // (milliseconds)
|
||||
0x02, 0x00, // Task flag bitfield
|
||||
0x00, 0x00, // byte index 1 = sleep mode
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // wakeupSources
|
||||
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
|
||||
};
|
||||
|
||||
const uint8_t GPS::_message_CFG_RXM_PSM[] PROGMEM = {
|
||||
@ -46,6 +46,9 @@ const uint8_t GPS::_message_CFG_PM2[] PROGMEM = {
|
||||
0x00, 0x00, 0x00, 0x00 // 0x64, 0x40, 0x01, 0x00 // reserved 11
|
||||
};
|
||||
|
||||
// Constallation setup, none required for Neo-6
|
||||
|
||||
// For Neo-7 GPS & SBAS
|
||||
const uint8_t GPS::_message_GNSS_7[] = {
|
||||
0x00, // msgVer (0 for this version)
|
||||
0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0)
|
||||
@ -272,6 +275,20 @@ const uint8_t GPS::_message_AID[] = {
|
||||
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
|
||||
const uint8_t GPS::_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.
|
||||
@ -283,7 +300,7 @@ const uint8_t GPS::_message_AID[] = {
|
||||
// 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 and higher products
|
||||
// This command applies to M8 products
|
||||
const uint8_t GPS::_message_PMS[] = {
|
||||
0x00, // Version (0)
|
||||
0x03, // Power setup value 3 = Agresssive 1Hz
|
||||
@ -297,4 +314,140 @@ const uint8_t GPS::_message_SAVE[] = {
|
||||
0xFF, 0xFF, 0x00, 0x00, // saveMask: save all sections
|
||||
0x00, 0x00, 0x00, 0x00, // loadMask: no sections loaded
|
||||
0x17 // deviceMask: BBR, Flash, EEPROM, and SPI Flash
|
||||
};
|
||||
};
|
||||
|
||||
// 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.
|
||||
|
||||
// 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.
|
||||
/*
|
||||
CFG-PM2 has been replaced by many CFG-PM commands
|
||||
OPERATEMODE E1 2 (0 | 1 | 2)
|
||||
POSUPDATEPERIOD U4 1000ms for M10 must be >= 5s try 5
|
||||
ACQPERIOD U4 10 seems ok for M10 def ok
|
||||
GRIDOFFSET U4 0 seems ok for M10 def ok
|
||||
ONTIME U2 1 will try 1
|
||||
MINACQTIME U1 0 will try 0 def ok
|
||||
MAXACQTIME U1 stick with default of 0 def ok
|
||||
DONOTENTEROFF L 1 stay at 1
|
||||
WAITTIMEFIX L 1 stay with 1
|
||||
UPDATEEPH L 1 changed to 1 for gps rework default is 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 stay with 1
|
||||
*/
|
||||
// CFG-PMS has been removed
|
||||
|
||||
// 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
|
||||
|
||||
const uint8_t GPS::_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};
|
||||
const uint8_t GPS::_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
|
||||
*/
|
||||
const uint8_t GPS::_message_VALSET_ITFM_RAM[] = {0x00, 0x01, 0x00, 0x00, 0x0d, 0x00, 0x41,
|
||||
0x10, 0x01, 0x13, 0x00, 0x41, 0x10, 0x01};
|
||||
const uint8_t GPS::_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
|
||||
|
||||
const uint8_t GPS::_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};
|
||||
|
||||
const uint8_t GPS::_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 GSA, GGA, RMC messages on:
|
||||
// Ram layer config message:
|
||||
// b5 62 06 8a 13 00 00 01 00 00 c0 00 91 20 01 bb 00 91 20 01 ac 00 91 20 01 e1 3b
|
||||
|
||||
// BBR layer config message:
|
||||
// b5 62 06 8a 13 00 00 02 00 00 c0 00 91 20 01 bb 00 91 20 01 ac 00 91 20 01 e2 4d
|
||||
|
||||
const uint8_t GPS::_message_VALSET_DISABLE_TXT_INFO_RAM[] = {0x00, 0x01, 0x00, 0x00, 0x07, 0x00, 0x92, 0x20, 0x03};
|
||||
const uint8_t GPS::_message_VALSET_DISABLE_TXT_INFO_BBR[] = {0x00, 0x02, 0x00, 0x00, 0x07, 0x00, 0x92, 0x20, 0x03};
|
||||
const uint8_t GPS::_message_VALSET_ENABLE_NMEA_RAM[] = {0x00, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x91, 0x20, 0x01, 0xbb,
|
||||
0x00, 0x91, 0x20, 0x01, 0xac, 0x00, 0x91, 0x20, 0x01};
|
||||
const uint8_t GPS::_message_VALSET_ENABLE_NMEA_BBR[] = {0x00, 0x02, 0x00, 0x00, 0xc0, 0x00, 0x91, 0x20, 0x01, 0xbb,
|
||||
0x00, 0x91, 0x20, 0x01, 0xac, 0x00, 0x91, 0x20, 0x01};
|
||||
const uint8_t GPS::_message_VALSET_DISABLE_SBAS_RAM[] = {0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x31,
|
||||
0x10, 0x00, 0x05, 0x00, 0x31, 0x10, 0x00};
|
||||
const uint8_t GPS::_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 visability 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
|
||||
*/
|
@ -12,46 +12,45 @@
|
||||
/* Enum definitions */
|
||||
/* Defines the device's role on the Mesh network */
|
||||
typedef enum _meshtastic_Config_DeviceConfig_Role {
|
||||
/* Client device role */
|
||||
/* Description: App connected or stand alone messaging device.
|
||||
Technical Details: Default Role */
|
||||
meshtastic_Config_DeviceConfig_Role_CLIENT = 0,
|
||||
/* Client Mute device role
|
||||
Same as a client except packets will not hop over this node, does not contribute to routing packets for mesh. */
|
||||
/* Description: Device that does not forward packets from other devices. */
|
||||
meshtastic_Config_DeviceConfig_Role_CLIENT_MUTE = 1,
|
||||
/* Router device role.
|
||||
Mesh packets will prefer to be routed over this node. This node will not be used by client apps.
|
||||
The wifi/ble radios and the oled screen will be put to sleep.
|
||||
/* Description: Infrastructure node for extending network coverage by relaying messages. Visible in Nodes list.
|
||||
Technical Details: Mesh packets will prefer to be routed over this node. This node will not be used by client apps.
|
||||
The wifi radio and the oled screen will be put to sleep.
|
||||
This mode may still potentially have higher power usage due to it's preference in message rebroadcasting on the mesh. */
|
||||
meshtastic_Config_DeviceConfig_Role_ROUTER = 2,
|
||||
/* Router Client device role
|
||||
Mesh packets will prefer to be routed over this node. The Router Client can be used as both a Router and an app connected Client. */
|
||||
/* Description: Combination of both ROUTER and CLIENT. Not for mobile devices. */
|
||||
meshtastic_Config_DeviceConfig_Role_ROUTER_CLIENT = 3,
|
||||
/* Repeater device role
|
||||
Mesh packets will simply be rebroadcasted over this node. Nodes configured with this role will not originate NodeInfo, Position, Telemetry
|
||||
/* Description: Infrastructure node for extending network coverage by relaying messages with minimal overhead. Not visible in Nodes list.
|
||||
Technical Details: Mesh packets will simply be rebroadcasted over this node. Nodes configured with this role will not originate NodeInfo, Position, Telemetry
|
||||
or any other packet type. They will simply rebroadcast any mesh packets on the same frequency, channel num, spread factor, and coding rate. */
|
||||
meshtastic_Config_DeviceConfig_Role_REPEATER = 4,
|
||||
/* Tracker device role
|
||||
Position Mesh packets will be prioritized higher and sent more frequently by default.
|
||||
/* Description: Broadcasts GPS position packets as priority.
|
||||
Technical Details: Position Mesh packets will be prioritized higher and sent more frequently by default.
|
||||
When used in conjunction with power.is_power_saving = true, nodes will wake up,
|
||||
send position, and then sleep for position.position_broadcast_secs seconds. */
|
||||
meshtastic_Config_DeviceConfig_Role_TRACKER = 5,
|
||||
/* Sensor device role
|
||||
Telemetry Mesh packets will be prioritized higher and sent more frequently by default.
|
||||
/* Description: Broadcasts telemetry packets as priority.
|
||||
Technical Details: Telemetry Mesh packets will be prioritized higher and sent more frequently by default.
|
||||
When used in conjunction with power.is_power_saving = true, nodes will wake up,
|
||||
send environment telemetry, and then sleep for telemetry.environment_update_interval seconds. */
|
||||
meshtastic_Config_DeviceConfig_Role_SENSOR = 6,
|
||||
/* TAK device role
|
||||
Used for nodes dedicated for connection to an ATAK EUD.
|
||||
/* Description: Optimized for ATAK system communication, reduces routine broadcasts.
|
||||
Technical Details: Used for nodes dedicated for connection to an ATAK EUD.
|
||||
Turns off many of the routine broadcasts to favor CoT packet stream
|
||||
from the Meshtastic ATAK plugin -> IMeshService -> Node */
|
||||
meshtastic_Config_DeviceConfig_Role_TAK = 7,
|
||||
/* Client Hidden device role
|
||||
Used for nodes that "only speak when spoken to"
|
||||
/* Description: Device that only broadcasts as needed for stealth or power savings.
|
||||
Technical Details: Used for nodes that "only speak when spoken to"
|
||||
Turns all of the routine broadcasts but allows for ad-hoc communication
|
||||
Still rebroadcasts, but with local only rebroadcast mode (known meshes only)
|
||||
Can be used for clandestine operation or to dramatically reduce airtime / power consumption */
|
||||
meshtastic_Config_DeviceConfig_Role_CLIENT_HIDDEN = 8,
|
||||
/* Lost and Found device role
|
||||
Used to automatically send a text message to the mesh
|
||||
/* Description: Broadcasts location as message to default channel regularly for to assist with device recovery.
|
||||
Technical Details: Used to automatically send a text message to the mesh
|
||||
with the current position of the device on a frequent interval:
|
||||
"I'm lost! Position: lat / long" */
|
||||
meshtastic_Config_DeviceConfig_Role_LOST_AND_FOUND = 9
|
||||
@ -313,6 +312,9 @@ typedef struct _meshtastic_Config_PositionConfig {
|
||||
uint32_t gps_en_gpio;
|
||||
/* Set where GPS is enabled, disabled, or not present */
|
||||
meshtastic_Config_PositionConfig_GpsMode gps_mode;
|
||||
/* Set GPS precision in bits per channel, or 0 for disabled */
|
||||
pb_size_t channel_precision_count;
|
||||
uint32_t channel_precision[8];
|
||||
} meshtastic_Config_PositionConfig;
|
||||
|
||||
/* Power Config\
|
||||
@ -580,7 +582,7 @@ extern "C" {
|
||||
/* Initializer values for message structs */
|
||||
#define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}}
|
||||
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0}
|
||||
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
||||
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN, 0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||
#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""}
|
||||
#define meshtastic_Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0}
|
||||
@ -589,7 +591,7 @@ extern "C" {
|
||||
#define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
|
||||
#define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}}
|
||||
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0}
|
||||
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
||||
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN, 0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||
#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""}
|
||||
#define meshtastic_Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0}
|
||||
@ -621,6 +623,7 @@ extern "C" {
|
||||
#define meshtastic_Config_PositionConfig_broadcast_smart_minimum_interval_secs_tag 11
|
||||
#define meshtastic_Config_PositionConfig_gps_en_gpio_tag 12
|
||||
#define meshtastic_Config_PositionConfig_gps_mode_tag 13
|
||||
#define meshtastic_Config_PositionConfig_channel_precision_tag 14
|
||||
#define meshtastic_Config_PowerConfig_is_power_saving_tag 1
|
||||
#define meshtastic_Config_PowerConfig_on_battery_shutdown_after_secs_tag 2
|
||||
#define meshtastic_Config_PowerConfig_adc_multiplier_override_tag 3
|
||||
@ -724,7 +727,8 @@ X(a, STATIC, SINGULAR, UINT32, tx_gpio, 9) \
|
||||
X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_distance, 10) \
|
||||
X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_interval_secs, 11) \
|
||||
X(a, STATIC, SINGULAR, UINT32, gps_en_gpio, 12) \
|
||||
X(a, STATIC, SINGULAR, UENUM, gps_mode, 13)
|
||||
X(a, STATIC, SINGULAR, UENUM, gps_mode, 13) \
|
||||
X(a, STATIC, REPEATED, UINT32, channel_precision, 14)
|
||||
#define meshtastic_Config_PositionConfig_CALLBACK NULL
|
||||
#define meshtastic_Config_PositionConfig_DEFAULT NULL
|
||||
|
||||
@ -830,7 +834,7 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg;
|
||||
#define meshtastic_Config_LoRaConfig_size 80
|
||||
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
|
||||
#define meshtastic_Config_NetworkConfig_size 196
|
||||
#define meshtastic_Config_PositionConfig_size 62
|
||||
#define meshtastic_Config_PositionConfig_size 110
|
||||
#define meshtastic_Config_PowerConfig_size 40
|
||||
#define meshtastic_Config_size 199
|
||||
|
||||
|
@ -316,7 +316,7 @@ extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePin_msg;
|
||||
#define meshtastic_DeviceState_size 17062
|
||||
#define meshtastic_NodeInfoLite_size 153
|
||||
#define meshtastic_NodeRemoteHardwarePin_size 29
|
||||
#define meshtastic_OEMStore_size 3246
|
||||
#define meshtastic_OEMStore_size 3294
|
||||
#define meshtastic_PositionLite_size 28
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -180,7 +180,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
|
||||
#define meshtastic_LocalModuleConfig_fields &meshtastic_LocalModuleConfig_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define meshtastic_LocalConfig_size 469
|
||||
#define meshtastic_LocalConfig_size 517
|
||||
#define meshtastic_LocalModuleConfig_size 631
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -111,7 +111,7 @@ typedef enum _meshtastic_HardwareModel {
|
||||
meshtastic_HardwareModel_RPI_PICO = 47,
|
||||
/* Heltec Wireless Tracker with ESP32-S3 CPU, built-in GPS, and TFT
|
||||
Newer V1.1, version is written on the PCB near the display. */
|
||||
meshtastic_HardwareModel_HELTEC_WIRELESS_TRACKER_V1_1 = 48,
|
||||
meshtastic_HardwareModel_HELTEC_WIRELESS_TRACKER = 48,
|
||||
/* Heltec Wireless Paper with ESP32-S3 CPU and E-Ink display */
|
||||
meshtastic_HardwareModel_HELTEC_WIRELESS_PAPER = 49,
|
||||
/* LilyGo T-Deck with ESP32-S3 CPU, Keyboard and IPS display */
|
||||
|
@ -38,16 +38,11 @@ int32_t StoreForwardModule::runOnce()
|
||||
// Only send packets if the channel is less than 25% utilized.
|
||||
if (airTime->isTxAllowedChannelUtil(true)) {
|
||||
storeForwardModule->sendPayload(this->busyTo, this->packetHistoryTXQueue_index);
|
||||
if (this->packetHistoryTXQueue_index == packetHistoryTXQueue_size) {
|
||||
// Tell the client we're done sending
|
||||
meshtastic_StoreAndForward sf = meshtastic_StoreAndForward_init_zero;
|
||||
sf.rr = meshtastic_StoreAndForward_RequestResponse_ROUTER_PING;
|
||||
storeForwardModule->sendMessage(this->busyTo, sf);
|
||||
LOG_INFO("*** S&F - Done. (ROUTER_PING)\n");
|
||||
if (this->packetHistoryTXQueue_index < packetHistoryTXQueue_size - 1) {
|
||||
this->packetHistoryTXQueue_index++;
|
||||
} else {
|
||||
this->packetHistoryTXQueue_index = 0;
|
||||
this->busy = false;
|
||||
} else {
|
||||
this->packetHistoryTXQueue_index++;
|
||||
}
|
||||
}
|
||||
} else if ((millis() - lastHeartbeat > (heartbeatInterval * 1000)) && airTime->isTxAllowedChannelUtil(true)) {
|
||||
@ -56,7 +51,7 @@ int32_t StoreForwardModule::runOnce()
|
||||
meshtastic_StoreAndForward sf = meshtastic_StoreAndForward_init_zero;
|
||||
sf.rr = meshtastic_StoreAndForward_RequestResponse_ROUTER_HEARTBEAT;
|
||||
sf.which_variant = meshtastic_StoreAndForward_heartbeat_tag;
|
||||
sf.variant.heartbeat.period = 300;
|
||||
sf.variant.heartbeat.period = heartbeatInterval;
|
||||
sf.variant.heartbeat.secondary = 0; // TODO we always have one primary router for now
|
||||
storeForwardModule->sendMessage(NODENUM_BROADCAST, sf);
|
||||
}
|
||||
@ -101,10 +96,11 @@ void StoreForwardModule::populatePSRAM()
|
||||
*
|
||||
* @param msAgo The number of milliseconds ago from which to start sending messages.
|
||||
* @param to The recipient ID to send the messages to.
|
||||
* @param last_request_index The index in the packet history of the last request from this node.
|
||||
*/
|
||||
void StoreForwardModule::historySend(uint32_t msAgo, uint32_t to)
|
||||
void StoreForwardModule::historySend(uint32_t msAgo, uint32_t to, uint32_t last_request_index)
|
||||
{
|
||||
uint32_t queueSize = storeForwardModule->historyQueueCreate(msAgo, to);
|
||||
uint32_t queueSize = storeForwardModule->historyQueueCreate(msAgo, to, &last_request_index);
|
||||
|
||||
if (queueSize) {
|
||||
LOG_INFO("*** S&F - Sending %u message(s)\n", queueSize);
|
||||
@ -118,6 +114,7 @@ void StoreForwardModule::historySend(uint32_t msAgo, uint32_t to)
|
||||
sf.which_variant = meshtastic_StoreAndForward_history_tag;
|
||||
sf.variant.history.history_messages = queueSize;
|
||||
sf.variant.history.window = msAgo;
|
||||
sf.variant.history.last_request = last_request_index;
|
||||
storeForwardModule->sendMessage(to, sf);
|
||||
}
|
||||
|
||||
@ -125,15 +122,18 @@ void StoreForwardModule::historySend(uint32_t msAgo, uint32_t to)
|
||||
* Creates a new history queue with messages that were received within the specified time frame.
|
||||
*
|
||||
* @param msAgo The number of milliseconds ago to start the history queue.
|
||||
* @param to The maximum number of messages to include in the history queue.
|
||||
* @param to The NodeNum of the recipient.
|
||||
* @param last_request_index The index in the packet history of the last request from this node.
|
||||
* @return The ID of the newly created history queue.
|
||||
*/
|
||||
uint32_t StoreForwardModule::historyQueueCreate(uint32_t msAgo, uint32_t to)
|
||||
uint32_t StoreForwardModule::historyQueueCreate(uint32_t msAgo, uint32_t to, uint32_t *last_request_index)
|
||||
{
|
||||
|
||||
this->packetHistoryTXQueue_size = 0;
|
||||
// If our history was cleared, ignore what the client is telling us
|
||||
uint32_t last_index = *last_request_index >= this->packetHistoryCurrent ? 0 : *last_request_index;
|
||||
|
||||
for (int i = 0; i < this->packetHistoryCurrent; i++) {
|
||||
for (int i = last_index; i < this->packetHistoryCurrent; i++) {
|
||||
/*
|
||||
LOG_DEBUG("SF historyQueueCreate\n");
|
||||
LOG_DEBUG("SF historyQueueCreate - time %d\n", this->packetHistory[i].time);
|
||||
@ -141,16 +141,11 @@ uint32_t StoreForwardModule::historyQueueCreate(uint32_t msAgo, uint32_t to)
|
||||
LOG_DEBUG("SF historyQueueCreate - math %d\n", (millis() - msAgo));
|
||||
*/
|
||||
if (this->packetHistory[i].time && (this->packetHistory[i].time < (millis() - msAgo))) {
|
||||
LOG_DEBUG("*** SF historyQueueCreate - Time matches - ok\n");
|
||||
/*
|
||||
Copy the messages that were received by the router in the last msAgo
|
||||
/* Copy the messages that were received by the router in the last msAgo
|
||||
to the packetHistoryTXQueue structure.
|
||||
|
||||
TODO: The condition (this->packetHistory[i].to & NODENUM_BROADCAST) == to) is not tested since
|
||||
I don't have an easy way to target a specific user. Will need to do this soon.
|
||||
*/
|
||||
if ((this->packetHistory[i].to & NODENUM_BROADCAST) == NODENUM_BROADCAST ||
|
||||
((this->packetHistory[i].to & NODENUM_BROADCAST) == to)) {
|
||||
Client not interested in packets from itself and only in broadcast packets or packets towards it. */
|
||||
if (this->packetHistory[i].from != to &&
|
||||
(this->packetHistory[i].to == NODENUM_BROADCAST || this->packetHistory[i].to == to)) {
|
||||
this->packetHistoryTXQueue[this->packetHistoryTXQueue_size].time = this->packetHistory[i].time;
|
||||
this->packetHistoryTXQueue[this->packetHistoryTXQueue_size].to = this->packetHistory[i].to;
|
||||
this->packetHistoryTXQueue[this->packetHistoryTXQueue_size].from = this->packetHistory[i].from;
|
||||
@ -159,9 +154,10 @@ uint32_t StoreForwardModule::historyQueueCreate(uint32_t msAgo, uint32_t to)
|
||||
memcpy(this->packetHistoryTXQueue[this->packetHistoryTXQueue_size].payload, this->packetHistory[i].payload,
|
||||
meshtastic_Constants_DATA_PAYLOAD_LEN);
|
||||
this->packetHistoryTXQueue_size++;
|
||||
*last_request_index = i + 1; // Set to one higher such that we don't send the same message again
|
||||
|
||||
LOG_DEBUG("*** PacketHistoryStruct time=%d\n", this->packetHistory[i].time);
|
||||
LOG_DEBUG("*** PacketHistoryStruct msg=%s\n", this->packetHistory[i].payload);
|
||||
LOG_DEBUG("*** PacketHistoryStruct time=%d, msg=%s\n", this->packetHistory[i].time,
|
||||
this->packetHistory[i].payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -177,15 +173,20 @@ void StoreForwardModule::historyAdd(const meshtastic_MeshPacket &mp)
|
||||
{
|
||||
const auto &p = mp.decoded;
|
||||
|
||||
this->packetHistory[this->packetHistoryCurrent].time = millis();
|
||||
this->packetHistory[this->packetHistoryCurrent].to = mp.to;
|
||||
this->packetHistory[this->packetHistoryCurrent].channel = mp.channel;
|
||||
this->packetHistory[this->packetHistoryCurrent].from = mp.from;
|
||||
this->packetHistory[this->packetHistoryCurrent].payload_size = p.payload.size;
|
||||
memcpy(this->packetHistory[this->packetHistoryCurrent].payload, p.payload.bytes, meshtastic_Constants_DATA_PAYLOAD_LEN);
|
||||
if (this->packetHistoryCurrent < this->records) {
|
||||
this->packetHistory[this->packetHistoryCurrent].time = millis();
|
||||
this->packetHistory[this->packetHistoryCurrent].to = mp.to;
|
||||
this->packetHistory[this->packetHistoryCurrent].channel = mp.channel;
|
||||
this->packetHistory[this->packetHistoryCurrent].from = mp.from;
|
||||
this->packetHistory[this->packetHistoryCurrent].payload_size = p.payload.size;
|
||||
memcpy(this->packetHistory[this->packetHistoryCurrent].payload, p.payload.bytes, meshtastic_Constants_DATA_PAYLOAD_LEN);
|
||||
|
||||
this->packetHistoryCurrent++;
|
||||
this->packetHistoryMax++;
|
||||
this->packetHistoryCurrent++;
|
||||
this->packetHistoryMax++;
|
||||
} else {
|
||||
// TODO: Overwrite the oldest message in the history buffer when it is full.
|
||||
LOG_WARN("*** S&F - PSRAM Full. Packet is not added to the history.\n");
|
||||
}
|
||||
}
|
||||
|
||||
meshtastic_MeshPacket *StoreForwardModule::allocReply()
|
||||
@ -213,10 +214,19 @@ void StoreForwardModule::sendPayload(NodeNum dest, uint32_t packetHistory_index)
|
||||
// TODO: Make this configurable.
|
||||
p->want_ack = false;
|
||||
|
||||
p->decoded.payload.size =
|
||||
this->packetHistoryTXQueue[packetHistory_index].payload_size; // You must specify how many bytes are in the reply
|
||||
memcpy(p->decoded.payload.bytes, this->packetHistoryTXQueue[packetHistory_index].payload,
|
||||
meshtastic_StoreAndForward sf = meshtastic_StoreAndForward_init_zero;
|
||||
sf.which_variant = meshtastic_StoreAndForward_text_tag;
|
||||
sf.variant.text.size = this->packetHistoryTXQueue[packetHistory_index].payload_size;
|
||||
memcpy(sf.variant.text.bytes, this->packetHistoryTXQueue[packetHistory_index].payload,
|
||||
this->packetHistoryTXQueue[packetHistory_index].payload_size);
|
||||
if (this->packetHistoryTXQueue[packetHistory_index].to == NODENUM_BROADCAST) {
|
||||
sf.rr = meshtastic_StoreAndForward_RequestResponse_ROUTER_TEXT_BROADCAST;
|
||||
} else {
|
||||
sf.rr = meshtastic_StoreAndForward_RequestResponse_ROUTER_TEXT_DIRECT;
|
||||
}
|
||||
|
||||
p->decoded.payload.size =
|
||||
pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), &meshtastic_StoreAndForward_msg, &sf);
|
||||
|
||||
service.sendToMesh(p);
|
||||
}
|
||||
@ -387,7 +397,9 @@ bool StoreForwardModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp,
|
||||
LOG_INFO("*** S&F - Busy. Try again shortly.\n");
|
||||
} else {
|
||||
if ((p->which_variant == meshtastic_StoreAndForward_history_tag) && (p->variant.history.window > 0)) {
|
||||
storeForwardModule->historySend(p->variant.history.window * 60000, getFrom(&mp)); // window is in minutes
|
||||
// window is in minutes
|
||||
storeForwardModule->historySend(p->variant.history.window * 60000, getFrom(&mp),
|
||||
p->variant.history.last_request);
|
||||
} else {
|
||||
storeForwardModule->historySend(historyReturnWindow * 60000, getFrom(&mp)); // defaults to 4 hours
|
||||
}
|
||||
@ -406,8 +418,7 @@ bool StoreForwardModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp,
|
||||
case meshtastic_StoreAndForward_RequestResponse_CLIENT_PONG:
|
||||
if (is_server) {
|
||||
LOG_INFO("*** StoreAndForward_RequestResponse_CLIENT_PONG\n");
|
||||
// The Client is alive, update NodeDB
|
||||
nodeDB.updateFrom(mp);
|
||||
// NodeDB is already updated
|
||||
}
|
||||
break;
|
||||
|
||||
@ -546,9 +557,7 @@ StoreForwardModule::StoreForwardModule()
|
||||
}
|
||||
|
||||
// Client
|
||||
}
|
||||
if ((config.device.role == meshtastic_Config_DeviceConfig_Role_CLIENT) ||
|
||||
(config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_CLIENT)) {
|
||||
} else {
|
||||
is_client = true;
|
||||
LOG_INFO("*** Initializing Store & Forward Module in Client mode\n");
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ struct PacketHistoryStruct {
|
||||
uint32_t to;
|
||||
uint32_t from;
|
||||
uint8_t channel;
|
||||
bool ack;
|
||||
uint8_t payload[meshtastic_Constants_DATA_PAYLOAD_LEN];
|
||||
pb_size_t payload_size;
|
||||
};
|
||||
@ -32,7 +31,7 @@ class StoreForwardModule : private concurrency::OSThread, public ProtobufModule<
|
||||
uint32_t packetHistoryTXQueue_size = 0;
|
||||
uint32_t packetHistoryTXQueue_index = 0;
|
||||
|
||||
uint32_t packetTimeMax = 5000;
|
||||
uint32_t packetTimeMax = 5000; // Interval between sending history packets as a server.
|
||||
|
||||
bool is_client = false;
|
||||
bool is_server = false;
|
||||
@ -41,7 +40,7 @@ class StoreForwardModule : private concurrency::OSThread, public ProtobufModule<
|
||||
StoreForwardModule();
|
||||
|
||||
unsigned long lastHeartbeat = 0;
|
||||
uint32_t heartbeatInterval = 300;
|
||||
uint32_t heartbeatInterval = default_broadcast_interval_secs;
|
||||
|
||||
/**
|
||||
Update our local reference of when we last saw that node.
|
||||
@ -49,9 +48,9 @@ class StoreForwardModule : private concurrency::OSThread, public ProtobufModule<
|
||||
*/
|
||||
void historyAdd(const meshtastic_MeshPacket &mp);
|
||||
void statsSend(uint32_t to);
|
||||
void historySend(uint32_t msAgo, uint32_t to);
|
||||
void historySend(uint32_t msAgo, uint32_t to, uint32_t last_request_index = 0);
|
||||
|
||||
uint32_t historyQueueCreate(uint32_t msAgo, uint32_t to);
|
||||
uint32_t historyQueueCreate(uint32_t msAgo, uint32_t to, uint32_t *last_request_index);
|
||||
|
||||
/**
|
||||
* Send our payload into the mesh
|
||||
@ -79,16 +78,16 @@ class StoreForwardModule : private concurrency::OSThread, public ProtobufModule<
|
||||
void populatePSRAM();
|
||||
|
||||
// S&F Defaults
|
||||
uint32_t historyReturnMax = 250; // 250 records
|
||||
uint32_t historyReturnWindow = 240; // 4 hours
|
||||
uint32_t historyReturnMax = 25; // Return maximum of 25 records by default.
|
||||
uint32_t historyReturnWindow = 240; // Return history of last 4 hours by default.
|
||||
uint32_t records = 0; // Calculated
|
||||
bool heartbeat = false; // No heartbeat.
|
||||
|
||||
// stats
|
||||
uint32_t requests = 0;
|
||||
uint32_t requests_history = 0;
|
||||
uint32_t requests = 0; // Number of times any client sent a request to the S&F.
|
||||
uint32_t requests_history = 0; // Number of times the history was requested.
|
||||
|
||||
uint32_t retry_delay = 0;
|
||||
uint32_t retry_delay = 0; // If server is busy, retry after this delay (in ms).
|
||||
|
||||
protected:
|
||||
virtual int32_t runOnce() override;
|
||||
@ -102,4 +101,4 @@ class StoreForwardModule : private concurrency::OSThread, public ProtobufModule<
|
||||
virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_StoreAndForward *p);
|
||||
};
|
||||
|
||||
extern StoreForwardModule *storeForwardModule;
|
||||
extern StoreForwardModule *storeForwardModule;
|
@ -106,7 +106,7 @@
|
||||
#elif defined(HELTEC_WSL_V3)
|
||||
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_WSL_V3
|
||||
#elif defined(HELTEC_WIRELESS_TRACKER)
|
||||
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_WIRELESS_TRACKER_V1_1
|
||||
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_WIRELESS_TRACKER
|
||||
#elif defined(HELTEC_WIRELESS_PAPER_V1_0)
|
||||
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_WIRELESS_PAPER_V1_0
|
||||
#elif defined(HELTEC_WIRELESS_PAPER)
|
||||
|
Loading…
Reference in New Issue
Block a user