Merge osxmods into 2.1

This commit is contained in:
Mke Brady
2014-09-09 00:14:31 +01:00
15 changed files with 595 additions and 102 deletions
+10 -9
View File
@@ -421,12 +421,12 @@ double vol2attn(double vol, long max_db, long min_db) {
return vol_setting;
}
uint64_t get_absolute_time_in_ns() {
uint64_t time_now_ns;
uint64_t get_absolute_time_in_fp() {
uint64_t time_now_fp;
#ifdef COMPILE_FOR_LINUX
struct timespec tn;
clock_gettime(CLOCK_MONOTONIC,&tn);
time_now_ns=((uint64_t)tn.tv_sec<<32)+((uint64_t)tn.tv_nsec<<32)/1000000000;
time_now_fp=((uint64_t)tn.tv_sec<<32)+((uint64_t)tn.tv_nsec<<32)/1000000000;
#endif
#ifdef COMPILE_FOR_OSX
uint64_t time_now_mach;
@@ -438,7 +438,7 @@ uint64_t get_absolute_time_in_ns() {
// If this is the first time we've run, get the timebase.
// We can use denom == 0 to indicate that sTimebaseInfo is
// uninitialised because it makes no sense to have a zero
// denominator is a fraction.
// denominator in a fraction.
if ( sTimebaseInfo.denom == 0 ) {
debug(1,"Mac initialise timebase info.");
@@ -448,12 +448,13 @@ uint64_t get_absolute_time_in_ns() {
// Do the maths. We hope that the multiplication doesn't
// overflow; the price you pay for working in fixed point.
// need to turn this into NTP 64-bit fixed point format
// and change the very misleading title of this function to
// get_absolute_fp_time or something
time_now_ns = time_now_mach * sTimebaseInfo.numer / sTimebaseInfo.denom;
// this gives us nanoseconds
uint64_t time_now_ns = time_now_mach * sTimebaseInfo.numer / sTimebaseInfo.denom;
// take the units and shift them to the upper half of the fp, and take the nanoseconds, shift them to the upper half and then divide the result to 1000000000
time_now_fp = ((time_now_ns/1000000000)<<32) + (((time_now_ns%1000000000)<<32)/1000000000);
#endif
return time_now_ns;
return time_now_fp;
}
+1 -1
View File
@@ -80,7 +80,7 @@ double vol2attn(double vol, long max_db, long min_db);
// return a monolithic (always increasing) time in nanoseconds
uint64_t get_absolute_time_in_ns(void);
uint64_t get_absolute_time_in_fp(void);
shairport_cfg config;
+18 -3
View File
@@ -7,24 +7,39 @@ AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([shairport.c])
AC_CONFIG_HEADERS([config.h])
# Derived from the Avahi configure.ac file
#
# Specifying the OS type, defaulting to linux.
#
AC_ARG_WITH(os_type, AS_HELP_STRING([--with-os-type=OSType],[Specify the distribution to target: One of linux darwin]))
if test "z$with_os_type" = "z"; then
with_os_type="linux"
fi
with_os_type=`echo ${with_os_type} | tr '[[:upper:]]' '[[:lower:]]' `
# Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
# Checks for libraries.
AC_CHECK_LIB([rt],[clock_gettime], , AC_MSG_ERROR(librt needed))
if test "x${with_os_type}" = xlinux; then
AC_CHECK_LIB([rt],[clock_gettime], , AC_MSG_ERROR(librt needed))
fi
AC_CHECK_LIB([daemon],[daemon_log], , AC_MSG_ERROR(libdaemon needed))
AC_CHECK_LIB([pthread],[pthread_create], , AC_MSG_ERROR(pthread library needed))
AC_CHECK_LIB([m],[exp], , AC_MSG_ERROR(maths library needed))
AC_CHECK_LIB([popt],[poptGetContext], , AC_MSG_ERROR(libpopt needed))
# Look for polarssl flag
AC_ARG_WITH(polarssl, [ --with-polarssl = choose polarssl for encryption services (choose this or openssl)], [
AC_ARG_WITH(polarssl, [ --with-polarssl = choose polarssl for encryption services (choose this or --with-openssl)], [
AC_MSG_RESULT(>>Including polarssl)
AC_CHECK_LIB([polarssl],[ssl_init], , AC_MSG_ERROR(PolarSSL selected but the library cannot be found!))], )
# Look for openssl flag
AC_ARG_WITH(openssl, [ --with-openssl = choose openssl for encryption services (choose this or polarssl)], [
AC_ARG_WITH(openssl, [ --with-openssl = choose openssl for encryption services (choose this or --with-polarssl)], [
AC_MSG_RESULT(>>Including openssl and libcrypto)
AC_CHECK_LIB([crypto], [MD5_Init], , AC_MSG_ERROR(libcrypto selected, but the library cannot be found!))
AC_CHECK_LIB([ssl],[SSL_library_init], , AC_MSG_ERROR(openssl selected but the library cannot be found!))], )
+7 -7
View File
@@ -35,25 +35,25 @@
#ifdef CONFIG_AVAHI
extern mdns_backend mdns_avahi;
#endif
extern mdns_backend mdns_external_avahi;
extern mdns_backend mdns_external_dns_sd;
extern mdns_backend mdns_tinysvcmdns;
#endif
#ifdef CONFIG_HAVE_DNS_SD_H
extern mdns_backend mdns_dns_sd;
extern mdns_backend mdns_external_dns_sd;
#endif
#ifdef CONFIG_TINYSVCMDNS
extern mdns_backend mdns_tinysvcmdns;
#endif
static mdns_backend *mdns_backends[] = {
#ifdef CONFIG_AVAHI
&mdns_avahi,
&mdns_external_avahi,
#endif
#ifdef CONFIG_HAVE_DNS_SD_H
&mdns_dns_sd,
#endif
&mdns_external_avahi,
&mdns_external_dns_sd,
#endif
#ifdef CONFIG_TINYSVCMDNS
&mdns_tinysvcmdns,
#endif
+36 -24
View File
@@ -162,6 +162,13 @@ static inline seq_t SUCCESSOR(seq_t x) {
return p;
}
static inline seq_t PREDECESSOR(seq_t x) {
uint32_t p = (x & 0xffff)+0x10000;
p-=1;
p = p & 0xffff;
return p;
}
static inline uint32_t ORDINATE(seq_t x) {
uint32_t p = x & 0xffff;
uint32_t q = ab_read & 0x0ffff;
@@ -170,7 +177,7 @@ static inline uint32_t ORDINATE(seq_t x) {
}
// wrapped number between two seq_t.
inline int32_t seq_diff(seq_t a, seq_t b) {
int32_t seq_diff(seq_t a, seq_t b) {
int32_t diff = ORDINATE(b) - ORDINATE(a);
return diff;
}
@@ -182,6 +189,13 @@ static inline int seq_order(seq_t a, seq_t b) {
return d > 0;
}
static inline seq_t seq_sum(seq_t a, seq_t b) {
uint32_t p = a & 0xffff;
uint32_t q = b & 0x0ffff;
uint32_t r = (a+b) & 0xffff;
return r;
}
static void alac_decode(short *dest, uint8_t *buf, int len) {
unsigned char packet[MAX_PACKET];
unsigned char packetp[MAX_PACKET];
@@ -276,7 +290,7 @@ void player_put_packet(seq_t seqno,uint32_t timestamp, uint8_t *data, int len) {
abuf = audio_buffer + BUFIDX(seqno);
ab_write = SUCCESSOR(seqno);
} else if (seq_order(ab_write, seqno)) { // newer than expected
rtp_request_resend(ab_write+1, seqno-1);
rtp_request_resend(SUCCESSOR(ab_write), PREDECESSOR(seqno));
resend_requests++;
abuf = audio_buffer + BUFIDX(seqno);
ab_write = SUCCESSOR(seqno);
@@ -301,7 +315,7 @@ void player_put_packet(seq_t seqno,uint32_t timestamp, uint8_t *data, int len) {
pthread_mutex_lock(&ab_mutex);
time_of_last_audio_packet = get_absolute_time_in_ns();
time_of_last_audio_packet = get_absolute_time_in_fp();
int rc = pthread_cond_signal(&flowcontrol);
if (rc)
@@ -335,7 +349,6 @@ static abuf_t *buffer_get_frame(void) {
int16_t buf_fill;
uint64_t local_time_now;
// struct timespec tn;
seq_t read, next;
abuf_t *abuf = 0;
int i;
abuf_t *curframe;
@@ -345,7 +358,7 @@ static abuf_t *buffer_get_frame(void) {
int32_t dac_delay = 0;
do {
// get the time
local_time_now = get_absolute_time_in_ns();
local_time_now = get_absolute_time_in_fp();
// if config.timeout (default 120) seconds have elapsed since the last audio packet was received, then we should stop.
// config.timeout of zero means don't check..., but iTunes may be confused by a long gap followed by a resumption...
@@ -384,7 +397,7 @@ static abuf_t *buffer_get_frame(void) {
if ((flush_rtp_timestamp) && (flush_rtp_timestamp>=curframe->timestamp)) {
// debug(1,"Dropping flushed packet %d",curframe->sequence_number);
curframe->ready=0;
ab_read++;
ab_read==SUCCESSOR(ab_read);
} else if (ab_buffering) { // if we are getting packets but not yet forwarding them to the player
if (first_packet_timestamp==0) { // if this is the very first packet
// debug(1,"First frame seen, time %u, with %d frames...",curframe->timestamp,seq_diff(ab_read, ab_write));
@@ -480,8 +493,8 @@ static abuf_t *buffer_get_frame(void) {
// debug(1,"pthread_cond_timedwait returned error code %d.",rc);
#endif
#ifdef COMPILE_FOR_OSX
uint64_t sec = time_to_wait_for_wakeup_ns>>32;;
uint64_t nsec = ((time_to_wait_for_wakeup_ns&0xffffffff)*1000000000)>>32;
uint64_t sec = time_to_wait_for_wakeup_fp>>32;;
uint64_t nsec = ((time_to_wait_for_wakeup_fp&0xffffffff)*1000000000)>>32;
struct timespec time_to_wait;
time_to_wait.tv_sec = sec;
time_to_wait.tv_nsec = nsec;
@@ -495,15 +508,15 @@ static abuf_t *buffer_get_frame(void) {
return 0;
}
read = ab_read;
ab_read++;
seq_t read = ab_read;
ab_read=SUCCESSOR(ab_read);
// check if t+16, t+32, t+64, t+128, ... (buffer_start_fill / 2)
// packets have arrived... last-chance resend
if (!ab_buffering) {
for (i = 16; i < (seq_diff(ab_read,ab_write) / 2); i = (i * 2)) {
next = ab_read + i;
seq_t next = seq_sum(ab_read,i);
abuf = audio_buffer + BUFIDX(next);
if (!abuf->ready) {
rtp_request_resend(next, next);
@@ -691,6 +704,7 @@ static void *player_thread_func(void *arg) {
if (inframe) {
inbuf = inframe->data;
if (inbuf) {
play_number++;
// if it's a supplied silent frame, let us know...
if (inframe->timestamp==0) {
// debug(1,"Player has a supplied silent frame.");
@@ -710,7 +724,7 @@ static void *player_thread_func(void *arg) {
rt = reference_timestamp;
nt = inframe->timestamp;
uint64_t local_time_now = get_absolute_time_in_ns();
uint64_t local_time_now = get_absolute_time_in_fp();
//struct timespec tn;
//clock_gettime(CLOCK_MONOTONIC,&tn);
//uint64_t local_time_now=((uint64_t)tn.tv_sec<<32)+((uint64_t)tn.tv_nsec<<32)/1000000000;
@@ -865,20 +879,18 @@ static void *player_thread_func(void *arg) {
if (inframe->sequence_number!=last_seqno_read)
debug(1,"Player: packets out of sequence: expected: %d, got %d.",last_seqno_read,inframe->sequence_number);
last_seqno_read=inframe->sequence_number; // reset warning...
}
if (play_number%print_interval==0) {
// we can now calculate running averages for sync error (frames), corrections (ppm), insertions plus deletions (ppm), drift (ppm)
double moving_average_sync_error = (1.0*tsum_of_sync_errors)/number_of_statistics;
double moving_average_correction = (1.0*tsum_of_corrections)/number_of_statistics;
double moving_average_insertions_plus_deletions = (1.0*tsum_of_insertions_and_deletions)/number_of_statistics;
double moving_average_drift = (1.0*tsum_of_drifts)/number_of_statistics;
uint64_t clock_jitter = ((local_to_remote_time_jitters/local_to_remote_time_jitters_count)*1000000)>>32;
// if ((play_number/print_interval)%20==0)
debug(1,"Sync error: %.1f (frames); net correction: %.1f (ppm); corrections: %.1f (ppm); missing packets %llu; late packets %llu; too late packets %llu; resend requests %llu; min DAC queue size %lli.", moving_average_sync_error, moving_average_correction*1000000/352, moving_average_insertions_plus_deletions*1000000/352,missing_packets,late_packets,too_late_packets,resend_requests,minimum_dac_queue_size);
minimum_dac_queue_size=1000000; // hack reset
}
}
if (play_number%print_interval==0) {
// we can now calculate running averages for sync error (frames), corrections (ppm), insertions plus deletions (ppm), drift (ppm)
double moving_average_sync_error = (1.0*tsum_of_sync_errors)/number_of_statistics;
double moving_average_correction = (1.0*tsum_of_corrections)/number_of_statistics;
double moving_average_insertions_plus_deletions = (1.0*tsum_of_insertions_and_deletions)/number_of_statistics;
double moving_average_drift = (1.0*tsum_of_drifts)/number_of_statistics;
// if ((play_number/print_interval)%20==0)
debug(1,"Sync error: %.1f (frames); net correction: %.1f (ppm); corrections: %.1f (ppm); missing packets %llu; late packets %llu; too late packets %llu; resend requests %llu; min DAC queue size %lli.", moving_average_sync_error, moving_average_correction*1000000/352, moving_average_insertions_plus_deletions*1000000/352,missing_packets,late_packets,too_late_packets,resend_requests,minimum_dac_queue_size);
minimum_dac_queue_size=1000000; // hack reset
}
}
}
}
+1 -1
View File
@@ -11,7 +11,7 @@ typedef struct {
typedef uint16_t seq_t;
// wrapped number between two seq_t.
inline int32_t seq_diff(seq_t a, seq_t b);
int32_t seq_diff(seq_t a, seq_t b);
int player_play(stream_cfg *cfg);
void player_stop(void);
+91 -46
View File
@@ -32,8 +32,10 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <errno.h>
#include "common.h"
#include "player.h"
@@ -153,7 +155,7 @@ static void *rtp_control_receiver(void *arg) {
if (please_shutdown)
break;
nread = recv(control_socket, packet, sizeof(packet), 0);
local_time_now=get_absolute_time_in_ns();
local_time_now=get_absolute_time_in_fp();
// clock_gettime(CLOCK_MONOTONIC,&tn);
// local_time_now=((uint64_t)tn.tv_sec<<32)+((uint64_t)tn.tv_nsec<<32)/1000000000;
@@ -245,8 +247,16 @@ static void *rtp_timing_sender(void *arg) {
req.origin = req.receive = req.transmit=0;
// clock_gettime(CLOCK_MONOTONIC,&dtt);
departure_time=get_absolute_time_in_ns();
sendto(timing_socket, &req, sizeof(req), 0, (struct sockaddr*)&rtp_client_timing_socket, sizeof(rtp_client_timing_socket));
departure_time=get_absolute_time_in_fp();
socklen_t msgsize = sizeof(struct sockaddr_in);
#ifdef AF_INET6
if (rtp_client_timing_socket.SAFAMILY==AF_INET6) {
msgsize = sizeof(struct sockaddr_in6);
}
#endif
if (sendto(timing_socket, &req, sizeof(req), 0, (struct sockaddr*)&rtp_client_timing_socket, msgsize)==-1) {
perror("Error sendto-ing to timing socket");
}
request_number++;
if (request_number<=4)
usleep(500000);
@@ -272,7 +282,7 @@ static void *rtp_timing_receiver(void *arg) {
if (please_shutdown)
break;
nread = recv(timing_socket, packet, sizeof(packet), 0);
arrival_time=get_absolute_time_in_ns();
arrival_time=get_absolute_time_in_fp();
// clock_gettime(CLOCK_MONOTONIC,&att);
if (nread < 0)
@@ -319,7 +329,7 @@ static void *rtp_timing_receiver(void *arg) {
unsigned int cc;
for (cc=time_ping_history-1;cc>0;cc--) {
time_pings[cc]=time_pings[cc-1];
time_pings[cc].dispersion = (time_pings[cc].dispersion*133)/100; // make the dispersions 'age' by this rational factor
time_pings[cc].dispersion = (time_pings[cc].dispersion*133)/100; // make the dispersions 'age' by this rational factor
}
time_pings[0].local_to_remote_difference = local_time_by_remote_clock-arrival_time;
time_pings[0].dispersion = return_time;
@@ -335,24 +345,22 @@ static void *rtp_timing_receiver(void *arg) {
l2rtd=time_pings[cc].local_to_remote_difference;
tld=time_pings[cc].dispersion;
}
int64_t ji;
if (time_ping_count>1) {
if (l2rtd>local_to_remote_time_difference) {
local_to_remote_time_jitters=local_to_remote_time_jitters+l2rtd-local_to_remote_time_difference;
ji = l2rtd-local_to_remote_time_difference;
} else {
local_to_remote_time_jitters=local_to_remote_time_jitters+local_to_remote_time_difference-l2rtd;
ji = - (local_to_remote_time_difference-l2rtd);
}
local_to_remote_time_jitters_count+=1;
}
// int64_t rtus = (tld*1000000)>>32; int64_t ji = ((local_to_remote_time_jitters/local_to_remote_time_jitters_count)*1000000)>>32; debug(1,"Choosing time difference with dispersion of %lld us with jitter of %lld",rtus,ji);
// int64_t rtus = (tld*1000000)>>32; ji = (ji*1000000)>>32; debug(1,"Choosing time difference with dispersion of %lld us with jitter of %lld us",rtus,ji);
int64_t ji;
local_to_remote_time_difference=l2rtd;
if (time_ping_count>1) {
if (l2rtd>local_to_remote_time_difference) {
local_to_remote_time_jitters=local_to_remote_time_jitters+l2rtd-local_to_remote_time_difference;
ji = l2rtd-local_to_remote_time_difference;
} else {
local_to_remote_time_jitters=local_to_remote_time_jitters+local_to_remote_time_difference-l2rtd;
ji = - (local_to_remote_time_difference-l2rtd);
}
local_to_remote_time_jitters_count+=1;
}
// uncomment below to print jitter between client's clock and oour clock
// int64_t rtus = (tld*1000000)>>32; ji = (ji*1000000)>>32; debug(1,"Choosing time difference with dispersion of %lld us with delta of %lld us",rtus,ji);
local_to_remote_time_difference=l2rtd;
} else {
debug(1, "Timing port -- Unknown RTP packet of type 0x%02X length %d.", packet[1], nread);
}
@@ -418,37 +426,67 @@ void rtp_setup(SOCKADDR *remote, int cport, int tport, int *lsport, int *lcport,
die("rtp_setup called with active stream!");
debug(2, "rtp_setup: cport=%d tport=%d.", cport, tport);
// we do our own timing and ignore the timing port.
// an audio perfectionist may wish to learn the protocol.
// print out what we know about the client
void *addr;
char *ipver;
int port;
char ipstr[INET6_ADDRSTRLEN];
char portstr[20];
#ifdef AF_INET6
if (remote->SAFAMILY == AF_INET6) {
struct sockaddr_in6 *sa6 = (struct sockaddr_in6*)remote;
addr = &(sa6->sin6_addr);
port = ntohs(sa6->sin6_port);
ipver = "IPv6";
}
#endif
if (remote->SAFAMILY == AF_INET) {
struct sockaddr_in *sa4 = (struct sockaddr_in*)remote;
addr = &(sa4->sin_addr);
port = ntohs(sa4->sin_port);
ipver = "IPv4";
}
inet_ntop(remote->SAFAMILY,addr,ipstr,sizeof(ipstr));
debug(1,"Connection from %s: %s:%d",ipver,ipstr,port);
// set up a the record of the remote's control socket
struct addrinfo hints;
struct addrinfo *servinfo;
memset(&rtp_client_control_socket,0,sizeof(rtp_client_control_socket));
memset(&hints,0, sizeof hints);
hints.ai_family = remote->SAFAMILY;
hints.ai_socktype = SOCK_DGRAM;
snprintf(portstr, 20, "%d", cport);
if (getaddrinfo(ipstr,portstr,&hints,&servinfo)!=0)
die("Can't get address of client's control port");
memcpy(&rtp_client_control_socket, remote, sizeof(rtp_client_control_socket));
#ifdef AF_INET6
if (rtp_client_control_socket.SAFAMILY == AF_INET6) {
struct sockaddr_in6 *sa6 = (struct sockaddr_in6*)&rtp_client_control_socket;
sa6->sin6_port = htons(cport);
} else
if (servinfo->ai_family == AF_INET6)
memcpy(&rtp_client_control_socket,servinfo->ai_addr,sizeof(struct sockaddr_in6));
else
#endif
{
struct sockaddr_in *sa = (struct sockaddr_in*)&rtp_client_control_socket;
sa->sin_port = htons(cport);
}
memcpy(&rtp_client_control_socket,servinfo->ai_addr,sizeof(struct sockaddr_in));
freeaddrinfo(servinfo);
// set up a the record of the remote's timing socket
memcpy(&rtp_client_timing_socket, remote, sizeof(rtp_client_timing_socket));
memset(&rtp_client_timing_socket,0,sizeof(rtp_client_timing_socket));
memset(&hints,0, sizeof hints);
hints.ai_family = remote->SAFAMILY;
hints.ai_socktype = SOCK_DGRAM;
snprintf(portstr, 20, "%d", tport);
if (getaddrinfo(ipstr,portstr,&hints,&servinfo)!=0)
die("Can't get address of client's timing port");
#ifdef AF_INET6
if (rtp_client_timing_socket.SAFAMILY == AF_INET6) {
struct sockaddr_in6 *sa6 = (struct sockaddr_in6*)&rtp_client_timing_socket;
sa6->sin6_port = htons(tport);
} else
if (servinfo->ai_family == AF_INET6)
memcpy(&rtp_client_timing_socket,servinfo->ai_addr,sizeof(struct sockaddr_in6));
else
#endif
{
struct sockaddr_in *sa = (struct sockaddr_in*)&rtp_client_timing_socket;
sa->sin_port = htons(tport);
}
memcpy(&rtp_client_timing_socket,servinfo->ai_addr,sizeof(struct sockaddr_in));
freeaddrinfo(servinfo);
// now, we open three sockets -- one for the audio stream, one for the timing and one for the control
@@ -513,8 +551,15 @@ void rtp_request_resend(seq_t first, seq_t last) {
*(unsigned short *)(req+2) = htons(1); // our seqnum
*(unsigned short *)(req+4) = htons(first); // missed seqnum
*(unsigned short *)(req+6) = htons(last-first+1); // count
sendto(audio_socket, req, sizeof(req), 0, (struct sockaddr*)&rtp_client_control_socket, sizeof(rtp_client_control_socket));
socklen_t msgsize = sizeof(struct sockaddr_in);
#ifdef AF_INET6
if (rtp_client_timing_socket.SAFAMILY==AF_INET6) {
msgsize = sizeof(struct sockaddr_in6);
}
#endif
if (sendto(audio_socket, req, sizeof(req), 0, (struct sockaddr*)&rtp_client_control_socket,msgsize)==-1) {
perror("Error sendto-ing to audio socket");
}
} else {
if (!request_sent) {
debug(2,"rtp_request_resend called without active stream!");
+12 -11
View File
@@ -751,23 +751,23 @@ static int rtsp_auth(char **nonce, rtsp_message *req, rtsp_message *resp) {
#ifdef HAVE_LIBPOLARSSL
md5_context tctx;
md5_starts(&tctx);
md5_update(&tctx, username, strlen(username));
md5_update(&tctx, (const unsigned char *)username, strlen(username));
md5_update(&tctx, (unsigned char *) ":", 1);
md5_update(&tctx, realm, strlen(realm));
md5_update(&tctx, (const unsigned char *)realm, strlen(realm));
md5_update(&tctx, (unsigned char *) ":", 1);
md5_update(&tctx, config.password, strlen(config.password));
md5_update(&tctx, (const unsigned char *)config.password, strlen(config.password));
md5_finish(&tctx,digest_urp);
md5_starts(&tctx);
md5_update(&tctx, req->method, strlen(req->method));
md5_update(&tctx, (const unsigned char *)req->method, strlen(req->method));
md5_update(&tctx, (unsigned char *) ":", 1);
md5_update(&tctx, uri, strlen(uri));
md5_update(&tctx, (const unsigned char *)uri, strlen(uri));
md5_finish(&tctx,digest_mu);
#endif
int i;
unsigned char buf[33];
for (i=0; i<16; i++)
sprintf(buf + 2*i, "%02X", digest_urp[i]);
sprintf((char *)buf + 2*i, "%02X", digest_urp[i]);
#ifdef HAVE_LIBSSL
MD5_Init(&ctx);
@@ -786,18 +786,18 @@ static int rtsp_auth(char **nonce, rtsp_message *req, rtsp_message *resp) {
md5_starts(&tctx);
md5_update(&tctx, buf, 32);
md5_update(&tctx, (unsigned char *) ":", 1);
md5_update(&tctx, *nonce, strlen(*nonce));
md5_update(&tctx, (const unsigned char *)*nonce, strlen(*nonce));
md5_update(&tctx, (unsigned char *) ":", 1);
for (i=0; i<16; i++)
sprintf(buf + 2*i, "%02X", digest_mu[i]);
sprintf((char *)buf + 2*i,"%02X", digest_mu[i]);
md5_update(&tctx, buf, 32);
md5_finish(&tctx,digest_total);
#endif
for (i=0; i<16; i++)
sprintf(buf + 2*i, "%02X", digest_total[i]);
sprintf((char *)buf + 2*i,"%02X", digest_total[i]);
if (!strcmp(response, buf))
if (!strcmp(response, (const char *)buf))
return 0;
warn("auth failed");
@@ -910,7 +910,8 @@ void rtsp_listen_loop(void) {
int fd = socket(p->ai_family, p->ai_socktype, IPPROTO_TCP);
int yes = 1;
ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1)
perror("setsockopt");
#ifdef IPV6_V6ONLY
// some systems don't support v4 access on v6 sockets, but some do.
+209
View File
@@ -0,0 +1,209 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXFileReference section */
2785806419BB488D00C0B34D /* alac.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = alac.c; sourceTree = "<group>"; };
2785806519BB488D00C0B34D /* alac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = alac.h; sourceTree = "<group>"; };
2785806619BB488D00C0B34D /* audio.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio.c; sourceTree = "<group>"; };
2785806719BB488D00C0B34D /* audio.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = audio.h; sourceTree = "<group>"; };
2785806819BB488D00C0B34D /* audio_alsa.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio_alsa.c; sourceTree = "<group>"; };
2785806919BB488D00C0B34D /* audio_ao.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio_ao.c; sourceTree = "<group>"; };
2785806A19BB488D00C0B34D /* audio_dummy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio_dummy.c; sourceTree = "<group>"; };
2785806B19BB488D00C0B34D /* audio_pipe.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio_pipe.c; sourceTree = "<group>"; };
2785806C19BB488D00C0B34D /* audio_pulse.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio_pulse.c; sourceTree = "<group>"; };
2785806D19BB488D00C0B34D /* audio_sndio.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio_sndio.c; sourceTree = "<group>"; };
2785806E19BB488D00C0B34D /* AUTHORS */ = {isa = PBXFileReference; lastKnownFileType = text; path = AUTHORS; sourceTree = "<group>"; };
2785807119BB488D00C0B34D /* common.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = common.c; sourceTree = "<group>"; };
2785807219BB488D00C0B34D /* common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = "<group>"; };
2785807C19BB488D00C0B34D /* configure.ac */ = {isa = PBXFileReference; lastKnownFileType = text; path = configure.ac; sourceTree = "<group>"; };
2785807D19BB488D00C0B34D /* COPYING */ = {isa = PBXFileReference; lastKnownFileType = text; path = COPYING; sourceTree = "<group>"; };
2785807F19BB488D00C0B34D /* documents */ = {isa = PBXFileReference; lastKnownFileType = folder; path = documents; sourceTree = "<group>"; };
2785808019BB488D00C0B34D /* INSTALL */ = {isa = PBXFileReference; lastKnownFileType = text; path = INSTALL; sourceTree = "<group>"; };
2785808219BB488D00C0B34D /* LICENSES */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSES; sourceTree = "<group>"; };
2785808419BB488D00C0B34D /* Makefile.am */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
2785808619BB488D00C0B34D /* mdns.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mdns.c; sourceTree = "<group>"; };
2785808719BB488D00C0B34D /* mdns.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mdns.h; sourceTree = "<group>"; };
2785808819BB488D00C0B34D /* mdns_avahi.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mdns_avahi.c; sourceTree = "<group>"; };
2785808919BB488D00C0B34D /* mdns_dns_sd.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mdns_dns_sd.c; sourceTree = "<group>"; };
2785808A19BB488D00C0B34D /* mdns_external.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mdns_external.c; sourceTree = "<group>"; };
2785808B19BB488D00C0B34D /* mdns_tinysvcmdns.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mdns_tinysvcmdns.c; sourceTree = "<group>"; };
2785808D19BB488D00C0B34D /* NEWS */ = {isa = PBXFileReference; lastKnownFileType = text; path = NEWS; sourceTree = "<group>"; };
2785808E19BB488D00C0B34D /* player.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = player.c; sourceTree = "<group>"; };
2785808F19BB488D00C0B34D /* player.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = player.h; sourceTree = "<group>"; };
2785809019BB488D00C0B34D /* README */ = {isa = PBXFileReference; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
2785809119BB488D00C0B34D /* README.md */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.md; sourceTree = "<group>"; };
2785809219BB488D00C0B34D /* rtp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = rtp.c; sourceTree = "<group>"; };
2785809319BB488D00C0B34D /* rtp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rtp.h; sourceTree = "<group>"; };
2785809419BB488D00C0B34D /* rtsp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = rtsp.c; sourceTree = "<group>"; };
2785809519BB488D00C0B34D /* rtsp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rtsp.h; sourceTree = "<group>"; };
2785809619BB488D00C0B34D /* scripts */ = {isa = PBXFileReference; lastKnownFileType = folder; path = scripts; sourceTree = "<group>"; };
2785809719BB488D00C0B34D /* shairport-sync.xcworkspace */ = {isa = PBXFileReference; lastKnownFileType = wrapper.workspace; path = "shairport-sync.xcworkspace"; sourceTree = "<group>"; };
2785809819BB488D00C0B34D /* shairport.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = shairport.c; sourceTree = "<group>"; };
2785809A19BB488D00C0B34D /* tinysvcmdns.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = tinysvcmdns.c; sourceTree = "<group>"; };
2785809B19BB488D00C0B34D /* tinysvcmdns.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = tinysvcmdns.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXGroup section */
2785805919BB488D00C0B34D = {
isa = PBXGroup;
children = (
2785806419BB488D00C0B34D /* alac.c */,
2785806519BB488D00C0B34D /* alac.h */,
2785806619BB488D00C0B34D /* audio.c */,
2785806719BB488D00C0B34D /* audio.h */,
2785806819BB488D00C0B34D /* audio_alsa.c */,
2785806919BB488D00C0B34D /* audio_ao.c */,
2785806A19BB488D00C0B34D /* audio_dummy.c */,
2785806B19BB488D00C0B34D /* audio_pipe.c */,
2785806C19BB488D00C0B34D /* audio_pulse.c */,
2785806D19BB488D00C0B34D /* audio_sndio.c */,
2785806E19BB488D00C0B34D /* AUTHORS */,
2785807119BB488D00C0B34D /* common.c */,
2785807219BB488D00C0B34D /* common.h */,
2785807C19BB488D00C0B34D /* configure.ac */,
2785807D19BB488D00C0B34D /* COPYING */,
2785807F19BB488D00C0B34D /* documents */,
2785808019BB488D00C0B34D /* INSTALL */,
2785808219BB488D00C0B34D /* LICENSES */,
2785808419BB488D00C0B34D /* Makefile.am */,
2785808619BB488D00C0B34D /* mdns.c */,
2785808719BB488D00C0B34D /* mdns.h */,
2785808819BB488D00C0B34D /* mdns_avahi.c */,
2785808919BB488D00C0B34D /* mdns_dns_sd.c */,
2785808A19BB488D00C0B34D /* mdns_external.c */,
2785808B19BB488D00C0B34D /* mdns_tinysvcmdns.c */,
2785808D19BB488D00C0B34D /* NEWS */,
2785808E19BB488D00C0B34D /* player.c */,
2785808F19BB488D00C0B34D /* player.h */,
2785809019BB488D00C0B34D /* README */,
2785809119BB488D00C0B34D /* README.md */,
2785809219BB488D00C0B34D /* rtp.c */,
2785809319BB488D00C0B34D /* rtp.h */,
2785809419BB488D00C0B34D /* rtsp.c */,
2785809519BB488D00C0B34D /* rtsp.h */,
2785809619BB488D00C0B34D /* scripts */,
2785809719BB488D00C0B34D /* shairport-sync.xcworkspace */,
2785809819BB488D00C0B34D /* shairport.c */,
2785809A19BB488D00C0B34D /* tinysvcmdns.c */,
2785809B19BB488D00C0B34D /* tinysvcmdns.h */,
);
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXLegacyTarget section */
2785805E19BB488D00C0B34D /* shairport-sync */ = {
isa = PBXLegacyTarget;
buildArgumentsString = "$(ACTION)";
buildConfigurationList = 2785809C19BB488D00C0B34D /* Build configuration list for PBXLegacyTarget "shairport-sync" */;
buildPhases = (
);
buildToolPath = /usr/bin/make;
buildWorkingDirectory = "/Users/mike/Documents/git/shairport-sync";
dependencies = (
);
name = "shairport-sync";
passBuildSettingsInEnvironment = 1;
productName = "shairport-sync";
};
/* End PBXLegacyTarget section */
/* Begin PBXProject section */
2785805A19BB488D00C0B34D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0510;
};
buildConfigurationList = 2785805D19BB488D00C0B34D /* Build configuration list for PBXProject "shairport-sync" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 2785805919BB488D00C0B34D;
projectDirPath = "";
projectRoot = "";
targets = (
2785805E19BB488D00C0B34D /* shairport-sync */,
);
};
/* End PBXProject section */
/* Begin XCBuildConfiguration section */
2785805B19BB488D00C0B34D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
2785805C19BB488D00C0B34D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
SDKROOT = macosx;
};
name = Release;
};
2785809D19BB488D00C0B34D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
DEBUGGING_SYMBOLS = YES;
GCC_DYNAMIC_NO_PIC = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
OTHER_CFLAGS = "";
OTHER_LDFLAGS = "";
PRODUCT_NAME = "shairport-sync";
};
name = Debug;
};
2785809E19BB488D00C0B34D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
OTHER_CFLAGS = "";
OTHER_LDFLAGS = "";
PRODUCT_NAME = "shairport-sync";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
2785805D19BB488D00C0B34D /* Build configuration list for PBXProject "shairport-sync" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2785805B19BB488D00C0B34D /* Debug */,
2785805C19BB488D00C0B34D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
2785809C19BB488D00C0B34D /* Build configuration list for PBXLegacyTarget "shairport-sync" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2785809D19BB488D00C0B34D /* Debug */,
2785809E19BB488D00C0B34D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 2785805A19BB488D00C0B34D /* Project object */;
}
@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "2785805E19BB488D00C0B34D"
BuildableName = "shairport-sync"
BlueprintName = "shairport-sync"
ReferencedContainer = "container:shairport-sync.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "NO">
<PathRunnable
FilePath = "/Users/mike/Documents/git/shairport-sync/shairport-sync">
</PathRunnable>
<CommandLineArguments>
<CommandLineArgument
argument = "-v"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
<AdditionalOptions>
<AdditionalOption
key = "DYLD_INSERT_LIBRARIES"
value = "/usr/lib/libgmalloc.dylib"
isEnabled = "YES">
</AdditionalOption>
<AdditionalOption
key = "OBJC_PRINT_EXCEPTIONS"
value = "YES"
isEnabled = "YES">
</AdditionalOption>
<AdditionalOption
key = "USERBREAK"
value = "1"
isEnabled = "YES">
</AdditionalOption>
<AdditionalOption
key = "MallocGuardEdges"
value = ""
isEnabled = "YES">
</AdditionalOption>
<AdditionalOption
key = "MallocScribble"
value = ""
isEnabled = "YES">
</AdditionalOption>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>shairport-sync.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>2785805E19BB488D00C0B34D</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:shairport-sync.xcodeproj">
</FileRef>
</Workspace>
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
<false/>
<key>IDESourceControlProjectIdentifier</key>
<string>FE3806DD-2182-4590-A83E-FEB5D071A2C5</string>
<key>IDESourceControlProjectName</key>
<string>shairport-sync</string>
<key>IDESourceControlProjectOriginsDictionary</key>
<dict>
<key>6DA2D7CF-469E-4320-AD70-9612E79D9450</key>
<string>ssh://github.com/mikebrady/shairport-sync.git</string>
</dict>
<key>IDESourceControlProjectPath</key>
<string>shairport-sync.xcworkspace</string>
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
<dict>
<key>6DA2D7CF-469E-4320-AD70-9612E79D9450</key>
<string>..</string>
</dict>
<key>IDESourceControlProjectURL</key>
<string>ssh://github.com/mikebrady/shairport-sync.git</string>
<key>IDESourceControlProjectVersion</key>
<integer>110</integer>
<key>IDESourceControlProjectWCCIdentifier</key>
<string>6DA2D7CF-469E-4320-AD70-9612E79D9450</string>
<key>IDESourceControlProjectWCConfigurations</key>
<array>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>
<key>IDESourceControlWCCIdentifierKey</key>
<string>6DA2D7CF-469E-4320-AD70-9612E79D9450</string>
<key>IDESourceControlWCCName</key>
<string>shairport-sync</string>
</dict>
</array>
</dict>
</plist>
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildLocationStyle</key>
<string>UseAppPreferences</string>
<key>CustomBuildLocationType</key>
<string>RelativeToDerivedData</string>
<key>DerivedDataLocationStyle</key>
<string>Default</string>
<key>HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges</key>
<true/>
<key>IssueFilterStyle</key>
<string>ShowActiveSchemeOnly</string>
<key>LiveSourceIssuesEnabled</key>
<true/>
<key>SnapshotAutomaticallyBeforeSignificantChanges</key>
<true/>
<key>SnapshotLocationStyle</key>
<string>Default</string>
</dict>
</plist>
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
type = "0"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.SymbolicBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "Yes"
symbolName = "SIGUSR1"
moduleName = "">
<Actions>
<BreakpointActionProxy
ActionExtensionID = "Xcode.BreakpointAction.DebuggerCommand">
<ActionContent
consoleCommand = "process handle SIGUSR1 -n true -p true -s false">
</ActionContent>
</BreakpointActionProxy>
</Actions>
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>