2010-01-29 14:44:24

by João Paulo Rechi Vita

[permalink] [raw]
Subject: [RFC] [PATCH 0/2] HFP AG integration with PulseAudio

SGkgYWxsLAoKSSdtIHRyeWluZyB0byBhZGQgc3VwcG9ydCBmb3IgdGhlIEhhbmRzZnJlZSBHYXRl
d2F5IHJvbGUgR3VzdGF2byBqdXN0IGFkZGVkCnRvIEJsdWVaIGFuZCBvRm9uby4gVGhlIEJsdWVa
IHBhdGNoZXMgY2FuIGJlIGZvdW5kIG9uIFsxXSBhbmQgWzJdIGFuZCB0aGUKb0Zvbm8gcGFydCB3
YXMganVzdCBtZXJnZWQgdXBzdHJlYW0uCgpCdXQgd2hlbiBpdCBjb21lcyB0byBpbnRlZ3JhdGUg
dGhlbSB3aXRoIFB1bHNlLCBJJ20gZ2V0dGluZyBhIFBPTExIVVAgd2hlbgp0cnlpbmcgdG8gd3Jp
dGUgb24gdGhlIGZkLiBBbHNvLCBpdCBzZWVtcyBkaWZmZXJlbnQgZ2F0ZXdheXMgaGF2ZSBkaWZm
ZXJlbnQKYmVoYXZpb3VycyByZWdhcmRpbmcgd2hlbiB0aGV5IGNvbm5lY3QgdGhlIFNDTyBsaW5r
LiBTb21lIHBob25lIGNvbm5lY3QKdGhlbSBqdXN0IGFmdGVyIHRoZSBSRkNPTU0gbGluayAoc29t
ZSBOb2tpYSBwaG9uZXMpLCB3aGVuIHRoZXJlIGlzIG5vIGNhbGwKZ29pbmcgb24geWV0LCBhbmQg
b3RoZXJzIGp1c3Qgd2hlbiBhIGNhbGwgaXMgc3RhcnRlZCAoQW5kcm9pZCAxLjUpLgoKQWxzbywg
cmlnaHQgbm93IHRoZSBzYW1lIHByb3BlcnR5IChTdGF0ZSkgaXMgYmVlaW5nIHVzZWQgdG8gcmVm
ZXIgd2hlbiB0aGUKUkZDT09NIGxpbmsgaXMgZXN0YWJsaXNoZWQgKFN0YXRlPUNvbm5lY3RlZCkg
YW5kIHdoZW4gdGhlIFNDTyBsaW5rIGlzCmVzdGFibGlzaGVkIChTdGF0ZT1QbGF5aW5nKS4gU2hv
dWxkbid0IHRoaXMgYmUgaGFuZGxlZCBieSBzZXBhcmF0ZSBwcm9wcz8KCkFuZCBsYXN0IGJ1dCBu
b3QgbGVhc3QsIGlzIHRoZSBuZXcgTWVkaWEgQVBJIGludGVuZGVkIHRvIGhhbmRsZSB0aGUgYXVk
aW8KcGFydCBvZiBoYW5kc2ZyZWUgZ2F0ZXdheXMgdG9vPyBJZiBzbywgbWF5YmUgd2Ugc2hvdWxk
IHVzZSBhbGwgdGhpcyB3b3JrCmFzIGEgcHJvdG90eXBlIGZvciBsYXR0ZXIgaW50ZWdyYXRpb24g
d2l0aCB0aGUgbmV3IEFQSS4KCkFueSBoZWxwIG9uIHRlc3RpbmcgYW5kIGdldHRpbmcgdGhpcyB3
b3JraW5nIHRvZ2V0aGVyIG9yIGNvbW1lbnRzIG9uIHRoZQp0b3BpYyB3b3VsZCBiZSBhcHByZWNp
YXRlZC4KClsxXSBodHRwOi8vd3d3LnNwaW5pY3MubmV0L2xpc3RzL2xpbnV4LWJsdWV0b290aC9t
c2cwNDI1MC5odG1sClsyXSBodHRwOi8vd3d3LnNwaW5pY3MubmV0L2xpc3RzL2xpbnV4LWJsdWV0
b290aC9tc2cwNDI1MS5odG1sCgotLQpKb8OjbyBQYXVsbyBSZWNoaSBWaXRhCmh0dHA6Ly9qcHJ2
aXRhLndvcmRwcmVzcy5jb20vCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f
X19fX19fX19fXwpvZm9ubyBtYWlsaW5nIGxpc3QKb2Zvbm9Ab2Zvbm8ub3JnCmh0dHA6Ly9saXN0
cy5vZm9uby5vcmcvbGlzdGluZm8vb2Zvbm8K


2010-01-29 14:53:24

by João Paulo Rechi Vita

[permalink] [raw]
Subject: Re: [RFC] [PATCH 0/2] HFP AG integration with PulseAudio

2010/1/29 João Paulo Rechi Vita <[email protected]>:
> Hi all,
>
> I'm trying to add support for the Handsfree Gateway role Gustavo just added
> to BlueZ and oFono. The BlueZ patches can be found on [1] and [2] and the
> oFono part was just merged upstream.
>
> But when it comes to integrate them with Pulse, I'm getting a POLLHUP when
> trying to write on the fd. Also, it seems different gateways have different
> behaviours regarding when they connect the SCO link. Some phone connect
> them just after the RFCOMM link (some Nokia phones), when there is no call
> going on yet, and others just when a call is started (Android 1.5).
>
> Also, right now the same property (State) is beeing used to refer when the
> RFCOOM link is established (State=Connected) and when the SCO link is
> established (State=Playing). Shouldn't this be handled by separate props?
>
> And last but not least, is the new Media API intended to handle the audio
> part of handsfree gateways too? If so, maybe we should use all this work
> as a prototype for latter integration with the new API.
>
> Any help on testing and getting this working together or comments on the
> topic would be appreciated.
>
> [1] http://www.spinics.net/lists/linux-bluetooth/msg04250.html
> [2] http://www.spinics.net/lists/linux-bluetooth/msg04251.html
>
> --
> João Paulo Rechi Vita
> http://jprvita.wordpress.com/
>
>

I forgot to add, suspending of the sink/source seemed to cause
disconnection by the AG, so you might want to disable
module-suspend-on-idle when testing. BTW, Lennart, is there any way to
mark a source/sink to not be suspended?

--
João Paulo Rechi Vita
http://jprvita.wordpress.com/

2010-01-29 14:44:26

by João Paulo Rechi Vita

[permalink] [raw]
Subject: [PATCH 2/2] bluetooth: add HFP Gateway support

From: João Paulo Rechi Vita <[email protected]>

Create the 'Handsfree Gateway' profile for bluetooth cards and add
filters for 'org.bluez.HandsfreeGateway' to the discover module so
module-bluetooth-device is loaded with the correct profile when a
Handsfree Gateway connects to bluetoothd (in this case bluetoothd
is acting as the headset).
---
src/modules/bluetooth/bluetooth-util.c | 30 ++++++++++--
src/modules/bluetooth/bluetooth-util.h | 3 +
src/modules/bluetooth/module-bluetooth-device.c | 50 +++++++++++++++-----
src/modules/bluetooth/module-bluetooth-discover.c | 9 +++-
4 files changed, 72 insertions(+), 20 deletions(-)

diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c
index d3f3bfe..a873e25 100644
--- a/src/modules/bluetooth/bluetooth-util.c
+++ b/src/modules/bluetooth/bluetooth-util.c
@@ -97,6 +97,7 @@ static pa_bluetooth_device* device_new(const char *path) {
d->audio_sink_state = PA_BT_AUDIO_STATE_INVALID;
d->audio_source_state = PA_BT_AUDIO_STATE_INVALID;
d->headset_state = PA_BT_AUDIO_STATE_INVALID;
+ d->hfgw_state = PA_BT_AUDIO_STATE_INVALID;

return d;
}
@@ -122,11 +123,11 @@ static pa_bool_t device_is_audio(pa_bluetooth_device *d) {
pa_assert(d);

return
- d->device_info_valid &&
+ d->device_info_valid && (d->hfgw_state != PA_BT_AUDIO_STATE_INVALID ||
(d->audio_state != PA_BT_AUDIO_STATE_INVALID &&
(d->audio_sink_state != PA_BT_AUDIO_STATE_INVALID ||
d->audio_source_state != PA_BT_AUDIO_STATE_INVALID ||
- d->headset_state != PA_BT_AUDIO_STATE_INVALID));
+ d->headset_state != PA_BT_AUDIO_STATE_INVALID)));
}

static int parse_device_property(pa_bluetooth_discovery *y, pa_bluetooth_device *d, DBusMessageIter *i) {
@@ -229,7 +230,10 @@ static int parse_device_property(pa_bluetooth_discovery *y, pa_bluetooth_device
PA_LLIST_PREPEND(pa_bluetooth_uuid, d->uuids, node);

/* Vudentz said the interfaces are here when the UUIDs are announced */
- if (strcasecmp(HSP_HS_UUID, value) == 0 || strcasecmp(HFP_HS_UUID, value) == 0) {
+ if (strcasecmp(HSP_AG_UUID, value) == 0 || strcasecmp(HFP_AG_UUID, value) == 0) {
+ pa_assert_se(m = dbus_message_new_method_call("org.bluez", d->path, "org.bluez.HandsfreeGateway", "GetProperties"));
+ send_and_add_to_pending(y, d, m, get_properties_reply);
+ } else if (strcasecmp(HSP_HS_UUID, value) == 0 || strcasecmp(HFP_HS_UUID, value) == 0) {
pa_assert_se(m = dbus_message_new_method_call("org.bluez", d->path, "org.bluez.Headset", "GetProperties"));
send_and_add_to_pending(y, d, m, get_properties_reply);
} else if (strcasecmp(A2DP_SINK_UUID, value) == 0) {
@@ -396,9 +400,14 @@ static void get_properties_reply(DBusPendingCall *pending, void *userdata) {
} else if (dbus_message_has_interface(p->message, "org.bluez.AudioSink")) {
if (parse_audio_property(y, &d->audio_sink_state, &dict_i) < 0)
goto finish;
+
} else if (dbus_message_has_interface(p->message, "org.bluez.AudioSource")) {
if (parse_audio_property(y, &d->audio_source_state, &dict_i) < 0)
goto finish;
+
+ } else if (dbus_message_has_interface(p->message, "org.bluez.HandsfreeGateway")) {
+ if (parse_audio_property(y, &d->hfgw_state, &arg_i) < 0)
+ goto finish;
}
}

@@ -626,6 +635,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
dbus_message_is_signal(m, "org.bluez.Headset", "PropertyChanged") ||
dbus_message_is_signal(m, "org.bluez.AudioSink", "PropertyChanged") ||
dbus_message_is_signal(m, "org.bluez.AudioSource", "PropertyChanged") ||
+ dbus_message_is_signal(m, "org.bluez.HandsfreeGateway", "PropertyChanged") ||
dbus_message_is_signal(m, "org.bluez.Device", "PropertyChanged")) {

pa_bluetooth_device *d;
@@ -653,9 +663,14 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
} else if (dbus_message_has_interface(m, "org.bluez.AudioSink")) {
if (parse_audio_property(y, &d->audio_sink_state, &arg_i) < 0)
goto fail;
+
} else if (dbus_message_has_interface(m, "org.bluez.AudioSource")) {
if (parse_audio_property(y, &d->audio_source_state, &arg_i) < 0)
goto fail;
+
+ } else if (dbus_message_has_interface(m, "org.bluez.HandsfreeGateway")) {
+ if (parse_audio_property(y, &d->hfgw_state, &arg_i) < 0)
+ goto fail;
}

run_callback(y, d, FALSE);
@@ -672,6 +687,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
d->audio_sink_state = PA_BT_AUDIO_STATE_DISCONNECTED;
d->audio_source_state = PA_BT_AUDIO_STATE_DISCONNECTED;
d->headset_state = PA_BT_AUDIO_STATE_DISCONNECTED;
+ d->hfgw_state = PA_BT_AUDIO_STATE_DISCONNECTED;

run_callback(y, d, FALSE);
}
@@ -801,7 +817,9 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) {
"type='signal',sender='org.bluez',interface='org.bluez.Audio',member='PropertyChanged'",
"type='signal',sender='org.bluez',interface='org.bluez.Headset',member='PropertyChanged'",
"type='signal',sender='org.bluez',interface='org.bluez.AudioSink',member='PropertyChanged'",
- "type='signal',sender='org.bluez',interface='org.bluez.AudioSource',member='PropertyChanged'", NULL) < 0) {
+ "type='signal',sender='org.bluez',interface='org.bluez.AudioSource',member='PropertyChanged'",
+ "type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged'",
+ NULL) < 0) {
pa_log("Failed to add D-Bus matches: %s", err.message);
goto fail;
}
@@ -855,7 +873,9 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) {
"type='signal',sender='org.bluez',interface='org.bluez.Audio',member='PropertyChanged'",
"type='signal',sender='org.bluez',interface='org.bluez.Headset',member='PropertyChanged'",
"type='signal',sender='org.bluez',interface='org.bluez.AudioSink',member='PropertyChanged'",
- "type='signal',sender='org.bluez',interface='org.bluez.AudioSource',member='PropertyChanged'", NULL);
+ "type='signal',sender='org.bluez',interface='org.bluez.AudioSource',member='PropertyChanged'",
+ "type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged'",
+ NULL);

dbus_connection_remove_filter(pa_dbus_connection_get(y->connection), filter_cb, y);

diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h
index e2a0c3d..9cee3de 100644
--- a/src/modules/bluetooth/bluetooth-util.h
+++ b/src/modules/bluetooth/bluetooth-util.h
@@ -89,6 +89,9 @@ struct pa_bluetooth_device {

/* Headset state */
pa_bt_audio_state_t headset_state;
+
+ /* HandsfreeGateway state */
+ pa_bt_audio_state_t hfgw_state;
};

pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *core);
diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c
index 0ba1421..f383aa7 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -71,7 +71,7 @@ PA_MODULE_USAGE(
"source_name=<name for the source> "
"source_properties=<properties for the source> "
"address=<address of the device> "
- "profile=<a2dp|hsp> "
+ "profile=<a2dp|hsp|hfgw> "
"rate=<sample rate> "
"channels=<number of channels> "
"path=<device object path> "
@@ -133,6 +133,7 @@ enum profile {
PROFILE_A2DP,
PROFILE_A2DP_SOURCE,
PROFILE_HSP,
+ PROFILE_HFGW,
PROFILE_OFF
};

@@ -316,12 +317,12 @@ static int parse_caps(struct userdata *u, uint8_t seid, const struct bt_get_capa
pa_log_debug("Payload size is %lu %lu", (unsigned long) bytes_left, (unsigned long) sizeof(*codec));

if (((u->profile == PROFILE_A2DP || u->profile == PROFILE_A2DP_SOURCE) && codec->transport != BT_CAPABILITIES_TRANSPORT_A2DP) ||
- (u->profile == PROFILE_HSP && codec->transport != BT_CAPABILITIES_TRANSPORT_SCO)) {
+ ((u->profile == PROFILE_HSP || u->profile == PROFILE_HFGW) && codec->transport != BT_CAPABILITIES_TRANSPORT_SCO)) {
pa_log_error("Got capabilities for wrong codec.");
return -1;
}

- if (u->profile == PROFILE_HSP) {
+ if (u->profile == PROFILE_HSP || u->profile == PROFILE_HFGW) {

if (bytes_left <= 0 || codec->length != sizeof(u->hsp.pcm_capabilities))
return -1;
@@ -399,7 +400,7 @@ static int get_caps(struct userdata *u, uint8_t seid) {
if (u->profile == PROFILE_A2DP || u->profile == PROFILE_A2DP_SOURCE)
msg.getcaps_req.transport = BT_CAPABILITIES_TRANSPORT_A2DP;
else {
- pa_assert(u->profile == PROFILE_HSP);
+ pa_assert(u->profile == PROFILE_HSP || u->profile == PROFILE_HFGW);
msg.getcaps_req.transport = BT_CAPABILITIES_TRANSPORT_SCO;
}
msg.getcaps_req.flags = u->auto_connect ? BT_FLAG_AUTOCONNECT : 0;
@@ -695,7 +696,7 @@ static int set_conf(struct userdata *u) {
if (setup_a2dp(u) < 0)
return -1;
} else {
- pa_assert(u->profile == PROFILE_HSP);
+ pa_assert(u->profile == PROFILE_HSP || u->profile == PROFILE_HFGW);

u->sample_spec.format = PA_SAMPLE_S16LE;
u->sample_spec.channels = 1;
@@ -987,7 +988,7 @@ static int hsp_process_render(struct userdata *u) {
int ret = 0;

pa_assert(u);
- pa_assert(u->profile == PROFILE_HSP);
+ pa_assert(u->profile == PROFILE_HSP || u->profile == PROFILE_HFGW);
pa_assert(u->sink);

/* First, render some data */
@@ -1052,7 +1053,7 @@ static int hsp_process_push(struct userdata *u) {
pa_memchunk memchunk;

pa_assert(u);
- pa_assert(u->profile == PROFILE_HSP);
+ pa_assert(u->profile == PROFILE_HSP || u->profile == PROFILE_HFGW);
pa_assert(u->source);
pa_assert(u->read_smoother);

@@ -1426,7 +1427,7 @@ static void thread_func(void *userdata) {
if (pollfd && (pollfd->revents & POLLIN)) {
int n_read;

- if (u->profile == PROFILE_HSP)
+ if (u->profile == PROFILE_HSP || PROFILE_HFGW)
n_read = hsp_process_push(u);
else
n_read = a2dp_process_push(u);
@@ -1834,7 +1835,7 @@ static int add_source(struct userdata *u) {
data.module = u->module;
pa_source_new_data_set_sample_spec(&data, &u->sample_spec);
pa_proplist_sets(data.proplist, "bluetooth.protocol", u->profile == PROFILE_A2DP_SOURCE ? "a2dp_source" : "hsp");
- if (u->profile == PROFILE_HSP)
+ if ((u->profile == PROFILE_HSP) || (u->profile == PROFILE_HFGW))
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
data.card = u->card;
data.name = get_name("source", u->modargs, u->address, &b);
@@ -1862,8 +1863,10 @@ static int add_source(struct userdata *u) {
pa_bytes_to_usec(u->block_size, &u->sample_spec));
}

- if (u->profile == PROFILE_HSP) {
+ if (u->profile == PROFILE_HSP || u->profile == PROFILE_HFGW)
pa_proplist_sets(u->source->proplist, "bluetooth.nrec", (u->hsp.pcm_capabilities.flags & BT_PCM_FLAG_NREC) ? "1" : "0");
+
+ if (u->profile == PROFILE_HSP) {
u->source->set_volume = source_set_volume_cb;
u->source->n_volume_steps = 16;
}
@@ -1951,12 +1954,14 @@ static int init_profile(struct userdata *u) {
return -1;

if (u->profile == PROFILE_A2DP ||
- u->profile == PROFILE_HSP)
+ u->profile == PROFILE_HSP ||
+ u->profile == PROFILE_HFGW)
if (add_sink(u) < 0)
r = -1;

if (u->profile == PROFILE_HSP ||
- u->profile == PROFILE_A2DP_SOURCE)
+ u->profile == PROFILE_A2DP_SOURCE ||
+ u->profile == PROFILE_HFGW)
if (add_source(u) < 0)
r = -1;

@@ -2091,6 +2096,10 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
pa_log_warn("A2DP is not connected, refused to switch profile");
return -PA_ERR_IO;
}
+ else if (device->hfgw_state <= PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_HFGW) {
+ pa_log_warn("HandsfreeGateway is not connected, refused to switch profile");
+ return -PA_ERR_IO;
+ }

if (u->sink) {
inputs = pa_sink_move_all_start(u->sink, NULL);
@@ -2226,6 +2235,20 @@ static int add_card(struct userdata *u, const pa_bluetooth_device *device) {
pa_hashmap_put(data.profiles, p->name, p);
}

+ if (pa_bluetooth_uuid_has(device->uuids, HFP_AG_UUID)) {
+ p = pa_card_profile_new("hfgw", _("Handsfree Gateway"), sizeof(enum profile));
+ p->priority = 20;
+ p->n_sinks = 1;
+ p->n_sources = 1;
+ p->max_sink_channels = 1;
+ p->max_source_channels = 1;
+
+ d = PA_CARD_PROFILE_DATA(p);
+ *d = PROFILE_HFGW;
+
+ pa_hashmap_put(data.profiles, p->name, p);
+ }
+
pa_assert(!pa_hashmap_isempty(data.profiles));

p = pa_card_profile_new("off", _("Off"), sizeof(enum profile));
@@ -2254,7 +2277,8 @@ static int add_card(struct userdata *u, const pa_bluetooth_device *device) {
d = PA_CARD_PROFILE_DATA(u->card->active_profile);

if ((device->headset_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_HSP) ||
- (device->audio_sink_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_A2DP)) {
+ (device->audio_sink_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_A2DP) ||
+ (device->hfgw_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_HFGW)) {
pa_log_warn("Default profile not connected, selecting off profile");
u->card->active_profile = pa_hashmap_get(u->card->profiles, "off");
u->card->save_profile = FALSE;
diff --git a/src/modules/bluetooth/module-bluetooth-discover.c b/src/modules/bluetooth/module-bluetooth-discover.c
index 0085fa8..fd34c6f 100644
--- a/src/modules/bluetooth/module-bluetooth-discover.c
+++ b/src/modules/bluetooth/module-bluetooth-discover.c
@@ -83,8 +83,10 @@ static pa_hook_result_t load_module_for_device(pa_bluetooth_discovery *y, const

mi = pa_hashmap_get(u->hashmap, d->path);

- if (!d->dead &&
- d->device_connected > 0 && (d->audio_state >= PA_BT_AUDIO_STATE_CONNECTED || d->audio_source_state >= PA_BT_AUDIO_STATE_CONNECTED)) {
+ if (!d->dead && d->device_connected > 0 &&
+ (d->audio_state >= PA_BT_AUDIO_STATE_CONNECTED ||
+ d->audio_source_state >= PA_BT_AUDIO_STATE_CONNECTED ||
+ d->hfgw_state > PA_BT_AUDIO_STATE_CONNECTED)) {

if (!mi) {
pa_module *m = NULL;
@@ -119,6 +121,9 @@ static pa_hook_result_t load_module_for_device(pa_bluetooth_discovery *y, const
if (d->audio_source_state >= PA_BT_AUDIO_STATE_CONNECTED)
args = pa_sprintf_malloc("%s profile=\"a2dp_source\" auto_connect=no", args);

+ if (d->hfgw_state > PA_BT_AUDIO_STATE_CONNECTED)
+ args = pa_sprintf_malloc("%s profile=\"hfgw\"", args);
+
pa_log_debug("Loading module-bluetooth-device %s", args);
m = pa_module_load(u->module->core, "module-bluetooth-device", args);
pa_xfree(args);
--
1.6.3.3


2010-01-29 14:44:25

by João Paulo Rechi Vita

[permalink] [raw]
Subject: [PATCH 1/2] bluetooth: improve dbus logging a little bit

From: João Paulo Rechi Vita <[email protected]>

---
src/modules/bluetooth/bluetooth-util.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c
index 47d6200..d3f3bfe 100644
--- a/src/modules/bluetooth/bluetooth-util.c
+++ b/src/modules/bluetooth/bluetooth-util.c
@@ -292,9 +292,10 @@ static int parse_audio_property(pa_bluetooth_discovery *u, int *state, DBusMessa
const char *value;
dbus_message_iter_get_basic(&variant_i, &value);

- if (pa_streq(key, "State"))
+ if (pa_streq(key, "State")) {
*state = pa_bt_audio_state_from_string(value);
-/* pa_log_debug("Value %s", value); */
+ pa_log_debug("dbus: property 'State' changed to value '%s'", value);
+ }

break;
}
--
1.6.3.3


2010-02-04 03:21:09

by Zhenhua Zhang

[permalink] [raw]
Subject: Re: [RFC] [PATCH 0/2] HFP AG integration with PulseAudio

SGkgSnBydml0YSwKCk9uIDAyLzA0LzIwMTAgMDI6MzAgQU0sIEpvw6NvIFBhdWxvIFJlY2hpIFZp
dGEgd3JvdGU6Cj4+Pgo+Pj4gSnVzdCB1cGRhdGluZywgdGhpcyBwYXRjaCBhY3R1YWxseSB3b3Jr
ZWQgd2hlbiB0ZXN0aW5nIHdpdGggYQo+Pj4gZGlmZmVyZW50IGFkYXB0ZXIgKEZ1aml0c3UtU2ll
bWVucyBDU1ItYmFzZWQpLiBUaGUgYWRhcHRlciBjYXVzaW5nCj4+PiBwcm9ibGVtcyB3YXMgYSBC
cm9hZGNvbSAyLjEsIHRoZSBpbnRlcm5hbCBhZGFwdGVyIG9mIGEgRGVsbCBNaW5pMTAuCj4+PiBB
bHNvLCBzdXNwZW5kaW5nIHRoZSBzb3VyY2UgLyBzaW5rIGFjdHVhbGx5IGRvZXNuJ3QgaW50ZXJm
ZXJlLgo+Pj4KPj4+IEkgZGlkIGEgc21hbGwgdmlkZW8gb2YgdGhlIHdob2xlIHN0dWZmOiBodHRw
Oi8vd3d3LnZpbWVvLmNvbS85MDc4Nzk5Cj4+Pgo+Pj4gVGhlcmUgYXJlIHN0aWxsIHNvbWUgcHJv
YmxlbXMgd2hlbiB0ZXN0aW5nIGFnYWluc3QgTm9raWEgTjkwMCBhbmQKPj4+IDI2NjAuIEFmdGVy
IHRoZSAiZW5hYmxlLW1vZGVtIiBzdGVwLCB0aGUgUkZDT01NIGxpbmsgaXMgY29ubmVjdGVkIGFu
ZAo+Pj4gdGhlIFNDTyBqdXN0IGFmdGVyIHRoYXQsIGxlYWRpbmcgbW9kdWxlLWJsdWV0b290aC1k
aXNjb3ZlciB0byBsb2FkCj4+PiBtb2R1bGUtYmx1ZXRvb3RoLWRldmljZS4gU29tZXRpbWVzIGFm
dGVyIHRoYXQgdGhlIHBvbGxpbmcgb24gdGhlCj4+PiBzdHJlYW0gZmQgZ2V0IGEgUE9MTEhVUCBh
bmQgdGhlIG1vZHVsZS1ibHVldG9vdGgtZGV2aWNlIHVubG9hZHMKPj4+IGl0c2VsZi4gT3RoZXIg
dGltZXMgdGhlIFBPTExIVVAgZG9lc24ndCBoYXBwZW4gYW5kIHRoZSByZW1haW5pbmcgc3RlcHMK
Pj4+IGdvIHdpdGhvdXQgYW55IHByb2JsZW0uCj4+Pgo+Pj4gSWRlYXMgb24gaG93IHRvIGltcHJv
dmUgdGhpcyBzY2VuYXJpbyB3aWxsIGJlIHZlcnkgaGVscGZ1bC4KPj4+Cj4+Pgo+Pgo+PiBUaGUg
b3V0cHV0IGZyb20gYmx1ZXRvb3RoZCBsaWtlcyBiZWxvdzoKPj4KPj4gYmx1ZXRvb3RoZFsyMTE0
MV06IEFjY2VwdGVkIEFHIGNvbm5lY3Rpb24gZnJvbSAwMDpCRDozQTpENDo0RTo1MyBmb3IKPj4g
L29yZy9ibHVlei8yMTE0MS9oY2kwL2Rldl8wMF9CRF8zQV9ENF80RV81Mwo+PiBibHVldG9vdGhk
WzIxMTQxXTogQWNjZXB0ZWQgU0NPIGNvbm5lY3Rpb24gZnJvbSAwMDpCRDozQTpENDo0RTo1Mwo+
PiBibHVldG9vdGhkWzIxMTQxXTogTm8gbWF0Y2hpbmcgY29ubmVjdGlvbiBmb3VuZCBmb3IgaGFu
ZGxlIDYKPj4gYmx1ZXRvb3RoZFsyMTE0MV06IHNjbyBjb25uZWN0aW9uIGlzIHJlbGVhc2VkCj4+
Cj4+IEkgdGhpbmsgeW91IHNob3VsZCBub3QgbG9hZCBtb2R1bGUtYmx1ZXRvb3RoLWRldmljZSB1
bnRpbCBhIHZvaWNlIGNhbGwgaXMKPj4gc3RhcnRlZCwgbm8gbWF0dGVyIGluY29taW5nIG9yIG91
dGdvaW5nLiBCZWNhdXNlIFBBIG1heSBwbGF5IG11c2ljIGZyb20KPj4gb3RoZXIgZGV2aWNlIGF0
IHRoZSBzYW1lIHRpbWUuIEFuZCBibHVldG9vdGgtZGV2aWNlIGFuZCBsb29wYmFjayBtb2R1bGUg
YXJlCj4+IGxvYWRlZCB0b2dldGhlci4gQWNjb3JkaW5nIHRvIEhGUCB2MS41IDQuMTMsIHRoZXJl
IGFyZSB0d28gY2FzZXMgZm9yCj4+IGluY29taW5nIGNhbGwuIEFuZCBvdXRnb2luZyBjYWxsIGlz
IHNpbXBsZXIgdGhhbiBpbmNvbWluZyBjYWxsLgo+Pgo+PiBJZiBBRyBhbmQgSEYgYm90aCBzdXBw
b3J0IGluIGJhbmQgcmluZyB0b25lcywgd2Ugc2hvdWxkIHNlbmQgYSBzaWduYWwgZnJvbQo+PiBv
Rm9ubyB0byBQQSB3aGVuIGNhbGxzZXR1cD0xLiBJZiBub3QsIHdlIHNob3VsZCBzZW5kIGl0IHdo
ZW4gY2FsbD0xLgo+Pgo+PiBJIGhhZCBhIHBhdGNoIG9yaWdpbmFsbHkgYnV0IEkgY2Fubm90IGZp
bmQgaXQgbm93LiA6LSguIFRoZSBiYXNpYyBpZGVhIGlzIHRvCj4+IGFkZCBhIGZpbHRlciBpbiBj
aWV2X25vdGlmeSgpIHRvIGVtaXQgc2lnbmFsIChDYWxsU3RhcnRlZCBhbmQgQ2FsbEVuZGVkKSB0
bwo+PiBQQS4gQW5kIFBBIGxvYWRzIG1vZHVsZSBvbmNlIGl0IGdvdCB0aGF0IHNpZ25hbC4gTWF5
YmUgdGhlIHNpZ25hbCBuYW1lIHdhcwo+PiBiYWQgYW5kIHlvdSBjb3VsZCBjaG9vc2UgYmV0dGVy
IG9uZSBhcyB5b3Ugd2FudC4gOy0pCj4+Cj4KPiBJIHRoaW5rIGxvYWRpbmcgbW9kdWxlLWJsdWV0
b290aC1kZXZpY2Ugb25seSB3aGVuIHRoZXJlIGlzIGFuIGFjdGl2ZQo+IGNhbGwgY2FuIGJlIGEg
Z29vZCBzb2x1dGlvbi4gQnV0IEknbSBjb25jZXJuZWQgYWJvdXQgb3RoZXIgYXVkaW8KPiBldmVu
dHMsIGkuIGUuOiByaW5naW5nLCBTTVMgbm90aWZpY2F0aW9uIGV0Yy46IGRvZXNuJ3QgdGhlIEFH
Cj4gZXN0YWJsaXNoZXMgYSBTQ08gY2hhbm5lbCBmb3IgdGhlIHRoZXNlIGV2ZW50cz8gQWxzbywg
SSBkb24ndCB0aGluawo+IHB1bHNlIHNob3VsZCBsaXN0ZW4gdG8gb2Zvbm8gc2lnbmFscywgaXQg
c2hvdWxkIGJlIGFnZW50LWFnbm9zdGljLiBCdXQKPiBhIHNpZ25hbCBjb3VsZCBiZSBhZGRlZCB0
byB0aGUgYWdlbnQgaW50ZXJmYWNlIGluIHRoaXMgY2FzZS4KClllYWguIE1heWJlIHlvdSBhcmUg
cmlnaHQuIFBBIHNob3VsZCBub3QgbGlzdGVuIHRvIG9mb25vIHNpZ25hbCBkaXJlY3RseSAKYnV0
IHRocm91Z2ggYW4gYWdlbnQgc2lnbmFsIHRvIG1ha2UgaXQgbW9yZSBnZW5lcmljLiBBRkFLLCBT
TVMgCm5vdGlmaWNhdGlvbiBkb2Vzbid0IHJlcXVpcmUgU0NPLiBVcHBlciBhcHAgY291bGQgc2lt
cGx5IHdhdGNoIHRoZSAKcHJvcGVydHkgY2hhbmdlcyBmcm9tIG9Gb25vLgoKPiBBbmQgSSdtIG5v
dCBzdXJlIGlmIGF1dG9tYXRpY2FsbHkgbG9hZGluZyBtb2R1bGUtbG9vcGJhY2sgaXMgYSBnb29k
Cj4gaWRlYSwgSSB0aGluayB3ZSBiZXR0ZXIgZXhwb3NlIHRocm91Z2ggdGhlIFVJIGhvdyB0byBo
YW5kbGUgdGhlIGF1ZGlvCj4gc3RyZWFtLiBTb21lIHVzZXJzIG1heSBoYXZlIGEgYnVuY2ggb2Yg
c291bmRjYXJkcyBvciBzb21lIHZlcnkgd2VpcmQKPiBhdWRpbyBzZXR1cCwgYW5kIGl0J3MgdXAg
dG8gdGhlbSB0byBkZWNpZGUgd2hpY2ggc291bmRjYXJkIHRvIGNvbm5lY3QKPiB0aGUgSEZQIHN0
cmVhbS4KPgoKSSBhbSBub3QgYXVkaW8gZXhwZXJ0IGJ1dCBBRkFLIFBBIGhhcyB2YXJpYW50IHBv
bGljaWVzIHRvIGNvbnRyb2wgd2hpY2ggCmF1ZGlvIHN0cmVhbSBzaG91bGQgYmUgZmVlZGVkIGlu
dG8gdGhlIHNwZWFrZXIvbWljLiBMb2FkaW5nIAptb2R1bGUtYmx1ZXRvb3RoLWRldmljZSBpcyBv
bmx5IHRoZSAxc3Qgc3RlcCB0byBjcmVhdGUgc291cmNlL3NpbmsuIEkgCnRoaW5rIHRoZSB2b2lj
ZWNhbGwgaGF2ZSB0aGUgaGlnaGVyIHByaW9yaXR5IHRoYW4gb3RoZXIgc3RlYW0gbGlrZSAKbXVz
aWMsIGV0Yy4gQW5kIHllcywgbG9hZGluZyBtb2R1bGUtbG9vcGJhY2sgY291bGQgYmUgZGVjaWRl
ZCBieSBQQSBwb2xpY3kuCgpUaGFua3MuClpoZW5odWEuCgpfX19fX19fX19fX19fX19fX19fX19f
X19fX19fX19fX19fX19fX19fX19fX19fXwpvZm9ubyBtYWlsaW5nIGxpc3QKb2Zvbm9Ab2Zvbm8u
b3JnCmh0dHA6Ly9saXN0cy5vZm9uby5vcmcvbGlzdGluZm8vb2Zvbm8K

2010-02-03 18:30:03

by João Paulo Rechi Vita

[permalink] [raw]
Subject: Re: [RFC] [PATCH 0/2] HFP AG integration with PulseAudio

On Tue, Feb 2, 2010 at 01:50, Zhenhua Zhang <[email protected]> wrote:
> Hi Jprvita,
>
> On 02/02/2010 01:09 AM, João Paulo Rechi Vita wrote:
>>
>> 2010/1/29 João Paulo Rechi Vita<[email protected]>:
>>
>>>
>>> Hi all,
>>>
>>> I'm trying to add support for the Handsfree Gateway role Gustavo just
>>> added
>>> to BlueZ and oFono. The BlueZ patches can be found on [1] and [2] and the
>>> oFono part was just merged upstream.
>>>
>>> But when it comes to integrate them with Pulse, I'm getting a POLLHUP
>>> when
>>> trying to write on the fd. Also, it seems different gateways have
>>> different
>>> behaviours regarding when they connect the SCO link. Some phone connect
>>> them just after the RFCOMM link (some Nokia phones), when there is no
>>> call
>>> going on yet, and others just when a call is started (Android 1.5).
>>>
>>> Also, right now the same property (State) is beeing used to refer when
>>> the
>>> RFCOOM link is established (State=Connected) and when the SCO link is
>>> established (State=Playing). Shouldn't this be handled by separate props?
>>>
>>> And last but not least, is the new Media API intended to handle the audio
>>> part of handsfree gateways too? If so, maybe we should use all this work
>>> as a prototype for latter integration with the new API.
>>>
>>> Any help on testing and getting this working together or comments on the
>>> topic would be appreciated.
>>>
>>> [1] http://www.spinics.net/lists/linux-bluetooth/msg04250.html
>>> [2] http://www.spinics.net/lists/linux-bluetooth/msg04251.html
>>>
>>> --
>>> João Paulo Rechi Vita
>>> http://jprvita.wordpress.com/
>>>
>>>
>>>
>>
>> Just updating, this patch actually worked when testing with a
>> different adapter (Fujitsu-Siemens CSR-based). The adapter causing
>> problems was a Broadcom 2.1, the internal adapter of a Dell Mini10.
>> Also, suspending the source / sink actually doesn't interfere.
>>
>> I did a small video of the whole stuff: http://www.vimeo.com/9078799
>>
>> There are still some problems when testing against Nokia N900 and
>> 2660. After the "enable-modem" step, the RFCOMM link is connected and
>> the SCO just after that, leading module-bluetooth-discover to load
>> module-bluetooth-device. Sometimes after that the polling on the
>> stream fd get a POLLHUP and the module-bluetooth-device unloads
>> itself. Other times the POLLHUP doesn't happen and the remaining steps
>> go without any problem.
>>
>> Ideas on how to improve this scenario will be very helpful.
>>
>>
>
> The output from bluetoothd likes below:
>
> bluetoothd[21141]: Accepted AG connection from 00:BD:3A:D4:4E:53 for
> /org/bluez/21141/hci0/dev_00_BD_3A_D4_4E_53
> bluetoothd[21141]: Accepted SCO connection from 00:BD:3A:D4:4E:53
> bluetoothd[21141]: No matching connection found for handle 6
> bluetoothd[21141]: sco connection is released
>
> I think you should not load module-bluetooth-device until a voice call is
> started, no matter incoming or outgoing. Because PA may play music from
> other device at the same time. And bluetooth-device and loopback module are
> loaded together. According to HFP v1.5 4.13, there are two cases for
> incoming call. And outgoing call is simpler than incoming call.
>
> If AG and HF both support in band ring tones, we should send a signal from
> oFono to PA when callsetup=1. If not, we should send it when call=1.
>
> I had a patch originally but I cannot find it now. :-(. The basic idea is to
> add a filter in ciev_notify() to emit signal (CallStarted and CallEnded) to
> PA. And PA loads module once it got that signal. Maybe the signal name was
> bad and you could choose better one as you want. ;-)
>

I think loading module-bluetooth-device only when there is an active
call can be a good solution. But I'm concerned about other audio
events, i. e.: ringing, SMS notification etc.: doesn't the AG
establishes a SCO channel for the these events? Also, I don't think
pulse should listen to ofono signals, it should be agent-agnostic. But
a signal could be added to the agent interface in this case.

And I'm not sure if automatically loading module-loopback is a good
idea, I think we better expose through the UI how to handle the audio
stream. Some users may have a bunch of soundcards or some very weird
audio setup, and it's up to them to decide which soundcard to connect
the HFP stream.

--
João Paulo Rechi Vita
http://jprvita.wordpress.com/

2010-02-02 17:03:57

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [RFC] [PATCH 0/2] HFP AG integration with PulseAudio

Hi,

2010/1/29 Jo?o Paulo Rechi Vita <[email protected]>:
> Hi all,
>
> I'm trying to add support for the Handsfree Gateway role Gustavo just added
> to BlueZ and oFono. The BlueZ patches can be found on [1] and [2] and the
> oFono part was just merged upstream.
>
> But when it comes to integrate them with Pulse, I'm getting a POLLHUP when
> trying to write on the fd. Also, it seems different gateways have different
> behaviours regarding when they connect the SCO link. Some phone connect
> them just after the RFCOMM link (some Nokia phones), when there is no call
> going on yet, and others just when a call is started (Android 1.5).
>
> Also, right now the same property (State) is beeing used to refer when the
> RFCOOM link is established (State=Connected) and when the SCO link is
> established (State=Playing). Shouldn't this be handled by separate props?
>
> And last but not least, is the new Media API intended to handle the audio
> part of handsfree gateways too? If so, maybe we should use all this work
> as a prototype for latter integration with the new API.

Yep, Media API is supposed to handle this, that why I asked them to be
though in an integrated manner maybe being registered in the same
interface (although hfp is not really media only), anyway basically we
should have pa acting as a2dp source/sink and/or hfp gateway/headset
endpoint handling the audio. So in essence ofono is acting as a
controller/target in a very similar way as avrcp does for a2dp,
although for avrcp we don't really need an agent as we use uinput.

> Any help on testing and getting this working together or comments on the
> topic would be appreciated.

There is already some code in my git tree:
http://gitorious.org/~vudentz/bluez/vudentzs-clone/commits/for-upstream

--
Luiz Augusto von Dentz
Engenheiro de Computa??o

2010-02-02 03:50:26

by Zhenhua Zhang

[permalink] [raw]
Subject: Re: [RFC] [PATCH 0/2] HFP AG integration with PulseAudio

Hi Jprvita,

On 02/02/2010 01:09 AM, João Paulo Rechi Vita wrote:
> 2010/1/29 João Paulo Rechi Vita<[email protected]>:
>
>> Hi all,
>>
>> I'm trying to add support for the Handsfree Gateway role Gustavo just added
>> to BlueZ and oFono. The BlueZ patches can be found on [1] and [2] and the
>> oFono part was just merged upstream.
>>
>> But when it comes to integrate them with Pulse, I'm getting a POLLHUP when
>> trying to write on the fd. Also, it seems different gateways have different
>> behaviours regarding when they connect the SCO link. Some phone connect
>> them just after the RFCOMM link (some Nokia phones), when there is no call
>> going on yet, and others just when a call is started (Android 1.5).
>>
>> Also, right now the same property (State) is beeing used to refer when the
>> RFCOOM link is established (State=Connected) and when the SCO link is
>> established (State=Playing). Shouldn't this be handled by separate props?
>>
>> And last but not least, is the new Media API intended to handle the audio
>> part of handsfree gateways too? If so, maybe we should use all this work
>> as a prototype for latter integration with the new API.
>>
>> Any help on testing and getting this working together or comments on the
>> topic would be appreciated.
>>
>> [1] http://www.spinics.net/lists/linux-bluetooth/msg04250.html
>> [2] http://www.spinics.net/lists/linux-bluetooth/msg04251.html
>>
>> --
>> João Paulo Rechi Vita
>> http://jprvita.wordpress.com/
>>
>>
>>
> Just updating, this patch actually worked when testing with a
> different adapter (Fujitsu-Siemens CSR-based). The adapter causing
> problems was a Broadcom 2.1, the internal adapter of a Dell Mini10.
> Also, suspending the source / sink actually doesn't interfere.
>
> I did a small video of the whole stuff: http://www.vimeo.com/9078799
>
> There are still some problems when testing against Nokia N900 and
> 2660. After the "enable-modem" step, the RFCOMM link is connected and
> the SCO just after that, leading module-bluetooth-discover to load
> module-bluetooth-device. Sometimes after that the polling on the
> stream fd get a POLLHUP and the module-bluetooth-device unloads
> itself. Other times the POLLHUP doesn't happen and the remaining steps
> go without any problem.
>
> Ideas on how to improve this scenario will be very helpful.
>
>

The output from bluetoothd likes below:

bluetoothd[21141]: Accepted AG connection from 00:BD:3A:D4:4E:53 for
/org/bluez/21141/hci0/dev_00_BD_3A_D4_4E_53
bluetoothd[21141]: Accepted SCO connection from 00:BD:3A:D4:4E:53
bluetoothd[21141]: No matching connection found for handle 6
bluetoothd[21141]: sco connection is released

I think you should not load module-bluetooth-device until a voice call
is started, no matter incoming or outgoing. Because PA may play music
from other device at the same time. And bluetooth-device and loopback
module are loaded together. According to HFP v1.5 4.13, there are two
cases for incoming call. And outgoing call is simpler than incoming call.

If AG and HF both support in band ring tones, we should send a signal
from oFono to PA when callsetup=1. If not, we should send it when call=1.

I had a patch originally but I cannot find it now. :-(. The basic idea
is to add a filter in ciev_notify() to emit signal (CallStarted and
CallEnded) to PA. And PA loads module once it got that signal. Maybe the
signal name was bad and you could choose better one as you want. ;-)

Thanks.
Zhenhua


2010-02-02 01:38:31

by Zhenhua Zhang

[permalink] [raw]
Subject: Re: [RFC] [PATCH 0/2] HFP AG integration with PulseAudio

Hi Jprvita,

On 02/02/2010 01:09 AM, João Paulo Rechi Vita wrote:
> 2010/1/29 João Paulo Rechi Vita<[email protected]>:
>
>> Hi all,
>>
>> I'm trying to add support for the Handsfree Gateway role Gustavo just added
>> to BlueZ and oFono. The BlueZ patches can be found on [1] and [2] and the
>> oFono part was just merged upstream.
>>
>> But when it comes to integrate them with Pulse, I'm getting a POLLHUP when
>> trying to write on the fd. Also, it seems different gateways have different
>> behaviours regarding when they connect the SCO link. Some phone connect
>> them just after the RFCOMM link (some Nokia phones), when there is no call
>> going on yet, and others just when a call is started (Android 1.5).
>>
>> Also, right now the same property (State) is beeing used to refer when the
>> RFCOOM link is established (State=Connected) and when the SCO link is
>> established (State=Playing). Shouldn't this be handled by separate props?
>>
>> And last but not least, is the new Media API intended to handle the audio
>> part of handsfree gateways too? If so, maybe we should use all this work
>> as a prototype for latter integration with the new API.
>>
>> Any help on testing and getting this working together or comments on the
>> topic would be appreciated.
>>
>> [1] http://www.spinics.net/lists/linux-bluetooth/msg04250.html
>> [2] http://www.spinics.net/lists/linux-bluetooth/msg04251.html
>>
>> --
>> João Paulo Rechi Vita
>> http://jprvita.wordpress.com/
>>
>>
>>
> Just updating, this patch actually worked when testing with a
> different adapter (Fujitsu-Siemens CSR-based). The adapter causing
> problems was a Broadcom 2.1, the internal adapter of a Dell Mini10.
> Also, suspending the source / sink actually doesn't interfere.
>
> I did a small video of the whole stuff: http://www.vimeo.com/907879
>

Good work! Looks like it works pretty fine. :-). At the last of video, I
saw you load loopback module manually. Zheng Huan made a patch to load
loopback automatically. I believe Padovan has a copy of that. You may
also integrate it with upstream.

> There are still some problems when testing against Nokia N900 and
> 2660. After the "enable-modem" step, the RFCOMM link is connected and
> the SCO just after that, leading module-bluetooth-discover to load
> module-bluetooth-device. Sometimes after that the polling on the
> stream fd get a POLLHUP and the module-bluetooth-device unloads
> itself. Other times the POLLHUP doesn't happen and the remaining steps
> go without any problem.
>
> Ideas on how to improve this scenario will be very helpful.
>
>

AFAK, the SCO connection request is from AG side and BlueZ will check if
no SCO stream comes from AG(??), it will shutdown the connection. In my
memory, I don't get POLLHUP event in my original patch. You can turn on
debug flag to see more BlueZ output.


2010-02-01 17:09:36

by João Paulo Rechi Vita

[permalink] [raw]
Subject: Re: [RFC] [PATCH 0/2] HFP AG integration with PulseAudio

2010/1/29 João Paulo Rechi Vita <[email protected]>:
> Hi all,
>
> I'm trying to add support for the Handsfree Gateway role Gustavo just added
> to BlueZ and oFono. The BlueZ patches can be found on [1] and [2] and the
> oFono part was just merged upstream.
>
> But when it comes to integrate them with Pulse, I'm getting a POLLHUP when
> trying to write on the fd. Also, it seems different gateways have different
> behaviours regarding when they connect the SCO link. Some phone connect
> them just after the RFCOMM link (some Nokia phones), when there is no call
> going on yet, and others just when a call is started (Android 1.5).
>
> Also, right now the same property (State) is beeing used to refer when the
> RFCOOM link is established (State=Connected) and when the SCO link is
> established (State=Playing). Shouldn't this be handled by separate props?
>
> And last but not least, is the new Media API intended to handle the audio
> part of handsfree gateways too? If so, maybe we should use all this work
> as a prototype for latter integration with the new API.
>
> Any help on testing and getting this working together or comments on the
> topic would be appreciated.
>
> [1] http://www.spinics.net/lists/linux-bluetooth/msg04250.html
> [2] http://www.spinics.net/lists/linux-bluetooth/msg04251.html
>
> --
> João Paulo Rechi Vita
> http://jprvita.wordpress.com/
>
>

Just updating, this patch actually worked when testing with a
different adapter (Fujitsu-Siemens CSR-based). The adapter causing
problems was a Broadcom 2.1, the internal adapter of a Dell Mini10.
Also, suspending the source / sink actually doesn't interfere.

I did a small video of the whole stuff: http://www.vimeo.com/9078799

There are still some problems when testing against Nokia N900 and
2660. After the "enable-modem" step, the RFCOMM link is connected and
the SCO just after that, leading module-bluetooth-discover to load
module-bluetooth-device. Sometimes after that the polling on the
stream fd get a POLLHUP and the module-bluetooth-device unloads
itself. Other times the POLLHUP doesn't happen and the remaining steps
go without any problem.

Ideas on how to improve this scenario will be very helpful.

--
João Paulo Rechi Vita
http://jprvita.wordpress.com/