Skip to content

Commit ae33d64

Browse files
committed
error hanlding for bytebeam http update
1 parent b47ab67 commit ae33d64

File tree

3 files changed

+177
-42
lines changed

3 files changed

+177
-42
lines changed

src/BytebeamHTTPUpdate.cpp

Lines changed: 153 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,51 @@
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

550
BytebeamHTTPUpdate::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+
2399
t_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

93207
BytebeamHTTPUpdate BytebeamhttpUpdate;

src/BytebeamHTTPUpdate.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,23 @@
33

44
#include "BytebeamArduinoDefines.h"
55

6-
#if defined(BYTEBEAM_ARDUINO_ARCH_ESP32) && defined(BYTEBEAM_ARDUINO_USE_MODEM)
6+
#if defined(BYTEBEAM_ARDUINO_ARCH_ESP32) && defined(BYTEBEAM_ARDUINO_USE_MODEM)
77

88
#include <Update.h>
9+
#include <StreamString.h>
910
#include <ArduinoHttpClient.h>
1011

12+
/// note we use HTTP client errors too so we start at 100
13+
#define HTTP_UE_TOO_LESS_SPACE (-100)
14+
#define HTTP_UE_SERVER_NOT_REPORT_SIZE (-101)
15+
#define HTTP_UE_SERVER_FILE_NOT_FOUND (-102)
16+
#define HTTP_UE_SERVER_FORBIDDEN (-103)
17+
#define HTTP_UE_SERVER_WRONG_HTTP_CODE (-104)
18+
#define HTTP_UE_SERVER_FAULTY_MD5 (-105)
19+
#define HTTP_UE_BIN_VERIFY_HEADER_FAILED (-106)
20+
#define HTTP_UE_BIN_FOR_WRONG_FLASH (-107)
21+
#define HTTP_UE_NO_PARTITION (-108)
22+
1123
enum BytebeamHTTPUpdateResult {
1224
HTTP_UPDATE_FAILED,
1325
HTTP_UPDATE_NO_UPDATES,
@@ -41,10 +53,20 @@ class BytebeamHTTPUpdate {
4153
void onError(BytebeamHTTPUpdateErrorCB cbOnError) { _cbError = cbOnError; }
4254
void onProgress(BytebeamHTTPUpdateProgressCB cbOnProgress) { _cbProgress = cbOnProgress; }
4355

56+
// Error infos
57+
int getLastError(void);
58+
String getLastErrorString(void);
59+
4460
// update the new image
4561
t_httpUpdate_return update(Client& client, const String& url, const String& currentVersion = "");
4662

4763
private:
64+
// mark the update
65+
bool runUpdate(Stream& in, uint32_t size);
66+
67+
// last error
68+
int _lastError;
69+
4870
// reboot on update flag
4971
bool _rebootOnUpdate;
5072

src/BytebeamOTA.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,7 @@ boolean BytebeamOTA::performOTA(char* actionId, char* otaUrl) {
121121

122122
switch (ret) {
123123
case HTTP_UPDATE_FAILED:
124-
// Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", this->BytebeamUpdate.getLastError(), this->BytebeamUpdate.getLastErrorString().c_str());
125-
Serial.printf("HTTP_UPDATE_FAILED");
124+
Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", this->BytebeamUpdate.getLastError(), this->BytebeamUpdate.getLastErrorString().c_str());
126125
break;
127126

128127
case HTTP_UPDATE_NO_UPDATES:

0 commit comments

Comments
 (0)