aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/hci_core.h25
-rw-r--r--include/net/bluetooth/l2cap.h2
-rw-r--r--net/bluetooth/hci_conn.c6
-rw-r--r--net/bluetooth/hci_event.c2
-rw-r--r--net/bluetooth/l2cap.c20
-rw-r--r--net/bluetooth/sco.c4
6 files changed, 49 insertions, 10 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 9473fce499e7..01f9316b4c23 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -478,7 +478,8 @@ struct hci_proto {
478 478
479 int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type); 479 int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type);
480 int (*connect_cfm) (struct hci_conn *conn, __u8 status); 480 int (*connect_cfm) (struct hci_conn *conn, __u8 status);
481 int (*disconn_ind) (struct hci_conn *conn, __u8 reason); 481 int (*disconn_ind) (struct hci_conn *conn);
482 int (*disconn_cfm) (struct hci_conn *conn, __u8 reason);
482 int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags); 483 int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
483 int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb); 484 int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb);
484 int (*security_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt); 485 int (*security_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt);
@@ -513,17 +514,33 @@ static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)
513 hp->connect_cfm(conn, status); 514 hp->connect_cfm(conn, status);
514} 515}
515 516
516static inline void hci_proto_disconn_ind(struct hci_conn *conn, __u8 reason) 517static inline int hci_proto_disconn_ind(struct hci_conn *conn)
517{ 518{
518 register struct hci_proto *hp; 519 register struct hci_proto *hp;
520 int reason = 0x13;
519 521
520 hp = hci_proto[HCI_PROTO_L2CAP]; 522 hp = hci_proto[HCI_PROTO_L2CAP];
521 if (hp && hp->disconn_ind) 523 if (hp && hp->disconn_ind)
522 hp->disconn_ind(conn, reason); 524 reason = hp->disconn_ind(conn);
523 525
524 hp = hci_proto[HCI_PROTO_SCO]; 526 hp = hci_proto[HCI_PROTO_SCO];
525 if (hp && hp->disconn_ind) 527 if (hp && hp->disconn_ind)
526 hp->disconn_ind(conn, reason); 528 reason = hp->disconn_ind(conn);
529
530 return reason;
531}
532
533static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason)
534{
535 register struct hci_proto *hp;
536
537 hp = hci_proto[HCI_PROTO_L2CAP];
538 if (hp && hp->disconn_cfm)
539 hp->disconn_cfm(conn, reason);
540
541 hp = hci_proto[HCI_PROTO_SCO];
542 if (hp && hp->disconn_cfm)
543 hp->disconn_cfm(conn, reason);
527} 544}
528 545
529static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) 546static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 54737c5dc86c..f566aa1f0a4c 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -221,6 +221,8 @@ struct l2cap_conn {
221 __u8 rx_ident; 221 __u8 rx_ident;
222 __u8 tx_ident; 222 __u8 tx_ident;
223 223
224 __u8 disc_reason;
225
224 struct l2cap_chan_list chan_list; 226 struct l2cap_chan_list chan_list;
225}; 227};
226 228
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index dcdaa4be7847..96281a11a186 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -159,6 +159,7 @@ static void hci_conn_timeout(unsigned long arg)
159{ 159{
160 struct hci_conn *conn = (void *) arg; 160 struct hci_conn *conn = (void *) arg;
161 struct hci_dev *hdev = conn->hdev; 161 struct hci_dev *hdev = conn->hdev;
162 __u8 reason;
162 163
163 BT_DBG("conn %p state %d", conn, conn->state); 164 BT_DBG("conn %p state %d", conn, conn->state);
164 165
@@ -177,7 +178,8 @@ static void hci_conn_timeout(unsigned long arg)
177 break; 178 break;
178 case BT_CONFIG: 179 case BT_CONFIG:
179 case BT_CONNECTED: 180 case BT_CONNECTED:
180 hci_acl_disconn(conn, 0x13); 181 reason = hci_proto_disconn_ind(conn);
182 hci_acl_disconn(conn, reason);
181 break; 183 break;
182 default: 184 default:
183 conn->state = BT_CLOSED; 185 conn->state = BT_CLOSED;
@@ -562,7 +564,7 @@ void hci_conn_hash_flush(struct hci_dev *hdev)
562 564
563 hci_conn_del_sysfs(c); 565 hci_conn_del_sysfs(c);
564 566
565 hci_proto_disconn_ind(c, 0x16); 567 hci_proto_disconn_cfm(c, 0x16);
566 hci_conn_del(c); 568 hci_conn_del(c);
567 } 569 }
568} 570}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 899b8991a466..c396542c2b82 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1021,7 +1021,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
1021 1021
1022 hci_conn_del_sysfs(conn); 1022 hci_conn_del_sysfs(conn);
1023 1023
1024 hci_proto_disconn_ind(conn, ev->reason); 1024 hci_proto_disconn_cfm(conn, ev->reason);
1025 hci_conn_del(conn); 1025 hci_conn_del(conn);
1026 } 1026 }
1027 1027
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 7bba469b6828..d563f2ebcbb3 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -206,6 +206,8 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so
206 206
207 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid); 207 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
208 208
209 conn->disc_reason = 0x13;
210
209 l2cap_pi(sk)->conn = conn; 211 l2cap_pi(sk)->conn = conn;
210 212
211 if (sk->sk_type == SOCK_SEQPACKET) { 213 if (sk->sk_type == SOCK_SEQPACKET) {
@@ -491,6 +493,8 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
491 spin_lock_init(&conn->lock); 493 spin_lock_init(&conn->lock);
492 rwlock_init(&conn->chan_list.lock); 494 rwlock_init(&conn->chan_list.lock);
493 495
496 conn->disc_reason = 0x13;
497
494 return conn; 498 return conn;
495} 499}
496 500
@@ -1840,6 +1844,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
1840 /* Check if the ACL is secure enough (if not SDP) */ 1844 /* Check if the ACL is secure enough (if not SDP) */
1841 if (psm != cpu_to_le16(0x0001) && 1845 if (psm != cpu_to_le16(0x0001) &&
1842 !hci_conn_check_link_mode(conn->hcon)) { 1846 !hci_conn_check_link_mode(conn->hcon)) {
1847 conn->disc_reason = 0x05;
1843 result = L2CAP_CR_SEC_BLOCK; 1848 result = L2CAP_CR_SEC_BLOCK;
1844 goto response; 1849 goto response;
1845 } 1850 }
@@ -2472,7 +2477,19 @@ static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
2472 return 0; 2477 return 0;
2473} 2478}
2474 2479
2475static int l2cap_disconn_ind(struct hci_conn *hcon, u8 reason) 2480static int l2cap_disconn_ind(struct hci_conn *hcon)
2481{
2482 struct l2cap_conn *conn = hcon->l2cap_data;
2483
2484 BT_DBG("hcon %p", hcon);
2485
2486 if (hcon->type != ACL_LINK || !conn)
2487 return 0x13;
2488
2489 return conn->disc_reason;
2490}
2491
2492static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
2476{ 2493{
2477 BT_DBG("hcon %p reason %d", hcon, reason); 2494 BT_DBG("hcon %p reason %d", hcon, reason);
2478 2495
@@ -2717,6 +2734,7 @@ static struct hci_proto l2cap_hci_proto = {
2717 .connect_ind = l2cap_connect_ind, 2734 .connect_ind = l2cap_connect_ind,
2718 .connect_cfm = l2cap_connect_cfm, 2735 .connect_cfm = l2cap_connect_cfm,
2719 .disconn_ind = l2cap_disconn_ind, 2736 .disconn_ind = l2cap_disconn_ind,
2737 .disconn_cfm = l2cap_disconn_cfm,
2720 .security_cfm = l2cap_security_cfm, 2738 .security_cfm = l2cap_security_cfm,
2721 .recv_acldata = l2cap_recv_acldata 2739 .recv_acldata = l2cap_recv_acldata
2722}; 2740};
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 7f10f97cd697..51ae0c3e470a 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -902,7 +902,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
902 return 0; 902 return 0;
903} 903}
904 904
905static int sco_disconn_ind(struct hci_conn *hcon, __u8 reason) 905static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
906{ 906{
907 BT_DBG("hcon %p reason %d", hcon, reason); 907 BT_DBG("hcon %p reason %d", hcon, reason);
908 908
@@ -985,7 +985,7 @@ static struct hci_proto sco_hci_proto = {
985 .id = HCI_PROTO_SCO, 985 .id = HCI_PROTO_SCO,
986 .connect_ind = sco_connect_ind, 986 .connect_ind = sco_connect_ind,
987 .connect_cfm = sco_connect_cfm, 987 .connect_cfm = sco_connect_cfm,
988 .disconn_ind = sco_disconn_ind, 988 .disconn_cfm = sco_disconn_cfm,
989 .recv_scodata = sco_recv_scodata 989 .recv_scodata = sco_recv_scodata
990}; 990};
991 991