]> git.sur5r.net Git - freertos/blob - 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
1 /*\r
2  * AWS IoT Jobs V1.0.0\r
3  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\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
11  *\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
14  *\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
21  */\r
22 \r
23 /**\r
24  * @file aws_iot_jobs_internal.h\r
25  * @brief Internal header of Jobs library. This header should not be included in\r
26  * typical application code.\r
27  */\r
28 \r
29 #ifndef AWS_IOT_JOBS_INTERNAL_H_\r
30 #define AWS_IOT_JOBS_INTERNAL_H_\r
31 \r
32 /* The config header is always included first. */\r
33 #include "iot_config.h"\r
34 \r
35 /* Linear containers (lists and queues) include. */\r
36 #include "iot_linear_containers.h"\r
37 \r
38 /* Jobs include. */\r
39 #include "aws_iot_jobs.h"\r
40 \r
41 /* AWS IoT include. */\r
42 #include "aws_iot.h"\r
43 \r
44 /**\r
45  * @def AwsIotJobs_Assert( expression )\r
46  * @brief Assertion macro for the Jobs library.\r
47  *\r
48  * Set @ref AWS_IOT_JOBS_ENABLE_ASSERTS to `1` to enable assertions in the Jobs\r
49  * library.\r
50  *\r
51  * @param[in] expression Expression to be evaluated.\r
52  */\r
53 #if AWS_IOT_JOBS_ENABLE_ASSERTS == 1\r
54     #ifndef AwsIotJobs_Assert\r
55         #ifdef Iot_DefaultAssert\r
56             #define AwsIotJobs_Assert( expression )    Iot_DefaultAssert( expression )\r
57         #else\r
58             #error "Asserts are enabled for Jobs, but AwsIotJobs_Assert is not defined"\r
59         #endif\r
60     #endif\r
61 #else\r
62     #define AwsIotJobs_Assert( expression )\r
63 #endif\r
64 \r
65 /* Configure logs for Jobs functions. */\r
66 #ifdef AWS_IOT_LOG_LEVEL_JOBS\r
67     #define LIBRARY_LOG_LEVEL        AWS_IOT_LOG_LEVEL_JOBS\r
68 #else\r
69     #ifdef IOT_LOG_LEVEL_GLOBAL\r
70         #define LIBRARY_LOG_LEVEL    IOT_LOG_LEVEL_GLOBAL\r
71     #else\r
72         #define LIBRARY_LOG_LEVEL    IOT_LOG_NONE\r
73     #endif\r
74 #endif\r
75 \r
76 #define LIBRARY_LOG_NAME    ( "Jobs" )\r
77 #include "iot_logging_setup.h"\r
78 \r
79 /*\r
80  * Provide default values for undefined memory allocation functions based on\r
81  * the usage of dynamic memory allocation.\r
82  */\r
83 #if IOT_STATIC_MEMORY_ONLY == 1\r
84     #include "iot_static_memory.h"\r
85 \r
86 /**\r
87  * @brief Allocate a #_jobsOperation_t. This function should have the same\r
88  * signature as [malloc]\r
89  * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
90  */\r
91     void * AwsIotJobs_MallocOperation( size_t size );\r
92 \r
93 /**\r
94  * @brief Free a #_jobsOperation_t. This function should have the same\r
95  * signature as [free]\r
96  * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
97  */\r
98     void AwsIotJobs_FreeOperation( void * ptr );\r
99 \r
100 /**\r
101  * @brief Allocate a buffer for a short string, used for topic names or client\r
102  * tokens. This function should have the same signature as [malloc]\r
103  * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
104  */\r
105     #define AwsIotJobs_MallocString    Iot_MallocMessageBuffer\r
106 \r
107 /**\r
108  * @brief Free a string. This function should have the same signature as\r
109  * [free]\r
110  * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
111  */\r
112     #define AwsIotJobs_FreeString      Iot_FreeMessageBuffer\r
113 \r
114 /**\r
115  * @brief Allocate a #_jobsSubscription_t. This function should have the\r
116  * same signature as [malloc]\r
117  * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
118  */\r
119     void * AwsIotJobs_MallocSubscription( size_t size );\r
120 \r
121 /**\r
122  * @brief Free a #_jobsSubscription_t. This function should have the same\r
123  * signature as [free]\r
124  * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
125  */\r
126     void AwsIotJobs_FreeSubscription( void * ptr );\r
127 #else /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
128     #ifndef AwsIotJobs_MallocOperation\r
129         #ifdef Iot_DefaultMalloc\r
130             #define AwsIotJobs_MallocOperation    Iot_DefaultMalloc\r
131         #else\r
132             #error "No malloc function defined for AwsIotJobs_MallocOperation"\r
133         #endif\r
134     #endif\r
135 \r
136     #ifndef AwsIotJobs_FreeOperation\r
137         #ifdef Iot_DefaultFree\r
138             #define AwsIotJobs_FreeOperation    Iot_DefaultFree\r
139         #else\r
140             #error "No free function defined for AwsIotJobs_FreeOperation"\r
141         #endif\r
142     #endif\r
143 \r
144     #ifndef AwsIotJobs_MallocString\r
145         #ifdef Iot_DefaultMalloc\r
146             #define AwsIotJobs_MallocString    Iot_DefaultMalloc\r
147         #else\r
148             #error "No malloc function defined for AwsIotJobs_MallocString"\r
149         #endif\r
150     #endif\r
151 \r
152     #ifndef AwsIotJobs_FreeString\r
153         #ifdef Iot_DefaultFree\r
154             #define AwsIotJobs_FreeString    Iot_DefaultFree\r
155         #else\r
156             #error "No free function defined for AwsIotJobs_FreeString"\r
157         #endif\r
158     #endif\r
159 \r
160     #ifndef AwsIotJobs_MallocSubscription\r
161         #ifdef Iot_DefaultMalloc\r
162             #define AwsIotJobs_MallocSubscription    Iot_DefaultMalloc\r
163         #else\r
164             #error "No malloc function defined for AwsIotJobs_MallocSubscription"\r
165         #endif\r
166     #endif\r
167 \r
168     #ifndef AwsIotJobs_FreeSubscription\r
169         #ifdef Iot_DefaultFree\r
170             #define AwsIotJobs_FreeSubscription    Iot_DefaultFree\r
171         #else\r
172             #error "No free function defined for AwsIotJobs_FreeSubscription"\r
173         #endif\r
174     #endif\r
175 #endif /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
176 \r
177 /**\r
178  * @cond DOXYGEN_IGNORE\r
179  * Doxygen should ignore this section.\r
180  *\r
181  * Provide default values for undefined configuration constants.\r
182  */\r
183 #ifndef AWS_IOT_JOBS_DEFAULT_MQTT_TIMEOUT_MS\r
184     #define AWS_IOT_JOBS_DEFAULT_MQTT_TIMEOUT_MS    ( 5000 )\r
185 #endif\r
186 #ifndef AWS_IOT_JOBS_NOTIFY_CALLBACKS\r
187     #define AWS_IOT_JOBS_NOTIFY_CALLBACKS           ( 1 )\r
188 #endif\r
189 /** @endcond */\r
190 \r
191 /**\r
192  * @brief The number of currently available Jobs operations.\r
193  *\r
194  * The 4 Jobs operations are GET PENDING, START NEXT, DESCRIBE, and UPDATE.\r
195  */\r
196 #define JOBS_OPERATION_COUNT                          ( 4 )\r
197 \r
198 /**\r
199  * @brief The number of currently available Jobs callbacks.\r
200  *\r
201  * The 2 Jobs callbacks are `jobs/notify` (AKA "Notify Pending") and\r
202  * `/jobs/notify-next` (AKA "Notify Next").\r
203  */\r
204 #define JOBS_CALLBACK_COUNT                           ( 2 )\r
205 \r
206 /**\r
207  * @brief The string representing a Jobs GET PENDING operation in a Jobs MQTT topic.\r
208  */\r
209 #define JOBS_GET_PENDING_OPERATION_STRING             "/jobs/get"\r
210 \r
211 /**\r
212  * @brief The length of #JOBS_GET_PENDING_OPERATION_STRING.\r
213  */\r
214 #define JOBS_GET_PENDING_OPERATION_STRING_LENGTH      ( ( uint16_t ) ( sizeof( JOBS_GET_PENDING_OPERATION_STRING ) - 1 ) )\r
215 \r
216 /**\r
217  * @brief The string representing a Jobs START NEXT operation in a Jobs MQTT topic.\r
218  */\r
219 #define JOBS_START_NEXT_OPERATION_STRING              "/jobs/start-next"\r
220 \r
221 /**\r
222  * @brief The length of #JOBS_START_NEXT_OPERATION_STRING.\r
223  */\r
224 #define JOBS_START_NEXT_OPERATION_STRING_LENGTH       ( ( uint16_t ) ( sizeof( JOBS_START_NEXT_OPERATION_STRING ) - 1 ) )\r
225 \r
226 /**\r
227  * @brief The string representing a Jobs DESCRIBE operation in a Jobs MQTT topic.\r
228  *\r
229  * This string should be placed after a Job ID.\r
230  */\r
231 #define JOBS_DESCRIBE_OPERATION_STRING                "/get"\r
232 \r
233 /**\r
234  * @brief The length of #JOBS_DESCRIBE_OPERATION_STRING.\r
235  */\r
236 #define JOBS_DESCRIBE_OPERATION_STRING_LENGTH         ( ( uint16_t ) ( sizeof( JOBS_DESCRIBE_OPERATION_STRING ) - 1 ) )\r
237 \r
238 /**\r
239  * @brief The string representing a Jobs UPDATE operation in a Jobs MQTT topic.\r
240  *\r
241  * This string should be placed after a Job ID.\r
242  */\r
243 #define JOBS_UPDATE_OPERATION_STRING                  "/update"\r
244 \r
245 /**\r
246  * @brief The length of #JOBS_UPDATE_OPERATION_STRING.\r
247  *\r
248  * This length excludes the length of the placeholder %s.\r
249  */\r
250 #define JOBS_UPDATE_OPERATION_STRING_LENGTH           ( ( uint16_t ) ( sizeof( JOBS_UPDATE_OPERATION_STRING ) - 1 ) )\r
251 \r
252 /**\r
253  * @brief The string representing the Jobs MQTT topic for receiving notifications\r
254  * of pending Jobs.\r
255  */\r
256 #define JOBS_NOTIFY_PENDING_CALLBACK_STRING           "/jobs/notify"\r
257 \r
258 /**\r
259  * @brief The length of #JOBS_NOTIFY_PENDING_CALLBACK_STRING.\r
260  */\r
261 #define JOBS_NOTIFY_PENDING_CALLBACK_STRING_LENGTH    ( ( uint16_t ) ( sizeof( JOBS_NOTIFY_PENDING_CALLBACK_STRING ) - 1 ) )\r
262 \r
263 /**\r
264  * @brief The string representing the Jobs MQTT topic for receiving notifications\r
265  * of the next pending Job.\r
266  */\r
267 #define JOBS_NOTIFY_NEXT_CALLBACK_STRING              "/jobs/notify-next"\r
268 \r
269 /**\r
270  * @brief The length of #JOBS_NOTIFY_NEXT_CALLBACK_STRING.\r
271  */\r
272 #define JOBS_NOTIFY_NEXT_CALLBACK_STRING_LENGTH       ( ( uint16_t ) ( sizeof( JOBS_NOTIFY_NEXT_CALLBACK_STRING ) - 1 ) )\r
273 \r
274 /**\r
275  * @brief The maximum length of a Job ID, per AWS IoT Service Limits.\r
276  *\r
277  * See https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html#job-limits\r
278  */\r
279 #define JOBS_MAX_ID_LENGTH                            ( 64 )\r
280 \r
281 /**\r
282  * @brief The maximum value of the Jobs step timeout, per AWS IoT Service Limits.\r
283  *\r
284  * See https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html#job-limits\r
285  */\r
286 #define JOBS_MAX_TIMEOUT                              ( 10080 )\r
287 \r
288 /**\r
289  * @brief A limit on the maximum length of a Jobs status details, per AWS IoT\r
290  * Service Limits.\r
291  *\r
292  * See https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html#job-limits\r
293  *\r
294  * This is actually the limit on the length of an entire Jobs document; but the\r
295  * status details must also not exceed this length,\r
296  */\r
297 #define JOBS_MAX_STATUS_DETAILS_LENGTH                ( 32768 )\r
298 \r
299 /**\r
300  * @brief The length of the longest Jobs topic suffix.\r
301  *\r
302  * This is the length of the longest Job ID, plus the length of the "UPDATE"\r
303  * operation suffix, plus the length of "/jobs/".\r
304  */\r
305 #define JOBS_LONGEST_SUFFIX_LENGTH                    ( JOBS_MAX_ID_LENGTH + JOBS_UPDATE_OPERATION_STRING_LENGTH + 6 )\r
306 \r
307 /*------------------------ Jobs internal data types -------------------------*/\r
308 \r
309 /**\r
310  * @brief Enumerations representing each of the Jobs library's API functions.\r
311  */\r
312 typedef enum _jobsOperationType\r
313 {\r
314     /* Jobs operations. */\r
315     JOBS_GET_PENDING = 0, /**< @ref jobs_function_getpendingasync */\r
316     JOBS_START_NEXT = 1,  /**< @ref jobs_function_startnextasync */\r
317     JOBS_DESCRIBE = 2,    /**< @ref jobs_function_describeasync */\r
318     JOBS_UPDATE = 3,      /**< @ref jobs_function_updateasync */\r
319 \r
320     /* Jobs callbacks. */\r
321     SET_NOTIFY_PENDING_CALLBACK = 4, /**< @ref jobs_function_setnotifypendingcallback */\r
322     SET_NOTIFY_NEXT_CALLBACK = 5     /**< @ref jobs_function_setnotifynextcallback */\r
323 } _jobsOperationType_t;\r
324 \r
325 /**\r
326  * @brief Enumerations representing each of the Jobs callback functions.\r
327  */\r
328 typedef enum _jobsCallbackType\r
329 {\r
330     NOTIFY_PENDING_CALLBACK = 0, /**< Pending Job notification callback. */\r
331     NOTIFY_NEXT_CALLBACK = 1     /**< Next Job notification callback. */\r
332 } _jobsCallbackType_t;\r
333 \r
334 /**\r
335  * @brief Parameter to #_AwsIotJobs_GenerateJsonRequest.\r
336  */\r
337 typedef union _jsonRequestContents\r
338 {\r
339     const AwsIotJobsUpdateInfo_t * pUpdateInfo; /**< @brief Valid for #JOBS_START_NEXT and #JOBS_UPDATE. */\r
340 \r
341     struct\r
342     {\r
343         int32_t executionNumber; /**< @brief Execution number. */\r
344         bool includeJobDocument; /**< @brief Whether the response should include the Job document. */\r
345     } describe;                  /**< @brief Valid for #JOBS_DESCRIBE. */\r
346 } _jsonRequestContents_t;\r
347 \r
348 /**\r
349  * @brief Represents a Jobs subscriptions object.\r
350  *\r
351  * These structures are stored in a list.\r
352  */\r
353 typedef struct _jobsSubscription\r
354 {\r
355     IotLink_t link;                                      /**< @brief List link member. */\r
356 \r
357     int32_t operationReferences[ JOBS_OPERATION_COUNT ]; /**< @brief Reference counters for Jobs operation topics. */\r
358     int32_t callbackReferences;                          /**< @brief Reference counter for Jobs callbacks. */\r
359 \r
360     /** @brief Jobs callbacks for this Thing. */\r
361     AwsIotJobsCallbackInfo_t callbacks[ JOBS_CALLBACK_COUNT ][ AWS_IOT_JOBS_NOTIFY_CALLBACKS ];\r
362 \r
363     /**\r
364      * @brief Buffer allocated for removing Jobs topics.\r
365      *\r
366      * This buffer is pre-allocated to ensure that memory is available when\r
367      * unsubscribing.\r
368      */\r
369     char * pTopicBuffer;\r
370 \r
371     size_t thingNameLength; /**< @brief Length of Thing Name. */\r
372     char pThingName[];      /**< @brief Thing Name associated with this subscriptions object. */\r
373 } _jobsSubscription_t;\r
374 \r
375 /**\r
376  * @brief Internal structure representing a single Jobs operation.\r
377  *\r
378  * A list of these structures keeps track of all in-progress Jobs operations.\r
379  */\r
380 typedef struct _jobsOperation\r
381 {\r
382     IotLink_t link; /**< @brief List link member. */\r
383 \r
384     /* Basic operation information. */\r
385     _jobsOperationType_t type;           /**< @brief Operation type. */\r
386     uint32_t flags;                      /**< @brief Flags passed to operation API function. */\r
387     AwsIotJobsError_t status;            /**< @brief Status of operation. */\r
388 \r
389     IotMqttConnection_t mqttConnection;  /**< @brief MQTT connection associated with this operation. */\r
390     _jobsSubscription_t * pSubscription; /**< @brief Jobs subscriptions object associated with this operation. */\r
391 \r
392     /* Jobs request information. */\r
393     const char * pJobsRequest; /**< @brief JSON document to send to the Jobs service. */\r
394     size_t jobsRequestLength;  /**< @brief Length of #_jobsOperation_t.pJobsRequest. */\r
395 \r
396     const char * pClientToken; /**< @brief Client token sent with request. */\r
397     size_t clientTokenLength;  /**< @brief Length of #_jobsOperation_t.pClientToken. */\r
398 \r
399     /* Jobs response information. */\r
400     const char * pJobsResponse; /**< @brief Response received from the Jobs service. */\r
401     size_t jobsResponseLength;  /**< @brief Length of #_jobsOperation_t.pJobsResponse. */\r
402 \r
403     /**\r
404      * @brief Function to allocate memory for an incoming Jobs response.\r
405      *\r
406      * Only used when the flag #AWS_IOT_JOBS_FLAG_WAITABLE is set.\r
407      */\r
408     void * ( *mallocResponse )( size_t );\r
409 \r
410     /* How to notify of an operation's completion. */\r
411     union\r
412     {\r
413         IotSemaphore_t waitSemaphore;      /**< @brief Semaphore to be used with @ref jobs_function_wait. */\r
414         AwsIotJobsCallbackInfo_t callback; /**< @brief User-provided callback function and parameter. */\r
415     } notify;                              /**< @brief How to notify of an operation's completion. */\r
416 \r
417     size_t jobIdLength;                    /**< @brief Length of #_jobsOperation_t.pJobId. */\r
418     char pJobId[];                         /**< @brief Job ID, saved for DESCRIBE and UPDATE operations. */\r
419 } _jobsOperation_t;\r
420 \r
421 /* Declarations of names printed in logs. */\r
422 #if LIBRARY_LOG_LEVEL > IOT_LOG_NONE\r
423     extern const char * const _pAwsIotJobsOperationNames[];\r
424     extern const char * const _pAwsIotJobsCallbackNames[];\r
425 #endif\r
426 \r
427 /* Declarations of variables for internal Jobs files. */\r
428 extern uint32_t _AwsIotJobsMqttTimeoutMs;\r
429 extern IotListDouble_t _AwsIotJobsPendingOperations;\r
430 extern IotListDouble_t _AwsIotJobsSubscriptions;\r
431 extern IotMutex_t _AwsIotJobsPendingOperationsMutex;\r
432 extern IotMutex_t _AwsIotJobsSubscriptionsMutex;\r
433 \r
434 /*------------------------ Jobs operation functions -------------------------*/\r
435 \r
436 /**\r
437  * @brief Create a record for a new in-progress Jobs operation.\r
438  *\r
439  * @param[in] type The type of Jobs operation for the request.\r
440  * @param[in] pRequestInfo Common Jobs request parameters.\r
441  * @param[in] pRequestContents Additional values to place in the JSON document,\r
442  * depending on `type`.\r
443  * @param[in] flags Flags variables passed to a user-facing Jobs function.\r
444  * @param[in] pCallbackInfo User-provided callback function and parameter.\r
445  * @param[out] pNewOperation Set to point to the new operation on success.\r
446  *\r
447  * @return #AWS_IOT_JOBS_SUCCESS or #AWS_IOT_JOBS_NO_MEMORY\r
448  */\r
449 AwsIotJobsError_t _AwsIotJobs_CreateOperation( _jobsOperationType_t type,\r
450                                                const AwsIotJobsRequestInfo_t * pRequestInfo,\r
451                                                const _jsonRequestContents_t * pRequestContents,\r
452                                                uint32_t flags,\r
453                                                const AwsIotJobsCallbackInfo_t * pCallbackInfo,\r
454                                                _jobsOperation_t ** pNewOperation );\r
455 \r
456 /**\r
457  * @brief Free resources used to record a Jobs operation. This is called when\r
458  * the operation completes.\r
459  *\r
460  * @param[in] pData The operation which completed. This parameter is of type\r
461  * `void*` to match the signature of [free]\r
462  * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
463  */\r
464 void _AwsIotJobs_DestroyOperation( void * pData );\r
465 \r
466 /**\r
467  * @brief Fill a buffer with a Jobs topic.\r
468  *\r
469  * @param[in] type One of: GET PENDING, START NEXT, DESCRIBE, or UPDATE.\r
470  * @param[in] pRequestInfo Common Jobs request parameters.\r
471  * @param[out] pTopicBuffer Address of the buffer for the Jobs topic. If the\r
472  * pointer at this address is `NULL`, this function will allocate a new buffer;\r
473  * otherwise, it will use the provided buffer.\r
474  * @param[out] pOperationTopicLength Length of the Jobs operation topic (excluding\r
475  * any suffix) placed in `pTopicBuffer`.\r
476  *\r
477  * @warning This function does not check the length of `pTopicBuffer`! Any provided\r
478  * buffer must be large enough to accommodate the full Jobs topic, plus\r
479  * #JOBS_LONGEST_SUFFIX_LENGTH.\r
480  *\r
481  * @return #AWS_IOT_JOBS_SUCCESS or #AWS_IOT_JOBS_NO_MEMORY. This function\r
482  * will not return #AWS_IOT_JOBS_NO_MEMORY when a buffer is provided.\r
483  */\r
484 AwsIotJobsError_t _AwsIotJobs_GenerateJobsTopic( _jobsOperationType_t type,\r
485                                                  const AwsIotJobsRequestInfo_t * pRequestInfo,\r
486                                                  char ** pTopicBuffer,\r
487                                                  uint16_t * pOperationTopicLength );\r
488 \r
489 /**\r
490  * @brief Process a Jobs operation by sending the necessary MQTT packets.\r
491  *\r
492  * @param[in] pRequestInfo Common Jobs request parameters.\r
493  * @param[in] pOperation Operation data to process.\r
494  *\r
495  * @return #AWS_IOT_JOBS_STATUS_PENDING on success. On error, one of\r
496  * #AWS_IOT_JOBS_NO_MEMORY or #AWS_IOT_JOBS_MQTT_ERROR.\r
497  */\r
498 AwsIotJobsError_t _AwsIotJobs_ProcessOperation( const AwsIotJobsRequestInfo_t * pRequestInfo,\r
499                                                 _jobsOperation_t * pOperation );\r
500 \r
501 /*----------------------- Jobs subscription functions -----------------------*/\r
502 \r
503 /**\r
504  * @brief Find a Jobs subscription object. May create a new subscription object\r
505  * and adds it to the subscription list if not found.\r
506  *\r
507  * @param[in] pThingName Thing Name in the subscription object.\r
508  * @param[in] thingNameLength Length of `pThingName`.\r
509  * @param[in] createIfNotFound If `true`, attempt to create a new subscription\r
510  * object if no match is found.\r
511  *\r
512  * @return Pointer to a Jobs subscription object, either found or newly\r
513  * allocated. Returns `NULL` if no subscription object is found and a new\r
514  * subscription object could not be allocated.\r
515  *\r
516  * @note This function should be called with the subscription list mutex locked.\r
517  */\r
518 _jobsSubscription_t * _AwsIotJobs_FindSubscription( const char * pThingName,\r
519                                                     size_t thingNameLength,\r
520                                                     bool createIfNotFound );\r
521 \r
522 /**\r
523  * @brief Remove a Jobs subscription object from the subscription list if\r
524  * unreferenced.\r
525  *\r
526  * @param[in] pSubscription Subscription object to check. If this object has no\r
527  * active references, it is removed from the subscription list.\r
528  * @param[out] pRemovedSubscription Removed subscription object, if any. Optional;\r
529  * pass `NULL` to ignore. If not `NULL`, this parameter will be set to the removed\r
530  * subscription and that subscription will not be destroyed.\r
531  *\r
532  * @note This function should be called with the subscription list mutex locked.\r
533  */\r
534 void _AwsIotJobs_RemoveSubscription( _jobsSubscription_t * pSubscription,\r
535                                      _jobsSubscription_t ** pRemovedSubscription );\r
536 \r
537 /**\r
538  * @brief Free resources used for a Jobs subscription object.\r
539  *\r
540  * @param[in] pData The subscription object to destroy. This parameter is of type\r
541  * `void*` to match the signature of [free]\r
542  * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
543  */\r
544 void _AwsIotJobs_DestroySubscription( void * pData );\r
545 \r
546 /**\r
547  * @brief Increment the reference count of a Jobs subscriptions object.\r
548  *\r
549  * Also adds MQTT subscriptions if necessary.\r
550  *\r
551  * @param[in] pOperation The operation for which the reference count should be\r
552  * incremented.\r
553  * @param[in] pTopicBuffer Topic buffer containing the operation topic, used if\r
554  * subscriptions need to be added.\r
555  * @param[in] operationTopicLength The length of the operation topic in `pTopicBuffer`.\r
556  * @param[in] callback MQTT callback function for when this operation completes.\r
557  *\r
558  * @warning This function does not check the length of `pTopicBuffer`! Any provided\r
559  * buffer must already contain the Jobs operation topic, plus enough space for the\r
560  * status suffix.\r
561  *\r
562  * @return #AWS_IOT_JOBS_SUCCESS on success. On error, one of\r
563  * #AWS_IOT_JOBS_NO_MEMORY or #AWS_IOT_JOBS_MQTT_ERROR.\r
564  *\r
565  * @note This function should be called with the subscription list mutex locked.\r
566  */\r
567 AwsIotJobsError_t _AwsIotJobs_IncrementReferences( _jobsOperation_t * pOperation,\r
568                                                    char * pTopicBuffer,\r
569                                                    uint16_t operationTopicLength,\r
570                                                    AwsIotMqttCallbackFunction_t callback );\r
571 \r
572 /**\r
573  * @brief Decrement the reference count of a Jobs subscriptions object.\r
574  *\r
575  * Also removed MQTT subscriptions and deletes the subscription object if necessary.\r
576  *\r
577  * @param[in] pOperation The operation for which the reference count should be\r
578  * decremented.\r
579  * @param[in] pTopicBuffer Topic buffer containing the operation topic, used if\r
580  * subscriptions need to be removed.\r
581  * @param[out] pRemovedSubscription Set to point to a removed subscription.\r
582  * Optional; pass `NULL` to ignore. If not `NULL`, this function will not destroy\r
583  * a removed subscription.\r
584  *\r
585  * @warning This function does not check the length of `pTopicBuffer`! Any provided\r
586  * buffer must be large enough to accommodate the full Jobs topic, plus\r
587  * #JOBS_LONGEST_SUFFIX_LENGTH.\r
588  *\r
589  * @note This function should be called with the subscription list mutex locked.\r
590  */\r
591 void _AwsIotJobs_DecrementReferences( _jobsOperation_t * pOperation,\r
592                                       char * pTopicBuffer,\r
593                                       _jobsSubscription_t ** pRemovedSubscription );\r
594 \r
595 /*------------------------ Jobs serializer functions ------------------------*/\r
596 \r
597 /**\r
598  * @brief Generates a Jobs JSON request document from an #AwsIotJobsRequestInfo_t\r
599  * and an #AwsIotJobsUpdateInfo_t.\r
600  *\r
601  * @param[in] type The type of Jobs operation for the request.\r
602  * @param[in] pRequestInfo Common Jobs request parameters.\r
603  * @param[in] pRequestContents Additional values to place in the JSON document,\r
604  * depending on `type`.\r
605  * @param[in] pOperation Operation associated with the Jobs request.\r
606  *\r
607  * @return #AWS_IOT_JOBS_SUCCESS on success; otherwise, #AWS_IOT_JOBS_NO_MEMORY.\r
608  */\r
609 AwsIotJobsError_t _AwsIotJobs_GenerateJsonRequest( _jobsOperationType_t type,\r
610                                                    const AwsIotJobsRequestInfo_t * pRequestInfo,\r
611                                                    const _jsonRequestContents_t * pRequestContents,\r
612                                                    _jobsOperation_t * pOperation );\r
613 \r
614 /**\r
615  * @brief Parse a response received from the Jobs service.\r
616  *\r
617  * @param[in] status Either ACCEPTED or REJECTED.\r
618  * @param[in] pResponse The response received from the Jobs service.\r
619  * @param[in] responseLength Length of `pResponse`.\r
620  * @param[out] pOperation Associated Jobs operation, where parse results are\r
621  * written.\r
622  */\r
623 void _AwsIotJobs_ParseResponse( AwsIotStatus_t status,\r
624                                 const char * pResponse,\r
625                                 size_t responseLength,\r
626                                 _jobsOperation_t * pOperation );\r
627 \r
628 #endif /* ifndef AWS_IOT_JOBS_INTERNAL_H_ */\r