-
Notifications
You must be signed in to change notification settings - Fork 24
/
azure_iot_mqtt.h
404 lines (354 loc) · 14.7 KB
/
azure_iot_mqtt.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
/* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License. */
/**
* @file azure_iot_mqtt.h
*
* @brief Azure IoT MQTT is the MQTT interface that AzureIoT middleware depends upon.
*
* @note This interface is private and subjected to change. Currently, there is only
* one implementation for this interface, which uses coreMQTT as underlying MQTT stack.
*/
#ifndef AZURE_IOT_MQTT_H
#define AZURE_IOT_MQTT_H
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "azure_iot_mqtt_port.h"
#include "azure_iot_transport_interface.h"
#define azureiotmqttPACKET_TYPE_CONNECT ( ( uint8_t ) 0x10U ) /**< @brief CONNECT (client-to-server). */
#define azureiotmqttPACKET_TYPE_CONNACK ( ( uint8_t ) 0x20U ) /**< @brief CONNACK (server-to-client). */
#define azureiotmqttPACKET_TYPE_PUBLISH ( ( uint8_t ) 0x30U ) /**< @brief PUBLISH (bidirectional). */
#define azureiotmqttPACKET_TYPE_PUBACK ( ( uint8_t ) 0x40U ) /**< @brief PUBACK (bidirectional). */
#define azureiotmqttPACKET_TYPE_PUBREC ( ( uint8_t ) 0x50U ) /**< @brief PUBREC (bidirectional). */
#define azureiotmqttPACKET_TYPE_PUBREL ( ( uint8_t ) 0x62U ) /**< @brief PUBREL (bidirectional). */
#define azureiotmqttPACKET_TYPE_PUBCOMP ( ( uint8_t ) 0x70U ) /**< @brief PUBCOMP (bidirectional). */
#define azureiotmqttPACKET_TYPE_SUBSCRIBE ( ( uint8_t ) 0x82U ) /**< @brief SUBSCRIBE (client-to-server). */
#define azureiotmqttPACKET_TYPE_SUBACK ( ( uint8_t ) 0x90U ) /**< @brief SUBACK (server-to-client). */
#define azureiotmqttPACKET_TYPE_UNSUBSCRIBE ( ( uint8_t ) 0xA2U ) /**< @brief UNSUBSCRIBE (client-to-server). */
#define azureiotmqttPACKET_TYPE_UNSUBACK ( ( uint8_t ) 0xB0U ) /**< @brief UNSUBACK (server-to-client). */
#define azureiotmqttPACKET_TYPE_PINGREQ ( ( uint8_t ) 0xC0U ) /**< @brief PINGREQ (client-to-server). */
#define azureiotmqttPACKET_TYPE_PINGRESP ( ( uint8_t ) 0xD0U ) /**< @brief PINGRESP (server-to-client). */
#define azureiotmqttPACKET_TYPE_DISCONNECT ( ( uint8_t ) 0xE0U ) /**< @brief DISCONNECT (client-to-server). */
#define azureiotmqttGET_PACKET_TYPE( ucType ) ( ( ucType ) & 0xF0U ) /**< @brief Get the packet type according to the MQTT spec */
/**
* @brief Quality of service values.
*/
typedef enum AzureIoTMQTTQoS
{
eAzureIoTMQTTQoS0 = 0, /** Delivery at most once. */
eAzureIoTMQTTQoS1 = 1, /** Delivery at least once. */
eAzureIoTMQTTQoS2 = 2 /** Delivery exactly once. */
} AzureIoTMQTTQoS_t;
/**
* @brief MQTT suback ack status states.
*/
typedef enum AzureIoTMQTTSubAckStatus
{
eMQTTSubAckSuccessQos0 = 0x00, /** Success with a maximum delivery at QoS 0. */
eMQTTSubAckSuccessQos1 = 0x01, /** Success with a maximum delivery at QoS 1. */
eMQTTSubAckSuccessQos2 = 0x02, /** Success with a maximum delivery at QoS 2. */
eMQTTSubAckFailure = 0x80 /** Failure. */
} AzureIoTMQTTSubAckStatus_t;
/**
* @brief Result values used for Azure IoT MQTT functions.
*/
typedef enum AzureIoTMQTTResult
{
eAzureIoTMQTTSuccess = 0, /** Function completed successfully. */
eAzureIoTMQTTBadParameter, /** At least one parameter was invalid. */
eAzureIoTMQTTNoMemory, /** A provided buffer was too small. */
eAzureIoTMQTTSendFailed, /** The transport send function failed. */
eAzureIoTMQTTRecvFailed, /** The transport receive function failed. */
eAzureIoTMQTTBadResponse, /** An invalid packet was received from the server. */
eAzureIoTMQTTServerRefused, /** The server refused a CONNECT or SUBSCRIBE. */
eAzureIoTMQTTNoDataAvailable, /** No data available from the transport interface. */
eAzureIoTMQTTIllegalState, /** An illegal state in the state record. */
eAzureIoTMQTTStateCollision, /** A collision with an existing state record entry. */
eAzureIoTMQTTKeepAliveTimeout, /** Timeout while waiting for PINGRESP. */
eAzureIoTMQTTFailed /** Function failed with Unknown Error. */
} AzureIoTMQTTResult_t;
/**
* @brief Connection info for the MQTT client.
*/
typedef struct AzureIoTMQTTConnectInfo
{
/**
* @brief Whether to establish a new, clean session or resume a previous session.
*/
bool xCleanSession;
/**
* @brief MQTT keep alive period, in seconds.
*/
uint16_t usKeepAliveSeconds;
/**
* @brief MQTT client identifier. Must be unique per client.
*/
const uint8_t * pcClientIdentifier;
/**
* @brief Length of the client identifier.
*/
uint16_t usClientIdentifierLength;
/**
* @brief MQTT user name. Set to NULL if not used.
*/
const uint8_t * pcUserName;
/**
* @brief Length of MQTT user name. Set to 0 if not used.
* or set pcUserName to NULL.
*/
uint16_t usUserNameLength;
/**
* @brief MQTT password. Set to NULL if not used.
*/
const uint8_t * pcPassword;
/**
* @brief Length of MQTT password. Set to 0 if not used
* or set pcPassword to NULL.
*/
uint16_t usPasswordLength;
} AzureIoTMQTTConnectInfo_t;
/**
* @brief Subscription info for the MQTT client.
*/
typedef struct AzureIoTMQTTSubscribeInfo
{
/**
* @brief Quality of Service for subscription.
*/
AzureIoTMQTTQoS_t xQoS;
/**
* @brief Topic filter to subscribe to.
*/
const uint8_t * pcTopicFilter;
/**
* @brief Length of subscription topic filter.
*/
uint16_t usTopicFilterLength;
} AzureIoTMQTTSubscribeInfo_t;
/**
* @brief Publish info for the MQTT client.
*/
typedef struct AzureIoTMQTTPublishInfo
{
/**
* @brief Quality of Service for message.
*/
AzureIoTMQTTQoS_t xQOS;
/**
* @brief Whether this is a retained message.
*/
bool xRetain;
/**
* @brief Whether this is a duplicate publish message.
*/
bool xDup;
/**
* @brief Topic name on which the message is published.
*/
const uint8_t * pcTopicName;
/**
* @brief Length of topic name.
*/
uint16_t usTopicNameLength;
/**
* @brief Message payload.
*/
const void * pvPayload;
/**
* @brief Message payload length.
*/
size_t xPayloadLength;
} AzureIoTMQTTPublishInfo_t;
/**
* @brief MQTT packet deserialized info for the MQTT client.
*/
typedef struct AzureIoTMQTTDeserializedInfo
{
uint16_t usPacketIdentifier; /**< @brief Packet ID of deserialized packet. */
AzureIoTMQTTPublishInfo_t * pxPublishInfo; /**< @brief Pointer to deserialized publish info. */
AzureIoTMQTTResult_t xDeserializationResult; /**< @brief Return code of deserialization. */
} AzureIoTMQTTDeserializedInfo_t;
/**
* @brief MQTT packet info for the MQTT client.
*/
typedef struct AzureIoTMQTTPacketInfo
{
/**
* @brief Type of incoming MQTT packet.
*/
uint8_t ucType;
/**
* @brief Remaining serialized data in the MQTT packet.
*/
uint8_t * pucRemainingData;
/**
* @brief Length of remaining serialized data.
*/
size_t xRemainingLength;
} AzureIoTMQTTPacketInfo_t;
/**
* @brief Typedef of the MQTT client which is defined by the MQTT port.
*/
typedef AzureIoTMQTT_t * AzureIoTMQTTHandle_t;
/**
* @brief The time function to be used for MQTT functionality.
*
* @note Must return the time since Unix epoch.
*/
typedef uint32_t ( * AzureIoTMQTTGetCurrentTimeFunc_t )( void );
/**
* @brief The callback function which will be invoked on receipt of an MQTT message.
*/
typedef void ( * AzureIoTMQTTEventCallback_t )( AzureIoTMQTTHandle_t pContext,
struct AzureIoTMQTTPacketInfo * pxPacketInfo,
struct AzureIoTMQTTDeserializedInfo * pxDeserializedInfo );
/**
* @brief Initialize an AzureIoTMQTT context.
*
* @note This function is for integration of the Azure IoT middleware and
* the underlying MQTT stack and should in general not be invoked by
* applications directly.
*
* @param[in] xContext The AzureIoTMQTT context to initialize.
* @param[in] pxTransportInterface The transport interface to use with the context.
* @param[in] xGetTimeFunction The time utility function to use with the context.
* @param[in] xUserCallback The user callback to use with the context to
* notify about incoming packet events.
* @param[in] pucNetworkBuffer Network buffer provided for the context.
* @param[in] xNetworkBufferLength Length of network buffer.
*
* @return An #AzureIoTMQTTResult_t with the result of the operation.
*/
AzureIoTMQTTResult_t AzureIoTMQTT_Init( AzureIoTMQTTHandle_t xContext,
const AzureIoTTransportInterface_t * pxTransportInterface,
AzureIoTMQTTGetCurrentTimeFunc_t xGetTimeFunction,
AzureIoTMQTTEventCallback_t xUserCallback,
uint8_t * pucNetworkBuffer,
size_t xNetworkBufferLength );
/**
* @brief Establish an MQTT session.
*
* @note Last Will and Testament is not used with Azure IoT Hub.
*
* This function will send MQTT CONNECT packet and receive a CONNACK packet. The
* send and receive from the network is done through the transport interface.
*
* @param[in] xContext Initialized AzureIoTMQTT context.
* @param[in] pxConnectInfo MQTT CONNECT packet information.
* @param[in] pxWillInfo Last Will and Testament. Pass NULL if Last Will and Testament is not used.
* @param[in] ulMilliseconds Maximum time in milliseconds to wait for a CONNACK packet.
* @param[out] pxSessionPresent Whether a previous session was present.
* Only relevant if not establishing a clean session.
*
* @return An #AzureIoTMQTTResult_t with the result of the operation.
*/
AzureIoTMQTTResult_t AzureIoTMQTT_Connect( AzureIoTMQTTHandle_t xContext,
const AzureIoTMQTTConnectInfo_t * pxConnectInfo,
const AzureIoTMQTTPublishInfo_t * pxWillInfo,
uint32_t ulMilliseconds,
bool * pxSessionPresent );
/**
* @brief Sends MQTT SUBSCRIBE for the given list of topic filters to
* the broker.
*
* @param[in] xContext Initialized AzureIoTMQTT context.
* @param[in] pxSubscriptionList List of MQTT subscription infos.
* @param[in] xSubscriptionCount The number of elements in pxSubscriptionList.
* @param[in] usPacketId Packet ID ( generated by #AzureIoTMQTT_GetPacketId ).
*
* @return An #AzureIoTMQTTResult_t with the result of the operation.
*/
AzureIoTMQTTResult_t AzureIoTMQTT_Subscribe( AzureIoTMQTTHandle_t xContext,
const AzureIoTMQTTSubscribeInfo_t * pxSubscriptionList,
size_t xSubscriptionCount,
uint16_t usPacketId );
/**
* @brief Publishes a message to the given topic name.
*
* @param[in] xContext Initialized AzureIoTMQTT context.
* @param[in] pxPublishInfo MQTT PUBLISH packet parameters.
* @param[in] usPacketId packet ID ( generated by #AzureIoTMQTT_GetPacketId ).
*
* @return An #AzureIoTMQTTResult_t with the result of the operation.
*/
AzureIoTMQTTResult_t AzureIoTMQTT_Publish( AzureIoTMQTTHandle_t xContext,
const AzureIoTMQTTPublishInfo_t * pxPublishInfo,
uint16_t usPacketId );
/**
* @brief Sends a MQTT PINGREQ to broker.
*
* @param[in] xContext Initialized AzureIoTMQTT context.
*
* @return An #AzureIoTMQTTResult_t with the result of the operation.
*/
AzureIoTMQTTResult_t AzureIoTMQTT_Ping( AzureIoTMQTTHandle_t xContext );
/**
* @brief Sends MQTT UNSUBSCRIBE for the given list of topic filters to
* the broker.
*
* @param[in] xContext Initialized AzureIoTMQTT context.
* @param[in] pxSubscriptionList List of MQTT subscription infos.
* @param[in] xSubscriptionCount The number of elements in pxSubscriptionList.
* @param[in] usPacketId packet ID ( generated by #AzureIoTMQTT_GetPacketId ).
*
* @return An #AzureIoTMQTTResult_t with the result of the operation.
*/
AzureIoTMQTTResult_t AzureIoTMQTT_Unsubscribe( AzureIoTMQTTHandle_t xContext,
const AzureIoTMQTTSubscribeInfo_t * pxSubscriptionList,
size_t xSubscriptionCount,
uint16_t usPacketId );
/**
* @brief Disconnect a MQTT session.
*
* @param[in] xContext Initialized AzureIoTMQTT context.
*
* @return An #AzureIoTMQTTResult_t with the result of the operation.
*/
AzureIoTMQTTResult_t AzureIoTMQTT_Disconnect( AzureIoTMQTTHandle_t xContext );
/**
* @brief Loop to receive packets from the transport interface. Handles keep
* alive.
*
* @param[in] xContext Initialized AzureIoTMQTT context.
* @param[in] ulMilliseconds Minimum time in milliseconds that the process loop will
* run, unless an error occurs.
*
* @return An #AzureIoTMQTTResult_t with the result of the operation.
*/
AzureIoTMQTTResult_t AzureIoTMQTT_ProcessLoop( AzureIoTMQTTHandle_t xContext,
uint32_t ulMilliseconds );
/**
* @brief Get a packet ID.
*
* @param[in] xContext Initialized AzureIoTMQTT context.
*
* @return A non-zero number.
*/
uint16_t AzureIoTMQTT_GetPacketId( AzureIoTMQTTHandle_t xContext );
/**
* @brief Parses the payload of a MQTT SUBACK packet that contains status codes
* corresponding to topic filter subscription requests from the original
* subscribe packet.
*
* Each return code in the SUBACK packet corresponds to a topic filter in the
* SUBSCRIBE Packet being acknowledged.
* The status codes can be one of the following:
* - 0x00 - Success - Maximum QoS 0
* - 0x01 - Success - Maximum QoS 1
* - 0x02 - Success - Maximum QoS 2
* - 0x80 - Failure
* Refer to #AzureIoTMQTTSubAckStatus_t for the status codes.
*
* @param[in] pxSubackPacket The SUBACK packet whose payload is to be parsed.
* @param[out] ppucPayloadStart This is populated with the starting address
* of the payload (or return codes for topic filters) in the SUBACK packet.
* @param[out] pxPayloadSize This is populated with the size of the payload
* in the SUBACK packet. It represents the number of topic filters whose
* SUBACK status is present in the packet.
*
* @return An #AzureIoTMQTTResult_t with the result of the operation.
*/
AzureIoTMQTTResult_t AzureIoTMQTT_GetSubAckStatusCodes( const AzureIoTMQTTPacketInfo_t * pxSubackPacket,
uint8_t ** ppucPayloadStart,
size_t * pxPayloadSize );
#endif /* AZURE_IOT_MQTT_H */