diff options
-rw-r--r-- | include/net/bluetooth/hci_core.h | 25 | ||||
-rw-r--r-- | include/net/bluetooth/l2cap.h | 2 | ||||
-rw-r--r-- | net/bluetooth/hci_conn.c | 6 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 2 | ||||
-rw-r--r-- | net/bluetooth/l2cap.c | 20 | ||||
-rw-r--r-- | net/bluetooth/sco.c | 4 |
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 | ||
516 | static inline void hci_proto_disconn_ind(struct hci_conn *conn, __u8 reason) | 517 | static 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 | |||
533 | static 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 | ||
529 | static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) | 546 | static 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 | ||
2475 | static int l2cap_disconn_ind(struct hci_conn *hcon, u8 reason) | 2480 | static 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 | |||
2492 | static 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 | ||
905 | static int sco_disconn_ind(struct hci_conn *hcon, __u8 reason) | 905 | static 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 | ||