SimpleLink CC32xx OTA Library
Simplifies the implementation of Internet connectivity
OtaLib.c
1 /*
2  * Copyright (c) 2018, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of Texas Instruments Incorporated nor the names of
17  * its contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /* Standard includes */
33 #include <stdlib.h>
34 #include <stdint.h>
35 
36 #include <ti/net/ota/otauser.h>
37 #include <ti/net/ota/source/CdnClient.h>
38 #include <ti/net/ota/source/OtaArchive.h>
39 #include <ti/net/ota/source/OtaLib.h>
40 #include <ti/net/ota/source/OtaHttpClient.h>
41 #include <ti/net/ota/source/OtaJson.h>
42 
43 OtaLib_t *pOtaLib;
44 
45 int16_t OTA_init(OTA_runningMode runningMode, OTA_memBlock* pMemBlock, OTA_eventHandler eventHandler)
46 {
47  _SlOtaLibTrace(("OTA_init: sizeof CdnClient=%d, sizeof OtaArchive=%d\r\n", sizeof(pOtaLib->CdnClient), sizeof(pOtaLib->OtaArchive)));
48  _SlOtaLibTrace(("OTA_init: sizeof OtaLib_t=%d, sizeof OTA_memBlock=%d\r\n", sizeof(OtaLib_t), sizeof(OTA_memBlock)));
49  if (sizeof(OtaLib_t) > sizeof(OTA_memBlock))
50  {
51  _SlOtaLibTrace(("OTA_init: ERROR buffer size OtaLib_t=%d < OTA_memBlock=%d\r\n", sizeof(OtaLib_t), sizeof(OTA_memBlock)));
52  return OTA_INIT_ERROR;
53  }
54  pOtaLib = (OtaLib_t *)pMemBlock;
55 
56  memset(pOtaLib, 0, sizeof(OtaLib_t));
57  pOtaLib->State = OTA_STATE_IDLE;
58 
59  _SlOtaLibTrace(("OTA_init: OTA lib version = %s\r\n", OTA_LIB_VERSION));
60 
61  CdnClient_Init(&pOtaLib->CdnClient, pOtaLib->NetBuf);
62  OtaArchive_init(&pOtaLib->OtaArchive);
63 
64  /* init statistics */
65  return OTA_STATUS_OK;
66 }
67 
68 uint8_t *_ExtractFileVersion(uint8_t *pFileName, uint32_t FileNameSize)
69 {
70  uint8_t *pVersionFileName = pFileName;
71 
72  /* VENDOR_DIR cannot be empty - the EXTLIB_OTA_SET_OPT_VENDOR_ID will fail first */
73 
74  /* minimum 2 slashes - in poll mode, filename must be "/VENDOR_DIR/file.tar", in push mode there are no slashaes */
75  while (pVersionFileName != NULL)
76  {
77  pVersionFileName = (uint8_t *)Str_FindChar(pFileName, '/', FileNameSize);
78  if (pVersionFileName != NULL)
79  {
80  /* go after the slash */
81  pFileName = pVersionFileName+1;
82  }
83  }
84 
85  return pFileName;
86 }
87 
88 void _OtaCleanToIdle(OtaLib_t *pOtaLib)
89 {
90  /*_SlOtaLibTrace(("_OtaCleanToIdle: close OTA client and CDN client and back to IDLE\r\n");*/
91  CdnClient_CloseServer(&pOtaLib->CdnClient);
92  CdnClient_CloseFileServer(&pOtaLib->CdnClient);
93 
94  pOtaLib->pOtaFileName = NULL;
95  pOtaLib->State = OTA_STATE_IDLE;
96  /* don't clean consecutive errors */
97 }
98 
99 int16_t OTA_set(OTA_option option, int32_t optionLen, uint8_t *pOptionVal, int32_t flags)
100 {
101  int16_t Status = OTA_STATUS_OK;
102 
103  switch (option)
104  {
105  case EXTLIB_OTA_SET_OPT_SERVER_INFO:
106  memcpy(&pOtaLib->OtaServerInfo, pOptionVal, sizeof(Ota_optServerInfo));
107  break;
108 
109  case EXTLIB_OTA_SET_OPT_FILE_SERVER_URL:
110  strcpy((char *)pOtaLib->FileUrlBuf, (char *)pOptionVal);
111  pOtaLib->OtaServerInfo.SecuredConnection = OTA_SERVER_SECURED;
112  break;
113 
114  case EXTLIB_OTA_SET_OPT_VENDOR_ID:
115  if (strlen((const char *)pOptionVal) >= MAX_VENDIR_DIR_SIZE)
116  {
117  return OTA_OPT_ERROR_VENDOR_DIR_SIZE;
118  }
119  strcpy((char *)pOtaLib->VendorDir, (const char *)pOptionVal);
120  break;
121 
122  case EXTLIB_OTA_SET_OPT_ACCEPT_UPDATE:
123  /* do nothing, the OTA is already on process and not in IDLE state */
124  break;
125 
126  case EXTLIB_OTA_SET_OPT_DECLINE_UPDATE:
127 
128  /* check if after OTA_STATE_CHECK_ARCHIVE_NEW_UPDATE state */
129  if (pOtaLib->State != OTA_STATE_REQ_FILE_URL)
130  {
131  _SlOtaLibTrace(("OTA_set: ERROR EXTLIB_OTA_SET_OPT_DECLINE_UPDATE in wrong state = %d\r\n", pOtaLib->State));
132  return OTA_OPT_ERROR_WRONG_STATE;
133  }
134 
135  /* close all connection from last OTA updates and back to IDLE */
136  pOtaLib->ConsecutiveOtaErrors = 0;
137  _OtaCleanToIdle(pOtaLib);
138  break;
139 
140  case EXTLIB_OTA_SET_OPT_IMAGE_COMMIT:
141 
142  Status = OtaArchive_commit();
143  if (Status < 0)
144  {
145  _SlOtaLibTrace(("OTA_set: ERROR OtaArchive_Commit, status=%d\r\n", Status));
146  return OTA_OPT_ERROR_COMMIT;
147  }
148 
149 
150  break;
151 
152  case EXTLIB_OTA_SET_OPT_IMAGE_ROLLBACK:
153 
154  Status = OtaArchive_rollback();
155  if (Status < 0)
156  {
157  if (Status == SL_ERROR_FS_BUNDLE_NOT_IN_CORRECT_STATE)
158  {
159  _SlOtaLibTrace(("OTA_set: ERROR OtaArchive_Rollback, status=%d - ignored SL_ERROR_FS_BUNDLE_NOT_IN_CORRECT_STATE\r\n", Status));
160  /* Ignore error calling rollback in the incorrect state */
161  return OTA_STATUS_OK;
162  }
163  _SlOtaLibTrace(("OTA_set: ERROR OtaArchive_Rollback, status=%d\r\n", Status));
164  return OTA_OPT_ERROR_ROLLBACK;
165  }
166  break;
167 
168  default:
169  _SlOtaLibTrace(("OTA_set: option %ld is not implemented\r\n", option));
170  return OTA_OPT_ERROR_OPTION_CODE;
171  }
172 
173  return Status;
174 }
175 
176 int16_t OTA_get(OTA_option option, int32_t *pOptionLen, uint8_t *pOptionVal)
177 {
178  Ota_optVersionsInfo *pVersionsInfo;
179  int16_t Status = OTA_STATUS_OK;
180 
181  switch (option)
182  {
183  case EXTLIB_OTA_GET_OPT_IS_ACTIVE:
184  *(int32_t *)pOptionVal = (pOtaLib->State != OTA_STATE_IDLE);
185  *pOptionLen = sizeof(int32_t);
186  break;
187 
188  case EXTLIB_OTA_GET_OPT_VERSIONS:
189 
190  pVersionsInfo = (Ota_optVersionsInfo *)pOptionVal;
191  /* get the current version from ota.dat file */
192  OtaArchive_getCurrentVersion(pVersionsInfo->CurrentVersion);
193  /* extract the new version from OtaFileName if exists */
194  if(pOtaLib->pOtaFileName == NULL)
195  {
196  /* can be if the OTA not in the right state and still didn't read the file name */
197  /* OTA file not exists (no upadte or state before reading the ota new update */
198  memset(pVersionsInfo->NewVersion, '0', VERSION_STR_SIZE);
199  }
200  else
201  {
202  uint8_t *pVersionFileName = _ExtractFileVersion(pOtaLib->pOtaFileName, MAX_CDN_FILE_NAME_SIZE);
203  /* extract version from file */
204  memcpy(pVersionsInfo->NewVersion, pVersionFileName, VERSION_STR_SIZE);
205  }
206  pVersionsInfo->NewVersion[VERSION_STR_SIZE] = 0; /* null terminated string */
207  break;
208 
209  case EXTLIB_OTA_GET_OPT_IS_PENDING_COMMIT:
210 
211  *(int32_t *)pOptionVal = OtaArchive_getPendingCommit();
212  break;
213 
214  default:
215  _SlOtaLibTrace(("OTA_get: option %ld is not implemented\r\n", option));
216  Status = OTA_OPT_ERROR_OPTION_CODE;
217  }
218 
219  return Status;
220 }
221 
222 #define BACK_TO_IDLE 0x1
223 
224 int16_t _OtaCheckConsecutiveErrors(OtaLib_t *pOtaLib, int16_t OtaStatus, int32_t Options)
225 {
226  int16_t Status;
227 
228  if (++pOtaLib->ConsecutiveOtaErrors >= MAX_CONSECUTIVE_OTA_ERRORS)
229  {
230  _SlOtaLibTrace(("\n_OtaCheckConsecutiveErrors: ConsecutiveOtaErrors=%d/%d, MAX_CONSECUTIVE_OTA_ERRORS!!! \r\n", pOtaLib->ConsecutiveOtaErrors, MAX_CONSECUTIVE_OTA_ERRORS));
231  pOtaLib->ConsecutiveOtaErrors = 0;
232  Status = OTA_RUN_ERROR_CONSECUTIVE_OTA_ERRORS;
233  }
234  else
235  {
236  _SlOtaLibTrace(("\n_OtaCheckConsecutiveErrors: ConsecutiveOtaErrors=%d/%d, return only WARNNING\r\n", pOtaLib->ConsecutiveOtaErrors, MAX_CONSECUTIVE_OTA_ERRORS));
237  Status = OtaStatus;
238  }
239 
240  if (Options & BACK_TO_IDLE)
241  {
242  pOtaLib->State = OTA_STATE_IDLE;
243  _OtaCleanToIdle(pOtaLib);
244  }
245 
246  return Status;
247 }
248 
249 int16_t OTA_run()
250 {
251  CdnClient_t *pCdnClient = (CdnClient_t *)&pOtaLib->CdnClient;
252  int16_t Status;
253  int16_t ProcessedBytes;
254 
255  switch (pOtaLib->State)
256  {
257  case OTA_STATE_IDLE:
258 #if OTA_SERVER_TYPE == OTA_FILE_DOWNLOAD
259  /* File Server URL must be initialized before running OTA */
260  if(pOtaLib->FileUrlBuf[0] == 0)
261  {
262  return OTA_RUN_ERROR_NO_SERVER_NO_VENDOR;
263  }
264  pOtaLib->State = OTA_STATE_CONNECT_FILE_SERVER;
265 #else
266  /* serverInfo and vendorDir must be init before running OTA */
267  if /*(*/(pOtaLib->OtaServerInfo.ServerName[0] == 0) /*|| (pOtaLib->VendorDir[0] == 0))*/
268  {
269  return OTA_RUN_ERROR_NO_SERVER_NO_VENDOR;
270  }
271 
272  pOtaLib->State = OTA_STATE_CONNECT_SERVER;
273 #endif
274  break;
275 #if OTA_SERVER_TYPE != OTA_FILE_DOWNLOAD
276  case OTA_STATE_CONNECT_SERVER:
277  _SlOtaLibTrace(("OTA_run: call CdnClient_ConnectServer OTA server=%s\r\n", pOtaLib->OtaServerInfo.ServerName));
278  Status = CdnClient_ConnectServer(pCdnClient, &pOtaLib->OtaServerInfo);
279  if( Status < 0)
280  {
281  _SlOtaLibTrace(("OTA_run: ERROR CdnClient_ConnectServer, Status=%ld\r\n", Status));
282  Status = _OtaCheckConsecutiveErrors(pOtaLib, OTA_RUN_STATUS_CONTINUE_WARNING_FAILED_CONNECT_FILE_SERVER, BACK_TO_IDLE);
283  return Status;
284  }
285  pOtaLib->State = OTA_STATE_REQ_OTA_DIR;
286  break;
287 
288  case OTA_STATE_REQ_OTA_DIR:
289  {
290  int32_t NumDirFiles;
291  _SlOtaLibTrace(("OTA_run: CdnClient_ReqOtaDir, VendorDir=%s\r\n", pOtaLib->VendorDir));
292  NumDirFiles = CdnClient_ReqOtaDir(pCdnClient, pOtaLib->VendorDir);
293  if (NumDirFiles < 0)
294  {
295  _SlOtaLibTrace(("OTA_run: ERROR CdnClient_ReqOtaDir, Status=%d\r\n", NumDirFiles));
296  Status = _OtaCheckConsecutiveErrors(pOtaLib, OTA_RUN_STATUS_CONTINUE_WARNING_FAILED_REQ_OTA_DIR, BACK_TO_IDLE);
297  return Status;
298  }
299  if (NumDirFiles == 0)
300  {
301  _SlOtaLibTrace(("OTA_run: ERROR CdnClient_ReqOtaDir - no updates\r\n"));
302  pOtaLib->ConsecutiveOtaErrors = 0;
303  pOtaLib->State = OTA_STATE_IDLE;
304  _OtaCleanToIdle(pOtaLib);
305  return OTA_RUN_STATUS_NO_UPDATES;
306  }
307  _SlOtaLibTrace(("OTA_run: CdnClient_ReqOtaDir, NumDirFiles=%ld\r\n", NumDirFiles));
308  pOtaLib->State = OTA_STATE_CHECK_ARCHIVE_NEW_UPDATE;
309  }
310  break;
311 
312  case OTA_STATE_CHECK_ARCHIVE_NEW_UPDATE:
313  {
314  uint8_t *pVersionFileName;
315  _SlOtaLibTrace(("OTA_run: CdnClient_GetNextDirFile\r\n"));
316  pOtaLib->pOtaFileName = CdnClient_GetNextDirFile(pCdnClient, &pOtaLib->OtaFileSize);
317 
318  /* check if last file in the list, still without tar file */
319  if( pOtaLib->pOtaFileName == NULL)
320  {
321  /* tar file not found, return no updates */
322  _SlOtaLibTrace(("OTA_run: ERROR CdnClient_ReqOtaDir - tar not found, no updates\r\n"));
323  pOtaLib->ConsecutiveOtaErrors = 0;
324  pOtaLib->State = OTA_STATE_IDLE;
325  _OtaCleanToIdle(pOtaLib);
326  return OTA_RUN_STATUS_NO_UPDATES;
327  }
328 
329  _SlOtaLibTrace(("OTA_run: CdnClient_GetNextDirFile: file=%s, size=%ld\r\n", pOtaLib->pOtaFileName, pOtaLib->OtaFileSize));
330 
331  if (strstr((const char *)pOtaLib->pOtaFileName, ".tar") == NULL)
332  {
333  _SlOtaLibTrace(("OTA_run: WARNING, not a tar file, filename=%s\r\n", pOtaLib->pOtaFileName));
334  /* Stay on state, check next file version */
335  pOtaLib->State = OTA_STATE_CHECK_ARCHIVE_NEW_UPDATE;
336  return OTA_RUN_STATUS_CONTINUE;
337  }
338 
339  /* continue anyway, user app can override this decision */
340  pOtaLib->State = OTA_STATE_REQ_FILE_URL;
341 
342 
343  /* Init the Tar parser module */
344  OtaArchive_init(&pOtaLib->OtaArchive);
345 
346  /* host should check the version */
347  pVersionFileName = _ExtractFileVersion(pOtaLib->pOtaFileName, MAX_CDN_FILE_NAME_SIZE);
348  if (OtaArchive_checkVersion(&pOtaLib->OtaArchive, pVersionFileName))
349  {
350  return OTA_RUN_STATUS_CHECK_NEWER_VERSION;
351  }
352  else
353  {
354  return OTA_RUN_STATUS_CHECK_OLDER_VERSION;
355  }
356  }
357 
358  case OTA_STATE_REQ_FILE_URL:
359 
360  _SlOtaLibTrace(("OTA_run: Call CdnClient_ReqFileUrl, filename = %s\r\n", pOtaLib->pOtaFileName));
361  Status = CdnClient_ReqFileUrl(pCdnClient, pOtaLib->pOtaFileName, pOtaLib->FileUrlBuf, sizeof(pOtaLib->FileUrlBuf));
362  if( Status < 0)
363  {
364  _SlOtaLibTrace(("OTA_run: ERROR CdnClient_ReqFileUrl, Status=%d\r\n", Status));
365  Status = _OtaCheckConsecutiveErrors(pOtaLib, OTA_RUN_STATUS_CONTINUE_WARNING_FAILED_REQ_FILE_URL, BACK_TO_IDLE);
366  return Status;
367  }
368 
369  /* In this stage the CDN server can be closed */
370  CdnClient_CloseServer(&pOtaLib->CdnClient);
371 
372  pOtaLib->State = OTA_STATE_CONNECT_FILE_SERVER;
373  break;
374 #endif
375  case OTA_STATE_CONNECT_FILE_SERVER:
376 
377  _SlOtaLibTrace(("OTA_run: Call CdnClient_ConnectFileServer, url = %s\r\n", pOtaLib->FileUrlBuf));
378  Status = CdnClient_ConnectFileServer(&pOtaLib->CdnClient, pOtaLib->FileUrlBuf, pOtaLib->OtaServerInfo.SecuredConnection);
379  if( Status < 0)
380  {
381  /* stay on this state for another retry */
382  _SlOtaLibTrace(("OTA_run: ERROR CdnClient_ConnectFileServer, Status=%d\r\n", Status));
383  Status = _OtaCheckConsecutiveErrors(pOtaLib, OTA_RUN_STATUS_CONTINUE_WARNING_FAILED_CONNECT_FILE_SERVER, BACK_TO_IDLE);
384  return Status;
385  }
386  pOtaLib->State = OTA_STATE_REQ_FILE_CONTENT;
387  break;
388 
389  case OTA_STATE_REQ_FILE_CONTENT:
390 
391  _SlOtaLibTrace(("OTA_run: Call CdnClient_ReqFileContent, url = %s\r\n", pOtaLib->FileUrlBuf));
392  Status = CdnClient_ReqFileContent(&pOtaLib->CdnClient, pOtaLib->FileUrlBuf);
393  if( Status < 0)
394  {
395  _SlOtaLibTrace(("OTA_run: ERROR CdnClient_ReqFileContent, Status=%d\r\n", Status));
396  Status = _OtaCheckConsecutiveErrors(pOtaLib, OTA_RUN_STATUS_CONTINUE_WARNING_FAILED_REQ_FILE_CONTENT, BACK_TO_IDLE);
397  return Status;
398  }
399 
400  pOtaLib->State = OTA_STATE_PREPARE_DOWNLOAD;
401  break;
402 
403  case OTA_STATE_PREPARE_DOWNLOAD:
404 
405  /* prepare receive buffer */
406  pOtaLib->pRecvChunk = pOtaLib->NetBuf;
407  pOtaLib->RecvChunkOffset = 0;
408  pOtaLib->RecvChunkForceReadMode = 0;
409 
410  pOtaLib->RecvChunkSize = CdnClient_RecvSkipHdr(pCdnClient->FileSockId, pOtaLib->pRecvChunk, NET_BUF_SIZE);
411  if (0 >= pOtaLib->RecvChunkSize)
412  {
413  _SlOtaLibTrace(("OTA_run: ERROR downloading, CdnClient_RecvSkipHdr Status=%ld\r\n", pOtaLib->RecvChunkSize));
414  /* Stop the parsing of the archive file */
415  OtaArchive_abort(&pOtaLib->OtaArchive);
416  Status = _OtaCheckConsecutiveErrors(pOtaLib, OTA_RUN_STATUS_CONTINUE_WARNING_FAILED_FILE_HDR, BACK_TO_IDLE);
417  return Status;
418  }
419 
420  pOtaLib->State = OTA_STATE_DOWNLOADING;
421  break;
422 
423  case OTA_STATE_DOWNLOADING:
424 
425  /* Check if to read more chunk */
426  if ((pOtaLib->RecvChunkOffset != 0) || (pOtaLib->RecvChunkSize == 0) || pOtaLib->RecvChunkForceReadMode)
427  {
428  int16_t UnprocessedSize = pOtaLib->RecvChunkSize-pOtaLib->RecvChunkOffset;
429  int16_t Len;
430 
431  if (UnprocessedSize >= TAR_HDR_SIZE)
432  {
433  /* No need to read more, enough unprocessed bytes to decode next TAR file header */
434  memcpy(&pOtaLib->pRecvChunk[0], &pOtaLib->pRecvChunk[pOtaLib->RecvChunkOffset], UnprocessedSize);
435  Len = UnprocessedSize;
436  }
437  else
438  {
439  Len = CdnClient_RecvAppend(pCdnClient->FileSockId, pOtaLib->pRecvChunk, NET_BUF_SIZE, pOtaLib->RecvChunkSize, pOtaLib->RecvChunkOffset);
440  }
441  if (0 >= Len)
442  {
443  _SlOtaLibTrace(("OTA_run: ERROR downloading, CdnClient_RecvAppend Status=%ld\r\n", Len));
444  /* Stop the parsing of the archive file */
445  OtaArchive_abort(&pOtaLib->OtaArchive);
446  Status = _OtaCheckConsecutiveErrors(pOtaLib, OTA_RUN_STATUS_CONTINUE_WARNING_FAILED_RECV_APPEND, BACK_TO_IDLE);
447  return Status;
448  }
449  pOtaLib->RecvChunkOffset = 0;
450  pOtaLib->RecvChunkSize = Len;
451  pOtaLib->RecvChunkForceReadMode = 0;
452  }
453 
454  Status = OtaArchive_process(&pOtaLib->OtaArchive, pOtaLib->pRecvChunk, pOtaLib->RecvChunkSize, &ProcessedBytes);
455  pOtaLib->RecvChunkForceReadMode = (Status == ARCHIVE_STATUS_FORCE_READ_MORE);
456  pOtaLib->RecvChunkOffset += ProcessedBytes;
457  if( Status < 0)
458  {
459  if (Status == ARCHIVE_STATUS_ERROR_SECURITY_ALERT)
460  {
461  _SlOtaLibTrace(("OTA_run: SECURITY ALERT OtaArchive_RunParse, Status=%d\r\n", Status));
462  /* On SECURITY ALERT, stop all, no consecutive errors check */
463  pOtaLib->State = OTA_STATE_IDLE;
464  _OtaCleanToIdle(pOtaLib);
465  Status = OTA_RUN_ERROR_SECURITY_ALERT;
466  }
467  else
468  {
469  _SlOtaLibTrace(("OTA_run: ERROR OtaArchive_RunParse, Status=%d\r\n", Status));
470  Status = _OtaCheckConsecutiveErrors(pOtaLib, OTA_RUN_STATUS_CONTINUE_WARNING_FAILED_DOWNLOAD_AND_SAVE, BACK_TO_IDLE);
471  }
472  return Status;
473  }
474  else if (Status == ARCHIVE_STATUS_DOWNLOAD_DONE)
475  {
476  _SlOtaLibTrace(("OTA_run: ---- Download file completed %s\r\n", pOtaLib->pOtaFileName));
477  CdnClient_CloseFileServer(&pOtaLib->CdnClient);
478  pOtaLib->State = OTA_STATE_WAIT_CONFIRM; /* not real state, cannot go to idle, user app should reset */
479  pOtaLib->ConsecutiveOtaErrors = 0;
480 
481  return OTA_RUN_STATUS_DOWNLOAD_DONE;
482  }
483  break;
484 
485  case OTA_STATE_WAIT_CONFIRM:
486  /* not real state, cannot go to idle, user app should reset */
487  _SlOtaLibTrace(("sl_OtaRun ERROR: unexpected state %d\r\n", pOtaLib->State));
488  return OTA_RUN_STATUS_DOWNLOAD_DONE;
489 
490  default:
491  _SlOtaLibTrace(("sl_OtaRun ERROR: unexpected state %d\r\n", pOtaLib->State));
492  return OTA_RUN_ERROR_UNEXPECTED_STATE;
493 
494  }
495 
496  return OTA_RUN_STATUS_CONTINUE;
497 }
498 
int16_t OTA_set(OTA_option option, int32_t optionLen, uint8_t *pOptionVal, int32_t flags)
Set OTA command/parameter.
Definition: OtaLib.c:99
int16_t OTA_get(OTA_option option, int32_t *pOptionLen, uint8_t *pOptionVal)
Get the current OTA status.
Definition: OtaLib.c:176
int16_t OTA_run()
Run the OTA App state machine.
Definition: OtaLib.c:249
int16_t OTA_init(OTA_runningMode runningMode, OTA_memBlock *pMemBlock, OTA_eventHandler eventHandler)
Initialize the OTA application.
Definition: OtaLib.c:45