shairport: add AirPort Express emulation software
Signed-off-by: Florian Fainelli <florian@openwrt.org> git-svn-id: svn://svn.openwrt.org/openwrt/packages@35746 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
parent
7f2cae5f49
commit
51584e3ed3
56
multimedia/shairport/Makefile
Normal file
56
multimedia/shairport/Makefile
Normal file
@ -0,0 +1,56 @@
|
||||
#
|
||||
# Copyright (C) 2013 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=shairport
|
||||
PKG_VERSION:=2012-10-20
|
||||
PKG_RELEASE:=$(PKG_SOURCE_VERSION)
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=git://github.com/albertz/shairport.git
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_SOURCE_VERSION:=4746bb11395d171ee800f074f489c42020a84932
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/shairport
|
||||
SECTION:=multimedia
|
||||
CATEGORY:=Multimedia
|
||||
DEPENDS:=+libpthread +avahi-utils +libopenssl +libao
|
||||
TITLE:=ShairPort AirPort Express emulator
|
||||
endef
|
||||
|
||||
define Package/shairport/description
|
||||
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.
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS += $(FPIC)
|
||||
|
||||
LIBS:=-lao -lm -lcrypto -lpthread
|
||||
|
||||
MAKE_FLAGS += \
|
||||
CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \
|
||||
LDFLAGS="$(TARGET_LDFLAGS) $(LIBS)"
|
||||
|
||||
define Package/shairport/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/shairport $(1)/usr/sbin/
|
||||
$(INSTALL_DIR) $(1)/etc/init.d/
|
||||
$(INSTALL_BIN) files/shairport.init $(1)/etc/init.d/shairport
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_DATA) files/shairport.config $(1)/etc/config/shairport
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,shairport))
|
3
multimedia/shairport/files/shairport.config
Normal file
3
multimedia/shairport/files/shairport.config
Normal file
@ -0,0 +1,3 @@
|
||||
config shairport
|
||||
option name 'AirPort'
|
||||
option buffer '256'
|
36
multimedia/shairport/files/shairport.init
Normal file
36
multimedia/shairport/files/shairport.init
Normal file
@ -0,0 +1,36 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
START=80
|
||||
|
||||
DAEMON="/usr/sbin/shairport"
|
||||
|
||||
config_shairport() {
|
||||
local cfg="$1"
|
||||
local args=""
|
||||
|
||||
config_get name "$cfg" name
|
||||
config_get password "$cfg" password
|
||||
config_get port "$cfg" port
|
||||
config_get buffer "$cfg" buffer
|
||||
|
||||
[ -z $name ] && name="AirPort"
|
||||
args="$args -a $name"
|
||||
|
||||
[ ! -z "$password" ] && args="$args -p $password"
|
||||
[ ! -z "$port" ] && args="$args -o $port"
|
||||
|
||||
[ -z $buffer ] && buffer="256"
|
||||
args="$args -b $buffer"
|
||||
|
||||
args="$args -d"
|
||||
|
||||
service_start $DAEMON $args
|
||||
}
|
||||
|
||||
start() {
|
||||
config_load shairport
|
||||
config_foreach config_shairport shairport
|
||||
}
|
||||
|
||||
stop() {
|
||||
service_stop $DAEMON
|
||||
}
|
108
multimedia/shairport/patches/001-fix_ipv6_fallback.patch
Normal file
108
multimedia/shairport/patches/001-fix_ipv6_fallback.patch
Normal file
@ -0,0 +1,108 @@
|
||||
diff --git a/socketlib.c b/socketlib.c
|
||||
index 9efdf22..eb44bcf 100644
|
||||
--- a/socketlib.c
|
||||
+++ b/socketlib.c
|
||||
@@ -39,9 +39,11 @@
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/buffer.h>
|
||||
|
||||
-int common_setup(struct addrinfo *pAddrInfo)
|
||||
-{
|
||||
+int common_setup(struct addrinfo **ppAddrInfo, int pPort)
|
||||
+{
|
||||
int tSock;
|
||||
+ struct addrinfo *pAddrInfo = *ppAddrInfo;
|
||||
+
|
||||
//printAddrs(pAddrInfo);
|
||||
tSock = socket(pAddrInfo->ai_family, pAddrInfo->ai_socktype, 0);
|
||||
#ifdef AF_INET6
|
||||
@@ -49,7 +51,17 @@ int common_setup(struct addrinfo *pAddrInfo)
|
||||
{
|
||||
//Fallback to ipv4
|
||||
perror("Failed to create ipv6 socket. Trying ipv4");
|
||||
- pAddrInfo->ai_family = AF_INET;
|
||||
+ (*ppAddrInfo)->ai_family = AF_INET;
|
||||
+ if (pPort != -1)
|
||||
+ {
|
||||
+ char tService[SERVLEN];
|
||||
+ sprintf(tService, "%d", pPort); // copies port to string
|
||||
+ int tFamily = AF_INET;
|
||||
+ if(getAddr(NULL, tService, tFamily, SOCK_STREAM, ppAddrInfo))
|
||||
+ {
|
||||
+ return ERROR; // getAddr prints out error message
|
||||
+ }
|
||||
+ }
|
||||
tSock = socket(pAddrInfo->ai_family, pAddrInfo->ai_socktype, 0);
|
||||
}
|
||||
#endif
|
||||
@@ -63,7 +75,7 @@ int setup_client(struct addrinfo *server_host)
|
||||
|
||||
while(tIdx++ < RETRY_COUNT)
|
||||
{
|
||||
- tSockDesc = common_setup(server_host);
|
||||
+ tSockDesc = common_setup(&server_host, -1);
|
||||
if (tSockDesc < 0 && tIdx >= RETRY_COUNT)
|
||||
{
|
||||
perror("Error: Could not create socket");
|
||||
@@ -107,9 +119,23 @@ int getAddr(char *pHostname, char *pService, int pFamily, int pSockType, struct
|
||||
return tError;
|
||||
}
|
||||
|
||||
-int setup_server(struct addrinfo *server_addr)
|
||||
+int setup_server(struct addrinfo *server_addr, int pPort)
|
||||
{
|
||||
- int tSock = common_setup(server_addr);
|
||||
+ char tService[SERVLEN];
|
||||
+ sprintf(tService, "%d", pPort); // copies port to string
|
||||
+ int tFamily = AF_INET;
|
||||
+ #ifdef AF_INET6
|
||||
+ //printf("Listening on IPv6 Socket\n");
|
||||
+ tFamily = AF_INET6;
|
||||
+ #else
|
||||
+ //printf("Listening on IPv4 Socket");
|
||||
+ #endif
|
||||
+ if(getAddr(NULL, tService, tFamily, SOCK_STREAM, &server_addr))
|
||||
+ {
|
||||
+ return ERROR; // getAddr prints out error message
|
||||
+ }
|
||||
+
|
||||
+ int tSock = common_setup(&server_addr, pPort);
|
||||
if (tSock < 0)
|
||||
{
|
||||
perror("Error: Could not create server socket");
|
||||
@@ -154,21 +180,7 @@ int acceptClient(int pSock, struct addrinfo *server_addr)
|
||||
|
||||
int setupListenServer(struct addrinfo **pAddrInfo, int pPort)
|
||||
{
|
||||
- char tService[SERVLEN];
|
||||
- sprintf(tService, "%d", pPort); // copies port to string
|
||||
- int tFamily = AF_INET;
|
||||
- #ifdef AF_INET6
|
||||
- //printf("Listening on IPv6 Socket\n");
|
||||
- tFamily = AF_INET6;
|
||||
- #else
|
||||
- //printf("Listening on IPv4 Socket");
|
||||
- #endif
|
||||
- if(getAddr(NULL, tService, tFamily, SOCK_STREAM, pAddrInfo))
|
||||
- {
|
||||
- return ERROR; // getAddr prints out error message
|
||||
- }
|
||||
-
|
||||
- int tSocketDescriptor = setup_server(*pAddrInfo);
|
||||
+ int tSocketDescriptor = setup_server(*pAddrInfo, pPort);
|
||||
char tAddr[INET6_ADDRSTRLEN];
|
||||
socklen_t tSize = INET6_ADDRSTRLEN;
|
||||
inet_ntop((*pAddrInfo)->ai_family, (*pAddrInfo)->ai_addr, tAddr, tSize);
|
||||
diff --git a/socketlib.h b/socketlib.h
|
||||
index 6d501f3..5cb1bf0 100644
|
||||
--- a/socketlib.h
|
||||
+++ b/socketlib.h
|
||||
@@ -24,7 +24,7 @@
|
||||
#define DEFAULT_UNIX "/unix"
|
||||
|
||||
int setup_client(struct addrinfo *server_info);
|
||||
-int setup_server(struct addrinfo *server_address);
|
||||
+int setup_server(struct addrinfo *server_address, int pPort);
|
||||
int setupListenServer(struct addrinfo **pAddrInfo, int pPort);
|
||||
int acceptClient(int pSock, struct addrinfo *server_addr);
|
||||
void delay(long pMillisecs, struct timeval *pRes);
|
Loading…
x
Reference in New Issue
Block a user