From: Jo?o Paulo Rechi Vita <jprvita@xxxxxxxxxxxxx> Create a structure pa_bluetooth_device to store information about the bluetooth device and utility functions to manipulate this structure. --- src/modules/bluetooth/bluez5-util.c | 84 +++++++++++++++++++++++++++++++++++++ src/modules/bluetooth/bluez5-util.h | 18 ++++++++ 2 files changed, 102 insertions(+) diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c index d5f1846..574a22d 100644 --- a/src/modules/bluetooth/bluez5-util.c +++ b/src/modules/bluetooth/bluez5-util.c @@ -44,8 +44,86 @@ struct pa_bluetooth_discovery { pa_dbus_connection *connection; bool filter_added; pa_hook hooks[PA_BLUETOOTH_HOOK_MAX]; + pa_hashmap *devices; }; +static pa_bluetooth_device* pa_bluetooth_discovery_create_device(pa_bluetooth_discovery *y, const char *path) { + pa_bluetooth_device *d; + + pa_assert(y); + pa_assert(path); + + d = pa_xnew0(pa_bluetooth_device, 1); + d->discovery = y; + d->path = pa_xstrdup(path); + + pa_hashmap_put(y->devices, d->path, d); + + return d; +} + +pa_bluetooth_device* pa_bluetooth_discovery_get_device_by_path(pa_bluetooth_discovery *y, const char *path) { + pa_bluetooth_device *d; + + pa_assert(y); + pa_assert(PA_REFCNT_VALUE(y) > 0); + pa_assert(path); + + if ((d = pa_hashmap_get(y->devices, path))) + if (d->device_info_valid == 1) + return d; + + return NULL; +} + +pa_bluetooth_device* pa_bluetooth_discovery_get_device_by_address(pa_bluetooth_discovery *y, const char *address) { + pa_bluetooth_device *d; + void *state = NULL; + + pa_assert(y); + pa_assert(PA_REFCNT_VALUE(y) > 0); + pa_assert(address); + + while ((d = pa_hashmap_iterate(y->devices, &state, NULL))) + if (pa_streq(d->address, address)) + return d->device_info_valid == 1 ? d : NULL; + + return NULL; +} + +static void pa_bluetooth_device_free(pa_bluetooth_device *d) { + pa_assert(d); + + d->discovery = NULL; + pa_xfree(d->path); + pa_xfree(d->alias); + pa_xfree(d->address); + pa_xfree(d); +} + +static void pa_bluetooth_discovery_remove_device(pa_bluetooth_discovery *y, const char *path) { + pa_bluetooth_device *d; + + if (!(d = pa_hashmap_remove(y->devices, path))) + pa_log_warn("Unknown device removed %s", path); + else { + pa_log_debug("Device %s removed", path); + pa_bluetooth_device_free(d); + } +} + +static void pa_bluetooth_discovery_remove_all_devices(pa_bluetooth_discovery *y) { + pa_bluetooth_device *d; + + pa_assert(y); + + while ((d = pa_hashmap_steal_first(y->devices))) { + d->dead = true; + pa_hook_fire(&y->hooks[PA_BLUETOOTH_HOOK_DEVICE_CONNECTION_CHANGED], d); + pa_bluetooth_device_free(d); + } +} + pa_hook* pa_bluetooth_discovery_hook(pa_bluetooth_discovery *y, pa_bluetooth_hook_t hook) { pa_assert(y); pa_assert(PA_REFCNT_VALUE(y) > 0); @@ -115,6 +193,7 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { y = pa_xnew0(pa_bluetooth_discovery, 1); PA_REFCNT_INIT(y); y->core = c; + y->devices = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); for (i = 0; i < PA_BLUETOOTH_HOOK_MAX; i++) pa_hook_init(&y->hooks[i], y); @@ -170,6 +249,11 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) { if (PA_REFCNT_DEC(y) > 0) return; + if (y->devices) { + pa_bluetooth_discovery_remove_all_devices(y); + pa_hashmap_free(y->devices, NULL); + } + if (y->connection) { pa_dbus_remove_matches(pa_dbus_connection_get(y->connection), "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged'" diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h index afbd8e9..a205b45 100644 --- a/src/modules/bluetooth/bluez5-util.h +++ b/src/modules/bluetooth/bluez5-util.h @@ -24,12 +24,30 @@ #include <pulsecore/core.h> +typedef struct pa_bluetooth_device pa_bluetooth_device; typedef struct pa_bluetooth_discovery pa_bluetooth_discovery; typedef enum pa_bluetooth_hook { + PA_BLUETOOTH_HOOK_DEVICE_CONNECTION_CHANGED, /* Call data: pa_bluetooth_device */ PA_BLUETOOTH_HOOK_MAX } pa_bluetooth_hook_t; +struct pa_bluetooth_device { + pa_bluetooth_discovery *discovery; + + bool dead; + int device_info_valid; /* 0: no results yet; 1: good results; -1: bad results ... */ + + /* Device information */ + char *path; + char *alias; + char *address; + int class_of_device; +}; + +pa_bluetooth_device* pa_bluetooth_discovery_get_device_by_path(pa_bluetooth_discovery *y, const char *path); +pa_bluetooth_device* pa_bluetooth_discovery_get_device_by_address(pa_bluetooth_discovery *y, const char *address); + pa_hook* pa_bluetooth_discovery_hook(pa_bluetooth_discovery *y, pa_bluetooth_hook_t hook); pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *core); -- 1.7.11.7