Linux bluetooth development
 help / color / mirror / Atom feed
* Re: HCI data payload not getting through when using BlueZ
From: Eponymous - @ 2011-05-17 12:45 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth
In-Reply-To: <BANLkTin1wGOa2=_9qHhYmmTbLs_E2xUHXw@mail.gmail.com>

lsusb:

Bus 001 Device 041: ID 0a12:0001 Cambridge Silicon Radio, Ltd
Bluetooth Dongle (HCI mode)
Bus 001 Device 040: ID 0a12:0001 Cambridge Silicon Radio, Ltd
Bluetooth Dongle (HCI mode)

These are definitely plain USB devices. There is no /dev/ttyUSBxx like
you would get with the FTDI USB->Serial converters.

I've checked over dmesg and the messages (of which there are many
since I have eight of these devices) says they are USB.

I don't want to become sidetracked from the issue though. Is there
anyway to debug this issue without using l2test or any other
upperlayers program? The issue I have seen was at the HCI level
remember so I'm thinking introducing the upperlayers is going to make
things unnecessarily complicated.

Cheers.


On Tue, May 17, 2011 at 12:50 PM, Anderson Lizardo
<anderson.lizardo@openbossa.org> wrote:
> Hi,
>
> On Tue, May 17, 2011 at 3:13 AM, Eponymous - <the.epon@gmail.com> wrote:
>> The chips are CSR Bluecores. In order to get upperlayers access rather
>>  than HCI over USB you have to configure a key in the firmware.
>>
>> As soon as I enable upperlayers access the devices disappear from hciconfig.
>
> As I said, there are various development/prototype devices out there
> that use UART (usually CDC ACM or FTDI over USB) transport instead of
> "plain" USB. If you post the relevant lines from "dmesg" and "lsusb"
> somewhere (after you configure the firmware key), we might be able to
> identify the transport.
>
> For UART, you need to use hciattach on a e.g. /dev/ttyUSBX device
> created when plugging the device.
>
> HTH,
> --
> Anderson Lizardo
> Instituto Nokia de Tecnologia - INdT
> Manaus - Brazil
>

^ permalink raw reply

* Re: HCI data payload not getting through when using BlueZ
From: Anderson Lizardo @ 2011-05-17 11:50 UTC (permalink / raw)
  To: Eponymous -; +Cc: linux-bluetooth
In-Reply-To: <BANLkTi=xgHcwU-2XeKoVweoLGRYQJNUvvg@mail.gmail.com>

Hi,

On Tue, May 17, 2011 at 3:13 AM, Eponymous - <the.epon@gmail.com> wrote:
> The chips are CSR Bluecores. In order to get upperlayers access rather
>  than HCI over USB you have to configure a key in the firmware.
>
> As soon as I enable upperlayers access the devices disappear from hciconfig.

As I said, there are various development/prototype devices out there
that use UART (usually CDC ACM or FTDI over USB) transport instead of
"plain" USB. If you post the relevant lines from "dmesg" and "lsusb"
somewhere (after you configure the firmware key), we might be able to
identify the transport.

For UART, you need to use hciattach on a e.g. /dev/ttyUSBX device
created when plugging the device.

HTH,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply

* [PATCH] Fix remaining empty parameter list in functions declarations
From: Szymon Janc @ 2011-05-17 10:47 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, Szymon Janc

---
 lib/sdp.c           |    2 +-
 sbc/sbctester.c     |    2 +-
 src/log.c           |    2 +-
 src/log.h           |    2 +-
 src/sdpd-database.c |    2 +-
 test/avtest.c       |    2 +-
 tools/avinfo.c      |    2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/lib/sdp.c b/lib/sdp.c
index 2425b1e..a48ee14 100644
--- a/lib/sdp.c
+++ b/lib/sdp.c
@@ -3111,7 +3111,7 @@ int sdp_record_update(sdp_session_t *session, const sdp_record_t *rec)
 	return sdp_device_record_update(session, BDADDR_ANY, rec);
 }
 
-sdp_record_t *sdp_record_alloc()
+sdp_record_t *sdp_record_alloc(void)
 {
 	sdp_record_t *rec = malloc(sizeof(sdp_record_t));
 
diff --git a/sbc/sbctester.c b/sbc/sbctester.c
index b1e3608..c08c22a 100644
--- a/sbc/sbctester.c
+++ b/sbc/sbctester.c
@@ -245,7 +245,7 @@ static int check_absolute_diff(SNDFILE * sndref, SF_INFO * infosref,
 	return verdict;
 }
 
-static void usage()
+static void usage(void)
 {
 	printf("SBC conformance test ver %s\n", VERSION);
 	printf("Copyright (c) 2007-2010  Marcel Holtmann\n");
diff --git a/src/log.c b/src/log.c
index 494ff5d..6fbbba9 100644
--- a/src/log.c
+++ b/src/log.c
@@ -86,7 +86,7 @@ static gboolean is_enabled(struct btd_debug_desc *desc)
 	return 0;
 }
 
-void __btd_toggle_debug()
+void __btd_toggle_debug(void)
 {
 	struct btd_debug_desc *desc;
 
diff --git a/src/log.h b/src/log.h
index 14e9bfd..78bbdd8 100644
--- a/src/log.h
+++ b/src/log.h
@@ -28,7 +28,7 @@ void btd_debug(const char *format, ...) __attribute__((format(printf, 1, 2)));
 
 void __btd_log_init(const char *debug, int detach);
 void __btd_log_cleanup(void);
-void __btd_toggle_debug();
+void __btd_toggle_debug(void);
 
 struct btd_debug_desc {
 	const char *file;
diff --git a/src/sdpd-database.c b/src/sdpd-database.c
index 08f542f..dd492bf 100644
--- a/src/sdpd-database.c
+++ b/src/sdpd-database.c
@@ -90,7 +90,7 @@ static void access_free(void *p)
 /*
  * Reset the service repository by deleting its contents
  */
-void sdp_svcdb_reset()
+void sdp_svcdb_reset(void)
 {
 	sdp_list_free(service_db, (sdp_free_func_t) sdp_record_free);
 	sdp_list_free(access_db, access_free);
diff --git a/test/avtest.c b/test/avtest.c
index 168326f..541b3cd 100644
--- a/test/avtest.c
+++ b/test/avtest.c
@@ -714,7 +714,7 @@ static void do_avctp_send(int sk, int invalid)
 		dump_avctp_header(hdr);
 }
 
-static void usage()
+static void usage(void)
 {
 	printf("avtest - Audio/Video testing ver %s\n", VERSION);
 	printf("Usage:\n"
diff --git a/tools/avinfo.c b/tools/avinfo.c
index 7f76c03..63b0da6 100644
--- a/tools/avinfo.c
+++ b/tools/avinfo.c
@@ -604,7 +604,7 @@ static int l2cap_connect(bdaddr_t *src, bdaddr_t *dst)
 	return sk;
 }
 
-static void usage()
+static void usage(void)
 {
 	printf("avinfo - Audio/Video Info Tool ver %s\n", VERSION);
 	printf("Usage:\n"
-- 
on behalf of ST-Ericsson


^ permalink raw reply related

* [PATCH] mgmt: fix DBG string format
From: Frédéric Danis @ 2011-05-17  9:04 UTC (permalink / raw)
  To: linux-bluetooth

---
 plugins/mgmtops.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/plugins/mgmtops.c b/plugins/mgmtops.c
index 5e89046..95de3d1 100644
--- a/plugins/mgmtops.c
+++ b/plugins/mgmtops.c
@@ -501,7 +501,7 @@ static int mgmt_pincode_reply(int index, bdaddr_t *bdaddr, const char *pin,
 	char addr[18];
 
 	ba2str(bdaddr, addr);
-	DBG("index %d addr %s pinlen %lu", index, addr, pin_len);
+	DBG("index %d addr %s pinlen %zu", index, addr, pin_len);
 
 	memset(buf, 0, sizeof(buf));
 
-- 
1.7.1


^ permalink raw reply related

* [PATCH 2/2] Simplify options for including/excluding plugins
From: Luiz Augusto von Dentz @ 2011-05-17  8:17 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1305620264-22304-1-git-send-email-luiz.dentz@gmail.com>

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

Plugins options are now handle with --plugin(-p)/--noplugin(-P) which
takes a string set containing the plugin names separated by ',',':' or
' 'similar to bluetoothd, ofono and connman.
---
 src/main.c   |   76 ++++++++++++++-------------------------------------------
 src/obexd.h  |    2 +-
 src/plugin.c |   51 +++++++++++++++++++++++++++++++++++++-
 3 files changed, 69 insertions(+), 60 deletions(-)

diff --git a/src/main.c b/src/main.c
index 018a8cf..fb4c8e0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -148,15 +148,10 @@ static void sig_debug(int sig)
 static gboolean option_detach = TRUE;
 static char *option_debug = NULL;
 static char *option_config = NULL;
+static char *option_plugin = NULL;
+static char *option_noplugin = NULL;
 
 static gboolean option_autoaccept = FALSE;
-static gboolean option_opp = FALSE;
-static gboolean option_ftp = FALSE;
-static gboolean option_pbap = FALSE;
-static gboolean option_irmc = FALSE;
-static gboolean option_pcsuite = FALSE;
-static gboolean option_syncevolution = FALSE;
-static gboolean option_mas = FALSE;
 
 static gboolean parse_debug(const char *key, const char *value,
 				gpointer user_data, GError **error)
@@ -192,20 +187,10 @@ static GOptionEntry options[] = {
 				"Config file location", "FILE" },
 	{ "auto-accept", 'a', 0, G_OPTION_ARG_NONE, &option_autoaccept,
 				"Automatically accept push requests" },
-	{ "opp", 'o', 0, G_OPTION_ARG_NONE, &option_opp,
-				"Enable Object Push server" },
-	{ "ftp", 'f', 0, G_OPTION_ARG_NONE, &option_ftp,
-				"Enable File Transfer server" },
-	{ "pbap", 'p', 0, G_OPTION_ARG_NONE, &option_pbap,
-				"Enable Phonebook Access server" },
-	{ "irmc", 'i', 0, G_OPTION_ARG_NONE, &option_irmc,
-				"Enable IrMC Sync server" },
-	{ "pcsuite", 's', 0, G_OPTION_ARG_NONE, &option_pcsuite,
-				"Enable PC Suite Services server" },
-	{ "syncevolution", 'e', 0, G_OPTION_ARG_NONE, &option_syncevolution,
-				"Enable OBEX server for SyncEvolution" },
-        { "mas", 'm', 0, G_OPTION_ARG_NONE, &option_mas,
-				"Enable Message Access server" },
+	{ "plugin", 'p', 0, G_OPTION_ARG_STRING, &option_plugin,
+				"Specify plugins to load", "NAME,..." },
+	{ "noplugin", 'P', 0, G_OPTION_ARG_STRING, &option_noplugin,
+				"Specify plugins not to load", "NAME,..." },
 	{ NULL },
 };
 
@@ -292,16 +277,6 @@ int main(int argc, char *argv[])
 		}
 	}
 
-	if (option_opp == FALSE && option_ftp == FALSE &&
-				option_pbap == FALSE &&
-				option_irmc == FALSE &&
-				option_syncevolution == FALSE &&
-				option_mas == FALSE) {
-		fprintf(stderr, "No server selected (use either "
-				"--opp, --ftp, --pbap, --irmc, --mas, or --syncevolution)\n");
-		exit(EXIT_FAILURE);
-	}
-
 	__obex_log_init("obexd", option_debug, option_detach);
 
 	if (option_config)
@@ -323,39 +298,26 @@ int main(int argc, char *argv[])
 		exit(EXIT_FAILURE);
 	}
 
-	plugin_init();
+	plugin_init(option_plugin, option_noplugin);
 
-	if (option_opp == TRUE)
-		obex_server_init(OBEX_OPP, obexd_settings.root_folder,
-						FALSE, option_autoaccept,
-						obexd_settings.symlinks,
-						NULL);
+	obex_server_init(OBEX_OPP, obexd_settings.root_folder, FALSE,
+			option_autoaccept, obexd_settings.symlinks, NULL);
 
-	if (option_ftp == TRUE)
-		obex_server_init(OBEX_FTP, obexd_settings.root_folder,
-						TRUE, option_autoaccept,
-						obexd_settings.symlinks,
-						obexd_settings.capability);
+	obex_server_init(OBEX_FTP, obexd_settings.root_folder, TRUE,
+			option_autoaccept, obexd_settings.symlinks,
+			obexd_settings.capability);
 
-	if (option_pbap == TRUE)
-		obex_server_init(OBEX_PBAP, NULL, TRUE, FALSE, FALSE, NULL);
+	obex_server_init(OBEX_PCSUITE, obexd_settings.root_folder, TRUE,
+			option_autoaccept, obexd_settings.symlinks,
+			obexd_settings.capability);
 
-	if (option_pcsuite == TRUE)
-		obex_server_init(OBEX_PCSUITE, obexd_settings.root_folder,
-						TRUE, option_autoaccept,
-						obexd_settings.symlinks,
-						obexd_settings.capability);
+	obex_server_init(OBEX_PBAP, NULL, TRUE, FALSE, FALSE, NULL);
 
-	if (option_irmc == TRUE)
-		obex_server_init(OBEX_IRMC, NULL, TRUE, FALSE, FALSE,
-						obexd_settings.capability);
+	obex_server_init(OBEX_IRMC, NULL, TRUE, FALSE, FALSE, NULL);
 
-	if (option_syncevolution == TRUE)
-		obex_server_init(OBEX_SYNCEVOLUTION, NULL, TRUE, FALSE,
-							FALSE, NULL);
+	obex_server_init(OBEX_SYNCEVOLUTION, NULL, TRUE, FALSE, FALSE, NULL);
 
-	if (option_mas == TRUE)
-		obex_server_init(OBEX_MAS, NULL, TRUE, FALSE, FALSE, NULL);
+	obex_server_init(OBEX_MAS, NULL, TRUE, FALSE, FALSE, NULL);
 
 	if (!root_folder_setup()) {
 		error("Unable to setup root folder %s",
diff --git a/src/obexd.h b/src/obexd.h
index df21f00..37106b7 100644
--- a/src/obexd.h
+++ b/src/obexd.h
@@ -21,7 +21,7 @@
  *
  */
 
-gboolean plugin_init(void);
+gboolean plugin_init(const char *pattern, const char *exclude);
 void plugin_cleanup(void);
 
 gboolean manager_init(void);
diff --git a/src/plugin.c b/src/plugin.c
index 14a569f..c8ec642 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -79,10 +79,39 @@ static gboolean add_plugin(void *handle, struct obex_plugin_desc *desc)
 	return TRUE;
 }
 
+static gboolean check_plugin(struct obex_plugin_desc *desc,
+				char **patterns, char **excludes)
+{
+	if (excludes) {
+		for (; *excludes; excludes++)
+			if (g_pattern_match_simple(*excludes, desc->name))
+				break;
+		if (*excludes) {
+			info("Excluding %s", desc->name);
+			return FALSE;
+		}
+	}
+
+	if (patterns) {
+		for (; *patterns; patterns++)
+			if (g_pattern_match_simple(*patterns, desc->name))
+				break;
+		if (*patterns == NULL) {
+			info("Ignoring %s", desc->name);
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+
 #include "builtin.h"
 
-gboolean plugin_init(void)
+gboolean plugin_init(const char *pattern, const char *exclude)
 {
+	gchar **patterns = NULL;
+	gchar **excludes = NULL;
 	GDir *dir;
 	const char *file;
 	unsigned int i;
@@ -90,10 +119,21 @@ gboolean plugin_init(void)
 	if (strlen(PLUGINDIR) == 0)
 		return FALSE;
 
+	if (pattern)
+		patterns = g_strsplit_set(pattern, ":, ", -1);
+
+	if (exclude)
+		excludes = g_strsplit_set(exclude, ":, ", -1);
+
 	DBG("Loading builtin plugins");
 
-	for (i = 0; __obex_builtin[i]; i++)
+	for (i = 0; __obex_builtin[i]; i++) {
+		if (check_plugin(__obex_builtin[i],
+					patterns, excludes) == FALSE)
+			continue;
+
 		add_plugin(NULL,  __obex_builtin[i]);
+	}
 
 	DBG("Loading plugins %s", PLUGINDIR);
 
@@ -129,11 +169,18 @@ gboolean plugin_init(void)
 			continue;
 		}
 
+		if (check_plugin(desc, patterns, excludes) == FALSE) {
+			dlclose(handle);
+			continue;
+		}
+
 		if (add_plugin(handle, desc) == FALSE)
 			dlclose(handle);
 	}
 
 	g_dir_close(dir);
+	g_strfreev(patterns);
+	g_strfreev(excludes);
 
 	return TRUE;
 }
-- 
1.7.1


^ permalink raw reply related

* [PATCH 1/2] Add conf file support
From: Luiz Augusto von Dentz @ 2011-05-17  8:17 UTC (permalink / raw)
  To: linux-bluetooth

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

This should reduce the amount of options which normally don't change each
time obexd is executed.
---
 Makefile.am    |    2 +-
 plugins/ftp.c  |    8 ++-
 src/main.c     |  176 +++++++++++++++++++++++++++++++++++++++-----------------
 src/obexd.conf |   19 ++++++
 4 files changed, 149 insertions(+), 56 deletions(-)
 create mode 100644 src/obexd.conf

diff --git a/Makefile.am b/Makefile.am
index 8d8fdc6..2b329a6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -138,7 +138,7 @@ INCLUDES = -I$(builddir)/src -I$(srcdir)/src -I$(srcdir)/plugins \
 
 CLEANFILES = $(service_DATA) $(builtin_files)
 
-EXTRA_DIST = src/genbuiltin $(doc_files) $(test_files) src/obex.conf \
+EXTRA_DIST = src/genbuiltin $(doc_files) $(test_files) src/obexd.conf \
 			src/obexd.service.in client/obex-client.service.in \
 			plugins/phonebook-dummy.c plugins/phonebook-ebook.c \
 			plugins/phonebook-tracker.c \
diff --git a/plugins/ftp.c b/plugins/ftp.c
index 79223bf..879d9e9 100644
--- a/plugins/ftp.c
+++ b/plugins/ftp.c
@@ -179,8 +179,12 @@ static int get_by_type(struct ftp_session *ftp, const char *type)
 	if (type == NULL && name == NULL)
 		return -EBADR;
 
-	if (g_strcmp0(type, CAP_TYPE) == 0)
-		return obex_get_stream_start(os, capability);
+	if (g_strcmp0(type, CAP_TYPE) == 0) {
+		if (capability)
+			return obex_get_stream_start(os, capability);
+		else
+			return -ENOENT;
+	}
 
 	path = g_build_filename(ftp->folder, name, NULL);
 	err = obex_get_stream_start(os, path);
diff --git a/src/main.c b/src/main.c
index 8154e3b..018a8cf 100644
--- a/src/main.c
+++ b/src/main.c
@@ -54,7 +54,83 @@
 
 #define DEFAULT_ROOT_PATH "/tmp"
 
-#define DEFAULT_CAP_FILE CONFIGDIR "/capability.xml"
+static struct {
+	char *root_setup;
+	char *root_folder;
+	char *capability;
+	gboolean symlinks;
+} obexd_settings  = {
+	.root_setup = NULL,
+	.root_folder = DEFAULT_ROOT_PATH,
+	.capability = NULL,
+	.symlinks = FALSE
+};
+
+static void parse_config(GKeyFile *config)
+{
+	GError *error = NULL;
+	char *string;
+	gboolean boolean;
+
+	string = g_key_file_get_string(config, "General",
+						"RootSetup", &error);
+	if (error == NULL)
+		obexd_settings.root_setup = string;
+	else
+		g_clear_error(&error);
+
+	string = g_key_file_get_string(config, "General",
+						"RootFolder", &error);
+	if (error == NULL) {
+		if (string[0] != '/') {
+			char *old_root = string, *home = getenv("HOME");
+			if (home) {
+				string = g_strdup_printf("%s/%s", home, old_root);
+				g_free(old_root);
+			}
+		}
+
+		obexd_settings.root_folder = string;
+	} else
+		g_clear_error(&error);
+
+	string = g_key_file_get_string(config, "General",
+						"Capability", &error);
+	if (error == NULL)
+		obexd_settings.capability = string;
+	else
+		g_clear_error(&error);
+
+	boolean = g_key_file_get_boolean(config, "General",
+						"Symlinks", &error);
+	if (error == NULL)
+		obexd_settings.symlinks = boolean;
+
+	g_clear_error(&error);
+}
+
+static GKeyFile *load_config(const char *file)
+{
+	GError *err = NULL;
+	GKeyFile *keyfile;
+
+	DBG("%s", file);
+
+	keyfile = g_key_file_new();
+
+	g_key_file_set_list_separator(keyfile, ',');
+
+	if (!g_key_file_load_from_file(keyfile, file, 0, &err)) {
+		error("Parsing %s failed: %s", file, err->message);
+		g_error_free(err);
+		g_key_file_free(keyfile);
+		return NULL;
+	}
+
+	parse_config(keyfile);
+
+	return keyfile;
+}
 
 static GMainLoop *main_loop = NULL;
 
@@ -71,10 +147,7 @@ static void sig_debug(int sig)
 
 static gboolean option_detach = TRUE;
 static char *option_debug = NULL;
-
-static char *option_root = NULL;
-static char *option_root_setup = NULL;
-static char *option_capability = NULL;
+static char *option_config = NULL;
 
 static gboolean option_autoaccept = FALSE;
 static gboolean option_opp = FALSE;
@@ -82,7 +155,6 @@ static gboolean option_ftp = FALSE;
 static gboolean option_pbap = FALSE;
 static gboolean option_irmc = FALSE;
 static gboolean option_pcsuite = FALSE;
-static gboolean option_symlinks = FALSE;
 static gboolean option_syncevolution = FALSE;
 static gboolean option_mas = FALSE;
 
@@ -97,6 +169,17 @@ static gboolean parse_debug(const char *key, const char *value,
 	return TRUE;
 }
 
+static gboolean set_config(const char *key, const char *value,
+				gpointer user_data, GError **error)
+{
+	if (!value)
+		return FALSE;
+
+	option_config = g_strdup(value);
+
+	return TRUE;
+}
+
 static GOptionEntry options[] = {
 	{ "nodaemon", 'n', G_OPTION_FLAG_REVERSE,
 				G_OPTION_ARG_NONE, &option_detach,
@@ -104,14 +187,9 @@ static GOptionEntry options[] = {
 	{ "debug", 'd', G_OPTION_FLAG_OPTIONAL_ARG,
 				G_OPTION_ARG_CALLBACK, parse_debug,
 				"Enable debug information output", "DEBUG" },
-	{ "root", 'r', 0, G_OPTION_ARG_STRING, &option_root,
-				"Specify root folder location", "PATH" },
-	{ "root-setup", 'S', 0, G_OPTION_ARG_STRING, &option_root_setup,
-				"Root folder setup script", "SCRIPT" },
-	{ "symlinks", 'l', 0, G_OPTION_ARG_NONE, &option_symlinks,
-				"Enable symlinks on root folder" },
-	{ "capability", 'c', 0, G_OPTION_ARG_STRING, &option_capability,
-				"Specify capability file", "FILE" },
+	{ "config", 'c', G_OPTION_FLAG_OPTIONAL_ARG,
+				G_OPTION_ARG_CALLBACK, set_config,
+				"Config file location", "FILE" },
 	{ "auto-accept", 'a', 0, G_OPTION_ARG_NONE, &option_autoaccept,
 				"Automatically accept push requests" },
 	{ "opp", 'o', 0, G_OPTION_ARG_NONE, &option_opp,
@@ -133,12 +211,12 @@ static GOptionEntry options[] = {
 
 const char *obex_option_root_folder(void)
 {
-	return option_root;
+	return obexd_settings.root_folder;
 }
 
 gboolean obex_option_symlinks(void)
 {
-	return option_symlinks;
+	return obexd_settings.symlinks;
 }
 
 static gboolean is_dir(const char *dir) {
@@ -152,32 +230,33 @@ static gboolean is_dir(const char *dir) {
 	return S_ISDIR(st.st_mode);
 }
 
-static gboolean root_folder_setup(char *root, char *root_setup)
+static gboolean root_folder_setup()
 {
 	int status;
-	char *argv[3] = { root_setup, root, NULL };
+	char *argv[3] = { obexd_settings.root_setup,
+					obexd_settings.root_folder, NULL };
 
-	if (is_dir(root))
+	if (is_dir(argv[1]))
 		return TRUE;
 
-	if (root_setup == NULL)
+	if (argv[0] == NULL || strlen(argv[0]) == 0)
 		return FALSE;
 
-	DBG("Setting up %s using %s", root, root_setup);
+	DBG("Setting up %s using %s", argv[1], argv[0]);
 
 	if (!g_spawn_sync(NULL, argv, NULL, 0, NULL, NULL, NULL, NULL,
 							&status, NULL)) {
-		error("Unable to execute %s", root_setup);
+		error("Unable to execute %s", argv[0]);
 		return FALSE;
 	}
 
 	if (WEXITSTATUS(status) != EXIT_SUCCESS) {
-		error("%s exited with status %d", root_setup,
+		error("%s exited with status %d", argv[0],
 							WEXITSTATUS(status));
 		return FALSE;
 	}
 
-	return is_dir(root);
+	return is_dir(argv[1]);
 }
 
 int main(int argc, char *argv[])
@@ -185,6 +264,7 @@ int main(int argc, char *argv[])
 	GOptionContext *context;
 	GError *err = NULL;
 	struct sigaction sa;
+	GKeyFile *config;
 
 #ifdef NEED_THREADS
 	if (g_thread_supported() == FALSE)
@@ -224,6 +304,9 @@ int main(int argc, char *argv[])
 
 	__obex_log_init("obexd", option_debug, option_detach);
 
+	if (option_config)
+		config = load_config(option_config);
+
 	DBG("Entering main loop");
 
 	main_loop = g_main_loop_new(NULL, FALSE);
@@ -240,43 +323,32 @@ int main(int argc, char *argv[])
 		exit(EXIT_FAILURE);
 	}
 
-	if (option_root == NULL)
-		option_root = g_strdup(DEFAULT_ROOT_PATH);
-
-	if (option_root[0] != '/') {
-		char *old_root = option_root, *home = getenv("HOME");
-		if (home) {
-			option_root = g_strdup_printf("%s/%s", home, old_root);
-			g_free(old_root);
-		}
-	}
-
 	plugin_init();
 
-	if (option_capability == NULL)
-		option_capability = g_strdup(DEFAULT_CAP_FILE);
-
 	if (option_opp == TRUE)
-		obex_server_init(OBEX_OPP, option_root, FALSE,
-				option_autoaccept, option_symlinks,
-				NULL);
+		obex_server_init(OBEX_OPP, obexd_settings.root_folder,
+						FALSE, option_autoaccept,
+						obexd_settings.symlinks,
+						NULL);
 
 	if (option_ftp == TRUE)
-		obex_server_init(OBEX_FTP, option_root, TRUE,
-				option_autoaccept, option_symlinks,
-				option_capability);
+		obex_server_init(OBEX_FTP, obexd_settings.root_folder,
+						TRUE, option_autoaccept,
+						obexd_settings.symlinks,
+						obexd_settings.capability);
 
 	if (option_pbap == TRUE)
 		obex_server_init(OBEX_PBAP, NULL, TRUE, FALSE, FALSE, NULL);
 
 	if (option_pcsuite == TRUE)
-		obex_server_init(OBEX_PCSUITE, option_root, TRUE,
-				option_autoaccept, option_symlinks,
-				option_capability);
+		obex_server_init(OBEX_PCSUITE, obexd_settings.root_folder,
+						TRUE, option_autoaccept,
+						obexd_settings.symlinks,
+						obexd_settings.capability);
 
 	if (option_irmc == TRUE)
 		obex_server_init(OBEX_IRMC, NULL, TRUE, FALSE, FALSE,
-				option_capability);
+						obexd_settings.capability);
 
 	if (option_syncevolution == TRUE)
 		obex_server_init(OBEX_SYNCEVOLUTION, NULL, TRUE, FALSE,
@@ -285,8 +357,9 @@ int main(int argc, char *argv[])
 	if (option_mas == TRUE)
 		obex_server_init(OBEX_MAS, NULL, TRUE, FALSE, FALSE, NULL);
 
-	if (!root_folder_setup(option_root, option_root_setup)) {
-		error("Unable to setup root folder %s", option_root);
+	if (!root_folder_setup()) {
+		error("Unable to setup root folder %s",
+						obexd_settings.root_folder);
 		exit(EXIT_FAILURE);
 	}
 
@@ -308,9 +381,6 @@ int main(int argc, char *argv[])
 
 	g_main_loop_unref(main_loop);
 
-	g_free(option_capability);
-	g_free(option_root);
-
 	__obex_log_cleanup();
 
 	return 0;
diff --git a/src/obexd.conf b/src/obexd.conf
new file mode 100644
index 0000000..ef2541b
--- /dev/null
+++ b/src/obexd.conf
@@ -0,0 +1,19 @@
+[General]
+
+# Root folder location. Both absolute and relative paths can be used, but
+# relative paths are assumed to be relative to user $HOME folder
+# Default /tmp
+RootFolder = /tmp
+
+# Root setup script absolute path used in case root folder doesn't exist
+# Default none
+#RootSetup =
+
+# Capability file or script absolute path, in case of script it should start
+# with '!' mark.
+# Default none
+#Capability =
+
+# Indicates if symbolics links should be followed (only on root folder)
+# Default false
+Symlinks = false
-- 
1.7.1


^ permalink raw reply related

* Does any one recognise this protocol? is it RF_COMM
From: Alan @ 2011-05-17  7:15 UTC (permalink / raw)
  To: linux-bluetooth

I am trying to write an OS driver for some propeitary hardware.
I have hit brick wall and need to go back and check what I know so far and 
turn over the rocks on the bits I hoped I could ignore. 


I am wondering if I made faulty guess early on.  hence this question.



What protocol is this?   Can it be RF_COMM ?

below is an edited extract of SnoppyPro logs from the windows software talking 
to the real physical device.

My question is what protocol are all the wrappers.
 I beleieve I identified HCI-ACL / L2CAp/ UNK / Proprietary.

The Unk one is probably something standard. As I can feed the proprietary part 
into an RF_COMM socket under linux and the device responds as if I am the 
windows machine. I thook that to mean Windows was talking RF_COMM.

Howver when I have unix software pretend  be the device and listen( ) the 
accept( ) never returns if it is the winodw software talking to me, but does 
when it is my linux software talking to my enulated on linux device.
I can post full hcidump of the failure to connect if you indicate what 
settings are intelligible to you, Im finding raw the most informative  as i 
can compare it to Snopypro logs....  
But expect people who knows things would understand the gobbledegooked
output modes better. 

The snoopy pro logs are at the USB level(?), and contain one extra (internal) 
layer of protocol data I do not undertsand. I think it is RF_COMM

Typical packets
Physical devices packet sent to Windows
113     in      up      0x82    28.093  28.093  00
TransferBuffer: 0x0000002b (43) length
pre  0000: 2b 20 27 00    23 00 41 00    09 ef 3f 
wrap 0000: 7e[1f 00](61)  24:ac:18:25:80:00 => 00:00:00:00:00:00
cmnd 0000: 02 00 00 04  70 00 01 00  00 00 00 01  00 00 00 40

Windows PC Packet sent to Device
122     out     down    0x02    28.140  28.140  00
TransferBuffer: 0x00000024 (36) length
pre  0000: 2b 20 20 00    1c 00 8c 00    0b ff 2f 00    
wrap 0000: 7e[17 00](69)  00:00:00:00:00:00 => 01:00:00:00:00:00
cmnd 0000: 01 02 76 65  72 0d 0a 86  

wrap and cmnd lines are the Device specific protocol burried in what look like 
lower layers. My LinuxSoftware emulates the Windows software by injecting the 
packets starting at 7E up the second last byte, into an RF_COMM socket.

What I think I know
Im pretty sure the   2b 20 20 00  is
Protocol: “Core_V4.0.pdf” Figure 5.2: HCI ACL Data Packet   p429
and 1c 00 8c 00
is L2CAP  [size and channel ID].

Does anyone recognise a protocol runnign on L2CAP that looks like this

09 ef 3f       Data        40   for inbound packets and
0b ff 2f 00    Data       86  for outbound packets

Here are the same packets dumped RAW for Linux Software talking
physical devices.  
(I cant get packets for windw softwware talking emulated device as the conect 
fails. Thats the problem)

Note there are binary differences in both the L2CAP and RFCOMM parts.
Most worrying to me is the missing 0.
> 02 2B 20 27 00 23 00 40 00 09 EF 3F 7E 1F 00 61 24 AC 18 25 
  80 00 00 00 00 00 00 00 02 00 00 04 70 00 01 00 00 00 00 01 
  00 00 00 40 
Linux RFComm packet.
< 02 2B 20 1F 00 1B 00 4D 00 0B EF 2F 7E 17 00 69 00 00 00 00 
  00 00 01 00 00 00 00 00 01 02 76 65 72 0D 0A 9A 

Any idea why the differences or where there is a reasonable document on what 
those RF_COMM bytes mean.
Im probably goign to have to go deep enough to understand the connect process.


          Alan

^ permalink raw reply

* Re: HCI data payload not getting through when using BlueZ
From: Eponymous - @ 2011-05-17  7:13 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth
In-Reply-To: <BANLkTinL=-ODxZa9CGboD0o9443cG-uFkQ@mail.gmail.com>

The chips are CSR Bluecores. In order to get upperlayers access rather
 than HCI over USB you have to configure a key in the firmware.

As soon as I enable upperlayers access the devices disappear from hciconfig.

On Mon, May 16, 2011 at 1:17 PM, Anderson Lizardo
<anderson.lizardo@openbossa.org> wrote:
> Hi,
>
> On Mon, May 16, 2011 at 6:36 AM, Eponymous - <the.epon@gmail.com> wrote:
>> OK guys,
>>
>> I had a theory that my l2test test was not working due to the fact
>> that the chip wasn't configured to work with upperlayers. After
>> enabling this however, the  devices disappear (in hciconfig) so I
>> can't really test any L2CAP stuff (which I assume is what l2test is
>> doing).
>>
>> Are there any other things I can try to help debug this issue I've seen?
>
> What is the chipset of your USB dongles ? A "lsusb -d <vid>:<pid>" and
> relevant output from dmesg might help here.
>
> What do you mean by "the chip wasn't configured to work with
> upperlayers" ? Was the chipset in a mode which was not HCI compliant?
>
> Keep in mind that there are development/prototype USB dongles which
> are in fact serial/FTDI devices, and thus require using hciattach to
> be able to use them in BlueZ.
>
> Regards,
> --
> Anderson Lizardo
> Instituto Nokia de Tecnologia - INdT
> Manaus - Brazil
>

^ permalink raw reply

* [PATCH v3 12/12] Drop variable EIR length
From: Claudio Takahasi @ 2011-05-16 20:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1305579001-3019-1-git-send-email-claudio.takahasi@openbossa.org>

From: Bruna Moreira <bruna.moreira@openbossa.org>

The functions eir_parse() and adapter_update_found_devices() now
assume that the EIR buffer has always 240 octets. For advertising
reports, the advertising data is stored on a buffer with 240 bytes,
padded with zeroes.
---
 plugins/hciops.c |   13 +++++++++----
 src/adapter.c    |    6 +++---
 src/adapter.h    |    4 ++--
 src/eir.c        |    8 ++++----
 src/eir.h        |    2 +-
 src/event.c      |    3 +--
 6 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/plugins/hciops.c b/plugins/hciops.c
index 37b2d8e..d976822 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -2171,7 +2171,7 @@ static inline void le_advertising_report(int index, evt_le_meta_event *meta)
 {
 	struct dev_info *dev = &devs[index];
 	le_advertising_info *info;
-	uint8_t num_reports, rssi;
+	uint8_t num_reports, rssi, eir[HCI_MAX_EIR_LENGTH];
 	const uint8_t RSSI_SIZE = 1;
 
 	num_reports = meta->data[0];
@@ -2179,8 +2179,10 @@ static inline void le_advertising_report(int index, evt_le_meta_event *meta)
 	info = (le_advertising_info *) &meta->data[1];
 	rssi = *(info->data + info->length);
 
-	btd_event_device_found(&dev->bdaddr, &info->bdaddr, 0, rssi,
-								info->data);
+	memset(eir, 0, sizeof(eir));
+	memcpy(eir, info->data, info->length);
+
+	btd_event_device_found(&dev->bdaddr, &info->bdaddr, 0, rssi, eir);
 
 	num_reports--;
 
@@ -2189,8 +2191,11 @@ static inline void le_advertising_report(int index, evt_le_meta_event *meta)
 								RSSI_SIZE);
 		rssi = *(info->data + info->length);
 
+		memset(eir, 0, sizeof(eir));
+		memcpy(eir, info->data, info->length);
+
 		btd_event_device_found(&dev->bdaddr, &info->bdaddr, 0, rssi,
-								info->data);
+									eir);
 	}
 }
 
diff --git a/src/adapter.c b/src/adapter.c
index 84e8ca6..33fd354 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2999,8 +2999,8 @@ static char *read_stored_data(bdaddr_t *local, bdaddr_t *peer, const char *file)
 }
 
 void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
-					uint32_t class, int8_t rssi,
-					uint8_t *data, size_t eir_size)
+						uint32_t class, int8_t rssi,
+						uint8_t *data)
 {
 	struct remote_dev_info *dev, match;
 	struct eir_data eir_data;
@@ -3010,7 +3010,7 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 	int err;
 
 	memset(&eir_data, 0, sizeof(eir_data));
-	err = eir_parse(&eir_data, data, HCI_MAX_EIR_LENGTH);
+	err = eir_parse(&eir_data, data);
 	if (err < 0) {
 		error("Error parsing EIR data: %s (%d)", strerror(-err), -err);
 		return;
diff --git a/src/adapter.h b/src/adapter.h
index 4c07e92..3526849 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -109,8 +109,8 @@ int adapter_get_discover_type(struct btd_adapter *adapter);
 struct remote_dev_info *adapter_search_found_devices(struct btd_adapter *adapter,
 						struct remote_dev_info *match);
 void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
-					uint32_t class, int8_t rssi,
-					uint8_t *data, size_t eir_size);
+						uint32_t class, int8_t rssi,
+						uint8_t *data);
 int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr);
 void adapter_emit_device_found(struct btd_adapter *adapter,
 						struct remote_dev_info *dev);
diff --git a/src/eir.c b/src/eir.c
index 7dfc444..01b6ac5 100644
--- a/src/eir.c
+++ b/src/eir.c
@@ -52,7 +52,7 @@ void eir_data_free(struct eir_data *eir)
 	g_free(eir->name);
 }
 
-int eir_parse(struct eir_data *eir, uint8_t *eir_data, size_t eir_length)
+int eir_parse(struct eir_data *eir, uint8_t *eir_data)
 {
 	uint16_t len = 0;
 	size_t total;
@@ -69,10 +69,10 @@ int eir_parse(struct eir_data *eir, uint8_t *eir_data, size_t eir_length)
 	eir->flags = -1;
 
 	/* No EIR data to parse */
-	if (eir_data == NULL || eir_length == 0)
+	if (eir_data == NULL)
 		return 0;
 
-	while (len < eir_length - 1) {
+	while (len < HCI_MAX_EIR_LENGTH - 1) {
 		uint8_t field_len = eir_data[0];
 
 		/* Check for the end of EIR */
@@ -115,7 +115,7 @@ int eir_parse(struct eir_data *eir, uint8_t *eir_data, size_t eir_length)
 	}
 
 	/* Bail out if got incorrect length */
-	if (len > eir_length)
+	if (len > HCI_MAX_EIR_LENGTH)
 		return -EINVAL;
 
 	total = uuid16_count + uuid32_count + uuid128_count;
diff --git a/src/eir.h b/src/eir.h
index ea38570..d225973 100644
--- a/src/eir.h
+++ b/src/eir.h
@@ -35,7 +35,7 @@ struct eir_data {
 };
 
 void eir_data_free(struct eir_data *eir);
-int eir_parse(struct eir_data *eir, uint8_t *eir_data, size_t eir_length);
+int eir_parse(struct eir_data *eir, uint8_t *eir_data);
 void eir_create(const char *name, int8_t tx_power, uint16_t did_vendor,
 			uint16_t did_product, uint16_t did_version,
 			GSList *uuids, uint8_t *data);
diff --git a/src/event.c b/src/event.c
index cd5e9e1..55ffadb 100644
--- a/src/event.c
+++ b/src/event.c
@@ -320,8 +320,7 @@ void btd_event_device_found(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
 	if (data)
 		write_remote_eir(local, peer, data);
 
-	adapter_update_found_devices(adapter, peer, class, rssi,
-						data, HCI_MAX_EIR_LENGTH);
+	adapter_update_found_devices(adapter, peer, class, rssi, data);
 }
 
 void btd_event_set_legacy_pairing(bdaddr_t *local, bdaddr_t *peer,
-- 
1.7.5.rc3


^ permalink raw reply related

* [PATCH v3 11/12] Replace EIR_DATA_LENGTH with HCI_MAX_EIR_LENGTH
From: Claudio Takahasi @ 2011-05-16 20:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1305579001-3019-1-git-send-email-claudio.takahasi@openbossa.org>

From: Bruna Moreira <bruna.moreira@openbossa.org>

Both defines have the same value (240) and meaning.
---
 src/adapter.c |    2 +-
 src/eir.c     |    9 +++++----
 src/eir.h     |    2 --
 src/event.c   |    2 +-
 4 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index f4359f9..84e8ca6 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3010,7 +3010,7 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 	int err;
 
 	memset(&eir_data, 0, sizeof(eir_data));
-	err = eir_parse(&eir_data, data, EIR_DATA_LENGTH);
+	err = eir_parse(&eir_data, data, HCI_MAX_EIR_LENGTH);
 	if (err < 0) {
 		error("Error parsing EIR data: %s (%d)", strerror(-err), -err);
 		return;
diff --git a/src/eir.c b/src/eir.c
index 2fbd919..7dfc444 100644
--- a/src/eir.c
+++ b/src/eir.c
@@ -27,6 +27,7 @@
 #include <glib.h>
 
 #include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
 #include <bluetooth/sdp.h>
 
 #include "glib-helper.h"
@@ -184,7 +185,7 @@ static void eir_generate_uuid128(GSList *list, uint8_t *ptr, uint16_t *eir_len)
 			continue;
 
 		/* Stop if not enough space to put next UUID128 */
-		if ((len + 2 + SIZEOF_UUID128) > EIR_DATA_LENGTH) {
+		if ((len + 2 + SIZEOF_UUID128) > HCI_MAX_EIR_LENGTH) {
 			truncated = TRUE;
 			break;
 		}
@@ -229,7 +230,7 @@ void eir_create(const char *name, int8_t tx_power, uint16_t did_vendor,
 	GSList *l;
 	uint8_t *ptr = data;
 	uint16_t eir_len = 0;
-	uint16_t uuid16[EIR_DATA_LENGTH / 2];
+	uint16_t uuid16[HCI_MAX_EIR_LENGTH / 2];
 	int i, uuid_count = 0;
 	gboolean truncated = FALSE;
 	size_t name_len;
@@ -289,7 +290,7 @@ void eir_create(const char *name, int8_t tx_power, uint16_t did_vendor,
 			continue;
 
 		/* Stop if not enough space to put next UUID16 */
-		if ((eir_len + 2 + sizeof(uint16_t)) > EIR_DATA_LENGTH) {
+		if ((eir_len + 2 + sizeof(uint16_t)) > HCI_MAX_EIR_LENGTH) {
 			truncated = TRUE;
 			break;
 		}
@@ -322,6 +323,6 @@ void eir_create(const char *name, int8_t tx_power, uint16_t did_vendor,
 	}
 
 	/* Group all UUID128 types */
-	if (eir_len <= EIR_DATA_LENGTH - 2)
+	if (eir_len <= HCI_MAX_EIR_LENGTH - 2)
 		eir_generate_uuid128(uuids, ptr, &eir_len);
 }
diff --git a/src/eir.h b/src/eir.h
index aacd16a..ea38570 100644
--- a/src/eir.h
+++ b/src/eir.h
@@ -22,8 +22,6 @@
  *
  */
 
-#define EIR_DATA_LENGTH  240
-
 struct uuid_info {
 	uuid_t uuid;
 	uint8_t svc_hint;
diff --git a/src/event.c b/src/event.c
index 8a7db17..cd5e9e1 100644
--- a/src/event.c
+++ b/src/event.c
@@ -321,7 +321,7 @@ void btd_event_device_found(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
 		write_remote_eir(local, peer, data);
 
 	adapter_update_found_devices(adapter, peer, class, rssi,
-						data, EIR_DATA_LENGTH);
+						data, HCI_MAX_EIR_LENGTH);
 }
 
 void btd_event_set_legacy_pairing(bdaddr_t *local, bdaddr_t *peer,
-- 
1.7.5.rc3


^ permalink raw reply related

* [PATCH v3 10/12] Cleanup inserting new device found entry
From: Claudio Takahasi @ 2011-05-16 20:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1305579001-3019-1-git-send-email-claudio.takahasi@openbossa.org>

---
 src/adapter.c |   97 +++++++++++++++++++++++++++-----------------------------
 1 files changed, 47 insertions(+), 50 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 6d5fdc9..f4359f9 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2914,29 +2914,24 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
 	g_free(alias);
 }
 
-static struct remote_dev_info *get_found_dev(struct btd_adapter *adapter,
-						const bdaddr_t *bdaddr,
-						gboolean *new_dev)
+static struct remote_dev_info *found_device_new(const bdaddr_t *bdaddr,
+					gboolean le, const char *name,
+					const char *alias, uint32_t class,
+					gboolean legacy, name_status_t status,
+					int flags)
 {
-	struct remote_dev_info *dev, match;
+	struct remote_dev_info *dev;
 
-	memset(&match, 0, sizeof(struct remote_dev_info));
-	bacpy(&match.bdaddr, bdaddr);
-	match.name_status = NAME_ANY;
-
-	dev = adapter_search_found_devices(adapter, &match);
-	if (dev) {
-		*new_dev = FALSE;
-		/* Out of range list update */
-		adapter->oor_devices = g_slist_remove(adapter->oor_devices,
-							dev);
-	} else {
-		*new_dev = TRUE;
-		dev = g_new0(struct remote_dev_info, 1);
-		bacpy(&dev->bdaddr, bdaddr);
-		adapter->found_devices = g_slist_prepend(adapter->found_devices,
-									dev);
-	}
+	dev = g_new0(struct remote_dev_info, 1);
+	bacpy(&dev->bdaddr, bdaddr);
+	dev->le = le;
+	dev->name = g_strdup(name);
+	dev->alias = g_strdup(alias);
+	dev->class = class;
+	dev->legacy = legacy;
+	dev->name_status = status;
+	if (flags >= 0)
+		dev->flags = flags;
 
 	return dev;
 }
@@ -3007,11 +3002,11 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 					uint32_t class, int8_t rssi,
 					uint8_t *data, size_t eir_size)
 {
-	struct remote_dev_info *dev;
+	struct remote_dev_info *dev, match;
 	struct eir_data eir_data;
-	char *name;
-	gboolean new_dev, legacy, le;
-	name_status_t name_status = NAME_NOT_REQUIRED;
+	char *alias, *name;
+	gboolean legacy, le;
+	name_status_t name_status;
 	int err;
 
 	memset(&eir_data, 0, sizeof(eir_data));
@@ -3024,6 +3019,25 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 	if (eir_data.name != NULL && eir_data.name_complete)
 		write_device_name(&adapter->bdaddr, bdaddr, eir_data.name);
 
+	/* Device already seen in the discovery session ? */
+	memset(&match, 0, sizeof(struct remote_dev_info));
+	bacpy(&match.bdaddr, bdaddr);
+	match.name_status = NAME_ANY;
+
+	dev = adapter_search_found_devices(adapter, &match);
+	if (dev) {
+		adapter->oor_devices = g_slist_remove(adapter->oor_devices,
+							dev);
+		if (dev->rssi != rssi)
+			goto done;
+
+		eir_data_free(&eir_data);
+
+		return;
+	}
+
+	/* New device in the discovery session */
+
 	name = read_stored_data(&adapter->bdaddr, bdaddr, "names");
 
 	if (eir_data.flags < 0) {
@@ -3042,34 +3056,19 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 	} else {
 		le = TRUE;
 		legacy = FALSE;
+		name_status = NAME_NOT_REQUIRED;
 	}
 
-	dev = get_found_dev(adapter, bdaddr, &new_dev);
-
-	if (new_dev) {
-		const char *dev_name = (name ? name : eir_data.name);
-		char *alias;
+	alias = read_stored_data(&adapter->bdaddr, bdaddr, "aliases");
 
-		if (dev_name)
-			dev->name = g_strdup(dev_name);
-
-		alias = read_stored_data(&adapter->bdaddr, bdaddr, "aliases");
-		if (alias) {
-			dev->alias = g_strdup(alias);
-			free(alias);
-		}
-
-		dev->le = FALSE;
-		dev->class = class;
-		dev->legacy = legacy;
-		dev->name_status = name_status;
+	dev = found_device_new(bdaddr, le, name, alias, class, legacy,
+						name_status, eir_data.flags);
+	free(name);
+	free(alias);
 
-		if (eir_data.flags >= 0)
-			dev->flags = eir_data.flags;
-
-	} else if (dev->rssi == rssi)
-		goto done;
+	adapter->found_devices = g_slist_prepend(adapter->found_devices, dev);
 
+done:
 	dev->rssi = rssi;
 
 	adapter->found_devices = g_slist_sort(adapter->found_devices,
@@ -3080,8 +3079,6 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 
 	adapter_emit_device_found(adapter, dev);
 
-done:
-	free(name);
 	eir_data_free(&eir_data);
 }
 
-- 
1.7.5.rc3


^ permalink raw reply related

* [PATCH v3 09/12] Change the order to write/read the remote's name
From: Claudio Takahasi @ 2011-05-16 20:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1305579001-3019-1-git-send-email-claudio.takahasi@openbossa.org>

When discovering, write the EIR "complete" name first before to read
the name. Only names retrieved from EIR "complete" name and HCI Remote
Name Request Complete event are stored. This patch doesn't change the
final result: the value of the name sent in the signal.
---
 src/adapter.c |   19 +++++--------------
 1 files changed, 5 insertions(+), 14 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index a274f26..6d5fdc9 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3012,7 +3012,6 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 	char *name;
 	gboolean new_dev, legacy, le;
 	name_status_t name_status = NAME_NOT_REQUIRED;
-	const char *dev_name;
 	int err;
 
 	memset(&eir_data, 0, sizeof(eir_data));
@@ -3022,6 +3021,9 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 		return;
 	}
 
+	if (eir_data.name != NULL && eir_data.name_complete)
+		write_device_name(&adapter->bdaddr, bdaddr, eir_data.name);
+
 	name = read_stored_data(&adapter->bdaddr, bdaddr, "names");
 
 	if (eir_data.flags < 0) {
@@ -3042,23 +3044,12 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 		legacy = FALSE;
 	}
 
-	/* Complete EIR names are always used. Shortened EIR names are only
-	 * used if there is no name already in storage. */
-	dev_name = name;
-	if (eir_data.name != NULL) {
-		if (eir_data.name_complete) {
-			write_device_name(&adapter->bdaddr, bdaddr,
-							eir_data.name);
-			name_status = NAME_NOT_REQUIRED;
-			dev_name = eir_data.name;
-		} else if (name == NULL)
-			dev_name = eir_data.name;
-	}
-
 	dev = get_found_dev(adapter, bdaddr, &new_dev);
 
 	if (new_dev) {
+		const char *dev_name = (name ? name : eir_data.name);
 		char *alias;
+
 		if (dev_name)
 			dev->name = g_strdup(dev_name);
 
-- 
1.7.5.rc3


^ permalink raw reply related

* [PATCH v3 08/12] Remove btd_event_advertising_report
From: Claudio Takahasi @ 2011-05-16 20:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1305579001-3019-1-git-send-email-claudio.takahasi@openbossa.org>

From: Bruna Moreira <bruna.moreira@openbossa.org>

Advertises should be notified using btd_event_device_found function
to keep the compatibility with mgmtops plugin.
---
 plugins/hciops.c |   13 ++++++++++---
 src/event.c      |   17 -----------------
 src/event.h      |    1 -
 3 files changed, 10 insertions(+), 21 deletions(-)

diff --git a/plugins/hciops.c b/plugins/hciops.c
index 07643a1..65ad4f3 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -2171,19 +2171,26 @@ static inline void le_advertising_report(int index, evt_le_meta_event *meta)
 {
 	struct dev_info *dev = &devs[index];
 	le_advertising_info *info;
-	uint8_t num_reports;
+	uint8_t num_reports, rssi;
 	const uint8_t RSSI_SIZE = 1;
 
 	num_reports = meta->data[0];
 
 	info = (le_advertising_info *) &meta->data[1];
-	btd_event_advertising_report(&dev->bdaddr, info);
+	rssi = *(info->data + info->length);
+
+	btd_event_device_found(&dev->bdaddr, &info->bdaddr, 0, rssi,
+								info->data);
+
 	num_reports--;
 
 	while (num_reports--) {
 		info = (le_advertising_info *) (info->data + info->length +
 								RSSI_SIZE);
-		btd_event_advertising_report(&dev->bdaddr, info);
+		rssi = *(info->data + info->length);
+
+		btd_event_device_found(&dev->bdaddr, &info->bdaddr, 0, rssi,
+								info->data);
 	}
 }
 
diff --git a/src/event.c b/src/event.c
index 115b285..3ee8802 100644
--- a/src/event.c
+++ b/src/event.c
@@ -281,23 +281,6 @@ void btd_event_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer,
 	device_simple_pairing_complete(device, status);
 }
 
-void btd_event_advertising_report(bdaddr_t *local, le_advertising_info *info)
-{
-	struct btd_adapter *adapter;
-	int8_t rssi;
-
-	adapter = manager_find_adapter(local);
-	if (adapter == NULL) {
-		error("No matching adapter found");
-		return;
-	}
-
-	rssi = *(info->data + info->length);
-
-	adapter_update_found_devices(adapter, &info->bdaddr, 0, rssi,
-						info->data, info->length);
-}
-
 static void update_lastseen(bdaddr_t *sba, bdaddr_t *dba)
 {
 	time_t t;
diff --git a/src/event.h b/src/event.h
index 005d8a7..22c199e 100644
--- a/src/event.h
+++ b/src/event.h
@@ -23,7 +23,6 @@
  */
 
 int btd_event_request_pin(bdaddr_t *sba, bdaddr_t *dba);
-void btd_event_advertising_report(bdaddr_t *local, le_advertising_info *info);
 void btd_event_device_found(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
 						int8_t rssi, uint8_t *data);
 void btd_event_set_legacy_pairing(bdaddr_t *local, bdaddr_t *peer, gboolean legacy);
-- 
1.7.5.rc3


^ permalink raw reply related

* [PATCH v3 07/12] Fix memory leak of EIR data
From: Claudio Takahasi @ 2011-05-16 20:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1305579001-3019-1-git-send-email-claudio.takahasi@openbossa.org>

---
 src/adapter.c |    1 +
 src/eir.c     |    7 +++++++
 src/eir.h     |    1 +
 3 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 556a537..a274f26 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3091,6 +3091,7 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 
 done:
 	free(name);
+	eir_data_free(&eir_data);
 }
 
 int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr)
diff --git a/src/eir.c b/src/eir.c
index d827c7e..2fbd919 100644
--- a/src/eir.c
+++ b/src/eir.c
@@ -44,6 +44,13 @@
 #define EIR_TX_POWER                0x0A  /* transmit power level */
 #define EIR_DEVICE_ID               0x10  /* device ID */
 
+void eir_data_free(struct eir_data *eir)
+{
+	g_slist_foreach(eir->services, (GFunc) g_free, NULL);
+	g_slist_free(eir->services);
+	g_free(eir->name);
+}
+
 int eir_parse(struct eir_data *eir, uint8_t *eir_data, size_t eir_length)
 {
 	uint16_t len = 0;
diff --git a/src/eir.h b/src/eir.h
index c7699eb..aacd16a 100644
--- a/src/eir.h
+++ b/src/eir.h
@@ -36,6 +36,7 @@ struct eir_data {
 	gboolean name_complete;
 };
 
+void eir_data_free(struct eir_data *eir);
 int eir_parse(struct eir_data *eir, uint8_t *eir_data, size_t eir_length);
 void eir_create(const char *name, int8_t tx_power, uint16_t did_vendor,
 			uint16_t did_product, uint16_t did_version,
-- 
1.7.5.rc3


^ permalink raw reply related

* [PATCH v3 06/12] Unify inquiry results and advertises
From: Claudio Takahasi @ 2011-05-16 20:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1305579001-3019-1-git-send-email-claudio.takahasi@openbossa.org>

Adapter needs to have only one method to allow discovery results
integration for both interfaces: hciops and mgmtops. This patch
moves the code related to advertises parsing to the same function
that handles inquiry results.
---
 src/adapter.c |   75 +++++++++++++++++++-------------------------------------
 src/adapter.h |    7 +----
 src/event.c   |   25 +++----------------
 3 files changed, 32 insertions(+), 75 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index e91ab81..556a537 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2966,42 +2966,6 @@ static void dev_prepend_uuid(gpointer data, gpointer user_data)
 	dev->services = g_slist_prepend(dev->services, g_strdup(new_uuid));
 }
 
-void adapter_update_device_from_info(struct btd_adapter *adapter,
-					bdaddr_t bdaddr, int8_t rssi,
-					const char *name, GSList *services,
-					int flags)
-{
-	struct remote_dev_info *dev;
-	gboolean new_dev;
-
-	dev = get_found_dev(adapter, &bdaddr, &new_dev);
-
-	if (new_dev)
-		dev->le = TRUE;
-	else if (dev->rssi == rssi)
-		return;
-
-	dev->rssi = rssi;
-
-	adapter->found_devices = g_slist_sort(adapter->found_devices,
-						(GCompareFunc) dev_rssi_cmp);
-
-	g_slist_foreach(services, remove_same_uuid, dev);
-	g_slist_foreach(services, dev_prepend_uuid, dev);
-
-	if (flags >= 0)
-		dev->flags = flags;
-
-	if (name) {
-		g_free(dev->name);
-		dev->name = g_strdup(name);
-	}
-
-	/* FIXME: check if other information was changed before emitting the
-	 * signal */
-	adapter_emit_device_found(adapter, dev);
-}
-
 static int pairing_is_legacy(bdaddr_t *local, bdaddr_t *peer, gboolean eir,
 					gboolean name, gboolean *legacy)
 {
@@ -3040,13 +3004,14 @@ static char *read_stored_data(bdaddr_t *local, bdaddr_t *peer, const char *file)
 }
 
 void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
-				uint32_t class, int8_t rssi, uint8_t *data)
+					uint32_t class, int8_t rssi,
+					uint8_t *data, size_t eir_size)
 {
 	struct remote_dev_info *dev;
 	struct eir_data eir_data;
 	char *name;
-	gboolean new_dev, legacy;
-	name_status_t name_status;
+	gboolean new_dev, legacy, le;
+	name_status_t name_status = NAME_NOT_REQUIRED;
 	const char *dev_name;
 	int err;
 
@@ -3058,16 +3023,24 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 	}
 
 	name = read_stored_data(&adapter->bdaddr, bdaddr, "names");
-	if (pairing_is_legacy(&adapter->bdaddr, bdaddr,
-				data ? TRUE : FALSE, name ? TRUE : FALSE,
-				&legacy) < 0)
-		legacy = TRUE;
-
-	if (!name && main_opts.name_resolv &&
-			adapter_has_discov_sessions(adapter))
-		name_status = NAME_REQUIRED;
-	else
-		name_status = NAME_NOT_REQUIRED;
+
+	if (eir_data.flags < 0) {
+		le = FALSE;
+
+		if (pairing_is_legacy(&adapter->bdaddr, bdaddr,
+					data ? TRUE : FALSE,
+					name ? TRUE : FALSE, &legacy) < 0)
+			legacy = TRUE;
+
+		if (!name && main_opts.name_resolv &&
+				adapter_has_discov_sessions(adapter))
+			name_status = NAME_REQUIRED;
+		else
+			name_status = NAME_NOT_REQUIRED;
+	} else {
+		le = TRUE;
+		legacy = FALSE;
+	}
 
 	/* Complete EIR names are always used. Shortened EIR names are only
 	 * used if there is no name already in storage. */
@@ -3099,6 +3072,10 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 		dev->class = class;
 		dev->legacy = legacy;
 		dev->name_status = name_status;
+
+		if (eir_data.flags >= 0)
+			dev->flags = eir_data.flags;
+
 	} else if (dev->rssi == rssi)
 		goto done;
 
diff --git a/src/adapter.h b/src/adapter.h
index 4785d5c..4c07e92 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -108,12 +108,9 @@ int adapter_get_state(struct btd_adapter *adapter);
 int adapter_get_discover_type(struct btd_adapter *adapter);
 struct remote_dev_info *adapter_search_found_devices(struct btd_adapter *adapter,
 						struct remote_dev_info *match);
-void adapter_update_device_from_info(struct btd_adapter *adapter,
-					bdaddr_t bdaddr, int8_t rssi,
-					const char *name, GSList *services,
-					int flags);
 void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
-				uint32_t class, int8_t rssi, uint8_t *data);
+					uint32_t class, int8_t rssi,
+					uint8_t *data, size_t eir_size);
 int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr);
 void adapter_emit_device_found(struct btd_adapter *adapter,
 						struct remote_dev_info *dev);
diff --git a/src/event.c b/src/event.c
index 2c893f0..115b285 100644
--- a/src/event.c
+++ b/src/event.c
@@ -281,19 +281,10 @@ void btd_event_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer,
 	device_simple_pairing_complete(device, status);
 }
 
-static void free_eir_data(struct eir_data *eir)
-{
-	g_slist_foreach(eir->services, (GFunc) g_free, NULL);
-	g_slist_free(eir->services);
-	g_free(eir->name);
-}
-
 void btd_event_advertising_report(bdaddr_t *local, le_advertising_info *info)
 {
 	struct btd_adapter *adapter;
-	struct eir_data eir_data;
 	int8_t rssi;
-	int err;
 
 	adapter = manager_find_adapter(local);
 	if (adapter == NULL) {
@@ -301,19 +292,10 @@ void btd_event_advertising_report(bdaddr_t *local, le_advertising_info *info)
 		return;
 	}
 
-	memset(&eir_data, 0, sizeof(eir_data));
-	err = eir_parse(&eir_data, info->data, info->length);
-	if (err < 0)
-		error("Error parsing advertising data: %s (%d)",
-							strerror(-err), -err);
-
 	rssi = *(info->data + info->length);
 
-	adapter_update_device_from_info(adapter, info->bdaddr, rssi,
-					eir_data.name, eir_data.services,
-					eir_data.flags);
-
-	free_eir_data(&eir_data);
+	adapter_update_found_devices(adapter, &info->bdaddr, 0, rssi,
+						info->data, info->length);
 }
 
 static void update_lastseen(bdaddr_t *sba, bdaddr_t *dba)
@@ -355,7 +337,8 @@ void btd_event_device_found(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
 	if (data)
 		write_remote_eir(local, peer, data);
 
-	adapter_update_found_devices(adapter, peer, class, rssi, data);
+	adapter_update_found_devices(adapter, peer, class, rssi,
+						data, EIR_DATA_LENGTH);
 }
 
 void btd_event_set_legacy_pairing(bdaddr_t *local, bdaddr_t *peer,
-- 
1.7.5.rc3


^ permalink raw reply related

* [PATCH v3 05/12] Don't resolve name if the name is in the storage
From: Claudio Takahasi @ 2011-05-16 20:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1305579001-3019-1-git-send-email-claudio.takahasi@openbossa.org>

---
 src/adapter.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 701558c..e91ab81 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3057,18 +3057,18 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 		return;
 	}
 
-	/* the inquiry result can be triggered by NON D-Bus client */
-	if (main_opts.name_resolv && adapter_has_discov_sessions(adapter))
-		name_status = NAME_REQUIRED;
-	else
-		name_status = NAME_NOT_REQUIRED;
-
 	name = read_stored_data(&adapter->bdaddr, bdaddr, "names");
 	if (pairing_is_legacy(&adapter->bdaddr, bdaddr,
 				data ? TRUE : FALSE, name ? TRUE : FALSE,
 				&legacy) < 0)
 		legacy = TRUE;
 
+	if (!name && main_opts.name_resolv &&
+			adapter_has_discov_sessions(adapter))
+		name_status = NAME_REQUIRED;
+	else
+		name_status = NAME_NOT_REQUIRED;
+
 	/* Complete EIR names are always used. Shortened EIR names are only
 	 * used if there is no name already in storage. */
 	dev_name = name;
-- 
1.7.5.rc3


^ permalink raw reply related

* [PATCH v3 04/12] Cleanup read name and alias from storage
From: Claudio Takahasi @ 2011-05-16 20:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1305579001-3019-1-git-send-email-claudio.takahasi@openbossa.org>

---
 src/adapter.c |   36 +++++++++++++++++++++++-------------
 1 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 6f85abf..701558c 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3027,13 +3027,24 @@ static int pairing_is_legacy(bdaddr_t *local, bdaddr_t *peer, gboolean eir,
 	return 0;
 }
 
+static char *read_stored_data(bdaddr_t *local, bdaddr_t *peer, const char *file)
+{
+	char local_addr[18], peer_addr[18], filename[PATH_MAX + 1];
+
+	ba2str(local, local_addr);
+	ba2str(peer, peer_addr);
+
+	create_name(filename, PATH_MAX, STORAGEDIR, local_addr, file);
+
+	return textfile_get(filename, peer_addr);
+}
+
 void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 				uint32_t class, int8_t rssi, uint8_t *data)
 {
-	char local_addr[18], peer_addr[18], filename[PATH_MAX + 1];
 	struct remote_dev_info *dev;
 	struct eir_data eir_data;
-	char *alias, *name;
+	char *name;
 	gboolean new_dev, legacy;
 	name_status_t name_status;
 	const char *dev_name;
@@ -3052,15 +3063,7 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 	else
 		name_status = NAME_NOT_REQUIRED;
 
-	ba2str(&adapter->bdaddr, local_addr);
-	ba2str(bdaddr, peer_addr);
-
-	create_name(filename, PATH_MAX, STORAGEDIR, local_addr, "aliases");
-	alias = textfile_get(filename, peer_addr);
-
-	create_name(filename, PATH_MAX, STORAGEDIR, local_addr, "names");
-	name = textfile_get(filename, peer_addr);
-
+	name = read_stored_data(&adapter->bdaddr, bdaddr, "names");
 	if (pairing_is_legacy(&adapter->bdaddr, bdaddr,
 				data ? TRUE : FALSE, name ? TRUE : FALSE,
 				&legacy) < 0)
@@ -3082,18 +3085,22 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 	dev = get_found_dev(adapter, bdaddr, &new_dev);
 
 	if (new_dev) {
+		char *alias;
 		if (dev_name)
 			dev->name = g_strdup(dev_name);
 
-		if (alias)
+		alias = read_stored_data(&adapter->bdaddr, bdaddr, "aliases");
+		if (alias) {
 			dev->alias = g_strdup(alias);
+			free(alias);
+		}
 
 		dev->le = FALSE;
 		dev->class = class;
 		dev->legacy = legacy;
 		dev->name_status = name_status;
 	} else if (dev->rssi == rssi)
-		return;
+		goto done;
 
 	dev->rssi = rssi;
 
@@ -3104,6 +3111,9 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 	g_slist_foreach(eir_data.services, dev_prepend_uuid, dev);
 
 	adapter_emit_device_found(adapter, dev);
+
+done:
+	free(name);
 }
 
 int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr)
-- 
1.7.5.rc3


^ permalink raw reply related

* [PATCH v3 03/12] Move legacy verification to a new function
From: Claudio Takahasi @ 2011-05-16 20:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1305579001-3019-1-git-send-email-claudio.takahasi@openbossa.org>

---
 src/adapter.c |   40 ++++++++++++++++++++++++++++------------
 1 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 3188974..6f85abf 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3002,6 +3002,31 @@ void adapter_update_device_from_info(struct btd_adapter *adapter,
 	adapter_emit_device_found(adapter, dev);
 }
 
+static int pairing_is_legacy(bdaddr_t *local, bdaddr_t *peer, gboolean eir,
+					gboolean name, gboolean *legacy)
+{
+	unsigned char features[8];
+	int err;
+
+	if (eir) {
+		*legacy = FALSE;
+		return 0;
+	}
+
+	if (name == FALSE) {
+		*legacy = TRUE;
+		return 0;
+	}
+
+	err = read_remote_features(local, peer, NULL, features);
+	if (err < 0)
+		return err;
+
+	*legacy = (features[0] & 0x01 ? FALSE : TRUE);
+
+	return 0;
+}
+
 void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 				uint32_t class, int8_t rssi, uint8_t *data)
 {
@@ -3011,7 +3036,6 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 	char *alias, *name;
 	gboolean new_dev, legacy;
 	name_status_t name_status;
-	unsigned char features[8];
 	const char *dev_name;
 	int err;
 
@@ -3037,17 +3061,9 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 	create_name(filename, PATH_MAX, STORAGEDIR, local_addr, "names");
 	name = textfile_get(filename, peer_addr);
 
-	if (data)
-		legacy = FALSE;
-	else if (name == NULL)
-		legacy = TRUE;
-	else if (read_remote_features(&adapter->bdaddr, bdaddr, NULL,
-							features) == 0) {
-		if (features[0] & 0x01)
-			legacy = FALSE;
-		else
-			legacy = TRUE;
-	} else
+	if (pairing_is_legacy(&adapter->bdaddr, bdaddr,
+				data ? TRUE : FALSE, name ? TRUE : FALSE,
+				&legacy) < 0)
 		legacy = TRUE;
 
 	/* Complete EIR names are always used. Shortened EIR names are only
-- 
1.7.5.rc3


^ permalink raw reply related

* [PATCH v3 02/12] Initial device found cleanup
From: Claudio Takahasi @ 2011-05-16 20:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1305579001-3019-1-git-send-email-claudio.takahasi@openbossa.org>

Moves EIR parsing call and stored name loading to adapter. This patch
doesn't change the implemented logic, it is only the initial step to
integrated inquiry results and LE advertises.
---
 src/adapter.c |   70 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 src/adapter.h |    4 +--
 src/event.c   |   60 +------------------------------------------------
 3 files changed, 64 insertions(+), 70 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index a85980c..3188974 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -58,6 +58,7 @@
 #include "storage.h"
 #include "attrib-server.h"
 #include "att.h"
+#include "eir.h"
 
 /* Flags Descriptions */
 #define EIR_LIM_DISC                0x01 /* LE Limited Discoverable Mode */
@@ -3002,18 +3003,71 @@ void adapter_update_device_from_info(struct btd_adapter *adapter,
 }
 
 void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
-				int8_t rssi, uint32_t class, const char *name,
-				const char *alias, gboolean legacy,
-				GSList *services, name_status_t name_status)
+				uint32_t class, int8_t rssi, uint8_t *data)
 {
+	char local_addr[18], peer_addr[18], filename[PATH_MAX + 1];
 	struct remote_dev_info *dev;
-	gboolean new_dev;
+	struct eir_data eir_data;
+	char *alias, *name;
+	gboolean new_dev, legacy;
+	name_status_t name_status;
+	unsigned char features[8];
+	const char *dev_name;
+	int err;
+
+	memset(&eir_data, 0, sizeof(eir_data));
+	err = eir_parse(&eir_data, data, EIR_DATA_LENGTH);
+	if (err < 0) {
+		error("Error parsing EIR data: %s (%d)", strerror(-err), -err);
+		return;
+	}
+
+	/* the inquiry result can be triggered by NON D-Bus client */
+	if (main_opts.name_resolv && adapter_has_discov_sessions(adapter))
+		name_status = NAME_REQUIRED;
+	else
+		name_status = NAME_NOT_REQUIRED;
+
+	ba2str(&adapter->bdaddr, local_addr);
+	ba2str(bdaddr, peer_addr);
+
+	create_name(filename, PATH_MAX, STORAGEDIR, local_addr, "aliases");
+	alias = textfile_get(filename, peer_addr);
+
+	create_name(filename, PATH_MAX, STORAGEDIR, local_addr, "names");
+	name = textfile_get(filename, peer_addr);
+
+	if (data)
+		legacy = FALSE;
+	else if (name == NULL)
+		legacy = TRUE;
+	else if (read_remote_features(&adapter->bdaddr, bdaddr, NULL,
+							features) == 0) {
+		if (features[0] & 0x01)
+			legacy = FALSE;
+		else
+			legacy = TRUE;
+	} else
+		legacy = TRUE;
+
+	/* Complete EIR names are always used. Shortened EIR names are only
+	 * used if there is no name already in storage. */
+	dev_name = name;
+	if (eir_data.name != NULL) {
+		if (eir_data.name_complete) {
+			write_device_name(&adapter->bdaddr, bdaddr,
+							eir_data.name);
+			name_status = NAME_NOT_REQUIRED;
+			dev_name = eir_data.name;
+		} else if (name == NULL)
+			dev_name = eir_data.name;
+	}
 
 	dev = get_found_dev(adapter, bdaddr, &new_dev);
 
 	if (new_dev) {
-		if (name)
-			dev->name = g_strdup(name);
+		if (dev_name)
+			dev->name = g_strdup(dev_name);
 
 		if (alias)
 			dev->alias = g_strdup(alias);
@@ -3030,8 +3084,8 @@ void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 	adapter->found_devices = g_slist_sort(adapter->found_devices,
 						(GCompareFunc) dev_rssi_cmp);
 
-	g_slist_foreach(services, remove_same_uuid, dev);
-	g_slist_foreach(services, dev_prepend_uuid, dev);
+	g_slist_foreach(eir_data.services, remove_same_uuid, dev);
+	g_slist_foreach(eir_data.services, dev_prepend_uuid, dev);
 
 	adapter_emit_device_found(adapter, dev);
 }
diff --git a/src/adapter.h b/src/adapter.h
index 51e8c30..4785d5c 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -113,9 +113,7 @@ void adapter_update_device_from_info(struct btd_adapter *adapter,
 					const char *name, GSList *services,
 					int flags);
 void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
-				int8_t rssi, uint32_t class, const char *name,
-				const char *alias, gboolean legacy,
-				GSList *services, name_status_t name_status);
+				uint32_t class, int8_t rssi, uint8_t *data);
 int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr);
 void adapter_emit_device_found(struct btd_adapter *adapter,
 						struct remote_dev_info *dev);
diff --git a/src/event.c b/src/event.c
index dc1b659..2c893f0 100644
--- a/src/event.c
+++ b/src/event.c
@@ -341,18 +341,7 @@ static void update_lastused(bdaddr_t *sba, bdaddr_t *dba)
 void btd_event_device_found(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
 				int8_t rssi, uint8_t *data)
 {
-	char filename[PATH_MAX + 1];
 	struct btd_adapter *adapter;
-	char local_addr[18], peer_addr[18], *alias, *name;
-	name_status_t name_status;
-	struct eir_data eir_data;
-	int err;
-	dbus_bool_t legacy;
-	unsigned char features[8];
-	const char *dev_name;
-
-	ba2str(local, local_addr);
-	ba2str(peer, peer_addr);
 
 	adapter = manager_find_adapter(local);
 	if (!adapter) {
@@ -366,54 +355,7 @@ void btd_event_device_found(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
 	if (data)
 		write_remote_eir(local, peer, data);
 
-	/* the inquiry result can be triggered by NON D-Bus client */
-	if (main_opts.name_resolv && adapter_has_discov_sessions(adapter))
-		name_status = NAME_REQUIRED;
-	else
-		name_status = NAME_NOT_REQUIRED;
-
-	create_name(filename, PATH_MAX, STORAGEDIR, local_addr, "aliases");
-	alias = textfile_get(filename, peer_addr);
-
-	create_name(filename, PATH_MAX, STORAGEDIR, local_addr, "names");
-	name = textfile_get(filename, peer_addr);
-
-	if (data)
-		legacy = FALSE;
-	else if (name == NULL)
-		legacy = TRUE;
-	else if (read_remote_features(local, peer, NULL, features) == 0) {
-		if (features[0] & 0x01)
-			legacy = FALSE;
-		else
-			legacy = TRUE;
-	} else
-		legacy = TRUE;
-
-	memset(&eir_data, 0, sizeof(eir_data));
-	err = eir_parse(&eir_data, data, EIR_DATA_LENGTH);
-	if (err < 0)
-		error("Error parsing EIR data: %s (%d)", strerror(-err), -err);
-
-	/* Complete EIR names are always used. Shortened EIR names are only
-	 * used if there is no name already in storage. */
-	dev_name = name;
-	if (eir_data.name != NULL) {
-		if (eir_data.name_complete) {
-			write_device_name(local, peer, eir_data.name);
-			name_status = NAME_NOT_REQUIRED;
-			dev_name = eir_data.name;
-		} else if (name == NULL)
-			dev_name = eir_data.name;
-	}
-
-	adapter_update_found_devices(adapter, peer, rssi, class, dev_name,
-					alias, legacy, eir_data.services,
-					name_status);
-
-	free_eir_data(&eir_data);
-	free(name);
-	free(alias);
+	adapter_update_found_devices(adapter, peer, class, rssi, data);
 }
 
 void btd_event_set_legacy_pairing(bdaddr_t *local, bdaddr_t *peer,
-- 
1.7.5.rc3


^ permalink raw reply related

* [PATCH v3 01/12] Move EIR related functions to a new file
From: Claudio Takahasi @ 2011-05-16 20:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 Makefile.am      |    2 +-
 plugins/hciops.c |  170 +----------------------------
 src/eir.c        |  320 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/eir.h        |   42 +++++++
 src/event.c      |  126 +---------------------
 src/sdpd.h       |   14 ---
 6 files changed, 369 insertions(+), 305 deletions(-)
 create mode 100644 src/eir.c
 create mode 100644 src/eir.h

diff --git a/Makefile.am b/Makefile.am
index caffbe2..175f8c9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -251,7 +251,7 @@ src_bluetoothd_SOURCES = $(gdbus_sources) $(builtin_sources) \
 			src/device.h src/device.c \
 			src/dbus-common.c src/dbus-common.h \
 			src/event.h src/event.c \
-			src/oob.h src/oob.c
+			src/oob.h src/oob.c src/eir.h src/eir.c
 src_bluetoothd_LDADD = lib/libbluetooth.la @GLIB_LIBS@ @DBUS_LIBS@ \
 							@CAPNG_LIBS@ -ldl -lrt
 src_bluetoothd_LDFLAGS = -Wl,--export-dynamic \
diff --git a/plugins/hciops.c b/plugins/hciops.c
index af638c8..07643a1 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -51,6 +51,7 @@
 #include "event.h"
 #include "manager.h"
 #include "oob.h"
+#include "eir.h"
 
 #define DISCOV_HALTED 0
 #define DISCOV_INQ 1
@@ -84,11 +85,6 @@ enum {
 	PENDING_NAME,
 };
 
-struct uuid_info {
-	uuid_t uuid;
-	uint8_t svc_hint;
-};
-
 struct bt_conn {
 	struct dev_info *dev;
 	bdaddr_t bdaddr;
@@ -1435,167 +1431,6 @@ static void read_local_features_complete(int index,
 		init_adapter(index);
 }
 
-#define SIZEOF_UUID128 16
-
-static void eir_generate_uuid128(GSList *list, uint8_t *ptr, uint16_t *eir_len)
-{
-	int i, k, uuid_count = 0;
-	uint16_t len = *eir_len;
-	uint8_t *uuid128;
-	gboolean truncated = FALSE;
-
-	/* Store UUIDs in place, skip 2 bytes to write type and length later */
-	uuid128 = ptr + 2;
-
-	for (; list; list = list->next) {
-		struct uuid_info *uuid = list->data;
-		uint8_t *uuid128_data = uuid->uuid.value.uuid128.data;
-
-		if (uuid->uuid.type != SDP_UUID128)
-			continue;
-
-		/* Stop if not enough space to put next UUID128 */
-		if ((len + 2 + SIZEOF_UUID128) > EIR_DATA_LENGTH) {
-			truncated = TRUE;
-			break;
-		}
-
-		/* Check for duplicates, EIR data is Little Endian */
-		for (i = 0; i < uuid_count; i++) {
-			for (k = 0; k < SIZEOF_UUID128; k++) {
-				if (uuid128[i * SIZEOF_UUID128 + k] !=
-					uuid128_data[SIZEOF_UUID128 - 1 - k])
-					break;
-			}
-			if (k == SIZEOF_UUID128)
-				break;
-		}
-
-		if (i < uuid_count)
-			continue;
-
-		/* EIR data is Little Endian */
-		for (k = 0; k < SIZEOF_UUID128; k++)
-			uuid128[uuid_count * SIZEOF_UUID128 + k] =
-				uuid128_data[SIZEOF_UUID128 - 1 - k];
-
-		len += SIZEOF_UUID128;
-		uuid_count++;
-	}
-
-	if (uuid_count > 0 || truncated) {
-		/* EIR Data length */
-		ptr[0] = (uuid_count * SIZEOF_UUID128) + 1;
-		/* EIR Data type */
-		ptr[1] = truncated ? EIR_UUID128_SOME : EIR_UUID128_ALL;
-		len += 2;
-		*eir_len = len;
-	}
-}
-
-static void create_ext_inquiry_response(int index, uint8_t *data)
-{
-	struct dev_info *dev = &devs[index];
-	GSList *l;
-	uint8_t *ptr = data;
-	uint16_t eir_len = 0;
-	uint16_t uuid16[EIR_DATA_LENGTH / 2];
-	int i, uuid_count = 0;
-	gboolean truncated = FALSE;
-	size_t name_len;
-
-	name_len = strlen(dev->name);
-
-	if (name_len > 0) {
-		/* EIR Data type */
-		if (name_len > 48) {
-			name_len = 48;
-			ptr[1] = EIR_NAME_SHORT;
-		} else
-			ptr[1] = EIR_NAME_COMPLETE;
-
-		/* EIR Data length */
-		ptr[0] = name_len + 1;
-
-		memcpy(ptr + 2, dev->name, name_len);
-
-		eir_len += (name_len + 2);
-		ptr += (name_len + 2);
-	}
-
-	if (dev->tx_power != 0) {
-		*ptr++ = 2;
-		*ptr++ = EIR_TX_POWER;
-		*ptr++ = (uint8_t) dev->tx_power;
-		eir_len += 3;
-	}
-
-	if (dev->did_vendor != 0x0000) {
-		uint16_t source = 0x0002;
-		*ptr++ = 9;
-		*ptr++ = EIR_DEVICE_ID;
-		*ptr++ = (source & 0x00ff);
-		*ptr++ = (source & 0xff00) >> 8;
-		*ptr++ = (dev->did_vendor & 0x00ff);
-		*ptr++ = (dev->did_vendor & 0xff00) >> 8;
-		*ptr++ = (dev->did_product & 0x00ff);
-		*ptr++ = (dev->did_product & 0xff00) >> 8;
-		*ptr++ = (dev->did_version & 0x00ff);
-		*ptr++ = (dev->did_version & 0xff00) >> 8;
-		eir_len += 10;
-	}
-
-	/* Group all UUID16 types */
-	for (l = dev->uuids; l != NULL; l = g_slist_next(l)) {
-		struct uuid_info *uuid = l->data;
-
-		if (uuid->uuid.type != SDP_UUID16)
-			continue;
-
-		if (uuid->uuid.value.uuid16 < 0x1100)
-			continue;
-
-		if (uuid->uuid.value.uuid16 == PNP_INFO_SVCLASS_ID)
-			continue;
-
-		/* Stop if not enough space to put next UUID16 */
-		if ((eir_len + 2 + sizeof(uint16_t)) > EIR_DATA_LENGTH) {
-			truncated = TRUE;
-			break;
-		}
-
-		/* Check for duplicates */
-		for (i = 0; i < uuid_count; i++)
-			if (uuid16[i] == uuid->uuid.value.uuid16)
-				break;
-
-		if (i < uuid_count)
-			continue;
-
-		uuid16[uuid_count++] = uuid->uuid.value.uuid16;
-		eir_len += sizeof(uint16_t);
-	}
-
-	if (uuid_count > 0) {
-		/* EIR Data length */
-		ptr[0] = (uuid_count * sizeof(uint16_t)) + 1;
-		/* EIR Data type */
-		ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL;
-
-		ptr += 2;
-		eir_len += 2;
-
-		for (i = 0; i < uuid_count; i++) {
-			*ptr++ = (uuid16[i] & 0x00ff);
-			*ptr++ = (uuid16[i] & 0xff00) >> 8;
-		}
-	}
-
-	/* Group all UUID128 types */
-	if (eir_len <= EIR_DATA_LENGTH - 2)
-		eir_generate_uuid128(dev->uuids, ptr, &eir_len);
-}
-
 static void update_ext_inquiry_response(int index)
 {
 	struct dev_info *dev = &devs[index];
@@ -1614,7 +1449,8 @@ static void update_ext_inquiry_response(int index)
 
 	memset(&cp, 0, sizeof(cp));
 
-	create_ext_inquiry_response(index, cp.data);
+	eir_create(dev->name, dev->tx_power, dev->did_vendor, dev->did_product,
+					dev->did_version, dev->uuids, cp.data);
 
 	if (memcmp(cp.data, dev->eir, sizeof(cp.data)) == 0)
 		return;
diff --git a/src/eir.c b/src/eir.c
new file mode 100644
index 0000000..d827c7e
--- /dev/null
+++ b/src/eir.c
@@ -0,0 +1,320 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2011  Nokia Corporation
+ *  Copyright (C) 2011  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
+ *
+ */
+#include <errno.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <glib.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/sdp.h>
+
+#include "glib-helper.h"
+#include "eir.h"
+
+#define EIR_FLAGS                   0x01  /* flags */
+#define EIR_UUID16_SOME             0x02  /* 16-bit UUID, more available */
+#define EIR_UUID16_ALL              0x03  /* 16-bit UUID, all listed */
+#define EIR_UUID32_SOME             0x04  /* 32-bit UUID, more available */
+#define EIR_UUID32_ALL              0x05  /* 32-bit UUID, all listed */
+#define EIR_UUID128_SOME            0x06  /* 128-bit UUID, more available */
+#define EIR_UUID128_ALL             0x07  /* 128-bit UUID, all listed */
+#define EIR_NAME_SHORT              0x08  /* shortened local name */
+#define EIR_NAME_COMPLETE           0x09  /* complete local name */
+#define EIR_TX_POWER                0x0A  /* transmit power level */
+#define EIR_DEVICE_ID               0x10  /* device ID */
+
+int eir_parse(struct eir_data *eir, uint8_t *eir_data, size_t eir_length)
+{
+	uint16_t len = 0;
+	size_t total;
+	size_t uuid16_count = 0;
+	size_t uuid32_count = 0;
+	size_t uuid128_count = 0;
+	uint8_t *uuid16 = NULL;
+	uint8_t *uuid32 = NULL;
+	uint8_t *uuid128 = NULL;
+	uuid_t service;
+	char *uuid_str;
+	unsigned int i;
+
+	eir->flags = -1;
+
+	/* No EIR data to parse */
+	if (eir_data == NULL || eir_length == 0)
+		return 0;
+
+	while (len < eir_length - 1) {
+		uint8_t field_len = eir_data[0];
+
+		/* Check for the end of EIR */
+		if (field_len == 0)
+			break;
+
+		switch (eir_data[1]) {
+		case EIR_UUID16_SOME:
+		case EIR_UUID16_ALL:
+			uuid16_count = field_len / 2;
+			uuid16 = &eir_data[2];
+			break;
+		case EIR_UUID32_SOME:
+		case EIR_UUID32_ALL:
+			uuid32_count = field_len / 4;
+			uuid32 = &eir_data[2];
+			break;
+		case EIR_UUID128_SOME:
+		case EIR_UUID128_ALL:
+			uuid128_count = field_len / 16;
+			uuid128 = &eir_data[2];
+			break;
+		case EIR_FLAGS:
+			eir->flags = eir_data[2];
+			break;
+		case EIR_NAME_SHORT:
+		case EIR_NAME_COMPLETE:
+			if (g_utf8_validate((char *) &eir_data[2],
+							field_len - 1, NULL))
+				eir->name = g_strndup((char *) &eir_data[2],
+								field_len - 1);
+			else
+				eir->name = g_strdup("");
+			eir->name_complete = eir_data[1] == EIR_NAME_COMPLETE;
+			break;
+		}
+
+		len += field_len + 1;
+		eir_data += field_len + 1;
+	}
+
+	/* Bail out if got incorrect length */
+	if (len > eir_length)
+		return -EINVAL;
+
+	total = uuid16_count + uuid32_count + uuid128_count;
+
+	/* No UUIDs were parsed, so skip code below */
+	if (!total)
+		return 0;
+
+	/* Generate uuids in SDP format (EIR data is Little Endian) */
+	service.type = SDP_UUID16;
+	for (i = 0; i < uuid16_count; i++) {
+		uint16_t val16 = uuid16[1];
+
+		val16 = (val16 << 8) + uuid16[0];
+		service.value.uuid16 = val16;
+		uuid_str = bt_uuid2string(&service);
+		eir->services = g_slist_append(eir->services, uuid_str);
+		uuid16 += 2;
+	}
+
+	service.type = SDP_UUID32;
+	for (i = uuid16_count; i < uuid32_count + uuid16_count; i++) {
+		uint32_t val32 = uuid32[3];
+		int k;
+
+		for (k = 2; k >= 0; k--)
+			val32 = (val32 << 8) + uuid32[k];
+
+		service.value.uuid32 = val32;
+		uuid_str = bt_uuid2string(&service);
+		eir->services = g_slist_append(eir->services, uuid_str);
+		uuid32 += 4;
+	}
+
+	service.type = SDP_UUID128;
+	for (i = uuid32_count + uuid16_count; i < total; i++) {
+		int k;
+
+		for (k = 0; k < 16; k++)
+			service.value.uuid128.data[k] = uuid128[16 - k - 1];
+
+		uuid_str = bt_uuid2string(&service);
+		eir->services = g_slist_append(eir->services, uuid_str);
+		uuid128 += 16;
+	}
+
+	return 0;
+}
+
+#define SIZEOF_UUID128 16
+
+static void eir_generate_uuid128(GSList *list, uint8_t *ptr, uint16_t *eir_len)
+{
+	int i, k, uuid_count = 0;
+	uint16_t len = *eir_len;
+	uint8_t *uuid128;
+	gboolean truncated = FALSE;
+
+	/* Store UUIDs in place, skip 2 bytes to write type and length later */
+	uuid128 = ptr + 2;
+
+	for (; list; list = list->next) {
+		struct uuid_info *uuid = list->data;
+		uint8_t *uuid128_data = uuid->uuid.value.uuid128.data;
+
+		if (uuid->uuid.type != SDP_UUID128)
+			continue;
+
+		/* Stop if not enough space to put next UUID128 */
+		if ((len + 2 + SIZEOF_UUID128) > EIR_DATA_LENGTH) {
+			truncated = TRUE;
+			break;
+		}
+
+		/* Check for duplicates, EIR data is Little Endian */
+		for (i = 0; i < uuid_count; i++) {
+			for (k = 0; k < SIZEOF_UUID128; k++) {
+				if (uuid128[i * SIZEOF_UUID128 + k] !=
+					uuid128_data[SIZEOF_UUID128 - 1 - k])
+					break;
+			}
+			if (k == SIZEOF_UUID128)
+				break;
+		}
+
+		if (i < uuid_count)
+			continue;
+
+		/* EIR data is Little Endian */
+		for (k = 0; k < SIZEOF_UUID128; k++)
+			uuid128[uuid_count * SIZEOF_UUID128 + k] =
+				uuid128_data[SIZEOF_UUID128 - 1 - k];
+
+		len += SIZEOF_UUID128;
+		uuid_count++;
+	}
+
+	if (uuid_count > 0 || truncated) {
+		/* EIR Data length */
+		ptr[0] = (uuid_count * SIZEOF_UUID128) + 1;
+		/* EIR Data type */
+		ptr[1] = truncated ? EIR_UUID128_SOME : EIR_UUID128_ALL;
+		len += 2;
+		*eir_len = len;
+	}
+}
+
+void eir_create(const char *name, int8_t tx_power, uint16_t did_vendor,
+			uint16_t did_product, uint16_t did_version,
+			GSList *uuids, uint8_t *data)
+{
+	GSList *l;
+	uint8_t *ptr = data;
+	uint16_t eir_len = 0;
+	uint16_t uuid16[EIR_DATA_LENGTH / 2];
+	int i, uuid_count = 0;
+	gboolean truncated = FALSE;
+	size_t name_len;
+
+	name_len = strlen(name);
+
+	if (name_len > 0) {
+		/* EIR Data type */
+		if (name_len > 48) {
+			name_len = 48;
+			ptr[1] = EIR_NAME_SHORT;
+		} else
+			ptr[1] = EIR_NAME_COMPLETE;
+
+		/* EIR Data length */
+		ptr[0] = name_len + 1;
+
+		memcpy(ptr + 2, name, name_len);
+
+		eir_len += (name_len + 2);
+		ptr += (name_len + 2);
+	}
+
+	if (tx_power != 0) {
+		*ptr++ = 2;
+		*ptr++ = EIR_TX_POWER;
+		*ptr++ = (uint8_t) tx_power;
+		eir_len += 3;
+	}
+
+	if (did_vendor != 0x0000) {
+		uint16_t source = 0x0002;
+		*ptr++ = 9;
+		*ptr++ = EIR_DEVICE_ID;
+		*ptr++ = (source & 0x00ff);
+		*ptr++ = (source & 0xff00) >> 8;
+		*ptr++ = (did_vendor & 0x00ff);
+		*ptr++ = (did_vendor & 0xff00) >> 8;
+		*ptr++ = (did_product & 0x00ff);
+		*ptr++ = (did_product & 0xff00) >> 8;
+		*ptr++ = (did_version & 0x00ff);
+		*ptr++ = (did_version & 0xff00) >> 8;
+		eir_len += 10;
+	}
+
+	/* Group all UUID16 types */
+	for (l = uuids; l != NULL; l = g_slist_next(l)) {
+		struct uuid_info *uuid = l->data;
+
+		if (uuid->uuid.type != SDP_UUID16)
+			continue;
+
+		if (uuid->uuid.value.uuid16 < 0x1100)
+			continue;
+
+		if (uuid->uuid.value.uuid16 == PNP_INFO_SVCLASS_ID)
+			continue;
+
+		/* Stop if not enough space to put next UUID16 */
+		if ((eir_len + 2 + sizeof(uint16_t)) > EIR_DATA_LENGTH) {
+			truncated = TRUE;
+			break;
+		}
+
+		/* Check for duplicates */
+		for (i = 0; i < uuid_count; i++)
+			if (uuid16[i] == uuid->uuid.value.uuid16)
+				break;
+
+		if (i < uuid_count)
+			continue;
+
+		uuid16[uuid_count++] = uuid->uuid.value.uuid16;
+		eir_len += sizeof(uint16_t);
+	}
+
+	if (uuid_count > 0) {
+		/* EIR Data length */
+		ptr[0] = (uuid_count * sizeof(uint16_t)) + 1;
+		/* EIR Data type */
+		ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL;
+
+		ptr += 2;
+		eir_len += 2;
+
+		for (i = 0; i < uuid_count; i++) {
+			*ptr++ = (uuid16[i] & 0x00ff);
+			*ptr++ = (uuid16[i] & 0xff00) >> 8;
+		}
+	}
+
+	/* Group all UUID128 types */
+	if (eir_len <= EIR_DATA_LENGTH - 2)
+		eir_generate_uuid128(uuids, ptr, &eir_len);
+}
diff --git a/src/eir.h b/src/eir.h
new file mode 100644
index 0000000..c7699eb
--- /dev/null
+++ b/src/eir.h
@@ -0,0 +1,42 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2011  Nokia Corporation
+ *  Copyright (C) 2011  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
+ *
+ */
+
+#define EIR_DATA_LENGTH  240
+
+struct uuid_info {
+	uuid_t uuid;
+	uint8_t svc_hint;
+};
+
+struct eir_data {
+	GSList *services;
+	int flags;
+	char *name;
+	gboolean name_complete;
+};
+
+int eir_parse(struct eir_data *eir, uint8_t *eir_data, size_t eir_length);
+void eir_create(const char *name, int8_t tx_power, uint16_t did_vendor,
+			uint16_t did_product, uint16_t did_version,
+			GSList *uuids, uint8_t *data);
diff --git a/src/event.c b/src/event.c
index 141a04e..dc1b659 100644
--- a/src/event.c
+++ b/src/event.c
@@ -58,13 +58,7 @@
 #include "storage.h"
 #include "event.h"
 #include "sdpd.h"
-
-struct eir_data {
-	GSList *services;
-	int flags;
-	char *name;
-	gboolean name_complete;
-};
+#include "eir.h"
 
 static gboolean get_adapter_and_device(bdaddr_t *src, bdaddr_t *dst,
 					struct btd_adapter **adapter,
@@ -287,120 +281,6 @@ void btd_event_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer,
 	device_simple_pairing_complete(device, status);
 }
 
-static int parse_eir_data(struct eir_data *eir, uint8_t *eir_data,
-							size_t eir_length)
-{
-	uint16_t len = 0;
-	size_t total;
-	size_t uuid16_count = 0;
-	size_t uuid32_count = 0;
-	size_t uuid128_count = 0;
-	uint8_t *uuid16 = NULL;
-	uint8_t *uuid32 = NULL;
-	uint8_t *uuid128 = NULL;
-	uuid_t service;
-	char *uuid_str;
-	unsigned int i;
-
-	eir->flags = -1;
-
-	/* No EIR data to parse */
-	if (eir_data == NULL || eir_length == 0)
-		return 0;
-
-	while (len < eir_length - 1) {
-		uint8_t field_len = eir_data[0];
-
-		/* Check for the end of EIR */
-		if (field_len == 0)
-			break;
-
-		switch (eir_data[1]) {
-		case EIR_UUID16_SOME:
-		case EIR_UUID16_ALL:
-			uuid16_count = field_len / 2;
-			uuid16 = &eir_data[2];
-			break;
-		case EIR_UUID32_SOME:
-		case EIR_UUID32_ALL:
-			uuid32_count = field_len / 4;
-			uuid32 = &eir_data[2];
-			break;
-		case EIR_UUID128_SOME:
-		case EIR_UUID128_ALL:
-			uuid128_count = field_len / 16;
-			uuid128 = &eir_data[2];
-			break;
-		case EIR_FLAGS:
-			eir->flags = eir_data[2];
-			break;
-		case EIR_NAME_SHORT:
-		case EIR_NAME_COMPLETE:
-			if (g_utf8_validate((char *) &eir_data[2],
-							field_len - 1, NULL))
-				eir->name = g_strndup((char *) &eir_data[2],
-								field_len - 1);
-			else
-				eir->name = g_strdup("");
-			eir->name_complete = eir_data[1] == EIR_NAME_COMPLETE;
-			break;
-		}
-
-		len += field_len + 1;
-		eir_data += field_len + 1;
-	}
-
-	/* Bail out if got incorrect length */
-	if (len > eir_length)
-		return -EINVAL;
-
-	total = uuid16_count + uuid32_count + uuid128_count;
-
-	/* No UUIDs were parsed, so skip code below */
-	if (!total)
-		return 0;
-
-	/* Generate uuids in SDP format (EIR data is Little Endian) */
-	service.type = SDP_UUID16;
-	for (i = 0; i < uuid16_count; i++) {
-		uint16_t val16 = uuid16[1];
-
-		val16 = (val16 << 8) + uuid16[0];
-		service.value.uuid16 = val16;
-		uuid_str = bt_uuid2string(&service);
-		eir->services = g_slist_append(eir->services, uuid_str);
-		uuid16 += 2;
-	}
-
-	service.type = SDP_UUID32;
-	for (i = uuid16_count; i < uuid32_count + uuid16_count; i++) {
-		uint32_t val32 = uuid32[3];
-		int k;
-
-		for (k = 2; k >= 0; k--)
-			val32 = (val32 << 8) + uuid32[k];
-
-		service.value.uuid32 = val32;
-		uuid_str = bt_uuid2string(&service);
-		eir->services = g_slist_append(eir->services, uuid_str);
-		uuid32 += 4;
-	}
-
-	service.type = SDP_UUID128;
-	for (i = uuid32_count + uuid16_count; i < total; i++) {
-		int k;
-
-		for (k = 0; k < 16; k++)
-			service.value.uuid128.data[k] = uuid128[16 - k - 1];
-
-		uuid_str = bt_uuid2string(&service);
-		eir->services = g_slist_append(eir->services, uuid_str);
-		uuid128 += 16;
-	}
-
-	return 0;
-}
-
 static void free_eir_data(struct eir_data *eir)
 {
 	g_slist_foreach(eir->services, (GFunc) g_free, NULL);
@@ -422,7 +302,7 @@ void btd_event_advertising_report(bdaddr_t *local, le_advertising_info *info)
 	}
 
 	memset(&eir_data, 0, sizeof(eir_data));
-	err = parse_eir_data(&eir_data, info->data, info->length);
+	err = eir_parse(&eir_data, info->data, info->length);
 	if (err < 0)
 		error("Error parsing advertising data: %s (%d)",
 							strerror(-err), -err);
@@ -511,7 +391,7 @@ void btd_event_device_found(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
 		legacy = TRUE;
 
 	memset(&eir_data, 0, sizeof(eir_data));
-	err = parse_eir_data(&eir_data, data, EIR_DATA_LENGTH);
+	err = eir_parse(&eir_data, data, EIR_DATA_LENGTH);
 	if (err < 0)
 		error("Error parsing EIR data: %s (%d)", strerror(-err), -err);
 
diff --git a/src/sdpd.h b/src/sdpd.h
index 471e9cc..9f5415f 100644
--- a/src/sdpd.h
+++ b/src/sdpd.h
@@ -34,20 +34,6 @@
 #define SDPDBG(fmt...)
 #endif
 
-#define EIR_DATA_LENGTH  240
-
-#define EIR_FLAGS                   0x01  /* flags */
-#define EIR_UUID16_SOME             0x02  /* 16-bit UUID, more available */
-#define EIR_UUID16_ALL              0x03  /* 16-bit UUID, all listed */
-#define EIR_UUID32_SOME             0x04  /* 32-bit UUID, more available */
-#define EIR_UUID32_ALL              0x05  /* 32-bit UUID, all listed */
-#define EIR_UUID128_SOME            0x06  /* 128-bit UUID, more available */
-#define EIR_UUID128_ALL             0x07  /* 128-bit UUID, all listed */
-#define EIR_NAME_SHORT              0x08  /* shortened local name */
-#define EIR_NAME_COMPLETE           0x09  /* complete local name */
-#define EIR_TX_POWER                0x0A  /* transmit power level */
-#define EIR_DEVICE_ID               0x10  /* device ID */
-
 typedef struct request {
 	bdaddr_t device;
 	bdaddr_t bdaddr;
-- 
1.7.5.rc3


^ permalink raw reply related

* [PATCH v3 00/12] Discovery Cleanup
From: Claudio Takahasi @ 2011-05-16 20:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <BANLkTikx8qkTnpb46Q=zh8=7NnwDyvXDXQ@mail.gmail.com>

Main changes are:
 - Unify advertising reports and inquiry results: mgmt sends device
   found event. Device type(BR/LE) are now discovered based on the
   EIR flags.
 - Logic improvement/cleanup: device found
 - Move EIR functions to a new file

Check AD Flags of the EIR data(in the advertising data) doesn't require
kernel socket API changes, broken LE devices can send advertises without
AD flags set, for this case the fallback is to consider it as BR device
and for the connection page timeout.

Open(old) issues: excessive dynamic memory allocation/free for EIR data.
Check if EIR has changed to send another DeviceFound signal, trust on RSSI
value only is not correct.

Bruna Moreira (3):
  Remove btd_event_advertising_report
  Replace EIR_DATA_LENGTH with HCI_MAX_EIR_LENGTH
  Drop variable EIR length

Claudio Takahasi (9):
  Move EIR related functions to a new file
  Initial device found cleanup
  Move legacy verification to a new function
  Cleanup read name and alias from storage
  Don't resolve name if the name is in the storage
  Unify inquiry results and advertises
  Fix memory leak of EIR data
  Change the order to write/read the remote's name
  Cleanup inserting new device found entry

 Makefile.am      |    2 +-
 plugins/hciops.c |  188 +++----------------------------
 src/adapter.c    |  174 ++++++++++++++++++-----------
 src/adapter.h    |    9 +-
 src/eir.c        |  328 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/eir.h        |   41 +++++++
 src/event.c      |  217 +-----------------------------------
 src/event.h      |    1 -
 src/sdpd.h       |   14 ---
 9 files changed, 502 insertions(+), 472 deletions(-)
 create mode 100644 src/eir.c
 create mode 100644 src/eir.h

-- 
1.7.5.rc3


^ permalink raw reply

* Re: HCI data payload not getting through when using BlueZ
From: Anderson Lizardo @ 2011-05-16 12:17 UTC (permalink / raw)
  To: Eponymous -; +Cc: linux-bluetooth
In-Reply-To: <BANLkTi=nUb=CxPYMgJQk7HKUF0OCsc7jUw@mail.gmail.com>

Hi,

On Mon, May 16, 2011 at 6:36 AM, Eponymous - <the.epon@gmail.com> wrote:
> OK guys,
>
> I had a theory that my l2test test was not working due to the fact
> that the chip wasn't configured to work with upperlayers. After
> enabling this however, the  devices disappear (in hciconfig) so I
> can't really test any L2CAP stuff (which I assume is what l2test is
> doing).
>
> Are there any other things I can try to help debug this issue I've seen?

What is the chipset of your USB dongles ? A "lsusb -d <vid>:<pid>" and
relevant output from dmesg might help here.

What do you mean by "the chip wasn't configured to work with
upperlayers" ? Was the chipset in a mode which was not HCI compliant?

Keep in mind that there are development/prototype USB dongles which
are in fact serial/FTDI devices, and thus require using hciattach to
be able to use them in BlueZ.

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply

* Re: HCI data payload not getting through when using BlueZ
From: Eponymous - @ 2011-05-16 10:36 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <BANLkTi=KK0zUyeBUxWJxUW+EyFvJ_SuALA@mail.gmail.com>

OK guys,

I had a theory that my l2test test was not working due to the fact
that the chip wasn't configured to work with upperlayers. After
enabling this however, the  devices disappear (in hciconfig) so I
can't really test any L2CAP stuff (which I assume is what l2test is
doing).

Are there any other things I can try to help debug this issue I've seen?

Thankyou.

On Fri, May 13, 2011 at 1:42 PM, Eponymous - <the.epon@gmail.com> wrote:
> The following were executed in a root shell.
>
> Receive Side (Device B):
>
> $ ./l2test -r 00:02:5B:00:31:21
> l2test[29219]: Waiting for connection on psm 4113 ...
>
> Transmit Side (Device A):
>
> $ ./l2test -s -b 10 00:02:5B:01:FE:DF
> l2test[29234]: Can't connect: Permission denied (13)
> $ ./l2test -s -b 10 00:02:5B:01:FE:DF
> l2test[29311]: Can't connect: Connection refused (111)
> $ ./l2test -s -b 10 00:02:5B:01:FE:DF
> l2test[29326]: Can't connect: Connection refused (111)
> $ ./l2test -s -b 10 00:02:5B:01:FE:DF
> l2test[29401]: Can't connect: Permission denied (13)
> $ ./l2test -s -b 10 00:02:5B:01:FE:DF
> l2test[29478]: Can't connect: Connection refused (111)
> $ ./l2test -s -b 10 00:02:5B:01:FE:DF
> l2test[29493]: Can't connect: Connection refused (111)
>
> Doesn't appear to work...
>
> On Fri, May 13, 2011 at 9:39 AM, Eponymous - <the.epon@gmail.com> wrote:
>> What format do you specify the bdaddr in ?
>>
>> Cheers.
>>
>> On Fri, May 13, 2011 at 9:26 AM, Mika Linnanoja
>> <mika.linnanoja@nokia.com> wrote:
>>> On 05/13/2011 11:13 AM, ext Suraj Sumangala wrote:
>>>>
>>>> You have to enable it in the cofigure file and change "test_enable" from
>>>> "no" to "yes".
>>>> Edit the file "configure", search for "test_enable"
>>>> change "test_enable=no" to "test_enable=yes"
>>>>
>>>> That is what I do to enable l2test. I guess there could be some other
>>>> cleaner way to do it.
>>>
>>> ./configure --help :)
>>>
>>> If you pull from the git repo ./bootstrap-configure already enables most of
>>> them.
>>>
>>> Although lately configure is often *not* complaining if something is missing
>>> from build dependencies, have to do a bit of trial & error to get it right.
>>>
>>> This is very easy to notice when trying to 'make' bluez on a clean system
>>> where it hasn't ever been built before.
>>>
>>> Cheers,
>>> Mika
>>>
>>
>

^ permalink raw reply

* Re: [PATCH -v2 3/7] Bluetooth: Create l2cap_chan_send()
From: Szymon Janc @ 2011-05-16  9:07 UTC (permalink / raw)
  To: Gustavo F. Padovan; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1305314450-25493-4-git-send-email-padovan@profusion.mobi>

Hi,

> This move all the sending logic to l2cap_core.c, but we still have a
> socket dependence there, struct msghdr. It will be removed in some of the
> further commits.

> +int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
> +{
> +	struct sock *sk = chan->sk;
> +	struct sk_buff *skb;
> +	u16 control;
> +	int err;
> +
> +	/* Connectionless channel */
> +	if (sk->sk_type == SOCK_DGRAM) {
> +		skb = l2cap_create_connless_pdu(chan, msg, len);
> +		if (IS_ERR(skb))
> +			return PTR_ERR(skb);
> +
> +		l2cap_do_send(chan, skb);
> +		return len;
> +	}
> +
> +	switch (chan->mode) {
> +	case L2CAP_MODE_BASIC:
> +		/* Check outgoing MTU */
> +		if (len > chan->omtu)
> +			return -EMSGSIZE;
> +
> +		/* Create a basic PDU */
> +		skb = l2cap_create_basic_pdu(chan, msg, len);
> +		if (IS_ERR(skb))
> +			return PTR_ERR(skb);
> +
> +		l2cap_do_send(chan, skb);
> +		err = len;
> +		break;
> +
> +	case L2CAP_MODE_ERTM:
> +	case L2CAP_MODE_STREAMING:

How about moving common part (sdu if-else) to a function and separate those 2 cases?
Would be less confusing imho.

> +		/* Entire SDU fits into one PDU */
> +		if (len <= chan->remote_mps) {
> +			control = L2CAP_SDU_UNSEGMENTED;
> +			skb = l2cap_create_iframe_pdu(chan, msg, len, control,
> +									0);
> +			if (IS_ERR(skb))
> +				return PTR_ERR(skb);
> +
> +			__skb_queue_tail(&chan->tx_q, skb);
> +
> +			if (chan->tx_send_head == NULL)
> +				chan->tx_send_head = skb;
> +
> +		} else {
> +			/* Segment SDU into multiples PDUs */
> +			err = l2cap_sar_segment_sdu(chan, msg, len);
> +			if (err < 0)
> +				return err;
> +		}
> +
> +		if (chan->mode == L2CAP_MODE_STREAMING) {
> +			l2cap_streaming_send(chan);
> +			err = len;
> +			break;
> +		}
> +
> +		if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
> +				(chan->conn_state & L2CAP_CONN_WAIT_F)) {
> +			err = len;
> +			break;
> +		}
> +
> +		err = l2cap_ertm_send(chan);
> +		if (err >= 0)
> +			err = len;
> +
> +		break;
> +
> +	default:
> +		BT_DBG("bad state %1.1x", chan->mode);
> +		err = -EBADFD;
> +	}
> +
> +	return err;
> +}

-- 
BR
Szymon Janc

^ permalink raw reply

* Re: [PATCH v6] Add ST-Ericsson CG2900 driver
From: Linus Walleij @ 2011-05-15 17:59 UTC (permalink / raw)
  To: Greg KH
  Cc: Par-Gunnar Hjalmdahl, devel, Mathieu Poirier,
	Par-Gunnar Hjalmdahl, Arnd Bergmann, Vitaly Wool, Marcel Holtmann,
	Greg Kroah-Hartman, linux-kernel, Lukasz Rymanowski,
	linux-bluetooth, Pavan Savoy, Lee Jones, Alan Cox
In-Reply-To: <20110515173644.GA18241@kroah.com>

2011/5/15 Greg KH <greg@kroah.com>:
> On Sun, May 15, 2011 at 07:29:04PM +0200, Linus Walleij wrote:
>> It was my recommendation to put it into staging, by doing this
>> people can talk about the architecture by submitting *patches*
>> to show how they want it instead of these fruitless discussions.
>>
>> So this should be a case where staging really helps, at least in
>> my dreams.
>
> Yes, that is where staging should help, hopefully we can get these build
> dependancies worked out to get this merged properly. =A0Perhaps for the
> .41 merge window?

Since one of the build dependencies is the GPIO rework that already
needed to be pushed from 2.6.40 to 2.6.41 due to shortage of
review power for drivers/gpio, and since I cannot merge the updates
to the current GPIO driver in arch/arm/plat-nomadik/gpio.c due to
the current ban on anything that grows arch/arm/* we will likely
have to postpone its merging to staging to 2.6.42.

Basically this driver has ended up in cross-subsystem dependency
hell :-)

But worse things have happened, and these are special times,
so let's let it rest for a while.

Linus Walleij

^ permalink raw reply


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