• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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