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