summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2014-07-29 14:41:58 +0100
committerWim Taymans <wtaymans@redhat.com>2014-08-13 14:38:27 +0200
commit54a5ea86f7a90b3ebd8b676ae5337b7894d5c7de (patch)
tree847c14552ce36c6eb8c02c0e1b567ea49d9aa08b
parentd0f0a462785b7911446137c0f810b7deb0e04ccf (diff)
work
-rw-r--r--src/modules/bluetooth/bluez5-util.c77
-rw-r--r--src/modules/bluetooth/module-bluez5-device.c10
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);