diff --git a/android/bluetooth.c b/android/bluetooth.c
index c664461..3030571 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
bdaddr_t bdaddr;
uint8_t bdaddr_type;
+ bdaddr_t rpa;
+ uint8_t rpa_type;
+
bool le;
bool bredr;
static void get_device_android_addr(struct device *dev, uint8_t *addr)
{
- bdaddr2android(&dev->bdaddr, addr);
+ /*
+ * If RPA is set it means that IRK was received and ID address is being
+ * used. Android Framework is still using old RPA and it needs to be
+ * used in notifications.
+ */
+ if (bacmp(&dev->rpa, BDADDR_ANY))
+ bdaddr2android(&dev->rpa, addr);
+ else
+ bdaddr2android(&dev->bdaddr, addr);
}
static void mgmt_debug(const char *str, void *user_data)
const struct device *dev = a;
const bdaddr_t *bdaddr = b;
+ /* Android is using RPA even if IRK was received and ID addr resolved */
+ if (!bacmp(&dev->rpa, bdaddr))
+ return 0;
+
return bacmp(&dev->bdaddr, bdaddr);
}
return;
}
- ba2str(dst, addr);
+ ba2str(&dev->bdaddr, addr);
DBG("%s Gatt CCC %d", addr, value);
/* Notify Gatt if its registered for LE events */
if (bdaddr_type != BDADDR_BREDR && gatt_device_found_cb) {
bool discoverable;
+ bdaddr_t *addr;
+ uint8_t addr_type;
discoverable = eir.flags & (EIR_LIM_DISC | EIR_GEN_DISC);
- gatt_device_found_cb(bdaddr, bdaddr_type, rssi, data_len, data,
- discoverable,
- dev->le_bonded);
+ /*
+ * If RPA is set it means that IRK was received and ID address
+ * is being used. Android Framework is still using old RPA and
+ * it needs to be used also in GATT notifications. Also GATT
+ * HAL implementation is using RPA for devices matching.
+ */
+ if (bacmp(&dev->rpa, BDADDR_ANY)) {
+ addr = &dev->rpa;
+ addr_type = dev->rpa_type;
+ } else {
+ addr = &dev->bdaddr;
+ addr_type = dev->bdaddr_type;
+ }
+
+ gatt_device_found_cb(addr, addr_type, rssi, data_len, data,
+ discoverable, dev->le_bonded);
}
if (!dev->bredr_paired && !dev->le_paired)
DBG("new IRK for %s, RPA %s", dst, rpa);
- /* TODO: handle new Identity to RPA mapping */
- dev = find_device(&addr->bdaddr);
- if (!dev)
- return;
+ if (!bacmp(&ev->rpa, BDADDR_ANY)) {
+ dev = find_device(&addr->bdaddr);
+ if (!dev)
+ return;
+ } else {
+ dev = find_device(&addr->bdaddr);
+
+ if (dev && dev->bredr_paired) {
+ bacpy(&dev->rpa, &addr->bdaddr);
+ dev->rpa_type = addr->type;
+
+ /* TODO merge properties ie. UUIDs */
+ } else {
+ dev = find_device(&ev->rpa);
+ if (!dev)
+ return;
+
+ /* don't leave garbage in cache file */
+ remove_device_info(dev, CACHE_FILE);
+
+ /*
+ * RPA resolution is transparent for Android Framework
+ * ie. device is still access by RPA so it need to be
+ * keep. After bluetoothd restart device is advertised
+ * to Android with IDA and RPA is not set.
+ */
+ bacpy(&dev->rpa, &dev->bdaddr);
+ dev->rpa_type = dev->bdaddr_type;
+
+ bacpy(&dev->bdaddr, &addr->bdaddr);
+ dev->bdaddr_type = addr->type;
+ }
+ }
+
+ update_device_state(dev, ev->key.addr.type, HAL_STATUS_SUCCESS, false,
+ true, !!ev->store_hint);
if (ev->store_hint)
store_irk(dev, ev->key.val);