Initial contribution.

This commit is contained in:
Roger Light
2014-05-07 23:27:00 +01:00
commit 0364bd1be7
372 changed files with 39627 additions and 0 deletions

39
.gitignore vendored Normal file
View File

@@ -0,0 +1,39 @@
*.o
*.exe
*.db
c/*.test
cpp/*.test
*.pyc
client/mosquitto_pub
client/mosquitto_sub
examples/mysql_log/mosquitto_mysql_log
examples/temperature_conversion/mqtt_temperature_conversion
man/mosquitto.8
man/mosquitto-tls.7
man/mosquitto.conf.5
man/libmosquitto.3
man/mosquitto_passwd.1
man/mosquitto_pub.1
man/mosquitto_sub.1
man/mqtt.7
src/db_dump/mosquitto_db_dump
src/mosquitto
src/mosquitto_passwd
test/broker/broker.pid
test/test_client
test/fake_user
test/msgsps_pub
test/msgsps_sub
test/msgsps_pub.dat
test/msgsps_sub.dat
test/broker/c/auth_plugin.so
lib/cpp/libmosquittopp.so*
lib/libmosquitto.so*
lib/libmosquitto.a
test/ssl/*.csr
build/
dist/

74
CMakeLists.txt Normal file
View File

@@ -0,0 +1,74 @@
# This is a cmake script.
set(CMAKE_LEGACY_CYGWIN_WIN32 0)
project(mosquitto)
cmake_minimum_required(VERSION 2.6)
set (VERSION 1.3.1)
if (WIN32)
execute_process(COMMAND cmd /c echo %DATE% %TIME% OUTPUT_VARIABLE TIMESTAMP
OUTPUT_STRIP_TRAILING_WHITESPACE)
else (WIN32)
execute_process(COMMAND date "+%F %T%z" OUTPUT_VARIABLE TIMESTAMP
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif (WIN32)
add_definitions (-DCMAKE -DVERSION=\"${VERSION}\" -DTIMESTAMP=\"${TIMESTAMP}\")
if (WIN32)
set (BINDIR .)
set (SBINDIR .)
set (SYSCONFDIR .)
set (LIBDIR .)
set (INCLUDEDIR include)
set (DATAROOTDIR share)
set (MANDIR man)
set (SHAREDEST .)
add_definitions("-D_CRT_SECURE_NO_WARNINGS")
else (WIN32)
set (BINDIR bin)
set (SBINDIR sbin)
if (${CMAKE_INSTALL_PREFIX} STREQUAL /usr)
set (SYSCONFDIR /etc/mosquitto)
else (${CMAKE_INSTALL_PREFIX} STREQUAL /usr)
set (SYSCONFDIR etc/mosquitto)
endif (${CMAKE_INSTALL_PREFIX} STREQUAL /usr)
set (LIBDIR lib${LIB_SUFFIX})
set (INCLUDEDIR include)
set (DATAROOTDIR share)
set (MANDIR ${DATAROOTDIR}/man)
set (SHAREDIR ${DATAROOTDIR}/mosquitto)
endif (WIN32)
option(WITH_TLS
"Include SSL/TLS support?" ON)
option(WITH_TLS_PSK
"Include TLS-PSK support (requires WITH_TLS)?" ON)
if (${WITH_TLS} STREQUAL ON)
find_package(OpenSSL REQUIRED)
add_definitions("-DWITH_TLS")
if (${WITH_TLS_PSK} STREQUAL ON)
add_definitions("-DWITH_TLS_PSK")
endif (${WITH_TLS_PSK} STREQUAL ON)
else (${WITH_TLS} STREQUAL ON)
set (OPENSSL_INCLUDE_DIR "")
endif (${WITH_TLS} STREQUAL ON)
# ========================================
# Include projects
# ========================================
add_subdirectory(lib)
add_subdirectory(client)
add_subdirectory(src)
add_subdirectory(man)
# ========================================
# Install config file
# ========================================
install(FILES mosquitto.conf aclfile.example pskfile.example pwfile.example DESTINATION ${SYSCONFDIR})

1093
ChangeLog.txt Normal file

File diff suppressed because it is too large Load Diff

2
LICENSE.txt Normal file
View File

@@ -0,0 +1,2 @@
This project is dual licensed under the Eclipse Public License 1.0 and the
Eclipse Distribution License 1.0 as described in the epl-v10 and edl-v10 files.

70
Makefile Normal file
View File

@@ -0,0 +1,70 @@
include config.mk
DIRS=lib client src
DOCDIRS=man
DISTDIRS=man
.PHONY : all mosquitto docs binary clean reallyclean test install uninstall dist sign copy
all : mosquitto docs
docs :
set -e; for d in ${DOCDIRS}; do $(MAKE) -C $${d}; done
binary : mosquitto
mosquitto :
set -e; for d in ${DIRS}; do $(MAKE) -C $${d}; done
clean :
set -e; for d in ${DIRS}; do $(MAKE) -C $${d} clean; done
set -e; for d in ${DOCDIRS}; do $(MAKE) -C $${d} clean; done
$(MAKE) -C test clean
reallyclean :
set -e; for d in ${DIRS}; do $(MAKE) -C $${d} reallyclean; done
set -e; for d in ${DOCDIRS}; do $(MAKE) -C $${d} reallyclean; done
$(MAKE) -C test reallyclean
-rm -f *.orig
test : mosquitto
$(MAKE) -C test test
install : mosquitto
set -e; for d in ${DIRS}; do $(MAKE) -C $${d} install; done
set -e; for d in ${DOCDIRS}; do $(MAKE) -C $${d} install; done
$(INSTALL) -d ${DESTDIR}/etc/mosquitto
$(INSTALL) -m 644 mosquitto.conf ${DESTDIR}/etc/mosquitto/mosquitto.conf.example
$(INSTALL) -m 644 aclfile.example ${DESTDIR}/etc/mosquitto/aclfile.example
$(INSTALL) -m 644 pwfile.example ${DESTDIR}/etc/mosquitto/pwfile.example
$(INSTALL) -m 644 pskfile.example ${DESTDIR}/etc/mosquitto/pskfile.example
uninstall :
set -e; for d in ${DIRS}; do $(MAKE) -C $${d} uninstall; done
rm -f ${DESTDIR}/etc/mosquitto/mosquitto.conf
rm -f ${DESTDIR}/etc/mosquitto/aclfile.example
rm -f ${DESTDIR}/etc/mosquitto/pwfile.example
rm -f ${DESTDIR}/etc/mosquitto/pskfile.example
dist : reallyclean
set -e; for d in ${DISTDIRS}; do $(MAKE) -C $${d} dist; done
echo $$(hg log -r . --template "{node}") > changeset
mkdir -p dist/mosquitto-${VERSION}
cp -r client changeset examples installer lib logo man misc security service src test ChangeLog.txt CMakeLists.txt LICENSE.txt LICENSE-3rd-party.txt Makefile compiling.txt config.h config.mk readme.txt readme-windows.txt mosquitto.conf aclfile.example pskfile.example pwfile.example dist/mosquitto-${VERSION}/
cd dist; tar -zcf mosquitto-${VERSION}.tar.gz mosquitto-${VERSION}/
set -e; for m in man/*.xml; \
do \
hfile=$$(echo $${m} | sed -e 's#man/\(.*\)\.xml#\1#' | sed -e 's/\./-/g'); \
$(XSLTPROC) $(DB_HTML_XSL) $${m} > dist/$${hfile}.html; \
done
sign : dist
cd dist; gpg --detach-sign -a mosquitto-${VERSION}.tar.gz
copy : sign
cd dist; scp mosquitto-${VERSION}.tar.gz mosquitto-${VERSION}.tar.gz.asc mosquitto:site/mosquitto.org/files/source/
cd dist; scp *.html mosquitto:site/mosquitto.org/man/
scp ChangeLog.txt mosquitto:site/mosquitto.org/

57
THANKS.txt Normal file
View File

@@ -0,0 +1,57 @@
These people have reported bugs / provided patches / done something else to aid
the mosquitto project. Thanks to you all!
If you think I've missed you off the list, please rest assured that it wasn't
intentional and get in touch and I'll fix it.
Adam Rudd
Andrew Elwell
Andy Piper
Andy Stanford-Clark
Bart Van Der Meerssche
Ben Tobin
Brad Stancel
Chris Willing
Craig Hollabaugh
Dan Anderson
Dariusz Suchojad
David Huang
David Monro
Dirk O. Kaar
Dominik Obermaier
Dominik Zajac
Ed Morris
Frank Hansen
Gary Koh
Joan Zapata
Karl Palsson
Larry Lendo
Martin Assarsson
Marty Lee
Matt Daubney
Michael C
Michael Frisch
Michael Rushton
Mike Bush
Neil Bothwick
Nicholas Humfrey
Nicholas O'Leary
Nithin Kumar
Paul Diston
Peter George
Rob Pridham
Robin Gingras
Roland de Boo
Sebastian Kroll
Sharon Ben-Asher
sskaje
Stefan Hudelmaier
Stefano Costa
Stephen Woods
Steven Lougheed
Thomas Hilbig
Tobias Assarsson
Toby Jaffey
Vicente Ruiz
Wayne Ingram
Yuvraaj Kelkar

9
aclfile.example Normal file
View File

@@ -0,0 +1,9 @@
# This affects access control for clients with no username.
topic read $SYS/#
# This only affects clients with username "roger".
user roger
topic foo/bar
# This affects all clients.
pattern write $SYS/broker/connection/%c/state

1
changeset Normal file
View File

@@ -0,0 +1 @@
b216c4246a7e9ff2be360ca2a7d102c5ea101f04

12
client/CMakeLists.txt Normal file
View File

@@ -0,0 +1,12 @@
include_directories(${mosquitto_SOURCE_DIR}/lib
${STDBOOL_H_PATH} ${STDINT_H_PATH})
link_directories(${mosquitto_BINARY_DIR}/lib)
add_executable(mosquitto_pub pub_client.c)
add_executable(mosquitto_sub sub_client.c)
target_link_libraries(mosquitto_pub mosquitto)
target_link_libraries(mosquitto_sub mosquitto)
install(TARGETS mosquitto_pub RUNTIME DESTINATION ${BINDIR} LIBRARY DESTINATION ${LIBDIR})
install(TARGETS mosquitto_sub RUNTIME DESTINATION ${BINDIR} LIBRARY DESTINATION ${LIBDIR})

34
client/Makefile Normal file
View File

@@ -0,0 +1,34 @@
include ../config.mk
.PHONY: all install uninstall reallyclean clean
all : mosquitto_pub mosquitto_sub
mosquitto_pub : pub_client.o ../lib/libmosquitto.so.${SOVERSION}
${CC} $< -o $@ ${CLIENT_LDFLAGS}
mosquitto_sub : sub_client.o ../lib/libmosquitto.so.${SOVERSION}
${CC} $< -o $@ ${CLIENT_LDFLAGS}
pub_client.o : pub_client.c ../lib/libmosquitto.so.${SOVERSION}
${CC} -c $< -o $@ ${CLIENT_CFLAGS}
sub_client.o : sub_client.c ../lib/libmosquitto.so.${SOVERSION}
${CC} -c $< -o $@ ${CLIENT_CFLAGS}
../lib/libmosquitto.so.${SOVERSION} :
$(MAKE) -C ../lib
install : all
$(INSTALL) -d ${DESTDIR}$(prefix)/bin
$(INSTALL) -s mosquitto_pub ${DESTDIR}${prefix}/bin/mosquitto_pub
$(INSTALL) -s mosquitto_sub ${DESTDIR}${prefix}/bin/mosquitto_sub
uninstall :
-rm -f ${DESTDIR}${prefix}/bin/mosquitto_pub
-rm -f ${DESTDIR}${prefix}/bin/mosquitto_sub
reallyclean : clean
clean :
-rm -f *.o mosquitto_pub mosquitto_sub

785
client/pub_client.c Normal file

File diff suppressed because it is too large Load Diff

650
client/sub_client.c Normal file

File diff suppressed because it is too large Load Diff

17
compiling.txt Normal file
View File

@@ -0,0 +1,17 @@
The following packages are required for mosquitto:
* tcp-wrappers (optional, package name libwrap0-dev)
* openssl (version 1.0.0 or greater if TLS-PSK support is needed)
* On Windows, the Redhat pthreads library is required if threading support is
to be included.
To compile, run "make", but also see the file config.mk for more details on the
various options that can be compiled in.
Where possible use the Makefiles to compile. This is particularly relevant for
the client libraries as symbol information will be included. Use cmake to
compile on Windows or Mac.
If you have any questions, problems or suggestions (particularly related to
installing on a more unusual device like a plug-computer) then please get in
touch using the details in readme.txt.

19
config.h Normal file
View File

@@ -0,0 +1,19 @@
/* ============================================================
* Control compile time options.
* ============================================================
*
* Compile time options have moved to config.mk.
*/
/* ============================================================
* Compatibility defines
*
* Generally for Windows native support.
* ============================================================ */
#ifdef WIN32
#define snprintf sprintf_s
#define strcasecmp strcmpi
#define strtok_r strtok_s
#define strerror_r(e, b, l) strerror_s(b, l, e)
#endif

218
config.mk Normal file
View File

@@ -0,0 +1,218 @@
# =============================================================================
# User configuration section.
#
# Largely, these are options that are designed to make mosquitto run more
# easily in restrictive environments by removing features.
#
# Modify the variable below to enable/disable features.
#
# Can also be overriden at the command line, e.g.:
#
# make WITH_TLS=no
# =============================================================================
# Uncomment to compile the broker with tcpd/libwrap support.
#WITH_WRAP:=yes
# Comment out to disable SSL/TLS support in the broker and client.
# Disabling this will also mean that passwords must be stored in plain text. It
# is strongly recommended that you only disable WITH_TLS if you are not using
# password authentication at all.
WITH_TLS:=yes
# Comment out to disable TLS/PSK support in the broker and client. Requires
# WITH_TLS=yes.
# This must be disabled if using openssl < 1.0.
WITH_TLS_PSK:=yes
# Comment out to disable client client threading support.
WITH_THREADING:=yes
# Uncomment to compile the broker with strict protocol support. This means that
# both the client library and the broker will be very strict about protocol
# compliance on incoming data. Neither of them will return an error on
# incorrect "remaining length" values if this is commented out. The old
# behaviour (prior to 0.12) is equivalent to compiling with
# WITH_STRICT_PROTOCOL defined and means that clients will be immediately
# disconnected from the broker on non-compliance.
#WITH_STRICT_PROTOCOL:=yes
# Comment out to remove bridge support from the broker. This allow the broker
# to connect to other brokers and subscribe/publish to topics. You probably
# want to leave this included unless you want to save a very small amount of
# memory size and CPU time.
WITH_BRIDGE:=yes
# Comment out to remove persistent database support from the broker. This
# allows the broker to store retained messages and durable subscriptions to a
# file periodically and on shutdown. This is usually desirable (and is
# suggested by the MQTT spec), but it can be disabled if required.
WITH_PERSISTENCE:=yes
# Comment out to remove memory tracking support from the broker. If disabled,
# mosquitto won't track heap memory usage nor export '$SYS/broker/heap/current
# size', but will use slightly less memory and CPU time.
WITH_MEMORY_TRACKING:=yes
# Compile with database upgrading support? If disabled, mosquitto won't
# automatically upgrade old database versions.
# Not currently supported.
#WITH_DB_UPGRADE:=yes
# Comment out to remove publishing of the $SYS topic hierarchy containing
# information about the broker state.
WITH_SYS_TREE:=yes
# Build with Python module. Comment out if Python is not installed, or required
# Python modules are not available.
WITH_PYTHON:=yes
# Build with SRV lookup support.
WITH_SRV:=yes
# =============================================================================
# End of user configuration
# =============================================================================
# Also bump lib/mosquitto.h, lib/python/setup.py, CMakeLists.txt,
# installer/mosquitto.nsi, installer/mosquitto-cygwin.nsi
VERSION=1.3.1
TIMESTAMP:=$(shell date "+%F %T%z")
# Client library SO version. Bump if incompatible API/ABI changes are made.
SOVERSION=1
# Man page generation requires xsltproc and docbook-xsl
XSLTPROC=xsltproc
# For html generation
DB_HTML_XSL=man/html.xsl
#MANCOUNTRIES=en_GB
UNAME:=$(shell uname -s)
ifeq ($(UNAME),SunOS)
ifeq ($(CC),cc)
CFLAGS?=-O
else
CFLAGS?=-Wall -ggdb -O2
endif
else
CFLAGS?=-Wall -ggdb -O2
endif
LIB_CFLAGS:=${CFLAGS} ${CPPFLAGS} -I. -I.. -I../lib
LIB_CXXFLAGS:=$(LIB_CFLAGS) ${CPPFLAGS}
LIB_LDFLAGS:=${LDFLAGS}
BROKER_CFLAGS:=${LIB_CFLAGS} ${CPPFLAGS} -DVERSION="\"${VERSION}\"" -DTIMESTAMP="\"${TIMESTAMP}\"" -DWITH_BROKER
CLIENT_CFLAGS:=${CFLAGS} ${CPPFLAGS} -I../lib -DVERSION="\"${VERSION}\""
ifeq ($(UNAME),FreeBSD)
BROKER_LIBS:=-lm
else
BROKER_LIBS:=-ldl -lm
endif
LIB_LIBS:=
PASSWD_LIBS:=
ifeq ($(UNAME),Linux)
BROKER_LIBS:=$(BROKER_LIBS) -lrt
LIB_LIBS:=$(LIB_LIBS) -lrt
endif
CLIENT_LDFLAGS:=$(LDFLAGS) -L../lib ../lib/libmosquitto.so.${SOVERSION}
ifeq ($(UNAME),SunOS)
ifeq ($(CC),cc)
LIB_CFLAGS:=$(LIB_CFLAGS) -xc99 -KPIC
else
LIB_CFLAGS:=$(LIB_CFLAGS) -fPIC
endif
ifeq ($(CXX),CC)
LIB_CXXFLAGS:=$(LIB_CXXFLAGS) -KPIC
else
LIB_CXXFLAGS:=$(LIB_CXXFLAGS) -fPIC
endif
else
LIB_CFLAGS:=$(LIB_CFLAGS) -fPIC
LIB_CXXFLAGS:=$(LIB_CXXFLAGS) -fPIC
endif
ifneq ($(UNAME),SunOS)
LIB_LDFLAGS:=$(LIB_LDFLAGS) -Wl,--version-script=linker.version -Wl,-soname,libmosquitto.so.$(SOVERSION)
endif
ifeq ($(UNAME),QNX)
BROKER_LIBS:=$(BROKER_LIBS) -lsocket
LIB_LIBS:=$(LIB_LIBS) -lsocket
endif
ifeq ($(WITH_WRAP),yes)
BROKER_LIBS:=$(BROKER_LIBS) -lwrap
BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_WRAP
endif
ifeq ($(WITH_TLS),yes)
BROKER_LIBS:=$(BROKER_LIBS) -lssl -lcrypto
LIB_LIBS:=$(LIB_LIBS) -lssl -lcrypto
BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_TLS
LIB_CFLAGS:=$(LIB_CFLAGS) -DWITH_TLS
PASSWD_LIBS:=-lcrypto
CLIENT_CFLAGS:=$(CLIENT_CFLAGS) -DWITH_TLS
ifeq ($(WITH_TLS_PSK),yes)
BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_TLS_PSK
LIB_CFLAGS:=$(LIB_CFLAGS) -DWITH_TLS_PSK
CLIENT_CFLAGS:=$(CLIENT_CFLAGS) -DWITH_TLS_PSK
endif
endif
ifeq ($(WITH_THREADING),yes)
LIB_LIBS:=$(LIB_LIBS) -lpthread
LIB_CFLAGS:=$(LIB_CFLAGS) -DWITH_THREADING
endif
ifeq ($(WITH_STRICT_PROTOCOL),yes)
LIB_CFLAGS:=$(LIB_CFLAGS) -DWITH_STRICT_PROTOCOL
BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_STRICT_PROTOCOL
endif
ifeq ($(WITH_BRIDGE),yes)
BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_BRIDGE
endif
ifeq ($(WITH_PERSISTENCE),yes)
BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_PERSISTENCE
endif
ifeq ($(WITH_MEMORY_TRACKING),yes)
ifneq ($(UNAME),SunOS)
BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_MEMORY_TRACKING
endif
endif
#ifeq ($(WITH_DB_UPGRADE),yes)
# BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_DB_UPGRADE
#endif
ifeq ($(WITH_SYS_TREE),yes)
BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_SYS_TREE
endif
ifeq ($(WITH_SRV),yes)
LIB_CFLAGS:=$(LIB_CFLAGS) -DWITH_SRV
LIB_LIBS:=$(LIB_LIBS) -lcares
endif
ifeq ($(UNAME),SunOS)
BROKER_LIBS:=$(BROKER_LIBS) -lsocket -lnsl
LIB_LIBS:=$(LIB_LIBS) -lsocket -lnsl
endif
INSTALL?=install
prefix=/usr/local
mandir=${prefix}/share/man
localedir=${prefix}/share/locale

View File

@@ -0,0 +1,43 @@
This is the description of the regex used previously for topic/subscription
matching. It is reproduced here for posterity.
When a message is ready to be published at the broker, we need to check all
of the subscriptions to see which ones the message should be sent to. This
would be easy without wildcards, but requires a bit more work with them.
The regex used to do the matching is of the form below for a topic of a/b/c:
^(?:(?:(a|\+)(?!$))(?:(?:/(?:(b|\+)(?!$)))(?:(?:/(?:c|\+))|/#)?|/#)?|#)$
In general, we're matching (a or +) followed by (the next levels of
hierarchy or #).
More specifically, all the levels of hierarchy must match, unless the last
level is #.
^(?: # Must start at beginning of string
(?: # (Level 1 hierarchy)
(a|\+)(?!$) # Match a or +, but only if not EOL.
) # AND
(?:
(?: # (Level 2 hierarchy)
/ # Match /
(?: # AND
(b|\+)(?!$) # Match b or +, but only if not EOL.
)
) # AND
(?:
(?: # (Level 3 hierarchy)
/ # Match /
(?: # AND
c|\+ # Match c or +.
)
)
| # OR (instead of level 3)
/# # Match /# at level 3
)? # Level 3 exist 1/0 times
| # OR (instead of level 2)
/# # Match /# at level 2
)? # Level 2 exist 1/0 times
| # OR (instead of level 1)
# # Match # at level 1
)$ # Must end on EOL.

View File

@@ -0,0 +1,7 @@
S'^(?:(?:(a|\\+)(?!$))(?:(?:/(?:(b|\\+)(?!$)))(?:(?:/(?:c|\\+))|/#)?|/#)?|#)$'
p1
.S'a/#\na/b/c\na/b/+\na/b\na/+\n+\n+/b\n+/+/+\n+/b/c\na/c'
p2
.I8
.S''
.

31
edl-v10 Normal file
View File

@@ -0,0 +1,31 @@
Eclipse Distribution License - v 1.0
Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
Neither the name of the Eclipse Foundation, Inc. nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

221
epl-v10 Normal file
View File

@@ -0,0 +1,221 @@
Eclipse Public License - v 1.0
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
1. DEFINITIONS
"Contribution" means:
a) in the case of the initial Contributor, the initial code and
documentation distributed under this Agreement, and
b) in the case of each subsequent Contributor:
i) changes to the Program, and
ii) additions to the Program;
where such changes and/or additions to the Program originate from and are
distributed by that particular Contributor. A Contribution 'originates' from a
Contributor if it was added to the Program by such Contributor itself or anyone
acting on such Contributor's behalf. Contributions do not include additions to
the Program which: (i) are separate modules of software distributed in
conjunction with the Program under their own license agreement, and (ii) are
not derivative works of the Program.
"Contributor" means any person or entity that distributes the Program.
"Licensed Patents " mean patent claims licensable by a Contributor which are
necessarily infringed by the use or sale of its Contribution alone or when
combined with the Program.
"Program" means the Contributions distributed in accordance with this Agreement.
"Recipient" means anyone who receives the Program under this Agreement,
including all Contributors.
2. GRANT OF RIGHTS
a) Subject to the terms of this Agreement, each Contributor hereby grants
Recipient a non-exclusive, worldwide, royalty-free copyright license to
reproduce, prepare derivative works of, publicly display, publicly
perform, distribute and sublicense the Contribution of such Contributor,
if any, and such derivative works, in source code and object code form.
b) Subject to the terms of this Agreement, each Contributor hereby grants
Recipient a non-exclusive, worldwide, royalty-free patent license under
Licensed Patents to make, use, sell, offer to sell, import and otherwise
transfer the Contribution of such Contributor, if any, in source code and
object code form. This patent license shall apply to the combination of the
Contribution and the Program if, at the time the Contribution is added by the
Contributor, such addition of the Contribution causes such combination to be
covered by the Licensed Patents. The patent license shall not apply to any
other combinations which include the Contribution. No hardware per se is
licensed hereunder.
c) Recipient understands that although each Contributor grants the licenses
to its Contributions set forth herein, no assurances are provided by any
Contributor that the Program does not infringe the patent or other
intellectual property rights of any other entity. Each Contributor disclaims
any liability to Recipient for claims brought by any other entity based on
infringement of intellectual property rights or otherwise. As a condition to
exercising the rights and licenses granted hereunder, each Recipient hereby
assumes sole responsibility to secure any other intellectual property rights
needed, if any. For example, if a third party patent license is required to
allow Recipient to distribute the Program, it is Recipient's responsibility
to acquire that license before distributing the Program.
d) Each Contributor represents that to its knowledge it has sufficient
copyright rights in its Contribution, if any, to grant the copyright license
set forth in this Agreement.
3. REQUIREMENTS
A Contributor may choose to distribute the Program in object code form under
its own license agreement, provided that:
a) it complies with the terms and conditions of this Agreement; and
b) its license agreement:
i) effectively disclaims on behalf of all Contributors all warranties and
conditions, express and implied, including warranties or conditions of
title and non-infringement, and implied warranties or conditions of
merchantability and fitness for a particular purpose;
ii) effectively excludes on behalf of all Contributors all liability for
damages, including direct, indirect, special, incidental and consequential
damages, such as lost profits;
iii) states that any provisions which differ from this Agreement are offered
by that Contributor alone and not by any other party; and
iv) states that source code for the Program is available from such
Contributor, and informs licensees how to obtain it in a reasonable manner
on or through a medium customarily used for software exchange.
When the Program is made available in source code form:
a) it must be made available under this Agreement; and
b) a copy of this Agreement must be included with each copy of the Program.
Contributors may not remove or alter any copyright notices contained within
the Program.
Each Contributor must identify itself as the originator of its Contribution,
if any, in a manner that reasonably allows subsequent Recipients to identify
the originator of the Contribution.
4. COMMERCIAL DISTRIBUTION
Commercial distributors of software may accept certain responsibilities with
respect to end users, business partners and the like. While this license is
intended to facilitate the commercial use of the Program, the Contributor who
includes the Program in a commercial product offering should do so in a
manner which does not create potential liability for other Contributors.
Therefore, if a Contributor includes the Program in a commercial product
offering, such Contributor ("Commercial Contributor") hereby agrees to defend
and indemnify every other Contributor ("Indemnified Contributor") against any
losses, damages and costs (collectively "Losses") arising from claims,
lawsuits and other legal actions brought by a third party against the
Indemnified Contributor to the extent caused by the acts or omissions of such
Commercial Contributor in connection with its distribution of the Program in
a commercial product offering. The obligations in this section do not apply
to any claims or Losses relating to any actual or alleged intellectual
property infringement. In order to qualify, an Indemnified Contributor must:
a) promptly notify the Commercial Contributor in writing of such claim, and
b) allow the Commercial Contributor to control, and cooperate with the
Commercial Contributor in, the defense and any related settlement
negotiations. The Indemnified Contributor may participate in any such claim
at its own expense.
For example, a Contributor might include the Program in a commercial product
offering, Product X. That Contributor is then a Commercial Contributor. If
that Commercial Contributor then makes performance claims, or offers
warranties related to Product X, those performance claims and warranties are
such Commercial Contributor's responsibility alone. Under this section, the
Commercial Contributor would have to defend claims against the other
Contributors related to those performance claims and warranties, and if a
court requires any other Contributor to pay any damages as a result, the
Commercial Contributor must pay those damages.
5. NO WARRANTY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON
AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A
PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the
appropriateness of using and distributing the Program and assumes all risks
associated with its exercise of rights under this Agreement , including but
not limited to the risks and costs of program errors, compliance with
applicable laws, damage to or loss of data, programs or equipment, and
unavailability or interruption of operations.
6. DISCLAIMER OF LIABILITY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGES.
7. GENERAL
If any provision of this Agreement is invalid or unenforceable under
applicable law, it shall not affect the validity or enforceability of the
remainder of the terms of this Agreement, and without further action by the
parties hereto, such provision shall be reformed to the minimum extent
necessary to make such provision valid and enforceable.
If Recipient institutes patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Program itself
(excluding combinations of the Program with other software or hardware)
infringes such Recipient's patent(s), then such Recipient's rights granted
under Section 2(b) shall terminate as of the date such litigation is filed.
All Recipient's rights under this Agreement shall terminate if it fails to
comply with any of the material terms or conditions of this Agreement and
does not cure such failure in a reasonable period of time after becoming
aware of such noncompliance. If all Recipient's rights under this Agreement
terminate, Recipient agrees to cease use and distribution of the Program as
soon as reasonably practicable. However, Recipient's obligations under this
Agreement and any licenses granted by Recipient relating to the Program shall
continue and survive.
Everyone is permitted to copy and distribute copies of this Agreement, but in
order to avoid inconsistency the Agreement is copyrighted and may only be
modified in the following manner. The Agreement Steward reserves the right to
publish new versions (including revisions) of this Agreement from time to
time. No one other than the Agreement Steward has the right to modify this
Agreement. The Eclipse Foundation is the initial Agreement Steward. The
Eclipse Foundation may assign the responsibility to serve as the Agreement
Steward to a suitable separate entity. Each new version of the Agreement will
be given a distinguishing version number. The Program (including
Contributions) may always be distributed subject to the version of the
Agreement under which it was received. In addition, after a new version of
the Agreement is published, Contributor may elect to distribute the Program
(including its Contributions) under the new version. Except as expressly
stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
licenses to the intellectual property of any Contributor under this
Agreement, whether expressly, by implication, estoppel or otherwise. All
rights in the Program not expressly granted under this Agreement are
reserved.
This Agreement is governed by the laws of the State of New York and the
intellectual property laws of the United States of America. No party to this
Agreement will bring a legal action under this Agreement more than one year
after the cause of action arose. Each party waives its rights to a jury trial
in any resulting litigation.

View File

@@ -0,0 +1,15 @@
CFLAGS=-Wall -ggdb
LDFLAGS=../../lib/libmosquitto.so.1 -lmysqlclient
.PHONY: all clean
all : mosquitto_mysql_log
mosquitto_mysql_log : mysql_log.o
${CC} $^ -o $@ ${LDFLAGS}
mysql_log.o : mysql_log.c
${CC} -c $^ -o $@ ${CFLAGS} -I../../lib
clean :
-rm -f *.o mosquitto_mysql_log

View File

@@ -0,0 +1,118 @@
#include <signal.h>
#include <stdio.h>
#include <string.h>
#ifndef WIN32
# include <unistd.h>
#else
# include <process.h>
# define snprintf sprintf_s
#endif
#include <mosquitto.h>
#include <mysql/mysql.h>
#define db_host "localhost"
#define db_username "mqtt_log"
#define db_password "password"
#define db_database "mqtt_log"
#define db_port 3306
#define db_query "INSERT INTO mqtt_log (topic, payload) VALUES (?,?)"
#define mqtt_host "localhost"
#define mqtt_port 1883
static int run = 1;
static MYSQL_STMT *stmt = NULL;
void handle_signal(int s)
{
run = 0;
}
void connect_callback(struct mosquitto *mosq, void *obj, int result)
{
}
void message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
{
MYSQL_BIND bind[2];
memset(bind, 0, sizeof(bind));
bind[0].buffer_type = MYSQL_TYPE_STRING;
bind[0].buffer = message->topic;
bind[1].buffer_type = MYSQL_TYPE_STRING;
bind[1].buffer = message->payload;
mysql_stmt_bind_param(stmt, bind);
mysql_stmt_execute(stmt);
}
int main(int argc, char *argv[])
{
MYSQL *connection;
my_bool reconnect = true;
char clientid[24];
struct mosquitto *mosq;
int rc = 0;
signal(SIGINT, handle_signal);
signal(SIGTERM, handle_signal);
mysql_library_init(0, NULL, NULL);
mosquitto_lib_init();
connection = mysql_init(NULL);
if(connection){
mysql_options(connection, MYSQL_OPT_RECONNECT, &reconnect);
connection = mysql_real_connect(connection, db_host, db_username, db_password, db_database, db_port, NULL, 0);
if(connection){
stmt = mysql_stmt_init(connection);
mysql_stmt_prepare(stmt, db_query, strlen(db_query));
memset(clientid, 0, 24);
snprintf(clientid, 23, "mysql_log_%d", getpid());
mosq = mosquitto_new(clientid, true, connection);
if(mosq){
mosquitto_connect_callback_set(mosq, connect_callback);
mosquitto_message_callback_set(mosq, message_callback);
rc = mosquitto_connect(mosq, mqtt_host, mqtt_port, 60);
mosquitto_subscribe(mosq, NULL, "#", 0);
while(run){
rc = mosquitto_loop(mosq, -1, 1);
if(run && rc){
sleep(20);
mosquitto_reconnect(mosq);
}
}
mosquitto_destroy(mosq);
}
mysql_stmt_close(stmt);
mysql_close(connection);
}else{
fprintf(stderr, "Error: Unable to connect to database.\n");
printf("%s\n", mysql_error(connection));
rc = 1;
}
}else{
fprintf(stderr, "Error: Unable to start mysql.\n");
rc = 1;
}
mysql_library_end();
mosquitto_lib_cleanup();
return rc;
}

View File

@@ -0,0 +1,18 @@
CFLAGS=-Wall -ggdb -I../../lib -I../../lib/cpp
LDFLAGS=-L../../lib ../../lib/cpp/libmosquittopp.so.1 ../../lib/libmosquitto.so.1
.PHONY: all clean
all : mqtt_temperature_conversion
mqtt_temperature_conversion : main.o temperature_conversion.o
${CXX} $^ -o $@ ${LDFLAGS}
main.o : main.cpp
${CXX} -c $^ -o $@ ${CFLAGS}
temperature_conversion.o : temperature_conversion.cpp
${CXX} -c $^ -o $@ ${CFLAGS}
clean :
-rm -f *.o mqtt_temperature_conversion

View File

@@ -0,0 +1,23 @@
#include "temperature_conversion.h"
int main(int argc, char *argv[])
{
class mqtt_tempconv *tempconv;
int rc;
mosqpp::lib_init();
tempconv = new mqtt_tempconv("tempconv", "localhost", 1883);
while(1){
rc = tempconv->loop();
if(rc){
tempconv->reconnect();
}
}
mosqpp::lib_cleanup();
return 0;
}

View File

@@ -0,0 +1,6 @@
This is a simple example of the C++ library mosquittopp.
It is a client that subscribes to the topic temperature/celsius which should
have temperature data in text form being published to it. It reads this data as
a Celsius temperature, converts to Farenheit and republishes on
temperature/farenheit.

View File

@@ -0,0 +1,45 @@
#include <cstdio>
#include <cstring>
#include "temperature_conversion.h"
#include <mosquittopp.h>
mqtt_tempconv::mqtt_tempconv(const char *id, const char *host, int port) : mosquittopp(id)
{
int keepalive = 60;
/* Connect immediately. This could also be done by calling
* mqtt_tempconv->connect(). */
connect(host, port, keepalive);
};
void mqtt_tempconv::on_connect(int rc)
{
printf("Connected with code %d.\n", rc);
if(rc == 0){
/* Only attempt to subscribe on a successful connect. */
subscribe(NULL, "temperature/celsius");
}
}
void mqtt_tempconv::on_message(const struct mosquitto_message *message)
{
double temp_celsius, temp_farenheit;
char buf[51];
if(!strcmp(message->topic, "temperature/celsius")){
memset(buf, 0, 51*sizeof(char));
/* Copy N-1 bytes to ensure always 0 terminated. */
memcpy(buf, message->payload, 50*sizeof(char));
temp_celsius = atof(buf);
temp_farenheit = temp_celsius*9.0/5.0 + 32.0;
snprintf(buf, 50, "%f", temp_farenheit);
publish(NULL, "temperature/farenheit", strlen(buf), buf);
}
}
void mqtt_tempconv::on_subscribe(int mid, int qos_count, const int *granted_qos)
{
printf("Subscription succeeded.\n");
}

View File

@@ -0,0 +1,17 @@
#ifndef TEMPERATURE_CONVERSION_H
#define TEMPERATURE_CONVERSION_H
#include <mosquittopp.h>
class mqtt_tempconv : public mosqpp::mosquittopp
{
public:
mqtt_tempconv(const char *id, const char *host, int port);
~mqtt_tempconv();
void on_connect(int rc);
void on_message(const struct mosquitto_message *message);
void on_subscribe(int mid, int qos_count, const int *granted_qos);
};
#endif

View File

@@ -0,0 +1,144 @@
; NSIS installer script for mosquitto
!include "MUI.nsh"
; For environment variable code
!include "WinMessages.nsh"
!define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
Name "mosquitto"
!define VERSION 1.3.1
OutFile "mosquitto-${VERSION}-install-cygwin.exe"
InstallDir "$PROGRAMFILES\mosquitto"
;--------------------------------
; Installer pages
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
;--------------------------------
; Uninstaller pages
!insertmacro MUI_UNPAGE_WELCOME
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH
;--------------------------------
; Languages
!insertmacro MUI_LANGUAGE "English"
;--------------------------------
; Installer sections
Section "Files" SecInstall
SectionIn RO
SetOutPath "$INSTDIR"
File "c:\cygwin\bin\cygwin1.dll"
File "c:\cygwin\bin\cyggcc_s-1.dll"
File "c:\cygwin\bin\cygcrypto-1.0.0.dll"
File "c:\cygwin\bin\cygssl-1.0.0.dll"
File "c:\cygwin\bin\cygz.dll"
File "..\src\mosquitto.exe"
File "..\build\src\Release\mosquitto_passwd.exe"
File "..\build\client\Release\mosquitto_pub.exe"
File "..\build\client\Release\mosquitto_sub.exe"
File "..\build\lib\Release\mosquitto.dll"
File "..\build\lib\cpp\Release\mosquittopp.dll"
File "..\aclfile.example"
File "..\ChangeLog.txt"
File "..\mosquitto.conf"
File "..\pwfile.example"
File "..\readme.txt"
File "..\readme-windows.txt"
File "C:\pthreads\Pre-built.2\dll\x86\pthreadVC2.dll"
File "C:\OpenSSL-Win32\libeay32.dll"
File "C:\OpenSSL-Win32\ssleay32.dll"
File "..\LICENSE.txt"
File "..\LICENSE-3rd-party.txt"
SetOutPath "$INSTDIR\devel"
File "..\lib\mosquitto.h"
File "..\build\lib\Release\mosquitto.lib"
File "..\lib\cpp\mosquittopp.h"
File "..\build\lib\cpp\Release\mosquittopp.lib"
File "..\src\mosquitto_plugin.h"
SetOutPath "$INSTDIR\python"
File "..\lib\python\mosquitto.py"
File "..\lib\python\setup.py"
File "..\lib\python\sub.py"
WriteUninstaller "$INSTDIR\Uninstall.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "DisplayName" "Mosquitto MQTT broker"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "UninstallString" "$\"$INSTDIR\Uninstall.exe$\""
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "QuietUninstallString" "$\"$INSTDIR\Uninstall.exe$\" /S"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "HelpLink" "http://mosquitto.org/"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "URLInfoAbout" "http://mosquitto.org/"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "DisplayVersion" "${VERSION}"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "NoModify" "1"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "NoRepair" "1"
WriteRegExpandStr ${env_hklm} MOSQUITTO_DIR $INSTDIR
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
SectionEnd
Section "Service" SecService
ExecWait '"$INSTDIR\mosquitto.exe" install'
SectionEnd
Section "Uninstall"
ExecWait '"$INSTDIR\mosquitto.exe" uninstall'
Delete "$INSTDIR\cygwin1.dll"
Delete "$INSTDIR\cyggcc_s-1.dll"
Delete "$INSTDIR\cygcrypto-1.0.0.dll"
Delete "$INSTDIR\cygssl-1.0.0.dll"
Delete "$INSTDIR\cygz.dll"
Delete "$INSTDIR\mosquitto.exe"
Delete "$INSTDIR\mosquitto_passwd.exe"
Delete "$INSTDIR\mosquitto_pub.exe"
Delete "$INSTDIR\mosquitto_sub.exe"
Delete "$INSTDIR\mosquitto.dll"
Delete "$INSTDIR\mosquittopp.dll"
Delete "$INSTDIR\aclfile.example"
Delete "$INSTDIR\ChangeLog.txt"
Delete "$INSTDIR\mosquitto.conf"
Delete "$INSTDIR\pwfile.example"
Delete "$INSTDIR\readme.txt"
Delete "$INSTDIR\readme-windows.txt"
Delete "$INSTDIR\pthreadVC2.dll"
Delete "$INSTDIR\libeay32.dll"
Delete "$INSTDIR\ssleay32.dll"
Delete "$INSTDIR\LICENSE.txt"
Delete "$INSTDIR\LICENSE-3rd-party.txt"
Delete "$INSTDIR\devel\mosquitto.h"
Delete "$INSTDIR\devel\mosquitto.lib"
Delete "$INSTDIR\devel\mosquittopp.h"
Delete "$INSTDIR\devel\mosquittopp.lib"
Delete "$INSTDIR\devel\mosquitto_plugin.h"
Delete "$INSTDIR\python\mosquitto.py"
Delete "$INSTDIR\python\setup.py"
Delete "$INSTDIR\python\sub.py"
Delete "$INSTDIR\Uninstall.exe"
RMDir "$INSTDIR"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto"
DeleteRegValue ${env_hklm} MOSQUITTO_DIR
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
SectionEnd
LangString DESC_SecInstall ${LANG_ENGLISH} "The main installation."
LangString DESC_SecService ${LANG_ENGLISH} "Install mosquitto as a Windows service?"
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${SecInstall} $(DESC_SecInstall)
!insertmacro MUI_DESCRIPTION_TEXT ${SecService} $(DESC_SecService)
!insertmacro MUI_FUNCTION_DESCRIPTION_END

134
installer/mosquitto.nsi Normal file
View File

@@ -0,0 +1,134 @@
; NSIS installer script for mosquitto
!include "MUI.nsh"
; For environment variable code
!include "WinMessages.nsh"
!define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
Name "mosquitto"
!define VERSION 1.3.1
OutFile "mosquitto-${VERSION}-install-win32.exe"
InstallDir "$PROGRAMFILES\mosquitto"
;--------------------------------
; Installer pages
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
;--------------------------------
; Uninstaller pages
!insertmacro MUI_UNPAGE_WELCOME
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH
;--------------------------------
; Languages
!insertmacro MUI_LANGUAGE "English"
;--------------------------------
; Installer sections
Section "Files" SecInstall
SectionIn RO
SetOutPath "$INSTDIR"
File "..\build\src\Release\mosquitto.exe"
File "..\build\src\Release\mosquitto_passwd.exe"
File "..\build\client\Release\mosquitto_pub.exe"
File "..\build\client\Release\mosquitto_sub.exe"
File "..\build\lib\Release\mosquitto.dll"
File "..\build\lib\cpp\Release\mosquittopp.dll"
File "..\aclfile.example"
File "..\ChangeLog.txt"
File "..\mosquitto.conf"
File "..\pwfile.example"
File "..\readme.txt"
File "..\readme-windows.txt"
File "C:\pthreads\Pre-built.2\dll\x86\pthreadVC2.dll"
File "C:\OpenSSL-Win32\libeay32.dll"
File "C:\OpenSSL-Win32\ssleay32.dll"
File "..\LICENSE.txt"
File "..\LICENSE-3rd-party.txt"
SetOutPath "$INSTDIR\devel"
File "..\lib\mosquitto.h"
File "..\build\lib\Release\mosquitto.lib"
File "..\lib\cpp\mosquittopp.h"
File "..\build\lib\cpp\Release\mosquittopp.lib"
File "..\src\mosquitto_plugin.h"
SetOutPath "$INSTDIR\python"
File "..\lib\python\mosquitto.py"
File "..\lib\python\setup.py"
File "..\lib\python\sub.py"
WriteUninstaller "$INSTDIR\Uninstall.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "DisplayName" "Mosquitto MQTT broker"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "UninstallString" "$\"$INSTDIR\Uninstall.exe$\""
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "QuietUninstallString" "$\"$INSTDIR\Uninstall.exe$\" /S"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "HelpLink" "http://mosquitto.org/"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "URLInfoAbout" "http://mosquitto.org/"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "DisplayVersion" "${VERSION}"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "NoModify" "1"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto" "NoRepair" "1"
WriteRegExpandStr ${env_hklm} MOSQUITTO_DIR $INSTDIR
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
SectionEnd
Section "Service" SecService
ExecWait '"$INSTDIR\mosquitto.exe" install'
SectionEnd
Section "Uninstall"
ExecWait '"$INSTDIR\mosquitto.exe" uninstall'
Delete "$INSTDIR\mosquitto.exe"
Delete "$INSTDIR\mosquitto_passwd.exe"
Delete "$INSTDIR\mosquitto_pub.exe"
Delete "$INSTDIR\mosquitto_sub.exe"
Delete "$INSTDIR\mosquitto.dll"
Delete "$INSTDIR\mosquittopp.dll"
Delete "$INSTDIR\aclfile.example"
Delete "$INSTDIR\ChangeLog.txt"
Delete "$INSTDIR\mosquitto.conf"
Delete "$INSTDIR\pwfile.example"
Delete "$INSTDIR\readme.txt"
Delete "$INSTDIR\readme-windows.txt"
Delete "$INSTDIR\pthreadVC2.dll"
Delete "$INSTDIR\libeay32.dll"
Delete "$INSTDIR\ssleay32.dll"
Delete "$INSTDIR\LICENSE.txt"
Delete "$INSTDIR\LICENSE-3rd-party.txt"
Delete "$INSTDIR\devel\mosquitto.h"
Delete "$INSTDIR\devel\mosquitto.lib"
Delete "$INSTDIR\devel\mosquittopp.h"
Delete "$INSTDIR\devel\mosquittopp.lib"
Delete "$INSTDIR\devel\mosquitto_plugin.h"
Delete "$INSTDIR\python\mosquitto.py"
Delete "$INSTDIR\python\setup.py"
Delete "$INSTDIR\python\sub.py"
Delete "$INSTDIR\Uninstall.exe"
RMDir "$INSTDIR"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto"
DeleteRegValue ${env_hklm} MOSQUITTO_DIR
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
SectionEnd
LangString DESC_SecInstall ${LANG_ENGLISH} "The main installation."
LangString DESC_SecService ${LANG_ENGLISH} "Install mosquitto as a Windows service?"
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${SecInstall} $(DESC_SecInstall)
!insertmacro MUI_DESCRIPTION_TEXT ${SecService} $(DESC_SecService)
!insertmacro MUI_FUNCTION_DESCRIPTION_END

71
lib/CMakeLists.txt Normal file
View File

@@ -0,0 +1,71 @@
add_subdirectory(cpp)
option(WITH_THREADING "Include client library threading support?" ON)
if (${WITH_THREADING} STREQUAL ON)
add_definitions("-DWITH_THREADING")
if (WIN32)
set (PTHREAD_LIBRARIES C:\\pthreads\\Pre-built.2\\lib\\x86\\pthreadVC2.lib)
set (PTHREAD_INCLUDE_DIR C:\\pthreads\\Pre-built.2\\include)
else (WIN32)
set (PTHREAD_LIBRARIES pthread)
set (PTHREAD_INCLUDE_DIR "")
endif (WIN32)
else (${WITH_THREADING} STREQUAL ON)
set (PTHREAD_LIBRARIES "")
set (PTHREAD_INCLUDE_DIR "")
endif (${WITH_THREADING} STREQUAL ON)
include_directories(${mosquitto_SOURCE_DIR} ${mosquitto_SOURCE_DIR}/lib
${STDBOOL_H_PATH} ${STDINT_H_PATH}
${OPENSSL_INCLUDE_DIR} ${PTHREAD_INCLUDE_DIR})
link_directories(${mosquitto_SOURCE_DIR}/lib)
add_library(libmosquitto SHARED
logging_mosq.c logging_mosq.h
memory_mosq.c memory_mosq.h
messages_mosq.c messages_mosq.h
mosquitto.c mosquitto.h
mosquitto_internal.h
mqtt3_protocol.h
net_mosq.c net_mosq.h
read_handle.c read_handle.h
read_handle_client.c
read_handle_shared.c
send_client_mosq.c
send_mosq.c send_mosq.h
srv_mosq.c
thread_mosq.c
time_mosq.c
tls_mosq.c
util_mosq.c util_mosq.h
will_mosq.c will_mosq.h)
set (LIBRARIES ${OPENSSL_LIBRARIES} ${PTHREAD_LIBRARIES})
if (UNIX AND NOT APPLE)
set (LIBRARIES ${LIBRARIES} rt)
endif (UNIX AND NOT APPLE)
if (WIN32)
set (LIBRARIES ${LIBRARIES} ws2_32)
endif (WIN32)
option(WITH_SRV "Include SRV lookup support?" ON)
if (${WITH_SRV} STREQUAL ON)
set (LIBRARIES ${LIBRARIES} cares)
endif (${WITH_SRV} STREQUAL ON)
target_link_libraries(libmosquitto ${LIBRARIES})
set_target_properties(libmosquitto PROPERTIES
OUTPUT_NAME mosquitto
VERSION ${VERSION}
SOVERSION 1
)
install(TARGETS libmosquitto RUNTIME DESTINATION ${BINDIR} LIBRARY DESTINATION ${LIBDIR})
install(FILES mosquitto.h DESTINATION ${INCLUDEDIR})
if (UNIX)
install(CODE "EXEC_PROGRAM(/sbin/ldconfig)")
endif (UNIX)

96
lib/Makefile Normal file
View File

@@ -0,0 +1,96 @@
include ../config.mk
.PHONY : really clean install
MOSQ_OBJS=mosquitto.o \
logging_mosq.o \
memory_mosq.o \
messages_mosq.o \
net_mosq.o \
read_handle.o \
read_handle_client.o \
read_handle_shared.o \
send_mosq.o \
send_client_mosq.o \
srv_mosq.o \
thread_mosq.o \
time_mosq.o \
tls_mosq.o \
util_mosq.o \
will_mosq.o
all : libmosquitto.so.${SOVERSION} libmosquitto.a
$(MAKE) -C cpp
install : all
$(INSTALL) -d ${DESTDIR}$(prefix)/lib${LIB_SUFFIX}/
$(INSTALL) -s libmosquitto.so.${SOVERSION} ${DESTDIR}${prefix}/lib${LIB_SUFFIX}/libmosquitto.so.${SOVERSION}
ln -sf libmosquitto.so.${SOVERSION} ${DESTDIR}${prefix}/lib${LIB_SUFFIX}/libmosquitto.so
$(INSTALL) -d ${DESTDIR}${prefix}/include/
$(INSTALL) mosquitto.h ${DESTDIR}${prefix}/include/mosquitto.h
$(MAKE) -C cpp install
uninstall :
-rm -f ${DESTDIR}${prefix}/lib${LIB_SUFFIX}/libmosquitto.so.${SOVERSION}
-rm -f ${DESTDIR}${prefix}/lib${LIB_SUFFIX}/libmosquitto.so
-rm -f ${DESTDIR}${prefix}/include/mosquitto.h
reallyclean : clean
clean :
-rm -f *.o libmosquitto.so.${SOVERSION} libmosquitto.so libmosquitto.a
$(MAKE) -C cpp clean
libmosquitto.so.${SOVERSION} : ${MOSQ_OBJS}
$(CC) -shared $(LIB_LDFLAGS) $^ -o $@ ${LIB_LIBS}
libmosquitto.a : ${MOSQ_OBJS}
$(AR) cr $@ $^
mosquitto.o : mosquitto.c mosquitto.h
$(CC) $(LIB_CFLAGS) -c $< -o $@
logging_mosq.o : logging_mosq.c logging_mosq.h
$(CC) $(LIB_CFLAGS) -c $< -o $@
messages_mosq.o : messages_mosq.c messages_mosq.h
$(CC) $(LIB_CFLAGS) -c $< -o $@
memory_mosq.o : memory_mosq.c memory_mosq.h
$(CC) $(LIB_CFLAGS) -c $< -o $@
net_mosq.o : net_mosq.c net_mosq.h
$(CC) $(LIB_CFLAGS) -c $< -o $@
read_handle.o : read_handle.c read_handle.h
$(CC) $(LIB_CFLAGS) -c $< -o $@
read_handle_client.o : read_handle_client.c read_handle.h
$(CC) $(LIB_CFLAGS) -c $< -o $@
read_handle_shared.o : read_handle_shared.c read_handle.h
$(CC) $(LIB_CFLAGS) -c $< -o $@
send_mosq.o : send_mosq.c send_mosq.h
$(CC) $(LIB_CFLAGS) -c $< -o $@
send_client_mosq.o : send_client_mosq.c send_mosq.h
$(CC) $(LIB_CFLAGS) -c $< -o $@
srv_mosq.o : srv_mosq.c
$(CC) $(LIB_CFLAGS) -c $< -o $@
thread_mosq.o : thread_mosq.c
$(CC) $(LIB_CFLAGS) -c $< -o $@
time_mosq.o : time_mosq.c
$(CC) $(LIB_CFLAGS) -c $< -o $@
tls_mosq.o : tls_mosq.c
$(CC) $(LIB_CFLAGS) -c $< -o $@
util_mosq.o : util_mosq.c util_mosq.h
$(CC) $(LIB_CFLAGS) -c $< -o $@
will_mosq.o : will_mosq.c will_mosq.h
$(CC) $(LIB_CFLAGS) -c $< -o $@

18
lib/cpp/CMakeLists.txt Normal file
View File

@@ -0,0 +1,18 @@
include_directories(${mosquitto_SOURCE_DIR}/lib ${mosquitto_SOURCE_DIR}/lib/cpp
${STDBOOL_H_PATH} ${STDINT_H_PATH})
link_directories(${mosquitto_BINARY_DIR}/lib)
add_library(mosquittopp SHARED
mosquittopp.cpp mosquittopp.h)
target_link_libraries(mosquittopp mosquitto)
set_target_properties(mosquittopp PROPERTIES
VERSION ${VERSION}
SOVERSION 1
)
install(TARGETS mosquittopp RUNTIME DESTINATION ${BINDIR} LIBRARY DESTINATION ${LIBDIR})
install(FILES mosquittopp.h DESTINATION ${INCLUDEDIR})
if (UNIX)
install(CODE "EXEC_PROGRAM(/sbin/ldconfig)")
endif (UNIX)

31
lib/cpp/Makefile Normal file
View File

@@ -0,0 +1,31 @@
include ../../config.mk
ifneq ($(UNAME),SunOS)
LIB_LDFLAGS:=$(LDFLAGS) -Wl,-soname,libmosquittopp.so.${SOVERSION}
endif
.PHONY : clean install
all : libmosquittopp.so.${SOVERSION}
install : all
$(INSTALL) -d ${DESTDIR}$(prefix)/lib${LIB_SUFFIX}/
$(INSTALL) -s libmosquittopp.so.${SOVERSION} ${DESTDIR}${prefix}/lib${LIB_SUFFIX}/libmosquittopp.so.${SOVERSION}
ln -sf libmosquittopp.so.${SOVERSION} ${DESTDIR}${prefix}/lib${LIB_SUFFIX}/libmosquittopp.so
$(INSTALL) -d ${DESTDIR}${prefix}/include/
$(INSTALL) mosquittopp.h ${DESTDIR}${prefix}/include/mosquittopp.h
uninstall :
-rm -f ${DESTDIR}${prefix}/lib${LIB_SUFFIX}/libmosquittopp.so.${SOVERSION}
-rm -f ${DESTDIR}${prefix}/lib${LIB_SUFFIX}/libmosquittopp.so
-rm -f ${DESTDIR}${prefix}/include/mosquittopp.h
clean :
-rm -f *.o libmosquittopp.so.${SOVERSION}
libmosquittopp.so.${SOVERSION} : mosquittopp.o
$(CXX) -shared $(LIB_LDFLAGS) $< -o $@ ../libmosquitto.so.${SOVERSION}
mosquittopp.o : mosquittopp.cpp mosquittopp.h
$(CXX) $(LIB_CXXFLAGS) -c $< -o $@

292
lib/cpp/mosquittopp.cpp Normal file
View File

@@ -0,0 +1,292 @@
/*
Copyright (c) 2010-2014 Roger Light <roger@atchoo.org>
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:
Roger Light - initial implementation and documentation.
*/
#include <cstdlib>
#include <mosquitto.h>
#include <mosquittopp.h>
namespace mosqpp {
static void on_connect_wrapper(struct mosquitto *mosq, void *userdata, int rc)
{
class mosquittopp *m = (class mosquittopp *)userdata;
m->on_connect(rc);
}
static void on_disconnect_wrapper(struct mosquitto *mosq, void *userdata, int rc)
{
class mosquittopp *m = (class mosquittopp *)userdata;
m->on_disconnect(rc);
}
static void on_publish_wrapper(struct mosquitto *mosq, void *userdata, int mid)
{
class mosquittopp *m = (class mosquittopp *)userdata;
m->on_publish(mid);
}
static void on_message_wrapper(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message)
{
class mosquittopp *m = (class mosquittopp *)userdata;
m->on_message(message);
}
static void on_subscribe_wrapper(struct mosquitto *mosq, void *userdata, int mid, int qos_count, const int *granted_qos)
{
class mosquittopp *m = (class mosquittopp *)userdata;
m->on_subscribe(mid, qos_count, granted_qos);
}
static void on_unsubscribe_wrapper(struct mosquitto *mosq, void *userdata, int mid)
{
class mosquittopp *m = (class mosquittopp *)userdata;
m->on_unsubscribe(mid);
}
static void on_log_wrapper(struct mosquitto *mosq, void *userdata, int level, const char *str)
{
class mosquittopp *m = (class mosquittopp *)userdata;
m->on_log(level, str);
}
int lib_version(int *major, int *minor, int *revision)
{
if(major) *major = LIBMOSQUITTO_MAJOR;
if(minor) *minor = LIBMOSQUITTO_MINOR;
if(revision) *revision = LIBMOSQUITTO_REVISION;
return LIBMOSQUITTO_VERSION_NUMBER;
}
int lib_init()
{
return mosquitto_lib_init();
}
int lib_cleanup()
{
return mosquitto_lib_cleanup();
}
const char* strerror(int mosq_errno)
{
return mosquitto_strerror(mosq_errno);
}
const char* connack_string(int connack_code)
{
return mosquitto_connack_string(connack_code);
}
int sub_topic_tokenise(const char *subtopic, char ***topics, int *count)
{
return mosquitto_sub_topic_tokenise(subtopic, topics, count);
}
int sub_topic_tokens_free(char ***topics, int count)
{
return mosquitto_sub_topic_tokens_free(topics, count);
}
int topic_matches_sub(const char *sub, const char *topic, bool *result)
{
return mosquitto_topic_matches_sub(sub, topic, result);
}
mosquittopp::mosquittopp(const char *id, bool clean_session)
{
m_mosq = mosquitto_new(id, clean_session, this);
mosquitto_connect_callback_set(m_mosq, on_connect_wrapper);
mosquitto_disconnect_callback_set(m_mosq, on_disconnect_wrapper);
mosquitto_publish_callback_set(m_mosq, on_publish_wrapper);
mosquitto_message_callback_set(m_mosq, on_message_wrapper);
mosquitto_subscribe_callback_set(m_mosq, on_subscribe_wrapper);
mosquitto_unsubscribe_callback_set(m_mosq, on_unsubscribe_wrapper);
mosquitto_log_callback_set(m_mosq, on_log_wrapper);
}
mosquittopp::~mosquittopp()
{
mosquitto_destroy(m_mosq);
}
int mosquittopp::reinitialise(const char *id, bool clean_session)
{
int rc;
rc = mosquitto_reinitialise(m_mosq, id, clean_session, this);
if(rc == MOSQ_ERR_SUCCESS){
mosquitto_connect_callback_set(m_mosq, on_connect_wrapper);
mosquitto_disconnect_callback_set(m_mosq, on_disconnect_wrapper);
mosquitto_publish_callback_set(m_mosq, on_publish_wrapper);
mosquitto_message_callback_set(m_mosq, on_message_wrapper);
mosquitto_subscribe_callback_set(m_mosq, on_subscribe_wrapper);
mosquitto_unsubscribe_callback_set(m_mosq, on_unsubscribe_wrapper);
mosquitto_log_callback_set(m_mosq, on_log_wrapper);
}
return rc;
}
int mosquittopp::connect(const char *host, int port, int keepalive)
{
return mosquitto_connect(m_mosq, host, port, keepalive);
}
int mosquittopp::connect(const char *host, int port, int keepalive, const char *bind_address)
{
return mosquitto_connect_bind(m_mosq, host, port, keepalive, bind_address);
}
int mosquittopp::connect_async(const char *host, int port, int keepalive)
{
return mosquitto_connect_async(m_mosq, host, port, keepalive);
}
int mosquittopp::connect_async(const char *host, int port, int keepalive, const char *bind_address)
{
return mosquitto_connect_bind_async(m_mosq, host, port, keepalive, bind_address);
}
int mosquittopp::reconnect()
{
return mosquitto_reconnect(m_mosq);
}
int mosquittopp::reconnect_async()
{
return mosquitto_reconnect_async(m_mosq);
}
int mosquittopp::disconnect()
{
return mosquitto_disconnect(m_mosq);
}
int mosquittopp::socket()
{
return mosquitto_socket(m_mosq);
}
int mosquittopp::will_set(const char *topic, int payloadlen, const void *payload, int qos, bool retain)
{
return mosquitto_will_set(m_mosq, topic, payloadlen, payload, qos, retain);
}
int mosquittopp::will_clear()
{
return mosquitto_will_clear(m_mosq);
}
int mosquittopp::username_pw_set(const char *username, const char *password)
{
return mosquitto_username_pw_set(m_mosq, username, password);
}
int mosquittopp::publish(int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain)
{
return mosquitto_publish(m_mosq, mid, topic, payloadlen, payload, qos, retain);
}
void mosquittopp::reconnect_delay_set(unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff)
{
mosquitto_reconnect_delay_set(m_mosq, reconnect_delay, reconnect_delay_max, reconnect_exponential_backoff);
}
int mosquittopp::max_inflight_messages_set(unsigned int max_inflight_messages)
{
return mosquitto_max_inflight_messages_set(m_mosq, max_inflight_messages);
}
void mosquittopp::message_retry_set(unsigned int message_retry)
{
mosquitto_message_retry_set(m_mosq, message_retry);
}
int mosquittopp::subscribe(int *mid, const char *sub, int qos)
{
return mosquitto_subscribe(m_mosq, mid, sub, qos);
}
int mosquittopp::unsubscribe(int *mid, const char *sub)
{
return mosquitto_unsubscribe(m_mosq, mid, sub);
}
int mosquittopp::loop(int timeout, int max_packets)
{
return mosquitto_loop(m_mosq, timeout, max_packets);
}
int mosquittopp::loop_misc()
{
return mosquitto_loop_misc(m_mosq);
}
int mosquittopp::loop_read(int max_packets)
{
return mosquitto_loop_read(m_mosq, max_packets);
}
int mosquittopp::loop_write(int max_packets)
{
return mosquitto_loop_write(m_mosq, max_packets);
}
int mosquittopp::loop_forever(int timeout, int max_packets)
{
return mosquitto_loop_forever(m_mosq, timeout, max_packets);
}
int mosquittopp::loop_start()
{
return mosquitto_loop_start(m_mosq);
}
int mosquittopp::loop_stop(bool force)
{
return mosquitto_loop_stop(m_mosq, force);
}
bool mosquittopp::want_write()
{
return mosquitto_want_write(m_mosq);
}
void mosquittopp::user_data_set(void *userdata)
{
mosquitto_user_data_set(m_mosq, userdata);
}
int mosquittopp::tls_set(const char *cafile, const char *capath, const char *certfile, const char *keyfile, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata))
{
return mosquitto_tls_set(m_mosq, cafile, capath, certfile, keyfile, pw_callback);
}
int mosquittopp::tls_opts_set(int cert_reqs, const char *tls_version, const char *ciphers)
{
return mosquitto_tls_opts_set(m_mosq, cert_reqs, tls_version, ciphers);
}
int mosquittopp::tls_insecure_set(bool value)
{
return mosquitto_tls_insecure_set(m_mosq, value);
}
int mosquittopp::tls_psk_set(const char *psk, const char *identity, const char *ciphers)
{
return mosquitto_tls_psk_set(m_mosq, psk, identity, ciphers);
}
}

102
lib/cpp/mosquittopp.h Normal file
View File

@@ -0,0 +1,102 @@
/*
Copyright (c) 2010-2013 Roger Light <roger@atchoo.org>
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:
Roger Light - initial implementation and documentation.
*/
#ifndef _MOSQUITTOPP_H_
#define _MOSQUITTOPP_H_
#ifdef _WIN32
# ifdef mosquittopp_EXPORTS
# define mosqpp_EXPORT __declspec(dllexport)
# else
# define mosqpp_EXPORT __declspec(dllimport)
# endif
#else
# define mosqpp_EXPORT
#endif
#include <cstdlib>
#include <time.h>
#include <mosquitto.h>
namespace mosqpp {
mosqpp_EXPORT const char *strerror(int mosq_errno);
mosqpp_EXPORT const char *connack_string(int connack_code);
mosqpp_EXPORT int sub_topic_tokenise(const char *subtopic, char ***topics, int *count);
mosqpp_EXPORT int sub_topic_tokens_free(char ***topics, int count);
mosqpp_EXPORT int lib_version(int *major, int *minor, int *revision);
mosqpp_EXPORT int lib_init();
mosqpp_EXPORT int lib_cleanup();
mosqpp_EXPORT int topic_matches_sub(const char *sub, const char *topic, bool *result);
/*
* Class: mosquittopp
*
* A mosquitto client class. This is a C++ wrapper class for the mosquitto C
* library. Please see mosquitto.h for details of the functions.
*/
class mosqpp_EXPORT mosquittopp {
private:
struct mosquitto *m_mosq;
public:
mosquittopp(const char *id=NULL, bool clean_session=true);
~mosquittopp();
int reinitialise(const char *id, bool clean_session);
int socket();
int will_set(const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false);
int will_clear();
int username_pw_set(const char *username, const char *password=NULL);
int connect(const char *host, int port=1883, int keepalive=60);
int connect_async(const char *host, int port=1883, int keepalive=60);
int connect(const char *host, int port, int keepalive, const char *bind_address);
int connect_async(const char *host, int port, int keepalive, const char *bind_address);
int reconnect();
int reconnect_async();
int disconnect();
int publish(int *mid, const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false);
int subscribe(int *mid, const char *sub, int qos=0);
int unsubscribe(int *mid, const char *sub);
void reconnect_delay_set(unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff);
int max_inflight_messages_set(unsigned int max_inflight_messages);
void message_retry_set(unsigned int message_retry);
void user_data_set(void *userdata);
int tls_set(const char *cafile, const char *capath=NULL, const char *certfile=NULL, const char *keyfile=NULL, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)=NULL);
int tls_opts_set(int cert_reqs, const char *tls_version=NULL, const char *ciphers=NULL);
int tls_insecure_set(bool value);
int tls_psk_set(const char *psk, const char *identity, const char *ciphers=NULL);
int loop(int timeout=-1, int max_packets=1);
int loop_misc();
int loop_read(int max_packets=1);
int loop_write(int max_packets=1);
int loop_forever(int timeout=-1, int max_packets=1);
int loop_start();
int loop_stop(bool force=false);
bool want_write();
virtual void on_connect(int rc) {return;};
virtual void on_disconnect(int rc) {return;};
virtual void on_publish(int mid) {return;};
virtual void on_message(const struct mosquitto_message *message) {return;};
virtual void on_subscribe(int mid, int qos_count, const int *granted_qos) {return;};
virtual void on_unsubscribe(int mid) {return;};
virtual void on_log(int level, const char *str) {return;};
virtual void on_error() {return;};
};
}
#endif

13
lib/dummypthread.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef _DUMMYPTHREAD_H_
#define _DUMMYPTHREAD_H_
#define pthread_create(A, B, C, D)
#define pthread_join(A, B)
#define pthread_cancel(A)
#define pthread_mutex_init(A, B)
#define pthread_mutex_destroy(A)
#define pthread_mutex_lock(A)
#define pthread_mutex_unlock(A)
#endif

363
lib/jsws/mosquitto.js Normal file
View File

@@ -0,0 +1,363 @@
/*
Copyright (c) 2012 Roger Light <roger@atchoo.org>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of mosquitto nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/* Mosquitto MQTT Javascript/Websocket client */
/* Provides complete support for QoS 0.
* Will not cause an error on QoS 1/2 packets.
*/
var CONNECT = 0x10;
var CONNACK = 0x20;
var PUBLISH = 0x30;
var PUBACK = 0x40;
var PUBREC = 0x50;
var PUBREL = 0x60;
var PUBCOMP = 0x70;
var SUBSCRIBE = 0x80;
var SUBACK = 0x90;
var UNSUBSCRIBE = 0xA0;
var UNSUBACK = 0xB0;
var PINGREQ = 0xC0;
var PINGRESP = 0xD0;
var DISCONNECT = 0xE0;
function AB2S(buffer) {
var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for(var i=0; i<len; i++){
binary += String.fromCharCode(bytes[i]);
}
return binary;
}
function Mosquitto()
{
this.ws = null;
this.onconnect = null;
this.ondisconnect = null;
this.onmessage = null;
}
Mosquitto.prototype = {
mqtt_ping : function()
{
var buffer = new ArrayBuffer(2);
var i8V = new Int8Array(buffer);
i8V[0] = PINGREQ;
i8V[1] = 0;
if(this.ws.readyState == 1){
this.ws.send(buffer);
}else{
this.queue(buffer);
}
setTimeout(function(_this){_this.mqtt_ping();}, 60000, this);
},
connect : function(url, keepalive){
this.url = url;
this.keepalive = keepalive;
this.mid = 1;
this.out_queue = new Array();
this.ws = new WebSocket(url, 'mqttv3.1');
this.ws.binaryType = "arraybuffer";
this.ws.onopen = this.ws_onopen;
this.ws.onclose = this.ws_onclose;
this.ws.onmessage = this.ws_onmessage;
this.ws.m = this;
this.ws.onerror = function(evt){
alert(evt.data);
}
},
disconnect : function(){
if(this.ws.readyState == 1){
var buffer = new ArrayBuffer(2);
var i8V = new Int8Array(buffer);
i8V[0] = DISCONNECT;
i8V[1] = 0;
this.ws.send(buffer);
this.ws.close();
}
},
ws_onopen : function(evt) {
var buffer = new ArrayBuffer(1+1+12+2+20);
var i8V = new Int8Array(buffer);
i=0;
i8V[i++] = CONNECT;
i8V[i++] = 12+2+20;
i8V[i++] = 0;
i8V[i++] = 6;
str = "MQIsdp";
for(var j=0; j<str.length; j++){
i8V[i++] = str.charCodeAt(j);
}
i8V[i++] = 3;
i8V[i++] = 2;
i8V[i++] = 0;
i8V[i++] = 60;
i8V[i++] = 0;
i8V[i++] = 20;
var str = "mjsws/";
for(var j=0; j<str.length; j++){
i8V[i++] = str.charCodeAt(j);
}
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
for(var j=0; j<14; j++){
i8V[i++] = chars.charCodeAt(Math.floor(Math.random()*chars.length));
}
this.send(buffer);
while(this.m.out_queue.length > 0){
this.send(this.m.out_queue.pop());
}
setTimeout(function(_this){_this.mqtt_ping();}, 60000, this.m);
},
ws_onclose : function(evt) {
if(this.m.ondisconnect){
this.m.ondisconnect(evt.data);
}
},
ws_onmessage : function(evt) {
var i8V = new Int8Array(evt.data);
buffer = evt.data;
var q=0;
while(i8V.length > 0 && q < 1000){
q++;
switch(i8V[0] & 0xF0){
case CONNACK:
var rl = i8V[1];
var rc = i8V[2];
if(this.m.onconnect){
this.m.onconnect(rc);
}
buffer = buffer.slice(rl+2);
i8V = new Int8Array(buffer);
break;
case PUBLISH:
var i=1;
var mult = 1;
var rl = 0;
var count = 0;
var digit;
var qos = (i8V[0] & 0x06) >> 1;
var retain = (i8V[0] & 0x01);
var mid = 0;
do{
count++;
digit = i8V[i++];
rl += (digit & 127)*mult;
mult *= 128;
}while((digit & 128) != 0);
var topiclen = i8V[i++]*256 + i8V[i++];
var atopic = buffer.slice(i, i+topiclen);
i+=topiclen;
var topic = AB2S(atopic);
if(qos > 0){
mid = i8V[i++]*256 + i8V[i++];
}
var apayload = buffer.slice(i, rl+count+1);
var payload = AB2S(apayload);
buffer = buffer.slice(rl+1+count);
i8V = new Int8Array(buffer);
if(this.m.onmessage){
this.m.onmessage(topic, payload, qos, retain);
}
break;
case PUBREC:
case PUBREL:
case PUBACK:
case PUBCOMP:
case SUBACK:
case UNSUBACK:
case PINGRESP:
var rl = i8V[1];
buffer = buffer.slice(rl+2);
i8V = new Int8Array(buffer);
break;
}
}
},
get_remaining_count : function(remaining_length)
{
if(remaining_length >= 0 && remaining_length < 128){
return 1;
}else if(remaining_length >= 128 && remaining_length < 16384){
return 2;
}else if(remaining_length >= 16384 && remaining_length < 2097152){
return 3;
}else if(remaining_length >= 2097152 && remaining_length < 268435456){
return 4;
}else{
return -1;
}
},
generate_mid : function()
{
var mid = this.mid;
this.mid++;
if(this.mid == 256) this.mid = 0;
return mid;
},
queue : function(buffer)
{
this.out_queue.push(buffer);
},
send_cmd_with_mid : function(cmd, mid)
{
var buffer = new ArrayBuffer(4);
var i8V = new Int8Array(buffer);
i8V[0] = cmd;
i8V[1] = 2;
i8V[2] = mid%128;
i8V[3] = mid/128;
if(this.ws.readyState == 1){
this.ws.send(buffer);
}else{
this.queue(buffer);
}
},
unsubscribe : function(topic)
{
var rl = 2+2+topic.length;
var remaining_count = this.get_remaining_count(rl);
var buffer = new ArrayBuffer(1+remaining_count+rl);
var i8V = new Int8Array(buffer);
var i=0;
i8V[i++] = UNSUBSCRIBE | 0x02;
do{
digit = Math.floor(rl % 128);
rl = Math.floor(rl / 128);
if(rl > 0){
digit = digit | 0x80;
}
i8V[i++] = digit;
}while(rl > 0);
i8V[i++] = 0;
i8V[i++] = this.generate_mid();
i8V[i++] = 0;
i8V[i++] = topic.length;
for(var j=0; j<topic.length; j++){
i8V[i++] = topic.charCodeAt(j);
}
if(this.ws.readyState == 1){
this.ws.send(buffer);
}else{
this.queue(buffer);
}
},
subscribe : function(topic, qos)
{
if(qos != 0){
return 1;
}
var rl = 2+2+topic.length+1;
var remaining_count = this.get_remaining_count(rl);
var buffer = new ArrayBuffer(1+remaining_count+rl);
var i8V = new Int8Array(buffer);
var i=0;
i8V[i++] = SUBSCRIBE | 0x02;
do{
digit = Math.floor(rl % 128);
rl = Math.floor(rl / 128);
if(rl > 0){
digit = digit | 0x80;
}
i8V[i++] = digit;
}while(rl > 0);
i8V[i++] = 0;
i8V[i++] = this.generate_mid();
i8V[i++] = 0;
i8V[i++] = topic.length;
for(var j=0; j<topic.length; j++){
i8V[i++] = topic.charCodeAt(j);
}
i8V[i++] = qos;
if(this.ws.readyState == 1){
this.ws.send(buffer);
}else{
this.queue(buffer);
}
},
publish : function(topic, payload, qos, retain){
if(qos != 0) return 1;
var rl = 2+topic.length+payload.length;
var remaining_count = this.get_remaining_count(rl);
var buffer = new ArrayBuffer(1+remaining_count+rl);
var i8V = new Int8Array(buffer);
var i=0;
retain = retain?1:0;
i8V[i++] = PUBLISH | (qos<<1) | retain;
do{
digit = Math.floor(rl % 128);
rl = Math.floor(rl / 128);
if(rl > 0){
digit = digit | 0x80;
}
i8V[i++] = digit;
}while(rl > 0);
i8V[i++] = 0;
i8V[i++] = topic.length;
for(var j=0; j<topic.length; j++){
i8V[i++] = topic.charCodeAt(j);
}
for(var j=0; j<payload.length; j++){
i8V[i++] = payload.charCodeAt(j);
}
if(this.ws.readyState == 1){
this.ws.send(buffer);
}else{
this.queue(buffer);
}
}
}

71
lib/linker.version Normal file
View File

@@ -0,0 +1,71 @@
/* Linker version script - currently used here primarily to control which
* symbols are exported.
*/
MOSQ_1.0 {
global:
mosquitto_lib_version;
mosquitto_lib_init;
mosquitto_lib_cleanup;
mosquitto_new;
mosquitto_destroy;
mosquitto_reinitialise;
mosquitto_will_set;
mosquitto_will_clear;
mosquitto_username_pw_set;
mosquitto_connect;
mosquitto_connect_async;
mosquitto_reconnect;
mosquitto_disconnect;
mosquitto_publish;
mosquitto_subscribe;
mosquitto_unsubscribe;
mosquitto_message_copy;
mosquitto_message_free;
mosquitto_loop;
mosquitto_socket;
mosquitto_loop_start;
mosquitto_loop_stop;
mosquitto_loop_read;
mosquitto_loop_write;
mosquitto_loop_misc;
mosquitto_connect_callback_set;
mosquitto_disconnect_callback_set;
mosquitto_publish_callback_set;
mosquitto_message_callback_set;
mosquitto_subscribe_callback_set;
mosquitto_unsubscribe_callback_set;
mosquitto_log_callback_set;
mosquitto_message_retry_set;
mosquitto_want_write;
mosquitto_user_data_set;
mosquitto_strerror;
mosquitto_connack_string;
mosquitto_tls_set;
mosquitto_tls_opts_set;
mosquitto_tls_psk_set;
mosquitto_sub_topic_tokenise;
mosquitto_sub_topic_tokens_free;
mosquitto_topic_matches_sub;
local: *;
};
MOSQ_1.1 {
global:
mosquitto_loop_forever;
} MOSQ_1.0;
MOSQ_1.2 {
global:
mosquitto_connect_bind;
mosquitto_connect_bind_async;
mosquitto_max_inflight_messages_set;
mosquitto_reconnect_delay_set;
mosquitto_reconnect_async;
mosquitto_tls_insecure_set;
} MOSQ_1.1;
MOSQ_1.3 {
global:
mosquitto_connect_srv;
} MOSQ_1.2;

56
lib/logging_mosq.c Normal file
View File

@@ -0,0 +1,56 @@
/*
Copyright (c) 2009-2014 Roger Light <roger@atchoo.org>
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:
Roger Light - initial implementation and documentation.
*/
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <mosquitto_internal.h>
#include <mosquitto.h>
#include <memory_mosq.h>
int _mosquitto_log_printf(struct mosquitto *mosq, int priority, const char *fmt, ...)
{
va_list va;
char *s;
int len;
assert(mosq);
assert(fmt);
pthread_mutex_lock(&mosq->log_callback_mutex);
if(mosq->on_log){
len = strlen(fmt) + 500;
s = _mosquitto_malloc(len*sizeof(char));
if(!s){
pthread_mutex_unlock(&mosq->log_callback_mutex);
return MOSQ_ERR_NOMEM;
}
va_start(va, fmt);
vsnprintf(s, len, fmt, va);
va_end(va);
s[len-1] = '\0'; /* Ensure string is null terminated. */
mosq->on_log(mosq, mosq->userdata, priority, s);
_mosquitto_free(s);
}
pthread_mutex_unlock(&mosq->log_callback_mutex);
return MOSQ_ERR_SUCCESS;
}

23
lib/logging_mosq.h Normal file
View File

@@ -0,0 +1,23 @@
/*
Copyright (c) 2009-2014 Roger Light <roger@atchoo.org>
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:
Roger Light - initial implementation and documentation.
*/
#ifndef _LOGGING_MOSQ_H_
#define _LOGGING_MOSQ_H_
#include <mosquitto.h>
int _mosquitto_log_printf(struct mosquitto *mosq, int priority, const char *fmt, ...);
#endif

121
lib/memory_mosq.c Normal file
View File

@@ -0,0 +1,121 @@
/*
Copyright (c) 2009-2014 Roger Light <roger@atchoo.org>
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:
Roger Light - initial implementation and documentation.
*/
#include <config.h>
#include <stdlib.h>
#include <string.h>
#include <memory_mosq.h>
#ifdef REAL_WITH_MEMORY_TRACKING
# if defined(__APPLE__)
# include <malloc/malloc.h>
# define malloc_usable_size malloc_size
# elif defined(__FreeBSD__)
# include <malloc_np.h>
# else
# include <malloc.h>
# endif
#endif
#ifdef REAL_WITH_MEMORY_TRACKING
static unsigned long memcount = 0;
static unsigned long max_memcount = 0;
#endif
void *_mosquitto_calloc(size_t nmemb, size_t size)
{
void *mem = calloc(nmemb, size);
#ifdef REAL_WITH_MEMORY_TRACKING
memcount += malloc_usable_size(mem);
if(memcount > max_memcount){
max_memcount = memcount;
}
#endif
return mem;
}
void _mosquitto_free(void *mem)
{
#ifdef REAL_WITH_MEMORY_TRACKING
memcount -= malloc_usable_size(mem);
#endif
free(mem);
}
void *_mosquitto_malloc(size_t size)
{
void *mem = malloc(size);
#ifdef REAL_WITH_MEMORY_TRACKING
memcount += malloc_usable_size(mem);
if(memcount > max_memcount){
max_memcount = memcount;
}
#endif
return mem;
}
#ifdef REAL_WITH_MEMORY_TRACKING
unsigned long _mosquitto_memory_used(void)
{
return memcount;
}
unsigned long _mosquitto_max_memory_used(void)
{
return max_memcount;
}
#endif
void *_mosquitto_realloc(void *ptr, size_t size)
{
void *mem;
#ifdef REAL_WITH_MEMORY_TRACKING
if(ptr){
memcount -= malloc_usable_size(ptr);
}
#endif
mem = realloc(ptr, size);
#ifdef REAL_WITH_MEMORY_TRACKING
memcount += malloc_usable_size(mem);
if(memcount > max_memcount){
max_memcount = memcount;
}
#endif
return mem;
}
char *_mosquitto_strdup(const char *s)
{
char *str = strdup(s);
#ifdef REAL_WITH_MEMORY_TRACKING
memcount += malloc_usable_size(str);
if(memcount > max_memcount){
max_memcount = memcount;
}
#endif
return str;
}

37
lib/memory_mosq.h Normal file
View File

@@ -0,0 +1,37 @@
/*
Copyright (c) 2010-2014 Roger Light <roger@atchoo.org>
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:
Roger Light - initial implementation and documentation.
*/
#ifndef _MEMORY_MOSQ_H_
#define _MEMORY_MOSQ_H_
#include <stdio.h>
#include <sys/types.h>
#if defined(WITH_MEMORY_TRACKING) && defined(WITH_BROKER) && !defined(WIN32) && !defined(__SYMBIAN32__)
#define REAL_WITH_MEMORY_TRACKING
#endif
void *_mosquitto_calloc(size_t nmemb, size_t size);
void _mosquitto_free(void *mem);
void *_mosquitto_malloc(size_t size);
#ifdef REAL_WITH_MEMORY_TRACKING
unsigned long _mosquitto_memory_used(void);
unsigned long _mosquitto_max_memory_used(void);
#endif
void *_mosquitto_realloc(void *ptr, size_t size);
char *_mosquitto_strdup(const char *s);
#endif

387
lib/messages_mosq.c Normal file
View File

@@ -0,0 +1,387 @@
/*
Copyright (c) 2010-2014 Roger Light <roger@atchoo.org>
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:
Roger Light - initial implementation and documentation.
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <mosquitto_internal.h>
#include <mosquitto.h>
#include <memory_mosq.h>
#include <messages_mosq.h>
#include <send_mosq.h>
#include <time_mosq.h>
void _mosquitto_message_cleanup(struct mosquitto_message_all **message)
{
struct mosquitto_message_all *msg;
if(!message || !*message) return;
msg = *message;
if(msg->msg.topic) _mosquitto_free(msg->msg.topic);
if(msg->msg.payload) _mosquitto_free(msg->msg.payload);
_mosquitto_free(msg);
}
void _mosquitto_message_cleanup_all(struct mosquitto *mosq)
{
struct mosquitto_message_all *tmp;
assert(mosq);
while(mosq->in_messages){
tmp = mosq->in_messages->next;
_mosquitto_message_cleanup(&mosq->in_messages);
mosq->in_messages = tmp;
}
while(mosq->out_messages){
tmp = mosq->out_messages->next;
_mosquitto_message_cleanup(&mosq->out_messages);
mosq->out_messages = tmp;
}
}
int mosquitto_message_copy(struct mosquitto_message *dst, const struct mosquitto_message *src)
{
if(!dst || !src) return MOSQ_ERR_INVAL;
dst->mid = src->mid;
dst->topic = _mosquitto_strdup(src->topic);
if(!dst->topic) return MOSQ_ERR_NOMEM;
dst->qos = src->qos;
dst->retain = src->retain;
if(src->payloadlen){
dst->payload = _mosquitto_malloc(src->payloadlen);
if(!dst->payload){
_mosquitto_free(dst->topic);
return MOSQ_ERR_NOMEM;
}
memcpy(dst->payload, src->payload, src->payloadlen);
dst->payloadlen = src->payloadlen;
}else{
dst->payloadlen = 0;
dst->payload = NULL;
}
return MOSQ_ERR_SUCCESS;
}
int _mosquitto_message_delete(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir)
{
struct mosquitto_message_all *message;
int rc;
assert(mosq);
rc = _mosquitto_message_remove(mosq, mid, dir, &message);
if(rc == MOSQ_ERR_SUCCESS){
_mosquitto_message_cleanup(&message);
}
return rc;
}
void mosquitto_message_free(struct mosquitto_message **message)
{
struct mosquitto_message *msg;
if(!message || !*message) return;
msg = *message;
if(msg->topic) _mosquitto_free(msg->topic);
if(msg->payload) _mosquitto_free(msg->payload);
_mosquitto_free(msg);
}
void _mosquitto_message_queue(struct mosquitto *mosq, struct mosquitto_message_all *message, enum mosquitto_msg_direction dir)
{
/* mosq->*_message_mutex should be locked before entering this function */
assert(mosq);
assert(message);
if(dir == mosq_md_out){
mosq->out_queue_len++;
message->next = NULL;
if(mosq->out_messages_last){
mosq->out_messages_last->next = message;
}else{
mosq->out_messages = message;
}
mosq->out_messages_last = message;
}else{
mosq->in_queue_len++;
if(message->msg.qos > 0 && (mosq->max_inflight_messages == 0 || mosq->inflight_messages < mosq->max_inflight_messages)){
mosq->inflight_messages++;
}
message->next = NULL;
if(mosq->in_messages_last){
mosq->in_messages_last->next = message;
}else{
mosq->in_messages = message;
}
mosq->in_messages_last = message;
}
}
void _mosquitto_messages_reconnect_reset(struct mosquitto *mosq)
{
struct mosquitto_message_all *message;
struct mosquitto_message_all *prev = NULL;
assert(mosq);
pthread_mutex_lock(&mosq->in_message_mutex);
message = mosq->in_messages;
mosq->in_queue_len = 0;
while(message){
mosq->in_queue_len++;
message->timestamp = 0;
if(message->msg.qos != 2){
if(prev){
prev->next = message->next;
_mosquitto_message_cleanup(&message);
message = prev;
}else{
mosq->in_messages = message->next;
_mosquitto_message_cleanup(&message);
message = mosq->in_messages;
}
}else{
/* Message state can be preserved here because it should match
* whatever the client has got. */
}
prev = message;
message = message->next;
}
mosq->in_messages_last = prev;
pthread_mutex_unlock(&mosq->in_message_mutex);
pthread_mutex_lock(&mosq->out_message_mutex);
mosq->inflight_messages = 0;
message = mosq->out_messages;
mosq->out_queue_len = 0;
while(message){
mosq->out_queue_len++;
message->timestamp = 0;
if(message->msg.qos > 0){
mosq->inflight_messages++;
}
if(mosq->max_inflight_messages == 0 || mosq->inflight_messages < mosq->max_inflight_messages){
if(message->msg.qos == 1){
message->state = mosq_ms_wait_for_puback;
}else if(message->msg.qos == 2){
/* Should be able to preserve state. */
}
}else{
message->state = mosq_ms_invalid;
}
prev = message;
message = message->next;
}
mosq->out_messages_last = prev;
pthread_mutex_unlock(&mosq->out_message_mutex);
}
int _mosquitto_message_remove(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, struct mosquitto_message_all **message)
{
struct mosquitto_message_all *cur, *prev = NULL;
bool found = false;
int rc;
assert(mosq);
assert(message);
if(dir == mosq_md_out){
pthread_mutex_lock(&mosq->out_message_mutex);
cur = mosq->out_messages;
while(cur){
if(cur->msg.mid == mid){
if(prev){
prev->next = cur->next;
}else{
mosq->out_messages = cur->next;
}
*message = cur;
mosq->out_queue_len--;
if(cur->next == NULL){
mosq->out_messages_last = prev;
}else if(!mosq->out_messages){
mosq->out_messages_last = NULL;
}
if(cur->msg.qos > 0){
mosq->inflight_messages--;
}
found = true;
break;
}
prev = cur;
cur = cur->next;
}
if(found){
cur = mosq->out_messages;
while(cur){
if(mosq->max_inflight_messages == 0 || mosq->inflight_messages < mosq->max_inflight_messages){
if(cur->msg.qos > 0 && cur->state == mosq_ms_invalid){
mosq->inflight_messages++;
if(cur->msg.qos == 1){
cur->state = mosq_ms_wait_for_puback;
}else if(cur->msg.qos == 2){
cur->state = mosq_ms_wait_for_pubrec;
}
rc = _mosquitto_send_publish(mosq, cur->msg.mid, cur->msg.topic, cur->msg.payloadlen, cur->msg.payload, cur->msg.qos, cur->msg.retain, cur->dup);
if(rc){
pthread_mutex_unlock(&mosq->out_message_mutex);
return rc;
}
}
}else{
pthread_mutex_unlock(&mosq->out_message_mutex);
return MOSQ_ERR_SUCCESS;
}
cur = cur->next;
}
pthread_mutex_unlock(&mosq->out_message_mutex);
return MOSQ_ERR_SUCCESS;
}else{
pthread_mutex_unlock(&mosq->out_message_mutex);
return MOSQ_ERR_NOT_FOUND;
}
}else{
pthread_mutex_lock(&mosq->in_message_mutex);
cur = mosq->in_messages;
while(cur){
if(cur->msg.mid == mid){
if(prev){
prev->next = cur->next;
}else{
mosq->in_messages = cur->next;
}
*message = cur;
mosq->in_queue_len--;
if(cur->next == NULL){
mosq->in_messages_last = prev;
}else if(!mosq->in_messages){
mosq->in_messages_last = NULL;
}
if(cur->msg.qos == 2){
mosq->inflight_messages--;
}
found = true;
break;
}
prev = cur;
cur = cur->next;
}
pthread_mutex_unlock(&mosq->in_message_mutex);
if(found){
return MOSQ_ERR_SUCCESS;
}else{
return MOSQ_ERR_NOT_FOUND;
}
}
}
#ifdef WITH_THREADING
void _mosquitto_message_retry_check_actual(struct mosquitto *mosq, struct mosquitto_message_all *messages, pthread_mutex_t mutex)
#else
void _mosquitto_message_retry_check_actual(struct mosquitto *mosq, struct mosquitto_message_all *messages)
#endif
{
time_t now = mosquitto_time();
assert(mosq);
#ifdef WITH_THREADING
pthread_mutex_lock(&mutex);
#endif
while(messages){
if(messages->timestamp + mosq->message_retry < now){
switch(messages->state){
case mosq_ms_wait_for_puback:
case mosq_ms_wait_for_pubrec:
messages->timestamp = now;
messages->dup = true;
_mosquitto_send_publish(mosq, messages->msg.mid, messages->msg.topic, messages->msg.payloadlen, messages->msg.payload, messages->msg.qos, messages->msg.retain, messages->dup);
break;
case mosq_ms_wait_for_pubrel:
messages->timestamp = now;
messages->dup = true;
_mosquitto_send_pubrec(mosq, messages->msg.mid);
break;
case mosq_ms_wait_for_pubcomp:
messages->timestamp = now;
messages->dup = true;
_mosquitto_send_pubrel(mosq, messages->msg.mid, true);
break;
default:
break;
}
}
messages = messages->next;
}
#ifdef WITH_THREADING
pthread_mutex_unlock(&mutex);
#endif
}
void _mosquitto_message_retry_check(struct mosquitto *mosq)
{
#ifdef WITH_THREADING
_mosquitto_message_retry_check_actual(mosq, mosq->out_messages, mosq->out_message_mutex);
_mosquitto_message_retry_check_actual(mosq, mosq->in_messages, mosq->in_message_mutex);
#else
_mosquitto_message_retry_check_actual(mosq, mosq->out_messages);
_mosquitto_message_retry_check_actual(mosq, mosq->in_messages);
#endif
}
void mosquitto_message_retry_set(struct mosquitto *mosq, unsigned int message_retry)
{
assert(mosq);
if(mosq) mosq->message_retry = message_retry;
}
int _mosquitto_message_out_update(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_state state)
{
struct mosquitto_message_all *message;
assert(mosq);
pthread_mutex_lock(&mosq->out_message_mutex);
message = mosq->out_messages;
while(message){
if(message->msg.mid == mid){
message->state = state;
message->timestamp = mosquitto_time();
pthread_mutex_unlock(&mosq->out_message_mutex);
return MOSQ_ERR_SUCCESS;
}
message = message->next;
}
pthread_mutex_unlock(&mosq->out_message_mutex);
return MOSQ_ERR_NOT_FOUND;
}
int mosquitto_max_inflight_messages_set(struct mosquitto *mosq, unsigned int max_inflight_messages)
{
if(!mosq) return MOSQ_ERR_INVAL;
mosq->max_inflight_messages = max_inflight_messages;
return MOSQ_ERR_SUCCESS;
}

31
lib/messages_mosq.h Normal file
View File

@@ -0,0 +1,31 @@
/*
Copyright (c) 2010-2014 Roger Light <roger@atchoo.org>
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:
Roger Light - initial implementation and documentation.
*/
#ifndef _MESSAGES_MOSQ_H_
#define _MESSAGES_MOSQ_H_
#include <mosquitto_internal.h>
#include <mosquitto.h>
void _mosquitto_message_cleanup_all(struct mosquitto *mosq);
void _mosquitto_message_cleanup(struct mosquitto_message_all **message);
int _mosquitto_message_delete(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir);
void _mosquitto_message_queue(struct mosquitto *mosq, struct mosquitto_message_all *message, enum mosquitto_msg_direction dir);
void _mosquitto_messages_reconnect_reset(struct mosquitto *mosq);
int _mosquitto_message_remove(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, struct mosquitto_message_all **message);
void _mosquitto_message_retry_check(struct mosquitto *mosq);
int _mosquitto_message_out_update(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_state state);
#endif

1293
lib/mosquitto.c Normal file

File diff suppressed because it is too large Load Diff

1409
lib/mosquitto.h Normal file

File diff suppressed because it is too large Load Diff

230
lib/mosquitto_internal.h Normal file
View File

@@ -0,0 +1,230 @@
/*
Copyright (c) 2010-2014 Roger Light <roger@atchoo.org>
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:
Roger Light - initial implementation and documentation.
*/
#ifndef _MOSQUITTO_INTERNAL_H_
#define _MOSQUITTO_INTERNAL_H_
#include <config.h>
#ifdef WIN32
# include <winsock2.h>
#endif
#ifdef WITH_TLS
#include <openssl/ssl.h>
#endif
#include <stdlib.h>
#if defined(WITH_THREADING) && !defined(WITH_BROKER)
# include <pthread.h>
#else
# include <dummypthread.h>
#endif
#ifdef WITH_SRV
# include <ares.h>
#endif
#ifdef WIN32
# if _MSC_VER < 1600
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
# else
# include <stdint.h>
# endif
#else
# include <stdint.h>
#endif
#include "mosquitto.h"
#include "time_mosq.h"
#ifdef WITH_BROKER
struct mosquitto_client_msg;
#endif
enum mosquitto_msg_direction {
mosq_md_in = 0,
mosq_md_out = 1
};
enum mosquitto_msg_state {
mosq_ms_invalid = 0,
mosq_ms_publish_qos0 = 1,
mosq_ms_publish_qos1 = 2,
mosq_ms_wait_for_puback = 3,
mosq_ms_publish_qos2 = 4,
mosq_ms_wait_for_pubrec = 5,
mosq_ms_resend_pubrel = 6,
mosq_ms_wait_for_pubrel = 7,
mosq_ms_resend_pubcomp = 8,
mosq_ms_wait_for_pubcomp = 9,
mosq_ms_send_pubrec = 10,
mosq_ms_queued = 11
};
enum mosquitto_client_state {
mosq_cs_new = 0,
mosq_cs_connected = 1,
mosq_cs_disconnecting = 2,
mosq_cs_connect_async = 3,
mosq_cs_connect_pending = 4,
mosq_cs_connect_srv = 5
};
enum _mosquitto_protocol {
mosq_p_invalid = 0,
mosq_p_mqtt31 = 1,
mosq_p_mqtt311 = 2,
mosq_p_mqtts = 3
};
enum _mosquitto_transport {
mosq_t_invalid = 0,
mosq_t_tcp = 1,
mosq_t_ws = 2,
mosq_t_sctp = 3
};
struct _mosquitto_packet{
uint8_t command;
uint8_t have_remaining;
uint8_t remaining_count;
uint16_t mid;
uint32_t remaining_mult;
uint32_t remaining_length;
uint32_t packet_length;
uint32_t to_process;
uint32_t pos;
uint8_t *payload;
struct _mosquitto_packet *next;
};
struct mosquitto_message_all{
struct mosquitto_message_all *next;
time_t timestamp;
//enum mosquitto_msg_direction direction;
enum mosquitto_msg_state state;
bool dup;
struct mosquitto_message msg;
};
struct mosquitto {
#ifndef WIN32
int sock;
# ifndef WITH_BROKER
int sockpairR, sockpairW;
# endif
#else
SOCKET sock;
# ifndef WITH_BROKER
SOCKET sockpairR, sockpairW;
# endif
#endif
enum _mosquitto_protocol protocol;
char *address;
char *id;
char *username;
char *password;
uint16_t keepalive;
bool clean_session;
enum mosquitto_client_state state;
time_t last_msg_in;
time_t last_msg_out;
time_t ping_t;
uint16_t last_mid;
struct _mosquitto_packet in_packet;
struct _mosquitto_packet *current_out_packet;
struct _mosquitto_packet *out_packet;
struct mosquitto_message *will;
#ifdef WITH_TLS
SSL *ssl;
SSL_CTX *ssl_ctx;
char *tls_cafile;
char *tls_capath;
char *tls_certfile;
char *tls_keyfile;
int (*tls_pw_callback)(char *buf, int size, int rwflag, void *userdata);
int tls_cert_reqs;
char *tls_version;
char *tls_ciphers;
char *tls_psk;
char *tls_psk_identity;
bool tls_insecure;
#endif
bool want_write;
#if defined(WITH_THREADING) && !defined(WITH_BROKER)
pthread_mutex_t callback_mutex;
pthread_mutex_t log_callback_mutex;
pthread_mutex_t msgtime_mutex;
pthread_mutex_t out_packet_mutex;
pthread_mutex_t current_out_packet_mutex;
pthread_mutex_t state_mutex;
pthread_mutex_t in_message_mutex;
pthread_mutex_t out_message_mutex;
pthread_t thread_id;
#endif
#ifdef WITH_BROKER
bool is_bridge;
struct _mqtt3_bridge *bridge;
struct mosquitto_client_msg *msgs;
struct mosquitto_client_msg *last_msg;
int msg_count;
int msg_count12;
struct _mosquitto_acl_user *acl_list;
struct _mqtt3_listener *listener;
time_t disconnect_t;
int pollfd_index;
int db_index;
struct _mosquitto_packet *out_packet_last;
bool is_dropping;
#else
void *userdata;
bool in_callback;
unsigned int message_retry;
time_t last_retry_check;
struct mosquitto_message_all *in_messages;
struct mosquitto_message_all *in_messages_last;
struct mosquitto_message_all *out_messages;
struct mosquitto_message_all *out_messages_last;
void (*on_connect)(struct mosquitto *, void *userdata, int rc);
void (*on_disconnect)(struct mosquitto *, void *userdata, int rc);
void (*on_publish)(struct mosquitto *, void *userdata, int mid);
void (*on_message)(struct mosquitto *, void *userdata, const struct mosquitto_message *message);
void (*on_subscribe)(struct mosquitto *, void *userdata, int mid, int qos_count, const int *granted_qos);
void (*on_unsubscribe)(struct mosquitto *, void *userdata, int mid);
void (*on_log)(struct mosquitto *, void *userdata, int level, const char *str);
//void (*on_error)();
char *host;
int port;
int in_queue_len;
int out_queue_len;
char *bind_address;
unsigned int reconnect_delay;
unsigned int reconnect_delay_max;
bool reconnect_exponential_backoff;
bool threaded;
struct _mosquitto_packet *out_packet_last;
int inflight_messages;
int max_inflight_messages;
# ifdef WITH_SRV
ares_channel achan;
# endif
#endif
};
#endif

53
lib/mqtt3_protocol.h Normal file
View File

@@ -0,0 +1,53 @@
/*
Copyright (c) 2009-2014 Roger Light <roger@atchoo.org>
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:
Roger Light - initial implementation and documentation.
*/
#ifndef _MQTT3_PROTOCOL_H_
#define _MQTT3_PROTOCOL_H_
/* For version 3 of the MQTT protocol */
#define PROTOCOL_NAME_v31 "MQIsdp"
#define PROTOCOL_VERSION_v31 3
#define PROTOCOL_NAME_v311 "MQTT"
#define PROTOCOL_VERSION_v311 4
/* Message types */
#define CONNECT 0x10
#define CONNACK 0x20
#define PUBLISH 0x30
#define PUBACK 0x40
#define PUBREC 0x50
#define PUBREL 0x60
#define PUBCOMP 0x70
#define SUBSCRIBE 0x80
#define SUBACK 0x90
#define UNSUBSCRIBE 0xA0
#define UNSUBACK 0xB0
#define PINGREQ 0xC0
#define PINGRESP 0xD0
#define DISCONNECT 0xE0
#define CONNACK_ACCEPTED 0
#define CONNACK_REFUSED_PROTOCOL_VERSION 1
#define CONNACK_REFUSED_IDENTIFIER_REJECTED 2
#define CONNACK_REFUSED_SERVER_UNAVAILABLE 3
#define CONNACK_REFUSED_BAD_USERNAME_PASSWORD 4
#define CONNACK_REFUSED_NOT_AUTHORIZED 5
#define MQTT_MAX_PAYLOAD 268435455
#endif

1116
lib/net_mosq.c Normal file

File diff suppressed because it is too large Load Diff

91
lib/net_mosq.h Normal file
View File

@@ -0,0 +1,91 @@
/*
Copyright (c) 2010-2014 Roger Light <roger@atchoo.org>
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:
Roger Light - initial implementation and documentation.
*/
#ifndef _NET_MOSQ_H_
#define _NET_MOSQ_H_
#ifndef WIN32
#include <unistd.h>
#else
#include <winsock2.h>
typedef int ssize_t;
#endif
#include <mosquitto_internal.h>
#include <mosquitto.h>
#ifdef WITH_BROKER
struct mosquitto_db;
#endif
#ifdef WIN32
# define COMPAT_CLOSE(a) closesocket(a)
# define COMPAT_ECONNRESET WSAECONNRESET
# define COMPAT_EWOULDBLOCK WSAEWOULDBLOCK
#else
# define COMPAT_CLOSE(a) close(a)
# define COMPAT_ECONNRESET ECONNRESET
# define COMPAT_EWOULDBLOCK EWOULDBLOCK
#endif
#ifndef WIN32
#else
#endif
/* For when not using winsock libraries. */
#ifndef INVALID_SOCKET
#define INVALID_SOCKET -1
#endif
/* Macros for accessing the MSB and LSB of a uint16_t */
#define MOSQ_MSB(A) (uint8_t)((A & 0xFF00) >> 8)
#define MOSQ_LSB(A) (uint8_t)(A & 0x00FF)
void _mosquitto_net_init(void);
void _mosquitto_net_cleanup(void);
void _mosquitto_packet_cleanup(struct _mosquitto_packet *packet);
int _mosquitto_packet_queue(struct mosquitto *mosq, struct _mosquitto_packet *packet);
int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t port, const char *bind_address, bool blocking);
int _mosquitto_socket_close(struct mosquitto *mosq);
int _mosquitto_try_connect(const char *host, uint16_t port, int *sock, const char *bind_address, bool blocking);
int _mosquitto_socket_nonblock(int sock);
int _mosquitto_socketpair(int *sp1, int *sp2);
int _mosquitto_read_byte(struct _mosquitto_packet *packet, uint8_t *byte);
int _mosquitto_read_bytes(struct _mosquitto_packet *packet, void *bytes, uint32_t count);
int _mosquitto_read_string(struct _mosquitto_packet *packet, char **str);
int _mosquitto_read_uint16(struct _mosquitto_packet *packet, uint16_t *word);
void _mosquitto_write_byte(struct _mosquitto_packet *packet, uint8_t byte);
void _mosquitto_write_bytes(struct _mosquitto_packet *packet, const void *bytes, uint32_t count);
void _mosquitto_write_string(struct _mosquitto_packet *packet, const char *str, uint16_t length);
void _mosquitto_write_uint16(struct _mosquitto_packet *packet, uint16_t word);
ssize_t _mosquitto_net_read(struct mosquitto *mosq, void *buf, size_t count);
ssize_t _mosquitto_net_write(struct mosquitto *mosq, void *buf, size_t count);
int _mosquitto_packet_write(struct mosquitto *mosq);
#ifdef WITH_BROKER
int _mosquitto_packet_read(struct mosquitto_db *db, struct mosquitto *mosq);
#else
int _mosquitto_packet_read(struct mosquitto *mosq);
#endif
#ifdef WITH_TLS
int _mosquitto_socket_apply_tls(struct mosquitto *mosq);
#endif
#endif

155
lib/read_handle.c Normal file
View File

@@ -0,0 +1,155 @@
/*
Copyright (c) 2009-2014 Roger Light <roger@atchoo.org>
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:
Roger Light - initial implementation and documentation.
*/
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <mosquitto.h>
#include <logging_mosq.h>
#include <memory_mosq.h>
#include <messages_mosq.h>
#include <mqtt3_protocol.h>
#include <net_mosq.h>
#include <read_handle.h>
#include <send_mosq.h>
#include <time_mosq.h>
#include <util_mosq.h>
int _mosquitto_packet_handle(struct mosquitto *mosq)
{
assert(mosq);
switch((mosq->in_packet.command)&0xF0){
case PINGREQ:
return _mosquitto_handle_pingreq(mosq);
case PINGRESP:
return _mosquitto_handle_pingresp(mosq);
case PUBACK:
return _mosquitto_handle_pubackcomp(mosq, "PUBACK");
case PUBCOMP:
return _mosquitto_handle_pubackcomp(mosq, "PUBCOMP");
case PUBLISH:
return _mosquitto_handle_publish(mosq);
case PUBREC:
return _mosquitto_handle_pubrec(mosq);
case PUBREL:
return _mosquitto_handle_pubrel(NULL, mosq);
case CONNACK:
return _mosquitto_handle_connack(mosq);
case SUBACK:
return _mosquitto_handle_suback(mosq);
case UNSUBACK:
return _mosquitto_handle_unsuback(mosq);
default:
/* If we don't recognise the command, return an error straight away. */
_mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unrecognised command %d\n", (mosq->in_packet.command)&0xF0);
return MOSQ_ERR_PROTOCOL;
}
}
int _mosquitto_handle_publish(struct mosquitto *mosq)
{
uint8_t header;
struct mosquitto_message_all *message;
int rc = 0;
uint16_t mid;
assert(mosq);
message = _mosquitto_calloc(1, sizeof(struct mosquitto_message_all));
if(!message) return MOSQ_ERR_NOMEM;
header = mosq->in_packet.command;
message->dup = (header & 0x08)>>3;
message->msg.qos = (header & 0x06)>>1;
message->msg.retain = (header & 0x01);
rc = _mosquitto_read_string(&mosq->in_packet, &message->msg.topic);
if(rc){
_mosquitto_message_cleanup(&message);
return rc;
}
if(!strlen(message->msg.topic)){
_mosquitto_message_cleanup(&message);
return MOSQ_ERR_PROTOCOL;
}
if(message->msg.qos > 0){
rc = _mosquitto_read_uint16(&mosq->in_packet, &mid);
if(rc){
_mosquitto_message_cleanup(&message);
return rc;
}
message->msg.mid = (int)mid;
}
message->msg.payloadlen = mosq->in_packet.remaining_length - mosq->in_packet.pos;
if(message->msg.payloadlen){
message->msg.payload = _mosquitto_calloc(message->msg.payloadlen+1, sizeof(uint8_t));
if(!message->msg.payload){
_mosquitto_message_cleanup(&message);
return MOSQ_ERR_NOMEM;
}
rc = _mosquitto_read_bytes(&mosq->in_packet, message->msg.payload, message->msg.payloadlen);
if(rc){
_mosquitto_message_cleanup(&message);
return rc;
}
}
_mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG,
"Client %s received PUBLISH (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes))",
mosq->id, message->dup, message->msg.qos, message->msg.retain,
message->msg.mid, message->msg.topic,
(long)message->msg.payloadlen);
message->timestamp = mosquitto_time();
switch(message->msg.qos){
case 0:
pthread_mutex_lock(&mosq->callback_mutex);
if(mosq->on_message){
mosq->in_callback = true;
mosq->on_message(mosq, mosq->userdata, &message->msg);
mosq->in_callback = false;
}
pthread_mutex_unlock(&mosq->callback_mutex);
_mosquitto_message_cleanup(&message);
return MOSQ_ERR_SUCCESS;
case 1:
rc = _mosquitto_send_puback(mosq, message->msg.mid);
pthread_mutex_lock(&mosq->callback_mutex);
if(mosq->on_message){
mosq->in_callback = true;
mosq->on_message(mosq, mosq->userdata, &message->msg);
mosq->in_callback = false;
}
pthread_mutex_unlock(&mosq->callback_mutex);
_mosquitto_message_cleanup(&message);
return rc;
case 2:
rc = _mosquitto_send_pubrec(mosq, message->msg.mid);
pthread_mutex_lock(&mosq->in_message_mutex);
message->state = mosq_ms_wait_for_pubrel;
_mosquitto_message_queue(mosq, message, mosq_md_in);
pthread_mutex_unlock(&mosq->in_message_mutex);
return rc;
default:
_mosquitto_message_cleanup(&message);
return MOSQ_ERR_PROTOCOL;
}
}

Some files were not shown because too many files have changed in this diff Show More