bluetooth: problem with old headset

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 02.03.2015 07:41, Georg Chini wrote:
> On 23.02.2015 09:06, David Henningsson wrote:
>>
>>
>> On 2015-02-21 23:14, Georg Chini wrote:
>>> Hello,
>>>
>>>
>>>
>>> With the Plantronics 590, the connect() call in bluez5_sco_acquire_cb
>>> returns
>>> "Protocol not supported". The headset itself is functional, I tested
>>> with my mobile.
>>>
>> I've heard of this, but never seen it myself. I suspect it's a kernel 
>> regression, but I'm not sure. Does it work with older kernels? Like, 
>> one, two, three years old kernels or such?
>>
> I had the chance to test this over the weekend. Works with kernel 3.10.
> This was the oldest kernel I still had on my machine, so I'll do some 
> more
> investigations to see where exactly it breaks.
Yes, it is a kernel regression introduced in 3.12. There are two reasons 
why it does no longer
work:
1) The driver expects the headset to issue a sync connection finished 
event (0x2c), even
if the connection attempt fails, so that it can test various packet 
types until it succeeds.
My old headset does not do so, it just sends a command status event 
(0x0f) with the
status code 0x1a. So the driver tries its first option and then fails.
2) The headset apparently needs a retrans_effort of 0xff (whatever that 
parameter means)
instead of 0x01.

The following patch (for kernel 3.17.2) solves the issue for me. Even if 
this is
not the right approach it at least shows where the problem is.

--- a/net/bluetooth/hci_event.c 2014-10-30 17:43:25.000000000 +0100
+++ b/net/bluetooth/hci_event.c 2015-03-02 22:41:11.303887654 +0100
@@ -1738,6 +1738,8 @@
                         sco->state = BT_CLOSED;

-                       hci_proto_connect_cfm(sco, status);
-                       hci_conn_del(sco);
+                       if (!hci_setup_sync(sco, handle)) {
+                           hci_proto_connect_cfm(sco, status);
+                           hci_conn_del(sco);
+                        }
                 }
         }

--- a/net/bluetooth/hci_conn.c  2014-10-30 17:43:25.000000000 +0100
+++ b/net/bluetooth/hci_conn.c  2015-03-02 21:51:32.569179920 +0100
@@ -37,17 +37,18 @@
         u16 pkt_type;
         u16 max_latency;
+        u8 retrans_effort;
  };

  static const struct sco_param sco_param_cvsd[] = {
-       { EDR_ESCO_MASK & ~ESCO_2EV3, 0x000a }, /* S3 */
-       { EDR_ESCO_MASK & ~ESCO_2EV3, 0x0007 }, /* S2 */
-       { EDR_ESCO_MASK | ESCO_EV3,   0x0007 }, /* S1 */
-       { EDR_ESCO_MASK | ESCO_HV3,   0xffff }, /* D1 */
-       { EDR_ESCO_MASK | ESCO_HV1,   0xffff }, /* D0 */
+       { EDR_ESCO_MASK & ~ESCO_2EV3, 0x000a, 0x01 }, /* S3 */
+       { EDR_ESCO_MASK & ~ESCO_2EV3, 0x0007, 0x01 }, /* S2 */
+       { EDR_ESCO_MASK | ESCO_EV3,   0x0007, 0x01 }, /* S1 */
+       { EDR_ESCO_MASK | ESCO_HV3,   0xffff, 0x01 }, /* D1 */
+       { EDR_ESCO_MASK | ESCO_HV1,   0xffff, 0xff }, /* D0 */
  };

  static const struct sco_param sco_param_wideband[] = {
-       { EDR_ESCO_MASK & ~ESCO_2EV3, 0x000d }, /* T2 */
-       { EDR_ESCO_MASK | ESCO_EV3,   0x0008 }, /* T1 */
+       { EDR_ESCO_MASK & ~ESCO_2EV3, 0x000d, 0x02 }, /* T2 */
+       { EDR_ESCO_MASK | ESCO_EV3,   0x0008, 0x02 }, /* T1 */
  };

@@ -191,5 +192,4 @@
                 if (conn->attempt > ARRAY_SIZE(sco_param_wideband))
                         return false;
-               cp.retrans_effort = 0x02;
                 param = &sco_param_wideband[conn->attempt - 1];
                 break;
@@ -197,5 +197,4 @@
                 if (conn->attempt > ARRAY_SIZE(sco_param_cvsd))
                         return false;
-               cp.retrans_effort = 0x01;
                 param = &sco_param_cvsd[conn->attempt - 1];
                 break;
@@ -206,4 +205,5 @@
         cp.pkt_type = __cpu_to_le16(param->pkt_type);
         cp.max_latency = __cpu_to_le16(param->max_latency);
+       cp.retrans_effort = param->retrans_effort;

         if (hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp) 
< 0)



[Index of Archives]     [Linux Audio Users]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux