Commit 97c72804 authored by Ian Craggs's avatar Ian Craggs

New asynchronous MQTT API (see MQTTAsync.h) and

SSL support for both old and new APIs.
parent 125edbb6
This diff is collapsed.
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009, 2012 IBM Corp. * Copyright (c) 2009, 2013 IBM Corp.
* *
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* *
* Contributors: * Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation * Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs - add SSL support
*******************************************************************************/ *******************************************************************************/
/** /**
...@@ -46,5 +47,5 @@ int clientSocketCompare(void* a, void* b) ...@@ -46,5 +47,5 @@ int clientSocketCompare(void* a, void* b)
{ {
Clients* client = (Clients*)a; Clients* client = (Clients*)a;
/*printf("comparing %d with %d\n", (char*)a, (char*)b); */ /*printf("comparing %d with %d\n", (char*)a, (char*)b); */
return client->socket == *(int*)b; return client->net.socket == *(int*)b;
} }
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009, 2012 IBM Corp. * Copyright (c) 2009, 2013 IBM Corp.
* *
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
...@@ -8,12 +8,20 @@ ...@@ -8,12 +8,20 @@
* *
* Contributors: * Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation * Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs - add SSL support
*******************************************************************************/ *******************************************************************************/
#if !defined(CLIENTS_H) #if !defined(CLIENTS_H)
#define CLIENTS_H #define CLIENTS_H
#include <time.h> #include <time.h>
#if defined(OPENSSL)
#if defined(WIN32)
#include "winsock2.h"
#endif
#include <openssl/ssl.h>
#endif
#include "MQTTClient.h"
#include "LinkedList.h" #include "LinkedList.h"
#include "MQTTClientPersistence.h" #include "MQTTClientPersistence.h"
/*BE /*BE
...@@ -116,6 +124,7 @@ def CLIENTS ...@@ -116,6 +124,7 @@ def CLIENTS
at 4 n8 bits 7:6 dec "connect_state" at 4 n8 bits 7:6 dec "connect_state"
at 8 at 8
n32 dec "socket" n32 dec "socket"
n32 ptr "SSL"
n32 dec "msgID" n32 dec "msgID"
n32 dec "keepAliveInterval" n32 dec "keepAliveInterval"
n32 dec "maxInflightMessages" n32 dec "maxInflightMessages"
...@@ -132,6 +141,15 @@ defList(CLIENTS) ...@@ -132,6 +141,15 @@ defList(CLIENTS)
BE*/ BE*/
typedef struct
{
int socket;
#if defined(OPENSSL)
SSL* ssl;
SSL_CTX* ctx;
#endif
} networkHandles;
/** /**
* Data related to one client * Data related to one client
*/ */
...@@ -144,8 +162,8 @@ typedef struct ...@@ -144,8 +162,8 @@ typedef struct
unsigned int connected : 1; /**< whether it is currently connected */ unsigned int connected : 1; /**< whether it is currently connected */
unsigned int good : 1; /**< if we have an error on the socket we turn this off */ unsigned int good : 1; /**< if we have an error on the socket we turn this off */
unsigned int ping_outstanding : 1; unsigned int ping_outstanding : 1;
unsigned int connect_state : 2; int connect_state : 4;
int socket; networkHandles net;
int msgID; int msgID;
int keepAliveInterval; int keepAliveInterval;
int retryInterval; int retryInterval;
...@@ -155,9 +173,13 @@ typedef struct ...@@ -155,9 +173,13 @@ typedef struct
List* inboundMsgs; List* inboundMsgs;
List* outboundMsgs; /**< in flight */ List* outboundMsgs; /**< in flight */
List* messageQueue; List* messageQueue;
unsigned int qentry_seqno;
void* phandle; /* the persistence handle */ void* phandle; /* the persistence handle */
MQTTClient_persistence* persistence; /* a persistence implementation */ MQTTClient_persistence* persistence; /* a persistence implementation */
int connectOptionsVersion; #if defined(OPENSSL)
MQTTClient_SSLOptions *sslopts;
SSL_SESSION* session; /***< SSL session pointer for fast handhake */
#endif
} Clients; } Clients;
int clientIDCompare(void* a, void* b); int clientIDCompare(void* a, void* b);
......
This diff is collapsed.
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009, 2012 IBM Corp. * Copyright (c) 2009, 2013 IBM Corp.
* *
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
...@@ -8,19 +8,22 @@ ...@@ -8,19 +8,22 @@
* *
* Contributors: * Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation * Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs - use tree data structure instead of list
*******************************************************************************/ *******************************************************************************/
#if !defined(HEAP_H) #if !defined(HEAP_H)
#define HEAP_H #define HEAP_H
#include <stdio.h> #if defined(HIGH_PERFORMANCE)
#define NO_HEAP_TRACKING 1
#endif
#include <stdio.h>
#include <memory.h> #include <memory.h>
#include <stdlib.h> #include <stdlib.h>
#define HEAP_TRACKING 1 #if !defined(NO_HEAP_TRACKING)
#if HEAP_TRACKING
/** /**
* redefines malloc to use "mymalloc" so that heap allocation can be tracked * redefines malloc to use "mymalloc" so that heap allocation can be tracked
* @param x the size of the item to be allocated * @param x the size of the item to be allocated
...@@ -44,23 +47,27 @@ ...@@ -44,23 +47,27 @@
#endif #endif
void* mymalloc(char*, int, size_t size); /**
void* myrealloc(char*, int, void* p, size_t size); * Information about the state of the heap.
void myfree(char*, int, void* p); */
void* Heap_findItem(void* p);
void Heap_unlink(char*, int, void* p);
typedef struct typedef struct
{ {
int current_size; int current_size; /**< current size of the heap in bytes */
int max_size; int max_size; /**< max size the heap has reached in bytes */
} heap_info; } heap_info;
void HeapScan();
void* mymalloc(char*, int, size_t size);
void* myrealloc(char*, int, void* p, size_t size);
void myfree(char*, int, void* p);
void Heap_scan(FILE* file);
int Heap_initialize(void); int Heap_initialize(void);
void Heap_terminate(void); void Heap_terminate(void);
heap_info* Heap_get_info(void); heap_info* Heap_get_info(void);
int HeapDump(FILE* file); int HeapDump(FILE* file);
int HeapDumpString(FILE* file, char* str); int HeapDumpString(FILE* file, char* str);
void* Heap_findItem(void* p);
void Heap_unlink(char* file, int line, void* p);
#endif #endif
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009, 2012 IBM Corp. * Copyright (c) 2009, 2013 IBM Corp.
* *
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* *
* Contributors: * Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation * Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs - updates for the async client
*******************************************************************************/ *******************************************************************************/
/** /**
...@@ -253,9 +254,9 @@ int ListRemove(List* aList, void* content) ...@@ -253,9 +254,9 @@ int ListRemove(List* aList, void* content)
* @param aList the list from which the item is to be removed * @param aList the list from which the item is to be removed
* @return 1=item removed, 0=item not removed * @return 1=item removed, 0=item not removed
*/ */
int ListRemoveHead(List* aList) void* ListDetachHead(List* aList)
{ {
int rc = 0; void *content = NULL;
if (aList->count > 0) if (aList->count > 0)
{ {
ListElement* first = aList->first; ListElement* first = aList->first;
...@@ -263,14 +264,26 @@ int ListRemoveHead(List* aList) ...@@ -263,14 +264,26 @@ int ListRemoveHead(List* aList)
aList->current = first->next; aList->current = first->next;
if (aList->last == first) /* i.e. no of items in list == 1 */ if (aList->last == first) /* i.e. no of items in list == 1 */
aList->last = NULL; aList->last = NULL;
free(first->content); content = first->content;
aList->first = aList->first->next; aList->first = aList->first->next;
if (aList->first) if (aList->first)
aList->first->prev = NULL; aList->first->prev = NULL;
free(first); free(first);
--(aList->count); --(aList->count);
} }
return rc; return content;
}
/**
* Removes and frees an the first item in a list.
* @param aList the list from which the item is to be removed
* @return 1=item removed, 0=item not removed
*/
int ListRemoveHead(List* aList)
{
free(ListDetachHead(aList));
return 0;
} }
......
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009, 2012 IBM Corp. * Copyright (c) 2009, 2013 IBM Corp.
* *
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* *
* Contributors: * Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation * Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs - updates for the async client
*******************************************************************************/ *******************************************************************************/
#if !defined(LINKEDLIST_H) #if !defined(LINKEDLIST_H)
...@@ -74,6 +75,7 @@ void ListInsert(List* aList, void* content, int size, ListElement* index); ...@@ -74,6 +75,7 @@ void ListInsert(List* aList, void* content, int size, ListElement* index);
int ListRemove(List* aList, void* content); int ListRemove(List* aList, void* content);
int ListRemoveItem(List* aList, void* content, int(*callback)(void*, void*)); int ListRemoveItem(List* aList, void* content, int(*callback)(void*, void*));
void* ListDetachHead(List* aList);
int ListRemoveHead(List* aList); int ListRemoveHead(List* aList);
void* ListPopTail(List* aList); void* ListPopTail(List* aList);
......
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009, 2012 IBM Corp. * Copyright (c) 2009, 2013 IBM Corp.
* *
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* *
* Contributors: * Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation * Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs - updates for the async client
*******************************************************************************/ *******************************************************************************/
#include "Log.h" #include "Log.h"
...@@ -17,6 +18,7 @@ ...@@ -17,6 +18,7 @@
#include "Messages.h" #include "Messages.h"
#include "LinkedList.h" #include "LinkedList.h"
#include "StackTrace.h" #include "StackTrace.h"
#include "Thread.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -26,6 +28,7 @@ ...@@ -26,6 +28,7 @@
#if !defined(WIN32) #if !defined(WIN32)
#include <syslog.h> #include <syslog.h>
#include <sys/stat.h>
#define GETTIMEOFDAY 1 #define GETTIMEOFDAY 1
#else #else
#define snprintf _snprintf #define snprintf _snprintf
...@@ -37,6 +40,13 @@ ...@@ -37,6 +40,13 @@
#include <sys/timeb.h> #include <sys/timeb.h>
#endif #endif
#if !defined(WIN32)
/**
* _unlink mapping for linux
*/
#define _unlink unlink
#endif
#if !defined(min) #if !defined(min)
#define min(A,B) ( (A) < (B) ? (A):(B)) #define min(A,B) ( (A) < (B) ? (A):(B))
...@@ -75,7 +85,13 @@ static traceEntry* trace_queue = NULL; ...@@ -75,7 +85,13 @@ static traceEntry* trace_queue = NULL;
static int trace_queue_size = 0; static int trace_queue_size = 0;
static FILE* trace_destination = NULL; /**< flag to indicate if trace is to be sent to a stream */ static FILE* trace_destination = NULL; /**< flag to indicate if trace is to be sent to a stream */
static char* trace_destination_name = NULL; /**< the name of the trace file */
static char* trace_destination_backup_name = NULL; /**< the name of the backup trace file */
static int lines_written = 0; /**< number of lines written to the current output file */
static int max_lines_per_file = 1000; /**< maximum number of lines to write to one trace file */
static int trace_output_level = -1; static int trace_output_level = -1;
static Log_traceCallback* trace_callback = NULL;
static void Log_output(int log_level, char* msg);
static int sametime_count = 0; static int sametime_count = 0;
#if defined(GETTIMEOFDAY) #if defined(GETTIMEOFDAY)
...@@ -85,8 +101,15 @@ struct timeb ts, last_ts; ...@@ -85,8 +101,15 @@ struct timeb ts, last_ts;
#endif #endif
static char msg_buf[512]; static char msg_buf[512];
#if defined(WIN32)
mutex_type log_mutex;
#else
static pthread_mutex_t log_mutex_store = PTHREAD_MUTEX_INITIALIZER;
static mutex_type log_mutex = &log_mutex_store;
#endif
int Log_initialize() int Log_initialize(Log_nameValue* info)
{ {
int rc = -1; int rc = -1;
char* envval = NULL; char* envval = NULL;
...@@ -97,8 +120,21 @@ int Log_initialize() ...@@ -97,8 +120,21 @@ int Log_initialize()
if ((envval = getenv("MQTT_C_CLIENT_TRACE")) != NULL && strlen(envval) > 0) if ((envval = getenv("MQTT_C_CLIENT_TRACE")) != NULL && strlen(envval) > 0)
{ {
if (strcmp(envval, "ON") == 0 || (trace_destination = fopen(envval, "wt")) == NULL) if (strcmp(envval, "ON") == 0 || (trace_destination = fopen(envval, "w")) == NULL)
trace_destination = stdout; trace_destination = stdout;
else
{
trace_destination_name = malloc(strlen(envval) + 1);
strcpy(trace_destination_name, envval);
trace_destination_backup_name = malloc(strlen(envval) + 3);
sprintf(trace_destination_backup_name, "%s.0", trace_destination_name);
}
}
if ((envval = getenv("MQTT_C_CLIENT_TRACE_MAX_LINES")) != NULL && strlen(envval) > 0)
{
max_lines_per_file = atoi(envval);
if (max_lines_per_file <= 0)
max_lines_per_file = 1000;
} }
if ((envval = getenv("MQTT_C_CLIENT_TRACE_LEVEL")) != NULL && strlen(envval) > 0) if ((envval = getenv("MQTT_C_CLIENT_TRACE_LEVEL")) != NULL && strlen(envval) > 0)
{ {
...@@ -110,11 +146,58 @@ int Log_initialize() ...@@ -110,11 +146,58 @@ int Log_initialize()
trace_settings.trace_level = TRACE_MINIMUM; trace_settings.trace_level = TRACE_MINIMUM;
else if (strcmp(envval, "PROTOCOL") == 0 || strcmp(envval, "TRACE_PROTOCOL") == 0) else if (strcmp(envval, "PROTOCOL") == 0 || strcmp(envval, "TRACE_PROTOCOL") == 0)
trace_output_level = TRACE_PROTOCOL; trace_output_level = TRACE_PROTOCOL;
else if (strcmp(envval, "ERROR") == 0 || strcmp(envval, "TRACE_ERROR") == 0)
trace_output_level = LOG_ERROR;
}
Log_output(TRACE_MINIMUM, "=========================================================");
Log_output(TRACE_MINIMUM, " Trace Output");
if (info)
{
while (info->name)
{
sprintf(msg_buf, "%s: %s", info->name, info->value);
Log_output(TRACE_MINIMUM, msg_buf);
info++;
}
}
#if !defined(WIN32)
struct stat buf;
if (stat("/proc/version", &buf) != -1)
{
FILE* vfile;
if ((vfile = fopen("/proc/version", "r")) != NULL)
{
int len;
strcpy(msg_buf, "/proc/version: ");
len = strlen(msg_buf);
if (fgets(&msg_buf[len], sizeof(msg_buf) - len, vfile))
Log_output(TRACE_MINIMUM, msg_buf);
fclose(vfile);
}
} }
#endif
Log_output(TRACE_MINIMUM, "=========================================================");
return rc; return rc;
} }
void Log_setTraceCallback(Log_traceCallback* callback)
{
trace_callback = callback;
}
void Log_setTraceLevel(enum LOG_LEVELS level)
{
if (level < TRACE_MINIMUM) /* the lowest we can go is TRACE_MINIMUM*/
trace_settings.trace_level = level;
trace_output_level = level;
}
void Log_terminate() void Log_terminate()
{ {
free(trace_queue); free(trace_queue);
...@@ -126,6 +209,10 @@ void Log_terminate() ...@@ -126,6 +209,10 @@ void Log_terminate()
fclose(trace_destination); fclose(trace_destination);
trace_destination = NULL; trace_destination = NULL;
} }
if (trace_destination_name)
free(trace_destination_name);
if (trace_destination_backup_name)
free(trace_destination_backup_name);
start_index = -1; start_index = -1;
next_index = 0; next_index = 0;
trace_output_level = -1; trace_output_level = -1;
...@@ -222,13 +309,44 @@ static char* Log_formatTraceEntry(traceEntry* cur_entry) ...@@ -222,13 +309,44 @@ static char* Log_formatTraceEntry(traceEntry* cur_entry)
} }
static void Log_output(int log_level, char* msg)
{
if (trace_destination)
{
Thread_lock_mutex(log_mutex); /* need to lock around the fiddling with the log files */
fprintf(trace_destination, "%s\n", msg);
if (trace_destination != stdout && ++lines_written >= max_lines_per_file)
{
fclose(trace_destination);
_unlink(trace_destination_backup_name); /* remove any old backup trace file */
rename(trace_destination_name, trace_destination_backup_name); /* rename recently closed to backup */
trace_destination = fopen(trace_destination_name, "w"); /* open new trace file */
if (trace_destination == NULL)
trace_destination = stdout;
lines_written = 0;
}
else
fflush(trace_destination);
Thread_unlock_mutex(log_mutex);
}
if (trace_callback)
(*trace_callback)(log_level, msg);
}
static void Log_posttrace(int log_level, traceEntry* cur_entry) static void Log_posttrace(int log_level, traceEntry* cur_entry)
{ {
if (trace_destination && if (((trace_output_level == -1) ? log_level >= trace_settings.trace_level : log_level >= trace_output_level))
((trace_output_level == -1) ? log_level >= trace_settings.trace_level : log_level >= trace_output_level))
{ {
fprintf(trace_destination, "%s\n", &Log_formatTraceEntry(cur_entry)[7]); char* msg = NULL;
fflush(trace_destination);
if (trace_destination || trace_callback)
msg = &Log_formatTraceEntry(cur_entry)[7];
Log_output(log_level, msg);
} }
} }
......
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009, 2012 IBM Corp. * Copyright (c) 2009, 2013 IBM Corp.
* *
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* *
* Contributors: * Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation * Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs - updates for the async client
*******************************************************************************/ *******************************************************************************/
#if !defined(LOG_H) #if !defined(LOG_H)
...@@ -27,7 +28,7 @@ map LOG_LEVELS ...@@ -27,7 +28,7 @@ map LOG_LEVELS
} }
BE*/ BE*/
enum { enum LOG_LEVELS {
TRACE_MAXIMUM = 1, TRACE_MAXIMUM = 1,
TRACE_MEDIUM, TRACE_MEDIUM,
TRACE_MINIMUM, TRACE_MINIMUM,
...@@ -60,10 +61,20 @@ extern trace_settings_type trace_settings; ...@@ -60,10 +61,20 @@ extern trace_settings_type trace_settings;
#define TRACE_MIN TRACE_MINIMUM #define TRACE_MIN TRACE_MINIMUM
#define TRACE_MED TRACE_MEDIUM #define TRACE_MED TRACE_MEDIUM
int Log_initialize(); typedef struct
{
const char* name;
const char* value;
} Log_nameValue;
int Log_initialize(Log_nameValue*);
void Log_terminate(); void Log_terminate();
void Log(int, int, char *, ...); void Log(int, int, char *, ...);
void Log_stackTrace(int, int, int, int, const char*, int, int*); void Log_stackTrace(int, int, int, int, const char*, int, int*);
typedef void Log_traceCallback(enum LOG_LEVELS level, char* message);
void Log_setTraceCallback(Log_traceCallback* callback);
void Log_setTraceLevel(enum LOG_LEVELS level);
#endif #endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009, 2012 IBM Corp. * Copyright (c) 2009, 2013 IBM Corp.
* *
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
...@@ -8,19 +8,31 @@ ...@@ -8,19 +8,31 @@
* *
* Contributors: * Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation * Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs, Allan Stockdill-Mander - SSL updates
*******************************************************************************/ *******************************************************************************/
/** /**
* @mainpage MQTT Client library for C * @mainpage MQTT Client library for C
* &copy; Copyright IBM Corp. 2009, 2011 * &copy; Copyright IBM Corp. 2009, 2012
* *
* @brief An MQTT client library in C. * @brief An MQTT client library in C.
* *
* An MQTT client application connects to MQTT-capable servers. * An MQTT client application connects to MQTT-capable servers.
* A typical client is responsible for collecting information from a telemetry * A typical client is responsible for collecting information from a telemetry
* device and publishing the information to the server. It can also subscribe * device and publishing the information to the server. It can also subscribe
* to topics, receive messages, and use this information to control the * to topics, receive messages, and use this information to control the
* telemetry device. MQTT clients implement the published MQTT v3 protocol. * telemetry device.
*
* MQTT clients implement the published MQTT v3 protocol. You can write your own
* API to the MQTT protocol using the programming language and platform of your
* choice. This can be time-consuming and error-prone.
*
* To simplify writing MQTT client applications, WebSphere MQ Telemetry provides
* C and Java client libraries that encapsulate the MQTT v3 protocol for a
* number of platforms. If you incorporate these libraries in your MQTT
* applications, a fully functional MQTT client can be written in a few lines of
* code. The information presented here documents the API provided by the IBM
* MQTT Client library for C.
* *
* <b>Using the client</b><br> * <b>Using the client</b><br>
* Applications that use the client library typically use a similar structure: * Applications that use the client library typically use a similar structure:
...@@ -112,6 +124,10 @@ ...@@ -112,6 +124,10 @@
* and version number. * and version number.
*/ */
#define MQTTCLIENT_BAD_STRUCTURE -8 #define MQTTCLIENT_BAD_STRUCTURE -8
/**
* Return code: A QoS value that falls outside of the acceptable range (0,1,2)
*/
#define MQTTCLIENT_BAD_QOS -9
/** /**
* A handle representing an MQTT client. A valid client handle is available * A handle representing an MQTT client. A valid client handle is available
...@@ -129,6 +145,7 @@ typedef void* MQTTClient; ...@@ -129,6 +145,7 @@ typedef void* MQTTClient;
* MQTTClient_getPendingDeliveryTokens()). * MQTTClient_getPendingDeliveryTokens()).
*/ */
typedef int MQTTClient_deliveryToken; typedef int MQTTClient_deliveryToken;
typedef int MQTTClient_token;
/** /**
* A structure representing the payload and attributes of an MQTT message. The * A structure representing the payload and attributes of an MQTT message. The
...@@ -261,7 +278,6 @@ typedef void MQTTClient_deliveryComplete(void* context, MQTTClient_deliveryToken ...@@ -261,7 +278,6 @@ typedef void MQTTClient_deliveryComplete(void* context, MQTTClient_deliveryToken
*/ */
typedef void MQTTClient_connectionLost(void* context, char* cause); typedef void MQTTClient_connectionLost(void* context, char* cause);
/** /**
* This function sets the callback functions for a specific client. * 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
...@@ -290,7 +306,8 @@ typedef void MQTTClient_connectionLost(void* context, char* cause); ...@@ -290,7 +306,8 @@ typedef void MQTTClient_connectionLost(void* context, char* cause);
* ::MQTTCLIENT_FAILURE if an error occurred. * ::MQTTCLIENT_FAILURE if an error occurred.
*/ */
DLLExport int MQTTClient_setCallbacks(MQTTClient handle, void* context, MQTTClient_connectionLost* cl, DLLExport int MQTTClient_setCallbacks(MQTTClient handle, void* context, MQTTClient_connectionLost* cl,
MQTTClient_messageArrived* ma, MQTTClient_deliveryComplete* dc); MQTTClient_messageArrived* ma, MQTTClient_deliveryComplete* dc);
/** /**
* This function creates an MQTT client ready for connection to the * This function creates an MQTT client ready for connection to the
...@@ -373,6 +390,57 @@ typedef struct ...@@ -373,6 +390,57 @@ typedef struct
#define MQTTClient_willOptions_initializer { "MQTW", 0, NULL, NULL, 0, 0 } #define MQTTClient_willOptions_initializer { "MQTW", 0, NULL, NULL, 0, 0 }
/**
* MQTTClient_sslProperties defines the settings to establish an SSL/TLS connection using the
* OpenSSL library. It covers the following scenarios:
* - Server authentication: The client needs the digital certificate of the server. It is included
* in a store containting trusted material (also known as "trust store").
* - Mutual authentication: Both client and server are authenticated during the SSL handshake. In
* addition to the digital certificate of the server in a trust store, the client will need its own
* digital certificate and the private key used to sign its digital certificate stored in a "key store".
* - Anonymous connection: Both client and server do not get authenticated and no credentials are needed
* to establish an SSL connection. Note that this scenario is not fully secure since it is subject to
* man-in-the-middle attacks.
*/
typedef struct
{
/** The eyecatcher for this structure. Must be MQTS */
char struct_id[4];
/** The version number of this structure. Must be 0 */
int struct_version;
/** The file in PEM format containing the public digital certificates trusted by the client. */
char* trustStore;
/** The file in PEM format containing the public certificate chain of the client. It may also include
* the client's private key.
*/
char* keyStore;
/** If not included in the sslKeyStore, this setting points to the file in PEM format containing
* the client's private key.
*/
char* privateKey;
/** The password to load the client's privateKey if encrypted. */
char* privateKeyPassword;
/**
* The list of cipher suites that the client will present to the server during the SSL handshake. For a
* full explanation of the cipher list format, please see the OpenSSL on-line documentation:
* http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT
* If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding
* those offering no encryption- will be considered.
* This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance).
*/
char* enabledCipherSuites;
/** True/False option to enable verification of the server certificate **/
int enableServerCertAuth;
} MQTTClient_SSLOptions;
#define MQTTClient_SSLOptions_initializer { "MQTS", 0, NULL, NULL, NULL, NULL, NULL, 1 }
/** /**
* MQTTClient_connectOptions defines several settings that control the way the * MQTTClient_connectOptions defines several settings that control the way the
* client connects to an MQTT server. * client connects to an MQTT server.
...@@ -391,7 +459,7 @@ typedef struct ...@@ -391,7 +459,7 @@ typedef struct
{ {
/** The eyecatcher for this structure. must be MQTC. */ /** The eyecatcher for this structure. must be MQTC. */
char struct_id[4]; char struct_id[4];
/** The version number of this structure. Must be 0 */ /** The version number of this structure. Must be 0 or 1. 0 signifies no SSL options */
int struct_version; int struct_version;
/** The "keep alive" interval, measured in seconds, defines the maximum time /** The "keep alive" interval, measured in seconds, defines the maximum time
* that should pass without communication between the client and the server * that should pass without communication between the client and the server
...@@ -461,9 +529,34 @@ typedef struct ...@@ -461,9 +529,34 @@ typedef struct
* The time interval in seconds * The time interval in seconds
*/ */
int retryInterval; int retryInterval;
/**
* This is a pointer to an MQTTClient_SSLOptions structure. If your
* application does not make use of SSL, set this pointer to NULL.
*/
MQTTClient_SSLOptions* ssl;
} MQTTClient_connectOptions; } MQTTClient_connectOptions;
#define MQTTClient_connectOptions_initializer { "MQTC", 0, 60, 1, 1, NULL, NULL, NULL, 30, 20 } #define MQTTClient_connectOptions_initializer { "MQTC", 1, 60, 1, 1, NULL, NULL, NULL, 30, 20, NULL }
/**
* MQTTClient_libraryInfo is used to store details relating to the currently used
* library such as the version in use, the time it was built and relevant openSSL
* options.
* There is one static instance of this struct in MQTTClient.c
*/
typedef struct
{
const char* name;
const char* value;
} MQTTClient_nameValue;
/**
* This function returns version information about the library.
* no trace information will be returned.
* @return an array of strings describing the library. The last entry is a NULL pointer.
*/
DLLExport MQTTClient_nameValue* MQTTClient_getVersionInfo();
/** /**
* This function attempts to connect a previously-created client (see * This function attempts to connect a previously-created client (see
...@@ -602,7 +695,6 @@ DLLExport int MQTTClient_unsubscribeMany(MQTTClient handle, int count, char** to ...@@ -602,7 +695,6 @@ DLLExport int MQTTClient_unsubscribeMany(MQTTClient handle, int count, char** to
*/ */
DLLExport int MQTTClient_publish(MQTTClient handle, char* topicName, int payloadlen, void* payload, int qos, int retained, DLLExport int MQTTClient_publish(MQTTClient handle, char* topicName, int payloadlen, void* payload, int qos, int retained,
MQTTClient_deliveryToken* dt); MQTTClient_deliveryToken* dt);
/** /**
* This function attempts to publish a message to a given topic (see also * This function attempts to publish a message to a given topic (see also
* MQTTClient_publish()). An ::MQTTClient_deliveryToken is issued when * MQTTClient_publish()). An ::MQTTClient_deliveryToken is issued when
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
* Contributors: * Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation * Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/ *******************************************************************************/
#if !defined(MQTTPROTOCOL_H) #if !defined(MQTTPROTOCOL_H)
#define MQTTPROTOCOL_H #define MQTTPROTOCOL_H
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment