2 * AWS IoT Common V1.0.0
\r
3 * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
\r
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
\r
6 * this software and associated documentation files (the "Software"), to deal in
\r
7 * the Software without restriction, including without limitation the rights to
\r
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
\r
9 * the Software, and to permit persons to whom the Software is furnished to do so,
\r
10 * subject to the following conditions:
\r
12 * The above copyright notice and this permission notice shall be included in all
\r
13 * copies or substantial portions of the Software.
\r
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
\r
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
\r
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
\r
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
25 * @brief Provides routines and constants that are common to AWS IoT libraries.
\r
26 * This header should not be included in typical application code.
\r
32 /* The config header is always included first. */
\r
33 #include "iot_config.h"
\r
35 /* Standard includes. */
\r
36 #include <stdbool.h>
\r
39 /* Platform types include. */
\r
40 #include "types/iot_platform_types.h"
\r
42 /* MQTT types include. */
\r
43 #include "types/iot_mqtt_types.h"
\r
46 * @brief The longest Thing Name accepted by AWS IoT, per the [AWS IoT
\r
47 * Service Limits](https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html#limits_iot).
\r
49 #define AWS_IOT_MAX_THING_NAME_LENGTH ( 128 )
\r
52 * @brief The common prefix of all AWS IoT MQTT topics.
\r
54 #define AWS_IOT_TOPIC_PREFIX "$aws/things/"
\r
57 * @brief The length of #AWS_IOT_TOPIC_PREFIX.
\r
59 #define AWS_IOT_TOPIC_PREFIX_LENGTH ( ( uint16_t ) ( sizeof( AWS_IOT_TOPIC_PREFIX ) - 1 ) )
\r
62 * @brief The suffix for an AWS IoT operation "accepted" topic.
\r
64 #define AWS_IOT_ACCEPTED_SUFFIX "/accepted"
\r
67 * @brief The length of #AWS_IOT_ACCEPTED_SUFFIX.
\r
69 #define AWS_IOT_ACCEPTED_SUFFIX_LENGTH ( ( uint16_t ) ( sizeof( AWS_IOT_ACCEPTED_SUFFIX ) - 1 ) )
\r
72 * @brief The suffix for an AWS IoT operation "rejected" topic.
\r
74 #define AWS_IOT_REJECTED_SUFFIX "/rejected"
\r
77 * @brief The length of #AWS_IOT_REJECTED_SUFFIX.
\r
79 #define AWS_IOT_REJECTED_SUFFIX_LENGTH ( ( uint16_t ) ( sizeof( AWS_IOT_REJECTED_SUFFIX ) - 1 ) )
\r
82 * @brief The JSON key used to represent client tokens for AWS IoT.
\r
84 #define AWS_IOT_CLIENT_TOKEN_KEY "clientToken"
\r
87 * @brief The length of #AWS_IOT_CLIENT_TOKEN_KEY.
\r
89 #define AWS_IOT_CLIENT_TOKEN_KEY_LENGTH ( sizeof( AWS_IOT_CLIENT_TOKEN_KEY ) - 1 )
\r
92 * @brief The length of the longest client token allowed by AWS IoT.
\r
94 #define AWS_IOT_CLIENT_TOKEN_MAX_LENGTH ( 64 )
\r
97 * @brief A flag to represent persistent subscriptions in a subscriptions
\r
100 * Its value is negative to distinguish it from valid subscription counts, which
\r
101 * are 0 or positive.
\r
103 #define AWS_IOT_PERSISTENT_SUBSCRIPTION ( -1 )
\r
106 * @brief Function pointer representing an MQTT blocking operation.
\r
108 * Currently, this is used to represent @ref mqtt_function_subscribesync or
\r
109 * @ref mqtt_function_unsubscribesync.
\r
111 * @param[in] mqttConnection The MQTT connection to use for the subscription.
\r
112 * @param[in] pSubscriptionList Pointer to the first element in the array of
\r
114 * @param[in] subscriptionCount The number of elements in pSubscriptionList.
\r
115 * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.
\r
116 * Currently, flags are ignored by this function; this parameter is for
\r
117 * future-compatibility.
\r
118 * @param[in] timeoutMs If the MQTT server does not acknowledge the subscriptions within
\r
119 * this timeout in milliseconds, this function returns #IOT_MQTT_TIMEOUT.
\r
121 * @return One of the following:
\r
122 * - #IOT_MQTT_SUCCESS
\r
123 * - #IOT_MQTT_NOT_INITIALIZED
\r
124 * - #IOT_MQTT_BAD_PARAMETER
\r
125 * - #IOT_MQTT_NO_MEMORY
\r
126 * - #IOT_MQTT_NETWORK_ERROR
\r
127 * - #IOT_MQTT_SCHEDULING_ERROR
\r
128 * - #IOT_MQTT_BAD_RESPONSE
\r
129 * - #IOT_MQTT_TIMEOUT
\r
130 * - #IOT_MQTT_SERVER_REFUSED
\r
132 typedef IotMqttError_t ( * AwsIotMqttFunction_t )( IotMqttConnection_t mqttConnection,
\r
133 const IotMqttSubscription_t * pSubscriptionList,
\r
134 size_t subscriptionCount,
\r
136 uint32_t timeoutMs );
\r
139 * @brief Function pointer representing an MQTT library callback function.
\r
141 * @param[in] pArgument Ignored.
\r
142 * @param[in] pMessage The received DELTA document (as an MQTT PUBLISH message).
\r
144 typedef void ( * AwsIotMqttCallbackFunction_t )( void * pArgument,
\r
145 IotMqttCallbackParam_t * pMessage );
\r
148 * @brief Enumerations representing each of the statuses that may be parsed
\r
151 typedef enum AwsIotStatus
\r
153 AWS_IOT_ACCEPTED = 0, /**< Operation accepted. */
\r
154 AWS_IOT_REJECTED = 1, /**< Operation rejected. */
\r
155 AWS_IOT_UNKNOWN = 2 /**< Unknown status (neither accepted nor rejected). */
\r
159 * @brief Information required to generate a topic for AWS IoT.
\r
161 typedef struct AwsIotTopicInfo
\r
163 const char * pThingName; /**< @brief The Thing Name associated with the operation. */
\r
164 size_t thingNameLength; /**< @brief The length of `pThingName`. */
\r
165 const char * pOperationName; /**< @brief The operation name to place in the topic. */
\r
166 uint16_t operationNameLength; /**< @brief The length of `pOperationName`. */
\r
167 uint16_t longestSuffixLength; /**< @brief The length of longest suffix that will be placed at the end of the topic. */
\r
168 void * ( *mallocString )( size_t size ); /**< @brief Function used to allocate a string, if needed. */
\r
169 } AwsIotTopicInfo_t;
\r
172 * @brief Information needed to modify AWS IoT subscription topics.
\r
174 * @warning The buffer passed as `pTopicFilterBase` must be large enough to
\r
175 * accommodate the "/accepted" and "/rejected" suffixes.
\r
177 typedef struct AwsIotSubscriptionInfo_t
\r
179 IotMqttConnection_t mqttConnection; /**< @brief The MQTT connection to use. */
\r
180 AwsIotMqttCallbackFunction_t callbackFunction; /**< @brief Callback function for MQTT subscribe. */
\r
181 uint32_t timeout; /**< @brief Timeout for MQTT function. */
\r
183 /* Topic filter. */
\r
184 char * pTopicFilterBase; /**< @brief Contains the base topic filter, without "/accepted" or "/rejected". */
\r
185 uint16_t topicFilterBaseLength; /**< @brief Length of the base topic filter. */
\r
186 } AwsIotSubscriptionInfo_t;
\r
189 * @brief Thing Name and length, used to match subscriptions.
\r
191 typedef struct AwsIotThingName
\r
193 const char * pThingName; /**< @brief Thing Name to compare. */
\r
194 size_t thingNameLength; /**< @brief Length of `pThingName`. */
\r
195 } AwsIotThingName_t;
\r
198 * @brief Initializes the lists used by AWS IoT operations.
\r
200 * @param[in] pPendingOperationsList The list that holds pending operations for
\r
202 * @param[in] pSubscriptionsList The list that holds subscriptions for a library.
\r
203 * @param[in] pPendingOperationsMutex The mutex that guards the pending operations
\r
205 * @param[in] pSubscriptionsMutex The mutex that guards the subscriptions list.
\r
207 * @return `true` if all initialization succeeded; `false` otherwise.
\r
209 bool AwsIot_InitLists( IotListDouble_t * pPendingOperationsList,
\r
210 IotListDouble_t * pSubscriptionsList,
\r
211 IotMutex_t * pPendingOperationsMutex,
\r
212 IotMutex_t * pSubscriptionsMutex );
\r
215 * @brief Checks that a Thing Name is valid for AWS IoT.
\r
217 * @param[in] pThingName Thing Name to validate.
\r
218 * @param[in] thingNameLength Length of `pThingName`.
\r
220 * @return `true` if `pThingName` is valid; `false` otherwise.
\r
222 bool AwsIot_ValidateThingName( const char * pThingName,
\r
223 size_t thingNameLength );
\r
226 * @brief Extracts the client token from a JSON document.
\r
228 * The client token is used to differentiate AWS IoT operations. It is unique per
\r
231 * @param[in] pJsonDocument The JSON document to parse.
\r
232 * @param[in] jsonDocumentLength The length of `pJsonDocument`.
\r
233 * @param[out] pClientToken Set to point to the client token in `pJsonDocument`.
\r
234 * @param[out] pClientTokenLength Set to the length of the client token.
\r
236 * @return `true` if the client token was found; `false` otherwise. The output
\r
237 * parameters are only valid if this function returns `true`.
\r
239 bool AwsIot_GetClientToken( const char * pJsonDocument,
\r
240 size_t jsonDocumentLength,
\r
241 const char ** pClientToken,
\r
242 size_t * pClientTokenLength );
\r
245 * @brief Parse the Thing Name from an MQTT topic.
\r
247 * @param[in] pTopicName The topic to parse.
\r
248 * @param[in] topicNameLength The length of `pTopicName`.
\r
249 * @param[out] pThingName Set to point to the Thing Name.
\r
250 * @param[out] pThingNameLength Set to the length of the Thing Name.
\r
252 * @return `true` if a Thing Name was successfully parsed; `false` otherwise. The output
\r
253 * parameters are only valid if this function returns `true`.
\r
255 bool AwsIot_ParseThingName( const char * pTopicName,
\r
256 uint16_t topicNameLength,
\r
257 const char ** pThingName,
\r
258 size_t * pThingNameLength );
\r
261 * @brief Parse the operation status (accepted or rejected) from an MQTT topic.
\r
263 * @param[in] pTopicName The topic to parse.
\r
264 * @param[in] topicNameLength The length of `pTopicName`.
\r
266 * @return Any #AwsIotStatus_t.
\r
268 AwsIotStatus_t AwsIot_ParseStatus( const char * pTopicName,
\r
269 uint16_t topicNameLength );
\r
272 * @brief Generate a topic to use for an AWS IoT operation.
\r
274 * @param[in] pTopicInfo Information needed to generate an AWS IoT topic.
\r
275 * @param[in,out] pTopicBuffer Where to place the generated topic. An existing
\r
276 * buffer may be passed in. If `NULL`, this function will attempt to allocate a
\r
278 * @param[out] pOperationTopicLength Set to the length of the generated topic.
\r
280 * @warning This function does not check the length of `pTopicBuffer`! Any provided
\r
281 * buffer must be long enough to accommodate the Thing Name, operation name, and
\r
282 * any other suffixes.
\r
284 * @return `true` if the topic was successfully generated; `false` otherwise.
\r
285 * This function will always succeed when an input buffer is provided.
\r
287 bool AwsIot_GenerateOperationTopic( const AwsIotTopicInfo_t * pTopicInfo,
\r
288 char ** pTopicBuffer,
\r
289 uint16_t * pOperationTopicLength );
\r
292 * @brief Add or remove subscriptions for AWS IoT operations.
\r
294 * @param[in] mqttOperation Either @ref mqtt_function_subscribesync or
\r
295 * @ref mqtt_function_unsubscribesync.
\r
296 * @param[in] pSubscriptionInfo Information needed to process an MQTT
\r
299 * @return See the return values of @ref mqtt_function_subscribesync or
\r
300 * @ref mqtt_function_unsubscribesync.
\r
302 IotMqttError_t AwsIot_ModifySubscriptions( AwsIotMqttFunction_t mqttOperation,
\r
303 const AwsIotSubscriptionInfo_t * pSubscriptionInfo );
\r
305 #endif /* ifndef AWS_IOT_H_ */
\r