diff options
author | Wim Taymans <wtaymans@redhat.com> | 2014-07-29 14:41:58 +0100 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2014-08-13 14:38:27 +0200 |
commit | 54a5ea86f7a90b3ebd8b676ae5337b7894d5c7de (patch) | |
tree | 847c14552ce36c6eb8c02c0e1b567ea49d9aa08b | |
parent | d0f0a462785b7911446137c0f810b7deb0e04ccf (diff) |
work
-rw-r--r-- | src/modules/bluetooth/bluez5-util.c | 77 | ||||
-rw-r--r-- | src/modules/bluetooth/module-bluez5-device.c | 10 |
2 files changed, 51 insertions, 36 deletions
diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c index 36826ce86..8edcaf691 100644 --- a/src/modules/bluetooth/bluez5-util.c +++ b/src/modules/bluetooth/bluez5-util.c @@ -232,6 +232,10 @@ void pa_bluetooth_transport_free(pa_bluetooth_transport *t) { pa_assert(t); pa_hashmap_remove(t->device->discovery->transports, t->path); + if (t->rfcomm_io) { + t->device->discovery->core->mainloop->io_free(t->rfcomm_io); + close (t->rfcomm_fd); + } pa_xfree(t->owner); pa_xfree(t->path); pa_xfree(t->config); @@ -261,7 +265,7 @@ static int bluez5_sco_acquire_cb(pa_bluetooth_transport *t, bool optional, size_ sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO); if (sock < 0) { - pa_log_error("socket(SEQPACKET, SCO)"); + pa_log_error("socket(SEQPACKET, SCO) %s", pa_cstrerror(errno)); return -1; } @@ -270,8 +274,8 @@ static int bluez5_sco_acquire_cb(pa_bluetooth_transport *t, bool optional, size_ bacpy(&addr.sco_bdaddr, &src); if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - pa_log_error("bind()"); - return -1; + pa_log_error("bind(): %s", pa_cstrerror(errno)); + goto fail_close; } if (voice) { @@ -281,8 +285,8 @@ static int bluez5_sco_acquire_cb(pa_bluetooth_transport *t, bool optional, size_ memset(&opts, 0, sizeof(opts)); opts.setting = voice; if (setsockopt(sock, SOL_BLUETOOTH, BT_VOICE, &opts, sizeof(opts)) < 0) { - pa_log_error("setsockopt()"); - return -1; + pa_log_error("setsockopt(): %s", pa_cstrerror(errno)); + goto fail_close; } } @@ -293,14 +297,14 @@ static int bluez5_sco_acquire_cb(pa_bluetooth_transport *t, bool optional, size_ pa_log_info ("doing connect\n"); err = connect(sock, (struct sockaddr *) &addr, sizeof(addr)); if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS)) { - pa_log_error("connect()"); - return -1; + pa_log_error("connect(): %s", pa_cstrerror(errno)); + goto fail_close; } len = sizeof(so); if (getsockopt(sock, SOL_SCO, SCO_OPTIONS, &so, &len) < 0) { - pa_log_error("getsockopt()"); - return -1; + pa_log_error("getsockopt(): %s", pa_cstrerror(errno)); + goto fail_close; } so.mtu = 48; @@ -314,14 +318,13 @@ static int bluez5_sco_acquire_cb(pa_bluetooth_transport *t, bool optional, size_ *omtu = so.mtu; return sock; + +fail_close: + close(sock); + return -1; } static void bluez5_sco_release_cb(pa_bluetooth_transport *t) { - if (t->rfcomm_io) { - t->device->discovery->core->mainloop->io_free(t->rfcomm_io); - t->rfcomm_io = NULL; - close (t->rfcomm_fd); - } pa_log_info("Transport %s released", t->path); } @@ -1771,16 +1774,29 @@ static DBusMessage *profile_new_connection(DBusConnection *conn, DBusMessage *m, handler = dbus_message_get_path(m); - if (pa_streq(handler, HSP_AG_PROFILE)) { - p = PA_BLUETOOTH_PROFILE_HSP_AG; - } else if (pa_streq(handler, HFP_AG_PROFILE)) { - p = PA_BLUETOOTH_PROFILE_HFP_AG; + pa_assert(dbus_message_iter_get_arg_type(&arg_i) == DBUS_TYPE_OBJECT_PATH); + dbus_message_iter_get_basic(&arg_i, &path); + + if ((d = pa_hashmap_get(y->devices, path))) { + if (!d->valid) { + pa_log_error("Information about device %s is invalid", path); + goto fail; + } } else { - p = PA_BLUETOOTH_PROFILE_HFP_AG; + /* InterfacesAdded signal is probably on its way, device_info_valid is kept as 0. */ + pa_log_warn("received for unknown device %s", path); + d = device_create(y, path); } - pa_assert(dbus_message_iter_get_arg_type(&arg_i) == DBUS_TYPE_OBJECT_PATH); - dbus_message_iter_get_basic(&arg_i, &path); + if (pa_streq(handler, HSP_AG_PROFILE)) { + /* refuse HSP when the device can do HFP */ + if (pa_hashmap_get(d->uuids, PA_BLUETOOTH_PROFILE_HFP_AG)) + goto refused; + p = PA_BLUETOOTH_PROFILE_HSP_AG; + } else if (pa_streq(handler, HFP_AG_PROFILE)) { + p = PA_BLUETOOTH_PROFILE_HFP_AG; + } else + goto refused; pa_assert_se(dbus_message_iter_next(&arg_i)); @@ -1811,25 +1827,14 @@ static DBusMessage *profile_new_connection(DBusConnection *conn, DBusMessage *m, sender = dbus_message_get_sender(m); - if ((d = pa_hashmap_get(y->devices, path))) { - if (!d->valid) { - pa_log_error("Information about device %s is invalid", path); - goto fail; - } - } else { - /* InterfacesAdded signal is probably on its way, device_info_valid is kept as 0. */ - pa_log_warn("received for unknown device %s", path); - d = device_create(y, path); - } - pathfd = pa_sprintf_malloc ("%s/fd%d", path, fd); d->transports[p] = t = pa_bluetooth_transport_new(d, sender, pathfd, p, NULL, 0); pa_xfree(pathfd); - t->acquire = bluez5_sco_acquire_cb; - t->release = bluez5_sco_release_cb; t->rfcomm_fd = fd; t->rfcomm_io = y->core->mainloop->io_new(y->core->mainloop, fd, PA_IO_EVENT_INPUT|PA_IO_EVENT_HANGUP, rfcomm_io_callback, t); + t->acquire = bluez5_sco_acquire_cb; + t->release = bluez5_sco_release_cb; pa_bluetooth_transport_put(t); pa_log_debug("Transport %s available for profile %s", t->path, pa_bluetooth_profile_to_string(t->profile)); @@ -1841,6 +1846,10 @@ static DBusMessage *profile_new_connection(DBusConnection *conn, DBusMessage *m, fail: pa_assert_se(r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments", "Unable to handle new connection")); return r; +refused: + pa_log_debug("dbus: NewConnection path=%s rejected", path); + pa_assert_se(r = dbus_message_new_error(m, "org.bluez.Error.Rejected", "New connection rejected")); + return r; } static DBusMessage *profile_request_disconnection(DBusConnection *conn, DBusMessage *m, void *userdata) { diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c index 31c820b59..2e0586ae4 100644 --- a/src/modules/bluetooth/module-bluez5-device.c +++ b/src/modules/bluetooth/module-bluez5-device.c @@ -34,6 +34,7 @@ #include <pulsecore/core-error.h> #include <pulsecore/core-util.h> +#include <pulsecore/core-rtclock.h> #include <pulsecore/i18n.h> #include <pulsecore/module.h> #include <pulsecore/modargs.h> @@ -1728,7 +1729,7 @@ static pa_card_profile *create_card_profile(struct userdata *u, const char *uuid p = PA_CARD_PROFILE_DATA(cp); *p = PA_BLUETOOTH_PROFILE_A2DP_SOURCE; } else if (pa_streq(uuid, PA_BLUETOOTH_UUID_HFP_HS)) { - cp = pa_card_profile_new("hfp_hs", _("Handsfree"), sizeof(pa_bluetooth_profile_t)); + cp = pa_card_profile_new("hfp_ag", _("Handsfree Audio Gateway"), sizeof(pa_bluetooth_profile_t)); cp->priority = 20; cp->n_sinks = 1; cp->n_sources = 1; @@ -1740,7 +1741,11 @@ static pa_card_profile *create_card_profile(struct userdata *u, const char *uuid p = PA_CARD_PROFILE_DATA(cp); *p = PA_BLUETOOTH_PROFILE_HFP_AG; } else if (pa_streq(uuid, PA_BLUETOOTH_UUID_HSP_HS)) { - cp = pa_card_profile_new("hsp_hs", _("Headset"), sizeof(pa_bluetooth_profile_t)); + /* don't add HSP when HFP is available */ + if (pa_hashmap_get (u->device->uuids, PA_BLUETOOTH_UUID_HFP_HS)) + goto done; + + cp = pa_card_profile_new("hsp_ag", _("Headset Audio Gateway"), sizeof(pa_bluetooth_profile_t)); cp->priority = 20; cp->n_sinks = 1; cp->n_sources = 1; @@ -1753,6 +1758,7 @@ static pa_card_profile *create_card_profile(struct userdata *u, const char *uuid *p = PA_BLUETOOTH_PROFILE_HSP_AG; } +done: if (cp && u->device->transports[*p]) cp->available = transport_state_to_availability(u->device->transports[*p]->state); |