AWS IoT Device Defender v1.0.0
AWS IoT Device Defender Client Library
defender.c File Reference

Implementation of the AWS IoT Device Defender Client Library. More...

#include <assert.h>
#include <stddef.h>
#include <string.h>
#include "defender.h"

Functions

static uint16_t getTopicLength (uint16_t thingNameLength, DefenderTopic_t api)
 Get the topic length for a given defender API. More...
 
static void writeFormatAndSuffix (char *pBuffer, DefenderTopic_t api)
 Write the format and suffix part for the given defender API to the buffer. More...
 
static DefenderStatus_t matchPrefix (const char *pRemainingTopic, uint16_t remainingTopicLength)
 Check if the unparsed topic so far starts with the defender prefix. More...
 
static DefenderStatus_t extractThingNameLength (const char *pRemainingTopic, uint16_t remainingTopicLength, uint16_t *pOutThingNameLength)
 Extract the length of thing name in the unparsed topic so far. More...
 
static DefenderStatus_t matchBridge (const char *pRemainingTopic, uint16_t remainingTopicLength)
 Check if the unparsed topic so far starts with the defender bridge. More...
 
static DefenderStatus_t matchApi (const char *pRemainingTopic, uint16_t remainingTopicLength, DefenderTopic_t *pOutApi)
 Check if the unparsed topic so far exactly matches one of the defender api topics. More...
 
DefenderStatus_t Defender_GetTopic (char *pBuffer, uint16_t bufferLength, const char *pThingName, uint16_t thingNameLength, DefenderTopic_t api, uint16_t *pOutLength)
 Populate the topic string for a Device Defender operation. More...
 
DefenderStatus_t Defender_MatchTopic (const char *pTopic, uint16_t topicLength, DefenderTopic_t *pOutApi, const char **ppOutThingName, uint16_t *pOutThingNameLength)
 Check if the given topic is one of the Device Defender topics. More...
 

Detailed Description

Implementation of the AWS IoT Device Defender Client Library.

Function Documentation

◆ getTopicLength()

static uint16_t getTopicLength ( uint16_t  thingNameLength,
DefenderTopic_t  api 
)
static

Get the topic length for a given defender API.

Parameters
[in]thingNameLengthThe length of the thing name as registered with AWS IoT.
[in]apiThe defender API value.
Returns
The topic length for the given defender API.

◆ writeFormatAndSuffix()

static void writeFormatAndSuffix ( char *  pBuffer,
DefenderTopic_t  api 
)
static

Write the format and suffix part for the given defender API to the buffer.

Format: json or cbor. Suffix: /accepted or /rejected or empty.

Parameters
[in]pBufferThe buffer to write the format and suffix part into.
[in]apiThe defender API value.
Note
This function assumes that the buffer is large enough to hold the value.

◆ matchPrefix()

static DefenderStatus_t matchPrefix ( const char *  pRemainingTopic,
uint16_t  remainingTopicLength 
)
static

Check if the unparsed topic so far starts with the defender prefix.

The defender prefix is "$aws/things/".

Parameters
[in]pRemainingTopicStarting location of the unparsed topic.
[in]remainingTopicLengthThe length of the unparsed topic.
Returns
DefenderSuccess if the unparsed topic starts with the defender prefix; DefenderNoMatch otherwise.

◆ extractThingNameLength()

static DefenderStatus_t extractThingNameLength ( const char *  pRemainingTopic,
uint16_t  remainingTopicLength,
uint16_t *  pOutThingNameLength 
)
static

Extract the length of thing name in the unparsed topic so far.

The end of thing name is marked by a forward slash. A zero length thing name is not valid.

This function extracts the same thing name from the following topic strings:

  • $aws/things/THING_NAME/defender/metrics/json
  • $aws/things/THING_NAME The second topic is not a valid defender topic and the matching will fail when we try to match the bridge part.
Parameters
[in]pRemainingTopicStarting location of the unparsed topic.
[in]remainingTopicLengthThe length of the unparsed topic.
[out]pOutThingNameLengthThe length of the thing name in the topic string.
Returns
DefenderSuccess if a valid thing name is found; DefenderNoMatch otherwise.

◆ matchBridge()

static DefenderStatus_t matchBridge ( const char *  pRemainingTopic,
uint16_t  remainingTopicLength 
)
static

Check if the unparsed topic so far starts with the defender bridge.

The defender bridge is "/defender/metrics/".

Parameters
[in]pRemainingTopicStarting location of the unparsed topic.
[in]remainingTopicLengthThe length of the unparsed topic.
Returns
DefenderSuccess if the unparsed topic starts with the defender bridge; DefenderNoMatch otherwise.

◆ matchApi()

static DefenderStatus_t matchApi ( const char *  pRemainingTopic,
uint16_t  remainingTopicLength,
DefenderTopic_t pOutApi 
)
static

Check if the unparsed topic so far exactly matches one of the defender api topics.

The defender api topics are the following:

  • json
  • json/accepted
  • json/rejected
  • cbor
  • cbor/accepted
  • cbor/rejected

The function also outputs the defender API value if a match is found.

Parameters
[in]pRemainingTopicStarting location of the unparsed topic.
[in]remainingTopicLengthThe length of the unparsed topic.
[out]pOutApiThe defender topic API value.
Returns
DefenderSuccess if the unparsed topic exactly matches one of the defender api topics; DefenderNoMatch otherwise.

◆ Defender_GetTopic()

DefenderStatus_t Defender_GetTopic ( char *  pBuffer,
uint16_t  bufferLength,
const char *  pThingName,
uint16_t  thingNameLength,
DefenderTopic_t  api,
uint16_t *  pOutLength 
)

Populate the topic string for a Device Defender operation.

Parameters
[in]pBufferThe buffer to write the topic string into.
[in]bufferLengthThe length of the buffer.
[in]pThingNameThe device's thingName as registered with AWS IoT.
[in]thingNameLengthThe length of the thing name.
[in]apiThe desired Device Defender API.
[out]pOutLengthThe length of the topic string written to the buffer.
Returns
DefenderSuccess if the topic string is written to the buffer; DefenderBadParameter if invalid parameters are passed; DefenderBufferTooSmall if the buffer cannot hold the full topic string.

Example

// The following example shows how to use the Defender_GetTopic API to
// generate a topic string for getting a JSON report accepted response.
#define TOPIC_BUFFER_LENGTH ( 256U )
// Every device should have a unique thing name registered with AWS IoT Core.
// This example assumes that the device has a unique serial number which is
// registered as the thing name with AWS IoT Core.
const char * pThingName = GetDeviceSerialNumber();
uint16_t thingNameLength = ( uint16_t )strlen( pThingname );
char topicBuffer[ TOPIC_BUFFER_LENGTH ] = { 0 };
uint16_t topicLength = 0;
status = Defender_GetTopic( &( topicBuffer[ 0 ] ),
TOPIC_BUFFER_LENGTH,
pThingName,
thingNameLength,
&( topicLength ) );
if( status == DefenderSuccess )
{
// The buffer topicBuffer contains the topic string of length
// topicLength for getting a JSON report accepted response. Subscribe
// to this topic using an MQTT client of your choice.
}
DefenderStatus_t Defender_GetTopic(char *pBuffer, uint16_t bufferLength, const char *pThingName, uint16_t thingNameLength, DefenderTopic_t api, uint16_t *pOutLength)
Populate the topic string for a Device Defender operation.
Definition: defender.c:381
DefenderStatus_t
Return codes from defender APIs.
Definition: defender.h:50
@ DefenderSuccess
Definition: defender.h:52
@ DefenderJsonReportAccepted
Definition: defender.h:66

◆ Defender_MatchTopic()

DefenderStatus_t Defender_MatchTopic ( const char *  pTopic,
uint16_t  topicLength,
DefenderTopic_t pOutApi,
const char **  ppOutThingName,
uint16_t *  pOutThingNameLength 
)

Check if the given topic is one of the Device Defender topics.

The function outputs which API the topic is for. It also optionally outputs the starting location and length of the thing name in the given topic.

Parameters
[in]pTopicThe topic string to check.
[in]topicLengthThe length of the topic string.
[out]pOutApiThe defender topic API value.
[out]ppOutThingNameOptional parameter to output the beginning of the thing name in the topic string. Pass NULL if not needed.
[out]pOutThingNameLengthOptional parameter to output the length of the thing name in the topic string. Pass NULL if not needed.
Returns
DefenderSuccess if the topic is one of the defender topics; DefenderBadParameter if invalid parameters are passed; DefenderNoMatch if the topic is NOT one of the defender topics (parameter pOutApi gets DefenderInvalidTopic).

Example

// The following example shows how to use the Defender_MatchTopic API to
// check if an incoming MQTT publish message is a Device Defender message.
// pTopic and topicLength are the topic string and length of the topic on
// which the publish message is received. These are usually provided by the
// MQTT client used. We pass the last two argument as NULL as we are not
// interested in the thing name in the topic string.
status = Defender_MatchTopic( pTopic,
topicLength,
&( api ),
NULL,
NULL );
if( status == DefenderSuccess )
{
{
// The published JSON report was accepted by the AWS IoT Device
// Defender service. You can parse the response using your choice
// of JSON parser and ensure that the report Id is same as was sent
// in the defender report.
}
else if( api == DefenderJsonReportRejected )
{
// The published JSON report was rejected by the AWS IoT Device
// Defender service.
}
else
{
// Unexpected response.
}
}
DefenderStatus_t Defender_MatchTopic(const char *pTopic, uint16_t topicLength, DefenderTopic_t *pOutApi, const char **ppOutThingName, uint16_t *pOutThingNameLength)
Check if the given topic is one of the Device Defender topics.
Definition: defender.c:462
DefenderTopic_t
Topic values for subscription requests.
Definition: defender.h:63
@ DefenderJsonReportRejected
Definition: defender.h:67