Bluetooth: Add management command for setting Device ID
authorMarcel Holtmann <marcel@holtmann.org>
Mon, 12 Mar 2012 03:00:29 +0000 (20:00 -0700)
committerGustavo Padovan <gustavo@padovan.org>
Wed, 9 May 2012 03:41:30 +0000 (00:41 -0300)
The Device ID details need to be programmed into the kernel for every
controller at least once. So provide management command for this.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
include/net/bluetooth/mgmt.h
net/bluetooth/mgmt.c

index ebfd91fc20f804437241614418e7505ac15c83a0..23fd0546fccbc1bd127b215bdb8c7150f08cfcb3 100644 (file)
@@ -341,6 +341,15 @@ struct mgmt_cp_unblock_device {
 } __packed;
 #define MGMT_UNBLOCK_DEVICE_SIZE       MGMT_ADDR_INFO_SIZE
 
+#define MGMT_OP_SET_DEVICE_ID          0x0028
+struct mgmt_cp_set_device_id {
+       __le16  source;
+       __le16  vendor;
+       __le16  product;
+       __le16  version;
+} __packed;
+#define MGMT_SET_DEVICE_ID_SIZE                8
+
 #define MGMT_EV_CMD_COMPLETE           0x0001
 struct mgmt_ev_cmd_complete {
        __le16  opcode;
index 1da458d9b5ca8fe7af991bceaacf9b403a0ee272..5e88fda42f1fd7796bb8602a05f537e5d52fe8f7 100644 (file)
@@ -78,6 +78,7 @@ static const u16 mgmt_commands[] = {
        MGMT_OP_CONFIRM_NAME,
        MGMT_OP_BLOCK_DEVICE,
        MGMT_OP_UNBLOCK_DEVICE,
+       MGMT_OP_SET_DEVICE_ID,
 };
 
 static const u16 mgmt_events[] = {
@@ -2523,6 +2524,30 @@ static int unblock_device(struct sock *sk, struct hci_dev *hdev, void *data,
        return err;
 }
 
+static int set_device_id(struct sock *sk, struct hci_dev *hdev, void *data,
+                        u16 len)
+{
+       struct mgmt_cp_set_device_id *cp = data;
+       int err;
+
+       BT_DBG("%s", hdev->name);
+
+       hci_dev_lock(hdev);
+
+       hdev->devid_source = __le16_to_cpu(cp->source);
+       hdev->devid_vendor = __le16_to_cpu(cp->vendor);
+       hdev->devid_product = __le16_to_cpu(cp->product);
+       hdev->devid_version = __le16_to_cpu(cp->version);
+
+       err = cmd_complete(sk, hdev->id, MGMT_OP_SET_DEVICE_ID, 0, NULL, 0);
+
+       update_eir(hdev);
+
+       hci_dev_unlock(hdev);
+
+       return err;
+}
+
 static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev,
                                void *data, u16 len)
 {
@@ -2669,6 +2694,7 @@ struct mgmt_handler {
        { confirm_name,           false, MGMT_CONFIRM_NAME_SIZE },
        { block_device,           false, MGMT_BLOCK_DEVICE_SIZE },
        { unblock_device,         false, MGMT_UNBLOCK_DEVICE_SIZE },
+       { set_device_id,          false, MGMT_SET_DEVICE_ID_SIZE },
 };