aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/hci.h2
-rw-r--r--include/net/bluetooth/hci_core.h3
-rw-r--r--net/bluetooth/hci_conn.c2
-rw-r--r--net/bluetooth/hci_core.c7
-rw-r--r--net/bluetooth/hci_event.c127
5 files changed, 118 insertions, 23 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 5ac0a18db63c..55576e848827 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -180,6 +180,8 @@ enum {
180 180
181#define LMP_SNIFF_SUBR 0x02 181#define LMP_SNIFF_SUBR 0x02
182 182
183#define LMP_SIMPLE_PAIR 0x08
184
183/* Connection modes */ 185/* Connection modes */
184#define HCI_CM_ACTIVE 0x0000 186#define HCI_CM_ACTIVE 0x0000
185#define HCI_CM_HOLD 0x0001 187#define HCI_CM_HOLD 0x0001
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index f73cc2945700..28fbd0caa534 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -348,7 +348,7 @@ static inline void hci_conn_put(struct hci_conn *conn)
348 if (conn->state == BT_CONNECTED) { 348 if (conn->state == BT_CONNECTED) {
349 timeo = msecs_to_jiffies(HCI_DISCONN_TIMEOUT); 349 timeo = msecs_to_jiffies(HCI_DISCONN_TIMEOUT);
350 if (!conn->out) 350 if (!conn->out)
351 timeo *= 2; 351 timeo *= 5;
352 } else 352 } else
353 timeo = msecs_to_jiffies(10); 353 timeo = msecs_to_jiffies(10);
354 } else 354 } else
@@ -463,6 +463,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
463#define lmp_sniff_capable(dev) ((dev)->features[0] & LMP_SNIFF) 463#define lmp_sniff_capable(dev) ((dev)->features[0] & LMP_SNIFF)
464#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR) 464#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
465#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO) 465#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO)
466#define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR)
466 467
467/* ----- HCI protocols ----- */ 468/* ----- HCI protocols ----- */
468struct hci_proto { 469struct hci_proto {
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 41351ba692e9..6f22533e7656 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -170,11 +170,13 @@ static void hci_conn_timeout(unsigned long arg)
170 170
171 switch (conn->state) { 171 switch (conn->state) {
172 case BT_CONNECT: 172 case BT_CONNECT:
173 case BT_CONNECT2:
173 if (conn->type == ACL_LINK) 174 if (conn->type == ACL_LINK)
174 hci_acl_connect_cancel(conn); 175 hci_acl_connect_cancel(conn);
175 else 176 else
176 hci_acl_disconn(conn, 0x13); 177 hci_acl_disconn(conn, 0x13);
177 break; 178 break;
179 case BT_CONFIG:
178 case BT_CONNECTED: 180 case BT_CONNECTED:
179 hci_acl_disconn(conn, 0x13); 181 hci_acl_disconn(conn, 0x13);
180 break; 182 break;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 69b2c1aac08a..f5b21cb93699 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1283,9 +1283,12 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int
1283 struct hci_conn *c; 1283 struct hci_conn *c;
1284 c = list_entry(p, struct hci_conn, list); 1284 c = list_entry(p, struct hci_conn, list);
1285 1285
1286 if (c->type != type || c->state != BT_CONNECTED 1286 if (c->type != type || skb_queue_empty(&c->data_q))
1287 || skb_queue_empty(&c->data_q))
1288 continue; 1287 continue;
1288
1289 if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
1290 continue;
1291
1289 num++; 1292 num++;
1290 1293
1291 if (c->sent < min) { 1294 if (c->sent < min) {
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index c8fda7dc2986..e3e360c3c536 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -624,6 +624,62 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
624 BT_DBG("%s status 0x%x", hdev->name, status); 624 BT_DBG("%s status 0x%x", hdev->name, status);
625} 625}
626 626
627static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
628{
629 struct hci_cp_read_remote_features *cp;
630 struct hci_conn *conn;
631
632 BT_DBG("%s status 0x%x", hdev->name, status);
633
634 if (!status)
635 return;
636
637 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
638 if (!cp)
639 return;
640
641 hci_dev_lock(hdev);
642
643 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
644 if (conn) {
645 if (conn->state == BT_CONFIG) {
646 conn->state = BT_CONNECTED;
647 hci_proto_connect_cfm(conn, status);
648 hci_conn_put(conn);
649 }
650 }
651
652 hci_dev_unlock(hdev);
653}
654
655static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
656{
657 struct hci_cp_read_remote_ext_features *cp;
658 struct hci_conn *conn;
659
660 BT_DBG("%s status 0x%x", hdev->name, status);
661
662 if (!status)
663 return;
664
665 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
666 if (!cp)
667 return;
668
669 hci_dev_lock(hdev);
670
671 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
672 if (conn) {
673 if (conn->state == BT_CONFIG) {
674 conn->state = BT_CONNECTED;
675 hci_proto_connect_cfm(conn, status);
676 hci_conn_put(conn);
677 }
678 }
679
680 hci_dev_unlock(hdev);
681}
682
627static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status) 683static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
628{ 684{
629 struct hci_cp_setup_sync_conn *cp; 685 struct hci_cp_setup_sync_conn *cp;
@@ -759,7 +815,12 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
759 815
760 if (!ev->status) { 816 if (!ev->status) {
761 conn->handle = __le16_to_cpu(ev->handle); 817 conn->handle = __le16_to_cpu(ev->handle);
762 conn->state = BT_CONNECTED; 818
819 if (conn->type == ACL_LINK) {
820 conn->state = BT_CONFIG;
821 hci_conn_hold(conn);
822 } else
823 conn->state = BT_CONNECTED;
763 824
764 if (test_bit(HCI_AUTH, &hdev->flags)) 825 if (test_bit(HCI_AUTH, &hdev->flags))
765 conn->link_mode |= HCI_LM_AUTH; 826 conn->link_mode |= HCI_LM_AUTH;
@@ -771,7 +832,8 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
771 if (conn->type == ACL_LINK) { 832 if (conn->type == ACL_LINK) {
772 struct hci_cp_read_remote_features cp; 833 struct hci_cp_read_remote_features cp;
773 cp.handle = ev->handle; 834 cp.handle = ev->handle;
774 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, sizeof(cp), &cp); 835 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
836 sizeof(cp), &cp);
775 } 837 }
776 838
777 /* Set packet type for incoming connection */ 839 /* Set packet type for incoming connection */
@@ -781,10 +843,6 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
781 cp.pkt_type = cpu_to_le16(conn->pkt_type); 843 cp.pkt_type = cpu_to_le16(conn->pkt_type);
782 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, 844 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
783 sizeof(cp), &cp); 845 sizeof(cp), &cp);
784 } else {
785 /* Update disconnect timer */
786 hci_conn_hold(conn);
787 hci_conn_put(conn);
788 } 846 }
789 } else 847 } else
790 conn->state = BT_CLOSED; 848 conn->state = BT_CLOSED;
@@ -804,9 +862,10 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
804 } 862 }
805 } 863 }
806 864
807 hci_proto_connect_cfm(conn, ev->status); 865 if (ev->status) {
808 if (ev->status) 866 hci_proto_connect_cfm(conn, ev->status);
809 hci_conn_del(conn); 867 hci_conn_del(conn);
868 }
810 869
811unlock: 870unlock:
812 hci_dev_unlock(hdev); 871 hci_dev_unlock(hdev);
@@ -1006,14 +1065,29 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff
1006 1065
1007 BT_DBG("%s status %d", hdev->name, ev->status); 1066 BT_DBG("%s status %d", hdev->name, ev->status);
1008 1067
1009 if (ev->status)
1010 return;
1011
1012 hci_dev_lock(hdev); 1068 hci_dev_lock(hdev);
1013 1069
1014 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 1070 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1015 if (conn) 1071 if (conn) {
1016 memcpy(conn->features, ev->features, 8); 1072 if (!ev->status)
1073 memcpy(conn->features, ev->features, 8);
1074
1075 if (conn->state == BT_CONFIG) {
1076 if (!ev->status && lmp_ssp_capable(hdev) &&
1077 lmp_ssp_capable(conn)) {
1078 struct hci_cp_read_remote_ext_features cp;
1079 cp.handle = ev->handle;
1080 cp.page = 0x01;
1081 hci_send_cmd(hdev,
1082 HCI_OP_READ_REMOTE_EXT_FEATURES,
1083 sizeof(cp), &cp);
1084 } else {
1085 conn->state = BT_CONNECTED;
1086 hci_proto_connect_cfm(conn, ev->status);
1087 hci_conn_put(conn);
1088 }
1089 }
1090 }
1017 1091
1018 hci_dev_unlock(hdev); 1092 hci_dev_unlock(hdev);
1019} 1093}
@@ -1180,6 +1254,14 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
1180 hci_cs_remote_name_req(hdev, ev->status); 1254 hci_cs_remote_name_req(hdev, ev->status);
1181 break; 1255 break;
1182 1256
1257 case HCI_OP_READ_REMOTE_FEATURES:
1258 hci_cs_read_remote_features(hdev, ev->status);
1259 break;
1260
1261 case HCI_OP_READ_REMOTE_EXT_FEATURES:
1262 hci_cs_read_remote_ext_features(hdev, ev->status);
1263 break;
1264
1183 case HCI_OP_SETUP_SYNC_CONN: 1265 case HCI_OP_SETUP_SYNC_CONN:
1184 hci_cs_setup_sync_conn(hdev, ev->status); 1266 hci_cs_setup_sync_conn(hdev, ev->status);
1185 break; 1267 break;
@@ -1422,19 +1504,24 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
1422 1504
1423 BT_DBG("%s", hdev->name); 1505 BT_DBG("%s", hdev->name);
1424 1506
1425 if (ev->status || ev->page != 0x01)
1426 return;
1427
1428 hci_dev_lock(hdev); 1507 hci_dev_lock(hdev);
1429 1508
1430 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 1509 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1431 if (conn) { 1510 if (conn) {
1432 struct inquiry_entry *ie; 1511 if (!ev->status && ev->page == 0x01) {
1512 struct inquiry_entry *ie;
1433 1513
1434 if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) 1514 if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst)))
1435 ie->data.ssp_mode = (ev->features[0] & 0x01); 1515 ie->data.ssp_mode = (ev->features[0] & 0x01);
1436 1516
1437 conn->ssp_mode = (ev->features[0] & 0x01); 1517 conn->ssp_mode = (ev->features[0] & 0x01);
1518 }
1519
1520 if (conn->state == BT_CONFIG) {
1521 conn->state = BT_CONNECTED;
1522 hci_proto_connect_cfm(conn, ev->status);
1523 hci_conn_put(conn);
1524 }
1438 } 1525 }
1439 1526
1440 hci_dev_unlock(hdev); 1527 hci_dev_unlock(hdev);