Initial commit of combined BLE and WiFi OTA

This commit is contained in:
Jake-B
2025-12-21 20:38:44 -05:00
parent 83c6161ac6
commit e93abf85c0
7 changed files with 34 additions and 113 deletions

View File

@@ -53,7 +53,7 @@
#endif #endif
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_WIFI #if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_WIFI
#include <WiFiOTA.h> #include <MeshtasticOTA.h>
#endif #endif
NodeDB *nodeDB = nullptr; NodeDB *nodeDB = nullptr;
@@ -739,8 +739,8 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
config.display.compass_orientation = COMPASS_ORIENTATION; config.display.compass_orientation = COMPASS_ORIENTATION;
#endif #endif
#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_WIFI #if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_WIFI
if (WiFiOTA::isUpdated()) { if (MeshtasticOTA::isUpdated()) {
WiFiOTA::recoverConfig(&config.network); MeshtasticOTA::recoverConfig(&config.network);
} }
#endif #endif

View File

@@ -9,11 +9,8 @@
#include "meshUtils.h" #include "meshUtils.h"
#include <FSCommon.h> #include <FSCommon.h>
#include <ctype.h> // for better whitespace handling #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 #if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_WIFI
#include "WiFiOTA.h" #include "MeshtasticOTA.h"
#endif #endif
#include "Router.h" #include "Router.h"
#include "configuration.h" #include "configuration.h"
@@ -237,24 +234,18 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
break; break;
} }
case meshtastic_AdminMessage_reboot_ota_seconds_tag: { case meshtastic_AdminMessage_reboot_ota_seconds_tag: {
// TODO: Update to new protobufs
int32_t s = r->reboot_ota_seconds; int32_t s = r->reboot_ota_seconds;
#if defined(ARCH_ESP32) #if defined(ARCH_ESP32)
#if !MESHTASTIC_EXCLUDE_BLUETOOTH if (MeshtasticOTA::trySwitchToOTA()) {
if (!BleOta::getOtaAppVersion().isEmpty()) { LOG_INFO("OTA Requested");
if (screen) if (screen)
screen->startFirmwareUpdateScreen(); screen->startFirmwareUpdateScreen();
BleOta::switchToOtaApp(); MeshtasticOTA::saveConfig(&config.network, (s % 2) & 0b1);
LOG_INFO("Rebooting to BLE OTA");
}
#endif
#if !MESHTASTIC_EXCLUDE_WIFI
if (WiFiOTA::trySwitchToOTA()) {
if (screen)
screen->startFirmwareUpdateScreen();
WiFiOTA::saveConfig(&config.network);
LOG_INFO("Rebooting to WiFi OTA"); LOG_INFO("Rebooting to WiFi OTA");
} else {
LOG_INFO("WIFI OTA Failed");
} }
#endif
#endif #endif
LOG_INFO("Reboot in %d seconds", s); LOG_INFO("Reboot in %d seconds", s);
rebootAtMsec = (s < 0) ? 0 : (millis() + s * 1000); rebootAtMsec = (s < 0) ? 0 : (millis() + s * 1000);

View File

@@ -1,46 +0,0 @@
#include "BleOta.h"
#include "Arduino.h"
#include <esp_ota_ops.h>
static const String MESHTASTIC_OTA_APP_PROJECT_NAME("Meshtastic-OTA");
const esp_partition_t *BleOta::findEspOtaAppPartition()
{
const esp_partition_t *part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_0, nullptr);
esp_app_desc_t app_desc;
esp_err_t ret = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_ota_get_partition_description(part, &app_desc));
if (ret != ESP_OK || MESHTASTIC_OTA_APP_PROJECT_NAME != app_desc.project_name) {
part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_1, nullptr);
ret = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_ota_get_partition_description(part, &app_desc));
}
if (ret == ESP_OK && MESHTASTIC_OTA_APP_PROJECT_NAME == app_desc.project_name) {
return part;
} else {
return nullptr;
}
}
String BleOta::getOtaAppVersion()
{
const esp_partition_t *part = findEspOtaAppPartition();
esp_app_desc_t app_desc;
esp_err_t ret = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_ota_get_partition_description(part, &app_desc));
String version;
if (ret == ESP_OK) {
version = app_desc.version;
}
return version;
}
bool BleOta::switchToOtaApp()
{
bool success = false;
const esp_partition_t *part = findEspOtaAppPartition();
if (part) {
success = (ESP_ERROR_CHECK_WITHOUT_ABORT(esp_ota_set_boot_partition(part)) == ESP_OK);
}
return success;
}

View File

@@ -1,20 +0,0 @@
#ifndef BLEOTA_H
#define BLEOTA_H
#include <Arduino.h>
#include <functional>
class BleOta
{
public:
explicit BleOta(){};
static String getOtaAppVersion();
static bool switchToOtaApp();
private:
String mUserAgent;
static const esp_partition_t *findEspOtaAppPartition();
};
#endif // BLEOTA_H

View File

@@ -1,13 +1,13 @@
#include "WiFiOTA.h" #include "MeshtasticOTA.h"
#include "configuration.h" #include "configuration.h"
#include <Preferences.h> #include <Preferences.h>
#include <esp_ota_ops.h> #include <esp_ota_ops.h>
namespace WiFiOTA namespace MeshtasticOTA
{ {
static const char *nvsNamespace = "ota-wifi"; static const char *nvsNamespace = "MeshtasticOTA";
static const char *appProjectName = "OTA-WiFi"; static const char *appProjectName = "MeshtasticOTA";
static bool updated = false; static bool updated = false;
@@ -43,12 +43,13 @@ void recoverConfig(meshtastic_Config_NetworkConfig *network)
strncpy(network->wifi_psk, psk.c_str(), sizeof(network->wifi_psk)); strncpy(network->wifi_psk, psk.c_str(), sizeof(network->wifi_psk));
} }
void saveConfig(meshtastic_Config_NetworkConfig *network) void saveConfig(meshtastic_Config_NetworkConfig *network, bool method)
{ {
LOG_INFO("Saving WiFi settings for upcoming OTA update"); LOG_INFO("Saving WiFi settings for upcoming OTA update");
Preferences prefs; Preferences prefs;
prefs.begin(nvsNamespace); prefs.begin(nvsNamespace);
prefs.putUChar("method", method);
prefs.putString("ssid", network->wifi_ssid); prefs.putString("ssid", network->wifi_ssid);
prefs.putString("psk", network->wifi_psk); prefs.putString("psk", network->wifi_psk);
prefs.putBool("updated", false); prefs.putBool("updated", false);
@@ -62,10 +63,14 @@ const esp_partition_t *getAppPartition()
bool getAppDesc(const esp_partition_t *part, esp_app_desc_t *app_desc) bool getAppDesc(const esp_partition_t *part, esp_app_desc_t *app_desc)
{ {
if (esp_ota_get_partition_description(part, app_desc) != ESP_OK) if (esp_ota_get_partition_description(part, app_desc) != ESP_OK) {
LOG_INFO("esp_ota_get_partition_description failed");
return false; return false;
if (strcmp(app_desc->project_name, appProjectName) != 0) }
if (strcmp(app_desc->project_name, appProjectName) != 0) {
LOG_INFO("app_desc->project_name == 0");
return false; return false;
}
return true; return true;
} }
@@ -89,4 +94,4 @@ const char *getVersion()
return app_desc.version; return app_desc.version;
} }
} // namespace WiFiOTA } // namespace MeshtasticOTA

View File

@@ -1,18 +1,18 @@
#ifndef WIFIOTA_H #ifndef MESHTASTICOTA_H
#define WIFIOTA_H #define MESHTASTICOTA_H
#include "mesh-pb-constants.h" #include "mesh-pb-constants.h"
#include <Arduino.h> #include <Arduino.h>
namespace WiFiOTA namespace MeshtasticOTA
{ {
void initialize(); void initialize();
bool isUpdated(); bool isUpdated();
void recoverConfig(meshtastic_Config_NetworkConfig *network); void recoverConfig(meshtastic_Config_NetworkConfig *network);
void saveConfig(meshtastic_Config_NetworkConfig *network); void saveConfig(meshtastic_Config_NetworkConfig *network, bool method);
bool trySwitchToOTA(); bool trySwitchToOTA();
const char *getVersion(); const char *getVersion();
} // namespace WiFiOTA } // namespace MeshtasticOTA
#endif // WIFIOTA_H #endif // MESHTASTICOTA_H

View File

@@ -5,11 +5,10 @@
#include "main.h" #include "main.h"
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !MESHTASTIC_EXCLUDE_BLUETOOTH #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !MESHTASTIC_EXCLUDE_BLUETOOTH
#include "BleOta.h"
#include "nimble/NimbleBluetooth.h" #include "nimble/NimbleBluetooth.h"
#endif #endif
#include <WiFiOTA.h> #include <MeshtasticOTA.h>
#if HAS_WIFI #if HAS_WIFI
#include "mesh/wifi/WiFiAPClient.h" #include "mesh/wifi/WiFiAPClient.h"
@@ -144,22 +143,14 @@ void esp32Setup()
preferences.putUInt("hwVendor", HW_VENDOR); preferences.putUInt("hwVendor", HW_VENDOR);
preferences.end(); preferences.end();
LOG_DEBUG("Number of Device Reboots: %d", rebootCounter); LOG_DEBUG("Number of Device Reboots: %d", rebootCounter);
#if !MESHTASTIC_EXCLUDE_BLUETOOTH
String BLEOTA = BleOta::getOtaAppVersion();
if (BLEOTA.isEmpty()) {
LOG_INFO("No BLE OTA firmware available");
} else {
LOG_INFO("BLE OTA firmware version %s", BLEOTA.c_str());
}
#endif
#if !MESHTASTIC_EXCLUDE_WIFI #if !MESHTASTIC_EXCLUDE_WIFI
String version = WiFiOTA::getVersion(); String version = MeshtasticOTA::getVersion();
if (version.isEmpty()) { if (version.isEmpty()) {
LOG_INFO("No WiFi OTA firmware available"); LOG_INFO("MeshtasticOTA firmware not available");
} else { } else {
LOG_INFO("WiFi OTA firmware version %s", version.c_str()); LOG_INFO("MeshtasticOTA firmware version %s", version.c_str());
} }
WiFiOTA::initialize(); MeshtasticOTA::initialize();
#endif #endif
// enableModemSleep(); // enableModemSleep();