Commit 59f45d57 authored by Johan Hedberg's avatar Johan Hedberg Committed by John W. Linville

Bluetooth: Fix conditions for HCI_Delete_Stored_Link_Key

Even though the HCI_Delete_Stored_Link_Key command is mandatory for 1.1
and later controllers some controllers do not seem to support it
properly as was witnessed by one Broadcom based controller:

< HCI Command: Delete Stored Link Key (0x03|0x0012) plen 7
    bdaddr 00:00:00:00:00:00 all 1
> HCI Event: Command Complete (0x0e) plen 4
    Delete Stored Link Key (0x03|0x0012) ncmd 1
    status 0x11 deleted 0
    Error: Unsupported Feature or Parameter Value

Luckily this same controller also doesn't list the command in its
supported commands bit mask (counting from 0 bit 7 of octet 6):

< HCI Command: Read Local Supported Commands (0x04|0x0002) plen 0
> HCI Event: Command Complete (0x0e) plen 68
    Read Local Supported Commands (0x04|0x0002) ncmd 1
    status 0x00
    Commands: ffffffffffff1ffffffffffff30fffff3f

Therefore, it makes sense to move sending of HCI_Delete_Stored_Link_Key
to after receiving the supported commands response and to only send it
if its respective bit in the mask is set. The downside of this is that
we no longer send the HCI_Delete_Stored_Link_Key command for Bluetooth
1.1 controllers since HCI_Read_Local_Supported_Command was introduced in
version 1.2, but this is an acceptable penalty as the command in
question shouldn't affect critical behavior.
Reported-by: default avatarPavel Machek <pavel@ucw.cz>
Signed-off-by: default avatarJohan Hedberg <johan.hedberg@intel.com>
Tested-by: default avatarPavel Machek <pavel@ucw.cz>
Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 300b962e
...@@ -341,7 +341,6 @@ static void hci_init1_req(struct hci_request *req, unsigned long opt) ...@@ -341,7 +341,6 @@ static void hci_init1_req(struct hci_request *req, unsigned long opt)
static void bredr_setup(struct hci_request *req) static void bredr_setup(struct hci_request *req)
{ {
struct hci_cp_delete_stored_link_key cp;
__le16 param; __le16 param;
__u8 flt_type; __u8 flt_type;
...@@ -365,10 +364,6 @@ static void bredr_setup(struct hci_request *req) ...@@ -365,10 +364,6 @@ static void bredr_setup(struct hci_request *req)
param = __constant_cpu_to_le16(0x7d00); param = __constant_cpu_to_le16(0x7d00);
hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param); hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
bacpy(&cp.bdaddr, BDADDR_ANY);
cp.delete_all = 0x01;
hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
/* Read page scan parameters */ /* Read page scan parameters */
if (req->hdev->hci_ver > BLUETOOTH_VER_1_1) { if (req->hdev->hci_ver > BLUETOOTH_VER_1_1) {
hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
...@@ -602,6 +597,16 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt) ...@@ -602,6 +597,16 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt)
struct hci_dev *hdev = req->hdev; struct hci_dev *hdev = req->hdev;
u8 p; u8 p;
/* Only send HCI_Delete_Stored_Link_Key if it is supported */
if (hdev->commands[6] & 0x80) {
struct hci_cp_delete_stored_link_key cp;
bacpy(&cp.bdaddr, BDADDR_ANY);
cp.delete_all = 0x01;
hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
sizeof(cp), &cp);
}
if (hdev->commands[5] & 0x10) if (hdev->commands[5] & 0x10)
hci_setup_link_policy(req); hci_setup_link_policy(req);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment