forked from mikebrady/shairport-sync
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
388 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
|
||
#include "config.h" | ||
|
||
#include "common.h" | ||
#include "player.h" | ||
#include "rtsp.h" | ||
|
||
#include "rtp.h" | ||
|
||
#include "dacp.h" | ||
#include <mosquitto.h> | ||
#include "mqtt.h" | ||
|
||
//this holds the mosquitto client | ||
struct mosquitto *mosq = NULL; | ||
char *topic = NULL; | ||
|
||
//mosquitto logging | ||
void _cb_log(struct mosquitto *mosq, void *userdata, int level, const char *str){ | ||
switch(level){ | ||
case MOSQ_LOG_DEBUG: | ||
debug(1, str); | ||
break; | ||
case MOSQ_LOG_INFO: | ||
debug(2, str); | ||
break; | ||
case MOSQ_LOG_NOTICE: | ||
debug(3, str); | ||
break; | ||
case MOSQ_LOG_WARNING: | ||
inform(str); | ||
break; | ||
case MOSQ_LOG_ERR: { | ||
die("MQTT: Error: %s\n", str); | ||
} | ||
} | ||
} | ||
|
||
//mosquitto message handler | ||
void on_message(struct mosquitto* mosq, void* userdata, const struct mosquitto_message* msg){ | ||
|
||
//null-terminate the payload | ||
char payload[msg->payloadlen+1]; | ||
memcpy(payload,msg->payload,msg->payloadlen); | ||
payload[msg->payloadlen]=0; | ||
|
||
debug(1, "[MQTT]: received Message on topic %s: %s\n",msg->topic, payload); | ||
|
||
//All recognized commands | ||
char* commands[] = { | ||
"command", "beginff", "beginrew", "mutetoggle", "nextitem", "previtem", "pause", | ||
"playpause", "play", "stop", "playresume", "shuffle_songs", "volumedown", "volumeup", | ||
NULL}; | ||
|
||
int it=0; | ||
|
||
//send command if it's a valid one | ||
while(commands[it++]!=NULL){ | ||
if( msg->payloadlen>=strlen(commands[it]) && | ||
strncmp(msg->payload, commands[it], strlen(commands[it]))==0 | ||
){ | ||
debug(1, "[MQTT]: DACP Command: %s\n",commands[it]); | ||
send_simple_dacp_command(commands[it]); | ||
break; | ||
} | ||
} | ||
} | ||
|
||
void on_disconnect(struct mosquitto* mosq, void* userdata, int rc){ | ||
debug(1, "[MQTT]: disconnected"); | ||
} | ||
|
||
void on_connect(struct mosquitto* mosq, void* userdata, int rc){ | ||
debug(1, "[MQTT]: connected"); | ||
|
||
//subscribe if requested | ||
if(config.mqtt_enable_remote){ | ||
char remotetopic[strlen(config.mqtt_topic)+8]; | ||
snprintf(remotetopic,strlen(config.mqtt_topic)+8,"%s/remote",config.mqtt_topic); | ||
mosquitto_subscribe(mosq,NULL,remotetopic,0); | ||
} | ||
} | ||
|
||
//helper function to publish under a topic and automatically append the main topic | ||
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); | ||
} | ||
|
||
//handler for incoming metadata | ||
void mqtt_process_metadata(uint32_t type, uint32_t code, char *data, uint32_t length){ | ||
if(config.mqtt_publish_raw){ | ||
uint32_t val; | ||
char topic[] = "____/____"; | ||
|
||
val=htonl(type); | ||
memcpy(topic,&val, 4); | ||
val=htonl(code); | ||
memcpy(topic+5,&val, 4); | ||
mqtt_publish(topic, data, length); | ||
} | ||
if(config.mqtt_publish_parsed){ | ||
if(type=='core'){ | ||
switch (code) { | ||
case 'asar': | ||
mqtt_publish("artist", data, length); | ||
break; | ||
case 'asal': | ||
mqtt_publish("album", data, length); | ||
break; | ||
case 'minm': | ||
mqtt_publish("title", data, length); | ||
break; | ||
case 'asgn': | ||
mqtt_publish("genre", data, length); | ||
break; | ||
case 'asfm': | ||
mqtt_publish("format", data, length); | ||
break; | ||
} | ||
}else if(type=='ssnc'){ | ||
switch (code) { | ||
case 'asal': | ||
mqtt_publish("songalbum", data, length); | ||
break; | ||
case 'pvol': | ||
mqtt_publish("volume", data, length); | ||
break; | ||
case 'clip': | ||
mqtt_publish("client_ip", data, length); | ||
break; | ||
case 'pbeg': | ||
mqtt_publish("play_start", data, length); | ||
break; | ||
case 'pend': | ||
mqtt_publish("play_end", data, length); | ||
break; | ||
case 'pfls': | ||
mqtt_publish("play_flush", data, length); | ||
break; | ||
case 'prsm': | ||
mqtt_publish("play_resume", data, length); | ||
break; | ||
case 'PICT': | ||
if(config.mqtt_publish_parsed){ | ||
mqtt_publish("cover", data, length); | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
|
||
return; | ||
} | ||
|
||
|
||
int initialise_mqtt() { | ||
debug(1, "Initialising MQTT"); | ||
if(config.mqtt_hostname==NULL){ | ||
debug(1, "[MQTT]: Not initialized, as the hostname is not set"); | ||
return 0; | ||
} | ||
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( | ||
config.mqtt_cafile != NULL || | ||
config.mqtt_capath != NULL || | ||
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) { | ||
die("[MQTT]: TLS Setup failed"); | ||
} | ||
} | ||
|
||
if( | ||
config.mqtt_username != NULL || | ||
config.mqtt_password != NULL | ||
){ | ||
if(mosquitto_username_pw_set(mosq,config.mqtt_username,config.mqtt_password) != MOSQ_ERR_SUCCESS) { | ||
die("[MQTT]: Username/Password set failed"); | ||
} | ||
} | ||
mosquitto_log_callback_set(mosq, _cb_log); | ||
|
||
if(config.mqtt_enable_remote){ | ||
mosquitto_message_callback_set(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)){ | ||
inform("[MQTT]: Could not establish a mqtt connection"); | ||
} | ||
if(mosquitto_loop_start(mosq) != MOSQ_ERR_SUCCESS){ | ||
inform("[MQTT]: Could start MQTT Main loop"); | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#ifndef MQTT_H | ||
#define MQTT_H | ||
#include <stdint.h> | ||
#include <mosquitto.h> | ||
|
||
|
||
int initialise_mqtt(); | ||
void mqtt_process_metadata(uint32_t type, uint32_t code, char *data, uint32_t length); | ||
void mqtt_publish(char* topic, char* data, uint32_t length); | ||
void mqtt_setup(); | ||
void on_connect(struct mosquitto* mosq, void* userdata, int rc); | ||
void on_disconnect(struct mosquitto* mosq, void* userdata, int rc); | ||
void on_message(struct mosquitto* mosq, void* userdata, const struct mosquitto_message* msg); | ||
void _cb_log(struct mosquitto *mosq, void *userdata, int level, const char *str); | ||
#endif /* #ifndef MQTT_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.