From 7697406d3aa540371590c7675448f493dde616e1 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 15 Sep 2021 10:54:09 +0100 Subject: [PATCH] Add topic modification example plugin. --- plugins/README.md | 9 ++ plugins/examples/CMakeLists.txt | 1 + plugins/examples/Makefile | 3 +- .../topic-modification/CMakeLists.txt | 24 +++++ plugins/examples/topic-modification/Makefile | 28 ++++++ .../mosquitto_topic_modification.c | 99 +++++++++++++++++++ plugins/examples/topic-modification/test.conf | 1 + plugins/examples/topic-modification/test.sh | 3 + 8 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 plugins/examples/topic-modification/CMakeLists.txt create mode 100644 plugins/examples/topic-modification/Makefile create mode 100644 plugins/examples/topic-modification/mosquitto_topic_modification.c create mode 100644 plugins/examples/topic-modification/test.conf create mode 100755 plugins/examples/topic-modification/test.sh diff --git a/plugins/README.md b/plugins/README.md index db545c77..523d771c 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -59,3 +59,12 @@ contents. ## Examples / Print IP on publish This is an **example** plugin that prints out client ID and IP address of any client that publishes on a particular topic. + +## Examples / Topic modification +This is an **example** plugin to demonstrate how it is possible to modify the +topic of messages after they have been received, and before they are sent on +to subscribers. + +This plugin removes the `/uplink` end part of topics that match the pattern +`device/+/data/uplink`, so devices publishing to `device/0001/data/uplink` will +effectively be publishing to `device/0001/data`. diff --git a/plugins/examples/CMakeLists.txt b/plugins/examples/CMakeLists.txt index dd5d6e3b..4c01a2a0 100644 --- a/plugins/examples/CMakeLists.txt +++ b/plugins/examples/CMakeLists.txt @@ -9,3 +9,4 @@ add_subdirectory(delayed-auth) add_subdirectory(force-retain) add_subdirectory(payload-modification) add_subdirectory(print-ip-on-publish) +add_subdirectory(topic-modification) diff --git a/plugins/examples/Makefile b/plugins/examples/Makefile index f341dea3..bf208d59 100644 --- a/plugins/examples/Makefile +++ b/plugins/examples/Makefile @@ -7,7 +7,8 @@ DIRS= \ force-retain \ message-timestamp \ payload-modification \ - print-ip-on-publish + print-ip-on-publish \ + topic-modification .PHONY : all binary check clean reallyclean test install uninstall diff --git a/plugins/examples/topic-modification/CMakeLists.txt b/plugins/examples/topic-modification/CMakeLists.txt new file mode 100644 index 00000000..7d38cc22 --- /dev/null +++ b/plugins/examples/topic-modification/CMakeLists.txt @@ -0,0 +1,24 @@ +add_library(mosquitto_topic_modification MODULE + mosquitto_topic_modification.c +) + +target_include_directories(mosquitto_topic_modification PRIVATE + "${OPENSSL_INCLUDE_DIR}" + "${STDBOOL_H_PATH}" + "${STDINT_H_PATH}" + "${mosquitto_SOURCE_DIR}" + "${mosquitto_SOURCE_DIR}/include" +) + +link_directories(${mosquitto_SOURCE_DIR}) + +set_target_properties(mosquitto_topic_modification PROPERTIES + PREFIX "" + POSITION_INDEPENDENT_CODE 1 +) +if(WIN32) + target_link_libraries(mosquitto_topic_modification mosquitto) +endif() + +# Don't install, these are example plugins only. +#install(TARGETS mosquitto_topic_modification RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") diff --git a/plugins/examples/topic-modification/Makefile b/plugins/examples/topic-modification/Makefile new file mode 100644 index 00000000..1939337b --- /dev/null +++ b/plugins/examples/topic-modification/Makefile @@ -0,0 +1,28 @@ +include ../../../config.mk + +.PHONY : all binary check clean reallyclean test install uninstall + +PLUGIN_NAME=mosquitto_topic_modification +PLUGIN_CFLAGS+=-I../../../include -I../../../ + +all : binary + +binary : ${PLUGIN_NAME}.so + +${PLUGIN_NAME}.so : ${PLUGIN_NAME}.c + $(CROSS_COMPILE)$(CC) $(PLUGIN_CPPFLAGS) $(PLUGIN_CFLAGS) $(PLUGIN_LDFLAGS) -fPIC -shared $< -o $@ + +reallyclean : clean +clean: + -rm -f *.o ${PLUGIN_NAME}.so *.gcda *.gcno + +check: test +test: + +install: ${PLUGIN_NAME}.so + # Don't install, these are examples only. + #$(INSTALL) -d "${DESTDIR}$(libdir)" + #$(INSTALL) ${STRIP_OPTS} ${PLUGIN_NAME}.so "${DESTDIR}${libdir}/${PLUGIN_NAME}.so" + +uninstall : + -rm -f "${DESTDIR}${libdir}/${PLUGIN_NAME}.so" diff --git a/plugins/examples/topic-modification/mosquitto_topic_modification.c b/plugins/examples/topic-modification/mosquitto_topic_modification.c new file mode 100644 index 00000000..fe5be704 --- /dev/null +++ b/plugins/examples/topic-modification/mosquitto_topic_modification.c @@ -0,0 +1,99 @@ +/* +Copyright (c) 2020 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. +*/ + +/* + * This is an *example* plugin which demonstrates how to modify the topic of + * a message after it is received by the broker and before it is sent on to + * other clients. + * + * You should be very sure of what you are doing before making use of this feature. + * + * Compile with: + * gcc -I -fPIC -shared mosquitto_topic_modification.c -o mosquitto_topic_modification.so + * + * Use in config with: + * + * plugin /path/to/mosquitto_topic_modification.so + * + * Note that this only works on Mosquitto 2.0 or later. + */ +#include +#include + +#include "mosquitto_broker.h" +#include "mosquitto_plugin.h" +#include "mosquitto.h" +#include "mqtt_protocol.h" + +#define PLUGIN_NAME "topic-modification" +#define PLUGIN_VERSION "1.0" + +#define UNUSED(A) (void)(A) + +static mosquitto_plugin_id_t *mosq_pid = NULL; + +static int callback_message(int event, void *event_data, void *userdata) +{ + struct mosquitto_evt_message *ed = event_data; + bool result; + + UNUSED(event); + UNUSED(userdata); + + /* This simply removes "/uplink" from the end of every matching topic. You + * can of course do much more complicated message processing if needed. */ + + mosquitto_topic_matches_sub("device/+/data/uplink", ed->topic, &result); + + if(result){ + ed->topic[strlen(ed->topic) - strlen("/uplink")] = '\0'; + } + + return MOSQ_ERR_SUCCESS; +} + +int mosquitto_plugin_version(int supported_version_count, const int *supported_versions) +{ + int i; + + for(i=0; i