Bluetooth: add to support LE privacy 1.2 & MGMT to load device RPA resolution 41/97941/5
authorh.sandeep <h.sandeep@samsung.com>
Tue, 15 Nov 2016 11:08:58 +0000 (16:38 +0530)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Tue, 22 Nov 2016 05:09:11 +0000 (14:09 +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: Ia1e7b2ae1ef9d5e12877d96759cb9089b52c20b7
Signed-off-by: paras.kumar <paras.kumar@samsung.com>
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 f9d117c1bf14f68da1b91807835d6d5fb4a33147..fe6eb86fba909741aac08e609a9810bd2be3c011 100644 (file)
@@ -133,6 +133,9 @@ struct smp_irk {
        bdaddr_t bdaddr;
        u8 addr_type;
        u8 val[16];
+#ifdef TIZEN_BT
+       u8 rpa_res_support;
+#endif
 };
 
 struct link_key {
@@ -1071,6 +1074,8 @@ int hci_get_conn_list(void __user *arg);
 int hci_get_conn_info(struct hci_dev *hdev, void __user *arg);
 int hci_get_auth_info(struct hci_dev *hdev, void __user *arg);
 #ifdef TIZEN_BT
+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_inquiry(void __user *arg);
index b4e30aeca4fbcd706237849daea3c9d7232697f0..314b69d6c29ed835816235c1d50b34db34bfd6bf 100644 (file)
@@ -222,6 +222,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
+
 /* EVENTS */
 
 /* For device name update changes */
index 1848ff8e93dafabf57fb0d9fce4ba82fd6705e2f..359ff4976805690d9e57ad22d9b767e8d38345e3 100644 (file)
@@ -724,13 +724,22 @@ static void hci_req_add_le_create_conn(struct hci_request *req,
        conn->state = BT_CONNECT;
 }
 
+#ifdef TIZEN_BT
+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 TIZEN_BT
+       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
@@ -739,11 +748,26 @@ static void hci_req_directed_advertising(struct hci_request *req,
         */
        hci_dev_clear_flag(hdev, HCI_LE_ADV);
 
+#ifdef TIZEN_BT
+       /* 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;
@@ -854,7 +878,11 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
                        return ERR_PTR(-EBUSY);
                }
 
+#ifdef TIZEN_BT
+               hci_req_directed_advertising(&req, conn, irk->rpa_res_support);
+#else
                hci_req_directed_advertising(&req, conn);
+#endif
                goto create_conn;
        }
 
index 39f2026dc477546aae9a844e2b1db9c2ab5aec8d..0d066020e77e28b9ed80d405713e1cdc1e2f772a 100644 (file)
@@ -2545,6 +2545,21 @@ void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
        }
 }
 
+#ifdef TIZEN_BT
+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;
+}
+#endif
 bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
 {
        struct smp_ltk *k;
index fc56baff26002df425cdf52a0b5dab15aa6b03ca..af8620d9af42b06760f74c78ff2e25e4d7533206 100644 (file)
@@ -7807,6 +7807,46 @@ void mgmt_le_data_length_change_complete(struct hci_dev *hdev,
 
        mgmt_event(MGMT_EV_LE_DATA_LENGTH_CHANGED, hdev, &ev, sizeof(ev), NULL);
 }
+
+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 = mgmt_cmd_status(sk, hdev->id,
+                                     MGMT_OP_SET_DEV_RPA_RES_SUPPORT,
+                                     MGMT_STATUS_NOT_SUPPORTED);
+               goto unlocked;
+       }
+
+       if (!hdev_is_powered(hdev)) {
+               err = mgmt_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 = mgmt_cmd_complete(sk, hdev->id,
+                                       MGMT_OP_SET_DEV_RPA_RES_SUPPORT,
+                                       MGMT_STATUS_NOT_PAIRED, NULL, 0);
+               goto unlocked;
+       }
+
+       err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_DEV_RPA_RES_SUPPORT,
+                               MGMT_STATUS_SUCCESS, NULL, 0);
+
+unlocked:
+       hci_dev_unlock(hdev);
+       return err;
+}
 #endif /* TIZEN_BT */
 
 static bool ltk_is_valid(struct mgmt_ltk_info *key)
@@ -9708,6 +9748,7 @@ static const struct hci_mgmt_handler tizen_mgmt_handlers[] = {
                                   MGMT_LE_READ_HOST_SUGGESTED_DATA_LENGTH_SIZE },
        { set_le_data_length_params,
                                   MGMT_LE_SET_DATA_LENGTH_SIZE },
+       { set_dev_rpa_res_support, MGMT_OP_SET_DEV_RPA_RES_SUPPORT_SIZE },
 };
 #endif