]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS-Labs/Source/FreeRTOS-IoT-Libraries/c_sdk/aws/jobs/src/private/aws_iot_jobs_internal.h
Add the Labs projects provided in the V10.2.1_191129 zip file.
[freertos] / FreeRTOS-Labs / Source / FreeRTOS-IoT-Libraries / c_sdk / aws / jobs / src / private / aws_iot_jobs_internal.h
diff --git a/FreeRTOS-Labs/Source/FreeRTOS-IoT-Libraries/c_sdk/aws/jobs/src/private/aws_iot_jobs_internal.h b/FreeRTOS-Labs/Source/FreeRTOS-IoT-Libraries/c_sdk/aws/jobs/src/private/aws_iot_jobs_internal.h
new file mode 100644 (file)
index 0000000..458bc00
--- /dev/null
@@ -0,0 +1,628 @@
+/*\r
+ * AWS IoT Jobs V1.0.0\r
+ * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
+ * this software and associated documentation files (the "Software"), to deal in\r
+ * the Software without restriction, including without limitation the rights to\r
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
+ * the Software, and to permit persons to whom the Software is furnished to do so,\r
+ * subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+/**\r
+ * @file aws_iot_jobs_internal.h\r
+ * @brief Internal header of Jobs library. This header should not be included in\r
+ * typical application code.\r
+ */\r
+\r
+#ifndef AWS_IOT_JOBS_INTERNAL_H_\r
+#define AWS_IOT_JOBS_INTERNAL_H_\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* Linear containers (lists and queues) include. */\r
+#include "iot_linear_containers.h"\r
+\r
+/* Jobs include. */\r
+#include "aws_iot_jobs.h"\r
+\r
+/* AWS IoT include. */\r
+#include "aws_iot.h"\r
+\r
+/**\r
+ * @def AwsIotJobs_Assert( expression )\r
+ * @brief Assertion macro for the Jobs library.\r
+ *\r
+ * Set @ref AWS_IOT_JOBS_ENABLE_ASSERTS to `1` to enable assertions in the Jobs\r
+ * library.\r
+ *\r
+ * @param[in] expression Expression to be evaluated.\r
+ */\r
+#if AWS_IOT_JOBS_ENABLE_ASSERTS == 1\r
+    #ifndef AwsIotJobs_Assert\r
+        #ifdef Iot_DefaultAssert\r
+            #define AwsIotJobs_Assert( expression )    Iot_DefaultAssert( expression )\r
+        #else\r
+            #error "Asserts are enabled for Jobs, but AwsIotJobs_Assert is not defined"\r
+        #endif\r
+    #endif\r
+#else\r
+    #define AwsIotJobs_Assert( expression )\r
+#endif\r
+\r
+/* Configure logs for Jobs functions. */\r
+#ifdef AWS_IOT_LOG_LEVEL_JOBS\r
+    #define LIBRARY_LOG_LEVEL        AWS_IOT_LOG_LEVEL_JOBS\r
+#else\r
+    #ifdef IOT_LOG_LEVEL_GLOBAL\r
+        #define LIBRARY_LOG_LEVEL    IOT_LOG_LEVEL_GLOBAL\r
+    #else\r
+        #define LIBRARY_LOG_LEVEL    IOT_LOG_NONE\r
+    #endif\r
+#endif\r
+\r
+#define LIBRARY_LOG_NAME    ( "Jobs" )\r
+#include "iot_logging_setup.h"\r
+\r
+/*\r
+ * Provide default values for undefined memory allocation functions based on\r
+ * the usage of dynamic memory allocation.\r
+ */\r
+#if IOT_STATIC_MEMORY_ONLY == 1\r
+    #include "iot_static_memory.h"\r
+\r
+/**\r
+ * @brief Allocate a #_jobsOperation_t. This function should have the same\r
+ * signature as [malloc]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
+ */\r
+    void * AwsIotJobs_MallocOperation( size_t size );\r
+\r
+/**\r
+ * @brief Free a #_jobsOperation_t. This function should have the same\r
+ * signature as [free]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
+ */\r
+    void AwsIotJobs_FreeOperation( void * ptr );\r
+\r
+/**\r
+ * @brief Allocate a buffer for a short string, used for topic names or client\r
+ * tokens. This function should have the same signature as [malloc]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
+ */\r
+    #define AwsIotJobs_MallocString    Iot_MallocMessageBuffer\r
+\r
+/**\r
+ * @brief Free a string. This function should have the same signature as\r
+ * [free]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
+ */\r
+    #define AwsIotJobs_FreeString      Iot_FreeMessageBuffer\r
+\r
+/**\r
+ * @brief Allocate a #_jobsSubscription_t. This function should have the\r
+ * same signature as [malloc]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
+ */\r
+    void * AwsIotJobs_MallocSubscription( size_t size );\r
+\r
+/**\r
+ * @brief Free a #_jobsSubscription_t. This function should have the same\r
+ * signature as [free]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
+ */\r
+    void AwsIotJobs_FreeSubscription( void * ptr );\r
+#else /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
+    #ifndef AwsIotJobs_MallocOperation\r
+        #ifdef Iot_DefaultMalloc\r
+            #define AwsIotJobs_MallocOperation    Iot_DefaultMalloc\r
+        #else\r
+            #error "No malloc function defined for AwsIotJobs_MallocOperation"\r
+        #endif\r
+    #endif\r
+\r
+    #ifndef AwsIotJobs_FreeOperation\r
+        #ifdef Iot_DefaultFree\r
+            #define AwsIotJobs_FreeOperation    Iot_DefaultFree\r
+        #else\r
+            #error "No free function defined for AwsIotJobs_FreeOperation"\r
+        #endif\r
+    #endif\r
+\r
+    #ifndef AwsIotJobs_MallocString\r
+        #ifdef Iot_DefaultMalloc\r
+            #define AwsIotJobs_MallocString    Iot_DefaultMalloc\r
+        #else\r
+            #error "No malloc function defined for AwsIotJobs_MallocString"\r
+        #endif\r
+    #endif\r
+\r
+    #ifndef AwsIotJobs_FreeString\r
+        #ifdef Iot_DefaultFree\r
+            #define AwsIotJobs_FreeString    Iot_DefaultFree\r
+        #else\r
+            #error "No free function defined for AwsIotJobs_FreeString"\r
+        #endif\r
+    #endif\r
+\r
+    #ifndef AwsIotJobs_MallocSubscription\r
+        #ifdef Iot_DefaultMalloc\r
+            #define AwsIotJobs_MallocSubscription    Iot_DefaultMalloc\r
+        #else\r
+            #error "No malloc function defined for AwsIotJobs_MallocSubscription"\r
+        #endif\r
+    #endif\r
+\r
+    #ifndef AwsIotJobs_FreeSubscription\r
+        #ifdef Iot_DefaultFree\r
+            #define AwsIotJobs_FreeSubscription    Iot_DefaultFree\r
+        #else\r
+            #error "No free function defined for AwsIotJobs_FreeSubscription"\r
+        #endif\r
+    #endif\r
+#endif /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
+\r
+/**\r
+ * @cond DOXYGEN_IGNORE\r
+ * Doxygen should ignore this section.\r
+ *\r
+ * Provide default values for undefined configuration constants.\r
+ */\r
+#ifndef AWS_IOT_JOBS_DEFAULT_MQTT_TIMEOUT_MS\r
+    #define AWS_IOT_JOBS_DEFAULT_MQTT_TIMEOUT_MS    ( 5000 )\r
+#endif\r
+#ifndef AWS_IOT_JOBS_NOTIFY_CALLBACKS\r
+    #define AWS_IOT_JOBS_NOTIFY_CALLBACKS           ( 1 )\r
+#endif\r
+/** @endcond */\r
+\r
+/**\r
+ * @brief The number of currently available Jobs operations.\r
+ *\r
+ * The 4 Jobs operations are GET PENDING, START NEXT, DESCRIBE, and UPDATE.\r
+ */\r
+#define JOBS_OPERATION_COUNT                          ( 4 )\r
+\r
+/**\r
+ * @brief The number of currently available Jobs callbacks.\r
+ *\r
+ * The 2 Jobs callbacks are `jobs/notify` (AKA "Notify Pending") and\r
+ * `/jobs/notify-next` (AKA "Notify Next").\r
+ */\r
+#define JOBS_CALLBACK_COUNT                           ( 2 )\r
+\r
+/**\r
+ * @brief The string representing a Jobs GET PENDING operation in a Jobs MQTT topic.\r
+ */\r
+#define JOBS_GET_PENDING_OPERATION_STRING             "/jobs/get"\r
+\r
+/**\r
+ * @brief The length of #JOBS_GET_PENDING_OPERATION_STRING.\r
+ */\r
+#define JOBS_GET_PENDING_OPERATION_STRING_LENGTH      ( ( uint16_t ) ( sizeof( JOBS_GET_PENDING_OPERATION_STRING ) - 1 ) )\r
+\r
+/**\r
+ * @brief The string representing a Jobs START NEXT operation in a Jobs MQTT topic.\r
+ */\r
+#define JOBS_START_NEXT_OPERATION_STRING              "/jobs/start-next"\r
+\r
+/**\r
+ * @brief The length of #JOBS_START_NEXT_OPERATION_STRING.\r
+ */\r
+#define JOBS_START_NEXT_OPERATION_STRING_LENGTH       ( ( uint16_t ) ( sizeof( JOBS_START_NEXT_OPERATION_STRING ) - 1 ) )\r
+\r
+/**\r
+ * @brief The string representing a Jobs DESCRIBE operation in a Jobs MQTT topic.\r
+ *\r
+ * This string should be placed after a Job ID.\r
+ */\r
+#define JOBS_DESCRIBE_OPERATION_STRING                "/get"\r
+\r
+/**\r
+ * @brief The length of #JOBS_DESCRIBE_OPERATION_STRING.\r
+ */\r
+#define JOBS_DESCRIBE_OPERATION_STRING_LENGTH         ( ( uint16_t ) ( sizeof( JOBS_DESCRIBE_OPERATION_STRING ) - 1 ) )\r
+\r
+/**\r
+ * @brief The string representing a Jobs UPDATE operation in a Jobs MQTT topic.\r
+ *\r
+ * This string should be placed after a Job ID.\r
+ */\r
+#define JOBS_UPDATE_OPERATION_STRING                  "/update"\r
+\r
+/**\r
+ * @brief The length of #JOBS_UPDATE_OPERATION_STRING.\r
+ *\r
+ * This length excludes the length of the placeholder %s.\r
+ */\r
+#define JOBS_UPDATE_OPERATION_STRING_LENGTH           ( ( uint16_t ) ( sizeof( JOBS_UPDATE_OPERATION_STRING ) - 1 ) )\r
+\r
+/**\r
+ * @brief The string representing the Jobs MQTT topic for receiving notifications\r
+ * of pending Jobs.\r
+ */\r
+#define JOBS_NOTIFY_PENDING_CALLBACK_STRING           "/jobs/notify"\r
+\r
+/**\r
+ * @brief The length of #JOBS_NOTIFY_PENDING_CALLBACK_STRING.\r
+ */\r
+#define JOBS_NOTIFY_PENDING_CALLBACK_STRING_LENGTH    ( ( uint16_t ) ( sizeof( JOBS_NOTIFY_PENDING_CALLBACK_STRING ) - 1 ) )\r
+\r
+/**\r
+ * @brief The string representing the Jobs MQTT topic for receiving notifications\r
+ * of the next pending Job.\r
+ */\r
+#define JOBS_NOTIFY_NEXT_CALLBACK_STRING              "/jobs/notify-next"\r
+\r
+/**\r
+ * @brief The length of #JOBS_NOTIFY_NEXT_CALLBACK_STRING.\r
+ */\r
+#define JOBS_NOTIFY_NEXT_CALLBACK_STRING_LENGTH       ( ( uint16_t ) ( sizeof( JOBS_NOTIFY_NEXT_CALLBACK_STRING ) - 1 ) )\r
+\r
+/**\r
+ * @brief The maximum length of a Job ID, per AWS IoT Service Limits.\r
+ *\r
+ * See https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html#job-limits\r
+ */\r
+#define JOBS_MAX_ID_LENGTH                            ( 64 )\r
+\r
+/**\r
+ * @brief The maximum value of the Jobs step timeout, per AWS IoT Service Limits.\r
+ *\r
+ * See https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html#job-limits\r
+ */\r
+#define JOBS_MAX_TIMEOUT                              ( 10080 )\r
+\r
+/**\r
+ * @brief A limit on the maximum length of a Jobs status details, per AWS IoT\r
+ * Service Limits.\r
+ *\r
+ * See https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html#job-limits\r
+ *\r
+ * This is actually the limit on the length of an entire Jobs document; but the\r
+ * status details must also not exceed this length,\r
+ */\r
+#define JOBS_MAX_STATUS_DETAILS_LENGTH                ( 32768 )\r
+\r
+/**\r
+ * @brief The length of the longest Jobs topic suffix.\r
+ *\r
+ * This is the length of the longest Job ID, plus the length of the "UPDATE"\r
+ * operation suffix, plus the length of "/jobs/".\r
+ */\r
+#define JOBS_LONGEST_SUFFIX_LENGTH                    ( JOBS_MAX_ID_LENGTH + JOBS_UPDATE_OPERATION_STRING_LENGTH + 6 )\r
+\r
+/*------------------------ Jobs internal data types -------------------------*/\r
+\r
+/**\r
+ * @brief Enumerations representing each of the Jobs library's API functions.\r
+ */\r
+typedef enum _jobsOperationType\r
+{\r
+    /* Jobs operations. */\r
+    JOBS_GET_PENDING = 0, /**< @ref jobs_function_getpendingasync */\r
+    JOBS_START_NEXT = 1,  /**< @ref jobs_function_startnextasync */\r
+    JOBS_DESCRIBE = 2,    /**< @ref jobs_function_describeasync */\r
+    JOBS_UPDATE = 3,      /**< @ref jobs_function_updateasync */\r
+\r
+    /* Jobs callbacks. */\r
+    SET_NOTIFY_PENDING_CALLBACK = 4, /**< @ref jobs_function_setnotifypendingcallback */\r
+    SET_NOTIFY_NEXT_CALLBACK = 5     /**< @ref jobs_function_setnotifynextcallback */\r
+} _jobsOperationType_t;\r
+\r
+/**\r
+ * @brief Enumerations representing each of the Jobs callback functions.\r
+ */\r
+typedef enum _jobsCallbackType\r
+{\r
+    NOTIFY_PENDING_CALLBACK = 0, /**< Pending Job notification callback. */\r
+    NOTIFY_NEXT_CALLBACK = 1     /**< Next Job notification callback. */\r
+} _jobsCallbackType_t;\r
+\r
+/**\r
+ * @brief Parameter to #_AwsIotJobs_GenerateJsonRequest.\r
+ */\r
+typedef union _jsonRequestContents\r
+{\r
+    const AwsIotJobsUpdateInfo_t * pUpdateInfo; /**< @brief Valid for #JOBS_START_NEXT and #JOBS_UPDATE. */\r
+\r
+    struct\r
+    {\r
+        int32_t executionNumber; /**< @brief Execution number. */\r
+        bool includeJobDocument; /**< @brief Whether the response should include the Job document. */\r
+    } describe;                  /**< @brief Valid for #JOBS_DESCRIBE. */\r
+} _jsonRequestContents_t;\r
+\r
+/**\r
+ * @brief Represents a Jobs subscriptions object.\r
+ *\r
+ * These structures are stored in a list.\r
+ */\r
+typedef struct _jobsSubscription\r
+{\r
+    IotLink_t link;                                      /**< @brief List link member. */\r
+\r
+    int32_t operationReferences[ JOBS_OPERATION_COUNT ]; /**< @brief Reference counters for Jobs operation topics. */\r
+    int32_t callbackReferences;                          /**< @brief Reference counter for Jobs callbacks. */\r
+\r
+    /** @brief Jobs callbacks for this Thing. */\r
+    AwsIotJobsCallbackInfo_t callbacks[ JOBS_CALLBACK_COUNT ][ AWS_IOT_JOBS_NOTIFY_CALLBACKS ];\r
+\r
+    /**\r
+     * @brief Buffer allocated for removing Jobs topics.\r
+     *\r
+     * This buffer is pre-allocated to ensure that memory is available when\r
+     * unsubscribing.\r
+     */\r
+    char * pTopicBuffer;\r
+\r
+    size_t thingNameLength; /**< @brief Length of Thing Name. */\r
+    char pThingName[];      /**< @brief Thing Name associated with this subscriptions object. */\r
+} _jobsSubscription_t;\r
+\r
+/**\r
+ * @brief Internal structure representing a single Jobs operation.\r
+ *\r
+ * A list of these structures keeps track of all in-progress Jobs operations.\r
+ */\r
+typedef struct _jobsOperation\r
+{\r
+    IotLink_t link; /**< @brief List link member. */\r
+\r
+    /* Basic operation information. */\r
+    _jobsOperationType_t type;           /**< @brief Operation type. */\r
+    uint32_t flags;                      /**< @brief Flags passed to operation API function. */\r
+    AwsIotJobsError_t status;            /**< @brief Status of operation. */\r
+\r
+    IotMqttConnection_t mqttConnection;  /**< @brief MQTT connection associated with this operation. */\r
+    _jobsSubscription_t * pSubscription; /**< @brief Jobs subscriptions object associated with this operation. */\r
+\r
+    /* Jobs request information. */\r
+    const char * pJobsRequest; /**< @brief JSON document to send to the Jobs service. */\r
+    size_t jobsRequestLength;  /**< @brief Length of #_jobsOperation_t.pJobsRequest. */\r
+\r
+    const char * pClientToken; /**< @brief Client token sent with request. */\r
+    size_t clientTokenLength;  /**< @brief Length of #_jobsOperation_t.pClientToken. */\r
+\r
+    /* Jobs response information. */\r
+    const char * pJobsResponse; /**< @brief Response received from the Jobs service. */\r
+    size_t jobsResponseLength;  /**< @brief Length of #_jobsOperation_t.pJobsResponse. */\r
+\r
+    /**\r
+     * @brief Function to allocate memory for an incoming Jobs response.\r
+     *\r
+     * Only used when the flag #AWS_IOT_JOBS_FLAG_WAITABLE is set.\r
+     */\r
+    void * ( *mallocResponse )( size_t );\r
+\r
+    /* How to notify of an operation's completion. */\r
+    union\r
+    {\r
+        IotSemaphore_t waitSemaphore;      /**< @brief Semaphore to be used with @ref jobs_function_wait. */\r
+        AwsIotJobsCallbackInfo_t callback; /**< @brief User-provided callback function and parameter. */\r
+    } notify;                              /**< @brief How to notify of an operation's completion. */\r
+\r
+    size_t jobIdLength;                    /**< @brief Length of #_jobsOperation_t.pJobId. */\r
+    char pJobId[];                         /**< @brief Job ID, saved for DESCRIBE and UPDATE operations. */\r
+} _jobsOperation_t;\r
+\r
+/* Declarations of names printed in logs. */\r
+#if LIBRARY_LOG_LEVEL > IOT_LOG_NONE\r
+    extern const char * const _pAwsIotJobsOperationNames[];\r
+    extern const char * const _pAwsIotJobsCallbackNames[];\r
+#endif\r
+\r
+/* Declarations of variables for internal Jobs files. */\r
+extern uint32_t _AwsIotJobsMqttTimeoutMs;\r
+extern IotListDouble_t _AwsIotJobsPendingOperations;\r
+extern IotListDouble_t _AwsIotJobsSubscriptions;\r
+extern IotMutex_t _AwsIotJobsPendingOperationsMutex;\r
+extern IotMutex_t _AwsIotJobsSubscriptionsMutex;\r
+\r
+/*------------------------ Jobs operation functions -------------------------*/\r
+\r
+/**\r
+ * @brief Create a record for a new in-progress Jobs operation.\r
+ *\r
+ * @param[in] type The type of Jobs operation for the request.\r
+ * @param[in] pRequestInfo Common Jobs request parameters.\r
+ * @param[in] pRequestContents Additional values to place in the JSON document,\r
+ * depending on `type`.\r
+ * @param[in] flags Flags variables passed to a user-facing Jobs function.\r
+ * @param[in] pCallbackInfo User-provided callback function and parameter.\r
+ * @param[out] pNewOperation Set to point to the new operation on success.\r
+ *\r
+ * @return #AWS_IOT_JOBS_SUCCESS or #AWS_IOT_JOBS_NO_MEMORY\r
+ */\r
+AwsIotJobsError_t _AwsIotJobs_CreateOperation( _jobsOperationType_t type,\r
+                                               const AwsIotJobsRequestInfo_t * pRequestInfo,\r
+                                               const _jsonRequestContents_t * pRequestContents,\r
+                                               uint32_t flags,\r
+                                               const AwsIotJobsCallbackInfo_t * pCallbackInfo,\r
+                                               _jobsOperation_t ** pNewOperation );\r
+\r
+/**\r
+ * @brief Free resources used to record a Jobs operation. This is called when\r
+ * the operation completes.\r
+ *\r
+ * @param[in] pData The operation which completed. This parameter is of type\r
+ * `void*` to match the signature of [free]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
+ */\r
+void _AwsIotJobs_DestroyOperation( void * pData );\r
+\r
+/**\r
+ * @brief Fill a buffer with a Jobs topic.\r
+ *\r
+ * @param[in] type One of: GET PENDING, START NEXT, DESCRIBE, or UPDATE.\r
+ * @param[in] pRequestInfo Common Jobs request parameters.\r
+ * @param[out] pTopicBuffer Address of the buffer for the Jobs topic. If the\r
+ * pointer at this address is `NULL`, this function will allocate a new buffer;\r
+ * otherwise, it will use the provided buffer.\r
+ * @param[out] pOperationTopicLength Length of the Jobs operation topic (excluding\r
+ * any suffix) placed in `pTopicBuffer`.\r
+ *\r
+ * @warning This function does not check the length of `pTopicBuffer`! Any provided\r
+ * buffer must be large enough to accommodate the full Jobs topic, plus\r
+ * #JOBS_LONGEST_SUFFIX_LENGTH.\r
+ *\r
+ * @return #AWS_IOT_JOBS_SUCCESS or #AWS_IOT_JOBS_NO_MEMORY. This function\r
+ * will not return #AWS_IOT_JOBS_NO_MEMORY when a buffer is provided.\r
+ */\r
+AwsIotJobsError_t _AwsIotJobs_GenerateJobsTopic( _jobsOperationType_t type,\r
+                                                 const AwsIotJobsRequestInfo_t * pRequestInfo,\r
+                                                 char ** pTopicBuffer,\r
+                                                 uint16_t * pOperationTopicLength );\r
+\r
+/**\r
+ * @brief Process a Jobs operation by sending the necessary MQTT packets.\r
+ *\r
+ * @param[in] pRequestInfo Common Jobs request parameters.\r
+ * @param[in] pOperation Operation data to process.\r
+ *\r
+ * @return #AWS_IOT_JOBS_STATUS_PENDING on success. On error, one of\r
+ * #AWS_IOT_JOBS_NO_MEMORY or #AWS_IOT_JOBS_MQTT_ERROR.\r
+ */\r
+AwsIotJobsError_t _AwsIotJobs_ProcessOperation( const AwsIotJobsRequestInfo_t * pRequestInfo,\r
+                                                _jobsOperation_t * pOperation );\r
+\r
+/*----------------------- Jobs subscription functions -----------------------*/\r
+\r
+/**\r
+ * @brief Find a Jobs subscription object. May create a new subscription object\r
+ * and adds it to the subscription list if not found.\r
+ *\r
+ * @param[in] pThingName Thing Name in the subscription object.\r
+ * @param[in] thingNameLength Length of `pThingName`.\r
+ * @param[in] createIfNotFound If `true`, attempt to create a new subscription\r
+ * object if no match is found.\r
+ *\r
+ * @return Pointer to a Jobs subscription object, either found or newly\r
+ * allocated. Returns `NULL` if no subscription object is found and a new\r
+ * subscription object could not be allocated.\r
+ *\r
+ * @note This function should be called with the subscription list mutex locked.\r
+ */\r
+_jobsSubscription_t * _AwsIotJobs_FindSubscription( const char * pThingName,\r
+                                                    size_t thingNameLength,\r
+                                                    bool createIfNotFound );\r
+\r
+/**\r
+ * @brief Remove a Jobs subscription object from the subscription list if\r
+ * unreferenced.\r
+ *\r
+ * @param[in] pSubscription Subscription object to check. If this object has no\r
+ * active references, it is removed from the subscription list.\r
+ * @param[out] pRemovedSubscription Removed subscription object, if any. Optional;\r
+ * pass `NULL` to ignore. If not `NULL`, this parameter will be set to the removed\r
+ * subscription and that subscription will not be destroyed.\r
+ *\r
+ * @note This function should be called with the subscription list mutex locked.\r
+ */\r
+void _AwsIotJobs_RemoveSubscription( _jobsSubscription_t * pSubscription,\r
+                                     _jobsSubscription_t ** pRemovedSubscription );\r
+\r
+/**\r
+ * @brief Free resources used for a Jobs subscription object.\r
+ *\r
+ * @param[in] pData The subscription object to destroy. This parameter is of type\r
+ * `void*` to match the signature of [free]\r
+ * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
+ */\r
+void _AwsIotJobs_DestroySubscription( void * pData );\r
+\r
+/**\r
+ * @brief Increment the reference count of a Jobs subscriptions object.\r
+ *\r
+ * Also adds MQTT subscriptions if necessary.\r
+ *\r
+ * @param[in] pOperation The operation for which the reference count should be\r
+ * incremented.\r
+ * @param[in] pTopicBuffer Topic buffer containing the operation topic, used if\r
+ * subscriptions need to be added.\r
+ * @param[in] operationTopicLength The length of the operation topic in `pTopicBuffer`.\r
+ * @param[in] callback MQTT callback function for when this operation completes.\r
+ *\r
+ * @warning This function does not check the length of `pTopicBuffer`! Any provided\r
+ * buffer must already contain the Jobs operation topic, plus enough space for the\r
+ * status suffix.\r
+ *\r
+ * @return #AWS_IOT_JOBS_SUCCESS on success. On error, one of\r
+ * #AWS_IOT_JOBS_NO_MEMORY or #AWS_IOT_JOBS_MQTT_ERROR.\r
+ *\r
+ * @note This function should be called with the subscription list mutex locked.\r
+ */\r
+AwsIotJobsError_t _AwsIotJobs_IncrementReferences( _jobsOperation_t * pOperation,\r
+                                                   char * pTopicBuffer,\r
+                                                   uint16_t operationTopicLength,\r
+                                                   AwsIotMqttCallbackFunction_t callback );\r
+\r
+/**\r
+ * @brief Decrement the reference count of a Jobs subscriptions object.\r
+ *\r
+ * Also removed MQTT subscriptions and deletes the subscription object if necessary.\r
+ *\r
+ * @param[in] pOperation The operation for which the reference count should be\r
+ * decremented.\r
+ * @param[in] pTopicBuffer Topic buffer containing the operation topic, used if\r
+ * subscriptions need to be removed.\r
+ * @param[out] pRemovedSubscription Set to point to a removed subscription.\r
+ * Optional; pass `NULL` to ignore. If not `NULL`, this function will not destroy\r
+ * a removed subscription.\r
+ *\r
+ * @warning This function does not check the length of `pTopicBuffer`! Any provided\r
+ * buffer must be large enough to accommodate the full Jobs topic, plus\r
+ * #JOBS_LONGEST_SUFFIX_LENGTH.\r
+ *\r
+ * @note This function should be called with the subscription list mutex locked.\r
+ */\r
+void _AwsIotJobs_DecrementReferences( _jobsOperation_t * pOperation,\r
+                                      char * pTopicBuffer,\r
+                                      _jobsSubscription_t ** pRemovedSubscription );\r
+\r
+/*------------------------ Jobs serializer functions ------------------------*/\r
+\r
+/**\r
+ * @brief Generates a Jobs JSON request document from an #AwsIotJobsRequestInfo_t\r
+ * and an #AwsIotJobsUpdateInfo_t.\r
+ *\r
+ * @param[in] type The type of Jobs operation for the request.\r
+ * @param[in] pRequestInfo Common Jobs request parameters.\r
+ * @param[in] pRequestContents Additional values to place in the JSON document,\r
+ * depending on `type`.\r
+ * @param[in] pOperation Operation associated with the Jobs request.\r
+ *\r
+ * @return #AWS_IOT_JOBS_SUCCESS on success; otherwise, #AWS_IOT_JOBS_NO_MEMORY.\r
+ */\r
+AwsIotJobsError_t _AwsIotJobs_GenerateJsonRequest( _jobsOperationType_t type,\r
+                                                   const AwsIotJobsRequestInfo_t * pRequestInfo,\r
+                                                   const _jsonRequestContents_t * pRequestContents,\r
+                                                   _jobsOperation_t * pOperation );\r
+\r
+/**\r
+ * @brief Parse a response received from the Jobs service.\r
+ *\r
+ * @param[in] status Either ACCEPTED or REJECTED.\r
+ * @param[in] pResponse The response received from the Jobs service.\r
+ * @param[in] responseLength Length of `pResponse`.\r
+ * @param[out] pOperation Associated Jobs operation, where parse results are\r
+ * written.\r
+ */\r
+void _AwsIotJobs_ParseResponse( AwsIotStatus_t status,\r
+                                const char * pResponse,\r
+                                size_t responseLength,\r
+                                _jobsOperation_t * pOperation );\r
+\r
+#endif /* ifndef AWS_IOT_JOBS_INTERNAL_H_ */\r