All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marcel Holtmann <marcel@holtmann.org>
To: BlueZ development <bluez-devel@lists.sourceforge.net>
Subject: Re: [Bluez-devel] Esco implementation patch
Date: Tue, 01 May 2007 13:24:54 +0200	[thread overview]
Message-ID: <1178018694.25217.8.camel@violet> (raw)
In-Reply-To: <016001c788a0$b7b229c0$8935c70a@dlh.st.com>

[-- 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

  reply	other threads:[~2007-05-01 11:24 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1178018694.25217.8.camel@violet \
    --to=marcel@holtmann.org \
    --cc=bluez-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.