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
;
47 pa_hook hooks
[PA_BLUETOOTH_HOOK_MAX
];
50 pa_hook
* pa_bluetooth_discovery_hook(pa_bluetooth_discovery
*y
, pa_bluetooth_hook_t hook
) {
52 pa_assert(PA_REFCNT_VALUE(y
) > 0);
54 return &y
->hooks
[hook
];
57 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*m
, void *userdata
) {
58 pa_bluetooth_discovery
*y
;
63 pa_assert_se(y
= userdata
);
65 dbus_error_init(&err
);
67 if (dbus_message_is_signal(m
, "org.freedesktop.DBus", "NameOwnerChanged")) {
68 const char *name
, *old_owner
, *new_owner
;
70 if (!dbus_message_get_args(m
, &err
,
71 DBUS_TYPE_STRING
, &name
,
72 DBUS_TYPE_STRING
, &old_owner
,
73 DBUS_TYPE_STRING
, &new_owner
,
75 pa_log_error("Failed to parse org.freedesktop.DBus.NameOwnerChanged: %s", err
.message
);
79 if (pa_streq(name
, BLUEZ_SERVICE
)) {
80 if (old_owner
&& *old_owner
) {
81 pa_log_debug("Bluetooth daemon disappeared");
82 /* TODO: remove all devices */
85 if (new_owner
&& *new_owner
) {
86 pa_log_debug("Bluetooth daemon appeared");
87 /* TODO: get managed objects */
91 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
95 dbus_error_free(&err
);
97 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
100 pa_bluetooth_discovery
* pa_bluetooth_discovery_get(pa_core
*c
) {
101 pa_bluetooth_discovery
*y
;
103 DBusConnection
*conn
;
106 if ((y
= pa_shared_get(c
, "bluetooth-discovery")))
107 return pa_bluetooth_discovery_ref(y
);
109 y
= pa_xnew0(pa_bluetooth_discovery
, 1);
113 for (i
= 0; i
< PA_BLUETOOTH_HOOK_MAX
; i
++)
114 pa_hook_init(&y
->hooks
[i
], y
);
116 pa_shared_set(c
, "bluetooth-discovery", y
);
118 dbus_error_init(&err
);
120 if (!(y
->connection
= pa_dbus_bus_get(y
->core
, DBUS_BUS_SYSTEM
, &err
))) {
121 pa_log_error("Failed to get D-Bus connection: %s", err
.message
);
125 conn
= pa_dbus_connection_get(y
->connection
);
127 /* dynamic detection of bluetooth audio devices */
128 if (!dbus_connection_add_filter(conn
, filter_cb
, y
, NULL
)) {
129 pa_log_error("Failed to add filter function");
132 y
->filter_added
= true;
134 if (pa_dbus_add_matches(conn
, &err
,
135 "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged'"
136 ",arg0='" BLUEZ_SERVICE
"'",
138 pa_log_error("Failed to add D-Bus matches: %s", err
.message
);
141 y
->matches_added
= true;
146 pa_bluetooth_discovery_unref(y
);
147 dbus_error_free(&err
);
152 pa_bluetooth_discovery
* pa_bluetooth_discovery_ref(pa_bluetooth_discovery
*y
) {
154 pa_assert(PA_REFCNT_VALUE(y
) > 0);
161 void pa_bluetooth_discovery_unref(pa_bluetooth_discovery
*y
) {
163 pa_assert(PA_REFCNT_VALUE(y
) > 0);
165 if (PA_REFCNT_DEC(y
) > 0)
170 if (y
->matches_added
)
171 pa_dbus_remove_matches(pa_dbus_connection_get(y
->connection
),
172 "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',"
173 "arg0='" BLUEZ_SERVICE
"'",
177 dbus_connection_remove_filter(pa_dbus_connection_get(y
->connection
), filter_cb
, y
);
179 pa_dbus_connection_unref(y
->connection
);
182 pa_shared_remove(y
->core
, "bluetooth-discovery");