@@ -82,7 +82,10 @@ OTACloudProcessInterface::State OTADefaultCloudProcessInterface::startOTA() {
8282 return HttpHeaderErrorFail;
8383 }
8484
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
8689
8790 return Fetch;
8891}
@@ -91,7 +94,45 @@ OTACloudProcessInterface::State OTADefaultCloudProcessInterface::fetch() {
9194 OTACloudProcessInterface::State res = Fetch;
9295 int http_res = 0 ;
9396 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 ();
94126
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 ;
95136 do {
96137 if (!http_client->connected ()) {
97138 res = OtaDownloadFail;
@@ -104,7 +145,7 @@ OTACloudProcessInterface::State OTADefaultCloudProcessInterface::fetch() {
104145 continue ;
105146 }
106147
107- http_res = http_client->read (context->buffer , context->buf_len );
148+ http_res = http_client->read (context->buffer , context->bufLen );
108149
109150 if (http_res < 0 ) {
110151 DEBUG_VERBOSE (" OTA ERROR: Download read error %d" , http_res);
@@ -119,8 +160,13 @@ OTACloudProcessInterface::State OTADefaultCloudProcessInterface::fetch() {
119160 res = ErrorWriteUpdateFileFail;
120161 goto exit;
121162 }
163+
164+ context->downloadedChunkSize += http_res;
165+
122166 } while ((context->downloadState == OtaDownloadFile || context->downloadState == OtaDownloadHeader) &&
123- millis () - start < downloadTime);
167+ (context->downloadedChunkSize < rangeSize));
168+
169+ context->printProgress = true ;
124170
125171 // TODO verify that the information present in the ota header match the info in context
126172 if (context->downloadState == OtaDownloadCompleted) {
@@ -145,8 +191,8 @@ OTACloudProcessInterface::State OTADefaultCloudProcessInterface::fetch() {
145191 }
146192
147193exit:
194+ http_client->stop (); // close the connection
148195 if (res != Fetch) {
149- http_client->stop (); // close the connection
150196 delete http_client;
151197 http_client = nullptr ;
152198 }
@@ -183,7 +229,6 @@ void OTADefaultCloudProcessInterface::parseOta(uint8_t* buffer, size_t buf_len)
183229 break ;
184230 }
185231 case OtaDownloadFile: {
186- uint32_t contentLength = http_client->contentLength ();
187232 context->decoder .decompress (cursor, buf_len - (cursor-buffer)); // TODO verify return value
188233
189234 context->calculatedCrc32 = crc_update (
@@ -195,19 +240,18 @@ void OTADefaultCloudProcessInterface::parseOta(uint8_t* buffer, size_t buf_len)
195240 cursor += buf_len - (cursor-buffer);
196241 context->downloadedSize += (cursor-buffer);
197242
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 );
201245 reportStatus (context->downloadedSize );
202- context->lastReportTime = millis () ;
246+ context->printProgress = false ;
203247 }
204248
205249 // TODO there should be no more bytes available when the download is completed
206- if (context->downloadedSize == contentLength) {
250+ if (context->downloadedSize == context-> contentLength ) {
207251 context->downloadState = OtaDownloadCompleted;
208252 }
209253
210- if (context->downloadedSize > contentLength) {
254+ if (context->downloadedSize > context-> contentLength ) {
211255 context->downloadState = OtaDownloadError;
212256 }
213257 // TODO fail if we exceed a timeout? and available is 0 (client is broken)
@@ -247,8 +291,10 @@ OTADefaultCloudProcessInterface::Context::Context(
247291 , calculatedCrc32(0xFFFFFFFF )
248292 , headerCopiedBytes(0 )
249293 , downloadedSize(0 )
250- , lastReportTime(0 )
294+ , printProgress(false )
295+ , contentLength(0 )
251296 , writeError(false )
297+ , downloadedChunkSize(0 )
252298 , decoder(putc) { }
253299
254300static const uint32_t crc_table[256 ] = {
0 commit comments