diff --git a/dacp.c b/dacp.c index 1c5271e19..424cabeaa 100644 --- a/dacp.c +++ b/dacp.c @@ -149,203 +149,216 @@ void http_cleanup(void *arg) { } int dacp_send_command(const char *command, char **body, ssize_t *bodysize) { + int result; + // debug(1,"dacp_send_command: command is: \"%s\".",command); + + if (dacp_server.port == 0) { + debug(1,"No DACP port specified yet"); + result = 490; // no port specified + } else { + + // will malloc space for the body or set it to NULL -- the caller should free it. + + // Using some custom HTTP-like return codes + // 498 Bad Address information for the DACP server + // 497 Can't establish a socket to the DACP server + // 496 Can't connect to the DACP server + // 495 Error receiving response + // 494 This client is already busy + // 493 Client failed to send a message + // 492 Argument out of range + // 491 Client refused connection + + struct addrinfo hints, *res; + int sockfd; + + struct HttpResponse response; + response.body = NULL; + response.malloced_size = 0; + response.size = 0; + response.code = 0; + + char portstring[10], server[1024], message[1024]; + memset(&portstring, 0, sizeof(portstring)); + if (dacp_server.connection_family == AF_INET6) { + snprintf(server, sizeof(server), "%s%%%u", dacp_server.ip_string, dacp_server.scope_id); + } else { + strcpy(server, dacp_server.ip_string); + } + snprintf(portstring, sizeof(portstring), "%u", dacp_server.port); - // will malloc space for the body or set it to NULL -- the caller should free it. - - // Using some custom HTTP-like return codes - // 498 Bad Address information for the DACP server - // 497 Can't establish a socket to the DACP server - // 496 Can't connect to the DACP server - // 495 Error receiving response - // 494 This client is already busy - // 493 Client failed to send a message - // 492 Argument out of range - - struct addrinfo hints, *res; - int sockfd; - - struct HttpResponse response; - response.body = NULL; - response.malloced_size = 0; - response.size = 0; - response.code = 0; - - char portstring[10], server[1024], message[1024]; - memset(&portstring, 0, sizeof(portstring)); - if (dacp_server.connection_family == AF_INET6) { - snprintf(server, sizeof(server), "%s%%%u", dacp_server.ip_string, dacp_server.scope_id); - } else { - strcpy(server, dacp_server.ip_string); - } - snprintf(portstring, sizeof(portstring), "%u", dacp_server.port); - - // first, load up address structs with getaddrinfo(): + // first, load up address structs with getaddrinfo(): - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; - // debug(1, "DACP port string is \"%s:%s\".", server, portstring); + // debug(1, "DACP port string is \"%s:%s\".", server, portstring); - int ires = getaddrinfo(server, portstring, &hints, &res); - if (ires) { - // debug(1,"Error %d \"%s\" at getaddrinfo.",ires,gai_strerror(ires)); - response.code = 498; // Bad Address information for the DACP server - } else { - uint64_t start_time = get_absolute_time_in_fp(); - pthread_cleanup_push(addrinfo_cleanup, (void *)&res); - // only do this one at a time -- not sure it is necessary, but better safe than sorry + int ires = getaddrinfo(server, portstring, &hints, &res); + if (ires) { + // debug(1,"Error %d \"%s\" at getaddrinfo.",ires,gai_strerror(ires)); + response.code = 498; // Bad Address information for the DACP server + } else { + uint64_t start_time = get_absolute_time_in_fp(); + pthread_cleanup_push(addrinfo_cleanup, (void *)&res); + // only do this one at a time -- not sure it is necessary, but better safe than sorry - int mutex_reply = sps_pthread_mutex_timedlock(&dacp_conversation_lock, 2000000, command, 1); - // int mutex_reply = pthread_mutex_lock(&dacp_conversation_lock); - if (mutex_reply == 0) { - pthread_cleanup_push(mutex_lock_cleanup, (void *)&dacp_conversation_lock); + int mutex_reply = sps_pthread_mutex_timedlock(&dacp_conversation_lock, 2000000, command, 1); + // int mutex_reply = pthread_mutex_lock(&dacp_conversation_lock); + if (mutex_reply == 0) { + pthread_cleanup_push(mutex_lock_cleanup, (void *)&dacp_conversation_lock); - // make a socket: - sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + // make a socket: + sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (sockfd == -1) { - // debug(1, "DACP socket could not be created -- error %d: \"%s\".",errno,strerror(errno)); - response.code = 497; // Can't establish a socket to the DACP server - } else { - pthread_cleanup_push(connect_cleanup, (void *)&sockfd); - // debug(2, "dacp_send_command: open socket %d.",sockfd); - - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 80000; - if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof tv) == -1) - debug(1, "dacp_send_command: error %d setting receive timeout.", errno); - if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (const char *)&tv, sizeof tv) == -1) - debug(1, "dacp_send_command: error %d setting send timeout.", errno); - - // connect! - // debug(1, "DACP socket created."); - if (connect(sockfd, res->ai_addr, res->ai_addrlen) < 0) { - debug(3, "dacp_send_command: connect failed with errno %d.", errno); - response.code = 496; // Can't connect to the DACP server + if (sockfd == -1) { + // debug(1, "DACP socket could not be created -- error %d: \"%s\".",errno,strerror(errno)); + response.code = 497; // Can't establish a socket to the DACP server } else { - // debug(1,"DACP connect succeeded."); - - snprintf(message, sizeof(message), - "GET /ctrl-int/1/%s HTTP/1.1\r\nHost: %s:%u\r\nActive-Remote: %u\r\n\r\n", - command, dacp_server.ip_string, dacp_server.port, dacp_server.active_remote_id); - - // Send command - debug(3, "dacp_send_command: \"%s\".", command); - ssize_t wresp = send(sockfd, message, strlen(message), 0); - if (wresp == -1) { - char errorstring[1024]; - strerror_r(errno, (char *)errorstring, sizeof(errorstring)); - debug(2, "dacp_send_command: write error %d: \"%s\".", errno, (char *)errorstring); - struct linger so_linger; - so_linger.l_onoff = 1; // "true" - so_linger.l_linger = 0; - int err = setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger); - if (err) - debug(1, "Could not set the dacp socket to abort due to a write error on closing."); - } - if (wresp != (ssize_t)strlen(message)) { - // debug(1, "dacp_send_command: send failed."); - response.code = 493; // Client failed to send a message - + pthread_cleanup_push(connect_cleanup, (void *)&sockfd); + // debug(2, "dacp_send_command: open socket %d.",sockfd); + + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 500000; + if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof tv) == -1) + debug(1, "dacp_send_command: error %d setting receive timeout.", errno); + if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (const char *)&tv, sizeof tv) == -1) + debug(1, "dacp_send_command: error %d setting send timeout.", errno); + + // connect! + // debug(1, "DACP socket created."); + if (connect(sockfd, res->ai_addr, res->ai_addrlen) < 0) { + // debug(1, "dacp_send_command: connect failed with errno %d.", errno); + if (errno == ECONNREFUSED) + response.code = 491; // DACP server doesn't want to talk anymore... + else + response.code = 496; // Can't connect to the DACP server } else { + // debug(1,"DACP connect succeeded."); + + snprintf(message, sizeof(message), + "GET /ctrl-int/1/%s HTTP/1.1\r\nHost: %s:%u\r\nActive-Remote: %u\r\n\r\n", + command, dacp_server.ip_string, dacp_server.port, dacp_server.active_remote_id); + + // Send command + debug(3, "dacp_send_command: \"%s\".", command); + ssize_t wresp = send(sockfd, message, strlen(message), 0); + if (wresp == -1) { + char errorstring[1024]; + strerror_r(errno, (char *)errorstring, sizeof(errorstring)); + debug(2, "dacp_send_command: write error %d: \"%s\".", errno, (char *)errorstring); + struct linger so_linger; + so_linger.l_onoff = 1; // "true" + so_linger.l_linger = 0; + int err = setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger); + if (err) + debug(1, "Could not set the dacp socket to abort due to a write error on closing."); + } + if (wresp != (ssize_t)strlen(message)) { + // debug(1, "dacp_send_command: send failed."); + response.code = 493; // Client failed to send a message - response.body = malloc(2048); // it can resize this if necessary - response.malloced_size = 2048; - pthread_cleanup_push(malloc_cleanup, response.body); - - struct http_roundtripper rt; - http_init(&rt, responseFuncs, &response); - pthread_cleanup_push(http_cleanup, &rt); - - int needmore = 1; - int looperror = 0; - char buffer[8192]; - memset(buffer, 0, sizeof(buffer)); - while (needmore && !looperror) { - const char *data = buffer; - if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof tv) == -1) - debug(1, "dacp_send_command: error %d setting receive timeout.", errno); - ssize_t ndata = recv(sockfd, buffer, sizeof(buffer), 0); - // debug(3, "Received %d bytes: \"%s\".", ndata, buffer); - if (ndata <= 0) { - if (ndata == -1) { - char errorstring[1024]; - strerror_r(errno, (char *)errorstring, sizeof(errorstring)); - debug(2, "dacp_send_command: receiving error %d: \"%s\".", errno, - (char *)errorstring); - struct linger so_linger; - so_linger.l_onoff = 1; // "true" - so_linger.l_linger = 0; - int err = setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger); - if (err) - debug(1, - "Could not set the dacp socket to abort due to a read error on closing."); + } else { + + response.body = malloc(2048); // it can resize this if necessary + response.malloced_size = 2048; + pthread_cleanup_push(malloc_cleanup, response.body); + + struct http_roundtripper rt; + http_init(&rt, responseFuncs, &response); + pthread_cleanup_push(http_cleanup, &rt); + + int needmore = 1; + int looperror = 0; + char buffer[8192]; + memset(buffer, 0, sizeof(buffer)); + while (needmore && !looperror) { + const char *data = buffer; + if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof tv) == -1) + debug(1, "dacp_send_command: error %d setting receive timeout.", errno); + ssize_t ndata = recv(sockfd, buffer, sizeof(buffer), 0); + // debug(3, "Received %d bytes: \"%s\".", ndata, buffer); + if (ndata <= 0) { + if (ndata == -1) { + char errorstring[1024]; + strerror_r(errno, (char *)errorstring, sizeof(errorstring)); + debug(2, "dacp_send_command: receiving error %d: \"%s\".", errno, + (char *)errorstring); + struct linger so_linger; + so_linger.l_onoff = 1; // "true" + so_linger.l_linger = 0; + int err = setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger); + if (err) + debug(1, + "Could not set the dacp socket to abort due to a read error on closing."); + } + + free(response.body); + response.body = NULL; + response.malloced_size = 0; + response.size = 0; + response.code = 495; // Error receiving response + looperror = 1; } + while (needmore && ndata && !looperror) { + int read; + needmore = http_data(&rt, data, ndata, &read); + ndata -= read; + data += read; + } + } + + if (http_iserror(&rt)) { + debug(3, "dacp_send_command: error parsing data."); free(response.body); response.body = NULL; response.malloced_size = 0; response.size = 0; - response.code = 495; // Error receiving response - looperror = 1; - } - - while (needmore && ndata && !looperror) { - int read; - needmore = http_data(&rt, data, ndata, &read); - ndata -= read; - data += read; } + // debug(1,"Size of response body is %d",response.size); + pthread_cleanup_pop(1); // this should call http_cleanup + // http_free(&rt); + pthread_cleanup_pop( + 0); // this should *not* free the malloced buffer -- just pop the malloc cleanup } - - if (http_iserror(&rt)) { - debug(3, "dacp_send_command: error parsing data."); - free(response.body); - response.body = NULL; - response.malloced_size = 0; - response.size = 0; - } - // debug(1,"Size of response body is %d",response.size); - pthread_cleanup_pop(1); // this should call http_cleanup - // http_free(&rt); - pthread_cleanup_pop( - 0); // this should *not* free the malloced buffer -- just pop the malloc cleanup } + pthread_cleanup_pop(1); // this should close the socket + // close(sockfd); + // debug(1,"DACP socket closed."); } - pthread_cleanup_pop(1); // this should close the socket - // close(sockfd); - // debug(1,"DACP socket closed."); + pthread_cleanup_pop(1); // this should unlock the dacp_conversation_lock); + // pthread_mutex_unlock(&dacp_conversation_lock); + // debug(1,"Sent command\"%s\" with a response body of size %d.",command,response.size); + // debug(1,"dacp_conversation_lock released."); + } else { + debug(3, + "dacp_send_command: could not acquire a lock on the dacp transmit/receive section " + "when attempting to " + "send the command \"%s\". Possible timeout?", + command); + response.code = 494; // This client is already busy } - pthread_cleanup_pop(1); // this should unlock the dacp_conversation_lock); - // pthread_mutex_unlock(&dacp_conversation_lock); - // debug(1,"Sent command\"%s\" with a response body of size %d.",command,response.size); - // debug(1,"dacp_conversation_lock released."); - } else { - debug(3, - "dacp_send_command: could not acquire a lock on the dacp transmit/receive section " - "when attempting to " - "send the command \"%s\". Possible timeout?", - command); - response.code = 494; // This client is already busy + pthread_cleanup_pop(1); // this should free the addrinfo + // freeaddrinfo(res); + uint64_t et = get_absolute_time_in_fp() - start_time; + et = (et * 1000000) >> 32; // microseconds + debug(3, "dacp_send_command: %f seconds, response code %d, command \"%s\".", + (1.0 * et) / 1000000, response.code, command); } - pthread_cleanup_pop(1); // this should free the addrinfo - // freeaddrinfo(res); - uint64_t et = get_absolute_time_in_fp() - start_time; - et = (et * 1000000) >> 32; // microseconds - debug(3, "dacp_send_command: %f seconds, response code %d, command \"%s\".", - (1.0 * et) / 1000000, response.code, command); + *body = response.body; + *bodysize = response.size; + result = response.code; } - *body = response.body; - *bodysize = response.size; - return response.code; + return result; } int send_simple_dacp_command(const char *command) { int reply = 0; char *server_reply = NULL; - debug(3, "Sending command \"%s\".", command); + debug(1, "send_simple_dacp_command: sending command \"%s\".", command); ssize_t reply_size = 0; reply = dacp_send_command(command, &server_reply, &reply_size); if (server_reply) { @@ -423,7 +436,7 @@ void set_dacp_server_information(rtsp_conn_info *conn) { void dacp_monitor_port_update_callback(char *dacp_id, uint16_t port) { debug_mutex_lock(&dacp_server_information_lock, 500000, 2); - debug(3, + debug(2, "dacp_monitor_port_update_callback with Remote ID \"%s\", target ID \"%s\" and port " "number %d.", dacp_id, dacp_server.dacp_id, port); @@ -474,7 +487,7 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) { metadata_store.dacp_server_active = 0; metadata_store.advanced_dacp_server_active = 0; debug(2, - "setting dacp_server_active and advanced_dacp_server_active to 0 with an update " + "setting metadata_store.dacp_server_active and metadata_store.advanced_dacp_server_active to 0 with an update " "flag value of %d", ch); metadata_hub_modify_epilog(ch); @@ -483,17 +496,44 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) { pthread_cond_wait(&dacp_server_information_cv, &dacp_server_information_lock); // debug(1,"dacp_monitor_thread_code wake up."); } + // so dacp_server.scan_enable will be true at this point bad_result_count = 0; idle_scan_count = 0; + } - scan_index++; + result = dacp_get_volume(&the_volume); // just want the http code + pthread_cleanup_pop(1); - if ((result == 403) || (result == 501)) { - bad_result_count++; - // debug(1,"Bad Scan : %d.",result); - } else + scan_index++; + // debug(1,"DACP Scan Result: %d.", result); + + if ((result == 200) || (result == 400)) { bad_result_count = 0; + } else { + if (bad_result_count < config.scan_max_bad_response_count) // limit to some reasonable value + bad_result_count++; + } + + // here, do the debouncing calculations to see + // if the dacp server and the + // advanced dacp server are available + + // -1 means we don't know because some bad statuses have been reported + // 0 means definitely no + // +1 means definitely yes + + int dacp_server_status_now = -1; + int advanced_dacp_server_status_now = -1; + + if (bad_result_count == 0) { + dacp_server_status_now = 1; + if (result == 200) + advanced_dacp_server_status_now = 1; + } else if (bad_result_count == config.scan_max_bad_response_count) { // if a sequence of bad return codes occurs, then it's gone + dacp_server_status_now = 0; + advanced_dacp_server_status_now = 0; + } if (metadata_store.player_thread_active == 0) idle_scan_count++; @@ -503,45 +543,37 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) { debug(3, "Scan Result: %d, Bad Scan Count: %d, Idle Scan Count: %d.", result, bad_result_count, idle_scan_count); - if ((bad_result_count == config.scan_max_bad_response_count) || - (idle_scan_count == config.scan_max_inactive_count)) { +/* not used +// decide if idle for too long + if (idle_scan_count == config.scan_max_inactive_count) { debug(2, "DACP server status scanning stopped."); dacp_server.scan_enable = 0; } - pthread_cleanup_pop(1); +*/ + + int update_needed = 0; + metadata_hub_modify_prolog(); + if (dacp_server_status_now != -1) { // if dacp_server_status_now is actually known... + if (metadata_store.dacp_server_active != dacp_server_status_now) { + debug(2, "metadata_store.dacp_server_active set to %d.", dacp_server_status_now); + metadata_store.dacp_server_active = dacp_server_status_now; + update_needed = 1; + } + } + if (advanced_dacp_server_status_now != -1) { // if advanced_dacp_server_status_now is actually known... + if (metadata_store.advanced_dacp_server_active != advanced_dacp_server_status_now) { + debug(2, "metadata_store.advanced_dacp_server_active set to %d.", dacp_server_status_now); + metadata_store.advanced_dacp_server_active = advanced_dacp_server_status_now; + update_needed = 1; + } + } + metadata_hub_modify_epilog(update_needed); + // pthread_mutex_unlock(&dacp_server_information_lock); // debug(1, "DACP Server ID \"%u\" at \"%s:%u\", scan %d.", dacp_server.active_remote_id, // dacp_server.ip_string, dacp_server.port, scan_index); - if (dacp_server.scan_enable == - 1) { // if it hasn't been turned off, continue looking for information. - int transient_problem = - (result == 494) || (result == 495) || - (result == 496); // this just means that it couldn't send the query because something - // else - // was sending a command or something - if ((!transient_problem) && (bad_result_count == 0) && (idle_scan_count == 0) && - (dacp_server.scan_enable == 1)) { - - // Any other result means that the DACP server is active, but not providing advanced - // features - - metadata_hub_modify_prolog(); - int inactive = metadata_store.dacp_server_active == 0; - if (inactive) { - metadata_store.dacp_server_active = 1; - debug(1, "Setting dacp_server_active to active because of a response of %d.", result); - } - int same = metadata_store.advanced_dacp_server_active == (result == 200); - if (!same) { - metadata_store.advanced_dacp_server_active = (result == 200); - debug(1, "Setting dacp_advanced_server_active to %d because of a response of %d.", - (result == 200), result); - } - metadata_hub_modify_epilog(inactive + (!same)); - } - if (result == 200) { metadata_hub_modify_prolog(); int diff = metadata_store.speaker_volume != the_volume; @@ -555,7 +587,7 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) { char command[1024] = ""; snprintf(command, sizeof(command) - 1, "playstatusupdate?revision-number=%d", revision_number); - // debug(1,"Command: \"%s\"",command); + // debug(1,"dacp_monitor_thread_code: command: \"%s\"",command); result = dacp_send_command(command, &response, &le); // debug(1,"Response to \"%s\" is %d.",command,result); if (result == 200) { @@ -775,7 +807,7 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) { } // finished possibly writing to the metadata hub - metadata_hub_modify_epilog(1); + metadata_hub_modify_epilog(1); // should really see if this can be made responsive to changes } else { debug(1, "Status Update not found.\n"); } @@ -815,7 +847,6 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) { sleep(config.scan_interval_when_active); else sleep(config.scan_interval_when_inactive); - } } debug(1, "DACP monitor thread exiting -- should never happen."); pthread_exit(NULL); @@ -901,6 +932,7 @@ int dacp_get_client_volume(int32_t *result) { char *server_reply = NULL; int32_t overall_volume = -1; ssize_t reply_size; + // debug(1,"dacp_get_client_volume: dacp_send_command"); int response = dacp_send_command("getproperty?properties=dmcp.volume", &server_reply, &reply_size); if (response == 200) { // if we get an okay @@ -947,7 +979,7 @@ int dacp_set_include_speaker_volume(int64_t machine_number, int32_t vo) { snprintf(message, sizeof(message), "setproperty?include-speaker-id=%" PRId64 "&dmcp.volume=%" PRId32 "", machine_number, vo); - debug(2, "sending \"%s\"", message); + debug(1, "sending \"%s\"", message); return send_simple_dacp_command(message); // should return 204 } @@ -957,7 +989,7 @@ int dacp_set_speaker_volume(int64_t machine_number, int32_t vo) { memset(message, 0, sizeof(message)); snprintf(message, sizeof(message), "setproperty?speaker-id=%" PRId64 "&dmcp.volume=%" PRId32 "", machine_number, vo); - debug(2, "sending \"%s\"", message); + debug(1, "sending \"%s\"", message); return send_simple_dacp_command(message); // should return 204 } @@ -970,6 +1002,7 @@ int dacp_get_speaker_list(dacp_spkr_stuff *speaker_info, int max_size_of_array, int speaker_count = -1; // will be fixed if there is no problem ssize_t le; + // debug(1,"dacp_speaker_list: dacp_send_command"); int response = dacp_send_command("getspeakers", &server_reply, &le); if (response == 200) { char *sp = server_reply; diff --git a/metadata_hub.c b/metadata_hub.c index dc2f34336..4f2d00afb 100644 --- a/metadata_hub.c +++ b/metadata_hub.c @@ -132,7 +132,9 @@ void metadata_hub_modify_prolog(void) { if (pthread_rwlock_trywrlock(&metadata_hub_re_lock) != 0) { debug(2, "Metadata_hub write lock is already taken -- must wait."); pthread_rwlock_wrlock(&metadata_hub_re_lock); - debug(2, "Okay -- acquired the metadata_hub write lock."); + debug(1, "Okay -- acquired the metadata_hub write lock."); + } else { + debug(3, "Metadata_hub write lock acquired."); } } @@ -143,6 +145,7 @@ void metadata_hub_modify_epilog(int modified) { run_metadata_watchers(); } pthread_rwlock_unlock(&metadata_hub_re_lock); + debug(3, "Metadata_hub write lock unlocked."); } void metadata_hub_read_prolog(void) { @@ -511,16 +514,16 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin break; case 'pbeg': metadata_hub_modify_prolog(); - changed = (metadata_store.player_state != PS_PLAYING); + changed = ((metadata_store.player_state != PS_PLAYING) || (metadata_store.player_thread_active == 0)); metadata_store.player_state = PS_PLAYING; metadata_store.player_thread_active = 1; metadata_hub_modify_epilog(changed); break; case 'pend': metadata_hub_modify_prolog(); - changed = (metadata_store.player_state != PS_STOPPED); - metadata_store.player_thread_active = 0; + changed = ((metadata_store.player_state != PS_STOPPED) || (metadata_store.player_thread_active == 1)); metadata_store.player_state = PS_STOPPED; + metadata_store.player_thread_active = 0; metadata_hub_modify_epilog(changed); break; case 'pfls': @@ -537,14 +540,15 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin metadata_hub_modify_epilog(changed); break; case 'pvol': { - // Note: it's assumed that the config.airplay volume has already been correctly set. - int32_t actual_volume; - int gv = dacp_get_volume(&actual_volume); metadata_hub_modify_prolog(); - if ((gv == 200) && (metadata_store.speaker_volume != actual_volume)) { - metadata_store.speaker_volume = actual_volume; - changed = 1; - } + // Note: it's assumed that the config.airplay volume has already been correctly set. + //int32_t actual_volume; + //int gv = dacp_get_volume(&actual_volume); + //metadata_hub_modify_prolog(); + //if ((gv == 200) && (metadata_store.speaker_volume != actual_volume)) { + // metadata_store.speaker_volume = actual_volume; + // changed = 1; + //} if (metadata_store.airplay_volume != config.airplay_volume) { metadata_store.airplay_volume = config.airplay_volume; changed = 1; diff --git a/shairport.c b/shairport.c index d97a6feac..1594c4f7b 100644 --- a/shairport.c +++ b/shairport.c @@ -407,14 +407,12 @@ int parse_options(int argc, char **argv) { config.scan_interval_when_active = 1; // number of seconds between DACP server scans when playing something config.scan_interval_when_inactive = - 3; // number of seconds between DACP server scans playing nothing + 1; // number of seconds between DACP server scans when playing nothing config.scan_max_bad_response_count = 5; // number of successive bad results to ignore before giving up - config.scan_max_inactive_count = - (15 * 60) / config.scan_interval_when_inactive; // number of scans to do before stopping if - // not made active again (15 minutes) -// config.scan_max_inactive_count = 5; // number of scans to do before stopping if not made active -// again (15 minutes ) + //config.scan_max_inactive_count = + // (365 * 24 * 60 * 60) / config.scan_interval_when_inactive; // number of scans to do before stopping if + // not made active again (not used) #endif // config_setting_t *setting;