diff options
author | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2008-11-07 15:22:35 -0300 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2008-11-07 15:22:35 -0300 |
commit | f1c3d8c1fabd801eac34c9069038d3f4cadcb58d (patch) | |
tree | 5c0d480731c94ec812e5c4c93abff59886d79576 /src/device.c | |
parent | 0dabe8201eac11459010694bca66d6b217936fcb (diff) |
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.
Diffstat (limited to 'src/device.c')
-rw-r--r-- | src/device.c | 122 |
1 files changed, 95 insertions, 27 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) |