Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Feb 2013 04:45:10 +0000 (UTC)
From:      Martin Wilke <miwi@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r312476 - in head/audio: . libshairport libshairport/files
Message-ID:  <201302180445.r1I4jA6M018618@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: miwi
Date: Mon Feb 18 04:45:09 2013
New Revision: 312476
URL: http://svnweb.freebsd.org/changeset/ports/312476

Log:
  libshairport
  ============
  Created by Team XBMC
  
  This is a fork of ShairPort written by James Laird <jhl@mafipulation.org>. The
  XBMC team decided to fork ShairPort and make it into a library.
  
  What it is
  ----------
  This program emulates an AirPort Express for the purpose of streaming music from
  iTunes and compatible iPods. It implements a server for the Apple RAOP protocol.
  ShairPort does not support AirPlay v2 (video and photo streaming).
  
  It supports multiple simultaneous streams, if your audio output chain (as
  detected by libao) does so.
  
  WWW: https://github.com/amejia1/libshairport
  
  PR:		ports/172775
  Submitted by:	Manuel Creach <manuel.creach@icloud.com>

Added:
  head/audio/libshairport/
  head/audio/libshairport/Makefile   (contents, props changed)
  head/audio/libshairport/distinfo   (contents, props changed)
  head/audio/libshairport/files/
  head/audio/libshairport/files/patch-configure.in   (contents, props changed)
  head/audio/libshairport/files/patch-src-Makefile.am   (contents, props changed)
  head/audio/libshairport/files/patch-src-alac.c   (contents, props changed)
  head/audio/libshairport/files/patch-src-ao.h   (contents, props changed)
  head/audio/libshairport/files/patch-src-hairtunes.c   (contents, props changed)
  head/audio/libshairport/files/patch-src-hairtunes.h   (contents, props changed)
  head/audio/libshairport/files/patch-src-shairport.c   (contents, props changed)
  head/audio/libshairport/files/patch-src-shairport.h   (contents, props changed)
  head/audio/libshairport/files/patch-src-socketlib.c   (contents, props changed)
  head/audio/libshairport/pkg-descr   (contents, props changed)
  head/audio/libshairport/pkg-plist   (contents, props changed)
Modified:
  head/audio/Makefile

Modified: head/audio/Makefile
==============================================================================
--- head/audio/Makefile	Mon Feb 18 04:44:29 2013	(r312475)
+++ head/audio/Makefile	Mon Feb 18 04:45:09 2013	(r312476)
@@ -396,6 +396,7 @@
     SUBDIR += liboggz
     SUBDIR += libopenspc
     SUBDIR += libsamplerate
+    SUBDIR += libshairport
     SUBDIR += libshout
     SUBDIR += libshout2
     SUBDIR += libsidplay

Added: head/audio/libshairport/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/audio/libshairport/Makefile	Mon Feb 18 04:45:09 2013	(r312476)
@@ -0,0 +1,23 @@
+# Created by: Manuel Creach <manuel.creach@icloud.com>
+# $FreeBSD$
+
+PORTNAME=	libshairport
+PORTVERSION=	1.2.0.20310
+CATEGORIES=	audio
+MASTER_SITES=	http://mirrors.xbmc.org/build-deps/darwin-libs/
+DISTNAME=	libshairport-${PORTVERSION}_lib
+
+MAINTAINER=	manuel.creach@icloud.com
+COMMENT=	An Airport Extreme Emulator
+
+FETCH_ARGS=	-pRr
+USE_GMAKE=	yes
+USE_AUTOTOOLS=	aclocal autoheader automake autoconf libtoolize
+ACLOCAL_ARGS=	-I.
+AUTOMAKE_ARGS=	--add-missing
+USE_LDCONFIG=	yes
+
+CPPFLAGS+=	-isystem${LOCALBASE}/include
+LDFLAGS+=	-L${LOCALBASE}/lib
+
+.include <bsd.port.mk>

Added: head/audio/libshairport/distinfo
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/audio/libshairport/distinfo	Mon Feb 18 04:45:09 2013	(r312476)
@@ -0,0 +1,2 @@
+SHA256 (libshairport-1.2.0.20310_lib.tar.gz) = 61602402d846a50e8ddf82c3fb5b81984de95ed56abfe0f1e22426d1901c564f
+SIZE (libshairport-1.2.0.20310_lib.tar.gz) = 32759

Added: head/audio/libshairport/files/patch-configure.in
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/audio/libshairport/files/patch-configure.in	Mon Feb 18 04:45:09 2013	(r312476)
@@ -0,0 +1,20 @@
+--- configure.in.orig	2011-09-23 22:56:46.000000000 +0200
++++ configure.in	2012-10-09 12:09:33.000000000 +0200
+@@ -11,8 +11,9 @@
+ 
+ # Checks for libraries.
+ #AC_CHECK_LIB([c],   [main])
+-#AC_CHECK_LIB([m],   [main])
++AC_CHECK_LIB([m],   [main])
+ AC_CHECK_LIB([ssl], [main],, AC_MSG_ERROR($missing_library))
++AC_CHECK_LIB([crypto], [main],, AC_MSG_ERROR($missing_library))
+ AC_CHECK_LIB([pthread], [main],, AC_MSG_ERROR($missing_library))
+ 
+ OUTPUT_FILES="Makefile"
+@@ -21,4 +22,4 @@
+ 
+ AC_CONFIG_FILES([${OUTPUT_FILES}])
+ AC_OUTPUT(Makefile src/Makefile)
+-AC_OUTPUT
+\ No newline at end of file
++AC_OUTPUT

Added: head/audio/libshairport/files/patch-src-Makefile.am
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/audio/libshairport/files/patch-src-Makefile.am	Mon Feb 18 04:45:09 2013	(r312476)
@@ -0,0 +1,12 @@
+--- src/Makefile.am.orig	2011-09-23 23:14:39.000000000 +0200
++++ src/Makefile.am	2012-10-09 12:09:33.000000000 +0200
+@@ -1,7 +1,7 @@
+ lib_LTLIBRARIES=libshairport.la
+ 
+-library_includedir=$(includedir)
+-library_include_HEADERS = shairport.h
++library_includedir=$(includedir)/shairport
++library_include_HEADERS = shairport.h ao.h socketlib.h
+ 
+ libshairport_la_SOURCES=shairport.c hairtunes.c socketlib.c alac.c
+ libshairport_la_LDFLAGS=-dynamiclib

Added: head/audio/libshairport/files/patch-src-alac.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/audio/libshairport/files/patch-src-alac.c	Mon Feb 18 04:45:09 2013	(r312476)
@@ -0,0 +1,47 @@
+--- src/alac.c.orig	2011-08-21 00:06:21.000000000 +0200
++++ src/alac.c	2012-10-09 12:09:33.000000000 +0200
+@@ -804,7 +804,7 @@
+             }
+             else
+             {
+-                fprintf(stderr, "FIXME: unhandled predicition type: %i\n", prediction_type);
++                xprintf("FIXME: unhandled predicition type: %i\n", prediction_type);
+                 /* i think the only other prediction type (or perhaps this is just a
+                  * boolean?) runs adaptive fir twice.. like:
+                  * predictor_decompress_fir_adapt(predictor_error, tempout, ...)
+@@ -885,7 +885,7 @@
+         }
+         case 20:
+         case 32:
+-            fprintf(stderr, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size);
++            xprintf("FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size);
+             break;
+         default:
+             break;
+@@ -1004,7 +1004,7 @@
+             }
+             else
+             { /* see mono case */
+-                fprintf(stderr, "FIXME: unhandled predicition type: %i\n", prediction_type_a);
++                xprintf("FIXME: unhandled predicition type: %i\n", prediction_type_a);
+             }
+ 
+             /* channel 2 */
+@@ -1029,7 +1029,7 @@
+             }
+             else
+             {
+-                fprintf(stderr, "FIXME: unhandled predicition type: %i\n", prediction_type_b);
++                xprintf("FIXME: unhandled predicition type: %i\n", prediction_type_b);
+             }
+         }
+         else
+@@ -1106,7 +1106,7 @@
+         }
+         case 20:
+         case 32:
+-            fprintf(stderr, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size);
++            xprintf("FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size);
+             break;
+         default:
+             break;

Added: head/audio/libshairport/files/patch-src-ao.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/audio/libshairport/files/patch-src-ao.h	Mon Feb 18 04:45:09 2013	(r312476)
@@ -0,0 +1,161 @@
+--- src/ao.h.orig	2012-10-09 12:33:01.000000000 +0200
++++ src/ao.h	2012-10-09 12:09:33.000000000 +0200
+@@ -0,0 +1,158 @@
++/*
++ *
++ *  ao.h 
++ *
++ *  Original Copyright (C) Aaron Holtzman - May 1999
++ *      Modifications Copyright (C) Stan Seibert - July 2000, July 2001
++ *      More Modifications Copyright (C) Jack Moffitt - October 2000
++ *
++ *  This file is part of libao, a cross-platform audio outputlibrary.  See
++ *  README for a history of this source code.
++ *
++ *  libao is free software; you can redistribute it and/or modify
++ *  it under the terms of the GNU General Public License as published by
++ *  the Free Software Foundation; either version 2, or (at your option)
++ *  any later version.
++ *
++ *  libao is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *  GNU General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with GNU Make; see the file COPYING.  If not, write to
++ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ */
++#ifndef __AO_H__
++#define __AO_H__
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif /* __cplusplus */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <stdint.h>
++#include <errno.h>
++
++/* --- Constants ---*/
++
++#define AO_TYPE_LIVE 1
++#define AO_TYPE_FILE 2
++
++
++#define AO_ENODRIVER   1
++#define AO_ENOTFILE    2
++#define AO_ENOTLIVE    3
++#define AO_EBADOPTION  4
++#define AO_EOPENDEVICE 5
++#define AO_EOPENFILE   6
++#define AO_EFILEEXISTS 7
++#define AO_EBADFORMAT  8
++
++#define AO_EFAIL       100
++
++
++#define AO_FMT_LITTLE 1
++#define AO_FMT_BIG    2
++#define AO_FMT_NATIVE 4
++
++/* --- Structures --- */
++
++typedef struct ao_info {
++  int  type; /* live output or file output? */
++  char *name; /* full name of driver */
++  char *short_name; /* short name of driver */
++        char *author; /* driver author */
++  char *comment; /* driver comment */
++  int  preferred_byte_format;
++  int  priority;
++  char **options;
++  int  option_count;
++} ao_info;
++
++typedef struct ao_functions ao_functions;
++typedef struct ao_device ao_device;
++
++typedef struct ao_sample_format {
++  int  bits; /* bits per sample */
++  int  rate; /* samples per second (in a single channel) */
++  int  channels; /* number of audio channels */
++  int  byte_format; /* Byte ordering in sample, see constants below */
++        char *matrix; /* input channel location/ordering */
++} ao_sample_format;
++
++typedef struct ao_option {
++  char *key;
++  char *value;
++  struct ao_option *next;
++} ao_option;
++
++#if defined(AO_BUILDING_LIBAO)
++#include "ao_private.h"
++#endif
++
++/* --- Functions --- */
++
++/* library setup/teardown */
++void ao_initialize(void);
++void ao_shutdown(void);
++
++/* device setup/playback/teardown */
++int   ao_append_global_option(const char *key,
++                              const char *value);
++int          ao_append_option(ao_option **options,
++                              const char *key,
++                              const char *value);
++void          ao_free_options(ao_option *options);
++
++char* ao_get_option(ao_option *options, const char* key);
++
++ao_device*       ao_open_live(int driver_id,
++                              ao_sample_format *format,
++                              ao_option *option);
++ao_device*       ao_open_file(int driver_id,
++                              const char *filename,
++                              int overwrite,
++                              ao_sample_format *format,
++                              ao_option *option);
++
++int                   ao_play(ao_device *device,
++                              char *output_samples,
++                              uint32_t num_bytes);
++int                  ao_close(ao_device *device);
++
++/* driver information */
++int              ao_driver_id(const char *short_name);
++int      ao_default_driver_id(void);
++ao_info       *ao_driver_info(int driver_id);
++ao_info **ao_driver_info_list(int *driver_count);
++char       *ao_file_extension(int driver_id);
++
++/* miscellaneous */
++int          ao_is_big_endian(void);
++
++
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif  /* __AO_H__ */
++
++extern struct AudioOutput g_ao;
++struct AudioOutput                                                                                                                                                                                              
++  {                                                                                                                                                                                                              
++      void (*ao_initialize)(void);                                                                                                                                                                               
++      int (*ao_play)(ao_device *, char *, uint32_t);                                                                                                                                                             
++      int (*ao_default_driver_id)(void);                                                                                                                                                                         
++      ao_device* (*ao_open_live)( int, ao_sample_format *, ao_option *);                                                                                                                                         
++      int (*ao_close)(ao_device *);                                                                                                                                                                              
++      /* -- Device Setup/Playback/Teardown -- */                                                                                                                                                                 
++      int (*ao_append_option)(ao_option **, const char *, const char *);                                                                                                                                         
++      void (*ao_free_options)(ao_option *);                                                                                                                                                                      
++      char* (*ao_get_option)(ao_option *, const char* );
++      void (*ao_set_metadata)(const char *buffer, unsigned int size);                                                                                                                                                         
++      void (*ao_set_metadata_coverart)(const char *buffer, unsigned int size);
++  }; 

Added: head/audio/libshairport/files/patch-src-hairtunes.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/audio/libshairport/files/patch-src-hairtunes.c	Mon Feb 18 04:45:09 2013	(r312476)
@@ -0,0 +1,233 @@
+--- src/hairtunes.c.orig	2011-09-23 21:55:48.000000000 +0200
++++ src/hairtunes.c	2012-10-09 12:09:33.000000000 +0200
+@@ -25,7 +25,7 @@
+  */
+ 
+ #define XBMC
+-//#defined HAS_AO
++#define HAS_AO
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+@@ -45,7 +45,7 @@
+ #include <sys/signal.h>
+ #include <fcntl.h>
+ #ifdef HAS_AO
+-#include <ao/ao.h>
++#include "ao.h"
+ #endif
+ 
+ #ifdef FANCY_RESAMPLING
+@@ -89,7 +89,6 @@
+ // maximal resampling shift - conservative
+ #define OUTFRAME_BYTES (4*(frame_size+3))
+ 
+-
+ alac_file *decoder_info;
+ 
+ #ifdef FANCY_RESAMPLING
+@@ -122,8 +121,8 @@
+ pthread_cond_t ab_buffer_ready;
+ 
+ static void die(char *why) {
+-    fprintf(stderr, "FATAL: %s\n", why);
+-    exit(1);
++    xprintf("FATAL: %s\n", why);
++    //exit(1);
+ }
+ 
+ static int hex2bin(unsigned char *buf, char *hex) {
+@@ -246,13 +245,13 @@
+             continue;
+         }
+         if (!strcmp(line, "exit\n")) {
+-            exit(0);
++            ;//exit(0);
+         }
+         if (!strcmp(line, "flush\n")) {
+             hairtunes_flush();
+         }
+     }
+-    fprintf(stderr, "bye!\n");
++    xprintf("bye!\n");
+     fflush(stderr);
+ #endif
+ 
+@@ -263,18 +262,28 @@
+ {
+   assert(f<=0);
+   if (debug)
+-      fprintf(stderr, "VOL: %lf\n", f);
++      xprintf("VOL: %lf\n", f);
+   volume = pow(10.0,0.05*f);
+   fix_volume = 65536.0 * volume;
+ }
+ 
++void hairtunes_set_metadata(const char *buffer, unsigned int size)
++{
++  g_ao.ao_set_metadata(buffer, size);
++}
++
++void hairtunes_set_metadata_coverart(const char *buffer, unsigned int size)
++{
++  g_ao.ao_set_metadata_coverart(buffer, size);
++}
++
+ void hairtunes_flush(void)
+ {
+   pthread_mutex_lock(&ab_mutex);
+   ab_resync();
+   pthread_mutex_unlock(&ab_mutex);
+   if (debug)
+-      fprintf(stderr, "FLUSH\n");
++      xprintf("FLUSH\n");
+ }
+ 
+ #ifdef HAIRTUNES_STANDALONE
+@@ -424,7 +433,7 @@
+     } else if (seq_order(ab_read, seqno)) {     // late but not yet played
+         abuf = audio_buffer + BUFIDX(seqno);
+     } else {    // too late.
+-        fprintf(stderr, "\nlate packet %04X (%04X:%04X)\n", seqno, ab_read, ab_write);
++        xprintf("\nlate packet %04X (%04X:%04X)\n", seqno, ab_read, ab_write);
+     }
+     buf_fill = ab_write - ab_read;
+     pthread_mutex_unlock(&ab_mutex);
+@@ -521,7 +530,7 @@
+     if (seq_order(last, first))
+         return;
+ 
+-    fprintf(stderr, "requesting resend on %d packets (port %d)\n", last-first+1, controlport);
++    xprintf("requesting resend on %d packets (port %d)\n", last-first+1, controlport);
+ 
+     char req[8];    // *not* a standard RTCP NACK
+     req[0] = 0x80;
+@@ -605,8 +614,8 @@
+         port += 3;
+     }
+ 
+-    printf("port: %d\n", port); // let our handler know where we end up listening
+-    printf("cport: %d\n", port+1);
++    xprintf("port: %d\n", port); // let our handler know where we end up listening
++    xprintf("cport: %d\n", port+1);
+ 
+     rtp_sockets[0] = sock;
+     rtp_sockets[1] = csock;
+@@ -709,7 +718,7 @@
+     bf_est_drift = biquad_filt(&bf_drift_lpf, CONTROL_B*(bf_est_err*CONTROL_A + 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);
++        xprintf("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;
+ 
+     bf_last_err = bf_est_err;
+@@ -725,7 +734,7 @@
+     buf_fill = ab_write - ab_read;
+     if (buf_fill < 1 || !ab_synced || ab_buffering) {    // init or underrun. stop and wait
+         if (ab_synced)
+-          fprintf(stderr, "\nunderrun\n");
++          xprintf("\nunderrun\n");
+ 
+         ab_buffering = 1;
+         pthread_cond_wait(&ab_buffer_ready, &ab_mutex);
+@@ -737,7 +746,7 @@
+         return 0;
+     }
+     if (buf_fill >= BUFFER_FRAMES) {   // overrunning! uh-oh. restart at a sane distance
+-        fprintf(stderr, "\noverrun.\n");
++        xprintf("\noverrun.\n");
+         ab_read = ab_write - START_FILL;
+     }
+     read = ab_read;
+@@ -749,7 +758,7 @@
+ 
+     volatile abuf_t *curframe = audio_buffer + BUFIDX(read);
+     if (!curframe->ready) {
+-        fprintf(stderr, "\nmissing frame.\n");
++        xprintf("\nmissing frame.\n");
+         memset(curframe->data, 0, FRAME_BYTES);
+     }
+     curframe->ready = 0;
+@@ -776,13 +785,13 @@
+     if (stuff) {
+         if (stuff==1) {
+             if (debug)
+-                fprintf(stderr, "+++++++++\n");
++                xprintf("+++++++++\n");
+             // interpolate one sample
+             *outptr++ = dithered_vol(((long)inptr[-2] + (long)inptr[0]) >> 1);
+             *outptr++ = dithered_vol(((long)inptr[-1] + (long)inptr[1]) >> 1);
+         } else if (stuff==-1) {
+             if (debug)
+-                fprintf(stderr, "---------\n");
++                xprintf("---------\n");
+             inptr++;
+             inptr++;
+         }
+@@ -849,6 +858,11 @@
+             inbuf = buffer_get_frame();
+         } while (!inbuf && audio_running);
+ 
++        if(!audio_running)
++        {
++          return 0; //don't access inbuf if audio stopped
++        }
++
+ #ifdef FANCY_RESAMPLING
+         if (fancy_resampling) {
+ 	        int i;
+@@ -881,7 +895,7 @@
+             }
+ #ifdef HAS_AO
+         } else {
+-            ao_play(dev, (char *)outbuf, play_samples*4);
++            g_ao.ao_play(dev, (char *)outbuf, play_samples*4);
+ #endif
+         }
+     }
+@@ -906,7 +920,7 @@
+ ao_device *dev;
+ 
+ void* init_ao() {
+-    ao_initialize();
++    g_ao.ao_initialize();
+ 
+     int driver;
+ #ifndef XBMC
+@@ -921,7 +935,7 @@
+ #endif
+     {
+         // otherwise choose the default
+-        driver = ao_default_driver_id();
++        driver = g_ao.ao_default_driver_id();
+     }
+ 
+     ao_sample_format fmt;
+@@ -944,9 +958,9 @@
+     }
+ #endif
+ 
+-    ao_append_option(&ao_opts, "name", "Streaming...");
++    g_ao.ao_append_option(&ao_opts, "name", "Streaming...");
+ 
+-    dev = ao_open_live(driver, &fmt, ao_opts);
++    dev = g_ao.ao_open_live(driver, &fmt, ao_opts);
+     if (dev == NULL) {
+         die("Could not open ao device");
+     }
+@@ -985,12 +999,13 @@
+   audio_running = 0;
+   pthread_join(audio_thread, NULL);
+ #ifdef HAS_AO
+-  ao_close(dev);
++  g_ao.ao_close(dev);
+ #endif
+ }
+ 
+ void hairtunes_cleanup(void)
+ {
++  pthread_cond_signal(&ab_buffer_ready);
+   clean_output();
+   clean_rtp();
+   clean_buffer();

Added: head/audio/libshairport/files/patch-src-hairtunes.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/audio/libshairport/files/patch-src-hairtunes.h	Mon Feb 18 04:45:09 2013	(r312476)
@@ -0,0 +1,11 @@
+--- src/hairtunes.h.orig	2011-08-21 00:06:21.000000000 +0200
++++ src/hairtunes.h	2012-10-09 12:09:33.000000000 +0200
+@@ -4,6 +4,8 @@
+ 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);
+ void hairtunes_setvolume(float vol);
++void hairtunes_set_metadata(const char *buffer, unsigned int size);
++void hairtunes_set_metadata_coverart(const char *buffer, unsigned int size);
+ void hairtunes_flush(void);
+ void hairtunes_cleanup(void);
+ 

Added: head/audio/libshairport/files/patch-src-shairport.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/audio/libshairport/files/patch-src-shairport.c	Mon Feb 18 04:45:09 2013	(r312476)
@@ -0,0 +1,691 @@
+--- src/shairport.c.orig	2011-08-21 01:57:56.000000000 +0200
++++ src/shairport.c	2012-10-09 12:09:33.000000000 +0200
+@@ -31,6 +31,27 @@
+ #include "shairport.h"
+ #include "hairtunes.h"
+ 
++static struct printfPtr g_printf={NULL};
++
++int xprintf(const char *format, ...)
++{
++  char dbg[2048];
++  va_list args;
++  va_start(args, format);
++  vsnprintf(dbg, sizeof(dbg), format, args);
++  va_end(args);
++  if(g_printf.extprintf)
++  {
++    g_printf.extprintf(dbg, sizeof(dbg));
++  }
++  else 
++  {
++    printf(dbg);
++  }
++
++  return 1;
++}
++
+ #ifndef TRUE
+ #define TRUE (-1)
+ #endif
+@@ -92,13 +113,26 @@
+ static char tPassword[56] = "";
+ static char tHWID[HWID_SIZE] = {0,51,52,53,54,55};
+ 
++#ifdef XBMC
++struct AudioOutput g_ao;
++void shairport_set_ao(struct AudioOutput *ao)
++{
++ g_ao=*ao;
++}
++
++void shairport_set_printf(struct printfPtr *funcPtr)
++{
++  g_printf = *funcPtr;
++}
++#endif
++
+ #ifndef XBMC
+ int main(int argc, char **argv)
+ #else
+ int shairport_main(int argc, char **argv)
+ #endif
+ {
+-  printf("initializing shairport\n");
++  xprintf("initializing shairport\n",NULL);
+   char tHWID_Hex[HWID_SIZE * 2 + 1];
+   char tKnownHwid[32];
+ 
+@@ -177,22 +211,22 @@
+     }    
+     else if(!strcmp(arg, "-h") || !strcmp(arg, "--help"))
+     {
+-      slog(LOG_INFO, "ShairPort version 0.05 C port - Airport Express emulator\n");
+-      slog(LOG_INFO, "Usage:\nshairport [OPTION...]\n\nOptions:\n");
+-      slog(LOG_INFO, "  -a, --apname=AirPort    Sets Airport name\n");
+-      slog(LOG_INFO, "  -p, --password=secret   Sets Password (not working)\n");
+-      slog(LOG_INFO, "  -o, --server_port=5000  Sets Port for Avahi/dns-sd\n");
+-      slog(LOG_INFO, "  -b, --buffer=282        Sets Number of frames to buffer before beginning playback\n");
+-      slog(LOG_INFO, "  -d                      Daemon mode\n");
+-      slog(LOG_INFO, "  -q, --quiet             Supresses all output.\n");
+-      slog(LOG_INFO, "  -v,-v2,-v3,-vv          Various debugging levels\n");
+-      slog(LOG_INFO, "\n");
++      xprintf("ShairPort version 0.05 C port - Airport Express emulator\n");
++      xprintf("Usage:\nshairport [OPTION...]\n\nOptions:\n");
++      xprintf("  -a, --apname=AirPort    Sets Airport name\n");
++      xprintf("  -p, --password=secret   Sets Password (not working)\n");
++      xprintf("  -o, --server_port=5000  Sets Port for Avahi/dns-sd\n");
++      xprintf("  -b, --buffer=282        Sets Number of frames to buffer before beginning playback\n");
++      xprintf("  -d                      Daemon mode\n");
++      xprintf("  -q, --quiet             Supresses all output.\n");
++      xprintf("  -v,-v2,-v3,-vv          Various debugging levels\n");
++      xprintf("\n");
+       return 0;
+     }    
+   }
+ 
+   if ( buffer_start_fill < 30 || buffer_start_fill > BUFFER_FRAMES ) { 
+-     fprintf(stderr, "buffer value must be > 30 and < %d\n", BUFFER_FRAMES);
++     xprintf("buffer value must be > 30 and < %d\n", BUFFER_FRAMES);
+      return(0);
+   }
+ 
+@@ -201,11 +235,11 @@
+     int tPid = fork();
+     if(tPid < 0)
+     {
+-      exit(1); // Error on fork
++      //exit(1); // Error on fork
+     }
+     else if(tPid > 0)
+     {
+-      exit(0);
++      //exit(0);
+     }
+     else
+     {
+@@ -246,10 +280,10 @@
+     sscanf(tHWID_Hex, "%02X%02X%02X%02X%02X%02X", &tHWID[0], &tHWID[1], &tHWID[2], &tHWID[3], &tHWID[4], &tHWID[5]);
+   }
+ 
+-  slog(LOG_INFO, "LogLevel: %d\n", kCurrentLogLevel);
+-  slog(LOG_INFO, "AirName: %s\n", tServerName);
+-  slog(LOG_INFO, "HWID: %.*s\n", HWID_SIZE, tHWID+1);
+-  slog(LOG_INFO, "HWID_Hex(%d): %s\n", strlen(tHWID_Hex), tHWID_Hex);
++  xprintf("LogLevel: %d\n", kCurrentLogLevel);
++  xprintf("AirName: %s\n", tServerName);
++  xprintf("HWID: %.*s\n", HWID_SIZE, tHWID+1);
++  xprintf("HWID_Hex(%d): %s\n", strlen(tHWID_Hex), tHWID_Hex);
+ 
+   if(tSimLevel >= 1)
+   {
+@@ -263,12 +297,12 @@
+ #ifndef XBMC
+     startAvahi(tHWID_Hex, tServerName, tPort);
+ #endif
+-    slog(LOG_DEBUG_V, "Starting connection server: specified server port: %d\n", tPort);
++    xprintf("Starting connection server: specified server port: %d\n", tPort);
+     tServerSock = setupListenServer(&tAddrInfo, tPort);
+     if(tServerSock < 0)
+     {
+       freeaddrinfo(tAddrInfo);
+-      slog(LOG_INFO, "Error setting up server socket on port %d, try specifying a different port\n", tPort);
++      xprintf("Error setting up server socket on port %d, try specifying a different port\n", tPort);
+       return 0;
+     }
+ 
+@@ -295,7 +329,7 @@
+ 
+     int readsock;
+ 
+-    slog(LOG_DEBUG_V, "Waiting for clients to connect\n");
++    xprintf("Waiting for clients to connect\n");
+ 
+     while(m_running)
+     {
+@@ -327,7 +361,7 @@
+         {
+           freeaddrinfo(tAddrInfo);
+           tAddrInfo = NULL;
+-          slog(LOG_DEBUG, "...Accepted Client Connection..\n");
++          xprintf("...Accepted Client Connection..\n");
+           close(tServerSock);
+           handleClient(tClientSock, tPassword, tHWID);
+           //close(tClientSock);
+@@ -335,11 +369,11 @@
+         }
+         else
+         {
+-          slog(LOG_DEBUG_VV, "Child now busy handling new client\n");
++          xprintf("Child now busy handling new client\n");
+           close(tClientSock);
+         }
+ #else
+-      slog(LOG_DEBUG, "...Accepted Client Connection..\n");
++      xprintf("...Accepted Client Connection..\n");
+       handleClient(tClientSock, tPassword, tHWID);
+ #endif
+       }
+@@ -349,7 +383,7 @@
+       }
+   }
+ 
+-  slog(LOG_DEBUG_VV, "Finished\n");
++  xprintf("Finished\n");
+   if(tAddrInfo != NULL)
+   {
+     freeaddrinfo(tAddrInfo);
+@@ -360,6 +394,7 @@
+ void shairport_exit(void)
+ {
+   m_running = 0;
++  close(tServerSock);
+ }
+ 
+ int shairport_is_running(void)
+@@ -407,7 +442,7 @@
+ 
+ void handleClient(int pSock, char *pPassword, char *pHWADDR)
+ {
+-  slog(LOG_DEBUG_VV, "In Handle Client\n");
++  xprintf("In Handle Client\n");
+   fflush(stdout);
+ 
+   socklen_t len;
+@@ -426,7 +461,7 @@
+ 
+   // deal with both IPv4 and IPv6:
+   if (addr.ss_family == AF_INET) {
+-      slog(LOG_DEBUG_V, "Constructing ipv4 address\n");
++      xprintf("Constructing ipv4 address\n");
+       struct sockaddr_in *s = (struct sockaddr_in *)&addr;
+       port = ntohs(s->sin_port);
+       inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr);
+@@ -446,20 +481,20 @@
+       if(memcmp(&addr.bin[0], "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\xff\xff", 12) == 0)
+       {
+         // its ipv4...
+-        slog(LOG_DEBUG_V, "Constructing ipv4 from ipv6 address\n");
++        xprintf("Constructing ipv4 from ipv6 address\n");
+         memcpy(ipbin, &addr.bin[12], 4);
+         ipbinlen = 4;
+       }
+       else
+       {
+-        slog(LOG_DEBUG_V, "Constructing ipv6 address\n");
++        xprintf("Constructing ipv6 address\n");
+         memcpy(ipbin, &s->sin6_addr, 16);
+         ipbinlen = 16;
+       }
+   }
+ 
+-  slog(LOG_DEBUG_V, "Peer IP address: %s\n", ipstr);
+-  slog(LOG_DEBUG_V, "Peer port      : %d\n", port);
++  xprintf("Peer IP address: %s\n", ipstr);
++  xprintf("Peer port      : %d\n", port);
+ 
+   int tMoreDataNeeded = 1;
+   struct keyring     tKeys;
+@@ -478,18 +513,19 @@
+     while(1 == tMoreDataNeeded)
+     {
+       tError = readDataFromClient(pSock, &(tConn.recv));
+-      if(!tError && strlen(tConn.recv.data) > 0)
++      //if(!tError && strlen(tConn.recv.data) > 0)
++      if(!tError && tConn.recv.current > 0)
+       {
+-        slog(LOG_DEBUG_VV, "Finished Reading some data from client\n");
++        xprintf("Finished Reading some data from client\n");
+         // parse client request
+         tMoreDataNeeded = parseMessage(&tConn, ipbin, ipbinlen, pHWADDR);
+         if(1 == tMoreDataNeeded)
+         {
+-          slog(LOG_DEBUG_VV, "\n\nNeed to read more data\n");
++          xprintf("\n\nNeed to read more data\n");
+         }
+         else if(-1 == tMoreDataNeeded) // Forked process down below ended.
+         {
+-          slog(LOG_DEBUG_V, "Forked Process ended...cleaning up\n");
++          xprintf("Forked Process ended...cleaning up\n");
+           cleanup(&tConn);
+           // pSock was already closed
+           return;
+@@ -498,13 +534,13 @@
+       }
+       else
+       {
+-        slog(LOG_DEBUG, "Error reading from socket, closing client\n");
++        xprintf("Error reading from socket, closing client\n");
+         // Error reading data....quit.
+         cleanup(&tConn);
+         return;
+       }
+     }
+-    slog(LOG_DEBUG_VV, "Writing: %d chars to socket\n", tConn.resp.current);
++    xprintf("Writing: %d chars to socket\n", tConn.resp.current);
+     //tConn->resp.data[tConn->resp.current-1] = '\0';
+     writeDataToClient(pSock, &(tConn.resp));
+    // Finished reading one message...
+@@ -517,9 +553,9 @@
+ 
+ void writeDataToClient(int pSock, struct shairbuffer *pResponse)
+ {
+-  slog(LOG_DEBUG_VV, "\n----Beg Send Response Header----\n%.*s\n", pResponse->current, pResponse->data);
++  xprintf("\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");
++  xprintf("----Send Response Header----\n");
+ }
+ 
+ int readDataFromClient(int pSock, struct shairbuffer *pClientBuffer)
+@@ -532,7 +568,7 @@
+   while(tRetval > 0 && tEnd < 0)
+   {
+      // Read from socket until \n\n, \r\n\r\n, or \r\r is found
+-      slog(LOG_DEBUG_V, "Waiting To Read...\n");
++      xprintf("Waiting To Read...\n");
+       fflush(stdout);
+       tRetval = read(pSock, tReadBuf, MAX_SIZE);
+       // if new buffer contains the end of request string, only copy partial buffer?
+@@ -543,40 +579,40 @@
+         {
+           pClientBuffer->marker = tEnd+1; // Marks start of content
+         }
+-        slog(SOCKET_LOG_LEVEL, "Found end of http request at: %d\n", tEnd);
++        xprintf("Found end of http request at: %d\n", tEnd);
+         fflush(stdout);        
+       }
+       else
+       {
+         tEnd = MAX_SIZE;
+-        slog(SOCKET_LOG_LEVEL, "Read %d of data so far\n%s\n", tRetval, tReadBuf);
++        xprintf("Read %d of data so far\n%s\n", tRetval, tReadBuf);
+         fflush(stdout);
+       }
+       if(tRetval > 0)
+       {
+         // Copy read data into tReceive;
+-        slog(SOCKET_LOG_LEVEL, "Read %d data, using %d of it\n", tRetval, tEnd);
++        xprintf("Read %d data, using %d of it\n", tRetval, tEnd);
+         addNToShairBuffer(pClientBuffer, tReadBuf, tRetval);
+-        slog(LOG_DEBUG_VV, "Finished copying data\n");
++        xprintf("Finished copying data\n");
+       }
+       else
+       {
+-        slog(LOG_DEBUG, "Error reading data from socket, got: %d bytes", tRetval);
++        xprintf("Error reading data from socket, got: %d bytes", tRetval);
+         return tRetval;
+       }
+   }
+   if(tEnd + 1 != tRetval)
+   {
+-    slog(SOCKET_LOG_LEVEL, "Read more data after end of http request. %d instead of %d\n", tRetval, tEnd+1);
++    xprintf("Read more data after end of http request. %d instead of %d\n", tRetval, tEnd+1);
+   }
+-  slog(SOCKET_LOG_LEVEL, "Finished Reading Data:\n%s\nEndOfData\n", pClientBuffer->data);
++  xprintf("Finished Reading Data:\n%s\nEndOfData\n", pClientBuffer->data);
+   fflush(stdout);
+   return 0;
+ }
+ 
+ char *getFromBuffer(char *pBufferPtr, const char *pField, int pLenAfterField, int *pReturnSize, char *pDelims)
+ {
+-  slog(LOG_DEBUG_V, "GettingFromBuffer: %s\n", pField);
++  xprintf("GettingFromBuffer: %s\n", pField);
+   char* tFound = strstr(pBufferPtr, pField);
+   int tSize = 0;
+   if(tFound != NULL)
+@@ -597,7 +633,7 @@
+     }
+     
+     tSize = (int) (tShortest - tFound);
+-    slog(LOG_DEBUG_VV, "Found %.*s  length: %d\n", tSize, tFound, tSize);
++    xprintf("Found %s  length: %d\n",tFound, tSize);
+     if(pReturnSize != NULL)
+     {
+       *pReturnSize = tSize;
+@@ -605,7 +641,7 @@
+   }
+   else
+   {
+-    slog(LOG_DEBUG_V, "Not Found\n");
++    xprintf("Not Found\n");
+   }
+   return tFound;
+ }
+@@ -639,10 +675,10 @@
+   {
+     char tTrim[tFoundSize + 2];
+     getTrimmed(tFound, tFoundSize, TRUE, TRUE, tTrim);
+-    slog(LOG_DEBUG_VV, "HeaderChallenge:  [%s] len: %d  sizeFound: %d\n", tTrim, strlen(tTrim), tFoundSize);
++    xprintf("HeaderChallenge:  [%s] len: %d  sizeFound: %d\n", tTrim, strlen(tTrim), tFoundSize);
+     int tChallengeDecodeSize = 16;
+     char *tChallenge = decode_base64((unsigned char *)tTrim, tFoundSize, &tChallengeDecodeSize);
+-    slog(LOG_DEBUG_VV, "Challenge Decode size: %d  expected 16\n", tChallengeDecodeSize);
++    xprintf("Challenge Decode size: %d  expected 16\n", tChallengeDecodeSize);
+ 
+     int tCurSize = 0;
+     unsigned char tChalResp[38];
+@@ -664,7 +700,7 @@
+     }
+ 
+     char *tTmp = encode_base64((unsigned char *)tChalResp, tCurSize);
+-    slog(LOG_DEBUG_VV, "Full sig: %s\n", tTmp);
++    xprintf("Full sig: %s\n", tTmp);
+     free(tTmp);
+ 
+     // RSA Encrypt
+@@ -709,15 +745,15 @@
+   if(tContent != NULL)
+   {
+     int tContentSize = atoi(tContent);
+-    if(pConn->recv.marker == 0 || strlen(pConn->recv.data+pConn->recv.marker) != tContentSize)
++    if(pConn->recv.marker == 0 || pConn->recv.current-pConn->recv.marker != tContentSize)
+     {
+       if(isLogEnabledFor(HEADER_LOG_LEVEL))
+       {
+-        slog(HEADER_LOG_LEVEL, "Content-Length: %s value -> %d\n", tContent, tContentSize);
++        xprintf("Content-Length: %s value -> %d\n", tContent, tContentSize);
+         if(pConn->recv.marker != 0)
+         {
+-          slog(HEADER_LOG_LEVEL, "ContentPtr has %d, but needs %d\n", 
+-                  strlen(pConn->recv.data+pConn->recv.marker), tContentSize);
++          xprintf("ContentPtr has %d, but needs %d\n", 
++                  (pConn->recv.current-pConn->recv.marker), tContentSize);
+         }
+       }
+       // check if value in tContent > 2nd read from client.
+@@ -726,7 +762,7 @@
+   }
+   else
+   {
+-    slog(LOG_DEBUG_VV, "No content, header only\n");
++    xprintf("No content, header only\n");
+   }
+ 
+   // "Creates" a new Response Header for our response message
+@@ -739,7 +775,7 @@
+     {
+       tLen = 20;
+     }
+-    slog(LOG_INFO, "********** RECV %.*s **********\n", tLen, pConn->recv.data);
++    xprintf("********** RECV %.*s **********\n", tLen, pConn->recv.data);
+   }
+ 
+   if(pConn->password != NULL)
+@@ -749,7 +785,7 @@
+ 
+   if(buildAppleResponse(pConn, pIpBin, pIpBinLen, pHWID)) // need to free sig
+   {
+-    slog(LOG_DEBUG_V, "Added AppleResponse to Apple-Challenge request\n");
++    xprintf("Added AppleResponse to Apple-Challenge request\n");
+   }
+ 
+   // Find option, then based on option, do different actions.
+@@ -769,14 +805,14 @@
+       int tKeySize = 0;
+       char tEncodedAesIV[tSize + 2];
+       getTrimmed(tHeaderVal, tSize, TRUE, TRUE, tEncodedAesIV);
+-      slog(LOG_DEBUG_VV, "AESIV: [%.*s] Size: %d  Strlen: %d\n", tSize, tEncodedAesIV, tSize, strlen(tEncodedAesIV));
++      xprintf("AESIV: [%.*s] Size: %d  Strlen: %d\n", tSize, tEncodedAesIV, tSize, strlen(tEncodedAesIV));
+       char *tDecodedIV =  decode_base64((unsigned char*) tEncodedAesIV, tSize, &tSize);
+ 
+       // grab the key, copy it out of the receive buffer
+       tHeaderVal = getFromContent(tContent, "a=rsaaeskey", &tKeySize);
+       char tEncodedAesKey[tKeySize + 2]; // +1 for nl, +1 for \0
+       getTrimmed(tHeaderVal, tKeySize, TRUE, TRUE, tEncodedAesKey);
+-      slog(LOG_DEBUG_VV, "AES KEY: [%s] Size: %d  Strlen: %d\n", tEncodedAesKey, tKeySize, strlen(tEncodedAesKey));
++      xprintf("AES KEY: [%s] Size: %d  Strlen: %d\n", tEncodedAesKey, tKeySize, strlen(tEncodedAesKey));
+       // remove base64 coding from key
+       char *tDecodedAesKey = decode_base64((unsigned char*) tEncodedAesKey,
+                               tKeySize, &tKeySize);  // Need to free DecodedAesKey
+@@ -785,7 +821,7 @@
+       int tFmtpSize = 0;
+       char *tFmtp = getFromContent(tContent, "a=fmtp", &tFmtpSize);  // Don't need to free
+       tFmtp = getTrimmedMalloc(tFmtp, tFmtpSize, TRUE, FALSE); // will need to free
+-      slog(LOG_DEBUG_VV, "Format: %s\n", tFmtp);
++      xprintf("Format: %s\n", tFmtp);
+ 
+       RSA *rsa = loadKey();
+       // Decrypt the binary aes key
+@@ -794,11 +830,11 @@
+       if(RSA_private_decrypt(tKeySize, (unsigned char *)tDecodedAesKey, 
+       (unsigned char*) tDecryptedKey, rsa, RSA_PKCS1_OAEP_PADDING) >= 0)

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201302180445.r1I4jA6M018618>