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> 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)));
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;
56 memset(pOtaLib, 0,
sizeof(
OtaLib_t));
57 pOtaLib->State = OTA_STATE_IDLE;
59 _SlOtaLibTrace((
"OTA_init: OTA lib version = %s\r\n", OTA_LIB_VERSION));
61 CdnClient_Init(&pOtaLib->CdnClient, pOtaLib->NetBuf);
62 OtaArchive_init(&pOtaLib->OtaArchive);
68 uint8_t *_ExtractFileVersion(uint8_t *pFileName, uint32_t FileNameSize)
70 uint8_t *pVersionFileName = pFileName;
75 while (pVersionFileName != NULL)
77 pVersionFileName = (uint8_t *)Str_FindChar(pFileName,
'/', FileNameSize);
78 if (pVersionFileName != NULL)
81 pFileName = pVersionFileName+1;
88 void _OtaCleanToIdle(
OtaLib_t *pOtaLib)
91 CdnClient_CloseServer(&pOtaLib->CdnClient);
92 CdnClient_CloseFileServer(&pOtaLib->CdnClient);
94 pOtaLib->pOtaFileName = NULL;
95 pOtaLib->State = OTA_STATE_IDLE;
99 int16_t
OTA_set(OTA_option option, int32_t optionLen, uint8_t *pOptionVal, int32_t flags)
101 int16_t Status = OTA_STATUS_OK;
105 case EXTLIB_OTA_SET_OPT_SERVER_INFO:
109 case EXTLIB_OTA_SET_OPT_FILE_SERVER_URL:
110 strcpy((
char *)pOtaLib->FileUrlBuf, (
char *)pOptionVal);
111 pOtaLib->OtaServerInfo.SecuredConnection = OTA_SERVER_SECURED;
114 case EXTLIB_OTA_SET_OPT_VENDOR_ID:
115 if (strlen((
const char *)pOptionVal) >= MAX_VENDIR_DIR_SIZE)
117 return OTA_OPT_ERROR_VENDOR_DIR_SIZE;
119 strcpy((
char *)pOtaLib->VendorDir, (
const char *)pOptionVal);
122 case EXTLIB_OTA_SET_OPT_ACCEPT_UPDATE:
126 case EXTLIB_OTA_SET_OPT_DECLINE_UPDATE:
129 if (pOtaLib->State != OTA_STATE_REQ_FILE_URL)
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;
136 pOtaLib->ConsecutiveOtaErrors = 0;
137 _OtaCleanToIdle(pOtaLib);
140 case EXTLIB_OTA_SET_OPT_IMAGE_COMMIT:
142 Status = OtaArchive_commit();
145 _SlOtaLibTrace((
"OTA_set: ERROR OtaArchive_Commit, status=%d\r\n", Status));
146 return OTA_OPT_ERROR_COMMIT;
152 case EXTLIB_OTA_SET_OPT_IMAGE_ROLLBACK:
154 Status = OtaArchive_rollback();
157 if (Status == SL_ERROR_FS_BUNDLE_NOT_IN_CORRECT_STATE)
159 _SlOtaLibTrace((
"OTA_set: ERROR OtaArchive_Rollback, status=%d - ignored SL_ERROR_FS_BUNDLE_NOT_IN_CORRECT_STATE\r\n", Status));
161 return OTA_STATUS_OK;
163 _SlOtaLibTrace((
"OTA_set: ERROR OtaArchive_Rollback, status=%d\r\n", Status));
164 return OTA_OPT_ERROR_ROLLBACK;
169 _SlOtaLibTrace((
"OTA_set: option %ld is not implemented\r\n", option));
170 return OTA_OPT_ERROR_OPTION_CODE;
176 int16_t
OTA_get(OTA_option option, int32_t *pOptionLen, uint8_t *pOptionVal)
179 int16_t Status = OTA_STATUS_OK;
183 case EXTLIB_OTA_GET_OPT_IS_ACTIVE:
184 *(int32_t *)pOptionVal = (pOtaLib->State != OTA_STATE_IDLE);
185 *pOptionLen =
sizeof(int32_t);
188 case EXTLIB_OTA_GET_OPT_VERSIONS:
192 OtaArchive_getCurrentVersion(pVersionsInfo->CurrentVersion);
194 if(pOtaLib->pOtaFileName == NULL)
198 memset(pVersionsInfo->NewVersion,
'0', VERSION_STR_SIZE);
202 uint8_t *pVersionFileName = _ExtractFileVersion(pOtaLib->pOtaFileName, MAX_CDN_FILE_NAME_SIZE);
204 memcpy(pVersionsInfo->NewVersion, pVersionFileName, VERSION_STR_SIZE);
206 pVersionsInfo->NewVersion[VERSION_STR_SIZE] = 0;
209 case EXTLIB_OTA_GET_OPT_IS_PENDING_COMMIT:
211 *(int32_t *)pOptionVal = OtaArchive_getPendingCommit();
215 _SlOtaLibTrace((
"OTA_get: option %ld is not implemented\r\n", option));
216 Status = OTA_OPT_ERROR_OPTION_CODE;
222 #define BACK_TO_IDLE 0x1 224 int16_t _OtaCheckConsecutiveErrors(
OtaLib_t *pOtaLib, int16_t OtaStatus, int32_t Options)
228 if (++pOtaLib->ConsecutiveOtaErrors >= MAX_CONSECUTIVE_OTA_ERRORS)
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;
236 _SlOtaLibTrace((
"\n_OtaCheckConsecutiveErrors: ConsecutiveOtaErrors=%d/%d, return only WARNNING\r\n", pOtaLib->ConsecutiveOtaErrors, MAX_CONSECUTIVE_OTA_ERRORS));
240 if (Options & BACK_TO_IDLE)
242 pOtaLib->State = OTA_STATE_IDLE;
243 _OtaCleanToIdle(pOtaLib);
253 int16_t ProcessedBytes;
255 switch (pOtaLib->State)
258 #if OTA_SERVER_TYPE == OTA_FILE_DOWNLOAD 260 if(pOtaLib->FileUrlBuf[0] == 0)
262 return OTA_RUN_ERROR_NO_SERVER_NO_VENDOR;
264 pOtaLib->State = OTA_STATE_CONNECT_FILE_SERVER;
267 if (pOtaLib->OtaServerInfo.ServerName[0] == 0)
269 return OTA_RUN_ERROR_NO_SERVER_NO_VENDOR;
272 pOtaLib->State = OTA_STATE_CONNECT_SERVER;
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);
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);
285 pOtaLib->State = OTA_STATE_REQ_OTA_DIR;
288 case OTA_STATE_REQ_OTA_DIR:
291 _SlOtaLibTrace((
"OTA_run: CdnClient_ReqOtaDir, VendorDir=%s\r\n", pOtaLib->VendorDir));
292 NumDirFiles = CdnClient_ReqOtaDir(pCdnClient, pOtaLib->VendorDir);
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);
299 if (NumDirFiles == 0)
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;
307 _SlOtaLibTrace((
"OTA_run: CdnClient_ReqOtaDir, NumDirFiles=%ld\r\n", NumDirFiles));
308 pOtaLib->State = OTA_STATE_CHECK_ARCHIVE_NEW_UPDATE;
312 case OTA_STATE_CHECK_ARCHIVE_NEW_UPDATE:
314 uint8_t *pVersionFileName;
315 _SlOtaLibTrace((
"OTA_run: CdnClient_GetNextDirFile\r\n"));
316 pOtaLib->pOtaFileName = CdnClient_GetNextDirFile(pCdnClient, &pOtaLib->OtaFileSize);
319 if( pOtaLib->pOtaFileName == NULL)
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;
329 _SlOtaLibTrace((
"OTA_run: CdnClient_GetNextDirFile: file=%s, size=%ld\r\n", pOtaLib->pOtaFileName, pOtaLib->OtaFileSize));
331 if (strstr((
const char *)pOtaLib->pOtaFileName,
".tar") == NULL)
333 _SlOtaLibTrace((
"OTA_run: WARNING, not a tar file, filename=%s\r\n", pOtaLib->pOtaFileName));
335 pOtaLib->State = OTA_STATE_CHECK_ARCHIVE_NEW_UPDATE;
336 return OTA_RUN_STATUS_CONTINUE;
340 pOtaLib->State = OTA_STATE_REQ_FILE_URL;
344 OtaArchive_init(&pOtaLib->OtaArchive);
347 pVersionFileName = _ExtractFileVersion(pOtaLib->pOtaFileName, MAX_CDN_FILE_NAME_SIZE);
348 if (OtaArchive_checkVersion(&pOtaLib->OtaArchive, pVersionFileName))
350 return OTA_RUN_STATUS_CHECK_NEWER_VERSION;
354 return OTA_RUN_STATUS_CHECK_OLDER_VERSION;
358 case OTA_STATE_REQ_FILE_URL:
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));
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);
370 CdnClient_CloseServer(&pOtaLib->CdnClient);
372 pOtaLib->State = OTA_STATE_CONNECT_FILE_SERVER;
375 case OTA_STATE_CONNECT_FILE_SERVER:
377 _SlOtaLibTrace((
"OTA_run: Call CdnClient_ConnectFileServer, url = %s\r\n", pOtaLib->FileUrlBuf));
378 Status = CdnClient_ConnectFileServer(&pOtaLib->CdnClient, pOtaLib->FileUrlBuf, pOtaLib->OtaServerInfo.SecuredConnection);
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);
386 pOtaLib->State = OTA_STATE_REQ_FILE_CONTENT;
389 case OTA_STATE_REQ_FILE_CONTENT:
391 _SlOtaLibTrace((
"OTA_run: Call CdnClient_ReqFileContent, url = %s\r\n", pOtaLib->FileUrlBuf));
392 Status = CdnClient_ReqFileContent(&pOtaLib->CdnClient, pOtaLib->FileUrlBuf);
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);
400 pOtaLib->State = OTA_STATE_PREPARE_DOWNLOAD;
403 case OTA_STATE_PREPARE_DOWNLOAD:
406 pOtaLib->pRecvChunk = pOtaLib->NetBuf;
407 pOtaLib->RecvChunkOffset = 0;
408 pOtaLib->RecvChunkForceReadMode = 0;
410 pOtaLib->RecvChunkSize = CdnClient_RecvSkipHdr(pCdnClient->FileSockId, pOtaLib->pRecvChunk, NET_BUF_SIZE);
411 if (0 >= pOtaLib->RecvChunkSize)
413 _SlOtaLibTrace((
"OTA_run: ERROR downloading, CdnClient_RecvSkipHdr Status=%ld\r\n", pOtaLib->RecvChunkSize));
415 OtaArchive_abort(&pOtaLib->OtaArchive);
416 Status = _OtaCheckConsecutiveErrors(pOtaLib, OTA_RUN_STATUS_CONTINUE_WARNING_FAILED_FILE_HDR, BACK_TO_IDLE);
420 pOtaLib->State = OTA_STATE_DOWNLOADING;
423 case OTA_STATE_DOWNLOADING:
426 if ((pOtaLib->RecvChunkOffset != 0) || (pOtaLib->RecvChunkSize == 0) || pOtaLib->RecvChunkForceReadMode)
428 int16_t UnprocessedSize = pOtaLib->RecvChunkSize-pOtaLib->RecvChunkOffset;
431 if (UnprocessedSize >= TAR_HDR_SIZE)
434 memcpy(&pOtaLib->pRecvChunk[0], &pOtaLib->pRecvChunk[pOtaLib->RecvChunkOffset], UnprocessedSize);
435 Len = UnprocessedSize;
439 Len = CdnClient_RecvAppend(pCdnClient->FileSockId, pOtaLib->pRecvChunk, NET_BUF_SIZE, pOtaLib->RecvChunkSize, pOtaLib->RecvChunkOffset);
443 _SlOtaLibTrace((
"OTA_run: ERROR downloading, CdnClient_RecvAppend Status=%ld\r\n", Len));
445 OtaArchive_abort(&pOtaLib->OtaArchive);
446 Status = _OtaCheckConsecutiveErrors(pOtaLib, OTA_RUN_STATUS_CONTINUE_WARNING_FAILED_RECV_APPEND, BACK_TO_IDLE);
449 pOtaLib->RecvChunkOffset = 0;
450 pOtaLib->RecvChunkSize = Len;
451 pOtaLib->RecvChunkForceReadMode = 0;
454 Status = OtaArchive_process(&pOtaLib->OtaArchive, pOtaLib->pRecvChunk, pOtaLib->RecvChunkSize, &ProcessedBytes);
455 pOtaLib->RecvChunkForceReadMode = (Status == ARCHIVE_STATUS_FORCE_READ_MORE);
456 pOtaLib->RecvChunkOffset += ProcessedBytes;
459 if (Status == ARCHIVE_STATUS_ERROR_SECURITY_ALERT)
461 _SlOtaLibTrace((
"OTA_run: SECURITY ALERT OtaArchive_RunParse, Status=%d\r\n", Status));
463 pOtaLib->State = OTA_STATE_IDLE;
464 _OtaCleanToIdle(pOtaLib);
465 Status = OTA_RUN_ERROR_SECURITY_ALERT;
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);
474 else if (Status == ARCHIVE_STATUS_DOWNLOAD_DONE)
476 _SlOtaLibTrace((
"OTA_run: ---- Download file completed %s\r\n", pOtaLib->pOtaFileName));
477 CdnClient_CloseFileServer(&pOtaLib->CdnClient);
478 pOtaLib->State = OTA_STATE_WAIT_CONFIRM;
479 pOtaLib->ConsecutiveOtaErrors = 0;
481 return OTA_RUN_STATUS_DOWNLOAD_DONE;
485 case OTA_STATE_WAIT_CONFIRM:
487 _SlOtaLibTrace((
"sl_OtaRun ERROR: unexpected state %d\r\n", pOtaLib->State));
488 return OTA_RUN_STATUS_DOWNLOAD_DONE;
491 _SlOtaLibTrace((
"sl_OtaRun ERROR: unexpected state %d\r\n", pOtaLib->State));
492 return OTA_RUN_ERROR_UNEXPECTED_STATE;
496 return OTA_RUN_STATUS_CONTINUE;
int16_t OTA_set(OTA_option option, int32_t optionLen, uint8_t *pOptionVal, int32_t flags)
Set OTA command/parameter.
int16_t OTA_get(OTA_option option, int32_t *pOptionLen, uint8_t *pOptionVal)
Get the current OTA status.
int16_t OTA_run()
Run the OTA App state machine.
int16_t OTA_init(OTA_runningMode runningMode, OTA_memBlock *pMemBlock, OTA_eventHandler eventHandler)
Initialize the OTA application.