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 <pulsecore/core.h>
27 #include <pulsecore/core-util.h>
28 #include <pulsecore/macro.h>
29 #include <pulsecore/module.h>
30 #include <pulsecore/shared.h>
32 #include "bluez5-util.h"
34 #include "module-bluez5-discover-symdef.h"
36 PA_MODULE_AUTHOR("João Paulo Rechi Vita");
37 PA_MODULE_DESCRIPTION("Detect available BlueZ 5 Bluetooth audio devices and load BlueZ 5 Bluetooth audio drivers");
38 PA_MODULE_VERSION(PACKAGE_VERSION);
39 PA_MODULE_LOAD_ONCE(true);
44 pa_hashmap *loaded_device_paths;
45 pa_hook_slot *device_connection_changed_slot;
46 pa_bluetooth_discovery *discovery;
49 static pa_hook_result_t device_connection_changed_cb(pa_bluetooth_discovery *y, const pa_bluetooth_device *d, struct userdata *u) {
55 module_loaded = pa_hashmap_get(u->loaded_device_paths, d->path) ? true : false;
57 if (module_loaded && !pa_bluetooth_device_any_transport_connected(d)) {
58 /* disconnection, the module unloads itself */
59 pa_log_debug("Unregistering module for %s", d->path);
60 pa_hashmap_remove(u->loaded_device_paths, d->path);
64 if (!module_loaded && pa_bluetooth_device_any_transport_connected(d)) {
65 /* a new device has been connected */
67 char *args = pa_sprintf_malloc("path=%s", d->path);
69 pa_log_debug("Loading module-bluez5-device %s", args);
70 m = pa_module_load(u->module->core, "module-bluez5-device", args);
74 /* No need to duplicate the path here since the device object will
75 * exist for the whole hashmap entry lifespan */
76 pa_hashmap_put(u->loaded_device_paths, d->path, d->path);
78 pa_log_warn("Failed to load module for device %s", d->path);
86 int pa__init(pa_module *m) {
91 m->userdata = u = pa_xnew0(struct userdata, 1);
94 u->loaded_device_paths = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
96 if (!(u->discovery = pa_bluetooth_discovery_get(u->core)))
99 u->device_connection_changed_slot =
100 pa_hook_connect(pa_bluetooth_discovery_hook(u->discovery, PA_BLUETOOTH_HOOK_DEVICE_CONNECTION_CHANGED),
101 PA_HOOK_NORMAL, (pa_hook_cb_t) device_connection_changed_cb, u);
110 void pa__done(pa_module *m) {
115 if (!(u = m->userdata))
118 if (u->device_connection_changed_slot)
119 pa_hook_slot_free(u->device_connection_changed_slot);
122 pa_bluetooth_discovery_unref(u->discovery);
124 if (u->loaded_device_paths)
125 pa_hashmap_free(u->loaded_device_paths);