Bluetooth: Functions to modify WhiteList
authorSudha Bheemanna <b.sudha@samsung.com>
Wed, 24 Aug 2016 09:32:56 +0000 (15:02 +0530)
committerHoegeun Kwon <hoegeun.kwon@samsung.com>
Mon, 6 Jul 2020 09:08:20 +0000 (18:08 +0900)
This patch provides MGMT commands to manage the white
list which includes, adding, removing and clearing the
devices from white list.

Change-Id: If71107129d3a090ae81448a8122b76accd4f5522
Signed-off-by: Sudha Bheemanna <b.sudha@samsung.com>
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
Signed-off-by: Amit Purwar <amit.purwar@samsung.com>
include/net/bluetooth/mgmt_tizen.h
net/bluetooth/mgmt.c

index 04bd255..6dc8e36 100644 (file)
@@ -46,4 +46,21 @@ struct mgmt_cp_set_scan_rsp_data {
 #define MGMT_SET_SCAN_RSP_DATA_SIZE            HCI_MAX_AD_LENGTH
 #define MGMT_SET_SCAN_RSP_MIN_APP_DATA_SIZE    1
 
+#define MGMT_OP_ADD_DEV_WHITE_LIST             (TIZEN_OP_CODE_BASE + 0x04)
+struct mgmt_cp_add_dev_white_list {
+       __u8    bdaddr_type;
+       bdaddr_t bdaddr;
+} __packed;
+#define MGMT_ADD_DEV_WHITE_LIST_SIZE           7
+
+#define MGMT_OP_REMOVE_DEV_FROM_WHITE_LIST     (TIZEN_OP_CODE_BASE + 0x05)
+struct mgmt_cp_remove_dev_from_white_list {
+       __u8    bdaddr_type;
+       bdaddr_t bdaddr;
+} __packed;
+#define MGMT_REMOVE_DEV_FROM_WHITE_LIST_SIZE   7
+
+#define MGMT_OP_CLEAR_DEV_WHITE_LIST           (TIZEN_OP_CODE_BASE + 0x06)
+#define MGMT_OP_CLEAR_DEV_WHITE_LIST_SIZE      0
+
 #endif /* __MGMT_TIZEN_H */
index 8e1a32b..87a0f87 100644 (file)
@@ -5285,6 +5285,244 @@ unlocked:
 
        return err;
 }
+
+/* Adv White List feature */
+static void add_white_list_complete(struct hci_dev *hdev, u8 status, u16 opcode)
+{
+       struct mgmt_cp_add_dev_white_list *cp;
+       struct mgmt_pending_cmd *cmd;
+
+       BT_DBG("status 0x%02x", status);
+
+       hci_dev_lock(hdev);
+
+       cmd = pending_find(MGMT_OP_ADD_DEV_WHITE_LIST, hdev);
+       if (!cmd)
+               goto unlock;
+
+       cp = cmd->param;
+
+       if (status)
+               mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_ADD_DEV_WHITE_LIST,
+                          mgmt_status(status));
+       else
+               mgmt_cmd_complete(cmd->sk, hdev->id,
+                               MGMT_OP_ADD_DEV_WHITE_LIST, 0, cp, sizeof(*cp));
+
+       mgmt_pending_remove(cmd);
+
+unlock:
+       hci_dev_unlock(hdev);
+}
+
+static int add_white_list(struct sock *sk, struct hci_dev *hdev,
+                          void *data, u16 len)
+{
+       struct mgmt_pending_cmd *cmd;
+       struct mgmt_cp_add_dev_white_list *cp = data;
+       struct hci_request req;
+       int err;
+
+       BT_DBG("%s", hdev->name);
+
+       if (!lmp_le_capable(hdev))
+               return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_DEV_WHITE_LIST,
+                                 MGMT_STATUS_NOT_SUPPORTED);
+
+       if (!hdev_is_powered(hdev))
+               return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_DEV_WHITE_LIST,
+                                 MGMT_STATUS_REJECTED);
+
+       hci_dev_lock(hdev);
+
+       if (pending_find(MGMT_OP_ADD_DEV_WHITE_LIST, hdev)) {
+               err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_DEV_WHITE_LIST,
+                               MGMT_STATUS_BUSY);
+               goto unlocked;
+       }
+
+       cmd = mgmt_pending_add(sk, MGMT_OP_ADD_DEV_WHITE_LIST, hdev, data, len);
+       if (!cmd) {
+               err = -ENOMEM;
+               goto unlocked;
+       }
+
+       hci_req_init(&req, hdev);
+
+       hci_req_add(&req, HCI_OP_LE_ADD_TO_WHITE_LIST, sizeof(*cp), cp);
+
+       err = hci_req_run(&req, add_white_list_complete);
+       if (err < 0) {
+               mgmt_pending_remove(cmd);
+               goto unlocked;
+       }
+
+unlocked:
+       hci_dev_unlock(hdev);
+
+       return err;
+}
+
+static void remove_from_white_list_complete(struct hci_dev *hdev,
+                       u8 status, u16 opcode)
+{
+       struct mgmt_cp_remove_dev_from_white_list *cp;
+       struct mgmt_pending_cmd *cmd;
+
+       BT_DBG("status 0x%02x", status);
+
+       hci_dev_lock(hdev);
+
+       cmd = pending_find(MGMT_OP_REMOVE_DEV_FROM_WHITE_LIST, hdev);
+       if (!cmd)
+               goto unlock;
+
+       cp = cmd->param;
+
+       if (status)
+               mgmt_cmd_status(cmd->sk, hdev->id,
+                       MGMT_OP_REMOVE_DEV_FROM_WHITE_LIST,
+                       mgmt_status(status));
+       else
+               mgmt_cmd_complete(cmd->sk, hdev->id,
+                       MGMT_OP_REMOVE_DEV_FROM_WHITE_LIST, 0,
+                       cp, sizeof(*cp));
+
+       mgmt_pending_remove(cmd);
+
+unlock:
+       hci_dev_unlock(hdev);
+}
+
+static int remove_from_white_list(struct sock *sk, struct hci_dev *hdev,
+                          void *data, u16 len)
+{
+       struct mgmt_pending_cmd *cmd;
+       struct mgmt_cp_remove_dev_from_white_list *cp = data;
+       struct hci_request req;
+       int err;
+
+       BT_DBG("%s", hdev->name);
+
+       if (!lmp_le_capable(hdev))
+               return mgmt_cmd_status(sk, hdev->id,
+                               MGMT_OP_REMOVE_DEV_FROM_WHITE_LIST,
+                               MGMT_STATUS_NOT_SUPPORTED);
+
+       if (!hdev_is_powered(hdev))
+               return mgmt_cmd_status(sk, hdev->id,
+                               MGMT_OP_REMOVE_DEV_FROM_WHITE_LIST,
+                               MGMT_STATUS_REJECTED);
+
+       hci_dev_lock(hdev);
+
+       if (pending_find(MGMT_OP_REMOVE_DEV_FROM_WHITE_LIST, hdev)) {
+               err = mgmt_cmd_status(sk, hdev->id,
+                               MGMT_OP_REMOVE_DEV_FROM_WHITE_LIST,
+                               MGMT_STATUS_BUSY);
+               goto unlocked;
+       }
+
+       cmd = mgmt_pending_add(sk, MGMT_OP_REMOVE_DEV_FROM_WHITE_LIST,
+                               hdev, data, len);
+       if (!cmd) {
+               err = -ENOMEM;
+               goto unlocked;
+       }
+
+       hci_req_init(&req, hdev);
+
+       hci_req_add(&req, HCI_OP_LE_DEL_FROM_WHITE_LIST, sizeof(*cp), cp);
+
+       err = hci_req_run(&req, remove_from_white_list_complete);
+       if (err < 0) {
+               mgmt_pending_remove(cmd);
+               goto unlocked;
+       }
+
+unlocked:
+       hci_dev_unlock(hdev);
+
+       return err;
+}
+
+static void clear_white_list_complete(struct hci_dev *hdev, u8 status,
+                       u16 opcode)
+{
+       struct mgmt_pending_cmd *cmd;
+
+       BT_DBG("status 0x%02x", status);
+
+       hci_dev_lock(hdev);
+
+       cmd = pending_find(MGMT_OP_CLEAR_DEV_WHITE_LIST, hdev);
+       if (!cmd)
+               goto unlock;
+
+       if (status)
+               mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_CLEAR_DEV_WHITE_LIST,
+                          mgmt_status(status));
+       else
+               mgmt_cmd_complete(cmd->sk, hdev->id,
+                               MGMT_OP_CLEAR_DEV_WHITE_LIST,
+                               0, NULL, 0);
+
+       mgmt_pending_remove(cmd);
+
+unlock:
+       hci_dev_unlock(hdev);
+}
+
+static int clear_white_list(struct sock *sk, struct hci_dev *hdev,
+                          void *data, u16 len)
+{
+       struct mgmt_pending_cmd *cmd;
+       struct hci_request req;
+       int err;
+
+       BT_DBG("%s", hdev->name);
+
+       if (!lmp_le_capable(hdev))
+               return mgmt_cmd_status(sk, hdev->id,
+                               MGMT_OP_CLEAR_DEV_WHITE_LIST,
+                               MGMT_STATUS_NOT_SUPPORTED);
+
+       if (!hdev_is_powered(hdev))
+               return mgmt_cmd_status(sk, hdev->id,
+                               MGMT_OP_CLEAR_DEV_WHITE_LIST,
+                               MGMT_STATUS_REJECTED);
+
+       hci_dev_lock(hdev);
+
+       if (pending_find(MGMT_OP_CLEAR_DEV_WHITE_LIST, hdev)) {
+               err = mgmt_cmd_status(sk, hdev->id,
+                               MGMT_OP_CLEAR_DEV_WHITE_LIST,
+                               MGMT_STATUS_BUSY);
+               goto unlocked;
+       }
+
+       cmd = mgmt_pending_add(sk, MGMT_OP_CLEAR_DEV_WHITE_LIST,
+                               hdev, NULL, 0);
+       if (!cmd) {
+               err = -ENOMEM;
+               goto unlocked;
+       }
+
+       hci_req_init(&req, hdev);
+
+       hci_req_add(&req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL);
+
+       err = hci_req_run(&req, clear_white_list_complete);
+       if (err < 0) {
+               mgmt_pending_remove(cmd);
+               goto unlocked;
+       }
+
+unlocked:
+       hci_dev_unlock(hdev);
+
+       return err;
+}
 #endif /* TIZEN_BT */
 
 static bool ltk_is_valid(struct mgmt_ltk_info *key)
@@ -7146,6 +7384,9 @@ static const struct hci_mgmt_handler tizen_mgmt_handlers[] = {
                                                HCI_MGMT_VAR_LEN },
        { set_scan_rsp_data,       MGMT_SET_SCAN_RSP_MIN_APP_DATA_SIZE,
                                                HCI_MGMT_VAR_LEN },
+       { add_white_list,          MGMT_ADD_DEV_WHITE_LIST_SIZE },
+       { remove_from_white_list,  MGMT_REMOVE_DEV_FROM_WHITE_LIST_SIZE },
+       { clear_white_list,        MGMT_OP_CLEAR_DEV_WHITE_LIST_SIZE },
 };
 #endif