Bluetooth: hci_sync: Convert MGMT_OP_SSP
authorBrian Gix <brian.gix@intel.com>
Wed, 27 Oct 2021 23:58:58 +0000 (16:58 -0700)
committerMarcel Holtmann <marcel@holtmann.org>
Fri, 29 Oct 2021 14:52:00 +0000 (16:52 +0200)
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>
include/net/bluetooth/hci_core.h
include/net/bluetooth/hci_sync.h
net/bluetooth/hci_event.c
net/bluetooth/hci_sync.c
net/bluetooth/mgmt.c

index a6b0752..3e53c84 100644 (file)
@@ -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);
index d9f2e31..db96546 100644 (file)
@@ -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);
index 6400869..0f5761b 100644 (file)
@@ -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
index 47beabe..8b63b4e 100644 (file)
@@ -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)
index ee144fa..bfa08eb 100644 (file)
@@ -1760,6 +1760,69 @@ failed:
        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) {
-               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;