Hi all

I just bought a Pioneer AV receiver that does AirPlay and would like
to stream it from my Ubuntu laptop. It did not work right away, and I
found tickets #950 and #890 regarding port number not being 5000 and I
have the same case here. Attached is a patch that at least for me
makes it connect to the port advertised in the SRV record. It needs to
be tested with a device that uses port 5000 as well to make sure it
still works for them as well.

However, even with this patch it still does not work for me. I get:
W: rtsp_client.c: Unexpected response: RTSP/1.0 500 Internal Server Error
W: rtsp_client.c: Unexpected response: Server: AirTunes/103.2
W: rtsp_client.c: Unexpected response: CSeq: 2
W: rtsp_client.c: Unexpected response:
so I will keep testing. I have an iPhone which can stream audio so I
will compare them and see what happens.

/Erik
From c9bb332e9ae3b5845441cf155c6f6bf5ccbb9822 Mon Sep 17 00:00:00 2001
From: Erik Ekman <[email protected]>
Date: Thu, 4 Aug 2011 20:48:46 +0200
Subject: [PATCH] raop: Use port number from mDNS for raop connection

The tcp port on many new devices is not 5000 but varying and given in the SRV
_raop._tcp record. Use this port number instead.
The module-raop-sink will default to port 5000 if no port is given to it.
---
 src/modules/raop/module-raop-discover.c |   14 +++++++++++---
 src/modules/raop/module-raop-sink.c     |   10 +++++++++-
 src/modules/raop/raop_client.c          |    6 ++++--
 src/modules/raop/raop_client.h          |    2 +-
 4 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/src/modules/raop/module-raop-discover.c b/src/modules/raop/module-raop-discover.c
index de1a2b1..f4f0897 100644
--- a/src/modules/raop/module-raop-discover.c
+++ b/src/modules/raop/module-raop-discover.c
@@ -63,6 +63,7 @@ struct tunnel {
     AvahiProtocol protocol;
     char *name, *type, *domain;
     uint32_t module_index;
+    uint16_t port;
 };
 
 struct userdata {
@@ -100,13 +101,15 @@ static int tunnel_compare(const void *a, const void *b) {
         return r;
     if ((r = strcmp(ta->domain, tb->domain)))
         return r;
+    if (ta->port != tb->port)
+        return 1;
 
     return 0;
 }
 
 static struct tunnel *tunnel_new(
         AvahiIfIndex interface, AvahiProtocol protocol,
-        const char *name, const char *type, const char *domain) {
+        const char *name, const char *type, const char *domain, uint16_t port) {
 
     struct tunnel *t;
     t = pa_xnew(struct tunnel, 1);
@@ -116,6 +119,7 @@ static struct tunnel *tunnel_new(
     t->type = pa_xstrdup(type);
     t->domain = pa_xstrdup(domain);
     t->module_index = PA_IDXSET_INVALID;
+    t->port = port;
     return t;
 }
 
@@ -142,7 +146,7 @@ static void resolver_cb(
 
     pa_assert(u);
 
-    tnl = tunnel_new(interface, protocol, name, type, domain);
+    tnl = tunnel_new(interface, protocol, name, type, domain, port);
 
     if (event != AVAHI_RESOLVER_FOUND)
         pa_log("Resolving of '%s' failed: %s", name, avahi_strerror(avahi_client_errno(u->client)));
@@ -194,16 +198,20 @@ static void resolver_cb(
                                  vname);*/
         if (nicename) {
             args = pa_sprintf_malloc("server=%s "
+                                     "port=%d "
                                      "sink_name=%s "
                                      "sink_properties=device.description=\"%s\"",
                                      avahi_address_snprint(at, sizeof(at), a),
+                                     tnl->port,
                                      vname,
                                      nicename);
 
         } else {
             args = pa_sprintf_malloc("server=%s "
+                                     "port=%d "
                                      "sink_name=%s",
                                      avahi_address_snprint(at, sizeof(at), a),
+                                     tnl->port,
                                      vname);
         }
 
@@ -244,7 +252,7 @@ static void browser_cb(
     if (flags & AVAHI_LOOKUP_RESULT_LOCAL)
         return;
 
-    t = tunnel_new(interface, protocol, name, type, domain);
+    t = tunnel_new(interface, protocol, name, type, domain, 0);
 
     if (event == AVAHI_BROWSER_NEW) {
 
diff --git a/src/modules/raop/module-raop-sink.c b/src/modules/raop/module-raop-sink.c
index 4b21d39..099edb8 100644
--- a/src/modules/raop/module-raop-sink.c
+++ b/src/modules/raop/module-raop-sink.c
@@ -68,6 +68,7 @@ PA_MODULE_USAGE(
         "sink_name=<name for the sink> "
         "sink_properties=<properties for the sink> "
         "server=<address>  "
+        "port=<port> "
         "format=<sample format> "
         "rate=<sample rate> "
         "channels=<number of channels>");
@@ -115,6 +116,7 @@ static const char* const valid_modargs[] = {
     "sink_name",
     "sink_properties",
     "server",
+    "port",
     "format",
     "rate",
     "channels",
@@ -507,6 +509,7 @@ int pa__init(pa_module*m) {
     pa_sample_spec ss;
     pa_modargs *ma = NULL;
     const char *server;
+    uint32_t port;
     pa_sink_new_data data;
 
     pa_assert(m);
@@ -569,6 +572,11 @@ int pa__init(pa_module*m) {
         goto fail;
     }
 
+    port = 0;
+    pa_modargs_get_value_u32(ma, "port", &port);
+    if (port == 0)
+        port = 5000;
+
     pa_sink_new_data_init(&data);
     data.driver = __FILE__;
     data.module = m;
@@ -601,7 +609,7 @@ int pa__init(pa_module*m) {
     pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
     pa_sink_set_rtpoll(u->sink, u->rtpoll);
 
-    if (!(u->raop = pa_raop_client_new(u->core, server))) {
+    if (!(u->raop = pa_raop_client_new(u->core, server, port))) {
         pa_log("Failed to connect to server.");
         goto fail;
     }
diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c
index cba7af9..5fdfcdf 100644
--- a/src/modules/raop/raop_client.c
+++ b/src/modules/raop/raop_client.c
@@ -73,6 +73,7 @@ struct pa_raop_client {
     char *host;
     char *sid;
     pa_rtsp_client *rtsp;
+    uint16_t port;
 
     uint8_t jack_type;
     uint8_t jack_status;
@@ -362,7 +363,7 @@ static void rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, pa_headerlist* he
     }
 }
 
-pa_raop_client* pa_raop_client_new(pa_core *core, const char* host) {
+pa_raop_client* pa_raop_client_new(pa_core *core, const char* host, uint16_t port) {
     pa_raop_client* c = pa_xnew0(pa_raop_client, 1);
 
     pa_assert(core);
@@ -371,6 +372,7 @@ pa_raop_client* pa_raop_client_new(pa_core *core, const char* host) {
     c->core = core;
     c->fd = -1;
     c->host = pa_xstrdup(host);
+    c->port = port;
 
     if (pa_raop_connect(c)) {
         pa_raop_client_free(c);
@@ -405,7 +407,7 @@ int pa_raop_connect(pa_raop_client* c) {
         return 0;
     }
 
-    c->rtsp = pa_rtsp_client_new(c->core->mainloop, c->host, 5000, "iTunes/4.6 (Macintosh; U; PPC Mac OS X 10.3)");
+    c->rtsp = pa_rtsp_client_new(c->core->mainloop, c->host, c->port, "iTunes/4.6 (Macintosh; U; PPC Mac OS X 10.3)");
 
     /* Initialise the AES encryption system */
     pa_random(c->aes_iv, sizeof(c->aes_iv));
diff --git a/src/modules/raop/raop_client.h b/src/modules/raop/raop_client.h
index ce81f39..0a764a1 100644
--- a/src/modules/raop/raop_client.h
+++ b/src/modules/raop/raop_client.h
@@ -26,7 +26,7 @@
 
 typedef struct pa_raop_client pa_raop_client;
 
-pa_raop_client* pa_raop_client_new(pa_core *core, const char* host);
+pa_raop_client* pa_raop_client_new(pa_core *core, const char* host, uint16_t port);
 void pa_raop_client_free(pa_raop_client* c);
 
 int pa_raop_connect(pa_raop_client* c);
-- 
1.7.1

_______________________________________________
pulseaudio-discuss mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Reply via email to