-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathMQTTClient.h
More file actions
1987 lines (1845 loc) · 85.4 KB
/
Copy pathMQTTClient.h
File metadata and controls
1987 lines (1845 loc) · 85.4 KB
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
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*******************************************************************************
* Copyright (c) 2009, 2024 IBM Corp., Ian Craggs and others
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* https://www.eclipse.org/legal/epl-2.0/
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs, Allan Stockdill-Mander - SSL updates
* Ian Craggs - multiple server connection support
* Ian Craggs - MQTT 3.1.1 support
* Ian Craggs - remove const from eyecatchers #168
*******************************************************************************/
/**
* @cond MQTTClient_internal
* @mainpage MQTT Client Library Internals
* In the beginning there was one MQTT C client library, MQTTClient, as implemented in MQTTClient.c
* This library was designed to be easy to use for applications which didn't mind if some of the calls
* blocked for a while. For instance, the MQTTClient_connect call will block until a successful
* connection has completed, or a connection has failed, which could be as long as the "connection
* timeout" interval, whose default is 30 seconds.
*
* However in mobile devices and other windowing environments, blocking on the GUI thread is a bad
* thing as it causes the user interface to freeze. Hence a new API, MQTTAsync, implemented
* in MQTTAsync.c, was devised. There are no blocking calls in this library, so it is well suited
* to GUI and mobile environments, at the expense of some extra complexity.
*
* Both libraries are designed to be sparing in the use of threads. So multiple client objects are
* handled by one or two threads, with a select call in Socket_getReadySocket(), used to determine
* when a socket has incoming data. This API is thread safe: functions may be called by multiple application
* threads, with the exception of ::MQTTClient_yield and ::MQTTClient_receive, which are intended
* for single threaded environments only.
*
* @endcond
* @cond MQTTClient_main
* @mainpage MQTT Client library for C (MQTTClient)
* © Copyright 2009, 2023 IBM Corp., Ian Craggs and others
*
* @brief An MQTT client library in C.
*
* These pages describe the original more synchronous API which might be
* considered easier to use. Some of the calls will block. For the new
* totally asynchronous API where no calls block, which is especially suitable
* for use in windowed environments, see the
* <a href="../../MQTTAsync/html/index.html">MQTT C Client Asynchronous API Documentation</a>.
* The MQTTClient API is not thread safe, whereas the MQTTAsync API is.
*
* An MQTT client application connects to MQTT-capable servers.
* A typical client is responsible for collecting information from a telemetry
* device and publishing the information to the server. It can also subscribe
* to topics, receive messages, and use this information to control the
* telemetry device.
*
* MQTT clients implement the published MQTT v3 protocol. You can write your own
* API to the MQTT protocol using the programming language and platform of your
* choice. This can be time-consuming and error-prone.
*
* To simplify writing MQTT client applications, this library encapsulates
* the MQTT v3 protocol for you. Using this library enables a fully functional
* MQTT client application to be written in a few lines of code.
* The information presented here documents the API provided
* by the MQTT Client library for C.
*
* <b>Using the client</b><br>
* Applications that use the client library typically use a similar structure:
* <ul>
* <li>Create a client object</li>
* <li>Set the options to connect to an MQTT server</li>
* <li>Set up callback functions if multi-threaded (asynchronous mode)
* operation is being used (see @ref async).</li>
* <li>Subscribe to any topics the client needs to receive</li>
* <li>Repeat until finished:</li>
* <ul>
* <li>Publish any messages the client needs to</li>
* <li>Handle any incoming messages</li>
* </ul>
* <li>Disconnect the client</li>
* <li>Free any memory being used by the client</li>
* </ul>
* Some simple examples are shown here:
* <ul>
* <li>@ref pubsync</li>
* <li>@ref pubasync</li>
* <li>@ref subasync</li>
* </ul>
* Additional information about important concepts is provided here:
* <ul>
* <li>@ref async</li>
* <li>@ref callbacks</li>
* <li>@ref wildcard</li>
* <li>@ref qos</li>
* <li>@ref tracing</li>
* </ul>
* @endcond
*/
/*
/// @cond EXCLUDE
*/
#if !defined(MQTTCLIENT_H)
#define MQTTCLIENT_H
#if defined(__cplusplus)
extern "C" {
#endif
#include <stdio.h>
/*
/// @endcond
*/
#include "MQTTExportDeclarations.h"
#include "MQTTProperties.h"
#include "MQTTReasonCodes.h"
#include "MQTTSubscribeOpts.h"
#if !defined(NO_PERSISTENCE)
#include "MQTTClientPersistence.h"
#else
#define MQTTCLIENT_PERSISTENCE_NONE 1
#endif
/**
* Return code: No error. Indicates successful completion of an MQTT client
* operation.
*/
#define MQTTCLIENT_SUCCESS 0
/**
* Return code: A generic error code indicating the failure of an MQTT client
* operation.
*/
#define MQTTCLIENT_FAILURE -1
/* error code -2 is MQTTCLIENT_PERSISTENCE_ERROR */
/**
* Return code: The client is disconnected.
*/
#define MQTTCLIENT_DISCONNECTED -3
/**
* Return code: The maximum number of messages allowed to be simultaneously
* in-flight has been reached.
*/
#define MQTTCLIENT_MAX_MESSAGES_INFLIGHT -4
/**
* Return code: An invalid UTF-8 string has been detected.
*/
#define MQTTCLIENT_BAD_UTF8_STRING -5
/**
* Return code: A NULL parameter has been supplied when this is invalid.
*/
#define MQTTCLIENT_NULL_PARAMETER -6
/**
* Return code: The topic has been truncated (the topic string includes
* embedded NULL characters). String functions will not access the full topic.
* Use the topic length value to access the full topic.
*/
#define MQTTCLIENT_TOPICNAME_TRUNCATED -7
/**
* Return code: A structure parameter does not have the correct eyecatcher
* and version number.
*/
#define MQTTCLIENT_BAD_STRUCTURE -8
/**
* Return code: A QoS value that falls outside of the acceptable range (0,1,2)
*/
#define MQTTCLIENT_BAD_QOS -9
/**
* Return code: Attempting SSL connection using non-SSL version of library
*/
#define MQTTCLIENT_SSL_NOT_SUPPORTED -10
/**
* Return code: unrecognized MQTT version
*/
#define MQTTCLIENT_BAD_MQTT_VERSION -11
/**
* Return code: protocol prefix in serverURI should be:
* @li @em tcp:// or @em mqtt:// - Insecure TCP
* @li @em ssl:// or @em mqtts:// - Encrypted SSL/TLS
* @li @em ws:// - Insecure websockets
* @li @em wss:// - Secure web sockets
* The TLS enabled prefixes (ssl, mqtts, wss) are only valid if a TLS
* version of the library is linked with.
*/
#define MQTTCLIENT_BAD_PROTOCOL -14
/**
* Return code: option not applicable to the requested version of MQTT
*/
#define MQTTCLIENT_BAD_MQTT_OPTION -15
/**
* Return code: call not applicable to the requested version of MQTT
*/
#define MQTTCLIENT_WRONG_MQTT_VERSION -16
/**
* Return code: 0 length will topic on connect
*/
#define MQTTCLIENT_0_LEN_WILL_TOPIC -17
/**
* Default MQTT version to connect with. Use 3.1.1 then fall back to 3.1
*/
#define MQTTVERSION_DEFAULT 0
/**
* MQTT version to connect with: 3.1
*/
#define MQTTVERSION_3_1 3
/**
* MQTT version to connect with: 3.1.1
*/
#define MQTTVERSION_3_1_1 4
/**
* MQTT version to connect with: 5
*/
#define MQTTVERSION_5 5
/**
* Bad return code from subscribe, as defined in the 3.1.1 specification
*/
#define MQTT_BAD_SUBSCRIBE 0x80
/**
* Initialization options
*/
typedef struct
{
/** The eyecatcher for this structure. Must be MQTG. */
char struct_id[4];
/** The version number of this structure. Must be 0 */
int struct_version;
/** 1 = we do openssl init, 0 = leave it to the application */
int do_openssl_init;
} MQTTClient_init_options;
#define MQTTClient_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 }
/**
* Global init of mqtt library. Call once on program start to set global behaviour.
* do_openssl_init - if mqtt library should initialize OpenSSL (1) or rely on the caller to do it before using the library (0)
*/
LIBMQTT_API void MQTTClient_global_init(MQTTClient_init_options* inits);
/**
* A handle representing an MQTT client. A valid client handle is available
* following a successful call to MQTTClient_create().
*/
typedef void* MQTTClient;
/**
* A value representing an MQTT message. A delivery token is returned to the
* client application when a message is published. The token can then be used to
* check that the message was successfully delivered to its destination (see
* MQTTClient_publish(),
* MQTTClient_publishMessage(),
* MQTTClient_deliveryComplete(),
* MQTTClient_waitForCompletion() and
* MQTTClient_getPendingDeliveryTokens()).
*/
typedef int MQTTClient_deliveryToken;
typedef int MQTTClient_token;
/**
* A structure representing the payload and attributes of an MQTT message. The
* message topic is not part of this structure (see MQTTClient_publishMessage(),
* MQTTClient_publish(), MQTTClient_receive(), MQTTClient_freeMessage()
* and MQTTClient_messageArrived()).
*/
typedef struct
{
/** The eyecatcher for this structure. must be MQTM. */
char struct_id[4];
/** The version number of this structure. Must be 0 or 1
* 0 indicates no message properties */
int struct_version;
/** The length of the MQTT message payload in bytes. */
int payloadlen;
/** A pointer to the payload of the MQTT message. */
void* payload;
/**
* The quality of service (QoS) assigned to the message.
* There are three levels of QoS:
* <DL>
* <DT><B>QoS0</B></DT>
* <DD>Fire and forget - the message may not be delivered</DD>
* <DT><B>QoS1</B></DT>
* <DD>At least once - the message will be delivered, but may be
* delivered more than once in some circumstances.</DD>
* <DT><B>QoS2</B></DT>
* <DD>Once and one only - the message will be delivered exactly once.</DD>
* </DL>
*/
int qos;
/**
* The retained flag serves two purposes depending on whether the message
* it is associated with is being published or received.
*
* <b>retained = true</b><br>
* For messages being published, a true setting indicates that the MQTT
* server should retain a copy of the message. The message will then be
* transmitted to new subscribers to a topic that matches the message topic.
* For subscribers registering a new subscription, the flag being true
* indicates that the received message is not a new one, but one that has
* been retained by the MQTT server.
*
* <b>retained = false</b> <br>
* For publishers, this indicates that this message should not be retained
* by the MQTT server. For subscribers, a false setting indicates this is
* a normal message, received as a result of it being published to the
* server.
*/
int retained;
/**
* The dup flag indicates whether or not this message is a duplicate.
* It is only meaningful when receiving QoS1 messages. When true, the
* client application should take appropriate action to deal with the
* duplicate message.
*/
int dup;
/** The message identifier is normally reserved for internal use by the
* MQTT client and server.
*/
int msgid;
/**
* The MQTT V5 properties associated with the message.
*/
MQTTProperties properties;
} MQTTClient_message;
#define MQTTClient_message_initializer { {'M', 'Q', 'T', 'M'}, 1, 0, NULL, 0, 0, 0, 0, MQTTProperties_initializer }
/**
* This is a callback function. The client application
* must provide an implementation of this function to enable asynchronous
* receipt of messages. The function is registered with the client library by
* passing it as an argument to MQTTClient_setCallbacks(). It is
* called by the client library when a new message that matches a client
* subscription has been received from the server. This function is executed on
* a separate thread to the one on which the client application is running.
* @param context A pointer to the <i>context</i> value originally passed to
* MQTTClient_setCallbacks(), which contains any application-specific context.
* @param topicName The topic associated with the received message.
* @param topicLen The length of the topic if there are one
* more NULL characters embedded in <i>topicName</i>, otherwise <i>topicLen</i>
* is 0. If <i>topicLen</i> is 0, the value returned by <i>strlen(topicName)</i>
* can be trusted. If <i>topicLen</i> is greater than 0, the full topic name
* can be retrieved by accessing <i>topicName</i> as a byte array of length
* <i>topicLen</i>.
* @param message The MQTTClient_message structure for the received message.
* This structure contains the message payload and attributes.
* @return This function must return 0 or 1 indicating whether or not
* the message has been safely received by the client application. <br>
* Returning 1 indicates that the message has been successfully handled.
* To free the message storage, ::MQTTClient_freeMessage must be called.
* To free the topic name storage, ::MQTTClient_free must be called.<br>
* Returning 0 indicates that there was a problem. In this
* case, the client library will reinvoke MQTTClient_messageArrived() to
* attempt to deliver the message to the application again.
* Do not free the message and topic storage when returning 0, otherwise
* the redelivery will fail.
*/
typedef int MQTTClient_messageArrived(void* context, char* topicName, int topicLen, MQTTClient_message* message);
/**
* This is a callback function. The client application
* must provide an implementation of this function to enable asynchronous
* notification of delivery of messages. The function is registered with the
* client library by passing it as an argument to MQTTClient_setCallbacks().
* It is called by the client library after the client application has
* published a message to the server. It indicates that the necessary
* handshaking and acknowledgements for the requested quality of service (see
* MQTTClient_message.qos) have been completed. This function is executed on a
* separate thread to the one on which the client application is running.
* <b>Note:</b>MQTTClient_deliveryComplete() is not called when messages are
* published at QoS0.
* @param context A pointer to the <i>context</i> value originally passed to
* MQTTClient_setCallbacks(), which contains any application-specific context.
* @param dt The ::MQTTClient_deliveryToken associated with
* the published message. Applications can check that all messages have been
* correctly published by matching the delivery tokens returned from calls to
* MQTTClient_publish() and MQTTClient_publishMessage() with the tokens passed
* to this callback.
*/
typedef void MQTTClient_deliveryComplete(void* context, MQTTClient_deliveryToken dt);
/**
* This is a callback function. The client application
* must provide an implementation of this function to enable asynchronous
* notification of the loss of connection to the server. The function is
* registered with the client library by passing it as an argument to
* MQTTClient_setCallbacks(). It is called by the client library if the client
* loses its connection to the server. The client application must take
* appropriate action, such as trying to reconnect or reporting the problem.
* This function is executed on a separate thread to the one on which the
* client application is running.
* @param context A pointer to the <i>context</i> value originally passed to
* MQTTClient_setCallbacks(), which contains any application-specific context.
* @param cause The reason for the disconnection.
* Currently, <i>cause</i> is always set to NULL.
*/
typedef void MQTTClient_connectionLost(void* context, char* cause);
/**
* This function sets the callback functions for a specific client.
* If your client application doesn't use a particular callback, set the
* relevant parameter to NULL. Calling MQTTClient_setCallbacks() puts the
* client into multi-threaded mode. Any necessary message acknowledgements and
* status communications are handled in the background without any intervention
* from the client application. See @ref async for more information.
*
* <b>Note:</b> The MQTT client must be disconnected when this function is
* called.
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param context A pointer to any application-specific context. The
* the <i>context</i> pointer is passed to each of the callback functions to
* provide access to the context information in the callback.
* @param cl A pointer to an MQTTClient_connectionLost() callback
* function. You can set this to NULL if your application doesn't handle
* disconnections.
* @param ma A pointer to an MQTTClient_messageArrived() callback
* function. This callback function must be set when you call
* MQTTClient_setCallbacks(), as otherwise there would be nowhere to deliver
* any incoming messages.
* @param dc A pointer to an MQTTClient_deliveryComplete() callback
* function. You can set this to NULL if your application publishes
* synchronously or if you do not want to check for successful delivery.
* @return ::MQTTCLIENT_SUCCESS if the callbacks were correctly set,
* ::MQTTCLIENT_FAILURE if an error occurred.
*/
LIBMQTT_API int MQTTClient_setCallbacks(MQTTClient handle, void* context, MQTTClient_connectionLost* cl,
MQTTClient_messageArrived* ma, MQTTClient_deliveryComplete* dc);
/**
* This is a callback function, which will be called when the a disconnect
* packet is received from the server. This applies to MQTT V5 and above only.
* @param context A pointer to the <i>context</i> value originally passed to
* ::MQTTClient_setDisconnected(), which contains any application-specific context.
* @param properties The MQTT V5 properties received with the disconnect, if any.
* @param reasonCode The MQTT V5 reason code received with the disconnect.
* Currently, <i>cause</i> is always set to NULL.
*/
typedef void MQTTClient_disconnected(void* context, MQTTProperties* properties,
enum MQTTReasonCodes reasonCode);
/**
* Sets the MQTTClient_disconnected() callback function for a client. This will be called
* if a disconnect packet is received from the server. Only valid for MQTT V5 and above.
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param context A pointer to any application-specific context. The
* the <i>context</i> pointer is passed to each of the callback functions to
* provide access to the context information in the callback.
* @param co A pointer to an MQTTClient_disconnected() callback
* function. NULL removes the callback setting.
* @return ::MQTTCLIENT_SUCCESS if the callbacks were correctly set,
* ::MQTTCLIENT_FAILURE if an error occurred.
*/
LIBMQTT_API int MQTTClient_setDisconnected(MQTTClient handle, void* context, MQTTClient_disconnected* co);
/**
* This is a callback function, the MQTT V5 version of MQTTClient_deliveryComplete().
* The client application
* must provide an implementation of this function to enable asynchronous
* notification of the completed delivery of messages.
* It is called by the client library after the client application has
* published a message to the server. It indicates that the necessary
* handshaking and acknowledgements for the requested quality of service (see
* MQTTClient_message.qos) have been completed. This function is executed on a
* separate thread to the one on which the client application is running.
* <b>Note:</b> It is not called when messages are published at QoS0.
* @param context A pointer to the <i>context</i> value originally passed to
* MQTTClient_setCallbacks(), which contains any application-specific context.
* @param dt The ::MQTTClient_deliveryToken associated with
* the published message. Applications can check that all messages have been
* correctly published by matching the delivery tokens returned from calls to
* MQTTClient_publish() and MQTTClient_publishMessage() with the tokens passed
* to this callback.
* @param packet_type the last received packet type for this completion. For QoS 1
* always PUBACK. For QoS 2 could be PUBREC or PUBCOMP.
* @param properties the MQTT V5 properties returned with the last packet from the server
* @param reasonCode the reason code returned from the server
*/
typedef void MQTTClient_published(void* context, int dt, int packet_type, MQTTProperties* properties,
enum MQTTReasonCodes reasonCode);
LIBMQTT_API int MQTTClient_setPublished(MQTTClient handle, void* context, MQTTClient_published* co);
/**
* This function creates an MQTT client ready for connection to the
* specified server and using the specified persistent storage (see
* MQTTClient_persistence). See also MQTTClient_destroy().
* @param handle A pointer to an ::MQTTClient handle. The handle is
* populated with a valid client reference following a successful return from
* this function.
* @param serverURI A null-terminated string specifying the server to
* which the client will connect. It takes the form <i>protocol://host:port</i>.
* Currently, <i>protocol</i> must be:
* <br>
* @em tcp:// or @em mqtt:// - Insecure TCP
* <br>
* @em ssl:// or @em mqtts:// - Encrypted SSL/TLS
* <br>
* @em ws:// - Insecure websockets
* <br>
* @em wss:// - Secure web sockets
* <br>
* The TLS enabled prefixes (ssl, mqtts, wss) are only valid if a TLS
* version of the library is linked with.
* For <i>host</i>, you can specify either an IP address or a host name. For
* instance, to connect to a server running on the local machines with the
* default MQTT port, specify <i>tcp://localhost:1883</i>.
* @param clientId The client identifier passed to the server when the
* client connects to it. It is a null-terminated UTF-8 encoded string.
* @param persistence_type The type of persistence to be used by the client:
* <br>
* ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or
* system on which the client is running fails or is switched off, the current
* state of any in-flight messages is lost and some messages may not be
* delivered even at QoS1 and QoS2.
* <br>
* ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based)
* persistence mechanism. Status about in-flight messages is held in persistent
* storage and provides some protection against message loss in the case of
* unexpected failure.
* <br>
* ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence
* implementation. Using this type of persistence gives control of the
* persistence mechanism to the application. The application has to implement
* the MQTTClient_persistence interface.
* @param persistence_context If the application uses
* ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should
* be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it
* should be set to the location of the persistence directory (if set
* to NULL, the persistence directory used is the working directory).
* Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this
* argument to point to a valid MQTTClient_persistence structure.
* @return ::MQTTCLIENT_SUCCESS if the client is successfully created, otherwise
* an error code is returned.
*/
LIBMQTT_API int MQTTClient_create(MQTTClient* handle, const char* serverURI, const char* clientId,
int persistence_type, void* persistence_context);
/** Options for the ::MQTTClient_createWithOptions call */
typedef struct
{
/** The eyecatcher for this structure. must be MQCO. */
char struct_id[4];
/** The version number of this structure. Must be 0 */
int struct_version;
/** Whether the MQTT version is 3.1, 3.1.1, or 5. To use V5, this must be set.
* MQTT V5 has to be chosen here, because during the create call the message persistence
* is initialized, and we want to know whether the format of any persisted messages
* is appropriate for the MQTT version we are going to connect with. Selecting 3.1 or
* 3.1.1 and attempting to read 5.0 persisted messages will result in an error on create. */
int MQTTVersion;
} MQTTClient_createOptions;
#define MQTTClient_createOptions_initializer { {'M', 'Q', 'C', 'O'}, 0, MQTTVERSION_DEFAULT }
/**
* A version of :MQTTClient_create() with additional options.
* This function creates an MQTT client ready for connection to the
* specified server and using the specified persistent storage (see
* MQTTClient_persistence). See also MQTTClient_destroy().
* @param handle A pointer to an ::MQTTClient handle. The handle is
* populated with a valid client reference following a successful return from
* this function.
* @param serverURI A null-terminated string specifying the server to
* which the client will connect. It takes the form <i>protocol://host:port</i>.
* Currently, <i>protocol</i> must be <i>tcp</i> or <i>ssl</i>.
* For <i>host</i>, you can
* specify either an IP address or a host name. For instance, to connect to
* a server running on the local machines with the default MQTT port, specify
* <i>tcp://localhost:1883</i>.
* @param clientId The client identifier passed to the server when the
* client connects to it. It is a null-terminated UTF-8 encoded string.
* @param persistence_type The type of persistence to be used by the client:
* <br>
* ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or
* system on which the client is running fails or is switched off, the current
* state of any in-flight messages is lost and some messages may not be
* delivered even at QoS1 and QoS2.
* <br>
* ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based)
* persistence mechanism. Status about in-flight messages is held in persistent
* storage and provides some protection against message loss in the case of
* unexpected failure.
* <br>
* ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence
* implementation. Using this type of persistence gives control of the
* persistence mechanism to the application. The application has to implement
* the MQTTClient_persistence interface.
* @param persistence_context If the application uses
* ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should
* be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it
* should be set to the location of the persistence directory (if set
* to NULL, the persistence directory used is the working directory).
* Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this
* argument to point to a valid MQTTClient_persistence structure.
* @param options additional options for the create.
* @return ::MQTTCLIENT_SUCCESS if the client is successfully created, otherwise
* an error code is returned.
*/
LIBMQTT_API int MQTTClient_createWithOptions(MQTTClient* handle, const char* serverURI, const char* clientId,
int persistence_type, void* persistence_context, MQTTClient_createOptions* options);
/**
* MQTTClient_willOptions defines the MQTT "Last Will and Testament" (LWT) settings for
* the client. In the event that a client unexpectedly loses its connection to
* the server, the server publishes the LWT message to the LWT topic on
* behalf of the client. This allows other clients (subscribed to the LWT topic)
* to be made aware that the client has disconnected. To enable the LWT
* function for a specific client, a valid pointer to an MQTTClient_willOptions
* structure is passed in the MQTTClient_connectOptions structure used in the
* MQTTClient_connect() call that connects the client to the server. The pointer
* to MQTTClient_willOptions can be set to NULL if the LWT function is not
* required.
*/
typedef struct
{
/** The eyecatcher for this structure. must be MQTW. */
char struct_id[4];
/** The version number of this structure. Must be 0 or 1
0 means there is no binary payload option
*/
int struct_version;
/** The LWT topic to which the LWT message will be published. */
const char* topicName;
/** The LWT payload in string form. */
const char* message;
/**
* The retained flag for the LWT message (see MQTTClient_message.retained).
*/
int retained;
/**
* The quality of service setting for the LWT message (see
* MQTTClient_message.qos and @ref qos).
*/
int qos;
/** The LWT payload in binary form. This is only checked and used if the message option is NULL */
struct
{
int len; /**< binary payload length */
const void* data; /**< binary payload data */
} payload;
} MQTTClient_willOptions;
#define MQTTClient_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, {0, NULL} }
#define MQTT_SSL_VERSION_DEFAULT 0
#define MQTT_SSL_VERSION_TLS_1_0 1
#define MQTT_SSL_VERSION_TLS_1_1 2
#define MQTT_SSL_VERSION_TLS_1_2 3
/**
* MQTTClient_sslProperties defines the settings to establish an SSL/TLS connection using the
* OpenSSL library. It covers the following scenarios:
* - Server authentication: The client needs the digital certificate of the server. It is included
* in a store containting trusted material (also known as "trust store").
* - Mutual authentication: Both client and server are authenticated during the SSL handshake. In
* addition to the digital certificate of the server in a trust store, the client will need its own
* digital certificate and the private key used to sign its digital certificate stored in a "key store".
* - Anonymous connection: Both client and server do not get authenticated and no credentials are needed
* to establish an SSL connection. Note that this scenario is not fully secure since it is subject to
* man-in-the-middle attacks.
*/
typedef struct
{
/** The eyecatcher for this structure. Must be MQTS */
char struct_id[4];
/** The version number of this structure. Must be [0-6].
* 0 means no sslVersion
* 1 means no verify, CApath
* 2 means no ssl_error_context, ssl_error_cb
* 3 means no ssl_psk_cb, ssl_psk_context, disableDefaultTrustStore
* 4 means no protos, protos_len
* 5 means no providerName
*/
int struct_version;
/** The file in PEM format containing the public digital certificates trusted by the client. */
const char* trustStore;
/** The file in PEM format containing the public certificate chain of the client. It may also include
* the client's private key.
*/
const char* keyStore;
/** If not included in the sslKeyStore, this setting points to the file in PEM format containing
* the client's private key.
*/
const char* privateKey;
/** The password to load the client's privateKey if encrypted. */
const char* privateKeyPassword;
/**
* The list of cipher suites that the client will present to the server during the SSL handshake. For a
* full explanation of the cipher list format, please see the OpenSSL on-line documentation:
* http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT
* If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding
* those offering no encryption- will be considered.
* This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance).
*/
const char* enabledCipherSuites;
/** True/False option to enable verification of the server certificate **/
int enableServerCertAuth;
/** The SSL/TLS version to use. Specify one of MQTT_SSL_VERSION_DEFAULT (0),
* MQTT_SSL_VERSION_TLS_1_0 (1), MQTT_SSL_VERSION_TLS_1_1 (2) or MQTT_SSL_VERSION_TLS_1_2 (3).
* Only used if struct_version is >= 1.
*/
int sslVersion;
/**
* Whether to carry out post-connect checks, including that a certificate
* matches the given host name.
* Exists only if struct_version >= 2
*/
int verify;
/**
* From the OpenSSL documentation:
* If CApath is not NULL, it points to a directory containing CA certificates in PEM format.
* Exists only if struct_version >= 2
*/
const char* CApath;
/**
* Callback function for OpenSSL error handler ERR_print_errors_cb
* Exists only if struct_version >= 3
*/
int (*ssl_error_cb) (const char *str, size_t len, void *u);
/**
* Application-specific contex for OpenSSL error handler ERR_print_errors_cb
* Exists only if struct_version >= 3
*/
void* ssl_error_context;
/**
* Callback function for setting TLS-PSK options. Parameters correspond to that of
* SSL_CTX_set_psk_client_callback, except for u which is the pointer ssl_psk_context.
* Exists only if struct_version >= 4
*/
unsigned int (*ssl_psk_cb) (const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len, void *u);
/**
* Application-specific contex for ssl_psk_cb
* Exists only if struct_version >= 4
*/
void* ssl_psk_context;
/**
* Don't load default SSL CA. Should be used together with PSK to make sure
* regular servers with certificate in place is not accepted.
* Exists only if struct_version >= 4
*/
int disableDefaultTrustStore;
/**
* The protocol-lists must be in wire-format, which is defined as a vector of non-empty, 8-bit length-prefixed, byte strings.
* The length-prefix byte is not included in the length. Each string is limited to 255 bytes. A byte-string length of 0 is invalid.
* A truncated byte-string is invalid.
* Check documentation for SSL_CTX_set_alpn_protos
* Exists only if struct_version >= 5
*/
const unsigned char *protos;
/**
* The length of the vector protos vector
* Exists only if struct_version >= 5
*/
unsigned int protos_len;
/** OpenSSL provider to used, NULL if disabled. */
const char* providerName;
} MQTTClient_SSLOptions;
#define MQTTClient_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 , NULL}
/**
* MQTTClient_libraryInfo is used to store details relating to the currently used
* library such as the version in use, the time it was built and relevant openSSL
* options.
* There is one static instance of this struct in MQTTClient.c
*/
typedef struct
{
const char* name;
const char* value;
} MQTTClient_nameValue;
/**
* This function returns version information about the library.
* no trace information will be returned.
* @return an array of strings describing the library. The last entry is a NULL pointer.
*/
LIBMQTT_API MQTTClient_nameValue* MQTTClient_getVersionInfo(void);
/**
* MQTTClient_connectOptions defines several settings that control the way the
* client connects to an MQTT server.
*
* <b>Note:</b> Default values are not defined for members of
* MQTTClient_connectOptions so it is good practice to specify all settings.
* If the MQTTClient_connectOptions structure is defined as an automatic
* variable, all members are set to random values and thus must be set by the
* client application. If the MQTTClient_connectOptions structure is defined
* as a static variable, initialization (in compliant compilers) sets all
* values to 0 (NULL for pointers). A #keepAliveInterval setting of 0 prevents
* correct operation of the client and so you <b>must</b> at least set a value
* for #keepAliveInterval.
*
* Suitable default values are set in the following initializers:
* - MQTTClient_connectOptions_initializer: for MQTT 3.1.1 non-WebSockets
* - MQTTClient_connectOptions_initializer5: for MQTT 5.0 non-WebSockets
* - MQTTClient_connectOptions_initializer_ws: for MQTT 3.1.1 WebSockets
* - MQTTClient_connectOptions_initializer5_ws: for MQTT 5.0 WebSockets
*/
typedef struct
{
/** The eyecatcher for this structure. must be MQTC. */
char struct_id[4];
/** The version number of this structure. Must be 0, 1, 2, 3, 4, 5, 6, 7 or 8.
* 0 signifies no SSL options and no serverURIs
* 1 signifies no serverURIs
* 2 signifies no MQTTVersion
* 3 signifies no returned values
* 4 signifies no binary password option
* 5 signifies no maxInflightMessages and cleanstart
* 6 signifies no HTTP headers option
* 7 signifies no HTTP proxy and HTTPS proxy options
*/
int struct_version;
/** The "keep alive" interval, measured in seconds, defines the maximum time
* that should pass without communication between the client and the server
* The client will ensure that at least one message travels across the
* network within each keep alive period. In the absence of a data-related
* message during the time period, the client sends a very small MQTT
* "ping" message, which the server will acknowledge. The keep alive
* interval enables the client to detect when the server is no longer
* available without having to wait for the long TCP/IP timeout.
*/
int keepAliveInterval;
/**
* This is a boolean value. The cleansession setting controls the behaviour
* of both the client and the server at connection and disconnection time.
* The client and server both maintain session state information. This
* information is used to ensure "at least once" and "exactly once"
* delivery, and "exactly once" receipt of messages. Session state also
* includes subscriptions created by an MQTT client. You can choose to
* maintain or discard state information between sessions.
*
* When cleansession is true, the state information is discarded at
* connect and disconnect. Setting cleansession to false keeps the state
* information. When you connect an MQTT client application with
* MQTTClient_connect(), the client identifies the connection using the
* client identifier and the address of the server. The server checks
* whether session information for this client
* has been saved from a previous connection to the server. If a previous
* session still exists, and cleansession=true, then the previous session
* information at the client and server is cleared. If cleansession=false,
* the previous session is resumed. If no previous session exists, a new
* session is started.
*/
int cleansession;
/**
* This is a boolean value that controls how many messages can be in-flight
* simultaneously. Setting <i>reliable</i> to true means that a published
* message must be completed (acknowledgements received) before another
* can be sent. Attempts to publish additional messages receive an
* ::MQTTCLIENT_MAX_MESSAGES_INFLIGHT return code. Setting this flag to
* false allows up to 10 messages to be in-flight. This can increase
* overall throughput in some circumstances.
*/
int reliable;
/**
* This is a pointer to an MQTTClient_willOptions structure. If your
* application does not make use of the Last Will and Testament feature,
* set this pointer to NULL.
*/
MQTTClient_willOptions* will;
/**
* MQTT servers that support the MQTT v3.1.1 protocol provide authentication
* and authorisation by user name and password. This is the user name
* parameter.
*/
const char* username;
/**
* MQTT servers that support the MQTT v3.1.1 protocol provide authentication
* and authorisation by user name and password. This is the password
* parameter.
*/
const char* password;
/**
* The time interval in seconds to allow a connect to complete.
*/
int connectTimeout;
/**
* The time interval in seconds after which unacknowledged publish requests are
* retried during a TCP session. With MQTT 3.1.1 and later, retries are
* not required except on reconnect. 0 turns off in-session retries, and is the
* recommended setting. Adding retries to an already overloaded network only
* exacerbates the problem.
*/
int retryInterval;
/**
* This is a pointer to an MQTTClient_SSLOptions structure. If your
* application does not make use of SSL, set this pointer to NULL.
*/
MQTTClient_SSLOptions* ssl;
/**
* The number of entries in the optional serverURIs array. Defaults to 0.
*/
int serverURIcount;
/**
* An optional array of null-terminated strings specifying the servers to
* which the client will connect. Each string takes the form <i>protocol://host:port</i>.
* <i>protocol</i> must be <i>tcp</i>, <i>ssl</i>, <i>ws</i> or <i>wss</i>.
* The TLS enabled prefixes (ssl, wss) are only valid if a TLS version of the library
* is linked with.
* For <i>host</i>, you can
* specify either an IP address or a host name. For instance, to connect to
* a server running on the local machines with the default MQTT port, specify
* <i>tcp://localhost:1883</i>.
* If this list is empty (the default), the server URI specified on MQTTClient_create()
* is used.
*/
char* const* serverURIs;
/**
* Sets the version of MQTT to be used on the connect.
* MQTTVERSION_DEFAULT (0) = default: start with 3.1.1, and if that fails, fall back to 3.1
* MQTTVERSION_3_1 (3) = only try version 3.1
* MQTTVERSION_3_1_1 (4) = only try version 3.1.1
* MQTTVERSION_5 (5) = only try version 5.0
*/
int MQTTVersion;
/**
* Returned from the connect when the MQTT version used to connect is 3.1.1
*/
struct
{
const char* serverURI; /**< the serverURI connected to */
int MQTTVersion; /**< the MQTT version used to connect with */
int sessionPresent; /**< if the MQTT version is 3.1.1, the value of sessionPresent returned in the connack */
} returned;
/**
* Optional binary password. Only checked and used if the password option is NULL
*/
struct
{
int len; /**< binary password length */
const void* data; /**< binary password data */
} binarypwd;
/**
* The maximum number of messages in flight
*/
int maxInflightMessages;
/*
* MQTT V5 clean start flag. Only clears state at the beginning of the session.
*/
int cleanstart;
/**
* HTTP headers for websockets
*/
const MQTTClient_nameValue* httpHeaders;
/**
* HTTP proxy
*/
const char* httpProxy;
/**
* HTTPS proxy
*/
const char* httpsProxy;
} MQTTClient_connectOptions;
/** Initializer for connect options for MQTT 3.1.1 non-WebSocket connections */
#define MQTTClient_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 8, 60, 1, 1, NULL, NULL, NULL, 30, 0, NULL,\
0, NULL, MQTTVERSION_DEFAULT, {NULL, 0, 0}, {0, NULL}, -1, 0, NULL, NULL, NULL}
/** Initializer for connect options for MQTT 5.0 non-WebSocket connections */
#define MQTTClient_connectOptions_initializer5 { {'M', 'Q', 'T', 'C'}, 8, 60, 0, 1, NULL, NULL, NULL, 30, 0, NULL,\
0, NULL, MQTTVERSION_5, {NULL, 0, 0}, {0, NULL}, -1, 1, NULL, NULL, NULL}
/** Initializer for connect options for MQTT 3.1.1 WebSockets connections.
* The keepalive interval is set to 45 seconds to avoid webserver 60 second inactivity timeouts.
*/
#define MQTTClient_connectOptions_initializer_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 1, 1, NULL, NULL, NULL, 30, 0, NULL,\
0, NULL, MQTTVERSION_DEFAULT, {NULL, 0, 0}, {0, NULL}, -1, 0, NULL, NULL, NULL}