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
79typedef 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
118PA_DEFINE_PRIVATE_CLASS(connection, pa_msgobject);
119#define CONNECTION(o) (connection_cast(o))
120
121struct pa_esound_protocol {
122    PA_REFCNT_DECLARE;
123
124    pa_core *core;
125    pa_idxset *connections;
126    unsigned n_player;
127};
128
129enum {
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
134enum {
135    CONNECTION_MESSAGE_REQUEST_DATA,
136    CONNECTION_MESSAGE_POST_DATA,
137    CONNECTION_MESSAGE_UNLINK_CONNECTION
138};
139
140typedef 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
146static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk);
147static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes);
148static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes);
149static void sink_input_kill_cb(pa_sink_input *i);
150static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk);
151static pa_usec_t source_output_get_latency_cb(pa_source_output *o);
152
153static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk);
154static void source_output_kill_cb(pa_source_output *o);
155
156static int esd_proto_connect(connection *c, esd_proto_t request, const void *data, size_t length);
157static int esd_proto_stream_play(connection *c, esd_proto_t request, const void *data, size_t length);
158static int esd_proto_stream_record(connection *c, esd_proto_t request, const void *data, size_t length);
159static int esd_proto_get_latency(connection *c, esd_proto_t request, const void *data, size_t length);
160static int esd_proto_server_info(connection *c, esd_proto_t request, const void *data, size_t length);
161static int esd_proto_all_info(connection *c, esd_proto_t request, const void *data, size_t length);
162static int esd_proto_stream_pan(connection *c, esd_proto_t request, const void *data, size_t length);
163static int esd_proto_sample_pan(connection *c, esd_proto_t request, const void *data, size_t length);
164static int esd_proto_sample_cache(connection *c, esd_proto_t request, const void *data, size_t length);
165static int esd_proto_sample_free_or_play(connection *c, esd_proto_t request, const void *data, size_t length);
166static int esd_proto_sample_get_id(connection *c, esd_proto_t request, const void *data, size_t length);
167static int esd_proto_standby_or_resume(connection *c, esd_proto_t request, const void *data, size_t length);
168static 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 */
171static 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
205static 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
256static 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
279static 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
291static 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
307static 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
317static 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
335static 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
380static 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
469static 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
563static 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
584static 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
610static 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
758static 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
794static 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
833static 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
885static 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
908static 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
942static 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
967static 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
992static 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
1000static 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
1188static 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
1237static 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
1265fail:
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
1278static 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
1287static 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
1296static 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 */
1325static 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 */
1369static 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 */
1403static 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 */
1418static 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
1428static 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 */
1437static 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
1448static 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
1454static 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
1466static 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
1477void 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
1570void 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
1582static 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
1598pa_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
1607pa_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
1616void 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
1634pa_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
1643pa_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
1652void 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
1671int 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