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