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