This enables Link Layer Privacy and sets RPA timeout to 900sec < HCI Command: LE Set Address Resolution Enable (0x08|0x002d) plen 1 Address resolution: Enabled (0x01) > HCI Event: Command Complete (0x0e) plen 4 LE Set Address Resolution Enable (0x08|0x002d) ncmd 1d Status: Success (0x00) < HCI Command: LE Set Resolvable Private Address Timeout (0x08|0x002e) plen 2 Timeout: 900 seconds > HCI Event: Command Complete (0x0e) plen 4 LE Set Resolvable Private Address Timeout (0x08|0x002e) ncmd 1 Status: Success (0x00) During Successfull pairing adding the information to device Resolving list < HCI Command: LE Add Device To Resolving List (0x08|0x0027) plen 39 Address type: Random (0x01) Address: D1:79:92:B1:83:DF (Static) Peer identity resolving key: ecc317056e5b385cda281b9c24a453e9 Local identity resolving key: 00000000000000000000000000000000 < ACL Data TX: Handle 3585 flags 0x00 dlen 21 SMP: Signing Information (0x0a) len 16 Signature key: 37b6c45656c7e8b3ec8db062c3e0c2b2 > ACL Data RX: Handle 3585 flags 0x02 dlen 9 ATT: Error Response (0x01) len 4 Read By Group Type Request (0x10) Handle: 0x0001 Error: Attribute Not Found (0x0a) > ACL Data RX: Handle 3585 flags 0x02 dlen 11 ATT: Read By Group Type Request (0x10) len 6 Handle range: 0x000a-0xffff Attribute group type: Primary Service (0x2800) > HCI Event: Command Complete (0x0e) plen 4 LE Add Device To Resolving List (0x08|0x0027) ncmd 1 Status: Success (0x00) Signed-off-by: Sathish Narsimman <sathish.narasimman@xxxxxxxxx> --- include/net/bluetooth/hci.h | 2 ++ net/bluetooth/hci_conn.c | 32 ++++++++++++++++++++++++++++++++ net/bluetooth/hci_core.c | 20 +++++++++++++++++++- net/bluetooth/hci_event.c | 32 +++++++++++++++++++++++++------- net/bluetooth/hci_request.c | 16 +++++++++++++--- net/bluetooth/mgmt.c | 10 +++++++++- net/bluetooth/smp.c | 11 +++++++++++ 7 files changed, 111 insertions(+), 12 deletions(-) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 352bc43940ff..d8431ebb8baa 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -1617,6 +1617,8 @@ struct hci_rp_le_read_resolv_list_size { #define HCI_OP_LE_SET_ADDR_RESOLV_ENABLE 0x202d +#define HCI_OP_LE_SET_RPA_TIMEOUT 0x202e + #define HCI_OP_LE_READ_MAX_DATA_LEN 0x202f struct hci_rp_le_read_max_data_len { __u8 status; diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index e245bc155cc2..06067c0852a6 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -830,6 +830,14 @@ static void hci_req_add_le_create_conn(struct hci_request *req, plen = sizeof(*cp); + /* If the own_addr_type is 0x03 or 0x02 and peer is present + * in Kernel IRK list, but not in resolving add the peer to + * the resolving list. + */ + if (own_addr_type == 0x03 || own_addr_type == 0x02) + hci_req_check_and_update_resolving_list(hdev, conn->dst_type, + &conn->dst); + if (scan_1m(hdev)) { cp->phys |= LE_SCAN_PHY_1M; set_ext_conn_params(conn, p); @@ -866,6 +874,14 @@ static void hci_req_add_le_create_conn(struct hci_request *req, cp.scan_interval = cpu_to_le16(hdev->le_scan_interval); cp.scan_window = cp.scan_interval; + /* If the own_addr_type is 0x03 or 0x02 and peer is present + * in Kernel IRK list, but not in resolving add the peer to + * the resolving list. + */ + if (own_addr_type == 0x03 || own_addr_type == 0x02) + hci_req_check_and_update_resolving_list(hdev, conn->dst_type, + &conn->dst); + bacpy(&cp.peer_addr, &conn->dst); cp.peer_addr_type = conn->dst_type; cp.own_address_type = own_addr_type; @@ -901,6 +917,14 @@ static void hci_req_directed_advertising(struct hci_request *req, &own_addr_type, &random_addr) < 0) return; + /* If the own_addr_type is 0x03 or 0x02 and peer is present + * in Kernel IRK list, but not in resolving add the peer to + * the resolving list. + */ + if (own_addr_type == 0x03 || own_addr_type == 0x03) + hci_req_check_and_update_resolving_list(hdev, conn->dst_type, + &conn->dst); + memset(&cp, 0, sizeof(cp)); cp.evt_properties = cpu_to_le16(LE_LEGACY_ADV_DIRECT_IND); @@ -959,6 +983,14 @@ static void hci_req_directed_advertising(struct hci_request *req, &own_addr_type) < 0) return; + /* If the own_addr_type is 0x03 or 0x02 and peer is present + * in Kernel IRK list, but not in resolving add the peer to + * the resolving list. + */ + if (own_addr_type == 0x03 || own_addr_type == 0x02) + hci_req_check_and_update_resolving_list(hdev, conn->dst_type, + &conn->dst); + memset(&cp, 0, sizeof(cp)); /* Some controllers might reject command if intervals are not diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index dbd2ad3a26ed..7727be922084 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -713,7 +713,7 @@ static int hci_init3_req(struct hci_request *req, unsigned long opt) /* If the controller supports the LE Extended Create Connection * command, enable the corresponding event. */ - if (use_ext_conn(hdev)) + if (use_ext_conn(hdev) || hdev->le_features[0] & HCI_LE_LL_PRIVACY) events[1] |= 0x02; /* LE Enhanced Connection * Complete */ @@ -762,6 +762,24 @@ static int hci_init3_req(struct hci_request *req, unsigned long opt) hci_req_add(req, HCI_OP_LE_CLEAR_RESOLV_LIST, 0, NULL); } + if (hdev->commands[35] & 0x02) { + u8 addr_resoln_enable = 0x01; + + /* Enable Address Resolution in controller */ + hci_req_add(req, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE, + sizeof(addr_resoln_enable), + &addr_resoln_enable); + } + + if (hdev->commands[35] & 0x40) { + __le16 rpa_timeout = cpu_to_le16(hdev->rpa_timeout); + + /* Set RPA timeout */ + hci_req_add(req, HCI_OP_LE_SET_RPA_TIMEOUT, 2, + &rpa_timeout); + + } + if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) { /* Read LE Maximum Data Length */ hci_req_add(req, HCI_OP_LE_READ_MAX_DATA_LEN, 0, NULL); diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 20408d386268..d5ce1921fadd 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1684,7 +1684,11 @@ static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb) return; hci_dev_lock(hdev); - hdev->adv_addr_type = cp->own_address_type; + + if (cp->own_address_type == ADDR_LE_DEV_PUBLIC) + hdev->adv_addr_type = ADDR_LE_DEV_PUBLIC; + else + hdev->adv_addr_type = ADDR_LE_DEV_RANDOM; hci_dev_unlock(hdev); } @@ -1704,7 +1708,12 @@ static void hci_cc_set_ext_adv_param(struct hci_dev *hdev, struct sk_buff *skb) return; hci_dev_lock(hdev); - hdev->adv_addr_type = cp->own_addr_type; + + if (cp->own_addr_type == ADDR_LE_DEV_PUBLIC) + hdev->adv_addr_type = ADDR_LE_DEV_PUBLIC; + else + hdev->adv_addr_type = ADDR_LE_DEV_RANDOM; + if (!hdev->cur_adv_instance) { /* Store in hdev for instance 0 */ hdev->adv_tx_power = rp->tx_power; @@ -2267,11 +2276,13 @@ static void cs_le_create_conn(struct hci_dev *hdev, bdaddr_t *peer_addr, * is needed for SMP. These values will not change during the * lifetime of the connection. */ - conn->init_addr_type = own_address_type; - if (own_address_type == ADDR_LE_DEV_RANDOM) + if (own_address_type == 0x03 || own_address_type == 0x01) { + conn->init_addr_type = ADDR_LE_DEV_RANDOM; bacpy(&conn->init_addr, &hdev->random_addr); - else + } else { + conn->init_addr_type = ADDR_LE_DEV_PUBLIC; bacpy(&conn->init_addr, &hdev->bdaddr); + } conn->resp_addr_type = peer_addr_type; bacpy(&conn->resp_addr, peer_addr); @@ -5141,6 +5152,8 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, } } + hci_req_check_and_update_resolving_list(hdev, (conn->dst_type), &conn->dst); + unlock: hci_update_background_scan(hdev); hci_dev_unlock(hdev); @@ -5365,8 +5378,13 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, /* Only resolvable random addresses are valid for these * kind of reports and others can be ignored. */ - if (!hci_bdaddr_is_rpa(direct_addr, direct_addr_type)) - return; + if (!hci_bdaddr_is_rpa(direct_addr, direct_addr_type)) { + /* Controller with LL Privacy Supported tend to resolve + * the RPA. In that case we should ignore this condition + */ + if ( !(hdev->le_features[0] & HCI_LE_LL_PRIVACY)) + return; + } /* If the controller is not using resolvable random * addresses, then this report can be ignored. diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index 6b685cdc7de5..12868caf50ea 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -1916,7 +1916,12 @@ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy, if (use_rpa) { int to; - *own_addr_type = ADDR_LE_DEV_RANDOM; + if (hdev->le_features[0] & HCI_LE_LL_PRIVACY) { + /*if there is no resolving list used in the controller + * use the bd_addr from latest Le_set_random_address*/ + *own_addr_type = 0x03; + } else + *own_addr_type = ADDR_LE_DEV_RANDOM; if (adv_instance) { if (!adv_instance->rpa_expired && @@ -2074,7 +2079,7 @@ int __hci_req_setup_ext_adv_instance(struct hci_request *req, u8 instance) hci_req_add(req, HCI_OP_LE_SET_EXT_ADV_PARAMS, sizeof(cp), &cp); - if (own_addr_type == ADDR_LE_DEV_RANDOM && + if (((own_addr_type == ADDR_LE_DEV_RANDOM) || (own_addr_type == 0x03)) && bacmp(&random_addr, BDADDR_ANY)) { struct hci_cp_le_set_adv_set_rand_addr cp; @@ -2341,7 +2346,12 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy, if (use_rpa) { int to; - *own_addr_type = ADDR_LE_DEV_RANDOM; + if (hdev->le_features[0] & HCI_LE_LL_PRIVACY) { + /*if there is no resolving list used in the controller + * use the bd_addr from latest Le_set_random_address*/ + *own_addr_type = 0x03; + } else + *own_addr_type = ADDR_LE_DEV_RANDOM; if (!hci_dev_test_and_clear_flag(hdev, HCI_RPA_EXPIRED) && !bacmp(&hdev->random_addr, &hdev->rpa)) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 6552003a170e..2b2bc011a130 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -5084,8 +5084,10 @@ static int set_debug_keys(struct sock *sk, struct hci_dev *hdev, if (err < 0) goto unlock; - if (changed) + if (changed) { err = new_settings(hdev, sk); + hci_req_update_resolving_list_local_irk(hdev); + } unlock: hci_dev_unlock(hdev); @@ -5227,6 +5229,8 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data, BDADDR_ANY); } + /* Load the resolving list with entries from IRK list.*/ + hci_load_resolving_list(hdev); hci_dev_set_flag(hdev, HCI_RPA_RESOLVING); err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_LOAD_IRKS, 0, NULL, 0); @@ -7213,6 +7217,10 @@ void mgmt_power_on(struct hci_dev *hdev, int err) if (match.sk) sock_put(match.sk); + /* If load _irk was called when controller was powered down, + * then the resolving list has to be updated now. + */ + hci_load_resolving_list(hdev); hci_dev_unlock(hdev); } diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 1476a91ce935..85be3f5d869a 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -2425,6 +2425,8 @@ int smp_cancel_and_remove_pairing(struct hci_dev *hdev, bdaddr_t *bdaddr, struct smp_chan *smp; int err; + hci_req_del_from_resolving_list(hdev, addr_type, bdaddr); + err = hci_remove_ltk(hdev, bdaddr, addr_type); hci_remove_irk(hdev, bdaddr, addr_type); @@ -2619,6 +2621,15 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr, smp->id_addr_type, smp->irk, &rpa); + /* Add the device to the resolving list.*/ + hci_req_update_resolving_list(conn->hcon->hdev, + smp->remote_irk->addr_type, + &smp->remote_irk->bdaddr, + smp->remote_irk->val); + + + /*TODO: Check remote device Supports LL Privacy. If not set the device + * with IRK to Device-privacy Mode - Should be discussed - Based on */ distribute: if (!(smp->remote_key_dist & KEY_DIST_MASK)) smp_distribute_keys(smp); -- 2.17.1