[pulseaudio-discuss] bluetooth: problem with old headset
Georg Chini
georg at chini.tk
Tue Mar 3 23:42:18 PST 2015
On 02.03.2015 23:02, Georg Chini wrote:
> 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?
>>>
>>
> 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.
Small correction, retrans_effort should be 0xff for D1 as well.
--- 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, 0xff }, /* 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)
More information about the pulseaudio-discuss
mailing list