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"
1
12
#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
+ }
2
116
3
117
#endif // defined(ARDUINO_ARCH_ESP32) && OTA_ENABLED
0 commit comments