Bluetooth: add to support LE privacy 1.2 & MGMT to load device RPA resolution 07/97907/4
authorh.sandeep <h.sandeep@samsung.com>
Tue, 15 Nov 2016 09:04:01 +0000 (14:34 +0530)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Tue, 22 Nov 2016 05:35:13 +0000 (14:35 +0900)
RPA resolution support of peer device to be checked before starting
directed advertising. This patch load the resolution support info of
device and check before starting directed advertising.

Change-Id: I9c982e72e83024bcb493488e29c33aba7ffbf485
Signed-off-by: h.sandeep <h.sandeep@samsung.com>
[Fix coding style and adjust commit-msg]
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
include/net/bluetooth/hci_core.h
include/net/bluetooth/mgmt_tizen.h
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/mgmt.c

index 185214e..0edf790 100644 (file)
@@ -130,6 +130,9 @@ struct smp_irk {
        bdaddr_t bdaddr;
        u8 addr_type;
        u8 val[16];
+#ifdef CONFIG_TIZEN_WIP
+       u8 rpa_res_support;
+#endif
 };
 
 struct link_key {
@@ -1053,6 +1056,8 @@ int hci_get_dev_list(void __user *arg);
 int hci_get_dev_info(void __user *arg);
 int hci_get_conn_list(void __user *arg);
 #ifdef CONFIG_TIZEN_WIP
+int hci_set_rpa_res_support(struct hci_dev *hdev, bdaddr_t *bdaddr,
+                           u8 addr_type, u8 enabled);
 u32 get_link_mode(struct hci_conn *conn);
 #endif
 int hci_get_conn_info(struct hci_dev *hdev, void __user *arg);
index baf2de4..4afb984 100644 (file)
@@ -220,6 +220,13 @@ struct mgmt_rp_le_set_data_length {
 } __packed;
 #define MGMT_LE_SET_DATA_LENGTH_RSP_SIZE               3
 
+#define MGMT_OP_SET_DEV_RPA_RES_SUPPORT                (TIZEN_OP_CODE_BASE + 0x19)
+struct mgmt_cp_set_dev_rpa_res_support {
+       struct  mgmt_addr_info addr;
+       __u8    res_support;
+} __packed;
+#define MGMT_OP_SET_DEV_RPA_RES_SUPPORT_SIZE   8
+
 /* BEGIN TIZEN_Bluetooth :: name update changes */
 #define MGMT_EV_DEVICE_NAME_UPDATE             (TIZEN_EV_BASE + 0x01)
 struct mgmt_ev_device_name_update {
index b133366..598cb67 100644 (file)
@@ -720,13 +720,22 @@ static void hci_req_add_le_create_conn(struct hci_request *req,
        conn->state = BT_CONNECT;
 }
 
+#ifdef CONFIG_TIZEN_WIP
+static void hci_req_directed_advertising(struct hci_request *req,
+                                        struct hci_conn *conn,
+                                        u8 rpa_res_support)
+#else
 static void hci_req_directed_advertising(struct hci_request *req,
                                         struct hci_conn *conn)
+#endif
 {
        struct hci_dev *hdev = req->hdev;
        struct hci_cp_le_set_adv_param cp;
        u8 own_addr_type;
        u8 enable;
+#ifdef CONFIG_TIZEN_WIP
+       bool require_privacy;
+#endif
 
        /* Clear the HCI_LE_ADV bit temporarily so that the
         * hci_update_random_address knows that it's safe to go ahead
@@ -735,11 +744,26 @@ static void hci_req_directed_advertising(struct hci_request *req,
         */
        clear_bit(HCI_LE_ADV, &hdev->dev_flags);
 
+#ifdef CONFIG_TIZEN_WIP
+       /* Set require_privacy to true if remote device is able to
+        * resolve RPA (As per BT spec 4.2 & Enhanced privacy feature)
+        * otherwise, set require_privacy to false so that the remote
+        * device has a chance of identifying us.
+        */
+       if (rpa_res_support)
+               require_privacy = true;
+       else
+               require_privacy = false;
+
+       if (hci_update_random_address(req, require_privacy, &own_addr_type) < 0)
+               return;
+#else
        /* Set require_privacy to false so that the remote device has a
         * chance of identifying us.
         */
        if (hci_update_random_address(req, false, &own_addr_type) < 0)
                return;
+#endif
 
        memset(&cp, 0, sizeof(cp));
        cp.type = LE_ADV_DIRECT_IND;
@@ -842,7 +866,11 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
                        return ERR_PTR(-EBUSY);
                }
 
+#ifdef CONFIG_TIZEN_WIP
+               hci_req_directed_advertising(&req, conn, irk->rpa_res_support);
+#else
                hci_req_directed_advertising(&req, conn);
+#endif
                goto create_conn;
        }
 
index c599077..be8bb5c 100644 (file)
@@ -2567,6 +2567,20 @@ void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
 }
 
 #ifdef CONFIG_TIZEN_WIP
+int hci_set_rpa_res_support(struct hci_dev *hdev, bdaddr_t *bdaddr,
+                           u8 addr_type, u8 enabled)
+{
+       struct smp_irk *irk;
+
+       irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
+       if (!irk)
+               return -ENOENT;
+
+       irk->rpa_res_support = enabled;
+
+       return 0;
+}
+
 /* Timeout Error Event is being handled */
 static void hci_tx_timeout_error_evt(struct hci_dev *hdev)
 {
index e2ae0fd..e6c8ff3 100644 (file)
@@ -5226,6 +5226,46 @@ done:
        hci_dev_unlock(hdev);
        return err;
 }
+
+static int set_dev_rpa_res_support(struct sock *sk, struct hci_dev *hdev,
+                                  void *data, u16 len)
+{
+       struct mgmt_cp_set_dev_rpa_res_support *cp = data;
+       int err;
+
+       BT_DBG("Set resolve RPA as %u for %s", cp->res_support, hdev->name);
+
+       hci_dev_lock(hdev);
+
+       if (!lmp_le_capable(hdev)) {
+               err = cmd_status(sk, hdev->id,
+                                MGMT_OP_SET_DEV_RPA_RES_SUPPORT,
+                                MGMT_STATUS_NOT_SUPPORTED);
+               goto unlocked;
+       }
+
+       if (!hdev_is_powered(hdev)) {
+               err = cmd_status(sk, hdev->id,
+                                MGMT_OP_SET_DEV_RPA_RES_SUPPORT,
+                                MGMT_STATUS_REJECTED);
+               goto unlocked;
+       }
+
+       if (hci_set_rpa_res_support(hdev, &cp->addr.bdaddr, cp->addr.type,
+                                   cp->res_support)) {
+               err = cmd_complete(sk, hdev->id,
+                                  MGMT_OP_SET_DEV_RPA_RES_SUPPORT,
+                                  MGMT_STATUS_NOT_PAIRED, NULL, 0);
+               goto unlocked;
+       }
+
+       err = cmd_complete(sk, hdev->id, MGMT_OP_SET_DEV_RPA_RES_SUPPORT,
+                          MGMT_STATUS_SUCCESS, NULL, 0);
+
+unlocked:
+       hci_dev_unlock(hdev);
+       return err;
+}
 /* END TIZEN_Bluetooth */
 #endif
 
@@ -8437,6 +8477,7 @@ static const struct mgmt_handler tizen_mgmt_handlers[] = {
                                   MGMT_LE_READ_HOST_SUGGESTED_DATA_LENGTH_SIZE },
        { set_le_data_length_params, false,
                                   MGMT_LE_SET_DATA_LENGTH_SIZE },
+       { set_dev_rpa_res_support, false, MGMT_OP_SET_DEV_RPA_RES_SUPPORT_SIZE },
 };
 #endif