mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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: Brian Gix <brian.gix@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
		
							parent
							
								
									5e233ed59c
								
							
						
					
					
						commit
						3244845c63
					
				
					 5 changed files with 80 additions and 83 deletions
				
			
		| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		err = hci_cmd_sync_queue(hdev, set_ssp_sync, cmd,
 | 
			
		||||
					 set_ssp_complete);
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
	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:
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue