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