Skip to content

Commit 4d94f95

Browse files
jaganathkrholtmann
authored andcommitted
Bluetooth: Use extended LE Connection if supported
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 <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent d12fb05 commit 4d94f95

File tree

5 files changed

+147
-18
lines changed

5 files changed

+147
-18
lines changed

include/net/bluetooth/hci.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,6 +1538,27 @@ struct hci_cp_le_set_ext_scan_enable {
15381538
__le16 period;
15391539
} __packed;
15401540

1541+
#define HCI_OP_LE_EXT_CREATE_CONN 0x2043
1542+
struct hci_cp_le_ext_create_conn {
1543+
__u8 filter_policy;
1544+
__u8 own_addr_type;
1545+
__u8 peer_addr_type;
1546+
bdaddr_t peer_addr;
1547+
__u8 phys;
1548+
__u8 data[0];
1549+
} __packed;
1550+
1551+
struct hci_cp_le_ext_conn_param {
1552+
__le16 scan_interval;
1553+
__le16 scan_window;
1554+
__le16 conn_interval_min;
1555+
__le16 conn_interval_max;
1556+
__le16 conn_latency;
1557+
__le16 supervision_timeout;
1558+
__le16 min_ce_len;
1559+
__le16 max_ce_len;
1560+
} __packed;
1561+
15411562
/* ---- HCI Events ---- */
15421563
#define HCI_EV_INQUIRY_COMPLETE 0x01
15431564

@@ -2015,6 +2036,21 @@ struct hci_ev_le_ext_adv_report {
20152036
__u8 data[0];
20162037
} __packed;
20172038

2039+
#define HCI_EV_LE_ENHANCED_CONN_COMPLETE 0x0a
2040+
struct hci_ev_le_enh_conn_complete {
2041+
__u8 status;
2042+
__le16 handle;
2043+
__u8 role;
2044+
__u8 bdaddr_type;
2045+
bdaddr_t bdaddr;
2046+
bdaddr_t local_rpa;
2047+
bdaddr_t peer_rpa;
2048+
__le16 interval;
2049+
__le16 latency;
2050+
__le16 supervision_timeout;
2051+
__u8 clk_accurancy;
2052+
} __packed;
2053+
20182054
/* Internal events generated by Bluetooth stack */
20192055
#define HCI_EV_STACK_INTERNAL 0xfd
20202056
struct hci_ev_stack_internal {

include/net/bluetooth/hci_core.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,6 +1161,8 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
11611161
/* Use ext scanning if set ext scan param and ext scan enable is supported */
11621162
#define use_ext_scan(dev) (((dev)->commands[37] & 0x20) && \
11631163
((dev)->commands[37] & 0x40))
1164+
/* Use ext create connection if command is supported */
1165+
#define use_ext_conn(dev) ((dev)->commands[37] & 0x80)
11641166

11651167
/* ----- HCI protocols ----- */
11661168
#define HCI_PROTO_DEFER 0x01

net/bluetooth/hci_conn.c

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,6 @@ static void hci_req_add_le_create_conn(struct hci_request *req,
752752
struct hci_conn *conn,
753753
bdaddr_t *direct_rpa)
754754
{
755-
struct hci_cp_le_create_conn cp;
756755
struct hci_dev *hdev = conn->hdev;
757756
u8 own_addr_type;
758757

@@ -775,25 +774,62 @@ static void hci_req_add_le_create_conn(struct hci_request *req,
775774
return;
776775
}
777776

778-
memset(&cp, 0, sizeof(cp));
777+
if (use_ext_conn(hdev)) {
778+
struct hci_cp_le_ext_create_conn *cp;
779+
struct hci_cp_le_ext_conn_param *p;
780+
/* As of now only LE 1M is supported */
781+
u8 data[sizeof(*cp) + sizeof(*p) * 1];
779782

780-
/* Set window to be the same value as the interval to enable
781-
* continuous scanning.
782-
*/
783-
cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
784-
cp.scan_window = cp.scan_interval;
783+
cp = (void *) data;
784+
p = (void *) cp->data;
785785

786-
bacpy(&cp.peer_addr, &conn->dst);
787-
cp.peer_addr_type = conn->dst_type;
788-
cp.own_address_type = own_addr_type;
789-
cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
790-
cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
791-
cp.conn_latency = cpu_to_le16(conn->le_conn_latency);
792-
cp.supervision_timeout = cpu_to_le16(conn->le_supv_timeout);
793-
cp.min_ce_len = cpu_to_le16(0x0000);
794-
cp.max_ce_len = cpu_to_le16(0x0000);
795-
796-
hci_req_add(req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
786+
memset(cp, 0, sizeof(*cp));
787+
788+
bacpy(&cp->peer_addr, &conn->dst);
789+
cp->peer_addr_type = conn->dst_type;
790+
cp->own_addr_type = own_addr_type;
791+
cp->phys = LE_SCAN_PHY_1M;
792+
793+
memset(p, 0, sizeof(*p));
794+
795+
/* Set window to be the same value as the interval to enable
796+
* continuous scanning.
797+
*/
798+
799+
p->scan_interval = cpu_to_le16(hdev->le_scan_interval);
800+
p->scan_window = p->scan_interval;
801+
p->conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
802+
p->conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
803+
p->conn_latency = cpu_to_le16(conn->le_conn_latency);
804+
p->supervision_timeout = cpu_to_le16(conn->le_supv_timeout);
805+
p->min_ce_len = cpu_to_le16(0x0000);
806+
p->max_ce_len = cpu_to_le16(0x0000);
807+
808+
hci_req_add(req, HCI_OP_LE_EXT_CREATE_CONN, sizeof(data), data);
809+
810+
} else {
811+
struct hci_cp_le_create_conn cp;
812+
813+
memset(&cp, 0, sizeof(cp));
814+
815+
/* Set window to be the same value as the interval to enable
816+
* continuous scanning.
817+
*/
818+
cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
819+
cp.scan_window = cp.scan_interval;
820+
821+
bacpy(&cp.peer_addr, &conn->dst);
822+
cp.peer_addr_type = conn->dst_type;
823+
cp.own_address_type = own_addr_type;
824+
cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
825+
cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
826+
cp.conn_latency = cpu_to_le16(conn->le_conn_latency);
827+
cp.supervision_timeout = cpu_to_le16(conn->le_supv_timeout);
828+
cp.min_ce_len = cpu_to_le16(0x0000);
829+
cp.max_ce_len = cpu_to_le16(0x0000);
830+
831+
hci_req_add(req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
832+
}
797833

798834
conn->state = BT_CONNECT;
799835
clear_bit(HCI_CONN_SCANNING, &conn->flags);

net/bluetooth/hci_core.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,14 @@ static int hci_init3_req(struct hci_request *req, unsigned long opt)
704704
* Report
705705
*/
706706

707+
/* If the controller supports the LE Extended Create Connection
708+
* command, enable the corresponding event.
709+
*/
710+
if (use_ext_conn(hdev))
711+
events[1] |= 0x02; /* LE Enhanced Connection
712+
* Complete
713+
*/
714+
707715
hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events),
708716
events);
709717

net/bluetooth/hci_event.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2031,6 +2031,31 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
20312031
hci_dev_unlock(hdev);
20322032
}
20332033

2034+
static void hci_cs_le_ext_create_conn(struct hci_dev *hdev, u8 status)
2035+
{
2036+
struct hci_cp_le_ext_create_conn *cp;
2037+
2038+
BT_DBG("%s status 0x%2.2x", hdev->name, status);
2039+
2040+
/* All connection failure handling is taken care of by the
2041+
* hci_le_conn_failed function which is triggered by the HCI
2042+
* request completion callbacks used for connecting.
2043+
*/
2044+
if (status)
2045+
return;
2046+
2047+
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_EXT_CREATE_CONN);
2048+
if (!cp)
2049+
return;
2050+
2051+
hci_dev_lock(hdev);
2052+
2053+
cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type,
2054+
cp->own_addr_type, cp->filter_policy);
2055+
2056+
hci_dev_unlock(hdev);
2057+
}
2058+
20342059
static void hci_cs_le_read_remote_features(struct hci_dev *hdev, u8 status)
20352060
{
20362061
struct hci_cp_le_read_remote_features *cp;
@@ -3233,6 +3258,10 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb,
32333258
hci_cs_le_start_enc(hdev, ev->status);
32343259
break;
32353260

3261+
case HCI_OP_LE_EXT_CREATE_CONN:
3262+
hci_cs_le_ext_create_conn(hdev, ev->status);
3263+
break;
3264+
32363265
default:
32373266
BT_DBG("%s opcode 0x%4.4x", hdev->name, *opcode);
32383267
break;
@@ -4733,6 +4762,20 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
47334762
le16_to_cpu(ev->supervision_timeout));
47344763
}
47354764

4765+
static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev,
4766+
struct sk_buff *skb)
4767+
{
4768+
struct hci_ev_le_enh_conn_complete *ev = (void *) skb->data;
4769+
4770+
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
4771+
4772+
le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type,
4773+
ev->role, le16_to_cpu(ev->handle),
4774+
le16_to_cpu(ev->interval),
4775+
le16_to_cpu(ev->latency),
4776+
le16_to_cpu(ev->supervision_timeout));
4777+
}
4778+
47364779
static void hci_le_conn_update_complete_evt(struct hci_dev *hdev,
47374780
struct sk_buff *skb)
47384781
{
@@ -5352,6 +5395,10 @@ static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
53525395
hci_le_ext_adv_report_evt(hdev, skb);
53535396
break;
53545397

5398+
case HCI_EV_LE_ENHANCED_CONN_COMPLETE:
5399+
hci_le_enh_conn_complete_evt(hdev, skb);
5400+
break;
5401+
53555402
default:
53565403
break;
53575404
}

0 commit comments

Comments
 (0)