Bluetooth: Send management event for class of device changes
Marcel Holtmann [Wed, 22 Feb 2012 17:38:01 +0000 (18:38 +0100)]
Currently there are no events to other management sockets if the class of
device got changed. So make sure they are sent.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>

include/net/bluetooth/hci_core.h
net/bluetooth/hci_event.c
net/bluetooth/mgmt.c

index abdaa79..24dd770 100644 (file)
@@ -1007,6 +1007,8 @@ int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
                                                u8 addr_type, u8 status);
 int mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status);
 int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status);
+int mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
+                                                               u8 status);
 int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status);
 int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
                                                u8 *randomizer, u8 status);
index e44e3fd..c79ffb9 100644 (file)
@@ -350,14 +350,19 @@ 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;
 
-       memcpy(hdev->dev_class, sent, 3);
+       hci_dev_lock(hdev);
+
+       if (status == 0)
+               memcpy(hdev->dev_class, sent, 3);
+
+       if (test_bit(HCI_MGMT, &hdev->dev_flags))
+               mgmt_set_class_of_dev_complete(hdev, sent, status);
+
+       hci_dev_unlock(hdev);
 }
 
 static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
index f7e111f..16bddd2 100644 (file)
@@ -3546,6 +3546,16 @@ int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
        return err;
 }
 
+int mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
+                                                               u8 status)
+{
+       int err;
+
+       err = mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class, 3, NULL);
+
+       return err;
+}
+
 int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status)
 {
        struct pending_cmd *cmd;