Commit 3244845c authored by Brian Gix's avatar Brian Gix Committed by Marcel Holtmann
Browse files

Bluetooth: hci_sync: Convert MGMT_OP_SSP



mgmt-tester paths:
Set SSP on - Success 2
Set Device ID - SSP off and Power on

Signed-off-by: default avatarBrian Gix <brian.gix@intel.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 5e233ed5
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -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);
+1 −3
Original line number Diff line number Diff line
@@ -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
+6 −1
Original line number Diff line number Diff line
@@ -2142,7 +2142,7 @@ 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;

@@ -2150,6 +2150,11 @@ static int hci_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode)
	    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)
+72 −78
Original line number Diff line number Diff line
@@ -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;
@@ -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) {
		err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SSP,
				      MGMT_STATUS_FAILED);

		if (cmd)
			mgmt_pending_remove(cmd);
		goto failed;
	}

failed:
@@ -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;