1 /*
2  * FreeRTOS V202212.00
3  * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * https://www.FreeRTOS.org
23  * https://github.com/FreeRTOS
24  *
25  */
26 
27 /**
28  * @file subscription_manager.h
29  * @brief Functions for managing MQTT subscriptions.
30  */
31 #ifndef SUBSCRIPTION_MANAGER_H
32 #define SUBSCRIPTION_MANAGER_H
33 
34 /**************************************************/
35 /******* DO NOT CHANGE the following order ********/
36 /**************************************************/
37 
38 /* Logging related header files are required to be included in the following order:
39  * 1. Include the header file "logging_levels.h".
40  * 2. Define LIBRARY_LOG_NAME and  LIBRARY_LOG_LEVEL.
41  * 3. Include the header file "logging_stack.h".
42  */
43 
44 /* Include header that defines log levels. */
45 #include "logging_levels.h"
46 
47 /* Logging configuration for the Subscription Manager module. */
48 #ifndef LIBRARY_LOG_NAME
49     #define LIBRARY_LOG_NAME     "Subscription Manager"
50 #endif
51 #ifndef LIBRARY_LOG_LEVEL
52     #define LIBRARY_LOG_LEVEL    LOG_ERROR
53 #endif
54 
55 #include "logging_stack.h"
56 
57 
58 /* Demo config include. */
59 #include "demo_config.h"
60 
61 /* core MQTT include. */
62 #include "core_mqtt.h"
63 
64 
65 /**
66  * @brief Maximum number of subscriptions maintained by the subscription manager
67  * simultaneously in a list.
68  */
69 #ifndef SUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS
70     #define SUBSCRIPTION_MANAGER_MAX_SUBSCRIPTIONS    10U
71 #endif
72 
73 /**
74  * @brief Callback function called when receiving a publish.
75  *
76  * @param[in] pvIncomingPublishCallbackContext The incoming publish callback context.
77  * @param[in] pxPublishInfo Deserialized publish information.
78  */
79 typedef void (* IncomingPubCallback_t )( void * pvIncomingPublishCallbackContext,
80                                          MQTTPublishInfo_t * pxPublishInfo );
81 
82 /**
83  * @brief An element in the list of subscriptions.
84  *
85  * This subscription manager implementation expects that the array of the
86  * subscription elements used for storing subscriptions to be initialized to 0.
87  *
88  * @note This implementation allows multiple tasks to subscribe to the same topic.
89  * In this case, another element is added to the subscription list, differing
90  * in the intended publish callback. Also note that the topic filters are not
91  * copied in the subscription manager and hence the topic filter strings need to
92  * stay in scope until unsubscribed.
93  */
94 typedef struct subscriptionElement
95 {
96     IncomingPubCallback_t pxIncomingPublishCallback;
97     void * pvIncomingPublishCallbackContext;
98     uint16_t usFilterStringLength;
99     const char * pcSubscriptionFilterString;
100 } SubscriptionElement_t;
101 
102 /**
103  * @brief Add a subscription to the subscription list.
104  *
105  * @note Multiple tasks can be subscribed to the same topic with different
106  * context-callback pairs. However, a single context-callback pair may only be
107  * associated to the same topic filter once.
108  *
109  * @param[in] pxSubscriptionList  The pointer to the subscription list array.
110  * @param[in] pcTopicFilterString Topic filter string of subscription.
111  * @param[in] usTopicFilterLength Length of topic filter string.
112  * @param[in] pxIncomingPublishCallback Callback function for the subscription.
113  * @param[in] pvIncomingPublishCallbackContext Context for the subscription callback.
114  *
115  * @return `true` if subscription added or exists, `false` if insufficient memory.
116  */
117 bool addSubscription( SubscriptionElement_t * pxSubscriptionList,
118                       const char * pcTopicFilterString,
119                       uint16_t usTopicFilterLength,
120                       IncomingPubCallback_t pxIncomingPublishCallback,
121                       void * pvIncomingPublishCallbackContext );
122 
123 /**
124  * @brief Remove a subscription from the subscription list.
125  *
126  * @note If the topic filter exists multiple times in the subscription list,
127  * then every instance of the subscription will be removed.
128  *
129  * @param[in] pxSubscriptionList  The pointer to the subscription list array.
130  * @param[in] pcTopicFilterString Topic filter of subscription.
131  * @param[in] usTopicFilterLength Length of topic filter.
132  */
133 void removeSubscription( SubscriptionElement_t * pxSubscriptionList,
134                          const char * pcTopicFilterString,
135                          uint16_t usTopicFilterLength );
136 
137 /**
138  * @brief Handle incoming publishes by invoking the callbacks registered
139  * for the incoming publish's topic filter.
140  *
141  * @param[in] pxSubscriptionList  The pointer to the subscription list array.
142  * @param[in] pxPublishInfo Info of incoming publish.
143  *
144  * @return `true` if an application callback could be invoked;
145  *  `false` otherwise.
146  */
147 bool handleIncomingPublishes( SubscriptionElement_t * pxSubscriptionList,
148                               MQTTPublishInfo_t * pxPublishInfo );
149 
150 #endif /* SUBSCRIPTION_MANAGER_H */
151