mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-11 04:17:43 +00:00
Merge branch 'master' into nomad-gemini
This commit is contained in:
@@ -123,23 +123,23 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
* Getters
|
||||
*/
|
||||
case meshtastic_AdminMessage_get_owner_request_tag:
|
||||
LOG_INFO("Client got owner");
|
||||
LOG_DEBUG("Client got owner");
|
||||
handleGetOwner(mp);
|
||||
break;
|
||||
|
||||
case meshtastic_AdminMessage_get_config_request_tag:
|
||||
LOG_INFO("Client got config");
|
||||
LOG_DEBUG("Client got config");
|
||||
handleGetConfig(mp, r->get_config_request);
|
||||
break;
|
||||
|
||||
case meshtastic_AdminMessage_get_module_config_request_tag:
|
||||
LOG_INFO("Client got module config");
|
||||
LOG_DEBUG("Client got module config");
|
||||
handleGetModuleConfig(mp, r->get_module_config_request);
|
||||
break;
|
||||
|
||||
case meshtastic_AdminMessage_get_channel_request_tag: {
|
||||
uint32_t i = r->get_channel_request - 1;
|
||||
LOG_INFO("Client got channel %u", i);
|
||||
LOG_DEBUG("Client got channel %u", i);
|
||||
if (i >= MAX_NUM_CHANNELS)
|
||||
myReply = allocErrorResponse(meshtastic_Routing_Error_BAD_REQUEST, &mp);
|
||||
else
|
||||
@@ -151,35 +151,35 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
* Setters
|
||||
*/
|
||||
case meshtastic_AdminMessage_set_owner_tag:
|
||||
LOG_INFO("Client set owner");
|
||||
LOG_DEBUG("Client set owner");
|
||||
handleSetOwner(r->set_owner);
|
||||
break;
|
||||
|
||||
case meshtastic_AdminMessage_set_config_tag:
|
||||
LOG_INFO("Client set config");
|
||||
LOG_DEBUG("Client set config");
|
||||
handleSetConfig(r->set_config);
|
||||
break;
|
||||
|
||||
case meshtastic_AdminMessage_set_module_config_tag:
|
||||
LOG_INFO("Client set module config");
|
||||
LOG_DEBUG("Client set module config");
|
||||
if (!handleSetModuleConfig(r->set_module_config)) {
|
||||
myReply = allocErrorResponse(meshtastic_Routing_Error_BAD_REQUEST, &mp);
|
||||
}
|
||||
break;
|
||||
|
||||
case meshtastic_AdminMessage_set_channel_tag:
|
||||
LOG_INFO("Client set channel %d", r->set_channel.index);
|
||||
LOG_DEBUG("Client set channel %d", r->set_channel.index);
|
||||
if (r->set_channel.index < 0 || r->set_channel.index >= (int)MAX_NUM_CHANNELS)
|
||||
myReply = allocErrorResponse(meshtastic_Routing_Error_BAD_REQUEST, &mp);
|
||||
else
|
||||
handleSetChannel(r->set_channel);
|
||||
break;
|
||||
case meshtastic_AdminMessage_set_ham_mode_tag:
|
||||
LOG_INFO("Client set ham mode");
|
||||
LOG_DEBUG("Client set ham mode");
|
||||
handleSetHamMode(r->set_ham_mode);
|
||||
break;
|
||||
case meshtastic_AdminMessage_get_ui_config_request_tag: {
|
||||
LOG_INFO("Client is getting device-ui config");
|
||||
LOG_DEBUG("Client is getting device-ui config");
|
||||
handleGetDeviceUIConfig(mp);
|
||||
handled = true;
|
||||
break;
|
||||
@@ -285,7 +285,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(r->set_favorite_node);
|
||||
if (node != NULL) {
|
||||
node->is_favorite = true;
|
||||
saveChanges(SEGMENT_DEVICESTATE, false);
|
||||
saveChanges(SEGMENT_NODEDATABASE, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -294,7 +294,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(r->remove_favorite_node);
|
||||
if (node != NULL) {
|
||||
node->is_favorite = false;
|
||||
saveChanges(SEGMENT_DEVICESTATE, false);
|
||||
saveChanges(SEGMENT_NODEDATABASE, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -307,7 +307,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
node->has_position = false;
|
||||
node->user.public_key.size = 0;
|
||||
node->user.public_key.bytes[0] = 0;
|
||||
saveChanges(SEGMENT_DEVICESTATE, false);
|
||||
saveChanges(SEGMENT_NODEDATABASE, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -316,7 +316,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(r->remove_ignored_node);
|
||||
if (node != NULL) {
|
||||
node->is_ignored = false;
|
||||
saveChanges(SEGMENT_DEVICESTATE, false);
|
||||
saveChanges(SEGMENT_NODEDATABASE, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -327,7 +327,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
node->position = TypeConversions::ConvertToPositionLite(r->set_fixed_position);
|
||||
nodeDB->setLocalPosition(r->set_fixed_position);
|
||||
config.position.fixed_position = true;
|
||||
saveChanges(SEGMENT_DEVICESTATE | SEGMENT_CONFIG, false);
|
||||
saveChanges(SEGMENT_DEVICESTATE | SEGMENT_NODEDATABASE | SEGMENT_CONFIG, false);
|
||||
#if !MESHTASTIC_EXCLUDE_GPS
|
||||
if (gps != nullptr)
|
||||
gps->enable();
|
||||
@@ -340,7 +340,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
LOG_INFO("Client received remove_fixed_position command");
|
||||
nodeDB->clearLocalPosition();
|
||||
config.position.fixed_position = false;
|
||||
saveChanges(SEGMENT_DEVICESTATE | SEGMENT_CONFIG, false);
|
||||
saveChanges(SEGMENT_DEVICESTATE | SEGMENT_NODEDATABASE | SEGMENT_CONFIG, false);
|
||||
break;
|
||||
}
|
||||
case meshtastic_AdminMessage_set_time_only_tag: {
|
||||
@@ -391,7 +391,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
LOG_DEBUG("Did not responded to a request that wanted a respond. req.variant=%d", r->which_payload_variant);
|
||||
} else if (handleResult != AdminMessageHandleResult::HANDLED) {
|
||||
// Probably a message sent by us or sent to our local node. FIXME, we should avoid scanning these messages
|
||||
LOG_INFO("Ignore irrelevant admin %d", r->which_payload_variant);
|
||||
LOG_DEBUG("Ignore irrelevant admin %d", r->which_payload_variant);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -450,11 +450,14 @@ void AdminModule::handleSetOwner(const meshtastic_User &o)
|
||||
if (owner.is_licensed != o.is_licensed) {
|
||||
changed = 1;
|
||||
owner.is_licensed = o.is_licensed;
|
||||
if (channels.ensureLicensedOperation()) {
|
||||
sendWarning(licensedModeMessage);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) { // If nothing really changed, don't broadcast on the network or write to flash
|
||||
service->reloadOwner(!hasOpenEditTransaction);
|
||||
saveChanges(SEGMENT_DEVICESTATE);
|
||||
saveChanges(SEGMENT_DEVICESTATE | SEGMENT_NODEDATABASE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -748,6 +751,9 @@ bool AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
|
||||
void AdminModule::handleSetChannel(const meshtastic_Channel &cc)
|
||||
{
|
||||
channels.setChannel(cc);
|
||||
if (channels.ensureLicensedOperation()) {
|
||||
sendWarning(licensedModeMessage);
|
||||
}
|
||||
channels.onConfigChanged(); // tell the radios about this change
|
||||
saveChanges(SEGMENT_CHANNELS, false);
|
||||
}
|
||||
@@ -1085,15 +1091,14 @@ void AdminModule::handleSetHamMode(const meshtastic_HamParameters &p)
|
||||
|
||||
config.device.rebroadcast_mode = meshtastic_Config_DeviceConfig_RebroadcastMode_LOCAL_ONLY;
|
||||
// Remove PSK of primary channel for plaintext amateur usage
|
||||
auto primaryChannel = channels.getByIndex(channels.getPrimaryIndex());
|
||||
auto &channelSettings = primaryChannel.settings;
|
||||
channelSettings.psk.bytes[0] = 0;
|
||||
channelSettings.psk.size = 0;
|
||||
channels.setChannel(primaryChannel);
|
||||
|
||||
if (channels.ensureLicensedOperation()) {
|
||||
sendWarning(licensedModeMessage);
|
||||
}
|
||||
channels.onConfigChanged();
|
||||
|
||||
service->reloadOwner(false);
|
||||
saveChanges(SEGMENT_CONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
|
||||
saveChanges(SEGMENT_CONFIG | SEGMENT_NODEDATABASE | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
|
||||
}
|
||||
|
||||
AdminModule::AdminModule() : ProtobufModule("Admin", meshtastic_PortNum_ADMIN_APP, &meshtastic_AdminMessage_msg)
|
||||
@@ -1179,4 +1184,4 @@ void disableBluetooth()
|
||||
nrf52Bluetooth->shutdown();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,9 @@ class AdminModule : public ProtobufModule<meshtastic_AdminMessage>, public Obser
|
||||
void sendWarning(const char *message);
|
||||
};
|
||||
|
||||
static constexpr const char *licensedModeMessage =
|
||||
"Licensed mode activated, removing admin channel and encryption from all channels";
|
||||
|
||||
extern AdminModule *adminModule;
|
||||
|
||||
void disableBluetooth();
|
||||
@@ -20,6 +20,11 @@ bool RoutingModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mesh
|
||||
if ((nodeDB->getMeshNode(mp.from) == NULL || !nodeDB->getMeshNode(mp.from)->has_user) &&
|
||||
(nodeDB->getMeshNode(mp.to) == NULL || !nodeDB->getMeshNode(mp.to)->has_user))
|
||||
return false;
|
||||
} else if (owner.is_licensed && nodeDB->getLicenseStatus(mp.from) == UserLicenseStatus::NotLicensed) {
|
||||
// Don't let licensed users to rebroadcast packets from unlicensed users
|
||||
// If we know they are in-fact unlicensed
|
||||
LOG_DEBUG("Packet from unlicensed user, ignoring packet");
|
||||
return false;
|
||||
}
|
||||
|
||||
printPacket("Routing sniffing", &mp);
|
||||
|
||||
@@ -31,7 +31,6 @@ int32_t PowerTelemetryModule::runOnce()
|
||||
doDeepSleep(nightyNightMs, true, false);
|
||||
}
|
||||
|
||||
uint32_t result = UINT32_MAX;
|
||||
/*
|
||||
Uncomment the preferences below if you want to use the module
|
||||
without having to configure it from the PythonAPI or WebUI.
|
||||
@@ -46,25 +45,33 @@ int32_t PowerTelemetryModule::runOnce()
|
||||
return disable();
|
||||
}
|
||||
|
||||
uint32_t sendToMeshIntervalMs = Default::getConfiguredOrDefaultMsScaled(
|
||||
moduleConfig.telemetry.power_update_interval, default_telemetry_broadcast_interval_secs, numOnlineNodes);
|
||||
|
||||
if (firstTime) {
|
||||
// This is the first time the OSThread library has called this function, so do some setup
|
||||
firstTime = 0;
|
||||
uint32_t result = UINT32_MAX;
|
||||
|
||||
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
|
||||
if (moduleConfig.telemetry.power_measurement_enabled) {
|
||||
LOG_INFO("Power Telemetry: init");
|
||||
// it's possible to have this module enabled, only for displaying values on the screen.
|
||||
// therefore, we should only enable the sensor loop if measurement is also enabled
|
||||
if (ina219Sensor.hasSensor() && !ina219Sensor.isInitialized())
|
||||
result = ina219Sensor.runOnce();
|
||||
if (ina226Sensor.hasSensor() && !ina226Sensor.isInitialized())
|
||||
result = ina226Sensor.runOnce();
|
||||
if (ina260Sensor.hasSensor() && !ina260Sensor.isInitialized())
|
||||
result = ina260Sensor.runOnce();
|
||||
if (ina3221Sensor.hasSensor() && !ina3221Sensor.isInitialized())
|
||||
result = ina3221Sensor.runOnce();
|
||||
if (max17048Sensor.hasSensor() && !max17048Sensor.isInitialized())
|
||||
result = max17048Sensor.runOnce();
|
||||
// If sensor is already initialized by EnvironmentTelemetryModule, then we don't need to initialize it again,
|
||||
// but we need to set the result to != UINT32_MAX to avoid it being disabled
|
||||
if (ina219Sensor.hasSensor())
|
||||
result = ina219Sensor.isInitialized() ? 0 : ina219Sensor.runOnce();
|
||||
if (ina226Sensor.hasSensor())
|
||||
result = ina226Sensor.isInitialized() ? 0 : ina226Sensor.runOnce();
|
||||
if (ina260Sensor.hasSensor())
|
||||
result = ina260Sensor.isInitialized() ? 0 : ina260Sensor.runOnce();
|
||||
if (ina3221Sensor.hasSensor())
|
||||
result = ina3221Sensor.isInitialized() ? 0 : ina3221Sensor.runOnce();
|
||||
if (max17048Sensor.hasSensor())
|
||||
result = max17048Sensor.isInitialized() ? 0 : max17048Sensor.runOnce();
|
||||
}
|
||||
|
||||
// it's possible to have this module enabled, only for displaying values on the screen.
|
||||
// therefore, we should only enable the sensor loop if measurement is also enabled
|
||||
return result == UINT32_MAX ? disable() : setStartDelay();
|
||||
#else
|
||||
return disable();
|
||||
@@ -74,10 +81,7 @@ int32_t PowerTelemetryModule::runOnce()
|
||||
if (!moduleConfig.telemetry.power_measurement_enabled)
|
||||
return disable();
|
||||
|
||||
if (((lastSentToMesh == 0) ||
|
||||
!Throttle::isWithinTimespanMs(lastSentToMesh, Default::getConfiguredOrDefaultMsScaled(
|
||||
moduleConfig.telemetry.power_update_interval,
|
||||
default_telemetry_broadcast_interval_secs, numOnlineNodes))) &&
|
||||
if (((lastSentToMesh == 0) || !Throttle::isWithinTimespanMs(lastSentToMesh, sendToMeshIntervalMs)) &&
|
||||
airTime->isTxAllowedAirUtil()) {
|
||||
sendTelemetry();
|
||||
lastSentToMesh = millis();
|
||||
@@ -89,8 +93,9 @@ int32_t PowerTelemetryModule::runOnce()
|
||||
lastSentToPhone = millis();
|
||||
}
|
||||
}
|
||||
return min(sendToPhoneIntervalMs, result);
|
||||
return min(sendToPhoneIntervalMs, sendToMeshIntervalMs);
|
||||
}
|
||||
|
||||
bool PowerTelemetryModule::wantUIFrame()
|
||||
{
|
||||
return moduleConfig.telemetry.power_screen_enabled;
|
||||
|
||||
@@ -109,7 +109,7 @@ void TraceRouteModule::appendMyIDandSNR(meshtastic_RouteDiscovery *updated, floa
|
||||
void TraceRouteModule::printRoute(meshtastic_RouteDiscovery *r, uint32_t origin, uint32_t dest, bool isTowardsDestination)
|
||||
{
|
||||
#ifdef DEBUG_PORT
|
||||
std::string route = "Route traced:";
|
||||
std::string route = "Route traced:\n";
|
||||
route += vformat("0x%x --> ", origin);
|
||||
for (uint8_t i = 0; i < r->route_count; i++) {
|
||||
if (i < r->snr_towards_count && r->snr_towards[i] != INT8_MIN)
|
||||
@@ -129,6 +129,7 @@ void TraceRouteModule::printRoute(meshtastic_RouteDiscovery *r, uint32_t origin,
|
||||
|
||||
// If there's a route back (or we are the destination as then the route is complete), print it
|
||||
if (r->route_back_count > 0 || origin == nodeDB->getNodeNum()) {
|
||||
route += "\n";
|
||||
if (r->snr_towards_count > 0 && origin == nodeDB->getNodeNum())
|
||||
route += vformat("(%.2fdB) 0x%x <-- ", (float)r->snr_back[r->snr_back_count - 1] / 4, origin);
|
||||
else
|
||||
@@ -150,6 +151,12 @@ meshtastic_MeshPacket *TraceRouteModule::allocReply()
|
||||
{
|
||||
assert(currentRequest);
|
||||
|
||||
// Ignore multi-hop broadcast requests
|
||||
if (isBroadcast(currentRequest->to) && currentRequest->hop_limit < currentRequest->hop_start) {
|
||||
ignoreRequest = true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Copy the payload of the current request
|
||||
auto req = *currentRequest;
|
||||
const auto &p = req.decoded;
|
||||
|
||||
@@ -144,9 +144,9 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state,
|
||||
bearingToOther -= myHeading;
|
||||
screen->drawNodeHeading(display, compassX, compassY, compassDiam, bearingToOther);
|
||||
|
||||
float bearingToOtherDegrees = (bearingToOther < 0) ? bearingToOther + 2*PI : bearingToOther;
|
||||
bearingToOtherDegrees = bearingToOtherDegrees * 180 / PI;
|
||||
|
||||
float bearingToOtherDegrees = (bearingToOther < 0) ? bearingToOther + 2 * PI : bearingToOther;
|
||||
bearingToOtherDegrees = bearingToOtherDegrees * 180 / PI;
|
||||
|
||||
// Distance to Waypoint
|
||||
float d = GeoCoord::latLongToMeter(DegD(wp.latitude_i), DegD(wp.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
|
||||
if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) {
|
||||
@@ -161,7 +161,6 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state,
|
||||
snprintf(distStr, sizeof(distStr), "%.1fkm %.0f°", d / 1000, bearingToOtherDegrees);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// If our node doesn't have position
|
||||
|
||||
Reference in New Issue
Block a user