Routines for supporting over the air updates using MQTT. More...
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "ota.h"
#include "ota_private.h"
#include "ota_cbor_private.h"
#include "ota_mqtt_private.h"
#include "ota_appversion32.h"
Functions | |
static OtaMqttStatus_t | subscribeToJobNotificationTopics (const OtaAgentContext_t *pAgentCtx) |
Subscribe to the jobs notification topic (i.e. New file version available). | |
static OtaMqttStatus_t | unsubscribeFromDataStream (const OtaAgentContext_t *pAgentCtx) |
UnSubscribe from the firmware update receive topic. | |
static OtaMqttStatus_t | unsubscribeFromJobNotificationTopic (const OtaAgentContext_t *pAgentCtx) |
UnSubscribe from the jobs notification topic. | |
static OtaMqttStatus_t | publishStatusMessage (const OtaAgentContext_t *pAgentCtx, const char *pMsg, uint32_t msgSize, uint8_t qos) |
Publish a message to the job status topic. | |
static uint32_t | buildStatusMessageReceiving (char *pMsgBuffer, size_t msgBufferSize, OtaJobStatus_t status, const OtaFileContext_t *pOTAFileCtx) |
Populate the message buffer with the job status message. | |
static uint32_t | prvBuildStatusMessageSelfTest (char *pMsgBuffer, size_t msgBufferSize, OtaJobStatus_t status, int32_t reason) |
Populate the message buffer with the message to indicate device in self-test. | |
static uint32_t | prvBuildStatusMessageFinish (char *pMsgBuffer, size_t msgBufferSize, OtaJobStatus_t status, int32_t reason, int32_t subReason, uint32_t previousVersion) |
Populate the response message with the status of the job. | |
static size_t | stringBuilder (char *pBuffer, size_t bufferSizeBytes, const char *const strings[]) |
Build a string from a set of strings. | |
static size_t | stringBuilderUInt32Decimal (char *pBuffer, size_t bufferSizeBytes, uint32_t value) |
Build a string with the decimal representation of a uint32_t value. | |
static size_t | stringBuilderUInt32Hex (char *pBuffer, size_t bufferSizeBytes, uint32_t value) |
Build a string with the hex representation of a uint32_t value. | |
OtaErr_t | requestJob_Mqtt (const OtaAgentContext_t *pAgentCtx) |
Check for available OTA job over MQTT. | |
OtaErr_t | updateJobStatus_Mqtt (const OtaAgentContext_t *pAgentCtx, OtaJobStatus_t status, int32_t reason, int32_t subReason) |
Update job status over MQTT. | |
OtaErr_t | initFileTransfer_Mqtt (const OtaAgentContext_t *pAgentCtx) |
Initialize file transfer over MQTT. | |
OtaErr_t | requestFileBlock_Mqtt (OtaAgentContext_t *pAgentCtx) |
Request File block over MQTT. | |
OtaErr_t | decodeFileBlock_Mqtt (const uint8_t *pMessageBuffer, size_t messageSize, int32_t *pFileId, int32_t *pBlockId, int32_t *pBlockSize, uint8_t *const *pPayload, size_t *pPayloadSize) |
Decode a cbor encoded fileblock. | |
OtaErr_t | cleanupControl_Mqtt (const OtaAgentContext_t *pAgentCtx) |
Cleanup related to OTA control plane over MQTT. | |
OtaErr_t | cleanupData_Mqtt (const OtaAgentContext_t *pAgentCtx) |
Cleanup related to OTA data plane over MQTT. | |
const char * | OTA_MQTT_strerror (OtaMqttStatus_t status) |
Status to string conversion for OTA MQTT interface status. | |
Variables | |
static const char | pOtaJobsGetNextTopicTemplate [] = MQTT_API_THINGS "%s"MQTT_API_JOBS_NEXT_GET |
static const char | pOtaJobsNotifyNextTopicTemplate [] = MQTT_API_THINGS "%s"MQTT_API_JOBS_NOTIFY_NEXT |
static const char | pOtaJobStatusTopicTemplate [] = MQTT_API_THINGS "%s"MQTT_API_JOBS "%s"MQTT_API_UPDATE |
static const char | pOtaStreamDataTopicTemplate [] = MQTT_API_THINGS "%s"MQTT_API_STREAMS "%s"MQTT_API_DATA_CBOR |
static const char | pOtaGetStreamTopicTemplate [] = MQTT_API_THINGS "%s"MQTT_API_STREAMS "%s"MQTT_API_GET_CBOR |
static const char | pOtaGetNextJobMsgTemplate [] = "{\"clientToken\":\"%u:%s\"}" |
static const char | pOtaStringReceive [] = "\"receive\"" |
static const char * | pOtaJobStatusStrings [NumJobStatusMappings] |
List of all the status cases a job can be in. | |
static const char * | pOtaJobReasonStrings [NumJobReasons] = { "", "ready", "active", "accepted", "rejected", "aborted" } |
These are the associated statusDetails 'reason' codes that go along with the above enums during the OTA update process. The 'Receiving' state is updated with transfer progress as number of blocks received of total blocks. | |
static const char | asciiDigits [] |
These are used for both decimal and hex string conversions. | |
Routines for supporting over the air updates using MQTT.
#define OTA_CLIENT_TOKEN "rdy" |
Arbitrary client token sent in the stream "GET" message.
#define OTA_CLIENT_TOKEN_MAX_THINGNAME_LEN 53U |
Max ThingName length = Max client token length (64) - Max request count length (10) - 1 (colon separator)
#define OTA_STATUS_MSG_MAX_SIZE 128U |
Max length of a job status message to the service.
#define MQTT_API_THINGS "$aws/things/" |
Topic strings used by the OTA process.
These first few are topic extensions to the dynamic base topic that includes the Thing name. Topic prefix for thing APIs.
#define MQTT_API_JOBS_NEXT_GET "/jobs/$next/get" |
Topic suffix for job API.
#define MQTT_API_JOBS_NOTIFY_NEXT "/jobs/notify-next" |
Topic suffix for job API.
#define MQTT_API_JOBS "/jobs/" |
Job API identifier.
#define MQTT_API_UPDATE "/update" |
Job API identifier.
#define MQTT_API_STREAMS "/streams/" |
Stream API identifier.
#define MQTT_API_DATA_CBOR "/data/cbor" |
Stream API suffix.
#define MQTT_API_GET_CBOR "/get/cbor" |
Stream API suffix.
#define JOBS_API_STATUS_IN_PROGRESS "IN_PROGRESS" |
We map all of the above status cases to one of these status strings. These are the only strings that are supported by the Job Service. You shall not change them to arbitrary strings or the job will not change states. The job document has be received on the device and update is in progress.
#define JOBS_API_STATUS_FAILED "FAILED" |
OTA update failed due to an error.
#define JOBS_API_STATUS_SUCCEEDED "SUCCEEDED" |
OTA update succeeded.
#define JOBS_API_STATUS_REJECTED "REJECTED" |
The job was rejected due to invalid parameters.
#define U32_MAX_LEN 10U |
Maximum number of output digits of an unsigned long value.
#define JOB_NAME_MAX_LEN 128U |
Maximum length of the name of job documents received from the server.
#define STREAM_NAME_MAX_LEN 44U |
Maximum length for the name of MQTT streams.
#define NULL_CHAR_LEN 1U |
Size of a single null character used to terminate topics and messages.
#define TOPIC_PLUS_THINGNAME_LEN | ( | topic | ) | ( CONST_STRLEN( topic ) + otaconfigMAX_THINGNAME_LEN + NULL_CHAR_LEN ) |
Calculate max buffer size based on topic template and thing name length.
#define TOPIC_GET_NEXT_BUFFER_SIZE ( TOPIC_PLUS_THINGNAME_LEN( pOtaJobsGetNextTopicTemplate ) ) |
Max buffer size for jobs/$next/get
topic.
#define TOPIC_NOTIFY_NEXT_BUFFER_SIZE ( TOPIC_PLUS_THINGNAME_LEN( pOtaJobsNotifyNextTopicTemplate ) ) |
Max buffer size for jobs/notify-next
topic.
#define TOPIC_JOB_STATUS_BUFFER_SIZE ( TOPIC_PLUS_THINGNAME_LEN( pOtaJobStatusTopicTemplate ) + JOB_NAME_MAX_LEN ) |
Max buffer size for jobs/<job_name>/update
topic.
#define TOPIC_STREAM_DATA_BUFFER_SIZE ( TOPIC_PLUS_THINGNAME_LEN( pOtaStreamDataTopicTemplate ) + STREAM_NAME_MAX_LEN ) |
Max buffer size for streams/<stream_name>/data/cbor
topic.
#define TOPIC_GET_STREAM_BUFFER_SIZE ( TOPIC_PLUS_THINGNAME_LEN( pOtaGetStreamTopicTemplate ) + STREAM_NAME_MAX_LEN ) |
Max buffer size for streams/<stream_name>/get/cbor
topic.
#define MSG_GET_NEXT_BUFFER_SIZE ( CONST_STRLEN( "{\"clientToken\":\"" ) + CONST_STRLEN( ":" ) + CONST_STRLEN( "\"}" ) + OTA_CLIENT_TOKEN_MAX_THINGNAME_LEN + U32_MAX_LEN + 1 ) |
Max buffer size for message of jobs/$next/get topic
.
|
static |
Subscribe to the jobs notification topic (i.e. New file version available).
[in] | pAgentCtx | Agent context which stores the thing details and mqtt interface. |
|
static |
UnSubscribe from the firmware update receive topic.
[in] | pAgentCtx | Agent context which stores the thing details and mqtt interface. |
|
static |
UnSubscribe from the jobs notification topic.
[in] | pAgentCtx | Agent context which stores the thing details and mqtt interface. |
|
static |
Publish a message to the job status topic.
[in] | pAgentCtx | Agent context which provides the details for the thing, job and mqtt interface. |
[in] | pMsg | Message to publish. |
[in] | msgSize | Size of message to send. |
[in] | qos | Quality of service level for mqtt. |
|
static |
Populate the message buffer with the job status message.
[in] | pMsgBuffer | Buffer to populate. |
[in] | msgBufferSize | Size of the message. |
[in] | status | Status of the operation. |
[in] | pOTAFileCtx | File context stores the information about the downloaded blocks and required size. |
|
static |
Populate the message buffer with the message to indicate device in self-test.
[in] | pMsgBuffer | Buffer to populate. |
[in] | msgBufferSize | Size of the message. |
[in] | status | Status of the operation. |
[in] | reason | Reason for job failure (if any). |
|
static |
Populate the response message with the status of the job.
[in] | pMsgBuffer | Buffer to populate. |
[in] | msgBufferSize | Size of the message. |
[in] | status | Status of the operation. |
[in] | reason | Reason for failure or the new firmware version. |
[in] | subReason | Error code due to which the operation failed. |
[in] | previousVersion | Version from which the new version was updated. |
|
static |
Build a string from a set of strings.
[in] | pBuffer | Buffer to place the output string in. |
[in] | bufferSizeBytes | Size of the buffer pointed to by pBuffer. |
[in] | strings | NULL-terminated array of string pointers. |
|
static |
Build a string with the decimal representation of a uint32_t value.
[in] | pBuffer | Buffer to place the output string in. |
[in] | bufferSizeBytes | Size of the buffer pointed to by pBuffer. |
[in] | value | The uint32_t value to convert. |
|
static |
Build a string with the hex representation of a uint32_t value.
[in] | pBuffer | Buffer to place the output string in. |
[in] | bufferSizeBytes | Size of the buffer pointed to by pBuffer. |
[in] | value | The uint32_t value to convert. |
OtaErr_t requestJob_Mqtt | ( | const OtaAgentContext_t * | pAgentCtx | ) |
Check for available OTA job over MQTT.
This function Request for the next available OTA job from the job service by publishing a "get next job" message to the job service.
[in] | pAgentCtx | The OTA agent context. |
OtaErr_t updateJobStatus_Mqtt | ( | const OtaAgentContext_t * | pAgentCtx, |
OtaJobStatus_t | status, | ||
int32_t | reason, | ||
int32_t | subReason | ||
) |
Update job status over MQTT.
This function updates the OTA job status over MQTT with information like in progress, completion or failure.
[in] | pAgentCtx | The OTA agent context. |
[in] | status | The OTA job status which should be updated. |
[in] | reason | The major reason for the status update. |
[in] | subReason | The platform specific reason. |
OtaErr_t initFileTransfer_Mqtt | ( | const OtaAgentContext_t * | pAgentCtx | ) |
Initialize file transfer over MQTT.
This function initializes the file transfer after the OTA job is parsed and accepted by subscribing to the data streaming topics.
[in] | pAgentCtx | The OTA agent context. |
< Buffer to store the topic generated for requesting data stream.
OtaErr_t requestFileBlock_Mqtt | ( | OtaAgentContext_t * | pAgentCtx | ) |
Request File block over MQTT.
This function is used for requesting a file block over MQTT using the file context.
[in] | pAgentCtx | The OTA agent context. |
OtaErr_t decodeFileBlock_Mqtt | ( | const uint8_t * | pMessageBuffer, |
size_t | messageSize, | ||
int32_t * | pFileId, | ||
int32_t * | pBlockId, | ||
int32_t * | pBlockSize, | ||
uint8_t *const * | pPayload, | ||
size_t * | pPayloadSize | ||
) |
Decode a cbor encoded fileblock.
This function is used for decoding a file block received over MQTT & encoded in cbor.
[in] | pMessageBuffer | The message to be decoded. |
[in] | messageSize | The size of the message in bytes. |
[out] | pFileId | The server file ID. |
[out] | pBlockId | The file block ID. |
[out] | pBlockSize | The file block size. |
[out] | pPayload | The payload. |
[out] | pPayloadSize | The payload size. |
OtaErr_t cleanupControl_Mqtt | ( | const OtaAgentContext_t * | pAgentCtx | ) |
Cleanup related to OTA control plane over MQTT.
This function cleanup by unsubscribing from any topics that were subscribed for performing OTA over MQTT.
[in] | pAgentCtx | The OTA agent context. |
OtaErr_t cleanupData_Mqtt | ( | const OtaAgentContext_t * | pAgentCtx | ) |
Cleanup related to OTA data plane over MQTT.
This function performs cleanup by unsubscribing from any topics that were subscribed for performing OTA data over MQTT.
[in] | pAgentCtx | The OTA agent context. |
const char * OTA_MQTT_strerror | ( | OtaMqttStatus_t | status | ) |
Status to string conversion for OTA MQTT interface status.
[in] | status | The status to convert to a string. |
|
static |
Topic template to request next job.
|
static |
Topic template to notify next .
|
static |
Topic template to update the current job.
|
static |
Topic template to receive data over a stream.
|
static |
Topic template to request next data over a stream.
|
static |
Used to specify client token id to authenticate job.
|
static |
Used to build the job receive template.
|
static |
List of all the status cases a job can be in.
|
static |
These are the associated statusDetails 'reason' codes that go along with the above enums during the OTA update process. The 'Receiving' state is updated with transfer progress as number of blocks received of total blocks.
|
static |
These are used for both decimal and hex string conversions.