@@ -82,7 +82,10 @@ OTACloudProcessInterface::State OTADefaultCloudProcessInterface::startOTA() {
82
82
return HttpHeaderErrorFail;
83
83
}
84
84
85
- context->lastReportTime = millis ();
85
+ context->contentLength = http_client->contentLength ();
86
+
87
+ DEBUG_VERBOSE (" OTA file length: %d" , context->contentLength );
88
+ http_client->stop (); // close the connection
86
89
87
90
return Fetch;
88
91
}
@@ -91,7 +94,45 @@ OTACloudProcessInterface::State OTADefaultCloudProcessInterface::fetch() {
91
94
OTACloudProcessInterface::State res = Fetch;
92
95
int http_res = 0 ;
93
96
uint32_t start = millis ();
97
+ char range[128 ] = {0 };
98
+
99
+ /* request chunk */
100
+ http_client->beginRequest ();
101
+ http_res = http_client->get (context->parsed_url .path ());
102
+
103
+ if (username != nullptr && password != nullptr ) {
104
+ http_client->sendBasicAuth (username, password);
105
+ }
106
+
107
+ size_t rangeSize = context->downloadedSize + context->maxChunkSize > context->contentLength ? context->contentLength - context->downloadedSize : context->maxChunkSize ;
108
+ sprintf (range, " bytes=%d-%d" , context->downloadedSize , context->downloadedSize + rangeSize);
109
+ DEBUG_VERBOSE (" OTA downloading range: %s" , range);
110
+ http_client->sendHeader (" Range" , range);
111
+ http_client->endRequest ();
112
+
113
+ if (http_res == HTTP_ERROR_CONNECTION_FAILED) {
114
+ DEBUG_VERBOSE (" OTA ERROR: http client error connecting to server \" %s:%d\" " ,
115
+ context->parsed_url .host (), context->parsed_url .port ());
116
+ return ServerConnectErrorFail;
117
+ } else if (http_res == HTTP_ERROR_TIMED_OUT) {
118
+ DEBUG_VERBOSE (" OTA ERROR: http client timeout \" %s\" " , OTACloudProcessInterface::context->url );
119
+ return OtaHeaderTimeoutFail;
120
+ } else if (http_res != HTTP_SUCCESS) {
121
+ DEBUG_VERBOSE (" OTA ERROR: http client returned %d on get \" %s\" " , res, OTACloudProcessInterface::context->url );
122
+ return OtaDownloadFail;
123
+ }
124
+
125
+ int statusCode = http_client->responseStatusCode ();
94
126
127
+ if (statusCode != 206 ) {
128
+ DEBUG_VERBOSE (" OTA ERROR: get response on \" %s\" returned status %d" , OTACloudProcessInterface::context->url , statusCode);
129
+ return HttpResponseFail;
130
+ }
131
+
132
+ http_client->skipResponseHeaders ();
133
+
134
+ /* download chunk */
135
+ context->downloadedChunkSize = 0 ;
95
136
do {
96
137
if (!http_client->connected ()) {
97
138
res = OtaDownloadFail;
@@ -104,7 +145,7 @@ OTACloudProcessInterface::State OTADefaultCloudProcessInterface::fetch() {
104
145
continue ;
105
146
}
106
147
107
- http_res = http_client->read (context->buffer , context->buf_len );
148
+ http_res = http_client->read (context->buffer , context->bufLen );
108
149
109
150
if (http_res < 0 ) {
110
151
DEBUG_VERBOSE (" OTA ERROR: Download read error %d" , http_res);
@@ -119,8 +160,13 @@ OTACloudProcessInterface::State OTADefaultCloudProcessInterface::fetch() {
119
160
res = ErrorWriteUpdateFileFail;
120
161
goto exit ;
121
162
}
163
+
164
+ context->downloadedChunkSize += http_res;
165
+
122
166
} while ((context->downloadState == OtaDownloadFile || context->downloadState == OtaDownloadHeader) &&
123
- millis () - start < downloadTime);
167
+ (context->downloadedChunkSize < rangeSize));
168
+
169
+ context->printProgress = true ;
124
170
125
171
// TODO verify that the information present in the ota header match the info in context
126
172
if (context->downloadState == OtaDownloadCompleted) {
@@ -145,8 +191,8 @@ OTACloudProcessInterface::State OTADefaultCloudProcessInterface::fetch() {
145
191
}
146
192
147
193
exit :
194
+ http_client->stop (); // close the connection
148
195
if (res != Fetch) {
149
- http_client->stop (); // close the connection
150
196
delete http_client;
151
197
http_client = nullptr ;
152
198
}
@@ -183,7 +229,6 @@ void OTADefaultCloudProcessInterface::parseOta(uint8_t* buffer, size_t buf_len)
183
229
break ;
184
230
}
185
231
case OtaDownloadFile: {
186
- uint32_t contentLength = http_client->contentLength ();
187
232
context->decoder .decompress (cursor, buf_len - (cursor-buffer)); // TODO verify return value
188
233
189
234
context->calculatedCrc32 = crc_update (
@@ -195,19 +240,18 @@ void OTADefaultCloudProcessInterface::parseOta(uint8_t* buffer, size_t buf_len)
195
240
cursor += buf_len - (cursor-buffer);
196
241
context->downloadedSize += (cursor-buffer);
197
242
198
- if ((millis () - context->lastReportTime ) > 10000 ) { // Report the download progress each X millisecond
199
- DEBUG_VERBOSE (" OTA Download Progress %d/%d" , context->downloadedSize , contentLength);
200
-
243
+ if (context->printProgress ) {
244
+ DEBUG_VERBOSE (" OTA Download Progress %d/%d" , context->downloadedSize , context->contentLength );
201
245
reportStatus (context->downloadedSize );
202
- context->lastReportTime = millis () ;
246
+ context->printProgress = false ;
203
247
}
204
248
205
249
// TODO there should be no more bytes available when the download is completed
206
- if (context->downloadedSize == contentLength) {
250
+ if (context->downloadedSize == context-> contentLength ) {
207
251
context->downloadState = OtaDownloadCompleted;
208
252
}
209
253
210
- if (context->downloadedSize > contentLength) {
254
+ if (context->downloadedSize > context-> contentLength ) {
211
255
context->downloadState = OtaDownloadError;
212
256
}
213
257
// TODO fail if we exceed a timeout? and available is 0 (client is broken)
@@ -247,8 +291,10 @@ OTADefaultCloudProcessInterface::Context::Context(
247
291
, calculatedCrc32(0xFFFFFFFF )
248
292
, headerCopiedBytes(0 )
249
293
, downloadedSize(0 )
250
- , lastReportTime(0 )
294
+ , printProgress(false )
295
+ , contentLength(0 )
251
296
, writeError(false )
297
+ , downloadedChunkSize(0 )
252
298
, decoder(putc) { }
253
299
254
300
static const uint32_t crc_table[256 ] = {
0 commit comments