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