Skip to content

Commit

Permalink
minor improvements on the mqtt feature
Browse files Browse the repository at this point in the history
  • Loading branch information
tillz committed Jun 19, 2018
1 parent 0269494 commit c445510
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 19 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ What else?
* Metadata — Shairport Sync can deliver metadata supplied by the source, such as Album Name, Artist Name, Cover Art, etc. through a pipe or UDP socket to a recipient application program — see https://github.com/mikebrady/shairport-sync-metadata-reader for a sample recipient. Sources that supply metadata include iTunes and the Music app in iOS.
* Raw Audio — Shairport Sync can deliver raw PCM audio to standard output or to a pipe. This output is delivered synchronously with the source after the appropriate latency and is not interpolated or "stuffed" on its way through Shairport Sync.
* Autotools and Libtool Support — the Shairport Sync build process uses GNU `autotools` and `libtool` to examine and configure the build environment — important for portability and for cross compilation. Previous versions of Shairport looked at the current system to determine which packages were available, instead of looking at the target system for what packages were available.
* A native mqtt interface for metadata and/or controls

Heritage
-------
Expand Down Expand Up @@ -124,6 +125,7 @@ The following libraries are required:
Optional:
* libsoxr
* libalac (This is a library containing the Apple ALAC decoder.)
* libmosquitto (To enable the mqtt-metadata-interface)

Many Linux distributions have Avahi and OpenSSL already in place, so normally it probably makes sense to choose those options rather than tinysvcmdns or mbed TLS. The `libsoxr` library is available in recent Linux distributions, but it requires lots of processor power — chances are an embedded processor won't be able to keep up.

Expand Down Expand Up @@ -166,6 +168,7 @@ $ autoreconf -i -f
- `--with-soxr` for libsoxr-based resampling.
- `--with-piddir` for specifying where the PID file should be stored. This directory is normally chosen automatically. The directory must be writable. If you use this option, you may have to edit the init script to search for the PID file in your new location.
- `--with-metadata` to add support for Shairport Sync to pipe metadata to a compatible application of your choice. See https://github.com/mikebrady/shairport-sync-metadata-reader for a sample metadata reader.
- `--with-mqtt-client` to add support for publishing metadata and remote control via [MQTT](https://en.wikipedia.org/wiki/MQTT)
- `--with-configfiles` to install a configuration file and a separate sample file at the `make install` stage. Default is to install. An existing `/etc/shairport-sync.conf` will not be overwritten.
- `--with-pkg-config` to use pkg-config to find libraries. Default is to use pkg-config — this option is for special purpose use.
- `--with-apple-alac` to include the Apple ALAC Decoder.
Expand Down
4 changes: 2 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ AM_CONDITIONAL([USE_MPRIS_CLIENT], [test "x$HAS_MPRIS_CLIENT" = "x1"])
#AM_CONDITIONAL([USE_DBUS_CORE_AND_DACP], [test "x$HAS_MPRIS" = "x1" -o "x$HAS_DBUS" = "x1"])

# Look for mqtt flag
AC_ARG_WITH(mqtt-interface, [ --with-mqtt-interface = include support for the native Shairport Sync MQTT interface], [
AC_ARG_WITH(mqtt-client, [ --with-mqtt-client = include support for the native Shairport Sync MQTT interface], [
AC_MSG_RESULT(>>Including MQTT support)
HAS_MQTT=1
AC_DEFINE([HAVE_MQTT], 1, [Needed by the compiler.])
Expand All @@ -332,7 +332,7 @@ AC_ARG_WITH(mqtt-interface, [ --with-mqtt-interface = include support for the n
AM_CONDITIONAL([USE_MQTT], [test "x$HAS_MQTT" = "x1"])


if test "x$HAS_MPRIS" = "x1" -o "x$HAS_DBUS" = "x1" -o "x$HAS_MQTT"; then
if test "x$HAS_MPRIS" = "x1" || test "x$HAS_DBUS" = "x1" || test "x$HAS_MQTT" = "x1"; then
AC_MSG_RESULT(>>Including the metadata hub)
HAS_METADATA_HUB=1
AC_DEFINE([HAVE_METADATA_HUB], 1, [Needed by the compiler.])
Expand Down
40 changes: 23 additions & 17 deletions mqtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
#include "mqtt.h"

//this holds the mosquitto client
struct mosquitto *mosq = NULL;
struct mosquitto *global_mosq = NULL;
char *topic = NULL;

//mosquitto logging
void _cb_log(struct mosquitto *mosq, void *userdata, int level, const char *str){
void _cb_log( __attribute__((unused)) struct mosquitto *mosq,
__attribute__((unused)) void *userdata, int level, const char *str){
switch(level){
case MOSQ_LOG_DEBUG:
debug(1, str);
Expand All @@ -40,7 +41,8 @@ void _cb_log(struct mosquitto *mosq, void *userdata, int level, const char *str)
}

//mosquitto message handler
void on_message(struct mosquitto* mosq, void* userdata, const struct mosquitto_message* msg){
void on_message( __attribute__((unused)) struct mosquitto* mosq,
__attribute__((unused)) void* userdata, const struct mosquitto_message* msg){

//null-terminate the payload
char payload[msg->payloadlen+1];
Expand All @@ -59,7 +61,7 @@ void on_message(struct mosquitto* mosq, void* userdata, const struct mosquitto_m

//send command if it's a valid one
while(commands[it++]!=NULL){
if( msg->payloadlen>=strlen(commands[it]) &&
if( (size_t)msg->payloadlen>=strlen(commands[it]) &&
strncmp(msg->payload, commands[it], strlen(commands[it]))==0
){
debug(1, "[MQTT]: DACP Command: %s\n",commands[it]);
Expand All @@ -69,11 +71,15 @@ void on_message(struct mosquitto* mosq, void* userdata, const struct mosquitto_m
}
}

void on_disconnect(struct mosquitto* mosq, void* userdata, int rc){
void on_disconnect( __attribute__((unused)) struct mosquitto* mosq,
__attribute__((unused)) void* userdata,
__attribute__((unused)) int rc){
debug(1, "[MQTT]: disconnected");
}

void on_connect(struct mosquitto* mosq, void* userdata, int rc){
void on_connect(struct mosquitto* mosq,
__attribute__((unused)) void* userdata,
__attribute__((unused)) int rc){
debug(1, "[MQTT]: connected");

//subscribe if requested
Expand All @@ -89,7 +95,7 @@ void mqtt_publish(char* topic, char* data, uint32_t length){
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(1, "[MQTT]: publishing under %s",fulltopic);
mosquitto_publish(mosq, NULL, fulltopic, length, data, 0, 0);
mosquitto_publish(global_mosq, NULL, fulltopic, length, data, 0, 0);
}

//handler for incoming metadata
Expand Down Expand Up @@ -167,8 +173,8 @@ int initialise_mqtt() {
}
int keepalive = 60;
mosquitto_lib_init();
if( !(mosq = mosquitto_new(config.service_name, true, NULL)) ){
die("[MQTT]: FATAL: Could not create mosquitto object! %d\n", mosq);
if( !(global_mosq = mosquitto_new(config.service_name, true, NULL)) ){
die("[MQTT]: FATAL: Could not create mosquitto object! %d\n", global_mosq);
}

if(
Expand All @@ -177,7 +183,7 @@ int initialise_mqtt() {
config.mqtt_certfile != NULL ||
config.mqtt_keyfile != NULL
){
if(mosquitto_tls_set(mosq,config.mqtt_cafile, config.mqtt_capath, config.mqtt_certfile, config.mqtt_keyfile, NULL) != MOSQ_ERR_SUCCESS) {
if(mosquitto_tls_set(global_mosq,config.mqtt_cafile, config.mqtt_capath, config.mqtt_certfile, config.mqtt_keyfile, NULL) != MOSQ_ERR_SUCCESS) {
die("[MQTT]: TLS Setup failed");
}
}
Expand All @@ -186,22 +192,22 @@ int initialise_mqtt() {
config.mqtt_username != NULL ||
config.mqtt_password != NULL
){
if(mosquitto_username_pw_set(mosq,config.mqtt_username,config.mqtt_password) != MOSQ_ERR_SUCCESS) {
if(mosquitto_username_pw_set(global_mosq,config.mqtt_username,config.mqtt_password) != MOSQ_ERR_SUCCESS) {
die("[MQTT]: Username/Password set failed");
}
}
mosquitto_log_callback_set(mosq, _cb_log);
mosquitto_log_callback_set(global_mosq, _cb_log);

if(config.mqtt_enable_remote){
mosquitto_message_callback_set(mosq, on_message);
mosquitto_message_callback_set(global_mosq, on_message);
}

mosquitto_disconnect_callback_set(mosq, on_disconnect);
mosquitto_connect_callback_set(mosq, on_connect);
if(mosquitto_connect(mosq, config.mqtt_hostname, config.mqtt_port, keepalive)){
mosquitto_disconnect_callback_set(global_mosq, on_disconnect);
mosquitto_connect_callback_set(global_mosq, on_connect);
if(mosquitto_connect(global_mosq, config.mqtt_hostname, config.mqtt_port, keepalive)){
inform("[MQTT]: Could not establish a mqtt connection");
}
if(mosquitto_loop_start(mosq) != MOSQ_ERR_SUCCESS){
if(mosquitto_loop_start(global_mosq) != MOSQ_ERR_SUCCESS){
inform("[MQTT]: Could start MQTT Main loop");
}

Expand Down

0 comments on commit c445510

Please sign in to comment.