1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2008 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
11
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #ifndef LOG_TAG
26 #define LOG_TAG "Context"
27 #endif
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/types.h>
33 #include <unistd.h>
34 #include <sys/stat.h>
35 #include <errno.h>
36 #include <signal.h>
37
38 #ifdef HAVE_SYS_WAIT_H
39 #include <sys/wait.h>
40 #endif
41
42 #ifdef HAVE_NETDB_H
43 #include <netdb.h>
44 #endif
45
46 #include <pulse/version.h>
47 #include <pulse/xmalloc.h>
48 #include <pulse/util.h>
49 #include <pulse/mainloop.h>
50 #include <pulse/timeval.h>
51 #include <pulse/fork-detect.h>
52 #include <pulse/client-conf.h>
53
54 #include <pulsecore/core-error.h>
55 #include <pulsecore/i18n.h>
56 #include <pulsecore/native-common.h>
57 #include <pulsecore/pdispatch.h>
58 #include <pulsecore/pstream.h>
59 #include <pulsecore/hashmap.h>
60 #include <pulsecore/socket-client.h>
61 #include <pulsecore/pstream-util.h>
62 #include <pulsecore/core-rtclock.h>
63 #include <pulsecore/core-util.h>
64 #include <pulsecore/log.h>
65 #include <pulsecore/socket.h>
66 #include <pulsecore/creds.h>
67 #include <pulsecore/macro.h>
68 #include <pulsecore/proplist-util.h>
69
70 #include "internal.h"
71 #include "context.h"
72
73 void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
74 static void pa_command_enable_srbchannel(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
75 static void pa_command_disable_srbchannel(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
76 static void pa_command_register_memfd_shmid(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
77
78 static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
79 [PA_COMMAND_REQUEST] = pa_command_request,
80 [PA_COMMAND_OVERFLOW] = pa_command_overflow_or_underflow,
81 [PA_COMMAND_UNDERFLOW] = pa_command_overflow_or_underflow,
82 [PA_COMMAND_PLAYBACK_STREAM_KILLED] = pa_command_stream_killed,
83 [PA_COMMAND_RECORD_STREAM_KILLED] = pa_command_stream_killed,
84 [PA_COMMAND_PLAYBACK_STREAM_MOVED] = pa_command_stream_moved,
85 [PA_COMMAND_RECORD_STREAM_MOVED] = pa_command_stream_moved,
86 [PA_COMMAND_PLAYBACK_STREAM_SUSPENDED] = pa_command_stream_suspended,
87 [PA_COMMAND_RECORD_STREAM_SUSPENDED] = pa_command_stream_suspended,
88 [PA_COMMAND_STARTED] = pa_command_stream_started,
89 [PA_COMMAND_SUBSCRIBE_EVENT] = pa_command_subscribe_event,
90 [PA_COMMAND_EXTENSION] = pa_command_extension,
91 [PA_COMMAND_PLAYBACK_STREAM_EVENT] = pa_command_stream_event,
92 [PA_COMMAND_RECORD_STREAM_EVENT] = pa_command_stream_event,
93 [PA_COMMAND_CLIENT_EVENT] = pa_command_client_event,
94 [PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED] = pa_command_stream_buffer_attr,
95 [PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED] = pa_command_stream_buffer_attr,
96 [PA_COMMAND_ENABLE_SRBCHANNEL] = pa_command_enable_srbchannel,
97 [PA_COMMAND_DISABLE_SRBCHANNEL] = pa_command_disable_srbchannel,
98 [PA_COMMAND_REGISTER_MEMFD_SHMID] = pa_command_register_memfd_shmid,
99 [PA_COMMAND_UNDERFLOW_OHOS] = pa_command_overflow_or_underflow,
100 };
101 static void context_free(pa_context *c);
102
103 #ifdef HAVE_DBUS
104 static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, void *userdata);
105 #endif
106
pa_context_new(pa_mainloop_api *mainloop, const char *name)107 pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) {
108 return pa_context_new_with_proplist(mainloop, name, NULL);
109 }
110
reset_callbacks(pa_context *c)111 static void reset_callbacks(pa_context *c) {
112 pa_assert(c);
113
114 c->state_callback = NULL;
115 c->state_userdata = NULL;
116
117 c->subscribe_callback = NULL;
118 c->subscribe_userdata = NULL;
119
120 c->event_callback = NULL;
121 c->event_userdata = NULL;
122
123 c->ext_device_manager.callback = NULL;
124 c->ext_device_manager.userdata = NULL;
125
126 c->ext_device_restore.callback = NULL;
127 c->ext_device_restore.userdata = NULL;
128
129 c->ext_stream_restore.callback = NULL;
130 c->ext_stream_restore.userdata = NULL;
131 }
132
pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, const pa_proplist *p)133 pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, const pa_proplist *p) {
134 pa_context *c;
135 pa_mem_type_t type;
136 const char *force_disable_shm_str;
137
138 pa_assert(mainloop);
139
140 if (pa_detect_fork())
141 return NULL;
142
143 pa_init_i18n();
144
145 c = pa_xnew0(pa_context, 1);
146 PA_REFCNT_INIT(c);
147
148 c->error = pa_xnew0(pa_context_error, 1);
149 assert(c->error);
150
151 c->proplist = p ? pa_proplist_copy(p) : pa_proplist_new();
152
153 if (name)
154 pa_proplist_sets(c->proplist, PA_PROP_APPLICATION_NAME, name);
155
156 #ifdef HAVE_DBUS
157 c->system_bus = c->session_bus = NULL;
158 #endif
159 c->mainloop = mainloop;
160 c->playback_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
161 c->record_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
162 c->client_index = PA_INVALID_INDEX;
163 c->use_rtclock = pa_mainloop_is_our_api(mainloop);
164
165 PA_LLIST_HEAD_INIT(pa_stream, c->streams);
166 PA_LLIST_HEAD_INIT(pa_operation, c->operations);
167
168 c->error->error = PA_OK;
169 c->state = PA_CONTEXT_UNCONNECTED;
170
171 reset_callbacks(c);
172
173 #ifndef MSG_NOSIGNAL
174 #ifdef SIGPIPE
175 pa_check_signal_is_blocked(SIGPIPE);
176 #endif
177 #endif
178
179 c->conf = pa_client_conf_new();
180 pa_client_conf_load(c->conf, true, true);
181
182 force_disable_shm_str = pa_proplist_gets(c->proplist, PA_PROP_CONTEXT_FORCE_DISABLE_SHM);
183 if (force_disable_shm_str) {
184 int b = pa_parse_boolean(force_disable_shm_str);
185 if (b < 0) {
186 pa_log_warn("Ignored invalid value for '%s' property: %s", PA_PROP_CONTEXT_FORCE_DISABLE_SHM, force_disable_shm_str);
187 } else if (b) {
188 c->conf->disable_shm = true;
189 }
190 }
191
192 c->srb_template.readfd = -1;
193 c->srb_template.writefd = -1;
194
195 c->memfd_on_local = (!c->conf->disable_memfd && pa_memfd_is_locally_supported());
196
197 type = (c->conf->disable_shm) ? PA_MEM_TYPE_PRIVATE :
198 ((!c->memfd_on_local) ?
199 PA_MEM_TYPE_SHARED_POSIX : PA_MEM_TYPE_SHARED_MEMFD);
200
201 if (!(c->mempool = pa_mempool_new(type, c->conf->shm_size, true))) {
202
203 if (!c->conf->disable_shm) {
204 pa_log_warn("Failed to allocate shared memory pool. Falling back to a normal private one.");
205 c->mempool = pa_mempool_new(PA_MEM_TYPE_PRIVATE, c->conf->shm_size, true);
206 }
207
208 if (!c->mempool) {
209 context_free(c);
210 return NULL;
211 }
212 }
213
214 return c;
215 }
216
context_unlink(pa_context *c)217 static void context_unlink(pa_context *c) {
218 pa_stream *s;
219
220 pa_assert(c);
221
222 s = c->streams ? pa_stream_ref(c->streams) : NULL;
223 while (s) {
224 pa_stream *n = s->next ? pa_stream_ref(s->next) : NULL;
225 pa_stream_set_state(s, c->state == PA_CONTEXT_FAILED ? PA_STREAM_FAILED : PA_STREAM_TERMINATED);
226 pa_stream_unref(s);
227 s = n;
228 }
229
230 while (c->operations)
231 pa_operation_cancel(c->operations);
232
233 if (c->pdispatch) {
234 pa_pdispatch_unref(c->pdispatch);
235 c->pdispatch = NULL;
236 }
237
238 if (c->pstream) {
239 pa_pstream_unlink(c->pstream);
240 pa_pstream_unref(c->pstream);
241 c->pstream = NULL;
242 }
243
244 if (c->srb_template.memblock) {
245 pa_memblock_unref(c->srb_template.memblock);
246 c->srb_template.memblock = NULL;
247 }
248
249 if (c->client) {
250 pa_socket_client_unref(c->client);
251 c->client = NULL;
252 }
253
254 reset_callbacks(c);
255 }
256
context_free(pa_context *c)257 static void context_free(pa_context *c) {
258 pa_assert(c);
259
260 context_unlink(c);
261
262 #ifdef HAVE_DBUS
263 if (c->system_bus) {
264 if (c->filter_added)
265 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c->system_bus), filter_cb, c);
266 pa_dbus_wrap_connection_free(c->system_bus);
267 }
268
269 if (c->session_bus) {
270 if (c->filter_added)
271 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c->session_bus), filter_cb, c);
272 pa_dbus_wrap_connection_free(c->session_bus);
273 }
274 #endif
275
276 if (c->record_streams)
277 pa_hashmap_free(c->record_streams);
278 if (c->playback_streams)
279 pa_hashmap_free(c->playback_streams);
280
281 if (c->mempool)
282 pa_mempool_unref(c->mempool);
283
284 if (c->conf)
285 pa_client_conf_free(c->conf);
286
287 pa_strlist_free(c->server_list);
288
289 if (c->proplist)
290 pa_proplist_free(c->proplist);
291
292 pa_xfree(c->server);
293 pa_xfree(c->error);
294 pa_xfree(c);
295 }
296
pa_context_ref(pa_context *c)297 pa_context* pa_context_ref(pa_context *c) {
298 pa_assert(c);
299 pa_assert(PA_REFCNT_VALUE(c) >= 1);
300
301 PA_REFCNT_INC(c);
302 return c;
303 }
304
pa_context_unref(pa_context *c)305 void pa_context_unref(pa_context *c) {
306 pa_assert(c);
307 pa_assert(PA_REFCNT_VALUE(c) >= 1);
308
309 if (PA_REFCNT_DEC(c) <= 0)
310 context_free(c);
311 }
312
pa_context_set_state(pa_context *c, pa_context_state_t st)313 void pa_context_set_state(pa_context *c, pa_context_state_t st) {
314 pa_assert(c);
315 pa_assert(PA_REFCNT_VALUE(c) >= 1);
316
317 if (c->state == st)
318 return;
319
320 pa_context_ref(c);
321
322 c->state = st;
323
324 if (c->state_callback)
325 c->state_callback(c, c->state_userdata);
326
327 if (st == PA_CONTEXT_FAILED || st == PA_CONTEXT_TERMINATED)
328 context_unlink(c);
329
330 pa_context_unref(c);
331 }
332
pa_context_set_error(const pa_context *c, int error)333 int pa_context_set_error(const pa_context *c, int error) {
334 pa_assert(error >= 0);
335 pa_assert(error < PA_ERR_MAX);
336
337 if (c)
338 c->error->error = error;
339
340 return error;
341 }
342
pa_context_fail(pa_context *c, int error)343 void pa_context_fail(pa_context *c, int error) {
344 pa_assert(c);
345 pa_assert(PA_REFCNT_VALUE(c) >= 1);
346
347 pa_context_set_error(c, error);
348 pa_context_set_state(c, PA_CONTEXT_FAILED);
349 }
350
pstream_die_callback(pa_pstream *p, void *userdata)351 static void pstream_die_callback(pa_pstream *p, void *userdata) {
352 pa_context *c = userdata;
353
354 pa_assert(p);
355 pa_assert(c);
356
357 pa_context_fail(c, PA_ERR_CONNECTIONTERMINATED);
358 }
359
pstream_packet_callback(pa_pstream *p, pa_packet *packet, pa_cmsg_ancil_data *ancil_data, void *userdata)360 static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, pa_cmsg_ancil_data *ancil_data, void *userdata) {
361 pa_context *c = userdata;
362
363 pa_assert(p);
364 pa_assert(packet);
365 pa_assert(c);
366
367 pa_context_ref(c);
368
369 if (pa_pdispatch_run(c->pdispatch, packet, ancil_data, c) < 0)
370 pa_context_fail(c, PA_ERR_PROTOCOL);
371
372 pa_context_unref(c);
373 }
374
handle_srbchannel_memblock(pa_context *c, pa_memblock *memblock)375 static void handle_srbchannel_memblock(pa_context *c, pa_memblock *memblock) {
376 pa_srbchannel *sr;
377 pa_tagstruct *t;
378
379 pa_assert(c);
380
381 /* Memblock sanity check */
382 if (!memblock) {
383 pa_context_fail(c, PA_ERR_PROTOCOL);
384 return;
385 } else if (pa_memblock_is_read_only(memblock)) {
386 pa_context_fail(c, PA_ERR_PROTOCOL);
387 return;
388 } else if (pa_memblock_is_ours(memblock)) {
389 pa_context_fail(c, PA_ERR_PROTOCOL);
390 return;
391 }
392
393 /* Create the srbchannel */
394 c->srb_template.memblock = memblock;
395 pa_memblock_ref(memblock);
396 sr = pa_srbchannel_new_from_template(c->mainloop, &c->srb_template);
397 if (!sr) {
398 pa_log_warn("Failed to create srbchannel from template");
399 c->srb_template.readfd = -1;
400 c->srb_template.writefd = -1;
401 pa_memblock_unref(c->srb_template.memblock);
402 c->srb_template.memblock = NULL;
403 return;
404 }
405
406 /* Ack the enable command */
407 t = pa_tagstruct_new();
408 pa_tagstruct_putu32(t, PA_COMMAND_ENABLE_SRBCHANNEL);
409 pa_tagstruct_putu32(t, c->srb_setup_tag);
410 pa_pstream_send_tagstruct(c->pstream, t);
411
412 /* ...and switch over */
413 pa_pstream_set_srbchannel(c->pstream, sr);
414 }
415
pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata)416 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) {
417 pa_context *c = userdata;
418 pa_stream *s;
419
420 pa_assert(p);
421 pa_assert(chunk);
422 pa_assert(chunk->length > 0);
423 pa_assert(c);
424 pa_assert(PA_REFCNT_VALUE(c) >= 1);
425
426 pa_context_ref(c);
427
428 if (c->srb_template.readfd != -1 && c->srb_template.memblock == NULL) {
429 handle_srbchannel_memblock(c, chunk->memblock);
430 pa_context_unref(c);
431 return;
432 }
433
434 if ((s = pa_hashmap_get(c->record_streams, PA_UINT32_TO_PTR(channel)))) {
435
436 if (chunk->memblock) {
437 pa_memblockq_seek(s->record_memblockq, offset, seek, true);
438 pa_memblockq_push_align(s->record_memblockq, chunk);
439 } else
440 pa_memblockq_seek(s->record_memblockq, offset+chunk->length, seek, true);
441
442 if (s->read_callback) {
443 size_t l;
444
445 if ((l = pa_memblockq_get_length(s->record_memblockq)) > 0)
446 s->read_callback(s, l, s->read_userdata);
447 }
448 }
449
450 pa_context_unref(c);
451 }
452
pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t, bool fail)453 int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t, bool fail) {
454 uint32_t err;
455 pa_assert(c);
456 pa_assert(PA_REFCNT_VALUE(c) >= 1);
457
458 if (command == PA_COMMAND_ERROR) {
459 pa_assert(t);
460
461 if (pa_tagstruct_getu32(t, &err) < 0 ||
462 !pa_tagstruct_eof(t)) {
463 pa_context_fail(c, PA_ERR_PROTOCOL);
464 return -1;
465 }
466
467 } else if (command == PA_COMMAND_TIMEOUT)
468 err = PA_ERR_TIMEOUT;
469 else {
470 pa_context_fail(c, PA_ERR_PROTOCOL);
471 return -1;
472 }
473
474 if (err == PA_OK) {
475 pa_context_fail(c, PA_ERR_PROTOCOL);
476 return -1;
477 }
478
479 if (err >= PA_ERR_MAX)
480 err = PA_ERR_UNKNOWN;
481
482 if (fail) {
483 pa_context_fail(c, (int) err);
484 return -1;
485 }
486
487 pa_context_set_error(c, (int) err);
488
489 return 0;
490 }
491
setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata)492 static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
493 pa_context *c = userdata;
494
495 pa_assert(pd);
496 pa_assert(c);
497 pa_assert(c->state == PA_CONTEXT_AUTHORIZING || c->state == PA_CONTEXT_SETTING_NAME);
498
499 pa_context_ref(c);
500
501 if (command != PA_COMMAND_REPLY) {
502 pa_context_handle_error(c, command, t, true);
503 goto finish;
504 }
505
506 switch(c->state) {
507 case PA_CONTEXT_AUTHORIZING: {
508 pa_tagstruct *reply;
509 bool shm_on_remote = false;
510 bool memfd_on_remote = false;
511
512 if (pa_tagstruct_getu32(t, &c->version) < 0 ||
513 !pa_tagstruct_eof(t)) {
514 pa_context_fail(c, PA_ERR_PROTOCOL);
515 goto finish;
516 }
517
518 /* Minimum supported version */
519 if (c->version < 8) {
520 pa_context_fail(c, PA_ERR_VERSION);
521 goto finish;
522 }
523
524 /* Starting with protocol version 13 the MSB of the version
525 tag reflects if shm is available for this connection or
526 not. */
527 if ((c->version & PA_PROTOCOL_VERSION_MASK) >= 13) {
528 shm_on_remote = !!(c->version & PA_PROTOCOL_FLAG_SHM);
529
530 /* Starting with protocol version 31, the second MSB of the version
531 * tag reflects whether memfd is supported on the other PA end. */
532 if ((c->version & PA_PROTOCOL_VERSION_MASK) >= 31)
533 memfd_on_remote = !!(c->version & PA_PROTOCOL_FLAG_MEMFD);
534
535 /* Reserve the two most-significant _bytes_ of the version tag
536 * for flags. */
537 c->version &= PA_PROTOCOL_VERSION_MASK;
538 }
539
540 pa_log_debug("Protocol version: remote %u, local %u", c->version, PA_PROTOCOL_VERSION);
541
542 /* Enable shared memory support if possible */
543 if (c->do_shm)
544 if (c->version < 10 || (c->version >= 13 && !shm_on_remote))
545 c->do_shm = false;
546
547 if (c->do_shm) {
548
549 /* Only enable SHM if both sides are owned by the same
550 * user. This is a security measure because otherwise
551 * data private to the user might leak. */
552
553 #ifdef HAVE_CREDS
554 const pa_creds *creds;
555 if (!(creds = pa_pdispatch_creds(pd)) || getuid() != creds->uid)
556 c->do_shm = false;
557 #endif
558 }
559
560 pa_log_debug("Negotiated SHM: %s", pa_yes_no(c->do_shm));
561 pa_pstream_enable_shm(c->pstream, c->do_shm);
562
563 c->shm_type = PA_MEM_TYPE_PRIVATE;
564 if (c->do_shm) {
565 if (c->version >= 31 && memfd_on_remote && c->memfd_on_local) {
566 const char *reason;
567
568 pa_pstream_enable_memfd(c->pstream);
569 if (pa_mempool_is_memfd_backed(c->mempool))
570 if (pa_pstream_register_memfd_mempool(c->pstream, c->mempool, &reason))
571 pa_log("Failed to regester memfd mempool. Reason: %s", reason);
572
573 /* Even if memfd pool registration fails, the negotiated SHM type
574 * shall remain memfd as both endpoints claim to support it. */
575 c->shm_type = PA_MEM_TYPE_SHARED_MEMFD;
576 } else
577 c->shm_type = PA_MEM_TYPE_SHARED_POSIX;
578 }
579
580 pa_log_debug("Memfd possible: %s", pa_yes_no(c->memfd_on_local));
581 pa_log_debug("Negotiated SHM type: %s", pa_mem_type_to_string(c->shm_type));
582
583 reply = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
584
585 if (c->version >= 13) {
586 pa_init_proplist(c->proplist);
587 pa_tagstruct_put_proplist(reply, c->proplist);
588 } else
589 pa_tagstruct_puts(reply, pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME));
590
591 pa_pstream_send_tagstruct(c->pstream, reply);
592 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
593
594 pa_context_set_state(c, PA_CONTEXT_SETTING_NAME);
595 break;
596 }
597
598 case PA_CONTEXT_SETTING_NAME :
599
600 if ((c->version >= 13 && (pa_tagstruct_getu32(t, &c->client_index) < 0 ||
601 c->client_index == PA_INVALID_INDEX)) ||
602 !pa_tagstruct_eof(t)) {
603 pa_context_fail(c, PA_ERR_PROTOCOL);
604 goto finish;
605 }
606
607 pa_context_set_state(c, PA_CONTEXT_READY);
608 break;
609
610 default:
611 pa_assert_not_reached();
612 }
613
614 finish:
615 pa_context_unref(c);
616 }
617
setup_context(pa_context *c, pa_iochannel *io)618 static void setup_context(pa_context *c, pa_iochannel *io) {
619 uint8_t cookie[PA_NATIVE_COOKIE_LENGTH];
620 pa_tagstruct *t;
621 uint32_t tag;
622
623 pa_assert(c);
624 pa_assert(io);
625
626 pa_context_ref(c);
627
628 pa_assert(!c->pstream);
629 c->pstream = pa_pstream_new(c->mainloop, io, c->mempool);
630
631 pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c);
632 pa_pstream_set_receive_packet_callback(c->pstream, pstream_packet_callback, c);
633 pa_pstream_set_receive_memblock_callback(c->pstream, pstream_memblock_callback, c);
634
635 pa_assert(!c->pdispatch);
636 c->pdispatch = pa_pdispatch_new(c->mainloop, c->use_rtclock, command_table, PA_COMMAND_MAX);
637
638 if (pa_client_conf_load_cookie(c->conf, cookie, sizeof(cookie)) < 0)
639 pa_log_info("No cookie loaded. Attempting to connect without.");
640
641 t = pa_tagstruct_command(c, PA_COMMAND_AUTH, &tag);
642
643 c->do_shm =
644 pa_mempool_is_shared(c->mempool) &&
645 c->is_local;
646
647 pa_log_debug("SHM possible: %s", pa_yes_no(c->do_shm));
648
649 /* Starting with protocol version 13 we use the MSB of the version
650 * tag for informing the other side if we could do SHM or not.
651 * Starting from version 31, second MSB is used to flag memfd support. */
652 pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION | (c->do_shm ? PA_PROTOCOL_FLAG_SHM : 0) |
653 (c->memfd_on_local ? PA_PROTOCOL_FLAG_MEMFD: 0));
654 pa_tagstruct_put_arbitrary(t, cookie, sizeof(cookie));
655
656 #ifdef HAVE_CREDS
657 {
658 pa_creds ucred;
659
660 if (pa_iochannel_creds_supported(io))
661 pa_iochannel_creds_enable(io);
662
663 ucred.uid = getuid();
664 ucred.gid = getgid();
665
666 pa_pstream_send_tagstruct_with_creds(c->pstream, t, &ucred);
667 }
668 #else
669 pa_pstream_send_tagstruct(c->pstream, t);
670 #endif
671
672 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
673
674 pa_context_set_state(c, PA_CONTEXT_AUTHORIZING);
675
676 pa_context_unref(c);
677 }
678
prepend_per_user(pa_strlist *l)679 static pa_strlist *prepend_per_user(pa_strlist *l) {
680 char *ufn;
681
682 /* The per-user instance */
683 if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
684 l = pa_strlist_prepend(l, ufn);
685 pa_xfree(ufn);
686 }
687
688 return l;
689 }
690
691 #ifndef OS_IS_WIN32
692
context_autospawn(pa_context *c)693 static int context_autospawn(pa_context *c) {
694 pid_t pid;
695 int status, r;
696 struct sigaction sa;
697
698 pa_context_ref(c);
699
700 if (sigaction(SIGCHLD, NULL, &sa) < 0) {
701 pa_log_debug("sigaction() failed: %s", pa_cstrerror(errno));
702 pa_context_fail(c, PA_ERR_INTERNAL);
703 goto fail;
704 }
705
706 #ifdef SA_NOCLDWAIT
707 if ((sa.sa_flags & SA_NOCLDWAIT) || sa.sa_handler == SIG_IGN) {
708 #else
709 if (sa.sa_handler == SIG_IGN) {
710 #endif
711 pa_log_error("Process disabled waitpid(), cannot autospawn.");
712 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
713 goto fail;
714 }
715
716 pa_log_debug("Trying to autospawn...");
717
718 if (c->spawn_api.prefork)
719 c->spawn_api.prefork();
720
721 if ((pid = fork()) < 0) {
722 pa_log_error(_("fork(): %s"), pa_cstrerror(errno));
723 pa_context_fail(c, PA_ERR_INTERNAL);
724
725 if (c->spawn_api.postfork)
726 c->spawn_api.postfork();
727
728 goto fail;
729 } else if (!pid) {
730 /* Child */
731
732 const char *state = NULL;
733 const char * argv[32];
734 unsigned n = 0;
735
736 if (c->spawn_api.atfork)
737 c->spawn_api.atfork();
738
739 /* We leave most of the cleaning up of the process environment
740 * to the executable. We only clean up the file descriptors to
741 * make sure the executable can actually be loaded
742 * correctly. */
743 pa_close_all(-1);
744
745 /* Setup argv */
746 argv[n++] = c->conf->daemon_binary;
747 argv[n++] = "--start";
748
749 while (n < PA_ELEMENTSOF(argv)-1) {
750 char *a;
751
752 if (!(a = pa_split_spaces(c->conf->extra_arguments, &state)))
753 break;
754
755 argv[n++] = a;
756 }
757
758 argv[n++] = NULL;
759 pa_assert(n <= PA_ELEMENTSOF(argv));
760
761 execv(argv[0], (char * const *) argv);
762 _exit(1);
763 }
764
765 /* Parent */
766
767 if (c->spawn_api.postfork)
768 c->spawn_api.postfork();
769
770 do {
771 r = waitpid(pid, &status, 0);
772 } while (r < 0 && errno == EINTR);
773
774 if (r < 0) {
775
776 if (errno != ECHILD) {
777 pa_log(_("waitpid(): %s"), pa_cstrerror(errno));
778 pa_context_fail(c, PA_ERR_INTERNAL);
779 goto fail;
780 }
781
782 /* hmm, something already reaped our child, so we assume
783 * startup worked, even if we cannot know */
784
785 } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
786 pa_log_error("Connection refused for status");
787 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
788 goto fail;
789 }
790
791 pa_context_unref(c);
792
793 return 0;
794
795 fail:
796
797 pa_context_unref(c);
798
799 return -1;
800 }
801
802 #endif /* OS_IS_WIN32 */
803
804 static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata);
805
806 #ifdef HAVE_DBUS
807 static void track_pulseaudio_on_dbus(pa_context *c, DBusBusType type, pa_dbus_wrap_connection **conn) {
808 DBusError error;
809
810 pa_assert(c);
811 pa_assert(conn);
812
813 dbus_error_init(&error);
814
815 if (!(*conn = pa_dbus_wrap_connection_new(c->mainloop, c->use_rtclock, type, &error)) || dbus_error_is_set(&error)) {
816 pa_log_warn("Unable to contact DBUS: %s: %s", error.name, error.message);
817 goto fail;
818 }
819
820 if (!dbus_connection_add_filter(pa_dbus_wrap_connection_get(*conn), filter_cb, c, NULL)) {
821 pa_log_warn("Failed to add filter function");
822 goto fail;
823 }
824 c->filter_added = true;
825
826 if (pa_dbus_add_matches(
827 pa_dbus_wrap_connection_get(*conn), &error,
828 "type='signal',sender='" DBUS_SERVICE_DBUS "',interface='" DBUS_INTERFACE_DBUS "',member='NameOwnerChanged',arg0='org.pulseaudio.Server',arg1=''", NULL) < 0) {
829
830 pa_log_warn("Unable to track org.pulseaudio.Server: %s: %s", error.name, error.message);
831 goto fail;
832 }
833
834 return;
835
836 fail:
837 if (*conn) {
838 pa_dbus_wrap_connection_free(*conn);
839 *conn = NULL;
840 }
841
842 dbus_error_free(&error);
843 }
844 #endif
845
846 static int try_next_connection(pa_context *c) {
847 char *u = NULL;
848 int r = -1;
849
850 pa_assert(c);
851 pa_assert(!c->client);
852
853 for (;;) {
854 pa_xfree(u);
855 u = NULL;
856
857 c->server_list = pa_strlist_pop(c->server_list, &u);
858
859 if (!u) {
860
861 #ifndef OS_IS_WIN32
862 if (c->do_autospawn) {
863
864 if ((r = context_autospawn(c)) < 0)
865 goto finish;
866
867 /* Autospawn only once */
868 c->do_autospawn = false;
869
870 /* Connect only to per-user sockets this time */
871 c->server_list = prepend_per_user(c->server_list);
872
873 /* Retry connection */
874 continue;
875 }
876 #endif
877
878 #ifdef HAVE_DBUS
879 if (c->no_fail && !c->server_specified) {
880 if (!c->session_bus)
881 track_pulseaudio_on_dbus(c, DBUS_BUS_SESSION, &c->session_bus);
882 if (!c->system_bus)
883 track_pulseaudio_on_dbus(c, DBUS_BUS_SYSTEM, &c->system_bus);
884
885 if (c->session_bus || c->system_bus) {
886 pa_log_debug("Waiting for PA on D-Bus...");
887 break;
888 }
889 } else
890 #endif
891 pa_log_error("Connection refused for try connect");
892 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
893
894 goto finish;
895 }
896
897 pa_log_debug("Trying to connect to %s...", u);
898
899 pa_xfree(c->server);
900 c->server = pa_xstrdup(u);
901
902 if (!(c->client = pa_socket_client_new_string(c->mainloop, c->use_rtclock, u, PA_NATIVE_DEFAULT_PORT)))
903 continue;
904
905 c->is_local = pa_socket_client_is_local(c->client);
906 pa_socket_client_set_callback(c->client, on_connection, c);
907 break;
908 }
909
910 r = 0;
911
912 finish:
913 pa_xfree(u);
914
915 return r;
916 }
917
918 static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata) {
919 pa_context *c = userdata;
920 int saved_errno = errno;
921
922 pa_assert(client);
923 pa_assert(c);
924 pa_assert(c->state == PA_CONTEXT_CONNECTING);
925
926 pa_context_ref(c);
927
928 pa_socket_client_unref(client);
929 c->client = NULL;
930
931 if (!io) {
932 /* Try the next item in the list */
933 if (saved_errno == ECONNREFUSED ||
934 saved_errno == ETIMEDOUT ||
935 saved_errno == EHOSTUNREACH) {
936 try_next_connection(c);
937 goto finish;
938 }
939
940 pa_log_error("Connection refused for io");
941 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
942 goto finish;
943 }
944
945 setup_context(c, io);
946
947 finish:
948 pa_context_unref(c);
949 }
950
951 #ifdef HAVE_DBUS
952 static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, void *userdata) {
953 pa_context *c = userdata;
954 bool is_session;
955
956 pa_assert(bus);
957 pa_assert(message);
958 pa_assert(c);
959
960 if (c->state != PA_CONTEXT_CONNECTING)
961 goto finish;
962
963 if (!c->no_fail)
964 goto finish;
965
966 /* FIXME: We probably should check if this is actually the NameOwnerChanged we were looking for */
967
968 is_session = c->session_bus && bus == pa_dbus_wrap_connection_get(c->session_bus);
969 pa_log_debug("Rock!! PulseAudio might be back on %s bus", is_session ? "session" : "system");
970
971 if (is_session)
972 /* The user instance via PF_LOCAL */
973 c->server_list = prepend_per_user(c->server_list);
974 else
975 /* The system wide instance via PF_LOCAL */
976 c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET);
977
978 if (!c->client)
979 try_next_connection(c);
980
981 finish:
982 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
983 }
984 #endif
985
986 int pa_context_connect(
987 pa_context *c,
988 const char *server,
989 pa_context_flags_t flags,
990 const pa_spawn_api *api) {
991
992 int r = -1;
993
994 pa_assert(c);
995 pa_assert(PA_REFCNT_VALUE(c) >= 1);
996
997 PA_CHECK_VALIDITY(c, !pa_detect_fork(), PA_ERR_FORKED);
998 PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_UNCONNECTED, PA_ERR_BADSTATE);
999 PA_CHECK_VALIDITY(c, !(flags & ~(PA_CONTEXT_NOAUTOSPAWN|PA_CONTEXT_NOFAIL)), PA_ERR_INVALID);
1000 PA_CHECK_VALIDITY(c, !server || *server, PA_ERR_INVALID);
1001
1002 if (server)
1003 c->conf->autospawn = false;
1004 else
1005 server = c->conf->default_server;
1006
1007 pa_context_ref(c);
1008
1009 c->no_fail = !!(flags & PA_CONTEXT_NOFAIL);
1010 c->server_specified = !!server;
1011 pa_assert(!c->server_list);
1012
1013 if (server) {
1014 if (!(c->server_list = pa_strlist_parse(server))) {
1015 pa_context_fail(c, PA_ERR_INVALIDSERVER);
1016 goto finish;
1017 }
1018
1019 } else {
1020 char *d;
1021
1022 /* Prepend in reverse order */
1023
1024 /* Follow the X display */
1025 if (c->conf->auto_connect_display) {
1026 if ((d = getenv("DISPLAY"))) {
1027 d = pa_xstrndup(d, strcspn(d, ":"));
1028
1029 if (*d)
1030 c->server_list = pa_strlist_prepend(c->server_list, d);
1031
1032 pa_xfree(d);
1033 }
1034 }
1035
1036 /* Add TCP/IP on the localhost */
1037 if (c->conf->auto_connect_localhost) {
1038 #if defined(HAVE_IPV6) && !defined(OS_IS_WIN32)
1039 /* FIXME: pa_socket_client does not support IPv6 on Windows */
1040 c->server_list = pa_strlist_prepend(c->server_list, "tcp6:[::1]");
1041 #endif
1042 c->server_list = pa_strlist_prepend(c->server_list, "tcp4:127.0.0.1");
1043 }
1044
1045 /* The system wide instance via PF_LOCAL */
1046 #ifndef OS_IS_WIN32
1047 c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET);
1048 #else
1049 /* see change_user in src/daemon/main.c */
1050 char *run_path = pa_sprintf_malloc("%s" PA_PATH_SEP "run" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, pa_win32_get_system_appdata());
1051 c->server_list = pa_strlist_prepend(c->server_list, run_path);
1052 pa_xfree(run_path);
1053 #endif
1054
1055 /* The user instance via PF_LOCAL */
1056 c->server_list = prepend_per_user(c->server_list);
1057 }
1058
1059 /* Set up autospawning */
1060 if (!(flags & PA_CONTEXT_NOAUTOSPAWN) && c->conf->autospawn) {
1061
1062 #ifdef HAVE_GETUID
1063 if (getuid() == 0)
1064 pa_log_debug("Not doing autospawn since we are root.");
1065 else {
1066 c->do_autospawn = true;
1067
1068 if (api)
1069 c->spawn_api = *api;
1070 }
1071 #endif
1072 }
1073
1074 pa_context_set_state(c, PA_CONTEXT_CONNECTING);
1075 r = try_next_connection(c);
1076
1077 finish:
1078 pa_context_unref(c);
1079
1080 return r;
1081 }
1082
1083 void pa_context_disconnect(pa_context *c) {
1084 pa_assert(c);
1085 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1086
1087 if (pa_detect_fork())
1088 return;
1089
1090 if (PA_CONTEXT_IS_GOOD(c->state))
1091 pa_context_set_state(c, PA_CONTEXT_TERMINATED);
1092 }
1093
1094 pa_context_state_t pa_context_get_state(const pa_context *c) {
1095 pa_assert(c);
1096 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1097
1098 return c->state;
1099 }
1100
1101 int pa_context_errno(const pa_context *c) {
1102
1103 if (!c)
1104 return PA_ERR_INVALID;
1105
1106 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1107
1108 return c->error->error;
1109 }
1110
1111 void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
1112 pa_assert(c);
1113 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1114
1115 if (pa_detect_fork())
1116 return;
1117
1118 if (c->state == PA_CONTEXT_TERMINATED || c->state == PA_CONTEXT_FAILED)
1119 return;
1120
1121 c->state_callback = cb;
1122 c->state_userdata = userdata;
1123 }
1124
1125 void pa_context_set_event_callback(pa_context *c, pa_context_event_cb_t cb, void *userdata) {
1126 pa_assert(c);
1127 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1128
1129 if (pa_detect_fork())
1130 return;
1131
1132 if (c->state == PA_CONTEXT_TERMINATED || c->state == PA_CONTEXT_FAILED)
1133 return;
1134
1135 c->event_callback = cb;
1136 c->event_userdata = userdata;
1137 }
1138
1139 int pa_context_is_pending(const pa_context *c) {
1140 pa_assert(c);
1141 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1142
1143 PA_CHECK_VALIDITY(c, !pa_detect_fork(), PA_ERR_FORKED);
1144 PA_CHECK_VALIDITY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE);
1145
1146 return (c->pstream && pa_pstream_is_pending(c->pstream)) ||
1147 (c->pdispatch && pa_pdispatch_is_pending(c->pdispatch)) ||
1148 c->client;
1149 }
1150
1151 static void set_dispatch_callbacks(pa_operation *o);
1152
1153 static void pdispatch_drain_callback(pa_pdispatch*pd, void *userdata) {
1154 set_dispatch_callbacks(userdata);
1155 }
1156
1157 static void pstream_drain_callback(pa_pstream *s, void *userdata) {
1158 set_dispatch_callbacks(userdata);
1159 }
1160
1161 static void set_dispatch_callbacks(pa_operation *o) {
1162 int done = 1;
1163
1164 pa_assert(o);
1165 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1166 pa_assert(o->context);
1167 pa_assert(PA_REFCNT_VALUE(o->context) >= 1);
1168 pa_assert(o->context->state == PA_CONTEXT_READY);
1169
1170 pa_pstream_set_drain_callback(o->context->pstream, NULL, NULL);
1171 pa_pdispatch_set_drain_callback(o->context->pdispatch, NULL, NULL);
1172
1173 if (pa_pdispatch_is_pending(o->context->pdispatch)) {
1174 pa_pdispatch_set_drain_callback(o->context->pdispatch, pdispatch_drain_callback, o);
1175 done = 0;
1176 }
1177
1178 if (pa_pstream_is_pending(o->context->pstream)) {
1179 pa_pstream_set_drain_callback(o->context->pstream, pstream_drain_callback, o);
1180 done = 0;
1181 }
1182
1183 if (done) {
1184 if (o->callback) {
1185 pa_context_notify_cb_t cb = (pa_context_notify_cb_t) o->callback;
1186 cb(o->context, o->userdata);
1187 }
1188
1189 pa_operation_done(o);
1190 pa_operation_unref(o);
1191 }
1192 }
1193
1194 pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
1195 pa_operation *o;
1196
1197 pa_assert(c);
1198 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1199
1200 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1201 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1202 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_context_is_pending(c), PA_ERR_BADSTATE);
1203
1204 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1205 set_dispatch_callbacks(pa_operation_ref(o));
1206
1207 return o;
1208 }
1209
1210 void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1211 pa_operation *o = userdata;
1212 int success = 1;
1213
1214 pa_assert(pd);
1215 pa_assert(o);
1216 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1217
1218 if (!o->context)
1219 goto finish;
1220
1221 if (command != PA_COMMAND_REPLY) {
1222 if (pa_context_handle_error(o->context, command, t, false) < 0)
1223 goto finish;
1224
1225 success = 0;
1226 } else if (!pa_tagstruct_eof(t)) {
1227 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1228 goto finish;
1229 }
1230
1231 if (o->callback) {
1232 pa_context_success_cb_t cb = (pa_context_success_cb_t) o->callback;
1233 cb(o->context, success, o->userdata);
1234 }
1235
1236 finish:
1237 pa_operation_done(o);
1238 pa_operation_unref(o);
1239 }
1240
1241 pa_operation* pa_context_send_simple_command(pa_context *c, uint32_t command, pa_pdispatch_cb_t internal_cb, pa_operation_cb_t cb, void *userdata) {
1242 pa_tagstruct *t;
1243 pa_operation *o;
1244 uint32_t tag;
1245
1246 pa_assert(c);
1247 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1248
1249 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1250 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1251
1252 o = pa_operation_new(c, NULL, cb, userdata);
1253
1254 t = pa_tagstruct_command(c, command, &tag);
1255 pa_pstream_send_tagstruct(c->pstream, t);
1256 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, internal_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1257
1258 return o;
1259 }
1260
1261 pa_operation* pa_context_exit_daemon(pa_context *c, pa_context_success_cb_t cb, void *userdata) {
1262 pa_assert(c);
1263 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1264
1265 return pa_context_send_simple_command(c, PA_COMMAND_EXIT, pa_context_simple_ack_callback, (pa_operation_cb_t) cb, userdata);
1266 }
1267
1268 pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1269 pa_tagstruct *t;
1270 pa_operation *o;
1271 uint32_t tag;
1272
1273 pa_assert(c);
1274 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1275
1276 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1277 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1278
1279 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1280 t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SINK, &tag);
1281 pa_tagstruct_puts(t, name);
1282 pa_pstream_send_tagstruct(c->pstream, t);
1283 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1284
1285 return o;
1286 }
1287
1288 pa_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1289 pa_tagstruct *t;
1290 pa_operation *o;
1291 uint32_t tag;
1292
1293 pa_assert(c);
1294 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1295
1296 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1297 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1298
1299 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1300 t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SOURCE, &tag);
1301 pa_tagstruct_puts(t, name);
1302 pa_pstream_send_tagstruct(c->pstream, t);
1303 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1304
1305 return o;
1306 }
1307
1308 int pa_context_is_local(const pa_context *c) {
1309 pa_assert(c);
1310 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1311
1312 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, -1);
1313 PA_CHECK_VALIDITY_RETURN_ANY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE, -1);
1314
1315 return c->is_local;
1316 }
1317
1318 pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1319 pa_operation *o;
1320
1321 pa_assert(c);
1322 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1323 pa_assert(name);
1324
1325 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1326 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1327
1328 if (c->version >= 13) {
1329 pa_proplist *p = pa_proplist_new();
1330
1331 pa_proplist_sets(p, PA_PROP_APPLICATION_NAME, name);
1332 o = pa_context_proplist_update(c, PA_UPDATE_REPLACE, p, cb, userdata);
1333 pa_proplist_free(p);
1334 } else {
1335 pa_tagstruct *t;
1336 uint32_t tag;
1337
1338 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1339 t = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
1340 pa_tagstruct_puts(t, name);
1341 pa_pstream_send_tagstruct(c->pstream, t);
1342 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1343 }
1344
1345 return o;
1346 }
1347
1348 const char* pa_get_library_version(void) {
1349 return pa_get_headers_version();
1350 }
1351
1352 const char* pa_context_get_server(const pa_context *c) {
1353 pa_assert(c);
1354 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1355
1356 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1357 PA_CHECK_VALIDITY_RETURN_NULL(c, c->server, PA_ERR_NOENTITY);
1358
1359 if (*c->server == '{') {
1360 char *e = strchr(c->server+1, '}');
1361 return e ? e+1 : c->server;
1362 }
1363
1364 return c->server;
1365 }
1366
1367 uint32_t pa_context_get_protocol_version(const pa_context *c) {
1368 return PA_PROTOCOL_VERSION;
1369 }
1370
1371 uint32_t pa_context_get_server_protocol_version(const pa_context *c) {
1372 pa_assert(c);
1373 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1374
1375 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, PA_INVALID_INDEX);
1376 PA_CHECK_VALIDITY_RETURN_ANY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE, PA_INVALID_INDEX);
1377
1378 return c->version;
1379 }
1380
1381 pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *tag) {
1382 pa_tagstruct *t;
1383
1384 pa_assert(c);
1385 pa_assert(tag);
1386
1387 t = pa_tagstruct_new();
1388 pa_tagstruct_putu32(t, command);
1389 pa_tagstruct_putu32(t, *tag = c->ctag++);
1390
1391 return t;
1392 }
1393
1394 uint32_t pa_context_get_index(const pa_context *c) {
1395 pa_assert(c);
1396 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1397
1398 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, PA_INVALID_INDEX);
1399 PA_CHECK_VALIDITY_RETURN_ANY(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE, PA_INVALID_INDEX);
1400 PA_CHECK_VALIDITY_RETURN_ANY(c, c->version >= 13, PA_ERR_NOTSUPPORTED, PA_INVALID_INDEX);
1401
1402 return c->client_index;
1403 }
1404
1405 pa_operation *pa_context_proplist_update(pa_context *c, pa_update_mode_t mode, const pa_proplist *p, pa_context_success_cb_t cb, void *userdata) {
1406 pa_operation *o;
1407 pa_tagstruct *t;
1408 uint32_t tag;
1409
1410 pa_assert(c);
1411 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1412
1413 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1414 PA_CHECK_VALIDITY_RETURN_NULL(c, mode == PA_UPDATE_SET || mode == PA_UPDATE_MERGE || mode == PA_UPDATE_REPLACE, PA_ERR_INVALID);
1415 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1416 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 13, PA_ERR_NOTSUPPORTED);
1417
1418 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1419
1420 t = pa_tagstruct_command(c, PA_COMMAND_UPDATE_CLIENT_PROPLIST, &tag);
1421 pa_tagstruct_putu32(t, (uint32_t) mode);
1422 pa_tagstruct_put_proplist(t, p);
1423
1424 pa_pstream_send_tagstruct(c->pstream, t);
1425 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1426
1427 /* Please note that we don't update c->proplist here, because we
1428 * don't export that field */
1429
1430 return o;
1431 }
1432
1433 pa_operation *pa_context_proplist_remove(pa_context *c, const char *const keys[], pa_context_success_cb_t cb, void *userdata) {
1434 pa_operation *o;
1435 pa_tagstruct *t;
1436 uint32_t tag;
1437 const char * const *k;
1438
1439 pa_assert(c);
1440 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1441
1442 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1443 PA_CHECK_VALIDITY_RETURN_NULL(c, keys && keys[0], PA_ERR_INVALID);
1444 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1445 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 13, PA_ERR_NOTSUPPORTED);
1446
1447 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1448
1449 t = pa_tagstruct_command(c, PA_COMMAND_REMOVE_CLIENT_PROPLIST, &tag);
1450
1451 for (k = keys; *k; k++)
1452 pa_tagstruct_puts(t, *k);
1453
1454 pa_tagstruct_puts(t, NULL);
1455
1456 pa_pstream_send_tagstruct(c->pstream, t);
1457 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1458
1459 /* Please note that we don't update c->proplist here, because we
1460 * don't export that field */
1461
1462 return o;
1463 }
1464
1465 void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1466 pa_context *c = userdata;
1467 uint32_t idx;
1468 const char *name;
1469
1470 pa_assert(pd);
1471 pa_assert(command == PA_COMMAND_EXTENSION);
1472 pa_assert(t);
1473 pa_assert(c);
1474 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1475
1476 pa_context_ref(c);
1477
1478 if (c->version < 15) {
1479 pa_context_fail(c, PA_ERR_PROTOCOL);
1480 goto finish;
1481 }
1482
1483 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1484 pa_tagstruct_gets(t, &name) < 0) {
1485 pa_context_fail(c, PA_ERR_PROTOCOL);
1486 goto finish;
1487 }
1488
1489 if (pa_streq(name, "module-device-manager"))
1490 pa_ext_device_manager_command(c, tag, t);
1491 else if (pa_streq(name, "module-device-restore"))
1492 pa_ext_device_restore_command(c, tag, t);
1493 else if (pa_streq(name, "module-stream-restore"))
1494 pa_ext_stream_restore_command(c, tag, t);
1495 else
1496 pa_log(_("Received message for unknown extension '%s'"), name);
1497
1498 finish:
1499 pa_context_unref(c);
1500 }
1501
1502 static void pa_command_enable_srbchannel(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1503 pa_context *c = userdata;
1504
1505 #ifdef HAVE_CREDS
1506 pa_cmsg_ancil_data *ancil = NULL;
1507
1508 pa_assert(pd);
1509 pa_assert(command == PA_COMMAND_ENABLE_SRBCHANNEL);
1510 pa_assert(t);
1511 pa_assert(c);
1512 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1513
1514 ancil = pa_pdispatch_take_ancil_data(pd);
1515 if (!ancil)
1516 goto fail;
1517
1518 /* Currently only one srb channel is supported, might change in future versions */
1519 if (c->srb_template.readfd != -1)
1520 goto fail;
1521
1522 if (ancil->nfd != 2 || ancil->fds[0] == -1 || ancil->fds[1] == -1)
1523 goto fail;
1524
1525 pa_context_ref(c);
1526
1527 c->srb_template.readfd = ancil->fds[0];
1528 c->srb_template.writefd = ancil->fds[1];
1529 c->srb_setup_tag = tag;
1530
1531 pa_context_unref(c);
1532
1533 ancil->close_fds_on_cleanup = false;
1534 return;
1535
1536 fail:
1537 if (ancil)
1538 pa_cmsg_ancil_data_close_fds(ancil);
1539
1540 pa_context_fail(c, PA_ERR_PROTOCOL);
1541 return;
1542 #else
1543 pa_assert(c);
1544 pa_context_fail(c, PA_ERR_PROTOCOL);
1545 #endif
1546 }
1547
1548 static void pa_command_disable_srbchannel(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1549 pa_context *c = userdata;
1550 pa_tagstruct *t2;
1551
1552 pa_assert(pd);
1553 pa_assert(command == PA_COMMAND_DISABLE_SRBCHANNEL);
1554 pa_assert(t);
1555 pa_assert(c);
1556 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1557
1558 pa_pstream_set_srbchannel(c->pstream, NULL);
1559
1560 c->srb_template.readfd = -1;
1561 c->srb_template.writefd = -1;
1562 if (c->srb_template.memblock) {
1563 pa_memblock_unref(c->srb_template.memblock);
1564 c->srb_template.memblock = NULL;
1565 }
1566
1567 /* Send disable command back again */
1568 t2 = pa_tagstruct_new();
1569 pa_tagstruct_putu32(t2, PA_COMMAND_DISABLE_SRBCHANNEL);
1570 pa_tagstruct_putu32(t2, tag);
1571 pa_pstream_send_tagstruct(c->pstream, t2);
1572 }
1573
1574 static void pa_command_register_memfd_shmid(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1575 pa_context *c = userdata;
1576
1577 pa_assert(pd);
1578 pa_assert(command == PA_COMMAND_REGISTER_MEMFD_SHMID);
1579 pa_assert(t);
1580 pa_assert(c);
1581 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1582
1583 if (pa_common_command_register_memfd_shmid(c->pstream, pd, c->version, command, t))
1584 pa_context_fail(c, PA_ERR_PROTOCOL);
1585 }
1586
1587 void pa_command_client_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1588 pa_context *c = userdata;
1589 pa_proplist *pl = NULL;
1590 const char *event;
1591
1592 pa_assert(pd);
1593 pa_assert(command == PA_COMMAND_CLIENT_EVENT);
1594 pa_assert(t);
1595 pa_assert(c);
1596 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1597
1598 pa_context_ref(c);
1599
1600 if (c->version < 15) {
1601 pa_context_fail(c, PA_ERR_PROTOCOL);
1602 goto finish;
1603 }
1604
1605 pl = pa_proplist_new();
1606
1607 if (pa_tagstruct_gets(t, &event) < 0 ||
1608 pa_tagstruct_get_proplist(t, pl) < 0 ||
1609 !pa_tagstruct_eof(t) || !event) {
1610 pa_context_fail(c, PA_ERR_PROTOCOL);
1611 goto finish;
1612 }
1613
1614 if (c->event_callback)
1615 c->event_callback(c, event, pl, c->event_userdata);
1616
1617 finish:
1618 pa_context_unref(c);
1619
1620 if (pl)
1621 pa_proplist_free(pl);
1622 }
1623
1624 pa_time_event* pa_context_rttime_new(const pa_context *c, pa_usec_t usec, pa_time_event_cb_t cb, void *userdata) {
1625 struct timeval tv;
1626
1627 pa_assert(c);
1628 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1629 pa_assert(c->mainloop);
1630
1631 if (usec == PA_USEC_INVALID)
1632 return c->mainloop->time_new(c->mainloop, NULL, cb, userdata);
1633
1634 pa_timeval_rtstore(&tv, usec, c->use_rtclock);
1635
1636 return c->mainloop->time_new(c->mainloop, &tv, cb, userdata);
1637 }
1638
1639 void pa_context_rttime_restart(const pa_context *c, pa_time_event *e, pa_usec_t usec) {
1640 struct timeval tv;
1641
1642 pa_assert(c);
1643 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1644 pa_assert(c->mainloop);
1645
1646 if (usec == PA_USEC_INVALID)
1647 c->mainloop->time_restart(e, NULL);
1648 else {
1649 pa_timeval_rtstore(&tv, usec, c->use_rtclock);
1650 c->mainloop->time_restart(e, &tv);
1651 }
1652 }
1653
1654 size_t pa_context_get_tile_size(const pa_context *c, const pa_sample_spec *ss) {
1655 size_t fs, mbs;
1656
1657 pa_assert(c);
1658 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1659
1660 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, (size_t) -1);
1661 PA_CHECK_VALIDITY_RETURN_ANY(c, !ss || pa_sample_spec_valid(ss), PA_ERR_INVALID, (size_t) -1);
1662
1663 fs = ss ? pa_frame_size(ss) : 1;
1664 mbs = PA_ROUND_DOWN(pa_mempool_block_size_max(c->mempool), fs);
1665 return PA_MAX(mbs, fs);
1666 }
1667
1668 int pa_context_load_cookie_from_file(pa_context *c, const char *cookie_file_path) {
1669 pa_assert(c);
1670 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1671
1672 PA_CHECK_VALIDITY(c, !pa_detect_fork(), PA_ERR_FORKED);
1673 PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_UNCONNECTED, PA_ERR_BADSTATE);
1674 PA_CHECK_VALIDITY(c, !cookie_file_path || *cookie_file_path, PA_ERR_INVALID);
1675
1676 pa_client_conf_set_cookie_file_from_application(c->conf, cookie_file_path);
1677
1678 return 0;
1679 }
1680