Compare commits

...

17 Commits

Author SHA1 Message Date
Ben Meadors
9ac0e26d42 Add option to preserve private key for factory reset (config) (#4679)
* Add option to preserve private key for factory reset (config)

* Typo fix

* Copy the key in the right direction, and set the size.

* Don't set the key size back to 0 right after setting it to 32.

* Set the key size before using it to do a memcpy.

* Use the right key_size for backing up private_key

* Don't factoryReset() for a missing nodeDB

* Disable Bluetooth in AdminModule when resetting device settings or nodeDB to avoid race

* Add checks for valid objects before deinit bluetooth

* Add disableBluetooth to handleSetConfig, handleSetModuleConfig, and commit settings

---------

Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
2024-09-11 08:42:26 -05:00
Ben Meadors
1ba4f6e222 Revert "Temp: Grab pre-release tag"
This reverts commit e8e9826adc.
2024-09-10 20:07:06 -05:00
Ben Meadors
e8e9826adc Temp: Grab pre-release tag 2024-09-10 19:27:59 -05:00
zerolint
6724f1f7ea Print Unix epoch on time_t 64bit platforms (#4673)
Fixes (#4600) by using unsigned 32bit for epoch.

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-09-10 15:51:28 -05:00
Ben Meadors
013021941e Remove scaling of smart position broadcast minimum interval specifically (#4677)
* Remove scaling of smart position broacast minimum interval specifically

* Trunk
2024-09-10 15:30:40 -05:00
Jonathan Bennett
4e850296b6 Fix repeatedly getting new NodeNum and add more debug (#4674)
* All the debug

* Change `memccpy()` to `memcpy()`

* Brint all the bytes of the MAC Address from the NodeDB

* Check for blank MAC Address in ourown NodeDB entry

* One more `memccpy()`

* Clean-up debug log

---------

Co-authored-by: GUVWAF <thijs@havinga.eu>
2024-09-10 13:24:57 -05:00
GUVWAF
f1602ee3f6 Merge pull request #4669 from GUVWAF/trFix 2024-09-09 23:13:39 +02:00
GUVWAF
5537f98dd6 Merge branch 'master' into trFix 2024-09-09 21:29:37 +02:00
GUVWAF
4ed12bf21d Try fix repeatedly getting a new NodeNum (#4670) 2024-09-09 14:22:32 -05:00
Ben Meadors
106dab23db Revert "Changes by create-pull-request action" (#4671) 2024-09-09 14:20:14 -05:00
GUVWAF
2f9dcee954 Fix size calculation of route/SNR array 2024-09-09 19:13:00 +02:00
Thomas Göttgens
68d6ff8c24 Merge pull request #4650 from fifieldt/AG3352
Add support for AG3352 and fix AG3335 support
2024-09-09 16:40:44 +02:00
Tom Fifield
dc8cc122a6 Add explicit to JSONValue constructors (#4665) 2024-09-09 09:20:21 -05:00
Tom Fifield
e9d55de3cb Fix out-of-bound array access in T1000X Sensor (#4663)
if u8i == 135, then u8i++ runs, the loop exits since u8i == 136,
then value for u8i is 136 after the for loop.

then in the next line, ntc_res2[u8i] will read past the end
 of the array
2024-09-09 07:54:11 -05:00
David
dacb452d47 Bugfix (#4660) 2024-09-09 07:16:58 -05:00
Thomas Göttgens
b2e2f1dba3 Merge branch 'master' into AG3352 2024-09-09 11:10:36 +02:00
Tom Fifield
6217e97c41 Add support for AG3352 and fix AG3335 support
AG33352 is a Mediatek/Airoha GPS/GLONASS/Galileo/BeiDou receiver.
Patch adds relevant detection and setup code.

Thanks to Bluebrolly and kongduino for providing the relevant
information and testing.

This patch also fixes support for the A3335, which is a related chip.
The setup and detection code now works as tested on a real life
T-1000E!

Thanks to @gpsfan for the guidance.
2024-09-09 09:06:05 +08:00
16 changed files with 113 additions and 54 deletions

View File

@@ -505,18 +505,18 @@ bool GPS::setup()
delay(250); delay(250);
_serial_gps->write("$CFGMSG,6,1,0\r\n"); _serial_gps->write("$CFGMSG,6,1,0\r\n");
delay(250); delay(250);
} else if (gnssModel == GNSS_MODEL_AG3335) { } else if (gnssModel == GNSS_MODEL_AG3335 || gnssModel == GNSS_MODEL_AG3352) {
_serial_gps->write("$PAIR066,1,0,1,0,0,1*3B\r\n"); // Enable GPS+GALILEO+NAVIC _serial_gps->write("$PAIR066,1,0,1,0,0,1*3B\r\n"); // Enable GPS+GALILEO+NAVIC
// Configure NMEA (sentences will output once per fix) // Configure NMEA (sentences will output once per fix)
_serial_gps->write("$PAIR062,0,0*3F\r\n"); // GGA ON _serial_gps->write("$PAIR062,0,1*3F\r\n"); // GGA ON
_serial_gps->write("$PAIR062,1,0*3F\r\n"); // GLL OFF _serial_gps->write("$PAIR062,1,0*3F\r\n"); // GLL OFF
_serial_gps->write("$PAIR062,2,1*3D\r\n"); // GSA ON _serial_gps->write("$PAIR062,2,0*3C\r\n"); // GSA OFF
_serial_gps->write("$PAIR062,3,0*3D\r\n"); // GSV OFF _serial_gps->write("$PAIR062,3,0*3D\r\n"); // GSV OFF
_serial_gps->write("$PAIR062,4,0*3B\r\n"); // RMC ON _serial_gps->write("$PAIR062,4,1*3B\r\n"); // RMC ON
_serial_gps->write("$PAIR062,5,0*3B\r\n"); // VTG OFF _serial_gps->write("$PAIR062,5,0*3B\r\n"); // VTG OFF
_serial_gps->write("$PAIR062,6,1*39\r\n"); // ZDA ON _serial_gps->write("$PAIR062,6,0*38\r\n"); // ZDA ON
delay(250); delay(250);
_serial_gps->write("$PAIR513*3D\r\n"); // save configuration _serial_gps->write("$PAIR513*3D\r\n"); // save configuration
@@ -1204,9 +1204,6 @@ GnssModel_t GPS::probe(int serialSpeed)
_serial_gps->updateBaudRate(serialSpeed); _serial_gps->updateBaudRate(serialSpeed);
} }
#endif #endif
#ifdef GNSS_AIROHA
return GNSS_MODEL_AG3335;
#endif
memset(&info, 0, sizeof(struct uBloxGnssModelInfo)); memset(&info, 0, sizeof(struct uBloxGnssModelInfo));
uint8_t buffer[768] = {0}; uint8_t buffer[768] = {0};
@@ -1225,7 +1222,12 @@ GnssModel_t GPS::probe(int serialSpeed)
PROBE_SIMPLE("ATGM332D", "$PCAS06,1*1A", "$GPTXT,01,01,02,HW=ATGM332D", GNSS_MODEL_ATGM336H, 500); PROBE_SIMPLE("ATGM332D", "$PCAS06,1*1A", "$GPTXT,01,01,02,HW=ATGM332D", GNSS_MODEL_ATGM336H, 500);
/* Airoha (Mediatek) AG3335A/M/S, A3352Q, Quectel L89 2.0, SimCom SIM65M */ /* Airoha (Mediatek) AG3335A/M/S, A3352Q, Quectel L89 2.0, SimCom SIM65M */
PROBE_SIMPLE("AG3335", "PAIR020*38", "$PAIR020,AG3335", GNSS_MODEL_AG3335, 500); _serial_gps->write("$PAIR062,2,0*3C\r\n"); // GSA OFF to reduce volume
_serial_gps->write("$PAIR062,3,0*3D\r\n"); // GSV OFF to reduce volume
_serial_gps->write("$PAIR513*3D\r\n"); // save configuration
PROBE_SIMPLE("AG3335", "$PAIR021*39", "$PAIR021,AG3335", GNSS_MODEL_AG3335, 500);
PROBE_SIMPLE("AG3352", "$PAIR021*39", "$PAIR021,AG3352", GNSS_MODEL_AG3352, 500);
PROBE_SIMPLE("LC86", "$PQTMVERNO*58", "$PQTMVERNO,LC86", GNSS_MODEL_AG3352, 500);
PROBE_SIMPLE("L76K", "$PCAS06,0*1B", "$GPTXT,01,01,02,SW=", GNSS_MODEL_MTK, 500); PROBE_SIMPLE("L76K", "$PCAS06,0*1B", "$GPTXT,01,01,02,SW=", GNSS_MODEL_MTK, 500);
@@ -1802,4 +1804,4 @@ void GPS::toggleGpsMode()
enable(); enable();
} }
} }
#endif // Exclude GPS #endif // Exclude GPS

View File

@@ -30,7 +30,8 @@ typedef enum {
GNSS_MODEL_UC6580, GNSS_MODEL_UC6580,
GNSS_MODEL_UNKNOWN, GNSS_MODEL_UNKNOWN,
GNSS_MODEL_MTK_L76B, GNSS_MODEL_MTK_L76B,
GNSS_MODEL_AG3335 GNSS_MODEL_AG3335,
GNSS_MODEL_AG3352
} GnssModel_t; } GnssModel_t;
typedef enum { typedef enum {

View File

@@ -43,7 +43,10 @@ void readFromRTC()
t.tm_sec = rtc.getSecond(); t.tm_sec = rtc.getSecond();
tv.tv_sec = gm_mktime(&t); tv.tv_sec = gm_mktime(&t);
tv.tv_usec = 0; tv.tv_usec = 0;
LOG_DEBUG("Read RTC time from RV3028 as %ld\n", tv.tv_sec);
uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
LOG_DEBUG("Read RTC time from RV3028 getTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t.tm_year + 1900, t.tm_mon + 1,
t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch);
timeStartMsec = now; timeStartMsec = now;
zeroOffsetSecs = tv.tv_sec; zeroOffsetSecs = tv.tv_sec;
if (currentQuality == RTCQualityNone) { if (currentQuality == RTCQualityNone) {
@@ -71,7 +74,10 @@ void readFromRTC()
t.tm_sec = tc.second; t.tm_sec = tc.second;
tv.tv_sec = gm_mktime(&t); tv.tv_sec = gm_mktime(&t);
tv.tv_usec = 0; tv.tv_usec = 0;
LOG_DEBUG("Read RTC time from PCF8563 as %ld\n", tv.tv_sec);
uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
LOG_DEBUG("Read RTC time from PCF8563 getDateTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t.tm_year + 1900,
t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch);
timeStartMsec = now; timeStartMsec = now;
zeroOffsetSecs = tv.tv_sec; zeroOffsetSecs = tv.tv_sec;
if (currentQuality == RTCQualityNone) { if (currentQuality == RTCQualityNone) {
@@ -81,7 +87,8 @@ void readFromRTC()
#else #else
if (!gettimeofday(&tv, NULL)) { if (!gettimeofday(&tv, NULL)) {
uint32_t now = millis(); uint32_t now = millis();
LOG_DEBUG("Read RTC time as %ld\n", tv.tv_sec); uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
LOG_DEBUG("Read RTC time as %ld\n", printableEpoch);
timeStartMsec = now; timeStartMsec = now;
zeroOffsetSecs = tv.tv_sec; zeroOffsetSecs = tv.tv_sec;
} }
@@ -101,6 +108,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate)
{ {
static uint32_t lastSetMsec = 0; static uint32_t lastSetMsec = 0;
uint32_t now = millis(); uint32_t now = millis();
uint32_t printableEpoch = tv->tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
bool shouldSet; bool shouldSet;
if (forceUpdate) { if (forceUpdate) {
@@ -113,7 +121,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate)
} else if (q >= RTCQualityNTP && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) { } else if (q >= RTCQualityNTP && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) {
// Every 12 hrs we will slam in a new GPS or Phone GPS / NTP time, to correct for local RTC clock drift // Every 12 hrs we will slam in a new GPS or Phone GPS / NTP time, to correct for local RTC clock drift
shouldSet = true; shouldSet = true;
LOG_DEBUG("Reapplying external time to correct clock drift %ld secs\n", tv->tv_sec); LOG_DEBUG("Reapplying external time to correct clock drift %ld secs\n", printableEpoch);
} else { } else {
shouldSet = false; shouldSet = false;
LOG_DEBUG("Current RTC quality: %s. Ignoring time of RTC quality of %s\n", RtcName(currentQuality), RtcName(q)); LOG_DEBUG("Current RTC quality: %s. Ignoring time of RTC quality of %s\n", RtcName(currentQuality), RtcName(q));
@@ -140,8 +148,8 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate)
#endif #endif
tm *t = gmtime(&tv->tv_sec); tm *t = gmtime(&tv->tv_sec);
rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec); t->tm_hour, t->tm_min, t->tm_sec, printableEpoch);
} }
#elif defined(PCF8563_RTC) #elif defined(PCF8563_RTC)
if (rtc_found.address == PCF8563_RTC) { if (rtc_found.address == PCF8563_RTC) {
@@ -154,8 +162,8 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate)
#endif #endif
tm *t = gmtime(&tv->tv_sec); tm *t = gmtime(&tv->tv_sec);
rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t->tm_year + 1900, t->tm_mon + 1,
t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec); t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, printableEpoch);
} }
#elif defined(ARCH_ESP32) #elif defined(ARCH_ESP32)
settimeofday(tv, NULL); settimeofday(tv, NULL);
@@ -272,4 +280,4 @@ time_t gm_mktime(struct tm *tm)
#else #else
return mktime(tm); return mktime(tm);
#endif #endif
} }

View File

@@ -9,7 +9,7 @@ CardKbI2cImpl::CardKbI2cImpl() : KbI2cBase("cardKB") {}
void CardKbI2cImpl::init() void CardKbI2cImpl::init()
{ {
#ifndef ARCH_PORTDUINO #if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_PORTDUINO)
if (cardkb_found.address == 0x00) { if (cardkb_found.address == 0x00) {
LOG_DEBUG("Rescanning for I2C keyboard\n"); LOG_DEBUG("Rescanning for I2C keyboard\n");
uint8_t i2caddr_scan[] = {CARDKB_ADDR, TDECK_KB_ADDR, BBQ10_KB_ADDR}; uint8_t i2caddr_scan[] = {CARDKB_ADDR, TDECK_KB_ADDR, BBQ10_KB_ADDR};
@@ -57,4 +57,4 @@ void CardKbI2cImpl::init()
} }
#endif #endif
inputBroker->registerSource(this); inputBroker->registerSource(this);
} }

View File

@@ -121,6 +121,8 @@ NodeDB::NodeDB()
owner.hw_model = HW_VENDOR; owner.hw_model = HW_VENDOR;
// Ensure user (nodeinfo) role is set to whatever we're configured to // Ensure user (nodeinfo) role is set to whatever we're configured to
owner.role = config.device.role; owner.role = config.device.role;
// Ensure macaddr is set to our macaddr as it will be copied in our info below
memcpy(owner.macaddr, ourMacAddr, sizeof(owner.macaddr));
// Include our owner in the node db under our nodenum // Include our owner in the node db under our nodenum
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(getNodeNum()); meshtastic_NodeInfoLite *info = getOrCreateMeshNode(getNodeNum());
@@ -243,7 +245,7 @@ bool NodeDB::factoryReset(bool eraseBleBonds)
#endif #endif
// second, install default state (this will deal with the duplicate mac address issue) // second, install default state (this will deal with the duplicate mac address issue)
installDefaultDeviceState(); installDefaultDeviceState();
installDefaultConfig(); installDefaultConfig(!eraseBleBonds); // Also preserve the private key if we're not erasing BLE bonds
installDefaultModuleConfig(); installDefaultModuleConfig();
installDefaultChannels(); installDefaultChannels();
// third, write everything to disk // third, write everything to disk
@@ -266,8 +268,13 @@ bool NodeDB::factoryReset(bool eraseBleBonds)
return true; return true;
} }
void NodeDB::installDefaultConfig() void NodeDB::installDefaultConfig(bool preserveKey = false)
{ {
uint8_t private_key_temp[32];
bool shouldPreserveKey = preserveKey && config.has_security && config.security.private_key.size > 0;
if (shouldPreserveKey) {
memcpy(private_key_temp, config.security.private_key.bytes, config.security.private_key.size);
}
LOG_INFO("Installing default LocalConfig\n"); LOG_INFO("Installing default LocalConfig\n");
memset(&config, 0, sizeof(meshtastic_LocalConfig)); memset(&config, 0, sizeof(meshtastic_LocalConfig));
config.version = DEVICESTATE_CUR_VER; config.version = DEVICESTATE_CUR_VER;
@@ -308,8 +315,14 @@ void NodeDB::installDefaultConfig()
#else #else
config.security.admin_key[0].size = 0; config.security.admin_key[0].size = 0;
#endif #endif
if (shouldPreserveKey) {
config.security.private_key.size = 32;
memcpy(config.security.private_key.bytes, private_key_temp, config.security.private_key.size);
printBytes("Restored key", config.security.private_key.bytes, config.security.private_key.size);
} else {
config.security.private_key.size = 0;
}
config.security.public_key.size = 0; config.security.public_key.size = 0;
config.security.private_key.size = 0;
#ifdef PIN_GPS_EN #ifdef PIN_GPS_EN
config.position.gps_en_gpio = PIN_GPS_EN; config.position.gps_en_gpio = PIN_GPS_EN;
#endif #endif
@@ -644,7 +657,9 @@ void NodeDB::pickNewNodeNum()
while ((nodeNum == NODENUM_BROADCAST || nodeNum < NUM_RESERVED) || while ((nodeNum == NODENUM_BROADCAST || nodeNum < NUM_RESERVED) ||
((found = getMeshNode(nodeNum)) && memcmp(found->user.macaddr, ourMacAddr, sizeof(ourMacAddr)) != 0)) { ((found = getMeshNode(nodeNum)) && memcmp(found->user.macaddr, ourMacAddr, sizeof(ourMacAddr)) != 0)) {
NodeNum candidate = random(NUM_RESERVED, LONG_MAX); // try a new random choice NodeNum candidate = random(NUM_RESERVED, LONG_MAX); // try a new random choice
LOG_WARN("NOTE! Our desired nodenum 0x%x is invalid or in use, so trying for 0x%x\n", nodeNum, candidate); LOG_WARN("NOTE! Our desired nodenum 0x%x is invalid or in use, by MAC ending in 0x%02x%02x vs our 0x%02x%02x, so "
"trying for 0x%x\n",
nodeNum, found->user.macaddr[4], found->user.macaddr[5], ourMacAddr[4], ourMacAddr[5], candidate);
nodeNum = candidate; nodeNum = candidate;
} }
LOG_DEBUG("Using nodenum 0x%x \n", nodeNum); LOG_DEBUG("Using nodenum 0x%x \n", nodeNum);
@@ -710,7 +725,7 @@ void NodeDB::loadFromDisk()
//} else { //} else {
if (devicestate.version < DEVICESTATE_MIN_VER) { if (devicestate.version < DEVICESTATE_MIN_VER) {
LOG_WARN("Devicestate %d is old, discarding\n", devicestate.version); LOG_WARN("Devicestate %d is old, discarding\n", devicestate.version);
factoryReset(); installDefaultDeviceState();
} else { } else {
LOG_INFO("Loaded saved devicestate version %d, with nodecount: %d\n", devicestate.version, LOG_INFO("Loaded saved devicestate version %d, with nodecount: %d\n", devicestate.version,
devicestate.node_db_lite.size()); devicestate.node_db_lite.size());
@@ -726,7 +741,7 @@ void NodeDB::loadFromDisk()
} else { } else {
if (config.version < DEVICESTATE_MIN_VER) { if (config.version < DEVICESTATE_MIN_VER) {
LOG_WARN("config %d is old, discarding\n", config.version); LOG_WARN("config %d is old, discarding\n", config.version);
installDefaultConfig(); installDefaultConfig(true);
} else { } else {
LOG_INFO("Loaded saved config version %d\n", config.version); LOG_INFO("Loaded saved config version %d\n", config.version);
} }
@@ -1039,7 +1054,7 @@ bool NodeDB::updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelInde
if (p.public_key.size > 0) { if (p.public_key.size > 0) {
printBytes("Incoming Pubkey: ", p.public_key.bytes, 32); printBytes("Incoming Pubkey: ", p.public_key.bytes, 32);
if (info->user.public_key.size > 0) { // if we have a key for this user already, don't overwrite with a new one if (info->user.public_key.size > 0) { // if we have a key for this user already, don't overwrite with a new one
LOG_INFO("Public Key set for node, not updateing!\n"); LOG_INFO("Public Key set for node, not updating!\n");
// we copy the key into the incoming packet, to prevent overwrite // we copy the key into the incoming packet, to prevent overwrite
memcpy(p.public_key.bytes, info->user.public_key.bytes, 32); memcpy(p.public_key.bytes, info->user.public_key.bytes, 32);
} else { } else {
@@ -1194,4 +1209,4 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
LOG_ERROR("A critical failure occurred, portduino is exiting..."); LOG_ERROR("A critical failure occurred, portduino is exiting...");
exit(2); exit(2);
#endif #endif
} }

View File

@@ -182,7 +182,8 @@ class NodeDB
void cleanupMeshDB(); void cleanupMeshDB();
/// Reinit device state from scratch (not loading from disk) /// Reinit device state from scratch (not loading from disk)
void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(), installDefaultModuleConfig(); void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(bool preserveKey),
installDefaultModuleConfig();
/// write to flash /// write to flash
/// @return true if the save was successful /// @return true if the save was successful

View File

@@ -78,7 +78,7 @@ meshtastic_UserLite TypeConversions::ConvertToUserLite(meshtastic_User user)
lite.hw_model = user.hw_model; lite.hw_model = user.hw_model;
lite.role = user.role; lite.role = user.role;
lite.is_licensed = user.is_licensed; lite.is_licensed = user.is_licensed;
memccpy(lite.macaddr, user.macaddr, sizeof(user.macaddr), sizeof(lite.macaddr)); memcpy(lite.macaddr, user.macaddr, sizeof(lite.macaddr));
memcpy(lite.public_key.bytes, user.public_key.bytes, sizeof(lite.public_key.bytes)); memcpy(lite.public_key.bytes, user.public_key.bytes, sizeof(lite.public_key.bytes));
lite.public_key.size = user.public_key.size; lite.public_key.size = user.public_key.size;
return lite; return lite;
@@ -94,7 +94,7 @@ meshtastic_User TypeConversions::ConvertToUser(uint32_t nodeNum, meshtastic_User
user.hw_model = lite.hw_model; user.hw_model = lite.hw_model;
user.role = lite.role; user.role = lite.role;
user.is_licensed = lite.is_licensed; user.is_licensed = lite.is_licensed;
memccpy(user.macaddr, lite.macaddr, sizeof(lite.macaddr), sizeof(user.macaddr)); memcpy(user.macaddr, lite.macaddr, sizeof(user.macaddr));
memcpy(user.public_key.bytes, lite.public_key.bytes, sizeof(user.public_key.bytes)); memcpy(user.public_key.bytes, lite.public_key.bytes, sizeof(user.public_key.bytes));
user.public_key.size = lite.public_key.size; user.public_key.size = lite.public_key.size;

View File

@@ -186,18 +186,22 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
break; break;
} }
case meshtastic_AdminMessage_factory_reset_config_tag: { case meshtastic_AdminMessage_factory_reset_config_tag: {
disableBluetooth();
LOG_INFO("Initiating factory config reset\n"); LOG_INFO("Initiating factory config reset\n");
nodeDB->factoryReset(); nodeDB->factoryReset();
LOG_INFO("Factory config reset finished, rebooting soon.\n");
reboot(DEFAULT_REBOOT_SECONDS); reboot(DEFAULT_REBOOT_SECONDS);
break; break;
} }
case meshtastic_AdminMessage_factory_reset_device_tag: { case meshtastic_AdminMessage_factory_reset_device_tag: {
disableBluetooth();
LOG_INFO("Initiating full factory reset\n"); LOG_INFO("Initiating full factory reset\n");
nodeDB->factoryReset(true); nodeDB->factoryReset(true);
reboot(DEFAULT_REBOOT_SECONDS); reboot(DEFAULT_REBOOT_SECONDS);
break; break;
} }
case meshtastic_AdminMessage_nodedb_reset_tag: { case meshtastic_AdminMessage_nodedb_reset_tag: {
disableBluetooth();
LOG_INFO("Initiating node-db reset\n"); LOG_INFO("Initiating node-db reset\n");
nodeDB->resetNodes(); nodeDB->resetNodes();
reboot(DEFAULT_REBOOT_SECONDS); reboot(DEFAULT_REBOOT_SECONDS);
@@ -209,6 +213,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
break; break;
} }
case meshtastic_AdminMessage_commit_edit_settings_tag: { case meshtastic_AdminMessage_commit_edit_settings_tag: {
disableBluetooth();
LOG_INFO("Committing transaction for edited settings\n"); LOG_INFO("Committing transaction for edited settings\n");
hasOpenEditTransaction = false; hasOpenEditTransaction = false;
saveChanges(SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS); saveChanges(SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
@@ -559,12 +564,16 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
break; break;
} }
if (requiresReboot) {
disableBluetooth();
}
saveChanges(changes, requiresReboot); saveChanges(changes, requiresReboot);
} }
void AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c) void AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
{ {
disableBluetooth();
switch (c.which_payload_variant) { switch (c.which_payload_variant) {
case meshtastic_ModuleConfig_mqtt_tag: case meshtastic_ModuleConfig_mqtt_tag:
LOG_INFO("Setting module config: MQTT\n"); LOG_INFO("Setting module config: MQTT\n");
@@ -636,7 +645,6 @@ void AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
moduleConfig.paxcounter = c.payload_variant.paxcounter; moduleConfig.paxcounter = c.payload_variant.paxcounter;
break; break;
} }
saveChanges(SEGMENT_MODULECONFIG); saveChanges(SEGMENT_MODULECONFIG);
} }
@@ -1031,3 +1039,16 @@ bool AdminModule::messageIsRequest(meshtastic_AdminMessage *r)
else else
return false; return false;
} }
void disableBluetooth()
{
#if HAS_BLUETOOTH
#ifdef ARCH_ESP32
if (nimbleBluetooth)
nimbleBluetooth->deinit();
#elif defined(ARCH_NRF52)
if (nrf52Bluetooth)
nrf52Bluetooth->shutdown();
#endif
#endif
}

View File

@@ -59,4 +59,6 @@ class AdminModule : public ProtobufModule<meshtastic_AdminMessage>, public Obser
bool messageIsRequest(meshtastic_AdminMessage *r); bool messageIsRequest(meshtastic_AdminMessage *r);
}; };
extern AdminModule *adminModule; extern AdminModule *adminModule;
void disableBluetooth();

View File

@@ -63,7 +63,7 @@ class PositionModule : public ProtobufModule<meshtastic_Position>, private concu
bool hasQualityTimesource(); bool hasQualityTimesource();
const uint32_t minimumTimeThreshold = const uint32_t minimumTimeThreshold =
Default::getConfiguredOrDefaultMsScaled(config.position.broadcast_smart_minimum_interval_secs, 30, numOnlineNodes); Default::getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30);
}; };
struct SmartPosition { struct SmartPosition {

View File

@@ -95,7 +95,7 @@ float T1000xSensor::getTemp()
Vout = ntc_vot; Vout = ntc_vot;
Rt = (HEATER_NTC_RP * vcc_vot) / Vout - HEATER_NTC_RP; Rt = (HEATER_NTC_RP * vcc_vot) / Vout - HEATER_NTC_RP;
for (u8i = 0; u8i < 136; u8i++) { for (u8i = 0; u8i < 135; u8i++) {
if (Rt >= ntc_res2[u8i]) { if (Rt >= ntc_res2[u8i]) {
break; break;
} }

View File

@@ -53,7 +53,7 @@ void TraceRouteModule::insertUnknownHops(meshtastic_MeshPacket &p, meshtastic_Ro
uint8_t hopsTaken = p.hop_start - p.hop_limit; uint8_t hopsTaken = p.hop_start - p.hop_limit;
int8_t diff = hopsTaken - *route_count; int8_t diff = hopsTaken - *route_count;
for (uint8_t i = 0; i < diff; i++) { for (uint8_t i = 0; i < diff; i++) {
if (*route_count < sizeof(*route) / sizeof(route[0])) { if (*route_count < ROUTE_SIZE) {
route[*route_count] = NODENUM_BROADCAST; // This will represent an unknown hop route[*route_count] = NODENUM_BROADCAST; // This will represent an unknown hop
*route_count += 1; *route_count += 1;
} }
@@ -61,7 +61,7 @@ void TraceRouteModule::insertUnknownHops(meshtastic_MeshPacket &p, meshtastic_Ro
// Add unknown SNR values if necessary // Add unknown SNR values if necessary
diff = *route_count - *snr_count; diff = *route_count - *snr_count;
for (uint8_t i = 0; i < diff; i++) { for (uint8_t i = 0; i < diff; i++) {
if (*snr_count < sizeof(*snr_list) / sizeof(snr_list[0])) { if (*snr_count < ROUTE_SIZE) {
snr_list[*snr_count] = INT8_MIN; // This will represent an unknown SNR snr_list[*snr_count] = INT8_MIN; // This will represent an unknown SNR
*snr_count += 1; *snr_count += 1;
} }
@@ -89,7 +89,7 @@ void TraceRouteModule::appendMyIDandSNR(meshtastic_RouteDiscovery *updated, floa
snr_list = updated->snr_back; snr_list = updated->snr_back;
} }
if (*snr_count < sizeof(*snr_list) / sizeof(snr_list[0])) { if (*snr_count < ROUTE_SIZE) {
snr_list[*snr_count] = (int8_t)(snr * 4); // Convert SNR to 1 byte snr_list[*snr_count] = (int8_t)(snr * 4); // Convert SNR to 1 byte
*snr_count += 1; *snr_count += 1;
} }
@@ -97,7 +97,7 @@ void TraceRouteModule::appendMyIDandSNR(meshtastic_RouteDiscovery *updated, floa
return; return;
// Length of route array can normally not be exceeded due to the max. hop_limit of 7 // Length of route array can normally not be exceeded due to the max. hop_limit of 7
if (*route_count < sizeof(*route) / sizeof(route[0])) { if (*route_count < ROUTE_SIZE) {
route[*route_count] = myNodeInfo.my_node_num; route[*route_count] = myNodeInfo.my_node_num;
*route_count += 1; *route_count += 1;
} else { } else {

View File

@@ -1,6 +1,8 @@
#pragma once #pragma once
#include "ProtobufModule.h" #include "ProtobufModule.h"
#define ROUTE_SIZE sizeof(((meshtastic_RouteDiscovery *)0)->route) / sizeof(((meshtastic_RouteDiscovery *)0)->route[0])
/** /**
* A module that traces the route to a certain destination node * A module that traces the route to a certain destination node
*/ */

View File

@@ -10,10 +10,14 @@
void lateInitVariant() void lateInitVariant()
{ {
// LOG_DEBUG("Heltec tracker initVariant\n"); // LOG_DEBUG("Heltec tracker initVariant\n");
#ifdef VEXT_ENABLE
GpioPin *hwEnable = new GpioHwPin(VEXT_ENABLE);
GpioVirtPin *virtGpsEnable = gps ? gps->enablePin : new GpioVirtPin();
#ifndef MESHTASTIC_EXCLUDE_GPS
GpioVirtPin *virtGpsEnable = gps ? gps->enablePin : new GpioVirtPin();
#else
GpioVirtPin *virtGpsEnable = new GpioVirtPin();
#endif
#ifndef MESHTASTIC_EXCLUDE_SCREEN
// On this board we are actually using the backlightEnable signal to already be controlling a physical enable to the // On this board we are actually using the backlightEnable signal to already be controlling a physical enable to the
// display controller. But we'd _ALSO_ like to have that signal drive a virtual GPIO. So nest it as needed. // display controller. But we'd _ALSO_ like to have that signal drive a virtual GPIO. So nest it as needed.
GpioVirtPin *virtScreenEnable = new GpioVirtPin(); GpioVirtPin *virtScreenEnable = new GpioVirtPin();
@@ -25,8 +29,11 @@ void lateInitVariant()
// Assume screen is initially powered // Assume screen is initially powered
splitter->set(true); splitter->set(true);
} }
#endif
#if defined(VEXT_ENABLE) && (!defined(MESHTASTIC_EXCLUDE_GPS) || !defined(MESHTASTIC_EXCLUDE_SCREEN))
// If either the GPS or the screen is on, turn on the external power regulator // If either the GPS or the screen is on, turn on the external power regulator
GpioPin *hwEnable = new GpioHwPin(VEXT_ENABLE);
new GpioBinaryTransformer(virtGpsEnable, virtScreenEnable, hwEnable, GpioBinaryTransformer::Or); new GpioBinaryTransformer(virtGpsEnable, virtScreenEnable, hwEnable, GpioBinaryTransformer::Or);
#endif #endif
} }

View File

@@ -40,15 +40,15 @@ class JSONValue
public: public:
JSONValue(/*NULL*/); JSONValue(/*NULL*/);
JSONValue(const char *m_char_value); explicit JSONValue(const char *m_char_value);
JSONValue(const std::string &m_string_value); explicit JSONValue(const std::string &m_string_value);
JSONValue(bool m_bool_value); explicit JSONValue(bool m_bool_value);
JSONValue(double m_number_value); explicit JSONValue(double m_number_value);
JSONValue(int m_integer_value); explicit JSONValue(int m_integer_value);
JSONValue(unsigned int m_integer_value); explicit JSONValue(unsigned int m_integer_value);
JSONValue(const JSONArray &m_array_value); explicit JSONValue(const JSONArray &m_array_value);
JSONValue(const JSONObject &m_object_value); explicit JSONValue(const JSONObject &m_object_value);
JSONValue(const JSONValue &m_source); explicit JSONValue(const JSONValue &m_source);
~JSONValue(); ~JSONValue();
bool IsNull() const; bool IsNull() const;

View File

@@ -1,4 +1,4 @@
[VERSION] [VERSION]
major = 2 major = 2
minor = 5 minor = 5
build = 1 build = 0