MQTTClient.c File Reference

Synchronous API implementation. More...

#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include "MQTTClient.h"
#include "MQTTPersistence.h"
#include "utf-8.h"
#include "MQTTProtocol.h"
#include "MQTTProtocolOut.h"
#include "Thread.h"
#include "SocketBuffer.h"
#include "StackTrace.h"
#include "Heap.h"
#include "OsWrapper.h"
#include "VersionInfo.h"
Include dependency graph for MQTTClient.c:

Data Structures

struct  qEntry
struct  MQTTClients

Defines

#define _GNU_SOURCE
#define URI_SSL   "ssl://"
#define URI_TCP   "tcp://"
#define WINAPI
#define START_TIME_TYPE   struct timeval
#define MAX_INFO_STRINGS   8

Functions

void MQTTClient_global_init (MQTTClient_init_options *inits)
 Global init of mqtt library.
void MQTTClient_init (void)
void MQTTClient_sleep (long milliseconds)
START_TIME_TYPE MQTTClient_start_clock (void)
long MQTTClient_elapsed (struct timeval start)
static void MQTTClient_terminate (void)
static void MQTTClient_emptyMessageQueue (Clients *client)
static int MQTTClient_deliverMessage (int rc, MQTTClients *m, char **topicName, int *topicLen, MQTTClient_message **message)
static int clientSockCompare (void *a, void *b)
 List callback function for comparing clients by socket.
static thread_return_type WINAPI connectionLost_call (void *context)
 Wrapper function to call connection lost on a separate thread.
static thread_return_type WINAPI MQTTClient_run (void *n)
static void MQTTClient_stop (void)
static void MQTTClient_closeSession (Clients *client)
static int MQTTClient_cleanSession (Clients *client)
static int MQTTClient_connectURIVersion (MQTTClient handle, MQTTClient_connectOptions *options, const char *serverURI, int MQTTVersion, START_TIME_TYPE start, long millisecsTimeout)
static int MQTTClient_connectURI (MQTTClient handle, MQTTClient_connectOptions *options, const char *serverURI)
static int MQTTClient_disconnect1 (MQTTClient handle, int timeout, int call_connection_lost, int stop)
 mqttclient_mutex must be locked when you call this function, if multi threaded
static int MQTTClient_disconnect_internal (MQTTClient handle, int timeout)
 mqttclient_mutex must be locked when you call this function, if multi threaded
static void MQTTClient_retry (void)
static MQTTPacketMQTTClient_cycle (int *sock, unsigned long timeout, int *rc)
static MQTTPacketMQTTClient_waitfor (MQTTClient handle, int packet_type, int *rc, long timeout)
static void MQTTProtocol_checkPendingWrites (void)
 See if any pending writes have been completed, and cleanup if so.
static void MQTTClient_writeComplete (int socket, int rc)
int MQTTClient_create (MQTTClient *handle, const char *serverURI, const char *clientId, int persistence_type, void *persistence_context)
 This function creates an MQTT client ready for connection to the specified server and using the specified persistent storage (see MQTTClient_persistence).
void MQTTClient_destroy (MQTTClient *handle)
 This function frees the memory allocated to an MQTT client (see MQTTClient_create()).
void MQTTClient_freeMessage (MQTTClient_message **message)
 This function frees memory allocated to an MQTT message, including the additional memory allocated to the message payload.
void MQTTClient_free (void *memory)
 This function frees memory allocated by the MQTT C client library, especially the topic name.
int MQTTClient_setCallbacks (MQTTClient handle, void *context, MQTTClient_connectionLost *cl, MQTTClient_messageArrived *ma, MQTTClient_deliveryComplete *dc)
 This function sets the callback functions for a specific client.
void Protocol_processPublication (Publish *publish, Clients *client)
static void setRetryLoopInterval (int keepalive)
int MQTTClient_connect (MQTTClient handle, MQTTClient_connectOptions *options)
 This function attempts to connect a previously-created client (see MQTTClient_create()) to an MQTT server using the specified options.
void MQTTProtocol_closeSession (Clients *c, int sendwill)
 mqttclient_mutex must be locked when you call this function, if multi threaded
int MQTTClient_disconnect (MQTTClient handle, int timeout)
 This function attempts to disconnect the client from the MQTT server.
int MQTTClient_isConnected (MQTTClient handle)
 This function allows the client application to test whether or not a client is currently connected to the MQTT server.
int MQTTClient_subscribeMany (MQTTClient handle, int count, char *const *topic, int *qos)
 This function attempts to subscribe a client to a list of topics, which may contain wildcards (see wildcard).
int MQTTClient_subscribe (MQTTClient handle, const char *topic, int qos)
 This function attempts to subscribe a client to a single topic, which may contain wildcards (see wildcard).
int MQTTClient_unsubscribeMany (MQTTClient handle, int count, char *const *topic)
 This function attempts to remove existing subscriptions to a list of topics made by the specified client.
int MQTTClient_unsubscribe (MQTTClient handle, const char *topic)
 This function attempts to remove an existing subscription made by the specified client.
int MQTTClient_publish (MQTTClient handle, const char *topicName, int payloadlen, void *payload, int qos, int retained, MQTTClient_deliveryToken *deliveryToken)
 This function attempts to publish a message to a given topic (see also MQTTClient_publishMessage()).
int MQTTClient_publishMessage (MQTTClient handle, const char *topicName, MQTTClient_message *message, MQTTClient_deliveryToken *deliveryToken)
 This function attempts to publish a message to a given topic (see also MQTTClient_publish()).
int MQTTClient_receive (MQTTClient handle, char **topicName, int *topicLen, MQTTClient_message **message, unsigned long timeout)
 This function performs a synchronous receive of incoming messages.
void MQTTClient_yield (void)
 When implementing a single-threaded client, call this function periodically to allow processing of message retries and to send MQTT keepalive pings.
int MQTTClient_waitForCompletion (MQTTClient handle, MQTTClient_deliveryToken mdt, unsigned long timeout)
 This function is called by the client application to synchronize execution of the main thread with completed publication of a message.
int MQTTClient_getPendingDeliveryTokens (MQTTClient handle, MQTTClient_deliveryToken **tokens)
 This function sets a pointer to an array of delivery tokens for messages that are currently in-flight (pending completion).
MQTTClient_nameValueMQTTClient_getVersionInfo (void)
 This function returns version information about the library.

Variables

const char * client_timestamp_eye = "MQTTClientV3_Timestamp " BUILD_TIMESTAMP
const char * client_version_eye = "MQTTClientV3_Version " CLIENT_VERSION
static ClientStates ClientState
ClientStatesbstate = &ClientState
MQTTProtocol state
static pthread_mutex_t mqttclient_mutex_store = PTHREAD_MUTEX_INITIALIZER
static mutex_type mqttclient_mutex = &mqttclient_mutex_store
static pthread_mutex_t socket_mutex_store = PTHREAD_MUTEX_INITIALIZER
static mutex_type socket_mutex = &socket_mutex_store
static pthread_mutex_t subscribe_mutex_store = PTHREAD_MUTEX_INITIALIZER
static mutex_type subscribe_mutex = &subscribe_mutex_store
static pthread_mutex_t unsubscribe_mutex_store = PTHREAD_MUTEX_INITIALIZER
static mutex_type unsubscribe_mutex = &unsubscribe_mutex_store
static pthread_mutex_t connect_mutex_store = PTHREAD_MUTEX_INITIALIZER
static mutex_type connect_mutex = &connect_mutex_store
static volatile int initialized = 0
static Listhandles = NULL
static int running = 0
static int tostop = 0
static thread_id_type run_id = 0
static int retryLoopInterval = 5

Detailed Description

Synchronous API implementation.


Function Documentation

static int clientSockCompare ( void *  a,
void *  b 
) [static]

List callback function for comparing clients by socket.

Parameters:
a first integer value
b second integer value
Returns:
boolean indicating whether a and b are equal
static thread_return_type WINAPI connectionLost_call ( void *  context  )  [static]

Wrapper function to call connection lost on a separate thread.

A separate thread is needed to allow the connectionLost function to make API calls (e.g. connect)

Parameters:
context a pointer to the relevant client
Returns:
thread_return_type standard thread return value - not used here
int MQTTClient_connect ( MQTTClient  handle,
MQTTClient_connectOptions options 
)

This function attempts to connect a previously-created client (see 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().

Parameters:
handle A valid client handle from a successful call to MQTTClient_create().
options A pointer to a valid MQTTClient_connectOptions structure.
Returns:
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. Error codes greater than 0 are returned by the MQTT protocol:

1: Connection refused: Unacceptable protocol version
2: Connection refused: Identifier rejected
3: Connection refused: Server unavailable
4: Connection refused: Bad user name or password
5: Connection refused: Not authorized
6-255: Reserved for future use

Here is the call graph for this function:

int MQTTClient_create ( MQTTClient *  handle,
const char *  serverURI,
const char *  clientId,
int  persistence_type,
void *  persistence_context 
)

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().

Parameters:
handle A pointer to an MQTTClient handle. The handle is populated with a valid client reference following a successful return from this function.
serverURI A null-terminated string specifying the server to which the client will connect. It takes the form protocol://host:port. Currently, protocol must be tcp or ssl. For host, 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 tcp://localhost:1883.
clientId The client identifier passed to the server when the client connects to it. It is a null-terminated UTF-8 encoded string.
persistence_type The type of persistence to be used by the client:
MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or system on which the client is running fails or is switched off, the current state of any in-flight messages is lost and some messages may not be delivered even at QoS1 and QoS2.
MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based) persistence mechanism. Status about in-flight messages is held in persistent storage and provides some protection against message loss in the case of unexpected failure.
MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence implementation. Using this type of persistence gives control of the persistence mechanism to the application. The application has to implement the MQTTClient_persistence interface.
persistence_context If the application uses MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should be set to NULL. For MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it should be set to the location of the persistence directory (if set to NULL, the persistence directory used is the working directory). Applications that use MQTTCLIENT_PERSISTENCE_USER persistence set this argument to point to a valid MQTTClient_persistence structure.
Returns:
MQTTCLIENT_SUCCESS if the client is successfully created, otherwise an error code is returned.

Here is the call graph for this function:

void MQTTClient_destroy ( MQTTClient *  handle  ) 

This function frees the memory allocated to an MQTT client (see MQTTClient_create()).

It should be called when the client is no longer required.

Parameters:
handle A pointer to the handle referring to the MQTTClient structure to be freed.

Here is the call graph for this function:

int MQTTClient_disconnect ( MQTTClient  handle,
int  timeout 
)

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 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 MQTTClient_connectOptions.cleansession and MQTTClient_connect()).

Parameters:
handle A valid client handle from a successful call to MQTTClient_create().
timeout The client delays disconnection for up to this time (in milliseconds) in order to allow in-flight message transfers to complete.
Returns:
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

Here is the call graph for this function:

void MQTTClient_free ( void *  ptr  ) 

This function frees memory allocated by the MQTT C client library, especially the topic name.

This is needed on Windows when the client libary and application program have been compiled with different versions of the C compiler. It is thus good policy to always use this function when freeing any MQTT C client- allocated memory.

Parameters:
ptr The pointer to the client library storage to be freed.
void MQTTClient_freeMessage ( MQTTClient_message **  msg  ) 

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. Important note: 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.

Parameters:
msg The address of a pointer to the MQTTClient_message structure to be freed.
int MQTTClient_getPendingDeliveryTokens ( MQTTClient  handle,
MQTTClient_deliveryToken **  tokens 
)

This function sets a pointer to an array of delivery tokens for messages that are currently in-flight (pending completion).

Important note: 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.

Parameters:
handle A valid client handle from a successful call to MQTTClient_create().
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.
Returns:
MQTTCLIENT_SUCCESS if the function returns successfully. An error code is returned if there was a problem obtaining the list of pending tokens.

Here is the call graph for this function:

MQTTClient_nameValue* MQTTClient_getVersionInfo ( void   ) 

This function returns version information about the library.

no trace information will be returned.

Returns:
an array of strings describing the library. The last entry is a NULL pointer.
void MQTTClient_global_init ( MQTTClient_init_options inits  ) 

Global init of mqtt library.

Call once on program start to set global behaviour. do_openssl_init - if mqtt library should initialize OpenSSL (1) or rely on the caller to do it before using the library (0)

int MQTTClient_isConnected ( MQTTClient  handle  ) 

This function allows the client application to test whether or not a client is currently connected to the MQTT server.

Parameters:
handle A valid client handle from a successful call to MQTTClient_create().
Returns:
Boolean true if the client is connected, otherwise false.

Here is the call graph for this function:

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_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 async, MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()).

Parameters:
handle A valid client handle from a successful call to MQTTClient_create().
topicName The topic associated with this message.
payloadlen The length of the payload in bytes.
payload A pointer to the byte array payload of the message.
qos The qos of the message.
retained The retained flag for the message.
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 argument to NULL.
Returns:
MQTTCLIENT_SUCCESS if the message is accepted for publication. An error code is returned if there was a problem accepting the message.

Here is the call graph for this function:

int MQTTClient_publishMessage ( MQTTClient  handle,
const char *  topicName,
MQTTClient_message msg,
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 async, MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()).

Parameters:
handle A valid client handle from a successful call to MQTTClient_create().
topicName The topic associated with this message.
msg A pointer to a valid MQTTClient_message structure containing the payload and attributes of the message to be published.
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 argument to NULL.
Returns:
MQTTCLIENT_SUCCESS if the message is accepted for publication. An error code is returned if there was a problem accepting the message.

Here is the call graph for this function:

int MQTTClient_receive ( MQTTClient  handle,
char **  topicName,
int *  topicLen,
MQTTClient_message **  message,
unsigned long  timeout 
)

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 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 (see also MQTTClient_yield()).

Important note: The application must free() the memory allocated to the topic and the message when processing is complete (see MQTTClient_freeMessage()).

Parameters:
handle A valid client handle from a successful call to MQTTClient_create().
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 topicName to point to the topic.
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 topicLen.
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 message to point to the received message. The pointer is set to NULL if the timeout expires.
timeout The length of time to wait for a message in milliseconds.
Returns:
MQTTCLIENT_SUCCESS or MQTTCLIENT_TOPICNAME_TRUNCATED if a message is received. MQTTCLIENT_SUCCESS can also indicate that the timeout expired, in which case message is NULL. An error code is returned if there was a problem trying to receive a message.

Here is the call graph for this function:

int MQTTClient_setCallbacks ( MQTTClient  handle,
void *  context,
MQTTClient_connectionLost *  cl,
MQTTClient_messageArrived *  ma,
MQTTClient_deliveryComplete *  dc 
)

This function sets the callback functions for a specific client.

If your client application doesn't use a particular callback, set the relevant parameter to NULL. Calling MQTTClient_setCallbacks() puts the client into multi-threaded mode. Any necessary message acknowledgements and status communications are handled in the background without any intervention from the client application. See async for more information.

Note: The MQTT client must be disconnected when this function is called.

Parameters:
handle A valid client handle from a successful call to MQTTClient_create().
context A pointer to any application-specific context. The the context pointer is passed to each of the callback functions to provide access to the context information in the callback.
cl A pointer to an MQTTClient_connectionLost() callback function. You can set this to NULL if your application doesn't handle disconnections.
ma A pointer to an MQTTClient_messageArrived() callback function. This callback function must be specified when you call MQTTClient_setCallbacks().
dc A pointer to an MQTTClient_deliveryComplete() callback function. You can set this to NULL if your application publishes synchronously or if you do not want to check for successful delivery.
Returns:
MQTTCLIENT_SUCCESS if the callbacks were correctly set, MQTTCLIENT_FAILURE if an error occurred.

Here is the call graph for this function:

int MQTTClient_subscribe ( MQTTClient  handle,
const char *  topic,
int  qos 
)

This function attempts to subscribe a client to a single topic, which may contain wildcards (see wildcard).

This call also specifies the qos requested for the subscription (see also MQTTClient_subscribeMany()).

Parameters:
handle A valid client handle from a successful call to MQTTClient_create().
topic The subscription topic, which may include wildcards.
qos The requested quality of service for the subscription.
Returns:
MQTTCLIENT_SUCCESS if the subscription request is successful. An error code is returned if there was a problem registering the subscription.

Here is the call graph for this function:

int MQTTClient_subscribeMany ( MQTTClient  handle,
int  count,
char *const *  topic,
int *  qos 
)

This function attempts to subscribe a client to a list of topics, which may contain wildcards (see wildcard).

This call also specifies the qos requested for each topic (see also MQTTClient_subscribe()).

Parameters:
handle A valid client handle from a successful call to MQTTClient_create().
count The number of topics for which the client is requesting subscriptions.
topic An array (of length count) of pointers to topics, each of which may include wildcards.
qos An array (of length count) of qos values. qos[n] is the requested QoS for topic[n].
Returns:
MQTTCLIENT_SUCCESS if the subscription request is successful. An error code is returned if there was a problem registering the subscriptions.

Here is the call graph for this function:

int MQTTClient_unsubscribe ( MQTTClient  handle,
const char *  topic 
)

This function attempts to remove an existing subscription made by the specified client.

Parameters:
handle A valid client handle from a successful call to MQTTClient_create().
topic The topic for the subscription to be removed, which may include wildcards (see wildcard).
Returns:
MQTTCLIENT_SUCCESS if the subscription is removed. An error code is returned if there was a problem removing the subscription.

Here is the call graph for this function:

int MQTTClient_unsubscribeMany ( MQTTClient  handle,
int  count,
char *const *  topic 
)

This function attempts to remove existing subscriptions to a list of topics made by the specified client.

Parameters:
handle A valid client handle from a successful call to MQTTClient_create().
count The number subscriptions to be removed.
topic An array (of length count) of pointers to the topics of the subscriptions to be removed, each of which may include wildcards.
Returns:
MQTTCLIENT_SUCCESS if the subscriptions are removed. An error code is returned if there was a problem removing the subscriptions.

Here is the call graph for this function:

int MQTTClient_waitForCompletion ( MQTTClient  handle,
MQTTClient_deliveryToken  dt,
unsigned long  timeout 
)

This function is called by the client application to synchronize execution 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 async.

Parameters:
handle A valid client handle from a successful call to MQTTClient_create().
dt The MQTTClient_deliveryToken that represents the message being tested for successful delivery. Delivery tokens are issued by the publishing functions MQTTClient_publish() and MQTTClient_publishMessage().
timeout The maximum time to wait in milliseconds.
Returns:
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.

Here is the call graph for this function:

void MQTTClient_yield ( void   ) 

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 not necessary to call this function.

Here is the call graph for this function:

static void MQTTProtocol_checkPendingWrites ( void   )  [static]

See if any pending writes have been completed, and cleanup if so.

Cleaning up means removing any publication data that was stored because the write did not originally complete.

Here is the call graph for this function:


Variable Documentation

ClientStates ClientState [static]
Initial value:
{
        CLIENT_VERSION, 
        NULL 
}
 All Data Structures Files Functions Variables Typedefs Defines

Generated on 2 Jun 2018 for MQTT C Client Libraries Internals by  doxygen 1.6.1