2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
33 #include <pulse/sample.h>
34 #include <pulse/timeval.h>
35 #include <pulse/utf8.h>
36 #include <pulse/xmalloc.h>
37 #include <pulse/proplist.h>
39 #include <pulsecore/esound.h>
40 #include <pulsecore/memblock.h>
41 #include <pulsecore/client.h>
42 #include <pulsecore/sink-input.h>
43 #include <pulsecore/sink.h>
44 #include <pulsecore/source-output.h>
45 #include <pulsecore/source.h>
46 #include <pulsecore/core-scache.h>
47 #include <pulsecore/sample-util.h>
48 #include <pulsecore/authkey.h>
49 #include <pulsecore/namereg.h>
50 #include <pulsecore/log.h>
51 #include <pulsecore/core-util.h>
52 #include <pulsecore/core-error.h>
53 #include <pulsecore/ipacl.h>
54 #include <pulsecore/macro.h>
55 #include <pulsecore/thread-mq.h>
56 #include <pulsecore/shared.h>
58 #include "endianmacros.h"
60 #include "protocol-esound.h"
62 /* Don't accept more connection than this */
63 #define MAX_CONNECTIONS 64
65 /* Kick a client if it doesn't authenticate within this time */
66 #define AUTH_TIMEOUT 5
68 #define DEFAULT_COOKIE_FILE ".esd_auth"
70 #define PLAYBACK_BUFFER_SECONDS (.25)
71 #define PLAYBACK_BUFFER_FRAGMENTS (10)
72 #define RECORD_BUFFER_SECONDS (5)
74 #define MAX_CACHE_SAMPLE_SIZE (2048000)
76 #define DEFAULT_SINK_LATENCY (150*PA_USEC_PER_MSEC)
77 #define DEFAULT_SOURCE_LATENCY (150*PA_USEC_PER_MSEC)
79 #define SCACHE_PREFIX "esound."
81 /* This is heavily based on esound's code */
83 typedef struct connection
{
88 pa_esound_protocol
*protocol
;
89 pa_esound_options
*options
;
92 pa_bool_t authorized
, swap_byte_order
;
94 size_t write_data_alloc
, write_data_index
, write_data_length
;
96 size_t read_data_alloc
, read_data_length
;
98 esd_client_state_t state
;
99 pa_sink_input
*sink_input
;
100 pa_source_output
*source_output
;
101 pa_memblockq
*input_memblockq
, *output_memblockq
;
102 pa_defer_event
*defer_event
;
107 pa_memblock
*current_memblock
;
108 size_t memblock_index
;
114 pa_memchunk memchunk
;
116 pa_sample_spec sample_spec
;
119 pa_time_event
*auth_timeout_event
;
122 PA_DECLARE_CLASS(connection
);
123 #define CONNECTION(o) (connection_cast(o))
124 static PA_DEFINE_CHECK_TYPE(connection
, pa_msgobject
);
126 struct pa_esound_protocol
{
130 pa_idxset
*connections
;
135 SINK_INPUT_MESSAGE_POST_DATA
= PA_SINK_INPUT_MESSAGE_MAX
, /* data from main loop to sink input */
136 SINK_INPUT_MESSAGE_DISABLE_PREBUF
140 CONNECTION_MESSAGE_REQUEST_DATA
,
141 CONNECTION_MESSAGE_POST_DATA
,
142 CONNECTION_MESSAGE_UNLINK_CONNECTION
145 typedef struct proto_handler
{
147 int (*proc
)(connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
148 const char *description
;
149 } esd_proto_handler_info_t
;
151 static int sink_input_pop_cb(pa_sink_input
*i
, size_t length
, pa_memchunk
*chunk
);
152 static void sink_input_process_rewind_cb(pa_sink_input
*i
, size_t nbytes
);
153 static void sink_input_update_max_rewind_cb(pa_sink_input
*i
, size_t nbytes
);
154 static void sink_input_kill_cb(pa_sink_input
*i
);
155 static int sink_input_process_msg(pa_msgobject
*o
, int code
, void *userdata
, int64_t offset
, pa_memchunk
*chunk
);
156 static pa_usec_t
source_output_get_latency_cb(pa_source_output
*o
);
158 static void source_output_push_cb(pa_source_output
*o
, const pa_memchunk
*chunk
);
159 static void source_output_kill_cb(pa_source_output
*o
);
161 static int esd_proto_connect(connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
162 static int esd_proto_stream_play(connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
163 static int esd_proto_stream_record(connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
164 static int esd_proto_get_latency(connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
165 static int esd_proto_server_info(connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
166 static int esd_proto_all_info(connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
167 static int esd_proto_stream_pan(connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
168 static int esd_proto_sample_pan(connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
169 static int esd_proto_sample_cache(connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
170 static int esd_proto_sample_free_or_play(connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
171 static int esd_proto_sample_get_id(connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
172 static int esd_proto_standby_or_resume(connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
173 static int esd_proto_standby_mode(connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
175 /* the big map of protocol handler info */
176 static struct proto_handler proto_map
[ESD_PROTO_MAX
] = {
177 { ESD_KEY_LEN
+ sizeof(int), esd_proto_connect
, "connect" },
178 { ESD_KEY_LEN
+ sizeof(int), NULL
, "lock" },
179 { ESD_KEY_LEN
+ sizeof(int), NULL
, "unlock" },
181 { ESD_NAME_MAX
+ 2 * sizeof(int), esd_proto_stream_play
, "stream play" },
182 { ESD_NAME_MAX
+ 2 * sizeof(int), esd_proto_stream_record
, "stream rec" },
183 { ESD_NAME_MAX
+ 2 * sizeof(int), esd_proto_stream_record
, "stream mon" },
185 { ESD_NAME_MAX
+ 3 * sizeof(int), esd_proto_sample_cache
, "sample cache" }, /* 6 */
186 { sizeof(int), esd_proto_sample_free_or_play
, "sample free" },
187 { sizeof(int), esd_proto_sample_free_or_play
, "sample play" }, /* 8 */
188 { sizeof(int), NULL
, "sample loop" },
189 { sizeof(int), NULL
, "sample stop" },
190 { (size_t) -1, NULL
, "TODO: sample kill" },
192 { ESD_KEY_LEN
+ sizeof(int), esd_proto_standby_or_resume
, "standby" },
193 { ESD_KEY_LEN
+ sizeof(int), esd_proto_standby_or_resume
, "resume" }, /* 13 */
195 { ESD_NAME_MAX
, esd_proto_sample_get_id
, "sample getid" }, /* 14 */
196 { ESD_NAME_MAX
+ 2 * sizeof(int), NULL
, "stream filter" },
198 { sizeof(int), esd_proto_server_info
, "server info" },
199 { sizeof(int), esd_proto_all_info
, "all info" },
200 { (size_t) -1, NULL
, "TODO: subscribe" },
201 { (size_t) -1, NULL
, "TODO: unsubscribe" },
203 { 3 * sizeof(int), esd_proto_stream_pan
, "stream pan"},
204 { 3 * sizeof(int), esd_proto_sample_pan
, "sample pan" },
206 { sizeof(int), esd_proto_standby_mode
, "standby mode" },
207 { 0, esd_proto_get_latency
, "get latency" }
210 static void connection_unlink(connection
*c
) {
217 pa_esound_options_unref(c
->options
);
222 pa_sink_input_unlink(c
->sink_input
);
223 pa_sink_input_unref(c
->sink_input
);
224 c
->sink_input
= NULL
;
227 if (c
->source_output
) {
228 pa_source_output_unlink(c
->source_output
);
229 pa_source_output_unref(c
->source_output
);
230 c
->source_output
= NULL
;
234 pa_client_free(c
->client
);
238 if (c
->state
== ESD_STREAMING_DATA
)
239 c
->protocol
->n_player
--;
242 pa_iochannel_free(c
->io
);
246 if (c
->defer_event
) {
247 c
->protocol
->core
->mainloop
->defer_free(c
->defer_event
);
248 c
->defer_event
= NULL
;
251 if (c
->auth_timeout_event
) {
252 c
->protocol
->core
->mainloop
->time_free(c
->auth_timeout_event
);
253 c
->auth_timeout_event
= NULL
;
256 pa_assert_se(pa_idxset_remove_by_data(c
->protocol
->connections
, c
, NULL
) == c
);
261 static void connection_free(pa_object
*obj
) {
262 connection
*c
= CONNECTION(obj
);
265 if (c
->input_memblockq
)
266 pa_memblockq_free(c
->input_memblockq
);
267 if (c
->output_memblockq
)
268 pa_memblockq_free(c
->output_memblockq
);
270 if (c
->playback
.current_memblock
)
271 pa_memblock_unref(c
->playback
.current_memblock
);
273 pa_xfree(c
->read_data
);
274 pa_xfree(c
->write_data
);
276 if (c
->scache
.memchunk
.memblock
)
277 pa_memblock_unref(c
->scache
.memchunk
.memblock
);
278 pa_xfree(c
->scache
.name
);
280 pa_xfree(c
->original_name
);
284 static void connection_write_prepare(connection
*c
, size_t length
) {
288 t
= c
->write_data_length
+length
;
290 if (c
->write_data_alloc
< t
)
291 c
->write_data
= pa_xrealloc(c
->write_data
, c
->write_data_alloc
= t
);
293 pa_assert(c
->write_data
);
296 static void connection_write(connection
*c
, const void *data
, size_t length
) {
300 c
->protocol
->core
->mainloop
->defer_enable(c
->defer_event
, 1);
302 connection_write_prepare(c
, length
);
304 pa_assert(c
->write_data
);
306 i
= c
->write_data_length
;
307 c
->write_data_length
+= length
;
309 memcpy((uint8_t*) c
->write_data
+ i
, data
, length
);
312 static void format_esd2native(int format
, pa_bool_t swap_bytes
, pa_sample_spec
*ss
) {
315 ss
->channels
= (uint8_t) (((format
& ESD_MASK_CHAN
) == ESD_STEREO
) ? 2 : 1);
316 if ((format
& ESD_MASK_BITS
) == ESD_BITS16
)
317 ss
->format
= swap_bytes
? PA_SAMPLE_S16RE
: PA_SAMPLE_S16NE
;
319 ss
->format
= PA_SAMPLE_U8
;
322 static int format_native2esd(pa_sample_spec
*ss
) {
325 format
= (ss
->format
== PA_SAMPLE_U8
) ? ESD_BITS8
: ESD_BITS16
;
326 format
|= (ss
->channels
>= 2) ? ESD_STEREO
: ESD_MONO
;
331 #define CHECK_VALIDITY(expression, ...) do { \
332 if (!(expression)) { \
333 pa_log_warn(__FILE__ ": " __VA_ARGS__); \
338 /*** esound commands ***/
340 static int esd_proto_connect(connection
*c
, esd_proto_t request
, const void *data
, size_t length
) {
344 connection_assert_ref(c
);
346 pa_assert(length
== (ESD_KEY_LEN
+ sizeof(uint32_t)));
348 if (!c
->authorized
&& c
->options
->auth_cookie
) {
351 if ((key
= pa_auth_cookie_read(c
->options
->auth_cookie
, ESD_KEY_LEN
)))
352 if (memcmp(data
, key
, ESD_KEY_LEN
) == 0)
353 c
->authorized
= TRUE
;
356 if (!c
->authorized
) {
357 pa_log("Kicked client with invalid authorization key.");
361 if (c
->auth_timeout_event
) {
362 c
->protocol
->core
->mainloop
->time_free(c
->auth_timeout_event
);
363 c
->auth_timeout_event
= NULL
;
366 data
= (const char*)data
+ ESD_KEY_LEN
;
368 memcpy(&ekey
, data
, sizeof(uint32_t));
369 if (ekey
== ESD_ENDIAN_KEY
)
370 c
->swap_byte_order
= FALSE
;
371 else if (ekey
== ESD_SWAP_ENDIAN_KEY
)
372 c
->swap_byte_order
= TRUE
;
374 pa_log_warn("Client sent invalid endian key");
378 pa_proplist_sets(c
->client
->proplist
, "esound.byte_order", c
->swap_byte_order
? "reverse" : "native");
381 connection_write(c
, &ok
, sizeof(int));
385 static int esd_proto_stream_play(connection
*c
, esd_proto_t request
, const void *data
, size_t length
) {
386 char name
[ESD_NAME_MAX
], *utf8_name
;
387 int32_t format
, rate
;
390 pa_sink
*sink
= NULL
;
391 pa_sink_input_new_data sdata
;
393 connection_assert_ref(c
);
395 pa_assert(length
== (sizeof(int32_t)*2+ESD_NAME_MAX
));
397 memcpy(&format
, data
, sizeof(int32_t));
398 format
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, format
);
399 data
= (const char*) data
+ sizeof(int32_t);
401 memcpy(&rate
, data
, sizeof(int32_t));
402 rate
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, rate
);
403 data
= (const char*) data
+ sizeof(int32_t);
405 ss
.rate
= (uint32_t) rate
;
406 format_esd2native(format
, c
->swap_byte_order
, &ss
);
408 CHECK_VALIDITY(pa_sample_spec_valid(&ss
), "Invalid sample specification");
410 if (c
->options
->default_sink
) {
411 sink
= pa_namereg_get(c
->protocol
->core
, c
->options
->default_sink
, PA_NAMEREG_SINK
);
412 CHECK_VALIDITY(sink
, "No such sink: %s", pa_strnull(c
->options
->default_sink
));
415 pa_strlcpy(name
, data
, sizeof(name
));
417 utf8_name
= pa_utf8_filter(name
);
418 pa_client_set_name(c
->client
, utf8_name
);
421 c
->original_name
= pa_xstrdup(name
);
423 pa_assert(!c
->sink_input
&& !c
->input_memblockq
);
425 pa_sink_input_new_data_init(&sdata
);
426 sdata
.driver
= __FILE__
;
427 sdata
.module
= c
->options
->module
;
428 sdata
.client
= c
->client
;
430 pa_sink_input_new_data_set_sample_spec(&sdata
, &ss
);
432 pa_sink_input_new(&c
->sink_input
, c
->protocol
->core
, &sdata
, 0);
433 pa_sink_input_new_data_done(&sdata
);
435 CHECK_VALIDITY(c
->sink_input
, "Failed to create sink input.");
437 l
= (size_t) ((double) pa_bytes_per_second(&ss
)*PLAYBACK_BUFFER_SECONDS
);
438 c
->input_memblockq
= pa_memblockq_new(
444 l
/PLAYBACK_BUFFER_FRAGMENTS
,
447 pa_iochannel_socket_set_rcvbuf(c
->io
, l
);
449 c
->sink_input
->parent
.process_msg
= sink_input_process_msg
;
450 c
->sink_input
->pop
= sink_input_pop_cb
;
451 c
->sink_input
->process_rewind
= sink_input_process_rewind_cb
;
452 c
->sink_input
->update_max_rewind
= sink_input_update_max_rewind_cb
;
453 c
->sink_input
->kill
= sink_input_kill_cb
;
454 c
->sink_input
->userdata
= c
;
456 pa_sink_input_set_requested_latency(c
->sink_input
, DEFAULT_SINK_LATENCY
);
458 c
->state
= ESD_STREAMING_DATA
;
460 c
->protocol
->n_player
++;
462 pa_atomic_store(&c
->playback
.missing
, (int) pa_memblockq_missing(c
->input_memblockq
));
464 pa_sink_input_put(c
->sink_input
);
469 static int esd_proto_stream_record(connection
*c
, esd_proto_t request
, const void *data
, size_t length
) {
470 char name
[ESD_NAME_MAX
], *utf8_name
;
471 int32_t format
, rate
;
472 pa_source
*source
= NULL
;
475 pa_source_output_new_data sdata
;
477 connection_assert_ref(c
);
479 pa_assert(length
== (sizeof(int32_t)*2+ESD_NAME_MAX
));
481 memcpy(&format
, data
, sizeof(int32_t));
482 format
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, format
);
483 data
= (const char*) data
+ sizeof(int32_t);
485 memcpy(&rate
, data
, sizeof(int32_t));
486 rate
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, rate
);
487 data
= (const char*) data
+ sizeof(int32_t);
489 ss
.rate
= (uint32_t) rate
;
490 format_esd2native(format
, c
->swap_byte_order
, &ss
);
492 CHECK_VALIDITY(pa_sample_spec_valid(&ss
), "Invalid sample specification.");
494 if (request
== ESD_PROTO_STREAM_MON
) {
497 sink
= pa_namereg_get(c
->protocol
->core
, c
->options
->default_sink
, PA_NAMEREG_SINK
);
498 CHECK_VALIDITY(sink
, "No such sink: %s", pa_strnull(c
->options
->default_sink
));
500 source
= sink
->monitor_source
;
501 CHECK_VALIDITY(source
, "No such source.");
503 pa_assert(request
== ESD_PROTO_STREAM_REC
);
505 if (c
->options
->default_source
) {
506 source
= pa_namereg_get(c
->protocol
->core
, c
->options
->default_source
, PA_NAMEREG_SOURCE
);
507 CHECK_VALIDITY(source
, "No such source: %s", pa_strnull(c
->options
->default_source
));
511 pa_strlcpy(name
, data
, sizeof(name
));
513 utf8_name
= pa_utf8_filter(name
);
514 pa_client_set_name(c
->client
, utf8_name
);
517 c
->original_name
= pa_xstrdup(name
);
519 pa_assert(!c
->output_memblockq
&& !c
->source_output
);
521 pa_source_output_new_data_init(&sdata
);
522 sdata
.driver
= __FILE__
;
523 sdata
.module
= c
->options
->module
;
524 sdata
.client
= c
->client
;
525 sdata
.source
= source
;
526 pa_source_output_new_data_set_sample_spec(&sdata
, &ss
);
528 pa_source_output_new(&c
->source_output
, c
->protocol
->core
, &sdata
, 0);
529 pa_source_output_new_data_done(&sdata
);
531 CHECK_VALIDITY(c
->source_output
, "Failed to create source output.");
533 l
= (size_t) (pa_bytes_per_second(&ss
)*RECORD_BUFFER_SECONDS
);
534 c
->output_memblockq
= pa_memblockq_new(
543 pa_iochannel_socket_set_sndbuf(c
->io
, l
);
545 c
->source_output
->push
= source_output_push_cb
;
546 c
->source_output
->kill
= source_output_kill_cb
;
547 c
->source_output
->get_latency
= source_output_get_latency_cb
;
548 c
->source_output
->userdata
= c
;
550 pa_source_output_set_requested_latency(c
->source_output
, DEFAULT_SOURCE_LATENCY
);
552 c
->state
= ESD_STREAMING_DATA
;
554 c
->protocol
->n_player
++;
556 pa_source_output_put(c
->source_output
);
561 static int esd_proto_get_latency(connection
*c
, esd_proto_t request
, const void *data
, size_t length
) {
565 connection_assert_ref(c
);
567 pa_assert(length
== 0);
569 if (!(sink
= pa_namereg_get(c
->protocol
->core
, c
->options
->default_sink
, PA_NAMEREG_SINK
)))
572 double usec
= (double) pa_sink_get_requested_latency(sink
);
573 latency
= (int) ((usec
*44100)/1000000);
576 latency
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, latency
);
577 connection_write(c
, &latency
, sizeof(int32_t));
582 static int esd_proto_server_info(connection
*c
, esd_proto_t request
, const void *data
, size_t length
) {
583 int32_t rate
= 44100, format
= ESD_STEREO
|ESD_BITS16
;
587 connection_assert_ref(c
);
589 pa_assert(length
== sizeof(int32_t));
591 if ((sink
= pa_namereg_get(c
->protocol
->core
, c
->options
->default_sink
, PA_NAMEREG_SINK
))) {
592 rate
= (int32_t) sink
->sample_spec
.rate
;
593 format
= format_native2esd(&sink
->sample_spec
);
596 connection_write_prepare(c
, sizeof(int32_t) * 3);
599 connection_write(c
, &response
, sizeof(int32_t));
600 rate
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, rate
);
601 connection_write(c
, &rate
, sizeof(int32_t));
602 format
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, format
);
603 connection_write(c
, &format
, sizeof(int32_t));
608 static int esd_proto_all_info(connection
*c
, esd_proto_t request
, const void *data
, size_t length
) {
611 uint32_t idx
= PA_IDXSET_INVALID
;
613 char terminator
[sizeof(int32_t)*6+ESD_NAME_MAX
];
615 connection_assert_ref(c
);
617 pa_assert(length
== sizeof(int32_t));
619 if (esd_proto_server_info(c
, request
, data
, length
) < 0)
622 k
= sizeof(int32_t)*5+ESD_NAME_MAX
;
623 s
= sizeof(int32_t)*6+ESD_NAME_MAX
;
624 nsamples
= pa_idxset_size(c
->protocol
->core
->scache
);
625 t
= s
*(nsamples
+1) + k
*(c
->protocol
->n_player
+1);
627 connection_write_prepare(c
, t
);
629 memset(terminator
, 0, sizeof(terminator
));
631 for (conn
= pa_idxset_first(c
->protocol
->connections
, &idx
); conn
; conn
= pa_idxset_next(c
->protocol
->connections
, &idx
)) {
632 int32_t id
, format
= ESD_BITS16
| ESD_STEREO
, rate
= 44100, lvolume
= ESD_VOLUME_BASE
, rvolume
= ESD_VOLUME_BASE
;
633 char name
[ESD_NAME_MAX
];
635 if (conn
->state
!= ESD_STREAMING_DATA
)
638 pa_assert(t
>= k
*2+s
);
640 if (conn
->sink_input
) {
641 pa_cvolume volume
= *pa_sink_input_get_volume(conn
->sink_input
);
642 rate
= (int32_t) conn
->sink_input
->sample_spec
.rate
;
643 lvolume
= (int32_t) ((volume
.values
[0]*ESD_VOLUME_BASE
)/PA_VOLUME_NORM
);
644 rvolume
= (int32_t) ((volume
.values
[volume
.channels
== 2 ? 1 : 0]*ESD_VOLUME_BASE
)/PA_VOLUME_NORM
);
645 format
= format_native2esd(&conn
->sink_input
->sample_spec
);
649 id
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, (int32_t) (conn
->index
+1));
650 connection_write(c
, &id
, sizeof(int32_t));
653 memset(name
, 0, ESD_NAME_MAX
); /* don't leak old data */
654 if (conn
->original_name
)
655 strncpy(name
, conn
->original_name
, ESD_NAME_MAX
);
656 else if (conn
->client
&& pa_proplist_gets(conn
->client
->proplist
, PA_PROP_APPLICATION_NAME
))
657 strncpy(name
, pa_proplist_gets(conn
->client
->proplist
, PA_PROP_APPLICATION_NAME
), ESD_NAME_MAX
);
658 connection_write(c
, name
, ESD_NAME_MAX
);
661 rate
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, rate
);
662 connection_write(c
, &rate
, sizeof(int32_t));
665 lvolume
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, lvolume
);
666 connection_write(c
, &lvolume
, sizeof(int32_t));
669 rvolume
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, rvolume
);
670 connection_write(c
, &rvolume
, sizeof(int32_t));
673 format
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, format
);
674 connection_write(c
, &format
, sizeof(int32_t));
679 pa_assert(t
== s
*(nsamples
+1)+k
);
682 connection_write(c
, terminator
, k
);
687 idx
= PA_IDXSET_INVALID
;
688 for (ce
= pa_idxset_first(c
->protocol
->core
->scache
, &idx
); ce
; ce
= pa_idxset_next(c
->protocol
->core
->scache
, &idx
)) {
689 int32_t id
, rate
, lvolume
, rvolume
, format
, len
;
690 char name
[ESD_NAME_MAX
];
691 pa_channel_map stereo
= { .channels
= 2, .map
= { PA_CHANNEL_POSITION_LEFT
, PA_CHANNEL_POSITION_RIGHT
} };
697 if (ce
->volume_is_set
) {
699 pa_cvolume_remap(&volume
, &ce
->channel_map
, &stereo
);
701 pa_cvolume_reset(&volume
, 2);
703 if (ce
->memchunk
.memblock
)
704 ss
= ce
->sample_spec
;
706 ss
.format
= PA_SAMPLE_S16NE
;
712 id
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, (int) (ce
->index
+1));
713 connection_write(c
, &id
, sizeof(int32_t));
716 memset(name
, 0, ESD_NAME_MAX
); /* don't leak old data */
717 if (strncmp(ce
->name
, SCACHE_PREFIX
, sizeof(SCACHE_PREFIX
)-1) == 0)
718 strncpy(name
, ce
->name
+sizeof(SCACHE_PREFIX
)-1, ESD_NAME_MAX
);
720 pa_snprintf(name
, ESD_NAME_MAX
, "native.%s", ce
->name
);
721 connection_write(c
, name
, ESD_NAME_MAX
);
724 rate
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, (int32_t) ss
.rate
);
725 connection_write(c
, &rate
, sizeof(int32_t));
728 lvolume
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, (int32_t) ((volume
.values
[0]*ESD_VOLUME_BASE
)/PA_VOLUME_NORM
));
729 connection_write(c
, &lvolume
, sizeof(int32_t));
732 rvolume
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, (int32_t) ((volume
.values
[1]*ESD_VOLUME_BASE
)/PA_VOLUME_NORM
));
733 connection_write(c
, &rvolume
, sizeof(int32_t));
736 format
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, format_native2esd(&ss
));
737 connection_write(c
, &format
, sizeof(int32_t));
740 len
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, (int) ce
->memchunk
.length
);
741 connection_write(c
, &len
, sizeof(int32_t));
749 connection_write(c
, terminator
, s
);
754 static int esd_proto_stream_pan(connection
*c
, esd_proto_t request
, const void *data
, size_t length
) {
756 uint32_t idx
, lvolume
, rvolume
;
759 connection_assert_ref(c
);
761 pa_assert(length
== sizeof(int32_t)*3);
763 memcpy(&idx
, data
, sizeof(uint32_t));
764 idx
= PA_MAYBE_UINT32_SWAP(c
->swap_byte_order
, idx
) - 1;
765 data
= (const char*)data
+ sizeof(uint32_t);
767 memcpy(&lvolume
, data
, sizeof(uint32_t));
768 lvolume
= PA_MAYBE_UINT32_SWAP(c
->swap_byte_order
, lvolume
);
769 data
= (const char*)data
+ sizeof(uint32_t);
771 memcpy(&rvolume
, data
, sizeof(uint32_t));
772 rvolume
= PA_MAYBE_UINT32_SWAP(c
->swap_byte_order
, rvolume
);
773 data
= (const char*)data
+ sizeof(uint32_t);
775 if ((conn
= pa_idxset_get_by_index(c
->protocol
->connections
, idx
)) && conn
->sink_input
) {
777 volume
.values
[0] = (lvolume
*PA_VOLUME_NORM
)/ESD_VOLUME_BASE
;
778 volume
.values
[1] = (rvolume
*PA_VOLUME_NORM
)/ESD_VOLUME_BASE
;
779 volume
.channels
= conn
->sink_input
->sample_spec
.channels
;
781 pa_sink_input_set_volume(conn
->sink_input
, &volume
, TRUE
);
786 connection_write(c
, &ok
, sizeof(int32_t));
791 static int esd_proto_sample_pan(connection
*c
, esd_proto_t request
, const void *data
, size_t length
) {
793 uint32_t idx
, lvolume
, rvolume
;
797 connection_assert_ref(c
);
799 pa_assert(length
== sizeof(int32_t)*3);
801 memcpy(&idx
, data
, sizeof(uint32_t));
802 idx
= PA_MAYBE_UINT32_SWAP(c
->swap_byte_order
, idx
) - 1;
803 data
= (const char*)data
+ sizeof(uint32_t);
805 memcpy(&lvolume
, data
, sizeof(uint32_t));
806 lvolume
= PA_MAYBE_UINT32_SWAP(c
->swap_byte_order
, lvolume
);
807 data
= (const char*)data
+ sizeof(uint32_t);
809 memcpy(&rvolume
, data
, sizeof(uint32_t));
810 rvolume
= PA_MAYBE_UINT32_SWAP(c
->swap_byte_order
, rvolume
);
811 data
= (const char*)data
+ sizeof(uint32_t);
813 volume
.values
[0] = (lvolume
*PA_VOLUME_NORM
)/ESD_VOLUME_BASE
;
814 volume
.values
[1] = (rvolume
*PA_VOLUME_NORM
)/ESD_VOLUME_BASE
;
817 if ((ce
= pa_idxset_get_by_index(c
->protocol
->core
->scache
, idx
))) {
818 pa_channel_map stereo
= { .channels
= 2, .map
= { PA_CHANNEL_POSITION_LEFT
, PA_CHANNEL_POSITION_RIGHT
} };
820 pa_cvolume_remap(&volume
, &stereo
, &ce
->channel_map
);
822 ce
->volume_is_set
= TRUE
;
826 connection_write(c
, &ok
, sizeof(int32_t));
831 static int esd_proto_sample_cache(connection
*c
, esd_proto_t request
, const void *data
, size_t length
) {
833 int32_t format
, rate
, sc_length
;
835 char name
[ESD_NAME_MAX
+sizeof(SCACHE_PREFIX
)-1];
837 connection_assert_ref(c
);
839 pa_assert(length
== (ESD_NAME_MAX
+3*sizeof(int32_t)));
841 memcpy(&format
, data
, sizeof(int32_t));
842 format
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, format
);
843 data
= (const char*)data
+ sizeof(int32_t);
845 memcpy(&rate
, data
, sizeof(int32_t));
846 rate
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, rate
);
847 data
= (const char*)data
+ sizeof(int32_t);
849 ss
.rate
= (uint32_t) rate
;
850 format_esd2native(format
, c
->swap_byte_order
, &ss
);
852 CHECK_VALIDITY(pa_sample_spec_valid(&ss
), "Invalid sample specification.");
854 memcpy(&sc_length
, data
, sizeof(int32_t));
855 sc_length
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, sc_length
);
856 data
= (const char*)data
+ sizeof(int32_t);
858 CHECK_VALIDITY(sc_length
<= MAX_CACHE_SAMPLE_SIZE
, "Sample too large (%d bytes).", (int)sc_length
);
860 strcpy(name
, SCACHE_PREFIX
);
861 pa_strlcpy(name
+sizeof(SCACHE_PREFIX
)-1, data
, ESD_NAME_MAX
);
863 CHECK_VALIDITY(pa_utf8_valid(name
), "Invalid UTF8 in sample name.");
865 pa_assert(!c
->scache
.memchunk
.memblock
);
866 c
->scache
.memchunk
.memblock
= pa_memblock_new(c
->protocol
->core
->mempool
, (size_t) sc_length
);
867 c
->scache
.memchunk
.index
= 0;
868 c
->scache
.memchunk
.length
= (size_t) sc_length
;
869 c
->scache
.sample_spec
= ss
;
870 pa_assert(!c
->scache
.name
);
871 c
->scache
.name
= pa_xstrdup(name
);
873 c
->state
= ESD_CACHING_SAMPLE
;
875 pa_scache_add_item(c
->protocol
->core
, c
->scache
.name
, NULL
, NULL
, NULL
, c
->client
->proplist
, &idx
);
878 connection_write(c
, &idx
, sizeof(uint32_t));
883 static int esd_proto_sample_get_id(connection
*c
, esd_proto_t request
, const void *data
, size_t length
) {
886 char name
[ESD_NAME_MAX
+sizeof(SCACHE_PREFIX
)-1];
888 connection_assert_ref(c
);
890 pa_assert(length
== ESD_NAME_MAX
);
892 strcpy(name
, SCACHE_PREFIX
);
893 pa_strlcpy(name
+sizeof(SCACHE_PREFIX
)-1, data
, ESD_NAME_MAX
);
895 CHECK_VALIDITY(pa_utf8_valid(name
), "Invalid UTF8 in sample name.");
898 if ((idx
= pa_scache_get_id_by_name(c
->protocol
->core
, name
)) != PA_IDXSET_INVALID
)
899 ok
= (int32_t) idx
+ 1;
901 connection_write(c
, &ok
, sizeof(int32_t));
906 static int esd_proto_sample_free_or_play(connection
*c
, esd_proto_t request
, const void *data
, size_t length
) {
911 connection_assert_ref(c
);
913 pa_assert(length
== sizeof(int32_t));
915 memcpy(&idx
, data
, sizeof(uint32_t));
916 idx
= PA_MAYBE_UINT32_SWAP(c
->swap_byte_order
, idx
) - 1;
920 if ((name
= pa_scache_get_name_by_id(c
->protocol
->core
, idx
))) {
921 if (request
== ESD_PROTO_SAMPLE_PLAY
) {
924 if ((sink
= pa_namereg_get(c
->protocol
->core
, c
->options
->default_sink
, PA_NAMEREG_SINK
)))
925 if (pa_scache_play_item(c
->protocol
->core
, name
, sink
, PA_VOLUME_NORM
, c
->client
->proplist
, NULL
) >= 0)
926 ok
= (int32_t) idx
+ 1;
928 pa_assert(request
== ESD_PROTO_SAMPLE_FREE
);
930 if (pa_scache_remove_item(c
->protocol
->core
, name
) >= 0)
931 ok
= (int32_t) idx
+ 1;
935 connection_write(c
, &ok
, sizeof(int32_t));
940 static int esd_proto_standby_or_resume(connection
*c
, esd_proto_t request
, const void *data
, size_t length
) {
943 connection_assert_ref(c
);
945 connection_write_prepare(c
, sizeof(int32_t) * 2);
946 connection_write(c
, &ok
, sizeof(int32_t));
948 if (request
== ESD_PROTO_STANDBY
)
949 ok
= pa_sink_suspend_all(c
->protocol
->core
, TRUE
) >= 0;
951 pa_assert(request
== ESD_PROTO_RESUME
);
952 ok
= pa_sink_suspend_all(c
->protocol
->core
, FALSE
) >= 0;
955 connection_write(c
, &ok
, sizeof(int32_t));
960 static int esd_proto_standby_mode(connection
*c
, esd_proto_t request
, const void *data
, size_t length
) {
962 pa_sink
*sink
, *source
;
964 connection_assert_ref(c
);
968 if ((sink
= pa_namereg_get(c
->protocol
->core
, c
->options
->default_sink
, PA_NAMEREG_SINK
)))
969 if (pa_sink_get_state(sink
) == PA_SINK_SUSPENDED
)
970 mode
= ESM_ON_STANDBY
;
972 if ((source
= pa_namereg_get(c
->protocol
->core
, c
->options
->default_source
, PA_NAMEREG_SOURCE
)))
973 if (pa_source_get_state(source
) == PA_SOURCE_SUSPENDED
)
974 mode
= ESM_ON_STANDBY
;
976 mode
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, mode
);
978 connection_write(c
, &mode
, sizeof(mode
));
982 /*** client callbacks ***/
984 static void client_kill_cb(pa_client
*c
) {
987 connection_unlink(CONNECTION(c
->userdata
));
990 /*** pa_iochannel callbacks ***/
992 static int do_read(connection
*c
) {
993 connection_assert_ref(c
);
995 /* pa_log("READ"); */
997 if (c
->state
== ESD_NEXT_REQUEST
) {
999 pa_assert(c
->read_data_length
< sizeof(c
->request
));
1001 if ((r
= pa_iochannel_read(c
->io
,
1002 ((uint8_t*) &c
->request
) + c
->read_data_length
,
1003 sizeof(c
->request
) - c
->read_data_length
)) <= 0) {
1005 if (r
< 0 && (errno
== EINTR
|| errno
== EAGAIN
))
1008 pa_log_debug("read(): %s", r
< 0 ? pa_cstrerror(errno
) : "EOF");
1012 c
->read_data_length
+= (size_t) r
;
1014 if (c
->read_data_length
>= sizeof(c
->request
)) {
1015 struct proto_handler
*handler
;
1017 c
->request
= PA_MAYBE_INT32_SWAP(c
->swap_byte_order
, c
->request
);
1019 if (c
->request
< ESD_PROTO_CONNECT
|| c
->request
>= ESD_PROTO_MAX
) {
1020 pa_log("recieved invalid request.");
1024 handler
= proto_map
+c
->request
;
1026 /* pa_log("executing request #%u", c->request); */
1028 if (!handler
->proc
) {
1029 pa_log("recieved unimplemented request #%u.", c
->request
);
1033 if (handler
->data_length
== 0) {
1034 c
->read_data_length
= 0;
1036 if (handler
->proc(c
, c
->request
, NULL
, 0) < 0)
1040 if (c
->read_data_alloc
< handler
->data_length
)
1041 c
->read_data
= pa_xrealloc(c
->read_data
, c
->read_data_alloc
= handler
->data_length
);
1042 pa_assert(c
->read_data
);
1044 c
->state
= ESD_NEEDS_REQDATA
;
1045 c
->read_data_length
= 0;
1049 } else if (c
->state
== ESD_NEEDS_REQDATA
) {
1051 struct proto_handler
*handler
= proto_map
+c
->request
;
1053 pa_assert(handler
->proc
);
1055 pa_assert(c
->read_data
&& c
->read_data_length
< handler
->data_length
);
1057 if ((r
= pa_iochannel_read(c
->io
,
1058 (uint8_t*) c
->read_data
+ c
->read_data_length
,
1059 handler
->data_length
- c
->read_data_length
)) <= 0) {
1061 if (r
< 0 && (errno
== EINTR
|| errno
== EAGAIN
))
1064 pa_log_debug("read(): %s", r
< 0 ? pa_cstrerror(errno
) : "EOF");
1068 c
->read_data_length
+= (size_t) r
;
1069 if (c
->read_data_length
>= handler
->data_length
) {
1070 size_t l
= c
->read_data_length
;
1071 pa_assert(handler
->proc
);
1073 c
->state
= ESD_NEXT_REQUEST
;
1074 c
->read_data_length
= 0;
1076 if (handler
->proc(c
, c
->request
, c
->read_data
, l
) < 0)
1079 } else if (c
->state
== ESD_CACHING_SAMPLE
) {
1083 pa_assert(c
->scache
.memchunk
.memblock
);
1084 pa_assert(c
->scache
.name
);
1085 pa_assert(c
->scache
.memchunk
.index
< c
->scache
.memchunk
.length
);
1087 p
= pa_memblock_acquire(c
->scache
.memchunk
.memblock
);
1088 r
= pa_iochannel_read(c
->io
, (uint8_t*) p
+c
->scache
.memchunk
.index
, c
->scache
.memchunk
.length
-c
->scache
.memchunk
.index
);
1089 pa_memblock_release(c
->scache
.memchunk
.memblock
);
1092 if (r
< 0 && (errno
== EINTR
|| errno
== EAGAIN
))
1095 pa_log_debug("read(): %s", r
< 0 ? pa_cstrerror(errno
) : "EOF");
1099 c
->scache
.memchunk
.index
+= (size_t) r
;
1100 pa_assert(c
->scache
.memchunk
.index
<= c
->scache
.memchunk
.length
);
1102 if (c
->scache
.memchunk
.index
== c
->scache
.memchunk
.length
) {
1105 c
->scache
.memchunk
.index
= 0;
1106 pa_scache_add_item(c
->protocol
->core
, c
->scache
.name
, &c
->scache
.sample_spec
, NULL
, &c
->scache
.memchunk
, c
->client
->proplist
, &idx
);
1108 pa_memblock_unref(c
->scache
.memchunk
.memblock
);
1109 pa_memchunk_reset(&c
->scache
.memchunk
);
1111 pa_xfree(c
->scache
.name
);
1112 c
->scache
.name
= NULL
;
1114 c
->state
= ESD_NEXT_REQUEST
;
1117 connection_write(c
, &idx
, sizeof(uint32_t));
1120 } else if (c
->state
== ESD_STREAMING_DATA
&& c
->sink_input
) {
1127 pa_assert(c
->input_memblockq
);
1129 /* pa_log("STREAMING_DATA"); */
1131 if (!(l
= (size_t) pa_atomic_load(&c
->playback
.missing
)))
1134 if (c
->playback
.current_memblock
) {
1136 space
= pa_memblock_get_length(c
->playback
.current_memblock
) - c
->playback
.memblock_index
;
1139 pa_memblock_unref(c
->playback
.current_memblock
);
1140 c
->playback
.current_memblock
= NULL
;
1144 if (!c
->playback
.current_memblock
) {
1145 pa_assert_se(c
->playback
.current_memblock
= pa_memblock_new(c
->protocol
->core
->mempool
, (size_t) -1));
1146 c
->playback
.memblock_index
= 0;
1148 space
= pa_memblock_get_length(c
->playback
.current_memblock
);
1154 p
= pa_memblock_acquire(c
->playback
.current_memblock
);
1155 r
= pa_iochannel_read(c
->io
, (uint8_t*) p
+c
->playback
.memblock_index
, l
);
1156 pa_memblock_release(c
->playback
.current_memblock
);
1160 if (r
< 0 && (errno
== EINTR
|| errno
== EAGAIN
))
1163 pa_log_debug("read(): %s", r
< 0 ? pa_cstrerror(errno
) : "EOF");
1167 chunk
.memblock
= c
->playback
.current_memblock
;
1168 chunk
.index
= c
->playback
.memblock_index
;
1169 chunk
.length
= (size_t) r
;
1171 c
->playback
.memblock_index
+= (size_t) r
;
1173 pa_asyncmsgq_post(c
->sink_input
->sink
->asyncmsgq
, PA_MSGOBJECT(c
->sink_input
), SINK_INPUT_MESSAGE_POST_DATA
, NULL
, 0, &chunk
, NULL
);
1174 pa_atomic_sub(&c
->playback
.missing
, (int) r
);
1180 static int do_write(connection
*c
) {
1181 connection_assert_ref(c
);
1183 /* pa_log("WRITE"); */
1185 if (c
->write_data_length
) {
1188 pa_assert(c
->write_data_index
< c
->write_data_length
);
1189 if ((r
= pa_iochannel_write(c
->io
, (uint8_t*) c
->write_data
+c
->write_data_index
, c
->write_data_length
-c
->write_data_index
)) < 0) {
1191 if (r
< 0 && (errno
== EINTR
|| errno
== EAGAIN
))
1194 pa_log("write(): %s", pa_cstrerror(errno
));
1198 c
->write_data_index
+= (size_t) r
;
1199 if (c
->write_data_index
>= c
->write_data_length
)
1200 c
->write_data_length
= c
->write_data_index
= 0;
1202 } else if (c
->state
== ESD_STREAMING_DATA
&& c
->source_output
) {
1207 if (pa_memblockq_peek(c
->output_memblockq
, &chunk
) < 0)
1210 pa_assert(chunk
.memblock
);
1211 pa_assert(chunk
.length
);
1213 p
= pa_memblock_acquire(chunk
.memblock
);
1214 r
= pa_iochannel_write(c
->io
, (uint8_t*) p
+chunk
.index
, chunk
.length
);
1215 pa_memblock_release(chunk
.memblock
);
1217 pa_memblock_unref(chunk
.memblock
);
1221 if (r
< 0 && (errno
== EINTR
|| errno
== EAGAIN
))
1224 pa_log("write(): %s", pa_cstrerror(errno
));
1228 pa_memblockq_drop(c
->output_memblockq
, (size_t) r
);
1234 static void do_work(connection
*c
) {
1235 connection_assert_ref(c
);
1237 c
->protocol
->core
->mainloop
->defer_enable(c
->defer_event
, 0);
1242 if (pa_iochannel_is_readable(c
->io
))
1246 if (c
->state
== ESD_STREAMING_DATA
&& !c
->sink_input
&& pa_iochannel_is_hungup(c
->io
))
1247 /* In case we are in capture mode we will never call read()
1248 * on the socket, hence we need to detect the hangup manually
1249 * here, instead of simply waiting for read() to return 0. */
1252 if (pa_iochannel_is_writable(c
->io
))
1253 if (do_write(c
) < 0)
1260 if (c
->state
== ESD_STREAMING_DATA
&& c
->sink_input
) {
1263 pa_iochannel_free(c
->io
);
1266 pa_asyncmsgq_post(c
->sink_input
->sink
->asyncmsgq
, PA_MSGOBJECT(c
->sink_input
), SINK_INPUT_MESSAGE_DISABLE_PREBUF
, NULL
, 0, NULL
, NULL
);
1268 connection_unlink(c
);
1271 static void io_callback(pa_iochannel
*io
, void *userdata
) {
1272 connection
*c
= CONNECTION(userdata
);
1274 connection_assert_ref(c
);
1280 static void defer_callback(pa_mainloop_api
*a
, pa_defer_event
*e
, void *userdata
) {
1281 connection
*c
= CONNECTION(userdata
);
1283 connection_assert_ref(c
);
1289 static int connection_process_msg(pa_msgobject
*o
, int code
, void*userdata
, int64_t offset
, pa_memchunk
*chunk
) {
1290 connection
*c
= CONNECTION(o
);
1291 connection_assert_ref(c
);
1297 case CONNECTION_MESSAGE_REQUEST_DATA
:
1301 case CONNECTION_MESSAGE_POST_DATA
:
1302 /* pa_log("got data %u", chunk->length); */
1303 pa_memblockq_push_align(c
->output_memblockq
, chunk
);
1307 case CONNECTION_MESSAGE_UNLINK_CONNECTION
:
1308 connection_unlink(c
);
1315 /*** sink_input callbacks ***/
1317 /* Called from thread context */
1318 static int sink_input_process_msg(pa_msgobject
*o
, int code
, void *userdata
, int64_t offset
, pa_memchunk
*chunk
) {
1319 pa_sink_input
*i
= PA_SINK_INPUT(o
);
1322 pa_sink_input_assert_ref(i
);
1323 c
= CONNECTION(i
->userdata
);
1324 connection_assert_ref(c
);
1328 case SINK_INPUT_MESSAGE_POST_DATA
: {
1331 /* New data from the main loop */
1332 pa_memblockq_push_align(c
->input_memblockq
, chunk
);
1334 if (pa_memblockq_is_readable(c
->input_memblockq
) && c
->playback
.underrun
) {
1335 pa_log_debug("Requesting rewind due to end of underrun.");
1336 pa_sink_input_request_rewind(c
->sink_input
, 0, FALSE
, TRUE
, FALSE
);
1339 /* pa_log("got data, %u", pa_memblockq_get_length(c->input_memblockq)); */
1344 case SINK_INPUT_MESSAGE_DISABLE_PREBUF
:
1345 pa_memblockq_prebuf_disable(c
->input_memblockq
);
1348 case PA_SINK_INPUT_MESSAGE_GET_LATENCY
: {
1349 pa_usec_t
*r
= userdata
;
1351 *r
= pa_bytes_to_usec(pa_memblockq_get_length(c
->input_memblockq
), &c
->sink_input
->sample_spec
);
1353 /* Fall through, the default handler will add in the extra
1354 * latency added by the resampler */
1358 return pa_sink_input_process_msg(o
, code
, userdata
, offset
, chunk
);
1362 /* Called from thread context */
1363 static int sink_input_pop_cb(pa_sink_input
*i
, size_t length
, pa_memchunk
*chunk
) {
1366 pa_sink_input_assert_ref(i
);
1367 c
= CONNECTION(i
->userdata
);
1368 connection_assert_ref(c
);
1371 if (pa_memblockq_peek(c
->input_memblockq
, chunk
) < 0) {
1373 c
->playback
.underrun
= TRUE
;
1375 if (c
->dead
&& pa_sink_input_safe_to_remove(i
))
1376 pa_asyncmsgq_post(pa_thread_mq_get()->outq
, PA_MSGOBJECT(c
), CONNECTION_MESSAGE_UNLINK_CONNECTION
, NULL
, 0, NULL
, NULL
);
1382 chunk
->length
= PA_MIN(length
, chunk
->length
);
1384 c
->playback
.underrun
= FALSE
;
1386 pa_memblockq_drop(c
->input_memblockq
, chunk
->length
);
1387 m
= pa_memblockq_pop_missing(c
->input_memblockq
);
1390 if (pa_atomic_add(&c
->playback
.missing
, (int) m
) <= 0)
1391 pa_asyncmsgq_post(pa_thread_mq_get()->outq
, PA_MSGOBJECT(c
), CONNECTION_MESSAGE_REQUEST_DATA
, NULL
, 0, NULL
, NULL
);
1397 /* Called from thread context */
1398 static void sink_input_process_rewind_cb(pa_sink_input
*i
, size_t nbytes
) {
1401 pa_sink_input_assert_ref(i
);
1402 c
= CONNECTION(i
->userdata
);
1403 connection_assert_ref(c
);
1405 /* If we are in an underrun, then we don't rewind */
1406 if (i
->thread_info
.underrun_for
> 0)
1409 pa_memblockq_rewind(c
->input_memblockq
, nbytes
);
1412 /* Called from thread context */
1413 static void sink_input_update_max_rewind_cb(pa_sink_input
*i
, size_t nbytes
) {
1416 pa_sink_input_assert_ref(i
);
1417 c
= CONNECTION(i
->userdata
);
1418 connection_assert_ref(c
);
1420 pa_memblockq_set_maxrewind(c
->input_memblockq
, nbytes
);
1423 static void sink_input_kill_cb(pa_sink_input
*i
) {
1424 pa_sink_input_assert_ref(i
);
1426 connection_unlink(CONNECTION(i
->userdata
));
1429 /*** source_output callbacks ***/
1431 /* Called from thread context */
1432 static void source_output_push_cb(pa_source_output
*o
, const pa_memchunk
*chunk
) {
1435 pa_source_output_assert_ref(o
);
1436 c
= CONNECTION(o
->userdata
);
1440 pa_asyncmsgq_post(pa_thread_mq_get()->outq
, PA_MSGOBJECT(c
), CONNECTION_MESSAGE_POST_DATA
, NULL
, 0, chunk
, NULL
);
1443 static void source_output_kill_cb(pa_source_output
*o
) {
1444 pa_source_output_assert_ref(o
);
1446 connection_unlink(CONNECTION(o
->userdata
));
1449 static pa_usec_t
source_output_get_latency_cb(pa_source_output
*o
) {
1452 pa_source_output_assert_ref(o
);
1453 c
= CONNECTION(o
->userdata
);
1456 return pa_bytes_to_usec(pa_memblockq_get_length(c
->output_memblockq
), &c
->source_output
->sample_spec
);
1459 /*** entry points ***/
1461 static void auth_timeout(pa_mainloop_api
*m
, pa_time_event
*e
, const struct timeval
*tv
, void *userdata
) {
1462 connection
*c
= CONNECTION(userdata
);
1466 connection_assert_ref(c
);
1467 pa_assert(c
->auth_timeout_event
== e
);
1470 connection_unlink(c
);
1473 void pa_esound_protocol_connect(pa_esound_protocol
*p
, pa_iochannel
*io
, pa_esound_options
*o
) {
1476 pa_client_new_data data
;
1483 if (pa_idxset_size(p
->connections
)+1 > MAX_CONNECTIONS
) {
1484 pa_log("Warning! Too many connections (%u), dropping incoming connection.", MAX_CONNECTIONS
);
1485 pa_iochannel_free(io
);
1489 pa_client_new_data_init(&data
);
1490 data
.module
= o
->module
;
1491 data
.driver
= __FILE__
;
1492 pa_iochannel_socket_peer_to_string(io
, pname
, sizeof(pname
));
1493 pa_proplist_setf(data
.proplist
, PA_PROP_APPLICATION_NAME
, "EsounD client (%s)", pname
);
1494 pa_proplist_sets(data
.proplist
, "esound-protocol.peer", pname
);
1495 client
= pa_client_new(p
->core
, &data
);
1496 pa_client_new_data_done(&data
);
1501 c
= pa_msgobject_new(connection
);
1502 c
->parent
.parent
.free
= connection_free
;
1503 c
->parent
.process_msg
= connection_process_msg
;
1506 pa_iochannel_set_callback(c
->io
, io_callback
, c
);
1509 c
->client
->kill
= client_kill_cb
;
1510 c
->client
->userdata
= c
;
1512 c
->options
= pa_esound_options_ref(o
);
1513 c
->authorized
= FALSE
;
1514 c
->swap_byte_order
= FALSE
;
1517 c
->read_data_length
= 0;
1518 c
->read_data
= pa_xmalloc(c
->read_data_alloc
= proto_map
[ESD_PROTO_CONNECT
].data_length
);
1520 c
->write_data_length
= c
->write_data_index
= c
->write_data_alloc
= 0;
1521 c
->write_data
= NULL
;
1523 c
->state
= ESD_NEEDS_REQDATA
;
1524 c
->request
= ESD_PROTO_CONNECT
;
1526 c
->sink_input
= NULL
;
1527 c
->input_memblockq
= NULL
;
1529 c
->source_output
= NULL
;
1530 c
->output_memblockq
= NULL
;
1532 c
->playback
.current_memblock
= NULL
;
1533 c
->playback
.memblock_index
= 0;
1534 c
->playback
.underrun
= TRUE
;
1535 pa_atomic_store(&c
->playback
.missing
, 0);
1537 pa_memchunk_reset(&c
->scache
.memchunk
);
1538 c
->scache
.name
= NULL
;
1540 c
->original_name
= NULL
;
1542 if (o
->auth_anonymous
) {
1543 pa_log_info("Client authenticated anonymously.");
1544 c
->authorized
= TRUE
;
1547 if (!c
->authorized
&&
1549 pa_ip_acl_check(o
->auth_ip_acl
, pa_iochannel_get_recv_fd(io
)) > 0) {
1551 pa_log_info("Client authenticated by IP ACL.");
1552 c
->authorized
= TRUE
;
1555 if (!c
->authorized
) {
1557 pa_gettimeofday(&tv
);
1558 tv
.tv_sec
+= AUTH_TIMEOUT
;
1559 c
->auth_timeout_event
= p
->core
->mainloop
->time_new(p
->core
->mainloop
, &tv
, auth_timeout
, c
);
1561 c
->auth_timeout_event
= NULL
;
1563 c
->defer_event
= p
->core
->mainloop
->defer_new(p
->core
->mainloop
, defer_callback
, c
);
1564 p
->core
->mainloop
->defer_enable(c
->defer_event
, 0);
1566 pa_idxset_put(p
->connections
, c
, &c
->index
);
1569 void pa_esound_protocol_disconnect(pa_esound_protocol
*p
, pa_module
*m
) {
1576 while ((c
= pa_idxset_iterate(p
->connections
, &state
, NULL
)))
1577 if (c
->options
->module
== m
)
1578 connection_unlink(c
);
1581 static pa_esound_protocol
* esound_protocol_new(pa_core
*c
) {
1582 pa_esound_protocol
*p
;
1586 p
= pa_xnew(pa_esound_protocol
, 1);
1589 p
->connections
= pa_idxset_new(NULL
, NULL
);
1592 pa_assert_se(pa_shared_set(c
, "esound-protocol", p
) >= 0);
1597 pa_esound_protocol
* pa_esound_protocol_get(pa_core
*c
) {
1598 pa_esound_protocol
*p
;
1600 if ((p
= pa_shared_get(c
, "esound-protocol")))
1601 return pa_esound_protocol_ref(p
);
1603 return esound_protocol_new(c
);
1606 pa_esound_protocol
* pa_esound_protocol_ref(pa_esound_protocol
*p
) {
1608 pa_assert(PA_REFCNT_VALUE(p
) >= 1);
1615 void pa_esound_protocol_unref(pa_esound_protocol
*p
) {
1618 pa_assert(PA_REFCNT_VALUE(p
) >= 1);
1620 if (PA_REFCNT_DEC(p
) > 0)
1623 while ((c
= pa_idxset_first(p
->connections
, NULL
)))
1624 connection_unlink(c
);
1626 pa_idxset_free(p
->connections
, NULL
, NULL
);
1628 pa_assert_se(pa_shared_remove(p
->core
, "esound-protocol") >= 0);
1633 pa_esound_options
* pa_esound_options_new(void) {
1634 pa_esound_options
*o
;
1636 o
= pa_xnew0(pa_esound_options
, 1);
1642 pa_esound_options
* pa_esound_options_ref(pa_esound_options
*o
) {
1644 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1651 void pa_esound_options_unref(pa_esound_options
*o
) {
1653 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1655 if (PA_REFCNT_DEC(o
) > 0)
1659 pa_ip_acl_free(o
->auth_ip_acl
);
1662 pa_auth_cookie_unref(o
->auth_cookie
);
1664 pa_xfree(o
->default_sink
);
1665 pa_xfree(o
->default_source
);
1670 int pa_esound_options_parse(pa_esound_options
*o
, pa_core
*c
, pa_modargs
*ma
) {
1675 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1678 if (pa_modargs_get_value_boolean(ma
, "auth-anonymous", &o
->auth_anonymous
) < 0) {
1679 pa_log("auth-anonymous= expects a boolean argument.");
1683 if ((acl
= pa_modargs_get_value(ma
, "auth-ip-acl", NULL
))) {
1686 if (!(ipa
= pa_ip_acl_new(acl
))) {
1687 pa_log("Failed to parse IP ACL '%s'", acl
);
1692 pa_ip_acl_free(o
->auth_ip_acl
);
1694 o
->auth_ip_acl
= ipa
;
1698 if (pa_modargs_get_value_boolean(ma
, "auth-cookie-enabled", &enabled
) < 0) {
1699 pa_log("auth-cookie-enabled= expects a boolean argument.");
1704 pa_auth_cookie_unref(o
->auth_cookie
);
1709 /* The new name for this is 'auth-cookie', for compat reasons
1710 * we check the old name too */
1711 if (!(cn
= pa_modargs_get_value(ma
, "auth-cookie", NULL
)))
1712 if (!(cn
= pa_modargs_get_value(ma
, "cookie", NULL
)))
1713 cn
= DEFAULT_COOKIE_FILE
;
1715 if (!(o
->auth_cookie
= pa_auth_cookie_get(c
, cn
, ESD_KEY_LEN
)))
1719 o
->auth_cookie
= NULL
;
1721 pa_xfree(o
->default_sink
);
1722 o
->default_sink
= pa_xstrdup(pa_modargs_get_value(ma
, "sink", NULL
));
1724 pa_xfree(o
->default_source
);
1725 o
->default_source
= pa_xstrdup(pa_modargs_get_value(ma
, "source", NULL
));