diff options
Diffstat (limited to 'src/device.c')
-rw-r--r-- | src/device.c | 78 |
1 files changed, 60 insertions, 18 deletions
diff --git a/src/device.c b/src/device.c index 1e7747d6..3f70e647 100644 --- a/src/device.c +++ b/src/device.c @@ -87,6 +87,8 @@ struct btd_device { /* Whether were creating a security mode 3 connection */ gboolean secmode3; + + sdp_list_t *tmp_records; }; struct browse_req { @@ -616,7 +618,7 @@ gint device_address_cmp(struct btd_device *device, const gchar *address) return strcasecmp(addr, address); } -void device_probe_drivers(struct btd_device *device, GSList *uuids, sdp_list_t *recs) +void device_probe_drivers(struct btd_device *device, GSList *uuids) { GSList *list; const char **uuid; @@ -626,62 +628,70 @@ void device_probe_drivers(struct btd_device *device, GSList *uuids, sdp_list_t * for (list = device_drivers; list; list = list->next) { struct btd_device_driver *driver = list->data; - GSList *records = NULL; + GSList *probe_uuids = NULL; for (uuid = driver->uuids; *uuid; uuid++) { - sdp_record_t *rec; + GSList *match; - if (!g_slist_find_custom(uuids, *uuid, - (GCompareFunc) strcasecmp)) - continue; - - rec = find_record_in_list(recs, *uuid); - if (!rec) + match = g_slist_find_custom(uuids, *uuid, + (GCompareFunc) strcasecmp); + if (!match) continue; - records = g_slist_append(records, rec); + probe_uuids = g_slist_append(probe_uuids, match->data); } - if (records) { + if (probe_uuids) { struct btd_driver_data *driver_data = g_new0(struct btd_driver_data, 1); - err = driver->probe(device, records); + err = driver->probe(device, probe_uuids); if (err < 0) { error("probe failed for driver %s", driver->name); g_free(driver_data); + g_slist_free(probe_uuids); continue; } driver_data->driver = driver; device->drivers = g_slist_append(device->drivers, driver_data); + g_slist_free(probe_uuids); } } for (list = uuids; list; list = list->next) { GSList *l = g_slist_find_custom(device->uuids, list->data, - (GCompareFunc) strcmp); + (GCompareFunc) strcasecmp); if (l) continue; device->uuids = g_slist_insert_sorted(device->uuids, - list->data, (GCompareFunc) strcmp); + list->data, (GCompareFunc) strcasecmp); + } + + if (device->tmp_records) { + sdp_list_free(device->tmp_records, + (sdp_free_func_t) sdp_record_free); + device->tmp_records = NULL; } } -void device_remove_drivers(struct btd_device *device, GSList *uuids, sdp_list_t *recs) +void device_remove_drivers(struct btd_device *device, GSList *uuids) { struct btd_adapter *adapter = device_get_adapter(device); GSList *list, *next; char srcaddr[18], dstaddr[18]; bdaddr_t src; + sdp_list_t *records; adapter_get_address(adapter, &src); ba2str(&src, srcaddr); ba2str(&device->bdaddr, dstaddr); + records = read_records(&src, &device->bdaddr); + debug("Remove drivers for %s", device->path); for (list = device->drivers; list; list = next) { @@ -698,20 +708,29 @@ void device_remove_drivers(struct btd_device *device, GSList *uuids, sdp_list_t (GCompareFunc) strcasecmp)) continue; + debug("UUID %s was removed from device %s", dstaddr); + driver->remove(device); device->drivers = g_slist_remove(device->drivers, driver_data); g_free(driver_data); - rec = find_record_in_list(recs, *uuid); + + rec = find_record_in_list(records, *uuid); if (!rec) continue; delete_record(srcaddr, dstaddr, rec->handle); + + records = sdp_list_remove(records, rec); + sdp_record_free(rec); } } + if (records) + sdp_list_free(records, (sdp_free_func_t) sdp_record_free); + for (list = uuids; list; list = list->next) device->uuids = g_slist_remove(device->uuids, list->data); } @@ -994,13 +1013,19 @@ static void search_cb(sdp_list_t *recs, int err, gpointer user_data) goto proceed; } + if (device->tmp_records && req->records) { + sdp_list_free(device->tmp_records, (sdp_free_func_t) sdp_record_free); + device->tmp_records = req->records; + req->records = NULL; + } + /* Probe matching drivers for services added */ if (req->uuids_added) - device_probe_drivers(device, req->uuids_added, req->records); + device_probe_drivers(device, req->uuids_added); /* Remove drivers for services removed */ if (req->uuids_removed) - device_remove_drivers(device, req->uuids_removed, req->records); + device_remove_drivers(device, req->uuids_removed); /* Propagate services changes */ services_changed(req); @@ -1314,6 +1339,23 @@ int device_set_paired(DBusConnection *conn, struct btd_device *device, return 0; } +const sdp_record_t *btd_device_get_record(struct btd_device *device, + const char *uuid) +{ + bdaddr_t src; + + if (device->tmp_records) + return find_record_in_list(device->tmp_records, uuid); + + adapter_get_address(device->adapter, &src); + + device->tmp_records = read_records(&src, &device->bdaddr); + if (!device->tmp_records) + return NULL; + + return find_record_in_list(device->tmp_records, uuid); +} + int btd_register_device_driver(struct btd_device_driver *driver) { device_drivers = g_slist_append(device_drivers, driver); |