From 9fe8b95dcf7ce9cab1d7bf136d51456a52a06527 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Sun, 17 Mar 2024 15:07:27 +0000 Subject: [PATCH] Refactor property functions to common static library. --- apps/db_dump/CMakeLists.txt | 1 + apps/db_dump/print.c | 19 +- include/mosquitto/libcommon_properties.h | 5 + include/mosquitto/mqtt_protocol.h | 4 + lib/CMakeLists.txt | 1 + lib/Makefile | 2 +- lib/actions_publish.c | 3 +- lib/actions_subscribe.c | 3 +- lib/actions_unsubscribe.c | 3 +- lib/connect.c | 1 + lib/packet_datatypes.c | 16 - lib/packet_mosq.c | 2 +- lib/packet_mosq.h | 2 - lib/property_mosq.c | 1108 +--------------- lib/property_mosq.h | 29 - lib/send_connect.c | 8 +- lib/send_disconnect.c | 2 +- lib/send_mosq.c | 2 +- lib/send_publish.c | 11 +- lib/send_subscribe.c | 2 +- lib/send_unsubscribe.c | 2 +- libcommon/CMakeLists.txt | 2 + libcommon/Makefile | 2 + libcommon/mqtt_common.c | 39 + libcommon/property_common.c | 1138 +++++++++++++++++ libcommon/property_common.h | 47 + src/CMakeLists.txt | 1 + src/Makefile | 2 +- src/bridge.c | 2 +- src/loop.c | 3 +- src/persist_write_v5.c | 5 +- src/property_broker.c | 1 + src/send_auth.c | 2 +- src/send_connack.c | 2 +- src/send_suback.c | 2 +- src/send_unsuback.c | 2 +- test/unit/broker/CMakeLists.txt | 5 + test/unit/broker/Makefile | 2 +- test/unit/broker/persist_read_test.c | 1 + test/unit/lib/CMakeLists.txt | 3 +- test/unit/lib/Makefile | 4 +- test/unit/lib/property_read.c | 15 +- test/unit/lib/property_write.c | 37 +- test/unit/lib/test.c | 4 - test/unit/libcommon/CMakeLists.txt | 6 + test/unit/libcommon/Makefile | 4 +- test/unit/{lib => libcommon}/property_add.c | 13 +- test/unit/{lib => libcommon}/property_value.c | 3 +- test/unit/libcommon/test.c | 4 + test/unit/libcommon/topic_test.c | 2 +- 50 files changed, 1344 insertions(+), 1235 deletions(-) create mode 100644 libcommon/mqtt_common.c create mode 100644 libcommon/property_common.c create mode 100644 libcommon/property_common.h rename test/unit/{lib => libcommon}/property_add.c (98%) rename test/unit/{lib => libcommon}/property_value.c (99%) diff --git a/apps/db_dump/CMakeLists.txt b/apps/db_dump/CMakeLists.txt index 8d6e3143f..7554996e7 100644 --- a/apps/db_dump/CMakeLists.txt +++ b/apps/db_dump/CMakeLists.txt @@ -22,6 +22,7 @@ target_include_directories(mosquitto_db_dump PRIVATE "${mosquitto_SOURCE_DIR}/common" "${mosquitto_SOURCE_DIR}/include" "${mosquitto_SOURCE_DIR}/lib" + "${mosquitto_SOURCE_DIR}/libcommon" "${mosquitto_SOURCE_DIR}/src" "${OPENSSL_INCLUDE_DIR}" ) diff --git a/apps/db_dump/print.c b/apps/db_dump/print.c index ea33bac47..ed8186695 100644 --- a/apps/db_dump/print.c +++ b/apps/db_dump/print.c @@ -35,38 +35,39 @@ static void print__properties(mosquitto_property *properties) printf("\tProperties:\n"); while(properties){ - switch(properties->identifier){ + switch(mosquitto_property_identifier(properties)){ /* Only properties for base messages are valid for saving */ case MQTT_PROP_PAYLOAD_FORMAT_INDICATOR: - printf("\t\tPayload format indicator: %d\n", properties->value.i8); + printf("\t\tPayload format indicator: %d\n", mosquitto_property_byte_value(properties)); break; case MQTT_PROP_CONTENT_TYPE: - printf("\t\tContent type: %s\n", properties->value.s.v); + printf("\t\tContent type: %s\n", mosquitto_property_string_value(properties)); break; case MQTT_PROP_RESPONSE_TOPIC: - printf("\t\tResponse topic: %s\n", properties->value.s.v); + printf("\t\tResponse topic: %s\n", mosquitto_property_string_value(properties)); break; case MQTT_PROP_CORRELATION_DATA: printf("\t\tCorrelation data: "); - for(i=0; ivalue.bin.len; i++){ - printf("%02X", properties->value.bin.v[i]); + const uint8_t *bin = mosquitto_property_binary_value(properties); + for(i=0; iname.v, properties->value.s.v); + printf("\t\tUser property: %s , %s\n", mosquitto_property_string_name(properties), mosquitto_property_string_value(properties)); break; default: - printf("\t\tInvalid property type: %d\n", properties->identifier); + printf("\t\tInvalid property type: %d\n", mosquitto_property_identifier(properties)); break; } - properties = properties->next; + properties = mosquitto_property_next(properties); } } diff --git a/include/mosquitto/libcommon_properties.h b/include/mosquitto/libcommon_properties.h index 7de718b08..17403cb6e 100644 --- a/include/mosquitto/libcommon_properties.h +++ b/include/mosquitto/libcommon_properties.h @@ -745,6 +745,11 @@ libmosq_EXPORT const char *mosquitto_property_identifier_to_string(int identifie libmosq_EXPORT int mosquitto_string_to_property_info(const char *propname, int *identifier, int *type); +void mosquitto_property_free(mosquitto_property **property); +unsigned int mosquitto_property_get_length(const mosquitto_property *property); +unsigned int mosquitto_property_get_length_all(const mosquitto_property *property); +unsigned int mosquitto_property_get_remaining_length(const mosquitto_property *props); + #ifdef __cplusplus } #endif diff --git a/include/mosquitto/mqtt_protocol.h b/include/mosquitto/mqtt_protocol.h index ebcf24736..61125418c 100644 --- a/include/mosquitto/mqtt_protocol.h +++ b/include/mosquitto/mqtt_protocol.h @@ -19,6 +19,8 @@ Contributors: #ifndef MQTT_PROTOCOL_H #define MQTT_PROTOCOL_H +#include + /* * File: mosquitto/mqtt_protocol.h * @@ -289,4 +291,6 @@ enum mqtt5_sub_options { #define MQTT_SUB_OPT_SET(opt, val) ((opt) |= val) #define MQTT_SUB_OPT_CLEAR(opt, val) ((opt) = (opt) & !val) +unsigned int mosquitto_varint_bytes(uint32_t size); + #endif diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 2216a1666..d9ba799c6 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -108,6 +108,7 @@ target_include_directories(libmosquitto PRIVATE "${mosquitto_SOURCE_DIR}" "${mosquitto_SOURCE_DIR}/common" + "${mosquitto_SOURCE_DIR}/libcommon" ) if(WITH_BUNDLED_DEPS) diff --git a/lib/Makefile b/lib/Makefile index 36fc6bd07..2efd62daa 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -2,7 +2,7 @@ R=.. include ${R}/config.mk LOCAL_CFLAGS+=-fPIC -LOCAL_CPPFLAGS+= +LOCAL_CPPFLAGS+=-I${R}/libcommon LOCAL_LDFLAGS+=-Wl,--version-script=linker.version -Wl,-soname,libmosquitto.so.$(SOVERSION) -fPIC -shared LOCAL_LIBADD+=-lcjson -lc ${LIB_ARGON2} ${LIBMOSQ_COMMON} STATIC_LIB_DEPS:= diff --git a/lib/actions_publish.c b/lib/actions_publish.c index 08c5f1c2d..250a847dd 100644 --- a/lib/actions_publish.c +++ b/lib/actions_publish.c @@ -26,6 +26,7 @@ Contributors: #include "mosquitto/mqtt_protocol.h" #include "packet_mosq.h" #include "property_mosq.h" +#include "property_common.h" #include "send_mosq.h" #include "util_mosq.h" @@ -98,7 +99,7 @@ int mosquitto_publish_v5(struct mosquitto *mosq, int *mid, const char *topic, in } if(mosq->maximum_packet_size > 0){ - remaining_length = 1 + 2+(uint32_t)tlen + (uint32_t)payloadlen + property__get_length_all(outgoing_properties); + remaining_length = 1 + 2+(uint32_t)tlen + (uint32_t)payloadlen + mosquitto_property_get_length_all(outgoing_properties); if(qos > 0){ remaining_length++; } diff --git a/lib/actions_subscribe.c b/lib/actions_subscribe.c index 9067bcc57..e415595a6 100644 --- a/lib/actions_subscribe.c +++ b/lib/actions_subscribe.c @@ -23,6 +23,7 @@ Contributors: #include "mosquitto/mqtt_protocol.h" #include "net_mosq.h" #include "packet_mosq.h" +#include "property_common.h" #include "send_mosq.h" @@ -77,7 +78,7 @@ int mosquitto_subscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count } if(mosq->maximum_packet_size > 0){ - remaining_length += 2 + property__get_length_all(outgoing_properties); + remaining_length += 2 + mosquitto_property_get_length_all(outgoing_properties); if(packet__check_oversize(mosq, remaining_length)){ return MOSQ_ERR_OVERSIZE_PACKET; } diff --git a/lib/actions_unsubscribe.c b/lib/actions_unsubscribe.c index 4f8037737..0c5d7d72c 100644 --- a/lib/actions_unsubscribe.c +++ b/lib/actions_unsubscribe.c @@ -25,6 +25,7 @@ Contributors: #include "net_mosq.h" #include "packet_mosq.h" #include "property_mosq.h" +#include "property_common.h" #include "send_mosq.h" @@ -73,7 +74,7 @@ int mosquitto_unsubscribe_multiple(struct mosquitto *mosq, int *mid, int sub_cou } if(mosq->maximum_packet_size > 0){ - remaining_length += 2U + property__get_length_all(outgoing_properties); + remaining_length += 2U + mosquitto_property_get_length_all(outgoing_properties); if(packet__check_oversize(mosq, remaining_length)){ return MOSQ_ERR_OVERSIZE_PACKET; } diff --git a/lib/connect.c b/lib/connect.c index cc509e86c..808902f31 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -27,6 +27,7 @@ Contributors: #include "logging_mosq.h" #include "messages_mosq.h" #include "packet_mosq.h" +#include "property_common.h" #include "net_mosq.h" #include "send_mosq.h" #include "socks_mosq.h" diff --git a/lib/packet_datatypes.c b/lib/packet_datatypes.c index 90d2d6105..839a40214 100644 --- a/lib/packet_datatypes.c +++ b/lib/packet_datatypes.c @@ -251,19 +251,3 @@ int packet__write_varint(struct mosquitto__packet *packet, uint32_t word) } return MOSQ_ERR_SUCCESS; } - - -unsigned int packet__varint_bytes(uint32_t word) -{ - if(word < 128){ - return 1; - }else if(word < 16384){ - return 2; - }else if(word < 2097152){ - return 3; - }else if(word < 268435456){ - return 4; - }else{ - return 5; - } -} diff --git a/lib/packet_mosq.c b/lib/packet_mosq.c index d9f114fae..f2a944f57 100644 --- a/lib/packet_mosq.c +++ b/lib/packet_mosq.c @@ -227,7 +227,7 @@ int packet__check_oversize(struct mosquitto *mosq, uint32_t remaining_length) if(mosq->maximum_packet_size == 0) return MOSQ_ERR_SUCCESS; - len = remaining_length + packet__varint_bytes(remaining_length); + len = remaining_length + mosquitto_varint_bytes(remaining_length); if(len > mosq->maximum_packet_size){ return MOSQ_ERR_OVERSIZE_PACKET; }else{ diff --git a/lib/packet_mosq.h b/lib/packet_mosq.h index cf87c9ebc..cd1c8fdc5 100644 --- a/lib/packet_mosq.h +++ b/lib/packet_mosq.h @@ -45,8 +45,6 @@ void packet__write_uint16(struct mosquitto__packet *packet, uint16_t word); void packet__write_uint32(struct mosquitto__packet *packet, uint32_t word); int packet__write_varint(struct mosquitto__packet *packet, uint32_t word); -unsigned int packet__varint_bytes(uint32_t word); - int packet__write(struct mosquitto *mosq); int packet__read(struct mosquitto *mosq); diff --git a/lib/property_mosq.c b/lib/property_mosq.c index 8741f3206..3d51ee41d 100644 --- a/lib/property_mosq.c +++ b/lib/property_mosq.c @@ -28,6 +28,7 @@ Contributors: #include "logging_mosq.h" #include "mosquitto/mqtt_protocol.h" #include "packet_mosq.h" +#include "property_common.h" #include "property_mosq.h" @@ -201,121 +202,6 @@ int property__read_all(int command, struct mosquitto__packet_in *packet, mosquit } -void property__free(mosquitto_property **property) -{ - if(!property || !(*property)) return; - - switch((*property)->property_type){ - case MQTT_PROP_TYPE_STRING: - mosquitto_FREE((*property)->value.s.v); - break; - - case MQTT_PROP_TYPE_BINARY: - mosquitto_FREE((*property)->value.bin.v); - break; - - case MQTT_PROP_TYPE_STRING_PAIR: - mosquitto_FREE((*property)->name.v); - mosquitto_FREE((*property)->value.s.v); - break; - - case MQTT_PROP_TYPE_BYTE: - case MQTT_PROP_TYPE_INT16: - case MQTT_PROP_TYPE_INT32: - case MQTT_PROP_TYPE_VARINT: - /* Nothing to free */ - break; - } - - SAFE_FREE(*property); -} - - -BROKER_EXPORT void mosquitto_property_free_all(mosquitto_property **property) -{ - mosquitto_property *p, *next; - - if(!property) return; - - p = *property; - while(p){ - next = p->next; - property__free(&p); - p = next; - } - *property = NULL; -} - - -unsigned int property__get_length(const mosquitto_property *property) -{ - if(!property) return 0; - - switch(property->property_type){ - case MQTT_PROP_TYPE_BYTE: - return 2; /* 1 (identifier) + 1 byte */ - - case MQTT_PROP_TYPE_INT16: - return 3; /* 1 (identifier) + 2 bytes */ - - case MQTT_PROP_TYPE_INT32: - return 5; /* 1 (identifier) + 4 bytes */ - - case MQTT_PROP_TYPE_VARINT: - if(property->value.varint < 128){ - return 2; - }else if(property->value.varint < 16384){ - return 3; - }else if(property->value.varint < 2097152){ - return 4; - }else if(property->value.varint < 268435456){ - return 5; - }else{ - return 0; - } - - case MQTT_PROP_TYPE_BINARY: - return 3U + property->value.bin.len; /* 1 + 2 bytes (len) + X bytes (payload) */ - - case MQTT_PROP_TYPE_STRING: - return 3U + property->value.s.len; /* 1 + 2 bytes (len) + X bytes (string) */ - - case MQTT_PROP_TYPE_STRING_PAIR: - return 5U + property->value.s.len + property->name.len; /* 1 + 2*(2 bytes (len) + X bytes (string))*/ - - default: - return 0; - } - return 0; -} - - -unsigned int property__get_length_all(const mosquitto_property *property) -{ - const mosquitto_property *p; - unsigned int len = 0; - - p = property; - while(p){ - len += property__get_length(p); - p = p->next; - } - return len; -} - - -/* Return the number of bytes we need to add on to the remaining length when - * encoding these properties. */ -unsigned int property__get_remaining_length(const mosquitto_property *props) -{ - unsigned int proplen, varbytes; - - proplen = property__get_length_all(props); - varbytes = packet__varint_bytes(proplen); - return proplen + varbytes; -} - - static int property__write(struct mosquitto__packet *packet, const mosquitto_property *property) { int rc; @@ -370,7 +256,7 @@ int property__write_all(struct mosquitto__packet *packet, const mosquitto_proper const mosquitto_property *p; if(write_len){ - rc = packet__write_varint(packet, property__get_length_all(properties)); + rc = packet__write_varint(packet, mosquitto_property_get_length_all(properties)); if(rc) return rc; } @@ -383,993 +269,3 @@ int property__write_all(struct mosquitto__packet *packet, const mosquitto_proper return MOSQ_ERR_SUCCESS; } - - -BROKER_EXPORT int mosquitto_property_check_command(int command, int identifier) -{ - switch(identifier){ - case MQTT_PROP_PAYLOAD_FORMAT_INDICATOR: - case MQTT_PROP_MESSAGE_EXPIRY_INTERVAL: - case MQTT_PROP_CONTENT_TYPE: - case MQTT_PROP_RESPONSE_TOPIC: - case MQTT_PROP_CORRELATION_DATA: - if(command != CMD_PUBLISH && command != CMD_WILL){ - return MOSQ_ERR_PROTOCOL; - } - break; - - case MQTT_PROP_SUBSCRIPTION_IDENTIFIER: - if(command != CMD_PUBLISH && command != CMD_SUBSCRIBE){ - return MOSQ_ERR_PROTOCOL; - } - break; - - case MQTT_PROP_SESSION_EXPIRY_INTERVAL: - if(command != CMD_CONNECT && command != CMD_CONNACK && command != CMD_DISCONNECT){ - return MOSQ_ERR_PROTOCOL; - } - break; - - case MQTT_PROP_AUTHENTICATION_METHOD: - case MQTT_PROP_AUTHENTICATION_DATA: - if(command != CMD_CONNECT && command != CMD_CONNACK && command != CMD_AUTH){ - return MOSQ_ERR_PROTOCOL; - } - break; - - case MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER: - case MQTT_PROP_SERVER_KEEP_ALIVE: - case MQTT_PROP_RESPONSE_INFORMATION: - case MQTT_PROP_MAXIMUM_QOS: - case MQTT_PROP_RETAIN_AVAILABLE: - case MQTT_PROP_WILDCARD_SUB_AVAILABLE: - case MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE: - case MQTT_PROP_SHARED_SUB_AVAILABLE: - if(command != CMD_CONNACK){ - return MOSQ_ERR_PROTOCOL; - } - break; - - case MQTT_PROP_WILL_DELAY_INTERVAL: - if(command != CMD_WILL){ - return MOSQ_ERR_PROTOCOL; - } - break; - - case MQTT_PROP_REQUEST_PROBLEM_INFORMATION: - case MQTT_PROP_REQUEST_RESPONSE_INFORMATION: - if(command != CMD_CONNECT){ - return MOSQ_ERR_PROTOCOL; - } - break; - - case MQTT_PROP_SERVER_REFERENCE: - if(command != CMD_CONNACK && command != CMD_DISCONNECT){ - return MOSQ_ERR_PROTOCOL; - } - break; - - case MQTT_PROP_REASON_STRING: - if(command == CMD_CONNECT || command == CMD_PUBLISH || command == CMD_SUBSCRIBE || command == CMD_UNSUBSCRIBE){ - return MOSQ_ERR_PROTOCOL; - } - break; - - case MQTT_PROP_RECEIVE_MAXIMUM: - case MQTT_PROP_TOPIC_ALIAS_MAXIMUM: - case MQTT_PROP_MAXIMUM_PACKET_SIZE: - if(command != CMD_CONNECT && command != CMD_CONNACK){ - return MOSQ_ERR_PROTOCOL; - } - break; - - case MQTT_PROP_TOPIC_ALIAS: - if(command != CMD_PUBLISH){ - return MOSQ_ERR_PROTOCOL; - } - break; - - case MQTT_PROP_USER_PROPERTY: - break; - - default: - return MOSQ_ERR_PROTOCOL; - } - return MOSQ_ERR_SUCCESS; -} - - -BROKER_EXPORT const char *mosquitto_property_identifier_to_string(int identifier) -{ - switch(identifier){ - case MQTT_PROP_PAYLOAD_FORMAT_INDICATOR: - return "payload-format-indicator"; - case MQTT_PROP_MESSAGE_EXPIRY_INTERVAL: - return "message-expiry-interval"; - case MQTT_PROP_CONTENT_TYPE: - return "content-type"; - case MQTT_PROP_RESPONSE_TOPIC: - return "response-topic"; - case MQTT_PROP_CORRELATION_DATA: - return "correlation-data"; - case MQTT_PROP_SUBSCRIPTION_IDENTIFIER: - return "subscription-identifier"; - case MQTT_PROP_SESSION_EXPIRY_INTERVAL: - return "session-expiry-interval"; - case MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER: - return "assigned-client-identifier"; - case MQTT_PROP_SERVER_KEEP_ALIVE: - return "server-keep-alive"; - case MQTT_PROP_AUTHENTICATION_METHOD: - return "authentication-method"; - case MQTT_PROP_AUTHENTICATION_DATA: - return "authentication-data"; - case MQTT_PROP_REQUEST_PROBLEM_INFORMATION: - return "request-problem-information"; - case MQTT_PROP_WILL_DELAY_INTERVAL: - return "will-delay-interval"; - case MQTT_PROP_REQUEST_RESPONSE_INFORMATION: - return "request-response-information"; - case MQTT_PROP_RESPONSE_INFORMATION: - return "response-information"; - case MQTT_PROP_SERVER_REFERENCE: - return "server-reference"; - case MQTT_PROP_REASON_STRING: - return "reason-string"; - case MQTT_PROP_RECEIVE_MAXIMUM: - return "receive-maximum"; - case MQTT_PROP_TOPIC_ALIAS_MAXIMUM: - return "topic-alias-maximum"; - case MQTT_PROP_TOPIC_ALIAS: - return "topic-alias"; - case MQTT_PROP_MAXIMUM_QOS: - return "maximum-qos"; - case MQTT_PROP_RETAIN_AVAILABLE: - return "retain-available"; - case MQTT_PROP_USER_PROPERTY: - return "user-property"; - case MQTT_PROP_MAXIMUM_PACKET_SIZE: - return "maximum-packet-size"; - case MQTT_PROP_WILDCARD_SUB_AVAILABLE: - return "wildcard-subscription-available"; - case MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE: - return "subscription-identifier-available"; - case MQTT_PROP_SHARED_SUB_AVAILABLE: - return "shared-subscription-available"; - default: - return NULL; - } -} - - -BROKER_EXPORT int mosquitto_string_to_property_info(const char *propname, int *identifier, int *type) -{ - if(!propname) return MOSQ_ERR_INVAL; - - if(!strcasecmp(propname, "payload-format-indicator")){ - *identifier = MQTT_PROP_PAYLOAD_FORMAT_INDICATOR; - *type = MQTT_PROP_TYPE_BYTE; - }else if(!strcasecmp(propname, "message-expiry-interval")){ - *identifier = MQTT_PROP_MESSAGE_EXPIRY_INTERVAL; - *type = MQTT_PROP_TYPE_INT32; - }else if(!strcasecmp(propname, "content-type")){ - *identifier = MQTT_PROP_CONTENT_TYPE; - *type = MQTT_PROP_TYPE_STRING; - }else if(!strcasecmp(propname, "response-topic")){ - *identifier = MQTT_PROP_RESPONSE_TOPIC; - *type = MQTT_PROP_TYPE_STRING; - }else if(!strcasecmp(propname, "correlation-data")){ - *identifier = MQTT_PROP_CORRELATION_DATA; - *type = MQTT_PROP_TYPE_BINARY; - }else if(!strcasecmp(propname, "subscription-identifier")){ - *identifier = MQTT_PROP_SUBSCRIPTION_IDENTIFIER; - *type = MQTT_PROP_TYPE_VARINT; - }else if(!strcasecmp(propname, "session-expiry-interval")){ - *identifier = MQTT_PROP_SESSION_EXPIRY_INTERVAL; - *type = MQTT_PROP_TYPE_INT32; - }else if(!strcasecmp(propname, "assigned-client-identifier")){ - *identifier = MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER; - *type = MQTT_PROP_TYPE_STRING; - }else if(!strcasecmp(propname, "server-keep-alive")){ - *identifier = MQTT_PROP_SERVER_KEEP_ALIVE; - *type = MQTT_PROP_TYPE_INT16; - }else if(!strcasecmp(propname, "authentication-method")){ - *identifier = MQTT_PROP_AUTHENTICATION_METHOD; - *type = MQTT_PROP_TYPE_STRING; - }else if(!strcasecmp(propname, "authentication-data")){ - *identifier = MQTT_PROP_AUTHENTICATION_DATA; - *type = MQTT_PROP_TYPE_BINARY; - }else if(!strcasecmp(propname, "request-problem-information")){ - *identifier = MQTT_PROP_REQUEST_PROBLEM_INFORMATION; - *type = MQTT_PROP_TYPE_BYTE; - }else if(!strcasecmp(propname, "will-delay-interval")){ - *identifier = MQTT_PROP_WILL_DELAY_INTERVAL; - *type = MQTT_PROP_TYPE_INT32; - }else if(!strcasecmp(propname, "request-response-information")){ - *identifier = MQTT_PROP_REQUEST_RESPONSE_INFORMATION; - *type = MQTT_PROP_TYPE_BYTE; - }else if(!strcasecmp(propname, "response-information")){ - *identifier = MQTT_PROP_RESPONSE_INFORMATION; - *type = MQTT_PROP_TYPE_STRING; - }else if(!strcasecmp(propname, "server-reference")){ - *identifier = MQTT_PROP_SERVER_REFERENCE; - *type = MQTT_PROP_TYPE_STRING; - }else if(!strcasecmp(propname, "reason-string")){ - *identifier = MQTT_PROP_REASON_STRING; - *type = MQTT_PROP_TYPE_STRING; - }else if(!strcasecmp(propname, "receive-maximum")){ - *identifier = MQTT_PROP_RECEIVE_MAXIMUM; - *type = MQTT_PROP_TYPE_INT16; - }else if(!strcasecmp(propname, "topic-alias-maximum")){ - *identifier = MQTT_PROP_TOPIC_ALIAS_MAXIMUM; - *type = MQTT_PROP_TYPE_INT16; - }else if(!strcasecmp(propname, "topic-alias")){ - *identifier = MQTT_PROP_TOPIC_ALIAS; - *type = MQTT_PROP_TYPE_INT16; - }else if(!strcasecmp(propname, "maximum-qos")){ - *identifier = MQTT_PROP_MAXIMUM_QOS; - *type = MQTT_PROP_TYPE_BYTE; - }else if(!strcasecmp(propname, "retain-available")){ - *identifier = MQTT_PROP_RETAIN_AVAILABLE; - *type = MQTT_PROP_TYPE_BYTE; - }else if(!strcasecmp(propname, "user-property")){ - *identifier = MQTT_PROP_USER_PROPERTY; - *type = MQTT_PROP_TYPE_STRING_PAIR; - }else if(!strcasecmp(propname, "maximum-packet-size")){ - *identifier = MQTT_PROP_MAXIMUM_PACKET_SIZE; - *type = MQTT_PROP_TYPE_INT32; - }else if(!strcasecmp(propname, "wildcard-subscription-available")){ - *identifier = MQTT_PROP_WILDCARD_SUB_AVAILABLE; - *type = MQTT_PROP_TYPE_BYTE; - }else if(!strcasecmp(propname, "subscription-identifier-available")){ - *identifier = MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE; - *type = MQTT_PROP_TYPE_BYTE; - }else if(!strcasecmp(propname, "shared-subscription-available")){ - *identifier = MQTT_PROP_SHARED_SUB_AVAILABLE; - *type = MQTT_PROP_TYPE_BYTE; - }else{ - return MOSQ_ERR_INVAL; - } - return MOSQ_ERR_SUCCESS; -} - - -static void property__add(mosquitto_property **proplist, struct mqtt5__property *prop) -{ - mosquitto_property *p; - - if(!(*proplist)){ - *proplist = prop; - } - - p = *proplist; - while(p->next){ - p = p->next; - } - p->next = prop; - prop->next = NULL; -} - - -BROKER_EXPORT int mosquitto_property_add_byte(mosquitto_property **proplist, int identifier, uint8_t value) -{ - mosquitto_property *prop; - - if(!proplist) return MOSQ_ERR_INVAL; - if(identifier != MQTT_PROP_PAYLOAD_FORMAT_INDICATOR - && identifier != MQTT_PROP_REQUEST_PROBLEM_INFORMATION - && identifier != MQTT_PROP_REQUEST_RESPONSE_INFORMATION - && identifier != MQTT_PROP_MAXIMUM_QOS - && identifier != MQTT_PROP_RETAIN_AVAILABLE - && identifier != MQTT_PROP_WILDCARD_SUB_AVAILABLE - && identifier != MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE - && identifier != MQTT_PROP_SHARED_SUB_AVAILABLE){ - return MOSQ_ERR_INVAL; - } - - prop = mosquitto_calloc(1, sizeof(mosquitto_property)); - if(!prop) return MOSQ_ERR_NOMEM; - - prop->client_generated = true; - prop->identifier = identifier; - prop->value.i8 = value; - prop->property_type = MQTT_PROP_TYPE_BYTE; - - property__add(proplist, prop); - return MOSQ_ERR_SUCCESS; -} - - -BROKER_EXPORT int mosquitto_property_add_int16(mosquitto_property **proplist, int identifier, uint16_t value) -{ - mosquitto_property *prop; - - if(!proplist) return MOSQ_ERR_INVAL; - if(identifier != MQTT_PROP_SERVER_KEEP_ALIVE - && identifier != MQTT_PROP_RECEIVE_MAXIMUM - && identifier != MQTT_PROP_TOPIC_ALIAS_MAXIMUM - && identifier != MQTT_PROP_TOPIC_ALIAS){ - return MOSQ_ERR_INVAL; - } - - prop = mosquitto_calloc(1, sizeof(mosquitto_property)); - if(!prop) return MOSQ_ERR_NOMEM; - - prop->client_generated = true; - prop->identifier = identifier; - prop->value.i16 = value; - prop->property_type = MQTT_PROP_TYPE_INT16; - - property__add(proplist, prop); - return MOSQ_ERR_SUCCESS; -} - - -BROKER_EXPORT int mosquitto_property_add_int32(mosquitto_property **proplist, int identifier, uint32_t value) -{ - mosquitto_property *prop; - - if(!proplist) return MOSQ_ERR_INVAL; - if(identifier != MQTT_PROP_MESSAGE_EXPIRY_INTERVAL - && identifier != MQTT_PROP_SESSION_EXPIRY_INTERVAL - && identifier != MQTT_PROP_WILL_DELAY_INTERVAL - && identifier != MQTT_PROP_MAXIMUM_PACKET_SIZE){ - - return MOSQ_ERR_INVAL; - } - - prop = mosquitto_calloc(1, sizeof(mosquitto_property)); - if(!prop) return MOSQ_ERR_NOMEM; - - prop->client_generated = true; - prop->identifier = identifier; - prop->value.i32 = value; - prop->property_type = MQTT_PROP_TYPE_INT32; - - property__add(proplist, prop); - return MOSQ_ERR_SUCCESS; -} - - -BROKER_EXPORT int mosquitto_property_add_varint(mosquitto_property **proplist, int identifier, uint32_t value) -{ - mosquitto_property *prop; - - if(!proplist || value > 268435455) return MOSQ_ERR_INVAL; - if(identifier != MQTT_PROP_SUBSCRIPTION_IDENTIFIER) return MOSQ_ERR_INVAL; - - prop = mosquitto_calloc(1, sizeof(mosquitto_property)); - if(!prop) return MOSQ_ERR_NOMEM; - - prop->client_generated = true; - prop->identifier = identifier; - prop->value.varint = value; - prop->property_type = MQTT_PROP_TYPE_VARINT; - - property__add(proplist, prop); - return MOSQ_ERR_SUCCESS; -} - - -BROKER_EXPORT int mosquitto_property_add_binary(mosquitto_property **proplist, int identifier, const void *value, uint16_t len) -{ - mosquitto_property *prop; - - if(!proplist) return MOSQ_ERR_INVAL; - if(identifier != MQTT_PROP_CORRELATION_DATA - && identifier != MQTT_PROP_AUTHENTICATION_DATA){ - - return MOSQ_ERR_INVAL; - } - - prop = mosquitto_calloc(1, sizeof(mosquitto_property)); - if(!prop) return MOSQ_ERR_NOMEM; - - prop->client_generated = true; - prop->identifier = identifier; - prop->property_type = MQTT_PROP_TYPE_BINARY; - - if(len){ - prop->value.bin.v = mosquitto_malloc(len); - if(!prop->value.bin.v){ - mosquitto_FREE(prop); - return MOSQ_ERR_NOMEM; - } - - memcpy(prop->value.bin.v, value, len); - prop->value.bin.len = len; - } - - property__add(proplist, prop); - return MOSQ_ERR_SUCCESS; -} - - -BROKER_EXPORT int mosquitto_property_add_string(mosquitto_property **proplist, int identifier, const char *value) -{ - mosquitto_property *prop; - size_t slen = 0; - - if(!proplist) return MOSQ_ERR_INVAL; - if(value){ - slen = strlen(value); - if(mosquitto_validate_utf8(value, (int)slen)) return MOSQ_ERR_MALFORMED_UTF8; - } - - if(identifier != MQTT_PROP_CONTENT_TYPE - && identifier != MQTT_PROP_RESPONSE_TOPIC - && identifier != MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER - && identifier != MQTT_PROP_AUTHENTICATION_METHOD - && identifier != MQTT_PROP_RESPONSE_INFORMATION - && identifier != MQTT_PROP_SERVER_REFERENCE - && identifier != MQTT_PROP_REASON_STRING){ - - return MOSQ_ERR_INVAL; - } - - prop = mosquitto_calloc(1, sizeof(mosquitto_property)); - if(!prop) return MOSQ_ERR_NOMEM; - - prop->client_generated = true; - prop->identifier = identifier; - prop->property_type = MQTT_PROP_TYPE_STRING; - if(value && slen > 0){ - prop->value.s.v = mosquitto_strdup(value); - if(!prop->value.s.v){ - mosquitto_FREE(prop); - return MOSQ_ERR_NOMEM; - } - prop->value.s.len = (uint16_t)slen; - } - - property__add(proplist, prop); - return MOSQ_ERR_SUCCESS; -} - - -BROKER_EXPORT int mosquitto_property_add_string_pair(mosquitto_property **proplist, int identifier, const char *name, const char *value) -{ - mosquitto_property *prop; - size_t slen_name = 0, slen_value = 0; - - if(!proplist) return MOSQ_ERR_INVAL; - if(identifier != MQTT_PROP_USER_PROPERTY) return MOSQ_ERR_INVAL; - if(name){ - slen_name = strlen(name); - if(mosquitto_validate_utf8(name, (int)slen_name)) return MOSQ_ERR_MALFORMED_UTF8; - } - if(value){ - if(mosquitto_validate_utf8(value, (int)slen_value)) return MOSQ_ERR_MALFORMED_UTF8; - } - - prop = mosquitto_calloc(1, sizeof(mosquitto_property)); - if(!prop) return MOSQ_ERR_NOMEM; - - prop->client_generated = true; - prop->identifier = identifier; - prop->property_type = MQTT_PROP_TYPE_STRING_PAIR; - - if(name){ - prop->name.v = mosquitto_strdup(name); - if(!prop->name.v){ - mosquitto_FREE(prop); - return MOSQ_ERR_NOMEM; - } - prop->name.len = (uint16_t)strlen(name); - } - - if(value){ - prop->value.s.v = mosquitto_strdup(value); - if(!prop->value.s.v){ - mosquitto_FREE(prop->name.v); - mosquitto_FREE(prop); - return MOSQ_ERR_NOMEM; - } - prop->value.s.len = (uint16_t)strlen(value); - } - - property__add(proplist, prop); - return MOSQ_ERR_SUCCESS; -} - -BROKER_EXPORT int mosquitto_property_check_all(int command, const mosquitto_property *properties) -{ - const mosquitto_property *p, *tail; - int rc; - - p = properties; - - while(p){ - /* Validity checks */ - if(p->identifier == MQTT_PROP_REQUEST_PROBLEM_INFORMATION - || p->identifier == MQTT_PROP_PAYLOAD_FORMAT_INDICATOR - || p->identifier == MQTT_PROP_REQUEST_RESPONSE_INFORMATION - || p->identifier == MQTT_PROP_MAXIMUM_QOS - || p->identifier == MQTT_PROP_RETAIN_AVAILABLE - || p->identifier == MQTT_PROP_WILDCARD_SUB_AVAILABLE - || p->identifier == MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE - || p->identifier == MQTT_PROP_SHARED_SUB_AVAILABLE){ - - if(p->value.i8 > 1){ - return MOSQ_ERR_PROTOCOL; - } - }else if(p->identifier == MQTT_PROP_MAXIMUM_PACKET_SIZE){ - if( p->value.i32 == 0){ - return MOSQ_ERR_PROTOCOL; - } - }else if(p->identifier == MQTT_PROP_RECEIVE_MAXIMUM - || p->identifier == MQTT_PROP_TOPIC_ALIAS){ - - if(p->value.i16 == 0){ - return MOSQ_ERR_PROTOCOL; - } - } - - /* Check for properties on incorrect commands */ - rc = mosquitto_property_check_command(command, p->identifier); - if(rc) return rc; - - /* Check for duplicates */ - if(p->identifier != MQTT_PROP_USER_PROPERTY){ - tail = p->next; - while(tail){ - if(p->identifier == tail->identifier){ - return MOSQ_ERR_DUPLICATE_PROPERTY; - } - tail = tail->next; - } - } - - p = p->next; - } - - return MOSQ_ERR_SUCCESS; -} - -static const mosquitto_property *property__get_property(const mosquitto_property *proplist, int identifier, bool skip_first) -{ - const mosquitto_property *p; - bool is_first = true; - - p = proplist; - - while(p){ - if(p->identifier == identifier){ - if(!is_first || !skip_first){ - return p; - } - is_first = false; - } - p = p->next; - } - return NULL; -} - - -BROKER_EXPORT int mosquitto_property_identifier(const mosquitto_property *property) -{ - if(property == NULL) return 0; - - return property->identifier; -} - - -BROKER_EXPORT int mosquitto_property_type(const mosquitto_property *property) -{ - if(property == NULL) return 0; - - return property->property_type; -} - - -BROKER_EXPORT mosquitto_property *mosquitto_property_next(const mosquitto_property *proplist) -{ - if(proplist == NULL) return NULL; - - return proplist->next; -} - - -BROKER_EXPORT const mosquitto_property *mosquitto_property_read_byte(const mosquitto_property *proplist, int identifier, uint8_t *value, bool skip_first) -{ - const mosquitto_property *p; - if(!proplist) return NULL; - - p = property__get_property(proplist, identifier, skip_first); - if(!p) return NULL; - if(p->identifier != MQTT_PROP_PAYLOAD_FORMAT_INDICATOR - && p->identifier != MQTT_PROP_REQUEST_PROBLEM_INFORMATION - && p->identifier != MQTT_PROP_REQUEST_RESPONSE_INFORMATION - && p->identifier != MQTT_PROP_MAXIMUM_QOS - && p->identifier != MQTT_PROP_RETAIN_AVAILABLE - && p->identifier != MQTT_PROP_WILDCARD_SUB_AVAILABLE - && p->identifier != MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE - && p->identifier != MQTT_PROP_SHARED_SUB_AVAILABLE){ - return NULL; - } - - if(value) *value = p->value.i8; - - return p; -} - - -BROKER_EXPORT const mosquitto_property *mosquitto_property_read_int16(const mosquitto_property *proplist, int identifier, uint16_t *value, bool skip_first) -{ - const mosquitto_property *p; - if(!proplist) return NULL; - - p = property__get_property(proplist, identifier, skip_first); - if(!p) return NULL; - if(p->identifier != MQTT_PROP_SERVER_KEEP_ALIVE - && p->identifier != MQTT_PROP_RECEIVE_MAXIMUM - && p->identifier != MQTT_PROP_TOPIC_ALIAS_MAXIMUM - && p->identifier != MQTT_PROP_TOPIC_ALIAS){ - return NULL; - } - - if(value) *value = p->value.i16; - - return p; -} - - -BROKER_EXPORT const mosquitto_property *mosquitto_property_read_int32(const mosquitto_property *proplist, int identifier, uint32_t *value, bool skip_first) -{ - const mosquitto_property *p; - if(!proplist) return NULL; - - p = property__get_property(proplist, identifier, skip_first); - if(!p) return NULL; - if(p->identifier != MQTT_PROP_MESSAGE_EXPIRY_INTERVAL - && p->identifier != MQTT_PROP_SESSION_EXPIRY_INTERVAL - && p->identifier != MQTT_PROP_WILL_DELAY_INTERVAL - && p->identifier != MQTT_PROP_MAXIMUM_PACKET_SIZE){ - - return NULL; - } - - if(value) *value = p->value.i32; - - return p; -} - - -BROKER_EXPORT const mosquitto_property *mosquitto_property_read_varint(const mosquitto_property *proplist, int identifier, uint32_t *value, bool skip_first) -{ - const mosquitto_property *p; - if(!proplist) return NULL; - - p = property__get_property(proplist, identifier, skip_first); - if(!p) return NULL; - if(p->identifier != MQTT_PROP_SUBSCRIPTION_IDENTIFIER){ - return NULL; - } - - if(value) *value = p->value.varint; - - return p; -} - - -BROKER_EXPORT const mosquitto_property *mosquitto_property_read_binary(const mosquitto_property *proplist, int identifier, void **value, uint16_t *len, bool skip_first) -{ - const mosquitto_property *p; - if(!proplist || (value && !len) || (!value && len)) return NULL; - - if(value) *value = NULL; - - p = property__get_property(proplist, identifier, skip_first); - if(!p) return NULL; - if(p->identifier != MQTT_PROP_CORRELATION_DATA - && p->identifier != MQTT_PROP_AUTHENTICATION_DATA){ - - return NULL; - } - - if(value){ - *len = p->value.bin.len; - if(p->value.bin.len){ - *value = calloc(1, *len + 1U); - if(!(*value)) return NULL; - - memcpy(*value, p->value.bin.v, *len); - }else{ - *value = NULL; - } - } - - return p; -} - - -BROKER_EXPORT const mosquitto_property *mosquitto_property_read_string(const mosquitto_property *proplist, int identifier, char **value, bool skip_first) -{ - const mosquitto_property *p; - if(!proplist) return NULL; - - p = property__get_property(proplist, identifier, skip_first); - if(!p) return NULL; - if(p->identifier != MQTT_PROP_CONTENT_TYPE - && p->identifier != MQTT_PROP_RESPONSE_TOPIC - && p->identifier != MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER - && p->identifier != MQTT_PROP_AUTHENTICATION_METHOD - && p->identifier != MQTT_PROP_RESPONSE_INFORMATION - && p->identifier != MQTT_PROP_SERVER_REFERENCE - && p->identifier != MQTT_PROP_REASON_STRING){ - - return NULL; - } - - if(value){ - if(p->value.s.len){ - *value = calloc(1, (size_t)p->value.s.len+1); - if(!(*value)) return NULL; - - memcpy(*value, p->value.s.v, p->value.s.len); - }else{ - *value = NULL; - } - } - - return p; -} - - -BROKER_EXPORT const mosquitto_property *mosquitto_property_read_string_pair(const mosquitto_property *proplist, int identifier, char **name, char **value, bool skip_first) -{ - const mosquitto_property *p; - if(!proplist) return NULL; - - if(name) *name = NULL; - if(value) *value = NULL; - - p = property__get_property(proplist, identifier, skip_first); - if(!p) return NULL; - if(p->identifier != MQTT_PROP_USER_PROPERTY) return NULL; - - if(name){ - if(p->name.len){ - *name = calloc(1, (size_t)p->name.len+1); - if(!(*name)) return NULL; - memcpy(*name, p->name.v, p->name.len); - }else{ - *name = NULL; - } - } - - if(value){ - if(p->value.s.len){ - *value = calloc(1, (size_t)p->value.s.len+1); - if(!(*value)){ - if(name){ - SAFE_FREE(*name); - } - return NULL; - } - memcpy(*value, p->value.s.v, p->value.s.len); - }else{ - *value = NULL; - } - } - - return p; -} - - -BROKER_EXPORT int mosquitto_property_remove(mosquitto_property **proplist, const mosquitto_property *property) -{ - mosquitto_property *item, *item_prev = NULL; - - if(proplist == NULL || property == NULL){ - return MOSQ_ERR_INVAL; - } - - item = *proplist; - while(item){ - if(item == property){ - if(item_prev == NULL){ - *proplist = (*proplist)->next; - }else{ - item_prev->next = item->next; - } - item->next = NULL; - return MOSQ_ERR_SUCCESS; - } - item_prev = item; - item = item->next; - } - - return MOSQ_ERR_NOT_FOUND; -} - - -BROKER_EXPORT int mosquitto_property_copy_all(mosquitto_property **dest, const mosquitto_property *src) -{ - mosquitto_property *pnew, *plast = NULL; - - if(!src) return MOSQ_ERR_SUCCESS; - if(!dest) return MOSQ_ERR_INVAL; - - *dest = NULL; - - while(src){ - pnew = calloc(1, sizeof(mosquitto_property)); - if(!pnew){ - mosquitto_property_free_all(dest); - return MOSQ_ERR_NOMEM; - } - if(plast){ - plast->next = pnew; - }else{ - *dest = pnew; - } - plast = pnew; - - pnew->client_generated = src->client_generated; - pnew->identifier = src->identifier; - pnew->property_type = src->property_type; - switch(pnew->property_type){ - case MQTT_PROP_TYPE_BYTE: - pnew->value.i8 = src->value.i8; - break; - - case MQTT_PROP_TYPE_INT16: - pnew->value.i16 = src->value.i16; - break; - - case MQTT_PROP_TYPE_INT32: - pnew->value.i32 = src->value.i32; - break; - - case MQTT_PROP_TYPE_VARINT: - pnew->value.varint = src->value.varint; - break; - - case MQTT_PROP_TYPE_STRING: - pnew->value.s.len = src->value.s.len; - pnew->value.s.v = src->value.s.v ? strdup(src->value.s.v) : (char*)calloc(1,1); - if(!pnew->value.s.v){ - mosquitto_property_free_all(dest); - return MOSQ_ERR_NOMEM; - } - break; - - case MQTT_PROP_TYPE_BINARY: - pnew->value.bin.len = src->value.bin.len; - if(src->value.bin.len){ - pnew->value.bin.v = malloc(pnew->value.bin.len); - if(!pnew->value.bin.v){ - mosquitto_property_free_all(dest); - return MOSQ_ERR_NOMEM; - } - memcpy(pnew->value.bin.v, src->value.bin.v, pnew->value.bin.len); - } - break; - - case MQTT_PROP_TYPE_STRING_PAIR: - pnew->value.s.len = src->value.s.len; - pnew->value.s.v = src->value.s.v ? strdup(src->value.s.v) : (char*)calloc(1,1); - if(!pnew->value.s.v){ - mosquitto_property_free_all(dest); - return MOSQ_ERR_NOMEM; - } - - pnew->name.len = src->name.len; - pnew->name.v = src->name.v ? strdup(src->name.v) : (char*)calloc(1,1); - if(!pnew->name.v){ - mosquitto_property_free_all(dest); - return MOSQ_ERR_NOMEM; - } - break; - - default: - mosquitto_property_free_all(dest); - return MOSQ_ERR_INVAL; - } - - src = mosquitto_property_next(src); - } - - return MOSQ_ERR_SUCCESS; -} - - -uint8_t mosquitto_property_byte_value(const mosquitto_property *property) -{ - if(property && property->property_type == MQTT_PROP_TYPE_BYTE){ - return property->value.i8; - }else{ - return 0; - } -} - - -uint16_t mosquitto_property_int16_value(const mosquitto_property *property) -{ - if(property && property->property_type == MQTT_PROP_TYPE_INT16){ - return property->value.i16; - }else{ - return 0; - } -} - - -uint32_t mosquitto_property_int32_value(const mosquitto_property *property) -{ - if(property && property->property_type == MQTT_PROP_TYPE_INT32){ - return property->value.i32; - }else{ - return 0; - } -} - - -uint32_t mosquitto_property_varint_value(const mosquitto_property *property) -{ - if(property && property->property_type == MQTT_PROP_TYPE_VARINT){ - return property->value.varint; - }else{ - return 0; - } -} - - -const void *mosquitto_property_binary_value(const mosquitto_property *property) -{ - if(property && property->property_type == MQTT_PROP_TYPE_BINARY){ - return property->value.bin.v; - }else{ - return NULL; - } -} - - -uint16_t mosquitto_property_binary_value_length(const mosquitto_property *property) -{ - if(property && property->property_type == MQTT_PROP_TYPE_BINARY){ - return property->value.bin.len; - }else{ - return 0; - } -} - - -const char *mosquitto_property_string_value(const mosquitto_property *property) -{ - if(property && (property->property_type == MQTT_PROP_TYPE_STRING || property->property_type == MQTT_PROP_TYPE_STRING_PAIR)){ - return property->value.s.v; - }else{ - return NULL; - } -} - - -uint16_t mosquitto_property_string_value_length(const mosquitto_property *property) -{ - if(property && (property->property_type == MQTT_PROP_TYPE_STRING || property->property_type == MQTT_PROP_TYPE_STRING_PAIR)){ - return property->value.s.len; - }else{ - return 0; - } -} - - -const char *mosquitto_property_string_name(const mosquitto_property *property) -{ - if(property && property->property_type == MQTT_PROP_TYPE_STRING_PAIR){ - return property->name.v; - }else{ - return NULL; - } -} - - -uint16_t mosquitto_property_string_name_length(const mosquitto_property *property) -{ - if(property && property->property_type == MQTT_PROP_TYPE_STRING_PAIR){ - return property->name.len; - }else{ - return 0; - } -} diff --git a/lib/property_mosq.h b/lib/property_mosq.h index 9741e73b5..f79c7412b 100644 --- a/lib/property_mosq.h +++ b/lib/property_mosq.h @@ -19,37 +19,8 @@ Contributors: #define PROPERTY_MOSQ_H #include "mosquitto_internal.h" -#include "mosquitto.h" - -struct mqtt__string { - char *v; - uint16_t len; -}; - -struct mqtt5__property { - struct mqtt5__property *next; - union { - uint8_t i8; - uint16_t i16; - uint32_t i32; - uint32_t varint; - struct mqtt__string bin; - struct mqtt__string s; - } value; - struct mqtt__string name; - int32_t identifier; - uint8_t property_type; - bool client_generated; -}; - int property__read_all(int command, struct mosquitto__packet_in *packet, mosquitto_property **property); int property__write_all(struct mosquitto__packet *packet, const mosquitto_property *property, bool write_len); -void property__free(mosquitto_property **property); - -unsigned int property__get_length(const mosquitto_property *property); -unsigned int property__get_length_all(const mosquitto_property *property); - -unsigned int property__get_remaining_length(const mosquitto_property *props); #endif diff --git a/lib/send_connect.c b/lib/send_connect.c index 872e4d92a..2bd03ade0 100644 --- a/lib/send_connect.c +++ b/lib/send_connect.c @@ -81,9 +81,9 @@ int send__connect(struct mosquitto *mosq, uint16_t keepalive, bool clean_session version = MQTT_PROTOCOL_V5; headerlen = 10; proplen = 0; - proplen += property__get_length_all(properties); - proplen += property__get_length_all(local_props); - varbytes = packet__varint_bytes(proplen); + proplen += mosquitto_property_get_remaining_length(properties); + proplen += mosquitto_property_get_remaining_length(local_props); + varbytes = mosquitto_varint_bytes(proplen); headerlen += proplen + varbytes; }else if(mosq->protocol == mosq_p_mqtt311){ version = MQTT_PROTOCOL_V311; @@ -110,7 +110,7 @@ int send__connect(struct mosquitto *mosq, uint16_t keepalive, bool clean_session payloadlen += (uint32_t)(2+strlen(mosq->will->msg.topic) + 2+(uint32_t)mosq->will->msg.payloadlen); if(mosq->protocol == mosq_p_mqtt5){ - payloadlen += property__get_remaining_length(mosq->will->properties); + payloadlen += mosquitto_property_get_remaining_length(mosq->will->properties); } } diff --git a/lib/send_disconnect.c b/lib/send_disconnect.c index e00094db4..bccefb1e6 100644 --- a/lib/send_disconnect.c +++ b/lib/send_disconnect.c @@ -59,7 +59,7 @@ int send__disconnect(struct mosquitto *mosq, uint8_t reason_code, const mosquitt if(mosq->protocol == mosq_p_mqtt5 && (reason_code != 0 || properties)){ remaining_length = 1; if(properties){ - remaining_length += property__get_remaining_length(properties); + remaining_length += mosquitto_property_get_remaining_length(properties); } }else{ remaining_length = 0; diff --git a/lib/send_mosq.c b/lib/send_mosq.c index 3babe360b..ab7794c9d 100644 --- a/lib/send_mosq.c +++ b/lib/send_mosq.c @@ -141,7 +141,7 @@ int send__command_with_mid(struct mosquitto *mosq, uint8_t command, uint16_t mid } if(properties){ - remaining_length += property__get_remaining_length(properties); + remaining_length += mosquitto_property_get_remaining_length(properties); } } diff --git a/lib/send_publish.c b/lib/send_publish.c index 337d5938c..90bcf2140 100644 --- a/lib/send_publish.c +++ b/lib/send_publish.c @@ -36,6 +36,7 @@ Contributors: #include "net_mosq.h" #include "packet_mosq.h" #include "property_mosq.h" +#include "property_common.h" #include "send_mosq.h" #include "utlist.h" @@ -224,7 +225,7 @@ int send__real_publish(struct mosquitto *mosq, uint16_t mid, const char *topic, if(qos > 0) packetlen += 2; /* For message id */ if(mosq->protocol == mosq_p_mqtt5){ proplen = 0; - proplen += property__get_length_all(store_props); + proplen += mosquitto_property_get_length_all(store_props); if(expiry_interval > 0){ expiry_prop.next = NULL; expiry_prop.value.i32 = expiry_interval; @@ -232,7 +233,7 @@ int send__real_publish(struct mosquitto *mosq, uint16_t mid, const char *topic, expiry_prop.property_type = MQTT_PROP_TYPE_INT32; expiry_prop.client_generated = false; - proplen += property__get_length_all(&expiry_prop); + proplen += mosquitto_property_get_length_all(&expiry_prop); } #ifdef WITH_BROKER if(topic_alias != 0){ @@ -242,7 +243,7 @@ int send__real_publish(struct mosquitto *mosq, uint16_t mid, const char *topic, topic_alias_prop.property_type = MQTT_PROP_TYPE_INT16; topic_alias_prop.client_generated = false; - proplen += property__get_length_all(&topic_alias_prop); + proplen += mosquitto_property_get_length_all(&topic_alias_prop); } if(subscription_identifier){ subscription_id_prop.next = NULL; @@ -251,11 +252,11 @@ int send__real_publish(struct mosquitto *mosq, uint16_t mid, const char *topic, subscription_id_prop.property_type = MQTT_PROP_TYPE_VARINT; subscription_id_prop.client_generated = false; - proplen += property__get_length_all(&subscription_id_prop); + proplen += mosquitto_property_get_length_all(&subscription_id_prop); } #endif - varbytes = packet__varint_bytes(proplen); + varbytes = mosquitto_varint_bytes(proplen); if(varbytes > 4){ /* FIXME - Properties too big, don't publish any - should remove some first really */ store_props = NULL; diff --git a/lib/send_subscribe.c b/lib/send_subscribe.c index adaae2209..593093b55 100644 --- a/lib/send_subscribe.c +++ b/lib/send_subscribe.c @@ -50,7 +50,7 @@ int send__subscribe(struct mosquitto *mosq, int *mid, int topic_count, char *con packetlen = 2; if(mosq->protocol == mosq_p_mqtt5){ - packetlen += property__get_remaining_length(properties); + packetlen += mosquitto_property_get_remaining_length(properties); } for(i=0; iprotocol == mosq_p_mqtt5){ - packetlen += property__get_remaining_length(properties); + packetlen += mosquitto_property_get_remaining_length(properties); } rc = packet__alloc(&packet, CMD_UNSUBSCRIBE | 2, packetlen); diff --git a/libcommon/CMakeLists.txt b/libcommon/CMakeLists.txt index 097050c35..bed2fdd7f 100644 --- a/libcommon/CMakeLists.txt +++ b/libcommon/CMakeLists.txt @@ -1,5 +1,7 @@ set(C_SRC memory_common.c + mqtt_common.c + property_common.c strings_common.c time_common.c topic_common.c diff --git a/libcommon/Makefile b/libcommon/Makefile index f7b9890cb..952303aac 100644 --- a/libcommon/Makefile +++ b/libcommon/Makefile @@ -13,6 +13,8 @@ LOCAL_LIBADD+= OBJS= \ memory_common.o \ + mqtt_common.o \ + property_common.o \ strings_common.o \ time_common.o \ topic_common.o \ diff --git a/libcommon/mqtt_common.c b/libcommon/mqtt_common.c new file mode 100644 index 000000000..acdcc001a --- /dev/null +++ b/libcommon/mqtt_common.c @@ -0,0 +1,39 @@ +/* +Copyright (c) 2009-2021 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License 2.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + https://www.eclipse.org/legal/epl-2.0/ +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#include "config.h" + +#include + +#include "mosquitto/mqtt_protocol.h" + + +unsigned int mosquitto_varint_bytes(uint32_t word) +{ + if(word < 128){ + return 1; + }else if(word < 16384){ + return 2; + }else if(word < 2097152){ + return 3; + }else if(word < 268435456){ + return 4; + }else{ + return 5; + } +} diff --git a/libcommon/property_common.c b/libcommon/property_common.c new file mode 100644 index 000000000..dee45db22 --- /dev/null +++ b/libcommon/property_common.c @@ -0,0 +1,1138 @@ +/* +Copyright (c) 2018-2021 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License 2.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + https://www.eclipse.org/legal/epl-2.0/ +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#include "config.h" + +#include +#include +#include + +#ifndef WIN32 +# include +#endif + +#include "mosquitto/mqtt_protocol.h" +#include "property_common.h" + + +void mosquitto_property_free(mosquitto_property **property) +{ + if(!property || !(*property)) return; + + switch((*property)->property_type){ + case MQTT_PROP_TYPE_STRING: + mosquitto_FREE((*property)->value.s.v); + break; + + case MQTT_PROP_TYPE_BINARY: + mosquitto_FREE((*property)->value.bin.v); + break; + + case MQTT_PROP_TYPE_STRING_PAIR: + mosquitto_FREE((*property)->name.v); + mosquitto_FREE((*property)->value.s.v); + break; + + case MQTT_PROP_TYPE_BYTE: + case MQTT_PROP_TYPE_INT16: + case MQTT_PROP_TYPE_INT32: + case MQTT_PROP_TYPE_VARINT: + /* Nothing to free */ + break; + } + + free(*property); + *property = NULL; +} + + +BROKER_EXPORT void mosquitto_property_free_all(mosquitto_property **property) +{ + mosquitto_property *p, *next; + + if(!property) return; + + p = *property; + while(p){ + next = p->next; + mosquitto_property_free(&p); + p = next; + } + *property = NULL; +} + + +unsigned int mosquitto_property_get_length(const mosquitto_property *property) +{ + if(!property) return 0; + + switch(property->property_type){ + case MQTT_PROP_TYPE_BYTE: + return 2; /* 1 (identifier) + 1 byte */ + + case MQTT_PROP_TYPE_INT16: + return 3; /* 1 (identifier) + 2 bytes */ + + case MQTT_PROP_TYPE_INT32: + return 5; /* 1 (identifier) + 4 bytes */ + + case MQTT_PROP_TYPE_VARINT: + if(property->value.varint < 128){ + return 2; + }else if(property->value.varint < 16384){ + return 3; + }else if(property->value.varint < 2097152){ + return 4; + }else if(property->value.varint < 268435456){ + return 5; + }else{ + return 0; + } + + case MQTT_PROP_TYPE_BINARY: + return 3U + property->value.bin.len; /* 1 + 2 bytes (len) + X bytes (payload) */ + + case MQTT_PROP_TYPE_STRING: + return 3U + property->value.s.len; /* 1 + 2 bytes (len) + X bytes (string) */ + + case MQTT_PROP_TYPE_STRING_PAIR: + return 5U + property->value.s.len + property->name.len; /* 1 + 2*(2 bytes (len) + X bytes (string))*/ + + default: + return 0; + } + return 0; +} + + +unsigned int mosquitto_property_get_length_all(const mosquitto_property *property) +{ + const mosquitto_property *p; + unsigned int len = 0; + + p = property; + while(p){ + len += mosquitto_property_get_length(p); + p = p->next; + } + return len; +} + + +BROKER_EXPORT int mosquitto_property_check_command(int command, int identifier) +{ + switch(identifier){ + case MQTT_PROP_PAYLOAD_FORMAT_INDICATOR: + case MQTT_PROP_MESSAGE_EXPIRY_INTERVAL: + case MQTT_PROP_CONTENT_TYPE: + case MQTT_PROP_RESPONSE_TOPIC: + case MQTT_PROP_CORRELATION_DATA: + if(command != CMD_PUBLISH && command != CMD_WILL){ + return MOSQ_ERR_PROTOCOL; + } + break; + + case MQTT_PROP_SUBSCRIPTION_IDENTIFIER: + if(command != CMD_PUBLISH && command != CMD_SUBSCRIBE){ + return MOSQ_ERR_PROTOCOL; + } + break; + + case MQTT_PROP_SESSION_EXPIRY_INTERVAL: + if(command != CMD_CONNECT && command != CMD_CONNACK && command != CMD_DISCONNECT){ + return MOSQ_ERR_PROTOCOL; + } + break; + + case MQTT_PROP_AUTHENTICATION_METHOD: + case MQTT_PROP_AUTHENTICATION_DATA: + if(command != CMD_CONNECT && command != CMD_CONNACK && command != CMD_AUTH){ + return MOSQ_ERR_PROTOCOL; + } + break; + + case MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER: + case MQTT_PROP_SERVER_KEEP_ALIVE: + case MQTT_PROP_RESPONSE_INFORMATION: + case MQTT_PROP_MAXIMUM_QOS: + case MQTT_PROP_RETAIN_AVAILABLE: + case MQTT_PROP_WILDCARD_SUB_AVAILABLE: + case MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE: + case MQTT_PROP_SHARED_SUB_AVAILABLE: + if(command != CMD_CONNACK){ + return MOSQ_ERR_PROTOCOL; + } + break; + + case MQTT_PROP_WILL_DELAY_INTERVAL: + if(command != CMD_WILL){ + return MOSQ_ERR_PROTOCOL; + } + break; + + case MQTT_PROP_REQUEST_PROBLEM_INFORMATION: + case MQTT_PROP_REQUEST_RESPONSE_INFORMATION: + if(command != CMD_CONNECT){ + return MOSQ_ERR_PROTOCOL; + } + break; + + case MQTT_PROP_SERVER_REFERENCE: + if(command != CMD_CONNACK && command != CMD_DISCONNECT){ + return MOSQ_ERR_PROTOCOL; + } + break; + + case MQTT_PROP_REASON_STRING: + if(command == CMD_CONNECT || command == CMD_PUBLISH || command == CMD_SUBSCRIBE || command == CMD_UNSUBSCRIBE){ + return MOSQ_ERR_PROTOCOL; + } + break; + + case MQTT_PROP_RECEIVE_MAXIMUM: + case MQTT_PROP_TOPIC_ALIAS_MAXIMUM: + case MQTT_PROP_MAXIMUM_PACKET_SIZE: + if(command != CMD_CONNECT && command != CMD_CONNACK){ + return MOSQ_ERR_PROTOCOL; + } + break; + + case MQTT_PROP_TOPIC_ALIAS: + if(command != CMD_PUBLISH){ + return MOSQ_ERR_PROTOCOL; + } + break; + + case MQTT_PROP_USER_PROPERTY: + break; + + default: + return MOSQ_ERR_PROTOCOL; + } + return MOSQ_ERR_SUCCESS; +} + + +BROKER_EXPORT const char *mosquitto_property_identifier_to_string(int identifier) +{ + switch(identifier){ + case MQTT_PROP_PAYLOAD_FORMAT_INDICATOR: + return "payload-format-indicator"; + case MQTT_PROP_MESSAGE_EXPIRY_INTERVAL: + return "message-expiry-interval"; + case MQTT_PROP_CONTENT_TYPE: + return "content-type"; + case MQTT_PROP_RESPONSE_TOPIC: + return "response-topic"; + case MQTT_PROP_CORRELATION_DATA: + return "correlation-data"; + case MQTT_PROP_SUBSCRIPTION_IDENTIFIER: + return "subscription-identifier"; + case MQTT_PROP_SESSION_EXPIRY_INTERVAL: + return "session-expiry-interval"; + case MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER: + return "assigned-client-identifier"; + case MQTT_PROP_SERVER_KEEP_ALIVE: + return "server-keep-alive"; + case MQTT_PROP_AUTHENTICATION_METHOD: + return "authentication-method"; + case MQTT_PROP_AUTHENTICATION_DATA: + return "authentication-data"; + case MQTT_PROP_REQUEST_PROBLEM_INFORMATION: + return "request-problem-information"; + case MQTT_PROP_WILL_DELAY_INTERVAL: + return "will-delay-interval"; + case MQTT_PROP_REQUEST_RESPONSE_INFORMATION: + return "request-response-information"; + case MQTT_PROP_RESPONSE_INFORMATION: + return "response-information"; + case MQTT_PROP_SERVER_REFERENCE: + return "server-reference"; + case MQTT_PROP_REASON_STRING: + return "reason-string"; + case MQTT_PROP_RECEIVE_MAXIMUM: + return "receive-maximum"; + case MQTT_PROP_TOPIC_ALIAS_MAXIMUM: + return "topic-alias-maximum"; + case MQTT_PROP_TOPIC_ALIAS: + return "topic-alias"; + case MQTT_PROP_MAXIMUM_QOS: + return "maximum-qos"; + case MQTT_PROP_RETAIN_AVAILABLE: + return "retain-available"; + case MQTT_PROP_USER_PROPERTY: + return "user-property"; + case MQTT_PROP_MAXIMUM_PACKET_SIZE: + return "maximum-packet-size"; + case MQTT_PROP_WILDCARD_SUB_AVAILABLE: + return "wildcard-subscription-available"; + case MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE: + return "subscription-identifier-available"; + case MQTT_PROP_SHARED_SUB_AVAILABLE: + return "shared-subscription-available"; + default: + return NULL; + } +} + + +BROKER_EXPORT int mosquitto_string_to_property_info(const char *propname, int *identifier, int *type) +{ + if(!propname) return MOSQ_ERR_INVAL; + + if(!strcasecmp(propname, "payload-format-indicator")){ + *identifier = MQTT_PROP_PAYLOAD_FORMAT_INDICATOR; + *type = MQTT_PROP_TYPE_BYTE; + }else if(!strcasecmp(propname, "message-expiry-interval")){ + *identifier = MQTT_PROP_MESSAGE_EXPIRY_INTERVAL; + *type = MQTT_PROP_TYPE_INT32; + }else if(!strcasecmp(propname, "content-type")){ + *identifier = MQTT_PROP_CONTENT_TYPE; + *type = MQTT_PROP_TYPE_STRING; + }else if(!strcasecmp(propname, "response-topic")){ + *identifier = MQTT_PROP_RESPONSE_TOPIC; + *type = MQTT_PROP_TYPE_STRING; + }else if(!strcasecmp(propname, "correlation-data")){ + *identifier = MQTT_PROP_CORRELATION_DATA; + *type = MQTT_PROP_TYPE_BINARY; + }else if(!strcasecmp(propname, "subscription-identifier")){ + *identifier = MQTT_PROP_SUBSCRIPTION_IDENTIFIER; + *type = MQTT_PROP_TYPE_VARINT; + }else if(!strcasecmp(propname, "session-expiry-interval")){ + *identifier = MQTT_PROP_SESSION_EXPIRY_INTERVAL; + *type = MQTT_PROP_TYPE_INT32; + }else if(!strcasecmp(propname, "assigned-client-identifier")){ + *identifier = MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER; + *type = MQTT_PROP_TYPE_STRING; + }else if(!strcasecmp(propname, "server-keep-alive")){ + *identifier = MQTT_PROP_SERVER_KEEP_ALIVE; + *type = MQTT_PROP_TYPE_INT16; + }else if(!strcasecmp(propname, "authentication-method")){ + *identifier = MQTT_PROP_AUTHENTICATION_METHOD; + *type = MQTT_PROP_TYPE_STRING; + }else if(!strcasecmp(propname, "authentication-data")){ + *identifier = MQTT_PROP_AUTHENTICATION_DATA; + *type = MQTT_PROP_TYPE_BINARY; + }else if(!strcasecmp(propname, "request-problem-information")){ + *identifier = MQTT_PROP_REQUEST_PROBLEM_INFORMATION; + *type = MQTT_PROP_TYPE_BYTE; + }else if(!strcasecmp(propname, "will-delay-interval")){ + *identifier = MQTT_PROP_WILL_DELAY_INTERVAL; + *type = MQTT_PROP_TYPE_INT32; + }else if(!strcasecmp(propname, "request-response-information")){ + *identifier = MQTT_PROP_REQUEST_RESPONSE_INFORMATION; + *type = MQTT_PROP_TYPE_BYTE; + }else if(!strcasecmp(propname, "response-information")){ + *identifier = MQTT_PROP_RESPONSE_INFORMATION; + *type = MQTT_PROP_TYPE_STRING; + }else if(!strcasecmp(propname, "server-reference")){ + *identifier = MQTT_PROP_SERVER_REFERENCE; + *type = MQTT_PROP_TYPE_STRING; + }else if(!strcasecmp(propname, "reason-string")){ + *identifier = MQTT_PROP_REASON_STRING; + *type = MQTT_PROP_TYPE_STRING; + }else if(!strcasecmp(propname, "receive-maximum")){ + *identifier = MQTT_PROP_RECEIVE_MAXIMUM; + *type = MQTT_PROP_TYPE_INT16; + }else if(!strcasecmp(propname, "topic-alias-maximum")){ + *identifier = MQTT_PROP_TOPIC_ALIAS_MAXIMUM; + *type = MQTT_PROP_TYPE_INT16; + }else if(!strcasecmp(propname, "topic-alias")){ + *identifier = MQTT_PROP_TOPIC_ALIAS; + *type = MQTT_PROP_TYPE_INT16; + }else if(!strcasecmp(propname, "maximum-qos")){ + *identifier = MQTT_PROP_MAXIMUM_QOS; + *type = MQTT_PROP_TYPE_BYTE; + }else if(!strcasecmp(propname, "retain-available")){ + *identifier = MQTT_PROP_RETAIN_AVAILABLE; + *type = MQTT_PROP_TYPE_BYTE; + }else if(!strcasecmp(propname, "user-property")){ + *identifier = MQTT_PROP_USER_PROPERTY; + *type = MQTT_PROP_TYPE_STRING_PAIR; + }else if(!strcasecmp(propname, "maximum-packet-size")){ + *identifier = MQTT_PROP_MAXIMUM_PACKET_SIZE; + *type = MQTT_PROP_TYPE_INT32; + }else if(!strcasecmp(propname, "wildcard-subscription-available")){ + *identifier = MQTT_PROP_WILDCARD_SUB_AVAILABLE; + *type = MQTT_PROP_TYPE_BYTE; + }else if(!strcasecmp(propname, "subscription-identifier-available")){ + *identifier = MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE; + *type = MQTT_PROP_TYPE_BYTE; + }else if(!strcasecmp(propname, "shared-subscription-available")){ + *identifier = MQTT_PROP_SHARED_SUB_AVAILABLE; + *type = MQTT_PROP_TYPE_BYTE; + }else{ + return MOSQ_ERR_INVAL; + } + return MOSQ_ERR_SUCCESS; +} + + +static void property__add(mosquitto_property **proplist, struct mqtt5__property *prop) +{ + mosquitto_property *p; + + if(!(*proplist)){ + *proplist = prop; + } + + p = *proplist; + while(p->next){ + p = p->next; + } + p->next = prop; + prop->next = NULL; +} + + +BROKER_EXPORT int mosquitto_property_add_byte(mosquitto_property **proplist, int identifier, uint8_t value) +{ + mosquitto_property *prop; + + if(!proplist) return MOSQ_ERR_INVAL; + if(identifier != MQTT_PROP_PAYLOAD_FORMAT_INDICATOR + && identifier != MQTT_PROP_REQUEST_PROBLEM_INFORMATION + && identifier != MQTT_PROP_REQUEST_RESPONSE_INFORMATION + && identifier != MQTT_PROP_MAXIMUM_QOS + && identifier != MQTT_PROP_RETAIN_AVAILABLE + && identifier != MQTT_PROP_WILDCARD_SUB_AVAILABLE + && identifier != MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE + && identifier != MQTT_PROP_SHARED_SUB_AVAILABLE){ + return MOSQ_ERR_INVAL; + } + + prop = mosquitto_calloc(1, sizeof(mosquitto_property)); + if(!prop) return MOSQ_ERR_NOMEM; + + prop->client_generated = true; + prop->identifier = identifier; + prop->value.i8 = value; + prop->property_type = MQTT_PROP_TYPE_BYTE; + + property__add(proplist, prop); + return MOSQ_ERR_SUCCESS; +} + + +BROKER_EXPORT int mosquitto_property_add_int16(mosquitto_property **proplist, int identifier, uint16_t value) +{ + mosquitto_property *prop; + + if(!proplist) return MOSQ_ERR_INVAL; + if(identifier != MQTT_PROP_SERVER_KEEP_ALIVE + && identifier != MQTT_PROP_RECEIVE_MAXIMUM + && identifier != MQTT_PROP_TOPIC_ALIAS_MAXIMUM + && identifier != MQTT_PROP_TOPIC_ALIAS){ + return MOSQ_ERR_INVAL; + } + + prop = mosquitto_calloc(1, sizeof(mosquitto_property)); + if(!prop) return MOSQ_ERR_NOMEM; + + prop->client_generated = true; + prop->identifier = identifier; + prop->value.i16 = value; + prop->property_type = MQTT_PROP_TYPE_INT16; + + property__add(proplist, prop); + return MOSQ_ERR_SUCCESS; +} + + +BROKER_EXPORT int mosquitto_property_add_int32(mosquitto_property **proplist, int identifier, uint32_t value) +{ + mosquitto_property *prop; + + if(!proplist) return MOSQ_ERR_INVAL; + if(identifier != MQTT_PROP_MESSAGE_EXPIRY_INTERVAL + && identifier != MQTT_PROP_SESSION_EXPIRY_INTERVAL + && identifier != MQTT_PROP_WILL_DELAY_INTERVAL + && identifier != MQTT_PROP_MAXIMUM_PACKET_SIZE){ + + return MOSQ_ERR_INVAL; + } + + prop = mosquitto_calloc(1, sizeof(mosquitto_property)); + if(!prop) return MOSQ_ERR_NOMEM; + + prop->client_generated = true; + prop->identifier = identifier; + prop->value.i32 = value; + prop->property_type = MQTT_PROP_TYPE_INT32; + + property__add(proplist, prop); + return MOSQ_ERR_SUCCESS; +} + + +BROKER_EXPORT int mosquitto_property_add_varint(mosquitto_property **proplist, int identifier, uint32_t value) +{ + mosquitto_property *prop; + + if(!proplist || value > 268435455) return MOSQ_ERR_INVAL; + if(identifier != MQTT_PROP_SUBSCRIPTION_IDENTIFIER) return MOSQ_ERR_INVAL; + + prop = mosquitto_calloc(1, sizeof(mosquitto_property)); + if(!prop) return MOSQ_ERR_NOMEM; + + prop->client_generated = true; + prop->identifier = identifier; + prop->value.varint = value; + prop->property_type = MQTT_PROP_TYPE_VARINT; + + property__add(proplist, prop); + return MOSQ_ERR_SUCCESS; +} + + +BROKER_EXPORT int mosquitto_property_add_binary(mosquitto_property **proplist, int identifier, const void *value, uint16_t len) +{ + mosquitto_property *prop; + + if(!proplist) return MOSQ_ERR_INVAL; + if(identifier != MQTT_PROP_CORRELATION_DATA + && identifier != MQTT_PROP_AUTHENTICATION_DATA){ + + return MOSQ_ERR_INVAL; + } + + prop = mosquitto_calloc(1, sizeof(mosquitto_property)); + if(!prop) return MOSQ_ERR_NOMEM; + + prop->client_generated = true; + prop->identifier = identifier; + prop->property_type = MQTT_PROP_TYPE_BINARY; + + if(len){ + prop->value.bin.v = mosquitto_malloc(len); + if(!prop->value.bin.v){ + mosquitto_FREE(prop); + return MOSQ_ERR_NOMEM; + } + + memcpy(prop->value.bin.v, value, len); + prop->value.bin.len = len; + } + + property__add(proplist, prop); + return MOSQ_ERR_SUCCESS; +} + + +BROKER_EXPORT int mosquitto_property_add_string(mosquitto_property **proplist, int identifier, const char *value) +{ + mosquitto_property *prop; + size_t slen = 0; + + if(!proplist) return MOSQ_ERR_INVAL; + if(value){ + slen = strlen(value); + if(mosquitto_validate_utf8(value, (int)slen)) return MOSQ_ERR_MALFORMED_UTF8; + } + + if(identifier != MQTT_PROP_CONTENT_TYPE + && identifier != MQTT_PROP_RESPONSE_TOPIC + && identifier != MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER + && identifier != MQTT_PROP_AUTHENTICATION_METHOD + && identifier != MQTT_PROP_RESPONSE_INFORMATION + && identifier != MQTT_PROP_SERVER_REFERENCE + && identifier != MQTT_PROP_REASON_STRING){ + + return MOSQ_ERR_INVAL; + } + + prop = mosquitto_calloc(1, sizeof(mosquitto_property)); + if(!prop) return MOSQ_ERR_NOMEM; + + prop->client_generated = true; + prop->identifier = identifier; + prop->property_type = MQTT_PROP_TYPE_STRING; + if(value && slen > 0){ + prop->value.s.v = mosquitto_strdup(value); + if(!prop->value.s.v){ + mosquitto_FREE(prop); + return MOSQ_ERR_NOMEM; + } + prop->value.s.len = (uint16_t)slen; + } + + property__add(proplist, prop); + return MOSQ_ERR_SUCCESS; +} + + +BROKER_EXPORT int mosquitto_property_add_string_pair(mosquitto_property **proplist, int identifier, const char *name, const char *value) +{ + mosquitto_property *prop; + size_t slen_name = 0, slen_value = 0; + + if(!proplist) return MOSQ_ERR_INVAL; + if(identifier != MQTT_PROP_USER_PROPERTY) return MOSQ_ERR_INVAL; + if(name){ + slen_name = strlen(name); + if(mosquitto_validate_utf8(name, (int)slen_name)) return MOSQ_ERR_MALFORMED_UTF8; + } + if(value){ + if(mosquitto_validate_utf8(value, (int)slen_value)) return MOSQ_ERR_MALFORMED_UTF8; + } + + prop = mosquitto_calloc(1, sizeof(mosquitto_property)); + if(!prop) return MOSQ_ERR_NOMEM; + + prop->client_generated = true; + prop->identifier = identifier; + prop->property_type = MQTT_PROP_TYPE_STRING_PAIR; + + if(name){ + prop->name.v = mosquitto_strdup(name); + if(!prop->name.v){ + mosquitto_FREE(prop); + return MOSQ_ERR_NOMEM; + } + prop->name.len = (uint16_t)strlen(name); + } + + if(value){ + prop->value.s.v = mosquitto_strdup(value); + if(!prop->value.s.v){ + mosquitto_FREE(prop->name.v); + mosquitto_FREE(prop); + return MOSQ_ERR_NOMEM; + } + prop->value.s.len = (uint16_t)strlen(value); + } + + property__add(proplist, prop); + return MOSQ_ERR_SUCCESS; +} + +BROKER_EXPORT int mosquitto_property_check_all(int command, const mosquitto_property *properties) +{ + const mosquitto_property *p, *tail; + int rc; + + p = properties; + + while(p){ + /* Validity checks */ + if(p->identifier == MQTT_PROP_REQUEST_PROBLEM_INFORMATION + || p->identifier == MQTT_PROP_PAYLOAD_FORMAT_INDICATOR + || p->identifier == MQTT_PROP_REQUEST_RESPONSE_INFORMATION + || p->identifier == MQTT_PROP_MAXIMUM_QOS + || p->identifier == MQTT_PROP_RETAIN_AVAILABLE + || p->identifier == MQTT_PROP_WILDCARD_SUB_AVAILABLE + || p->identifier == MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE + || p->identifier == MQTT_PROP_SHARED_SUB_AVAILABLE){ + + if(p->value.i8 > 1){ + return MOSQ_ERR_PROTOCOL; + } + }else if(p->identifier == MQTT_PROP_MAXIMUM_PACKET_SIZE){ + if( p->value.i32 == 0){ + return MOSQ_ERR_PROTOCOL; + } + }else if(p->identifier == MQTT_PROP_RECEIVE_MAXIMUM + || p->identifier == MQTT_PROP_TOPIC_ALIAS){ + + if(p->value.i16 == 0){ + return MOSQ_ERR_PROTOCOL; + } + } + + /* Check for properties on incorrect commands */ + rc = mosquitto_property_check_command(command, p->identifier); + if(rc) return rc; + + /* Check for duplicates */ + if(p->identifier != MQTT_PROP_USER_PROPERTY){ + tail = p->next; + while(tail){ + if(p->identifier == tail->identifier){ + return MOSQ_ERR_DUPLICATE_PROPERTY; + } + tail = tail->next; + } + } + + p = p->next; + } + + return MOSQ_ERR_SUCCESS; +} + +static const mosquitto_property *property__get_property(const mosquitto_property *proplist, int identifier, bool skip_first) +{ + const mosquitto_property *p; + bool is_first = true; + + p = proplist; + + while(p){ + if(p->identifier == identifier){ + if(!is_first || !skip_first){ + return p; + } + is_first = false; + } + p = p->next; + } + return NULL; +} + + +BROKER_EXPORT int mosquitto_property_identifier(const mosquitto_property *property) +{ + if(property == NULL) return 0; + + return property->identifier; +} + + +BROKER_EXPORT int mosquitto_property_type(const mosquitto_property *property) +{ + if(property == NULL) return 0; + + return property->property_type; +} + + +BROKER_EXPORT mosquitto_property *mosquitto_property_next(const mosquitto_property *proplist) +{ + if(proplist == NULL) return NULL; + + return proplist->next; +} + + +BROKER_EXPORT const mosquitto_property *mosquitto_property_read_byte(const mosquitto_property *proplist, int identifier, uint8_t *value, bool skip_first) +{ + const mosquitto_property *p; + if(!proplist) return NULL; + + p = property__get_property(proplist, identifier, skip_first); + if(!p) return NULL; + if(p->identifier != MQTT_PROP_PAYLOAD_FORMAT_INDICATOR + && p->identifier != MQTT_PROP_REQUEST_PROBLEM_INFORMATION + && p->identifier != MQTT_PROP_REQUEST_RESPONSE_INFORMATION + && p->identifier != MQTT_PROP_MAXIMUM_QOS + && p->identifier != MQTT_PROP_RETAIN_AVAILABLE + && p->identifier != MQTT_PROP_WILDCARD_SUB_AVAILABLE + && p->identifier != MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE + && p->identifier != MQTT_PROP_SHARED_SUB_AVAILABLE){ + return NULL; + } + + if(value) *value = p->value.i8; + + return p; +} + + +BROKER_EXPORT const mosquitto_property *mosquitto_property_read_int16(const mosquitto_property *proplist, int identifier, uint16_t *value, bool skip_first) +{ + const mosquitto_property *p; + if(!proplist) return NULL; + + p = property__get_property(proplist, identifier, skip_first); + if(!p) return NULL; + if(p->identifier != MQTT_PROP_SERVER_KEEP_ALIVE + && p->identifier != MQTT_PROP_RECEIVE_MAXIMUM + && p->identifier != MQTT_PROP_TOPIC_ALIAS_MAXIMUM + && p->identifier != MQTT_PROP_TOPIC_ALIAS){ + return NULL; + } + + if(value) *value = p->value.i16; + + return p; +} + + +BROKER_EXPORT const mosquitto_property *mosquitto_property_read_int32(const mosquitto_property *proplist, int identifier, uint32_t *value, bool skip_first) +{ + const mosquitto_property *p; + if(!proplist) return NULL; + + p = property__get_property(proplist, identifier, skip_first); + if(!p) return NULL; + if(p->identifier != MQTT_PROP_MESSAGE_EXPIRY_INTERVAL + && p->identifier != MQTT_PROP_SESSION_EXPIRY_INTERVAL + && p->identifier != MQTT_PROP_WILL_DELAY_INTERVAL + && p->identifier != MQTT_PROP_MAXIMUM_PACKET_SIZE){ + + return NULL; + } + + if(value) *value = p->value.i32; + + return p; +} + + +BROKER_EXPORT const mosquitto_property *mosquitto_property_read_varint(const mosquitto_property *proplist, int identifier, uint32_t *value, bool skip_first) +{ + const mosquitto_property *p; + if(!proplist) return NULL; + + p = property__get_property(proplist, identifier, skip_first); + if(!p) return NULL; + if(p->identifier != MQTT_PROP_SUBSCRIPTION_IDENTIFIER){ + return NULL; + } + + if(value) *value = p->value.varint; + + return p; +} + + +BROKER_EXPORT const mosquitto_property *mosquitto_property_read_binary(const mosquitto_property *proplist, int identifier, void **value, uint16_t *len, bool skip_first) +{ + const mosquitto_property *p; + if(!proplist || (value && !len) || (!value && len)) return NULL; + + if(value) *value = NULL; + + p = property__get_property(proplist, identifier, skip_first); + if(!p) return NULL; + if(p->identifier != MQTT_PROP_CORRELATION_DATA + && p->identifier != MQTT_PROP_AUTHENTICATION_DATA){ + + return NULL; + } + + if(value){ + *len = p->value.bin.len; + if(p->value.bin.len){ + *value = calloc(1, *len + 1U); + if(!(*value)) return NULL; + + memcpy(*value, p->value.bin.v, *len); + }else{ + *value = NULL; + } + } + + return p; +} + + +BROKER_EXPORT const mosquitto_property *mosquitto_property_read_string(const mosquitto_property *proplist, int identifier, char **value, bool skip_first) +{ + const mosquitto_property *p; + if(!proplist) return NULL; + + p = property__get_property(proplist, identifier, skip_first); + if(!p) return NULL; + if(p->identifier != MQTT_PROP_CONTENT_TYPE + && p->identifier != MQTT_PROP_RESPONSE_TOPIC + && p->identifier != MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER + && p->identifier != MQTT_PROP_AUTHENTICATION_METHOD + && p->identifier != MQTT_PROP_RESPONSE_INFORMATION + && p->identifier != MQTT_PROP_SERVER_REFERENCE + && p->identifier != MQTT_PROP_REASON_STRING){ + + return NULL; + } + + if(value){ + if(p->value.s.len){ + *value = calloc(1, (size_t)p->value.s.len+1); + if(!(*value)) return NULL; + + memcpy(*value, p->value.s.v, p->value.s.len); + }else{ + *value = NULL; + } + } + + return p; +} + + +BROKER_EXPORT const mosquitto_property *mosquitto_property_read_string_pair(const mosquitto_property *proplist, int identifier, char **name, char **value, bool skip_first) +{ + const mosquitto_property *p; + if(!proplist) return NULL; + + if(name) *name = NULL; + if(value) *value = NULL; + + p = property__get_property(proplist, identifier, skip_first); + if(!p) return NULL; + if(p->identifier != MQTT_PROP_USER_PROPERTY) return NULL; + + if(name){ + if(p->name.len){ + *name = calloc(1, (size_t)p->name.len+1); + if(!(*name)) return NULL; + memcpy(*name, p->name.v, p->name.len); + }else{ + *name = NULL; + } + } + + if(value){ + if(p->value.s.len){ + *value = calloc(1, (size_t)p->value.s.len+1); + if(!(*value)){ + if(name){ + free(*name); + *name = NULL; + } + return NULL; + } + memcpy(*value, p->value.s.v, p->value.s.len); + }else{ + *value = NULL; + } + } + + return p; +} + + +BROKER_EXPORT int mosquitto_property_remove(mosquitto_property **proplist, const mosquitto_property *property) +{ + mosquitto_property *item, *item_prev = NULL; + + if(proplist == NULL || property == NULL){ + return MOSQ_ERR_INVAL; + } + + item = *proplist; + while(item){ + if(item == property){ + if(item_prev == NULL){ + *proplist = (*proplist)->next; + }else{ + item_prev->next = item->next; + } + item->next = NULL; + return MOSQ_ERR_SUCCESS; + } + item_prev = item; + item = item->next; + } + + return MOSQ_ERR_NOT_FOUND; +} + + +BROKER_EXPORT int mosquitto_property_copy_all(mosquitto_property **dest, const mosquitto_property *src) +{ + mosquitto_property *pnew, *plast = NULL; + + if(!src) return MOSQ_ERR_SUCCESS; + if(!dest) return MOSQ_ERR_INVAL; + + *dest = NULL; + + while(src){ + pnew = calloc(1, sizeof(mosquitto_property)); + if(!pnew){ + mosquitto_property_free_all(dest); + return MOSQ_ERR_NOMEM; + } + if(plast){ + plast->next = pnew; + }else{ + *dest = pnew; + } + plast = pnew; + + pnew->client_generated = src->client_generated; + pnew->identifier = src->identifier; + pnew->property_type = src->property_type; + switch(pnew->property_type){ + case MQTT_PROP_TYPE_BYTE: + pnew->value.i8 = src->value.i8; + break; + + case MQTT_PROP_TYPE_INT16: + pnew->value.i16 = src->value.i16; + break; + + case MQTT_PROP_TYPE_INT32: + pnew->value.i32 = src->value.i32; + break; + + case MQTT_PROP_TYPE_VARINT: + pnew->value.varint = src->value.varint; + break; + + case MQTT_PROP_TYPE_STRING: + pnew->value.s.len = src->value.s.len; + pnew->value.s.v = src->value.s.v ? strdup(src->value.s.v) : (char*)calloc(1,1); + if(!pnew->value.s.v){ + mosquitto_property_free_all(dest); + return MOSQ_ERR_NOMEM; + } + break; + + case MQTT_PROP_TYPE_BINARY: + pnew->value.bin.len = src->value.bin.len; + if(src->value.bin.len){ + pnew->value.bin.v = malloc(pnew->value.bin.len); + if(!pnew->value.bin.v){ + mosquitto_property_free_all(dest); + return MOSQ_ERR_NOMEM; + } + memcpy(pnew->value.bin.v, src->value.bin.v, pnew->value.bin.len); + } + break; + + case MQTT_PROP_TYPE_STRING_PAIR: + pnew->value.s.len = src->value.s.len; + pnew->value.s.v = src->value.s.v ? strdup(src->value.s.v) : (char*)calloc(1,1); + if(!pnew->value.s.v){ + mosquitto_property_free_all(dest); + return MOSQ_ERR_NOMEM; + } + + pnew->name.len = src->name.len; + pnew->name.v = src->name.v ? strdup(src->name.v) : (char*)calloc(1,1); + if(!pnew->name.v){ + mosquitto_property_free_all(dest); + return MOSQ_ERR_NOMEM; + } + break; + + default: + mosquitto_property_free_all(dest); + return MOSQ_ERR_INVAL; + } + + src = mosquitto_property_next(src); + } + + return MOSQ_ERR_SUCCESS; +} + + +uint8_t mosquitto_property_byte_value(const mosquitto_property *property) +{ + if(property && property->property_type == MQTT_PROP_TYPE_BYTE){ + return property->value.i8; + }else{ + return 0; + } +} + + +uint16_t mosquitto_property_int16_value(const mosquitto_property *property) +{ + if(property && property->property_type == MQTT_PROP_TYPE_INT16){ + return property->value.i16; + }else{ + return 0; + } +} + + +uint32_t mosquitto_property_int32_value(const mosquitto_property *property) +{ + if(property && property->property_type == MQTT_PROP_TYPE_INT32){ + return property->value.i32; + }else{ + return 0; + } +} + + +uint32_t mosquitto_property_varint_value(const mosquitto_property *property) +{ + if(property && property->property_type == MQTT_PROP_TYPE_VARINT){ + return property->value.varint; + }else{ + return 0; + } +} + + +const void *mosquitto_property_binary_value(const mosquitto_property *property) +{ + if(property && property->property_type == MQTT_PROP_TYPE_BINARY){ + return property->value.bin.v; + }else{ + return NULL; + } +} + + +uint16_t mosquitto_property_binary_value_length(const mosquitto_property *property) +{ + if(property && property->property_type == MQTT_PROP_TYPE_BINARY){ + return property->value.bin.len; + }else{ + return 0; + } +} + + +const char *mosquitto_property_string_value(const mosquitto_property *property) +{ + if(property && (property->property_type == MQTT_PROP_TYPE_STRING || property->property_type == MQTT_PROP_TYPE_STRING_PAIR)){ + return property->value.s.v; + }else{ + return NULL; + } +} + + +uint16_t mosquitto_property_string_value_length(const mosquitto_property *property) +{ + if(property && (property->property_type == MQTT_PROP_TYPE_STRING || property->property_type == MQTT_PROP_TYPE_STRING_PAIR)){ + return property->value.s.len; + }else{ + return 0; + } +} + + +const char *mosquitto_property_string_name(const mosquitto_property *property) +{ + if(property && property->property_type == MQTT_PROP_TYPE_STRING_PAIR){ + return property->name.v; + }else{ + return NULL; + } +} + + +uint16_t mosquitto_property_string_name_length(const mosquitto_property *property) +{ + if(property && property->property_type == MQTT_PROP_TYPE_STRING_PAIR){ + return property->name.len; + }else{ + return 0; + } +} + +/* Return the number of bytes we need to add on to the remaining length when + * encoding these properties. */ +unsigned int mosquitto_property_get_remaining_length(const mosquitto_property *props) +{ + unsigned int proplen, varbytes; + + proplen = mosquitto_property_get_length_all(props); + varbytes = mosquitto_varint_bytes(proplen); + return proplen + varbytes; +} + + diff --git a/libcommon/property_common.h b/libcommon/property_common.h new file mode 100644 index 000000000..be4accde5 --- /dev/null +++ b/libcommon/property_common.h @@ -0,0 +1,47 @@ +/* +Copyright (c) 2018-2021 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License 2.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + https://www.eclipse.org/legal/epl-2.0/ +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + +Contributors: + Roger Light - initial implementation and documentation. +*/ +#ifndef PROPERTY_COMMON_H +#define PROPERTY_COMMON_H + +#include +#include + +#include "mosquitto.h" + +struct mqtt__string { + char *v; + uint16_t len; +}; + +struct mqtt5__property { + struct mqtt5__property *next; + union { + uint8_t i8; + uint16_t i16; + uint32_t i32; + uint32_t varint; + struct mqtt__string bin; + struct mqtt__string s; + } value; + struct mqtt__string name; + int32_t identifier; + uint8_t property_type; + bool client_generated; +}; + +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 924dca523..e3bfd8fff 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -232,6 +232,7 @@ target_include_directories(mosquitto PRIVATE "${mosquitto_SOURCE_DIR}/common" "${mosquitto_SOURCE_DIR}/lib" + "${mosquitto_SOURCE_DIR}/libcommon" "${mosquitto_SOURCE_DIR}/src" ) if(WITH_BUNDLED_DEPS) diff --git a/src/Makefile b/src/Makefile index 8a30397b0..c8e8d7c76 100644 --- a/src/Makefile +++ b/src/Makefile @@ -4,7 +4,7 @@ include ${R}/config.mk .PHONY: all install uninstall clean reallyclean LOCAL_CFLAGS+= -LOCAL_CPPFLAGS+=-DWITH_BROKER -I${R}/lib +LOCAL_CPPFLAGS+=-DWITH_BROKER -I${R}/lib -I${R}/libcommon LOCAL_LDFLAGS+= LOCAL_LDADD+=-lcjson -lm ${LIB_ARGON2} ${LIBMOSQ_COMMON} diff --git a/src/bridge.c b/src/bridge.c index 5c4ff1976..5a4d480b8 100644 --- a/src/bridge.c +++ b/src/bridge.c @@ -41,12 +41,12 @@ Contributors: #include #endif -#include "mosquitto/mqtt_protocol.h" #include "mosquitto.h" #include "mosquitto_broker_internal.h" #include "mosquitto_internal.h" #include "net_mosq.h" #include "packet_mosq.h" +#include "property_common.h" #include "send_mosq.h" #include "sys_tree.h" #include "tls_mosq.h" diff --git a/src/loop.c b/src/loop.c index 71e76f017..ab1a86c83 100644 --- a/src/loop.c +++ b/src/loop.c @@ -48,6 +48,7 @@ Contributors: #include "mosquitto_broker_internal.h" #include "mosquitto/mqtt_protocol.h" #include "packet_mosq.h" +#include "property_common.h" #include "send_mosq.h" #include "sys_tree.h" #include "util_mosq.h" @@ -116,7 +117,7 @@ static void read_message_expiry_interval(mosquitto_property **proplist, uint32_t }else{ previous->next = mosquitto_property_next(p); } - property__free(&p); + mosquitto_property_free(&p); return; } diff --git a/src/persist_write_v5.c b/src/persist_write_v5.c index be878e53b..37818990f 100644 --- a/src/persist_write_v5.c +++ b/src/persist_write_v5.c @@ -34,6 +34,7 @@ Contributors: #include "mosquitto_broker_internal.h" #include "persist.h" #include "packet_mosq.h" +#include "property_common.h" #include "property_mosq.h" #include "util_mosq.h" @@ -95,7 +96,7 @@ int persist__chunk_client_msg_write_v6(FILE *db_fptr, struct P_client_msg *chunk if(chunk->subscription_identifier){ subscription_id_prop.value.varint = chunk->subscription_identifier; - proplen += property__get_remaining_length(&subscription_id_prop); + proplen += mosquitto_property_get_remaining_length(&subscription_id_prop); } chunk->F.mid = htons(chunk->F.mid); @@ -145,7 +146,7 @@ int persist__chunk_message_store_write_v6(FILE *db_fptr, struct P_base_msg *chun int rc; if(chunk->properties){ - proplen += property__get_remaining_length(chunk->properties); + proplen += mosquitto_property_get_remaining_length(chunk->properties); } chunk->F.payloadlen = htonl(chunk->F.payloadlen); diff --git a/src/property_broker.c b/src/property_broker.c index 535899c72..5286ec712 100644 --- a/src/property_broker.c +++ b/src/property_broker.c @@ -24,6 +24,7 @@ Contributors: #include "mosquitto_broker_internal.h" #include "mosquitto/mqtt_protocol.h" #include "property_mosq.h" +#include "property_common.h" /* Process the incoming properties, we should be able to assume that only valid * properties for CONNECT are present here. */ diff --git a/src/send_auth.c b/src/send_auth.c index e58a87810..a367dd6a2 100644 --- a/src/send_auth.c +++ b/src/send_auth.c @@ -47,7 +47,7 @@ int send__auth(struct mosquitto *context, uint8_t reason_code, const void *auth_ if(rc) goto error; } - remaining_length += property__get_remaining_length(properties); + remaining_length += mosquitto_property_get_remaining_length(properties); rc = packet__check_oversize(context, remaining_length); if(rc) goto error; diff --git a/src/send_connack.c b/src/send_connack.c index 4c78a2f02..fd146fdd7 100644 --- a/src/send_connack.c +++ b/src/send_connack.c @@ -75,7 +75,7 @@ int send__connack(struct mosquitto *context, uint8_t ack, uint8_t reason_code, c } } - remaining_length += property__get_remaining_length(connack_props); + remaining_length += mosquitto_property_get_remaining_length(connack_props); } if(packet__check_oversize(context, remaining_length)){ diff --git a/src/send_suback.c b/src/send_suback.c index 2e7444abf..80e6b8a0c 100644 --- a/src/send_suback.c +++ b/src/send_suback.c @@ -37,7 +37,7 @@ int send__suback(struct mosquitto *context, uint16_t mid, uint32_t payloadlen, c remaining_length = 2+payloadlen; if(context->protocol == mosq_p_mqtt5){ - remaining_length += property__get_remaining_length(properties); + remaining_length += mosquitto_property_get_remaining_length(properties); } rc = packet__alloc(&packet, CMD_SUBACK, remaining_length); if(rc){ diff --git a/src/send_unsuback.c b/src/send_unsuback.c index 65e86d892..7353132f5 100644 --- a/src/send_unsuback.c +++ b/src/send_unsuback.c @@ -37,7 +37,7 @@ int send__unsuback(struct mosquitto *mosq, uint16_t mid, int reason_code_count, remaining_length = 2; if(mosq->protocol == mosq_p_mqtt5){ - remaining_length += property__get_remaining_length(properties); + remaining_length += mosquitto_property_get_remaining_length(properties); remaining_length += (uint32_t)reason_code_count; } diff --git a/test/unit/broker/CMakeLists.txt b/test/unit/broker/CMakeLists.txt index c4b9d52d3..eae6ec0da 100644 --- a/test/unit/broker/CMakeLists.txt +++ b/test/unit/broker/CMakeLists.txt @@ -4,6 +4,7 @@ add_library(bridge-topic-obj ../../../src/bridge_topic.c ) target_compile_definitions(bridge-topic-obj PRIVATE WITH_BRIDGE WITH_BROKER) +target_include_directories(bridge-topic-obj PRIVATE ${mosquitto_SOURCE_DIR}/libcommon) target_link_libraries(bridge-topic-obj PUBLIC common-unit-test-header) add_executable(bridge-topic-test @@ -44,6 +45,7 @@ add_executable(persist-read-test ../../../lib/util_mosq.c ) target_compile_definitions(persist-read-test PRIVATE TEST_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}" WITH_PERSISTENCE WITH_BROKER) +target_include_directories(persist-read-test PRIVATE ${mosquitto_SOURCE_DIR}/libcommon) target_link_libraries(persist-read-test PRIVATE persistence-read-obj libmosquitto_common) add_test(NAME unit-persist-read-test COMMAND persist-read-test) @@ -62,6 +64,7 @@ add_library(persistence-write-obj ../../../src/topic_tok.c ) target_compile_definitions(persistence-write-obj PRIVATE WITH_PERSISTENCE WITH_BROKER) +target_include_directories(persistence-write-obj PRIVATE ${mosquitto_SOURCE_DIR}/libcommon) target_link_libraries(persistence-write-obj PUBLIC common-unit-test-header) add_executable(persist-write-test @@ -73,6 +76,7 @@ add_executable(persist-write-test ../../../lib/packet_mosq.c ) target_compile_definitions(persist-write-test PRIVATE TEST_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}" WITH_PERSISTENCE WITH_BROKER WITH_SYS_TREE) +target_include_directories(persist-write-test PRIVATE ${mosquitto_SOURCE_DIR}/libcommon) target_link_libraries(persist-write-test PRIVATE persistence-write-obj OpenSSL::SSL libmosquitto_common) add_test(NAME unit-persist-write-test COMMAND persist-write-test) @@ -86,6 +90,7 @@ add_library(subs-obj ../../../src/topic_tok.c ) target_compile_definitions(subs-obj PRIVATE WITH_BROKER) +target_include_directories(subs-obj PRIVATE ${mosquitto_SOURCE_DIR}/libcommon) target_link_libraries(subs-obj PUBLIC common-unit-test-header) add_executable(subs-test diff --git a/test/unit/broker/Makefile b/test/unit/broker/Makefile index 41749905a..7b33d1d57 100644 --- a/test/unit/broker/Makefile +++ b/test/unit/broker/Makefile @@ -5,7 +5,7 @@ include ${R}/make/broker.mk .PHONY: all check test test-compile clean coverage LOCAL_CFLAGS+=-coverage -LOCAL_CPPFLAGS+=-DWITH_BROKER -I${R}/src -I${R}/test -I${R}/lib -DTEST_SOURCE_DIR='"$(realpath .)"' -I${R}/lib +LOCAL_CPPFLAGS+=-DWITH_BROKER -I${R}/src -I${R}/test -I${R}/lib -DTEST_SOURCE_DIR='"$(realpath .)"' -I${R}/lib -I${R}/libcommon LOCAL_LDFLAGS+=-coverage LOCAL_LDADD+=-lcunit ${LIBMOSQ_COMMON} diff --git a/test/unit/broker/persist_read_test.c b/test/unit/broker/persist_read_test.c index 80fd9d61f..a17699f2e 100644 --- a/test/unit/broker/persist_read_test.c +++ b/test/unit/broker/persist_read_test.c @@ -10,6 +10,7 @@ #include "mosquitto_broker_internal.h" #include "persist.h" #include "property_mosq.h" +#include "property_common.h" char *last_sub = NULL; int last_qos; diff --git a/test/unit/lib/CMakeLists.txt b/test/unit/lib/CMakeLists.txt index 228396faa..5ba5a1484 100644 --- a/test/unit/lib/CMakeLists.txt +++ b/test/unit/lib/CMakeLists.txt @@ -2,11 +2,9 @@ add_executable(lib-test datatype_read.c datatype_write.c misc_trim_test.c - property_add.c property_read.c property_user_read.c property_write.c - property_value.c stubs.c # main test files test.c @@ -17,5 +15,6 @@ add_executable(lib-test ../../../lib/util_mosq.c ) +target_include_directories(lib-test PRIVATE ${mosquitto_SOURCE_DIR}/libcommon) target_link_libraries(lib-test PRIVATE common-unit-test-header OpenSSL::SSL libmosquitto_common) add_test(NAME unit-lib-test COMMAND lib-test) diff --git a/test/unit/lib/Makefile b/test/unit/lib/Makefile index 0fe2880a5..6f4dfe15b 100644 --- a/test/unit/lib/Makefile +++ b/test/unit/lib/Makefile @@ -4,7 +4,7 @@ include ${R}/config.mk .PHONY: all check test test-compile clean coverage LOCAL_CFLAGS+=-coverage -LOCAL_CPPFLAGS+=-I${R}/src -I${R}/test -I${R}/lib -DTEST_SOURCE_DIR='"$(realpath .)"' +LOCAL_CPPFLAGS+=-I${R}/src -I${R}/test -I${R}/lib -I${R}/libcommon -DTEST_SOURCE_DIR='"$(realpath .)"' LOCAL_LDFLAGS+=-coverage LOCAL_LDADD+=-lcunit ${LIBMOSQ_COMMON} @@ -17,11 +17,9 @@ TEST_OBJS = \ datatype_read.o \ datatype_write.o \ misc_trim_test.o \ - property_add.o \ property_read.o \ property_user_read.o \ property_write.o \ - property_value.o \ stubs.o \ LIB_OBJS = \ diff --git a/test/unit/lib/property_read.c b/test/unit/lib/property_read.c index 1505c6461..fa0b17fae 100644 --- a/test/unit/lib/property_read.c +++ b/test/unit/lib/property_read.c @@ -2,6 +2,7 @@ #include #include "mosquitto/mqtt_protocol.h" +#include "property_common.h" #include "property_mosq.h" #include "packet_mosq.h" @@ -28,7 +29,7 @@ static void byte_prop_read_helper( CU_ASSERT_EQUAL(properties->identifier, identifier); CU_ASSERT_EQUAL(properties->value.i8, value_expected); CU_ASSERT_PTR_EQUAL(properties->next, NULL); - CU_ASSERT_EQUAL(property__get_length_all(properties), 2); + CU_ASSERT_EQUAL(mosquitto_property_get_length_all(properties), 2); mosquitto_property_free_all(&properties); } CU_ASSERT_PTR_EQUAL(properties, NULL); @@ -87,7 +88,7 @@ static void int32_prop_read_helper( CU_ASSERT_EQUAL(properties->identifier, identifier); CU_ASSERT_EQUAL(properties->value.i32, value_expected); CU_ASSERT_PTR_EQUAL(properties->next, NULL); - CU_ASSERT_EQUAL(property__get_length_all(properties), 5); + CU_ASSERT_EQUAL(mosquitto_property_get_length_all(properties), 5); mosquitto_property_free_all(&properties); } CU_ASSERT_PTR_EQUAL(properties, NULL); @@ -137,7 +138,7 @@ static void int16_prop_read_helper( CU_ASSERT_EQUAL(properties->identifier, identifier); CU_ASSERT_EQUAL(properties->value.i16, value_expected); CU_ASSERT_PTR_EQUAL(properties->next, NULL); - CU_ASSERT_EQUAL(property__get_length_all(properties), 3); + CU_ASSERT_EQUAL(mosquitto_property_get_length_all(properties), 3); mosquitto_property_free_all(&properties); } CU_ASSERT_PTR_EQUAL(properties, NULL); @@ -183,7 +184,7 @@ static void string_prop_read_helper( CU_ASSERT_EQUAL(properties->value.s.len, strlen(value_expected)); CU_ASSERT_STRING_EQUAL(properties->value.s.v, value_expected); CU_ASSERT_PTR_EQUAL(properties->next, NULL); - CU_ASSERT_EQUAL(property__get_length_all(properties), 1+2+strlen(value_expected)); + CU_ASSERT_EQUAL(mosquitto_property_get_length_all(properties), 1+2+strlen(value_expected)); mosquitto_property_free_all(&properties); } CU_ASSERT_PTR_EQUAL(properties, NULL); @@ -248,7 +249,7 @@ static void binary_prop_read_helper( CU_ASSERT_EQUAL(properties->value.bin.len, len_expected); CU_ASSERT_EQUAL(memcmp(properties->value.bin.v, value_expected, (size_t)len_expected), 0); CU_ASSERT_PTR_EQUAL(properties->next, NULL); - CU_ASSERT_EQUAL(property__get_length_all(properties), 1+2+(unsigned int)len_expected); + CU_ASSERT_EQUAL(mosquitto_property_get_length_all(properties), 1+2+(unsigned int)len_expected); mosquitto_property_free_all(&properties); } CU_ASSERT_PTR_EQUAL(properties, NULL); @@ -302,7 +303,7 @@ static void string_pair_prop_read_helper( CU_ASSERT_PTR_NOT_NULL(properties->next); }else{ CU_ASSERT_PTR_NULL(properties->next); - CU_ASSERT_EQUAL(property__get_length_all(properties), 1+2+strlen(name_expected)+2+strlen(value_expected)); + CU_ASSERT_EQUAL(mosquitto_property_get_length_all(properties), 1+2+strlen(name_expected)+2+strlen(value_expected)); } mosquitto_property_free_all(&properties); } @@ -333,7 +334,7 @@ static void varint_prop_read_helper( CU_ASSERT_EQUAL(properties->identifier, identifier); CU_ASSERT_EQUAL(properties->value.varint, value_expected); CU_ASSERT_PTR_NULL(properties->next); - CU_ASSERT_EQUAL(property__get_length_all(properties), packet__varint_bytes(value_expected)+1); + CU_ASSERT_EQUAL(mosquitto_property_get_length_all(properties), mosquitto_varint_bytes(value_expected)+1); mosquitto_property_free_all(&properties); } CU_ASSERT_PTR_NULL(properties); diff --git a/test/unit/lib/property_write.c b/test/unit/lib/property_write.c index 49c3967c1..2b222b86a 100644 --- a/test/unit/lib/property_write.c +++ b/test/unit/lib/property_write.c @@ -2,6 +2,7 @@ #include #include "mosquitto/mqtt_protocol.h" +#include "property_common.h" #include "property_mosq.h" #include "packet_mosq.h" @@ -24,7 +25,7 @@ static void byte_prop_write_helper( property.value.i8 = value_expected; property.property_type = MQTT_PROP_TYPE_BYTE; - rc = packet__alloc(&packet, 0, property__get_length_all(&property)+11); + rc = packet__alloc(&packet, 0, mosquitto_property_get_length_all(&property)+11); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); if(rc != MOSQ_ERR_SUCCESS) return; @@ -48,7 +49,7 @@ static void byte_prop_write_helper( CU_ASSERT_EQUAL(mosquitto_property_type(properties), MQTT_PROP_TYPE_BYTE); CU_ASSERT_PTR_EQUAL(properties->next, NULL); CU_ASSERT_PTR_EQUAL(mosquitto_property_next(properties), NULL); - CU_ASSERT_EQUAL(property__get_length_all(properties), 2); + CU_ASSERT_EQUAL(mosquitto_property_get_length_all(properties), 2); mosquitto_property_free_all(&properties); } CU_ASSERT_PTR_EQUAL(properties, NULL); @@ -75,7 +76,7 @@ static void int32_prop_write_helper( property.value.i32 = value_expected; property.property_type = MQTT_PROP_TYPE_INT32; - rc = packet__alloc(&packet, 0, property__get_length_all(&property)+11); + rc = packet__alloc(&packet, 0, mosquitto_property_get_length_all(&property)+11); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); if(rc != MOSQ_ERR_SUCCESS) return; @@ -99,7 +100,7 @@ static void int32_prop_write_helper( CU_ASSERT_EQUAL(mosquitto_property_type(properties), MQTT_PROP_TYPE_INT32); CU_ASSERT_PTR_EQUAL(properties->next, NULL); CU_ASSERT_PTR_EQUAL(mosquitto_property_next(properties), NULL); - CU_ASSERT_EQUAL(property__get_length_all(properties), 5); + CU_ASSERT_EQUAL(mosquitto_property_get_length_all(properties), 5); mosquitto_property_free_all(&properties); } CU_ASSERT_PTR_EQUAL(properties, NULL); @@ -126,7 +127,7 @@ static void int16_prop_write_helper( property.value.i16 = value_expected; property.property_type = MQTT_PROP_TYPE_INT16; - rc = packet__alloc(&packet, 0, property__get_length_all(&property)+11); + rc = packet__alloc(&packet, 0, mosquitto_property_get_length_all(&property)+11); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); if(rc != MOSQ_ERR_SUCCESS) return; @@ -150,7 +151,7 @@ static void int16_prop_write_helper( CU_ASSERT_EQUAL(mosquitto_property_type(properties), MQTT_PROP_TYPE_INT16); CU_ASSERT_PTR_EQUAL(properties->next, NULL); CU_ASSERT_PTR_EQUAL(mosquitto_property_next(properties), NULL); - CU_ASSERT_EQUAL(property__get_length_all(properties), 3); + CU_ASSERT_EQUAL(mosquitto_property_get_length_all(properties), 3); mosquitto_property_free_all(&properties); } CU_ASSERT_PTR_EQUAL(properties, NULL); @@ -180,7 +181,7 @@ static void string_prop_write_helper( property.value.s.len = (uint16_t)strlen(value_expected); - rc = packet__alloc(&packet, 0, property__get_length_all(&property)+11); + rc = packet__alloc(&packet, 0, mosquitto_property_get_length_all(&property)+11); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); if(rc != MOSQ_ERR_SUCCESS) return; @@ -205,7 +206,7 @@ static void string_prop_write_helper( CU_ASSERT_EQUAL(mosquitto_property_type(properties), MQTT_PROP_TYPE_STRING); CU_ASSERT_PTR_EQUAL(properties->next, NULL); CU_ASSERT_PTR_EQUAL(mosquitto_property_next(properties), NULL); - CU_ASSERT_EQUAL(property__get_length_all(properties), 1+2+strlen(value_expected)); + CU_ASSERT_EQUAL(mosquitto_property_get_length_all(properties), 1+2+strlen(value_expected)); mosquitto_property_free_all(&properties); } CU_ASSERT_PTR_EQUAL(properties, NULL); @@ -239,7 +240,7 @@ static void binary_prop_write_helper( memcpy(property.value.bin.v, value_expected, len_expected); property.value.bin.len = len_expected; - rc = packet__alloc(&packet, 0, property__get_length_all(&property)+11); + rc = packet__alloc(&packet, 0, mosquitto_property_get_length_all(&property)+11); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); if(rc != MOSQ_ERR_SUCCESS) return; @@ -264,7 +265,7 @@ static void binary_prop_write_helper( CU_ASSERT_EQUAL(mosquitto_property_type(properties), MQTT_PROP_TYPE_BINARY); CU_ASSERT_PTR_EQUAL(properties->next, NULL); CU_ASSERT_PTR_EQUAL(mosquitto_property_next(properties), NULL); - CU_ASSERT_EQUAL(property__get_length_all(properties), 1+2+len_expected); + CU_ASSERT_EQUAL(mosquitto_property_get_length_all(properties), 1+2+len_expected); mosquitto_property_free_all(&properties); } CU_ASSERT_PTR_EQUAL(properties, NULL); @@ -301,7 +302,7 @@ static void string_pair_prop_write_helper( property.name.len = (uint16_t)strlen(name_expected); - rc = packet__alloc(&packet, 0, property__get_length_all(&property)+11); + rc = packet__alloc(&packet, 0, mosquitto_property_get_length_all(&property)+11); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); if(rc != MOSQ_ERR_SUCCESS) return; @@ -332,7 +333,7 @@ static void string_pair_prop_write_helper( }else{ CU_ASSERT_PTR_NULL(properties->next); CU_ASSERT_PTR_NULL(mosquitto_property_next(properties)); - CU_ASSERT_EQUAL(property__get_length_all(properties), 1+2+strlen(name_expected)+2+strlen(value_expected)); + CU_ASSERT_EQUAL(mosquitto_property_get_length_all(properties), 1+2+strlen(name_expected)+2+strlen(value_expected)); } mosquitto_property_free_all(&properties); } @@ -360,9 +361,9 @@ static void varint_prop_write_helper( property.property_type = MQTT_PROP_TYPE_VARINT; property.value.varint = value_expected; - CU_ASSERT_EQUAL(remaining_length, property__get_length_all(&property)+1); + CU_ASSERT_EQUAL(remaining_length, mosquitto_property_get_length_all(&property)+1); - rc = packet__alloc(&packet, 0, property__get_length_all(&property)+11); + rc = packet__alloc(&packet, 0, mosquitto_property_get_length_all(&property)+11); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); if(rc != MOSQ_ERR_SUCCESS) return; @@ -386,13 +387,13 @@ static void varint_prop_write_helper( CU_ASSERT_PTR_NULL(properties->next); CU_ASSERT_PTR_NULL(mosquitto_property_next(properties)); if(value_expected < 128){ - CU_ASSERT_EQUAL(property__get_length_all(properties), 2); + CU_ASSERT_EQUAL(mosquitto_property_get_length_all(properties), 2); }else if(value_expected < 16384){ - CU_ASSERT_EQUAL(property__get_length_all(properties), 3); + CU_ASSERT_EQUAL(mosquitto_property_get_length_all(properties), 3); }else if(value_expected < 2097152){ - CU_ASSERT_EQUAL(property__get_length_all(properties), 4); + CU_ASSERT_EQUAL(mosquitto_property_get_length_all(properties), 4); }else if(value_expected < 268435456){ - CU_ASSERT_EQUAL(property__get_length_all(properties), 5); + CU_ASSERT_EQUAL(mosquitto_property_get_length_all(properties), 5); }else{ CU_FAIL("Incorrect varint value."); } diff --git a/test/unit/lib/test.c b/test/unit/lib/test.c index cd8c7d501..d6ee10ba4 100644 --- a/test/unit/lib/test.c +++ b/test/unit/lib/test.c @@ -6,11 +6,9 @@ int init_datatype_read_tests(void); int init_datatype_write_tests(void); -int init_property_add_tests(void); int init_property_read_tests(void); int init_property_user_read_tests(void); int init_property_write_tests(void); -int init_property_value_tests(void); int init_misc_trim_tests(void); int main(int argc, char *argv[]) @@ -28,11 +26,9 @@ int main(int argc, char *argv[]) if(0 || init_datatype_read_tests() || init_datatype_write_tests() - || init_property_add_tests() || init_property_read_tests() || init_property_user_read_tests() || init_property_write_tests() - || init_property_value_tests() || init_misc_trim_tests() ){ diff --git a/test/unit/libcommon/CMakeLists.txt b/test/unit/libcommon/CMakeLists.txt index b5337ea24..76a8537c8 100644 --- a/test/unit/libcommon/CMakeLists.txt +++ b/test/unit/libcommon/CMakeLists.txt @@ -1,10 +1,16 @@ add_executable(libcommon-test + property_add.c + property_value.c strings_test.c test.c topic_test.c utf8.c ) +target_include_directories(libcommon-test + PRIVATE + ${mosquitto_SOURCE_DIR}/libcommon +) target_link_libraries(libcommon-test PRIVATE common-unit-test-header diff --git a/test/unit/libcommon/Makefile b/test/unit/libcommon/Makefile index 4fdda0f93..a69877430 100644 --- a/test/unit/libcommon/Makefile +++ b/test/unit/libcommon/Makefile @@ -4,7 +4,7 @@ include ${R}/config.mk .PHONY: all check test test-compile clean coverage LOCAL_CFLAGS+=-coverage -LOCAL_CPPFLAGS+=-I${R}/src -I${R}/test -I${R}/lib -DTEST_SOURCE_DIR='"$(realpath .)"' +LOCAL_CPPFLAGS+=-I${R}/libcommon -DTEST_SOURCE_DIR='"$(realpath .)"' LOCAL_LDFLAGS+=-coverage LOCAL_LDADD+=-lcunit ${LIBMOSQ_COMMON} @@ -13,6 +13,8 @@ ifeq ($(WITH_TLS),yes) endif TEST_OBJS = \ + property_add.o \ + property_value.o \ strings_test.o \ test.o \ topic_test.o \ diff --git a/test/unit/lib/property_add.c b/test/unit/libcommon/property_add.c similarity index 98% rename from test/unit/lib/property_add.c rename to test/unit/libcommon/property_add.c index c0e705e10..a24b3c54f 100644 --- a/test/unit/lib/property_add.c +++ b/test/unit/libcommon/property_add.c @@ -2,8 +2,7 @@ #include #include "mosquitto/mqtt_protocol.h" -#include "property_mosq.h" -#include "packet_mosq.h" +#include "property_common.h" static void check_count(mosquitto_property *proplist, int expected) { @@ -585,7 +584,7 @@ static void TEST_check_length(void) unsigned int varbytes; unsigned int i; - len = property__get_remaining_length(proplist); + len = mosquitto_property_get_remaining_length(proplist); CU_ASSERT_EQUAL(len, 1); for(i=1; i<10000; i++){ @@ -593,7 +592,7 @@ static void TEST_check_length(void) CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); CU_ASSERT_PTR_NOT_NULL(proplist); if(proplist){ - len = property__get_remaining_length(proplist); + len = mosquitto_property_get_remaining_length(proplist); if(i < 64){ varbytes = 1; }else if(i < 8192){ @@ -615,7 +614,7 @@ static void TEST_remove_single(void) int rc; unsigned int len; - len = property__get_remaining_length(proplist); + len = mosquitto_property_get_remaining_length(proplist); CU_ASSERT_EQUAL(len, 1); for(int i=1; i<10; i++){ @@ -688,7 +687,7 @@ static void TEST_remove_non_existent(void) int rc; unsigned int len; - len = property__get_remaining_length(proplist); + len = mosquitto_property_get_remaining_length(proplist); CU_ASSERT_EQUAL(len, 1); rc = mosquitto_property_add_byte(&proplist, MQTT_PROP_SHARED_SUB_AVAILABLE, 0); @@ -716,7 +715,7 @@ static void TEST_remove_invalid(void) rc = mosquitto_property_remove(NULL, NULL); CU_ASSERT_EQUAL(rc, MOSQ_ERR_INVAL); - len = property__get_remaining_length(proplist); + len = mosquitto_property_get_remaining_length(proplist); CU_ASSERT_EQUAL(len, 1); rc = mosquitto_property_add_byte(&proplist, MQTT_PROP_SHARED_SUB_AVAILABLE, 0); diff --git a/test/unit/lib/property_value.c b/test/unit/libcommon/property_value.c similarity index 99% rename from test/unit/lib/property_value.c rename to test/unit/libcommon/property_value.c index f09202f7a..a346852ca 100644 --- a/test/unit/lib/property_value.c +++ b/test/unit/libcommon/property_value.c @@ -2,8 +2,7 @@ #include #include "mosquitto/mqtt_protocol.h" -#include "property_mosq.h" -#include "packet_mosq.h" +#include "property_common.h" static void TEST_value_byte_success(void) { diff --git a/test/unit/libcommon/test.c b/test/unit/libcommon/test.c index 247441a85..c58fbc107 100644 --- a/test/unit/libcommon/test.c +++ b/test/unit/libcommon/test.c @@ -4,6 +4,8 @@ #include #include +int init_property_add_tests(void); +int init_property_value_tests(void); int init_strings_tests(void); int init_topic_tests(void); int init_utf8_tests(void); @@ -21,6 +23,8 @@ int main(int argc, char *argv[]) } if(0 + || init_property_add_tests() + || init_property_value_tests() || init_strings_tests() || init_topic_tests() || init_utf8_tests() diff --git a/test/unit/libcommon/topic_test.c b/test/unit/libcommon/topic_test.c index 95ae6eadd..4e9ad7afa 100644 --- a/test/unit/libcommon/topic_test.c +++ b/test/unit/libcommon/topic_test.c @@ -1,7 +1,7 @@ #include #include -#include +#include struct topic_test{ const char *topic_filter;