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