Commit f892244b authored by Brian Gix's avatar Brian Gix Committed by Marcel Holtmann

Bluetooth: hci_sync: Convert MGMT_OP_READ_LOCAL_OOB_DATA

New functions:
  hci_read_local_oob_data_sync

This function requires all of the data from the cmd cmplt event
to be passed up to the caller via the skb.

mgmt-tester paths:
Read Local OOB Data - Not powered
Read Local OOB Data - Legacy pairing
Read Local OOB Data - Success SSP
Read Local OOB Data - Success SC
Signed-off-by: default avatarBrian Gix <brian.gix@intel.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent d81a494c
...@@ -78,6 +78,8 @@ int hci_update_scan_sync(struct hci_dev *hdev); ...@@ -78,6 +78,8 @@ int hci_update_scan_sync(struct hci_dev *hdev);
int hci_write_le_host_supported_sync(struct hci_dev *hdev, u8 le, u8 simul); int hci_write_le_host_supported_sync(struct hci_dev *hdev, u8 le, u8 simul);
int hci_remove_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance, int hci_remove_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance,
struct sock *sk); struct sock *sk);
struct sk_buff *hci_read_local_oob_data_sync(struct hci_dev *hdev, bool ext,
struct sock *sk);
int hci_dev_open_sync(struct hci_dev *hdev); int hci_dev_open_sync(struct hci_dev *hdev);
int hci_dev_close_sync(struct hci_dev *hdev); int hci_dev_close_sync(struct hci_dev *hdev);
......
...@@ -1703,6 +1703,15 @@ static int hci_resume_advertising_sync(struct hci_dev *hdev) ...@@ -1703,6 +1703,15 @@ static int hci_resume_advertising_sync(struct hci_dev *hdev)
return err; return err;
} }
struct sk_buff *hci_read_local_oob_data_sync(struct hci_dev *hdev,
bool extended, struct sock *sk)
{
u16 opcode = extended ? HCI_OP_READ_LOCAL_OOB_EXT_DATA :
HCI_OP_READ_LOCAL_OOB_DATA;
return __hci_cmd_sync_sk(hdev, opcode, 0, NULL, 0, HCI_CMD_TIMEOUT, sk);
}
/* Device must not be scanning when updating the accept list. /* Device must not be scanning when updating the accept list.
* *
* Update is done using the following sequence: * Update is done using the following sequence:
......
...@@ -4793,28 +4793,33 @@ static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev, ...@@ -4793,28 +4793,33 @@ static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev,
status); status);
} }
static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status, static void read_local_oob_data_complete(struct hci_dev *hdev, void *data, int err)
u16 opcode, struct sk_buff *skb)
{ {
struct mgmt_rp_read_local_oob_data mgmt_rp; struct mgmt_rp_read_local_oob_data mgmt_rp;
size_t rp_size = sizeof(mgmt_rp); size_t rp_size = sizeof(mgmt_rp);
struct mgmt_pending_cmd *cmd; struct mgmt_pending_cmd *cmd = data;
struct sk_buff *skb = cmd->skb;
u8 status = mgmt_status(err);
bt_dev_dbg(hdev, "status %u", status); if (!status) {
if (!skb)
status = MGMT_STATUS_FAILED;
else if (IS_ERR(skb))
status = mgmt_status(PTR_ERR(skb));
else
status = mgmt_status(skb->data[0]);
}
cmd = pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev); bt_dev_dbg(hdev, "status %d", status);
if (!cmd)
return;
if (status || !skb) { if (status) {
mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, status);
status ? mgmt_status(status) : MGMT_STATUS_FAILED);
goto remove; goto remove;
} }
memset(&mgmt_rp, 0, sizeof(mgmt_rp)); memset(&mgmt_rp, 0, sizeof(mgmt_rp));
if (opcode == HCI_OP_READ_LOCAL_OOB_DATA) { if (!bredr_sc_enabled(hdev)) {
struct hci_rp_read_local_oob_data *rp = (void *) skb->data; struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
if (skb->len < sizeof(*rp)) { if (skb->len < sizeof(*rp)) {
...@@ -4849,14 +4854,31 @@ static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status, ...@@ -4849,14 +4854,31 @@ static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status,
MGMT_STATUS_SUCCESS, &mgmt_rp, rp_size); MGMT_STATUS_SUCCESS, &mgmt_rp, rp_size);
remove: remove:
mgmt_pending_remove(cmd); if (skb && !IS_ERR(skb))
kfree_skb(skb);
mgmt_pending_free(cmd);
}
static int read_local_oob_data_sync(struct hci_dev *hdev, void *data)
{
struct mgmt_pending_cmd *cmd = data;
if (bredr_sc_enabled(hdev))
cmd->skb = hci_read_local_oob_data_sync(hdev, true, cmd->sk);
else
cmd->skb = hci_read_local_oob_data_sync(hdev, false, cmd->sk);
if (IS_ERR(cmd->skb))
return PTR_ERR(cmd->skb);
else
return 0;
} }
static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev, static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev,
void *data, u16 data_len) void *data, u16 data_len)
{ {
struct mgmt_pending_cmd *cmd; struct mgmt_pending_cmd *cmd;
struct hci_request req;
int err; int err;
bt_dev_dbg(hdev, "sock %p", sk); bt_dev_dbg(hdev, "sock %p", sk);
...@@ -4881,22 +4903,20 @@ static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev, ...@@ -4881,22 +4903,20 @@ static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev,
goto unlock; goto unlock;
} }
cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_DATA, hdev, NULL, 0); cmd = mgmt_pending_new(sk, MGMT_OP_READ_LOCAL_OOB_DATA, hdev, NULL, 0);
if (!cmd) { if (!cmd)
err = -ENOMEM; err = -ENOMEM;
goto unlock;
}
hci_req_init(&req, hdev);
if (bredr_sc_enabled(hdev))
hci_req_add(&req, HCI_OP_READ_LOCAL_OOB_EXT_DATA, 0, NULL);
else else
hci_req_add(&req, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL); err = hci_cmd_sync_queue(hdev, read_local_oob_data_sync, cmd,
read_local_oob_data_complete);
err = hci_req_run_skb(&req, read_local_oob_data_complete); if (err < 0) {
if (err < 0) err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
mgmt_pending_remove(cmd); MGMT_STATUS_FAILED);
if (cmd)
mgmt_pending_free(cmd);
}
unlock: unlock:
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
......
...@@ -27,6 +27,7 @@ struct mgmt_pending_cmd { ...@@ -27,6 +27,7 @@ struct mgmt_pending_cmd {
void *param; void *param;
size_t param_len; size_t param_len;
struct sock *sk; struct sock *sk;
struct sk_buff *skb;
void *user_data; void *user_data;
int (*cmd_complete)(struct mgmt_pending_cmd *cmd, u8 status); int (*cmd_complete)(struct mgmt_pending_cmd *cmd, u8 status);
}; };
......
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