public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* Sniff mode issues regarding Sony Ericsson headsets: kernel patch proposal.
@ 2008-09-03 19:37 Fabien Chevalier
  2008-09-03 19:49 ` [Bluez-devel] " Marcel Holtmann
  2008-09-06 16:56 ` Brian Sammon
  0 siblings, 2 replies; 15+ messages in thread
From: Fabien Chevalier @ 2008-09-03 19:37 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: BlueZ development

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


Hi Marcel,

Due to job requirement, I recently fined tuned a kernel to work well 
with some Sony Erisson A2DP Headsets (namely Motorola HBH-DS970 and 
HBH-DS980): this means making sure to force the other side to exit sniff 
mode early on before the AVDTP signalling comes into play.

If i remember well we had a talk a while ago about the way the sniff 
mode was handled by the kernel due to various issues with some bluetooth 
keyboards. The conclusion we had at that time, the best way to handle 
this issue was to add a socket option on an L2CAP channel to force the 
other side to exit sniff mode even if it was the one who initially 
entered the sniff mode.

I used this approach and wrote & tested a patch against 2.6.26-mh3. 
Patch is attached and seems to solve the issue.

*but*

During validation testing we found yet another issue that seems to be 
related to the way we handle the sniff mode.
The syndrom is that if the user screws up at enterring the pin code 
during pairing bluez fails to close the acl connection properly,
which means subsequent attempts result in a "connection already exist" 
error. From the user point of view it is impossible to try to pair again 
to the same headset...which is quite annoying.
Below is an hci trace of the issue:
< ACL data: handle 1 flags 0x02 dlen 12
    L2CAP(s): Connect req: psm 25 scid 0x0040
 > HCI Event: Number of Completed Packets (0x13) plen 5
    handle 1 packets 1
 > ACL data: handle 1 flags 0x02 dlen 16
    L2CAP(s): Connect rsp: dcid 0x0051 scid 0x0040 result 1 status 1
      Connection pending - Authentication pending
 > HCI Event: PIN Code Request (0x16) plen 6
    bdaddr 00:1C:A4:2C:FA:4A
< HCI Command: PIN Code Request Reply (0x01|0x000d) plen 23
    bdaddr 00:1C:A4:2C:FA:4A len 4 pin '1111'
 > HCI Event: Command Complete (0x0e) plen 10
    PIN Code Request Reply (0x01|0x000d) ncmd 2
    status 0x00 bdaddr 00:1C:A4:2C:FA:4A
 > ACL data: handle 1 flags 0x02 dlen 16
    L2CAP(s): Connect rsp: dcid 0x0051 scid 0x0040 result 3 status 0
      Connection refused - security block
 > HCI Event: Mode Change (0x14) plen 6
    status 0x00 handle 1 mode 0x02 interval 2048
    Mode: Sniff
< HCI Command: Disconnect (0x01|0x0006) plen 3
    handle 1 reason 0x13
    Reason: Remote User Terminated Connection
 > HCI Event: Command Status (0x0f) plen 4
    Disconnect (0x01|0x0006) status 0x00 ncmd 1
 > HCI Event: Disconn Complete (0x05) plen 4
    status 0x0c handle 1 reason 0x1f
    Error: Command Disallowed
 > HCI Event: Command Status (0x0f) plen 4
    Unknown (0x00|0x0000) status 0x00 ncmd 2

I hacked the kernel to try to see if forcing the headset to exit sniff 
mode before sending disconnect would solve the issue.... well it did :-)
Trace below shows this working:
< ACL data: handle 1 flags 0x02 dlen 12
    L2CAP(s): Connect req: psm 25 scid 0x0040
 > HCI Event: Read Remote Supported Features (0x0b) plen 11
    status 0x00 handle 1
    Features: 0xff 0x2e 0x2d 0xfa 0x98 0x39 0x00 0x80
 > HCI Event: Command Status (0x0f) plen 4
    Unknown (0x00|0x0000) status 0x00 ncmd 1
 > HCI Event: Command Complete (0x0e) plen 6
    Write Link Policy Settings (0x02|0x000d) ncmd 2
    status 0x00 handle 1
 > HCI Event: Number of Completed Packets (0x13) plen 5
    handle 1 packets 1
 > ACL data: handle 1 flags 0x02 dlen 16
    L2CAP(s): Connect rsp: dcid 0x0053 scid 0x0040 result 1 status 1
      Connection pending - Authentication pending
 > HCI Event: PIN Code Request (0x16) plen 6
    bdaddr 00:1C:A4:2C:FA:4A
< HCI Command: PIN Code Request Reply (0x01|0x000d) plen 23
    bdaddr 00:1C:A4:2C:FA:4A len 4 pin '1111'
 > HCI Event: Command Complete (0x0e) plen 10
    PIN Code Request Reply (0x01|0x000d) ncmd 2
    status 0x00 bdaddr 00:1C:A4:2C:FA:4A
 > ACL data: handle 1 flags 0x02 dlen 16
    L2CAP(s): Connect rsp: dcid 0x0053 scid 0x0040 result 3 status 0
      Connection refused - security block
 > HCI Event: Mode Change (0x14) plen 6
    status 0x00 handle 1 mode 0x02 interval 2048
    Mode: Sniff
< HCI Command: Exit Sniff Mode (0x02|0x0004) plen 2
    handle 1
 > HCI Event: Command Status (0x0f) plen 4
    Exit Sniff Mode (0x02|0x0004) status 0x00 ncmd 1
< HCI Command: Disconnect (0x01|0x0006) plen 3
    handle 1 reason 0x13
    Reason: Remote User Terminated Connection
 > HCI Event: Command Status (0x0f) plen 4
    Disconnect (0x01|0x0006) status 0x00 ncmd 0
 > HCI Event: Mode Change (0x14) plen 6
    status 0x00 handle 1 mode 0x00 interval 0
    Mode: Active
 > HCI Event: Command Status (0x0f) plen 4
    Unknown (0x00|0x0000) status 0x00 ncmd 1
 > HCI Event: Disconn Complete (0x05) plen 4
    status 0x00 handle 1 reason 0x16
    Reason: Connection Terminated by Local Host
 > HCI Event: Command Status (0x0f) plen 4
    Unknown (0x00|0x0000) status 0x00 ncmd 2

Conclusion: to have those bloody Sony Erisson headsets working we have 
to change two things in the kernel:
  1) Provide a way for a L2CAP socket user to alter sniff mode exit 
behaviour
  2) Make sure we exit sniff mode before to disconnect

Question 1: Are you interested in reviewing then merging my patches if i 
try to fix thoses issues ?
Question 2: I have the gut feeling that we should change default 
behaviour to the behaviour required by those headsets, and provide a 
socket option for the bluetooth HID, rather than the other way round. 
What do you think ?

If we can come on an agreement on the proper way to fix this issue then 
i should come with a patch in a 3-4 days timeframe.

Regards,

Fabien




[-- Attachment #2: a2dp-sniff-mode-issue.diff --]
[-- Type: text/plain, Size: 3306 bytes --]

diff -ru -x '*.so' -x '*.lds' -x '*.a' -x '*.elf' -x '.*' -x '*.order' -x '*.ko' -x '*.mod.c' -x '*.o' -x '*.cmd' linux-2.6.26/include/net/bluetooth/hci_core.h linux-2.6.26+mh3+fch/include/net/bluetooth/hci_core.h
--- linux-2.6.26/include/net/bluetooth/hci_core.h	2008-09-01 17:06:22.000000000 +0200
+++ linux-2.6.26+mh3+fch/include/net/bluetooth/hci_core.h	2008-09-01 12:22:36.000000000 +0200
@@ -170,6 +170,7 @@
 	__u32		 link_mode;
 	__u8             auth_type;
 	__u8             power_save;
+	__u8             force_active_mode;
 	unsigned long	 pend;
 
 	unsigned int	 sent;
diff -ru -x '*.so' -x '*.lds' -x '*.a' -x '*.elf' -x '.*' -x '*.order' -x '*.ko' -x '*.mod.c' -x '*.o' -x '*.cmd' linux-2.6.26/include/net/bluetooth/l2cap.h linux-2.6.26+mh3+fch/include/net/bluetooth/l2cap.h
--- linux-2.6.26/include/net/bluetooth/l2cap.h	2008-07-13 23:51:29.000000000 +0200
+++ linux-2.6.26+mh3+fch/include/net/bluetooth/l2cap.h	2008-09-01 16:20:17.000000000 +0200
@@ -62,6 +62,8 @@
 #define L2CAP_LM_RELIABLE	0x0010
 #define L2CAP_LM_SECURE		0x0020
 
+#define L2CAP_FORCE_ACTIVE_MODE	0x04
+
 /* L2CAP command codes */
 #define L2CAP_COMMAND_REJ 0x01
 #define L2CAP_CONN_REQ    0x02
Seulement dans linux-2.6.26+mh3+fch/kernel: bounds.s
Seulement dans linux-2.6.26+mh3+fch/kernel: timeconst.h
Seulement dans linux-2.6.26+mh3+fch/lib: crc32table.h
Seulement dans linux-2.6.26+mh3+fch/lib: gen_crc32table
Seulement dans linux-2.6.26+mh3+fch/: Module.symvers
diff -ru -x '*.so' -x '*.lds' -x '*.a' -x '*.elf' -x '.*' -x '*.order' -x '*.ko' -x '*.mod.c' -x '*.o' -x '*.cmd' linux-2.6.26/net/bluetooth/hci_conn.c linux-2.6.26+mh3+fch/net/bluetooth/hci_conn.c
--- linux-2.6.26/net/bluetooth/hci_conn.c	2008-09-01 17:06:22.000000000 +0200
+++ linux-2.6.26+mh3+fch/net/bluetooth/hci_conn.c	2008-09-01 16:16:33.000000000 +0200
@@ -214,6 +214,7 @@
 	conn->state = BT_OPEN;
 
 	conn->power_save = 1;
+	conn->force_active_mode = 0;
 
 	switch (type) {
 	case ACL_LINK:
@@ -464,7 +465,10 @@
 	if (test_bit(HCI_RAW, &hdev->flags))
 		return;
 
-	if (conn->mode != HCI_CM_SNIFF || !conn->power_save)
+	if (conn->mode != HCI_CM_SNIFF)
+		goto timer;
+
+	if (!conn->power_save && !conn->force_active_mode)
 		goto timer;
 
 	if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
diff -ru -x '*.so' -x '*.lds' -x '*.a' -x '*.elf' -x '.*' -x '*.order' -x '*.ko' -x '*.mod.c' -x '*.o' -x '*.cmd' linux-2.6.26/net/bluetooth/l2cap.c linux-2.6.26+mh3+fch/net/bluetooth/l2cap.c
--- linux-2.6.26/net/bluetooth/l2cap.c	2008-09-01 17:06:22.000000000 +0200
+++ linux-2.6.26+mh3+fch/net/bluetooth/l2cap.c	2008-09-01 17:18:23.000000000 +0200
@@ -1133,6 +1133,20 @@
 		l2cap_pi(sk)->link_mode = opt;
 		break;
 
+	case L2CAP_FORCE_ACTIVE_MODE:
+		if (sk->sk_state != BT_CONNECTED) {
+			err = -ENOTCONN;
+			break;
+		}
+
+		if (get_user(opt, (u32 __user *) optval)) {
+			err = -EFAULT;
+			break;
+		}
+
+		l2cap_pi(sk)->conn->hcon->force_active_mode = opt;
+		break;
+
 	default:
 		err = -ENOPROTOOPT;
 		break;
@@ -1189,6 +1203,17 @@
 
 		break;
 
+	case L2CAP_FORCE_ACTIVE_MODE:
+		if (sk->sk_state != BT_CONNECTED) {
+			err = -ENOTCONN;
+			break;
+		}
+
+		if (put_user(l2cap_pi(sk)->conn->hcon->force_active_mode,
+				 (u32 __user *) optval))
+			err = -EFAULT;
+		break;
+
 	default:
 		err = -ENOPROTOOPT;
 		break;

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

end of thread, other threads:[~2008-09-14 10:00 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-03 19:37 Sniff mode issues regarding Sony Ericsson headsets: kernel patch proposal Fabien Chevalier
2008-09-03 19:49 ` [Bluez-devel] " Marcel Holtmann
2008-09-04 10:43   ` Fabien Chevalier
2008-09-04 12:56     ` Fabien Chevalier
2008-09-04 13:51       ` Marcel Holtmann
2008-09-04 15:15         ` Fabien Chevalier
2008-09-04 13:49     ` Marcel Holtmann
2008-09-04 15:12       ` Fabien Chevalier
2008-09-13 21:09   ` Fabien Chevalier
2008-09-14  0:05     ` Marcel Holtmann
2008-09-14  8:24       ` Fabien Chevalier
2008-09-14  9:22         ` Marcel Holtmann
2008-09-14 10:00           ` Fabien Chevalier
2008-09-06 16:56 ` Brian Sammon
2008-09-08 17:32   ` Fabien Chevalier

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