AWS IoT Over-the-air Update v3.3.0
Client library for AWS IoT OTA
ota.h File Reference

OTA Agent Interface. More...

#include <stdio.h>
#include <stdint.h>
#include "ota_private.h"
#include "ota_os_interface.h"
#include "ota_mqtt_interface.h"
#include "ota_http_interface.h"
#include "ota_platform_interface.h"
Include dependency graph for ota.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  OtaJobDocument_t
 OTA Job document. More...
 
struct  OtaInterfaces_t
 OTA Interface for referencing different components. More...
 
struct  OtaAppBuffer_t
 OTA Application Buffer size information. More...
 
struct  OtaAgentContext_t
 The OTA agent is a singleton today. The structure keeps it nice and organized. More...
 

Macros

#define CONST_STRLEN(s)   ( ( ( uint32_t ) sizeof( s ) ) - 1UL )
 Evaluates to the length of a constant string defined like 'static const char str[]= "xyz";.
 
#define OTA_FILE_SIG_KEY_STR_MAX_LENGTH   32
 

Typedefs

typedef void(* OtaAppCallback_t) (OtaJobEvent_t eEvent, const void *pData)
 OTA update complete callback function typedef. More...
 

Enumerations

enum  OtaErr_t {
  OtaErrNone = 0 , OtaErrUninitialized , OtaErrPanic , OtaErrInvalidArg ,
  OtaErrAgentStopped , OtaErrSignalEventFailed , OtaErrRequestJobFailed , OtaErrInitFileTransferFailed ,
  OtaErrRequestFileBlockFailed , OtaErrCleanupControlFailed , OtaErrCleanupDataFailed , OtaErrUpdateJobStatusFailed ,
  OtaErrJobParserError , OtaErrInvalidDataProtocol , OtaErrMomentumAbort , OtaErrDowngradeNotAllowed ,
  OtaErrSameFirmwareVersion , OtaErrImageStateMismatch , OtaErrNoActiveJob , OtaErrUserAbort ,
  OtaErrFailedToEncodeCbor , OtaErrFailedToDecodeCbor , OtaErrActivateFailed , OtaErrFileSizeOverflow
}
 The OTA API return status. OTA agent error codes are in the upper 8 bits of the 32 bit OTA error word, OtaErr_t. More...
 
enum  OtaState_t {
  OtaAgentStateNoTransition = -1 , OtaAgentStateInit = 0 , OtaAgentStateReady , OtaAgentStateRequestingJob ,
  OtaAgentStateWaitingForJob , OtaAgentStateCreatingFile , OtaAgentStateRequestingFileBlock , OtaAgentStateWaitingForFileBlock ,
  OtaAgentStateClosingFile , OtaAgentStateSuspended , OtaAgentStateShuttingDown , OtaAgentStateStopped ,
  OtaAgentStateAll
}
 OTA Agent states. More...
 
enum  OtaJobParseErr_t {
  OtaJobParseErrUnknown = -1 , OtaJobParseErrNone = 0 , OtaJobParseErrNullJob , OtaJobParseErrUpdateCurrentJob ,
  OtaJobParseErrZeroFileSize , OtaJobParseErrNonConformingJobDoc , OtaJobParseErrBadModelInitParams , OtaJobParseErrNoContextAvailable ,
  OtaJobParseErrNoActiveJobs
}
 OTA job document parser error codes.
 
enum  OtaJobEvent_t {
  OtaJobEventActivate = 0 , OtaJobEventFail = 1 , OtaJobEventStartTest = 2 , OtaJobEventProcessed = 3 ,
  OtaJobEventSelfTestFailed = 4 , OtaJobEventParseCustomJob = 5 , OtaJobEventReceivedJob = 6 , OtaJobEventUpdateComplete = 7 ,
  OtaLastJobEvent = OtaJobEventStartTest
}
 OTA Job callback events. More...
 
enum  OtaJobStatus_t {
  JobStatusInProgress = 0 , JobStatusFailed , JobStatusSucceeded , JobStatusRejected ,
  JobStatusFailedWithVal , NumJobStatusMappings
}
 Gives the status of the job operation.
 

Functions

OtaErr_t OTA_Init (OtaAppBuffer_t *pOtaBuffer, const OtaInterfaces_t *pOtaInterfaces, const uint8_t *pThingName, OtaAppCallback_t OtaAppCallback)
 OTA Agent initialization function. More...
 
OtaState_t OTA_Shutdown (uint32_t ticksToWait, uint8_t unsubscribeFlag)
 Signal to the OTA Agent to shut down. More...
 
OtaState_t OTA_GetState (void)
 Get the current state of the OTA agent. More...
 
OtaErr_t OTA_ActivateNewImage (void)
 Activate the newest MCU image received via OTA. More...
 
OtaErr_t OTA_SetImageState (OtaImageState_t state)
 Set the state of the current MCU image. More...
 
OtaImageState_t OTA_GetImageState (void)
 Get the state of the currently running MCU image. More...
 
OtaErr_t OTA_CheckForUpdate (void)
 Request for the next available OTA job from the job service. More...
 
OtaErr_t OTA_Suspend (void)
 Suspend OTA agent operations . More...
 
OtaErr_t OTA_Resume (void)
 Resume OTA agent operations . More...
 
void OTA_EventProcessingTask (void *pUnused)
 OTA agent event processing loop. More...
 
bool OTA_SignalEvent (const OtaEventMsg_t *const pEventMsg)
 Signal event to the OTA Agent task. More...
 
OtaErr_t OTA_GetStatistics (OtaAgentStatistics_t *pStatistics)
 Get the statistics of OTA message packets. More...
 
const char * OTA_Err_strerror (OtaErr_t err)
 Error code to string conversion for OTA errors. More...
 
const char * OTA_JobParse_strerror (OtaJobParseErr_t err)
 Error code to string conversion for OTA Job Parsing errors. More...
 
const char * OTA_PalStatus_strerror (OtaPalMainStatus_t status)
 Status code to string conversion for OTA PAL status. More...
 
const char * OTA_OsStatus_strerror (OtaOsStatus_t status)
 Status code to string conversion for OTA OS status. More...
 

Variables

const char OTA_JsonFileSignatureKey [OTA_FILE_SIG_KEY_STR_MAX_LENGTH]
 The OTA signature algorithm string is specified by the PAL.
 

Detailed Description

OTA Agent Interface.

Macro Definition Documentation

◆ OTA_FILE_SIG_KEY_STR_MAX_LENGTH

#define OTA_FILE_SIG_KEY_STR_MAX_LENGTH   32

Maximum length of the file signature key.

Function Documentation

◆ OTA_Init()

OtaErr_t OTA_Init ( OtaAppBuffer_t pOtaBuffer,
const OtaInterfaces_t pOtaInterfaces,
const uint8_t *  pThingName,
OtaAppCallback_t  OtaAppCallback 
)

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 OTA_CheckForUpdate. Only one OTA Agent may exist.

Parameters
[in]pOtaBufferBuffers used by the agent to store different params.
[in]pOtaInterfacesA pointer to the OS context.
[in]pThingNameA pointer to a C string holding the Thing name.
[in]OtaAppCallbackStatic 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.
Returns
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.

Example

// 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.
// 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.
}
#define OTA_MAX_BLOCK_BITMAP_SIZE
Max allowed number of bytes to track all blocks of an OTA file. Adjust block size if more range is ne...
Definition: ota_private.h:64
OtaErr_t
The OTA API return status. OTA agent error codes are in the upper 8 bits of the 32 bit OTA error word...
Definition: ota.h:79
OtaJobEvent_t
OTA Job callback events.
Definition: ota.h:166
@ OtaErrNone
No error occurred during the operation.
Definition: ota.h:80
OtaErr_t OTA_Init(OtaAppBuffer_t *pOtaBuffer, const OtaInterfaces_t *pOtaInterfaces, const uint8_t *pThingName, OtaAppCallback_t OtaAppCallback)
OTA Agent initialization function.
Definition: ota.c:3075
OTA Application Buffer size information.
Definition: ota.h:272
uint8_t * pUpdateFilePath
Path to store the files.
Definition: ota.h:273
OtaInitEvent_t init
Initialization event.
Definition: ota_os_interface.h:263
OTA Interface for referencing different components.
Definition: ota.h:258
OtaOSInterface_t os
OS interface to store event, timers and memory operations.
Definition: ota.h:259
OtaEventInterface_t event
OTA Event interface.
Definition: ota_os_interface.h:306

◆ OTA_Shutdown()

OtaState_t OTA_Shutdown ( uint32_t  ticksToWait,
uint8_t  unsubscribeFlag 
)

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.

Parameters
[in]ticksToWaitThe 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.
[in]unsubscribeFlagFlag 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.
Returns
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.

Example

// 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.
}
OtaState_t OTA_GetState(void)
Get the current state of the OTA agent.
Definition: ota.c:3228
OtaState_t OTA_Shutdown(uint32_t ticksToWait, uint8_t unsubscribeFlag)
Signal to the OTA Agent to shut down.
Definition: ota.c:3169

◆ OTA_GetState()

OtaState_t OTA_GetState ( void  )

Get the current state of the OTA agent.

Returns
The current state of the OTA agent.

Example Check if OTA agent is in suspended state.

// OTA Agent state
while( state != OtaAgentStateSuspended )
{
// Do something while the agent is back to
// the desired state.
state = OTA_GetState();
}
OtaState_t
OTA Agent states.
Definition: ota.h:115

◆ OTA_ActivateNewImage()

OtaErr_t OTA_ActivateNewImage ( void  )

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 OTA_Init function for more information about configuring the callback.

Returns
OtaErrNone if successful, otherwise an error code prefixed with 'OtaErr' from the list above.

Example

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.
if( otaErr == OtaErrActivateFailed )
{
// Handle Image activation failure by requesting manual response, sending
// error logs or retrying activation.
}
}
// Handle other events
}
@ OtaErrActivateFailed
Failed to activate the new image.
Definition: ota.h:102
@ OtaJobEventActivate
OTA receive is authenticated and ready to activate.
Definition: ota.h:167
OtaErr_t OTA_ActivateNewImage(void)
Activate the newest MCU image received via OTA.
Definition: ota.c:3277

◆ OTA_SetImageState()

OtaErr_t OTA_SetImageState ( OtaImageState_t  state)

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.

Parameters
[in]stateThe state to set of the OTA image.
Returns
OtaErrNone if successful, otherwise an error code prefixed with 'OtaErr' from the list above.

Example Set image state to reflect new image is accepted in application callback.

static void otaAppCallback( OtaJobEvent_t event,
const void * pData )
{
OtaErr_t otaErr = OtaErrNone;
if( event == OtaJobEventStartTest )
{
if( err != OtaErrNone )
{
// Handle failure or retry setting the image state.
}
}
// Handle other events
}
@ OtaJobEventStartTest
OTA job is now in self test, perform user tests.
Definition: ota.h:169
@ OtaImageStateAccepted
The state of the OTA MCU Image post successful download and successful self_test.
Definition: ota_private.h:317
OtaErr_t OTA_SetImageState(OtaImageState_t state)
Set the state of the current MCU image.
Definition: ota.c:3313

◆ OTA_GetImageState()

OtaImageState_t OTA_GetImageState ( void  )

Get the state of the currently running MCU image.

The states are OtaImageStateTesting, OtaImageStateAccepted, OtaImageStateAborted or OtaImageStateRejected; see OtaImageState_t documentation.

Returns
The state of the current context's OTA image.

◆ OTA_CheckForUpdate()

OtaErr_t OTA_CheckForUpdate ( void  )

Request for the next available OTA job from the job service.

Returns
OtaErrNone if successful, otherwise an error code prefixed with 'OtaErr' from the list above.

◆ OTA_Suspend()

OtaErr_t OTA_Suspend ( void  )

Suspend OTA agent operations .

Returns
OtaErrNone if successful, otherwise an error code prefixed with 'OtaErr' from the list above.

Example Suspend the OTA agent when a network error occurs.

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().
}
}
}
OtaErr_t OTA_Suspend(void)
Suspend OTA agent operations .
Definition: ota.c:3378

◆ OTA_Resume()

OtaErr_t OTA_Resume ( void  )

Resume OTA agent operations .

Returns
OtaErrNone if successful, otherwise an error code prefixed with 'OtaErr' from the list above.

Example Resume the OTA agent after the network errors are resolved.

bool handleReconnect()
{
// OTA event message used for sending event to OTA Agent.
OtaEventMsg_t eventMsg = { 0 };
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.
OTA_SignalEvent( &eventMsg );
}
if( otaErr != OtaErrNone )
returnStatus = false;
}
return returnStatus;
}
@ OtaAgentEventStart
Start the OTA state machine.
Definition: ota_private.h:346
@ OtaErrUninitialized
The error code has not yet been set by a logic path.
Definition: ota.h:81
bool OTA_SignalEvent(const OtaEventMsg_t *const pEventMsg)
Signal event to the OTA Agent task.
Definition: ota.c:2934
OtaErr_t OTA_Resume(void)
Resume OTA agent operations .
Definition: ota.c:3411
Stores information about the event message.
Definition: ota_private.h:430
OtaEvent_t eventId
Definition: ota_private.h:432

◆ OTA_EventProcessingTask()

void OTA_EventProcessingTask ( void *  pUnused)

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.

Parameters
[in]pUnusedCan 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.

◆ OTA_SignalEvent()

bool OTA_SignalEvent ( const OtaEventMsg_t *const  pEventMsg)

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.

Parameters
[in]pEventMsgEvent to be added to the queue
Returns
true If operation is successful, false If the event can not be added

Example Signal OTA agent that a new file block has been received over the http connection.

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();
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;
}
OtaHttpStatus_t
The OTA HTTP interface return status.
Definition: ota_http_interface.h:86
@ OtaAgentEventReceivedFileBlock
Event to trigger when file block is received.
Definition: ota_private.h:352
@ OtaHttpRequestFailed
Error sending the HTTP request.
Definition: ota_http_interface.h:90
@ OtaHttpSuccess
OTA HTTP interface success.
Definition: ota_http_interface.h:87
The OTA Agent event and data structures.
Definition: ota_private.h:418
uint8_t data[OTA_DATA_BLOCK_SIZE]
Definition: ota_private.h:419
uint32_t dataLength
Definition: ota_private.h:420

◆ OTA_GetStatistics()

OtaErr_t OTA_GetStatistics ( OtaAgentStatistics_t pStatistics)

Get the statistics of OTA message packets.

Packet statistics are:

  • Received: The number of OTA packets that have been received but not necessarily queued for processing by the OTA agent.
  • 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.
  • Processed: The number of OTA packets that have actually been processed.
  • Dropped: The number of OTA packets that have been dropped because of either no queue or at shutdown cleanup.
Note
Calling OTA_Init will reset this statistic.
Returns
OtaErrNone if the statistics can be received successfully.

Example

// OTA library packet statistics per job.
OtaAgentStatistics_t otaStatistics = { 0 };
// 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 );
}
OtaErr_t OTA_GetStatistics(OtaAgentStatistics_t *pStatistics)
Get the statistics of OTA message packets.
Definition: ota.c:3236
This is the OTA statistics structure to hold useful info.
Definition: ota_private.h:291
uint32_t otaPacketsReceived
Definition: ota_private.h:292
uint32_t otaPacketsQueued
Definition: ota_private.h:293
uint32_t otaPacketsProcessed
Definition: ota_private.h:294
uint32_t otaPacketsDropped
Definition: ota_private.h:295

◆ OTA_Err_strerror()

const char * OTA_Err_strerror ( OtaErr_t  err)

Error code to string conversion for OTA errors.

Parameters
[in]errThe error to convert to a string.
Returns
The string representation of the error.

◆ OTA_JobParse_strerror()

const char * OTA_JobParse_strerror ( OtaJobParseErr_t  err)

Error code to string conversion for OTA Job Parsing errors.

Parameters
[in]errThe error to convert to a string.
Returns
The string representation of the error.

◆ OTA_PalStatus_strerror()

const char * OTA_PalStatus_strerror ( OtaPalMainStatus_t  status)

Status code to string conversion for OTA PAL status.

Parameters
[in]statusThe status to convert to a string.
Returns
The string representation of the status.

◆ OTA_OsStatus_strerror()

const char * OTA_OsStatus_strerror ( OtaOsStatus_t  status)

Status code to string conversion for OTA OS status.

Parameters
[in]statusThe status to convert to a string.
Returns
The string representation of the status.