/* * AWS IoT Device Defender Client v1.1.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 defender.h * @brief Interface for the AWS IoT Device Defender Client Library. */ #ifndef DEFENDER_H_ #define DEFENDER_H_ /* Standard includes. */ #include /* DEFENDER_DO_NOT_USE_CUSTOM_CONFIG allows building the Device Defender library * without a config file. If a config file is provided, DEFENDER_DO_NOT_USE_CUSTOM_CONFIG * macro must not be defined. */ #ifndef DEFENDER_DO_NOT_USE_CUSTOM_CONFIG #include "defender_config.h" #endif /* Default config values. */ #include "defender_config_defaults.h" /** * @ingroup defender_enum_types * @brief Return codes from defender APIs. */ typedef enum { DefenderError = 0, /**< Generic Error. */ DefenderSuccess, /**< Success. */ DefenderNoMatch, /**< The provided topic does not match any defender topic. */ DefenderBadParameter, /**< Invalid parameters were passed. */ DefenderBufferTooSmall /**< The output buffer is too small. */ } DefenderStatus_t; /** * @ingroup defender_enum_types * @brief Topic values for subscription requests. */ typedef enum { DefenderInvalidTopic = -1, /**< Invalid topic. */ DefenderJsonReportPublish, /**< Topic for publishing a JSON report. */ DefenderJsonReportAccepted, /**< Topic for getting a JSON report accepted response. */ DefenderJsonReportRejected, /**< Topic for getting a JSON report rejected response. */ DefenderCborReportPublish, /**< Topic for publishing a CBOR report. */ DefenderCborReportAccepted, /**< Topic for getting a CBOR report accepted response. */ DefenderCborReportRejected, /**< Topic for getting a CBOR report rejected response. */ DefenderMaxTopic } DefenderTopic_t; /*-----------------------------------------------------------*/ /** * @brief Helper macro to calculate the length of a string literal. */ #define STRING_LITERAL_LENGTH( literal ) ( ( uint16_t ) ( sizeof( literal ) - 1U ) ) /*-----------------------------------------------------------*/ /** * @ingroup defender_constants * @brief Maximum length of a thing's name as permitted by AWS IoT Core. */ #define DEFENDER_THINGNAME_MAX_LENGTH 128U /** * @ingroup defender_constants * @brief Minimum period between 2 consecutive defender reports sent by the * device. * * This is as per AWS IoT Device Defender Service reference. */ #define DEFENDER_REPORT_MIN_PERIOD_SECONDS 300 /*-----------------------------------------------------------*/ /* * A Defender topic has the following format: * * * * Where: * = $aws/things/ * = Name of the thing. * = /defender/metrics/ * = json or cbor * = /accepted or /rejected or empty * * Examples: * $aws/things/THING_NAME/defender/metrics/json * $aws/things/THING_NAME/defender/metrics/json/accepted * $aws/things/THING_NAME/defender/metrics/json/rejected * $aws/things/THING_NAME/defender/metrics/cbor * $aws/things/THING_NAME/defender/metrics/cbor/accepted * $aws/things/THING_NAME/defender/metrics/json/rejected */ /** * @cond DOXYGEN_IGNORE * Doxygen should ignore these macros as they are private. */ #define DEFENDER_API_PREFIX "$aws/things/" #define DEFENDER_API_LENGTH_PREFIX STRING_LITERAL_LENGTH( DEFENDER_API_PREFIX ) #define DEFENDER_API_BRIDGE "/defender/metrics/" #define DEFENDER_API_LENGTH_BRIDGE STRING_LITERAL_LENGTH( DEFENDER_API_BRIDGE ) #define DEFENDER_API_JSON_FORMAT "json" #define DEFENDER_API_LENGTH_JSON_FORMAT STRING_LITERAL_LENGTH( DEFENDER_API_JSON_FORMAT ) #define DEFENDER_API_CBOR_FORMAT "cbor" #define DEFENDER_API_LENGTH_CBOR_FORMAT STRING_LITERAL_LENGTH( DEFENDER_API_CBOR_FORMAT ) #define DEFENDER_API_ACCEPTED_SUFFIX "/accepted" #define DEFENDER_API_LENGTH_ACCEPTED_SUFFIX STRING_LITERAL_LENGTH( DEFENDER_API_ACCEPTED_SUFFIX ) #define DEFENDER_API_REJECTED_SUFFIX "/rejected" #define DEFENDER_API_LENGTH_REJECTED_SUFFIX STRING_LITERAL_LENGTH( DEFENDER_API_REJECTED_SUFFIX ) #define DEFENDER_API_NULL_SUFFIX "" #define DEFENDER_API_LENGTH_NULL_SUFFIX ( 0U ) /** @endcond */ /*-----------------------------------------------------------*/ /** * @cond DOXYGEN_IGNORE * Doxygen should ignore this macro as it is private. */ /* Defender API topic lengths. */ #define DEFENDER_API_COMMON_LENGTH( thingNameLength, reportFormatLength, suffixLength ) \ ( DEFENDER_API_LENGTH_PREFIX + \ ( thingNameLength ) + \ DEFENDER_API_LENGTH_BRIDGE + \ ( reportFormatLength ) + \ ( suffixLength ) ) /** @endcond */ /** * @brief Length of the topic string for publishing a JSON report. * * @param[in] thingNameLength Length of the thing name as registered with AWS IoT Core. */ #define DEFENDER_API_LENGTH_JSON_PUBLISH( thingNameLength ) \ DEFENDER_API_COMMON_LENGTH( thingNameLength, \ DEFENDER_API_LENGTH_JSON_FORMAT, \ DEFENDER_API_LENGTH_NULL_SUFFIX ) /** * @brief Length of the topic string for getting a JSON report accepted response. * * @param[in] thingNameLength Length of the thing name as registered with AWS IoT Core. */ #define DEFENDER_API_LENGTH_JSON_ACCEPTED( thingNameLength ) \ DEFENDER_API_COMMON_LENGTH( thingNameLength, \ DEFENDER_API_LENGTH_JSON_FORMAT, \ DEFENDER_API_LENGTH_ACCEPTED_SUFFIX ) /** * @brief Length of the topic string for getting a JSON report rejected response. * * @param[in] thingNameLength Length of the thing name as registered with AWS IoT Core. */ #define DEFENDER_API_LENGTH_JSON_REJECTED( thingNameLength ) \ DEFENDER_API_COMMON_LENGTH( thingNameLength, \ DEFENDER_API_LENGTH_JSON_FORMAT, \ DEFENDER_API_LENGTH_REJECTED_SUFFIX ) /** * @brief Length of the topic string for publishing a CBOR report. * * @param[in] thingNameLength Length of the thing name as registered with AWS IoT Core. */ #define DEFENDER_API_LENGTH_CBOR_PUBLISH( thingNameLength ) \ DEFENDER_API_COMMON_LENGTH( thingNameLength, \ DEFENDER_API_LENGTH_CBOR_FORMAT, \ DEFENDER_API_LENGTH_NULL_SUFFIX ) /** * @brief Length of the topic string for getting a CBOR report accepted response. * * @param[in] thingNameLength Length of the thing name. as registered with AWS IoT Core. */ #define DEFENDER_API_LENGTH_CBOR_ACCEPTED( thingNameLength ) \ DEFENDER_API_COMMON_LENGTH( thingNameLength, \ DEFENDER_API_LENGTH_CBOR_FORMAT, \ DEFENDER_API_LENGTH_ACCEPTED_SUFFIX ) /** * @brief Length of the topic string for getting a CBOR report rejected response. * * @param[in] thingNameLength Length of the thing name as registered with AWS IoT Core. */ #define DEFENDER_API_LENGTH_CBOR_REJECTED( thingNameLength ) \ DEFENDER_API_COMMON_LENGTH( thingNameLength, \ DEFENDER_API_LENGTH_CBOR_FORMAT, \ DEFENDER_API_LENGTH_REJECTED_SUFFIX ) /** * @brief Maximum length of the topic string for any defender operation. * * @param[in] thingNameLength Length of the thing name as registered with AWS IoT Core. */ #define DEFENDER_API_MAX_LENGTH( thingNameLength ) \ DEFENDER_API_LENGTH_CBOR_ACCEPTED( thingNameLength ) /*-----------------------------------------------------------*/ /** * @cond DOXYGEN_IGNORE * Doxygen should ignore this macro as it is private. */ /* Defender API topics. */ #define DEFENDER_API_COMMON( thingName, reportFormat, suffix ) \ ( DEFENDER_API_PREFIX \ thingName \ DEFENDER_API_BRIDGE \ reportFormat \ suffix ) /** @endcond */ /** * @brief Topic string for publishing a JSON report. * * This macro should be used when the thing name is known at the compile time. * If the thing name is not known at compile time, the #Defender_GetTopic API * should be used instead. * * @param thingName The thing name as registered with AWS IoT Core. */ #define DEFENDER_API_JSON_PUBLISH( thingName ) \ DEFENDER_API_COMMON( thingName, \ DEFENDER_API_JSON_FORMAT, \ DEFENDER_API_NULL_SUFFIX ) /** * @brief Topic string for getting a JSON report accepted response. * * This macro should be used when the thing name is known at the compile time. * If the thing name is not known at compile time, the #Defender_GetTopic API * should be used instead. * * @param thingName The thing name as registered with AWS IoT Core. */ #define DEFENDER_API_JSON_ACCEPTED( thingName ) \ DEFENDER_API_COMMON( thingName, \ DEFENDER_API_JSON_FORMAT, \ DEFENDER_API_ACCEPTED_SUFFIX ) /** * @brief Topic string for getting a JSON report rejected response. * * This macro should be used when the thing name is known at the compile time. * If the thing name is not known at compile time, the #Defender_GetTopic API * should be used instead. * * @param thingName The thing name as registered with AWS IoT Core. */ #define DEFENDER_API_JSON_REJECTED( thingName ) \ DEFENDER_API_COMMON( thingName, \ DEFENDER_API_JSON_FORMAT, \ DEFENDER_API_REJECTED_SUFFIX ) /** * @brief Topic string for publishing a CBOR report. * * This macro should be used when the thing name is known at the compile time. * If the thing name is not known at compile time, the #Defender_GetTopic API * should be used instead. * * @param thingName The thing name as registered with AWS IoT Core. */ #define DEFENDER_API_CBOR_PUBLISH( thingName ) \ DEFENDER_API_COMMON( thingName, \ DEFENDER_API_CBOR_FORMAT, \ DEFENDER_API_NULL_SUFFIX ) /** * @brief Topic string for getting a CBOR report accepted response. * * This macro should be used when the thing name is known at the compile time. * If the thing name is not known at compile time, the #Defender_GetTopic API * should be used instead. * * @param thingName The thing name as registered with AWS IoT Core. */ #define DEFENDER_API_CBOR_ACCEPTED( thingName ) \ DEFENDER_API_COMMON( thingName, \ DEFENDER_API_CBOR_FORMAT, \ DEFENDER_API_ACCEPTED_SUFFIX ) /** * @brief Topic string for getting a CBOR report rejected response. * * This macro should be used when the thing name is known at the compile time. * If the thing name is not known at compile time, the #Defender_GetTopic API * should be used instead. * * @param thingName The thing name as registered with AWS IoT Core. */ #define DEFENDER_API_CBOR_REJECTED( thingName ) \ DEFENDER_API_COMMON( thingName, \ DEFENDER_API_CBOR_FORMAT, \ DEFENDER_API_REJECTED_SUFFIX ) /*-----------------------------------------------------------*/ /** * @cond DOXYGEN_IGNORE * Doxygen should ignore this macro as it is private. */ /* Keys used in defender report. */ #if ( defined( DEFENDER_USE_LONG_KEYS ) && ( DEFENDER_USE_LONG_KEYS == 1 ) ) #define DEFENDER_REPORT_SELECT_KEY( longKey, shortKey ) ( longKey ) #else #define DEFENDER_REPORT_SELECT_KEY( longKey, shortKey ) ( shortKey ) #endif /** @endcond */ /** * @ingroup defender_constants * @brief "header" key in the defender report. */ #define DEFENDER_REPORT_HEADER_KEY DEFENDER_REPORT_SELECT_KEY( "header", "hed" ) /** * @ingroup defender_constants * @brief Length of the "header" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_HEADER_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_HEADER_KEY ) /** * @ingroup defender_constants * @brief "metrics" key in the defender report. */ #define DEFENDER_REPORT_METRICS_KEY DEFENDER_REPORT_SELECT_KEY( "metrics", "met" ) /** * @ingroup defender_constants * @brief Length of the "metrics" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_METRICS_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_METRICS_KEY ) /** * @ingroup defender_constants * @brief "report_id" key in the defender report. */ #define DEFENDER_REPORT_ID_KEY DEFENDER_REPORT_SELECT_KEY( "report_id", "rid" ) /** * @ingroup defender_constants * @brief Length of the "report_id" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_ID_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_ID_KEY ) /** * @ingroup defender_constants * @brief "version" key in the defender report. */ #define DEFENDER_REPORT_VERSION_KEY DEFENDER_REPORT_SELECT_KEY( "version", "v" ) /** * @ingroup defender_constants * @brief Length of the "version" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_VERSION_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_VERSION_KEY ) /** * @ingroup defender_constants * @brief "tcp_connections" key in the defender report. */ #define DEFENDER_REPORT_TCP_CONNECTIONS_KEY DEFENDER_REPORT_SELECT_KEY( "tcp_connections", "tc" ) /** * @ingroup defender_constants * @brief Length of the "tcp_connections" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_TCP_CONNECTIONS_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_TCP_CONNECTIONS_KEY ) /** * @ingroup defender_constants * @brief "established_connections" key in the defender report. */ #define DEFENDER_REPORT_ESTABLISHED_CONNECTIONS_KEY DEFENDER_REPORT_SELECT_KEY( "established_connections", "ec" ) /** * @ingroup defender_constants * @brief Length of the "established_connections" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_ESTABLISHED_CONNECTIONS_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_ESTABLISHED_CONNECTIONS_KEY ) /** * @ingroup defender_constants * @brief "connections" key in the defender report. */ #define DEFENDER_REPORT_CONNECTIONS_KEY DEFENDER_REPORT_SELECT_KEY( "connections", "cs" ) /** * @ingroup defender_constants * @brief Length of the "connections" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_CONNECTIONS_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_CONNECTIONS_KEY ) /** * @ingroup defender_constants * @brief "remote_addr" key in the defender report. */ #define DEFENDER_REPORT_REMOTE_ADDR_KEY DEFENDER_REPORT_SELECT_KEY( "remote_addr", "rad" ) /** * @ingroup defender_constants * @brief Length of the "remote_addr" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_REMOTE_ADDR_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_REMOTE_ADDR_KEY ) /** * @ingroup defender_constants * @brief "local_port" key in the defender report. */ #define DEFENDER_REPORT_LOCAL_PORT_KEY DEFENDER_REPORT_SELECT_KEY( "local_port", "lp" ) /** * @ingroup defender_constants * @brief Length of the "local_port" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_LOCAL_PORT_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_LOCAL_PORT_KEY ) /** * @ingroup defender_constants * @brief "local_interface" key in the defender report. */ #define DEFENDER_REPORT_LOCAL_INTERFACE_KEY DEFENDER_REPORT_SELECT_KEY( "local_interface", "li" ) /** * @ingroup defender_constants * @brief Length of the "local_interface" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_LOCAL_INTERFACE_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_LOCAL_INTERFACE_KEY ) /** * @ingroup defender_constants * @brief "total" key in the defender report. */ #define DEFENDER_REPORT_TOTAL_KEY DEFENDER_REPORT_SELECT_KEY( "total", "t" ) /** * @ingroup defender_constants * @brief Length of the "total" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_TOTAL_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_TOTAL_KEY ) /** * @ingroup defender_constants * @brief "listening_tcp_ports" key in the defender report. */ #define DEFENDER_REPORT_TCP_LISTENING_PORTS_KEY DEFENDER_REPORT_SELECT_KEY( "listening_tcp_ports", "tp" ) /** * @ingroup defender_constants * @brief Length of the "listening_tcp_ports" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_TCP_LISTENING_PORTS_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_TCP_LISTENING_PORTS_KEY ) /** * @ingroup defender_constants * @brief "ports" key in the defender report. */ #define DEFENDER_REPORT_PORTS_KEY DEFENDER_REPORT_SELECT_KEY( "ports", "pts" ) /** * @ingroup defender_constants * @brief Length of the "ports" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_PORTS_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_PORTS_KEY ) /** * @ingroup defender_constants * @brief "port" key in the defender report. */ #define DEFENDER_REPORT_PORT_KEY DEFENDER_REPORT_SELECT_KEY( "port", "pt" ) /** * @ingroup defender_constants * @brief Length of the "port" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_PORT_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_PORT_KEY ) /** * @ingroup defender_constants * @brief "interface" key in the defender report. */ #define DEFENDER_REPORT_INTERFACE_KEY DEFENDER_REPORT_SELECT_KEY( "interface", "if" ) /** * @ingroup defender_constants * @brief Length of the "interface" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_INTERFACE_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_INTERFACE_KEY ) /** * @ingroup defender_constants * @brief "listening_udp_ports" key in the defender report. */ #define DEFENDER_REPORT_UDP_LISTENING_PORTS_KEY DEFENDER_REPORT_SELECT_KEY( "listening_udp_ports", "up" ) /** * @ingroup defender_constants * @brief Length of the "listening_udp_ports" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_UDP_LISTENING_PORTS_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_UDP_LISTENING_PORTS_KEY ) /** * @ingroup defender_constants * @brief "network_stats" key in the defender report. */ #define DEFENDER_REPORT_NETWORK_STATS_KEY DEFENDER_REPORT_SELECT_KEY( "network_stats", "ns" ) /** * @ingroup defender_constants * @brief Length of the "network_stats" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_NETWORK_STATS_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_NETWORK_STATS_KEY ) /** * @ingroup defender_constants * @brief "bytes_in" key in the defender report. */ #define DEFENDER_REPORT_BYTES_IN_KEY DEFENDER_REPORT_SELECT_KEY( "bytes_in", "bi" ) /** * @ingroup defender_constants * @brief Length of the "bytes_in" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_BYTES_IN_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_BYTES_IN_KEY ) /** * @ingroup defender_constants * @brief "bytes_out" key in the defender report. */ #define DEFENDER_REPORT_BYTES_OUT_KEY DEFENDER_REPORT_SELECT_KEY( "bytes_out", "bo" ) /** * @ingroup defender_constants * @brief Length of the "bytes_out" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_BYTES_OUT_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_BYTES_OUT_KEY ) /** * @ingroup defender_constants * @brief "packets_in" key in the defender report. */ #define DEFENDER_REPORT_PKTS_IN_KEY DEFENDER_REPORT_SELECT_KEY( "packets_in", "pi" ) /** * @ingroup defender_constants * @brief Length of the "packets_in" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_PKTS_IN_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_PKTS_IN_KEY ) /** * @ingroup defender_constants * @brief "packets_out" key in the defender report. */ #define DEFENDER_REPORT_PKTS_OUT_KEY DEFENDER_REPORT_SELECT_KEY( "packets_out", "po" ) /** * @ingroup defender_constants * @brief Length of the "packets_out" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_PKS_OUT_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_LENGTH_PKS_OUT_KEY ) /** * @ingroup defender_constants * @brief "custom_metrics" key in the defender report. */ #define DEFENDER_REPORT_CUSTOM_METRICS_KEY DEFENDER_REPORT_SELECT_KEY( "custom_metrics", "cmet" ) /** * @ingroup defender_constants * @brief Length of the "custom_metrics" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_CUSTOM_METRICS_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_LENGTH_CUSTOM_METRICS_KEY ) /** * @ingroup defender_constants * @brief "number" key in the defender report. */ #define DEFENDER_REPORT_NUMBER_KEY "number" /** * @ingroup defender_constants * @brief Length of the "number" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_NUMBER_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_LENGTH_NUMBER_KEY ) /** * @ingroup defender_constants * @brief "number_list" key in the defender report. */ #define DEFENDER_REPORT_NUMBER_LIST_KEY "number_list" /** * @ingroup defender_constants * @brief Length of the "number_list" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_NUMBER_LIST_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_LENGTH_NUMBER_LIST_KEY ) /** * @ingroup defender_constants * @brief "string_list" key in the defender report. */ #define DEFENDER_REPORT_STRING_LIST_KEY "string_list" /** * @ingroup defender_constants * @brief Length of the "string_list" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_STRING_LIST_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_LENGTH_STRING_LIST_KEY ) /** * @ingroup defender_constants * @brief "ip_list" key in the defender report. */ #define DEFENDER_REPORT_IP_LIST_KEY "ip_list" /** * @ingroup defender_constants * @brief Length of the "ip_list" key in the defender report. */ #define DEFENDER_REPORT_LENGTH_IP_LIST_KEY STRING_LITERAL_LENGTH( DEFENDER_REPORT_LENGTH_IP_LIST_KEY ) /*-----------------------------------------------------------*/ /** * @brief Populate the topic string for a Device Defender operation. * * @param[in] pBuffer The buffer to write the topic string into. * @param[in] bufferLength The length of the buffer. * @param[in] pThingName The device's thingName as registered with AWS IoT. * @param[in] thingNameLength The length of the thing name. * @param[in] api The desired Device Defender API. * @param[out] pOutLength The length of the topic string written to the buffer. * * @return #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 * @code{c} * * // 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; * DefenderStatus_t status = DefenderSuccess; * * status = Defender_GetTopic( &( topicBuffer[ 0 ] ), * TOPIC_BUFFER_LENGTH, * pThingName, * thingNameLength, * DefenderJsonReportAccepted, * &( 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. * } * @endcode */ /* @[declare_defender_gettopic] */ DefenderStatus_t Defender_GetTopic( char * pBuffer, uint16_t bufferLength, const char * pThingName, uint16_t thingNameLength, DefenderTopic_t api, uint16_t * pOutLength ); /* @[declare_defender_gettopic] */ /*-----------------------------------------------------------*/ /** * @brief 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. * * @param[in] pTopic The topic string to check. * @param[in] topicLength The length of the topic string. * @param[out] pOutApi The defender topic API value. * @param[out] ppOutThingName Optional parameter to output the beginning of the * thing name in the topic string. Pass NULL if not needed. * @param[out] pOutThingNameLength Optional parameter to output the length of * the thing name in the topic string. Pass NULL if not needed. * * @return #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 * @code{c} * * // The following example shows how to use the Defender_MatchTopic API to * // check if an incoming MQTT publish message is a Device Defender message. * * DefenderTopic_t api; * DefenderStatus_t status = DefenderSuccess; * * // 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 ) * { * if( api == DefenderJsonReportAccepted ) * { * // 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. * } * } * @endcode */ /* @[declare_defender_matchtopic] */ DefenderStatus_t Defender_MatchTopic( const char * pTopic, uint16_t topicLength, DefenderTopic_t * pOutApi, const char ** ppOutThingName, uint16_t * pOutThingNameLength ); /* @[declare_defender_matchtopic] */ /*-----------------------------------------------------------*/ #endif /* DEFENDER_H_ */