Merge branch 'mqtt5' into develop

This commit is contained in:
Roger A. Light
2019-02-26 18:51:31 +00:00
373 changed files with 19709 additions and 4187 deletions
+15 -5
View File
@@ -1,11 +1,17 @@
*.o
*.so
*.exe
*.db
*.gcda
*.gcno
*.exe
*.o
*.old
*.pyc
*.so
*.vglog
massif.out.*
vglog*
c/*.test
cpp/*.test
*.pyc
*.vglog
build/
@@ -50,5 +56,9 @@ test/ssl/*.csr
test/lib/c/*.test
test/lib/cpp/*.test
test/unit/coverage.info
test/unit/mosq_test
test/unit/out
www/cache/
__pycache__
+11 -11
View File
@@ -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.5.4)
set (VERSION 1.5.90)
add_definitions (-DCMAKE -DVERSION=\"${VERSION}\")
@@ -51,7 +51,7 @@ option(WITH_TLS_PSK
"Include TLS-PSK support (requires WITH_TLS)?" ON)
option(WITH_EC
"Include Elliptic Curve support (requires WITH_TLS)?" ON)
if (${WITH_TLS} STREQUAL ON)
if (WITH_TLS)
find_package(OpenSSL REQUIRED)
add_definitions("-DWITH_TLS")
@@ -62,19 +62,19 @@ if (${WITH_TLS} STREQUAL ON)
if (${WITH_EC} STREQUAL ON)
add_definitions("-DWITH_EC")
endif (${WITH_EC} STREQUAL ON)
else (${WITH_TLS} STREQUAL ON)
else (WITH_TLS)
set (OPENSSL_INCLUDE_DIR "")
endif (${WITH_TLS} STREQUAL ON)
endif (WITH_TLS)
option(WITH_SOCKS "Include SOCKS5 support?" ON)
if (${WITH_SOCKS} STREQUAL ON)
if (WITH_SOCKS)
add_definitions("-DWITH_SOCKS")
endif (${WITH_SOCKS} STREQUAL ON)
endif (WITH_SOCKS)
option(WITH_SRV "Include SRV lookup support?" OFF)
option(WITH_THREADING "Include client library threading support?" ON)
if (${WITH_THREADING} STREQUAL ON)
if (WITH_THREADING)
add_definitions("-DWITH_THREADING")
if (WIN32)
if (CMAKE_CL_64)
@@ -92,10 +92,10 @@ if (${WITH_THREADING} STREQUAL ON)
endif()
set (PTHREAD_INCLUDE_DIR "")
endif (WIN32)
else (${WITH_THREADING} STREQUAL ON)
else (WITH_THREADING)
set (PTHREAD_LIBRARIES "")
set (PTHREAD_INCLUDE_DIR "")
endif (${WITH_THREADING} STREQUAL ON)
endif (WITH_THREADING)
option(DOCUMENTATION "Build documentation?" ON)
@@ -106,9 +106,9 @@ option(DOCUMENTATION "Build documentation?" ON)
add_subdirectory(lib)
add_subdirectory(client)
add_subdirectory(src)
if (${DOCUMENTATION} STREQUAL ON)
if (DOCUMENTATION)
add_subdirectory(man)
endif (${DOCUMENTATION} STREQUAL ON)
endif (DOCUMENTATION)
# ========================================
# Install config file
+121
View File
@@ -1,6 +1,13 @@
1.6 - 2018xxxx
==============
Broker features:
- Improved general support for broker generated client ids. Removed libuuid
dependency.
- auto_id_prefix now defaults to 'auto-'.
- Add max_keepalive option, to allow a maximum keepalive value to be set for
MQTT v5 clients only.
Client library features:
- Add mosquitto_subscribe_multiple() for sending subscriptions to multiple
topics in one command.
@@ -9,6 +16,120 @@ Client features:
- Add -E to mosquitto_sub, which causes it to exit immediately after having
its subscriptions acknowledged. Use with -c to create a durable client
session without requiring a message to be received.
- -V now accepts `5, `311`, `31`, as well as `mqttv5` etc.
Client fixes:
- mosquitto_pub wouldn't always publish all messages when using `-l` and
QoS>0. This has been fixed.
1.5.7 - 201902xx
================
Broker:
- Fix build failure when using WITH_ADNS=yes
- Ensure that an error occurs if `per_listener_settings true` is given after
other security options. Closes #1149.
- Fix include_dir not sorting config files before loading. This was partially
fixed in 1.5 previously.
Library:
- Fix `mosquitto_topic_matches_sub()` not returning MOSQ_ERR_INVAL for
invalid subscriptions like `topic/#abc`. This only affects the return value,
not the match/no match result, which was already correct.
Build:
- Don't require C99 compiler.
1.5.6 - 20190206
================
Security:
- CVE-2018-12551: If Mosquitto is configured to use a password file for
authentication, any malformed data in the password file will be treated as
valid. This typically means that the malformed data becomes a username and no
password. If this occurs, clients can circumvent authentication and get access
to the broker by using the malformed username. In particular, a blank line
will be treated as a valid empty username. Other security measures are
unaffected. Users who have only used the mosquitto_passwd utility to create
and modify their password files are unaffected by this vulnerability.
Affects version 1.0 to 1.5.5 inclusive.
- CVE-2018-12550: If an ACL file is empty, or has only blank lines or
comments, then mosquitto treats the ACL file as not being defined, which
means that no topic access is denied. Although denying access to all topics
is not a useful configuration, this behaviour is unexpected and could lead
to access being incorrectly granted in some circumstances. This is now
fixed. Affects versions 1.0 to 1.5.5 inclusive.
- CVE-2018-12546. If a client publishes a retained message to a topic that
they have access to, and then their access to that topic is revoked, the
retained message will still be delivered to future subscribers. This
behaviour may be undesirable in some applications, so a configuration option
`check_retain_source` has been introduced to enforce checking of the
retained message source on publish.
Broker:
- Fixed comment handling for config options that have optional arguments.
- Improved documentation around bridge topic remapping.
- Handle mismatched handshakes (e.g. QoS1 PUBLISH with QoS2 reply) properly.
- Fix spaces not being allowed in the bridge remote_username option. Closes
#1131.
- Allow broker to always restart on Windows when using `log_dest file`. Closes
#1080.
- Fix Will not being sent for Websockets clients. Closes #1143.
- Windows: Fix possible crash when client disconnects. Closes #1137.
- Fixed durable clients being unable to receive messages when offline, when
per_listener_settings was set to true. Closes #1081.
- Add log message for the case where a client is disconnected for sending a
topic with invalid UTF-8. Closes #1144.
Library:
- Fix TLS connections not working over SOCKS.
- Don't clear SSL context when TLS connection is closed, meaning if a user
provided an external SSL_CTX they have less chance of leaking references.
Build:
- Fix comparison of boolean values in CMake build. Closes #1101.
- Fix compilation when openssl deprecated APIs are not available.
Closes #1094.
- Man pages can now be built on any system. Closes #1139.
1.5.5 - 20181211
================
Security:
- If `per_listener_settings` is set to true, then the `acl_file` setting was
ignored for the "default listener" only. This has been fixed. This does not
affect any listeners defined with the `listener` option. Closes #1073.
This is now tracked as CVE-2018-20145.
Broker:
- Add `socket_domain` option to allow listeners to disable IPv6 support.
This is required to work around a problem in libwebsockets that means
sockets only listen on IPv6 by default if IPv6 support is compiled in.
Closes #1004.
- When using ADNS, don't ask for all network protocols when connecting,
because this can lead to confusing "Protocol not supported" errors if the
network is down. Closes #1062.
- Fix outgoing retained messages not being sent by bridges on initial
connection. Closes #1040.
- Don't reload auth_opt_ options on reload, to match the behaviour of the
other plugin options. Closes #1068.
- Print message on error when installing/uninstalling as a Windows service.
- All non-error connect/disconnect messages are controlled by the
`connection_messages` option. Closes #772. Closes #613. Closes #537.
Library:
- Fix reconnect delay backoff behaviour. Closes #1027.
- Don't call on_disconnect() twice if keepalive tests fail. Closes #1067.
Client:
- Always print leading zeros in mosquitto_sub when output format is hex.
Closes #1066.
Build:
- Fix building where TLS-PSK is not available. Closes #68.
1.5.4 - 20181108
+3
View File
@@ -81,3 +81,6 @@ copy : sign
cd dist; scp *.html mosquitto:site/mosquitto.org/man/
scp ChangeLog.txt mosquitto:site/mosquitto.org/
coverage :
lcov --capture --directory . --output-file coverage.info
genhtml coverage.info --output-directory out
+6 -5
View File
@@ -1,14 +1,15 @@
include_directories(${mosquitto_SOURCE_DIR} ${mosquitto_SOURCE_DIR}/lib
${STDBOOL_H_PATH} ${STDINT_H_PATH} ${PTHREAD_INCLUDE_DIR})
${STDBOOL_H_PATH} ${STDINT_H_PATH} ${PTHREAD_INCLUDE_DIR}
${OPENSSL_INCLUDE_DIR})
link_directories(${mosquitto_BINARY_DIR}/lib)
set(shared_src client_shared.c client_shared.h)
set(shared_src client_shared.c client_shared.h client_props.c)
if (${WITH_SRV} STREQUAL ON)
if (WITH_SRV)
add_definitions("-DWITH_SRV")
endif (${WITH_SRV} STREQUAL ON)
endif (WITH_SRV)
add_executable(mosquitto_pub pub_client.c ${shared_src})
add_executable(mosquitto_pub pub_client.c pub_shared.c ${shared_src})
add_executable(mosquitto_sub sub_client.c sub_client_output.c ${shared_src})
+11 -5
View File
@@ -20,21 +20,24 @@ static : static_pub static_sub
# This makes mosquitto_pub/sub versions that are statically linked with
# libmosquitto only.
static_pub : pub_client.o client_shared.o ../lib/libmosquitto.a
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} -lssl -lcrypto -lpthread
static_sub : sub_client.o sub_client_output.o client_shared.o ../lib/libmosquitto.a
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} -lssl -lcrypto -lpthread
mosquitto_pub : pub_client.o client_shared.o
mosquitto_pub : pub_client.o pub_shared.o client_shared.o client_props.o
${CROSS_COMPILE}${CC} $^ -o $@ ${CLIENT_LDFLAGS}
mosquitto_sub : sub_client.o sub_client_output.o client_shared.o
mosquitto_sub : sub_client.o sub_client_output.o client_shared.o client_props.o
${CROSS_COMPILE}${CC} $^ -o $@ ${CLIENT_LDFLAGS}
pub_client.o : pub_client.c ${SHARED_DEP}
${CROSS_COMPILE}${CC} -c $< -o $@ ${CLIENT_CFLAGS}
pub_shared.o : pub_shared.c ${SHARED_DEP}
${CROSS_COMPILE}${CC} -c $< -o $@ ${CLIENT_CFLAGS}
sub_client.o : sub_client.c ${SHARED_DEP}
${CROSS_COMPILE}${CC} -c $< -o $@ ${CLIENT_CFLAGS}
@@ -44,6 +47,9 @@ sub_client_output.o : sub_client_output.c ${SHARED_DEP}
client_shared.o : client_shared.c client_shared.h
${CROSS_COMPILE}${CC} -c $< -o $@ ${CLIENT_CFLAGS}
client_props.o : client_props.c client_shared.h
${CROSS_COMPILE}${CC} -c $< -o $@ ${CLIENT_CFLAGS}
../lib/libmosquitto.so.${SOVERSION} :
$(MAKE) -C ../lib
@@ -62,4 +68,4 @@ uninstall :
reallyclean : clean
clean :
-rm -f *.o mosquitto_pub mosquitto_sub
-rm -f *.o mosquitto_pub mosquitto_sub *.gcda *.gcno
+193
View File
@@ -0,0 +1,193 @@
/*
Copyright (c) 2018 Roger Light <roger@atchoo.org>
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
and Eclipse Distribution License v1.0 which accompany this distribution.
The Eclipse Public License is available at
http://www.eclipse.org/legal/epl-v10.html
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
Contributors:
Roger Light - initial implementation and documentation.
*/
#include "config.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <unistd.h>
#include <strings.h>
#else
#include <process.h>
#include <winsock2.h>
#define snprintf sprintf_s
#define strncasecmp _strnicmp
#endif
#include "mosquitto.h"
#include "mqtt_protocol.h"
#include "client_shared.h"
enum prop_type
{
PROP_TYPE_BYTE,
PROP_TYPE_INT16,
PROP_TYPE_INT32,
PROP_TYPE_BINARY,
PROP_TYPE_STRING,
PROP_TYPE_STRING_PAIR
};
/* This parses property inputs. It should work for any command type, but is limited at the moment.
*
* Format:
*
* command property value
* command property key value
*
* Example:
*
* publish message-expiry-interval 32
* connect user-property key value
*/
int cfg_parse_property(struct mosq_config *cfg, int argc, char *argv[], int *idx)
{
char *cmdname = NULL, *propname = NULL;
char *key = NULL, *value = NULL;
int cmd, identifier, type;
mosquitto_property **proplist;
int rc;
/* idx now points to "command" */
if((*idx)+2 > argc-1){
/* Not enough args */
fprintf(stderr, "Error: --property argument given but not enough arguments specified.\n\n");
return MOSQ_ERR_INVAL;
}
cmdname = argv[*idx];
if(mosquitto_string_to_command(cmdname, &cmd)){
fprintf(stderr, "Error: Invalid command given in --property argument.\n\n");
return MOSQ_ERR_INVAL;
}
propname = argv[(*idx)+1];
if(mosquitto_string_to_property_info(propname, &identifier, &type)){
fprintf(stderr, "Error: Invalid property name given in --property argument.\n\n");
return MOSQ_ERR_INVAL;
}
if(mosquitto_property_check_command(cmd, identifier)){
fprintf(stderr, "Error: %s property not allow for %s in --property argument.\n\n", propname, cmdname);
return MOSQ_ERR_INVAL;
}
if(identifier == MQTT_PROP_USER_PROPERTY){
if((*idx)+3 > argc-1){
/* Not enough args */
fprintf(stderr, "Error: --property argument given but not enough arguments specified.\n\n");
return MOSQ_ERR_INVAL;
}
key = argv[(*idx)+2];
value = argv[(*idx)+3];
(*idx) += 3;
}else{
value = argv[(*idx)+2];
(*idx) += 2;
}
switch(cmd){
case CMD_CONNECT:
proplist = &cfg->connect_props;
break;
case CMD_PUBLISH:
if(identifier == MQTT_PROP_TOPIC_ALIAS){
cfg->have_topic_alias = true;
}
if(identifier == MQTT_PROP_SUBSCRIPTION_IDENTIFIER){
fprintf(stderr, "Error: %s property not supported for %s in --property argument.\n\n", propname, cmdname);
return MOSQ_ERR_INVAL;
}
proplist = &cfg->publish_props;
break;
case CMD_SUBSCRIBE:
if(identifier != MQTT_PROP_SUBSCRIPTION_IDENTIFIER && identifier != MQTT_PROP_USER_PROPERTY){
fprintf(stderr, "Error: %s property not supported for %s in --property argument.\n\n", propname, cmdname);
return MOSQ_ERR_NOT_SUPPORTED;
}
proplist = &cfg->subscribe_props;
break;
case CMD_UNSUBSCRIBE:
proplist = &cfg->unsubscribe_props;
break;
case CMD_DISCONNECT:
proplist = &cfg->disconnect_props;
break;
case CMD_AUTH:
fprintf(stderr, "Error: %s property not supported for %s in --property argument.\n\n", propname, cmdname);
return MOSQ_ERR_NOT_SUPPORTED;
case CMD_WILL:
proplist = &cfg->will_props;
break;
case CMD_PUBACK:
case CMD_PUBREC:
case CMD_PUBREL:
case CMD_PUBCOMP:
case CMD_SUBACK:
case CMD_UNSUBACK:
fprintf(stderr, "Error: %s property not supported for %s in --property argument.\n\n", propname, cmdname);
return MOSQ_ERR_NOT_SUPPORTED;
default:
return MOSQ_ERR_INVAL;
}
switch(type){
case MQTT_PROP_TYPE_BYTE:
rc = mosquitto_property_add_byte(proplist, identifier, atoi(value));
break;
case MQTT_PROP_TYPE_INT16:
rc = mosquitto_property_add_int16(proplist, identifier, atoi(value));
break;
case MQTT_PROP_TYPE_INT32:
rc = mosquitto_property_add_int32(proplist, identifier, atoi(value));
break;
case MQTT_PROP_TYPE_VARINT:
rc = mosquitto_property_add_varint(proplist, identifier, atoi(value));
break;
case MQTT_PROP_TYPE_BINARY:
rc = mosquitto_property_add_binary(proplist, identifier, value, strlen(value));
break;
case MQTT_PROP_TYPE_STRING:
rc = mosquitto_property_add_string(proplist, identifier, value);
break;
case MQTT_PROP_TYPE_STRING_PAIR:
rc = mosquitto_property_add_string_pair(proplist, identifier, key, value);
break;
default:
return MOSQ_ERR_INVAL;
}
if(rc){
fprintf(stderr, "Error adding property %s %d\n", propname, type);
return rc;
}
return MOSQ_ERR_SUCCESS;
}
+77 -14
View File
@@ -32,9 +32,12 @@ Contributors:
#endif
#include <mosquitto.h>
#include <mqtt_protocol.h>
#include "client_shared.h"
#ifdef WITH_SOCKS
static int mosquitto__parse_socks_url(struct mosq_config *cfg, char *url);
#endif
static int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, char *argv[]);
@@ -154,7 +157,7 @@ void client_config_cleanup(struct mosq_config *cfg)
free(cfg->tls_engine);
free(cfg->tls_engine_kpass_sha1);
free(cfg->keyform);
# ifdef WITH_TLS_PSK
# ifdef FINAL_WITH_TLS_PSK
free(cfg->psk);
free(cfg->psk_identity);
# endif
@@ -182,6 +185,12 @@ void client_config_cleanup(struct mosq_config *cfg)
free(cfg->socks5_username);
free(cfg->socks5_password);
#endif
mosquitto_property_free_all(&cfg->connect_props);
mosquitto_property_free_all(&cfg->publish_props);
mosquitto_property_free_all(&cfg->subscribe_props);
mosquitto_property_free_all(&cfg->unsubscribe_props);
mosquitto_property_free_all(&cfg->disconnect_props);
mosquitto_property_free_all(&cfg->will_props);
}
int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char *argv[])
@@ -320,7 +329,7 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char *
return 1;
}
#endif
#ifdef WITH_TLS_PSK
#ifdef FINAL_WITH_TLS_PSK
if((cfg->cafile || cfg->capath) && cfg->psk){
if(!cfg->quiet) fprintf(stderr, "Error: Only one of --psk or --cafile/--capath may be used at once.\n");
return 1;
@@ -344,8 +353,44 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char *
}
if(!cfg->host){
cfg->host = "localhost";
cfg->host = strdup("localhost");
if(!cfg->host){
if(!cfg->quiet) fprintf(stderr, "Error: Out of memory.\n");
return 1;
}
}
rc = mosquitto_property_check_all(CMD_CONNECT, cfg->connect_props);
if(rc){
if(!cfg->quiet) fprintf(stderr, "Error in CONNECT properties: %s\n", mosquitto_strerror(rc));
return 1;
}
rc = mosquitto_property_check_all(CMD_PUBLISH, cfg->publish_props);
if(rc){
if(!cfg->quiet) fprintf(stderr, "Error in PUBLISH properties: %s\n", mosquitto_strerror(rc));
return 1;
}
rc = mosquitto_property_check_all(CMD_SUBSCRIBE, cfg->subscribe_props);
if(rc){
if(!cfg->quiet) fprintf(stderr, "Error in SUBSCRIBE properties: %s\n", mosquitto_strerror(rc));
return 1;
}
rc = mosquitto_property_check_all(CMD_UNSUBSCRIBE, cfg->unsubscribe_props);
if(rc){
if(!cfg->quiet) fprintf(stderr, "Error in UNSUBSCRIBE properties: %s\n", mosquitto_strerror(rc));
return 1;
}
rc = mosquitto_property_check_all(CMD_DISCONNECT, cfg->disconnect_props);
if(rc){
if(!cfg->quiet) fprintf(stderr, "Error in DISCONNECT properties: %s\n", mosquitto_strerror(rc));
return 1;
}
rc = mosquitto_property_check_all(CMD_WILL, cfg->will_props);
if(rc){
if(!cfg->quiet) fprintf(stderr, "Error in Will properties: %s\n", mosquitto_strerror(rc));
return 1;
}
return MOSQ_ERR_SUCCESS;
}
@@ -487,6 +532,12 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c
}
}else if(!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")){
cfg->debug = true;
}else if(!strcmp(argv[i], "-D") || !strcmp(argv[i], "--property")){
i++;
if(cfg_parse_property(cfg, argc, argv, &i)){
return 1;
}
cfg->protocol_version = MQTT_PROTOCOL_V5;
}else if(!strcmp(argv[i], "-f") || !strcmp(argv[i], "--file")){
if(pub_or_sub == CLIENT_SUB){
goto unknown_option;
@@ -686,15 +737,22 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c
}else{
cfg->pub_mode = MSGMODE_NULL;
}
}else if(!strcmp(argv[i], "--retain-as-published")){
if(pub_or_sub == CLIENT_PUB){
goto unknown_option;
}
cfg->sub_opts |= MQTT_SUB_OPT_RETAIN_AS_PUBLISHED;
}else if(!strcmp(argv[i], "-V") || !strcmp(argv[i], "--protocol-version")){
if(i==argc-1){
fprintf(stderr, "Error: --protocol-version argument given but no version specified.\n\n");
return 1;
}else{
if(!strcmp(argv[i+1], "mqttv31")){
if(!strcmp(argv[i+1], "mqttv31") || !strcmp(argv[i+1], "31")){
cfg->protocol_version = MQTT_PROTOCOL_V31;
}else if(!strcmp(argv[i+1], "mqttv311")){
}else if(!strcmp(argv[i+1], "mqttv311") || !strcmp(argv[i+1], "311")){
cfg->protocol_version = MQTT_PROTOCOL_V311;
}else if(!strcmp(argv[i+1], "mqttv5") || !strcmp(argv[i+1], "5")){
cfg->protocol_version = MQTT_PROTOCOL_V5;
}else{
fprintf(stderr, "Error: Invalid protocol version argument given.\n\n");
return 1;
@@ -713,7 +771,7 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c
i++;
}
#endif
#ifdef WITH_TLS_PSK
#ifdef FINAL_WITH_TLS_PSK
}else if(!strcmp(argv[i], "--psk")){
if(i==argc-1){
fprintf(stderr, "Error: --psk argument given but no key specified.\n\n");
@@ -924,16 +982,22 @@ unknown_option:
int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg)
{
#ifdef WITH_SOCKS
int rc;
#endif
if(cfg->will_topic && mosquitto_will_set(mosq, cfg->will_topic,
mosquitto_int_option(mosq, MOSQ_OPT_PROTOCOL_VERSION, cfg->protocol_version);
if(cfg->will_topic && mosquitto_will_set_v5(mosq, cfg->will_topic,
cfg->will_payloadlen, cfg->will_payload, cfg->will_qos,
cfg->will_retain)){
cfg->will_retain, cfg->will_props)){
if(!cfg->quiet) fprintf(stderr, "Error: Problem setting will.\n");
mosquitto_lib_cleanup();
return 1;
}
cfg->will_props = NULL;
if(cfg->username && mosquitto_username_pw_set(mosq, cfg->username, cfg->password)){
if(!cfg->quiet) fprintf(stderr, "Error: Problem setting username and password.\n");
mosquitto_lib_cleanup();
@@ -967,7 +1031,7 @@ int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg)
mosquitto_lib_cleanup();
return 1;
}
# ifdef WITH_TLS_PSK
# ifdef FINAL_WITH_TLS_PSK
if(cfg->psk && mosquitto_tls_psk_set(mosq, cfg->psk, cfg->psk_identity, NULL)){
if(!cfg->quiet) fprintf(stderr, "Error: Problem setting TLS-PSK options.\n");
mosquitto_lib_cleanup();
@@ -990,7 +1054,6 @@ int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg)
}
}
#endif
mosquitto_opts_set(mosq, MOSQ_OPT_PROTOCOL_VERSION, &(cfg->protocol_version));
return MOSQ_ERR_SUCCESS;
}
@@ -1007,7 +1070,7 @@ int client_id_generate(struct mosq_config *cfg, const char *id_base)
return 1;
}
snprintf(cfg->id, strlen(cfg->id_prefix)+10, "%s%d", cfg->id_prefix, getpid());
}else if(!cfg->id){
}else if(!cfg->id && (cfg->protocol_version == MQTT_PROTOCOL_V31 || cfg->protocol_version == MQTT_PROTOCOL_V311)){
hostname[0] = '\0';
gethostname(hostname, 256);
hostname[255] = '\0';
@@ -1040,7 +1103,7 @@ int client_connect(struct mosquitto *mosq, struct mosq_config *cfg)
if(cfg->port < 0){
#ifdef WITH_TLS
if(cfg->cafile || cfg->capath
# ifdef WITH_TLS_PSK
# ifdef FINAL_WITH_TLS_PSK
|| cfg->psk
# endif
){
@@ -1058,10 +1121,10 @@ int client_connect(struct mosquitto *mosq, struct mosq_config *cfg)
if(cfg->use_srv){
rc = mosquitto_connect_srv(mosq, cfg->host, cfg->keepalive, cfg->bind_address);
}else{
rc = mosquitto_connect_bind(mosq, cfg->host, port, cfg->keepalive, cfg->bind_address);
rc = mosquitto_connect_bind_v5(mosq, cfg->host, port, cfg->keepalive, cfg->bind_address, cfg->connect_props);
}
#else
rc = mosquitto_connect_bind(mosq, cfg->host, port, cfg->keepalive, cfg->bind_address);
rc = mosquitto_connect_bind_v5(mosq, cfg->host, port, cfg->keepalive, cfg->bind_address, cfg->connect_props);
#endif
if(rc>0){
if(!cfg->quiet){
+11 -1
View File
@@ -69,7 +69,7 @@ struct mosq_config {
char *tls_engine;
char *tls_engine_kpass_sha1;
char *keyform;
# ifdef WITH_TLS_PSK
# ifdef FINAL_WITH_TLS_PSK
char *psk;
char *psk_identity;
# endif
@@ -89,12 +89,20 @@ struct mosq_config {
int msg_count; /* sub */
char *format; /* sub */
int timeout; /* sub */
int sub_opts; /* sub */
#ifdef WITH_SOCKS
char *socks5_host;
int socks5_port;
char *socks5_username;
char *socks5_password;
#endif
mosquitto_property *connect_props;
mosquitto_property *publish_props;
mosquitto_property *subscribe_props;
mosquitto_property *unsubscribe_props;
mosquitto_property *disconnect_props;
mosquitto_property *will_props;
bool have_topic_alias; /* pub */
};
int client_config_load(struct mosq_config *config, int pub_or_sub, int argc, char *argv[]);
@@ -103,4 +111,6 @@ int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg);
int client_id_generate(struct mosq_config *cfg, const char *id_base);
int client_connect(struct mosquitto *mosq, struct mosq_config *cfg);
int cfg_parse_property(struct mosq_config *cfg, int argc, char *argv[], int *idx);
#endif
+67 -246
View File
@@ -31,50 +31,43 @@ Contributors:
#include <mosquitto.h>
#include "client_shared.h"
#define STATUS_CONNECTING 0
#define STATUS_CONNACK_RECVD 1
#define STATUS_WAITING 2
#define STATUS_DISCONNECTING 3
#include "pub_shared.h"
/* Global variables for use in callbacks. See sub_client.c for an example of
* using a struct to hold variables for use in callbacks. */
static char *topic = NULL;
static char *message = NULL;
static long msglen = 0;
static int qos = 0;
static int retain = 0;
static int mode = MSGMODE_NONE;
static int status = STATUS_CONNECTING;
static int mid_sent = 0;
static int last_mid = -1;
static int last_mid_sent = -1;
static bool connected = true;
static char *username = NULL;
static char *password = NULL;
static bool disconnect_sent = false;
static bool quiet = false;
static bool first_publish = true;
void my_connect_callback(struct mosquitto *mosq, void *obj, int result)
int my_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, void *payload, int qos, bool retain)
{
if(cfg.protocol_version == MQTT_PROTOCOL_V5 && cfg.have_topic_alias && first_publish == false){
return mosquitto_publish_v5(mosq, mid, NULL, payloadlen, payload, qos, retain, cfg.publish_props);
}else{
first_publish = false;
return mosquitto_publish_v5(mosq, mid, topic, payloadlen, payload, qos, retain, cfg.publish_props);
}
}
void my_connect_callback(struct mosquitto *mosq, void *obj, int result, int flags, const mosquitto_property *properties)
{
int rc = MOSQ_ERR_SUCCESS;
if(!result){
switch(mode){
switch(cfg.pub_mode){
case MSGMODE_CMD:
case MSGMODE_FILE:
case MSGMODE_STDIN_FILE:
rc = mosquitto_publish(mosq, &mid_sent, topic, msglen, message, qos, retain);
rc = my_publish(mosq, &mid_sent, cfg.topic, cfg.msglen, cfg.message, cfg.qos, cfg.retain);
break;
case MSGMODE_NULL:
rc = mosquitto_publish(mosq, &mid_sent, topic, 0, NULL, qos, retain);
rc = my_publish(mosq, &mid_sent, cfg.topic, 0, NULL, cfg.qos, cfg.retain);
break;
case MSGMODE_STDIN_LINE:
status = STATUS_CONNACK_RECVD;
break;
}
if(rc){
if(!quiet){
if(!cfg.quiet){
switch(rc){
case MOSQ_ERR_INVAL:
fprintf(stderr, "Error: Invalid input. Does your topic contain '+' or '#'?\n");
@@ -91,114 +84,24 @@ void my_connect_callback(struct mosquitto *mosq, void *obj, int result)
case MOSQ_ERR_PAYLOAD_SIZE:
fprintf(stderr, "Error: Message payload is too large.\n");
break;
case MOSQ_ERR_QOS_NOT_SUPPORTED:
fprintf(stderr, "Error: Message QoS not supported on broker, try a lower QoS.\n");
break;
}
}
mosquitto_disconnect(mosq);
mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
}
}else{
if(result && !quiet){
fprintf(stderr, "%s\n", mosquitto_connack_string(result));
if(result && !cfg.quiet){
if(cfg.protocol_version == MQTT_PROTOCOL_V5){
fprintf(stderr, "%s\n", mosquitto_reason_string(result));
}else{
fprintf(stderr, "%s\n", mosquitto_connack_string(result));
}
}
}
}
void my_disconnect_callback(struct mosquitto *mosq, void *obj, int rc)
{
connected = false;
}
void my_publish_callback(struct mosquitto *mosq, void *obj, int mid)
{
last_mid_sent = mid;
if(mode == MSGMODE_STDIN_LINE){
if(mid == last_mid){
mosquitto_disconnect(mosq);
disconnect_sent = true;
}
}else if(disconnect_sent == false){
mosquitto_disconnect(mosq);
disconnect_sent = true;
}
}
void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str)
{
printf("%s\n", str);
}
int load_stdin(void)
{
long pos = 0, rlen;
char buf[1024];
char *aux_message = NULL;
mode = MSGMODE_STDIN_FILE;
while(!feof(stdin)){
rlen = fread(buf, 1, 1024, stdin);
aux_message = realloc(message, pos+rlen);
if(!aux_message){
if(!quiet) fprintf(stderr, "Error: Out of memory.\n");
free(message);
return 1;
} else
{
message = aux_message;
}
memcpy(&(message[pos]), buf, rlen);
pos += rlen;
}
msglen = pos;
if(!msglen){
if(!quiet) fprintf(stderr, "Error: Zero length input.\n");
return 1;
}
return 0;
}
int load_file(const char *filename)
{
long pos, rlen;
FILE *fptr = NULL;
fptr = fopen(filename, "rb");
if(!fptr){
if(!quiet) fprintf(stderr, "Error: Unable to open file \"%s\".\n", filename);
return 1;
}
mode = MSGMODE_FILE;
fseek(fptr, 0, SEEK_END);
msglen = ftell(fptr);
if(msglen > 268435455){
fclose(fptr);
if(!quiet) fprintf(stderr, "Error: File \"%s\" is too large (>268,435,455 bytes).\n", filename);
return 1;
}else if(msglen == 0){
fclose(fptr);
if(!quiet) fprintf(stderr, "Error: File \"%s\" is empty.\n", filename);
return 1;
}else if(msglen < 0){
fclose(fptr);
if(!quiet) fprintf(stderr, "Error: Unable to determine size of file \"%s\".\n", filename);
return 1;
}
fseek(fptr, 0, SEEK_SET);
message = malloc(msglen);
if(!message){
fclose(fptr);
if(!quiet) fprintf(stderr, "Error: Out of memory.\n");
return 1;
}
pos = 0;
while(pos < msglen){
rlen = fread(&(message[pos]), sizeof(char), msglen-pos, fptr);
pos += rlen;
}
fclose(fptr);
return 0;
}
void print_usage(void)
{
@@ -224,17 +127,20 @@ void print_usage(void)
printf(" [{--cafile file | --capath dir} [--cert file] [--key file]\n");
printf(" [--ciphers ciphers] [--insecure]\n");
printf(" [--tls-engine engine] [--keyform keyform] [--tls-engine-kpass-sha1]]\n");
#ifdef WITH_TLS_PSK
#ifdef FINAL_WITH_TLS_PSK
printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
#endif
#endif
#ifdef WITH_SOCKS
printf(" [--proxy socks-url]\n");
#endif
printf(" [--property command identifier value]\n");
printf(" [-D command identifier value]\n");
printf(" mosquitto_pub --help\n\n");
printf(" -A : bind the outgoing socket to this host/ip address. Use to control which interface\n");
printf(" the client communicates over.\n");
printf(" -d : enable debug messages.\n");
printf(" -D : Define MQTT v5 properties. See the documentation for more details.\n");
printf(" -f : send the contents of a file as the message.\n");
printf(" -h : mqtt host to connect to. Defaults to localhost.\n");
printf(" -i : id to use for this client. Defaults to mosquitto_pub_ appended with the process id.\n");
@@ -258,7 +164,7 @@ void print_usage(void)
printf(" -t : mqtt topic to publish to.\n");
printf(" -u : provide a username\n");
printf(" -V : specify the version of the MQTT protocol to use when connecting.\n");
printf(" Can be mqttv31 or mqttv311. Defaults to mqttv311.\n");
printf(" Can be mqttv5, mqttv311 or mqttv31. Defaults to mqttv311.\n");
printf(" --help : display this message.\n");
printf(" --quiet : don't print error messages.\n");
printf(" --will-payload : payload for the client Will, which is sent by the broker in case of\n");
@@ -282,9 +188,9 @@ void print_usage(void)
printf(" hostname. Using this option means that you cannot be sure that the\n");
printf(" remote host is the server you wish to connect to and so is insecure.\n");
printf(" Do not use this option in a production environment.\n");
printf(" --tls-engine : If set, enables the use of a SSL engine device.\n");
printf(" --tls-engine : If set, enables the use of a TLS engine device.\n");
printf(" --tls-engine-kpass-sha1 : SHA1 of the key password to be used with the selected SSL engine.\n");
# ifdef WITH_TLS_PSK
# ifdef FINAL_WITH_TLS_PSK
printf(" --psk : pre-shared-key in hexadecimal (no leading 0x) to enable TLS-PSK mode.\n");
printf(" --psk-identity : client identity string for TLS-PSK mode.\n");
# endif
@@ -294,191 +200,106 @@ void print_usage(void)
printf(" socks5h://[username[:password]@]hostname[:port]\n");
printf(" Only \"none\" and \"username\" authentication is supported.\n");
#endif
printf("\nSee http://mosquitto.org/ for more information.\n\n");
printf("\nSee https://mosquitto.org/ for more information.\n\n");
}
int main(int argc, char *argv[])
{
struct mosq_config cfg;
struct mosquitto *mosq = NULL;
int rc;
int rc2;
char *buf, *buf2;
int buf_len = 1024;
int buf_len_actual;
int read_len;
int pos;
buf = malloc(buf_len);
if(!buf){
fprintf(stderr, "Error: Out of memory.\n");
return 1;
}
mosquitto_lib_init();
if(pub_shared_init()) return 1;
memset(&cfg, 0, sizeof(struct mosq_config));
rc = client_config_load(&cfg, CLIENT_PUB, argc, argv);
if(rc){
client_config_cleanup(&cfg);
if(rc == 2){
/* --help */
print_usage();
}else{
fprintf(stderr, "\nUse 'mosquitto_pub --help' to see usage.\n");
}
free(buf);
return 1;
goto cleanup;
}
topic = cfg.topic;
message = cfg.message;
msglen = cfg.msglen;
qos = cfg.qos;
retain = cfg.retain;
mode = cfg.pub_mode;
username = cfg.username;
password = cfg.password;
quiet = cfg.quiet;
#ifndef WITH_THREADING
if(cfg.pub_mode == MSGMODE_STDIN_LINE){
fprintf(stderr, "Error: '-l' mode not available, threading support has not been compiled in.\n");
free(buf);
return 1;
goto cleanup;
}
#endif
if(cfg.pub_mode == MSGMODE_STDIN_FILE){
if(load_stdin()){
fprintf(stderr, "Error loading input from stdin.\n");
free(buf);
return 1;
goto cleanup;
}
}else if(cfg.file_input){
if(load_file(cfg.file_input)){
fprintf(stderr, "Error loading input file \"%s\".\n", cfg.file_input);
free(buf);
return 1;
goto cleanup;
}
}
if(!topic || mode == MSGMODE_NONE){
if(!cfg.topic || cfg.pub_mode == MSGMODE_NONE){
fprintf(stderr, "Error: Both topic and message must be supplied.\n");
print_usage();
free(buf);
return 1;
goto cleanup;
}
mosquitto_lib_init();
if(client_id_generate(&cfg, "mosqpub")){
free(buf);
return 1;
goto cleanup;
}
mosq = mosquitto_new(cfg.id, true, NULL);
if(!mosq){
switch(errno){
case ENOMEM:
if(!quiet) fprintf(stderr, "Error: Out of memory.\n");
if(!cfg.quiet) fprintf(stderr, "Error: Out of memory.\n");
break;
case EINVAL:
if(!quiet) fprintf(stderr, "Error: Invalid id.\n");
if(!cfg.quiet) fprintf(stderr, "Error: Invalid id.\n");
break;
}
mosquitto_lib_cleanup();
free(buf);
return 1;
goto cleanup;
}
if(cfg.debug){
mosquitto_log_callback_set(mosq, my_log_callback);
}
mosquitto_connect_callback_set(mosq, my_connect_callback);
mosquitto_disconnect_callback_set(mosq, my_disconnect_callback);
mosquitto_publish_callback_set(mosq, my_publish_callback);
mosquitto_connect_v5_callback_set(mosq, my_connect_callback);
mosquitto_disconnect_v5_callback_set(mosq, my_disconnect_callback);
mosquitto_publish_v5_callback_set(mosq, my_publish_callback);
if(client_opts_set(mosq, &cfg)){
free(buf);
return 1;
goto cleanup;
}
rc = client_connect(mosq, &cfg);
if(rc) return rc;
if(mode == MSGMODE_STDIN_LINE){
mosquitto_loop_start(mosq);
if(rc){
goto cleanup;
}
do{
if(mode == MSGMODE_STDIN_LINE){
if(status == STATUS_CONNACK_RECVD){
pos = 0;
read_len = buf_len;
while(fgets(&buf[pos], read_len, stdin)){
buf_len_actual = strlen(buf);
if(buf[buf_len_actual-1] == '\n'){
buf[buf_len_actual-1] = '\0';
rc2 = mosquitto_publish(mosq, &mid_sent, topic, buf_len_actual-1, buf, qos, retain);
if(rc2){
if(!quiet) fprintf(stderr, "Error: Publish returned %d, disconnecting.\n", rc2);
mosquitto_disconnect(mosq);
}
break;
}else{
buf_len += 1024;
pos += 1023;
read_len = 1024;
buf2 = realloc(buf, buf_len);
if(!buf2){
free(buf);
fprintf(stderr, "Error: Out of memory.\n");
return 1;
}
buf = buf2;
}
}
if(feof(stdin)){
if(last_mid == -1){
/* Empty file */
mosquitto_disconnect(mosq);
disconnect_sent = true;
status = STATUS_DISCONNECTING;
}else{
last_mid = mid_sent;
status = STATUS_WAITING;
}
}
}else if(status == STATUS_WAITING){
if(last_mid_sent == last_mid && disconnect_sent == false){
mosquitto_disconnect(mosq);
disconnect_sent = true;
}
#ifdef WIN32
Sleep(100);
#else
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 100000000;
nanosleep(&ts, NULL);
#endif
}
rc = MOSQ_ERR_SUCCESS;
}else{
rc = mosquitto_loop(mosq, -1, 1);
}
}while(rc == MOSQ_ERR_SUCCESS && connected);
rc = pub_shared_loop(mosq);
if(mode == MSGMODE_STDIN_LINE){
mosquitto_loop_stop(mosq, false);
}
if(message && mode == MSGMODE_FILE){
free(message);
if(cfg.message && cfg.pub_mode == MSGMODE_FILE){
free(cfg.message);
}
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
client_config_cleanup(&cfg);
pub_shared_cleanup();
if(rc){
fprintf(stderr, "Error: %s\n", mosquitto_strerror(rc));
}
return rc;
cleanup:
mosquitto_lib_cleanup();
client_config_cleanup(&cfg);
pub_shared_cleanup();
return 1;
}
+243
View File
@@ -0,0 +1,243 @@
/*
Copyright (c) 2009-2018 Roger Light <roger@atchoo.org>
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
and Eclipse Distribution License v1.0 which accompany this distribution.
The Eclipse Public License is available at
http://www.eclipse.org/legal/epl-v10.html
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
Contributors:
Roger Light - initial implementation and documentation.
*/
#include "config.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <time.h>
#else
#include <process.h>
#include <winsock2.h>
#define snprintf sprintf_s
#endif
#include <mosquitto.h>
#include <mqtt_protocol.h>
#include "client_shared.h"
#include "pub_shared.h"
/* 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 = 0;
int status = STATUS_CONNECTING;
struct mosq_config cfg;
static int last_mid = -1;
static int last_mid_sent = -1;
static bool connected = true;
static bool disconnect_sent = false;
static char *buf = NULL;
static int buf_len = 1024;
void my_disconnect_callback(struct mosquitto *mosq, void *obj, int rc, const mosquitto_property *properties)
{
connected = false;
}
void my_publish_callback(struct mosquitto *mosq, void *obj, int mid, int reason_code, const mosquitto_property *properties)
{
last_mid_sent = mid;
if(cfg.pub_mode == MSGMODE_STDIN_LINE){
if(mid == last_mid){
mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
disconnect_sent = true;
}
}else if(disconnect_sent == false){
mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
disconnect_sent = true;
}
}
void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str)
{
printf("%s\n", str);
}
int load_stdin(void)
{
long pos = 0, rlen;
char buf[1024];
char *aux_message = NULL;
cfg.pub_mode = MSGMODE_STDIN_FILE;
while(!feof(stdin)){
rlen = fread(buf, 1, 1024, stdin);
aux_message = realloc(cfg.message, pos+rlen);
if(!aux_message){
if(!cfg.quiet) fprintf(stderr, "Error: Out of memory.\n");
free(cfg.message);
return 1;
} else
{
cfg.message = aux_message;
}
memcpy(&(cfg.message[pos]), buf, rlen);
pos += rlen;
}
cfg.msglen = pos;
if(!cfg.msglen){
if(!cfg.quiet) fprintf(stderr, "Error: Zero length input.\n");
return 1;
}
return 0;
}
int load_file(const char *filename)
{
long pos, rlen;
FILE *fptr = NULL;
fptr = fopen(filename, "rb");
if(!fptr){
if(!cfg.quiet) fprintf(stderr, "Error: Unable to open file \"%s\".\n", filename);
return 1;
}
cfg.pub_mode = MSGMODE_FILE;
fseek(fptr, 0, SEEK_END);
cfg.msglen = ftell(fptr);
if(cfg.msglen > 268435455){
fclose(fptr);
if(!cfg.quiet) fprintf(stderr, "Error: File \"%s\" is too large (>268,435,455 bytes).\n", filename);
return 1;
}else if(cfg.msglen == 0){
fclose(fptr);
if(!cfg.quiet) fprintf(stderr, "Error: File \"%s\" is empty.\n", filename);
return 1;
}else if(cfg.msglen < 0){
fclose(fptr);
if(!cfg.quiet) fprintf(stderr, "Error: Unable to determine size of file \"%s\".\n", filename);
return 1;
}
fseek(fptr, 0, SEEK_SET);
cfg.message = malloc(cfg.msglen);
if(!cfg.message){
fclose(fptr);
if(!cfg.quiet) fprintf(stderr, "Error: Out of memory.\n");
return 1;
}
pos = 0;
while(pos < cfg.msglen){
rlen = fread(&(cfg.message[pos]), sizeof(char), cfg.msglen-pos, fptr);
pos += rlen;
}
fclose(fptr);
return 0;
}
int pub_shared_init(void)
{
buf = malloc(buf_len);
if(!buf){
fprintf(stderr, "Error: Out of memory.\n");
return 1;
}
return 0;
}
int pub_shared_loop(struct mosquitto *mosq)
{
int read_len;
int pos;
int rc, rc2;
char *buf2;
int buf_len_actual;
int mode;
mode = cfg.pub_mode;
if(mode == MSGMODE_STDIN_LINE){
mosquitto_loop_start(mosq);
}
do{
if(mode == MSGMODE_STDIN_LINE){
if(status == STATUS_CONNACK_RECVD){
pos = 0;
read_len = buf_len;
while(connected && fgets(&buf[pos], read_len, stdin)){
buf_len_actual = strlen(buf);
if(buf[buf_len_actual-1] == '\n'){
buf[buf_len_actual-1] = '\0';
rc2 = my_publish(mosq, &mid_sent, cfg.topic, buf_len_actual-1, buf, cfg.qos, cfg.retain);
if(rc2){
if(!cfg.quiet) fprintf(stderr, "Error: Publish returned %d, disconnecting.\n", rc2);
mosquitto_disconnect_v5(mosq, MQTT_RC_DISCONNECT_WITH_WILL_MSG, cfg.disconnect_props);
}
break;
}else{
buf_len += 1024;
pos += 1023;
read_len = 1024;
buf2 = realloc(buf, buf_len);
if(!buf2){
fprintf(stderr, "Error: Out of memory.\n");
return MOSQ_ERR_NOMEM;
}
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;
}
}
}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 = MOSQ_ERR_SUCCESS;
}else{
rc = mosquitto_loop(mosq, -1, 1);
}
}while(rc == MOSQ_ERR_SUCCESS && connected);
if(mode == MSGMODE_STDIN_LINE){
mosquitto_loop_stop(mosq, false);
}
return 0;
}
void pub_shared_cleanup(void)
{
free(buf);
}
+42
View File
@@ -0,0 +1,42 @@
/*
Copyright (c) 2009-2018 Roger Light <roger@atchoo.org>
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
and Eclipse Distribution License v1.0 which accompany this distribution.
The Eclipse Public License is available at
http://www.eclipse.org/legal/epl-v10.html
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
Contributors:
Roger Light - initial implementation and documentation.
*/
#ifndef PUB_SHARED_H
#define PUB_SHARED_H
#define STATUS_CONNECTING 0
#define STATUS_CONNACK_RECVD 1
#define STATUS_WAITING 2
#define STATUS_DISCONNECTING 3
extern int mid_sent;
extern int status;
extern struct mosq_config cfg;
void my_connect_callback(struct mosquitto *mosq, void *obj, int result, int flags, const mosquitto_property *properties);
void my_disconnect_callback(struct mosquitto *mosq, void *obj, int rc, const mosquitto_property *properties);
void my_publish_callback(struct mosquitto *mosq, void *obj, int mid, int reason_code, const mosquitto_property *properties);
void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str);
int load_stdin(void);
int load_file(const char *filename);
int my_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, void *payload, int qos, bool retain);
int pub_shared_init(void);
int pub_shared_loop(struct mosquitto *mosq);
void pub_shared_cleanup(void);
#endif
+26
View File
@@ -0,0 +1,26 @@
LD_LIBRARY_PATH=../lib ./mosquitto_pub \
\
-t asdf -V mqttv5 -m '{"key":"value"}' \
\
-D connect authentication-data password \
-D connect authentication-method something \
-D connect maximum-packet-size 0191 \
-D connect receive-maximum 1000 \
-D connect request-problem-information 1 \
-D connect request-response-information 1 \
-D connect session-expiry-interval 39 \
-D connect topic-alias-maximum 123 \
-D connect user-property connect up \
\
-D publish content-type application/json \
-D publish correlation-data some-data \
-D publish message-expiry-interval 59 \
-D publish payload-format-indicator 1 \
-D publish response-topic /dev/null \
-D publish topic-alias 4 \
-D publish user-property publish up \
\
-D disconnect reason-string "reason" \
-D disconnect session-expiry-interval 40 \
-D disconnect user-property disconnect up
+54 -53
View File
@@ -32,8 +32,10 @@ Contributors:
#endif
#include <mosquitto.h>
#include <mqtt_protocol.h>
#include "client_shared.h"
static struct mosq_config cfg;
bool process_messages = true;
int msg_count = 0;
struct mosquitto *mosq = NULL;
@@ -43,7 +45,7 @@ void my_signal_handler(int signum)
{
if(signum == SIGALRM){
process_messages = false;
mosquitto_disconnect(mosq);
mosquitto_disconnect_v5(mosq, MQTT_RC_DISCONNECT_WITH_WILL_MSG, cfg.disconnect_props);
}
}
#endif
@@ -51,80 +53,72 @@ void my_signal_handler(int signum)
void print_message(struct mosq_config *cfg, const struct mosquitto_message *message);
void my_message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
void my_message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message, const mosquitto_property *properties)
{
struct mosq_config *cfg;
int i;
bool res;
if(process_messages == false) return;
assert(obj);
cfg = (struct mosq_config *)obj;
if(cfg->retained_only && !message->retain && process_messages){
if(cfg.retained_only && !message->retain && process_messages){
process_messages = false;
mosquitto_disconnect(mosq);
mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
return;
}
if(message->retain && cfg->no_retain) return;
if(cfg->filter_outs){
for(i=0; i<cfg->filter_out_count; i++){
mosquitto_topic_matches_sub(cfg->filter_outs[i], message->topic, &res);
if(message->retain && cfg.no_retain) return;
if(cfg.filter_outs){
for(i=0; i<cfg.filter_out_count; i++){
mosquitto_topic_matches_sub(cfg.filter_outs[i], message->topic, &res);
if(res) return;
}
}
print_message(cfg, message);
print_message(&cfg, message);
if(cfg->msg_count>0){
if(cfg.msg_count>0){
msg_count++;
if(cfg->msg_count == msg_count){
if(cfg.msg_count == msg_count){
process_messages = false;
mosquitto_disconnect(mosq);
mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
}
}
}
void my_connect_callback(struct mosquitto *mosq, void *obj, int result, int flags)
void my_connect_callback(struct mosquitto *mosq, void *obj, int result, int flags, const mosquitto_property *properties)
{
int i;
struct mosq_config *cfg;
assert(obj);
cfg = (struct mosq_config *)obj;
if(!result){
mosquitto_subscribe_multiple(mosq, NULL, cfg->topic_count, cfg->topics, cfg->qos);
mosquitto_subscribe_multiple(mosq, NULL, cfg.topic_count, cfg.topics, cfg.qos, cfg.sub_opts, cfg.subscribe_props);
for(i=0; i<cfg->unsub_topic_count; i++){
mosquitto_unsubscribe(mosq, NULL, cfg->unsub_topics[i]);
for(i=0; i<cfg.unsub_topic_count; i++){
mosquitto_unsubscribe_v5(mosq, NULL, cfg.unsub_topics[i], cfg.unsubscribe_props);
}
}else{
if(result && !cfg->quiet){
fprintf(stderr, "%s\n", mosquitto_connack_string(result));
if(result && !cfg.quiet){
if(cfg.protocol_version == MQTT_PROTOCOL_V5){
fprintf(stderr, "%s\n", mosquitto_reason_string(result));
}else{
fprintf(stderr, "%s\n", mosquitto_connack_string(result));
}
}
mosquitto_disconnect(mosq);
mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
}
}
void my_subscribe_callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos)
{
int i;
struct mosq_config *cfg;
assert(obj);
cfg = (struct mosq_config *)obj;
if(!cfg->quiet) printf("Subscribed (mid: %d): %d", mid, granted_qos[0]);
if(!cfg.quiet) printf("Subscribed (mid: %d): %d", mid, granted_qos[0]);
for(i=1; i<qos_count; i++){
if(!cfg->quiet) printf(", %d", granted_qos[i]);
if(!cfg.quiet) printf(", %d", granted_qos[i]);
}
if(!cfg->quiet) printf("\n");
if(!cfg.quiet) printf("\n");
if(cfg->exit_after_sub){
mosquitto_disconnect(mosq);
if(cfg.exit_after_sub){
mosquitto_disconnect_v5(mosq, 0, cfg.disconnect_props);
}
}
@@ -159,19 +153,21 @@ void print_usage(void)
printf(" [{--cafile file | --capath dir} [--cert file] [--key file]\n");
printf(" [--ciphers ciphers] [--insecure] [--tls-engine engine]\n");
printf(" [--keyform keyform] [--tls-engine-kpass-sha1]]\n");
#ifdef WITH_TLS_PSK
#ifdef FINAL_WITH_TLS_PSK
printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
#endif
#endif
#ifdef WITH_SOCKS
printf(" [--proxy socks-url]\n");
#endif
printf(" [-D command identifier value]\n");
printf(" mosquitto_sub --help\n\n");
printf(" -A : bind the outgoing socket to this host/ip address. Use to control which interface\n");
printf(" the client communicates over.\n");
printf(" -c : disable 'clean session' (store subscription and pending messages when client disconnects).\n");
printf(" -C : disconnect and exit after receiving the 'msg_count' messages.\n");
printf(" -d : enable debug messages.\n");
printf(" -D : Define MQTT v5 properties. See the documentation for more details.\n");
printf(" -E : Exit once all subscriptions have been acknowledged by the broker.\n");
printf(" -F : output format.\n");
printf(" -h : mqtt host to connect to. Defaults to localhost.\n");
@@ -195,7 +191,7 @@ void print_usage(void)
printf(" -U : unsubscribe from a topic. May be repeated.\n");
printf(" -v : print published messages verbosely.\n");
printf(" -V : specify the version of the MQTT protocol to use when connecting.\n");
printf(" Can be mqttv31 or mqttv311. Defaults to mqttv311.\n");
printf(" Can be mqttv5, mqttv311 or mqttv31. Defaults to mqttv311.\n");
#ifndef WIN32
printf(" -W : Specifies a timeout in seconds how long to process incoming MQTT messages.\n");
#endif
@@ -226,7 +222,7 @@ void print_usage(void)
printf(" Do not use this option in a production environment.\n");
printf(" --tls-engine : If set, enables the use of a SSL engine device.\n");
printf(" --tls-engine-kpass-sha1 : SHA1 of the key password to be used with the selected SSL engine.\n");
#ifdef WITH_TLS_PSK
#ifdef FINAL_WITH_TLS_PSK
printf(" --psk : pre-shared-key in hexadecimal (no leading 0x) to enable TLS-PSK mode.\n");
printf(" --psk-identity : client identity string for TLS-PSK mode.\n");
#endif
@@ -241,7 +237,6 @@ void print_usage(void)
int main(int argc, char *argv[])
{
struct mosq_config cfg;
int rc;
#ifndef WIN32
struct sigaction sigact;
@@ -249,27 +244,26 @@ int main(int argc, char *argv[])
memset(&cfg, 0, sizeof(struct mosq_config));
mosquitto_lib_init();
rc = client_config_load(&cfg, CLIENT_SUB, argc, argv);
if(rc){
client_config_cleanup(&cfg);
if(rc == 2){
/* --help */
print_usage();
}else{
fprintf(stderr, "\nUse 'mosquitto_sub --help' to see usage.\n");
}
return 1;
goto cleanup;
}
if(cfg.no_retain && cfg.retained_only){
fprintf(stderr, "\nError: Combining '-R' and '--retained-only' makes no sense.\n");
return 1;
goto cleanup;
}
mosquitto_lib_init();
if(client_id_generate(&cfg, "mosqsub")){
return 1;
goto cleanup;
}
mosq = mosquitto_new(cfg.id, cfg.clean_session, &cfg);
@@ -282,21 +276,22 @@ int main(int argc, char *argv[])
if(!cfg.quiet) fprintf(stderr, "Error: Invalid id and/or clean_session.\n");
break;
}
mosquitto_lib_cleanup();
return 1;
goto cleanup;
}
if(client_opts_set(mosq, &cfg)){
return 1;
goto cleanup;
}
if(cfg.debug){
mosquitto_log_callback_set(mosq, my_log_callback);
mosquitto_subscribe_callback_set(mosq, my_subscribe_callback);
}
mosquitto_connect_with_flags_callback_set(mosq, my_connect_callback);
mosquitto_message_callback_set(mosq, my_message_callback);
mosquitto_connect_v5_callback_set(mosq, my_connect_callback);
mosquitto_message_v5_callback_set(mosq, my_message_callback);
rc = client_connect(mosq, &cfg);
if(rc) return rc;
if(rc){
goto cleanup;
}
#ifndef WIN32
sigact.sa_handler = my_signal_handler;
@@ -305,7 +300,7 @@ int main(int argc, char *argv[])
if(sigaction(SIGALRM, &sigact, NULL) == -1){
perror("sigaction");
return 1;
goto cleanup;
}
if(cfg.timeout){
@@ -321,9 +316,15 @@ int main(int argc, char *argv[])
if(cfg.msg_count>0 && rc == MOSQ_ERR_NO_CONN){
rc = 0;
}
client_config_cleanup(&cfg);
if(rc){
fprintf(stderr, "Error: %s\n", mosquitto_strerror(rc));
}
return rc;
cleanup:
mosquitto_lib_cleanup();
client_config_cleanup(&cfg);
return 1;
}
+2 -2
View File
@@ -85,11 +85,11 @@ static void write_payload(const unsigned char *payload, int payloadlen, int hex)
(void)fwrite(payload, 1, payloadlen, stdout);
}else if(hex == 1){
for(i=0; i<payloadlen; i++){
fprintf(stdout, "%x", payload[i]);
fprintf(stdout, "%02x", payload[i]);
}
}else if(hex == 2){
for(i=0; i<payloadlen; i++){
fprintf(stdout, "%X", payload[i]);
fprintf(stdout, "%02X", payload[i]);
}
}
}
+31
View File
@@ -0,0 +1,31 @@
LD_LIBRARY_PATH=../lib ./mosquitto_sub \
\
-V mqttv5 -C 10 -t \$SYS/# -v -U unsub --will-topic will --will-payload '{"key":"value"}' \
\
-D connect authentication-data password \
-D connect authentication-method something \
-D connect maximum-packet-size 0191 \
-D connect receive-maximum 1000 \
-D connect request-problem-information 1 \
-D connect request-response-information 1 \
-D connect session-expiry-interval 39 \
-D connect topic-alias-maximum 123 \
-D connect user-property connect up \
\
-D will content-type application/json \
-D will correlation-data some-data \
-D will message-expiry-interval 59 \
-D will payload-format-indicator 1 \
-D will response-topic /dev/null \
-D will user-property will up \
-D will will-delay-interval 100 \
\
-D subscribe subscription-identifier 1 \
-D subscribe user-property subscribe up \
\
-D unsubscribe user-property unsubscribe up \
\
-D disconnect reason-string "reason" \
-D disconnect session-expiry-interval 40 \
-D disconnect user-property disconnect up
-1
View File
@@ -3,7 +3,6 @@ are optional.
* openssl
* c-ares (for DNS-SRV support, disabled by default)
* libuuid (from util-linux, can be disabled)
* tcp-wrappers (optional, package name libwrap0-dev)
* libwebsockets (optional, disabled by default, version 1.3 and above)
* On Windows, a pthreads library is required if threading support is to be
+8
View File
@@ -39,4 +39,12 @@
#define uthash_malloc(sz) mosquitto__malloc(sz)
#define uthash_free(ptr,sz) mosquitto__free(ptr)
#ifdef WITH_TLS
# include <openssl/opensslconf.h>
# if defined(WITH_TLS_PSK) && !defined(OPENSSL_NO_PSK)
# define FINAL_WITH_TLS_PSK
# endif
#endif
#endif
+15 -13
View File
@@ -64,10 +64,6 @@ WITH_SYSTEMD:=no
# Build with SRV lookup support.
WITH_SRV:=no
# Build using libuuid for clientid generation (Linux only - please report if
# supported on your platform).
WITH_UUID:=yes
# Build with websockets support on the broker.
WITH_WEBSOCKETS:=no
@@ -98,6 +94,9 @@ WITH_EPOLL:=yes
# Build with bundled uthash.h
WITH_BUNDLED_DEPS:=yes
# Build with coverage options
WITH_COVERAGE:=no
# =============================================================================
# End of user configuration
# =============================================================================
@@ -105,13 +104,13 @@ WITH_BUNDLED_DEPS:=yes
# Also bump lib/mosquitto.h, CMakeLists.txt,
# installer/mosquitto.nsi, installer/mosquitto64.nsi
VERSION=1.5.4
VERSION=1.5.90
# Client library SO version. Bump if incompatible API/ABI changes are made.
SOVERSION=1
# Man page generation requires xsltproc and docbook-xsl
XSLTPROC=xsltproc
XSLTPROC=xsltproc --nonet
# For html generation
DB_HTML_XSL=man/html.xsl
@@ -134,6 +133,7 @@ LIB_CXXFLAGS:=$(CFLAGS) ${CPPFLAGS} -I. -I.. -I../lib
LIB_LDFLAGS:=${LDFLAGS}
BROKER_CFLAGS:=${LIB_CFLAGS} ${CPPFLAGS} -DVERSION="\"${VERSION}\"" -DWITH_BROKER
BROKER_LDFLAGS:=${LDFLAGS}
CLIENT_CFLAGS:=${CFLAGS} ${CPPFLAGS} -I.. -I../lib -DVERSION="\"${VERSION}\""
ifneq ($(or $(findstring $(UNAME),FreeBSD), $(findstring $(UNAME),OpenBSD), $(findstring $(UNAME),NetBSD)),)
@@ -211,13 +211,6 @@ ifeq ($(WITH_SOCKS),yes)
CLIENT_CFLAGS:=$(CLIENT_CFLAGS) -DWITH_SOCKS
endif
ifeq ($(WITH_UUID),yes)
ifeq ($(UNAME),Linux)
BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_UUID
BROKER_LIBS:=$(BROKER_LIBS) -luuid
endif
endif
ifeq ($(WITH_BRIDGE),yes)
BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_BRIDGE
endif
@@ -301,3 +294,12 @@ endif
ifeq ($(WITH_BUNDLED_DEPS),yes)
BROKER_CFLAGS:=$(BROKER_CFLAGS) -Ideps
endif
ifeq ($(WITH_COVERAGE),yes)
BROKER_CFLAGS:=$(BROKER_CFLAGS) -coverage
BROKER_LDFLAGS:=$(BROKER_LDFLAGS) -coverage
LIB_CFLAGS:=$(LIB_CFLAGS) -coverage
LIB_LDFLAGS:=$(LIB_LDFLAGS) -coverage
CLIENT_CFLAGS:=$(CLIENT_CFLAGS) -coverage
CLIENT_LDFLAGS:=$(CLIENT_LDFLAGS) -coverage
endif
+4 -4
View File
@@ -3,8 +3,8 @@ FROM alpine:3.8
LABEL maintainer="Roger Light <roger@atchoo.org>" \
description="Eclipse Mosquitto MQTT Broker"
ENV VERSION=1.5.4 \
DOWNLOAD_SHA256=5fd7f3454fd6d286645d032bc07f44a1c8583cec02ef2422c9eb32e0a89a9b2f \
ENV VERSION=1.5.6 \
DOWNLOAD_SHA256=d5bdc13cc668350026376d57fc14de10aaee029f6840707677637d15e0751a40 \
GPG_KEYS=A0D6EEA1DCAE49A635A3B2F0779B22DFB3E717B7 \
LWS_VERSION=2.4.2
@@ -67,8 +67,8 @@ RUN set -x && \
WITH_WEBSOCKETS=yes \
prefix=/usr \
binary && \
addgroup -S mosquitto 2>/dev/null && \
adduser -S -D -H -h /var/empty -s /sbin/nologin -G mosquitto -g mosquitto mosquitto 2>/dev/null && \
addgroup -S -g 1883 mosquitto 2>/dev/null && \
adduser -S -u 1883 -D -H -h /var/empty -s /sbin/nologin -G mosquitto -g mosquitto mosquitto 2>/dev/null && \
mkdir -p /mosquitto/config /mosquitto/data /mosquitto/log && \
install -d /usr/sbin/ && \
install -s -m755 /build/mosq/src/mosquitto /usr/sbin/mosquitto && \
+5
View File
@@ -13,6 +13,11 @@ Two docker volumes have been created in the image to be used for persistent stor
/mosquitto/log
```
## User/Group
The image runs mosqutto under the mosquitto user and group, which are created
with a uid and gid of 1883.
## Configuration
When creating a container from the image, the default configuration values are used.
To use a custom configuration file, mount a **local** configuration file to `/mosquitto/config/mosquitto.conf`
+6 -32
View File
@@ -9,7 +9,7 @@
!define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
Name "Eclipse Mosquitto"
!define VERSION 1.5.4
!define VERSION 1.5.90
OutFile "mosquitto-${VERSION}-install-windows-x86.exe"
InstallDir "$PROGRAMFILES\mosquitto"
@@ -18,8 +18,7 @@ InstallDir "$PROGRAMFILES\mosquitto"
; Installer pages
!insertmacro MUI_PAGE_WELCOME
Page custom DependencyPage
!insertmacro MUI_PAGE_COMPONENTS
;!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
@@ -55,8 +54,8 @@ Section "Files" SecInstall
File "..\readme.md"
File "..\readme-windows.txt"
;File "C:\pthreads\Pre-built.2\dll\x86\pthreadVC2.dll"
;File "C:\OpenSSL-Win32\bin\libssl_1-1.dll"
;File "C:\OpenSSL-Win32\bin\libcrypto_1-1.dll"
File "C:\OpenSSL-Win32\bin\libssl-1_1.dll"
File "C:\OpenSSL-Win32\bin\libcrypto-1_1.dll"
File "..\edl-v10"
File "..\epl-v10"
@@ -96,8 +95,8 @@ Section "Uninstall"
Delete "$INSTDIR\readme.txt"
Delete "$INSTDIR\readme-windows.txt"
;Delete "$INSTDIR\pthreadVC2.dll"
;Delete "$INSTDIR\libssl_1-1.dll"
;Delete "$INSTDIR\libcrypto_1-1.dll"
Delete "$INSTDIR\libssl-1_1.dll"
Delete "$INSTDIR\libcrypto-1_1.dll"
Delete "$INSTDIR\edl-v10"
Delete "$INSTDIR\epl-v10"
@@ -120,28 +119,3 @@ LangString DESC_SecInstall ${LANG_ENGLISH} "The main installation."
!insertmacro MUI_DESCRIPTION_TEXT ${SecInstall} $(DESC_SecInstall)
!insertmacro MUI_FUNCTION_DESCRIPTION_END
Var Dialog
Var OSSLLink
Var PTHLink
Function DependencyPage
nsDialogs::Create 1018
Pop $Dialog
${If} $Dialog == error
Abort
${EndIf}
${NSD_CreateLabel} 0 0 100% 12u "OpenSSL - install 'Win32 OpenSSL v1.1.0* Light' then copy libssl_1-1.dll and libcrypto_1-1.dll to the mosquitto directory"
${NSD_CreateLink} 13u 13u 100% 12u "http://slproweb.com/products/Win32OpenSSL.html"
Pop $OSSLLink
${NSD_OnClick} $OSSLLink OnClick_OSSL
!insertmacro MUI_HEADER_TEXT_PAGE "Dependencies" "This page lists packages that must be installed if not already present"
nsDialogs::Show
FunctionEnd
Function OnClick_OSSL
Pop $0
ExecShell "open" "http://slproweb.com/products/Win32OpenSSL.html"
FunctionEnd
+6 -32
View File
@@ -9,7 +9,7 @@
!define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
Name "Eclipse Mosquitto"
!define VERSION 1.5.4
!define VERSION 1.5.90
OutFile "mosquitto-${VERSION}-install-windows-x64.exe"
!include "x64.nsh"
@@ -19,8 +19,7 @@ InstallDir "$PROGRAMFILES64\mosquitto"
; Installer pages
!insertmacro MUI_PAGE_WELCOME
Page custom DependencyPage
!insertmacro MUI_PAGE_COMPONENTS
;!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
@@ -56,8 +55,8 @@ Section "Files" SecInstall
File "..\readme.md"
File "..\readme-windows.txt"
;File "C:\pthreads\Pre-built.2\dll\x64\pthreadVC2.dll"
;File "C:\OpenSSL-Win64\bin\libssl_1-1-x64.dll"
;File "C:\OpenSSL-Win64\bin\libcrypto_1-1-x64.dll"
File "C:\OpenSSL-Win64\bin\libssl-1_1-x64.dll"
File "C:\OpenSSL-Win64\bin\libcrypto-1_1-x64.dll"
File "..\edl-v10"
File "..\epl-v10"
@@ -97,8 +96,8 @@ Section "Uninstall"
Delete "$INSTDIR\readme.txt"
Delete "$INSTDIR\readme-windows.txt"
;Delete "$INSTDIR\pthreadVC2.dll"
;Delete "$INSTDIR\libssl_1-1-x64.dll"
;Delete "$INSTDIR\libcrypto_1-1-x64.dll"
Delete "$INSTDIR\libssl-1_1-x64.dll"
Delete "$INSTDIR\libcrypto-1_1-x64.dll"
Delete "$INSTDIR\edl-v10"
Delete "$INSTDIR\epl-v10"
@@ -121,28 +120,3 @@ LangString DESC_SecInstall ${LANG_ENGLISH} "The main installation."
!insertmacro MUI_DESCRIPTION_TEXT ${SecInstall} $(DESC_SecInstall)
!insertmacro MUI_FUNCTION_DESCRIPTION_END
Var Dialog
Var OSSLLink
Var PTHLink
Function DependencyPage
nsDialogs::Create 1018
Pop $Dialog
${If} $Dialog == error
Abort
${EndIf}
${NSD_CreateLabel} 0 0 100% 12u "OpenSSL - install 'Win64 OpenSSL v1.1.0* Light' then copy libssl_1-1-x64.dll and libcrypto_1-1-x64.dll to the mosquitto directory"
${NSD_CreateLink} 13u 13u 100% 12u "http://slproweb.com/products/Win32OpenSSL.html"
Pop $OSSLLink
${NSD_OnClick} $OSSLLink OnClick_OSSL
!insertmacro MUI_HEADER_TEXT_PAGE "Dependencies" "This page lists packages that must be installed if not already present"
nsDialogs::Show
FunctionEnd
Function OnClick_OSSL
Pop $0
ExecShell "open" "http://slproweb.com/products/Win32OpenSSL.html"
FunctionEnd
+11 -8
View File
@@ -11,7 +11,9 @@ set(C_SRC
actions.c
callbacks.c
connect.c
handle_auth.c
handle_connack.c
handle_disconnect.c
handle_ping.c
handle_pubackcomp.c
handle_publish.c
@@ -26,9 +28,10 @@ set(C_SRC
messages_mosq.c messages_mosq.h
mosquitto.c mosquitto.h
mosquitto_internal.h
mqtt3_protocol.h
mqtt_protocol.h
net_mosq.c net_mosq.h
options.c
packet_datatypes.c
packet_mosq.c packet_mosq.h
read_handle.c read_handle.h
send_connect.c
@@ -44,7 +47,7 @@ set(C_SRC
time_mosq.c
tls_mosq.c
utf8_mosq.c
util_mosq.c util_mosq.h
util_mosq.c util_topic.c util_mosq.h
will_mosq.c will_mosq.h)
set (LIBRARIES ${OPENSSL_LIBRARIES} ${PTHREAD_LIBRARIES})
@@ -60,7 +63,7 @@ if (WIN32)
set (LIBRARIES ${LIBRARIES} ws2_32)
endif (WIN32)
if (${WITH_SRV} STREQUAL ON)
if (WITH_SRV)
# Simple detect c-ares
find_path(ARES_HEADER ares.h)
if (ARES_HEADER)
@@ -69,7 +72,7 @@ if (${WITH_SRV} STREQUAL ON)
else (ARES_HEADER)
message(WARNING "c-ares library not found.")
endif (ARES_HEADER)
endif (${WITH_SRV} STREQUAL ON)
endif (WITH_SRV)
add_library(libmosquitto SHARED ${C_SRC})
set_target_properties(libmosquitto PROPERTIES
@@ -86,13 +89,13 @@ set_target_properties(libmosquitto PROPERTIES
install(TARGETS libmosquitto RUNTIME DESTINATION "${BINDIR}" LIBRARY DESTINATION "${LIBDIR}")
if (${WITH_STATIC_LIBRARIES} STREQUAL ON)
if (WITH_STATIC_LIBRARIES)
add_library(libmosquitto_static STATIC ${C_SRC})
if (${WITH_PIC} STREQUAL ON)
if (WITH_PIC)
set_target_properties(libmosquitto_static PROPERTIES
POSITION_INDEPENDENT_CODE 1
)
endif (${WITH_PIC} STREQUAL ON)
endif (WITH_PIC)
target_link_libraries(libmosquitto_static ${LIBRARIES})
@@ -103,7 +106,7 @@ if (${WITH_STATIC_LIBRARIES} STREQUAL ON)
target_compile_definitions(libmosquitto_static PUBLIC "LIBMOSQUITTO_STATIC")
install(TARGETS libmosquitto_static RUNTIME DESTINATION "${BINDIR}" ARCHIVE DESTINATION "${LIBDIR}")
endif (${WITH_STATIC_LIBRARIES} STREQUAL ON)
endif (WITH_STATIC_LIBRARIES)
install(FILES mosquitto.h DESTINATION "${INCLUDEDIR}")
+21 -1
View File
@@ -6,7 +6,9 @@ MOSQ_OBJS=mosquitto.o \
actions.o \
callbacks.o \
connect.o \
handle_auth.o \
handle_connack.o \
handle_disconnect.o \
handle_ping.o \
handle_pubackcomp.o \
handle_publish.o \
@@ -21,7 +23,9 @@ MOSQ_OBJS=mosquitto.o \
messages_mosq.o \
net_mosq.o \
options.o \
packet_datatypes.o \
packet_mosq.o \
property_mosq.o \
read_handle.o \
send_connect.o \
send_disconnect.o \
@@ -36,6 +40,7 @@ MOSQ_OBJS=mosquitto.o \
tls_mosq.o \
utf8_mosq.o \
util_mosq.o \
util_topic.o \
will_mosq.o
ALL_DEPS:=
@@ -80,7 +85,7 @@ uninstall :
reallyclean : clean
clean :
-rm -f *.o libmosquitto.so.${SOVERSION} libmosquitto.so libmosquitto.a
-rm -f *.o libmosquitto.so.${SOVERSION} libmosquitto.so libmosquitto.a *.gcno *.gcda
$(MAKE) -C cpp clean
libmosquitto.so.${SOVERSION} : ${MOSQ_OBJS}
@@ -101,9 +106,15 @@ callbacks.o : callbacks.c mosquitto.h mosquitto_internal.h
connect.o : connect.c mosquitto.h mosquitto_internal.h
${CROSS_COMPILE}$(CC) $(LIB_CFLAGS) -c $< -o $@
handle_auth.o : handle_auth.c read_handle.h
${CROSS_COMPILE}$(CC) $(LIB_CFLAGS) -c $< -o $@
handle_connack.o : handle_connack.c read_handle.h
${CROSS_COMPILE}$(CC) $(LIB_CFLAGS) -c $< -o $@
handle_disconnect.o : handle_disconnect.c read_handle.h
${CROSS_COMPILE}$(CC) $(LIB_CFLAGS) -c $< -o $@
handle_publish.o : handle_publish.c read_handle.h
${CROSS_COMPILE}$(CC) $(LIB_CFLAGS) -c $< -o $@
@@ -146,9 +157,15 @@ net_mosq.o : net_mosq.c net_mosq.h
options.o : options.c mosquitto.h mosquitto_internal.h
${CROSS_COMPILE}$(CC) $(LIB_CFLAGS) -c $< -o $@
packet_datatypes.o : packet_datatypes.c packet_mosq.h
${CROSS_COMPILE}$(CC) $(LIB_CFLAGS) -c $< -o $@
packet_mosq.o : packet_mosq.c packet_mosq.h
${CROSS_COMPILE}$(CC) $(LIB_CFLAGS) -c $< -o $@
property_mosq.o : property_mosq.c property_mosq.h
${CROSS_COMPILE}$(CC) $(LIB_CFLAGS) -c $< -o $@
read_handle.o : read_handle.c read_handle.h
${CROSS_COMPILE}$(CC) $(LIB_CFLAGS) -c $< -o $@
@@ -191,6 +208,9 @@ utf8_mosq.o : utf8_mosq.c
util_mosq.o : util_mosq.c util_mosq.h
${CROSS_COMPILE}$(CC) $(LIB_CFLAGS) -c $< -o $@
util_topic.o : util_topic.c util_mosq.h
${CROSS_COMPILE}$(CC) $(LIB_CFLAGS) -c $< -o $@
will_mosq.o : will_mosq.c will_mosq.h
${CROSS_COMPILE}$(CC) $(LIB_CFLAGS) -c $< -o $@
+162 -30
View File
@@ -22,25 +22,84 @@ Contributors:
#include "mosquitto_internal.h"
#include "memory_mosq.h"
#include "messages_mosq.h"
#include "mqtt3_protocol.h"
#include "mqtt_protocol.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "send_mosq.h"
#include "util_mosq.h"
int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain)
{
return mosquitto_publish_v5(mosq, mid, topic, payloadlen, payload, qos, retain, NULL);
}
int mosquitto_publish_v5(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain, const mosquitto_property *properties)
{
struct mosquitto_message_all *message;
uint16_t local_mid;
int queue_status;
const mosquitto_property *p;
const mosquitto_property *outgoing_properties = NULL;
mosquitto_property local_property;
bool have_topic_alias;
int rc;
int tlen = 0;
uint32_t remaining_length;
if(!mosq || !topic || qos<0 || qos>2) return MOSQ_ERR_INVAL;
if(STREMPTY(topic)) return MOSQ_ERR_INVAL;
if(mosquitto_validate_utf8(topic, strlen(topic))) return MOSQ_ERR_MALFORMED_UTF8;
if(payloadlen < 0 || payloadlen > MQTT_MAX_PAYLOAD) return MOSQ_ERR_PAYLOAD_SIZE;
if(!mosq || qos<0 || qos>2) return MOSQ_ERR_INVAL;
if(mosq->protocol != mosq_p_mqtt5 && properties) return MOSQ_ERR_NOT_SUPPORTED;
if(qos > mosq->maximum_qos) return MOSQ_ERR_QOS_NOT_SUPPORTED;
if(mosquitto_pub_topic_check(topic) != MOSQ_ERR_SUCCESS){
return MOSQ_ERR_INVAL;
if(properties){
if(properties->client_generated){
outgoing_properties = properties;
}else{
memcpy(&local_property, properties, sizeof(mosquitto_property));
local_property.client_generated = true;
local_property.next = NULL;
outgoing_properties = &local_property;
}
rc = mosquitto_property_check_all(CMD_PUBLISH, outgoing_properties);
if(rc) return rc;
}
if(!topic || STREMPTY(topic)){
if(topic) topic = NULL;
if(mosq->protocol == mosq_p_mqtt5){
p = outgoing_properties;
have_topic_alias = false;
while(p){
if(p->identifier == MQTT_PROP_TOPIC_ALIAS){
have_topic_alias = true;
break;
}
p = p->next;
}
if(have_topic_alias == false){
return MOSQ_ERR_INVAL;
}
}else{
return MOSQ_ERR_INVAL;
}
}else{
tlen = strlen(topic);
if(mosquitto_validate_utf8(topic, tlen)) return MOSQ_ERR_MALFORMED_UTF8;
if(payloadlen < 0 || payloadlen > MQTT_MAX_PAYLOAD) return MOSQ_ERR_PAYLOAD_SIZE;
if(mosquitto_pub_topic_check(topic) != MOSQ_ERR_SUCCESS){
return MOSQ_ERR_INVAL;
}
}
if(mosq->maximum_packet_size > 0){
remaining_length = 1 + 2+tlen + payloadlen + property__get_length_all(outgoing_properties);
if(qos > 0){
remaining_length++;
}
if(packet__check_oversize(mosq, remaining_length)){
return MOSQ_ERR_OVERSIZE_PACKET;
}
}
local_mid = mosquitto__mid_generate(mosq);
@@ -49,7 +108,7 @@ int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int p
}
if(qos == 0){
return send__publish(mosq, local_mid, topic, payloadlen, payload, qos, retain, false);
return send__publish(mosq, local_mid, topic, payloadlen, payload, qos, retain, false, outgoing_properties, NULL, 0);
}else{
message = mosquitto__calloc(1, sizeof(struct mosquitto_message_all));
if(!message) return MOSQ_ERR_NOMEM;
@@ -57,10 +116,12 @@ int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int p
message->next = NULL;
message->timestamp = mosquitto_time();
message->msg.mid = local_mid;
message->msg.topic = mosquitto__strdup(topic);
if(!message->msg.topic){
message__cleanup(&message);
return MOSQ_ERR_NOMEM;
if(topic){
message->msg.topic = mosquitto__strdup(topic);
if(!message->msg.topic){
message__cleanup(&message);
return MOSQ_ERR_NOMEM;
}
}
if(payloadlen){
message->msg.payloadlen = payloadlen;
@@ -87,7 +148,7 @@ int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int p
message->state = mosq_ms_wait_for_pubrec;
}
pthread_mutex_unlock(&mosq->out_message_mutex);
return send__publish(mosq, message->msg.mid, message->msg.topic, message->msg.payloadlen, message->msg.payload, message->msg.qos, message->msg.retain, message->dup);
return send__publish(mosq, message->msg.mid, message->msg.topic, message->msg.payloadlen, message->msg.payload, message->msg.qos, message->msg.retain, message->dup, outgoing_properties, NULL, 0);
}else{
message->state = mosq_ms_invalid;
pthread_mutex_unlock(&mosq->out_message_mutex);
@@ -99,41 +160,112 @@ int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int p
int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos)
{
if(!mosq) return MOSQ_ERR_INVAL;
if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
if(mosquitto_sub_topic_check(sub)) return MOSQ_ERR_INVAL;
if(mosquitto_validate_utf8(sub, strlen(sub))) return MOSQ_ERR_MALFORMED_UTF8;
return send__subscribe(mosq, mid, 1, (char *const *const)&sub, qos);
return mosquitto_subscribe_multiple(mosq, mid, 1, (char *const *const)&sub, qos, 0, NULL);
}
int mosquitto_subscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, int qos)
int mosquitto_subscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, int qos, int options, const mosquitto_property *properties)
{
return mosquitto_subscribe_multiple(mosq, mid, 1, (char *const *const)&sub, qos, options, properties);
}
int mosquitto_subscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, int qos, int options, const mosquitto_property *properties)
{
const mosquitto_property *outgoing_properties = NULL;
mosquitto_property local_property;
int i;
int rc;
uint32_t remaining_length = 0;
int slen;
if(!mosq || !sub_count || !sub) return MOSQ_ERR_INVAL;
if(mosq->protocol != mosq_p_mqtt5 && properties) return MOSQ_ERR_NOT_SUPPORTED;
if(qos < 0 || qos > 2) return MOSQ_ERR_INVAL;
if((options & 0x30) == 0x30 || (options & 0xC0) != 0) return MOSQ_ERR_INVAL;
if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
if(properties){
if(properties->client_generated){
outgoing_properties = properties;
}else{
memcpy(&local_property, properties, sizeof(mosquitto_property));
local_property.client_generated = true;
local_property.next = NULL;
outgoing_properties = &local_property;
}
rc = mosquitto_property_check_all(CMD_SUBSCRIBE, outgoing_properties);
if(rc) return rc;
}
for(i=0; i<sub_count; i++){
if(mosquitto_sub_topic_check(sub[i])) return MOSQ_ERR_INVAL;
if(mosquitto_validate_utf8(sub[i], strlen(sub[i]))) return MOSQ_ERR_MALFORMED_UTF8;
slen = strlen(sub[i]);
if(mosquitto_validate_utf8(sub[i], slen)) return MOSQ_ERR_MALFORMED_UTF8;
remaining_length += 2+slen + 1;
}
return send__subscribe(mosq, mid, sub_count, sub, qos);
if(mosq->maximum_packet_size > 0){
remaining_length += 2 + property__get_length_all(outgoing_properties);
if(packet__check_oversize(mosq, remaining_length)){
return MOSQ_ERR_OVERSIZE_PACKET;
}
}
return send__subscribe(mosq, mid, sub_count, sub, qos|options, outgoing_properties);
}
int mosquitto_unsubscribe(struct mosquitto *mosq, int *mid, const char *sub)
{
if(!mosq) return MOSQ_ERR_INVAL;
if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
if(mosquitto_sub_topic_check(sub)) return MOSQ_ERR_INVAL;
if(mosquitto_validate_utf8(sub, strlen(sub))) return MOSQ_ERR_MALFORMED_UTF8;
return send__unsubscribe(mosq, mid, sub);
return mosquitto_unsubscribe_multiple(mosq, mid, 1, (char *const *const)&sub, NULL);
}
int mosquitto_unsubscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, const mosquitto_property *properties)
{
return mosquitto_unsubscribe_multiple(mosq, mid, 1, (char *const *const)&sub, properties);
}
int mosquitto_unsubscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, const mosquitto_property *properties)
{
const mosquitto_property *outgoing_properties = NULL;
mosquitto_property local_property;
int rc;
int i;
uint32_t remaining_length = 0;
int slen;
if(!mosq) return MOSQ_ERR_INVAL;
if(mosq->protocol != mosq_p_mqtt5 && properties) return MOSQ_ERR_NOT_SUPPORTED;
if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
if(properties){
if(properties->client_generated){
outgoing_properties = properties;
}else{
memcpy(&local_property, properties, sizeof(mosquitto_property));
local_property.client_generated = true;
local_property.next = NULL;
outgoing_properties = &local_property;
}
rc = mosquitto_property_check_all(CMD_UNSUBSCRIBE, outgoing_properties);
if(rc) return rc;
}
for(i=0; i<sub_count; i++){
if(mosquitto_sub_topic_check(sub[i])) return MOSQ_ERR_INVAL;
slen = strlen(sub[i]);
if(mosquitto_validate_utf8(sub[i], slen)) return MOSQ_ERR_MALFORMED_UTF8;
remaining_length += 2+slen;
}
if(mosq->maximum_packet_size > 0){
remaining_length += 2 + property__get_length_all(outgoing_properties);
if(packet__check_oversize(mosq, remaining_length)){
return MOSQ_ERR_OVERSIZE_PACKET;
}
}
return send__unsubscribe(mosq, mid, sub_count, sub, outgoing_properties);
}
+85
View File
@@ -0,0 +1,85 @@
/*
Copyright (c) 2019 Roger Light <roger@atchoo.org>
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
and Eclipse Distribution License v1.0 which accompany this distribution.
The Eclipse Public License is available at
http://www.eclipse.org/legal/epl-v10.html
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
Contributors:
Roger Light - initial implementation and documentation.
*/
#include "config.h"
#include "mosquitto.h"
#include "alias_mosq.h"
#include "memory_mosq.h"
int alias__add(struct mosquitto *mosq, const char *topic, int alias)
{
int i;
struct mosquitto__alias *aliases;
for(i=0; i<mosq->alias_count; i++){
if(mosq->aliases[i].alias == alias){
mosquitto__free(mosq->aliases[i].topic);
mosq->aliases[i].topic = mosquitto__strdup(topic);
if(mosq->aliases[i].topic){
return MOSQ_ERR_SUCCESS;
}else{
return MOSQ_ERR_NOMEM;
}
}
}
/* New alias */
aliases = mosquitto__realloc(mosq->aliases, sizeof(struct mosquitto__alias)*(mosq->alias_count+1));
if(!aliases) return MOSQ_ERR_NOMEM;
mosq->aliases = aliases;
mosq->aliases[mosq->alias_count].alias = alias;
mosq->aliases[mosq->alias_count].topic = mosquitto__strdup(topic);
if(!mosq->aliases[mosq->alias_count].topic){
return MOSQ_ERR_NOMEM;
}
mosq->alias_count++;
return MOSQ_ERR_SUCCESS;
}
int alias__find(struct mosquitto *mosq, char **topic, int alias)
{
int i;
for(i=0; i<mosq->alias_count; i++){
if(mosq->aliases[i].alias == alias){
*topic = mosquitto__strdup(mosq->aliases[i].topic);
if(*topic){
return MOSQ_ERR_SUCCESS;
}else{
return MOSQ_ERR_NOMEM;
}
}
}
return MOSQ_ERR_INVAL;
}
void alias__free_all(struct mosquitto *mosq)
{
int i;
for(i=0; i<mosq->alias_count; i++){
mosquitto__free(mosq->aliases[i].topic);
}
mosquitto__free(mosq->aliases);
mosq->aliases = NULL;
mosq->alias_count = 0;
}
+26
View File
@@ -0,0 +1,26 @@
/*
Copyright (c) 2019 Roger Light <roger@atchoo.org>
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
and Eclipse Distribution License v1.0 which accompany this distribution.
The Eclipse Public License is available at
http://www.eclipse.org/legal/epl-v10.html
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
Contributors:
Roger Light - initial implementation and documentation.
*/
#ifndef ALIAS_MOSQ_H
#define ALIAS_MOSQ_H
#include "mosquitto_internal.h"
int alias__add(struct mosquitto *mosq, const char *topic, int alias);
int alias__find(struct mosquitto *mosq, char **topic, int alias);
void alias__free_all(struct mosquitto *mosq);
#endif
+42
View File
@@ -34,6 +34,13 @@ void mosquitto_connect_with_flags_callback_set(struct mosquitto *mosq, void (*on
pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_connect_v5_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int, const mosquitto_property *))
{
pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_connect_v5 = on_connect;
pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_disconnect_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int))
{
pthread_mutex_lock(&mosq->callback_mutex);
@@ -41,6 +48,13 @@ void mosquitto_disconnect_callback_set(struct mosquitto *mosq, void (*on_disconn
pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_disconnect_v5_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int, const mosquitto_property *))
{
pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_disconnect_v5 = on_disconnect;
pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_publish_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int))
{
pthread_mutex_lock(&mosq->callback_mutex);
@@ -48,6 +62,13 @@ void mosquitto_publish_callback_set(struct mosquitto *mosq, void (*on_publish)(s
pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_publish_v5_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int, int, const mosquitto_property *props))
{
pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_publish_v5 = on_publish;
pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_message_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *))
{
pthread_mutex_lock(&mosq->callback_mutex);
@@ -55,6 +76,13 @@ void mosquitto_message_callback_set(struct mosquitto *mosq, void (*on_message)(s
pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_message_v5_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *, const mosquitto_property *props))
{
pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_message_v5 = on_message;
pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_subscribe_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *))
{
pthread_mutex_lock(&mosq->callback_mutex);
@@ -62,6 +90,13 @@ void mosquitto_subscribe_callback_set(struct mosquitto *mosq, void (*on_subscrib
pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_subscribe_v5_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *, const mosquitto_property *props))
{
pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_subscribe_v5 = on_subscribe;
pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_unsubscribe_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int))
{
pthread_mutex_lock(&mosq->callback_mutex);
@@ -69,6 +104,13 @@ void mosquitto_unsubscribe_callback_set(struct mosquitto *mosq, void (*on_unsubs
pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_unsubscribe_v5_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int, const mosquitto_property *props))
{
pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_unsubscribe_v5 = on_unsubscribe;
pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_log_callback_set(struct mosquitto *mosq, void (*on_log)(struct mosquitto *, void *, int, const char *))
{
pthread_mutex_lock(&mosq->log_callback_mutex);
+120 -9
View File
@@ -16,25 +16,46 @@ Contributors:
#include "config.h"
#include <string.h>
#include "mosquitto.h"
#include "mosquitto_internal.h"
#include "logging_mosq.h"
#include "messages_mosq.h"
#include "memory_mosq.h"
#include "packet_mosq.h"
#include "mqtt_protocol.h"
#include "net_mosq.h"
#include "send_mosq.h"
#include "socks_mosq.h"
static int mosquitto__reconnect(struct mosquitto *mosq, bool blocking);
static int mosquitto__reconnect(struct mosquitto *mosq, bool blocking, const mosquitto_property *properties);
static int mosquitto__connect_init(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address);
static int mosquitto__connect_init(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address)
{
int i;
if(!mosq) return MOSQ_ERR_INVAL;
if(!host || port <= 0) return MOSQ_ERR_INVAL;
if(mosq->id == NULL && (mosq->protocol == mosq_p_mqtt31 || mosq->protocol == mosq_p_mqtt311)){
mosq->id = (char *)mosquitto__calloc(24, sizeof(char));
if(!mosq->id){
return MOSQ_ERR_NOMEM;
}
mosq->id[0] = 'm';
mosq->id[1] = 'o';
mosq->id[2] = 's';
mosq->id[3] = 'q';
mosq->id[4] = '/';
for(i=5; i<23; i++){
mosq->id[i] = (random()%73)+48;
}
}
mosquitto__free(mosq->host);
mosq->host = mosquitto__strdup(host);
if(!mosq->host) return MOSQ_ERR_NOMEM;
@@ -47,6 +68,8 @@ static int mosquitto__connect_init(struct mosquitto *mosq, const char *host, int
}
mosq->keepalive = keepalive;
mosq->receive_quota = mosq->receive_maximum;
mosq->send_quota = mosq->send_maximum;
if(mosq->sockpairR != INVALID_SOCKET){
COMPAT_CLOSE(mosq->sockpairR);
@@ -73,8 +96,19 @@ int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int ke
int mosquitto_connect_bind(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address)
{
return mosquitto_connect_bind_v5(mosq, host, port, keepalive, bind_address, NULL);
}
int mosquitto_connect_bind_v5(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address, const mosquitto_property *properties)
{
int rc;
if(properties){
rc = mosquitto_property_check_all(CMD_CONNECT, properties);
if(rc) return rc;
}
rc = mosquitto__connect_init(mosq, host, port, keepalive, bind_address);
if(rc) return rc;
@@ -82,7 +116,7 @@ int mosquitto_connect_bind(struct mosquitto *mosq, const char *host, int port, i
mosq->state = mosq_cs_new;
pthread_mutex_unlock(&mosq->state_mutex);
return mosquitto__reconnect(mosq, true);
return mosquitto__reconnect(mosq, true, properties);
}
@@ -101,28 +135,44 @@ int mosquitto_connect_bind_async(struct mosquitto *mosq, const char *host, int p
mosq->state = mosq_cs_connect_async;
pthread_mutex_unlock(&mosq->state_mutex);
return mosquitto__reconnect(mosq, false);
return mosquitto__reconnect(mosq, false, NULL);
}
int mosquitto_reconnect_async(struct mosquitto *mosq)
{
return mosquitto__reconnect(mosq, false);
return mosquitto__reconnect(mosq, false, NULL);
}
int mosquitto_reconnect(struct mosquitto *mosq)
{
return mosquitto__reconnect(mosq, true);
return mosquitto__reconnect(mosq, true, NULL);
}
static int mosquitto__reconnect(struct mosquitto *mosq, bool blocking)
static int mosquitto__reconnect(struct mosquitto *mosq, bool blocking, const mosquitto_property *properties)
{
const mosquitto_property *outgoing_properties = NULL;
mosquitto_property local_property;
int rc;
struct mosquitto__packet *packet;
if(!mosq) return MOSQ_ERR_INVAL;
if(!mosq->host || mosq->port <= 0) return MOSQ_ERR_INVAL;
if(mosq->protocol != mosq_p_mqtt5 && properties) return MOSQ_ERR_NOT_SUPPORTED;
if(properties){
if(properties->client_generated){
outgoing_properties = properties;
}else{
memcpy(&local_property, properties, sizeof(mosquitto_property));
local_property.client_generated = true;
local_property.next = NULL;
outgoing_properties = &local_property;
}
rc = mosquitto_property_check_all(CMD_CONNECT, outgoing_properties);
if(rc) return rc;
}
pthread_mutex_lock(&mosq->state_mutex);
#ifdef WITH_SOCKS
@@ -143,7 +193,7 @@ static int mosquitto__reconnect(struct mosquitto *mosq, bool blocking)
mosq->ping_t = 0;
packet__cleanup(&mosq->in_packet);
pthread_mutex_lock(&mosq->current_out_packet_mutex);
pthread_mutex_lock(&mosq->out_packet_mutex);
@@ -193,20 +243,81 @@ static int mosquitto__reconnect(struct mosquitto *mosq, bool blocking)
}else
#endif
{
return send__connect(mosq, mosq->keepalive, mosq->clean_session);
return send__connect(mosq, mosq->keepalive, mosq->clean_start, outgoing_properties);
}
}
int mosquitto_disconnect(struct mosquitto *mosq)
{
return mosquitto_disconnect_v5(mosq, 0, NULL);
}
int mosquitto_disconnect_v5(struct mosquitto *mosq, int reason_code, const mosquitto_property *properties)
{
const mosquitto_property *outgoing_properties = NULL;
mosquitto_property local_property;
int rc;
if(!mosq) return MOSQ_ERR_INVAL;
if(mosq->protocol != mosq_p_mqtt5 && properties) return MOSQ_ERR_NOT_SUPPORTED;
if(properties){
if(properties->client_generated){
outgoing_properties = properties;
}else{
memcpy(&local_property, properties, sizeof(mosquitto_property));
local_property.client_generated = true;
local_property.next = NULL;
outgoing_properties = &local_property;
}
rc = mosquitto_property_check_all(CMD_DISCONNECT, outgoing_properties);
if(rc) return rc;
}
pthread_mutex_lock(&mosq->state_mutex);
mosq->state = mosq_cs_disconnecting;
pthread_mutex_unlock(&mosq->state_mutex);
if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
return send__disconnect(mosq);
return send__disconnect(mosq, reason_code, outgoing_properties);
}
void do_client_disconnect(struct mosquitto *mosq, int reason_code, const mosquitto_property *properties)
{
pthread_mutex_lock(&mosq->state_mutex);
mosq->state = mosq_cs_disconnecting;
pthread_mutex_unlock(&mosq->state_mutex);
net__socket_close(mosq);
/* Free data and reset values */
pthread_mutex_lock(&mosq->out_packet_mutex);
mosq->current_out_packet = mosq->out_packet;
if(mosq->out_packet){
mosq->out_packet = mosq->out_packet->next;
if(!mosq->out_packet){
mosq->out_packet_last = NULL;
}
}
pthread_mutex_unlock(&mosq->out_packet_mutex);
pthread_mutex_lock(&mosq->msgtime_mutex);
mosq->next_msg_out = mosquitto_time() + mosq->keepalive;
pthread_mutex_unlock(&mosq->msgtime_mutex);
pthread_mutex_lock(&mosq->callback_mutex);
if(mosq->on_disconnect){
mosq->in_callback = true;
mosq->on_disconnect(mosq, mosq->userdata, reason_code);
mosq->in_callback = false;
}
if(mosq->on_disconnect_v5){
mosq->in_callback = true;
mosq->on_disconnect_v5(mosq, mosq->userdata, reason_code, properties);
mosq->in_callback = false;
}
pthread_mutex_unlock(&mosq->callback_mutex);
pthread_mutex_unlock(&mosq->current_out_packet_mutex);
}
+4 -4
View File
@@ -15,16 +15,16 @@ set_target_properties(mosquittopp PROPERTIES
)
install(TARGETS mosquittopp RUNTIME DESTINATION "${BINDIR}" LIBRARY DESTINATION "${LIBDIR}")
if (${WITH_STATIC_LIBRARIES} STREQUAL ON)
if (WITH_STATIC_LIBRARIES)
add_library(mosquittopp_static STATIC
${C_SRC}
${CPP_SRC}
)
if (${WITH_PIC} STREQUAL ON)
if (WITH_PIC)
set_target_properties(mosquittopp_static PROPERTIES
POSITION_INDEPENDENT_CODE 1
)
endif (${WITH_PIC} STREQUAL ON)
endif (WITH_PIC)
target_link_libraries(mosquittopp_static ${LIBRARIES})
@@ -35,7 +35,7 @@ if (${WITH_STATIC_LIBRARIES} STREQUAL ON)
target_compile_definitions(mosquittopp_static PUBLIC "LIBMOSQUITTO_STATIC")
install(TARGETS mosquittopp_static RUNTIME DESTINATION "${BINDIR}" ARCHIVE DESTINATION "${LIBDIR}")
endif (${WITH_STATIC_LIBRARIES} STREQUAL ON)
endif (WITH_STATIC_LIBRARIES)
install(FILES mosquittopp.h DESTINATION "${INCLUDEDIR}")
+49
View File
@@ -0,0 +1,49 @@
/*
Copyright (c) 2018 Roger Light <roger@atchoo.org>
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
and Eclipse Distribution License v1.0 which accompany this distribution.
The Eclipse Public License is available at
http://www.eclipse.org/legal/epl-v10.html
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
Contributors:
Roger Light - initial implementation and documentation.
*/
#include "config.h"
#include <stdio.h>
#include <string.h>
#include "logging_mosq.h"
#include "mosquitto_internal.h"
#include "mqtt_protocol.h"
#include "packet_mosq.h"
#include "property_mosq.h"
int handle__auth(struct mosquitto *mosq)
{
int rc = 0;
uint8_t reason_code;
mosquitto_property *properties = NULL;
if(!mosq) return MOSQ_ERR_INVAL;
log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s received AUTH", mosq->id);
if(mosq->protocol != mosq_p_mqtt5){
return MOSQ_ERR_PROTOCOL;
}
if(packet__read_byte(&mosq->in_packet, &reason_code)) return 1;
rc = property__read_all(CMD_AUTH, &mosq->in_packet, &properties);
if(rc) return rc;
mosquitto_property_free_all(&properties); /* FIXME - TEMPORARY UNTIL PROPERTIES PROCESSED */
return MOSQ_ERR_SUCCESS;
}
+44 -6
View File
@@ -22,35 +22,73 @@ Contributors:
#include "logging_mosq.h"
#include "memory_mosq.h"
#include "messages_mosq.h"
#include "mqtt_protocol.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "property_mosq.h"
#include "read_handle.h"
int handle__connack(struct mosquitto *mosq)
{
uint8_t connect_flags;
uint8_t result;
uint8_t reason_code;
int rc;
mosquitto_property *properties = NULL;
char *clientid = NULL;
assert(mosq);
rc = packet__read_byte(&mosq->in_packet, &connect_flags);
if(rc) return rc;
rc = packet__read_byte(&mosq->in_packet, &result);
rc = packet__read_byte(&mosq->in_packet, &reason_code);
if(rc) return rc;
log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s received CONNACK (%d)", mosq->id, result);
if(mosq->protocol == mosq_p_mqtt5){
rc = property__read_all(CMD_CONNACK, &mosq->in_packet, &properties);
if(rc) return rc;
}
mosquitto_property_read_string(properties, MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER, &clientid, false);
if(clientid){
if(mosq->id){
/* We've been sent a client identifier but already have one. This
* shouldn't happen. */
free(clientid);
mosquitto_property_free_all(&properties);
return MOSQ_ERR_PROTOCOL;
}else{
mosq->id = clientid;
clientid = NULL;
}
}
mosquitto_property_read_byte(properties, MQTT_PROP_MAXIMUM_QOS, &mosq->maximum_qos, false);
mosquitto_property_read_int16(properties, MQTT_PROP_RECEIVE_MAXIMUM, &mosq->send_maximum, false);
mosquitto_property_read_int16(properties, MQTT_PROP_SERVER_KEEP_ALIVE, &mosq->keepalive, false);
mosquitto_property_read_int32(properties, MQTT_PROP_MAXIMUM_PACKET_SIZE, &mosq->maximum_packet_size, false);
mosq->send_quota = mosq->send_maximum;
log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s received CONNACK (%d)", mosq->id, reason_code);
pthread_mutex_lock(&mosq->callback_mutex);
if(mosq->on_connect){
mosq->in_callback = true;
mosq->on_connect(mosq, mosq->userdata, result);
mosq->on_connect(mosq, mosq->userdata, reason_code);
mosq->in_callback = false;
}
if(mosq->on_connect_with_flags){
mosq->in_callback = true;
mosq->on_connect_with_flags(mosq, mosq->userdata, result, connect_flags);
mosq->on_connect_with_flags(mosq, mosq->userdata, reason_code, connect_flags);
mosq->in_callback = false;
}
if(mosq->on_connect_v5){
mosq->in_callback = true;
mosq->on_connect_v5(mosq, mosq->userdata, reason_code, connect_flags, properties);
mosq->in_callback = false;
}
pthread_mutex_unlock(&mosq->callback_mutex);
switch(result){
mosquitto_property_free_all(&properties);
switch(reason_code){
case 0:
if(mosq->state != mosq_cs_disconnecting){
mosq->state = mosq_cs_connected;
+62
View File
@@ -0,0 +1,62 @@
/*
Copyright (c) 2009-2018 Roger Light <roger@atchoo.org>
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
and Eclipse Distribution License v1.0 which accompany this distribution.
The Eclipse Public License is available at
http://www.eclipse.org/legal/epl-v10.html
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
Contributors:
Roger Light - initial implementation and documentation.
*/
#include "config.h"
#include <stdio.h>
#include <string.h>
#include "logging_mosq.h"
#include "mqtt_protocol.h"
#include "memory_mosq.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "property_mosq.h"
#include "send_mosq.h"
#include "util_mosq.h"
int handle__disconnect(struct mosquitto *mosq)
{
int rc;
uint8_t reason_code;
mosquitto_property *properties = NULL;
if(!mosq){
return MOSQ_ERR_INVAL;
}
if(mosq->protocol != mosq_p_mqtt5){
return MOSQ_ERR_PROTOCOL;
}
rc = packet__read_byte(&mosq->in_packet, &reason_code);
if(rc) return rc;
if(mosq->in_packet.remaining_length > 2){
rc = property__read_all(CMD_DISCONNECT, &mosq->in_packet, &properties);
if(rc) return rc;
mosquitto_property_free_all(&properties);
}
log__printf(mosq, MOSQ_LOG_DEBUG, "Received DISCONNECT (%d)", reason_code);
do_client_disconnect(mosq, reason_code, properties);
mosquitto_property_free_all(&properties);
return MOSQ_ERR_SUCCESS;
}
+1 -1
View File
@@ -28,7 +28,7 @@ Contributors:
#include "logging_mosq.h"
#include "memory_mosq.h"
#include "messages_mosq.h"
#include "mqtt3_protocol.h"
#include "mqtt_protocol.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "read_handle.h"
+31 -3
View File
@@ -28,7 +28,7 @@ Contributors:
#include "logging_mosq.h"
#include "memory_mosq.h"
#include "messages_mosq.h"
#include "mqtt3_protocol.h"
#include "mqtt_protocol.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "read_handle.h"
@@ -42,17 +42,36 @@ int handle__pubackcomp(struct mosquitto_db *db, struct mosquitto *mosq, const ch
int handle__pubackcomp(struct mosquitto *mosq, const char *type)
#endif
{
uint8_t reason_code = 0;
uint16_t mid;
int rc;
mosquitto_property *properties = NULL;
int qos;
assert(mosq);
rc = packet__read_uint16(&mosq->in_packet, &mid);
if(rc) return rc;
qos = type[3] == 'A'?1:2; /* pubAck or pubComp */
if(mid == 0) return MOSQ_ERR_PROTOCOL;
if(mosq->protocol == mosq_p_mqtt5 && mosq->in_packet.remaining_length > 2){
rc = packet__read_byte(&mosq->in_packet, &reason_code);
if(rc) return rc;
if(mosq->in_packet.remaining_length > 3){
rc = property__read_all(CMD_PUBACK, &mosq->in_packet, &properties);
if(rc) return rc;
}
}
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_DEBUG, "Received %s from %s (Mid: %d)", type, mosq->id, mid);
/* Immediately free, we don't do anything with Reason String or User Property at the moment */
mosquitto_property_free_all(&properties);
if(mid){
rc = db__message_delete(db, mosq, mid, mosq_md_out);
rc = db__message_delete(db, mosq, mid, mosq_md_out, mosq_ms_wait_for_pubcomp, qos);
if(rc == MOSQ_ERR_NOT_FOUND){
log__printf(mosq, MOSQ_LOG_WARNING, "Warning: Received %s from %s for an unknown packet identifier %d.", type, mosq->id, mid);
return MOSQ_ERR_SUCCESS;
@@ -63,7 +82,10 @@ int handle__pubackcomp(struct mosquitto *mosq, const char *type)
#else
log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s received %s (Mid: %d)", mosq->id, type, mid);
if(!message__delete(mosq, mid, mosq_md_out)){
rc = message__delete(mosq, mid, mosq_md_out, qos);
if(rc){
return rc;
}else{
/* Only inform the client the message has been sent once. */
pthread_mutex_lock(&mosq->callback_mutex);
if(mosq->on_publish){
@@ -71,7 +93,13 @@ int handle__pubackcomp(struct mosquitto *mosq, const char *type)
mosq->on_publish(mosq, mosq->userdata, mid);
mosq->in_callback = false;
}
if(mosq->on_publish_v5){
mosq->in_callback = true;
mosq->on_publish_v5(mosq, mosq->userdata, mid, reason_code, properties);
mosq->in_callback = false;
}
pthread_mutex_unlock(&mosq->callback_mutex);
mosquitto_property_free_all(&properties);
}
#endif
+37
View File
@@ -23,8 +23,10 @@ Contributors:
#include "mosquitto_internal.h"
#include "logging_mosq.h"
#include "memory_mosq.h"
#include "mqtt_protocol.h"
#include "messages_mosq.h"
#include "packet_mosq.h"
#include "property_mosq.h"
#include "send_mosq.h"
#include "time_mosq.h"
@@ -36,6 +38,7 @@ int handle__publish(struct mosquitto *mosq)
int rc = 0;
uint16_t mid;
int slen;
mosquitto_property *properties = NULL;
assert(mosq);
@@ -59,24 +62,44 @@ int handle__publish(struct mosquitto *mosq)
}
if(message->msg.qos > 0){
if(mosq->protocol == mosq_p_mqtt5){
if(mosq->receive_quota == 0){
message__cleanup(&message);
/* FIXME - should send a DISCONNECT here */
return MOSQ_ERR_PROTOCOL;
}
mosq->receive_quota--;
}
rc = packet__read_uint16(&mosq->in_packet, &mid);
if(rc){
message__cleanup(&message);
return rc;
}
if(mid == 0){
message__cleanup(&message);
return MOSQ_ERR_PROTOCOL;
}
message->msg.mid = (int)mid;
}
if(mosq->protocol == mosq_p_mqtt5){
rc = property__read_all(CMD_PUBLISH, &mosq->in_packet, &properties);
if(rc) return rc;
}
message->msg.payloadlen = mosq->in_packet.remaining_length - mosq->in_packet.pos;
if(message->msg.payloadlen){
message->msg.payload = mosquitto__calloc(message->msg.payloadlen+1, sizeof(uint8_t));
if(!message->msg.payload){
message__cleanup(&message);
mosquitto_property_free_all(&properties);
return MOSQ_ERR_NOMEM;
}
rc = packet__read_bytes(&mosq->in_packet, message->msg.payload, message->msg.payloadlen);
if(rc){
message__cleanup(&message);
mosquitto_property_free_all(&properties);
return rc;
}
}
@@ -95,8 +118,14 @@ int handle__publish(struct mosquitto *mosq)
mosq->on_message(mosq, mosq->userdata, &message->msg);
mosq->in_callback = false;
}
if(mosq->on_message_v5){
mosq->in_callback = true;
mosq->on_message_v5(mosq, mosq->userdata, &message->msg, properties);
mosq->in_callback = false;
}
pthread_mutex_unlock(&mosq->callback_mutex);
message__cleanup(&message);
mosquitto_property_free_all(&properties);
return MOSQ_ERR_SUCCESS;
case 1:
rc = send__puback(mosq, message->msg.mid);
@@ -106,8 +135,14 @@ int handle__publish(struct mosquitto *mosq)
mosq->on_message(mosq, mosq->userdata, &message->msg);
mosq->in_callback = false;
}
if(mosq->on_message_v5){
mosq->in_callback = true;
mosq->on_message_v5(mosq, mosq->userdata, &message->msg, properties);
mosq->in_callback = false;
}
pthread_mutex_unlock(&mosq->callback_mutex);
message__cleanup(&message);
mosquitto_property_free_all(&properties);
return rc;
case 2:
rc = send__pubrec(mosq, message->msg.mid);
@@ -115,9 +150,11 @@ int handle__publish(struct mosquitto *mosq)
message->state = mosq_ms_wait_for_pubrel;
message__queue(mosq, message, mosq_md_in);
pthread_mutex_unlock(&mosq->in_message_mutex);
mosquitto_property_free_all(&properties);
return rc;
default:
message__cleanup(&message);
mosquitto_property_free_all(&properties);
return MOSQ_ERR_PROTOCOL;
}
}
+38 -4
View File
@@ -28,29 +28,63 @@ Contributors:
#include "logging_mosq.h"
#include "memory_mosq.h"
#include "messages_mosq.h"
#include "mqtt3_protocol.h"
#include "mqtt_protocol.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "read_handle.h"
#include "send_mosq.h"
#include "util_mosq.h"
int handle__pubrec(struct mosquitto *mosq)
int handle__pubrec(struct mosquitto_db *db, struct mosquitto *mosq)
{
uint8_t reason_code = 0;
uint16_t mid;
int rc;
mosquitto_property *properties = NULL;
assert(mosq);
rc = packet__read_uint16(&mosq->in_packet, &mid);
if(rc) return rc;
if(mid == 0) return MOSQ_ERR_PROTOCOL;
if(mosq->protocol == mosq_p_mqtt5 && mosq->in_packet.remaining_length > 2){
rc = packet__read_byte(&mosq->in_packet, &reason_code);
if(rc) return rc;
if(mosq->in_packet.remaining_length > 3){
rc = property__read_all(CMD_PUBREC, &mosq->in_packet, &properties);
if(rc) return rc;
/* Immediately free, we don't do anything with Reason String or User Property at the moment */
mosquitto_property_free_all(&properties);
}
}
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_DEBUG, "Received PUBREC from %s (Mid: %d)", mosq->id, mid);
rc = db__message_update(mosq, mid, mosq_md_out, mosq_ms_wait_for_pubcomp);
if(reason_code < 0x80){
rc = db__message_update(mosq, mid, mosq_md_out, mosq_ms_wait_for_pubcomp, 2);
}else{
return db__message_delete(db, mosq, mid, mosq_md_out, mosq_ms_wait_for_pubrec, 2);
}
#else
log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PUBREC (Mid: %d)", mosq->id, mid);
rc = message__out_update(mosq, mid, mosq_ms_wait_for_pubcomp);
if(reason_code < 0x80){
rc = message__out_update(mosq, mid, mosq_ms_wait_for_pubcomp, 2);
}else{
if(!message__delete(mosq, mid, mosq_md_out, 2)){
/* Only inform the client the message has been sent once. */
pthread_mutex_lock(&mosq->callback_mutex);
if(mosq->on_publish_v5){
mosq->in_callback = true;
mosq->on_publish_v5(mosq, mosq->userdata, mid, reason_code, properties);
mosq->in_callback = false;
}
pthread_mutex_unlock(&mosq->callback_mutex);
}
return MOSQ_ERR_SUCCESS;
}
#endif
if(rc == MOSQ_ERR_NOT_FOUND){
log__printf(mosq, MOSQ_LOG_WARNING, "Warning: Received PUBREC from %s for an unknown packet identifier %d.", mosq->id, mid);
+42 -6
View File
@@ -28,7 +28,7 @@ Contributors:
#include "logging_mosq.h"
#include "memory_mosq.h"
#include "messages_mosq.h"
#include "mqtt3_protocol.h"
#include "mqtt_protocol.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "read_handle.h"
@@ -38,32 +38,64 @@ Contributors:
int handle__pubrel(struct mosquitto_db *db, struct mosquitto *mosq)
{
uint8_t reason_code;
uint16_t mid;
#ifndef WITH_BROKER
struct mosquitto_message_all *message = NULL;
#endif
int rc;
mosquitto_property *properties = NULL;
assert(mosq);
if(mosq->protocol == mosq_p_mqtt311){
if(mosq->protocol != mosq_p_mqtt31){
if((mosq->in_packet.command&0x0F) != 0x02){
return MOSQ_ERR_PROTOCOL;
}
}
rc = packet__read_uint16(&mosq->in_packet, &mid);
if(rc) return rc;
if(mid == 0) return MOSQ_ERR_PROTOCOL;
if(mosq->protocol == mosq_p_mqtt5 && mosq->in_packet.remaining_length > 2){
rc = packet__read_byte(&mosq->in_packet, &reason_code);
if(rc) return rc;
if(mosq->in_packet.remaining_length > 3){
rc = property__read_all(CMD_PUBREL, &mosq->in_packet, &properties);
if(rc) return rc;
}
}
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_DEBUG, "Received PUBREL from %s (Mid: %d)", mosq->id, mid);
if(db__message_release(db, mosq, mid, mosq_md_in)){
/* Immediately free, we don't do anything with Reason String or User Property at the moment */
mosquitto_property_free_all(&properties);
rc = db__message_release(db, mosq, mid, mosq_md_in);
if(rc == MOSQ_ERR_PROTOCOL){
return rc;
}else if(rc != MOSQ_ERR_SUCCESS){
/* Message not found. Still send a PUBCOMP anyway because this could be
* due to a repeated PUBREL after a client has reconnected. */
log__printf(mosq, MOSQ_LOG_WARNING, "Warning: Received PUBREL from %s for an unknown packet identifier %d.", mosq->id, mid);
}
rc = send__pubcomp(mosq, mid);
if(rc) return rc;
#else
log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PUBREL (Mid: %d)", mosq->id, mid);
if(!message__remove(mosq, mid, mosq_md_in, &message)){
rc = send__pubcomp(mosq, mid);
if(rc){
message__remove(mosq, mid, mosq_md_in, &message, 2);
return rc;
}
rc = message__remove(mosq, mid, mosq_md_in, &message, 2);
if(rc){
return rc;
}else{
/* Only pass the message on if we have removed it from the queue - this
* prevents multiple callbacks for the same message. */
pthread_mutex_lock(&mosq->callback_mutex);
@@ -72,12 +104,16 @@ int handle__pubrel(struct mosquitto_db *db, struct mosquitto *mosq)
mosq->on_message(mosq, mosq->userdata, &message->msg);
mosq->in_callback = false;
}
if(mosq->on_message_v5){
mosq->in_callback = true;
mosq->on_message_v5(mosq, mosq->userdata, &message->msg, properties);
mosq->in_callback = false;
}
pthread_mutex_unlock(&mosq->callback_mutex);
mosquitto_property_free_all(&properties);
message__cleanup(&message);
}
#endif
rc = send__pubcomp(mosq, mid);
if(rc) return rc;
return MOSQ_ERR_SUCCESS;
}
+19 -1
View File
@@ -26,7 +26,9 @@ Contributors:
#include "mosquitto_internal.h"
#include "logging_mosq.h"
#include "memory_mosq.h"
#include "mqtt_protocol.h"
#include "packet_mosq.h"
#include "property_mosq.h"
int handle__suback(struct mosquitto *mosq)
@@ -37,6 +39,7 @@ int handle__suback(struct mosquitto *mosq)
int qos_count;
int i = 0;
int rc;
mosquitto_property *properties = NULL;
assert(mosq);
#ifdef WITH_BROKER
@@ -46,6 +49,12 @@ int handle__suback(struct mosquitto *mosq)
#endif
rc = packet__read_uint16(&mosq->in_packet, &mid);
if(rc) return rc;
if(mid == 0) return MOSQ_ERR_PROTOCOL;
if(mosq->protocol == mosq_p_mqtt5){
rc = property__read_all(CMD_SUBACK, &mosq->in_packet, &properties);
if(rc) return rc;
}
qos_count = mosq->in_packet.remaining_length - mosq->in_packet.pos;
granted_qos = mosquitto__malloc(qos_count*sizeof(int));
@@ -59,14 +68,23 @@ int handle__suback(struct mosquitto *mosq)
granted_qos[i] = (int)qos;
i++;
}
#ifndef WITH_BROKER
#ifdef WITH_BROKER
/* Immediately free, we don't do anything with Reason String or User Property at the moment */
mosquitto_property_free_all(&properties);
#else
pthread_mutex_lock(&mosq->callback_mutex);
if(mosq->on_subscribe){
mosq->in_callback = true;
mosq->on_subscribe(mosq, mosq->userdata, mid, qos_count, granted_qos);
mosq->in_callback = false;
}
if(mosq->on_subscribe_v5){
mosq->in_callback = true;
mosq->on_subscribe_v5(mosq, mosq->userdata, mid, qos_count, granted_qos, properties);
mosq->in_callback = false;
}
pthread_mutex_unlock(&mosq->callback_mutex);
mosquitto_property_free_all(&properties);
#endif
mosquitto__free(granted_qos);
+20 -2
View File
@@ -28,9 +28,10 @@ Contributors:
#include "logging_mosq.h"
#include "memory_mosq.h"
#include "messages_mosq.h"
#include "mqtt3_protocol.h"
#include "mqtt_protocol.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "property_mosq.h"
#include "read_handle.h"
#include "send_mosq.h"
#include "util_mosq.h"
@@ -40,6 +41,7 @@ int handle__unsuback(struct mosquitto *mosq)
{
uint16_t mid;
int rc;
mosquitto_property *properties = NULL;
assert(mosq);
#ifdef WITH_BROKER
@@ -49,14 +51,30 @@ int handle__unsuback(struct mosquitto *mosq)
#endif
rc = packet__read_uint16(&mosq->in_packet, &mid);
if(rc) return rc;
#ifndef WITH_BROKER
if(mid == 0) return MOSQ_ERR_PROTOCOL;
if(mosq->protocol == mosq_p_mqtt5){
rc = property__read_all(CMD_UNSUBACK, &mosq->in_packet, &properties);
if(rc) return rc;
}
#ifdef WITH_BROKER
/* Immediately free, we don't do anything with Reason String or User Property at the moment */
mosquitto_property_free_all(&properties);
#else
pthread_mutex_lock(&mosq->callback_mutex);
if(mosq->on_unsubscribe){
mosq->in_callback = true;
mosq->on_unsubscribe(mosq, mosq->userdata, mid);
mosq->in_callback = false;
}
if(mosq->on_unsubscribe_v5){
mosq->in_callback = true;
mosq->on_unsubscribe_v5(mosq, mosq->userdata, mid, properties);
mosq->in_callback = false;
}
pthread_mutex_unlock(&mosq->callback_mutex);
mosquitto_property_free_all(&properties);
#endif
return MOSQ_ERR_SUCCESS;
+35
View File
@@ -94,6 +94,41 @@ MOSQ_1.5 {
MOSQ_1.6 {
global:
mosquitto_connect_bind_v5;
mosquitto_connect_v5_callback_set;
mosquitto_disconnect_v5;
mosquitto_disconnect_v5_callback_set;
mosquitto_int_option;
mosquitto_message_v5_callback_set;
mosquitto_property_add_binary;
mosquitto_property_add_byte;
mosquitto_property_add_int16;
mosquitto_property_add_int32;
mosquitto_property_add_string;
mosquitto_property_add_string_pair;
mosquitto_property_add_varint;
mosquitto_property_check_all;
mosquitto_property_check_command;
mosquitto_property_free_all;
mosquitto_property_read_binary;
mosquitto_property_read_byte;
mosquitto_property_read_int16;
mosquitto_property_read_int32;
mosquitto_property_read_string;
mosquitto_property_read_string_pair;
mosquitto_property_read_varint;
mosquitto_publish_v5;
mosquitto_publish_v5_callback_set;
mosquitto_reason_string;
mosquitto_string_option;
mosquitto_string_to_command;
mosquitto_string_to_property_info;
mosquitto_subscribe_multiple;
mosquitto_subscribe_v5;
mosquitto_subscribe_v5_callback_set;
mosquitto_unsubscribe_multiple;
mosquitto_unsubscribe_v5;
mosquitto_unsubscribe_v5_callback_set;
mosquitto_void_option;
mosquitto_will_set_v5;
} MOSQ_1.5;
+17 -37
View File
@@ -147,12 +147,10 @@ int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets)
}else{
if(mosq->sock != INVALID_SOCKET){
if(FD_ISSET(mosq->sock, &readfds)){
do{
rc = mosquitto_loop_read(mosq, max_packets);
if(rc || mosq->sock == INVALID_SOCKET){
return rc;
}
}while(SSL_DATA_PENDING(mosq));
rc = mosquitto_loop_read(mosq, max_packets);
if(rc || mosq->sock == INVALID_SOCKET){
return rc;
}
}
if(mosq->sockpairR != INVALID_SOCKET && FD_ISSET(mosq->sockpairR, &readfds)){
#ifndef WIN32
@@ -245,8 +243,12 @@ int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets)
}else{
pthread_mutex_unlock(&mosq->state_mutex);
if(mosq->reconnect_delay > 0 && mosq->reconnect_exponential_backoff){
reconnect_delay = mosq->reconnect_delay*reconnects*reconnects;
if(mosq->reconnect_delay_max > mosq->reconnect_delay){
if(mosq->reconnect_exponential_backoff){
reconnect_delay = mosq->reconnect_delay*(reconnects+1)*(reconnects+1);
}else{
reconnect_delay = mosq->reconnect_delay*(reconnects+1);
}
}else{
reconnect_delay = mosq->reconnect_delay;
}
@@ -284,37 +286,10 @@ int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets)
int mosquitto_loop_misc(struct mosquitto *mosq)
{
time_t now;
int rc;
if(!mosq) return MOSQ_ERR_INVAL;
if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
mosquitto__check_keepalive(mosq);
now = mosquitto_time();
if(mosq->ping_t && now - mosq->ping_t >= mosq->keepalive){
/* mosq->ping_t != 0 means we are waiting for a pingresp.
* This hasn't happened in the keepalive time so we should disconnect.
*/
net__socket_close(mosq);
pthread_mutex_lock(&mosq->state_mutex);
if(mosq->state == mosq_cs_disconnecting){
rc = MOSQ_ERR_SUCCESS;
}else{
rc = MOSQ_ERR_KEEPALIVE;
}
pthread_mutex_unlock(&mosq->state_mutex);
pthread_mutex_lock(&mosq->callback_mutex);
if(mosq->on_disconnect){
mosq->in_callback = true;
mosq->on_disconnect(mosq, mosq->userdata, rc);
mosq->in_callback = false;
}
pthread_mutex_unlock(&mosq->callback_mutex);
return MOSQ_ERR_CONN_LOST;
}
return MOSQ_ERR_SUCCESS;
return mosquitto__check_keepalive(mosq);
}
@@ -333,6 +308,11 @@ static int mosquitto__loop_rc_handle(struct mosquitto *mosq, int rc)
mosq->on_disconnect(mosq, mosq->userdata, rc);
mosq->in_callback = false;
}
if(mosq->on_disconnect_v5){
mosq->in_callback = true;
mosq->on_disconnect_v5(mosq, mosq->userdata, rc, NULL);
mosq->in_callback = false;
}
pthread_mutex_unlock(&mosq->callback_mutex);
return rc;
}
@@ -364,7 +344,7 @@ int mosquitto_loop_read(struct mosquitto *mosq, int max_packets)
/* Queue len here tells us how many messages are awaiting processing and
* have QoS > 0. We should try to deal with that many in this loop in order
* to keep up. */
for(i=0; i<max_packets; i++){
for(i=0; i<max_packets || SSL_DATA_PENDING(mosq); i++){
#ifdef WITH_SOCKS
if(mosq->socks5_host){
rc = socks5__read(mosq);
+28 -23
View File
@@ -26,6 +26,7 @@ Contributors:
#include "messages_mosq.h"
#include "send_mosq.h"
#include "time_mosq.h"
#include "util_mosq.h"
void message__cleanup(struct mosquitto_message_all **message)
{
@@ -82,13 +83,13 @@ int mosquitto_message_copy(struct mosquitto_message *dst, const struct mosquitto
return MOSQ_ERR_SUCCESS;
}
int message__delete(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir)
int message__delete(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, int qos)
{
struct mosquitto_message_all *message;
int rc;
assert(mosq);
rc = message__remove(mosq, mid, dir, &message);
rc = message__remove(mosq, mid, dir, &message, qos);
if(rc == MOSQ_ERR_SUCCESS){
message__cleanup(&message);
}
@@ -123,6 +124,7 @@ int message__queue(struct mosquitto *mosq, struct mosquitto_message_all *message
/* mosq->*_message_mutex should be locked before entering this function */
assert(mosq);
assert(message);
assert(message->msg.qos != 0);
if(dir == mosq_md_out){
mosq->out_queue_len++;
@@ -133,12 +135,10 @@ int message__queue(struct mosquitto *mosq, struct mosquitto_message_all *message
mosq->out_messages = message;
}
mosq->out_messages_last = message;
if(message->msg.qos > 0){
if(mosq->max_inflight_messages == 0 || mosq->inflight_messages < mosq->max_inflight_messages){
mosq->inflight_messages++;
}else{
rc = 1;
}
if(mosq->send_quota > 0){
mosq->send_quota--;
}else{
rc = 1;
}
}else{
mosq->in_queue_len++;
@@ -187,17 +187,15 @@ void message__reconnect_reset(struct mosquitto *mosq)
pthread_mutex_lock(&mosq->out_message_mutex);
mosq->inflight_messages = 0;
mosq->send_quota = mosq->send_maximum;
message = mosq->out_messages;
mosq->out_queue_len = 0;
while(message){
mosq->out_queue_len++;
message->timestamp = 0;
if(mosq->max_inflight_messages == 0 || mosq->inflight_messages < mosq->max_inflight_messages){
if(message->msg.qos > 0){
mosq->inflight_messages++;
}
if(mosq->send_quota > 0){
mosq->send_quota--;
if(message->msg.qos == 1){
message->state = mosq_ms_publish_qos1;
}else if(message->msg.qos == 2){
@@ -218,7 +216,7 @@ void message__reconnect_reset(struct mosquitto *mosq)
pthread_mutex_unlock(&mosq->out_message_mutex);
}
int message__remove(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, struct mosquitto_message_all **message)
int message__remove(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, struct mosquitto_message_all **message, int qos)
{
struct mosquitto_message_all *cur, *prev = NULL;
bool found = false;
@@ -231,6 +229,9 @@ int message__remove(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_dir
cur = mosq->out_messages;
while(cur){
if(cur->msg.mid == mid){
if(cur->msg.qos != qos){
return MOSQ_ERR_PROTOCOL;
}
if(prev){
prev->next = cur->next;
}else{
@@ -243,9 +244,7 @@ int message__remove(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_dir
}else if(!mosq->out_messages){
mosq->out_messages_last = NULL;
}
if(cur->msg.qos > 0){
mosq->inflight_messages--;
}
util__increment_send_quota(mosq);
found = true;
break;
}
@@ -256,15 +255,15 @@ int message__remove(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_dir
if(found){
cur = mosq->out_messages;
while(cur){
if(mosq->max_inflight_messages == 0 || mosq->inflight_messages < mosq->max_inflight_messages){
if(mosq->send_quota > 0){
if(cur->msg.qos > 0 && cur->state == mosq_ms_invalid){
mosq->inflight_messages++;
mosq->send_quota--;
if(cur->msg.qos == 1){
cur->state = mosq_ms_wait_for_puback;
}else if(cur->msg.qos == 2){
cur->state = mosq_ms_wait_for_pubrec;
}
rc = send__publish(mosq, cur->msg.mid, cur->msg.topic, cur->msg.payloadlen, cur->msg.payload, cur->msg.qos, cur->msg.retain, cur->dup);
rc = send__publish(mosq, cur->msg.mid, cur->msg.topic, cur->msg.payloadlen, cur->msg.payload, cur->msg.qos, cur->msg.retain, cur->dup, NULL, NULL, 0);
if(rc){
pthread_mutex_unlock(&mosq->out_message_mutex);
return rc;
@@ -287,6 +286,9 @@ int message__remove(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_dir
cur = mosq->in_messages;
while(cur){
if(cur->msg.mid == mid){
if(cur->msg.qos != qos){
return MOSQ_ERR_PROTOCOL;
}
if(prev){
prev->next = cur->next;
}else{
@@ -334,7 +336,7 @@ void message__retry_check_actual(struct mosquitto *mosq, struct mosquitto_messag
case mosq_ms_publish_qos2:
messages->timestamp = now;
messages->dup = true;
send__publish(mosq, messages->msg.mid, messages->msg.topic, messages->msg.payloadlen, messages->msg.payload, messages->msg.qos, messages->msg.retain, messages->dup);
send__publish(mosq, messages->msg.mid, messages->msg.topic, messages->msg.payloadlen, messages->msg.payload, messages->msg.qos, messages->msg.retain, messages->dup, NULL, NULL, 0);
break;
case mosq_ms_wait_for_pubrel:
messages->timestamp = now;
@@ -370,7 +372,7 @@ void mosquitto_message_retry_set(struct mosquitto *mosq, unsigned int message_re
{
}
int message__out_update(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_state state)
int message__out_update(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_state state, int qos)
{
struct mosquitto_message_all *message;
assert(mosq);
@@ -379,6 +381,9 @@ int message__out_update(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg
message = mosq->out_messages;
while(message){
if(message->msg.mid == mid){
if(message->msg.qos != qos){
return MOSQ_ERR_PROTOCOL;
}
message->state = state;
message->timestamp = mosquitto_time();
pthread_mutex_unlock(&mosq->out_message_mutex);
@@ -394,7 +399,7 @@ int mosquitto_max_inflight_messages_set(struct mosquitto *mosq, unsigned int max
{
if(!mosq) return MOSQ_ERR_INVAL;
mosq->max_inflight_messages = max_inflight_messages;
mosq->send_maximum = max_inflight_messages;
return MOSQ_ERR_SUCCESS;
}
+3 -3
View File
@@ -21,11 +21,11 @@ Contributors:
void message__cleanup_all(struct mosquitto *mosq);
void message__cleanup(struct mosquitto_message_all **message);
int message__delete(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir);
int message__delete(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, int qos);
int message__queue(struct mosquitto *mosq, struct mosquitto_message_all *message, enum mosquitto_msg_direction dir);
void message__reconnect_reset(struct mosquitto *mosq);
int message__remove(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, struct mosquitto_message_all **message);
int message__remove(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, struct mosquitto_message_all **message, int qos);
void message__retry_check(struct mosquitto *mosq);
int message__out_update(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_state state);
int message__out_update(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_state state, int qos);
#endif
+147 -23
View File
@@ -27,6 +27,7 @@ Contributors:
#include "mosquitto_internal.h"
#include "memory_mosq.h"
#include "messages_mosq.h"
#include "mqtt_protocol.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "will_mosq.h"
@@ -63,12 +64,12 @@ int mosquitto_lib_cleanup(void)
return MOSQ_ERR_SUCCESS;
}
struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *userdata)
struct mosquitto *mosquitto_new(const char *id, bool clean_start, void *userdata)
{
struct mosquitto *mosq = NULL;
int rc;
if(clean_session == false && id == NULL){
if(clean_start == false && id == NULL){
errno = EINVAL;
return NULL;
}
@@ -85,7 +86,7 @@ struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *userda
#ifdef WITH_THREADING
mosq->thread_id = pthread_self();
#endif
rc = mosquitto_reinitialise(mosq, id, clean_session, userdata);
rc = mosquitto_reinitialise(mosq, id, clean_start, userdata);
if(rc){
mosquitto_destroy(mosq);
if(rc == MOSQ_ERR_INVAL){
@@ -101,13 +102,11 @@ struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *userda
return mosq;
}
int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_session, void *userdata)
int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_start, void *userdata)
{
int i;
if(!mosq) return MOSQ_ERR_INVAL;
if(clean_session == false && id == NULL){
if(clean_start == false && id == NULL){
return MOSQ_ERR_INVAL;
}
@@ -124,7 +123,7 @@ int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_se
mosq->sockpairR = INVALID_SOCKET;
mosq->sockpairW = INVALID_SOCKET;
mosq->keepalive = 60;
mosq->clean_session = clean_session;
mosq->clean_start = clean_start;
if(id){
if(STREMPTY(id)){
return MOSQ_ERR_INVAL;
@@ -133,20 +132,6 @@ int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_se
return MOSQ_ERR_MALFORMED_UTF8;
}
mosq->id = mosquitto__strdup(id);
}else{
mosq->id = (char *)mosquitto__calloc(24, sizeof(char));
if(!mosq->id){
return MOSQ_ERR_NOMEM;
}
mosq->id[0] = 'm';
mosq->id[1] = 'o';
mosq->id[2] = 's';
mosq->id[3] = 'q';
mosq->id[4] = '/';
for(i=5; i<23; i++){
mosq->id[i] = (rand()%73)+48;
}
}
mosq->in_packet.payload = NULL;
packet__cleanup(&mosq->in_packet);
@@ -161,7 +146,9 @@ int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_se
mosq->in_messages_last = NULL;
mosq->out_messages = NULL;
mosq->out_messages_last = NULL;
mosq->max_inflight_messages = 20;
mosq->maximum_qos = 2;
mosq->receive_maximum = 20;
mosq->send_maximum = 20;
mosq->will = NULL;
mosq->on_connect = NULL;
mosq->on_publish = NULL;
@@ -372,6 +359,14 @@ const char *mosquitto_strerror(int mosq_errno)
return "Proxy error.";
case MOSQ_ERR_MALFORMED_UTF8:
return "Malformed UTF-8";
case MOSQ_ERR_DUPLICATE_PROPERTY:
return "Duplicate property in property list";
case MOSQ_ERR_TLS_HANDSHAKE:
return "TLS handshake failed.";
case MOSQ_ERR_QOS_NOT_SUPPORTED:
return "Requested QoS not supported on server.";
case MOSQ_ERR_OVERSIZE_PACKET:
return "Packet larger than supported by the server.";
default:
return "Unknown error.";
}
@@ -397,6 +392,135 @@ const char *mosquitto_connack_string(int connack_code)
}
}
const char *mosquitto_reason_string(int reason_code)
{
switch(reason_code){
case MQTT_RC_SUCCESS:
return "Success";
case MQTT_RC_GRANTED_QOS1:
return "Granted QoS 1";
case MQTT_RC_GRANTED_QOS2:
return "Granted QoS 2";
case MQTT_RC_DISCONNECT_WITH_WILL_MSG:
return "Disconnect with Will Message";
case MQTT_RC_NO_MATCHING_SUBSCRIBERS:
return "No matching subscribers";
case MQTT_RC_NO_SUBSCRIPTION_EXISTED:
return "No subscription existed";
case MQTT_RC_CONTINUE_AUTHENTICATION:
return "Continue authentication";
case MQTT_RC_REAUTHENTICATE:
return "Re-authenticate";
case MQTT_RC_UNSPECIFIED:
return "Unspecified error";
case MQTT_RC_MALFORMED_PACKET:
return "Malformed Packet";
case MQTT_RC_PROTOCOL_ERROR:
return "Protocol Error";
case MQTT_RC_IMPLEMENTATION_SPECIFIC:
return "Implementation specific error";
case MQTT_RC_UNSUPPORTED_PROTOCOL_VERSION:
return "Unsupported Protocol Version";
case MQTT_RC_CLIENTID_NOT_VALID:
return "Client Identifier not valid";
case MQTT_RC_BAD_USERNAME_OR_PASSWORD:
return "Bad User Name or Password";
case MQTT_RC_NOT_AUTHORIZED:
return "Not authorized";
case MQTT_RC_SERVER_UNAVAILABLE:
return "Server unavailable";
case MQTT_RC_SERVER_BUSY:
return "Server busy";
case MQTT_RC_BANNED:
return "Banned";
case MQTT_RC_SERVER_SHUTTING_DOWN:
return "Server shutting down";
case MQTT_RC_BAD_AUTHENTICATION_METHOD:
return "Bad authentication method";
case MQTT_RC_KEEP_ALIVE_TIMEOUT:
return "Keep Alive timeout";
case MQTT_RC_SESSION_TAKEN_OVER:
return "Session taken over";
case MQTT_RC_TOPIC_FILTER_INVALID:
return "Topic Filter invalid";
case MQTT_RC_TOPIC_NAME_INVALID:
return "Topic Name invalid";
case MQTT_RC_PACKET_ID_IN_USE:
return "Packet Identifier in use";
case MQTT_RC_PACKET_ID_NOT_FOUND:
return "Packet Identifier not found";
case MQTT_RC_RECEIVE_MAXIMUM_EXCEEDED:
return "Receive Maximum exceeded";
case MQTT_RC_TOPIC_ALIAS_INVALID:
return "Topic Alias invalid";
case MQTT_RC_PACKET_TOO_LARGE:
return "Packet too large";
case MQTT_RC_MESSAGE_RATE_TOO_HIGH:
return "Message rate too high";
case MQTT_RC_QUOTA_EXCEEDED:
return "Quota exceeded";
case MQTT_RC_ADMINISTRATIVE_ACTION:
return "Administrative action";
case MQTT_RC_PAYLOAD_FORMAT_INVALID:
return "Payload format invalid";
case MQTT_RC_RETAIN_NOT_SUPPORTED:
return "Retain not supported";
case MQTT_RC_QOS_NOT_SUPPORTED:
return "QoS not supported";
case MQTT_RC_USE_ANOTHER_SERVER:
return "Use another server";
case MQTT_RC_SERVER_MOVED:
return "Server moved";
case MQTT_RC_SHARED_SUBS_NOT_SUPPORTED:
return "Shared Subscriptions not supported";
case MQTT_RC_CONNECTION_RATE_EXCEEDED:
return "Connection rate exceeded";
case MQTT_RC_MAXIMUM_CONNECT_TIME:
return "Maximum connect time";
case MQTT_RC_SUBSCRIPTION_IDS_NOT_SUPPORTED:
return "Subscription identifiers not supported";
case MQTT_RC_WILDCARD_SUBS_NOT_SUPPORTED:
return "Wildcard Subscriptions not supported";
default:
return "Unknown reason";
}
}
int mosquitto_string_to_command(const char *str, int *cmd)
{
if(!strcasecmp(str, "connect")){
*cmd = CMD_CONNECT;
}else if(!strcasecmp(str, "connack")){
*cmd = CMD_CONNACK;
}else if(!strcasecmp(str, "publish")){
*cmd = CMD_PUBLISH;
}else if(!strcasecmp(str, "puback")){
*cmd = CMD_PUBACK;
}else if(!strcasecmp(str, "pubrec")){
*cmd = CMD_PUBREC;
}else if(!strcasecmp(str, "pubrel")){
*cmd = CMD_PUBREL;
}else if(!strcasecmp(str, "pubcomp")){
*cmd = CMD_PUBCOMP;
}else if(!strcasecmp(str, "subscribe")){
*cmd = CMD_SUBSCRIBE;
}else if(!strcasecmp(str, "unsubscribe")){
*cmd = CMD_UNSUBSCRIBE;
}else if(!strcasecmp(str, "disconnect")){
*cmd = CMD_DISCONNECT;
}else if(!strcasecmp(str, "auth")){
*cmd = CMD_AUTH;
}else if(!strcasecmp(str, "will")){
*cmd = CMD_WILL;
}else{
return MOSQ_ERR_INVAL;
}
return MOSQ_ERR_SUCCESS;
}
int mosquitto_sub_topic_tokenise(const char *subtopic, char ***topics, int *count)
{
int len;
+1212 -69
View File
File diff suppressed because it is too large Load Diff
+30 -7
View File
@@ -115,7 +115,8 @@ enum mosquitto__protocol {
mosq_p_invalid = 0,
mosq_p_mqtt31 = 1,
mosq_p_mqtt311 = 2,
mosq_p_mqtts = 3
mosq_p_mqtts = 3,
mosq_p_mqtt5 = 5,
};
enum mosquitto__threaded_state {
@@ -131,6 +132,12 @@ enum mosquitto__transport {
mosq_t_sctp = 3
};
struct mosquitto__alias{
char *topic;
uint16_t alias;
};
struct mosquitto__packet{
uint8_t *payload;
struct mosquitto__packet *next;
@@ -146,11 +153,13 @@ struct mosquitto__packet{
struct mosquitto_message_all{
struct mosquitto_message_all *next;
mosquitto_property *properties;
time_t timestamp;
//enum mosquitto_msg_direction direction;
enum mosquitto_msg_state state;
bool dup;
struct mosquitto_message msg;
uint32_t expiry_interval;
};
#ifdef WITH_TLS
@@ -182,7 +191,10 @@ struct mosquitto {
struct mosquitto__packet in_packet;
struct mosquitto__packet *current_out_packet;
struct mosquitto__packet *out_packet;
struct mosquitto_message *will;
struct mosquitto_message_all *will;
struct mosquitto__alias *aliases;
uint32_t maximum_packet_size;
int alias_count;
#ifdef WITH_TLS
SSL *ssl;
SSL_CTX *ssl_ctx;
@@ -216,10 +228,10 @@ struct mosquitto {
pthread_mutex_t mid_mutex;
pthread_t thread_id;
#endif
bool clean_session;
bool clean_start;
uint32_t session_expiry_interval;
#ifdef WITH_BROKER
char *old_id; /* for when a duplicate client connects, but we still want to
know what the id was */
bool removed_from_by_id; /* True if removed from by_id hash */
bool is_dropping;
bool is_bridge;
struct mosquitto__bridge *bridge;
@@ -262,11 +274,17 @@ struct mosquitto {
struct mosquitto_message_all *out_messages_last;
void (*on_connect)(struct mosquitto *, void *userdata, int rc);
void (*on_connect_with_flags)(struct mosquitto *, void *userdata, int rc, int flags);
void (*on_connect_v5)(struct mosquitto *, void *userdata, int rc, int flags, const mosquitto_property *props);
void (*on_disconnect)(struct mosquitto *, void *userdata, int rc);
void (*on_disconnect_v5)(struct mosquitto *, void *userdata, int rc, const mosquitto_property *props);
void (*on_publish)(struct mosquitto *, void *userdata, int mid);
void (*on_publish_v5)(struct mosquitto *, void *userdata, int mid, int reason_code, const mosquitto_property *props);
void (*on_message)(struct mosquitto *, void *userdata, const struct mosquitto_message *message);
void (*on_message_v5)(struct mosquitto *, void *userdata, const struct mosquitto_message *message, const mosquitto_property *props);
void (*on_subscribe)(struct mosquitto *, void *userdata, int mid, int qos_count, const int *granted_qos);
void (*on_subscribe_v5)(struct mosquitto *, void *userdata, int mid, int qos_count, const int *granted_qos, const mosquitto_property *props);
void (*on_unsubscribe)(struct mosquitto *, void *userdata, int mid);
void (*on_unsubscribe_v5)(struct mosquitto *, void *userdata, int mid, const mosquitto_property *props);
void (*on_log)(struct mosquitto *, void *userdata, int level, const char *str);
//void (*on_error)();
char *host;
@@ -279,12 +297,15 @@ struct mosquitto {
bool reconnect_exponential_backoff;
char threaded;
struct mosquitto__packet *out_packet_last;
int inflight_messages;
int max_inflight_messages;
# ifdef WITH_SRV
ares_channel achan;
# endif
#endif
int send_quota;
int receive_quota;
uint16_t send_maximum;
uint16_t receive_maximum;
uint8_t maximum_qos;
#ifdef WITH_BROKER
UT_hash_handle hh_id;
@@ -298,5 +319,7 @@ struct mosquitto {
#define STREMPTY(str) (str[0] == '\0')
void do_client_disconnect(struct mosquitto *mosq, int reason_code, const mosquitto_property *properties);
#endif
-53
View File
@@ -1,53 +0,0 @@
/*
Copyright (c) 2009-2018 Roger Light <roger@atchoo.org>
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
and Eclipse Distribution License v1.0 which accompany this distribution.
The Eclipse Public License is available at
http://www.eclipse.org/legal/epl-v10.html
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
Contributors:
Roger Light - initial implementation and documentation.
*/
#ifndef MQTT3_PROTOCOL_H
#define MQTT3_PROTOCOL_H
/* For version 3 of the MQTT protocol */
#define PROTOCOL_NAME_v31 "MQIsdp"
#define PROTOCOL_VERSION_v31 3
#define PROTOCOL_NAME_v311 "MQTT"
#define PROTOCOL_VERSION_v311 4
/* Message types */
#define CONNECT 0x10
#define CONNACK 0x20
#define PUBLISH 0x30
#define PUBACK 0x40
#define PUBREC 0x50
#define PUBREL 0x60
#define PUBCOMP 0x70
#define SUBSCRIBE 0x80
#define SUBACK 0x90
#define UNSUBSCRIBE 0xA0
#define UNSUBACK 0xB0
#define PINGREQ 0xC0
#define PINGRESP 0xD0
#define DISCONNECT 0xE0
#define CONNACK_ACCEPTED 0
#define CONNACK_REFUSED_PROTOCOL_VERSION 1
#define CONNACK_REFUSED_IDENTIFIER_REJECTED 2
#define CONNACK_REFUSED_SERVER_UNAVAILABLE 3
#define CONNACK_REFUSED_BAD_USERNAME_PASSWORD 4
#define CONNACK_REFUSED_NOT_AUTHORIZED 5
#define MQTT_MAX_PAYLOAD 268435455
#endif
+158
View File
@@ -0,0 +1,158 @@
/*
Copyright (c) 2009-2018 Roger Light <roger@atchoo.org>
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
and Eclipse Distribution License v1.0 which accompany this distribution.
The Eclipse Public License is available at
http://www.eclipse.org/legal/epl-v10.html
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
Contributors:
Roger Light - initial implementation and documentation.
*/
#ifndef MQTT_PROTOCOL_H
#define MQTT_PROTOCOL_H
#define PROTOCOL_NAME_v31 "MQIsdp"
#define PROTOCOL_VERSION_v31 3
#define PROTOCOL_NAME "MQTT"
#define PROTOCOL_VERSION_v311 4
#define PROTOCOL_VERSION_v5 5
/* Message types */
#define CMD_CONNECT 0x10
#define CMD_CONNACK 0x20
#define CMD_PUBLISH 0x30
#define CMD_PUBACK 0x40
#define CMD_PUBREC 0x50
#define CMD_PUBREL 0x60
#define CMD_PUBCOMP 0x70
#define CMD_SUBSCRIBE 0x80
#define CMD_SUBACK 0x90
#define CMD_UNSUBSCRIBE 0xA0
#define CMD_UNSUBACK 0xB0
#define CMD_PINGREQ 0xC0
#define CMD_PINGRESP 0xD0
#define CMD_DISCONNECT 0xE0
#define CMD_AUTH 0xF0
/* Mosquitto only: for distinguishing CONNECT and WILL properties */
#define CMD_WILL 0x100
enum mqtt311_connack_codes {
CONNACK_ACCEPTED = 0,
CONNACK_REFUSED_PROTOCOL_VERSION = 1,
CONNACK_REFUSED_IDENTIFIER_REJECTED = 2,
CONNACK_REFUSED_SERVER_UNAVAILABLE = 3,
CONNACK_REFUSED_BAD_USERNAME_PASSWORD = 4,
CONNACK_REFUSED_NOT_AUTHORIZED = 5,
};
enum mqtt5_return_codes {
MQTT_RC_SUCCESS = 0, /* CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, UNSUBACK, AUTH */
MQTT_RC_NORMAL_DISCONNECTION = 0, /* DISCONNECT */
MQTT_RC_GRANTED_QOS0 = 0, /* SUBACK */
MQTT_RC_GRANTED_QOS1 = 1, /* SUBACK */
MQTT_RC_GRANTED_QOS2 = 2, /* SUBACK */
MQTT_RC_DISCONNECT_WITH_WILL_MSG = 4, /* DISCONNECT */
MQTT_RC_NO_MATCHING_SUBSCRIBERS = 16, /* PUBACK, PUBREC */
MQTT_RC_NO_SUBSCRIPTION_EXISTED = 17, /* UNSUBACK */
MQTT_RC_CONTINUE_AUTHENTICATION = 24, /* AUTH */
MQTT_RC_REAUTHENTICATE = 25, /* AUTH */
MQTT_RC_UNSPECIFIED = 128, /* CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT */
MQTT_RC_MALFORMED_PACKET = 129, /* CONNACK, DISCONNECT */
MQTT_RC_PROTOCOL_ERROR = 130, /* DISCONNECT */
MQTT_RC_IMPLEMENTATION_SPECIFIC = 131, /* CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT */
MQTT_RC_UNSUPPORTED_PROTOCOL_VERSION = 132, /* CONNACK */
MQTT_RC_CLIENTID_NOT_VALID = 133, /* CONNACK */
MQTT_RC_BAD_USERNAME_OR_PASSWORD = 134, /* CONNACK */
MQTT_RC_NOT_AUTHORIZED = 135, /* CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT */
MQTT_RC_SERVER_UNAVAILABLE = 136, /* CONNACK */
MQTT_RC_SERVER_BUSY = 137, /* CONNACK, DISCONNECT */
MQTT_RC_BANNED = 138, /* CONNACK */
MQTT_RC_SERVER_SHUTTING_DOWN = 139, /* DISCONNECT */
MQTT_RC_BAD_AUTHENTICATION_METHOD = 140, /* CONNACK */
MQTT_RC_KEEP_ALIVE_TIMEOUT = 141, /* DISCONNECT */
MQTT_RC_SESSION_TAKEN_OVER = 142, /* DISCONNECT */
MQTT_RC_TOPIC_FILTER_INVALID = 143, /* SUBACK, UNSUBACK, DISCONNECT */
MQTT_RC_TOPIC_NAME_INVALID = 144, /* CONNACK, PUBACK, PUBREC, DISCONNECT */
MQTT_RC_PACKET_ID_IN_USE = 145, /* PUBACK, SUBACK, UNSUBACK */
MQTT_RC_PACKET_ID_NOT_FOUND = 146, /* PUBREL, PUBCOMP */
MQTT_RC_RECEIVE_MAXIMUM_EXCEEDED = 147, /* DISCONNECT */
MQTT_RC_TOPIC_ALIAS_INVALID = 148, /* DISCONNECT */
MQTT_RC_PACKET_TOO_LARGE = 149, /* CONNACK, PUBACK, PUBREC, DISCONNECT */
MQTT_RC_MESSAGE_RATE_TOO_HIGH = 150, /* DISCONNECT */
MQTT_RC_QUOTA_EXCEEDED = 151, /* PUBACK, PUBREC, SUBACK, DISCONNECT */
MQTT_RC_ADMINISTRATIVE_ACTION = 152, /* DISCONNECT */
MQTT_RC_PAYLOAD_FORMAT_INVALID = 153, /* CONNACK, DISCONNECT */
MQTT_RC_RETAIN_NOT_SUPPORTED = 154, /* CONNACK, DISCONNECT */
MQTT_RC_QOS_NOT_SUPPORTED = 155, /* CONNACK, DISCONNECT */
MQTT_RC_USE_ANOTHER_SERVER = 156, /* CONNACK, DISCONNECT */
MQTT_RC_SERVER_MOVED = 157, /* CONNACK, DISCONNECT */
MQTT_RC_SHARED_SUBS_NOT_SUPPORTED = 158, /* SUBACK, DISCONNECT */
MQTT_RC_CONNECTION_RATE_EXCEEDED = 159, /* CONNACK, DISCONNECT */
MQTT_RC_MAXIMUM_CONNECT_TIME = 160, /* DISCONNECT */
MQTT_RC_SUBSCRIPTION_IDS_NOT_SUPPORTED = 161, /* SUBACK, DISCONNECT */
MQTT_RC_WILDCARD_SUBS_NOT_SUPPORTED = 162, /* SUBACK, DISCONNECT */
};
enum mqtt5_property {
MQTT_PROP_PAYLOAD_FORMAT_INDICATOR = 1, /* Byte : PUBLISH, Will Properties */
MQTT_PROP_MESSAGE_EXPIRY_INTERVAL = 2, /* 4 byte int : PUBLISH, Will Properties */
MQTT_PROP_CONTENT_TYPE = 3, /* UTF-8 string : PUBLISH, Will Properties */
MQTT_PROP_RESPONSE_TOPIC = 8, /* UTF-8 string : PUBLISH, Will Properties */
MQTT_PROP_CORRELATION_DATA = 9, /* Binary Data : PUBLISH, Will Properties */
MQTT_PROP_SUBSCRIPTION_IDENTIFIER = 11, /* Variable byte int : PUBLISH, SUBSCRIBE */
MQTT_PROP_SESSION_EXPIRY_INTERVAL = 17, /* 4 byte int : CONNECT, CONNACK, DISCONNECT */
MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER = 18, /* UTF-8 string : CONNACK */
MQTT_PROP_SERVER_KEEP_ALIVE = 19, /* 2 byte int : CONNACK */
MQTT_PROP_AUTHENTICATION_METHOD = 21, /* UTF-8 string : CONNECT, CONNACK, AUTH */
MQTT_PROP_AUTHENTICATION_DATA = 22, /* Binary Data : CONNECT, CONNACK, AUTH */
MQTT_PROP_REQUEST_PROBLEM_INFORMATION = 23, /* Byte : CONNECT */
MQTT_PROP_WILL_DELAY_INTERVAL = 24, /* 4 byte int : Will properties */
MQTT_PROP_REQUEST_RESPONSE_INFORMATION = 25,/* Byte : CONNECT */
MQTT_PROP_RESPONSE_INFORMATION = 26, /* UTF-8 string : CONNACK */
MQTT_PROP_SERVER_REFERENCE = 28, /* UTF-8 string : CONNACK, DISCONNECT */
MQTT_PROP_REASON_STRING = 31, /* UTF-8 string : All except Will properties */
MQTT_PROP_RECEIVE_MAXIMUM = 33, /* 2 byte int : CONNECT, CONNACK */
MQTT_PROP_TOPIC_ALIAS_MAXIMUM = 34, /* 2 byte int : CONNECT, CONNACK */
MQTT_PROP_TOPIC_ALIAS = 35, /* 2 byte int : PUBLISH */
MQTT_PROP_MAXIMUM_QOS = 36, /* Byte : CONNACK */
MQTT_PROP_RETAIN_AVAILABLE = 37, /* Byte : CONNACK */
MQTT_PROP_USER_PROPERTY = 38, /* UTF-8 string pair : All */
MQTT_PROP_MAXIMUM_PACKET_SIZE = 39, /* 4 byte int : CONNECT, CONNACK */
MQTT_PROP_WILDCARD_SUB_AVAILABLE = 40, /* Byte : CONNACK */
MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE = 41, /* Byte : CONNACK */
MQTT_PROP_SHARED_SUB_AVAILABLE = 42, /* Byte : CONNACK */
};
enum mqtt5_property_type {
MQTT_PROP_TYPE_BYTE = 1,
MQTT_PROP_TYPE_INT16 = 2,
MQTT_PROP_TYPE_INT32 = 3,
MQTT_PROP_TYPE_VARINT = 4,
MQTT_PROP_TYPE_BINARY = 5,
MQTT_PROP_TYPE_STRING = 6,
MQTT_PROP_TYPE_STRING_PAIR = 7
};
enum mqtt5_sub_options {
MQTT_SUB_OPT_NO_LOCAL = 0x04,
MQTT_SUB_OPT_RETAIN_AS_PUBLISHED = 0x08,
MQTT_SUB_OPT_SEND_RETAIN_ALWAYS = 0x00,
MQTT_SUB_OPT_SEND_RETAIN_NEW = 0x10,
MQTT_SUB_OPT_SEND_RETAIN_NEVER = 0x20,
};
#define MQTT_MAX_PAYLOAD 268435455
#endif

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