From: Mike Brady Date: Mon, 19 Mar 2018 16:53:58 +0000 (+0000) Subject: Add server status -- i.e. can we still send commands to the DACP server. Hook it... X-Git-Tag: 3.2RC1~7^2~50 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c02e53ea8072798dbb8916c262a27f6ab6062875;p=thirdparty%2Fshairport-sync.git Add server status -- i.e. can we still send commands to the DACP server. Hook it up as "Server" property in basic remote control. --- diff --git a/dacp.c b/dacp.c index fbafe810..d6b023b9 100644 --- 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); diff --git a/dbus-basic-remote-control.c b/dbus-basic-remote-control.c index 11aeebde..d64cd509 100644 --- a/dbus-basic-remote-control.c +++ b/dbus-basic-remote-control.c @@ -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 */ diff --git a/mdns_avahi.c b/mdns_avahi.c index 1658da4b..ff9cda7f 100644 --- a/mdns_avahi.c +++ b/mdns_avahi.c @@ -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 { diff --git a/metadata_hub.h b/metadata_hub.h index 4a7e8c6d..5f01f665 100644 --- a/metadata_hub.h +++ b/metadata_hub.h @@ -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 diff --git a/org.gnome.ShairportSync.Basic.Remote.Control.xml b/org.gnome.ShairportSync.Basic.Remote.Control.xml index fd048844..2495f766 100644 --- a/org.gnome.ShairportSync.Basic.Remote.Control.xml +++ b/org.gnome.ShairportSync.Basic.Remote.Control.xml @@ -14,7 +14,7 @@ - + diff --git a/player.c b/player.c index 6dabd4fc..d1107fb5 100644 --- 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 461deeb1..4adc81c7 100644 --- 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