@@ -1659,6 +1659,8 @@ void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 *bdaddr_type);
int hci_req_update_resolving_list(struct hci_dev *hdev, u8 addr_type,
bdaddr_t *bdaddr, u8 irk[16]);
+void hci_req_update_resolving_list_local_irk(struct hci_dev *hdev);
+
void hci_req_del_from_resolving_list(struct hci_dev *hdev, u8 addr_type,
bdaddr_t *bdaddr);
@@ -965,6 +965,56 @@ int hci_req_update_resolving_list(struct hci_dev *hdev, u8 type, bdaddr_t *bdadd
return 0;
}
+void hci_req_update_resolving_list_local_irk(struct hci_dev *hdev)
+{
+ struct bdaddr_list_with_irk *irk;
+ struct hci_request req;
+
+ BT_DBG("");
+
+ /* Nothing to be done if LL privacy is not supported. */
+ if (!(hdev->le_features[0] & HCI_LE_LL_PRIVACY))
+ return;
+
+ /* If resolving list is empty, nothing is to be done.*/
+ if (list_empty(&hdev->le_resolv_list))
+ return;
+
+ /* Resolving List cannot be updated if address resolution
+ * in the controller is enabled and advertisement or scanning
+ * or create connection command is ongoing.
+ */
+ if ( !hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION) &&
+ ( hci_dev_test_flag(hdev, HCI_LE_ADV) ||
+ hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
+ hci_lookup_le_connect(hdev) ) )
+ return;
+
+ /* If resolving list is not empty, then clear the resolving list
+ * and add back each entry with updated local IRK.
+ */
+ hci_req_init(&req, hdev);
+
+ list_for_each_entry(irk, &hdev->le_resolv_list, list) {
+ struct hci_cp_le_add_to_resolv_list cp;
+ struct hci_cp_le_del_from_resolv_list cp1;
+
+ cp1.bdaddr_type = irk->bdaddr_type;
+ bacpy(&cp1.bdaddr, &irk->bdaddr);
+ hci_req_add(&req, HCI_OP_LE_DEL_FROM_RESOLV_LIST,
+ sizeof(cp1), &cp1);
+
+ cp.bdaddr_type = irk->bdaddr_type;
+ bacpy(&cp.bdaddr, &irk->bdaddr);
+ memcpy(cp.peer_irk, irk->peer_irk, 16);
+ memcpy(cp.local_irk, hdev->irk, 16);
+ hci_req_add(&req, HCI_OP_LE_ADD_TO_RESOLV_LIST,
+ sizeof(cp), &cp);
+ }
+
+ hci_req_run(&req, NULL);
+}
+
void hci_req_del_from_resolving_list(struct hci_dev *hdev, u8 addr_type, bdaddr_t *bdaddr)
{
struct hci_cp_le_del_from_resolv_list cp;