X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2Fraop_rtp.c;h=1896e160b562c50e1b67081cb65c1950c86165fe;hb=3baaba9d370042e04c70653d46e18bc289d83269;hp=205eee98c097b8b550be662f7bb8aeb2768072c5;hpb=067f00ef04240a933923b996f27ed037ef09c2e6;p=deb_shairplay.git diff --git a/src/lib/raop_rtp.c b/src/lib/raop_rtp.c index 205eee9..1896e16 100644 --- a/src/lib/raop_rtp.c +++ b/src/lib/raop_rtp.c @@ -39,13 +39,21 @@ struct raop_rtp_s { struct sockaddr_storage remote_saddr; socklen_t remote_saddr_len; + /* MUTEX LOCKED VARIABLES START */ /* These variables only edited mutex locked */ int running; int joined; + float volume; + unsigned char *metadata; + int metadata_len; + unsigned char *coverart; + int coverart_len; + int flush; thread_handle_t thread; mutex_handle_t run_mutex; + /* MUTEX LOCKED VARIABLES END */ /* Remote control and timing ports */ unsigned short control_rport; @@ -94,6 +102,10 @@ raop_rtp_parse_remote(raop_rtp_t *raop_rtp, const char *remote) free(original); return -1; } + if (strstr(current, ":")) { + /* FIXME: iTunes sends IP4 even with an IPv6 address, does it mean something */ + family = AF_INET6; + } ret = netutils_parse_address(family, current, &raop_rtp->remote_saddr, sizeof(raop_rtp->remote_saddr)); @@ -149,6 +161,8 @@ raop_rtp_destroy(raop_rtp_t *raop_rtp) MUTEX_DESTROY(raop_rtp->run_mutex); raop_buffer_destroy(raop_rtp->buffer); + free(raop_rtp->metadata); + free(raop_rtp->coverart); free(raop_rtp); } } @@ -210,7 +224,7 @@ raop_rtp_resend_callback(void *opaque, unsigned short seqnum, unsigned short cou addr = (struct sockaddr *)&raop_rtp->control_saddr; addrlen = raop_rtp->control_saddr_len; - logger_log(raop_rtp->logger, LOGGER_DEBUG, "Got resend request %d %d\n", seqnum, count); + logger_log(raop_rtp->logger, LOGGER_DEBUG, "Got resend request %d %d", seqnum, count); ourseqnum = raop_rtp->control_seqnum++; /* Fill the request buffer */ @@ -225,7 +239,7 @@ raop_rtp_resend_callback(void *opaque, unsigned short seqnum, unsigned short cou ret = sendto(raop_rtp->csock, (const char *)packet, sizeof(packet), 0, addr, addrlen); if (ret == -1) { - logger_log(raop_rtp->logger, LOGGER_WARNING, "Resend failed: %d\n", SOCKET_GET_ERROR()); + logger_log(raop_rtp->logger, LOGGER_WARNING, "Resend failed: %d", SOCKET_GET_ERROR()); } return 0; @@ -320,7 +334,7 @@ raop_rtp_thread_udp(void *arg) if (packetlen >= 12) { char type = packet[1] & ~0x80; - logger_log(raop_rtp->logger, LOGGER_DEBUG, "Got control packet of type 0x%02x\n", type); + logger_log(raop_rtp->logger, LOGGER_DEBUG, "Got control packet of type 0x%02x", type); if (type == 0x56) { /* Handle resent data packet */ int ret = raop_buffer_queue(raop_rtp->buffer, packet+4, packetlen-4, 1); @@ -328,7 +342,7 @@ raop_rtp_thread_udp(void *arg) } } } else if (FD_ISSET(raop_rtp->tsock, &rfds)) { - logger_log(raop_rtp->logger, LOGGER_INFO, "Would have timing packet in queue\n"); + logger_log(raop_rtp->logger, LOGGER_INFO, "Would have timing packet in queue"); } else if (FD_ISSET(raop_rtp->dsock, &rfds)) { saddrlen = sizeof(saddr); packetlen = recvfrom(raop_rtp->dsock, (char *)packet, sizeof(packet), 0, @@ -355,7 +369,7 @@ raop_rtp_thread_udp(void *arg) } } } - logger_log(raop_rtp->logger, LOGGER_INFO, "Exiting thread\n"); + logger_log(raop_rtp->logger, LOGGER_INFO, "Exiting UDP RAOP thread"); raop_rtp->callbacks.audio_destroy(raop_rtp->callbacks.cls, cb_data); return 0; @@ -421,19 +435,19 @@ raop_rtp_thread_tcp(void *arg) continue; } else if (ret == -1) { /* FIXME: Error happened */ - logger_log(raop_rtp->logger, LOGGER_INFO, "Error in select\n"); + logger_log(raop_rtp->logger, LOGGER_INFO, "Error in select"); break; } if (stream_fd == -1 && FD_ISSET(raop_rtp->dsock, &rfds)) { struct sockaddr_storage saddr; socklen_t saddrlen; - logger_log(raop_rtp->logger, LOGGER_INFO, "Accepting client\n"); + logger_log(raop_rtp->logger, LOGGER_INFO, "Accepting client"); saddrlen = sizeof(saddr); stream_fd = accept(raop_rtp->dsock, (struct sockaddr *)&saddr, &saddrlen); if (stream_fd == -1) { /* FIXME: Error happened */ - logger_log(raop_rtp->logger, LOGGER_INFO, "Error in accept %d %s\n", errno, strerror(errno)); + logger_log(raop_rtp->logger, LOGGER_INFO, "Error in accept %d %s", errno, strerror(errno)); break; } } @@ -446,11 +460,11 @@ raop_rtp_thread_tcp(void *arg) ret = recv(stream_fd, (char *)(packet+packetlen), sizeof(packet)-packetlen, 0); if (ret == 0) { /* TCP socket closed */ - logger_log(raop_rtp->logger, LOGGER_INFO, "TCP socket closed\n"); + logger_log(raop_rtp->logger, LOGGER_INFO, "TCP socket closed"); break; } else if (ret == -1) { /* FIXME: Error happened */ - logger_log(raop_rtp->logger, LOGGER_INFO, "Error in recv\n"); + logger_log(raop_rtp->logger, LOGGER_INFO, "Error in recv"); break; } packetlen += ret; @@ -466,7 +480,7 @@ raop_rtp_thread_tcp(void *arg) rtplen = (packet[2] << 8) | packet[3]; if (rtplen > sizeof(packet)) { /* FIXME: Too long packet */ - logger_log(raop_rtp->logger, LOGGER_INFO, "Error, packet too long %d\n", rtplen); + logger_log(raop_rtp->logger, LOGGER_INFO, "Error, packet too long %d", rtplen); break; } if (packetlen < 4+rtplen) { @@ -493,7 +507,7 @@ raop_rtp_thread_tcp(void *arg) closesocket(stream_fd); } - logger_log(raop_rtp->logger, LOGGER_INFO, "Exiting thread\n"); + logger_log(raop_rtp->logger, LOGGER_INFO, "Exiting TCP RAOP thread"); raop_rtp->callbacks.audio_destroy(raop_rtp->callbacks.cls, cb_data); return 0; @@ -520,7 +534,7 @@ raop_rtp_start(raop_rtp_t *raop_rtp, int use_udp, unsigned short control_rport, use_ipv6 = 1; } if (raop_rtp_init_sockets(raop_rtp, use_ipv6, use_udp) < 0) { - logger_log(raop_rtp->logger, LOGGER_INFO, "Initializing sockets failed\n"); + logger_log(raop_rtp->logger, LOGGER_INFO, "Initializing sockets failed"); MUTEX_UNLOCK(raop_rtp->run_mutex); return; } @@ -556,6 +570,48 @@ raop_rtp_set_volume(raop_rtp_t *raop_rtp, float volume) MUTEX_UNLOCK(raop_rtp->run_mutex); } +void +raop_rtp_set_metadata(raop_rtp_t *raop_rtp, const char *data, int datalen) +{ + unsigned char *metadata; + + assert(raop_rtp); + + if (datalen <= 0) { + return; + } + metadata = malloc(datalen); + assert(metadata); + memcpy(metadata, data, datalen); + + /* Set metadata in thread instead */ + MUTEX_LOCK(raop_rtp->run_mutex); + raop_rtp->metadata = metadata; + raop_rtp->metadata_len = datalen; + MUTEX_UNLOCK(raop_rtp->run_mutex); +} + +void +raop_rtp_set_coverart(raop_rtp_t *raop_rtp, const char *data, int datalen) +{ + unsigned char *coverart; + + assert(raop_rtp); + + if (datalen <= 0) { + return; + } + coverart = malloc(datalen); + assert(coverart); + memcpy(coverart, data, datalen); + + /* Set coverart in thread instead */ + MUTEX_LOCK(raop_rtp->run_mutex); + raop_rtp->coverart = coverart; + raop_rtp->coverart_len = datalen; + MUTEX_UNLOCK(raop_rtp->run_mutex); +} + void raop_rtp_flush(raop_rtp_t *raop_rtp, int next_seq) {