]> code.delx.au - pulseaudio/blob - src/pulsecore/protocol-esound.c
Remove unnecessary #includes
[pulseaudio] / src / pulsecore / protocol-esound.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
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.
11
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.
16
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
20 USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <errno.h>
28 #include <string.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31
32 #include <pulse/rtclock.h>
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>
38
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/namereg.h>
49 #include <pulsecore/log.h>
50 #include <pulsecore/core-util.h>
51 #include <pulsecore/core-error.h>
52 #include <pulsecore/ipacl.h>
53 #include <pulsecore/macro.h>
54 #include <pulsecore/thread-mq.h>
55 #include <pulsecore/shared.h>
56 #include <pulsecore/endianmacros.h>
57
58 #include "protocol-esound.h"
59
60 /* Don't accept more connection than this */
61 #define MAX_CONNECTIONS 64
62
63 /* Kick a client if it doesn't authenticate within this time */
64 #define AUTH_TIMEOUT (5*PA_USEC_PER_SEC)
65
66 #define DEFAULT_COOKIE_FILE ".esd_auth"
67
68 #define PLAYBACK_BUFFER_SECONDS (.25)
69 #define PLAYBACK_BUFFER_FRAGMENTS (10)
70 #define RECORD_BUFFER_SECONDS (5)
71
72 #define MAX_CACHE_SAMPLE_SIZE (2048000)
73
74 #define DEFAULT_SINK_LATENCY (150*PA_USEC_PER_MSEC)
75 #define DEFAULT_SOURCE_LATENCY (150*PA_USEC_PER_MSEC)
76
77 #define SCACHE_PREFIX "esound."
78
79 /* This is heavily based on esound's code */
80
81 typedef struct connection {
82 pa_msgobject parent;
83
84 uint32_t index;
85 pa_bool_t dead;
86 pa_esound_protocol *protocol;
87 pa_esound_options *options;
88 pa_iochannel *io;
89 pa_client *client;
90 pa_bool_t authorized, swap_byte_order;
91 void *write_data;
92 size_t write_data_alloc, write_data_index, write_data_length;
93 void *read_data;
94 size_t read_data_alloc, read_data_length;
95 esd_proto_t request;
96 esd_client_state_t state;
97 pa_sink_input *sink_input;
98 pa_source_output *source_output;
99 pa_memblockq *input_memblockq, *output_memblockq;
100 pa_defer_event *defer_event;
101
102 char *original_name;
103
104 struct {
105 pa_memblock *current_memblock;
106 size_t memblock_index;
107 pa_atomic_t missing;
108 pa_bool_t underrun;
109 } playback;
110
111 struct {
112 pa_memchunk memchunk;
113 char *name;
114 pa_sample_spec sample_spec;
115 } scache;
116
117 pa_time_event *auth_timeout_event;
118 } connection;
119
120 PA_DEFINE_PRIVATE_CLASS(connection, pa_msgobject);
121 #define CONNECTION(o) (connection_cast(o))
122
123 struct pa_esound_protocol {
124 PA_REFCNT_DECLARE;
125
126 pa_core *core;
127 pa_idxset *connections;
128 unsigned n_player;
129 };
130
131 enum {
132 SINK_INPUT_MESSAGE_POST_DATA = PA_SINK_INPUT_MESSAGE_MAX, /* data from main loop to sink input */
133 SINK_INPUT_MESSAGE_DISABLE_PREBUF
134 };
135
136 enum {
137 CONNECTION_MESSAGE_REQUEST_DATA,
138 CONNECTION_MESSAGE_POST_DATA,
139 CONNECTION_MESSAGE_UNLINK_CONNECTION
140 };
141
142 typedef struct proto_handler {
143 size_t data_length;
144 int (*proc)(connection *c, esd_proto_t request, const void *data, size_t length);
145 const char *description;
146 } esd_proto_handler_info_t;
147
148 static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk);
149 static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes);
150 static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes);
151 static void sink_input_kill_cb(pa_sink_input *i);
152 static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk);
153 static pa_usec_t source_output_get_latency_cb(pa_source_output *o);
154
155 static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk);
156 static void source_output_kill_cb(pa_source_output *o);
157
158 static int esd_proto_connect(connection *c, esd_proto_t request, const void *data, size_t length);
159 static int esd_proto_stream_play(connection *c, esd_proto_t request, const void *data, size_t length);
160 static int esd_proto_stream_record(connection *c, esd_proto_t request, const void *data, size_t length);
161 static int esd_proto_get_latency(connection *c, esd_proto_t request, const void *data, size_t length);
162 static int esd_proto_server_info(connection *c, esd_proto_t request, const void *data, size_t length);
163 static int esd_proto_all_info(connection *c, esd_proto_t request, const void *data, size_t length);
164 static int esd_proto_stream_pan(connection *c, esd_proto_t request, const void *data, size_t length);
165 static int esd_proto_sample_pan(connection *c, esd_proto_t request, const void *data, size_t length);
166 static int esd_proto_sample_cache(connection *c, esd_proto_t request, const void *data, size_t length);
167 static int esd_proto_sample_free_or_play(connection *c, esd_proto_t request, const void *data, size_t length);
168 static int esd_proto_sample_get_id(connection *c, esd_proto_t request, const void *data, size_t length);
169 static int esd_proto_standby_or_resume(connection *c, esd_proto_t request, const void *data, size_t length);
170 static int esd_proto_standby_mode(connection *c, esd_proto_t request, const void *data, size_t length);
171
172 /* the big map of protocol handler info */
173 static struct proto_handler proto_map[ESD_PROTO_MAX] = {
174 { ESD_KEY_LEN + sizeof(int), esd_proto_connect, "connect" },
175 { ESD_KEY_LEN + sizeof(int), NULL, "lock" },
176 { ESD_KEY_LEN + sizeof(int), NULL, "unlock" },
177
178 { ESD_NAME_MAX + 2 * sizeof(int), esd_proto_stream_play, "stream play" },
179 { ESD_NAME_MAX + 2 * sizeof(int), esd_proto_stream_record, "stream rec" },
180 { ESD_NAME_MAX + 2 * sizeof(int), esd_proto_stream_record, "stream mon" },
181
182 { ESD_NAME_MAX + 3 * sizeof(int), esd_proto_sample_cache, "sample cache" }, /* 6 */
183 { sizeof(int), esd_proto_sample_free_or_play, "sample free" },
184 { sizeof(int), esd_proto_sample_free_or_play, "sample play" }, /* 8 */
185 { sizeof(int), NULL, "sample loop" },
186 { sizeof(int), NULL, "sample stop" },
187 { (size_t) -1, NULL, "TODO: sample kill" },
188
189 { ESD_KEY_LEN + sizeof(int), esd_proto_standby_or_resume, "standby" },
190 { ESD_KEY_LEN + sizeof(int), esd_proto_standby_or_resume, "resume" }, /* 13 */
191
192 { ESD_NAME_MAX, esd_proto_sample_get_id, "sample getid" }, /* 14 */
193 { ESD_NAME_MAX + 2 * sizeof(int), NULL, "stream filter" },
194
195 { sizeof(int), esd_proto_server_info, "server info" },
196 { sizeof(int), esd_proto_all_info, "all info" },
197 { (size_t) -1, NULL, "TODO: subscribe" },
198 { (size_t) -1, NULL, "TODO: unsubscribe" },
199
200 { 3 * sizeof(int), esd_proto_stream_pan, "stream pan"},
201 { 3 * sizeof(int), esd_proto_sample_pan, "sample pan" },
202
203 { sizeof(int), esd_proto_standby_mode, "standby mode" },
204 { 0, esd_proto_get_latency, "get latency" }
205 };
206
207 static void connection_unlink(connection *c) {
208 pa_assert(c);
209
210 if (!c->protocol)
211 return;
212
213 if (c->options) {
214 pa_esound_options_unref(c->options);
215 c->options = NULL;
216 }
217
218 if (c->sink_input) {
219 pa_sink_input_unlink(c->sink_input);
220 pa_sink_input_unref(c->sink_input);
221 c->sink_input = NULL;
222 }
223
224 if (c->source_output) {
225 pa_source_output_unlink(c->source_output);
226 pa_source_output_unref(c->source_output);
227 c->source_output = NULL;
228 }
229
230 if (c->client) {
231 pa_client_free(c->client);
232 c->client = NULL;
233 }
234
235 if (c->state == ESD_STREAMING_DATA)
236 c->protocol->n_player--;
237
238 if (c->io) {
239 pa_iochannel_free(c->io);
240 c->io = NULL;
241 }
242
243 if (c->defer_event) {
244 c->protocol->core->mainloop->defer_free(c->defer_event);
245 c->defer_event = NULL;
246 }
247
248 if (c->auth_timeout_event) {
249 c->protocol->core->mainloop->time_free(c->auth_timeout_event);
250 c->auth_timeout_event = NULL;
251 }
252
253 pa_assert_se(pa_idxset_remove_by_data(c->protocol->connections, c, NULL) == c);
254 c->protocol = NULL;
255 connection_unref(c);
256 }
257
258 static void connection_free(pa_object *obj) {
259 connection *c = CONNECTION(obj);
260 pa_assert(c);
261
262 if (c->input_memblockq)
263 pa_memblockq_free(c->input_memblockq);
264 if (c->output_memblockq)
265 pa_memblockq_free(c->output_memblockq);
266
267 if (c->playback.current_memblock)
268 pa_memblock_unref(c->playback.current_memblock);
269
270 pa_xfree(c->read_data);
271 pa_xfree(c->write_data);
272
273 if (c->scache.memchunk.memblock)
274 pa_memblock_unref(c->scache.memchunk.memblock);
275 pa_xfree(c->scache.name);
276
277 pa_xfree(c->original_name);
278 pa_xfree(c);
279 }
280
281 static void connection_write_prepare(connection *c, size_t length) {
282 size_t t;
283 pa_assert(c);
284
285 t = c->write_data_length+length;
286
287 if (c->write_data_alloc < t)
288 c->write_data = pa_xrealloc(c->write_data, c->write_data_alloc = t);
289
290 pa_assert(c->write_data);
291 }
292
293 static void connection_write(connection *c, const void *data, size_t length) {
294 size_t i;
295 pa_assert(c);
296
297 c->protocol->core->mainloop->defer_enable(c->defer_event, 1);
298
299 connection_write_prepare(c, length);
300
301 pa_assert(c->write_data);
302
303 i = c->write_data_length;
304 c->write_data_length += length;
305
306 memcpy((uint8_t*) c->write_data + i, data, length);
307 }
308
309 static void format_esd2native(int format, pa_bool_t swap_bytes, pa_sample_spec *ss) {
310 pa_assert(ss);
311
312 ss->channels = (uint8_t) (((format & ESD_MASK_CHAN) == ESD_STEREO) ? 2 : 1);
313 if ((format & ESD_MASK_BITS) == ESD_BITS16)
314 ss->format = swap_bytes ? PA_SAMPLE_S16RE : PA_SAMPLE_S16NE;
315 else
316 ss->format = PA_SAMPLE_U8;
317 }
318
319 static int format_native2esd(pa_sample_spec *ss) {
320 int format = 0;
321
322 format = (ss->format == PA_SAMPLE_U8) ? ESD_BITS8 : ESD_BITS16;
323 format |= (ss->channels >= 2) ? ESD_STEREO : ESD_MONO;
324
325 return format;
326 }
327
328 #define CHECK_VALIDITY(expression, ...) do { \
329 if (PA_UNLIKELY(!(expression))) { \
330 pa_log_warn(__FILE__ ": " __VA_ARGS__); \
331 return -1; \
332 } \
333 } while(0);
334
335 /*** esound commands ***/
336
337 static int esd_proto_connect(connection *c, esd_proto_t request, const void *data, size_t length) {
338 uint32_t ekey;
339 int ok;
340
341 connection_assert_ref(c);
342 pa_assert(data);
343 pa_assert(length == (ESD_KEY_LEN + sizeof(uint32_t)));
344
345 if (!c->authorized && c->options->auth_cookie) {
346 const uint8_t*key;
347
348 if ((key = pa_auth_cookie_read(c->options->auth_cookie, ESD_KEY_LEN)))
349 if (memcmp(data, key, ESD_KEY_LEN) == 0)
350 c->authorized = TRUE;
351 }
352
353 if (!c->authorized) {
354 pa_log("Kicked client with invalid authorization key.");
355 return -1;
356 }
357
358 if (c->auth_timeout_event) {
359 c->protocol->core->mainloop->time_free(c->auth_timeout_event);
360 c->auth_timeout_event = NULL;
361 }
362
363 data = (const char*)data + ESD_KEY_LEN;
364
365 memcpy(&ekey, data, sizeof(uint32_t));
366 if (ekey == ESD_ENDIAN_KEY)
367 c->swap_byte_order = FALSE;
368 else if (ekey == ESD_SWAP_ENDIAN_KEY)
369 c->swap_byte_order = TRUE;
370 else {
371 pa_log_warn("Client sent invalid endian key");
372 return -1;
373 }
374
375 pa_proplist_sets(c->client->proplist, "esound.byte_order", c->swap_byte_order ? "reverse" : "native");
376
377 ok = 1;
378 connection_write(c, &ok, sizeof(int));
379 return 0;
380 }
381
382 static int esd_proto_stream_play(connection *c, esd_proto_t request, const void *data, size_t length) {
383 char name[ESD_NAME_MAX], *utf8_name;
384 int32_t format, rate;
385 pa_sample_spec ss;
386 size_t l;
387 pa_sink *sink = NULL;
388 pa_sink_input_new_data sdata;
389 pa_memchunk silence;
390
391 connection_assert_ref(c);
392 pa_assert(data);
393 pa_assert(length == (sizeof(int32_t)*2+ESD_NAME_MAX));
394
395 memcpy(&format, data, sizeof(int32_t));
396 format = PA_MAYBE_INT32_SWAP(c->swap_byte_order, format);
397 data = (const char*) data + sizeof(int32_t);
398
399 memcpy(&rate, data, sizeof(int32_t));
400 rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate);
401 data = (const char*) data + sizeof(int32_t);
402
403 ss.rate = (uint32_t) rate;
404 format_esd2native(format, c->swap_byte_order, &ss);
405
406 CHECK_VALIDITY(pa_sample_spec_valid(&ss), "Invalid sample specification");
407
408 if (c->options->default_sink) {
409 sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK);
410 CHECK_VALIDITY(sink, "No such sink: %s", pa_strnull(c->options->default_sink));
411 }
412
413 pa_strlcpy(name, data, sizeof(name));
414
415 utf8_name = pa_utf8_filter(name);
416 pa_client_set_name(c->client, utf8_name);
417 pa_xfree(utf8_name);
418
419 c->original_name = pa_xstrdup(name);
420
421 pa_assert(!c->sink_input && !c->input_memblockq);
422
423 pa_sink_input_new_data_init(&sdata);
424 sdata.driver = __FILE__;
425 sdata.module = c->options->module;
426 sdata.client = c->client;
427 if (sink)
428 pa_sink_input_new_data_set_sink(&sdata, sink, FALSE);
429 pa_sink_input_new_data_set_sample_spec(&sdata, &ss);
430
431 pa_sink_input_new(&c->sink_input, c->protocol->core, &sdata);
432 pa_sink_input_new_data_done(&sdata);
433
434 CHECK_VALIDITY(c->sink_input, "Failed to create sink input.");
435
436 l = (size_t) ((double) pa_bytes_per_second(&ss)*PLAYBACK_BUFFER_SECONDS);
437 pa_sink_input_get_silence(c->sink_input, &silence);
438 c->input_memblockq = pa_memblockq_new(
439 0,
440 l,
441 l,
442 pa_frame_size(&ss),
443 (size_t) -1,
444 l/PLAYBACK_BUFFER_FRAGMENTS,
445 0,
446 &silence);
447 pa_memblock_unref(silence.memblock);
448 pa_iochannel_socket_set_rcvbuf(c->io, l);
449
450 c->sink_input->parent.process_msg = sink_input_process_msg;
451 c->sink_input->pop = sink_input_pop_cb;
452 c->sink_input->process_rewind = sink_input_process_rewind_cb;
453 c->sink_input->update_max_rewind = sink_input_update_max_rewind_cb;
454 c->sink_input->kill = sink_input_kill_cb;
455 c->sink_input->userdata = c;
456
457 pa_sink_input_set_requested_latency(c->sink_input, DEFAULT_SINK_LATENCY);
458
459 c->state = ESD_STREAMING_DATA;
460
461 c->protocol->n_player++;
462
463 pa_atomic_store(&c->playback.missing, (int) pa_memblockq_pop_missing(c->input_memblockq));
464
465 pa_sink_input_put(c->sink_input);
466
467 return 0;
468 }
469
470 static int esd_proto_stream_record(connection *c, esd_proto_t request, const void *data, size_t length) {
471 char name[ESD_NAME_MAX], *utf8_name;
472 int32_t format, rate;
473 pa_source *source = NULL;
474 pa_sample_spec ss;
475 size_t l;
476 pa_source_output_new_data sdata;
477
478 connection_assert_ref(c);
479 pa_assert(data);
480 pa_assert(length == (sizeof(int32_t)*2+ESD_NAME_MAX));
481
482 memcpy(&format, data, sizeof(int32_t));
483 format = PA_MAYBE_INT32_SWAP(c->swap_byte_order, format);
484 data = (const char*) data + sizeof(int32_t);
485
486 memcpy(&rate, data, sizeof(int32_t));
487 rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate);
488 data = (const char*) data + sizeof(int32_t);
489
490 ss.rate = (uint32_t) rate;
491 format_esd2native(format, c->swap_byte_order, &ss);
492
493 CHECK_VALIDITY(pa_sample_spec_valid(&ss), "Invalid sample specification.");
494
495 if (request == ESD_PROTO_STREAM_MON) {
496 pa_sink* sink;
497
498 sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK);
499 CHECK_VALIDITY(sink, "No such sink: %s", pa_strnull(c->options->default_sink));
500
501 source = sink->monitor_source;
502 CHECK_VALIDITY(source, "No such source.");
503 } else {
504 pa_assert(request == ESD_PROTO_STREAM_REC);
505
506 if (c->options->default_source) {
507 source = pa_namereg_get(c->protocol->core, c->options->default_source, PA_NAMEREG_SOURCE);
508 CHECK_VALIDITY(source, "No such source: %s", pa_strnull(c->options->default_source));
509 }
510 }
511
512 pa_strlcpy(name, data, sizeof(name));
513
514 utf8_name = pa_utf8_filter(name);
515 pa_client_set_name(c->client, utf8_name);
516 pa_xfree(utf8_name);
517
518 c->original_name = pa_xstrdup(name);
519
520 pa_assert(!c->output_memblockq && !c->source_output);
521
522 pa_source_output_new_data_init(&sdata);
523 sdata.driver = __FILE__;
524 sdata.module = c->options->module;
525 sdata.client = c->client;
526 if (source)
527 pa_source_output_new_data_set_source(&sdata, source, FALSE);
528 pa_source_output_new_data_set_sample_spec(&sdata, &ss);
529
530 pa_source_output_new(&c->source_output, c->protocol->core, &sdata);
531 pa_source_output_new_data_done(&sdata);
532
533 CHECK_VALIDITY(c->source_output, "Failed to create source output.");
534
535 l = (size_t) (pa_bytes_per_second(&ss)*RECORD_BUFFER_SECONDS);
536 c->output_memblockq = pa_memblockq_new(
537 0,
538 l,
539 l,
540 pa_frame_size(&ss),
541 1,
542 0,
543 0,
544 NULL);
545 pa_iochannel_socket_set_sndbuf(c->io, l);
546
547 c->source_output->push = source_output_push_cb;
548 c->source_output->kill = source_output_kill_cb;
549 c->source_output->get_latency = source_output_get_latency_cb;
550 c->source_output->userdata = c;
551
552 pa_source_output_set_requested_latency(c->source_output, DEFAULT_SOURCE_LATENCY);
553
554 c->state = ESD_STREAMING_DATA;
555
556 c->protocol->n_player++;
557
558 pa_source_output_put(c->source_output);
559
560 return 0;
561 }
562
563 static int esd_proto_get_latency(connection *c, esd_proto_t request, const void *data, size_t length) {
564 pa_sink *sink;
565 int32_t latency;
566
567 connection_assert_ref(c);
568 pa_assert(!data);
569 pa_assert(length == 0);
570
571 if (!(sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK)))
572 latency = 0;
573 else {
574 double usec = (double) pa_sink_get_requested_latency(sink);
575 latency = (int) ((usec*44100)/1000000);
576 }
577
578 latency = PA_MAYBE_INT32_SWAP(c->swap_byte_order, latency);
579 connection_write(c, &latency, sizeof(int32_t));
580
581 return 0;
582 }
583
584 static int esd_proto_server_info(connection *c, esd_proto_t request, const void *data, size_t length) {
585 int32_t rate = 44100, format = ESD_STEREO|ESD_BITS16;
586 int32_t response;
587 pa_sink *sink;
588
589 connection_assert_ref(c);
590 pa_assert(data);
591 pa_assert(length == sizeof(int32_t));
592
593 if ((sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK))) {
594 rate = (int32_t) sink->sample_spec.rate;
595 format = format_native2esd(&sink->sample_spec);
596 }
597
598 connection_write_prepare(c, sizeof(int32_t) * 3);
599
600 response = 0;
601 connection_write(c, &response, sizeof(int32_t));
602 rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate);
603 connection_write(c, &rate, sizeof(int32_t));
604 format = PA_MAYBE_INT32_SWAP(c->swap_byte_order, format);
605 connection_write(c, &format, sizeof(int32_t));
606
607 return 0;
608 }
609
610 static int esd_proto_all_info(connection *c, esd_proto_t request, const void *data, size_t length) {
611 size_t t, k, s;
612 connection *conn;
613 uint32_t idx = PA_IDXSET_INVALID;
614 unsigned nsamples;
615 char terminator[sizeof(int32_t)*6+ESD_NAME_MAX];
616
617 connection_assert_ref(c);
618 pa_assert(data);
619 pa_assert(length == sizeof(int32_t));
620
621 if (esd_proto_server_info(c, request, data, length) < 0)
622 return -1;
623
624 k = sizeof(int32_t)*5+ESD_NAME_MAX;
625 s = sizeof(int32_t)*6+ESD_NAME_MAX;
626 nsamples = pa_idxset_size(c->protocol->core->scache);
627 t = s*(nsamples+1) + k*(c->protocol->n_player+1);
628
629 connection_write_prepare(c, t);
630
631 memset(terminator, 0, sizeof(terminator));
632
633 PA_IDXSET_FOREACH(conn, c->protocol->connections, idx) {
634 int32_t id, format = ESD_BITS16 | ESD_STEREO, rate = 44100, lvolume = ESD_VOLUME_BASE, rvolume = ESD_VOLUME_BASE;
635 char name[ESD_NAME_MAX];
636
637 if (conn->state != ESD_STREAMING_DATA)
638 continue;
639
640 pa_assert(t >= k*2+s);
641
642 if (conn->sink_input) {
643 pa_cvolume volume;
644 pa_sink_input_get_volume(conn->sink_input, &volume, TRUE);
645 rate = (int32_t) conn->sink_input->sample_spec.rate;
646 lvolume = (int32_t) ((volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM);
647 rvolume = (int32_t) ((volume.values[volume.channels == 2 ? 1 : 0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM);
648 format = format_native2esd(&conn->sink_input->sample_spec);
649 }
650
651 /* id */
652 id = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) (conn->index+1));
653 connection_write(c, &id, sizeof(int32_t));
654
655 /* name */
656 memset(name, 0, ESD_NAME_MAX); /* don't leak old data */
657 if (conn->original_name)
658 strncpy(name, conn->original_name, ESD_NAME_MAX);
659 else if (conn->client && pa_proplist_gets(conn->client->proplist, PA_PROP_APPLICATION_NAME))
660 strncpy(name, pa_proplist_gets(conn->client->proplist, PA_PROP_APPLICATION_NAME), ESD_NAME_MAX);
661 connection_write(c, name, ESD_NAME_MAX);
662
663 /* rate */
664 rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate);
665 connection_write(c, &rate, sizeof(int32_t));
666
667 /* left */
668 lvolume = PA_MAYBE_INT32_SWAP(c->swap_byte_order, lvolume);
669 connection_write(c, &lvolume, sizeof(int32_t));
670
671 /*right*/
672 rvolume = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rvolume);
673 connection_write(c, &rvolume, sizeof(int32_t));
674
675 /*format*/
676 format = PA_MAYBE_INT32_SWAP(c->swap_byte_order, format);
677 connection_write(c, &format, sizeof(int32_t));
678
679 t -= k;
680 }
681
682 pa_assert(t == s*(nsamples+1)+k);
683 t -= k;
684
685 connection_write(c, terminator, k);
686
687 if (nsamples) {
688 pa_scache_entry *ce;
689
690 idx = PA_IDXSET_INVALID;
691
692 PA_IDXSET_FOREACH(ce, c->protocol->core->scache, idx) {
693 int32_t id, rate, lvolume, rvolume, format, len;
694 char name[ESD_NAME_MAX];
695 pa_channel_map stereo = { .channels = 2, .map = { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT } };
696 pa_cvolume volume;
697 pa_sample_spec ss;
698
699 pa_assert(t >= s*2);
700
701 if (ce->volume_is_set) {
702 volume = ce->volume;
703 pa_cvolume_remap(&volume, &ce->channel_map, &stereo);
704 } else
705 pa_cvolume_reset(&volume, 2);
706
707 if (ce->memchunk.memblock)
708 ss = ce->sample_spec;
709 else {
710 ss.format = PA_SAMPLE_S16NE;
711 ss.rate = 44100;
712 ss.channels = 2;
713 }
714
715 /* id */
716 id = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int) (ce->index+1));
717 connection_write(c, &id, sizeof(int32_t));
718
719 /* name */
720 memset(name, 0, ESD_NAME_MAX); /* don't leak old data */
721 if (strncmp(ce->name, SCACHE_PREFIX, sizeof(SCACHE_PREFIX)-1) == 0)
722 strncpy(name, ce->name+sizeof(SCACHE_PREFIX)-1, ESD_NAME_MAX);
723 else
724 pa_snprintf(name, ESD_NAME_MAX, "native.%s", ce->name);
725 connection_write(c, name, ESD_NAME_MAX);
726
727 /* rate */
728 rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) ss.rate);
729 connection_write(c, &rate, sizeof(int32_t));
730
731 /* left */
732 lvolume = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) ((volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM));
733 connection_write(c, &lvolume, sizeof(int32_t));
734
735 /*right*/
736 rvolume = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) ((volume.values[1]*ESD_VOLUME_BASE)/PA_VOLUME_NORM));
737 connection_write(c, &rvolume, sizeof(int32_t));
738
739 /*format*/
740 format = PA_MAYBE_INT32_SWAP(c->swap_byte_order, format_native2esd(&ss));
741 connection_write(c, &format, sizeof(int32_t));
742
743 /*length*/
744 len = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int) ce->memchunk.length);
745 connection_write(c, &len, sizeof(int32_t));
746
747 t -= s;
748 }
749 }
750
751 pa_assert(t == s);
752
753 connection_write(c, terminator, s);
754
755 return 0;
756 }
757
758 static int esd_proto_stream_pan(connection *c, esd_proto_t request, const void *data, size_t length) {
759 int32_t ok;
760 uint32_t idx, lvolume, rvolume;
761 connection *conn;
762
763 connection_assert_ref(c);
764 pa_assert(data);
765 pa_assert(length == sizeof(int32_t)*3);
766
767 memcpy(&idx, data, sizeof(uint32_t));
768 idx = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, idx) - 1;
769 data = (const char*)data + sizeof(uint32_t);
770
771 memcpy(&lvolume, data, sizeof(uint32_t));
772 lvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, lvolume);
773 data = (const char*)data + sizeof(uint32_t);
774
775 memcpy(&rvolume, data, sizeof(uint32_t));
776 rvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, rvolume);
777
778 if ((conn = pa_idxset_get_by_index(c->protocol->connections, idx)) && conn->sink_input) {
779 pa_cvolume volume;
780 volume.values[0] = (lvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE;
781 volume.values[1] = (rvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE;
782 volume.channels = conn->sink_input->sample_spec.channels;
783
784 pa_sink_input_set_volume(conn->sink_input, &volume, TRUE, TRUE);
785 ok = 1;
786 } else
787 ok = 0;
788
789 connection_write(c, &ok, sizeof(int32_t));
790
791 return 0;
792 }
793
794 static int esd_proto_sample_pan(connection *c, esd_proto_t request, const void *data, size_t length) {
795 int32_t ok = 0;
796 uint32_t idx, lvolume, rvolume;
797 pa_cvolume volume;
798 pa_scache_entry *ce;
799
800 connection_assert_ref(c);
801 pa_assert(data);
802 pa_assert(length == sizeof(int32_t)*3);
803
804 memcpy(&idx, data, sizeof(uint32_t));
805 idx = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, idx) - 1;
806 data = (const char*)data + sizeof(uint32_t);
807
808 memcpy(&lvolume, data, sizeof(uint32_t));
809 lvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, lvolume);
810 data = (const char*)data + sizeof(uint32_t);
811
812 memcpy(&rvolume, data, sizeof(uint32_t));
813 rvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, rvolume);
814
815 volume.values[0] = (lvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE;
816 volume.values[1] = (rvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE;
817 volume.channels = 2;
818
819 if ((ce = pa_idxset_get_by_index(c->protocol->core->scache, idx))) {
820 pa_channel_map stereo = { .channels = 2, .map = { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT } };
821
822 pa_cvolume_remap(&volume, &stereo, &ce->channel_map);
823 ce->volume = volume;
824 ce->volume_is_set = TRUE;
825 ok = 1;
826 }
827
828 connection_write(c, &ok, sizeof(int32_t));
829
830 return 0;
831 }
832
833 static int esd_proto_sample_cache(connection *c, esd_proto_t request, const void *data, size_t length) {
834 pa_sample_spec ss;
835 int32_t format, rate, sc_length;
836 uint32_t idx;
837 char name[ESD_NAME_MAX+sizeof(SCACHE_PREFIX)-1];
838
839 connection_assert_ref(c);
840 pa_assert(data);
841 pa_assert(length == (ESD_NAME_MAX+3*sizeof(int32_t)));
842
843 memcpy(&format, data, sizeof(int32_t));
844 format = PA_MAYBE_INT32_SWAP(c->swap_byte_order, format);
845 data = (const char*)data + sizeof(int32_t);
846
847 memcpy(&rate, data, sizeof(int32_t));
848 rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate);
849 data = (const char*)data + sizeof(int32_t);
850
851 ss.rate = (uint32_t) rate;
852 format_esd2native(format, c->swap_byte_order, &ss);
853
854 CHECK_VALIDITY(pa_sample_spec_valid(&ss), "Invalid sample specification.");
855
856 memcpy(&sc_length, data, sizeof(int32_t));
857 sc_length = PA_MAYBE_INT32_SWAP(c->swap_byte_order, sc_length);
858 data = (const char*)data + sizeof(int32_t);
859
860 CHECK_VALIDITY(sc_length <= MAX_CACHE_SAMPLE_SIZE, "Sample too large (%d bytes).", (int)sc_length);
861
862 strcpy(name, SCACHE_PREFIX);
863 pa_strlcpy(name+sizeof(SCACHE_PREFIX)-1, data, ESD_NAME_MAX);
864
865 CHECK_VALIDITY(pa_utf8_valid(name), "Invalid UTF8 in sample name.");
866
867 pa_assert(!c->scache.memchunk.memblock);
868 c->scache.memchunk.memblock = pa_memblock_new(c->protocol->core->mempool, (size_t) sc_length);
869 c->scache.memchunk.index = 0;
870 c->scache.memchunk.length = (size_t) sc_length;
871 c->scache.sample_spec = ss;
872 pa_assert(!c->scache.name);
873 c->scache.name = pa_xstrdup(name);
874
875 c->state = ESD_CACHING_SAMPLE;
876
877 pa_scache_add_item(c->protocol->core, c->scache.name, NULL, NULL, NULL, c->client->proplist, &idx);
878
879 idx += 1;
880 connection_write(c, &idx, sizeof(uint32_t));
881
882 return 0;
883 }
884
885 static int esd_proto_sample_get_id(connection *c, esd_proto_t request, const void *data, size_t length) {
886 int32_t ok;
887 uint32_t idx;
888 char name[ESD_NAME_MAX+sizeof(SCACHE_PREFIX)-1];
889
890 connection_assert_ref(c);
891 pa_assert(data);
892 pa_assert(length == ESD_NAME_MAX);
893
894 strcpy(name, SCACHE_PREFIX);
895 pa_strlcpy(name+sizeof(SCACHE_PREFIX)-1, data, ESD_NAME_MAX);
896
897 CHECK_VALIDITY(pa_utf8_valid(name), "Invalid UTF8 in sample name.");
898
899 ok = -1;
900 if ((idx = pa_scache_get_id_by_name(c->protocol->core, name)) != PA_IDXSET_INVALID)
901 ok = (int32_t) idx + 1;
902
903 connection_write(c, &ok, sizeof(int32_t));
904
905 return 0;
906 }
907
908 static int esd_proto_sample_free_or_play(connection *c, esd_proto_t request, const void *data, size_t length) {
909 int32_t ok;
910 const char *name;
911 uint32_t idx;
912
913 connection_assert_ref(c);
914 pa_assert(data);
915 pa_assert(length == sizeof(int32_t));
916
917 memcpy(&idx, data, sizeof(uint32_t));
918 idx = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, idx) - 1;
919
920 ok = 0;
921
922 if ((name = pa_scache_get_name_by_id(c->protocol->core, idx))) {
923 if (request == ESD_PROTO_SAMPLE_PLAY) {
924 pa_sink *sink;
925
926 if ((sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK)))
927 if (pa_scache_play_item(c->protocol->core, name, sink, PA_VOLUME_NORM, c->client->proplist, NULL) >= 0)
928 ok = (int32_t) idx + 1;
929 } else {
930 pa_assert(request == ESD_PROTO_SAMPLE_FREE);
931
932 if (pa_scache_remove_item(c->protocol->core, name) >= 0)
933 ok = (int32_t) idx + 1;
934 }
935 }
936
937 connection_write(c, &ok, sizeof(int32_t));
938
939 return 0;
940 }
941
942 static int esd_proto_standby_or_resume(connection *c, esd_proto_t request, const void *data, size_t length) {
943 int32_t ok = 1;
944
945 connection_assert_ref(c);
946
947 connection_write_prepare(c, sizeof(int32_t) * 2);
948 connection_write(c, &ok, sizeof(int32_t));
949
950 if (request == ESD_PROTO_STANDBY)
951 ok = pa_sink_suspend_all(c->protocol->core, TRUE, PA_SUSPEND_USER) >= 0;
952 else {
953 pa_assert(request == ESD_PROTO_RESUME);
954 ok = pa_sink_suspend_all(c->protocol->core, FALSE, PA_SUSPEND_USER) >= 0;
955 }
956
957 connection_write(c, &ok, sizeof(int32_t));
958
959 return 0;
960 }
961
962 static int esd_proto_standby_mode(connection *c, esd_proto_t request, const void *data, size_t length) {
963 int32_t mode;
964 pa_sink *sink, *source;
965
966 connection_assert_ref(c);
967
968 mode = ESM_RUNNING;
969
970 if ((sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK)))
971 if (pa_sink_get_state(sink) == PA_SINK_SUSPENDED)
972 mode = ESM_ON_STANDBY;
973
974 if ((source = pa_namereg_get(c->protocol->core, c->options->default_source, PA_NAMEREG_SOURCE)))
975 if (pa_source_get_state(source) == PA_SOURCE_SUSPENDED)
976 mode = ESM_ON_STANDBY;
977
978 mode = PA_MAYBE_INT32_SWAP(c->swap_byte_order, mode);
979
980 connection_write(c, &mode, sizeof(mode));
981 return 0;
982 }
983
984 /*** client callbacks ***/
985
986 static void client_kill_cb(pa_client *c) {
987 pa_assert(c);
988
989 connection_unlink(CONNECTION(c->userdata));
990 }
991
992 /*** pa_iochannel callbacks ***/
993
994 static int do_read(connection *c) {
995 connection_assert_ref(c);
996
997 /* pa_log("READ"); */
998
999 if (c->state == ESD_NEXT_REQUEST) {
1000 ssize_t r;
1001 pa_assert(c->read_data_length < sizeof(c->request));
1002
1003 if ((r = pa_iochannel_read(c->io,
1004 ((uint8_t*) &c->request) + c->read_data_length,
1005 sizeof(c->request) - c->read_data_length)) <= 0) {
1006
1007 if (r < 0 && (errno == EINTR || errno == EAGAIN))
1008 return 0;
1009
1010 pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF");
1011 return -1;
1012 }
1013
1014 c->read_data_length += (size_t) r;
1015
1016 if (c->read_data_length >= sizeof(c->request)) {
1017 struct proto_handler *handler;
1018
1019 c->request = PA_MAYBE_INT32_SWAP(c->swap_byte_order, c->request);
1020
1021 if (c->request < ESD_PROTO_CONNECT || c->request >= ESD_PROTO_MAX) {
1022 pa_log("recieved invalid request.");
1023 return -1;
1024 }
1025
1026 handler = proto_map+c->request;
1027
1028 /* pa_log("executing request #%u", c->request); */
1029
1030 if (!handler->proc) {
1031 pa_log("recieved unimplemented request #%u.", c->request);
1032 return -1;
1033 }
1034
1035 if (handler->data_length == 0) {
1036 c->read_data_length = 0;
1037
1038 if (handler->proc(c, c->request, NULL, 0) < 0)
1039 return -1;
1040
1041 } else {
1042 if (c->read_data_alloc < handler->data_length)
1043 c->read_data = pa_xrealloc(c->read_data, c->read_data_alloc = handler->data_length);
1044 pa_assert(c->read_data);
1045
1046 c->state = ESD_NEEDS_REQDATA;
1047 c->read_data_length = 0;
1048 }
1049 }
1050
1051 } else if (c->state == ESD_NEEDS_REQDATA) {
1052 ssize_t r;
1053 struct proto_handler *handler = proto_map+c->request;
1054
1055 pa_assert(handler->proc);
1056
1057 pa_assert(c->read_data && c->read_data_length < handler->data_length);
1058
1059 if ((r = pa_iochannel_read(c->io,
1060 (uint8_t*) c->read_data + c->read_data_length,
1061 handler->data_length - c->read_data_length)) <= 0) {
1062
1063 if (r < 0 && (errno == EINTR || errno == EAGAIN))
1064 return 0;
1065
1066 pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF");
1067 return -1;
1068 }
1069
1070 c->read_data_length += (size_t) r;
1071 if (c->read_data_length >= handler->data_length) {
1072 size_t l = c->read_data_length;
1073 pa_assert(handler->proc);
1074
1075 c->state = ESD_NEXT_REQUEST;
1076 c->read_data_length = 0;
1077
1078 if (handler->proc(c, c->request, c->read_data, l) < 0)
1079 return -1;
1080 }
1081 } else if (c->state == ESD_CACHING_SAMPLE) {
1082 ssize_t r;
1083 void *p;
1084
1085 pa_assert(c->scache.memchunk.memblock);
1086 pa_assert(c->scache.name);
1087 pa_assert(c->scache.memchunk.index < c->scache.memchunk.length);
1088
1089 p = pa_memblock_acquire(c->scache.memchunk.memblock);
1090 r = pa_iochannel_read(c->io, (uint8_t*) p+c->scache.memchunk.index, c->scache.memchunk.length-c->scache.memchunk.index);
1091 pa_memblock_release(c->scache.memchunk.memblock);
1092
1093 if (r <= 0) {
1094 if (r < 0 && (errno == EINTR || errno == EAGAIN))
1095 return 0;
1096
1097 pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF");
1098 return -1;
1099 }
1100
1101 c->scache.memchunk.index += (size_t) r;
1102 pa_assert(c->scache.memchunk.index <= c->scache.memchunk.length);
1103
1104 if (c->scache.memchunk.index == c->scache.memchunk.length) {
1105 uint32_t idx;
1106
1107 c->scache.memchunk.index = 0;
1108 pa_scache_add_item(c->protocol->core, c->scache.name, &c->scache.sample_spec, NULL, &c->scache.memchunk, c->client->proplist, &idx);
1109
1110 pa_memblock_unref(c->scache.memchunk.memblock);
1111 pa_memchunk_reset(&c->scache.memchunk);
1112
1113 pa_xfree(c->scache.name);
1114 c->scache.name = NULL;
1115
1116 c->state = ESD_NEXT_REQUEST;
1117
1118 idx += 1;
1119 connection_write(c, &idx, sizeof(uint32_t));
1120 }
1121
1122 } else if (c->state == ESD_STREAMING_DATA && c->sink_input) {
1123 pa_memchunk chunk;
1124 ssize_t r;
1125 size_t l;
1126 void *p;
1127 size_t space = 0;
1128
1129 pa_assert(c->input_memblockq);
1130
1131 /* pa_log("STREAMING_DATA"); */
1132
1133 if ((l = (size_t) pa_atomic_load(&c->playback.missing)) <= 0)
1134 return 0;
1135
1136 if (c->playback.current_memblock) {
1137
1138 space = pa_memblock_get_length(c->playback.current_memblock) - c->playback.memblock_index;
1139
1140 if (space <= 0) {
1141 pa_memblock_unref(c->playback.current_memblock);
1142 c->playback.current_memblock = NULL;
1143 }
1144 }
1145
1146 if (!c->playback.current_memblock) {
1147 pa_assert_se(c->playback.current_memblock = pa_memblock_new(c->protocol->core->mempool, (size_t) -1));
1148 c->playback.memblock_index = 0;
1149
1150 space = pa_memblock_get_length(c->playback.current_memblock);
1151 }
1152
1153 if (l > space)
1154 l = space;
1155
1156 p = pa_memblock_acquire(c->playback.current_memblock);
1157 r = pa_iochannel_read(c->io, (uint8_t*) p+c->playback.memblock_index, l);
1158 pa_memblock_release(c->playback.current_memblock);
1159
1160 if (r <= 0) {
1161
1162 if (r < 0 && (errno == EINTR || errno == EAGAIN))
1163 return 0;
1164
1165 pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF");
1166 return -1;
1167 }
1168
1169 chunk.memblock = c->playback.current_memblock;
1170 chunk.index = c->playback.memblock_index;
1171 chunk.length = (size_t) r;
1172
1173 c->playback.memblock_index += (size_t) r;
1174
1175 pa_atomic_sub(&c->playback.missing, (int) r);
1176 pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, 0, &chunk, NULL);
1177 }
1178
1179 return 0;
1180 }
1181
1182 static int do_write(connection *c) {
1183 connection_assert_ref(c);
1184
1185 /* pa_log("WRITE"); */
1186
1187 if (c->write_data_length) {
1188 ssize_t r;
1189
1190 pa_assert(c->write_data_index < c->write_data_length);
1191 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) {
1192
1193 if (r < 0 && (errno == EINTR || errno == EAGAIN))
1194 return 0;
1195
1196 pa_log("write(): %s", pa_cstrerror(errno));
1197 return -1;
1198 }
1199
1200 c->write_data_index += (size_t) r;
1201 if (c->write_data_index >= c->write_data_length)
1202 c->write_data_length = c->write_data_index = 0;
1203
1204 } else if (c->state == ESD_STREAMING_DATA && c->source_output) {
1205 pa_memchunk chunk;
1206 ssize_t r;
1207 void *p;
1208
1209 if (pa_memblockq_peek(c->output_memblockq, &chunk) < 0)
1210 return 0;
1211
1212 pa_assert(chunk.memblock);
1213 pa_assert(chunk.length);
1214
1215 p = pa_memblock_acquire(chunk.memblock);
1216 r = pa_iochannel_write(c->io, (uint8_t*) p+chunk.index, chunk.length);
1217 pa_memblock_release(chunk.memblock);
1218
1219 pa_memblock_unref(chunk.memblock);
1220
1221 if (r < 0) {
1222
1223 if (r < 0 && (errno == EINTR || errno == EAGAIN))
1224 return 0;
1225
1226 pa_log("write(): %s", pa_cstrerror(errno));
1227 return -1;
1228 }
1229
1230 pa_memblockq_drop(c->output_memblockq, (size_t) r);
1231 }
1232
1233 return 0;
1234 }
1235
1236 static void do_work(connection *c) {
1237 connection_assert_ref(c);
1238
1239 c->protocol->core->mainloop->defer_enable(c->defer_event, 0);
1240
1241 if (c->dead)
1242 return;
1243
1244 if (pa_iochannel_is_readable(c->io))
1245 if (do_read(c) < 0)
1246 goto fail;
1247
1248 if (c->state == ESD_STREAMING_DATA && !c->sink_input && pa_iochannel_is_hungup(c->io))
1249 /* In case we are in capture mode we will never call read()
1250 * on the socket, hence we need to detect the hangup manually
1251 * here, instead of simply waiting for read() to return 0. */
1252 goto fail;
1253
1254 if (pa_iochannel_is_writable(c->io))
1255 if (do_write(c) < 0)
1256 goto fail;
1257
1258 return;
1259
1260 fail:
1261
1262 if (c->state == ESD_STREAMING_DATA && c->sink_input) {
1263 c->dead = TRUE;
1264
1265 pa_iochannel_free(c->io);
1266 c->io = NULL;
1267
1268 pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_DISABLE_PREBUF, NULL, 0, NULL, NULL);
1269 } else
1270 connection_unlink(c);
1271 }
1272
1273 static void io_callback(pa_iochannel*io, void *userdata) {
1274 connection *c = CONNECTION(userdata);
1275
1276 connection_assert_ref(c);
1277 pa_assert(io);
1278
1279 do_work(c);
1280 }
1281
1282 static void defer_callback(pa_mainloop_api*a, pa_defer_event *e, void *userdata) {
1283 connection *c = CONNECTION(userdata);
1284
1285 connection_assert_ref(c);
1286 pa_assert(e);
1287
1288 do_work(c);
1289 }
1290
1291 static int connection_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) {
1292 connection *c = CONNECTION(o);
1293 connection_assert_ref(c);
1294
1295 if (!c->protocol)
1296 return -1;
1297
1298 switch (code) {
1299 case CONNECTION_MESSAGE_REQUEST_DATA:
1300 do_work(c);
1301 break;
1302
1303 case CONNECTION_MESSAGE_POST_DATA:
1304 /* pa_log("got data %u", chunk->length); */
1305 pa_memblockq_push_align(c->output_memblockq, chunk);
1306 do_work(c);
1307 break;
1308
1309 case CONNECTION_MESSAGE_UNLINK_CONNECTION:
1310 connection_unlink(c);
1311 break;
1312 }
1313
1314 return 0;
1315 }
1316
1317 /*** sink_input callbacks ***/
1318
1319 /* Called from thread context */
1320 static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
1321 pa_sink_input *i = PA_SINK_INPUT(o);
1322 connection*c;
1323
1324 pa_sink_input_assert_ref(i);
1325 c = CONNECTION(i->userdata);
1326 connection_assert_ref(c);
1327
1328 switch (code) {
1329
1330 case SINK_INPUT_MESSAGE_POST_DATA: {
1331 pa_assert(chunk);
1332
1333 /* New data from the main loop */
1334 pa_memblockq_push_align(c->input_memblockq, chunk);
1335
1336 if (pa_memblockq_is_readable(c->input_memblockq) && c->playback.underrun) {
1337 pa_log_debug("Requesting rewind due to end of underrun.");
1338 pa_sink_input_request_rewind(c->sink_input, 0, FALSE, TRUE, FALSE);
1339 }
1340
1341 /* pa_log("got data, %u", pa_memblockq_get_length(c->input_memblockq)); */
1342
1343 return 0;
1344 }
1345
1346 case SINK_INPUT_MESSAGE_DISABLE_PREBUF:
1347 pa_memblockq_prebuf_disable(c->input_memblockq);
1348 return 0;
1349
1350 case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
1351 pa_usec_t *r = userdata;
1352
1353 *r = pa_bytes_to_usec(pa_memblockq_get_length(c->input_memblockq), &c->sink_input->sample_spec);
1354
1355 /* Fall through, the default handler will add in the extra
1356 * latency added by the resampler */
1357 }
1358
1359 default:
1360 return pa_sink_input_process_msg(o, code, userdata, offset, chunk);
1361 }
1362 }
1363
1364 /* Called from thread context */
1365 static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) {
1366 connection*c;
1367
1368 pa_sink_input_assert_ref(i);
1369 c = CONNECTION(i->userdata);
1370 connection_assert_ref(c);
1371 pa_assert(chunk);
1372
1373 if (pa_memblockq_peek(c->input_memblockq, chunk) < 0) {
1374
1375 c->playback.underrun = TRUE;
1376
1377 if (c->dead && pa_sink_input_safe_to_remove(i))
1378 pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_UNLINK_CONNECTION, NULL, 0, NULL, NULL);
1379
1380 return -1;
1381 } else {
1382 size_t m;
1383
1384 c->playback.underrun = FALSE;
1385
1386 chunk->length = PA_MIN(length, chunk->length);
1387 pa_memblockq_drop(c->input_memblockq, chunk->length);
1388 m = pa_memblockq_pop_missing(c->input_memblockq);
1389
1390 if (m > 0)
1391 if (pa_atomic_add(&c->playback.missing, (int) m) <= 0)
1392 pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL);
1393
1394 return 0;
1395 }
1396 }
1397
1398 /* Called from thread context */
1399 static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
1400 connection *c;
1401
1402 pa_sink_input_assert_ref(i);
1403 c = CONNECTION(i->userdata);
1404 connection_assert_ref(c);
1405
1406 /* If we are in an underrun, then we don't rewind */
1407 if (i->thread_info.underrun_for > 0)
1408 return;
1409
1410 pa_memblockq_rewind(c->input_memblockq, nbytes);
1411 }
1412
1413 /* Called from thread context */
1414 static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {
1415 connection *c;
1416
1417 pa_sink_input_assert_ref(i);
1418 c = CONNECTION(i->userdata);
1419 connection_assert_ref(c);
1420
1421 pa_memblockq_set_maxrewind(c->input_memblockq, nbytes);
1422 }
1423
1424 static void sink_input_kill_cb(pa_sink_input *i) {
1425 pa_sink_input_assert_ref(i);
1426
1427 connection_unlink(CONNECTION(i->userdata));
1428 }
1429
1430 /*** source_output callbacks ***/
1431
1432 /* Called from thread context */
1433 static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) {
1434 connection *c;
1435
1436 pa_source_output_assert_ref(o);
1437 c = CONNECTION(o->userdata);
1438 pa_assert(c);
1439 pa_assert(chunk);
1440
1441 pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_POST_DATA, NULL, 0, chunk, NULL);
1442 }
1443
1444 static void source_output_kill_cb(pa_source_output *o) {
1445 pa_source_output_assert_ref(o);
1446
1447 connection_unlink(CONNECTION(o->userdata));
1448 }
1449
1450 static pa_usec_t source_output_get_latency_cb(pa_source_output *o) {
1451 connection*c;
1452
1453 pa_source_output_assert_ref(o);
1454 c = CONNECTION(o->userdata);
1455 pa_assert(c);
1456
1457 return pa_bytes_to_usec(pa_memblockq_get_length(c->output_memblockq), &c->source_output->sample_spec);
1458 }
1459
1460 /*** entry points ***/
1461
1462 static void auth_timeout(pa_mainloop_api *m, pa_time_event *e, const struct timeval *t, void *userdata) {
1463 connection *c = CONNECTION(userdata);
1464
1465 pa_assert(m);
1466 connection_assert_ref(c);
1467 pa_assert(c->auth_timeout_event == e);
1468
1469 if (!c->authorized)
1470 connection_unlink(c);
1471 }
1472
1473 void pa_esound_protocol_connect(pa_esound_protocol *p, pa_iochannel *io, pa_esound_options *o) {
1474 connection *c;
1475 char pname[128];
1476 pa_client_new_data data;
1477 pa_client *client;
1478
1479 pa_assert(p);
1480 pa_assert(io);
1481 pa_assert(o);
1482
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);
1486 return;
1487 }
1488
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);
1497
1498 if (!client)
1499 return;
1500
1501 c = pa_msgobject_new(connection);
1502 c->parent.parent.free = connection_free;
1503 c->parent.process_msg = connection_process_msg;
1504 c->protocol = p;
1505 c->io = io;
1506 pa_iochannel_set_callback(c->io, io_callback, c);
1507
1508 c->client = client;
1509 c->client->kill = client_kill_cb;
1510 c->client->userdata = c;
1511
1512 c->options = pa_esound_options_ref(o);
1513 c->authorized = FALSE;
1514 c->swap_byte_order = FALSE;
1515 c->dead = FALSE;
1516
1517 c->read_data_length = 0;
1518 c->read_data = pa_xmalloc(c->read_data_alloc = proto_map[ESD_PROTO_CONNECT].data_length);
1519
1520 c->write_data_length = c->write_data_index = c->write_data_alloc = 0;
1521 c->write_data = NULL;
1522
1523 c->state = ESD_NEEDS_REQDATA;
1524 c->request = ESD_PROTO_CONNECT;
1525
1526 c->sink_input = NULL;
1527 c->input_memblockq = NULL;
1528
1529 c->source_output = NULL;
1530 c->output_memblockq = NULL;
1531
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);
1536
1537 pa_memchunk_reset(&c->scache.memchunk);
1538 c->scache.name = NULL;
1539
1540 c->original_name = NULL;
1541
1542 if (o->auth_anonymous) {
1543 pa_log_info("Client authenticated anonymously.");
1544 c->authorized = TRUE;
1545 }
1546
1547 if (!c->authorized &&
1548 o->auth_ip_acl &&
1549 pa_ip_acl_check(o->auth_ip_acl, pa_iochannel_get_recv_fd(io)) > 0) {
1550
1551 pa_log_info("Client authenticated by IP ACL.");
1552 c->authorized = TRUE;
1553 }
1554
1555 if (!c->authorized)
1556 c->auth_timeout_event = pa_core_rttime_new(p->core, pa_rtclock_now() + AUTH_TIMEOUT, auth_timeout, c);
1557 else
1558 c->auth_timeout_event = NULL;
1559
1560 c->defer_event = p->core->mainloop->defer_new(p->core->mainloop, defer_callback, c);
1561 p->core->mainloop->defer_enable(c->defer_event, 0);
1562
1563 pa_idxset_put(p->connections, c, &c->index);
1564 }
1565
1566 void pa_esound_protocol_disconnect(pa_esound_protocol *p, pa_module *m) {
1567 connection *c;
1568 void *state = NULL;
1569
1570 pa_assert(p);
1571 pa_assert(m);
1572
1573 while ((c = pa_idxset_iterate(p->connections, &state, NULL)))
1574 if (c->options->module == m)
1575 connection_unlink(c);
1576 }
1577
1578 static pa_esound_protocol* esound_protocol_new(pa_core *c) {
1579 pa_esound_protocol *p;
1580
1581 pa_assert(c);
1582
1583 p = pa_xnew(pa_esound_protocol, 1);
1584 PA_REFCNT_INIT(p);
1585 p->core = c;
1586 p->connections = pa_idxset_new(NULL, NULL);
1587 p->n_player = 0;
1588
1589 pa_assert_se(pa_shared_set(c, "esound-protocol", p) >= 0);
1590
1591 return p;
1592 }
1593
1594 pa_esound_protocol* pa_esound_protocol_get(pa_core *c) {
1595 pa_esound_protocol *p;
1596
1597 if ((p = pa_shared_get(c, "esound-protocol")))
1598 return pa_esound_protocol_ref(p);
1599
1600 return esound_protocol_new(c);
1601 }
1602
1603 pa_esound_protocol* pa_esound_protocol_ref(pa_esound_protocol *p) {
1604 pa_assert(p);
1605 pa_assert(PA_REFCNT_VALUE(p) >= 1);
1606
1607 PA_REFCNT_INC(p);
1608
1609 return p;
1610 }
1611
1612 void pa_esound_protocol_unref(pa_esound_protocol *p) {
1613 connection *c;
1614 pa_assert(p);
1615 pa_assert(PA_REFCNT_VALUE(p) >= 1);
1616
1617 if (PA_REFCNT_DEC(p) > 0)
1618 return;
1619
1620 while ((c = pa_idxset_first(p->connections, NULL)))
1621 connection_unlink(c);
1622
1623 pa_idxset_free(p->connections, NULL, NULL);
1624
1625 pa_assert_se(pa_shared_remove(p->core, "esound-protocol") >= 0);
1626
1627 pa_xfree(p);
1628 }
1629
1630 pa_esound_options* pa_esound_options_new(void) {
1631 pa_esound_options *o;
1632
1633 o = pa_xnew0(pa_esound_options, 1);
1634 PA_REFCNT_INIT(o);
1635
1636 return o;
1637 }
1638
1639 pa_esound_options* pa_esound_options_ref(pa_esound_options *o) {
1640 pa_assert(o);
1641 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1642
1643 PA_REFCNT_INC(o);
1644
1645 return o;
1646 }
1647
1648 void pa_esound_options_unref(pa_esound_options *o) {
1649 pa_assert(o);
1650 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1651
1652 if (PA_REFCNT_DEC(o) > 0)
1653 return;
1654
1655 if (o->auth_ip_acl)
1656 pa_ip_acl_free(o->auth_ip_acl);
1657
1658 if (o->auth_cookie)
1659 pa_auth_cookie_unref(o->auth_cookie);
1660
1661 pa_xfree(o->default_sink);
1662 pa_xfree(o->default_source);
1663
1664 pa_xfree(o);
1665 }
1666
1667 int pa_esound_options_parse(pa_esound_options *o, pa_core *c, pa_modargs *ma) {
1668 pa_bool_t enabled;
1669 const char *acl;
1670
1671 pa_assert(o);
1672 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1673 pa_assert(ma);
1674
1675 if (pa_modargs_get_value_boolean(ma, "auth-anonymous", &o->auth_anonymous) < 0) {
1676 pa_log("auth-anonymous= expects a boolean argument.");
1677 return -1;
1678 }
1679
1680 if ((acl = pa_modargs_get_value(ma, "auth-ip-acl", NULL))) {
1681 pa_ip_acl *ipa;
1682
1683 if (!(ipa = pa_ip_acl_new(acl))) {
1684 pa_log("Failed to parse IP ACL '%s'", acl);
1685 return -1;
1686 }
1687
1688 if (o->auth_ip_acl)
1689 pa_ip_acl_free(o->auth_ip_acl);
1690
1691 o->auth_ip_acl = ipa;
1692 }
1693
1694 enabled = TRUE;
1695 if (pa_modargs_get_value_boolean(ma, "auth-cookie-enabled", &enabled) < 0) {
1696 pa_log("auth-cookie-enabled= expects a boolean argument.");
1697 return -1;
1698 }
1699
1700 if (o->auth_cookie)
1701 pa_auth_cookie_unref(o->auth_cookie);
1702
1703 if (enabled) {
1704 const char *cn;
1705
1706 /* The new name for this is 'auth-cookie', for compat reasons
1707 * we check the old name too */
1708 if (!(cn = pa_modargs_get_value(ma, "auth-cookie", NULL)))
1709 if (!(cn = pa_modargs_get_value(ma, "cookie", NULL)))
1710 cn = DEFAULT_COOKIE_FILE;
1711
1712 if (!(o->auth_cookie = pa_auth_cookie_get(c, cn, ESD_KEY_LEN)))
1713 return -1;
1714
1715 } else
1716 o->auth_cookie = NULL;
1717
1718 pa_xfree(o->default_sink);
1719 o->default_sink = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
1720
1721 pa_xfree(o->default_source);
1722 o->default_source = pa_xstrdup(pa_modargs_get_value(ma, "source", NULL));
1723
1724 return 0;
1725 }