Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH 3/3 v2] Use libtracker-sparql in PBAP
From: Radoslaw Jablonski @ 2011-02-02 10:21 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1296642108-14063-1-git-send-email-ext-jablonski.radoslaw@nokia.com>

Now direct tracker connection for transporting retrieved
parts of data is used, instead of D-Bus. This should result better
performance for PBAP requests.
Each part of results is now fetched from tracker asynchronously
and getting more results can be stopped in any moment -
GCancellable stored in phonebook_data is used for that purpose.
If processing of data has finished (or it was cancelled) then cleanup
of pending_reply is done in last invocation of
async_query_cursor_next_cb.
---
 plugins/phonebook-tracker.c |  271 +++++++++++++++++++++++--------------------
 1 files changed, 147 insertions(+), 124 deletions(-)

diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 3b61d6b..79bc1c6 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -29,6 +29,7 @@
 #include <dbus/dbus.h>
 #include <openobex/obex.h>
 #include <openobex/obex_const.h>
+#include <libtracker-sparql/tracker-sparql.h>
 
 #include "log.h"
 #include "obex.h"
@@ -891,7 +892,7 @@
 	"} GROUP BY ?call ORDER BY DESC(nmo:receivedDate(?call)) "	\
 	"LIMIT 40"
 
-typedef void (*reply_list_foreach_t) (char **reply, int num_fields,
+typedef void (*reply_list_foreach_t) (const char **reply, int num_fields,
 							void *user_data);
 
 typedef void (*add_field_t) (struct phonebook_contact *contact,
@@ -918,7 +919,7 @@ struct phonebook_data {
 	phonebook_cache_ready_cb ready_cb;
 	phonebook_entry_cb entry_cb;
 	int newmissedcalls;
-	DBusPendingCall *call;
+	GCancellable *query_canc;
 };
 
 struct phonebook_index {
@@ -926,7 +927,7 @@ struct phonebook_index {
 	int index;
 };
 
-static DBusConnection *connection = NULL;
+static TrackerSparqlConnection *connection = NULL;
 
 static const char *name2query(const char *name)
 {
@@ -999,131 +1000,139 @@ static const char *folder2query(const char *folder)
 	return NULL;
 }
 
-static char **string_array_from_iter(DBusMessageIter iter, int array_len)
+static const char **string_array_from_cursor(TrackerSparqlCursor *cursor,
+								int array_len)
 {
-	DBusMessageIter sub;
-	char **result;
+	const char **result;
 	int i;
 
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
-		return NULL;
-
-	result = g_new0(char *, array_len);
-
-	dbus_message_iter_recurse(&iter, &sub);
-
-	i = 0;
-	while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
-		char *arg;
+	result = g_new0(const char *, array_len);
 
-		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) {
-			g_free(result);
-			return NULL;
-		}
-
-		dbus_message_iter_get_basic(&sub, &arg);
+	for (i = 0; i < array_len; ++i) {
+		TrackerSparqlValueType type;
 
-		result[i] = arg;
+		type = tracker_sparql_cursor_get_value_type(cursor, i);
 
-		i++;
-		dbus_message_iter_next(&sub);
+		if (type == TRACKER_SPARQL_VALUE_TYPE_BLANK_NODE ||
+				type == TRACKER_SPARQL_VALUE_TYPE_UNBOUND)
+			/* For null/unbound type filling result part with ""*/
+			result[i] = "";
+		else
+			/* Filling with string representation of content*/
+			result[i] = tracker_sparql_cursor_get_string(cursor, i,
+									NULL);
 	}
 
 	return result;
 }
 
-static void query_reply(DBusPendingCall *call, void *user_data)
+
+static void query_free_data(void *user_data)
 {
-	DBusMessage *reply = dbus_pending_call_steal_reply(call);
+	DBG("");
 	struct pending_reply *pending = user_data;
-	DBusMessageIter iter, element;
-	DBusError derr;
-	int err;
-
-	dbus_error_init(&derr);
-	if (dbus_set_error_from_message(&derr, reply)) {
-		error("Replied with an error: %s, %s", derr.name,
-							derr.message);
-		dbus_error_free(&derr);
-
-		err = -1;
-		goto done;
-	}
-
-	dbus_message_iter_init(reply, &iter);
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
-		error("SparqlQuery reply is not an array");
 
-		err = -1;
-		goto done;
-	}
-
-	dbus_message_iter_recurse(&iter, &element);
-
-	err = 0;
+	if (!pending)
+		return;
 
-	while (dbus_message_iter_get_arg_type(&element) != DBUS_TYPE_INVALID) {
-		char **node;
+	g_free(pending);
+}
 
-		if (dbus_message_iter_get_arg_type(&element) !=
-						DBUS_TYPE_ARRAY) {
-			error("element is not an array");
-			goto done;
-		}
+static void update_cancellable(struct phonebook_data *pdata,
+							GCancellable *canc)
+{
+	if (pdata->query_canc)
+		g_object_unref(pdata->query_canc);
 
-		node = string_array_from_iter(element, pending->num_fields);
-		pending->callback(node, pending->num_fields,
-							pending->user_data);
+	pdata->query_canc = canc;
+}
 
-		g_free(node);
+static void async_query_cursor_next_cb(GObject *source, GAsyncResult *result,
+							gpointer user_data)
+{
+	struct pending_reply *pending = user_data;
+	TrackerSparqlCursor *cursor = TRACKER_SPARQL_CURSOR (source);
+	GCancellable *cancellable;
+	GError *error = NULL;
+	gboolean success;
+	const char **node;
+
+	success = tracker_sparql_cursor_next_finish(
+						TRACKER_SPARQL_CURSOR (source),
+						result,
+						&error);
+
+	if (!success) {
+		if (error) {
+			DBG("cursor_next error: %s", error->message);
+			g_error_free(error);
+		} else
+			/* When tracker_sparql_cursor_next_finish ends with
+			 * failure and no error is set, that means end of
+			 * results returned by query */
+			pending->callback(NULL, 0, pending->user_data);
 
-		dbus_message_iter_next(&element);
+		goto failed;
 	}
 
-done:
-	/* This is the last entry */
-	pending->callback(NULL, err, pending->user_data);
+	node = string_array_from_cursor(cursor, pending->num_fields);
+	pending->callback(node, pending->num_fields, pending->user_data);
+	g_free(node);
 
-	dbus_message_unref(reply);
 
-	/* pending data is freed in query_free_data after call is unreffed. */
-}
-
-static void query_free_data(void *user_data)
-{
-	struct pending_reply *pending = user_data;
-
-	if (!pending)
-		return;
+	/* getting next row from query results */
+	cancellable = g_cancellable_new();
+	update_cancellable(pending->user_data, cancellable);
+	tracker_sparql_cursor_next_async(cursor, cancellable,
+						async_query_cursor_next_cb,
+						pending);
+	return;
 
-	g_free(pending);
+failed:
+	g_object_unref(cursor);
+	query_free_data(pending);
 }
 
-static DBusPendingCall *query_tracker(const char *query, int num_fields,
-		reply_list_foreach_t callback, void *user_data, int *err)
+static void query_tracker(const char *query, int num_fields,
+				reply_list_foreach_t callback, void *user_data,
+				int *err)
+
 {
 	struct pending_reply *pending;
-	DBusPendingCall *call;
-	DBusMessage *msg;
+	GCancellable *cancellable;
+	TrackerSparqlCursor *cursor;
+	GError *error = NULL;
+
+	DBG("");
 
 	if (connection == NULL)
-		connection = obex_dbus_get_connection();
+		connection = tracker_sparql_connection_get_direct(
+								NULL, &error);
 
-	msg = dbus_message_new_method_call(TRACKER_SERVICE,
-			TRACKER_RESOURCES_PATH, TRACKER_RESOURCES_INTERFACE,
-								"SparqlQuery");
+	if (!connection) {
+		if (error) {
+			DBG("direct-connection error: %s", error->message);
+			g_error_free(error);
+		}
 
-	dbus_message_append_args(msg, DBUS_TYPE_STRING, &query,
-						DBUS_TYPE_INVALID);
+		goto failed;
+	}
 
-	if (dbus_connection_send_with_reply(connection, msg, &call,
-							-1) == FALSE) {
-		error("Could not send dbus message");
-		dbus_message_unref(msg);
-		if (err)
-			*err = -EPERM;
-		return NULL;
+	cancellable = g_cancellable_new();
+	update_cancellable(user_data, cancellable);
+	cursor = tracker_sparql_connection_query(connection, query,
+							cancellable, &error);
+
+	if (cursor == NULL) {
+		if (error) {
+			DBG("connection_query error: %s", error->message);
+			g_error_free(error);
+		}
+
+		g_object_unref(cancellable);
+		g_object_unref(cursor);
+
+		goto failed;
 	}
 
 	pending = g_new0(struct pending_reply, 1);
@@ -1131,14 +1140,21 @@ static DBusPendingCall *query_tracker(const char *query, int num_fields,
 	pending->user_data = user_data;
 	pending->num_fields = num_fields;
 
-	dbus_pending_call_set_notify(call, query_reply, pending,
-							query_free_data);
-	dbus_message_unref(msg);
+	/* Now asynchronously going through each row of results - callback
+	 * async_query_cursor_next_cb will be called ALWAYS, even if async
+	 * request was canceled */
+	tracker_sparql_cursor_next_async(cursor, cancellable,
+						async_query_cursor_next_cb,
+						pending);
 
 	if (err)
 		*err = 0;
 
-	return call;
+	return;
+
+failed:
+	if (err)
+		*err = -EPERM;
 }
 
 static char *iso8601_utc_to_localtime(const char *datetime)
@@ -1331,7 +1347,8 @@ static GString *gen_vcards(GSList *contacts,
 	return vcards;
 }
 
-static void pull_contacts_size(char **reply, int num_fields, void *user_data)
+static void pull_contacts_size(const char **reply, int num_fields,
+							void *user_data)
 {
 	struct phonebook_data *data = user_data;
 
@@ -1363,7 +1380,8 @@ static void add_affiliation(char **field, const char *value)
 	*field = g_strdup(value);
 }
 
-static void contact_init(struct phonebook_contact *contact, char **reply)
+static void contact_init(struct phonebook_contact *contact,
+							const char **reply)
 {
 
 	contact->fullname = g_strdup(reply[COL_FULL_NAME]);
@@ -1395,8 +1413,8 @@ static enum phonebook_number_type get_phone_type(const char *affilation)
 	return TEL_TYPE_OTHER;
 }
 
-static void add_aff_number(struct phonebook_contact *contact, char *pnumber,
-								char *aff_type)
+static void add_aff_number(struct phonebook_contact *contact,
+				const char *pnumber, const char *aff_type)
 {
 	char **num_parts;
 	char *type, *number;
@@ -1433,7 +1451,7 @@ failed:
 }
 
 static void contact_add_numbers(struct phonebook_contact *contact,
-								char **reply)
+							const char **reply)
 {
 	char **aff_numbers;
 	int i;
@@ -1459,8 +1477,8 @@ static enum phonebook_field_type get_field_type(const char *affilation)
 	return FIELD_TYPE_OTHER;
 }
 
-static void add_aff_field(struct phonebook_contact *contact, char *aff_email,
-						add_field_t add_field_cb)
+static void add_aff_field(struct phonebook_contact *contact,
+			const char *aff_email, add_field_t add_field_cb)
 {
 	char **email_parts;
 	char *type, *email;
@@ -1490,7 +1508,7 @@ failed:
 }
 
 static void contact_add_emails(struct phonebook_contact *contact,
-								char **reply)
+							const char **reply)
 {
 	char **aff_emails;
 	int i;
@@ -1506,7 +1524,7 @@ static void contact_add_emails(struct phonebook_contact *contact,
 }
 
 static void contact_add_addresses(struct phonebook_contact *contact,
-								char **reply)
+							const char **reply)
 {
 	char **aff_addr;
 	int i;
@@ -1522,7 +1540,8 @@ static void contact_add_addresses(struct phonebook_contact *contact,
 	g_strfreev(aff_addr);
 }
 
-static void contact_add_urls(struct phonebook_contact *contact, char **reply)
+static void contact_add_urls(struct phonebook_contact *contact,
+							const char **reply)
 {
 	char **aff_url;
 	int i;
@@ -1538,7 +1557,7 @@ static void contact_add_urls(struct phonebook_contact *contact, char **reply)
 }
 
 static void contact_add_organization(struct phonebook_contact *contact,
-								char **reply)
+							const char **reply)
 {
 	/* Adding fields connected by nco:hasAffiliation - they may be in
 	 * separate replies */
@@ -1548,7 +1567,7 @@ static void contact_add_organization(struct phonebook_contact *contact,
 	add_affiliation(&contact->role, reply[COL_ORG_ROLE]);
 }
 
-static void pull_contacts(char **reply, int num_fields, void *user_data)
+static void pull_contacts(const char **reply, int num_fields, void *user_data)
 {
 	struct phonebook_data *data = user_data;
 	const struct apparam_field *params = data->params;
@@ -1649,7 +1668,7 @@ fail:
 	 */
 }
 
-static void add_to_cache(char **reply, int num_fields, void *user_data)
+static void add_to_cache(const char **reply, int num_fields, void *user_data)
 {
 	struct phonebook_data *data = user_data;
 	char *formatted;
@@ -1699,6 +1718,9 @@ done:
 
 int phonebook_init(void)
 {
+	g_thread_init(NULL);
+	g_type_init();
+
 	return 0;
 }
 
@@ -1792,12 +1814,13 @@ void phonebook_req_finalize(void *request)
 	if (!data)
 		return;
 
-	if (!dbus_pending_call_get_completed(data->call))
-		dbus_pending_call_cancel(data->call);
-
-	dbus_pending_call_unref(data->call);
+	/* canceling asynchronous operation on tracker if any is active */
+	if (data->query_canc) {
+		g_cancellable_cancel(data->query_canc);
+		g_object_unref(data->query_canc);
+	}
 
-	/* freeing list of contacts used for generating vcards */
+	/* freeing contacts */
 	for (l = data->contacts; l; l = l->next) {
 		struct contact_data *c_data = l->data;
 
@@ -1828,7 +1851,8 @@ static void gstring_free_helper(gpointer data, gpointer user_data)
 	g_string_free(data, TRUE);
 }
 
-static void pull_newmissedcalls(char **reply, int num_fields, void *user_data)
+static void pull_newmissedcalls(const char **reply, int num_fields,
+							void *user_data)
 {
 	struct phonebook_data *data = user_data;
 	reply_list_foreach_t pull_cb;
@@ -1870,8 +1894,7 @@ done:
 		pull_cb = pull_contacts;
 	}
 
-	dbus_pending_call_unref(data->call);
-	data->call = query_tracker(query, col_amount, pull_cb, data, &err);
+	query_tracker(query, col_amount, pull_cb, data, &err);
 	if (err < 0)
 		data->cb(NULL, 0, err, 0, data->user_data);
 }
@@ -1910,7 +1933,7 @@ void *phonebook_pull(const char *name, const struct apparam_field *params,
 	data->params = params;
 	data->user_data = user_data;
 	data->cb = cb;
-	data->call = query_tracker(query, col_amount, pull_cb, data, err);
+	query_tracker(query, col_amount, pull_cb, data, err);
 
 	return data;
 }
@@ -1938,8 +1961,8 @@ void *phonebook_get_entry(const char *folder, const char *id,
 		query = g_strdup_printf(CONTACTS_OTHER_QUERY_FROM_URI,
 								id, id, id);
 
-	data->call = query_tracker(query, PULL_QUERY_COL_AMOUNT, pull_contacts,
-								data, err);
+	query_tracker(query, PULL_QUERY_COL_AMOUNT,
+						pull_contacts, data, err);
 
 	g_free(query);
 
@@ -1965,7 +1988,7 @@ void *phonebook_create_cache(const char *name, phonebook_entry_cb entry_cb,
 	data->entry_cb = entry_cb;
 	data->ready_cb = ready_cb;
 	data->user_data = user_data;
-	data->call = query_tracker(query, 7, add_to_cache, data, err);
+	query_tracker(query, 7, add_to_cache, data, err);
 
 	return data;
 }
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 2/3 v2] Move freeing contacts data to phonebook_req_finalize
From: Radoslaw Jablonski @ 2011-02-02 10:21 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1296642108-14063-1-git-send-email-ext-jablonski.radoslaw@nokia.com>

Previously data used for generating vcards was freed only in
gen_vcards body. This may result a memory leak, if fetching data
from tracker was cancelled in the middle of process and gen_vcards
wasn't called. Phonebook_req_finalize is better place for this
kind of cleanup.
---
 plugins/phonebook-tracker.c |   14 ++++++++++----
 1 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index e60cf74..3b61d6b 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -1326,10 +1326,6 @@ static GString *gen_vcards(GSList *contacts,
 		struct contact_data *c_data = l->data;
 		phonebook_add_contact(vcards, c_data->contact,
 					params->filter, params->format);
-
-		g_free(c_data->id);
-		phonebook_contact_free(c_data->contact);
-		g_free(c_data);
 	}
 
 	return vcards;
@@ -1789,6 +1785,7 @@ done:
 void phonebook_req_finalize(void *request)
 {
 	struct phonebook_data *data = request;
+	GSList *l;
 
 	DBG("");
 
@@ -1800,6 +1797,15 @@ void phonebook_req_finalize(void *request)
 
 	dbus_pending_call_unref(data->call);
 
+	/* freeing list of contacts used for generating vcards */
+	for (l = data->contacts; l; l = l->next) {
+		struct contact_data *c_data = l->data;
+
+		g_free(c_data->id);
+		phonebook_contact_free(c_data->contact);
+		g_free(c_data);
+	}
+
 	g_slist_free(data->contacts);
 	g_free(data);
 }
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 1/3 v2] Add libtracker-sparql to obexd dependencies
From: Radoslaw Jablonski @ 2011-02-02 10:21 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski

In PBAP tracker is used only for reading and returns rather big
parts of data, so using direct access libtracker-sparql is better
solution than tracker D-Bus API(libtracker-sparql in most PBAP
scenarios should be faster).
---
 Makefile.am  |    4 +++-
 configure.ac |    7 +++++++
 2 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index a317556..fc996ec 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -79,7 +79,8 @@ src_obexd_SOURCES = $(gdbus_sources) $(builtin_sources) $(btio_sources) \
 
 src_obexd_LDADD = @DBUS_LIBS@ @GLIB_LIBS@ @GTHREAD_LIBS@ \
 					@EBOOK_LIBS@ @OPENOBEX_LIBS@ \
-					@BLUEZ_LIBS@ @LIBICAL_LIBS@ -ldl
+					@BLUEZ_LIBS@ @LIBICAL_LIBS@ \
+					@TRACKER_SPARQL_LIBS@ -ldl
 
 src_obexd_LDFLAGS = -Wl,--export-dynamic
 
@@ -124,6 +125,7 @@ service_DATA = $(service_in_files:.service.in=.service)
 AM_CFLAGS = @OPENOBEX_CFLAGS@ @BLUEZ_CFLAGS@ @EBOOK_CFLAGS@ \
 			@GTHREAD_CFLAGS@ @GLIB_CFLAGS@ @DBUS_CFLAGS@ \
 			@LIBICAL_CFLAGS@ -D_FILE_OFFSET_BITS=64 \
+			@TRACKER_SPARQL_CFLAGS@ \
 			-DOBEX_PLUGIN_BUILTIN -DPLUGINDIR=\""$(plugindir)"\"
 
 INCLUDES = -I$(builddir)/src -I$(srcdir)/src -I$(srcdir)/plugins \
diff --git a/configure.ac b/configure.ac
index e48a3cc..aa8bfb0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -136,6 +136,13 @@ if (test "${phonebook_driver}" = "ebook"); then
 	AC_SUBST(GTHREAD_LIBS)
 fi
 
+if (test "${phonebook_driver}" = "tracker"); then
+	PKG_CHECK_MODULES(TRACKER_SPARQL, tracker-sparql-0.9, dummy=yes,
+				AC_MSG_ERROR(libtracker-sparql is required))
+	AC_SUBST(TRACKER_SPARQL_CFLAGS)
+	AC_SUBST(TRACKER_SPARQL_LIBS)
+fi
+
 AC_SUBST([PHONEBOOK_DRIVER], [phonebook-${phonebook_driver}.c])
 
 AC_ARG_ENABLE(server, AC_HELP_STRING([--disable-server],
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH 1/2] Fix possible crash on AVDTP Suspend req timeout
From: Johan Hedberg @ 2011-02-02 10:10 UTC (permalink / raw)
  To: Dmitriy Paliy; +Cc: linux-bluetooth
In-Reply-To: <1296632538-2784-1-git-send-email-dmitriy.paliy@nokia.com>

Hi Dmitriy,

On Wed, Feb 02, 2011, Dmitriy Paliy wrote:
> This fixes possible bluetoothd crash on AVDTP Suspend request timeout
> if A2DP client was destroyed after the request was sent but before its
> timeout handled.
> 
> If Suspend request times out due to any reason, then references to A2DP
> session and stream are cleared in unix_client. Therefore, callback cannot
> be removed when unix_client is destroyed (e.g. on incomming call).
> 
> After that, consequent Abort request is sent. If the request times out
> as well, than stream_state_changed callback is invoked to change AVDTP
> state to Idle, which causes crash due to NULL dereferencing.
> 
> Therefore, it is important to keep references to AVDTP session and stream
> in unix_client until it is destroyed.
> ---
>  audio/unix.c |   15 ++++-----------
>  1 files changed, 4 insertions(+), 11 deletions(-)

Thanks. Both patches have been pushed upstream.

Johan

^ permalink raw reply

* [PATCH 3/3] Use libtracker-sparql in PBAP
From: Radoslaw Jablonski @ 2011-02-02  8:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1296634531-32164-1-git-send-email-ext-jablonski.radoslaw@nokia.com>

Now direct tracker connection for transporting retrieved
parts of data is used, instead of D-Bus. This should result better
performance for PBAP requests.
Each part of results is now fetched from tracker asynchronously
and getting more results can be stopped in any moment -
GCancellable stored in phonebook_data is used for that purpose.
If processing of data has finished (or it was cancelled) then cleanup
of pending_reply is done in last invocation of
async_query_cursor_next_cb.
---
 plugins/phonebook-tracker.c |  261 ++++++++++++++++++++++--------------------
 1 files changed, 137 insertions(+), 124 deletions(-)

diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 3b61d6b..a609269 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -29,6 +29,7 @@
 #include <dbus/dbus.h>
 #include <openobex/obex.h>
 #include <openobex/obex_const.h>
+#include <libtracker-sparql/tracker-sparql.h>
 
 #include "log.h"
 #include "obex.h"
@@ -891,7 +892,9 @@
 	"} GROUP BY ?call ORDER BY DESC(nmo:receivedDate(?call)) "	\
 	"LIMIT 40"
 
-typedef void (*reply_list_foreach_t) (char **reply, int num_fields,
+
+
+typedef void (*reply_list_foreach_t) (const char **reply, int num_fields,
 							void *user_data);
 
 typedef void (*add_field_t) (struct phonebook_contact *contact,
@@ -918,7 +921,7 @@ struct phonebook_data {
 	phonebook_cache_ready_cb ready_cb;
 	phonebook_entry_cb entry_cb;
 	int newmissedcalls;
-	DBusPendingCall *call;
+	GCancellable *query_canc;
 };
 
 struct phonebook_index {
@@ -926,7 +929,7 @@ struct phonebook_index {
 	int index;
 };
 
-static DBusConnection *connection = NULL;
+static TrackerSparqlConnection *connection = NULL;
 
 static const char *name2query(const char *name)
 {
@@ -999,131 +1002,127 @@ static const char *folder2query(const char *folder)
 	return NULL;
 }
 
-static char **string_array_from_iter(DBusMessageIter iter, int array_len)
+static const char **string_array_from_cursor(TrackerSparqlCursor *cursor,
+								int array_len)
 {
-	DBusMessageIter sub;
-	char **result;
+	const char **result;
 	int i;
 
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
-		return NULL;
-
-	result = g_new0(char *, array_len);
-
-	dbus_message_iter_recurse(&iter, &sub);
-
-	i = 0;
-	while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
-		char *arg;
-
-		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) {
-			g_free(result);
-			return NULL;
-		}
+	result = g_new0(const char *, array_len);
 
-		dbus_message_iter_get_basic(&sub, &arg);
+	for(i = 0;i < array_len;++i) {
+		TrackerSparqlValueType type;
 
-		result[i] = arg;
+		type = tracker_sparql_cursor_get_value_type (cursor,i);
 
-		i++;
-		dbus_message_iter_next(&sub);
+		if (type == TRACKER_SPARQL_VALUE_TYPE_BLANK_NODE ||
+				type == TRACKER_SPARQL_VALUE_TYPE_UNBOUND)
+			/* For null/unbound type filling result part with ""*/
+			result[i] = "";
+		else
+			/* Filling with string representation of content*/
+			result[i] = tracker_sparql_cursor_get_string(cursor, i,
+									NULL);
 	}
 
 	return result;
 }
 
-static void query_reply(DBusPendingCall *call, void *user_data)
+
+static void query_free_data(void *user_data)
 {
-	DBusMessage *reply = dbus_pending_call_steal_reply(call);
+	DBG("");
 	struct pending_reply *pending = user_data;
-	DBusMessageIter iter, element;
-	DBusError derr;
-	int err;
-
-	dbus_error_init(&derr);
-	if (dbus_set_error_from_message(&derr, reply)) {
-		error("Replied with an error: %s, %s", derr.name,
-							derr.message);
-		dbus_error_free(&derr);
-
-		err = -1;
-		goto done;
-	}
 
-	dbus_message_iter_init(reply, &iter);
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
-		error("SparqlQuery reply is not an array");
-
-		err = -1;
-		goto done;
-	}
-
-	dbus_message_iter_recurse(&iter, &element);
-
-	err = 0;
+	if (!pending)
+		return;
 
-	while (dbus_message_iter_get_arg_type(&element) != DBUS_TYPE_INVALID) {
-		char **node;
+	g_free(pending);
+}
 
-		if (dbus_message_iter_get_arg_type(&element) !=
-						DBUS_TYPE_ARRAY) {
-			error("element is not an array");
-			goto done;
-		}
+static void update_cancellable(struct phonebook_data *pdata, GCancellable *canc)
+{
+	if (pdata->query_canc)
+		g_object_unref(pdata->query_canc);
 
-		node = string_array_from_iter(element, pending->num_fields);
-		pending->callback(node, pending->num_fields,
-							pending->user_data);
+	pdata->query_canc = canc;
+}
 
-		g_free(node);
+static void async_query_cursor_next_cb(GObject *source, GAsyncResult *result,
+							gpointer user_data)
+{
+	struct pending_reply *pending = user_data;
+	TrackerSparqlCursor *cursor = TRACKER_SPARQL_CURSOR (source);
+	GCancellable *cancellable;
+	GError *error = NULL;
+	gboolean success;
+	const char **node;
+
+	success = tracker_sparql_cursor_next_finish(
+						TRACKER_SPARQL_CURSOR (source),
+						result,
+						&error);
+
+	if(!success) {
+		if (!error)
+			/* When tracker_sparql_cursor_next_finish ends with
+			 * failure and no error is set, that means end of
+			 * results returned by query */
+			pending->callback(NULL, 0, pending->user_data);
 
-		dbus_message_iter_next(&element);
+		goto failed;
 	}
 
-done:
-	/* This is the last entry */
-	pending->callback(NULL, err, pending->user_data);
-
-	dbus_message_unref(reply);
-
-	/* pending data is freed in query_free_data after call is unreffed. */
-}
+	node = string_array_from_cursor(cursor, pending->num_fields);
+	pending->callback(node, pending->num_fields, pending->user_data);
+	g_free(node);
 
-static void query_free_data(void *user_data)
-{
-	struct pending_reply *pending = user_data;
 
-	if (!pending)
-		return;
+	/* getting next row from query results */
+	cancellable = g_cancellable_new();
+	update_cancellable(pending->user_data, cancellable);
+	tracker_sparql_cursor_next_async(cursor, cancellable,
+						async_query_cursor_next_cb,
+						pending);
+	return;
 
-	g_free(pending);
+failed:
+	g_object_unref(cursor);
+	query_free_data(pending);
 }
 
-static DBusPendingCall *query_tracker(const char *query, int num_fields,
-		reply_list_foreach_t callback, void *user_data, int *err)
+static void query_tracker(const char *query, int num_fields,
+				reply_list_foreach_t callback, void *user_data,
+				int *err)
+
 {
 	struct pending_reply *pending;
-	DBusPendingCall *call;
-	DBusMessage *msg;
+	GCancellable *cancellable;
+	TrackerSparqlCursor *cursor;
+	GError *error = NULL;
+
+	DBG("");
 
 	if (connection == NULL)
-		connection = obex_dbus_get_connection();
+		connection = tracker_sparql_connection_get_direct (NULL,
+									&error);
 
-	msg = dbus_message_new_method_call(TRACKER_SERVICE,
-			TRACKER_RESOURCES_PATH, TRACKER_RESOURCES_INTERFACE,
-								"SparqlQuery");
+	if (!connection) {
+		DBG("Direct-tracker connection failed");
 
-	dbus_message_append_args(msg, DBUS_TYPE_STRING, &query,
-						DBUS_TYPE_INVALID);
+		goto failed;
+	}
 
-	if (dbus_connection_send_with_reply(connection, msg, &call,
-							-1) == FALSE) {
-		error("Could not send dbus message");
-		dbus_message_unref(msg);
-		if (err)
-			*err = -EPERM;
-		return NULL;
+	cancellable = g_cancellable_new();
+	update_cancellable(user_data, cancellable);
+	cursor = tracker_sparql_connection_query(connection, query, cancellable,
+									&error);
+
+	if (cursor == NULL || error) {
+		g_object_unref(cancellable);
+		g_object_unref(cursor);
+
+		goto failed;
 	}
 
 	pending = g_new0(struct pending_reply, 1);
@@ -1131,14 +1130,21 @@ static DBusPendingCall *query_tracker(const char *query, int num_fields,
 	pending->user_data = user_data;
 	pending->num_fields = num_fields;
 
-	dbus_pending_call_set_notify(call, query_reply, pending,
-							query_free_data);
-	dbus_message_unref(msg);
+	/* Now asynchronously going through each row of results - callback
+	 * async_query_cursor_next_cb will be called ALWAYS, even if async
+	 * request was canceled */
+	tracker_sparql_cursor_next_async(cursor, cancellable,
+						async_query_cursor_next_cb,
+						pending);
 
 	if (err)
 		*err = 0;
 
-	return call;
+	return;
+
+failed:
+	if (err)
+		*err = -EPERM;
 }
 
 static char *iso8601_utc_to_localtime(const char *datetime)
@@ -1326,12 +1332,14 @@ static GString *gen_vcards(GSList *contacts,
 		struct contact_data *c_data = l->data;
 		phonebook_add_contact(vcards, c_data->contact,
 					params->filter, params->format);
+
 	}
 
 	return vcards;
 }
 
-static void pull_contacts_size(char **reply, int num_fields, void *user_data)
+static void pull_contacts_size(const char **reply, int num_fields,
+							void *user_data)
 {
 	struct phonebook_data *data = user_data;
 
@@ -1363,7 +1371,7 @@ static void add_affiliation(char **field, const char *value)
 	*field = g_strdup(value);
 }
 
-static void contact_init(struct phonebook_contact *contact, char **reply)
+static void contact_init(struct phonebook_contact *contact,const char **reply)
 {
 
 	contact->fullname = g_strdup(reply[COL_FULL_NAME]);
@@ -1395,8 +1403,8 @@ static enum phonebook_number_type get_phone_type(const char *affilation)
 	return TEL_TYPE_OTHER;
 }
 
-static void add_aff_number(struct phonebook_contact *contact, char *pnumber,
-								char *aff_type)
+static void add_aff_number(struct phonebook_contact *contact,
+				const char *pnumber, const char *aff_type)
 {
 	char **num_parts;
 	char *type, *number;
@@ -1433,7 +1441,7 @@ failed:
 }
 
 static void contact_add_numbers(struct phonebook_contact *contact,
-								char **reply)
+							const char **reply)
 {
 	char **aff_numbers;
 	int i;
@@ -1459,8 +1467,8 @@ static enum phonebook_field_type get_field_type(const char *affilation)
 	return FIELD_TYPE_OTHER;
 }
 
-static void add_aff_field(struct phonebook_contact *contact, char *aff_email,
-						add_field_t add_field_cb)
+static void add_aff_field(struct phonebook_contact *contact,
+				const char *aff_email, add_field_t add_field_cb)
 {
 	char **email_parts;
 	char *type, *email;
@@ -1490,7 +1498,7 @@ failed:
 }
 
 static void contact_add_emails(struct phonebook_contact *contact,
-								char **reply)
+							const char **reply)
 {
 	char **aff_emails;
 	int i;
@@ -1506,7 +1514,7 @@ static void contact_add_emails(struct phonebook_contact *contact,
 }
 
 static void contact_add_addresses(struct phonebook_contact *contact,
-								char **reply)
+							const char **reply)
 {
 	char **aff_addr;
 	int i;
@@ -1522,7 +1530,8 @@ static void contact_add_addresses(struct phonebook_contact *contact,
 	g_strfreev(aff_addr);
 }
 
-static void contact_add_urls(struct phonebook_contact *contact, char **reply)
+static void contact_add_urls(struct phonebook_contact *contact,
+							const char **reply)
 {
 	char **aff_url;
 	int i;
@@ -1538,7 +1547,7 @@ static void contact_add_urls(struct phonebook_contact *contact, char **reply)
 }
 
 static void contact_add_organization(struct phonebook_contact *contact,
-								char **reply)
+							const char **reply)
 {
 	/* Adding fields connected by nco:hasAffiliation - they may be in
 	 * separate replies */
@@ -1548,7 +1557,7 @@ static void contact_add_organization(struct phonebook_contact *contact,
 	add_affiliation(&contact->role, reply[COL_ORG_ROLE]);
 }
 
-static void pull_contacts(char **reply, int num_fields, void *user_data)
+static void pull_contacts(const char **reply, int num_fields, void *user_data)
 {
 	struct phonebook_data *data = user_data;
 	const struct apparam_field *params = data->params;
@@ -1649,7 +1658,7 @@ fail:
 	 */
 }
 
-static void add_to_cache(char **reply, int num_fields, void *user_data)
+static void add_to_cache(const char **reply, int num_fields, void *user_data)
 {
 	struct phonebook_data *data = user_data;
 	char *formatted;
@@ -1699,6 +1708,9 @@ done:
 
 int phonebook_init(void)
 {
+	g_thread_init(NULL);
+	g_type_init();
+
 	return 0;
 }
 
@@ -1792,12 +1804,13 @@ void phonebook_req_finalize(void *request)
 	if (!data)
 		return;
 
-	if (!dbus_pending_call_get_completed(data->call))
-		dbus_pending_call_cancel(data->call);
-
-	dbus_pending_call_unref(data->call);
+	/* canceling asynchronous operation on tracker if any is active */
+	if(data->query_canc) {
+		g_cancellable_cancel(data->query_canc);
+		g_object_unref(data->query_canc);
+	}
 
-	/* freeing list of contacts used for generating vcards */
+	/* freeing contacts */
 	for (l = data->contacts; l; l = l->next) {
 		struct contact_data *c_data = l->data;
 
@@ -1828,7 +1841,8 @@ static void gstring_free_helper(gpointer data, gpointer user_data)
 	g_string_free(data, TRUE);
 }
 
-static void pull_newmissedcalls(char **reply, int num_fields, void *user_data)
+static void pull_newmissedcalls(const char **reply, int num_fields,
+								void *user_data)
 {
 	struct phonebook_data *data = user_data;
 	reply_list_foreach_t pull_cb;
@@ -1870,8 +1884,7 @@ done:
 		pull_cb = pull_contacts;
 	}
 
-	dbus_pending_call_unref(data->call);
-	data->call = query_tracker(query, col_amount, pull_cb, data, &err);
+	query_tracker(query, col_amount, pull_cb, data, &err);
 	if (err < 0)
 		data->cb(NULL, 0, err, 0, data->user_data);
 }
@@ -1910,7 +1923,7 @@ void *phonebook_pull(const char *name, const struct apparam_field *params,
 	data->params = params;
 	data->user_data = user_data;
 	data->cb = cb;
-	data->call = query_tracker(query, col_amount, pull_cb, data, err);
+	query_tracker(query, col_amount, pull_cb, data, err);
 
 	return data;
 }
@@ -1938,8 +1951,8 @@ void *phonebook_get_entry(const char *folder, const char *id,
 		query = g_strdup_printf(CONTACTS_OTHER_QUERY_FROM_URI,
 								id, id, id);
 
-	data->call = query_tracker(query, PULL_QUERY_COL_AMOUNT, pull_contacts,
-								data, err);
+	query_tracker(query, PULL_QUERY_COL_AMOUNT,
+						pull_contacts, data, err);
 
 	g_free(query);
 
@@ -1965,7 +1978,7 @@ void *phonebook_create_cache(const char *name, phonebook_entry_cb entry_cb,
 	data->entry_cb = entry_cb;
 	data->ready_cb = ready_cb;
 	data->user_data = user_data;
-	data->call = query_tracker(query, 7, add_to_cache, data, err);
+	query_tracker(query, 7, add_to_cache, data, err);
 
 	return data;
 }
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 2/3] Move freeing contacts data to phonebook_req_finalize
From: Radoslaw Jablonski @ 2011-02-02  8:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1296634531-32164-1-git-send-email-ext-jablonski.radoslaw@nokia.com>

Previously data used for generating vcards was freed only in
gen_vcards body. This may result a memory leak, if fetching data
from tracker was cancelled in the middle of process and gen_vcards
wasn't called. Phonebook_req_finalize is better place for this
kind of cleanup.
---
 plugins/phonebook-tracker.c |   14 ++++++++++----
 1 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index e60cf74..3b61d6b 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -1326,10 +1326,6 @@ static GString *gen_vcards(GSList *contacts,
 		struct contact_data *c_data = l->data;
 		phonebook_add_contact(vcards, c_data->contact,
 					params->filter, params->format);
-
-		g_free(c_data->id);
-		phonebook_contact_free(c_data->contact);
-		g_free(c_data);
 	}
 
 	return vcards;
@@ -1789,6 +1785,7 @@ done:
 void phonebook_req_finalize(void *request)
 {
 	struct phonebook_data *data = request;
+	GSList *l;
 
 	DBG("");
 
@@ -1800,6 +1797,15 @@ void phonebook_req_finalize(void *request)
 
 	dbus_pending_call_unref(data->call);
 
+	/* freeing list of contacts used for generating vcards */
+	for (l = data->contacts; l; l = l->next) {
+		struct contact_data *c_data = l->data;
+
+		g_free(c_data->id);
+		phonebook_contact_free(c_data->contact);
+		g_free(c_data);
+	}
+
 	g_slist_free(data->contacts);
 	g_free(data);
 }
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 1/3] Add libtracker-sparql to obexd dependencies
From: Radoslaw Jablonski @ 2011-02-02  8:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski

In PBAP tracker is used only for reading and returns rather big
parts of data, so using direct access libtracker-sparql is better
solution than tracker D-Bus API(libtracker-sparql in most PBAP
scenarios should be faster).
---
 Makefile.am  |    4 +++-
 configure.ac |    7 +++++++
 2 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index a317556..fc996ec 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -79,7 +79,8 @@ src_obexd_SOURCES = $(gdbus_sources) $(builtin_sources) $(btio_sources) \
 
 src_obexd_LDADD = @DBUS_LIBS@ @GLIB_LIBS@ @GTHREAD_LIBS@ \
 					@EBOOK_LIBS@ @OPENOBEX_LIBS@ \
-					@BLUEZ_LIBS@ @LIBICAL_LIBS@ -ldl
+					@BLUEZ_LIBS@ @LIBICAL_LIBS@ \
+					@TRACKER_SPARQL_LIBS@ -ldl
 
 src_obexd_LDFLAGS = -Wl,--export-dynamic
 
@@ -124,6 +125,7 @@ service_DATA = $(service_in_files:.service.in=.service)
 AM_CFLAGS = @OPENOBEX_CFLAGS@ @BLUEZ_CFLAGS@ @EBOOK_CFLAGS@ \
 			@GTHREAD_CFLAGS@ @GLIB_CFLAGS@ @DBUS_CFLAGS@ \
 			@LIBICAL_CFLAGS@ -D_FILE_OFFSET_BITS=64 \
+			@TRACKER_SPARQL_CFLAGS@ \
 			-DOBEX_PLUGIN_BUILTIN -DPLUGINDIR=\""$(plugindir)"\"
 
 INCLUDES = -I$(builddir)/src -I$(srcdir)/src -I$(srcdir)/plugins \
diff --git a/configure.ac b/configure.ac
index e48a3cc..aa8bfb0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -136,6 +136,13 @@ if (test "${phonebook_driver}" = "ebook"); then
 	AC_SUBST(GTHREAD_LIBS)
 fi
 
+if (test "${phonebook_driver}" = "tracker"); then
+	PKG_CHECK_MODULES(TRACKER_SPARQL, tracker-sparql-0.9, dummy=yes,
+				AC_MSG_ERROR(libtracker-sparql is required))
+	AC_SUBST(TRACKER_SPARQL_CFLAGS)
+	AC_SUBST(TRACKER_SPARQL_LIBS)
+fi
+
 AC_SUBST([PHONEBOOK_DRIVER], [phonebook-${phonebook_driver}.c])
 
 AC_ARG_ENABLE(server, AC_HELP_STRING([--disable-server],
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 2/2] Code cleanup: unnesessary line removed in avdtp.c
From: Dmitriy Paliy @ 2011-02-02  7:42 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Dmitriy Paliy
In-Reply-To: <1296632538-2784-1-git-send-email-dmitriy.paliy@nokia.com>

---
 audio/avdtp.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/audio/avdtp.c b/audio/avdtp.c
index 88e3e8a..cd57747 100644
--- a/audio/avdtp.c
+++ b/audio/avdtp.c
@@ -2666,7 +2666,6 @@ static int send_req(struct avdtp *session, gboolean priority,
 		goto failed;
 	}
 
-
 	session->req = req;
 
 	req->timeout = g_timeout_add_seconds(req->signal_id == AVDTP_ABORT ?
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 1/2] Fix possible crash on AVDTP Suspend req timeout
From: Dmitriy Paliy @ 2011-02-02  7:42 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Dmitriy Paliy

This fixes possible bluetoothd crash on AVDTP Suspend request timeout
if A2DP client was destroyed after the request was sent but before its
timeout handled.

If Suspend request times out due to any reason, then references to A2DP
session and stream are cleared in unix_client. Therefore, callback cannot
be removed when unix_client is destroyed (e.g. on incomming call).

After that, consequent Abort request is sent. If the request times out
as well, than stream_state_changed callback is invoked to change AVDTP
state to Idle, which causes crash due to NULL dereferencing.

Therefore, it is important to keep references to AVDTP session and stream
in unix_client until it is destroyed.
---
 audio/unix.c |   15 ++++-----------
 1 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/audio/unix.c b/audio/unix.c
index a4b92f4..3c47510 100644
--- a/audio/unix.c
+++ b/audio/unix.c
@@ -836,7 +836,6 @@ static void a2dp_suspend_complete(struct avdtp *session,
 	struct unix_client *client = user_data;
 	char buf[BT_SUGGESTED_BUFFER_SIZE];
 	struct bt_stop_stream_rsp *rsp = (void *) buf;
-	struct a2dp_data *a2dp = &client->d.a2dp;
 
 	if (err)
 		goto failed;
@@ -854,15 +853,6 @@ failed:
 	error("suspend failed");
 
 	unix_ipc_error(client, BT_STOP_STREAM, EIO);
-
-	if (a2dp->sep) {
-		a2dp_sep_unlock(a2dp->sep, a2dp->session);
-		a2dp->sep = NULL;
-	}
-
-	avdtp_unref(a2dp->session);
-	a2dp->session = NULL;
-	a2dp->stream = NULL;
 }
 
 static void start_discovery(struct audio_device *dev, struct unix_client *client)
@@ -1272,9 +1262,11 @@ static void start_close(struct audio_device *dev, struct unix_client *client,
 	case TYPE_SINK:
 		a2dp = &client->d.a2dp;
 
-		if (client->cb_id > 0)
+		if (client->cb_id > 0) {
 			avdtp_stream_remove_cb(a2dp->session, a2dp->stream,
 								client->cb_id);
+			client->cb_id = 0;
+		}
 		if (a2dp->sep) {
 			a2dp_sep_unlock(a2dp->sep, a2dp->session);
 			a2dp->sep = NULL;
@@ -1283,6 +1275,7 @@ static void start_close(struct audio_device *dev, struct unix_client *client,
 			avdtp_unref(a2dp->session);
 			a2dp->session = NULL;
 		}
+		a2dp->stream = NULL;
 		break;
 	default:
 		error("No known services for device");
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH 1/2] Fix sending HCIDEVUP when adapter is already up
From: Johan Hedberg @ 2011-02-01 23:22 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1296575248-20185-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Tue, Feb 01, 2011, Luiz Augusto von Dentz wrote:
> There is no need for HCIDEVUP/fork in such cases it will just consume
> more resources for no reason.
> 
> To fix this HCI_DEV_REG is no longer generate for adapter already up
> instead init_device is called directly which simplify the code path.
> ---
>  plugins/hciops.c |   15 +++++++++++----
>  1 files changed, 11 insertions(+), 4 deletions(-)

Both patches have been pushed upstream. Thanks.

Johan

^ permalink raw reply

* [PATCH 2/2] Fix stopping inquiry before adapter object is initialized
From: Luiz Augusto von Dentz @ 2011-02-01 15:47 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1296575248-20185-1-git-send-email-luiz.dentz@gmail.com>

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

This can cause errors on command complete since the adapter object could
not be found to set its mode.
---
 plugins/hciops.c |   50 ++++++++++++++++++++++++++------------------------
 1 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/plugins/hciops.c b/plugins/hciops.c
index 80ae61a..e5160ea 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -455,6 +455,29 @@ static void start_adapter(int index)
 	memset(dev->eir, 0, sizeof(dev->eir));
 }
 
+static int hciops_stop_inquiry(int index)
+{
+	struct dev_info *dev = &devs[index];
+	struct hci_dev_info di;
+	int err;
+
+	DBG("hci%d", index);
+
+	if (hci_devinfo(index, &di) < 0)
+		return -errno;
+
+	if (hci_test_bit(HCI_INQUIRY, &di.flags))
+		err = hci_send_cmd(dev->sk, OGF_LINK_CTL,
+						OCF_INQUIRY_CANCEL, 0, 0);
+	else
+		err = hci_send_cmd(dev->sk, OGF_LINK_CTL,
+					OCF_EXIT_PERIODIC_INQUIRY, 0, 0);
+	if (err < 0)
+		err = -errno;
+
+	return err;
+}
+
 static gboolean init_adapter(int index)
 {
 	struct dev_info *dev = &devs[index];
@@ -494,6 +517,9 @@ static gboolean init_adapter(int index)
 	hciops_set_discoverable(index, discoverable);
 	hciops_set_pairable(index, pairable);
 
+	if (dev->already_up)
+		hciops_stop_inquiry(index);
+
 done:
 	btd_adapter_unref(adapter);
 	return TRUE;
@@ -2600,29 +2626,6 @@ static void device_event(int event, int index)
 	}
 }
 
-static int hciops_stop_inquiry(int index)
-{
-	struct dev_info *dev = &devs[index];
-	struct hci_dev_info di;
-	int err;
-
-	DBG("hci%d", index);
-
-	if (hci_devinfo(index, &di) < 0)
-		return -errno;
-
-	if (hci_test_bit(HCI_INQUIRY, &di.flags))
-		err = hci_send_cmd(dev->sk, OGF_LINK_CTL,
-						OCF_INQUIRY_CANCEL, 0, 0);
-	else
-		err = hci_send_cmd(dev->sk, OGF_LINK_CTL,
-					OCF_EXIT_PERIODIC_INQUIRY, 0, 0);
-	if (err < 0)
-		err = -errno;
-
-	return err;
-}
-
 static gboolean init_known_adapters(gpointer user_data)
 {
 	struct hci_dev_list_req *dl;
@@ -2666,7 +2669,6 @@ static gboolean init_known_adapters(gpointer user_data)
 			continue;
 
 		init_conn_list(dr->dev_id);
-		hciops_stop_inquiry(dr->dev_id);
 
 		dev->pending = 0;
 		hci_set_bit(PENDING_VERSION, &dev->pending);
-- 
1.7.1


^ permalink raw reply related

* [PATCH 1/2] Fix sending HCIDEVUP when adapter is already up
From: Luiz Augusto von Dentz @ 2011-02-01 15:47 UTC (permalink / raw)
  To: linux-bluetooth

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

There is no need for HCIDEVUP/fork in such cases it will just consume
more resources for no reason.

To fix this HCI_DEV_REG is no longer generate for adapter already up
instead init_device is called directly which simplify the code path.
---
 plugins/hciops.c |   15 +++++++++++----
 1 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/plugins/hciops.c b/plugins/hciops.c
index ecfcec3..80ae61a 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -2458,7 +2458,7 @@ static void init_pending(int index)
 	hci_set_bit(PENDING_NAME, &dev->pending);
 }
 
-static void init_device(int index)
+static void init_device(int index, gboolean already_up)
 {
 	struct hci_dev_req dr;
 	int dd;
@@ -2482,6 +2482,10 @@ static void init_device(int index)
 	init_pending(index);
 	start_hci_dev(index);
 
+	/* Avoid forking if nothing else has to be done */
+	if (already_up)
+		return;
+
 	/* Do initialization in the separate process */
 	pid = fork();
 	switch (pid) {
@@ -2562,7 +2566,7 @@ static void device_event(int event, int index)
 	switch (event) {
 	case HCI_DEV_REG:
 		info("HCI dev %d registered", index);
-		init_device(index);
+		init_device(index, FALSE);
 		break;
 
 	case HCI_DEV_UNREG:
@@ -2648,12 +2652,15 @@ static gboolean init_known_adapters(gpointer user_data)
 
 	for (i = 0; i < dl->dev_num; i++, dr++) {
 		struct dev_info *dev;
+		gboolean already_up;
+
+		already_up = hci_test_bit(HCI_UP, &dr->dev_opt);
 
-		device_event(HCI_DEV_REG, dr->dev_id);
+		init_device(dr->dev_id, already_up);
 
 		dev = &devs[dr->dev_id];
 
-		dev->already_up = hci_test_bit(HCI_UP, &dr->dev_opt);
+		dev->already_up = already_up;
 
 		if (!dev->already_up)
 			continue;
-- 
1.7.1


^ permalink raw reply related

* Re: A2DP reconfigure with BMW Carkit (supporting multi streams) timeouts.
From: Lukasz Rymanowski @ 2011-02-01 14:16 UTC (permalink / raw)
  To: roystonr
  Cc: Luiz Augusto von Dentz, Johan Hedberg, linux-bluetooth, skrovvid,
	rshaffer
In-Reply-To: <2ec0d2a2febdbcf4ab73812ad709f542.squirrel@www.codeaurora.org>

Hi Roystonr,

> Have provided the patch to the tester to verify as we don't have the BMW
> CK available locally. Would update the feedback received.

I'm just wondering, Is it working for you ?

>
> Regards,
> Royston Rodrigues
>

Regards
\Lukasz

^ permalink raw reply

* Re: [PATCH v5 0/4] Adding HID Feature Report Support to hidraw
From: Antonio Ospite @ 2011-02-01 11:47 UTC (permalink / raw)
  To: Alan Ott
  Cc: Jiri Kosina, Marcel Holtmann, Gustavo F. Padovan, David S. Miller,
	Michael Poole, Eric Dumazet, linux-input, linux-kernel, linux-usb,
	linux-bluetooth, netdev, Bastien Nocera
In-Reply-To: <1295337880-12452-1-git-send-email-alan@signal11.us>

[-- Attachment #1: Type: text/plain, Size: 942 bytes --]

On Tue, 18 Jan 2011 03:04:36 -0500
Alan Ott <alan@signal11.us> wrote:

> This patch adds Feature Report support for USB and Bluetooth HID devices
> through hidraw.
> 
> The first two patches prepare the bluetooth side for the change.
> 	a. Make sure the hidp_session() thread is started before
> 	   device's probe() functions are called.
> 	b. Wait for ACK/NAK on sent reports, and return proper
> 	   error codes.
> The third patch is the hidraw core and USB changes.

In particular, this third patch is a prerequisite for the bluez
sixaxis-cable plugin, originally written by Bastien Nocera (added to
CC) which I plan to submit when these changes are merged in mainline
linux.

[...]

-- 
Antonio Ospite
http://ao2.it

PGP public key ID: 0x4553B001

A: Because it messes up the order in which people normally read text.
   See http://en.wikipedia.org/wiki/Posting_style
Q: Why is top-posting such a bad thing?

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply

* Re: [PATCH 1/2] Implement dump for event LE Read Remote Used Features Complete.
From: Johan Hedberg @ 2011-02-01  9:12 UTC (permalink / raw)
  To: Andre Dieb Martins; +Cc: linux-bluetooth
In-Reply-To: <1296500972-14105-1-git-send-email-andre.dieb@signove.com>

Hi André

On Mon, Jan 31, 2011, Andre Dieb Martins wrote:
> ---
>  parser/hci.c |   23 +++++++++++++++++++++++
>  1 files changed, 23 insertions(+), 0 deletions(-)

Both patches have been pushed upstream. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH] Fix hciconfig leadv returned response.
From: Johan Hedberg @ 2011-02-01  9:10 UTC (permalink / raw)
  To: Andre Dieb Martins; +Cc: linux-bluetooth
In-Reply-To: <1296500253-11888-1-git-send-email-andre.dieb@signove.com>

Hi André,

On Mon, Jan 31, 2011, Andre Dieb Martins wrote:
> Fixes hciconfig leadv returned response by treating both status of the command
> execution and HCI error code.
> ---
>  tools/hciconfig.c |   15 ++++++++++++---
>  1 files changed, 12 insertions(+), 3 deletions(-)

The patch has been pushed upstream. Thanks. However, I did have to fix
your commit message first: the summary line should not have a '.' at the
end and no line should be longer than 74 characters so that the message
is properly viewable with git log on a 80 character wide terminal.

Johan

^ permalink raw reply

* Re: [PATCH 2/6 v2] Add an interactive mode to gatttool
From: Johan Hedberg @ 2011-02-01  9:03 UTC (permalink / raw)
  To: Sheldon Demario; +Cc: linux-bluetooth
In-Reply-To: <1296494878-27221-1-git-send-email-sheldon.demario@openbossa.org>

On Mon, Jan 31, 2011, Sheldon Demario wrote:
> +static gboolean cmd_connect(gpointer cmd)
> +{
> +	const char **c = (const char **) cmd;
> +	if (conn_state != STATE_DISCONNECTED)

Missing line after the variable declaration and unnecessary explicit
type-cast (no need for void pointers). However why does this function
take a gpointer to begin with? I'd imagine the most convenient thing to
give the command handlers either a char* with the entire command line or
a pre-parsed argc + argv with the help of g_shell_parse_argv.

> +	if (c[1] != NULL) {

Now that's just ugly. Much better if you use g_shell_parse_argv and then
you can use the usual getopt to separate switches from mandatory
parameters, etc.

> +static struct {
> +	char *cmd;

I suppose this should be const char *

> +	gboolean (*func)(gpointer cmd);

As I mentioned, instead of gpointer do char * or then (what I'd prefer)
simply argc + argv.

> +	char *param;

Again, const

> +	char *desc;

Same here.

> +} commands[] = {
> +	{ "connect",	cmd_connect,	"<bdaddr>",	"Connect"},
> +	{ "disconnect",	cmd_disconnect,	NULL,		"Disconnect"},
> +	{ "characteristics",	characteristics,	NULL,
> +						"Characteristcs Discovery"},
> +	{ NULL, NULL, NULL, NULL}
> +};

Where's the "help" command? That's the first one I'd expect to be
implemented. Also, ctrl-d and "exit" should work from the start as ways
of exiting the program.

> +static void parse_line(char *line_read)
> +{
> +	char **command;
> +	int j;

Why j and not i?

> +static int do_interactive(void)

Didn't I tell you to do all the interactive stuff away from the main
gatttool.c file? There should only be the parsing of command line
parameters and a call to the interactive .c file in the case of
interactive mode.

Johan

^ permalink raw reply

* Re: [PATCH 1/2 v3] Fix creating device object when connection fails
From: Johan Hedberg @ 2011-02-01  8:30 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1296548930-23062-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Tue, Feb 01, 2011, Luiz Augusto von Dentz wrote:
> There is no need to create a new object since there is no connection and
> the device is not permanent/paired.
> ---
>  src/event.c |    7 ++++++-
>  1 files changed, 6 insertions(+), 1 deletions(-)

Thanks. This one has been pushed upstream now. I'll skip 2/2 since it
should never happen that there's a connection without a corresponding
device object.

Johan

^ permalink raw reply

* [PATCH 1/2 v3] Fix creating device object when connection fails
From: Luiz Augusto von Dentz @ 2011-02-01  8:28 UTC (permalink / raw)
  To: linux-bluetooth

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

There is no need to create a new object since there is no connection and
the device is not permanent/paired.
---
 src/event.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/src/event.c b/src/event.c
index ff768c0..cbaf9d7 100644
--- a/src/event.c
+++ b/src/event.c
@@ -676,7 +676,12 @@ void btd_event_conn_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t status)
 	struct btd_device *device;
 	DBusConnection *conn = get_dbus_connection();
 
-	if (!get_adapter_and_device(local, peer, &adapter, &device, TRUE))
+	DBG("status 0x%02x", status);
+
+	if (!get_adapter_and_device(local, peer, &adapter, &device, FALSE))
+		return;
+
+	if (!device)
 		return;
 
 	if (device_is_temporary(device))
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH] Set connection state to BT_DISCONN to avoid multiple responses
From: Liang Bao @ 2011-02-01  3:44 UTC (permalink / raw)
  To: Ville Tervo; +Cc: linux-bluetooth
In-Reply-To: <20110131075723.GO874@null>

2011/1/31 Ville Tervo <ville.tervo@nokia.com>:
> Hi,
>
> On Sat, Jan 29, 2011 at 09:39:37PM +0800, ext Liang Bao wrote:
>> From: Bao Liang <tim.bao@gmail.com>
>>
>> This patch fixes a minor issue that two connection responses will be sent
>> for one L2CAP connection request. If the L2CAP connection request is first
>> blocked due to security reason and responded with reason "security block",
>> the state of the connection remains BT_CONNECT2. If a pairing procedure
>> completes successfully before the ACL connection is down, local host will
>> send another connection complete response. See the following packets
>> captured by hcidump.
>>
>> 2010-12-07 22:21:24.928096 < ACL data: handle 12 flags 0x00 dlen 16
>>     0000: 0c 00 01 00 03 19 08 00  41 00 53 00 03 00 00 00  ........A.S.....
>> ... ...
>>
>> 2010-12-07 22:21:35.791747 > HCI Event: Auth Complete (0x06) plen 3
>>     status 0x00 handle 12
>> ... ...
>>
>> 2010-12-07 22:21:35.872372 > ACL data: handle 12 flags 0x02 dlen 16
>>     L2CAP(s): Connect rsp: dcid 0x0054 scid 0x0040 result 0 status 0
>>       Connection successful
>>
>> Signed-off-by: Liang Bao <tim.bao@gmail.com>
>
> Now it looks good to me.
>
> Acked-by: Ville Tervo <ville.tervo@nokia.com>
>
Thanks, so ready for push? ;)
>> ---
>>  net/bluetooth/l2cap.c |    1 +
>>  1 files changed, 1 insertions(+), 0 deletions(-)
>>
>> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
>> index fadf26b..364197d 100644
>> --- a/net/bluetooth/l2cap.c
>> +++ b/net/bluetooth/l2cap.c
>> @@ -848,6 +848,7 @@ static void __l2cap_sock_close(struct sock *sk, int reason)
>>                               result = L2CAP_CR_SEC_BLOCK;
>>                       else
>>                               result = L2CAP_CR_BAD_PSM;
>> +                     sk->sk_state = BT_DISCONN;
>>
>>                       rsp.scid   = cpu_to_le16(l2cap_pi(sk)->dcid);
>>                       rsp.dcid   = cpu_to_le16(l2cap_pi(sk)->scid);
>> --
>> 1.7.1
>>
>
> --
> Ville
>

^ permalink raw reply

* [PATCH 2/2] Add missing const to utility functions.
From: Andre Dieb Martins @ 2011-01-31 19:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andre Dieb Martins
In-Reply-To: <1296500972-14105-1-git-send-email-andre.dieb@signove.com>

From: André Dieb Martins <andre.dieb@signove.com>

---
 parser/hci.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/parser/hci.c b/parser/hci.c
index 8b45376..183fa66 100644
--- a/parser/hci.c
+++ b/parser/hci.c
@@ -704,7 +704,7 @@ static char *authentication2str(uint8_t authentication)
 	}
 }
 
-static char *eventmask2str(uint8_t mask[8])
+static char *eventmask2str(const uint8_t mask[8])
 {
 	int i;
 
@@ -733,7 +733,7 @@ static char *eventmask2str(uint8_t mask[8])
 	}
 }
 
-static char *lefeatures2str(uint8_t features[8])
+static char *lefeatures2str(const uint8_t features[8])
 {
 	if (features[0] & 0x01)
 		return "Link Layer supports LE Encryption";
-- 
1.7.1


^ permalink raw reply related

* [PATCH 1/2] Implement dump for event LE Read Remote Used Features Complete.
From: Andre Dieb Martins @ 2011-01-31 19:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andre Dieb Martins

From: André Dieb Martins <andre.dieb@signove.com>

---
 parser/hci.c |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/parser/hci.c b/parser/hci.c
index 6f9e2a3..8b45376 100644
--- a/parser/hci.c
+++ b/parser/hci.c
@@ -3546,6 +3546,26 @@ static inline void evt_le_conn_update_complete_dump(int level,
 			btohs(uevt->supervision_timeout) * 10.0);
 }
 
+static inline void evt_le_read_remote_used_features_complete_dump(int level, struct frame *frm)
+{
+	int i;
+	evt_le_read_remote_used_features_complete *revt = frm->ptr;
+
+	p_indent(level, frm);
+	printf("status 0x%2.2x handle %d\n", revt->status, btohs(revt->handle));
+
+	if (revt->status > 0) {
+		p_indent(level, frm);
+		printf("Error: %s\n", status2str(revt->status));
+	} else {
+		p_indent(level, frm);
+		printf("Features:");
+		for (i = 0; i < 8; i++)
+			printf(" 0x%2.2x", revt->features[i]);
+		printf("\n");
+	}
+}
+
 static inline void le_meta_ev_dump(int level, struct frame *frm)
 {
 	evt_le_meta_event *mevt = frm->ptr;
@@ -3569,6 +3589,9 @@ static inline void le_meta_ev_dump(int level, struct frame *frm)
 	case EVT_LE_CONN_UPDATE_COMPLETE:
 		evt_le_conn_update_complete_dump(level + 1, frm);
 		break;
+	case EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE:
+		evt_le_read_remote_used_features_complete_dump(level + 1, frm);
+		break;
 	default:
 		raw_dump(level, frm);
 		break;
-- 
1.7.1


^ permalink raw reply related

* [PATCH] Fix hciconfig leadv returned response.
From: Andre Dieb Martins @ 2011-01-31 18:57 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andre Dieb Martins

Fixes hciconfig leadv returned response by treating both status of the command
execution and HCI error code.
---
 tools/hciconfig.c |   15 ++++++++++++---
 1 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/tools/hciconfig.c b/tools/hciconfig.c
index c271d14..05a8910 100644
--- a/tools/hciconfig.c
+++ b/tools/hciconfig.c
@@ -269,11 +269,20 @@ static void cmd_le_adv(int ctl, int hdev, char *opt)
 	rq.rlen = 1;
 
 	ret = hci_send_req(dd, &rq, 100);
-	if (status || ret < 0)
+
+	hci_close_dev(dd);
+
+	if (ret < 0) {
 		fprintf(stderr, "Can't set advertise mode on hci%d: %s (%d)\n",
 						hdev, strerror(errno), errno);
+		exit(1);
+	}
 
-	hci_close_dev(dd);
+	if (status) {
+		fprintf(stderr, "LE set advertise enable on hci%d returned status %d\n",
+						hdev, status);
+		exit(1);
+	}
 }
 
 static void cmd_le_states(int ctl, int hdev, char *opt)
@@ -302,7 +311,7 @@ static void cmd_le_states(int ctl, int hdev, char *opt)
 
 	err = hci_send_req(dd, &rq, 1000);
 
-	close(dd);
+	hci_close_dev(dd);
 
 	if (err < 0) {
 		fprintf(stderr, "Can't read LE supported states on hci%d:"
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH 2/2] Add option to enable privacy during scanning to hcitool
From: Claudio Takahasi @ 2011-01-31 18:09 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <AANLkTimic7tgjGbsnzunHZN=KOu5kKoDzh45FfusKh=e@mail.gmail.com>

Hi Luiz,

On Mon, Jan 31, 2011 at 1:46 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> Hi Claudio,
>
> On Mon, Jan 31, 2011 at 3:50 PM, Claudio Takahasi
> <claudio.takahasi@openbossa.org> wrote:
>> Hi Johan,
>>
>> On Mon, Jan 31, 2011 at 6:40 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
>>> Hi Claudio,
>>>
>>> On Fri, Jan 28, 2011, Claudio Takahasi wrote:
>>>> When privacy is enabled, random address is used during active scanning.
>>>> The non-resolvable private address shall be set using hciconfig.
>>>> ---
>>>>  tools/hcitool.c |   13 +++++++++----
>>>>  1 files changed, 9 insertions(+), 4 deletions(-)
>>>
>>> Both patches have been pushed upstream. Thanks.
>>>
>>> Any plans how to represent this feature in the official APIs? I suppose
>>> the random address can be generated automatically using some appropriate
>>> source such as the HCI_LE_Rand command but how do we represent the
>>> public vs random address selection using the D-Bus API? Or do we even
>>> need to do that?
>>>
>>> Johan
>>>
>>
>> I added these changes to investigate the PTS  test result, it is not
>> mandatory. I am was planning to focus on Register Application API
>> first instead of privacy for central. The implementation is simple, if
>> someone in the community wants to help us, here are some guidelines:
>>
>> My idea is add a new property in the adapter interface called:
>> Privacy. The changes will be:
>> 1. Add Privacy property with persistent storage =>
>> adapter.SetProperty("Privacy", True/False)
>
> Can this be unset, I mean can a device really use a random/private and
> than latter switch to public? For what I understand if anyone pair
> using the random/private address they don't store the actual address
> but a key to resolve the address, so switching on runtime is IMO not a
> good idea, perhaps a parameter on main.conf is enough?

Yes, there isn't such restriction. At least, I didn't find it.
For central, if I understood correctly a non-resolvable private(or
random static for reconnection address) address can be used when a new
discovery session starts. We can always use a non-resolvable private
address during the scanning, I don't see an use case that we need to
use a random static for it.

Indeed the random static needs to be stored, otherwise the white
list/reconnection address will not work, but this will affect
advertising only. How to use random static address needs further
investigation from my side, but I don't think that it needs to be
exposed to the users.

>
> Actually the spec say that there could be at least 3 types of random address:
>
> - Static
> - Private Non-resolvable
> - Private Resolvable
>
>> 2. Generate a non-resolvable private address. My suggestion is to read
>> the data directly from "/dev/random" instead of use HCI_LE_Rand
>> command(needs to wait for command complete).
>
> I remember someone saying that the controller should be able to
> generate a more random number because it uses the RF signal
> interference for that, but Im not sure if this is actually true or
> not, or if enough to give up the idea of using /dev/random.
>
>> 3. Trigger the LE scanning based on this property.
>>
I forgot to add some items
4. Use/Set the reconnection address when necessary

5. While list management for peripheral

BR,
Claudio

>> PS: For LE Create Connection command the own address type must be set
>> based on privacy value, however this change requires changes in the
>> kernel. Currently, Own_Address_Type is hard-coded in the kernel(public
>> address only).
>
> Yep, we probably need to start by fixing this, it seems some device
> will already come with random addresses so it will be nice to have
> this fixed asap.
>
>
> --
> Luiz Augusto von Dentz
> Computer Engineer
>

^ permalink raw reply

* Re: [PATCH] Bluetooth: Support SCO over HCI for Atheros AR300x Bluetooth device
From: Suraj Sumangala @ 2011-01-31 17:28 UTC (permalink / raw)
  To: Suraj Sumangala; +Cc: linux-bluetooth@vger.kernel.org, Jothikumar Mothilal
In-Reply-To: <1296211744-2487-1-git-send-email-suraj@atheros.com>

Hi,

On 1/28/2011 4:19 PM, Suraj Sumangala wrote:
> This patch adds SCO over HCI support to Atheros AR300x HCI transport
> driver.
>
> Signed-off-by: Suraj Sumangala<suraj@atheros.com>
> ---
>   drivers/bluetooth/hci_ath.c |   18 +++++++++---------
>   1 files changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c
> index 6a160c1..161bd20 100644
> --- a/drivers/bluetooth/hci_ath.c
> +++ b/drivers/bluetooth/hci_ath.c

*ping*

Regards
Suraj


^ 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