summaryrefslogtreecommitdiffstats
path: root/src/device.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2008-10-09 14:11:16 +0200
committerJohan Hedberg <johan.hedberg@nokia.com>2008-10-09 15:13:28 +0200
commit548026e08bd9b83b3685d515a916e2cf674184f3 (patch)
tree75f707ae2a4b825ae7f60cef44f54a74579e21a0 /src/device.c
parent99c24bafe1619e6ace7e89be2ddea2e8f2eaf98f (diff)
Make device driver probe calls take UUID's instead of full records
This is preparation for allowing the device object to be correctly set up even when we don't have the full service records but only the remote UUID's.
Diffstat (limited to 'src/device.c')
-rw-r--r--src/device.c78
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);