Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH v2 08/15] adapter: Convert device sdp file
From: Frédéric Danis @ 2012-12-13 20:39 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1355431170-12897-1-git-send-email-frederic.danis@linux.intel.com>

Save SDP records in device device file located in SDP directory.

Parse "sdp" file to retrieve services, i.e. sdp records with
attribute uuid.
Create device attributes file based on this.
---
 src/adapter.c |  171 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 171 insertions(+)

diff --git a/src/adapter.c b/src/adapter.c
index 241c6c8..02d54a3 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2604,6 +2604,164 @@ static void convert_file(char *file, char *address,
 	free(str);
 }
 
+static gboolean record_has_uuid(const sdp_record_t *rec,
+				const char *profile_uuid)
+{
+	sdp_list_t *pat;
+
+	for (pat = rec->pattern; pat != NULL; pat = pat->next) {
+		char *uuid;
+		int ret;
+
+		uuid = bt_uuid2string(pat->data);
+		if (!uuid)
+			continue;
+
+		ret = strcasecmp(uuid, profile_uuid);
+
+		g_free(uuid);
+
+		if (ret == 0)
+			return TRUE;
+	}
+
+	return FALSE;
+}
+
+static void store_attribute_uuid(GKeyFile *key_file, uint16_t start,
+					char *att_uuid, uuid_t uuid)
+{
+	char handle[6], uuid_str[33];
+	int i;
+
+	switch (uuid.type) {
+	case SDP_UUID16:
+		sprintf(uuid_str, "%4.4X", uuid.value.uuid16);
+		break;
+	case SDP_UUID32:
+		sprintf(uuid_str, "%8.8X", uuid.value.uuid32);
+		break;
+	case SDP_UUID128:
+		for (i = 0; i < 16; i++)
+			sprintf(uuid_str + (i * 2), "%2.2X",
+					uuid.value.uuid128.data[i]);
+		break;
+	default:
+		uuid_str[0] = '\0';
+	}
+
+	sprintf(handle, "%hu", start);
+	g_key_file_set_string(key_file, handle, "UUID", att_uuid);
+	g_key_file_set_string(key_file, handle, "Value", uuid_str);
+}
+
+static void store_sdp_record(char *local, char *peer, int handle, char *value)
+{
+	char filename[PATH_MAX + 1];
+	GKeyFile *key_file;
+	char handle_str[11];
+	char *data;
+	gsize length = 0;
+
+	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
+	filename[PATH_MAX] = '\0';
+
+	key_file = g_key_file_new();
+	g_key_file_load_from_file(key_file, filename, 0, NULL);
+
+	sprintf(handle_str, "0x%8.8X", handle);
+	g_key_file_set_string(key_file, "ServiceRecords", handle_str, value);
+
+	data = g_key_file_to_data(key_file, &length, NULL);
+	if (length > 0) {
+		create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+		g_file_set_contents(filename, data, length, NULL);
+	}
+
+	g_free(data);
+
+	g_key_file_free(key_file);
+}
+
+static void convert_sdp_entry(char *key, char *value, void *user_data)
+{
+	char *src_addr = user_data;
+	char dst_addr[18];
+	char type = BDADDR_BREDR;
+	int handle, ret;
+	char filename[PATH_MAX + 1];
+	GKeyFile *key_file;
+	struct stat st;
+	sdp_record_t *rec;
+	uuid_t uuid;
+	char *att_uuid, *prim_uuid;
+	uint16_t start = 0, end = 0, psm = 0;
+	int err;
+	char *data;
+	gsize length = 0;
+
+	ret = sscanf(key, "%17s#%hhu#%08X", dst_addr, &type, &handle);
+	if (ret < 3) {
+		ret = sscanf(key, "%17s#%08X", dst_addr, &handle);
+		if (ret < 2)
+			return;
+	}
+
+	if (bachk(dst_addr) != 0)
+		return;
+
+	/* Check if the device directory has been created as records should
+	 * only be converted for known devices */
+	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s", src_addr, dst_addr);
+	filename[PATH_MAX] = '\0';
+
+	err = stat(filename, &st);
+	if (err || !S_ISDIR(st.st_mode))
+		return;
+
+	/* store device records in cache */
+	store_sdp_record(src_addr, dst_addr, handle, value);
+
+	/* Retrieve device record and check if there is an
+	 * attribute entry in it */
+	sdp_uuid16_create(&uuid, ATT_UUID);
+	att_uuid = bt_uuid2string(&uuid);
+
+	sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
+	prim_uuid = bt_uuid2string(&uuid);
+
+	rec = record_from_string(value);
+
+	if (record_has_uuid(rec, att_uuid))
+		goto failed;
+
+	if (!gatt_parse_record(rec, &uuid, &psm, &start, &end))
+		goto failed;
+
+	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/attributes", src_addr,
+								dst_addr);
+	filename[PATH_MAX] = '\0';
+
+	key_file = g_key_file_new();
+	g_key_file_load_from_file(key_file, filename, 0, NULL);
+
+	store_attribute_uuid(key_file, start, prim_uuid, uuid);
+
+	data = g_key_file_to_data(key_file, &length, NULL);
+	if (length > 0) {
+		create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+		g_file_set_contents(filename, data, length, NULL);
+	}
+
+	g_free(data);
+	g_key_file_free(key_file);
+
+failed:
+	sdp_record_free(rec);
+	g_free(prim_uuid);
+	g_free(att_uuid);
+}
+
 static void convert_device_storage(struct btd_adapter *adapter)
 {
 	char filename[PATH_MAX + 1];
@@ -2648,6 +2806,19 @@ static void convert_device_storage(struct btd_adapter *adapter)
 
 	/* Convert device ids */
 	convert_file("did", address, convert_did_entry, FALSE);
+
+	/* Convert sdp */
+	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/sdp", address);
+	filename[PATH_MAX] = '\0';
+
+	str = textfile_get(filename, "converted");
+	if (str && strcmp(str, "yes") == 0) {
+		DBG("Legacy %s file already converted", filename);
+	} else {
+		textfile_foreach(filename, convert_sdp_entry, address);
+		textfile_put(filename, "converted", "yes");
+	}
+	free(str);
 }
 
 static void convert_config(struct btd_adapter *adapter, const char *filename,
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 07/15] doc: Update Settings-storage for SDP records
From: Frédéric Danis @ 2012-12-13 20:39 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1355431170-12897-1-git-send-email-frederic.danis@linux.intel.com>

SDP records shouls be saved in device file located in cache
directory, as we cannot guarantee that this info is available
always and profiles should work even if the info is not there.
---
 doc/settings-storage.txt |   14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/doc/settings-storage.txt b/doc/settings-storage.txt
index a43b7af..792c899 100644
--- a/doc/settings-storage.txt
+++ b/doc/settings-storage.txt
@@ -115,13 +115,23 @@ Sample:
 Cache directory file format
 ============================
 
-Each file, named by remote device address, contains one [General] group.
-This general group contains:
+Each file, named by remote device address, may includes multiple groups
+(General and ServiceRecords).
+
+In ServiceRecords, SDP records are stored using their handle as key
+(hexadecimal format).
+
+[General] group contains:
 
   Name		String		Remote device friendly name
 
   ShortName	String		Remote device shortened name
 
+[ServiceRecords] group contains
+
+  <0x...>	String		SDP record as hexadecimal encoded
+				string
+
 Info file format
 ================
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 06/15] device: Delete storage device recursively
From: Frédéric Danis @ 2012-12-13 20:39 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1355431170-12897-1-git-send-email-frederic.danis@linux.intel.com>

Device storage directory may contain multiple files like info or
attributes but also files stored by plug-ins or profiles,
so completely delete directory.
---
 src/device.c |   36 ++++++++++++++++++++++++++++++------
 1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/src/device.c b/src/device.c
index 42a7c65..36bf9bc 100644
--- a/src/device.c
+++ b/src/device.c
@@ -34,6 +34,7 @@
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <errno.h>
+#include <dirent.h>
 
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/uuid.h>
@@ -2031,6 +2032,34 @@ uint16_t btd_device_get_version(struct btd_device *device)
 	return device->version;
 }
 
+static void delete_folder_tree(const char *dirname)
+{
+	DIR *dir;
+	struct dirent *entry;
+	char filename[PATH_MAX + 1];
+
+	dir = opendir(dirname);
+	if (dir == NULL)
+		return;
+
+	while ((entry = readdir(dir)) != NULL) {
+		if (g_str_equal(entry->d_name, ".") ||
+				g_str_equal(entry->d_name, ".."))
+			continue;
+
+		snprintf(filename, PATH_MAX, "%s/%s", dirname, entry->d_name);
+		filename[PATH_MAX] = '\0';
+
+		if (entry->d_type == DT_DIR)
+			delete_folder_tree(filename);
+		else
+			unlink(filename);
+	}
+	closedir(dir);
+
+	rmdir(dirname);
+}
+
 static void device_remove_stored(struct btd_device *device)
 {
 	const bdaddr_t *src = adapter_get_address(device->adapter);
@@ -2062,15 +2091,10 @@ static void device_remove_stored(struct btd_device *device)
 	ba2str(src, adapter_addr);
 	ba2str(&device->bdaddr, device_addr);
 
-	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", adapter_addr,
-			device_addr);
-	filename[PATH_MAX] = '\0';
-	remove(filename);
-
 	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s", adapter_addr,
 			device_addr);
 	filename[PATH_MAX] = '\0';
-	remove(filename);
+	delete_folder_tree(filename);
 }
 
 void device_remove(struct btd_device *device, gboolean remove_stored)
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 05/15] adapter: Probe profiles after device creation
From: Frédéric Danis @ 2012-12-13 20:39 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1355431170-12897-1-git-send-email-frederic.danis@linux.intel.com>

---
 src/adapter.c |   40 ++++------------------------------------
 1 file changed, 4 insertions(+), 36 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 3bb1ea6..241c6c8 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1628,38 +1628,6 @@ static const GDBusPropertyTable adapter_properties[] = {
 	{ }
 };
 
-static void create_stored_device_from_profiles(char *key, char *value,
-						void *user_data)
-{
-	char address[18];
-	uint8_t bdaddr_type;
-	struct btd_adapter *adapter = user_data;
-	GSList *list, *uuids = bt_string2list(value);
-	struct btd_device *device;
-
-	if (sscanf(key, "%17s#%hhu", address, &bdaddr_type) < 2)
-		bdaddr_type = BDADDR_BREDR;
-
-	if (g_slist_find_custom(adapter->devices,
-				address, (GCompareFunc) device_address_cmp))
-		return;
-
-	device = device_create(adapter, address, bdaddr_type);
-	if (!device)
-		return;
-
-	device_set_temporary(device, FALSE);
-	adapter->devices = g_slist_append(adapter->devices, device);
-
-	list = device_services_from_record(device, uuids);
-	if (list)
-		device_register_primaries(device, list, ATT_PSM);
-
-	device_probe_profiles(device, uuids);
-
-	g_slist_free_full(uuids, g_free);
-}
-
 struct adapter_keys {
 	struct btd_adapter *adapter;
 	GSList *keys;
@@ -1843,10 +1811,6 @@ static void load_devices(struct btd_adapter *adapter)
 
 	ba2str(&adapter->bdaddr, srcaddr);
 
-	create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "profiles");
-	textfile_foreach(filename, create_stored_device_from_profiles,
-								adapter);
-
 	create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "primaries");
 	textfile_foreach(filename, create_stored_device_from_primaries,
 								adapter);
@@ -1900,6 +1864,10 @@ static void load_devices(struct btd_adapter *adapter)
 		device_set_temporary(device, FALSE);
 		adapter->devices = g_slist_append(adapter->devices, device);
 
+		l = device_get_uuids(device);
+		if (l)
+			device_probe_profiles(device, l);
+
 device_exist:
 		if (key_info || ltk_info) {
 			device_set_paired(device, TRUE);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 04/15] device: Load profiles from storage
From: Frédéric Danis @ 2012-12-13 20:39 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1355431170-12897-1-git-send-email-frederic.danis@linux.intel.com>

Add device_get_uuids() to retrieve UUIDs list.
It will allow to call device_probe_profiles() from
load_devices() of adapter.c after device creation.

Remove write_device_profiles from storage.[ch].
---
 src/device.c  |   89 ++++++++++++++++++++++++++++++---------------------------
 src/device.h  |    1 +
 src/storage.c |   18 ------------
 src/storage.h |    2 --
 4 files changed, 48 insertions(+), 62 deletions(-)

diff --git a/src/device.c b/src/device.c
index e07e7b8..42a7c65 100644
--- a/src/device.c
+++ b/src/device.c
@@ -216,6 +216,7 @@ static gboolean store_device_info_cb(gpointer user_data)
 	char device_addr[18];
 	char *str;
 	char class[9];
+	gchar **uuids = NULL;
 	gsize length = 0;
 
 	device->store_id = 0;
@@ -279,6 +280,19 @@ static gboolean store_device_info_cb(gpointer user_data)
 	g_key_file_set_boolean(key_file, "General", "Blocked",
 							device->blocked);
 
+	if (device->uuids) {
+		GSList *l;
+		int i;
+
+		uuids = g_new0(gchar *, g_slist_length(device->uuids) + 1);
+		for (i = 0, l = device->uuids; l; l = g_slist_next(l), i++)
+			uuids[i] = l->data;
+		g_key_file_set_string_list(key_file, "General", "Profiles",
+						(const gchar **)uuids, i);
+	} else {
+		g_key_file_remove_key(key_file, "General", "Profiles", NULL);
+	}
+
 	if (device->vendor_src) {
 		g_key_file_set_integer(key_file, "DeviceID", "Source",
 					device->vendor_src);
@@ -299,6 +313,7 @@ static gboolean store_device_info_cb(gpointer user_data)
 	g_free(str);
 
 	g_key_file_free(key_file);
+	g_free(uuids);
 
 	return FALSE;
 }
@@ -1740,6 +1755,7 @@ static void load_info(struct btd_device *device, const gchar *local,
 	char *str;
 	gboolean store_needed = FALSE;
 	gboolean blocked;
+	gchar **uuids;
 	int source, vendor, product, version;
 	char **techno, **t;
 	gboolean bredr = FALSE;
@@ -1819,6 +1835,27 @@ next:
 	if (blocked)
 		device_block(device, FALSE);
 
+	/* Load device profile list */
+	uuids = g_key_file_get_string_list(key_file, "General", "Profiles",
+						NULL, NULL);
+	if (uuids) {
+		gchar **uuid;
+
+		for (uuid = uuids; *uuid; uuid++) {
+			GSList *match;
+
+			match = g_slist_find_custom(device->uuids, *uuid,
+							bt_uuid_strcmp);
+			if (match)
+				continue;
+
+			device->uuids = g_slist_insert_sorted(device->uuids,
+								g_strdup(*uuid),
+								bt_uuid_strcmp);
+		}
+		g_strfreev(uuids);
+	}
+
 	/* Load device id */
 	source = g_key_file_get_integer(key_file, "DeviceID", "Source", NULL);
 	if (source) {
@@ -2124,6 +2161,11 @@ static gboolean record_has_uuid(const sdp_record_t *rec,
 	return FALSE;
 }
 
+GSList *device_get_uuids(struct btd_device *device)
+{
+	return device->uuids;
+}
+
 static GSList *device_match_profile(struct btd_device *device,
 					struct btd_profile *profile,
 					GSList *uuids)
@@ -2263,35 +2305,16 @@ add_uuids:
 static void device_remove_profiles(struct btd_device *device, GSList *uuids)
 {
 	char srcaddr[18], dstaddr[18];
-	sdp_list_t *records;
 	GSList *l, *next;
 
 	ba2str(adapter_get_address(device->adapter), srcaddr);
 	ba2str(&device->bdaddr, dstaddr);
 
-	records = read_records(adapter_get_address(device->adapter),
-							&device->bdaddr);
-
 	DBG("Removing profiles for %s", dstaddr);
 
-	for (l = uuids; l != NULL; l = g_slist_next(l)) {
-		sdp_record_t *rec;
-
-		device->uuids = g_slist_remove(device->uuids, l->data);
-
-		rec = find_record_in_list(records, l->data);
-		if (!rec)
-			continue;
-
-		delete_record(srcaddr, dstaddr, device->bdaddr_type,
-							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);
+	g_slist_free(device->uuids);
+	device->uuids = NULL;
+	store_device_info(device);
 
 	for (l = device->profiles; l != NULL; l = next) {
 		struct btd_profile *profile = l->data;
@@ -2460,24 +2483,6 @@ static void update_gatt_services(struct browse_req *req, GSList *current,
 	g_slist_free(left);
 }
 
-static void store_profiles(struct btd_device *device)
-{
-	struct btd_adapter *adapter = device->adapter;
-	char *str;
-
-	if (!device->uuids) {
-		write_device_profiles(adapter_get_address(adapter),
-					&device->bdaddr, device->bdaddr_type,
-					"");
-		return;
-	}
-
-	str = bt_list2string(device->uuids);
-	write_device_profiles(adapter_get_address(adapter), &device->bdaddr,
-						device->bdaddr_type, str);
-	g_free(str);
-}
-
 GSList *device_services_from_record(struct btd_device *device, GSList *profiles)
 {
 	GSList *l, *prim_list = NULL;
@@ -2567,7 +2572,7 @@ send_reply:
 	device_svc_resolved(device, err);
 
 	if (!device->temporary)
-		store_profiles(device);
+		store_device_info(device);
 
 	browse_request_free(req);
 }
@@ -3820,7 +3825,7 @@ void btd_device_add_uuid(struct btd_device *device, const char *uuid)
 	g_free(new_uuid);
 	g_slist_free(uuid_list);
 
-	store_profiles(device);
+	store_device_info(device);
 	uuids_changed(device);
 }
 
diff --git a/src/device.h b/src/device.h
index a207a4f..9102e60 100644
--- a/src/device.h
+++ b/src/device.h
@@ -42,6 +42,7 @@ uint16_t btd_device_get_version(struct btd_device *device);
 void device_remove(struct btd_device *device, gboolean remove_stored);
 gint device_address_cmp(struct btd_device *device, const gchar *address);
 gint device_bdaddr_cmp(struct btd_device *device, bdaddr_t *bdaddr);
+GSList *device_get_uuids(struct btd_device *device);
 void device_probe_profiles(struct btd_device *device, GSList *profiles);
 const sdp_record_t *btd_device_get_record(struct btd_device *device,
 						const char *uuid);
diff --git a/src/storage.c b/src/storage.c
index 0b9ed2d..74b19c0 100644
--- a/src/storage.c
+++ b/src/storage.c
@@ -245,24 +245,6 @@ ssize_t read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin)
 	return len;
 }
 
-int write_device_profiles(const bdaddr_t *src, const bdaddr_t *dst,
-					uint8_t dst_type, const char *profiles)
-{
-	char filename[PATH_MAX + 1], key[20];
-
-	if (!profiles)
-		return -EINVAL;
-
-	create_filename(filename, PATH_MAX, src, "profiles");
-
-	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-	ba2str(dst, key);
-	sprintf(&key[17], "#%hhu", dst_type);
-
-	return textfile_put(filename, key, profiles);
-}
-
 int delete_entry(const bdaddr_t *src, const char *storage, const bdaddr_t *dst,
 							uint8_t dst_type)
 {
diff --git a/src/storage.h b/src/storage.h
index cb9d836..2e2889d 100644
--- a/src/storage.h
+++ b/src/storage.h
@@ -35,8 +35,6 @@ int read_remote_appearance(const bdaddr_t *local, const bdaddr_t *peer,
 int write_lastused_info(const bdaddr_t *local, const bdaddr_t *peer,
 					uint8_t peer_type, struct tm *tm);
 ssize_t read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin);
-int write_device_profiles(const bdaddr_t *src, const bdaddr_t *dst,
-				uint8_t dst_type, const char *profiles);
 int delete_entry(const bdaddr_t *src, const char *storage, const bdaddr_t *dst,
 							uint8_t dst_type);
 int store_record(const gchar *src, const gchar *dst, uint8_t dst_type,
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 03/15] adapter: Convert device profiles list
From: Frédéric Danis @ 2012-12-13 20:39 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1355431170-12897-1-git-send-email-frederic.danis@linux.intel.com>

---
 src/adapter.c |    9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/adapter.c b/src/adapter.c
index 940cc0a..3bb1ea6 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2553,6 +2553,12 @@ static void convert_ltk_entry(GKeyFile *key_file, void *value)
 	g_free(str);
 }
 
+static void convert_profiles_entry(GKeyFile *key_file, void *value)
+{
+	g_strdelimit(value, " ", ';');
+	g_key_file_set_string(key_file, "General", "Profiles", value);
+}
+
 static void convert_entry(char *key, char *value, void *user_data)
 {
 	struct device_converter *converter = user_data;
@@ -2660,6 +2666,9 @@ static void convert_device_storage(struct btd_adapter *adapter)
 	/* Convert blocked */
 	convert_file("blocked", address, convert_blocked_entry, TRUE);
 
+	/* Convert profiles */
+	convert_file("profiles", address, convert_profiles_entry, TRUE);
+
 	/* Convert linkkeys */
 	convert_file("linkkeys", address, convert_linkkey_entry, TRUE);
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 02/15] device: Add device_create_from_storage() function
From: Frédéric Danis @ 2012-12-13 20:39 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1355431170-12897-1-git-send-email-frederic.danis@linux.intel.com>

This function is used from load_devices() of adapter.c
during bluetoothd start-up to re-load known devices from
storage key file.

device_create() is used to create new devices for which
no storage exists, but until all device load during start-up
has been converted we should continue to call load_info().
---
 src/adapter.c |   10 +++++----
 src/device.c  |   69 ++++++++++++++++++++++++++++++++++++++++++++-------------
 src/device.h  |    2 ++
 3 files changed, 61 insertions(+), 20 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 15db015..940cc0a 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1885,8 +1885,6 @@ static void load_devices(struct btd_adapter *adapter)
 		if (ltk_info)
 			ltks.keys = g_slist_append(ltks.keys, ltk_info);
 
-		g_key_file_free(key_file);
-
 		l = g_slist_find_custom(adapter->devices, entry->d_name,
 					(GCompareFunc) device_address_cmp);
 		if (l) {
@@ -1894,9 +1892,10 @@ static void load_devices(struct btd_adapter *adapter)
 			goto device_exist;
 		}
 
-		device = device_create(adapter, entry->d_name, BDADDR_BREDR);
+		device = device_create_from_storage(adapter, entry->d_name,
+							key_file);
 		if (!device)
-			continue;
+			goto free;
 
 		device_set_temporary(device, FALSE);
 		adapter->devices = g_slist_append(adapter->devices, device);
@@ -1906,6 +1905,9 @@ device_exist:
 			device_set_paired(device, TRUE);
 			device_set_bonded(device, TRUE);
 		}
+
+free:
+		g_key_file_free(key_file);
 	}
 
 	closedir(dir);
diff --git a/src/device.c b/src/device.c
index 515ee61..e07e7b8 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1735,10 +1735,8 @@ failed:
 }
 
 static void load_info(struct btd_device *device, const gchar *local,
-			const gchar *peer)
+			const gchar *peer, GKeyFile *key_file)
 {
-	char filename[PATH_MAX + 1];
-	GKeyFile *key_file;
 	char *str;
 	gboolean store_needed = FALSE;
 	gboolean blocked;
@@ -1747,12 +1745,6 @@ static void load_info(struct btd_device *device, const gchar *local,
 	gboolean bredr = FALSE;
 	gboolean le = FALSE;
 
-	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", local, peer);
-	filename[PATH_MAX] = '\0';
-
-	key_file = g_key_file_new();
-	g_key_file_load_from_file(key_file, filename, 0, NULL);
-
 	/* Load device name from storage info file, if that fails fall back to
 	 * the cache.
 	 */
@@ -1847,18 +1839,14 @@ next:
 
 	if (store_needed)
 		store_device_info(device);
-
-	g_key_file_free(key_file);
 }
 
-struct btd_device *device_create(struct btd_adapter *adapter,
-				const gchar *address, uint8_t bdaddr_type)
+static struct btd_device *device_new(struct btd_adapter *adapter,
+				const gchar *address)
 {
 	gchar *address_up;
 	struct btd_device *device;
 	const gchar *adapter_path = adapter_get_path(adapter);
-	const bdaddr_t *src;
-	char srcaddr[18];
 
 	device = g_try_malloc0(sizeof(struct btd_device));
 	if (device == NULL)
@@ -1882,11 +1870,60 @@ struct btd_device *device_create(struct btd_adapter *adapter,
 
 	str2ba(address, &device->bdaddr);
 	device->adapter = adapter;
+
+	return btd_device_ref(device);
+}
+
+struct btd_device *device_create_from_storage(struct btd_adapter *adapter,
+				const char *address, GKeyFile *key_file)
+{
+	struct btd_device *device;
+	const bdaddr_t *src;
+	char srcaddr[18];
+
+	device = device_new(adapter, address);
+	if (device == NULL)
+		return NULL;
+
+	src = adapter_get_address(adapter);
+	ba2str(src, srcaddr);
+
+	load_info(device, srcaddr, address, key_file);
+
+	return device;
+}
+
+struct btd_device *device_create(struct btd_adapter *adapter,
+				const gchar *address, uint8_t bdaddr_type)
+{
+	struct btd_device *device;
+	const bdaddr_t *src;
+	char srcaddr[18];
+	char filename[PATH_MAX + 1];
+	GKeyFile *key_file;
+
+	device = device_new(adapter, address);
+	if (device == NULL)
+		return NULL;
+
 	device->bdaddr_type = bdaddr_type;
 	src = adapter_get_address(adapter);
 	ba2str(src, srcaddr);
 
-	load_info(device, srcaddr, address);
+	/*TODO: after all device load during start-up has been converted to
+	 * new key file structure, this should be replaced by :
+	 *	str = load_cached_name(device, srcaddr, address);
+	 *	if (str) {
+	 *		strcpy(device->name, str);
+	 *		g_free(str);
+	 *	}
+	 */
+	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", srcaddr,
+			address);
+	key_file = g_key_file_new();
+	g_key_file_load_from_file(key_file, filename, 0, NULL);
+	load_info(device, srcaddr, address, key_file);
+	g_key_file_free(key_file);
 
 	return btd_device_ref(device);
 }
diff --git a/src/device.h b/src/device.h
index b569a71..a207a4f 100644
--- a/src/device.h
+++ b/src/device.h
@@ -28,6 +28,8 @@ struct btd_device;
 
 struct btd_device *device_create(struct btd_adapter *adapter,
 				const char *address, uint8_t bdaddr_type);
+struct btd_device *device_create_from_storage(struct btd_adapter *adapter,
+				const char *address, GKeyFile *key_file);
 
 void device_set_name(struct btd_device *device, const char *name);
 void device_get_name(struct btd_device *device, char *name, size_t len);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 01/15] device: Retrieve device technology from storage
From: Frédéric Danis @ 2012-12-13 20:39 UTC (permalink / raw)
  To: linux-bluetooth

---
 src/device.c |   68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/src/device.c b/src/device.c
index e7aa44d..515ee61 100644
--- a/src/device.c
+++ b/src/device.c
@@ -244,6 +244,35 @@ static gboolean store_device_info_cb(gpointer user_data)
 		g_key_file_remove_key(key_file, "General", "Class", NULL);
 	}
 
+	switch (device->bdaddr_type) {
+	case BDADDR_BREDR:
+		g_key_file_set_string(key_file, "General",
+					"SupportedTechnologies", "BR/EDR");
+		g_key_file_remove_key(key_file, "General",
+					"AddressType", NULL);
+		break;
+
+	case BDADDR_LE_PUBLIC:
+		g_key_file_set_string(key_file, "General",
+					"SupportedTechnologies", "LE");
+		g_key_file_set_string(key_file, "General",
+					"AddressType", "public");
+		break;
+
+	case BDADDR_LE_RANDOM:
+		g_key_file_set_string(key_file, "General",
+					"SupportedTechnologies", "LE");
+		g_key_file_set_string(key_file, "General",
+					"AddressType", "static");
+		break;
+
+	default:
+		g_key_file_remove_key(key_file, "General",
+					"SupportedTechnologies", NULL);
+		g_key_file_remove_key(key_file, "General",
+					"AddressType", NULL);
+	}
+
 	g_key_file_set_boolean(key_file, "General", "Trusted",
 							device->trusted);
 
@@ -1714,6 +1743,9 @@ static void load_info(struct btd_device *device, const gchar *local,
 	gboolean store_needed = FALSE;
 	gboolean blocked;
 	int source, vendor, product, version;
+	char **techno, **t;
+	gboolean bredr = FALSE;
+	gboolean le = FALSE;
 
 	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", local, peer);
 	filename[PATH_MAX] = '\0';
@@ -1750,6 +1782,42 @@ static void load_info(struct btd_device *device, const gchar *local,
 		g_free(str);
 	}
 
+	/* Load device technology */
+	techno = g_key_file_get_string_list(key_file, "General",
+					"SupportedTechnologies", NULL, NULL);
+	if (!techno)
+		goto next;
+
+	for (t = techno; *t; t++) {
+		if (g_str_equal(*t, "BR/EDR"))
+			bredr = TRUE;
+		else if (g_str_equal(*t, "LE"))
+			le = TRUE;
+		else
+			error("Unknown device technology");
+	}
+
+	if (bredr && le) {
+		/* TODO: Add correct type for dual mode device */
+	} else if (bredr) {
+		device->bdaddr_type = BDADDR_BREDR;
+	} else if (le) {
+		str = g_key_file_get_string(key_file, "General",
+						"AddressType", NULL);
+
+		if (str && g_str_equal(str, "public"))
+			device->bdaddr_type = BDADDR_LE_PUBLIC;
+		else if (str && g_str_equal(str, "static"))
+			device->bdaddr_type = BDADDR_LE_RANDOM;
+		else
+			error("Unknown LE device technology");
+
+		g_free(str);
+	}
+
+	g_strfreev(techno);
+
+next:
 	/* Load trust */
 	device->trusted = g_key_file_get_boolean(key_file, "General",
 							"Trusted", NULL);
-- 
1.7.9.5


^ permalink raw reply related

* Re: [PATCH BlueZ 1/2] core: Remove RequestSession and ReleaseSession
From: Johan Hedberg @ 2012-12-13 20:15 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1355428840-27065-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Thu, Dec 13, 2012, Luiz Augusto von Dentz wrote:
> Sessions is no longer used by obexd and the concept is probably not
> relevant anymore since BlueZ 5 don't remember powered state anymore.
> ---
>  doc/adapter-api.txt |  26 +---------
>  src/adapter.c       | 134 ----------------------------------------------------
>  2 files changed, 1 insertion(+), 159 deletions(-)

Both patches have been applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH] mgmt-api: Remove not needed restriction on add/remove OOB data
From: Johan Hedberg @ 2012-12-13 20:15 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1355407852-22047-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Thu, Dec 13, 2012, Szymon Janc wrote:
> Those commands don't send any HCI commands to controller so there is no
> need to restrict them to only powered up controller. This also clarify
> that provided OOB data is persistent over power down/up toggles.
> ---
>  doc/mgmt-api.txt | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)

Applied. Thanks.

Johan

^ permalink raw reply

* [PATCH BlueZ 2/2] core: Remove ConfirmModeChange method
From: Luiz Augusto von Dentz @ 2012-12-13 20:00 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1355428840-27065-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This method was only used by RequestSession which is now removed.
---
 doc/agent-api.txt |  9 ---------
 src/agent.c       | 55 -------------------------------------------------------
 src/agent.h       |  4 ----
 3 files changed, 68 deletions(-)

diff --git a/doc/agent-api.txt b/doc/agent-api.txt
index bd8d8ff..caed7f8 100644
--- a/doc/agent-api.txt
+++ b/doc/agent-api.txt
@@ -119,15 +119,6 @@ Methods		void Release()
 			Possible errors: org.bluez.Error.Rejected
 			                 org.bluez.Error.Canceled
 
-		void ConfirmModeChange(string mode)
-
-			This method gets called if a mode change is requested
-			that needs to be confirmed by the user. An example
-			would be leaving flight mode.
-
-			Possible errors: org.bluez.Error.Rejected
-			                 org.bluez.Error.Canceled
-
 		void Cancel()
 
 			This method gets called to indicate that the agent
diff --git a/src/agent.c b/src/agent.c
index 7ecf19a..ec183c0 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -459,61 +459,6 @@ failed:
 	return err;
 }
 
-static int confirm_mode_change_request_new(struct agent_request *req,
-						const char *mode)
-{
-	struct agent *agent = req->agent;
-
-	req->msg = dbus_message_new_method_call(agent->name, agent->path,
-				"org.bluez.Agent", "ConfirmModeChange");
-	if (req->msg == NULL) {
-		error("Couldn't allocate D-Bus message");
-		return -ENOMEM;
-	}
-
-	dbus_message_append_args(req->msg,
-				DBUS_TYPE_STRING, &mode,
-				DBUS_TYPE_INVALID);
-
-	if (dbus_connection_send_with_reply(btd_get_dbus_connection(), req->msg,
-					&req->call, REQUEST_TIMEOUT) == FALSE) {
-		error("D-Bus send failed");
-		return -EIO;
-	}
-
-	dbus_pending_call_set_notify(req->call, simple_agent_reply, req, NULL);
-	return 0;
-}
-
-int agent_confirm_mode_change(struct agent *agent, const char *new_mode,
-				agent_cb cb, void *user_data,
-				GDestroyNotify destroy)
-{
-	struct agent_request *req;
-	int err;
-
-	if (agent->request)
-		return -EBUSY;
-
-	DBG("Calling Agent.ConfirmModeChange: name=%s, path=%s, mode=%s",
-			agent->name, agent->path, new_mode);
-
-	req = agent_request_new(agent, AGENT_REQUEST_CONFIRM_MODE,
-				cb, user_data, destroy);
-
-	err = confirm_mode_change_request_new(req, new_mode);
-	if (err < 0)
-		goto failed;
-
-	agent->request = req;
-
-	return 0;
-
-failed:
-	agent_request_free(req, FALSE);
-	return err;
-}
-
 static void passkey_reply(DBusPendingCall *call, void *user_data)
 {
 	struct agent_request *req = user_data;
diff --git a/src/agent.h b/src/agent.h
index 2b011b7..3957317 100644
--- a/src/agent.h
+++ b/src/agent.h
@@ -49,10 +49,6 @@ int agent_request_pincode(struct agent *agent, struct btd_device *device,
 				agent_pincode_cb cb, gboolean secure,
 				void *user_data, GDestroyNotify destroy);
 
-int agent_confirm_mode_change(struct agent *agent, const char *new_mode,
-				agent_cb cb, void *user_data,
-				GDestroyNotify destroy);
-
 int agent_request_passkey(struct agent *agent, struct btd_device *device,
 				agent_passkey_cb cb, void *user_data,
 				GDestroyNotify destroy);
-- 
1.7.11.7


^ permalink raw reply related

* [PATCH BlueZ 1/2] core: Remove RequestSession and ReleaseSession
From: Luiz Augusto von Dentz @ 2012-12-13 20:00 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Sessions is no longer used by obexd and the concept is probably not
relevant anymore since BlueZ 5 don't remember powered state anymore.
---
 doc/adapter-api.txt |  26 +---------
 src/adapter.c       | 134 ----------------------------------------------------
 2 files changed, 1 insertion(+), 159 deletions(-)

diff --git a/doc/adapter-api.txt b/doc/adapter-api.txt
index 5d2ea65..1817f7c 100644
--- a/doc/adapter-api.txt
+++ b/doc/adapter-api.txt
@@ -14,31 +14,7 @@ Service		org.bluez
 Interface	org.bluez.Adapter1
 Object path	[variable prefix]/{hci0,hci1,...}
 
-Methods		void RequestSession()
-
-			This method requests a client session that provides
-			operational Bluetooth. A possible mode change must be
-			confirmed by the user via the agent.
-
-			Clients may request multiple sessions. All sessions
-			are released when adapter's mode is changed to off
-			state.
-
-			Possible Errors: org.bluez.Error.Rejected
-
-		void ReleaseSession()
-
-			Release a previously requested session. It sets
-			adapter to the mode in use on the moment of session
-			request.
-
-			Setting the powered or discoverable properties
-			changes adapter's mode persistently, such that session
-			release will not modify it.
-
-			Possible Errors: org.bluez.Error.DoesNotExist
-
-		void StartDiscovery()
+Methods		void StartDiscovery()
 
 			This method starts the device discovery session. This
 			includes an inquiry procedure and remote device name
diff --git a/src/adapter.c b/src/adapter.c
index 0a3297e..d4a03b9 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -339,18 +339,6 @@ static int adapter_set_mode(struct btd_adapter *adapter, uint8_t mode)
 	return err;
 }
 
-static struct session_req *find_session_by_msg(GSList *list, const DBusMessage *msg)
-{
-	for (; list; list = list->next) {
-		struct session_req *req = list->data;
-
-		if (req->msg == msg)
-			return req;
-	}
-
-	return NULL;
-}
-
 static int set_mode(struct btd_adapter *adapter, uint8_t new_mode)
 {
 	int err;
@@ -392,24 +380,6 @@ done:
 	return 0;
 }
 
-static void set_session_pending_mode(struct btd_adapter *adapter,
-					uint8_t new_mode, DBusMessage *msg)
-{
-	struct session_req *req;
-
-	/*
-	 * Schedule the reply to be sent when a mode-change notification
-	 * arrives. The reply will be sent by set_mode_complete().
-	 */
-	req = find_session_by_msg(adapter->mode_sessions, msg);
-	if (req) {
-		adapter->pending_mode = req;
-		session_ref(req);
-	} else
-		adapter->pending_mode = create_session(adapter, msg, new_mode,
-					SESSION_TYPE_MODE_SESSION, NULL);
-}
-
 static void set_discoverable(struct btd_adapter *adapter,
 			gboolean discoverable, GDBusPendingPropertySet id)
 {
@@ -732,45 +702,6 @@ static void session_unref(struct session_req *req)
 	session_free(req);
 }
 
-static void confirm_mode_cb(struct agent *agent, DBusError *derr, void *data)
-{
-	DBusConnection *conn = btd_get_dbus_connection();
-	struct session_req *req = data;
-	int err;
-	DBusMessage *reply;
-
-	req->got_reply = TRUE;
-
-	if (derr && dbus_error_is_set(derr)) {
-		reply = dbus_message_new_error(req->msg, derr->name,
-						derr->message);
-		g_dbus_send_message(conn, reply);
-		session_unref(req);
-		return;
-	}
-
-	err = set_mode(req->adapter, req->mode);
-	if (err >= 0 && req->adapter->mode != req->mode) {
-		set_session_pending_mode(req->adapter, req->mode, req->msg);
-		goto done;
-	}
-
-	if (err < 0)
-		reply = btd_error_failed(req->msg, strerror(-err));
-	else
-		reply = dbus_message_new_method_return(req->msg);
-
-	/*
-	 * Send reply immediately only if there was an error changing mode, or
-	 * change is not needed. Otherwise, reply is sent in
-	 * set_mode_complete.
-	 */
-	g_dbus_send_message(conn, reply);
-
-done:
-	session_unref(req);
-}
-
 static void set_discoverable_timeout(struct btd_adapter *adapter,
 				uint32_t timeout, GDBusPendingPropertySet id)
 {
@@ -1409,67 +1340,6 @@ static gboolean adapter_property_get_uuids(const GDBusPropertyTable *property,
 	return TRUE;
 }
 
-static DBusMessage *request_session(DBusConnection *conn,
-					DBusMessage *msg, void *data)
-{
-	struct btd_adapter *adapter = data;
-	struct session_req *req;
-	const char *sender = dbus_message_get_sender(msg);
-	uint8_t new_mode;
-	int err;
-
-	if (!adapter->agent)
-		return btd_error_agent_not_available(msg);
-
-	if (!adapter->mode_sessions)
-		adapter->global_mode = adapter->mode;
-
-	if (adapter->discoverable)
-		new_mode = MODE_DISCOVERABLE;
-	else
-		new_mode = MODE_CONNECTABLE;
-
-	req = find_session(adapter->mode_sessions, sender);
-	if (req) {
-		session_ref(req);
-		return dbus_message_new_method_return(msg);
-	} else {
-		req = create_session(adapter, msg, new_mode,
-				SESSION_TYPE_MODE_SESSION, session_owner_exit);
-		adapter->mode_sessions = g_slist_append(adapter->mode_sessions,
-							req);
-	}
-
-	/* No need to change mode */
-	if (adapter->mode >= new_mode)
-		return dbus_message_new_method_return(msg);
-
-	err = agent_confirm_mode_change(adapter->agent, mode2str(new_mode),
-					confirm_mode_cb, req, NULL);
-	if (err < 0) {
-		session_unref(req);
-		return btd_error_failed(msg, strerror(-err));
-	}
-
-	return NULL;
-}
-
-static DBusMessage *release_session(DBusConnection *conn,
-					DBusMessage *msg, void *data)
-{
-	struct btd_adapter *adapter = data;
-	struct session_req *req;
-	const char *sender = dbus_message_get_sender(msg);
-
-	req = find_session(adapter->mode_sessions, sender);
-	if (!req)
-		return btd_error_failed(msg, "Invalid Session");
-
-	session_unref(req);
-
-	return dbus_message_new_method_return(msg);
-}
-
 static uint8_t parse_io_capability(const char *capability)
 {
 	if (g_str_equal(capability, ""))
@@ -1584,10 +1454,6 @@ static DBusMessage *unregister_agent(DBusConnection *conn, DBusMessage *msg,
 }
 
 static const GDBusMethodTable adapter_methods[] = {
-	{ GDBUS_ASYNC_METHOD("RequestSession", NULL, NULL,
-			request_session) },
-	{ GDBUS_METHOD("ReleaseSession", NULL, NULL,
-			release_session) },
 	{ GDBUS_METHOD("StartDiscovery", NULL, NULL,
 			adapter_start_discovery) },
 	{ GDBUS_ASYNC_METHOD("StopDiscovery", NULL, NULL,
-- 
1.7.11.7


^ permalink raw reply related

* [PATCH 2/2] Bluetooth: mgmt: Avoid using magic number in status code
From: Szymon Janc @ 2012-12-13 14:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1355407881-22110-1-git-send-email-szymon.janc@tieto.com>

Use MGMT_STATUS_SUCCESS for success return code.

Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
 net/bluetooth/mgmt.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 65f9a2d..8752c55 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2257,7 +2257,7 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
 	if (err < 0)
 		status = MGMT_STATUS_FAILED;
 	else
-		status = 0;
+		status = MGMT_STATUS_SUCCESS;
 
 	err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, status,
 			   &cp->addr, sizeof(cp->addr));
@@ -2281,7 +2281,7 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
 	if (err < 0)
 		status = MGMT_STATUS_INVALID_PARAMS;
 	else
-		status = 0;
+		status = MGMT_STATUS_SUCCESS;
 
 	err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
 			   status, &cp->addr, sizeof(cp->addr));
@@ -2513,7 +2513,7 @@ static int block_device(struct sock *sk, struct hci_dev *hdev, void *data,
 	if (err < 0)
 		status = MGMT_STATUS_FAILED;
 	else
-		status = 0;
+		status = MGMT_STATUS_SUCCESS;
 
 	err = cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE, status,
 			   &cp->addr, sizeof(cp->addr));
@@ -2538,7 +2538,7 @@ static int unblock_device(struct sock *sk, struct hci_dev *hdev, void *data,
 	if (err < 0)
 		status = MGMT_STATUS_INVALID_PARAMS;
 	else
-		status = 0;
+		status = MGMT_STATUS_SUCCESS;
 
 	err = cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE, status,
 			   &cp->addr, sizeof(cp->addr));
-- 
1.8.0


^ permalink raw reply related

* [PATCH 1/2] Bluetooth: mgmt: Remove not needed restriction on add/remove OOB data
From: Szymon Janc @ 2012-12-13 14:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Those commands don't send any HCI commands to controller so there is no
need to restrict them to only powered up controller. This also makes
implementation more consistent as already stored remote OOB data
persist power toggle.

Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
 net/bluetooth/mgmt.c | 17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 5d0ef75..65f9a2d 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2252,13 +2252,6 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
 
 	hci_dev_lock(hdev);
 
-	if (!hdev_is_powered(hdev)) {
-		err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA,
-				   MGMT_STATUS_NOT_POWERED, &cp->addr,
-				   sizeof(cp->addr));
-		goto unlock;
-	}
-
 	err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr, cp->hash,
 				      cp->randomizer);
 	if (err < 0)
@@ -2269,7 +2262,6 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
 	err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, status,
 			   &cp->addr, sizeof(cp->addr));
 
-unlock:
 	hci_dev_unlock(hdev);
 	return err;
 }
@@ -2285,14 +2277,6 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
 
 	hci_dev_lock(hdev);
 
-	if (!hdev_is_powered(hdev)) {
-		err = cmd_complete(sk, hdev->id,
-				   MGMT_OP_REMOVE_REMOTE_OOB_DATA,
-				   MGMT_STATUS_NOT_POWERED, &cp->addr,
-				   sizeof(cp->addr));
-		goto unlock;
-	}
-
 	err = hci_remove_remote_oob_data(hdev, &cp->addr.bdaddr);
 	if (err < 0)
 		status = MGMT_STATUS_INVALID_PARAMS;
@@ -2302,7 +2286,6 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
 	err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
 			   status, &cp->addr, sizeof(cp->addr));
 
-unlock:
 	hci_dev_unlock(hdev);
 	return err;
 }
-- 
1.8.0


^ permalink raw reply related

* [PATCH] mgmt-api: Remove not needed restriction on add/remove OOB data
From: Szymon Janc @ 2012-12-13 14:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Those commands don't send any HCI commands to controller so there is no
need to restrict them to only powered up controller. This also clarify
that provided OOB data is persistent over power down/up toggles.
---
 doc/mgmt-api.txt | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/doc/mgmt-api.txt b/doc/mgmt-api.txt
index 202c055..60f4da4 100644
--- a/doc/mgmt-api.txt
+++ b/doc/mgmt-api.txt
@@ -701,7 +701,7 @@ Add Remote Out Of Band Data Command
 	Return Parameters:	Address (6 Octets)
 				Address_Type (1 Octet)
 
-	This command can only be used when the controller is powered.
+	Provided Out Of Band data is persistent over power down/up toggles.
 
 	This command generates a Command Complete event on success
 	or failure.
@@ -717,8 +717,6 @@ Remove Remote Out Of Band Data Command
 	Return Parameters:	Address (6 Octets)
 				Address_Type (1 Octet)
 
-	This command can only be used when the controller is powered.
-
 	This command generates a Command Complete event on success
 	or failure.
 
-- 
1.8.0


^ permalink raw reply related

* Re: [PATCH BlueZ] build: Remove obexd usb plugin
From: Johan Hedberg @ 2012-12-13 12:27 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1355400231-25205-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Thu, Dec 13, 2012, Luiz Augusto von Dentz wrote:
> This plugin is not longer maintained and used to work only in meego
> times.
> ---
>  Makefile.obexd      |   5 -
>  obexd/plugins/usb.c | 299 ----------------------------------------------------
>  2 files changed, 304 deletions(-)
>  delete mode 100644 obexd/plugins/usb.c

Applied. Thanks.

Johan

^ permalink raw reply

* [PATCH BlueZ] build: Remove obexd usb plugin
From: Luiz Augusto von Dentz @ 2012-12-13 12:03 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This plugin is not longer maintained and used to work only in meego
times.
---
 Makefile.obexd      |   5 -
 obexd/plugins/usb.c | 299 ----------------------------------------------------
 2 files changed, 304 deletions(-)
 delete mode 100644 obexd/plugins/usb.c

diff --git a/Makefile.obexd b/Makefile.obexd
index 9498ac1..e6536bc 100644
--- a/Makefile.obexd
+++ b/Makefile.obexd
@@ -11,11 +11,6 @@ obexd_builtin_sources += obexd/plugins/filesystem.c obexd/plugins/filesystem.h
 obexd_builtin_modules += bluetooth
 obexd_builtin_sources += obexd/plugins/bluetooth.c
 
-if USB
-obexd_builtin_modules += usb
-obexd_builtin_sources += obexd/plugins/usb.c
-endif
-
 if EXPERIMENTAL
 obexd_builtin_modules += pcsuite
 obexd_builtin_sources += obexd/plugins/pcsuite.c
diff --git a/obexd/plugins/usb.c b/obexd/plugins/usb.c
deleted file mode 100644
index 1c3da3e..0000000
--- a/obexd/plugins/usb.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- *
- *  OBEX Server
- *
- *  Copyright (C) 2007-2010  Nokia Corporation
- *  Copyright (C) 2007-2010  Marcel Holtmann <marcel@holtmann.org>
- *
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <termios.h>
-#include <inttypes.h>
-
-#include <glib.h>
-#include <gdbus/gdbus.h>
-
-#include "obexd.h"
-#include "plugin.h"
-#include "server.h"
-#include "obex.h"
-#include "transport.h"
-#include "service.h"
-#include "log.h"
-
-static GIOChannel *usb_io = NULL;
-static guint usb_reconnecting = 0;
-static guint usb_watch = 0;
-static DBusConnection *connection = NULL;
-
-#define USB_RX_MTU 65535
-#define USB_TX_MTU 65535
-#define USB_DEVNODE "/dev/ttyGS0"
-
-static int usb_connect(struct obex_server *server);
-
-static void usb_disconnect(struct obex_server *server)
-{
-	if (usb_reconnecting > 0) {
-		g_source_remove(usb_reconnecting);
-		usb_reconnecting = 0;
-	}
-
-	if (usb_watch > 0) {
-		g_source_remove(usb_watch);
-		usb_watch = 0;
-	}
-
-	/* already disconnected */
-	if (usb_io == NULL)
-		return;
-
-	g_io_channel_shutdown(usb_io, TRUE, NULL);
-	g_io_channel_unref(usb_io);
-	usb_io = NULL;
-	DBG("disconnected");
-}
-
-static gboolean usb_reconnect(void *data)
-{
-	struct obex_server *server = data;
-
-	DBG("reconnecting");
-	usb_reconnecting = 0;
-	usb_connect(server);
-
-	return FALSE;
-}
-
-static gboolean usb_watchdog(GIOChannel *io, GIOCondition cond,
-				void *user_data)
-{
-	struct obex_server *server = user_data;
-
-	usb_watch = 0;
-	usb_disconnect(server);
-
-	if ((cond & G_IO_NVAL) == FALSE)
-		usb_reconnecting = g_idle_add(usb_reconnect, server);
-
-	return FALSE;
-}
-
-static int usb_connect(struct obex_server *server)
-{
-	struct termios options;
-	int fd, err, arg;
-	glong flags;
-
-	if (usb_reconnecting > 0) {
-		g_source_remove(usb_reconnecting);
-		usb_reconnecting = 0;
-	}
-
-	/* already connected */
-	if (usb_io != NULL)
-		return 0;
-
-	fd = open(USB_DEVNODE, O_RDWR | O_NOCTTY);
-	if (fd < 0)
-		return fd;
-
-	flags = fcntl(fd, F_GETFL);
-	fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
-
-	tcgetattr(fd, &options);
-	cfmakeraw(&options);
-	options.c_oflag &= ~ONLCR;
-	tcsetattr(fd, TCSANOW, &options);
-
-	arg = fcntl(fd, F_GETFL);
-	if (arg < 0) {
-		err = -errno;
-		goto failed;
-	}
-
-	arg |= O_NONBLOCK;
-	if (fcntl(fd, F_SETFL, arg) < 0) {
-		err = -errno;
-		goto failed;
-	}
-
-	usb_io = g_io_channel_unix_new(fd);
-	g_io_channel_set_close_on_unref(usb_io, TRUE);
-
-	err = obex_server_new_connection(server, usb_io, USB_TX_MTU,
-							USB_RX_MTU, TRUE);
-	if (err < 0)
-		goto failed;
-
-	usb_watch = g_io_add_watch(usb_io, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-					usb_watchdog, server);
-
-	DBG("Successfully opened %s", USB_DEVNODE);
-
-	return 0;
-
-failed:
-	error("usb: %s (%d)", strerror(-err), -err);
-	if (usb_io == NULL)
-		close(fd);
-	else
-		usb_disconnect(server);
-	return err;
-}
-
-static void sig_usb(int sig)
-{
-}
-
-static void usb_set_mode(struct obex_server *server, const char *mode)
-{
-	DBG("%s", mode);
-
-	if (g_str_equal(mode, "ovi_suite") == TRUE)
-		usb_connect(server);
-	else if (g_str_equal(mode, "USB disconnected") == TRUE)
-		usb_disconnect(server);
-}
-
-static gboolean handle_signal(DBusConnection *connection,
-				DBusMessage *message, void *user_data)
-{
-	struct obex_server *server = user_data;
-	const char *mode;
-
-	dbus_message_get_args(message, NULL,
-				DBUS_TYPE_STRING, &mode,
-				DBUS_TYPE_INVALID);
-
-	usb_set_mode(server, mode);
-
-	return TRUE;
-}
-
-static void usb_stop(void *data)
-{
-	guint id = GPOINTER_TO_UINT(data);
-	g_dbus_remove_watch(connection, id);
-}
-
-static void mode_request_reply(DBusPendingCall *call, void *user_data)
-{
-	struct obex_server *server = user_data;
-	DBusMessage *reply = dbus_pending_call_steal_reply(call);
-	DBusError derr;
-
-	dbus_error_init(&derr);
-	if (dbus_set_error_from_message(&derr, reply)) {
-		error("usb: Replied with an error: %s, %s",
-				derr.name, derr.message);
-		dbus_error_free(&derr);
-	} else {
-		const char *mode;
-		dbus_message_get_args(reply, NULL,
-				DBUS_TYPE_STRING, &mode,
-				DBUS_TYPE_INVALID);
-
-		usb_set_mode(server, mode);
-	}
-
-	dbus_message_unref(reply);
-}
-
-static void *usb_start(struct obex_server *server, int *err)
-{
-	guint id;
-	DBusMessage *msg;
-	DBusPendingCall *call;
-
-	msg = dbus_message_new_method_call("com.meego.usb_moded",
-						"/com/meego/usb_moded",
-						"com.meego.usb_moded",
-						"mode_request");
-
-	if (dbus_connection_send_with_reply(connection,
-					msg, &call, -1) == FALSE) {
-		error("usb: unable to send mode_request");
-		dbus_message_unref(msg);
-		goto fail;
-	}
-
-	dbus_pending_call_set_notify(call, mode_request_reply, server, NULL);
-	dbus_pending_call_unref(call);
-	dbus_message_unref(msg);
-
-	id = g_dbus_add_signal_watch(connection, NULL, NULL,
-					"com.meego.usb_moded",
-					"sig_usb_state_ind",
-					handle_signal, server, NULL);
-
-	if (err != NULL)
-		*err = 0;
-
-	return GUINT_TO_POINTER(id);
-
-fail:
-	if (err != NULL)
-		*err = -1;
-
-	return NULL;
-}
-
-static struct obex_transport_driver driver = {
-	.name = "usb",
-	.service = OBEX_PCSUITE,
-	.start = usb_start,
-	.stop = usb_stop
-};
-
-static int usb_init(void)
-{
-	struct sigaction sa;
-
-	memset(&sa, 0, sizeof(sa));
-	sa.sa_handler = sig_usb;
-	sigaction(SIGUSR1, &sa, NULL);
-	sigaction(SIGHUP, &sa, NULL);
-
-	connection = g_dbus_setup_private(DBUS_BUS_SYSTEM, NULL, NULL);
-	if (connection == NULL)
-		return -EPERM;
-
-	return obex_transport_driver_register(&driver);
-}
-
-static void usb_exit(void)
-{
-	if (connection)
-		dbus_connection_unref(connection);
-
-	obex_transport_driver_unregister(&driver);
-}
-
-OBEX_PLUGIN_DEFINE(usb, usb_init, usb_exit)
-- 
1.7.11.7


^ permalink raw reply related

* Re: [BLE] org.bluez.Device1.Connect() returns org.bluez.Error.NotAvailable
From: Johan Hedberg @ 2012-12-13  7:48 UTC (permalink / raw)
  To: Ting Chou; +Cc: Anderson Lizardo, linux-bluetooth@vger.kernel.org
In-Reply-To: <ADCBF04BB97EBF4AAE65663F8478B61CA99E65AC43@Luna.iaSolution.net>

Hi Ting,

On Thu, Dec 13, 2012, Ting Chou wrote:
> > > I'm not sure if I understand correctly. But do you mean the GCEP you
> > > mentioned above is applied while "reconnecting" to a supported device?
> > 
> > Yes, all GAP connection procedures are applicable for re-connection.
> > There is no "reconnection" procedure as per GAP (as far as I know).
> > But note that each GATT profile can specify reconnection procedures in
> > case of disconnection due to link loss (most of those that I read have
> > this). For instance, in HTP:
> > 
> > "5.2.4 Link Loss Reconnection Procedure
> > When a connection is terminated due to link loss, a Collector should
> > attempt to reconnect to the Thermometer using any of the GAP connection
> > procedures with the parameters in Table 5.2."
> > 
> > This is what BlueZ is doing for profiles implemented internally, except
> > that the parameters we use are not the ones recommended on the profile
> > specs (that could be implemented in future, but for now GCEP uses fixed
> > connection parameters).
> > 
> 
> So I should exercise the D-Bus API like following for LE device:
> 
>   Adapter1.StartDiscovery
>   Device1.Pair
>   ...
>   ...
>   // link loss
>   ...
>   // auto reconnect
>   ...
>   Adapter1.RemoveDevice
> 
> Is my understanding correct?

Yes, except that you should call Adapter1.StopDiscovery before calling
Device1.Pair.

Johan

^ permalink raw reply

* RE: [BLE] org.bluez.Device1.Connect() returns org.bluez.Error.NotAvailable
From: Ting Chou @ 2012-12-13  2:33 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: Johan Hedberg, linux-bluetooth@vger.kernel.org
In-Reply-To: <CAJdJm_PPnSmEV0nmjeka6vLa9qG9-FvZTvhypi9mfVyw+KxH+Q@mail.gmail.com>

Hi Anderson,

> > I'm not sure if I understand correctly. But do you mean the GCEP you
> > mentioned above is applied while "reconnecting" to a supported device?
> 
> Yes, all GAP connection procedures are applicable for re-connection.
> There is no "reconnection" procedure as per GAP (as far as I know).
> But note that each GATT profile can specify reconnection procedures in
> case of disconnection due to link loss (most of those that I read have
> this). For instance, in HTP:
> 
> "5.2.4 Link Loss Reconnection Procedure
> When a connection is terminated due to link loss, a Collector should
> attempt to reconnect to the Thermometer using any of the GAP connection
> procedures with the parameters in Table 5.2."
> 
> This is what BlueZ is doing for profiles implemented internally, except
> that the parameters we use are not the ones recommended on the profile
> specs (that could be implemented in future, but for now GCEP uses fixed
> connection parameters).
> 

So I should exercise the D-Bus API like following for LE device:

  Adapter1.StartDiscovery
  Device1.Pair
  ...
  ...
  // link loss
  ...
  // auto reconnect
  ...
  Adapter1.RemoveDevice

Is my understanding correct?

Thank you,
Ting

^ permalink raw reply

* Re: [RFC 12/16] Bluetooth: Use abstract chan->data in comparison
From: Gustavo Padovan @ 2012-12-12 19:57 UTC (permalink / raw)
  To: Andrei Emeltchenko, linux-bluetooth, Gustavo Padovan
In-Reply-To: <20121212082009.GA7034@aemeltch-MOBL1>

Hi Andrei,

* Andrei Emeltchenko <andrei.emeltchenko.news@gmail.com> [2012-12-12 10:20:11 +0200]:

> Hi Gustavo,
> 
> On Wed, Dec 12, 2012 at 02:13:40AM -0200, Gustavo Padovan wrote:
> > From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> > 
> > If the L2CAP user is l2cap_sock.c chan->data is a pointer to the l2cap
> > socket so chan->sk and chan->data are the same thing. Then we can just
> > compare with chan->data instead.
> > 
> > Non-socket users will have skb->sk = NULL, thus this change does not
> > interfere in other users.
> > 
> > Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> > ---
> >  net/bluetooth/l2cap_core.c | 3 +--
> >  1 file changed, 1 insertion(+), 2 deletions(-)
> > 
> > diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> > index 934ac1b..92936db 100644
> > --- a/net/bluetooth/l2cap_core.c
> > +++ b/net/bluetooth/l2cap_core.c
> > @@ -2682,12 +2682,11 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
> >  	mutex_lock(&conn->chan_lock);
> >  
> >  	list_for_each_entry(chan, &conn->chan_l, list) {
> > -		struct sock *sk = chan->sk;
> >  		if (chan->chan_type != L2CAP_CHAN_RAW)
> >  			continue;
> >  
> >  		/* Don't send frame to the socket it came from */
> > -		if (skb->sk == sk)
> > +		if (skb->sk && skb->sk == chan->data)
> 
> In the other patch you delete chan->sk pointer and then we have only
> chan->data which points to sk. What is the reason for that? This would
> confuse people reading chan->data guessing what the hell is this.
> 
> I really think we can leave chan->sk if it is needed and it is better to
> remove chan->data.

chan->data is the generic data pointer for l2cap users, l2cap_sock.c puts an
struct sock while a2mp.c puts struct amp_mgr there. I'll better add a comment
to struct l2cap_chan saying what it is for instead of re-adding struct sock.

	Gustavo

^ permalink raw reply

* Re: [RFC 04/16] Bluetooth: add l2cap_state_change_and_error()
From: Gustavo Padovan @ 2012-12-12 19:26 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth, Gustavo Padovan
In-Reply-To: <CAJdJm_PMBC8nivsJuYDp-wW5ei1WF7m3SJzh78RScUyQu5ApJQ@mail.gmail.com>

* Anderson Lizardo <anderson.lizardo@openbossa.org> [2012-12-12 09:40:06 -0400]:

> Hi Gustavo,
> 
> On Wed, Dec 12, 2012 at 12:13 AM, Gustavo Padovan <gustavo@padovan.org> wrote:
> > @@ -238,7 +244,7 @@ static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
> >         struct sock *sk = chan->sk;
> >
> >         lock_sock(sk);
> > -       __l2cap_chan_set_err(chan, err);
> > +       chan->ops->state_change(chan, chan->state, 0);
> 
> Why "0" and not "err" ?

Yes, it is "err" here. I fixed both issues you reported.

	Gustavo

^ permalink raw reply

* Re: [PATCH BlueZ 01/11] obexd: Port bluetooth plugin to use external profile support
From: Johan Hedberg @ 2012-12-12 18:55 UTC (permalink / raw)
  To: Mikel Astiz; +Cc: Luiz Augusto von Dentz, linux-bluetooth
In-Reply-To: <CANT-zCWrF=xz-ud=tKbds9Fag5uH+ryLL3ZiQG=APqcZgEq0ug@mail.gmail.com>

Hi Mikel,

On Wed, Dec 12, 2012, Mikel Astiz wrote:
> I'm a bit confused with these recent changes. I haven't been following
> this closely so I guess I'm missing the Big Plan but let me start with
> the basics: both bluetoothd and obexd repositories were merged but I
> believe both daemons are still going to be separate daemons, is this
> correct?
> 
> If yes, it makes sense that obexd makes use of the "external profile"
> infrastructure.
> 
> But in that case, why would we add any obex-specific code into
> bluetoothd? My understanding was that, if a profile is implemented as
> an external profile, the bluetoothd core would not be aware of it.

No, bluetoothd still takes care of SDP record registration,
server/client socket handling, authorization, etc. Some external
profiles (like HFP implemented through oFono) also take part in the
Device.Connect connection procedure (this is particularly important for
HFP since it needs to be the first of the audio profiles to be
connected).

>From the L2CAP/RFCOMM connection establishment onwards the external
profile takes over though through the NewConnection method.

Johan

^ permalink raw reply

* Rayson BTM-112 support
From: Wojciech Kazubski @ 2012-12-12 16:49 UTC (permalink / raw)
  To: linux-bluetooth

Hello

I am trying to make Rayson BTM-112 module working with Linux. This is the BT 
module designed to use with microcontolers  and supports SPP profile. It works 
out of the box with Windows (creating two seriarial ports - COM8 and COM 9 or 
so) and I can pair it under Linux but no serial port is created.

Have I missed anything? (any bluez modules that have to be installed 
separately? modprobe entries?)

I am using Fedora 17 and openSUSE 12.2 and the module is not working in both 
distributions. 

Wojciech Kazubski



^ permalink raw reply

* Re: [PATCH BlueZ 01/11] obexd: Port bluetooth plugin to use external profile support
From: Mikel Astiz @ 2012-12-12 16:38 UTC (permalink / raw)
  To: Luiz Augusto von Dentz, linux-bluetooth
In-Reply-To: <20121212120236.GA11264@x220.ger.corp.intel.com>

Hi Johan, Luiz,

On Wed, Dec 12, 2012 at 1:02 PM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Luiz,
>
> On Wed, Dec 12, 2012, Luiz Augusto von Dentz wrote:
>> This changes obexd to use ProfileManager.RegisterProfile
>> ---
>>  obexd/plugins/bluetooth.c | 696 ++++++++++++++--------------------------------
>>  1 file changed, 212 insertions(+), 484 deletions(-)
>
> All patches in this set have been applied. I also removed the service
> plugin in the same go as now all known users of it are gone.

I'm a bit confused with these recent changes. I haven't been following
this closely so I guess I'm missing the Big Plan but let me start with
the basics: both bluetoothd and obexd repositories were merged but I
believe both daemons are still going to be separate daemons, is this
correct?

If yes, it makes sense that obexd makes use of the "external profile"
infrastructure.

But in that case, why would we add any obex-specific code into
bluetoothd? My understanding was that, if a profile is implemented as
an external profile, the bluetoothd core would not be aware of it.

Cheers,
Mikel

^ permalink raw reply

* [PATCH 14/14] input: Use new storage architecture
From: Frédéric Danis @ 2012-12-12 15:48 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1355327283-1558-1-git-send-email-frederic.danis@linux.intel.com>

When an input device is probed, it tries to retrieve its SDP record
from "input" file in storage directory.
If this fails, during bonding phase, records is vailable from device
object.

During connection, retrieve SDP record from "input" file.
---
 profiles/input/device.c  |   17 ++++++++---
 profiles/input/manager.c |   75 +++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 84 insertions(+), 8 deletions(-)

diff --git a/profiles/input/device.c b/profiles/input/device.c
index 2d8077a..5eba0be 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -316,7 +316,8 @@ static gboolean encrypt_notify(GIOChannel *io, GIOCondition condition,
 static int hidp_add_connection(struct input_device *idev)
 {
 	struct hidp_connadd_req *req;
-	uint8_t dst_type;
+	char *filename, *data;
+	GKeyFile *key_file = NULL;
 	sdp_record_t *rec;
 	char src_addr[18], dst_addr[18];
 	GError *gerr = NULL;
@@ -331,15 +332,23 @@ static int hidp_add_connection(struct input_device *idev)
 	ba2str(&idev->src, src_addr);
 	ba2str(&idev->dst, dst_addr);
 
-	dst_type = device_get_addr_type(idev->device);
+	filename = device_get_storage_path(idev->device, "input");
 
-	rec = fetch_record(src_addr, dst_addr, dst_type, idev->handle);
-	if (!rec) {
+	key_file = g_key_file_new();
+	g_key_file_load_from_file(key_file, filename, 0, NULL);
+	data = g_key_file_get_string(key_file, "SDP", "Record", NULL);
+	g_key_file_free(key_file);
+	g_free(filename);
+
+	if (!data) {
 		error("Rejected connection from unknown device %s", dst_addr);
 		err = -EPERM;
 		goto cleanup;
 	}
 
+	rec = record_from_string(data);
+	g_free(data);
+
 	extract_hid_record(rec, req);
 	sdp_record_free(rec);
 
diff --git a/profiles/input/manager.c b/profiles/input/manager.c
index 622e24b..db42c34 100644
--- a/profiles/input/manager.c
+++ b/profiles/input/manager.c
@@ -27,6 +27,8 @@
 
 #include <errno.h>
 #include <stdbool.h>
+#include <stdlib.h>
+#include <fcntl.h>
 
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/sdp.h>
@@ -42,6 +44,7 @@
 #include "device.h"
 #include "server.h"
 #include "manager.h"
+#include "storage.h"
 
 static int idle_timeout = 0;
 
@@ -54,19 +57,83 @@ static void input_remove(struct btd_device *device, const char *uuid)
 	input_device_unregister(path, uuid);
 }
 
+static void store_hid_record(char *filename, const sdp_record_t *rec)
+{
+	sdp_buf_t buf;
+	int size, i;
+	char *str, *data;
+	GKeyFile *key_file = NULL;
+	gsize length = 0;
+
+	if (sdp_gen_record_pdu(rec, &buf) < 0)
+		return;
+
+	size = buf.data_size;
+	str = g_malloc0(size*2+1);
+
+	for (i = 0; i < size; i++)
+		sprintf(str + (i * 2), "%02X", buf.data[i]);
+
+	free(buf.data);
+
+	key_file = g_key_file_new();
+	g_key_file_set_string(key_file, "SDP", "Record", str);
+
+	data = g_key_file_to_data(key_file, &length, NULL);
+	if (length > 0) {
+		create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+		g_file_set_contents(filename, data, length, NULL);
+	}
+
+	g_free(data);
+	g_free(str);
+
+	g_key_file_free(key_file);
+}
+
 static int hid_device_probe(struct btd_profile *p, struct btd_device *device,
 								GSList *uuids)
 {
 	const gchar *path = device_get_path(device);
 	const sdp_record_t *rec = btd_device_get_record(device, uuids->data);
+	sdp_record_t *stored_rec;
+	char *filename, *data;
+	GKeyFile *key_file = NULL;
+	int err;
 
 	DBG("path %s", path);
 
-	if (!rec)
-		return -1;
+	filename = device_get_storage_path(device, "input");
+
+	if (rec) {
+		store_hid_record(filename, rec);
+
+		err = input_device_register(device, path, HID_UUID, rec,
+						idle_timeout * 60);
+		goto end;
+	}
+
+	key_file = g_key_file_new();
+	g_key_file_load_from_file(key_file, filename, 0, NULL);
+	data = g_key_file_get_string(key_file, "SDP", "Record", NULL);
+	g_key_file_free(key_file);
+
+	if (!data) {
+		err = -1;
+		goto end;
+	}
+
+	stored_rec = record_from_string(data);
+	g_free(data);
+
+	err = input_device_register(device, path, HID_UUID, stored_rec,
+						idle_timeout * 60);
+	sdp_record_free(stored_rec);
+
+end:
+	g_free(filename);
 
-	return input_device_register(device, path, HID_UUID, rec,
-							idle_timeout * 60);
+	return err;
 }
 
 static void hid_device_remove(struct btd_profile *p, struct btd_device *device)
-- 
1.7.9.5


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox