summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2008-11-07 15:22:35 -0300
committerLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2008-11-07 15:22:35 -0300
commitf1c3d8c1fabd801eac34c9069038d3f4cadcb58d (patch)
tree5c0d480731c94ec812e5c4c93abff59886d79576 /src
parent0dabe8201eac11459010694bca66d6b217936fcb (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.c122
-rw-r--r--src/device.h2
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);