AWS IoT Device Shadow v1.3.0
AWS IoT Device Shadow client library
shadow.c File Reference

Implements the user-facing functions of the Shadow library. More...

#include <string.h>
#include "shadow.h"

Macros

#define SHADOW_NAME_MAX_LENGTH   ( 64U )
 Maximum shadow name length. Refer to https://docs.aws.amazon.com/general/latest/gr/iot-core.html#device-shadow-limits for more details about the Device Shadow limits.
 
#define SHADOW_THINGNAME_MAX_LENGTH   ( 128U )
 Maximum thing name length. Refer to https://docs.aws.amazon.com/general/latest/gr/iot-core.html#device-shadow-limits for more details about the Device Shadow limits.
 
#define SHADOW_OP_UPDATE_ACCEPTED   SHADOW_OP_UPDATE SHADOW_SUFFIX_ACCEPTED
 The string representing "/shadow/update/accepted".
 
#define SHADOW_OP_UPDATE_REJECTED   SHADOW_OP_UPDATE SHADOW_SUFFIX_REJECTED
 The string representing "/shadow/update/rejected".
 
#define SHADOW_OP_UPDATE_DELTA   SHADOW_OP_UPDATE SHADOW_SUFFIX_DELTA
 The string representing "/shadow/update/delta".
 
#define SHADOW_OP_UPDATE_DOCUMENTS   SHADOW_OP_UPDATE SHADOW_SUFFIX_DOCUMENTS
 The string representing "/shadow/update/document".
 
#define SHADOW_OP_DELETE_ACCEPTED   SHADOW_OP_DELETE SHADOW_SUFFIX_ACCEPTED
 The string representing "/shadow/delete/accepted".
 
#define SHADOW_OP_DELETE_REJECTED   SHADOW_OP_DELETE SHADOW_SUFFIX_REJECTED
 The string representing "/shadow/delete/accepted".
 
#define SHADOW_OP_GET_ACCEPTED   SHADOW_OP_GET SHADOW_SUFFIX_ACCEPTED
 The string representing "/shadow/get/accepted".
 
#define SHADOW_OP_GET_REJECTED   SHADOW_OP_GET SHADOW_SUFFIX_REJECTED
 The string representing "/shadow/get/accepted".
 
#define SHADOW_OP_UPDATE_ACCEPTED_LENGTH   ( SHADOW_OP_UPDATE_LENGTH + SHADOW_SUFFIX_ACCEPTED_LENGTH )
 The length of "/shadow/update/accepted".
 
#define SHADOW_OP_UPDATE_REJECTED_LENGTH   ( SHADOW_OP_UPDATE_LENGTH + SHADOW_SUFFIX_REJECTED_LENGTH )
 The length of "/shadow/update/rejected".
 
#define SHADOW_OP_UPDATE_DOCUMENTS_LENGTH   ( SHADOW_OP_UPDATE_LENGTH + SHADOW_SUFFIX_DOCUMENTS_LENGTH )
 The length of "/shadow/update/document".
 
#define SHADOW_OP_UPDATE_DELTA_LENGTH   ( SHADOW_OP_UPDATE_LENGTH + SHADOW_SUFFIX_DELTA_LENGTH )
 The length of "/shadow/update/rejected".
 
#define SHADOW_OP_GET_ACCEPTED_LENGTH   ( SHADOW_OP_GET_LENGTH + SHADOW_SUFFIX_ACCEPTED_LENGTH )
 The length of "/shadow/get/accepted".
 
#define SHADOW_OP_GET_REJECTED_LENGTH   ( SHADOW_OP_GET_LENGTH + SHADOW_SUFFIX_REJECTED_LENGTH )
 The length of "/shadow/get/rejected".
 
#define SHADOW_OP_DELETE_ACCEPTED_LENGTH   ( SHADOW_OP_DELETE_LENGTH + SHADOW_SUFFIX_ACCEPTED_LENGTH )
 The length of "/shadow/get/accepted".
 
#define SHADOW_OP_DELETE_REJECTED_LENGTH   ( SHADOW_OP_DELETE_LENGTH + SHADOW_SUFFIX_REJECTED_LENGTH )
 The length of "/shadow/delete/rejected".
 

Functions

static ShadowStatus_t validateMatchTopicParameters (const char *pTopic, uint16_t topicLength, const ShadowMessageType_t *pMessageType)
 Check if Shadow_MatchTopicString has valid parameters. More...
 
static ShadowStatus_t validateAssembleTopicParameters (ShadowTopicStringType_t topicType, const char *pThingName, uint8_t thingNameLength, const char *pShadowName, uint8_t shadowNameLength, const char *pTopicBuffer, const uint16_t *pOutLength)
 Check if Shadow_AssembleTopicString has valid parameters. More...
 
static ShadowStatus_t containsSubString (const char *pString, uint16_t stringLength, const char *pSubString, uint16_t subStringLength)
 Determine if the string contains the substring. More...
 
static ShadowStatus_t validateName (const char *pString, uint16_t stringLength, uint8_t maxAllowedLength, uint8_t *pNameLength)
 Check if the Thing or Shadow Name is valid. More...
 
static ShadowStatus_t extractShadowMessageType (const char *pString, uint16_t stringLength, ShadowMessageType_t *pMessageType)
 Extract the Shadow message type from a string. More...
 
static ShadowStatus_t extractThingName (const char *pTopic, uint16_t topicLength, uint16_t *pConsumedTopicLength, uint8_t *pThingNameLength)
 Extract the Thing name from a topic string. More...
 
static ShadowStatus_t extractShadowRootAndName (const char *pTopic, uint16_t topicLength, uint16_t *pConsumedTopicLength, uint8_t *pShadowNameLength)
 Extract the classic shadow root OR the named shadow root and shadow name from a topic string. More...
 
static const char * getShadowOperationString (ShadowTopicStringType_t topicType)
 Get the shadow operation string for a given shadow topic type. More...
 
static uint16_t getShadowOperationLength (ShadowTopicStringType_t topicType)
 Get the shadow operation string length for a given shadow topic type. More...
 
static void createShadowTopicString (ShadowTopicStringType_t topicType, const char *pThingName, uint8_t thingNameLength, const char *pShadowName, uint8_t shadowNameLength, char *pTopicBuffer)
 Creates a shadow topic string. More...
 
ShadowStatus_t Shadow_MatchTopicString (const char *pTopic, uint16_t topicLength, ShadowMessageType_t *pMessageType, const char **pThingName, uint8_t *pThingNameLength, const char **pShadowName, uint8_t *pShadowNameLength)
 Given the topic string of an incoming message, determine whether it is related to a device shadow; if it is, return information about the type of device shadow message, and pointers to the Thing Name and Shadow Name inside of the topic string. See ShadowMessageType_t for the list of message types. Those types correspond to Device Shadow Topics. More...
 
ShadowStatus_t Shadow_AssembleTopicString (ShadowTopicStringType_t topicType, const char *pThingName, uint8_t thingNameLength, const char *pShadowName, uint8_t shadowNameLength, char *pTopicBuffer, uint16_t bufferSize, uint16_t *pOutLength)
 Assemble shadow topic string when Thing Name or Shadow Name is only known at run time. If both the Thing Name and Shadow Name are known at compile time, use SHADOW_TOPIC_STR_* macros instead. More...
 
ShadowStatus_t Shadow_MatchTopic (const char *pTopic, uint16_t topicLength, ShadowMessageType_t *pMessageType, const char **pThingName, uint16_t *pThingNameLength)
 Given the topic string of an incoming message, determine whether it is related to an unnamed ("Classic") device shadow; if it is, return information about the type of device shadow message, and a pointers to the Thing Name inside of the topic string. See ShadowMessageType_t for the list of message types. Those types correspond to Device Shadow Topics. More...
 

Detailed Description

Implements the user-facing functions of the Shadow library.

Function Documentation

◆ validateMatchTopicParameters()

static ShadowStatus_t validateMatchTopicParameters ( const char *  pTopic,
uint16_t  topicLength,
const ShadowMessageType_t pMessageType 
)
static

Check if Shadow_MatchTopicString has valid parameters.

Parameters
[in]pTopicPointer to the topic string.
[in]topicLengthLength of pTopic.
[in]pMessageTypePointer to caller-supplied memory for returning the type of the shadow message.
Returns
Return SHADOW_SUCCESS if the parameters are valid; return SHADOW_BAD_PARAMETER if not.

◆ validateAssembleTopicParameters()

static ShadowStatus_t validateAssembleTopicParameters ( ShadowTopicStringType_t  topicType,
const char *  pThingName,
uint8_t  thingNameLength,
const char *  pShadowName,
uint8_t  shadowNameLength,
const char *  pTopicBuffer,
const uint16_t *  pOutLength 
)
static

Check if Shadow_AssembleTopicString has valid parameters.

Parameters
[in]topicTypeShadow topic type.
[in]pThingNameThing Name string.
[in]thingNameLengthLength of Thing Name string pointed to by pThingName.
[in]pShadowNameShadow Name string.
[in]shadowNameLengthLength of Shadow Name string pointed to by pShadowName.
[in]pTopicBufferPointer to the topic buffer.
[in]pOutLengthPointer to the length of the topic created.
Returns
Return SHADOW_SUCCESS if the parameters are valid; return SHADOW_BAD_PARAMETER if not.

◆ containsSubString()

static ShadowStatus_t containsSubString ( const char *  pString,
uint16_t  stringLength,
const char *  pSubString,
uint16_t  subStringLength 
)
static

Determine if the string contains the substring.

Parameters
[in]pStringPointer to the string.
[in]stringLengthLength of pString.
[in]pSubStringPointer to the substring.
[in]subStringLengthLength of pSubString.
Returns
Return SHADOW_SUCCESS if it contains; return SHADOW_FAIL if not.

◆ validateName()

static ShadowStatus_t validateName ( const char *  pString,
uint16_t  stringLength,
uint8_t  maxAllowedLength,
uint8_t *  pNameLength 
)
static

Check if the Thing or Shadow Name is valid.

Parameters
[in]pStringPointer to the starting of a name.
[in]stringLengthLength of pString.
[in]maxAllowedLengthMaximum allowed length of the Thing or Shadow name.
[out]pNameLengthPointer to caller-supplied memory for returning the length of the Thing or Shadow Name.
Returns
Return SHADOW_SUCCESS if it is valid; return SHADOW_FAIL if it is not.

◆ extractShadowMessageType()

static ShadowStatus_t extractShadowMessageType ( const char *  pString,
uint16_t  stringLength,
ShadowMessageType_t pMessageType 
)
static

Extract the Shadow message type from a string.

Parameters
[in]pStringPointer to the string.
[in]stringLengthLength of pString.
[out]pMessageTypePointer to caller-supplied memory for returning the type of the shadow message.
Returns
Return SHADOW_SUCCESS if successfully extracted; return SHADOW_MESSAGE_TYPE_PARSE_FAILED if failed.

◆ extractThingName()

static ShadowStatus_t extractThingName ( const char *  pTopic,
uint16_t  topicLength,
uint16_t *  pConsumedTopicLength,
uint8_t *  pThingNameLength 
)
static

Extract the Thing name from a topic string.

Parameters
[in]pTopicPointer to the topic string.
[in]topicLengthLength of pTopic.
[in,out]pConsumedTopicLengthPointer to caller-supplied memory for returning the consumed topic length.
[out]pThingNameLengthPointer to caller-supplied memory for returning the Thing name length.
Returns
Return SHADOW_SUCCESS if successfully extracted; return SHADOW_THINGNAME_PARSE_FAILED if Thing name parsing fails.

◆ extractShadowRootAndName()

static ShadowStatus_t extractShadowRootAndName ( const char *  pTopic,
uint16_t  topicLength,
uint16_t *  pConsumedTopicLength,
uint8_t *  pShadowNameLength 
)
static

Extract the classic shadow root OR the named shadow root and shadow name from a topic string.

Parameters
[in]pTopicPointer to the topic string.
[in]topicLengthLength of pTopic.
[in,out]pConsumedTopicLengthPointer to caller-supplied memory for returning the consumed topic length.
[out]pShadowNameLengthPointer to caller-supplied memory for returning the shadow name length.
Returns
Return SHADOW_SUCCESS if successfully extracted; return SHADOW_ROOT_PARSE_FAILED shadow root parsing fails. return SHADOW_SHADOWNAME_PARSE_FAILED shadow name parsing fails.

◆ getShadowOperationString()

static const char * getShadowOperationString ( ShadowTopicStringType_t  topicType)
static

Get the shadow operation string for a given shadow topic type.

Parameters
[in]topicTypeThe given shadow topic type.
Returns
The shadow operation string for the given shadow type.

◆ getShadowOperationLength()

static uint16_t getShadowOperationLength ( ShadowTopicStringType_t  topicType)
static

Get the shadow operation string length for a given shadow topic type.

Parameters
[in]topicTypeThe given shadow topic type.
Returns
The shadow operation string length for the given shadow type.

◆ createShadowTopicString()

static void createShadowTopicString ( ShadowTopicStringType_t  topicType,
const char *  pThingName,
uint8_t  thingNameLength,
const char *  pShadowName,
uint8_t  shadowNameLength,
char *  pTopicBuffer 
)
static

Creates a shadow topic string.

Parameters
[in]topicTypeThe type of shadow topic to be constructed.
[in]pThingNamePointer to the Thing name.
[in]thingNameLengthThe length of the Thing name.
[in]pShadowNamePointer to the Shadow name.
[in]shadowNameLengthThe length of the Shadow name.
[out]pTopicBufferPointer to caller-supplied memory for returning the constructed shadow topic string.

◆ Shadow_MatchTopicString()

ShadowStatus_t Shadow_MatchTopicString ( const char *  pTopic,
uint16_t  topicLength,
ShadowMessageType_t pMessageType,
const char **  pThingName,
uint8_t *  pThingNameLength,
const char **  pShadowName,
uint8_t *  pShadowNameLength 
)

Given the topic string of an incoming message, determine whether it is related to a device shadow; if it is, return information about the type of device shadow message, and pointers to the Thing Name and Shadow Name inside of the topic string. See ShadowMessageType_t for the list of message types. Those types correspond to Device Shadow Topics.

Note
When this function returns, the pointer pThingName points at the first character of the <thingName> segment inside of the topic string. Likewise, the pointer pShadowName points at the first character of the <shadowName> segment inside of the topic string (if the topic is for a named shadow, not the "Classic" shadow.) Caller is responsible for keeping the memory holding the topic string around while accessing the Thing Name through pThingName and the Shadow Name through pShadowName.
Parameters
[in]pTopicPointer to the MQTT topic string. Does not have to be null-terminated.
[in]topicLengthLength of the MQTT topic string.
[out]pMessageTypePointer to caller-supplied memory for returning the type of the shadow message.
[out]pThingNamePoints to the 1st character of Thing Name inside of the topic string, and can be null if caller does not need to know the Thing Name contained in the topic string.
[out]pThingNameLengthPointer to caller-supplied memory for returning the length of the Thing Name, and can be null if caller does not need to know the Thing Name contained in the topic string.
[out]pShadowNamePoints to the 1st character of Shadow Name inside of the topic string, and can be null if caller does not need to know the Shadow Name contained in the topic string. Null is returned if the shadow is Classic.
[out]pShadowNameLengthPointer to caller-supplied memory for returning the length of the Shadow Name, and can be null if caller does not need to know the Shadow Name contained in the topic string. A value of 0 is returned if the shadow is Classic.
Returns
One of the following:
  • SHADOW_SUCCESS if the message is related to a device shadow;
  • An error code defined in ShadowStatus_t if the message is not related to a device shadow, if any input parameter is invalid, or if the function fails to parse the topic string.

Example

// Variables used in this example.
#define SHADOW_TOPIC_MAX_LENGTH ( 256U )
ShadowStatus_te shadowStatus = SHADOW_SUCCESS;
char * pTopicName; //usually supplied by MQTT stack
uint16_t topicNameLength; //usually supplied by MQTT stack
ShadowMessageType_t messageType;
shadowStatus = Shadow_MatchTopicString( pTopicName,
topicNameLength,
&messageType,
NULL,
NULL,
NULL,
NULL );
if( shadowStatus == SHADOW_SUCCESS )
{
// It is a device shadow message. And the type of the message has been returned in messageType.
// Now we can act on the message.
}
ShadowMessageType_t
Each of these values describes the type of a shadow message. https://docs.aws.amazon....
Definition: shadow.h:62
@ SHADOW_SUCCESS
Shadow function success.
Definition: shadow.h:103
ShadowStatus_t Shadow_MatchTopicString(const char *pTopic, uint16_t topicLength, ShadowMessageType_t *pMessageType, const char **pThingName, uint8_t *pThingNameLength, const char **pShadowName, uint8_t *pShadowNameLength)
Given the topic string of an incoming message, determine whether it is related to a device shadow; if...
Definition: shadow.c:766

◆ Shadow_AssembleTopicString()

ShadowStatus_t Shadow_AssembleTopicString ( ShadowTopicStringType_t  topicType,
const char *  pThingName,
uint8_t  thingNameLength,
const char *  pShadowName,
uint8_t  shadowNameLength,
char *  pTopicBuffer,
uint16_t  bufferSize,
uint16_t *  pOutLength 
)

Assemble shadow topic string when Thing Name or Shadow Name is only known at run time. If both the Thing Name and Shadow Name are known at compile time, use SHADOW_TOPIC_STR_* macros instead.

Parameters
[in]topicTypeIndicates what topic will be written into the buffer pointed to by pTopicBuffer. can be one of:
  • ShadowTopicStringTypeGet
  • ShadowTopicStringTypeGetAccepted
  • ShadowTopicStringTypeGetRejected
  • ShadowTopicStringTypeDelete
  • ShadowTopicStringTypeDeleteAccepted
  • ShadowTopicStringTypeDeleteRejected
  • ShadowTopicStringTypeUpdate
  • ShadowTopicStringTypeUpdateAccepted
  • ShadowTopicStringTypeUpdateRejected
  • ShadowTopicStringTypeUpdateDocuments
  • ShadowTopicStringTypeUpdateDelta
[in]pThingNameThing Name string. No need to be null terminated. Must not be NULL.
[in]thingNameLengthLength of Thing Name string pointed to by pThingName. Must not be zero.
[in]pShadowNameShadow Name string. No need to be null terminated. Must not be NULL. Empty string for classic shadow.
[in]shadowNameLengthLength of Shadow Name string pointed to by pShadowName. Zero for classic shadow.
[out]pTopicBufferPointer to buffer for returning the topic string. Caller is responsible for supplying memory pointed to by pTopicBuffer. This function does not fill in the terminating null character. The app can supply a buffer that does not have space for holding the null character.
[in]bufferSizeLength of pTopicBuffer. This function will return error if bufferSize is less than the length of the assembled topic string.
[out]pOutLengthPointer to caller-supplied memory for returning the length of the topic string.
Returns
One of the following:
  • SHADOW_SUCCESS if successful.
  • An error code if failed to assemble.

Example

// Variables used in this example.
#define SHADOW_TOPIC_MAX_LENGTH ( 256U )
char topicBuffer[ SHADOW_TOPIC_MAX_LENGTH ] = { 0 };
uint16_t bufferSize = SHADOW_TOPIC_MAX_LENGTH;
uint16_t outLength = 0;
const char thingName[] = "TestThingName";
uint16_t thingNameLength = ( sizeof( thingName ) - 1U );
const char shadowName[] = "TestShadowName";
uint16_t shadowNameLength = ( sizeof( shadowName ) - 1U );
shadowStatus = Shadow_AssembleTopicString( ShadowTopicStringTypeUpdateDelta,
thingName,
thingNameLength,
shadowName,
shadowNameLength,
& ( topicBuffer[ 0 ] ),
bufferSize,
& outLength );
if( shadowStatus == SHADOW_SUCCESS )
{
// The assembled topic string is put in pTopicBuffer with the length outLength.
}
ShadowStatus_t
Return codes from Shadow functions.
Definition: shadow.h:102
ShadowStatus_t Shadow_AssembleTopicString(ShadowTopicStringType_t topicType, const char *pThingName, uint8_t thingNameLength, const char *pShadowName, uint8_t shadowNameLength, char *pTopicBuffer, uint16_t bufferSize, uint16_t *pOutLength)
Assemble shadow topic string when Thing Name or Shadow Name is only known at run time....
Definition: shadow.c:875

◆ Shadow_MatchTopic()

ShadowStatus_t Shadow_MatchTopic ( const char *  pTopic,
uint16_t  topicLength,
ShadowMessageType_t pMessageType,
const char **  pThingName,
uint16_t *  pThingNameLength 
)

Given the topic string of an incoming message, determine whether it is related to an unnamed ("Classic") device shadow; if it is, return information about the type of device shadow message, and a pointers to the Thing Name inside of the topic string. See ShadowMessageType_t for the list of message types. Those types correspond to Device Shadow Topics.

Deprecated:
Please use Shadow_MatchTopicString in new designs.

See Shadow_MatchTopicString for documentation of common behavior.