Add copyright notices to all relevant files. (based on svn log)
[profile/ivi/pulseaudio.git] / src / modules / module-tunnel.c
1 /* $Id$ */
2
3 /***
4   This file is part of PulseAudio.
5
6   Copyright 2004-2006 Lennart Poettering
7   Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
8
9   PulseAudio is free software; you can redistribute it and/or modify
10   it under the terms of the GNU Lesser General Public License as published
11   by the Free Software Foundation; either version 2 of the License,
12   or (at your option) any later version.
13
14   PulseAudio is distributed in the hope that it will be useful, but
15   WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   General Public License for more details.
18
19   You should have received a copy of the GNU Lesser General Public License
20   along with PulseAudio; if not, write to the Free Software
21   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22   USA.
23 ***/
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <unistd.h>
30 #include <assert.h>
31 #include <string.h>
32 #include <errno.h>
33 #include <sys/types.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36
37 #include <pulse/timeval.h>
38 #include <pulse/util.h>
39 #include <pulse/version.h>
40 #include <pulse/xmalloc.h>
41
42 #include <pulsecore/module.h>
43 #include <pulsecore/core-util.h>
44 #include <pulsecore/modargs.h>
45 #include <pulsecore/log.h>
46 #include <pulsecore/core-subscribe.h>
47 #include <pulsecore/sink-input.h>
48 #include <pulsecore/pdispatch.h>
49 #include <pulsecore/pstream.h>
50 #include <pulsecore/pstream-util.h>
51 #include <pulsecore/authkey.h>
52 #include <pulsecore/socket-client.h>
53 #include <pulsecore/socket-util.h>
54 #include <pulsecore/authkey-prop.h>
55
56 #ifdef TUNNEL_SINK
57 #include "module-tunnel-sink-symdef.h"
58 PA_MODULE_DESCRIPTION("Tunnel module for sinks")
59 PA_MODULE_USAGE(
60         "server=<address> "
61         "sink=<remote sink name> "
62         "cookie=<filename> "
63         "format=<sample format> "
64         "channels=<number of channels> "
65         "rate=<sample rate> "
66         "sink_name=<name for the local sink> "
67         "channel_map=<channel map>")
68 #else
69 #include "module-tunnel-source-symdef.h"
70 PA_MODULE_DESCRIPTION("Tunnel module for sources")
71 PA_MODULE_USAGE(
72         "server=<address> "
73         "source=<remote source name> "
74         "cookie=<filename> "
75         "format=<sample format> "
76         "channels=<number of channels> "
77         "rate=<sample rate> "
78         "source_name=<name for the local source> "
79         "channel_map=<channel map>")
80 #endif
81
82 PA_MODULE_AUTHOR("Lennart Poettering")
83 PA_MODULE_VERSION(PACKAGE_VERSION)
84
85 #define DEFAULT_TLENGTH (44100*2*2/10)  //(10240*8)
86 #define DEFAULT_MAXLENGTH ((DEFAULT_TLENGTH*3)/2)
87 #define DEFAULT_MINREQ 512
88 #define DEFAULT_PREBUF (DEFAULT_TLENGTH-DEFAULT_MINREQ)
89 #define DEFAULT_FRAGSIZE 1024
90
91 #define DEFAULT_TIMEOUT 5
92
93 #define LATENCY_INTERVAL 10
94
95 static const char* const valid_modargs[] = {
96     "server",
97     "cookie",
98     "format",
99     "channels",
100     "rate",
101 #ifdef TUNNEL_SINK
102     "sink_name",
103     "sink",
104 #else
105     "source_name",
106     "source",
107 #endif
108     "channel_map",
109     NULL,
110 };
111
112 static void command_stream_killed(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
113 static void command_subscribe_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
114
115 #ifdef TUNNEL_SINK
116 static void command_request(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
117 #endif
118
119 static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
120 #ifdef TUNNEL_SINK
121     [PA_COMMAND_REQUEST] = command_request,
122 #endif
123     [PA_COMMAND_PLAYBACK_STREAM_KILLED] = command_stream_killed,
124     [PA_COMMAND_RECORD_STREAM_KILLED] = command_stream_killed,
125     [PA_COMMAND_SUBSCRIBE_EVENT] = command_subscribe_event,
126 };
127
128 struct userdata {
129     pa_socket_client *client;
130     pa_pstream *pstream;
131     pa_pdispatch *pdispatch;
132
133     char *server_name;
134 #ifdef TUNNEL_SINK
135     char *sink_name;
136     pa_sink *sink;
137     uint32_t requested_bytes;
138 #else
139     char *source_name;
140     pa_source *source;
141 #endif
142
143     pa_module *module;
144     pa_core *core;
145
146     uint8_t auth_cookie[PA_NATIVE_COOKIE_LENGTH];
147
148     uint32_t version;
149     uint32_t ctag;
150     uint32_t device_index;
151     uint32_t channel;
152
153     pa_usec_t host_latency;
154
155     pa_time_event *time_event;
156
157     int auth_cookie_in_property;
158 };
159
160 static void close_stuff(struct userdata *u) {
161     assert(u);
162
163     if (u->pstream) {
164         pa_pstream_close(u->pstream);
165         pa_pstream_unref(u->pstream);
166         u->pstream = NULL;
167     }
168
169     if (u->pdispatch) {
170         pa_pdispatch_unref(u->pdispatch);
171         u->pdispatch = NULL;
172     }
173
174     if (u->client) {
175         pa_socket_client_unref(u->client);
176         u->client = NULL;
177     }
178
179 #ifdef TUNNEL_SINK
180     if (u->sink) {
181         pa_sink_disconnect(u->sink);
182         pa_sink_unref(u->sink);
183         u->sink = NULL;
184     }
185 #else
186     if (u->source) {
187         pa_source_disconnect(u->source);
188         pa_source_unref(u->source);
189         u->source = NULL;
190     }
191 #endif
192
193     if (u->time_event) {
194         u->core->mainloop->time_free(u->time_event);
195         u->time_event = NULL;
196     }
197 }
198
199 static void die(struct userdata *u) {
200     assert(u);
201     close_stuff(u);
202     pa_module_unload_request(u->module);
203 }
204
205 static void command_stream_killed(pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
206     struct userdata *u = userdata;
207     assert(pd && t && u && u->pdispatch == pd);
208
209     pa_log("stream killed");
210     die(u);
211 }
212
213 static void request_info(struct userdata *u);
214
215 static void command_subscribe_event(pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
216     struct userdata *u = userdata;
217     pa_subscription_event_type_t e;
218     uint32_t idx;
219
220     assert(pd && t && u);
221     assert(command == PA_COMMAND_SUBSCRIBE_EVENT);
222
223     if (pa_tagstruct_getu32(t, &e) < 0 ||
224         pa_tagstruct_getu32(t, &idx) < 0 ||
225         !pa_tagstruct_eof(t)) {
226         pa_log("invalid protocol reply");
227         die(u);
228         return;
229     }
230
231 #ifdef TUNNEL_SINK
232     if (e != (PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE))
233         return;
234 #else
235     if (e != (PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE))
236         return;
237 #endif
238
239     request_info(u);
240 }
241
242 #ifdef TUNNEL_SINK
243 static void send_prebuf_request(struct userdata *u) {
244     pa_tagstruct *t;
245
246     t = pa_tagstruct_new(NULL, 0);
247     pa_tagstruct_putu32(t, PA_COMMAND_PREBUF_PLAYBACK_STREAM);
248     pa_tagstruct_putu32(t, u->ctag++);
249     pa_tagstruct_putu32(t, u->channel);
250     pa_pstream_send_tagstruct(u->pstream, t);
251 }
252
253 static void send_bytes(struct userdata *u) {
254     assert(u);
255
256     if (!u->pstream)
257         return;
258
259     while (u->requested_bytes > 0) {
260         pa_memchunk chunk;
261         if (pa_sink_render(u->sink, u->requested_bytes, &chunk) < 0) {
262
263             if (u->requested_bytes >= DEFAULT_TLENGTH-DEFAULT_PREBUF)
264                 send_prebuf_request(u);
265
266             return;
267         }
268
269         pa_pstream_send_memblock(u->pstream, u->channel, 0, PA_SEEK_RELATIVE, &chunk);
270         pa_memblock_unref(chunk.memblock);
271
272 /*         pa_log("sent %lu", (unsigned long) chunk.length); */
273
274         if (chunk.length > u->requested_bytes)
275             u->requested_bytes = 0;
276         else
277             u->requested_bytes -= chunk.length;
278     }
279 }
280
281 static void command_request(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
282     struct userdata *u = userdata;
283     uint32_t bytes, channel;
284     assert(pd && command == PA_COMMAND_REQUEST && t && u && u->pdispatch == pd);
285
286     if (pa_tagstruct_getu32(t, &channel) < 0 ||
287         pa_tagstruct_getu32(t, &bytes) < 0 ||
288         !pa_tagstruct_eof(t)) {
289         pa_log("invalid protocol reply");
290         die(u);
291         return;
292     }
293
294     if (channel != u->channel) {
295         pa_log("recieved data for invalid channel");
296         die(u);
297         return;
298     }
299
300     u->requested_bytes += bytes;
301     send_bytes(u);
302 }
303
304 #endif
305
306 static void stream_get_latency_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
307     struct userdata *u = userdata;
308     pa_usec_t sink_usec, source_usec, transport_usec;
309     int playing;
310     int64_t write_index, read_index;
311     struct timeval local, remote, now;
312     assert(pd && u);
313
314     if (command != PA_COMMAND_REPLY) {
315         if (command == PA_COMMAND_ERROR)
316             pa_log("failed to get latency.");
317         else
318             pa_log("protocol error.");
319         die(u);
320         return;
321     }
322
323     if (pa_tagstruct_get_usec(t, &sink_usec) < 0 ||
324         pa_tagstruct_get_usec(t, &source_usec) < 0 ||
325         pa_tagstruct_get_boolean(t, &playing) < 0 ||
326         pa_tagstruct_get_timeval(t, &local) < 0 ||
327         pa_tagstruct_get_timeval(t, &remote) < 0 ||
328         pa_tagstruct_gets64(t, &write_index) < 0 ||
329         pa_tagstruct_gets64(t, &read_index) < 0 ||
330         !pa_tagstruct_eof(t)) {
331         pa_log("invalid reply. (latency)");
332         die(u);
333         return;
334     }
335
336     pa_gettimeofday(&now);
337
338     /* FIXME! This could use some serious love. */
339
340     if (pa_timeval_cmp(&local, &remote) < 0 && pa_timeval_cmp(&remote, &now)) {
341         /* local and remote seem to have synchronized clocks */
342 #ifdef TUNNEL_SINK
343         transport_usec = pa_timeval_diff(&remote, &local);
344 #else
345         transport_usec = pa_timeval_diff(&now, &remote);
346 #endif
347     } else
348         transport_usec = pa_timeval_diff(&now, &local)/2;
349
350 #ifdef TUNNEL_SINK
351     u->host_latency = sink_usec + transport_usec;
352 #else
353     u->host_latency = source_usec + transport_usec;
354     if (u->host_latency > sink_usec)
355         u->host_latency -= sink_usec;
356     else
357         u->host_latency = 0;
358 #endif
359
360 /*     pa_log("estimated host latency: %0.0f usec", (double) u->host_latency);  */
361 }
362
363 static void request_latency(struct userdata *u) {
364     pa_tagstruct *t;
365     struct timeval now;
366     uint32_t tag;
367     assert(u);
368
369     t = pa_tagstruct_new(NULL, 0);
370 #ifdef TUNNEL_SINK
371     pa_tagstruct_putu32(t, PA_COMMAND_GET_PLAYBACK_LATENCY);
372 #else
373     pa_tagstruct_putu32(t, PA_COMMAND_GET_RECORD_LATENCY);
374 #endif
375     pa_tagstruct_putu32(t, tag = u->ctag++);
376     pa_tagstruct_putu32(t, u->channel);
377
378     pa_gettimeofday(&now);
379     pa_tagstruct_put_timeval(t, &now);
380
381     pa_pstream_send_tagstruct(u->pstream, t);
382     pa_pdispatch_register_reply(u->pdispatch, tag, DEFAULT_TIMEOUT, stream_get_latency_callback, u, NULL);
383 }
384
385 static void stream_get_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
386     struct userdata *u = userdata;
387     uint32_t idx, owner_module, monitor_source;
388     pa_usec_t latency;
389     const char *name, *description, *monitor_source_name, *driver;
390     int mute;
391     uint32_t flags;
392     pa_sample_spec sample_spec;
393     pa_channel_map channel_map;
394     pa_cvolume volume;
395     assert(pd && u);
396
397     if (command != PA_COMMAND_REPLY) {
398         if (command == PA_COMMAND_ERROR)
399             pa_log("failed to get info.");
400         else
401             pa_log("protocol error.");
402         die(u);
403         return;
404     }
405
406     if (pa_tagstruct_getu32(t, &idx) < 0 ||
407         pa_tagstruct_gets(t, &name) < 0 ||
408         pa_tagstruct_gets(t, &description) < 0 ||
409         pa_tagstruct_get_sample_spec(t, &sample_spec) < 0 ||
410         pa_tagstruct_get_channel_map(t, &channel_map) < 0 ||
411         pa_tagstruct_getu32(t, &owner_module) < 0 ||
412         pa_tagstruct_get_cvolume(t, &volume) < 0 ||
413         pa_tagstruct_get_boolean(t, &mute) < 0 ||
414         pa_tagstruct_getu32(t, &monitor_source) < 0 ||
415         pa_tagstruct_gets(t, &monitor_source_name) < 0 ||
416         pa_tagstruct_get_usec(t, &latency) < 0 ||
417         pa_tagstruct_gets(t, &driver) < 0 ||
418         pa_tagstruct_getu32(t, &flags) < 0 ||
419         !pa_tagstruct_eof(t)) {
420         pa_log("invalid reply. (get_info)");
421         die(u);
422         return;
423     }
424
425 #ifdef TUNNEL_SINK
426     assert(u->sink);
427     if ((!!mute == !!u->sink->hw_muted) &&
428         pa_cvolume_equal(&volume, &u->sink->hw_volume))
429         return;
430 #else
431     assert(u->source);
432     if ((!!mute == !!u->source->hw_muted) &&
433         pa_cvolume_equal(&volume, &u->source->hw_volume))
434         return;
435 #endif
436
437 #ifdef TUNNEL_SINK
438     memcpy(&u->sink->hw_volume, &volume, sizeof(pa_cvolume));
439     u->sink->hw_muted = !!mute;
440
441     pa_subscription_post(u->sink->core,
442         PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE,
443         u->sink->index);
444 #else
445     memcpy(&u->source->hw_volume, &volume, sizeof(pa_cvolume));
446     u->source->hw_muted = !!mute;
447
448     pa_subscription_post(u->source->core,
449         PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE,
450         u->source->index);
451 #endif
452 }
453
454 static void request_info(struct userdata *u) {
455     pa_tagstruct *t;
456     uint32_t tag;
457     assert(u);
458
459     t = pa_tagstruct_new(NULL, 0);
460 #ifdef TUNNEL_SINK
461     pa_tagstruct_putu32(t, PA_COMMAND_GET_SINK_INFO);
462 #else
463     pa_tagstruct_putu32(t, PA_COMMAND_GET_SOURCE_INFO);
464 #endif
465     pa_tagstruct_putu32(t, tag = u->ctag++);
466
467     pa_tagstruct_putu32(t, PA_INVALID_INDEX);
468 #ifdef TUNNEL_SINK
469     pa_tagstruct_puts(t, u->sink_name);
470 #else
471     pa_tagstruct_puts(t, u->source_name);
472 #endif
473
474     pa_pstream_send_tagstruct(u->pstream, t);
475     pa_pdispatch_register_reply(u->pdispatch, tag, DEFAULT_TIMEOUT, stream_get_info_callback, u, NULL);
476 }
477
478 static void start_subscribe(struct userdata *u) {
479     pa_tagstruct *t;
480     uint32_t tag;
481     assert(u);
482
483     t = pa_tagstruct_new(NULL, 0);
484     pa_tagstruct_putu32(t, PA_COMMAND_SUBSCRIBE);
485     pa_tagstruct_putu32(t, tag = u->ctag++);
486
487 #ifdef TUNNEL_SINK
488     pa_tagstruct_putu32(t, PA_SUBSCRIPTION_MASK_SINK);
489 #else
490     pa_tagstruct_putu32(t, PA_SUBSCRIPTION_MASK_SOURCE);
491 #endif
492
493     pa_pstream_send_tagstruct(u->pstream, t);
494 }
495
496 static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) {
497     struct userdata *u = userdata;
498     struct timeval ntv;
499     assert(m && e && u);
500
501     request_latency(u);
502
503     pa_gettimeofday(&ntv);
504     ntv.tv_sec += LATENCY_INTERVAL;
505     m->time_restart(e, &ntv);
506 }
507
508 static void create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
509     struct userdata *u = userdata;
510     struct timeval ntv;
511     assert(pd && u && u->pdispatch == pd);
512
513     if (command != PA_COMMAND_REPLY) {
514         if (command == PA_COMMAND_ERROR)
515             pa_log("failed to create stream.");
516         else
517             pa_log("protocol error.");
518         die(u);
519         return;
520     }
521
522     if (pa_tagstruct_getu32(t, &u->channel) < 0 ||
523         pa_tagstruct_getu32(t, &u->device_index) < 0
524 #ifdef TUNNEL_SINK
525         || pa_tagstruct_getu32(t, &u->requested_bytes) < 0
526 #endif
527         )
528         goto parse_error;
529
530     if (u->version >= 9) {
531 #ifdef TUNNEL_SINK
532         uint32_t maxlength, tlength, prebuf, minreq;
533
534         if (pa_tagstruct_getu32(t, &maxlength) < 0 ||
535             pa_tagstruct_getu32(t, &tlength) < 0 ||
536             pa_tagstruct_getu32(t, &prebuf) < 0 ||
537             pa_tagstruct_getu32(t, &minreq) < 0)
538             goto parse_error;
539 #else
540         uint32_t maxlength, fragsize;
541
542         if (pa_tagstruct_getu32(t, &maxlength) < 0 ||
543             pa_tagstruct_getu32(t, &fragsize) < 0)
544             goto parse_error;
545 #endif
546     }
547
548     if (!pa_tagstruct_eof(t))
549         goto parse_error;
550
551     start_subscribe(u);
552     request_info(u);
553
554     assert(!u->time_event);
555     pa_gettimeofday(&ntv);
556     ntv.tv_sec += LATENCY_INTERVAL;
557     u->time_event = u->core->mainloop->time_new(u->core->mainloop, &ntv, timeout_callback, u);
558
559     request_latency(u);
560 #ifdef TUNNEL_SINK
561     send_bytes(u);
562 #endif
563
564     return;
565
566 parse_error:
567     pa_log("invalid reply. (create stream)");
568     die(u);
569 }
570
571 static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
572     struct userdata *u = userdata;
573     pa_tagstruct *reply;
574     char name[256], un[128], hn[128];
575 #ifdef TUNNEL_SINK
576     pa_cvolume volume;
577 #endif
578     assert(pd && u && u->pdispatch == pd);
579
580     if (command != PA_COMMAND_REPLY ||
581         pa_tagstruct_getu32(t, &u->version) < 0 ||
582         !pa_tagstruct_eof(t)) {
583         if (command == PA_COMMAND_ERROR)
584             pa_log("failed to authenticate");
585         else
586             pa_log("protocol error.");
587         die(u);
588         return;
589     }
590
591     /* Minimum supported protocol version */
592     if (u->version < 8) {
593         pa_log("incompatible protocol version");
594         die(u);
595         return;
596     }
597
598 #ifdef TUNNEL_SINK
599     snprintf(name, sizeof(name), "Tunnel from host %s, user %s, sink %s",
600              pa_get_host_name(hn, sizeof(hn)),
601              pa_get_user_name(un, sizeof(un)),
602              u->sink->name);
603 #else
604     snprintf(name, sizeof(name), "Tunnel from host %s, user %s, source %s",
605              pa_get_host_name(hn, sizeof(hn)),
606              pa_get_user_name(un, sizeof(un)),
607              u->source->name);
608 #endif
609
610     reply = pa_tagstruct_new(NULL, 0);
611     pa_tagstruct_putu32(reply, PA_COMMAND_SET_CLIENT_NAME);
612     pa_tagstruct_putu32(reply, tag = u->ctag++);
613     pa_tagstruct_puts(reply, name);
614     pa_pstream_send_tagstruct(u->pstream, reply);
615     /* We ignore the server's reply here */
616
617     reply = pa_tagstruct_new(NULL, 0);
618 #ifdef TUNNEL_SINK
619     pa_tagstruct_putu32(reply, PA_COMMAND_CREATE_PLAYBACK_STREAM);
620     pa_tagstruct_putu32(reply, tag = u->ctag++);
621     pa_tagstruct_puts(reply, name);
622     pa_tagstruct_put_sample_spec(reply, &u->sink->sample_spec);
623     pa_tagstruct_put_channel_map(reply, &u->sink->channel_map);
624     pa_tagstruct_putu32(reply, PA_INVALID_INDEX);
625     pa_tagstruct_puts(reply, u->sink_name);
626     pa_tagstruct_putu32(reply, DEFAULT_MAXLENGTH);
627     pa_tagstruct_put_boolean(reply, 0);
628     pa_tagstruct_putu32(reply, DEFAULT_TLENGTH);
629     pa_tagstruct_putu32(reply, DEFAULT_PREBUF);
630     pa_tagstruct_putu32(reply, DEFAULT_MINREQ);
631     pa_tagstruct_putu32(reply, 0);
632     pa_cvolume_reset(&volume, u->sink->sample_spec.channels);
633     pa_tagstruct_put_cvolume(reply, &volume);
634 #else
635     pa_tagstruct_putu32(reply, PA_COMMAND_CREATE_RECORD_STREAM);
636     pa_tagstruct_putu32(reply, tag = u->ctag++);
637     pa_tagstruct_puts(reply, name);
638     pa_tagstruct_put_sample_spec(reply, &u->source->sample_spec);
639     pa_tagstruct_put_channel_map(reply, &u->source->channel_map);
640     pa_tagstruct_putu32(reply, PA_INVALID_INDEX);
641     pa_tagstruct_puts(reply, u->source_name);
642     pa_tagstruct_putu32(reply, DEFAULT_MAXLENGTH);
643     pa_tagstruct_put_boolean(reply, 0);
644     pa_tagstruct_putu32(reply, DEFAULT_FRAGSIZE);
645 #endif
646
647     pa_pstream_send_tagstruct(u->pstream, reply);
648     pa_pdispatch_register_reply(u->pdispatch, tag, DEFAULT_TIMEOUT, create_stream_callback, u, NULL);
649 }
650
651 static void pstream_die_callback(pa_pstream *p, void *userdata) {
652     struct userdata *u = userdata;
653     assert(p && u);
654
655     pa_log("stream died.");
656     die(u);
657 }
658
659 static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata) {
660     struct userdata *u = userdata;
661     assert(p && packet && u);
662
663     if (pa_pdispatch_run(u->pdispatch, packet, creds, u) < 0) {
664         pa_log("invalid packet");
665         die(u);
666     }
667 }
668
669 #ifndef TUNNEL_SINK
670 static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, PA_GCC_UNUSED int64_t offset, PA_GCC_UNUSED pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata) {
671     struct userdata *u = userdata;
672     assert(p && chunk && u);
673
674     if (channel != u->channel) {
675         pa_log("recieved memory block on bad channel.");
676         die(u);
677         return;
678     }
679
680     pa_source_post(u->source, chunk);
681 }
682 #endif
683
684 static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata) {
685     struct userdata *u = userdata;
686     pa_tagstruct *t;
687     uint32_t tag;
688     assert(sc && u && u->client == sc);
689
690     pa_socket_client_unref(u->client);
691     u->client = NULL;
692
693     if (!io) {
694         pa_log("connection failed.");
695         pa_module_unload_request(u->module);
696         return;
697     }
698
699     u->pstream = pa_pstream_new(u->core->mainloop, io, u->core->mempool);
700     u->pdispatch = pa_pdispatch_new(u->core->mainloop, command_table, PA_COMMAND_MAX);
701
702     pa_pstream_set_die_callback(u->pstream, pstream_die_callback, u);
703     pa_pstream_set_recieve_packet_callback(u->pstream, pstream_packet_callback, u);
704 #ifndef TUNNEL_SINK
705     pa_pstream_set_recieve_memblock_callback(u->pstream, pstream_memblock_callback, u);
706 #endif
707
708     t = pa_tagstruct_new(NULL, 0);
709     pa_tagstruct_putu32(t, PA_COMMAND_AUTH);
710     pa_tagstruct_putu32(t, tag = u->ctag++);
711     pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION);
712     pa_tagstruct_put_arbitrary(t, u->auth_cookie, sizeof(u->auth_cookie));
713     pa_pstream_send_tagstruct(u->pstream, t);
714     pa_pdispatch_register_reply(u->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, u, NULL);
715
716 }
717
718 #ifdef TUNNEL_SINK
719 static void sink_notify(pa_sink*sink) {
720     struct userdata *u;
721     assert(sink && sink->userdata);
722     u = sink->userdata;
723
724     send_bytes(u);
725 }
726
727 static pa_usec_t sink_get_latency(pa_sink *sink) {
728     struct userdata *u;
729     uint32_t l;
730     pa_usec_t usec = 0;
731     assert(sink && sink->userdata);
732     u = sink->userdata;
733
734     l = DEFAULT_TLENGTH;
735
736     if (l > u->requested_bytes) {
737         l -= u->requested_bytes;
738         usec += pa_bytes_to_usec(l, &u->sink->sample_spec);
739     }
740
741     usec += u->host_latency;
742
743     return usec;
744 }
745
746 static int sink_get_hw_volume(pa_sink *sink) {
747     struct userdata *u;
748     assert(sink && sink->userdata);
749     u = sink->userdata;
750
751     return 0;
752 }
753
754 static int sink_set_hw_volume(pa_sink *sink) {
755     struct userdata *u;
756     pa_tagstruct *t;
757     uint32_t tag;
758     assert(sink && sink->userdata);
759     u = sink->userdata;
760
761     t = pa_tagstruct_new(NULL, 0);
762     pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_VOLUME);
763     pa_tagstruct_putu32(t, tag = u->ctag++);
764
765     pa_tagstruct_putu32(t, PA_INVALID_INDEX);
766     pa_tagstruct_puts(t, u->sink_name);
767     pa_tagstruct_put_cvolume(t, &sink->hw_volume);
768     pa_pstream_send_tagstruct(u->pstream, t);
769
770     return 0;
771 }
772
773 static int sink_get_hw_mute(pa_sink *sink) {
774     struct userdata *u;
775     assert(sink && sink->userdata);
776     u = sink->userdata;
777
778     return 0;
779 }
780
781 static int sink_set_hw_mute(pa_sink *sink) {
782     struct userdata *u;
783     pa_tagstruct *t;
784     uint32_t tag;
785     assert(sink && sink->userdata);
786     u = sink->userdata;
787
788     t = pa_tagstruct_new(NULL, 0);
789     pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_MUTE);
790     pa_tagstruct_putu32(t, tag = u->ctag++);
791
792     pa_tagstruct_putu32(t, PA_INVALID_INDEX);
793     pa_tagstruct_puts(t, u->sink_name);
794     pa_tagstruct_put_boolean(t, !!sink->hw_muted);
795     pa_pstream_send_tagstruct(u->pstream, t);
796
797     return 0;
798 }
799
800 #else
801 static pa_usec_t source_get_latency(pa_source *source) {
802     struct userdata *u;
803     assert(source && source->userdata);
804     u = source->userdata;
805
806     return u->host_latency;
807 }
808
809 static int source_get_hw_volume(pa_source *source) {
810     struct userdata *u;
811     assert(source && source->userdata);
812     u = source->userdata;
813
814     return 0;
815 }
816
817 static int source_set_hw_volume(pa_source *source) {
818     struct userdata *u;
819     pa_tagstruct *t;
820     uint32_t tag;
821     assert(source && source->userdata);
822     u = source->userdata;
823
824     t = pa_tagstruct_new(NULL, 0);
825     pa_tagstruct_putu32(t, PA_COMMAND_SET_SOURCE_VOLUME);
826     pa_tagstruct_putu32(t, tag = u->ctag++);
827
828     pa_tagstruct_putu32(t, PA_INVALID_INDEX);
829     pa_tagstruct_puts(t, u->source_name);
830     pa_tagstruct_put_cvolume(t, &source->hw_volume);
831     pa_pstream_send_tagstruct(u->pstream, t);
832
833     return 0;
834 }
835
836 static int source_get_hw_mute(pa_source *source) {
837     struct userdata *u;
838     assert(source && source->userdata);
839     u = source->userdata;
840
841     return 0;
842 }
843
844 static int source_set_hw_mute(pa_source *source) {
845     struct userdata *u;
846     pa_tagstruct *t;
847     uint32_t tag;
848     assert(source && source->userdata);
849     u = source->userdata;
850
851     t = pa_tagstruct_new(NULL, 0);
852     pa_tagstruct_putu32(t, PA_COMMAND_SET_SOURCE_MUTE);
853     pa_tagstruct_putu32(t, tag = u->ctag++);
854
855     pa_tagstruct_putu32(t, PA_INVALID_INDEX);
856     pa_tagstruct_puts(t, u->source_name);
857     pa_tagstruct_put_boolean(t, !!source->hw_muted);
858     pa_pstream_send_tagstruct(u->pstream, t);
859
860     return 0;
861 }
862 #endif
863
864 static int load_key(struct userdata *u, const char*fn) {
865     assert(u);
866
867     u->auth_cookie_in_property = 0;
868
869     if (!fn && pa_authkey_prop_get(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME, u->auth_cookie, sizeof(u->auth_cookie)) >= 0) {
870         pa_log_debug("using already loaded auth cookie.");
871         pa_authkey_prop_ref(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME);
872         u->auth_cookie_in_property = 1;
873         return 0;
874     }
875
876     if (!fn)
877         fn = PA_NATIVE_COOKIE_FILE;
878
879     if (pa_authkey_load_auto(fn, u->auth_cookie, sizeof(u->auth_cookie)) < 0)
880         return -1;
881
882     pa_log_debug("loading cookie from disk.");
883
884     if (pa_authkey_prop_put(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME, u->auth_cookie, sizeof(u->auth_cookie)) >= 0)
885         u->auth_cookie_in_property = 1;
886
887     return 0;
888 }
889
890 int pa__init(pa_core *c, pa_module*m) {
891     pa_modargs *ma = NULL;
892     struct userdata *u = NULL;
893     pa_sample_spec ss;
894     pa_channel_map map;
895     char *t, *dn = NULL;
896
897     assert(c && m);
898
899     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
900         pa_log("failed to parse module arguments");
901         goto fail;
902     }
903
904     u = pa_xmalloc(sizeof(struct userdata));
905     m->userdata = u;
906     u->module = m;
907     u->core = c;
908     u->client = NULL;
909     u->pdispatch = NULL;
910     u->pstream = NULL;
911     u->server_name = NULL;
912 #ifdef TUNNEL_SINK
913     u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));;
914     u->sink = NULL;
915     u->requested_bytes = 0;
916 #else
917     u->source_name = pa_xstrdup(pa_modargs_get_value(ma, "source", NULL));;
918     u->source = NULL;
919 #endif
920     u->ctag = 1;
921     u->device_index = u->channel = PA_INVALID_INDEX;
922     u->host_latency = 0;
923     u->auth_cookie_in_property = 0;
924     u->time_event = NULL;
925
926     if (load_key(u, pa_modargs_get_value(ma, "cookie", NULL)) < 0)
927         goto fail;
928
929     if (!(u->server_name = pa_xstrdup(pa_modargs_get_value(ma, "server", NULL)))) {
930         pa_log("no server specified.");
931         goto fail;
932     }
933
934     ss = c->default_sample_spec;
935     if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
936         pa_log("invalid sample format specification");
937         goto fail;
938     }
939
940     if (!(u->client = pa_socket_client_new_string(c->mainloop, u->server_name, PA_NATIVE_DEFAULT_PORT))) {
941         pa_log("failed to connect to server '%s'", u->server_name);
942         goto fail;
943     }
944
945     if (!u->client)
946         goto fail;
947
948     pa_socket_client_set_callback(u->client, on_connection, u);
949
950 #ifdef TUNNEL_SINK
951
952     if (!(dn = pa_xstrdup(pa_modargs_get_value(ma, "sink_name", NULL))))
953         dn = pa_sprintf_malloc("tunnel.%s", u->server_name);
954
955     if (!(u->sink = pa_sink_new(c, __FILE__, dn, 0, &ss, &map))) {
956         pa_log("failed to create sink.");
957         goto fail;
958     }
959
960     u->sink->get_latency = sink_get_latency;
961     u->sink->get_hw_volume = sink_get_hw_volume;
962     u->sink->set_hw_volume = sink_set_hw_volume;
963     u->sink->get_hw_mute = sink_get_hw_mute;
964     u->sink->set_hw_mute = sink_set_hw_mute;
965     u->sink->notify = sink_notify;
966     u->sink->userdata = u;
967     pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Tunnel to %s%s%s", u->sink_name ? u->sink_name : "", u->sink_name ? " on " : "", u->server_name));
968     pa_xfree(t);
969
970     pa_sink_set_owner(u->sink, m);
971 #else
972
973     if (!(dn = pa_xstrdup(pa_modargs_get_value(ma, "source_name", NULL))))
974         dn = pa_sprintf_malloc("tunnel.%s", u->server_name);
975
976     if (!(u->source = pa_source_new(c, __FILE__, dn, 0, &ss, &map))) {
977         pa_log("failed to create source.");
978         goto fail;
979     }
980
981     u->source->get_latency = source_get_latency;
982     u->source->get_hw_volume = source_get_hw_volume;
983     u->source->set_hw_volume = source_set_hw_volume;
984     u->source->get_hw_mute = source_get_hw_mute;
985     u->source->set_hw_mute = source_set_hw_mute;
986     u->source->userdata = u;
987
988     pa_source_set_description(u->source, t = pa_sprintf_malloc("Tunnel to %s%s%s", u->source_name ? u->source_name : "", u->source_name ? " on " : "", u->server_name));
989     pa_xfree(t);
990
991     pa_source_set_owner(u->source, m);
992 #endif
993
994     pa_xfree(dn);
995
996     u->time_event = NULL;
997
998     pa_modargs_free(ma);
999
1000     return 0;
1001
1002 fail:
1003     pa__done(c, m);
1004
1005     if (ma)
1006         pa_modargs_free(ma);
1007
1008     pa_xfree(dn);
1009
1010     return  -1;
1011 }
1012
1013 void pa__done(pa_core *c, pa_module*m) {
1014     struct userdata* u;
1015     assert(c && m);
1016
1017     if (!(u = m->userdata))
1018         return;
1019
1020     close_stuff(u);
1021
1022     if (u->auth_cookie_in_property)
1023         pa_authkey_prop_unref(c, PA_NATIVE_COOKIE_PROPERTY_NAME);
1024
1025 #ifdef TUNNEL_SINK
1026     pa_xfree(u->sink_name);
1027 #else
1028     pa_xfree(u->source_name);
1029 #endif
1030     pa_xfree(u->server_name);
1031
1032     pa_xfree(u);
1033 }
1034
1035