~binli/ubuntu/vivid/pulseaudio/load-extcon-module

« back to all changes in this revision

Viewing changes to src/modules/module-esound-sink.c

  • Committer: Bin Li
  • Date: 2016-01-23 15:04:48 UTC
  • Revision ID: bin.li@canonical.com-20160123150448-5ockvw4p5xxntda4
init the 1:6.0-0ubuntu9.15 from silo 12

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***
 
2
  This file is part of PulseAudio.
 
3
 
 
4
  Copyright 2004-2006 Lennart Poettering
 
5
 
 
6
  PulseAudio is free software; you can redistribute it and/or modify
 
7
  it under the terms of the GNU Lesser General Public License as published
 
8
  by the Free Software Foundation; either version 2.1 of the License,
 
9
  or (at your option) any later version.
 
10
 
 
11
  PulseAudio is distributed in the hope that it will be useful, but
 
12
  WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
14
  General Public License for more details.
 
15
 
 
16
  You should have received a copy of the GNU Lesser General Public License
 
17
  along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
 
18
***/
 
19
 
 
20
#ifdef HAVE_CONFIG_H
 
21
#include <config.h>
 
22
#endif
 
23
 
 
24
#include <stdlib.h>
 
25
#include <stdio.h>
 
26
#include <errno.h>
 
27
#include <string.h>
 
28
#include <unistd.h>
 
29
 
 
30
#ifdef HAVE_NETINET_IN_H
 
31
#include <netinet/in.h>
 
32
#endif
 
33
 
 
34
#ifdef HAVE_NETINET_TCP_H
 
35
#include <netinet/tcp.h>
 
36
#endif
 
37
 
 
38
#ifdef HAVE_SYS_IOCTL_H
 
39
#include <sys/ioctl.h>
 
40
#endif
 
41
 
 
42
#ifdef HAVE_LINUX_SOCKIOS_H
 
43
#include <linux/sockios.h>
 
44
#endif
 
45
 
 
46
#include <pulse/rtclock.h>
 
47
#include <pulse/timeval.h>
 
48
#include <pulse/xmalloc.h>
 
49
 
 
50
#include <pulsecore/socket.h>
 
51
#include <pulsecore/core-error.h>
 
52
#include <pulsecore/iochannel.h>
 
53
#include <pulsecore/sink.h>
 
54
#include <pulsecore/module.h>
 
55
#include <pulsecore/core-util.h>
 
56
#include <pulsecore/modargs.h>
 
57
#include <pulsecore/log.h>
 
58
#include <pulsecore/socket-client.h>
 
59
#include <pulsecore/esound.h>
 
60
#include <pulsecore/authkey.h>
 
61
#include <pulsecore/thread-mq.h>
 
62
#include <pulsecore/thread.h>
 
63
#include <pulsecore/time-smoother.h>
 
64
#include <pulsecore/socket-util.h>
 
65
#include <pulsecore/rtpoll.h>
 
66
#include <pulsecore/poll.h>
 
67
 
 
68
#include "module-esound-sink-symdef.h"
 
69
 
 
70
PA_MODULE_AUTHOR("Lennart Poettering");
 
71
PA_MODULE_DESCRIPTION("ESOUND Sink");
 
72
PA_MODULE_VERSION(PACKAGE_VERSION);
 
73
PA_MODULE_LOAD_ONCE(false);
 
74
PA_MODULE_USAGE(
 
75
        "sink_name=<name for the sink> "
 
76
        "sink_properties=<properties for the sink> "
 
77
        "server=<address> cookie=<filename>  "
 
78
        "format=<sample format> "
 
79
        "rate=<sample rate> "
 
80
        "channels=<number of channels>");
 
81
 
 
82
#define DEFAULT_SINK_NAME "esound_out"
 
83
 
 
84
struct userdata {
 
85
    pa_core *core;
 
86
    pa_module *module;
 
87
    pa_sink *sink;
 
88
 
 
89
    pa_thread_mq thread_mq;
 
90
    pa_rtpoll *rtpoll;
 
91
    pa_rtpoll_item *rtpoll_item;
 
92
    pa_thread *thread;
 
93
 
 
94
    pa_memchunk memchunk;
 
95
 
 
96
    void *write_data;
 
97
    size_t write_length, write_index;
 
98
 
 
99
    void *read_data;
 
100
    size_t read_length, read_index;
 
101
 
 
102
    enum {
 
103
        STATE_AUTH,
 
104
        STATE_LATENCY,
 
105
        STATE_PREPARE,
 
106
        STATE_RUNNING,
 
107
        STATE_DEAD
 
108
    } state;
 
109
 
 
110
    pa_usec_t latency;
 
111
 
 
112
    esd_format_t format;
 
113
    int32_t rate;
 
114
 
 
115
    pa_smoother *smoother;
 
116
    int fd;
 
117
 
 
118
    int64_t offset;
 
119
 
 
120
    pa_iochannel *io;
 
121
    pa_socket_client *client;
 
122
 
 
123
    size_t block_size;
 
124
};
 
125
 
 
126
static const char* const valid_modargs[] = {
 
127
    "sink_name",
 
128
    "sink_properties",
 
129
    "server",
 
130
    "cookie",
 
131
    "format",
 
132
    "rate",
 
133
    "channels",
 
134
    NULL
 
135
};
 
136
 
 
137
enum {
 
138
    SINK_MESSAGE_PASS_SOCKET = PA_SINK_MESSAGE_MAX
 
139
};
 
140
 
 
141
static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
 
142
    struct userdata *u = PA_SINK(o)->userdata;
 
143
 
 
144
    switch (code) {
 
145
 
 
146
        case PA_SINK_MESSAGE_SET_STATE:
 
147
 
 
148
            switch ((pa_sink_state_t) PA_PTR_TO_UINT(data)) {
 
149
 
 
150
                case PA_SINK_SUSPENDED:
 
151
                    pa_assert(PA_SINK_IS_OPENED(u->sink->thread_info.state));
 
152
 
 
153
                    pa_smoother_pause(u->smoother, pa_rtclock_now());
 
154
                    break;
 
155
 
 
156
                case PA_SINK_IDLE:
 
157
                case PA_SINK_RUNNING:
 
158
 
 
159
                    if (u->sink->thread_info.state == PA_SINK_SUSPENDED)
 
160
                        pa_smoother_resume(u->smoother, pa_rtclock_now(), true);
 
161
 
 
162
                    break;
 
163
 
 
164
                case PA_SINK_UNLINKED:
 
165
                case PA_SINK_INIT:
 
166
                case PA_SINK_INVALID_STATE:
 
167
                    ;
 
168
            }
 
169
 
 
170
            break;
 
171
 
 
172
        case PA_SINK_MESSAGE_GET_LATENCY: {
 
173
            pa_usec_t w, r;
 
174
 
 
175
            r = pa_smoother_get(u->smoother, pa_rtclock_now());
 
176
            w = pa_bytes_to_usec((uint64_t) u->offset + u->memchunk.length, &u->sink->sample_spec);
 
177
 
 
178
            *((pa_usec_t*) data) = w > r ? w - r : 0;
 
179
            return 0;
 
180
        }
 
181
 
 
182
        case SINK_MESSAGE_PASS_SOCKET: {
 
183
            struct pollfd *pollfd;
 
184
 
 
185
            pa_assert(!u->rtpoll_item);
 
186
 
 
187
            u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1);
 
188
            pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
 
189
            pollfd->fd = u->fd;
 
190
            pollfd->events = pollfd->revents = 0;
 
191
 
 
192
            return 0;
 
193
        }
 
194
    }
 
195
 
 
196
    return pa_sink_process_msg(o, code, data, offset, chunk);
 
197
}
 
198
 
 
199
static void thread_func(void *userdata) {
 
200
    struct userdata *u = userdata;
 
201
    int write_type = 0;
 
202
 
 
203
    pa_assert(u);
 
204
 
 
205
    pa_log_debug("Thread starting up");
 
206
 
 
207
    pa_thread_mq_install(&u->thread_mq);
 
208
 
 
209
    pa_smoother_set_time_offset(u->smoother, pa_rtclock_now());
 
210
 
 
211
    for (;;) {
 
212
        int ret;
 
213
 
 
214
        if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
 
215
            pa_sink_process_rewind(u->sink, 0);
 
216
 
 
217
        if (u->rtpoll_item) {
 
218
            struct pollfd *pollfd;
 
219
            pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
 
220
 
 
221
            /* Render some data and write it to the fifo */
 
222
            if (PA_SINK_IS_OPENED(u->sink->thread_info.state) && pollfd->revents) {
 
223
                pa_usec_t usec;
 
224
                int64_t n;
 
225
 
 
226
                for (;;) {
 
227
                    ssize_t l;
 
228
                    void *p;
 
229
 
 
230
                    if (u->memchunk.length <= 0)
 
231
                        pa_sink_render(u->sink, u->block_size, &u->memchunk);
 
232
 
 
233
                    pa_assert(u->memchunk.length > 0);
 
234
 
 
235
                    p = pa_memblock_acquire(u->memchunk.memblock);
 
236
                    l = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, u->memchunk.length, &write_type);
 
237
                    pa_memblock_release(u->memchunk.memblock);
 
238
 
 
239
                    pa_assert(l != 0);
 
240
 
 
241
                    if (l < 0) {
 
242
 
 
243
                        if (errno == EINTR)
 
244
                            continue;
 
245
                        else if (errno == EAGAIN) {
 
246
 
 
247
                            /* OK, we filled all socket buffers up
 
248
                             * now. */
 
249
                            goto filled_up;
 
250
 
 
251
                        } else {
 
252
                            pa_log("Failed to write data to FIFO: %s", pa_cstrerror(errno));
 
253
                            goto fail;
 
254
                        }
 
255
 
 
256
                    } else {
 
257
                        u->offset += l;
 
258
 
 
259
                        u->memchunk.index += (size_t) l;
 
260
                        u->memchunk.length -= (size_t) l;
 
261
 
 
262
                        if (u->memchunk.length <= 0) {
 
263
                            pa_memblock_unref(u->memchunk.memblock);
 
264
                            pa_memchunk_reset(&u->memchunk);
 
265
                        }
 
266
 
 
267
                        pollfd->revents = 0;
 
268
 
 
269
                        if (u->memchunk.length > 0)
 
270
 
 
271
                            /* OK, we wrote less that we asked for,
 
272
                             * hence we can assume that the socket
 
273
                             * buffers are full now */
 
274
                            goto filled_up;
 
275
                    }
 
276
                }
 
277
 
 
278
            filled_up:
 
279
 
 
280
                /* At this spot we know that the socket buffers are
 
281
                 * fully filled up. This is the best time to estimate
 
282
                 * the playback position of the server */
 
283
 
 
284
                n = u->offset;
 
285
 
 
286
#ifdef SIOCOUTQ
 
287
                {
 
288
                    int l;
 
289
                    if (ioctl(u->fd, SIOCOUTQ, &l) >= 0 && l > 0)
 
290
                        n -= l;
 
291
                }
 
292
#endif
 
293
 
 
294
                usec = pa_bytes_to_usec((uint64_t) n, &u->sink->sample_spec);
 
295
 
 
296
                if (usec > u->latency)
 
297
                    usec -= u->latency;
 
298
                else
 
299
                    usec = 0;
 
300
 
 
301
                pa_smoother_put(u->smoother, pa_rtclock_now(), usec);
 
302
            }
 
303
 
 
304
            /* Hmm, nothing to do. Let's sleep */
 
305
            pollfd->events = (short) (PA_SINK_IS_OPENED(u->sink->thread_info.state) ? POLLOUT : 0);
 
306
        }
 
307
 
 
308
        if ((ret = pa_rtpoll_run(u->rtpoll)) < 0)
 
309
            goto fail;
 
310
 
 
311
        if (ret == 0)
 
312
            goto finish;
 
313
 
 
314
        if (u->rtpoll_item) {
 
315
            struct pollfd* pollfd;
 
316
 
 
317
            pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
 
318
 
 
319
            if (pollfd->revents & ~POLLOUT) {
 
320
                pa_log("FIFO shutdown.");
 
321
                goto fail;
 
322
            }
 
323
        }
 
324
    }
 
325
 
 
326
fail:
 
327
    /* If this was no regular exit from the loop we have to continue
 
328
     * processing messages until we received PA_MESSAGE_SHUTDOWN */
 
329
    pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL);
 
330
    pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
 
331
 
 
332
finish:
 
333
    pa_log_debug("Thread shutting down");
 
334
}
 
335
 
 
336
static int do_write(struct userdata *u) {
 
337
    ssize_t r;
 
338
    pa_assert(u);
 
339
 
 
340
    if (!pa_iochannel_is_writable(u->io))
 
341
        return 0;
 
342
 
 
343
    if (u->write_data) {
 
344
        pa_assert(u->write_index < u->write_length);
 
345
 
 
346
        if ((r = pa_iochannel_write(u->io, (uint8_t*) u->write_data + u->write_index, u->write_length - u->write_index)) < 0) {
 
347
            pa_log("write() failed: %s", pa_cstrerror(errno));
 
348
            return -1;
 
349
        }
 
350
 
 
351
        u->write_index += (size_t) r;
 
352
        pa_assert(u->write_index <= u->write_length);
 
353
 
 
354
        if (u->write_index == u->write_length) {
 
355
            pa_xfree(u->write_data);
 
356
            u->write_data = NULL;
 
357
            u->write_index = u->write_length = 0;
 
358
        }
 
359
    }
 
360
 
 
361
    if (!u->write_data && u->state == STATE_PREPARE) {
 
362
        int so_sndbuf = 0;
 
363
        socklen_t sl = sizeof(int);
 
364
 
 
365
        /* OK, we're done with sending all control data we need to, so
 
366
         * let's hand the socket over to the IO thread now */
 
367
 
 
368
        pa_assert(u->fd < 0);
 
369
        u->fd = pa_iochannel_get_send_fd(u->io);
 
370
 
 
371
        pa_iochannel_set_noclose(u->io, true);
 
372
        pa_iochannel_free(u->io);
 
373
        u->io = NULL;
 
374
 
 
375
        pa_make_tcp_socket_low_delay(u->fd);
 
376
 
 
377
        if (getsockopt(u->fd, SOL_SOCKET, SO_SNDBUF, (void *) &so_sndbuf, &sl) < 0)
 
378
            pa_log_warn("getsockopt(SO_SNDBUF) failed: %s", pa_cstrerror(errno));
 
379
        else {
 
380
            pa_log_debug("SO_SNDBUF is %zu.", (size_t) so_sndbuf);
 
381
            pa_sink_set_max_request(u->sink, PA_MAX((size_t) so_sndbuf, u->block_size));
 
382
        }
 
383
 
 
384
        pa_log_debug("Connection authenticated, handing fd to IO thread...");
 
385
 
 
386
        pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_PASS_SOCKET, NULL, 0, NULL, NULL);
 
387
        u->state = STATE_RUNNING;
 
388
    }
 
389
 
 
390
    return 0;
 
391
}
 
392
 
 
393
static int handle_response(struct userdata *u) {
 
394
    pa_assert(u);
 
395
 
 
396
    switch (u->state) {
 
397
 
 
398
        case STATE_AUTH:
 
399
            pa_assert(u->read_length == sizeof(int32_t));
 
400
 
 
401
            /* Process auth data */
 
402
            if (!*(int32_t*) u->read_data) {
 
403
                pa_log("Authentication failed: %s", pa_cstrerror(errno));
 
404
                return -1;
 
405
            }
 
406
 
 
407
            /* Request latency data */
 
408
            pa_assert(!u->write_data);
 
409
            *(int32_t*) (u->write_data = pa_xmalloc(u->write_length = sizeof(int32_t))) = ESD_PROTO_LATENCY;
 
410
 
 
411
            u->write_index = 0;
 
412
            u->state = STATE_LATENCY;
 
413
 
 
414
            /* Space for next response */
 
415
            pa_assert(u->read_length >= sizeof(int32_t));
 
416
            u->read_index = 0;
 
417
            u->read_length = sizeof(int32_t);
 
418
 
 
419
            break;
 
420
 
 
421
        case STATE_LATENCY: {
 
422
            int32_t *p;
 
423
            pa_assert(u->read_length == sizeof(int32_t));
 
424
 
 
425
            /* Process latency info */
 
426
            u->latency = (pa_usec_t) ((double) (*(int32_t*) u->read_data) * 1000000 / 44100);
 
427
            if (u->latency > 10000000) {
 
428
                pa_log_warn("Invalid latency information received from server");
 
429
                u->latency = 0;
 
430
            }
 
431
 
 
432
            /* Create stream */
 
433
            pa_assert(!u->write_data);
 
434
            p = u->write_data = pa_xmalloc0(u->write_length = sizeof(int32_t)*3+ESD_NAME_MAX);
 
435
            *(p++) = ESD_PROTO_STREAM_PLAY;
 
436
            *(p++) = u->format;
 
437
            *(p++) = u->rate;
 
438
            pa_strlcpy((char*) p, "PulseAudio Tunnel", ESD_NAME_MAX);
 
439
 
 
440
            u->write_index = 0;
 
441
            u->state = STATE_PREPARE;
 
442
 
 
443
            /* Don't read any further */
 
444
            pa_xfree(u->read_data);
 
445
            u->read_data = NULL;
 
446
            u->read_index = u->read_length = 0;
 
447
 
 
448
            break;
 
449
        }
 
450
 
 
451
        default:
 
452
            pa_assert_not_reached();
 
453
    }
 
454
 
 
455
    return 0;
 
456
}
 
457
 
 
458
static int do_read(struct userdata *u) {
 
459
    pa_assert(u);
 
460
 
 
461
    if (!pa_iochannel_is_readable(u->io))
 
462
        return 0;
 
463
 
 
464
    if (u->state == STATE_AUTH || u->state == STATE_LATENCY) {
 
465
        ssize_t r;
 
466
 
 
467
        if (!u->read_data)
 
468
            return 0;
 
469
 
 
470
        pa_assert(u->read_index < u->read_length);
 
471
 
 
472
        if ((r = pa_iochannel_read(u->io, (uint8_t*) u->read_data + u->read_index, u->read_length - u->read_index)) <= 0) {
 
473
            pa_log("read() failed: %s", r < 0 ? pa_cstrerror(errno) : "EOF");
 
474
            return -1;
 
475
        }
 
476
 
 
477
        u->read_index += (size_t) r;
 
478
        pa_assert(u->read_index <= u->read_length);
 
479
 
 
480
        if (u->read_index == u->read_length)
 
481
            return handle_response(u);
 
482
    }
 
483
 
 
484
    return 0;
 
485
}
 
486
 
 
487
static void io_callback(pa_iochannel *io, void*userdata) {
 
488
    struct userdata *u = userdata;
 
489
    pa_assert(u);
 
490
 
 
491
    if (do_read(u) < 0 || do_write(u) < 0) {
 
492
 
 
493
        if (u->io) {
 
494
            pa_iochannel_free(u->io);
 
495
            u->io = NULL;
 
496
        }
 
497
 
 
498
        pa_module_unload_request(u->module, true);
 
499
    }
 
500
}
 
501
 
 
502
static void on_connection(pa_socket_client *c, pa_iochannel*io, void *userdata) {
 
503
    struct userdata *u = userdata;
 
504
 
 
505
    pa_socket_client_unref(u->client);
 
506
    u->client = NULL;
 
507
 
 
508
    if (!io) {
 
509
        pa_log("Connection failed: %s", pa_cstrerror(errno));
 
510
        pa_module_unload_request(u->module, true);
 
511
        return;
 
512
    }
 
513
 
 
514
    pa_assert(!u->io);
 
515
    u->io = io;
 
516
    pa_iochannel_set_callback(u->io, io_callback, u);
 
517
 
 
518
    pa_log_debug("Connection established, authenticating ...");
 
519
}
 
520
 
 
521
int pa__init(pa_module*m) {
 
522
    struct userdata *u = NULL;
 
523
    pa_sample_spec ss;
 
524
    pa_modargs *ma = NULL;
 
525
    const char *espeaker;
 
526
    uint32_t key;
 
527
    pa_sink_new_data data;
 
528
    char *cookie_path;
 
529
    int r;
 
530
 
 
531
    pa_assert(m);
 
532
 
 
533
    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
 
534
        pa_log("failed to parse module arguments");
 
535
        goto fail;
 
536
    }
 
537
 
 
538
    ss = m->core->default_sample_spec;
 
539
    if (pa_modargs_get_sample_spec(ma, &ss) < 0) {
 
540
        pa_log("invalid sample format specification");
 
541
        goto fail;
 
542
    }
 
543
 
 
544
    if ((ss.format != PA_SAMPLE_U8 && ss.format != PA_SAMPLE_S16NE) ||
 
545
        (ss.channels > 2)) {
 
546
        pa_log("esound sample type support is limited to mono/stereo and U8 or S16NE sample data");
 
547
        goto fail;
 
548
    }
 
549
 
 
550
    u = pa_xnew0(struct userdata, 1);
 
551
    u->core = m->core;
 
552
    u->module = m;
 
553
    m->userdata = u;
 
554
    u->fd = -1;
 
555
    u->smoother = pa_smoother_new(
 
556
            PA_USEC_PER_SEC,
 
557
            PA_USEC_PER_SEC*2,
 
558
            true,
 
559
            true,
 
560
            10,
 
561
            0,
 
562
            false);
 
563
    pa_memchunk_reset(&u->memchunk);
 
564
    u->offset = 0;
 
565
 
 
566
    u->rtpoll = pa_rtpoll_new();
 
567
    pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
 
568
    u->rtpoll_item = NULL;
 
569
 
 
570
    u->format =
 
571
        (ss.format == PA_SAMPLE_U8 ? ESD_BITS8 : ESD_BITS16) |
 
572
        (ss.channels == 2 ? ESD_STEREO : ESD_MONO);
 
573
    u->rate = (int32_t) ss.rate;
 
574
    u->block_size = pa_usec_to_bytes(PA_USEC_PER_SEC/20, &ss);
 
575
 
 
576
    u->read_data = u->write_data = NULL;
 
577
    u->read_index = u->write_index = u->read_length = u->write_length = 0;
 
578
 
 
579
    u->state = STATE_AUTH;
 
580
    u->latency = 0;
 
581
 
 
582
    if (!(espeaker = getenv("ESPEAKER")))
 
583
        espeaker = ESD_UNIX_SOCKET_NAME;
 
584
 
 
585
    espeaker = pa_modargs_get_value(ma, "server", espeaker);
 
586
 
 
587
    pa_sink_new_data_init(&data);
 
588
    data.driver = __FILE__;
 
589
    data.module = m;
 
590
    pa_sink_new_data_set_name(&data, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME));
 
591
    pa_sink_new_data_set_sample_spec(&data, &ss);
 
592
    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, espeaker);
 
593
    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_API, "esd");
 
594
    pa_proplist_setf(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "EsounD Output on %s", espeaker);
 
595
 
 
596
    if (pa_modargs_get_proplist(ma, "sink_properties", data.proplist, PA_UPDATE_REPLACE) < 0) {
 
597
        pa_log("Invalid properties");
 
598
        pa_sink_new_data_done(&data);
 
599
        goto fail;
 
600
    }
 
601
 
 
602
    u->sink = pa_sink_new(m->core, &data, PA_SINK_LATENCY|PA_SINK_NETWORK);
 
603
    pa_sink_new_data_done(&data);
 
604
 
 
605
    if (!u->sink) {
 
606
        pa_log("Failed to create sink.");
 
607
        goto fail;
 
608
    }
 
609
 
 
610
    u->sink->parent.process_msg = sink_process_msg;
 
611
    u->sink->userdata = u;
 
612
 
 
613
    pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
 
614
    pa_sink_set_rtpoll(u->sink, u->rtpoll);
 
615
 
 
616
    if (!(u->client = pa_socket_client_new_string(u->core->mainloop, true, espeaker, ESD_DEFAULT_PORT))) {
 
617
        pa_log("Failed to connect to server.");
 
618
        goto fail;
 
619
    }
 
620
 
 
621
    pa_socket_client_set_callback(u->client, on_connection, u);
 
622
 
 
623
    cookie_path = pa_xstrdup(pa_modargs_get_value(ma, "cookie", NULL));
 
624
    if (!cookie_path) {
 
625
        if (pa_append_to_home_dir(".esd_auth", &cookie_path) < 0)
 
626
            goto fail;
 
627
    }
 
628
 
 
629
    /* Prepare the initial request */
 
630
    u->write_data = pa_xmalloc(u->write_length = ESD_KEY_LEN + sizeof(int32_t));
 
631
 
 
632
    r = pa_authkey_load(cookie_path, true, u->write_data, ESD_KEY_LEN);
 
633
    pa_xfree(cookie_path);
 
634
    if (r < 0) {
 
635
        pa_log("Failed to load cookie");
 
636
        goto fail;
 
637
    }
 
638
 
 
639
    key = ESD_ENDIAN_KEY;
 
640
    memcpy((uint8_t*) u->write_data + ESD_KEY_LEN, &key, sizeof(key));
 
641
 
 
642
    /* Reserve space for the response */
 
643
    u->read_data = pa_xmalloc(u->read_length = sizeof(int32_t));
 
644
 
 
645
    if (!(u->thread = pa_thread_new("esound-sink", thread_func, u))) {
 
646
        pa_log("Failed to create thread.");
 
647
        goto fail;
 
648
    }
 
649
 
 
650
    pa_sink_put(u->sink);
 
651
 
 
652
    pa_modargs_free(ma);
 
653
 
 
654
    return 0;
 
655
 
 
656
fail:
 
657
    if (ma)
 
658
        pa_modargs_free(ma);
 
659
 
 
660
    pa__done(m);
 
661
 
 
662
    return -1;
 
663
}
 
664
 
 
665
int pa__get_n_used(pa_module *m) {
 
666
    struct userdata *u;
 
667
 
 
668
    pa_assert(m);
 
669
    pa_assert_se(u = m->userdata);
 
670
 
 
671
    return pa_sink_linked_by(u->sink);
 
672
}
 
673
 
 
674
void pa__done(pa_module*m) {
 
675
    struct userdata *u;
 
676
    pa_assert(m);
 
677
 
 
678
    if (!(u = m->userdata))
 
679
        return;
 
680
 
 
681
    if (u->sink)
 
682
        pa_sink_unlink(u->sink);
 
683
 
 
684
    if (u->thread) {
 
685
        pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
 
686
        pa_thread_free(u->thread);
 
687
    }
 
688
 
 
689
    pa_thread_mq_done(&u->thread_mq);
 
690
 
 
691
    if (u->sink)
 
692
        pa_sink_unref(u->sink);
 
693
 
 
694
    if (u->io)
 
695
        pa_iochannel_free(u->io);
 
696
 
 
697
    if (u->rtpoll_item)
 
698
        pa_rtpoll_item_free(u->rtpoll_item);
 
699
 
 
700
    if (u->rtpoll)
 
701
        pa_rtpoll_free(u->rtpoll);
 
702
 
 
703
    if (u->memchunk.memblock)
 
704
        pa_memblock_unref(u->memchunk.memblock);
 
705
 
 
706
    if (u->client)
 
707
        pa_socket_client_unref(u->client);
 
708
 
 
709
    pa_xfree(u->read_data);
 
710
    pa_xfree(u->write_data);
 
711
 
 
712
    if (u->smoother)
 
713
        pa_smoother_free(u->smoother);
 
714
 
 
715
    if (u->fd >= 0)
 
716
        pa_close(u->fd);
 
717
 
 
718
    pa_xfree(u);
 
719
}