Merge pull request #138 from toofishes/cleanup

Cleanup, optimization, and bug fixes
This commit is contained in:
Albert Zeyer
2012-02-24 14:59:44 -08:00
7 changed files with 201 additions and 180 deletions
+2 -2
View File
@@ -4,7 +4,7 @@ OBJS=socketlib.o shairport.o alac.o hairtunes.o
all: hairtunes shairport
hairtunes: hairtunes.c alac.o
$(CC) $(CFLAGS) -DHAIRTUNES_STANDALONE hairtunes.c alac.c -o $@ $(LDFLAGS)
$(CC) $(CFLAGS) -DHAIRTUNES_STANDALONE hairtunes.c alac.o -o $@ $(LDFLAGS)
shairport: $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $@ $(LDFLAGS)
@@ -23,7 +23,7 @@ install: hairtunes shairport
install -D -m 0755 shairport.pl $(DESTDIR)$(prefix)/bin/shairport.pl
install -D -m 0755 shairport $(DESTDIR)$(prefix)/bin/shairport
.PTHONY: all clean install
.PHONY: all clean install
.SILENT: clean
+4 -5
View File
@@ -109,7 +109,6 @@ void alac_set_info(alac_file *alac, char *inputbuffer)
alac->setinfo_8a_rate = *(uint32_t*)ptr;
if (!host_bigendian)
_Swap32(alac->setinfo_8a_rate);
ptr += 4;
allocate_buffers(alac);
@@ -290,7 +289,7 @@ found:
#define RICE_THRESHOLD 8 // maximum number of bits for a rice prefix.
int32_t entropy_decode_value(alac_file* alac,
static int32_t entropy_decode_value(alac_file* alac,
int readSampleSize,
int k,
int rice_kmodifier_mask)
@@ -334,7 +333,7 @@ int32_t entropy_decode_value(alac_file* alac,
return x;
}
void entropy_rice_decode(alac_file* alac,
static void entropy_rice_decode(alac_file* alac,
int32_t* outputBuffer,
int outputSize,
int readSampleSize,
@@ -551,7 +550,7 @@ static void predictor_decompress_fir_adapt(int32_t *error_buffer,
}
}
void deinterlace_16(int32_t *buffer_a, int32_t *buffer_b,
static void deinterlace_16(int32_t *buffer_a, int32_t *buffer_b,
int16_t *buffer_out,
int numchannels, int numsamples,
uint8_t interlacing_shift,
@@ -610,7 +609,7 @@ void deinterlace_16(int32_t *buffer_a, int32_t *buffer_b,
}
}
void deinterlace_24(int32_t *buffer_a, int32_t *buffer_b,
static void deinterlace_24(int32_t *buffer_a, int32_t *buffer_b,
int uncompressed_bytes,
int32_t *uncompressed_bytes_buffer_a, int32_t *uncompressed_bytes_buffer_b,
void *buffer_out,
+120 -97
View File
@@ -48,7 +48,7 @@
#endif
#include <assert.h>
int debug = 0;
static int debug = 0;
#include "alac.h"
@@ -60,66 +60,68 @@ int debug = 0;
typedef unsigned short seq_t;
// global options (constant after init)
unsigned char aeskey[16], aesiv[16];
AES_KEY aes;
char *rtphost = 0;
int dataport = 0, controlport = 0, timingport = 0;
int fmtp[32];
int sampling_rate;
int frame_size;
static unsigned char aeskey[16], aesiv[16];
static AES_KEY aes;
static char *rtphost = 0;
static int dataport = 0, controlport = 0, timingport = 0;
static int fmtp[32];
static int sampling_rate;
static int frame_size;
int buffer_start_fill = START_FILL;
static int buffer_start_fill;
char *libao_driver = NULL;
char *libao_devicename = NULL;
char *libao_deviceid = NULL; // ao_options expects "char*"
static char *libao_driver = NULL;
static char *libao_devicename = NULL;
static char *libao_deviceid = NULL; // ao_options expects "char*"
// FIFO name and file handle
char *pipename = NULL;
int pipe_handle = -1;
static char *pipename = NULL;
static int pipe_handle = -1;
#define FRAME_BYTES (4*frame_size)
// maximal resampling shift - conservative
#define OUTFRAME_BYTES (4*(frame_size+3))
alac_file *decoder_info;
static alac_file *decoder_info;
#ifdef FANCY_RESAMPLING
int fancy_resampling = 1;
SRC_STATE *src;
static int fancy_resampling = 1;
static SRC_STATE *src;
#endif
int init_rtp(void);
void init_buffer(void);
int init_output(void);
void rtp_request_resend(seq_t first, seq_t last);
void ab_resync(void);
static int init_rtp(void);
static void init_buffer(void);
static int init_output(void);
static void rtp_request_resend(seq_t first, seq_t last);
static void ab_resync(void);
// interthread variables
// stdin->decoder
volatile double volume = 1.0;
volatile long fix_volume = 0x10000;
// stdin->decoder
static double volume = 1.0;
static int fix_volume = 0x10000;
static pthread_mutex_t vol_mutex = PTHREAD_MUTEX_INITIALIZER;
typedef struct audio_buffer_entry { // decoded audio packets
int ready;
signed short *data;
} abuf_t;
volatile abuf_t audio_buffer[BUFFER_FRAMES];
static abuf_t audio_buffer[BUFFER_FRAMES];
#define BUFIDX(seqno) ((seq_t)(seqno) % BUFFER_FRAMES)
// mutex-protected variables
volatile seq_t ab_read, ab_write;
int ab_buffering = 1, ab_synced = 0;
pthread_mutex_t ab_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t ab_buffer_ready = PTHREAD_COND_INITIALIZER;
static seq_t ab_read, ab_write;
static int ab_buffering = 1, ab_synced = 0;
static pthread_mutex_t ab_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t ab_buffer_ready = PTHREAD_COND_INITIALIZER;
void die(char *why) {
static void die(char *why) {
fprintf(stderr, "FATAL: %s\n", why);
exit(1);
}
int hex2bin(unsigned char *buf, char *hex) {
#ifdef HAIRTUNES_STANDALONE
static int hex2bin(unsigned char *buf, char *hex) {
int i, j;
if (strlen(hex) != 0x20)
return 1;
@@ -131,8 +133,9 @@ int hex2bin(unsigned char *buf, char *hex) {
}
return 0;
}
#endif
int init_decoder(void) {
static int init_decoder(void) {
alac_file *alac;
frame_size = fmtp[1]; // stereo samples
@@ -163,7 +166,8 @@ int init_decoder(void) {
}
int hairtunes_init(char *pAeskey, char *pAesiv, char *fmtpstr, int pCtrlPort, int pTimingPort,
int pDataPort, char *pRtpHost, char*pPipeName, char *pLibaoDriver, char *pLibaoDeviceName, char *pLibaoDeviceId)
int pDataPort, char *pRtpHost, char*pPipeName, char *pLibaoDriver, char *pLibaoDeviceName, char *pLibaoDeviceId,
int bufStartFill)
{
if(pAeskey != NULL)
memcpy(aeskey, pAeskey, sizeof(aeskey));
@@ -183,6 +187,9 @@ int hairtunes_init(char *pAeskey, char *pAesiv, char *fmtpstr, int pCtrlPort, in
controlport = pCtrlPort;
timingport = pTimingPort;
dataport = pDataPort;
if(bufStartFill < 0)
bufStartFill = START_FILL;
buffer_start_fill = bufStartFill;
AES_set_decrypt_key(aeskey, 128, &aes);
@@ -214,8 +221,10 @@ int hairtunes_init(char *pAeskey, char *pAesiv, char *fmtpstr, int pCtrlPort, in
assert(f<=0);
if (debug)
fprintf(stderr, "VOL: %lf\n", f);
pthread_mutex_lock(&vol_mutex);
volume = pow(10.0,0.05*f);
fix_volume = 65536.0 * volume;
pthread_mutex_unlock(&vol_mutex);
continue;
}
if (!strcmp(line, "exit\n")) {
@@ -309,18 +318,18 @@ int main(int argc, char **argv) {
if (hex2bin(aeskey, hexaeskey))
die("can't understand key");
return hairtunes_init(NULL, NULL, fmtpstr, controlport, timingport, dataport,
NULL, NULL, NULL, NULL, NULL);
NULL, NULL, NULL, NULL, NULL, START_FILL);
}
#endif
void init_buffer(void) {
static void init_buffer(void) {
int i;
for (i=0; i<BUFFER_FRAMES; i++)
audio_buffer[i].data = malloc(OUTFRAME_BYTES);
ab_resync();
}
void ab_resync(void) {
static void ab_resync(void) {
int i;
for (i=0; i<BUFFER_FRAMES; i++)
audio_buffer[i].ready = 0;
@@ -335,7 +344,7 @@ static inline int seq_order(seq_t a, seq_t b) {
return d > 0;
}
void alac_decode(short *dest, char *buf, int len) {
static void alac_decode(short *dest, char *buf, int len) {
unsigned char packet[MAX_PACKET];
assert(len<=MAX_PACKET);
@@ -352,9 +361,8 @@ void alac_decode(short *dest, char *buf, int len) {
assert(outsize == FRAME_BYTES);
}
void buffer_put_packet(seq_t seqno, char *data, int len) {
volatile abuf_t *abuf = 0;
short read;
static void buffer_put_packet(seq_t seqno, char *data, int len) {
abuf_t *abuf = 0;
short buf_fill;
pthread_mutex_lock(&ab_mutex);
@@ -367,7 +375,7 @@ void buffer_put_packet(seq_t seqno, char *data, int len) {
abuf = audio_buffer + BUFIDX(seqno);
ab_write = seqno;
} else if (seq_order(ab_write, seqno)) { // newer than expected
rtp_request_resend(ab_write, seqno-1);
rtp_request_resend(ab_write+1, seqno-1);
abuf = audio_buffer + BUFIDX(seqno);
ab_write = seqno;
} else if (seq_order(ab_read, seqno)) { // late but not yet played
@@ -383,29 +391,22 @@ void buffer_put_packet(seq_t seqno, char *data, int len) {
abuf->ready = 1;
}
pthread_mutex_lock(&ab_mutex);
if (ab_buffering && buf_fill >= buffer_start_fill) {
ab_buffering = 0;
pthread_cond_signal(&ab_buffer_ready);
}
if (!ab_buffering) {
// check if the t+10th packet has arrived... last-chance resend
read = ab_read + 10;
abuf = audio_buffer + BUFIDX(read);
if (abuf->ready != 1) {
rtp_request_resend(read, read);
abuf->ready = -1;
}
}
pthread_mutex_unlock(&ab_mutex);
}
static int rtp_sockets[2]; // data, control
#ifdef AF_INET6
struct sockaddr_in6 rtp_client;
static struct sockaddr_in6 rtp_client;
#else
struct sockaddr_in rtp_client;
static struct sockaddr_in rtp_client;
#endif
void *rtp_thread_func(void *arg) {
static void *rtp_thread_func(void *arg) {
socklen_t si_len = sizeof(rtp_client);
char packet[MAX_PACKET];
char *pktp;
@@ -449,7 +450,7 @@ void *rtp_thread_func(void *arg) {
return 0;
}
void rtp_request_resend(seq_t first, seq_t last) {
static void rtp_request_resend(seq_t first, seq_t last) {
if (seq_order(last, first))
return;
@@ -471,25 +472,25 @@ void rtp_request_resend(seq_t first, seq_t last) {
}
int init_rtp(void) {
static int init_rtp(void) {
struct sockaddr_in si;
int type = AF_INET;
struct sockaddr* si_p = (struct sockaddr*)&si;
socklen_t si_len = sizeof(si);
struct sockaddr* si_p = (struct sockaddr*)&si;
socklen_t si_len = sizeof(si);
unsigned short *sin_port = &si.sin_port;
memset(&si, 0, sizeof(si));
#ifdef AF_INET6
struct sockaddr_in6 si6;
type = AF_INET6;
si_p = (struct sockaddr*)&si6;
si_len = sizeof(si6);
si_p = (struct sockaddr*)&si6;
si_len = sizeof(si6);
sin_port = &si6.sin6_port;
memset(&si6, 0, sizeof(si6));
#endif
si.sin_family = AF_INET;
#ifdef SIN_LEN
si.sin_len = sizeof(si);
si.sin_len = sizeof(si);
#endif
si.sin_addr.s_addr = htonl(INADDR_ANY);
#ifdef AF_INET6
@@ -507,14 +508,14 @@ int init_rtp(void) {
if(sock < 0)
sock = socket(type, SOCK_DGRAM, IPPROTO_UDP);
#ifdef AF_INET6
if(sock==-1 && type == AF_INET6) {
// try fallback to IPv4
type = AF_INET;
si_p = (struct sockaddr*)&si;
si_len = sizeof(si);
sin_port = &si.sin_port;
continue;
}
if(sock==-1 && type == AF_INET6) {
// try fallback to IPv4
type = AF_INET;
si_p = (struct sockaddr*)&si;
si_len = sizeof(si);
sin_port = &si.sin_port;
continue;
}
#endif
if (sock==-1)
die("Can't create data socket!");
@@ -550,11 +551,11 @@ int init_rtp(void) {
static inline short dithered_vol(short sample) {
static short rand_a, rand_b;
long out;
rand_b = rand_a;
rand_a = rand() & 0xffff;
out = (long)sample * fix_volume;
if (fix_volume < 0x10000) {
rand_b = rand_a;
rand_a = rand() & 0xffff;
out += rand_a;
out -= rand_b;
}
@@ -590,14 +591,14 @@ static void biquad_lpf(biquad_t *bq, double freq, double Q) {
static double biquad_filt(biquad_t *bq, double in) {
double w = in - bq->a[0]*bq->hist[0] - bq->a[1]*bq->hist[1];
double out __attribute__((unused)) = bq->b[1]*bq->hist[0] + bq->b[2]*bq->hist[1] + bq->b[0]*w;
double out = bq->b[1]*bq->hist[0] + bq->b[2]*bq->hist[1] + bq->b[0]*w;
bq->hist[1] = bq->hist[0];
bq->hist[0] = w;
return w;
return out;
}
double bf_playback_rate = 1.0;
static double bf_playback_rate = 1.0;
static double bf_est_drift = 0.0; // local clock is slower by
static biquad_t bf_drift_lpf;
@@ -606,7 +607,7 @@ static biquad_t bf_err_lpf, bf_err_deriv_lpf;
static double desired_fill;
static int fill_count;
void bf_est_reset(short fill) {
static void bf_est_reset(short fill) {
biquad_lpf(&bf_drift_lpf, 1.0/180.0, 0.3);
biquad_lpf(&bf_err_lpf, 1.0/10.0, 0.25);
biquad_lpf(&bf_err_deriv_lpf, 1.0/2.0, 0.2);
@@ -615,7 +616,8 @@ void bf_est_reset(short fill) {
bf_est_err = bf_last_err = 0;
desired_fill = fill_count = 0;
}
void bf_est_update(short fill) {
static void bf_est_update(short fill) {
if (fill_count < 1000) {
desired_fill += (double)fill/1000.0;
fill_count++;
@@ -628,20 +630,25 @@ void bf_est_update(short fill) {
double buf_delta = fill - desired_fill;
bf_est_err = biquad_filt(&bf_err_lpf, buf_delta);
double err_deriv = biquad_filt(&bf_err_deriv_lpf, bf_est_err - bf_last_err);
double adj_error = CONTROL_A * bf_est_err;
bf_est_drift = biquad_filt(&bf_drift_lpf, CONTROL_B*(bf_est_err*CONTROL_A + err_deriv) + bf_est_drift);
bf_est_drift = biquad_filt(&bf_drift_lpf, CONTROL_B*(adj_error + err_deriv) + bf_est_drift);
if (debug)
fprintf(stderr, "bf %d err %f drift %f desiring %f ed %f estd %f\r", fill, bf_est_err, bf_est_drift, desired_fill, err_deriv, err_deriv + CONTROL_A*bf_est_err);
bf_playback_rate = 1.0 + CONTROL_A*bf_est_err + bf_est_drift;
fprintf(stderr, "bf %d err %f drift %f desiring %f ed %f estd %f\n",
fill, bf_est_err, bf_est_drift, desired_fill, err_deriv, err_deriv + adj_error);
bf_playback_rate = 1.0 + adj_error + bf_est_drift;
bf_last_err = bf_est_err;
}
// get the next frame, when available. return 0 if underrun/stream reset.
short *buffer_get_frame(void) {
static short *buffer_get_frame(void) {
short buf_fill;
seq_t read;
abuf_t *abuf = 0;
unsigned short next;
int i;
pthread_mutex_lock(&ab_mutex);
@@ -654,32 +661,44 @@ short *buffer_get_frame(void) {
pthread_cond_wait(&ab_buffer_ready, &ab_mutex);
ab_read++;
buf_fill = ab_write - ab_read;
bf_est_reset(buf_fill);
pthread_mutex_unlock(&ab_mutex);
bf_est_reset(buf_fill);
return 0;
}
if (buf_fill >= BUFFER_FRAMES) { // overrunning! uh-oh. restart at a sane distance
fprintf(stderr, "\noverrun.\n");
ab_read = ab_write - START_FILL;
ab_read = ab_write - buffer_start_fill;
}
read = ab_read;
ab_read++;
pthread_mutex_unlock(&ab_mutex);
buf_fill = ab_write - ab_read;
bf_est_update(buf_fill);
volatile abuf_t *curframe = audio_buffer + BUFIDX(read);
if (curframe->ready != 1) {
// check if t+16, t+32, t+64, t+128, ... (START_FILL / 2)
// packets have arrived... last-chance resend
if (!ab_buffering) {
for (i = 16; i < (START_FILL / 2); i = (i * 2)) {
next = ab_read + i;
abuf = audio_buffer + BUFIDX(next);
if (!abuf->ready) {
rtp_request_resend(next, next);
}
}
}
abuf_t *curframe = audio_buffer + BUFIDX(read);
if (!curframe->ready) {
fprintf(stderr, "\nmissing frame.\n");
memset(curframe->data, 0, FRAME_BYTES);
}
curframe->ready = 0;
pthread_mutex_unlock(&ab_mutex);
return curframe->data;
}
int stuff_buffer(double playback_rate, short *inptr, short *outptr) {
static int stuff_buffer(double playback_rate, short *inptr, short *outptr) {
int i;
int stuffsamp = frame_size;
int stuff = 0;
@@ -692,6 +711,7 @@ int stuff_buffer(double playback_rate, short *inptr, short *outptr) {
stuffsamp = rand() % (frame_size - 1);
}
pthread_mutex_lock(&vol_mutex);
for (i=0; i<stuffsamp; i++) { // the whole frame, if no stuffing
*outptr++ = dithered_vol(*inptr++);
*outptr++ = dithered_vol(*inptr++);
@@ -714,12 +734,13 @@ int stuff_buffer(double playback_rate, short *inptr, short *outptr) {
*outptr++ = dithered_vol(*inptr++);
}
}
pthread_mutex_unlock(&vol_mutex);
return frame_size + stuff;
}
void *audio_thread_func(void *arg) {
ao_device* dev = arg;
static void *audio_thread_func(void *arg) {
ao_device* dev = arg;
int play_samples;
signed short buf_fill __attribute__((unused));
@@ -749,11 +770,13 @@ void *audio_thread_func(void *arg) {
#ifdef FANCY_RESAMPLING
if (fancy_resampling) {
int i;
int i;
pthread_mutex_lock(&vol_mutex);
for (i=0; i<2*FRAME_BYTES; i++) {
frame[i] = (float)inbuf[i] / 32768.0;
frame[i] *= volume;
}
pthread_mutex_unlock(&vol_mutex);
srcdat.src_ratio = bf_playback_rate;
src_process(src, &srcdat);
assert(srcdat.input_frames_used == FRAME_BYTES);
@@ -787,18 +810,18 @@ void *audio_thread_func(void *arg) {
#define NUM_CHANNELS 2
void handle_broken_fifo() {
static void handle_broken_fifo() {
close(pipe_handle);
pipe_handle = -1;
}
void init_pipe(char* pipe) {
static void init_pipe(const char* pipe) {
// make the FIFO and catch the broken pipe signal
mknod(pipe, S_IFIFO | 0644, 0);
signal(SIGPIPE, handle_broken_fifo);
}
void* init_ao() {
static void* init_ao(void) {
ao_initialize();
int driver;
@@ -815,12 +838,12 @@ void* init_ao() {
ao_sample_format fmt;
memset(&fmt, 0, sizeof(fmt));
fmt.bits = 16;
fmt.rate = sampling_rate;
fmt.channels = NUM_CHANNELS;
fmt.byte_format = AO_FMT_NATIVE;
ao_option *ao_opts = NULL;
if(libao_deviceid) {
ao_append_option(&ao_opts, "id", libao_deviceid);
@@ -839,8 +862,8 @@ void* init_ao() {
return dev;
}
int init_output(void) {
void* arg = 0;
static int init_output(void) {
void* arg = 0;
if (pipename) {
init_pipe(pipename);
+3 -2
View File
@@ -1,7 +1,8 @@
#ifndef _HAIRTUNES_H_
#define _HAIRTUNES_H_
int hairtunes_init(char *pAeskey, char *pAesiv, char *pFmtpstr, int pCtrlPort, int pTimingPort,
int pDataPort, char *pRtpHost, char*pPipeName, char *pLibaoDriver, char *pLibaoDeviceName, char *pLibaoDeviceId);
int hairtunes_init(char *pAeskey, char *pAesiv, char *fmtpstr, int pCtrlPort, int pTimingPort,
int pDataPort, char *pRtpHost, char*pPipeName, char *pLibaoDriver, char *pLibaoDeviceName, char *pLibaoDeviceId,
int bufStartFill);
// default buffer size
// needs to be a power of 2 because of the way BUFIDX(seqno) works
+70 -45
View File
@@ -40,7 +40,7 @@
// TEMP
int kCurrentLogLevel = LOG_INFO;
extern int buffer_start_fill;
int bufferStartFill = -1;
#ifdef _WIN32
#define DEVNULL "nul"
@@ -52,7 +52,37 @@ extern int buffer_start_fill;
#define HEADER_LOG_LEVEL LOG_DEBUG
#define AVAHI_LOG_LEVEL LOG_DEBUG
void handle_sigchld(int signo) {
static void handleClient(int pSock, char *pPassword, char *pHWADDR);
static void writeDataToClient(int pSock, struct shairbuffer *pResponse);
static int readDataFromClient(int pSock, struct shairbuffer *pClientBuffer);
static int parseMessage(struct connection *pConn,unsigned char *pIpBin, unsigned int pIpBinLen, char *pHWADDR);
static void propogateCSeq(struct connection *pConn);
static void cleanupBuffers(struct connection *pConnection);
static void cleanup(struct connection *pConnection);
static int startAvahi(const char *pHwAddr, const char *pServerName, int pPort);
static int getAvailChars(struct shairbuffer *pBuf);
static void addToShairBuffer(struct shairbuffer *pBuf, char *pNewBuf);
static void addNToShairBuffer(struct shairbuffer *pBuf, char *pNewBuf, int pNofNewBuf);
static char *getTrimmedMalloc(char *pChar, int pSize, int pEndStr, int pAddNL);
static char *getTrimmed(char *pChar, int pSize, int pEndStr, int pAddNL, char *pTrimDest);
static void slog(int pLevel, char *pFormat, ...);
static int isLogEnabledFor(int pLevel);
static void initConnection(struct connection *pConn, struct keyring *pKeys, struct comms *pComms, int pSocket, char *pPassword);
static void closePipe(int *pPipe);
static void initBuffer(struct shairbuffer *pBuf, int pNumChars);
static void setKeys(struct keyring *pKeys, char *pIV, char* pAESKey, char *pFmtp);
static RSA *loadKey(void);
static void handle_sigchld(int signo) {
int status;
waitpid(-1, &status, WNOHANG);
}
@@ -113,12 +143,12 @@ int main(int argc, char **argv)
}
else if(!strcmp(arg, "-b"))
{
buffer_start_fill = atoi(*++argv);
bufferStartFill = atoi(*++argv);
argc--;
}
else if(!strncmp(arg, "--buffer=", 9))
{
buffer_start_fill = atoi(arg + 9);
bufferStartFill = atoi(arg + 9);
}
else if(!strcmp(arg, "-k"))
{
@@ -161,7 +191,7 @@ int main(int argc, char **argv)
}
}
if ( buffer_start_fill < 30 || buffer_start_fill > BUFFER_FRAMES ) {
if ( bufferStartFill < 30 || bufferStartFill > BUFFER_FRAMES ) {
fprintf(stderr, "buffer value must be > 30 and < %d\n", BUFFER_FRAMES);
return(0);
}
@@ -275,7 +305,7 @@ int main(int argc, char **argv)
return 0;
}
int findEnd(char *tReadBuf)
static int findEnd(char *tReadBuf)
{
// find \n\n, \r\n\r\n, or \r\r is found
int tIdx = 0;
@@ -313,7 +343,7 @@ int findEnd(char *tReadBuf)
return -1;
}
void handleClient(int pSock, char *pPassword, char *pHWADDR)
static void handleClient(int pSock, char *pPassword, char *pHWADDR)
{
slog(LOG_DEBUG_VV, "In Handle Client\n");
fflush(stdout);
@@ -346,13 +376,13 @@ void handleClient(int pSock, char *pPassword, char *pHWADDR)
port = ntohs(s->sin6_port);
inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr);
union {
struct sockaddr_in6 s;
unsigned char bin[sizeof(struct sockaddr_in6)];
} addr;
memcpy(&addr.s, &s->sin6_addr, sizeof(struct sockaddr_in6));
if(memcmp(&addr.bin[0], "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\xff\xff", 12) == 0)
union {
struct sockaddr_in6 s;
unsigned char bin[sizeof(struct sockaddr_in6)];
} addr;
memcpy(&addr.s, &s->sin6_addr, sizeof(struct sockaddr_in6));
if(memcmp(&addr.bin[0], "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\xff\xff", 12) == 0)
{
// its ipv4...
memcpy(ipbin, &addr.bin[12], 4);
@@ -421,15 +451,14 @@ void handleClient(int pSock, char *pPassword, char *pHWADDR)
fflush(stdout);
}
void writeDataToClient(int pSock, struct shairbuffer *pResponse)
static void writeDataToClient(int pSock, struct shairbuffer *pResponse)
{
slog(LOG_DEBUG_VV, "\n----Beg Send Response Header----\n%.*s\n", pResponse->current, pResponse->data);
send(pSock, pResponse->data, pResponse->current,0);
slog(LOG_DEBUG_VV, "----Send Response Header----\n");
}
int readDataFromClient(int pSock, struct shairbuffer *pClientBuffer)
static int readDataFromClient(int pSock, struct shairbuffer *pClientBuffer)
{
char tReadBuf[MAX_SIZE];
tReadBuf[0] = '\0';
@@ -481,7 +510,7 @@ int readDataFromClient(int pSock, struct shairbuffer *pClientBuffer)
return 0;
}
char *getFromBuffer(char *pBufferPtr, const char *pField, int pLenAfterField, int *pReturnSize, char *pDelims)
static char *getFromBuffer(char *pBufferPtr, const char *pField, int pLenAfterField, int *pReturnSize, char *pDelims)
{
slog(LOG_DEBUG_V, "GettingFromBuffer: %s\n", pField);
char* tFound = strstr(pBufferPtr, pField);
@@ -517,25 +546,25 @@ char *getFromBuffer(char *pBufferPtr, const char *pField, int pLenAfterField, in
return tFound;
}
char *getFromHeader(char *pHeaderPtr, const char *pField, int *pReturnSize)
static char *getFromHeader(char *pHeaderPtr, const char *pField, int *pReturnSize)
{
return getFromBuffer(pHeaderPtr, pField, 2, pReturnSize, "\r\n");
}
char *getFromContent(char *pContentPtr, const char* pField, int *pReturnSize)
static char *getFromContent(char *pContentPtr, const char* pField, int *pReturnSize)
{
return getFromBuffer(pContentPtr, pField, 1, pReturnSize, "\r\n");
}
char *getFromSetup(char *pContentPtr, const char* pField, int *pReturnSize)
static char *getFromSetup(char *pContentPtr, const char* pField, int *pReturnSize)
{
return getFromBuffer(pContentPtr, pField, 1, pReturnSize, ";\r\n");
}
// Handles compiling the Apple-Challenge, HWID, and Server IP Address
// Into the response the airplay client is expecting.
int buildAppleResponse(struct connection *pConn, unsigned char *pIpBin, unsigned int pIpBinLen, char *pHWID)
static int buildAppleResponse(struct connection *pConn, unsigned char *pIpBin,
unsigned int pIpBinLen, char *pHWID)
{
// Find Apple-Challenge
char *tResponse = NULL;
@@ -604,7 +633,7 @@ int buildAppleResponse(struct connection *pConn, unsigned char *pIpBin, unsigned
}
//parseMessage(tConn->recv.data, tConn->recv.mark, &tConn->resp, ipstr, pHWADDR, tConn->keys);
int parseMessage(struct connection *pConn, unsigned char *pIpBin, unsigned int pIpBinLen, char *pHWID)
static int parseMessage(struct connection *pConn, unsigned char *pIpBin, unsigned int pIpBinLen, char *pHWID)
{
int tReturn = 0; // 0 = good, 1 = Needs More Data, -1 = close client socket.
if(pConn->resp.data == NULL)
@@ -774,7 +803,8 @@ int parseMessage(struct connection *pConn, unsigned char *pIpBin, unsigned int p
}
cleanupBuffers(pConn);
hairtunes_init(tKeys->aeskey, tKeys->aesiv, tKeys->fmt, tControlport, tTimingport,
tDataport, tRtp, tPipe, tAoDriver, tAoDeviceName, tAoDeviceId);
tDataport, tRtp, tPipe, tAoDriver, tAoDeviceName, tAoDeviceId,
bufferStartFill);
// Quit when finished.
slog(LOG_DEBUG, "Returned from hairtunes init....returning -1, should close out this whole side of the fork\n");
@@ -859,7 +889,7 @@ int parseMessage(struct connection *pConn, unsigned char *pIpBin, unsigned int p
}
// Copies CSeq value from request, and adds standard header values in.
void propogateCSeq(struct connection *pConn) //char *pRecvBuffer, struct shairbuffer *pConn->recp.data)
static void propogateCSeq(struct connection *pConn) //char *pRecvBuffer, struct shairbuffer *pConn->recp.data)
{
int tSize=0;
char *tRecPtr = getFromHeader(pConn->recv.data, "CSeq", &tSize);
@@ -883,7 +913,7 @@ void cleanupBuffers(struct connection *pConn)
}
}
void cleanup(struct connection *pConn)
static void cleanup(struct connection *pConn)
{
cleanupBuffers(pConn);
if(pConn->hairtunes != NULL)
@@ -917,7 +947,7 @@ void cleanup(struct connection *pConn)
}
}
int startAvahi(const char *pHWStr, const char *pServerName, int pPort)
static int startAvahi(const char *pHWStr, const char *pServerName, int pPort)
{
int tMaxServerName = 25; // Something reasonable? iPad showed 21, iphone 25
int tPid = fork();
@@ -959,22 +989,17 @@ int startAvahi(const char *pHWStr, const char *pServerName, int pPort)
return tPid;
}
void printBufferInfo(struct shairbuffer *pBuf, int pLevel)
{
slog(pLevel, "Buffer: [%s] size: %d maxchars:%d\n", pBuf->data, pBuf->current, pBuf->maxsize/sizeof(char));
}
int getAvailChars(struct shairbuffer *pBuf)
static int getAvailChars(struct shairbuffer *pBuf)
{
return (pBuf->maxsize / sizeof(char)) - pBuf->current;
}
void addToShairBuffer(struct shairbuffer *pBuf, char *pNewBuf)
static void addToShairBuffer(struct shairbuffer *pBuf, char *pNewBuf)
{
addNToShairBuffer(pBuf, pNewBuf, strlen(pNewBuf));
}
void addNToShairBuffer(struct shairbuffer *pBuf, char *pNewBuf, int pNofNewBuf)
static void addNToShairBuffer(struct shairbuffer *pBuf, char *pNewBuf, int pNofNewBuf)
{
int tAvailChars = getAvailChars(pBuf);
if(pNofNewBuf > tAvailChars)
@@ -998,7 +1023,7 @@ void addNToShairBuffer(struct shairbuffer *pBuf, char *pNewBuf, int pNofNewBuf)
}
}
char *getTrimmedMalloc(char *pChar, int pSize, int pEndStr, int pAddNL)
static char *getTrimmedMalloc(char *pChar, int pSize, int pEndStr, int pAddNL)
{
int tAdditionalSize = 0;
if(pEndStr)
@@ -1010,7 +1035,7 @@ char *getTrimmedMalloc(char *pChar, int pSize, int pEndStr, int pAddNL)
}
// Must free returned ptr
char *getTrimmed(char *pChar, int pSize, int pEndStr, int pAddNL, char *pTrimDest)
static char *getTrimmed(char *pChar, int pSize, int pEndStr, int pAddNL, char *pTrimDest)
{
int tSize = pSize;
if(pEndStr)
@@ -1035,7 +1060,7 @@ char *getTrimmed(char *pChar, int pSize, int pEndStr, int pAddNL, char *pTrimDes
return pTrimDest;
}
void slog(int pLevel, char *pFormat, ...)
static void slog(int pLevel, char *pFormat, ...)
{
#ifdef SHAIRPORT_LOG
if(isLogEnabledFor(pLevel))
@@ -1048,7 +1073,7 @@ void slog(int pLevel, char *pFormat, ...)
#endif
}
int isLogEnabledFor(int pLevel)
static int isLogEnabledFor(int pLevel)
{
if(pLevel <= kCurrentLogLevel)
{
@@ -1057,7 +1082,7 @@ int isLogEnabledFor(int pLevel)
return FALSE;
}
void initConnection(struct connection *pConn, struct keyring *pKeys,
static void initConnection(struct connection *pConn, struct keyring *pKeys,
struct comms *pComms, int pSocket, char *pPassword)
{
pConn->hairtunes = pComms;
@@ -1081,7 +1106,7 @@ void initConnection(struct connection *pConn, struct keyring *pKeys,
}
}
void closePipe(int *pPipe)
static void closePipe(int *pPipe)
{
if(*pPipe != -1)
{
@@ -1090,7 +1115,7 @@ void closePipe(int *pPipe)
}
}
void initBuffer(struct shairbuffer *pBuf, int pNumChars)
static void initBuffer(struct shairbuffer *pBuf, int pNumChars)
{
if(pBuf->data != NULL)
{
@@ -1105,7 +1130,7 @@ void initBuffer(struct shairbuffer *pBuf, int pNumChars)
memset(pBuf->data, 0, pBuf->maxsize);
}
void setKeys(struct keyring *pKeys, char *pIV, char* pAESKey, char *pFmtp)
static void setKeys(struct keyring *pKeys, char *pIV, char* pAESKey, char *pFmtp)
{
if(pKeys->aesiv != NULL)
{
@@ -1149,7 +1174,7 @@ void setKeys(struct keyring *pKeys, char *pIV, char* pAESKey, char *pFmtp)
"2gG0N5hvJpzwwhbhXqFKA4zaaSrw622wDniAK5MlIE0tIAKKP4yxNGjoD2QYjhBGuhvkWKY=\n" \
"-----END RSA PRIVATE KEY-----"
RSA *loadKey()
static RSA *loadKey(void)
{
BIO *tBio = BIO_new_mem_buf(AIRPORT_PRIVATE_KEY, -1);
RSA *rsa = PEM_read_bio_RSAPrivateKey(tBio, NULL, NULL, NULL); //NULL, NULL, NULL);
-27
View File
@@ -52,33 +52,6 @@ struct connection
char *password;
};
RSA *loadKey();
int startAvahi(const char *pHwAddr, const char *pServerName, int pPort);
void cleanupBuffers(struct connection *pConnection);
void cleanup(struct connection *pConnection);
void handleClient(int pSock, char *pPassword, char *pHWADDR);
int getAvailChars(struct shairbuffer *pBuf);
char *getTrimmedMalloc(char *pChar, int pSize, int pEndStr, int pAddNL);
char *getTrimmed(char *pChar, int pSize, int pEndStr, int pAddNL, char *pTrimDest);
void initBuffer(struct shairbuffer *pBuf, int pNumChars);
void printBufferInfo(struct shairbuffer *pBuf, int pLevel);
void addToShairBuffer(struct shairbuffer *pBuf, char *pNewBuf);
void addNToShairBuffer(struct shairbuffer *pBuf, char *pNewBuf, int pNofNewBuf);
int readDataFromClient(int pSock, struct shairbuffer *pClientBuffer);
int parseMessage(struct connection *pConn,unsigned char *pIpBin, unsigned int pIpBinLen, char *pHWADDR);
void closePipe(int *pPipe);
void setKeys(struct keyring *pKeys, char *pIV, char* pAESKey, char *pFmtp);
void initConnection(struct connection *pConn, struct keyring *pKeys,
struct comms *pComms, int pSocket, char *pPassword);
void writeDataToClient(int pSock, struct shairbuffer *pResponse);
void propogateCSeq(struct connection *pConn);
int buildAppleResponse(struct connection *pConn, unsigned char *pIpBin, unsigned int pIpBinLen, char *pHwAddr);
void sim(int pLevel, char *pValue1, char *pValue2);
void slog(int pLevel, char *pFormat, ...);
int isLogEnabledFor(int pLevel);
#endif
+2 -2
View File
@@ -183,7 +183,7 @@ void delay(long pMillisecs, struct timeval *pRes)
select(0,NULL,NULL,NULL,pRes);
}
int getCorrectedEncodeSize(int pSize)
static int getCorrectedEncodeSize(int pSize)
{
if(pSize % 4 == 0)
{
@@ -264,7 +264,7 @@ char *encode_base64(unsigned char *input, int length)
b64 = BIO_push(b64, bmem);
BIO_write(b64, input, length);
BIO_flush(b64);
(void)BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
char *buff = (char *)malloc(bptr->length);