Bluetooth: Add discovery type validity helper
authorJohan Hedberg <johan.hedberg@intel.com>
Wed, 11 Nov 2015 06:11:24 +0000 (08:11 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Thu, 19 Nov 2015 16:50:30 +0000 (17:50 +0100)
As preparation for moving the discovery HCI commands behind
req_workqueue, add a helper and do the validity checks of the given
discovery type before proceeding further. This way we don't need to do
them again in hci_request.c.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
net/bluetooth/mgmt.c

index a229cfd0530eca9558af91b7b685ffd73237cb1a..e634b4d85249170050a692fb6de3c43c14e919f1 100644 (file)
@@ -4375,6 +4375,33 @@ unlock:
        hci_dev_unlock(hdev);
 }
 
+static bool discovery_type_is_valid(struct hci_dev *hdev, uint8_t type,
+                                   uint8_t *mgmt_status)
+{
+       switch (type) {
+       case DISCOV_TYPE_LE:
+               *mgmt_status = mgmt_le_support(hdev);
+               if (*mgmt_status)
+                       return false;
+               break;
+       case DISCOV_TYPE_INTERLEAVED:
+               *mgmt_status = mgmt_le_support(hdev);
+               if (*mgmt_status)
+                       return false;
+               /* Intentional fall-through */
+       case DISCOV_TYPE_BREDR:
+               *mgmt_status = mgmt_bredr_support(hdev);
+               if (*mgmt_status)
+                       return false;
+               break;
+       default:
+               *mgmt_status = MGMT_STATUS_INVALID_PARAMS;
+               return false;
+       }
+
+       return true;
+}
+
 static int start_discovery(struct sock *sk, struct hci_dev *hdev,
                           void *data, u16 len)
 {
@@ -4403,6 +4430,12 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
                goto failed;
        }
 
+       if (!discovery_type_is_valid(hdev, cp->type, &status)) {
+               err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY,
+                                       status, &cp->type, sizeof(cp->type));
+               goto failed;
+       }
+
        cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, hdev, data, len);
        if (!cmd) {
                err = -ENOMEM;
@@ -4502,6 +4535,13 @@ static int start_service_discovery(struct sock *sk, struct hci_dev *hdev,
                goto failed;
        }
 
+       if (!discovery_type_is_valid(hdev, cp->type, &status)) {
+               err = mgmt_cmd_complete(sk, hdev->id,
+                                       MGMT_OP_START_SERVICE_DISCOVERY,
+                                       status, &cp->type, sizeof(cp->type));
+               goto failed;
+       }
+
        cmd = mgmt_pending_add(sk, MGMT_OP_START_SERVICE_DISCOVERY,
                               hdev, data, len);
        if (!cmd) {