Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
P
paho.mqtt.c
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
eclipse
paho.mqtt.c
Commits
149a9ea2
Commit
149a9ea2
authored
Jun 28, 2017
by
Ian Craggs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Change global init parameter to structure, issue #136
parent
dd6f1b7c
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
670 additions
and
640 deletions
+670
-640
MQTTAsync.c
src/MQTTAsync.c
+4
-4
MQTTAsync.h
src/MQTTAsync.h
+324
-309
MQTTClient.c
src/MQTTClient.c
+30
-30
MQTTClient.h
src/MQTTClient.h
+312
-297
No files found.
src/MQTTAsync.c
View file @
149a9ea2
...
...
@@ -66,10 +66,10 @@
const
char
*
client_timestamp_eye
=
"MQTTAsyncV3_Timestamp "
BUILD_TIMESTAMP
;
const
char
*
client_version_eye
=
"MQTTAsyncV3_Version "
CLIENT_VERSION
;
void
MQTTAsync_global_init
(
int
handle_openssl_init
)
void
MQTTAsync_global_init
(
MQTTAsync_init_options
*
inits
)
{
#if defined(OPENSSL)
SSLSocket_handleOpensslInit
(
handle
_openssl_init
);
SSLSocket_handleOpensslInit
(
inits
->
do
_openssl_init
);
#endif
}
...
...
@@ -1374,7 +1374,7 @@ static void nextOrClose(MQTTAsyncs* m, int rc, char* message)
(
*
(
m
->
connect
.
onFailure
))(
m
->
connect
.
context
,
&
data
);
}
MQTTAsync_startConnectRetry
(
m
);
}
}
}
...
...
@@ -2159,7 +2159,7 @@ static int retryLoopInterval = 5;
static
void
setRetryLoopInterval
(
int
keepalive
)
{
int
proposed
=
keepalive
/
10
;
if
(
proposed
<
1
)
proposed
=
1
;
else
if
(
proposed
>
5
)
...
...
src/MQTTAsync.h
View file @
149a9ea2
...
...
@@ -3,15 +3,15 @@
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation
* Ian Craggs - initial API and implementation
* Ian Craggs, Allan Stockdill-Mander - SSL connections
* Ian Craggs - multiple server connection support
* Ian Craggs - MQTT 3.1.1 support
...
...
@@ -27,27 +27,27 @@
/**
* @cond MQTTAsync_main
* @mainpage Asynchronous MQTT client library for C
*
*
* © Copyright IBM Corp. 2009, 2017
*
*
* @brief An Asynchronous MQTT client library for C.
*
* 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
* 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
* 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
* 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 Asynchronous MQTT Client library for C.
*
*
* <b>Using the client</b><br>
* Applications that use the client library typically use a similar structure:
* <ul>
...
...
@@ -78,8 +78,8 @@
* </ul>
* @endcond
*/
/// @cond EXCLUDE
#if defined(__cplusplus)
extern
"C"
{
...
...
@@ -123,7 +123,7 @@
*/
#define MQTTASYNC_DISCONNECTED -3
/**
* Return code: The maximum number of messages allowed to be simultaneously
* Return code: The maximum number of messages allowed to be simultaneously
* in-flight has been reached.
*/
#define MQTTASYNC_MAX_MESSAGES_INFLIGHT -4
...
...
@@ -184,12 +184,27 @@
*/
#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
;
}
MQTTAsync_init_options
;
#define MQTTAsync_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 }
/**
* Global init of mqtt library. Call once on program start to set global behaviour.
* handle_openssl_init - if mqtt library should handle openssl init (1) or rely on the caller to init it before using mqtt (0)
*/
void
MQTTAsync_global_init
(
int
handle_openssl_init
);
void
MQTTAsync_global_init
(
MQTTAsync_init_options
*
inits
);
/**
* A handle representing an MQTT client. A valid client handle is available
...
...
@@ -200,8 +215,8 @@ typedef void* MQTTAsync;
* A value representing an MQTT message. A 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
* MQTTAsync_publish(),
* MQTTAsync_publishMessage(),
* MQTTAsync_publish(),
* MQTTAsync_publishMessage(),
* MQTTAsync_deliveryComplete(), and
* MQTTAsync_getPendingTokens()).
*/
...
...
@@ -223,48 +238,48 @@ typedef struct
int
payloadlen
;
/** A pointer to the payload of the MQTT message. */
void
*
payload
;
/**
* The quality of service (QoS) assigned to the message.
/**
* 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
* <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.
*
* 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
* 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 ndicates 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
* For publishers, this ndicates 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.
/**
* 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.
* MQTT client and server.
*/
int
msgid
;
}
MQTTAsync_message
;
...
...
@@ -273,63 +288,63 @@ typedef struct
/**
* This is a callback function. The client application
* must provide an implementation of this function to enable asynchronous
* 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 MQTTAsync_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
* @param context A pointer to the <i>context</i> value originally passed to
* MQTTAsync_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 MQTTAsync_message structure for the received message.
* can be retrieved by accessing <i>topicName</i> as a byte array of length
* <i>topicLen</i>.
* @param message The MQTTAsync_message structure for the received message.
* This structure contains the message payload and attributes.
* @return This function must return a boolean value indicating whether or not
* the message has been safely received by the client application. Returning
* true indicates that the message has been successfully handled.
* Returning false indicates that there was a problem. In this
* case, the client library will reinvoke MQTTAsync_messageArrived() to
* the message has been safely received by the client application. Returning
* true indicates that the message has been successfully handled.
* Returning false indicates that there was a problem. In this
* case, the client library will reinvoke MQTTAsync_messageArrived() to
* attempt to deliver the message to the application again.
*/
typedef
int
MQTTAsync_messageArrived
(
void
*
context
,
char
*
topicName
,
int
topicLen
,
MQTTAsync_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 to the server. The function is
* registered with the client library by passing it as an argument to MQTTAsync_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
* must provide an implementation of this function to enable asynchronous
* notification of delivery of messages to the server. The function is
* registered with the client library by passing it as an argument to MQTTAsync_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
* MQTTAsync_message.qos) have been completed. 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
* @param context A pointer to the <i>context</i> value originally passed to
* MQTTAsync_setCallbacks(), which contains any application-specific context.
* @param token The ::MQTTAsync_token associated with
* the published message. Applications can check that all messages have been
* the published message. Applications can check that all messages have been
* correctly published by matching the tokens returned from calls to
* MQTTAsync_send() and MQTTAsync_sendMessage() with the tokens passed
* to this callback.
* to this callback.
*/
typedef
void
MQTTAsync_deliveryComplete
(
void
*
context
,
MQTTAsync_token
token
);
/**
* 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
* 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
* MQTTAsync_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
* 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
* @param context A pointer to the <i>context</i> value originally passed to
* MQTTAsync_setCallbacks(), which contains any application-specific context.
* @param cause The reason for the disconnection.
* Currently, <i>cause</i> is always set to NULL.
...
...
@@ -373,12 +388,12 @@ typedef struct
union
{
/** For subscribe, the granted QoS of the subscription returned by the server. */
int
qos
;
int
qos
;
/** For subscribeMany, the list of granted QoSs of the subscriptions returned by the server. */
int
*
qosList
;
int
*
qosList
;
/** For publish, the message being sent to the server. */
struct
{
{
MQTTAsync_message
message
;
char
*
destinationName
;
}
pub
;
...
...
@@ -394,11 +409,11 @@ typedef struct
/**
* This is a callback function. The client application
* must provide an implementation of this function to enable asynchronous
* notification of the successful completion of an API call. The function is
* registered with the client library by passing it as an argument in
* ::MQTTAsync_responseOptions.
* @param context A pointer to the <i>context</i> value originally passed to
* must provide an implementation of this function to enable asynchronous
* notification of the successful completion of an API call. The function is
* registered with the client library by passing it as an argument in
* ::MQTTAsync_responseOptions.
* @param context A pointer to the <i>context</i> value originally passed to
* ::MQTTAsync_responseOptions, which contains any application-specific context.
* @param response Any success data associated with the API completion.
*/
...
...
@@ -406,11 +421,11 @@ typedef void MQTTAsync_onSuccess(void* context, MQTTAsync_successData* response)
/**
* This is a callback function. The client application
* must provide an implementation of this function to enable asynchronous
* notification of the unsuccessful completion of an API call. The function is
* registered with the client library by passing it as an argument in
* ::MQTTAsync_responseOptions.
* @param context A pointer to the <i>context</i> value originally passed to
* must provide an implementation of this function to enable asynchronous
* notification of the unsuccessful completion of an API call. The function is
* registered with the client library by passing it as an argument in
* ::MQTTAsync_responseOptions.
* @param context A pointer to the <i>context</i> value originally passed to
* ::MQTTAsync_responseOptions, which contains any application-specific context.
* @param response Any failure data associated with the API completion.
*/
...
...
@@ -421,14 +436,14 @@ typedef struct
/** The eyecatcher for this structure. Must be MQTR */
char
struct_id
[
4
];
/** The version number of this structure. Must be 0 */
int
struct_version
;
/**
int
struct_version
;
/**
* A pointer to a callback function to be called if the API call successfully
* completes. Can be set to NULL, in which case no indication of successful
* completion will be received.
*/
MQTTAsync_onSuccess
*
onSuccess
;
/**
/**
* A pointer to a callback function to be called if the API call fails.
* Can be set to NULL, in which case no indication of unsuccessful
* completion will be received.
...
...
@@ -439,7 +454,7 @@ typedef struct
* the <i>context</i> pointer is passed to success or failure callback functions to
* provide access to the context information in the callback.
*/
void
*
context
;
void
*
context
;
MQTTAsync_token
token
;
/* output */
}
MQTTAsync_responseOptions
;
...
...
@@ -448,17 +463,17 @@ typedef struct
/**
* This function sets the global callback functions for a specific client.
* If your client application doesn't use a particular callback, set the
* If your client application doesn't use a particular callback, set the
* relevant parameter to NULL. Any necessary message acknowledgements and
* status communications are handled in the background without any intervention
* from the client application. If you do not set a messageArrived callback
* function, you will not be notified of the receipt of any messages as a
* result of a subscription.
*
* <b>Note:</b> The MQTT client must be disconnected when this function is
* called.
* function, you will not be notified of the receipt of any messages as a
* result of a subscription.
*
* <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
* MQTTAsync_create().
* MQTTAsync_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.
...
...
@@ -469,7 +484,7 @@ typedef struct
* function. You can set this to NULL if your application doesn't handle
* receipt of messages.
* @param dc A pointer to an MQTTAsync_deliveryComplete() callback
* function. You can set this to NULL if you do not want to check
* function. You can set this to NULL if you do not want to check
* for successful delivery.
* @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set,
* ::MQTTASYNC_FAILURE if an error occurred.
...
...
@@ -481,7 +496,7 @@ DLLExport int MQTTAsync_setCallbacks(MQTTAsync handle, void* context, MQTTAsync_
/**
* Sets the MQTTAsync_connected() callback function for a client.
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* MQTTAsync_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.
...
...
@@ -497,48 +512,48 @@ DLLExport int MQTTAsync_setConnected(MQTTAsync handle, void* context, MQTTAsync_
* Reconnects a client with the previously used connect options. Connect
* must have previously been called for this to work.
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* MQTTAsync_create().
* @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set,
* ::MQTTASYNC_FAILURE if an error occurred.
*/
DLLExport
int
MQTTAsync_reconnect
(
MQTTAsync
handle
);
/**
* This function creates an MQTT client ready for connection to the
* specified server and using the specified persistent storage (see
* This function creates an MQTT client ready for connection to the
* specified server and using the specified persistent storage (see
* MQTTAsync_persistence). See also MQTTAsync_destroy().
* @param handle A pointer to an ::MQTTAsync handle. The handle is
* populated with a valid client reference following a successful return from
* this function.
* 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>.
* <i>protocol</i> must be <i>tcp</i> or <i>ssl</i>. For <i>host</i>, you can
* <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.
* 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
* ::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
* 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)
* ::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
* 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
* 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
* @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
* 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.
...
...
@@ -572,10 +587,10 @@ DLLExport int MQTTAsync_createWithOptions(MQTTAsync* handle, const char* serverU
* 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 MQTTAsync_willOptions
* function for a specific client, a valid pointer to an MQTTAsync_willOptions
* structure is passed in the MQTTAsync_connectOptions structure used in the
* MQTTAsync_connect() call that connects the client to the server. The pointer
* to MQTTAsync_willOptions can be set to NULL if the LWT function is not
* to MQTTAsync_willOptions can be set to NULL if the LWT function is not
* required.
*/
typedef
struct
...
...
@@ -594,8 +609,8 @@ typedef struct
* The retained flag for the LWT message (see MQTTAsync_message.retained).
*/
int
retained
;
/**
* The quality of service setting for the LWT message (see
/**
* The quality of service setting for the LWT message (see
* MQTTAsync_message.qos and @ref qos).
*/
int
qos
;
...
...
@@ -610,68 +625,68 @@ typedef struct
#define MQTTAsync_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, { 0, NULL } }
/**
* MQTTAsync_sslProperties defines the settings to establish an SSL/TLS connection using the
* MQTTAsync_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
* - 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
* - 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
typedef
struct
{
/** The eyecatcher for this structure. Must be MQTS */
char
struct_id
[
4
];
/** The version number of this structure. Must be 0 */
int
struct_version
;
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.
* 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
* 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
;
const
char
*
enabledCipherSuites
;
/** True/False option to enable verification of the server certificate **/
int
enableServerCertAuth
;
}
MQTTAsync_SSLOptions
;
#define MQTTAsync_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 0, NULL, NULL, NULL, NULL, NULL, 1 }
/**
* MQTTAsync_connectOptions defines several settings that control the way the
* client connects to an MQTT server. Default values are set in
* client connects to an MQTT server. Default values are set in
* MQTTAsync_connectOptions_initializer.
*/
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 or 5.
/** The version number of this structure. Must be 0, 1, 2, 3 4 or 5.
* 0 signifies no SSL options and no serverURIs
* 1 signifies no serverURIs
* 1 signifies no serverURIs
* 2 signifies no MQTTVersion
* 3 signifies no automatic reconnect options
* 4 signifies no binary password option (just string)
...
...
@@ -680,55 +695,55 @@ typedef struct
/** 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
* 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.
* Set to 0 if you do not want any keep alive processing.
*/
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.
* 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
* MQTTAsync_connect(), the client identifies the connection using the
* client identifier and the address of the server. The server checks
* 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
* MQTTAsync_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
* 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 controls how many messages can be in-flight simultaneously.
/**
* This controls how many messages can be in-flight simultaneously.
*/
int
maxInflight
;
/**
* This is a pointer to an MQTTAsync_willOptions structure. If your
* application does not make use of the Last Will and Testament feature,
int
maxInflight
;
/**
* This is a pointer to an MQTTAsync_willOptions structure. If your
* application does not make use of the Last Will and Testament feature,
* set this pointer to NULL.
*/
MQTTAsync_willOptions
*
will
;
/**
/**
* MQTT servers that support the MQTT v3.1 protocol provide authentication
* and authorisation by user name and password. This is the user name
* parameter.
* and authorisation by user name and password. This is the user name
* parameter.
*/
const
char
*
username
;
/**
const
char
*
username
;
/**
* MQTT servers that support the MQTT v3.1 protocol provide authentication
* and authorisation by user name and password. This is the password
* and authorisation by user name and password. This is the password
* parameter.
*/
const
char
*
password
;
...
...
@@ -740,18 +755,18 @@ typedef struct
* The time interval in seconds
*/
int
retryInterval
;
/**
* This is a pointer to an MQTTAsync_SSLOptions structure. If your
/**
* This is a pointer to an MQTTAsync_SSLOptions structure. If your
* application does not make use of SSL, set this pointer to NULL.
*/
MQTTAsync_SSLOptions
*
ssl
;
/**
/**
* A pointer to a callback function to be called if the connect successfully
* completes. Can be set to NULL, in which case no indication of successful
* completion will be received.
*/
MQTTAsync_onSuccess
*
onSuccess
;
/**
/**
* A pointer to a callback function to be called if the connect fails.
* Can be set to NULL, in which case no indication of unsuccessful
* completion will be received.
...
...
@@ -770,11 +785,11 @@ typedef struct
/**
* An 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> or <i>ssl</i>. For <i>host</i>, you can
* <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 domain name. For instance, to connect to
* a server running on the local machines with the default MQTT port, specify
* <i>tcp://localhost:1883</i>.
*/
*/
char
*
const
*
serverURIs
;
/**
* Sets the version of MQTT to be used on the connect.
...
...
@@ -795,7 +810,7 @@ typedef struct
* Maximum retry interval in seconds. The doubling stops here on failed retries.
*/
int
maxRetryInterval
;
/**
/**
* Optional binary password. Only checked and used if the password option is NULL
*/
struct
{
...
...
@@ -813,11 +828,11 @@ NULL, NULL, NULL, NULL, 0, NULL, 0, 0, 1, 60, {0, NULL}}
* MQTTAsync_create()) to an MQTT server using the specified options. If you
* want to enable asynchronous message and status notifications, you must call
* MQTTAsync_setCallbacks() prior to MQTTAsync_connect().
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param options A pointer to a valid MQTTAsync_connectOptions
* structure.
* @return ::MQTTASYNC_SUCCESS if the client connect request was accepted.
* @return ::MQTTASYNC_SUCCESS if the client connect request was accepted.
* If the client was unable to connect to the server, an error code is
* returned via the onFailure callback, if set.
* Error codes greater than 0 are returned by the MQTT protocol:<br><br>
...
...
@@ -838,17 +853,17 @@ typedef struct
/** The version number of this structure. Must be 0 or 1. 0 signifies no SSL options */
int
struct_version
;
/**
* The client delays disconnection for up to this time (in
* The client delays disconnection for up to this time (in
* milliseconds) in order to allow in-flight message transfers to complete.
*/
int
timeout
;
/**
/**
* A pointer to a callback function to be called if the disconnect successfully
* completes. Can be set to NULL, in which case no indication of successful
* completion will be received.
*/
MQTTAsync_onSuccess
*
onSuccess
;
/**
/**
* A pointer to a callback function to be called if the disconnect fails.
* Can be set to NULL, in which case no indication of unsuccessful
* completion will be received.
...
...
@@ -859,7 +874,7 @@ typedef struct
* the <i>context</i> pointer is passed to success or failure callback functions to
* provide access to the context information in the callback.
*/
void
*
context
;
void
*
context
;
}
MQTTAsync_disconnectOptions
;
#define MQTTAsync_disconnectOptions_initializer { {'M', 'Q', 'T', 'D'}, 0, 0, NULL, NULL, NULL }
...
...
@@ -868,18 +883,18 @@ typedef struct
/**
* This function attempts to disconnect the client from the MQTT
* server. In order to allow the client time to complete handling of messages
* that are in-flight when this function is called, a timeout period is
* that are in-flight when this function is called, a timeout period is
* specified. When the timeout period has expired, the client disconnects even
* if there are still outstanding message acknowledgements.
* The next time the client connects to the same server, any QoS 1 or 2
* messages which have not completed will be retried depending on the
* cleansession settings for both the previous and the new connection (see
* The next time the client connects to the same server, any QoS 1 or 2
* messages which have not completed will be retried depending on the
* cleansession settings for both the previous and the new connection (see
* MQTTAsync_connectOptions.cleansession and MQTTAsync_connect()).
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param options The client delays disconnection for up to this time (in
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param options The client delays disconnection for up to this time (in
* milliseconds) in order to allow in-flight message transfers to complete.
* @return ::MQTTASYNC_SUCCESS if the client successfully disconnects from
* @return ::MQTTASYNC_SUCCESS if the client successfully disconnects from
* the server. An error code is returned if the client was unable to disconnect
* from the server
*/
...
...
@@ -889,86 +904,86 @@ DLLExport int MQTTAsync_disconnect(MQTTAsync handle, const MQTTAsync_disconnectO
/**
* This function allows the client application to test whether or not a
* client is currently connected to the MQTT server.
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @return Boolean true if the client is connected, otherwise false.
*/
DLLExport
int
MQTTAsync_isConnected
(
MQTTAsync
handle
);
/**
* This function attempts to subscribe a client to a single topic, which may
* contain wildcards (see @ref wildcard). This call also specifies the
* This function attempts to subscribe a client to a single topic, which may
* contain wildcards (see @ref wildcard). This call also specifies the
* @ref qos requested for the subscription
* (see also MQTTAsync_subscribeMany()).
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param topic The subscription topic, which may include wildcards.
* @param qos The requested quality of service for the subscription.
* @param response A pointer to a response options structure. Used to set callback functions.
* @return ::MQTTASYNC_SUCCESS if the subscription request is successful.
* An error code is returned if there was a problem registering the
* subscription.
* @return ::MQTTASYNC_SUCCESS if the subscription request is successful.
* An error code is returned if there was a problem registering the
* subscription.
*/
DLLExport
int
MQTTAsync_subscribe
(
MQTTAsync
handle
,
const
char
*
topic
,
int
qos
,
MQTTAsync_responseOptions
*
response
);
/**
* This function attempts to subscribe a client to a list of topics, which may
* contain wildcards (see @ref wildcard). This call also specifies the
* @ref qos requested for each topic (see also MQTTAsync_subscribe()).
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param count The number of topics for which the client is requesting
* contain wildcards (see @ref wildcard). This call also specifies the
* @ref qos requested for each topic (see also MQTTAsync_subscribe()).
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param count The number of topics for which the client is requesting
* subscriptions.
* @param topic An array (of length <i>count</i>) of pointers to
* @param topic An array (of length <i>count</i>) of pointers to
* topics, each of which may include wildcards.
* @param qos An array (of length <i>count</i>) of @ref qos
* values. qos[n] is the requested QoS for topic[n].
* @param response A pointer to a response options structure. Used to set callback functions.
* @return ::MQTTASYNC_SUCCESS if the subscription request is successful.
* An error code is returned if there was a problem registering the
* subscriptions.
* @return ::MQTTASYNC_SUCCESS if the subscription request is successful.
* An error code is returned if there was a problem registering the
* subscriptions.
*/
DLLExport
int
MQTTAsync_subscribeMany
(
MQTTAsync
handle
,
int
count
,
char
*
const
*
topic
,
int
*
qos
,
MQTTAsync_responseOptions
*
response
);
/**
* This function attempts to remove an existing subscription made by the
/**
* This function attempts to remove an existing subscription made by the
* specified client.
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param topic The topic for the subscription to be removed, which may
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param topic The topic for the subscription to be removed, which may
* include wildcards (see @ref wildcard).
* @param response A pointer to a response options structure. Used to set callback functions.
* @return ::MQTTASYNC_SUCCESS if the subscription is removed.
* An error code is returned if there was a problem removing the
* subscription.
* @return ::MQTTASYNC_SUCCESS if the subscription is removed.
* An error code is returned if there was a problem removing the
* subscription.
*/
DLLExport
int
MQTTAsync_unsubscribe
(
MQTTAsync
handle
,
const
char
*
topic
,
MQTTAsync_responseOptions
*
response
);
/**
/**
* This function attempts to remove existing subscriptions to a list of topics
* made by the specified client.
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param count The number subscriptions to be removed.
* @param topic An array (of length <i>count</i>) of pointers to the topics of
* the subscriptions to be removed, each of which may include wildcards.
* @param response A pointer to a response options structure. Used to set callback functions.
* @return ::MQTTASYNC_SUCCESS if the subscriptions are removed.
* @return ::MQTTASYNC_SUCCESS if the subscriptions are removed.
* An error code is returned if there was a problem removing the subscriptions.
*/
DLLExport
int
MQTTAsync_unsubscribeMany
(
MQTTAsync
handle
,
int
count
,
char
*
const
*
topic
,
MQTTAsync_responseOptions
*
response
);
/**
/**
* This function attempts to publish a message to a given topic (see also
* ::MQTTAsync_sendMessage()). An ::MQTTAsync_token is issued when
* this function returns successfully. If the client application needs to
* test for successful delivery of messages, a callback should be set
* ::MQTTAsync_sendMessage()). An ::MQTTAsync_token is issued when
* this function returns successfully. If the client application needs to
* test for successful delivery of messages, a callback should be set
* (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()).
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param destinationName The topic associated with this message.
* @param payloadlen The length of the payload in bytes.
* @param payload A pointer to the byte array payload of the message.
...
...
@@ -976,42 +991,42 @@ DLLExport int MQTTAsync_unsubscribeMany(MQTTAsync handle, int count, char* const
* @param retained The retained flag for the message.
* @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions.
* This is optional and can be set to NULL.
* @return ::MQTTASYNC_SUCCESS if the message is accepted for publication.
* @return ::MQTTASYNC_SUCCESS if the message is accepted for publication.
* An error code is returned if there was a problem accepting the message.
*/
DLLExport
int
MQTTAsync_send
(
MQTTAsync
handle
,
const
char
*
destinationName
,
int
payloadlen
,
void
*
payload
,
int
qos
,
int
retained
,
MQTTAsync_responseOptions
*
response
);
/**
/**
* This function attempts to publish a message to a given topic (see also
* MQTTAsync_publish()). An ::MQTTAsync_token is issued when
* this function returns successfully. If the client application needs to
* test for successful delivery of messages, a callback should be set
* MQTTAsync_publish()). An ::MQTTAsync_token is issued when
* this function returns successfully. If the client application needs to
* test for successful delivery of messages, a callback should be set
* (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()).
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param destinationName The topic associated with this message.
* @param msg A pointer to a valid MQTTAsync_message structure containing
* @param msg A pointer to a valid MQTTAsync_message structure containing
* the payload and attributes of the message to be published.
* @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions.
* @return ::MQTTASYNC_SUCCESS if the message is accepted for publication.
* @return ::MQTTASYNC_SUCCESS if the message is accepted for publication.
* An error code is returned if there was a problem accepting the message.
*/
DLLExport
int
MQTTAsync_sendMessage
(
MQTTAsync
handle
,
const
char
*
destinationName
,
const
MQTTAsync_message
*
msg
,
MQTTAsync_responseOptions
*
response
);
/**
* This function sets a pointer to an array of tokens for
* messages that are currently in-flight (pending completion).
* This function sets a pointer to an array of tokens for
* messages that are currently in-flight (pending completion).
*
* <b>Important note:</b> The memory used to hold the array of tokens is
* malloc()'d in this function. The client application is responsible for
* <b>Important note:</b> The memory used to hold the array of tokens is
* malloc()'d in this function. The client application is responsible for
* freeing this memory when it is no longer required.
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param tokens The address of a pointer to an ::MQTTAsync_token.
* When the function returns successfully, the pointer is set to point to an
* @param handle A valid client handle from a successful call to
* MQTTAsync_create().
* @param tokens The address of a pointer to an ::MQTTAsync_token.
* When the function returns successfully, the pointer is set to point to an
* array of tokens representing messages pending completion. The last member of
* the array is set to -1 to indicate there are no more tokens. If no tokens
* are pending, the pointer is set to NULL.
...
...
@@ -1047,13 +1062,13 @@ DLLExport int MQTTAsync_waitForCompletion(MQTTAsync handle, MQTTAsync_token toke
/**
* This function frees memory allocated to an MQTT message, including the
* This function frees memory allocated to an MQTT message, including the
* additional memory allocated to the message payload. The client application
* calls this function when the message has been fully processed. <b>Important
* note:</b> This function does not free the memory allocated to a message
* topic string. It is the responsibility of the client application to free
* calls this function when the message has been fully processed. <b>Important
* note:</b> This function does not free the memory allocated to a message
* topic string. It is the responsibility of the client application to free
* this memory using the MQTTAsync_free() library function.
* @param msg The address of a pointer to the ::MQTTAsync_message structure
* @param msg The address of a pointer to the ::MQTTAsync_message structure
* to be freed.
*/
DLLExport
void
MQTTAsync_freeMessage
(
MQTTAsync_message
**
msg
);
...
...
@@ -1068,18 +1083,18 @@ DLLExport void MQTTAsync_freeMessage(MQTTAsync_message** msg);
*/
DLLExport
void
MQTTAsync_free
(
void
*
ptr
);
/**
/**
* This function frees the memory allocated to an MQTT client (see
* MQTTAsync_create()). It should be called when the client is no longer
* MQTTAsync_create()). It should be called when the client is no longer
* required.
* @param handle A pointer to the handle referring to the ::MQTTAsync
* @param handle A pointer to the handle referring to the ::MQTTAsync
* structure to be freed.
*/
DLLExport
void
MQTTAsync_destroy
(
MQTTAsync
*
handle
);
enum
MQTTASYNC_TRACE_LEVELS
enum
MQTTASYNC_TRACE_LEVELS
{
MQTTASYNC_TRACE_MAXIMUM
=
1
,
MQTTASYNC_TRACE_MEDIUM
,
...
...
@@ -1091,29 +1106,29 @@ enum MQTTASYNC_TRACE_LEVELS
};
/**
* This function sets the level of trace information which will be
/**
* This function sets the level of trace information which will be
* returned in the trace callback.
* @param level the trace level required
* @param level the trace level required
*/
DLLExport
void
MQTTAsync_setTraceLevel
(
enum
MQTTASYNC_TRACE_LEVELS
level
);
/**
* This is a callback function prototype which must be implemented if you want
/**
* This is a callback function prototype which must be implemented if you want
* to receive trace information.
* @param level the trace level of the message returned
* @param meesage the trace message. This is a pointer to a static buffer which
* will be overwritten on each call. You must copy the data if you want to keep
* it for later.
* it for later.
*/
typedef
void
MQTTAsync_traceCallback
(
enum
MQTTASYNC_TRACE_LEVELS
level
,
char
*
message
);
/**
* This function sets the trace callback if needed. If set to NULL,
* no trace information will be returned. The default trace level is
* MQTTASYNC_TRACE_MINIMUM.
* @param callback a pointer to the function which will handle the trace information
/**
* This function sets the trace callback if needed. If set to NULL,
* no trace information will be returned. The default trace level is
* MQTTASYNC_TRACE_MINIMUM.
* @param callback a pointer to the function which will handle the trace information
*/
DLLExport
void
MQTTAsync_setTraceCallback
(
MQTTAsync_traceCallback
*
callback
);
...
...
@@ -1124,18 +1139,18 @@ typedef struct
const
char
*
value
;
}
MQTTAsync_nameValue
;
/**
* This function returns version information about the library.
* no trace information will be returned. The default trace level is
/**
* This function returns version information about the library.
* no trace information will be returned. The default trace level is
* MQTTASYNC_TRACE_MINIMUM
* @return an array of strings describing the library. The last entry is a NULL pointer.
* @return an array of strings describing the library. The last entry is a NULL pointer.
*/
DLLExport
MQTTAsync_nameValue
*
MQTTAsync_getVersionInfo
(
void
);
/**
* @cond MQTTAsync_main
* @page async Threading
* @page async Threading
* The client application runs on several threads.
* Processing of handshaking and maintaining
* the network connection is performed in the background.
...
...
@@ -1143,7 +1158,7 @@ DLLExport MQTTAsync_nameValue* MQTTAsync_getVersionInfo(void);
* threads.
* Notifications of status and message reception are provided to the client
* application using callbacks registered with the library by the call to
* MQTTAsync_setCallbacks() (see MQTTAsync_messageArrived(),
* MQTTAsync_setCallbacks() (see MQTTAsync_messageArrived(),
* MQTTAsync_connectionLost() and MQTTAsync_deliveryComplete()).
* In addition, some functions allow success and failure callbacks to be set
* for individual requests, in the ::MQTTAsync_responseOptions structure. Applications
...
...
@@ -1155,85 +1170,85 @@ DLLExport MQTTAsync_nameValue* MQTTAsync_getVersionInfo(void);
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=444093)
*
* @page wildcard Subscription wildcards
* Every MQTT message includes a topic that classifies it. MQTT servers use
* Every MQTT message includes a topic that classifies it. MQTT servers use
* topics to determine which subscribers should receive messages published to
* the server.
*
* Consider the server receiving messages from several environmental sensors.
*
* Consider the server receiving messages from several environmental sensors.
* Each sensor publishes its measurement data as a message with an associated
* topic. Subscribing applications need to know which sensor originally
* published each received message. A unique topic is thus used to identify
* each sensor and measurement type. Topics such as SENSOR1TEMP,
* SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very
* flexible. If additional sensors are added to the system at a later date,
* subscribing applications must be modified to receive them.
* topic. Subscribing applications need to know which sensor originally
* published each received message. A unique topic is thus used to identify
* each sensor and measurement type. Topics such as SENSOR1TEMP,
* SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very
* flexible. If additional sensors are added to the system at a later date,
* subscribing applications must be modified to receive them.
*
* To provide more flexibility, MQTT supports a hierarchical topic namespace.
* This allows application designers to organize topics to simplify their
* management. Levels in the hierarchy are delimited by the '/' character,
* such as SENSOR/1/HUMIDITY. Publishers and subscribers use these
* To provide more flexibility, MQTT supports a hierarchical topic namespace.
* This allows application designers to organize topics to simplify their
* management. Levels in the hierarchy are delimited by the '/' character,
* such as SENSOR/1/HUMIDITY. Publishers and subscribers use these
* hierarchical topics as already described.
*
* For subscriptions, two wildcard characters are supported:
* <ul>
* <li>A '#' character represents a complete sub-tree of the hierarchy and
* thus must be the last character in a subscription topic string, such as
* SENSOR/#. This will match any topic starting with SENSOR/, such as
* <li>A '#' character represents a complete sub-tree of the hierarchy and
* thus must be the last character in a subscription topic string, such as
* SENSOR/#. This will match any topic starting with SENSOR/, such as
* SENSOR/1/TEMP and SENSOR/2/HUMIDITY.</li>
* <li> A '+' character represents a single level of the hierarchy and is
* used between delimiters. For example, SENSOR/+/TEMP will match
* <li> A '+' character represents a single level of the hierarchy and is
* used between delimiters. For example, SENSOR/+/TEMP will match
* SENSOR/1/TEMP and SENSOR/2/TEMP.</li>
* </ul>
* Publishers are not allowed to use the wildcard characters in their topic
* Publishers are not allowed to use the wildcard characters in their topic
* names.
*
* Deciding on your topic hierarchy is an important step in your system design.
*
* @page qos Quality of service
* The MQTT protocol provides three qualities of service for delivering
* messages between clients and servers: "at most once", "at least once" and
* "exactly once".
* The MQTT protocol provides three qualities of service for delivering
* messages between clients and servers: "at most once", "at least once" and
* "exactly once".
*
* Quality of service (QoS) is an attribute of an individual message being
* Quality of service (QoS) is an attribute of an individual message being
* published. An application sets the QoS for a specific message by setting the
* MQTTAsync_message.qos field to the required value.
*
* A subscribing client can set the maximum quality of service a server uses
* to send messages that match the client subscriptions. The
* MQTTAsync_subscribe() and MQTTAsync_subscribeMany() functions set this
* maximum. The QoS of a message forwarded to a subscriber thus might be
* different to the QoS given to the message by the original publisher.
* to send messages that match the client subscriptions. The
* MQTTAsync_subscribe() and MQTTAsync_subscribeMany() functions set this
* maximum. The QoS of a message forwarded to a subscriber thus might be
* different to the QoS given to the message by the original publisher.
* The lower of the two values is used to forward a message.
*
* The three levels are:
*
* <b>QoS0, At most once:</b> The message is delivered at most once, or it
* may not be delivered at all. Its delivery across the network is not
* acknowledged. The message is not stored. The message could be lost if the
* client is disconnected, or if the server fails. QoS0 is the fastest mode of
* <b>QoS0, At most once:</b> The message is delivered at most once, or it
* may not be delivered at all. Its delivery across the network is not
* acknowledged. The message is not stored. The message could be lost if the
* client is disconnected, or if the server fails. QoS0 is the fastest mode of
* transfer. It is sometimes called "fire and forget".
*
* The MQTT protocol does not require servers to forward publications at QoS0
* The MQTT protocol does not require servers to forward publications at QoS0
* to a client. If the client is disconnected at the time the server receives
* the publication, the publication might be discarded, depending on the
* the publication, the publication might be discarded, depending on the
* server implementation.
*
* <b>QoS1, At least once:</b> The message is always delivered at least once.
* It might be delivered multiple times if there is a failure before an
* acknowledgment is received by the sender. The message must be stored
* locally at the sender, until the sender receives confirmation that the
* message has been published by the receiver. The message is stored in case
*
* <b>QoS1, At least once:</b> The message is always delivered at least once.
* It might be delivered multiple times if there is a failure before an
* acknowledgment is received by the sender. The message must be stored
* locally at the sender, until the sender receives confirmation that the
* message has been published by the receiver. The message is stored in case
* the message must be sent again.
*
* <b>QoS2, Exactly once:</b> The message is always delivered exactly once.
*
* <b>QoS2, Exactly once:</b> The message is always delivered exactly once.
* The message must be stored locally at the sender, until the sender receives
* confirmation that the message has been published by the receiver. The
* message is stored in case the message must be sent again. QoS2 is the
* safest, but slowest mode of transfer. A more sophisticated handshaking
* confirmation that the message has been published by the receiver. The
* message is stored in case the message must be sent again. QoS2 is the
* safest, but slowest mode of transfer. A more sophisticated handshaking
* and acknowledgement sequence is used than for QoS1 to ensure no duplication
* of messages occurs.
* @page publish Publication example
@code
#include <stdio.h>
...
...
@@ -1313,7 +1328,7 @@ void onConnect(void* context, MQTTAsync_successData* response)
int rc;
printf("Successful connection\n");
opts.onSuccess = onSend;
opts.context = client;
...
...
@@ -1367,7 +1382,7 @@ int main(int argc, char* argv[])
MQTTAsync_destroy(&client);
return rc;
}
* @endcode
* @page subscribe Subscription example
@code
...
...
@@ -1517,7 +1532,7 @@ int main(int argc, char* argv[])
if (finished)
goto exit;
do
do
{
ch = getchar();
} while (ch!='Q' && ch != 'q');
...
...
@@ -1539,15 +1554,15 @@ exit:
MQTTAsync_destroy(&client);
return rc;
}
* @endcode
* @page tracing Tracing
*
*
* Runtime tracing can be controlled by environment variables or API calls.
*
* #### Environment variables
*
* Tracing is switched on by setting the MQTT_C_CLIENT_TRACE environment variable.
* Tracing is switched on by setting the MQTT_C_CLIENT_TRACE environment variable.
* A value of ON, or stdout, prints to stdout, any other value is interpreted as a file name to use.
*
* The amount of trace detail is controlled with the MQTT_C_CLIENT_TRACE_LEVEL environment
...
...
@@ -1562,7 +1577,7 @@ exit:
*
* MQTTAsync_traceCallback() is used to set a callback function which is called whenever trace
* information is available. This will be the same information as that printed if the
* environment variables were used to control the trace.
* environment variables were used to control the trace.
*
* The MQTTAsync_setTraceLevel() calls is used to set the maximum level of trace entries that will be
* passed to the callback function. The levels are:
...
...
@@ -1574,13 +1589,13 @@ exit:
* 6. ::MQTTASYNC_TRACE_SEVERE
* 7. ::MQTTASYNC_TRACE_FATAL
*
* Selecting ::MQTTASYNC_TRACE_MAXIMUM will cause all trace entries at all levels to be returned.
* Selecting ::MQTTASYNC_TRACE_MAXIMUM will cause all trace entries at all levels to be returned.
* Choosing ::MQTTASYNC_TRACE_ERROR will cause ERROR, SEVERE and FATAL trace entries to be returned
* to the callback function.
*
* ### MQTT Packet Tracing
*
* A feature that can be very useful is printing the MQTT packets that are sent and received. To
*
* A feature that can be very useful is printing the MQTT packets that are sent and received. To
* achieve this, use the following environment variable settings:
* @code
MQTT_C_CLIENT_TRACE=ON
...
...
@@ -1603,7 +1618,7 @@ exit:
* 6. packet details
*
* ### Default Level Tracing
*
*
* This is an extract of a default level trace of a call to connect:
* @code
19700101 010000.000 (1152206656) (0)> MQTTClient_connect:893
...
...
@@ -1634,22 +1649,22 @@ exit:
* 7. return value (if there is one)
*
* ### Memory Allocation Tracing
*
* Setting the trace level to maximum causes memory allocations and frees to be traced along with
*
* Setting the trace level to maximum causes memory allocations and frees to be traced along with
* the default trace entries, with messages like the following:
* @code
20130528 161819.657 Allocating 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 177 ptr 0x179f930
20130528 161819.657 Freeing 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 201, heap use now 896 bytes
* @endcode
* When the last MQTT client object is destroyed, if the trace is being recorded
* When the last MQTT client object is destroyed, if the trace is being recorded
* and all memory allocated by the client library has not been freed, an error message will be
* written to the trace. This can help with fixing memory leaks. The message will look like this:
* @code
20130528 163909.208 Some memory not freed at shutdown, possible memory leak
20130528 163909.208 Heap scan start, total 880 bytes
20130528 163909.208 Heap element size 32, line 354, file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c, ptr 0x260cb00
20130528 163909.208 Content
20130528 163909.208 Content
20130528 163909.209 Heap scan end
* @endcode
* @endcond
...
...
src/MQTTClient.c
View file @
149a9ea2
...
...
@@ -3,17 +3,17 @@
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* 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 - bug 384016 - segv setting will message
* Ian Craggs - bug 384053 - v1.0.0.7 - stop MQTTClient_receive on socket error
* Ian Craggs - bug 384053 - v1.0.0.7 - stop MQTTClient_receive on socket error
* Ian Craggs, Allan Stockdill-Mander - add ability to connect with SSL
* Ian Craggs - multiple server connection support
* Ian Craggs - fix for bug 413429 - connectionLost not called
...
...
@@ -73,10 +73,10 @@
const
char
*
client_timestamp_eye
=
"MQTTClientV3_Timestamp "
BUILD_TIMESTAMP
;
const
char
*
client_version_eye
=
"MQTTClientV3_Version "
CLIENT_VERSION
;
void
MQTTClient_global_init
(
int
handle_openssl_init
)
void
MQTTClient_global_init
(
MQTTClient_init_options
*
inits
)
{
#if defined(OPENSSL)
SSLSocket_handleOpensslInit
(
handle
_openssl_init
);
SSLSocket_handleOpensslInit
(
inits
->
do
_openssl_init
);
#endif
}
...
...
@@ -567,7 +567,7 @@ static thread_return_type WINAPI MQTTClient_run(void* n)
{
if
(
m
->
c
->
connected
)
MQTTClient_disconnect_internal
(
m
,
0
);
else
else
{
if
(
m
->
c
->
connect_state
==
2
&&
!
Thread_check_sem
(
m
->
connect_sem
))
{
...
...
@@ -645,7 +645,7 @@ static thread_return_type WINAPI MQTTClient_run(void* n)
}
#if defined(OPENSSL)
else
if
(
m
->
c
->
connect_state
==
2
&&
!
Thread_check_sem
(
m
->
connect_sem
))
{
{
rc
=
SSLSocket_connect
(
m
->
c
->
net
.
ssl
,
m
->
c
->
net
.
socket
);
if
(
rc
==
1
||
rc
==
SSL_FATAL
)
{
...
...
@@ -869,7 +869,7 @@ static int MQTTClient_connectURIVersion(MQTTClient handle, MQTTClient_connectOpt
rc
=
SOCKET_ERROR
;
goto
exit
;
}
#if defined(OPENSSL)
if
(
m
->
ssl
)
{
...
...
@@ -895,7 +895,7 @@ static int MQTTClient_connectURIVersion(MQTTClient handle, MQTTClient_connectOpt
rc
=
SOCKET_ERROR
;
goto
exit
;
}
else
if
(
rc
==
1
)
else
if
(
rc
==
1
)
{
rc
=
MQTTCLIENT_SUCCESS
;
m
->
c
->
connect_state
=
3
;
...
...
@@ -927,7 +927,7 @@ static int MQTTClient_connectURIVersion(MQTTClient handle, MQTTClient_connectOpt
}
#endif
}
#if defined(OPENSSL)
if
(
m
->
c
->
connect_state
==
2
)
/* SSL connect sent - wait for completion */
{
...
...
@@ -994,9 +994,9 @@ exit:
if
(
rc
==
MQTTCLIENT_SUCCESS
)
{
if
(
options
->
struct_version
==
4
)
/* means we have to fill out return values */
{
{
options
->
returned
.
serverURI
=
serverURI
;
options
->
returned
.
MQTTVersion
=
MQTTVersion
;
options
->
returned
.
MQTTVersion
=
MQTTVersion
;
options
->
returned
.
sessionPresent
=
sessionPresent
;
}
}
...
...
@@ -1011,7 +1011,7 @@ static int retryLoopInterval = 5;
static
void
setRetryLoopInterval
(
int
keepalive
)
{
int
proposed
=
keepalive
/
10
;
if
(
proposed
<
1
)
proposed
=
1
;
else
if
(
proposed
>
5
)
...
...
@@ -1049,7 +1049,7 @@ static int MQTTClient_connectURI(MQTTClient handle, MQTTClient_connectOptions* o
if
(
options
->
will
&&
(
options
->
will
->
struct_version
==
0
||
options
->
will
->
struct_version
==
1
))
{
const
void
*
source
=
NULL
;
m
->
c
->
will
=
malloc
(
sizeof
(
willMessages
));
if
(
options
->
will
->
message
||
(
options
->
will
->
struct_version
==
1
&&
options
->
will
->
payload
.
data
))
{
...
...
@@ -1066,7 +1066,7 @@ static int MQTTClient_connectURI(MQTTClient handle, MQTTClient_connectOptions* o
m
->
c
->
will
->
payload
=
malloc
(
m
->
c
->
will
->
payloadlen
);
memcpy
(
m
->
c
->
will
->
payload
,
source
,
m
->
c
->
will
->
payloadlen
);
}
else
else
{
m
->
c
->
will
->
payload
=
NULL
;
m
->
c
->
will
->
payloadlen
=
0
;
...
...
@@ -1075,7 +1075,7 @@ static int MQTTClient_connectURI(MQTTClient handle, MQTTClient_connectOptions* o
m
->
c
->
will
->
retained
=
options
->
will
->
retained
;
m
->
c
->
will
->
topic
=
MQTTStrdup
(
options
->
will
->
topicName
);
}
#if defined(OPENSSL)
if
(
m
->
c
->
sslopts
)
{
...
...
@@ -1169,7 +1169,7 @@ int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions* options)
goto
exit
;
}
}
#if defined(OPENSSL)
if
(
options
->
struct_version
!=
0
&&
options
->
ssl
)
/* check validity of SSL options structure */
{
...
...
@@ -1193,11 +1193,11 @@ int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions* options)
else
{
int
i
;
for
(
i
=
0
;
i
<
options
->
serverURIcount
;
++
i
)
{
char
*
serverURI
=
options
->
serverURIs
[
i
];
if
(
strncmp
(
URI_TCP
,
serverURI
,
strlen
(
URI_TCP
))
==
0
)
serverURI
+=
strlen
(
URI_TCP
);
#if defined(OPENSSL)
...
...
@@ -1209,7 +1209,7 @@ int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions* options)
#endif
if
((
rc
=
MQTTClient_connectURI
(
handle
,
options
,
serverURI
))
==
MQTTCLIENT_SUCCESS
)
break
;
}
}
}
exit:
...
...
@@ -1362,7 +1362,7 @@ int MQTTClient_subscribeMany(MQTTClient handle, int count, char* const* topic, i
rc
=
MQTTCLIENT_BAD_UTF8_STRING
;
goto
exit
;
}
if
(
qos
[
i
]
<
0
||
qos
[
i
]
>
2
)
{
rc
=
MQTTCLIENT_BAD_QOS
;
...
...
@@ -1396,14 +1396,14 @@ int MQTTClient_subscribeMany(MQTTClient handle, int count, char* const* topic, i
Thread_lock_mutex
(
mqttclient_mutex
);
if
(
pack
!=
NULL
)
{
Suback
*
sub
=
(
Suback
*
)
pack
;
Suback
*
sub
=
(
Suback
*
)
pack
;
ListElement
*
current
=
NULL
;
i
=
0
;
while
(
ListNextElement
(
sub
->
qoss
,
&
current
))
{
int
*
reqqos
=
(
int
*
)(
current
->
content
);
qos
[
i
++
]
=
*
reqqos
;
}
}
rc
=
MQTTProtocol_handleSubacks
(
pack
,
m
->
c
->
net
.
socket
);
m
->
pack
=
NULL
;
}
...
...
@@ -1541,7 +1541,7 @@ int MQTTClient_publish(MQTTClient handle, const char* topicName, int payloadlen,
goto
exit
;
/* If outbound queue is full, block until it is not */
while
(
m
->
c
->
outboundMsgs
->
count
>=
m
->
c
->
maxInflightMessages
||
while
(
m
->
c
->
outboundMsgs
->
count
>=
m
->
c
->
maxInflightMessages
||
Socket_noPendingWrites
(
m
->
c
->
net
.
socket
)
==
0
)
/* wait until the socket is free of large packets being written */
{
if
(
blocked
==
0
)
...
...
@@ -1865,7 +1865,7 @@ int MQTTClient_receive(MQTTClient handle, char** topicName, int* topicLen, MQTTC
{
int
sock
=
0
;
MQTTClient_cycle
(
&
sock
,
(
timeout
>
elapsed
)
?
timeout
-
elapsed
:
0L
,
&
rc
);
if
(
rc
==
SOCKET_ERROR
)
{
if
(
ListFindItem
(
handles
,
&
sock
,
clientSockCompare
)
&&
/* find client corresponding to socket */
...
...
@@ -2075,17 +2075,17 @@ static void MQTTProtocol_checkPendingWrites(void)
static
void
MQTTClient_writeComplete
(
int
socket
)
{
ListElement
*
found
=
NULL
;
FUNC_ENTRY
;
/* a partial write is now complete for a socket - this will be on a publish*/
MQTTProtocol_checkPendingWrites
();
/* find the client using this socket */
if
((
found
=
ListFindItem
(
handles
,
&
socket
,
clientSockCompare
))
!=
NULL
)
{
MQTTClients
*
m
=
(
MQTTClients
*
)(
found
->
content
);
time
(
&
(
m
->
c
->
net
.
lastSent
));
}
FUNC_EXIT
;
...
...
src/MQTTClient.h
View file @
149a9ea2
...
...
@@ -3,11 +3,11 @@
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
...
...
@@ -22,18 +22,18 @@
* @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
* 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
* 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
* 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
* 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.
...
...
@@ -42,10 +42,10 @@
* @cond MQTTClient_main
* @mainpage MQTT Client library for C
* © Copyright IBM Corp. 2009, 2017
*
*
* @brief An MQTT client library in C.
*
* These pages describe the original more synchronous API which might be
* 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
...
...
@@ -53,27 +53,27 @@
* 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
* 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
* 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
* 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)
* <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>
...
...
@@ -140,7 +140,7 @@
*/
#define MQTTCLIENT_DISCONNECTED -3
/**
* Return code: The maximum number of messages allowed to be simultaneously
* Return code: The maximum number of messages allowed to be simultaneously
* in-flight has been reached.
*/
#define MQTTCLIENT_MAX_MESSAGES_INFLIGHT -4
...
...
@@ -189,11 +189,26 @@
*/
#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.
*
handle_openssl_init - if mqtt library should handle openssl init (1) or rely on the caller to init it before using mqtt
(0)
*
do_openssl_init - if mqtt library should initialize OpenSSL (1) or rely on the caller to do it before using the library
(0)
*/
void
MQTTClient_global_init
(
int
handle_openssl_init
);
void
MQTTClient_global_init
(
MQTTClient_init_options
*
inits
);
/**
* A handle representing an MQTT client. A valid client handle is available
...
...
@@ -204,9 +219,9 @@ 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_publish(),
* MQTTClient_publishMessage(),
* MQTTClient_deliveryComplete(),
* MQTTClient_waitForCompletion() and
* MQTTClient_getPendingDeliveryTokens()).
*/
...
...
@@ -229,48 +244,48 @@ typedef struct
int
payloadlen
;
/** A pointer to the payload of the MQTT message. */
void
*
payload
;
/**
* The quality of service (QoS) assigned to the message.
/**
* 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
* <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.
*
* 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
* 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 ndicates 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
* For publishers, this ndicates 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.
/**
* 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.
* MQTT client and server.
*/
int
msgid
;
}
MQTTClient_message
;
...
...
@@ -279,65 +294,65 @@ typedef struct
/**
* This is a callback function. The client application
* must provide an implementation of this function to enable asynchronous
* 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
* @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.
* 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 a boolean value indicating whether or not
* the message has been safely received by the client application. Returning
* true indicates that the message has been successfully handled.
* Returning false indicates that there was a problem. In this
* case, the client library will reinvoke MQTTClient_messageArrived() to
* the message has been safely received by the client application. Returning
* true indicates that the message has been successfully handled.
* Returning false 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.
*/
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
* 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
* <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
* @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
* 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.
* 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
* 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
* 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
* @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.
...
...
@@ -346,16 +361,16 @@ 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
* 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.
*
* <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().
* 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.
...
...
@@ -366,22 +381,22 @@ typedef void MQTTClient_connectionLost(void* context, char* cause);
* function. This callback function must be specified when you call
* MQTTClient_setCallbacks().
* @param dc A pointer to an MQTTClient_deliveryComplete() callback
* function. You can set this to NULL if your application publishes
* 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.
*/
DLLExport
int
MQTTClient_setCallbacks
(
MQTTClient
handle
,
void
*
context
,
MQTTClient_connectionLost
*
cl
,
MQTTClient_messageArrived
*
ma
,
MQTTClient_deliveryComplete
*
dc
);
/**
* This function creates an MQTT client ready for connection to the
* specified server and using the specified persistent storage (see
* 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.
* 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>.
...
...
@@ -390,27 +405,27 @@ DLLExport int MQTTClient_setCallbacks(MQTTClient handle, void* context, MQTTClie
* 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.
* 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
* ::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
* 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)
* ::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
* 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
* 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
* @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
* 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.
...
...
@@ -426,17 +441,17 @@ DLLExport int MQTTClient_create(MQTTClient* handle, const char* serverURI, const
* 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
* 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
* 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
/** The version number of this structure. Must be 0 or 1
0 means there is no binary payload option
*/
int
struct_version
;
...
...
@@ -448,8 +463,8 @@ typedef struct
* The retained flag for the LWT message (see MQTTClient_message.retained).
*/
int
retained
;
/**
* The quality of service setting for the LWT message (see
/**
* The quality of service setting for the LWT message (see
* MQTTClient_message.qos and @ref qos).
*/
int
qos
;
...
...
@@ -464,41 +479,41 @@ typedef struct
#define MQTTClient_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, {0, NULL} }
/**
* MQTTClient_sslProperties defines the settings to establish an SSL/TLS connection using the
* 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
* - 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
* - 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
typedef
struct
{
/** The eyecatcher for this structure. Must be MQTS */
char
struct_id
[
4
];
/** The version number of this structure. Must be 0 */
int
struct_version
;
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.
* 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
* 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
...
...
@@ -509,21 +524,21 @@ typedef struct
/** True/False option to enable verification of the server certificate **/
int
enableServerCertAuth
;
}
MQTTClient_SSLOptions
;
#define MQTTClient_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 0, NULL, NULL, NULL, NULL, NULL, 1 }
/**
* MQTTClient_connectOptions defines several settings that control the way the
* client connects to an MQTT server.
* client connects to an MQTT server.
*
* <b>Note:</b> Default values are not defined for members of
* <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
* 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.
...
...
@@ -532,9 +547,9 @@ 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 or 5.
/** The version number of this structure. Must be 0, 1, 2, 3, 4 or 5.
* 0 signifies no SSL options and no serverURIs
* 1 signifies no serverURIs
* 1 signifies no serverURIs
* 2 signifies no MQTTVersion
* 3 signifies no returned values
* 4 signifies no binary password option
...
...
@@ -543,60 +558,60 @@ typedef struct
/** 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
* 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.
* 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
* 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
* 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
* 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
* 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,
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.
* and authorisation by user name and password. This is the user name
* parameter.
*/
const
char
*
username
;
/**
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
* and authorisation by user name and password. This is the password
* parameter.
*/
const
char
*
password
;
...
...
@@ -608,8 +623,8 @@ typedef struct
* The time interval in seconds
*/
int
retryInterval
;
/**
* This is a pointer to an MQTTClient_SSLOptions structure. If your
/**
* 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
;
...
...
@@ -620,13 +635,13 @@ typedef struct
/**
* 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> or <i>ssl</i>. For <i>host</i>, you can
* <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>.
* 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.
...
...
@@ -638,13 +653,13 @@ typedef struct
/**
* Returned from the connect when the MQTT version used to connect is 3.1.1
*/
struct
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
{
...
...
@@ -658,7 +673,7 @@ typedef struct
/**
* 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.
* options.
* There is one static instance of this struct in MQTTClient.c
*/
...
...
@@ -680,13 +695,13 @@ DLLExport MQTTClient_nameValue* MQTTClient_getVersionInfo(void);
* MQTTClient_create()) to an MQTT server using the specified options. If you
* want to enable asynchronous message and status notifications, you must call
* MQTTClient_setCallbacks() prior to MQTTClient_connect().
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param options A pointer to a valid MQTTClient_connectOptions
* structure.
* @return ::MQTTCLIENT_SUCCESS if the client successfully connects to the
* server. An error code is returned if the client was unable to connect to
* the server.
* the server.
* Error codes greater than 0 are returned by the MQTT protocol:<br><br>
* <b>1</b>: Connection refused: Unacceptable protocol version<br>
* <b>2</b>: Connection refused: Identifier rejected<br>
...
...
@@ -700,18 +715,18 @@ DLLExport int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions* o
/**
* This function attempts to disconnect the client from the MQTT
* server. In order to allow the client time to complete handling of messages
* that are in-flight when this function is called, a timeout period is
* that are in-flight when this function is called, a timeout period is
* specified. When the timeout period has expired, the client disconnects even
* if there are still outstanding message acknowledgements.
* The next time the client connects to the same server, any QoS 1 or 2
* messages which have not completed will be retried depending on the
* cleansession settings for both the previous and the new connection (see
* The next time the client connects to the same server, any QoS 1 or 2
* messages which have not completed will be retried depending on the
* cleansession settings for both the previous and the new connection (see
* MQTTClient_connectOptions.cleansession and MQTTClient_connect()).
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param timeout The client delays disconnection for up to this time (in
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param timeout The client delays disconnection for up to this time (in
* milliseconds) in order to allow in-flight message transfers to complete.
* @return ::MQTTCLIENT_SUCCESS if the client successfully disconnects from
* @return ::MQTTCLIENT_SUCCESS if the client successfully disconnects from
* the server. An error code is returned if the client was unable to disconnect
* from the server
*/
...
...
@@ -720,8 +735,8 @@ DLLExport int MQTTClient_disconnect(MQTTClient handle, int timeout);
/**
* This function allows the client application to test whether or not a
* client is currently connected to the MQTT server.
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @return Boolean true if the client is connected, otherwise false.
*/
DLLExport
int
MQTTClient_isConnected
(
MQTTClient
handle
);
...
...
@@ -731,104 +746,104 @@ DLLExport int MQTTClient_isConnected(MQTTClient handle);
Returns return code, MQTTCLIENT_SUCCESS == success, non-zero some sort of error (TBD) */
/**
* This function attempts to subscribe a client to a single topic, which may
* contain wildcards (see @ref wildcard). This call also specifies the
* This function attempts to subscribe a client to a single topic, which may
* contain wildcards (see @ref wildcard). This call also specifies the
* @ref qos requested for the subscription
* (see also MQTTClient_subscribeMany()).
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param topic The subscription topic, which may include wildcards.
* @param qos The requested quality of service for the subscription.
* @return ::MQTTCLIENT_SUCCESS if the subscription request is successful.
* An error code is returned if there was a problem registering the
* subscription.
* @return ::MQTTCLIENT_SUCCESS if the subscription request is successful.
* An error code is returned if there was a problem registering the
* subscription.
*/
DLLExport
int
MQTTClient_subscribe
(
MQTTClient
handle
,
const
char
*
topic
,
int
qos
);
/**
* This function attempts to subscribe a client to a list of topics, which may
* contain wildcards (see @ref wildcard). This call also specifies the
* @ref qos requested for each topic (see also MQTTClient_subscribe()).
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param count The number of topics for which the client is requesting
* contain wildcards (see @ref wildcard). This call also specifies the
* @ref qos requested for each topic (see also MQTTClient_subscribe()).
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param count The number of topics for which the client is requesting
* subscriptions.
* @param topic An array (of length <i>count</i>) of pointers to
* @param topic An array (of length <i>count</i>) of pointers to
* topics, each of which may include wildcards.
* @param qos An array (of length <i>count</i>) of @ref qos
* values. qos[n] is the requested QoS for topic[n].
* @return ::MQTTCLIENT_SUCCESS if the subscription request is successful.
* An error code is returned if there was a problem registering the
* subscriptions.
* @return ::MQTTCLIENT_SUCCESS if the subscription request is successful.
* An error code is returned if there was a problem registering the
* subscriptions.
*/
DLLExport
int
MQTTClient_subscribeMany
(
MQTTClient
handle
,
int
count
,
char
*
const
*
topic
,
int
*
qos
);
/**
* This function attempts to remove an existing subscription made by the
/**
* This function attempts to remove an existing subscription made by the
* specified client.
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param topic The topic for the subscription to be removed, which may
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param topic The topic for the subscription to be removed, which may
* include wildcards (see @ref wildcard).
* @return ::MQTTCLIENT_SUCCESS if the subscription is removed.
* An error code is returned if there was a problem removing the
* subscription.
* @return ::MQTTCLIENT_SUCCESS if the subscription is removed.
* An error code is returned if there was a problem removing the
* subscription.
*/
DLLExport
int
MQTTClient_unsubscribe
(
MQTTClient
handle
,
const
char
*
topic
);
/**
/**
* This function attempts to remove existing subscriptions to a list of topics
* made by the specified client.
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param count The number subscriptions to be removed.
* @param topic An array (of length <i>count</i>) of pointers to the topics of
* the subscriptions to be removed, each of which may include wildcards.
* @return ::MQTTCLIENT_SUCCESS if the subscriptions are removed.
* @return ::MQTTCLIENT_SUCCESS if the subscriptions are removed.
* An error code is returned if there was a problem removing the subscriptions.
*/
DLLExport
int
MQTTClient_unsubscribeMany
(
MQTTClient
handle
,
int
count
,
char
*
const
*
topic
);
/**
/**
* This function attempts to publish a message to a given topic (see also
* MQTTClient_publishMessage()). An ::MQTTClient_deliveryToken is issued when
* this function returns successfully. If the client application needs to
* test for succesful delivery of QoS1 and QoS2 messages, this can be done
* either asynchronously or synchronously (see @ref async,
* MQTTClient_publishMessage()). An ::MQTTClient_deliveryToken is issued when
* this function returns successfully. If the client application needs to
* test for succesful delivery of QoS1 and QoS2 messages, this can be done
* either asynchronously or synchronously (see @ref async,
* ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()).
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param topicName The topic associated with this message.
* @param payloadlen The length of the payload in bytes.
* @param payload A pointer to the byte array payload of the message.
* @param qos The @ref qos of the message.
* @param retained The retained flag for the message.
* @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated
* with a token representing the message when the function returns
* successfully. If your application does not use delivery tokens, set this
* with a token representing the message when the function returns
* successfully. If your application does not use delivery tokens, set this
* argument to NULL.
* @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication.
* @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication.
* An error code is returned if there was a problem accepting the message.
*/
DLLExport
int
MQTTClient_publish
(
MQTTClient
handle
,
const
char
*
topicName
,
int
payloadlen
,
void
*
payload
,
int
qos
,
int
retained
,
MQTTClient_deliveryToken
*
dt
);
/**
/**
* This function attempts to publish a message to a given topic (see also
* MQTTClient_publish()). An ::MQTTClient_deliveryToken is issued when
* this function returns successfully. If the client application needs to
* test for succesful delivery of QoS1 and QoS2 messages, this can be done
* either asynchronously or synchronously (see @ref async,
* MQTTClient_publish()). An ::MQTTClient_deliveryToken is issued when
* this function returns successfully. If the client application needs to
* test for succesful delivery of QoS1 and QoS2 messages, this can be done
* either asynchronously or synchronously (see @ref async,
* ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()).
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param topicName The topic associated with this message.
* @param msg A pointer to a valid MQTTClient_message structure containing
* @param msg A pointer to a valid MQTTClient_message structure containing
* the payload and attributes of the message to be published.
* @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated
* with a token representing the message when the function returns
* successfully. If your application does not use delivery tokens, set this
* with a token representing the message when the function returns
* successfully. If your application does not use delivery tokens, set this
* argument to NULL.
* @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication.
* @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication.
* An error code is returned if there was a problem accepting the message.
*/
DLLExport
int
MQTTClient_publishMessage
(
MQTTClient
handle
,
const
char
*
topicName
,
MQTTClient_message
*
msg
,
MQTTClient_deliveryToken
*
dt
);
...
...
@@ -839,30 +854,30 @@ DLLExport int MQTTClient_publishMessage(MQTTClient handle, const char* topicName
* of the main thread with completed publication of a message. When called,
* MQTTClient_waitForCompletion() blocks execution until the message has been
* successful delivered or the specified timeout has expired. See @ref async.
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param dt The ::MQTTClient_deliveryToken that represents the message being
* tested for successful delivery. Delivery tokens are issued by the
* tested for successful delivery. Delivery tokens are issued by the
* publishing functions MQTTClient_publish() and MQTTClient_publishMessage().
* @param timeout The maximum time to wait in milliseconds.
* @return ::MQTTCLIENT_SUCCESS if the message was successfully delivered.
* An error code is returned if the timeout expires or there was a problem
* @return ::MQTTCLIENT_SUCCESS if the message was successfully delivered.
* An error code is returned if the timeout expires or there was a problem
* checking the token.
*/
DLLExport
int
MQTTClient_waitForCompletion
(
MQTTClient
handle
,
MQTTClient_deliveryToken
dt
,
unsigned
long
timeout
);
/**
* This function sets a pointer to an array of delivery tokens for
* messages that are currently in-flight (pending completion).
* This function sets a pointer to an array of delivery tokens for
* messages that are currently in-flight (pending completion).
*
* <b>Important note:</b> The memory used to hold the array of tokens is
* malloc()'d in this function. The client application is responsible for
* <b>Important note:</b> The memory used to hold the array of tokens is
* malloc()'d in this function. The client application is responsible for
* freeing this memory when it is no longer required.
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param tokens The address of a pointer to an ::MQTTClient_deliveryToken.
* When the function returns successfully, the pointer is set to point to an
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param tokens The address of a pointer to an ::MQTTClient_deliveryToken.
* When the function returns successfully, the pointer is set to point to an
* array of tokens representing messages pending completion. The last member of
* the array is set to -1 to indicate there are no more tokens. If no tokens
* are pending, the pointer is set to NULL.
...
...
@@ -875,7 +890,7 @@ DLLExport int MQTTClient_getPendingDeliveryTokens(MQTTClient handle, MQTTClient_
/**
* When implementing a single-threaded client, call this function periodically
* to allow processing of message retries and to send MQTT keepalive pings.
* If the application is calling MQTTClient_receive() regularly, then it is
* If the application is calling MQTTClient_receive() regularly, then it is
* not necessary to call this function.
*/
DLLExport
void
MQTTClient_yield
(
void
);
...
...
@@ -883,45 +898,45 @@ DLLExport void MQTTClient_yield(void);
/**
* This function performs a synchronous receive of incoming messages. It should
* be used only when the client application has not set callback methods to
* support asynchronous receipt of messages (see @ref async and
* support asynchronous receipt of messages (see @ref async and
* MQTTClient_setCallbacks()). Using this function allows a single-threaded
* client subscriber application to be written. When called, this function
* blocks until the next message arrives or the specified timeout expires
* client subscriber application to be written. When called, this function
* blocks until the next message arrives or the specified timeout expires
*(see also MQTTClient_yield()).
*
* <b>Important note:</b> The application must free() the memory allocated
* to the topic and the message when processing is complete (see
* MQTTClient_freeMessage()).
* @param handle A valid client handle from a successful call to
* @param handle A valid client handle from a successful call to
* MQTTClient_create().
* @param topicName The address of a pointer to a topic. This function
* @param topicName The address of a pointer to a topic. This function
* allocates the memory for the topic and returns it to the application
* by setting <i>topicName</i> to point to the topic.
* @param topicLen The length of the topic. If the return code from this
* function is ::MQTTCLIENT_TOPICNAME_TRUNCATED, the topic contains embedded
* @param topicLen The length of the topic. If the return code from this
* function is ::MQTTCLIENT_TOPICNAME_TRUNCATED, the topic contains embedded
* NULL characters and the full topic should be retrieved by using
* <i>topicLen</i>.
* @param message The address of a pointer to the received message. This
* function allocates the memory for the message and returns it to the
* application by setting <i>message</i> to point to the received message.
* The pointer is set to NULL if the timeout expires.
* @param timeout The length of time to wait for a message in milliseconds.
* @return ::MQTTCLIENT_SUCCESS or ::MQTTCLIENT_TOPICNAME_TRUNCATED if a
* message is received. ::MQTTCLIENT_SUCCESS can also indicate that the
* timeout expired, in which case <i>message</i> is NULL. An error code is
* @param timeout The length of time to wait for a message in milliseconds.
* @return ::MQTTCLIENT_SUCCESS or ::MQTTCLIENT_TOPICNAME_TRUNCATED if a
* message is received. ::MQTTCLIENT_SUCCESS can also indicate that the
* timeout expired, in which case <i>message</i> is NULL. An error code is
* returned if there was a problem trying to receive a message.
*/
DLLExport
int
MQTTClient_receive
(
MQTTClient
handle
,
char
**
topicName
,
int
*
topicLen
,
MQTTClient_message
**
message
,
unsigned
long
timeout
);
/**
* This function frees memory allocated to an MQTT message, including the
* This function frees memory allocated to an MQTT message, including the
* additional memory allocated to the message payload. The client application
* calls this function when the message has been fully processed. <b>Important
* note:</b> This function does not free the memory allocated to a message
* topic string. It is the responsibility of the client application to free
* calls this function when the message has been fully processed. <b>Important
* note:</b> This function does not free the memory allocated to a message
* topic string. It is the responsibility of the client application to free
* this memory using the MQTTClient_free() library function.
* @param msg The address of a pointer to the ::MQTTClient_message structure
* @param msg The address of a pointer to the ::MQTTClient_message structure
* to be freed.
*/
DLLExport
void
MQTTClient_freeMessage
(
MQTTClient_message
**
msg
);
...
...
@@ -936,11 +951,11 @@ DLLExport void MQTTClient_freeMessage(MQTTClient_message** msg);
*/
DLLExport
void
MQTTClient_free
(
void
*
ptr
);
/**
/**
* This function frees the memory allocated to an MQTT client (see
* MQTTClient_create()). It should be called when the client is no longer
* MQTTClient_create()). It should be called when the client is no longer
* required.
* @param handle A pointer to the handle referring to the ::MQTTClient
* @param handle A pointer to the handle referring to the ::MQTTClient
* structure to be freed.
*/
DLLExport
void
MQTTClient_destroy
(
MQTTClient
*
handle
);
...
...
@@ -958,104 +973,104 @@ DLLExport void MQTTClient_destroy(MQTTClient* handle);
* calls MQTTClient_setCallbacks(), this puts the client into asynchronous
* mode, otherwise it operates in synchronous mode.
*
* In synchronous mode, the client application runs on a single thread.
* Messages are published using the MQTTClient_publish() and
* In synchronous mode, the client application runs on a single thread.
* Messages are published using the MQTTClient_publish() and
* MQTTClient_publishMessage() functions. To determine that a QoS1 or QoS2
* (see @ref qos) message has been successfully delivered, the application
* must call the MQTTClient_waitForCompletion() function. An example showing
* synchronous publication is shown in @ref pubsync. Receiving messages in
* synchronous publication is shown in @ref pubsync. Receiving messages in
* synchronous mode uses the MQTTClient_receive() function. Client applications
* must call either MQTTClient_receive() or MQTTClient_yield() relatively
* must call either MQTTClient_receive() or MQTTClient_yield() relatively
* frequently in order to allow processing of acknowledgements and the MQTT
* "pings" that keep the network connection to the server alive.
*
*
* In asynchronous mode, the client application runs on several threads. The
* main program calls functions in the client library to publish and subscribe,
* just as for the synchronous mode. Processing of handshaking and maintaining
* the network connection is performed in the background, however.
* Notifications of status and message reception are provided to the client
* application using callbacks registered with the library by the call to
* MQTTClient_setCallbacks() (see MQTTClient_messageArrived(),
* MQTTClient_setCallbacks() (see MQTTClient_messageArrived(),
* MQTTClient_connectionLost() and MQTTClient_deliveryComplete()).
* This API is not thread safe however - it is not possible to call it from multiple
* threads without synchronization. You can use the MQTTAsync API for that.
*
* @page wildcard Subscription wildcards
* Every MQTT message includes a topic that classifies it. MQTT servers use
* Every MQTT message includes a topic that classifies it. MQTT servers use
* topics to determine which subscribers should receive messages published to
* the server.
*
* Consider the server receiving messages from several environmental sensors.
*
* Consider the server receiving messages from several environmental sensors.
* Each sensor publishes its measurement data as a message with an associated
* topic. Subscribing applications need to know which sensor originally
* published each received message. A unique topic is thus used to identify
* each sensor and measurement type. Topics such as SENSOR1TEMP,
* SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very
* flexible. If additional sensors are added to the system at a later date,
* subscribing applications must be modified to receive them.
* topic. Subscribing applications need to know which sensor originally
* published each received message. A unique topic is thus used to identify
* each sensor and measurement type. Topics such as SENSOR1TEMP,
* SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very
* flexible. If additional sensors are added to the system at a later date,
* subscribing applications must be modified to receive them.
*
* To provide more flexibility, MQTT supports a hierarchical topic namespace.
* This allows application designers to organize topics to simplify their
* management. Levels in the hierarchy are delimited by the '/' character,
* such as SENSOR/1/HUMIDITY. Publishers and subscribers use these
* To provide more flexibility, MQTT supports a hierarchical topic namespace.
* This allows application designers to organize topics to simplify their
* management. Levels in the hierarchy are delimited by the '/' character,
* such as SENSOR/1/HUMIDITY. Publishers and subscribers use these
* hierarchical topics as already described.
*
* For subscriptions, two wildcard characters are supported:
* <ul>
* <li>A '#' character represents a complete sub-tree of the hierarchy and
* thus must be the last character in a subscription topic string, such as
* SENSOR/#. This will match any topic starting with SENSOR/, such as
* <li>A '#' character represents a complete sub-tree of the hierarchy and
* thus must be the last character in a subscription topic string, such as
* SENSOR/#. This will match any topic starting with SENSOR/, such as
* SENSOR/1/TEMP and SENSOR/2/HUMIDITY.</li>
* <li> A '+' character represents a single level of the hierarchy and is
* used between delimiters. For example, SENSOR/+/TEMP will match
* <li> A '+' character represents a single level of the hierarchy and is
* used between delimiters. For example, SENSOR/+/TEMP will match
* SENSOR/1/TEMP and SENSOR/2/TEMP.</li>
* </ul>
* Publishers are not allowed to use the wildcard characters in their topic
* Publishers are not allowed to use the wildcard characters in their topic
* names.
*
* Deciding on your topic hierarchy is an important step in your system design.
*
* @page qos Quality of service
* The MQTT protocol provides three qualities of service for delivering
* messages between clients and servers: "at most once", "at least once" and
* "exactly once".
* The MQTT protocol provides three qualities of service for delivering
* messages between clients and servers: "at most once", "at least once" and
* "exactly once".
*
* Quality of service (QoS) is an attribute of an individual message being
* Quality of service (QoS) is an attribute of an individual message being
* published. An application sets the QoS for a specific message by setting the
* MQTTClient_message.qos field to the required value.
*
* A subscribing client can set the maximum quality of service a server uses
* to send messages that match the client subscriptions. The
* MQTTClient_subscribe() and MQTTClient_subscribeMany() functions set this
* maximum. The QoS of a message forwarded to a subscriber thus might be
* different to the QoS given to the message by the original publisher.
* to send messages that match the client subscriptions. The
* MQTTClient_subscribe() and MQTTClient_subscribeMany() functions set this
* maximum. The QoS of a message forwarded to a subscriber thus might be
* different to the QoS given to the message by the original publisher.
* The lower of the two values is used to forward a message.
*
* The three levels are:
*
* <b>QoS0, At most once:</b> The message is delivered at most once, or it
* may not be delivered at all. Its delivery across the network is not
* acknowledged. The message is not stored. The message could be lost if the
* client is disconnected, or if the server fails. QoS0 is the fastest mode of
* <b>QoS0, At most once:</b> The message is delivered at most once, or it
* may not be delivered at all. Its delivery across the network is not
* acknowledged. The message is not stored. The message could be lost if the
* client is disconnected, or if the server fails. QoS0 is the fastest mode of
* transfer. It is sometimes called "fire and forget".
*
* The MQTT protocol does not require servers to forward publications at QoS0
* The MQTT protocol does not require servers to forward publications at QoS0
* to a client. If the client is disconnected at the time the server receives
* the publication, the publication might be discarded, depending on the
* the publication, the publication might be discarded, depending on the
* server implementation.
*
* <b>QoS1, At least once:</b> The message is always delivered at least once.
* It might be delivered multiple times if there is a failure before an
* acknowledgment is received by the sender. The message must be stored
* locally at the sender, until the sender receives confirmation that the
* message has been published by the receiver. The message is stored in case
*
* <b>QoS1, At least once:</b> The message is always delivered at least once.
* It might be delivered multiple times if there is a failure before an
* acknowledgment is received by the sender. The message must be stored
* locally at the sender, until the sender receives confirmation that the
* message has been published by the receiver. The message is stored in case
* the message must be sent again.
*
* <b>QoS2, Exactly once:</b> The message is always delivered exactly once.
*
* <b>QoS2, Exactly once:</b> The message is always delivered exactly once.
* The message must be stored locally at the sender, until the sender receives
* confirmation that the message has been published by the receiver. The
* message is stored in case the message must be sent again. QoS2 is the
* safest, but slowest mode of transfer. A more sophisticated handshaking
* confirmation that the message has been published by the receiver. The
* message is stored in case the message must be sent again. QoS2 is the
* safest, but slowest mode of transfer. A more sophisticated handshaking
* and acknowledgement sequence is used than for QoS1 to ensure no duplication
* of messages occurs.
* @page pubsync Synchronous publication example
...
...
@@ -1189,7 +1204,7 @@ int main(int argc, char* argv[])
MQTTClient_destroy(&client);
return rc;
}
* @endcode
* @page subasync Asynchronous subscription example
@code
...
...
@@ -1262,7 +1277,7 @@ int main(int argc, char* argv[])
"Press Q<Enter> to quit\n\n", TOPIC, CLIENTID, QOS);
MQTTClient_subscribe(client, TOPIC, QOS);
do
do
{
ch = getchar();
} while(ch!='Q' && ch != 'q');
...
...
@@ -1271,10 +1286,10 @@ int main(int argc, char* argv[])
MQTTClient_destroy(&client);
return rc;
}
* @endcode
* @page tracing Tracing
*
*
* Runtime tracing is controlled by environment variables.
*
* Tracing is switched on by setting MQTT_C_CLIENT_TRACE. A value of ON, or stdout, prints to
...
...
@@ -1289,8 +1304,8 @@ int main(int argc, char* argv[])
* new trace entries. The default size is 1000 lines.
*
* ### MQTT Packet Tracing
*
* A feature that can be very useful is printing the MQTT packets that are sent and received. To
*
* A feature that can be very useful is printing the MQTT packets that are sent and received. To
* achieve this, use the following environment variable settings:
* @code
MQTT_C_CLIENT_TRACE=ON
...
...
@@ -1313,7 +1328,7 @@ int main(int argc, char* argv[])
* 6. packet details
*
* ### Default Level Tracing
*
*
* This is an extract of a default level trace of a call to connect:
* @code
19700101 010000.000 (1152206656) (0)> MQTTClient_connect:893
...
...
@@ -1344,22 +1359,22 @@ int main(int argc, char* argv[])
* 7. return value (if there is one)
*
* ### Memory Allocation Tracing
*
* Setting the trace level to maximum causes memory allocations and frees to be traced along with
*
* Setting the trace level to maximum causes memory allocations and frees to be traced along with
* the default trace entries, with messages like the following:
* @code
20130528 161819.657 Allocating 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 177 ptr 0x179f930
20130528 161819.657 Freeing 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 201, heap use now 896 bytes
* @endcode
* When the last MQTT client object is destroyed, if the trace is being recorded
* When the last MQTT client object is destroyed, if the trace is being recorded
* and all memory allocated by the client library has not been freed, an error message will be
* written to the trace. This can help with fixing memory leaks. The message will look like this:
* @code
20130528 163909.208 Some memory not freed at shutdown, possible memory leak
20130528 163909.208 Heap scan start, total 880 bytes
20130528 163909.208 Heap element size 32, line 354, file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c, ptr 0x260cb00
20130528 163909.208 Content
20130528 163909.208 Content
20130528 163909.209 Heap scan end
* @endcode
* @endcond
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment