From 383608613a4beb9a3f14b4f3850f4a14c83e9c22 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 1 Nov 2018 11:37:57 +0000 Subject: [PATCH] Client+lib will property support. --- client/client_shared.c | 7 ++++--- lib/linker.version | 1 + lib/mosquitto.h | 34 ++++++++++++++++++++++++++++++++++ lib/options.c | 8 +++++++- lib/will_mosq.c | 21 ++++++++++++++++++++- lib/will_mosq.h | 2 +- src/bridge.c | 8 ++++---- 7 files changed, 71 insertions(+), 10 deletions(-) diff --git a/client/client_shared.c b/client/client_shared.c index aa2529aa..df70a108 100644 --- a/client/client_shared.c +++ b/client/client_shared.c @@ -905,9 +905,11 @@ int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg) { int rc; - if(cfg->will_topic && mosquitto_will_set(mosq, cfg->will_topic, + mosquitto_opts_set(mosq, MOSQ_OPT_PROTOCOL_VERSION, &(cfg->protocol_version)); + + if(cfg->will_topic && mosquitto_will_set_with_properties(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(); @@ -954,7 +956,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; } diff --git a/lib/linker.version b/lib/linker.version index 9ec233cc..c12be67e 100644 --- a/lib/linker.version +++ b/lib/linker.version @@ -108,4 +108,5 @@ MOSQ_1.6 { mosquitto_string_to_command; mosquitto_string_to_property_info; mosquitto_subscribe_multiple; + mosquitto_will_set_with_properties; } MOSQ_1.5; diff --git a/lib/mosquitto.h b/lib/mosquitto.h index c7ba275d..fd658e4d 100644 --- a/lib/mosquitto.h +++ b/lib/mosquitto.h @@ -316,6 +316,40 @@ libmosq_EXPORT int mosquitto_reinitialise(struct mosquitto *mosq, const char *id */ libmosq_EXPORT int mosquitto_will_set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain); +/* + * Function: mosquitto_will_set_with_properties + * + * Configure will information for a mosquitto instance, with attached + * properties. By default, clients do not have a will. This must be called + * before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * topic - the topic on which to publish the will. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the will. + * retain - set to true to make the will a retained message. + * properties - list of MQTT 5 properties. Can be NULL. On success only, the + * property list becomes the property of libmosquitto once this + * function is called and will be freed by the library. The + * property list must be freed by the application on error. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8. + * MOSQ_ERR_NOT_SUPPORTED - if properties is not NULL and the client is not + * using MQTT v5 + * MOSQ_ERR_PROTOCOL - if a property is invalid for use with wills. + */ +libmosq_EXPORT int mosquitto_will_set_with_properties(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain, mosquitto_property *properties); + /* * Function: mosquitto_will_clear * diff --git a/lib/options.c b/lib/options.c index 5ec32302..12a19d8b 100644 --- a/lib/options.c +++ b/lib/options.c @@ -30,9 +30,15 @@ Contributors: int mosquitto_will_set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain) +{ + return mosquitto_will_set_with_properties(mosq, topic, payloadlen, payload, qos, retain, NULL); +} + + +int mosquitto_will_set_with_properties(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain, mosquitto_property *properties) { if(!mosq) return MOSQ_ERR_INVAL; - return will__set(mosq, topic, payloadlen, payload, qos, retain); + return will__set(mosq, topic, payloadlen, payload, qos, retain, properties); } diff --git a/lib/will_mosq.c b/lib/will_mosq.c index 7062b512..b9a13b9d 100644 --- a/lib/will_mosq.c +++ b/lib/will_mosq.c @@ -33,10 +33,12 @@ Contributors: #include "read_handle.h" #include "send_mosq.h" #include "util_mosq.h" +#include "will_mosq.h" -int will__set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain) +int will__set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain, mosquitto_property *properties) { int rc = MOSQ_ERR_SUCCESS; + mosquitto_property *p; if(!mosq || !topic) return MOSQ_ERR_INVAL; if(payloadlen < 0 || payloadlen > MQTT_MAX_PAYLOAD) return MOSQ_ERR_PAYLOAD_SIZE; @@ -45,9 +47,22 @@ int will__set(struct mosquitto *mosq, const char *topic, int payloadlen, const v if(mosquitto_pub_topic_check(topic)) return MOSQ_ERR_INVAL; if(mosquitto_validate_utf8(topic, strlen(topic))) return MOSQ_ERR_MALFORMED_UTF8; + if(properties){ + if(mosq->protocol != mosq_p_mqtt5){ + return MOSQ_ERR_NOT_SUPPORTED; + } + p = properties; + while(p){ + rc = mosquitto_property_command_check(CMD_WILL, p->identifier); + if(rc) return rc; + p = p->next; + } + } + if(mosq->will){ mosquitto__free(mosq->will->msg.topic); mosquitto__free(mosq->will->msg.payload); + mosquitto_property_free_all(&mosq->will->properties); mosquitto__free(mosq->will); } @@ -75,6 +90,8 @@ int will__set(struct mosquitto *mosq, const char *topic, int payloadlen, const v mosq->will->msg.qos = qos; mosq->will->msg.retain = retain; + mosq->will->properties = properties; + return MOSQ_ERR_SUCCESS; cleanup: @@ -99,6 +116,8 @@ int will__clear(struct mosquitto *mosq) mosquitto__free(mosq->will->msg.payload); mosq->will->msg.payload = NULL; + mosquitto_property_free_all(&mosq->will->properties); + mosquitto__free(mosq->will); mosq->will = NULL; diff --git a/lib/will_mosq.h b/lib/will_mosq.h index 7afb4089..e46d1bd9 100644 --- a/lib/will_mosq.h +++ b/lib/will_mosq.h @@ -20,7 +20,7 @@ Contributors: #include "mosquitto.h" #include "mosquitto_internal.h" -int will__set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain); +int will__set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain, mosquitto_property *properties); int will__clear(struct mosquitto *mosq); #endif diff --git a/src/bridge.c b/src/bridge.c index cbff3a9a..2446184d 100644 --- a/src/bridge.c +++ b/src/bridge.c @@ -159,7 +159,7 @@ int bridge__connect_step1(struct mosquitto_db *db, struct mosquitto *context) context->bridge->initial_notification_done = true; } notification_payload = '0'; - rc = will__set(context, context->bridge->notification_topic, 1, ¬ification_payload, 1, true); + rc = will__set(context, context->bridge->notification_topic, 1, ¬ification_payload, 1, true, NULL); if(rc != MOSQ_ERR_SUCCESS){ return rc; } @@ -177,7 +177,7 @@ int bridge__connect_step1(struct mosquitto_db *db, struct mosquitto *context) } notification_payload = '0'; - rc = will__set(context, notification_topic, 1, ¬ification_payload, 1, true); + rc = will__set(context, notification_topic, 1, ¬ification_payload, 1, true, NULL); mosquitto__free(notification_topic); if(rc != MOSQ_ERR_SUCCESS){ return rc; @@ -327,7 +327,7 @@ int bridge__connect(struct mosquitto_db *db, struct mosquitto *context) if (!context->bridge->notifications_local_only) { notification_payload = '0'; - rc = will__set(context, context->bridge->notification_topic, 1, ¬ification_payload, 1, true); + rc = will__set(context, context->bridge->notification_topic, 1, ¬ification_payload, 1, true, NULL); if(rc != MOSQ_ERR_SUCCESS){ return rc; } @@ -347,7 +347,7 @@ int bridge__connect(struct mosquitto_db *db, struct mosquitto *context) if (!context->bridge->notifications_local_only) { notification_payload = '0'; - rc = will__set(context, notification_topic, 1, ¬ification_payload, 1, true); + rc = will__set(context, notification_topic, 1, ¬ification_payload, 1, true, NULL); mosquitto__free(notification_topic); if(rc != MOSQ_ERR_SUCCESS){ return rc;