From 4b0ab7e43f4fa555641902b07f2f7ab3821f2b75 Mon Sep 17 00:00:00 2001 From: Alok Barsode Date: Mon, 21 Jul 2008 14:53:56 +0530 Subject: Adding sdp_record list as parameter to probe. Signed-off-by: Alok Barsode --- hcid/adapter.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ hcid/device.c | 57 +++++++++++++++++++++++++++++++++++++++++-------------- hcid/device.h | 4 ++-- 3 files changed, 99 insertions(+), 22 deletions(-) (limited to 'hcid') diff --git a/hcid/adapter.c b/hcid/adapter.c index 7b655fda..2d0d6e21 100644 --- a/hcid/adapter.c +++ b/hcid/adapter.c @@ -74,6 +74,11 @@ static DBusConnection *connection = NULL; +struct record_list { + sdp_list_t *recs; + const gchar *addr; +}; + struct mode_req { struct adapter *adapter; DBusConnection *conn; /* Connection reference */ @@ -2115,24 +2120,67 @@ static int active_conn_append(GSList **list, bdaddr_t *bdaddr, return 0; } +static void create_stored_records_from_keys(char *key, char *value, + void *user_data) +{ + struct record_list *rec_list = user_data; + const gchar *addr = rec_list->addr; + sdp_record_t *rec; + int size, i, len; + uint8_t *pdata; + char tmp[3] = ""; + + if (strstr(key, addr) == NULL) + return; + + size = strlen(value)/2; + pdata = g_malloc0(size); + + for (i = 0; i < size; i++) { + memcpy(tmp, value + (i*2), 2); + pdata[i] = (uint8_t) strtol(tmp, NULL, 16); + } + + rec = sdp_extract_pdu(pdata, &len); + free(pdata); + + rec_list->recs = sdp_list_append(rec_list->recs, rec); +} + static void create_stored_device_from_profiles(char *key, char *value, void *user_data) { + char filename[PATH_MAX + 1]; struct adapter *adapter = user_data; GSList *uuids = bt_string2list(value); struct btd_device *device; + const gchar *src; + struct record_list rec_list; if (g_slist_find_custom(adapter->devices, key, (GCompareFunc) device_address_cmp)) return; device = device_create(connection, adapter, key); - if (device) { - device_set_temporary(device, FALSE); - adapter->devices = g_slist_append(adapter->devices, device); - device_probe_drivers(device, uuids); - g_slist_free(uuids); - } + if (!device) + return; + + device_set_temporary(device, FALSE); + adapter->devices = g_slist_append(adapter->devices, device); + + src = adapter->address; + rec_list.addr = device_get_address(device); + rec_list.recs = NULL; + + create_name(filename, PATH_MAX, STORAGEDIR, src, "sdp"); + textfile_foreach(filename, create_stored_records_from_keys, &rec_list); + + device_probe_drivers(device, uuids, rec_list.recs); + + if (rec_list.recs != NULL) + sdp_list_free(rec_list.recs, (sdp_free_func_t) sdp_record_free); + + g_slist_free(uuids); } static void create_stored_device_from_linkkeys(char *key, char *value, diff --git a/hcid/device.c b/hcid/device.c index 85b469c1..cfbab920 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -572,14 +572,35 @@ gint device_address_cmp(struct btd_device *device, const gchar *address) return strcasecmp(device->address, address); } -static int cmp_by_name(const void *data, const void *user_data) +sdp_record_t *get_record(sdp_list_t *recs, const char *uuid) { - const struct btd_device_driver *dev_driver = data, *driver = user_data; + sdp_list_t *seq; + + for (seq = recs; seq; seq = seq->next) { + sdp_record_t *rec = (sdp_record_t *) seq->data; + sdp_list_t *svcclass = NULL; + char *uuid_str; + + if (sdp_get_service_classes(rec, &svcclass) < 0) + continue; + + /* Extract the uuid */ + uuid_str = bt_uuid2string(svcclass->data); + if (!uuid_str) + continue; - return (strcmp(dev_driver->name, driver->name)); + if (!strcasecmp(uuid_str, uuid)) { + sdp_list_free(svcclass, free); + free(uuid_str); + return rec; + } + sdp_list_free(svcclass, free); + free(uuid_str); + } + return NULL; } -void device_probe_drivers(struct btd_device *device, GSList *uuids) +void device_probe_drivers(struct btd_device *device, GSList *uuids, sdp_list_t *recs) { GSList *list; const char **uuid; @@ -589,21 +610,20 @@ void device_probe_drivers(struct btd_device *device, GSList *uuids) for (list = drivers; list; list = list->next) { struct btd_device_driver *driver = list->data; - gboolean do_probe = FALSE; + GSList *records = NULL; for (uuid = driver->uuids; *uuid; uuid++) { GSList *match = g_slist_find_custom(uuids, *uuid, (GCompareFunc) strcasecmp); if (match) { - do_probe = TRUE; - break; + sdp_record_t *rec = get_record(recs, *uuid); + + records = g_slist_append(records, rec); } } - if (do_probe == TRUE && !g_slist_find_custom(device->drivers, - driver, (GCompareFunc) cmp_by_name)) { - - err = driver->probe(device); + if (records) { + err = driver->probe(device, records); if (err < 0) { error("probe failed for driver %s", driver->name); @@ -620,8 +640,11 @@ void device_probe_drivers(struct btd_device *device, GSList *uuids) list->data, (GCompareFunc) strcmp); } -void device_remove_drivers(struct btd_device *device, GSList *uuids) +void device_remove_drivers(struct btd_device *device, GSList *uuids, sdp_list_t *recs) { + struct adapter *adapter = device_get_adapter(device); + const gchar *src = adapter->address; + const gchar *dst = device_get_address(device); GSList *list; debug("Remove drivers for %s", device->path); @@ -640,6 +663,8 @@ void device_remove_drivers(struct btd_device *device, GSList *uuids) driver->remove(device); device->drivers = g_slist_remove(device->drivers, driver); + sdp_record_t *rec = get_record(recs, *uuid); + delete_record(src, dst, rec->handle); } } @@ -760,6 +785,9 @@ static void services_changed(struct browse_req *req) static void update_services(struct browse_req *req, sdp_list_t *recs) { struct btd_device *device = req->device; + struct adapter *adapter = device_get_adapter(device); + const gchar *src = adapter->address; + const gchar *dst = device_get_address(device); sdp_list_t *seq; for (seq = recs; seq; seq = seq->next) { @@ -773,6 +801,7 @@ static void update_services(struct browse_req *req, sdp_list_t *recs) if (sdp_get_service_classes(rec, &svcclass) < 0) continue; + store_record(src, dst, rec); /* Extract the first element and skip the remainning */ uuid_str = bt_uuid2string(svcclass->data); @@ -846,11 +875,11 @@ probe: /* Probe matching drivers for services added */ if (req->uuids_added) - device_probe_drivers(device, req->uuids_added); + device_probe_drivers(device, req->uuids_added, recs); /* Remove drivers for services removed */ if (req->uuids_removed) - device_remove_drivers(device, req->uuids_removed); + device_remove_drivers(device, req->uuids_removed, recs); /* Store the device's profiles in the filesystem */ store(device); diff --git a/hcid/device.h b/hcid/device.h index 0e6944b3..bbb0846f 100644 --- a/hcid/device.h +++ b/hcid/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); -void device_probe_drivers(struct btd_device *device, GSList *uuids); +void device_probe_drivers(struct btd_device *device, GSList *uuids, sdp_list_t *recs); struct adapter *device_get_adapter(struct btd_device *device); const gchar *device_get_address(struct btd_device *device); const gchar *device_get_path(struct btd_device *device); @@ -48,7 +48,7 @@ uint8_t device_get_auth(struct btd_device *device); struct btd_device_driver { const char *name; const char **uuids; - int (*probe) (struct btd_device *device); + int (*probe) (struct btd_device *device, GSList *records); void (*remove) (struct btd_device *device); }; -- cgit