From d9294d644930c88c875b35b9efa10beb0854c13b Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 21 Feb 2014 18:04:26 +0200 Subject: [PATCH] core: Add support for merging duplicate device object data --- src/adapter.c | 14 ++++++++--- src/device.c | 65 ++++++++++++++++++++++++++++++--------------------- src/device.h | 1 + 3 files changed, 50 insertions(+), 30 deletions(-) diff --git a/src/adapter.c b/src/adapter.c index bb2c017c4..146d141be 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -5662,7 +5662,7 @@ static void new_irk_callback(uint16_t index, uint16_t length, const struct mgmt_addr_info *addr = &ev->irk.addr; const struct mgmt_irk_info *irk = &ev->irk; struct btd_adapter *adapter = user_data; - struct btd_device *device; + struct btd_device *device, *duplicate; bool persistent; char dst[18], rpa[18]; @@ -5676,12 +5676,17 @@ static void new_irk_callback(uint16_t index, uint16_t length, DBG("hci%u new IRK for %s RPA %s", adapter->dev_id, dst, rpa); - if (bacmp(&ev->rpa, BDADDR_ANY)) + if (bacmp(&ev->rpa, BDADDR_ANY)) { device = btd_adapter_get_device(adapter, &ev->rpa, BDADDR_LE_RANDOM); - else + duplicate = btd_adapter_find_device(adapter, &addr->bdaddr); + if (duplicate == device) + duplicate = NULL; + } else { device = btd_adapter_get_device(adapter, &addr->bdaddr, addr->type); + duplicate = NULL; + } if (!device) { error("Unable to get device object for %s", dst); @@ -5690,6 +5695,9 @@ static void new_irk_callback(uint16_t index, uint16_t length, device_update_addr(device, &addr->bdaddr, addr->type); + if (duplicate) + device_merge_duplicate(device, duplicate); + persistent = !!ev->store_hint; if (!persistent) return; diff --git a/src/device.c b/src/device.c index a73ba293c..a52faea6f 100644 --- a/src/device.c +++ b/src/device.c @@ -274,37 +274,13 @@ static GSList *find_service_with_state(GSList *list, static void update_technologies(GKeyFile *file, struct btd_device *dev) { - bool bredr = dev->bredr; - bool le = dev->le; const char *list[2]; - char **old_list; - size_t i, len; - - /* It's theoretically possible that we've known the same - * physical device by its Resolvable Private Address over LE and - * its public address over BR/EDR, thereby creating two - * btd_device objects which still share the same storage. - * Therefore, once merging information into storage we need to - * make sure that we don't clear the other supported technology. - */ - old_list = g_key_file_get_string_list(file, "General", - "SupportedTechnologies", - &len, NULL); - for (i = 0; i < len; i++) { - if (!strcmp(old_list[i], "BR/EDR")) - bredr = true; - else if (!strcmp(old_list[i], "LE")) - le = true; - } - - g_strfreev(old_list); + size_t len = 0; - len = 0; - - if (bredr) + if (dev->bredr) list[len++] = "BR/EDR"; - if (le) { + if (dev->le) { const char *type; if (dev->bdaddr_type == BDADDR_LE_PUBLIC) @@ -2477,6 +2453,41 @@ void device_update_last_seen(struct btd_device *device, uint8_t bdaddr_type) device->le_seen = time(NULL); } +/* It is possible that we have two device objects for the same device in + * case it has first been discovered over BR/EDR and has a private + * address when discovered over LE for the first time. In such a case we + * need to inherit critical values from the duplicate so that we don't + * ovewrite them when writing to storage. The next time bluetoothd + * starts the device will show up as a single instance. + */ +void device_merge_duplicate(struct btd_device *dev, struct btd_device *dup) +{ + GSList *l; + + DBG(""); + + dev->bredr = dup->bredr; + + dev->trusted = dup->trusted; + dev->blocked = dup->blocked; + + for (l = dup->uuids; l; l = g_slist_next(l)) + dev->uuids = g_slist_append(dev->uuids, g_strdup(l->data)); + + if (dev->name[0] == '\0') + strcpy(dev->name, dup->name); + + if (!dev->alias) + dev->alias = g_strdup(dup->alias); + + dev->class = dup->class; + + dev->vendor_src = dup->vendor_src; + dev->vendor = dup->vendor; + dev->product = dup->product; + dev->version = dup->version; +} + uint32_t btd_device_get_class(struct btd_device *device) { return device->class; diff --git a/src/device.h b/src/device.h index 7add01747..d8e4df247 100644 --- a/src/device.h +++ b/src/device.h @@ -42,6 +42,7 @@ void device_update_addr(struct btd_device *device, const bdaddr_t *bdaddr, uint8_t bdaddr_type); void device_set_bredr_support(struct btd_device *device, bool bredr); void device_update_last_seen(struct btd_device *device, uint8_t bdaddr_type); +void device_merge_duplicate(struct btd_device *dev, struct btd_device *dup); uint32_t btd_device_get_class(struct btd_device *device); uint16_t btd_device_get_vendor(struct btd_device *device); uint16_t btd_device_get_vendor_src(struct btd_device *device); -- 2.47.3