2021-11-30 14:51:24 +01:00

814 lines
32 KiB
C

/*
* AWS IoT Over-the-air Update v3.2.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* @file ota.h
* @brief OTA Agent Interface
*/
#ifndef OTA_H
#define OTA_H
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/* Standard includes. */
/* For FILE type in OtaFileContext_t.*/
#include <stdio.h>
#include <stdint.h>
/* OTA Library Interface include. */
#include "ota_private.h"
#include "ota_os_interface.h"
#include "ota_mqtt_interface.h"
#include "ota_http_interface.h"
#include "ota_platform_interface.h"
/**
* @ingroup ota_helpers
* @brief Evaluates to the length of a constant string defined like 'static const char str[]= "xyz";
*/
#define CONST_STRLEN( s ) ( ( ( uint32_t ) sizeof( s ) ) - 1UL )
#define OTA_FILE_SIG_KEY_STR_MAX_LENGTH 32 /*!< Maximum length of the file signature key. */
/**
* @ingroup ota_helpers
* @brief The OTA signature algorithm string is specified by the PAL.
*
*/
/* MISRA rule 8.6 requires identifier with external linkage to have exact one external definition.
* However, this variable is defined in OTA platform abstraction layer implementation, which is
* not in this repository but in C-SDK and amazon-freertos repo, so it's a false positive. */
/* coverity[misra_c_2012_rule_8_6_violation] */
extern const char OTA_JsonFileSignatureKey[ OTA_FILE_SIG_KEY_STR_MAX_LENGTH ];
/*-------------------------- OTA enumerated types --------------------------*/
/**
* @ingroup ota_enum_types
* @brief The OTA API return status.
* OTA agent error codes are in the upper 8 bits of the 32 bit OTA error word, OtaErr_t.
*/
typedef enum OtaErr
{
OtaErrNone = 0, /*!< @brief No error occurred during the operation. */
OtaErrUninitialized, /*!< @brief The error code has not yet been set by a logic path. */
OtaErrPanic, /*!< @brief Unrecoverable Firmware error. Probably should log error and reboot. */
OtaErrInvalidArg, /*!< @brief API called with invalid argument. */
OtaErrAgentStopped, /*!< @brief Returned when operations are performed that requires OTA Agent running & its stopped. */
OtaErrSignalEventFailed, /*!< @brief Failed to send event to OTA state machine. */
OtaErrRequestJobFailed, /*!< @brief Failed to request the job document. */
OtaErrInitFileTransferFailed, /*!< @brief Failed to update the OTA job status. */
OtaErrRequestFileBlockFailed, /*!< @brief Failed to request file block. */
OtaErrCleanupControlFailed, /*!< @brief Failed to clean up the control plane. */
OtaErrCleanupDataFailed, /*!< @brief Failed to clean up the data plane. */
OtaErrUpdateJobStatusFailed, /*!< @brief Failed to update the OTA job status. */
OtaErrJobParserError, /*!< @brief An error occurred during job document parsing. See reason sub-code. */
OtaErrInvalidDataProtocol, /*!< @brief Job does not have a valid protocol for data transfer. */
OtaErrMomentumAbort, /*!< @brief Too many OTA stream requests without any response. */
OtaErrDowngradeNotAllowed, /*!< @brief Firmware version is older than the previous version. */
OtaErrSameFirmwareVersion, /*!< @brief Firmware version is the same as previous. New firmware could have failed to commit. */
OtaErrImageStateMismatch, /*!< @brief The OTA job was in Self Test but the platform image state was not. Possible tampering. */
OtaErrNoActiveJob, /*!< @brief Attempt to set final image state without an active job. */
OtaErrUserAbort, /*!< @brief User aborted the active OTA. */
OtaErrFailedToEncodeCbor, /*!< @brief Failed to encode CBOR object for requesting data block from streaming service. */
OtaErrFailedToDecodeCbor, /*!< @brief Failed to decode CBOR object from streaming service response. */
OtaErrActivateFailed /*!< @brief Failed to activate the new image. */
} OtaErr_t;
/**
* @ingroup ota_enum_types
* @brief OTA Agent states.
*
* The current state of the OTA Task (OTA Agent).
*
* @note There is currently support only for a single OTA context.
*/
typedef enum OtaState
{
OtaAgentStateNoTransition = -1,
OtaAgentStateInit = 0,
OtaAgentStateReady,
OtaAgentStateRequestingJob,
OtaAgentStateWaitingForJob,
OtaAgentStateCreatingFile,
OtaAgentStateRequestingFileBlock,
OtaAgentStateWaitingForFileBlock,
OtaAgentStateClosingFile,
OtaAgentStateSuspended,
OtaAgentStateShuttingDown,
OtaAgentStateStopped,
OtaAgentStateAll
} OtaState_t;
/**
* @ingroup ota_enum_types
* @brief OTA job document parser error codes.
*/
typedef enum OtaJobParseErr
{
OtaJobParseErrUnknown = -1, /* @brief The error code has not yet been set by a logic path. */
OtaJobParseErrNone = 0, /* @brief Signifies no error has occurred. */
OtaJobParseErrNullJob, /* @brief A null job was reported (no job ID). */
OtaJobParseErrUpdateCurrentJob, /* @brief We're already busy with the reported job ID. */
OtaJobParseErrZeroFileSize, /* @brief Job document specified a zero sized file. This is not allowed. */
OtaJobParseErrNonConformingJobDoc, /* @brief The job document failed to fulfill the model requirements. */
OtaJobParseErrBadModelInitParams, /* @brief There was an invalid initialization parameter used in the document model. */
OtaJobParseErrNoContextAvailable, /* @brief There was not an OTA context available. */
OtaJobParseErrNoActiveJobs /* @brief No active jobs are available in the service. */
} OtaJobParseErr_t;
/**
* @ingroup ota_enum_types
* @brief OTA Job callback events.
*
* After an OTA update image is received and authenticated, the agent calls the user
* callback (set with the @ref OTA_Init API) with the value OtaJobEventActivate to
* signal that the device must be rebooted to activate the new image. When the device
* boots, if the OTA job status is in self test mode, the agent calls the user callback
* with the value OtaJobEventStartTest, signaling that any additional self tests
* should be performed.
*
* If the OTA receive fails for any reason, the agent calls the user callback with
* the value OtaJobEventFail instead to allow the user to log the failure and take
* any action deemed appropriate by the user code.
*
* See the OtaImageState_t type for more information.
*/
typedef enum OtaJobEvent
{
OtaJobEventActivate = 0, /*!< @brief OTA receive is authenticated and ready to activate. */
OtaJobEventFail = 1, /*!< @brief OTA receive failed. Unable to use this update. */
OtaJobEventStartTest = 2, /*!< @brief OTA job is now in self test, perform user tests. */
OtaJobEventProcessed = 3, /*!< @brief OTA event queued by OTA_SignalEvent is processed. */
OtaJobEventSelfTestFailed = 4, /*!< @brief OTA self-test failed for current job. */
OtaJobEventParseCustomJob = 5, /*!< @brief OTA event for parsing custom job document. */
OtaJobEventReceivedJob = 6, /*!< @brief OTA event when a new valid AFT-OTA job is received. */
OtaJobEventUpdateComplete = 7, /*!< @brief OTA event when the update is completed. */
OtaLastJobEvent = OtaJobEventStartTest
} OtaJobEvent_t;
/**
* @ingroup ota_enum_types
* @brief Gives the status of the job operation.
*
*/
typedef enum
{
JobStatusInProgress = 0,
JobStatusFailed,
JobStatusSucceeded,
JobStatusRejected, /* Not possible today using the "get next job" feature. FUTURE! */
JobStatusFailedWithVal, /* This shows 2 numeric reason codes. */
NumJobStatusMappings
} OtaJobStatus_t;
/**
* @ingroup ota_struct_types
* @brief OTA Job document.
* @note This is provided as context to the app callback, #OtaAppCallback_t,
* to provide information of a custom job that cannot be parsed.
*
* Structure representing OTA job document.
*/
typedef struct OtaJobDocument
{
const uint8_t * pJobDocJson; /*!< @brief Job document in JSON format. */
size_t jobDocLength; /*!< @brief Job document length in bytes. */
const uint8_t * pJobId; /*!< @brief Job ID associated with the job document. */
size_t jobIdLength; /*!< @brief Length of job ID in bytes. */
uint32_t fileTypeId; /*!< @brief File Type ID from the job document. */
OtaJobParseErr_t parseErr; /*!< @brief Job parsing status. */
OtaJobStatus_t status; /*!< @brief Job status. */
int32_t reason; /*!< @brief Job status reason. */
int32_t subReason; /*!< @brief Job status subreason. */
} OtaJobDocument_t;
/*------------------------- OTA callbacks --------------------------*/
/**
* @ingroup ota_callback_types
* @brief OTA update complete callback function typedef.
*
* The user must register a callback function when initializing the OTA Agent. This
* callback is used to notify the main application when the OTA update job is complete.
* Typically, it is used to reset the device after a successful update by calling
* @ref OTA_ActivateNewImage and may also be used to kick off user specified self tests
* during the Self Test phase.
*
* The callback function is called with one of the following arguments:
*
* OtaJobEventActivate OTA update is authenticated and ready to activate.
* OtaJobEventFail OTA update failed. Unable to use this update.
* OtaJobEventStartTest OTA job is now ready for optional user self tests.
*
* When OtaJobEventActivate is received, the job status details have been updated with
* the state as ready for Self Test. After reboot, the new firmware will (normally) be
* notified that it is in the Self Test phase via the callback and the application may
* then optionally run its own tests before committing the new image.
*
* If the callback function is called with a result of OtaJobEventFail, the OTA update
* job has failed in some way and should be rejected.
*
* @param[in] eEvent An OTA update event from the OtaJobEvent_t enum.
*
* @param[in] pData Optional data related to the event.
*/
typedef void (* OtaAppCallback_t)( OtaJobEvent_t eEvent,
const void * pData );
/*--------------------------- OTA structs ----------------------------*/
/**
* @ingroup ota_struct_types
* @brief OTA Interface for referencing different components.
*
* Information about the different interfaces used to initialize
* the OTA agent with references to components.
*/
typedef struct OtaInterface
{
OtaOSInterface_t os; /*!< @brief OS interface to store event, timers and memory operations. */
OtaMqttInterface_t mqtt; /*!< @brief MQTT interface that references the publish subscribe methods and callbacks. */
OtaHttpInterface_t http; /*!< @brief HTTP interface to request data. */
OtaPalInterface_t pal; /*!< @brief OTA PAL callback structure. */
} OtaInterfaces_t;
/**
* @ingroup ota_struct_types
* @brief OTA Application Buffer size information.
*
* File key signature information to verify the authenticity of the incoming file
*/
typedef struct OtaAppBuffer
{
uint8_t * pUpdateFilePath; /*!< @brief Path to store the files. */
uint16_t updateFilePathsize; /*!< @brief Maximum size of the file path. */
uint8_t * pCertFilePath; /*!< @brief Path to certificate file. */
uint16_t certFilePathSize; /*!< @brief Maximum size of the certificate file path. */
uint8_t * pStreamName; /*!< @brief Name of stream to download the files. */
uint16_t streamNameSize; /*!< @brief Maximum size of the stream name. */
uint8_t * pDecodeMemory; /*!< @brief Place to store the decoded files. */
uint32_t decodeMemorySize; /*!< @brief Maximum size of the decoded files buffer. */
uint8_t * pFileBitmap; /*!< @brief Bitmap of the parameters received. */
uint16_t fileBitmapSize; /*!< @brief Maximum size of the bitmap. */
uint8_t * pUrl; /*!< @brief Presigned url to download files from S3. */
uint16_t urlSize; /*!< @brief Maximum size of the URL. */
uint8_t * pAuthScheme; /*!< @brief Authentication scheme used to validate download. */
uint16_t authSchemeSize; /*!< @brief Maximum size of the auth scheme. */
} OtaAppBuffer_t;
/**
* @ingroup ota_private_struct_types
* @brief The OTA agent is a singleton today. The structure keeps it nice and organized.
*/
typedef struct OtaAgentContext
{
OtaState_t state; /*!< State of the OTA agent. */
uint8_t pThingName[ otaconfigMAX_THINGNAME_LEN + 1U ]; /*!< Thing name + zero terminator. */
OtaFileContext_t fileContext; /*!< Static array of OTA file structures. */
uint32_t fileIndex; /*!< Index of current file in the array. */
uint32_t serverFileID; /*!< Variable to store current file ID passed down */
uint8_t pActiveJobName[ OTA_JOB_ID_MAX_SIZE ]; /*!< The currently active job name. We only allow one at a time. */
uint8_t * pClientTokenFromJob; /*!< The clientToken field from the latest update job. */
uint32_t timestampFromJob; /*!< Timestamp received from the latest job document. */
OtaImageState_t imageState; /*!< The current application image state. */
uint32_t numOfBlocksToReceive; /*!< Number of data blocks to receive per data request. */
OtaAgentStatistics_t statistics; /*!< The OTA agent statistics block. */
uint32_t requestMomentum; /*!< The number of requests sent before a response was received. */
const OtaInterfaces_t * pOtaInterface; /*!< Collection of all interfaces used by the agent. */
OtaAppCallback_t OtaAppCallback; /*!< OTA App callback. */
uint8_t unsubscribeOnShutdown; /*!< Flag to indicate if unsubscribe from job topics should be done at shutdown. */
} OtaAgentContext_t;
/*------------------------- OTA Public API --------------------------*/
/**
* @brief OTA Agent initialization function.
*
* Initialize the OTA engine by starting the OTA Agent ("OTA Task") in the system. This function must
* be called with the connection client context before calling @ref OTA_CheckForUpdate. Only one
* OTA Agent may exist.
*
* @param[in] pOtaBuffer Buffers used by the agent to store different params.
* @param[in] pOtaInterfaces A pointer to the OS context.
* @param[in] pThingName A pointer to a C string holding the Thing name.
* @param[in] OtaAppCallback Static callback function for when an OTA job is complete. This function will have
* input of the state of the OTA image after download and during self-test.
* @return OtaErr_t The state of the OTA Agent upon return from the OtaState_t enum.
* If the agent was successfully initialized and ready to operate, the state will be
* OtaAgentStateReady. Otherwise, it will be one of the other OtaState_t enum values.
*
* <b>Example</b>
* @code{c}
* // Application callback when the OTA agent has completed the job
* // or is in self test mode. For example see [demos](https://github.com/aws/aws-iot-device-sdk-embedded-C/tree/main/demos/ota)
* void otaAppCallback( OtaJobEvent_t event,
* const void * pData );
*
* // Optional: User buffer to pass down to the OTA Agent. These
* // buffers are assumed to be initialized previously, example:
* // uint8_t updateFilePath[ OTA_MAX_FILE_PATH_SIZE ];
* OtaAppBuffer_t otaBuffer =
* {
* .pUpdateFilePath = updateFilePath,
* .updateFilePathsize = OTA_MAX_FILE_PATH_SIZE,
* .pCertFilePath = certFilePath,
* .certFilePathSize = OTA_MAX_FILE_PATH_SIZE,
* .pDecodeMemory = decodeMem,
* .decodeMemorySize = otaconfigFILE_BLOCK_SIZE,
* .pFileBitmap = bitmap,
* .fileBitmapSize = OTA_MAX_BLOCK_BITMAP_SIZE,
* .pUrl = updateUrl,
* .urlSize = OTA_MAX_URL_SIZE,
* .pAuthScheme = authScheme,
* .authSchemeSize = OTA_MAX_AUTH_SCHEME_SIZE
* };
*
* // OTA interface context required for library interface functions
* // The functions set by these interfaces are assumed to be defined
* // For more information see [demos](https://github.com/aws/aws-iot-device-sdk-embedded-C/tree/main/demos/ota)
* OtaInterfaces_t pOtaInterfaces =
* {
* // Initialize OTA library OS Interface.
* .os.event.init = Posix_OtaInitEvent;
* .os.event.send = Posix_OtaSendEvent;
* ...
* // Initialize the OTA library MQTT Interface.
* .mqtt.subscribe = mqttSubscribe;
* .mqtt.publish = mqttPublish;
* .mqtt.unsubscribe = mqttUnsubscribe;
* // Initialize the OTA library HTTP Interface.
* .http.init = httpInit;
* .http.request = httpRequest;
* .http.deinit = httpDeinit;
* // Initialize the OTA library PAL Interface.
* .pal.getPlatformImageState = otaPal_GetPlatformImageState;
* .pal.setPlatformImageState = otaPal_SetPlatformImageState;
* }
*
* // OTA library error status.
* OtaErr_t otaErr = OtaErrNone;
*
* // Unique client identifier
* char * pClientIdentifier = "uniqueClientID";
*
* otaErr = OTA_Init( &otaBuffer,
* &otaInterfaces,
* ( const uint8_t * ) pClientIdentifier,
* otaAppCallback ) ) != OtaErrNone )
* if( otaErr == OtaErrNone )
* {
* // Do something with the OTA agent.
* }
* @endcode
*/
/* @[declare_ota_init] */
OtaErr_t OTA_Init( OtaAppBuffer_t * pOtaBuffer,
const OtaInterfaces_t * pOtaInterfaces,
const uint8_t * pThingName,
OtaAppCallback_t OtaAppCallback );
/* @[declare_ota_init] */
/**
* @brief Signal to the OTA Agent to shut down.
*
* Signals the OTA agent task to shut down. The OTA agent will unsubscribe from all MQTT job
* notification topics, stop in progress OTA jobs, if any, and clear all resources.
*
* @param[in] ticksToWait The number of ticks to wait for the OTA Agent to complete the shutdown process.
* If this is set to zero, the function will return immediately without waiting. The actual state is
* returned to the caller. The agent does not sleep for this while but used for busy looping.
*
* @param[in] unsubscribeFlag Flag to indicate if unsubscribe operations should be performed from the job topics when
* shutdown is called. If the flag is 0 then unsubscribe operations are not called for job topics If application
* requires it to be unsubscribed from the job topics then flag must be set to 1 when calling OTA_Shutdown.
*
* @return One of the OTA agent states from the OtaState_t enum.
* A normal shutdown will return OtaAgentStateNotReady. Otherwise, refer to the OtaState_t enum for details.
*
* <b>Example</b>
* @code{c}
* // ticksToWait used for busy looping until shutdown. Actual delay may depend on the agent priority,
* // and platform.
* uint32_t ticksToWait = 100;
*
* // If it is required that the unsubscribe operations are not
* //performed while shutting down set this to 0.
* uint8_t unsubscribe = 1;
*
* OTA_Shutdown(ticksToWait, unsubscribe);
* ...
*
* if( OTA_GetState() != OtaAgentStateStopped )
* {
* // Optional: Disconnect MQTT and HTTP connections
* // required by the OTA agent and other tasks.
* }
* @endcode
*/
/* @[declare_ota_shutdown] */
OtaState_t OTA_Shutdown( uint32_t ticksToWait,
uint8_t unsubscribeFlag );
/* @[declare_ota_shutdown] */
/**
* @brief Get the current state of the OTA agent.
*
* @return The current state of the OTA agent.
*
* <b>Example</b>
* Check if OTA agent is in suspended state.
* @code{c}
* // OTA Agent state
* OtaState_t state = OTA_GetState();
*
* while( state != OtaAgentStateSuspended )
* {
* // Do something while the agent is back to
* // the desired state.
* state = OTA_GetState();
* }
* @endcode
*/
/* @[declare_ota_getstate] */
OtaState_t OTA_GetState( void );
/* @[declare_ota_getstate] */
/**
* @brief Activate the newest MCU image received via OTA.
*
* This function should reset the MCU and cause a reboot of the system to execute the newly updated
* firmware. It should be called by the user code sometime after the OtaJobEventActivate event
* is passed to the users application via the OTA Job Complete Callback mechanism. Refer to the
* @ref OTA_Init function for more information about configuring the callback.
*
* @return OtaErrNone if successful, otherwise an error code prefixed with 'OtaErr' from the
* list above.
*
* <b>Example</b>
* @code{c}
* static void otaAppCallback( OtaJobEvent_t event,
* const void * pData )
* {
* OtaErr_t otaErr = OtaErrNone;
* if( event == OtaJobEventActivate )
* {
* // Activate the new firmware image.
* // This calls the platform specific code required to
* // activate the received OTA update firmware.
* otaErr = OTA_ActivateNewImage();
* if( otaErr == OtaErrActivateFailed )
* {
* // Handle Image activation failure by requesting manual response, sending
* // error logs or retrying activation.
* }
* }
*
* // Handle other events
* }
* @endcode
*/
/* @[declare_ota_activatenewimage] */
OtaErr_t OTA_ActivateNewImage( void );
/* @[declare_ota_activatenewimage] */
/**
* @brief Set the state of the current MCU image.
*
* The states are OtaImageStateTesting, OtaImageStateAccepted, OtaImageStateAborted or
* OtaImageStateRejected; see OtaImageState_t documentation. This will update the status of the
* current image and publish to the active job status topic.
*
* @param[in] state The state to set of the OTA image.
*
* @return OtaErrNone if successful, otherwise an error code prefixed with 'OtaErr' from the
* list above.
*
* <b>Example</b>
* Set image state to reflect new image is accepted in application callback.
*
* @code{c}
* static void otaAppCallback( OtaJobEvent_t event,
* const void * pData )
* {
* OtaErr_t otaErr = OtaErrNone;
*
* if( event == OtaJobEventStartTest )
* {
* err = OTA_SetImageState( OtaImageStateAccepted );
* if( err != OtaErrNone )
* {
* // Handle failure or retry setting the image state.
* }
* }
*
* // Handle other events
* }
* @endcode
*/
/* @[declare_ota_setimagestate] */
OtaErr_t OTA_SetImageState( OtaImageState_t state );
/* @[declare_ota_setimagestate] */
/**
* @brief Get the state of the currently running MCU image.
*
* The states are OtaImageStateTesting, OtaImageStateAccepted, OtaImageStateAborted or
* OtaImageStateRejected; see OtaImageState_t documentation.
*
* @return The state of the current context's OTA image.
*/
/* @[declare_ota_getimagestate] */
OtaImageState_t OTA_GetImageState( void );
/* @[declare_ota_getimagestate] */
/**
* @brief Request for the next available OTA job from the job service.
*
* @return OtaErrNone if successful, otherwise an error code prefixed with 'OtaErr' from the
* list above.
*/
/* @[declare_ota_checkforupdate] */
OtaErr_t OTA_CheckForUpdate( void );
/* @[declare_ota_checkforupdate] */
/**
* @brief Suspend OTA agent operations .
*
* @return OtaErrNone if successful, otherwise an error code prefixed with 'OtaErr' from the
* list above.
*
* <b>Example</b>
* Suspend the OTA agent when a network error occurs.
* @code{c}
* void handleNetworkErrors()
* {
* OtaErr_t otaErr = OtaErrNone;
* int16_t suspendTimeout = 5000U;
*
* // Handle disconnects and other network reset operations
*
* // Suspend OTA operations.
* otaErr = OTA_Suspend();
*
* if( otaErr != OtaErrNone )
* {
* // Suspend may fail due to Event queue failure,
* // or if the agent has shut down, handle the failure by
* // sending logs or retrying OTA_Suspend().
* }
* else
* {
* while( ( ( OTA_GetState() != OtaAgentStateSuspended )
* && ( suspendTimeout > 0 ) )
* {
* // Wait for OTA Library state to suspend
* portSleep( 1000U );
* suspendTimeout -= 1000U;
* }
* if( OTA_GetState() != OtaAgentStateSuspended )
* {
* // Handle Suspend failure or Retry OTA_Suspend().
* }
* }
* }
* @endcode
*/
/* @[declare_ota_suspend] */
OtaErr_t OTA_Suspend( void );
/* @[declare_ota_suspend] */
/**
* @brief Resume OTA agent operations .
*
* @return OtaErrNone if successful, otherwise an error code prefixed with 'OtaErr' from the
* list above.
*
* <b>Example</b>
* Resume the OTA agent after the network errors are resolved.
* @code{c}
* bool handleReconnect()
* {
* // OTA event message used for sending event to OTA Agent.
* OtaEventMsg_t eventMsg = { 0 };
* OtaErr_t otaErr = OtaErrUninitialized;
* bool returnStatus = establishConnection();
*
* if( returnStatus == EXIT_SUCCESS )
* {
* // Check if OTA process was suspended and resume if required.
* if( OTA_GetState() == OtaAgentStateSuspended )
* {
* // Resume OTA operations.
* otaErr = OTA_Resume();
* }
* else
* {
* // Send start event to OTA Agent.
* eventMsg.eventId = OtaAgentEventStart;
* OTA_SignalEvent( &eventMsg );
* }
*
* if( otaErr != OtaErrNone )
* returnStatus = false;
* }
*
* return returnStatus;
* }
* @endcode
*/
/* @[declare_ota_resume] */
OtaErr_t OTA_Resume( void );
/* @[declare_ota_resume] */
/**
* @brief OTA agent event processing loop.
*
* This is the main event loop to handle events for OTA update and needs to be called by
* the application task. This loop will continue to handle and execute events received for
* OTA Update until this tasks is terminated by the application.
*
* @param[in] pUnused Can be used to pass down functionality to the agent task, Unused for now.
* This can be a function pointer that executes as the first routine when the
* event loop starts.
*
* For a Posix based reference of creating a thread with this task,
* please see the [demos in AWS IoT Embedded C SDK repository](https://github.com/aws/aws-iot-device-sdk-embedded-C/tree/main/demos/ota).
*/
/* @[declare_ota_eventprocessingtask] */
void OTA_EventProcessingTask( void * pUnused );
/* @[declare_ota_eventprocessingtask] */
/**
* @brief Signal event to the OTA Agent task.
*
* This function adds the event to the back of event queue and used
* by internal OTA modules to signal agent task.
*
* @param[in] pEventMsg Event to be added to the queue
* @return true If operation is successful, false If the event can not be added
*
* <b>Example</b>
* Signal OTA agent that a new file block has been received over the http connection.
* @code{c}
* OtaHttpStatus_t handleDataFromHTTPService( const HTTPResponse_t * pResponse )
* {
* // Assume otaEventBufferGet is a user defined, thread-safe function
* // that gets an available buffer from the pool of OTA buffers.
* OtaEventData_t * pData = otaEventBufferGet();
* OtaHttpStatus_t returnValue = OtaHttpRequestFailed;
* bool result = false;
*
* // Validate pResponse for correct data.
*
* if( pData != NULL )
* {
* memcpy( pData->data, pResponse->pBody, pResponse->bodyLen );
* pData->dataLength = pResponse->bodyLen;
*
* // Send job document received event.
* eventMsg.eventId = OtaAgentEventReceivedFileBlock;
* eventMsg.pEventData = pData;
* result = OTA_SignalEvent( &eventMsg );
*
* if( result )
* {
* returnValue = OtaHttpSuccess;
* }
* }
* return returnValue;
* }
* @endcode
*/
/* @[declare_ota_signalevent] */
bool OTA_SignalEvent( const OtaEventMsg_t * const pEventMsg );
/* @[declare_ota_signalevent] */
/*---------------------------------------------------------------------------*/
/* Statistics API */
/*---------------------------------------------------------------------------*/
/**
* @brief Get the statistics of OTA message packets.
*
* Packet statistics are:
* <ul>
* <li> Received: The number of OTA packets that have been received
* but not necessarily queued for processing by the OTA agent.
* <li> Queued: The number of OTA packets that have been queued for
* processing. This implies there was a free message queue entry so
* it can be passed to the agent for processing.
* <li> Processed: The number of OTA packets that have actually been
* processed.
* <li> Dropped: The number of OTA packets that have been dropped
* because of either no queue or at shutdown cleanup.
*</ul>
* @note Calling @ref OTA_Init will reset this statistic.
*
* @return OtaErrNone if the statistics can be received successfully.
*
* <b>Example</b>
* @code{c}
* // OTA library packet statistics per job.
* OtaAgentStatistics_t otaStatistics = { 0 };
* OtaErr_t otaErr = OtaErrNone;
*
* // Get the current statistics from the agent.
* otaErr = OTA_GetStatistics( &otaStatistics );
*
* if( otaErr != OtaErrNone )
* {
* printf( " Received: %u Queued: %u Processed: %u Dropped: %u",
* otaStatistics.otaPacketsReceived,
* otaStatistics.otaPacketsQueued,
* otaStatistics.otaPacketsProcessed,
* otaStatistics.otaPacketsDropped );
* }
* @endcode
*/
/* @[declare_ota_getstatistics] */
OtaErr_t OTA_GetStatistics( OtaAgentStatistics_t * pStatistics );
/* @[declare_ota_getstatistics] */
/**
* @brief Error code to string conversion for OTA errors.
*
* @param[in] err The error to convert to a string.
*
* @return The string representation of the error.
*/
/* @[declare_ota_err_strerror] */
const char * OTA_Err_strerror( OtaErr_t err );
/* @[declare_ota_err_strerror] */
/**
* @brief Error code to string conversion for OTA Job Parsing errors.
*
* @param[in] err The error to convert to a string.
*
* @return The string representation of the error.
*/
/* @[declare_ota_jobparse_strerror] */
const char * OTA_JobParse_strerror( OtaJobParseErr_t err );
/* @[declare_ota_jobparse_strerror] */
/**
* @brief Status code to string conversion for OTA PAL status.
*
* @param[in] status The status to convert to a string.
*
* @return The string representation of the status.
*/
/* @[declare_ota_palstatus_strerror] */
const char * OTA_PalStatus_strerror( OtaPalMainStatus_t status );
/* @[declare_ota_palstatus_strerror] */
/**
* @brief Status code to string conversion for OTA OS status.
*
* @param[in] status The status to convert to a string.
*
* @return The string representation of the status.
*/
/* @[declare_ota_osstatus_strerror] */
const char * OTA_OsStatus_strerror( OtaOsStatus_t status );
/* @[declare_ota_osstatus_strerror] */
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* ifndef OTA_H */