From: Mikel Astiz <[email protected]>

Dynamically change the size of the SCO packets according to the size of
the received ones.
---
This patch has been hanging around for some time since our last discussion [1].

I haven't been able to clarify why exactly this MTU change is needed, but it 
can be experimentally observed that several Bluetooth chips from different 
manufacturers behave similarly: when two SCO streams are set up, the size of 
the packets doubles.

My best guess is that it's influenced by the constraints in the USB transport 
layer, but I wasn't able to confirm this yet nor was I able to find such 
behavior in the Bluetooth spec.

In any case, I believe the patch should do no harm.

This v1 proposal rewrites the patch in a more conservative way. The MTU changes 
are accepted only if they match the known pattern of changing between 48 and 96 
back and forth.

You can test this patch by connecting two headsets (or two phones or whatever 
else doing HFP/HSP). You probably also need to change the adapter's SCO MTU by 
doing:

sudo ./hciconfig hci0 scomtu 96:8

[1] 
http://thread.gmane.org/gmane.comp.audio.pulseaudio.general/12982/focus=15363

 src/modules/bluetooth/module-bluetooth-device.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/src/modules/bluetooth/module-bluetooth-device.c 
b/src/modules/bluetooth/module-bluetooth-device.c
index c877df2..552db4b 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -625,7 +625,8 @@ static int hsp_process_push(struct userdata *u) {
     pa_assert(u->source);
     pa_assert(u->read_smoother);
 
-    memchunk.memblock = pa_memblock_new(u->core->mempool, u->read_block_size);
+    /* Read minimum 96 bytes to be able to detect multi-SCO setup */
+    memchunk.memblock = pa_memblock_new(u->core->mempool, PA_MAX(96U, 
u->read_block_size));
     memchunk.index = memchunk.length = 0;
 
     for (;;) {
@@ -681,6 +682,23 @@ static int hsp_process_push(struct userdata *u) {
             break;
         }
 
+        /* In order to support multi-SCO scenarios, adapt size of I/O blocks
+         * according to the size we just got, only considering the typical MTU
+         * changes observed in these cases */
+        if ((size_t) l != u->read_link_mtu && (l == 48U || l == 96U)) {
+            pa_log_info("SCO MTU change detected: %zu->%zd", 
u->write_block_size, l);
+
+            u->read_link_mtu = (size_t) l;
+            u->write_link_mtu = (size_t) l;
+
+            bt_transport_config_mtu(u);
+
+            if (u->write_memchunk.memblock) {
+                pa_memblock_unref(u->write_memchunk.memblock);
+                pa_memchunk_reset(&u->write_memchunk);
+            }
+        }
+
         memchunk.length = (size_t) l;
         u->read_index += (uint64_t) l;
 
-- 
1.8.1.2

_______________________________________________
pulseaudio-discuss mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Reply via email to