Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed some bugs with OTA #184

Closed
wants to merge 8 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@
// Firmware title and version used to compare with remote version, to check if an update is needed.
// Title needs to be the same and version needs to be different --> downgrading is possible
#if THINGSBOARD_ENABLE_PROGMEM
constexpr char CURRENT_FIRMWARE_TITLE[] PROGMEM = "TEST";
const std::string CURRENT_FIRMWARE_TITLE PROGMEM = "TEST";
constexpr char CURRENT_FIRMWARE_VERSION[] PROGMEM = "1.0.0";
#else
constexpr char CURRENT_FIRMWARE_TITLE[] = "TEST";
const std::string CURRENT_FIRMWARE_TITLE = "TEST";
constexpr char CURRENT_FIRMWARE_VERSION[] = "1.0.0";
#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@
// Firmware title and version used to compare with remote version, to check if an update is needed.
// Title needs to be the same and version needs to be different --> downgrading is possible
#if THINGSBOARD_ENABLE_PROGMEM
constexpr char CURRENT_FIRMWARE_TITLE[] PROGMEM = "TEST";
const std::string CURRENT_FIRMWARE_TITLE[] PROGMEM = "TEST";
constexpr char CURRENT_FIRMWARE_VERSION[] PROGMEM = "1.0.0";
#else
constexpr char CURRENT_FIRMWARE_TITLE[] = "TEST";
const std::string CURRENT_FIRMWARE_TITLE = "TEST";
constexpr char CURRENT_FIRMWARE_VERSION[] = "1.0.0";
#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <esp_wifi.h>
#include <nvs_flash.h>
#include <esp_random.h>
#include <Ticker.h>


// Whether the given script is using encryption or not,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <esp_log.h>
#include <esp_wifi.h>
#include <nvs_flash.h>
#incllude <Ticker.h>


// Whether the given script is using encryption or not,
Expand All @@ -18,7 +19,7 @@

// Firmware title and version used to compare with remote version, to check if an update is needed.
// Title needs to be the same and version needs to be different --> downgrading is possible
constexpr char CURRENT_FIRMWARE_TITLE[] = "ESP32";
const std::string CURRENT_FIRMWARE_TITLE = "ESP32";
constexpr char CURRENT_FIRMWARE_VERSION[] = "1.0.0";

// Maximum amount of retries we attempt to download each firmware chunck over MQTT
Expand Down
5 changes: 4 additions & 1 deletion src/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,5 +186,8 @@
# else
# define THINGSBOARD_ENABLE_PSRAM 0
# endif

#
# ifdef ESP8266
# define THINGSBOARD_ENABLE_PROGMEM 0
# endif
#endif // Configuration_h
9 changes: 4 additions & 5 deletions src/OTA_Update_Callback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ OTA_Update_Callback::OTA_Update_Callback() :
// Nothing to do
}

OTA_Update_Callback::OTA_Update_Callback(function endCb, const char *currFwTitle, const char *currFwVersion, IUpdater *updater, const uint8_t &chunkRetries, const uint16_t &chunkSize, const uint64_t &timeout) :
OTA_Update_Callback::OTA_Update_Callback(function endCb,const std::string currFwTitle, const char *currFwVersion, IUpdater *updater, const uint8_t &chunkRetries, const uint16_t &chunkSize, const uint64_t &timeout) :
OTA_Update_Callback(nullptr, endCb, currFwTitle, currFwVersion, updater, chunkRetries, chunkSize, timeout)
{
// Nothing to do
}

OTA_Update_Callback::OTA_Update_Callback(progressFn progressCb, function endCb, const char *currFwTitle, const char *currFwVersion, IUpdater *updater, const uint8_t &chunkRetries, const uint16_t &chunkSize, const uint64_t &timeout) :
OTA_Update_Callback::OTA_Update_Callback(progressFn progressCb, function endCb,const std::string currFwTitle, const char *currFwVersion, IUpdater *updater, const uint8_t &chunkRetries, const uint16_t &chunkSize, const uint64_t &timeout) :
Callback(endCb, OTA_CB_IS_NULL),
m_progressCb(progressCb),
m_fwTitel(currFwTitle),
Expand All @@ -31,12 +31,11 @@ OTA_Update_Callback::OTA_Update_Callback(progressFn progressCb, function endCb,
void OTA_Update_Callback::Set_Progress_Callback(progressFn progressCb) {
m_progressCb = progressCb;
}

const char* OTA_Update_Callback::Get_Firmware_Title() const {
std::string OTA_Update_Callback::Get_Firmware_Title() const {
return m_fwTitel;
}

void OTA_Update_Callback::Set_Firmware_Title(const char *currFwTitle) {
void OTA_Update_Callback::Set_Firmware_Title(const std::string currFwTitle) {
m_fwTitel = currFwTitle;
}

Expand Down
14 changes: 7 additions & 7 deletions src/OTA_Update_Callback.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#ifndef OTA_Update_Callback_h
#define OTA_Update_Callback_h

#include <string>
// Local includes.
#include "Callback.h"

Expand Down Expand Up @@ -62,7 +62,7 @@ class OTA_Update_Callback : public Callback<void, const bool&> {
// because the whole chunk is saved into the heap before it can be processed and is then erased again after it has been used
/// @param timeout Maximum amount of time in microseconds for the OTA firmware update for each seperate chunk,
/// until that chunk counts as a timeout, retries is then subtraced by one and the download is retried
OTA_Update_Callback(function endCb, const char *currFwTitle, const char *currFwVersion, IUpdater *updater, const uint8_t &chunkRetries = CHUNK_RETRIES, const uint16_t &chunkSize = CHUNK_SIZE, const uint64_t &timeout = REQUEST_TIMEOUT);
OTA_Update_Callback(function endCb,const std::string currFwTitle, const char *currFwVersion, IUpdater *updater, const uint8_t &chunkRetries = CHUNK_RETRIES, const uint16_t &chunkSize = CHUNK_SIZE, const uint64_t &timeout = REQUEST_TIMEOUT);

/// @brief Constructs callbacks that will be called when the OTA firmware data,
/// has been completly sent by the cloud, received by the client and written to the flash partition as well as callback
Expand All @@ -80,7 +80,7 @@ class OTA_Update_Callback : public Callback<void, const bool&> {
// because the whole chunk is saved into the heap before it can be processed and is then erased again after it has been used
/// @param timeout Maximum amount of time in microseconds for the OTA firmware update for each seperate chunk,
/// until that chunk counts as a timeout, retries is then subtraced by one and the download is retried
OTA_Update_Callback(progressFn progressCb, function endCb, const char *currFwTitle, const char *currFwVersion, IUpdater *updater, const uint8_t &chunkRetries = CHUNK_RETRIES, const uint16_t &chunkSize = CHUNK_SIZE, const uint64_t &timeout = REQUEST_TIMEOUT);
OTA_Update_Callback(progressFn progressCb, function endCb,const std::string currFwTitle, const char *currFwVersion, IUpdater *updater, const uint8_t &chunkRetries = CHUNK_RETRIES, const uint16_t &chunkSize = CHUNK_SIZE, const uint64_t &timeout = REQUEST_TIMEOUT);

/// @brief Calls the progress callback that was subscribed, when this class instance was initally created
/// @tparam Logger Logging class that should be used to print messages generated by internal processes
Expand All @@ -105,12 +105,12 @@ class OTA_Update_Callback : public Callback<void, const bool&> {
/// @brief Gets the current firmware title, used to decide if an OTA firmware update is already installed and therefore should not be downladed,
/// this is only done if the title of the update and the current firmware title are the same because if they are not then this firmware is meant for another device type
/// @return Current firmware title of the device
const char* Get_Firmware_Title() const;
std::string Get_Firmware_Title() const;

/// @brief Sets the current firmware title, used to decide if an OTA firmware update is already installed and therefore should not be downladed,
/// this is only done if the title of the update and the current firmware title are the same because if they are not then this firmware is meant for another device type
/// @param currFwTitle Current firmware title of the device
void Set_Firmware_Title(const char *currFwTitle);
void Set_Firmware_Title(const std::string currFwTitle);

/// @brief Gets the current firmware version, used to decide if an OTA firmware update is already installed and therefore should not be downladed,
/// this is only done if the version of the update and the current firmware version are different, because if they are not then we would download the same firmware as is already on the device
Expand Down Expand Up @@ -166,8 +166,8 @@ class OTA_Update_Callback : public Callback<void, const bool&> {

private:
progressFn m_progressCb; // Progress callback to call
const char *m_fwTitel; // Current firmware title of device
const char *m_fwVersion; // Current firmware version of device
std::string m_fwTitel; // Current firmware title of device
const char *m_fwVersion; // Current firmware version of device
IUpdater *m_updater; // Updater implementation used to write firmware data
uint8_t m_retries; // Maximum amount of retries for a single chunk to be downloaded and flashes successfully
uint16_t m_size; // Size of chunks the firmware data will be split into
Expand Down
17 changes: 8 additions & 9 deletions src/ThingsBoard.h
Original file line number Diff line number Diff line change
Expand Up @@ -954,7 +954,7 @@ class ThingsBoardSized {
/// @param currFwTitle Current device firmware title
/// @param currFwVersion Current device firmware version
/// @return Whether sending the current device firmware information was successful or not
inline bool Firmware_Send_Info(const char *currFwTitle, const char *currFwVersion) {
inline bool Firmware_Send_Info(std::string currFwTitle, const char *currFwVersion) {
StaticJsonDocument<JSON_OBJECT_SIZE(2)> currentFirmwareInfo;
const JsonObject currentFirmwareInfoObject = currentFirmwareInfo.to<JsonObject>();

Expand Down Expand Up @@ -1269,11 +1269,11 @@ class ThingsBoardSized {
/// @param callback Callback method that will be called
/// @return Whether checking and sending the current device firmware information was successful or not
inline bool Prepare_Firmware_Settings(const OTA_Update_Callback& callback) {
const char *currFwTitle = callback.Get_Firmware_Title();
const std::string currFwTitle = callback.Get_Firmware_Title();
const char *currFwVersion = callback.Get_Firmware_Version();

// Send current firmware version
if (currFwTitle == nullptr || currFwVersion == nullptr) {
if (currFwTitle.empty() || currFwVersion == nullptr) {
return false;
}
else if (!Firmware_Send_Info(currFwTitle, currFwVersion)) {
Expand Down Expand Up @@ -1333,23 +1333,22 @@ class ThingsBoardSized {
const std::string fw_checksum = data[FW_CHKS_KEY].as<std::string>();
const std::string fw_algorithm = data[FW_CHKS_ALGO_KEY].as<std::string>();
const size_t fw_size = data[FW_SIZE_KEY].as<const size_t>();

const char *curr_fw_title = m_fw_callback->Get_Firmware_Title();
std::string curr_fw_title = m_fw_callback->Get_Firmware_Title();
const char *curr_fw_version = m_fw_callback->Get_Firmware_Version();

if (fw_title == nullptr || fw_version == nullptr || curr_fw_title == nullptr || curr_fw_version == nullptr || fw_algorithm.empty() || fw_checksum.empty()) {
if (fw_title == nullptr || fw_version == nullptr || curr_fw_title.empty() || curr_fw_version==nullptr || fw_algorithm.empty() || fw_checksum.empty()) {
Logger::log(EMPTY_FW);
Firmware_Send_State(FW_STATE_FAILED, EMPTY_FW);
return;
}
// If firmware version and title is the same, we do not initiate an update, because we expect the binary to be the same one we are currently using
else if (strncmp_P(curr_fw_title, fw_title, JSON_STRING_SIZE(strlen(curr_fw_title))) == 0 && strncmp_P(curr_fw_version, fw_version, JSON_STRING_SIZE(strlen(curr_fw_version))) == 0) {
else if (strncmp_P(curr_fw_title.c_str(), fw_title, JSON_STRING_SIZE(curr_fw_title.length())) == 0 && strncmp_P(curr_fw_version, fw_version, JSON_STRING_SIZE(strlen(curr_fw_version))) == 0) {
Logger::log(FW_UP_TO_DATE);
Firmware_Send_State(FW_STATE_FAILED, FW_UP_TO_DATE);
return;
}
// If firmware title is not the same, we do not initiate an update, because we expect the binary to be for another device type
else if (strncmp_P(curr_fw_title, fw_title, JSON_STRING_SIZE(strlen(curr_fw_title))) != 0) {
else if (strncmp_P(curr_fw_title.c_str(), fw_title, JSON_STRING_SIZE(curr_fw_title.length())) != 0) {
Logger::log(FW_NOT_FOR_US);
Firmware_Send_State(FW_STATE_FAILED, FW_NOT_FOR_US);
return;
Expand Down Expand Up @@ -1385,7 +1384,7 @@ class ThingsBoardSized {
#if THINGSBOARD_ENABLE_DEBUG
Logger::log(PAGE_BREAK);
Logger::log(NEW_FW);
char firmware[JSON_STRING_SIZE(strlen(FROM_TOO)) + JSON_STRING_SIZE(strlen(curr_fw_version)) + JSON_STRING_SIZE(strlen(fw_version))];
char firmware[JSON_STRING_SIZE(strlen(FROM_TOO)) + JSON_STRING_SIZE(curr_fw_version.length())) + JSON_STRING_SIZE(strlen(fw_version))];
snprintf_P(firmware, sizeof(firmware), FROM_TOO, curr_fw_version, fw_version);
Logger::log(firmware);
Logger::log(DOWNLOADING_FW);
Expand Down
Loading