diff options
-rw-r--r-- | src/device.c | 122 | ||||
-rw-r--r-- | 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); |