Re: [pulseaudio-discuss] [PATCH] raop: silence a Coverity complaint

2017-07-27 Thread Hajime Fujita
I thought I added this fix before but apparently not.
Looks good to me. Thank you for bringing this up.


Hajime

> On Jul 27, 2017, at 8:07 PM, Tanu Kaskinen  wrote:
> 
> CID: 1398155
> ---
> src/modules/raop/raop-sink.c | 7 +++
> 1 file changed, 7 insertions(+)
> 
> diff --git a/src/modules/raop/raop-sink.c b/src/modules/raop/raop-sink.c
> index e5d219e87..4d13927fc 100644
> --- a/src/modules/raop/raop-sink.c
> +++ b/src/modules/raop/raop-sink.c
> @@ -391,6 +391,13 @@ static void thread_func(void *userdata) {
> if (!pa_raop_client_can_stream(u->raop))
> continue;
> 
> +/* This assertion is meant to silence a complaint from Coverity about
> + * pollfd being possibly NULL when we access it later. That's a false
> + * positive, because we check pa_raop_client_can_stream() above, and 
> if
> + * that returns true, it means that the connection is up, and when 
> the
> + * connection is up, pollfd will be non-NULL. */
> +pa_assert(pollfd);
> +
> if (u->memchunk.length <= 0) {
> if (u->memchunk.memblock)
> pa_memblock_unref(u->memchunk.memblock);
> -- 
> 2.13.2
> 

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [RAOP] [PATCH] Fix audio synchronisation

2017-07-25 Thread Hajime Fujita
Hi Colin,

Thank you for working on this!

I haven’t had a chance to actually test the patch, but just skimmed it. The 
idea seems reasonable. Will try to see if I can test it this weekend.

> -c->rtptime += length / 4;
> +c->rtpdiff = length / 4;
> +c->rtptime += c->rtpdiff;

Could you remind me what was “/4”? Was that because 16-bit audio data x 2 
channels?
Sorry, it’s been a few years since I started working on RAOP code.


Thanks,
Hajime

> On Jul 22, 2017, at 9:21 AM, Colin Leroy  wrote:
> 
> On 22 July 2017 at 14h53, Colin Leroy wrote:
> 
> Hi, 
> 
>> I think I've figured out how to cleanly synchronise audio and video
>> with RAOP with relying on my empirical "shifting audio 2300ms in
>> mplayer works".
> 
> *without*relying on, obviously :)
> 
> -- 
> Colin
> ___
> pulseaudio-discuss mailing list
> pulseaudio-discuss@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH 0/8] more Coverity fixes and cleanups

2017-03-08 Thread Hajime Fujita
Hi Peter,

Thank you for the fix; raop patches look good to me.

Best,
Hajime

> On Mar 8, 2017, at 9:09 AM, Peter Meerwald-Stadler  wrote:
> 
> some more Coverity fixes and cleanups
> also addresses Hajime Fujita's earlier review comments
> 
> Peter Meerwald-Stadler (8):
>  raop: Fix potential dereference after NULL check
>  raop: Fix potential NULL dereference
>  raop: Log if pa_atoi() fails, latency is not used anyway
>  raop: Error out on parsing server port component
>  core: Assert return value of pa_shared_set/_remove() in dbus-shared
>  core: Document behaviour of pa_shared_remove() in case name does not
>exist
>  oss: Fix dead code
>  pulse: Explicitly ignore pa_mainloop_run() return value in thread
>function
> 
> src/modules/oss/module-oss.c   |  2 +-
> src/modules/raop/raop-client.c | 50 +-
> src/modules/raop/raop-sink.c   | 10 +
> src/pulse/thread-mainloop.c|  2 +-
> src/pulsecore/dbus-shared.c|  4 ++--
> src/pulsecore/shared.c |  2 +-
> src/pulsecore/shared.h |  4 +++-
> 7 files changed, 44 insertions(+), 30 deletions(-)
> 
> -- 
> 2.7.4
> 
> ___
> pulseaudio-discuss mailing list
> pulseaudio-discuss@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH v2 10/10] raop: Fix potential NULL dereference

2017-03-08 Thread Hajime Fujita

> On Mar 8, 2017, at 9:11 AM, Peter Meerwald-Stadler  wrote:
> 
> 
>>> diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
>>> index d329a09..5248691 100644
>>> --- a/src/modules/raop/raop-client.c
>>> +++ b/src/modules/raop/raop-client.c
>>> @@ -1254,13 +1254,13 @@ static void rtsp_auth_cb(pa_rtsp_client *rtsp, 
>>> pa_rtsp_state_t state, pa_rtsp_st
>>>pa_xfree(token);
>>>}
>>> 
>>> -if (pa_safe_streq(mth, "Basic")) {
>>> +if (pa_safe_streq(mth, "Basic") && realm) {
>>>rtrim_char(realm, '\"’);
>> 
>> I would remove `rtrim_char(realm, '\"’);` from this block and keep the if 
>> condition as-is, since realm is not used later.
> 
> even though realm is not referenced in the code, RFC2617 requires it to be 
> present; so I think we should check for it (before we assumed it is 
> present)

Okay, then it makes sense.

> 
>>> 
>>>pa_raop_basic_response(DEFAULT_USER_NAME, c->password, 
>>> );
>>>ath = pa_sprintf_malloc("Basic %s",
>>>response);
>>> -} else if (pa_safe_streq(mth, "Digest")) {
>>> +} else if (pa_safe_streq(mth, "Digest") && realm && nonce) 
>>> {
>> 
>> Why don’t we do like this:
>> +if (realm == NULL) {
>> +pa_log_error("realm not provided");
>> +goto error;
>> +} else if (nonce == NULL) {
>> +pa_log_error("nonce not provided");
>> +goto error;
>> +}
> 
> ok, this adds more code; my goal was addressing the NULL dereference in 
> case realm and/or nonce was missing
> 
> p.
> 
> -- 
> 
> Peter Meerwald-Stadler
> Mobile: +43 664 24 44 418

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH v2 00/10] Coverity fixes, raop

2017-03-06 Thread Hajime Fujita
Hi Peter,

Thank you for taking care of this!
Actually I also started working on this but haven’t had a chance to cleanup the 
patches.

Patches look good except where I made comments on each message.


Thanks,
Hajime

> On Mar 6, 2017, at 1:43 AM, Peter Meerwald-Stadler  wrote:
> 
> the first patch commits the model file as used on scan.coverity.com
> and rewrites pa_assert_se() so that Coverity doesn't complain about
> side-effects
> 
> some more Coverity fixes for the raop code
> 
> Peter Meerwald-Stadler (10):
>  build: Add Coverity scan model
>  raop: Fix double free
>  raop: Fix loop searching for port number
>  raop: Fix memleak
>  raop: Fix resource leaks
>  raop: Fix potential memory leak
>  raop: Fix indentation
>  raop: Silence unchecked return value warnings
>  raop: Fix potential resource leaks
>  raop: Fix potential NULL dereference
> 
> coverity/model.c| 18 ++
> src/modules/raop/module-raop-discover.c | 22 +
> src/modules/raop/raop-client.c  | 44 +
> src/modules/raop/raop-sink.c|  6 ++---
> src/pulsecore/macro.h   |  9 +++
> 5 files changed, 70 insertions(+), 29 deletions(-)
> create mode 100644 coverity/model.c
> 
> -- 
> 2.7.4
> 
> ___
> pulseaudio-discuss mailing list
> pulseaudio-discuss@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH v2 08/10] raop: Silence unchecked return value warnings

2017-03-06 Thread Hajime Fujita

> On Mar 6, 2017, at 1:43 AM, Peter Meerwald-Stadler  wrote:
> 
> Signed-off-by: Peter Meerwald-Stadler 
> ---
> src/modules/raop/raop-client.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
> index c6e1877..d329a09 100644
> --- a/src/modules/raop/raop-client.c
> +++ b/src/modules/raop/raop-client.c
> @@ -1034,9 +1034,9 @@ static void rtsp_stream_cb(pa_rtsp_client *rtsp, 
> pa_rtsp_state_t state, pa_rtsp_
> if ((pc = strstr(token, "="))) {
> *pc = 0;
> if (pa_streq(token, "control_port"))
> -pa_atou(pc + 1, );
> +(void) pa_atou(pc + 1, );
> if (pa_streq(token, "timing_port"))
> -pa_atou(pc + 1, );
> +(void) pa_atou(pc + 1, );

I think these should jump to `setup_error` in case of error instead of ignoring.

> *pc = '=';
> }
> pa_xfree(token);
> -- 
> 2.7.4
> 
> ___
> pulseaudio-discuss mailing list
> pulseaudio-discuss@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH v2 05/10] raop: Fix resource leaks

2017-03-06 Thread Hajime Fujita

> On Mar 6, 2017, at 1:43 AM, Peter Meerwald-Stadler  wrote:
> 
> Coverity ID: #1398158, #1398159
> 
> Signed-off-by: Peter Meerwald-Stadler 
> ---
> src/modules/raop/raop-client.c | 14 ++
> 1 file changed, 6 insertions(+), 8 deletions(-)
> 
> diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
> index 4c3083e..03558f6 100644
> --- a/src/modules/raop/raop-client.c
> +++ b/src/modules/raop/raop-client.c
> @@ -1223,7 +1223,7 @@ static void rtsp_auth_cb(pa_rtsp_client *rtsp, 
> pa_rtsp_state_t state, pa_rtsp_st
> static bool waiting = false;
> const char *current = NULL;
> char space[] = " ";
> -char *token,*ath = NULL;
> +char *token, *ath = NULL;
> char *publ, *wath, *mth, *val;

Should we initialize mth to NULL here to prevent freeing a random address later?
This could happen when `wath = pa_xstrdup(pa_headerlist_gets(headers, 
"WWW-Authenticate"));` becomes NULL.

> char *realm = NULL, *nonce = NULL, *response = NULL;
> char comma[] = ",";
> @@ -1260,9 +1260,6 @@ static void rtsp_auth_cb(pa_rtsp_client *rtsp, 
> pa_rtsp_state_t state, pa_rtsp_st
> pa_raop_basic_response(DEFAULT_USER_NAME, c->password, 
> );
> ath = pa_sprintf_malloc("Basic %s",
> response);
> -
> -pa_xfree(response);
> -pa_xfree(realm);
> } else if (pa_safe_streq(mth, "Digest")) {
> rtrim_char(realm, '\"');
> rtrim_char(nonce, '\"');
> @@ -1271,17 +1268,18 @@ static void rtsp_auth_cb(pa_rtsp_client *rtsp, 
> pa_rtsp_state_t state, pa_rtsp_st
> ath = pa_sprintf_malloc("Digest username=\"%s\", 
> realm=\"%s\", nonce=\"%s\", uri=\"*\", response=\"%s\"",
> DEFAULT_USER_NAME, realm, nonce,
> response);
> -
> -pa_xfree(response);
> -pa_xfree(realm);
> -pa_xfree(nonce);
> } else {
> pa_log_error("unsupported authentication method: %s", 
> mth);
> +pa_xfree(realm);
> +pa_xfree(nonce);
> pa_xfree(wath);
> pa_xfree(mth);
> goto error;
> }
> 
> +pa_xfree(response);
> +pa_xfree(realm);
> +pa_xfree(nonce);
> pa_xfree(wath);
> pa_xfree(mth);
> 
> -- 
> 2.7.4
> 
> ___
> pulseaudio-discuss mailing list
> pulseaudio-discuss@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH v2 10/10] raop: Fix potential NULL dereference

2017-03-06 Thread Hajime Fujita

> On Mar 6, 2017, at 1:43 AM, Peter Meerwald-Stadler  wrote:
> 
> 'realm' is mandatory
> 
> Signed-off-by: Peter Meerwald-Stadler 
> ---
> src/modules/raop/raop-client.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
> index d329a09..5248691 100644
> --- a/src/modules/raop/raop-client.c
> +++ b/src/modules/raop/raop-client.c
> @@ -1254,13 +1254,13 @@ static void rtsp_auth_cb(pa_rtsp_client *rtsp, 
> pa_rtsp_state_t state, pa_rtsp_st
> pa_xfree(token);
> }
> 
> -if (pa_safe_streq(mth, "Basic")) {
> +if (pa_safe_streq(mth, "Basic") && realm) {
> rtrim_char(realm, '\"’);

I would remove `rtrim_char(realm, '\"’);` from this block and keep the if 
condition as-is, since realm is not used later.

> 
> pa_raop_basic_response(DEFAULT_USER_NAME, c->password, 
> );
> ath = pa_sprintf_malloc("Basic %s",
> response);
> -} else if (pa_safe_streq(mth, "Digest")) {
> +} else if (pa_safe_streq(mth, "Digest") && realm && nonce) {

Why don’t we do like this:
+if (realm == NULL) {
+pa_log_error("realm not provided");
+goto error;
+} else if (nonce == NULL) {
+pa_log_error("nonce not provided");
+goto error;
+}

> rtrim_char(realm, '\"');
> rtrim_char(nonce, '\"');
> 
> -- 
> 2.7.4
> 
> ___
> pulseaudio-discuss mailing list
> pulseaudio-discuss@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH v7 00/33] raop2 support for module-raop-sink

2017-01-10 Thread Hajime Fujita
Hi Tanu and Anton,

> On Jan 10, 2017, at 5:57 PM, Tanu Kaskinen <ta...@iki.fi> wrote:
> 
> On Thu, 2017-01-05 at 22:34 +0100, Anton Lundin wrote:
>> On 06 November, 2016 - Hajime Fujita wrote:
>> 
>>> This patch set adds a support for UDP version of RAOP (so called
>>> raop2). Most of the RAOP devices (e.g. AppleTV, AirportExpress,
>>> third party AV receivers) today use UDP version, so this patch
>>> set is expected to support those devices.
>>> 
>> 
>> I've took a close look at the non-raop changes and those LGTM.
>> 
>> Feel free to add a Reviewed-by: Anton Lundin <gla...@acc.umu.se> to them
>> if you feel for it.
>> 
>> I've tested and glanced at the raop-code and it ain't perfect but its
>> way better than the current code for anything modern, so I'd suggest
>> merging this.
>> 
>> Feel free to add a Tested-by: Anton Lundin <gla...@acc.umu.se> to them
>> if you feel for it.

First, thank you Anton for taking a look at this patch set and supporting 
merging it.

> 
> Thanks, I pushed the three core-util patches to the "next" branch. I
> started to apply the rest of the patches too, but the first raop patch
> failed to build:
> 
>  CC   modules/raop/module_raop_sink_la-module-raop-sink.lo
> modules/raop/module-raop-sink.c: In function ‘udp_thread_func’:
> modules/raop/module-raop-sink.c:724:19: error: too many arguments to function 
> ‘pa_rtpoll_run’
> if ((rv = pa_rtpoll_run(u->rtpoll, true)) < 0)
>   ^
> In file included from ./pulsecore/source.h:41:0,
> from ./pulsecore/core.h:49,
> from ./pulsecore/sink.h:33,
> from modules/raop/module-raop-sink.c:44:
> ./pulsecore/rtpoll.h:61:5: note: declared here
> int pa_rtpoll_run(pa_rtpoll *f);
> ^
> Makefile:9124: recipe for target 
> 'modules/raop/module_raop_sink_la-module-raop-sink.lo' failed
> 
> Maybe that's fixed in later patches, but for bisecting it's best to
> avoid commits that break the build.

I thought I have fixed this before, but apparently it was incomplete. Sorry 
about that. It should have been fixed as you suggested.

> I also tried to build the whole patch set, but Debian has updated to
> openssl 1.1.0, and at the time when these patches were submitted, we
> didn't yet have the patch that fixes the compatibility issue with
> openssl 1.1.0, so that failed too. Trying to apply both the openssl fix
> and the raop patches results in conflicts.
> 
> These issues should be easy enough to resolve, and if there's nothing
> more complicated, I'll fix the issues myself and push the patches.

That’ll be awesome.
But if you need my help I’d be more than happy to do so.

> -- 
> Tanu
> 
> https://www.patreon.com/tanuk
> ___
> pulseaudio-discuss mailing list
> pulseaudio-discuss@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Thanks,
Hajime

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 32/33] raop: Fix #36: invalid access to freed object

2016-11-06 Thread Hajime Fujita
From: ced2c 

The RTSP client is not waiting anymore a new header after the
previous one (which can never occurs if RAOP is disconnected)
but after sending a command.

This patch fixes Issue #36.
https://github.com/hfujita/pulseaudio-raop2/issues/36
---
 src/modules/rtp/rtsp_client.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/modules/rtp/rtsp_client.c b/src/modules/rtp/rtsp_client.c
index fd5d2d8..34210f9 100644
--- a/src/modules/rtp/rtsp_client.c
+++ b/src/modules/rtp/rtsp_client.c
@@ -236,7 +236,6 @@ static void line_callback(pa_ioline *line, const char *s, 
void *userdata) {
 
 pa_log_debug("Full response received. Dispatching");
 headers_read(c);
-c->waiting = 1;
 goto exit;
 }
 
@@ -481,7 +480,8 @@ static int rtsp_exec(pa_rtsp_client *c, const char *cmd,
 pa_log_debug(hdrs);*/
 pa_ioline_puts(c->ioline, hdrs);
 pa_xfree(hdrs);
-
+/* The command is sent we can configure the rtsp client structure to 
handle a new answer */
+c->waiting = 1;
 return 0;
 }
 
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 31/33] raop: Fix memory leaks

2016-11-06 Thread Hajime Fujita
From: Hajime Fujita <crisp.fuj...@nifty.com>

This patch fixes several memory leaks, and thereby fixes Issue #35.
(https://github.com/hfujita/pulseaudio-raop2/issues/35)
---
 src/modules/raop/raop-client.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index f71ad9d..d695ce9 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -537,6 +537,7 @@ static ssize_t resend_udp_audio_packets(pa_raop_client *c, 
uint16_t seq, uint16_
 return total;
 }
 
+/* Caller has to free the allocated memory region for packet */
 static size_t build_udp_sync_packet(pa_raop_client *c, uint32_t stamp, 
uint32_t **packet) {
 const size_t size = sizeof(udp_sync_header) + 12;
 const uint32_t delay = 88200;
@@ -570,8 +571,10 @@ static ssize_t send_udp_sync_packet(pa_raop_client *c, 
uint32_t stamp) {
 size_t size = 0;
 
 size = build_udp_sync_packet(c, stamp, );
-if (packet != NULL && size > 0)
+if (packet != NULL && size > 0) {
 written = pa_loop_write(c->udp_cfd, packet, size, NULL);
+pa_xfree(packet);
+}
 
 return written;
 }
@@ -606,6 +609,7 @@ static size_t handle_udp_control_packet(pa_raop_client *c, 
const uint8_t packet[
 return written;
 }
 
+/* Caller has to free the allocated memory region for packet */
 static size_t build_udp_timing_packet(pa_raop_client *c, const uint32_t 
data[6], uint64_t received, uint32_t **packet) {
 const size_t size = sizeof(udp_timing_header) + 24;
 uint32_t *buffer = NULL;
@@ -638,8 +642,10 @@ static ssize_t send_udp_timing_packet(pa_raop_client *c, 
const uint32_t data[6],
 size_t size = 0;
 
 size = build_udp_timing_packet(c, data, received, );
-if (packet != NULL && size > 0)
+if (packet != NULL && size > 0) {
 written = pa_loop_write(c->udp_tfd, packet, size, NULL);
+pa_xfree(packet);
+}
 
 return written;
 }
@@ -1366,7 +1372,7 @@ pa_raop_client* pa_raop_client_new(pa_core *core, const 
char *host, pa_raop_prot
 
 c = pa_xnew0(pa_raop_client, 1);
 c->core = core;
-c->host = pa_xstrdup(a.path_or_host);
+c->host = a.path_or_host; /* Will eventually be freed on destruction of c 
*/
 if (a.port > 0)
 c->port = a.port;
 else
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 28/33] raop: Stop recording when RTSP FLUSH is issued

2016-11-06 Thread Hajime Fujita
From: Hajime Fujita <crisp.fuj...@nifty.com>

This patch fixes the issue #31.
https://github.com/hfujita/pulseaudio-raop2/issues/31

This patch sets c->is_recording = false when the RTSP FLUSH command
is issued. This avoids a race between the server response and
the record activation in some cases.
---
 src/modules/raop/raop-client.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index 52b2dee..bbef59d 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -1114,8 +1114,6 @@ static void rtsp_stream_cb(pa_rtsp_client *rtsp, 
pa_rtsp_state_t state, pa_rtsp_
 case STATE_FLUSH: {
 pa_log_debug("RAOP: FLUSHED");
 
-c->is_recording = false;
-
 break;
 }
 
@@ -1614,6 +1612,8 @@ int pa_raop_client_flush(pa_raop_client *c) {
 return 1;
 }
 
+c->is_recording = false;
+
 rv = pa_rtsp_flush(c->rtsp, c->seq, c->rtptime);
 return rv;
 }
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 25/33] raop: Correctly wrap RTP packet sequence number

2016-11-06 Thread Hajime Fujita
From: Martin Blanchard 

---
 src/modules/raop/raop-client.c| 27 +++---
 src/modules/raop/raop-packet-buffer.c | 70 ---
 src/modules/raop/raop-packet-buffer.h |  5 ++-
 3 files changed, 65 insertions(+), 37 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index 574f10b..52b2dee 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -24,6 +24,7 @@
 #endif
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -316,10 +317,10 @@ static size_t build_tcp_audio_packet(pa_raop_client *c, 
pa_memchunk *block, pa_m
 buffer += packet->index / sizeof(uint32_t);
 raw += block->index;
 
-if (c->seq == 0x) {
-pa_log_debug("wrapping sequence number");
-c->seq = pa_raop_packet_buffer_wrap_seq(c->pbuf, c->seq);
-} else
+/* Wrap sequence number to 0 then UINT16_MAX is reached */
+if (c->seq == UINT16_MAX)
+c->seq = 0;
+else
 c->seq++;
 
 memcpy(buffer, tcp_audio_header, sizeof(tcp_audio_header));
@@ -360,13 +361,13 @@ static ssize_t send_tcp_audio_packet(pa_raop_client *c, 
pa_memchunk *block, size
 ssize_t written = -1;
 size_t done = 0;
 
-if (!(packet = pa_raop_packet_buffer_get(c->pbuf, c->seq, max)))
+if (!(packet = pa_raop_packet_buffer_retrieve(c->pbuf, c->seq)))
 return -1;
 
 if (packet->length <= 0) {
 pa_assert(block->index == offset);
 
-if (!(packet = pa_raop_packet_buffer_get(c->pbuf, c->seq + 1, max)))
+if (!(packet = pa_raop_packet_buffer_prepare(c->pbuf, c->seq + 1, 
max)))
 return -1;
 
 packet->index = 0;
@@ -427,10 +428,10 @@ static size_t build_udp_audio_packet(pa_raop_client *c, 
pa_memchunk *block, pa_m
 
 c->rtptime += length / 4;
 
-if (c->seq == 0x) {
-pa_log_debug("wrapping sequence number");
-c->seq = pa_raop_packet_buffer_wrap_seq(c->pbuf, c->seq);
-} else
+/* Wrap sequence number to 0 then UINT16_MAX is reached */
+if (c->seq == UINT16_MAX)
+c->seq = 0;
+else
 c->seq++;
 
 pa_memblock_release(block->memblock);
@@ -453,11 +454,11 @@ static ssize_t send_udp_audio_packet(pa_raop_client *c, 
pa_memchunk *block, size
 /* UDP packet has to be sent at once ! */
 pa_assert(block->index == offset);
 
-if (!(packet = pa_raop_packet_buffer_get(c->pbuf, c->seq, max)))
+if (!(packet = pa_raop_packet_buffer_prepare(c->pbuf, c->seq, max)))
 return -1;
 
-packet->length = max;
 packet->index = sizeof(udp_audio_retrans_header);
+packet->length = max - sizeof(udp_audio_retrans_header);
 if (!build_udp_audio_packet(c, block, packet))
 return -1;
 
@@ -508,7 +509,7 @@ static ssize_t resend_udp_audio_packets(pa_raop_client *c, 
uint16_t seq, uint16_
 uint8_t *buffer = NULL;
 ssize_t written = -1;
 
-if (!(packet = pa_raop_packet_buffer_get(c->pbuf, seq + i, 0)))
+if (!(packet = pa_raop_packet_buffer_retrieve(c->pbuf, seq + i)))
 continue;
 
 if (packet->index > 0) {
diff --git a/src/modules/raop/raop-packet-buffer.c 
b/src/modules/raop/raop-packet-buffer.c
index 4c45d18..05f9592 100644
--- a/src/modules/raop/raop-packet-buffer.c
+++ b/src/modules/raop/raop-packet-buffer.c
@@ -25,6 +25,7 @@
 #endif
 
 #include 
+#include 
 #include 
 
 #include 
@@ -37,7 +38,9 @@
 struct pa_raop_packet_buffer {
 pa_memchunk *packets;
 pa_mempool *mempool;
+
 size_t size;
+size_t count;
 
 uint16_t seq;
 size_t pos;
@@ -49,6 +52,7 @@ pa_raop_packet_buffer *pa_raop_packet_buffer_new(pa_mempool 
*mempool, const size
 pa_assert(mempool);
 pa_assert(size > 0);
 
+pb->count = 0;
 pb->size = size;
 pb->mempool = mempool;
 pb->packets = pa_xnew0(pa_memchunk, size);
@@ -80,7 +84,8 @@ void pa_raop_packet_buffer_reset(pa_raop_packet_buffer *pb, 
uint16_t seq) {
 pa_assert(pb->packets);
 
 pb->pos = 0;
-pb->seq = seq - 1;
+pb->count = 0;
+pb->seq = (!seq) ? UINT16_MAX : seq - 1;
 for (i = 0; i < pb->size; i++) {
 if (pb->packets[i].memblock)
 pa_memblock_unref(pb->packets[i].memblock);
@@ -88,23 +93,43 @@ void pa_raop_packet_buffer_reset(pa_raop_packet_buffer *pb, 
uint16_t seq) {
 }
 }
 
-uint16_t pa_raop_packet_buffer_wrap_seq(pa_raop_packet_buffer *pb, uint16_t 
seq) {
-int seq_shift;
+pa_memchunk *pa_raop_packet_buffer_prepare(pa_raop_packet_buffer *pb, uint16_t 
seq, const size_t size) {
+pa_memchunk *packet = NULL;
+size_t i;
 
 pa_assert(pb);
+pa_assert(pb->packets);
+
+if (seq == 0) {
+/* 0 means seq reached UINT16_MAX and has been wrapped... */
+pa_assert(pb->seq == UINT16_MAX);
+pb->seq = 0;
+} else {
+/* ...otherwise, seq MUST have be increased! */
+pa_assert(seq == pb->seq + 1);
+pb->seq++;
+}
+
+i = (pb->pos + 1) % 

[pulseaudio-discuss] [PATCH v7 29/33] raop: Disable is_recording flag when tearing down the connection

2016-11-06 Thread Hajime Fujita
From: Hajime Fujita <crisp.fuj...@nifty.com>

This patch is based on a similar idea as the previous one -- disabling
the flag right after the session is getting closed, rather than waiting
for a response from the server.
---
 src/modules/raop/raop-client.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index bbef59d..68d188a 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -1120,8 +1120,6 @@ static void rtsp_stream_cb(pa_rtsp_client *rtsp, 
pa_rtsp_state_t state, pa_rtsp_
 case STATE_TEARDOWN: {
 pa_log_debug("RAOP: TEARDOWN");
 
-c->is_recording = false;
-
 if (c->tcp_sfd > 0)
 pa_close(c->tcp_sfd);
 c->tcp_sfd = -1;
@@ -1631,6 +1629,8 @@ int pa_raop_client_teardown(pa_raop_client *c) {
 return 1;
 }
 
+c->is_recording = false;
+
 rv = pa_rtsp_teardown(c->rtsp);
 return rv;
 }
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 30/33] raop: Discard data upon getting EAGAIN on a socket

2016-11-06 Thread Hajime Fujita
From: Hajime Fujita <crisp.fuj...@nifty.com>

This patch discards audio data when a socket returns EAGAIN.
This was made based on a suggestion by karlstav
(https://github.com/karlstav), and is supposed to solve Issue #32.
(https://github.com/hfujita/pulseaudio-raop2/issues/32)
---
 src/modules/raop/raop-client.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index 68d188a..f71ad9d 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -471,8 +471,7 @@ static ssize_t send_udp_audio_packet(pa_raop_client *c, 
pa_memchunk *block, size
 written = pa_write(c->udp_sfd, buffer, packet->length, NULL);
 if (written < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
 pa_log_debug("Discarding UDP (audio, seq=%d) packet due to EAGAIN 
(%s)", c->seq, pa_cstrerror(errno));
-pa_memblock_release(packet->memblock);
-return (ssize_t) packet->length;
+written = packet->length;
 }
 
 pa_memblock_release(packet->memblock);
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 27/33] raop: Add back initial volume RTSP SET_PARAMETER request on connect

2016-11-06 Thread Hajime Fujita
From: Martin Blanchard 

Regression introduced in commit 8c6407f:
raop: Merge TCP and UDP code paths + refactoring

Anyway, we need to determine if initial volume has to be setup before
sending RECORD or after:

- Setting it up *before* shouldn't be a problem: sink.c waits for
CONNECT state, set the volume and client.c triggers RECORD only once
he's got the SET_PARAMETER reply from server.

- Setting it up *after* seems to be more difficult if we try not to
send any audio before receiving the SET_PARAMETER reply form server. A
solution may be to send SET_PARAMETER just after the RECORD server
response is received and hope that it get processed by server during the
2sec latency/buffering time...

Attached patch implement that last solution. Works for me, but I cannot
guaranty it will with your hardware...
---
 src/modules/raop/raop-sink.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/src/modules/raop/raop-sink.c b/src/modules/raop/raop-sink.c
index 2d8157e..6b707cf 100644
--- a/src/modules/raop/raop-sink.c
+++ b/src/modules/raop/raop-sink.c
@@ -95,6 +95,8 @@ enum {
 
 static void userdata_free(struct userdata *u);
 
+static void sink_set_volume_cb(pa_sink *s);
+
 static void raop_state_cb(pa_raop_state_t state, void *userdata) {
 struct userdata *u = userdata;
 
@@ -228,6 +230,9 @@ static int sink_process_msg(pa_msgobject *o, int code, void 
*data, int64_t offse
 /* Our stream has been suspended so we just flush 
it... */
 pa_rtpoll_set_timer_disabled(u->rtpoll);
 pa_raop_client_flush(u->raop);
+} else {
+/* Set the initial volume */
+sink_set_volume_cb(u->sink);
 }
 
 return 0;
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 24/33] raop: Add IPv6 support

2016-11-06 Thread Hajime Fujita
From: Hajime Fujita <crisp.fuj...@nifty.com>

---
 src/modules/raop/raop-client.c | 23 ---
 src/modules/rtp/rtsp_client.c  |  2 +-
 2 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index cf415d0..574f10b 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -752,6 +752,7 @@ static int open_bind_udp_socket(pa_raop_client *c, uint16_t 
*actual_port) {
 if (inet_pton(AF_INET, pa_rtsp_localip(c->rtsp), _addr) > 0) {
 sa4.sin_family = af = AF_INET;
 sa4.sin_port = htons(port);
+sa4.sin_addr.s_addr = INADDR_ANY;
 sa = (struct sockaddr *) 
 salen = sizeof(sa4);
 sa_port = _port;
@@ -759,6 +760,7 @@ static int open_bind_udp_socket(pa_raop_client *c, uint16_t 
*actual_port) {
 } else if (inet_pton(AF_INET6, pa_rtsp_localip(c->rtsp), _addr) > 
0) {
 sa6.sin6_family = af = AF_INET6;
 sa6.sin6_port = htons(port);
+sa6.sin6_addr = in6addr_any;
 sa = (struct sockaddr *) 
 salen = sizeof(sa6);
 sa_port = _port;
@@ -849,11 +851,18 @@ static void rtsp_stream_cb(pa_rtsp_client *rtsp, 
pa_rtsp_state_t state, pa_rtsp_
 int frames = 0;
 const char *ip;
 char *url;
+int ipv;
 
 pa_log_debug("RAOP: CONNECTED");
 
 ip = pa_rtsp_localip(c->rtsp);
-url = pa_sprintf_malloc("rtsp://%s/%s", ip, c->sid);
+if (pa_is_ip6_address(ip)) {
+ipv = 6;
+url = pa_sprintf_malloc("rtsp://[%s]/%s", ip, c->sid);
+} else {
+ipv = 4;
+url = pa_sprintf_malloc("rtsp://%s/%s", ip, c->sid);
+}
 pa_rtsp_set_url(c->rtsp, url);
 
 if (c->protocol == PA_RAOP_PROTOCOL_TCP)
@@ -865,14 +874,14 @@ static void rtsp_stream_cb(pa_rtsp_client *rtsp, 
pa_rtsp_state_t state, pa_rtsp_
 case PA_RAOP_ENCRYPTION_NONE: {
 sdp = pa_sprintf_malloc(
 "v=0\r\n"
-"o=iTunes %s 0 IN IP4 %s\r\n"
+"o=iTunes %s 0 IN IP%d %s\r\n"
 "s=iTunes\r\n"
-"c=IN IP4 %s\r\n"
+"c=IN IP%d %s\r\n"
 "t=0 0\r\n"
 "m=audio 0 RTP/AVP 96\r\n"
 "a=rtpmap:96 AppleLossless\r\n"
 "a=fmtp:96 %d 0 16 40 10 14 2 255 0 0 44100\r\n",
-c->sid, ip, c->host, frames);
+c->sid, ipv, ip, ipv, c->host, frames);
 
 break;
 }
@@ -886,16 +895,16 @@ static void rtsp_stream_cb(pa_rtsp_client *rtsp, 
pa_rtsp_state_t state, pa_rtsp_
 
 sdp = pa_sprintf_malloc(
 "v=0\r\n"
-"o=iTunes %s 0 IN IP4 %s\r\n"
+"o=iTunes %s 0 IN IP%d %s\r\n"
 "s=iTunes\r\n"
-"c=IN IP4 %s\r\n"
+"c=IN IP%d %s\r\n"
 "t=0 0\r\n"
 "m=audio 0 RTP/AVP 96\r\n"
 "a=rtpmap:96 AppleLossless\r\n"
 "a=fmtp:96 %d 0 16 40 10 14 2 255 0 0 44100\r\n"
 "a=rsaaeskey:%s\r\n"
 "a=aesiv:%s\r\n",
-c->sid, ip, c->host, frames, key, iv);
+c->sid, ipv, ip, ipv, c->host, frames, key, iv);
 
 pa_xfree(key);
 pa_xfree(iv);
diff --git a/src/modules/rtp/rtsp_client.c b/src/modules/rtp/rtsp_client.c
index 31b8673..fd5d2d8 100644
--- a/src/modules/rtp/rtsp_client.c
+++ b/src/modules/rtp/rtsp_client.c
@@ -330,7 +330,7 @@ static void on_connection(pa_socket_client *sc, 
pa_iochannel *io, void *userdata
 }
 } else if (AF_INET6 == sa.sa.sa_family) {
 if ((res = inet_ntop(AF_INET6, _addr, buf, 
sizeof(buf {
-c->localip = pa_sprintf_malloc("[%s]", res);
+c->localip = pa_xstrdup(res);
 }
 }
 }
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 22/33] raop: Do not flush when RTSP object is not ready

2016-11-06 Thread Hajime Fujita
From: Stephen Paul Weber 

This patch fixes a crash issue reported at
https://github.com/hfujita/pulseaudio-raop2/issues/9
---
 src/modules/raop/raop-client.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index 90488e4..cf415d0 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -1596,7 +1596,7 @@ int pa_raop_client_flush(pa_raop_client *c) {
 
 pa_assert(c);
 
-if (!c->rtsp) {
+if (!c->rtsp || !pa_rtsp_exec_ready(c->rtsp)) {
 pa_log_debug("Cannot FLUSH, connection not established yet...)");
 return 0;
 } else if (!c->sci) {
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 20/33] raop: fix typos

2016-11-06 Thread Hajime Fujita
From: Colin Leroy 

---
 src/modules/raop/raop-client.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index 8dc05a4..8a43a19 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -174,14 +174,14 @@ static const uint8_t udp_sync_header[8] = {
 0x00, 0x00, 0x00, 0x00
 };
 
-/* Timming packet header [8x8] (cf. rfc3550):
+/* Timing packet header [8x8] (cf. rfc3550):
  *  [0]   RTP v2: 0x80
  *  [1]   Payload type: 0x53 | Marker bit: 0x80 (always set)
  *  [2,3] Sequence number: 0x0007
  *  [4,7] Timestamp: 0x (unused) */
 #define PAYLOAD_TIMING_REQUEST  0x52
 #define PAYLOAD_TIMING_REPLY0x53
-static const uint8_t udp_timming_header[8] = {
+static const uint8_t udp_timing_header[8] = {
 0x80, 0xd3, 0x00, 0x07,
 0x00, 0x00, 0x00, 0x00
 };
@@ -587,7 +587,7 @@ static size_t handle_udp_control_packet(pa_raop_client *c, 
const uint8_t packet[
 if (nbp <= 0)
 return 1;
 
-/* The market bit is always set (see rfc3550 for packet structure) ! */
+/* The marker bit is always set (see rfc3550 for packet structure) ! */
 payload = packet[1] ^ 0x80;
 switch (payload) {
 case PAYLOAD_RETRANSMIT_REQUEST:
@@ -604,7 +604,7 @@ static size_t handle_udp_control_packet(pa_raop_client *c, 
const uint8_t packet[
 }
 
 static size_t build_udp_timing_packet(pa_raop_client *c, const uint32_t 
data[6], uint64_t received, uint32_t **packet) {
-const size_t size = sizeof(udp_timming_header) + 24;
+const size_t size = sizeof(udp_timing_header) + 24;
 uint32_t *buffer = NULL;
 uint64_t transmitted = 0;
 struct timeval tv;
@@ -613,7 +613,7 @@ static size_t build_udp_timing_packet(pa_raop_client *c, 
const uint32_t data[6],
 if (!(buffer = pa_xmalloc0(size)))
 return 0;
 
-memcpy(buffer, udp_timming_header, sizeof(udp_timming_header));
+memcpy(buffer, udp_timing_header, sizeof(udp_timing_header));
 /* Copying originate timestamp from the incoming request packet. */
 buffer[2] = data[4];
 buffer[3] = data[5];
@@ -653,9 +653,9 @@ static size_t handle_udp_timing_packet(pa_raop_client *c, 
const uint8_t packet[]
 return 0;
 
 rci = timeval_to_ntp(pa_rtclock_get());
-data = (uint32_t *) (packet + sizeof(udp_timming_header));
+data = (uint32_t *) (packet + sizeof(udp_timing_header));
 
-/* The market bit is always set (see rfc3550 for packet structure) ! */
+/* The marker bit is always set (see rfc3550 for packet structure) ! */
 payload = packet[1] ^ 0x80;
 switch (payload) {
 case PAYLOAD_TIMING_REQUEST:
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 23/33] raop: Add address to RAOP device description

2016-11-06 Thread Hajime Fujita
From: Hajime Fujita <crisp.fuj...@nifty.com>

Some time one device announces multiple addresses (e.g. IPv4 one
and IPv6 one). Or some user may own multiple RAOP devices with
the same model name.
This patch adds device port to device description so that users
can distinguish appropriate RAOP sink by its address.
---
 src/modules/raop/module-raop-discover.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/src/modules/raop/module-raop-discover.c 
b/src/modules/raop/module-raop-discover.c
index bf05dec..c0b4549 100644
--- a/src/modules/raop/module-raop-discover.c
+++ b/src/modules/raop/module-raop-discover.c
@@ -241,19 +241,22 @@ static void resolver_cb(
 avahi_free(device);
 pa_xfree(dname);
 
+avahi_address_snprint(at, sizeof(at), a);
 if (nicename) {
 args = pa_sprintf_malloc("server=[%s]:%u "
  "sink_name=%s "
- "sink_properties='device.description=\"%s\"'",
- avahi_address_snprint(at, sizeof(at), a), 
port,
+ "sink_properties='device.description=\"%s 
(%s:%u)\"'",
+ at, port,
  vname,
- nicename);
+ nicename, at, port);
 pa_xfree(nicename);
 } else {
 args = pa_sprintf_malloc("server=[%s]:%u "
- "sink_name=%s",
- avahi_address_snprint(at, sizeof(at), a), 
port,
- vname);
+ "sink_name=%s"
+ 
"sink_properties='device.description=\"%s:%u\"'",
+ at, port,
+ vname,
+ at, port);
 }
 
 if (tp != NULL) {
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 26/33] raop: Silently drop out-of-history retransmission request

2016-11-06 Thread Hajime Fujita
From: Hajime Fujita <crisp.fuj...@nifty.com>

---
 src/modules/raop/raop-packet-buffer.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/modules/raop/raop-packet-buffer.c 
b/src/modules/raop/raop-packet-buffer.c
index 05f9592..72fd729 100644
--- a/src/modules/raop/raop-packet-buffer.c
+++ b/src/modules/raop/raop-packet-buffer.c
@@ -142,13 +142,15 @@ pa_memchunk 
*pa_raop_packet_buffer_retrieve(pa_raop_packet_buffer *pb, uint16_t
 if (seq < pb->seq) {
 /* Regular case: pb->seq did not wrapped since seq. */
 delta = pb->seq - seq;
-pa_assert(delta <= pb->count);
 } else {
 /* Tricky case: pb->seq wrapped since seq! */
 delta = pb->seq + (UINT16_MAX - seq);
-pa_assert(delta <= pb->count);
 }
 
+/* If the requested packet is too old, do nothing and return */
+if (delta > pb->count)
+return NULL;
+
 i = (pb->size + pb->pos - delta) % pb->size;
 
 if (delta < pb->size && pb->packets[i].memblock)
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 11/33] raop: Add a MD5 hashing fuction

2016-11-06 Thread Hajime Fujita
From: Martin Blanchard <tch...@gmx.com>

MD5 hashing will be needed during the authentication process.

Original patch by Martin Blanchard. Patch splitted by
Hajime Fujita <crisp.fuj...@nifty.com>.
---
 src/modules/raop/raop_util.c | 27 +++
 src/modules/raop/raop_util.h |  2 ++
 2 files changed, 29 insertions(+)

diff --git a/src/modules/raop/raop_util.c b/src/modules/raop/raop_util.c
index d24d67d..c9021ec 100644
--- a/src/modules/raop/raop_util.c
+++ b/src/modules/raop/raop_util.c
@@ -30,12 +30,21 @@
 #include 
 #include 
 
+#include 
+#include 
+
 #include 
 
 #include 
 
 #include "raop_util.h"
 
+#ifndef MD5_DIGEST_LENGTH
+#define MD5_DIGEST_LENGTH 16
+#endif
+
+#define MD5_HASH_LENGTH (2*MD5_DIGEST_LENGTH)
+
 #define BASE64_DECODE_ERROR 0x
 
 static const char base64_chars[] =
@@ -141,3 +150,21 @@ int pa_raop_base64_decode(const char *str, void *data) {
 
 return q - (unsigned char *) data;
 }
+
+int pa_raop_md5_hash(const char *data, int len, char **str) {
+unsigned char d[MD5_DIGEST_LENGTH];
+char *s = NULL;
+int i;
+
+pa_assert(data);
+pa_assert(str);
+
+MD5((unsigned char*) data, len, d);
+s = pa_xnew(char, MD5_HASH_LENGTH);
+for (i = 0; i < MD5_DIGEST_LENGTH; i++)
+sprintf([2*i], "%02x", (unsigned int) d[i]);
+
+*str = s;
+s[MD5_HASH_LENGTH] = 0;
+return strlen(s);
+}
diff --git a/src/modules/raop/raop_util.h b/src/modules/raop/raop_util.h
index 7a8d73e..dc0b767 100644
--- a/src/modules/raop/raop_util.h
+++ b/src/modules/raop/raop_util.h
@@ -30,4 +30,6 @@
 int pa_raop_base64_encode(const void *data, int len, char **str);
 int pa_raop_base64_decode(const char *str, void *data);
 
+int pa_raop_md5_hash(const char *data, int len, char **str);
+
 #endif
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 16/33] raop: Rework packet's store memory management

2016-11-06 Thread Hajime Fujita
From: Martin Blanchard 

This patch switch the packet-buffer to use core memory pool instead of
manually allocating the room required for storing TCP/UDP packets. Packets
are now stored using pa_memchunk instead of internal struct. Quite a few
malloc saved compare to previous design.
---
 src/modules/raop/raop-client.c| 261 ++
 src/modules/raop/raop-packet-buffer.c | 187 +---
 src/modules/raop/raop-packet-buffer.h |  17 +--
 src/modules/raop/raop-sink.c  |   4 +-
 4 files changed, 216 insertions(+), 253 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index f1e5970..195b00c 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -65,6 +65,8 @@
 #define FRAMES_PER_TCP_PACKET 4096
 #define FRAMES_PER_UDP_PACKET 352
 
+#define RTX_BUFFERING_SECONDS 4
+
 #define DEFAULT_TCP_AUDIO_PORT   6000
 #define DEFAULT_UDP_AUDIO_PORT   6000
 #define DEFAULT_UDP_CONTROL_PORT 6001
@@ -323,92 +325,102 @@ static size_t write_AAC_data(uint8_t *packet, const 
size_t max, uint8_t *raw, si
 return size;
 }
 
-static size_t build_tcp_audio_packet(pa_raop_client *c, uint8_t *raw, size_t 
*index, size_t *length, uint32_t **packet) {
-const size_t max = sizeof(tcp_audio_header) + 8 + 16384;
+static size_t build_tcp_audio_packet(pa_raop_client *c, pa_memchunk *block, 
pa_memchunk *packet) {
+const size_t head = sizeof(tcp_audio_header);
 uint32_t *buffer = NULL;
-size_t size, head;
+uint8_t *raw = NULL;
+size_t length, size;
 
-*packet = NULL;
-if (!(buffer = pa_xmalloc0(max)))
-return 0;
+raw = pa_memblock_acquire(block->memblock);
+buffer = pa_memblock_acquire(packet->memblock);
+buffer += packet->index / sizeof(uint32_t);
+raw += block->index;
 
-size = head = sizeof(tcp_audio_header);
+c->seq++;
 memcpy(buffer, tcp_audio_header, sizeof(tcp_audio_header));
 buffer[1] |= htonl((uint32_t) c->seq);
 buffer[2] = htonl(c->rtptime);
 buffer[3] = htonl(c->ssrc);
 
+length = block->length;
+size = sizeof(tcp_audio_header);
 if (c->codec == PA_RAOP_CODEC_PCM)
-size += write_PCM_data(((uint8_t *) buffer + head), max - head, raw, 
length);
+size += write_PCM_data(((uint8_t *) buffer + head), packet->length - 
head, raw, );
 else if (c->codec == PA_RAOP_CODEC_ALAC)
-size += write_ALAC_data(((uint8_t *) buffer + head), max - head, raw, 
length, false);
+size += write_ALAC_data(((uint8_t *) buffer + head), packet->length - 
head, raw, , false);
 else
-size += write_AAC_data(((uint8_t *) buffer + head), max - head, raw, 
length);
-c->rtptime += *length / 4;
+size += write_AAC_data(((uint8_t *) buffer + head), packet->length - 
head, raw, );
+c->rtptime += length / 4;
+
+pa_memblock_release(block->memblock);
 
 buffer[0] |= htonl((uint32_t) size - 4);
 if (c->encryption == PA_RAOP_ENCRYPTION_RSA)
 pa_raop_aes_encrypt(c->secret, (uint8_t *) buffer + head, size - head);
 
-*packet = buffer;
+pa_memblock_release(packet->memblock);
+packet->length = size;
+
 return size;
 }
 
 static ssize_t send_tcp_audio_packet(pa_raop_client *c, pa_memchunk *block, 
size_t offset) {
-static uint32_t * packet = NULL;
-static size_t size, sent;
+static int write_type = 0;
+const size_t max = sizeof(tcp_audio_header) + 8 + 16384;
+pa_memchunk *packet = NULL;
+uint8_t *buffer = NULL;
 double progress = 0.0;
-size_t index, length;
-uint8_t *raw = NULL;
-ssize_t written;
+ssize_t written = -1;
+size_t done = 0;
+
+if (!(packet = pa_raop_packet_buffer_get(c->pbuf, c->seq, max)))
+return -1;
 
-if (!packet) {
-index = block->index;
-length = block->length;
-raw = pa_memblock_acquire(block->memblock);
+if (packet->length <= 0) {
+pa_assert(block->index == offset);
 
-pa_assert(raw);
-pa_assert(index == offset);
-pa_assert(length > 0);
+if (!(packet = pa_raop_packet_buffer_get(c->pbuf, c->seq + 1, max)))
+return -1;
 
-size = build_tcp_audio_packet(c, raw, , , );
-sent = 0;
+packet->index = 0;
+packet->length = max;
+if (!build_tcp_audio_packet(c, block, packet))
+return -1;
 }
 
-written = -1;
-if (packet != NULL && size > 0)
-written = pa_write(c->tcp_sfd, packet + sent, size - sent, NULL);
-if (block->index == offset)
-c->seq++;
-if (sent == 0)
-pa_memblock_release(block->memblock);
+buffer = pa_memblock_acquire(packet->memblock);
+
+pa_assert(buffer);
+
+buffer += packet->index;
+if (buffer && packet->length > 0)
+written = pa_write(c->tcp_sfd, buffer, packet->length, _type);
 if (written > 0) {
-sent += written;
-progress = (double) sent / 

[pulseaudio-discuss] [PATCH v7 15/33] raop: Update and standardise source file headers

2016-11-06 Thread Hajime Fujita
From: Martin Blanchard <tch...@gmx.com>

---
 src/modules/raop/raop-client.c|  2 ++
 src/modules/raop/raop-packet-buffer.c | 11 +--
 src/modules/raop/raop-packet-buffer.h | 17 -
 src/modules/raop/raop-sink.c  |  1 +
 src/modules/raop/raop-util.c  |  3 ++-
 5 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index 813b161..f1e5970 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -2,6 +2,8 @@
   This file is part of PulseAudio.
 
   Copyright 2008 Colin Guthrie
+  Copyright 2013 Hajime Fujita
+  Copyright 2013 Martin Blanchard
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
diff --git a/src/modules/raop/raop-packet-buffer.c 
b/src/modules/raop/raop-packet-buffer.c
index ef8ea15..d9d8549 100644
--- a/src/modules/raop/raop-packet-buffer.c
+++ b/src/modules/raop/raop-packet-buffer.c
@@ -1,15 +1,15 @@
 /***
-  Circular buffer for RTP audio packets with random access support
-  by RTP sequence number.
+  This file is part of PulseAudio.
 
-  Copyright 2013 Matthias Wabersich, Hajime Fujita
+  Copyright 2013 Matthias Wabersich
+  Copyright 2013 Hajime Fujita
 
-  This is free software; you can redistribute it and/or modify
+  PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
   by the Free Software Foundation; either version 2.1 of the License,
   or (at your option) any later version.
 
-  This is distributed in the hope that it will be useful, but
+  PulseAudio 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.
@@ -18,7 +18,6 @@
   along with PulseAudio; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
   USA.
-
 ***/
 
 #include 
diff --git a/src/modules/raop/raop-packet-buffer.h 
b/src/modules/raop/raop-packet-buffer.h
index d8a08a0..69a0ce1 100644
--- a/src/modules/raop/raop-packet-buffer.h
+++ b/src/modules/raop/raop-packet-buffer.h
@@ -1,18 +1,18 @@
-#ifndef RAOP_PACKET_BUFFER_H_INCLUDED
-#define RAOP_PACKET_BUFFER_H_INCLUDED
+#ifndef fooraoppacketbufferfoo
+#define fooraoppacketbufferfoo
 
 /***
-  Circular buffer for RTP audio packets with random access support
-  by RTP sequence number.
+  This file is part of PulseAudio.
 
-  Copyright 2013 Matthias Wabersich, Hajime Fujita
+  Copyright 2013 Matthias Wabersich
+  Copyright 2013 Hajime Fujita
 
-  This is free software; you can redistribute it and/or modify
+  PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
   by the Free Software Foundation; either version 2.1 of the License,
   or (at your option) any later version.
 
-  This is distributed in the hope that it will be useful, but
+  PulseAudio 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.
@@ -21,7 +21,6 @@
   along with PulseAudio; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
   USA.
-
 ***/
 
 struct pa_raop_packet_element;
@@ -39,4 +38,4 @@ void pa_raop_pb_delete(pa_raop_packet_buffer *pb);
 void pa_raop_pb_write_packet(pa_raop_packet_buffer *pb, uint16_t seq_num, 
const uint8_t *packet_data, ssize_t packet_length);
 ssize_t pa_raop_pb_read_packet(pa_raop_packet_buffer *pb, uint16_t seq_num, 
uint8_t **packet_data);
 
-#endif /* RAOP_PACKET_BUFFER_H_INCLUDED */
+#endif
diff --git a/src/modules/raop/raop-sink.c b/src/modules/raop/raop-sink.c
index 4f743be..22b1ccc 100644
--- a/src/modules/raop/raop-sink.c
+++ b/src/modules/raop/raop-sink.c
@@ -3,6 +3,7 @@
 
   Copyright 2004-2006 Lennart Poettering
   Copyright 2008 Colin Guthrie
+  Copyright 2013 Hajime Fujita
   Copyright 2013 Martin Blanchard
 
   PulseAudio is free software; you can redistribute it and/or modify
diff --git a/src/modules/raop/raop-util.c b/src/modules/raop/raop-util.c
index 3e3eb00..febc204 100644
--- a/src/modules/raop/raop-util.c
+++ b/src/modules/raop/raop-util.c
@@ -1,8 +1,9 @@
 /***
   This file is part of PulseAudio.
 
+  Copyright 2008 Colin Guthrie
+  Copyright Kungliga Tekniska högskolan
   Copyright 2013 Martin Blanchard
-  Copyright Kungliga Tekniska Høgskolan & Colin Guthrie
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
-- 
2.9.3

___
pulseaudio-discuss ma

[pulseaudio-discuss] [PATCH v7 18/33] raop: Fix sink getting destroyed after one use

2016-11-06 Thread Hajime Fujita
From: Colin Leroy 

It is expected to get disconnected after switching back to a
different sink.
---
 src/modules/raop/raop-sink.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/modules/raop/raop-sink.c b/src/modules/raop/raop-sink.c
index 23989d1..2d8157e 100644
--- a/src/modules/raop/raop-sink.c
+++ b/src/modules/raop/raop-sink.c
@@ -252,7 +252,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void 
*data, int64_t offse
 
 if (u->sink->thread_info.state == PA_SINK_SUSPENDED)
 pa_rtpoll_set_timer_disabled(u->rtpoll);
-else
+else if (u->sink->thread_info.state != PA_SINK_IDLE)
 pa_module_unload_request(u->module, true);
 
 return 0;
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 17/33] raop: Remove unimplemented code (PCM and AAC)

2016-11-06 Thread Hajime Fujita
From: Martin Blanchard 

---
 src/modules/raop/raop-client.c | 44 ++
 1 file changed, 14 insertions(+), 30 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index 195b00c..81a68a0 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -267,16 +267,6 @@ static inline void bit_writer(uint8_t **buffer, uint8_t 
*bit_pos, size_t *size,
 }
 }
 
-static size_t write_PCM_data(uint8_t *packet, const size_t max, uint8_t *raw, 
size_t *length) {
-size_t size = 0;
-
-pa_memzero(packet, max);
-
-pa_log("Raw PCM not implemented...");
-
-return size;
-}
-
 static size_t write_ALAC_data(uint8_t *packet, const size_t max, uint8_t *raw, 
size_t *length, bool compress) {
 uint32_t nbs = (*length / 2) / 2;
 uint8_t *ibp, *maxibp;
@@ -315,16 +305,6 @@ static size_t write_ALAC_data(uint8_t *packet, const 
size_t max, uint8_t *raw, s
 return size;
 }
 
-static size_t write_AAC_data(uint8_t *packet, const size_t max, uint8_t *raw, 
size_t *length) {
-size_t size = 0;
-
-pa_memzero(packet, max);
-
-pa_log("AAC encoding not implemented...");
-
-return size;
-}
-
 static size_t build_tcp_audio_packet(pa_raop_client *c, pa_memchunk *block, 
pa_memchunk *packet) {
 const size_t head = sizeof(tcp_audio_header);
 uint32_t *buffer = NULL;
@@ -344,12 +324,14 @@ static size_t build_tcp_audio_packet(pa_raop_client *c, 
pa_memchunk *block, pa_m
 
 length = block->length;
 size = sizeof(tcp_audio_header);
-if (c->codec == PA_RAOP_CODEC_PCM)
-size += write_PCM_data(((uint8_t *) buffer + head), packet->length - 
head, raw, );
-else if (c->codec == PA_RAOP_CODEC_ALAC)
+if (c->codec == PA_RAOP_CODEC_ALAC)
 size += write_ALAC_data(((uint8_t *) buffer + head), packet->length - 
head, raw, , false);
-else
-size += write_AAC_data(((uint8_t *) buffer + head), packet->length - 
head, raw, );
+else {
+pa_log_debug("Only ALAC encoding is supported, sending zeros...");
+pa_memzero(((uint8_t *) buffer + head), packet->length - head);
+size += length;
+}
+
 c->rtptime += length / 4;
 
 pa_memblock_release(block->memblock);
@@ -430,12 +412,14 @@ static size_t build_udp_audio_packet(pa_raop_client *c, 
pa_memchunk *block, pa_m
 
 length = block->length;
 size = sizeof(udp_audio_header);
-if (c->codec == PA_RAOP_CODEC_PCM)
-size += write_PCM_data(((uint8_t *) buffer + head), packet->length - 
head, raw, );
-else if (c->codec == PA_RAOP_CODEC_ALAC)
+if (c->codec == PA_RAOP_CODEC_ALAC)
 size += write_ALAC_data(((uint8_t *) buffer + head), packet->length - 
head, raw, , false);
-else
-size += write_AAC_data(((uint8_t *) buffer + head), packet->length - 
head, raw, );
+else {
+pa_log_debug("Only ALAC encoding is supported, sending zeros...");
+pa_memzero(((uint8_t *) buffer + head), packet->length - head);
+size += length;
+}
+
 c->rtptime += length / 4;
 c->seq++;
 
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 21/33] raop: Fix packet retransmission

2016-11-06 Thread Hajime Fujita
From: Colin Leroy 

Fix UDP header decoding (sequence number and number of packets);
Fix missing pa_memblock_release() causing assertions after retransmission.
---
 src/modules/raop/raop-client.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index 8a43a19..90488e4 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -470,6 +470,7 @@ static ssize_t send_udp_audio_packet(pa_raop_client *c, 
pa_memchunk *block, size
 written = pa_write(c->udp_sfd, buffer, packet->length, NULL);
 if (written < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
 pa_log_debug("Discarding UDP (audio, seq=%d) packet due to EAGAIN 
(%s)", c->seq, pa_cstrerror(errno));
+pa_memblock_release(packet->memblock);
 return (ssize_t) packet->length;
 }
 
@@ -525,9 +526,11 @@ static ssize_t resend_udp_audio_packets(pa_raop_client *c, 
uint16_t seq, uint16_
 written = pa_write(c->udp_cfd, buffer, packet->length, NULL);
 if (written < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
 pa_log_debug("Discarding UDP (audio-restransmitted, seq=%d) packet 
due to EAGAIN", seq + i);
+pa_memblock_release(packet->memblock);
 continue;
 }
 
+pa_memblock_release(packet->memblock);
 total +=  written;
 }
 
@@ -582,8 +585,8 @@ static size_t handle_udp_control_packet(pa_raop_client *c, 
const uint8_t packet[
 if (size != 8 || packet[0] != 0x80)
 return 1;
 
-seq = ntohs((uint16_t) packet[4]);
-nbp = ntohs((uint16_t) packet[6]);
+seq = ntohs((uint16_t) (packet[4] | packet[5] << 8));
+nbp = ntohs((uint16_t) (packet[6] | packet[7] << 8));
 if (nbp <= 0)
 return 1;
 
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 09/33] raop: Extract encryption related code into a separate file

2016-11-06 Thread Hajime Fujita
From: Martin Blanchard 

That makes the raop_client.c code smaller/cleaner and will simplify
addition of more crypto related stuffs like authentication.
---
 src/Makefile.am|   1 +
 src/modules/raop/raop_client.c | 116 +---
 src/modules/raop/raop_client.h |   3 +-
 src/modules/raop/raop_crypto.c | 146 +
 src/modules/raop/raop_crypto.h |  35 ++
 5 files changed, 215 insertions(+), 86 deletions(-)
 create mode 100644 src/modules/raop/raop_crypto.c
 create mode 100644 src/modules/raop/raop_crypto.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 7b5dec2..95e5eac 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1154,6 +1154,7 @@ librtp_la_LIBADD = $(AM_LIBADD) 
libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@
 
 libraop_la_SOURCES = \
 modules/raop/raop_client.c modules/raop/raop_client.h \
+modules/raop/raop_crypto.c modules/raop/raop_crypto.h \
 modules/raop/base64.c modules/raop/base64.h \
 modules/raop/raop_packet_buffer.h modules/raop/raop_packet_buffer.c
 libraop_la_CFLAGS = $(AM_CFLAGS) $(OPENSSL_CFLAGS) 
-I$(top_srcdir)/src/modules/rtp
diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c
index e6e3737..5c825eb 100644
--- a/src/modules/raop/raop_client.c
+++ b/src/modules/raop/raop_client.c
@@ -32,13 +32,6 @@
 #include 
 #endif
 
-/* TODO: Replace OpenSSL with NSS */
-#include 
-#include 
-#include 
-#include 
-#include 
-
 #include 
 #include 
 #include 
@@ -56,12 +49,11 @@
 #include 
 
 #include "raop_client.h"
-#include "rtsp_client.h"
-#include "base64.h"
 
+#include "rtsp_client.h"
 #include "raop_packet_buffer.h"
-
-#define AES_CHUNKSIZE 16
+#include "raop_crypto.h"
+#include "base64.h"
 
 #define JACK_STATUS_DISCONNECTED 0
 #define JACK_STATUS_CONNECTED 1
@@ -100,12 +92,8 @@ struct pa_raop_client {
 uint8_t jack_type;
 uint8_t jack_status;
 
-/* Encryption Related bits */
 int encryption; /* Enable encryption? */
-AES_KEY aes;
-uint8_t aes_iv[AES_CHUNKSIZE]; /* Initialization vector for aes-cbc */
-uint8_t aes_nv[AES_CHUNKSIZE]; /* Next vector for aes-cbc */
-uint8_t aes_key[AES_CHUNKSIZE]; /* Key for aes-cbc */
+pa_raop_secret *aes;
 
 uint16_t seq;
 uint32_t rtptime;
@@ -240,50 +228,6 @@ static inline void bit_writer(uint8_t **buffer, uint8_t 
*bit_pos, int *size, uin
 }
 }
 
-static int rsa_encrypt(uint8_t *text, int len, uint8_t *res) {
-const char n[] =
-"59dE8qLieItsH1WgjrcFRKj6eUWqi+bGLOX1HL3U3GhC/j0Qg90u3sG/1CUtwC"
-"5vOYvfDmFI6oSFXi5ELabWJmT2dKHzBJKa3k9ok+8t9ucRqMd6DZHJ2YCCLlDR"
-"KSKv6kDqnw4UwPdpOMXziC/AMj3Z/lUVX1G7WSHCAWKf1zNS1eLvqr+boEjXuB"
-"OitnZ/bDzPHrTOZz0Dew0uowxf/+sG+NCK3eQJVxqcaJ/vEHKIVd2M+5qL71yJ"
-"Q+87X6oV3eaYvt3zWZYD6z5vYTcrtij2VZ9Zmni/UAaHqn9JdsBWLUEpVviYnh"
-"imNVvYFZeCXg/IdTQ+x4IRdiXNv5hEew==";
-const char e[] = "AQAB";
-uint8_t modules[256];
-uint8_t exponent[8];
-int size;
-RSA *rsa;
-
-rsa = RSA_new();
-size = pa_base64_decode(n, modules);
-rsa->n = BN_bin2bn(modules, size, NULL);
-size = pa_base64_decode(e, exponent);
-rsa->e = BN_bin2bn(exponent, size, NULL);
-
-size = RSA_public_encrypt(len, text, res, rsa, RSA_PKCS1_OAEP_PADDING);
-RSA_free(rsa);
-return size;
-}
-
-static int aes_encrypt(pa_raop_client *c, uint8_t *data, int size) {
-uint8_t *buf;
-int i=0, j;
-
-pa_assert(c);
-
-memcpy(c->aes_nv, c->aes_iv, AES_CHUNKSIZE);
-while (i+AES_CHUNKSIZE <= size) {
-buf = data + i;
-for (j=0; jaes_nv[j];
-
-AES_encrypt(buf, buf, >aes);
-memcpy(c->aes_nv, buf, AES_CHUNKSIZE);
-i += AES_CHUNKSIZE;
-}
-return i;
-}
-
 static inline void rtrimchar(char *str, char rc) {
 char *sp = str + strlen(str) - 1;
 while (sp >= str && *sp == rc) {
@@ -570,8 +514,6 @@ static ssize_t udp_send_audio_packet(pa_raop_client *c, 
bool retrans, uint8_t *b
 }
 
 static void do_rtsp_announce(pa_raop_client *c) {
-int i;
-uint8_t rsakey[512];
 char *key, *iv, *sac = NULL, *sdp;
 uint16_t rand_data;
 const char *ip;
@@ -583,22 +525,20 @@ static void do_rtsp_announce(pa_raop_client *c) {
 pa_rtsp_set_url(c->rtsp, url);
 pa_xfree(url);
 
-/* Now encrypt our aes_public key to send to the device. */
-i = rsa_encrypt(c->aes_key, AES_CHUNKSIZE, rsakey);
-pa_base64_encode(rsakey, i, );
-rtrimchar(key, '=');
-pa_base64_encode(c->aes_iv, AES_CHUNKSIZE, );
-rtrimchar(iv, '=');
-
 /* UDP protocol does not need "Apple-Challenge" at announce. */
 if (c->protocol == RAOP_TCP) {
 pa_random(_data, sizeof(rand_data));
-pa_base64_encode(_data, AES_CHUNKSIZE, );
+pa_base64_encode(_data, sizeof(rand_data), );
 rtrimchar(sac, '=');
 pa_rtsp_add_header(c->rtsp, 

[pulseaudio-discuss] [PATCH v7 14/33] raop: Prefer ALAC encoding to raw PCM if supported by server

2016-11-06 Thread Hajime Fujita
From: Martin Blanchard 

ALAC encoding is to be prefered simply because ALAC audio packet reverse-
engineering and implementation is in better shape than raw PCM. Sending ALAC
audio does not mean compressing audio and thus linking an external library to
do so. ALAC packets has the ability to carry uncompressed PCM frames, and
that's what is implemented at the time.
---
 src/modules/raop/module-raop-discover.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/modules/raop/module-raop-discover.c 
b/src/modules/raop/module-raop-discover.c
index 6e2542a..bf05dec 100644
--- a/src/modules/raop/module-raop-discover.c
+++ b/src/modules/raop/module-raop-discover.c
@@ -200,7 +200,10 @@ static void resolver_cb(
  *  - 1 = ALAC,
  *  - 2 = AAC,
  *  - 3 = AAC ELD. */
-cn = pa_xstrdup("PCM");
+if (pa_str_in_list(value, ",", "1"))
+cn = pa_xstrdup("ALAC");
+else
+cn = pa_xstrdup("PCM");
 } else if (pa_streq(key, "md")) {
 /* Supported metadata types:
  *  - 0 = text,
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 10/33] raop: Move base64 implementation to a util file

2016-11-06 Thread Hajime Fujita
From: Martin Blanchard <tch...@gmx.com>

Base64 implementation is now in a common file called raop_util.c.
Old Base64 files are removed but copyright is preserved.

Original patch by Martin Blanchard, patch splitted by
Hajime Fujita <crisp.fuj...@nifty.com>.
---
 src/Makefile.am|  4 +-
 src/modules/raop/raop_client.c |  6 +-
 src/modules/raop/raop_crypto.c | 10 +--
 src/modules/raop/{base64.c => raop_util.c} | 99 --
 src/modules/raop/{base64.h => raop_util.h} | 11 ++--
 5 files changed, 69 insertions(+), 61 deletions(-)
 rename src/modules/raop/{base64.c => raop_util.c} (72%)
 rename src/modules/raop/{base64.h => raop_util.h} (78%)

diff --git a/src/Makefile.am b/src/Makefile.am
index 95e5eac..e52dd95 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1154,9 +1154,9 @@ librtp_la_LIBADD = $(AM_LIBADD) 
libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@
 
 libraop_la_SOURCES = \
 modules/raop/raop_client.c modules/raop/raop_client.h \
+modules/raop/raop_packet_buffer.h modules/raop/raop_packet_buffer.c \
 modules/raop/raop_crypto.c modules/raop/raop_crypto.h \
-modules/raop/base64.c modules/raop/base64.h \
-modules/raop/raop_packet_buffer.h modules/raop/raop_packet_buffer.c
+modules/raop/raop_util.c modules/raop/raop_util.h
 libraop_la_CFLAGS = $(AM_CFLAGS) $(OPENSSL_CFLAGS) 
-I$(top_srcdir)/src/modules/rtp
 libraop_la_LDFLAGS = $(AM_LDFLAGS) $(AM_LIBLDFLAGS) -avoid-version
 libraop_la_LIBADD = $(AM_LIBADD) $(OPENSSL_LIBS) 
libpulsecore-@PA_MAJORMINOR@.la librtp.la libpulsecommon-@PA_MAJORMINOR@.la 
libpulse.la
diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c
index 5c825eb..a2ec91e 100644
--- a/src/modules/raop/raop_client.c
+++ b/src/modules/raop/raop_client.c
@@ -53,7 +53,7 @@
 #include "rtsp_client.h"
 #include "raop_packet_buffer.h"
 #include "raop_crypto.h"
-#include "base64.h"
+#include "raop_util.h"
 
 #define JACK_STATUS_DISCONNECTED 0
 #define JACK_STATUS_CONNECTED 1
@@ -528,7 +528,7 @@ static void do_rtsp_announce(pa_raop_client *c) {
 /* UDP protocol does not need "Apple-Challenge" at announce. */
 if (c->protocol == RAOP_TCP) {
 pa_random(_data, sizeof(rand_data));
-pa_base64_encode(_data, sizeof(rand_data), );
+pa_raop_base64_encode(_data, 8*sizeof(rand_data), );
 rtrimchar(sac, '=');
 pa_rtsp_add_header(c->rtsp, "Apple-Challenge", sac);
 }
@@ -689,7 +689,7 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state 
state, pa_headerlist
 
 /* Set the Apple-Challenge key */
 pa_random(, sizeof(rand));
-pa_base64_encode(, sizeof(rand), );
+pa_raop_base64_encode(, 8*sizeof(rand), );
 rtrimchar(sac, '=');
 pa_rtsp_add_header(c->rtsp, "Apple-Challenge", sac);
 
diff --git a/src/modules/raop/raop_crypto.c b/src/modules/raop/raop_crypto.c
index cd2934b..eacf392 100644
--- a/src/modules/raop/raop_crypto.c
+++ b/src/modules/raop/raop_crypto.c
@@ -37,7 +37,7 @@
 #include 
 
 #include "raop_crypto.h"
-#include "base64.h"
+#include "raop_util.h"
 
 #define AES_CHUNK_SIZE 16
 
@@ -68,9 +68,9 @@ static int rsa_encrypt(uint8_t *data, int len, uint8_t *str) {
 pa_assert(str);
 
 rsa = RSA_new();
-size = pa_base64_decode(rsa_modulus, modules);
+size = pa_raop_base64_decode(rsa_modulus, modules);
 rsa->n = BN_bin2bn(modules, size, NULL);
-size = pa_base64_decode(rsa_exponent, exponent);
+size = pa_raop_base64_decode(rsa_exponent, exponent);
 rsa->e = BN_bin2bn(exponent, size, NULL);
 
 size = RSA_public_encrypt(len, data, str, rsa, RSA_PKCS1_OAEP_PADDING);
@@ -102,7 +102,7 @@ char* pa_raop_secret_get_iv(pa_raop_secret *s) {
 
 pa_assert(s);
 
-pa_base64_encode(s->iv, AES_CHUNK_SIZE, _iv);
+pa_raop_base64_encode(s->iv, AES_CHUNK_SIZE, _iv);
 
 return base64_iv;
 }
@@ -116,7 +116,7 @@ char* pa_raop_secret_get_key(pa_raop_secret *s) {
 
 /* Encrypt our AES public key to send to the device */
 size = rsa_encrypt(s->key, AES_CHUNK_SIZE, rsa_key);
-pa_base64_encode(rsa_key, size, _key);
+pa_raop_base64_encode(rsa_key, size, _key);
 
 return base64_key;
 }
diff --git a/src/modules/raop/base64.c b/src/modules/raop/raop_util.c
similarity index 72%
rename from src/modules/raop/base64.c
rename to src/modules/raop/raop_util.c
index 073e6a2..d24d67d 100644
--- a/src/modules/raop/base64.c
+++ b/src/modules/raop/raop_util.c
@@ -1,7 +1,8 @@
 /***
   This file is part of PulseAudio.
 
-  Copyright 2008 Colin Guthrie
+  Copyright 2013 Martin Blanchard
+  Copyright Kungliga Tekniska Høgskolan & Colin Guthrie
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Les

[pulseaudio-discuss] [PATCH v7 12/33] raop: Add BA (Basic) and DA (Digest) HTTP authentication helpers

2016-11-06 Thread Hajime Fujita
From: Martin Blanchard 

RAOP authentication is using standard HTTP challenge-response authentication
scheme. This patch adds two helper functions that generate the proper hash
(for both techniques) given a username, a password and session related tokens.
---
 src/modules/raop/raop_client.c | 245 +++--
 src/modules/raop/raop_client.h |   4 +
 src/modules/raop/raop_util.c   |  40 +++
 src/modules/raop/raop_util.h   |   4 +
 src/modules/rtp/rtsp_client.c  |  83 ++
 src/modules/rtp/rtsp_client.h  |  26 +++--
 6 files changed, 359 insertions(+), 43 deletions(-)

diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c
index a2ec91e..1323cd0 100644
--- a/src/modules/raop/raop_client.c
+++ b/src/modules/raop/raop_client.c
@@ -65,6 +65,9 @@
 #define VOLUME_MIN -144
 #define VOLUME_MAX 0
 
+#define USER_AGENT "iTunes/11.0.4 (Windows; N)"
+#define USER_NAME "iTunes"
+
 #define DEFAULT_RAOP_PORT 5000
 #define UDP_DEFAULT_AUDIO_PORT 6000
 #define UDP_DEFAULT_CONTROL_PORT 6001
@@ -85,13 +88,15 @@ struct pa_raop_client {
 pa_core *core;
 char *host;
 uint16_t port;
-char *sid;
 pa_rtsp_client *rtsp;
-pa_raop_protocol_t protocol;
+char *sci, *sid;
+char *pwd;
 
 uint8_t jack_type;
 uint8_t jack_status;
 
+pa_raop_protocol_t protocol;
+
 int encryption; /* Enable encryption? */
 pa_raop_secret *aes;
 
@@ -125,6 +130,9 @@ struct pa_raop_client {
 uint32_t udp_sync_interval;
 uint32_t udp_sync_count;
 
+pa_raop_client_auth_cb_t udp_auth_callback;
+void *udp_auth_userdata;
+
 pa_raop_client_setup_cb_t udp_setup_callback;
 void *udp_setup_userdata;
 
@@ -576,7 +584,7 @@ static void do_rtsp_announce(pa_raop_client *c) {
 pa_xfree(sdp);
 }
 
-static void tcp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
pa_headerlist* headers, void *userdata) {
+static void tcp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
pa_rtsp_status status, pa_headerlist* headers, void *userdata) {
 pa_raop_client* c = userdata;
 pa_assert(c);
 pa_assert(rtsp);
@@ -675,12 +683,13 @@ static void tcp_rtsp_cb(pa_rtsp_client *rtsp, 
pa_rtsp_state state, pa_headerlist
 }
 }
 
-static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
pa_headerlist *headers, void *userdata) {
+static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
pa_rtsp_status status, pa_headerlist *headers, void *userdata) {
 pa_raop_client *c = userdata;
 
 pa_assert(c);
 pa_assert(rtsp);
 pa_assert(rtsp == c->rtsp);
+pa_assert(STATUS_OK == status);
 
 switch (state) {
 case STATE_CONNECT: {
@@ -982,6 +991,178 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, 
pa_rtsp_state state, pa_headerlist
 }
 }
 
+static void rtsp_authentication_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
pa_rtsp_status status, pa_headerlist *headers, void *userdata) {
+pa_raop_client *c = userdata;
+
+pa_assert(c);
+pa_assert(rtsp);
+pa_assert(rtsp == c->rtsp);
+
+switch (state) {
+case STATE_CONNECT: {
+char *sci = NULL, *sac = NULL;
+uint16_t rac;
+struct {
+uint32_t ci1;
+uint32_t ci2;
+} rci;
+
+pa_random(, sizeof(rci));
+/* Generate a random Client-Instance number */
+sci = pa_sprintf_malloc("%08x%08x",rci.ci1, rci.ci2);
+pa_rtsp_add_header(c->rtsp, "Client-Instance", sci);
+
+pa_random(, sizeof(rac));
+/* Generate a random Apple-Challenge key */
+pa_raop_base64_encode(, 8*sizeof(rac), );
+pa_log_debug ("APPLECHALLENGE >> %s | %d", sac, (int) sizeof(rac));
+rtrimchar(sac, '=');
+pa_rtsp_add_header(c->rtsp, "Apple-Challenge", sac);
+
+pa_rtsp_options(c->rtsp);
+
+pa_xfree(sac);
+pa_xfree(sci);
+break;
+}
+
+case STATE_OPTIONS: {
+static bool waiting = false;
+const char *current = NULL;
+char space[] = " ";
+char *token,*ath = NULL;
+char *publ, *wath, *mth, *val;
+char *realm = NULL, *nonce = NULL, *response = NULL;
+char comma[] = ",";
+
+pa_log_debug("RAOP: OPTIONS");
+/* We do not consider the Apple-Response */
+pa_rtsp_remove_header(c->rtsp, "Apple-Challenge");
+
+if (STATUS_UNAUTHORIZED == status) {
+wath = pa_xstrdup(pa_headerlist_gets(headers, 
"WWW-Authenticate"));
+if (true == waiting) {
+pa_xfree(wath);
+goto failure;
+}
+
+if (wath)
+mth = pa_split(wath, space, );
+while ((token = pa_split(wath, comma, ))) {
+val = NULL;
+if ((val = strstr(token, "="))) {

[pulseaudio-discuss] [PATCH v7 08/33] raop: Better playback resume handling

2016-11-06 Thread Hajime Fujita
From: Martin Blanchard 

When playback stops, a FLUSH command is send to the server and the sink
goes to IDLE. If playback resumes quickly, sink goes back to RUNNING
(without being SUSPENDED) and the sink should just start streaming again.
This patch implements this behaviour.
---
 src/modules/raop/module-raop-sink.c |  8 ++--
 src/modules/raop/raop_client.c  | 26 +++---
 src/modules/raop/raop_client.h  |  1 +
 3 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/src/modules/raop/module-raop-sink.c 
b/src/modules/raop/module-raop-sink.c
index 4ed0c1b..564ef99 100644
--- a/src/modules/raop/module-raop-sink.c
+++ b/src/modules/raop/module-raop-sink.c
@@ -332,10 +332,14 @@ static int udp_sink_process_msg(pa_msgobject *o, int 
code, void *data, int64_t o
 
 pa_smoother_resume(u->smoother, pa_rtclock_now(), true);
 
-if (!pa_raop_client_udp_can_stream(u->raop)) {
-/* Connecting will trigger a RECORD */
+if (!pa_raop_client_udp_is_alive(u->raop)) {
+/* Connecting will trigger a RECORD and start steaming 
*/
 pa_raop_client_connect(u->raop);
+} else if (!pa_raop_client_udp_can_stream(u->raop)) {
+/* RECORD alredy sent, simply start streaming */
+pa_raop_client_udp_stream(u->raop);
 }
+
 udp_start_wakeup_clock(u);
 
 break;
diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c
index 11c871d..e6e3737 100644
--- a/src/modules/raop/raop_client.c
+++ b/src/modules/raop/raop_client.c
@@ -934,8 +934,6 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state 
state, pa_headerlist
 
 pa_log_debug("RAOP: RECORD");
 
-c->is_recording = true;
-
 alt = pa_xstrdup(pa_headerlist_gets(headers, "Audio-Latency"));
 /* Generate a random synchronization source identifier from this 
session. */
 pa_random(, sizeof(rand));
@@ -947,6 +945,8 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state 
state, pa_headerlist
 c->udp_first_packet = true;
 c->udp_sync_count = 0;
 
+c->is_recording = true;
+
 c->udp_record_callback(c->udp_setup_userdata);
 
 pa_xfree(alt);
@@ -1150,11 +1150,12 @@ int pa_raop_client_connect(pa_raop_client *c) {
 
 int pa_raop_client_flush(pa_raop_client *c) {
 int rv = 0;
+
 pa_assert(c);
 
 if (c->rtsp != NULL) {
 rv = pa_rtsp_flush(c->rtsp, c->seq, c->rtptime);
-c->udp_sync_count = -1;
+c->udp_sync_count = 0;
 }
 
 return rv;
@@ -1193,6 +1194,25 @@ int pa_raop_client_udp_can_stream(pa_raop_client *c) {
 return rv;
 }
 
+int pa_raop_client_udp_stream(pa_raop_client *c) {
+int rv = 0;
+
+pa_assert(c);
+
+if (c->rtsp != NULL && c->udp_stream_fd > 0) {
+if (!c->is_recording) {
+c->udp_first_packet = true;
+c->udp_sync_count = 0;
+
+c->is_recording = true;
+ }
+
+rv = 1;
+}
+
+return rv;
+}
+
 int pa_raop_client_udp_handle_timing_packet(pa_raop_client *c, const uint8_t 
packet[], ssize_t size) {
 const uint32_t * data = NULL;
 uint8_t payload = 0;
diff --git a/src/modules/raop/raop_client.h b/src/modules/raop/raop_client.h
index 6ab6d32..d49c146 100644
--- a/src/modules/raop/raop_client.h
+++ b/src/modules/raop/raop_client.h
@@ -43,6 +43,7 @@ int pa_raop_client_teardown(pa_raop_client *c);
 
 int pa_raop_client_udp_is_alive(pa_raop_client *c);
 int pa_raop_client_udp_can_stream(pa_raop_client *c);
+int pa_raop_client_udp_stream(pa_raop_client *c);
 
 void pa_raop_client_set_encryption(pa_raop_client *c, int encryption);
 pa_volume_t pa_raop_client_adjust_volume(pa_raop_client *c, pa_volume_t 
volume);
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 07/33] raop: Do not send audio before RECORD response

2016-11-06 Thread Hajime Fujita
From: Martin Blanchard 

This patch prevents audio packets to be sent before the server
respond to the RECORD command.
---
 src/modules/raop/module-raop-sink.c |  6 +++---
 src/modules/raop/raop_client.c  | 25 -
 src/modules/raop/raop_client.h  |  1 +
 3 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/src/modules/raop/module-raop-sink.c 
b/src/modules/raop/module-raop-sink.c
index c1afedd..4ed0c1b 100644
--- a/src/modules/raop/module-raop-sink.c
+++ b/src/modules/raop/module-raop-sink.c
@@ -310,7 +310,7 @@ static int udp_sink_process_msg(pa_msgobject *o, int code, 
void *data, int64_t o
 pa_log_debug("RAOP: SUSPENDED");
 pa_smoother_pause(u->smoother, pa_rtclock_now());
 
-if (pa_raop_client_udp_can_stream(u->raop)) {
+if (pa_raop_client_udp_is_alive(u->raop)) {
 /* Issue a TEARDOWN if we are still connected. */
 pa_raop_client_teardown(u->raop);
 }
@@ -756,10 +756,10 @@ static void udp_thread_func(struct userdata *u) {
 continue;
 }
 
-if (!pa_raop_client_udp_can_stream(u->raop))
-continue;
 if (u->sink->thread_info.state != PA_SINK_RUNNING)
 continue;
+if (!pa_raop_client_udp_can_stream(u->raop))
+continue;
 
 if (u->encoded_memchunk.length <= 0) {
 if (u->encoded_memchunk.memblock != NULL)
diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c
index 1c6c49e..11c871d 100644
--- a/src/modules/raop/raop_client.c
+++ b/src/modules/raop/raop_client.c
@@ -131,6 +131,8 @@ struct pa_raop_client {
 
 uint32_t udp_ssrc;
 
+bool is_recording;
+
 bool udp_first_packet;
 uint32_t udp_sync_interval;
 uint32_t udp_sync_count;
@@ -932,6 +934,8 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state 
state, pa_headerlist
 
 pa_log_debug("RAOP: RECORD");
 
+c->is_recording = true;
+
 alt = pa_xstrdup(pa_headerlist_gets(headers, "Audio-Latency"));
 /* Generate a random synchronization source identifier from this 
session. */
 pa_random(, sizeof(rand));
@@ -958,6 +962,8 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state 
state, pa_headerlist
 case STATE_FLUSH: {
 pa_log_debug("RAOP: FLUSHED");
 
+c->is_recording = false;
+
 break;
 }
 
@@ -966,6 +972,8 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state 
state, pa_headerlist
 pa_assert(c->udp_disconnected_callback);
 pa_assert(c->rtsp);
 
+c->is_recording = false;
+
 pa_rtsp_disconnect(c->rtsp);
 
 if (c->udp_stream_fd > 0) {
@@ -1066,6 +1074,8 @@ pa_raop_client* pa_raop_client_new(pa_core *core, const 
char *host, pa_raop_prot
 else
 c->port = DEFAULT_RAOP_PORT;
 
+c->is_recording = false;
+
 c->udp_first_packet = true;
 
 ss = core->default_sample_spec;
@@ -1133,6 +1143,8 @@ int pa_raop_client_connect(pa_raop_client *c) {
 else
 pa_rtsp_set_callback(c->rtsp, udp_rtsp_cb, c);
 
+c->is_recording = false;
+
 return pa_rtsp_connect(c->rtsp);
 }
 
@@ -1159,7 +1171,7 @@ int pa_raop_client_teardown(pa_raop_client *c) {
 return rv;
 }
 
-int pa_raop_client_udp_can_stream(pa_raop_client *c) {
+int pa_raop_client_udp_is_alive(pa_raop_client *c) {
 int rv = 0;
 
 pa_assert(c);
@@ -1170,6 +1182,17 @@ int pa_raop_client_udp_can_stream(pa_raop_client *c) {
 return rv;
 }
 
+int pa_raop_client_udp_can_stream(pa_raop_client *c) {
+int rv = 0;
+
+pa_assert(c);
+
+if (c->is_recording && c->udp_stream_fd > 0)
+rv = 1;
+
+return rv;
+}
+
 int pa_raop_client_udp_handle_timing_packet(pa_raop_client *c, const uint8_t 
packet[], ssize_t size) {
 const uint32_t * data = NULL;
 uint8_t payload = 0;
diff --git a/src/modules/raop/raop_client.h b/src/modules/raop/raop_client.h
index 578e9d0..6ab6d32 100644
--- a/src/modules/raop/raop_client.h
+++ b/src/modules/raop/raop_client.h
@@ -41,6 +41,7 @@ int pa_raop_client_connect(pa_raop_client *c);
 int pa_raop_client_flush(pa_raop_client *c);
 int pa_raop_client_teardown(pa_raop_client *c);
 
+int pa_raop_client_udp_is_alive(pa_raop_client *c);
 int pa_raop_client_udp_can_stream(pa_raop_client *c);
 
 void pa_raop_client_set_encryption(pa_raop_client *c, int encryption);
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 01/33] pulsecore: Add pa_strneq macro

2016-11-06 Thread Hajime Fujita
From: Hajime Fujita <crisp.fuj...@nifty.com>

This macro compares if the given two strings, with the maximum length
of n, are equal. Useful for strings that are not NULL-terminated.
---
 src/pulsecore/core-util.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h
index 8847528..be023a8 100644
--- a/src/pulsecore/core-util.h
+++ b/src/pulsecore/core-util.h
@@ -219,6 +219,7 @@ void pa_unset_env_recorded(void);
 bool pa_in_system_mode(void);
 
 #define pa_streq(a,b) (!strcmp((a),(b)))
+#define pa_strneq(a,b,n) (!strncmp((a),(b),(n)))
 
 /* Like pa_streq, but does not blow up on NULL pointers. */
 static inline bool pa_safe_streq(const char *a, const char *b) {
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 05/33] raop: Parse server capabilities on discovery

2016-11-06 Thread Hajime Fujita
From: Martin Blanchard <tin...@gmx.fr>

During the discovery phase, raop servers send their capabilities
(supported encryption, audio codec...). These should be passed to the
raop sink via module's arguments.

Original patch written by Martin Blanchard, then modified by Hajime
Fujita <crisp.fuj...@nifty.com> based on review comments by
Anton Lundin <gla...@acc.umu.se>.
Now resolver_cb always dtrdup()s string blocks given by Avahi,
to make the code easier to maintain.
---
 src/modules/raop/module-raop-discover.c | 89 -
 src/modules/raop/module-raop-sink.c |  2 +-
 2 files changed, 88 insertions(+), 3 deletions(-)

diff --git a/src/modules/raop/module-raop-discover.c 
b/src/modules/raop/module-raop-discover.c
index 1ced777..6e2542a 100644
--- a/src/modules/raop/module-raop-discover.c
+++ b/src/modules/raop/module-raop-discover.c
@@ -139,6 +139,9 @@ static void resolver_cb(
 struct userdata *u = userdata;
 struct tunnel *tnl;
 char *device = NULL, *nicename, *dname, *vname, *args;
+char *tp = NULL, *et = NULL, *cn = NULL;
+char *ch = NULL, *ss = NULL, *sr = NULL;
+char *t = NULL;
 char at[AVAHI_ADDRESS_STR_MAX];
 AvahiStringList *l;
 pa_module *m;
@@ -169,6 +172,51 @@ static void resolver_cb(
 if (pa_streq(key, "device")) {
 device = value;
 value = NULL;
+} else if (pa_streq(key, "tp")) {
+/* Transport protocol:
+ *  - TCP = only TCP,
+ *  - UDP = only UDP,
+ *  - TCP,UDP = both supported (UDP should be prefered) */
+if (pa_str_in_list(value, ",", "UDP"))
+tp = pa_xstrdup("UDP");
+else if (pa_str_in_list(value, ",", "TCP"))
+tp = pa_xstrdup("TCP");
+else
+tp = pa_xstrdup(value);
+} else if (pa_streq(key, "et")) {
+/* Supported encryption types:
+ *  - 0 = none,
+ *  - 1 = RSA,
+ *  - 2 = FairPlay,
+ *  - 3 = MFiSAP,
+ *  - 4 = FairPlay SAPv2.5. */
+ if (pa_str_in_list(value, ",", "1"))
+ et = pa_xstrdup("RSA");
+ else
+ et = pa_xstrdup("none");
+} else if (pa_streq(key, "cn")) {
+/* Suported audio codecs:
+ *  - 0 = PCM,
+ *  - 1 = ALAC,
+ *  - 2 = AAC,
+ *  - 3 = AAC ELD. */
+cn = pa_xstrdup("PCM");
+} else if (pa_streq(key, "md")) {
+/* Supported metadata types:
+ *  - 0 = text,
+ *  - 1 = artwork,
+ *  - 2 = progress. */
+} else if (pa_streq(key, "pw")) {
+/* Requires password ? (true/false) */
+} else if (pa_streq(key, "ch")) {
+/* Number of channels */
+ch = pa_xstrdup(value);
+} else if (pa_streq(key, "ss")) {
+/* Sample size */
+ss = pa_xstrdup(value);
+} else if (pa_streq(key, "sr")) {
+/* Sample rate */
+sr = pa_xstrdup(value);
 }
 
 avahi_free(key);
@@ -176,9 +224,9 @@ static void resolver_cb(
 }
 
 if (device)
-dname = pa_sprintf_malloc("raop.%s.%s", host_name, device);
+dname = pa_sprintf_malloc("raop_output.%s.%s", host_name, device);
 else
-dname = pa_sprintf_malloc("raop.%s", host_name);
+dname = pa_sprintf_malloc("raop_output.%s", host_name);
 
 if (!(vname = pa_namereg_make_valid_name(dname))) {
 pa_log("Cannot construct valid device name from '%s'.", dname);
@@ -205,6 +253,43 @@ static void resolver_cb(
  vname);
 }
 
+if (tp != NULL) {
+t = args;
+args = pa_sprintf_malloc("%s protocol=%s", args, tp);
+pa_xfree(tp);
+pa_xfree(t);
+}
+if (et != NULL) {
+t = args;
+args = pa_sprintf_malloc("%s encryption=%s", args, et);
+pa_xfree(et);
+pa_xfree(t);
+}
+if (cn != NULL) {
+t = args;
+args = pa_sprintf_malloc("%s codec=%s", args, cn);
+pa_xfree(cn);
+pa_xfree(t);
+}
+if (ch != NULL) {
+t = args;
+args = pa_sprintf_malloc("%s channels=%s", args, ch);
+pa_xfree(ch);
+pa_xfree(t);
+}
+if (ss != NULL) {
+t = args;
+args = pa_sprintf_malloc("%s format=%s", args, ss);
+pa_xfree(ss);
+pa_xfree(t);
+}
+if (sr != NULL) {
+t = args;
+args = pa_sprintf_malloc("%s rate=%s", args, sr);
+pa_xfree(sr);
+pa_xfree(t);
+}
+

[pulseaudio-discuss] [PATCH v7 04/33] raop: Add UDP protocol handling

2016-11-06 Thread Hajime Fujita
From: Hajime Fujita <crisp.fuj...@nifty.com>

There are two versions in the RAOP protocol; one uses TCP and the
other uses UDP. Current raop implementation only supports TCP
version.

This patch adds an initial UDP protocol support for RAOP.
It is based on Martin Blanchard's work
(http://repo.or.cz/w/pulseaudio-raopUDP.git/shortlog/refs/heads/raop)
which is inspired by Christophe Fergeau's work
(https://github.com/zx2c4/pulseaudio-raop2).

Matrin's modifications were edited by Hajime Fujita, so that it
would support both TCP and UDP protocol in a single module.

Also this patch includes a fix that was found thanks to Matthias,
who reported that his ALAC
codec support fixed the issue.
https://bugs.freedesktop.org/show_bug.cgi?id=42804#c30
---
 src/modules/raop/module-raop-sink.c |  457 +--
 src/modules/raop/raop_client.c  | 1063 +++
 src/modules/raop/raop_client.h  |   39 +-
 3 files changed, 1400 insertions(+), 159 deletions(-)

diff --git a/src/modules/raop/module-raop-sink.c 
b/src/modules/raop/module-raop-sink.c
index 6fc3d94..1eadde2 100644
--- a/src/modules/raop/module-raop-sink.c
+++ b/src/modules/raop/module-raop-sink.c
@@ -66,12 +66,13 @@ PA_MODULE_USAGE(
 "sink_name= "
 "sink_properties= "
 "server=  "
+"protocol= "
+"encryption= "
+"codec= "
 "format= "
 "rate= "
 "channels=");
 
-#define DEFAULT_SINK_NAME "raop"
-
 struct userdata {
 pa_core *core;
 pa_module *module;
@@ -82,6 +83,8 @@ struct userdata {
 pa_rtpoll_item *rtpoll_item;
 pa_thread *thread;
 
+pa_raop_protocol_t protocol;
+
 pa_memchunk raw_memchunk;
 pa_memchunk encoded_memchunk;
 
@@ -97,7 +100,6 @@ struct userdata {
 int32_t rate;
 
 pa_smoother *smoother;
-int fd;
 
 int64_t offset;
 int64_t encoding_overhead;
@@ -107,12 +109,26 @@ struct userdata {
 pa_raop_client *raop;
 
 size_t block_size;
+
+/* Members only for the TCP protocol */
+int tcp_fd;
+
+/* Members only for the UDP protocol */
+int udp_control_fd;
+int udp_timing_fd;
+
+/* For UDP thread wakeup clock calculation */
+pa_usec_t udp_playback_start;
+uint32_t  udp_sent_packets;
 };
 
 static const char* const valid_modargs[] = {
 "sink_name",
 "sink_properties",
 "server",
+"protocol",
+"encryption",
+"codec",
 "format",
 "rate",
 "channels",
@@ -120,23 +136,26 @@ static const char* const valid_modargs[] = {
 };
 
 enum {
-SINK_MESSAGE_PASS_SOCKET = PA_SINK_MESSAGE_MAX,
-SINK_MESSAGE_RIP_SOCKET
+SINK_MESSAGE_TCP_PASS_SOCKET = PA_SINK_MESSAGE_MAX,
+SINK_MESSAGE_TCP_RIP_SOCKET,
+SINK_MESSAGE_UDP_SETUP,
+SINK_MESSAGE_UDP_RECORD,
+SINK_MESSAGE_UDP_DISCONNECTED,
 };
 
 /* Forward declarations: */
 static void sink_set_volume_cb(pa_sink *);
 
-static void on_connection(int fd, void *userdata) {
+static void tcp_on_connection(int fd, void *userdata) {
 int so_sndbuf = 0;
 socklen_t sl = sizeof(int);
 struct userdata *u = userdata;
 pa_assert(u);
 
-pa_assert(u->fd < 0);
-u->fd = fd;
+pa_assert(u->tcp_fd < 0);
+u->tcp_fd = fd;
 
-if (getsockopt(u->fd, SOL_SOCKET, SO_SNDBUF, _sndbuf, ) < 0)
+if (getsockopt(u->tcp_fd, SOL_SOCKET, SO_SNDBUF, _sndbuf, ) < 0)
 pa_log_warn("getsockopt(SO_SNDBUF) failed: %s", pa_cstrerror(errno));
 else {
 pa_log_debug("SO_SNDBUF is %zu.", (size_t) so_sndbuf);
@@ -148,19 +167,28 @@ static void on_connection(int fd, void *userdata) {
 
 pa_log_debug("Connection authenticated, handing fd to IO thread...");
 
-pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->sink), 
SINK_MESSAGE_PASS_SOCKET, NULL, 0, NULL, NULL);
+pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->sink), 
SINK_MESSAGE_TCP_PASS_SOCKET, NULL, 0, NULL, NULL);
 }
 
-static void on_close(void*userdata) {
+static void tcp_on_close(void*userdata) {
 struct userdata *u = userdata;
 pa_assert(u);
 
 pa_log_debug("Connection closed, informing IO thread...");
 
-pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->sink), 
SINK_MESSAGE_RIP_SOCKET, NULL, 0, NULL, NULL);
+pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->sink), 
SINK_MESSAGE_TCP_RIP_SOCKET, NULL, 0, NULL, NULL);
+}
+
+static pa_usec_t sink_get_latency(const struct userdata *u) {
+pa_usec_t w, r;
+
+r = pa_smoother_get(u->smoother, pa_rtclock_now());
+w = pa_bytes_to_usec((u->offset - u->encoding_overhead + 
(u->encoded_memchunk.length / u->encoding_ratio)), >sink->sample_spec);
+
+return w > r ? w - r : 0;
 }
 
-static int sink_proce

[pulseaudio-discuss] [PATCH v7 02/33] pulsecore: Add pa_split_space_in_place function

2016-11-06 Thread Hajime Fujita
From: Hajime Fujita <crisp.fuj...@nifty.com>

---
 src/pulsecore/core-util.c | 19 +++
 src/pulsecore/core-util.h |  1 +
 2 files changed, 20 insertions(+)

diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index f2999b2..9d571b8 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -1121,6 +1121,25 @@ char *pa_split_spaces(const char *c, const char **state) 
{
 return pa_xstrndup(current, l);
 }
 
+/* Similar to pa_split_spaces, except this returns a string in-place.
+   Returned string is generally not NULL-terminated.
+   See pa_split_in_place(). */
+const char *pa_split_spaces_in_place(const char *c, int *n, const char 
**state) {
+const char *current = *state ? *state : c;
+size_t l;
+
+if (!*current || *c == 0)
+return NULL;
+
+current += strspn(current, WHITESPACE);
+l = strcspn(current, WHITESPACE);
+
+*state = current+l;
+
+*n = l;
+return current;
+}
+
 PA_STATIC_TLS_DECLARE(signame, pa_xfree);
 
 /* Return the name of an UNIX signal. Similar to Solaris sig2str() */
diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h
index be023a8..e28b6aa 100644
--- a/src/pulsecore/core-util.h
+++ b/src/pulsecore/core-util.h
@@ -112,6 +112,7 @@ static inline const char *pa_strna(const char *x) {
 char *pa_split(const char *c, const char *delimiters, const char **state);
 const char *pa_split_in_place(const char *c, const char *delimiters, int *n, 
const char **state);
 char *pa_split_spaces(const char *c, const char **state);
+const char *pa_split_spaces_in_place(const char *c, int *n, const char 
**state);
 
 char *pa_strip_nl(char *s);
 char *pa_strip(char *s);
-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v7 06/33] raop: Packet retransmission support for UDP

2016-11-06 Thread Hajime Fujita
From: Matthias Wabersich <pulseau...@niafc.de>

This patch adds an RTP audio packet retransmission support and a
circular buffer implementation for it.

This patch was originally written by Matthias Wabersich [1] and
later debugged and integrated into the latest tree by Hajime Fujita

[1]: https://bugs.freedesktop.org/show_bug.cgi?id=42804#c44
---
 src/Makefile.am   |   3 +-
 src/modules/raop/raop_client.c| 109 ++---
 src/modules/raop/raop_client.h|   2 +
 src/modules/raop/raop_packet_buffer.c | 172 ++
 src/modules/raop/raop_packet_buffer.h |  42 +
 5 files changed, 316 insertions(+), 12 deletions(-)
 create mode 100644 src/modules/raop/raop_packet_buffer.c
 create mode 100644 src/modules/raop/raop_packet_buffer.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 2d5bdd4..7b5dec2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1154,7 +1154,8 @@ librtp_la_LIBADD = $(AM_LIBADD) 
libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@
 
 libraop_la_SOURCES = \
 modules/raop/raop_client.c modules/raop/raop_client.h \
-modules/raop/base64.c modules/raop/base64.h
+modules/raop/base64.c modules/raop/base64.h \
+modules/raop/raop_packet_buffer.h modules/raop/raop_packet_buffer.c
 libraop_la_CFLAGS = $(AM_CFLAGS) $(OPENSSL_CFLAGS) 
-I$(top_srcdir)/src/modules/rtp
 libraop_la_LDFLAGS = $(AM_LDFLAGS) $(AM_LIBLDFLAGS) -avoid-version
 libraop_la_LIBADD = $(AM_LIBADD) $(OPENSSL_LIBS) 
libpulsecore-@PA_MAJORMINOR@.la librtp.la libpulsecommon-@PA_MAJORMINOR@.la 
libpulse.la
diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c
index c0be2ec..1c6c49e 100644
--- a/src/modules/raop/raop_client.c
+++ b/src/modules/raop/raop_client.c
@@ -59,7 +59,8 @@
 #include "rtsp_client.h"
 #include "base64.h"
 
-#define UDP_FRAMES_PER_PACKET 352
+#include "raop_packet_buffer.h"
+
 #define AES_CHUNKSIZE 16
 
 #define JACK_STATUS_DISCONNECTED 0
@@ -77,6 +78,8 @@
 #define UDP_DEFAULT_CONTROL_PORT 6001
 #define UDP_DEFAULT_TIMING_PORT 6002
 
+#define UDP_DEFAULT_PKT_BUF_SIZE 1000
+
 typedef enum {
 UDP_PAYLOAD_TIMING_REQUEST = 0x52,
 UDP_PAYLOAD_TIMING_RESPONSE = 0x53,
@@ -140,6 +143,8 @@ struct pa_raop_client {
 
 pa_raop_client_disconnected_cb_t udp_disconnected_callback;
 void *udp_disconnected_userdata;
+
+pa_raop_packet_buffer *packet_buffer;
 };
 
 /* Timming packet header (8x8):
@@ -530,12 +535,35 @@ static void udp_build_audio_header(pa_raop_client *c, 
uint32_t *buffer, size_t s
 buffer[2] = htonl(c->udp_ssrc);
 }
 
-static ssize_t udp_send_audio_packet(pa_raop_client *c, uint8_t *buffer, 
size_t size) {
-ssize_t length;
+/* Audio retransmission header:
+ * [0]RTP v2: 0x80
+ * [1]Payload type: 0x56 + 0x80 (marker == on)
+ * [2]Unknown; seems always 0x01
+ * [3]Unknown; seems some random number around 0x20~0x40
+ * [4,5]  Original RTP header htons(0x8060)
+ * [6,7]  Packet sequence number to be retransmitted
+ * [8,11] Original RTP timestamp on the lost packet */
+static void udp_build_retrans_header(uint32_t *buffer, size_t size, uint16_t 
seq_num) {
+uint8_t x = 0x30; /* FIXME: what's this?? */
+
+pa_assert(size >= sizeof(uint32_t) * 2);
+
+buffer[0] = htonl((uint32_t) 0x8000
+  | ((uint32_t) UDP_PAYLOAD_RETRANSMIT_REPLY | 0x80) << 16
+  | 0x0100
+  | x);
+buffer[1] = htonl((uint32_t) 0x8060 | seq_num);
+}
 
-length = pa_write(c->udp_stream_fd, buffer, size, NULL);
-c->seq++;
+static ssize_t udp_send_audio_packet(pa_raop_client *c, bool retrans, uint8_t 
*buffer, size_t size) {
+ssize_t length;
+int fd = retrans ? c->udp_control_fd : c->udp_stream_fd;
 
+length = pa_write(fd, buffer, size, NULL);
+if (length < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
+pa_log_debug("Discarding audio packet %d due to EAGAIN", c->seq);
+length = size;
+}
 return length;
 }
 
@@ -947,6 +975,8 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state 
state, pa_headerlist
 
 pa_log_debug("RTSP control channel closed (teardown)");
 
+pa_raop_pb_clear(c->packet_buffer);
+
 pa_rtsp_client_free(c->rtsp);
 pa_xfree(c->sid);
 c->rtsp = NULL;
@@ -983,6 +1013,8 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, 
pa_rtsp_state state, pa_headerlist
 
 pa_log_debug("RTSP control channel closed (disconnected)");
 
+pa_raop_pb_clear(c->packet_buffer);
+
 pa_rtsp_client_free(c->rtsp);
 pa_xfree(c->sid);
 c->rtsp = NULL;
@@ -1046,7 +1078,8 @@ pa_raop_client* pa_raop_client_new(pa_core *core, const 
char *host, pa_raop_prot
 pa_raop_client_free(c);
 return NULL;
  

[pulseaudio-discuss] [PATCH v7 00/33] raop2 support for module-raop-sink

2016-11-06 Thread Hajime Fujita
This patch set adds a support for UDP version of RAOP (so called
raop2). Most of the RAOP devices (e.g. AppleTV, AirportExpress,
third party AV receivers) today use UDP version, so this patch
set is expected to support those devices.

This patch set can also be accessed from:
https://github.com/hfujita/pulseaudio-raop2/tree/hf/raop2-v7-next

This patch addresses several comments from reviewers.
From Arun Raghavan:
  
(https://lists.freedesktop.org/archives/pulseaudio-discuss/2016-February/thread.html)
* Use pa_split_in_place instead of pa_split in pa_str_in-list
* Remove garbage file from the log

From Anton Lundin:
https://lists.freedesktop.org/archives/pulseaudio-discuss/2016-October/027025.html
* Make sure using correct spell of KTH
* Always pa_xstrdup() and pa_xfree() on server capability discovery
  for better code maintainability.
* Split a base64 cleanup patch and an MD5 patch
* Retain KTH copyright on base64 implementation

From both:
* Stop dropping "device" key when parsing server capabilities
* Swap order between "raop: Add UDP protocol handling" and
  "raop: Parse server capabilities on discovery".


Colin Leroy (4):
  raop: Fix sink getting destroyed after one use
  raop: fix sequence number overflow
  raop: fix typos
  raop: Fix packet retransmission

Hajime Fujita (11):
  pulsecore: Add pa_strneq macro
  pulsecore: Add pa_split_space_in_place function
  pulsecore: Do in-place search in pa_str_in_list_spaces
  raop: Add UDP protocol handling
  raop: Add address to RAOP device description
  raop: Add IPv6 support
  raop: Silently drop out-of-history retransmission request
  raop: Stop recording when RTSP FLUSH is issued
  raop: Disable is_recording flag when tearing down the connection
  raop: Discard data upon getting EAGAIN on a socket
  raop: Fix memory leaks

Martin Blanchard (14):
  raop: Parse server capabilities on discovery
  raop: Do not send audio before RECORD response
  raop: Better playback resume handling
  raop: Extract encryption related code into a separate file
  raop: Move base64 implementation to a util file
  raop: Add a MD5 hashing fuction
  raop: Add BA (Basic) and DA (Digest) HTTP authentication helpers
  raop: Merge TCP and UDP code paths + refactoring
  raop: Prefer ALAC encoding to raw PCM if supported by server
  raop: Update and standardise source file headers
  raop: Rework packet's store memory management
  raop: Remove unimplemented code (PCM and AAC)
  raop: Correctly wrap RTP packet sequence number
  raop: Add back initial volume RTSP SET_PARAMETER request on connect

Matthias Wabersich (1):
  raop: Packet retransmission support for UDP

Stephen Paul Weber (1):
  raop: Do not flush when RTSP object is not ready

ced2c (2):
  raop: Fix #36: invalid access to freed object
  raop: Fix #37: OOB access in rtsp_auth_cb

 src/Makefile.am|8 +-
 src/modules/raop/module-raop-discover.c|  107 +-
 src/modules/raop/module-raop-sink.c|  630 +-
 src/modules/raop/raop-client.c | 1768 
 src/modules/raop/raop-client.h |   83 ++
 src/modules/raop/raop-crypto.c |  146 +++
 src/modules/raop/raop-crypto.h |   35 +
 src/modules/raop/raop-packet-buffer.c  |  161 +++
 src/modules/raop/raop-packet-buffer.h  |   40 +
 src/modules/raop/raop-sink.c   |  669 +++
 src/modules/raop/raop-sink.h   |   33 +
 src/modules/raop/{base64.c => raop-util.c} |  165 ++-
 src/modules/raop/{base64.h => raop-util.h} |   17 +-
 src/modules/raop/raop_client.c |  570 -
 src/modules/raop/raop_client.h |   42 -
 src/modules/rtp/rtsp_client.c  |   91 +-
 src/modules/rtp/rtsp_client.h  |   30 +-
 src/pulsecore/core-util.c  |   30 +-
 src/pulsecore/core-util.h  |2 +
 19 files changed, 3307 insertions(+), 1320 deletions(-)
 create mode 100644 src/modules/raop/raop-client.c
 create mode 100644 src/modules/raop/raop-client.h
 create mode 100644 src/modules/raop/raop-crypto.c
 create mode 100644 src/modules/raop/raop-crypto.h
 create mode 100644 src/modules/raop/raop-packet-buffer.c
 create mode 100644 src/modules/raop/raop-packet-buffer.h
 create mode 100644 src/modules/raop/raop-sink.c
 create mode 100644 src/modules/raop/raop-sink.h
 rename src/modules/raop/{base64.c => raop-util.c} (50%)
 rename src/modules/raop/{base64.h => raop-util.h} (61%)
 delete mode 100644 src/modules/raop/raop_client.c
 delete mode 100644 src/modules/raop/raop_client.h

-- 
2.9.3

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Revisiting raop2 patches

2016-11-05 Thread Hajime Fujita
Anton Lundin wrote:
> On 30 October, 2016 - Hajime Fujita wrote:
>>
>>> On Oct 26, 2016, at 9:58 PM, Hajime Fujita <crisp.fuj...@nifty.com> wrote:
>>>
>>>> On Oct 25, 2016, at 3:47 PM, Anton Lundin <gla...@acc.umu.se> wrote:
>>>
>>>> Also, value is set to NULL in some parsing blocks and not in others.
>>>> Some blocks strdup(value), and let avahi_free(value) free it, others
>>>> "steal" value and set value = NULL. I'd feel more comfortable with all
>>>> the code paths strdup'ing them selfs. Even, why not use pa_xstrdup ?
>>>
>>> Will take a look.
>>
>> So I took a look at this.
>>
>> To me, this code makes some sense.
>> Strdup is used when the raop module generates a new string based on 
>> information in a value given by Avahi.
>> Value “stealing” happens when the raop module uses an Avahi string as-is. In 
>> this case strdup’ing is essentially a waste of memory and allocation/free 
>> cost. (Nobody probably cares about the cost here though)
>>
>> “strdup” should be “pa_xstrdup”, I agree.
>>
> 
> Yea, its some added cost in the discovery process, the thing that stands
> out to me is that the code paths are different. Different means
> complexity and complexity menas potential for bugs.
> 
> Yea, its a simple case, but I don't know the allocation rules for
> avahi-strings. Its better to handle all of that logic right there and
> then, and let PA own the strings from there and onwards.
> 
> It's also the case of keeping track of whats avahi-memory and whats
> pa-memory. I'd guess pa_xfree() and avahi_free() are compatible wrappers
> ontop of free(), but who knows. Some day some crazy person might change
> one of them to be a completely different beast, and things will start to
> behave strangely.
> 
> In such a code path as this one, I'd vote for clarity and robustness
> every day of the week.
> 
> 
> One can clearly see that module-raop-discover.c inherited alot of code
> from module-zeroconf-discover.c, and this odity is there to. The same
> goes for ex. that the hashmap that keeps track of all loaded raop
> modules are called tunnels.

Okay, I understand your concern really is a valid point. I don't have strong 
preference for either side, so simply follow your suggestion.


Thanks,
Hajime
 
> //Anton - who clearly hears the bikeshedding warning bells going off
> 
> 

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Revisiting raop2 patches

2016-11-05 Thread Hajime Fujita
So now I have a new set of patches which (hopefully) address all of Anton's 
following comments.
Now the patches are rebased against `next`, as some of the raop patches have 
already been merged here.

I think the standard practice is to rebase patches on top of master, but for 
this case can I simply push the patches on top of next?


Thanks,
Hajime

Anton Lundin wrote:
> On 25 October, 2016 - Tanu Kaskinen wrote:
> 
>> On Mon, 2016-10-24 at 22:09 -0500, Hajime Fujita wrote:
>>> On Oct 24, 2016, at 4:05 PM, Anton Lundin <gla...@acc.umu.se> wrote:
>>>> On 24 October, 2016 - Colin Leroy wrote:
>>>>> On 24 October 2016 at 20h58, Tanu Kaskinen wrote:
>>>>>> It would be great to have more people reviewing patches, but I don't
>>>>>> know how to acquire those people. I don't think the reviews have to
>>>>>> necessarily be done by someone with a title of "maintainer", but on
>>>>>> the other hand, giving much trust to drive-by contributors seems risky
>>>>>> too...
>>>>>
>>>>> Reviewing is hard when you don't have an extensive knowledge of the
>>>>> codebase... I'd propose to do it, but I'd suck at it - "yeah, seems
>>>>> fine to me" :D
>>
>> Reviewing is a good way to gain knowledge of the codebase, though. Even
>> if the reviews weren't very thorough in the beginning, I'd still be
>> willing to pay that price if the new reviewer was going to stay around
>> for a longer time. (When you said "I'd propose to do it", you probably
>> didn't mean becoming a long-term reviewer, but I thought I should make
>> this point anyway.)
>>
>>>> I think we can file the raop2 code under a quite special category. It
>>>> doesn't have a big inpact outside of the raop2 code, and those bits are
>>>> quite trivial to review. I just read them my self and they looked ok to
>>>> me =)
>>
>> Are there any patches in the set that you'd be comfortable if I tagged
>> them with "Reviewed-by: Anton Lundin <gla...@acc.umu.se>"?
>>
> 
> I see what you did there Tanu =)
> 
> It sort of pushed my buttons so here we go:
> 
> 
> Support IPv6 address in pa_socket_client_new_string() (51d0fed4)
> Reviewed-by: Anton Lundin <gla...@acc.umu.se>
> 
> rtp: Freeing ioline when disconnecting (256724cc)
> Reviewed-by: Anton Lundin <gla...@acc.umu.se>
> 
> raop: Cosmetic fixes / Match coding style (1c9ccf74)
> Converts the already messed up ö in Högskolan to a Danish ö ø instead of
> the Swedish ö.
> The text looks to have bin messed up way back in time by Colin, and I've
> even saw traces that svn was involved, so what unholy things happed
> there we should probably just leave to future archaeological
> investigations to figure out.
> I'm sending a patch. Rebase / merge the coding style patch on top of that
> and I'm happy with it. 
> Reviewed-by: Anton Lundin <gla...@acc.umu.se>
> 
> raop: Add pulsecore/core-utils a pa_str_in_list function (6835e40a)
> Reviewed-by: Anton Lundin <gla...@acc.umu.se>
> 
> raop: Parse server capabilities on discovery (88cbec61)
> Why was the device part dropped from the device name? Nothing in the
> commit message says anything about that. The device part was dropped
> from the parsing to, even when some other no-op parsing blocks are left
> there for future reference.
> 
> Also, value is set to NULL in some parsing blocks and not in others.
> Some blocks strdup(value), and let avahi_free(value) free it, others
> "steal" value and set value = NULL. I'd feel more comfortable with all
> the code paths strdup'ing them selfs. Even, why not use pa_xstrdup ?
> 
> I think this patch is placed to early in the patch stack to. It adds
> options to the module-raop-sink which it can't parse.
> 
> rtp: New pa_rtsp_options function (1e7e70e4)
> Reviewed-by: Anton Lundin <gla...@acc.umu.se>
> 
> rtp: Random seq number at the beginning of the session (8e3c0047)
> Reviewed-by: Anton Lundin <gla...@acc.umu.se>
> 
> rtp: Introduce pa_rtsp_exec_ready() (5c4185ee)
> Reviewed-by: Anton Lundin <gla...@acc.umu.se>
> 
> raop: Add a MD5 hashing fuction (5f089f3)
> Also touches the KTH text, and should be corrected.
> The commit message could be clearer to. Maybe split the MD5 and the
> base64 parts into two patches?
> 
> raop: Update and standardise source file headers (d0483146)
> Removes KTH from the copyright header. Is that a good thing to do?
> 
> The rest are just to big, hard and complicated for a sane review, at
> least by me. One would need to really kno

Re: [pulseaudio-discuss] Revisiting raop2 patches

2016-10-30 Thread Hajime Fujita
Hi Anton,

> On Oct 26, 2016, at 9:58 PM, Hajime Fujita <crisp.fuj...@nifty.com> wrote:
> 
> Hi Anton,
> 
> Thank you for your effort on taking a look at the patches!
> 
>> On Oct 25, 2016, at 3:47 PM, Anton Lundin <gla...@acc.umu.se> wrote:
>> 
>> On 25 October, 2016 - Tanu Kaskinen wrote:
>> 
>>> On Mon, 2016-10-24 at 22:09 -0500, Hajime Fujita wrote:
>>>> On Oct 24, 2016, at 4:05 PM, Anton Lundin <gla...@acc.umu.se> wrote:
>>>>> On 24 October, 2016 - Colin Leroy wrote:
>>>>>> On 24 October 2016 at 20h58, Tanu Kaskinen wrote:
>>>>>>> It would be great to have more people reviewing patches, but I don't
>>>>>>> know how to acquire those people. I don't think the reviews have to
>>>>>>> necessarily be done by someone with a title of "maintainer", but on
>>>>>>> the other hand, giving much trust to drive-by contributors seems risky
>>>>>>> too...
>>>>>> 
>>>>>> Reviewing is hard when you don't have an extensive knowledge of the
>>>>>> codebase... I'd propose to do it, but I'd suck at it - "yeah, seems
>>>>>> fine to me" :D
>>> 
>>> Reviewing is a good way to gain knowledge of the codebase, though. Even
>>> if the reviews weren't very thorough in the beginning, I'd still be
>>> willing to pay that price if the new reviewer was going to stay around
>>> for a longer time. (When you said "I'd propose to do it", you probably
>>> didn't mean becoming a long-term reviewer, but I thought I should make
>>> this point anyway.)
>>> 
>>>>> I think we can file the raop2 code under a quite special category. It
>>>>> doesn't have a big inpact outside of the raop2 code, and those bits are
>>>>> quite trivial to review. I just read them my self and they looked ok to
>>>>> me =)
>>> 
>>> Are there any patches in the set that you'd be comfortable if I tagged
>>> them with "Reviewed-by: Anton Lundin <gla...@acc.umu.se>"?
>>> 
>> 
>> I see what you did there Tanu =)
>> 
>> It sort of pushed my buttons so here we go:
>> 
>> 
>> Support IPv6 address in pa_socket_client_new_string() (51d0fed4)
>> Reviewed-by: Anton Lundin <gla...@acc.umu.se>
>> 
>> rtp: Freeing ioline when disconnecting (256724cc)
>> Reviewed-by: Anton Lundin <gla...@acc.umu.se>
>> 
>> raop: Cosmetic fixes / Match coding style (1c9ccf74)
>> Converts the already messed up ö in Högskolan to a Danish ö ø instead of
>> the Swedish ö.
>> The text looks to have bin messed up way back in time by Colin, and I've
>> even saw traces that svn was involved, so what unholy things happed
>> there we should probably just leave to future archaeological
>> investigations to figure out.
>> I'm sending a patch. Rebase / merge the coding style patch on top of that
>> and I'm happy with it. 
>> Reviewed-by: Anton Lundin <gla...@acc.umu.se>
> 
> Thank you for addressing this. I hope I didn’t make a mistake in a later 
> commit to bring back this error...
> 
>> raop: Add pulsecore/core-utils a pa_str_in_list function (6835e40a)
>> Reviewed-by: Anton Lundin <gla...@acc.umu.se>
>> 
>> raop: Parse server capabilities on discovery (88cbec61)
>> Why was the device part dropped from the device name? Nothing in the
>> commit message says anything about that. The device part was dropped
>> from the parsing to, even when some other no-op parsing blocks are left
>> there for future reference.
> 
> I actually asked this to Martin (the original author of the patch) before, 
> and he did not remember the reason anymore.
> Now that nobody can explain the reason for change, maybe I should rewrite the 
> code so that it makes sense to everyone.
> 
>> Also, value is set to NULL in some parsing blocks and not in others.
>> Some blocks strdup(value), and let avahi_free(value) free it, others
>> "steal" value and set value = NULL. I'd feel more comfortable with all
>> the code paths strdup'ing them selfs. Even, why not use pa_xstrdup ?
> 
> Will take a look.

So I took a look at this.

To me, this code makes some sense.
Strdup is used when the raop module generates a new string based on information 
in a value given by Avahi.
Value “stealing” happens when the raop module uses an Avahi string as-is. In 
this case strdup’ing is essentially a waste of memory and allocation/free cost. 
(Nobody probably cares about the cost here though)

“strdup

Re: [pulseaudio-discuss] Revisiting raop2 patches

2016-10-24 Thread Hajime Fujita
Corin, Tanu, and Anton,

Thank you folks for your responses!

> On Oct 24, 2016, at 4:05 PM, Anton Lundin  wrote:
> 
> On 24 October, 2016 - Colin Leroy wrote:
> 
>> On 24 October 2016 at 20h58, Tanu Kaskinen wrote:
>> 
>> Hi, 
>> 
>>> It would be great to have more people reviewing patches, but I don't
>>> know how to acquire those people. I don't think the reviews have to
>>> necessarily be done by someone with a title of "maintainer", but on
>>> the other hand, giving much trust to drive-by contributors seems risky
>>> too...
>> 
>> Reviewing is hard when you don't have an extensive knowledge of the
>> codebase... I'd propose to do it, but I'd suck at it - "yeah, seems
>> fine to me" :D
>> 
> 
> I think we can file the raop2 code under a quite special category. It
> doesn't have a big inpact outside of the raop2 code, and those bits are
> quite trivial to review. I just read them my self and they looked ok to
> me =)

That sounds interesting. Not sure if it’s a good idea to essentially “skipping" 
reviews for non-raop2 patches, but it makes a lot of sense to focus on the 
patches that touch the core and other modules.

Actually as an author of the patches my expectation for the review was to make 
sure
a) we didn’t screw up when making changes to other parts of PA
b) naming conventions are acceptable
c) pulsecore API usages are correct

Any other concerns from maintainer’s point of view? I think this is also a good 
opportunity for me (and potentially others) to learn about the review process.

> On the other hand, the raop2 code itself is quit the opposite. It
> requires understanding of raop2 and pa.
> 
> Here comes the point: The current raop2 code is pretty much unusable.
> There are probably very few who have such old devices that they work
> with that code, and the changes only affects raop2 users.

This is a very valid point. I’d say this was already true three years ago when 
I started working on this project. And it was so disappointing to know that 
module-raop-sink didn’t work with most of the raop devices in the market 
despite its name. That’s the why I started working on this.

> I'd love to see the code merged, and even with the
> module-raop-discover module disabled by default. That way this change
> only affects users who really wants and uses this feature, and probably
> need this code to get their gear working.

FYI: in my understanding it’s already disabled by default.

> So my suggestion is to take a look at the non-raop2 patches so the
> maintainers are happy with those, and merge the lot.
> 
> 
> //Anton
> 
> 
> -- 
> Anton Lundin  +46702-161604
> ___
> pulseaudio-discuss mailing list
> pulseaudio-discuss@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH v6 00/37] raop2 support for module-raop-sink

2016-02-21 Thread Hajime Fujita
Hi Arun,

> On Feb 15, 2016, at 3:32 AM, Arun Raghavan <a...@accosted.net> wrote:
> 
> On 12 February 2016 at 12:03, Hajime Fujita <crisp.fuj...@nifty.com> wrote:
>> Hi Arun,
>> 
>> Arun Raghavan wrote:
>>> Hi Hajime,
>>> I'm still working on this, it's slow going since I have other things to
>>> do in parallel.
>> 
>> Thank you for your reply. Yeah that's totally fine. Just wanted make sure if 
>> it was appropriate to submit a new series.
>> 
>>> It's a bit hard to review this work properly per-commit, so I'm going
>>> to try to summarise the issues I've found at one go.
>>> 
>>> * There are some style issues that I'm fixing up as I find, and I'll
>>> just have that as a commit on top of your tree.
>>> 
>>> * While testing, I see there are two instances loaded every time (one
>>> for IPv4 and one for IPv6) -- wouldn't it be more user friendly to make
>>> sure we load only one? This doesn't appear to be a new issue, so not a
>>> blocker on this series
>> 
>> I've been aware of this for a while. I think my thought was that some user 
>> might want to explicitly choose IPv4 or v6 address. I'm not sure if it is a 
>> real need though.
>> 
>>> 
>>> * I tried this against Airserver on a Mac (worked) and a current
>>> generation Apple TV (did not work) -- just got stuck trying to start
>>> playback
>> 
>> Hmm you mean the latest Apple TV which came out last year? I currently don't 
>> have that one so it'll be a bit hard to debug... let me check the price :)
> 
> That's the one. I might be able to try again and get you a packet
> capture if that helps.

Yeah that’d definitely help.


Thank you,
Hajime

> 
> -- Arun
> ___
> pulseaudio-discuss mailing list
> pulseaudio-discuss@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH v6 00/37] raop2 support for module-raop-sink

2016-02-11 Thread Hajime Fujita
Hi Arun,

Arun Raghavan wrote:
> Hi Hajime,
> I'm still working on this, it's slow going since I have other things to
> do in parallel.

Thank you for your reply. Yeah that's totally fine. Just wanted make sure if it 
was appropriate to submit a new series.

> It's a bit hard to review this work properly per-commit, so I'm going
> to try to summarise the issues I've found at one go. 
> 
> * There are some style issues that I'm fixing up as I find, and I'll
> just have that as a commit on top of your tree.
> 
> * While testing, I see there are two instances loaded every time (one
> for IPv4 and one for IPv6) -- wouldn't it be more user friendly to make
> sure we load only one? This doesn't appear to be a new issue, so not a
> blocker on this series

I've been aware of this for a while. I think my thought was that some user 
might want to explicitly choose IPv4 or v6 address. I'm not sure if it is a 
real need though.

> 
> * I tried this against Airserver on a Mac (worked) and a current
> generation Apple TV (did not work) -- just got stuck trying to start
> playback

Hmm you mean the latest Apple TV which came out last year? I currently don't 
have that one so it'll be a bit hard to debug... let me check the price :)

> 
> Will reply again once I'm through the patch set.
> 
> Regards,
> Arun
> 
> On Wed, 2016-02-10 at 18:50 -0600, Hajime Fujita wrote:
>> Hi Arun,
>>
>> Are you still going through the patches?
>> If you are done, I'll submit a new series of patches that address
>> your comments.
>>
>>
>> Thanks,
>> Hajime
>>
>> Hajime Fujita wrote:
>>> Arun Raghavan wrote:
>>>> On Sun, 2016-01-31 at 22:15 -0600, Hajime Fujita wrote:
>>>>> From: Hajime Fujita <crisp.fuj...@nifty.com>
>>>>>
>>>>> This is basically same as the previous patch series,
>>>>> with several patches squashed for conciseness, rebased
>>>>> on the latest master.
>>>>> http://lists.freedesktop.org/archives/pulseaudio-discuss/2015-O
>>>>> ctober
>>>>> /024547.html
>>>>>
>>>>> This patch set adds a support for UDP version of RAOP (so
>>>>> called
>>>>> raop2). Most of the RAOP devices (e.g. AppleTV, AirportExpress,
>>>>> third party AV receivers) today use UDP version, so this patch
>>>>> set is expected to support those devices.
>>>>>
>>>>> Also the patches can be seen from here:
>>>>> https://github.com/hfujita/pulseaudio-raop2/compare/323dc5bf...
>>>>> hf/rao
>>>>> p2-v4-v8.0
>>>>>
>>>>
>>>> Thank you for your perseverance in getting this through. I'm
>>>> going to
>>>> try to do a pass through the list in the coming days.
>>>>
>>>> I'm using the raop2-v4-v8.0 branch. Please let me know if I
>>>> should be
>>>> looking at something else.
>>>
>>> Hi Arun,
>>>
>>> Thank you for taking a look at this.
>>> Yes, that is the right one. I'll start addressing your comments.
>>>
>>>
>>> Best,
>>> Hajime
>>>
>>>>
>>>> Regards,
>>>> Arun
>>>> ___
>>>> pulseaudio-discuss mailing list
>>>> pulseaudio-discuss@lists.freedesktop.org
>>>> https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
>>>>
>>>
>>> ___
>>> pulseaudio-discuss mailing list
>>> pulseaudio-discuss@lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
>>>
>>
>> ___
>> pulseaudio-discuss mailing list
>> pulseaudio-discuss@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
> ___
> pulseaudio-discuss mailing list
> pulseaudio-discuss@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
> 

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH v6 00/37] raop2 support for module-raop-sink

2016-02-10 Thread Hajime Fujita
Hi Arun,

Are you still going through the patches?
If you are done, I'll submit a new series of patches that address your comments.


Thanks,
Hajime

Hajime Fujita wrote:
> Arun Raghavan wrote:
>> On Sun, 2016-01-31 at 22:15 -0600, Hajime Fujita wrote:
>>> From: Hajime Fujita <crisp.fuj...@nifty.com>
>>>
>>> This is basically same as the previous patch series,
>>> with several patches squashed for conciseness, rebased
>>> on the latest master.
>>> http://lists.freedesktop.org/archives/pulseaudio-discuss/2015-October
>>> /024547.html
>>>
>>> This patch set adds a support for UDP version of RAOP (so called
>>> raop2). Most of the RAOP devices (e.g. AppleTV, AirportExpress,
>>> third party AV receivers) today use UDP version, so this patch
>>> set is expected to support those devices.
>>>
>>> Also the patches can be seen from here:
>>> https://github.com/hfujita/pulseaudio-raop2/compare/323dc5bf...hf/rao
>>> p2-v4-v8.0
>>>
>>
>> Thank you for your perseverance in getting this through. I'm going to
>> try to do a pass through the list in the coming days.
>>
>> I'm using the raop2-v4-v8.0 branch. Please let me know if I should be
>> looking at something else.
> 
> Hi Arun,
> 
> Thank you for taking a look at this.
> Yes, that is the right one. I'll start addressing your comments.
> 
> 
> Best,
> Hajime
> 
>>
>> Regards,
>> Arun
>> ___
>> pulseaudio-discuss mailing list
>> pulseaudio-discuss@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
>>
> 
> ___
> pulseaudio-discuss mailing list
> pulseaudio-discuss@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
> 

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH v6 00/37] raop2 support for module-raop-sink

2016-02-09 Thread Hajime Fujita
Arun Raghavan wrote:
> On Sun, 2016-01-31 at 22:15 -0600, Hajime Fujita wrote:
>> From: Hajime Fujita <crisp.fuj...@nifty.com>
>>
>> This is basically same as the previous patch series,
>> with several patches squashed for conciseness, rebased
>> on the latest master.
>> http://lists.freedesktop.org/archives/pulseaudio-discuss/2015-October
>> /024547.html
>>
>> This patch set adds a support for UDP version of RAOP (so called
>> raop2). Most of the RAOP devices (e.g. AppleTV, AirportExpress,
>> third party AV receivers) today use UDP version, so this patch
>> set is expected to support those devices.
>>
>> Also the patches can be seen from here:
>> https://github.com/hfujita/pulseaudio-raop2/compare/323dc5bf...hf/rao
>> p2-v4-v8.0
>>
> 
> Thank you for your perseverance in getting this through. I'm going to
> try to do a pass through the list in the coming days.
> 
> I'm using the raop2-v4-v8.0 branch. Please let me know if I should be
> looking at something else.

Hi Arun,

Thank you for taking a look at this.
Yes, that is the right one. I'll start addressing your comments.


Best,
Hajime

> 
> Regards,
> Arun
> ___
> pulseaudio-discuss mailing list
> pulseaudio-discuss@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
> 

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH v6 04/37] raop: Add pulsecore/core-utils a pa_str_in_list function

2016-02-09 Thread Hajime Fujita
Arun Raghavan wrote:
> On Sun, 2016-01-31 at 22:16 -0600, Hajime Fujita wrote:
>> From: Martin Blanchard <tin...@gmx.fr>
>>
>> ---
>>  src/pulsecore/core-util.c | 20 
>>  src/pulsecore/core-util.h |  5 +++--
>>  2 files changed, 23 insertions(+), 2 deletions(-)
>>
>> diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
>> index 19c89a9..9fd4301 100644
>> --- a/src/pulsecore/core-util.c
>> +++ b/src/pulsecore/core-util.c
>> @@ -2977,6 +2977,26 @@ bool pa_in_system_mode(void) {
>>  return !!atoi(e);
>>  }
>>  
>> +/* Checks a delimiters-separated list of words in haystack for needle */
>> +bool pa_str_in_list(const char *haystack, const char *delimiters, const 
>> char *needle) {
>> +char *s;
>> +const char *state = NULL;
>> +
>> +if (!haystack || !needle)
>> +return false;
>> +
>> +while ((s = pa_split(haystack, delimiters, ))) {
> 
> Would be nicer to use pa_split_in_place() here.

Sure. Actually there is another function pa_str_in_list_spaces() right after 
this, which has almost the same structure including use of pa_split. I think 
pa_str_in_list() was written based on pa_str_in_list_spaces().

Do you also want to modify pa_str_in_list_spaces() so it uses 
pa_split_in_places()? Perhaps in a separate commit.


Thanks,
Hajime

> 
> -- Arun
> 
>> +if (pa_streq(needle, s)) {
>> +pa_xfree(s);
>> +return true;
>> +}
>> +
>> +pa_xfree(s);
>> +}
>> +
>> +return false;
>> +}
>> +
>>  /* Checks a whitespace-separated list of words in haystack for needle */
>>  bool pa_str_in_list_spaces(const char *haystack, const char *needle) {
>>  char *s;
>> diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h
>> index d5a2d39..56b527f 100644
>> --- a/src/pulsecore/core-util.h
>> +++ b/src/pulsecore/core-util.h
>> @@ -109,8 +109,8 @@ static inline const char *pa_strna(const char *x) {
>>  return x ? x : "n/a";
>>  }
>>  
>> -char *pa_split(const char *c, const char*delimiters, const char **state);
>> -const char *pa_split_in_place(const char *c, const char*delimiters, int *n, 
>> const char **state);
>> +char *pa_split(const char *c, const char *delimiters, const char **state);
>> +const char *pa_split_in_place(const char *c, const char *delimiters, int 
>> *n, const char **state);
>>  char *pa_split_spaces(const char *c, const char **state);
>>  
>>  char *pa_strip_nl(char *s);
>> @@ -228,6 +228,7 @@ static inline bool pa_safe_streq(const char *a, const 
>> char *b) {
>>  }
>>  
>>  bool pa_str_in_list_spaces(const char *needle, const char *haystack);
>> +bool pa_str_in_list(const char *haystack, const char *delimiters, const 
>> char *needle);
>>  
>>  char *pa_get_host_name_malloc(void);
>>  char *pa_get_user_name_malloc(void);
> ___
> pulseaudio-discuss mailing list
> pulseaudio-discuss@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
> 

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH v6 16/37] raop: Add the core implementation of RAOP authentication

2016-02-09 Thread Hajime Fujita
Arun Raghavan wrote:
> On Sun, 2016-01-31 at 22:16 -0600, Hajime Fujita wrote:
>> From: Martin Blanchard <tch...@gmx.com>
>>
>> RAOP authentication (password) is based on BA and DA HTTP authentication
>> schemes. This patch adds the RSTP client the ability to specify the caller
>> of server response status. Tracking the '401 Unauthorized' status allow
>> the RAOP client to respond the server challenge authentication request.
>> This patch adds the core implementation but does not introduce the
>> authentication scheme in the RAOP connection process yet.
>> ---
>>  src/modules/raop/raop_client.c  |  245 +-
>>  src/modules/raop/raop_client.c.orig | 1495 
>> +++
> 
> Please remove this file from this commit rather than adding it and
> removing it later.

Oops. Good catch.


Thank you,
Hajime

> 
> -- Arun
> 
>>  src/modules/raop/raop_client.h  |4 +
>>  src/modules/rtp/rtsp_client.c   |   83 +-
>>  src/modules/rtp/rtsp_client.h   |   26 +-
>>  5 files changed, 1810 insertions(+), 43 deletions(-)
>>  create mode 100644 src/modules/raop/raop_client.c.orig
>>
>> diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c
>> index a2ec91e..1323cd0 100644
>> --- a/src/modules/raop/raop_client.c
>> +++ b/src/modules/raop/raop_client.c
>> @@ -65,6 +65,9 @@
>>  #define VOLUME_MIN -144
>>  #define VOLUME_MAX 0
>>  
>> +#define USER_AGENT "iTunes/11.0.4 (Windows; N)"
>> +#define USER_NAME "iTunes"
>> +
>>  #define DEFAULT_RAOP_PORT 5000
>>  #define UDP_DEFAULT_AUDIO_PORT 6000
>>  #define UDP_DEFAULT_CONTROL_PORT 6001
>> @@ -85,13 +88,15 @@ struct pa_raop_client {
>>  pa_core *core;
>>  char *host;
>>  uint16_t port;
>> -char *sid;
>>  pa_rtsp_client *rtsp;
>> -pa_raop_protocol_t protocol;
>> +char *sci, *sid;
>> +char *pwd;
>>  
>>  uint8_t jack_type;
>>  uint8_t jack_status;
>>  
>> +pa_raop_protocol_t protocol;
>> +
>>  int encryption; /* Enable encryption? */
>>  pa_raop_secret *aes;
>>  
>> @@ -125,6 +130,9 @@ struct pa_raop_client {
>>  uint32_t udp_sync_interval;
>>  uint32_t udp_sync_count;
>>  
>> +pa_raop_client_auth_cb_t udp_auth_callback;
>> +void *udp_auth_userdata;
>> +
>>  pa_raop_client_setup_cb_t udp_setup_callback;
>>  void *udp_setup_userdata;
>>  
>> @@ -576,7 +584,7 @@ static void do_rtsp_announce(pa_raop_client *c) {
>>  pa_xfree(sdp);
>>  }
>>  
>> -static void tcp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
>> pa_headerlist* headers, void *userdata) {
>> +static void tcp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
>> pa_rtsp_status status, pa_headerlist* headers, void *userdata) {
>>  pa_raop_client* c = userdata;
>>  pa_assert(c);
>>  pa_assert(rtsp);
>> @@ -675,12 +683,13 @@ static void tcp_rtsp_cb(pa_rtsp_client *rtsp, 
>> pa_rtsp_state state, pa_headerlist
>>  }
>>  }
>>  
>> -static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
>> pa_headerlist *headers, void *userdata) {
>> +static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
>> pa_rtsp_status status, pa_headerlist *headers, void *userdata) {
>>  pa_raop_client *c = userdata;
>>  
>>  pa_assert(c);
>>  pa_assert(rtsp);
>>  pa_assert(rtsp == c->rtsp);
>> +pa_assert(STATUS_OK == status);
>>  
>>  switch (state) {
>>  case STATE_CONNECT: {
>> @@ -982,6 +991,178 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, 
>> pa_rtsp_state state, pa_headerlist
>>  }
>>  }
>>  
>> +static void rtsp_authentication_cb(pa_rtsp_client *rtsp, pa_rtsp_state 
>> state, pa_rtsp_status status, pa_headerlist *headers, void *userdata) {
>> +pa_raop_client *c = userdata;
>> +
>> +pa_assert(c);
>> +pa_assert(rtsp);
>> +pa_assert(rtsp == c->rtsp);
>> +
>> +switch (state) {
>> +case STATE_CONNECT: {
>> +char *sci = NULL, *sac = NULL;
>> +uint16_t rac;
>> +struct {
>> +uint32_t ci1;
>> +uint32_t ci2;
>> +} rci;
>> +
>> +pa_random(, sizeof(rci));
>> +/* Generate a random Client-Instance number */
>> +sci = pa_sprintf_malloc("%08x%08x",rci.c

Re: [pulseaudio-discuss] [PATCH v6 09/37] raop: Add UDP protocol handling

2016-02-09 Thread Hajime Fujita
Arun Raghavan wrote:
> On Sun, 2016-01-31 at 22:16 -0600, Hajime Fujita wrote:
>> From: Hajime Fujita <crisp.fuj...@nifty.com>
>>
>> There are two versions in the RAOP protocol; one uses TCP and the
>> other uses UDP. Current raop implementation only supports TCP
>> version.
>>
>> This patch adds an initial UDP protocol support for RAOP.
>> It is based on Martin Blanchard's work
>> (http://repo.or.cz/w/pulseaudio-raopUDP.git/shortlog/refs/heads/raop)
>> which is inspired by Christophe Fergeau's work
>> (https://github.com/zx2c4/pulseaudio-raop2).
>>
>> Matrin's modifications were edited by Hajime Fujita, so that it
>> would support both TCP and UDP protocol in a single module.
>>
>> Also this patch includes a fix that was found thanks to Matthias,
>> who reported that his ALAC
>> codec support fixed the issue.
>> https://bugs.freedesktop.org/show_bug.cgi?id=42804#c30
>> ---
> 
> Ideally this patch should come before "raop: Parse server capabilities
> on discovery" as it introduces modargs that the previous commit uses.
> If there are conflicts on rebase though, I'm okay with not reordering.

Makes sense. Actually I am able to reorder.


Thanks,
Hajime

> 
>>  src/modules/raop/module-raop-sink.c |  457 +--
>>  src/modules/raop/raop_client.c  | 1063 
>> +++
>>  src/modules/raop/raop_client.h  |   39 +-
>>  3 files changed, 1400 insertions(+), 159 deletions(-)
>>
>> diff --git a/src/modules/raop/module-raop-sink.c 
>> b/src/modules/raop/module-raop-sink.c
>> index 6fc3d94..1eadde2 100644
>> --- a/src/modules/raop/module-raop-sink.c
>> +++ b/src/modules/raop/module-raop-sink.c
>> @@ -66,12 +66,13 @@ PA_MODULE_USAGE(
>>  "sink_name= "
>>  "sink_properties= "
>>  "server=  "
>> +"protocol= "
>> +"encryption= "
>> +"codec= "
>>  "format= "
>>  "rate= "
>>  "channels=");
>>  
>> -#define DEFAULT_SINK_NAME "raop"
>> -
>>  struct userdata {
>>  pa_core *core;
>>  pa_module *module;
>> @@ -82,6 +83,8 @@ struct userdata {
>>  pa_rtpoll_item *rtpoll_item;
>>  pa_thread *thread;
>>  
>> +pa_raop_protocol_t protocol;
>> +
>>  pa_memchunk raw_memchunk;
>>  pa_memchunk encoded_memchunk;
>>  
>> @@ -97,7 +100,6 @@ struct userdata {
>>  int32_t rate;
>>  
>>  pa_smoother *smoother;
>> -int fd;
>>  
>>  int64_t offset;
>>  int64_t encoding_overhead;
>> @@ -107,12 +109,26 @@ struct userdata {
>>  pa_raop_client *raop;
>>  
>>  size_t block_size;
>> +
>> +/* Members only for the TCP protocol */
>> +int tcp_fd;
>> +
>> +/* Members only for the UDP protocol */
>> +int udp_control_fd;
>> +int udp_timing_fd;
>> +
>> +/* For UDP thread wakeup clock calculation */
>> +pa_usec_t udp_playback_start;
>> +uint32_t  udp_sent_packets;
>>  };
>>  
>>  static const char* const valid_modargs[] = {
>>  "sink_name",
>>  "sink_properties",
>>  "server",
>> +"protocol",
>> +"encryption",
>> +"codec",
>>  "format",
>>  "rate",
>>  "channels",
>> @@ -120,23 +136,26 @@ static const char* const valid_modargs[] = {
>>  };
>>  
>>  enum {
>> -SINK_MESSAGE_PASS_SOCKET = PA_SINK_MESSAGE_MAX,
>> -SINK_MESSAGE_RIP_SOCKET
>> +SINK_MESSAGE_TCP_PASS_SOCKET = PA_SINK_MESSAGE_MAX,
>> +SINK_MESSAGE_TCP_RIP_SOCKET,
>> +SINK_MESSAGE_UDP_SETUP,
>> +SINK_MESSAGE_UDP_RECORD,
>> +SINK_MESSAGE_UDP_DISCONNECTED,
>>  };
>>  
>>  /* Forward declarations: */
>>  static void sink_set_volume_cb(pa_sink *);
>>  
>> -static void on_connection(int fd, void *userdata) {
>> +static void tcp_on_connection(int fd, void *userdata) {
>>  int so_sndbuf = 0;
>>  socklen_t sl = sizeof(int);
>>  struct userdata *u = userdata;
>>  pa_assert(u);
>>  
>> -pa_assert(u->fd < 0);
>> -u->fd = fd;
>> +pa_assert(u->tcp_fd < 0);
>> +u->tcp_fd = fd;
>>  
>> -if (getsockopt(u->fd, SOL_SOCKET, SO_SNDBUF, _sndbuf, ) < 0)
>> +if (ge

Re: [pulseaudio-discuss] [PATCH v6 05/37] raop: Parse server capabilities on discovery

2016-02-09 Thread Hajime Fujita
Arun Raghavan wrote:
> On Sun, 2016-01-31 at 22:16 -0600, Hajime Fujita wrote:
>> From: Martin Blanchard <tin...@gmx.fr>
>>
>> During the discovery phase, raop servers send theirs capabilities
>> (supported encryption, audio codec...). These should be passed to the
>> raop sink via module's arguments.
>> ---
>>  src/modules/raop/module-raop-discover.c | 100
>> 
>>  1 file changed, 90 insertions(+), 10 deletions(-)
>>
>> diff --git a/src/modules/raop/module-raop-discover.c
>> b/src/modules/raop/module-raop-discover.c
>> index 1ced777..f174da3 100644
>> --- a/src/modules/raop/module-raop-discover.c
>> +++ b/src/modules/raop/module-raop-discover.c
>> @@ -138,7 +138,10 @@ static void resolver_cb(
>>  void *userdata) {
>>  struct userdata *u = userdata;
>>  struct tunnel *tnl;
>> -char *device = NULL, *nicename, *dname, *vname, *args;
>> +char *nicename, *dname, *vname, *args;
>> +char *tp = NULL, *et = NULL, *cn = NULL;
>> +char *ch = NULL, *ss = NULL, *sr = NULL;
>> +char *t = NULL;
>>  char at[AVAHI_ADDRESS_STR_MAX];
>>  AvahiStringList *l;
>>  pa_module *m;
>> @@ -166,8 +169,54 @@ static void resolver_cb(
>>  pa_assert_se(avahi_string_list_get_pair(l, , ,
>> NULL) == 0);
>>  
>>  pa_log_debug("Found key: '%s' with value: '%s'", key,
>> value);
>> -if (pa_streq(key, "device")) {
>> -device = value;
> 
> Is there a reason the device is dropped here. Ideally this should be a
> separate commit, but for now, if we have a reason we can put in the
> commit message, that'd be fine too.

Hmm actually I'm not sure why device was dropped here.
At least I'll make it a separate patch.


Thanks,
Hajime

> 
> -- Arun
> 
>> +
>> +if (pa_streq(key, "tp")) {
>> +/* Transport protocol:
>> + *  - TCP = only TCP,
>> + *  - UDP = only UDP,
>> + *  - TCP,UDP = both supported (UDP should be prefered)
>> */
>> + if (pa_str_in_list(value, ",", "UDP"))
>> + tp = strdup("UDP");
>> +else if (pa_str_in_list(value, ",", "TCP"))
>> +tp = strdup("TCP");
>> +else
>> +tp = strdup(value);
>> +} else if (pa_streq(key, "et")) {
>> +/* Supported encryption types:
>> + *  - 0 = none,
>> + *  - 1 = RSA,
>> + *  - 2 = FairPlay,
>> + *  - 3 = MFiSAP,
>> + *  - 4 = FairPlay SAPv2.5. */
>> + if (pa_str_in_list(value, ",", "1"))
>> + et = strdup("RSA");
>> + else
>> + et = strdup("none");
>> +} else if (pa_streq(key, "cn")) {
>> +/* Suported audio codecs:
>> + *  - 0 = PCM,
>> + *  - 1 = ALAC,
>> + *  - 2 = AAC,
>> + *  - 3 = AAC ELD. */
>> +cn = strdup("PCM");
>> +} else if (pa_streq(key, "md")) {
>> +/* Supported metadata types:
>> + *  - 0 = text,
>> + *  - 1 = artwork,
>> + *  - 2 = progress. */
>> +} else if (pa_streq(key, "pw")) {
>> +/* Requires password ? (true/false) */
>> +} else if (pa_streq(key, "ch")) {
>> +/* Number of channels */
>> +ch = value;
>> +value = NULL;
>> +} else if (pa_streq(key, "ss")) {
>> +/* Sample size */
>> +ss = value;
>> +value = NULL;
>> +} else if (pa_streq(key, "sr")) {
>> +/* Sample rate */
>> +sr = value;
>>  value = NULL;
>>  }
>>  
>> @@ -175,19 +224,13 @@ static void resolver_cb(
>>  avahi_free(value);
>>  }
>>  
>> -if (device)
>> -dname = pa_sprintf_malloc("raop.%s.%s", host_name, device);
>> -else
>> -dname = pa_sprintf_malloc("raop.%s", host_name);
>> -
>> +dname = pa_sprintf_malloc("raop_output.%s", host_name);
>>  if (!(vname = pa_namereg_make_valid_name(dname))) {
>>  pa_log("Cannot construct valid device name from '%s'.&q

[pulseaudio-discuss] [PATCH v6 13/37] raop: Extract encryption related code into a separate file

2016-01-31 Thread Hajime Fujita
From: Martin Blanchard 

That makes the raop_client.c code smaller/cleaner and will simplify
addition of more crypto related stuffs like authentication.
---
 src/Makefile.am|   1 +
 src/modules/raop/raop_client.c | 116 +---
 src/modules/raop/raop_client.h |   3 +-
 src/modules/raop/raop_crypto.c | 146 +
 src/modules/raop/raop_crypto.h |  35 ++
 5 files changed, 215 insertions(+), 86 deletions(-)
 create mode 100644 src/modules/raop/raop_crypto.c
 create mode 100644 src/modules/raop/raop_crypto.h

diff --git a/src/Makefile.am b/src/Makefile.am
index d60cc19..e5b9131 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1133,6 +1133,7 @@ librtp_la_LIBADD = $(AM_LIBADD) 
libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@
 
 libraop_la_SOURCES = \
 modules/raop/raop_client.c modules/raop/raop_client.h \
+modules/raop/raop_crypto.c modules/raop/raop_crypto.h \
 modules/raop/base64.c modules/raop/base64.h \
 modules/raop/raop_packet_buffer.h modules/raop/raop_packet_buffer.c
 libraop_la_CFLAGS = $(AM_CFLAGS) $(OPENSSL_CFLAGS) 
-I$(top_srcdir)/src/modules/rtp
diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c
index e6e3737..5c825eb 100644
--- a/src/modules/raop/raop_client.c
+++ b/src/modules/raop/raop_client.c
@@ -32,13 +32,6 @@
 #include 
 #endif
 
-/* TODO: Replace OpenSSL with NSS */
-#include 
-#include 
-#include 
-#include 
-#include 
-
 #include 
 #include 
 #include 
@@ -56,12 +49,11 @@
 #include 
 
 #include "raop_client.h"
-#include "rtsp_client.h"
-#include "base64.h"
 
+#include "rtsp_client.h"
 #include "raop_packet_buffer.h"
-
-#define AES_CHUNKSIZE 16
+#include "raop_crypto.h"
+#include "base64.h"
 
 #define JACK_STATUS_DISCONNECTED 0
 #define JACK_STATUS_CONNECTED 1
@@ -100,12 +92,8 @@ struct pa_raop_client {
 uint8_t jack_type;
 uint8_t jack_status;
 
-/* Encryption Related bits */
 int encryption; /* Enable encryption? */
-AES_KEY aes;
-uint8_t aes_iv[AES_CHUNKSIZE]; /* Initialization vector for aes-cbc */
-uint8_t aes_nv[AES_CHUNKSIZE]; /* Next vector for aes-cbc */
-uint8_t aes_key[AES_CHUNKSIZE]; /* Key for aes-cbc */
+pa_raop_secret *aes;
 
 uint16_t seq;
 uint32_t rtptime;
@@ -240,50 +228,6 @@ static inline void bit_writer(uint8_t **buffer, uint8_t 
*bit_pos, int *size, uin
 }
 }
 
-static int rsa_encrypt(uint8_t *text, int len, uint8_t *res) {
-const char n[] =
-"59dE8qLieItsH1WgjrcFRKj6eUWqi+bGLOX1HL3U3GhC/j0Qg90u3sG/1CUtwC"
-"5vOYvfDmFI6oSFXi5ELabWJmT2dKHzBJKa3k9ok+8t9ucRqMd6DZHJ2YCCLlDR"
-"KSKv6kDqnw4UwPdpOMXziC/AMj3Z/lUVX1G7WSHCAWKf1zNS1eLvqr+boEjXuB"
-"OitnZ/bDzPHrTOZz0Dew0uowxf/+sG+NCK3eQJVxqcaJ/vEHKIVd2M+5qL71yJ"
-"Q+87X6oV3eaYvt3zWZYD6z5vYTcrtij2VZ9Zmni/UAaHqn9JdsBWLUEpVviYnh"
-"imNVvYFZeCXg/IdTQ+x4IRdiXNv5hEew==";
-const char e[] = "AQAB";
-uint8_t modules[256];
-uint8_t exponent[8];
-int size;
-RSA *rsa;
-
-rsa = RSA_new();
-size = pa_base64_decode(n, modules);
-rsa->n = BN_bin2bn(modules, size, NULL);
-size = pa_base64_decode(e, exponent);
-rsa->e = BN_bin2bn(exponent, size, NULL);
-
-size = RSA_public_encrypt(len, text, res, rsa, RSA_PKCS1_OAEP_PADDING);
-RSA_free(rsa);
-return size;
-}
-
-static int aes_encrypt(pa_raop_client *c, uint8_t *data, int size) {
-uint8_t *buf;
-int i=0, j;
-
-pa_assert(c);
-
-memcpy(c->aes_nv, c->aes_iv, AES_CHUNKSIZE);
-while (i+AES_CHUNKSIZE <= size) {
-buf = data + i;
-for (j=0; jaes_nv[j];
-
-AES_encrypt(buf, buf, >aes);
-memcpy(c->aes_nv, buf, AES_CHUNKSIZE);
-i += AES_CHUNKSIZE;
-}
-return i;
-}
-
 static inline void rtrimchar(char *str, char rc) {
 char *sp = str + strlen(str) - 1;
 while (sp >= str && *sp == rc) {
@@ -570,8 +514,6 @@ static ssize_t udp_send_audio_packet(pa_raop_client *c, 
bool retrans, uint8_t *b
 }
 
 static void do_rtsp_announce(pa_raop_client *c) {
-int i;
-uint8_t rsakey[512];
 char *key, *iv, *sac = NULL, *sdp;
 uint16_t rand_data;
 const char *ip;
@@ -583,22 +525,20 @@ static void do_rtsp_announce(pa_raop_client *c) {
 pa_rtsp_set_url(c->rtsp, url);
 pa_xfree(url);
 
-/* Now encrypt our aes_public key to send to the device. */
-i = rsa_encrypt(c->aes_key, AES_CHUNKSIZE, rsakey);
-pa_base64_encode(rsakey, i, );
-rtrimchar(key, '=');
-pa_base64_encode(c->aes_iv, AES_CHUNKSIZE, );
-rtrimchar(iv, '=');
-
 /* UDP protocol does not need "Apple-Challenge" at announce. */
 if (c->protocol == RAOP_TCP) {
 pa_random(_data, sizeof(rand_data));
-pa_base64_encode(_data, AES_CHUNKSIZE, );
+pa_base64_encode(_data, sizeof(rand_data), );
 rtrimchar(sac, '=');
 pa_rtsp_add_header(c->rtsp, 

[pulseaudio-discuss] [PATCH v6 22/37] raop: Fix sink getting destroyed after one use

2016-01-31 Thread Hajime Fujita
From: Colin Leroy 

It is expected to get disconnected after switching back to a
different sink.
---
 src/modules/raop/raop-sink.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/modules/raop/raop-sink.c b/src/modules/raop/raop-sink.c
index 23989d1..2d8157e 100644
--- a/src/modules/raop/raop-sink.c
+++ b/src/modules/raop/raop-sink.c
@@ -252,7 +252,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void 
*data, int64_t offse
 
 if (u->sink->thread_info.state == PA_SINK_SUSPENDED)
 pa_rtpoll_set_timer_disabled(u->rtpoll);
-else
+else if (u->sink->thread_info.state != PA_SINK_IDLE)
 pa_module_unload_request(u->module, true);
 
 return 0;
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 04/37] raop: Add pulsecore/core-utils a pa_str_in_list function

2016-01-31 Thread Hajime Fujita
From: Martin Blanchard 

---
 src/pulsecore/core-util.c | 20 
 src/pulsecore/core-util.h |  5 +++--
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index 19c89a9..9fd4301 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -2977,6 +2977,26 @@ bool pa_in_system_mode(void) {
 return !!atoi(e);
 }
 
+/* Checks a delimiters-separated list of words in haystack for needle */
+bool pa_str_in_list(const char *haystack, const char *delimiters, const char 
*needle) {
+char *s;
+const char *state = NULL;
+
+if (!haystack || !needle)
+return false;
+
+while ((s = pa_split(haystack, delimiters, ))) {
+if (pa_streq(needle, s)) {
+pa_xfree(s);
+return true;
+}
+
+pa_xfree(s);
+}
+
+return false;
+}
+
 /* Checks a whitespace-separated list of words in haystack for needle */
 bool pa_str_in_list_spaces(const char *haystack, const char *needle) {
 char *s;
diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h
index d5a2d39..56b527f 100644
--- a/src/pulsecore/core-util.h
+++ b/src/pulsecore/core-util.h
@@ -109,8 +109,8 @@ static inline const char *pa_strna(const char *x) {
 return x ? x : "n/a";
 }
 
-char *pa_split(const char *c, const char*delimiters, const char **state);
-const char *pa_split_in_place(const char *c, const char*delimiters, int *n, 
const char **state);
+char *pa_split(const char *c, const char *delimiters, const char **state);
+const char *pa_split_in_place(const char *c, const char *delimiters, int *n, 
const char **state);
 char *pa_split_spaces(const char *c, const char **state);
 
 char *pa_strip_nl(char *s);
@@ -228,6 +228,7 @@ static inline bool pa_safe_streq(const char *a, const char 
*b) {
 }
 
 bool pa_str_in_list_spaces(const char *needle, const char *haystack);
+bool pa_str_in_list(const char *haystack, const char *delimiters, const char 
*needle);
 
 char *pa_get_host_name_malloc(void);
 char *pa_get_user_name_malloc(void);
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 19/37] raop: Update and standardise source file headers

2016-01-31 Thread Hajime Fujita
From: Martin Blanchard <tch...@gmx.com>

---
 src/modules/raop/raop-client.c|  2 ++
 src/modules/raop/raop-packet-buffer.c | 11 +--
 src/modules/raop/raop-packet-buffer.h | 17 -
 src/modules/raop/raop-sink.c  |  1 +
 src/modules/raop/raop-util.c  |  3 +--
 5 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index c41a753..d5d636d 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -2,6 +2,8 @@
   This file is part of PulseAudio.
 
   Copyright 2008 Colin Guthrie
+  Copyright 2013 Hajime Fujita
+  Copyright 2013 Martin Blanchard
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
diff --git a/src/modules/raop/raop-packet-buffer.c 
b/src/modules/raop/raop-packet-buffer.c
index ef8ea15..d9d8549 100644
--- a/src/modules/raop/raop-packet-buffer.c
+++ b/src/modules/raop/raop-packet-buffer.c
@@ -1,15 +1,15 @@
 /***
-  Circular buffer for RTP audio packets with random access support
-  by RTP sequence number.
+  This file is part of PulseAudio.
 
-  Copyright 2013 Matthias Wabersich, Hajime Fujita
+  Copyright 2013 Matthias Wabersich
+  Copyright 2013 Hajime Fujita
 
-  This is free software; you can redistribute it and/or modify
+  PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
   by the Free Software Foundation; either version 2.1 of the License,
   or (at your option) any later version.
 
-  This is distributed in the hope that it will be useful, but
+  PulseAudio 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.
@@ -18,7 +18,6 @@
   along with PulseAudio; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
   USA.
-
 ***/
 
 #include 
diff --git a/src/modules/raop/raop-packet-buffer.h 
b/src/modules/raop/raop-packet-buffer.h
index d8a08a0..69a0ce1 100644
--- a/src/modules/raop/raop-packet-buffer.h
+++ b/src/modules/raop/raop-packet-buffer.h
@@ -1,18 +1,18 @@
-#ifndef RAOP_PACKET_BUFFER_H_INCLUDED
-#define RAOP_PACKET_BUFFER_H_INCLUDED
+#ifndef fooraoppacketbufferfoo
+#define fooraoppacketbufferfoo
 
 /***
-  Circular buffer for RTP audio packets with random access support
-  by RTP sequence number.
+  This file is part of PulseAudio.
 
-  Copyright 2013 Matthias Wabersich, Hajime Fujita
+  Copyright 2013 Matthias Wabersich
+  Copyright 2013 Hajime Fujita
 
-  This is free software; you can redistribute it and/or modify
+  PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
   by the Free Software Foundation; either version 2.1 of the License,
   or (at your option) any later version.
 
-  This is distributed in the hope that it will be useful, but
+  PulseAudio 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.
@@ -21,7 +21,6 @@
   along with PulseAudio; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
   USA.
-
 ***/
 
 struct pa_raop_packet_element;
@@ -39,4 +38,4 @@ void pa_raop_pb_delete(pa_raop_packet_buffer *pb);
 void pa_raop_pb_write_packet(pa_raop_packet_buffer *pb, uint16_t seq_num, 
const uint8_t *packet_data, ssize_t packet_length);
 ssize_t pa_raop_pb_read_packet(pa_raop_packet_buffer *pb, uint16_t seq_num, 
uint8_t **packet_data);
 
-#endif /* RAOP_PACKET_BUFFER_H_INCLUDED */
+#endif
diff --git a/src/modules/raop/raop-sink.c b/src/modules/raop/raop-sink.c
index 4f743be..22b1ccc 100644
--- a/src/modules/raop/raop-sink.c
+++ b/src/modules/raop/raop-sink.c
@@ -3,6 +3,7 @@
 
   Copyright 2004-2006 Lennart Poettering
   Copyright 2008 Colin Guthrie
+  Copyright 2013 Hajime Fujita
   Copyright 2013 Martin Blanchard
 
   PulseAudio is free software; you can redistribute it and/or modify
diff --git a/src/modules/raop/raop-util.c b/src/modules/raop/raop-util.c
index 8095417..0d4eea7 100644
--- a/src/modules/raop/raop-util.c
+++ b/src/modules/raop/raop-util.c
@@ -1,8 +1,7 @@
 /***
   This file is part of PulseAudio.
 
-  Copyright 2013 Martin Blanchard
-  Copyright Kungliga Tekniska Høgskolan & Colin Guthrie
+  Copyright 2008 Colin Guthrie
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freed

[pulseaudio-discuss] [PATCH v6 31/37] raop: Add back initial volume RTSP SET_PARAMETER request on connect

2016-01-31 Thread Hajime Fujita
From: Martin Blanchard 

Regression introduced in commit 8c6407f:
raop: Merge TCP and UDP code paths + refactoring

Anyway, we need to determine if initial volume has to be setup before
sending RECORD or after:

- Setting it up *before* shouldn't be a problem: sink.c waits for
CONNECT state, set the volume and client.c triggers RECORD only once
he's got the SET_PARAMETER reply from server.

- Setting it up *after* seems to be more difficult if we try not to
send any audio before receiving the SET_PARAMETER reply form server. A
solution may be to send SET_PARAMETER just after the RECORD server
response is received and hope that it get processed by server during the
2sec latency/buffering time...

Attached patch implement that last solution. Works for me, but I cannot
guaranty it will with your hardware...
---
 src/modules/raop/raop-sink.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/src/modules/raop/raop-sink.c b/src/modules/raop/raop-sink.c
index 2d8157e..6b707cf 100644
--- a/src/modules/raop/raop-sink.c
+++ b/src/modules/raop/raop-sink.c
@@ -95,6 +95,8 @@ enum {
 
 static void userdata_free(struct userdata *u);
 
+static void sink_set_volume_cb(pa_sink *s);
+
 static void raop_state_cb(pa_raop_state_t state, void *userdata) {
 struct userdata *u = userdata;
 
@@ -228,6 +230,9 @@ static int sink_process_msg(pa_msgobject *o, int code, void 
*data, int64_t offse
 /* Our stream has been suspended so we just flush 
it... */
 pa_rtpoll_set_timer_disabled(u->rtpoll);
 pa_raop_client_flush(u->raop);
+} else {
+/* Set the initial volume */
+sink_set_volume_cb(u->sink);
 }
 
 return 0;
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 25/37] raop: Fix packet retransmission

2016-01-31 Thread Hajime Fujita
From: Colin Leroy 

Fix UDP header decoding (sequence number and number of packets);
Fix missing pa_memblock_release() causing assertions after retransmission.
---
 src/modules/raop/raop-client.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index 471a217..3b458b3 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -470,6 +470,7 @@ static ssize_t send_udp_audio_packet(pa_raop_client *c, 
pa_memchunk *block, size
 written = pa_write(c->udp_sfd, buffer, packet->length, NULL);
 if (written < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
 pa_log_debug("Discarding UDP (audio, seq=%d) packet due to EAGAIN 
(%s)", c->seq, pa_cstrerror(errno));
+pa_memblock_release(packet->memblock);
 return (ssize_t) packet->length;
 }
 
@@ -525,9 +526,11 @@ static ssize_t resend_udp_audio_packets(pa_raop_client *c, 
uint16_t seq, uint16_
 written = pa_write(c->udp_cfd, buffer, packet->length, NULL);
 if (written < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
 pa_log_debug("Discarding UDP (audio-restransmitted, seq=%d) packet 
due to EAGAIN", seq + i);
+pa_memblock_release(packet->memblock);
 continue;
 }
 
+pa_memblock_release(packet->memblock);
 total +=  written;
 }
 
@@ -582,8 +585,8 @@ static size_t handle_udp_control_packet(pa_raop_client *c, 
const uint8_t packet[
 if (size != 8 || packet[0] != 0x80)
 return 1;
 
-seq = ntohs((uint16_t) packet[4]);
-nbp = ntohs((uint16_t) packet[6]);
+seq = ntohs((uint16_t) (packet[4] | packet[5] << 8));
+nbp = ntohs((uint16_t) (packet[6] | packet[7] << 8));
 if (nbp <= 0)
 return 1;
 
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 09/37] raop: Add UDP protocol handling

2016-01-31 Thread Hajime Fujita
From: Hajime Fujita <crisp.fuj...@nifty.com>

There are two versions in the RAOP protocol; one uses TCP and the
other uses UDP. Current raop implementation only supports TCP
version.

This patch adds an initial UDP protocol support for RAOP.
It is based on Martin Blanchard's work
(http://repo.or.cz/w/pulseaudio-raopUDP.git/shortlog/refs/heads/raop)
which is inspired by Christophe Fergeau's work
(https://github.com/zx2c4/pulseaudio-raop2).

Matrin's modifications were edited by Hajime Fujita, so that it
would support both TCP and UDP protocol in a single module.

Also this patch includes a fix that was found thanks to Matthias,
who reported that his ALAC
codec support fixed the issue.
https://bugs.freedesktop.org/show_bug.cgi?id=42804#c30
---
 src/modules/raop/module-raop-sink.c |  457 +--
 src/modules/raop/raop_client.c  | 1063 +++
 src/modules/raop/raop_client.h  |   39 +-
 3 files changed, 1400 insertions(+), 159 deletions(-)

diff --git a/src/modules/raop/module-raop-sink.c 
b/src/modules/raop/module-raop-sink.c
index 6fc3d94..1eadde2 100644
--- a/src/modules/raop/module-raop-sink.c
+++ b/src/modules/raop/module-raop-sink.c
@@ -66,12 +66,13 @@ PA_MODULE_USAGE(
 "sink_name= "
 "sink_properties= "
 "server=  "
+"protocol= "
+"encryption= "
+"codec= "
 "format= "
 "rate= "
 "channels=");
 
-#define DEFAULT_SINK_NAME "raop"
-
 struct userdata {
 pa_core *core;
 pa_module *module;
@@ -82,6 +83,8 @@ struct userdata {
 pa_rtpoll_item *rtpoll_item;
 pa_thread *thread;
 
+pa_raop_protocol_t protocol;
+
 pa_memchunk raw_memchunk;
 pa_memchunk encoded_memchunk;
 
@@ -97,7 +100,6 @@ struct userdata {
 int32_t rate;
 
 pa_smoother *smoother;
-int fd;
 
 int64_t offset;
 int64_t encoding_overhead;
@@ -107,12 +109,26 @@ struct userdata {
 pa_raop_client *raop;
 
 size_t block_size;
+
+/* Members only for the TCP protocol */
+int tcp_fd;
+
+/* Members only for the UDP protocol */
+int udp_control_fd;
+int udp_timing_fd;
+
+/* For UDP thread wakeup clock calculation */
+pa_usec_t udp_playback_start;
+uint32_t  udp_sent_packets;
 };
 
 static const char* const valid_modargs[] = {
 "sink_name",
 "sink_properties",
 "server",
+"protocol",
+"encryption",
+"codec",
 "format",
 "rate",
 "channels",
@@ -120,23 +136,26 @@ static const char* const valid_modargs[] = {
 };
 
 enum {
-SINK_MESSAGE_PASS_SOCKET = PA_SINK_MESSAGE_MAX,
-SINK_MESSAGE_RIP_SOCKET
+SINK_MESSAGE_TCP_PASS_SOCKET = PA_SINK_MESSAGE_MAX,
+SINK_MESSAGE_TCP_RIP_SOCKET,
+SINK_MESSAGE_UDP_SETUP,
+SINK_MESSAGE_UDP_RECORD,
+SINK_MESSAGE_UDP_DISCONNECTED,
 };
 
 /* Forward declarations: */
 static void sink_set_volume_cb(pa_sink *);
 
-static void on_connection(int fd, void *userdata) {
+static void tcp_on_connection(int fd, void *userdata) {
 int so_sndbuf = 0;
 socklen_t sl = sizeof(int);
 struct userdata *u = userdata;
 pa_assert(u);
 
-pa_assert(u->fd < 0);
-u->fd = fd;
+pa_assert(u->tcp_fd < 0);
+u->tcp_fd = fd;
 
-if (getsockopt(u->fd, SOL_SOCKET, SO_SNDBUF, _sndbuf, ) < 0)
+if (getsockopt(u->tcp_fd, SOL_SOCKET, SO_SNDBUF, _sndbuf, ) < 0)
 pa_log_warn("getsockopt(SO_SNDBUF) failed: %s", pa_cstrerror(errno));
 else {
 pa_log_debug("SO_SNDBUF is %zu.", (size_t) so_sndbuf);
@@ -148,19 +167,28 @@ static void on_connection(int fd, void *userdata) {
 
 pa_log_debug("Connection authenticated, handing fd to IO thread...");
 
-pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->sink), 
SINK_MESSAGE_PASS_SOCKET, NULL, 0, NULL, NULL);
+pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->sink), 
SINK_MESSAGE_TCP_PASS_SOCKET, NULL, 0, NULL, NULL);
 }
 
-static void on_close(void*userdata) {
+static void tcp_on_close(void*userdata) {
 struct userdata *u = userdata;
 pa_assert(u);
 
 pa_log_debug("Connection closed, informing IO thread...");
 
-pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->sink), 
SINK_MESSAGE_RIP_SOCKET, NULL, 0, NULL, NULL);
+pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->sink), 
SINK_MESSAGE_TCP_RIP_SOCKET, NULL, 0, NULL, NULL);
+}
+
+static pa_usec_t sink_get_latency(const struct userdata *u) {
+pa_usec_t w, r;
+
+r = pa_smoother_get(u->smoother, pa_rtclock_now());
+w = pa_bytes_to_usec((u->offset - u->encoding_overhead + 
(u->encoded_memchunk.length / u->encoding_ratio)), >sink->sample_spec);
+
+return w > r ? w - r : 0;
 }
 
-static int sink_proce

[pulseaudio-discuss] [PATCH v6 06/37] rtp: New pa_rtsp_options function

2016-01-31 Thread Hajime Fujita
From: Colin Leroy 

Add a function performing a call to the OPTIONS request; also,
in some special cases, tuning transport parameters is required (default:
"RTP/AVP/TCP;unicast;interleaved=0-1;mode=record") ! The RAOP client for
example needs to overwrite them.
---
 src/modules/raop/raop_client.c |  6 +-
 src/modules/rtp/rtsp_client.c  | 23 +--
 src/modules/rtp/rtsp_client.h  |  4 +++-
 3 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c
index 29c4f08..a5dd29c 100644
--- a/src/modules/raop/raop_client.c
+++ b/src/modules/raop/raop_client.c
@@ -281,10 +281,14 @@ static void rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state 
state, pa_headerlist *he
 break;
 }
 
+case STATE_OPTIONS:
+pa_log_debug("RAOP: OPTIONS");
+break;
+
 case STATE_ANNOUNCE:
 pa_log_debug("RAOP: ANNOUNCED");
 pa_rtsp_remove_header(c->rtsp, "Apple-Challenge");
-pa_rtsp_setup(c->rtsp);
+pa_rtsp_setup(c->rtsp, NULL);
 break;
 
 case STATE_SETUP: {
diff --git a/src/modules/rtp/rtsp_client.c b/src/modules/rtp/rtsp_client.c
index 56f6e15..aa0217d 100644
--- a/src/modules/rtp/rtsp_client.c
+++ b/src/modules/rtp/rtsp_client.c
@@ -443,6 +443,22 @@ static int rtsp_exec(pa_rtsp_client *c, const char *cmd,
 return 0;
 }
 
+int pa_rtsp_options(pa_rtsp_client *c) {
+char *url;
+int rv;
+
+pa_assert(c);
+
+url = c->url;
+c->state = STATE_OPTIONS;
+
+c->url = (char *)"*";
+rv = rtsp_exec(c, "OPTIONS", NULL, NULL, 0, NULL);
+
+c->url = url;
+return rv;
+}
+
 int pa_rtsp_announce(pa_rtsp_client *c, const char *sdp) {
 int rv;
 
@@ -457,14 +473,17 @@ int pa_rtsp_announce(pa_rtsp_client *c, const char *sdp) {
 return rv;
 }
 
-int pa_rtsp_setup(pa_rtsp_client *c) {
+int pa_rtsp_setup(pa_rtsp_client *c, const char *transport) {
 pa_headerlist *headers;
 int rv;
 
 pa_assert(c);
 
 headers = pa_headerlist_new();
-pa_headerlist_puts(headers, "Transport", 
"RTP/AVP/TCP;unicast;interleaved=0-1;mode=record");
+if (!transport)
+pa_headerlist_puts(headers, "Transport", 
"RTP/AVP/TCP;unicast;interleaved=0-1;mode=record");
+else
+pa_headerlist_puts(headers, "Transport", transport);
 
 c->state = STATE_SETUP;
 rv = rtsp_exec(c, "SETUP", NULL, NULL, 1, headers);
diff --git a/src/modules/rtp/rtsp_client.h b/src/modules/rtp/rtsp_client.h
index d51acda..7e9978d 100644
--- a/src/modules/rtp/rtsp_client.h
+++ b/src/modules/rtp/rtsp_client.h
@@ -33,6 +33,7 @@
 typedef struct pa_rtsp_client pa_rtsp_client;
 typedef enum {
   STATE_CONNECT,
+  STATE_OPTIONS,
   STATE_ANNOUNCE,
   STATE_SETUP,
   STATE_RECORD,
@@ -57,9 +58,10 @@ void pa_rtsp_set_url(pa_rtsp_client *c, const char *url);
 void pa_rtsp_add_header(pa_rtsp_client *c, const char *key, const char *value);
 void pa_rtsp_remove_header(pa_rtsp_client *c, const char *key);
 
+int pa_rtsp_options(pa_rtsp_client *c);
 int pa_rtsp_announce(pa_rtsp_client *c, const char *sdp);
 
-int pa_rtsp_setup(pa_rtsp_client *c);
+int pa_rtsp_setup(pa_rtsp_client *c, const char *transport);
 int pa_rtsp_record(pa_rtsp_client *c, uint16_t *seq, uint32_t *rtptime);
 int pa_rtsp_teardown(pa_rtsp_client *c);
 
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 21/37] raop: Remove unimplemented code (PCM and AAC)

2016-01-31 Thread Hajime Fujita
From: Martin Blanchard 

---
 src/modules/raop/raop-client.c | 44 ++
 1 file changed, 14 insertions(+), 30 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index 4e73d12..a1c282f 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -267,16 +267,6 @@ static inline void bit_writer(uint8_t **buffer, uint8_t 
*bit_pos, size_t *size,
 }
 }
 
-static size_t write_PCM_data(uint8_t *packet, const size_t max, uint8_t *raw, 
size_t *length) {
-size_t size = 0;
-
-pa_memzero(packet, max);
-
-pa_log("Raw PCM not implemented...");
-
-return size;
-}
-
 static size_t write_ALAC_data(uint8_t *packet, const size_t max, uint8_t *raw, 
size_t *length, bool compress) {
 uint32_t nbs = (*length / 2) / 2;
 uint8_t *ibp, *maxibp;
@@ -315,16 +305,6 @@ static size_t write_ALAC_data(uint8_t *packet, const 
size_t max, uint8_t *raw, s
 return size;
 }
 
-static size_t write_AAC_data(uint8_t *packet, const size_t max, uint8_t *raw, 
size_t *length) {
-size_t size = 0;
-
-pa_memzero(packet, max);
-
-pa_log("AAC encoding not implemented...");
-
-return size;
-}
-
 static size_t build_tcp_audio_packet(pa_raop_client *c, pa_memchunk *block, 
pa_memchunk *packet) {
 const size_t head = sizeof(tcp_audio_header);
 uint32_t *buffer = NULL;
@@ -344,12 +324,14 @@ static size_t build_tcp_audio_packet(pa_raop_client *c, 
pa_memchunk *block, pa_m
 
 length = block->length;
 size = sizeof(tcp_audio_header);
-if (c->codec == PA_RAOP_CODEC_PCM)
-size += write_PCM_data(((uint8_t *) buffer + head), packet->length - 
head, raw, );
-else if (c->codec == PA_RAOP_CODEC_ALAC)
+if (c->codec == PA_RAOP_CODEC_ALAC)
 size += write_ALAC_data(((uint8_t *) buffer + head), packet->length - 
head, raw, , false);
-else
-size += write_AAC_data(((uint8_t *) buffer + head), packet->length - 
head, raw, );
+else {
+pa_log_debug("Only ALAC encoding is supported, sending zeros...");
+pa_memzero(((uint8_t *) buffer + head), packet->length - head);
+size += length;
+}
+
 c->rtptime += length / 4;
 
 pa_memblock_release(block->memblock);
@@ -430,12 +412,14 @@ static size_t build_udp_audio_packet(pa_raop_client *c, 
pa_memchunk *block, pa_m
 
 length = block->length;
 size = sizeof(udp_audio_header);
-if (c->codec == PA_RAOP_CODEC_PCM)
-size += write_PCM_data(((uint8_t *) buffer + head), packet->length - 
head, raw, );
-else if (c->codec == PA_RAOP_CODEC_ALAC)
+if (c->codec == PA_RAOP_CODEC_ALAC)
 size += write_ALAC_data(((uint8_t *) buffer + head), packet->length - 
head, raw, , false);
-else
-size += write_AAC_data(((uint8_t *) buffer + head), packet->length - 
head, raw, );
+else {
+pa_log_debug("Only ALAC encoding is supported, sending zeros...");
+pa_memzero(((uint8_t *) buffer + head), packet->length - head);
+size += length;
+}
+
 c->rtptime += length / 4;
 c->seq++;
 
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 12/37] raop: Better playback resume handling

2016-01-31 Thread Hajime Fujita
From: Martin Blanchard 

When playback stops, a FLUSH command is send to the server and the sink
goes to IDLE. If playback resumes quickly, sink goes back to RUNNING
(without being SUSPENDED) and the sink should just start streaming again.
This patch implements this behaviour.
---
 src/modules/raop/module-raop-sink.c |  8 ++--
 src/modules/raop/raop_client.c  | 26 +++---
 src/modules/raop/raop_client.h  |  1 +
 3 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/src/modules/raop/module-raop-sink.c 
b/src/modules/raop/module-raop-sink.c
index 8deb139..1e83e97 100644
--- a/src/modules/raop/module-raop-sink.c
+++ b/src/modules/raop/module-raop-sink.c
@@ -332,10 +332,14 @@ static int udp_sink_process_msg(pa_msgobject *o, int 
code, void *data, int64_t o
 
 pa_smoother_resume(u->smoother, pa_rtclock_now(), true);
 
-if (!pa_raop_client_udp_can_stream(u->raop)) {
-/* Connecting will trigger a RECORD */
+if (!pa_raop_client_udp_is_alive(u->raop)) {
+/* Connecting will trigger a RECORD and start steaming 
*/
 pa_raop_client_connect(u->raop);
+} else if (!pa_raop_client_udp_can_stream(u->raop)) {
+/* RECORD alredy sent, simply start streaming */
+pa_raop_client_udp_stream(u->raop);
 }
+
 udp_start_wakeup_clock(u);
 
 break;
diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c
index 11c871d..e6e3737 100644
--- a/src/modules/raop/raop_client.c
+++ b/src/modules/raop/raop_client.c
@@ -934,8 +934,6 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state 
state, pa_headerlist
 
 pa_log_debug("RAOP: RECORD");
 
-c->is_recording = true;
-
 alt = pa_xstrdup(pa_headerlist_gets(headers, "Audio-Latency"));
 /* Generate a random synchronization source identifier from this 
session. */
 pa_random(, sizeof(rand));
@@ -947,6 +945,8 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state 
state, pa_headerlist
 c->udp_first_packet = true;
 c->udp_sync_count = 0;
 
+c->is_recording = true;
+
 c->udp_record_callback(c->udp_setup_userdata);
 
 pa_xfree(alt);
@@ -1150,11 +1150,12 @@ int pa_raop_client_connect(pa_raop_client *c) {
 
 int pa_raop_client_flush(pa_raop_client *c) {
 int rv = 0;
+
 pa_assert(c);
 
 if (c->rtsp != NULL) {
 rv = pa_rtsp_flush(c->rtsp, c->seq, c->rtptime);
-c->udp_sync_count = -1;
+c->udp_sync_count = 0;
 }
 
 return rv;
@@ -1193,6 +1194,25 @@ int pa_raop_client_udp_can_stream(pa_raop_client *c) {
 return rv;
 }
 
+int pa_raop_client_udp_stream(pa_raop_client *c) {
+int rv = 0;
+
+pa_assert(c);
+
+if (c->rtsp != NULL && c->udp_stream_fd > 0) {
+if (!c->is_recording) {
+c->udp_first_packet = true;
+c->udp_sync_count = 0;
+
+c->is_recording = true;
+ }
+
+rv = 1;
+}
+
+return rv;
+}
+
 int pa_raop_client_udp_handle_timing_packet(pa_raop_client *c, const uint8_t 
packet[], ssize_t size) {
 const uint32_t * data = NULL;
 uint8_t payload = 0;
diff --git a/src/modules/raop/raop_client.h b/src/modules/raop/raop_client.h
index 6ab6d32..d49c146 100644
--- a/src/modules/raop/raop_client.h
+++ b/src/modules/raop/raop_client.h
@@ -43,6 +43,7 @@ int pa_raop_client_teardown(pa_raop_client *c);
 
 int pa_raop_client_udp_is_alive(pa_raop_client *c);
 int pa_raop_client_udp_can_stream(pa_raop_client *c);
+int pa_raop_client_udp_stream(pa_raop_client *c);
 
 void pa_raop_client_set_encryption(pa_raop_client *c, int encryption);
 pa_volume_t pa_raop_client_adjust_volume(pa_raop_client *c, pa_volume_t 
volume);
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 29/37] raop: Correctly wrap RTP packet sequence number

2016-01-31 Thread Hajime Fujita
From: Martin Blanchard 

---
 src/modules/raop/raop-client.c| 27 +++---
 src/modules/raop/raop-packet-buffer.c | 70 ---
 src/modules/raop/raop-packet-buffer.h |  5 ++-
 3 files changed, 65 insertions(+), 37 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index 724d420..d8de2ae 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -24,6 +24,7 @@
 #endif
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -316,10 +317,10 @@ static size_t build_tcp_audio_packet(pa_raop_client *c, 
pa_memchunk *block, pa_m
 buffer += packet->index / sizeof(uint32_t);
 raw += block->index;
 
-if (c->seq == 0x) {
-pa_log_debug("wrapping sequence number");
-c->seq = pa_raop_packet_buffer_wrap_seq(c->pbuf, c->seq);
-} else
+/* Wrap sequence number to 0 then UINT16_MAX is reached */
+if (c->seq == UINT16_MAX)
+c->seq = 0;
+else
 c->seq++;
 
 memcpy(buffer, tcp_audio_header, sizeof(tcp_audio_header));
@@ -360,13 +361,13 @@ static ssize_t send_tcp_audio_packet(pa_raop_client *c, 
pa_memchunk *block, size
 ssize_t written = -1;
 size_t done = 0;
 
-if (!(packet = pa_raop_packet_buffer_get(c->pbuf, c->seq, max)))
+if (!(packet = pa_raop_packet_buffer_retrieve(c->pbuf, c->seq)))
 return -1;
 
 if (packet->length <= 0) {
 pa_assert(block->index == offset);
 
-if (!(packet = pa_raop_packet_buffer_get(c->pbuf, c->seq + 1, max)))
+if (!(packet = pa_raop_packet_buffer_prepare(c->pbuf, c->seq + 1, 
max)))
 return -1;
 
 packet->index = 0;
@@ -427,10 +428,10 @@ static size_t build_udp_audio_packet(pa_raop_client *c, 
pa_memchunk *block, pa_m
 
 c->rtptime += length / 4;
 
-if (c->seq == 0x) {
-pa_log_debug("wrapping sequence number");
-c->seq = pa_raop_packet_buffer_wrap_seq(c->pbuf, c->seq);
-} else
+/* Wrap sequence number to 0 then UINT16_MAX is reached */
+if (c->seq == UINT16_MAX)
+c->seq = 0;
+else
 c->seq++;
 
 pa_memblock_release(block->memblock);
@@ -453,11 +454,11 @@ static ssize_t send_udp_audio_packet(pa_raop_client *c, 
pa_memchunk *block, size
 /* UDP packet has to be sent at once ! */
 pa_assert(block->index == offset);
 
-if (!(packet = pa_raop_packet_buffer_get(c->pbuf, c->seq, max)))
+if (!(packet = pa_raop_packet_buffer_prepare(c->pbuf, c->seq, max)))
 return -1;
 
-packet->length = max;
 packet->index = sizeof(udp_audio_retrans_header);
+packet->length = max - sizeof(udp_audio_retrans_header);
 if (!build_udp_audio_packet(c, block, packet))
 return -1;
 
@@ -508,7 +509,7 @@ static ssize_t resend_udp_audio_packets(pa_raop_client *c, 
uint16_t seq, uint16_
 uint8_t *buffer = NULL;
 ssize_t written = -1;
 
-if (!(packet = pa_raop_packet_buffer_get(c->pbuf, seq + i, 0)))
+if (!(packet = pa_raop_packet_buffer_retrieve(c->pbuf, seq + i)))
 continue;
 
 if (packet->index > 0) {
diff --git a/src/modules/raop/raop-packet-buffer.c 
b/src/modules/raop/raop-packet-buffer.c
index 4c45d18..05f9592 100644
--- a/src/modules/raop/raop-packet-buffer.c
+++ b/src/modules/raop/raop-packet-buffer.c
@@ -25,6 +25,7 @@
 #endif
 
 #include 
+#include 
 #include 
 
 #include 
@@ -37,7 +38,9 @@
 struct pa_raop_packet_buffer {
 pa_memchunk *packets;
 pa_mempool *mempool;
+
 size_t size;
+size_t count;
 
 uint16_t seq;
 size_t pos;
@@ -49,6 +52,7 @@ pa_raop_packet_buffer *pa_raop_packet_buffer_new(pa_mempool 
*mempool, const size
 pa_assert(mempool);
 pa_assert(size > 0);
 
+pb->count = 0;
 pb->size = size;
 pb->mempool = mempool;
 pb->packets = pa_xnew0(pa_memchunk, size);
@@ -80,7 +84,8 @@ void pa_raop_packet_buffer_reset(pa_raop_packet_buffer *pb, 
uint16_t seq) {
 pa_assert(pb->packets);
 
 pb->pos = 0;
-pb->seq = seq - 1;
+pb->count = 0;
+pb->seq = (!seq) ? UINT16_MAX : seq - 1;
 for (i = 0; i < pb->size; i++) {
 if (pb->packets[i].memblock)
 pa_memblock_unref(pb->packets[i].memblock);
@@ -88,23 +93,43 @@ void pa_raop_packet_buffer_reset(pa_raop_packet_buffer *pb, 
uint16_t seq) {
 }
 }
 
-uint16_t pa_raop_packet_buffer_wrap_seq(pa_raop_packet_buffer *pb, uint16_t 
seq) {
-int seq_shift;
+pa_memchunk *pa_raop_packet_buffer_prepare(pa_raop_packet_buffer *pb, uint16_t 
seq, const size_t size) {
+pa_memchunk *packet = NULL;
+size_t i;
 
 pa_assert(pb);
+pa_assert(pb->packets);
+
+if (seq == 0) {
+/* 0 means seq reached UINT16_MAX and has been wrapped... */
+pa_assert(pb->seq == UINT16_MAX);
+pb->seq = 0;
+} else {
+/* ...otherwise, seq MUST have be increased! */
+pa_assert(seq == pb->seq + 1);
+pb->seq++;
+}
+
+i = (pb->pos + 1) % 

[pulseaudio-discuss] [PATCH v6 02/37] rtp: Freeing ioline when disconnecting

2016-01-31 Thread Hajime Fujita
From: Hajime Fujita <crisp.fuj...@nifty.com>

pa_ioline_close does not free the ioline structure itself, so we
have to unref the structure if we want to free it.
---
 src/modules/rtp/rtsp_client.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/modules/rtp/rtsp_client.c b/src/modules/rtp/rtsp_client.c
index bdfd24f..6f828ba 100644
--- a/src/modules/rtp/rtsp_client.c
+++ b/src/modules/rtp/rtsp_client.c
@@ -348,8 +348,10 @@ void pa_rtsp_set_callback(pa_rtsp_client *c, pa_rtsp_cb_t 
callback, void *userda
 void pa_rtsp_disconnect(pa_rtsp_client *c) {
 pa_assert(c);
 
-if (c->ioline)
+if (c->ioline) {
 pa_ioline_close(c->ioline);
+pa_ioline_unref(c->ioline);
+}
 c->ioline = NULL;
 }
 
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 16/37] raop: Add the core implementation of RAOP authentication

2016-01-31 Thread Hajime Fujita
From: Martin Blanchard 

RAOP authentication (password) is based on BA and DA HTTP authentication
schemes. This patch adds the RSTP client the ability to specify the caller
of server response status. Tracking the '401 Unauthorized' status allow
the RAOP client to respond the server challenge authentication request.
This patch adds the core implementation but does not introduce the
authentication scheme in the RAOP connection process yet.
---
 src/modules/raop/raop_client.c  |  245 +-
 src/modules/raop/raop_client.c.orig | 1495 +++
 src/modules/raop/raop_client.h  |4 +
 src/modules/rtp/rtsp_client.c   |   83 +-
 src/modules/rtp/rtsp_client.h   |   26 +-
 5 files changed, 1810 insertions(+), 43 deletions(-)
 create mode 100644 src/modules/raop/raop_client.c.orig

diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c
index a2ec91e..1323cd0 100644
--- a/src/modules/raop/raop_client.c
+++ b/src/modules/raop/raop_client.c
@@ -65,6 +65,9 @@
 #define VOLUME_MIN -144
 #define VOLUME_MAX 0
 
+#define USER_AGENT "iTunes/11.0.4 (Windows; N)"
+#define USER_NAME "iTunes"
+
 #define DEFAULT_RAOP_PORT 5000
 #define UDP_DEFAULT_AUDIO_PORT 6000
 #define UDP_DEFAULT_CONTROL_PORT 6001
@@ -85,13 +88,15 @@ struct pa_raop_client {
 pa_core *core;
 char *host;
 uint16_t port;
-char *sid;
 pa_rtsp_client *rtsp;
-pa_raop_protocol_t protocol;
+char *sci, *sid;
+char *pwd;
 
 uint8_t jack_type;
 uint8_t jack_status;
 
+pa_raop_protocol_t protocol;
+
 int encryption; /* Enable encryption? */
 pa_raop_secret *aes;
 
@@ -125,6 +130,9 @@ struct pa_raop_client {
 uint32_t udp_sync_interval;
 uint32_t udp_sync_count;
 
+pa_raop_client_auth_cb_t udp_auth_callback;
+void *udp_auth_userdata;
+
 pa_raop_client_setup_cb_t udp_setup_callback;
 void *udp_setup_userdata;
 
@@ -576,7 +584,7 @@ static void do_rtsp_announce(pa_raop_client *c) {
 pa_xfree(sdp);
 }
 
-static void tcp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
pa_headerlist* headers, void *userdata) {
+static void tcp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
pa_rtsp_status status, pa_headerlist* headers, void *userdata) {
 pa_raop_client* c = userdata;
 pa_assert(c);
 pa_assert(rtsp);
@@ -675,12 +683,13 @@ static void tcp_rtsp_cb(pa_rtsp_client *rtsp, 
pa_rtsp_state state, pa_headerlist
 }
 }
 
-static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
pa_headerlist *headers, void *userdata) {
+static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
pa_rtsp_status status, pa_headerlist *headers, void *userdata) {
 pa_raop_client *c = userdata;
 
 pa_assert(c);
 pa_assert(rtsp);
 pa_assert(rtsp == c->rtsp);
+pa_assert(STATUS_OK == status);
 
 switch (state) {
 case STATE_CONNECT: {
@@ -982,6 +991,178 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, 
pa_rtsp_state state, pa_headerlist
 }
 }
 
+static void rtsp_authentication_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
pa_rtsp_status status, pa_headerlist *headers, void *userdata) {
+pa_raop_client *c = userdata;
+
+pa_assert(c);
+pa_assert(rtsp);
+pa_assert(rtsp == c->rtsp);
+
+switch (state) {
+case STATE_CONNECT: {
+char *sci = NULL, *sac = NULL;
+uint16_t rac;
+struct {
+uint32_t ci1;
+uint32_t ci2;
+} rci;
+
+pa_random(, sizeof(rci));
+/* Generate a random Client-Instance number */
+sci = pa_sprintf_malloc("%08x%08x",rci.ci1, rci.ci2);
+pa_rtsp_add_header(c->rtsp, "Client-Instance", sci);
+
+pa_random(, sizeof(rac));
+/* Generate a random Apple-Challenge key */
+pa_raop_base64_encode(, 8*sizeof(rac), );
+pa_log_debug ("APPLECHALLENGE >> %s | %d", sac, (int) sizeof(rac));
+rtrimchar(sac, '=');
+pa_rtsp_add_header(c->rtsp, "Apple-Challenge", sac);
+
+pa_rtsp_options(c->rtsp);
+
+pa_xfree(sac);
+pa_xfree(sci);
+break;
+}
+
+case STATE_OPTIONS: {
+static bool waiting = false;
+const char *current = NULL;
+char space[] = " ";
+char *token,*ath = NULL;
+char *publ, *wath, *mth, *val;
+char *realm = NULL, *nonce = NULL, *response = NULL;
+char comma[] = ",";
+
+pa_log_debug("RAOP: OPTIONS");
+/* We do not consider the Apple-Response */
+pa_rtsp_remove_header(c->rtsp, "Apple-Challenge");
+
+if (STATUS_UNAUTHORIZED == status) {
+wath = pa_xstrdup(pa_headerlist_gets(headers, 
"WWW-Authenticate"));
+if (true == waiting) {
+pa_xfree(wath);
+goto failure;
+}
+
+

[pulseaudio-discuss] [PATCH v6 36/37] raop: Fix #36: invalid access to freed object

2016-01-31 Thread Hajime Fujita
From: ced2c 

The RTSP client is not waiting anymore a new header after the
previous one (which can never occurs if RAOP is disconnected)
but after sending a command.

This patch fixes Issue #36.
https://github.com/hfujita/pulseaudio-raop2/issues/36
---
 src/modules/rtp/rtsp_client.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/modules/rtp/rtsp_client.c b/src/modules/rtp/rtsp_client.c
index fd5d2d8..34210f9 100644
--- a/src/modules/rtp/rtsp_client.c
+++ b/src/modules/rtp/rtsp_client.c
@@ -236,7 +236,6 @@ static void line_callback(pa_ioline *line, const char *s, 
void *userdata) {
 
 pa_log_debug("Full response received. Dispatching");
 headers_read(c);
-c->waiting = 1;
 goto exit;
 }
 
@@ -481,7 +480,8 @@ static int rtsp_exec(pa_rtsp_client *c, const char *cmd,
 pa_log_debug(hdrs);*/
 pa_ioline_puts(c->ioline, hdrs);
 pa_xfree(hdrs);
-
+/* The command is sent we can configure the rtsp client structure to 
handle a new answer */
+c->waiting = 1;
 return 0;
 }
 
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 20/37] raop: Rework packet's store memory management

2016-01-31 Thread Hajime Fujita
From: Martin Blanchard 

This patch switch the packet-buffer to use core memory pool instead of
manually allocating the room required for storing TCP/UDP packets. Packets
are now stored using pa_memchunk instead of internal struct. Quite a few
malloc saved compare to previous design.
---
 src/modules/raop/raop-client.c| 261 ++
 src/modules/raop/raop-packet-buffer.c | 187 +---
 src/modules/raop/raop-packet-buffer.h |  17 +--
 src/modules/raop/raop-sink.c  |   4 +-
 4 files changed, 216 insertions(+), 253 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index d5d636d..4e73d12 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -65,6 +65,8 @@
 #define FRAMES_PER_TCP_PACKET 4096
 #define FRAMES_PER_UDP_PACKET 352
 
+#define RTX_BUFFERING_SECONDS 4
+
 #define DEFAULT_TCP_AUDIO_PORT   6000
 #define DEFAULT_UDP_AUDIO_PORT   6000
 #define DEFAULT_UDP_CONTROL_PORT 6001
@@ -323,92 +325,102 @@ static size_t write_AAC_data(uint8_t *packet, const 
size_t max, uint8_t *raw, si
 return size;
 }
 
-static size_t build_tcp_audio_packet(pa_raop_client *c, uint8_t *raw, size_t 
*index, size_t *length, uint32_t **packet) {
-const size_t max = sizeof(tcp_audio_header) + 8 + 16384;
+static size_t build_tcp_audio_packet(pa_raop_client *c, pa_memchunk *block, 
pa_memchunk *packet) {
+const size_t head = sizeof(tcp_audio_header);
 uint32_t *buffer = NULL;
-size_t size, head;
+uint8_t *raw = NULL;
+size_t length, size;
 
-*packet = NULL;
-if (!(buffer = pa_xmalloc0(max)))
-return 0;
+raw = pa_memblock_acquire(block->memblock);
+buffer = pa_memblock_acquire(packet->memblock);
+buffer += packet->index / sizeof(uint32_t);
+raw += block->index;
 
-size = head = sizeof(tcp_audio_header);
+c->seq++;
 memcpy(buffer, tcp_audio_header, sizeof(tcp_audio_header));
 buffer[1] |= htonl((uint32_t) c->seq);
 buffer[2] = htonl(c->rtptime);
 buffer[3] = htonl(c->ssrc);
 
+length = block->length;
+size = sizeof(tcp_audio_header);
 if (c->codec == PA_RAOP_CODEC_PCM)
-size += write_PCM_data(((uint8_t *) buffer + head), max - head, raw, 
length);
+size += write_PCM_data(((uint8_t *) buffer + head), packet->length - 
head, raw, );
 else if (c->codec == PA_RAOP_CODEC_ALAC)
-size += write_ALAC_data(((uint8_t *) buffer + head), max - head, raw, 
length, false);
+size += write_ALAC_data(((uint8_t *) buffer + head), packet->length - 
head, raw, , false);
 else
-size += write_AAC_data(((uint8_t *) buffer + head), max - head, raw, 
length);
-c->rtptime += *length / 4;
+size += write_AAC_data(((uint8_t *) buffer + head), packet->length - 
head, raw, );
+c->rtptime += length / 4;
+
+pa_memblock_release(block->memblock);
 
 buffer[0] |= htonl((uint32_t) size - 4);
 if (c->encryption == PA_RAOP_ENCRYPTION_RSA)
 pa_raop_aes_encrypt(c->secret, (uint8_t *) buffer + head, size - head);
 
-*packet = buffer;
+pa_memblock_release(packet->memblock);
+packet->length = size;
+
 return size;
 }
 
 static ssize_t send_tcp_audio_packet(pa_raop_client *c, pa_memchunk *block, 
size_t offset) {
-static uint32_t * packet = NULL;
-static size_t size, sent;
+static int write_type = 0;
+const size_t max = sizeof(tcp_audio_header) + 8 + 16384;
+pa_memchunk *packet = NULL;
+uint8_t *buffer = NULL;
 double progress = 0.0;
-size_t index, length;
-uint8_t *raw = NULL;
-ssize_t written;
+ssize_t written = -1;
+size_t done = 0;
+
+if (!(packet = pa_raop_packet_buffer_get(c->pbuf, c->seq, max)))
+return -1;
 
-if (!packet) {
-index = block->index;
-length = block->length;
-raw = pa_memblock_acquire(block->memblock);
+if (packet->length <= 0) {
+pa_assert(block->index == offset);
 
-pa_assert(raw);
-pa_assert(index == offset);
-pa_assert(length > 0);
+if (!(packet = pa_raop_packet_buffer_get(c->pbuf, c->seq + 1, max)))
+return -1;
 
-size = build_tcp_audio_packet(c, raw, , , );
-sent = 0;
+packet->index = 0;
+packet->length = max;
+if (!build_tcp_audio_packet(c, block, packet))
+return -1;
 }
 
-written = -1;
-if (packet != NULL && size > 0)
-written = pa_write(c->tcp_sfd, packet + sent, size - sent, NULL);
-if (block->index == offset)
-c->seq++;
-if (sent == 0)
-pa_memblock_release(block->memblock);
+buffer = pa_memblock_acquire(packet->memblock);
+
+pa_assert(buffer);
+
+buffer += packet->index;
+if (buffer && packet->length > 0)
+written = pa_write(c->tcp_sfd, buffer, packet->length, _type);
 if (written > 0) {
-sent += written;
-progress = (double) sent / 

[pulseaudio-discuss] [PATCH v6 23/37] raop: fix sequence number overflow

2016-01-31 Thread Hajime Fujita
From: Colin Leroy 

Wrap sequence number when we reach uint16_t's max 0x.
---
 src/modules/raop/raop-client.c| 14 --
 src/modules/raop/raop-packet-buffer.c | 17 -
 src/modules/raop/raop-packet-buffer.h |  1 +
 3 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index a1c282f..6ae8799 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -316,7 +316,12 @@ static size_t build_tcp_audio_packet(pa_raop_client *c, 
pa_memchunk *block, pa_m
 buffer += packet->index / sizeof(uint32_t);
 raw += block->index;
 
-c->seq++;
+if (c->seq == 0x) {
+pa_log_debug("wrapping sequence number");
+c->seq = pa_raop_packet_buffer_wrap_seq(c->pbuf, c->seq);
+} else
+c->seq++;
+
 memcpy(buffer, tcp_audio_header, sizeof(tcp_audio_header));
 buffer[1] |= htonl((uint32_t) c->seq);
 buffer[2] = htonl(c->rtptime);
@@ -421,7 +426,12 @@ static size_t build_udp_audio_packet(pa_raop_client *c, 
pa_memchunk *block, pa_m
 }
 
 c->rtptime += length / 4;
-c->seq++;
+
+if (c->seq == 0x) {
+pa_log_debug("wrapping sequence number");
+c->seq = pa_raop_packet_buffer_wrap_seq(c->pbuf, c->seq);
+} else
+c->seq++;
 
 pa_memblock_release(block->memblock);
 
diff --git a/src/modules/raop/raop-packet-buffer.c 
b/src/modules/raop/raop-packet-buffer.c
index 06e3125..4c45d18 100644
--- a/src/modules/raop/raop-packet-buffer.c
+++ b/src/modules/raop/raop-packet-buffer.c
@@ -88,13 +88,28 @@ void pa_raop_packet_buffer_reset(pa_raop_packet_buffer *pb, 
uint16_t seq) {
 }
 }
 
+uint16_t pa_raop_packet_buffer_wrap_seq(pa_raop_packet_buffer *pb, uint16_t 
seq) {
+int seq_shift;
+
+pa_assert(pb);
+
+if (seq > pb->seq)
+seq_shift = pb->seq - 1;
+else
+seq_shift = seq;
+
+pb->seq -= seq_shift;
+
+return seq - seq_shift;
+
+}
+
 pa_memchunk *pa_raop_packet_buffer_get(pa_raop_packet_buffer *pb, uint16_t 
seq, const size_t size) {
 pa_memchunk *packet = NULL;
 size_t delta, i;
 
 pa_assert(pb);
 pa_assert(pb->packets);
-pa_assert(seq > 0);
 
 if (seq == pb->seq)
 packet = >packets[pb->pos];
diff --git a/src/modules/raop/raop-packet-buffer.h 
b/src/modules/raop/raop-packet-buffer.h
index b8c7617..cb2bfdf 100644
--- a/src/modules/raop/raop-packet-buffer.h
+++ b/src/modules/raop/raop-packet-buffer.h
@@ -35,4 +35,5 @@ void pa_raop_packet_buffer_free(pa_raop_packet_buffer *pb);
 void pa_raop_packet_buffer_reset(pa_raop_packet_buffer *pb, uint16_t seq);
 pa_memchunk *pa_raop_packet_buffer_get(pa_raop_packet_buffer *pb, uint16_t 
seq, const size_t size);
 
+uint16_t pa_raop_packet_buffer_wrap_seq(pa_raop_packet_buffer *pb, uint16_t 
seq);
 #endif
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 11/37] raop: Do not send audio before RECORD response

2016-01-31 Thread Hajime Fujita
From: Martin Blanchard 

This patch prevents audio packets to be sent before the server
respond to the RECORD command.
---
 src/modules/raop/module-raop-sink.c |  6 +++---
 src/modules/raop/raop_client.c  | 25 -
 src/modules/raop/raop_client.h  |  1 +
 3 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/src/modules/raop/module-raop-sink.c 
b/src/modules/raop/module-raop-sink.c
index 1eadde2..8deb139 100644
--- a/src/modules/raop/module-raop-sink.c
+++ b/src/modules/raop/module-raop-sink.c
@@ -310,7 +310,7 @@ static int udp_sink_process_msg(pa_msgobject *o, int code, 
void *data, int64_t o
 pa_log_debug("RAOP: SUSPENDED");
 pa_smoother_pause(u->smoother, pa_rtclock_now());
 
-if (pa_raop_client_udp_can_stream(u->raop)) {
+if (pa_raop_client_udp_is_alive(u->raop)) {
 /* Issue a TEARDOWN if we are still connected. */
 pa_raop_client_teardown(u->raop);
 }
@@ -756,10 +756,10 @@ static void udp_thread_func(struct userdata *u) {
 continue;
 }
 
-if (!pa_raop_client_udp_can_stream(u->raop))
-continue;
 if (u->sink->thread_info.state != PA_SINK_RUNNING)
 continue;
+if (!pa_raop_client_udp_can_stream(u->raop))
+continue;
 
 if (u->encoded_memchunk.length <= 0) {
 if (u->encoded_memchunk.memblock != NULL)
diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c
index 1c6c49e..11c871d 100644
--- a/src/modules/raop/raop_client.c
+++ b/src/modules/raop/raop_client.c
@@ -131,6 +131,8 @@ struct pa_raop_client {
 
 uint32_t udp_ssrc;
 
+bool is_recording;
+
 bool udp_first_packet;
 uint32_t udp_sync_interval;
 uint32_t udp_sync_count;
@@ -932,6 +934,8 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state 
state, pa_headerlist
 
 pa_log_debug("RAOP: RECORD");
 
+c->is_recording = true;
+
 alt = pa_xstrdup(pa_headerlist_gets(headers, "Audio-Latency"));
 /* Generate a random synchronization source identifier from this 
session. */
 pa_random(, sizeof(rand));
@@ -958,6 +962,8 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state 
state, pa_headerlist
 case STATE_FLUSH: {
 pa_log_debug("RAOP: FLUSHED");
 
+c->is_recording = false;
+
 break;
 }
 
@@ -966,6 +972,8 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state 
state, pa_headerlist
 pa_assert(c->udp_disconnected_callback);
 pa_assert(c->rtsp);
 
+c->is_recording = false;
+
 pa_rtsp_disconnect(c->rtsp);
 
 if (c->udp_stream_fd > 0) {
@@ -1066,6 +1074,8 @@ pa_raop_client* pa_raop_client_new(pa_core *core, const 
char *host, pa_raop_prot
 else
 c->port = DEFAULT_RAOP_PORT;
 
+c->is_recording = false;
+
 c->udp_first_packet = true;
 
 ss = core->default_sample_spec;
@@ -1133,6 +1143,8 @@ int pa_raop_client_connect(pa_raop_client *c) {
 else
 pa_rtsp_set_callback(c->rtsp, udp_rtsp_cb, c);
 
+c->is_recording = false;
+
 return pa_rtsp_connect(c->rtsp);
 }
 
@@ -1159,7 +1171,7 @@ int pa_raop_client_teardown(pa_raop_client *c) {
 return rv;
 }
 
-int pa_raop_client_udp_can_stream(pa_raop_client *c) {
+int pa_raop_client_udp_is_alive(pa_raop_client *c) {
 int rv = 0;
 
 pa_assert(c);
@@ -1170,6 +1182,17 @@ int pa_raop_client_udp_can_stream(pa_raop_client *c) {
 return rv;
 }
 
+int pa_raop_client_udp_can_stream(pa_raop_client *c) {
+int rv = 0;
+
+pa_assert(c);
+
+if (c->is_recording && c->udp_stream_fd > 0)
+rv = 1;
+
+return rv;
+}
+
 int pa_raop_client_udp_handle_timing_packet(pa_raop_client *c, const uint8_t 
packet[], ssize_t size) {
 const uint32_t * data = NULL;
 uint8_t payload = 0;
diff --git a/src/modules/raop/raop_client.h b/src/modules/raop/raop_client.h
index 578e9d0..6ab6d32 100644
--- a/src/modules/raop/raop_client.h
+++ b/src/modules/raop/raop_client.h
@@ -41,6 +41,7 @@ int pa_raop_client_connect(pa_raop_client *c);
 int pa_raop_client_flush(pa_raop_client *c);
 int pa_raop_client_teardown(pa_raop_client *c);
 
+int pa_raop_client_udp_is_alive(pa_raop_client *c);
 int pa_raop_client_udp_can_stream(pa_raop_client *c);
 
 void pa_raop_client_set_encryption(pa_raop_client *c, int encryption);
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 00/37] raop2 support for module-raop-sink

2016-01-31 Thread Hajime Fujita
From: Hajime Fujita <crisp.fuj...@nifty.com>

This is basically same as the previous patch series,
with several patches squashed for conciseness, rebased
on the latest master.
http://lists.freedesktop.org/archives/pulseaudio-discuss/2015-October/024547.html

This patch set adds a support for UDP version of RAOP (so called
raop2). Most of the RAOP devices (e.g. AppleTV, AirportExpress,
third party AV receivers) today use UDP version, so this patch
set is expected to support those devices.

Also the patches can be seen from here:
https://github.com/hfujita/pulseaudio-raop2/compare/323dc5bf...hf/raop2-v4-v8.0

Colin Leroy (5):
  rtp: New pa_rtsp_options function
  raop: Fix sink getting destroyed after one use
  raop: fix sequence number overflow
  raop: fix typos
  raop: Fix packet retransmission

Hajime Fujita (11):
  Support IPv6 address in pa_socket_client_new_string()
  rtp: Freeing ioline when disconnecting
  rtp: Introduce pa_rtsp_exec_ready()
  raop: Add UDP protocol handling
  raop: Add address to RAOP device description
  raop: Add IPv6 support
  raop: Silently drop out-of-history retransmission request
  raop: Stop recording when RTSP FLUSH is issued
  raop: Disable is_recording flag when tearing down the connection
  raop: Discard data upon getting EAGAIN on a socket
  raop: Fix memory leaks

Martin Blanchard (17):
  raop: Cosmetic fixes / Match coding style
  raop: Add pulsecore/core-utils a pa_str_in_list function
  raop: Parse server capabilities on discovery
  rtp: Random seq number at the beginning of the session
  raop: Do not send audio before RECORD response
  raop: Better playback resume handling
  raop: Extract encryption related code into a separate file
  raop: Add a MD5 hashing fuction
  raop: Add BA (Basic) and DA (Digest) HTTP authentication helpers
  raop: Add the core implementation of RAOP authentication
  raop: Merge TCP and UDP code paths + refactoring
  raop: Prefer ALAC encoding to raw PCM if supported by server
  raop: Update and standardise source file headers
  raop: Rework packet's store memory management
  raop: Remove unimplemented code (PCM and AAC)
  raop: Correctly wrap RTP packet sequence number
  raop: Add back initial volume RTSP SET_PARAMETER request on connect

Matthias Wabersich (1):
  raop: Packet retransmission support for UDP

Stephen Paul Weber (1):
  raop: Do not flush when RTSP object is not ready

ced2c (2):
  raop: Fix #36: invalid access to freed object
  raop: Fix #37: OOB access in rtsp_auth_cb

 src/Makefile.am |8 +-
 src/modules/raop/base64.c   |  124 ---
 src/modules/raop/base64.h   |   32 -
 src/modules/raop/module-raop-discover.c |  253 +++--
 src/modules/raop/module-raop-sink.c |  636 +--
 src/modules/raop/raop-client.c  | 1767 +++
 src/modules/raop/raop-client.h  |   83 ++
 src/modules/raop/raop-crypto.c  |  146 +++
 src/modules/raop/raop-crypto.h  |   35 +
 src/modules/raop/raop-packet-buffer.c   |  161 +++
 src/modules/raop/raop-packet-buffer.h   |   40 +
 src/modules/raop/raop-sink.c|  669 
 src/modules/raop/raop-sink.h|   33 +
 src/modules/raop/raop-util.c|  209 
 src/modules/raop/raop-util.h|   32 +
 src/modules/raop/raop_client.c  |  563 --
 src/modules/raop/raop_client.h  |   42 -
 src/modules/rtp/rtsp_client.c   |  173 ++-
 src/modules/rtp/rtsp_client.h   |   60 +-
 src/pulsecore/core-util.c   |   20 +
 src/pulsecore/core-util.h   |5 +-
 src/pulsecore/parseaddr.c   |   11 +
 src/pulsecore/parseaddr.h   |2 +
 src/pulsecore/socket-client.c   |   21 +-
 24 files changed, 3598 insertions(+), 1527 deletions(-)
 delete mode 100644 src/modules/raop/base64.c
 delete mode 100644 src/modules/raop/base64.h
 create mode 100644 src/modules/raop/raop-client.c
 create mode 100644 src/modules/raop/raop-client.h
 create mode 100644 src/modules/raop/raop-crypto.c
 create mode 100644 src/modules/raop/raop-crypto.h
 create mode 100644 src/modules/raop/raop-packet-buffer.c
 create mode 100644 src/modules/raop/raop-packet-buffer.h
 create mode 100644 src/modules/raop/raop-sink.c
 create mode 100644 src/modules/raop/raop-sink.h
 create mode 100644 src/modules/raop/raop-util.c
 create mode 100644 src/modules/raop/raop-util.h
 delete mode 100644 src/modules/raop/raop_client.c
 delete mode 100644 src/modules/raop/raop_client.h

-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 01/37] Support IPv6 address in pa_socket_client_new_string()

2016-01-31 Thread Hajime Fujita
From: Hajime Fujita <crisp.fuj...@nifty.com>

pa_socket_client_new_string() did not work as expected when an IPv6
address string like "2001:db8::1" is passed as the "name" parameter.
This is because the name parameter is then passed to pa_parse_address(),
which thinks the last colon as a separator between hostname (or address)
and a port number. To prevent pa_parse_address() from doing this, an IPv6
address must be bracketed with "[]" (e.g. "[2001:db8::1]"). [1]

This patch fixes pa_socket_client_new_string() so that it internally
adds brackets to an IPv6 address. This decision is based on a
discussion at [2].

[1]: 
http://lists.freedesktop.org/archives/pulseaudio-discuss/2014-October/022010.html
[2]: 
http://lists.freedesktop.org/archives/pulseaudio-discuss/2014-November/022401.html
---
 src/pulsecore/parseaddr.c | 11 +++
 src/pulsecore/parseaddr.h |  2 ++
 src/pulsecore/socket-client.c | 21 +++--
 3 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/src/pulsecore/parseaddr.c b/src/pulsecore/parseaddr.c
index 7f72e79..b909f52 100644
--- a/src/pulsecore/parseaddr.c
+++ b/src/pulsecore/parseaddr.c
@@ -143,3 +143,14 @@ bool pa_is_ip_address(const char *a) {
 
 return false;
 }
+
+bool pa_is_ip6_address(const char *a) {
+char buf[INET6_ADDRSTRLEN];
+
+pa_assert(a);
+
+if (inet_pton(AF_INET6, a, buf) >= 1)
+return true;
+
+return false;
+}
diff --git a/src/pulsecore/parseaddr.h b/src/pulsecore/parseaddr.h
index 5d2c358..6bb4d85 100644
--- a/src/pulsecore/parseaddr.h
+++ b/src/pulsecore/parseaddr.h
@@ -41,4 +41,6 @@ int pa_parse_address(const char *a, pa_parsed_address *ret_p);
 
 bool pa_is_ip_address(const char *a);
 
+bool pa_is_ip6_address(const char *a);
+
 #endif
diff --git a/src/pulsecore/socket-client.c b/src/pulsecore/socket-client.c
index b4067f0..c87406d 100644
--- a/src/pulsecore/socket-client.c
+++ b/src/pulsecore/socket-client.c
@@ -428,12 +428,28 @@ static void start_timeout(pa_socket_client *c, bool 
use_rtclock) {
 pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, bool 
use_rtclock, const char*name, uint16_t default_port) {
 pa_socket_client *c = NULL;
 pa_parsed_address a;
+char *name_buf;
 
 pa_assert(m);
 pa_assert(name);
 
-if (pa_parse_address(name, ) < 0)
-return NULL;
+a.path_or_host = NULL;
+
+if (pa_is_ip6_address(name)) {
+size_t len = strlen(name);
+name_buf = pa_xmalloc(len + 3);
+memcpy(name_buf + 1, name, len);
+name_buf[0] = '[';
+name_buf[len + 1] = ']';
+name_buf[len + 2] = '\0';
+} else {
+name_buf = pa_xstrdup(name);
+}
+
+if (pa_parse_address(name_buf, ) < 0) {
+pa_log_warn("parsing address failed: %s", name_buf);
+goto finish;
+}
 
 if (!a.port)
 a.port = default_port;
@@ -530,6 +546,7 @@ pa_socket_client* 
pa_socket_client_new_string(pa_mainloop_api *m, bool use_rtclo
 }
 
 finish:
+pa_xfree(name_buf);
 pa_xfree(a.path_or_host);
 return c;
 
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 14/37] raop: Add a MD5 hashing fuction

2016-01-31 Thread Hajime Fujita
From: Martin Blanchard 

MD5 hashing will be needed during the authentication process. Base64 and
MD5 code is now in a commun file called raop_util.c. Old Base64 files are
removed but copyright is preserved.
---
 src/Makefile.am|   4 +-
 src/modules/raop/base64.c  | 136 -
 src/modules/raop/base64.h  |  32 
 src/modules/raop/raop_client.c |   6 +-
 src/modules/raop/raop_crypto.c |  10 +--
 src/modules/raop/raop_util.c   | 170 +
 src/modules/raop/raop_util.h   |  28 +++
 7 files changed, 208 insertions(+), 178 deletions(-)
 delete mode 100644 src/modules/raop/base64.c
 delete mode 100644 src/modules/raop/base64.h
 create mode 100644 src/modules/raop/raop_util.c
 create mode 100644 src/modules/raop/raop_util.h

diff --git a/src/Makefile.am b/src/Makefile.am
index e5b9131..9a1e1cf 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1133,9 +1133,9 @@ librtp_la_LIBADD = $(AM_LIBADD) 
libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@
 
 libraop_la_SOURCES = \
 modules/raop/raop_client.c modules/raop/raop_client.h \
+modules/raop/raop_packet_buffer.h modules/raop/raop_packet_buffer.c \
 modules/raop/raop_crypto.c modules/raop/raop_crypto.h \
-modules/raop/base64.c modules/raop/base64.h \
-modules/raop/raop_packet_buffer.h modules/raop/raop_packet_buffer.c
+modules/raop/raop_util.c modules/raop/raop_util.h
 libraop_la_CFLAGS = $(AM_CFLAGS) $(OPENSSL_CFLAGS) 
-I$(top_srcdir)/src/modules/rtp
 libraop_la_LDFLAGS = $(AM_LDFLAGS) $(AM_LIBLDFLAGS) -avoid-version
 libraop_la_LIBADD = $(AM_LIBADD) $(OPENSSL_LIBS) 
libpulsecore-@PA_MAJORMINOR@.la librtp.la libpulsecommon-@PA_MAJORMINOR@.la 
libpulse.la
diff --git a/src/modules/raop/base64.c b/src/modules/raop/base64.c
deleted file mode 100644
index d541745..000
--- a/src/modules/raop/base64.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2008 Colin Guthrie
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio 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 Lesser General Public License
-  along with PulseAudio; if not, see .
-***/
-
-/***
-  This file was originally inspired by a file developed by
-  Kungliga Tekniska Høgskolan.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include 
-#endif
-
-#include 
-#include 
-
-#include 
-
-#include "base64.h"
-
-static const char base64_chars[] =
-"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-static int pos(char c) {
-if (c >= 'A' && c <= 'Z')
-return c - 'A' + 0;
-if (c >= 'a' && c <= 'z')
-return c - 'a' + 26;
-if (c >= '0' && c <= '9')
-return c - '0' + 52;
-if (c == '+')
-return 62;
-if (c == '/')
-return 63;
-
-return -1;
-}
-
-int pa_base64_encode(const void *data, int size, char **str) {
-char *s, *p;
-int i;
-int c;
-const unsigned char *q;
-
-p = s = pa_xnew(char, size * 4 / 3 + 4);
-q = (const unsigned char *) data;
-for (i = 0; i < size;) {
-c = q[i++];
-c *= 256;
-if (i < size)
-c += q[i];
-i++;
-c *= 256;
-if (i < size)
-c += q[i];
-i++;
-p[0] = base64_chars[(c & 0x00fc) >> 18];
-p[1] = base64_chars[(c & 0x0003f000) >> 12];
-p[2] = base64_chars[(c & 0x0fc0) >> 6];
-p[3] = base64_chars[(c & 0x003f) >> 0];
-if (i > size)
-p[3] = '=';
-if (i > size + 1)
-p[2] = '=';
-p += 4;
-}
-
-*p = 0;
-*str = s;
-
-return strlen(s);
-}
-
-#define DECODE_ERROR 0x
-
-static unsigned int token_decode(const char *token) {
-int i;
-unsigned int val = 0;
-int marker = 0;
-
-if (strlen(token) < 4)
-return DECODE_ERROR;
-for (i = 0; i < 4; i++) {
-val *= 64;
-if (token[i] == '=')
-marker++;
-else if (marker > 0)
-return DECODE_ERROR;
-else {
-int lpos = pos(token[i]);
-if (lpos < 0)
-return DECODE_ERROR;
-val += lpos;
-}
-}
-
-if (marker > 2)
-return DECODE_ERROR;
-
-return (marker << 24) | val;
-}
-
-int pa_base64_decode(const char *str, void *data) {
-const char *p;
-unsigned char *q;
-
-q = data;
-for (p = str; *p && (*p == '=' || strchr(base64_chars, *p)); p += 4) {
-

[pulseaudio-discuss] [PATCH v6 15/37] raop: Add BA (Basic) and DA (Digest) HTTP authentication helpers

2016-01-31 Thread Hajime Fujita
From: Martin Blanchard 

RAOP authentication is using standard HTTP challenge-response authentication
scheme. This patch adds two helper functions that generate the proper hash
(for both techniques) given a username, a password and session related tokens.
---
 src/modules/raop/raop_util.c | 40 
 src/modules/raop/raop_util.h |  4 
 2 files changed, 44 insertions(+)

diff --git a/src/modules/raop/raop_util.c b/src/modules/raop/raop_util.c
index 54f7c6d..d13b7ee 100644
--- a/src/modules/raop/raop_util.c
+++ b/src/modules/raop/raop_util.c
@@ -35,6 +35,7 @@
 
 #include 
 
+#include 
 #include 
 
 #include "raop_util.h"
@@ -168,3 +169,42 @@ int pa_raop_md5_hash(const char *data, int len, char 
**str) {
 s[MD5_HASH_LENGTH] = 0;
 return strlen(s);
 }
+
+int pa_raop_basic_response(const char *user, const char *pwd, char **str) {
+char *tmp, *B = NULL;
+
+pa_assert(str);
+
+tmp = pa_sprintf_malloc("%s:%s", user, pwd);
+pa_raop_base64_encode(tmp, strlen(tmp), );
+pa_xfree(tmp);
+
+*str = B;
+return strlen(B);
+}
+
+int pa_raop_digest_response(const char *user, const char *realm, const char 
*password,
+const char *nonce, const char *uri, char **str) {
+char *A1, *HA1, *A2, *HA2;
+char *tmp, *KD = NULL;
+
+pa_assert(str);
+
+A1 = pa_sprintf_malloc("%s:%s:%s", user, realm, password);
+pa_raop_md5_hash(A1, strlen(A1), );
+pa_xfree(A1);
+
+A2 = pa_sprintf_malloc("OPTIONS:%s", uri);
+pa_raop_md5_hash(A2, strlen(A2), );
+pa_xfree(A2);
+
+tmp = pa_sprintf_malloc("%s:%s:%s", HA1, nonce, HA2);
+pa_raop_md5_hash(tmp, strlen(tmp), );
+pa_xfree(tmp);
+
+pa_xfree(HA1);
+pa_xfree(HA2);
+
+*str = KD;
+return strlen(KD);
+}
diff --git a/src/modules/raop/raop_util.h b/src/modules/raop/raop_util.h
index a95c822..a3f0dfa 100644
--- a/src/modules/raop/raop_util.h
+++ b/src/modules/raop/raop_util.h
@@ -25,4 +25,8 @@ int pa_raop_base64_decode(const char *str, void *data);
 
 int pa_raop_md5_hash(const char *data, int len, char **str);
 
+int pa_raop_basic_response(const char *user, const char *pwd, char **str);
+int pa_raop_digest_response(const char *user, const char *realm, const char 
*password,
+const char *nonce, const char *uri, char **str);
+
 #endif
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 10/37] raop: Packet retransmission support for UDP

2016-01-31 Thread Hajime Fujita
From: Matthias Wabersich <pulseau...@niafc.de>

This patch adds an RTP audio packet retransmission support and a
circular buffer implementation for it.

This patch was originally written by Matthias Wabersich [1] and
later debugged and integrated into the latest tree by Hajime Fujita

[1]: https://bugs.freedesktop.org/show_bug.cgi?id=42804#c44
---
 src/Makefile.am   |   3 +-
 src/modules/raop/raop_client.c| 109 ++---
 src/modules/raop/raop_client.h|   2 +
 src/modules/raop/raop_packet_buffer.c | 172 ++
 src/modules/raop/raop_packet_buffer.h |  42 +
 5 files changed, 316 insertions(+), 12 deletions(-)
 create mode 100644 src/modules/raop/raop_packet_buffer.c
 create mode 100644 src/modules/raop/raop_packet_buffer.h

diff --git a/src/Makefile.am b/src/Makefile.am
index b0ca2bc..d60cc19 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1133,7 +1133,8 @@ librtp_la_LIBADD = $(AM_LIBADD) 
libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@
 
 libraop_la_SOURCES = \
 modules/raop/raop_client.c modules/raop/raop_client.h \
-modules/raop/base64.c modules/raop/base64.h
+modules/raop/base64.c modules/raop/base64.h \
+modules/raop/raop_packet_buffer.h modules/raop/raop_packet_buffer.c
 libraop_la_CFLAGS = $(AM_CFLAGS) $(OPENSSL_CFLAGS) 
-I$(top_srcdir)/src/modules/rtp
 libraop_la_LDFLAGS = $(AM_LDFLAGS) $(AM_LIBLDFLAGS) -avoid-version
 libraop_la_LIBADD = $(AM_LIBADD) $(OPENSSL_LIBS) 
libpulsecore-@PA_MAJORMINOR@.la librtp.la libpulsecommon-@PA_MAJORMINOR@.la 
libpulse.la
diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c
index c0be2ec..1c6c49e 100644
--- a/src/modules/raop/raop_client.c
+++ b/src/modules/raop/raop_client.c
@@ -59,7 +59,8 @@
 #include "rtsp_client.h"
 #include "base64.h"
 
-#define UDP_FRAMES_PER_PACKET 352
+#include "raop_packet_buffer.h"
+
 #define AES_CHUNKSIZE 16
 
 #define JACK_STATUS_DISCONNECTED 0
@@ -77,6 +78,8 @@
 #define UDP_DEFAULT_CONTROL_PORT 6001
 #define UDP_DEFAULT_TIMING_PORT 6002
 
+#define UDP_DEFAULT_PKT_BUF_SIZE 1000
+
 typedef enum {
 UDP_PAYLOAD_TIMING_REQUEST = 0x52,
 UDP_PAYLOAD_TIMING_RESPONSE = 0x53,
@@ -140,6 +143,8 @@ struct pa_raop_client {
 
 pa_raop_client_disconnected_cb_t udp_disconnected_callback;
 void *udp_disconnected_userdata;
+
+pa_raop_packet_buffer *packet_buffer;
 };
 
 /* Timming packet header (8x8):
@@ -530,12 +535,35 @@ static void udp_build_audio_header(pa_raop_client *c, 
uint32_t *buffer, size_t s
 buffer[2] = htonl(c->udp_ssrc);
 }
 
-static ssize_t udp_send_audio_packet(pa_raop_client *c, uint8_t *buffer, 
size_t size) {
-ssize_t length;
+/* Audio retransmission header:
+ * [0]RTP v2: 0x80
+ * [1]Payload type: 0x56 + 0x80 (marker == on)
+ * [2]Unknown; seems always 0x01
+ * [3]Unknown; seems some random number around 0x20~0x40
+ * [4,5]  Original RTP header htons(0x8060)
+ * [6,7]  Packet sequence number to be retransmitted
+ * [8,11] Original RTP timestamp on the lost packet */
+static void udp_build_retrans_header(uint32_t *buffer, size_t size, uint16_t 
seq_num) {
+uint8_t x = 0x30; /* FIXME: what's this?? */
+
+pa_assert(size >= sizeof(uint32_t) * 2);
+
+buffer[0] = htonl((uint32_t) 0x8000
+  | ((uint32_t) UDP_PAYLOAD_RETRANSMIT_REPLY | 0x80) << 16
+  | 0x0100
+  | x);
+buffer[1] = htonl((uint32_t) 0x8060 | seq_num);
+}
 
-length = pa_write(c->udp_stream_fd, buffer, size, NULL);
-c->seq++;
+static ssize_t udp_send_audio_packet(pa_raop_client *c, bool retrans, uint8_t 
*buffer, size_t size) {
+ssize_t length;
+int fd = retrans ? c->udp_control_fd : c->udp_stream_fd;
 
+length = pa_write(fd, buffer, size, NULL);
+if (length < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
+pa_log_debug("Discarding audio packet %d due to EAGAIN", c->seq);
+length = size;
+}
 return length;
 }
 
@@ -947,6 +975,8 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state 
state, pa_headerlist
 
 pa_log_debug("RTSP control channel closed (teardown)");
 
+pa_raop_pb_clear(c->packet_buffer);
+
 pa_rtsp_client_free(c->rtsp);
 pa_xfree(c->sid);
 c->rtsp = NULL;
@@ -983,6 +1013,8 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, 
pa_rtsp_state state, pa_headerlist
 
 pa_log_debug("RTSP control channel closed (disconnected)");
 
+pa_raop_pb_clear(c->packet_buffer);
+
 pa_rtsp_client_free(c->rtsp);
 pa_xfree(c->sid);
 c->rtsp = NULL;
@@ -1046,7 +1078,8 @@ pa_raop_client* pa_raop_client_new(pa_core *core, const 
char *host, pa_raop_prot
 pa_raop_client_free(c);
 return NULL;
  

[pulseaudio-discuss] [PATCH v6 32/37] raop: Stop recording when RTSP FLUSH is issued

2016-01-31 Thread Hajime Fujita
From: Hajime Fujita <crisp.fuj...@nifty.com>

This patch fixes the issue #31.
https://github.com/hfujita/pulseaudio-raop2/issues/31

This patch sets c->is_recording = false when the RTSP FLUSH command
is issued. This avoids a race between the server response and
the record activation in some cases.
---
 src/modules/raop/raop-client.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index d8de2ae..9dc40f4 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -1114,8 +1114,6 @@ static void rtsp_stream_cb(pa_rtsp_client *rtsp, 
pa_rtsp_state_t state, pa_rtsp_
 case STATE_FLUSH: {
 pa_log_debug("RAOP: FLUSHED");
 
-c->is_recording = false;
-
 break;
 }
 
@@ -1613,6 +1611,8 @@ int pa_raop_client_flush(pa_raop_client *c) {
 return 1;
 }
 
+c->is_recording = false;
+
 rv = pa_rtsp_flush(c->rtsp, c->seq, c->rtptime);
 return rv;
 }
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 34/37] raop: Discard data upon getting EAGAIN on a socket

2016-01-31 Thread Hajime Fujita
From: Hajime Fujita <crisp.fuj...@nifty.com>

This patch discards audio data when a socket returns EAGAIN.
This was made based on a suggestion by karlstav
(https://github.com/karlstav), and is supposed to solve Issue #32.
(https://github.com/hfujita/pulseaudio-raop2/issues/32)
---
 src/modules/raop/raop-client.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index 533dc81..998e450 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -471,8 +471,7 @@ static ssize_t send_udp_audio_packet(pa_raop_client *c, 
pa_memchunk *block, size
 written = pa_write(c->udp_sfd, buffer, packet->length, NULL);
 if (written < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
 pa_log_debug("Discarding UDP (audio, seq=%d) packet due to EAGAIN 
(%s)", c->seq, pa_cstrerror(errno));
-pa_memblock_release(packet->memblock);
-return (ssize_t) packet->length;
+written = packet->length;
 }
 
 pa_memblock_release(packet->memblock);
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 03/37] raop: Cosmetic fixes / Match coding style

2016-01-31 Thread Hajime Fujita
From: Martin Blanchard 

---
 src/modules/raop/base64.c   |  28 --
 src/modules/raop/base64.h   |   6 +-
 src/modules/raop/module-raop-discover.c | 169 
 src/modules/raop/module-raop-sink.c |  56 +--
 src/modules/raop/raop_client.c  |  91 -
 src/modules/raop/raop_client.h  |  16 +--
 src/modules/rtp/rtsp_client.c   |  64 +++-
 src/modules/rtp/rtsp_client.h   |  32 +++---
 8 files changed, 246 insertions(+), 216 deletions(-)

diff --git a/src/modules/raop/base64.c b/src/modules/raop/base64.c
index cdf52a6..d541745 100644
--- a/src/modules/raop/base64.c
+++ b/src/modules/raop/base64.c
@@ -17,10 +17,10 @@
   along with PulseAudio; if not, see .
 ***/
 
-/*
+/***
   This file was originally inspired by a file developed by
-Kungliga Tekniska H�gskolan
-*/
+  Kungliga Tekniska Høgskolan.
+***/
 
 #ifdef HAVE_CONFIG_H
 #include 
@@ -37,11 +37,17 @@ static const char base64_chars[] =
 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
 static int pos(char c) {
-if (c >= 'A' && c <= 'Z') return c - 'A' + 0;
-if (c >= 'a' && c <= 'z') return c - 'a' + 26;
-if (c >= '0' && c <= '9') return c - '0' + 52;
-if (c == '+') return 62;
-if (c == '/') return 63;
+if (c >= 'A' && c <= 'Z')
+return c - 'A' + 0;
+if (c >= 'a' && c <= 'z')
+return c - 'a' + 26;
+if (c >= '0' && c <= '9')
+return c - '0' + 52;
+if (c == '+')
+return 62;
+if (c == '/')
+return 63;
+
 return -1;
 }
 
@@ -73,8 +79,10 @@ int pa_base64_encode(const void *data, int size, char **str) 
{
 p[2] = '=';
 p += 4;
 }
+
 *p = 0;
 *str = s;
+
 return strlen(s);
 }
 
@@ -84,6 +92,7 @@ static unsigned int token_decode(const char *token) {
 int i;
 unsigned int val = 0;
 int marker = 0;
+
 if (strlen(token) < 4)
 return DECODE_ERROR;
 for (i = 0; i < 4; i++) {
@@ -99,8 +108,10 @@ static unsigned int token_decode(const char *token) {
 val += lpos;
 }
 }
+
 if (marker > 2)
 return DECODE_ERROR;
+
 return (marker << 24) | val;
 }
 
@@ -120,5 +131,6 @@ int pa_base64_decode(const char *str, void *data) {
 if (marker < 1)
 *q++ = val & 0xff;
 }
+
 return q - (unsigned char *) data;
 }
diff --git a/src/modules/raop/base64.h b/src/modules/raop/base64.h
index 352ab96..ce6b9c4 100644
--- a/src/modules/raop/base64.h
+++ b/src/modules/raop/base64.h
@@ -21,10 +21,10 @@
   along with PulseAudio; if not, see .
 ***/
 
-/*
+/***
   This file was originally inspired by a file developed by
-Kungliga Tekniska Høgskolan
-*/
+  Kungliga Tekniska Høgskolan.
+***/
 
 int pa_base64_encode(const void *data, int size, char **str);
 int pa_base64_decode(const char *str, void *data);
diff --git a/src/modules/raop/module-raop-discover.c 
b/src/modules/raop/module-raop-discover.c
index f083044..1ced777 100644
--- a/src/modules/raop/module-raop-discover.c
+++ b/src/modules/raop/module-raop-discover.c
@@ -52,6 +52,17 @@ PA_MODULE_LOAD_ONCE(true);
 
 #define SERVICE_TYPE_SINK "_raop._tcp"
 
+struct userdata {
+pa_core *core;
+pa_module *module;
+
+AvahiPoll *avahi_poll;
+AvahiClient *client;
+AvahiServiceBrowser *sink_browser;
+
+pa_hashmap *tunnels;
+};
+
 static const char* const valid_modargs[] = {
 NULL
 };
@@ -63,16 +74,6 @@ struct tunnel {
 uint32_t module_index;
 };
 
-struct userdata {
-pa_core *core;
-pa_module *module;
-AvahiPoll *avahi_poll;
-AvahiClient *client;
-AvahiServiceBrowser *sink_browser;
-
-pa_hashmap *tunnels;
-};
-
 static unsigned tunnel_hash(const void *p) {
 const struct tunnel *t = p;
 
@@ -102,11 +103,11 @@ static int tunnel_compare(const void *a, const void *b) {
 return 0;
 }
 
-static struct tunnel *tunnel_new(
+static struct tunnel* tunnel_new(
 AvahiIfIndex interface, AvahiProtocol protocol,
 const char *name, const char *type, const char *domain) {
-
 struct tunnel *t;
+
 t = pa_xnew(struct tunnel, 1);
 t->interface = interface;
 t->protocol = protocol;
@@ -114,6 +115,7 @@ static struct tunnel *tunnel_new(
 t->type = pa_xstrdup(type);
 t->domain = pa_xstrdup(domain);
 t->module_index = PA_IDXSET_INVALID;
+
 return t;
 }
 
@@ -134,88 +136,87 @@ static void resolver_cb(
 AvahiStringList *txt,
 AvahiLookupResultFlags flags,
 void *userdata) {
-
 struct userdata *u = userdata;
 struct tunnel *tnl;
+char *device = NULL, *nicename, *dname, *vname, *args;
+char at[AVAHI_ADDRESS_STR_MAX];
+AvahiStringList *l;
+pa_module *m;
 
 pa_assert(u);
 
 tnl = tunnel_new(interface, protocol, name, type, domain);
 
-if (event != AVAHI_RESOLVER_FOUND)
+if (event != 

[pulseaudio-discuss] [PATCH v6 27/37] raop: Add address to RAOP device description

2016-01-31 Thread Hajime Fujita
From: Hajime Fujita <crisp.fuj...@nifty.com>

Some time one device announces multiple addresses (e.g. IPv4 one
and IPv6 one). Or some user may own multiple RAOP devices with
the same model name.
This patch adds device port to device description so that users
can distinguish appropriate RAOP sink by its address.
---
 src/modules/raop/module-raop-discover.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/src/modules/raop/module-raop-discover.c 
b/src/modules/raop/module-raop-discover.c
index 00065aa..05911b4 100644
--- a/src/modules/raop/module-raop-discover.c
+++ b/src/modules/raop/module-raop-discover.c
@@ -236,19 +236,22 @@ static void resolver_cb(
 
 pa_xfree(dname);
 
+avahi_address_snprint(at, sizeof(at), a);
 if (nicename) {
 args = pa_sprintf_malloc("server=[%s]:%u "
  "sink_name=%s "
- "sink_properties='device.description=\"%s\"'",
- avahi_address_snprint(at, sizeof(at), a), 
port,
+ "sink_properties='device.description=\"%s 
(%s:%u)\"'",
+ at, port,
  vname,
- nicename);
+ nicename, at, port);
 pa_xfree(nicename);
 } else {
 args = pa_sprintf_malloc("server=[%s]:%u "
- "sink_name=%s",
- avahi_address_snprint(at, sizeof(at), a), 
port,
- vname);
+ "sink_name=%s"
+ 
"sink_properties='device.description=\"%s:%u\"'",
+ at, port,
+ vname,
+ at, port);
 }
 
 if (tp != NULL) {
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 07/37] rtp: Random seq number at the beginning of the session

2016-01-31 Thread Hajime Fujita
From: Martin Blanchard 

---
 src/modules/rtp/rtsp_client.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/modules/rtp/rtsp_client.c b/src/modules/rtp/rtsp_client.c
index aa0217d..6e65860 100644
--- a/src/modules/rtp/rtsp_client.c
+++ b/src/modules/rtp/rtsp_client.c
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "rtsp_client.h"
 
@@ -199,7 +200,7 @@ static void line_callback(pa_ioline *line, const char *s, 
void *userdata) {
 }
 if (c->waiting) {
 pa_log_warn("Unexpected response: %s", s2);
-goto exit;;
+goto exit;
 }
 if (!strlen(s2)) {
 /* End of headers */
@@ -504,8 +505,8 @@ int pa_rtsp_record(pa_rtsp_client *c, uint16_t *seq, 
uint32_t *rtptime) {
 return -1;
 }
 
-/* Todo: Generate these values randomly as per spec */
-*seq = *rtptime = 0;
+pa_random(seq, sizeof(*seq));
+pa_random(rtptime, sizeof(*rtptime));
 
 headers = pa_headerlist_new();
 pa_headerlist_puts(headers, "Range", "npt=0-");
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 33/37] raop: Disable is_recording flag when tearing down the connection

2016-01-31 Thread Hajime Fujita
From: Hajime Fujita <crisp.fuj...@nifty.com>

This patch is based on a similar idea as the previous one -- disabling
the flag right after the session is getting closed, rather than waiting
for a response from the server.
---
 src/modules/raop/raop-client.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index 9dc40f4..533dc81 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -1120,8 +1120,6 @@ static void rtsp_stream_cb(pa_rtsp_client *rtsp, 
pa_rtsp_state_t state, pa_rtsp_
 case STATE_TEARDOWN: {
 pa_log_debug("RAOP: TEARDOWN");
 
-c->is_recording = false;
-
 if (c->tcp_sfd > 0)
 pa_close(c->tcp_sfd);
 c->tcp_sfd = -1;
@@ -1630,6 +1628,8 @@ int pa_raop_client_teardown(pa_raop_client *c) {
 return 1;
 }
 
+c->is_recording = false;
+
 rv = pa_rtsp_teardown(c->rtsp);
 return rv;
 }
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 18/37] raop: Prefer ALAC encoding to raw PCM if supported by server

2016-01-31 Thread Hajime Fujita
From: Martin Blanchard 

ALAC encoding is to be prefered simply because ALAC audio packet reverse-
engineering and implementation is in better shape than raw PCM. Sending ALAC
audio does not mean compressing audio and thus linking an external library to
do so. ALAC packets has the ability to carry uncompressed PCM frames, and
that's what is implemented at the time.
---
 src/modules/raop/module-raop-discover.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/modules/raop/module-raop-discover.c 
b/src/modules/raop/module-raop-discover.c
index f174da3..00065aa 100644
--- a/src/modules/raop/module-raop-discover.c
+++ b/src/modules/raop/module-raop-discover.c
@@ -198,7 +198,10 @@ static void resolver_cb(
  *  - 1 = ALAC,
  *  - 2 = AAC,
  *  - 3 = AAC ELD. */
-cn = strdup("PCM");
+if (pa_str_in_list(value, ",", "1"))
+cn = strdup("ALAC");
+else
+cn = strdup("PCM");
 } else if (pa_streq(key, "md")) {
 /* Supported metadata types:
  *  - 0 = text,
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH v6 08/37] rtp: Introduce pa_rtsp_exec_ready()

2016-01-31 Thread Hajime Fujita
From: Hajime Fujita <crisp.fuj...@nifty.com>

In the current RTSP implementation, there is a vulnerable window
between the RTSP object creation and the URL initialization.
If any RTSP command is issued during this period, it will lead to
crash by assertion violation.

This patch introduces pa_rtsp_exec_ready(), which returns if it is
safe to issue RTSP commands.
---
 src/modules/rtp/rtsp_client.c | 6 ++
 src/modules/rtp/rtsp_client.h | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/src/modules/rtp/rtsp_client.c b/src/modules/rtp/rtsp_client.c
index 6e65860..198417e 100644
--- a/src/modules/rtp/rtsp_client.c
+++ b/src/modules/rtp/rtsp_client.c
@@ -389,6 +389,12 @@ void pa_rtsp_remove_header(pa_rtsp_client *c, const char 
*key) {
 pa_headerlist_remove(c->headers, key);
 }
 
+bool pa_rtsp_exec_ready(const pa_rtsp_client *c) {
+pa_assert(c);
+
+return c->url != NULL && c->ioline != NULL;
+}
+
 static int rtsp_exec(pa_rtsp_client *c, const char *cmd,
 const char *content_type, const char *content,
 int expect_response,
diff --git a/src/modules/rtp/rtsp_client.h b/src/modules/rtp/rtsp_client.h
index 7e9978d..abc60ee 100644
--- a/src/modules/rtp/rtsp_client.h
+++ b/src/modules/rtp/rtsp_client.h
@@ -58,6 +58,8 @@ void pa_rtsp_set_url(pa_rtsp_client *c, const char *url);
 void pa_rtsp_add_header(pa_rtsp_client *c, const char *key, const char *value);
 void pa_rtsp_remove_header(pa_rtsp_client *c, const char *key);
 
+bool pa_rtsp_exec_ready(const pa_rtsp_client *c);
+
 int pa_rtsp_options(pa_rtsp_client *c);
 int pa_rtsp_announce(pa_rtsp_client *c, const char *sdp);
 
-- 
2.5.0

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] raop2 support for module-raop-sink (v5)

2015-10-15 Thread Hajime Fujita

Hello,

I'd like to ask for reviewing a set of patches on raop2 support again.
After a long period we finally resolved the memory corruption issue that 
was pointed out by Alexander [1].


The latest patches are here, rebased onto master as of today.
https://github.com/hfujita/pulseaudio-raop2/compare/12a93495b9cba1af...1ada704

[1]: 
http://lists.freedesktop.org/archives/pulseaudio-discuss/2015-January/023003.html


Now the code is tested with "valgrind  --trace-children=yes 
--leak-check=full ./src/pulseaudio". No raop-related warning showed up, 
while some from tools called from the libtools wrapper script showed up.
Also the following warning showed up but this was also observed in the 
master.

  ==19752== Warning: invalid file descriptor 1034 in syscall close()


Thank you in advance,
Hajime
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Patch review status wiki page updated

2015-01-19 Thread Hajime Fujita
Hi Tanu,

It is correct. And I checked out the Wiki page. Thank you for the updates!


Best,
Hajime

 On Jan 19, 2015, at 07:59, Tanu Kaskinen tanu.kaski...@linux.intel.com 
 wrote:
 
 On Sun, 2015-01-18 at 18:46 -0600, Hajime Fujita wrote:
 Hi Tanu,
 
 Could you update the location of the raop2 patch series to
 https://github.com/hfujita/pulseaudio-raop2/compare/29a20c7541845798c1367ad538126a7a19129139...hf/raop2-v2-v5.99.2
 
 This is our latest patches and already rebased against PA 6.0 RC2.
 
 Will do. If I understood correctly, you will still work on the Valgrind
 issues, so I'll keep the patch set still in the waiting for a new
 version section.
 
 -- 
 Tanu
 

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] RAOP2 patch testing result

2015-01-18 Thread Hajime Fujita

Hello Alexander,

I think I have fixed the leaks, and pushed the changes to
https://github.com/hfujita/pulseaudio-raop2 (at `hf/raop2-v2-v5.99.2` 
branch -- now it's rebased against RC2).


Could you give it a try?

Also, here's how I launched valgrind. If more detailed options are 
necessary please let me know.

  $ valgrind --leak-check=yes ./src/.libs/pulseaudio ...

Detailed output from valgrind can be found here:
https://github.com/hfujita/pulseaudio-raop2/issues/35


Thank you,
Hajime

Alexander E. Patrakov wrote:

05.01.2015 08:57, Hajime Fujita wrote:

Hello Alexander,



Then I pressed the back arrow to seek back. Result: it froze.

Also tested with VLC, seeking there does not freeze.


We believe we finally figured out the cause and fixed the issue.
Please try the latest patches in
https://github.com/hfujita/pulseaudio-raop2 (at `hf/raop2-v2-v5.99.1`
branch).


Fixed indeed.


The detailed discussion can be found here:
https://github.com/hfujita/pulseaudio-raop2/issues/31


With Bino, I was able to trigger this assertion failure:

E: [raop-sink-[192.168.1.39]:5000] rtsp_client.c: Assertion 'c-url'
failed at modules/rtp/rtsp_client.c:441, function rtsp_exec(). Aborting.


I could not reproduce this (Bino immediately crashed with any of my
input file), but I believe this has also been fixed in the above branch.
(https://github.com/hfujita/pulseaudio-raop2/issues/9)


Indeed, there is no such crash anymore.


Then I started Airfoil Speakers on Android. Result: PulseAudio does
not
see it, even if module-raop-discover is reloaded.


And Airfoil Speakers is not a RAOP2 server. So not a bug.

Still, we have a lot of valgrind splats during normal usage of the
module, please find them in the attached file.

If your PC is not fast enough by default to valgrind pulseaudio (i.e. if
pulseaudio gets killed on starting a new stream due to exhausting the
realtime budget), this default.pa tweak can help:

load-module module-udev-detect tsched_buffer_size=5



___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Patch review status wiki page updated

2015-01-18 Thread Hajime Fujita

Hi Tanu,

Could you update the location of the raop2 patch series to
https://github.com/hfujita/pulseaudio-raop2/compare/29a20c7541845798c1367ad538126a7a19129139...hf/raop2-v2-v5.99.2

This is our latest patches and already rebased against PA 6.0 RC2.


Thanks,
Hajime

Tanu Kaskinen wrote:

Patch review status updated:
http://www.freedesktop.org/wiki/Software/PulseAudio/PatchStatus/

Statistics:

* 2015-01-13
   * 21 patches are pending review.
   * The oldest pending patch is 177 days old.

* 2015-01-08
   * 26 patches are pending review.
   * The oldest pending patch is 172 days old.

* 2014-12-29
   * 22 patches are pending review.
   * The oldest pending patch is 162 days old.

* 2014-12-22
   * 23 patches are pending review.
   * The oldest pending patch is 155 days old.

* 2014-12-15
   * 21 patches are pending review.
   * The oldest pending patch is 148 days old.

* 2014-12-08
   * 22 patches are pending review.
   * The oldest pending patch is 141 days old.

* 2014-12-01
   * 24 patches are pending review.
   * The oldest pending patch is 134 days old.

* 2014-11-18
   * 71 patches are pending review.
   * The oldest pending patch is 427 days old.

* 2014-11-11
   * 72 patches are pending review.
   * The oldest pending patch is 420 days old.

* 2014-09-28
   * 148 patches are pending review.
   * The oldest pending patch is 386 days old.



___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] RAOP2 patch testing result

2015-01-04 Thread Hajime Fujita

Hello Alexander,

Alexander E. Patrakov wrote:

13.11.2014 02:13, Martin Blanchard wrote:

On Tue, 2014-11-11 at 23:45 +0500, Alexander E. Patrakov wrote:

Hi.


Hello Alexander!


I have cloned the raop2-v2 branch from
https://github.com/colinleroy/pulseaudio


First, thanks for the testings.


The following test was applied.

I have installed the Android HiFi application (also known as HiFi
Speaker), version 1.7 Beta, on my Android phone, and started it.

Link: http://forum.xda-developers.com/showthread.php?p=29986442

Version is important: this one is possibly-buggy in an interesting way.
Also, newer versions require a license for more than 30 minutes of
playback. Note: for some reason, Google Play has removed this app, so
you can only get it from various shady sources such as above.

Then, I ran the following command:

pacmd load-module module-raop-discover

Result: it found the speaker!

Then I started mpv on a music file, and redirected its output to the
HiFi Speaker using pavucontrol. Result: it worked.

Then I pressed the back arrow to seek back. Result: it froze.


I can reproduce that, will try to fix it. You should not experience such
a problem with GStreamer based players, I think. Have you try any other
players?


I had no GStreamer-based players installed, so installed gst123 for a
quick test. Result: same freeze.

Also tested with VLC, seeking there does not freeze.


We believe we finally figured out the cause and fixed the issue.
Please try the latest patches in 
https://github.com/hfujita/pulseaudio-raop2 (at `hf/raop2-v2-v5.99.1` 
branch).


The detailed discussion can be found here:
https://github.com/hfujita/pulseaudio-raop2/issues/31


With Bino, I was able to trigger this assertion failure:

E: [raop-sink-[192.168.1.39]:5000] rtsp_client.c: Assertion 'c-url'
failed at modules/rtp/rtsp_client.c:441, function rtsp_exec(). Aborting.


I could not reproduce this (Bino immediately crashed with any of my 
input file), but I believe this has also been fixed in the above branch.

(https://github.com/hfujita/pulseaudio-raop2/issues/9)


Then I killed the HiFi Speaker application on Android. Result:
PulseAudio unfroze mpv's stream and moved it back to analog headphones.

Then I started Airfoil Speakers on Android. Result: PulseAudio does not
see it, even if module-raop-discover is reloaded.


This may be a module-raop-discover bug (Avahi related). Can you post the
full pulseaudio log?


Sure. And here is what avahi-browse --all prints:

aep@aep-haswell ~/raop/pulseaudio $ avahi-browse --all
+   eno1 IPv6 aep@aep-haswell: Built-in Audio Digital Stereo (HDMI)
_pulse-sink._tcp local
+   eno1 IPv6 aep@aep-haswell: Built-in Audio Analog Stereo
_pulse-sink._tcp local
+   eno1 IPv4 aep@aep-haswell: Built-in Audio Digital Stereo (HDMI)
_pulse-sink._tcp local
+   eno1 IPv4 aep@aep-haswell: Built-in Audio Analog Stereo
_pulse-sink._tcp local
+   eno1 IPv6 aep@aep-haswell _pulse-server._tcp   local
+   eno1 IPv4 aep@aep-haswell _pulse-server._tcp   local
+   eno1 IPv6 aep@aep-haswell: HD Webcam C910 Analog Stereo
_pulse-source._tcp   local
+   eno1 IPv6 aep@aep-haswell: Built-in Audio Analog Stereo
_pulse-source._tcp   local
+   eno1 IPv4 aep@aep-haswell: HD Webcam C910 Analog Stereo
_pulse-source._tcp   local
+   eno1 IPv4 aep@aep-haswell: Built-in Audio Analog Stereo
_pulse-source._tcp   local
+   eno1 IPv6 aep-haswell   _ssh._tcp
  local
+   eno1 IPv4 aep-haswell   _ssh._tcp
  local
+   eno1 IPv6 aep-haswell [94:de:80:6f:9a:d4] _workstation._tcplocal
+   eno1 IPv4 aep-haswell [94:de:80:6f:9a:d4] _workstation._tcplocal
+   eno1 IPv6 aep-haswell _sftp-ssh._tcp   local
+   eno1 IPv4 aep-haswell _sftp-ssh._tcp   local
+   eno1 IPv6 5CF8A18FB95B@Android _airfoilspeaker._tcp local
+   eno1 IPv6 5CF8A18FB95B@Android (2) _airfoilspeaker._tcp local
+   eno1 IPv4 5CF8A18FB95B@Android _airfoilspeaker._tcp local
-   eno1 IPv4 5CF8A18FB95B@Android _airfoilspeaker._tcp local
-   eno1 IPv6 5CF8A18FB95B@Android _airfoilspeaker._tcp local
+   eno1 IPv4 5CF8A18FB95B@Android _airfoilspeaker._tcp local
+   eno1 IPv6 5CF8A18FB95B@Android _airfoilspeaker._tcp local

The relevant part of the pulseaudio log is:

D: [raop-sink-[192.168.1.39]:5000] raop-client.c: Can't stream,
connection not established yet...
D: [raop-sink-[192.168.1.39]:5000] raop-client.c: Can't stream,
connection not established yet...
D: [raop-sink-[192.168.1.39]:5000] raop-client.c: Can't stream,
connection not established yet...
D: [raop-sink-[192.168.1.39]:5000] raop-client.c: Can't stream,
connection not established yet...
D: [pulseaudio] socket-client.c: connect(): Connection refused
E: [pulseaudio] rtsp_client.c: Connection failed: Connection refused

So - it is not on port 5000. This connects and pretends to send audio:

pacmd load-module module-raop-sink 'server=[192.168.1.39]:6000'
sink_name=raop_output.Airfoil.local

Re: [pulseaudio-discuss] only ALAC! [Was: raop on gentoo+systemd]

2014-11-11 Thread Hajime Fujita

Hi,

Probably you should supply more arguments to module-raop-sink.

Here's a line from my log:
(   0.210|   0.000) I: [lt-pulseaudio] module.c: Loaded 
module-raop-sink (index: #28; argument: server=[192.168.1.130]:5000 
sink_name=raop_output.Apple-TV.local 
sink_properties='device.description=Apple TV (192.168.1.130:5000)' 
protocol=UDP encryption=none codec=ALAC


So at least you'll need codec=ALAC, as well as other ones, maybe.


Best,
Hajime

SGT. Garcia wrote:

trying with a WAV file: https://gist.github.com/450b00f7fc91bbd1ad49

still nu luck.
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss



___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] incomplete IPv6 support in pa_socket_client_new_string()

2014-11-08 Thread Hajime Fujita

Tanu Kaskinen wrote:

On Thu, 2014-11-06 at 22:26 -0600, Hajime Fujita wrote:

Tanu Kaskinen wrote:

On Wed, 2014-11-05 at 22:29 -0600, Hajime Fujita wrote:

Hi Tanu,

Thank you for your comment and sorry for the late reply.

Tanu Kaskinen wrote:

On Tue, 2014-10-21 at 00:49 -0500, Hajime Fujita wrote:

Hello,

I'm currently working on IPv6 support for the raop module [1].

During the work I found a potential issue in
pa_socket_client_new_string() (in pulsecore/socket-client.c) as pointed
out in [1].

It does not work as expected when an IPv6 address string like
2001:db8::1 is passed as the name parameter. This is because the
name parameter is passed to pa_parse_address(), which thinks the last
colon as a separator between hostname (or address) and a port number. To
prevent pa_parse_address() from doing this, an IPv6 address must be
bracketed with [] (e.g. [2001:db8::1]).

I'm wondering what would be the best solution for this situation.
a. Modify callers: callers of pa_socket_client_new_string() must add
brackets to IPv6 addresses.
b. Modify pa_socket_client_new_string(): if an IPv6 address is given as
the name parameter, it will be bracketed before being passed to
pa_parse_address().

Any opinions or suggestions?


I think it makes more sense to fix this in the callers of
pa_socket_client_new_string(). It would be good to also add a comment in
socket-client.h saying that the name parameter can include also the port
using the usual syntax, and for that reason IPv6 addresses must be
enclosed in brackets.



Do you have any justification behind this?


Yes, sorry for leaving it out from my answer. The justification: I think
you can't actually implement suggestion b, because there's no way you
can figure out in pa_socket_client_new_string() whether
1234::1234:1234 contains only an IP address or an IP address and a
port.


Well my justification for option b was:
if the caller wants to pass addr:port style string to
pa_socket_client_new_string(), addr must be surrounded by brackets for
the very reason you described.
So, if pa_socket_client_new_string() sees a string like
1234::1234:1234, I thought it would be safe to interpret it as an IPv6
address alone, not including port.


Ok, now I understand (and looking back, I feel I should have understood
already from the first mail...). I think pa_parse_address() should be
changed so that 1234::1234:1234 is parsed as an IP address, not IP
address + port. That way the problem is fixed for all callers of
pa_parse_address(), not only for pa_socket_client_new_string().



Thanks, this makes sense. I'll send a patch for this.


Best,
Hajime

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] Support IPv6 address in pa_socket_client_new_string()

2014-11-08 Thread Hajime Fujita
These patches address an issue that pa_socket_client_new_string()
cannot handle IPv6 address correctly [1].

[1]: http://lists.freedesktop.org/archives/pulseaudio-discuss/2014-October/0
22010.html

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH 1/2] parseaddr: Add new call pa_is_ip6_address()

2014-11-08 Thread Hajime Fujita
---
 src/pulsecore/parseaddr.c | 11 +++
 src/pulsecore/parseaddr.h |  2 ++
 2 files changed, 13 insertions(+)

diff --git a/src/pulsecore/parseaddr.c b/src/pulsecore/parseaddr.c
index d31e68c..f49c81c 100644
--- a/src/pulsecore/parseaddr.c
+++ b/src/pulsecore/parseaddr.c
@@ -145,3 +145,14 @@ bool pa_is_ip_address(const char *a) {
 
 return false;
 }
+
+bool pa_is_ip6_address(const char *a) {
+char buf[INET6_ADDRSTRLEN];
+
+pa_assert(a);
+
+if (inet_pton(AF_INET6, a, buf) = 1)
+return true;
+
+return false;
+}
diff --git a/src/pulsecore/parseaddr.h b/src/pulsecore/parseaddr.h
index 9c9745b..57be7a6 100644
--- a/src/pulsecore/parseaddr.h
+++ b/src/pulsecore/parseaddr.h
@@ -43,4 +43,6 @@ int pa_parse_address(const char *a, pa_parsed_address *ret_p);
 
 bool pa_is_ip_address(const char *a);
 
+bool pa_is_ip6_address(const char *a);
+
 #endif
-- 
1.9.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH 1/2] parseaddr: Add new call pa_is_ip6_address()

2014-11-08 Thread Hajime Fujita
---
 src/pulsecore/parseaddr.c | 11 +++
 src/pulsecore/parseaddr.h |  2 ++
 2 files changed, 13 insertions(+)

diff --git a/src/pulsecore/parseaddr.c b/src/pulsecore/parseaddr.c
index d31e68c..f49c81c 100644
--- a/src/pulsecore/parseaddr.c
+++ b/src/pulsecore/parseaddr.c
@@ -145,3 +145,14 @@ bool pa_is_ip_address(const char *a) {
 
 return false;
 }
+
+bool pa_is_ip6_address(const char *a) {
+char buf[INET6_ADDRSTRLEN];
+
+pa_assert(a);
+
+if (inet_pton(AF_INET6, a, buf) = 1)
+return true;
+
+return false;
+}
diff --git a/src/pulsecore/parseaddr.h b/src/pulsecore/parseaddr.h
index 9c9745b..57be7a6 100644
--- a/src/pulsecore/parseaddr.h
+++ b/src/pulsecore/parseaddr.h
@@ -43,4 +43,6 @@ int pa_parse_address(const char *a, pa_parsed_address *ret_p);
 
 bool pa_is_ip_address(const char *a);
 
+bool pa_is_ip6_address(const char *a);
+
 #endif
-- 
1.9.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] [PATCH] Support IPv6 address in pa_socket_client_new_string()

2014-11-08 Thread Hajime Fujita
pa_socket_client_new_string() did not work as expected when an IPv6
address string like 2001:db8::1 is passed as the name parameter.
This is because the name parameter is then passed to pa_parse_address(),
which thinks the last colon as a separator between hostname (or address)
and a port number. To prevent pa_parse_address() from doing this, an IPv6
address must be bracketed with [] (e.g. [2001:db8::1]). [1]

This patch fixes pa_socket_client_new_string() so that it internally
adds brackets to an IPv6 address. This decision is based on a
discussion at [2].

[1]: 
http://lists.freedesktop.org/archives/pulseaudio-discuss/2014-October/022010.html
[2]: 
http://lists.freedesktop.org/archives/pulseaudio-discuss/2014-November/022401.html
---
 src/pulsecore/socket-client.c | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/pulsecore/socket-client.c b/src/pulsecore/socket-client.c
index 564a366..a784833 100644
--- a/src/pulsecore/socket-client.c
+++ b/src/pulsecore/socket-client.c
@@ -430,12 +430,28 @@ static void start_timeout(pa_socket_client *c, bool 
use_rtclock) {
 pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, bool 
use_rtclock, const char*name, uint16_t default_port) {
 pa_socket_client *c = NULL;
 pa_parsed_address a;
+char *name_buf;
 
 pa_assert(m);
 pa_assert(name);
 
-if (pa_parse_address(name, a)  0)
-return NULL;
+a.path_or_host = NULL;
+
+if (pa_is_ip6_address(name)) {
+size_t len = strlen(name);
+name_buf = pa_xmalloc(len + 3);
+memcpy(name_buf + 1, name, len);
+name_buf[0] = '[';
+name_buf[len + 1] = ']';
+name_buf[len + 2] = '\0';
+} else {
+name_buf = pa_xstrdup(name);
+}
+
+if (pa_parse_address(name_buf, a)  0) {
+pa_log_warn(parsing address failed: %s, name_buf);
+goto finish;
+}
 
 if (!a.port)
 a.port = default_port;
@@ -532,6 +548,7 @@ pa_socket_client* 
pa_socket_client_new_string(pa_mainloop_api *m, bool use_rtclo
 }
 
 finish:
+pa_xfree(name_buf);
 pa_xfree(a.path_or_host);
 return c;
 
-- 
1.9.1

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Support IPv6 address in pa_socket_client_new_string()

2014-11-08 Thread Hajime Fujita

Sorry, git send-email did not work well for some reason...

I wanted to submit these two patches in the following order.
[PATCH 1/2] parseaddr: Add new call pa_is_ip6_address()
[PATCH] Support IPv6 address in pa_socket_client_new_string()


Thanks,
Hajime

Hajime Fujita wrote:

These patches address an issue that pa_socket_client_new_string()
cannot handle IPv6 address correctly [1].

[1]: http://lists.freedesktop.org/archives/pulseaudio-discuss/2014-October/0
22010.html

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss



___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] incomplete IPv6 support in pa_socket_client_new_string()

2014-11-06 Thread Hajime Fujita

Tanu Kaskinen wrote:

On Wed, 2014-11-05 at 22:29 -0600, Hajime Fujita wrote:

Hi Tanu,

Thank you for your comment and sorry for the late reply.

Tanu Kaskinen wrote:

On Tue, 2014-10-21 at 00:49 -0500, Hajime Fujita wrote:

Hello,

I'm currently working on IPv6 support for the raop module [1].

During the work I found a potential issue in
pa_socket_client_new_string() (in pulsecore/socket-client.c) as pointed
out in [1].

It does not work as expected when an IPv6 address string like
2001:db8::1 is passed as the name parameter. This is because the
name parameter is passed to pa_parse_address(), which thinks the last
colon as a separator between hostname (or address) and a port number. To
prevent pa_parse_address() from doing this, an IPv6 address must be
bracketed with [] (e.g. [2001:db8::1]).

I'm wondering what would be the best solution for this situation.
a. Modify callers: callers of pa_socket_client_new_string() must add
brackets to IPv6 addresses.
b. Modify pa_socket_client_new_string(): if an IPv6 address is given as
the name parameter, it will be bracketed before being passed to
pa_parse_address().

Any opinions or suggestions?


I think it makes more sense to fix this in the callers of
pa_socket_client_new_string(). It would be good to also add a comment in
socket-client.h saying that the name parameter can include also the port
using the usual syntax, and for that reason IPv6 addresses must be
enclosed in brackets.



Do you have any justification behind this?


Yes, sorry for leaving it out from my answer. The justification: I think
you can't actually implement suggestion b, because there's no way you
can figure out in pa_socket_client_new_string() whether
1234::1234:1234 contains only an IP address or an IP address and a
port.


Well my justification for option b was:
if the caller wants to pass addr:port style string to 
pa_socket_client_new_string(), addr must be surrounded by brackets for 
the very reason you described.
So, if pa_socket_client_new_string() sees a string like 
1234::1234:1234, I thought it would be safe to interpret it as an IPv6 
address alone, not including port.



Thanks,
Hajime

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] incomplete IPv6 support in pa_socket_client_new_string()

2014-11-05 Thread Hajime Fujita

Hi Tanu,

Thank you for your comment and sorry for the late reply.

Tanu Kaskinen wrote:

On Tue, 2014-10-21 at 00:49 -0500, Hajime Fujita wrote:

Hello,

I'm currently working on IPv6 support for the raop module [1].

During the work I found a potential issue in
pa_socket_client_new_string() (in pulsecore/socket-client.c) as pointed
out in [1].

It does not work as expected when an IPv6 address string like
2001:db8::1 is passed as the name parameter. This is because the
name parameter is passed to pa_parse_address(), which thinks the last
colon as a separator between hostname (or address) and a port number. To
prevent pa_parse_address() from doing this, an IPv6 address must be
bracketed with [] (e.g. [2001:db8::1]).

I'm wondering what would be the best solution for this situation.
a. Modify callers: callers of pa_socket_client_new_string() must add
brackets to IPv6 addresses.
b. Modify pa_socket_client_new_string(): if an IPv6 address is given as
the name parameter, it will be bracketed before being passed to
pa_parse_address().

Any opinions or suggestions?


I think it makes more sense to fix this in the callers of
pa_socket_client_new_string(). It would be good to also add a comment in
socket-client.h saying that the name parameter can include also the port
using the usual syntax, and for that reason IPv6 addresses must be
enclosed in brackets.



Do you have any justification behind this?


Thanks,
Hajime

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] raop no sound

2014-01-12 Thread Hajime Fujita
Hmm, you are right. Your device seems to understand the TCP version. I
suppose the current stable pulseaudio should support your device.
Unfortunately I don't have any experience with TCP version of the
protocol, so I don't have a clue at this moment.

A few things that came up to my mind...
- usually module-raop-discover will automatically find the device, so
you don't have to manually load module-raop-sink. Have you installed
some additional modules like pulseaudio-zeroconf or something?
- If you have paprefs command in your system, launch it and enable
Airtunes from the GUI interface there.
- Attaching a log would help us understanding the issue more precisely.


Thanks,
Hajime

haman...@t-online.de wrote:
 
 Hi Wolfgang,

 What Airport device are you using?

 Perhaps your device only supports raop2 protocol, which is not supported
 by the latest stable pulseaudio.

 I and some collaborators are now working on raop2 support. You may find
 this interesting.
 http://hfujita.github.io/pulseaudio-raop2/


 Thanks,
 Hajime

 
 Hi Hajime,
 
 this is beginning of talk - I would believe it is understanding but I wanted 
 to figure out
 first.. At least it seems to accept the TCP suggestion (and it is taking in 
 data
 via tcp)
 
 ANNOUNCE rtsp://192.168.2.20/322896 RTSP/1.0
 CSeq: 1
 Content-Type: application/sdp
 Content-Length: 571
 User-Agent: iTunes/4.6 (Macintosh; U; PPC Mac OS X 10.3)
 Client-Instance: 
 Apple-Challenge: .
 
 v=0
 o=iTunes 322896 IN INP4 192.168.2.20
 s=iTunes
 c=IN IP4 192.168.2.31
 t=0 0
 m=audio 0 RTP/AVP 96
 a=rtpmap:96 Apple Lossless
 a=fmtp:96 4096 0 16 40 10 14 2 255 0 0 44100
 a=rsaaeskey:H4.
 a=aesiv:
 
 RTSP/1.0 200 OK
 Server: AirTunes/105.1
 CSeq:1
 
 SETUP rtsp://192.168.2.20/322896 RTSP/1.0
 CSeq: 2
 Transport: RTP/AVP/TCP;unicast;interleaved=0-1;mode=record
 User-Agent: iTunes/4.6 (Macintosh; U; PPC Mac OS X 10.3)
 Client-Instance: 
 
 RTSP/1.0 200 OK
 Transport: RTP/AVP/TCP;unicast;mode=record;server_port=6000
 Session: 1
 Audio-Jack-Status: connteced; type=analog
 Server: AirTunes/105.1
 CSeq: 2
 
 
 ___
 pulseaudio-discuss mailing list
 pulseaudio-discuss@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
 

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH 00/25] raop2 support for module-raop-sink

2013-12-07 Thread Hajime Fujita
Hi Tanu and Martin,

Sorry for the late reply.

I just pushed a new series of patches to raop2-for-merge2 branch.
https://github.com/hfujita/pulseaudio-raop2/commits/raop2-for-merge2
Nothing has really been changed from raop2-for-merge1. It's just for
rebasing and cleaning up some unused patches.

Perhaps it would be better for Martin to rebase your new patches onto
this branch before reviewing. If these patches are kind of trivial, I
can merge them if you send them to me. (However the refactoring patch
sounds non-trivial for me...)


Thanks,
Hajime

Martin Blanchard wrote:
 Hello Tanu,
 
 On jeu., 2013-12-05 at 11:29 +0200, Tanu Kaskinen wrote:
 On Sat, 2013-09-07 at 11:34 -0500, Hajime Fujita wrote:
 This patch set adds a support for UDP version of RAOP (so called
 raop2). Most of the RAOP devices (e.g. AppleTV, AirportExpress,
 third party AV receivers) today use UDP version, so this patch
 set is expected to support those devices.

 While there are still some remaining issues, and testing has not
 been done thoroughly, we'd like to have a review so that we can
 discuss some design/style issues as early as possible.

 This patch set is now the oldest one in our queue, so I plan to start
 reviewing it soon. Has the RAOP work moved on after these patches were
 submitted? If so, could you send an updated patch set?

 
 The work we are doing on the RAOP module is on github, in a repo managed
 by Hajime [1]. And yes, the code did move on after the patches send
 here... 
 
 Moreover, there are a few commits that I haven't submitted yet to
 Hajime. Basically it brings an implementation for password
 authentication, plus a large re-factoring that aims at merging old TCP
 code path into the new UDP version. As of now, there are quiet some
 duplication between the two implementations.
 
 I don't know if Hajime has time to build a new set of patches. On my
 side, I need a few more weeks to finish re-factoring and testing the TCP
 code. So it's probably better to wait for a new version I guess, or, at
 least, for Hajime opinion on that. Anyway, thanks for the interest in
 our work !
 
 [1] https://github.com/hfujita/pulseaudio-raop2/commits/raop2-for-merge1
 
 Martin
 
 
 
 ___
 pulseaudio-discuss mailing list
 pulseaudio-discuss@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
 



___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] How to control playback start timing (RAOP)

2013-10-17 Thread Hajime Fujita
Hi Tanu,

Thank you for the message.

Tanu Kaskinen wrote:
 On Wed, 2013-10-16 at 22:04 -0500, Hajime Fujita wrote:
 Hi,

 I've been working on raop2 support for the raop module.

 Currently when starting playback through RAOP, there is a huge delay in
 sound. 2-3 sec after starting music from a player software, actual sound
 starts being heard from the speaker.
 And as a result, there is a gap between a screen and sound. For example,
 progress counter of a player software shows 00:03 when the actual
 music begins. This would be a serious issue when playing movie.

 I'm wondering how I can solve this issue. I think most of the delay is
 due to protocol initialization and impossible to reduce. So the feasible
 approach might be to tell the application that playback is not yet ready.

 Is there any document or existing module from which I can learn some
 idea to address this issue?
 
 If you want lip-sync with movies, you only need to provide accurate
 latency information in your sink implementation. The latency reporting
 is done by handling the PA_SINK_MESSAGE_GET_LATENCY message. It seems
 that module-raop-sink.c (the version in upstream) already tries pretty
 hard to estimate the latency accurately. I think the logic depends on
 TCP's flow control, though, and if I recall correctly, you were working
 on UDP support. Does the RAOP protocol have any latency reporting
 functionality? If not, then you can only guess what the real latency is.

That's right. RAOP2 is using UDP and the current technique in upstream
does not seem to work. I'm not sure if there is an explicit latency
notification in RAOP2 protocol[1], but I think I can somehow estimate
the timing using several timing packets and so on.

Before figuring out how to estimate the accurate latency, I tried to
return a large (~2-3 sec) latency upon PA_SINK_MESSAGE_GET_LATENCY
message to see what happens.
(BTW, the handler is supposed to return microseconds, right?)

It seems that timing gap between pictures and sound gets better in
general, but I experienced a few issues.

1. I got several Implicit underrun once in about every 15s.

(  78.834|   1.289) D: [raop-sink] protocol-native.c: Implicit underrun
of 'audio stream'
(  78.835|   0.001) D: [raop-sink] protocol-native.c: Requesting rewind
due to rewrite.
(  78.835|   0.000) D: [raop-sink] sink-input.c: Requesting rewind due
to corking
(  78.836|   0.000) D: [raop-sink] module-raop-sink.c: RAOP: IDLE

The last line RAOP: IDLE means that the sink module got PA_SINK_IDLE
message.
When I get this message, there's an interruption in sound.

2. There's still a huge timing gap right after starting playback. Once I
get an interruption which I mentioned above, the gap seems to be reduced.

Any ideas, or suggestions?


[1]: There's a header named Audio-Latency in some response, but
apparently it's not working or at least we don't know how to interpret
the number correctly.


Thanks,
Hajime

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


[pulseaudio-discuss] How to control playback start timing (RAOP)

2013-10-16 Thread Hajime Fujita
Hi,

I've been working on raop2 support for the raop module.

Currently when starting playback through RAOP, there is a huge delay in
sound. 2-3 sec after starting music from a player software, actual sound
starts being heard from the speaker.
And as a result, there is a gap between a screen and sound. For example,
progress counter of a player software shows 00:03 when the actual
music begins. This would be a serious issue when playing movie.

I'm wondering how I can solve this issue. I think most of the delay is
due to protocol initialization and impossible to reduce. So the feasible
approach might be to tell the application that playback is not yet ready.

Is there any document or existing module from which I can learn some
idea to address this issue?


Thank you,
Hajime
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] An raop2 support

2013-09-20 Thread Hajime Fujita
Hi Tanu,

Tanu Kaskinen wrote:
 On Wed, 2013-09-18 at 23:09 -0500, Hajime Fujita wrote:
 Hi Tanu,

 Thank you so much for your advice.

 Tanu Kaskinen wrote:
 On Sun, 2013-09-15 at 00:24 -0500, Hajime Fujita wrote:
 For those who are interested in raop2 experiments,

 As Matthias pointed out [1], current volume calculation is incorrect.
 https://bugs.freedesktop.org/show_bug.cgi?id=42804#c43

 I have uploaded a patch which calculates volume in more reasonable way.
 https://github.com/hfujita/pulseaudio-raop2/commit/69f3ce883dfb93eb7b24f98b9664e14071672475

 First I have to confess that this is the first time for me to deal with
 the unit 'dB', so maybe I'm doing totally stupid. I'd be very happy if I
 could have any suggestions from who is more experienced in this field.

 I started looking at pa_raop_client_set_volume() in
 src/modules/raop/raop_client.c. It was using pa_sw_volume_to_dB to
 calculate dB from a linear scale.

 Correction: pa_volume_t doesn't use a linear scale, it uses a cubic
 scale (see pa_sw_volume_from_linear() and pa_sw_volume_to_linear()).

 I see. I should have noticed some comments about cubic scale.
 http://cgit.freedesktop.org/pulseaudio/pulseaudio/tree/src/pulse/volume.c#n251


 Then I learned from code reading that pa_sw_volume_to_dB essentially
 calculates the following:
   20 * log10((v/MAXVOLUME)^3) = 60 * log10(v/MAXVOLUME)
 This does not fit into the volume scale which RAOP is expecting, where
 -30.0 db is a kind of minimum [2].

 [2]: http://git.zx2c4.com/Airtunes2/about/#id29

 Also I looked at packet dumps from iPad and guessed how it calculated dB
 from a linear scale. It looked like iPad was using the following formula.
   db = 10 * log10(volume/MAXVOLUME/30)
 So for the time being I decided to follow this way.

 The way to convert pa_volume_t to dB is to use pa_sw_volume_to_dB().
 Doing anything else means that the result is not dB, it's something
 different.

 The way to handle this is to ensure that the volume that is given to
 pa_raop_client_set_volume() is never outside the supported range. In
 module-raop-sink.c there's sink_set_volume_cb(), which calls
 pa_raop_client_set_volume(). In sink_set_volume_cb() there's this line:

 pa_cvolume_set(hw, s-sample_spec.channels, v);

 Before that line you should check what dB value v corresponds to, and if
 it's outside the supported range, then you should modify v to fall into
 the supported range. Any modification that you make to v will be
 compensated with software volume, so the modifications shouldn't affect
 the resulting volume at all, assuming that the RAOP device actually
 attenuates the signal by the dB amount that you send to it.


 According to your advice, I inserted an adjustment to v before
 pa_cvolume_set. Here's the patch.
 https://github.com/hfujita/pulseaudio-raop2/commit/c6337c0fef7710ee20b42ed3fb87ec12910ce35a

 Adjustment goes like this (pa_raop_client_adjust_volume()):
   adj(v) = v * (1 - minv/maxv) + minv;
 where pa_sw_volume_to_dB(minv) = -30.0,
 and pa_sw_volume_to_dB(maxv) = 0.0

 The idea is that when the original v is 0, adj(0) = minv. And when the
 original v is maxv, adj(maxv) = maxv;

 Does this make sense?
 
 The idea was to simply adjust v to -30 dB if the original v is less than
 that. There's no need to do any complicated calculations.

Do you mean something like
  v = max(minv, v); /* where minv corresponds to -30.0dB */ ?

If I do that, resulted volume will be almost muted in the range of 0% =
v = 31%, then suddenly goes up beyond 31%. (31% is where dB becomes -30.0)
I was afraid that this was not an intuitive behavior to users.

 As you noted, this also affects the software volume, and in my
 environment, the actual volume (volume heard from the speaker) may be
 way too small.
 
 What do you mean by way too small? The maximum volume will be the same
 as before, but the minimum volume will be quieter than before. With the
 original code you complained that you need to keep the volume at rather
 low levels, so extending the scale towards low volumes should help with
 this.

Well, this could be just my personal feeling. Since it was a bit loud
before (however it was almost the same volume level as iPad), this time
I felt it was way too small.

I wonder if it makes sense to 1) adjust v as
  adj(v) = v * (1 - minv/maxv) + minv;
and 2) use the original v for pa_cvolume_set(), then 3) use adj(v) for
setting the actual RAOP device volume.
Under this condition, the calculated software volume always becomes
100%, as in the current (mainline) raop module.


Thanks,
Hajime

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


  1   2   >