Bluetooth: Functions to modify WhiteList 62/306562/1
authorSudha Bheemanna <b.sudha@samsung.com>
Wed, 24 Aug 2016 09:32:56 +0000 (15:02 +0530)
committerJaehoon Chung <jh80.chung@samsung.com>
Fri, 23 Feb 2024 02:12:21 +0000 (11:12 +0900)
This patch provides MGMT commands to manage the white
list which includes, adding, removing and clearing the
devices from white list.

Change-Id: I1747e0aa3da4081a72909d89a25f4a21a12e2f44
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>
Signed-off-by: Wootak Jung <wootak.jung@samsung.com>
Signed-off-by: Jaehoon Chung <jh80.chung@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 b309bd4..d7a2528 100644 (file)
@@ -7296,6 +7296,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_ACCEPT_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_ACCEPT_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_ACCEPT_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;
+}
+
 static void set_scan_rsp_data_complete(struct hci_dev *hdev, u8 status,
                        u16 opcode)
 {
@@ -9605,6 +9843,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