mirror of
https://github.com/eclipse-mosquitto/mosquitto.git
synced 2026-09-22 08:04:23 +08:00
Merge branch 'mqtt5' into develop
This commit is contained in:
+15
-5
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
Executable
+26
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Executable
+31
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 && \
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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}")
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
Reference in New Issue
Block a user