@@ -98,7 +98,113 @@ OTACloudProcessInterface::State OTADefaultCloudProcessInterface::fetch() {
9898}
9999
100100OTACloudProcessInterface::State OTADefaultCloudProcessInterface::fetchChunk () {
101- return OtaDownloadFail;
101+ OTACloudProcessInterface::State res = Fetch;
102+ int http_res = 0 ;
103+ uint32_t start = millis ();
104+ char range[128 ] = {0 };
105+
106+ /* stop connected client */
107+ http_client->stop ();
108+
109+ /* request chunk */
110+ http_client->beginRequest ();
111+ http_res = http_client->get (context->parsed_url .path ());
112+
113+ if (username != nullptr && password != nullptr ) {
114+ http_client->sendBasicAuth (username, password);
115+ }
116+
117+ size_t rangeSize = context->downloadedSize + context->maxChunkSize > context->contentLength ? context->contentLength - context->downloadedSize : context->maxChunkSize ;
118+ sprintf (range, " bytes=%d-%d" , context->downloadedSize , context->downloadedSize + rangeSize);
119+ DEBUG_VERBOSE (" OTA downloading range: %s" , range);
120+ http_client->sendHeader (" Range" , range);
121+ http_client->endRequest ();
122+
123+ if (http_res == HTTP_ERROR_CONNECTION_FAILED) {
124+ DEBUG_VERBOSE (" OTA ERROR: http client error connecting to server \" %s:%d\" " ,
125+ context->parsed_url .host (), context->parsed_url .port ());
126+ return ServerConnectErrorFail;
127+ } else if (http_res == HTTP_ERROR_TIMED_OUT) {
128+ DEBUG_VERBOSE (" OTA ERROR: http client timeout \" %s\" " , OTACloudProcessInterface::context->url );
129+ return OtaHeaderTimeoutFail;
130+ } else if (http_res != HTTP_SUCCESS) {
131+ DEBUG_VERBOSE (" OTA ERROR: http client returned %d on get \" %s\" " , res, OTACloudProcessInterface::context->url );
132+ return OtaDownloadFail;
133+ }
134+
135+ int statusCode = http_client->responseStatusCode ();
136+
137+ if (statusCode != 206 ) {
138+ DEBUG_VERBOSE (" OTA ERROR: get response on \" %s\" returned status %d" , OTACloudProcessInterface::context->url , statusCode);
139+ return HttpResponseFail;
140+ }
141+
142+ http_client->skipResponseHeaders ();
143+
144+ /* download chunk */
145+ context->downloadedChunkSize = 0 ;
146+ do {
147+ if (!http_client->connected ()) {
148+ res = OtaDownloadFail;
149+ goto exit;
150+ }
151+
152+ if (http_client->available () == 0 ) {
153+ /* Avoid tight loop and allow yield */
154+ delay (1 );
155+ continue ;
156+ }
157+
158+ http_res = http_client->read (context->buffer , context->bufLen );
159+
160+ if (http_res < 0 ) {
161+ DEBUG_VERBOSE (" OTA ERROR: Download read error %d" , http_res);
162+ res = OtaDownloadFail;
163+ goto exit;
164+ }
165+
166+ parseOta (context->buffer , http_res);
167+
168+ if (context->writeError ) {
169+ DEBUG_VERBOSE (" OTA ERROR: File write error" );
170+ res = ErrorWriteUpdateFileFail;
171+ goto exit;
172+ }
173+
174+ context->downloadedChunkSize += http_res;
175+
176+ } while ((context->downloadState == OtaDownloadFile || context->downloadState == OtaDownloadHeader) &&
177+ (context->downloadedChunkSize < rangeSize));
178+
179+ // TODO verify that the information present in the ota header match the info in context
180+ if (context->downloadState == OtaDownloadCompleted) {
181+ // Verify that the downloaded file size is matching the expected size ??
182+ // this could distinguish between consistency of the downloaded bytes and filesize
183+
184+ // validate CRC
185+ context->calculatedCrc32 ^= 0xFFFFFFFF ; // finalize CRC
186+ if (context->header .header .crc32 == context->calculatedCrc32 ) {
187+ DEBUG_VERBOSE (" Ota download completed successfully" );
188+ res = FlashOTA;
189+ } else {
190+ res = OtaHeaderCrcFail;
191+ }
192+ } else if (context->downloadState == OtaDownloadError) {
193+ DEBUG_VERBOSE (" OTA ERROR: OtaDownloadError" );
194+
195+ res = OtaDownloadFail;
196+ } else if (context->downloadState == OtaDownloadMagicNumberMismatch) {
197+ DEBUG_VERBOSE (" OTA ERROR: Magic number mismatch" );
198+ res = OtaHeaderMagicNumberFail;
199+ }
200+
201+ exit:
202+ if (res != Fetch) {
203+ http_client->stop (); // close the connection
204+ delete http_client;
205+ http_client = nullptr ;
206+ }
207+ return res;
102208}
103209
104210OTACloudProcessInterface::State OTADefaultCloudProcessInterface::fetchTime () {
@@ -265,6 +371,7 @@ OTADefaultCloudProcessInterface::Context::Context(
265371 , lastReportTime(0 )
266372 , contentLength(0 )
267373 , writeError(false )
374+ , downloadedChunkSize(0 )
268375 , decoder(putc) { }
269376
270377static const uint32_t crc_table[256 ] = {
0 commit comments