Open Source Telephony
 help / color / mirror / Atom feed
* [RFC] [PATCH 0/2] HFP AG integration with PulseAudio
@ 2010-01-29 14:44 =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
  2010-01-29 14:44 ` [PATCH 1/2] bluetooth: improve dbus logging a little bit =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita @ 2010-01-29 14:44 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 1304 bytes --]

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/


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/2] bluetooth: improve dbus logging a little bit
  2010-01-29 14:44 [RFC] [PATCH 0/2] HFP AG integration with PulseAudio =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
@ 2010-01-29 14:44 ` =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
  2010-01-29 14:44   ` [PATCH 2/2] bluetooth: add HFP Gateway support =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
  2010-01-29 14:53 ` [RFC] [PATCH 0/2] HFP AG integration with PulseAudio =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita @ 2010-01-29 14:44 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 947 bytes --]

From: João Paulo Rechi Vita <jprvita@profusion.mobi>

---
 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


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/2] bluetooth: add HFP Gateway support
  2010-01-29 14:44 ` [PATCH 1/2] bluetooth: improve dbus logging a little bit =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
@ 2010-01-29 14:44   ` =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
  0 siblings, 0 replies; 10+ messages in thread
From: =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita @ 2010-01-29 14:44 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 16551 bytes --]

From: João Paulo Rechi Vita <jprvita@profusion.mobi>

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


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [RFC] [PATCH 0/2] HFP AG integration with PulseAudio
  2010-01-29 14:44 [RFC] [PATCH 0/2] HFP AG integration with PulseAudio =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
  2010-01-29 14:44 ` [PATCH 1/2] bluetooth: improve dbus logging a little bit =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
@ 2010-01-29 14:53 ` =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
  2010-02-01 17:09 ` =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
  2010-02-02 17:03 ` Luiz Augusto von Dentz
  3 siblings, 0 replies; 10+ messages in thread
From: =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita @ 2010-01-29 14:53 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 1710 bytes --]

2010/1/29 João Paulo Rechi Vita <jprvita@gmail.com>:
> 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/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] [PATCH 0/2] HFP AG integration with PulseAudio
  2010-01-29 14:44 [RFC] [PATCH 0/2] HFP AG integration with PulseAudio =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
  2010-01-29 14:44 ` [PATCH 1/2] bluetooth: improve dbus logging a little bit =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
  2010-01-29 14:53 ` [RFC] [PATCH 0/2] HFP AG integration with PulseAudio =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
@ 2010-02-01 17:09 ` =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
  2010-02-02  1:38   ` Zhenhua Zhang
  2010-02-02  3:50   ` Zhenhua Zhang
  2010-02-02 17:03 ` Luiz Augusto von Dentz
  3 siblings, 2 replies; 10+ messages in thread
From: =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita @ 2010-02-01 17:09 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 2313 bytes --]

2010/1/29 João Paulo Rechi Vita <jprvita@gmail.com>:
> 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/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] [PATCH 0/2] HFP AG integration with PulseAudio
  2010-02-01 17:09 ` =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
@ 2010-02-02  1:38   ` Zhenhua Zhang
  2010-02-02  3:50   ` Zhenhua Zhang
  1 sibling, 0 replies; 10+ messages in thread
From: Zhenhua Zhang @ 2010-02-02  1:38 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 2933 bytes --]

Hi Jprvita,

On 02/02/2010 01:09 AM, João Paulo Rechi Vita wrote:
> 2010/1/29 João Paulo Rechi Vita<jprvita@gmail.com>:
>    
>> 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.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] [PATCH 0/2] HFP AG integration with PulseAudio
  2010-02-01 17:09 ` =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
  2010-02-02  1:38   ` Zhenhua Zhang
@ 2010-02-02  3:50   ` Zhenhua Zhang
  2010-02-03 18:30     ` =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
  1 sibling, 1 reply; 10+ messages in thread
From: Zhenhua Zhang @ 2010-02-02  3:50 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 3571 bytes --]

Hi Jprvita,

On 02/02/2010 01:09 AM, João Paulo Rechi Vita wrote:
> 2010/1/29 João Paulo Rechi Vita<jprvita@gmail.com>:
>    
>> 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


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] [PATCH 0/2] HFP AG integration with PulseAudio
  2010-01-29 14:44 [RFC] [PATCH 0/2] HFP AG integration with PulseAudio =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
                   ` (2 preceding siblings ...)
  2010-02-01 17:09 ` =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
@ 2010-02-02 17:03 ` Luiz Augusto von Dentz
  3 siblings, 0 replies; 10+ messages in thread
From: Luiz Augusto von Dentz @ 2010-02-02 17:03 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 1870 bytes --]

Hi,

2010/1/29 João Paulo Rechi Vita <jprvita@gmail.com>:
> 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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] [PATCH 0/2] HFP AG integration with PulseAudio
  2010-02-02  3:50   ` Zhenhua Zhang
@ 2010-02-03 18:30     ` =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
  2010-02-04  3:21       ` Zhenhua Zhang
  0 siblings, 1 reply; 10+ messages in thread
From: =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita @ 2010-02-03 18:30 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 4507 bytes --]

On Tue, Feb 2, 2010 at 01:50, Zhenhua Zhang <zhenhua.zhang@intel.com> wrote:
> Hi Jprvita,
>
> On 02/02/2010 01:09 AM, João Paulo Rechi Vita wrote:
>>
>> 2010/1/29 João Paulo Rechi Vita<jprvita@gmail.com>:
>>
>>>
>>> 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/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] [PATCH 0/2] HFP AG integration with PulseAudio
  2010-02-03 18:30     ` =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
@ 2010-02-04  3:21       ` Zhenhua Zhang
  0 siblings, 0 replies; 10+ messages in thread
From: Zhenhua Zhang @ 2010-02-04  3:21 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 3529 bytes --]

Hi Jprvita,

On 02/04/2010 02:30 AM, João Paulo Rechi Vita wrote:
>>>
>>> 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.

Yeah. Maybe you are right. PA should not listen to ofono signal directly 
but through an agent signal to make it more generic. AFAK, SMS 
notification doesn't require SCO. Upper app could simply watch the 
property changes from oFono.

> 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.
>

I am not audio expert but AFAK PA has variant policies to control which 
audio stream should be feeded into the speaker/mic. Loading 
module-bluetooth-device is only the 1st step to create source/sink. I 
think the voicecall have the higher priority than other steam like 
music, etc. And yes, loading module-loopback could be decided by PA policy.

Thanks.
Zhenhua.


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2010-02-04  3:21 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-29 14:44 [RFC] [PATCH 0/2] HFP AG integration with PulseAudio =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
2010-01-29 14:44 ` [PATCH 1/2] bluetooth: improve dbus logging a little bit =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
2010-01-29 14:44   ` [PATCH 2/2] bluetooth: add HFP Gateway support =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
2010-01-29 14:53 ` [RFC] [PATCH 0/2] HFP AG integration with PulseAudio =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
2010-02-01 17:09 ` =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
2010-02-02  1:38   ` Zhenhua Zhang
2010-02-02  3:50   ` Zhenhua Zhang
2010-02-03 18:30     ` =?unknown-8bit?q?Jo=C3=A3o?= Paulo Rechi Vita
2010-02-04  3:21       ` Zhenhua Zhang
2010-02-02 17:03 ` Luiz Augusto von Dentz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox