mirror of
https://github.com/eclipse/mosquitto.git
synced 2025-05-08 16:52:13 +08:00
Merge branch 'master'
Conflicts: ChangeLog.txt config.mk src/context.c src/loop.c src/subs.c test/broker/01-connect-bad-packet.py test/broker/02-subpub-qos1-bad-pubcomp.py test/broker/02-subpub-qos1-bad-pubrec.py test/broker/02-subpub-qos2-bad-puback-1.py test/broker/02-subpub-qos2-bad-puback-2.py test/broker/02-subpub-qos2-bad-pubcomp.py test/broker/02-subpub-qos2.py test/broker/07-will-null-topic.py
This commit is contained in:
commit
c0443637e8
@ -11,7 +11,7 @@ project(mosquitto)
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
# Only for version 3 and up. cmake_policy(SET CMP0042 NEW)
|
||||
|
||||
set (VERSION 1.6.7)
|
||||
set (VERSION 1.6.8)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
|
||||
|
||||
@ -119,9 +119,9 @@ install(FILES mosquitto.conf aclfile.example pskfile.example pwfile.example DEST
|
||||
# ========================================
|
||||
|
||||
configure_file(libmosquitto.pc.in libmosquitto.pc @ONLY)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libmosquitto.pc" DESTINATION "${CMAKE_INSTALL_PREFIX}/share/pkgconfig")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libmosquitto.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||
configure_file(libmosquittopp.pc.in libmosquittopp.pc @ONLY)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libmosquittopp.pc" DESTINATION "${CMAKE_INSTALL_PREFIX}/share/pkgconfig")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libmosquittopp.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||
|
||||
# ========================================
|
||||
# Testing
|
||||
|
@ -38,6 +38,55 @@ Clients:
|
||||
- mosquitto_sub will now exit if all subscriptions were denied.
|
||||
|
||||
|
||||
1.6.8 - 20191128
|
||||
================
|
||||
|
||||
Broker:
|
||||
- Various fixes for `allow_zero_length_clientid` config, where this option was
|
||||
not being set correctly. Closes #1429.
|
||||
- Fix incorrect memory tracking causing problems with memory_limit option.
|
||||
Closes #1437.
|
||||
- Fix subscription topics being limited to 200 characters instead of 200
|
||||
hierarchy levels. Closes #1441.
|
||||
- Only a single CRL could be loaded at once. This has been fixed.
|
||||
Closes #1442.
|
||||
- Fix problems with reloading config when `per_listener_settings` was true.
|
||||
Closes #1459.
|
||||
- Fix retained messages with an expiry interval not being expired after being
|
||||
restored from persistence. Closes #1464.
|
||||
- Fix messages with an expiry interval being sent without an expiry interval
|
||||
property just before they were expired. Closes #1464.
|
||||
- Fix TLS Websockets clients not receiving messages after taking over a
|
||||
previous connection. Closes #1489.
|
||||
- Fix MQTT 3.1.1 clients using clean session false, or MQTT 5.0 clients using
|
||||
session-expiry-interval set to infinity never expiring, even when the global
|
||||
`persistent_client_expiration` option was set. Closes #1494.
|
||||
|
||||
Client library:
|
||||
- Fix publish properties not being passed to on_message_v5 callback for QoS 2
|
||||
messages. Closes #1432.
|
||||
- Fix documentation issues in mosquitto.h. Closes #1478.
|
||||
- Document `mosquitto_connect_srv()`. Closes #1499.
|
||||
|
||||
Clients:
|
||||
- Fix duplicate cfg definition in rr_client. Closes #1453.
|
||||
- Fix `mosquitto_pub -l` hang when stdin stream ends. Closes #1448.
|
||||
- Fix `mosquitto_pub -l` not sending the final line of stdin if it does not
|
||||
end with a new line. Closes #1473.
|
||||
- Make documentation for `mosquitto_pub -l` match reality - blank lines are
|
||||
sent as empty messages. Closes #1474.
|
||||
- Free memory in `mosquitto_sub` when quiting without having made a successful
|
||||
connection. Closes #1513.
|
||||
|
||||
Build:
|
||||
- Added `CLIENT_STATIC_LDADD` to makefile builds to allow more libraries to be
|
||||
linked when compiling the clients with a static libmosquitto, as required
|
||||
for e.g. openssl on some systems.
|
||||
|
||||
Installer:
|
||||
- Fix mosquitto_rr.exe not being included in Windows installers. Closes #1463.
|
||||
|
||||
|
||||
1.6.7 - 20190925
|
||||
================
|
||||
|
||||
|
@ -21,13 +21,13 @@ static : static_pub static_sub static_rr
|
||||
# libmosquitto only.
|
||||
|
||||
static_pub : pub_client.o pub_shared.o client_props.o client_shared.o ../lib/libmosquitto.a
|
||||
${CROSS_COMPILE}${CC} $^ -o mosquitto_pub ${CLIENT_LDFLAGS} ${STATIC_LIB_DEPS}
|
||||
${CROSS_COMPILE}${CC} $^ -o mosquitto_pub ${CLIENT_LDFLAGS} ${STATIC_LIB_DEPS} ${CLIENT_STATIC_LDADD}
|
||||
|
||||
static_sub : sub_client.o sub_client_output.o client_props.o client_shared.o ../lib/libmosquitto.a
|
||||
${CROSS_COMPILE}${CC} $^ -o mosquitto_sub ${CLIENT_LDFLAGS} ${STATIC_LIB_DEPS}
|
||||
${CROSS_COMPILE}${CC} $^ -o mosquitto_sub ${CLIENT_LDFLAGS} ${STATIC_LIB_DEPS} ${CLIENT_STATIC_LDADD}
|
||||
|
||||
static_rr : rr_client.o client_props.o client_shared.o pub_shared.o sub_client_output.o ../lib/libmosquitto.a
|
||||
${CROSS_COMPILE}${CC} $^ -o mosquitto_rr ${CLIENT_LDFLAGS} ${STATIC_LIB_DEPS}
|
||||
${CROSS_COMPILE}${CC} $^ -o mosquitto_rr ${CLIENT_LDFLAGS} ${STATIC_LIB_DEPS} ${CLIENT_STATIC_LDADD}
|
||||
|
||||
mosquitto_pub : pub_client.o pub_shared.o client_shared.o client_props.o
|
||||
${CROSS_COMPILE}${CC} $(CLIENT_LDFLAGS) $^ -o $@ $(CLIENT_LDADD)
|
||||
|
@ -45,6 +45,7 @@ static int line_buf_len = 1024;
|
||||
static bool disconnect_sent = false;
|
||||
static int publish_count = 0;
|
||||
static bool ready_for_repeat = false;
|
||||
static volatile int status = STATUS_CONNECTING;
|
||||
|
||||
#ifdef WIN32
|
||||
static uint64_t next_publish_tv;
|
||||
@ -219,111 +220,122 @@ int pub_shared_init(void)
|
||||
}
|
||||
|
||||
|
||||
int pub_shared_loop(struct mosquitto *mosq)
|
||||
int pub_stdin_line_loop(struct mosquitto *mosq)
|
||||
{
|
||||
int read_len;
|
||||
int pos;
|
||||
int rc, rc2;
|
||||
char *buf2;
|
||||
int buf_len_actual;
|
||||
int mode;
|
||||
int loop_delay = 1000;
|
||||
int buf_len_actual = 0;
|
||||
int pos;
|
||||
int rc = MOSQ_ERR_SUCCESS;
|
||||
int read_len;
|
||||
bool stdin_finished = false;
|
||||
|
||||
mosquitto_loop_start(mosq);
|
||||
stdin_finished = false;
|
||||
do{
|
||||
if(status == STATUS_CONNACK_RECVD){
|
||||
pos = 0;
|
||||
read_len = line_buf_len;
|
||||
while(status == STATUS_CONNACK_RECVD && fgets(&line_buf[pos], read_len, stdin)){
|
||||
buf_len_actual = strlen(line_buf);
|
||||
if(line_buf[buf_len_actual-1] == '\n'){
|
||||
line_buf[buf_len_actual-1] = '\0';
|
||||
rc = my_publish(mosq, &mid_sent, cfg.topic, buf_len_actual-1, line_buf, cfg.qos, cfg.retain);
|
||||
pos = 0;
|
||||
if(rc){
|
||||
err_printf(&cfg, "Error: Publish returned %d, disconnecting.\n", rc);
|
||||
mosquitto_disconnect_v5(mosq, MQTT_RC_DISCONNECT_WITH_WILL_MSG, cfg.disconnect_props);
|
||||
}
|
||||
break;
|
||||
}else{
|
||||
line_buf_len += 1024;
|
||||
pos += 1023;
|
||||
read_len = 1024;
|
||||
buf2 = realloc(line_buf, line_buf_len);
|
||||
if(!buf2){
|
||||
err_printf(&cfg, "Error: Out of memory.\n");
|
||||
return MOSQ_ERR_NOMEM;
|
||||
}
|
||||
line_buf = buf2;
|
||||
}
|
||||
}
|
||||
if(pos != 0){
|
||||
rc = my_publish(mosq, &mid_sent, cfg.topic, buf_len_actual, line_buf, cfg.qos, cfg.retain);
|
||||
if(rc){
|
||||
err_printf(&cfg, "Error: Publish returned %d, disconnecting.\n", rc);
|
||||
mosquitto_disconnect_v5(mosq, MQTT_RC_DISCONNECT_WITH_WILL_MSG, cfg.disconnect_props);
|
||||
}
|
||||
}
|
||||
if(feof(stdin)){
|
||||
if(mid_sent == -1){
|
||||
/* Empty file */
|
||||
mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
|
||||
disconnect_sent = true;
|
||||
status = STATUS_DISCONNECTING;
|
||||
}else{
|
||||
last_mid = mid_sent;
|
||||
status = STATUS_WAITING;
|
||||
}
|
||||
stdin_finished = true;
|
||||
}else if(status == STATUS_DISCONNECTED){
|
||||
/* Not end of stdin, so we've lost our connection and must
|
||||
* reconnect */
|
||||
}
|
||||
}
|
||||
|
||||
if(status == STATUS_WAITING){
|
||||
if(last_mid_sent == last_mid && disconnect_sent == false){
|
||||
mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
|
||||
disconnect_sent = true;
|
||||
}
|
||||
#ifdef WIN32
|
||||
Sleep(100);
|
||||
#else
|
||||
struct timespec ts;
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 100000000;
|
||||
nanosleep(&ts, NULL);
|
||||
#endif
|
||||
}
|
||||
}while(stdin_finished == false);
|
||||
mosquitto_loop_stop(mosq, false);
|
||||
|
||||
if(status == STATUS_DISCONNECTED){
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}else{
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int pub_other_loop(struct mosquitto *mosq)
|
||||
{
|
||||
int rc;
|
||||
int loop_delay = 1000;
|
||||
|
||||
if(cfg.repeat_count > 1 && (cfg.repeat_delay.tv_sec == 0 || cfg.repeat_delay.tv_usec != 0)){
|
||||
loop_delay = cfg.repeat_delay.tv_usec / 2000;
|
||||
}
|
||||
|
||||
mode = cfg.pub_mode;
|
||||
|
||||
if(mode == MSGMODE_STDIN_LINE){
|
||||
mosquitto_loop_start(mosq);
|
||||
stdin_finished = false;
|
||||
}
|
||||
|
||||
do{
|
||||
if(mode == MSGMODE_STDIN_LINE){
|
||||
if(status == STATUS_CONNACK_RECVD){
|
||||
pos = 0;
|
||||
read_len = line_buf_len;
|
||||
while(status == STATUS_CONNACK_RECVD && fgets(&line_buf[pos], read_len, stdin)){
|
||||
buf_len_actual = strlen(line_buf);
|
||||
if(line_buf[buf_len_actual-1] == '\n'){
|
||||
line_buf[buf_len_actual-1] = '\0';
|
||||
rc2 = my_publish(mosq, &mid_sent, cfg.topic, buf_len_actual-1, line_buf, cfg.qos, cfg.retain);
|
||||
if(rc2){
|
||||
err_printf(&cfg, "Error: Publish returned %d, disconnecting.\n", rc2);
|
||||
mosquitto_disconnect_v5(mosq, MQTT_RC_DISCONNECT_WITH_WILL_MSG, cfg.disconnect_props);
|
||||
}
|
||||
break;
|
||||
}else{
|
||||
line_buf_len += 1024;
|
||||
pos += 1023;
|
||||
read_len = 1024;
|
||||
buf2 = realloc(line_buf, line_buf_len);
|
||||
if(!buf2){
|
||||
err_printf(&cfg, "Error: Out of memory.\n");
|
||||
return MOSQ_ERR_NOMEM;
|
||||
}
|
||||
line_buf = buf2;
|
||||
}
|
||||
}
|
||||
if(feof(stdin)){
|
||||
if(mid_sent == -1){
|
||||
/* Empty file */
|
||||
mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
|
||||
disconnect_sent = true;
|
||||
status = STATUS_DISCONNECTING;
|
||||
}else{
|
||||
last_mid = mid_sent;
|
||||
status = STATUS_WAITING;
|
||||
}
|
||||
stdin_finished = true;
|
||||
}else if(status == STATUS_DISCONNECTED){
|
||||
/* Not end of stdin, so we've lost our connection and must
|
||||
* reconnect */
|
||||
}
|
||||
}else if(status == STATUS_WAITING){
|
||||
if(last_mid_sent == last_mid && disconnect_sent == false){
|
||||
mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
|
||||
disconnect_sent = true;
|
||||
}
|
||||
#ifdef WIN32
|
||||
Sleep(100);
|
||||
#else
|
||||
struct timespec ts;
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 100000000;
|
||||
nanosleep(&ts, NULL);
|
||||
#endif
|
||||
}
|
||||
rc = mosquitto_loop(mosq, loop_delay, 1);
|
||||
if(ready_for_repeat && check_repeat_time()){
|
||||
rc = MOSQ_ERR_SUCCESS;
|
||||
}else{
|
||||
rc = mosquitto_loop(mosq, loop_delay, 1);
|
||||
if(ready_for_repeat && check_repeat_time()){
|
||||
rc = 0;
|
||||
switch(cfg.pub_mode){
|
||||
case MSGMODE_CMD:
|
||||
case MSGMODE_FILE:
|
||||
case MSGMODE_STDIN_FILE:
|
||||
rc = my_publish(mosq, &mid_sent, cfg.topic, cfg.msglen, cfg.message, cfg.qos, cfg.retain);
|
||||
break;
|
||||
case MSGMODE_NULL:
|
||||
rc = my_publish(mosq, &mid_sent, cfg.topic, 0, NULL, cfg.qos, cfg.retain);
|
||||
break;
|
||||
case MSGMODE_STDIN_LINE:
|
||||
break;
|
||||
}
|
||||
if(rc){
|
||||
err_printf(&cfg, "Error sending repeat publish: %s", mosquitto_strerror(rc));
|
||||
}
|
||||
switch(cfg.pub_mode){
|
||||
case MSGMODE_CMD:
|
||||
case MSGMODE_FILE:
|
||||
case MSGMODE_STDIN_FILE:
|
||||
rc = my_publish(mosq, &mid_sent, cfg.topic, cfg.msglen, cfg.message, cfg.qos, cfg.retain);
|
||||
break;
|
||||
case MSGMODE_NULL:
|
||||
rc = my_publish(mosq, &mid_sent, cfg.topic, 0, NULL, cfg.qos, cfg.retain);
|
||||
break;
|
||||
}
|
||||
if(rc){
|
||||
err_printf(&cfg, "Error sending repeat publish: %s", mosquitto_strerror(rc));
|
||||
}
|
||||
}
|
||||
}while(rc == MOSQ_ERR_SUCCESS && stdin_finished == false);
|
||||
}while(rc == MOSQ_ERR_SUCCESS);
|
||||
|
||||
if(mode == MSGMODE_STDIN_LINE){
|
||||
mosquitto_loop_stop(mosq, false);
|
||||
}
|
||||
if(status == STATUS_DISCONNECTED){
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}else{
|
||||
@ -332,6 +344,16 @@ int pub_shared_loop(struct mosquitto *mosq)
|
||||
}
|
||||
|
||||
|
||||
int pub_shared_loop(struct mosquitto *mosq)
|
||||
{
|
||||
if(cfg.pub_mode == MSGMODE_STDIN_LINE){
|
||||
return pub_stdin_line_loop(mosq);
|
||||
}else{
|
||||
return pub_other_loop(mosq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pub_shared_cleanup(void)
|
||||
{
|
||||
free(line_buf);
|
||||
|
@ -37,7 +37,6 @@ Contributors:
|
||||
/* Global variables for use in callbacks. See sub_client.c for an example of
|
||||
* using a struct to hold variables for use in callbacks. */
|
||||
int mid_sent = -1;
|
||||
int status = STATUS_CONNECTING;
|
||||
struct mosq_config cfg;
|
||||
|
||||
void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str)
|
||||
|
@ -23,7 +23,6 @@ Contributors:
|
||||
#define STATUS_DISCONNECTED 4
|
||||
|
||||
extern int mid_sent;
|
||||
extern int status;
|
||||
extern struct mosq_config cfg;
|
||||
|
||||
|
||||
|
@ -48,7 +48,8 @@ enum rr__state {
|
||||
|
||||
static enum rr__state client_state = rr_s_new;
|
||||
|
||||
struct mosq_config cfg;
|
||||
extern struct mosq_config cfg;
|
||||
|
||||
bool process_messages = true;
|
||||
int msg_count = 0;
|
||||
struct mosquitto *mosq = NULL;
|
||||
|
@ -46,7 +46,7 @@ static bool timed_out = false;
|
||||
#ifndef WIN32
|
||||
void my_signal_handler(int signum)
|
||||
{
|
||||
if(signum == SIGALRM){
|
||||
if(signum == SIGALRM || signum == SIGTERM || signum == SIGINT){
|
||||
process_messages = false;
|
||||
mosquitto_disconnect_v5(mosq, MQTT_RC_DISCONNECT_WITH_WILL_MSG, cfg.disconnect_props);
|
||||
timed_out = true;
|
||||
@ -354,6 +354,16 @@ int main(int argc, char *argv[])
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(sigaction(SIGTERM, &sigact, NULL) == -1){
|
||||
perror("sigaction");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(sigaction(SIGINT, &sigact, NULL) == -1){
|
||||
perror("sigaction");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(cfg.timeout){
|
||||
alarm(cfg.timeout);
|
||||
}
|
||||
@ -377,6 +387,7 @@ int main(int argc, char *argv[])
|
||||
return rc;
|
||||
|
||||
cleanup:
|
||||
mosquitto_destroy(mosq);
|
||||
mosquitto_lib_cleanup();
|
||||
client_config_cleanup(&cfg);
|
||||
return 1;
|
||||
|
11
config.mk
11
config.mk
@ -82,6 +82,11 @@ WITH_STRIP:=no
|
||||
# Build static libraries
|
||||
WITH_STATIC_LIBRARIES:=no
|
||||
|
||||
# Use this variable to add extra library dependencies when building the clients
|
||||
# with the static libmosquitto library. This may be required on some systems
|
||||
# where e.g. -lz or -latomic are needed for openssl.
|
||||
CLIENT_STATIC_LDADD:=
|
||||
|
||||
# Build shared libraries
|
||||
WITH_SHARED_LIBRARIES:=yes
|
||||
|
||||
@ -110,7 +115,7 @@ WITH_CJSON:=yes
|
||||
|
||||
# Also bump lib/mosquitto.h, CMakeLists.txt,
|
||||
# installer/mosquitto.nsi, installer/mosquitto64.nsi
|
||||
VERSION=1.6.7
|
||||
VERSION=1.6.8
|
||||
|
||||
# Client library SO version. Bump if incompatible API/ABI changes are made.
|
||||
SOVERSION=1
|
||||
@ -329,3 +334,7 @@ ifeq ($(WITH_CJSON),yes)
|
||||
CLIENT_CFLAGS:=$(CLIENT_CFLAGS) -DWITH_CJSON -I/usr/include/cjson
|
||||
CLIENT_LDADD:=$(CLIENT_LDADD) -lcjson
|
||||
endif
|
||||
|
||||
BROKER_LDADD:=${BROKER_LDADD} ${LDADD}
|
||||
CLIENT_LDADD:=${CLIENT_LDADD} ${LDADD}
|
||||
PASSWD_LDADD:=${PASSWD_LDADD} ${LDADD}
|
||||
|
@ -3,7 +3,7 @@ MAINTAINER David Audet <david.audet@ca.com>
|
||||
|
||||
LABEL Description="Eclipse Mosquitto MQTT Broker"
|
||||
|
||||
RUN apk --no-cache add mosquitto=1.4.12-r0 && \
|
||||
RUN apk --no-cache add mosquitto=1.4.12-r0 ca-certificates && \
|
||||
mkdir -p /mosquitto/config /mosquitto/data /mosquitto/log && \
|
||||
cp /etc/mosquitto/mosquitto.conf /mosquitto/config && \
|
||||
chown -R mosquitto:mosquitto /mosquitto
|
||||
|
@ -75,7 +75,7 @@ RUN set -x && \
|
||||
install -m644 /build/mosq/mosquitto.conf /mosquitto/config/mosquitto.conf && \
|
||||
chown -R mosquitto:mosquitto /mosquitto && \
|
||||
apk --no-cache add \
|
||||
libuuid && \
|
||||
ca-certificates libuuid && \
|
||||
apk del build-deps && \
|
||||
rm -rf /build
|
||||
|
||||
|
@ -78,6 +78,8 @@ RUN set -x && \
|
||||
install -s -m755 /build/mosq/src/mosquitto_passwd /usr/bin/mosquitto_passwd && \
|
||||
install -m644 /build/mosq/mosquitto.conf /mosquitto/config/mosquitto.conf && \
|
||||
chown -R mosquitto:mosquitto /mosquitto && \
|
||||
apk --no-cache add \
|
||||
ca-certificates && \
|
||||
apk del build-deps && \
|
||||
rm -rf /build
|
||||
|
||||
|
@ -12,7 +12,8 @@ RUN apk --no-cache add \
|
||||
util-linux-dev \
|
||||
libwebsockets-dev \
|
||||
libxslt \
|
||||
python2
|
||||
python2 \
|
||||
ca-certificates
|
||||
|
||||
# This build procedure is based on:
|
||||
# https://github.com/alpinelinux/aports/blob/master/main/mosquitto/APKBUILD
|
||||
@ -46,6 +47,7 @@ LABEL maintainer="Jonathan Hanson <jonathan@jonathan-hanson.org>" \
|
||||
# Install the run-time dependencies
|
||||
RUN apk --no-cache add \
|
||||
busybox \
|
||||
ca-certificates \
|
||||
libcrypto1.0 \
|
||||
libssl1.0 \
|
||||
libuuid \
|
||||
|
@ -59,6 +59,8 @@ RUN set -x && \
|
||||
install -s -m755 /build/mosq/src/mosquitto_passwd /usr/bin/mosquitto_passwd && \
|
||||
install -m644 /build/mosq/mosquitto.conf /mosquitto/config/mosquitto.conf && \
|
||||
chown -R mosquitto:mosquitto /mosquitto && \
|
||||
apk --no-cache add \
|
||||
ca-certificates && \
|
||||
apk del build-deps && \
|
||||
rm -rf /build
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
!define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
|
||||
|
||||
Name "Eclipse Mosquitto"
|
||||
!define VERSION 1.6.7
|
||||
!define VERSION 1.6.8
|
||||
OutFile "mosquitto-${VERSION}-install-windows-x86.exe"
|
||||
|
||||
InstallDir "$PROGRAMFILES\mosquitto"
|
||||
@ -45,6 +45,7 @@ Section "Files" SecInstall
|
||||
File "..\build\src\Release\mosquitto_passwd.exe"
|
||||
File "..\build\client\Release\mosquitto_pub.exe"
|
||||
File "..\build\client\Release\mosquitto_sub.exe"
|
||||
File "..\build\client\Release\mosquitto_rr.exe"
|
||||
File "..\build\lib\Release\mosquitto.dll"
|
||||
File "..\build\lib\cpp\Release\mosquittopp.dll"
|
||||
File "..\aclfile.example"
|
||||
@ -90,6 +91,7 @@ Section "Uninstall"
|
||||
Delete "$INSTDIR\mosquitto_passwd.exe"
|
||||
Delete "$INSTDIR\mosquitto_pub.exe"
|
||||
Delete "$INSTDIR\mosquitto_sub.exe"
|
||||
Delete "$INSTDIR\mosquitto_rr.exe"
|
||||
Delete "$INSTDIR\mosquitto.dll"
|
||||
Delete "$INSTDIR\mosquittopp.dll"
|
||||
Delete "$INSTDIR\aclfile.example"
|
||||
|
@ -9,7 +9,7 @@
|
||||
!define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
|
||||
|
||||
Name "Eclipse Mosquitto"
|
||||
!define VERSION 1.6.7
|
||||
!define VERSION 1.6.8
|
||||
OutFile "mosquitto-${VERSION}-install-windows-x64.exe"
|
||||
|
||||
!include "x64.nsh"
|
||||
@ -46,6 +46,7 @@ Section "Files" SecInstall
|
||||
File "..\build64\src\Release\mosquitto_passwd.exe"
|
||||
File "..\build64\client\Release\mosquitto_pub.exe"
|
||||
File "..\build64\client\Release\mosquitto_sub.exe"
|
||||
File "..\build64\client\Release\mosquitto_rr.exe"
|
||||
File "..\build64\lib\Release\mosquitto.dll"
|
||||
File "..\build64\lib\cpp\Release\mosquittopp.dll"
|
||||
File "..\aclfile.example"
|
||||
@ -91,6 +92,7 @@ Section "Uninstall"
|
||||
Delete "$INSTDIR\mosquitto_passwd.exe"
|
||||
Delete "$INSTDIR\mosquitto_pub.exe"
|
||||
Delete "$INSTDIR\mosquitto_sub.exe"
|
||||
Delete "$INSTDIR\mosquitto_rr.exe"
|
||||
Delete "$INSTDIR\mosquitto.dll"
|
||||
Delete "$INSTDIR\mosquittopp.dll"
|
||||
Delete "$INSTDIR\aclfile.example"
|
||||
|
@ -152,13 +152,13 @@ int handle__publish(struct mosquitto *mosq)
|
||||
mosquitto_property_free_all(&properties);
|
||||
return rc;
|
||||
case 2:
|
||||
message->properties = properties;
|
||||
util__decrement_receive_quota(mosq);
|
||||
rc = send__pubrec(mosq, message->msg.mid, 0);
|
||||
pthread_mutex_lock(&mosq->msgs_in.mutex);
|
||||
message->state = mosq_ms_wait_for_pubrel;
|
||||
message__queue(mosq, message, mosq_md_in);
|
||||
pthread_mutex_unlock(&mosq->msgs_in.mutex);
|
||||
mosquitto_property_free_all(&properties);
|
||||
return rc;
|
||||
default:
|
||||
message__cleanup(&message);
|
||||
|
@ -114,7 +114,7 @@ int handle__pubrel(struct mosquitto_db *db, struct mosquitto *mosq)
|
||||
}
|
||||
if(mosq->on_message_v5){
|
||||
mosq->in_callback = true;
|
||||
mosq->on_message_v5(mosq, mosq->userdata, &message->msg, properties);
|
||||
mosq->on_message_v5(mosq, mosq->userdata, &message->msg, message->properties);
|
||||
mosq->in_callback = false;
|
||||
}
|
||||
pthread_mutex_unlock(&mosq->callback_mutex);
|
||||
|
349
lib/mosquitto.h
349
lib/mosquitto.h
@ -48,7 +48,7 @@ extern "C" {
|
||||
|
||||
#define LIBMOSQUITTO_MAJOR 1
|
||||
#define LIBMOSQUITTO_MINOR 6
|
||||
#define LIBMOSQUITTO_REVISION 7
|
||||
#define LIBMOSQUITTO_REVISION 8
|
||||
/* LIBMOSQUITTO_VERSION_NUMBER looks like 1002001 for e.g. version 1.2.1. */
|
||||
#define LIBMOSQUITTO_VERSION_NUMBER (LIBMOSQUITTO_MAJOR*1000000+LIBMOSQUITTO_MINOR*1000+LIBMOSQUITTO_REVISION)
|
||||
|
||||
@ -393,11 +393,9 @@ libmosq_EXPORT int mosquitto_will_clear(struct mosquitto *mosq);
|
||||
/*
|
||||
* Function: mosquitto_username_pw_set
|
||||
*
|
||||
* Configure username and password for a mosquitton instance. This is only
|
||||
* supported by brokers that implement the MQTT spec v3.1. By default, no
|
||||
* username or password will be sent.
|
||||
* If username is NULL, the password argument is ignored.
|
||||
* This must be called before calling mosquitto_connect().
|
||||
* Configure username and password for a mosquitto instance. By default, no
|
||||
* username or password will be sent. For v3.1 and v3.1.1 clients, if username
|
||||
* is NULL, the password argument is ignored.
|
||||
*
|
||||
* This is must be called before calling <mosquitto_connect>.
|
||||
*
|
||||
@ -481,8 +479,13 @@ libmosq_EXPORT int mosquitto_connect_bind(struct mosquitto *mosq, const char *ho
|
||||
* Function: mosquitto_connect_bind_v5
|
||||
*
|
||||
* Connect to an MQTT broker. This extends the functionality of
|
||||
* <mosquitto_connect> by adding the bind_address parameter. Use this function
|
||||
* if you need to restrict network communication over a particular interface.
|
||||
* <mosquitto_connect> by adding the bind_address parameter and MQTT v5
|
||||
* properties. Use this function if you need to restrict network communication
|
||||
* over a particular interface.
|
||||
*
|
||||
* Use e.g. <mosquitto_property_add_string> and similar to create a list of
|
||||
* properties, then attach them to this publish. Properties need freeing with
|
||||
* <mosquitto_property_free_all>.
|
||||
*
|
||||
* Parameters:
|
||||
* mosq - a valid mosquitto instance.
|
||||
@ -581,20 +584,18 @@ libmosq_EXPORT int mosquitto_connect_bind_async(struct mosquitto *mosq, const ch
|
||||
/*
|
||||
* Function: mosquitto_connect_srv
|
||||
*
|
||||
* Connect to an MQTT broker. This is a non-blocking call. If you use
|
||||
* <mosquitto_connect_async> your client must use the threaded interface
|
||||
* <mosquitto_loop_start>. If you need to use <mosquitto_loop>, you must use
|
||||
* <mosquitto_connect> to connect the client.
|
||||
* Connect to an MQTT broker.
|
||||
*
|
||||
* This extends the functionality of <mosquitto_connect_async> by adding the
|
||||
* bind_address parameter. Use this function if you need to restrict network
|
||||
* communication over a particular interface.
|
||||
* If you set `host` to `example.com`, then this call will attempt to retrieve
|
||||
* the DNS SRV record for `_secure-mqtt._tcp.example.com` or
|
||||
* `_mqtt._tcp.example.com` to discover which actual host to connect to.
|
||||
*
|
||||
* May be called before or after <mosquitto_loop_start>.
|
||||
* DNS SRV support is not usually compiled in to libmosquitto, use of this call
|
||||
* is not recommended.
|
||||
*
|
||||
* Parameters:
|
||||
* mosq - a valid mosquitto instance.
|
||||
* host - the hostname or ip address of the broker to connect to.
|
||||
* host - the hostname to search for an SRV record.
|
||||
* keepalive - the number of seconds after which the broker should send a PING
|
||||
* message to the client if no other messages have been exchanged
|
||||
* in that time.
|
||||
@ -631,10 +632,6 @@ libmosq_EXPORT int mosquitto_connect_srv(struct mosquitto *mosq, const char *hos
|
||||
* MOSQ_ERR_SUCCESS - on success.
|
||||
* MOSQ_ERR_INVAL - if the input parameters were invalid.
|
||||
* MOSQ_ERR_NOMEM - if an out of memory condition occurred.
|
||||
*
|
||||
* Returns:
|
||||
* MOSQ_ERR_SUCCESS - on success.
|
||||
* MOSQ_ERR_INVAL - if the input parameters were invalid.
|
||||
* MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno
|
||||
* contains the error code, even on Windows.
|
||||
* Use strerror_r() where available or FormatMessage() on
|
||||
@ -662,10 +659,6 @@ libmosq_EXPORT int mosquitto_reconnect(struct mosquitto *mosq);
|
||||
* MOSQ_ERR_SUCCESS - on success.
|
||||
* MOSQ_ERR_INVAL - if the input parameters were invalid.
|
||||
* MOSQ_ERR_NOMEM - if an out of memory condition occurred.
|
||||
*
|
||||
* Returns:
|
||||
* MOSQ_ERR_SUCCESS - on success.
|
||||
* MOSQ_ERR_INVAL - if the input parameters were invalid.
|
||||
* MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno
|
||||
* contains the error code, even on Windows.
|
||||
* Use strerror_r() where available or FormatMessage() on
|
||||
@ -696,8 +689,8 @@ libmosq_EXPORT int mosquitto_disconnect(struct mosquitto *mosq);
|
||||
*
|
||||
* Disconnect from the broker, with attached MQTT properties.
|
||||
*
|
||||
* Use <mosquitto_property_add_*> to create a list of properties, then attach
|
||||
* them to this publish. Properties need freeing with
|
||||
* Use e.g. <mosquitto_property_add_string> and similar to create a list of
|
||||
* properties, then attach them to this publish. Properties need freeing with
|
||||
* <mosquitto_property_free_all>.
|
||||
*
|
||||
* Parameters:
|
||||
@ -768,8 +761,8 @@ libmosq_EXPORT int mosquitto_publish(struct mosquitto *mosq, int *mid, const cha
|
||||
*
|
||||
* Publish a message on a given topic, with attached MQTT properties.
|
||||
*
|
||||
* Use <mosquitto_property_add_*> to create a list of properties, then attach
|
||||
* them to this publish. Properties need freeing with
|
||||
* Use e.g. <mosquitto_property_add_string> and similar to create a list of
|
||||
* properties, then attach them to this publish. Properties need freeing with
|
||||
* <mosquitto_property_free_all>.
|
||||
*
|
||||
* Requires the mosquitto instance to be connected with MQTT 5.
|
||||
@ -850,8 +843,8 @@ libmosq_EXPORT int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const c
|
||||
*
|
||||
* Subscribe to a topic, with attached MQTT properties.
|
||||
*
|
||||
* Use <mosquitto_property_add_*> to create a list of properties, then attach
|
||||
* them to this subscribe. Properties need freeing with
|
||||
* Use e.g. <mosquitto_property_add_string> and similar to create a list of
|
||||
* properties, then attach them to this publish. Properties need freeing with
|
||||
* <mosquitto_property_free_all>.
|
||||
*
|
||||
* Requires the mosquitto instance to be connected with MQTT 5.
|
||||
@ -867,26 +860,26 @@ libmosq_EXPORT int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const c
|
||||
* qos - the requested Quality of Service for this subscription.
|
||||
* options - options to apply to this subscription, OR'd together. Set to 0 to
|
||||
* use the default options, otherwise choose from the list:
|
||||
* MQTT_SUB_OPT_NO_LOCAL - with this option set, if this client
|
||||
* MQTT_SUB_OPT_NO_LOCAL: with this option set, if this client
|
||||
* publishes to a topic to which it is subscribed, the
|
||||
* broker will not publish the message back to the
|
||||
* client.
|
||||
* MQTT_SUB_OPT_RETAIN_AS_PUBLISHED - with this option set, messages
|
||||
* MQTT_SUB_OPT_RETAIN_AS_PUBLISHED: with this option set, messages
|
||||
* published for this subscription will keep the
|
||||
* retain flag as was set by the publishing client.
|
||||
* The default behaviour without this option set has
|
||||
* the retain flag indicating whether a message is
|
||||
* fresh/stale.
|
||||
* MQTT_SUB_OPT_SEND_RETAIN_ALWAYS - with this option set,
|
||||
* MQTT_SUB_OPT_SEND_RETAIN_ALWAYS: with this option set,
|
||||
* pre-existing retained messages are sent as soon as
|
||||
* the subscription is made, even if the subscription
|
||||
* already exists. This is the default behaviour, so
|
||||
* it is not necessary to set this option.
|
||||
* MQTT_SUB_OPT_SEND_RETAIN_NEW - with this option set, pre-existing
|
||||
* MQTT_SUB_OPT_SEND_RETAIN_NEW: with this option set, pre-existing
|
||||
* retained messages for this subscription will be
|
||||
* sent when the subscription is made, but only if the
|
||||
* subscription does not already exist.
|
||||
* MQTT_SUB_OPT_SEND_RETAIN_NEVER - with this option set,
|
||||
* MQTT_SUB_OPT_SEND_RETAIN_NEVER: with this option set,
|
||||
* pre-existing retained messages will never be sent
|
||||
* for this subscription.
|
||||
* properties - a valid mosquitto_property list, or NULL.
|
||||
@ -925,26 +918,26 @@ libmosq_EXPORT int mosquitto_subscribe_v5(struct mosquitto *mosq, int *mid, cons
|
||||
* options - options to apply to this subscription, OR'd together. This
|
||||
* argument is not used for MQTT v3 susbcriptions. Set to 0 to use
|
||||
* the default options, otherwise choose from the list:
|
||||
* MQTT_SUB_OPT_NO_LOCAL - with this option set, if this client
|
||||
* MQTT_SUB_OPT_NO_LOCAL: with this option set, if this client
|
||||
* publishes to a topic to which it is subscribed, the
|
||||
* broker will not publish the message back to the
|
||||
* client.
|
||||
* MQTT_SUB_OPT_RETAIN_AS_PUBLISHED - with this option set, messages
|
||||
* MQTT_SUB_OPT_RETAIN_AS_PUBLISHED: with this option set, messages
|
||||
* published for this subscription will keep the
|
||||
* retain flag as was set by the publishing client.
|
||||
* The default behaviour without this option set has
|
||||
* the retain flag indicating whether a message is
|
||||
* fresh/stale.
|
||||
* MQTT_SUB_OPT_SEND_RETAIN_ALWAYS - with this option set,
|
||||
* MQTT_SUB_OPT_SEND_RETAIN_ALWAYS: with this option set,
|
||||
* pre-existing retained messages are sent as soon as
|
||||
* the subscription is made, even if the subscription
|
||||
* already exists. This is the default behaviour, so
|
||||
* it is not necessary to set this option.
|
||||
* MQTT_SUB_OPT_SEND_RETAIN_NEW - with this option set, pre-existing
|
||||
* MQTT_SUB_OPT_SEND_RETAIN_NEW: with this option set, pre-existing
|
||||
* retained messages for this subscription will be
|
||||
* sent when the subscription is made, but only if the
|
||||
* subscription does not already exist.
|
||||
* MQTT_SUB_OPT_SEND_RETAIN_NEVER - with this option set,
|
||||
* MQTT_SUB_OPT_SEND_RETAIN_NEVER: with this option set,
|
||||
* pre-existing retained messages will never be sent
|
||||
* for this subscription.
|
||||
* properties - a valid mosquitto_property list, or NULL. Only used with MQTT
|
||||
@ -990,6 +983,10 @@ libmosq_EXPORT int mosquitto_unsubscribe(struct mosquitto *mosq, int *mid, const
|
||||
*
|
||||
* Unsubscribe from a topic, with attached MQTT properties.
|
||||
*
|
||||
* Use e.g. <mosquitto_property_add_string> and similar to create a list of
|
||||
* properties, then attach them to this publish. Properties need freeing with
|
||||
* <mosquitto_property_free_all>.
|
||||
*
|
||||
* Parameters:
|
||||
* mosq - a valid mosquitto instance.
|
||||
* mid - a pointer to an int. If not NULL, the function will set this to
|
||||
@ -1101,52 +1098,16 @@ libmosq_EXPORT void mosquitto_message_free_contents(struct mosquitto_message *me
|
||||
*
|
||||
* Section: Network loop (managed by libmosquitto)
|
||||
*
|
||||
* The internal network loop must be called at a regular interval. The two
|
||||
* recommended approaches are to use either <mosquitto_loop_forever> or
|
||||
* <mosquitto_loop_start>. <mosquitto_loop_forever> is a blocking call and is
|
||||
* suitable for the situation where you only want to handle incoming messages
|
||||
* in callbacks. <mosquitto_loop_start> is a non-blocking call, it creates a
|
||||
* separate thread to run the loop for you. Use this function when you have
|
||||
* other tasks you need to run at the same time as the MQTT client, e.g.
|
||||
* reading data from a sensor.
|
||||
*
|
||||
* ====================================================================== */
|
||||
/*
|
||||
* Function: mosquitto_loop
|
||||
*
|
||||
* The main network loop for the client. You must call this frequently in order
|
||||
* to keep communications between the client and broker working. If incoming
|
||||
* data is present it will then be processed. Outgoing commands, from e.g.
|
||||
* <mosquitto_publish>, are normally sent immediately that their function is
|
||||
* called, but this is not always possible. <mosquitto_loop> will also attempt
|
||||
* to send any remaining outgoing messages, which also includes commands that
|
||||
* are part of the flow for messages with QoS>0.
|
||||
*
|
||||
* An alternative approach is to use <mosquitto_loop_start> to run the client
|
||||
* loop in its own thread.
|
||||
*
|
||||
* This calls select() to monitor the client network socket. If you want to
|
||||
* integrate mosquitto client operation with your own select() call, use
|
||||
* <mosquitto_socket>, <mosquitto_loop_read>, <mosquitto_loop_write> and
|
||||
* <mosquitto_loop_misc>.
|
||||
*
|
||||
* Threads:
|
||||
*
|
||||
* Parameters:
|
||||
* mosq - a valid mosquitto instance.
|
||||
* timeout - Maximum number of milliseconds to wait for network activity
|
||||
* in the select() call before timing out. Set to 0 for instant
|
||||
* return. Set negative to use the default of 1000ms.
|
||||
* max_packets - this parameter is currently unused and should be set to 1 for
|
||||
* future compatibility.
|
||||
*
|
||||
* Returns:
|
||||
* MOSQ_ERR_SUCCESS - on success.
|
||||
* MOSQ_ERR_INVAL - if the input parameters were invalid.
|
||||
* MOSQ_ERR_NOMEM - if an out of memory condition occurred.
|
||||
* MOSQ_ERR_NO_CONN - if the client isn't connected to a broker.
|
||||
* MOSQ_ERR_CONN_LOST - if the connection to the broker was lost.
|
||||
* MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the
|
||||
* broker.
|
||||
* MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno
|
||||
* contains the error code, even on Windows.
|
||||
* Use strerror_r() where available or FormatMessage() on
|
||||
* Windows.
|
||||
* See Also:
|
||||
* <mosquitto_loop_forever>, <mosquitto_loop_start>, <mosquitto_loop_stop>
|
||||
*/
|
||||
libmosq_EXPORT int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets);
|
||||
|
||||
/*
|
||||
* Function: mosquitto_loop_forever
|
||||
@ -1228,6 +1189,52 @@ libmosq_EXPORT int mosquitto_loop_start(struct mosquitto *mosq);
|
||||
*/
|
||||
libmosq_EXPORT int mosquitto_loop_stop(struct mosquitto *mosq, bool force);
|
||||
|
||||
/*
|
||||
* Function: mosquitto_loop
|
||||
*
|
||||
* The main network loop for the client. This must be called frequently
|
||||
* to keep communications between the client and broker working. This is
|
||||
* carried out by <mosquitto_loop_forever> and <mosquitto_loop_start>, which
|
||||
* are the recommended ways of handling the network loop. You may also use this
|
||||
* function if you wish. It must not be called inside a callback.
|
||||
*
|
||||
* If incoming data is present it will then be processed. Outgoing commands,
|
||||
* from e.g. <mosquitto_publish>, are normally sent immediately that their
|
||||
* function is called, but this is not always possible. <mosquitto_loop> will
|
||||
* also attempt to send any remaining outgoing messages, which also includes
|
||||
* commands that are part of the flow for messages with QoS>0.
|
||||
*
|
||||
* This calls select() to monitor the client network socket. If you want to
|
||||
* integrate mosquitto client operation with your own select() call, use
|
||||
* <mosquitto_socket>, <mosquitto_loop_read>, <mosquitto_loop_write> and
|
||||
* <mosquitto_loop_misc>.
|
||||
*
|
||||
* Threads:
|
||||
*
|
||||
* Parameters:
|
||||
* mosq - a valid mosquitto instance.
|
||||
* timeout - Maximum number of milliseconds to wait for network activity
|
||||
* in the select() call before timing out. Set to 0 for instant
|
||||
* return. Set negative to use the default of 1000ms.
|
||||
* max_packets - this parameter is currently unused and should be set to 1 for
|
||||
* future compatibility.
|
||||
*
|
||||
* Returns:
|
||||
* MOSQ_ERR_SUCCESS - on success.
|
||||
* MOSQ_ERR_INVAL - if the input parameters were invalid.
|
||||
* MOSQ_ERR_NOMEM - if an out of memory condition occurred.
|
||||
* MOSQ_ERR_NO_CONN - if the client isn't connected to a broker.
|
||||
* MOSQ_ERR_CONN_LOST - if the connection to the broker was lost.
|
||||
* MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the
|
||||
* broker.
|
||||
* MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno
|
||||
* contains the error code, even on Windows.
|
||||
* Use strerror_r() where available or FormatMessage() on
|
||||
* Windows.
|
||||
* See Also:
|
||||
* <mosquitto_loop_forever>, <mosquitto_loop_start>, <mosquitto_loop_stop>
|
||||
*/
|
||||
libmosq_EXPORT int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets);
|
||||
|
||||
/* ======================================================================
|
||||
*
|
||||
@ -1302,7 +1309,8 @@ libmosq_EXPORT int mosquitto_loop_write(struct mosquitto *mosq, int max_packets)
|
||||
* monitoring the client network socket for activity yourself.
|
||||
*
|
||||
* This function deals with handling PINGs and checking whether messages need
|
||||
* to be retried, so should be called fairly frequently.
|
||||
* to be retried, so should be called fairly frequently, around once per second
|
||||
* is sufficient.
|
||||
*
|
||||
* Parameters:
|
||||
* mosq - a valid mosquitto instance.
|
||||
@ -1424,12 +1432,12 @@ libmosq_EXPORT int mosquitto_opts_set(struct mosquitto *mosq, enum mosq_opt_t op
|
||||
* value - the option specific value.
|
||||
*
|
||||
* Options:
|
||||
* MOSQ_OPT_PROTOCOL_VERSION
|
||||
* MOSQ_OPT_PROTOCOL_VERSION -
|
||||
* Value must be set to either MQTT_PROTOCOL_V31,
|
||||
* MQTT_PROTOCOL_V311, or MQTT_PROTOCOL_V5. Must be set before the
|
||||
* client connects. Defaults to MQTT_PROTOCOL_V311.
|
||||
*
|
||||
* MOSQ_OPT_RECEIVE_MAXIMUM
|
||||
* MOSQ_OPT_RECEIVE_MAXIMUM -
|
||||
* Value can be set between 1 and 65535 inclusive, and represents
|
||||
* the maximum number of incoming QoS 1 and QoS 2 messages that this
|
||||
* client wants to process at once. Defaults to 20. This option is
|
||||
@ -1439,7 +1447,7 @@ libmosq_EXPORT int mosquitto_opts_set(struct mosquitto *mosq, enum mosq_opt_t op
|
||||
* will override this option. Using this option is the recommended
|
||||
* method however.
|
||||
*
|
||||
* MOSQ_OPT_SEND_MAXIMUM
|
||||
* MOSQ_OPT_SEND_MAXIMUM -
|
||||
* Value can be set between 1 and 65535 inclusive, and represents
|
||||
* the maximum number of outgoing QoS 1 and QoS 2 messages that this
|
||||
* client will attempt to have "in flight" at once. Defaults to 20.
|
||||
@ -1448,7 +1456,7 @@ libmosq_EXPORT int mosquitto_opts_set(struct mosquitto *mosq, enum mosq_opt_t op
|
||||
* MQTT_PROP_RECEIVE_MAXIMUM property that has a lower value than
|
||||
* this option, then the broker provided value will be used.
|
||||
*
|
||||
* MOSQ_OPT_SSL_CTX_WITH_DEFAULTS
|
||||
* MOSQ_OPT_SSL_CTX_WITH_DEFAULTS -
|
||||
* If value is set to a non zero value, then the user specified
|
||||
* SSL_CTX passed in using MOSQ_OPT_SSL_CTX will have the default
|
||||
* options applied to it. This means that you only need to change
|
||||
@ -1457,7 +1465,8 @@ libmosq_EXPORT int mosquitto_opts_set(struct mosquitto *mosq, enum mosq_opt_t op
|
||||
* use <mosquitto_tls_set> to configure the cafile/capath as a
|
||||
* minimum.
|
||||
* This option is only available for openssl 1.1.0 and higher.
|
||||
* MOSQ_OPT_TLS_OCSP_REQUIRED
|
||||
*
|
||||
* MOSQ_OPT_TLS_OCSP_REQUIRED -
|
||||
* Set whether OCSP checking on TLS connections is required. Set to
|
||||
* 1 to enable checking, or 0 (the default) for no checking.
|
||||
*/
|
||||
@ -1475,7 +1484,7 @@ libmosq_EXPORT int mosquitto_int_option(struct mosquitto *mosq, enum mosq_opt_t
|
||||
* value - the option specific value.
|
||||
*
|
||||
* Options:
|
||||
* MOSQ_OPT_SSL_CTX
|
||||
* MOSQ_OPT_SSL_CTX -
|
||||
* Pass an openssl SSL_CTX to be used when creating TLS connections
|
||||
* rather than libmosquitto creating its own. This must be called
|
||||
* before connecting to have any effect. If you use this option, the
|
||||
@ -2216,26 +2225,26 @@ libmosq_EXPORT int mosquitto_string_to_command(const char *str, int *cmd);
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* subtopic: "a/deep/topic/hierarchy"
|
||||
* subtopic: "a/deep/topic/hierarchy"
|
||||
*
|
||||
* Would result in:
|
||||
* Would result in:
|
||||
*
|
||||
* topics[0] = "a"
|
||||
* topics[1] = "deep"
|
||||
* topics[2] = "topic"
|
||||
* topics[3] = "hierarchy"
|
||||
* topics[0] = "a"
|
||||
* topics[1] = "deep"
|
||||
* topics[2] = "topic"
|
||||
* topics[3] = "hierarchy"
|
||||
*
|
||||
* and:
|
||||
* and:
|
||||
*
|
||||
* subtopic: "/a/deep/topic/hierarchy/"
|
||||
* subtopic: "/a/deep/topic/hierarchy/"
|
||||
*
|
||||
* Would result in:
|
||||
* Would result in:
|
||||
*
|
||||
* topics[0] = NULL
|
||||
* topics[1] = "a"
|
||||
* topics[2] = "deep"
|
||||
* topics[3] = "topic"
|
||||
* topics[4] = "hierarchy"
|
||||
* topics[0] = NULL
|
||||
* topics[1] = "a"
|
||||
* topics[2] = "deep"
|
||||
* topics[3] = "topic"
|
||||
* topics[4] = "hierarchy"
|
||||
*
|
||||
* Parameters:
|
||||
* subtopic - the subscription/topic to tokenise
|
||||
@ -2284,6 +2293,29 @@ libmosq_EXPORT int mosquitto_sub_topic_tokens_free(char ***topics, int count);
|
||||
|
||||
/*
|
||||
* Function: mosquitto_topic_matches_sub
|
||||
*
|
||||
* Check whether a topic matches a subscription.
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* foo/bar would match the subscription foo/# or +/bar
|
||||
* non/matching would not match the subscription non/+/+
|
||||
*
|
||||
* Parameters:
|
||||
* sub - subscription string to check topic against.
|
||||
* topic - topic to check.
|
||||
* result - bool pointer to hold result. Will be set to true if the topic
|
||||
* matches the subscription.
|
||||
*
|
||||
* Returns:
|
||||
* MOSQ_ERR_SUCCESS - on success
|
||||
* MOSQ_ERR_INVAL - if the input parameters were invalid.
|
||||
* MOSQ_ERR_NOMEM - if an out of memory condition occurred.
|
||||
*/
|
||||
libmosq_EXPORT int mosquitto_topic_matches_sub(const char *sub, const char *topic, bool *result);
|
||||
|
||||
|
||||
/*
|
||||
* Function: mosquitto_topic_matches_sub2
|
||||
*
|
||||
* Check whether a topic matches a subscription.
|
||||
@ -2303,10 +2335,9 @@ libmosq_EXPORT int mosquitto_sub_topic_tokens_free(char ***topics, int count);
|
||||
*
|
||||
* Returns:
|
||||
* MOSQ_ERR_SUCCESS - on success
|
||||
* MOSQ_ERR_INVAL - if the input parameters were invalid.
|
||||
* MOSQ_ERR_NOMEM - if an out of memory condition occurred.
|
||||
* MOSQ_ERR_INVAL - if the input parameters were invalid.
|
||||
* MOSQ_ERR_NOMEM - if an out of memory condition occurred.
|
||||
*/
|
||||
libmosq_EXPORT int mosquitto_topic_matches_sub(const char *sub, const char *topic, bool *result);
|
||||
libmosq_EXPORT int mosquitto_topic_matches_sub2(const char *sub, size_t sublen, const char *topic, size_t topiclen, bool *result);
|
||||
|
||||
/*
|
||||
@ -2323,6 +2354,31 @@ libmosq_EXPORT int mosquitto_topic_matches_sub2(const char *sub, size_t sublen,
|
||||
*
|
||||
* Parameters:
|
||||
* topic - the topic to check
|
||||
*
|
||||
* Returns:
|
||||
* MOSQ_ERR_SUCCESS - for a valid topic
|
||||
* MOSQ_ERR_INVAL - if the topic contains a + or a #, or if it is too long.
|
||||
* MOSQ_ERR_MALFORMED_UTF8 - if sub or topic is not valid UTF-8
|
||||
*
|
||||
* See Also:
|
||||
* <mosquitto_sub_topic_check>
|
||||
*/
|
||||
libmosq_EXPORT int mosquitto_pub_topic_check(const char *topic);
|
||||
|
||||
/*
|
||||
* Function: mosquitto_pub_topic_check2
|
||||
*
|
||||
* Check whether a topic to be used for publishing is valid.
|
||||
*
|
||||
* This searches for + or # in a topic and checks its length.
|
||||
*
|
||||
* This check is already carried out in <mosquitto_publish> and
|
||||
* <mosquitto_will_set>, there is no need to call it directly before them. It
|
||||
* may be useful if you wish to check the validity of a topic in advance of
|
||||
* making a connection for example.
|
||||
*
|
||||
* Parameters:
|
||||
* topic - the topic to check
|
||||
* topiclen - length of the topic in bytes
|
||||
*
|
||||
* Returns:
|
||||
@ -2333,7 +2389,6 @@ libmosq_EXPORT int mosquitto_topic_matches_sub2(const char *sub, size_t sublen,
|
||||
* See Also:
|
||||
* <mosquitto_sub_topic_check>
|
||||
*/
|
||||
libmosq_EXPORT int mosquitto_pub_topic_check(const char *topic);
|
||||
libmosq_EXPORT int mosquitto_pub_topic_check2(const char *topic, size_t topiclen);
|
||||
|
||||
/*
|
||||
@ -2352,6 +2407,34 @@ libmosq_EXPORT int mosquitto_pub_topic_check2(const char *topic, size_t topiclen
|
||||
*
|
||||
* Parameters:
|
||||
* topic - the topic to check
|
||||
*
|
||||
* Returns:
|
||||
* MOSQ_ERR_SUCCESS - for a valid topic
|
||||
* MOSQ_ERR_INVAL - if the topic contains a + or a # that is in an
|
||||
* invalid position, or if it is too long.
|
||||
* MOSQ_ERR_MALFORMED_UTF8 - if topic is not valid UTF-8
|
||||
*
|
||||
* See Also:
|
||||
* <mosquitto_sub_topic_check>
|
||||
*/
|
||||
libmosq_EXPORT int mosquitto_sub_topic_check(const char *topic);
|
||||
|
||||
/*
|
||||
* Function: mosquitto_sub_topic_check2
|
||||
*
|
||||
* Check whether a topic to be used for subscribing is valid.
|
||||
*
|
||||
* This searches for + or # in a topic and checks that they aren't in invalid
|
||||
* positions, such as with foo/#/bar, foo/+bar or foo/bar#, and checks its
|
||||
* length.
|
||||
*
|
||||
* This check is already carried out in <mosquitto_subscribe> and
|
||||
* <mosquitto_unsubscribe>, there is no need to call it directly before them.
|
||||
* It may be useful if you wish to check the validity of a topic in advance of
|
||||
* making a connection for example.
|
||||
*
|
||||
* Parameters:
|
||||
* topic - the topic to check
|
||||
* topiclen - the length in bytes of the topic
|
||||
*
|
||||
* Returns:
|
||||
@ -2363,10 +2446,34 @@ libmosq_EXPORT int mosquitto_pub_topic_check2(const char *topic, size_t topiclen
|
||||
* See Also:
|
||||
* <mosquitto_sub_topic_check>
|
||||
*/
|
||||
libmosq_EXPORT int mosquitto_sub_topic_check(const char *topic);
|
||||
libmosq_EXPORT int mosquitto_sub_topic_check2(const char *topic, size_t topiclen);
|
||||
|
||||
|
||||
/*
|
||||
* Function: mosquitto_validate_utf8
|
||||
*
|
||||
* Helper function to validate whether a UTF-8 string is valid, according to
|
||||
* the UTF-8 spec and the MQTT additions.
|
||||
*
|
||||
* Parameters:
|
||||
* str - a string to check
|
||||
* len - the length of the string in bytes
|
||||
*
|
||||
* Returns:
|
||||
* MOSQ_ERR_SUCCESS - on success
|
||||
* MOSQ_ERR_INVAL - if str is NULL or len<0 or len>65536
|
||||
* MOSQ_ERR_MALFORMED_UTF8 - if str is not valid UTF-8
|
||||
*/
|
||||
libmosq_EXPORT int mosquitto_validate_utf8(const char *str, int len);
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
*
|
||||
* Section: One line client helper functions
|
||||
*
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
struct libmosquitto_will {
|
||||
char *topic;
|
||||
void *payload;
|
||||
@ -2497,24 +2604,6 @@ libmosq_EXPORT int mosquitto_subscribe_callback(
|
||||
const struct libmosquitto_tls *tls);
|
||||
|
||||
|
||||
/*
|
||||
* Function: mosquitto_validate_utf8
|
||||
*
|
||||
* Helper function to validate whether a UTF-8 string is valid, according to
|
||||
* the UTF-8 spec and the MQTT additions.
|
||||
*
|
||||
* Parameters:
|
||||
* str - a string to check
|
||||
* len - the length of the string in bytes
|
||||
*
|
||||
* Returns:
|
||||
* MOSQ_ERR_SUCCESS - on success
|
||||
* MOSQ_ERR_INVAL - if str is NULL or len<0 or len>65536
|
||||
* MOSQ_ERR_MALFORMED_UTF8 - if str is not valid UTF-8
|
||||
*/
|
||||
libmosq_EXPORT int mosquitto_validate_utf8(const char *str, int len);
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
*
|
||||
* Section: Properties
|
||||
|
@ -909,7 +909,6 @@ ssize_t net__read(struct mosquitto *mosq, void *buf, size_t count)
|
||||
errno = 0;
|
||||
#ifdef WITH_TLS
|
||||
if(mosq->ssl){
|
||||
ERR_clear_error();
|
||||
ret = SSL_read(mosq->ssl, buf, count);
|
||||
if(ret <= 0){
|
||||
err = SSL_get_error(mosq->ssl, ret);
|
||||
@ -924,6 +923,7 @@ ssize_t net__read(struct mosquitto *mosq, void *buf, size_t count)
|
||||
net__print_ssl_error(mosq);
|
||||
errno = EPROTO;
|
||||
}
|
||||
ERR_clear_error();
|
||||
#ifdef WIN32
|
||||
WSASetLastError(errno);
|
||||
#endif
|
||||
@ -957,7 +957,6 @@ ssize_t net__write(struct mosquitto *mosq, void *buf, size_t count)
|
||||
#ifdef WITH_TLS
|
||||
if(mosq->ssl){
|
||||
mosq->want_write = false;
|
||||
ERR_clear_error();
|
||||
ret = SSL_write(mosq->ssl, buf, count);
|
||||
if(ret < 0){
|
||||
err = SSL_get_error(mosq->ssl, ret);
|
||||
@ -972,6 +971,7 @@ ssize_t net__write(struct mosquitto *mosq, void *buf, size_t count)
|
||||
net__print_ssl_error(mosq);
|
||||
errno = EPROTO;
|
||||
}
|
||||
ERR_clear_error();
|
||||
#ifdef WIN32
|
||||
WSASetLastError(errno);
|
||||
#endif
|
||||
|
@ -11,492 +11,12 @@
|
||||
|
||||
<refnamediv>
|
||||
<refname>libmosquitto</refname>
|
||||
<refpurpose>MQTT version 3.1.1 client library</refpurpose>
|
||||
<refpurpose>MQTT version 5.0/3.1.1 client library</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
<para>This is an overview of how to use libmosquitto to create MQTT
|
||||
aware client programs. There may be separate man pages on each of the
|
||||
functions described here in the future.</para>
|
||||
<para>This man page is woefully incomplete, please see the comments
|
||||
in mosquitto.h for missing functions and a description of the
|
||||
functions.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>libmosquitto symbol names</title>
|
||||
<para>All public functions in libmosquitto have the prefix
|
||||
"mosquitto_". Any other functions defined in the source code are to be
|
||||
treated as private functions and may change between any release. Do not
|
||||
use these functions!</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Functions</title>
|
||||
|
||||
<refsect2>
|
||||
<title>Library version</title>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_lib_version</function></funcdef>
|
||||
<paramdef>int *<parameter>major</parameter></paramdef>
|
||||
<paramdef>int *<parameter>minor</parameter></paramdef>
|
||||
<paramdef>int *<parameter>revision</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
<para>Obtain version information about the library. If any of
|
||||
major, minor or revision are not NULL they will return the
|
||||
corresponding version numbers. The return value is an integer
|
||||
representation of the complete version number (e.g. 1009001 for 1.9.1)
|
||||
that can be used for comparisons.</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Library initialisation and cleanup</title>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_lib_init</function></funcdef>
|
||||
<void/></funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_lib_cleanup</function></funcdef>
|
||||
<void/></funcprototype></funcsynopsis>
|
||||
<para>Call mosquitto_lib_init() before using any of the other
|
||||
library functions and mosquitto_lib_cleanup() after finishing
|
||||
with the library.</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Client constructor/destructor</title>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>struct mosquitto *<function>mosquitto_new</function></funcdef>
|
||||
<paramdef>const char *<parameter>id</parameter></paramdef>
|
||||
<paramdef>bool <parameter>clean_session</parameter></paramdef>
|
||||
<paramdef>void *<parameter>userdata</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
<para>Create a new mosquitto client instance.</para>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>void <function>mosquitto_destroy</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
<para>Use to free memory associated with a mosquitto client instance.</para>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_reinitialise</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>id</parameter></paramdef>
|
||||
<paramdef>bool <parameter>clean_session</parameter></paramdef>
|
||||
<paramdef>void *<parameter>userdata</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Authentication and encryption</title>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_username_pw_set</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>username</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>password</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_tls_set</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>cafile</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>capath</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>certfile</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>keyfile</parameter></paramdef>
|
||||
<paramdef>int <parameter>(*pw_callback)(char *buf, int size, int rwflag, void *userdata)</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_tls_opts_set</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>int <parameter>cert_reqs</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>tls_version</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>ciphers</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_tls_insecure_set</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>bool <parameter>value</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_tls_psk_set</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>psk</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>identity</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>ciphers</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Wills</title>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_will_set</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>topic</parameter></paramdef>
|
||||
<paramdef>int <parameter>payloadlen</parameter></paramdef>
|
||||
<paramdef>const void *<parameter>payload</parameter></paramdef>
|
||||
<paramdef>int <parameter>qos</parameter></paramdef>
|
||||
<paramdef>bool <parameter>retain</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_will_clear</function></funcdef>
|
||||
<paramdef><parameter>struct mosquitto *mosq</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Connect/disconnect</title>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_connect</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>host</parameter></paramdef>
|
||||
<paramdef>int <parameter>port</parameter></paramdef>
|
||||
<paramdef>int <parameter>keepalive</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_connect_bind</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>host</parameter></paramdef>
|
||||
<paramdef>int <parameter>port</parameter></paramdef>
|
||||
<paramdef>int <parameter>keepalive</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>bind_address</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_connect_async</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>host</parameter></paramdef>
|
||||
<paramdef>int <parameter>port</parameter></paramdef>
|
||||
<paramdef>int <parameter>keepalive</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_connect_bind_async</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>host</parameter></paramdef>
|
||||
<paramdef>int <parameter>port</parameter></paramdef>
|
||||
<paramdef>int <parameter>keepalive</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>bind_address</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_reconnect</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_reconnect_async</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_disconnect</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Publish</title>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_publish</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>int *<parameter>mid</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>topic</parameter></paramdef>
|
||||
<paramdef>int <parameter>payloadlen</parameter></paramdef>
|
||||
<paramdef>const void *<parameter>payload</parameter></paramdef>
|
||||
<paramdef>int <parameter>qos</parameter></paramdef>
|
||||
<paramdef>bool <parameter>retain</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Subscribe/unsubscribe</title>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_subscribe</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>int *<parameter>mid</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>sub</parameter></paramdef>
|
||||
<paramdef>int <parameter>qos</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_unsubscribe</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>int *<parameter>mid</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>sub</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Network loop</title>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_loop</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>int <parameter>timeout</parameter></paramdef>
|
||||
<paramdef>int <parameter>max_packets</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_loop_read</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>int <parameter>max_packets</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_loop_write</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>int <parameter>max_packets</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_loop_misc</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_loop_forever</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>int <parameter>timeout</parameter></paramdef>
|
||||
<paramdef>int <parameter>max_packets</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_socket</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>bool <function>mosquitto_want_write</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Threaded network loop</title>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_loop_start</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_loop_stop</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>bool <parameter>force</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Misc client functions</title>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_max_inflight_messages_set</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>unsigned int <parameter>max_inflight_messages</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_reconnect_delay_set</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>unsigned int <parameter>reconnect_delay</parameter></paramdef>
|
||||
<paramdef>unsigned int <parameter>reconnect_delay_max</parameter></paramdef>
|
||||
<paramdef>bool <parameter>reconnect_exponential_backoff</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_user_data_set</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>void *<parameter>userdata</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Callbacks</title>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_connect_callback_set</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>void <parameter>(*on_connect)(struct mosquitto *, void *, int)</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_disconnect_callback_set</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>void <parameter>(*on_disconnect)(struct mosquitto *, void *, int)</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_publish_callback_set</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>void <parameter>(*on_publish)(struct mosquitto *, void *, int)</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_message_callback_set</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>void <parameter>(*on_message)(struct mosquitto *, void *, const struct mosquitto_message *)</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_subscribe_callback_set</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>void <parameter>(*on_subscribe)(struct mosquitto *, void *, int, int, const int *)</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_unsubscribe_callback_set</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>void <parameter>(*on_unsubscribe)(struct mosquitto *, void *, int)</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_log_callback_set</function></funcdef>
|
||||
<paramdef>struct mosquitto *<parameter>mosq</parameter></paramdef>
|
||||
<paramdef>void <parameter>(*on_unsubscribe)(struct mosquitto *, void *, int, const char *)</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Utility functions</title>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>const char *<function>mosquitto_connack_string</function></funcdef>
|
||||
<paramdef>int <parameter>connack_code</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_message_copy</function></funcdef>
|
||||
<paramdef>struct mosquitto_message *<parameter>dst</parameter></paramdef>
|
||||
<paramdef>const struct mosquitto_message *<parameter>src</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_message_free</function></funcdef>
|
||||
<paramdef>struct mosquitto_message **<parameter>message</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>const char *<function>mosquitto_strerror</function></funcdef>
|
||||
<paramdef>int <parameter>mosq_errno</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_sub_topic_tokenise</function></funcdef>
|
||||
<paramdef>const char *<parameter>subtopic</parameter></paramdef>
|
||||
<paramdef>char ***<parameter>topics</parameter></paramdef>
|
||||
<paramdef>int *<parameter>count</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_sub_topic_tokens_free</function></funcdef>
|
||||
<paramdef>char ***<parameter>topics</parameter></paramdef>
|
||||
<paramdef>int <parameter>count</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_topic_matches_sub</function></funcdef>
|
||||
<paramdef>const char *<parameter>sub</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>topic</parameter></paramdef>
|
||||
<paramdef>bool *<parameter>result</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Helper functions</title>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_subscribe_simple</function></funcdef>
|
||||
<paramdef>struct mosquitto_message **<parameter>message</parameter></paramdef>
|
||||
<paramdef>int <parameter>msg_count</parameter></paramdef>
|
||||
<paramdef>bool <parameter>want_retained</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>topic</parameter></paramdef>
|
||||
<paramdef>int<parameter>qos</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>host</parameter></paramdef>
|
||||
<paramdef>int <parameter>port</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>client_id</parameter></paramdef>
|
||||
<paramdef>int <parameter>keepalive</parameter></paramdef>
|
||||
<paramdef>bool <parameter>clean_session</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>username</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>password</parameter></paramdef>
|
||||
<paramdef>const struct libmosquitto_will *<parameter>will</parameter></paramdef>
|
||||
<paramdef>const struct libmosquitto_tls *<parameter>tls</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
|
||||
<funcsynopsis><funcprototype><funcdef>int <function>mosquitto_subscribe_callback</function></funcdef>
|
||||
<paramdef>int <parameter>(*callback)(struct mosquitto *, void *, const struct mosquitto_message *)</parameter></paramdef>
|
||||
<paramdef>void *<parameter>userdata</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>topic</parameter></paramdef>
|
||||
<paramdef>int <parameter>qos</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>host</parameter></paramdef>
|
||||
<paramdef>int <parameter>port</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>client_id</parameter></paramdef>
|
||||
<paramdef>int <parameter>keepalive</parameter></paramdef>
|
||||
<paramdef>bool <parameter>clean_session</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>username</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>password</parameter></paramdef>
|
||||
<paramdef>const struct libmosquitto_will *<parameter>will</parameter></paramdef>
|
||||
<paramdef>const struct libmosquitto_tls *<parameter>tls</parameter></paramdef>
|
||||
</funcprototype></funcsynopsis>
|
||||
</refsect2>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Examples</title>
|
||||
<para><programlisting language="C">
|
||||
#include <stdio.h>
|
||||
#include <mosquitto.h>
|
||||
|
||||
void my_message_callback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message)
|
||||
{
|
||||
if(message->payloadlen){
|
||||
printf("%s %s\n", message->topic, message->payload);
|
||||
}else{
|
||||
printf("%s (null)\n", message->topic);
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void my_connect_callback(struct mosquitto *mosq, void *userdata, int result)
|
||||
{
|
||||
int i;
|
||||
if(!result){
|
||||
/* Subscribe to broker information topics on successful connect. */
|
||||
mosquitto_subscribe(mosq, NULL, "$SYS/#", 2);
|
||||
}else{
|
||||
fprintf(stderr, "Connect failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
void my_subscribe_callback(struct mosquitto *mosq, void *userdata, int mid, int qos_count, const int *granted_qos)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("Subscribed (mid: %d): %d", mid, granted_qos[0]);
|
||||
for(i=1; i<qos_count; i++){
|
||||
printf(", %d", granted_qos[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void my_log_callback(struct mosquitto *mosq, void *userdata, int level, const char *str)
|
||||
{
|
||||
/* Pring all log messages regardless of level. */
|
||||
printf("%s\n", str);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
char *host = "localhost";
|
||||
int port = 1883;
|
||||
int keepalive = 60;
|
||||
bool clean_session = true;
|
||||
struct mosquitto *mosq = NULL;
|
||||
|
||||
mosquitto_lib_init();
|
||||
mosq = mosquitto_new(NULL, clean_session, NULL);
|
||||
if(!mosq){
|
||||
fprintf(stderr, "Error: Out of memory.\n");
|
||||
return 1;
|
||||
}
|
||||
mosquitto_log_callback_set(mosq, my_log_callback);
|
||||
mosquitto_connect_callback_set(mosq, my_connect_callback);
|
||||
mosquitto_message_callback_set(mosq, my_message_callback);
|
||||
mosquitto_subscribe_callback_set(mosq, my_subscribe_callback);
|
||||
|
||||
if(mosquitto_connect(mosq, host, port, keepalive)){
|
||||
fprintf(stderr, "Unable to connect.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
mosquitto_loop_forever(mosq, -1, 1);
|
||||
|
||||
mosquitto_destroy(mosq);
|
||||
mosquitto_lib_cleanup();
|
||||
return 0;
|
||||
}
|
||||
</programlisting></para>
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
<title>See Also</title>
|
||||
<simplelist type="inline">
|
||||
<member>
|
||||
<citerefentry>
|
||||
<refentrytitle><link xlink:href="mosquitto-8.html">mosquitto</link></refentrytitle>
|
||||
<manvolnum>8</manvolnum>
|
||||
</citerefentry>
|
||||
<citerefentry>
|
||||
<refentrytitle><link xlink:href="mqtt-7.html">mqtt</link></refentrytitle>
|
||||
<manvolnum>7</manvolnum>
|
||||
</citerefentry>
|
||||
</member>
|
||||
</simplelist>
|
||||
<title>Documentation</title>
|
||||
<para>See <ulink url="https://mosquitto.org/api/"/></para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
@ -339,7 +339,7 @@
|
||||
<term><option>-l</option></term>
|
||||
<term><option>--stdin-line</option></term>
|
||||
<listitem>
|
||||
<para>Send messages read from stdin, splitting separate lines into separate messages. Note that blank lines won't be sent.</para>
|
||||
<para>Send messages read from stdin, splitting separate lines into separate messages.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
MAJOR=1
|
||||
MINOR=6
|
||||
REVISION=7
|
||||
REVISION=8
|
||||
|
||||
sed -i "s/^VERSION=.*/VERSION=${MAJOR}.${MINOR}.${REVISION}/" config.mk
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
name: mosquitto
|
||||
version: 1.6.7
|
||||
version: 1.6.8
|
||||
summary: Eclipse Mosquitto MQTT broker
|
||||
description: This is a message broker that supports version 3.1 and 3.1.1 of the MQTT
|
||||
protocol.
|
||||
@ -16,18 +16,23 @@ apps:
|
||||
command: launcher.sh
|
||||
daemon: simple
|
||||
restart-condition: always
|
||||
plugs: [network, network-bind]
|
||||
plugs: [home, network, network-bind]
|
||||
|
||||
pub:
|
||||
command: usr/bin/mosquitto_pub
|
||||
plugs: [network]
|
||||
plugs: [home, network]
|
||||
|
||||
rr:
|
||||
command: usr/bin/mosquitto_rr
|
||||
plugs: [home, network]
|
||||
|
||||
sub:
|
||||
command: usr/bin/mosquitto_sub
|
||||
plugs: [network]
|
||||
plugs: [home, network]
|
||||
|
||||
passwd:
|
||||
command: usr/bin/mosquitto_passwd
|
||||
plugs: [home]
|
||||
|
||||
|
||||
parts:
|
||||
@ -64,6 +69,7 @@ parts:
|
||||
prime:
|
||||
- usr/sbin/mosquitto
|
||||
- usr/bin/mosquitto_pub
|
||||
- usr/bin/mosquitto_rr
|
||||
- usr/bin/mosquitto_sub
|
||||
- usr/bin/mosquitto_passwd
|
||||
- usr/lib/libmosquitto.so*
|
||||
|
@ -271,6 +271,7 @@ void config__init(struct mosquitto_db *db, struct mosquitto__config *config)
|
||||
config->default_listener.max_connections = -1;
|
||||
config->default_listener.protocol = mp_mqtt;
|
||||
config->default_listener.security_options.allow_anonymous = -1;
|
||||
config->default_listener.security_options.allow_zero_length_clientid = true;
|
||||
config->default_listener.maximum_qos = 2;
|
||||
config->default_listener.max_topic_alias = 10;
|
||||
}
|
||||
@ -474,6 +475,7 @@ int config__parse_args(struct mosquitto_db *db, struct mosquitto__config *config
|
||||
|| config->default_listener.security_options.psk_file
|
||||
|| config->default_listener.security_options.auth_plugin_config_count
|
||||
|| config->default_listener.security_options.allow_anonymous != -1
|
||||
|| config->default_listener.security_options.allow_zero_length_clientid != true
|
||||
){
|
||||
|
||||
config->listener_count++;
|
||||
@ -532,6 +534,7 @@ int config__parse_args(struct mosquitto_db *db, struct mosquitto__config *config
|
||||
config->listeners[config->listener_count-1].security_options.auth_plugin_configs = config->default_listener.security_options.auth_plugin_configs;
|
||||
config->listeners[config->listener_count-1].security_options.auth_plugin_config_count = config->default_listener.security_options.auth_plugin_config_count;
|
||||
config->listeners[config->listener_count-1].security_options.allow_anonymous = config->default_listener.security_options.allow_anonymous;
|
||||
config->listeners[config->listener_count-1].security_options.allow_zero_length_clientid = config->default_listener.security_options.allow_zero_length_clientid;
|
||||
}
|
||||
|
||||
/* Default to drop to mosquitto user if we are privileged and no user specified. */
|
||||
@ -641,6 +644,7 @@ int config__read(struct mosquitto_db *db, struct mosquitto__config *config, bool
|
||||
config__init_reload(db, &config_reload);
|
||||
config_reload.listeners = config->listeners;
|
||||
config_reload.listener_count = config->listener_count;
|
||||
cur_security_options = NULL;
|
||||
rc = config__read_file(&config_reload, reload, db->config_file, &cr, 0, &lineno);
|
||||
}else{
|
||||
rc = config__read_file(config, reload, db->config_file, &cr, 0, &lineno);
|
||||
@ -1441,6 +1445,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
|
||||
}
|
||||
|
||||
cur_listener->security_options.allow_anonymous = -1;
|
||||
cur_listener->security_options.allow_zero_length_clientid = true;
|
||||
cur_listener->protocol = mp_mqtt;
|
||||
cur_listener->port = tmp_int;
|
||||
cur_listener->maximum_qos = 2;
|
||||
|
@ -201,8 +201,11 @@ void context__disconnect(struct mosquitto_db *db, struct mosquitto *context)
|
||||
|
||||
context__send_will(db, context);
|
||||
if(context->session_expiry_interval == 0){
|
||||
|
||||
if(context->bridge == NULL){
|
||||
/* Client session is due to be expired now */
|
||||
#ifdef WITH_BRIDGE
|
||||
if(context->bridge == NULL)
|
||||
#endif
|
||||
{
|
||||
if(context->will_delay_interval == 0){
|
||||
/* This will be done later, after the will is published for delay>0. */
|
||||
context__add_to_disused(db, context);
|
||||
|
@ -160,6 +160,9 @@ int connect__on_authorised(struct mosquitto_db *db, struct mosquitto *context, v
|
||||
}
|
||||
}
|
||||
|
||||
if(context->clean_start == true){
|
||||
sub__clean_session(db, found_context);
|
||||
}
|
||||
session_expiry__remove(found_context);
|
||||
will_delay__remove(found_context);
|
||||
will__clear(found_context);
|
||||
|
36
src/loop.c
36
src/loop.c
@ -126,7 +126,6 @@ int mosquitto_main_loop(struct mosquitto_db *db, mosq_sock_t *listensock, int li
|
||||
#endif
|
||||
int i;
|
||||
#ifdef WITH_EPOLL
|
||||
int rc;
|
||||
int j;
|
||||
struct epoll_event ev, events[MAX_EVENTS];
|
||||
#else
|
||||
@ -134,8 +133,9 @@ int mosquitto_main_loop(struct mosquitto_db *db, mosq_sock_t *listensock, int li
|
||||
int pollfd_index;
|
||||
int pollfd_max;
|
||||
#endif
|
||||
time_t expiration_check_time = 0;
|
||||
char *id;
|
||||
#ifdef WITH_BRIDGE
|
||||
int rc;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(WITH_WEBSOCKETS) && LWS_LIBRARY_VERSION_NUMBER == 3002000
|
||||
@ -165,10 +165,6 @@ int mosquitto_main_loop(struct mosquitto_db *db, mosq_sock_t *listensock, int li
|
||||
}
|
||||
#endif
|
||||
|
||||
if(db->config->persistent_client_expiration > 0){
|
||||
expiration_check_time = time(NULL) + 3600;
|
||||
}
|
||||
|
||||
#ifdef WITH_EPOLL
|
||||
db->epollfd = 0;
|
||||
if ((db->epollfd = epoll_create(MAX_EVENTS)) == -1) {
|
||||
@ -286,32 +282,6 @@ int mosquitto_main_loop(struct mosquitto_db *db, mosq_sock_t *listensock, int li
|
||||
# endif
|
||||
#endif
|
||||
|
||||
now = time(NULL);
|
||||
if(db->config->persistent_client_expiration > 0 && now > expiration_check_time){
|
||||
HASH_ITER(hh_id, db->contexts_by_id, context, ctxt_tmp){
|
||||
if(context->sock == INVALID_SOCKET && context->session_expiry_interval > 0 && context->session_expiry_interval != UINT32_MAX){
|
||||
/* This is a persistent client, check to see if the
|
||||
* last time it connected was longer than
|
||||
* persistent_client_expiration seconds ago. If so,
|
||||
* expire it and clean up.
|
||||
*/
|
||||
if(now > context->session_expiry_time){
|
||||
if(context->id){
|
||||
id = context->id;
|
||||
}else{
|
||||
id = "<unknown>";
|
||||
}
|
||||
log__printf(NULL, MOSQ_LOG_NOTICE, "Expiring persistent client %s due to timeout.", id);
|
||||
G_CLIENTS_EXPIRED_INC();
|
||||
context->session_expiry_interval = 0;
|
||||
mosquitto__set_state(context, mosq_cs_expiring);
|
||||
do_disconnect(db, context, MOSQ_ERR_SUCCESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
expiration_check_time = time(NULL) + 3600;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
sigprocmask(SIG_SETMASK, &sigblock, &origsig);
|
||||
#ifdef WITH_EPOLL
|
||||
|
@ -431,7 +431,7 @@ int net__load_crl_file(struct mosquitto__listener *listener)
|
||||
}
|
||||
lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
|
||||
rc = X509_load_crl_file(lookup, listener->crlfile, X509_FILETYPE_PEM);
|
||||
if(rc != 1){
|
||||
if(rc < 1){
|
||||
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load certificate revocation file \"%s\". Check crlfile.", listener->crlfile);
|
||||
net__print_error(MOSQ_LOG_ERR, "Error: %s");
|
||||
return 1;
|
||||
|
@ -114,6 +114,12 @@ static int persist__client_msg_restore(struct mosquitto_db *db, struct P_client_
|
||||
struct mosquitto *context;
|
||||
struct mosquitto_msg_data *msg_data;
|
||||
|
||||
HASH_FIND(hh, db->msg_store_load, &chunk->F.store_id, sizeof(dbid_t), load);
|
||||
if(!load){
|
||||
/* Can't find message - probably expired */
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
cmsg = mosquitto__calloc(1, sizeof(struct mosquitto_client_msg));
|
||||
if(!cmsg){
|
||||
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
|
||||
@ -131,12 +137,6 @@ static int persist__client_msg_restore(struct mosquitto_db *db, struct P_client_
|
||||
cmsg->dup = chunk->F.retain_dup&0x0F;
|
||||
cmsg->properties = chunk->properties;
|
||||
|
||||
HASH_FIND(hh, db->msg_store_load, &chunk->F.store_id, sizeof(dbid_t), load);
|
||||
if(!load){
|
||||
mosquitto__free(cmsg);
|
||||
log__printf(NULL, MOSQ_LOG_ERR, "Error restoring persistent database, message store corrupt.");
|
||||
return 1;
|
||||
}
|
||||
cmsg->store = load->store;
|
||||
db__msg_store_ref_inc(cmsg->store);
|
||||
|
||||
@ -273,7 +273,13 @@ static int persist__msg_store_chunk_restore(struct mosquitto_db *db, FILE *db_fp
|
||||
if(chunk.F.expiry_time > 0){
|
||||
message_expiry_interval64 = chunk.F.expiry_time - time(NULL);
|
||||
if(message_expiry_interval64 < 0 || message_expiry_interval64 > UINT32_MAX){
|
||||
message_expiry_interval = 0;
|
||||
/* Expired message */
|
||||
mosquitto__free(chunk.source.id);
|
||||
mosquitto__free(chunk.source.username);
|
||||
mosquitto__free(chunk.topic);
|
||||
UHPA_FREE(chunk.payload, chunk.F.payloadlen);
|
||||
mosquitto__free(load);
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}else{
|
||||
message_expiry_interval = (uint32_t)message_expiry_interval64;
|
||||
}
|
||||
@ -327,8 +333,7 @@ static int persist__retain_chunk_restore(struct mosquitto_db *db, FILE *db_fptr)
|
||||
if(load){
|
||||
retain__store(db, load->store->topic, load->store, NULL);
|
||||
}else{
|
||||
log__printf(NULL, MOSQ_LOG_ERR, "Error: Corrupt database whilst restoring a retained message.");
|
||||
return MOSQ_ERR_INVAL;
|
||||
/* Can't find the message - probably expired */
|
||||
}
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ static int retain__process(struct mosquitto_db *db, struct mosquitto__retainhier
|
||||
mosquitto_property *properties = NULL;
|
||||
struct mosquitto_msg_store *retained;
|
||||
|
||||
if(branch->retained->message_expiry_time > 0 && now > branch->retained->message_expiry_time){
|
||||
if(branch->retained->message_expiry_time > 0 && now >= branch->retained->message_expiry_time){
|
||||
db__msg_store_ref_dec(db, &branch->retained);
|
||||
branch->retained = NULL;
|
||||
#ifdef WITH_SYS_TREE
|
||||
|
@ -22,6 +22,7 @@ Contributors:
|
||||
|
||||
#include "mosquitto_broker_internal.h"
|
||||
#include "memory_mosq.h"
|
||||
#include "sys_tree.h"
|
||||
#include "time_mosq.h"
|
||||
|
||||
static struct session_expiry_list *expiry_list = NULL;
|
||||
@ -38,17 +39,32 @@ int session_expiry__add(struct mosquitto_db *db, struct mosquitto *context)
|
||||
{
|
||||
struct session_expiry_list *item;
|
||||
|
||||
if(db->config->persistent_client_expiration == 0){
|
||||
if(context->session_expiry_interval == UINT32_MAX){
|
||||
/* There isn't a global expiry set, and the client has asked to
|
||||
* never expire, so we don't add it to the list. */
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
item = mosquitto__calloc(1, sizeof(struct session_expiry_list));
|
||||
if(!item) return MOSQ_ERR_NOMEM;
|
||||
|
||||
item->context = context;
|
||||
item->context->session_expiry_time = time(NULL);
|
||||
if(db->config->persistent_client_expiration == 0 ||
|
||||
db->config->persistent_client_expiration < item->context->session_expiry_interval){
|
||||
|
||||
if(db->config->persistent_client_expiration == 0){
|
||||
/* No global expiry, so use the client expiration interval */
|
||||
item->context->session_expiry_time += item->context->session_expiry_interval;
|
||||
}else{
|
||||
item->context->session_expiry_time += db->config->persistent_client_expiration;
|
||||
/* We have a global expiry interval */
|
||||
if(db->config->persistent_client_expiration < item->context->session_expiry_interval){
|
||||
/* The client expiry is longer than the global expiry, so use the global */
|
||||
item->context->session_expiry_time += db->config->persistent_client_expiration;
|
||||
}else{
|
||||
/* The global expiry is longer than the client expiry, so use the client */
|
||||
item->context->session_expiry_time += item->context->session_expiry_interval;
|
||||
}
|
||||
}
|
||||
context->expiry_list_item = item;
|
||||
|
||||
@ -95,12 +111,16 @@ void session_expiry__check(struct mosquitto_db *db, time_t now)
|
||||
last_check = now;
|
||||
|
||||
DL_FOREACH_SAFE(expiry_list, item, tmp){
|
||||
if(item->context->session_expiry_interval != UINT32_MAX
|
||||
&& item->context->session_expiry_time < now){
|
||||
if(item->context->session_expiry_time < now){
|
||||
|
||||
context = item->context;
|
||||
session_expiry__remove(context);
|
||||
|
||||
if(context->id){
|
||||
log__printf(NULL, MOSQ_LOG_NOTICE, "Expiring client %s due to timeout.", context->id);
|
||||
}
|
||||
G_CLIENTS_EXPIRED_INC();
|
||||
|
||||
/* Session has now expired, so clear interval */
|
||||
context->session_expiry_interval = 0;
|
||||
/* Session has expired, so will delay should be cleared. */
|
||||
|
@ -151,6 +151,7 @@ static int subs__process(struct mosquitto_db *db, struct mosquitto__subhier *hie
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int sub__add_leaf(struct mosquitto *context, int qos, uint32_t identifier, int options, struct mosquitto__subleaf **head, struct mosquitto__subleaf **newleaf)
|
||||
{
|
||||
struct mosquitto__subleaf *leaf;
|
||||
@ -539,7 +540,7 @@ struct mosquitto__subhier *sub__add_hier_entry(struct mosquitto__subhier *parent
|
||||
}
|
||||
child->parent = parent;
|
||||
child->topic_len = len;
|
||||
child->topic = malloc(len+1);
|
||||
child->topic = mosquitto__malloc(len+1);
|
||||
if(!child->topic){
|
||||
child->topic_len = 0;
|
||||
mosquitto__free(child);
|
||||
@ -829,4 +830,3 @@ void sub__tree_print(struct mosquitto__subhier *root, int level)
|
||||
sub__tree_print(branch->children, level+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,6 +66,7 @@ int sub__topic_tokenise(const char *subtopic, struct sub__token **topics)
|
||||
int start, stop, tlen;
|
||||
int i;
|
||||
char *topic;
|
||||
int count = 0;
|
||||
|
||||
assert(subtopic);
|
||||
assert(topics);
|
||||
@ -90,6 +91,7 @@ int sub__topic_tokenise(const char *subtopic, struct sub__token **topics)
|
||||
for(i=start; i<len+1; i++){
|
||||
if(subtopic[i] == '/' || subtopic[i] == '\0'){
|
||||
stop = i;
|
||||
count++;
|
||||
|
||||
if(start != stop){
|
||||
tlen = stop-start;
|
||||
@ -108,6 +110,11 @@ int sub__topic_tokenise(const char *subtopic, struct sub__token **topics)
|
||||
}
|
||||
}
|
||||
|
||||
if(count > TOPIC_HIERARCHY_LIMIT){
|
||||
/* Set limit on hierarchy levels, to restrict stack usage. */
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
|
@ -22,8 +22,10 @@ def do_test(proto_ver):
|
||||
sock.close()
|
||||
if len(data) == 0:
|
||||
rc = 0
|
||||
except socket.error:
|
||||
rc = 0
|
||||
except socket.error as e:
|
||||
if e.errno == errno.ECONNRESET:
|
||||
# Connection has been closed by peer, this is the expected behaviour
|
||||
rc = 0
|
||||
finally:
|
||||
broker.terminate()
|
||||
broker.wait()
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Test whether a CONNECT with a zero length client id results in the correct CONNACK packet.
|
||||
|
||||
# MQTT V3.1 only - zero length is invalid.
|
||||
from mosq_test_helper import *
|
||||
|
||||
def do_test(proto_ver):
|
||||
|
@ -15,7 +15,10 @@ try:
|
||||
sock = mosq_test.do_client_connect(connect_packet, b"", port=port)
|
||||
sock.close()
|
||||
rc = 0
|
||||
|
||||
except socket.error as e:
|
||||
if e.errno == errno.ECONNRESET:
|
||||
# Connection has been closed by peer, this is the expected behaviour
|
||||
rc = 0
|
||||
finally:
|
||||
broker.terminate()
|
||||
broker.wait()
|
||||
|
125
test/broker/01-connect-zero-length-id.py
Executable file
125
test/broker/01-connect-zero-length-id.py
Executable file
@ -0,0 +1,125 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Test whether a CONNECT with a zero length client id results in the correct behaviour.
|
||||
|
||||
# MQTT v3.1.1 - zero length is allowed, unless allow_zero_length_clientid is false, and unless clean_start is False.
|
||||
# MQTT v5.0 - zero length is allowed, unless allow_zero_length_clientid is false
|
||||
|
||||
from mosq_test_helper import *
|
||||
|
||||
def write_config(filename, port1, port2, per_listener, allow_zero):
|
||||
with open(filename, 'w') as f:
|
||||
f.write("per_listener_settings %s\n" % (per_listener))
|
||||
f.write("port %d\n" % (port2))
|
||||
if allow_zero != "":
|
||||
f.write("allow_zero_length_clientid %s\n" % (allow_zero))
|
||||
f.write("listener %d\n" % (port1))
|
||||
if allow_zero != "":
|
||||
f.write("allow_zero_length_clientid %s\n" % (allow_zero))
|
||||
|
||||
|
||||
def do_test(per_listener, proto_ver, clean_start, allow_zero, client_port, expect_fail):
|
||||
conf_file = os.path.basename(__file__).replace('.py', '.conf')
|
||||
write_config(conf_file, port1, port2, per_listener, allow_zero)
|
||||
|
||||
rc = 1
|
||||
keepalive = 10
|
||||
connect_packet = mosq_test.gen_connect("", keepalive=keepalive, proto_ver=proto_ver, clean_session=clean_start)
|
||||
if proto_ver == 4:
|
||||
if expect_fail == True:
|
||||
connack_packet = mosq_test.gen_connack(rc=2, proto_ver=proto_ver)
|
||||
else:
|
||||
connack_packet = mosq_test.gen_connack(rc=0, proto_ver=proto_ver)
|
||||
else:
|
||||
if expect_fail == True:
|
||||
connack_packet = mosq_test.gen_connack(rc=128, proto_ver=proto_ver, properties=None)
|
||||
else:
|
||||
props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_ASSIGNED_CLIENT_IDENTIFIER, "auto-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
|
||||
connack_packet = mosq_test.gen_connack(rc=0, proto_ver=proto_ver, properties=props)
|
||||
# Remove the "xxxx" part - this means the front part of the packet
|
||||
# is correct (so remaining length etc. is correct), but we don't
|
||||
# need to match against the random id.
|
||||
connack_packet = connack_packet[:-36]
|
||||
|
||||
broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port1, use_conf=True)
|
||||
|
||||
try:
|
||||
sock = mosq_test.do_client_connect(connect_packet, connack_packet, port=client_port)
|
||||
sock.close()
|
||||
rc = 0
|
||||
finally:
|
||||
broker.terminate()
|
||||
broker.wait()
|
||||
(stdo, stde) = broker.communicate()
|
||||
os.remove(conf_file)
|
||||
if rc:
|
||||
print(stde.decode('utf-8'))
|
||||
print("per_listener:%s proto_ver:%d client_port:%d clean_start:%d allow_zero:%s" % (per_listener, proto_ver, client_port, clean_start, allow_zero))
|
||||
print("port1:%d port2:%d" % (port1, port2))
|
||||
exit(rc)
|
||||
|
||||
|
||||
(port1, port2) = mosq_test.get_port(2)
|
||||
|
||||
test_v4 = True
|
||||
test_v5 = True
|
||||
|
||||
if test_v4 == True:
|
||||
do_test(per_listener="false", proto_ver=4, client_port=port1, clean_start=True, allow_zero="true", expect_fail=False)
|
||||
do_test(per_listener="false", proto_ver=4, client_port=port1, clean_start=True, allow_zero="false", expect_fail=True)
|
||||
do_test(per_listener="false", proto_ver=4, client_port=port1, clean_start=False, allow_zero="true", expect_fail=True)
|
||||
do_test(per_listener="false", proto_ver=4, client_port=port1, clean_start=False, allow_zero="false", expect_fail=True)
|
||||
do_test(per_listener="true", proto_ver=4, client_port=port1, clean_start=True, allow_zero="true", expect_fail=False)
|
||||
do_test(per_listener="true", proto_ver=4, client_port=port1, clean_start=True, allow_zero="false", expect_fail=True)
|
||||
do_test(per_listener="true", proto_ver=4, client_port=port1, clean_start=False, allow_zero="true", expect_fail=True)
|
||||
do_test(per_listener="true", proto_ver=4, client_port=port1, clean_start=False, allow_zero="false", expect_fail=True)
|
||||
|
||||
do_test(per_listener="false", proto_ver=4, client_port=port2, clean_start=True, allow_zero="true", expect_fail=False)
|
||||
do_test(per_listener="false", proto_ver=4, client_port=port2, clean_start=True, allow_zero="false", expect_fail=True)
|
||||
do_test(per_listener="false", proto_ver=4, client_port=port2, clean_start=False, allow_zero="true", expect_fail=True)
|
||||
do_test(per_listener="false", proto_ver=4, client_port=port2, clean_start=False, allow_zero="false", expect_fail=True)
|
||||
do_test(per_listener="true", proto_ver=4, client_port=port2, clean_start=True, allow_zero="true", expect_fail=False)
|
||||
do_test(per_listener="true", proto_ver=4, client_port=port2, clean_start=True, allow_zero="false", expect_fail=True)
|
||||
do_test(per_listener="true", proto_ver=4, client_port=port2, clean_start=False, allow_zero="true", expect_fail=True)
|
||||
do_test(per_listener="true", proto_ver=4, client_port=port2, clean_start=False, allow_zero="false", expect_fail=True)
|
||||
|
||||
do_test(per_listener="false", proto_ver=4, client_port=port1, clean_start=True, allow_zero="", expect_fail=False)
|
||||
do_test(per_listener="false", proto_ver=4, client_port=port1, clean_start=False, allow_zero="", expect_fail=True)
|
||||
do_test(per_listener="true", proto_ver=4, client_port=port1, clean_start=True, allow_zero="", expect_fail=False)
|
||||
do_test(per_listener="true", proto_ver=4, client_port=port1, clean_start=False, allow_zero="", expect_fail=True)
|
||||
|
||||
do_test(per_listener="false", proto_ver=4, client_port=port2, clean_start=True, allow_zero="", expect_fail=False)
|
||||
do_test(per_listener="false", proto_ver=4, client_port=port2, clean_start=False, allow_zero="", expect_fail=True)
|
||||
do_test(per_listener="true", proto_ver=4, client_port=port2, clean_start=True, allow_zero="", expect_fail=False)
|
||||
do_test(per_listener="true", proto_ver=4, client_port=port2, clean_start=False, allow_zero="", expect_fail=True)
|
||||
|
||||
if test_v5 == True:
|
||||
do_test(per_listener="false", proto_ver=5, client_port=port1, clean_start=True, allow_zero="true", expect_fail=False)
|
||||
do_test(per_listener="false", proto_ver=5, client_port=port1, clean_start=True, allow_zero="false", expect_fail=True)
|
||||
do_test(per_listener="false", proto_ver=5, client_port=port1, clean_start=False, allow_zero="true", expect_fail=False)
|
||||
do_test(per_listener="false", proto_ver=5, client_port=port1, clean_start=False, allow_zero="false", expect_fail=True)
|
||||
do_test(per_listener="true", proto_ver=5, client_port=port1, clean_start=True, allow_zero="true", expect_fail=False)
|
||||
do_test(per_listener="true", proto_ver=5, client_port=port1, clean_start=True, allow_zero="false", expect_fail=True)
|
||||
do_test(per_listener="true", proto_ver=5, client_port=port1, clean_start=False, allow_zero="true", expect_fail=False)
|
||||
do_test(per_listener="true", proto_ver=5, client_port=port1, clean_start=False, allow_zero="false", expect_fail=True)
|
||||
|
||||
do_test(per_listener="false", proto_ver=5, client_port=port2, clean_start=True, allow_zero="true", expect_fail=False)
|
||||
do_test(per_listener="false", proto_ver=5, client_port=port2, clean_start=True, allow_zero="false", expect_fail=True)
|
||||
do_test(per_listener="false", proto_ver=5, client_port=port2, clean_start=False, allow_zero="true", expect_fail=False)
|
||||
do_test(per_listener="false", proto_ver=5, client_port=port2, clean_start=False, allow_zero="false", expect_fail=True)
|
||||
do_test(per_listener="true", proto_ver=5, client_port=port2, clean_start=True, allow_zero="true", expect_fail=False)
|
||||
do_test(per_listener="true", proto_ver=5, client_port=port2, clean_start=True, allow_zero="false", expect_fail=True)
|
||||
do_test(per_listener="true", proto_ver=5, client_port=port2, clean_start=False, allow_zero="true", expect_fail=False)
|
||||
do_test(per_listener="true", proto_ver=5, client_port=port2, clean_start=False, allow_zero="false", expect_fail=True)
|
||||
|
||||
do_test(per_listener="false", proto_ver=5, client_port=port1, clean_start=True, allow_zero="", expect_fail=False)
|
||||
do_test(per_listener="false", proto_ver=5, client_port=port1, clean_start=False, allow_zero="", expect_fail=False)
|
||||
do_test(per_listener="true", proto_ver=5, client_port=port1, clean_start=True, allow_zero="", expect_fail=False)
|
||||
do_test(per_listener="true", proto_ver=5, client_port=port1, clean_start=False, allow_zero="", expect_fail=False)
|
||||
|
||||
do_test(per_listener="false", proto_ver=5, client_port=port2, clean_start=True, allow_zero="", expect_fail=False)
|
||||
do_test(per_listener="false", proto_ver=5, client_port=port2, clean_start=False, allow_zero="", expect_fail=False)
|
||||
do_test(per_listener="true", proto_ver=5, client_port=port2, clean_start=True, allow_zero="", expect_fail=False)
|
||||
do_test(per_listener="true", proto_ver=5, client_port=port2, clean_start=False, allow_zero="", expect_fail=False)
|
||||
|
||||
exit(0)
|
50
test/broker/02-subpub-qos0-long-topic.py
Executable file
50
test/broker/02-subpub-qos0-long-topic.py
Executable file
@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Test whether a client subscribed to a topic receives its own message sent to that topic, for long topics.
|
||||
|
||||
from mosq_test_helper import *
|
||||
|
||||
def do_test(topic, succeeds):
|
||||
rc = 1
|
||||
mid = 53
|
||||
keepalive = 60
|
||||
connect_packet = mosq_test.gen_connect("subpub-qos0-test", keepalive=keepalive)
|
||||
connack_packet = mosq_test.gen_connack(rc=0)
|
||||
|
||||
subscribe_packet = mosq_test.gen_subscribe(mid, topic, 0)
|
||||
suback_packet = mosq_test.gen_suback(mid, 0)
|
||||
|
||||
publish_packet = mosq_test.gen_publish(topic, qos=0, payload="message")
|
||||
|
||||
port = mosq_test.get_port()
|
||||
broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port)
|
||||
|
||||
try:
|
||||
sock = mosq_test.do_client_connect(connect_packet, connack_packet, timeout=20, port=port)
|
||||
|
||||
if succeeds == True:
|
||||
mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback")
|
||||
mosq_test.do_send_receive(sock, publish_packet, publish_packet, "publish")
|
||||
else:
|
||||
mosq_test.do_send_receive(sock, subscribe_packet, b"", "suback")
|
||||
|
||||
rc = 0
|
||||
|
||||
sock.close()
|
||||
finally:
|
||||
broker.terminate()
|
||||
broker.wait()
|
||||
(stdo, stde) = broker.communicate()
|
||||
if rc:
|
||||
print(stde.decode('utf-8'))
|
||||
exit(rc)
|
||||
|
||||
do_test("/"*200, True) # 200 max hierarchy limit
|
||||
do_test("abc/"*199+"d", True) # 200 max hierarchy limit, longer overall string than 200
|
||||
|
||||
do_test("/"*201, False) # Exceeds 200 max hierarchy limit
|
||||
do_test("abc/"*200+"d", False) # Exceeds 200 max hierarchy limit, longer overall string than 200
|
||||
|
||||
|
||||
exit(0)
|
||||
|
@ -55,6 +55,10 @@ def do_test(proto_ver):
|
||||
rc = 0
|
||||
|
||||
sock.close()
|
||||
except socket.error as e:
|
||||
if e.errno == errno.ECONNRESET:
|
||||
# Connection has been closed by peer, this is the expected behaviour
|
||||
rc = 0
|
||||
finally:
|
||||
broker.terminate()
|
||||
broker.wait()
|
||||
|
@ -52,6 +52,10 @@ def do_test(proto_ver):
|
||||
rc = 0
|
||||
|
||||
sock.close()
|
||||
except socket.error as e:
|
||||
if e.errno == errno.ECONNRESET:
|
||||
# Connection has been closed by peer, this is the expected behaviour
|
||||
rc = 0
|
||||
finally:
|
||||
broker.terminate()
|
||||
broker.wait()
|
||||
|
@ -55,6 +55,10 @@ def do_test(proto_ver):
|
||||
rc = 0
|
||||
|
||||
sock.close()
|
||||
except socket.error as e:
|
||||
if e.errno == errno.ECONNRESET:
|
||||
# Connection has been closed by peer, this is the expected behaviour
|
||||
rc = 0
|
||||
finally:
|
||||
broker.terminate()
|
||||
broker.wait()
|
||||
|
@ -54,6 +54,10 @@ def do_test(proto_ver):
|
||||
rc = 0
|
||||
|
||||
sock.close()
|
||||
except socket.error as e:
|
||||
if e.errno == errno.ECONNRESET:
|
||||
# Connection has been closed by peer, this is the expected behaviour
|
||||
rc = 0
|
||||
finally:
|
||||
broker.terminate()
|
||||
broker.wait()
|
||||
|
@ -55,6 +55,10 @@ def do_test(proto_ver):
|
||||
rc = 0
|
||||
|
||||
sock.close()
|
||||
except socket.error as e:
|
||||
if e.errno == errno.ECONNRESET:
|
||||
# Connection has been closed by peer, this is the expected behaviour
|
||||
rc = 0
|
||||
finally:
|
||||
broker.terminate()
|
||||
broker.wait()
|
||||
|
@ -39,6 +39,7 @@ def do_test(proto_ver):
|
||||
|
||||
if mosq_test.expect_packet(sock, "publish2", publish_packet2):
|
||||
mosq_test.do_send_receive(sock, pubrec_packet2, pubrel_packet2, "pubrel2")
|
||||
sock.send(pubcomp_packet2)
|
||||
# Broker side of flow complete so can quit here.
|
||||
rc = 0
|
||||
|
||||
|
@ -17,6 +17,10 @@ def do_test(proto_ver):
|
||||
sock = mosq_test.do_client_connect(connect_packet, b"", timeout=30, port=port)
|
||||
rc = 0
|
||||
sock.close()
|
||||
except socket.error as e:
|
||||
if e.errno == errno.ECONNRESET:
|
||||
# Connection has been closed by peer, this is the expected behaviour
|
||||
rc = 0
|
||||
finally:
|
||||
broker.terminate()
|
||||
broker.wait()
|
||||
@ -30,4 +34,3 @@ def do_test(proto_ver):
|
||||
do_test(proto_ver=4)
|
||||
do_test(proto_ver=5)
|
||||
exit(0)
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
# Test whether a client can connect without an SSL certificate if one is required.
|
||||
|
||||
from mosq_test_helper import *
|
||||
import errno
|
||||
|
||||
if sys.version < '2.7':
|
||||
print("WARNING: SSL not supported on Python 2.6")
|
||||
|
@ -41,11 +41,13 @@ ifeq ($(WITH_TLS),yes)
|
||||
else
|
||||
./01-connect-uname-password-success-no-tls.py
|
||||
endif
|
||||
./01-connect-zero-length-id.py
|
||||
|
||||
|
||||
02 :
|
||||
./02-shared-qos0-v5.py
|
||||
./02-subhier-crash.py
|
||||
./02-subpub-qos0-long-topic.py
|
||||
./02-subpub-qos0-retain-as-publish.py
|
||||
./02-subpub-qos0-send-retain.py
|
||||
./02-subpub-qos0-subscription-id.py
|
||||
|
@ -15,3 +15,4 @@ import ssl
|
||||
import struct
|
||||
import subprocess
|
||||
import time
|
||||
import errno
|
||||
|
@ -22,9 +22,11 @@ tests = [
|
||||
(1, './01-connect-uname-password-denied.py'),
|
||||
(1, './01-connect-uname-password-success.py'),
|
||||
(1, './01-connect-uname-pwd-no-flag.py'),
|
||||
(2, './01-connect-zero-length-id.py'),
|
||||
|
||||
(1, './02-shared-qos0-v5.py'),
|
||||
(1, './02-subhier-crash.py'),
|
||||
(1, './02-subpub-qos0-long-topic.py'),
|
||||
(1, './02-subpub-qos0-retain-as-publish.py'),
|
||||
(1, './02-subpub-qos0-send-retain.py'),
|
||||
(1, './02-subpub-qos0-subscription-id.py'),
|
||||
|
58
test/lib/11-prop-recv-qos0.py
Executable file
58
test/lib/11-prop-recv-qos0.py
Executable file
@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Check whether the v5 message callback gets the properties
|
||||
|
||||
from mosq_test_helper import *
|
||||
|
||||
port = mosq_test.get_lib_port()
|
||||
|
||||
rc = 1
|
||||
keepalive = 60
|
||||
connect_packet = mosq_test.gen_connect("prop-test", keepalive=keepalive, proto_ver=5)
|
||||
connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5)
|
||||
|
||||
props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_CONTENT_TYPE, "plain/text")
|
||||
props += mqtt5_props.gen_string_prop(mqtt5_props.PROP_RESPONSE_TOPIC, "msg/123")
|
||||
publish_packet = mosq_test.gen_publish("prop/test", qos=0, payload="message", proto_ver=5, properties=props)
|
||||
|
||||
ok_packet = mosq_test.gen_publish("ok", qos=0, payload="ok", proto_ver=5)
|
||||
|
||||
disconnect_packet = mosq_test.gen_disconnect(proto_ver=5)
|
||||
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
sock.settimeout(10)
|
||||
sock.bind(('', port))
|
||||
sock.listen(5)
|
||||
|
||||
client_args = sys.argv[1:]
|
||||
env = dict(os.environ)
|
||||
env['LD_LIBRARY_PATH'] = '../../lib:../../lib/cpp'
|
||||
try:
|
||||
pp = env['PYTHONPATH']
|
||||
except KeyError:
|
||||
pp = ''
|
||||
env['PYTHONPATH'] = '../../lib/python:'+pp
|
||||
client = mosq_test.start_client(filename=sys.argv[1].replace('/', '-'), cmd=client_args, env=env, port=port)
|
||||
|
||||
try:
|
||||
(conn, address) = sock.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
if mosq_test.expect_packet(conn, "connect", connect_packet):
|
||||
conn.send(connack_packet)
|
||||
|
||||
conn.send(publish_packet)
|
||||
if mosq_test.expect_packet(conn, "ok", ok_packet):
|
||||
rc = 0
|
||||
|
||||
conn.close()
|
||||
finally:
|
||||
client.terminate()
|
||||
client.wait()
|
||||
if rc:
|
||||
(stdo, stde) = client.communicate()
|
||||
print(stde)
|
||||
sock.close()
|
||||
|
||||
exit(rc)
|
62
test/lib/11-prop-recv-qos1.py
Executable file
62
test/lib/11-prop-recv-qos1.py
Executable file
@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Check whether the v5 message callback gets the properties
|
||||
|
||||
from mosq_test_helper import *
|
||||
|
||||
port = mosq_test.get_lib_port()
|
||||
|
||||
rc = 1
|
||||
keepalive = 60
|
||||
connect_packet = mosq_test.gen_connect("prop-test", keepalive=keepalive, proto_ver=5)
|
||||
connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5)
|
||||
|
||||
|
||||
mid = 1
|
||||
props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_CONTENT_TYPE, "plain/text")
|
||||
props += mqtt5_props.gen_string_prop(mqtt5_props.PROP_RESPONSE_TOPIC, "msg/123")
|
||||
publish_packet = mosq_test.gen_publish("prop/test", mid=mid, qos=1, payload="message", proto_ver=5, properties=props)
|
||||
puback_packet = mosq_test.gen_puback(mid=mid, proto_ver=5)
|
||||
|
||||
ok_packet = mosq_test.gen_publish("ok", qos=0, payload="ok", proto_ver=5)
|
||||
|
||||
disconnect_packet = mosq_test.gen_disconnect(proto_ver=5)
|
||||
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
sock.settimeout(10)
|
||||
sock.bind(('', port))
|
||||
sock.listen(5)
|
||||
|
||||
client_args = sys.argv[1:]
|
||||
env = dict(os.environ)
|
||||
env['LD_LIBRARY_PATH'] = '../../lib:../../lib/cpp'
|
||||
try:
|
||||
pp = env['PYTHONPATH']
|
||||
except KeyError:
|
||||
pp = ''
|
||||
env['PYTHONPATH'] = '../../lib/python:'+pp
|
||||
client = mosq_test.start_client(filename=sys.argv[1].replace('/', '-'), cmd=client_args, env=env, port=port)
|
||||
|
||||
try:
|
||||
(conn, address) = sock.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
if mosq_test.expect_packet(conn, "connect", connect_packet):
|
||||
conn.send(connack_packet)
|
||||
|
||||
conn.send(publish_packet)
|
||||
if mosq_test.expect_packet(conn, "puback", puback_packet):
|
||||
if mosq_test.expect_packet(conn, "ok", ok_packet):
|
||||
rc = 0
|
||||
|
||||
conn.close()
|
||||
finally:
|
||||
client.terminate()
|
||||
client.wait()
|
||||
if rc:
|
||||
(stdo, stde) = client.communicate()
|
||||
print(stde)
|
||||
sock.close()
|
||||
|
||||
exit(rc)
|
66
test/lib/11-prop-recv-qos2.py
Executable file
66
test/lib/11-prop-recv-qos2.py
Executable file
@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Check whether the v5 message callback gets the properties
|
||||
|
||||
from mosq_test_helper import *
|
||||
|
||||
port = mosq_test.get_lib_port()
|
||||
|
||||
rc = 1
|
||||
keepalive = 60
|
||||
connect_packet = mosq_test.gen_connect("prop-test", keepalive=keepalive, proto_ver=5)
|
||||
connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5)
|
||||
|
||||
|
||||
mid = 1
|
||||
props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_CONTENT_TYPE, "plain/text")
|
||||
props += mqtt5_props.gen_string_prop(mqtt5_props.PROP_RESPONSE_TOPIC, "msg/123")
|
||||
publish_packet = mosq_test.gen_publish("prop/test", mid=mid, qos=2, payload="message", proto_ver=5, properties=props)
|
||||
pubrec_packet = mosq_test.gen_pubrec(mid=mid, proto_ver=5)
|
||||
pubrel_packet = mosq_test.gen_pubrel(mid=mid, proto_ver=5)
|
||||
pubcomp_packet = mosq_test.gen_pubcomp(mid=mid, proto_ver=5)
|
||||
|
||||
ok_packet = mosq_test.gen_publish("ok", qos=0, payload="ok", proto_ver=5)
|
||||
|
||||
disconnect_packet = mosq_test.gen_disconnect(proto_ver=5)
|
||||
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
sock.settimeout(10)
|
||||
sock.bind(('', port))
|
||||
sock.listen(5)
|
||||
|
||||
client_args = sys.argv[1:]
|
||||
env = dict(os.environ)
|
||||
env['LD_LIBRARY_PATH'] = '../../lib:../../lib/cpp'
|
||||
try:
|
||||
pp = env['PYTHONPATH']
|
||||
except KeyError:
|
||||
pp = ''
|
||||
env['PYTHONPATH'] = '../../lib/python:'+pp
|
||||
client = mosq_test.start_client(filename=sys.argv[1].replace('/', '-'), cmd=client_args, env=env, port=port)
|
||||
|
||||
try:
|
||||
(conn, address) = sock.accept()
|
||||
conn.settimeout(10)
|
||||
|
||||
if mosq_test.expect_packet(conn, "connect", connect_packet):
|
||||
conn.send(connack_packet)
|
||||
|
||||
conn.send(publish_packet)
|
||||
if mosq_test.expect_packet(conn, "pubrec", pubrec_packet):
|
||||
conn.send(pubrel_packet)
|
||||
if mosq_test.expect_packet(conn, "pubcomp", pubcomp_packet):
|
||||
if mosq_test.expect_packet(conn, "ok", ok_packet):
|
||||
rc = 0
|
||||
|
||||
conn.close()
|
||||
finally:
|
||||
client.terminate()
|
||||
client.wait()
|
||||
if rc:
|
||||
(stdo, stde) = client.communicate()
|
||||
print(stde)
|
||||
sock.close()
|
||||
|
||||
exit(rc)
|
@ -68,6 +68,9 @@ endif
|
||||
./11-prop-oversize-packet.py $@/11-prop-oversize-packet.test
|
||||
./11-prop-send-content-type.py $@/11-prop-send-content-type.test
|
||||
./11-prop-send-payload-format.py $@/11-prop-send-payload-format.test
|
||||
./11-prop-recv-qos0.py $@/11-prop-recv-qos0.test
|
||||
./11-prop-recv-qos1.py $@/11-prop-recv-qos1.test
|
||||
./11-prop-recv-qos2.py $@/11-prop-recv-qos2.test
|
||||
|
||||
clean :
|
||||
$(MAKE) -C c clean
|
||||
|
@ -42,33 +42,24 @@ int main(int argc, char *argv[])
|
||||
mosquitto_connect_callback_set(mosq, on_connect);
|
||||
mosquitto_disconnect_callback_set(mosq, on_disconnect);
|
||||
mosquitto_subscribe_callback_set(mosq, on_subscribe);
|
||||
printf("ok, about to call connect_async\n");
|
||||
|
||||
// this only works if loop_start is first. with loop_start second,
|
||||
// it fails on both 1.6.4 _and_ 1.6.5
|
||||
// in this order, 1.6.4 works and 1.6.5 fails.
|
||||
rc = mosquitto_loop_start(mosq);
|
||||
printf("loop_start returned rc: %d\n", rc);
|
||||
if (rc) {
|
||||
printf("which is: %s\n", mosquitto_strerror(rc));
|
||||
if(rc){
|
||||
printf("loop_start failed: %s\n", mosquitto_strerror(rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
// not sure which rc you want to be returned....
|
||||
rc = mosquitto_connect_async(mosq, "localhost", port, 60);
|
||||
printf("connect async returned rc: %d\n", rc);
|
||||
if (rc) {
|
||||
printf("which is: %s\n", mosquitto_strerror(rc));
|
||||
if(rc){
|
||||
printf("connect_async failed: %s\n", mosquitto_strerror(rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
printf("ok, so we can start just waiting now, loop_start will run in it's thread\n");
|
||||
/* 10 millis to be system polite */
|
||||
//struct timespec tv = { 0, 10e6 };
|
||||
struct timespec tv = { 1, 0 };
|
||||
/* 50 millis to be system polite */
|
||||
struct timespec tv = { 0, 50e6 };
|
||||
while(should_run){
|
||||
nanosleep(&tv, NULL);
|
||||
printf("...waiting...\n");
|
||||
}
|
||||
printf("Already exited should_run....\n");
|
||||
|
||||
mosquitto_disconnect(mosq);
|
||||
mosquitto_loop_stop(mosq, false);
|
||||
|
@ -42,29 +42,22 @@ int main(int argc, char *argv[])
|
||||
mosquitto_connect_callback_set(mosq, on_connect);
|
||||
mosquitto_disconnect_callback_set(mosq, on_disconnect);
|
||||
mosquitto_subscribe_callback_set(mosq, on_subscribe);
|
||||
printf("ok, about to call connect_async\n");
|
||||
|
||||
rc = mosquitto_connect_async(mosq, "localhost", port, 60);
|
||||
printf("connect async returned rc: %d\n", rc);
|
||||
if (rc) {
|
||||
printf("which is: %s\n", mosquitto_strerror(rc));
|
||||
if(rc){
|
||||
printf("connect_async failed: %s\n", mosquitto_strerror(rc));
|
||||
}
|
||||
|
||||
rc = mosquitto_loop_start(mosq);
|
||||
printf("loop_start returned rc: %d\n", rc);
|
||||
if (rc) {
|
||||
printf("which is: %s\n", mosquitto_strerror(rc));
|
||||
if(rc){
|
||||
printf("loop_start failed: %s\n", mosquitto_strerror(rc));
|
||||
}
|
||||
|
||||
printf("ok, so we can start just waiting now, loop_start will run in it's thread\n");
|
||||
/* 10 millis to be system polite */
|
||||
//struct timespec tv = { 0, 10e6 };
|
||||
struct timespec tv = { 1, 0 };
|
||||
/* 50 millis to be system polite */
|
||||
struct timespec tv = { 0, 50e6 };
|
||||
while(should_run){
|
||||
nanosleep(&tv, NULL);
|
||||
printf("...waiting...\n");
|
||||
}
|
||||
printf("Already exited should_run....\n");
|
||||
|
||||
mosquitto_disconnect(mosq);
|
||||
mosquitto_loop_stop(mosq, false);
|
||||
|
81
test/lib/c/11-prop-recv-qos0.c
Normal file
81
test/lib/c/11-prop-recv-qos0.c
Normal file
@ -0,0 +1,81 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <mosquitto.h>
|
||||
#include <mqtt_protocol.h>
|
||||
|
||||
static int run = -1;
|
||||
static int sent_mid = -1;
|
||||
|
||||
void on_connect(struct mosquitto *mosq, void *obj, int rc)
|
||||
{
|
||||
int rc2;
|
||||
mosquitto_property *proplist = NULL;
|
||||
|
||||
if(rc){
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void on_message_v5(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg, const mosquitto_property *properties)
|
||||
{
|
||||
int rc;
|
||||
char *str;
|
||||
|
||||
if(properties){
|
||||
if(mosquitto_property_read_string(properties, MQTT_PROP_CONTENT_TYPE, &str, false)){
|
||||
rc = strcmp(str, "plain/text");
|
||||
free(str);
|
||||
|
||||
if(rc == 0){
|
||||
if(mosquitto_property_read_string(properties, MQTT_PROP_RESPONSE_TOPIC, &str, false)){
|
||||
rc = strcmp(str, "msg/123");
|
||||
free(str);
|
||||
|
||||
if(rc == 0){
|
||||
if(msg->qos == 0){
|
||||
mosquitto_publish(mosq, NULL, "ok", 2, "ok", 0, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* No matching message, so quit with an error */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
void on_publish(struct mosquitto *mosq, void *obj, int mid)
|
||||
{
|
||||
run = 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int rc;
|
||||
int tmp;
|
||||
struct mosquitto *mosq;
|
||||
|
||||
int port = atoi(argv[1]);
|
||||
|
||||
mosquitto_lib_init();
|
||||
|
||||
mosq = mosquitto_new("prop-test", true, NULL);
|
||||
mosquitto_connect_callback_set(mosq, on_connect);
|
||||
mosquitto_message_v5_callback_set(mosq, on_message_v5);
|
||||
mosquitto_int_option(mosq, MOSQ_OPT_PROTOCOL_VERSION, MQTT_PROTOCOL_V5);
|
||||
|
||||
rc = mosquitto_connect(mosq, "localhost", port, 60);
|
||||
|
||||
while(run == -1){
|
||||
rc = mosquitto_loop(mosq, -1, 1);
|
||||
}
|
||||
|
||||
mosquitto_lib_cleanup();
|
||||
return run;
|
||||
}
|
81
test/lib/c/11-prop-recv-qos1.c
Normal file
81
test/lib/c/11-prop-recv-qos1.c
Normal file
@ -0,0 +1,81 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <mosquitto.h>
|
||||
#include <mqtt_protocol.h>
|
||||
|
||||
static int run = -1;
|
||||
static int sent_mid = -1;
|
||||
|
||||
void on_connect(struct mosquitto *mosq, void *obj, int rc)
|
||||
{
|
||||
int rc2;
|
||||
mosquitto_property *proplist = NULL;
|
||||
|
||||
if(rc){
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void on_message_v5(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg, const mosquitto_property *properties)
|
||||
{
|
||||
int rc;
|
||||
char *str;
|
||||
|
||||
if(properties){
|
||||
if(mosquitto_property_read_string(properties, MQTT_PROP_CONTENT_TYPE, &str, false)){
|
||||
rc = strcmp(str, "plain/text");
|
||||
free(str);
|
||||
|
||||
if(rc == 0){
|
||||
if(mosquitto_property_read_string(properties, MQTT_PROP_RESPONSE_TOPIC, &str, false)){
|
||||
rc = strcmp(str, "msg/123");
|
||||
free(str);
|
||||
|
||||
if(rc == 0){
|
||||
if(msg->qos == 1){
|
||||
mosquitto_publish(mosq, NULL, "ok", 2, "ok", 0, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* No matching message, so quit with an error */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
void on_publish(struct mosquitto *mosq, void *obj, int mid)
|
||||
{
|
||||
run = 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int rc;
|
||||
int tmp;
|
||||
struct mosquitto *mosq;
|
||||
|
||||
int port = atoi(argv[1]);
|
||||
|
||||
mosquitto_lib_init();
|
||||
|
||||
mosq = mosquitto_new("prop-test", true, NULL);
|
||||
mosquitto_connect_callback_set(mosq, on_connect);
|
||||
mosquitto_message_v5_callback_set(mosq, on_message_v5);
|
||||
mosquitto_int_option(mosq, MOSQ_OPT_PROTOCOL_VERSION, MQTT_PROTOCOL_V5);
|
||||
|
||||
rc = mosquitto_connect(mosq, "localhost", port, 60);
|
||||
|
||||
while(run == -1){
|
||||
rc = mosquitto_loop(mosq, -1, 1);
|
||||
}
|
||||
|
||||
mosquitto_lib_cleanup();
|
||||
return run;
|
||||
}
|
82
test/lib/c/11-prop-recv-qos2.c
Normal file
82
test/lib/c/11-prop-recv-qos2.c
Normal file
@ -0,0 +1,82 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <mosquitto.h>
|
||||
#include <mqtt_protocol.h>
|
||||
|
||||
static int run = -1;
|
||||
static int sent_mid = -1;
|
||||
|
||||
void on_connect(struct mosquitto *mosq, void *obj, int rc)
|
||||
{
|
||||
int rc2;
|
||||
mosquitto_property *proplist = NULL;
|
||||
|
||||
if(rc){
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void on_message_v5(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg, const mosquitto_property *properties)
|
||||
{
|
||||
int rc;
|
||||
char *str;
|
||||
|
||||
if(properties){
|
||||
if(mosquitto_property_read_string(properties, MQTT_PROP_CONTENT_TYPE, &str, false)){
|
||||
rc = strcmp(str, "plain/text");
|
||||
free(str);
|
||||
|
||||
if(rc == 0){
|
||||
if(mosquitto_property_read_string(properties, MQTT_PROP_RESPONSE_TOPIC, &str, false)){
|
||||
rc = strcmp(str, "msg/123");
|
||||
free(str);
|
||||
|
||||
if(rc == 0){
|
||||
if(msg->qos == 2){
|
||||
mosquitto_publish(mosq, NULL, "ok", 2, "ok", 0, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* No matching message, so quit with an error */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
void on_publish(struct mosquitto *mosq, void *obj, int mid)
|
||||
{
|
||||
run = 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int rc;
|
||||
int tmp;
|
||||
struct mosquitto *mosq;
|
||||
|
||||
int port = atoi(argv[1]);
|
||||
|
||||
mosquitto_lib_init();
|
||||
|
||||
mosq = mosquitto_new("prop-test", true, NULL);
|
||||
mosquitto_connect_callback_set(mosq, on_connect);
|
||||
mosquitto_message_v5_callback_set(mosq, on_message_v5);
|
||||
mosquitto_int_option(mosq, MOSQ_OPT_PROTOCOL_VERSION, MQTT_PROTOCOL_V5);
|
||||
|
||||
rc = mosquitto_connect(mosq, "localhost", port, 60);
|
||||
|
||||
while(run == -1){
|
||||
rc = mosquitto_loop(mosq, -1, 1);
|
||||
}
|
||||
|
||||
mosquitto_destroy(mosq);
|
||||
mosquitto_lib_cleanup();
|
||||
return run;
|
||||
}
|
@ -46,6 +46,9 @@ SRC = \
|
||||
08-ssl-fake-cacert.c \
|
||||
09-util-topic-tokenise.c \
|
||||
11-prop-oversize-packet.c \
|
||||
11-prop-recv-qos0.c \
|
||||
11-prop-recv-qos1.c \
|
||||
11-prop-recv-qos2.c \
|
||||
11-prop-send-payload-format.c \
|
||||
11-prop-send-content-type.c
|
||||
|
||||
|
@ -106,7 +106,13 @@ def packet_matches(name, recvd, expected):
|
||||
|
||||
|
||||
def do_send_receive(sock, send_packet, receive_packet, error_string="send receive error"):
|
||||
sock.send(send_packet)
|
||||
size = len(send_packet)
|
||||
total_sent = 0
|
||||
while total_sent < size:
|
||||
sent = sock.send(send_packet[total_sent:])
|
||||
if sent == 0:
|
||||
raise RuntimeError("socket connection broken")
|
||||
total_sent += sent
|
||||
|
||||
if expect_packet(sock, error_string, receive_packet):
|
||||
return sock
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
# Source
|
||||
|
||||
* [mosquitto-1.6.7.tar.gz](https://mosquitto.org/files/source/mosquitto-1.6.7.tar.gz) (319kB) ([GPG signature](https://mosquitto.org/files/source/mosquitto-1.6.7.tar.gz.asc))
|
||||
* [mosquitto-1.6.8.tar.gz](https://mosquitto.org/files/source/mosquitto-1.6.8.tar.gz) (319kB) ([GPG signature](https://mosquitto.org/files/source/mosquitto-1.6.8.tar.gz.asc))
|
||||
* [Git source code repository](https://github.com/eclipse/mosquitto) (github.com)
|
||||
|
||||
Older downloads are available at [https://mosquitto.org/files/](../files/)
|
||||
@ -24,8 +24,8 @@ distributions.
|
||||
|
||||
## Windows
|
||||
|
||||
* [mosquitto-1.6.7-install-windows-x64.exe](https://mosquitto.org/files/binary/win64/mosquitto-1.6.7-install-windows-x64.exe) (~1.4 MB) (64-bit build, Windows Vista and up, built with Visual Studio Community 2017)
|
||||
* [mosquitto-1.6.7-install-windows-x32.exe](https://mosquitto.org/files/binary/win32/mosquitto-1.6.7-install-windows-x86.exe) (~1.4 MB) (32-bit build, Windows Vista and up, built with Visual Studio Community 2017)
|
||||
* [mosquitto-1.6.8-install-windows-x64.exe](https://mosquitto.org/files/binary/win64/mosquitto-1.6.8-install-windows-x64.exe) (~1.4 MB) (64-bit build, Windows Vista and up, built with Visual Studio Community 2017)
|
||||
* [mosquitto-1.6.8-install-windows-x32.exe](https://mosquitto.org/files/binary/win32/mosquitto-1.6.8-install-windows-x86.exe) (~1.4 MB) (32-bit build, Windows Vista and up, built with Visual Studio Community 2017)
|
||||
|
||||
See also readme-windows.txt after installing.
|
||||
|
||||
|
@ -53,9 +53,8 @@
|
||||
href="https://test.mosquitto.org/">test.mosquitto.org</a> where
|
||||
you can test your clients in a variety of ways: plain MQTT,
|
||||
MQTT over TLS, MQTT over TLS (with <a
|
||||
href="https://test.mosquitto.org/ssl/">client certificate</a>,
|
||||
href="https://test.mosquitto.org/ssl/">client certificate</a>),
|
||||
MQTT over WebSockets and MQTT over WebSockets with TLS.</p>
|
||||
platforms.</p>
|
||||
</div>
|
||||
|
||||
<div class="column column-justify">
|
||||
|
75
www/posts/2019/11/version-1-6-8-released.md
Normal file
75
www/posts/2019/11/version-1-6-8-released.md
Normal file
@ -0,0 +1,75 @@
|
||||
<!--
|
||||
.. title: Version 1.6.8 released.
|
||||
.. slug: version-1-6-8-released
|
||||
.. date: 2019-11-28 16:44:19 UTC+00:00
|
||||
.. tags: Releases
|
||||
.. category:
|
||||
.. link:
|
||||
.. description:
|
||||
.. type: text
|
||||
-->
|
||||
|
||||
Mosquitto 1.6.8 has been released, this is a bugfix release.
|
||||
|
||||
# Broker
|
||||
- Various fixes for `allow_zero_length_clientid` config, where this option was
|
||||
not being set correctly. Closes [#1429].
|
||||
- Fix incorrect memory tracking causing problems with `memory_limit` option.
|
||||
Closes [#1437].
|
||||
- Fix subscription topics being limited to 200 characters instead of 200
|
||||
hierarchy levels. Closes [#1441].
|
||||
- Only a single CRL could be loaded at once. This has been fixed.
|
||||
Closes [#1442].
|
||||
- Fix problems with reloading config when `per_listener_settings` was true.
|
||||
Closes [#1459].
|
||||
- Fix retained messages with an expiry interval not being expired after being
|
||||
restored from persistence. Closes [#1464].
|
||||
- Fix messages with an expiry interval being sent without an expiry interval
|
||||
property just before they were expired. Closes [#1464].
|
||||
- Fix TLS Websockets clients not receiving messages after taking over a
|
||||
previous connection. Closes [#1489].
|
||||
- Fix MQTT 3.1.1 clients using clean session false, or MQTT 5.0 clients using
|
||||
session-expiry-interval set to infinity never expiring, even when the global
|
||||
`persistent_client_expiration` option was set. Closes [#1494].
|
||||
|
||||
# Client library
|
||||
- Fix publish properties not being passed to `on_message_v5()` callback for QoS 2
|
||||
messages. Closes [#1432].
|
||||
- Fix documentation issues in mosquitto.h. Closes [#1478].
|
||||
- Document `mosquitto_connect_srv()`. Closes [#1499].
|
||||
|
||||
# Clients
|
||||
- Fix duplicate cfg definition in rr_client. Closes [#1453].
|
||||
- Fix `mosquitto_pub -l` hang when stdin stream ends. Closes [#1448].
|
||||
- Fix `mosquitto_pub -l` not sending the final line of stdin if it does not
|
||||
end with a new line. Closes [#1473].
|
||||
- Make documentation for `mosquitto_pub -l` match reality - blank lines are
|
||||
sent as empty messages. Closes [#1474].
|
||||
- Free memory in `mosquitto_sub` when quiting without having made a successful
|
||||
connection. Closes [#1513].
|
||||
|
||||
# Build
|
||||
- Added `CLIENT_STATIC_LDADD` to makefile builds to allow more libraries to be
|
||||
linked when compiling the clients with a static libmosquitto, as required
|
||||
for e.g. openssl on some systems.
|
||||
|
||||
# Installer
|
||||
- Fix `mosquitto_rr.exe` not being included in Windows installers. Closes [#1463].
|
||||
|
||||
[#1429]: https://github.com/eclipse/mosquitto/issues/1429
|
||||
[#1432]: https://github.com/eclipse/mosquitto/issues/1432
|
||||
[#1437]: https://github.com/eclipse/mosquitto/issues/1437
|
||||
[#1441]: https://github.com/eclipse/mosquitto/issues/1441
|
||||
[#1442]: https://github.com/eclipse/mosquitto/issues/1442
|
||||
[#1448]: https://github.com/eclipse/mosquitto/issues/1448
|
||||
[#1453]: https://github.com/eclipse/mosquitto/issues/1453
|
||||
[#1459]: https://github.com/eclipse/mosquitto/issues/1459
|
||||
[#1463]: https://github.com/eclipse/mosquitto/issues/1463
|
||||
[#1464]: https://github.com/eclipse/mosquitto/issues/1464
|
||||
[#1473]: https://github.com/eclipse/mosquitto/issues/1473
|
||||
[#1474]: https://github.com/eclipse/mosquitto/issues/1474
|
||||
[#1478]: https://github.com/eclipse/mosquitto/issues/1478
|
||||
[#1489]: https://github.com/eclipse/mosquitto/issues/1489
|
||||
[#1494]: https://github.com/eclipse/mosquitto/issues/1494
|
||||
[#1499]: https://github.com/eclipse/mosquitto/issues/1499
|
||||
[#1513]: https://github.com/eclipse/mosquitto/issues/1513
|
Loading…
x
Reference in New Issue
Block a user