This is an iTunes server (DAAP) for OpenWrt. It is a re-write of firefly media server (mt-daapd), which is currently included in OpenWrt. forked-daapd has better features. It supports Apple Remote, and it also has been patched against a timeout-problem with iTunes, which I think mt-daapd has. I made a Wiki-Howto, where you can read more about the package:
http://wiki.openwrt.org/inbox/howto/forked-daapd I made the package available some time ago, here is the forum announcement: https://forum.openwrt.org/viewtopic.php?id=30302 It depends on 3 libraries, which are not part of OpenWrt: libavl, libunistring and libantlr3c. I'm also sending Makefiles for these libraries (I'm sending patches for these in separat mails). Signed-off-by: Espen Jürgensen <espenjurgen...@gmail.com> --- Index: package/forked-daapd/patches/itunes_timeout.patch =================================================================== --- package/forked-daapd/patches/itunes_timeout.patch (revision 0) +++ package/forked-daapd/patches/itunes_timeout.patch (revision 0) @@ -0,0 +1,164 @@ +--- a/src/httpd_daap.c 2011-09-11 15:46:25.000000000 +0200 ++++ b/src/httpd_daap.c 2012-06-23 23:28:11.662712064 +0200 +@@ -58,9 +58,11 @@ + + + /* Session timeout in seconds */ +-#define DAAP_SESSION_TIMEOUT 1800 ++#define DAAP_SESSION_TIMEOUT 0 /* By default the session never times out */ ++/* We announce this timeout to the client when returning server capabilities */ ++#define DAAP_SESSION_TIMEOUT_CAPABILITY 1800 + /* Update requests refresh interval in seconds */ +-#define DAAP_UPDATE_REFRESH 300 ++#define DAAP_UPDATE_REFRESH 0 + + + struct uri_map { +@@ -130,7 +132,7 @@ + + s = (struct daap_session *)item; + +- evtimer_del(&s->timeout); ++ if (event_initialized(&s->timeout)) evtimer_del(&s->timeout); + free(s); + } + +@@ -173,8 +175,10 @@ + + next_session_id++; + +- evtimer_set(&s->timeout, daap_session_timeout_cb, s); +- event_base_set(evbase_httpd, &s->timeout); ++ if (DAAP_SESSION_TIMEOUT > 0) { ++ evtimer_set(&s->timeout, daap_session_timeout_cb, s); ++ event_base_set(evbase_httpd, &s->timeout); ++ } + + node = avl_insert(daap_sessions, s); + if (!node) +@@ -185,12 +189,14 @@ + return NULL; + } + +- evutil_timerclear(&tv); +- tv.tv_sec = DAAP_SESSION_TIMEOUT; +- +- ret = evtimer_add(&s->timeout, &tv); +- if (ret < 0) +- DPRINTF(E_LOG, L_DAAP, "Could not add session timeout event for session %d\n", s->id); ++ if (DAAP_SESSION_TIMEOUT > 0) { ++ evutil_timerclear(&tv); ++ tv.tv_sec = DAAP_SESSION_TIMEOUT; ++ ++ ret = evtimer_add(&s->timeout, &tv); ++ if (ret < 0) ++ DPRINTF(E_LOG, L_DAAP, "Could not add session timeout event for session %d\n", s->id); ++ } + + return s; + } +@@ -225,14 +231,18 @@ + + s = (struct daap_session *)node->item; + +- event_del(&s->timeout); ++ if (DAAP_SESSION_TIMEOUT > 0) { ++ event_del(&s->timeout); ++ } + + evutil_timerclear(&tv); + tv.tv_sec = DAAP_SESSION_TIMEOUT; + +- ret = evtimer_add(&s->timeout, &tv); +- if (ret < 0) +- DPRINTF(E_LOG, L_DAAP, "Could not add session timeout event for session %d\n", s->id); ++ if (DAAP_SESSION_TIMEOUT > 0) { ++ ret = evtimer_add(&s->timeout, &tv); ++ if (ret < 0) ++ DPRINTF(E_LOG, L_DAAP, "Could not add session timeout event for session %d\n", s->id); ++ } + + return s; + +@@ -269,7 +279,7 @@ + update_free(struct daap_update_request *ur) + { + if (event_initialized(&ur->timeout)) +- evtimer_del(&ur->timeout); ++ evtimer_del(&ur->timeout); + free(ur); + } + +@@ -678,25 +688,23 @@ + dmap_add_container(evbuf, "msrv", len - 8); + dmap_add_int(evbuf, "mstt", 200); /* 12 */ + dmap_add_int(evbuf, "mpro", mpro); /* 12 */ +- dmap_add_int(evbuf, "apro", apro); /* 12 */ + dmap_add_string(evbuf, "minm", name); /* 8 + strlen(name) */ +- +- dmap_add_int(evbuf, "mstm", DAAP_SESSION_TIMEOUT); /* 12 */ +- dmap_add_char(evbuf, "msal", 1); /* 9 */ ++ dmap_add_int(evbuf, "apro", apro); /* 12 */ + + dmap_add_char(evbuf, "mslr", 1); /* 9 */ ++ dmap_add_int(evbuf, "mstm", DAAP_SESSION_TIMEOUT_CAPABILITY); /* 12 */ ++ dmap_add_char(evbuf, "msal", 1); /* 9 */ + dmap_add_char(evbuf, "msau", (passwd) ? 2 : 0); /* 9 */ ++ dmap_add_char(evbuf, "msup", 1); /* 9 */ ++ ++ dmap_add_char(evbuf, "mspi", 1); /* 9 */ + dmap_add_char(evbuf, "msex", 1); /* 9 */ + dmap_add_char(evbuf, "msix", 1); /* 9 */ + dmap_add_char(evbuf, "msbr", 1); /* 9 */ + dmap_add_char(evbuf, "msqy", 1); /* 9 */ + +- dmap_add_char(evbuf, "mspi", 1); /* 9 */ + dmap_add_int(evbuf, "msdc", 1); /* 12 */ + +- /* Advertise updates support even though we don't send updates */ +- dmap_add_char(evbuf, "msup", 1); /* 9 */ +- + httpd_send_reply(req, HTTP_OK, "OK", evbuf); + } + +@@ -887,22 +895,24 @@ + } + memset(ur, 0, sizeof(struct daap_update_request)); + +- evtimer_set(&ur->timeout, update_refresh_cb, ur); +- event_base_set(evbase_httpd, &ur->timeout); +- +- evutil_timerclear(&tv); +- tv.tv_sec = DAAP_UPDATE_REFRESH; +- +- ret = evtimer_add(&ur->timeout, &tv); +- if (ret < 0) +- { +- DPRINTF(E_LOG, L_DAAP, "Could not add update timeout event\n"); +- +- dmap_send_error(req, "mupd", "Could not register timer"); +- +- update_free(ur); +- return; +- } ++ if (DAAP_UPDATE_REFRESH > 0) { ++ evtimer_set(&ur->timeout, update_refresh_cb, ur); ++ event_base_set(evbase_httpd, &ur->timeout); ++ ++ evutil_timerclear(&tv); ++ tv.tv_sec = DAAP_UPDATE_REFRESH; ++ ++ ret = evtimer_add(&ur->timeout, &tv); ++ if (ret < 0) ++ { ++ DPRINTF(E_LOG, L_DAAP, "Could not add update timeout event\n"); ++ ++ dmap_send_error(req, "mupd", "Could not register timer"); ++ ++ update_free(ur); ++ return; ++ } ++ } + + /* NOTE: we may need to keep reqd_rev in there too */ + ur->req = req; Index: package/forked-daapd/patches/configure.in.patch =================================================================== --- package/forked-daapd/patches/configure.in.patch (revision 0) +++ package/forked-daapd/patches/configure.in.patch (revision 0) @@ -0,0 +1,11 @@ +--- a/configure.in 2011-09-11 15:46:25.000000000 +0200 ++++ b/configure.in 2012-06-23 11:24:32.899076652 +0200 +@@ -185,7 +185,7 @@ + fi + + AC_CHECK_HEADERS([sys/eventfd.h]) +- AC_CHECK_FUNCS(eventfd) ++ AC_CHECK_FUNCS(eventfd_write) + + AC_CHECK_HEADER(sys/signalfd.h, , AC_MSG_ERROR([signalfd required; glibc 2.9+ recommended])) + Index: package/forked-daapd/Makefile =================================================================== --- package/forked-daapd/Makefile (revision 0) +++ package/forked-daapd/Makefile (revision 0) @@ -0,0 +1,64 @@ +# $Id$ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=forked-daapd +PKG_VERSION:=0.19 +PKG_RELEASE:=5 +PKG_MD5SUM:=53e6f1d6683e3275e7c7698ec923a97e + +PKG_SOURCE_URL:=http://alioth.debian.org/~jblache/forked-daapd \ + http://www.gyfgafguf.dk/openwrt/mirror +PKG_SOURCE:=forked-daapd-$(PKG_VERSION).tar.gz +PKG_CAT:=zcat + +PKG_FIXUP:=libtool +PKG_INSTALL:=1 +PKG_BUILD_DIR:=$(BUILD_DIR)/forked-daapd-$(PKG_VERSION) +PKG_BUILD_DEPENDS:=libgpg-error libgcrypt libgdbm zlib libexpat libunistring \ + libevent libdaemon libantlr3c confuse glib2 alsa-lib libffmpeg-full \ + mxml libavl avahi-daemon libavahi-client sqlite3-cli + +include $(INCLUDE_DIR)/package.mk + +define Package/forked-daapd +SECTION:=sound +CATEGORY:=Sound +TITLE:=Improved iTunes server. Support for Apple Remote. Includes patch for iTunes 10.5 timeouts. +MAINTAINER:=Espen Jürgensen <espenjurgensen+open...@gmail.com> +URL:=https://github.com/jasonmc/forked-daapd +DEPENDS:=+libgpg-error +libgcrypt +libgdbm +zlib +libexpat +libunistring \ + +libevent +libdaemon +libantlr3c +confuse +glib2 +alsa-lib +libffmpeg-full \ + +mxml +libavl +avahi-daemon +libavahi-client +sqlite3-cli +endef + +define Package/forked-daapd/conffiles +/etc/forked-daapd.conf +endef + +# Fix for libevent +TARGET_CPPFLAGS += -I$(STAGING_DIR)/usr/include/libevent +TARGET_LDFLAGS += -L$(STAGING_DIR)/usr/lib/libevent + +TARGET_CFLAGS += $(FPIC) +TARGET_LDFLAGS += -Wl,-rpath-link,$(STAGING_DIR)/usr/lib + +define Build/Configure + $(call Build/Configure/Default, \ + --enable-shared \ + --enable-static) +endef + +define Package/forked-daapd/install + $(INSTALL_DIR) $(1)/etc + $(INSTALL_DATA) ./files/forked-daapd.conf $(1)/etc/ + $(INSTALL_DIR) $(1)/usr/lib + $(INSTALL_DIR) $(1)/usr/lib/forked-daapd + $(CP) $(PKG_INSTALL_DIR)/usr/lib/forked-daapd/* $(1)//usr/lib/forked-daapd/ + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/forked-daapd $(1)/usr/sbin/ + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/forked-daapd.init $(1)/etc/init.d/forked-daapd +endef + +$(eval $(call BuildPackage,forked-daapd)) Index: package/forked-daapd/files/forked-daapd.init =================================================================== --- package/forked-daapd/files/forked-daapd.init (revision 0) +++ package/forked-daapd/files/forked-daapd.init (revision 0) @@ -0,0 +1,15 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2010 OpenWrt.org + +START=99 +BIN=/usr/sbin/forked-daapd +PID=/var/run/forked-daapd.pid +SSD=start-stop-daemon + +start() { + $SSD -p $PID -S -x $BIN -- -P $PID +} + +stop() { + $SSD -p $PID -K -s SIGINT +} Index: package/forked-daapd/files/forked-daapd.conf =================================================================== --- package/forked-daapd/files/forked-daapd.conf (revision 0) +++ package/forked-daapd/files/forked-daapd.conf (revision 0) @@ -0,0 +1,57 @@ + +general { + # Username + uid = "root" + logfile = "/var/log/forked-daapd.log" + # Database location +# db_path = "/mnt/sda1/.forked-daapd.db" + # Available levels: fatal, log, warning, info, debug, spam + loglevel = log + # Admin password for the non-existent web interface + admin_password = "unused" + # Enable/disable IPv6 + ipv6 = no +} + +# Library configuration +library { + # Name of the library as displayed by the clients + # %h: hostname, %v: version + name = "My Music on %h" + # TCP port to listen on. Default port is 3689 (daap) + port = 3689 + # Password for the library. Optional. +# password = "" + + # Directories to index + directories = { "/mnt/sda1/Music" } + # Directories containing compilations + # Matches anywhere in the path (not a regexp, though) +# compilations = { "/compilations/" } + + # Should iTunes metadata override ours? +# itunes_overrides = true + + # Formats: mp4a, mp4v, mpeg, alac, flac, mpc, ogg, wma, wmal, wmav, aif, wav + # Formats that should never be transcoded +# no_transcode = { "alac", "mp4a" } + # Formats that should always be transcoded +# force_transcode = { "ogg", "flac" } +} + +# Local audio output +audio { + # AirTunes name - used in the speaker list in Remote + nickname = "OpenWrt" + # Audio device name for local audio output +# card = "default" + # Mixer channel to use for volume control - ALSA/Linux only + # If not set, PCM will be used if available, otherwise Master. +# mixer = "" +} + +# Airport Express device +#apex "ApEx" { + # AirTunes password +# password = "s1kr3t" +#} _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel