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