Add server status -- i.e. can we still send commands to the DACP server. Hook it up as "Server" property in basic remote control.

This commit is contained in:
Mike Brady
2018-03-19 16:53:58 +00:00
parent fba40733f3
commit c02e53ea80
7 changed files with 42 additions and 7 deletions
+22 -3
View File
@@ -46,6 +46,7 @@
#include "tinyhttp/http.h"
typedef struct {
int players_connection_thread_index; // the connection thread index when a player thread is associated with this, zero otherwise
int scan_enable; // set to 1 if if sacanning should be considered
uint16_t port; // zero if no port discovered
short connection_family; // AF_INET6 or AF_INET
@@ -251,7 +252,7 @@ int dacp_send_command(const char *command, char **body, ssize_t *bodysize) {
int send_simple_dacp_command(const char *command) {
int reply = 0;
char *server_reply = NULL;
debug(2, "Sending command \"%s\".", command);
debug(3, "Sending command \"%s\".", command);
ssize_t reply_size = 0;
reply = dacp_send_command(command, &server_reply, &reply_size);
if (server_reply) {
@@ -261,11 +262,20 @@ int send_simple_dacp_command(const char *command) {
return reply;
}
void relinquish_dacp_server_information(rtsp_conn_info *conn) {
// this will set the dacp_server.players_connection_thread_index to zero iff it has the same value as the conn's connection number
// this is to signify that the player has stopped, but only if another thread (with a different index) hasn't already taken over the dacp service
ss_pthread_mutex_timedlock(&dacp_server_information_lock,500000,"set_dacp_server_information couldn't get DACP server information lock in 0.5 second!.",1);
if (dacp_server.players_connection_thread_index == conn->connection_number)
dacp_server.players_connection_thread_index = 0;
pthread_mutex_unlock(&dacp_server_information_lock);
}
// this will be running on the thread of its caller, not of the conversation thread...
void set_dacp_server_information(rtsp_conn_info *conn) { // tell the DACP conversation thread that
// the port has been set or changed
ss_pthread_mutex_timedlock(&dacp_server_information_lock,500000,"set_dacp_server_information couldn't get DACP server information lock in 0.5 second!.",1);
dacp_server.players_connection_thread_index = conn->connection_number;
dacp_server.port = conn->dacp_port;
dacp_server.connection_family = conn->connection_ip_family;
dacp_server.scope_id = conn->self_scope_id;
@@ -275,6 +285,11 @@ void set_dacp_server_information(rtsp_conn_info *conn) { // tell the DACP conver
dacp_server.scan_enable = 1;
else
dacp_server.scan_enable = 0;
metadata_hub_modify_prolog();
int ch = metadata_store.dacp_server_active != dacp_server.scan_enable;
metadata_store.dacp_server_active = dacp_server.scan_enable;
metadata_hub_modify_epilog(ch);
pthread_cond_signal(&dacp_server_information_cv);
pthread_mutex_unlock(&dacp_server_information_lock);
}
@@ -297,6 +312,10 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) {
if ((result == 496) || (result == 403) || (result == 501)) {
// debug(1,"Stopping scan because the response to \"dacp_get_volume(NULL)\" is %d.",result);
dacp_server.scan_enable = 0;
metadata_hub_modify_prolog();
int ch = metadata_store.dacp_server_active !=0;
metadata_store.dacp_server_active = 0;
metadata_hub_modify_epilog(ch);
}
pthread_mutex_unlock(&dacp_server_information_lock);
// debug(1, "DACP Server ID \"%u\" at \"%s:%u\", scan %d.", dacp_server.active_remote_id,
@@ -840,7 +859,7 @@ int dacp_get_volume(int32_t *the_actual_volume) {
debug(1, "Unexpected return code %d from dacp_get_speaker_list.", http_response);
}
} else {
debug(2, "Unexpected return code %d from dacp_get_client_volume.", http_response);
debug(3, "Unexpected return code %d from dacp_get_client_volume.", http_response);
}
if (the_actual_volume) {
// debug(1,"dacp_get_volume returns %d.",actual_volume);
+6
View File
@@ -20,8 +20,14 @@ ShairportSyncBasicRemoteControl *shairportSyncBasicRemoteControlSkeleton;
void dbus_basic_remote_control_metadata_watcher(struct metadata_bundle *argc, __attribute__((unused)) void *userdata) {
// debug(1, "DBUS basic remote control watcher called");
shairport_sync_basic_remote_control_set_airplay_volume(shairportSyncBasicRemoteControlSkeleton, argc->airplay_volume);
if (argc->dacp_server_active)
shairport_sync_basic_remote_control_set_server(shairportSyncBasicRemoteControlSkeleton, argc->client_ip);
else
shairport_sync_basic_remote_control_set_server(shairportSyncBasicRemoteControlSkeleton, "");
GVariantBuilder *dict_builder, *aa;
/* Build the metadata array */
+3
View File
@@ -143,10 +143,13 @@ static void browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, Avah
if (conn->dacp_id != 0) {
debug(3, "Client's DACP status withdrawn.");
conn->dacp_port = 0;
/*
#ifdef HAVE_DACP_CLIENT
// this might be in a race condition with another connection that could come into effect before this one has terminated.
set_dacp_server_information(conn); // this will have the effect of telling the scanner
// that the DACP server is no longer working
#endif
*/
}
}
} else {
+4 -1
View File
@@ -27,6 +27,9 @@ struct metadata_bundle;
typedef void (*metadata_watcher)(struct metadata_bundle *argc, void *userdata);
typedef struct metadata_bundle {
int dacp_server_active; // true if there's a reachable DACP server (assumed to be the Airplay client) ; false otherwise
int changed; // normally 0, nonzero if a field has been changed
int playerstatusupdates_are_received; // false if it's "traditional" metadata
@@ -65,7 +68,7 @@ typedef struct metadata_bundle {
char *sort_as; // a malloced string -- if non-zero, free it before replacing it
int sort_as_changed;
char *client_ip; // IP number used by the audio source (i.e. the "client")
char *client_ip; // IP number used by the audio source (i.e. the "client"), which is also the DACP server
int client_ip_changed;
char *server_ip; // IP number used by Shairport Sync
@@ -14,7 +14,7 @@
<method name='ShuffleSongs'/>
<method name='VolumeUp'/>
<method name='VolumeDown'/>
<property name='Status' type='s' access='read'/>
<property name='Server' type='s' access='read'/>
<property name='AirplayVolume' type='d' access='read'/>
<property name='Metadata' type='a{sv}' access='read'>
<annotation name="org.qtproject.QtDBus.QtTypeName" value="QVariantMap"/>
+4
View File
@@ -1601,10 +1601,14 @@ static void *player_thread_func(void *arg) {
int sync_error_out_of_bounds =
0; // number of times in a row that there's been a serious sync error
// stop looking elsewhere for DACP stuff
conn->dacp_port = 0;
set_dacp_server_information(conn); // this will stop scanning until a port is registered by the code initiated by the mdns_dacp_monitor
// start an mdns/zeroconf thread to look for DACP messages containing our DACP_ID and getting the
// port number
// mdns_dacp_monitor(conn->dacp_id, &conn->dacp_port, &conn->dacp_private);
mdns_dacp_monitor(conn);
conn->framesProcessedInThisEpoch = 0;
conn->framesGeneratedInThisEpoch = 0;
+2 -2
View File
@@ -99,7 +99,7 @@ static pthread_mutex_t reference_counter_lock = PTHREAD_MUTEX_INITIALIZER;
static rtsp_conn_info **conns = NULL;
int RTSP_connection_index = 0;
int RTSP_connection_index = 1;
#ifdef CONFIG_METADATA
@@ -865,7 +865,7 @@ static void handle_set_parameter_parameter(rtsp_conn_info *conn, rtsp_message *r
if (!strncmp(cp, "volume: ", 8)) {
float volume = atof(cp + 8);
debug(2, "AirPlay request to set volume to: %f.", volume);
// debug(2, "AirPlay request to set volume to: %f.", volume);
player_volume(volume, conn);
} else
#ifdef CONFIG_METADATA