]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Add server status -- i.e. can we still send commands to the DACP server. Hook it...
authorMike Brady <mikebrady@eircom.net>
Mon, 19 Mar 2018 16:53:58 +0000 (16:53 +0000)
committerMike Brady <mikebrady@eircom.net>
Mon, 19 Mar 2018 16:53:58 +0000 (16:53 +0000)
dacp.c
dbus-basic-remote-control.c
mdns_avahi.c
metadata_hub.h
org.gnome.ShairportSync.Basic.Remote.Control.xml
player.c
rtsp.c

diff --git a/dacp.c b/dacp.c
index fbafe81080b8e04017a9a0a03be83f92564a821f..d6b023b90b7a3d39dd75cac1a25ab2fc306b63ac 100644 (file)
--- a/dacp.c
+++ b/dacp.c
@@ -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);
index 11aeebde34de5866785fa924fb5ae5f3fcd7479a..d64cd5091f8b431db6330e13b6888a6ab5a9a18c 100644 (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 */
index 1658da4b7b1a351b946c360525653b907a2b9447..ff9cda7f28eccf68a650ed2b7ac1615e917050ae 100644 (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 {
index 4a7e8c6d8e57074617a7dfe9b30b5465b9d5b64b..5f01f665eb52fa7ed2cab15d5f0ffacba49bc343 100644 (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
index fd0488449ccbe35fc87424d24c1cf973d68e361f..2495f766db15352588ae02691f7ec0ff592375e6 100644 (file)
@@ -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"/>
index 6dabd4fc2c5d84b2a81a729a01a024246dcd4b0d..d1107fb52e74818dc1ac6fba12596f886d0a3007 100644 (file)
--- a/player.c
+++ b/player.c
@@ -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;
diff --git a/rtsp.c b/rtsp.c
index 461deeb1ae2f7ad009242efa3e710b5b53599a8d..4adc81c7e522f60219ad1f664b2902b87d66a4d3 100644 (file)
--- a/rtsp.c
+++ b/rtsp.c
@@ -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