Commit 542b96b9 authored by Ian Craggs's avatar Ian Craggs

Merge branch 'master' of git://git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.c

Conflicts:
	test/MQTTTest_v2.c
parents 60b2825e 8257d538
#*******************************************************************************
# Copyright (c) 2009, 2013 IBM Corp.
#
# 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.
#
# The Eclipse Public License is available at
# http://www.eclipse.org/legal/epl-v10.html
# 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
# Allan Stockdill-Mander - SSL updates
# Andy Piper - various fixes
#*******************************************************************************/
# Note: on OS X you should install XCode and the associated command-line tools
SHELL = /bin/sh
.PHONY: clean, mkdir, install, uninstall, html
# assume this is normally run in the main Paho directory
ifndef srcdir
srcdir = src
endif
ifndef blddir
blddir = build/output
endif
ifndef prefix
prefix = /usr/local
endif
ifndef exec_prefix
exec_prefix = ${prefix}
endif
bindir = $(exec_prefix)/bin
includedir = $(prefix)/include
libdir = $(exec_prefix)/lib
SOURCE_FILES = $(wildcard $(srcdir)/*.c)
SOURCE_FILES_C = $(filter-out $(srcdir)/MQTTAsync.c $(srcdir)/MQTTVersion.c $(srcdir)/SSLSocket.c, $(SOURCE_FILES))
SOURCE_FILES_CS = $(filter-out $(srcdir)/MQTTAsync.c $(srcdir)/MQTTVersion.c, $(SOURCE_FILES))
SOURCE_FILES_A = $(filter-out $(srcdir)/MQTTClient.c $(srcdir)/MQTTVersion.c $(srcdir)/SSLSocket.c, $(SOURCE_FILES))
SOURCE_FILES_AS = $(filter-out $(srcdir)/MQTTClient.c $(srcdir)/MQTTVersion.c, $(SOURCE_FILES))
HEADERS = $(srcdir)/*.h
HEADERS_C = $(filter-out $(srcdir)/MQTTAsync.h, $(HEADERS))
HEADERS_A = $(HEADERS)
SAMPLE_FILES_C = stdinpub stdoutsub pubsync pubasync subasync
SYNC_SAMPLES = ${addprefix ${blddir}/samples/,${SAMPLE_FILES_C}}
SAMPLE_FILES_A = stdoutsuba MQTTAsync_subscribe MQTTAsync_publish
ASYNC_SAMPLES = ${addprefix ${blddir}/samples/,${SAMPLE_FILES_A}}
TEST_FILES_C = test1
SYNC_TESTS = ${addprefix ${blddir}/test/,${TEST_FILES_C}}
TEST_FILES_CS = test3
SYNC_SSL_TESTS = ${addprefix ${blddir}/test/,${TEST_FILES_CS}}
TEST_FILES_A = test4
ASYNC_TESTS = ${addprefix ${blddir}/test/,${TEST_FILES_A}}
TEST_FILES_AS = test5
ASYNC_SSL_TESTS = ${addprefix ${blddir}/test/,${TEST_FILES_AS}}
# The names of the four different libraries to be built
MQTTLIB_C = paho-mqtt3c
MQTTLIB_CS = paho-mqtt3cs
MQTTLIB_A = paho-mqtt3a
MQTTLIB_AS = paho-mqtt3as
# determine current platform
ifeq ($(OS),Windows_NT)
OSTYPE = $(OS)
else
OSTYPE = $(shell uname -s)
MACHINETYPE = $(shell uname -m)
endif
ifeq ($(OSTYPE),Linux)
CC = gcc
ifndef INSTALL
INSTALL = install
endif
INSTALL_PROGRAM = $(INSTALL)
INSTALL_DATA = $(INSTALL) -m 644
DOXYGEN_COMMAND = doxygen
MAJOR_VERSION = 1
MINOR_VERSION = 0
VERSION = ${MAJOR_VERSION}.${MINOR_VERSION}
MQTTLIB_C_TARGET = ${blddir}/lib${MQTTLIB_C}.so.${VERSION}
MQTTLIB_CS_TARGET = ${blddir}/lib${MQTTLIB_CS}.so.${VERSION}
MQTTLIB_A_TARGET = ${blddir}/lib${MQTTLIB_A}.so.${VERSION}
MQTTLIB_AS_TARGET = ${blddir}/lib${MQTTLIB_AS}.so.${VERSION}
MQTTVERSION_TARGET = ${blddir}/MQTTVersion
CCFLAGS_SO = -g -fPIC -Os -Wall -fvisibility=hidden
FLAGS_EXE = -I ${srcdir} -lpthread -L ${blddir}
LDFLAGS_C = -shared -Wl,-soname,lib$(MQTTLIB_C).so.${MAJOR_VERSION} -Wl,-init,MQTTClient_init
LDFLAGS_CS = -shared -Wl,-soname,lib$(MQTTLIB_CS).so.${MAJOR_VERSION} -ldl -lcrypto -lssl -Wl,-no-whole-archive -Wl,-init,MQTTClient_init
LDFLAGS_A = -shared -Wl,-soname,lib${MQTTLIB_A}.so.${MAJOR_VERSION} -Wl,-init,MQTTAsync_init
LDFLAGS_AS = -shared -Wl,-soname,lib${MQTTLIB_AS}.so.${MAJOR_VERSION} -ldl -lcrypto -lssl -Wl,-no-whole-archive -Wl,-init,MQTTAsync_init
all: build
build: | mkdir ${MQTTLIB_C_TARGET} ${MQTTLIB_CS_TARGET} ${MQTTLIB_A_TARGET} ${MQTTLIB_AS_TARGET} ${MQTTVERSION_TARGET} ${SYNC_SAMPLES} ${ASYNC_SAMPLES} ${SYNC_TESTS} ${SYNC_SSL_TESTS} ${ASYNC_TESTS} ${ASYNC_SSL_TESTS}
clean:
rm -rf ${blddir}/*
mkdir:
-mkdir -p ${blddir}/samples
-mkdir -p ${blddir}/test
${SYNC_TESTS}: ${blddir}/test/%: ${srcdir}/../test/%.c
${CC} -g -o ${blddir}/test/${basename ${+F}} $< -l${MQTTLIB_C} ${FLAGS_EXE}
${SYNC_SSL_TESTS}: ${blddir}/test/%: ${srcdir}/../test/%.c
${CC} -g -o ${blddir}/test/${basename ${+F}} $< -l${MQTTLIB_CS} ${FLAGS_EXE} -lssl
${ASYNC_TESTS}: ${blddir}/test/%: ${srcdir}/../test/%.c
${CC} -g -o ${blddir}/test/${basename ${+F}} $< -l${MQTTLIB_A} ${FLAGS_EXE}
${ASYNC_SSL_TESTS}: ${blddir}/test/%: ${srcdir}/../test/%.c
${CC} -g -o ${blddir}/test/${basename ${+F}} $< -l${MQTTLIB_AS} ${FLAGS_EXE} -lssl
${SYNC_SAMPLES}: ${blddir}/samples/%: ${srcdir}/samples/%.c
${CC} -o ${blddir}/samples/${basename ${+F}} $< -l${MQTTLIB_C} ${FLAGS_EXE}
${ASYNC_SAMPLES}: ${blddir}/samples/%: ${srcdir}/samples/%.c
${CC} -o ${blddir}/samples/${basename ${+F}} $< -l${MQTTLIB_A} ${FLAGS_EXE}
${MQTTLIB_C_TARGET}: ${SOURCE_FILES_C} ${HEADERS_C}
${CC} ${CCFLAGS_SO} ${LDFLAGS_C} -o $@ ${SOURCE_FILES_C}
-ln -s lib$(MQTTLIB_C).so.${VERSION} ${blddir}/lib$(MQTTLIB_C).so.${MAJOR_VERSION}
-ln -s lib$(MQTTLIB_C).so.${MAJOR_VERSION} ${blddir}/lib$(MQTTLIB_C).so
${MQTTLIB_CS_TARGET}: ${SOURCE_FILES_CS} ${HEADERS_C}
${CC} ${CCFLAGS_SO} ${LDFLAGS_CS} -o $@ ${SOURCE_FILES_CS} -DOPENSSL
-ln -s lib$(MQTTLIB_CS).so.${VERSION} ${blddir}/lib$(MQTTLIB_CS).so.${MAJOR_VERSION}
-ln -s lib$(MQTTLIB_CS).so.${MAJOR_VERSION} ${blddir}/lib$(MQTTLIB_CS).so
${MQTTLIB_A_TARGET}: ${SOURCE_FILES_A} ${HEADERS_A}
${CC} ${CCFLAGS_SO} ${LDFLAGS_A} -o $@ ${SOURCE_FILES_A}
-ln -s lib$(MQTTLIB_A).so.${VERSION} ${blddir}/lib$(MQTTLIB_A).so.${MAJOR_VERSION}
-ln -s lib$(MQTTLIB_A).so.${MAJOR_VERSION} ${blddir}/lib$(MQTTLIB_A).so
${MQTTLIB_AS_TARGET}: ${SOURCE_FILES_AS} ${HEADERS_A}
${CC} ${CCFLAGS_SO} ${LDFLAGS_AS} -o $@ ${SOURCE_FILES_AS} -DOPENSSL
-ln -s lib$(MQTTLIB_AS).so.${VERSION} ${blddir}/lib$(MQTTLIB_AS).so.${MAJOR_VERSION}
-ln -s lib$(MQTTLIB_AS).so.${MAJOR_VERSION} ${blddir}/lib$(MQTTLIB_AS).so
${MQTTVERSION_TARGET}: $(srcdir)/MQTTVersion.c $(srcdir)/MQTTAsync.h
${CC} ${FLAGS_EXE} -o $@ -l${MQTTLIB_A} $(srcdir)/MQTTVersion.c -ldl
strip_options:
$(eval INSTALL_OPTS := -s)
install-strip: build strip_options install
install: build
$(INSTALL_DATA) ${INSTALL_OPTS} ${MQTTLIB_C_TARGET} $(DESTDIR)${libdir}
$(INSTALL_DATA) ${INSTALL_OPTS} ${MQTTLIB_CS_TARGET} $(DESTDIR)${libdir}
$(INSTALL_DATA) ${INSTALL_OPTS} ${MQTTLIB_A_TARGET} $(DESTDIR)${libdir}
$(INSTALL_DATA) ${INSTALL_OPTS} ${MQTTLIB_AS_TARGET} $(DESTDIR)${libdir}
$(INSTALL_PROGRAM) ${INSTALL_OPTS} ${MQTTVERSION_TARGET} $(DESTDIR)${bindir}
/sbin/ldconfig $(DESTDIR)${libdir}
ln -s lib$(MQTTLIB_C).so.${MAJOR_VERSION} $(DESTDIR)${libdir}/lib$(MQTTLIB_C).so
ln -s lib$(MQTTLIB_CS).so.${MAJOR_VERSION} $(DESTDIR)${libdir}/lib$(MQTTLIB_CS).so
ln -s lib$(MQTTLIB_A).so.${MAJOR_VERSION} $(DESTDIR)${libdir}/lib$(MQTTLIB_A).so
ln -s lib$(MQTTLIB_AS).so.${MAJOR_VERSION} $(DESTDIR)${libdir}/lib$(MQTTLIB_AS).so
$(INSTALL_DATA) ${srcdir}/MQTTAsync.h $(DESTDIR)${includedir}
$(INSTALL_DATA) ${srcdir}/MQTTClient.h $(DESTDIR)${includedir}
$(INSTALL_DATA) ${srcdir}/MQTTClientPersistence.h $(DESTDIR)${includedir}
uninstall:
rm $(DESTDIR)${libdir}/lib$(MQTTLIB_C).so.${VERSION}
rm $(DESTDIR)${libdir}/lib$(MQTTLIB_CS).so.${VERSION}
rm $(DESTDIR)${libdir}/lib$(MQTTLIB_A).so.${VERSION}
rm $(DESTDIR)${libdir}/lib$(MQTTLIB_AS).so.${VERSION}
rm $(DESTDIR)${bindir}/MQTTVersion
/sbin/ldconfig $(DESTDIR)${libdir}
rm $(DESTDIR)${libdir}/lib$(MQTTLIB_C).so
rm $(DESTDIR)${libdir}/lib$(MQTTLIB_CS).so
rm $(DESTDIR)${libdir}/lib$(MQTTLIB_A).so
rm $(DESTDIR)${libdir}/lib$(MQTTLIB_AS).so
rm $(DESTDIR)${includedir}/MQTTAsync.h
rm $(DESTDIR)${includedir}/MQTTClient.h
rm $(DESTDIR)${includedir}/MQTTClientPersistence.h
html:
-mkdir -p ${blddir}/doc
cd ${srcdir}; $(DOXYGEN_COMMAND) ../doc/DoxyfileV3ClientAPI
cd ${srcdir}; $(DOXYGEN_COMMAND) ../doc/DoxyfileV3AsyncAPI
cd ${srcdir}; $(DOXYGEN_COMMAND) ../doc/DoxyfileV3ClientInternal
endif
...@@ -54,10 +54,15 @@ ...@@ -54,10 +54,15 @@
<property name="ldflags.so" value="-fvisibility=hidden -shared" /> <property name="ldflags.so" value="-fvisibility=hidden -shared" />
<mkdir dir="${output.folder}"/> <mkdir dir="${output.folder}"/>
<!-- display gcc version -->
<exec executable="gcc" failonerror="true">
<arg line="-v"/>
</exec>
<!-- non-SSL, synchronous library --> <!-- non-SSL, synchronous library -->
<property name="output.filename" value="${output.folder}/lib${libname}.so" /> <property name="output.filename" value="${output.folder}/lib${libname}.so" />
<exec executable="gcc" failonerror="true"> <exec executable="gcc" failonerror="true">
<arg line="${ccflags.so} ${ldflags.so} -Wl,-soname,lib${libname}.so -o ${output.filename} ${sync.source.files}"/> <arg line="${ccflags.so} ${ldflags.so} -Wl,-init,MQTTClient_init -Wl,-soname,lib${libname}.so -o ${output.filename} ${sync.source.files}"/>
</exec> </exec>
<exec executable="strip" failonerror="true"> <exec executable="strip" failonerror="true">
<arg value="${output.filename}" /> <arg value="${output.filename}" />
...@@ -69,7 +74,7 @@ ...@@ -69,7 +74,7 @@
<!-- SSL, synchronous library --> <!-- SSL, synchronous library -->
<property name="output.ssl.filename" value="${output.folder}/lib${libname.ssl}.so" /> <property name="output.ssl.filename" value="${output.folder}/lib${libname.ssl}.so" />
<exec executable="gcc" failonerror="true"> <exec executable="gcc" failonerror="true">
<arg line="-DOPENSSL ${ccflags.so} ${ldflags.so} -Wl,-soname,lib${libname.ssl}.so -o ${output.ssl.filename} ${sync.source.files}"/> <arg line="-DOPENSSL ${ccflags.so} ${ldflags.so} -Wl,-init,MQTTClient_init -Wl,-soname,lib${libname.ssl}.so -o ${output.ssl.filename} ${sync.source.files}"/>
</exec> </exec>
<exec executable="strip" failonerror="true"> <exec executable="strip" failonerror="true">
<arg value="${output.ssl.filename}" /> <arg value="${output.ssl.filename}" />
...@@ -80,7 +85,7 @@ ...@@ -80,7 +85,7 @@
<!-- non-SSL, asynchronous library --> <!-- non-SSL, asynchronous library -->
<property name="output.async.filename" value="${output.folder}/lib${libname.async}.so" /> <property name="output.async.filename" value="${output.folder}/lib${libname.async}.so" />
<exec executable="gcc" failonerror="true"> <exec executable="gcc" failonerror="true">
<arg line="${ccflags.so} ${ldflags.so} -Wl,-soname,lib${libname.async}.so -o ${output.async.filename} ${async.source.files}"/> <arg line="${ccflags.so} ${ldflags.so} -Wl,-init,MQTTAsync_init -Wl,-soname,lib${libname.async}.so -o ${output.async.filename} ${async.source.files}"/>
</exec> </exec>
<exec executable="strip" failonerror="true"> <exec executable="strip" failonerror="true">
<arg value="${output.async.filename}" /> <arg value="${output.async.filename}" />
...@@ -92,7 +97,7 @@ ...@@ -92,7 +97,7 @@
<!-- SSL, asynchronous library --> <!-- SSL, asynchronous library -->
<property name="output.async.ssl.filename" value="${output.folder}/lib${libname.async.ssl}.so" /> <property name="output.async.ssl.filename" value="${output.folder}/lib${libname.async.ssl}.so" />
<exec executable="gcc" failonerror="true"> <exec executable="gcc" failonerror="true">
<arg line="-DOPENSSL ${ccflags.so} ${ldflags.so} -Wl,-soname,lib${libname.async.ssl}.so -o ${output.async.ssl.filename} ${async.source.files}"/> <arg line="-DOPENSSL ${ccflags.so} ${ldflags.so} -Wl,-init,MQTTAsync_init -Wl,-soname,lib${libname.async.ssl}.so -o ${output.async.ssl.filename} ${async.source.files}"/>
</exec> </exec>
<exec executable="strip" failonerror="true"> <exec executable="strip" failonerror="true">
<arg value="${output.async.ssl.filename}" /> <arg value="${output.async.ssl.filename}" />
......
...@@ -52,7 +52,7 @@ PROJECT_LOGO = "../doc/pahologo.png" ...@@ -52,7 +52,7 @@ PROJECT_LOGO = "../doc/pahologo.png"
# If a relative path is entered, it will be relative to the location # If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used. # where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY = "MQTTClient_internal/" OUTPUT_DIRECTORY = "../build/output/doc/MQTTClient_internal/"
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
# 4096 sub-directories (in 2 levels) under the output directory of each output # 4096 sub-directories (in 2 levels) under the output directory of each output
......
...@@ -324,7 +324,6 @@ static void Log_output(int log_level, char* msg) ...@@ -324,7 +324,6 @@ static void Log_output(int log_level, char* msg)
{ {
if (trace_destination) if (trace_destination)
{ {
Thread_lock_mutex(log_mutex); /* need to lock around the fiddling with the log files */
fprintf(trace_destination, "%s\n", msg); fprintf(trace_destination, "%s\n", msg);
if (trace_destination != stdout && ++lines_written >= max_lines_per_file) if (trace_destination != stdout && ++lines_written >= max_lines_per_file)
...@@ -340,7 +339,6 @@ static void Log_output(int log_level, char* msg) ...@@ -340,7 +339,6 @@ static void Log_output(int log_level, char* msg)
} }
else else
fflush(trace_destination); fflush(trace_destination);
Thread_unlock_mutex(log_mutex);
} }
if (trace_callback) if (trace_callback)
...@@ -393,13 +391,14 @@ static void Log_trace(int log_level, char* buf) ...@@ -393,13 +391,14 @@ static void Log_trace(int log_level, char* buf)
*/ */
void Log(int log_level, int msgno, char* format, ...) void Log(int log_level, int msgno, char* format, ...)
{ {
char* temp = NULL;
static char msg_buf[512];
if (log_level >= trace_settings.trace_level) if (log_level >= trace_settings.trace_level)
{ {
char* temp = NULL;
static char msg_buf[512];
va_list args; va_list args;
/* we're using a static character buffer, so we need to make sure only one thread uses it at a time */
Thread_lock_mutex(log_mutex);
if (format == NULL && (temp = Messages_get(msgno, log_level)) != NULL) if (format == NULL && (temp = Messages_get(msgno, log_level)) != NULL)
format = temp; format = temp;
...@@ -408,6 +407,7 @@ void Log(int log_level, int msgno, char* format, ...) ...@@ -408,6 +407,7 @@ void Log(int log_level, int msgno, char* format, ...)
Log_trace(log_level, msg_buf); Log_trace(log_level, msg_buf);
va_end(args); va_end(args);
Thread_unlock_mutex(log_mutex);
} }
/*if (log_level >= LOG_ERROR) /*if (log_level >= LOG_ERROR)
...@@ -415,9 +415,7 @@ void Log(int log_level, int msgno, char* format, ...) ...@@ -415,9 +415,7 @@ void Log(int log_level, int msgno, char* format, ...)
char* filename = NULL; char* filename = NULL;
Log_recordFFDC(&msg_buf[7]); Log_recordFFDC(&msg_buf[7]);
} }
*/
if (log_level == LOG_FATAL)
exit(-1);*/
} }
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
* Ian Craggs - multiple server connection support * Ian Craggs - multiple server connection support
* Ian Craggs - fix for bug 413429 - connectionLost not called * Ian Craggs - fix for bug 413429 - connectionLost not called
* Ian Craggs - fix for bug# 415042 - using already freed structure * Ian Craggs - fix for bug# 415042 - using already freed structure
* Ian Craggs - fix for bug 419233 - mutexes not reporting errors
* Ian Craggs - fix for bug #420851
*******************************************************************************/ *******************************************************************************/
/** /**
...@@ -24,7 +26,7 @@ ...@@ -24,7 +26,7 @@
* *
*/ */
#define _GNU_SOURCE /* for pthread_mutexattr_settype */
#include <stdlib.h> #include <stdlib.h>
#if !defined(WIN32) #if !defined(WIN32)
#include <sys/time.h> #include <sys/time.h>
...@@ -70,15 +72,10 @@ enum MQTTAsync_threadStates ...@@ -70,15 +72,10 @@ enum MQTTAsync_threadStates
enum MQTTAsync_threadStates sendThread_state = STOPPED; enum MQTTAsync_threadStates sendThread_state = STOPPED;
enum MQTTAsync_threadStates receiveThread_state = STOPPED; enum MQTTAsync_threadStates receiveThread_state = STOPPED;
#if !defined(WIN32)
static cond_type send_cond;
#else
static sem_type send_sem;
#endif
#if defined(WIN32) #if defined(WIN32)
static mutex_type mqttasync_mutex = NULL; static mutex_type mqttasync_mutex = NULL;
static mutex_type mqttcommand_mutex = NULL; static mutex_type mqttcommand_mutex = NULL;
static sem_type send_sem = NULL;
extern mutex_type stack_mutex; extern mutex_type stack_mutex;
extern mutex_type heap_mutex; extern mutex_type heap_mutex;
extern mutex_type log_mutex; extern mutex_type log_mutex;
...@@ -94,6 +91,12 @@ BOOL APIENTRY DllMain(HANDLE hModule, ...@@ -94,6 +91,12 @@ BOOL APIENTRY DllMain(HANDLE hModule,
{ {
mqttasync_mutex = CreateMutex(NULL, 0, NULL); mqttasync_mutex = CreateMutex(NULL, 0, NULL);
mqttcommand_mutex = CreateMutex(NULL, 0, NULL); mqttcommand_mutex = CreateMutex(NULL, 0, NULL);
send_sem = CreateEvent(
NULL, /* default security attributes */
FALSE, /* manual-reset event? */
FALSE, /* initial state is nonsignaled */
NULL /* object name */
);
stack_mutex = CreateMutex(NULL, 0, NULL); stack_mutex = CreateMutex(NULL, 0, NULL);
heap_mutex = CreateMutex(NULL, 0, NULL); heap_mutex = CreateMutex(NULL, 0, NULL);
log_mutex = CreateMutex(NULL, 0, NULL); log_mutex = CreateMutex(NULL, 0, NULL);
...@@ -112,6 +115,22 @@ static pthread_mutex_t mqttasync_mutex_store = PTHREAD_MUTEX_INITIALIZER; ...@@ -112,6 +115,22 @@ static pthread_mutex_t mqttasync_mutex_store = PTHREAD_MUTEX_INITIALIZER;
static mutex_type mqttasync_mutex = &mqttasync_mutex_store; static mutex_type mqttasync_mutex = &mqttasync_mutex_store;
static pthread_mutex_t mqttcommand_mutex_store = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t mqttcommand_mutex_store = PTHREAD_MUTEX_INITIALIZER;
static mutex_type mqttcommand_mutex = &mqttcommand_mutex_store; static mutex_type mqttcommand_mutex = &mqttcommand_mutex_store;
static cond_type_struct send_cond_store = { PTHREAD_COND_INITIALIZER, PTHREAD_MUTEX_INITIALIZER };
static cond_type send_cond = &send_cond_store;
void MQTTAsync_init()
{
pthread_mutexattr_t attr;
int rc;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
if ((rc = pthread_mutex_init(mqttasync_mutex, &attr)) != 0)
printf("MQTTAsync: error %d initializing async_mutex\n", rc);
if ((rc = pthread_mutex_init(mqttcommand_mutex, &attr)) != 0)
printf("MQTTAsync: error %d initializing command_mutex\n", rc);
}
#define WINAPI #define WINAPI
#endif #endif
...@@ -299,6 +318,22 @@ int clientSockCompare(void* a, void* b) ...@@ -299,6 +318,22 @@ int clientSockCompare(void* a, void* b)
} }
void MQTTAsync_lock_mutex(mutex_type amutex)
{
int rc = Thread_lock_mutex(amutex);
if (rc != 0)
Log(LOG_ERROR, 0, "Error %d locking mutex", rc);
}
void MQTTAsync_unlock_mutex(mutex_type amutex)
{
int rc = Thread_unlock_mutex(amutex);
if (rc != 0)
Log(LOG_ERROR, 0, "Error %d unlocking mutex", rc);
}
int MQTTAsync_create(MQTTAsync* handle, char* serverURI, char* clientId, int MQTTAsync_create(MQTTAsync* handle, char* serverURI, char* clientId,
int persistence_type, void* persistence_context) int persistence_type, void* persistence_context)
{ {
...@@ -306,7 +341,7 @@ int MQTTAsync_create(MQTTAsync* handle, char* serverURI, char* clientId, ...@@ -306,7 +341,7 @@ int MQTTAsync_create(MQTTAsync* handle, char* serverURI, char* clientId,
MQTTAsyncs *m = NULL; MQTTAsyncs *m = NULL;
FUNC_ENTRY; FUNC_ENTRY;
rc = Thread_lock_mutex(mqttasync_mutex); MQTTAsync_lock_mutex(mqttasync_mutex);
if (serverURI == NULL || clientId == NULL) if (serverURI == NULL || clientId == NULL)
{ {
...@@ -333,11 +368,6 @@ int MQTTAsync_create(MQTTAsync* handle, char* serverURI, char* clientId, ...@@ -333,11 +368,6 @@ int MQTTAsync_create(MQTTAsync* handle, char* serverURI, char* clientId,
commands = ListInitialize(); commands = ListInitialize();
#if defined(OPENSSL) #if defined(OPENSSL)
SSLSocket_initialize(); SSLSocket_initialize();
#endif
#if !defined(WIN32)
send_cond = Thread_create_cond();
#else
send_sem = Thread_create_sem();
#endif #endif
initialized = 1; initialized = 1;
} }
...@@ -382,7 +412,7 @@ int MQTTAsync_create(MQTTAsync* handle, char* serverURI, char* clientId, ...@@ -382,7 +412,7 @@ int MQTTAsync_create(MQTTAsync* handle, char* serverURI, char* clientId,
ListAppend(bstate->clients, m->c, sizeof(Clients) + 3*sizeof(List)); ListAppend(bstate->clients, m->c, sizeof(Clients) + 3*sizeof(List));
exit: exit:
Thread_unlock_mutex(mqttasync_mutex); MQTTAsync_unlock_mutex(mqttasync_mutex);
FUNC_EXIT_RC(rc); FUNC_EXIT_RC(rc);
return rc; return rc;
} }
...@@ -395,11 +425,6 @@ void MQTTAsync_terminate(void) ...@@ -395,11 +425,6 @@ void MQTTAsync_terminate(void)
if (initialized) if (initialized)
{ {
ListElement* elem = NULL; ListElement* elem = NULL;
#if !defined(WIN32)
Thread_destroy_cond(send_cond);
#else
Thread_destroy_sem(send_sem);
#endif
ListFree(bstate->clients); ListFree(bstate->clients);
ListFree(handles); ListFree(handles);
while (ListNextElement(commands, &elem)) while (ListNextElement(commands, &elem))
...@@ -678,10 +703,10 @@ int MQTTAsync_restoreCommands(MQTTAsyncs* client) ...@@ -678,10 +703,10 @@ int MQTTAsync_restoreCommands(MQTTAsyncs* client)
int MQTTAsync_addCommand(MQTTAsync_queuedCommand* command, int command_size) int MQTTAsync_addCommand(MQTTAsync_queuedCommand* command, int command_size)
{ {
int rc; int rc = 0;
FUNC_ENTRY; FUNC_ENTRY;
rc = Thread_lock_mutex(mqttcommand_mutex); MQTTAsync_lock_mutex(mqttcommand_mutex);
command->command.start_time = MQTTAsync_start_clock(); command->command.start_time = MQTTAsync_start_clock();
if (command->command.type == CONNECT || if (command->command.type == CONNECT ||
(command->command.type == DISCONNECT && command->command.details.dis.internal)) (command->command.type == DISCONNECT && command->command.details.dis.internal))
...@@ -704,7 +729,7 @@ int MQTTAsync_addCommand(MQTTAsync_queuedCommand* command, int command_size) ...@@ -704,7 +729,7 @@ int MQTTAsync_addCommand(MQTTAsync_queuedCommand* command, int command_size)
MQTTAsync_persistCommand(command); MQTTAsync_persistCommand(command);
#endif #endif
} }
rc = Thread_unlock_mutex(mqttcommand_mutex); MQTTAsync_unlock_mutex(mqttcommand_mutex);
#if !defined(WIN32) #if !defined(WIN32)
Thread_signal_cond(send_cond); Thread_signal_cond(send_cond);
#else #else
...@@ -729,16 +754,12 @@ void MQTTAsync_checkDisconnect(MQTTAsync handle, MQTTAsync_command* command) ...@@ -729,16 +754,12 @@ void MQTTAsync_checkDisconnect(MQTTAsync handle, MQTTAsync_command* command)
if (command->details.dis.internal && m->cl && was_connected) if (command->details.dis.internal && m->cl && was_connected)
{ {
Log(TRACE_MIN, -1, "Calling connectionLost for client %s", m->c->clientID); Log(TRACE_MIN, -1, "Calling connectionLost for client %s", m->c->clientID);
Thread_unlock_mutex(mqttasync_mutex);
(*(m->cl))(m->context, NULL); (*(m->cl))(m->context, NULL);
Thread_lock_mutex(mqttasync_mutex);
} }
else if (!command->details.dis.internal && command->onSuccess) else if (!command->details.dis.internal && command->onSuccess)
{ {
Log(TRACE_MIN, -1, "Calling disconnect complete for client %s", m->c->clientID); Log(TRACE_MIN, -1, "Calling disconnect complete for client %s", m->c->clientID);
Thread_unlock_mutex(mqttasync_mutex);
(*(command->onSuccess))(command->context, NULL); (*(command->onSuccess))(command->context, NULL);
Thread_lock_mutex(mqttasync_mutex);
} }
} }
FUNC_EXIT; FUNC_EXIT;
...@@ -887,8 +908,8 @@ void MQTTAsync_processCommand() ...@@ -887,8 +908,8 @@ void MQTTAsync_processCommand()
List* ignored_clients = NULL; List* ignored_clients = NULL;
FUNC_ENTRY; FUNC_ENTRY;
Thread_lock_mutex(mqttasync_mutex); MQTTAsync_lock_mutex(mqttasync_mutex);
Thread_lock_mutex(mqttcommand_mutex); MQTTAsync_lock_mutex(mqttcommand_mutex);
/* only the first command in the list must be processed for any particular client, so if we skip /* only the first command in the list must be processed for any particular client, so if we skip
a command for a client, we must skip all following commands for that client. Use a list of a command for a client, we must skip all following commands for that client. Use a list of
...@@ -904,13 +925,18 @@ void MQTTAsync_processCommand() ...@@ -904,13 +925,18 @@ void MQTTAsync_processCommand()
if (ListFind(ignored_clients, cmd->client)) if (ListFind(ignored_clients, cmd->client))
continue; continue;
if (cmd->command.type == CONNECT || (cmd->client->c->connected && if (cmd->command.type == CONNECT || cmd->command.type == DISCONNECT || (cmd->client->c->connected &&
cmd->client->c->connect_state == 0 && Socket_noPendingWrites(cmd->client->c->net.socket))) cmd->client->c->connect_state == 0 && Socket_noPendingWrites(cmd->client->c->net.socket)))
{
if ((cmd->command.type == PUBLISH || cmd->command.type == SUBSCRIBE || cmd->command.type == UNSUBSCRIBE) &&
cmd->client->c->outboundMsgs->count >= MAX_MSG_ID - 1)
; /* no more message ids available */
else
{ {
command = cmd; command = cmd;
break; break;
} }
else }
ListAppend(ignored_clients, cmd->client, sizeof(cmd->client)); ListAppend(ignored_clients, cmd->client, sizeof(cmd->client));
} }
ListFreeNoContent(ignored_clients); ListFreeNoContent(ignored_clients);
...@@ -922,7 +948,7 @@ void MQTTAsync_processCommand() ...@@ -922,7 +948,7 @@ void MQTTAsync_processCommand()
MQTTAsync_unpersistCommand(command); MQTTAsync_unpersistCommand(command);
#endif #endif
} }
Thread_unlock_mutex(mqttcommand_mutex); MQTTAsync_unlock_mutex(mqttcommand_mutex);
if (!command) if (!command)
goto exit; /* nothing to do */ goto exit; /* nothing to do */
...@@ -1022,9 +1048,7 @@ void MQTTAsync_processCommand() ...@@ -1022,9 +1048,7 @@ void MQTTAsync_processCommand()
data.alt.pub.message.qos = command->command.details.pub.qos; data.alt.pub.message.qos = command->command.details.pub.qos;
data.alt.pub.message.retained = command->command.details.pub.retained; data.alt.pub.message.retained = command->command.details.pub.retained;
Log(TRACE_MIN, -1, "Calling publish success for client %s", command->client->c->clientID); Log(TRACE_MIN, -1, "Calling publish success for client %s", command->client->c->clientID);
Thread_unlock_mutex(mqttasync_mutex);
(*(command->command.onSuccess))(command->command.context, &data); (*(command->command.onSuccess))(command->command.context, &data);
Thread_lock_mutex(mqttasync_mutex);
} }
} }
else else
...@@ -1086,10 +1110,7 @@ void MQTTAsync_processCommand() ...@@ -1086,10 +1110,7 @@ void MQTTAsync_processCommand()
if (command->command.onFailure) if (command->command.onFailure)
{ {
Log(TRACE_MIN, -1, "Calling command failure for client %s", command->client->c->clientID); Log(TRACE_MIN, -1, "Calling command failure for client %s", command->client->c->clientID);
Thread_unlock_mutex(mqttasync_mutex);
(*(command->command.onFailure))(command->command.context, NULL); (*(command->command.onFailure))(command->command.context, NULL);
Thread_lock_mutex(mqttasync_mutex);
} }
MQTTAsync_freeConnect(command->command); MQTTAsync_freeConnect(command->command);
MQTTAsync_freeCommand(command); /* free up the command if necessary */ MQTTAsync_freeCommand(command); /* free up the command if necessary */
...@@ -1103,7 +1124,7 @@ void MQTTAsync_processCommand() ...@@ -1103,7 +1124,7 @@ void MQTTAsync_processCommand()
} }
exit: exit:
Thread_unlock_mutex(mqttasync_mutex); MQTTAsync_unlock_mutex(mqttasync_mutex);
FUNC_EXIT; FUNC_EXIT;
} }
...@@ -1119,7 +1140,7 @@ void MQTTAsync_checkTimeouts() ...@@ -1119,7 +1140,7 @@ void MQTTAsync_checkTimeouts()
if (difftime(now, last) < 3) if (difftime(now, last) < 3)
goto exit; goto exit;
Thread_lock_mutex(mqttasync_mutex); MQTTAsync_lock_mutex(mqttasync_mutex);
last = now; last = now;
while (ListNextElement(handles, &current)) /* for each client */ while (ListNextElement(handles, &current)) /* for each client */
{ {
...@@ -1153,9 +1174,7 @@ void MQTTAsync_checkTimeouts() ...@@ -1153,9 +1174,7 @@ void MQTTAsync_checkTimeouts()
if (m->connect.onFailure) if (m->connect.onFailure)
{ {
Log(TRACE_MIN, -1, "Calling connect failure for client %s", m->c->clientID); Log(TRACE_MIN, -1, "Calling connect failure for client %s", m->c->clientID);
Thread_unlock_mutex(mqttasync_mutex);
(*(m->connect.onFailure))(m->connect.context, NULL); (*(m->connect.onFailure))(m->connect.context, NULL);
Thread_lock_mutex(mqttasync_mutex);
} }
} }
continue; continue;
...@@ -1171,7 +1190,7 @@ void MQTTAsync_checkTimeouts() ...@@ -1171,7 +1190,7 @@ void MQTTAsync_checkTimeouts()
{ {
MQTTAsync_queuedCommand* com = (MQTTAsync_queuedCommand*)(cur_response->content); MQTTAsync_queuedCommand* com = (MQTTAsync_queuedCommand*)(cur_response->content);
if (MQTTAsync_elapsed(com->command.start_time) < 30000) if (1 /*MQTTAsync_elapsed(com->command.start_time) < 120000*/)
break; /* command has not timed out */ break; /* command has not timed out */
else else
{ {
...@@ -1179,9 +1198,7 @@ void MQTTAsync_checkTimeouts() ...@@ -1179,9 +1198,7 @@ void MQTTAsync_checkTimeouts()
{ {
Log(TRACE_MIN, -1, "Calling %s failure for client %s", Log(TRACE_MIN, -1, "Calling %s failure for client %s",
MQTTPacket_name(com->command.type), m->c->clientID); MQTTPacket_name(com->command.type), m->c->clientID);
Thread_unlock_mutex(mqttasync_mutex);
(*(com->command.onFailure))(com->command.context, NULL); (*(com->command.onFailure))(com->command.context, NULL);
Thread_lock_mutex(mqttasync_mutex);
} }
timed_out_count++; timed_out_count++;
} }
...@@ -1189,8 +1206,8 @@ void MQTTAsync_checkTimeouts() ...@@ -1189,8 +1206,8 @@ void MQTTAsync_checkTimeouts()
for (i = 0; i < timed_out_count; ++i) for (i = 0; i < timed_out_count; ++i)
ListRemoveHead(m->responses); /* remove the first response in the list */ ListRemoveHead(m->responses); /* remove the first response in the list */
} }
MQTTAsync_unlock_mutex(mqttasync_mutex);
exit: exit:
Thread_unlock_mutex(mqttasync_mutex);
FUNC_EXIT; FUNC_EXIT;
} }
...@@ -1198,9 +1215,9 @@ exit: ...@@ -1198,9 +1215,9 @@ exit:
thread_return_type WINAPI MQTTAsync_sendThread(void* n) thread_return_type WINAPI MQTTAsync_sendThread(void* n)
{ {
FUNC_ENTRY; FUNC_ENTRY;
Thread_lock_mutex(mqttasync_mutex); MQTTAsync_lock_mutex(mqttasync_mutex);
sendThread_state = RUNNING; sendThread_state = RUNNING;
Thread_unlock_mutex(mqttasync_mutex); MQTTAsync_unlock_mutex(mqttasync_mutex);
while (!tostop) while (!tostop)
{ {
/*int rc;*/ /*int rc;*/
...@@ -1208,17 +1225,17 @@ thread_return_type WINAPI MQTTAsync_sendThread(void* n) ...@@ -1208,17 +1225,17 @@ thread_return_type WINAPI MQTTAsync_sendThread(void* n)
while (commands->count > 0) while (commands->count > 0)
MQTTAsync_processCommand(); MQTTAsync_processCommand();
#if !defined(WIN32) #if !defined(WIN32)
/*rc =*/ Thread_wait_cond_timeout(send_cond, 1); /*rc =*/ Thread_wait_cond(send_cond, 1);
#else #else
/*rc =*/ Thread_wait_sem_timeout(send_sem, 1); /*rc =*/ Thread_wait_sem(send_sem, 1000);
#endif #endif
MQTTAsync_checkTimeouts(); MQTTAsync_checkTimeouts();
} }
sendThread_state = STOPPING; sendThread_state = STOPPING;
Thread_lock_mutex(mqttasync_mutex); MQTTAsync_lock_mutex(mqttasync_mutex);
sendThread_state = STOPPED; sendThread_state = STOPPED;
Thread_unlock_mutex(mqttasync_mutex); MQTTAsync_unlock_mutex(mqttasync_mutex);
FUNC_EXIT; FUNC_EXIT;
return 0; return 0;
} }
...@@ -1290,7 +1307,7 @@ void MQTTAsync_destroy(MQTTAsync* handle) ...@@ -1290,7 +1307,7 @@ void MQTTAsync_destroy(MQTTAsync* handle)
MQTTAsyncs* m = *handle; MQTTAsyncs* m = *handle;
FUNC_ENTRY; FUNC_ENTRY;
Thread_lock_mutex(mqttasync_mutex); MQTTAsync_lock_mutex(mqttasync_mutex);
if (m == NULL) if (m == NULL)
goto exit; goto exit;
...@@ -1324,7 +1341,7 @@ void MQTTAsync_destroy(MQTTAsync* handle) ...@@ -1324,7 +1341,7 @@ void MQTTAsync_destroy(MQTTAsync* handle)
MQTTAsync_terminate(); MQTTAsync_terminate();
exit: exit:
Thread_unlock_mutex(mqttasync_mutex); MQTTAsync_unlock_mutex(mqttasync_mutex);
FUNC_EXIT; FUNC_EXIT;
} }
...@@ -1389,7 +1406,7 @@ thread_return_type WINAPI MQTTAsync_receiveThread(void* n) ...@@ -1389,7 +1406,7 @@ thread_return_type WINAPI MQTTAsync_receiveThread(void* n)
long timeout = 10L; /* first time in we have a small timeout. Gets things started more quickly */ long timeout = 10L; /* first time in we have a small timeout. Gets things started more quickly */
FUNC_ENTRY; FUNC_ENTRY;
Thread_lock_mutex(mqttasync_mutex); MQTTAsync_lock_mutex(mqttasync_mutex);
receiveThread_state = RUNNING; receiveThread_state = RUNNING;
while (!tostop) while (!tostop)
{ {
...@@ -1398,9 +1415,9 @@ thread_return_type WINAPI MQTTAsync_receiveThread(void* n) ...@@ -1398,9 +1415,9 @@ thread_return_type WINAPI MQTTAsync_receiveThread(void* n)
MQTTAsyncs* m = NULL; MQTTAsyncs* m = NULL;
MQTTPacket* pack = NULL; MQTTPacket* pack = NULL;
Thread_unlock_mutex(mqttasync_mutex); MQTTAsync_unlock_mutex(mqttasync_mutex);
pack = MQTTAsync_cycle(&sock, timeout, &rc); pack = MQTTAsync_cycle(&sock, timeout, &rc);
Thread_lock_mutex(mqttasync_mutex); MQTTAsync_lock_mutex(mqttasync_mutex);
if (tostop) if (tostop)
break; break;
timeout = 1000L; timeout = 1000L;
...@@ -1419,9 +1436,9 @@ thread_return_type WINAPI MQTTAsync_receiveThread(void* n) ...@@ -1419,9 +1436,9 @@ thread_return_type WINAPI MQTTAsync_receiveThread(void* n)
} }
if (rc == SOCKET_ERROR) if (rc == SOCKET_ERROR)
{ {
Thread_unlock_mutex(mqttasync_mutex); MQTTAsync_unlock_mutex(mqttasync_mutex);
MQTTAsync_disconnect_internal(m, 0); MQTTAsync_disconnect_internal(m, 0);
Thread_lock_mutex(mqttasync_mutex); MQTTAsync_lock_mutex(mqttasync_mutex);
} }
else else
{ {
...@@ -1465,9 +1482,7 @@ thread_return_type WINAPI MQTTAsync_receiveThread(void* n) ...@@ -1465,9 +1482,7 @@ thread_return_type WINAPI MQTTAsync_receiveThread(void* n)
if (m->connect.onSuccess) if (m->connect.onSuccess)
{ {
Log(TRACE_MIN, -1, "Calling connect success for client %s", m->c->clientID); Log(TRACE_MIN, -1, "Calling connect success for client %s", m->c->clientID);
Thread_unlock_mutex(mqttasync_mutex);
(*(m->connect.onSuccess))(m->connect.context, NULL); (*(m->connect.onSuccess))(m->connect.context, NULL);
Thread_lock_mutex(mqttasync_mutex);
} }
} }
else else
...@@ -1498,9 +1513,7 @@ thread_return_type WINAPI MQTTAsync_receiveThread(void* n) ...@@ -1498,9 +1513,7 @@ thread_return_type WINAPI MQTTAsync_receiveThread(void* n)
data.code = rc; data.code = rc;
data.message = "CONNACK return code"; data.message = "CONNACK return code";
Log(TRACE_MIN, -1, "Calling connect failure for client %s", m->c->clientID); Log(TRACE_MIN, -1, "Calling connect failure for client %s", m->c->clientID);
Thread_unlock_mutex(mqttasync_mutex);
(*(m->connect.onFailure))(m->connect.context, &data); (*(m->connect.onFailure))(m->connect.context, &data);
Thread_lock_mutex(mqttasync_mutex);
} }
} }
} }
...@@ -1538,9 +1551,7 @@ thread_return_type WINAPI MQTTAsync_receiveThread(void* n) ...@@ -1538,9 +1551,7 @@ thread_return_type WINAPI MQTTAsync_receiveThread(void* n)
rc = MQTTProtocol_handleSubacks(pack, m->c->net.socket); rc = MQTTProtocol_handleSubacks(pack, m->c->net.socket);
handleCalled = 1; handleCalled = 1;
Log(TRACE_MIN, -1, "Calling subscribe success for client %s", m->c->clientID); Log(TRACE_MIN, -1, "Calling subscribe success for client %s", m->c->clientID);
Thread_unlock_mutex(mqttasync_mutex);
(*(command->command.onSuccess))(command->command.context, &data); (*(command->command.onSuccess))(command->command.context, &data);
Thread_lock_mutex(mqttasync_mutex);
if (array) if (array)
free(array); free(array);
} }
...@@ -1569,9 +1580,7 @@ thread_return_type WINAPI MQTTAsync_receiveThread(void* n) ...@@ -1569,9 +1580,7 @@ thread_return_type WINAPI MQTTAsync_receiveThread(void* n)
rc = MQTTProtocol_handleUnsubacks(pack, m->c->net.socket); rc = MQTTProtocol_handleUnsubacks(pack, m->c->net.socket);
handleCalled = 1; handleCalled = 1;
Log(TRACE_MIN, -1, "Calling unsubscribe success for client %s", m->c->clientID); Log(TRACE_MIN, -1, "Calling unsubscribe success for client %s", m->c->clientID);
Thread_unlock_mutex(mqttasync_mutex);
(*(command->command.onSuccess))(command->command.context, NULL); (*(command->command.onSuccess))(command->command.context, NULL);
Thread_lock_mutex(mqttasync_mutex);
} }
MQTTAsync_freeCommand(command); MQTTAsync_freeCommand(command);
break; break;
...@@ -1584,7 +1593,7 @@ thread_return_type WINAPI MQTTAsync_receiveThread(void* n) ...@@ -1584,7 +1593,7 @@ thread_return_type WINAPI MQTTAsync_receiveThread(void* n)
} }
} }
receiveThread_state = STOPPED; receiveThread_state = STOPPED;
Thread_unlock_mutex(mqttasync_mutex); MQTTAsync_unlock_mutex(mqttasync_mutex);
#if !defined(WIN32) #if !defined(WIN32)
if (sendThread_state != STOPPED) if (sendThread_state != STOPPED)
Thread_signal_cond(send_cond); Thread_signal_cond(send_cond);
...@@ -1625,10 +1634,10 @@ void MQTTAsync_stop() ...@@ -1625,10 +1634,10 @@ void MQTTAsync_stop()
tostop = 1; tostop = 1;
while ((sendThread_state != STOPPED || receiveThread_state != STOPPED) && ++count < 100) while ((sendThread_state != STOPPED || receiveThread_state != STOPPED) && ++count < 100)
{ {
Thread_unlock_mutex(mqttasync_mutex); MQTTAsync_unlock_mutex(mqttasync_mutex);
Log(TRACE_MIN, -1, "sleeping"); Log(TRACE_MIN, -1, "sleeping");
MQTTAsync_sleep(100L); MQTTAsync_sleep(100L);
Thread_lock_mutex(mqttasync_mutex); MQTTAsync_lock_mutex(mqttasync_mutex);
} }
rc = 1; rc = 1;
tostop = 0; tostop = 0;
...@@ -1647,7 +1656,7 @@ int MQTTAsync_setCallbacks(MQTTAsync handle, void* context, ...@@ -1647,7 +1656,7 @@ int MQTTAsync_setCallbacks(MQTTAsync handle, void* context,
MQTTAsyncs* m = handle; MQTTAsyncs* m = handle;
FUNC_ENTRY; FUNC_ENTRY;
Thread_lock_mutex(mqttasync_mutex); MQTTAsync_lock_mutex(mqttasync_mutex);
if (m == NULL || ma == NULL || m->c->connect_state != 0) if (m == NULL || ma == NULL || m->c->connect_state != 0)
rc = MQTTASYNC_FAILURE; rc = MQTTASYNC_FAILURE;
...@@ -1659,7 +1668,7 @@ int MQTTAsync_setCallbacks(MQTTAsync handle, void* context, ...@@ -1659,7 +1668,7 @@ int MQTTAsync_setCallbacks(MQTTAsync handle, void* context,
m->dc = dc; m->dc = dc;
} }
Thread_unlock_mutex(mqttasync_mutex); MQTTAsync_unlock_mutex(mqttasync_mutex);
FUNC_EXIT_RC(rc); FUNC_EXIT_RC(rc);
return rc; return rc;
} }
...@@ -1903,9 +1912,7 @@ int MQTTAsync_deliverMessage(MQTTAsyncs* m, char* topicName, int topicLen, MQTTA ...@@ -1903,9 +1912,7 @@ int MQTTAsync_deliverMessage(MQTTAsyncs* m, char* topicName, int topicLen, MQTTA
Log(TRACE_MIN, -1, "Calling messageArrived for client %s, queue depth %d", Log(TRACE_MIN, -1, "Calling messageArrived for client %s, queue depth %d",
m->c->clientID, m->c->messageQueue->count); m->c->clientID, m->c->messageQueue->count);
Thread_unlock_mutex(mqttasync_mutex);
rc = (*(m->ma))(m->context, topicName, topicLen, mm); rc = (*(m->ma))(m->context, topicName, topicLen, mm);
Thread_lock_mutex(mqttasync_mutex);
/* if 0 (false) is returned by the callback then it failed, so we don't remove the message from /* if 0 (false) is returned by the callback then it failed, so we don't remove the message from
* the queue, and it will be retried later. If 1 is returned then the message data may have been freed, * the queue, and it will be retried later. If 1 is returned then the message data may have been freed,
* so we must be careful how we use it. * so we must be careful how we use it.
...@@ -2028,17 +2035,17 @@ int MQTTAsync_connect(MQTTAsync handle, MQTTAsync_connectOptions* options) ...@@ -2028,17 +2035,17 @@ int MQTTAsync_connect(MQTTAsync handle, MQTTAsync_connectOptions* options)
tostop = 0; tostop = 0;
if (sendThread_state != STARTING && sendThread_state != RUNNING) if (sendThread_state != STARTING && sendThread_state != RUNNING)
{ {
Thread_lock_mutex(mqttasync_mutex); MQTTAsync_lock_mutex(mqttasync_mutex);
sendThread_state = STARTING; sendThread_state = STARTING;
Thread_start(MQTTAsync_sendThread, NULL); Thread_start(MQTTAsync_sendThread, NULL);
Thread_unlock_mutex(mqttasync_mutex); MQTTAsync_unlock_mutex(mqttasync_mutex);
} }
if (receiveThread_state != STARTING && receiveThread_state != RUNNING) if (receiveThread_state != STARTING && receiveThread_state != RUNNING)
{ {
Thread_lock_mutex(mqttasync_mutex); MQTTAsync_lock_mutex(mqttasync_mutex);
receiveThread_state = STARTING; receiveThread_state = STARTING;
Thread_start(MQTTAsync_receiveThread, handle); Thread_start(MQTTAsync_receiveThread, handle);
Thread_unlock_mutex(mqttasync_mutex); MQTTAsync_unlock_mutex(mqttasync_mutex);
} }
m->c->keepAliveInterval = options->keepAliveInterval; m->c->keepAliveInterval = options->keepAliveInterval;
...@@ -2047,6 +2054,8 @@ int MQTTAsync_connect(MQTTAsync handle, MQTTAsync_connectOptions* options) ...@@ -2047,6 +2054,8 @@ int MQTTAsync_connect(MQTTAsync handle, MQTTAsync_connectOptions* options)
if (m->c->will) if (m->c->will)
{ {
free(m->c->will->msg);
free(m->c->will->topic);
free(m->c->will); free(m->c->will);
m->c->will = NULL; m->c->will = NULL;
} }
...@@ -2063,14 +2072,51 @@ int MQTTAsync_connect(MQTTAsync handle, MQTTAsync_connectOptions* options) ...@@ -2063,14 +2072,51 @@ int MQTTAsync_connect(MQTTAsync handle, MQTTAsync_connectOptions* options)
} }
#if defined(OPENSSL) #if defined(OPENSSL)
if (m->c->sslopts)
{
if (m->c->sslopts->trustStore)
free(m->c->sslopts->trustStore);
if (m->c->sslopts->keyStore)
free(m->c->sslopts->keyStore);
if (m->c->sslopts->privateKey)
free(m->c->sslopts->privateKey);
if (m->c->sslopts->privateKeyPassword)
free(m->c->sslopts->privateKeyPassword);
if (m->c->sslopts->enabledCipherSuites)
free(m->c->sslopts->enabledCipherSuites);
free(m->c->sslopts);
m->c->sslopts = NULL;
}
if (options->struct_version != 0 && options->ssl) if (options->struct_version != 0 && options->ssl)
{ {
m->c->sslopts = malloc(sizeof(MQTTClient_SSLOptions)); m->c->sslopts = malloc(sizeof(MQTTClient_SSLOptions));
m->c->sslopts->trustStore = options->ssl->trustStore; memset(m->c->sslopts, '\0', sizeof(MQTTClient_SSLOptions));
m->c->sslopts->keyStore = options->ssl->keyStore; if (options->ssl->trustStore)
m->c->sslopts->privateKey = options->ssl->privateKey; {
m->c->sslopts->privateKeyPassword = options->ssl->privateKeyPassword; m->c->sslopts->trustStore = malloc(strlen(options->ssl->trustStore) + 1);
m->c->sslopts->enabledCipherSuites = options->ssl->enabledCipherSuites; strcpy(m->c->sslopts->trustStore, options->ssl->trustStore);
}
if (options->ssl->keyStore)
{
m->c->sslopts->keyStore = malloc(strlen(options->ssl->keyStore) + 1);
strcpy(m->c->sslopts->keyStore, options->ssl->keyStore);
}
if (options->ssl->privateKey)
{
m->c->sslopts->privateKey = malloc(strlen(options->ssl->privateKey) + 1);
strcpy(m->c->sslopts->privateKey, options->ssl->privateKey);
}
if (options->ssl->privateKeyPassword)
{
m->c->sslopts->privateKeyPassword = malloc(strlen(options->ssl->privateKeyPassword) + 1);
strcpy(m->c->sslopts->privateKeyPassword, options->ssl->privateKeyPassword);
}
if (options->ssl->enabledCipherSuites)
{
m->c->sslopts->enabledCipherSuites = malloc(strlen(options->ssl->enabledCipherSuites) + 1);
strcpy(m->c->sslopts->enabledCipherSuites, options->ssl->enabledCipherSuites);
}
m->c->sslopts->enableServerCertAuth = options->ssl->enableServerCertAuth; m->c->sslopts->enableServerCertAuth = options->ssl->enableServerCertAuth;
} }
#endif #endif
...@@ -2179,10 +2225,10 @@ int MQTTAsync_isConnected(MQTTAsync handle) ...@@ -2179,10 +2225,10 @@ int MQTTAsync_isConnected(MQTTAsync handle)
int rc = 0; int rc = 0;
FUNC_ENTRY; FUNC_ENTRY;
Thread_lock_mutex(mqttasync_mutex); MQTTAsync_lock_mutex(mqttasync_mutex);
if (m && m->c) if (m && m->c)
rc = m->c->connected; rc = m->c->connected;
Thread_unlock_mutex(mqttasync_mutex); MQTTAsync_unlock_mutex(mqttasync_mutex);
FUNC_EXIT_RC(rc); FUNC_EXIT_RC(rc);
return rc; return rc;
} }
...@@ -2206,6 +2252,11 @@ int MQTTAsync_subscribeMany(MQTTAsync handle, int count, char** topic, int* qos, ...@@ -2206,6 +2252,11 @@ int MQTTAsync_subscribeMany(MQTTAsync handle, int count, char** topic, int* qos,
rc = MQTTASYNC_DISCONNECTED; rc = MQTTASYNC_DISCONNECTED;
goto exit; goto exit;
} }
if (m->c->outboundMsgs->count >= MAX_MSG_ID - 1)
{
rc = MQTTASYNC_NO_MORE_MSGIDS;
goto exit;
}
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
if (!UTF8_validateString(topic[i])) if (!UTF8_validateString(topic[i]))
...@@ -2277,7 +2328,11 @@ int MQTTAsync_unsubscribeMany(MQTTAsync handle, int count, char** topic, MQTTAsy ...@@ -2277,7 +2328,11 @@ int MQTTAsync_unsubscribeMany(MQTTAsync handle, int count, char** topic, MQTTAsy
rc = MQTTASYNC_DISCONNECTED; rc = MQTTASYNC_DISCONNECTED;
goto exit; goto exit;
} }
if (m->c->outboundMsgs->count >= MAX_MSG_ID - 1)
{
rc = MQTTASYNC_NO_MORE_MSGIDS;
goto exit;
}
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
if (!UTF8_validateString(topic[i])) if (!UTF8_validateString(topic[i]))
...@@ -2340,6 +2395,9 @@ int MQTTAsync_send(MQTTAsync handle, char* destinationName, int payloadlen, void ...@@ -2340,6 +2395,9 @@ int MQTTAsync_send(MQTTAsync handle, char* destinationName, int payloadlen, void
rc = MQTTASYNC_BAD_UTF8_STRING; rc = MQTTASYNC_BAD_UTF8_STRING;
else if (qos < 0 || qos > 2) else if (qos < 0 || qos > 2)
rc = MQTTASYNC_BAD_QOS; rc = MQTTASYNC_BAD_QOS;
else if (m->c->outboundMsgs->count >= MAX_MSG_ID - 1)
rc = MQTTASYNC_NO_MORE_MSGIDS;
if (rc != MQTTASYNC_SUCCESS) if (rc != MQTTASYNC_SUCCESS)
goto exit; goto exit;
...@@ -2514,9 +2572,7 @@ exit: ...@@ -2514,9 +2572,7 @@ exit:
if (m->connect.onFailure) if (m->connect.onFailure)
{ {
Log(TRACE_MIN, -1, "Calling connect failure for client %s", m->c->clientID); Log(TRACE_MIN, -1, "Calling connect failure for client %s", m->c->clientID);
Thread_unlock_mutex(mqttasync_mutex);
(*(m->connect.onFailure))(m->connect.context, NULL); (*(m->connect.onFailure))(m->connect.context, NULL);
Thread_lock_mutex(mqttasync_mutex);
} }
} }
} }
...@@ -2559,7 +2615,7 @@ MQTTPacket* MQTTAsync_cycle(int* sock, unsigned long timeout, int* rc) ...@@ -2559,7 +2615,7 @@ MQTTPacket* MQTTAsync_cycle(int* sock, unsigned long timeout, int* rc)
#if defined(OPENSSL) #if defined(OPENSSL)
} }
#endif #endif
Thread_lock_mutex(mqttasync_mutex); MQTTAsync_lock_mutex(mqttasync_mutex);
if (*sock > 0) if (*sock > 0)
{ {
MQTTAsyncs* m = NULL; MQTTAsyncs* m = NULL;
...@@ -2595,9 +2651,7 @@ MQTTPacket* MQTTAsync_cycle(int* sock, unsigned long timeout, int* rc) ...@@ -2595,9 +2651,7 @@ MQTTPacket* MQTTAsync_cycle(int* sock, unsigned long timeout, int* rc)
if (m->connect.onFailure) if (m->connect.onFailure)
{ {
Log(TRACE_MIN, -1, "Calling connect failure for client %s", m->c->clientID); Log(TRACE_MIN, -1, "Calling connect failure for client %s", m->c->clientID);
Thread_unlock_mutex(mqttasync_mutex);
(*(m->connect.onFailure))(m->connect.context, NULL); (*(m->connect.onFailure))(m->connect.context, NULL);
Thread_lock_mutex(mqttasync_mutex);
} }
} }
} }
...@@ -2617,6 +2671,8 @@ MQTTPacket* MQTTAsync_cycle(int* sock, unsigned long timeout, int* rc) ...@@ -2617,6 +2671,8 @@ MQTTPacket* MQTTAsync_cycle(int* sock, unsigned long timeout, int* rc)
msgid = ack.msgId; msgid = ack.msgId;
*rc = (pack->header.bits.type == PUBCOMP) ? *rc = (pack->header.bits.type == PUBCOMP) ?
MQTTProtocol_handlePubcomps(pack, *sock) : MQTTProtocol_handlePubacks(pack, *sock); MQTTProtocol_handlePubcomps(pack, *sock) : MQTTProtocol_handlePubacks(pack, *sock);
if (!m)
Log(LOG_ERROR, -1, "PUBCOMP or PUBACK received for no client, msgid %d", msgid);
if (m) if (m)
{ {
ListElement* current = NULL; ListElement* current = NULL;
...@@ -2645,9 +2701,7 @@ MQTTPacket* MQTTAsync_cycle(int* sock, unsigned long timeout, int* rc) ...@@ -2645,9 +2701,7 @@ MQTTPacket* MQTTAsync_cycle(int* sock, unsigned long timeout, int* rc)
data.alt.pub.message.qos = command->command.details.pub.qos; data.alt.pub.message.qos = command->command.details.pub.qos;
data.alt.pub.message.retained = command->command.details.pub.retained; data.alt.pub.message.retained = command->command.details.pub.retained;
Log(TRACE_MIN, -1, "Calling publish success for client %s", m->c->clientID); Log(TRACE_MIN, -1, "Calling publish success for client %s", m->c->clientID);
Thread_unlock_mutex(mqttasync_mutex);
(*(command->command.onSuccess))(command->command.context, &data); (*(command->command.onSuccess))(command->command.context, &data);
Thread_lock_mutex(mqttasync_mutex);
} }
MQTTAsync_freeCommand(command); MQTTAsync_freeCommand(command);
break; break;
...@@ -2668,7 +2722,7 @@ MQTTPacket* MQTTAsync_cycle(int* sock, unsigned long timeout, int* rc) ...@@ -2668,7 +2722,7 @@ MQTTPacket* MQTTAsync_cycle(int* sock, unsigned long timeout, int* rc)
} }
} }
MQTTAsync_retry(); MQTTAsync_retry();
Thread_unlock_mutex(mqttasync_mutex); MQTTAsync_unlock_mutex(mqttasync_mutex);
FUNC_EXIT_RC(*rc); FUNC_EXIT_RC(*rc);
return pack; return pack;
} }
...@@ -2688,7 +2742,7 @@ int MQTTAsync_getPendingTokens(MQTTAsync handle, MQTTAsync_token **tokens) ...@@ -2688,7 +2742,7 @@ int MQTTAsync_getPendingTokens(MQTTAsync handle, MQTTAsync_token **tokens)
*tokens = NULL; *tokens = NULL;
FUNC_ENTRY; FUNC_ENTRY;
Thread_lock_mutex(mqttasync_mutex); MQTTAsync_lock_mutex(mqttasync_mutex);
if (m == NULL) if (m == NULL)
{ {
...@@ -2711,7 +2765,7 @@ int MQTTAsync_getPendingTokens(MQTTAsync handle, MQTTAsync_token **tokens) ...@@ -2711,7 +2765,7 @@ int MQTTAsync_getPendingTokens(MQTTAsync handle, MQTTAsync_token **tokens)
} }
exit: exit:
Thread_unlock_mutex(mqttasync_mutex); MQTTAsync_unlock_mutex(mqttasync_mutex);
FUNC_EXIT_RC(rc); FUNC_EXIT_RC(rc);
return rc; return rc;
} }
......
...@@ -140,6 +140,10 @@ ...@@ -140,6 +140,10 @@
* Return code: A qos parameter is not 0, 1 or 2 * Return code: A qos parameter is not 0, 1 or 2
*/ */
#define MQTTASYNC_BAD_QOS -9 #define MQTTASYNC_BAD_QOS -9
/**
* Return code: All 65535 MQTT msgids are being used
*/
#define MQTTASYNC_NO_MORE_MSGIDS -10
/** /**
* A handle representing an MQTT client. A valid client handle is available * A handle representing an MQTT client. A valid client handle is available
......
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
* Ian Craggs, Allan Stockdill-Mander - add ability to connect with SSL * Ian Craggs, Allan Stockdill-Mander - add ability to connect with SSL
* Ian Craggs - multiple server connection support * Ian Craggs - multiple server connection support
* Ian Craggs - fix for bug 413429 - connectionLost not called * Ian Craggs - fix for bug 413429 - connectionLost not called
* Ian Craggs - fix for bug 421103 - trying to write to same socket, in publish/retries
* Ian Craggs - fix for bug 419233 - mutexes not reporting errors
* Ian Craggs - fix for bug #420851
*******************************************************************************/ *******************************************************************************/
/** /**
...@@ -25,6 +28,7 @@ ...@@ -25,6 +28,7 @@
* *
*/ */
#define _GNU_SOURCE /* for pthread_mutexattr_settype */
#include <stdlib.h> #include <stdlib.h>
#if !defined(WIN32) #if !defined(WIN32)
#include <sys/time.h> #include <sys/time.h>
...@@ -96,6 +100,18 @@ BOOL APIENTRY DllMain(HANDLE hModule, ...@@ -96,6 +100,18 @@ BOOL APIENTRY DllMain(HANDLE hModule,
#else #else
static pthread_mutex_t mqttclient_mutex_store = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t mqttclient_mutex_store = PTHREAD_MUTEX_INITIALIZER;
static mutex_type mqttclient_mutex = &mqttclient_mutex_store; static mutex_type mqttclient_mutex = &mqttclient_mutex_store;
void MQTTClient_init()
{
pthread_mutexattr_t attr;
int rc;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
if ((rc = pthread_mutex_init(mqttclient_mutex, &attr)) != 0)
printf("MQTTAsync: error %d initializing client_mutex\n", rc);
}
#define WINAPI #define WINAPI
#endif #endif
...@@ -735,18 +751,73 @@ int MQTTClient_connectURI(MQTTClient handle, MQTTClient_connectOptions* options, ...@@ -735,18 +751,73 @@ int MQTTClient_connectURI(MQTTClient handle, MQTTClient_connectOptions* options,
m->c->cleansession = options->cleansession; m->c->cleansession = options->cleansession;
m->c->maxInflightMessages = (options->reliable) ? 1 : 10; m->c->maxInflightMessages = (options->reliable) ? 1 : 10;
if (m->c->will)
{
free(m->c->will->msg);
free(m->c->will->topic);
free(m->c->will);
m->c->will = NULL;
}
if (options->will && options->will->struct_version == 0) if (options->will && options->will->struct_version == 0)
{ {
m->c->will = malloc(sizeof(willMessages)); m->c->will = malloc(sizeof(willMessages));
m->c->will->msg = options->will->message; m->c->will->msg = malloc(strlen(options->will->message) + 1);
strcpy(m->c->will->msg, options->will->message);
m->c->will->qos = options->will->qos; m->c->will->qos = options->will->qos;
m->c->will->retained = options->will->retained; m->c->will->retained = options->will->retained;
m->c->will->topic = options->will->topicName; m->c->will->topic = malloc(strlen(options->will->topicName) + 1);
strcpy(m->c->will->topic, options->will->topicName);
} }
#if defined(OPENSSL) #if defined(OPENSSL)
if (m->c->sslopts)
{
if (m->c->sslopts->trustStore)
free(m->c->sslopts->trustStore);
if (m->c->sslopts->keyStore)
free(m->c->sslopts->keyStore);
if (m->c->sslopts->privateKey)
free(m->c->sslopts->privateKey);
if (m->c->sslopts->privateKeyPassword)
free(m->c->sslopts->privateKeyPassword);
if (m->c->sslopts->enabledCipherSuites)
free(m->c->sslopts->enabledCipherSuites);
free(m->c->sslopts);
m->c->sslopts = NULL;
}
if (options->struct_version != 0 && options->ssl) if (options->struct_version != 0 && options->ssl)
m->c->sslopts = options->ssl; {
m->c->sslopts = malloc(sizeof(MQTTClient_SSLOptions));
memset(m->c->sslopts, '\0', sizeof(MQTTClient_SSLOptions));
if (options->ssl->trustStore)
{
m->c->sslopts->trustStore = malloc(strlen(options->ssl->trustStore) + 1);
strcpy(m->c->sslopts->trustStore, options->ssl->trustStore);
}
if (options->ssl->keyStore)
{
m->c->sslopts->keyStore = malloc(strlen(options->ssl->keyStore) + 1);
strcpy(m->c->sslopts->keyStore, options->ssl->keyStore);
}
if (options->ssl->privateKey)
{
m->c->sslopts->privateKey = malloc(strlen(options->ssl->privateKey) + 1);
strcpy(m->c->sslopts->privateKey, options->ssl->privateKey);
}
if (options->ssl->privateKeyPassword)
{
m->c->sslopts->privateKeyPassword = malloc(strlen(options->ssl->privateKeyPassword) + 1);
strcpy(m->c->sslopts->privateKeyPassword, options->ssl->privateKeyPassword);
}
if (options->ssl->enabledCipherSuites)
{
m->c->sslopts->enabledCipherSuites = malloc(strlen(options->ssl->enabledCipherSuites) + 1);
strcpy(m->c->sslopts->enabledCipherSuites, options->ssl->enabledCipherSuites);
}
m->c->sslopts->enableServerCertAuth = options->ssl->enableServerCertAuth;
}
#endif #endif
m->c->username = options->username; m->c->username = options->username;
...@@ -1262,7 +1333,8 @@ int MQTTClient_publish(MQTTClient handle, char* topicName, int payloadlen, void* ...@@ -1262,7 +1333,8 @@ int MQTTClient_publish(MQTTClient handle, char* topicName, int payloadlen, void*
goto exit; goto exit;
/* If outbound queue is full, block until it is not */ /* 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) if (blocked == 0)
{ {
...@@ -1468,15 +1540,15 @@ MQTTPacket* MQTTClient_waitfor(MQTTClient handle, int packet_type, int* rc, long ...@@ -1468,15 +1540,15 @@ MQTTPacket* MQTTClient_waitfor(MQTTClient handle, int packet_type, int* rc, long
{ {
if (packet_type == CONNECT) if (packet_type == CONNECT)
{ {
if ((*rc = Thread_wait_sem(m->connect_sem)) == 0) if ((*rc = Thread_wait_sem(m->connect_sem, timeout)) == 0)
*rc = m->rc; *rc = m->rc;
} }
else if (packet_type == CONNACK) else if (packet_type == CONNACK)
*rc = Thread_wait_sem(m->connack_sem); *rc = Thread_wait_sem(m->connack_sem, timeout);
else if (packet_type == SUBACK) else if (packet_type == SUBACK)
*rc = Thread_wait_sem(m->suback_sem); *rc = Thread_wait_sem(m->suback_sem, timeout);
else if (packet_type == UNSUBACK) else if (packet_type == UNSUBACK)
*rc = Thread_wait_sem(m->unsuback_sem); *rc = Thread_wait_sem(m->unsuback_sem, timeout);
if (*rc == 0 && packet_type != CONNECT && m->pack == NULL) if (*rc == 0 && packet_type != CONNECT && m->pack == NULL)
Log(TRACE_MIN, -1, "waitfor unexpectedly is NULL for client %s, packet_type %d", m->c->clientID, packet_type); Log(TRACE_MIN, -1, "waitfor unexpectedly is NULL for client %s, packet_type %d", m->c->clientID, packet_type);
pack = m->pack; pack = m->pack;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
* 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 * Ian Craggs, Allan Stockdill-Mander - SSL updates
* Ian Craggs - fix for bug 413429 - connectionLost not called * Ian Craggs - fix for bug 413429 - connectionLost not called
* Ian Craggs - fix for bug 421103 - trying to write to same socket, in retry
*******************************************************************************/ *******************************************************************************/
/** /**
...@@ -61,16 +62,28 @@ int messageIDCompare(void* a, void* b) ...@@ -61,16 +62,28 @@ int messageIDCompare(void* a, void* b)
* Assign a new message id for a client. Make sure it isn't already being used and does * Assign a new message id for a client. Make sure it isn't already being used and does
* not exceed the maximum. * not exceed the maximum.
* @param client a client structure * @param client a client structure
* @return the next message id to use * @return the next message id to use, or 0 if none available
*/ */
int MQTTProtocol_assignMsgId(Clients* client) int MQTTProtocol_assignMsgId(Clients* client)
{ {
int start_msgid = client->msgID;
int msgid = start_msgid;
FUNC_ENTRY; FUNC_ENTRY;
client->msgID = (client->msgID == MAX_MSG_ID) ? 1 : client->msgID + 1; msgid = (msgid == MAX_MSG_ID) ? 1 : msgid + 1;
while (ListFindItem(client->outboundMsgs, &(client->msgID), messageIDCompare) != NULL) while (ListFindItem(client->outboundMsgs, &msgid, messageIDCompare) != NULL)
client->msgID = (client->msgID == MAX_MSG_ID) ? 1 : client->msgID + 1; {
FUNC_EXIT_RC(client->msgID); msgid = (msgid == MAX_MSG_ID) ? 1 : msgid + 1;
return client->msgID; if (msgid == start_msgid)
{ /* we've tried them all - none free */
msgid = 0;
break;
}
}
if (msgid != 0)
client->msgID = msgid;
FUNC_EXIT_RC(msgid);
return msgid;
} }
...@@ -544,7 +557,9 @@ void MQTTProtocol_retries(time_t now, Clients* client) ...@@ -544,7 +557,9 @@ void MQTTProtocol_retries(time_t now, Clients* client)
if (client->retryInterval <= 0) /* 0 or -ive retryInterval turns off retry */ if (client->retryInterval <= 0) /* 0 or -ive retryInterval turns off retry */
goto exit; goto exit;
while (client && ListNextElement(client->outboundMsgs, &outcurrent)) while (client && ListNextElement(client->outboundMsgs, &outcurrent) &&
client->connected && client->good && /* client is connected and has no errors */
Socket_noPendingWrites(client->net.socket)) /* there aren't any previous packets still stacked up on the socket */
{ {
Messages* m = (Messages*)(outcurrent->content); Messages* m = (Messages*)(outcurrent->content);
if (difftime(now, m->lastTouch) > max(client->retryInterval, 10)) if (difftime(now, m->lastTouch) > max(client->retryInterval, 10))
...@@ -649,7 +664,19 @@ void MQTTProtocol_freeClient(Clients* client) ...@@ -649,7 +664,19 @@ void MQTTProtocol_freeClient(Clients* client)
} }
#if defined(OPENSSL) #if defined(OPENSSL)
if (client->sslopts) if (client->sslopts)
{
if (client->sslopts->trustStore)
free(client->sslopts->trustStore);
if (client->sslopts->keyStore)
free(client->sslopts->keyStore);
if (client->sslopts->privateKey)
free(client->sslopts->privateKey);
if (client->sslopts->privateKeyPassword)
free(client->sslopts->privateKeyPassword);
if (client->sslopts->enabledCipherSuites)
free(client->sslopts->enabledCipherSuites);
free(client->sslopts); free(client->sslopts);
}
#endif #endif
/* don't free the client structure itself... this is done elsewhere */ /* don't free the client structure itself... this is done elsewhere */
FUNC_EXIT; FUNC_EXIT;
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
* */ * */
char* libraries[] = {"mqttv3c", "mqttv3cs", "mqttv3a", "mqttv3as"}; char* libraries[] = {"paho-mqtt3c", "paho-mqtt3cs", "paho-mqtt3a", "paho-mqtt3as"};
char* eyecatchers[] = {"MQTTAsyncV3_Version", "MQTTAsyncV3_Timestamp", char* eyecatchers[] = {"MQTTAsyncV3_Version", "MQTTAsyncV3_Timestamp",
"MQTTClientV3_Version", "MQTTClientV3_Timestamp"}; "MQTTClientV3_Version", "MQTTClientV3_Timestamp"};
...@@ -176,7 +176,7 @@ void printEyecatchers(char* filename) ...@@ -176,7 +176,7 @@ void printEyecatchers(char* filename)
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
printf("MQTTVersion: print the version strings of an MQTT client library\n"); printf("MQTTVersion: print the version strings of an MQTT client library\n");
printf("Copyright (c) 2012 IBM Corp.\n"); printf("Copyright (c) 2013 IBM Corp.\n");
if (argc == 1) if (argc == 1)
{ {
...@@ -190,7 +190,7 @@ int main(int argc, char** argv) ...@@ -190,7 +190,7 @@ int main(int argc, char** argv)
#if defined(WIN32) #if defined(WIN32)
sprintf(namebuf, "%s.dll", libraries[i]); sprintf(namebuf, "%s.dll", libraries[i]);
#else #else
sprintf(namebuf, "lib%s.so", libraries[i]); sprintf(namebuf, "lib%s.so.1", libraries[i]);
#endif #endif
printf("--- Trying library %s ---\n", libraries[i]); printf("--- Trying library %s ---\n", libraries[i]);
if (!loadandcall(namebuf)) if (!loadandcall(namebuf))
......
...@@ -461,6 +461,8 @@ int SSLSocket_createContext(networkHandles* net, MQTTClient_SSLOptions* opts) ...@@ -461,6 +461,8 @@ int SSLSocket_createContext(networkHandles* net, MQTTClient_SSLOptions* opts)
if (opts->keyStore) if (opts->keyStore)
{ {
int rc1 = 0;
if ((rc = SSL_CTX_use_certificate_chain_file(net->ctx, opts->keyStore)) != 1) if ((rc = SSL_CTX_use_certificate_chain_file(net->ctx, opts->keyStore)) != 1)
{ {
SSLSocket_error("SSL_CTX_use_certificate_chain_file", NULL, net->socket, rc); SSLSocket_error("SSL_CTX_use_certificate_chain_file", NULL, net->socket, rc);
...@@ -477,7 +479,10 @@ int SSLSocket_createContext(networkHandles* net, MQTTClient_SSLOptions* opts) ...@@ -477,7 +479,10 @@ int SSLSocket_createContext(networkHandles* net, MQTTClient_SSLOptions* opts)
} }
/* support for ASN.1 == DER format? DER can contain only one certificate? */ /* support for ASN.1 == DER format? DER can contain only one certificate? */
if ((rc = SSL_CTX_use_PrivateKey_file(net->ctx, opts->privateKey, SSL_FILETYPE_PEM)) != 1) rc1 = SSL_CTX_use_PrivateKey_file(net->ctx, opts->privateKey, SSL_FILETYPE_PEM);
if (opts->privateKey == opts->keyStore)
opts->privateKey = NULL;
if (rc1 != 1)
{ {
SSLSocket_error("SSL_CTX_use_PrivateKey_file", NULL, net->socket, rc); SSLSocket_error("SSL_CTX_use_PrivateKey_file", NULL, net->socket, rc);
goto free_ctx; goto free_ctx;
......
...@@ -45,14 +45,14 @@ BE*/ ...@@ -45,14 +45,14 @@ BE*/
typedef struct typedef struct
{ {
unsigned long threadid; thread_id_type threadid;
char name[MAX_FUNCTION_NAME_LENGTH]; char name[MAX_FUNCTION_NAME_LENGTH];
int line; int line;
} stackEntry; } stackEntry;
typedef struct typedef struct
{ {
unsigned long id; thread_id_type id;
int maxdepth; int maxdepth;
int current_depth; int current_depth;
stackEntry callstack[MAX_STACK_DEPTH]; stackEntry callstack[MAX_STACK_DEPTH];
...@@ -137,11 +137,13 @@ exit: ...@@ -137,11 +137,13 @@ exit:
} }
void StackTrace_printStack(char* dest) void StackTrace_printStack(FILE* dest)
{ {
FILE* file = stdout; FILE* file = stdout;
int t = 0; int t = 0;
if (dest)
file = dest;
for (t = 0; t < thread_count; ++t) for (t = 0; t < thread_count; ++t)
{ {
threadEntry *cur_thread = &threads[t]; threadEntry *cur_thread = &threads[t];
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#ifndef STACKTRACE_H_ #ifndef STACKTRACE_H_
#define STACKTRACE_H_ #define STACKTRACE_H_
#include <stdio.h>
#include "Log.h" #include "Log.h"
#if defined(NOSTACKTRACE) #if defined(NOSTACKTRACE)
...@@ -63,7 +64,7 @@ ...@@ -63,7 +64,7 @@
void StackTrace_entry(const char* name, int line, int trace); void StackTrace_entry(const char* name, int line, int trace);
void StackTrace_exit(const char* name, int line, void* return_value, int trace); void StackTrace_exit(const char* name, int line, void* return_value, int trace);
void StackTrace_dumpStack(char* dest); void StackTrace_printStack(FILE* dest);
char* StackTrace_get(unsigned long); char* StackTrace_get(unsigned long);
#endif /* STACKTRACE_H_ */ #endif /* STACKTRACE_H_ */
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
* Ian Craggs - initial implementation * Ian Craggs - initial implementation
* Ian Craggs, Allan Stockdill-Mander - async client updates * Ian Craggs, Allan Stockdill-Mander - async client updates
* Ian Craggs - bug #415042 - start Linux thread as disconnected * Ian Craggs - bug #415042 - start Linux thread as disconnected
* Ian Craggs - fix for bug #420851
*******************************************************************************/ *******************************************************************************/
/** /**
...@@ -100,7 +101,7 @@ mutex_type Thread_create_mutex() ...@@ -100,7 +101,7 @@ mutex_type Thread_create_mutex()
/** /**
* Lock a mutex which has already been created, block until ready * Lock a mutex which has already been created, block until ready
* @param mutex the mutex * @param mutex the mutex
* @return completion code * @return completion code, 0 is success
*/ */
int Thread_lock_mutex(mutex_type mutex) int Thread_lock_mutex(mutex_type mutex)
{ {
...@@ -108,11 +109,11 @@ int Thread_lock_mutex(mutex_type mutex) ...@@ -108,11 +109,11 @@ int Thread_lock_mutex(mutex_type mutex)
/* don't add entry/exit trace points as the stack log uses mutexes - recursion beckons */ /* don't add entry/exit trace points as the stack log uses mutexes - recursion beckons */
#if defined(WIN32) #if defined(WIN32)
if (WaitForSingleObject(mutex, INFINITE) != WAIT_FAILED) /* WaitForSingleObject returns WAIT_OBJECT_0 (0), on success */
rc = WaitForSingleObject(mutex, INFINITE);
#else #else
if ((rc = pthread_mutex_lock(mutex)) == 0) rc = pthread_mutex_lock(mutex);
#endif #endif
rc = 0;
return rc; return rc;
} }
...@@ -121,7 +122,7 @@ int Thread_lock_mutex(mutex_type mutex) ...@@ -121,7 +122,7 @@ int Thread_lock_mutex(mutex_type mutex)
/** /**
* Unlock a mutex which has already been locked * Unlock a mutex which has already been locked
* @param mutex the mutex * @param mutex the mutex
* @return completion code * @return completion code, 0 is success
*/ */
int Thread_unlock_mutex(mutex_type mutex) int Thread_unlock_mutex(mutex_type mutex)
{ {
...@@ -129,11 +130,14 @@ int Thread_unlock_mutex(mutex_type mutex) ...@@ -129,11 +130,14 @@ int Thread_unlock_mutex(mutex_type mutex)
/* don't add entry/exit trace points as the stack log uses mutexes - recursion beckons */ /* don't add entry/exit trace points as the stack log uses mutexes - recursion beckons */
#if defined(WIN32) #if defined(WIN32)
if (ReleaseMutex(mutex) != 0) /* if ReleaseMutex fails, the return value is 0 */
if (ReleaseMutex(mutex) == 0)
rc = GetLastError();
else
rc = 0;
#else #else
if ((rc = pthread_mutex_unlock(mutex)) == 0) rc = pthread_mutex_unlock(mutex);
#endif #endif
rc = 0;
return rc; return rc;
} }
...@@ -236,10 +240,10 @@ sem_type Thread_create_sem() ...@@ -236,10 +240,10 @@ sem_type Thread_create_sem()
/** /**
* Wait for a semaphore to be posted, or timeout. * Wait for a semaphore to be posted, or timeout.
* @param sem the semaphore * @param sem the semaphore
* @param timeout the maximum time to wait, in seconds * @param timeout the maximum time to wait, in milliseconds
* @return completion code * @return completion code
*/ */
int Thread_wait_sem_timeout(sem_type sem, int timeout) int Thread_wait_sem(sem_type sem, int timeout)
{ {
/* sem_timedwait is the obvious call to use, but seemed not to work on the Viper, /* sem_timedwait is the obvious call to use, but seemed not to work on the Viper,
* so I've used trywait in a loop instead. Ian Craggs 23/7/2010 * so I've used trywait in a loop instead. Ian Craggs 23/7/2010
...@@ -249,8 +253,8 @@ int Thread_wait_sem_timeout(sem_type sem, int timeout) ...@@ -249,8 +253,8 @@ int Thread_wait_sem_timeout(sem_type sem, int timeout)
#define USE_TRYWAIT #define USE_TRYWAIT
#if defined(USE_TRYWAIT) #if defined(USE_TRYWAIT)
int i = 0; int i = 0;
int interval = 10000; int interval = 10000; /* 10000 microseconds: 10 milliseconds */
int count = (1000000 / interval) * timeout; int count = (1000 * timeout) / interval; /* how many intervals in timeout period */
#else #else
struct timespec ts; struct timespec ts;
#endif #endif
...@@ -258,7 +262,7 @@ int Thread_wait_sem_timeout(sem_type sem, int timeout) ...@@ -258,7 +262,7 @@ int Thread_wait_sem_timeout(sem_type sem, int timeout)
FUNC_ENTRY; FUNC_ENTRY;
#if defined(WIN32) #if defined(WIN32)
rc = WaitForSingleObject(sem, timeout*1000L); rc = WaitForSingleObject(sem, timeout);
#elif defined(USE_TRYWAIT) #elif defined(USE_TRYWAIT)
while (++i < count && (rc = sem_trywait(sem)) != 0) while (++i < count && (rc = sem_trywait(sem)) != 0)
{ {
...@@ -282,17 +286,6 @@ int Thread_wait_sem_timeout(sem_type sem, int timeout) ...@@ -282,17 +286,6 @@ int Thread_wait_sem_timeout(sem_type sem, int timeout)
} }
/**
* Wait for a semaphore to be posted, or timeout after 10 seconds.
* @param sem the semaphore
* @return completion code
*/
int Thread_wait_sem(sem_type sem)
{
return Thread_wait_sem_timeout(sem, 10);
}
/** /**
* Check to see if a semaphore has been posted, without waiting. * Check to see if a semaphore has been posted, without waiting.
* @param sem the semaphore * @param sem the semaphore
...@@ -404,7 +397,7 @@ int Thread_signal_cond(cond_type condvar) ...@@ -404,7 +397,7 @@ int Thread_signal_cond(cond_type condvar)
* Wait with a timeout (seconds) for condition variable * Wait with a timeout (seconds) for condition variable
* @return completion code * @return completion code
*/ */
int Thread_wait_cond_timeout(cond_type condvar, int timeout) int Thread_wait_cond(cond_type condvar, int timeout)
{ {
FUNC_ENTRY; FUNC_ENTRY;
int rc = 0; int rc = 0;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* Contributors: * Contributors:
* Ian Craggs - initial implementation * Ian Craggs - initial implementation
* Ian Craggs, Allan Stockdill-Mander - async client updates * Ian Craggs, Allan Stockdill-Mander - async client updates
* Ian Craggs - fix for bug #420851
*******************************************************************************/ *******************************************************************************/
#if !defined(THREAD_H) #if !defined(THREAD_H)
...@@ -41,7 +42,7 @@ ...@@ -41,7 +42,7 @@
cond_type Thread_create_cond(); cond_type Thread_create_cond();
int Thread_signal_cond(cond_type); int Thread_signal_cond(cond_type);
int Thread_wait_cond_timeout(cond_type condvar, int timeout); int Thread_wait_cond(cond_type condvar, int timeout);
int Thread_destroy_cond(cond_type); int Thread_destroy_cond(cond_type);
#endif #endif
...@@ -55,8 +56,7 @@ void Thread_destroy_mutex(mutex_type); ...@@ -55,8 +56,7 @@ void Thread_destroy_mutex(mutex_type);
thread_id_type Thread_getid(); thread_id_type Thread_getid();
sem_type Thread_create_sem(); sem_type Thread_create_sem();
int Thread_wait_sem(sem_type sem); int Thread_wait_sem(sem_type sem, int timeout);
int Thread_wait_sem_timeout(sem_type sem, int timeout);
int Thread_check_sem(sem_type sem); int Thread_check_sem(sem_type sem);
int Thread_post_sem(sem_type sem); int Thread_post_sem(sem_type sem);
int Thread_destroy_sem(sem_type sem); int Thread_destroy_sem(sem_type sem);
......
...@@ -63,7 +63,7 @@ void usage() ...@@ -63,7 +63,7 @@ void usage()
printf(" --port <port> (default is 1883)\n"); printf(" --port <port> (default is 1883)\n");
printf(" --qos <qos> (default is 0)\n"); printf(" --qos <qos> (default is 0)\n");
printf(" --retained (default is off)\n"); printf(" --retained (default is off)\n");
printf(" --delimiter <delim> (default is \n)"); printf(" --delimiter <delim> (default is \\n)");
printf(" --clientid <clientid> (default is hostname+timestamp)"); printf(" --clientid <clientid> (default is hostname+timestamp)");
printf(" --maxdatalen 100\n"); printf(" --maxdatalen 100\n");
printf(" --username none\n"); printf(" --username none\n");
...@@ -93,7 +93,7 @@ void cfinish(int sig) ...@@ -93,7 +93,7 @@ void cfinish(int sig)
struct struct
{ {
char* clientid; char* clientid;
char delimiter; char* delimiter;
int maxdatalen; int maxdatalen;
int qos; int qos;
int retained; int retained;
...@@ -104,7 +104,7 @@ struct ...@@ -104,7 +104,7 @@ struct
int verbose; int verbose;
} opts = } opts =
{ {
"publisher", '\n', 100, 0, 0, NULL, NULL, "localhost", "1883", 0 "publisher", "\n", 100, 0, 0, NULL, NULL, "localhost", "1883", 0
}; };
void getopts(int argc, char** argv); void getopts(int argc, char** argv);
...@@ -156,11 +156,19 @@ int main(int argc, char** argv) ...@@ -156,11 +156,19 @@ int main(int argc, char** argv)
while (!toStop) while (!toStop)
{ {
int data_len = 0; int data_len = 0;
int delim_len = 0;
delim_len = strlen(opts.delimiter);
do do
{ {
buffer[data_len++] = getchar(); buffer[data_len++] = getchar();
} while (buffer[data_len-1] != opts.delimiter && data_len < opts.maxdatalen); if (data_len > delim_len)
{
//printf("comparing %s %s\n", opts.delimiter, &buffer[data_len - delim_len]);
if (strncmp(opts.delimiter, &buffer[data_len - delim_len], delim_len) == 0)
break;
}
} while (data_len < opts.maxdatalen);
if (opts.verbose) if (opts.verbose)
printf("Publishing data of length %d\n", data_len); printf("Publishing data of length %d\n", data_len);
...@@ -256,7 +264,7 @@ void getopts(int argc, char** argv) ...@@ -256,7 +264,7 @@ void getopts(int argc, char** argv)
else if (strcmp(argv[count], "--delimiter") == 0) else if (strcmp(argv[count], "--delimiter") == 0)
{ {
if (++count < argc) if (++count < argc)
opts.delimiter = argv[count][0]; opts.delimiter = argv[count];
else else
usage(); usage();
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
* *
* Contributors: * Contributors:
* Ian Craggs - initial contribution * Ian Craggs - initial contribution
* Ian Craggs - change delimiter option from char to string
*******************************************************************************/ *******************************************************************************/
/* /*
...@@ -61,7 +62,7 @@ void usage() ...@@ -61,7 +62,7 @@ void usage()
printf(" --host <hostname> (default is localhost)\n"); printf(" --host <hostname> (default is localhost)\n");
printf(" --port <port> (default is 1883)\n"); printf(" --port <port> (default is 1883)\n");
printf(" --qos <qos> (default is 2)\n"); printf(" --qos <qos> (default is 2)\n");
printf(" --delimiter <delim> (default is no delimiter)\n"); printf(" --delimiter <delim> (default is \\n)\n");
printf(" --clientid <clientid> (default is hostname+timestamp)\n"); printf(" --clientid <clientid> (default is hostname+timestamp)\n");
printf(" --username none\n"); printf(" --username none\n");
printf(" --password none\n"); printf(" --password none\n");
...@@ -92,7 +93,7 @@ struct opts_struct ...@@ -92,7 +93,7 @@ struct opts_struct
{ {
char* clientid; char* clientid;
int nodelimiter; int nodelimiter;
char delimiter; char* delimiter;
int qos; int qos;
char* username; char* username;
char* password; char* password;
...@@ -101,7 +102,7 @@ struct opts_struct ...@@ -101,7 +102,7 @@ struct opts_struct
int showtopics; int showtopics;
} opts = } opts =
{ {
"stdout-subscriber", 1, '\n', 2, NULL, NULL, "localhost", "1883", 0 "stdout-subscriber", 0, "\n", 2, NULL, NULL, "localhost", "1883", 0
}; };
void getopts(int argc, char** argv); void getopts(int argc, char** argv);
...@@ -156,7 +157,7 @@ int main(int argc, char** argv) ...@@ -156,7 +157,7 @@ int main(int argc, char** argv)
if (opts.nodelimiter) if (opts.nodelimiter)
printf("%.*s", message->payloadlen, (char*)message->payload); printf("%.*s", message->payloadlen, (char*)message->payload);
else else
printf("%.*s%c", message->payloadlen, (char*)message->payload, opts.delimiter); printf("%.*s%s", message->payloadlen, (char*)message->payload, opts.delimiter);
fflush(stdout); fflush(stdout);
MQTTClient_freeMessage(&message); MQTTClient_freeMessage(&message);
MQTTClient_free(topicName); MQTTClient_free(topicName);
...@@ -234,15 +235,9 @@ void getopts(int argc, char** argv) ...@@ -234,15 +235,9 @@ void getopts(int argc, char** argv)
else if (strcmp(argv[count], "--delimiter") == 0) else if (strcmp(argv[count], "--delimiter") == 0)
{ {
if (++count < argc) if (++count < argc)
{ opts.delimiter = argv[count];
if (strcmp("newline", argv[count]) == 0)
opts.delimiter = '\n';
else
opts.delimiter = argv[count][0];
opts.nodelimiter = 0;
}
else else
usage(); opts.nodelimiter = 1;
} }
else if (strcmp(argv[count], "--showtopics") == 0) else if (strcmp(argv[count], "--showtopics") == 0)
{ {
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <MQTTClientPersistence.h> #include <MQTTClientPersistence.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <sys/time.h>
#if defined(WIN32) #if defined(WIN32)
#include <Windows.h> #include <Windows.h>
...@@ -150,7 +151,7 @@ ...@@ -150,7 +151,7 @@
void onSend(void* context, MQTTAsync_successData* response) void onSend(void* context, MQTTAsync_successData* response)
{ {
static int last_send = 0; static last_send = 0;
if (response->token - last_send != 1) if (response->token - last_send != 1)
printf("Error in onSend, token value %d, last_send %d\n", response->token, last_send); printf("Error in onSend, token value %d, last_send %d\n", response->token, last_send);
...@@ -234,7 +235,6 @@ void handleTrace(enum MQTTASYNC_TRACE_LEVELS level, char* message) ...@@ -234,7 +235,6 @@ void handleTrace(enum MQTTASYNC_TRACE_LEVELS level, char* message)
MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
MQTTAsync_message pubmsg = MQTTAsync_message_initializer; MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
MQTTAsync_token token; MQTTAsync_token token;
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
signal(SIGINT, handleSignal); signal(SIGINT, handleSignal);
signal(SIGTERM, handleSignal); signal(SIGTERM, handleSignal);
...@@ -339,9 +339,10 @@ void handleTrace(enum MQTTASYNC_TRACE_LEVELS level, char* message) ...@@ -339,9 +339,10 @@ void handleTrace(enum MQTTASYNC_TRACE_LEVELS level, char* message)
printf("Waiting for connect\n"); printf("Waiting for connect\n");
while (connected == 0 && finished == 0 && toStop == 0) { while (connected == 0 && finished == 0 && toStop == 0) {
printf("Waiting for connect: %d %d %d\n", connected, finished, toStop); printf("Waiting for connect: %d %d %d\n", connected, finished, toStop);
Sleep(1); usleep(10000L);
} }
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
printf("Waiting for connect: %d %d %d\n", connected, finished, toStop); printf("Waiting for connect: %d %d %d\n", connected, finished, toStop);
printf("Successful connection\n"); printf("Successful connection\n");
...@@ -350,8 +351,8 @@ void handleTrace(enum MQTTASYNC_TRACE_LEVELS level, char* message) ...@@ -350,8 +351,8 @@ void handleTrace(enum MQTTASYNC_TRACE_LEVELS level, char* message)
{ {
unsigned long i; unsigned long i;
struct timeval tv; struct timeval tv;
//gettimeofday(&tv,NULL); gettimeofday(&tv,NULL);
//printf("start seconds : %ld\n",tv.tv_sec); printf("start seconds : %ld\n",tv.tv_sec);
for (i = 0; i < options.message_count; i++) for (i = 0; i < options.message_count; i++)
{ {
opts.onSuccess = onSend; opts.onSuccess = onSend;
...@@ -362,7 +363,7 @@ void handleTrace(enum MQTTASYNC_TRACE_LEVELS level, char* message) ...@@ -362,7 +363,7 @@ void handleTrace(enum MQTTASYNC_TRACE_LEVELS level, char* message)
pubmsg.qos = options.qos; pubmsg.qos = options.qos;
pubmsg.retained = 0; pubmsg.retained = 0;
deliveredtoken = 0; deliveredtoken = 0;
Sleep(1); usleep(100);
if ((rc = MQTTAsync_sendMessage(client, options.topic, &pubmsg, &opts)) if ((rc = MQTTAsync_sendMessage(client, options.topic, &pubmsg, &opts))
!= MQTTASYNC_SUCCESS) != MQTTASYNC_SUCCESS)
...@@ -372,9 +373,9 @@ void handleTrace(enum MQTTASYNC_TRACE_LEVELS level, char* message) ...@@ -372,9 +373,9 @@ void handleTrace(enum MQTTASYNC_TRACE_LEVELS level, char* message)
} }
} }
//gettimeofday(&tv,NULL); gettimeofday(&tv,NULL);
//printf("end seconds : %ld\n",tv.tv_sec); printf("end seconds : %ld\n",tv.tv_sec);
} else if (strcmp(options.action, "subscribe") == 0) { } else if (strcmp(options.action, "subscribe") == 0) {
opts.onSuccess = onSubscribe; opts.onSuccess = onSubscribe;
opts.onFailure = onSubscribeFailure; opts.onFailure = onSubscribeFailure;
......
-----BEGIN CERTIFICATE-----
MIICnTCCAgagAwIBAgIBATANBgkqhkiG9w0BAQUFADByMQswCQYDVQQGEwJHQjET
MBEGA1UECAwKRGVyYnlzaGlyZTEOMAwGA1UEBwwFRGVyYnkxGjAYBgNVBAoMEU1v
c3F1aXR0byBQcm9qZWN0MRAwDgYDVQQLDAdUZXN0aW5nMRAwDgYDVQQDDAdSb290
IENBMB4XDTEzMDcyNDIzNTExNloXDTE4MDcyMzIzNTExNlowZTELMAkGA1UEBhMC
R0IxEzARBgNVBAgMCkRlcmJ5c2hpcmUxGjAYBgNVBAoMEU1vc3F1aXR0byBQcm9q
ZWN0MRAwDgYDVQQLDAdUZXN0aW5nMRMwEQYDVQQDDApTaWduaW5nIENBMIGfMA0G
CSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1Sir65IBDbm7bI4lHDakEoN0Y6DUg/Spz
FoPe4cbixwS1pg3514X2srv9w03Kzp/obDOs/JzbqcPfOBAuiiPlMm1hw9az1B7N
9lg/2DKHL/7Oq8IZUKsFjhbFAMjQd/PAZCkBO1FS1Y0jZes4/1fzlqq4rYItTie+
YX8tTDc/7QIDAQABo1AwTjAdBgNVHQ4EFgQU5W621SksDwZxSpsZsFkm6/QuAQYw
HwYDVR0jBBgwFoAUq92KK7UYT6V7F1mySt6+LWTPzr4wDAYDVR0TBAUwAwEB/zAN
BgkqhkiG9w0BAQUFAAOBgQBMcwdjElUOhXqoqlX1DWik58X73GHxjE52jao4BHRZ
S+PpwOOjfnq4CfIXF1cMp95cK+Eh566lEJf2udlV1waKew578T86+UsRO/T/a0bb
3FuuZH3TXnO+OjNMTWKMZ0iLQtPwNN4m9lszECrSgJ53yCIB6iq/zfXVSop7XFzd
VQ==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICqDCCAhGgAwIBAgIJAKrzwmdXIUxsMA0GCSqGSIb3DQEBBQUAMG0xCzAJBgNV
BAYTAkdCMRMwEQYDVQQIDApEZXJieXNoaXJlMQ4wDAYDVQQHDAVEZXJieTEVMBMG
A1UECgwMUGFobyBQcm9qZWN0MRAwDgYDVQQLDAdUZXN0aW5nMRAwDgYDVQQDDAdS
b290IENBMB4XDTEzMDcyOTE5MjEyOVoXDTIzMDcyNzE5MjEyOVowbTELMAkGA1UE
BhMCR0IxEzARBgNVBAgMCkRlcmJ5c2hpcmUxDjAMBgNVBAcMBURlcmJ5MRUwEwYD
VQQKDAxQYWhvIFByb2plY3QxEDAOBgNVBAsMB1Rlc3RpbmcxEDAOBgNVBAMMB1Jv
b3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKbPzEEWCKsjjwjJ787u
Q32k5EdqoDddMEjSVbZNSNEwUew1L7O8NTbmtCEeVFQjOLAdmdiF3rQbXHV+Zew0
jt2g4vtPpl1GOG6jA/6YznKAyQdvGCdYfGZUN2tN+mbtVxWqkHZitQDQGaSHnx24
NX649La2uyFy+7l9o8++xPONAgMBAAGjUDBOMB0GA1UdDgQWBBRKK2nWMR2jaOhG
b/tL8462jVEOvzAfBgNVHSMEGDAWgBRKK2nWMR2jaOhGb/tL8462jVEOvzAMBgNV
HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAEd+gW86/W+fisz5PFHAeEw7zn9q
dzLHm7+QZgNLZ9h7/ZbhObRUFMRtU2xm4amyh85h7hUE5R2E2uW2OXumic7/D4ZD
6unjr4m5jwVWDTqTUYIcNSriyoDWAVlPfOWaU5NyUhqS1DM28tvOWVHVLCxmVcZl
tJQqo5eHbQ/+Hjfx
-----END CERTIFICATE-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=GB, ST=Derbyshire, L=Derby, O=Mosquitto Project, OU=Testing, CN=Root CA
Validity
Not Before: Jul 24 23:51:16 2013 GMT
Not After : Jul 23 23:51:16 2018 GMT
Subject: C=GB, ST=Derbyshire, O=Mosquitto Project, OU=Testing, CN=Signing CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (1024 bit)
Modulus:
00:b5:4a:2a:fa:e4:80:43:6e:6e:db:23:89:47:0d:
a9:04:a0:dd:18:e8:35:20:fd:2a:73:16:83:de:e1:
c6:e2:c7:04:b5:a6:0d:f9:d7:85:f6:b2:bb:fd:c3:
4d:ca:ce:9f:e8:6c:33:ac:fc:9c:db:a9:c3:df:38:
10:2e:8a:23:e5:32:6d:61:c3:d6:b3:d4:1e:cd:f6:
58:3f:d8:32:87:2f:fe:ce:ab:c2:19:50:ab:05:8e:
16:c5:00:c8:d0:77:f3:c0:64:29:01:3b:51:52:d5:
8d:23:65:eb:38:ff:57:f3:96:aa:b8:ad:82:2d:4e:
27:be:61:7f:2d:4c:37:3f:ed
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
E5:6E:B6:D5:29:2C:0F:06:71:4A:9B:19:B0:59:26:EB:F4:2E:01:06
X509v3 Authority Key Identifier:
keyid:AB:DD:8A:2B:B5:18:4F:A5:7B:17:59:B2:4A:DE:BE:2D:64:CF:CE:BE
X509v3 Basic Constraints:
CA:TRUE
Signature Algorithm: sha1WithRSAEncryption
4c:73:07:63:12:55:0e:85:7a:a8:aa:55:f5:0d:68:a4:e7:c5:
fb:dc:61:f1:8c:4e:76:8d:aa:38:04:74:59:4b:e3:e9:c0:e3:
a3:7e:7a:b8:09:f2:17:17:57:0c:a7:de:5c:2b:e1:21:e7:ae:
a5:10:97:f6:b9:d9:55:d7:06:8a:7b:0e:7b:f1:3f:3a:f9:4b:
11:3b:f4:ff:6b:46:db:dc:5b:ae:64:7d:d3:5e:73:be:3a:33:
4c:4d:62:8c:67:48:8b:42:d3:f0:34:de:26:f6:5b:33:10:2a:
d2:80:9e:77:c8:22:01:ea:2a:bf:cd:f5:d5:4a:8a:7b:5c:5c:
dd:55
-----BEGIN CERTIFICATE-----
MIICnTCCAgagAwIBAgIBATANBgkqhkiG9w0BAQUFADByMQswCQYDVQQGEwJHQjET
MBEGA1UECAwKRGVyYnlzaGlyZTEOMAwGA1UEBwwFRGVyYnkxGjAYBgNVBAoMEU1v
c3F1aXR0byBQcm9qZWN0MRAwDgYDVQQLDAdUZXN0aW5nMRAwDgYDVQQDDAdSb290
IENBMB4XDTEzMDcyNDIzNTExNloXDTE4MDcyMzIzNTExNlowZTELMAkGA1UEBhMC
R0IxEzARBgNVBAgMCkRlcmJ5c2hpcmUxGjAYBgNVBAoMEU1vc3F1aXR0byBQcm9q
ZWN0MRAwDgYDVQQLDAdUZXN0aW5nMRMwEQYDVQQDDApTaWduaW5nIENBMIGfMA0G
CSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1Sir65IBDbm7bI4lHDakEoN0Y6DUg/Spz
FoPe4cbixwS1pg3514X2srv9w03Kzp/obDOs/JzbqcPfOBAuiiPlMm1hw9az1B7N
9lg/2DKHL/7Oq8IZUKsFjhbFAMjQd/PAZCkBO1FS1Y0jZes4/1fzlqq4rYItTie+
YX8tTDc/7QIDAQABo1AwTjAdBgNVHQ4EFgQU5W621SksDwZxSpsZsFkm6/QuAQYw
HwYDVR0jBBgwFoAUq92KK7UYT6V7F1mySt6+LWTPzr4wDAYDVR0TBAUwAwEB/zAN
BgkqhkiG9w0BAQUFAAOBgQBMcwdjElUOhXqoqlX1DWik58X73GHxjE52jao4BHRZ
S+PpwOOjfnq4CfIXF1cMp95cK+Eh566lEJf2udlV1waKew578T86+UsRO/T/a0bb
3FuuZH3TXnO+OjNMTWKMZ0iLQtPwNN4m9lszECrSgJ53yCIB6iq/zfXVSop7XFzd
VQ==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICnTCCAgagAwIBAgIBATANBgkqhkiG9w0BAQUFADByMQswCQYDVQQGEwJHQjET
MBEGA1UECAwKRGVyYnlzaGlyZTEOMAwGA1UEBwwFRGVyYnkxGjAYBgNVBAoMEU1v
c3F1aXR0byBQcm9qZWN0MRAwDgYDVQQLDAdUZXN0aW5nMRAwDgYDVQQDDAdSb290
IENBMB4XDTEzMDcyNDIzNTExNloXDTE4MDcyMzIzNTExNlowZTELMAkGA1UEBhMC
R0IxEzARBgNVBAgMCkRlcmJ5c2hpcmUxGjAYBgNVBAoMEU1vc3F1aXR0byBQcm9q
ZWN0MRAwDgYDVQQLDAdUZXN0aW5nMRMwEQYDVQQDDApTaWduaW5nIENBMIGfMA0G
CSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1Sir65IBDbm7bI4lHDakEoN0Y6DUg/Spz
FoPe4cbixwS1pg3514X2srv9w03Kzp/obDOs/JzbqcPfOBAuiiPlMm1hw9az1B7N
9lg/2DKHL/7Oq8IZUKsFjhbFAMjQd/PAZCkBO1FS1Y0jZes4/1fzlqq4rYItTie+
YX8tTDc/7QIDAQABo1AwTjAdBgNVHQ4EFgQU5W621SksDwZxSpsZsFkm6/QuAQYw
HwYDVR0jBBgwFoAUq92KK7UYT6V7F1mySt6+LWTPzr4wDAYDVR0TBAUwAwEB/zAN
BgkqhkiG9w0BAQUFAAOBgQBMcwdjElUOhXqoqlX1DWik58X73GHxjE52jao4BHRZ
S+PpwOOjfnq4CfIXF1cMp95cK+Eh566lEJf2udlV1waKew578T86+UsRO/T/a0bb
3FuuZH3TXnO+OjNMTWKMZ0iLQtPwNN4m9lszECrSgJ53yCIB6iq/zfXVSop7XFzd
VQ==
-----END CERTIFICATE-----
# This file generates the keys and certificates used for testing mosquitto.
# None of the keys are encrypted, so do not just use this script to generate
# files for your own use.
rm -f *.crt *.key *.csr
for a in root signing; do
rm -rf ${a}CA/
mkdir -p ${a}CA/newcerts
touch ${a}CA/index.txt
echo 01 > ${a}CA/serial
echo 01 > ${a}CA/crlnumber
done
rm -rf certs
BASESUBJ="/C=GB/ST=Derbyshire/L=Derby/O=Mosquitto Project/OU=Testing"
SBASESUBJ="/C=GB/ST=Nottinghamshire/L=Nottingham/O=Server/OU=Production"
BBASESUBJ="/C=GB/ST=Nottinghamshire/L=Nottingham/O=Server/OU=Bridge"
# The root CA
openssl genrsa -out test-root-ca.key 1024
openssl req -new -x509 -days 3650 -key test-root-ca.key -out test-root-ca.crt -config openssl.cnf -subj "${BASESUBJ}/CN=Root CA/"
# Another root CA that doesn't sign anything
openssl genrsa -out test-bad-root-ca.key 1024
openssl req -new -x509 -days 3650 -key test-bad-root-ca.key -out test-bad-root-ca.crt -config openssl.cnf -subj "${BASESUBJ}/CN=Bad Root CA/"
# This is a root CA that has the exact same details as the real root CA, but is a different key and certificate. Effectively a "fake" CA.
openssl genrsa -out test-fake-root-ca.key 1024
openssl req -new -x509 -days 3650 -key test-fake-root-ca.key -out test-fake-root-ca.crt -config openssl.cnf -subj "${BASESUBJ}/CN=Root CA/"
# An intermediate CA, signed by the root CA, used to sign server/client csrs.
openssl genrsa -out test-signing-ca.key 1024
openssl req -out test-signing-ca.csr -key test-signing-ca.key -new -config openssl.cnf -subj "${BASESUBJ}/CN=Signing CA/"
openssl ca -config openssl.cnf -name CA_root -extensions v3_ca -out test-signing-ca.crt -infiles test-signing-ca.csr
# An alternative intermediate CA, signed by the root CA, not used to sign anything.
openssl genrsa -out test-alt-ca.key 1024
openssl req -out test-alt-ca.csr -key test-alt-ca.key -new -config openssl.cnf -subj "${BASESUBJ}/CN=Alternative Signing CA/"
openssl ca -config openssl.cnf -name CA_root -extensions v3_ca -out test-alt-ca.crt -infiles test-alt-ca.csr
# Valid server key and certificate.
openssl genrsa -out server.key 1024
openssl req -new -key server.key -out server.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=localhost/"
openssl ca -config openssl.cnf -name CA_signing -out server.crt -infiles server.csr
# Expired server certificate, based on the above server key.
openssl req -new -days 1 -key server.key -out server-expired.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=localhost/"
openssl ca -config openssl.cnf -name CA_signing -days 1 -startdate 120820000000Z -enddate 120821000000Z -out server-expired.crt -infiles server-expired.csr
# Valid client key and certificate.
openssl genrsa -out client.key 1024
openssl req -new -key client.key -out client.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=test client/"
openssl ca -config openssl.cnf -name CA_signing -out client.crt -infiles client.csr
# Expired client certificate, based on the above client key.
openssl req -new -days 1 -key client.key -out client-expired.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=test client expired/"
openssl ca -config openssl.cnf -name CA_signing -days 1 -startdate 120820000000Z -enddate 120821000000Z -out client-expired.crt -infiles client-expired.csr
# Revoked client certificate, based on a new client key.
openssl genrsa -out client-revoked.key 1024
openssl req -new -days 1 -key client-revoked.key -out client-revoked.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=test client revoked/"
openssl ca -config openssl.cnf -name CA_signing -out client-revoked.crt -infiles client-revoked.csr
openssl ca -config openssl.cnf -name CA_signing -revoke client-revoked.crt
openssl ca -config openssl.cnf -name CA_signing -gencrl -out crl.pem
cat test-signing-ca.crt test-root-ca.crt > all-ca.crt
#mkdir certs
#cp test-signing-ca.crt certs/test-signing-ca.pem
#cp test-root-ca.crt certs/test-root.ca.pem
c_rehash certs
#
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#
# This definition stops the following lines choking if HOME isn't
# defined.
HOME = .
RANDFILE = $ENV::HOME/.rnd
# Extra OBJECT IDENTIFIER info:
#oid_file = $ENV::HOME/.oid
oid_section = new_oids
# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions =
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)
[ new_oids ]
# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
# Add a simple OID like this:
# testoid1=1.2.3.4
# Or use config file substitution like this:
# testoid2=${testoid1}.5.6
# Policies used by the TSA examples.
tsa_policy1 = 1.2.3.4.1
tsa_policy2 = 1.2.3.4.5.6
tsa_policy3 = 1.2.3.4.5.7
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_signing ]
dir = ./signingCA # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several ctificates with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = test-signing-ca.crt # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/crl.pem # The current CRL
private_key = test-signing-ca.key # The private key
RANDFILE = $dir/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
# Extension copying option: use with caution.
# copy_extensions = copy
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions = crl_ext
default_days = 1825 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = default # use public key default MD
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_anything
[ CA_inter ]
dir = ./interCA
certs = $dir/certs
crl_dir = $dir/crl
database = $dir/index.txt
new_certs_dir = $dir/newcerts
certificate = test-inter-ca.crt
serial = $dir/serial
crlnumber = $dir/crlnumber
crl = $dir/crl.pem
private_key = test-inter-ca.key
RANDFILE = $dir/.rand
#x509_extensions = v3_ca
x509_extensions = usr_cert
name_opt = ca_default
cert_opt = ca_default
default_days = 1825
default_crl_days = 30
default_md = default
preserve = no
policy = policy_match
unique_subject = yes
[ CA_root ]
dir = ./rootCA
certs = $dir/certs
crl_dir = $dir/crl
database = $dir/index.txt
new_certs_dir = $dir/newcerts
certificate = test-root-ca.crt
serial = $dir/serial
crlnumber = $dir/crlnumber
crl = $dir/crl.pem
private_key = test-root-ca.key
RANDFILE = $dir/.rand
x509_extensions = v3_ca
name_opt = ca_default
cert_opt = ca_default
default_days = 1825
default_crl_days = 30
default_md = default
preserve = no
policy = policy_match
unique_subject = yes
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = 2048
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret
# output_password = secret
# This sets a mask for permitted string types. There are several options.
# default: PrintableString, T61String, BMPString.
# pkix : PrintableString, BMPString (PKIX recommendation before 2004)
# utf8only: only UTF8Strings (PKIX recommendation after 2004).
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
string_mask = utf8only
# req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = GB
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Derbyshire
localityName = Locality Name (eg, city)
localityName_default = Derby
0.organizationName = Organization Name (eg, company)
0.organizationName_default = Mosquitto Project
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = Testing
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 64
# SET-ex3 = SET extension number 3
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name
[ usr_cert ]
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This is required for TSA certificates.
# extendedKeyUsage = critical,timeStamping
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign
# Some might want this also
# nsCertType = sslCA, emailCA
# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy
# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints= critical, DER:30:03:01:01:FF
[ crl_ext ]
# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always
[ proxy_cert_ext ]
# These extensions should be added when creating a proxy certificate
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This really needs to be in place for it to be a proxy certificate.
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
####################################################################
[ tsa ]
default_tsa = tsa_config1 # the default TSA section
[ tsa_config1 ]
# These are used by the TSA reply generation only.
dir = ./demoCA # TSA root directory
serial = $dir/tsaserial # The current serial number (mandatory)
crypto_device = builtin # OpenSSL engine to use for signing
signer_cert = $dir/tsacert.pem # The TSA signing certificate
# (optional)
certs = $dir/cacert.pem # Certificate chain to include in reply
# (optional)
signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
default_policy = tsa_policy1 # Policy if request did not specify it
# (optional)
other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
digests = md5, sha1 # Acceptable message digests (mandatory)
accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
clock_precision_digits = 0 # number of digits after dot. (optional)
ordering = yes # Is ordering defined for timestamps?
# (optional, default: no)
tsa_name = yes # Must the TSA name be included in the reply?
# (optional, default: no)
ess_cert_id_chain = no # Must the ESS cert id chain be included?
# (optional, default: no)
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=GB, ST=Derbyshire, O=Paho Project, OU=Testing, CN=Signing CA
Validity
Not Before: Jul 29 19:21:30 2013 GMT
Not After : Jul 28 19:21:30 2018 GMT
Subject: C=GB, ST=Nottinghamshire, L=Nottingham, O=Server, OU=Production, CN=localhost
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (1024 bit)
Modulus:
00:be:b7:65:98:5e:e1:e0:68:e7:14:04:e5:40:2d:
d3:b4:f2:b2:dd:6e:5c:97:7a:5b:c5:4f:7a:45:11:
99:4e:56:30:c6:d6:50:29:88:c3:31:6d:b0:f1:a8:
5f:f5:fd:cc:d1:52:0f:40:70:04:cc:14:0d:98:45:
62:a8:f9:88:0a:be:20:32:53:c5:48:fb:b0:e4:25:
db:25:ec:0d:c4:6a:28:dc:af:d7:2d:63:99:b9:f4:
c0:32:54:dc:be:4d:9f:7f:67:7e:2a:be:82:2d:de:
37:35:0b:0d:7b:b8:9c:55:ff:cf:ab:fe:61:e9:8c:
bf:c4:27:e2:56:2f:1a:73:87
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
A1:8C:9A:D1:28:58:68:C5:46:5B:FA:C5:48:01:96:67:55:97:65:8A
X509v3 Authority Key Identifier:
keyid:29:4D:6E:C7:F2:F7:71:72:DA:27:9C:9C:AB:DA:07:1D:47:9C:D8:41
Signature Algorithm: sha1WithRSAEncryption
78:f6:a1:34:ac:2c:a5:0a:1d:82:97:97:1f:f5:03:44:a7:c0:
4d:e8:8d:67:e7:71:50:30:3c:8b:77:eb:81:96:78:6b:ab:31:
5a:ba:7b:1c:ad:ec:fd:a6:5d:73:ef:99:2d:6f:9f:7e:13:ac:
b2:61:2f:e4:56:cc:28:f1:e4:7f:ea:a9:b2:f2:85:87:68:52:
65:b0:42:54:84:92:2f:fb:45:d4:36:e2:3c:0e:4c:a6:6d:82:
8f:72:c0:66:0c:5f:b2:a7:7c:9b:be:cd:19:55:5d:40:27:99:
14:e2:cf:59:cb:4b:40:e4:98:2d:f7:93:14:4a:50:dc:75:9c:
5c:9d
-----BEGIN CERTIFICATE-----
MIICxzCCAjCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJHQjET
MBEGA1UECAwKRGVyYnlzaGlyZTEVMBMGA1UECgwMUGFobyBQcm9qZWN0MRAwDgYD
VQQLDAdUZXN0aW5nMRMwEQYDVQQDDApTaWduaW5nIENBMB4XDTEzMDcyOTE5MjEz
MFoXDTE4MDcyODE5MjEzMFowdjELMAkGA1UEBhMCR0IxGDAWBgNVBAgMD05vdHRp
bmdoYW1zaGlyZTETMBEGA1UEBwwKTm90dGluZ2hhbTEPMA0GA1UECgwGU2VydmVy
MRMwEQYDVQQLDApQcm9kdWN0aW9uMRIwEAYDVQQDDAlsb2NhbGhvc3QwgZ8wDQYJ
KoZIhvcNAQEBBQADgY0AMIGJAoGBAL63ZZhe4eBo5xQE5UAt07Tyst1uXJd6W8VP
ekURmU5WMMbWUCmIwzFtsPGoX/X9zNFSD0BwBMwUDZhFYqj5iAq+IDJTxUj7sOQl
2yXsDcRqKNyv1y1jmbn0wDJU3L5Nn39nfiq+gi3eNzULDXu4nFX/z6v+YemMv8Qn
4lYvGnOHAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5T
U0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBShjJrRKFhoxUZb+sVI
AZZnVZdlijAfBgNVHSMEGDAWgBQpTW7H8vdxctonnJyr2gcdR5zYQTANBgkqhkiG
9w0BAQUFAAOBgQB49qE0rCylCh2Cl5cf9QNEp8BN6I1n53FQMDyLd+uBlnhrqzFa
unscrez9pl1z75ktb59+E6yyYS/kVswo8eR/6qmy8oWHaFJlsEJUhJIv+0XUNuI8
DkymbYKPcsBmDF+yp3ybvs0ZVV1AJ5kU4s9Zy0tA5Jgt95MUSlDcdZxcnQ==
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQC+t2WYXuHgaOcUBOVALdO08rLdblyXelvFT3pFEZlOVjDG1lAp
iMMxbbDxqF/1/czRUg9AcATMFA2YRWKo+YgKviAyU8VI+7DkJdsl7A3Eaijcr9ct
Y5m59MAyVNy+TZ9/Z34qvoIt3jc1Cw17uJxV/8+r/mHpjL/EJ+JWLxpzhwIDAQAB
AoGAW1dC1UM8M1qKsc/WbHKGXreOavccaYA0y79Q9BuFrTsiiVjDc+EIe3fpsxPN
QeeYXPhMTbRY19US3cb9hahdOtPZc1zKRoloWl995v6X5XufTmgigBRUrRKG6rln
wok6PYwKQmcG+yVaOjPwiJBx+4gfGjD6qO/fhK2sWWtyneECQQDrUEiaWvQE0uli
EI34MhO3As0iYyw1qFHVck4bbFS4RT0gnhWYVeabd5mTKx1ztLlr0ykwaCf9FoMG
U2liyV/VAkEAz3t0v8vZrlpotW9CRzBQ63vYW3+d8m5Hmkvsghrfem52je6MN0oL
2Y7F3JrJh1bC9ZNgtkBF/mIQgv9jGBoP6wJASKTYRQ6fFn4mHmgN6/lJrM3olh0X
oNj9qm9HPaAL53c4j8E92XFrZ8NcXdqJlRbNx0PBC3icH727ZVCK0DxqoQJABTRn
nVgTwdfqwIJl+zsvDHky2Di/UZGKokg9SpY5/OxAdRcC1XA6E98M/5eybn6yrU5h
IrFCEDuNhnu5lKUyuQJAAiNPFWPkl4XeghyzPDA1lUYMwKPr7oEwELqS8fIq/g4K
BI10X7qlpioI4I6jA9lwlIdtR+q620UFZRlQts9nug==
-----END RSA PRIVATE KEY-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=GB, ST=Derbyshire, O=Paho Project, OU=Testing, CN=Signing CA
Validity
Not Before: Jul 29 19:21:30 2013 GMT
Not After : Jul 28 19:21:30 2018 GMT
Subject: C=GB, ST=Nottinghamshire, L=Nottingham, O=Server, OU=Production, CN=localhost
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (1024 bit)
Modulus:
00:be:b7:65:98:5e:e1:e0:68:e7:14:04:e5:40:2d:
d3:b4:f2:b2:dd:6e:5c:97:7a:5b:c5:4f:7a:45:11:
99:4e:56:30:c6:d6:50:29:88:c3:31:6d:b0:f1:a8:
5f:f5:fd:cc:d1:52:0f:40:70:04:cc:14:0d:98:45:
62:a8:f9:88:0a:be:20:32:53:c5:48:fb:b0:e4:25:
db:25:ec:0d:c4:6a:28:dc:af:d7:2d:63:99:b9:f4:
c0:32:54:dc:be:4d:9f:7f:67:7e:2a:be:82:2d:de:
37:35:0b:0d:7b:b8:9c:55:ff:cf:ab:fe:61:e9:8c:
bf:c4:27:e2:56:2f:1a:73:87
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
A1:8C:9A:D1:28:58:68:C5:46:5B:FA:C5:48:01:96:67:55:97:65:8A
X509v3 Authority Key Identifier:
keyid:29:4D:6E:C7:F2:F7:71:72:DA:27:9C:9C:AB:DA:07:1D:47:9C:D8:41
Signature Algorithm: sha1WithRSAEncryption
78:f6:a1:34:ac:2c:a5:0a:1d:82:97:97:1f:f5:03:44:a7:c0:
4d:e8:8d:67:e7:71:50:30:3c:8b:77:eb:81:96:78:6b:ab:31:
5a:ba:7b:1c:ad:ec:fd:a6:5d:73:ef:99:2d:6f:9f:7e:13:ac:
b2:61:2f:e4:56:cc:28:f1:e4:7f:ea:a9:b2:f2:85:87:68:52:
65:b0:42:54:84:92:2f:fb:45:d4:36:e2:3c:0e:4c:a6:6d:82:
8f:72:c0:66:0c:5f:b2:a7:7c:9b:be:cd:19:55:5d:40:27:99:
14:e2:cf:59:cb:4b:40:e4:98:2d:f7:93:14:4a:50:dc:75:9c:
5c:9d
-----BEGIN CERTIFICATE-----
MIICxzCCAjCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJHQjET
MBEGA1UECAwKRGVyYnlzaGlyZTEVMBMGA1UECgwMUGFobyBQcm9qZWN0MRAwDgYD
VQQLDAdUZXN0aW5nMRMwEQYDVQQDDApTaWduaW5nIENBMB4XDTEzMDcyOTE5MjEz
MFoXDTE4MDcyODE5MjEzMFowdjELMAkGA1UEBhMCR0IxGDAWBgNVBAgMD05vdHRp
bmdoYW1zaGlyZTETMBEGA1UEBwwKTm90dGluZ2hhbTEPMA0GA1UECgwGU2VydmVy
MRMwEQYDVQQLDApQcm9kdWN0aW9uMRIwEAYDVQQDDAlsb2NhbGhvc3QwgZ8wDQYJ
KoZIhvcNAQEBBQADgY0AMIGJAoGBAL63ZZhe4eBo5xQE5UAt07Tyst1uXJd6W8VP
ekURmU5WMMbWUCmIwzFtsPGoX/X9zNFSD0BwBMwUDZhFYqj5iAq+IDJTxUj7sOQl
2yXsDcRqKNyv1y1jmbn0wDJU3L5Nn39nfiq+gi3eNzULDXu4nFX/z6v+YemMv8Qn
4lYvGnOHAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5T
U0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBShjJrRKFhoxUZb+sVI
AZZnVZdlijAfBgNVHSMEGDAWgBQpTW7H8vdxctonnJyr2gcdR5zYQTANBgkqhkiG
9w0BAQUFAAOBgQB49qE0rCylCh2Cl5cf9QNEp8BN6I1n53FQMDyLd+uBlnhrqzFa
unscrez9pl1z75ktb59+E6yyYS/kVswo8eR/6qmy8oWHaFJlsEJUhJIv+0XUNuI8
DkymbYKPcsBmDF+yp3ybvs0ZVV1AJ5kU4s9Zy0tA5Jgt95MUSlDcdZxcnQ==
-----END CERTIFICATE-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=GB, ST=Derbyshire, L=Derby, O=Paho Project, OU=Testing, CN=Root CA
Validity
Not Before: Jul 29 19:21:30 2013 GMT
Not After : Jul 28 19:21:30 2018 GMT
Subject: C=GB, ST=Derbyshire, O=Paho Project, OU=Testing, CN=Signing CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (1024 bit)
Modulus:
00:dc:26:78:40:ae:b2:ad:2f:26:12:0a:d5:b1:18:
80:16:d8:88:be:0b:42:ce:32:ad:12:d5:f5:78:1b:
35:28:f2:13:1b:05:09:fb:7e:d7:d9:a1:8a:0d:4a:
fe:95:37:d4:16:75:83:e4:6a:44:34:33:57:2e:49:
ba:bc:b4:cf:d0:c0:87:e0:bc:f0:60:76:14:00:d6:
eb:cb:f6:db:b3:43:f1:c8:4d:4a:0a:bb:e0:37:7c:
8e:93:1f:a0:87:68:59:fe:0c:25:40:f3:7c:fd:71:
90:55:ef:de:18:b4:08:86:c9:75:c2:99:2f:ce:12:
bf:c5:5e:cf:5f:f1:06:53:07
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
29:4D:6E:C7:F2:F7:71:72:DA:27:9C:9C:AB:DA:07:1D:47:9C:D8:41
X509v3 Authority Key Identifier:
keyid:4A:2B:69:D6:31:1D:A3:68:E8:46:6F:FB:4B:F3:8E:B6:8D:51:0E:BF
X509v3 Basic Constraints:
CA:TRUE
Signature Algorithm: sha1WithRSAEncryption
48:ec:d7:80:8a:8f:82:a6:42:b1:89:2c:b9:4b:6d:0a:37:b8:
72:19:05:de:75:80:0c:d6:41:97:b2:d7:fe:99:cb:7e:c4:0e:
77:97:09:a8:9f:87:ff:0b:de:3f:1c:dc:1e:fe:09:36:a7:f5:
54:9a:85:4e:fb:6f:27:fe:0f:29:45:61:8d:07:c6:0c:da:37:
3d:a3:69:4b:82:71:e6:24:e0:87:a6:ee:d5:87:61:dd:8f:08:
fe:33:a6:1f:ae:b2:ae:1f:d8:2c:20:c8:a6:fc:33:0e:82:68:
80:23:61:10:ad:5c:1d:80:d6:b1:5f:e4:af:66:6d:63:10:e4:
96:e4
-----BEGIN CERTIFICATE-----
MIICkzCCAfygAwIBAgIBATANBgkqhkiG9w0BAQUFADBtMQswCQYDVQQGEwJHQjET
MBEGA1UECAwKRGVyYnlzaGlyZTEOMAwGA1UEBwwFRGVyYnkxFTATBgNVBAoMDFBh
aG8gUHJvamVjdDEQMA4GA1UECwwHVGVzdGluZzEQMA4GA1UEAwwHUm9vdCBDQTAe
Fw0xMzA3MjkxOTIxMzBaFw0xODA3MjgxOTIxMzBaMGAxCzAJBgNVBAYTAkdCMRMw
EQYDVQQIDApEZXJieXNoaXJlMRUwEwYDVQQKDAxQYWhvIFByb2plY3QxEDAOBgNV
BAsMB1Rlc3RpbmcxEzARBgNVBAMMClNpZ25pbmcgQ0EwgZ8wDQYJKoZIhvcNAQEB
BQADgY0AMIGJAoGBANwmeECusq0vJhIK1bEYgBbYiL4LQs4yrRLV9XgbNSjyExsF
Cft+19mhig1K/pU31BZ1g+RqRDQzVy5Jury0z9DAh+C88GB2FADW68v227ND8chN
Sgq74Dd8jpMfoIdoWf4MJUDzfP1xkFXv3hi0CIbJdcKZL84Sv8Vez1/xBlMHAgMB
AAGjUDBOMB0GA1UdDgQWBBQpTW7H8vdxctonnJyr2gcdR5zYQTAfBgNVHSMEGDAW
gBRKK2nWMR2jaOhGb/tL8462jVEOvzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEB
BQUAA4GBAEjs14CKj4KmQrGJLLlLbQo3uHIZBd51gAzWQZey1/6Zy37EDneXCaif
h/8L3j8c3B7+CTan9VSahU77byf+DylFYY0HxgzaNz2jaUuCceYk4Iem7tWHYd2P
CP4zph+usq4f2CwgyKb8Mw6CaIAjYRCtXB2A1rFf5K9mbWMQ5Jbk
-----END CERTIFICATE-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 2 (0x2)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=GB, ST=Derbyshire, L=Derby, O=Paho Project, OU=Testing, CN=Root CA
Validity
Not Before: Jul 29 19:21:30 2013 GMT
Not After : Jul 28 19:21:30 2018 GMT
Subject: C=GB, ST=Derbyshire, O=Paho Project, OU=Testing, CN=Alternative Signing CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (1024 bit)
Modulus:
00:d3:16:c8:c3:0c:90:e5:68:3d:11:13:a7:8e:fb:
11:c5:de:aa:3f:4d:ac:95:4f:c4:c2:60:8a:df:95:
b5:db:75:04:76:42:19:5f:d9:63:0e:e4:c0:8e:db:
a5:5f:21:ec:f3:3d:a0:c1:82:8b:61:b4:1a:5b:3c:
9e:42:bd:5f:5b:b4:a8:00:8d:e1:bf:99:93:c8:45:
1f:6d:29:ab:67:f0:35:9c:48:0b:a0:a2:18:32:70:
35:5e:ea:fe:1f:33:ab:b5:85:ef:1d:2a:a9:75:60:
38:ed:3a:33:be:5d:40:89:cb:0b:b3:25:e8:e7:bc:
13:6b:62:28:1d:a7:9c:aa:99
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
3A:70:4C:5D:76:C6:B4:CF:E7:BC:4B:F4:CE:C6:B8:46:C2:95:41:9B
X509v3 Authority Key Identifier:
keyid:4A:2B:69:D6:31:1D:A3:68:E8:46:6F:FB:4B:F3:8E:B6:8D:51:0E:BF
X509v3 Basic Constraints:
CA:TRUE
Signature Algorithm: sha1WithRSAEncryption
2f:74:dd:ef:da:03:cf:14:78:ae:6f:0d:04:29:75:db:c5:a2:
c0:fd:1e:46:bf:3c:25:3c:03:3b:a6:f4:f1:3a:89:54:83:e9:
3a:0f:d7:81:9a:8d:7f:2d:6b:b1:ca:17:7f:ef:93:18:c4:68:
b8:b2:1d:d2:9c:d9:9f:66:9d:18:25:18:b4:4f:72:bf:24:c5:
0c:2d:fc:cf:ad:c8:ff:25:f1:36:12:72:b4:46:e1:c9:17:19:
c5:1e:f5:26:8a:ae:33:5f:69:16:6f:62:ce:fc:ba:c3:a3:c5:
50:a3:a5:42:a9:02:6a:25:77:90:3e:e3:b7:e5:ac:7f:3f:bb:
1c:17
-----BEGIN CERTIFICATE-----
MIICnzCCAgigAwIBAgIBAjANBgkqhkiG9w0BAQUFADBtMQswCQYDVQQGEwJHQjET
MBEGA1UECAwKRGVyYnlzaGlyZTEOMAwGA1UEBwwFRGVyYnkxFTATBgNVBAoMDFBh
aG8gUHJvamVjdDEQMA4GA1UECwwHVGVzdGluZzEQMA4GA1UEAwwHUm9vdCBDQTAe
Fw0xMzA3MjkxOTIxMzBaFw0xODA3MjgxOTIxMzBaMGwxCzAJBgNVBAYTAkdCMRMw
EQYDVQQIDApEZXJieXNoaXJlMRUwEwYDVQQKDAxQYWhvIFByb2plY3QxEDAOBgNV
BAsMB1Rlc3RpbmcxHzAdBgNVBAMMFkFsdGVybmF0aXZlIFNpZ25pbmcgQ0EwgZ8w
DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANMWyMMMkOVoPRETp477EcXeqj9NrJVP
xMJgit+Vtdt1BHZCGV/ZYw7kwI7bpV8h7PM9oMGCi2G0Gls8nkK9X1u0qACN4b+Z
k8hFH20pq2fwNZxIC6CiGDJwNV7q/h8zq7WF7x0qqXVgOO06M75dQInLC7Ml6Oe8
E2tiKB2nnKqZAgMBAAGjUDBOMB0GA1UdDgQWBBQ6cExddsa0z+e8S/TOxrhGwpVB
mzAfBgNVHSMEGDAWgBRKK2nWMR2jaOhGb/tL8462jVEOvzAMBgNVHRMEBTADAQH/
MA0GCSqGSIb3DQEBBQUAA4GBAC903e/aA88UeK5vDQQpddvFosD9Hka/PCU8Azum
9PE6iVSD6ToP14GajX8ta7HKF3/vkxjEaLiyHdKc2Z9mnRglGLRPcr8kxQwt/M+t
yP8l8TYScrRG4ckXGcUe9SaKrjNfaRZvYs78usOjxVCjpUKpAmold5A+47flrH8/
uxwX
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDTFsjDDJDlaD0RE6eO+xHF3qo/TayVT8TCYIrflbXbdQR2Qhlf
2WMO5MCO26VfIezzPaDBgothtBpbPJ5CvV9btKgAjeG/mZPIRR9tKatn8DWcSAug
ohgycDVe6v4fM6u1he8dKql1YDjtOjO+XUCJywuzJejnvBNrYigdp5yqmQIDAQAB
AoGAFaQtWwnrxQlF0X1hXWBSNyYX8DuHaRtvgboiIsAXj/NUTMeEEHaaGEnNkBfm
wXUZ9OoplA1NOuwbE6WIWDFQGEgma/yLBdy4HYxQpAbJ1qnR7DyoxQ8NHPhBH+cW
GI92g7NqDEphdoHrWYy5YZYCFVr3pTHXbxlBn/VTLBsQnIECQQDr9BcQxEnPfi6e
Kk8cenA/54tGl7Ewpklb8XBrQrm/djfOAFt+CTMexerBv7BnfgriAg5wtlHtTkpK
BLLULE3pAkEA5QXmZ2WvGl0kvgBYGdiOZAruMobOVxxVxF05gvh8Sw6fNj8pI9pn
sbzyFZWIjcuDBfTLx+GVvkhqtQhs6ZYZMQJBAOSfjR3c45veKrNsUV1Jsavp4cST
xMdbyCcDaSc07x/6HxZGuGAF7/d4VABJiVauBUN6NJ23uuhR/J99r/zvtMkCQCQe
qhfkkZk213Sf2UU6QjrE/ow5dpGGhoBRs6BUUEYGKFYF4BcnevMtOYDt9HtofWGT
GhCMI3G/OhUTHxo38gECQG0nSN+QQ4tddHcktz1rnfwbnmTuNloZLC4ahR67lz75
uP42Ct0dXPjzakzDCGI2CgNk5QGk/IUO6fq4mYVxqRI=
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIICsDCCAhmgAwIBAgIJANKB0fFTAhRpMA0GCSqGSIb3DQEBBQUAMHExCzAJBgNV
BAYTAkdCMRMwEQYDVQQIDApEZXJieXNoaXJlMQ4wDAYDVQQHDAVEZXJieTEVMBMG
A1UECgwMUGFobyBQcm9qZWN0MRAwDgYDVQQLDAdUZXN0aW5nMRQwEgYDVQQDDAtC
YWQgUm9vdCBDQTAeFw0xMzA3MjkxOTIxMjlaFw0yMzA3MjcxOTIxMjlaMHExCzAJ
BgNVBAYTAkdCMRMwEQYDVQQIDApEZXJieXNoaXJlMQ4wDAYDVQQHDAVEZXJieTEV
MBMGA1UECgwMUGFobyBQcm9qZWN0MRAwDgYDVQQLDAdUZXN0aW5nMRQwEgYDVQQD
DAtCYWQgUm9vdCBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA6+nf2D7S
IP42qMVmfAEpKZw22qF0mLVjjL22bWVHwwE1CS5euzD/gBM7i0u7hvFgbvI13Yq4
Du2ebfjv3n4TAIIQg+UOAY5NbzfUG0A+50J6tPpNtnTij3KXskhQRAlvjDSd3TlU
UiONY2HMwaU56ktqXZzZE7prU0RICZ+DK8cCAwEAAaNQME4wHQYDVR0OBBYEFH/5
0qkqiFd2x/lspeK61TO4PGF1MB8GA1UdIwQYMBaAFH/50qkqiFd2x/lspeK61TO4
PGF1MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEARtsgIzT+IVRJHYT1
wP7C2PuXxbRXFG8a0qqGaA0f4SuICq7NvC3bF5l9zDh4yMvftj8keTiOIa3+alw3
ucdTz25Jaq/ZER/c68cklMPqcgdwcb/RbxpY5t3PittU2J5wAn/MmFfRiqbsxhgW
hkYbAtnqBXzJ8HdN/HmIyFW7+q4=
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDr6d/YPtIg/jaoxWZ8ASkpnDbaoXSYtWOMvbZtZUfDATUJLl67
MP+AEzuLS7uG8WBu8jXdirgO7Z5t+O/efhMAghCD5Q4Bjk1vN9QbQD7nQnq0+k22
dOKPcpeySFBECW+MNJ3dOVRSI41jYczBpTnqS2pdnNkTumtTREgJn4MrxwIDAQAB
AoGBAJk4o/bqDkX5dfy1gPOHOXnaCNKEzJqmLMrrKIHypuIjdZPJ9yLzFu7TDvhQ
rrJdMTm9vHhwMU0Yza41YW2LSsDpeCI0RkpMxG+Aqaxz+kRYPzwDFFI6YAX0NWpS
O9iie9+sDp0MfOwPlDwtY9T7OegrPH/ngtxWxFp7R0YxVLQJAkEA+Or0TgAklxy/
2LQV27OPFXc0ejYf67hLNdOC66PhTCO18avjEpDEeA00vF5DkqT+VXJVz2XyXX97
+cCAf3sYhQJBAPKgM3pmHrhMxr+qgyqiTiKD42kASWLDGEDP0EP4tVaZNdwWH2XG
tSanhf6eOdoHlq0+3c3tIDwJZ+uCr21ACtsCQAiUeLVTle9Lg2Vh17sJ9m2j/UAV
K4aBhL4nO0UKEhMAzB23cg1KxirpMZ8olKWyYD3rwf9zISaN5WUXeJZsVM0CQQC5
GEhNb0yuUzwoil+ojcvH/w/lUeeqZaXCBAghYsKMvzNcpK/tSAt44sKRfYoq8DEe
F+DEscsuogpanAdS9FGTAkAt8POChqwkCSjXQ9TlPQhdL4bRcENBQz6xp9TEOYT+
M+FFifLj/ke8sRWXjrar1k45u8VWJJmd/0gmsUSiWoaS
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIICqDCCAhGgAwIBAgIJALWM56dkMt5jMA0GCSqGSIb3DQEBBQUAMG0xCzAJBgNV
BAYTAkdCMRMwEQYDVQQIDApEZXJieXNoaXJlMQ4wDAYDVQQHDAVEZXJieTEVMBMG
A1UECgwMUGFobyBQcm9qZWN0MRAwDgYDVQQLDAdUZXN0aW5nMRAwDgYDVQQDDAdS
b290IENBMB4XDTEzMDcyOTE5MjEzMFoXDTIzMDcyNzE5MjEzMFowbTELMAkGA1UE
BhMCR0IxEzARBgNVBAgMCkRlcmJ5c2hpcmUxDjAMBgNVBAcMBURlcmJ5MRUwEwYD
VQQKDAxQYWhvIFByb2plY3QxEDAOBgNVBAsMB1Rlc3RpbmcxEDAOBgNVBAMMB1Jv
b3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOpNNgRF6qhcGxndkPFE
1uZVQZ2x9GV3UlARuTnG89MX+6W+fXQ0gfdcbKs1/puhFqvrcqrWmoIgRtM/lZR/
YDs5EXfpb13V5pDDn8X7AD2+poUb9eHxcB6fKuRbyt1PsS42umwUlpIDtK6p6H8/
ZfxSiOE73kyY6CUvJfTC4WHrAgMBAAGjUDBOMB0GA1UdDgQWBBSXmasVth7iUHhF
8MDaBnSIGBV4qzAfBgNVHSMEGDAWgBSXmasVth7iUHhF8MDaBnSIGBV4qzAMBgNV
HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBANAYCcz14fk3Y+9CBMm/kitCWAkI
Ia54KL0A8ynqrLHssO3Ilq+wb10vSNLxhsdws3zNAfXteFxOvGm24Yu+8oTBQ26K
QfTp/cH9yoF97ONMxg7rqANOJeYv0BeJdDcgjCMgmql5ETEz2cf9tTWBUAtd1ZZC
YPS5aiNsetk+XuS9
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDqTTYEReqoXBsZ3ZDxRNbmVUGdsfRld1JQEbk5xvPTF/ulvn10
NIH3XGyrNf6boRar63Kq1pqCIEbTP5WUf2A7ORF36W9d1eaQw5/F+wA9vqaFG/Xh
8XAenyrkW8rdT7EuNrpsFJaSA7Suqeh/P2X8UojhO95MmOglLyX0wuFh6wIDAQAB
AoGBAMhOUgu9Kivc8l5eiXd6fq5T3NDQPjwwknJZdJzsda7WJhFAlUgvS50Jqu2E
L7MlOJippVJgPZ9ZsLMQ/PQDIWRdLg2K9VLS4nPl3p7LzHoDmqDnMLPo9fUGBile
EnWwSSCWrz8ATyDO1ct5oJmK/S9QRxdvtw+6SbmorhnzypihAkEA+9LNpjnpuOWf
iF0TGWKhK53WPtiCBnuisXGZEZws9mzFGlfdR98sBDyekl7oHOb+JI0SDpPl3PBE
hZXcF7VPtQJBAO4wA1sxXqfYUazt6SInUTzpaNZ9xPrK0p1PgxZLxJrZV6hZByvW
FGb+cKGnOHIYq4tnCg0cyRe1xX4MJU6wrx8CQGRtNUZNYkAykuS2+Z7uDohucbqu
bWxYchGB1CGJvwSnbBONZtn6znsCEdsdrkOYe1HoUIMvyEPMLgd4NEXgMOECQF+u
y/pbR9IXVSAp5oiA0OKuRR49Id85kQf+xAM15sHp44vOT9ItSr7hIa/etA8pl+gF
OYVw9dtfevmauXX2BjMCQQCrse1jUAp3xmsXwb1JieclSh/C/FcGeo6DYpIcm9bK
RiVCmpzy3hOqYW137l5WvpUwZmN2wPvaKCacF/t75EiG
-----END RSA PRIVATE KEY-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
aa:f3:c2:67:57:21:4c:6c
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=GB, ST=Derbyshire, L=Derby, O=Paho Project, OU=Testing, CN=Root CA
Validity
Not Before: Jul 29 19:21:29 2013 GMT
Not After : Jul 27 19:21:29 2023 GMT
Subject: C=GB, ST=Derbyshire, L=Derby, O=Paho Project, OU=Testing, CN=Root CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (1024 bit)
Modulus:
00:a6:cf:cc:41:16:08:ab:23:8f:08:c9:ef:ce:ee:
43:7d:a4:e4:47:6a:a0:37:5d:30:48:d2:55:b6:4d:
48:d1:30:51:ec:35:2f:b3:bc:35:36:e6:b4:21:1e:
54:54:23:38:b0:1d:99:d8:85:de:b4:1b:5c:75:7e:
65:ec:34:8e:dd:a0:e2:fb:4f:a6:5d:46:38:6e:a3:
03:fe:98:ce:72:80:c9:07:6f:18:27:58:7c:66:54:
37:6b:4d:fa:66:ed:57:15:aa:90:76:62:b5:00:d0:
19:a4:87:9f:1d:b8:35:7e:b8:f4:b6:b6:bb:21:72:
fb:b9:7d:a3:cf:be:c4:f3:8d
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
4A:2B:69:D6:31:1D:A3:68:E8:46:6F:FB:4B:F3:8E:B6:8D:51:0E:BF
X509v3 Authority Key Identifier:
keyid:4A:2B:69:D6:31:1D:A3:68:E8:46:6F:FB:4B:F3:8E:B6:8D:51:0E:BF
X509v3 Basic Constraints:
CA:TRUE
Signature Algorithm: sha1WithRSAEncryption
47:7e:81:6f:3a:fd:6f:9f:8a:cc:f9:3c:51:c0:78:4c:3b:ce:
7f:6a:77:32:c7:9b:bf:90:66:03:4b:67:d8:7b:fd:96:e1:39:
b4:54:14:c4:6d:53:6c:66:e1:a9:b2:87:ce:61:ee:15:04:e5:
1d:84:da:e5:b6:39:7b:a6:89:ce:ff:0f:86:43:ea:e9:e3:af:
89:b9:8f:05:56:0d:3a:93:51:82:1c:35:2a:e2:ca:80:d6:01:
59:4f:7c:e5:9a:53:93:72:52:1a:92:d4:33:36:f2:db:ce:59:
51:d5:2c:2c:66:55:c6:65:b4:94:2a:a3:97:87:6d:0f:fe:1e:
37:f1
-----BEGIN CERTIFICATE-----
MIICqDCCAhGgAwIBAgIJAKrzwmdXIUxsMA0GCSqGSIb3DQEBBQUAMG0xCzAJBgNV
BAYTAkdCMRMwEQYDVQQIDApEZXJieXNoaXJlMQ4wDAYDVQQHDAVEZXJieTEVMBMG
A1UECgwMUGFobyBQcm9qZWN0MRAwDgYDVQQLDAdUZXN0aW5nMRAwDgYDVQQDDAdS
b290IENBMB4XDTEzMDcyOTE5MjEyOVoXDTIzMDcyNzE5MjEyOVowbTELMAkGA1UE
BhMCR0IxEzARBgNVBAgMCkRlcmJ5c2hpcmUxDjAMBgNVBAcMBURlcmJ5MRUwEwYD
VQQKDAxQYWhvIFByb2plY3QxEDAOBgNVBAsMB1Rlc3RpbmcxEDAOBgNVBAMMB1Jv
b3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKbPzEEWCKsjjwjJ787u
Q32k5EdqoDddMEjSVbZNSNEwUew1L7O8NTbmtCEeVFQjOLAdmdiF3rQbXHV+Zew0
jt2g4vtPpl1GOG6jA/6YznKAyQdvGCdYfGZUN2tN+mbtVxWqkHZitQDQGaSHnx24
NX649La2uyFy+7l9o8++xPONAgMBAAGjUDBOMB0GA1UdDgQWBBRKK2nWMR2jaOhG
b/tL8462jVEOvzAfBgNVHSMEGDAWgBRKK2nWMR2jaOhGb/tL8462jVEOvzAMBgNV
HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAEd+gW86/W+fisz5PFHAeEw7zn9q
dzLHm7+QZgNLZ9h7/ZbhObRUFMRtU2xm4amyh85h7hUE5R2E2uW2OXumic7/D4ZD
6unjr4m5jwVWDTqTUYIcNSriyoDWAVlPfOWaU5NyUhqS1DM28tvOWVHVLCxmVcZl
tJQqo5eHbQ/+Hjfx
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCmz8xBFgirI48Iye/O7kN9pORHaqA3XTBI0lW2TUjRMFHsNS+z
vDU25rQhHlRUIziwHZnYhd60G1x1fmXsNI7doOL7T6ZdRjhuowP+mM5ygMkHbxgn
WHxmVDdrTfpm7VcVqpB2YrUA0Bmkh58duDV+uPS2trshcvu5faPPvsTzjQIDAQAB
AoGAFVhNqJ5rKYr5SISefPocBL3OwByyt6LjBM51TUiCYtIuCW2c1wDkRkwrDHnX
DJUdMdv3za8DmkROBnLQE/N9vEVhrfrDpBpU6ne/0tbxRlmDi1ihH+zgBUZkIkQo
kP5kQrV6Tfv7zhFv6cZzewRjGYzTwt8xWB54bKFlsJSlj/kCQQDY0AirnfIVyK+0
mkqwYEiXWCQfkdRtbLBwpE8S/bbMQVb+Qxh8iCEdw3u1/c/GRFG/qUQ/54/Tetlx
ZWTTusuXAkEAxPY1+EyW90I8cDSBsrL+S47meut5Qp1Z/WspKjuZgozT7YnECK1k
JWyXIfBixMIqeQp+pVfVRtYSumvnVhAuewJAA3ylBw2NPShzGvZ4SQnjYPu76P4R
aoka9VTPKMEH1ZUfbwtpM2eFENN6A91HICstHWX9gQGaYI5TPO2ih30zlQJBAIRH
06FqVu3DJ3I4YW8R9eXrGHIvmaYapeikQuZhVs0uJdtf7i/hu+PClZIurzb0LLBU
UxBa+Bt2BOf9NkY/4ecCQQCYLGMiKrfckXC6VtQalLuEXkeE8spcdh/NV22Qpim5
xfir6M2ZcPDxaFpPmSDSS1TRTaeulX/djUE35EdNPVP8
-----END RSA PRIVATE KEY-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=GB, ST=Derbyshire, L=Derby, O=Paho Project, OU=Testing, CN=Root CA
Validity
Not Before: Jul 29 19:21:30 2013 GMT
Not After : Jul 28 19:21:30 2018 GMT
Subject: C=GB, ST=Derbyshire, O=Paho Project, OU=Testing, CN=Signing CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (1024 bit)
Modulus:
00:dc:26:78:40:ae:b2:ad:2f:26:12:0a:d5:b1:18:
80:16:d8:88:be:0b:42:ce:32:ad:12:d5:f5:78:1b:
35:28:f2:13:1b:05:09:fb:7e:d7:d9:a1:8a:0d:4a:
fe:95:37:d4:16:75:83:e4:6a:44:34:33:57:2e:49:
ba:bc:b4:cf:d0:c0:87:e0:bc:f0:60:76:14:00:d6:
eb:cb:f6:db:b3:43:f1:c8:4d:4a:0a:bb:e0:37:7c:
8e:93:1f:a0:87:68:59:fe:0c:25:40:f3:7c:fd:71:
90:55:ef:de:18:b4:08:86:c9:75:c2:99:2f:ce:12:
bf:c5:5e:cf:5f:f1:06:53:07
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
29:4D:6E:C7:F2:F7:71:72:DA:27:9C:9C:AB:DA:07:1D:47:9C:D8:41
X509v3 Authority Key Identifier:
keyid:4A:2B:69:D6:31:1D:A3:68:E8:46:6F:FB:4B:F3:8E:B6:8D:51:0E:BF
X509v3 Basic Constraints:
CA:TRUE
Signature Algorithm: sha1WithRSAEncryption
48:ec:d7:80:8a:8f:82:a6:42:b1:89:2c:b9:4b:6d:0a:37:b8:
72:19:05:de:75:80:0c:d6:41:97:b2:d7:fe:99:cb:7e:c4:0e:
77:97:09:a8:9f:87:ff:0b:de:3f:1c:dc:1e:fe:09:36:a7:f5:
54:9a:85:4e:fb:6f:27:fe:0f:29:45:61:8d:07:c6:0c:da:37:
3d:a3:69:4b:82:71:e6:24:e0:87:a6:ee:d5:87:61:dd:8f:08:
fe:33:a6:1f:ae:b2:ae:1f:d8:2c:20:c8:a6:fc:33:0e:82:68:
80:23:61:10:ad:5c:1d:80:d6:b1:5f:e4:af:66:6d:63:10:e4:
96:e4
-----BEGIN CERTIFICATE-----
MIICkzCCAfygAwIBAgIBATANBgkqhkiG9w0BAQUFADBtMQswCQYDVQQGEwJHQjET
MBEGA1UECAwKRGVyYnlzaGlyZTEOMAwGA1UEBwwFRGVyYnkxFTATBgNVBAoMDFBh
aG8gUHJvamVjdDEQMA4GA1UECwwHVGVzdGluZzEQMA4GA1UEAwwHUm9vdCBDQTAe
Fw0xMzA3MjkxOTIxMzBaFw0xODA3MjgxOTIxMzBaMGAxCzAJBgNVBAYTAkdCMRMw
EQYDVQQIDApEZXJieXNoaXJlMRUwEwYDVQQKDAxQYWhvIFByb2plY3QxEDAOBgNV
BAsMB1Rlc3RpbmcxEzARBgNVBAMMClNpZ25pbmcgQ0EwgZ8wDQYJKoZIhvcNAQEB
BQADgY0AMIGJAoGBANwmeECusq0vJhIK1bEYgBbYiL4LQs4yrRLV9XgbNSjyExsF
Cft+19mhig1K/pU31BZ1g+RqRDQzVy5Jury0z9DAh+C88GB2FADW68v227ND8chN
Sgq74Dd8jpMfoIdoWf4MJUDzfP1xkFXv3hi0CIbJdcKZL84Sv8Vez1/xBlMHAgMB
AAGjUDBOMB0GA1UdDgQWBBQpTW7H8vdxctonnJyr2gcdR5zYQTAfBgNVHSMEGDAW
gBRKK2nWMR2jaOhGb/tL8462jVEOvzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEB
BQUAA4GBAEjs14CKj4KmQrGJLLlLbQo3uHIZBd51gAzWQZey1/6Zy37EDneXCaif
h/8L3j8c3B7+CTan9VSahU77byf+DylFYY0HxgzaNz2jaUuCceYk4Iem7tWHYd2P
CP4zph+usq4f2CwgyKb8Mw6CaIAjYRCtXB2A1rFf5K9mbWMQ5Jbk
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDcJnhArrKtLyYSCtWxGIAW2Ii+C0LOMq0S1fV4GzUo8hMbBQn7
ftfZoYoNSv6VN9QWdYPkakQ0M1cuSbq8tM/QwIfgvPBgdhQA1uvL9tuzQ/HITUoK
u+A3fI6TH6CHaFn+DCVA83z9cZBV794YtAiGyXXCmS/OEr/FXs9f8QZTBwIDAQAB
AoGAEEMDNPvylNpbvI9yU3+Uzps2FpusVqDlqfOGC1YvKhQflypbH2myNhA5q1uz
zH/wOax6jp/O4/A6619k3NWaWBUSDeD1jczdzzDB6Eq1+6oj1szwLBA5EQHz5tuM
0BIWVGv12bqY/LGBbYsIABBTr584rA3QSgM3K4SPxKKiyYECQQD6ELRf6hfd5qhs
8RJY5f3yXaV6rSpz8meht4VwMguiYwNBHrHAHxgumMfLiJ2PWa+6aFUxcWs93RfL
5Tzn2DtHAkEA4WADib1R05V3X2XcU9ursA0va5nPEtQ0fNJAUm4iJOtEElk61Ku4
0KFokloTovpAgno+QxQdy1trwBz/ov2KQQJAaNeaGGCYUxPC57IHBDihSP1UROPX
Wbd3FYlRK+H/mLy0f5fz5F3lEJxDoCUOEi0DDT9zAIDR+qT4tibNa1LwPwJAQDtT
BtCUH487pE6tiqDSv6wiVbJSV/VuuBxcBKIqzQbYMbqIj9AZLiyyVvOhIRPditI4
KHn1O93kSa56FQPZgQJAV0mCqYciPBU4z3qtLGIDqdzTszBh4U5cTu5M+TICrg20
dtH2X0dETx7c2+7FDkr1ktVq9skJAXMw6mWM8FMYFg==
-----END RSA PRIVATE KEY-----
...@@ -222,10 +222,10 @@ void write_test_result() ...@@ -222,10 +222,10 @@ void write_test_result()
{ {
long duration = elapsed(global_start_time); long duration = elapsed(global_start_time);
fprintf(xml, " time=\"%d.%.3d\" >\n", duration / 1000, duration % 1000); fprintf(xml, " time=\"%ld.%.3ld\" >\n", duration / 1000, duration % 1000);
if (cur_output != output) if (cur_output != output)
{ {
fprintf(xml, output); fprintf(xml, "%s", output);
cur_output = output; cur_output = output;
} }
fprintf(xml, "</testcase>\n"); fprintf(xml, "</testcase>\n");
...@@ -789,10 +789,10 @@ int test4(struct Options options) ...@@ -789,10 +789,10 @@ int test4(struct Options options)
fprintf(xml, "<testcase classname=\"test1\" name=\"persistence\""); fprintf(xml, "<testcase classname=\"test1\" name=\"persistence\"");
global_start_time = start_clock(); global_start_time = start_clock();
rc = test4_run(1) + test4_run(2); rc = test4_run(1) + test4_run(2);
fprintf(xml, " time=\"%d\" >\n", elapsed(global_start_time) / 1000); fprintf(xml, " time=\"%ld\" >\n", elapsed(global_start_time) / 1000);
if (cur_output != output) if (cur_output != output)
{ {
fprintf(xml, output); fprintf(xml, "%s", output);
cur_output = output; cur_output = output;
} }
fprintf(xml, "</testcase>\n"); fprintf(xml, "</testcase>\n");
...@@ -1099,7 +1099,7 @@ int main(int argc, char** argv) ...@@ -1099,7 +1099,7 @@ int main(int argc, char** argv)
int (*tests[])() = {NULL, test1, test2, test3, test4, test5, test6}; int (*tests[])() = {NULL, test1, test2, test3, test4, test5, test6};
xml = fopen("TEST-test1.xml", "w"); xml = fopen("TEST-test1.xml", "w");
fprintf(xml, "<testsuite name=\"test1\" tests=\"%d\">\n", ARRAY_SIZE(tests) - 1); fprintf(xml, "<testsuite name=\"test1\" tests=\"%d\">\n", (int)(ARRAY_SIZE(tests) - 1));
setenv("MQTT_C_CLIENT_TRACE", "ON", 1); setenv("MQTT_C_CLIENT_TRACE", "ON", 1);
setenv("MQTT_C_CLIENT_TRACE_LEVEL", "ERROR", 1); setenv("MQTT_C_CLIENT_TRACE_LEVEL", "ERROR", 1);
......
...@@ -125,6 +125,7 @@ char* test_map[] = ...@@ -125,6 +125,7 @@ char* test_map[] =
"5c", // 13 "5c", // 13
}; };
void getopts(int argc, char** argv) void getopts(int argc, char** argv)
{ {
int count = 1; int count = 1;
...@@ -132,14 +133,13 @@ void getopts(int argc, char** argv) ...@@ -132,14 +133,13 @@ void getopts(int argc, char** argv)
while (count < argc) while (count < argc)
{ {
if (strcmp(argv[count], "--help") == 0) if (strcmp(argv[count], "--help") == 0)
{
usage(); usage();
}
else if (strcmp(argv[count], "--test_no") == 0) else if (strcmp(argv[count], "--test_no") == 0)
{ {
if (++count < argc) if (++count < argc)
{ {
int i; int i;
for (i = 1; i < ARRAY_SIZE(test_map); ++i) for (i = 1; i < ARRAY_SIZE(test_map); ++i)
{ {
if (strcmp(argv[count], test_map[i]) == 0) if (strcmp(argv[count], test_map[i]) == 0)
...@@ -358,10 +358,10 @@ void write_test_result() ...@@ -358,10 +358,10 @@ void write_test_result()
{ {
long duration = elapsed(global_start_time); long duration = elapsed(global_start_time);
fprintf(xml, " time=\"%d.%.3d\" >\n", duration / 1000, duration % 1000); fprintf(xml, " time=\"%ld.%.3ld\" >\n", duration / 1000, duration % 1000);
if (cur_output != output) if (cur_output != output)
{ {
fprintf(xml, output); fprintf(xml, "%s", output);
cur_output = output; cur_output = output;
} }
fprintf(xml, "</testcase>\n"); fprintf(xml, "</testcase>\n");
...@@ -631,7 +631,7 @@ int test2a_s(struct Options options) ...@@ -631,7 +631,7 @@ int test2a_s(struct Options options)
fprintf(xml, "<testcase classname=\"test3\" name=\"test 2a_s\""); fprintf(xml, "<testcase classname=\"test3\" name=\"test 2a_s\"");
global_start_time = start_clock(); global_start_time = start_clock();
if (!(assert("good rc from create", (rc = MQTTClient_create(&c, options.mutual_auth_connection, "test2a_s", if (!(assert("good rc from create", (rc = MQTTClient_create(&c, options.server_auth_connection, "test2a_s",
MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore)) == MQTTCLIENT_SUCCESS, "rc was %d\n", rc))) MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore)) == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
goto exit; goto exit;
...@@ -653,8 +653,6 @@ int test2a_s(struct Options options) ...@@ -653,8 +653,6 @@ int test2a_s(struct Options options)
opts.ssl->privateKeyPassword = options.client_key_pass; opts.ssl->privateKeyPassword = options.client_key_pass;
if (options.client_private_key_file) if (options.client_private_key_file)
opts.ssl->privateKey = options.client_private_key_file; opts.ssl->privateKey = options.client_private_key_file;
//opts.ssl->enabledCipherSuites = "DEFAULT";
//opts.ssl->enabledServerCertAuth = 1;
MyLog(LOGA_DEBUG, "Connecting"); MyLog(LOGA_DEBUG, "Connecting");
...@@ -1412,7 +1410,7 @@ int test5c(struct Options options) ...@@ -1412,7 +1410,7 @@ int test5c(struct Options options)
//opts.ssl->trustStore = /*file of certificates trusted by client*/ //opts.ssl->trustStore = /*file of certificates trusted by client*/
//opts.ssl->keyStore = options.client_key_file; /*file of certificate for client to present to server*/ //opts.ssl->keyStore = options.client_key_file; /*file of certificate for client to present to server*/
//if (options.client_key_pass != NULL) opts.ssl->privateKeyPassword = options.client_key_pass; //if (options.client_key_pass != NULL) opts.ssl->privateKeyPassword = options.client_key_pass;
//opts.ssl->enabledCipherSuites = "DEFAULT"; opts.ssl->enabledCipherSuites = "DEFAULT";
opts.ssl->enableServerCertAuth = 0; opts.ssl->enableServerCertAuth = 0;
MyLog(LOGA_DEBUG, "Connecting"); MyLog(LOGA_DEBUG, "Connecting");
...@@ -1475,11 +1473,11 @@ int main(int argc, char** argv) ...@@ -1475,11 +1473,11 @@ int main(int argc, char** argv)
{ {
int* numtests = &tests; int* numtests = &tests;
int rc = 0; int rc = 0;
int (*tests[])() = {NULL, test1, test2a_s, test2a_m, test2b, test2c, test3a_s, test3a_m, test3b, test4_s, test4_m, /*test5a, test5b,*/ test5c}; int (*tests[])() = {NULL, test1, test2a_s, test2a_m, test2b, test2c, test3a_s, test3a_m, test3b, test4_s, test4_m, /*test5a, test5b,test5c */};
MQTTClient_nameValue* info; MQTTClient_nameValue* info;
xml = fopen("TEST-test3.xml", "w"); xml = fopen("TEST-test3.xml", "w");
fprintf(xml, "<testsuite name=\"test3\" tests=\"%d\">\n", ARRAY_SIZE(tests) - 1); fprintf(xml, "<testsuite name=\"test3\" tests=\"%d\">\n", (int)(ARRAY_SIZE(tests) - 1));
setenv("MQTT_C_CLIENT_TRACE", "ON", 1); setenv("MQTT_C_CLIENT_TRACE", "ON", 1);
setenv("MQTT_C_CLIENT_TRACE_LEVEL", "ERROR", 1); setenv("MQTT_C_CLIENT_TRACE_LEVEL", "ERROR", 1);
......
...@@ -205,10 +205,10 @@ void write_test_result() ...@@ -205,10 +205,10 @@ void write_test_result()
{ {
long duration = elapsed(global_start_time); long duration = elapsed(global_start_time);
fprintf(xml, " time=\"%d.%.3d\" >\n", duration / 1000, duration % 1000); fprintf(xml, " time=\"%ld.%.3ld\" >\n", duration / 1000, duration % 1000);
if (cur_output != output) if (cur_output != output)
{ {
fprintf(xml, output); fprintf(xml, "%s", output);
cur_output = output; cur_output = output;
} }
fprintf(xml, "</testcase>\n"); fprintf(xml, "</testcase>\n");
...@@ -1031,7 +1031,7 @@ int test6(struct Options options) ...@@ -1031,7 +1031,7 @@ int test6(struct Options options)
test_finished = 0; test_finished = 0;
cinfo.should_fail = 1; /* fail to connect */ cinfo.should_fail = 1; /* fail to connect */
rc = MQTTAsync_create(&cinfo.c, "tcp://rubbish:1883", "async ha connection test", rc = MQTTAsync_create(&cinfo.c, "tcp://rubbish:1883", "async ha connection",
MQTTCLIENT_PERSISTENCE_DEFAULT, NULL); MQTTCLIENT_PERSISTENCE_DEFAULT, NULL);
assert("good rc from create", rc == MQTTASYNC_SUCCESS, "rc was %d\n", rc); assert("good rc from create", rc == MQTTASYNC_SUCCESS, "rc was %d\n", rc);
if (rc != MQTTASYNC_SUCCESS) if (rc != MQTTASYNC_SUCCESS)
...@@ -1063,7 +1063,7 @@ int test6(struct Options options) ...@@ -1063,7 +1063,7 @@ int test6(struct Options options)
test_finished = 0; test_finished = 0;
cinfo.should_fail = 0; /* should connect */ cinfo.should_fail = 0; /* should connect */
rc = MQTTAsync_create(&cinfo.c, "tcp://rubbish:1883", "async ha connection test", rc = MQTTAsync_create(&cinfo.c, "tcp://rubbish:1883", "async ha connection",
MQTTCLIENT_PERSISTENCE_DEFAULT, NULL); MQTTCLIENT_PERSISTENCE_DEFAULT, NULL);
assert("good rc from create", rc == MQTTASYNC_SUCCESS, "rc was %d\n", rc); assert("good rc from create", rc == MQTTASYNC_SUCCESS, "rc was %d\n", rc);
if (rc != MQTTASYNC_SUCCESS) if (rc != MQTTASYNC_SUCCESS)
...@@ -1122,7 +1122,7 @@ int main(int argc, char** argv) ...@@ -1122,7 +1122,7 @@ int main(int argc, char** argv)
MQTTAsync_nameValue* info; MQTTAsync_nameValue* info;
xml = fopen("TEST-test4.xml", "w"); xml = fopen("TEST-test4.xml", "w");
fprintf(xml, "<testsuite name=\"test4\" tests=\"%d\">\n", ARRAY_SIZE(tests) - 1); fprintf(xml, "<testsuite name=\"test4\" tests=\"%d\">\n", (int)(ARRAY_SIZE(tests)) - 1);
getopts(argc, argv); getopts(argc, argv);
......
...@@ -277,10 +277,10 @@ void write_test_result() ...@@ -277,10 +277,10 @@ void write_test_result()
{ {
long duration = elapsed(global_start_time); long duration = elapsed(global_start_time);
fprintf(xml, " time=\"%d.%.3d\" >\n", duration / 1000, duration % 1000); fprintf(xml, " time=\"%ld.%.3ld\" >\n", duration / 1000, duration % 1000);
if (cur_output != output) if (cur_output != output)
{ {
fprintf(xml, output); fprintf(xml, "%s", output);
cur_output = output; cur_output = output;
} }
fprintf(xml, "</testcase>\n"); fprintf(xml, "</testcase>\n");
...@@ -2035,10 +2035,10 @@ int main(int argc, char** argv) ...@@ -2035,10 +2035,10 @@ int main(int argc, char** argv)
int i; int i;
int (*tests[])() = int (*tests[])() =
{ NULL, test1, test2a, test2b, test2c, test3a, test3b, test4, /* test5a, { NULL, test1, test2a, test2b, test2c, test3a, test3b, test4, /* test5a,
test5b, */ test5c, test6, test7 }; test5b, test5c, */ test6, test7 };
xml = fopen("TEST-test5.xml", "w"); xml = fopen("TEST-test5.xml", "w");
fprintf(xml, "<testsuite name=\"test5\" tests=\"%d\">\n", ARRAY_SIZE(tests) - 1); fprintf(xml, "<testsuite name=\"test5\" tests=\"%lu\">\n", ARRAY_SIZE(tests) - 1);
MQTTAsync_setTraceCallback(handleTrace); MQTTAsync_setTraceCallback(handleTrace);
getopts(argc, argv); getopts(argc, argv);
......
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