pulse: client connect to dbus
[pulseaudio-raopUDP/pulseaudio-raop-alac.git] / src / pulse / context.c
bloba18a6423c92ec20164555849c2a83063202a590f
1 /***
2 This file is part of PulseAudio.
4 Copyright 2004-2008 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
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.
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.
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 USA.
21 ***/
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <sys/types.h>
31 #include <unistd.h>
32 #include <sys/stat.h>
33 #include <errno.h>
34 #include <signal.h>
35 #include <limits.h>
36 #include <locale.h>
38 #ifdef HAVE_SYS_WAIT_H
39 #include <sys/wait.h>
40 #endif
42 #ifdef HAVE_SYS_SOCKET_H
43 #include <sys/socket.h>
44 #endif
45 #ifdef HAVE_SYS_UN_H
46 #include <sys/un.h>
47 #endif
48 #ifdef HAVE_NETDB_H
49 #include <netdb.h>
50 #endif
52 #include <pulse/version.h>
53 #include <pulse/xmalloc.h>
54 #include <pulse/utf8.h>
55 #include <pulse/util.h>
56 #include <pulse/i18n.h>
58 #include <pulsecore/winsock.h>
59 #include <pulsecore/core-error.h>
61 #include <pulsecore/native-common.h>
62 #include <pulsecore/pdispatch.h>
63 #include <pulsecore/pstream.h>
64 #include <pulsecore/dynarray.h>
65 #include <pulsecore/socket-client.h>
66 #include <pulsecore/pstream-util.h>
67 #include <pulsecore/core-util.h>
68 #include <pulsecore/log.h>
69 #include <pulsecore/socket-util.h>
70 #include <pulsecore/creds.h>
71 #include <pulsecore/macro.h>
72 #include <pulsecore/proplist-util.h>
74 #include "internal.h"
76 #include "client-conf.h"
77 #include "fork-detect.h"
79 #ifdef HAVE_X11
80 #include "client-conf-x11.h"
81 #endif
83 #include "context.h"
85 void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
87 static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
88 [PA_COMMAND_REQUEST] = pa_command_request,
89 [PA_COMMAND_OVERFLOW] = pa_command_overflow_or_underflow,
90 [PA_COMMAND_UNDERFLOW] = pa_command_overflow_or_underflow,
91 [PA_COMMAND_PLAYBACK_STREAM_KILLED] = pa_command_stream_killed,
92 [PA_COMMAND_RECORD_STREAM_KILLED] = pa_command_stream_killed,
93 [PA_COMMAND_PLAYBACK_STREAM_MOVED] = pa_command_stream_moved,
94 [PA_COMMAND_RECORD_STREAM_MOVED] = pa_command_stream_moved,
95 [PA_COMMAND_PLAYBACK_STREAM_SUSPENDED] = pa_command_stream_suspended,
96 [PA_COMMAND_RECORD_STREAM_SUSPENDED] = pa_command_stream_suspended,
97 [PA_COMMAND_STARTED] = pa_command_stream_started,
98 [PA_COMMAND_SUBSCRIBE_EVENT] = pa_command_subscribe_event,
99 [PA_COMMAND_EXTENSION] = pa_command_extension,
100 [PA_COMMAND_PLAYBACK_STREAM_EVENT] = pa_command_stream_event,
101 [PA_COMMAND_RECORD_STREAM_EVENT] = pa_command_stream_event,
102 [PA_COMMAND_CLIENT_EVENT] = pa_command_client_event
104 static void context_free(pa_context *c);
105 static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, void *userdata);
107 pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) {
108 return pa_context_new_with_proplist(mainloop, name, NULL);
111 static void reset_callbacks(pa_context *c) {
112 pa_assert(c);
114 c->state_callback = NULL;
115 c->state_userdata = NULL;
117 c->subscribe_callback = NULL;
118 c->subscribe_userdata = NULL;
120 c->event_callback = NULL;
121 c->event_userdata = NULL;
123 c->ext_stream_restore.callback = NULL;
124 c->ext_stream_restore.userdata = NULL;
127 pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, pa_proplist *p) {
128 pa_context *c;
130 pa_assert(mainloop);
132 if (pa_detect_fork())
133 return NULL;
135 pa_init_i18n();
137 c = pa_xnew(pa_context, 1);
138 PA_REFCNT_INIT(c);
140 c->proplist = p ? pa_proplist_copy(p) : pa_proplist_new();
142 if (name)
143 pa_proplist_sets(c->proplist, PA_PROP_APPLICATION_NAME, name);
145 c->no_fail = FALSE;
146 c->system_bus = c->session_bus = NULL;
147 c->mainloop = mainloop;
148 c->client = NULL;
149 c->pstream = NULL;
150 c->pdispatch = NULL;
151 c->playback_streams = pa_dynarray_new();
152 c->record_streams = pa_dynarray_new();
153 c->client_index = PA_INVALID_INDEX;
155 PA_LLIST_HEAD_INIT(pa_stream, c->streams);
156 PA_LLIST_HEAD_INIT(pa_operation, c->operations);
158 c->error = PA_OK;
159 c->state = PA_CONTEXT_UNCONNECTED;
160 c->ctag = 0;
161 c->csyncid = 0;
163 reset_callbacks(c);
165 c->is_local = FALSE;
166 c->server_list = NULL;
167 c->server = NULL;
169 c->do_shm = FALSE;
171 c->do_autospawn = FALSE;
172 memset(&c->spawn_api, 0, sizeof(c->spawn_api));
174 #ifndef MSG_NOSIGNAL
175 #ifdef SIGPIPE
176 pa_check_signal_is_blocked(SIGPIPE);
177 #endif
178 #endif
180 c->conf = pa_client_conf_new();
181 #ifdef HAVE_X11
182 pa_client_conf_from_x11(c->conf, NULL);
183 #endif
184 pa_client_conf_load(c->conf, NULL);
185 pa_client_conf_env(c->conf);
187 if (!(c->mempool = pa_mempool_new(!c->conf->disable_shm, c->conf->shm_size))) {
189 if (!c->conf->disable_shm)
190 c->mempool = pa_mempool_new(FALSE, c->conf->shm_size);
192 if (!c->mempool) {
193 context_free(c);
194 return NULL;
198 return c;
201 static void context_unlink(pa_context *c) {
202 pa_stream *s;
204 pa_assert(c);
206 s = c->streams ? pa_stream_ref(c->streams) : NULL;
207 while (s) {
208 pa_stream *n = s->next ? pa_stream_ref(s->next) : NULL;
209 pa_stream_set_state(s, c->state == PA_CONTEXT_FAILED ? PA_STREAM_FAILED : PA_STREAM_TERMINATED);
210 pa_stream_unref(s);
211 s = n;
214 while (c->operations)
215 pa_operation_cancel(c->operations);
217 if (c->pdispatch) {
218 pa_pdispatch_unref(c->pdispatch);
219 c->pdispatch = NULL;
222 if (c->pstream) {
223 pa_pstream_unlink(c->pstream);
224 pa_pstream_unref(c->pstream);
225 c->pstream = NULL;
228 if (c->client) {
229 pa_socket_client_unref(c->client);
230 c->client = NULL;
233 reset_callbacks(c);
236 static void context_free(pa_context *c) {
237 pa_assert(c);
239 context_unlink(c);
241 if (c->system_bus) {
242 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c->system_bus), filter_cb, c);
243 pa_dbus_wrap_connection_free(c->system_bus);
246 if (c->session_bus) {
247 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c->session_bus), filter_cb, c);
248 pa_dbus_wrap_connection_free(c->session_bus);
251 if (c->record_streams)
252 pa_dynarray_free(c->record_streams, NULL, NULL);
253 if (c->playback_streams)
254 pa_dynarray_free(c->playback_streams, NULL, NULL);
256 if (c->mempool)
257 pa_mempool_free(c->mempool);
259 if (c->conf)
260 pa_client_conf_free(c->conf);
262 pa_strlist_free(c->server_list);
264 if (c->proplist)
265 pa_proplist_free(c->proplist);
267 pa_xfree(c->server);
268 pa_xfree(c);
271 pa_context* pa_context_ref(pa_context *c) {
272 pa_assert(c);
273 pa_assert(PA_REFCNT_VALUE(c) >= 1);
275 PA_REFCNT_INC(c);
276 return c;
279 void pa_context_unref(pa_context *c) {
280 pa_assert(c);
281 pa_assert(PA_REFCNT_VALUE(c) >= 1);
283 if (PA_REFCNT_DEC(c) <= 0)
284 context_free(c);
287 void pa_context_set_state(pa_context *c, pa_context_state_t st) {
288 pa_assert(c);
289 pa_assert(PA_REFCNT_VALUE(c) >= 1);
291 if (c->state == st)
292 return;
294 pa_context_ref(c);
296 c->state = st;
298 if (c->state_callback)
299 c->state_callback(c, c->state_userdata);
301 if (st == PA_CONTEXT_FAILED || st == PA_CONTEXT_TERMINATED)
302 context_unlink(c);
304 pa_context_unref(c);
307 int pa_context_set_error(pa_context *c, int error) {
308 pa_assert(error >= 0);
309 pa_assert(error < PA_ERR_MAX);
311 if (c)
312 c->error = error;
314 return error;
317 void pa_context_fail(pa_context *c, int error) {
318 pa_assert(c);
319 pa_assert(PA_REFCNT_VALUE(c) >= 1);
321 pa_context_set_error(c, error);
322 pa_context_set_state(c, PA_CONTEXT_FAILED);
325 static void pstream_die_callback(pa_pstream *p, void *userdata) {
326 pa_context *c = userdata;
328 pa_assert(p);
329 pa_assert(c);
331 pa_context_fail(c, PA_ERR_CONNECTIONTERMINATED);
334 static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata) {
335 pa_context *c = userdata;
337 pa_assert(p);
338 pa_assert(packet);
339 pa_assert(c);
341 pa_context_ref(c);
343 if (pa_pdispatch_run(c->pdispatch, packet, creds, c) < 0)
344 pa_context_fail(c, PA_ERR_PROTOCOL);
346 pa_context_unref(c);
349 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) {
350 pa_context *c = userdata;
351 pa_stream *s;
353 pa_assert(p);
354 pa_assert(chunk);
355 pa_assert(chunk->length > 0);
356 pa_assert(c);
357 pa_assert(PA_REFCNT_VALUE(c) >= 1);
359 pa_context_ref(c);
361 if ((s = pa_dynarray_get(c->record_streams, channel))) {
363 if (chunk->memblock) {
364 pa_memblockq_seek(s->record_memblockq, offset, seek);
365 pa_memblockq_push_align(s->record_memblockq, chunk);
366 } else
367 pa_memblockq_seek(s->record_memblockq, offset+chunk->length, seek);
369 if (s->read_callback) {
370 size_t l;
372 if ((l = pa_memblockq_get_length(s->record_memblockq)) > 0)
373 s->read_callback(s, l, s->read_userdata);
377 pa_context_unref(c);
380 int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t, pa_bool_t fail) {
381 uint32_t err;
382 pa_assert(c);
383 pa_assert(PA_REFCNT_VALUE(c) >= 1);
385 if (command == PA_COMMAND_ERROR) {
386 pa_assert(t);
388 if (pa_tagstruct_getu32(t, &err) < 0 ||
389 !pa_tagstruct_eof(t)) {
390 pa_context_fail(c, PA_ERR_PROTOCOL);
391 return -1;
394 } else if (command == PA_COMMAND_TIMEOUT)
395 err = PA_ERR_TIMEOUT;
396 else {
397 pa_context_fail(c, PA_ERR_PROTOCOL);
398 return -1;
401 if (err == PA_OK) {
402 pa_context_fail(c, PA_ERR_PROTOCOL);
403 return -1;
406 if (err >= PA_ERR_MAX)
407 err = PA_ERR_UNKNOWN;
409 if (fail) {
410 pa_context_fail(c, (int) err);
411 return -1;
414 pa_context_set_error(c, (int) err);
416 return 0;
419 static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
420 pa_context *c = userdata;
422 pa_assert(pd);
423 pa_assert(c);
424 pa_assert(c->state == PA_CONTEXT_AUTHORIZING || c->state == PA_CONTEXT_SETTING_NAME);
426 pa_context_ref(c);
428 if (command != PA_COMMAND_REPLY) {
429 pa_context_handle_error(c, command, t, TRUE);
430 goto finish;
433 switch(c->state) {
434 case PA_CONTEXT_AUTHORIZING: {
435 pa_tagstruct *reply;
436 pa_bool_t shm_on_remote = FALSE;
438 if (pa_tagstruct_getu32(t, &c->version) < 0 ||
439 !pa_tagstruct_eof(t)) {
440 pa_context_fail(c, PA_ERR_PROTOCOL);
441 goto finish;
444 /* Minimum supported version */
445 if (c->version < 8) {
446 pa_context_fail(c, PA_ERR_VERSION);
447 goto finish;
450 /* Starting with protocol version 13 the MSB of the version
451 tag reflects if shm is available for this connection or
452 not. */
453 if (c->version >= 13) {
454 shm_on_remote = !!(c->version & 0x80000000U);
455 c->version &= 0x7FFFFFFFU;
458 pa_log_debug("Protocol version: remote %u, local %u", c->version, PA_PROTOCOL_VERSION);
460 /* Enable shared memory support if possible */
461 if (c->do_shm)
462 if (c->version < 10 || (c->version >= 13 && !shm_on_remote))
463 c->do_shm = FALSE;
465 if (c->do_shm) {
467 /* Only enable SHM if both sides are owned by the same
468 * user. This is a security measure because otherwise
469 * data private to the user might leak. */
471 #ifdef HAVE_CREDS
472 const pa_creds *creds;
473 if (!(creds = pa_pdispatch_creds(pd)) || getuid() != creds->uid)
474 c->do_shm = FALSE;
475 #endif
478 pa_log_debug("Negotiated SHM: %s", pa_yes_no(c->do_shm));
479 pa_pstream_enable_shm(c->pstream, c->do_shm);
481 reply = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
483 if (c->version >= 13) {
484 pa_init_proplist(c->proplist);
485 pa_tagstruct_put_proplist(reply, c->proplist);
486 } else
487 pa_tagstruct_puts(reply, pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME));
489 pa_pstream_send_tagstruct(c->pstream, reply);
490 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
492 pa_context_set_state(c, PA_CONTEXT_SETTING_NAME);
493 break;
496 case PA_CONTEXT_SETTING_NAME :
498 if ((c->version >= 13 && (pa_tagstruct_getu32(t, &c->client_index) < 0 ||
499 c->client_index == PA_INVALID_INDEX)) ||
500 !pa_tagstruct_eof(t)) {
501 pa_context_fail(c, PA_ERR_PROTOCOL);
502 goto finish;
505 pa_context_set_state(c, PA_CONTEXT_READY);
506 break;
508 default:
509 pa_assert_not_reached();
512 finish:
513 pa_context_unref(c);
516 static void setup_context(pa_context *c, pa_iochannel *io) {
517 pa_tagstruct *t;
518 uint32_t tag;
520 pa_assert(c);
521 pa_assert(io);
523 pa_context_ref(c);
525 pa_assert(!c->pstream);
526 c->pstream = pa_pstream_new(c->mainloop, io, c->mempool);
528 pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c);
529 pa_pstream_set_recieve_packet_callback(c->pstream, pstream_packet_callback, c);
530 pa_pstream_set_recieve_memblock_callback(c->pstream, pstream_memblock_callback, c);
532 pa_assert(!c->pdispatch);
533 c->pdispatch = pa_pdispatch_new(c->mainloop, command_table, PA_COMMAND_MAX);
535 if (!c->conf->cookie_valid)
536 pa_log_info(_("No cookie loaded. Attempting to connect without."));
538 t = pa_tagstruct_command(c, PA_COMMAND_AUTH, &tag);
540 c->do_shm =
541 pa_mempool_is_shared(c->mempool) &&
542 c->is_local;
544 pa_log_debug("SHM possible: %s", pa_yes_no(c->do_shm));
546 /* Starting with protocol version 13 we use the MSB of the version
547 * tag for informing the other side if we could do SHM or not */
548 pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION | (c->do_shm ? 0x80000000U : 0));
549 pa_tagstruct_put_arbitrary(t, c->conf->cookie, sizeof(c->conf->cookie));
551 #ifdef HAVE_CREDS
553 pa_creds ucred;
555 if (pa_iochannel_creds_supported(io))
556 pa_iochannel_creds_enable(io);
558 ucred.uid = getuid();
559 ucred.gid = getgid();
561 pa_pstream_send_tagstruct_with_creds(c->pstream, t, &ucred);
563 #else
564 pa_pstream_send_tagstruct(c->pstream, t);
565 #endif
567 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
569 pa_context_set_state(c, PA_CONTEXT_AUTHORIZING);
571 pa_context_unref(c);
574 #ifdef ENABLE_LEGACY_RUNTIME_DIR
575 static char *get_old_legacy_runtime_dir(void) {
576 char *p, u[128];
577 struct stat st;
579 if (!pa_get_user_name(u, sizeof(u)))
580 return NULL;
582 p = pa_sprintf_malloc("/tmp/pulse-%s", u);
584 if (stat(p, &st) < 0) {
585 pa_xfree(p);
586 return NULL;
589 if (st.st_uid != getuid()) {
590 pa_xfree(p);
591 return NULL;
594 return p;
597 static char *get_very_old_legacy_runtime_dir(void) {
598 char *p, h[128];
599 struct stat st;
601 if (!pa_get_home_dir(h, sizeof(h)))
602 return NULL;
604 p = pa_sprintf_malloc("%s/.pulse", h);
606 if (stat(p, &st) < 0) {
607 pa_xfree(p);
608 return NULL;
611 if (st.st_uid != getuid()) {
612 pa_xfree(p);
613 return NULL;
616 return p;
618 #endif
620 static pa_strlist *prepend_per_user(pa_strlist *l) {
621 char *ufn;
623 #ifdef ENABLE_LEGACY_RUNTIME_DIR
624 static char *legacy_dir;
626 /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
627 if ((legacy_dir = get_very_old_legacy_runtime_dir())) {
628 char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
629 l = pa_strlist_prepend(l, p);
630 pa_xfree(p);
631 pa_xfree(legacy_dir);
634 /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
635 if ((legacy_dir = get_old_legacy_runtime_dir())) {
636 char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
637 l = pa_strlist_prepend(l, p);
638 pa_xfree(p);
639 pa_xfree(legacy_dir);
641 #endif
643 /* The per-user instance */
644 if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
645 l = pa_strlist_prepend(l, ufn);
646 pa_xfree(ufn);
649 return l;
652 #ifndef OS_IS_WIN32
654 static int context_autospawn(pa_context *c) {
655 pid_t pid;
656 int status, r;
658 pa_log_debug("Trying to autospawn...");
660 pa_context_ref(c);
662 if (c->spawn_api.prefork)
663 c->spawn_api.prefork();
665 if ((pid = fork()) < 0) {
666 pa_log_error(_("fork(): %s"), pa_cstrerror(errno));
667 pa_context_fail(c, PA_ERR_INTERNAL);
669 if (c->spawn_api.postfork)
670 c->spawn_api.postfork();
672 goto fail;
673 } else if (!pid) {
674 /* Child */
676 const char *state = NULL;
677 #define MAX_ARGS 64
678 const char * argv[MAX_ARGS+1];
679 int n;
681 if (c->spawn_api.atfork)
682 c->spawn_api.atfork();
684 pa_close_all(-1);
686 /* Setup argv */
688 n = 0;
690 argv[n++] = c->conf->daemon_binary;
691 argv[n++] = "--start";
693 while (n < MAX_ARGS) {
694 char *a;
696 if (!(a = pa_split_spaces(c->conf->extra_arguments, &state)))
697 break;
699 argv[n++] = a;
702 argv[n++] = NULL;
704 execv(argv[0], (char * const *) argv);
705 _exit(1);
706 #undef MAX_ARGS
709 /* Parent */
711 if (c->spawn_api.postfork)
712 c->spawn_api.postfork();
714 do {
715 r = waitpid(pid, &status, 0);
716 } while (r < 0 && errno == EINTR);
718 if (r < 0) {
719 pa_log(_("waitpid(): %s"), pa_cstrerror(errno));
720 pa_context_fail(c, PA_ERR_INTERNAL);
721 goto fail;
722 } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
723 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
724 goto fail;
727 pa_context_unref(c);
729 return 0;
731 fail:
733 pa_context_unref(c);
735 return -1;
738 #endif /* OS_IS_WIN32 */
740 static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata);
742 static void track_pulseaudio_on_dbus(pa_context *c, DBusBusType type, pa_dbus_wrap_connection **conn) {
743 DBusError error;
745 pa_assert(c);
746 pa_assert(conn);
748 dbus_error_init(&error);
749 if (!(*conn = pa_dbus_wrap_connection_new(c->mainloop, type, &error)) || dbus_error_is_set(&error)) {
750 pa_log_warn("Unable to contact DBUS: %s: %s", error.name, error.message);
751 goto finish;
754 if (!dbus_connection_add_filter(pa_dbus_wrap_connection_get(*conn), filter_cb, c, NULL)) {
755 pa_log_warn("Failed to add filter function");
756 goto finish;
759 if (pa_dbus_add_matches(
760 pa_dbus_wrap_connection_get(*conn), &error,
761 "type='signal',sender='" DBUS_SERVICE_DBUS "',interface='" DBUS_INTERFACE_DBUS "',member='NameOwnerChanged',arg0='org.pulseaudio',arg1=''", NULL) < 0)
762 pa_log_warn("Unable to track org.pulseaudio: %s: %s", error.name, error.message);
764 finish:
765 dbus_error_free(&error);
768 static int try_next_connection(pa_context *c) {
769 char *u = NULL;
770 int r = -1;
772 pa_assert(c);
773 pa_assert(!c->client);
775 for (;;) {
776 pa_xfree(u);
777 u = NULL;
779 c->server_list = pa_strlist_pop(c->server_list, &u);
781 if (!u) {
783 #ifndef OS_IS_WIN32
784 if (c->do_autospawn) {
786 if ((r = context_autospawn(c)) < 0)
787 goto finish;
789 /* Autospawn only once */
790 c->do_autospawn = FALSE;
792 /* Connect only to per-user sockets this time */
793 c->server_list = prepend_per_user(c->server_list);
795 /* Retry connection */
796 continue;
798 #endif
800 if (c->no_fail) {
801 if (!c->system_bus)
802 track_pulseaudio_on_dbus(c, DBUS_BUS_SYSTEM, &c->system_bus);
803 if (!c->session_bus)
804 track_pulseaudio_on_dbus(c, DBUS_BUS_SESSION, &c->session_bus);
805 } else
806 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
808 goto finish;
811 pa_log_debug("Trying to connect to %s...", u);
813 pa_xfree(c->server);
814 c->server = pa_xstrdup(u);
816 if (!(c->client = pa_socket_client_new_string(c->mainloop, u, PA_NATIVE_DEFAULT_PORT)))
817 continue;
819 c->is_local = !!pa_socket_client_is_local(c->client);
820 pa_socket_client_set_callback(c->client, on_connection, c);
821 break;
824 r = 0;
826 finish:
827 pa_xfree(u);
829 return r;
832 static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata) {
833 pa_context *c = userdata;
834 int saved_errno = errno;
836 pa_assert(client);
837 pa_assert(c);
838 pa_assert(c->state == PA_CONTEXT_CONNECTING);
840 pa_context_ref(c);
842 pa_socket_client_unref(client);
843 c->client = NULL;
845 if (!io) {
846 /* Try the item in the list */
847 if (saved_errno == ECONNREFUSED ||
848 saved_errno == ETIMEDOUT ||
849 saved_errno == EHOSTUNREACH) {
850 try_next_connection(c);
851 goto finish;
854 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
855 goto finish;
858 setup_context(c, io);
860 finish:
861 pa_context_unref(c);
864 static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, void *userdata) {
865 pa_context *c = userdata;
866 pa_bool_t is_session;
868 pa_assert(bus);
869 pa_assert(message);
870 pa_assert(c);
872 if (c->state != PA_CONTEXT_CONNECTING)
873 goto finish;
875 is_session = bus == pa_dbus_wrap_connection_get(c->session_bus);
876 pa_log_debug("Rock!! PulseAudio is baack on %s bus", is_session ? "session" : "system");
878 if (is_session) {
879 /* The user instance via PF_LOCAL */
880 c->server_list = prepend_per_user(c->server_list);
881 } else {
882 /* The system wide instance via PF_LOCAL */
883 c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET);
886 try_next_connection(c);
888 finish:
889 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
892 int pa_context_connect(
893 pa_context *c,
894 const char *server,
895 pa_context_flags_t flags,
896 const pa_spawn_api *api) {
898 int r = -1;
900 pa_assert(c);
901 pa_assert(PA_REFCNT_VALUE(c) >= 1);
903 PA_CHECK_VALIDITY(c, !pa_detect_fork(), PA_ERR_FORKED);
904 PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_UNCONNECTED, PA_ERR_BADSTATE);
905 PA_CHECK_VALIDITY(c, !(flags & ~(PA_CONTEXT_NOAUTOSPAWN|PA_CONTEXT_NOFAIL)), PA_ERR_INVALID);
906 PA_CHECK_VALIDITY(c, !server || *server, PA_ERR_INVALID);
908 if (!server)
909 server = c->conf->default_server;
911 pa_context_ref(c);
913 c->no_fail = flags & PA_CONTEXT_NOFAIL;
914 pa_assert(!c->server_list);
916 if (server) {
917 if (!(c->server_list = pa_strlist_parse(server))) {
918 pa_context_fail(c, PA_ERR_INVALIDSERVER);
919 goto finish;
922 } else {
923 char *d;
925 /* Prepend in reverse order */
927 /* Follow the X display */
928 if ((d = getenv("DISPLAY"))) {
929 char *e;
930 d = pa_xstrdup(d);
931 if ((e = strchr(d, ':')))
932 *e = 0;
934 if (*d)
935 c->server_list = pa_strlist_prepend(c->server_list, d);
937 pa_xfree(d);
940 /* Add TCP/IP on the localhost */
941 c->server_list = pa_strlist_prepend(c->server_list, "tcp6:[::1]");
942 c->server_list = pa_strlist_prepend(c->server_list, "tcp4:127.0.0.1");
944 /* The system wide instance via PF_LOCAL */
945 c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET);
947 /* The user instance via PF_LOCAL */
948 c->server_list = prepend_per_user(c->server_list);
950 /* Set up autospawning */
951 if (!(flags & PA_CONTEXT_NOAUTOSPAWN) && c->conf->autospawn) {
953 if (getuid() == 0)
954 pa_log_debug("Not doing autospawn since we are root.");
955 else {
956 c->do_autospawn = TRUE;
958 if (api)
959 c->spawn_api = *api;
964 pa_context_set_state(c, PA_CONTEXT_CONNECTING);
965 r = try_next_connection(c);
967 finish:
968 pa_context_unref(c);
970 return r;
973 void pa_context_disconnect(pa_context *c) {
974 pa_assert(c);
975 pa_assert(PA_REFCNT_VALUE(c) >= 1);
977 if (pa_detect_fork())
978 return;
980 if (PA_CONTEXT_IS_GOOD(c->state))
981 pa_context_set_state(c, PA_CONTEXT_TERMINATED);
984 pa_context_state_t pa_context_get_state(pa_context *c) {
985 pa_assert(c);
986 pa_assert(PA_REFCNT_VALUE(c) >= 1);
988 return c->state;
991 int pa_context_errno(pa_context *c) {
992 pa_assert(c);
993 pa_assert(PA_REFCNT_VALUE(c) >= 1);
995 return c->error;
998 void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
999 pa_assert(c);
1000 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1002 if (pa_detect_fork())
1003 return;
1005 if (c->state == PA_CONTEXT_TERMINATED || c->state == PA_CONTEXT_FAILED)
1006 return;
1008 c->state_callback = cb;
1009 c->state_userdata = userdata;
1012 void pa_context_set_event_callback(pa_context *c, pa_context_event_cb_t cb, void *userdata) {
1013 pa_assert(c);
1014 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1016 if (pa_detect_fork())
1017 return;
1019 if (c->state == PA_CONTEXT_TERMINATED || c->state == PA_CONTEXT_FAILED)
1020 return;
1022 c->event_callback = cb;
1023 c->event_userdata = userdata;
1026 int pa_context_is_pending(pa_context *c) {
1027 pa_assert(c);
1028 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1030 PA_CHECK_VALIDITY(c, !pa_detect_fork(), PA_ERR_FORKED);
1031 PA_CHECK_VALIDITY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE);
1033 return (c->pstream && pa_pstream_is_pending(c->pstream)) ||
1034 (c->pdispatch && pa_pdispatch_is_pending(c->pdispatch)) ||
1035 c->client;
1038 static void set_dispatch_callbacks(pa_operation *o);
1040 static void pdispatch_drain_callback(pa_pdispatch*pd, void *userdata) {
1041 set_dispatch_callbacks(userdata);
1044 static void pstream_drain_callback(pa_pstream *s, void *userdata) {
1045 set_dispatch_callbacks(userdata);
1048 static void set_dispatch_callbacks(pa_operation *o) {
1049 int done = 1;
1051 pa_assert(o);
1052 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1053 pa_assert(o->context);
1054 pa_assert(PA_REFCNT_VALUE(o->context) >= 1);
1055 pa_assert(o->context->state == PA_CONTEXT_READY);
1057 pa_pstream_set_drain_callback(o->context->pstream, NULL, NULL);
1058 pa_pdispatch_set_drain_callback(o->context->pdispatch, NULL, NULL);
1060 if (pa_pdispatch_is_pending(o->context->pdispatch)) {
1061 pa_pdispatch_set_drain_callback(o->context->pdispatch, pdispatch_drain_callback, o);
1062 done = 0;
1065 if (pa_pstream_is_pending(o->context->pstream)) {
1066 pa_pstream_set_drain_callback(o->context->pstream, pstream_drain_callback, o);
1067 done = 0;
1070 if (done) {
1071 if (o->callback) {
1072 pa_context_notify_cb_t cb = (pa_context_notify_cb_t) o->callback;
1073 cb(o->context, o->userdata);
1076 pa_operation_done(o);
1077 pa_operation_unref(o);
1081 pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
1082 pa_operation *o;
1084 pa_assert(c);
1085 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1087 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1088 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1089 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_context_is_pending(c), PA_ERR_BADSTATE);
1091 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1092 set_dispatch_callbacks(pa_operation_ref(o));
1094 return o;
1097 void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1098 pa_operation *o = userdata;
1099 int success = 1;
1101 pa_assert(pd);
1102 pa_assert(o);
1103 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1105 if (!o->context)
1106 goto finish;
1108 if (command != PA_COMMAND_REPLY) {
1109 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
1110 goto finish;
1112 success = 0;
1113 } else if (!pa_tagstruct_eof(t)) {
1114 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1115 goto finish;
1118 if (o->callback) {
1119 pa_context_success_cb_t cb = (pa_context_success_cb_t) o->callback;
1120 cb(o->context, success, o->userdata);
1123 finish:
1124 pa_operation_done(o);
1125 pa_operation_unref(o);
1128 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) {
1129 pa_tagstruct *t;
1130 pa_operation *o;
1131 uint32_t tag;
1133 pa_assert(c);
1134 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1136 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1137 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1139 o = pa_operation_new(c, NULL, cb, userdata);
1141 t = pa_tagstruct_command(c, command, &tag);
1142 pa_pstream_send_tagstruct(c->pstream, t);
1143 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, internal_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1145 return o;
1148 pa_operation* pa_context_exit_daemon(pa_context *c, pa_context_success_cb_t cb, void *userdata) {
1149 pa_assert(c);
1150 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1152 return pa_context_send_simple_command(c, PA_COMMAND_EXIT, pa_context_simple_ack_callback, (pa_operation_cb_t) cb, userdata);
1155 pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1156 pa_tagstruct *t;
1157 pa_operation *o;
1158 uint32_t tag;
1160 pa_assert(c);
1161 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1163 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1164 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1166 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1167 t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SINK, &tag);
1168 pa_tagstruct_puts(t, name);
1169 pa_pstream_send_tagstruct(c->pstream, t);
1170 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);
1172 return o;
1175 pa_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1176 pa_tagstruct *t;
1177 pa_operation *o;
1178 uint32_t tag;
1180 pa_assert(c);
1181 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1183 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1184 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1186 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1187 t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SOURCE, &tag);
1188 pa_tagstruct_puts(t, name);
1189 pa_pstream_send_tagstruct(c->pstream, t);
1190 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);
1192 return o;
1195 int pa_context_is_local(pa_context *c) {
1196 pa_assert(c);
1197 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1199 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, -1);
1200 PA_CHECK_VALIDITY_RETURN_ANY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE, -1);
1202 return !!c->is_local;
1205 pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1206 pa_operation *o;
1208 pa_assert(c);
1209 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1210 pa_assert(name);
1212 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1213 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1215 if (c->version >= 13) {
1216 pa_proplist *p = pa_proplist_new();
1218 pa_proplist_sets(p, PA_PROP_APPLICATION_NAME, name);
1219 o = pa_context_proplist_update(c, PA_UPDATE_REPLACE, p, cb, userdata);
1220 pa_proplist_free(p);
1221 } else {
1222 pa_tagstruct *t;
1223 uint32_t tag;
1225 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1226 t = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
1227 pa_tagstruct_puts(t, name);
1228 pa_pstream_send_tagstruct(c->pstream, t);
1229 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);
1232 return o;
1235 const char* pa_get_library_version(void) {
1236 return PACKAGE_VERSION;
1239 const char* pa_context_get_server(pa_context *c) {
1240 pa_assert(c);
1241 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1243 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1244 PA_CHECK_VALIDITY_RETURN_NULL(c, c->server, PA_ERR_NOENTITY);
1246 if (*c->server == '{') {
1247 char *e = strchr(c->server+1, '}');
1248 return e ? e+1 : c->server;
1251 return c->server;
1254 uint32_t pa_context_get_protocol_version(pa_context *c) {
1255 return PA_PROTOCOL_VERSION;
1258 uint32_t pa_context_get_server_protocol_version(pa_context *c) {
1259 pa_assert(c);
1260 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1262 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, PA_INVALID_INDEX);
1263 PA_CHECK_VALIDITY_RETURN_ANY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE, PA_INVALID_INDEX);
1265 return c->version;
1268 pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *tag) {
1269 pa_tagstruct *t;
1271 pa_assert(c);
1272 pa_assert(tag);
1274 t = pa_tagstruct_new(NULL, 0);
1275 pa_tagstruct_putu32(t, command);
1276 pa_tagstruct_putu32(t, *tag = c->ctag++);
1278 return t;
1281 uint32_t pa_context_get_index(pa_context *c) {
1282 pa_assert(c);
1283 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1285 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, PA_INVALID_INDEX);
1286 PA_CHECK_VALIDITY_RETURN_ANY(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE, PA_INVALID_INDEX);
1287 PA_CHECK_VALIDITY_RETURN_ANY(c, c->version >= 13, PA_ERR_NOTSUPPORTED, PA_INVALID_INDEX);
1289 return c->client_index;
1292 pa_operation *pa_context_proplist_update(pa_context *c, pa_update_mode_t mode, pa_proplist *p, pa_context_success_cb_t cb, void *userdata) {
1293 pa_operation *o;
1294 pa_tagstruct *t;
1295 uint32_t tag;
1297 pa_assert(c);
1298 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1300 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1301 PA_CHECK_VALIDITY_RETURN_NULL(c, mode == PA_UPDATE_SET || mode == PA_UPDATE_MERGE || mode == PA_UPDATE_REPLACE, PA_ERR_INVALID);
1302 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1303 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 13, PA_ERR_NOTSUPPORTED);
1305 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1307 t = pa_tagstruct_command(c, PA_COMMAND_UPDATE_CLIENT_PROPLIST, &tag);
1308 pa_tagstruct_putu32(t, (uint32_t) mode);
1309 pa_tagstruct_put_proplist(t, p);
1311 pa_pstream_send_tagstruct(c->pstream, t);
1312 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);
1314 /* Please note that we don't update c->proplist here, because we
1315 * don't export that field */
1317 return o;
1320 pa_operation *pa_context_proplist_remove(pa_context *c, const char *const keys[], pa_context_success_cb_t cb, void *userdata) {
1321 pa_operation *o;
1322 pa_tagstruct *t;
1323 uint32_t tag;
1324 const char * const *k;
1326 pa_assert(c);
1327 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1329 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1330 PA_CHECK_VALIDITY_RETURN_NULL(c, keys && keys[0], PA_ERR_INVALID);
1331 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1332 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 13, PA_ERR_NOTSUPPORTED);
1334 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1336 t = pa_tagstruct_command(c, PA_COMMAND_REMOVE_CLIENT_PROPLIST, &tag);
1338 for (k = keys; *k; k++)
1339 pa_tagstruct_puts(t, *k);
1341 pa_tagstruct_puts(t, NULL);
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);
1346 /* Please note that we don't update c->proplist here, because we
1347 * don't export that field */
1349 return o;
1352 void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1353 pa_context *c = userdata;
1354 uint32_t idx;
1355 const char *name;
1357 pa_assert(pd);
1358 pa_assert(command == PA_COMMAND_EXTENSION);
1359 pa_assert(t);
1360 pa_assert(c);
1361 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1363 pa_context_ref(c);
1365 if (c->version < 15) {
1366 pa_context_fail(c, PA_ERR_PROTOCOL);
1367 goto finish;
1370 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1371 pa_tagstruct_gets(t, &name) < 0) {
1372 pa_context_fail(c, PA_ERR_PROTOCOL);
1373 goto finish;
1376 if (!strcmp(name, "module-stream-restore"))
1377 pa_ext_stream_restore_command(c, tag, t);
1378 else
1379 pa_log(_("Received message for unknown extension '%s'"), name);
1381 finish:
1382 pa_context_unref(c);
1386 void pa_command_client_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1387 pa_context *c = userdata;
1388 pa_proplist *pl = NULL;
1389 const char *event;
1391 pa_assert(pd);
1392 pa_assert(command == PA_COMMAND_CLIENT_EVENT);
1393 pa_assert(t);
1394 pa_assert(c);
1395 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1397 pa_context_ref(c);
1399 if (c->version < 15) {
1400 pa_context_fail(c, PA_ERR_PROTOCOL);
1401 goto finish;
1404 pl = pa_proplist_new();
1406 if (pa_tagstruct_gets(t, &event) < 0 ||
1407 pa_tagstruct_get_proplist(t, pl) < 0 ||
1408 !pa_tagstruct_eof(t) || !event) {
1409 pa_context_fail(c, PA_ERR_PROTOCOL);
1410 goto finish;
1413 if (c->event_callback)
1414 c->event_callback(c, event, pl, c->event_userdata);
1416 finish:
1417 pa_context_unref(c);
1419 if (pl)
1420 pa_proplist_free(pl);