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 | |
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')
-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); |