2 This file is part of PulseAudio.
4 Copyright 2008-2013 João Paulo Rechi Vita
6 PulseAudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
11 PulseAudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with PulseAudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
26 #include <pulse/xmalloc.h>
28 #include <pulsecore/core.h>
29 #include <pulsecore/core-util.h>
30 #include <pulsecore/dbus-shared.h>
31 #include <pulsecore/log.h>
32 #include <pulsecore/macro.h>
33 #include <pulsecore/refcnt.h>
34 #include <pulsecore/shared.h>
36 #include "bluez5-util.h"
38 #define BLUEZ_SERVICE "org.bluez"
40 struct pa_bluetooth_discovery
{
44 pa_dbus_connection
*connection
;
49 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*m
, void *userdata
) {
50 pa_bluetooth_discovery
*y
;
55 pa_assert_se(y
= userdata
);
57 dbus_error_init(&err
);
59 if (dbus_message_is_signal(m
, "org.freedesktop.DBus", "NameOwnerChanged")) {
60 const char *name
, *old_owner
, *new_owner
;
62 if (!dbus_message_get_args(m
, &err
,
63 DBUS_TYPE_STRING
, &name
,
64 DBUS_TYPE_STRING
, &old_owner
,
65 DBUS_TYPE_STRING
, &new_owner
,
67 pa_log_error("Failed to parse org.freedesktop.DBus.NameOwnerChanged: %s", err
.message
);
71 if (pa_streq(name
, BLUEZ_SERVICE
)) {
72 if (old_owner
&& *old_owner
) {
73 pa_log_debug("Bluetooth daemon disappeared");
74 /* TODO: remove all devices */
77 if (new_owner
&& *new_owner
) {
78 pa_log_debug("Bluetooth daemon appeared");
79 /* TODO: get managed objects */
83 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
87 dbus_error_free(&err
);
89 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
92 pa_bluetooth_discovery
* pa_bluetooth_discovery_get(pa_core
*c
) {
93 pa_bluetooth_discovery
*y
;
97 if ((y
= pa_shared_get(c
, "bluetooth-discovery")))
98 return pa_bluetooth_discovery_ref(y
);
100 y
= pa_xnew0(pa_bluetooth_discovery
, 1);
104 pa_shared_set(c
, "bluetooth-discovery", y
);
106 dbus_error_init(&err
);
108 if (!(y
->connection
= pa_dbus_bus_get(y
->core
, DBUS_BUS_SYSTEM
, &err
))) {
109 pa_log_error("Failed to get D-Bus connection: %s", err
.message
);
113 conn
= pa_dbus_connection_get(y
->connection
);
115 /* dynamic detection of bluetooth audio devices */
116 if (!dbus_connection_add_filter(conn
, filter_cb
, y
, NULL
)) {
117 pa_log_error("Failed to add filter function");
120 y
->filter_added
= true;
122 if (pa_dbus_add_matches(conn
, &err
,
123 "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged'"
124 ",arg0='" BLUEZ_SERVICE
"'",
126 pa_log_error("Failed to add D-Bus matches: %s", err
.message
);
129 y
->matches_added
= true;
134 pa_bluetooth_discovery_unref(y
);
135 dbus_error_free(&err
);
140 pa_bluetooth_discovery
* pa_bluetooth_discovery_ref(pa_bluetooth_discovery
*y
) {
142 pa_assert(PA_REFCNT_VALUE(y
) > 0);
149 void pa_bluetooth_discovery_unref(pa_bluetooth_discovery
*y
) {
151 pa_assert(PA_REFCNT_VALUE(y
) > 0);
153 if (PA_REFCNT_DEC(y
) > 0)
158 if (y
->matches_added
)
159 pa_dbus_remove_matches(pa_dbus_connection_get(y
->connection
),
160 "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',"
161 "arg0='" BLUEZ_SERVICE
"'",
165 dbus_connection_remove_filter(pa_dbus_connection_get(y
->connection
), filter_cb
, y
);
167 pa_dbus_connection_unref(y
->connection
);
170 pa_shared_remove(y
->core
, "bluetooth-discovery");