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