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