]> code.delx.au - pulseaudio/blob - src/pulsecore/protocol-native.c
Rework memory management to allow shared memory data transfer. The central idea
[pulseaudio] / src / pulsecore / protocol-native.c
1 /* $Id$ */
2
3 /***
4 This file is part of PulseAudio.
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 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, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <string.h>
27 #include <stdio.h>
28 #include <assert.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31
32 #include <pulse/timeval.h>
33 #include <pulse/version.h>
34 #include <pulse/utf8.h>
35 #include <pulse/util.h>
36 #include <pulse/xmalloc.h>
37
38 #include <pulsecore/native-common.h>
39 #include <pulsecore/packet.h>
40 #include <pulsecore/client.h>
41 #include <pulsecore/source-output.h>
42 #include <pulsecore/sink-input.h>
43 #include <pulsecore/pstream.h>
44 #include <pulsecore/tagstruct.h>
45 #include <pulsecore/pdispatch.h>
46 #include <pulsecore/pstream-util.h>
47 #include <pulsecore/authkey.h>
48 #include <pulsecore/namereg.h>
49 #include <pulsecore/core-scache.h>
50 #include <pulsecore/core-subscribe.h>
51 #include <pulsecore/log.h>
52 #include <pulsecore/autoload.h>
53 #include <pulsecore/authkey-prop.h>
54 #include <pulsecore/strlist.h>
55 #include <pulsecore/props.h>
56 #include <pulsecore/sample-util.h>
57 #include <pulsecore/llist.h>
58 #include <pulsecore/creds.h>
59 #include <pulsecore/core-util.h>
60 #include <pulsecore/ipacl.h>
61
62 #include "protocol-native.h"
63
64 /* Kick a client if it doesn't authenticate within this time */
65 #define AUTH_TIMEOUT 60
66
67 /* Don't accept more connection than this */
68 #define MAX_CONNECTIONS 64
69
70 #define MAX_MEMBLOCKQ_LENGTH (4*1024*1024) /* 4MB */
71
72 struct connection;
73 struct pa_protocol_native;
74
75 struct record_stream {
76 struct connection *connection;
77 uint32_t index;
78 pa_source_output *source_output;
79 pa_memblockq *memblockq;
80 size_t fragment_size;
81 };
82
83 struct playback_stream {
84 int type;
85 struct connection *connection;
86 uint32_t index;
87 pa_sink_input *sink_input;
88 pa_memblockq *memblockq;
89 size_t requested_bytes;
90 int drain_request;
91 uint32_t drain_tag;
92 uint32_t syncid;
93 int underrun;
94
95 /* Sync group members */
96 PA_LLIST_FIELDS(struct playback_stream);
97 };
98
99 struct upload_stream {
100 int type;
101 struct connection *connection;
102 uint32_t index;
103 pa_memchunk memchunk;
104 size_t length;
105 char *name;
106 pa_sample_spec sample_spec;
107 pa_channel_map channel_map;
108 };
109
110 struct output_stream {
111 int type;
112 };
113
114 enum {
115 UPLOAD_STREAM,
116 PLAYBACK_STREAM
117 };
118
119 struct connection {
120 int authorized;
121 uint32_t version;
122 pa_protocol_native *protocol;
123 pa_client *client;
124 pa_pstream *pstream;
125 pa_pdispatch *pdispatch;
126 pa_idxset *record_streams, *output_streams;
127 uint32_t rrobin_index;
128 pa_subscription *subscription;
129 pa_time_event *auth_timeout_event;
130 };
131
132 struct pa_protocol_native {
133 pa_module *module;
134 int public;
135 pa_core *core;
136 pa_socket_server *server;
137 pa_idxset *connections;
138 uint8_t auth_cookie[PA_NATIVE_COOKIE_LENGTH];
139 int auth_cookie_in_property;
140 #ifdef HAVE_CREDS
141 char *auth_group;
142 #endif
143 pa_ip_acl *auth_ip_acl;
144 };
145
146 static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk);
147 static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_t length);
148 static void sink_input_kill_cb(pa_sink_input *i);
149 static pa_usec_t sink_input_get_latency_cb(pa_sink_input *i);
150
151 static void request_bytes(struct playback_stream*s);
152
153 static void source_output_kill_cb(pa_source_output *o);
154 static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk);
155 static pa_usec_t source_output_get_latency_cb(pa_source_output *o);
156
157 static void command_exit(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
158 static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
159 static void command_drain_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
160 static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
161 static void command_delete_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
162 static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
163 static void command_set_client_name(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
164 static void command_lookup(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
165 static void command_stat(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
166 static void command_get_playback_latency(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
167 static void command_get_record_latency(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
168 static void command_create_upload_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
169 static void command_finish_upload_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
170 static void command_play_sample(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
171 static void command_remove_sample(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
172 static void command_get_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
173 static void command_get_info_list(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
174 static void command_get_server_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
175 static void command_subscribe(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
176 static void command_set_volume(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
177 static void command_set_mute(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
178 static void command_cork_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
179 static void command_flush_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
180 static void command_trigger_or_prebuf_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
181 static void command_set_default_sink_or_source(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
182 static void command_set_stream_name(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
183 static void command_kill(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
184 static void command_load_module(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
185 static void command_unload_module(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
186 static void command_add_autoload(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
187 static void command_remove_autoload(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
188 static void command_get_autoload_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
189 static void command_get_autoload_info_list(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
190 static void command_cork_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
191 static void command_flush_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
192 static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
193
194 static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
195 [PA_COMMAND_ERROR] = NULL,
196 [PA_COMMAND_TIMEOUT] = NULL,
197 [PA_COMMAND_REPLY] = NULL,
198 [PA_COMMAND_CREATE_PLAYBACK_STREAM] = command_create_playback_stream,
199 [PA_COMMAND_DELETE_PLAYBACK_STREAM] = command_delete_stream,
200 [PA_COMMAND_DRAIN_PLAYBACK_STREAM] = command_drain_playback_stream,
201 [PA_COMMAND_CREATE_RECORD_STREAM] = command_create_record_stream,
202 [PA_COMMAND_DELETE_RECORD_STREAM] = command_delete_stream,
203 [PA_COMMAND_AUTH] = command_auth,
204 [PA_COMMAND_REQUEST] = NULL,
205 [PA_COMMAND_EXIT] = command_exit,
206 [PA_COMMAND_SET_CLIENT_NAME] = command_set_client_name,
207 [PA_COMMAND_LOOKUP_SINK] = command_lookup,
208 [PA_COMMAND_LOOKUP_SOURCE] = command_lookup,
209 [PA_COMMAND_STAT] = command_stat,
210 [PA_COMMAND_GET_PLAYBACK_LATENCY] = command_get_playback_latency,
211 [PA_COMMAND_GET_RECORD_LATENCY] = command_get_record_latency,
212 [PA_COMMAND_CREATE_UPLOAD_STREAM] = command_create_upload_stream,
213 [PA_COMMAND_DELETE_UPLOAD_STREAM] = command_delete_stream,
214 [PA_COMMAND_FINISH_UPLOAD_STREAM] = command_finish_upload_stream,
215 [PA_COMMAND_PLAY_SAMPLE] = command_play_sample,
216 [PA_COMMAND_REMOVE_SAMPLE] = command_remove_sample,
217 [PA_COMMAND_GET_SINK_INFO] = command_get_info,
218 [PA_COMMAND_GET_SOURCE_INFO] = command_get_info,
219 [PA_COMMAND_GET_CLIENT_INFO] = command_get_info,
220 [PA_COMMAND_GET_MODULE_INFO] = command_get_info,
221 [PA_COMMAND_GET_SINK_INPUT_INFO] = command_get_info,
222 [PA_COMMAND_GET_SOURCE_OUTPUT_INFO] = command_get_info,
223 [PA_COMMAND_GET_SAMPLE_INFO] = command_get_info,
224 [PA_COMMAND_GET_SINK_INFO_LIST] = command_get_info_list,
225 [PA_COMMAND_GET_SOURCE_INFO_LIST] = command_get_info_list,
226 [PA_COMMAND_GET_MODULE_INFO_LIST] = command_get_info_list,
227 [PA_COMMAND_GET_CLIENT_INFO_LIST] = command_get_info_list,
228 [PA_COMMAND_GET_SINK_INPUT_INFO_LIST] = command_get_info_list,
229 [PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST] = command_get_info_list,
230 [PA_COMMAND_GET_SAMPLE_INFO_LIST] = command_get_info_list,
231 [PA_COMMAND_GET_SERVER_INFO] = command_get_server_info,
232 [PA_COMMAND_SUBSCRIBE] = command_subscribe,
233
234 [PA_COMMAND_SET_SINK_VOLUME] = command_set_volume,
235 [PA_COMMAND_SET_SINK_INPUT_VOLUME] = command_set_volume,
236 [PA_COMMAND_SET_SOURCE_VOLUME] = command_set_volume,
237
238 [PA_COMMAND_SET_SINK_MUTE] = command_set_mute,
239 [PA_COMMAND_SET_SOURCE_MUTE] = command_set_mute,
240
241 [PA_COMMAND_CORK_PLAYBACK_STREAM] = command_cork_playback_stream,
242 [PA_COMMAND_FLUSH_PLAYBACK_STREAM] = command_flush_playback_stream,
243 [PA_COMMAND_TRIGGER_PLAYBACK_STREAM] = command_trigger_or_prebuf_playback_stream,
244 [PA_COMMAND_PREBUF_PLAYBACK_STREAM] = command_trigger_or_prebuf_playback_stream,
245
246 [PA_COMMAND_CORK_RECORD_STREAM] = command_cork_record_stream,
247 [PA_COMMAND_FLUSH_RECORD_STREAM] = command_flush_record_stream,
248
249 [PA_COMMAND_SET_DEFAULT_SINK] = command_set_default_sink_or_source,
250 [PA_COMMAND_SET_DEFAULT_SOURCE] = command_set_default_sink_or_source,
251 [PA_COMMAND_SET_PLAYBACK_STREAM_NAME] = command_set_stream_name,
252 [PA_COMMAND_SET_RECORD_STREAM_NAME] = command_set_stream_name,
253 [PA_COMMAND_KILL_CLIENT] = command_kill,
254 [PA_COMMAND_KILL_SINK_INPUT] = command_kill,
255 [PA_COMMAND_KILL_SOURCE_OUTPUT] = command_kill,
256 [PA_COMMAND_LOAD_MODULE] = command_load_module,
257 [PA_COMMAND_UNLOAD_MODULE] = command_unload_module,
258 [PA_COMMAND_GET_AUTOLOAD_INFO] = command_get_autoload_info,
259 [PA_COMMAND_GET_AUTOLOAD_INFO_LIST] = command_get_autoload_info_list,
260 [PA_COMMAND_ADD_AUTOLOAD] = command_add_autoload,
261 [PA_COMMAND_REMOVE_AUTOLOAD] = command_remove_autoload,
262
263 [PA_COMMAND_MOVE_SINK_INPUT] = command_move_stream,
264 [PA_COMMAND_MOVE_SOURCE_OUTPUT] = command_move_stream
265 };
266
267 /* structure management */
268
269 static struct upload_stream* upload_stream_new(
270 struct connection *c,
271 const pa_sample_spec *ss,
272 const pa_channel_map *map,
273 const char *name, size_t length) {
274
275 struct upload_stream *s;
276 assert(c && ss && name && length);
277
278 s = pa_xnew(struct upload_stream, 1);
279 s->type = UPLOAD_STREAM;
280 s->connection = c;
281 s->sample_spec = *ss;
282 s->channel_map = *map;
283 s->name = pa_xstrdup(name);
284
285 s->memchunk.memblock = NULL;
286 s->memchunk.index = 0;
287 s->memchunk.length = 0;
288
289 s->length = length;
290
291 pa_idxset_put(c->output_streams, s, &s->index);
292 return s;
293 }
294
295 static void upload_stream_free(struct upload_stream *o) {
296 assert(o && o->connection);
297
298 pa_idxset_remove_by_data(o->connection->output_streams, o, NULL);
299
300 pa_xfree(o->name);
301
302 if (o->memchunk.memblock)
303 pa_memblock_unref(o->memchunk.memblock);
304
305 pa_xfree(o);
306 }
307
308 static struct record_stream* record_stream_new(
309 struct connection *c,
310 pa_source *source,
311 const pa_sample_spec *ss,
312 const pa_channel_map *map,
313 const char *name,
314 size_t maxlength,
315 size_t fragment_size) {
316
317 struct record_stream *s;
318 pa_source_output *source_output;
319 size_t base;
320 pa_source_output_new_data data;
321
322 assert(c && source && ss && name && maxlength);
323
324 pa_source_output_new_data_init(&data);
325 data.source = source;
326 data.driver = __FILE__;
327 data.name = name;
328 pa_source_output_new_data_set_sample_spec(&data, ss);
329 pa_source_output_new_data_set_channel_map(&data, map);
330 data.module = c->protocol->module;
331 data.client = c->client;
332
333 if (!(source_output = pa_source_output_new(source->core, &data, 0)))
334 return NULL;
335
336 s = pa_xnew(struct record_stream, 1);
337 s->connection = c;
338 s->source_output = source_output;
339 s->source_output->push = source_output_push_cb;
340 s->source_output->kill = source_output_kill_cb;
341 s->source_output->get_latency = source_output_get_latency_cb;
342 s->source_output->userdata = s;
343
344 s->memblockq = pa_memblockq_new(
345 0,
346 maxlength,
347 0,
348 base = pa_frame_size(ss),
349 1,
350 0,
351 NULL);
352 assert(s->memblockq);
353
354 s->fragment_size = (fragment_size/base)*base;
355 if (!s->fragment_size)
356 s->fragment_size = base;
357
358 pa_idxset_put(c->record_streams, s, &s->index);
359 return s;
360 }
361
362 static void record_stream_free(struct record_stream* r) {
363 assert(r && r->connection);
364
365 pa_idxset_remove_by_data(r->connection->record_streams, r, NULL);
366 pa_source_output_disconnect(r->source_output);
367 pa_source_output_unref(r->source_output);
368 pa_memblockq_free(r->memblockq);
369 pa_xfree(r);
370 }
371
372 static struct playback_stream* playback_stream_new(
373 struct connection *c,
374 pa_sink *sink,
375 const pa_sample_spec *ss,
376 const pa_channel_map *map,
377 const char *name,
378 size_t maxlength,
379 size_t tlength,
380 size_t prebuf,
381 size_t minreq,
382 pa_cvolume *volume,
383 uint32_t syncid) {
384
385 struct playback_stream *s, *ssync;
386 pa_sink_input *sink_input;
387 pa_memblock *silence;
388 uint32_t idx;
389 int64_t start_index;
390 pa_sink_input_new_data data;
391
392 assert(c && sink && ss && name && maxlength);
393
394 /* Find syncid group */
395 for (ssync = pa_idxset_first(c->output_streams, &idx); ssync; ssync = pa_idxset_next(c->output_streams, &idx)) {
396
397 if (ssync->type != PLAYBACK_STREAM)
398 continue;
399
400 if (ssync->syncid == syncid)
401 break;
402 }
403
404 /* Synced streams must connect to the same sink */
405 if (ssync && ssync->sink_input->sink != sink)
406 return NULL;
407
408 pa_sink_input_new_data_init(&data);
409 data.sink = sink;
410 data.driver = __FILE__;
411 data.name = name;
412 pa_sink_input_new_data_set_sample_spec(&data, ss);
413 pa_sink_input_new_data_set_channel_map(&data, map);
414 pa_sink_input_new_data_set_volume(&data, volume);
415 data.module = c->protocol->module;
416 data.client = c->client;
417
418 if (!(sink_input = pa_sink_input_new(sink->core, &data, 0)))
419 return NULL;
420
421 s = pa_xnew(struct playback_stream, 1);
422 s->type = PLAYBACK_STREAM;
423 s->connection = c;
424 s->syncid = syncid;
425 s->sink_input = sink_input;
426 s->underrun = 1;
427
428 s->sink_input->peek = sink_input_peek_cb;
429 s->sink_input->drop = sink_input_drop_cb;
430 s->sink_input->kill = sink_input_kill_cb;
431 s->sink_input->get_latency = sink_input_get_latency_cb;
432 s->sink_input->userdata = s;
433
434 if (ssync) {
435 /* Sync id found, now find head of list */
436 PA_LLIST_FIND_HEAD(struct playback_stream, ssync, &ssync);
437
438 /* Prepend ourselves */
439 PA_LLIST_PREPEND(struct playback_stream, ssync, s);
440
441 /* Set our start index to the current read index of the other grozp member(s) */
442 assert(ssync->next);
443 start_index = pa_memblockq_get_read_index(ssync->next->memblockq);
444 } else {
445 /* This ia a new sync group */
446 PA_LLIST_INIT(struct playback_stream, s);
447 start_index = 0;
448 }
449
450 silence = pa_silence_memblock_new(c->protocol->core->mempool, ss, 0);
451
452 s->memblockq = pa_memblockq_new(
453 start_index,
454 maxlength,
455 tlength,
456 pa_frame_size(ss),
457 prebuf,
458 minreq,
459 silence);
460
461 pa_memblock_unref(silence);
462
463 s->requested_bytes = 0;
464 s->drain_request = 0;
465
466 pa_idxset_put(c->output_streams, s, &s->index);
467
468 return s;
469 }
470
471 static void playback_stream_free(struct playback_stream* p) {
472 struct playback_stream *head;
473 assert(p && p->connection);
474
475 if (p->drain_request)
476 pa_pstream_send_error(p->connection->pstream, p->drain_tag, PA_ERR_NOENTITY);
477
478 PA_LLIST_FIND_HEAD(struct playback_stream, p, &head);
479 PA_LLIST_REMOVE(struct playback_stream, head, p);
480
481 pa_idxset_remove_by_data(p->connection->output_streams, p, NULL);
482 pa_sink_input_disconnect(p->sink_input);
483 pa_sink_input_unref(p->sink_input);
484 pa_memblockq_free(p->memblockq);
485 pa_xfree(p);
486 }
487
488 static void connection_free(struct connection *c) {
489 struct record_stream *r;
490 struct output_stream *o;
491 assert(c && c->protocol);
492
493 pa_idxset_remove_by_data(c->protocol->connections, c, NULL);
494 while ((r = pa_idxset_first(c->record_streams, NULL)))
495 record_stream_free(r);
496 pa_idxset_free(c->record_streams, NULL, NULL);
497
498 while ((o = pa_idxset_first(c->output_streams, NULL)))
499 if (o->type == PLAYBACK_STREAM)
500 playback_stream_free((struct playback_stream*) o);
501 else
502 upload_stream_free((struct upload_stream*) o);
503 pa_idxset_free(c->output_streams, NULL, NULL);
504
505 pa_pdispatch_unref(c->pdispatch);
506 pa_pstream_close(c->pstream);
507 pa_pstream_unref(c->pstream);
508 pa_client_free(c->client);
509
510 if (c->subscription)
511 pa_subscription_free(c->subscription);
512
513 if (c->auth_timeout_event)
514 c->protocol->core->mainloop->time_free(c->auth_timeout_event);
515
516 pa_xfree(c);
517 }
518
519 static void request_bytes(struct playback_stream *s) {
520 pa_tagstruct *t;
521 size_t l;
522 assert(s);
523
524 if (!(l = pa_memblockq_missing(s->memblockq)))
525 return;
526
527 if (l <= s->requested_bytes)
528 return;
529
530 l -= s->requested_bytes;
531
532 if (l < pa_memblockq_get_minreq(s->memblockq))
533 return;
534
535 s->requested_bytes += l;
536
537 t = pa_tagstruct_new(NULL, 0);
538 assert(t);
539 pa_tagstruct_putu32(t, PA_COMMAND_REQUEST);
540 pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
541 pa_tagstruct_putu32(t, s->index);
542 pa_tagstruct_putu32(t, l);
543 pa_pstream_send_tagstruct(s->connection->pstream, t);
544
545 /* pa_log(__FILE__": Requesting %u bytes", l); */
546 }
547
548 static void send_memblock(struct connection *c) {
549 uint32_t start;
550 struct record_stream *r;
551
552 start = PA_IDXSET_INVALID;
553 for (;;) {
554 pa_memchunk chunk;
555
556 if (!(r = pa_idxset_rrobin(c->record_streams, &c->rrobin_index)))
557 return;
558
559 if (start == PA_IDXSET_INVALID)
560 start = c->rrobin_index;
561 else if (start == c->rrobin_index)
562 return;
563
564 if (pa_memblockq_peek(r->memblockq, &chunk) >= 0) {
565 pa_memchunk schunk = chunk;
566
567 if (schunk.length > r->fragment_size)
568 schunk.length = r->fragment_size;
569
570 pa_pstream_send_memblock(c->pstream, r->index, 0, PA_SEEK_RELATIVE, &schunk);
571 pa_memblockq_drop(r->memblockq, &chunk, schunk.length);
572 pa_memblock_unref(schunk.memblock);
573
574 return;
575 }
576 }
577 }
578
579 static void send_playback_stream_killed(struct playback_stream *p) {
580 pa_tagstruct *t;
581 assert(p);
582
583 t = pa_tagstruct_new(NULL, 0);
584 pa_tagstruct_putu32(t, PA_COMMAND_PLAYBACK_STREAM_KILLED);
585 pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
586 pa_tagstruct_putu32(t, p->index);
587 pa_pstream_send_tagstruct(p->connection->pstream, t);
588 }
589
590 static void send_record_stream_killed(struct record_stream *r) {
591 pa_tagstruct *t;
592 assert(r);
593
594 t = pa_tagstruct_new(NULL, 0);
595 pa_tagstruct_putu32(t, PA_COMMAND_RECORD_STREAM_KILLED);
596 pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
597 pa_tagstruct_putu32(t, r->index);
598 pa_pstream_send_tagstruct(r->connection->pstream, t);
599 }
600
601 /*** sinkinput callbacks ***/
602
603 static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) {
604 struct playback_stream *s;
605 assert(i && i->userdata && chunk);
606 s = i->userdata;
607
608 if (pa_memblockq_get_length(s->memblockq) <= 0 && !s->underrun) {
609 pa_tagstruct *t;
610
611 /* Report that we're empty */
612
613 t = pa_tagstruct_new(NULL, 0);
614 pa_tagstruct_putu32(t, PA_COMMAND_UNDERFLOW);
615 pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
616 pa_tagstruct_putu32(t, s->index);
617 pa_pstream_send_tagstruct(s->connection->pstream, t);
618
619 s->underrun = 1;
620 }
621
622 if (pa_memblockq_peek(s->memblockq, chunk) < 0) {
623 /* pa_log(__FILE__": peek: failure"); */
624 return -1;
625 }
626
627 /* pa_log(__FILE__": peek: %u", chunk->length); */
628
629 return 0;
630 }
631
632 static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_t length) {
633 struct playback_stream *s;
634 assert(i && i->userdata && length);
635 s = i->userdata;
636
637 pa_memblockq_drop(s->memblockq, chunk, length);
638
639 request_bytes(s);
640
641 if (s->drain_request && !pa_memblockq_is_readable(s->memblockq)) {
642 pa_pstream_send_simple_ack(s->connection->pstream, s->drain_tag);
643 s->drain_request = 0;
644 }
645
646 /* pa_log(__FILE__": after_drop: %u %u", pa_memblockq_get_length(s->memblockq), pa_memblockq_is_readable(s->memblockq)); */
647 }
648
649 static void sink_input_kill_cb(pa_sink_input *i) {
650 assert(i && i->userdata);
651 send_playback_stream_killed((struct playback_stream *) i->userdata);
652 playback_stream_free((struct playback_stream *) i->userdata);
653 }
654
655 static pa_usec_t sink_input_get_latency_cb(pa_sink_input *i) {
656 struct playback_stream *s;
657 assert(i && i->userdata);
658 s = i->userdata;
659
660 /*pa_log(__FILE__": get_latency: %u", pa_memblockq_get_length(s->memblockq));*/
661
662 return pa_bytes_to_usec(pa_memblockq_get_length(s->memblockq), &s->sink_input->sample_spec);
663 }
664
665 /*** source_output callbacks ***/
666
667 static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) {
668 struct record_stream *s;
669 assert(o && o->userdata && chunk);
670 s = o->userdata;
671
672 if (pa_memblockq_push_align(s->memblockq, chunk) < 0) {
673 pa_log_warn(__FILE__": Failed to push data into output queue.");
674 return;
675 }
676
677 if (!pa_pstream_is_pending(s->connection->pstream))
678 send_memblock(s->connection);
679 }
680
681 static void source_output_kill_cb(pa_source_output *o) {
682 assert(o && o->userdata);
683 send_record_stream_killed((struct record_stream *) o->userdata);
684 record_stream_free((struct record_stream *) o->userdata);
685 }
686
687 static pa_usec_t source_output_get_latency_cb(pa_source_output *o) {
688 struct record_stream *s;
689 assert(o && o->userdata);
690 s = o->userdata;
691
692 /*pa_log(__FILE__": get_latency: %u", pa_memblockq_get_length(s->memblockq));*/
693
694 return pa_bytes_to_usec(pa_memblockq_get_length(s->memblockq), &o->sample_spec);
695 }
696
697 /*** pdispatch callbacks ***/
698
699 static void protocol_error(struct connection *c) {
700 pa_log(__FILE__": protocol error, kicking client");
701 connection_free(c);
702 }
703
704 #define CHECK_VALIDITY(pstream, expression, tag, error) do { \
705 if (!(expression)) { \
706 pa_pstream_send_error((pstream), (tag), (error)); \
707 return; \
708 } \
709 } while(0);
710
711 static pa_tagstruct *reply_new(uint32_t tag) {
712 pa_tagstruct *reply;
713
714 reply = pa_tagstruct_new(NULL, 0);
715 pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
716 pa_tagstruct_putu32(reply, tag);
717 return reply;
718 }
719
720 static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
721 struct connection *c = userdata;
722 struct playback_stream *s;
723 uint32_t maxlength, tlength, prebuf, minreq, sink_index, syncid;
724 const char *name, *sink_name;
725 pa_sample_spec ss;
726 pa_channel_map map;
727 pa_tagstruct *reply;
728 pa_sink *sink;
729 pa_cvolume volume;
730 int corked;
731
732 assert(c && t && c->protocol && c->protocol->core);
733
734 if (pa_tagstruct_get(
735 t,
736 PA_TAG_STRING, &name,
737 PA_TAG_SAMPLE_SPEC, &ss,
738 PA_TAG_CHANNEL_MAP, &map,
739 PA_TAG_U32, &sink_index,
740 PA_TAG_STRING, &sink_name,
741 PA_TAG_U32, &maxlength,
742 PA_TAG_BOOLEAN, &corked,
743 PA_TAG_U32, &tlength,
744 PA_TAG_U32, &prebuf,
745 PA_TAG_U32, &minreq,
746 PA_TAG_U32, &syncid,
747 PA_TAG_CVOLUME, &volume,
748 PA_TAG_INVALID) < 0 ||
749 !pa_tagstruct_eof(t) ||
750 !name) {
751 protocol_error(c);
752 return;
753 }
754
755 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
756 CHECK_VALIDITY(c->pstream, name && pa_utf8_valid(name), tag, PA_ERR_INVALID);
757 CHECK_VALIDITY(c->pstream, sink_index != PA_INVALID_INDEX || !sink_name || (*sink_name && pa_utf8_valid(name)), tag, PA_ERR_INVALID);
758 CHECK_VALIDITY(c->pstream, pa_channel_map_valid(&map), tag, PA_ERR_INVALID);
759 CHECK_VALIDITY(c->pstream, pa_sample_spec_valid(&ss), tag, PA_ERR_INVALID);
760 CHECK_VALIDITY(c->pstream, pa_cvolume_valid(&volume), tag, PA_ERR_INVALID);
761 CHECK_VALIDITY(c->pstream, map.channels == ss.channels && volume.channels == ss.channels, tag, PA_ERR_INVALID);
762 CHECK_VALIDITY(c->pstream, maxlength > 0 && maxlength <= MAX_MEMBLOCKQ_LENGTH, tag, PA_ERR_INVALID);
763
764 if (sink_index != PA_INVALID_INDEX)
765 sink = pa_idxset_get_by_index(c->protocol->core->sinks, sink_index);
766 else
767 sink = pa_namereg_get(c->protocol->core, sink_name, PA_NAMEREG_SINK, 1);
768
769 CHECK_VALIDITY(c->pstream, sink, tag, PA_ERR_NOENTITY);
770
771 s = playback_stream_new(c, sink, &ss, &map, name, maxlength, tlength, prebuf, minreq, &volume, syncid);
772 CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_INVALID);
773
774 pa_sink_input_cork(s->sink_input, corked);
775
776 reply = reply_new(tag);
777 pa_tagstruct_putu32(reply, s->index);
778 assert(s->sink_input);
779 pa_tagstruct_putu32(reply, s->sink_input->index);
780 pa_tagstruct_putu32(reply, s->requested_bytes = pa_memblockq_missing(s->memblockq));
781
782 if (c->version >= 9) {
783 /* Since 0.9 we support sending the buffer metrics back to the client */
784
785 pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_maxlength(s->memblockq));
786 pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_tlength(s->memblockq));
787 pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_prebuf(s->memblockq));
788 pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_minreq(s->memblockq));
789 }
790
791 pa_pstream_send_tagstruct(c->pstream, reply);
792 request_bytes(s);
793 }
794
795 static void command_delete_stream(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
796 struct connection *c = userdata;
797 uint32_t channel;
798 assert(c && t);
799
800 if (pa_tagstruct_getu32(t, &channel) < 0 ||
801 !pa_tagstruct_eof(t)) {
802 protocol_error(c);
803 return;
804 }
805
806 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
807
808 if (command == PA_COMMAND_DELETE_PLAYBACK_STREAM) {
809 struct playback_stream *s;
810 if (!(s = pa_idxset_get_by_index(c->output_streams, channel)) || (s->type != PLAYBACK_STREAM)) {
811 pa_pstream_send_error(c->pstream, tag, PA_ERR_EXIST);
812 return;
813 }
814
815 playback_stream_free(s);
816 } else if (command == PA_COMMAND_DELETE_RECORD_STREAM) {
817 struct record_stream *s;
818 if (!(s = pa_idxset_get_by_index(c->record_streams, channel))) {
819 pa_pstream_send_error(c->pstream, tag, PA_ERR_EXIST);
820 return;
821 }
822
823 record_stream_free(s);
824 } else {
825 struct upload_stream *s;
826 assert(command == PA_COMMAND_DELETE_UPLOAD_STREAM);
827 if (!(s = pa_idxset_get_by_index(c->output_streams, channel)) || (s->type != UPLOAD_STREAM)) {
828 pa_pstream_send_error(c->pstream, tag, PA_ERR_EXIST);
829 return;
830 }
831
832 upload_stream_free(s);
833 }
834
835 pa_pstream_send_simple_ack(c->pstream, tag);
836 }
837
838 static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
839 struct connection *c = userdata;
840 struct record_stream *s;
841 uint32_t maxlength, fragment_size;
842 uint32_t source_index;
843 const char *name, *source_name;
844 pa_sample_spec ss;
845 pa_channel_map map;
846 pa_tagstruct *reply;
847 pa_source *source;
848 int corked;
849 assert(c && t && c->protocol && c->protocol->core);
850
851 if (pa_tagstruct_gets(t, &name) < 0 ||
852 pa_tagstruct_get_sample_spec(t, &ss) < 0 ||
853 pa_tagstruct_get_channel_map(t, &map) < 0 ||
854 pa_tagstruct_getu32(t, &source_index) < 0 ||
855 pa_tagstruct_gets(t, &source_name) < 0 ||
856 pa_tagstruct_getu32(t, &maxlength) < 0 ||
857 pa_tagstruct_get_boolean(t, &corked) < 0 ||
858 pa_tagstruct_getu32(t, &fragment_size) < 0 ||
859 !pa_tagstruct_eof(t)) {
860 protocol_error(c);
861 return;
862 }
863
864 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
865 CHECK_VALIDITY(c->pstream, name && pa_utf8_valid(name), tag, PA_ERR_INVALID);
866 CHECK_VALIDITY(c->pstream, pa_sample_spec_valid(&ss), tag, PA_ERR_INVALID);
867 CHECK_VALIDITY(c->pstream, pa_channel_map_valid(&map), tag, PA_ERR_INVALID);
868 CHECK_VALIDITY(c->pstream, source_index != PA_INVALID_INDEX || !source_name || (*source_name && pa_utf8_valid(source_name)), tag, PA_ERR_INVALID);
869 CHECK_VALIDITY(c->pstream, map.channels == ss.channels, tag, PA_ERR_INVALID);
870 CHECK_VALIDITY(c->pstream, maxlength <= MAX_MEMBLOCKQ_LENGTH, tag, PA_ERR_INVALID);
871
872 if (source_index != PA_INVALID_INDEX)
873 source = pa_idxset_get_by_index(c->protocol->core->sources, source_index);
874 else
875 source = pa_namereg_get(c->protocol->core, source_name, PA_NAMEREG_SOURCE, 1);
876
877 CHECK_VALIDITY(c->pstream, source, tag, PA_ERR_NOENTITY);
878
879 s = record_stream_new(c, source, &ss, &map, name, maxlength, fragment_size);
880 CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_INVALID);
881
882 pa_source_output_cork(s->source_output, corked);
883
884 reply = reply_new(tag);
885 pa_tagstruct_putu32(reply, s->index);
886 assert(s->source_output);
887 pa_tagstruct_putu32(reply, s->source_output->index);
888
889 if (c->version >= 9) {
890 /* Since 0.9 we support sending the buffer metrics back to the client */
891
892 pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_maxlength(s->memblockq));
893 pa_tagstruct_putu32(reply, (uint32_t) s->fragment_size);
894 }
895
896 pa_pstream_send_tagstruct(c->pstream, reply);
897 }
898
899 static void command_exit(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
900 struct connection *c = userdata;
901 assert(c && t);
902
903 if (!pa_tagstruct_eof(t)) {
904 protocol_error(c);
905 return;
906 }
907
908 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
909
910 assert(c->protocol && c->protocol->core && c->protocol->core->mainloop);
911 c->protocol->core->mainloop->quit(c->protocol->core->mainloop, 0);
912 pa_pstream_send_simple_ack(c->pstream, tag); /* nonsense */
913 }
914
915 static void command_auth(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
916 struct connection *c = userdata;
917 const void*cookie;
918 pa_tagstruct *reply;
919 assert(c && t);
920
921 if (pa_tagstruct_getu32(t, &c->version) < 0 ||
922 pa_tagstruct_get_arbitrary(t, &cookie, PA_NATIVE_COOKIE_LENGTH) < 0 ||
923 !pa_tagstruct_eof(t)) {
924 protocol_error(c);
925 return;
926 }
927
928 /* Minimum supported version */
929 if (c->version < 8) {
930 pa_pstream_send_error(c->pstream, tag, PA_ERR_VERSION);
931 return;
932 }
933
934 if (!c->authorized) {
935 int success = 0;
936
937 #ifdef HAVE_CREDS
938 const pa_creds *creds;
939
940 if ((creds = pa_pdispatch_creds(pd))) {
941 if (creds->uid == getuid())
942 success = 1;
943 else if (c->protocol->auth_group) {
944 int r;
945 gid_t gid;
946
947 if ((gid = pa_get_gid_of_group(c->protocol->auth_group)) == (gid_t) -1)
948 pa_log_warn(__FILE__": failed to get GID of group '%s'", c->protocol->auth_group);
949 else if (gid == creds->gid)
950 success = 1;
951
952 if (!success) {
953 if ((r = pa_uid_in_group(creds->uid, c->protocol->auth_group)) < 0)
954 pa_log_warn(__FILE__": failed to check group membership.");
955 else if (r > 0)
956 success = 1;
957 }
958 }
959
960 pa_log_info(__FILE__": Got credentials: uid=%lu gid=%lu success=%i",
961 (unsigned long) creds->uid,
962 (unsigned long) creds->gid,
963 success);
964 }
965 #endif
966
967 if (!success && memcmp(c->protocol->auth_cookie, cookie, PA_NATIVE_COOKIE_LENGTH) == 0)
968 success = 1;
969
970 if (!success) {
971 pa_log_warn(__FILE__": Denied access to client with invalid authorization data.");
972 pa_pstream_send_error(c->pstream, tag, PA_ERR_ACCESS);
973 return;
974 }
975
976 c->authorized = 1;
977 if (c->auth_timeout_event) {
978 c->protocol->core->mainloop->time_free(c->auth_timeout_event);
979 c->auth_timeout_event = NULL;
980 }
981 }
982
983 reply = reply_new(tag);
984 pa_tagstruct_putu32(reply, PA_PROTOCOL_VERSION);
985 pa_pstream_send_tagstruct(c->pstream, reply);
986 }
987
988 static void command_set_client_name(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
989 struct connection *c = userdata;
990 const char *name;
991 assert(c && t);
992
993 if (pa_tagstruct_gets(t, &name) < 0 ||
994 !pa_tagstruct_eof(t)) {
995 protocol_error(c);
996 return;
997 }
998
999 CHECK_VALIDITY(c->pstream, name && pa_utf8_valid(name), tag, PA_ERR_INVALID);
1000
1001 pa_client_set_name(c->client, name);
1002 pa_pstream_send_simple_ack(c->pstream, tag);
1003 }
1004
1005 static void command_lookup(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1006 struct connection *c = userdata;
1007 const char *name;
1008 uint32_t idx = PA_IDXSET_INVALID;
1009 assert(c && t);
1010
1011 if (pa_tagstruct_gets(t, &name) < 0 ||
1012 !pa_tagstruct_eof(t)) {
1013 protocol_error(c);
1014 return;
1015 }
1016
1017 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1018 CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID);
1019
1020 if (command == PA_COMMAND_LOOKUP_SINK) {
1021 pa_sink *sink;
1022 if ((sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK, 1)))
1023 idx = sink->index;
1024 } else {
1025 pa_source *source;
1026 assert(command == PA_COMMAND_LOOKUP_SOURCE);
1027 if ((source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1)))
1028 idx = source->index;
1029 }
1030
1031 if (idx == PA_IDXSET_INVALID)
1032 pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY);
1033 else {
1034 pa_tagstruct *reply;
1035 reply = reply_new(tag);
1036 pa_tagstruct_putu32(reply, idx);
1037 pa_pstream_send_tagstruct(c->pstream, reply);
1038 }
1039 }
1040
1041 static void command_drain_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1042 struct connection *c = userdata;
1043 uint32_t idx;
1044 struct playback_stream *s;
1045 assert(c && t);
1046
1047 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1048 !pa_tagstruct_eof(t)) {
1049 protocol_error(c);
1050 return;
1051 }
1052
1053 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1054 s = pa_idxset_get_by_index(c->output_streams, idx);
1055 CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
1056 CHECK_VALIDITY(c->pstream, s->type == PLAYBACK_STREAM, tag, PA_ERR_NOENTITY);
1057
1058 s->drain_request = 0;
1059
1060 pa_memblockq_prebuf_disable(s->memblockq);
1061
1062 if (!pa_memblockq_is_readable(s->memblockq)) {
1063 /* pa_log("immediate drain: %u", pa_memblockq_get_length(s->memblockq)); */
1064 pa_pstream_send_simple_ack(c->pstream, tag);
1065 } else {
1066 /* pa_log("slow drain triggered"); */
1067 s->drain_request = 1;
1068 s->drain_tag = tag;
1069
1070 pa_sink_notify(s->sink_input->sink);
1071 }
1072 }
1073
1074 static void command_stat(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1075 struct connection *c = userdata;
1076 pa_tagstruct *reply;
1077 const pa_mempool_stat *stat;
1078 assert(c && t);
1079
1080 if (!pa_tagstruct_eof(t)) {
1081 protocol_error(c);
1082 return;
1083 }
1084
1085 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1086
1087 stat = pa_mempool_get_stat(c->protocol->core->mempool);
1088
1089 reply = reply_new(tag);
1090 pa_tagstruct_putu32(reply, stat->n_allocated);
1091 pa_tagstruct_putu32(reply, stat->allocated_size);
1092 pa_tagstruct_putu32(reply, stat->n_accumulated);
1093 pa_tagstruct_putu32(reply, stat->accumulated_size);
1094 pa_tagstruct_putu32(reply, pa_scache_total_size(c->protocol->core));
1095 pa_pstream_send_tagstruct(c->pstream, reply);
1096 }
1097
1098 static void command_get_playback_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1099 struct connection *c = userdata;
1100 pa_tagstruct *reply;
1101 struct playback_stream *s;
1102 struct timeval tv, now;
1103 uint32_t idx;
1104 pa_usec_t latency;
1105 assert(c && t);
1106
1107 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1108 pa_tagstruct_get_timeval(t, &tv) < 0 ||
1109 !pa_tagstruct_eof(t)) {
1110 protocol_error(c);
1111 return;
1112 }
1113
1114 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1115 s = pa_idxset_get_by_index(c->output_streams, idx);
1116 CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
1117 CHECK_VALIDITY(c->pstream, s->type == PLAYBACK_STREAM, tag, PA_ERR_NOENTITY);
1118
1119 reply = reply_new(tag);
1120
1121 latency = pa_sink_get_latency(s->sink_input->sink);
1122 if (s->sink_input->resampled_chunk.memblock)
1123 latency += pa_bytes_to_usec(s->sink_input->resampled_chunk.length, &s->sink_input->sample_spec);
1124 pa_tagstruct_put_usec(reply, latency);
1125
1126 pa_tagstruct_put_usec(reply, 0);
1127 pa_tagstruct_put_boolean(reply, s->sink_input->state == PA_SINK_INPUT_RUNNING);
1128 pa_tagstruct_put_timeval(reply, &tv);
1129 pa_tagstruct_put_timeval(reply, pa_gettimeofday(&now));
1130 pa_tagstruct_puts64(reply, pa_memblockq_get_write_index(s->memblockq));
1131 pa_tagstruct_puts64(reply, pa_memblockq_get_read_index(s->memblockq));
1132 pa_pstream_send_tagstruct(c->pstream, reply);
1133 }
1134
1135 static void command_get_record_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1136 struct connection *c = userdata;
1137 pa_tagstruct *reply;
1138 struct record_stream *s;
1139 struct timeval tv, now;
1140 uint32_t idx;
1141 assert(c && t);
1142
1143 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1144 pa_tagstruct_get_timeval(t, &tv) < 0 ||
1145 !pa_tagstruct_eof(t)) {
1146 protocol_error(c);
1147 return;
1148 }
1149
1150 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1151 s = pa_idxset_get_by_index(c->record_streams, idx);
1152 CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
1153
1154 reply = reply_new(tag);
1155 pa_tagstruct_put_usec(reply, s->source_output->source->monitor_of ? pa_sink_get_latency(s->source_output->source->monitor_of) : 0);
1156 pa_tagstruct_put_usec(reply, pa_source_get_latency(s->source_output->source));
1157 pa_tagstruct_put_boolean(reply, 0);
1158 pa_tagstruct_put_timeval(reply, &tv);
1159 pa_tagstruct_put_timeval(reply, pa_gettimeofday(&now));
1160 pa_tagstruct_puts64(reply, pa_memblockq_get_write_index(s->memblockq));
1161 pa_tagstruct_puts64(reply, pa_memblockq_get_read_index(s->memblockq));
1162 pa_pstream_send_tagstruct(c->pstream, reply);
1163 }
1164
1165 static void command_create_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1166 struct connection *c = userdata;
1167 struct upload_stream *s;
1168 uint32_t length;
1169 const char *name;
1170 pa_sample_spec ss;
1171 pa_channel_map map;
1172 pa_tagstruct *reply;
1173 assert(c && t && c->protocol && c->protocol->core);
1174
1175 if (pa_tagstruct_gets(t, &name) < 0 ||
1176 pa_tagstruct_get_sample_spec(t, &ss) < 0 ||
1177 pa_tagstruct_get_channel_map(t, &map) < 0 ||
1178 pa_tagstruct_getu32(t, &length) < 0 ||
1179 !pa_tagstruct_eof(t)) {
1180 protocol_error(c);
1181 return;
1182 }
1183
1184 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1185 CHECK_VALIDITY(c->pstream, pa_sample_spec_valid(&ss), tag, PA_ERR_INVALID);
1186 CHECK_VALIDITY(c->pstream, pa_channel_map_valid(&map), tag, PA_ERR_INVALID);
1187 CHECK_VALIDITY(c->pstream, map.channels == ss.channels, tag, PA_ERR_INVALID);
1188 CHECK_VALIDITY(c->pstream, (length % pa_frame_size(&ss)) == 0 && length > 0, tag, PA_ERR_INVALID);
1189 CHECK_VALIDITY(c->pstream, length <= PA_SCACHE_ENTRY_SIZE_MAX, tag, PA_ERR_TOOLARGE);
1190 CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID);
1191
1192 s = upload_stream_new(c, &ss, &map, name, length);
1193 CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_INVALID);
1194
1195 reply = reply_new(tag);
1196 pa_tagstruct_putu32(reply, s->index);
1197 pa_tagstruct_putu32(reply, length);
1198 pa_pstream_send_tagstruct(c->pstream, reply);
1199 }
1200
1201 static void command_finish_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1202 struct connection *c = userdata;
1203 uint32_t channel;
1204 struct upload_stream *s;
1205 uint32_t idx;
1206 assert(c && t);
1207
1208 if (pa_tagstruct_getu32(t, &channel) < 0 ||
1209 !pa_tagstruct_eof(t)) {
1210 protocol_error(c);
1211 return;
1212 }
1213
1214 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1215
1216 s = pa_idxset_get_by_index(c->output_streams, channel);
1217 CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
1218 CHECK_VALIDITY(c->pstream, s->type == UPLOAD_STREAM, tag, PA_ERR_NOENTITY);
1219
1220 if (pa_scache_add_item(c->protocol->core, s->name, &s->sample_spec, &s->channel_map, &s->memchunk, &idx) < 0)
1221 pa_pstream_send_error(c->pstream, tag, PA_ERR_INTERNAL);
1222 else
1223 pa_pstream_send_simple_ack(c->pstream, tag);
1224
1225 upload_stream_free(s);
1226 }
1227
1228 static void command_play_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1229 struct connection *c = userdata;
1230 uint32_t sink_index;
1231 pa_volume_t volume;
1232 pa_sink *sink;
1233 const char *name, *sink_name;
1234 assert(c && t);
1235
1236 if (pa_tagstruct_getu32(t, &sink_index) < 0 ||
1237 pa_tagstruct_gets(t, &sink_name) < 0 ||
1238 pa_tagstruct_getu32(t, &volume) < 0 ||
1239 pa_tagstruct_gets(t, &name) < 0 ||
1240 !pa_tagstruct_eof(t)) {
1241 protocol_error(c);
1242 return;
1243 }
1244
1245 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1246 CHECK_VALIDITY(c->pstream, sink_index != PA_INVALID_INDEX || !sink_name || (*sink_name && pa_utf8_valid(name)), tag, PA_ERR_INVALID);
1247 CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID);
1248
1249 if (sink_index != PA_INVALID_INDEX)
1250 sink = pa_idxset_get_by_index(c->protocol->core->sinks, sink_index);
1251 else
1252 sink = pa_namereg_get(c->protocol->core, sink_name, PA_NAMEREG_SINK, 1);
1253
1254 CHECK_VALIDITY(c->pstream, sink, tag, PA_ERR_NOENTITY);
1255
1256 if (pa_scache_play_item(c->protocol->core, name, sink, volume) < 0) {
1257 pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY);
1258 return;
1259 }
1260
1261 pa_pstream_send_simple_ack(c->pstream, tag);
1262 }
1263
1264 static void command_remove_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1265 struct connection *c = userdata;
1266 const char *name;
1267 assert(c && t);
1268
1269 if (pa_tagstruct_gets(t, &name) < 0 ||
1270 !pa_tagstruct_eof(t)) {
1271 protocol_error(c);
1272 return;
1273 }
1274
1275 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1276 CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID);
1277
1278 if (pa_scache_remove_item(c->protocol->core, name) < 0) {
1279 pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY);
1280 return;
1281 }
1282
1283 pa_pstream_send_simple_ack(c->pstream, tag);
1284 }
1285
1286 static void sink_fill_tagstruct(pa_tagstruct *t, pa_sink *sink) {
1287 assert(t && sink);
1288 pa_tagstruct_put(
1289 t,
1290 PA_TAG_U32, sink->index,
1291 PA_TAG_STRING, sink->name,
1292 PA_TAG_STRING, sink->description,
1293 PA_TAG_SAMPLE_SPEC, &sink->sample_spec,
1294 PA_TAG_CHANNEL_MAP, &sink->channel_map,
1295 PA_TAG_U32, sink->owner ? sink->owner->index : PA_INVALID_INDEX,
1296 PA_TAG_CVOLUME, pa_sink_get_volume(sink, PA_MIXER_HARDWARE),
1297 PA_TAG_BOOLEAN, pa_sink_get_mute(sink, PA_MIXER_HARDWARE),
1298 PA_TAG_U32, sink->monitor_source ? sink->monitor_source->index : PA_INVALID_INDEX,
1299 PA_TAG_STRING, sink->monitor_source ? sink->monitor_source->name : NULL,
1300 PA_TAG_USEC, pa_sink_get_latency(sink),
1301 PA_TAG_STRING, sink->driver,
1302 PA_TAG_U32,
1303 (sink->get_hw_volume ? PA_SINK_HW_VOLUME_CTRL : 0) |
1304 (sink->get_latency ? PA_SINK_LATENCY : 0) |
1305 (sink->is_hardware ? PA_SINK_HARDWARE : 0),
1306 PA_TAG_INVALID);
1307 }
1308
1309 static void source_fill_tagstruct(pa_tagstruct *t, pa_source *source) {
1310 assert(t && source);
1311 pa_tagstruct_put(
1312 t,
1313 PA_TAG_U32, source->index,
1314 PA_TAG_STRING, source->name,
1315 PA_TAG_STRING, source->description,
1316 PA_TAG_SAMPLE_SPEC, &source->sample_spec,
1317 PA_TAG_CHANNEL_MAP, &source->channel_map,
1318 PA_TAG_U32, source->owner ? source->owner->index : PA_INVALID_INDEX,
1319 PA_TAG_CVOLUME, pa_source_get_volume(source, PA_MIXER_HARDWARE),
1320 PA_TAG_BOOLEAN, pa_source_get_mute(source, PA_MIXER_HARDWARE),
1321 PA_TAG_U32, source->monitor_of ? source->monitor_of->index : PA_INVALID_INDEX,
1322 PA_TAG_STRING, source->monitor_of ? source->monitor_of->name : NULL,
1323 PA_TAG_USEC, pa_source_get_latency(source),
1324 PA_TAG_STRING, source->driver,
1325 PA_TAG_U32,
1326 (source->get_hw_volume ? PA_SOURCE_HW_VOLUME_CTRL : 0) |
1327 (source->get_latency ? PA_SOURCE_LATENCY : 0) |
1328 (source->is_hardware ? PA_SOURCE_HARDWARE : 0),
1329 PA_TAG_INVALID);
1330 }
1331
1332 static void client_fill_tagstruct(pa_tagstruct *t, pa_client *client) {
1333 assert(t && client);
1334 pa_tagstruct_putu32(t, client->index);
1335 pa_tagstruct_puts(t, client->name);
1336 pa_tagstruct_putu32(t, client->owner ? client->owner->index : PA_INVALID_INDEX);
1337 pa_tagstruct_puts(t, client->driver);
1338 }
1339
1340 static void module_fill_tagstruct(pa_tagstruct *t, pa_module *module) {
1341 assert(t && module);
1342 pa_tagstruct_putu32(t, module->index);
1343 pa_tagstruct_puts(t, module->name);
1344 pa_tagstruct_puts(t, module->argument);
1345 pa_tagstruct_putu32(t, module->n_used);
1346 pa_tagstruct_put_boolean(t, module->auto_unload);
1347 }
1348
1349 static void sink_input_fill_tagstruct(pa_tagstruct *t, pa_sink_input *s) {
1350 assert(t && s);
1351 pa_tagstruct_putu32(t, s->index);
1352 pa_tagstruct_puts(t, s->name);
1353 pa_tagstruct_putu32(t, s->module ? s->module->index : PA_INVALID_INDEX);
1354 pa_tagstruct_putu32(t, s->client ? s->client->index : PA_INVALID_INDEX);
1355 pa_tagstruct_putu32(t, s->sink->index);
1356 pa_tagstruct_put_sample_spec(t, &s->sample_spec);
1357 pa_tagstruct_put_channel_map(t, &s->channel_map);
1358 pa_tagstruct_put_cvolume(t, &s->volume);
1359 pa_tagstruct_put_usec(t, pa_sink_input_get_latency(s));
1360 pa_tagstruct_put_usec(t, pa_sink_get_latency(s->sink));
1361 pa_tagstruct_puts(t, pa_resample_method_to_string(pa_sink_input_get_resample_method(s)));
1362 pa_tagstruct_puts(t, s->driver);
1363 }
1364
1365 static void source_output_fill_tagstruct(pa_tagstruct *t, pa_source_output *s) {
1366 assert(t && s);
1367 pa_tagstruct_putu32(t, s->index);
1368 pa_tagstruct_puts(t, s->name);
1369 pa_tagstruct_putu32(t, s->module ? s->module->index : PA_INVALID_INDEX);
1370 pa_tagstruct_putu32(t, s->client ? s->client->index : PA_INVALID_INDEX);
1371 pa_tagstruct_putu32(t, s->source->index);
1372 pa_tagstruct_put_sample_spec(t, &s->sample_spec);
1373 pa_tagstruct_put_channel_map(t, &s->channel_map);
1374 pa_tagstruct_put_usec(t, pa_source_output_get_latency(s));
1375 pa_tagstruct_put_usec(t, pa_source_get_latency(s->source));
1376 pa_tagstruct_puts(t, pa_resample_method_to_string(pa_source_output_get_resample_method(s)));
1377 pa_tagstruct_puts(t, s->driver);
1378 }
1379
1380 static void scache_fill_tagstruct(pa_tagstruct *t, pa_scache_entry *e) {
1381 assert(t && e);
1382 pa_tagstruct_putu32(t, e->index);
1383 pa_tagstruct_puts(t, e->name);
1384 pa_tagstruct_put_cvolume(t, &e->volume);
1385 pa_tagstruct_put_usec(t, pa_bytes_to_usec(e->memchunk.length, &e->sample_spec));
1386 pa_tagstruct_put_sample_spec(t, &e->sample_spec);
1387 pa_tagstruct_put_channel_map(t, &e->channel_map);
1388 pa_tagstruct_putu32(t, e->memchunk.length);
1389 pa_tagstruct_put_boolean(t, e->lazy);
1390 pa_tagstruct_puts(t, e->filename);
1391 }
1392
1393 static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1394 struct connection *c = userdata;
1395 uint32_t idx;
1396 pa_sink *sink = NULL;
1397 pa_source *source = NULL;
1398 pa_client *client = NULL;
1399 pa_module *module = NULL;
1400 pa_sink_input *si = NULL;
1401 pa_source_output *so = NULL;
1402 pa_scache_entry *sce = NULL;
1403 const char *name;
1404 pa_tagstruct *reply;
1405 assert(c && t);
1406
1407 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1408 (command != PA_COMMAND_GET_CLIENT_INFO &&
1409 command != PA_COMMAND_GET_MODULE_INFO &&
1410 command != PA_COMMAND_GET_SINK_INPUT_INFO &&
1411 command != PA_COMMAND_GET_SOURCE_OUTPUT_INFO &&
1412 pa_tagstruct_gets(t, &name) < 0) ||
1413 !pa_tagstruct_eof(t)) {
1414 protocol_error(c);
1415 return;
1416 }
1417
1418 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1419 CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID);
1420
1421 if (command == PA_COMMAND_GET_SINK_INFO) {
1422 if (idx != PA_INVALID_INDEX)
1423 sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx);
1424 else
1425 sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK, 1);
1426 } else if (command == PA_COMMAND_GET_SOURCE_INFO) {
1427 if (idx != PA_INVALID_INDEX)
1428 source = pa_idxset_get_by_index(c->protocol->core->sources, idx);
1429 else
1430 source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1);
1431 } else if (command == PA_COMMAND_GET_CLIENT_INFO)
1432 client = pa_idxset_get_by_index(c->protocol->core->clients, idx);
1433 else if (command == PA_COMMAND_GET_MODULE_INFO)
1434 module = pa_idxset_get_by_index(c->protocol->core->modules, idx);
1435 else if (command == PA_COMMAND_GET_SINK_INPUT_INFO)
1436 si = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx);
1437 else if (command == PA_COMMAND_GET_SOURCE_OUTPUT_INFO)
1438 so = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx);
1439 else {
1440 assert(command == PA_COMMAND_GET_SAMPLE_INFO);
1441 if (idx != PA_INVALID_INDEX)
1442 sce = pa_idxset_get_by_index(c->protocol->core->scache, idx);
1443 else
1444 sce = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SAMPLE, 0);
1445 }
1446
1447 if (!sink && !source && !client && !module && !si && !so && !sce) {
1448 pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY);
1449 return;
1450 }
1451
1452 reply = reply_new(tag);
1453 if (sink)
1454 sink_fill_tagstruct(reply, sink);
1455 else if (source)
1456 source_fill_tagstruct(reply, source);
1457 else if (client)
1458 client_fill_tagstruct(reply, client);
1459 else if (module)
1460 module_fill_tagstruct(reply, module);
1461 else if (si)
1462 sink_input_fill_tagstruct(reply, si);
1463 else if (so)
1464 source_output_fill_tagstruct(reply, so);
1465 else
1466 scache_fill_tagstruct(reply, sce);
1467 pa_pstream_send_tagstruct(c->pstream, reply);
1468 }
1469
1470 static void command_get_info_list(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1471 struct connection *c = userdata;
1472 pa_idxset *i;
1473 uint32_t idx;
1474 void *p;
1475 pa_tagstruct *reply;
1476 assert(c && t);
1477
1478 if (!pa_tagstruct_eof(t)) {
1479 protocol_error(c);
1480 return;
1481 }
1482
1483 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1484
1485 reply = reply_new(tag);
1486
1487 if (command == PA_COMMAND_GET_SINK_INFO_LIST)
1488 i = c->protocol->core->sinks;
1489 else if (command == PA_COMMAND_GET_SOURCE_INFO_LIST)
1490 i = c->protocol->core->sources;
1491 else if (command == PA_COMMAND_GET_CLIENT_INFO_LIST)
1492 i = c->protocol->core->clients;
1493 else if (command == PA_COMMAND_GET_MODULE_INFO_LIST)
1494 i = c->protocol->core->modules;
1495 else if (command == PA_COMMAND_GET_SINK_INPUT_INFO_LIST)
1496 i = c->protocol->core->sink_inputs;
1497 else if (command == PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST)
1498 i = c->protocol->core->source_outputs;
1499 else {
1500 assert(command == PA_COMMAND_GET_SAMPLE_INFO_LIST);
1501 i = c->protocol->core->scache;
1502 }
1503
1504 if (i) {
1505 for (p = pa_idxset_first(i, &idx); p; p = pa_idxset_next(i, &idx)) {
1506 if (command == PA_COMMAND_GET_SINK_INFO_LIST)
1507 sink_fill_tagstruct(reply, p);
1508 else if (command == PA_COMMAND_GET_SOURCE_INFO_LIST)
1509 source_fill_tagstruct(reply, p);
1510 else if (command == PA_COMMAND_GET_CLIENT_INFO_LIST)
1511 client_fill_tagstruct(reply, p);
1512 else if (command == PA_COMMAND_GET_MODULE_INFO_LIST)
1513 module_fill_tagstruct(reply, p);
1514 else if (command == PA_COMMAND_GET_SINK_INPUT_INFO_LIST)
1515 sink_input_fill_tagstruct(reply, p);
1516 else if (command == PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST)
1517 source_output_fill_tagstruct(reply, p);
1518 else {
1519 assert(command == PA_COMMAND_GET_SAMPLE_INFO_LIST);
1520 scache_fill_tagstruct(reply, p);
1521 }
1522 }
1523 }
1524
1525 pa_pstream_send_tagstruct(c->pstream, reply);
1526 }
1527
1528 static void command_get_server_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1529 struct connection *c = userdata;
1530 pa_tagstruct *reply;
1531 char txt[256];
1532 const char *n;
1533 assert(c && t);
1534
1535 if (!pa_tagstruct_eof(t)) {
1536 protocol_error(c);
1537 return;
1538 }
1539
1540 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1541
1542 reply = reply_new(tag);
1543 pa_tagstruct_puts(reply, PACKAGE_NAME);
1544 pa_tagstruct_puts(reply, PACKAGE_VERSION);
1545 pa_tagstruct_puts(reply, pa_get_user_name(txt, sizeof(txt)));
1546 pa_tagstruct_puts(reply, pa_get_fqdn(txt, sizeof(txt)));
1547 pa_tagstruct_put_sample_spec(reply, &c->protocol->core->default_sample_spec);
1548
1549 n = pa_namereg_get_default_sink_name(c->protocol->core);
1550 pa_tagstruct_puts(reply, n);
1551 n = pa_namereg_get_default_source_name(c->protocol->core);
1552 pa_tagstruct_puts(reply, n);
1553
1554 pa_tagstruct_putu32(reply, c->protocol->core->cookie);
1555
1556 pa_pstream_send_tagstruct(c->pstream, reply);
1557 }
1558
1559 static void subscription_cb(pa_core *core, pa_subscription_event_type_t e, uint32_t idx, void *userdata) {
1560 pa_tagstruct *t;
1561 struct connection *c = userdata;
1562 assert(c && core);
1563
1564 t = pa_tagstruct_new(NULL, 0);
1565 pa_tagstruct_putu32(t, PA_COMMAND_SUBSCRIBE_EVENT);
1566 pa_tagstruct_putu32(t, (uint32_t) -1);
1567 pa_tagstruct_putu32(t, e);
1568 pa_tagstruct_putu32(t, idx);
1569 pa_pstream_send_tagstruct(c->pstream, t);
1570 }
1571
1572 static void command_subscribe(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1573 struct connection *c = userdata;
1574 pa_subscription_mask_t m;
1575 assert(c && t);
1576
1577 if (pa_tagstruct_getu32(t, &m) < 0 ||
1578 !pa_tagstruct_eof(t)) {
1579 protocol_error(c);
1580 return;
1581 }
1582
1583 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1584 CHECK_VALIDITY(c->pstream, (m & ~PA_SUBSCRIPTION_MASK_ALL) == 0, tag, PA_ERR_INVALID);
1585
1586 if (c->subscription)
1587 pa_subscription_free(c->subscription);
1588
1589 if (m != 0) {
1590 c->subscription = pa_subscription_new(c->protocol->core, m, subscription_cb, c);
1591 assert(c->subscription);
1592 } else
1593 c->subscription = NULL;
1594
1595 pa_pstream_send_simple_ack(c->pstream, tag);
1596 }
1597
1598 static void command_set_volume(
1599 PA_GCC_UNUSED pa_pdispatch *pd,
1600 uint32_t command,
1601 uint32_t tag,
1602 pa_tagstruct *t,
1603 void *userdata) {
1604
1605 struct connection *c = userdata;
1606 uint32_t idx;
1607 pa_cvolume volume;
1608 pa_sink *sink = NULL;
1609 pa_source *source = NULL;
1610 pa_sink_input *si = NULL;
1611 const char *name = NULL;
1612 assert(c && t);
1613
1614 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1615 (command == PA_COMMAND_SET_SINK_VOLUME && pa_tagstruct_gets(t, &name) < 0) ||
1616 (command == PA_COMMAND_SET_SOURCE_VOLUME && pa_tagstruct_gets(t, &name) < 0) ||
1617 pa_tagstruct_get_cvolume(t, &volume) ||
1618 !pa_tagstruct_eof(t)) {
1619 protocol_error(c);
1620 return;
1621 }
1622
1623 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1624 CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID);
1625 CHECK_VALIDITY(c->pstream, pa_cvolume_valid(&volume), tag, PA_ERR_INVALID);
1626
1627 if (command == PA_COMMAND_SET_SINK_VOLUME) {
1628 if (idx != PA_INVALID_INDEX)
1629 sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx);
1630 else
1631 sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK, 1);
1632 } else if (command == PA_COMMAND_SET_SOURCE_VOLUME) {
1633 if (idx != (uint32_t) -1)
1634 source = pa_idxset_get_by_index(c->protocol->core->sources, idx);
1635 else
1636 source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1);
1637 } else {
1638 assert(command == PA_COMMAND_SET_SINK_INPUT_VOLUME);
1639 si = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx);
1640 }
1641
1642 CHECK_VALIDITY(c->pstream, si || sink || source, tag, PA_ERR_NOENTITY);
1643
1644 if (sink)
1645 pa_sink_set_volume(sink, PA_MIXER_HARDWARE, &volume);
1646 else if (source)
1647 pa_source_set_volume(source, PA_MIXER_HARDWARE, &volume);
1648 else if (si)
1649 pa_sink_input_set_volume(si, &volume);
1650
1651 pa_pstream_send_simple_ack(c->pstream, tag);
1652 }
1653
1654 static void command_set_mute(
1655 PA_GCC_UNUSED pa_pdispatch *pd,
1656 uint32_t command,
1657 uint32_t tag,
1658 pa_tagstruct *t,
1659 void *userdata) {
1660
1661 struct connection *c = userdata;
1662 uint32_t idx;
1663 int mute;
1664 pa_sink *sink = NULL;
1665 pa_source *source = NULL;
1666 const char *name = NULL;
1667 assert(c && t);
1668
1669 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1670 pa_tagstruct_gets(t, &name) < 0 ||
1671 pa_tagstruct_get_boolean(t, &mute) ||
1672 !pa_tagstruct_eof(t)) {
1673 protocol_error(c);
1674 return;
1675 }
1676
1677 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1678 CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID);
1679
1680 if (command == PA_COMMAND_SET_SINK_MUTE) {
1681 if (idx != PA_INVALID_INDEX)
1682 sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx);
1683 else
1684 sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK, 1);
1685 } else {
1686 assert(command == PA_COMMAND_SET_SOURCE_MUTE);
1687 if (idx != (uint32_t) -1)
1688 source = pa_idxset_get_by_index(c->protocol->core->sources, idx);
1689 else
1690 source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1);
1691 }
1692
1693 CHECK_VALIDITY(c->pstream, sink || source, tag, PA_ERR_NOENTITY);
1694
1695 if (sink)
1696 pa_sink_set_mute(sink, PA_MIXER_HARDWARE, mute);
1697 else if (source)
1698 pa_source_set_mute(source, PA_MIXER_HARDWARE, mute);
1699
1700 pa_pstream_send_simple_ack(c->pstream, tag);
1701 }
1702
1703 static void command_cork_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1704 struct connection *c = userdata;
1705 uint32_t idx;
1706 int b;
1707 struct playback_stream *s, *ssync;
1708 assert(c && t);
1709
1710 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1711 pa_tagstruct_get_boolean(t, &b) < 0 ||
1712 !pa_tagstruct_eof(t)) {
1713 protocol_error(c);
1714 return;
1715 }
1716
1717 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1718 CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX, tag, PA_ERR_INVALID);
1719 s = pa_idxset_get_by_index(c->output_streams, idx);
1720 CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
1721 CHECK_VALIDITY(c->pstream, s->type == PLAYBACK_STREAM, tag, PA_ERR_NOENTITY);
1722
1723 pa_sink_input_cork(s->sink_input, b);
1724 pa_memblockq_prebuf_force(s->memblockq);
1725
1726 /* Do the same for all other members in the sync group */
1727 for (ssync = s->prev; ssync; ssync = ssync->prev) {
1728 pa_sink_input_cork(ssync->sink_input, b);
1729 pa_memblockq_prebuf_force(ssync->memblockq);
1730 }
1731
1732 for (ssync = s->next; ssync; ssync = ssync->next) {
1733 pa_sink_input_cork(ssync->sink_input, b);
1734 pa_memblockq_prebuf_force(ssync->memblockq);
1735 }
1736
1737 pa_pstream_send_simple_ack(c->pstream, tag);
1738 }
1739
1740 static void command_flush_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1741 struct connection *c = userdata;
1742 uint32_t idx;
1743 struct playback_stream *s, *ssync;
1744 assert(c && t);
1745
1746 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1747 !pa_tagstruct_eof(t)) {
1748 protocol_error(c);
1749 return;
1750 }
1751
1752 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1753 CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX, tag, PA_ERR_INVALID);
1754 s = pa_idxset_get_by_index(c->output_streams, idx);
1755 CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
1756 CHECK_VALIDITY(c->pstream, s->type == PLAYBACK_STREAM, tag, PA_ERR_NOENTITY);
1757
1758 pa_memblockq_flush(s->memblockq);
1759 s->underrun = 0;
1760
1761 /* Do the same for all other members in the sync group */
1762 for (ssync = s->prev; ssync; ssync = ssync->prev) {
1763 pa_memblockq_flush(ssync->memblockq);
1764 ssync->underrun = 0;
1765 }
1766
1767 for (ssync = s->next; ssync; ssync = ssync->next) {
1768 pa_memblockq_flush(ssync->memblockq);
1769 ssync->underrun = 0;
1770 }
1771
1772 pa_pstream_send_simple_ack(c->pstream, tag);
1773 pa_sink_notify(s->sink_input->sink);
1774 request_bytes(s);
1775
1776 for (ssync = s->prev; ssync; ssync = ssync->prev)
1777 request_bytes(ssync);
1778
1779 for (ssync = s->next; ssync; ssync = ssync->next)
1780 request_bytes(ssync);
1781 }
1782
1783 static void command_trigger_or_prebuf_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1784 struct connection *c = userdata;
1785 uint32_t idx;
1786 struct playback_stream *s;
1787 assert(c && t);
1788
1789 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1790 !pa_tagstruct_eof(t)) {
1791 protocol_error(c);
1792 return;
1793 }
1794
1795 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1796 CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX, tag, PA_ERR_INVALID);
1797 s = pa_idxset_get_by_index(c->output_streams, idx);
1798 CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
1799 CHECK_VALIDITY(c->pstream, s->type == PLAYBACK_STREAM, tag, PA_ERR_NOENTITY);
1800
1801 switch (command) {
1802 case PA_COMMAND_PREBUF_PLAYBACK_STREAM:
1803 pa_memblockq_prebuf_force(s->memblockq);
1804 break;
1805
1806 case PA_COMMAND_TRIGGER_PLAYBACK_STREAM:
1807 pa_memblockq_prebuf_disable(s->memblockq);
1808 break;
1809
1810 default:
1811 abort();
1812 }
1813
1814 pa_sink_notify(s->sink_input->sink);
1815 pa_pstream_send_simple_ack(c->pstream, tag);
1816 request_bytes(s);
1817 }
1818
1819 static void command_cork_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1820 struct connection *c = userdata;
1821 uint32_t idx;
1822 struct record_stream *s;
1823 int b;
1824 assert(c && t);
1825
1826 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1827 pa_tagstruct_get_boolean(t, &b) < 0 ||
1828 !pa_tagstruct_eof(t)) {
1829 protocol_error(c);
1830 return;
1831 }
1832
1833 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1834 s = pa_idxset_get_by_index(c->record_streams, idx);
1835 CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
1836
1837 pa_source_output_cork(s->source_output, b);
1838 pa_memblockq_prebuf_force(s->memblockq);
1839 pa_pstream_send_simple_ack(c->pstream, tag);
1840 }
1841
1842 static void command_flush_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1843 struct connection *c = userdata;
1844 uint32_t idx;
1845 struct record_stream *s;
1846 assert(c && t);
1847
1848 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1849 !pa_tagstruct_eof(t)) {
1850 protocol_error(c);
1851 return;
1852 }
1853
1854 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1855 s = pa_idxset_get_by_index(c->record_streams, idx);
1856 CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
1857
1858 pa_memblockq_flush(s->memblockq);
1859 pa_pstream_send_simple_ack(c->pstream, tag);
1860 }
1861
1862 static void command_set_default_sink_or_source(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1863 struct connection *c = userdata;
1864 const char *s;
1865 assert(c && t);
1866
1867 if (pa_tagstruct_gets(t, &s) < 0 ||
1868 !pa_tagstruct_eof(t)) {
1869 protocol_error(c);
1870 return;
1871 }
1872
1873 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1874 CHECK_VALIDITY(c->pstream, !s || (*s && pa_utf8_valid(s)), tag, PA_ERR_INVALID);
1875
1876 pa_namereg_set_default(c->protocol->core, s, command == PA_COMMAND_SET_DEFAULT_SOURCE ? PA_NAMEREG_SOURCE : PA_NAMEREG_SINK);
1877 pa_pstream_send_simple_ack(c->pstream, tag);
1878 }
1879
1880 static void command_set_stream_name(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1881 struct connection *c = userdata;
1882 uint32_t idx;
1883 const char *name;
1884 assert(c && t);
1885
1886 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1887 pa_tagstruct_gets(t, &name) < 0 ||
1888 !pa_tagstruct_eof(t)) {
1889 protocol_error(c);
1890 return;
1891 }
1892
1893 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1894 CHECK_VALIDITY(c->pstream, name && pa_utf8_valid(name), tag, PA_ERR_INVALID);
1895
1896 if (command == PA_COMMAND_SET_PLAYBACK_STREAM_NAME) {
1897 struct playback_stream *s;
1898
1899 s = pa_idxset_get_by_index(c->output_streams, idx);
1900 CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
1901 CHECK_VALIDITY(c->pstream, s->type == PLAYBACK_STREAM, tag, PA_ERR_NOENTITY);
1902
1903 pa_sink_input_set_name(s->sink_input, name);
1904
1905 } else {
1906 struct record_stream *s;
1907
1908 s = pa_idxset_get_by_index(c->record_streams, idx);
1909 CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
1910
1911 pa_source_output_set_name(s->source_output, name);
1912 }
1913
1914 pa_pstream_send_simple_ack(c->pstream, tag);
1915 }
1916
1917 static void command_kill(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1918 struct connection *c = userdata;
1919 uint32_t idx;
1920 assert(c && t);
1921
1922 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1923 !pa_tagstruct_eof(t)) {
1924 protocol_error(c);
1925 return;
1926 }
1927
1928 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1929
1930 if (command == PA_COMMAND_KILL_CLIENT) {
1931 pa_client *client;
1932
1933 client = pa_idxset_get_by_index(c->protocol->core->clients, idx);
1934 CHECK_VALIDITY(c->pstream, client, tag, PA_ERR_NOENTITY);
1935 pa_client_kill(client);
1936
1937 } else if (command == PA_COMMAND_KILL_SINK_INPUT) {
1938 pa_sink_input *s;
1939
1940 s = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx);
1941 CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
1942
1943 pa_sink_input_kill(s);
1944 } else {
1945 pa_source_output *s;
1946
1947 assert(command == PA_COMMAND_KILL_SOURCE_OUTPUT);
1948
1949 s = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx);
1950 CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
1951
1952 pa_source_output_kill(s);
1953 }
1954
1955 pa_pstream_send_simple_ack(c->pstream, tag);
1956 }
1957
1958 static void command_load_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1959 struct connection *c = userdata;
1960 pa_module *m;
1961 const char *name, *argument;
1962 pa_tagstruct *reply;
1963 assert(c && t);
1964
1965 if (pa_tagstruct_gets(t, &name) < 0 ||
1966 pa_tagstruct_gets(t, &argument) < 0 ||
1967 !pa_tagstruct_eof(t)) {
1968 protocol_error(c);
1969 return;
1970 }
1971
1972 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1973 CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name) && !strchr(name, '/'), tag, PA_ERR_INVALID);
1974 CHECK_VALIDITY(c->pstream, !argument || pa_utf8_valid(argument), tag, PA_ERR_INVALID);
1975
1976 if (!(m = pa_module_load(c->protocol->core, name, argument))) {
1977 pa_pstream_send_error(c->pstream, tag, PA_ERR_MODINITFAILED);
1978 return;
1979 }
1980
1981 reply = reply_new(tag);
1982 pa_tagstruct_putu32(reply, m->index);
1983 pa_pstream_send_tagstruct(c->pstream, reply);
1984 }
1985
1986 static void command_unload_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1987 struct connection *c = userdata;
1988 uint32_t idx;
1989 pa_module *m;
1990 assert(c && t);
1991
1992 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1993 !pa_tagstruct_eof(t)) {
1994 protocol_error(c);
1995 return;
1996 }
1997
1998 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
1999 m = pa_idxset_get_by_index(c->protocol->core->modules, idx);
2000 CHECK_VALIDITY(c->pstream, m, tag, PA_ERR_NOENTITY);
2001
2002 pa_module_unload_request(m);
2003 pa_pstream_send_simple_ack(c->pstream, tag);
2004 }
2005
2006 static void command_add_autoload(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
2007 struct connection *c = userdata;
2008 const char *name, *module, *argument;
2009 uint32_t type;
2010 uint32_t idx;
2011 pa_tagstruct *reply;
2012 assert(c && t);
2013
2014 if (pa_tagstruct_gets(t, &name) < 0 ||
2015 pa_tagstruct_getu32(t, &type) < 0 ||
2016 pa_tagstruct_gets(t, &module) < 0 ||
2017 pa_tagstruct_gets(t, &argument) < 0 ||
2018 !pa_tagstruct_eof(t)) {
2019 protocol_error(c);
2020 return;
2021 }
2022
2023 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
2024 CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID);
2025 CHECK_VALIDITY(c->pstream, type == 0 || type == 1, tag, PA_ERR_INVALID);
2026 CHECK_VALIDITY(c->pstream, module && *module && pa_utf8_valid(module), tag, PA_ERR_INVALID);
2027 CHECK_VALIDITY(c->pstream, !argument || pa_utf8_valid(argument), tag, PA_ERR_INVALID);
2028
2029 if (pa_autoload_add(c->protocol->core, name, type == 0 ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE, module, argument, &idx) < 0) {
2030 pa_pstream_send_error(c->pstream, tag, PA_ERR_EXIST);
2031 return;
2032 }
2033
2034 reply = reply_new(tag);
2035 pa_tagstruct_putu32(reply, idx);
2036 pa_pstream_send_tagstruct(c->pstream, reply);
2037 }
2038
2039 static void command_remove_autoload(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
2040 struct connection *c = userdata;
2041 const char *name = NULL;
2042 uint32_t type, idx = PA_IDXSET_INVALID;
2043 int r;
2044 assert(c && t);
2045
2046 if ((pa_tagstruct_getu32(t, &idx) < 0 &&
2047 (pa_tagstruct_gets(t, &name) < 0 ||
2048 pa_tagstruct_getu32(t, &type) < 0)) ||
2049 !pa_tagstruct_eof(t)) {
2050 protocol_error(c);
2051 return;
2052 }
2053
2054 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
2055 CHECK_VALIDITY(c->pstream, name || idx != PA_IDXSET_INVALID, tag, PA_ERR_INVALID);
2056 CHECK_VALIDITY(c->pstream, !name || (*name && pa_utf8_valid(name) && (type == 0 || type == 1)), tag, PA_ERR_INVALID);
2057
2058 if (name)
2059 r = pa_autoload_remove_by_name(c->protocol->core, name, type == 0 ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE);
2060 else
2061 r = pa_autoload_remove_by_index(c->protocol->core, idx);
2062
2063 CHECK_VALIDITY(c->pstream, r >= 0, tag, PA_ERR_NOENTITY);
2064
2065 pa_pstream_send_simple_ack(c->pstream, tag);
2066 }
2067
2068 static void autoload_fill_tagstruct(pa_tagstruct *t, const pa_autoload_entry *e) {
2069 assert(t && e);
2070
2071 pa_tagstruct_putu32(t, e->index);
2072 pa_tagstruct_puts(t, e->name);
2073 pa_tagstruct_putu32(t, e->type == PA_NAMEREG_SINK ? 0 : 1);
2074 pa_tagstruct_puts(t, e->module);
2075 pa_tagstruct_puts(t, e->argument);
2076 }
2077
2078 static void command_get_autoload_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
2079 struct connection *c = userdata;
2080 const pa_autoload_entry *a = NULL;
2081 uint32_t type, idx;
2082 const char *name;
2083 pa_tagstruct *reply;
2084 assert(c && t);
2085
2086 if ((pa_tagstruct_getu32(t, &idx) < 0 &&
2087 (pa_tagstruct_gets(t, &name) < 0 ||
2088 pa_tagstruct_getu32(t, &type) < 0)) ||
2089 !pa_tagstruct_eof(t)) {
2090 protocol_error(c);
2091 return;
2092 }
2093
2094 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
2095 CHECK_VALIDITY(c->pstream, name || idx != PA_IDXSET_INVALID, tag, PA_ERR_INVALID);
2096 CHECK_VALIDITY(c->pstream, !name || (*name && (type == 0 || type == 1) && pa_utf8_valid(name)), tag, PA_ERR_INVALID);
2097
2098 if (name)
2099 a = pa_autoload_get_by_name(c->protocol->core, name, type == 0 ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE);
2100 else
2101 a = pa_autoload_get_by_index(c->protocol->core, idx);
2102
2103 CHECK_VALIDITY(c->pstream, a, tag, PA_ERR_NOENTITY);
2104
2105 reply = reply_new(tag);
2106 autoload_fill_tagstruct(reply, a);
2107 pa_pstream_send_tagstruct(c->pstream, reply);
2108 }
2109
2110 static void command_get_autoload_info_list(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
2111 struct connection *c = userdata;
2112 pa_tagstruct *reply;
2113 assert(c && t);
2114
2115 if (!pa_tagstruct_eof(t)) {
2116 protocol_error(c);
2117 return;
2118 }
2119
2120 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
2121
2122 reply = reply_new(tag);
2123
2124 if (c->protocol->core->autoload_hashmap) {
2125 pa_autoload_entry *a;
2126 void *state = NULL;
2127
2128 while ((a = pa_hashmap_iterate(c->protocol->core->autoload_hashmap, &state, NULL)))
2129 autoload_fill_tagstruct(reply, a);
2130 }
2131
2132 pa_pstream_send_tagstruct(c->pstream, reply);
2133 }
2134
2135 static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
2136 struct connection *c = userdata;
2137 uint32_t idx = PA_INVALID_INDEX, idx_device = PA_INVALID_INDEX;
2138 const char *name = NULL;
2139
2140 assert(c);
2141 assert(t);
2142
2143 if (pa_tagstruct_getu32(t, &idx) < 0 ||
2144 pa_tagstruct_getu32(t, &idx_device) < 0 ||
2145 pa_tagstruct_gets(t, &name) < 0 ||
2146 !pa_tagstruct_eof(t)) {
2147 protocol_error(c);
2148 return;
2149 }
2150
2151 CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
2152 CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX, tag, PA_ERR_INVALID);
2153 CHECK_VALIDITY(c->pstream, idx_device != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID);
2154
2155 if (command == PA_COMMAND_MOVE_SINK_INPUT) {
2156 pa_sink_input *si = NULL;
2157 pa_sink *sink = NULL;
2158
2159 si = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx);
2160
2161 if (idx_device != PA_INVALID_INDEX)
2162 sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx_device);
2163 else
2164 sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK, 1);
2165
2166 CHECK_VALIDITY(c->pstream, si && sink, tag, PA_ERR_NOENTITY);
2167
2168 if (pa_sink_input_move_to(si, sink, 0) < 0) {
2169 pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID);
2170 return;
2171 }
2172 } else {
2173 pa_source_output *so = NULL;
2174 pa_source *source;
2175
2176 so = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx);
2177
2178 if (idx_device != PA_INVALID_INDEX)
2179 source = pa_idxset_get_by_index(c->protocol->core->sources, idx_device);
2180 else
2181 source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1);
2182
2183 CHECK_VALIDITY(c->pstream, so && source, tag, PA_ERR_NOENTITY);
2184
2185 if (pa_source_output_move_to(so, source) < 0) {
2186 pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID);
2187 return;
2188 }
2189 }
2190
2191 pa_pstream_send_simple_ack(c->pstream, tag);
2192
2193 }
2194
2195 /*** pstream callbacks ***/
2196
2197 static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata) {
2198 struct connection *c = userdata;
2199 assert(p && packet && packet->data && c);
2200
2201 if (pa_pdispatch_run(c->pdispatch, packet, creds, c) < 0) {
2202 pa_log(__FILE__": invalid packet.");
2203 connection_free(c);
2204 }
2205 }
2206
2207 static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata) {
2208 struct connection *c = userdata;
2209 struct output_stream *stream;
2210 assert(p && chunk && userdata);
2211
2212 if (!(stream = pa_idxset_get_by_index(c->output_streams, channel))) {
2213 pa_log(__FILE__": client sent block for invalid stream.");
2214 /* Ignoring */
2215 return;
2216 }
2217
2218 if (stream->type == PLAYBACK_STREAM) {
2219 struct playback_stream *ps = (struct playback_stream*) stream;
2220 if (chunk->length >= ps->requested_bytes)
2221 ps->requested_bytes = 0;
2222 else
2223 ps->requested_bytes -= chunk->length;
2224
2225 pa_memblockq_seek(ps->memblockq, offset, seek);
2226
2227 if (pa_memblockq_push_align(ps->memblockq, chunk) < 0) {
2228 pa_tagstruct *t;
2229
2230 pa_log_warn(__FILE__": failed to push data into queue");
2231
2232 /* Pushing this block into the queue failed, so we simulate
2233 * it by skipping ahead */
2234
2235 pa_memblockq_seek(ps->memblockq, chunk->length, PA_SEEK_RELATIVE);
2236
2237 /* Notify the user */
2238 t = pa_tagstruct_new(NULL, 0);
2239 pa_tagstruct_putu32(t, PA_COMMAND_OVERFLOW);
2240 pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
2241 pa_tagstruct_putu32(t, ps->index);
2242 pa_pstream_send_tagstruct(p, t);
2243 }
2244
2245 ps->underrun = 0;
2246
2247 pa_sink_notify(ps->sink_input->sink);
2248
2249 } else {
2250 struct upload_stream *u = (struct upload_stream*) stream;
2251 size_t l;
2252 assert(u->type == UPLOAD_STREAM);
2253
2254 if (!u->memchunk.memblock) {
2255 if (u->length == chunk->length) {
2256 u->memchunk = *chunk;
2257 pa_memblock_ref(u->memchunk.memblock);
2258 u->length = 0;
2259 } else {
2260 u->memchunk.memblock = pa_memblock_new(c->protocol->core->mempool, u->length);
2261 u->memchunk.index = u->memchunk.length = 0;
2262 }
2263 }
2264
2265 assert(u->memchunk.memblock);
2266
2267 l = u->length;
2268 if (l > chunk->length)
2269 l = chunk->length;
2270
2271 if (l > 0) {
2272 memcpy((uint8_t*) u->memchunk.memblock->data + u->memchunk.index + u->memchunk.length,
2273 (uint8_t*) chunk->memblock->data+chunk->index, l);
2274 u->memchunk.length += l;
2275 u->length -= l;
2276 }
2277 }
2278 }
2279
2280 static void pstream_die_callback(pa_pstream *p, void *userdata) {
2281 struct connection *c = userdata;
2282 assert(p && c);
2283 connection_free(c);
2284
2285 /* pa_log(__FILE__": connection died.");*/
2286 }
2287
2288
2289 static void pstream_drain_callback(pa_pstream *p, void *userdata) {
2290 struct connection *c = userdata;
2291 assert(p && c);
2292
2293 send_memblock(c);
2294 }
2295
2296 /*** client callbacks ***/
2297
2298 static void client_kill_cb(pa_client *c) {
2299 assert(c && c->userdata);
2300 connection_free(c->userdata);
2301 }
2302
2303 /*** socket server callbacks ***/
2304
2305 static void auth_timeout(pa_mainloop_api*m, pa_time_event *e, const struct timeval *tv, void *userdata) {
2306 struct connection *c = userdata;
2307 assert(m && tv && c && c->auth_timeout_event == e);
2308
2309 if (!c->authorized)
2310 connection_free(c);
2311 }
2312
2313 static void on_connection(PA_GCC_UNUSED pa_socket_server*s, pa_iochannel *io, void *userdata) {
2314 pa_protocol_native *p = userdata;
2315 struct connection *c;
2316 char cname[256], pname[128];
2317 assert(io && p);
2318
2319 if (pa_idxset_size(p->connections)+1 > MAX_CONNECTIONS) {
2320 pa_log_warn(__FILE__": Warning! Too many connections (%u), dropping incoming connection.", MAX_CONNECTIONS);
2321 pa_iochannel_free(io);
2322 return;
2323 }
2324
2325 c = pa_xmalloc(sizeof(struct connection));
2326
2327 c->authorized = !!p->public;
2328
2329 if (!c->authorized && p->auth_ip_acl && pa_ip_acl_check(p->auth_ip_acl, pa_iochannel_get_recv_fd(io)) > 0) {
2330 pa_log_info(__FILE__": Client authenticated by IP ACL.");
2331 c->authorized = 1;
2332 }
2333
2334 if (!c->authorized) {
2335 struct timeval tv;
2336 pa_gettimeofday(&tv);
2337 tv.tv_sec += AUTH_TIMEOUT;
2338 c->auth_timeout_event = p->core->mainloop->time_new(p->core->mainloop, &tv, auth_timeout, c);
2339 } else
2340 c->auth_timeout_event = NULL;
2341
2342 c->version = 8;
2343 c->protocol = p;
2344 pa_iochannel_socket_peer_to_string(io, pname, sizeof(pname));
2345 snprintf(cname, sizeof(cname), "Native client (%s)", pname);
2346 assert(p->core);
2347 c->client = pa_client_new(p->core, __FILE__, cname);
2348 assert(c->client);
2349 c->client->kill = client_kill_cb;
2350 c->client->userdata = c;
2351 c->client->owner = p->module;
2352
2353 c->pstream = pa_pstream_new(p->core->mainloop, io, p->core->mempool);
2354 assert(c->pstream);
2355
2356 pa_pstream_use_shm(c->pstream, 1);
2357
2358 pa_pstream_set_recieve_packet_callback(c->pstream, pstream_packet_callback, c);
2359 pa_pstream_set_recieve_memblock_callback(c->pstream, pstream_memblock_callback, c);
2360 pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c);
2361 pa_pstream_set_drain_callback(c->pstream, pstream_drain_callback, c);
2362
2363 c->pdispatch = pa_pdispatch_new(p->core->mainloop, command_table, PA_COMMAND_MAX);
2364 assert(c->pdispatch);
2365
2366 c->record_streams = pa_idxset_new(NULL, NULL);
2367 c->output_streams = pa_idxset_new(NULL, NULL);
2368 assert(c->record_streams && c->output_streams);
2369
2370 c->rrobin_index = PA_IDXSET_INVALID;
2371 c->subscription = NULL;
2372
2373 pa_idxset_put(p->connections, c, NULL);
2374
2375
2376 #ifdef HAVE_CREDS
2377 if (pa_iochannel_creds_supported(io))
2378 pa_iochannel_creds_enable(io);
2379
2380 #endif
2381 }
2382
2383 /*** module entry points ***/
2384
2385 static int load_key(pa_protocol_native*p, const char*fn) {
2386 assert(p);
2387
2388 p->auth_cookie_in_property = 0;
2389
2390 if (!fn && pa_authkey_prop_get(p->core, PA_NATIVE_COOKIE_PROPERTY_NAME, p->auth_cookie, sizeof(p->auth_cookie)) >= 0) {
2391 pa_log_info(__FILE__": using already loaded auth cookie.");
2392 pa_authkey_prop_ref(p->core, PA_NATIVE_COOKIE_PROPERTY_NAME);
2393 p->auth_cookie_in_property = 1;
2394 return 0;
2395 }
2396
2397 if (!fn)
2398 fn = PA_NATIVE_COOKIE_FILE;
2399
2400 if (pa_authkey_load_auto(fn, p->auth_cookie, sizeof(p->auth_cookie)) < 0)
2401 return -1;
2402
2403 pa_log_info(__FILE__": loading cookie from disk.");
2404
2405 if (pa_authkey_prop_put(p->core, PA_NATIVE_COOKIE_PROPERTY_NAME, p->auth_cookie, sizeof(p->auth_cookie)) >= 0)
2406 p->auth_cookie_in_property = 1;
2407
2408 return 0;
2409 }
2410
2411 static pa_protocol_native* protocol_new_internal(pa_core *c, pa_module *m, pa_modargs *ma) {
2412 pa_protocol_native *p;
2413 int public = 0;
2414 const char *acl;
2415
2416 assert(c);
2417 assert(ma);
2418
2419 if (pa_modargs_get_value_boolean(ma, "auth-anonymous", &public) < 0) {
2420 pa_log(__FILE__": auth-anonymous= expects a boolean argument.");
2421 return NULL;
2422 }
2423
2424 p = pa_xnew(pa_protocol_native, 1);
2425 p->core = c;
2426 p->module = m;
2427 p->public = public;
2428 p->server = NULL;
2429 p->auth_ip_acl = NULL;
2430
2431 #ifdef HAVE_CREDS
2432 {
2433 int a = 1;
2434 if (pa_modargs_get_value_boolean(ma, "auth-group-enabled", &a) < 0) {
2435 pa_log(__FILE__": auth-group-enabled= expects a boolean argument.");
2436 return NULL;
2437 }
2438 p->auth_group = a ? pa_xstrdup(pa_modargs_get_value(ma, "auth-group", c->is_system_instance ? PA_ACCESS_GROUP : NULL)) : NULL;
2439
2440 if (p->auth_group)
2441 pa_log_info(__FILE__": Allowing access to group '%s'.", p->auth_group);
2442 }
2443 #endif
2444
2445
2446 if ((acl = pa_modargs_get_value(ma, "auth-ip-acl", NULL))) {
2447
2448 if (!(p->auth_ip_acl = pa_ip_acl_new(acl))) {
2449 pa_log(__FILE__": Failed to parse IP ACL '%s'", acl);
2450 goto fail;
2451 }
2452 }
2453
2454 if (load_key(p, pa_modargs_get_value(ma, "cookie", NULL)) < 0)
2455 goto fail;
2456
2457 p->connections = pa_idxset_new(NULL, NULL);
2458 assert(p->connections);
2459
2460 return p;
2461
2462 fail:
2463 #ifdef HAVE_CREDS
2464 pa_xfree(p->auth_group);
2465 #endif
2466 if (p->auth_ip_acl)
2467 pa_ip_acl_free(p->auth_ip_acl);
2468 pa_xfree(p);
2469 return NULL;
2470 }
2471
2472 pa_protocol_native* pa_protocol_native_new(pa_core *core, pa_socket_server *server, pa_module *m, pa_modargs *ma) {
2473 char t[256];
2474 pa_protocol_native *p;
2475
2476 if (!(p = protocol_new_internal(core, m, ma)))
2477 return NULL;
2478
2479 p->server = server;
2480 pa_socket_server_set_callback(p->server, on_connection, p);
2481
2482 if (pa_socket_server_get_address(p->server, t, sizeof(t))) {
2483 pa_strlist *l;
2484 l = pa_property_get(core, PA_NATIVE_SERVER_PROPERTY_NAME);
2485 l = pa_strlist_prepend(l, t);
2486 pa_property_replace(core, PA_NATIVE_SERVER_PROPERTY_NAME, l);
2487 }
2488
2489 return p;
2490 }
2491
2492 void pa_protocol_native_free(pa_protocol_native *p) {
2493 struct connection *c;
2494 assert(p);
2495
2496 while ((c = pa_idxset_first(p->connections, NULL)))
2497 connection_free(c);
2498 pa_idxset_free(p->connections, NULL, NULL);
2499
2500 if (p->server) {
2501 char t[256];
2502
2503 if (pa_socket_server_get_address(p->server, t, sizeof(t))) {
2504 pa_strlist *l;
2505 l = pa_property_get(p->core, PA_NATIVE_SERVER_PROPERTY_NAME);
2506 l = pa_strlist_remove(l, t);
2507
2508 if (l)
2509 pa_property_replace(p->core, PA_NATIVE_SERVER_PROPERTY_NAME, l);
2510 else
2511 pa_property_remove(p->core, PA_NATIVE_SERVER_PROPERTY_NAME);
2512 }
2513
2514 pa_socket_server_unref(p->server);
2515 }
2516
2517 if (p->auth_cookie_in_property)
2518 pa_authkey_prop_unref(p->core, PA_NATIVE_COOKIE_PROPERTY_NAME);
2519
2520 if (p->auth_ip_acl)
2521 pa_ip_acl_free(p->auth_ip_acl);
2522
2523 #ifdef HAVE_CREDS
2524 pa_xfree(p->auth_group);
2525 #endif
2526 pa_xfree(p);
2527 }
2528
2529 pa_protocol_native* pa_protocol_native_new_iochannel(pa_core*core, pa_iochannel *io, pa_module *m, pa_modargs *ma) {
2530 pa_protocol_native *p;
2531
2532 if (!(p = protocol_new_internal(core, m, ma)))
2533 return NULL;
2534
2535 on_connection(NULL, io, p);
2536
2537 return p;
2538 }