4 This file is part of PulseAudio.
6 Copyright 2004-2006 Lennart Poettering
7 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
9 PulseAudio is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published
11 by the Free Software Foundation; either version 2 of the License,
12 or (at your option) any later version.
14 PulseAudio is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with PulseAudio; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
36 #include <pulse/sample.h>
37 #include <pulse/timeval.h>
38 #include <pulse/utf8.h>
39 #include <pulse/xmalloc.h>
41 #include <pulsecore/esound.h>
42 #include <pulsecore/memblock.h>
43 #include <pulsecore/client.h>
44 #include <pulsecore/sink-input.h>
45 #include <pulsecore/sink.h>
46 #include <pulsecore/source-output.h>
47 #include <pulsecore/source.h>
48 #include <pulsecore/core-scache.h>
49 #include <pulsecore/sample-util.h>
50 #include <pulsecore/authkey.h>
51 #include <pulsecore/namereg.h>
52 #include <pulsecore/log.h>
53 #include <pulsecore/core-util.h>
54 #include <pulsecore/core-error.h>
55 #include <pulsecore/ipacl.h>
57 #include "endianmacros.h"
59 #include "protocol-esound.h"
61 /* Don't accept more connection than this */
62 #define MAX_CONNECTIONS 64
64 /* Kick a client if it doesn't authenticate within this time */
65 #define AUTH_TIMEOUT 5
67 #define DEFAULT_COOKIE_FILE ".esd_auth"
69 #define PLAYBACK_BUFFER_SECONDS (.25)
70 #define PLAYBACK_BUFFER_FRAGMENTS (10)
71 #define RECORD_BUFFER_SECONDS (5)
72 #define RECORD_BUFFER_FRAGMENTS (100)
74 #define MAX_CACHE_SAMPLE_SIZE (1024000)
76 #define SCACHE_PREFIX "esound."
78 /* This is heavily based on esound's code */
83 pa_protocol_esound
*protocol
;
86 int authorized
, swap_byte_order
;
88 size_t write_data_alloc
, write_data_index
, write_data_length
;
90 size_t read_data_alloc
, read_data_length
;
92 esd_client_state_t state
;
93 pa_sink_input
*sink_input
;
94 pa_source_output
*source_output
;
95 pa_memblockq
*input_memblockq
, *output_memblockq
;
96 pa_defer_event
*defer_event
;
101 pa_memblock
*current_memblock
;
102 size_t memblock_index
, fragment_size
;
106 pa_memchunk memchunk
;
108 pa_sample_spec sample_spec
;
111 pa_time_event
*auth_timeout_event
;
114 struct pa_protocol_esound
{
118 pa_socket_server
*server
;
119 pa_idxset
*connections
;
120 char *sink_name
, *source_name
;
122 uint8_t esd_key
[ESD_KEY_LEN
];
123 pa_ip_acl
*auth_ip_acl
;
126 typedef struct proto_handler
{
128 int (*proc
)(struct connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
129 const char *description
;
130 } esd_proto_handler_info_t
;
132 static void sink_input_drop_cb(pa_sink_input
*i
, const pa_memchunk
*chunk
, size_t length
);
133 static int sink_input_peek_cb(pa_sink_input
*i
, pa_memchunk
*chunk
);
134 static void sink_input_kill_cb(pa_sink_input
*i
);
135 static pa_usec_t
sink_input_get_latency_cb(pa_sink_input
*i
);
136 static pa_usec_t
source_output_get_latency_cb(pa_source_output
*o
);
138 static void source_output_push_cb(pa_source_output
*o
, const pa_memchunk
*chunk
);
139 static void source_output_kill_cb(pa_source_output
*o
);
141 static int esd_proto_connect(struct connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
142 static int esd_proto_stream_play(struct connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
143 static int esd_proto_stream_record(struct connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
144 static int esd_proto_get_latency(struct connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
145 static int esd_proto_server_info(struct connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
146 static int esd_proto_all_info(struct connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
147 static int esd_proto_stream_pan(struct connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
148 static int esd_proto_sample_cache(struct connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
149 static int esd_proto_sample_free_or_play(struct connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
150 static int esd_proto_sample_get_id(struct connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
151 static int esd_proto_standby_or_resume(struct connection
*c
, esd_proto_t request
, const void *data
, size_t length
);
153 /* the big map of protocol handler info */
154 static struct proto_handler proto_map
[ESD_PROTO_MAX
] = {
155 { ESD_KEY_LEN
+ sizeof(int), esd_proto_connect
, "connect" },
156 { ESD_KEY_LEN
+ sizeof(int), NULL
, "lock" },
157 { ESD_KEY_LEN
+ sizeof(int), NULL
, "unlock" },
159 { ESD_NAME_MAX
+ 2 * sizeof(int), esd_proto_stream_play
, "stream play" },
160 { ESD_NAME_MAX
+ 2 * sizeof(int), esd_proto_stream_record
, "stream rec" },
161 { ESD_NAME_MAX
+ 2 * sizeof(int), esd_proto_stream_record
, "stream mon" },
163 { ESD_NAME_MAX
+ 3 * sizeof(int), esd_proto_sample_cache
, "sample cache" }, /* 6 */
164 { sizeof(int), esd_proto_sample_free_or_play
, "sample free" },
165 { sizeof(int), esd_proto_sample_free_or_play
, "sample play" }, /* 8 */
166 { sizeof(int), NULL
, "sample loop" },
167 { sizeof(int), NULL
, "sample stop" },
168 { -1, NULL
, "TODO: sample kill" },
170 { ESD_KEY_LEN
+ sizeof(int), esd_proto_standby_or_resume
, "standby" }, /* NOOP! */
171 { ESD_KEY_LEN
+ sizeof(int), esd_proto_standby_or_resume
, "resume" }, /* NOOP! */ /* 13 */
173 { ESD_NAME_MAX
, esd_proto_sample_get_id
, "sample getid" }, /* 14 */
174 { ESD_NAME_MAX
+ 2 * sizeof(int), NULL
, "stream filter" },
176 { sizeof(int), esd_proto_server_info
, "server info" },
177 { sizeof(int), esd_proto_all_info
, "all info" },
178 { -1, NULL
, "TODO: subscribe" },
179 { -1, NULL
, "TODO: unsubscribe" },
181 { 3 * sizeof(int), esd_proto_stream_pan
, "stream pan"},
182 { 3 * sizeof(int), NULL
, "sample pan" },
184 { sizeof(int), NULL
, "standby mode" },
185 { 0, esd_proto_get_latency
, "get latency" }
188 static void connection_free(struct connection
*c
) {
190 pa_idxset_remove_by_data(c
->protocol
->connections
, c
, NULL
);
192 if (c
->state
== ESD_STREAMING_DATA
)
193 c
->protocol
->n_player
--;
195 pa_client_free(c
->client
);
198 pa_sink_input_disconnect(c
->sink_input
);
199 pa_sink_input_unref(c
->sink_input
);
202 if (c
->source_output
) {
203 pa_source_output_disconnect(c
->source_output
);
204 pa_source_output_unref(c
->source_output
);
207 if (c
->input_memblockq
)
208 pa_memblockq_free(c
->input_memblockq
);
209 if (c
->output_memblockq
)
210 pa_memblockq_free(c
->output_memblockq
);
212 if (c
->playback
.current_memblock
)
213 pa_memblock_unref(c
->playback
.current_memblock
);
215 pa_xfree(c
->read_data
);
216 pa_xfree(c
->write_data
);
219 pa_iochannel_free(c
->io
);
222 c
->protocol
->core
->mainloop
->defer_free(c
->defer_event
);
224 if (c
->scache
.memchunk
.memblock
)
225 pa_memblock_unref(c
->scache
.memchunk
.memblock
);
226 pa_xfree(c
->scache
.name
);
228 if (c
->auth_timeout_event
)
229 c
->protocol
->core
->mainloop
->time_free(c
->auth_timeout_event
);
231 pa_xfree(c
->original_name
);
235 static void connection_write_prepare(struct connection
*c
, size_t length
) {
239 t
= c
->write_data_length
+length
;
241 if (c
->write_data_alloc
< t
)
242 c
->write_data
= pa_xrealloc(c
->write_data
, c
->write_data_alloc
= t
);
244 assert(c
->write_data
);
247 static void connection_write(struct connection
*c
, const void *data
, size_t length
) {
251 assert(c
->protocol
&& c
->protocol
->core
&& c
->protocol
->core
->mainloop
&& c
->protocol
->core
->mainloop
->defer_enable
);
252 c
->protocol
->core
->mainloop
->defer_enable(c
->defer_event
, 1);
254 connection_write_prepare(c
, length
);
256 assert(c
->write_data
);
258 i
= c
->write_data_length
;
259 c
->write_data_length
+= length
;
261 memcpy((char*)c
->write_data
+ i
, data
, length
);
264 static void format_esd2native(int format
, int swap_bytes
, pa_sample_spec
*ss
) {
267 ss
->channels
= ((format
& ESD_MASK_CHAN
) == ESD_STEREO
) ? 2 : 1;
268 if ((format
& ESD_MASK_BITS
) == ESD_BITS16
)
269 ss
->format
= swap_bytes
? PA_SAMPLE_S16RE
: PA_SAMPLE_S16NE
;
271 ss
->format
= PA_SAMPLE_U8
;
274 static int format_native2esd(pa_sample_spec
*ss
) {
277 format
= (ss
->format
== PA_SAMPLE_U8
) ? ESD_BITS8
: ESD_BITS16
;
278 format
|= (ss
->channels
>= 2) ? ESD_STEREO
: ESD_MONO
;
283 #define CHECK_VALIDITY(expression, ...) do { \
284 if (!(expression)) { \
285 pa_log_warn(__FILE__ ": " __VA_ARGS__); \
290 /*** esound commands ***/
292 static int esd_proto_connect(struct connection
*c
, PA_GCC_UNUSED esd_proto_t request
, const void *data
, size_t length
) {
296 assert(length
== (ESD_KEY_LEN
+ sizeof(uint32_t)));
298 if (!c
->authorized
) {
299 if (memcmp(data
, c
->protocol
->esd_key
, ESD_KEY_LEN
) != 0) {
300 pa_log("kicked client with invalid authorization key.");
305 if (c
->auth_timeout_event
) {
306 c
->protocol
->core
->mainloop
->time_free(c
->auth_timeout_event
);
307 c
->auth_timeout_event
= NULL
;
311 data
= (const char*)data
+ ESD_KEY_LEN
;
313 memcpy(&ekey
, data
, sizeof(uint32_t));
314 if (ekey
== ESD_ENDIAN_KEY
)
315 c
->swap_byte_order
= 0;
316 else if (ekey
== ESD_SWAP_ENDIAN_KEY
)
317 c
->swap_byte_order
= 1;
319 pa_log("client sent invalid endian key");
324 connection_write(c
, &ok
, sizeof(int));
328 static int esd_proto_stream_play(struct connection
*c
, PA_GCC_UNUSED esd_proto_t request
, const void *data
, size_t length
) {
329 char name
[ESD_NAME_MAX
], *utf8_name
;
330 int32_t format
, rate
;
333 pa_sink
*sink
= NULL
;
334 pa_sink_input_new_data sdata
;
336 assert(c
&& length
== (sizeof(int32_t)*2+ESD_NAME_MAX
));
338 memcpy(&format
, data
, sizeof(int32_t));
339 format
= MAYBE_INT32_SWAP(c
->swap_byte_order
, format
);
340 data
= (const char*)data
+ sizeof(int32_t);
342 memcpy(&rate
, data
, sizeof(int32_t));
343 rate
= MAYBE_INT32_SWAP(c
->swap_byte_order
, rate
);
344 data
= (const char*)data
+ sizeof(int32_t);
347 format_esd2native(format
, c
->swap_byte_order
, &ss
);
349 CHECK_VALIDITY(pa_sample_spec_valid(&ss
), "Invalid sample specification");
351 if (c
->protocol
->sink_name
) {
352 sink
= pa_namereg_get(c
->protocol
->core
, c
->protocol
->sink_name
, PA_NAMEREG_SINK
, 1);
353 CHECK_VALIDITY(sink
, "No such sink: %s", c
->protocol
->sink_name
);
356 strncpy(name
, data
, sizeof(name
));
357 name
[sizeof(name
)-1] = 0;
359 utf8_name
= pa_utf8_filter(name
);
360 pa_client_set_name(c
->client
, utf8_name
);
363 c
->original_name
= pa_xstrdup(name
);
365 assert(!c
->sink_input
&& !c
->input_memblockq
);
367 pa_sink_input_new_data_init(&sdata
);
369 sdata
.driver
= __FILE__
;
370 sdata
.name
= c
->client
->name
;
371 pa_sink_input_new_data_set_sample_spec(&sdata
, &ss
);
372 sdata
.module
= c
->protocol
->module
;
373 sdata
.client
= c
->client
;
375 c
->sink_input
= pa_sink_input_new(c
->protocol
->core
, &sdata
, 0);
376 CHECK_VALIDITY(c
->sink_input
, "Failed to create sink input.");
378 l
= (size_t) (pa_bytes_per_second(&ss
)*PLAYBACK_BUFFER_SECONDS
);
379 c
->input_memblockq
= pa_memblockq_new(
385 l
/PLAYBACK_BUFFER_FRAGMENTS
,
387 pa_iochannel_socket_set_rcvbuf(c
->io
, l
/PLAYBACK_BUFFER_FRAGMENTS
*2);
388 c
->playback
.fragment_size
= l
/10;
390 c
->sink_input
->peek
= sink_input_peek_cb
;
391 c
->sink_input
->drop
= sink_input_drop_cb
;
392 c
->sink_input
->kill
= sink_input_kill_cb
;
393 c
->sink_input
->get_latency
= sink_input_get_latency_cb
;
394 c
->sink_input
->userdata
= c
;
396 c
->state
= ESD_STREAMING_DATA
;
398 c
->protocol
->n_player
++;
403 static int esd_proto_stream_record(struct connection
*c
, esd_proto_t request
, const void *data
, size_t length
) {
404 char name
[ESD_NAME_MAX
], *utf8_name
;
405 int32_t format
, rate
;
406 pa_source
*source
= NULL
;
409 pa_source_output_new_data sdata
;
411 assert(c
&& length
== (sizeof(int32_t)*2+ESD_NAME_MAX
));
413 memcpy(&format
, data
, sizeof(int32_t));
414 format
= MAYBE_INT32_SWAP(c
->swap_byte_order
, format
);
415 data
= (const char*)data
+ sizeof(int32_t);
417 memcpy(&rate
, data
, sizeof(int32_t));
418 rate
= MAYBE_INT32_SWAP(c
->swap_byte_order
, rate
);
419 data
= (const char*)data
+ sizeof(int32_t);
422 format_esd2native(format
, c
->swap_byte_order
, &ss
);
424 CHECK_VALIDITY(pa_sample_spec_valid(&ss
), "Invalid sample specification.");
426 if (request
== ESD_PROTO_STREAM_MON
) {
429 if (!(sink
= pa_namereg_get(c
->protocol
->core
, c
->protocol
->sink_name
, PA_NAMEREG_SINK
, 1))) {
430 pa_log("no such sink.");
434 if (!(source
= sink
->monitor_source
)) {
435 pa_log("no such monitor source.");
439 assert(request
== ESD_PROTO_STREAM_REC
);
441 if (c
->protocol
->source_name
) {
442 if (!(source
= pa_namereg_get(c
->protocol
->core
, c
->protocol
->source_name
, PA_NAMEREG_SOURCE
, 1))) {
443 pa_log("no such source.");
449 strncpy(name
, data
, sizeof(name
));
450 name
[sizeof(name
)-1] = 0;
452 utf8_name
= pa_utf8_filter(name
);
453 pa_client_set_name(c
->client
, utf8_name
);
456 c
->original_name
= pa_xstrdup(name
);
458 assert(!c
->output_memblockq
&& !c
->source_output
);
460 pa_source_output_new_data_init(&sdata
);
461 sdata
.source
= source
;
462 sdata
.driver
= __FILE__
;
463 sdata
.name
= c
->client
->name
;
464 pa_source_output_new_data_set_sample_spec(&sdata
, &ss
);
465 sdata
.module
= c
->protocol
->module
;
466 sdata
.client
= c
->client
;
468 c
->source_output
= pa_source_output_new(c
->protocol
->core
, &sdata
, 9);
469 CHECK_VALIDITY(c
->source_output
, "Failed to create source_output.");
471 l
= (size_t) (pa_bytes_per_second(&ss
)*RECORD_BUFFER_SECONDS
);
472 c
->output_memblockq
= pa_memblockq_new(
480 pa_iochannel_socket_set_sndbuf(c
->io
, l
/RECORD_BUFFER_FRAGMENTS
*2);
482 c
->source_output
->push
= source_output_push_cb
;
483 c
->source_output
->kill
= source_output_kill_cb
;
484 c
->source_output
->get_latency
= source_output_get_latency_cb
;
485 c
->source_output
->userdata
= c
;
487 c
->state
= ESD_STREAMING_DATA
;
489 c
->protocol
->n_player
++;
494 static int esd_proto_get_latency(struct connection
*c
, PA_GCC_UNUSED esd_proto_t request
, const void *data
, size_t length
) {
498 assert(c
&& !data
&& length
== 0);
500 if (!(sink
= pa_namereg_get(c
->protocol
->core
, c
->protocol
->sink_name
, PA_NAMEREG_SINK
, 1)))
503 double usec
= pa_sink_get_latency(sink
);
504 latency
= (int) ((usec
*44100)/1000000);
507 latency
= MAYBE_INT32_SWAP(c
->swap_byte_order
, latency
);
508 connection_write(c
, &latency
, sizeof(int32_t));
512 static int esd_proto_server_info(struct connection
*c
, PA_GCC_UNUSED esd_proto_t request
, const void *data
, size_t length
) {
513 int32_t rate
= 44100, format
= ESD_STEREO
|ESD_BITS16
;
517 assert(c
&& data
&& length
== sizeof(int32_t));
519 if ((sink
= pa_namereg_get(c
->protocol
->core
, c
->protocol
->sink_name
, PA_NAMEREG_SINK
, 1))) {
520 rate
= sink
->sample_spec
.rate
;
521 format
= format_native2esd(&sink
->sample_spec
);
524 connection_write_prepare(c
, sizeof(int32_t) * 3);
527 connection_write(c
, &response
, sizeof(int32_t));
528 rate
= MAYBE_INT32_SWAP(c
->swap_byte_order
, rate
);
529 connection_write(c
, &rate
, sizeof(int32_t));
530 format
= MAYBE_INT32_SWAP(c
->swap_byte_order
, format
);
531 connection_write(c
, &format
, sizeof(int32_t));
536 static int esd_proto_all_info(struct connection
*c
, esd_proto_t request
, const void *data
, size_t length
) {
538 struct connection
*conn
;
539 uint32_t idx
= PA_IDXSET_INVALID
;
541 char terminator
[sizeof(int32_t)*6+ESD_NAME_MAX
];
543 assert(c
&& data
&& length
== sizeof(int32_t));
545 if (esd_proto_server_info(c
, request
, data
, length
) < 0)
548 k
= sizeof(int32_t)*5+ESD_NAME_MAX
;
549 s
= sizeof(int32_t)*6+ESD_NAME_MAX
;
550 nsamples
= c
->protocol
->core
->scache
? pa_idxset_size(c
->protocol
->core
->scache
) : 0;
551 t
= s
*(nsamples
+1) + k
*(c
->protocol
->n_player
+1);
553 connection_write_prepare(c
, t
);
555 memset(terminator
, 0, sizeof(terminator
));
557 for (conn
= pa_idxset_first(c
->protocol
->connections
, &idx
); conn
; conn
= pa_idxset_next(c
->protocol
->connections
, &idx
)) {
558 int32_t id
, format
= ESD_BITS16
| ESD_STEREO
, rate
= 44100, lvolume
= ESD_VOLUME_BASE
, rvolume
= ESD_VOLUME_BASE
;
559 char name
[ESD_NAME_MAX
];
561 if (conn
->state
!= ESD_STREAMING_DATA
)
566 if (conn
->sink_input
) {
567 pa_cvolume volume
= *pa_sink_input_get_volume(conn
->sink_input
);
568 rate
= conn
->sink_input
->sample_spec
.rate
;
569 lvolume
= (volume
.values
[0]*ESD_VOLUME_BASE
)/PA_VOLUME_NORM
;
570 rvolume
= (volume
.values
[1]*ESD_VOLUME_BASE
)/PA_VOLUME_NORM
;
571 format
= format_native2esd(&conn
->sink_input
->sample_spec
);
575 id
= MAYBE_INT32_SWAP(c
->swap_byte_order
, (int32_t) (conn
->index
+1));
576 connection_write(c
, &id
, sizeof(int32_t));
579 memset(name
, 0, ESD_NAME_MAX
); /* don't leak old data */
580 if (conn
->original_name
)
581 strncpy(name
, conn
->original_name
, ESD_NAME_MAX
);
582 else if (conn
->client
&& conn
->client
->name
)
583 strncpy(name
, conn
->client
->name
, ESD_NAME_MAX
);
584 connection_write(c
, name
, ESD_NAME_MAX
);
587 rate
= MAYBE_INT32_SWAP(c
->swap_byte_order
, rate
);
588 connection_write(c
, &rate
, sizeof(int32_t));
591 lvolume
= MAYBE_INT32_SWAP(c
->swap_byte_order
, lvolume
);
592 connection_write(c
, &lvolume
, sizeof(int32_t));
595 rvolume
= MAYBE_INT32_SWAP(c
->swap_byte_order
, rvolume
);
596 connection_write(c
, &rvolume
, sizeof(int32_t));
599 format
= MAYBE_INT32_SWAP(c
->swap_byte_order
, format
);
600 connection_write(c
, &format
, sizeof(int32_t));
605 assert(t
== s
*(nsamples
+1)+k
);
608 connection_write(c
, terminator
, k
);
613 idx
= PA_IDXSET_INVALID
;
614 for (ce
= pa_idxset_first(c
->protocol
->core
->scache
, &idx
); ce
; ce
= pa_idxset_next(c
->protocol
->core
->scache
, &idx
)) {
615 int32_t id
, rate
, lvolume
, rvolume
, format
, len
;
616 char name
[ESD_NAME_MAX
];
621 id
= MAYBE_INT32_SWAP(c
->swap_byte_order
, (int) (ce
->index
+1));
622 connection_write(c
, &id
, sizeof(int32_t));
625 memset(name
, 0, ESD_NAME_MAX
); /* don't leak old data */
626 if (strncmp(ce
->name
, SCACHE_PREFIX
, sizeof(SCACHE_PREFIX
)-1) == 0)
627 strncpy(name
, ce
->name
+sizeof(SCACHE_PREFIX
)-1, ESD_NAME_MAX
);
629 snprintf(name
, ESD_NAME_MAX
, "native.%s", ce
->name
);
630 connection_write(c
, name
, ESD_NAME_MAX
);
633 rate
= MAYBE_UINT32_SWAP(c
->swap_byte_order
, ce
->sample_spec
.rate
);
634 connection_write(c
, &rate
, sizeof(int32_t));
637 lvolume
= MAYBE_UINT32_SWAP(c
->swap_byte_order
, (ce
->volume
.values
[0]*ESD_VOLUME_BASE
)/PA_VOLUME_NORM
);
638 connection_write(c
, &lvolume
, sizeof(int32_t));
641 rvolume
= MAYBE_UINT32_SWAP(c
->swap_byte_order
, (ce
->volume
.values
[0]*ESD_VOLUME_BASE
)/PA_VOLUME_NORM
);
642 connection_write(c
, &rvolume
, sizeof(int32_t));
645 format
= MAYBE_INT32_SWAP(c
->swap_byte_order
, format_native2esd(&ce
->sample_spec
));
646 connection_write(c
, &format
, sizeof(int32_t));
649 len
= MAYBE_INT32_SWAP(c
->swap_byte_order
, (int) ce
->memchunk
.length
);
650 connection_write(c
, &len
, sizeof(int32_t));
658 connection_write(c
, terminator
, s
);
663 static int esd_proto_stream_pan(struct connection
*c
, PA_GCC_UNUSED esd_proto_t request
, const void *data
, size_t length
) {
665 uint32_t idx
, lvolume
, rvolume
;
666 struct connection
*conn
;
668 assert(c
&& data
&& length
== sizeof(int32_t)*3);
670 memcpy(&idx
, data
, sizeof(uint32_t));
671 idx
= MAYBE_UINT32_SWAP(c
->swap_byte_order
, idx
) - 1;
672 data
= (const char*)data
+ sizeof(uint32_t);
674 memcpy(&lvolume
, data
, sizeof(uint32_t));
675 lvolume
= MAYBE_UINT32_SWAP(c
->swap_byte_order
, lvolume
);
676 data
= (const char*)data
+ sizeof(uint32_t);
678 memcpy(&rvolume
, data
, sizeof(uint32_t));
679 rvolume
= MAYBE_UINT32_SWAP(c
->swap_byte_order
, rvolume
);
680 data
= (const char*)data
+ sizeof(uint32_t);
682 if ((conn
= pa_idxset_get_by_index(c
->protocol
->connections
, idx
)) && conn
->sink_input
) {
684 volume
.values
[0] = (lvolume
*PA_VOLUME_NORM
)/ESD_VOLUME_BASE
;
685 volume
.values
[1] = (rvolume
*PA_VOLUME_NORM
)/ESD_VOLUME_BASE
;
687 pa_sink_input_set_volume(conn
->sink_input
, &volume
);
692 connection_write(c
, &ok
, sizeof(int32_t));
697 static int esd_proto_sample_cache(struct connection
*c
, PA_GCC_UNUSED esd_proto_t request
, const void *data
, size_t length
) {
699 int32_t format
, rate
, sc_length
;
701 char name
[ESD_NAME_MAX
+sizeof(SCACHE_PREFIX
)-1];
703 assert(c
&& data
&& length
== (ESD_NAME_MAX
+3*sizeof(int32_t)));
705 memcpy(&format
, data
, sizeof(int32_t));
706 format
= MAYBE_INT32_SWAP(c
->swap_byte_order
, format
);
707 data
= (const char*)data
+ sizeof(int32_t);
709 memcpy(&rate
, data
, sizeof(int32_t));
710 rate
= MAYBE_INT32_SWAP(c
->swap_byte_order
, rate
);
711 data
= (const char*)data
+ sizeof(int32_t);
714 format_esd2native(format
, c
->swap_byte_order
, &ss
);
716 CHECK_VALIDITY(pa_sample_spec_valid(&ss
), "Invalid sample specification.");
718 memcpy(&sc_length
, data
, sizeof(int32_t));
719 sc_length
= MAYBE_INT32_SWAP(c
->swap_byte_order
, sc_length
);
720 data
= (const char*)data
+ sizeof(int32_t);
722 CHECK_VALIDITY(sc_length
<= MAX_CACHE_SAMPLE_SIZE
, "Sample too large (%d bytes).", (int)sc_length
);
724 strcpy(name
, SCACHE_PREFIX
);
725 strncpy(name
+sizeof(SCACHE_PREFIX
)-1, data
, ESD_NAME_MAX
);
726 name
[sizeof(name
)-1] = 0;
728 CHECK_VALIDITY(pa_utf8_valid(name
), "Invalid UTF8 in sample name.");
730 assert(!c
->scache
.memchunk
.memblock
);
731 c
->scache
.memchunk
.memblock
= pa_memblock_new(c
->protocol
->core
->mempool
, sc_length
);
732 c
->scache
.memchunk
.index
= 0;
733 c
->scache
.memchunk
.length
= sc_length
;
734 c
->scache
.sample_spec
= ss
;
735 assert(!c
->scache
.name
);
736 c
->scache
.name
= pa_xstrdup(name
);
738 c
->state
= ESD_CACHING_SAMPLE
;
740 pa_scache_add_item(c
->protocol
->core
, c
->scache
.name
, NULL
, NULL
, NULL
, &idx
);
743 connection_write(c
, &idx
, sizeof(uint32_t));
748 static int esd_proto_sample_get_id(struct connection
*c
, PA_GCC_UNUSED esd_proto_t request
, const void *data
, size_t length
) {
751 char name
[ESD_NAME_MAX
+sizeof(SCACHE_PREFIX
)-1];
753 assert(c
&& data
&& length
== ESD_NAME_MAX
);
755 strcpy(name
, SCACHE_PREFIX
);
756 strncpy(name
+sizeof(SCACHE_PREFIX
)-1, data
, ESD_NAME_MAX
);
757 name
[sizeof(name
)-1] = 0;
759 CHECK_VALIDITY(pa_utf8_valid(name
), "Invalid UTF8 in sample name.");
762 if ((idx
= pa_scache_get_id_by_name(c
->protocol
->core
, name
)) != PA_IDXSET_INVALID
)
765 connection_write(c
, &ok
, sizeof(int32_t));
770 static int esd_proto_sample_free_or_play(struct connection
*c
, esd_proto_t request
, const void *data
, size_t length
) {
775 assert(c
&& data
&& length
== sizeof(int32_t));
777 memcpy(&idx
, data
, sizeof(uint32_t));
778 idx
= MAYBE_UINT32_SWAP(c
->swap_byte_order
, idx
) - 1;
782 if ((name
= pa_scache_get_name_by_id(c
->protocol
->core
, idx
))) {
783 if (request
== ESD_PROTO_SAMPLE_PLAY
) {
786 if ((sink
= pa_namereg_get(c
->protocol
->core
, c
->protocol
->sink_name
, PA_NAMEREG_SINK
, 1)))
787 if (pa_scache_play_item(c
->protocol
->core
, name
, sink
, PA_VOLUME_NORM
) >= 0)
790 assert(request
== ESD_PROTO_SAMPLE_FREE
);
792 if (pa_scache_remove_item(c
->protocol
->core
, name
) >= 0)
797 connection_write(c
, &ok
, sizeof(int32_t));
802 static int esd_proto_standby_or_resume(struct connection
*c
, PA_GCC_UNUSED esd_proto_t request
, PA_GCC_UNUSED
const void *data
, PA_GCC_UNUSED
size_t length
) {
805 connection_write_prepare(c
, sizeof(int32_t) * 2);
808 connection_write(c
, &ok
, sizeof(int32_t));
809 connection_write(c
, &ok
, sizeof(int32_t));
814 /*** client callbacks ***/
816 static void client_kill_cb(pa_client
*c
) {
817 assert(c
&& c
->userdata
);
818 connection_free(c
->userdata
);
821 /*** pa_iochannel callbacks ***/
823 static int do_read(struct connection
*c
) {
826 /* pa_log("READ"); */
828 if (c
->state
== ESD_NEXT_REQUEST
) {
830 assert(c
->read_data_length
< sizeof(c
->request
));
832 if ((r
= pa_iochannel_read(c
->io
, ((uint8_t*) &c
->request
) + c
->read_data_length
, sizeof(c
->request
) - c
->read_data_length
)) <= 0) {
833 pa_log_debug("read(): %s", r
< 0 ? pa_cstrerror(errno
) : "EOF");
837 if ((c
->read_data_length
+= r
) >= sizeof(c
->request
)) {
838 struct proto_handler
*handler
;
840 c
->request
= MAYBE_INT32_SWAP(c
->swap_byte_order
, c
->request
);
842 if (c
->request
< ESD_PROTO_CONNECT
|| c
->request
> ESD_PROTO_MAX
) {
843 pa_log("recieved invalid request.");
847 handler
= proto_map
+c
->request
;
849 /* pa_log("executing request #%u", c->request); */
851 if (!handler
->proc
) {
852 pa_log("recieved unimplemented request #%u.", c
->request
);
856 if (handler
->data_length
== 0) {
857 c
->read_data_length
= 0;
859 if (handler
->proc(c
, c
->request
, NULL
, 0) < 0)
863 if (c
->read_data_alloc
< handler
->data_length
)
864 c
->read_data
= pa_xrealloc(c
->read_data
, c
->read_data_alloc
= handler
->data_length
);
865 assert(c
->read_data
);
867 c
->state
= ESD_NEEDS_REQDATA
;
868 c
->read_data_length
= 0;
872 } else if (c
->state
== ESD_NEEDS_REQDATA
) {
874 struct proto_handler
*handler
= proto_map
+c
->request
;
876 assert(handler
->proc
);
878 assert(c
->read_data
&& c
->read_data_length
< handler
->data_length
);
880 if ((r
= pa_iochannel_read(c
->io
, (uint8_t*) c
->read_data
+ c
->read_data_length
, handler
->data_length
- c
->read_data_length
)) <= 0) {
881 pa_log_debug("read(): %s", r
< 0 ? pa_cstrerror(errno
) : "EOF");
885 if ((c
->read_data_length
+= r
) >= handler
->data_length
) {
886 size_t l
= c
->read_data_length
;
887 assert(handler
->proc
);
889 c
->state
= ESD_NEXT_REQUEST
;
890 c
->read_data_length
= 0;
892 if (handler
->proc(c
, c
->request
, c
->read_data
, l
) < 0)
895 } else if (c
->state
== ESD_CACHING_SAMPLE
) {
899 assert(c
->scache
.memchunk
.memblock
);
900 assert(c
->scache
.name
);
901 assert(c
->scache
.memchunk
.index
< c
->scache
.memchunk
.length
);
903 p
= pa_memblock_acquire(c
->scache
.memchunk
.memblock
);
905 if ((r
= pa_iochannel_read(c
->io
, (uint8_t*) p
+c
->scache
.memchunk
.index
, c
->scache
.memchunk
.length
-c
->scache
.memchunk
.index
)) <= 0) {
906 pa_memblock_release(c
->scache
.memchunk
.memblock
);
907 pa_log_debug("read(): %s", r
< 0 ? pa_cstrerror(errno
) : "EOF");
911 pa_memblock_release(c
->scache
.memchunk
.memblock
);
913 c
->scache
.memchunk
.index
+= r
;
914 assert(c
->scache
.memchunk
.index
<= c
->scache
.memchunk
.length
);
916 if (c
->scache
.memchunk
.index
== c
->scache
.memchunk
.length
) {
919 c
->scache
.memchunk
.index
= 0;
920 pa_scache_add_item(c
->protocol
->core
, c
->scache
.name
, &c
->scache
.sample_spec
, NULL
, &c
->scache
.memchunk
, &idx
);
922 pa_memblock_unref(c
->scache
.memchunk
.memblock
);
923 c
->scache
.memchunk
.memblock
= NULL
;
924 c
->scache
.memchunk
.index
= c
->scache
.memchunk
.length
= 0;
926 pa_xfree(c
->scache
.name
);
927 c
->scache
.name
= NULL
;
929 c
->state
= ESD_NEXT_REQUEST
;
932 connection_write(c
, &idx
, sizeof(uint32_t));
935 } else if (c
->state
== ESD_STREAMING_DATA
&& c
->sink_input
) {
941 assert(c
->input_memblockq
);
943 /* pa_log("STREAMING_DATA"); */
945 if (!(l
= pa_memblockq_missing(c
->input_memblockq
)))
948 if (l
> c
->playback
.fragment_size
)
949 l
= c
->playback
.fragment_size
;
951 if (c
->playback
.current_memblock
)
952 if (pa_memblock_get_length(c
->playback
.current_memblock
) - c
->playback
.memblock_index
< l
) {
953 pa_memblock_unref(c
->playback
.current_memblock
);
954 c
->playback
.current_memblock
= NULL
;
955 c
->playback
.memblock_index
= 0;
958 if (!c
->playback
.current_memblock
) {
959 c
->playback
.current_memblock
= pa_memblock_new(c
->protocol
->core
->mempool
, c
->playback
.fragment_size
*2);
960 assert(c
->playback
.current_memblock
);
961 assert(pa_memblock_get_length(c
->playback
.current_memblock
) >= l
);
962 c
->playback
.memblock_index
= 0;
965 p
= pa_memblock_acquire(c
->playback
.current_memblock
);
967 if ((r
= pa_iochannel_read(c
->io
, (uint8_t*) p
+c
->playback
.memblock_index
, l
)) <= 0) {
968 pa_memblock_release(c
->playback
.current_memblock
);
969 pa_log_debug("read(): %s", r
< 0 ? pa_cstrerror(errno
) : "EOF");
972 pa_memblock_release(c
->playback
.current_memblock
);
974 chunk
.memblock
= c
->playback
.current_memblock
;
975 chunk
.index
= c
->playback
.memblock_index
;
977 assert(chunk
.memblock
);
979 c
->playback
.memblock_index
+= r
;
981 assert(c
->input_memblockq
);
982 pa_memblockq_push_align(c
->input_memblockq
, &chunk
);
983 assert(c
->sink_input
);
984 pa_sink_notify(c
->sink_input
->sink
);
990 static int do_write(struct connection
*c
) {
993 /* pa_log("WRITE"); */
995 if (c
->write_data_length
) {
998 assert(c
->write_data_index
< c
->write_data_length
);
999 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) {
1000 pa_log("write(): %s", pa_cstrerror(errno
));
1004 if ((c
->write_data_index
+=r
) >= c
->write_data_length
)
1005 c
->write_data_length
= c
->write_data_index
= 0;
1007 } else if (c
->state
== ESD_STREAMING_DATA
&& c
->source_output
) {
1012 assert(c
->output_memblockq
);
1013 if (pa_memblockq_peek(c
->output_memblockq
, &chunk
) < 0)
1016 assert(chunk
.memblock
);
1017 assert(chunk
.length
);
1019 p
= pa_memblock_acquire(chunk
.memblock
);
1021 if ((r
= pa_iochannel_write(c
->io
, (uint8_t*) p
+chunk
.index
, chunk
.length
)) < 0) {
1022 pa_memblock_release(chunk
.memblock
);
1023 pa_memblock_unref(chunk
.memblock
);
1024 pa_log("write(): %s", pa_cstrerror(errno
));
1028 pa_memblock_release(chunk
.memblock
);
1030 pa_memblockq_drop(c
->output_memblockq
, &chunk
, r
);
1031 pa_memblock_unref(chunk
.memblock
);
1033 pa_source_notify(c
->source_output
->source
);
1039 static void do_work(struct connection
*c
) {
1042 assert(c
->protocol
&& c
->protocol
->core
&& c
->protocol
->core
->mainloop
&& c
->protocol
->core
->mainloop
->defer_enable
);
1043 c
->protocol
->core
->mainloop
->defer_enable(c
->defer_event
, 0);
1048 if (pa_iochannel_is_readable(c
->io
)) {
1053 if (c
->state
== ESD_STREAMING_DATA
&& c
->source_output
&& pa_iochannel_is_hungup(c
->io
))
1054 /* In case we are in capture mode we will never call read()
1055 * on the socket, hence we need to detect the hangup manually
1056 * here, instead of simply waiting for read() to return 0. */
1059 if (pa_iochannel_is_writable(c
->io
))
1060 if (do_write(c
) < 0)
1067 if (c
->state
== ESD_STREAMING_DATA
&& c
->sink_input
) {
1070 pa_iochannel_free(c
->io
);
1073 pa_memblockq_prebuf_disable(c
->input_memblockq
);
1074 pa_sink_notify(c
->sink_input
->sink
);
1079 static void io_callback(pa_iochannel
*io
, void *userdata
) {
1080 struct connection
*c
= userdata
;
1081 assert(io
&& c
&& c
->io
== io
);
1086 /*** defer callback ***/
1088 static void defer_callback(pa_mainloop_api
*a
, pa_defer_event
*e
, void *userdata
) {
1089 struct connection
*c
= userdata
;
1090 assert(a
&& c
&& c
->defer_event
== e
);
1092 /* pa_log("DEFER"); */
1097 /*** sink_input callbacks ***/
1099 static int sink_input_peek_cb(pa_sink_input
*i
, pa_memchunk
*chunk
) {
1100 struct connection
*c
;
1101 assert(i
&& i
->userdata
&& chunk
);
1104 if (pa_memblockq_peek(c
->input_memblockq
, chunk
) < 0) {
1115 static void sink_input_drop_cb(pa_sink_input
*i
, const pa_memchunk
*chunk
, size_t length
) {
1116 struct connection
*c
= i
->userdata
;
1117 assert(i
&& c
&& length
);
1119 /* pa_log("DROP"); */
1121 pa_memblockq_drop(c
->input_memblockq
, chunk
, length
);
1124 assert(c
->protocol
&& c
->protocol
->core
&& c
->protocol
->core
->mainloop
&& c
->protocol
->core
->mainloop
->defer_enable
);
1127 c
->protocol
->core
->mainloop
->defer_enable(c
->defer_event
, 1);
1129 /* assert(pa_memblockq_get_length(c->input_memblockq) > 2048); */
1132 static void sink_input_kill_cb(pa_sink_input
*i
) {
1133 assert(i
&& i
->userdata
);
1134 connection_free((struct connection
*) i
->userdata
);
1137 static pa_usec_t
sink_input_get_latency_cb(pa_sink_input
*i
) {
1138 struct connection
*c
= i
->userdata
;
1140 return pa_bytes_to_usec(pa_memblockq_get_length(c
->input_memblockq
), &c
->sink_input
->sample_spec
);
1143 /*** source_output callbacks ***/
1145 static void source_output_push_cb(pa_source_output
*o
, const pa_memchunk
*chunk
) {
1146 struct connection
*c
= o
->userdata
;
1147 assert(o
&& c
&& chunk
);
1149 pa_memblockq_push(c
->output_memblockq
, chunk
);
1152 assert(c
->protocol
&& c
->protocol
->core
&& c
->protocol
->core
->mainloop
&& c
->protocol
->core
->mainloop
->defer_enable
);
1155 c
->protocol
->core
->mainloop
->defer_enable(c
->defer_event
, 1);
1158 static void source_output_kill_cb(pa_source_output
*o
) {
1159 assert(o
&& o
->userdata
);
1160 connection_free((struct connection
*) o
->userdata
);
1163 static pa_usec_t
source_output_get_latency_cb(pa_source_output
*o
) {
1164 struct connection
*c
= o
->userdata
;
1166 return pa_bytes_to_usec(pa_memblockq_get_length(c
->output_memblockq
), &c
->source_output
->sample_spec
);
1169 /*** socket server callback ***/
1171 static void auth_timeout(pa_mainloop_api
*m
, pa_time_event
*e
, const struct timeval
*tv
, void *userdata
) {
1172 struct connection
*c
= userdata
;
1173 assert(m
&& tv
&& c
&& c
->auth_timeout_event
== e
);
1179 static void on_connection(pa_socket_server
*s
, pa_iochannel
*io
, void *userdata
) {
1180 struct connection
*c
;
1181 pa_protocol_esound
*p
= userdata
;
1182 char cname
[256], pname
[128];
1183 assert(s
&& io
&& p
);
1185 if (pa_idxset_size(p
->connections
)+1 > MAX_CONNECTIONS
) {
1186 pa_log("Warning! Too many connections (%u), dropping incoming connection.", MAX_CONNECTIONS
);
1187 pa_iochannel_free(io
);
1191 c
= pa_xnew(struct connection
, 1);
1194 pa_iochannel_set_callback(c
->io
, io_callback
, c
);
1196 pa_iochannel_socket_peer_to_string(io
, pname
, sizeof(pname
));
1197 snprintf(cname
, sizeof(cname
), "EsounD client (%s)", pname
);
1199 c
->client
= pa_client_new(p
->core
, __FILE__
, cname
);
1201 c
->client
->owner
= p
->module
;
1202 c
->client
->kill
= client_kill_cb
;
1203 c
->client
->userdata
= c
;
1205 c
->authorized
= !!p
->public;
1206 c
->swap_byte_order
= 0;
1209 c
->read_data_length
= 0;
1210 c
->read_data
= pa_xmalloc(c
->read_data_alloc
= proto_map
[ESD_PROTO_CONNECT
].data_length
);
1212 c
->write_data_length
= c
->write_data_index
= c
->write_data_alloc
= 0;
1213 c
->write_data
= NULL
;
1215 c
->state
= ESD_NEEDS_REQDATA
;
1216 c
->request
= ESD_PROTO_CONNECT
;
1218 c
->sink_input
= NULL
;
1219 c
->input_memblockq
= NULL
;
1221 c
->source_output
= NULL
;
1222 c
->output_memblockq
= NULL
;
1224 c
->playback
.current_memblock
= NULL
;
1225 c
->playback
.memblock_index
= 0;
1226 c
->playback
.fragment_size
= 0;
1228 c
->scache
.memchunk
.length
= c
->scache
.memchunk
.index
= 0;
1229 c
->scache
.memchunk
.memblock
= NULL
;
1230 c
->scache
.name
= NULL
;
1232 c
->original_name
= NULL
;
1234 if (!c
->authorized
&& p
->auth_ip_acl
&& pa_ip_acl_check(p
->auth_ip_acl
, pa_iochannel_get_recv_fd(io
)) > 0) {
1235 pa_log_info("Client authenticated by IP ACL.");
1239 if (!c
->authorized
) {
1241 pa_gettimeofday(&tv
);
1242 tv
.tv_sec
+= AUTH_TIMEOUT
;
1243 c
->auth_timeout_event
= p
->core
->mainloop
->time_new(p
->core
->mainloop
, &tv
, auth_timeout
, c
);
1245 c
->auth_timeout_event
= NULL
;
1247 c
->defer_event
= p
->core
->mainloop
->defer_new(p
->core
->mainloop
, defer_callback
, c
);
1248 assert(c
->defer_event
);
1249 p
->core
->mainloop
->defer_enable(c
->defer_event
, 0);
1251 pa_idxset_put(p
->connections
, c
, &c
->index
);
1254 /*** entry points ***/
1256 pa_protocol_esound
* pa_protocol_esound_new(pa_core
*core
, pa_socket_server
*server
, pa_module
*m
, pa_modargs
*ma
) {
1257 pa_protocol_esound
*p
;
1266 p
= pa_xnew(pa_protocol_esound
, 1);
1268 if (pa_modargs_get_value_boolean(ma
, "auth-anonymous", &public) < 0) {
1269 pa_log("auth-anonymous= expects a boolean argument.");
1273 if (pa_authkey_load_auto(pa_modargs_get_value(ma
, "cookie", DEFAULT_COOKIE_FILE
), p
->esd_key
, sizeof(p
->esd_key
)) < 0)
1276 if ((acl
= pa_modargs_get_value(ma
, "auth-ip-acl", NULL
))) {
1278 if (!(p
->auth_ip_acl
= pa_ip_acl_new(acl
))) {
1279 pa_log("Failed to parse IP ACL '%s'", acl
);
1283 p
->auth_ip_acl
= NULL
;
1288 pa_socket_server_set_callback(p
->server
, on_connection
, p
);
1290 p
->connections
= pa_idxset_new(NULL
, NULL
);
1291 assert(p
->connections
);
1293 p
->sink_name
= pa_xstrdup(pa_modargs_get_value(ma
, "sink", NULL
));
1294 p
->source_name
= pa_xstrdup(pa_modargs_get_value(ma
, "source", NULL
));
1304 void pa_protocol_esound_free(pa_protocol_esound
*p
) {
1305 struct connection
*c
;
1308 while ((c
= pa_idxset_first(p
->connections
, NULL
)))
1311 pa_idxset_free(p
->connections
, NULL
, NULL
);
1312 pa_socket_server_unref(p
->server
);
1315 pa_ip_acl_free(p
->auth_ip_acl
);