Skip to content

Refactor OTA request handler code #252

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

Merged
merged 5 commits into from
May 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 8 additions & 74 deletions src/ArduinoIoTCloudTCP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
#include "tls/utility/CryptoUtil.h"
#endif

#if defined(ARDUINO_PORTENTA_H7_M7)
#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4)
# include <algorithm>
# include "tls/utility/SHA256.h"
# include <stm32h7xx_hal_rtc_ex.h>
#endif
Expand All @@ -45,6 +46,7 @@

#include "utility/watchdog/Watchdog.h"


/******************************************************************************
* EXTERN
******************************************************************************/
Expand Down Expand Up @@ -579,83 +581,15 @@ int ArduinoIoTCloudTCP::write(String const topic, byte const data[], int const l
#if OTA_ENABLED
void ArduinoIoTCloudTCP::onOTARequest()
{
#ifdef ARDUINO_ARCH_SAMD
samd_watchdog_reset();
#endif /* ARDUINO_ARCH_SAMD */

DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s _ota_url = %s", __FUNCTION__, _ota_url.c_str());

#if OTA_STORAGE_SNU
/* Just to be safe delete any remains from previous updates. */
WiFiStorage.remove("/fs/UPDATE.BIN.LZSS");
WiFiStorage.remove("/fs/UPDATE.BIN.LZSS.TMP");

#ifdef ARDUINO_ARCH_SAMD
samd_watchdog_reset();
#endif /* ARDUINO_ARCH_SAMD */

/* Trigger direct download to nina module. */
uint8_t nina_ota_err_code = 0;
if (!WiFiStorage.downloadOTA(_ota_url.c_str(), &nina_ota_err_code))
{
DEBUG_ERROR("ArduinoIoTCloudTCP::%s error download to nina: %d", __FUNCTION__, nina_ota_err_code);
_ota_error = static_cast<int>(OTAError::DownloadFailed);
return;
}

/* Perform the reset to reboot to SxU. */
NVIC_SystemReset();
#endif /* OTA_STORAGE_SNU */

#if OTA_STORAGE_PORTENTA_QSPI
mbed_watchdog_reset();

Arduino_Portenta_OTA::Error ota_portenta_err = Arduino_Portenta_OTA::Error::None;
/* Use 2nd partition of QSPI (1st partition contains WiFi firmware) */
Arduino_Portenta_OTA_QSPI ota_portenta_qspi(QSPI_FLASH_FATFS_MBR, 2);

mbed_watchdog_reset();

/* Initialize the QSPI memory for OTA handling. */
if((ota_portenta_err = ota_portenta_qspi.begin()) != Arduino_Portenta_OTA::Error::None) {
DEBUG_ERROR("Arduino_Portenta_OTA_QSPI::begin() failed with %d", static_cast<int>(ota_portenta_err));
return;
}

mbed_watchdog_reset();

/* Just to be safe delete any remains from previous updates. */
remove("/fs/UPDATE.BIN");
remove("/fs/UPDATE.BIN.LZSS");

mbed_watchdog_reset();

/* Download the OTA file from the web storage location. */
int const ota_portenta_qspi_download_ret_code = ota_portenta_qspi.download((char*)(_ota_url.c_str()), true /* is_https */);
DEBUG_VERBOSE("Arduino_Portenta_OTA_QSPI::download(%s) returns %d", _ota_url.c_str(), ota_portenta_qspi_download_ret_code);

mbed_watchdog_reset();

/* Decompress the LZSS compressed OTA file. */
int const ota_portenta_qspi_decompress_ret_code = ota_portenta_qspi.decompress();
DEBUG_VERBOSE("Arduino_Portenta_OTA_QSPI::decompress() returns %d", ota_portenta_qspi_decompress_ret_code);
if (ota_portenta_qspi_decompress_ret_code < 0)
{
DEBUG_ERROR("Arduino_Portenta_OTA_QSPI::decompress() failed with %d", ota_portenta_qspi_decompress_ret_code);
return;
}

mbed_watchdog_reset();

/* Schedule the firmware update. */
if((ota_portenta_err = ota_portenta_qspi.update()) != Arduino_Portenta_OTA::Error::None) {
DEBUG_ERROR("Arduino_Portenta_OTA_QSPI::update() failed with %d", static_cast<int>(ota_portenta_err));
return;
}
_ota_error = samd_onOTARequest(_ota_url.c_str());
#endif

/* Perform the reset to reboot - then the bootloader performs the actual application update. */
NVIC_SystemReset();
#endif /* OTA_STORAGE_PORTENTA_QSPI */
#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4)
_ota_error = portenta_h7_onOTARequest(_ota_url.c_str());
#endif
}
#endif

Expand Down
86 changes: 86 additions & 0 deletions src/utility/ota/OTA-portenta-h7.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
This file is part of ArduinoIoTCloud.

Copyright 2020 ARDUINO SA (http://www.arduino.cc/)

This software is released under the GNU General Public License version 3,
which covers the main part of arduino-cli.
The terms of this license can be found at:
https://www.gnu.org/licenses/gpl-3.0.en.html

You can be released from the requirements of the above licenses by purchasing
a commercial license. Buying such a license is mandatory if you want to modify or
otherwise use the software for commercial activities involving the Arduino
software without disclosing the source code of your own applications. To purchase
a commercial license, send an email to [email protected].
*/

#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4)

/******************************************************************************
* INCLUDE
******************************************************************************/

#include "OTA.h"

#include <Arduino_DebugUtils.h>
#include <Arduino_Portenta_OTA.h>

#include "../watchdog/Watchdog.h"

/******************************************************************************
* FUNCTION DEFINITION
******************************************************************************/

int portenta_h7_onOTARequest(char const * ota_url)
{
mbed_watchdog_reset();

Arduino_Portenta_OTA::Error ota_portenta_err = Arduino_Portenta_OTA::Error::None;
/* Use 2nd partition of QSPI (1st partition contains WiFi firmware) */
Arduino_Portenta_OTA_QSPI ota_portenta_qspi(QSPI_FLASH_FATFS_MBR, 2);

mbed_watchdog_reset();

/* Initialize the QSPI memory for OTA handling. */
if((ota_portenta_err = ota_portenta_qspi.begin()) != Arduino_Portenta_OTA::Error::None) {
DEBUG_ERROR("Arduino_Portenta_OTA_QSPI::begin() failed with %d", static_cast<int>(ota_portenta_err));
return static_cast<int>(ota_portenta_err);
}

mbed_watchdog_reset();

/* Just to be safe delete any remains from previous updates. */
remove("/fs/UPDATE.BIN");
remove("/fs/UPDATE.BIN.LZSS");

mbed_watchdog_reset();

/* Download the OTA file from the web storage location. */
int const ota_portenta_qspi_download_ret_code = ota_portenta_qspi.download(ota_url, true /* is_https */);
DEBUG_VERBOSE("Arduino_Portenta_OTA_QSPI::download(%s) returns %d", ota_url, ota_portenta_qspi_download_ret_code);

mbed_watchdog_reset();

/* Decompress the LZSS compressed OTA file. */
int const ota_portenta_qspi_decompress_ret_code = ota_portenta_qspi.decompress();
DEBUG_VERBOSE("Arduino_Portenta_OTA_QSPI::decompress() returns %d", ota_portenta_qspi_decompress_ret_code);
if (ota_portenta_qspi_decompress_ret_code < 0)
{
DEBUG_ERROR("Arduino_Portenta_OTA_QSPI::decompress() failed with %d", ota_portenta_qspi_decompress_ret_code);
return ota_portenta_qspi_decompress_ret_code;
}

mbed_watchdog_reset();

/* Schedule the firmware update. */
if((ota_portenta_err = ota_portenta_qspi.update()) != Arduino_Portenta_OTA::Error::None) {
DEBUG_ERROR("Arduino_Portenta_OTA_QSPI::update() failed with %d", static_cast<int>(ota_portenta_err));
return static_cast<int>(ota_portenta_err);
}

/* Perform the reset to reboot - then the bootloader performs the actual application update. */
NVIC_SystemReset();
}

#endif /* defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) */
63 changes: 63 additions & 0 deletions src/utility/ota/OTA-samd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
This file is part of ArduinoIoTCloud.

Copyright 2020 ARDUINO SA (http://www.arduino.cc/)

This software is released under the GNU General Public License version 3,
which covers the main part of arduino-cli.
The terms of this license can be found at:
https://www.gnu.org/licenses/gpl-3.0.en.html

You can be released from the requirements of the above licenses by purchasing
a commercial license. Buying such a license is mandatory if you want to modify or
otherwise use the software for commercial activities involving the Arduino
software without disclosing the source code of your own applications. To purchase
a commercial license, send an email to [email protected].
*/

#ifdef ARDUINO_ARCH_SAMD

/******************************************************************************
* INCLUDE
******************************************************************************/

#include "OTA.h"

#include <Arduino_DebugUtils.h>

#include "../watchdog/Watchdog.h"

#if OTA_STORAGE_SNU
# include <SNU.h>
# include <WiFiNINA.h> /* WiFiStorage */
#endif

/******************************************************************************
* FUNCTION DEFINITION
******************************************************************************/

int samd_onOTARequest(char const * ota_url)
{
samd_watchdog_reset();

#if OTA_STORAGE_SNU
/* Just to be safe delete any remains from previous updates. */
WiFiStorage.remove("/fs/UPDATE.BIN.LZSS");
WiFiStorage.remove("/fs/UPDATE.BIN.LZSS.TMP");

samd_watchdog_reset();

/* Trigger direct download to nina module. */
uint8_t nina_ota_err_code = 0;
if (!WiFiStorage.downloadOTA(ota_url, &nina_ota_err_code))
{
DEBUG_ERROR("ArduinoIoTCloudTCP::%s error download to nina: %d", __FUNCTION__, nina_ota_err_code);
return static_cast<int>(OTAError::DownloadFailed);
}

/* Perform the reset to reboot to SxU. */
NVIC_SystemReset();
#endif /* OTA_STORAGE_SNU */
}

#endif /* ARDUINO_ARCH_SAMD */
21 changes: 11 additions & 10 deletions src/utility/ota/OTA.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,6 @@
******************************************************************************/

#include <AIoTC_Config.h>
#if OTA_ENABLED

#if OTA_STORAGE_SNU && !defined(ARDUINO_AVR_UNO_WIFI_REV2)
#include <SNU.h>
#endif /* OTA_STORAGE_SNU */

#if OTA_STORAGE_SSU
#include <SSU.h>
Expand All @@ -37,10 +32,6 @@
#include <SFU.h>
#endif /* OTA_STORAGE_SFU */

#if OTA_STORAGE_PORTENTA_QSPI
#include <Arduino_Portenta_OTA.h>
#endif /* OTA_STORAGE_PORTENTA_QSPI */

/******************************************************************************
* TYPEDEF
******************************************************************************/
Expand All @@ -51,6 +42,16 @@ enum class OTAError : int
DownloadFailed = 1,
};

#endif /* OTA_ENABLED */
/******************************************************************************
* FUNCTION DEFINITION
******************************************************************************/

#ifdef ARDUINO_ARCH_SAMD
int samd_onOTARequest(char const * ota_url);
#endif

#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4)
int portenta_h7_onOTARequest(char const * ota_url);
#endif

#endif /* ARDUINO_OTA_LOGIC_H_ */