Bluetooth: Ask upper layers for HCI disconnect reason
[pandora-kernel.git] / net / bluetooth / hci_conn.c
index 2435e83..96281a1 100644 (file)
@@ -159,6 +159,7 @@ static void hci_conn_timeout(unsigned long arg)
 {
        struct hci_conn *conn = (void *) arg;
        struct hci_dev *hdev = conn->hdev;
+       __u8 reason;
 
        BT_DBG("conn %p state %d", conn, conn->state);
 
@@ -177,7 +178,8 @@ static void hci_conn_timeout(unsigned long arg)
                break;
        case BT_CONFIG:
        case BT_CONNECTED:
-               hci_acl_disconn(conn, 0x13);
+               reason = hci_proto_disconn_ind(conn);
+               hci_acl_disconn(conn, reason);
                break;
        default:
                conn->state = BT_CLOSED;
@@ -391,19 +393,14 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
 EXPORT_SYMBOL(hci_conn_check_link_mode);
 
 /* Authenticate remote device */
-static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level)
+static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
 {
        BT_DBG("conn %p", conn);
 
-       if (sec_level > conn->sec_level)
-               conn->link_mode &= ~HCI_LM_AUTH;
-
-       conn->sec_level = sec_level;
-
-       if (sec_level == BT_SECURITY_HIGH)
-               conn->auth_type |= 0x01;
-
-       if (conn->link_mode & HCI_LM_AUTH)
+       if (sec_level > conn->sec_level) {
+               conn->sec_level = sec_level;
+               conn->auth_type = auth_type;
+       } else if (conn->link_mode & HCI_LM_AUTH)
                return 1;
 
        if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
@@ -417,27 +414,30 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level)
 }
 
 /* Enable security */
-int hci_conn_security(struct hci_conn *conn, __u8 sec_level)
+int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
 {
        BT_DBG("conn %p", conn);
 
+       if (conn->auth_type == 0xff)
+               conn->auth_type = auth_type;
+
        if (sec_level == BT_SECURITY_SDP)
                return 1;
 
        if (sec_level == BT_SECURITY_LOW) {
                if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0)
-                       return hci_conn_auth(conn, sec_level);
+                       return hci_conn_auth(conn, sec_level, auth_type);
                else
                        return 1;
        }
 
        if (conn->link_mode & HCI_LM_ENCRYPT)
-               return hci_conn_auth(conn, sec_level);
+               return hci_conn_auth(conn, sec_level, auth_type);
 
        if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
                return 0;
 
-       if (hci_conn_auth(conn, sec_level)) {
+       if (hci_conn_auth(conn, sec_level, auth_type)) {
                struct hci_cp_set_conn_encrypt cp;
                cp.handle  = cpu_to_le16(conn->handle);
                cp.encrypt = 1;
@@ -564,7 +564,7 @@ void hci_conn_hash_flush(struct hci_dev *hdev)
 
                hci_conn_del_sysfs(c);
 
-               hci_proto_disconn_ind(c, 0x16);
+               hci_proto_disconn_cfm(c, 0x16);
                hci_conn_del(c);
        }
 }