1 /*
2 * coreMQTT Agent v1.2.0
3 * Copyright (C) 2021 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
23 /**
24 * @file core_mqtt_agent_command_functions.c
25 * @brief Implements functions to process MQTT agent commands.
26 */
27
28 /* Standard includes. */
29 #include <string.h>
30 #include <stdio.h>
31 #include <assert.h>
32
33 /* MQTT agent include. */
34 #include "core_mqtt_agent.h"
35
36 /* Header include. */
37 #include "core_mqtt_agent_command_functions.h"
38
39 /* MQTT Agent default logging configuration include. */
40 #include "core_mqtt_agent_default_logging.h"
41
42 /*-----------------------------------------------------------*/
43
MQTTAgentCommand_ProcessLoop(MQTTAgentContext_t * pMqttAgentContext,void * pUnusedArg,MQTTAgentCommandFuncReturns_t * pReturnFlags)44 MQTTStatus_t MQTTAgentCommand_ProcessLoop( MQTTAgentContext_t * pMqttAgentContext,
45 void * pUnusedArg,
46 MQTTAgentCommandFuncReturns_t * pReturnFlags )
47 {
48 ( void ) pUnusedArg;
49 ( void ) pMqttAgentContext;
50 assert( pReturnFlags != NULL );
51
52 ( void ) memset( pReturnFlags, 0x00, sizeof( MQTTAgentCommandFuncReturns_t ) );
53 pReturnFlags->runProcessLoop = true;
54
55 return MQTTSuccess;
56 }
57
58 /*-----------------------------------------------------------*/
59
MQTTAgentCommand_Publish(MQTTAgentContext_t * pMqttAgentContext,void * pPublishArg,MQTTAgentCommandFuncReturns_t * pReturnFlags)60 MQTTStatus_t MQTTAgentCommand_Publish( MQTTAgentContext_t * pMqttAgentContext,
61 void * pPublishArg,
62 MQTTAgentCommandFuncReturns_t * pReturnFlags )
63 {
64 const MQTTPublishInfo_t * pPublishInfo;
65 MQTTStatus_t ret;
66
67 assert( pMqttAgentContext != NULL );
68 assert( pPublishArg != NULL );
69 assert( pReturnFlags != NULL );
70
71 ( void ) memset( pReturnFlags, 0x00, sizeof( MQTTAgentCommandFuncReturns_t ) );
72 pPublishInfo = ( const MQTTPublishInfo_t * ) ( pPublishArg );
73
74 if( pPublishInfo->qos != MQTTQoS0 )
75 {
76 pReturnFlags->packetId = MQTT_GetPacketId( &( pMqttAgentContext->mqttContext ) );
77 }
78
79 LogInfo( ( "Publishing message to %.*s.\n", ( int ) pPublishInfo->topicNameLength, pPublishInfo->pTopicName ) );
80 ret = MQTT_Publish( &( pMqttAgentContext->mqttContext ), pPublishInfo, pReturnFlags->packetId );
81
82 /* Add to pending ack list, or call callback if QoS 0. */
83 pReturnFlags->addAcknowledgment = ( pPublishInfo->qos != MQTTQoS0 ) && ( ret == MQTTSuccess );
84 pReturnFlags->runProcessLoop = true;
85
86 return ret;
87 }
88
89 /*-----------------------------------------------------------*/
90
MQTTAgentCommand_Subscribe(MQTTAgentContext_t * pMqttAgentContext,void * pVoidSubscribeArgs,MQTTAgentCommandFuncReturns_t * pReturnFlags)91 MQTTStatus_t MQTTAgentCommand_Subscribe( MQTTAgentContext_t * pMqttAgentContext,
92 void * pVoidSubscribeArgs,
93 MQTTAgentCommandFuncReturns_t * pReturnFlags )
94 {
95 const MQTTAgentSubscribeArgs_t * pSubscribeArgs;
96 MQTTStatus_t ret;
97
98 assert( pMqttAgentContext != NULL );
99 assert( pVoidSubscribeArgs != NULL );
100 assert( pReturnFlags != NULL );
101
102 ( void ) memset( pReturnFlags, 0x00, sizeof( MQTTAgentCommandFuncReturns_t ) );
103 pSubscribeArgs = ( const MQTTAgentSubscribeArgs_t * ) ( pVoidSubscribeArgs );
104 pReturnFlags->packetId = MQTT_GetPacketId( &( pMqttAgentContext->mqttContext ) );
105
106 ret = MQTT_Subscribe( &( pMqttAgentContext->mqttContext ),
107 pSubscribeArgs->pSubscribeInfo,
108 pSubscribeArgs->numSubscriptions,
109 pReturnFlags->packetId );
110
111 pReturnFlags->addAcknowledgment = ( ret == MQTTSuccess );
112 pReturnFlags->runProcessLoop = true;
113
114 return ret;
115 }
116
117 /*-----------------------------------------------------------*/
118
MQTTAgentCommand_Unsubscribe(MQTTAgentContext_t * pMqttAgentContext,void * pVoidSubscribeArgs,MQTTAgentCommandFuncReturns_t * pReturnFlags)119 MQTTStatus_t MQTTAgentCommand_Unsubscribe( MQTTAgentContext_t * pMqttAgentContext,
120 void * pVoidSubscribeArgs,
121 MQTTAgentCommandFuncReturns_t * pReturnFlags )
122 {
123 const MQTTAgentSubscribeArgs_t * pSubscribeArgs;
124 MQTTStatus_t ret;
125
126 assert( pMqttAgentContext != NULL );
127 assert( pVoidSubscribeArgs != NULL );
128 assert( pReturnFlags != NULL );
129
130 ( void ) memset( pReturnFlags, 0x00, sizeof( MQTTAgentCommandFuncReturns_t ) );
131 pSubscribeArgs = ( const MQTTAgentSubscribeArgs_t * ) ( pVoidSubscribeArgs );
132 pReturnFlags->packetId = MQTT_GetPacketId( &( pMqttAgentContext->mqttContext ) );
133
134 ret = MQTT_Unsubscribe( &( pMqttAgentContext->mqttContext ),
135 pSubscribeArgs->pSubscribeInfo,
136 pSubscribeArgs->numSubscriptions,
137 pReturnFlags->packetId );
138
139 pReturnFlags->addAcknowledgment = ( ret == MQTTSuccess );
140 pReturnFlags->runProcessLoop = true;
141
142 return ret;
143 }
144
145 /*-----------------------------------------------------------*/
146
MQTTAgentCommand_Connect(MQTTAgentContext_t * pMqttAgentContext,void * pVoidConnectArgs,MQTTAgentCommandFuncReturns_t * pReturnFlags)147 MQTTStatus_t MQTTAgentCommand_Connect( MQTTAgentContext_t * pMqttAgentContext,
148 void * pVoidConnectArgs,
149 MQTTAgentCommandFuncReturns_t * pReturnFlags )
150 {
151 MQTTStatus_t ret;
152 MQTTAgentConnectArgs_t * pConnectInfo;
153
154 assert( pMqttAgentContext != NULL );
155 assert( pVoidConnectArgs != NULL );
156 assert( pReturnFlags != NULL );
157
158 pConnectInfo = ( MQTTAgentConnectArgs_t * ) ( pVoidConnectArgs );
159
160 ret = MQTT_Connect( &( pMqttAgentContext->mqttContext ),
161 pConnectInfo->pConnectInfo,
162 pConnectInfo->pWillInfo,
163 pConnectInfo->timeoutMs,
164 &( pConnectInfo->sessionPresent ) );
165
166 /* Resume a session if one existed, else clear the list of acknowledgments. */
167 if( ret == MQTTSuccess )
168 {
169 LogInfo( ( "Session present flag: %d", pConnectInfo->sessionPresent ) );
170 ret = MQTTAgent_ResumeSession( pMqttAgentContext,
171 pConnectInfo->sessionPresent );
172 }
173
174 ( void ) memset( pReturnFlags, 0x00, sizeof( MQTTAgentCommandFuncReturns_t ) );
175
176 return ret;
177 }
178
179 /*-----------------------------------------------------------*/
180
MQTTAgentCommand_Disconnect(MQTTAgentContext_t * pMqttAgentContext,void * pUnusedArg,MQTTAgentCommandFuncReturns_t * pReturnFlags)181 MQTTStatus_t MQTTAgentCommand_Disconnect( MQTTAgentContext_t * pMqttAgentContext,
182 void * pUnusedArg,
183 MQTTAgentCommandFuncReturns_t * pReturnFlags )
184 {
185 MQTTStatus_t ret;
186
187 ( void ) pUnusedArg;
188
189 assert( pMqttAgentContext != NULL );
190 assert( pReturnFlags != NULL );
191
192 ret = MQTT_Disconnect( &( pMqttAgentContext->mqttContext ) );
193
194 ( void ) memset( pReturnFlags, 0x00, sizeof( MQTTAgentCommandFuncReturns_t ) );
195 pReturnFlags->endLoop = true;
196
197 return ret;
198 }
199
200 /*-----------------------------------------------------------*/
201
MQTTAgentCommand_Ping(MQTTAgentContext_t * pMqttAgentContext,void * pUnusedArg,MQTTAgentCommandFuncReturns_t * pReturnFlags)202 MQTTStatus_t MQTTAgentCommand_Ping( MQTTAgentContext_t * pMqttAgentContext,
203 void * pUnusedArg,
204 MQTTAgentCommandFuncReturns_t * pReturnFlags )
205 {
206 MQTTStatus_t ret;
207
208 ( void ) pUnusedArg;
209
210 assert( pMqttAgentContext != NULL );
211 assert( pReturnFlags != NULL );
212
213 ret = MQTT_Ping( &( pMqttAgentContext->mqttContext ) );
214
215 ( void ) memset( pReturnFlags, 0x00, sizeof( MQTTAgentCommandFuncReturns_t ) );
216
217 pReturnFlags->runProcessLoop = true;
218
219 return ret;
220 }
221
222 /*-----------------------------------------------------------*/
223
MQTTAgentCommand_Terminate(MQTTAgentContext_t * pMqttAgentContext,void * pUnusedArg,MQTTAgentCommandFuncReturns_t * pReturnFlags)224 MQTTStatus_t MQTTAgentCommand_Terminate( MQTTAgentContext_t * pMqttAgentContext,
225 void * pUnusedArg,
226 MQTTAgentCommandFuncReturns_t * pReturnFlags )
227 {
228 MQTTStatus_t ret;
229
230 ( void ) pUnusedArg;
231
232 assert( pMqttAgentContext != NULL );
233 assert( pMqttAgentContext->agentInterface.releaseCommand != NULL );
234 assert( pReturnFlags != NULL );
235
236 LogInfo( ( "Terminating command loop.\n" ) );
237 ( void ) memset( pReturnFlags, 0x00, sizeof( MQTTAgentCommandFuncReturns_t ) );
238 pReturnFlags->endLoop = true;
239
240 ret = MQTTAgent_CancelAll( pMqttAgentContext );
241
242 return ret;
243 }
244
245 /*-----------------------------------------------------------*/
246