Skip to content

Commit

Permalink
Bluetooth: hci_sync: Convert MGMT_OP_SSP
Browse files Browse the repository at this point in the history
mgmt-tester paths:
Set SSP on - Success 2
Set Device ID - SSP off and Power on

Signed-off-by: Brian Gix <[email protected]>
Signed-off-by: Marcel Holtmann <[email protected]>
  • Loading branch information
bgix authored and holtmann committed Oct 29, 2021
1 parent 5e233ed commit 3244845
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 83 deletions.
1 change: 0 additions & 1 deletion include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -1806,7 +1806,6 @@ int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 entered);
void mgmt_auth_failed(struct hci_conn *conn, u8 status);
void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status);
void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status);
void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
u8 status);
void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status);
Expand Down
1 change: 1 addition & 0 deletions include/net/bluetooth/hci_sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ int hci_update_class_sync(struct hci_dev *hdev);
int hci_update_eir_sync(struct hci_dev *hdev);
int hci_update_class_sync(struct hci_dev *hdev);
int hci_update_name_sync(struct hci_dev *hdev);
int hci_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode);

int hci_update_random_address_sync(struct hci_dev *hdev, bool require_privacy,
bool rpa, u8 *own_addr_type);
Expand Down
4 changes: 1 addition & 3 deletions net/bluetooth/hci_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -545,9 +545,7 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
hdev->features[1][0] &= ~LMP_HOST_SSP;
}

if (hci_dev_test_flag(hdev, HCI_MGMT))
mgmt_ssp_enable_complete(hdev, sent->mode, status);
else if (!status) {
if (!status) {
if (sent->mode)
hci_dev_set_flag(hdev, HCI_SSP_ENABLED);
else
Expand Down
7 changes: 6 additions & 1 deletion net/bluetooth/hci_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -2142,14 +2142,19 @@ int hci_write_sc_support_sync(struct hci_dev *hdev, u8 val)
return err;
}

static int hci_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode)
int hci_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode)
{
int err;

if (!hci_dev_test_flag(hdev, HCI_SSP_ENABLED) ||
lmp_host_ssp_capable(hdev))
return 0;

if (!mode && hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) {
__hci_cmd_sync_status(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE,
sizeof(mode), &mode, HCI_CMD_TIMEOUT);
}

err = __hci_cmd_sync_status(hdev, HCI_OP_WRITE_SSP_MODE,
sizeof(mode), &mode, HCI_CMD_TIMEOUT);
if (err)
Expand Down
150 changes: 72 additions & 78 deletions net/bluetooth/mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1760,6 +1760,69 @@ static int set_link_security(struct sock *sk, struct hci_dev *hdev, void *data,
return err;
}

static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
{
struct cmd_lookup match = { NULL, hdev };
struct mgmt_pending_cmd *cmd = data;
struct mgmt_mode *cp = cmd->param;
u8 enable = cp->val;
bool changed;

if (err) {
u8 mgmt_err = mgmt_status(err);

if (enable && hci_dev_test_and_clear_flag(hdev,
HCI_SSP_ENABLED)) {
hci_dev_clear_flag(hdev, HCI_HS_ENABLED);
new_settings(hdev, NULL);
}

mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, cmd_status_rsp,
&mgmt_err);
return;
}

if (enable) {
changed = !hci_dev_test_and_set_flag(hdev, HCI_SSP_ENABLED);
} else {
changed = hci_dev_test_and_clear_flag(hdev, HCI_SSP_ENABLED);

if (!changed)
changed = hci_dev_test_and_clear_flag(hdev,
HCI_HS_ENABLED);
else
hci_dev_clear_flag(hdev, HCI_HS_ENABLED);
}

mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, settings_rsp, &match);

if (changed)
new_settings(hdev, match.sk);

if (match.sk)
sock_put(match.sk);

hci_update_eir_sync(hdev);
}

static int set_ssp_sync(struct hci_dev *hdev, void *data)
{
struct mgmt_pending_cmd *cmd = data;
struct mgmt_mode *cp = cmd->param;
bool changed = false;
int err;

if (cp->val)
changed = !hci_dev_test_and_set_flag(hdev, HCI_SSP_ENABLED);

err = hci_write_ssp_mode_sync(hdev, cp->val);

if (!err && changed)
hci_dev_clear_flag(hdev, HCI_SSP_ENABLED);

return err;
}

static int set_ssp(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
{
struct mgmt_mode *cp = data;
Expand Down Expand Up @@ -1821,19 +1884,18 @@ static int set_ssp(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
}

cmd = mgmt_pending_add(sk, MGMT_OP_SET_SSP, hdev, data, len);
if (!cmd) {
if (!cmd)
err = -ENOMEM;
goto failed;
}

if (!cp->val && hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS))
hci_send_cmd(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE,
sizeof(cp->val), &cp->val);
else
err = hci_cmd_sync_queue(hdev, set_ssp_sync, cmd,
set_ssp_complete);

err = hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, 1, &cp->val);
if (err < 0) {
mgmt_pending_remove(cmd);
goto failed;
err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SSP,
MGMT_STATUS_FAILED);

if (cmd)
mgmt_pending_remove(cmd);
}

failed:
Expand Down Expand Up @@ -9309,74 +9371,6 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status)
sock_put(match.sk);
}

static void clear_eir(struct hci_request *req)
{
struct hci_dev *hdev = req->hdev;
struct hci_cp_write_eir cp;

if (!lmp_ext_inq_capable(hdev))
return;

memset(hdev->eir, 0, sizeof(hdev->eir));

memset(&cp, 0, sizeof(cp));

hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
}

void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
{
struct cmd_lookup match = { NULL, hdev };
struct hci_request req;
bool changed = false;

if (status) {
u8 mgmt_err = mgmt_status(status);

if (enable && hci_dev_test_and_clear_flag(hdev,
HCI_SSP_ENABLED)) {
hci_dev_clear_flag(hdev, HCI_HS_ENABLED);
new_settings(hdev, NULL);
}

mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, cmd_status_rsp,
&mgmt_err);
return;
}

if (enable) {
changed = !hci_dev_test_and_set_flag(hdev, HCI_SSP_ENABLED);
} else {
changed = hci_dev_test_and_clear_flag(hdev, HCI_SSP_ENABLED);
if (!changed)
changed = hci_dev_test_and_clear_flag(hdev,
HCI_HS_ENABLED);
else
hci_dev_clear_flag(hdev, HCI_HS_ENABLED);
}

mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, settings_rsp, &match);

if (changed)
new_settings(hdev, match.sk);

if (match.sk)
sock_put(match.sk);

hci_req_init(&req, hdev);

if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) {
if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS))
hci_req_add(&req, HCI_OP_WRITE_SSP_DEBUG_MODE,
sizeof(enable), &enable);
__hci_req_update_eir(&req);
} else {
clear_eir(&req);
}

hci_req_run(&req, NULL);
}

static void sk_lookup(struct mgmt_pending_cmd *cmd, void *data)
{
struct cmd_lookup *match = data;
Expand Down

0 comments on commit 3244845

Please sign in to comment.