diff options
-rw-r--r-- | include/net/bluetooth/hci_core.h | 5 | ||||
-rw-r--r-- | include/net/bluetooth/mgmt_tizen.h | 7 | ||||
-rw-r--r-- | net/bluetooth/hci_conn.c | 28 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 15 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 41 |
5 files changed, 96 insertions, 0 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index f9d117c1bf14..fe6eb86fba90 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -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); diff --git a/include/net/bluetooth/mgmt_tizen.h b/include/net/bluetooth/mgmt_tizen.h index a2ec784da31a..3fe7c7d4ea8b 100644 --- a/include/net/bluetooth/mgmt_tizen.h +++ b/include/net/bluetooth/mgmt_tizen.h @@ -228,6 +228,13 @@ struct mgmt_cp_set_irk { } __packed; #define MGMT_SET_IRK_SIZE 16 +#define MGMT_OP_SET_DEV_RPA_RES_SUPPORT (TIZEN_OP_CODE_BASE + 0x1a) +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 */ diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 1848ff8e93da..359ff4976805 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -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; } diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 39f2026dc477..0d066020e77e 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -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; diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 3fbcfdbe219d..185513200931 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -7834,6 +7834,46 @@ unlocked: 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 = 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) @@ -9736,6 +9776,7 @@ static const struct hci_mgmt_handler tizen_mgmt_handlers[] = { { set_le_data_length_params, MGMT_LE_SET_DATA_LENGTH_SIZE }, { set_irk, MGMT_SET_IRK_SIZE }, + { set_dev_rpa_res_support, MGMT_OP_SET_DEV_RPA_RES_SUPPORT_SIZE }, }; #endif |