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