mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-19 08:17:36 +00:00
Meshtastic unified OTA (#9231)
* Initial commit of combined BLE and WiFi OTA * Incorporate ota_hash in AdminMessage protobuf * OTA protobuf changes * Trunk fmt --------- Co-authored-by: Jake-B <jake-b@users.noreply.github.com>
This commit is contained in:
@@ -9,11 +9,8 @@
|
||||
#include "meshUtils.h"
|
||||
#include <FSCommon.h>
|
||||
#include <ctype.h> // for better whitespace handling
|
||||
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_BLUETOOTH
|
||||
#include "BleOta.h"
|
||||
#endif
|
||||
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_WIFI
|
||||
#include "WiFiOTA.h"
|
||||
#include "MeshtasticOTA.h"
|
||||
#endif
|
||||
#include "Router.h"
|
||||
#include "configuration.h"
|
||||
@@ -236,28 +233,27 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
reboot(r->reboot_seconds);
|
||||
break;
|
||||
}
|
||||
case meshtastic_AdminMessage_reboot_ota_seconds_tag: {
|
||||
int32_t s = r->reboot_ota_seconds;
|
||||
case meshtastic_AdminMessage_ota_request_tag: {
|
||||
#if defined(ARCH_ESP32)
|
||||
#if !MESHTASTIC_EXCLUDE_BLUETOOTH
|
||||
if (!BleOta::getOtaAppVersion().isEmpty()) {
|
||||
if (r->ota_request.ota_hash.size != 32) {
|
||||
suppressRebootBanner = true;
|
||||
if (screen)
|
||||
screen->startFirmwareUpdateScreen();
|
||||
BleOta::switchToOtaApp();
|
||||
LOG_INFO("Rebooting to BLE OTA");
|
||||
LOG_INFO("OTA Failed: Invalid `ota_hash` provided");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if !MESHTASTIC_EXCLUDE_WIFI
|
||||
if (WiFiOTA::trySwitchToOTA()) {
|
||||
|
||||
meshtastic_OTAMode mode = r->ota_request.reboot_ota_mode;
|
||||
if (MeshtasticOTA::trySwitchToOTA()) {
|
||||
LOG_INFO("OTA Requested");
|
||||
suppressRebootBanner = true;
|
||||
if (screen)
|
||||
screen->startFirmwareUpdateScreen();
|
||||
WiFiOTA::saveConfig(&config.network);
|
||||
MeshtasticOTA::saveConfig(&config.network, mode, r->ota_request.ota_hash.bytes);
|
||||
LOG_INFO("Rebooting to WiFi OTA");
|
||||
} else {
|
||||
LOG_INFO("WIFI OTA Failed");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
int s = 1; // Reboot in 1 second, hard coded
|
||||
LOG_INFO("Reboot in %d seconds", s);
|
||||
rebootAtMsec = (s < 0) ? 0 : (millis() + s * 1000);
|
||||
break;
|
||||
|
||||
@@ -3,26 +3,25 @@
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR
|
||||
|
||||
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||
#include "Default.h"
|
||||
#include "AirQualityTelemetry.h"
|
||||
#include "Default.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "RTC.h"
|
||||
#include "Router.h"
|
||||
#include "Sensor/AddI2CSensorTemplate.h"
|
||||
#include "UnitConversions.h"
|
||||
#include "graphics/ScreenFonts.h"
|
||||
#include "graphics/SharedUIDisplay.h"
|
||||
#include "graphics/images.h"
|
||||
#include "graphics/ScreenFonts.h"
|
||||
#include "main.h"
|
||||
#include "sleep.h"
|
||||
#include <Throttle.h>
|
||||
#include "Sensor/AddI2CSensorTemplate.h"
|
||||
|
||||
// Sensors
|
||||
#include "Sensor/PMSA003ISensor.h"
|
||||
|
||||
|
||||
void AirQualityTelemetryModule::i2cScanFinished(ScanI2C *i2cScanner)
|
||||
{
|
||||
if (!moduleConfig.telemetry.air_quality_enabled && !AIR_QUALITY_TELEMETRY_MODULE_ENABLE) {
|
||||
@@ -57,7 +56,7 @@ int32_t AirQualityTelemetryModule::runOnce()
|
||||
|
||||
uint32_t result = UINT32_MAX;
|
||||
|
||||
if (!(moduleConfig.telemetry.air_quality_enabled || moduleConfig.telemetry.air_quality_screen_enabled ||
|
||||
if (!(moduleConfig.telemetry.air_quality_enabled || moduleConfig.telemetry.air_quality_screen_enabled ||
|
||||
AIR_QUALITY_TELEMETRY_MODULE_ENABLE)) {
|
||||
// If this module is not enabled, and the user doesn't want the display screen don't waste any OSThread time on it
|
||||
return disable();
|
||||
@@ -74,7 +73,6 @@ int32_t AirQualityTelemetryModule::runOnce()
|
||||
if (!sensors.empty()) {
|
||||
result = DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// it's possible to have this module enabled, only for displaying values on the screen.
|
||||
@@ -95,27 +93,26 @@ int32_t AirQualityTelemetryModule::runOnce()
|
||||
}
|
||||
|
||||
if (((lastSentToMesh == 0) ||
|
||||
!Throttle::isWithinTimespanMs(lastSentToMesh, Default::getConfiguredOrDefaultMsScaled(
|
||||
moduleConfig.telemetry.air_quality_interval,
|
||||
default_telemetry_broadcast_interval_secs, numOnlineNodes))) &&
|
||||
!Throttle::isWithinTimespanMs(lastSentToMesh, Default::getConfiguredOrDefaultMsScaled(
|
||||
moduleConfig.telemetry.air_quality_interval,
|
||||
default_telemetry_broadcast_interval_secs, numOnlineNodes))) &&
|
||||
airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_SENSOR) &&
|
||||
airTime->isTxAllowedAirUtil()) {
|
||||
sendTelemetry();
|
||||
lastSentToMesh = millis();
|
||||
} else if (((lastSentToPhone == 0) || !Throttle::isWithinTimespanMs(lastSentToPhone, sendToPhoneIntervalMs)) &&
|
||||
(service->isToPhoneQueueEmpty())) {
|
||||
(service->isToPhoneQueueEmpty())) {
|
||||
// Just send to phone when it's not our time to send to mesh yet
|
||||
// Only send while queue is empty (phone assumed connected)
|
||||
sendTelemetry(NODENUM_BROADCAST, true);
|
||||
lastSentToPhone = millis();
|
||||
}
|
||||
|
||||
// Send to sleep sensors that consume power
|
||||
LOG_INFO("Sending sensors to sleep");
|
||||
for (TelemetrySensor *sensor : sensors) {
|
||||
sensor->sleep();
|
||||
}
|
||||
|
||||
// Send to sleep sensors that consume power
|
||||
LOG_INFO("Sending sensors to sleep");
|
||||
for (TelemetrySensor *sensor : sensors) {
|
||||
sensor->sleep();
|
||||
}
|
||||
}
|
||||
return min(sendToPhoneIntervalMs, result);
|
||||
}
|
||||
@@ -161,8 +158,8 @@ void AirQualityTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiSta
|
||||
const auto &m = telemetry.variant.air_quality_metrics;
|
||||
|
||||
// Check if any telemetry field has valid data
|
||||
bool hasAny = m.has_pm10_standard || m.has_pm25_standard || m.has_pm100_standard || m.has_pm10_environmental || m.has_pm25_environmental ||
|
||||
m.has_pm100_environmental;
|
||||
bool hasAny = m.has_pm10_standard || m.has_pm25_standard || m.has_pm100_standard || m.has_pm10_environmental ||
|
||||
m.has_pm25_environmental || m.has_pm100_environmental;
|
||||
|
||||
if (!hasAny) {
|
||||
display->drawString(x, currentY, "No Telemetry");
|
||||
@@ -296,10 +293,10 @@ bool AirQualityTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
|
||||
m.time = getTime();
|
||||
if (getAirQualityTelemetry(&m)) {
|
||||
LOG_INFO("Send: pm10_standard=%u, pm25_standard=%u, pm100_standard=%u, \
|
||||
pm10_environmental=%u, pm25_environmental=%u, pm100_environmental=%u", \
|
||||
m.variant.air_quality_metrics.pm10_standard, m.variant.air_quality_metrics.pm25_standard, \
|
||||
m.variant.air_quality_metrics.pm100_standard, m.variant.air_quality_metrics.pm10_environmental, \
|
||||
m.variant.air_quality_metrics.pm25_environmental, m.variant.air_quality_metrics.pm100_environmental);
|
||||
pm10_environmental=%u, pm25_environmental=%u, pm100_environmental=%u",
|
||||
m.variant.air_quality_metrics.pm10_standard, m.variant.air_quality_metrics.pm25_standard,
|
||||
m.variant.air_quality_metrics.pm100_standard, m.variant.air_quality_metrics.pm10_environmental,
|
||||
m.variant.air_quality_metrics.pm25_environmental, m.variant.air_quality_metrics.pm100_environmental);
|
||||
|
||||
meshtastic_MeshPacket *p = allocDataProtobuf(m);
|
||||
p->to = dest;
|
||||
@@ -341,8 +338,8 @@ bool AirQualityTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
|
||||
}
|
||||
|
||||
AdminMessageHandleResult AirQualityTelemetryModule::handleAdminMessageForModule(const meshtastic_MeshPacket &mp,
|
||||
meshtastic_AdminMessage *request,
|
||||
meshtastic_AdminMessage *response)
|
||||
meshtastic_AdminMessage *request,
|
||||
meshtastic_AdminMessage *response)
|
||||
{
|
||||
AdminMessageHandleResult result = AdminMessageHandleResult::NOT_HANDLED;
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
#include <OLEDDisplayUi.h>
|
||||
|
||||
class AirQualityTelemetryModule : private concurrency::OSThread,
|
||||
public ScanI2CConsumer,
|
||||
public ProtobufModule<meshtastic_Telemetry>
|
||||
public ScanI2CConsumer,
|
||||
public ProtobufModule<meshtastic_Telemetry>
|
||||
{
|
||||
CallbackObserver<AirQualityTelemetryModule, const meshtastic::Status *> nodeStatusObserver =
|
||||
CallbackObserver<AirQualityTelemetryModule, const meshtastic::Status *>(this,
|
||||
|
||||
@@ -141,9 +141,9 @@ extern void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const c
|
||||
#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10
|
||||
#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true
|
||||
|
||||
#include "Sensor/AddI2CSensorTemplate.h"
|
||||
#include "graphics/ScreenFonts.h"
|
||||
#include <Throttle.h>
|
||||
#include "Sensor/AddI2CSensorTemplate.h"
|
||||
|
||||
void EnvironmentTelemetryModule::i2cScanFinished(ScanI2C *i2cScanner)
|
||||
{
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR || !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR
|
||||
|
||||
#include <forward_list>
|
||||
#include "TelemetrySensor.h"
|
||||
#include "detect/ScanI2C.h"
|
||||
#include "detect/ScanI2CTwoWire.h"
|
||||
#include <Wire.h>
|
||||
#include <forward_list>
|
||||
|
||||
static std::forward_list<TelemetrySensor *> sensors;
|
||||
|
||||
|
||||
@@ -2,17 +2,14 @@
|
||||
|
||||
#if !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR
|
||||
|
||||
#include "../detect/reClockI2C.h"
|
||||
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||
#include "PMSA003ISensor.h"
|
||||
#include "TelemetrySensor.h"
|
||||
#include "../detect/reClockI2C.h"
|
||||
|
||||
#include <Wire.h>
|
||||
|
||||
PMSA003ISensor::PMSA003ISensor()
|
||||
: TelemetrySensor(meshtastic_TelemetrySensorType_PMSA003I, "PMSA003I")
|
||||
{
|
||||
}
|
||||
PMSA003ISensor::PMSA003ISensor() : TelemetrySensor(meshtastic_TelemetrySensorType_PMSA003I, "PMSA003I") {}
|
||||
|
||||
bool PMSA003ISensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
|
||||
{
|
||||
@@ -26,7 +23,7 @@ bool PMSA003ISensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
|
||||
|
||||
#if defined(PMSA003I_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C)
|
||||
uint32_t currentClock = reClockI2C(PMSA003I_I2C_CLOCK_SPEED, _bus);
|
||||
if (!currentClock){
|
||||
if (!currentClock) {
|
||||
LOG_WARN("PMSA003I can't be used at this clock speed");
|
||||
return false;
|
||||
}
|
||||
@@ -51,7 +48,7 @@ bool PMSA003ISensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
|
||||
|
||||
bool PMSA003ISensor::getMetrics(meshtastic_Telemetry *measurement)
|
||||
{
|
||||
if(!isActive()){
|
||||
if (!isActive()) {
|
||||
LOG_WARN("PMSA003I is not active");
|
||||
return false;
|
||||
}
|
||||
@@ -79,9 +76,7 @@ bool PMSA003ISensor::getMetrics(meshtastic_Telemetry *measurement)
|
||||
return false;
|
||||
}
|
||||
|
||||
auto read16 = [](uint8_t *data, uint8_t idx) -> uint16_t {
|
||||
return (data[idx] << 8) | data[idx + 1];
|
||||
};
|
||||
auto read16 = [](uint8_t *data, uint8_t idx) -> uint16_t { return (data[idx] << 8) | data[idx + 1]; };
|
||||
|
||||
computedChecksum = 0;
|
||||
|
||||
@@ -141,7 +136,6 @@ bool PMSA003ISensor::isActive()
|
||||
return state == State::ACTIVE;
|
||||
}
|
||||
|
||||
|
||||
void PMSA003ISensor::sleep()
|
||||
{
|
||||
#ifdef PMSA003I_ENABLE_PIN
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
#include "TelemetrySensor.h"
|
||||
|
||||
#define PMSA003I_I2C_CLOCK_SPEED 100000
|
||||
#define PMSA003I_FRAME_LENGTH 32
|
||||
#define PMSA003I_FRAME_LENGTH 32
|
||||
#define PMSA003I_WARMUP_MS 30000
|
||||
|
||||
class PMSA003ISensor : public TelemetrySensor
|
||||
{
|
||||
public:
|
||||
public:
|
||||
PMSA003ISensor();
|
||||
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
|
||||
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
virtual void sleep() override;
|
||||
virtual uint32_t wakeUp() override;
|
||||
|
||||
private:
|
||||
private:
|
||||
enum class State { IDLE, ACTIVE };
|
||||
State state = State::ACTIVE;
|
||||
|
||||
@@ -28,7 +28,7 @@ private:
|
||||
uint16_t receivedChecksum = 0;
|
||||
|
||||
uint8_t buffer[PMSA003I_FRAME_LENGTH]{};
|
||||
TwoWire * _bus{};
|
||||
TwoWire *_bus{};
|
||||
uint8_t _address{};
|
||||
};
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ class TelemetrySensor
|
||||
// TODO: delete after migration
|
||||
bool hasSensor() { return nodeTelemetrySensorsMap[sensorType].first > 0; }
|
||||
// Functions to sleep / wakeup sensors that support it
|
||||
virtual void sleep() {};
|
||||
virtual void sleep(){};
|
||||
virtual uint32_t wakeUp() { return 0; }
|
||||
// Return active by default, override per sensor
|
||||
virtual bool isActive() { return true; }
|
||||
|
||||
Reference in New Issue
Block a user