1+ /*
2+ This file is part of the ArduinoIoTCloud library.
3+
4+ Copyright (c) 2024 Arduino SA
5+
6+ This Source Code Form is subject to the terms of the Mozilla Public
7+ License, v. 2.0. If a copy of the MPL was not distributed with this
8+ file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+ */
10+
11+ #include " AIoTC_Config.h"
112#if defined(ARDUINO_ARCH_ESP32) && OTA_ENABLED
13+ #include " OTAEsp32.h"
14+ #include < esp_ota_ops.h>
15+ #include < Update.h>
16+
17+ ESP32OTACloudProcess::ESP32OTACloudProcess (MessageStream *ms, Client* client)
18+ : OTADefaultCloudProcessInterface(ms), rom_partition(nullptr ) {
19+
20+ }
21+
22+
23+ OTACloudProcessInterface::State ESP32OTACloudProcess::resume (Message* msg) {
24+ return OtaBegin;
25+ }
26+
27+ OTACloudProcessInterface::State ESP32OTACloudProcess::startOTA () {
28+ if (Update.isRunning ()) {
29+ Update.abort ();
30+ DEBUG_VERBOSE (" %s: Aborting running update" , __FUNCTION__);
31+ }
32+
33+ if (!Update.begin (UPDATE_SIZE_UNKNOWN)) {
34+ DEBUG_VERBOSE (" %s: failed to initialize flash update" , __FUNCTION__);
35+ return OtaStorageInitFail;
36+ }
37+
38+ return OTADefaultCloudProcessInterface::startOTA ();
39+ }
40+
41+ OTACloudProcessInterface::State ESP32OTACloudProcess::flashOTA () {
42+
43+ if (!Update.end (true )) {
44+ DEBUG_VERBOSE (" %s: Failure to apply OTA update" , __FUNCTION__);
45+ return OtaStorageEndFail;
46+ }
47+
48+ return Reboot;
49+ }
50+
51+ OTACloudProcessInterface::State ESP32OTACloudProcess::reboot () {
52+ ESP.restart ();
53+
54+ return Idle; // we won't reach this
55+ }
56+
57+ int ESP32OTACloudProcess::writeFlash (uint8_t * const buffer, size_t len) {
58+ return Update.write (buffer, len);
59+ }
60+
61+ bool ESP32OTACloudProcess::isOtaCapable () {
62+ const esp_partition_t * ota_0 = esp_partition_find_first (ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_0, NULL );
63+ const esp_partition_t * ota_1 = esp_partition_find_first (ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_1, NULL );
64+ return ((ota_0 != nullptr ) && (ota_1 != nullptr ));
65+ }
66+
67+ void * ESP32OTACloudProcess::appStartAddress () {
68+ return nullptr ;
69+ }
70+ uint32_t ESP32OTACloudProcess::appSize () {
71+ return ESP.getSketchSize ();
72+ }
73+
74+ bool ESP32OTACloudProcess::appFlashOpen () {
75+ rom_partition = esp_ota_get_running_partition ();
76+
77+ if (rom_partition == nullptr ) {
78+ return false ;
79+ }
80+
81+ return true ;
82+ }
83+
84+ void ESP32OTACloudProcess::calculateSHA256 (SHA256& sha256_calc) {
85+ if (!appFlashOpen ()) {
86+ return ; // TODO error reporting
87+ }
88+
89+ sha256_calc.begin ();
90+
91+ uint8_t b[SPI_FLASH_SEC_SIZE];
92+ if (b == nullptr ) {
93+ DEBUG_VERBOSE (" ESP32::SHA256 Not enough memory to allocate buffer" );
94+ return ; // TODO error reporting
95+ }
96+
97+ uint32_t read_bytes = 0 ;
98+ uint32_t const app_size = ESP.getSketchSize ();
99+ for (uint32_t a = rom_partition->address ; read_bytes < app_size; ) {
100+ /* Check if we are reading last sector and compute used size */
101+ uint32_t const read_size = read_bytes + SPI_FLASH_SEC_SIZE < app_size ?
102+ SPI_FLASH_SEC_SIZE : app_size - read_bytes;
103+
104+ /* Use always 4 bytes aligned reads */
105+ if (!ESP.flashRead (a, reinterpret_cast <uint32_t *>(b), (read_size + 3 ) & ~3 )) {
106+ DEBUG_VERBOSE (" ESP32::SHA256 Could not read data from flash" );
107+ return ;
108+ }
109+ sha256_calc.update (b, read_size);
110+ a += read_size;
111+ read_bytes += read_size;
112+ }
113+
114+ appFlashClose ();
115+ }
2116
3117#endif // defined(ARDUINO_ARCH_ESP32) && OTA_ENABLED
0 commit comments