Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH 5/7 v3] Add support for notyfying pbap about more parts from backend
From: Radoslaw Jablonski @ 2011-02-14  9:19 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1297675191-8046-1-git-send-email-ext-jablonski.radoslaw@nokia.com>

Added new parameter to phonebook_cb - lastpart variable.
If backend want to notify that more parts of current
request will be delivered later, it should use lastpart=FALSE.
Because of that, PBAP core will 'know' that should not finalize
request immediately after receiving data and wait for more
parts to come.
If result is returned in one part and no more responses part
will be sent later, then backend should use lastparam=TRUE.
Previously results of request from backend was always returned
in one part to PBAP core.
---
 plugins/irmc.c              |    5 +++--
 plugins/pbap.c              |   10 +++++++---
 plugins/phonebook-dummy.c   |    4 ++--
 plugins/phonebook-ebook.c   |    7 ++++---
 plugins/phonebook-tracker.c |   13 +++++++------
 plugins/phonebook.h         |    2 +-
 6 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/plugins/irmc.c b/plugins/irmc.c
index 0488cae..e1e83f9 100644
--- a/plugins/irmc.c
+++ b/plugins/irmc.c
@@ -133,7 +133,8 @@ static const char *owner_vcard =
 		"END:VCARD\r\n";
 
 static void phonebook_size_result(const char *buffer, size_t bufsize,
-				int vcards, int missed, void *user_data)
+					int vcards, int missed,
+					gboolean lastpart, void *user_data)
 {
 	struct irmc_session *irmc = user_data;
 
@@ -148,7 +149,7 @@ static void phonebook_size_result(const char *buffer, size_t bufsize,
 }
 
 static void query_result(const char *buffer, size_t bufsize, int vcards,
-					int missed, void *user_data)
+				int missed, gboolean lastpart, void *user_data)
 {
 	struct irmc_session *irmc = user_data;
 	const char *s, *t;
diff --git a/plugins/pbap.c b/plugins/pbap.c
index 6579d09..5775eea 100644
--- a/plugins/pbap.c
+++ b/plugins/pbap.c
@@ -148,6 +148,7 @@ struct pbap_object {
 	GString *buffer;
 	GByteArray *aparams;
 	gboolean firstpacket;
+	gboolean lastpart;
 	struct pbap_session *session;
 	void *request;
 };
@@ -254,7 +255,8 @@ static GByteArray *append_aparam_header(GByteArray *buf, uint8_t tag,
 }
 
 static void phonebook_size_result(const char *buffer, size_t bufsize,
-				int vcards, int missed, void *user_data)
+					int vcards, int missed,
+					gboolean lastpart, void *user_data)
 {
 	struct pbap_session *pbap = user_data;
 	uint16_t phonebooksize;
@@ -286,17 +288,19 @@ static void phonebook_size_result(const char *buffer, size_t bufsize,
 }
 
 static void query_result(const char *buffer, size_t bufsize, int vcards,
-					int missed, void *user_data)
+				int missed, gboolean lastpart, void *user_data)
 {
 	struct pbap_session *pbap = user_data;
 
 	DBG("");
 
-	if (pbap->obj->request) {
+	if (pbap->obj->request && lastpart) {
 		phonebook_req_finalize(pbap->obj->request);
 		pbap->obj->request = NULL;
 	}
 
+	pbap->obj->lastpart = lastpart;
+
 	if (vcards <= 0) {
 		obex_object_set_io_flags(pbap->obj, G_IO_ERR, -ENOENT);
 		return;
diff --git a/plugins/phonebook-dummy.c b/plugins/phonebook-dummy.c
index 60b7640..76dd550 100644
--- a/plugins/phonebook-dummy.c
+++ b/plugins/phonebook-dummy.c
@@ -248,7 +248,7 @@ static gboolean read_dir(void *user_data)
 	closedir(dp);
 done:
 	/* FIXME: Missing vCards fields filtering */
-	dummy->cb(buffer->str, buffer->len, count, 0, dummy->user_data);
+	dummy->cb(buffer->str, buffer->len, count, 0, TRUE, dummy->user_data);
 
 	g_string_free(buffer, TRUE);
 
@@ -346,7 +346,7 @@ static gboolean read_entry(void *user_data)
 
 	/* FIXME: Missing vCards fields filtering */
 
-	dummy->cb(buffer, count, 1, 0, dummy->user_data);
+	dummy->cb(buffer, count, 1, 0, TRUE, dummy->user_data);
 
 	return FALSE;
 }
diff --git a/plugins/phonebook-ebook.c b/plugins/phonebook-ebook.c
index 70b9c02..6cc4f31 100644
--- a/plugins/phonebook-ebook.c
+++ b/plugins/phonebook-ebook.c
@@ -186,7 +186,8 @@ static void ebookpull_cb(EBook *book, EBookStatus estatus, GList *contacts,
 
 done:
 	data->completed = TRUE;
-	data->contacts_cb(string->str, string->len, count, 0, data->user_data);
+	data->contacts_cb(string->str, string->len, count, 0, TRUE,
+							data->user_data);
 
 fail:
 	g_string_free(string, TRUE);
@@ -212,7 +213,7 @@ static void ebook_entry_cb(EBook *book, EBookStatus estatus,
 
 	if (estatus != E_BOOK_ERROR_OK) {
 		error("E-Book query failed: status %d", estatus);
-		data->contacts_cb(NULL, 0, 1, 0, data->user_data);
+		data->contacts_cb(NULL, 0, 1, 0, TRUE, data->user_data);
 		goto fail;
 	}
 
@@ -223,7 +224,7 @@ static void ebook_entry_cb(EBook *book, EBookStatus estatus,
 
 	len = vcard ? strlen(vcard) : 0;
 
-	data->contacts_cb(vcard, len, 1, 0, data->user_data);
+	data->contacts_cb(vcard, len, 1, 0, TRUE, data->user_data);
 
 	g_free(vcard);
 
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 210799d..aea2365 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -1334,7 +1334,7 @@ static int pull_contacts_size(const char **reply, int num_fields,
 	struct phonebook_data *data = user_data;
 
 	if (num_fields < 0) {
-		data->cb(NULL, 0, num_fields, 0, data->user_data);
+		data->cb(NULL, 0, num_fields, 0, TRUE, data->user_data);
 		return -EINTR;
 	}
 
@@ -1343,7 +1343,8 @@ static int pull_contacts_size(const char **reply, int num_fields,
 		return 0;
 	}
 
-	data->cb(NULL, 0, data->index, data->newmissedcalls, data->user_data);
+	data->cb(NULL, 0, data->index, data->newmissedcalls, TRUE,
+							data->user_data);
 
 	return 0;
 	/*
@@ -1561,7 +1562,7 @@ static int pull_contacts(const char **reply, int num_fields, void *user_data)
 	static char *temp_id = NULL;
 
 	if (num_fields < 0) {
-		data->cb(NULL, 0, num_fields, 0, data->user_data);
+		data->cb(NULL, 0, num_fields, 0, TRUE, data->user_data);
 		goto fail;
 	}
 
@@ -1641,7 +1642,7 @@ done:
 	vcards = gen_vcards(data->contacts, params);
 
 	data->cb(vcards->str, vcards->len, g_slist_length(data->contacts),
-					data->newmissedcalls, data->user_data);
+				data->newmissedcalls, TRUE, data->user_data);
 
 	g_string_free(vcards, TRUE);
 fail:
@@ -1868,7 +1869,7 @@ done:
 	data->contacts = NULL;
 
 	if (num_fields < 0) {
-		data->cb(NULL, 0, num_fields, 0, data->user_data);
+		data->cb(NULL, 0, num_fields, 0, TRUE, data->user_data);
 		return -EINTR;
 	}
 
@@ -1884,7 +1885,7 @@ done:
 
 	err = query_tracker(query, col_amount, pull_cb, data);
 	if (err < 0) {
-		data->cb(NULL, 0, err, 0, data->user_data);
+		data->cb(NULL, 0, err, 0, TRUE, data->user_data);
 
 		return -EINTR;
 	}
diff --git a/plugins/phonebook.h b/plugins/phonebook.h
index bfbae0f..f6df164 100644
--- a/plugins/phonebook.h
+++ b/plugins/phonebook.h
@@ -50,7 +50,7 @@ struct apparam_field {
  * Contacts will be returned in the vcard format.
  */
 typedef void (*phonebook_cb) (const char *buffer, size_t bufsize,
-		int vcards, int missed, void *user_data);
+		int vcards, int missed, gboolean lastpart, void *user_data);
 
 /*
  * Interface between the PBAP core and backends to
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 4/7 v3] Support for stop fetching data when maxlistcount is achieved
From: Radoslaw Jablonski @ 2011-02-14  9:19 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1297675191-8046-1-git-send-email-ext-jablonski.radoslaw@nokia.com>

When desired number of results has been already processed,
then sending already collected data and stopping fetching
more results from tracker (previously in this scenario
unnecessarily processing data continued untill end of results
in db)
---
 plugins/phonebook-tracker.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index c80ee68..210799d 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -1602,11 +1602,17 @@ static int pull_contacts(const char **reply, int num_fields, void *user_data)
 
 	last_index = params->liststartoffset + params->maxlistcount;
 
-	if ((data->index <= params->liststartoffset ||
-						data->index > last_index) &&
-						params->maxlistcount > 0)
+	if (data->index <= params->liststartoffset)
 		return 0;
 
+	/* max number of results achieved - need send vcards data that was
+	 * already collected and stop further data processing (these operations
+	 * will be invoked in "done" section) */
+	if (data->index > last_index && params->maxlistcount > 0) {
+		DBG("Maxlistcount achieved");
+		goto done;
+	}
+
 add_entry:
 	contact = g_new0(struct phonebook_contact, 1);
 	contact_init(contact, reply);
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 3/7 v3] Remove unnecessary checking for num_fields in pull_contact
From: Radoslaw Jablonski @ 2011-02-14  9:19 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1297675191-8046-1-git-send-email-ext-jablonski.radoslaw@nokia.com>

This check is no longer needed - it was used to ensure that no
error occured in querying tracker. This is redundant because
checking for that case is located in the beginning of pull_contacts
function.
---
 plugins/phonebook-tracker.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 6b9bb2f..c80ee68 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -1634,9 +1634,7 @@ add_numbers:
 done:
 	vcards = gen_vcards(data->contacts, params);
 
-	if (num_fields == 0)
-		data->cb(vcards->str, vcards->len,
-					g_slist_length(data->contacts),
+	data->cb(vcards->str, vcards->len, g_slist_length(data->contacts),
 					data->newmissedcalls, data->user_data);
 
 	g_string_free(vcards, TRUE);
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 2/7 v3] Add return value to reply_list_foreach_t in phonebook-tracker
From: Radoslaw Jablonski @ 2011-02-14  9:19 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1297675191-8046-1-git-send-email-ext-jablonski.radoslaw@nokia.com>

This changes are needed for notyfying that fetching data
from tracker should be stopped.
This will be usable in scenarios like:
*some error occurred during processing data
*maximum number of results already processed (due to pbap
 maxlistcount parameter)
*suspending processing data if pbap buffer is too large
---
 plugins/phonebook-tracker.c |   58 ++++++++++++++++++++++++++----------------
 1 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 8044395..6b9bb2f 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -890,7 +890,7 @@
 	"} GROUP BY ?call ORDER BY DESC(nmo:receivedDate(?call)) "	\
 	"LIMIT 40"
 
-typedef void (*reply_list_foreach_t) (const char **reply, int num_fields,
+typedef int (*reply_list_foreach_t) (const char **reply, int num_fields,
 							void *user_data);
 
 typedef void (*add_field_t) (struct phonebook_contact *contact,
@@ -1042,6 +1042,7 @@ static void async_query_cursor_next_cb(GObject *source, GAsyncResult *result,
 	GError *error = NULL;
 	gboolean success;
 	const char **node;
+	int err;
 
 	success = tracker_sparql_cursor_next_finish(
 						TRACKER_SPARQL_CURSOR(source),
@@ -1061,17 +1062,22 @@ static void async_query_cursor_next_cb(GObject *source, GAsyncResult *result,
 	}
 
 	node = string_array_from_cursor(cursor, pending->num_fields);
-	pending->callback(node, pending->num_fields, pending->user_data);
+	err = pending->callback(node, pending->num_fields, pending->user_data);
 	g_free(node);
 
-
-	/* getting next row from query results */
-	cancellable = g_cancellable_new();
-	update_cancellable(pending->user_data, cancellable);
-	tracker_sparql_cursor_next_async(cursor, cancellable,
+	/* Fetch next result only if processing current chunk ended with
+	 * success. Sometimes during processing data, we are able to determine
+	 * if there is no need to get more data from tracker - by example
+	 * stored amount of data parts is big enough for sending and we might
+	 * want to suspend processing or just some error occurred. */
+	if (!err) {
+		cancellable = g_cancellable_new();
+		update_cancellable(pending->user_data, cancellable);
+		tracker_sparql_cursor_next_async(cursor, cancellable,
 						async_query_cursor_next_cb,
 						pending);
-	return;
+		return;
+	}
 
 failed:
 	g_object_unref(cursor);
@@ -1322,23 +1328,24 @@ static GString *gen_vcards(GSList *contacts,
 	return vcards;
 }
 
-static void pull_contacts_size(const char **reply, int num_fields,
+static int pull_contacts_size(const char **reply, int num_fields,
 							void *user_data)
 {
 	struct phonebook_data *data = user_data;
 
 	if (num_fields < 0) {
 		data->cb(NULL, 0, num_fields, 0, data->user_data);
-		return;
+		return -EINTR;
 	}
 
 	if (reply != NULL) {
 		data->index = atoi(reply[0]);
-		return;
+		return 0;
 	}
 
 	data->cb(NULL, 0, data->index, data->newmissedcalls, data->user_data);
 
+	return 0;
 	/*
 	 * phonebook_data is freed in phonebook_req_finalize. Useful in
 	 * cases when call is terminated.
@@ -1542,7 +1549,7 @@ static void contact_add_organization(struct phonebook_contact *contact,
 	add_affiliation(&contact->role, reply[COL_ORG_ROLE]);
 }
 
-static void pull_contacts(const char **reply, int num_fields, void *user_data)
+static int pull_contacts(const char **reply, int num_fields, void *user_data)
 {
 	struct phonebook_data *data = user_data;
 	const struct apparam_field *params = data->params;
@@ -1585,7 +1592,7 @@ static void pull_contacts(const char **reply, int num_fields, void *user_data)
 
 	if (i == num_fields - 4 && !g_str_equal(reply[CONTACTS_ID_COL],
 						TRACKER_DEFAULT_CONTACT_ME))
-		return;
+		return 0;
 
 	if (g_strcmp0(temp_id, reply[CONTACTS_ID_COL])) {
 		data->index++;
@@ -1598,7 +1605,7 @@ static void pull_contacts(const char **reply, int num_fields, void *user_data)
 	if ((data->index <= params->liststartoffset ||
 						data->index > last_index) &&
 						params->maxlistcount > 0)
-		return;
+		return 0;
 
 add_entry:
 	contact = g_new0(struct phonebook_contact, 1);
@@ -1622,7 +1629,7 @@ add_numbers:
 		data->contacts = g_slist_append(data->contacts, contact_data);
 	}
 
-	return;
+	return 0;
 
 done:
 	vcards = gen_vcards(data->contacts, params);
@@ -1637,13 +1644,14 @@ fail:
 	g_free(temp_id);
 	temp_id = NULL;
 
+	return -EINTR;
 	/*
 	 * phonebook_data is freed in phonebook_req_finalize. Useful in
 	 * cases when call is terminated.
 	 */
 }
 
-static void add_to_cache(const char **reply, int num_fields, void *user_data)
+static int add_to_cache(const char **reply, int num_fields, void *user_data)
 {
 	struct phonebook_data *data = user_data;
 	char *formatted;
@@ -1660,7 +1668,7 @@ static void add_to_cache(const char **reply, int num_fields, void *user_data)
 
 	if (i == num_fields &&
 			!g_str_equal(reply[0], TRACKER_DEFAULT_CONTACT_ME))
-		return;
+		return 0;
 
 	if (i == 6)
 		formatted = g_strdup(reply[6]);
@@ -1679,12 +1687,13 @@ static void add_to_cache(const char **reply, int num_fields, void *user_data)
 
 	g_free(formatted);
 
-	return;
+	return 0;
 
 done:
 	if (num_fields <= 0)
 		data->ready_cb(data->user_data);
 
+	return -EINTR;
 	/*
 	 * phonebook_data is freed in phonebook_req_finalize. Useful in
 	 * cases when call is terminated.
@@ -1826,7 +1835,7 @@ static void gstring_free_helper(gpointer data, gpointer user_data)
 	g_string_free(data, TRUE);
 }
 
-static void pull_newmissedcalls(const char **reply, int num_fields,
+static int pull_newmissedcalls(const char **reply, int num_fields,
 							void *user_data)
 {
 	struct phonebook_data *data = user_data;
@@ -1846,7 +1855,7 @@ static void pull_newmissedcalls(const char **reply, int num_fields,
 								number);
 		}
 	}
-	return;
+	return 0;
 
 done:
 	DBG("newmissedcalls %d", data->newmissedcalls);
@@ -1856,7 +1865,7 @@ done:
 
 	if (num_fields < 0) {
 		data->cb(NULL, 0, num_fields, 0, data->user_data);
-		return;
+		return -EINTR;
 	}
 
 	if (data->params->maxlistcount == 0) {
@@ -1870,8 +1879,13 @@ done:
 	}
 
 	err = query_tracker(query, col_amount, pull_cb, data);
-	if (err < 0)
+	if (err < 0) {
 		data->cb(NULL, 0, err, 0, data->user_data);
+
+		return -EINTR;
+	}
+
+	return 0;
 }
 
 void *phonebook_pull(const char *name, const struct apparam_field *params,
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 1/7 v3] Add return value to query tracker
From: Radoslaw Jablonski @ 2011-02-14  9:19 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski

Previously errors were returned via parameter err - it was needed
because some time ago query_tracker was returning newly allocated
structure. Now returning error through return value has more
sense.
---
 plugins/phonebook-tracker.c |   37 ++++++++++++++++++-------------------
 1 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index e116175..8044395 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -1078,9 +1078,8 @@ failed:
 	g_free(pending);
 }
 
-static void query_tracker(const char *query, int num_fields,
-				reply_list_foreach_t callback, void *user_data,
-				int *err)
+static int query_tracker(const char *query, int num_fields,
+				reply_list_foreach_t callback, void *user_data)
 {
 	struct pending_reply *pending;
 	GCancellable *cancellable;
@@ -1099,7 +1098,7 @@ static void query_tracker(const char *query, int num_fields,
 			g_error_free(error);
 		}
 
-		goto failed;
+		return -EINTR;
 	}
 
 	cancellable = g_cancellable_new();
@@ -1115,7 +1114,7 @@ static void query_tracker(const char *query, int num_fields,
 
 		g_object_unref(cancellable);
 
-		goto failed;
+		return -EINTR;
 	}
 
 	pending = g_new0(struct pending_reply, 1);
@@ -1130,14 +1129,7 @@ static void query_tracker(const char *query, int num_fields,
 						async_query_cursor_next_cb,
 						pending);
 
-	if (err)
-		*err = 0;
-
-	return;
-
-failed:
-	if (err)
-		*err = -EPERM;
+	return 0;
 }
 
 static char *iso8601_utc_to_localtime(const char *datetime)
@@ -1877,7 +1869,7 @@ done:
 		pull_cb = pull_contacts;
 	}
 
-	query_tracker(query, col_amount, pull_cb, data, &err);
+	err = query_tracker(query, col_amount, pull_cb, data);
 	if (err < 0)
 		data->cb(NULL, 0, err, 0, data->user_data);
 }
@@ -1888,7 +1880,7 @@ void *phonebook_pull(const char *name, const struct apparam_field *params,
 	struct phonebook_data *data;
 	const char *query;
 	reply_list_foreach_t pull_cb;
-	int col_amount;
+	int col_amount, ret;
 
 	DBG("name %s", name);
 
@@ -1916,7 +1908,9 @@ void *phonebook_pull(const char *name, const struct apparam_field *params,
 	data->params = params;
 	data->user_data = user_data;
 	data->cb = cb;
-	query_tracker(query, col_amount, pull_cb, data, err);
+	ret = query_tracker(query, col_amount, pull_cb, data);
+	if (err)
+		*err = ret;
 
 	return data;
 }
@@ -1927,6 +1921,7 @@ void *phonebook_get_entry(const char *folder, const char *id,
 {
 	struct phonebook_data *data;
 	char *query;
+	int ret;
 
 	DBG("folder %s id %s", folder, id);
 
@@ -1944,8 +1939,9 @@ void *phonebook_get_entry(const char *folder, const char *id,
 		query = g_strdup_printf(CONTACTS_OTHER_QUERY_FROM_URI,
 								id, id, id);
 
-	query_tracker(query, PULL_QUERY_COL_AMOUNT,
-						pull_contacts, data, err);
+	ret = query_tracker(query, PULL_QUERY_COL_AMOUNT, pull_contacts, data);
+	if (err)
+		*err = ret;
 
 	g_free(query);
 
@@ -1957,6 +1953,7 @@ void *phonebook_create_cache(const char *name, phonebook_entry_cb entry_cb,
 {
 	struct phonebook_data *data;
 	const char *query;
+	int ret;
 
 	DBG("name %s", name);
 
@@ -1971,7 +1968,9 @@ 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;
-	query_tracker(query, 7, add_to_cache, data, err);
+	ret = query_tracker(query, 7, add_to_cache, data);
+	if (err)
+		*err = ret;
 
 	return data;
 }
-- 
1.7.0.4


^ permalink raw reply related

* bluetooth disabled with current 2.6.38-rc4
From: Justin Mattock @ 2011-02-14  1:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: linux-kernel@vger.kernel.org Mailing List

maybe I missed something, but my bluetooth is just not functioning with
2.6.38-rc4(works with 2.6.37-rc4)

I've done a bisect on this, but was pointed to:
c0e45c1ca3162acb2e77b3d9e152ce6e7b6fa3f5
but doesn't look correct to me

here is what I am seeing with the bluetooth-applet etc..:

working correctly:
http://www.flickr.com/photos/44066293@N08/5443727238/

not working:
http://www.flickr.com/photos/44066293@N08/5443124859/

my /var/log/daemon.log shows:

Feb 13 17:12:22 Linux-2 acpid: 1 client rule loaded
Feb 13 17:12:23 Linux-2 bluetoothd[1950]: HCI dev 0 registered
Feb 13 17:12:23 Linux-2 bluetoothd[1950]: Listening for HCI events on  
hci0
Feb 13 17:12:23 Linux-2 bluetoothd[1950]: HCI dev 0 up
Feb 13 17:12:23 Linux-2 bluetoothd[1950]: Unable to find matching  
adapter

I can try at another bisect, but might take some time.. let me know if  
there is something I can test
or do.

Justin P. Mattock

^ permalink raw reply

* [PATCH] Bluetooth: rfcomm: Release BTM while sleeping to avoid deadlock.
From: Владислав @ 2011-02-13  1:01 UTC (permalink / raw)
  To: linux-bluetooth

Bug description:
Kernel freezes for ~2 seconds after trying to access /dev/rfcommX device.
Steps to reproduce:
1. Edit /etc/bluetooth/rfcomm.conf - uncomment default config, set "bind" to "yes".
2. Issue "sudo rfcomm bind all" to create /dev/rfcomm0 device node.
3. Issue "cat /dev/rfcomm0" to trigger a bug.
Everything freezes (at least GUI): cursor does not move, no response from
keypresses, no gui redraw for 2~3 seconds.
Then cat displays expected error message "cat: /dev/rfcomm0: Host is down"
and system starts to respond again.
What expected (and occurs with 2.6.35) : no freeze between cat and error message.
Things goes worse when device, mentioned in /etc/bluetooth/rfcomm.conf
is in range and not paired - system displays pairing request and locks
up for a longer time, maybe completely - I did not wait longer than ~30
seconds and turned off bluetooth device.

Fix:
Release BTM while sleeping to avoid deadlock.

diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 2575c2d..d7b9af4 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -727,7 +727,9 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
 			break;
 		}
 
+		tty_unlock();
 		schedule();
+		tty_lock();
 	}
 	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&dev->wait, &wait);





^ permalink raw reply related

* Re: [BUG] usb problems in .38-rc3+
From: Ed Tomlinson @ 2011-02-12 14:38 UTC (permalink / raw)
  To: Anand Gadiyar; +Cc: Oliver Neukum, linux-kernel, linux-bluetooth, linux-usb
In-Reply-To: <c037b856cfa01b5c7014873850cd07a9@mail.gmail.com>

On Wednesday 09 February 2011 01:17:40 Anand Gadiyar wrote:
> Ed Tomlinson wrote:
> > On Tuesday 08 February 2011 01:46:16 Gadiyar, Anand wrote:
> > > On Tue, Feb 8, 2011 at 7:45 AM, Ed Tomlinson <edt@aei.ca> wrote:
> > > > I tried bisecting without much luck.  It started with about 4000
> commits to check.  It was still bad
> > > > when it reached the first 1000 commits post .37.  Then all boots
> started crashing.  I think its possible
> > > > to restrict a bisect to a directory - if so, what dir should I try?
> > > >
> > >
> > > Maybe drivers/ or drivers/usb would be enough for a first attempt?
> > > I usually start there.
> > >
> > > You could just do:
> > >
> > > git bisect start -- [path]
> > >
> > > to restrict bisection to commits that touch [path].
> >
> > This is as far as I can get:
> >
> > # bad: [100b33c8bd8a3235fd0b7948338d6cbb3db3c63d] Linux 2.6.38-rc4
> > # good: [3c0eee3fe6a3a1c745379547c7e7c904aa64f6d5] Linux 2.6.37
> > # good: [387c31c7e5c9805b0aef8833d1731a5fe7bdea14] Linux 2.6.37-rc8
> > # good: [90a8a73c06cc32b609a880d48449d7083327e11a] Linux 2.6.37-rc7
> > # good: [c8ddb2713c624f432fa5fe3c7ecffcdda46ea0d4] Linux 2.6.37-rc1
> > git bisect start 'v2.6.38-rc4' 'v2.6.37' 'v2.6.37-rc8' 'v2.6.37-rc7'
> 'v2.6.37-rc1' '--' 'drivers/usb' 'drivers/bluetooth'
> > # good: [5cdc5bd8b2b1190cb54548c03194b154b4892e2a] Merge branch
> 'musb-hw' of git://gitorious.org/usb/usb into musb
> > git bisect good 5cdc5bd8b2b1190cb54548c03194b154b4892e2a
> > # bad: [f2c565e223af39ed38be5c84b1a37b591b22db83] xHCI: replace
> dev_dbg() with xhci_dbg()
> > git bisect bad f2c565e223af39ed38be5c84b1a37b591b22db83
> > # good: [2af10844eb6ed104f9505bf3a7ba3ceb02264f31] USB: Merge 2.6.37-rc5
> into usb-next
> > git bisect good 2af10844eb6ed104f9505bf3a7ba3ceb02264f31
> > # bad: [3e5b08cbbf78bedd316904ab0cf3b27119433ee5] Merge branch
> 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
> > git bisect bad 3e5b08cbbf78bedd316904ab0cf3b27119433ee5
> > # good: [1051b9f0f9eab8091fe3bf98320741adf36b4cfa] Merge branch
> 'for-rmk' of git://git.pengutronix.de/git/imx/linux-2.6 into devel-stable
> > git bisect good 1051b9f0f9eab8091fe3bf98320741adf36b4cfa
> >
> > After this the kernel does not build.
> >
> > Any clues?
> 
> Is it easier to just fix the build break locally and proceed?
> 
> I'm afraid I don't know how to skip a step during bisection.
> I try narrowing things down manually.
> 
> Given that 2.6.37 is fine, can you check if v2.6.38-rc1 works?
> If it doesn't work, then this break was caused by something that
> went in during the merge window (which I believe is most likely).
> 
> You may be able to get somewhere by using snapshots of
> linux-next as of particular days. They are available at [1]
> as a single patch against a tag from Linus' tree.
> 
> Warning: This could be tedious, maybe not much more than a
> git-bisect. Maybe easier to try and work it out from the
> code.

I am not having much luck bisecting or using daily snapshots.  They either
do not build or opps during boot....

The latest round of usb fixes (67d019528e5c2693145217cf18a507689980d2a4) from 
Greg did not help 

How else can we track this down?

Ed

^ permalink raw reply

* Re: HCI core error recovery.
From: Andrei Warkentin @ 2011-02-12  6:47 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <AANLkTi=qB6WcjkQcp0teuL5DTKKBSSK0ydWD1EtwCh=n@mail.gmail.com>

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

On Fri, Feb 11, 2011 at 5:07 PM, Andrei Warkentin <andreiw@motorola.com> wrote:
> Dear List,
>
> I've run into an interesting problem. Excuse me in advance if this was
> already covered here, or for my explanations, since I'm not too
> familiar with overall flow within BlueZ or Bluetooth specifics...
> We've had some hardware config issues that resulted in garbage/malformed
> messages arriving via H4 into the HCI layer. We've since resolved
> these, but it got me thinking. The issues would result in certain HCI
> messages being missed, including occasionally disconnect events being
> missed, and a subsequent connect event would result in a double add.
>
> I was thinking about how to fix at the very least the crash. The sysfs
> object is created as a last step after getting a "connection
> completed" HCI message, I think. What I am unsure about is if it's
> safe to just ignore the add if there is already a sysfs entry...
>
> So I would think the HCI core needs some resiliency against
> bad/malignant bluetooth controllers, and perform error
> recovery/resynchronization. Perhaps maybe there is room for a virtual
> hci controller that just injects various message types to see how well
> the core can cope?
>
> Thanks in advance,
> A

To further explain the issue, here is what was happening -

0) A BT device is paired.
1) Host goes into sleep mode.
2) BT device turns off.
3) Host wakes up due to BT waking the host. Due to UART resume issues,
HCI message corrupted. hci_disconn_complete_evt never gets called.
4) BT device turns on.
5) devref gets incremented in  hci_conn_complete_evt, and is now 2.
6) BT device turns off. hci_disconn_complete_evt is called, conn hash
is deleted, but sysfs entry not cleaned up since
atomic_dec_and_test(&conn->devref) != 0.
7) BT device turns on. sysfs add fails since it never was cleaned up.

The attached patch takes care of that. I'm not too familiar with BlueZ
(or bluetooth :-(), so I would like your feedback. In particular, I am
unsure about sync connections.
The primary issue overall is that HCI core doesn't handle HCI issues
(whether caused by transport issues, or bad/malicious BT controller).
I am curious if there are other ways to break the core.

Thanks,
A

[-- Attachment #2: 0001-BlueZ-HCI-Be-more-resilient-to-HCI-protocol-problems.patch --]
[-- Type: text/x-diff, Size: 2028 bytes --]

From 436bf684f8c0b9c92ce7aa21af4f53fa5629bf94 Mon Sep 17 00:00:00 2001
From: Andrei Warkentin <andreiw@motorola.com>
Date: Sat, 12 Feb 2011 01:25:25 -0600
Subject: [PATCH] BlueZ: HCI: Be more resilient to HCI protocol problems.

Do not corrupt kernel structs on connect message handling after
a missed (due to HCI transport issues or bad BT controller)
disconnect event message.

Change-Id: I8f461068896f7497f1e0127ea22ae6f07ae876b7
Signed-off-by: Andrei Warkentin <andreiw@motorola.com>
---
 net/bluetooth/hci_event.c |   23 +++++++++++++++++++----
 1 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index bbb4441..5bf51f0 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -895,8 +895,15 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
 		} else
 			conn->state = BT_CONNECTED;
 
-		hci_conn_hold_device(conn);
-		hci_conn_add_sysfs(conn);
+		/* We could have somehow not hci_conn_del-eted, due
+		   to errors in the HCI transport. */
+		if (atomic_read(&conn->devref) == 0) {
+			hci_conn_hold_device(conn);
+			hci_conn_add_sysfs(conn);
+		} else {
+			BT_ERR("connection to %s was never torn down", batostr(&ev->bdaddr));
+			hci_proto_disconn_cfm(conn, 0x16);
+		}
 
 		if (test_bit(HCI_AUTH, &hdev->flags))
 			conn->link_mode |= HCI_LM_AUTH;
@@ -1697,8 +1704,16 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu
 		conn->handle = __le16_to_cpu(ev->handle);
 		conn->state  = BT_CONNECTED;
 
-		hci_conn_hold_device(conn);
-		hci_conn_add_sysfs(conn);
+		/* We could have somehow not hci_conn_del-eted, due
+		   to errors in the HCI transport. */
+		if (atomic_read(&conn->devref) == 0) {
+			hci_conn_hold_device(conn);
+			hci_conn_add_sysfs(conn);
+		} else {
+			BT_ERR("sync connection to %s was never torn down", batostr(&ev->bdaddr));
+			hci_proto_disconn_cfm(conn, 0x16);
+		}
+
 		break;
 
 	case 0x10:	/* Connection Accept Timeout */
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH] BlueZ: HCI_LDISC: Make hci a child of the corresponding tty device.
From: Andrei Warkentin @ 2011-02-11 23:19 UTC (permalink / raw)
  To: linux-bluetooth

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

Dear List,

This depends on Dmitry Eremin-Solenikov's "Tty: add tty_struct->dev
pointer to corresponding device instance" patch,
which is in 2.6.37.

Thanks,
A

[-- Attachment #2: 0001-BlueZ-HCI_LDISC-Make-hci-a-child-of-the-correspondin.patch --]
[-- Type: text/x-diff, Size: 955 bytes --]

From 3ae2156afa420f3ba5cb73295037680bdca340f1 Mon Sep 17 00:00:00 2001
From: Andrei Warkentin <andreiw@motorola.com>
Date: Fri, 11 Feb 2011 17:59:52 -0600
Subject: [PATCH] BlueZ: HCI_LDISC: Make hci a child of the corresponding tty device.

Makes /sys/class/bluetooth/hciX a symlink to
path under corresponding tty.

Change-Id: I297361c13c61e2ad82293030553d9f0653e1273a
Signed-off-by: Andrei Warkentin <andreiw@motorola.com>
---
 drivers/bluetooth/hci_ldisc.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 17361ba..6a1b066 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -396,6 +396,7 @@ static int hci_uart_register_dev(struct hci_uart *hu)
 	hdev->flush = hci_uart_flush;
 	hdev->send  = hci_uart_send_frame;
 	hdev->destruct = hci_uart_destruct;
+	hdev->parent = hu->tty->dev;
 
 	hdev->owner = THIS_MODULE;
 
-- 
1.7.0.4


^ permalink raw reply related

* HCI core error recovery.
From: Andrei Warkentin @ 2011-02-11 23:07 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <AANLkTi=yuqTG1MiqN3FHM+2m0OX9QNajq8+xJG_D1-EG@mail.gmail.com>

Dear List,

I've run into an interesting problem. Excuse me in advance if this was
already covered here, or for my explanations, since I'm not too
familiar with overall flow within BlueZ or Bluetooth specifics...
We've had some hardware config issues that resulted in garbage/malformed
messages arriving via H4 into the HCI layer. We've since resolved
these, but it got me thinking. The issues would result in certain HCI
messages being missed, including occasionally disconnect events being
missed, and a subsequent connect event would result in a double add.

I was thinking about how to fix at the very least the crash. The sysfs
object is created as a last step after getting a "connection
completed" HCI message, I think. What I am unsure about is if it's
safe to just ignore the add if there is already a sysfs entry...

So I would think the HCI core needs some resiliency against
bad/malignant bluetooth controllers, and perform error
recovery/resynchronization. Perhaps maybe there is room for a virtual
hci controller that just injects various message types to see how well
the core can cope?

Thanks in advance,
A

[60197.080512] ------------[ cut here ]------------
[60197.085805] WARNING: at lib/list_debug.c:30 __list_add+0x60/0x80()
[60197.092426] list_add corruption. prev->next should be next
(da77fce8), but was cad1c39c. (prev=cad1c39c).
[60197.102778] Modules linked in: [last unloaded: bcm4329]
[60197.110097] [<c003a5f0>] (unwind_backtrace+0x0/0xf0) from
[<c006f774>] (warn_slowpath_common+0x4c/0x64)
[60197.120668] [<c006f774>] (warn_slowpath_common+0x4c/0x64) from
[<c006f80c>] (warn_slowpath_fmt+0x2c/0x3c)
[60197.130896] [<c006f80c>] (warn_slowpath_fmt+0x2c/0x3c) from
[<c01c9d18>] (__list_add+0x60/0x80)
[60197.140758] [<c01c9d18>] (__list_add+0x60/0x80) from [<c03e0920>]
(klist_add_tail+0x30/0x3c)
[60197.149903] [<c03e0920>] (klist_add_tail+0x30/0x3c) from
[<c0207868>] (device_add+0x35c/0x4b4)
[60197.159190] [<c0207868>] (device_add+0x35c/0x4b4) from [<c03ca444>]
(add_conn+0x38/0x100)
[60197.167754] [<c03ca444>] (add_conn+0x38/0x100) from [<c0081bec>]
(process_one_work+0x214/0x378)
[60197.177063] [<c0081bec>] (process_one_work+0x214/0x378) from
[<c0082130>] (worker_thread+0x224/0x39c)
[60197.187011] [<c0082130>] (worker_thread+0x224/0x39c) from
[<c0087180>] (kthread+0x80/0x88)
[60197.196052] [<c0087180>] (kthread+0x80/0x88) from [<c0035c04>]
(kernel_thread_exit+0x0/0x8)
[60197.205072] ---[ end trace 4576f4f7aba96cc4 ]---
[60197.214585] ------------[ cut here ]------------
[60197.219714] WARNING: at lib/list_debug.c:30 __list_add+0x60/0x80()
[60197.226507] list_add corruption. prev->next should be next
(ee1af820), but was e8a102d0. (prev=e8a102d0).
[60197.236701] Modules linked in: [last unloaded: bcm4329]
[60197.243157] [<c003a5f0>] (unwind_backtrace+0x0/0xf0) from
[<c006f774>] (warn_slowpath_common+0x4c/0x64)
[60197.253266] [<c006f774>] (warn_slowpath_common+0x4c/0x64) from
[<c006f80c>] (warn_slowpath_fmt+0x2c/0x3c)
[60197.263803] [<c006f80c>] (warn_slowpath_fmt+0x2c/0x3c) from
[<c01c9d18>] (__list_add+0x60/0x80)
[60197.273243] [<c01c9d18>] (__list_add+0x60/0x80) from [<c03e0920>]
(klist_add_tail+0x30/0x3c)
[60197.282069] [<c03e0920>] (klist_add_tail+0x30/0x3c) from
[<c0207894>] (device_add+0x388/0x4b4)
[60197.291356] [<c0207894>] (device_add+0x388/0x4b4) from [<c03ca444>]
(add_conn+0x38/0x100)
[60197.300269] [<c03ca444>] (add_conn+0x38/0x100) from [<c0081bec>]
(process_one_work+0x214/0x378)
[60197.309629] [<c0081bec>] (process_one_work+0x214/0x378) from
[<c0082130>] (worker_thread+0x224/0x39c)
[60197.319238] [<c0082130>] (worker_thread+0x224/0x39c) from
[<c0087180>] (kthread+0x80/0x88)
[60197.328179] [<c0087180>] (kthread+0x80/0x88) from [<c0035c04>]
(kernel_thread_exit+0x0/0x8)
[60197.337101] ---[ end trace 4576f4f7aba96cc5 ]---

^ permalink raw reply

* Re: [PATCHv2] Bluetooth: hcitool: add bdaddr type option to lecc
From: Johan Hedberg @ 2011-02-11 22:08 UTC (permalink / raw)
  To: Emeltchenko Andrei; +Cc: linux-bluetooth
In-Reply-To: <1297449064-32164-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Fri, Feb 11, 2011, Emeltchenko Andrei wrote:
> ---
>  tools/hcitool.c |    9 +++++++--
>  1 files changed, 7 insertions(+), 2 deletions(-)

Pushed upstream. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH 1/2] Fix wrong parameter order for memcpy in btoh128 function
From: Johan Hedberg @ 2011-02-11 22:06 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: linux-bluetooth
In-Reply-To: <1297446699-17349-1-git-send-email-claudio.takahasi@openbossa.org>

Hi Claudio,

On Fri, Feb 11, 2011, Claudio Takahasi wrote:
> ---
>  lib/sdp.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)

Both patches have been pushed upstream. Thanks.

Johan

^ permalink raw reply

* Re: [RFC 4/7] Add att_get_u128
From: Claudio Takahasi @ 2011-02-11 21:48 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1297456626-22837-5-git-send-email-claudio.takahasi@openbossa.org>

SGkgZm9sa3MsCgpPbiBGcmksIEZlYiAxMSwgMjAxMSBhdCA2OjM3IFBNLCBDbGF1ZGlvIFRha2Fo
YXNpCjxjbGF1ZGlvLnRha2FoYXNpQG9wZW5ib3NzYS5vcmc+IHdyb3RlOgo+IEZ1bmN0aW9uIHRv
IGNvbnZlcnQgMTI4LWJpdHMgdmFsdWVzIGZyb20gbGl0dGxlIGVuZGlhbiB0byBob3N0Cj4gb3Jk
ZXIuIERpZmZlcmVudCB0aGFuIFNEUCwgQVRUIHVzZXMgbGl0dGxlIGVuZGlhbiBmb3JtYXQuCj4g
LS0tCj4gwqBhdHRyaWIvYXR0LmMgwqAgwqAgwqB8IMKgIDEyICsrKysrKysrLS0tLQo+IMKgYXR0
cmliL2F0dC5oIMKgIMKgIMKgfCDCoCAxMCArKysrKysrKysrCj4gwqBhdHRyaWIvZ2F0dC5jIMKg
IMKgIHwgwqAgMTMgKysrKysrKystLS0tLQo+IMKgYXR0cmliL2dhdHR0b29sLmMgfCDCoCDCoDYg
KysrKy0tCj4gwqA0IGZpbGVzIGNoYW5nZWQsIDMwIGluc2VydGlvbnMoKyksIDExIGRlbGV0aW9u
cygtKQo+Cj4gZGlmZiAtLWdpdCBhL2F0dHJpYi9hdHQuYyBiL2F0dHJpYi9hdHQuYwo+IGluZGV4
IGRmZjg1OTcuLjViODUxYTIgMTAwNjQ0Cj4gLS0tIGEvYXR0cmliL2F0dC5jCj4gKysrIGIvYXR0
cmliL2F0dC5jCj4gQEAgLTE0MSw4ICsxNDEsMTAgQEAgdWludDE2X3QgZGVjX3JlYWRfYnlfZ3Jw
X3JlcShjb25zdCB1aW50OF90ICpwZHUsIGludCBsZW4sIHVpbnQxNl90ICpzdGFydCwKPiDCoCDC
oCDCoCDCoCplbmQgPSBhdHRfZ2V0X3UxNigmcGR1WzNdKTsKPiDCoCDCoCDCoCDCoGlmIChsZW4g
PT0gbWluX2xlbiArIDIpCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBzZHBfdXVpZDE2X2NyZWF0
ZSh1dWlkLCBhdHRfZ2V0X3UxNigmcGR1WzVdKSk7Cj4gLSDCoCDCoCDCoCBlbHNlCj4gLSDCoCDC
oCDCoCDCoCDCoCDCoCDCoCBzZHBfdXVpZDEyOF9jcmVhdGUodXVpZCwgJnBkdVs1XSk7Cj4gKyDC
oCDCoCDCoCBlbHNlIHsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHVpbnQxMjhfdCBoMTI4ID0g
YXR0X2dldF91MTI4KCZwZHVbNV0pOwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgc2RwX3V1aWQx
MjhfY3JlYXRlKHV1aWQsICZoMTI4KTsKPiArIMKgIMKgIMKgIH0KPgo+IMKgIMKgIMKgIMKgcmV0
dXJuIGxlbjsKPiDCoH0KPiBAQCAtMzcwLDggKzM3MiwxMCBAQCB1aW50MTZfdCBkZWNfcmVhZF9i
eV90eXBlX3JlcShjb25zdCB1aW50OF90ICpwZHUsIGludCBsZW4sIHVpbnQxNl90ICpzdGFydCwK
Pgo+IMKgIMKgIMKgIMKgaWYgKGxlbiA9PSBtaW5fbGVuICsgMikKPiDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoHNkcF91dWlkMTZfY3JlYXRlKHV1aWQsIGF0dF9nZXRfdTE2KCZwZHVbNV0pKTsKPiAt
IMKgIMKgIMKgIGVsc2UKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHNkcF91dWlkMTI4X2NyZWF0
ZSh1dWlkLCAmcGR1WzVdKTsKPiArIMKgIMKgIMKgIGVsc2Ugewo+ICsgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgdWludDEyOF90IGgxMjggPSBhdHRfZ2V0X3UxMjgoJnBkdVs1XSk7Cj4gKyDCoCDCoCDC
oCDCoCDCoCDCoCDCoCBzZHBfdXVpZDEyOF9jcmVhdGUodXVpZCwgJmgxMjgpOwo+ICsgwqAgwqAg
wqAgfQo+Cj4gwqAgwqAgwqAgwqByZXR1cm4gbGVuOwo+IMKgfQo+IGRpZmYgLS1naXQgYS9hdHRy
aWIvYXR0LmggYi9hdHRyaWIvYXR0LmgKPiBpbmRleCA3ZTgxZGM0Li4wY2Q2NjI2IDEwMDY0NAo+
IC0tLSBhL2F0dHJpYi9hdHQuaAo+ICsrKyBiL2F0dHJpYi9hdHQuaAo+IEBAIC0xNzAsNiArMTcw
LDE2IEBAIHN0YXRpYyBpbmxpbmUgdWludDMyX3QgYXR0X2dldF91MzIoY29uc3Qgdm9pZCAqcHRy
KQo+IMKgIMKgIMKgIMKgcmV0dXJuIGJ0b2hsKGJ0X2dldF91bmFsaWduZWQodTMyX3B0cikpOwo+
IMKgfQo+Cj4gK3N0YXRpYyBpbmxpbmUgdWludDEyOF90IGF0dF9nZXRfdTEyOChjb25zdCB2b2lk
ICpwdHIpClBhc3MgYSB1aW50MTI4X3QgcG9pbnRlciBvciByZXR1cm4gdGhlIHN0cnVjdCB1aW50
MTI4X3Q/CgpCUiwKQ2xhdWRpbwo+ICt7Cj4gKyDCoCDCoCDCoCBjb25zdCB1aW50MTI4X3QgKnUx
MjhfcHRyID0gcHRyOwo+ICsgwqAgwqAgwqAgdWludDEyOF90IGRzdDsKPiArCj4gKyDCoCDCoCDC
oCBidG9oMTI4KHUxMjhfcHRyLCAmZHN0KTsKPiArCj4gKyDCoCDCoCDCoCByZXR1cm4gZHN0Owo+
ICt9Cj4gKwo+IMKgc3RhdGljIGlubGluZSB2b2lkIGF0dF9wdXRfdTgodWludDhfdCBzcmMsIHZv
aWQgKmRzdCkKPiDCoHsKPiDCoCDCoCDCoCDCoGJ0X3B1dF91bmFsaWduZWQoc3JjLCAodWludDhf
dCAqKSBkc3QpOwo+IGRpZmYgLS1naXQgYS9hdHRyaWIvZ2F0dC5jIGIvYXR0cmliL2dhdHQuYwo+
IGluZGV4IGI5OWQzOWMuLjNmZWRjYzQgMTAwNjQ0Cj4gLS0tIGEvYXR0cmliL2dhdHQuYwo+ICsr
KyBiL2F0dHJpYi9nYXR0LmMKPiBAQCAtMTc0LDkgKzE3NCwxMCBAQCBzdGF0aWMgdm9pZCBwcmlt
YXJ5X2FsbF9jYihndWludDggc3RhdHVzLCBjb25zdCBndWludDggKmlwZHUsIGd1aW50MTYgaXBs
ZW4sCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqBhdHRfZ2V0X3UxNigmZGF0YVs0XSkpOwo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgc2RwX3V1aWQxNl90b191dWlkMTI4KCZ1MTI4LCAmdTE2KTsKPgo+IC0gwqAg
wqAgwqAgwqAgwqAgwqAgwqAgfSBlbHNlIGlmIChsaXN0LT5sZW4gPT0gMjApCj4gLSDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBzZHBfdXVpZDEyOF9jcmVhdGUoJnUxMjgsICZkYXRh
WzRdKTsKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGVsc2UKPiArIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIH0gZWxzZSBpZiAobGlzdC0+bGVuID09IDIwKSB7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCB1aW50MTI4X3QgaDEyOCA9IGF0dF9nZXRfdTEyOCgmZGF0YVs0XSk7Cj4g
KyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBzZHBfdXVpZDEyOF9jcmVhdGUoJnUx
MjgsICZoMTI4KTsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIH0gZWxzZQo+IMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLyogU2tpcHBpbmcgaW52YWxpZCBkYXRhICovCj4gwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBjb250aW51ZTsKPgo+IEBAIC0yNzEsOCAr
MjcyLDEwIEBAIHN0YXRpYyB2b2lkIGNoYXJfZGlzY292ZXJlZF9jYihndWludDggc3RhdHVzLCBj
b25zdCBndWludDggKmlwZHUsIGd1aW50MTYgaXBsZW4sCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqBpZiAobGlzdC0+bGVuID09IDcpIHsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoHNkcF91dWlkMTZfY3JlYXRlKCZ1MTYsIGF0dF9nZXRfdTE2KCZ2YWx1ZVs1XSkpOwo+IMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgc2RwX3V1aWQxNl90b191dWlkMTI4KCZ1
MTI4LCAmdTE2KTsKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIH0gZWxzZQo+IC0gwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgc2RwX3V1aWQxMjhfY3JlYXRlKCZ1MTI4LCAmdmFsdWVb
NV0pOwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgfSBlbHNlIHsKPiArIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIHVpbnQxMjhfdCBoMTI4ID0gYXR0X2dldF91MTI4KCZ2YWx1ZVs1
XSk7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBzZHBfdXVpZDEyOF9jcmVh
dGUoJnUxMjgsICZoMTI4KTsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIH0KPgo+IMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgY2hhcnMgPSBnX3RyeV9uZXcwKHN0cnVjdCBhdHRfY2hhciwgMSk7Cj4g
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAoIWNoYXJzKSB7Cj4gZGlmZiAtLWdpdCBhL2F0dHJp
Yi9nYXR0dG9vbC5jIGIvYXR0cmliL2dhdHR0b29sLmMKPiBpbmRleCA4ZThlZDhlLi42YzkzOTRl
IDEwMDY0NAo+IC0tLSBhL2F0dHJpYi9nYXR0dG9vbC5jCj4gKysrIGIvYXR0cmliL2dhdHR0b29s
LmMKPiBAQCAtNDY0LDggKzQ2NCwxMCBAQCBzdGF0aWMgdm9pZCBjaGFyX2Rlc2NfY2IoZ3VpbnQ4
IHN0YXR1cywgY29uc3QgZ3VpbnQ4ICpwZHUsIGd1aW50MTYgcGxlbiwKPgo+IMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgaWYgKGZvcm1hdCA9PSAweDAxKQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgc2RwX3V1aWQxNl9jcmVhdGUoJnV1aWQsIGF0dF9nZXRfdTE2KCZ2YWx1ZVsy
XSkpOwo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgZWxzZQo+IC0gwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgc2RwX3V1aWQxMjhfY3JlYXRlKCZ1dWlkLCAmdmFsdWVbMl0pOwo+ICsg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgZWxzZSB7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCB1aW50MTI4X3QgaDEyOCA9IGF0dF9nZXRfdTEyOCgmdmFsdWVbMl0pOwo+ICsgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgc2RwX3V1aWQxMjhfY3JlYXRlKCZ1dWlkLCAm
aDEyOCk7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCB9Cj4KPiDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoHNkcF91dWlkMnN0cm4oJnV1aWQsIHV1aWRzdHIsIE1BWF9MRU5fVVVJRF9TVFIpOwo+IMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgZ19wcmludCgiaGFuZGxlID0gMHglMDR4LCB1dWlkID0gJXNc
biIsIGhhbmRsZSwgdXVpZHN0cik7Cj4gLS0KPiAxLjcuNAo+Cj4K

^ permalink raw reply

* Re: [PATCHv2] Bluetooth: hcitool: add option for LE_Scan_Type parameter
From: Johan Hedberg @ 2011-02-11 21:48 UTC (permalink / raw)
  To: Emeltchenko Andrei; +Cc: linux-bluetooth
In-Reply-To: <1297445024-29256-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Fri, Feb 11, 2011, Emeltchenko Andrei wrote:
> The LE_Scan_Type parameter controls the type of scan to perform.
> ---
>  tools/hcitool.c |   10 ++++++++--
>  1 files changed, 8 insertions(+), 2 deletions(-)

Pushed upstream. Thanks.

Johan

^ permalink raw reply

* [RFC 3/3] Bluetooth: Send LE Connection Update Command
From: Claudio Takahasi @ 2011-02-11 21:28 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: padovan, Claudio Takahasi
In-Reply-To: <1297459736-24514-1-git-send-email-claudio.takahasi@openbossa.org>

If the new connection update parameter are accepted, the LE master
host sends the LE Connection Update Command to its controller informing
the new requested parameters.

Signed-off-by: Claudio Takahasi <claudio.takahasi@openbossa.org>
---
 include/net/bluetooth/hci.h      |   11 +++++++++++
 include/net/bluetooth/hci_core.h |    2 ++
 net/bluetooth/hci_conn.c         |   20 ++++++++++++++++++++
 net/bluetooth/l2cap_core.c       |    7 ++++++-
 4 files changed, 39 insertions(+), 1 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 46438f4..12417e1 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -701,6 +701,17 @@ struct hci_rp_le_ltk_neg_reply {
 	__le16	handle;
 } __packed;
 
+#define HCI_OP_LE_CONN_UPDATE		0x2013
+struct hci_cp_le_conn_update {
+	__le16   handle;
+	__le16   conn_interval_min;
+	__le16   conn_interval_max;
+	__le16   conn_latency;
+	__le16   supervision_timeout;
+	__le16   min_ce_len;
+	__le16   max_ce_len;
+} __packed;
+
 /* ---- HCI Events ---- */
 #define HCI_EV_INQUIRY_COMPLETE		0x01
 
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 5114122..f6c61d2 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -786,5 +786,7 @@ void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result);
 void hci_le_start_enc(struct hci_conn *conn, u8 ltk[16]);
 void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16]);
 void hci_le_ltk_neg_reply(struct hci_conn *conn);
+void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
+					u16 latency, u16 to_multiplier);
 
 #endif /* __HCI_CORE_H */
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index ee7dcdd..d646037 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -231,6 +231,26 @@ void hci_le_ltk_neg_reply(struct hci_conn *conn)
 }
 EXPORT_SYMBOL(hci_le_ltk_neg_reply);
 
+void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
+					u16 latency, u16 to_multiplier)
+{
+	struct hci_cp_le_conn_update cp;
+	struct hci_dev *hdev = conn->hdev;
+
+	memset(&cp, 0, sizeof(cp));
+
+	cp.handle		= cpu_to_le16(conn->handle);
+	cp.conn_interval_min	= cpu_to_le16(min);
+	cp.conn_interval_max	= cpu_to_le16(max);
+	cp.conn_latency		= cpu_to_le16(latency);
+	cp.supervision_timeout	= cpu_to_le16(to_multiplier);
+	cp.min_ce_len		= cpu_to_le16(0x0001);
+	cp.max_ce_len		= cpu_to_le16(0x0001);
+
+	hci_send_cmd(hdev, HCI_OP_LE_CONN_UPDATE, sizeof(cp), &cp);
+}
+EXPORT_SYMBOL(hci_le_conn_update);
+
 /* Device _must_ be locked */
 void hci_sco_setup(struct hci_conn *conn, __u8 status)
 {
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 8b76a72..66c4d80 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -2555,7 +2555,9 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
 						min, max, latency, to_multiplier);
 
 	memset(&rsp, 0, sizeof(rsp));
-	if (l2cap_check_conn_param(min, max, latency, to_multiplier))
+
+	err = l2cap_check_conn_param(min, max, latency, to_multiplier);
+	if (err)
 		rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
 	else
 		rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
@@ -2563,6 +2565,9 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
 	l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
 							sizeof(rsp), &rsp);
 
+	if (!err)
+		hci_le_conn_update(hcon, min, max, latency, to_multiplier);
+
 	return 0;
 }
 
-- 
1.7.4


^ permalink raw reply related

* [RFC 2/3] Bluetooth: Add connection parameter update response
From: Claudio Takahasi @ 2011-02-11 21:28 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: padovan, Claudio Takahasi
In-Reply-To: <1297459736-24514-1-git-send-email-claudio.takahasi@openbossa.org>

Implements L2CAP Connection Parameter Update Response defined in
the Bluetooth Core Specification, Volume 3, Part A, section 4.21.
Address the LE Connection Parameter Procedure initiated by the slave.

Connection Interval Minimum and Maximum have the same range: 6 to
3200. Time = N * 1.25ms. Minimum shall be less or equal to Maximum.
The Slave Latency field shall have a value in the range of 0 to
((connSupervisionTimeout / connIntervalMax) - 1). Latency field shall
be less than 500. connSupervisionTimeout = Timeout Multiplier * 10 ms.
Multiplier field shall have a value in the range of 10 to 3200.

Signed-off-by: Claudio Takahasi <claudio.takahasi@openbossa.org>
---
 include/net/bluetooth/l2cap.h |   15 ++++++++++
 net/bluetooth/l2cap_core.c    |   60 ++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 74 insertions(+), 1 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 6aa70e9..be0116b 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -261,6 +261,21 @@ struct l2cap_info_rsp {
 #define L2CAP_IR_SUCCESS    0x0000
 #define L2CAP_IR_NOTSUPP    0x0001
 
+struct l2cap_conn_param_update_req {
+	__le16      min;
+	__le16      max;
+	__le16      latency;
+	__le16      to_multiplier;
+} __packed;
+
+struct l2cap_conn_param_update_rsp {
+	__le16      result;
+} __packed;
+
+/* Connection Parameters result */
+#define L2CAP_CONN_PARAM_ACCEPTED	0x0000
+#define L2CAP_CONN_PARAM_REJECTED	0x0001
+
 /* ----- L2CAP connections ----- */
 struct l2cap_chan_list {
 	struct sock	*head;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 122fc1c..8b76a72 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -2508,6 +2508,64 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
 	return 0;
 }
 
+static int inline l2cap_check_conn_param(u16 min, u16 max, u16 latency,
+							u16 to_multiplier)
+{
+	u16 max_latency;
+
+	if (min > max || min < 6 || max > 3200)
+		return -EINVAL;
+
+	if (to_multiplier < 10 || to_multiplier > 3200)
+		return -EINVAL;
+
+	if (max >= to_multiplier * 8)
+		return -EINVAL;
+
+	max_latency = (to_multiplier * 8 / max) - 1;
+	if (latency > 499 || latency > max_latency)
+		return -EINVAL;
+
+	return 0;
+}
+
+static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
+					struct l2cap_cmd_hdr *cmd, u8 *data)
+{
+	struct hci_conn *hcon = conn->hcon;
+	struct l2cap_conn_param_update_req *req;
+	struct l2cap_conn_param_update_rsp rsp;
+	u16 min, max, latency, to_multiplier, cmd_len;
+	int err;
+
+	if (!(hcon->link_mode & HCI_LM_MASTER))
+		return -EINVAL;
+
+	cmd_len = __le16_to_cpu(cmd->len);
+	if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
+		return -EPROTO;
+
+	req = (struct l2cap_conn_param_update_req *) data;
+	min 		= __le16_to_cpu(req->min);
+	max 		= __le16_to_cpu(req->max);
+	latency		= __le16_to_cpu(req->latency);
+	to_multiplier	= __le16_to_cpu(req->to_multiplier);
+
+	BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
+						min, max, latency, to_multiplier);
+
+	memset(&rsp, 0, sizeof(rsp));
+	if (l2cap_check_conn_param(min, max, latency, to_multiplier))
+		rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
+	else
+		rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
+
+	l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
+							sizeof(rsp), &rsp);
+
+	return 0;
+}
+
 static inline int bredr_sig_cmd(struct l2cap_conn *conn,
 			struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
 {
@@ -2577,7 +2635,7 @@ static inline int le_sig_cmd(struct l2cap_conn *conn,
 		break;
 
 	case L2CAP_CONN_PARAM_UPDATE_REQ:
-		err = -EINVAL;
+		err = l2cap_conn_param_update_req(conn, cmd, data);
 		break;
 
 	case L2CAP_CONN_PARAM_UPDATE_RSP:
-- 
1.7.4


^ permalink raw reply related

* [RFC 1/3] Bluetooth: Add LE signaling commands handling
From: Claudio Takahasi @ 2011-02-11 21:28 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: padovan, Claudio Takahasi
In-Reply-To: <1297459736-24514-1-git-send-email-claudio.takahasi@openbossa.org>

This patch splits the L2CAP command handling function in order to
have a clear separation between the commands related to BR/EDR and
LE. Commands and responses in the LE signaling channel are not being
handled yet, command reject is sent to all received requests. Bluetooth
Core Specification, Volume 3, Part A, section 4 defines the signaling
packets formats and allowed commands/responses over the LE signaling
channel.

Signed-off-by: Claudio Takahasi <claudio.takahasi@openbossa.org>
---
 include/net/bluetooth/l2cap.h |    2 +
 net/bluetooth/l2cap_core.c    |  150 +++++++++++++++++++++++++++--------------
 2 files changed, 100 insertions(+), 52 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 420981c..6aa70e9 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -89,6 +89,8 @@ struct l2cap_conninfo {
 #define L2CAP_ECHO_RSP		0x09
 #define L2CAP_INFO_REQ		0x0a
 #define L2CAP_INFO_RSP		0x0b
+#define L2CAP_CONN_PARAM_UPDATE_REQ	0x12
+#define L2CAP_CONN_PARAM_UPDATE_RSP	0x13
 
 /* L2CAP feature mask */
 #define L2CAP_FEAT_FLOWCTL	0x00000001
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 0ca54d8..122fc1c 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1435,7 +1435,11 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
 
 	lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
 	lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
-	lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
+
+	if (conn->hcon->type == LE_LINK)
+		lh->cid = cpu_to_le16(L2CAP_CID_LE_SIGNALING);
+	else
+		lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
 
 	cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
 	cmd->code  = code;
@@ -2504,12 +2508,98 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
 	return 0;
 }
 
-static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
+static inline int bredr_sig_cmd(struct l2cap_conn *conn,
+			struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
+{
+	int err = 0;
+
+	switch (cmd->code) {
+	case L2CAP_COMMAND_REJ:
+		l2cap_command_rej(conn, cmd, data);
+		break;
+
+	case L2CAP_CONN_REQ:
+		err = l2cap_connect_req(conn, cmd, data);
+		break;
+
+	case L2CAP_CONN_RSP:
+		err = l2cap_connect_rsp(conn, cmd, data);
+		break;
+
+	case L2CAP_CONF_REQ:
+		err = l2cap_config_req(conn, cmd, cmd_len, data);
+		break;
+
+	case L2CAP_CONF_RSP:
+		err = l2cap_config_rsp(conn, cmd, data);
+		break;
+
+	case L2CAP_DISCONN_REQ:
+		err = l2cap_disconnect_req(conn, cmd, data);
+		break;
+
+	case L2CAP_DISCONN_RSP:
+		err = l2cap_disconnect_rsp(conn, cmd, data);
+		break;
+
+	case L2CAP_ECHO_REQ:
+		l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
+		break;
+
+	case L2CAP_ECHO_RSP:
+		break;
+
+	case L2CAP_INFO_REQ:
+		err = l2cap_information_req(conn, cmd, data);
+		break;
+
+	case L2CAP_INFO_RSP:
+		err = l2cap_information_rsp(conn, cmd, data);
+		break;
+
+	default:
+		BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
+		err = -EINVAL;
+		break;
+	}
+
+	return err;
+}
+
+static inline int le_sig_cmd(struct l2cap_conn *conn,
+					struct l2cap_cmd_hdr *cmd, u8 *data)
+{
+	int err;
+
+	switch (cmd->code) {
+	case L2CAP_COMMAND_REJ:
+		err = 0;
+		break;
+
+	case L2CAP_CONN_PARAM_UPDATE_REQ:
+		err = -EINVAL;
+		break;
+
+	case L2CAP_CONN_PARAM_UPDATE_RSP:
+		err = 0;
+		break;
+
+	default:
+		BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
+		err = -EINVAL;
+		break;
+	}
+
+	return err;
+}
+
+static inline void l2cap_sig_channel(struct l2cap_conn *conn,
+							struct sk_buff *skb)
 {
 	u8 *data = skb->data;
 	int len = skb->len;
 	struct l2cap_cmd_hdr cmd;
-	int err = 0;
+	int err;
 
 	l2cap_raw_recv(conn, skb);
 
@@ -2528,55 +2618,10 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *sk
 			break;
 		}
 
-		switch (cmd.code) {
-		case L2CAP_COMMAND_REJ:
-			l2cap_command_rej(conn, &cmd, data);
-			break;
-
-		case L2CAP_CONN_REQ:
-			err = l2cap_connect_req(conn, &cmd, data);
-			break;
-
-		case L2CAP_CONN_RSP:
-			err = l2cap_connect_rsp(conn, &cmd, data);
-			break;
-
-		case L2CAP_CONF_REQ:
-			err = l2cap_config_req(conn, &cmd, cmd_len, data);
-			break;
-
-		case L2CAP_CONF_RSP:
-			err = l2cap_config_rsp(conn, &cmd, data);
-			break;
-
-		case L2CAP_DISCONN_REQ:
-			err = l2cap_disconnect_req(conn, &cmd, data);
-			break;
-
-		case L2CAP_DISCONN_RSP:
-			err = l2cap_disconnect_rsp(conn, &cmd, data);
-			break;
-
-		case L2CAP_ECHO_REQ:
-			l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
-			break;
-
-		case L2CAP_ECHO_RSP:
-			break;
-
-		case L2CAP_INFO_REQ:
-			err = l2cap_information_req(conn, &cmd, data);
-			break;
-
-		case L2CAP_INFO_RSP:
-			err = l2cap_information_rsp(conn, &cmd, data);
-			break;
-
-		default:
-			BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
-			err = -EINVAL;
-			break;
-		}
+		if (conn->hcon->type == LE_LINK)
+			err = le_sig_cmd(conn, &cmd, data);
+		else
+			err = bredr_sig_cmd(conn, &cmd, cmd_len, data);
 
 		if (err) {
 			struct l2cap_cmd_rej rej;
@@ -3573,6 +3618,7 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
 	BT_DBG("len %d, cid 0x%4.4x", len, cid);
 
 	switch (cid) {
+	case L2CAP_CID_LE_SIGNALING:
 	case L2CAP_CID_SIGNALING:
 		l2cap_sig_channel(conn, skb);
 		break;
-- 
1.7.4


^ permalink raw reply related

* [RFC 0/3] LE Connection Parameter Update Procedure
From: Claudio Takahasi @ 2011-02-11 21:28 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: padovan, Claudio Takahasi

The following patches implement the support for LE Connection Parameter
Update procedure started by the LE slave/peripheral device. Procedure
started by the master will be addressed later when the requirements
become more clear, Bluetooth Core SPEC and GAP test specification are
not matching.

Patches are rebased using Vinicius SMP patches, repo:
git://git.infradead.org/users/vcgomes/linux-2.6.git for-next

LE signaling channel can receive the following L2CAP commands(only):
  - Command Reject
  - Connection Parameter Update request
  - Connection Parameter Update response

Claudio Takahasi (3):
  Bluetooth: Add LE signaling commands handling
  Bluetooth: Add connection parameter update response
  Bluetooth: Send LE Connection Update Command

 include/net/bluetooth/hci.h      |   11 ++
 include/net/bluetooth/hci_core.h |    2 +
 include/net/bluetooth/l2cap.h    |   17 +++
 net/bluetooth/hci_conn.c         |   20 ++++
 net/bluetooth/l2cap_core.c       |  213 ++++++++++++++++++++++++++++---------
 5 files changed, 211 insertions(+), 52 deletions(-)

-- 
1.7.4


^ permalink raw reply

* Re: [PATCH 6/7 v2] Introduction of phonebook_pull_read
From: Johan Hedberg @ 2011-02-11 21:14 UTC (permalink / raw)
  To: Radoslaw Jablonski; +Cc: linux-bluetooth
In-Reply-To: <1297433139-10923-6-git-send-email-ext-jablonski.radoslaw@nokia.com>

Hi Radek,

On Fri, Feb 11, 2011, Radoslaw Jablonski wrote:
> +	ret = phonebook_pull_read(irmc->request);
> +
> +	if (err) {
> +		*err = ret;
> +	}

No empty line before the if-statement and no {} for one-line sections.

> +		ret = phonebook_pull_read(irmc->request);
> +
> +		if (ret < 0) {

No empty line here, like above.

> +	ret = phonebook_pull_read(request);
> +
> +	if (ret < 0)

Same here.

> +		len = string_read(obj->buffer, buf, count);
> +
> +		if (len == 0 && !obj->lastpart) {

And here.

Johan

^ permalink raw reply

* Re: [PATCH 1/7 v2] Add return value to query tracker
From: Johan Hedberg @ 2011-02-11 21:11 UTC (permalink / raw)
  To: Radoslaw Jablonski; +Cc: linux-bluetooth
In-Reply-To: <1297433139-10923-1-git-send-email-ext-jablonski.radoslaw@nokia.com>

Hi Radek,

On Fri, Feb 11, 2011, Radoslaw Jablonski wrote:
> +	if(err)

Coding style: space between if and (

> +	if(err)

Same here.

> +	if(err)

And here.

Johan

^ permalink raw reply

* Re: [PATCH] Bluetooth: hcitool: add option for LE_Scan_Type parameter
From: Johan Hedberg @ 2011-02-11 21:10 UTC (permalink / raw)
  To: Emeltchenko Andrei, linux-bluetooth
In-Reply-To: <20110211210607.GB26894@jh-x301>

Hi,

On Fri, Feb 11, 2011, Johan Hedberg wrote:
> Hi Andrei,
> 
> On Thu, Feb 10, 2011, Emeltchenko Andrei wrote:
> > +	"\tlescan [--scantype] set scan type 0 - passive, 1 - active (default)\n";
> 
> Maybe this should be a boolean flag like the address type? I.e.
> --passive and/or --active command line switches?

Nevermind. I see that you already sent an updated patch which does this.

Johan

^ permalink raw reply

* Re: [PATCH] Bluetooth: hcitool: add option for LE_Scan_Type parameter
From: Johan Hedberg @ 2011-02-11 21:06 UTC (permalink / raw)
  To: Emeltchenko Andrei; +Cc: linux-bluetooth
In-Reply-To: <1297373795-14909-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Thu, Feb 10, 2011, Emeltchenko Andrei wrote:
> +	"\tlescan [--scantype] set scan type 0 - passive, 1 - active (default)\n";

Maybe this should be a boolean flag like the address type? I.e.
--passive and/or --active command line switches?

Johan

^ permalink raw reply

* Re: [PATCH] Add check for ACL_START_NO_FLUSH
From: Johan Hedberg @ 2011-02-11 21:03 UTC (permalink / raw)
  To: Daniel Westerlund; +Cc: linux-bluetooth
In-Reply-To: <AANLkTinUUNTzRf767irg3qSK8iefjn=pKMCknQ8f9=u-@mail.gmail.com>

Hi Daniel,

On Thu, Feb 10, 2011, Daniel ??rstadius wrote:
> In addition to ACL_START, hcidump should check for the flag
> ACL_START_NO_FLUSH to indicate the start of a frame.
> 
> Using '==' instead of '&' for the comparison since
> ACL_START_NO_FLUSH is defined to zero.
> 
> The flag was introduced in BlueZ commit
> 2430512c983cad8c20252f1df8f297399993ca3d
> ---
>  parser/l2cap.c |    3 ++-
>  1 files changed, 2 insertions(+), 1 deletions(-)

Pushed upstream after obvious coding-style fixes. Please pay attention
to those.

Johan

^ permalink raw reply

* [RFC 7/7] Convert from host order to network order before to print UUID128
From: Claudio Takahasi @ 2011-02-11 20:37 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1297456626-22837-1-git-send-email-claudio.takahasi@openbossa.org>

---
 lib/sdp.c         |   30 +++++++++++++++++-------------
 src/glib-helper.c |   14 ++++++++------
 tools/sdptool.c   |   16 +++++++++-------
 3 files changed, 34 insertions(+), 26 deletions(-)

diff --git a/lib/sdp.c b/lib/sdp.c
index 3c4cd50..75154e9 100644
--- a/lib/sdp.c
+++ b/lib/sdp.c
@@ -285,13 +285,15 @@ int sdp_uuid2strn(const uuid_t *uuid, char *str, size_t n)
 		unsigned short data3;
 		unsigned int   data4;
 		unsigned short data5;
+		uint128_t n128;
 
-		memcpy(&data0, &uuid->value.uuid128.data[0], 4);
-		memcpy(&data1, &uuid->value.uuid128.data[4], 2);
-		memcpy(&data2, &uuid->value.uuid128.data[6], 2);
-		memcpy(&data3, &uuid->value.uuid128.data[8], 2);
-		memcpy(&data4, &uuid->value.uuid128.data[10], 4);
-		memcpy(&data5, &uuid->value.uuid128.data[14], 2);
+		hton128(&uuid->value.uuid128, &n128);
+		memcpy(&data0, &n128.data[0], 4);
+		memcpy(&data1, &n128.data[4], 2);
+		memcpy(&data2, &n128.data[6], 2);
+		memcpy(&data3, &n128.data[8], 2);
+		memcpy(&data4, &n128.data[10], 4);
+		memcpy(&data5, &n128.data[14], 2);
 
 		snprintf(str, n, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
 				ntohl(data0), ntohs(data1),
@@ -333,13 +335,15 @@ void sdp_uuid_print(const uuid_t *uuid)
 		unsigned short data3;
 		unsigned int data4;
 		unsigned short data5;
-
-		memcpy(&data0, &uuid->value.uuid128.data[0], 4);
-		memcpy(&data1, &uuid->value.uuid128.data[4], 2);
-		memcpy(&data2, &uuid->value.uuid128.data[6], 2);
-		memcpy(&data3, &uuid->value.uuid128.data[8], 2);
-		memcpy(&data4, &uuid->value.uuid128.data[10], 4);
-		memcpy(&data5, &uuid->value.uuid128.data[14], 2);
+		uint128_t n128;
+
+		hton128(&uuid->value.uuid128, &n128);
+		memcpy(&data0, &n128.data[0], 4);
+		memcpy(&data1, &n128.data[4], 2);
+		memcpy(&data2, &n128.data[6], 2);
+		memcpy(&data3, &n128.data[8], 2);
+		memcpy(&data4, &n128.data[10], 4);
+		memcpy(&data5, &n128.data[14], 2);
 
 		SDPDBG("  uint128_t : 0x%.8x-", ntohl(data0));
 		SDPDBG("%.4x-", ntohs(data1));
diff --git a/src/glib-helper.c b/src/glib-helper.c
index 22c14e7..2b7e1b3 100644
--- a/src/glib-helper.c
+++ b/src/glib-helper.c
@@ -372,6 +372,7 @@ char *bt_uuid2string(uuid_t *uuid)
 {
 	gchar *str;
 	uuid_t uuid128;
+	uint128_t n128;
 	unsigned int data0;
 	unsigned short data1;
 	unsigned short data2;
@@ -397,12 +398,13 @@ char *bt_uuid2string(uuid_t *uuid)
 		return NULL;
 	}
 
-	memcpy(&data0, &uuid128.value.uuid128.data[0], 4);
-	memcpy(&data1, &uuid128.value.uuid128.data[4], 2);
-	memcpy(&data2, &uuid128.value.uuid128.data[6], 2);
-	memcpy(&data3, &uuid128.value.uuid128.data[8], 2);
-	memcpy(&data4, &uuid128.value.uuid128.data[10], 4);
-	memcpy(&data5, &uuid128.value.uuid128.data[14], 2);
+	hton128(&uuid128.value.uuid128, &n128);
+	memcpy(&data0, &n128.data[0], 4);
+	memcpy(&data1, &n128.data[4], 2);
+	memcpy(&data2, &n128.data[6], 2);
+	memcpy(&data3, &n128.data[8], 2);
+	memcpy(&data4, &n128.data[10], 4);
+	memcpy(&data5, &n128.data[14], 2);
 
 	str = g_try_malloc0(MAX_LEN_UUID_STR);
 	if (!str)
diff --git a/tools/sdptool.c b/tools/sdptool.c
index 140a46a..341e258 100644
--- a/tools/sdptool.c
+++ b/tools/sdptool.c
@@ -389,13 +389,15 @@ static void sdp_uuid_printf(uuid_t *uuid, struct attrib_context *context, int in
 			unsigned short data3;
 			unsigned int data4;
 			unsigned short data5;
-
-			memcpy(&data0, &uuid->value.uuid128.data[0], 4);
-			memcpy(&data1, &uuid->value.uuid128.data[4], 2);
-			memcpy(&data2, &uuid->value.uuid128.data[6], 2);
-			memcpy(&data3, &uuid->value.uuid128.data[8], 2);
-			memcpy(&data4, &uuid->value.uuid128.data[10], 4);
-			memcpy(&data5, &uuid->value.uuid128.data[14], 2);
+			uint128_t n128;
+
+			hton128(&uuid->value.uuid128, &n128);
+			memcpy(&data0, &n128.data[0], 4);
+			memcpy(&data1, &n128.data[4], 2);
+			memcpy(&data2, &n128.data[6], 2);
+			memcpy(&data3, &n128.data[8], 2);
+			memcpy(&data4, &n128.data[10], 4);
+			memcpy(&data5, &n128.data[14], 2);
 
 			printf("%.*sUUID128 : 0x%.8x-%.4x-%.4x-%.4x-%.8x-%.4x\n",
 				indent, indent_spaces,
-- 
1.7.4


^ permalink raw reply related


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