diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/adapter.c | 8 | ||||
| -rw-r--r-- | src/device.c | 78 | ||||
| -rw-r--r-- | src/device.h | 6 | ||||
| -rw-r--r-- | src/storage.c | 22 | ||||
| -rw-r--r-- | src/storage.h | 2 | 
5 files changed, 81 insertions, 35 deletions
| diff --git a/src/adapter.c b/src/adapter.c index 1e22b4b3..f983069e 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -2274,7 +2274,6 @@ static void create_stored_device_from_profiles(char *key, char *value,  	struct btd_adapter *adapter = user_data;  	GSList *uuids = bt_string2list(value);  	struct btd_device *device; -	sdp_list_t *records;  	bdaddr_t dst;  	char srcaddr[18], dstaddr[18]; @@ -2294,12 +2293,7 @@ static void create_stored_device_from_profiles(char *key, char *value,  	device_get_address(device, &dst);  	ba2str(&dst, dstaddr); -	records = read_records(srcaddr, dstaddr); - -	device_probe_drivers(device, uuids, records); - -	if (records) -		sdp_list_free(records, (sdp_free_func_t) sdp_record_free); +	device_probe_drivers(device, uuids);  	g_slist_free(uuids);  } diff --git a/src/device.c b/src/device.c index 1e7747d6..3f70e647 100644 --- a/src/device.c +++ b/src/device.c @@ -87,6 +87,8 @@ struct btd_device {  	/* Whether were creating a security mode 3 connection */  	gboolean	secmode3; + +	sdp_list_t	*tmp_records;  };  struct browse_req { @@ -616,7 +618,7 @@ 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, sdp_list_t *recs) +void device_probe_drivers(struct btd_device *device, GSList *uuids)  {  	GSList *list;  	const char **uuid; @@ -626,62 +628,70 @@ void device_probe_drivers(struct btd_device *device, GSList *uuids, sdp_list_t *  	for (list = device_drivers; list; list = list->next) {  		struct btd_device_driver *driver = list->data; -		GSList *records = NULL; +		GSList *probe_uuids = NULL;  		for (uuid = driver->uuids; *uuid; uuid++) { -			sdp_record_t *rec; +			GSList *match; -			if (!g_slist_find_custom(uuids, *uuid, -					(GCompareFunc) strcasecmp)) -				continue; - -			rec = find_record_in_list(recs, *uuid); -			if (!rec) +			match = g_slist_find_custom(uuids, *uuid, +							(GCompareFunc) strcasecmp); +			if (!match)  				continue; -			records = g_slist_append(records, rec); +			probe_uuids = g_slist_append(probe_uuids, match->data);  		} -		if (records) { +		if (probe_uuids) {  			struct btd_driver_data *driver_data = g_new0(struct btd_driver_data, 1); -			err = driver->probe(device, records); +			err = driver->probe(device, probe_uuids);  			if (err < 0) {  				error("probe failed for driver %s",  							driver->name);  				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) {  		GSList *l = g_slist_find_custom(device->uuids, list->data, -							(GCompareFunc) strcmp); +							(GCompareFunc) strcasecmp);  		if (l)  			continue;  		device->uuids = g_slist_insert_sorted(device->uuids, -					list->data, (GCompareFunc) strcmp); +					list->data, (GCompareFunc) strcasecmp); +	} + +	if (device->tmp_records) { +		sdp_list_free(device->tmp_records, +				(sdp_free_func_t) sdp_record_free); +		device->tmp_records = NULL;  	}  } -void device_remove_drivers(struct btd_device *device, GSList *uuids, sdp_list_t *recs) +void device_remove_drivers(struct btd_device *device, GSList *uuids)  {  	struct btd_adapter *adapter = device_get_adapter(device);  	GSList *list, *next;  	char srcaddr[18], dstaddr[18];  	bdaddr_t src; +	sdp_list_t *records;  	adapter_get_address(adapter, &src);  	ba2str(&src, srcaddr);  	ba2str(&device->bdaddr, dstaddr); +	records = read_records(&src, &device->bdaddr); +  	debug("Remove drivers for %s", device->path);  	for (list = device->drivers; list; list = next) { @@ -698,20 +708,29 @@ void device_remove_drivers(struct btd_device *device, GSList *uuids, sdp_list_t  					(GCompareFunc) strcasecmp))  				continue; +			debug("UUID %s was removed from device %s", dstaddr); +  			driver->remove(device);  			device->drivers = g_slist_remove(device->drivers,  								driver_data);  			g_free(driver_data); -			rec = find_record_in_list(recs, *uuid); + +			rec = find_record_in_list(records, *uuid);  			if (!rec)  				continue;  			delete_record(srcaddr, dstaddr, rec->handle); + +			records = sdp_list_remove(records, rec); +			sdp_record_free(rec);  		}  	} +	if (records) +		sdp_list_free(records, (sdp_free_func_t) sdp_record_free); +  	for (list = uuids; list; list = list->next)  		device->uuids = g_slist_remove(device->uuids, list->data);  } @@ -994,13 +1013,19 @@ static void search_cb(sdp_list_t *recs, int err, gpointer user_data)  		goto proceed;  	} +	if (device->tmp_records && req->records) { +		sdp_list_free(device->tmp_records, (sdp_free_func_t) sdp_record_free); +		device->tmp_records = req->records; +		req->records = NULL; +	} +  	/* Probe matching drivers for services added */  	if (req->uuids_added) -		device_probe_drivers(device, req->uuids_added, req->records); +		device_probe_drivers(device, req->uuids_added);  	/* Remove drivers for services removed */  	if (req->uuids_removed) -		device_remove_drivers(device, req->uuids_removed, req->records); +		device_remove_drivers(device, req->uuids_removed);  	/* Propagate services changes */  	services_changed(req); @@ -1314,6 +1339,23 @@ int device_set_paired(DBusConnection *conn, struct btd_device *device,  	return 0;  } +const sdp_record_t *btd_device_get_record(struct btd_device *device, +						const char *uuid) +{ +	bdaddr_t src; + +	if (device->tmp_records) +		return find_record_in_list(device->tmp_records, uuid); + +	adapter_get_address(device->adapter, &src); + +	device->tmp_records = read_records(&src, &device->bdaddr); +	if (!device->tmp_records) +		return NULL; + +	return find_record_in_list(device->tmp_records, uuid); +} +  int btd_register_device_driver(struct btd_device_driver *driver)  {  	device_drivers = g_slist_append(device_drivers, driver); diff --git a/src/device.h b/src/device.h index a1fa15ab..e0d334f6 100644 --- a/src/device.h +++ b/src/device.h @@ -30,7 +30,9 @@ 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, sdp_list_t *recs); +void device_probe_drivers(struct btd_device *device, GSList *uuids); +const sdp_record_t *btd_device_get_record(struct btd_device *device, +						const char *uuid);  struct btd_adapter *device_get_adapter(struct btd_device *device);  void device_get_address(struct btd_device *adapter, bdaddr_t *bdaddr);  const gchar *device_get_path(struct btd_device *device); @@ -54,7 +56,7 @@ void device_set_secmode3_conn(struct btd_device *device, gboolean enable);  struct btd_device_driver {  	const char *name;  	const char **uuids; -	int (*probe) (struct btd_device *device, GSList *records); +	int (*probe) (struct btd_device *device, GSList *uuids);  	void (*remove) (struct btd_device *device);  }; diff --git a/src/storage.c b/src/storage.c index d048ddb4..d99fb33c 100644 --- a/src/storage.c +++ b/src/storage.c @@ -845,15 +845,19 @@ static void create_stored_records_from_keys(char *key, char *value,  	rec_list->recs = sdp_list_append(rec_list->recs, rec);  } -sdp_list_t *read_records(const gchar *src, const gchar *dst) +sdp_list_t *read_records(bdaddr_t *src, bdaddr_t *dst)  {  	char filename[PATH_MAX + 1];  	struct record_list rec_list; +	char srcaddr[18], dstaddr[18]; -	rec_list.addr = dst; +	ba2str(src, srcaddr); +	ba2str(dst, dstaddr); + +	rec_list.addr = dstaddr;  	rec_list.recs = NULL; -	create_name(filename, PATH_MAX, STORAGEDIR, src, "sdp"); +	create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "sdp");  	textfile_foreach(filename, create_stored_records_from_keys, &rec_list);  	return rec_list.recs; @@ -952,16 +956,17 @@ static int read_device_id_from_did(const gchar *src, const gchar *dst,  	return 0;  } -int read_device_id(const gchar *src, const gchar *dst, +int read_device_id(const gchar *srcaddr, const gchar *dstaddr,  					uint16_t *source, uint16_t *vendor,  					uint16_t *product, uint16_t *version)  {  	uint16_t lsource, lvendor, lproduct, lversion;  	sdp_list_t *recs;  	sdp_record_t *rec; +	bdaddr_t src, dst;  	int err; -	err = read_device_id_from_did(src, dst, &lsource, +	err = read_device_id_from_did(srcaddr, dstaddr, &lsource,  						vendor, product, version);  	if (!err) {  		if (lsource == 0xffff) @@ -970,7 +975,10 @@ int read_device_id(const gchar *src, const gchar *dst,  		return err;  	} -	recs = read_records(src, dst); +	str2ba(srcaddr, &src); +	str2ba(dstaddr, &dst); + +	recs = read_records(&src, &dst);  	rec = find_record_in_list(recs, PNP_UUID);  	if (rec) { @@ -1004,7 +1012,7 @@ int read_device_id(const gchar *src, const gchar *dst,  		lversion = 0x0000;  	} -	store_device_id(src, dst, lsource, lvendor, lproduct, lversion); +	store_device_id(srcaddr, dstaddr, lsource, lvendor, lproduct, lversion);  	if (err)  		return err; diff --git a/src/storage.h b/src/storage.h index d6008a40..bff36a7c 100644 --- a/src/storage.h +++ b/src/storage.h @@ -59,7 +59,7 @@ int delete_entry(bdaddr_t *src, const char *storage, const char *key);  int store_record(const gchar *src, const gchar *dst, sdp_record_t *rec);  sdp_record_t *fetch_record(const gchar *src, const gchar *dst, const uint32_t handle);  int delete_record(const gchar *src, const gchar *dst, const uint32_t handle); -sdp_list_t *read_records(const gchar *src, const gchar *dst); +sdp_list_t *read_records(bdaddr_t *src, bdaddr_t *dst);  sdp_record_t *find_record_in_list(sdp_list_t *recs, const char *uuid);  int store_device_id(const gchar *src, const gchar *dst,  				const uint16_t source, const uint16_t vendor, | 
