summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/adapter.c8
-rw-r--r--src/device.c78
-rw-r--r--src/device.h6
-rw-r--r--src/storage.c22
-rw-r--r--src/storage.h2
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,