pull/3630/head
Ben Meadors 2024-04-15 10:32:39 -05:00
rodzic ba2ee3e493
commit 56496fc81b
1 zmienionych plików z 80 dodań i 168 usunięć

Wyświetl plik

@ -55,18 +55,15 @@ meshtastic_OEMStore oemStore;
bool meshtastic_DeviceState_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field)
{
if (ostream)
{
if (ostream) {
std::vector<meshtastic_NodeInfoLite> *vec = (std::vector<meshtastic_NodeInfoLite> *)field->pData;
for (auto item : *vec)
{
for (auto item : *vec) {
if (!pb_encode_tag_for_field(ostream, field))
return false;
pb_encode_submessage(ostream, meshtastic_NodeInfoLite_fields, &item);
}
}
if (istream)
{
if (istream) {
meshtastic_NodeInfoLite node; // this gets good data
std::vector<meshtastic_NodeInfoLite> *vec = (std::vector<meshtastic_NodeInfoLite> *)field->pData;
@ -144,14 +141,12 @@ NodeDB::NodeDB()
if (channelFileCRC != crc32Buffer(&channelFile, sizeof(channelFile)))
saveWhat |= SEGMENT_CHANNELS;
if (!devicestate.node_remote_hardware_pins)
{
if (!devicestate.node_remote_hardware_pins) {
meshtastic_NodeRemoteHardwarePin empty[12] = {meshtastic_RemoteHardwarePin_init_default};
memcpy(devicestate.node_remote_hardware_pins, empty, sizeof(empty));
}
if (config.position.gps_enabled)
{
if (config.position.gps_enabled) {
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED;
config.position.gps_enabled = 0;
}
@ -173,13 +168,11 @@ bool NodeDB::resetRadioConfig(bool factory_reset)
radioGeneration++;
if (factory_reset)
{
if (factory_reset) {
didFactoryReset = factoryReset();
}
if (channelFile.channels_count != MAX_NUM_CHANNELS)
{
if (channelFile.channels_count != MAX_NUM_CHANNELS) {
LOG_INFO("Setting default channel and radio preferences!\n");
channels.initDefaults();
@ -190,8 +183,7 @@ bool NodeDB::resetRadioConfig(bool factory_reset)
// Update the global myRegion
initRegion();
if (didFactoryReset)
{
if (didFactoryReset) {
LOG_INFO("Rebooting due to factory reset");
screen->startRebootScreen();
rebootAtMsec = millis() + (5 * 1000);
@ -205,8 +197,7 @@ bool NodeDB::factoryReset()
LOG_INFO("Performing factory reset!\n");
// first, remove the "/prefs" (this removes most prefs)
rmDir("/prefs");
if (FSCom.exists("/static/rangetest.csv") && !FSCom.remove("/static/rangetest.csv"))
{
if (FSCom.exists("/static/rangetest.csv") && !FSCom.remove("/static/rangetest.csv")) {
LOG_ERROR("Could not remove rangetest.csv file\n");
}
// second, install default state (this will deal with the duplicate mac address issue)
@ -393,27 +384,18 @@ void NodeDB::installDefaultModuleConfig()
void NodeDB::installRoleDefaults(meshtastic_Config_DeviceConfig_Role role)
{
if (role == meshtastic_Config_DeviceConfig_Role_ROUTER)
{
if (role == meshtastic_Config_DeviceConfig_Role_ROUTER) {
initConfigIntervals();
initModuleConfigIntervals();
}
else if (role == meshtastic_Config_DeviceConfig_Role_REPEATER)
{
} else if (role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
config.display.screen_on_secs = 1;
}
else if (role == meshtastic_Config_DeviceConfig_Role_SENSOR)
{
} else if (role == meshtastic_Config_DeviceConfig_Role_SENSOR) {
moduleConfig.telemetry.environment_measurement_enabled = true;
moduleConfig.telemetry.environment_update_interval = 300;
}
else if (role == meshtastic_Config_DeviceConfig_Role_LOST_AND_FOUND)
{
} else if (role == meshtastic_Config_DeviceConfig_Role_LOST_AND_FOUND) {
config.position.position_broadcast_smart_enabled = false;
config.position.position_broadcast_secs = 300; // Every 5 minutes
}
else if (role == meshtastic_Config_DeviceConfig_Role_TAK)
{
} else if (role == meshtastic_Config_DeviceConfig_Role_TAK) {
config.device.node_info_broadcast_secs = ONE_DAY;
config.position.position_broadcast_smart_enabled = false;
config.position.position_broadcast_secs = ONE_DAY;
@ -422,9 +404,7 @@ void NodeDB::installRoleDefaults(meshtastic_Config_DeviceConfig_Role role)
(meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_SPEED |
meshtastic_Config_PositionConfig_PositionFlags_HEADING | meshtastic_Config_PositionConfig_PositionFlags_DOP);
moduleConfig.telemetry.device_update_interval = ONE_DAY;
}
else if (role == meshtastic_Config_DeviceConfig_Role_TAK_TRACKER)
{
} else if (role == meshtastic_Config_DeviceConfig_Role_TAK_TRACKER) {
config.device.node_info_broadcast_secs = ONE_DAY;
config.position.position_broadcast_smart_enabled = true;
config.position.position_broadcast_secs = 3 * 60; // Every 3 minutes
@ -435,9 +415,7 @@ void NodeDB::installRoleDefaults(meshtastic_Config_DeviceConfig_Role role)
(meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_SPEED |
meshtastic_Config_PositionConfig_PositionFlags_HEADING | meshtastic_Config_PositionConfig_PositionFlags_DOP);
moduleConfig.telemetry.device_update_interval = ONE_DAY;
}
else if (role == meshtastic_Config_DeviceConfig_Role_CLIENT_HIDDEN)
{
} else if (role == meshtastic_Config_DeviceConfig_Role_CLIENT_HIDDEN) {
config.device.rebroadcast_mode = meshtastic_Config_DeviceConfig_RebroadcastMode_LOCAL_ONLY;
config.device.node_info_broadcast_secs = UINT32_MAX;
config.position.position_broadcast_smart_enabled = false;
@ -477,8 +455,7 @@ void NodeDB::resetNodes()
void NodeDB::removeNodeByNum(uint nodeNum)
{
int newPos = 0, removed = 0;
for (int i = 0; i < numMeshNodes; i++)
{
for (int i = 0; i < numMeshNodes; i++) {
if (meshNodes->at(i).num != nodeNum)
meshNodes->at(newPos++) = meshNodes->at(i);
else
@ -504,8 +481,7 @@ void NodeDB::clearLocalPosition()
void NodeDB::cleanupMeshDB()
{
int newPos = 0, removed = 0;
for (int i = 0; i < numMeshNodes; i++)
{
for (int i = 0; i < numMeshNodes; i++) {
if (meshNodes->at(i).has_user)
meshNodes->at(newPos++) = meshNodes->at(i);
else
@ -551,8 +527,7 @@ void NodeDB::installDefaultDeviceState()
void NodeDB::pickNewNodeNum()
{
NodeNum nodeNum = myNodeInfo.my_node_num;
if (nodeNum == 0)
{
if (nodeNum == 0) {
getMacAddr(ourMacAddr); // Make sure ourMacAddr is set
// Pick an initial nodenum based on the macaddr
nodeNum = (ourMacAddr[2] << 24) | (ourMacAddr[3] << 16) | (ourMacAddr[4] << 8) | ourMacAddr[5];
@ -560,8 +535,7 @@ void NodeDB::pickNewNodeNum()
meshtastic_NodeInfoLite *found;
while ((nodeNum == NODENUM_BROADCAST || nodeNum < NUM_RESERVED) ||
((found = getMeshNode(nodeNum)) && memcmp(found->user.macaddr, owner.macaddr, sizeof(owner.macaddr)) != 0))
{
((found = getMeshNode(nodeNum)) && memcmp(found->user.macaddr, owner.macaddr, sizeof(owner.macaddr)) != 0)) {
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);
nodeNum = candidate;
@ -584,34 +558,27 @@ LoadFileResult NodeDB::loadProto(const char *filename, size_t protoSize, size_t
LoadFileResult state = LoadFileResult::OTHER_FAILURE;
#ifdef FSCom
if (!FSCom.exists(filename))
{
if (!FSCom.exists(filename)) {
LOG_INFO("File %s not found\n", filename);
return LoadFileResult::NOT_FOUND;
}
auto f = FSCom.open(filename, FILE_O_READ);
if (f)
{
if (f) {
LOG_INFO("Loading %s\n", filename);
pb_istream_t stream = {&readcb, &f, protoSize};
memset(dest_struct, 0, objSize);
if (!pb_decode(&stream, fields, dest_struct))
{
if (!pb_decode(&stream, fields, dest_struct)) {
LOG_ERROR("Error: can't decode protobuf %s\n", PB_GET_ERROR(&stream));
state = LoadFileResult::DECODE_FAILED;
}
else
{
} else {
LOG_INFO("Loaded %s successfully\n", filename);
state = LoadFileResult::SUCCESS;
}
f.close();
}
else
{
} else {
LOG_ERROR("Could not open / read %s\n", filename);
}
#else
@ -627,19 +594,13 @@ void NodeDB::loadFromDisk()
auto state = loadProto(prefFileName, sizeof(meshtastic_DeviceState) + MAX_NUM_NODES * sizeof(meshtastic_NodeInfo),
sizeof(meshtastic_DeviceState), &meshtastic_DeviceState_msg, &devicestate);
if (state != LoadFileResult::SUCCESS)
{
if (state != LoadFileResult::SUCCESS) {
installDefaultDeviceState(); // Our in RAM copy might now be corrupt
}
else
{
if (devicestate.version < DEVICESTATE_MIN_VER)
{
} else {
if (devicestate.version < DEVICESTATE_MIN_VER) {
LOG_WARN("Devicestate %d is old, discarding\n", devicestate.version);
factoryReset();
}
else
{
} else {
LOG_INFO("Loaded saved devicestate version %d, with nodecount: %d\n", devicestate.version,
devicestate.node_db_lite.size());
meshNodes = &devicestate.node_db_lite;
@ -650,64 +611,45 @@ void NodeDB::loadFromDisk()
state = loadProto(configFileName, meshtastic_LocalConfig_size, sizeof(meshtastic_LocalConfig), &meshtastic_LocalConfig_msg,
&config);
if (state != LoadFileResult::SUCCESS)
{
if (state != LoadFileResult::SUCCESS) {
installDefaultConfig(); // Our in RAM copy might now be corrupt
}
else
{
if (config.version < DEVICESTATE_MIN_VER)
{
} else {
if (config.version < DEVICESTATE_MIN_VER) {
LOG_WARN("config %d is old, discarding\n", config.version);
installDefaultConfig();
}
else
{
} else {
LOG_INFO("Loaded saved config version %d\n", config.version);
}
}
state = loadProto(moduleConfigFileName, meshtastic_LocalModuleConfig_size, sizeof(meshtastic_LocalModuleConfig),
&meshtastic_LocalModuleConfig_msg, &moduleConfig);
if (state != LoadFileResult::SUCCESS)
{
if (state != LoadFileResult::SUCCESS) {
installDefaultModuleConfig(); // Our in RAM copy might now be corrupt
}
else
{
if (moduleConfig.version < DEVICESTATE_MIN_VER)
{
} else {
if (moduleConfig.version < DEVICESTATE_MIN_VER) {
LOG_WARN("moduleConfig %d is old, discarding\n", moduleConfig.version);
installDefaultModuleConfig();
}
else
{
} else {
LOG_INFO("Loaded saved moduleConfig version %d\n", moduleConfig.version);
}
}
state = loadProto(channelFileName, meshtastic_ChannelFile_size, sizeof(meshtastic_ChannelFile), &meshtastic_ChannelFile_msg,
&channelFile);
if (state != LoadFileResult::SUCCESS)
{
if (state != LoadFileResult::SUCCESS) {
installDefaultChannels(); // Our in RAM copy might now be corrupt
}
else
{
if (channelFile.version < DEVICESTATE_MIN_VER)
{
} else {
if (channelFile.version < DEVICESTATE_MIN_VER) {
LOG_WARN("channelFile %d is old, discarding\n", channelFile.version);
installDefaultChannels();
}
else
{
} else {
LOG_INFO("Loaded saved channelFile version %d\n", channelFile.version);
}
}
state = loadProto(oemConfigFile, meshtastic_OEMStore_size, sizeof(meshtastic_OEMStore), &meshtastic_OEMStore_msg, &oemStore);
if (state == LoadFileResult::SUCCESS)
{
if (state == LoadFileResult::SUCCESS) {
LOG_INFO("Loaded OEMStore\n");
}
}
@ -721,40 +663,31 @@ bool NodeDB::saveProto(const char *filename, size_t protoSize, const pb_msgdesc_
String filenameTmp = filename;
filenameTmp += ".tmp";
auto f = FSCom.open(filenameTmp.c_str(), FILE_O_WRITE);
if (f)
{
if (f) {
LOG_INFO("Saving %s\n", filename);
pb_ostream_t stream = {&writecb, &f, protoSize};
if (!pb_encode(&stream, fields, dest_struct))
{
if (!pb_encode(&stream, fields, dest_struct)) {
LOG_ERROR("Error: can't encode protobuf %s\n", PB_GET_ERROR(&stream));
}
else
{
} else {
okay = true;
}
f.flush();
f.close();
// brief window of risk here ;-)
if (FSCom.exists(filename) && !FSCom.remove(filename))
{
if (FSCom.exists(filename) && !FSCom.remove(filename)) {
LOG_WARN("Can't remove old pref file\n");
}
if (!renameFile(filenameTmp.c_str(), filename))
{
if (!renameFile(filenameTmp.c_str(), filename)) {
LOG_ERROR("Error: can't rename new pref file\n");
}
}
else
{
} else {
LOG_ERROR("Can't write prefs\n");
#ifdef ARCH_NRF52
static uint8_t failedCounter = 0;
failedCounter++;
if (failedCounter >= 2)
{
if (failedCounter >= 2) {
LOG_ERROR("Failed to save file twice. Rebooting...\n");
delay(100);
NVIC_SystemReset();
@ -793,13 +726,11 @@ void NodeDB::saveToDisk(int saveWhat)
#ifdef FSCom
FSCom.mkdir("/prefs");
#endif
if (saveWhat & SEGMENT_DEVICESTATE)
{
if (saveWhat & SEGMENT_DEVICESTATE) {
saveDeviceStateToDisk();
}
if (saveWhat & SEGMENT_CONFIG)
{
if (saveWhat & SEGMENT_CONFIG) {
config.has_device = true;
config.has_display = true;
config.has_lora = true;
@ -807,11 +738,11 @@ void NodeDB::saveToDisk(int saveWhat)
config.has_power = true;
config.has_network = true;
config.has_bluetooth = true;
saveProto(configFileName, meshtastic_LocalConfig_size, &meshtastic_LocalConfig_msg, &config);
}
if (saveWhat & SEGMENT_MODULECONFIG)
{
if (saveWhat & SEGMENT_MODULECONFIG) {
moduleConfig.has_canned_message = true;
moduleConfig.has_external_notification = true;
moduleConfig.has_mqtt = true;
@ -819,11 +750,16 @@ void NodeDB::saveToDisk(int saveWhat)
moduleConfig.has_serial = true;
moduleConfig.has_store_forward = true;
moduleConfig.has_telemetry = true;
moduleConfig.has_neighbor_info = true;
moduleConfig.has_detection_sensor = true;
moduleConfig.has_ambient_lighting = true;
moduleConfig.has_audio = true;
moduleConfig.has_paxcounter = true;
saveProto(moduleConfigFileName, meshtastic_LocalModuleConfig_size, &meshtastic_LocalModuleConfig_msg, &moduleConfig);
}
if (saveWhat & SEGMENT_CHANNELS)
{
if (saveWhat & SEGMENT_CHANNELS) {
saveChannelsToDisk();
}
}
@ -866,8 +802,7 @@ size_t NodeDB::getNumOnlineMeshNodes(bool localOnly)
size_t numseen = 0;
// FIXME this implementation is kinda expensive
for (int i = 0; i < numMeshNodes; i++)
{
for (int i = 0; i < numMeshNodes; i++) {
if (localOnly && meshNodes->at(i).via_mqtt)
continue;
if (sinceLastSeen(&meshNodes->at(i)) < NUM_ONLINE_SECS)
@ -884,29 +819,23 @@ size_t NodeDB::getNumOnlineMeshNodes(bool localOnly)
void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSource src)
{
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(nodeId);
if (!info)
{
if (!info) {
return;
}
if (src == RX_SRC_LOCAL)
{
if (src == RX_SRC_LOCAL) {
// Local packet, fully authoritative
LOG_INFO("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.timestamp, p.time, p.latitude_i,
p.longitude_i, p.altitude);
setLocalPosition(p);
info->position = TypeConversions::ConvertToPositionLite(p);
}
else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source)
{
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) {
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
// (stop-gap fix for issue #900)
LOG_DEBUG("updatePosition SPECIAL time setting time=%u\n", p.time);
info->position.time = p.time;
}
else
{
} else {
// Be careful to only update fields that have been set by the REMOTE sender
// A lot of position reports don't have time populated. In that case, be careful to not blow away the time we
// recorded based on the packet rxTime
@ -936,18 +865,14 @@ void NodeDB::updateTelemetry(uint32_t nodeId, const meshtastic_Telemetry &t, RxS
{
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(nodeId);
// Environment metrics should never go to NodeDb but we'll safegaurd anyway
if (!info || t.which_variant != meshtastic_Telemetry_device_metrics_tag)
{
if (!info || t.which_variant != meshtastic_Telemetry_device_metrics_tag) {
return;
}
if (src == RX_SRC_LOCAL)
{
if (src == RX_SRC_LOCAL) {
// Local packet, fully authoritative
LOG_DEBUG("updateTelemetry LOCAL\n");
}
else
{
} else {
LOG_DEBUG("updateTelemetry REMOTE node=0x%x \n", nodeId);
}
info->device_metrics = t.variant.device_metrics;
@ -961,8 +886,7 @@ void NodeDB::updateTelemetry(uint32_t nodeId, const meshtastic_Telemetry &t, RxS
bool NodeDB::updateUser(uint32_t nodeId, const meshtastic_User &p, uint8_t channelIndex)
{
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(nodeId);
if (!info)
{
if (!info) {
return false;
}
@ -978,8 +902,7 @@ bool NodeDB::updateUser(uint32_t nodeId, const meshtastic_User &p, uint8_t chann
info->user.short_name, info->channel);
info->has_user = true;
if (changed)
{
if (changed) {
updateGUIforNode = info;
powerFSM.trigger(EVENT_NODEDB_UPDATED);
notifyObservers(true); // Force an update whether or not our node counts have changed
@ -995,13 +918,11 @@ bool NodeDB::updateUser(uint32_t nodeId, const meshtastic_User &p, uint8_t chann
/// we updateGUI and updateGUIforNode if we think our this change is big enough for a redraw
void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
{
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.from)
{
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.from) {
LOG_DEBUG("Update DB node 0x%x, rx_time=%u\n", mp.from, mp.rx_time);
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(getFrom(&mp));
if (!info)
{
if (!info) {
return;
}
@ -1022,8 +943,7 @@ void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
uint8_t NodeDB::getMeshNodeChannel(NodeNum n)
{
const meshtastic_NodeInfoLite *info = getMeshNode(n);
if (!info)
{
if (!info) {
return 0; // defaults to PRIMARY
}
return info->channel;
@ -1045,27 +965,22 @@ meshtastic_NodeInfoLite *NodeDB::getOrCreateMeshNode(NodeNum n)
{
meshtastic_NodeInfoLite *lite = getMeshNode(n);
if (!lite)
{
if ((numMeshNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfoLite_size * 3))
{
if (!lite) {
if ((numMeshNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < meshtastic_NodeInfoLite_size * 3)) {
if (screen)
screen->print("Warn: node database full!\nErasing oldest entry\n");
LOG_WARN("Node database full! Erasing oldest entry\n");
// look for oldest node and erase it
uint32_t oldest = UINT32_MAX;
int oldestIndex = -1;
for (int i = 1; i < numMeshNodes; i++)
{
if (!meshNodes->at(i).is_favorite && meshNodes->at(i).last_heard < oldest)
{
for (int i = 1; i < numMeshNodes; i++) {
if (!meshNodes->at(i).is_favorite && meshNodes->at(i).last_heard < oldest) {
oldest = meshNodes->at(i).last_heard;
oldestIndex = i;
}
}
// Shove the remaining nodes down the chain
for (int i = oldestIndex; i < numMeshNodes - 1; i++)
{
for (int i = oldestIndex; i < numMeshNodes - 1; i++) {
meshNodes->at(i) = meshNodes->at(i + 1);
}
(numMeshNodes)--;
@ -1087,12 +1002,9 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
// Print error to screen and serial port
String lcd = String("Critical error ") + code + "!\n";
screen->print(lcd.c_str());
if (filename)
{
if (filename) {
LOG_ERROR("NOTE! Recording critical error %d at %s:%lu\n", code, filename, address);
}
else
{
} else {
LOG_ERROR("NOTE! Recording critical error %d, address=0x%lx\n", code, address);
}