linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jaganath Kanakkassery <jaganath.k.os@gmail.com>
To: linux-bluetooth@vger.kernel.org
Cc: Jaganath Kanakkassery <jaganathx.kanakkassery@intel.com>
Subject: [PATCH v1 05/18] Bluetooth: Use extended LE Connection if supported
Date: Thu, 12 Apr 2018 16:49:34 +0530	[thread overview]
Message-ID: <1523531987-17140-6-git-send-email-jaganathx.kanakkassery@intel.com> (raw)
In-Reply-To: <1523531987-17140-1-git-send-email-jaganathx.kanakkassery@intel.com>

This implements extended LE craete connection and enhanced
LE conn complete event if the controller supports.

For now it is as good as legacy LE connection and event as
no new features in the extended connection is handled.

< HCI Command: LE Extended Create Connection (0x08|0x0043) plen 26
        Filter policy: White list is not used (0x00)
        Own address type: Public (0x00)
        Peer address type: Random (0x01)
        Peer address: DB:7E:2E:1D:85:E8 (Static)
        Initiating PHYs: 0x01
        Entry 0: LE 1M
          Scan interval: 60.000 msec (0x0060)
          Scan window: 60.000 msec (0x0060)
          Min connection interval: 50.00 msec (0x0028)
          Max connection interval: 70.00 msec (0x0038)
          Connection latency: 0 (0x0000)
          Supervision timeout: 420 msec (0x002a)
          Min connection length: 0.000 msec (0x0000)
          Max connection length: 0.000 msec (0x0000)
> HCI Event: Command Status (0x0f) plen 4
      LE Extended Create Connection (0x08|0x0043) ncmd 2
        Status: Success (0x00)
> HCI Event: LE Meta Event (0x3e) plen 31
      LE Enhanced Connection Complete (0x0a)
        Status: Success (0x00)
        Handle: 3585
        Role: Master (0x00)
        Peer address type: Random (0x01)
        Peer address: DB:7E:2E:1D:85:E8 (Static)
        Local resolvable private address: 00:00:00:00:00:00 (Non-Resolvable)
        Peer resolvable private address: 00:00:00:00:00:00 (Non-Resolvable)
        Connection interval: 67.50 msec (0x0036)
        Connection latency: 0 (0x0000)
        Supervision timeout: 420 msec (0x002a)
        Master clock accuracy: 0x00
@ MGMT Event: Device Connected (0x000b) plen 40
        LE Address: DB:7E:2E:1D:85:E8 (Static)
        Flags: 0x00000000
        Data length: 27
        Name (complete): Designer Mouse
        Appearance: Mouse (0x03c2)
        Flags: 0x05
          LE Limited Discoverable Mode
          BR/EDR Not Supported
        16-bit Service UUIDs (complete): 1 entry
          Human Interface Device (0x1812)

Signed-off-by: Jaganath Kanakkassery <jaganathx.kanakkassery@intel.com>
---
 include/net/bluetooth/hci.h      | 36 ++++++++++++++++++++
 include/net/bluetooth/hci_core.h |  2 ++
 net/bluetooth/hci_conn.c         | 72 ++++++++++++++++++++++++++++++----------
 net/bluetooth/hci_core.c         |  6 ++++
 net/bluetooth/hci_event.c        | 47 ++++++++++++++++++++++++++
 5 files changed, 145 insertions(+), 18 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 34eaaf9..85ceeb9 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1530,6 +1530,27 @@ struct hci_cp_le_set_ext_scan_enable {
 	__le16  period;
 } __packed;
 
+#define HCI_OP_LE_EXT_CREATE_CONN    0x2043
+struct hci_cp_le_ext_create_conn {
+	__u8      filter_policy;
+	__u8      own_addr_type;
+	__u8      peer_addr_type;
+	bdaddr_t  peer_addr;
+	__u8      phys;
+	__u8      data[0];
+} __packed;
+
+struct hci_cp_le_ext_conn_param {
+	__le16 scan_interval;
+	__le16 scan_window;
+	__le16 conn_interval_min;
+	__le16 conn_interval_max;
+	__le16 conn_latency;
+	__le16 supervision_timeout;
+	__le16 min_ce_len;
+	__le16 max_ce_len;
+} __packed;
+
 /* ---- HCI Events ---- */
 #define HCI_EV_INQUIRY_COMPLETE		0x01
 
@@ -2007,6 +2028,21 @@ struct hci_ev_le_ext_adv_report {
 	__u8	 data[0];
 } __packed;
 
+#define HCI_EV_LE_ENHANCED_CONN_COMPLETE    0x0a
+struct hci_ev_le_enh_conn_complete {
+	__u8      status;
+	__le16    handle;
+	__u8      role;
+	__u8      bdaddr_type;
+	bdaddr_t  bdaddr;
+	bdaddr_t  local_rpa;
+	bdaddr_t  peer_rpa;
+	__le16    interval;
+	__le16    latency;
+	__le16    supervision_timeout;
+	__u8      clk_accurancy;
+} __packed;
+
 /* Internal events generated by Bluetooth stack */
 #define HCI_EV_STACK_INTERNAL	0xfd
 struct hci_ev_stack_internal {
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 4b32601..b0021ba 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1160,6 +1160,8 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
 #define use_ext_scan(dev) (((dev)->commands[37] & 0x20) && \
 			   ((dev)->commands[37] & 0x40))
 
+#define use_ext_conn(dev) ((dev)->commands[37] & 0x80)
+
 /* ----- HCI protocols ----- */
 #define HCI_PROTO_DEFER             0x01
 
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index a968253..db4118e 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -751,7 +751,6 @@ static bool conn_use_rpa(struct hci_conn *conn)
 static void hci_req_add_le_create_conn(struct hci_request *req,
 				       struct hci_conn *conn)
 {
-	struct hci_cp_le_create_conn cp;
 	struct hci_dev *hdev = conn->hdev;
 	u8 own_addr_type;
 
@@ -762,25 +761,62 @@ static void hci_req_add_le_create_conn(struct hci_request *req,
 				      &own_addr_type))
 		return;
 
-	memset(&cp, 0, sizeof(cp));
+	if (use_ext_conn(hdev)) {
+		struct hci_cp_le_ext_create_conn *cp;
+		struct hci_cp_le_ext_conn_param *p;
+		/* As of now only LE 1M is supported */
+		u8 data[sizeof(*cp) + sizeof(*p) * 1];
 
-	/* Set window to be the same value as the interval to enable
-	 * continuous scanning.
-	 */
-	cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
-	cp.scan_window = cp.scan_interval;
+		cp = (void *) data;
+		p = (void *) cp->data;
 
-	bacpy(&cp.peer_addr, &conn->dst);
-	cp.peer_addr_type = conn->dst_type;
-	cp.own_address_type = own_addr_type;
-	cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
-	cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
-	cp.conn_latency = cpu_to_le16(conn->le_conn_latency);
-	cp.supervision_timeout = cpu_to_le16(conn->le_supv_timeout);
-	cp.min_ce_len = cpu_to_le16(0x0000);
-	cp.max_ce_len = cpu_to_le16(0x0000);
-
-	hci_req_add(req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
+		memset(cp, 0, sizeof(*cp));
+
+		bacpy(&cp->peer_addr, &conn->dst);
+		cp->peer_addr_type = conn->dst_type;
+		cp->own_addr_type = own_addr_type;
+		cp->phys = LE_SCAN_PHY_1M;
+
+		memset(p, 0, sizeof(*p));
+
+		/* Set window to be the same value as the interval to enable
+		 * continuous scanning.
+		 */
+
+		p->scan_interval = cpu_to_le16(hdev->le_scan_interval);
+		p->scan_window = p->scan_interval;
+		p->conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
+		p->conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
+		p->conn_latency = cpu_to_le16(conn->le_conn_latency);
+		p->supervision_timeout = cpu_to_le16(conn->le_supv_timeout);
+		p->min_ce_len = cpu_to_le16(0x0000);
+		p->max_ce_len = cpu_to_le16(0x0000);
+
+		hci_req_add(req, HCI_OP_LE_EXT_CREATE_CONN, sizeof(data), data);
+
+	} else {
+		struct hci_cp_le_create_conn cp;
+
+		memset(&cp, 0, sizeof(cp));
+
+		/* Set window to be the same value as the interval to enable
+		 * continuous scanning.
+		 */
+		cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
+		cp.scan_window = cp.scan_interval;
+
+		bacpy(&cp.peer_addr, &conn->dst);
+		cp.peer_addr_type = conn->dst_type;
+		cp.own_address_type = own_addr_type;
+		cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
+		cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
+		cp.conn_latency = cpu_to_le16(conn->le_conn_latency);
+		cp.supervision_timeout = cpu_to_le16(conn->le_supv_timeout);
+		cp.min_ce_len = cpu_to_le16(0x0000);
+		cp.max_ce_len = cpu_to_le16(0x0000);
+
+		hci_req_add(req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
+	}
 
 	conn->state = BT_CONNECT;
 	clear_bit(HCI_CONN_SCANNING, &conn->flags);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 8a0954b..cdc9616 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -711,6 +711,12 @@ static int hci_init3_req(struct hci_request *req, unsigned long opt)
 		if (use_ext_scan(hdev))
 			events[1] |= 0x10;	/* LE Extended adv report */
 
+		/* If the controller supports the LE Extended connection
+		 *  enable the corresponding event.
+		 */
+		if (use_ext_conn(hdev))
+			events[1] |= 0x02;      /* LE Enhanced conn complete */
+
 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events),
 			    events);
 
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index f651feb..4d757a5 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2004,6 +2004,31 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
 	hci_dev_unlock(hdev);
 }
 
+static void hci_cs_le_ext_create_conn(struct hci_dev *hdev, u8 status)
+{
+	struct hci_cp_le_ext_create_conn *cp;
+
+	BT_DBG("%s status 0x%2.2x", hdev->name, status);
+
+	/* All connection failure handling is taken care of by the
+	 * hci_le_conn_failed function which is triggered by the HCI
+	 * request completion callbacks used for connecting.
+	 */
+	if (status)
+		return;
+
+	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_EXT_CREATE_CONN);
+	if (!cp)
+		return;
+
+	hci_dev_lock(hdev);
+
+	cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type,
+			  cp->own_addr_type, cp->filter_policy);
+
+	hci_dev_unlock(hdev);
+}
+
 static void hci_cs_le_read_remote_features(struct hci_dev *hdev, u8 status)
 {
 	struct hci_cp_le_read_remote_features *cp;
@@ -3198,6 +3223,10 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb,
 		hci_cs_le_start_enc(hdev, ev->status);
 		break;
 
+	case HCI_OP_LE_EXT_CREATE_CONN:
+		hci_cs_le_ext_create_conn(hdev, ev->status);
+		break;
+
 	default:
 		BT_DBG("%s opcode 0x%4.4x", hdev->name, *opcode);
 		break;
@@ -4698,6 +4727,20 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 			     le16_to_cpu(ev->supervision_timeout));
 }
 
+static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev,
+					 struct sk_buff *skb)
+{
+	struct hci_ev_le_enh_conn_complete *ev = (void *) skb->data;
+
+	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
+
+	le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type,
+			     ev->role, le16_to_cpu(ev->handle),
+			     le16_to_cpu(ev->interval),
+			     le16_to_cpu(ev->latency),
+			     le16_to_cpu(ev->supervision_timeout));
+}
+
 static void hci_le_conn_update_complete_evt(struct hci_dev *hdev,
 					    struct sk_buff *skb)
 {
@@ -5306,6 +5349,10 @@ static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_le_ext_adv_report_evt(hdev, skb);
 		break;
 
+	case HCI_EV_LE_ENHANCED_CONN_COMPLETE:
+		hci_le_enh_conn_complete_evt(hdev, skb);
+		break;
+
 	default:
 		break;
 	}
-- 
2.7.4


  parent reply	other threads:[~2018-04-12 11:19 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-12 11:19 [PATCH v1 00/18] Extended Adv, Scan, Connection and PHY support Jaganath Kanakkassery
2018-04-12 11:19 ` [PATCH v1 01/18] Bluetooth: Introduce helpers for LE set scan start and complete Jaganath Kanakkassery
2018-04-12 11:19 ` [PATCH v1 02/18] Bluetooth: Use extended scanning if controller supports Jaganath Kanakkassery
2018-04-12 11:19 ` [PATCH v1 03/18] Bluetooth: Process extended ADV report event Jaganath Kanakkassery
2018-04-12 11:19 ` [PATCH v1 04/18] Bluetooth: Introduce helpers for le conn status and complete Jaganath Kanakkassery
2018-04-12 11:19 ` Jaganath Kanakkassery [this message]
2018-04-12 11:19 ` [PATCH v1 06/18] Bluetooth: Define PHY flags in hdev and set 1M as default Jaganath Kanakkassery
2018-04-12 11:19 ` [PATCH v1 07/18] Bluetooth: Implement Get PHY Configuration mgmt command Jaganath Kanakkassery
2018-04-12 11:19 ` [PATCH v1 08/18] Bluetooth: Implement Set PHY Confguration command Jaganath Kanakkassery
2018-04-12 11:19 ` [PATCH v1 09/18] Bluetooth: Set Scan PHYs based on selected PHYs by user Jaganath Kanakkassery
2018-04-12 11:19 ` [PATCH v1 10/18] Bluetooth: Handle extended ADV PDU types Jaganath Kanakkassery
2018-04-12 11:19 ` [PATCH v1 11/18] Bluetooth: Use selected PHYs in extended connect Jaganath Kanakkassery
2018-04-12 11:19 ` [PATCH v1 12/18] Bluetooth: Read no of adv sets during init Jaganath Kanakkassery
2018-04-12 11:19 ` [PATCH v1 13/18] Bluetooth: Impmlement extended adv enable Jaganath Kanakkassery
2018-04-12 11:19 ` [PATCH v1 14/18] Bluetooth: Use Set ext adv/scan rsp data if controller supports Jaganath Kanakkassery
2018-04-12 11:19 ` [PATCH v1 15/18] Bluetooth: Implement disable and removal of adv instance Jaganath Kanakkassery
2018-04-13 16:28   ` kbuild test robot
2018-04-13 16:28   ` [RFC PATCH] Bluetooth: __hci_req_remove_ext_adv_set() can be static kbuild test robot
2018-04-12 11:19 ` [PATCH v1 16/18] Bluetooth: Use ext adv for directed adv Jaganath Kanakkassery
2018-04-13 14:29   ` kbuild test robot
2018-04-12 11:19 ` [PATCH v1 17/18] Bluetooth: Implement Set ADV set random address Jaganath Kanakkassery
2018-04-12 11:19 ` [PATCH v1 18/18] Bluetooth: Implement secondary advertising on different PHYs Jaganath Kanakkassery

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=1523531987-17140-6-git-send-email-jaganathx.kanakkassery@intel.com \
    --to=jaganath.k.os@gmail.com \
    --cc=jaganathx.kanakkassery@intel.com \
    --cc=linux-bluetooth@vger.kernel.org \
    /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 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).