diff --git a/dacp.c b/dacp.c index 28faece1..77313f73 100644 --- a/dacp.c +++ b/dacp.c @@ -56,7 +56,7 @@ typedef struct { int always_use_revision_number_1; // for dealing with forked-daapd; uint32_t scope_id; // if it's an ipv6 connection, this will be its scope id char ip_string[INET6_ADDRSTRLEN]; // the ip string pointing to the client - uint32_t active_remote_id; // send this when you want to send remote control commands + char *active_remote_id; // send this when you want to send remote control commands void *port_monitor_private_storage; } dacp_server_record; @@ -77,25 +77,23 @@ void *response_realloc(__attribute__((unused)) void *opaque, void *ptr, int size void *t = realloc(ptr, size); if ((t == NULL) && (size != 0)) debug(1, "Response realloc of size %d failed!", size); - if (t != ptr) - debug(3, "response_realloc pointer changed for size %d", size); return t; } void response_body(void *opaque, const char *data, int size) { struct HttpResponse *response = (struct HttpResponse *)opaque; - ssize_t space_available = response->malloced_size - response->size; //must be greater than or equal to 0 + ssize_t space_available = response->malloced_size - response->size; if (space_available < size) { - debug(3,"Getting more space for the response -- %d allocated, need %d bytes but only %d bytes left.\n", response->malloced_size, size, space_available); - ssize_t size_requested = size - space_available + response->malloced_size; + // debug(1,"Getting more space for the response -- need %d bytes but only %ld bytes left.\n", + // size, + // size - space_available); + ssize_t size_requested = size - space_available + response->malloced_size + 16384; void *t = realloc(response->body, size_requested); response->malloced_size = size_requested; - if (t) { - if (response->body != t) - debug(3, "response_body pointer changed for size %u.", size_requested); + if (t) response->body = t; - } else { + else { die("dacp: can't allocate any more space for parser."); } } @@ -228,7 +226,7 @@ int dacp_send_command(const char *command, char **body, ssize_t *bodysize) { struct timeval tv; tv.tv_sec = 0; - tv.tv_usec = 100000; + 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) @@ -246,7 +244,7 @@ int dacp_send_command(const char *command, char **body, ssize_t *bodysize) { // 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", + "GET /ctrl-int/1/%s HTTP/1.1\r\nHost: %s:%u\r\nActive-Remote: %s\r\n\r\n", command, dacp_server.ip_string, dacp_server.port, dacp_server.active_remote_id); @@ -270,10 +268,8 @@ int dacp_send_command(const char *command, char **body, ssize_t *bodysize) { } else { - response.body = malloc(0); // it will resize this if necessary - if (response.body == NULL) - die("Can not allocatr space for a DACP response."); - response.malloced_size = 0; + 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; @@ -290,8 +286,6 @@ int dacp_send_command(const char *command, char **body, ssize_t *bodysize) { 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) && ((size_t)ndata > sizeof(buffer)/2)) - debug(1, "Received %u bytes: \"%s\".", ndata, buffer); if (ndata <= 0) { if (ndata == -1) { char errorstring[1024]; @@ -449,9 +443,11 @@ void set_dacp_server_information(rtsp_conn_info *conn) { // metadata_hub_modify_epilog(ch); } } - dacp_server.active_remote_id = conn->dacp_active_remote; // even if the dacp_id remains the same, - // the active remote will change. - debug(3, "set_dacp_server_information set active-remote id to %" PRIu32 ".", + if (dacp_server.active_remote_id) + free(dacp_server.active_remote_id); + dacp_server.active_remote_id = strdup(conn->dacp_active_remote); // even if the dacp_id remains the same, + // the active remote will change. + debug(3, "set_dacp_server_information set active-remote id to %s.", dacp_server.active_remote_id); pthread_cond_signal(&dacp_server_information_cv); debug_mutex_unlock(&dacp_server_information_lock, 3); @@ -463,20 +459,24 @@ void dacp_monitor_port_update_callback(char *dacp_id, uint16_t port) { "dacp_monitor_port_update_callback with Remote ID \"%s\", target ID \"%s\" and port " "number %d.", dacp_id, dacp_server.dacp_id, port); - if (strcmp(dacp_id, dacp_server.dacp_id) == 0) { - dacp_server.port = port; - if (port == 0) - dacp_server.scan_enable = 0; - else { - dacp_server.scan_enable = 1; - // debug(2, "dacp_monitor_port_update_callback enables scan"); - } - // 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); + if ((dacp_id == NULL) || (dacp_server.dacp_id == NULL)) { + warn("dacp_id or dacp_server.dacp_id NULL detected"); } else { - debug(1, "dacp port monitor reporting on an out-of-use remote."); + if (strcmp(dacp_id, dacp_server.dacp_id) == 0) { + dacp_server.port = port; + if (port == 0) + dacp_server.scan_enable = 0; + else { + dacp_server.scan_enable = 1; + // debug(2, "dacp_monitor_port_update_callback enables scan"); + } + // 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); + } else { + debug(1, "dacp port monitor reporting on an out-of-use remote."); + } } pthread_cond_signal(&dacp_server_information_cv); debug_mutex_unlock(&dacp_server_information_lock, 3); @@ -1005,6 +1005,10 @@ void dacp_monitor_stop() { pthread_mutex_destroy(&dacp_conversation_lock); pthread_cond_destroy(&dacp_server_information_cv); debug(3, "DACP Server Information Condition Variable destroyed."); + if (dacp_server.active_remote_id) { + free(dacp_server.active_remote_id); + dacp_server.active_remote_id = NULL; + } } } diff --git a/player.h b/player.h index 2b0c2c2e..013dfb6f 100644 --- a/player.h +++ b/player.h @@ -197,7 +197,6 @@ typedef struct { // could be one of many, so we need to know it uint32_t self_scope_id; // if it's an ipv6 connection, this will be its scope short connection_ip_family; // AF_INET / AF_INET6 - uint32_t client_active_remote; // used when you want to control the client... SOCKADDR rtp_client_control_socket; // a socket pointing to the control port of the client SOCKADDR rtp_client_timing_socket; // a socket pointing to the timing port of the client @@ -265,7 +264,7 @@ typedef struct { char *dacp_id; // id of the client -- used to find the port to be used // uint16_t dacp_port; // port on the client to send remote control messages to, else // zero - uint32_t dacp_active_remote; // key to send to the remote controller + char *dacp_active_remote; // key to send to the remote controller void *dapo_private_storage; // this is used for compatibility, if dacp stuff isn't enabled. int enable_dither; // needed for filling silences before play actually starts diff --git a/rtsp.c b/rtsp.c index a1eeff13..974c8a40 100644 --- a/rtsp.c +++ b/rtsp.c @@ -3,7 +3,7 @@ * Copyright (c) James Laird 2013 * Modifications associated with audio synchronization, mutithreading and - * metadata handling copyright (c) Mike Brady 2014-2019 + * metadata handling copyright (c) Mike Brady 2014-2020 * All rights reserved. * * Permission is hereby granted, free of charge, to any person @@ -975,15 +975,19 @@ void handle_setup(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) { debug(2, "Connection %d: SETUP -- Active-Remote string seen: \"%s\".", conn->connection_number, ar); // get the active remote - char *p; - conn->dacp_active_remote = strtoul(ar, &p, 10); + if (conn->dacp_active_remote) // this is in case SETUP was previously called + free(conn->dacp_active_remote); + conn->dacp_active_remote = strdup(ar); #ifdef CONFIG_METADATA send_metadata('ssnc', 'acre', ar, strlen(ar), req, 1); #endif } else { debug(2, "Connection %d: SETUP -- Note: no Active-Remote information the SETUP Record.", conn->connection_number); - conn->dacp_active_remote = 0; + if (conn->dacp_active_remote) {// this is in case SETUP was previously called + free(conn->dacp_active_remote); + conn->dacp_active_remote = NULL; + } } ar = msg_get_header(req, "DACP-ID"); @@ -998,9 +1002,10 @@ void handle_setup(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) { } else { debug(2, "Connection %d: SETUP doesn't include DACP-ID string information.", conn->connection_number); - if (conn->dacp_id) // this is in case SETUP was previously called + if (conn->dacp_id) {// this is in case SETUP was previously called free(conn->dacp_id); - conn->dacp_id = NULL; + conn->dacp_id = NULL; + } } char *hdr = msg_get_header(req, "Transport"); diff --git a/shairport.c b/shairport.c index 4ee45bc9..127b23f6 100644 --- a/shairport.c +++ b/shairport.c @@ -1763,8 +1763,7 @@ int main(int argc, char **argv) { config.output = audio_get_output(config.output_name); if (!config.output) { - audio_ls_outputs(); - die("Invalid audio output specified!"); + die("Invalid audio backend \"%s\" selected!", config.output_name == NULL ? "" : config.output_name); } config.output->init(argc - audio_arg, argv + audio_arg);