]> code.delx.au - pulseaudio/blob - src/pulsecore/protocol-esound.c
iochannel: Avoid unnecessary wakeup after successful write
[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 "esound protocol connection input_memblockq",
440 0,
441 l,
442 l,
443 &ss,
444 (size_t) -1,
445 l/PLAYBACK_BUFFER_FRAGMENTS,
446 0,
447 &silence);
448 pa_memblock_unref(silence.memblock);
449 pa_iochannel_socket_set_rcvbuf(c->io, l);
450
451 c->sink_input->parent.process_msg = sink_input_process_msg;
452 c->sink_input->pop = sink_input_pop_cb;
453 c->sink_input->process_rewind = sink_input_process_rewind_cb;
454 c->sink_input->update_max_rewind = sink_input_update_max_rewind_cb;
455 c->sink_input->kill = sink_input_kill_cb;
456 c->sink_input->userdata = c;
457
458 pa_sink_input_set_requested_latency(c->sink_input, DEFAULT_SINK_LATENCY);
459
460 c->state = ESD_STREAMING_DATA;
461
462 c->protocol->n_player++;
463
464 pa_atomic_store(&c->playback.missing, (int) pa_memblockq_pop_missing(c->input_memblockq));
465
466 pa_sink_input_put(c->sink_input);
467
468 return 0;
469 }
470
471 static int esd_proto_stream_record(connection *c, esd_proto_t request, const void *data, size_t length) {
472 char name[ESD_NAME_MAX], *utf8_name;
473 int32_t format, rate;
474 pa_source *source = NULL;
475 pa_sample_spec ss;
476 size_t l;
477 pa_source_output_new_data sdata;
478
479 connection_assert_ref(c);
480 pa_assert(data);
481 pa_assert(length == (sizeof(int32_t)*2+ESD_NAME_MAX));
482
483 memcpy(&format, data, sizeof(int32_t));
484 format = PA_MAYBE_INT32_SWAP(c->swap_byte_order, format);
485 data = (const char*) data + sizeof(int32_t);
486
487 memcpy(&rate, data, sizeof(int32_t));
488 rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate);
489 data = (const char*) data + sizeof(int32_t);
490
491 ss.rate = (uint32_t) rate;
492 format_esd2native(format, c->swap_byte_order, &ss);
493
494 CHECK_VALIDITY(pa_sample_spec_valid(&ss), "Invalid sample specification.");
495
496 if (request == ESD_PROTO_STREAM_MON) {
497 pa_sink* sink;
498
499 sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK);
500 CHECK_VALIDITY(sink, "No such sink: %s", pa_strnull(c->options->default_sink));
501
502 source = sink->monitor_source;
503 CHECK_VALIDITY(source, "No such source.");
504 } else {
505 pa_assert(request == ESD_PROTO_STREAM_REC);
506
507 if (c->options->default_source) {
508 source = pa_namereg_get(c->protocol->core, c->options->default_source, PA_NAMEREG_SOURCE);
509 CHECK_VALIDITY(source, "No such source: %s", pa_strnull(c->options->default_source));
510 }
511 }
512
513 pa_strlcpy(name, data, sizeof(name));
514
515 utf8_name = pa_utf8_filter(name);
516 pa_client_set_name(c->client, utf8_name);
517 pa_xfree(utf8_name);
518
519 c->original_name = pa_xstrdup(name);
520
521 pa_assert(!c->output_memblockq && !c->source_output);
522
523 pa_source_output_new_data_init(&sdata);
524 sdata.driver = __FILE__;
525 sdata.module = c->options->module;
526 sdata.client = c->client;
527 if (source)
528 pa_source_output_new_data_set_source(&sdata, source, FALSE);
529 pa_source_output_new_data_set_sample_spec(&sdata, &ss);
530
531 pa_source_output_new(&c->source_output, c->protocol->core, &sdata);
532 pa_source_output_new_data_done(&sdata);
533
534 CHECK_VALIDITY(c->source_output, "Failed to create source output.");
535
536 l = (size_t) (pa_bytes_per_second(&ss)*RECORD_BUFFER_SECONDS);
537 c->output_memblockq = pa_memblockq_new(
538 "esound protocol connection output_memblockq",
539 0,
540 l,
541 l,
542 &ss,
543 1,
544 0,
545 0,
546 NULL);
547 pa_iochannel_socket_set_sndbuf(c->io, l);
548
549 c->source_output->push = source_output_push_cb;
550 c->source_output->kill = source_output_kill_cb;
551 c->source_output->get_latency = source_output_get_latency_cb;
552 c->source_output->userdata = c;
553
554 pa_source_output_set_requested_latency(c->source_output, DEFAULT_SOURCE_LATENCY);
555
556 c->state = ESD_STREAMING_DATA;
557
558 c->protocol->n_player++;
559
560 pa_source_output_put(c->source_output);
561
562 return 0;
563 }
564
565 static int esd_proto_get_latency(connection *c, esd_proto_t request, const void *data, size_t length) {
566 pa_sink *sink;
567 int32_t latency;
568
569 connection_assert_ref(c);
570 pa_assert(!data);
571 pa_assert(length == 0);
572
573 if (!(sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK)))
574 latency = 0;
575 else {
576 double usec = (double) pa_sink_get_requested_latency(sink);
577 latency = (int) ((usec*44100)/1000000);
578 }
579
580 latency = PA_MAYBE_INT32_SWAP(c->swap_byte_order, latency);
581 connection_write(c, &latency, sizeof(int32_t));
582
583 return 0;
584 }
585
586 static int esd_proto_server_info(connection *c, esd_proto_t request, const void *data, size_t length) {
587 int32_t rate = 44100, format = ESD_STEREO|ESD_BITS16;
588 int32_t response;
589 pa_sink *sink;
590
591 connection_assert_ref(c);
592 pa_assert(data);
593 pa_assert(length == sizeof(int32_t));
594
595 if ((sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK))) {
596 rate = (int32_t) sink->sample_spec.rate;
597 format = format_native2esd(&sink->sample_spec);
598 }
599
600 connection_write_prepare(c, sizeof(int32_t) * 3);
601
602 response = 0;
603 connection_write(c, &response, sizeof(int32_t));
604 rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate);
605 connection_write(c, &rate, sizeof(int32_t));
606 format = PA_MAYBE_INT32_SWAP(c->swap_byte_order, format);
607 connection_write(c, &format, sizeof(int32_t));
608
609 return 0;
610 }
611
612 static int esd_proto_all_info(connection *c, esd_proto_t request, const void *data, size_t length) {
613 size_t t, k, s;
614 connection *conn;
615 uint32_t idx = PA_IDXSET_INVALID;
616 unsigned nsamples;
617 char terminator[sizeof(int32_t)*6+ESD_NAME_MAX];
618
619 connection_assert_ref(c);
620 pa_assert(data);
621 pa_assert(length == sizeof(int32_t));
622
623 if (esd_proto_server_info(c, request, data, length) < 0)
624 return -1;
625
626 k = sizeof(int32_t)*5+ESD_NAME_MAX;
627 s = sizeof(int32_t)*6+ESD_NAME_MAX;
628 nsamples = pa_idxset_size(c->protocol->core->scache);
629 t = s*(nsamples+1) + k*(c->protocol->n_player+1);
630
631 connection_write_prepare(c, t);
632
633 memset(terminator, 0, sizeof(terminator));
634
635 PA_IDXSET_FOREACH(conn, c->protocol->connections, idx) {
636 int32_t id, format = ESD_BITS16 | ESD_STEREO, rate = 44100, lvolume = ESD_VOLUME_BASE, rvolume = ESD_VOLUME_BASE;
637 char name[ESD_NAME_MAX];
638
639 if (conn->state != ESD_STREAMING_DATA)
640 continue;
641
642 pa_assert(t >= k*2+s);
643
644 if (conn->sink_input) {
645 pa_cvolume volume;
646 pa_sink_input_get_volume(conn->sink_input, &volume, TRUE);
647 rate = (int32_t) conn->sink_input->sample_spec.rate;
648 lvolume = (int32_t) ((volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM);
649 rvolume = (int32_t) ((volume.values[volume.channels == 2 ? 1 : 0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM);
650 format = format_native2esd(&conn->sink_input->sample_spec);
651 }
652
653 /* id */
654 id = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) (conn->index+1));
655 connection_write(c, &id, sizeof(int32_t));
656
657 /* name */
658 memset(name, 0, ESD_NAME_MAX); /* don't leak old data */
659 if (conn->original_name)
660 strncpy(name, conn->original_name, ESD_NAME_MAX);
661 else if (conn->client && pa_proplist_gets(conn->client->proplist, PA_PROP_APPLICATION_NAME))
662 strncpy(name, pa_proplist_gets(conn->client->proplist, PA_PROP_APPLICATION_NAME), ESD_NAME_MAX);
663 connection_write(c, name, ESD_NAME_MAX);
664
665 /* rate */
666 rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate);
667 connection_write(c, &rate, sizeof(int32_t));
668
669 /* left */
670 lvolume = PA_MAYBE_INT32_SWAP(c->swap_byte_order, lvolume);
671 connection_write(c, &lvolume, sizeof(int32_t));
672
673 /*right*/
674 rvolume = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rvolume);
675 connection_write(c, &rvolume, sizeof(int32_t));
676
677 /*format*/
678 format = PA_MAYBE_INT32_SWAP(c->swap_byte_order, format);
679 connection_write(c, &format, sizeof(int32_t));
680
681 t -= k;
682 }
683
684 pa_assert(t == s*(nsamples+1)+k);
685 t -= k;
686
687 connection_write(c, terminator, k);
688
689 if (nsamples) {
690 pa_scache_entry *ce;
691
692 idx = PA_IDXSET_INVALID;
693
694 PA_IDXSET_FOREACH(ce, c->protocol->core->scache, idx) {
695 int32_t id, rate, lvolume, rvolume, format, len;
696 char name[ESD_NAME_MAX];
697 pa_channel_map stereo = { .channels = 2, .map = { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT } };
698 pa_cvolume volume;
699 pa_sample_spec ss;
700
701 pa_assert(t >= s*2);
702
703 if (ce->volume_is_set) {
704 volume = ce->volume;
705 pa_cvolume_remap(&volume, &ce->channel_map, &stereo);
706 } else
707 pa_cvolume_reset(&volume, 2);
708
709 if (ce->memchunk.memblock)
710 ss = ce->sample_spec;
711 else {
712 ss.format = PA_SAMPLE_S16NE;
713 ss.rate = 44100;
714 ss.channels = 2;
715 }
716
717 /* id */
718 id = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int) (ce->index+1));
719 connection_write(c, &id, sizeof(int32_t));
720
721 /* name */
722 memset(name, 0, ESD_NAME_MAX); /* don't leak old data */
723 if (strncmp(ce->name, SCACHE_PREFIX, sizeof(SCACHE_PREFIX)-1) == 0)
724 strncpy(name, ce->name+sizeof(SCACHE_PREFIX)-1, ESD_NAME_MAX);
725 else
726 pa_snprintf(name, ESD_NAME_MAX, "native.%s", ce->name);
727 connection_write(c, name, ESD_NAME_MAX);
728
729 /* rate */
730 rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) ss.rate);
731 connection_write(c, &rate, sizeof(int32_t));
732
733 /* left */
734 lvolume = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) ((volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM));
735 connection_write(c, &lvolume, sizeof(int32_t));
736
737 /*right*/
738 rvolume = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) ((volume.values[1]*ESD_VOLUME_BASE)/PA_VOLUME_NORM));
739 connection_write(c, &rvolume, sizeof(int32_t));
740
741 /*format*/
742 format = PA_MAYBE_INT32_SWAP(c->swap_byte_order, format_native2esd(&ss));
743 connection_write(c, &format, sizeof(int32_t));
744
745 /*length*/
746 len = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int) ce->memchunk.length);
747 connection_write(c, &len, sizeof(int32_t));
748
749 t -= s;
750 }
751 }
752
753 pa_assert(t == s);
754
755 connection_write(c, terminator, s);
756
757 return 0;
758 }
759
760 static int esd_proto_stream_pan(connection *c, esd_proto_t request, const void *data, size_t length) {
761 int32_t ok;
762 uint32_t idx, lvolume, rvolume;
763 connection *conn;
764
765 connection_assert_ref(c);
766 pa_assert(data);
767 pa_assert(length == sizeof(int32_t)*3);
768
769 memcpy(&idx, data, sizeof(uint32_t));
770 idx = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, idx) - 1;
771 data = (const char*)data + sizeof(uint32_t);
772
773 memcpy(&lvolume, data, sizeof(uint32_t));
774 lvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, lvolume);
775 data = (const char*)data + sizeof(uint32_t);
776
777 memcpy(&rvolume, data, sizeof(uint32_t));
778 rvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, rvolume);
779
780 if ((conn = pa_idxset_get_by_index(c->protocol->connections, idx)) && conn->sink_input) {
781 pa_cvolume volume;
782 volume.values[0] = (lvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE;
783 volume.values[1] = (rvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE;
784 volume.channels = conn->sink_input->sample_spec.channels;
785
786 pa_sink_input_set_volume(conn->sink_input, &volume, TRUE, TRUE);
787 ok = 1;
788 } else
789 ok = 0;
790
791 connection_write(c, &ok, sizeof(int32_t));
792
793 return 0;
794 }
795
796 static int esd_proto_sample_pan(connection *c, esd_proto_t request, const void *data, size_t length) {
797 int32_t ok = 0;
798 uint32_t idx, lvolume, rvolume;
799 pa_cvolume volume;
800 pa_scache_entry *ce;
801
802 connection_assert_ref(c);
803 pa_assert(data);
804 pa_assert(length == sizeof(int32_t)*3);
805
806 memcpy(&idx, data, sizeof(uint32_t));
807 idx = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, idx) - 1;
808 data = (const char*)data + sizeof(uint32_t);
809
810 memcpy(&lvolume, data, sizeof(uint32_t));
811 lvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, lvolume);
812 data = (const char*)data + sizeof(uint32_t);
813
814 memcpy(&rvolume, data, sizeof(uint32_t));
815 rvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, rvolume);
816
817 volume.values[0] = (lvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE;
818 volume.values[1] = (rvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE;
819 volume.channels = 2;
820
821 if ((ce = pa_idxset_get_by_index(c->protocol->core->scache, idx))) {
822 pa_channel_map stereo = { .channels = 2, .map = { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT } };
823
824 pa_cvolume_remap(&volume, &stereo, &ce->channel_map);
825 ce->volume = volume;
826 ce->volume_is_set = TRUE;
827 ok = 1;
828 }
829
830 connection_write(c, &ok, sizeof(int32_t));
831
832 return 0;
833 }
834
835 static int esd_proto_sample_cache(connection *c, esd_proto_t request, const void *data, size_t length) {
836 pa_sample_spec ss;
837 int32_t format, rate, sc_length;
838 uint32_t idx;
839 char name[ESD_NAME_MAX+sizeof(SCACHE_PREFIX)-1];
840
841 connection_assert_ref(c);
842 pa_assert(data);
843 pa_assert(length == (ESD_NAME_MAX+3*sizeof(int32_t)));
844
845 memcpy(&format, data, sizeof(int32_t));
846 format = PA_MAYBE_INT32_SWAP(c->swap_byte_order, format);
847 data = (const char*)data + sizeof(int32_t);
848
849 memcpy(&rate, data, sizeof(int32_t));
850 rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate);
851 data = (const char*)data + sizeof(int32_t);
852
853 ss.rate = (uint32_t) rate;
854 format_esd2native(format, c->swap_byte_order, &ss);
855
856 CHECK_VALIDITY(pa_sample_spec_valid(&ss), "Invalid sample specification.");
857
858 memcpy(&sc_length, data, sizeof(int32_t));
859 sc_length = PA_MAYBE_INT32_SWAP(c->swap_byte_order, sc_length);
860 data = (const char*)data + sizeof(int32_t);
861
862 CHECK_VALIDITY(sc_length <= MAX_CACHE_SAMPLE_SIZE, "Sample too large (%d bytes).", (int)sc_length);
863
864 strcpy(name, SCACHE_PREFIX);
865 pa_strlcpy(name+sizeof(SCACHE_PREFIX)-1, data, ESD_NAME_MAX);
866
867 CHECK_VALIDITY(pa_utf8_valid(name), "Invalid UTF8 in sample name.");
868
869 pa_assert(!c->scache.memchunk.memblock);
870 c->scache.memchunk.memblock = pa_memblock_new(c->protocol->core->mempool, (size_t) sc_length);
871 c->scache.memchunk.index = 0;
872 c->scache.memchunk.length = (size_t) sc_length;
873 c->scache.sample_spec = ss;
874 pa_assert(!c->scache.name);
875 c->scache.name = pa_xstrdup(name);
876
877 c->state = ESD_CACHING_SAMPLE;
878
879 pa_scache_add_item(c->protocol->core, c->scache.name, NULL, NULL, NULL, c->client->proplist, &idx);
880
881 idx += 1;
882 connection_write(c, &idx, sizeof(uint32_t));
883
884 return 0;
885 }
886
887 static int esd_proto_sample_get_id(connection *c, esd_proto_t request, const void *data, size_t length) {
888 int32_t ok;
889 uint32_t idx;
890 char name[ESD_NAME_MAX+sizeof(SCACHE_PREFIX)-1];
891
892 connection_assert_ref(c);
893 pa_assert(data);
894 pa_assert(length == ESD_NAME_MAX);
895
896 strcpy(name, SCACHE_PREFIX);
897 pa_strlcpy(name+sizeof(SCACHE_PREFIX)-1, data, ESD_NAME_MAX);
898
899 CHECK_VALIDITY(pa_utf8_valid(name), "Invalid UTF8 in sample name.");
900
901 ok = -1;
902 if ((idx = pa_scache_get_id_by_name(c->protocol->core, name)) != PA_IDXSET_INVALID)
903 ok = (int32_t) idx + 1;
904
905 connection_write(c, &ok, sizeof(int32_t));
906
907 return 0;
908 }
909
910 static int esd_proto_sample_free_or_play(connection *c, esd_proto_t request, const void *data, size_t length) {
911 int32_t ok;
912 const char *name;
913 uint32_t idx;
914
915 connection_assert_ref(c);
916 pa_assert(data);
917 pa_assert(length == sizeof(int32_t));
918
919 memcpy(&idx, data, sizeof(uint32_t));
920 idx = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, idx) - 1;
921
922 ok = 0;
923
924 if ((name = pa_scache_get_name_by_id(c->protocol->core, idx))) {
925 if (request == ESD_PROTO_SAMPLE_PLAY) {
926 pa_sink *sink;
927
928 if ((sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK)))
929 if (pa_scache_play_item(c->protocol->core, name, sink, PA_VOLUME_NORM, c->client->proplist, NULL) >= 0)
930 ok = (int32_t) idx + 1;
931 } else {
932 pa_assert(request == ESD_PROTO_SAMPLE_FREE);
933
934 if (pa_scache_remove_item(c->protocol->core, name) >= 0)
935 ok = (int32_t) idx + 1;
936 }
937 }
938
939 connection_write(c, &ok, sizeof(int32_t));
940
941 return 0;
942 }
943
944 static int esd_proto_standby_or_resume(connection *c, esd_proto_t request, const void *data, size_t length) {
945 int32_t ok = 1;
946
947 connection_assert_ref(c);
948
949 connection_write_prepare(c, sizeof(int32_t) * 2);
950 connection_write(c, &ok, sizeof(int32_t));
951
952 pa_log_debug("%s of all sinks and sources requested by client %" PRIu32 ".",
953 request == ESD_PROTO_STANDBY ? "Suspending" : "Resuming", c->client->index);
954
955 if (request == ESD_PROTO_STANDBY) {
956 ok = pa_sink_suspend_all(c->protocol->core, true, PA_SUSPEND_USER) >= 0;
957 ok &= pa_source_suspend_all(c->protocol->core, true, PA_SUSPEND_USER) >= 0;
958 } else {
959 pa_assert(request == ESD_PROTO_RESUME);
960 ok = pa_sink_suspend_all(c->protocol->core, false, PA_SUSPEND_USER) >= 0;
961 ok &= pa_source_suspend_all(c->protocol->core, false, PA_SUSPEND_USER) >= 0;
962 }
963
964 connection_write(c, &ok, sizeof(int32_t));
965
966 return 0;
967 }
968
969 static int esd_proto_standby_mode(connection *c, esd_proto_t request, const void *data, size_t length) {
970 int32_t mode;
971 pa_sink *sink, *source;
972
973 connection_assert_ref(c);
974
975 mode = ESM_RUNNING;
976
977 if ((sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK)))
978 if (pa_sink_get_state(sink) == PA_SINK_SUSPENDED)
979 mode = ESM_ON_STANDBY;
980
981 if ((source = pa_namereg_get(c->protocol->core, c->options->default_source, PA_NAMEREG_SOURCE)))
982 if (pa_source_get_state(source) == PA_SOURCE_SUSPENDED)
983 mode = ESM_ON_STANDBY;
984
985 mode = PA_MAYBE_INT32_SWAP(c->swap_byte_order, mode);
986
987 connection_write(c, &mode, sizeof(mode));
988 return 0;
989 }
990
991 /*** client callbacks ***/
992
993 static void client_kill_cb(pa_client *c) {
994 pa_assert(c);
995
996 connection_unlink(CONNECTION(c->userdata));
997 }
998
999 /*** pa_iochannel callbacks ***/
1000
1001 static int do_read(connection *c) {
1002 connection_assert_ref(c);
1003
1004 /* pa_log("READ"); */
1005
1006 if (c->state == ESD_NEXT_REQUEST) {
1007 ssize_t r;
1008 pa_assert(c->read_data_length < sizeof(c->request));
1009
1010 if ((r = pa_iochannel_read(c->io,
1011 ((uint8_t*) &c->request) + c->read_data_length,
1012 sizeof(c->request) - c->read_data_length)) <= 0) {
1013
1014 if (r < 0 && (errno == EINTR || errno == EAGAIN))
1015 return 0;
1016
1017 pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF");
1018 return -1;
1019 }
1020
1021 c->read_data_length += (size_t) r;
1022
1023 if (c->read_data_length >= sizeof(c->request)) {
1024 struct proto_handler *handler;
1025
1026 c->request = PA_MAYBE_INT32_SWAP(c->swap_byte_order, c->request);
1027
1028 if (c->request < ESD_PROTO_CONNECT || c->request >= ESD_PROTO_MAX) {
1029 pa_log("received invalid request.");
1030 return -1;
1031 }
1032
1033 handler = proto_map+c->request;
1034
1035 /* pa_log("executing request #%u", c->request); */
1036
1037 if (!handler->proc) {
1038 pa_log("received unimplemented request #%u.", c->request);
1039 return -1;
1040 }
1041
1042 if (handler->data_length == 0) {
1043 c->read_data_length = 0;
1044
1045 if (handler->proc(c, c->request, NULL, 0) < 0)
1046 return -1;
1047
1048 } else {
1049 if (c->read_data_alloc < handler->data_length)
1050 c->read_data = pa_xrealloc(c->read_data, c->read_data_alloc = handler->data_length);
1051 pa_assert(c->read_data);
1052
1053 c->state = ESD_NEEDS_REQDATA;
1054 c->read_data_length = 0;
1055 }
1056 }
1057
1058 } else if (c->state == ESD_NEEDS_REQDATA) {
1059 ssize_t r;
1060 struct proto_handler *handler = proto_map+c->request;
1061
1062 pa_assert(handler->proc);
1063
1064 pa_assert(c->read_data && c->read_data_length < handler->data_length);
1065
1066 if ((r = pa_iochannel_read(c->io,
1067 (uint8_t*) c->read_data + c->read_data_length,
1068 handler->data_length - c->read_data_length)) <= 0) {
1069
1070 if (r < 0 && (errno == EINTR || errno == EAGAIN))
1071 return 0;
1072
1073 pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF");
1074 return -1;
1075 }
1076
1077 c->read_data_length += (size_t) r;
1078 if (c->read_data_length >= handler->data_length) {
1079 size_t l = c->read_data_length;
1080 pa_assert(handler->proc);
1081
1082 c->state = ESD_NEXT_REQUEST;
1083 c->read_data_length = 0;
1084
1085 if (handler->proc(c, c->request, c->read_data, l) < 0)
1086 return -1;
1087 }
1088 } else if (c->state == ESD_CACHING_SAMPLE) {
1089 ssize_t r;
1090 void *p;
1091
1092 pa_assert(c->scache.memchunk.memblock);
1093 pa_assert(c->scache.name);
1094 pa_assert(c->scache.memchunk.index < c->scache.memchunk.length);
1095
1096 p = pa_memblock_acquire(c->scache.memchunk.memblock);
1097 r = pa_iochannel_read(c->io, (uint8_t*) p+c->scache.memchunk.index, c->scache.memchunk.length-c->scache.memchunk.index);
1098 pa_memblock_release(c->scache.memchunk.memblock);
1099
1100 if (r <= 0) {
1101 if (r < 0 && (errno == EINTR || errno == EAGAIN))
1102 return 0;
1103
1104 pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF");
1105 return -1;
1106 }
1107
1108 c->scache.memchunk.index += (size_t) r;
1109 pa_assert(c->scache.memchunk.index <= c->scache.memchunk.length);
1110
1111 if (c->scache.memchunk.index == c->scache.memchunk.length) {
1112 uint32_t idx;
1113
1114 c->scache.memchunk.index = 0;
1115 pa_scache_add_item(c->protocol->core, c->scache.name, &c->scache.sample_spec, NULL, &c->scache.memchunk, c->client->proplist, &idx);
1116
1117 pa_memblock_unref(c->scache.memchunk.memblock);
1118 pa_memchunk_reset(&c->scache.memchunk);
1119
1120 pa_xfree(c->scache.name);
1121 c->scache.name = NULL;
1122
1123 c->state = ESD_NEXT_REQUEST;
1124
1125 idx += 1;
1126 connection_write(c, &idx, sizeof(uint32_t));
1127 }
1128
1129 } else if (c->state == ESD_STREAMING_DATA && c->sink_input) {
1130 pa_memchunk chunk;
1131 ssize_t r;
1132 size_t l;
1133 void *p;
1134 size_t space = 0;
1135
1136 pa_assert(c->input_memblockq);
1137
1138 /* pa_log("STREAMING_DATA"); */
1139
1140 if ((l = (size_t) pa_atomic_load(&c->playback.missing)) <= 0)
1141 return 0;
1142
1143 if (c->playback.current_memblock) {
1144
1145 space = pa_memblock_get_length(c->playback.current_memblock) - c->playback.memblock_index;
1146
1147 if (space <= 0) {
1148 pa_memblock_unref(c->playback.current_memblock);
1149 c->playback.current_memblock = NULL;
1150 }
1151 }
1152
1153 if (!c->playback.current_memblock) {
1154 pa_assert_se(c->playback.current_memblock = pa_memblock_new(c->protocol->core->mempool, (size_t) -1));
1155 c->playback.memblock_index = 0;
1156
1157 space = pa_memblock_get_length(c->playback.current_memblock);
1158 }
1159
1160 if (l > space)
1161 l = space;
1162
1163 p = pa_memblock_acquire(c->playback.current_memblock);
1164 r = pa_iochannel_read(c->io, (uint8_t*) p+c->playback.memblock_index, l);
1165 pa_memblock_release(c->playback.current_memblock);
1166
1167 if (r <= 0) {
1168
1169 if (r < 0 && (errno == EINTR || errno == EAGAIN))
1170 return 0;
1171
1172 pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF");
1173 return -1;
1174 }
1175
1176 chunk.memblock = c->playback.current_memblock;
1177 chunk.index = c->playback.memblock_index;
1178 chunk.length = (size_t) r;
1179
1180 c->playback.memblock_index += (size_t) r;
1181
1182 pa_atomic_sub(&c->playback.missing, (int) r);
1183 pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, 0, &chunk, NULL);
1184 }
1185
1186 return 0;
1187 }
1188
1189 static int do_write(connection *c) {
1190 connection_assert_ref(c);
1191
1192 /* pa_log("WRITE"); */
1193
1194 if (c->write_data_length) {
1195 ssize_t r;
1196
1197 pa_assert(c->write_data_index < c->write_data_length);
1198 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) {
1199
1200 if (r < 0 && (errno == EINTR || errno == EAGAIN))
1201 return 0;
1202
1203 pa_log("write(): %s", pa_cstrerror(errno));
1204 return -1;
1205 }
1206
1207 c->write_data_index += (size_t) r;
1208 if (c->write_data_index >= c->write_data_length)
1209 c->write_data_length = c->write_data_index = 0;
1210
1211 } else if (c->state == ESD_STREAMING_DATA && c->source_output) {
1212 pa_memchunk chunk;
1213 ssize_t r;
1214 void *p;
1215
1216 if (pa_memblockq_peek(c->output_memblockq, &chunk) < 0)
1217 return 0;
1218
1219 pa_assert(chunk.memblock);
1220 pa_assert(chunk.length);
1221
1222 p = pa_memblock_acquire(chunk.memblock);
1223 r = pa_iochannel_write(c->io, (uint8_t*) p+chunk.index, chunk.length);
1224 pa_memblock_release(chunk.memblock);
1225
1226 pa_memblock_unref(chunk.memblock);
1227
1228 if (r < 0) {
1229 pa_log("write(): %s", pa_cstrerror(errno));
1230 return -1;
1231 }
1232
1233 pa_memblockq_drop(c->output_memblockq, (size_t) r);
1234 }
1235
1236 return 0;
1237 }
1238
1239 static void do_work(connection *c) {
1240 connection_assert_ref(c);
1241
1242 c->protocol->core->mainloop->defer_enable(c->defer_event, 0);
1243
1244 if (c->dead)
1245 return;
1246
1247 if (pa_iochannel_is_readable(c->io))
1248 if (do_read(c) < 0)
1249 goto fail;
1250
1251 if (c->state == ESD_STREAMING_DATA && !c->sink_input && pa_iochannel_is_hungup(c->io))
1252 /* In case we are in capture mode we will never call read()
1253 * on the socket, hence we need to detect the hangup manually
1254 * here, instead of simply waiting for read() to return 0. */
1255 goto fail;
1256
1257 if (pa_iochannel_is_writable(c->io))
1258 if (do_write(c) < 0)
1259 goto fail;
1260
1261 return;
1262
1263 fail:
1264
1265 if (c->state == ESD_STREAMING_DATA && c->sink_input) {
1266 c->dead = TRUE;
1267
1268 pa_iochannel_free(c->io);
1269 c->io = NULL;
1270
1271 pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_DISABLE_PREBUF, NULL, 0, NULL, NULL);
1272 } else
1273 connection_unlink(c);
1274 }
1275
1276 static void io_callback(pa_iochannel*io, void *userdata) {
1277 connection *c = CONNECTION(userdata);
1278
1279 connection_assert_ref(c);
1280 pa_assert(io);
1281
1282 do_work(c);
1283 }
1284
1285 static void defer_callback(pa_mainloop_api*a, pa_defer_event *e, void *userdata) {
1286 connection *c = CONNECTION(userdata);
1287
1288 connection_assert_ref(c);
1289 pa_assert(e);
1290
1291 do_work(c);
1292 }
1293
1294 static int connection_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) {
1295 connection *c = CONNECTION(o);
1296 connection_assert_ref(c);
1297
1298 if (!c->protocol)
1299 return -1;
1300
1301 switch (code) {
1302 case CONNECTION_MESSAGE_REQUEST_DATA:
1303 do_work(c);
1304 break;
1305
1306 case CONNECTION_MESSAGE_POST_DATA:
1307 /* pa_log("got data %u", chunk->length); */
1308 pa_memblockq_push_align(c->output_memblockq, chunk);
1309 do_work(c);
1310 break;
1311
1312 case CONNECTION_MESSAGE_UNLINK_CONNECTION:
1313 connection_unlink(c);
1314 break;
1315 }
1316
1317 return 0;
1318 }
1319
1320 /*** sink_input callbacks ***/
1321
1322 /* Called from thread context */
1323 static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
1324 pa_sink_input *i = PA_SINK_INPUT(o);
1325 connection*c;
1326
1327 pa_sink_input_assert_ref(i);
1328 c = CONNECTION(i->userdata);
1329 connection_assert_ref(c);
1330
1331 switch (code) {
1332
1333 case SINK_INPUT_MESSAGE_POST_DATA: {
1334 pa_assert(chunk);
1335
1336 /* New data from the main loop */
1337 pa_memblockq_push_align(c->input_memblockq, chunk);
1338
1339 if (pa_memblockq_is_readable(c->input_memblockq) && c->playback.underrun) {
1340 pa_log_debug("Requesting rewind due to end of underrun.");
1341 pa_sink_input_request_rewind(c->sink_input, 0, FALSE, TRUE, FALSE);
1342 }
1343
1344 /* pa_log("got data, %u", pa_memblockq_get_length(c->input_memblockq)); */
1345
1346 return 0;
1347 }
1348
1349 case SINK_INPUT_MESSAGE_DISABLE_PREBUF:
1350 pa_memblockq_prebuf_disable(c->input_memblockq);
1351 return 0;
1352
1353 case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
1354 pa_usec_t *r = userdata;
1355
1356 *r = pa_bytes_to_usec(pa_memblockq_get_length(c->input_memblockq), &c->sink_input->sample_spec);
1357
1358 /* Fall through, the default handler will add in the extra
1359 * latency added by the resampler */
1360 }
1361
1362 default:
1363 return pa_sink_input_process_msg(o, code, userdata, offset, chunk);
1364 }
1365 }
1366
1367 /* Called from thread context */
1368 static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) {
1369 connection*c;
1370
1371 pa_sink_input_assert_ref(i);
1372 c = CONNECTION(i->userdata);
1373 connection_assert_ref(c);
1374 pa_assert(chunk);
1375
1376 if (pa_memblockq_peek(c->input_memblockq, chunk) < 0) {
1377
1378 c->playback.underrun = TRUE;
1379
1380 if (c->dead && pa_sink_input_safe_to_remove(i))
1381 pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_UNLINK_CONNECTION, NULL, 0, NULL, NULL);
1382
1383 return -1;
1384 } else {
1385 size_t m;
1386
1387 c->playback.underrun = FALSE;
1388
1389 chunk->length = PA_MIN(length, chunk->length);
1390 pa_memblockq_drop(c->input_memblockq, chunk->length);
1391 m = pa_memblockq_pop_missing(c->input_memblockq);
1392
1393 if (m > 0)
1394 if (pa_atomic_add(&c->playback.missing, (int) m) <= 0)
1395 pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL);
1396
1397 return 0;
1398 }
1399 }
1400
1401 /* Called from thread context */
1402 static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
1403 connection *c;
1404
1405 pa_sink_input_assert_ref(i);
1406 c = CONNECTION(i->userdata);
1407 connection_assert_ref(c);
1408
1409 /* If we are in an underrun, then we don't rewind */
1410 if (i->thread_info.underrun_for > 0)
1411 return;
1412
1413 pa_memblockq_rewind(c->input_memblockq, nbytes);
1414 }
1415
1416 /* Called from thread context */
1417 static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {
1418 connection *c;
1419
1420 pa_sink_input_assert_ref(i);
1421 c = CONNECTION(i->userdata);
1422 connection_assert_ref(c);
1423
1424 pa_memblockq_set_maxrewind(c->input_memblockq, nbytes);
1425 }
1426
1427 static void sink_input_kill_cb(pa_sink_input *i) {
1428 pa_sink_input_assert_ref(i);
1429
1430 connection_unlink(CONNECTION(i->userdata));
1431 }
1432
1433 /*** source_output callbacks ***/
1434
1435 /* Called from thread context */
1436 static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) {
1437 connection *c;
1438
1439 pa_source_output_assert_ref(o);
1440 c = CONNECTION(o->userdata);
1441 pa_assert(c);
1442 pa_assert(chunk);
1443
1444 pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_POST_DATA, NULL, 0, chunk, NULL);
1445 }
1446
1447 static void source_output_kill_cb(pa_source_output *o) {
1448 pa_source_output_assert_ref(o);
1449
1450 connection_unlink(CONNECTION(o->userdata));
1451 }
1452
1453 static pa_usec_t source_output_get_latency_cb(pa_source_output *o) {
1454 connection*c;
1455
1456 pa_source_output_assert_ref(o);
1457 c = CONNECTION(o->userdata);
1458 pa_assert(c);
1459
1460 return pa_bytes_to_usec(pa_memblockq_get_length(c->output_memblockq), &c->source_output->sample_spec);
1461 }
1462
1463 /*** entry points ***/
1464
1465 static void auth_timeout(pa_mainloop_api *m, pa_time_event *e, const struct timeval *t, void *userdata) {
1466 connection *c = CONNECTION(userdata);
1467
1468 pa_assert(m);
1469 connection_assert_ref(c);
1470 pa_assert(c->auth_timeout_event == e);
1471
1472 if (!c->authorized)
1473 connection_unlink(c);
1474 }
1475
1476 void pa_esound_protocol_connect(pa_esound_protocol *p, pa_iochannel *io, pa_esound_options *o) {
1477 connection *c;
1478 char pname[128];
1479 pa_client_new_data data;
1480 pa_client *client;
1481
1482 pa_assert(p);
1483 pa_assert(io);
1484 pa_assert(o);
1485
1486 if (pa_idxset_size(p->connections)+1 > MAX_CONNECTIONS) {
1487 pa_log("Warning! Too many connections (%u), dropping incoming connection.", MAX_CONNECTIONS);
1488 pa_iochannel_free(io);
1489 return;
1490 }
1491
1492 pa_client_new_data_init(&data);
1493 data.module = o->module;
1494 data.driver = __FILE__;
1495 pa_iochannel_socket_peer_to_string(io, pname, sizeof(pname));
1496 pa_proplist_setf(data.proplist, PA_PROP_APPLICATION_NAME, "EsounD client (%s)", pname);
1497 pa_proplist_sets(data.proplist, "esound-protocol.peer", pname);
1498 client = pa_client_new(p->core, &data);
1499 pa_client_new_data_done(&data);
1500
1501 if (!client)
1502 return;
1503
1504 c = pa_msgobject_new(connection);
1505 c->parent.parent.free = connection_free;
1506 c->parent.process_msg = connection_process_msg;
1507 c->protocol = p;
1508 c->io = io;
1509 pa_iochannel_set_callback(c->io, io_callback, c);
1510
1511 c->client = client;
1512 c->client->kill = client_kill_cb;
1513 c->client->userdata = c;
1514
1515 c->options = pa_esound_options_ref(o);
1516 c->authorized = FALSE;
1517 c->swap_byte_order = FALSE;
1518 c->dead = FALSE;
1519
1520 c->read_data_length = 0;
1521 c->read_data = pa_xmalloc(c->read_data_alloc = proto_map[ESD_PROTO_CONNECT].data_length);
1522
1523 c->write_data_length = c->write_data_index = c->write_data_alloc = 0;
1524 c->write_data = NULL;
1525
1526 c->state = ESD_NEEDS_REQDATA;
1527 c->request = ESD_PROTO_CONNECT;
1528
1529 c->sink_input = NULL;
1530 c->input_memblockq = NULL;
1531
1532 c->source_output = NULL;
1533 c->output_memblockq = NULL;
1534
1535 c->playback.current_memblock = NULL;
1536 c->playback.memblock_index = 0;
1537 c->playback.underrun = TRUE;
1538 pa_atomic_store(&c->playback.missing, 0);
1539
1540 pa_memchunk_reset(&c->scache.memchunk);
1541 c->scache.name = NULL;
1542
1543 c->original_name = NULL;
1544
1545 if (o->auth_anonymous) {
1546 pa_log_info("Client authenticated anonymously.");
1547 c->authorized = TRUE;
1548 }
1549
1550 if (!c->authorized &&
1551 o->auth_ip_acl &&
1552 pa_ip_acl_check(o->auth_ip_acl, pa_iochannel_get_recv_fd(io)) > 0) {
1553
1554 pa_log_info("Client authenticated by IP ACL.");
1555 c->authorized = TRUE;
1556 }
1557
1558 if (!c->authorized)
1559 c->auth_timeout_event = pa_core_rttime_new(p->core, pa_rtclock_now() + AUTH_TIMEOUT, auth_timeout, c);
1560 else
1561 c->auth_timeout_event = NULL;
1562
1563 c->defer_event = p->core->mainloop->defer_new(p->core->mainloop, defer_callback, c);
1564 p->core->mainloop->defer_enable(c->defer_event, 0);
1565
1566 pa_idxset_put(p->connections, c, &c->index);
1567 }
1568
1569 void pa_esound_protocol_disconnect(pa_esound_protocol *p, pa_module *m) {
1570 connection *c;
1571 void *state = NULL;
1572
1573 pa_assert(p);
1574 pa_assert(m);
1575
1576 while ((c = pa_idxset_iterate(p->connections, &state, NULL)))
1577 if (c->options->module == m)
1578 connection_unlink(c);
1579 }
1580
1581 static pa_esound_protocol* esound_protocol_new(pa_core *c) {
1582 pa_esound_protocol *p;
1583
1584 pa_assert(c);
1585
1586 p = pa_xnew(pa_esound_protocol, 1);
1587 PA_REFCNT_INIT(p);
1588 p->core = c;
1589 p->connections = pa_idxset_new(NULL, NULL);
1590 p->n_player = 0;
1591
1592 pa_assert_se(pa_shared_set(c, "esound-protocol", p) >= 0);
1593
1594 return p;
1595 }
1596
1597 pa_esound_protocol* pa_esound_protocol_get(pa_core *c) {
1598 pa_esound_protocol *p;
1599
1600 if ((p = pa_shared_get(c, "esound-protocol")))
1601 return pa_esound_protocol_ref(p);
1602
1603 return esound_protocol_new(c);
1604 }
1605
1606 pa_esound_protocol* pa_esound_protocol_ref(pa_esound_protocol *p) {
1607 pa_assert(p);
1608 pa_assert(PA_REFCNT_VALUE(p) >= 1);
1609
1610 PA_REFCNT_INC(p);
1611
1612 return p;
1613 }
1614
1615 void pa_esound_protocol_unref(pa_esound_protocol *p) {
1616 connection *c;
1617 pa_assert(p);
1618 pa_assert(PA_REFCNT_VALUE(p) >= 1);
1619
1620 if (PA_REFCNT_DEC(p) > 0)
1621 return;
1622
1623 while ((c = pa_idxset_first(p->connections, NULL)))
1624 connection_unlink(c);
1625
1626 pa_idxset_free(p->connections, NULL);
1627
1628 pa_assert_se(pa_shared_remove(p->core, "esound-protocol") >= 0);
1629
1630 pa_xfree(p);
1631 }
1632
1633 pa_esound_options* pa_esound_options_new(void) {
1634 pa_esound_options *o;
1635
1636 o = pa_xnew0(pa_esound_options, 1);
1637 PA_REFCNT_INIT(o);
1638
1639 return o;
1640 }
1641
1642 pa_esound_options* pa_esound_options_ref(pa_esound_options *o) {
1643 pa_assert(o);
1644 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1645
1646 PA_REFCNT_INC(o);
1647
1648 return o;
1649 }
1650
1651 void pa_esound_options_unref(pa_esound_options *o) {
1652 pa_assert(o);
1653 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1654
1655 if (PA_REFCNT_DEC(o) > 0)
1656 return;
1657
1658 if (o->auth_ip_acl)
1659 pa_ip_acl_free(o->auth_ip_acl);
1660
1661 if (o->auth_cookie)
1662 pa_auth_cookie_unref(o->auth_cookie);
1663
1664 pa_xfree(o->default_sink);
1665 pa_xfree(o->default_source);
1666
1667 pa_xfree(o);
1668 }
1669
1670 int pa_esound_options_parse(pa_esound_options *o, pa_core *c, pa_modargs *ma) {
1671 pa_bool_t enabled;
1672 const char *acl;
1673
1674 pa_assert(o);
1675 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1676 pa_assert(ma);
1677
1678 if (pa_modargs_get_value_boolean(ma, "auth-anonymous", &o->auth_anonymous) < 0) {
1679 pa_log("auth-anonymous= expects a boolean argument.");
1680 return -1;
1681 }
1682
1683 if ((acl = pa_modargs_get_value(ma, "auth-ip-acl", NULL))) {
1684 pa_ip_acl *ipa;
1685
1686 if (!(ipa = pa_ip_acl_new(acl))) {
1687 pa_log("Failed to parse IP ACL '%s'", acl);
1688 return -1;
1689 }
1690
1691 if (o->auth_ip_acl)
1692 pa_ip_acl_free(o->auth_ip_acl);
1693
1694 o->auth_ip_acl = ipa;
1695 }
1696
1697 enabled = TRUE;
1698 if (pa_modargs_get_value_boolean(ma, "auth-cookie-enabled", &enabled) < 0) {
1699 pa_log("auth-cookie-enabled= expects a boolean argument.");
1700 return -1;
1701 }
1702
1703 if (o->auth_cookie)
1704 pa_auth_cookie_unref(o->auth_cookie);
1705
1706 if (enabled) {
1707 const char *cn;
1708
1709 /* The new name for this is 'auth-cookie', for compat reasons
1710 * we check the old name too */
1711 if (!(cn = pa_modargs_get_value(ma, "auth-cookie", NULL)))
1712 if (!(cn = pa_modargs_get_value(ma, "cookie", NULL)))
1713 cn = DEFAULT_COOKIE_FILE;
1714
1715 if (!(o->auth_cookie = pa_auth_cookie_get(c, cn, TRUE, ESD_KEY_LEN)))
1716 return -1;
1717
1718 } else
1719 o->auth_cookie = NULL;
1720
1721 pa_xfree(o->default_sink);
1722 o->default_sink = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
1723
1724 pa_xfree(o->default_source);
1725 o->default_source = pa_xstrdup(pa_modargs_get_value(ma, "source", NULL));
1726
1727 return 0;
1728 }