[Bluetooth] Disable disconnect timer during Simple Pairing
[pandora-kernel.git] / net / bluetooth / hci_event.c
index 9af181a..7c9ac01 100644 (file)
@@ -198,12 +198,14 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
 
        BT_DBG("%s status 0x%x", hdev->name, status);
 
+       if (status)
+               return;
+
        sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
        if (!sent)
                return;
 
-       if (!status)
-               memcpy(hdev->dev_name, sent, 248);
+       memcpy(hdev->dev_name, sent, 248);
 }
 
 static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
@@ -313,12 +315,14 @@ static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
 
        BT_DBG("%s status 0x%x", hdev->name, status);
 
+       if (status)
+               return;
+
        sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
        if (!sent)
                return;
 
-       if (!status)
-               memcpy(hdev->dev_class, sent, 3);
+       memcpy(hdev->dev_class, sent, 3);
 }
 
 static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
@@ -333,7 +337,7 @@ static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
 
        setting = __le16_to_cpu(rp->voice_setting);
 
-       if (hdev->voice_setting == setting )
+       if (hdev->voice_setting == setting)
                return;
 
        hdev->voice_setting = setting;
@@ -350,28 +354,31 @@ static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
 static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
 {
        __u8 status = *((__u8 *) skb->data);
+       __u16 setting;
        void *sent;
 
        BT_DBG("%s status 0x%x", hdev->name, status);
 
+       if (status)
+               return;
+
        sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
        if (!sent)
                return;
 
-       if (!status) {
-               __u16 setting = get_unaligned_le16(sent);
+       setting = get_unaligned_le16(sent);
+
+       if (hdev->voice_setting == setting)
+               return;
 
-               if (hdev->voice_setting != setting) {
-                       hdev->voice_setting = setting;
+       hdev->voice_setting = setting;
 
-                       BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
+       BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
 
-                       if (hdev->notify) {
-                               tasklet_disable(&hdev->tx_task);
-                               hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
-                               tasklet_enable(&hdev->tx_task);
-                       }
-               }
+       if (hdev->notify) {
+               tasklet_disable(&hdev->tx_task);
+               hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
+               tasklet_enable(&hdev->tx_task);
        }
 }
 
@@ -789,10 +796,14 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
 
        if (mask & HCI_LM_ACCEPT) {
                /* Connection accepted */
+               struct inquiry_entry *ie;
                struct hci_conn *conn;
 
                hci_dev_lock(hdev);
 
+               if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr)))
+                       memcpy(ie->data.dev_class, ev->dev_class, 3);
+
                conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
                if (!conn) {
                        if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
@@ -1453,6 +1464,38 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
        hci_dev_unlock(hdev);
 }
 
+static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct hci_ev_io_capa_request *ev = (void *) skb->data;
+       struct hci_conn *conn;
+
+       BT_DBG("%s", hdev->name);
+
+       hci_dev_lock(hdev);
+
+       conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
+       if (conn)
+               hci_conn_hold(conn);
+
+       hci_dev_unlock(hdev);
+}
+
+static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
+       struct hci_conn *conn;
+
+       BT_DBG("%s", hdev->name);
+
+       hci_dev_lock(hdev);
+
+       conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
+       if (conn)
+               hci_conn_put(conn);
+
+       hci_dev_unlock(hdev);
+}
+
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct hci_event_hdr *hdr = (void *) skb->data;
@@ -1577,6 +1620,14 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
                hci_extended_inquiry_result_evt(hdev, skb);
                break;
 
+       case HCI_EV_IO_CAPA_REQUEST:
+               hci_io_capa_request_evt(hdev, skb);
+               break;
+
+       case HCI_EV_SIMPLE_PAIR_COMPLETE:
+               hci_simple_pair_complete_evt(hdev, skb);
+               break;
+
        default:
                BT_DBG("%s event 0x%x", hdev->name, event);
                break;