Bluetooth: Fix returning proper command status for start_discovery
authorJohan Hedberg <johan.hedberg@intel.com>
Thu, 10 Jan 2013 12:54:09 +0000 (14:54 +0200)
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>
Thu, 10 Jan 2013 18:28:40 +0000 (16:28 -0200)
Management commands should whenever possible fail with proper command
status or command complete events. This patch fixes the
mgmt_start_discovery command to do this for the failure cases where an
incorrect parameter value was passed to it ("not supported" if the
parameter value was valid but the controller doesn't support it and
"invalid params" if it isn't valid at all).

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
net/bluetooth/mgmt.c

index 3959c471b2b4c62357ec7f1e32742bee27de03dd..b1b0a36e1e801f4ed4e8b0bdd0912eead4a84d24 100644 (file)
@@ -2382,31 +2382,45 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
 
        switch (hdev->discovery.type) {
        case DISCOV_TYPE_BREDR:
-               if (lmp_bredr_capable(hdev))
-                       err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR);
-               else
-                       err = -ENOTSUPP;
+               if (!lmp_bredr_capable(hdev)) {
+                       err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
+                                        MGMT_STATUS_NOT_SUPPORTED);
+                       mgmt_pending_remove(cmd);
+                       goto failed;
+               }
+
+               err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR);
                break;
 
        case DISCOV_TYPE_LE:
-               if (lmp_host_le_capable(hdev))
-                       err = hci_le_scan(hdev, LE_SCAN_TYPE, LE_SCAN_INT,
-                                         LE_SCAN_WIN, LE_SCAN_TIMEOUT_LE_ONLY);
-               else
-                       err = -ENOTSUPP;
+               if (!lmp_host_le_capable(hdev)) {
+                       err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
+                                        MGMT_STATUS_NOT_SUPPORTED);
+                       mgmt_pending_remove(cmd);
+                       goto failed;
+               }
+
+               err = hci_le_scan(hdev, LE_SCAN_TYPE, LE_SCAN_INT,
+                                 LE_SCAN_WIN, LE_SCAN_TIMEOUT_LE_ONLY);
                break;
 
        case DISCOV_TYPE_INTERLEAVED:
-               if (lmp_host_le_capable(hdev) && lmp_bredr_capable(hdev))
-                       err = hci_le_scan(hdev, LE_SCAN_TYPE, LE_SCAN_INT,
-                                         LE_SCAN_WIN,
-                                         LE_SCAN_TIMEOUT_BREDR_LE);
-               else
-                       err = -ENOTSUPP;
+               if (!lmp_host_le_capable(hdev) || !lmp_bredr_capable(hdev)) {
+                       err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
+                                        MGMT_STATUS_NOT_SUPPORTED);
+                       mgmt_pending_remove(cmd);
+                       goto failed;
+               }
+
+               err = hci_le_scan(hdev, LE_SCAN_TYPE, LE_SCAN_INT, LE_SCAN_WIN,
+                                 LE_SCAN_TIMEOUT_BREDR_LE);
                break;
 
        default:
-               err = -EINVAL;
+               err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
+                                MGMT_STATUS_INVALID_PARAMS);
+               mgmt_pending_remove(cmd);
+               goto failed;
        }
 
        if (err < 0)