From f1c3d8c1fabd801eac34c9069038d3f4cadcb58d Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 7 Nov 2008 15:22:35 -0300 Subject: Add support for device pattern drivers. The support is necessary for driver like serial which should be able to register RFCOMM UUID but was unable to do so as we were only matching the profile itself. --- src/device.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++------------- src/device.h | 2 +- 2 files changed, 96 insertions(+), 28 deletions(-) diff --git a/src/device.c b/src/device.c index 31cd9ca0..cd2cdb96 100644 --- a/src/device.c +++ b/src/device.c @@ -601,50 +601,118 @@ 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) +static GSList *pattern_to_list(sdp_list_t *pattern) +{ + GSList *l = NULL; + + while (pattern) { + char *uuid; + + uuid = bt_uuid2string(pattern->data); + if (!uuid) + continue; + + l = g_slist_append(l, uuid); + + pattern = pattern->next; + } + + return l; +} + +static GSList *device_match_pattern(struct btd_device *device, + const char *pattern, + GSList *profiles) +{ + GSList *l, *uuids = NULL; + GSList *patterns = NULL; + + for (l = profiles; l; l = l->next) { + const char *uuid = l->data; + const sdp_record_t *rec; + + rec = btd_device_get_record(device, uuid); + + if (!rec) + continue; + + patterns = pattern_to_list(rec->pattern); + + if (!g_slist_find_custom(patterns, pattern, + (GCompareFunc) strcasecmp)) + continue; + + uuids = g_slist_append(uuids, l->data); + } + + g_slist_foreach(patterns, (GFunc) g_free, NULL); + g_slist_free(patterns); + + return uuids; +} + +static GSList *device_match_driver(struct btd_device *device, + struct btd_device_driver *driver, + GSList *profiles) { - GSList *list; const char **uuid; + GSList *uuids = NULL; + + for (uuid = driver->uuids; *uuid; uuid++) { + GSList *match; + + /* match profile driver */ + match = g_slist_find_custom(profiles, *uuid, + (GCompareFunc) strcasecmp); + if (match) { + uuids = g_slist_append(uuids, match->data); + continue; + } + + /* match pattern driver */ + match = device_match_pattern(device, *uuid, profiles); + for (; match; match = match->next) + uuids = g_slist_append(uuids, match->data); + } + + return uuids; +} + +void device_probe_drivers(struct btd_device *device, GSList *profiles) +{ + GSList *list; int err; debug("Probe drivers for %s", device->path); for (list = device_drivers; list; list = list->next) { struct btd_device_driver *driver = list->data; - GSList *probe_uuids = NULL; + GSList *probe_uuids; + struct btd_driver_data *driver_data; - for (uuid = driver->uuids; *uuid; uuid++) { - GSList *match; - - match = g_slist_find_custom(uuids, *uuid, - (GCompareFunc) strcasecmp); - if (!match) - continue; - - probe_uuids = g_slist_append(probe_uuids, match->data); - } + probe_uuids = device_match_driver(device, driver, profiles); - if (probe_uuids) { - struct btd_driver_data *driver_data = g_new0(struct btd_driver_data, 1); + if (!probe_uuids) + continue; - err = driver->probe(device, probe_uuids); - if (err < 0) { - error("probe failed with driver %s for device %s", - driver->name, device->path); + driver_data = g_new0(struct btd_driver_data, 1); - g_free(driver_data); - g_slist_free(probe_uuids); - continue; - } + err = driver->probe(device, probe_uuids); + if (err < 0) { + error("probe failed with driver %s for device %s", + driver->name, device->path); - driver_data->driver = driver; - device->drivers = g_slist_append(device->drivers, - driver_data); + 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) { + for (list = profiles; list; list = list->next) { GSList *l = g_slist_find_custom(device->uuids, list->data, (GCompareFunc) strcasecmp); if (l) diff --git a/src/device.h b/src/device.h index c0d3b2bb..a2c04545 100644 --- a/src/device.h +++ b/src/device.h @@ -30,7 +30,7 @@ void device_remove(DBusConnection *conn, struct btd_device *device); gint device_address_cmp(struct btd_device *device, const gchar *address); int device_browse(struct btd_device *device, DBusConnection *conn, DBusMessage *msg, uuid_t *search, gboolean reverse); -void device_probe_drivers(struct btd_device *device, GSList *uuids); +void device_probe_drivers(struct btd_device *device, GSList *profiles); const sdp_record_t *btd_device_get_record(struct btd_device *device, const char *uuid); void btd_device_add_uuid(struct btd_device *device, const char *uuid); -- cgit