summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2008-10-09 14:11:16 +0200
committerJohan Hedberg <johan.hedberg@nokia.com>2008-10-09 15:13:28 +0200
commit548026e08bd9b83b3685d515a916e2cf674184f3 (patch)
tree75f707ae2a4b825ae7f60cef44f54a74579e21a0 /src
parent99c24bafe1619e6ace7e89be2ddea2e8f2eaf98f (diff)
Make device driver probe calls take UUID's instead of full records
This is preparation for allowing the device object to be correctly set up even when we don't have the full service records but only the remote UUID's.
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,