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