#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
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) {
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;
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);
}
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,
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);
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
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