From: Mike Brady <4265913+mikebrady@users.noreply.github.com> Date: Mon, 7 Feb 2022 12:36:08 +0000 (+0000) Subject: MQTT -- add code to deal with empty payloads by adding a dummy payload to empty messa... X-Git-Tag: 4.1-rc1~24^2~286 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3d720d65bf506d246a5d7210e391e0090de4b7bc;p=thirdparty%2Fshairport-sync.git MQTT -- add code to deal with empty payloads by adding a dummy payload to empty messages by default. --- diff --git a/common.h b/common.h index 904b9279..f81540b7 100644 --- a/common.h +++ b/common.h @@ -151,6 +151,7 @@ typedef struct { int mqtt_publish_parsed; int mqtt_publish_cover; int mqtt_enable_remote; + char *mqtt_empty_payload_substitute; #endif uint8_t hw_addr[8]; // only needs 6 but 8 is handy when converting this to a number int port; diff --git a/mqtt.c b/mqtt.c index c4982d99..c6808515 100644 --- a/mqtt.c +++ b/mqtt.c @@ -93,12 +93,20 @@ void on_connect(struct mosquitto *mosq, __attribute__((unused)) void *userdata, } // helper function to publish under a topic and automatically append the main topic -void mqtt_publish(char *topic, char *data, uint32_t length) { +void mqtt_publish(char *topic, char *data_in, uint32_t length_in) { + char *data = data_in; + uint32_t length = length_in; + + if ((length == 0) && (config.mqtt_empty_payload_substitute != NULL)) { + length = strlen(config.mqtt_empty_payload_substitute); + data = config.mqtt_empty_payload_substitute; + } + char fulltopic[strlen(config.mqtt_topic) + strlen(topic) + 3]; snprintf(fulltopic, strlen(config.mqtt_topic) + strlen(topic) + 2, "%s/%s", config.mqtt_topic, topic); debug(2, "[MQTT]: publishing under %s", fulltopic); - + int rc; if ((rc = mosquitto_publish(global_mosq, NULL, fulltopic, length, data, 0, 0)) != MOSQ_ERR_SUCCESS) { diff --git a/scripts/shairport-sync.conf b/scripts/shairport-sync.conf index edb204d5..730b4c1c 100644 --- a/scripts/shairport-sync.conf +++ b/scripts/shairport-sync.conf @@ -224,6 +224,12 @@ metadata = // How to enable the MQTT-metadata/remote-service // For this section to be operative, Shairport Sync must be built with the following configuration flag: // --with-mqtt-client + +// Note that, for compatability with many MQTT brokers and applications, +// every message that has no extra data is given a +// payload consisting of the string "--". +// You can change this or you can enable empty payloads -- see below. + mqtt = { // enabled = "no"; // set this to yes to enable the mqtt-metadata-service @@ -238,8 +244,10 @@ mqtt = // topic = NULL; //MQTT topic where this instance of shairport-sync should publish. If not set, the general.name value is used. // publish_raw = "no"; //whether to publish all available metadata under the codes given in the 'metadata' docs. // publish_parsed = "no"; //whether to publish a small (but useful) subset of metadata under human-understandable topics +// empty_payload_substitute = "--"; // MQTT messages with empty payloads often are invisible or have special significance to MQTT brokers and readers. +// To avoid empty payload problems, the string here is used instead of any empty payload. Set it to the empty string -- "" -- to leave the payload empty. // Currently published topics:artist,album,title,genre,format,songalbum,volume,client_ip, -// Additionally, empty messages at the topics play_start,play_end,play_flush,play_resume are published +// Additionally, messages at the topics play_start,play_end,play_flush,play_resume are published // publish_cover = "no"; //whether to publish the cover over mqtt in binary form. This may lead to a bit of load on the broker // enable_remote = "no"; //whether to remote control via MQTT. RC is available under `topic`/remote. // Available commands are "command", "beginff", "beginrew", "mutetoggle", "nextitem", "previtem", "pause", "playpause", "play", "stop", "playresume", "shuffle_songs", "volumedown", "volumeup" diff --git a/shairport.c b/shairport.c index 89a57961..e9fdd8d2 100644 --- a/shairport.c +++ b/shairport.c @@ -1181,6 +1181,14 @@ int parse_options(int argc, char **argv) { die("You need to have metadata.include_cover_art enabled in order to use mqtt.publish_cover"); } config_set_lookup_bool(config.cfg, "mqtt.enable_remote", &config.mqtt_enable_remote); + if (config_lookup_string(config.cfg, "mqtt.empty_payload_substitute", &str)) { + if (strlen(str) == 0) + config.mqtt_empty_payload_substitute = NULL; + else + config.mqtt_empty_payload_substitute = strdup(str); + } else { + config.mqtt_empty_payload_substitute = strdup("--"); + } #ifndef CONFIG_AVAHI if (config.mqtt_enable_remote) { die("You have enabled MQTT remote control which requires shairport-sync to be built with " @@ -1191,7 +1199,7 @@ int parse_options(int argc, char **argv) { #endif #ifdef CONFIG_AIRPLAY_2 - int64_t aid; + long long aid; // replace the airplay_device_id with this, if provided if (config_lookup_int64(config.cfg, "general.airplay_device_id", &aid)) { @@ -1510,6 +1518,11 @@ void exit_function() { if (config.service_name) free(config.service_name); +#ifdef CONFIG_MQTT + if (config.mqtt_empty_payload_substitute) + free(config.mqtt_empty_payload_substitute); +#endif + #ifdef CONFIG_CONVOLUTION if (config.convolution_ir_file) free(config.convolution_ir_file);