11#include " BytebeamHTTPUpdate.h"
22
3- #if defined(BYTEBEAM_ARDUINO_ARCH_ESP32) && defined(BYTEBEAM_ARDUINO_USE_MODEM)
3+ #if defined(BYTEBEAM_ARDUINO_ARCH_ESP32) && defined(BYTEBEAM_ARDUINO_USE_MODEM)
4+
5+ bool BytebeamHTTPUpdate::runUpdate (Stream& in, uint32_t size) {
6+ StreamString error;
7+
8+ if (_cbProgress) {
9+ Update.onProgress (_cbProgress);
10+ }
11+
12+ if (!Update.begin (size, U_FLASH, _ledPin, _ledOn)) {
13+ _lastError = Update.getError ();
14+ Update.printError (error);
15+ error.trim (); // remove line ending
16+ Serial.printf (" Update.begin failed! (%s)\n " , error.c_str ());
17+ return false ;
18+ }
19+
20+ if (_cbProgress) {
21+ _cbProgress (0 , size);
22+ }
23+
24+ // To do: the MD5 could be checked if the server sends it
25+ // To do: the SHA256 could be checked if the server sends it
26+
27+ if (Update.writeStream (in) != size) {
28+ _lastError = Update.getError ();
29+ Update.printError (error);
30+ error.trim (); // remove line ending
31+ Serial.printf (" Update.writeStream failed! (%s)\n " , error.c_str ());
32+ return false ;
33+ }
34+
35+ if (_cbProgress) {
36+ _cbProgress (size, size);
37+ }
38+
39+ if (!Update.end ()) {
40+ _lastError = Update.getError ();
41+ Update.printError (error);
42+ error.trim (); // remove line ending
43+ Serial.printf (" Update.end failed! (%s)\n " , error.c_str ());
44+ return false ;
45+ }
46+
47+ return true ;
48+ }
449
550BytebeamHTTPUpdate::BytebeamHTTPUpdate () {
651 //
@@ -20,17 +65,55 @@ BytebeamHTTPUpdate::~BytebeamHTTPUpdate() {
2065 Serial.println (" I am BytebeamHTTPUpdate::~BytebeamHTTPUpdate()" );
2166}
2267
68+ int BytebeamHTTPUpdate::getLastError (void ) {
69+ return _lastError;
70+ }
71+
72+ String BytebeamHTTPUpdate::getLastErrorString (void ) {
73+ if (_lastError == 0 ) {
74+ return String (); // no error
75+ }
76+
77+ // error from Update class
78+ if (_lastError > 0 ) {
79+ StreamString error;
80+ Update.printError (error);
81+ error.trim (); // remove line ending
82+ return String (" Update error: " ) + error;
83+ }
84+
85+ switch (_lastError) {
86+ case HTTP_UE_TOO_LESS_SPACE:
87+ return " Not Enough space" ;
88+ case HTTP_UE_SERVER_NOT_REPORT_SIZE:
89+ return " Server Did Not Report Size" ;
90+ case HTTP_UE_BIN_VERIFY_HEADER_FAILED:
91+ return " Verify Bin Header Failed" ;
92+ case HTTP_UE_NO_PARTITION:
93+ return " Partition Could Not be Found" ;
94+ }
95+
96+ return String (" HTTP Error" );
97+ }
98+
2399t_httpUpdate_return BytebeamHTTPUpdate::update(Client& client, const String& url, const String& currentVersion) {
24100 // url will come in this format "https://firmware.cloud.bytebeam.io/api/v1/firmwares/{version}/artifact\"
25101 const uint16_t port = 443 ;
26102 const String server = url.substring (8 , 34 );
27103 const String resource = url.substring (34 , url.length ());
104+ BytebeamHTTPUpdateResult ret = HTTP_UPDATE_FAILED;
28105
29106 HttpClient http (client, server, port);
30107
108+ Serial.printf (" ESP32 info:\n " );
109+ Serial.printf (" - free Space: %d\n " , ESP.getFreeSketchSpace ());
110+ Serial.printf (" - current Sketch Size: %d\n " , ESP.getSketchSize ());
111+
112+ int statusCode = 0 ;
113+
31114 if (http.get (resource) == 0 ) {
32115 // read status code
33- int statusCode = http.responseStatusCode ();
116+ statusCode = http.responseStatusCode ();
34117 Serial.print (" Status code : " );
35118 Serial.println (statusCode);
36119
@@ -46,48 +129,79 @@ t_httpUpdate_return BytebeamHTTPUpdate::update(Client& client, const String& url
46129 }
47130
48131 // image size
49- size_t size = 0 ;
132+ size_t len = 0 ;
50133
51134 // read content length
52- size = http.contentLength ();
135+ len = http.contentLength ();
53136 Serial.print (" Content Length : " );
54- Serial.println (size);
55-
56- // Warn main app we're starting up...
57- if (_cbStart) {
58- _cbStart ();
59- }
60-
61- // set the progress callback, if any
62- if (_cbProgress) {
63- Update.onProgress (_cbProgress);
64- }
65-
66- if (!Update.begin (size, U_FLASH, _ledPin, _ledOn)) {
67- Serial.println (" Update begin failed !" );
68- return HTTP_UPDATE_FAILED;
69- }
70-
71- if (Update.writeStream (http) != size) {
72- Serial.println (" Update writeStream failed !" );
73- return HTTP_UPDATE_FAILED;
74- }
75-
76- if (!Update.end ()) {
77- Serial.println (" Update end failed !" );
78- return HTTP_UPDATE_FAILED;
79- }
80-
81- // Warn main app we're all done
82- if (_cbEnd) {
83- _cbEnd ();
84- }
85-
86- if (_rebootOnUpdate) {
87- ESP.restart ();
137+ Serial.println (len);
138+
139+ // /< OK (Start Update)
140+ if (statusCode == 200 ) {
141+ if (len > 0 ) {
142+ bool startUpdate = true ;
143+
144+ // check if space is available
145+ int sketchFreeSpace = ESP.getFreeSketchSpace ();
146+ if (!sketchFreeSpace){
147+ _lastError = HTTP_UE_NO_PARTITION;
148+ return HTTP_UPDATE_FAILED;
149+ }
150+
151+ // make sure we have enough space available
152+ if (len > sketchFreeSpace) {
153+ Serial.printf (" FreeSketchSpace to low (%d) needed: %d\n " , sketchFreeSpace, len);
154+ startUpdate = false ;
155+ }
156+
157+ if (!startUpdate) {
158+ _lastError = HTTP_UE_TOO_LESS_SPACE;
159+ ret = HTTP_UPDATE_FAILED;
160+ } else {
161+ // Warn main app we're starting up...
162+ if (_cbStart) {
163+ _cbStart ();
164+ }
165+
166+ if (http.peek () != 0xE9 ) {
167+ Serial.println (" Magic header does not start with 0xE9\n " );
168+ _lastError = HTTP_UE_BIN_VERIFY_HEADER_FAILED;
169+ http.stop ();
170+ return HTTP_UPDATE_FAILED;
171+ }
172+
173+ if (runUpdate (http, len)) {
174+ ret = HTTP_UPDATE_OK;
175+ log_d (" Update ok\n " );
176+ http.stop ();
177+
178+ // Warn main app we're all done
179+ if (_cbEnd) {
180+ _cbEnd ();
181+ }
182+
183+ if (_rebootOnUpdate) {
184+ Serial.println (" Rebooting..." );
185+ ESP.restart ();
186+ }
187+ } else {
188+ ret = HTTP_UPDATE_FAILED;
189+ Serial.println (" Update failed\n " );
190+ }
191+ }
192+ } else {
193+ _lastError = HTTP_UE_SERVER_NOT_REPORT_SIZE;
194+ ret = HTTP_UPDATE_FAILED;
195+ Serial.println (" Content-Length was 0 or wasn't set by Server?!\n " );
196+ }
197+ } else {
198+ _lastError = statusCode;
199+ ret = HTTP_UPDATE_FAILED;
200+ Serial.printf (" HTTP Code is (%d)\n " , statusCode);
88201 }
89202
90- return HTTP_UPDATE_OK;
203+ http.stop ();
204+ return ret;
91205}
92206
93207BytebeamHTTPUpdate BytebeamhttpUpdate;
0 commit comments