linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [Bluez-devel] Esco implementation patch
@ 2007-04-25  6:58 Sumeet VERMA
  2007-04-25  7:44 ` Marcel Holtmann
  0 siblings, 1 reply; 24+ messages in thread
From: Sumeet VERMA @ 2007-04-25  6:58 UTC (permalink / raw)
  To: Bluez devel

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

Hi Marcel
I have done an implementation of esco in bluez kernel. I have hardcoded the settings of eSCO connection at the moment (packet type EV3).
Please review it and feel free to make modifications. This is working fine on my side. I changed the 2.6.20 kernel code.

Thanks and Regards,
Sumeet 

[-- Attachment #2: esco_patch.tgz --]
[-- Type: application/octet-stream, Size: 3101 bytes --]

[-- Attachment #3: Type: text/plain, Size: 286 bytes --]

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/

[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-04-25  6:58 [Bluez-devel] Esco implementation patch Sumeet VERMA
@ 2007-04-25  7:44 ` Marcel Holtmann
  2007-04-26  4:56   ` Sumeet VERMA
  0 siblings, 1 reply; 24+ messages in thread
From: Marcel Holtmann @ 2007-04-25  7:44 UTC (permalink / raw)
  To: BlueZ development

Hi Sumeet,

> I have done an implementation of esco in bluez kernel. I have hardcoded the settings of eSCO connection at the moment (packet type EV3).
> Please review it and feel free to make modifications. This is working fine on my side. I changed the 2.6.20 kernel code.

your patch is reverse and please don't send separate patches for each
file. Create a big diff that includes all changes.

Regards

Marcel



-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-04-25  7:44 ` Marcel Holtmann
@ 2007-04-26  4:56   ` Sumeet VERMA
  2007-04-26  5:19     ` Denis KENZIOR
  0 siblings, 1 reply; 24+ messages in thread
From: Sumeet VERMA @ 2007-04-26  4:56 UTC (permalink / raw)
  To: 'BlueZ development'

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

Hi Marcel
Sorry for the mistake. Please find a single diff attached. 

Regards,
Sumeet 
-----Original Message-----
From: bluez-devel-bounces@lists.sourceforge.net
[mailto:bluez-devel-bounces@lists.sourceforge.net] On Behalf Of Marcel
Holtmann
Sent: Wednesday, April 25, 2007 1:14 PM
To: BlueZ development
Subject: Re: [Bluez-devel] Esco implementation patch

Hi Sumeet,

> I have done an implementation of esco in bluez kernel. I have hardcoded
the settings of eSCO connection at the moment (packet type EV3).
> Please review it and feel free to make modifications. This is working fine
on my side. I changed the 2.6.20 kernel code.

your patch is reverse and please don't send separate patches for each file.
Create a big diff that includes all changes.

Regards

Marcel



-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express Download DB2 Express C - the
FREE version of DB2 express and take control of your XML. No limits. Just
data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

[-- Attachment #2: esco.patch --]
[-- Type: application/octet-stream, Size: 11880 bytes --]

diff -ur ../orig/include/hci_core.h ../escopatch/include/hci_core.h
--- ../orig/include/hci_core.h	2007-04-18 11:18:02.000000000 +0530
+++ ../escopatch/include/hci_core.h	2007-04-25 07:47:27.000000000 +0530
@@ -308,6 +308,7 @@
 void hci_acl_connect(struct hci_conn *conn);
 void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
 void hci_add_sco(struct hci_conn *conn, __u16 handle);
+void hci_add_esco(struct hci_conn *conn, __u16 handle);
 
 struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
 int    hci_conn_del(struct hci_conn *conn);
diff -ur ../orig/include/hci.h ../escopatch/include/hci.h
--- ../orig/include/hci.h	2007-04-18 11:18:02.000000000 +0530
+++ ../escopatch/include/hci.h	2007-04-25 07:48:03.000000000 +0530
@@ -138,6 +138,7 @@
 /* Baseband links */
 #define SCO_LINK	0x00
 #define ACL_LINK	0x01
+#define ESCO_LINK	0x02
 
 /* LMP features */
 #define LMP_3SLOT	0x01
@@ -337,6 +338,28 @@
 	__le16   pkt_type;
 } __attribute__ ((packed));
 
+#define OCF_SETUP_SYNC_CONN	0x0028
+struct hci_cp_setup_sync_conn {
+	__le16	handle;
+	__u32	tx_bw;
+	__u32	rx_bw;
+	__le16	max_latency;
+	__le16	voice_setting;
+	__u8 	retx_effort;
+	__le16	pkt_type;	
+} __attribute__ ((packed));
+
+#define OCF_ACCEPT_SYNC_CONN	0x0029
+struct hci_cp_accept_sync_conn {
+	bdaddr_t bdaddr;
+	__u32	tx_bw;
+	__u32	rx_bw;
+	__le16	max_latency;
+	__le16	content_format;
+	__u8	retx_effort;
+	__le16	pkt_type;	
+} __attribute__ ((packed));
+
 #define OCF_INQUIRY		0x0001
 struct hci_cp_inquiry {
 	__u8     lap[3];
@@ -662,6 +685,19 @@
 	__le16   max_local_timeout;
 } __attribute__ ((packed));
 
+#define HCI_EV_SYNC_CONN_COMPLETE  0x2C
+struct hci_ev_sync_conn_complete {
+	__u8	status;
+	__le16	handle;
+	bdaddr_t bdaddr;
+	__u8	link_type;
+	__u8	tx_interval;
+	__u8	retx_window;
+	__le16	rx_pkt_len;
+	__le16	tx_pkt_len;
+	__u8	air_mode;
+} __attribute__ ((packed));
+
 /* Internal events generated by Bluetooth stack */
 #define HCI_EV_STACK_INTERNAL	0xFD
 struct hci_ev_stack_internal {
diff -ur ../orig/src/bluetooth.mod.c ../escopatch/src/bluetooth.mod.c
--- ../orig/src/bluetooth.mod.c	2007-04-18 11:16:52.000000000 +0530
+++ ../escopatch/src/bluetooth.mod.c	2007-04-25 07:21:07.000000000 +0530
@@ -125,4 +125,4 @@
 "depends=";
 
 
-MODULE_INFO(srcversion, "0DEF4A4EF3FAE1E27E3D437");
+MODULE_INFO(srcversion, "72AB206AE1E9B57B1430323");
diff -ur ../orig/src/hci_conn.c ../escopatch/src/hci_conn.c
--- ../orig/src/hci_conn.c	2007-04-18 11:16:53.000000000 +0530
+++ ../escopatch/src/hci_conn.c	2007-04-25 07:45:44.000000000 +0530
@@ -130,6 +130,27 @@
 	hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, sizeof(cp), &cp);
 }
 
+void hci_add_esco(struct hci_conn *conn, __u16 handle)
+{
+	struct hci_dev *hdev = conn->hdev;
+	struct hci_cp_setup_sync_conn cp;
+
+	BT_DBG("%p", conn);
+
+	conn->state = BT_CONNECT;
+	conn->out = 1;
+
+	cp.handle = __cpu_to_le16(handle);
+	cp.tx_bw = __cpu_to_le32(0x00001f40);
+	cp.rx_bw = __cpu_to_le32(0x00001f40);
+	cp.max_latency = __cpu_to_le16(0xffff);
+	cp.voice_setting = __cpu_to_le16(hdev->voice_setting);
+	cp.retx_effort = 0x00;
+	cp.pkt_type = __cpu_to_le16(0x03c8); //EV3 as per spec Corev2.0+EDR
+
+	hci_send_cmd(hdev, OGF_LINK_CTL, OCF_SETUP_SYNC_CONN, sizeof(cp), &cp);
+}
+
 static void hci_conn_timeout(unsigned long arg)
 {
 	struct hci_conn *conn = (void *) arg;
@@ -221,7 +242,7 @@
 
 	del_timer(&conn->disc_timer);
 
-	if (conn->type == SCO_LINK) {
+	if ((conn->type == SCO_LINK) || (conn->type == ESCO_LINK))  { 
 		struct hci_conn *acl = conn->link;
 		if (acl) {
 			acl->link = NULL;
@@ -314,13 +335,22 @@
 	if (acl->state == BT_OPEN || acl->state == BT_CLOSED)
 		hci_acl_connect(acl);
 
-	if (type == SCO_LINK) {
+	if ((type == SCO_LINK) || (type == ESCO_LINK)) { 
 		struct hci_conn *sco;
 
-		if (!(sco = hci_conn_hash_lookup_ba(hdev, SCO_LINK, dst))) {
-			if (!(sco = hci_conn_add(hdev, SCO_LINK, dst))) {
-				hci_conn_put(acl);
-				return NULL;
+		if(type == SCO_LINK) { 
+			if (!(sco = hci_conn_hash_lookup_ba(hdev, SCO_LINK, dst))) {
+				if (!(sco = hci_conn_add(hdev, SCO_LINK, dst))) { 
+					hci_conn_put(acl);
+					return NULL;
+				}
+			}
+		} else {
+			if (!(sco = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, dst))) {
+				if (!(sco = hci_conn_add(hdev, ESCO_LINK, dst))) {
+					hci_conn_put(acl);
+					return NULL;
+				}
 			}
 		}
 		acl->link = sco;
@@ -329,8 +359,12 @@
 		hci_conn_hold(sco);
 
 		if (acl->state == BT_CONNECTED && 
-				(sco->state == BT_OPEN || sco->state == BT_CLOSED))
-			hci_add_sco(sco, acl->handle);
+				(sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
+			if(type == SCO_LINK) 
+				hci_add_sco(sco, acl->handle); 
+			else 
+				hci_add_esco(sco, acl->handle); 
+		}
 
 		return sco;
 	} else {
diff -ur ../orig/src/hci_event.c ../escopatch/src/hci_event.c
--- ../orig/src/hci_event.c	2007-04-18 11:16:53.000000000 +0530
+++ ../escopatch/src/hci_event.c	2007-04-25 07:40:07.000000000 +0530
@@ -82,7 +82,37 @@
 		hci_dev_unlock(hdev);
 
 		break;
+	
+	case OCF_ADD_SCO:
+		status = *((__u8 *) skb->data);
+		
+		/* If ADD_SCO_CONNECTION is not supported, try establishing an eSCO link */
+		if (status == 0x01) {
+			struct hci_cp_add_sco *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_ADD_SCO);
+			__u16 handle;
+			struct hci_conn *acl,*sco;
+			bdaddr_t *dst;
+			
+			if(!cp)
+				break;
+			
+			handle = __le16_to_cpu(cp->handle);
+
+			BT_DBG("%s Add SCO error: Command not supported. handle %d status 0x%x. ", hdev->name, handle, status);				     
+
+			hci_dev_lock(hdev);
+			acl= hci_conn_hash_lookup_handle(hdev, handle);
+			if(acl && (sco=acl->link)) {
+				dst = &(sco->dst);
+				/* Clear SCO */
+				sco->state = BT_CLOSED;
 
+				hci_proto_connect_cfm(sco, status);
+				hci_conn_del(sco);
+			}
+			hci_dev_unlock(hdev);
+		}
+	
 	default:
 		BT_DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
 		break;
@@ -453,6 +483,33 @@
 	case OCF_CREATE_CONN:
 		hci_cs_create_conn(hdev, status);
 		break;
+	
+	case OCF_SETUP_SYNC_CONN:
+                if (status) {
+                        struct hci_conn *acl, *sco;
+                        struct hci_cp_setup_sync_conn *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_SETUP_SYNC_CONN);
+                        __u16 handle;
+
+                        if (!cp)
+                                break;
+
+                        handle = __le16_to_cpu(cp->handle);
+
+                        BT_DBG("%s SETUP Sync Conn error: handle %d status 0x%x", hdev->name, handle, status);
+
+                        hci_dev_lock(hdev);
+
+                        acl = hci_conn_hash_lookup_handle(hdev, handle);
+                        if (acl && (sco = acl->link)) {
+                                sco->state = BT_CLOSED;
+
+                                hci_proto_connect_cfm(sco, status);
+                                hci_conn_del(sco);
+                        }
+
+                        hci_dev_unlock(hdev);
+                }
+                break;
 
 	case OCF_ADD_SCO:
 		if (status) {
@@ -1126,6 +1183,70 @@
 	hci_dev_unlock(hdev);
 }
 
+/* Synchronous Connection Complete Event */
+static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_ev_sync_conn_complete *ev = (struct hci_ev_sync_conn_complete *) skb->data;
+	struct hci_conn *conn;
+
+	BT_DBG("%s status %d", hdev->name, ev->status);
+
+	hci_dev_lock(hdev);
+	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
+	if (!conn) {
+                hci_dev_unlock(hdev);
+                return;
+        }
+
+        if (!ev->status) {
+                conn->handle = __le16_to_cpu(ev->handle);
+                conn->state  = BT_CONNECTED;
+
+
+                if (test_bit(HCI_AUTH, &hdev->flags))
+                        conn->link_mode |= HCI_LM_AUTH;
+
+                if (test_bit(HCI_ENCRYPT, &hdev->flags))
+                        conn->link_mode |= HCI_LM_ENCRYPT;
+
+                /* Set packet type for incoming connection */
+                if (!conn->out) {
+                        struct hci_cp_change_conn_ptype cp;
+                        cp.handle = ev->handle;
+                        cp.pkt_type = (conn->type == ACL_LINK) ?
+                                __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK):
+                                __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
+			
+                        hci_send_cmd(hdev, OGF_LINK_CTL,
+                                OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp);
+                } else {
+	                /* Update disconnect timer */
+                        hci_conn_hold(conn);
+                        hci_conn_put(conn);
+                }
+        } else
+                conn->state = BT_CLOSED;
+
+	if (conn->type == ACL_LINK) {
+                struct hci_conn *sco = conn->link;
+                if (sco) {
+                        if (!ev->status) {
+                                hci_add_sco(sco, conn->handle);
+			}
+                        else {
+                                hci_proto_connect_cfm(sco, ev->status);
+                                hci_conn_del(sco);
+                        }
+                }
+        }
+
+        hci_proto_connect_cfm(conn, ev->status);
+        if (ev->status)
+                hci_conn_del(conn);
+
+        hci_dev_unlock(hdev);
+}
+
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data;
@@ -1161,7 +1282,7 @@
 	case HCI_EV_CONN_REQUEST:
 		hci_conn_request_evt(hdev, skb);
 		break;
-
+	
 	case HCI_EV_CONN_COMPLETE:
 		hci_conn_complete_evt(hdev, skb);
 		break;
@@ -1217,6 +1338,10 @@
 	case HCI_EV_SNIFF_SUBRATE:
 		hci_sniff_subrate_evt(hdev, skb);
 		break;
+	
+	case HCI_EV_SYNC_CONN_COMPLETE:
+		hci_sync_conn_complete_evt(hdev, skb);
+		break;
 
 	case HCI_EV_CMD_STATUS:
 		cs = (struct hci_ev_cmd_status *) skb->data;
diff -ur ../orig/src/l2cap.mod.c ../escopatch/src/l2cap.mod.c
--- ../orig/src/l2cap.mod.c	2007-04-18 11:16:53.000000000 +0530
+++ ../escopatch/src/l2cap.mod.c	2007-04-25 07:21:20.000000000 +0530
@@ -101,4 +101,4 @@
 "depends=bluetooth";
 
 
-MODULE_INFO(srcversion, "75EF27EE0CCFFB206FCB9E2");
+MODULE_INFO(srcversion, "E07DDD764CA7D15B51CEB74");
diff -ur ../orig/src/sco.c ../escopatch/src/sco.c
--- ../orig/src/sco.c	2007-04-18 11:16:53.000000000 +0530
+++ ../escopatch/src/sco.c	2007-04-25 07:42:11.000000000 +0530
@@ -200,7 +200,8 @@
 
 	err = -ENOMEM;
 
-	hcon = hci_connect(hdev, SCO_LINK, dst);
+	//hcon = hci_connect(hdev, SCO_LINK, dst);
+	hcon = hci_connect(hdev, ESCO_LINK, dst); 
 	if (!hcon)
 		goto done;
 
@@ -846,8 +847,9 @@
 {
 	BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
 
-	if (hcon->type != SCO_LINK)
+	if ((hcon->type != SCO_LINK) && (hcon->type != ESCO_LINK)) { 
 		return 0;
+	}
 
 	if (!status) {
 		struct sco_conn *conn;
@@ -865,8 +867,9 @@
 {
 	BT_DBG("hcon %p reason %d", hcon, reason);
 
-	if (hcon->type != SCO_LINK)
+	if ((hcon->type != SCO_LINK) && (hcon->type != ESCO_LINK)) { 
 		return 0;
+	}
 
 	sco_conn_del(hcon, bt_err(reason));
 	return 0;
diff -ur ../orig/src/sco.mod.c ../escopatch/src/sco.mod.c
--- ../orig/src/sco.mod.c	2007-04-18 11:16:52.000000000 +0530
+++ ../escopatch/src/sco.mod.c	2007-04-25 07:21:23.000000000 +0530
@@ -92,4 +92,4 @@
 "depends=bluetooth";
 
 
-MODULE_INFO(srcversion, "792016A3CBF462DCE34EE81");
+MODULE_INFO(srcversion, "6E48E206EFFDE97AC6DEF28");
Only in ../escopatch/src: state

[-- Attachment #3: Type: text/plain, Size: 286 bytes --]

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/

[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-04-26  4:56   ` Sumeet VERMA
@ 2007-04-26  5:19     ` Denis KENZIOR
  2007-04-26  6:24       ` Mayank BATRA
  2007-04-26  6:29       ` Sumeet VERMA
  0 siblings, 2 replies; 24+ messages in thread
From: Denis KENZIOR @ 2007-04-26  5:19 UTC (permalink / raw)
  To: bluez-devel

I'm concerned about the ADD_SCO addition to the hci_cc_link_ctl function.  The 
Version 2.0 + EDR page 617 specifies that:

"no Command Complete event will be sent by the Controller to indicate that 
this command has been completed...."

To me that means that Add Sco should never trigger the hci_cc_link_ctl 
function?

-Denis

On Thursday 26 April 2007 14:56, Sumeet VERMA wrote:
> Hi Marcel
> Sorry for the mistake. Please find a single diff attached.
>
> Regards,
> Sumeet
> -----Original Message-----
> From: bluez-devel-bounces@lists.sourceforge.net
> [mailto:bluez-devel-bounces@lists.sourceforge.net] On Behalf Of Marcel
> Holtmann
> Sent: Wednesday, April 25, 2007 1:14 PM
> To: BlueZ development
> Subject: Re: [Bluez-devel] Esco implementation patch
>
> Hi Sumeet,
>
> > I have done an implementation of esco in bluez kernel. I have hardcoded
>
> the settings of eSCO connection at the moment (packet type EV3).
>
> > Please review it and feel free to make modifications. This is working
> > fine
>
> on my side. I changed the 2.6.20 kernel code.
>
> your patch is reverse and please don't send separate patches for each file.
> Create a big diff that includes all changes.
>
> Regards
>
> Marcel
>
>
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by DB2 Express Download DB2 Express C - the
> FREE version of DB2 express and take control of your XML. No limits. Just
> data. Click to get it now.
> http://sourceforge.net/powerbar/db2/
> _______________________________________________
> Bluez-devel mailing list
> Bluez-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/bluez-devel

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-04-26  5:19     ` Denis KENZIOR
@ 2007-04-26  6:24       ` Mayank BATRA
  2007-04-26  6:29       ` Sumeet VERMA
  1 sibling, 0 replies; 24+ messages in thread
From: Mayank BATRA @ 2007-04-26  6:24 UTC (permalink / raw)
  To: 'BlueZ development'

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Denis,

> I'm concerned about the ADD_SCO addition to the 
> hci_cc_link_ctl function.  The 
> Version 2.0 + EDR page 617 specifies that:
> 
> "no Command Complete event will be sent by the Controller to 
> indicate that 
> this command has been completed...."
> 
> To me that means that Add Sco should never trigger the 
> hci_cc_link_ctl 
> function?

Yes, but please also read page 611 which states "They may be implemented
by a controller to allow for backwards compatibility
with a host utilizing a prior version of the specification.
A host should not use these commands."

This means that a BT 2.0 controller is not expected to implement the
deprecated commands.

In this case the device treats the ADD_SCO command as an unknown HCI
command and thus generates a command complete event.
The point that you mentioned would be applicable if the device processes
the ADD_SCO command normally.

Having said this, I agree that a problem is bound to arise when the host
is BT 1.1 and it has no idea about the BT 2.0 specifications.

Best Regards,

Mayank
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (MingW32)

iQEVAwUBRjBFkPlzfQCQpKQiAQJmXggAtllspT24CRt62TK6RL810xjq/DCXxKbk
Nn9JSCph2ev+jHdyvdBIWgfUAw0HEWZDJn82/9il4t3+AjiL6eCvCtYcxBAbvHXa
GGOzDknA2B133dRmJsR0bwHhO2e8fSLMYyiTMV2OINF52UHlHZKtqfy2oOGhGc2F
LqO0KxRFZ8Gt4LqoakWW7wyM1n22ny62QzBsP01hE/zTrMInMFSCNv+M6MgqQCW4
EUW5JWKQe72g3FMTS+NBAWhED3v69ckDWBLlHlFIS2OSARbh19bNC2O+f1BF9oZU
3riR6GDlnW2mvB6O002ImlABp2ZlYD2g4fofPgFGHBaNNp6gjG5SSQ==
=kZ/x
-----END PGP SIGNATURE-----



-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-04-26  5:19     ` Denis KENZIOR
  2007-04-26  6:24       ` Mayank BATRA
@ 2007-04-26  6:29       ` Sumeet VERMA
  2007-04-26 10:19         ` dkenzior
  2007-04-26 19:40         ` Marcel Holtmann
  1 sibling, 2 replies; 24+ messages in thread
From: Sumeet VERMA @ 2007-04-26  6:29 UTC (permalink / raw)
  To: 'BlueZ development'

Denis
Actually when the ADD_SCO_CONNECTION is not supported a command complete is
generated with the status 0x01 (Unknown HCI Command). The controller doesn't
know about this command at all. If the controller had known about this
command then it will generate a command status with suitable status code.

Regards,
Sumeet 
-----Original Message-----
From: bluez-devel-bounces@lists.sourceforge.net
[mailto:bluez-devel-bounces@lists.sourceforge.net] On Behalf Of Denis
KENZIOR
Sent: Thursday, April 26, 2007 10:49 AM
To: bluez-devel@lists.sourceforge.net
Subject: Re: [Bluez-devel] Esco implementation patch

I'm concerned about the ADD_SCO addition to the hci_cc_link_ctl function.
The Version 2.0 + EDR page 617 specifies that:

"no Command Complete event will be sent by the Controller to indicate that
this command has been completed...."

To me that means that Add Sco should never trigger the hci_cc_link_ctl
function?

-Denis

On Thursday 26 April 2007 14:56, Sumeet VERMA wrote:
> Hi Marcel
> Sorry for the mistake. Please find a single diff attached.
>
> Regards,
> Sumeet
> -----Original Message-----
> From: bluez-devel-bounces@lists.sourceforge.net
> [mailto:bluez-devel-bounces@lists.sourceforge.net] On Behalf Of Marcel 
> Holtmann
> Sent: Wednesday, April 25, 2007 1:14 PM
> To: BlueZ development
> Subject: Re: [Bluez-devel] Esco implementation patch
>
> Hi Sumeet,
>
> > I have done an implementation of esco in bluez kernel. I have 
> > hardcoded
>
> the settings of eSCO connection at the moment (packet type EV3).
>
> > Please review it and feel free to make modifications. This is 
> > working fine
>
> on my side. I changed the 2.6.20 kernel code.
>
> your patch is reverse and please don't send separate patches for each
file.
> Create a big diff that includes all changes.
>
> Regards
>
> Marcel
>
>
>
> ----------------------------------------------------------------------
> --- This SF.net email is sponsored by DB2 Express Download DB2 Express 
> C - the FREE version of DB2 express and take control of your XML. No 
> limits. Just data. Click to get it now.
> http://sourceforge.net/powerbar/db2/
> _______________________________________________
> Bluez-devel mailing list
> Bluez-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/bluez-devel

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express Download DB2 Express C - the
FREE version of DB2 express and take control of your XML. No limits. Just
data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-04-26  6:29       ` Sumeet VERMA
@ 2007-04-26 10:19         ` dkenzior
  2007-04-26 10:36           ` Sumeet VERMA
  2007-04-26 19:40         ` Marcel Holtmann
  1 sibling, 1 reply; 24+ messages in thread
From: dkenzior @ 2007-04-26 10:19 UTC (permalink / raw)
  To: BlueZ development

Sumeet,

Yep you are correct.  However what I'm trying to say is that if the
adapter is Bluetooth 1.2+ compatible and implements Add Sco Connection for
backward compatibility, then the faster eSCO alternative will never be
used.  Most of the Bluetooth 1.2+ USB adapters I've had experience with,
do implement the Add Sco command for backward compatibility.

Shouldn't we try to query the Adapter version first and then use the
commands which are appropriate?

-Denis

> Denis
> Actually when the ADD_SCO_CONNECTION is not supported a command complete
> is
> generated with the status 0x01 (Unknown HCI Command). The controller
> doesn't
> know about this command at all. If the controller had known about this
> command then it will generate a command status with suitable status code.
>
> Regards,
> Sumeet



-----------------------------------------
Trolltech ASA, Sandakerveien 116, PO Box 4332, Nydalen NO-0402 Oslo, Norway

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-04-26 10:19         ` dkenzior
@ 2007-04-26 10:36           ` Sumeet VERMA
  2007-04-26 14:18             ` Marcel Holtmann
  0 siblings, 1 reply; 24+ messages in thread
From: Sumeet VERMA @ 2007-04-26 10:36 UTC (permalink / raw)
  To: 'BlueZ development'

Denis
Yes I think that's a good idea. I think the change required is very minimal.
In sco.c whether I create a SCO or ESCO link depends on the version which is
readily available in hci_dev structure. Its just a matter of adding a
conditional statement (if else). Maybe I can also to check the feature bit
mask. I will try this.

Regards,
Sumeet 
-----Original Message-----
From: bluez-devel-bounces@lists.sourceforge.net
[mailto:bluez-devel-bounces@lists.sourceforge.net] On Behalf Of
dkenzior@trolltech.com
Sent: Thursday, April 26, 2007 3:49 PM
To: BlueZ development
Subject: Re: [Bluez-devel] Esco implementation patch

Sumeet,

Yep you are correct.  However what I'm trying to say is that if the adapter
is Bluetooth 1.2+ compatible and implements Add Sco Connection for backward
compatibility, then the faster eSCO alternative will never be used.  Most of
the Bluetooth 1.2+ USB adapters I've had experience with, do implement the
Add Sco command for backward compatibility.

Shouldn't we try to query the Adapter version first and then use the
commands which are appropriate?

-Denis

> Denis
> Actually when the ADD_SCO_CONNECTION is not supported a command 
> complete is generated with the status 0x01 (Unknown HCI Command). The 
> controller doesn't know about this command at all. If the controller 
> had known about this command then it will generate a command status 
> with suitable status code.
>
> Regards,
> Sumeet



-----------------------------------------
Trolltech ASA, Sandakerveien 116, PO Box 4332, Nydalen NO-0402 Oslo, Norway

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express Download DB2 Express C - the
FREE version of DB2 express and take control of your XML. No limits. Just
data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-04-26 10:36           ` Sumeet VERMA
@ 2007-04-26 14:18             ` Marcel Holtmann
  0 siblings, 0 replies; 24+ messages in thread
From: Marcel Holtmann @ 2007-04-26 14:18 UTC (permalink / raw)
  To: BlueZ development

Hi Sumeet,

> Yes I think that's a good idea. I think the change required is very minimal.
> In sco.c whether I create a SCO or ESCO link depends on the version which is
> readily available in hci_dev structure. Its just a matter of adding a
> conditional statement (if else). Maybe I can also to check the feature bit
> mask. I will try this.

don't use the version information. Use the features bits and check for
the LMP_ESCO bit.

Regards

Marcel



-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-04-26  6:29       ` Sumeet VERMA
  2007-04-26 10:19         ` dkenzior
@ 2007-04-26 19:40         ` Marcel Holtmann
  2007-04-27  7:50           ` Sumeet VERMA
  1 sibling, 1 reply; 24+ messages in thread
From: Marcel Holtmann @ 2007-04-26 19:40 UTC (permalink / raw)
  To: BlueZ development

Hi Sumeet,

> Actually when the ADD_SCO_CONNECTION is not supported a command complete is
> generated with the status 0x01 (Unknown HCI Command). The controller doesn't
> know about this command at all. If the controller had known about this
> command then it will generate a command status with suitable status code.

I reviewed that patch and the current attempt to support eSCO is wrong
and eSCO shouldn't be an alternate if SCO fails. In case the LMP_ESCO
features bit is set, then we should always use the new eSCO commands to
setup the audio link. Only in case of Bluetooth 1.1 adapters and earlier
we fall back to the old SCO setup. My understanding is that the new eSCO
setup routine of Bluetooth 1.2 chips or later can handle the remote
Bluetooth 1.1 devices without problems.

Please also use le32 for 32-bit size variables in HCI commands and
events. Don't diff *.mod.c files. These are auto-generated.

Regards

Marcel



-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-04-26 19:40         ` Marcel Holtmann
@ 2007-04-27  7:50           ` Sumeet VERMA
  2007-05-01 11:24             ` Marcel Holtmann
  0 siblings, 1 reply; 24+ messages in thread
From: Sumeet VERMA @ 2007-04-27  7:50 UTC (permalink / raw)
  To: 'BlueZ development'

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

Marcel
I have corrected the mistakes. Please review the attached patch and let me
know if this is fine. 

Regards,
Sumeet 
-----Original Message-----
From: bluez-devel-bounces@lists.sourceforge.net
[mailto:bluez-devel-bounces@lists.sourceforge.net] On Behalf Of Marcel
Holtmann
Sent: Friday, April 27, 2007 1:11 AM
To: BlueZ development
Subject: Re: [Bluez-devel] Esco implementation patch

Hi Sumeet,

> Actually when the ADD_SCO_CONNECTION is not supported a command 
> complete is generated with the status 0x01 (Unknown HCI Command). The 
> controller doesn't know about this command at all. If the controller 
> had known about this command then it will generate a command status with
suitable status code.

I reviewed that patch and the current attempt to support eSCO is wrong and
eSCO shouldn't be an alternate if SCO fails. In case the LMP_ESCO features
bit is set, then we should always use the new eSCO commands to setup the
audio link. Only in case of Bluetooth 1.1 adapters and earlier we fall back
to the old SCO setup. My understanding is that the new eSCO setup routine of
Bluetooth 1.2 chips or later can handle the remote Bluetooth 1.1 devices
without problems.

Please also use le32 for 32-bit size variables in HCI commands and events.
Don't diff *.mod.c files. These are auto-generated.

Regards

Marcel



-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express Download DB2 Express C - the
FREE version of DB2 express and take control of your XML. No limits. Just
data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

[-- Attachment #2: esco.2.patch --]
[-- Type: application/octet-stream, Size: 9807 bytes --]

diff -ru ../orig/include/hci_core.h ../escopatch/include/hci_core.h
--- ../orig/include/hci_core.h	2007-04-18 11:18:02.000000000 +0530
+++ ../escopatch/include/hci_core.h	2007-04-27 08:57:18.000000000 +0530
@@ -308,6 +308,7 @@
 void hci_acl_connect(struct hci_conn *conn);
 void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
 void hci_add_sco(struct hci_conn *conn, __u16 handle);
+void hci_add_esco(struct hci_conn *conn, __u16 handle);
 
 struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
 int    hci_conn_del(struct hci_conn *conn);
diff -ru ../orig/include/hci.h ../escopatch/include/hci.h
--- ../orig/include/hci.h	2007-04-18 11:18:02.000000000 +0530
+++ ../escopatch/include/hci.h	2007-04-27 08:58:23.000000000 +0530
@@ -138,6 +138,7 @@
 /* Baseband links */
 #define SCO_LINK	0x00
 #define ACL_LINK	0x01
+#define ESCO_LINK	0x02
 
 /* LMP features */
 #define LMP_3SLOT	0x01
@@ -337,6 +338,28 @@
 	__le16   pkt_type;
 } __attribute__ ((packed));
 
+#define OCF_SETUP_SYNC_CONN	0x0028
+struct hci_cp_setup_sync_conn {
+	__le16	handle;
+	__le32	tx_bw;
+	__le32	rx_bw;
+	__le16	max_latency;
+	__le16	voice_setting;
+	__u8 	retx_effort;
+	__le16	pkt_type;	
+} __attribute__ ((packed));
+
+#define OCF_ACCEPT_SYNC_CONN	0x0029
+struct hci_cp_accept_sync_conn {
+	bdaddr_t bdaddr;
+	__le32	tx_bw;
+	__le32	rx_bw;
+	__le16	max_latency;
+	__le16	content_format;
+	__u8	retx_effort;
+	__le16	pkt_type;	
+} __attribute__ ((packed));
+
 #define OCF_INQUIRY		0x0001
 struct hci_cp_inquiry {
 	__u8     lap[3];
@@ -662,6 +685,19 @@
 	__le16   max_local_timeout;
 } __attribute__ ((packed));
 
+#define HCI_EV_SYNC_CONN_COMPLETE  0x2C
+struct hci_ev_sync_conn_complete {
+	__u8	status;
+	__le16	handle;
+	bdaddr_t bdaddr;
+	__u8	link_type;
+	__u8	tx_interval;
+	__u8	retx_window;
+	__le16	rx_pkt_len;
+	__le16	tx_pkt_len;
+	__u8	air_mode;
+} __attribute__ ((packed));
+
 /* Internal events generated by Bluetooth stack */
 #define HCI_EV_STACK_INTERNAL	0xFD
 struct hci_ev_stack_internal {
diff -ru ../orig/src/hci_conn.c ../escopatch/src/hci_conn.c
--- ../orig/src/hci_conn.c	2007-04-18 11:16:53.000000000 +0530
+++ ../escopatch/src/hci_conn.c	2007-04-27 09:08:32.000000000 +0530
@@ -130,6 +130,27 @@
 	hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, sizeof(cp), &cp);
 }
 
+void hci_add_esco(struct hci_conn *conn, __u16 handle)
+{
+	struct hci_dev *hdev = conn->hdev;
+	struct hci_cp_setup_sync_conn cp;
+
+	BT_DBG("%p", conn);
+
+	conn->state = BT_CONNECT;
+	conn->out = 1;
+
+	cp.handle = __cpu_to_le16(handle);
+	cp.tx_bw = __cpu_to_le32(0x00001f40);
+	cp.rx_bw = __cpu_to_le32(0x00001f40);
+	cp.max_latency = __cpu_to_le16(0xffff);
+	cp.voice_setting = __cpu_to_le16(hdev->voice_setting);
+	cp.retx_effort = 0x00;
+	cp.pkt_type = __cpu_to_le16(0x03c8); //EV3 as per spec Corev2.0+EDR
+
+	hci_send_cmd(hdev, OGF_LINK_CTL, OCF_SETUP_SYNC_CONN, sizeof(cp), &cp);
+}
+
 static void hci_conn_timeout(unsigned long arg)
 {
 	struct hci_conn *conn = (void *) arg;
@@ -221,7 +242,7 @@
 
 	del_timer(&conn->disc_timer);
 
-	if (conn->type == SCO_LINK) {
+	if ((conn->type == SCO_LINK) || (conn->type == ESCO_LINK))  { 
 		struct hci_conn *acl = conn->link;
 		if (acl) {
 			acl->link = NULL;
@@ -314,13 +335,22 @@
 	if (acl->state == BT_OPEN || acl->state == BT_CLOSED)
 		hci_acl_connect(acl);
 
-	if (type == SCO_LINK) {
+	if ((type == SCO_LINK) || (type == ESCO_LINK)) { 
 		struct hci_conn *sco;
 
-		if (!(sco = hci_conn_hash_lookup_ba(hdev, SCO_LINK, dst))) {
-			if (!(sco = hci_conn_add(hdev, SCO_LINK, dst))) {
-				hci_conn_put(acl);
-				return NULL;
+		if(type == SCO_LINK) { 
+			if (!(sco = hci_conn_hash_lookup_ba(hdev, SCO_LINK, dst))) {
+				if (!(sco = hci_conn_add(hdev, SCO_LINK, dst))) { 
+					hci_conn_put(acl);
+					return NULL;
+				}
+			}
+		} else {
+			if (!(sco = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, dst))) {
+				if (!(sco = hci_conn_add(hdev, ESCO_LINK, dst))) {
+					hci_conn_put(acl);
+					return NULL;
+				}
 			}
 		}
 		acl->link = sco;
@@ -329,8 +359,12 @@
 		hci_conn_hold(sco);
 
 		if (acl->state == BT_CONNECTED && 
-				(sco->state == BT_OPEN || sco->state == BT_CLOSED))
-			hci_add_sco(sco, acl->handle);
+				(sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
+			if(type == SCO_LINK) 
+				hci_add_sco(sco, acl->handle); 
+			else 
+				hci_add_esco(sco, acl->handle); 
+		}
 
 		return sco;
 	} else {
diff -ru ../orig/src/hci_event.c ../escopatch/src/hci_event.c
--- ../orig/src/hci_event.c	2007-04-18 11:16:53.000000000 +0530
+++ ../escopatch/src/hci_event.c	2007-04-27 09:13:18.000000000 +0530
@@ -453,6 +453,33 @@
 	case OCF_CREATE_CONN:
 		hci_cs_create_conn(hdev, status);
 		break;
+	
+	case OCF_SETUP_SYNC_CONN:
+                if (status) {
+                        struct hci_conn *acl, *sco;
+                        struct hci_cp_setup_sync_conn *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_SETUP_SYNC_CONN);
+                        __u16 handle;
+
+                        if (!cp)
+                                break;
+
+                        handle = __le16_to_cpu(cp->handle);
+
+                        BT_DBG("%s SETUP Sync Conn error: handle %d status 0x%x", hdev->name, handle, status);
+
+                        hci_dev_lock(hdev);
+
+                        acl = hci_conn_hash_lookup_handle(hdev, handle);
+                        if (acl && (sco = acl->link)) {
+                                sco->state = BT_CLOSED;
+
+                                hci_proto_connect_cfm(sco, status);
+                                hci_conn_del(sco);
+                        }
+
+                        hci_dev_unlock(hdev);
+                }
+                break;
 
 	case OCF_ADD_SCO:
 		if (status) {
@@ -1126,6 +1153,70 @@
 	hci_dev_unlock(hdev);
 }
 
+/* Synchronous Connection Complete Event */
+static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_ev_sync_conn_complete *ev = (struct hci_ev_sync_conn_complete *) skb->data;
+	struct hci_conn *conn;
+
+	BT_DBG("%s status %d", hdev->name, ev->status);
+
+	hci_dev_lock(hdev);
+	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
+	if (!conn) {
+                hci_dev_unlock(hdev);
+                return;
+        }
+
+        if (!ev->status) {
+                conn->handle = __le16_to_cpu(ev->handle);
+                conn->state  = BT_CONNECTED;
+
+
+                if (test_bit(HCI_AUTH, &hdev->flags))
+                        conn->link_mode |= HCI_LM_AUTH;
+
+                if (test_bit(HCI_ENCRYPT, &hdev->flags))
+                        conn->link_mode |= HCI_LM_ENCRYPT;
+
+                /* Set packet type for incoming connection */
+                if (!conn->out) {
+                        struct hci_cp_change_conn_ptype cp;
+                        cp.handle = ev->handle;
+                        cp.pkt_type = (conn->type == ACL_LINK) ?
+                                __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK):
+                                __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
+			
+                        hci_send_cmd(hdev, OGF_LINK_CTL,
+                                OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp);
+                } else {
+	                /* Update disconnect timer */
+                        hci_conn_hold(conn);
+                        hci_conn_put(conn);
+                }
+        } else
+                conn->state = BT_CLOSED;
+
+	if (conn->type == ACL_LINK) {
+                struct hci_conn *sco = conn->link;
+                if (sco) {
+                        if (!ev->status) {
+                                hci_add_sco(sco, conn->handle);
+			}
+                        else {
+                                hci_proto_connect_cfm(sco, ev->status);
+                                hci_conn_del(sco);
+                        }
+                }
+        }
+
+        hci_proto_connect_cfm(conn, ev->status);
+        if (ev->status)
+                hci_conn_del(conn);
+
+        hci_dev_unlock(hdev);
+}
+
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data;
@@ -1161,7 +1252,7 @@
 	case HCI_EV_CONN_REQUEST:
 		hci_conn_request_evt(hdev, skb);
 		break;
-
+	
 	case HCI_EV_CONN_COMPLETE:
 		hci_conn_complete_evt(hdev, skb);
 		break;
@@ -1218,6 +1309,10 @@
 		hci_sniff_subrate_evt(hdev, skb);
 		break;
 
+	case HCI_EV_SYNC_CONN_COMPLETE:
+		hci_sync_conn_complete_evt(hdev, skb);
+		break;
+
 	case HCI_EV_CMD_STATUS:
 		cs = (struct hci_ev_cmd_status *) skb->data;
 		skb_pull(skb, sizeof(cs));
diff -ru ../orig/src/sco.c ../escopatch/src/sco.c
--- ../orig/src/sco.c	2007-04-18 11:16:53.000000000 +0530
+++ ../escopatch/src/sco.c	2007-04-27 09:06:17.000000000 +0530
@@ -200,7 +200,10 @@
 
 	err = -ENOMEM;
 
-	hcon = hci_connect(hdev, SCO_LINK, dst);
+	if(hdev->features[3] & 0x80) //LMP eSCO feature bit
+		hcon = hci_connect(hdev, ESCO_LINK, dst);
+	else 
+		hcon = hci_connect(hdev, SCO_LINK, dst); 
 	if (!hcon)
 		goto done;
 
@@ -846,7 +849,7 @@
 {
 	BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
 
-	if (hcon->type != SCO_LINK)
+	if ((hcon->type != SCO_LINK) && (hcon->type != ESCO_LINK)) 
 		return 0;
 
 	if (!status) {
@@ -865,7 +868,7 @@
 {
 	BT_DBG("hcon %p reason %d", hcon, reason);
 
-	if (hcon->type != SCO_LINK)
+	if ((hcon->type != SCO_LINK) && (hcon->type != ESCO_LINK)) 
 		return 0;
 
 	sco_conn_del(hcon, bt_err(reason));

[-- Attachment #3: Type: text/plain, Size: 286 bytes --]

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/

[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-04-27  7:50           ` Sumeet VERMA
@ 2007-05-01 11:24             ` Marcel Holtmann
  2007-05-03  3:57               ` Denis KENZIOR
  0 siblings, 1 reply; 24+ messages in thread
From: Marcel Holtmann @ 2007-05-01 11:24 UTC (permalink / raw)
  To: BlueZ development

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

Hi Sumeet,

> I have corrected the mistakes. Please review the attached patch and let me
> know if this is fine. 

this patch is incomplete. It doesn't handle incoming eSCO connections
and it can't handle SCO audio packets over HCI when a real eSCO
connection has been established.

However it shows a more clean way to actually address eSCO support.

Regards

Marcel


[-- Attachment #2: patch --]
[-- Type: text/x-patch, Size: 16893 bytes --]

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 93ce272..7a001e5 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -114,7 +114,7 @@ enum {
 #define HCI_EVENT_PKT		0x04
 #define HCI_VENDOR_PKT		0xff
 
-/* HCI Packet types */
+/* HCI packet types */
 #define HCI_DM1		0x0008
 #define HCI_DM3		0x0400
 #define HCI_DM5		0x4000
@@ -129,6 +129,14 @@ enum {
 #define SCO_PTYPE_MASK	(HCI_HV1 | HCI_HV2 | HCI_HV3)
 #define ACL_PTYPE_MASK	(~SCO_PTYPE_MASK)
 
+/* eSCO packet types */
+#define ESCO_HV1	0x0001
+#define ESCO_HV2	0x0002
+#define ESCO_HV3	0x0004
+#define ESCO_EV3	0x0008
+#define ESCO_EV4	0x0010
+#define ESCO_EV5	0x0020
+
 /* ACL flags */
 #define ACL_CONT		0x01
 #define ACL_START		0x02
@@ -138,6 +146,7 @@ enum {
 /* Baseband links */
 #define SCO_LINK	0x00
 #define ACL_LINK	0x01
+#define ESCO_LINK	0x02
 
 /* LMP features */
 #define LMP_3SLOT	0x01
@@ -162,6 +171,11 @@ enum {
 #define LMP_PSCHEME	0x02
 #define LMP_PCONTROL	0x04
 
+#define LMP_ESCO	0x80
+
+#define LMP_EV4		0x01
+#define LMP_EV5		0x02
+
 #define LMP_SNIFF_SUBR	0x02
 
 /* Connection modes */
@@ -296,7 +310,18 @@ struct hci_cp_host_buffer_size {
 } __attribute__ ((packed));
 
 /* Link Control */
-#define OGF_LINK_CTL	0x01 
+#define OGF_LINK_CTL	0x01
+
+#define OCF_INQUIRY		0x0001
+struct hci_cp_inquiry {
+	__u8     lap[3];
+	__u8     length;
+	__u8     num_rsp;
+} __attribute__ ((packed));
+
+#define OCF_INQUIRY_CANCEL	0x0002
+
+#define OCF_EXIT_PERIODIC_INQ	0x0004
 
 #define OCF_CREATE_CONN		0x0005
 struct hci_cp_create_conn {
@@ -319,35 +344,24 @@ struct hci_cp_accept_conn_req {
 	__u8     role;
 } __attribute__ ((packed));
 
-#define OCF_REJECT_CONN_REQ	0x000a
+#define OCF_REJECT_CONN_REQ	0x000A
 struct hci_cp_reject_conn_req {
 	bdaddr_t bdaddr;
 	__u8     reason;
 } __attribute__ ((packed));
 
-#define OCF_DISCONNECT	0x0006
+#define OCF_DISCONNECT		0x0006
 struct hci_cp_disconnect {
 	__le16   handle;
 	__u8     reason;
 } __attribute__ ((packed));
 
-#define OCF_ADD_SCO	0x0007
+#define OCF_ADD_SCO		0x0007
 struct hci_cp_add_sco {
 	__le16   handle;
 	__le16   pkt_type;
 } __attribute__ ((packed));
 
-#define OCF_INQUIRY		0x0001
-struct hci_cp_inquiry {
-	__u8     lap[3];
-	__u8     length;
-	__u8     num_rsp;
-} __attribute__ ((packed));
-
-#define OCF_INQUIRY_CANCEL	0x0002
-
-#define OCF_EXIT_PERIODIC_INQ	0x0004
-
 #define OCF_LINK_KEY_REPLY	0x000B
 struct hci_cp_link_key_reply {
 	bdaddr_t bdaddr;
@@ -398,13 +412,41 @@ struct hci_cp_read_remote_features {
 	__le16   handle;
 } __attribute__ ((packed));
 
-#define OCF_READ_REMOTE_VERSION 0x001D
+#define OCF_READ_REMOTE_VERSION	0x001D
 struct hci_cp_read_remote_version {
 	__le16   handle;
 } __attribute__ ((packed));
 
+#define OCF_SETUP_SYNC_CONN	0x0028
+struct hci_cp_setup_sync_conn {
+	__le16   handle;
+	__le32   tx_bandwidth;
+	__le32   rx_bandwidth;
+	__le16   max_latency;
+	__le16   voice_setting;
+	__u8     retrans_effort;
+	__le16   pkt_type;
+} __attribute__ ((packed));
+
+#define OCF_ACCEPT_SYNC_CONN_REQ 0x0029
+struct hci_cp_accept_sync_conn_req {
+	bdaddr_t bdaddr;
+	__le32   tx_bandwidth;
+	__le32   rx_bandwidth;
+	__le16   max_latency;
+	__le16   content_format;
+	__u8     retrans_effort;
+	__le16   pkt_type;
+} __attribute__ ((packed));
+
+#define OCF_REJECT_SYNC_CONN_REQ 0x002A
+struct hci_cp_reject_sync_conn_req {
+	bdaddr_t bdaddr;
+	__u8     reason;
+} __attribute__ ((packed));
+
 /* Link Policy */
-#define OGF_LINK_POLICY	0x02   
+#define OGF_LINK_POLICY	0x02
 
 #define OCF_SNIFF_MODE		0x0003
 struct hci_cp_sniff_mode {
@@ -516,7 +558,7 @@ struct extended_inquiry_info {
 	__u8     data[240];
 } __attribute__ ((packed));
 
-#define HCI_EV_CONN_COMPLETE 	0x03
+#define HCI_EV_CONN_COMPLETE	0x03
 struct hci_ev_conn_complete {
 	__u8     status;
 	__le16   handle;
@@ -572,7 +614,7 @@ struct hci_ev_qos_setup_complete {
 	struct   hci_qos qos;
 } __attribute__ ((packed));
 
-#define HCI_EV_CMD_COMPLETE 	0x0E
+#define HCI_EV_CMD_COMPLETE	0x0E
 struct hci_ev_cmd_complete {
 	__u8     ncmd;
 	__le16   opcode;
@@ -652,6 +694,29 @@ struct hci_ev_pscan_rep_mode {
 	__u8     pscan_rep_mode;
 } __attribute__ ((packed));
 
+#define HCI_EV_SYNC_CONN_COMPLETE	0x2C
+struct hci_ev_sync_conn_complete {
+	__u8     status;
+	__le16   handle;
+	bdaddr_t bdaddr;
+	__u8     link_type;
+	__u8     tx_interval;
+	__u8     retrans_window;
+	__le16   rx_pkt_len;
+	__le16   tx_pkt_len;
+	__u8     air_mode;
+} __attribute__ ((packed));
+
+#define HCI_EV_SYNC_CONN_CHANGED	0x2D
+struct hci_ev_sync_conn_changed {
+	__u8     status;
+	__le16   handle;
+	__u8     tx_interval;
+	__u8     retrans_window;
+	__le16   rx_pkt_len;
+	__le16   tx_pkt_len;
+} __attribute__ ((packed));
+
 #define HCI_EV_SNIFF_SUBRATE	0x2E
 struct hci_ev_sniff_subrate {
 	__u8     status;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index c0fc396..6e71886 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -78,6 +78,7 @@ struct hci_dev {
 	__u16		voice_setting;
 
 	__u16		pkt_type;
+	__u16		esco_type;
 	__u16		link_policy;
 	__u16		link_mode;
 
@@ -308,6 +309,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
 void hci_acl_connect(struct hci_conn *conn);
 void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
 void hci_add_sco(struct hci_conn *conn, __u16 handle);
+void hci_setup_sync(struct hci_conn *conn, __u16 handle);
 
 struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
 int    hci_conn_del(struct hci_conn *conn);
@@ -449,6 +451,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
 #define lmp_encrypt_capable(dev)   ((dev)->features[0] & LMP_ENCRYPT)
 #define lmp_sniff_capable(dev)     ((dev)->features[0] & LMP_SNIFF)
 #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
+#define lmp_esco_capable(dev)      ((dev)->features[3] & LMP_ESCO)
 
 /* ----- HCI protocols ----- */
 struct hci_proto {
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 63980bd..23cb5fb 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -123,12 +123,34 @@ void hci_add_sco(struct hci_conn *conn, __u16 handle)
 	conn->state = BT_CONNECT;
 	conn->out = 1;
 
-	cp.pkt_type = cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
 	cp.handle   = cpu_to_le16(handle);
+	cp.pkt_type = cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
 
 	hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, sizeof(cp), &cp);
 }
 
+void hci_setup_sync(struct hci_conn *conn, __u16 handle)
+{
+	struct hci_dev *hdev = conn->hdev;
+	struct hci_cp_setup_sync_conn cp;
+
+	BT_DBG("%p", conn);
+
+	conn->state = BT_CONNECT;
+	conn->out = 1;
+
+	cp.handle   = cpu_to_le16(handle);
+	cp.pkt_type = cpu_to_le16(hdev->esco_type);
+
+	cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
+	cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
+	cp.max_latency    = cpu_to_le16(0xffff);
+	cp.voice_setting  = cpu_to_le16(hdev->voice_setting);
+	cp.retrans_effort = 0xff;
+
+	hci_send_cmd(hdev, OGF_LINK_CTL, OCF_SETUP_SYNC_CONN, sizeof(cp), &cp);
+}
+
 static void hci_conn_timeout(unsigned long arg)
 {
 	struct hci_conn *conn = (void *) arg;
@@ -143,7 +165,10 @@ static void hci_conn_timeout(unsigned long arg)
 
 	switch (conn->state) {
 	case BT_CONNECT:
-		hci_acl_connect_cancel(conn);
+		if (conn->type == ACL_LINK)
+			hci_acl_connect_cancel(conn);
+		else
+			conn->state = BT_CLOSED;
 		break;
 	case BT_CONNECTED:
 		hci_acl_disconn(conn, 0x13);
@@ -220,19 +245,19 @@ int hci_conn_del(struct hci_conn *conn)
 
 	del_timer(&conn->disc_timer);
 
-	if (conn->type == SCO_LINK) {
-		struct hci_conn *acl = conn->link;
-		if (acl) {
-			acl->link = NULL;
-			hci_conn_put(acl);
-		}
-	} else {
+	if (conn->type == ACL_LINK) {
 		struct hci_conn *sco = conn->link;
 		if (sco)
 			sco->link = NULL;
 
 		/* Unacked frames */
 		hdev->acl_cnt += conn->sent;
+	} else {
+		struct hci_conn *acl = conn->link;
+		if (acl) {
+			acl->link = NULL;
+			hci_conn_put(acl);
+		}
 	}
 
 	tasklet_disable(&hdev->tx_task);
@@ -297,9 +322,10 @@ EXPORT_SYMBOL(hci_get_route);
 
 /* Create SCO or ACL connection.
  * Device _must_ be locked */
-struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
+struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
 {
 	struct hci_conn *acl;
+	struct hci_conn *sco;
 
 	BT_DBG("%s dst %s", hdev->name, batostr(dst));
 
@@ -313,28 +339,30 @@ struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
 	if (acl->state == BT_OPEN || acl->state == BT_CLOSED)
 		hci_acl_connect(acl);
 
-	if (type == SCO_LINK) {
-		struct hci_conn *sco;
+	if (type == ACL_LINK)
+		return acl;
 
-		if (!(sco = hci_conn_hash_lookup_ba(hdev, SCO_LINK, dst))) {
-			if (!(sco = hci_conn_add(hdev, SCO_LINK, dst))) {
-				hci_conn_put(acl);
-				return NULL;
-			}
+	if (!(sco = hci_conn_hash_lookup_ba(hdev, type, dst))) {
+		if (!(sco = hci_conn_add(hdev, type, dst))) {
+			hci_conn_put(acl);
+			return NULL;
 		}
-		acl->link = sco;
-		sco->link = acl;
+	}
 
-		hci_conn_hold(sco);
+	acl->link = sco;
+	sco->link = acl;
 
-		if (acl->state == BT_CONNECTED &&
-				(sco->state == BT_OPEN || sco->state == BT_CLOSED))
-			hci_add_sco(sco, acl->handle);
+	hci_conn_hold(sco);
 
-		return sco;
-	} else {
-		return acl;
+	if (acl->state == BT_CONNECTED &&
+			(sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
+		if (lmp_esco_capable(hdev))
+			hci_setup_sync(sco, acl->handle);
+		else
+			hci_add_sco(sco, acl->handle);
 	}
+
+	return sco;
 }
 EXPORT_SYMBOL(hci_connect);
 
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index aa4b56a..5d6cd1d 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -851,6 +851,7 @@ int hci_register_dev(struct hci_dev *hdev)
 
 	hdev->flags = 0;
 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
+	hdev->esco_type = ESCO_HV1;
 	hdev->link_mode = (HCI_LM_ACCEPT);
 
 	hdev->idle_timeout = 0;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 447ba71..04acae4 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -350,11 +350,24 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s
 		if (hdev->features[0] & LMP_5SLOT)
 			hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
 
-		if (hdev->features[1] & LMP_HV2)
-			hdev->pkt_type |= (HCI_HV2);
+		if (hdev->features[1] & LMP_HV2) {
+			hdev->pkt_type  |= HCI_HV2;
+			hdev->esco_type |= ESCO_HV2;
+		}
+
+		if (hdev->features[1] & LMP_HV3) {
+			hdev->pkt_type  |= HCI_HV3;
+			hdev->esco_type |= ESCO_HV3;
+		}
 
-		if (hdev->features[1] & LMP_HV3)
-			hdev->pkt_type |= (HCI_HV3);
+		if (hdev->features[3] & LMP_ESCO)
+			hdev->esco_type |= ESCO_EV3;
+
+		if (hdev->features[4] & LMP_EV4)
+			hdev->esco_type |= ESCO_EV4;
+
+		if (hdev->features[4] & LMP_EV5)
+			hdev->esco_type |= ESCO_EV5;
 
 		BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name,
 				lf->features[0], lf->features[1], lf->features[2]);
@@ -444,40 +457,75 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
 	hci_dev_unlock(hdev);
 }
 
-static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
+static inline void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
 {
-	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+	struct hci_conn *acl, *sco;
+	struct hci_cp_add_sco *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_ADD_SCO);
 
-	switch (ocf) {
-	case OCF_CREATE_CONN:
-		hci_cs_create_conn(hdev, status);
-		break;
+	if (!cp)
+		return;
 
-	case OCF_ADD_SCO:
-		if (status) {
-			struct hci_conn *acl, *sco;
-			struct hci_cp_add_sco *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_ADD_SCO);
-			__u16 handle;
+	hci_dev_lock(hdev);
 
-			if (!cp)
-				break;
+	if (status) {
+		__u16 handle = __le16_to_cpu(cp->handle);
 
-			handle = __le16_to_cpu(cp->handle);
+		BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status);
 
-			BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status);
+		acl = hci_conn_hash_lookup_handle(hdev, handle);
+		if (acl && (sco = acl->link)) {
+			sco->state = BT_CLOSED;
 
-			hci_dev_lock(hdev);
+			hci_proto_connect_cfm(sco, status);
+			hci_conn_del(sco);
+		}
+	}
 
-			acl = hci_conn_hash_lookup_handle(hdev, handle);
-			if (acl && (sco = acl->link)) {
-				sco->state = BT_CLOSED;
+	hci_dev_unlock(hdev);
+}
 
-				hci_proto_connect_cfm(sco, status);
-				hci_conn_del(sco);
-			}
+static inline void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
+{
+	struct hci_conn *acl, *sco;
+	struct hci_cp_setup_sync_conn *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_SETUP_SYNC_CONN);
 
-			hci_dev_unlock(hdev);
+	if (!cp)
+		return;
+
+	hci_dev_lock(hdev);
+
+	if (status) {
+		__u16 handle = __le16_to_cpu(cp->handle);
+
+		BT_DBG("%s Setup Sync Conn error: handle %d status 0x%x", hdev->name, handle, status);
+
+		acl = hci_conn_hash_lookup_handle(hdev, handle);
+		if (acl && (sco = acl->link)) {
+			sco->state = BT_CLOSED;
+
+			hci_proto_connect_cfm(sco, status);
+			hci_conn_del(sco);
 		}
+	}
+
+	hci_dev_unlock(hdev);
+}
+
+static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
+{
+	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+
+	switch (ocf) {
+	case OCF_CREATE_CONN:
+		hci_cs_create_conn(hdev, status);
+		break;
+
+	case OCF_ADD_SCO:
+		hci_cs_add_sco(hdev, status);
+		break;
+
+	case OCF_SETUP_SYNC_CONN:
+		hci_cs_setup_sync_conn(hdev, status);
 		break;
 
 	case OCF_INQUIRY:
@@ -810,7 +858,10 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
 		struct hci_conn *sco = conn->link;
 		if (sco) {
 			if (!ev->status)
-				hci_add_sco(sco, conn->handle);
+				if (lmp_esco_capable(hdev))
+					hci_setup_sync(sco, conn->handle);
+				else
+					hci_add_sco(sco, conn->handle);
 			else {
 				hci_proto_connect_cfm(sco, ev->status);
 				hci_conn_del(sco);
@@ -881,12 +932,12 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
 		if (conn) {
 			conn->sent -= count;
 
-			if (conn->type == SCO_LINK) {
-				if ((hdev->sco_cnt += count) > hdev->sco_pkts)
-					hdev->sco_cnt = hdev->sco_pkts;
-			} else {
+			if (conn->type == ACL_LINK) {
 				if ((hdev->acl_cnt += count) > hdev->acl_pkts)
 					hdev->acl_cnt = hdev->acl_pkts;
+			} else {
+				if ((hdev->sco_cnt += count) > hdev->sco_pkts)
+					hdev->sco_cnt = hdev->sco_pkts;
 			}
 		}
 	}
@@ -1108,6 +1159,36 @@ static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *
 	hci_dev_unlock(hdev);
 }
 
+/* Synchronous Connection Complete Event */
+static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_ev_sync_conn_complete *ev = (struct hci_ev_sync_conn_complete *) skb->data;
+	struct hci_conn *conn;
+
+	BT_DBG("%s status %d", hdev->name, ev->status);
+
+	hci_dev_lock(hdev);
+
+	conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
+	if (!conn) {
+		hci_dev_unlock(hdev);
+		return;
+	}
+
+	if (!ev->status) {
+		conn->handle = __le16_to_cpu(ev->handle);
+		conn->type   = ev->link_type;
+		conn->state  = BT_CONNECTED;
+	} else
+		conn->state = BT_CLOSED;
+
+	hci_proto_connect_cfm(conn, ev->status);
+	if (ev->status)
+		hci_conn_del(conn);
+
+	hci_dev_unlock(hdev);
+}
+
 /* Sniff Subrate */
 static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
@@ -1213,6 +1294,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_pscan_rep_mode_evt(hdev, skb);
 		break;
 
+	case HCI_EV_SYNC_CONN_COMPLETE:
+		hci_sync_conn_complete_evt(hdev, skb);
+		break;
+
 	case HCI_EV_SNIFF_SUBRATE:
 		hci_sniff_subrate_evt(hdev, skb);
 		break;
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 3f5163e..2334294 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -189,7 +189,7 @@ static int sco_connect(struct sock *sk)
 	struct sco_conn *conn;
 	struct hci_conn *hcon;
 	struct hci_dev  *hdev;
-	int err = 0;
+	int err, type;
 
 	BT_DBG("%s -> %s", batostr(src), batostr(dst));
 
@@ -200,7 +200,9 @@ static int sco_connect(struct sock *sk)
 
 	err = -ENOMEM;
 
-	hcon = hci_connect(hdev, SCO_LINK, dst);
+	type = lmp_esco_capable(hdev) ? ESCO_LINK : SCO_LINK;
+
+	hcon = hci_connect(hdev, type, dst);
 	if (!hcon)
 		goto done;
 
@@ -846,7 +848,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
 {
 	BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
 
-	if (hcon->type != SCO_LINK)
+	if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
 		return 0;
 
 	if (!status) {
@@ -865,7 +867,7 @@ static int sco_disconn_ind(struct hci_conn *hcon, __u8 reason)
 {
 	BT_DBG("hcon %p reason %d", hcon, reason);
 
-	if (hcon->type != SCO_LINK)
+	if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
 		return 0;
 
 	sco_conn_del(hcon, bt_err(reason));

[-- Attachment #3: Type: text/plain, Size: 286 bytes --]

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/

[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-05-01 11:24             ` Marcel Holtmann
@ 2007-05-03  3:57               ` Denis KENZIOR
  2007-05-03  4:38                 ` Mayank BATRA
  2007-05-03  5:25                 ` Marcel Holtmann
  0 siblings, 2 replies; 24+ messages in thread
From: Denis KENZIOR @ 2007-05-03  3:57 UTC (permalink / raw)
  To: BlueZ development

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

Marcel,

Here's a modified patch that implements eSCO sockets, including incoming SCO 
connections.  This was a merge of my previous work for the 2.4 series of 
kernels, so some variables might be named differently than in your patch.

I've tested it on several machines here, including eSco->eSco connection, 
eSco->sco connection for both incoming and outgoing scenarios, everything 
seems fine, however I'm sure more testing is required.

> this patch is incomplete. It doesn't handle incoming eSCO connections
> and it can't handle SCO audio packets over HCI when a real eSCO
> connection has been established.

Why do you say this? What is required in order to get eSCO packets flowing?

-Denis

[-- Attachment #2: esco.patch --]
[-- Type: text/x-diff, Size: 20398 bytes --]

diff -r -p -U5 linux-2.6.20.7/include/net/bluetooth/hci_core.h linux-2.6.20.7-dkenzior/include/net/bluetooth/hci_core.h
--- linux-2.6.20.7/include/net/bluetooth/hci_core.h	2007-04-14 06:48:14.000000000 +1000
+++ linux-2.6.20.7-dkenzior/include/net/bluetooth/hci_core.h	2007-05-02 07:45:15.000000000 +1000
@@ -76,10 +76,11 @@ struct hci_dev {
 	__u16		hci_rev;
 	__u16		manufacturer;
 	__u16		voice_setting;
 
 	__u16		pkt_type;
+	__u16		esco_pkt_type;
 	__u16		link_policy;
 	__u16		link_mode;
 
 	__u32		idle_timeout;
 	__u16		sniff_min_interval;
@@ -447,10 +448,11 @@ void hci_conn_del_sysfs(struct hci_conn 
 /* ----- LMP capabilities ----- */
 #define lmp_rswitch_capable(dev)   ((dev)->features[0] & LMP_RSWITCH)
 #define lmp_encrypt_capable(dev)   ((dev)->features[0] & LMP_ENCRYPT)
 #define lmp_sniff_capable(dev)     ((dev)->features[0] & LMP_SNIFF)
 #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
+#define lmp_esco_capable(dev)      ((dev)->features[3] & LMP_ESCO)
 
 /* ----- HCI protocols ----- */
 struct hci_proto {
 	char 		*name;
 	unsigned int	id;
diff -r -p -U5 linux-2.6.20.7/include/net/bluetooth/hci.h linux-2.6.20.7-dkenzior/include/net/bluetooth/hci.h
--- linux-2.6.20.7/include/net/bluetooth/hci.h	2007-04-14 06:48:14.000000000 +1000
+++ linux-2.6.20.7-dkenzior/include/net/bluetooth/hci.h	2007-05-03 13:30:27.000000000 +1000
@@ -127,19 +127,33 @@ enum {
 #define HCI_HV3		0x0080
 
 #define SCO_PTYPE_MASK	(HCI_HV1 | HCI_HV2 | HCI_HV3)
 #define ACL_PTYPE_MASK	(~SCO_PTYPE_MASK)
 
+/* eSCO packet types */
+#define HCI_ESCO_HV1	0x0001
+#define HCI_ESCO_HV2	0x0002
+#define HCI_ESCO_HV3	0x0004
+#define HCI_ESCO_EV3	0x0008
+#define HCI_ESCO_EV4	0x0010
+#define HCI_ESCO_EV5	0x0020
+
+/* Some devices seem to have trouble establishing EV* packet connections */
+/* with other devices.  For this reason we mask out the eSCO packets */ 
+/* for now.  Might need to address this later */
+#define ESCO_PTYPE_MASK	(HCI_ESCO_HV1 | HCI_ESCO_HV2 | HCI_ESCO_HV3)
+
 /* ACL flags */
 #define ACL_CONT		0x01
 #define ACL_START		0x02
 #define ACL_ACTIVE_BCAST	0x04
 #define ACL_PICO_BCAST		0x08
 
 /* Baseband links */
 #define SCO_LINK	0x00
 #define ACL_LINK	0x01
+#define ESCO_LINK	0x02
 
 /* LMP features */
 #define LMP_3SLOT	0x01
 #define LMP_5SLOT	0x02
 #define LMP_ENCRYPT	0x04
@@ -156,10 +170,15 @@ enum {
 #define LMP_HV2		0x10
 #define LMP_HV3		0x20
 #define LMP_ULAW	0x40
 #define LMP_ALAW	0x80
 
+/* eSCO support and packets */
+#define LMP_ESCO	0x80
+#define LMP_EV4		0x01
+#define LMP_EV5		0x02
+
 #define LMP_CVSD	0x01
 #define LMP_PSCHEME	0x02
 #define LMP_PCONTROL	0x04
 
 #define LMP_SNIFF_SUBR	0x02
@@ -317,16 +336,33 @@ struct hci_cp_create_conn_cancel {
 struct hci_cp_accept_conn_req {
 	bdaddr_t bdaddr;
 	__u8     role;
 } __attribute__ ((packed));
 
+#define OCF_ACCEPT_SYNC_CONN_REQ	0x0029
+struct hci_cp_accept_sync_conn_req {
+	bdaddr_t	bdaddr;
+	__le32		tx_rate;
+	__le32		rx_rate;
+	__le16		max_latency;
+	__le16		voice_setting;
+	__u8		retrans_effort;
+	__le16		pkt_type;
+} __attribute__((packed));
+
 #define OCF_REJECT_CONN_REQ	0x000a
 struct hci_cp_reject_conn_req {
 	bdaddr_t bdaddr;
 	__u8     reason;
 } __attribute__ ((packed));
 
+#define OCF_REJECT_SYNC_CONN_REQ	0x002a
+struct hci_cp_reject_sync_conn_req {
+	bdaddr_t 	bdaddr;
+	__u8		reason;
+} __attribute__ ((packed));
+
 #define OCF_DISCONNECT	0x0006
 struct hci_cp_disconnect {
 	__le16   handle;
 	__u8     reason;
 } __attribute__ ((packed));
@@ -335,10 +371,21 @@ struct hci_cp_disconnect {
 struct hci_cp_add_sco {
 	__le16   handle;
 	__le16   pkt_type;
 } __attribute__ ((packed));
 
+#define OCF_SETUP_SYNC_CONN	0x0028
+struct hci_cp_setup_sync_conn {
+	__le16	handle;
+	__le32 	tx_rate;
+	__le32	rx_rate;
+	__le16	latency;
+	__le16	voice_setting;
+	__u8	retrans_effort;
+	__le16	pkt_type;
+} __attribute__ ((packed));
+
 #define OCF_INQUIRY		0x0001
 struct hci_cp_inquiry {
 	__u8     lap[3];
 	__u8     length;
 	__u8     num_rsp;
@@ -523,10 +570,33 @@ struct hci_ev_conn_complete {
 	bdaddr_t bdaddr;
 	__u8     link_type;
 	__u8     encr_mode;
 } __attribute__ ((packed));
 
+#define HCI_EV_SYNC_CONN_COMPLETE	0x2C
+struct hci_ev_sync_conn_complete {
+	__u8 		status;
+	__le16		handle;
+	bdaddr_t	bdaddr;
+	__u8		link_type;
+	__u8		trans_interval;
+	__u8		retrans_window;
+	__le16		rx_pkt_len;
+	__le16		tx_pkt_len;
+	__u8		air_mode;
+} __attribute__ ((packed));
+
+#define HCI_EV_SYNC_CONN_CHANGED       0x2D
+struct hci_ev_sync_conn_changed {
+	__u8		status;
+	__le16		handle;
+	__u8		trans_interval;
+	__u8		retrans_window;
+	__le16		rx_pkt_len;
+	__le16		tx_pkt_len;
+} __attribute__ ((packed));
+
 #define HCI_EV_CONN_REQUEST	0x04
 struct hci_ev_conn_request {
 	bdaddr_t bdaddr;
 	__u8     dev_class[3];
 	__u8     link_type;
diff -r -p -U5 linux-2.6.20.7/net/bluetooth/hci_conn.c linux-2.6.20.7-dkenzior/net/bluetooth/hci_conn.c
--- linux-2.6.20.7/net/bluetooth/hci_conn.c	2007-04-14 06:48:14.000000000 +1000
+++ linux-2.6.20.7-dkenzior/net/bluetooth/hci_conn.c	2007-05-02 09:54:33.000000000 +1000
@@ -115,21 +115,37 @@ void hci_acl_disconn(struct hci_conn *co
 }
 
 void hci_add_sco(struct hci_conn *conn, __u16 handle)
 {
 	struct hci_dev *hdev = conn->hdev;
-	struct hci_cp_add_sco cp;
 
 	BT_DBG("%p", conn);
 
 	conn->state = BT_CONNECT;
 	conn->out = 1;
 
-	cp.pkt_type = __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
-	cp.handle   = __cpu_to_le16(handle);
+	/* Devices that support 1.2 should be using the eSCO */
+	/* commands.  Add SCO commands were deprecated in 1.2 */
 
-	hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, sizeof(cp), &cp);
+	if (lmp_esco_capable(hdev)) {
+		struct hci_cp_setup_sync_conn cp;
+		cp.handle = __cpu_to_le16(handle);
+		cp.tx_rate = __cpu_to_le32(0x1f40);
+		cp.rx_rate = __cpu_to_le32(0x1f40);
+		cp.latency = __cpu_to_le16(0xffff);
+		cp.voice_setting = __cpu_to_le16(hdev->voice_setting);
+		cp.retrans_effort = 0xff;
+		cp.pkt_type = __cpu_to_le16(hdev->esco_pkt_type & ESCO_PTYPE_MASK);
+	
+		hci_send_cmd(hdev, OGF_LINK_CTL, OCF_SETUP_SYNC_CONN, sizeof(cp), &cp);
+	} else {
+		struct hci_cp_add_sco cp;
+		cp.pkt_type = __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
+		cp.handle   = __cpu_to_le16(handle);
+
+		hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, sizeof(cp), &cp);
+	}
 }
 
 static void hci_conn_timeout(unsigned long arg)
 {
 	struct hci_conn *conn = (void *) arg;
@@ -142,11 +158,14 @@ static void hci_conn_timeout(unsigned lo
 
 	hci_dev_lock(hdev);
 
 	switch (conn->state) {
 	case BT_CONNECT:
-		hci_acl_connect_cancel(conn);
+		if (conn->type == ACL_LINK)
+			hci_acl_connect_cancel(conn);
+		else
+			conn->state = BT_CLOSED;
 		break;
  	case BT_CONNECTED:
 		hci_acl_disconn(conn, 0x13);
 		break;
 	default:
@@ -219,23 +238,23 @@ int hci_conn_del(struct hci_conn *conn)
 
 	del_timer(&conn->idle_timer);
 
 	del_timer(&conn->disc_timer);
 
-	if (conn->type == SCO_LINK) {
-		struct hci_conn *acl = conn->link;
-		if (acl) {
-			acl->link = NULL;
-			hci_conn_put(acl);
-		}
-	} else {
+	if (conn->type == ACL_LINK) {
 		struct hci_conn *sco = conn->link;
 		if (sco)
 			sco->link = NULL;
 
 		/* Unacked frames */
 		hdev->acl_cnt += conn->sent;
+	} else {
+		struct hci_conn *acl = conn->link;
+		if (acl) {
+			acl->link = NULL;
+			hci_conn_put(acl);
+		}
 	}
 
 	tasklet_disable(&hdev->tx_task);
 
 	hci_conn_del_sysfs(conn);
@@ -299,10 +318,11 @@ EXPORT_SYMBOL(hci_get_route);
 /* Create SCO or ACL connection.
  * Device _must_ be locked */
 struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
 {
 	struct hci_conn *acl;
+	struct hci_conn *sco;
 
 	BT_DBG("%s dst %s", hdev->name, batostr(dst));
 
 	if (!(acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst))) {
 		if (!(acl = hci_conn_add(hdev, ACL_LINK, dst)))
@@ -312,32 +332,29 @@ struct hci_conn * hci_connect(struct hci
 	hci_conn_hold(acl);
 
 	if (acl->state == BT_OPEN || acl->state == BT_CLOSED)
 		hci_acl_connect(acl);
 
-	if (type == SCO_LINK) {
-		struct hci_conn *sco;
+	if (type == ACL_LINK)
+		return acl;
 
-		if (!(sco = hci_conn_hash_lookup_ba(hdev, SCO_LINK, dst))) {
-			if (!(sco = hci_conn_add(hdev, SCO_LINK, dst))) {
-				hci_conn_put(acl);
-				return NULL;
-			}
+	if (!(sco = hci_conn_hash_lookup_ba(hdev, type, dst))) {
+		if (!(sco = hci_conn_add(hdev, type, dst))) {
+			hci_conn_put(acl);
+			return NULL;
 		}
-		acl->link = sco;
-		sco->link = acl;
+	}
+	acl->link = sco;
+	sco->link = acl;
 
-		hci_conn_hold(sco);
+	hci_conn_hold(sco);
 
-		if (acl->state == BT_CONNECTED && 
-				(sco->state == BT_OPEN || sco->state == BT_CLOSED))
-			hci_add_sco(sco, acl->handle);
+	if (acl->state == BT_CONNECTED && 
+			(sco->state == BT_OPEN || sco->state == BT_CLOSED))
+		hci_add_sco(sco, acl->handle);
 
-		return sco;
-	} else {
-		return acl;
-	}
+	return sco;
 }
 EXPORT_SYMBOL(hci_connect);
 
 /* Authenticate remote device */
 int hci_conn_auth(struct hci_conn *conn)
diff -r -p -U5 linux-2.6.20.7/net/bluetooth/hci_core.c linux-2.6.20.7-dkenzior/net/bluetooth/hci_core.c
--- linux-2.6.20.7/net/bluetooth/hci_core.c	2007-04-14 06:48:14.000000000 +1000
+++ linux-2.6.20.7-dkenzior/net/bluetooth/hci_core.c	2007-04-26 10:50:06.000000000 +1000
@@ -849,10 +849,11 @@ int hci_register_dev(struct hci_dev *hde
 	atomic_set(&hdev->refcnt, 1);
 	spin_lock_init(&hdev->lock);
 
 	hdev->flags = 0;
 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
+	hdev->esco_pkt_type = HCI_ESCO_HV1;
 	hdev->link_mode = (HCI_LM_ACCEPT);
 
 	hdev->idle_timeout = 0;
 	hdev->sniff_max_interval = 800;
 	hdev->sniff_min_interval = 80;
diff -r -p -U5 linux-2.6.20.7/net/bluetooth/hci_event.c linux-2.6.20.7-dkenzior/net/bluetooth/hci_event.c
--- linux-2.6.20.7/net/bluetooth/hci_event.c	2007-04-14 06:48:14.000000000 +1000
+++ linux-2.6.20.7-dkenzior/net/bluetooth/hci_event.c	2007-05-03 12:35:17.000000000 +1000
@@ -349,18 +349,32 @@ static void hci_cc_info_param(struct hci
 			hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
 
 		if (hdev->features[0] & LMP_5SLOT)
 			hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
 
-		if (hdev->features[1] & LMP_HV2)
-			hdev->pkt_type |= (HCI_HV2);
+		if (hdev->features[1] & LMP_HV2) {
+			hdev->pkt_type |= HCI_HV2;
+			hdev->esco_pkt_type |= HCI_ESCO_HV2;
+		}
+
+		if (hdev->features[1] & LMP_HV3) {
+			hdev->pkt_type |= HCI_HV3;
+			hdev->esco_pkt_type |= HCI_ESCO_HV3;
+		}
+
+		if (hdev->features[4] & LMP_ESCO)
+			hdev->esco_pkt_type |= HCI_ESCO_EV3;
 
-		if (hdev->features[1] & LMP_HV3)
-			hdev->pkt_type |= (HCI_HV3);
+		if (hdev->features[5] & LMP_EV4)
+			hdev->esco_pkt_type |= HCI_ESCO_EV4;
+
+		if (hdev->features[5] & LMP_EV5)
+			hdev->esco_pkt_type |= HCI_ESCO_EV5;
 
 		BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name,
 				lf->features[0], lf->features[1], lf->features[2]);
+		BT_DBG("%s: eSco packets: 0x%x", hdev->name, hdev->esco_pkt_type);
 
 		break;
 
 	case OCF_READ_BUFFER_SIZE:
 		bs = (struct hci_rp_read_buffer_size *) skb->data;
@@ -443,44 +457,80 @@ static inline void hci_cs_create_conn(st
 	}
 
 	hci_dev_unlock(hdev);
 }
 
-static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
+static inline void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
 {
-	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+	struct hci_conn *acl, *sco;
+	struct hci_cp_add_sco *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_ADD_SCO);
 
-	switch (ocf) {
-	case OCF_CREATE_CONN:
-		hci_cs_create_conn(hdev, status);
-		break;
+	if (!cp)
+		return;	
 
-	case OCF_ADD_SCO:
-		if (status) {
-			struct hci_conn *acl, *sco;
-			struct hci_cp_add_sco *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_ADD_SCO);
-			__u16 handle;
+	hci_dev_lock(hdev);
 
-			if (!cp)
-				break;
+	if (status) {
+		__u16 handle = __le16_to_cpu(cp->handle);
 
-			handle = __le16_to_cpu(cp->handle);
+		BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status);
 
-			BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status);
+		acl = hci_conn_hash_lookup_handle(hdev, handle);
+		if (acl && (sco = acl->link)) {
+			sco->state = BT_CLOSED;
 
-			hci_dev_lock(hdev);
+			hci_proto_connect_cfm(sco, status);
+			hci_conn_del(sco);
+		}
+	}
 
-			acl = hci_conn_hash_lookup_handle(hdev, handle);
-			if (acl && (sco = acl->link)) {
-				sco->state = BT_CLOSED;
+	hci_dev_unlock(hdev);
+}
 
-				hci_proto_connect_cfm(sco, status);
-				hci_conn_del(sco);
-			}
+static inline void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
+{
+	struct hci_conn *acl, *sco;
+	struct hci_cp_setup_sync_conn *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_SETUP_SYNC_CONN);
 
-			hci_dev_unlock(hdev);
+	if (!cp)
+		return;	
+
+	hci_dev_lock(hdev);
+
+	if (status) {
+		__u16 handle = __le16_to_cpu(cp->handle);
+
+		BT_DBG("%s eSCO conn setup error: handle %d status 0x%x",
+			hdev->name, handle, status);
+
+		acl = hci_conn_hash_lookup_handle(hdev, handle);
+		if (acl && (sco = acl->link)) {
+			sco->state = BT_CLOSED;
+
+			hci_proto_connect_cfm(sco, status);
+			hci_conn_del(sco);
 		}
+	}
+
+	hci_dev_unlock(hdev);	
+}
+
+static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
+{
+	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+	
+	switch (ocf) {
+	case OCF_CREATE_CONN:
+		hci_cs_create_conn(hdev, status);
+		break;
+
+	case OCF_ADD_SCO:
+		hci_cs_add_sco(hdev, status);
+		break;
+
+	case OCF_SETUP_SYNC_CONN:
+		hci_cs_setup_sync_conn(hdev, status);
 		break;
 
 	case OCF_INQUIRY:
 		if (status) {
 			BT_DBG("%s Inquiry error: status 0x%x", hdev->name, status);
@@ -709,11 +759,10 @@ static inline void hci_conn_request_evt(
 	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
 
 	if (mask & HCI_LM_ACCEPT) {
 		/* Connection accepted */
 		struct hci_conn *conn;
-		struct hci_cp_accept_conn_req cp;
 
 		hci_dev_lock(hdev);
 		conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
 		if (!conn) {
 			if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
@@ -724,27 +773,55 @@ static inline void hci_conn_request_evt(
 		}
 		memcpy(conn->dev_class, ev->dev_class, 3);
 		conn->state = BT_CONNECT;
 		hci_dev_unlock(hdev);
 
-		bacpy(&cp.bdaddr, &ev->bdaddr);
+		if ((ev->link_type == ACL_LINK) || (!lmp_esco_capable(hdev))) {
+			struct hci_cp_accept_conn_req cp;
+			bacpy(&cp.bdaddr, &ev->bdaddr);
+
+			if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
+				cp.role = 0x00; /* Become master */
+			else
+				cp.role = 0x01; /* Remain slave */
 
-		if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
-			cp.role = 0x00; /* Become master */
-		else
-			cp.role = 0x01; /* Remain slave */
+			hci_send_cmd(hdev, OGF_LINK_CTL,
+					OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp);
+		} else {
+			/* Send the Accept Sync Connection Command */
+			struct hci_cp_accept_sync_conn_req cp;
+			
+			bacpy(&cp.bdaddr, &ev->bdaddr);
+			cp.tx_rate = __cpu_to_le32(0x1f40);
+			cp.rx_rate = __cpu_to_le32(0x1f40);
+			cp.max_latency = __cpu_to_le16(0xffff);
+			cp.voice_setting = __cpu_to_le16(hdev->voice_setting);
+			cp.retrans_effort = 0xff;
+			cp.pkt_type = __cpu_to_le16(hdev->esco_pkt_type & ESCO_PTYPE_MASK);
 
-		hci_send_cmd(hdev, OGF_LINK_CTL,
-				OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp);
+			hci_send_cmd(hdev, OGF_LINK_CTL,
+					OCF_ACCEPT_SYNC_CONN_REQ, sizeof(cp), &cp);
+		}
 	} else {
 		/* Connection rejected */
-		struct hci_cp_reject_conn_req cp;
 
-		bacpy(&cp.bdaddr, &ev->bdaddr);
-		cp.reason = 0x0f;
-		hci_send_cmd(hdev, OGF_LINK_CTL,
-				OCF_REJECT_CONN_REQ, sizeof(cp), &cp);
+		if ((ev->link_type == ACL_LINK) || (!lmp_esco_capable(hdev))) {
+			struct hci_cp_reject_conn_req cp;
+
+			bacpy(&cp.bdaddr, &ev->bdaddr);
+			cp.reason = 0x0f;
+			hci_send_cmd(hdev, OGF_LINK_CTL,
+					OCF_REJECT_CONN_REQ, sizeof(cp), &cp);
+		} else {
+			struct hci_cp_reject_sync_conn_req cp;
+			
+			bacpy(&cp.bdaddr, &ev->bdaddr);
+			cp.reason = 0x0f;
+
+			hci_send_cmd(hdev, OGF_LINK_CTL,
+					OCF_REJECT_SYNC_CONN_REQ, sizeof(cp), &cp);
+		}
 	}
 }
 
 /* Connect Complete */
 static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
@@ -828,10 +905,60 @@ static inline void hci_conn_complete_evt
 		hci_acl_connect(pend);
 
 	hci_dev_unlock(hdev);
 }
 
+/* eSCO Connect Complete */
+static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_ev_sync_conn_complete *ev = (struct hci_ev_sync_conn_complete *) skb->data;
+	struct hci_conn *conn;
+
+	BT_DBG("%s", hdev->name);
+
+	hci_dev_lock(hdev);
+
+	/* There are two possibilities here.  We establish an outgoing ESCO link and get */
+	/* back a SCO link.  Or we got a connect request with a SCO/ESCO link type and */
+	/* arrived here once it was established */
+	conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
+	if (!conn) {
+		/* Incoming SCO case */
+		conn = hci_conn_hash_lookup_ba(hdev, SCO_LINK, &ev->bdaddr);
+		if (!conn) {
+			hci_dev_unlock(hdev);
+			return;
+		}
+
+		if (conn->out) {
+			BT_DBG("ended up with a SCO link");
+			hci_conn_del(conn);
+			hci_dev_unlock(hdev);
+			return;
+		}
+	}
+
+	if (!ev->status) {
+		conn->handle = __le16_to_cpu(ev->handle);
+		conn->type = ev->link_type;
+		conn->state  = BT_CONNECTED;
+
+		if (conn->out) {
+			/* Update disconnect timer */
+			hci_conn_hold(conn);
+			hci_conn_put(conn);
+		}
+	} else
+		conn->state = BT_CLOSED;
+
+	hci_proto_connect_cfm(conn, ev->status);
+	if (ev->status)
+		hci_conn_del(conn);
+
+	hci_dev_unlock(hdev);
+}
+
 /* Disconnect Complete */
 static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_ev_disconn_complete *ev = (struct hci_ev_disconn_complete *) skb->data;
 	struct hci_conn *conn;
@@ -880,16 +1007,16 @@ static inline void hci_num_comp_pkts_evt
 
 		conn = hci_conn_hash_lookup_handle(hdev, handle);
 		if (conn) {
 			conn->sent -= count;
 
-			if (conn->type == SCO_LINK) {
-				if ((hdev->sco_cnt += count) > hdev->sco_pkts)
-					hdev->sco_cnt = hdev->sco_pkts;
-			} else {
+			if (conn->type == ACL_LINK) {
 				if ((hdev->acl_cnt += count) > hdev->acl_pkts)
 					hdev->acl_cnt = hdev->acl_pkts;
+			} else {
+				if ((hdev->sco_cnt += count) > hdev->sco_pkts)
+					hdev->sco_cnt = hdev->sco_pkts;
 			}
 		}
 	}
 	hci_sched_tx(hdev);
 
@@ -1164,10 +1291,14 @@ void hci_event_packet(struct hci_dev *hd
 
 	case HCI_EV_CONN_COMPLETE:
 		hci_conn_complete_evt(hdev, skb);
 		break;
 
+	case HCI_EV_SYNC_CONN_COMPLETE:
+		hci_sync_conn_complete_evt(hdev, skb);
+		break;
+
 	case HCI_EV_DISCONN_COMPLETE:
 		hci_disconn_complete_evt(hdev, skb);
 		break;
 
 	case HCI_EV_ROLE_CHANGE:
diff -r -p -U5 linux-2.6.20.7/net/bluetooth/sco.c linux-2.6.20.7-dkenzior/net/bluetooth/sco.c
--- linux-2.6.20.7/net/bluetooth/sco.c	2007-04-14 06:48:14.000000000 +1000
+++ linux-2.6.20.7-dkenzior/net/bluetooth/sco.c	2007-05-03 10:18:22.000000000 +1000
@@ -187,22 +187,24 @@ static int sco_connect(struct sock *sk)
 	bdaddr_t *src = &bt_sk(sk)->src;
 	bdaddr_t *dst = &bt_sk(sk)->dst;
 	struct sco_conn *conn;
 	struct hci_conn *hcon;
 	struct hci_dev  *hdev;
-	int err = 0;
+	int err, type;
 
 	BT_DBG("%s -> %s", batostr(src), batostr(dst));
 
 	if (!(hdev = hci_get_route(dst, src)))
 		return -EHOSTUNREACH;
 
 	hci_dev_lock_bh(hdev);
 
 	err = -ENOMEM;
 
-	hcon = hci_connect(hdev, SCO_LINK, dst);
+	type = lmp_esco_capable(hdev) ? ESCO_LINK : SCO_LINK;
+
+	hcon = hci_connect(hdev, type, dst);
 	if (!hcon)
 		goto done;
 
 	conn = sco_conn_add(hcon, 0);
 	if (!conn) {
@@ -836,19 +838,22 @@ done:
 /* ----- SCO interface with lower layer (HCI) ----- */
 static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
 {
 	BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
 
+	if (type != SCO_LINK && type != ESCO_LINK)
+		return 0;
+
 	/* Always accept connection */
 	return HCI_LM_ACCEPT;
 }
 
 static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
 {
 	BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
 
-	if (hcon->type != SCO_LINK)
+	if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
 		return 0;
 
 	if (!status) {
 		struct sco_conn *conn;
 
@@ -863,11 +868,11 @@ static int sco_connect_cfm(struct hci_co
 
 static int sco_disconn_ind(struct hci_conn *hcon, __u8 reason)
 {
 	BT_DBG("hcon %p reason %d", hcon, reason);
 
-	if (hcon->type != SCO_LINK)
+	if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
 		return 0;
 
 	sco_conn_del(hcon, bt_err(reason));
 	return 0;
 }

[-- Attachment #3: Type: text/plain, Size: 286 bytes --]

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/

[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-05-03  3:57               ` Denis KENZIOR
@ 2007-05-03  4:38                 ` Mayank BATRA
  2007-05-03  5:00                   ` Denis KENZIOR
  2007-05-03  5:25                 ` Marcel Holtmann
  1 sibling, 1 reply; 24+ messages in thread
From: Mayank BATRA @ 2007-05-03  4:38 UTC (permalink / raw)
  To: 'BlueZ development'

On Thursday, May 03, 2007 9:27 AM +0530, Denis KENZIOR wrote:
> Here's a modified patch that implements eSCO sockets, including
> incoming SCO connections.  This was a merge of my previous work for
> the 2.4 series of kernels, so some variables might be named
> differently than in your patch. 

How about the 2-EV* and 3-EV* packet types? The spec says that a 0 for these bits means they have been enabled.
Shouldn't you also check for their support in the feature mask?

> I've tested it on several machines here, including eSco->eSco
> connection, eSco->sco connection for both incoming and outgoing
> scenarios, everything seems fine, however I'm sure more testing is
> required. 

How did you mangage to set up an eSCO since you are using only HV* packet types (ESCO_PTYPE_MASK)?
Or is it because the 2-EV* and 3-EV* bits are "0" thus the controller thinks you want to enable those packet types?

>> this patch is incomplete. It doesn't handle incoming eSCO connections
>> and it can't handle SCO audio packets over HCI when a real eSCO
>> connection has been established.
> 
> Why do you say this? What is required in order to get eSCO packets
> flowing? 

Regards,

Mayank


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-05-03  4:38                 ` Mayank BATRA
@ 2007-05-03  5:00                   ` Denis KENZIOR
  2007-05-03  5:16                     ` Marcel Holtmann
  0 siblings, 1 reply; 24+ messages in thread
From: Denis KENZIOR @ 2007-05-03  5:00 UTC (permalink / raw)
  To: BlueZ development

Mayank,

> How about the 2-EV* and 3-EV* packet types? The spec says that a 0 for
> these bits means they have been enabled. Shouldn't you also check for their
> support in the feature mask?

Good question.  I'm not entirely sure of this, however I did not interpret the 
specification in this manner.  All it says is that there is a specific 
feature mask to disable 2-EV and 3-EV packets.  There is nothing to say 
whether or not they are explicitly enabled.  Also the examples in the 
specification use the esco feature masks in the same manner as I do.  So I 
would assume that if EV3 support is not enabled, then 2-EV3 and 3-EV3 packets 
will not be used by the controller as well.  However, I could be wrong.

>
> > I've tested it on several machines here, including eSco->eSco
> > connection, eSco->sco connection for both incoming and outgoing
> > scenarios, everything seems fine, however I'm sure more testing is
> > required.
>
> How did you mangage to set up an eSCO since you are using only HV* packet
> types (ESCO_PTYPE_MASK)? Or is it because the 2-EV* and 3-EV* bits are "0"
> thus the controller thinks you want to enable those packet types?

Well, it comes down to what the controller labels as an eSCO connection.  E.g. 
the link_type returned in the connection complete and sync connection 
complete events.  Doing BlueZ<->BlueZ which both use the patch, I get 
link_type of eSCO.  Doing BlueZ<->BlueZ with one end not using the patch, I 
get a link_type of SCO.  Perhaps it is the particular hardware I'm using?

Setup is a STLC2500 serial device connected to a BT1.2 USB dongle on a 
non-patched kernel and a BT 2.0 USB dongle on a patched kernel.

Regards,
-Denis


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-05-03  5:00                   ` Denis KENZIOR
@ 2007-05-03  5:16                     ` Marcel Holtmann
  2007-05-03  5:23                       ` Mayank BATRA
  2007-05-03  5:24                       ` Denis KENZIOR
  0 siblings, 2 replies; 24+ messages in thread
From: Marcel Holtmann @ 2007-05-03  5:16 UTC (permalink / raw)
  To: BlueZ development

Hi Denis,

> > How about the 2-EV* and 3-EV* packet types? The spec says that a 0 for
> > these bits means they have been enabled. Shouldn't you also check for their
> > support in the feature mask?
> 
> Good question.  I'm not entirely sure of this, however I did not interpret the 
> specification in this manner.  All it says is that there is a specific 
> feature mask to disable 2-EV and 3-EV packets.  There is nothing to say 
> whether or not they are explicitly enabled.  Also the examples in the 
> specification use the esco feature masks in the same manner as I do.  So I 
> would assume that if EV3 support is not enabled, then 2-EV3 and 3-EV3 packets 
> will not be used by the controller as well.  However, I could be wrong.

don't worry about packet types. This is the link managers job. Enable as
much packet types as possible.

> > > I've tested it on several machines here, including eSco->eSco
> > > connection, eSco->sco connection for both incoming and outgoing
> > > scenarios, everything seems fine, however I'm sure more testing is
> > > required.
> >
> > How did you mangage to set up an eSCO since you are using only HV* packet
> > types (ESCO_PTYPE_MASK)? Or is it because the 2-EV* and 3-EV* bits are "0"
> > thus the controller thinks you want to enable those packet types?
> 
> Well, it comes down to what the controller labels as an eSCO connection.  E.g. 
> the link_type returned in the connection complete and sync connection 
> complete events.  Doing BlueZ<->BlueZ which both use the patch, I get 
> link_type of eSCO.  Doing BlueZ<->BlueZ with one end not using the patch, I 
> get a link_type of SCO.  Perhaps it is the particular hardware I'm using?

No. It is the difference between using Accept Connection Request or
Accept Synchronous Connection Request. In the first case it has to fall
back to SCO since it has no further information on how to negotiate an
eSCO link.

Regards

Marcel



-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-05-03  5:16                     ` Marcel Holtmann
@ 2007-05-03  5:23                       ` Mayank BATRA
  2007-05-03  5:29                         ` Marcel Holtmann
  2007-05-03  5:24                       ` Denis KENZIOR
  1 sibling, 1 reply; 24+ messages in thread
From: Mayank BATRA @ 2007-05-03  5:23 UTC (permalink / raw)
  To: 'BlueZ development'

Hi Marcel,

On Thursday, May 03, 2007 10:47 AM +0530, Marcel Holtmann wrote:
>>> How about the 2-EV* and 3-EV* packet types? The spec says that a 0
>>> for these bits means they have been enabled. Shouldn't you also
>>> check for their support in the feature mask?
>> 
>> Good question.  I'm not entirely sure of this, however I did not
>> interpret the specification in this manner.  All it says is that
>> there is a specific feature mask to disable 2-EV and 3-EV packets. 
>> There is nothing to say whether or not they are explicitly enabled. 
>> Also the examples in the specification use the esco feature masks in
>> the same manner as I do.  So I would assume that if EV3 support is
>> not enabled, then 2-EV3 and 3-EV3 packets will not be used by the
>> controller as well.  However, I could be wrong. 
> 
> don't worry about packet types. This is the link managers job. Enable
> as much packet types as possible.

But you'll fall into trouble if the local controller does not support
the packet type that you've enabled.
In Denis' case it worked because the device supported the 2-EV* and
3-EV* packet types and he "accidentaly" enabled them.
Why not check their support in the feature mask as well?

Regards,

Mayank


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-05-03  5:16                     ` Marcel Holtmann
  2007-05-03  5:23                       ` Mayank BATRA
@ 2007-05-03  5:24                       ` Denis KENZIOR
  2007-05-03  5:28                         ` Marcel Holtmann
  1 sibling, 1 reply; 24+ messages in thread
From: Denis KENZIOR @ 2007-05-03  5:24 UTC (permalink / raw)
  To: BlueZ development

Marcel,

> don't worry about packet types. This is the link managers job. Enable as
> much packet types as possible.

OK, that is what I thought as well.

>
> No. It is the difference between using Accept Connection Request or
> Accept Synchronous Connection Request. In the first case it has to fall
> back to SCO since it has no further information on how to negotiate an
> eSCO link.

This is strange, because I would send an accept_sync_conn, get a 
sync_conn_complete_event and the link_type would be 0x0 (SCO) when connecting 
to an unpatched BlueZ box.  Again, I imagine more testing is required.

Regards,

-Denis

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-05-03  3:57               ` Denis KENZIOR
  2007-05-03  4:38                 ` Mayank BATRA
@ 2007-05-03  5:25                 ` Marcel Holtmann
  2007-05-04  7:36                   ` Denis KENZIOR
  1 sibling, 1 reply; 24+ messages in thread
From: Marcel Holtmann @ 2007-05-03  5:25 UTC (permalink / raw)
  To: BlueZ development

Hi Denis,

> Here's a modified patch that implements eSCO sockets, including incoming SCO 
> connections.  This was a merge of my previous work for the 2.4 series of 
> kernels, so some variables might be named differently than in your patch.

please make sure you use my naming of variables. Otherwise it is too
much confusion. And please create a patch relative to this one so I can
actually review it. And please keep hci_setup_sync(). Doing the
separation this way it more logical than hacking up hci_add_sco(). The
function that decides which command to use should be hci_connect().

> > this patch is incomplete. It doesn't handle incoming eSCO connections
> > and it can't handle SCO audio packets over HCI when a real eSCO
> > connection has been established.
> 
> Why do you say this? What is required in order to get eSCO packets flowing?

If you have type == ESCO_LINK then the kernel doesn't send these packets
over the transport layer.

Regards

Marcel



-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-05-03  5:24                       ` Denis KENZIOR
@ 2007-05-03  5:28                         ` Marcel Holtmann
  0 siblings, 0 replies; 24+ messages in thread
From: Marcel Holtmann @ 2007-05-03  5:28 UTC (permalink / raw)
  To: BlueZ development

Hi Denis,

> > No. It is the difference between using Accept Connection Request or
> > Accept Synchronous Connection Request. In the first case it has to fall
> > back to SCO since it has no further information on how to negotiate an
> > eSCO link.
> 
> This is strange, because I would send an accept_sync_conn, get a 
> sync_conn_complete_event and the link_type would be 0x0 (SCO) when connecting 
> to an unpatched BlueZ box.  Again, I imagine more testing is required.

but the unpatched side replies with a Accept Connection Request and this
can only lead to a SCO link since no additional parameters for the eSCO
negotiation are available.

Regards

Marcel



-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-05-03  5:23                       ` Mayank BATRA
@ 2007-05-03  5:29                         ` Marcel Holtmann
  0 siblings, 0 replies; 24+ messages in thread
From: Marcel Holtmann @ 2007-05-03  5:29 UTC (permalink / raw)
  To: BlueZ development

Hi Mayank,

> >>> How about the 2-EV* and 3-EV* packet types? The spec says that a 0
> >>> for these bits means they have been enabled. Shouldn't you also
> >>> check for their support in the feature mask?
> >> 
> >> Good question.  I'm not entirely sure of this, however I did not
> >> interpret the specification in this manner.  All it says is that
> >> there is a specific feature mask to disable 2-EV and 3-EV packets. 
> >> There is nothing to say whether or not they are explicitly enabled. 
> >> Also the examples in the specification use the esco feature masks in
> >> the same manner as I do.  So I would assume that if EV3 support is
> >> not enabled, then 2-EV3 and 3-EV3 packets will not be used by the
> >> controller as well.  However, I could be wrong. 
> > 
> > don't worry about packet types. This is the link managers job. Enable
> > as much packet types as possible.
> 
> But you'll fall into trouble if the local controller does not support
> the packet type that you've enabled.
> In Denis' case it worked because the device supported the 2-EV* and
> 3-EV* packet types and he "accidentaly" enabled them.
> Why not check their support in the feature mask as well?

this is not needed. Unknown or reserved bits should be ignored. That is
the job of the link manager. And btw. it works fine for ACL EDR packets.
If you have a problem then the link manager firmware authors read the
specification wrong.

Regards

Marcel



-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] Esco implementation patch
  2007-05-03  5:25                 ` Marcel Holtmann
@ 2007-05-04  7:36                   ` Denis KENZIOR
  2007-05-04  8:53                     ` [Bluez-devel] sdpd and multiple bluetooth devices Olivier Le Pogam
  0 siblings, 1 reply; 24+ messages in thread
From: Denis KENZIOR @ 2007-05-04  7:36 UTC (permalink / raw)
  To: BlueZ development

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

Marcel,

> please make sure you use my naming of variables. Otherwise it is too
> much confusion. And please create a patch relative to this one so I can
> actually review it. And please keep hci_setup_sync(). Doing the
> separation this way it more logical than hacking up hci_add_sco(). The
> function that decides which command to use should be hci_connect().

Attached is a patch against yours.

Can you point me in the right direction with regard to adding ESCO packets to 
be transported over HCI?

Also, I noticed that SCO connections are accepted regardless of whether a SCO 
socket is open or not.  Is this intended?

-Denis

[-- Attachment #2: esco-patch-marcels-changes.patch --]
[-- Type: text/x-diff, Size: 8118 bytes --]

diff -p -U5 -r linux-2.6.21.1/include/net/bluetooth/hci.h linux-2.6.21.1-dkenzior/include/net/bluetooth/hci.h
--- linux-2.6.21.1/include/net/bluetooth/hci.h	2007-05-04 13:30:11.000000000 +1000
+++ linux-2.6.21.1-dkenzior/include/net/bluetooth/hci.h	2007-05-04 13:54:53.000000000 +1000
@@ -135,10 +135,15 @@ enum {
 #define ESCO_HV3	0x0004
 #define ESCO_EV3	0x0008
 #define ESCO_EV4	0x0010
 #define ESCO_EV5	0x0020
 
+/* Some devices seem to have trouble establishing EV* packet connections */
+/* with other devices.  For this reason we mask out the eSCO packets */ 
+/* for now.  Might need to address this later */
+#define ESCO_PTYPE_MASK	(ESCO_HV1 | ESCO_HV2 | ESCO_HV3)
+
 /* ACL flags */
 #define ACL_CONT		0x01
 #define ACL_START		0x02
 #define ACL_ACTIVE_BCAST	0x04
 #define ACL_PICO_BCAST		0x08
diff -p -U5 -r linux-2.6.21.1/net/bluetooth/hci_conn.c linux-2.6.21.1-dkenzior/net/bluetooth/hci_conn.c
--- linux-2.6.21.1/net/bluetooth/hci_conn.c	2007-05-04 13:33:00.000000000 +1000
+++ linux-2.6.21.1-dkenzior/net/bluetooth/hci_conn.c	2007-05-04 14:02:57.000000000 +1000
@@ -138,11 +138,11 @@ void hci_setup_sync(struct hci_conn *con
 
 	conn->state = BT_CONNECT;
 	conn->out = 1;
 
 	cp.handle   = cpu_to_le16(handle);
-	cp.pkt_type = cpu_to_le16(hdev->esco_type);
+	cp.pkt_type = cpu_to_le16(hdev->esco_type & ESCO_PTYPE_MASK);
 
 	cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
 	cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
 	cp.max_latency    = cpu_to_le16(0xffff);
 	cp.voice_setting  = cpu_to_le16(hdev->voice_setting);
diff -p -U5 -r linux-2.6.21.1/net/bluetooth/hci_event.c linux-2.6.21.1-dkenzior/net/bluetooth/hci_event.c
--- linux-2.6.21.1/net/bluetooth/hci_event.c	2007-05-04 13:30:11.000000000 +1000
+++ linux-2.6.21.1-dkenzior/net/bluetooth/hci_event.c	2007-05-04 15:47:15.000000000 +1000
@@ -369,10 +369,11 @@ static void hci_cc_info_param(struct hci
 		if (hdev->features[4] & LMP_EV5)
 			hdev->esco_type |= ESCO_EV5;
 
 		BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name,
 				lf->features[0], lf->features[1], lf->features[2]);
+		BT_DBG("%s: eSco packets: 0x%x", hdev->name, hdev->esco_type);
 
 		break;
 
 	case OCF_READ_BUFFER_SIZE:
 		bs = (struct hci_rp_read_buffer_size *) skb->data;
@@ -756,11 +757,10 @@ static inline void hci_conn_request_evt(
 	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
 
 	if (mask & HCI_LM_ACCEPT) {
 		/* Connection accepted */
 		struct hci_conn *conn;
-		struct hci_cp_accept_conn_req cp;
 
 		hci_dev_lock(hdev);
 		conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
 		if (!conn) {
 			if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
@@ -771,27 +771,55 @@ static inline void hci_conn_request_evt(
 		}
 		memcpy(conn->dev_class, ev->dev_class, 3);
 		conn->state = BT_CONNECT;
 		hci_dev_unlock(hdev);
 
-		bacpy(&cp.bdaddr, &ev->bdaddr);
+		if ((ev->link_type == ACL_LINK) || (!lmp_esco_capable(hdev))) {
+			struct hci_cp_accept_conn_req cp;
+			bacpy(&cp.bdaddr, &ev->bdaddr);
 
-		if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
-			cp.role = 0x00; /* Become master */
-		else
-			cp.role = 0x01; /* Remain slave */
+			if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
+				cp.role = 0x00; /* Become master */
+			else
+				cp.role = 0x01; /* Remain slave */
 
-		hci_send_cmd(hdev, OGF_LINK_CTL,
-				OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp);
+			hci_send_cmd(hdev, OGF_LINK_CTL,
+					OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp);
+		} else {
+			/* Send the Accept Sync Connection Command */
+			struct hci_cp_accept_sync_conn_req cp;
+			
+			bacpy(&cp.bdaddr, &ev->bdaddr);
+			cp.pkt_type = __cpu_to_le16(hdev->esco_type & ESCO_PTYPE_MASK);
+			cp.tx_bandwidth = __cpu_to_le32(0x00001f40);
+			cp.rx_bandwidth = __cpu_to_le32(0x00001f40);
+			cp.max_latency = __cpu_to_le16(0xffff);
+			cp.content_format = __cpu_to_le16(hdev->voice_setting);
+			cp.retrans_effort = 0xff;
+
+			hci_send_cmd(hdev, OGF_LINK_CTL,
+					OCF_ACCEPT_SYNC_CONN_REQ, sizeof(cp), &cp);
+		}
 	} else {
 		/* Connection rejected */
-		struct hci_cp_reject_conn_req cp;
 
-		bacpy(&cp.bdaddr, &ev->bdaddr);
-		cp.reason = 0x0f;
-		hci_send_cmd(hdev, OGF_LINK_CTL,
-				OCF_REJECT_CONN_REQ, sizeof(cp), &cp);
+		if ((ev->link_type == ACL_LINK) || (!lmp_esco_capable(hdev))) {
+			struct hci_cp_reject_conn_req cp;
+
+			bacpy(&cp.bdaddr, &ev->bdaddr);
+			cp.reason = 0x0f;
+			hci_send_cmd(hdev, OGF_LINK_CTL,
+					OCF_REJECT_CONN_REQ, sizeof(cp), &cp);
+		} else {
+			struct hci_cp_reject_sync_conn_req cp;
+			
+			bacpy(&cp.bdaddr, &ev->bdaddr);
+			cp.reason = 0x0f;
+
+			hci_send_cmd(hdev, OGF_LINK_CTL,
+					OCF_REJECT_SYNC_CONN_REQ, sizeof(cp), &cp);
+		}
 	}
 }
 
 /* Connect Complete */
 static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
@@ -878,10 +906,60 @@ static inline void hci_conn_complete_evt
 		hci_acl_connect(pend);
 
 	hci_dev_unlock(hdev);
 }
 
+/* eSCO Connect Complete */
+static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_ev_sync_conn_complete *ev = (struct hci_ev_sync_conn_complete *) skb->data;
+	struct hci_conn *conn;
+
+	BT_DBG("%s", hdev->name);
+
+	hci_dev_lock(hdev);
+
+	/* There are two possibilities here.  We establish an outgoing ESCO link and get */
+	/* back a SCO link.  Or we got a connect request with a SCO/ESCO link type and */
+	/* arrived here once it was established */
+	conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
+	if (!conn) {
+		/* Incoming SCO case */
+		conn = hci_conn_hash_lookup_ba(hdev, SCO_LINK, &ev->bdaddr);
+		if (!conn) {
+			hci_dev_unlock(hdev);
+			return;
+		}
+
+		if (conn->out) {
+			BT_DBG("ended up with a SCO link");
+			hci_conn_del(conn);
+			hci_dev_unlock(hdev);
+			return;
+		}
+	}
+
+	if (!ev->status) {
+		conn->handle = __le16_to_cpu(ev->handle);
+		conn->type = ev->link_type;
+		conn->state  = BT_CONNECTED;
+
+		if (conn->out) {
+			/* Update disconnect timer */
+			hci_conn_hold(conn);
+			hci_conn_put(conn);
+		}
+	} else
+		conn->state = BT_CLOSED;
+
+	hci_proto_connect_cfm(conn, ev->status);
+	if (ev->status)
+		hci_conn_del(conn);
+
+	hci_dev_unlock(hdev);
+}
+
 /* Disconnect Complete */
 static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_ev_disconn_complete *ev = (struct hci_ev_disconn_complete *) skb->data;
 	struct hci_conn *conn;
@@ -1157,40 +1235,10 @@ static inline void hci_pscan_rep_mode_ev
 	}
 
 	hci_dev_unlock(hdev);
 }
 
-/* Synchronous Connection Complete Event */
-static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-	struct hci_ev_sync_conn_complete *ev = (struct hci_ev_sync_conn_complete *) skb->data;
-	struct hci_conn *conn;
-
-	BT_DBG("%s status %d", hdev->name, ev->status);
-
-	hci_dev_lock(hdev);
-
-	conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
-	if (!conn) {
-		hci_dev_unlock(hdev);
-		return;
-	}
-
-	if (!ev->status) {
-		conn->handle = __le16_to_cpu(ev->handle);
-		conn->type   = ev->link_type;
-		conn->state  = BT_CONNECTED;
-	} else
-		conn->state = BT_CLOSED;
-
-	hci_proto_connect_cfm(conn, ev->status);
-	if (ev->status)
-		hci_conn_del(conn);
-
-	hci_dev_unlock(hdev);
-}
-
 /* Sniff Subrate */
 static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_ev_sniff_subrate *ev = (struct hci_ev_sniff_subrate *) skb->data;
 	struct hci_conn *conn;
diff -p -U5 -r linux-2.6.21.1/net/bluetooth/sco.c linux-2.6.21.1-dkenzior/net/bluetooth/sco.c
--- linux-2.6.21.1/net/bluetooth/sco.c	2007-05-04 13:30:11.000000000 +1000
+++ linux-2.6.21.1-dkenzior/net/bluetooth/sco.c	2007-05-04 13:33:31.000000000 +1000
@@ -838,10 +838,13 @@ done:
 /* ----- SCO interface with lower layer (HCI) ----- */
 static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
 {
 	BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
 
+	if (type != SCO_LINK && type != ESCO_LINK)
+		return 0;
+
 	/* Always accept connection */
 	return HCI_LM_ACCEPT;
 }
 
 static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)

[-- Attachment #3: Type: text/plain, Size: 286 bytes --]

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/

[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* [Bluez-devel] sdpd and multiple bluetooth devices
  2007-05-04  7:36                   ` Denis KENZIOR
@ 2007-05-04  8:53                     ` Olivier Le Pogam
  2007-05-04  9:18                       ` Marcel Holtmann
  0 siblings, 1 reply; 24+ messages in thread
From: Olivier Le Pogam @ 2007-05-04  8:53 UTC (permalink / raw)
  To: BlueZ development

Hello,

I'm sorry I think this is a very simple question ...

I have 2 devices hci0 and hci1 and I'd like to manage
services on both with sdptool.

Could you please tell me how I should configure
/etc/rc.d/init.d/bluetooth
so I have 2 SDP databases, one for each device ?
... for now I just have "daemon sdpd" in this file

Then can I use sdptool -i hciN ... ?

Thanks a lot,
Oli

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

* Re: [Bluez-devel] sdpd and multiple bluetooth devices
  2007-05-04  8:53                     ` [Bluez-devel] sdpd and multiple bluetooth devices Olivier Le Pogam
@ 2007-05-04  9:18                       ` Marcel Holtmann
  0 siblings, 0 replies; 24+ messages in thread
From: Marcel Holtmann @ 2007-05-04  9:18 UTC (permalink / raw)
  To: Olivier Le Pogam, BlueZ development

Hi Olivier,

> I'm sorry I think this is a very simple question ...
> 
> I have 2 devices hci0 and hci1 and I'd like to manage
> services on both with sdptool.
> 
> Could you please tell me how I should configure
> /etc/rc.d/init.d/bluetooth
> so I have 2 SDP databases, one for each device ?
> ... for now I just have "daemon sdpd" in this file
> 
> Then can I use sdptool -i hciN ... ?

I think that sdptool doesn't handle the case of two different SDP
databases. You have to use the Bluetooth library directly.

Regards

Marcel



-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

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

end of thread, other threads:[~2007-05-04  9:18 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-25  6:58 [Bluez-devel] Esco implementation patch Sumeet VERMA
2007-04-25  7:44 ` Marcel Holtmann
2007-04-26  4:56   ` Sumeet VERMA
2007-04-26  5:19     ` Denis KENZIOR
2007-04-26  6:24       ` Mayank BATRA
2007-04-26  6:29       ` Sumeet VERMA
2007-04-26 10:19         ` dkenzior
2007-04-26 10:36           ` Sumeet VERMA
2007-04-26 14:18             ` Marcel Holtmann
2007-04-26 19:40         ` Marcel Holtmann
2007-04-27  7:50           ` Sumeet VERMA
2007-05-01 11:24             ` Marcel Holtmann
2007-05-03  3:57               ` Denis KENZIOR
2007-05-03  4:38                 ` Mayank BATRA
2007-05-03  5:00                   ` Denis KENZIOR
2007-05-03  5:16                     ` Marcel Holtmann
2007-05-03  5:23                       ` Mayank BATRA
2007-05-03  5:29                         ` Marcel Holtmann
2007-05-03  5:24                       ` Denis KENZIOR
2007-05-03  5:28                         ` Marcel Holtmann
2007-05-03  5:25                 ` Marcel Holtmann
2007-05-04  7:36                   ` Denis KENZIOR
2007-05-04  8:53                     ` [Bluez-devel] sdpd and multiple bluetooth devices Olivier Le Pogam
2007-05-04  9:18                       ` Marcel Holtmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).