Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH 3/7 v2] Remove unnecessary checking for num_fields in pull_contact
From: Radoslaw Jablonski @ 2011-02-11 14:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1297433139-10923-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 a8c8a87..be94867 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 v2] Add return value to reply_list_foreach_t in phonebook-tracker
From: Radoslaw Jablonski @ 2011-02-11 14:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski
In-Reply-To: <1297433139-10923-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 623e294..a8c8a87 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 v2] Add return value to query tracker
From: Radoslaw Jablonski @ 2011-02-11 14:05 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 |   40 +++++++++++++++++++++-------------------
 1 files changed, 21 insertions(+), 19 deletions(-)

diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index e116175..623e294 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,10 @@ 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 +1922,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,11 +1940,13 @@ 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);
 
 	g_free(query);
 
+	if(err)
+		*err = ret;
+
 	return data;
 }
 
@@ -1957,6 +1955,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 +1970,10 @@ 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

* Re: [PATCH v5 0/4] Adding HID Feature Report Support to hidraw
From: Jiri Kosina @ 2011-02-11 14:02 UTC (permalink / raw)
  To: Gustavo F. Padovan
  Cc: Alan Ott, Marcel Holtmann, David S. Miller, Michael Poole,
	Eric Dumazet, linux-input, linux-kernel, linux-usb,
	linux-bluetooth, netdev
In-Reply-To: <20110210181441.GB2173@joana>

On Thu, 10 Feb 2011, Gustavo F. Padovan 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.
> > > The fourth patch is the Bluetooth changes.
> > > 
> > > Thanks to Antonio Ospite and Bill Good for providing testing and feedback.
> > > 
> > > 
> > > Alan Ott (4):
> > >   bt hidp: Move hid_add_device() call to after hidp_session() has
> > >     started.
> > >   bt hidp: Wait for ACK on Sent Reports
> > >   HID: Add Support for Setting and Getting Feature Reports from hidraw
> > >   Bluetooth hidp: Add support for hidraw HIDIOCGFEATURE and
> > >     HIDIOCSFEATURE
> > > 
> > >  drivers/hid/hidraw.c          |  106 +++++++++++++++++++-
> > >  drivers/hid/usbhid/hid-core.c |   35 +++++++
> > >  include/linux/hid.h           |    3 +
> > >  include/linux/hidraw.h        |    3 +
> > >  net/bluetooth/hidp/core.c     |  214 ++++++++++++++++++++++++++++++++++++++---
> > >  net/bluetooth/hidp/hidp.h     |   15 +++
> > 
> > Before proceeding with these patches, I'd really like to have comment 
> > (ideally 'Acked-by') from Marcel on the net/bluetooth/hidp part, 
> > obviously.
> 
> I have tested it and it seems ok to me and to Marcel. For net/bluetooth/
> 
> Acked-by: Gustavo F. Padovan <padovan@profusion.mobi>

Awesome, thanks a lot everyone for having this sorted out finally!

I will be taking the patchset through my tree.

-- 
Jiri Kosina
SUSE Labs, Novell Inc.

^ permalink raw reply

* [PATCH] btusb:fix crash with quirky dongles doing sound
From: Oliver Neukum @ 2011-02-11 12:00 UTC (permalink / raw)
  To: Marcel Holtmann, Gustavo F. Padovan, linux-bluetooth, linux-usb,
	stable, ensonic

=46rom befd2cd1a7875d395f72b38f2cb89a03f16edaba Mon Sep 17 00:00:00 2001
=46rom: Oliver Neukum <oliver@neukum.org>
Date: Fri, 11 Feb 2011 12:35:05 +0100
Subject: [PATCH] btusb:fix crash with quirky dongles doing sound

Quirky dongles sometimes do not use the iso interface which
causes a crash with runtime PM

Signed-off-by: Oliver Neukum <oneukum@suse.de>
=2D--
 drivers/bluetooth/btusb.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 1da773f..08c8629 100644
=2D-- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -826,7 +826,7 @@ static void btusb_work(struct work_struct *work)
=20
 	if (hdev->conn_hash.sco_num > 0) {
 		if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) {
=2D			err =3D usb_autopm_get_interface(data->isoc);
+			err =3D usb_autopm_get_interface(data->isoc ? data->isoc : data->intf);
 			if (err < 0) {
 				clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
 				usb_kill_anchored_urbs(&data->isoc_anchor);
@@ -855,7 +855,7 @@ static void btusb_work(struct work_struct *work)
=20
 		__set_isoc_interface(hdev, 0);
 		if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags))
=2D			usb_autopm_put_interface(data->isoc);
+			usb_autopm_put_interface(data->isoc ? data->isoc : data->intf);
 	}
 }
=20
=2D-=20
1.7.1

^ permalink raw reply

* Re: [PATCH] Bluetooth: hcitool: add bdaddr type option to lecc
From: Anderson Lizardo @ 2011-02-11 11:14 UTC (permalink / raw)
  To: Emeltchenko Andrei; +Cc: linux-bluetooth
In-Reply-To: <1297299551-10297-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Wed, Feb 9, 2011 at 9:59 PM, Emeltchenko Andrei
<Andrei.Emeltchenko.news@gmail.com> wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
>
> ---
>  tools/hcitool.c |   10 +++++++---
>  1 files changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/tools/hcitool.c b/tools/hcitool.c
> index 536d407..c097526 100644
> --- a/tools/hcitool.c
> +++ b/tools/hcitool.c
> @@ -2420,7 +2420,7 @@ static struct option lecc_options[] = {
>
>  static const char *lecc_help =
>        "Usage:\n"
> -       "\tlecc <bdaddr>\n";
> +       "\tlecc <bdaddr> [conn type]\n";

Actually it would be "[bdaddr type]", right?

But I still think we should have a --random boolean option that sets
the bdaddr type to 0x01 if it is TRUE, FALSE otherwise. Other values
are RFU.

>
>  static void cmd_lecc(int dev_id, int argc, char **argv)
>  {
> @@ -2437,7 +2437,7 @@ static void cmd_lecc(int dev_id, int argc, char **argv)
>                        return;
>                }
>        }
> -       helper_arg(1, 1, &argc, &argv, lecc_help);
> +       helper_arg(1, 2, &argc, &argv, lecc_help);
>
>        if (dev_id < 0)
>                dev_id = hci_get_route(NULL);
> @@ -2450,10 +2450,14 @@ static void cmd_lecc(int dev_id, int argc, char **argv)
>
>        str2ba(argv[0], &bdaddr);
>
> +       if (argc == 2)
> +               peer_bdaddr_type = atoi(argv[1]);
> +       else
> +               peer_bdaddr_type = 0;
> +

Note you are not validating values here as in your other patch.

>        interval = htobs(0x0004);
>        window = htobs(0x0004);
>        initiator_filter = 0x00;
> -       peer_bdaddr_type = 0x00;
>        own_bdaddr_type = 0x00;
>        min_interval = htobs(0x000F);
>        max_interval = htobs(0x000F);
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

Regards,
-- 
Anderson Lizardo
OpenBossa Labs - INdT
Manaus - Brazil

^ permalink raw reply

* Re: [PATCH] Bluetooth: hcitool: add option for LE_Scan_Type parameter
From: Anderson Lizardo @ 2011-02-11 11:09 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 at 6:36 PM, Emeltchenko Andrei
<Andrei.Emeltchenko.news@gmail.com> wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
>
> The LE_Scan_Type parameter controls the type of scan to perform.
> ---
>  tools/hcitool.c |   14 ++++++++++++--
>  1 files changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/tools/hcitool.c b/tools/hcitool.c
> index c097526..6d17ad5 100644
> --- a/tools/hcitool.c
> +++ b/tools/hcitool.c
> @@ -2350,23 +2350,33 @@ done:
>  static struct option lescan_options[] = {
>        { "help",       0, 0, 'h' },
>        { "privacy",    0, 0, 'p' },
> +       { "scantype",   1, 0, 's' },
>        { 0, 0, 0, 0 }
>  };
>
>  static const char *lescan_help =
>        "Usage:\n"
> -       "\tlescan [--privacy] enable privacy\n";
> +       "\tlescan [--privacy] enable privacy\n"
> +       "\tlescan [--scantype] set scan type 0 - passive, 1 - active (default)\n";

I think it is enough to have a "--passive" boolean option and set
scantype to 0x00 if it is TRUE and 0x01 if it is FALSE.

Regards,
-- 
Anderson Lizardo
OpenBossa Labs - INdT
Manaus - Brazil

^ permalink raw reply

* [PATCH v2] Bluetooth: Add firmware support for Atheros 3012
From: Bala Shanmugam @ 2011-02-11 10:08 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Bala Shanmugam

Blacklisted AR3012 PID in btusb and added the same
in ath3k to load patch and sysconfig files.

Signed-off-by: Bala Shanmugam <sbalashanmugam@atheros.com>
---
 drivers/bluetooth/ath3k.c |  279 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/bluetooth/btusb.c |    3 +
 2 files changed, 282 insertions(+), 0 deletions(-)

diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 41dadac..7035006 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -31,6 +31,30 @@
 
 #define VERSION "1.0"
 
+#define ATH3K_DNLOAD				0x01
+#define ATH3K_GETSTATE				0x05
+#define ATH3K_SET_NORMAL_MODE			0x07
+#define ATH3K_GETVERSION			0x09
+#define USB_REG_SWITCH_VID_PID			0x0a
+
+#define ATH3K_MODE_MASK				0x3F
+#define ATH3K_NORMAL_MODE			0x0E
+
+#define ATH3K_PATCH_UPDATE			0x80
+#define ATH3K_SYSCFG_UPDATE			0x40
+
+#define ATH3K_XTAL_FREQ_26M			0x00
+#define ATH3K_XTAL_FREQ_40M			0x01
+#define ATH3K_XTAL_FREQ_19P2			0x02
+#define ATH3K_NAME_LEN				0xFF
+
+struct ath3k_version {
+	unsigned int	rom_version;
+	unsigned int	build_version;
+	unsigned int	ram_version;
+	unsigned char	ref_clock;
+	unsigned char	reserved[0x07];
+};
 
 static struct usb_device_id ath3k_table[] = {
 	/* Atheros AR3011 */
@@ -41,13 +65,29 @@ static struct usb_device_id ath3k_table[] = {
 
 	/* Atheros AR9285 Malbec with sflash firmware */
 	{ USB_DEVICE(0x03F0, 0x311D) },
+
+	/* Atheros AR3012 with sflash firmware*/
+	{ USB_DEVICE(0x0CF3, 0x3004) },
+
 	{ }	/* Terminating entry */
 };
 
 MODULE_DEVICE_TABLE(usb, ath3k_table);
 
+#define BTUSB_ATH3012		0x80
+/* This table is to load patch and sysconfig files
+ * for AR3012 */
+static struct usb_device_id ath3k_blist_tbl[] = {
+
+	/* Atheros AR3012 with sflash firmware*/
+	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
+
+	{ }	/* Terminating entry */
+};
+
 #define USB_REQ_DFU_DNLOAD	1
 #define BULK_SIZE		4096
+#define FW_HDR_SIZE		20
 
 static int ath3k_load_firmware(struct usb_device *udev,
 				const struct firmware *firmware)
@@ -103,6 +143,215 @@ error:
 	return err;
 }
 
+static int ath3k_get_state(struct usb_device *udev, unsigned char *state)
+{
+	int pipe = 0;
+
+	pipe = usb_rcvctrlpipe(udev, 0);
+	return usb_control_msg(udev, pipe, ATH3K_GETSTATE,
+			USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
+			state, 0x01, USB_CTRL_SET_TIMEOUT);
+}
+
+static int ath3k_get_version(struct usb_device *udev,
+			struct ath3k_version *version)
+{
+	int pipe = 0;
+
+	pipe = usb_rcvctrlpipe(udev, 0);
+	return usb_control_msg(udev, pipe, ATH3K_GETVERSION,
+			USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, version,
+			sizeof(struct ath3k_version),
+			USB_CTRL_SET_TIMEOUT);
+}
+
+static int ath3k_load_fwfile(struct usb_device *udev,
+		const struct firmware *firmware)
+{
+	u8 *send_buf;
+	int err, pipe, len, size, count, sent = 0;
+	int ret;
+
+	count = firmware->size;
+
+	send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
+	if (!send_buf) {
+		BT_ERR("Can't allocate memory chunk for firmware");
+		return -ENOMEM;
+	}
+
+	size = min_t(uint, count, FW_HDR_SIZE);
+	memcpy(send_buf, firmware->data, size);
+
+	pipe = usb_sndctrlpipe(udev, 0);
+	ret = usb_control_msg(udev, pipe, ATH3K_DNLOAD,
+			USB_TYPE_VENDOR, 0, 0, send_buf,
+			size, USB_CTRL_SET_TIMEOUT);
+	if (ret < 0) {
+		BT_ERR("Can't change to loading configuration err");
+		kfree(send_buf);
+		return ret;
+	}
+
+	sent += size;
+	count -= size;
+
+	while (count) {
+		size = min_t(uint, count, BULK_SIZE);
+		pipe = usb_sndbulkpipe(udev, 0x02);
+
+		memcpy(send_buf, firmware->data + sent, size);
+
+		err = usb_bulk_msg(udev, pipe, send_buf, size,
+					&len, 3000);
+		if (err || (len != size)) {
+			BT_ERR("Error in firmware loading err = %d,"
+				"len = %d, size = %d", err, len, size);
+			kfree(send_buf);
+			return err;
+		}
+		sent  += size;
+		count -= size;
+	}
+
+	kfree(send_buf);
+	return 0;
+}
+
+static int ath3k_switch_pid(struct usb_device *udev)
+{
+	int pipe = 0;
+
+	pipe = usb_sndctrlpipe(udev, 0);
+	return usb_control_msg(udev, pipe, USB_REG_SWITCH_VID_PID,
+			USB_TYPE_VENDOR, 0, 0,
+			NULL, 0, USB_CTRL_SET_TIMEOUT);
+}
+
+static int ath3k_set_normal_mode(struct usb_device *udev)
+{
+	unsigned char fw_state;
+	int pipe = 0, ret;
+
+	ret = ath3k_get_state(udev, &fw_state);
+	if (ret < 0) {
+		BT_ERR("Can't get state to change to normal mode err");
+		return ret;
+	}
+
+	if ((fw_state & ATH3K_MODE_MASK) == ATH3K_NORMAL_MODE) {
+		BT_DBG("firmware was already in normal mode");
+		return 0;
+	}
+
+	pipe = usb_sndctrlpipe(udev, 0);
+	return usb_control_msg(udev, pipe, ATH3K_SET_NORMAL_MODE,
+			USB_TYPE_VENDOR, 0, 0,
+			NULL, 0, USB_CTRL_SET_TIMEOUT);
+}
+
+static int ath3k_load_patch(struct usb_device *udev)
+{
+	unsigned char fw_state;
+	char filename[ATH3K_NAME_LEN] = {0};
+	const struct firmware *firmware;
+	struct ath3k_version fw_version, pt_version;
+	int ret;
+
+	ret = ath3k_get_state(udev, &fw_state);
+	if (ret < 0) {
+		BT_ERR("Can't get state to change to load ram patch err");
+		return ret;
+	}
+
+	if (fw_state & ATH3K_PATCH_UPDATE) {
+		BT_DBG("Patch was already downloaded");
+		return 0;
+	}
+
+	ret = ath3k_get_version(udev, &fw_version);
+	if (ret < 0) {
+		BT_ERR("Can't get version to change to load ram patch err");
+		return ret;
+	}
+
+	snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu",
+		fw_version.rom_version);
+
+	ret = request_firmware(&firmware, filename, &udev->dev);
+	if (ret < 0) {
+		BT_ERR("Patch file not found %s", filename);
+		return ret;
+	}
+
+	pt_version.rom_version = *(int *)(firmware->data + firmware->size - 8);
+	pt_version.build_version = *(int *)
+		(firmware->data + firmware->size - 4);
+
+	if ((pt_version.rom_version != fw_version.rom_version) ||
+		(pt_version.build_version <= fw_version.build_version)) {
+		BT_ERR("Patch file version did not match with firmware");
+		release_firmware(firmware);
+		return -EINVAL;
+	}
+
+	ret = ath3k_load_fwfile(udev, firmware);
+	release_firmware(firmware);
+
+	return ret;
+}
+
+static int ath3k_load_syscfg(struct usb_device *udev)
+{
+	unsigned char fw_state;
+	char filename[ATH3K_NAME_LEN] = {0};
+	const struct firmware *firmware;
+	struct ath3k_version fw_version;
+	int clk_value, ret;
+
+	ret = ath3k_get_state(udev, &fw_state);
+	if (ret < 0) {
+		BT_ERR("Can't get state to change to load configration err");
+		return -EBUSY;
+	}
+
+	ret = ath3k_get_version(udev, &fw_version);
+	if (ret < 0) {
+		BT_ERR("Can't get version to change to load ram patch err");
+		return ret;
+	}
+
+	switch (fw_version.ref_clock) {
+
+	case ATH3K_XTAL_FREQ_26M:
+		clk_value = 26;
+		break;
+	case ATH3K_XTAL_FREQ_40M:
+		clk_value = 40;
+		break;
+	case ATH3K_XTAL_FREQ_19P2:
+		clk_value = 19;
+		break;
+	default:
+		clk_value = 0;
+		break;
+	}
+
+	snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s",
+		fw_version.rom_version, clk_value, ".dfu");
+
+	ret = request_firmware(&firmware, filename, &udev->dev);
+	if (ret < 0) {
+		BT_ERR("Configuration file not found %s", filename);
+		return ret;
+	}
+
+	ret = ath3k_load_fwfile(udev, firmware);
+	release_firmware(firmware);
+
+	return ret;
+}
+
 static int ath3k_probe(struct usb_interface *intf,
 			const struct usb_device_id *id)
 {
@@ -115,7 +364,37 @@ static int ath3k_probe(struct usb_interface *intf,
 	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
 		return -ENODEV;
 
+	/* match device ID in ath3k blacklist table */
+	if (!id->driver_info) {
+		const struct usb_device_id *match;
+		match = usb_match_id(intf, ath3k_blist_tbl);
+		if (match)
+			id = match;
+	}
+
+	/* load patch and sysconfig files for AR3012 */
+	if (id->driver_info & BTUSB_ATH3012) {
+		ret = ath3k_load_patch(udev);
+		if (ret < 0) {
+			BT_ERR("Loading patch file failed");
+			return ret;
+		}
+		ret = ath3k_load_syscfg(udev);
+		if (ret < 0) {
+			BT_ERR("Loading sysconfig file failed");
+			return ret;
+		}
+		ret = ath3k_set_normal_mode(udev);
+		if (ret < 0) {
+			BT_ERR("Set normal mode failed");
+			return ret;
+		}
+		ath3k_switch_pid(udev);
+		return 0;
+	}
+
 	if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) {
+		BT_ERR("Error loading firmware");
 		return -EIO;
 	}
 
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 4cefa91..fa84109 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -105,6 +105,9 @@ static struct usb_device_id blacklist_table[] = {
 	/* Atheros AR9285 Malbec with sflash firmware */
 	{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
 
+	/* Atheros 3012 with sflash firmware */
+	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_IGNORE },
+
 	/* Broadcom BCM2035 */
 	{ USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
 	{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
-- 
1.6.3.3


^ permalink raw reply related

* Re: [PATCH] Bluetooth: Add firmware support for Atheros 3012
From: Bala Shanmugam @ 2011-02-11  7:23 UTC (permalink / raw)
  To: Gustavo F. Padovan
  Cc: Shanmugamkamatchi Balashanmugam, linux-bluetooth@vger.kernel.org
In-Reply-To: <20110210172611.GA20033@joana>

Hi Padovan,

On 2/10/2011 10:56 PM, Gustavo F. Padovan wrote:
> Hi Bala,
>
> * Bala Shanmugam<sbalashanmugam@atheros.com>  [2011-02-09 17:45:15 +0530]:
>
>> Blacklisted AR3012 PID in btusb and added the same
>> in ath3k to load patch and sysconfig files.
>>
>> Signed-off-by: Bala Shanmugam<sbalashanmugam@atheros.com>
>> ---
>>   drivers/bluetooth/ath3k.c |  326 ++++++++++++++++++++++++++++++++++++++++++++-
>>   drivers/bluetooth/btusb.c |    3 +
>>   2 files changed, 325 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
>> index 41dadac..37e7cb4 100644
>> --- a/drivers/bluetooth/ath3k.c
>> +++ b/drivers/bluetooth/ath3k.c
>> @@ -31,6 +31,33 @@
>>
>>   #define VERSION "1.0"
>>
>> +#define ATH3K_DNLOAD				0x01
>> +#define ATH3K_GETSTATE				0x05
>> +#define ATH3K_SET_NORMAL_MODE			0x07
>> +#define ATH3K_SET_PREBOOT_MODE			0x08
>> +#define ATH3K_GETVERSION			0x09
>> +#define USB_REG_SWITCH_VID_PID			0x0a
>> +
>> +#define ATH3K_MODE_MASK				0x3F
>> +#define ATH3K_NORMAL_MODE			0x0E
>> +#define ATH3K_PREBOOT_MODE			0x0D
>> +
>> +#define ATH3K_UPDATE_MASK			0xC0
>> +#define ATH3K_PATCH_UPDATE			0x80
>> +#define ATH3K_SYSCFG_UPDATE			0x40
>> +
>> +#define ATH3K_XTAL_FREQ_26M			0x00
>> +#define ATH3K_XTAL_FREQ_40M			0x01
>> +#define ATH3K_XTAL_FREQ_19P2			0x02
>> +#define ATH3K_NAME_LEN				0xFF
> There is some macros here that you are not using in the code.
For time being we don't support switching to preboot boot mode, so I didn't
use some macros.  I will remove it now and add it when required.
>> +
>> +struct ath3k_version {
>> +	unsigned int	rom_version;
>> +	unsigned int	build_version;
>> +	unsigned int	ram_version;
>> +	unsigned char	ref_clock;
>> +	unsigned char	reserved[0x07];
>> +};
>>
>>   static struct usb_device_id ath3k_table[] = {
>>   	/* Atheros AR3011 */
>> @@ -41,13 +68,29 @@ static struct usb_device_id ath3k_table[] = {
>>
>>   	/* Atheros AR9285 Malbec with sflash firmware */
>>   	{ USB_DEVICE(0x03F0, 0x311D) },
>> +
>> +	/* Atheros AR3012 with sflash firmware*/
>> +	{ USB_DEVICE(0x0CF3, 0x3004) },
>> +
>>   	{ }	/* Terminating entry */
>>   };
>>
>>   MODULE_DEVICE_TABLE(usb, ath3k_table);
>>
>> +#define BTUSB_ATH3012		0x80
>> +/* This table is to load patch and sysconfig files
>> + * for AR3012 */
>> +static struct usb_device_id ath3k_blist_tbl[] = {
>> +
>> +	/* Atheros AR3012 with sflash firmware*/
>> +	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
>> +
>> +	{ }	/* Terminating entry */
>> +};
>> +
>>   #define USB_REQ_DFU_DNLOAD	1
>>   #define BULK_SIZE		4096
>> +#define FW_HDR_SIZE		20
>>
>>   static int ath3k_load_firmware(struct usb_device *udev,
>>   				const struct firmware *firmware)
>> @@ -67,10 +110,10 @@ static int ath3k_load_firmware(struct usb_device *udev,
>>   	}
>>
>>   	memcpy(send_buf, firmware->data, 20);
>> -	if ((err = usb_control_msg(udev, pipe,
>> -				USB_REQ_DFU_DNLOAD,
>> -				USB_TYPE_VENDOR, 0, 0,
>> -				send_buf, 20, USB_CTRL_SET_TIMEOUT))<  0) {
>> +	err = usb_control_msg(udev, pipe, USB_REQ_DFU_DNLOAD,
>> +			USB_TYPE_VENDOR, 0, 0,
>> +			send_buf, 20, USB_CTRL_SET_TIMEOUT);
>> +	if (err<  0) {
>>   		BT_ERR("Can't change to loading configuration err");
>>   		goto error;
>
> Please send a separate patch for code styling fixes.
Sure. Thanks.
>>   	}
>> @@ -103,6 +146,255 @@ error:
>>   	return err;
>>   }
>>
>> +static int ath3k_get_state(struct usb_device *udev, unsigned char *state)
>> +{
>> +	int pipe = 0, ret;
>> +
>> +	pipe = usb_rcvctrlpipe(udev, 0);
>> +	ret = usb_control_msg(udev, pipe, ATH3K_GETSTATE,
>> +			USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
>> +			state, 0x01, USB_CTRL_SET_TIMEOUT);
>> +	return ret;
>
> return usb_control_msg(); and get rid of ret.
Sure. Thanks.
>> +}
>> +
>> +static int ath3k_get_version(struct usb_device *udev,
>> +			struct ath3k_version *version)
>> +{
>> +	int pipe = 0, ret;
>> +
>> +	pipe = usb_rcvctrlpipe(udev, 0);
>> +	ret = usb_control_msg(udev, pipe, ATH3K_GETVERSION,
>> +			USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, version,
>> +			sizeof(struct ath3k_version),
>> +			USB_CTRL_SET_TIMEOUT);
>> +	return ret;
> Same as above.
>
>> +}
>> +
>> +static int ath3k_load_fwfile(struct usb_device *udev,
>> +		const struct firmware *firmware)
>> +{
>> +	u8 *send_buf;
>> +	int err, pipe, len, size, count, sent = 0;
>> +	int ret;
>> +
>> +	count = firmware->size;
>> +
>> +	send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
>> +	if (!send_buf) {
>> +		BT_ERR("Can't allocate memory chunk for firmware");
>> +		return -ENOMEM;
>> +	}
>> +
>> +	size = min_t(uint, count, FW_HDR_SIZE);
>> +	memcpy(send_buf, firmware->data, size);
>> +
>> +	pipe = usb_sndctrlpipe(udev, 0);
>> +	ret = usb_control_msg(udev, pipe, ATH3K_DNLOAD,
>> +			USB_TYPE_VENDOR, 0, 0, send_buf,
>> +			size, USB_CTRL_SET_TIMEOUT);
>> +	if (ret<  0) {
>> +		BT_ERR("Can't change to loading configuration err");
>> +		kfree(send_buf);
>> +		return ret;
>> +	}
>> +
>> +	sent += size;
>> +	count -= size;
>> +
>> +	while (count) {
>> +		size = min_t(uint, count, BULK_SIZE);
>> +		pipe = usb_sndbulkpipe(udev, 0x02);
>> +
>> +		memcpy(send_buf, firmware->data + sent, size);
>> +
>> +		err = usb_bulk_msg(udev, pipe, send_buf, size,
>> +					&len, 3000);
>> +		if (err || (len != size)) {
>> +			BT_ERR("Error in firmware loading err = %d,"
>> +				"len = %d, size = %d", err, len, size);
>> +			kfree(send_buf);
>> +			return err;
>> +		}
>> +		sent  += size;
>> +		count -= size;
>> +	}
>> +
>> +	kfree(send_buf);
>> +	return 0;
>> +}
>> +
>> +static int ath3k_switch_pid(struct usb_device *udev)
>> +{
>> +	int pipe = 0, ret;
>> +
>> +	pipe = usb_sndctrlpipe(udev, 0);
>> +	ret = usb_control_msg(udev, pipe, USB_REG_SWITCH_VID_PID,
>> +			USB_TYPE_VENDOR, 0, 0,
>> +			NULL, 0, USB_CTRL_SET_TIMEOUT);
>> +	return ret;
>> +}
>> +
>> +static int ath3k_set_normal_mode(struct usb_device *udev)
>> +{
>> +	unsigned char fw_state;
>> +	int pipe = 0, ret;
>> +
>> +	ret = ath3k_get_state(udev,&fw_state);
>> +	if (ret<  0) {
>> +		BT_ERR("Can't get state to change to normal mode err");
>> +		return ret;
>> +	}
>> +
>> +	if ((fw_state&  ATH3K_MODE_MASK) == ATH3K_NORMAL_MODE) {
>> +		BT_DBG("firmware was already in normal mode");
>> +		return 0;
>> +	}
>> +
>> +	pipe = usb_sndctrlpipe(udev, 0);
>> +	ret = usb_control_msg(udev, pipe, ATH3K_SET_NORMAL_MODE,
>> +			USB_TYPE_VENDOR, 0, 0,
>> +			NULL, 0, USB_CTRL_SET_TIMEOUT);
> Use return usb_control_msg(); here as well.
>
>> +	if (ret<  0)
>> +		BT_ERR("Can't set normal mode err");
>> +
>> +	return ret;
>> +}
>> +
>> +static int ath3k_load_patch(struct usb_device *udev)
>> +{
>> +	unsigned char fw_state;
>> +	char filename[ATH3K_NAME_LEN] = {0};
>> +	const struct firmware *firmware;
>> +	struct ath3k_version fw_version, pt_version;
>> +	int delay = 0, ret;
>> +
>> +	ret = ath3k_get_state(udev,&fw_state);
>> +	if (ret<  0) {
>> +		BT_ERR("Can't get state to change to load ram patch err");
>> +		return ret;
>> +	}
>> +
>> +	if (fw_state&  ATH3K_PATCH_UPDATE) {
>> +		BT_DBG("Patch was already downloaded");
>> +		return 0;
>> +	}
>> +
>> +	ret = ath3k_get_version(udev,&fw_version);
>> +	if (ret<  0) {
>> +		BT_ERR("Can't get version to change to load ram patch err");
>> +		return ret;
>> +	}
>> +
>> +	snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu",
>> +		fw_version.rom_version);
>> +
>> +	ret = request_firmware(&firmware, filename,&udev->dev);
>> +	if (ret<  0) {
>> +		BT_ERR("Patch file not found %s", filename);
>> +		return ret;
>> +	}
>> +
>> +	pt_version.rom_version = *(int *)(firmware->data + firmware->size - 8);
>> +	pt_version.build_version = *(int *)
>> +		(firmware->data + firmware->size - 4);
>> +
>> +	if ((pt_version.rom_version != fw_version.rom_version) ||
>> +		(pt_version.build_version<= fw_version.build_version)) {
>> +		BT_ERR("Patch file version did not match with firmware");
>> +		release_firmware(firmware);
>> +		return -EINVAL;
>> +	}
>> +
>> +	ret = ath3k_load_fwfile(udev, firmware);
>> +	if (ret<  0) {
>> +		BT_ERR("Patch loading failed - %s", filename);
>> +		release_firmware(firmware);
>> +		return ret;
>> +	}
>> +
>> +	release_firmware(firmware);
>> +
>> +	do {
>> +		ret = ath3k_get_state(udev,&fw_state);
>> +		if (ret<  0)
>> +			continue;
>> +
>> +		if (fw_state&  ATH3K_PATCH_UPDATE) {
>> +			BT_DBG("Patch has been downloaded successfully");
>> +			break;
>> +		}
>> +		delay++;
>> +	} while (delay<  3);
>> +
>> +	return 0;
>> +}
>> +
>> +static int ath3k_load_syscfg(struct usb_device *udev)
>> +{
>> +	unsigned char fw_state;
>> +	char filename[ATH3K_NAME_LEN] = {0};
>> +	const struct firmware *firmware;
>> +	struct ath3k_version fw_version;
>> +	int clk_value, delay = 0, ret;
>> +
>> +	if (ath3k_get_state(udev,&fw_state)<  0) {
>> +		BT_ERR("Can't get state to change to load configration err");
>> +		return -EBUSY;
>> +	}
>> +
>> +	ret = ath3k_get_version(udev,&fw_version);
>> +	if (ret<  0) {
>> +		BT_ERR("Can't get version to change to load ram patch err");
>> +		return ret;
>> +	}
>> +
>> +	switch (fw_version.ref_clock) {
>> +
>> +	case ATH3K_XTAL_FREQ_26M:
>> +		clk_value = 26;
>> +		break;
>> +	case ATH3K_XTAL_FREQ_40M:
>> +		clk_value = 40;
>> +		break;
>> +	case ATH3K_XTAL_FREQ_19P2:
>> +		clk_value = 19;
>> +		break;
>> +	default:
>> +		clk_value = 0;
>> +		break;
>> +	}
>> +
>> +	snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s",
>> +		fw_version.rom_version, clk_value, ".dfu");
>> +
>> +	ret = request_firmware(&firmware, filename,&udev->dev);
>> +	if (ret<  0) {
>> +		BT_ERR("Configuration file not found %s", filename);
>> +		return ret;
>> +	}
>> +
>> +	ret = ath3k_load_fwfile(udev, firmware);
>> +	if (ret<  0) {
>> +		BT_ERR("Configuration loading failed - %s", filename);
>> +		release_firmware(firmware);
>> +		return ret;
>> +	}
>> +
>> +	release_firmware(firmware);
> 	ret = ath3k_load_fwfile()
> 	release_firmware()
> 	if (ret<  0)
> 		return ret;
>
>> +
>> +	do {
>> +		ret = ath3k_get_state(udev,&fw_state);
>> +		if (ret<  0)
>> +			continue;
> Can this became a infinite loop? if ath3k_get_state() always return ret<  0.
>
If the firmware download is successful, ath3k_get_state should not 
return err.
We basically want to wait until the firmware state is updated.
I tested now and firmware state is updated immediately after download and
wait is not required I believe.
Thanks for pointing it out.
I will send updated patch incorporating all your comments.

Best Regards,
Bala.




^ permalink raw reply

* [HACK PATCH] N900 l2cap connect crash, NULL parent
From: David Fries @ 2011-02-11  3:53 UTC (permalink / raw)
  To: linux-bluetooth

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

Here's a patch to avoid a very repeatable crash in the N900.  If I
take a Motorola S305 bluetooth headset that was previously paried with
the N900, turn it on, and press the play button before the headphones
automatically pair with the cell phone, the N900 will crash (and
reboot) in pairing.  If I wait until after they have paired there
isn't any problem.  The patch is against the kernel-power
2.6.28-maemo46 by Thomas Tanner, the stock Nokia PR1.2 oops looked
the same, I just haven't gone back to that kernel.

All of the original oops dumps had the same backtrace functions,
(see original.txt for the full oops)

Backtrace: 
l2cap_load+0x7e8/0xa94 [l2cap]
l2cap_sock_destruct+0x124/0x1484 [l2cap]
l2cap_recv_acldata+0x0/0x1f0 [l2cap]
hci_rx_task+0x0/0x298 [bluetooth]
tasklet_action+0x0/0xc0
__do_softirq+0x0/0xf4
irq_exit+0x0/0xa8

I first cherry picked the kernel patch by Andrei Emeltchenko
e501d0553a7580fcc6654d7f58a5f061d31d00af
"Bluetooth: Check L2CAP pending status before sending connect request"

It was still crashing, but the backtrace changed,
(see pending_protect.txt for the full oops)

Backtrace: 
l2cap_conn_start+0x0/0x2ac [l2cap]
l2cap_recv_frame+0x0/0x12bc [l2cap]
l2cap_recv_acldata+0x0/0x1f0 [l2cap]
hci_rx_task+0x0/0x298 [bluetooth]
tasklet_action+0x0/0xc0
__do_softirq+0x0/0xf4
irq_exit+0x0/0xa8

Then I added the following patch to protected against a NULL parent,
and it no longer crashes.  I'm not sure what to think about the above
"pending status" patch, I added a check and the
__l2cap_no_conn_pending function added by that patch never sees a
pending connection, but it did change the backtrace, so I'm confused.
But then again the original trace lists l2cap_load, which only
contains a return statement, and shouldn't be prone to making NULL
pointer dereferences anyawy.

I also attached two syslogs, one with out touching the headset while
it powered on and paired,
cut_no_press.txt

and another with pressing the button before it paired.  This one
prints the debug message instead of the crash that would have
happened.
avoided crash in l2cap_conn_start parent 00000000 result 1 status 2
cut_with_press.txt


There's also a patch on android.git.kernel.org
"Bluetooth: Hack: Don't dereference null pointer."
http://android.git.kernel.org/?p=kernel/common.git;a=commit;h=5a2ad658a5efea775a00b162c1062ce33e8e3aaa

and a bug report on bugs.maemo.org
https://bugs.maemo.org/show_bug.cgi?id=10510


Subject: [PATCH] work around for l2cap NULL dereference in l2cap_conn_start

just skip the dereference, print sk
---
 net/bluetooth/l2cap.c |   11 ++++++++++-
 1 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index ed83c1f..c5b4fbf 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -408,7 +408,16 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
 					struct sock *parent = bt_sk(sk)->parent;
 					rsp.result = cpu_to_le16(L2CAP_CR_PEND);
 					rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
-					parent->sk_data_ready(parent, 0);
+					if(!parent) {
+						printk(KERN_DEBUG "avoided "
+							"crash in %s sk %p "
+							"result %d status %d\n",
+							__func__, sk,
+							rsp.result, rsp.status);
+					} else {
+						parent->sk_data_ready(parent,
+							0);
+					}
 
 				} else {
 					sk->sk_state = BT_CONFIG;
-- 
1.7.2.3


[-- Attachment #2: original.txt --]
[-- Type: text/plain, Size: 9114 bytes --]

Log Entry 23 (at position 22)
[43998.551239] Unable to handle kernel NULL pointer dereference at virtual address 00000144
[43998.551300] pgd = ccb24000
[43998.551330] [00000144] *pgd=8cb0d031, *pte=00000000, *ppte=00000000
[43998.551391] Internal error: Oops: 17 [#1] PREEMPT
[43998.551422] Modules linked in: sd_mod scsi_mod iphb rfcomm panic_info_buff sco l2cap ext3 jbd omaplfb ext4 mbcache pvrsrvkm jbd2 bridgedriver ipv6 g_file_storage uinput board_rx51_camera omap_previewer_hack omap34xxcam_mod isp_mod iovmm videobuf_dma_sg videobuf_core omap3_iommu iommu2 iommu dspbridge ssi_mcsaab_imp phonet mmc_block cmt_speech joydev omap_hsmmc wl12xx smc91x mii omap_ssi hci_h4p omap_wdt mac80211 crc7 nokia_av mmc_core tsc2005 bluetooth fmtx_si4713 videodev ad5820 adp1653 smia_sensor et8ek8 rtc_twl4030 smiaregs v4l1_compat compat_ioctl32 leds_lp5523 leds_twl4030_vibra lis302dl twl4030_wdt tsl2563 v4l2_int_device led_class rtc_core
[43998.552001] CPU: 0    Not tainted  (2.6.28.10power46 #1)
[43998.552062] PC is at l2cap_load+0x9ec/0xa94 [l2cap]
[43998.552185] LR is at hci_conn_security+0x50/0xc8 [bluetooth]
[43998.552215] pc : [<bf2cdb28>]    lr : [<bf07bc2c>]    psr: 20000153
[43998.552246] sp : cc89bb30  ip : cc89bb10  fp : cc89bb5c
[43998.552276] r10: 00000000  r9 : c4e7c814  r8 : c6c05100
[43998.552307] r7 : c6c05100  r6 : cc89a000  r5 : c263aa00  r4 : 00000000
[43998.552337] r3 : 00000000  r2 : 00000002  r1 : 00000000  r0 : 00000000
[43998.552368] Flags: nzCv  IRQs on  FIQs off  Mode SVC_32  ISA ARM  Segment user
[43998.552429] Control: 10c5387d  Table: 8cb24018  DAC: 00000015
[43998.552459] Process bluetoothd (pid: 945, stack limit = 0xcc89a2e8)
[43998.552490] Stack: (0xcc89bb30 to 0xcc89c000)
[43998.552520] bb20:                                     00000001 c03a1b40 00400041 00020001 
[43998.552581] bb40: 00000000 00000002 c4e7c810 cc89a000 cc89bc7c cc89bb60 bf2cf14c bf2cd930 
[43998.552673] bb60: cc89a000 c0062170 cc89bb84 c2597c00 c0052f90 00000008 cc89bb94 cc89bb88 
[43998.552764] bb80: c0062180 00000008 cc89bbcc cc89bb98 c0061e38 c006217c cfe3dc84 00000000 
[43998.552856] bba0: cc89bba0 cc89bba0 00000025 00000102 cc89a000 c03b3080 00000102 cc89a000 
[43998.552947] bbc0: cc89bbfc cc89bbd0 c005cd48 c005cbcc c03817cc 00000025 00000025 00000000 
[43998.553039] bbe0: 00000001 00000001 00000000 c6ddcb4d cc89bc14 cc89bc00 c005d0f8 c004f8ac 
[43998.553100] bc00: 00000025 00000000 cc89bc2c cc89bc18 c002c088 c005d094 c269a07c c269a07c 
[43998.553192] bc20: cfc92000 fffff010 cc89bc64 cc89bc38 c00623ec c0061a74 c81a17f3 a0000153 
[43998.553283] bc40: c81a174d c269a07c fffff010 0008020b 0000000b 00000010 c6c05100 c2597c00 
[43998.553375] bc60: 0000000b cc89a000 cc89a000 0000200b cc89bc9c cc89bc80 bf2d0930 bf2ce0f8 
[43998.553466] bc80: c269a000 c2597c00 cfc92000 0000000b cc89bcc4 cc89bca0 bf079b54 bf2d087c 
[43998.553527] bca0: 00000000 cc89a000 c03b3080 00000001 00000014 0000000a cc89bcdc cc89bcc8 
[43998.553619] bcc0: c005cef8 bf0799fc 00000102 cc89a000 cc89bd0c cc89bce0 c005cccc c005ce8c 
[43998.553710] bce0: c038203c 00000049 00000049 00000000 cee9fd60 00000001 00000000 cee9fd60 
[43998.553802] bd00: cc89bd24 cc89bd10 c005d0d4 c005cc74 00000049 00000000 cc89bd3c cc89bd28 
[43998.553894] bd20: c002c088 c005d094 ffffffff d8200000 cc89bda4 cc89bd40 c0299184 c002c00c 
[43998.553955] bd40: cee99ccc 00000002 00000000 00000000 c055a360 00000001 cee9fd60 c2597b40 
[43998.554046] bd60: cc89be28 c2597b88 cee9fd60 cc89bda4 00000000 cc89bd88 fffffffa c008e2c0 
[43998.554138] bd80: 60000153 ffffffff 0000168e cee9fd60 00000001 c2597b40 cc89bdc4 cc89bda8 
[43998.554229] bda0: c008e50c c008e214 0000168e 00000000 cc89a000 c2597b40 cc89be14 cc89bdc8 
[43998.554321] bdc0: c0090b24 c008e4f8 c00cc518 c0156de4 cee9fcc0 cc84ba50 cee9fcc0 00000000 
[43998.554382] bde0: 00000000 c00cc4f4 c055a2c0 00000000 ce5f1680 cc84ba50 cc84ba50 00000000 
[43998.554473] be00: 40026000 cd456480 cc89be64 cc89be18 c009ea7c c0090a6c ccb25000 00000000 
[43998.554565] be20: 00000000 cc983894 00000000 00000001 40026000 00000000 00000001 00000000 
[43998.554656] be40: ce5f1680 00001000 cc84ba50 000
Log Entry 24 (at position 23)
<7>mtdoops: Ready 23, 24 (no erase)
[43998.555419] ccb24000 40026000 cc89bec4 cc89be68 
[43998.555450] be60: c009fd68 c009ea34 00000001 00000000 00000000 cc89be80 c021b4c8 c021adb0 
[43998.555541] be80: 00000000 cd456480 cc89beac 00000098 ccb25000 c00b7b04 cfc921d8 cd4564b4 
[43998.555633] bea0: ce5f1680 cd456480 cc84ba50 cc89bfb0 00000017 40026000 cc89befc cc89bec8 
[43998.555725] bec0: c029b08c c009f9fc c0074e14 c0040740 ffffffff c029af20 c0372894 00000017 
[43998.555816] bee0: cc89bfb0 40026000 40025fb1 00000013 cc89bfac cc89bf00 c002c270 c029af2c 
[43998.555877] bf00: 00000000 00000000 cc89bf34 cc89bf18 bf079fd4 c0219fa0 00000000 cc89a000 
[43998.555969] bf20: c03b3080 00000001 cc89bf4c cc89bf38 c005cef8 bf079c94 00000102 cc89a000 
[43998.556060] bf40: cc89bf7c cc89bf50 c005cd48 c005cbcc c038203c 00000049 00000049 00000000 
[43998.556152] bf60: 400251f2 00000001 00000000 00000013 cc89bf94 cc89bf80 c005d0f8 c004f8ac 
[43998.556213] bf80: 00000049 00000000 cc89bfac ffffffff 40025fb0 40025f96 0000001a 00069700 
[43998.556304] bfa0: 00000000 cc89bfb0 c02995a0 c002c23c 00069700 40025fb0 00000000 00000030 
[43998.556396] bfc0: 40025fff 40025fb0 40025f96 0000001a 00069700 40025fb1 00000013 bea5ca54 
[43998.556488] bfe0: 0006971a bea5c9c0 0003b904 0003b924 20000050 ffffffff 805e2021 805e2421 
[43998.556579] Backtrace: 
[43998.556610] [<bf2cd924>] (l2cap_load+0x7e8/0xa94 [l2cap]) from [<bf2cf14c>] (l2cap_sock_destruct+0x1184/0x1484 [l2cap])
[43998.556701]  r7:cc89a000 r6:c4e7c810 r5:00000002 r4:00000000
[43998.556762] [<bf2ce0ec>] (l2cap_sock_destruct+0x124/0x1484 [l2cap]) from [<bf2d0930>] (l2cap_recv_acldata+0xc0/0x1f0 [l2cap])
[43998.556854] [<bf2d0870>] (l2cap_recv_acldata+0x0/0x1f0 [l2cap]) from [<bf079b54>] (hci_rx_task+0x164/0x298 [bluetooth])
[43998.557006]  r7:0000000b r6:cfc92000 r5:c2597c00 r4:c269a000
[43998.557067] [<bf0799f0>] (hci_rx_task+0x0/0x298 [bluetooth]) from [<c005cef8>] (tasklet_action+0x78/0xc0)
[43998.557220] [<c005ce80>] (tasklet_action+0x0/0xc0) from [<c005cccc>] (__do_softirq+0x64/0xf4)
[43998.557281]  r5:cc89a000 r4:00000102
[43998.557312] [<c005cc68>] (__do_softirq+0x0/0xf4) from [<c005d0d4>] (irq_exit+0x4c/0xa8)
[43998.557403] [<c005d088>] (irq_exit+0x0/0xa8) from [<c002c088>] (__exception_text_start+0x88/0xa8)
[43998.557464]  r5:00000000 r4:00000049
[43998.557495] [<c002c000>] (__exception_text_start+0x0/0xa8) from [<c0299184>] (__irq_svc+0x44/0xa4)
[43998.557586] Exception stack(0xcc89bd40 to 0xcc89bd88)
[43998.557617] bd40: cee99ccc 00000002 00000000 00000000 c055a360 00000001 cee9fd60 c2597b40 
[43998.557708] bd60: cc89be28 c2597b88 cee9fd60 cc89bda4 00000000 cc89bd88 fffffffa c008e2c0 
[43998.557800] bd80: 60000153 ffffffff                                                       
[43998.557861]  r5:d8200000 r4:ffffffff
[43998.557922] [<c008e208>] (find_get_page+0x0/0xc0) from [<c008e50c>] (find_lock_page+0x20/0x74)
[43998.558013]  r7:c2597b40 r6:00000001 r5:cee9fd60 r4:0000168e
[43998.558074] [<c008e4ec>] (find_lock_page+0x0/0x74) from [<c0090b24>] (filemap_fault+0xc4/0x454)
[43998.558135]  r7:c2597b40 r6:cc89a000 r5:00000000 r4:0000168e
[43998.558197] [<c0090a60>] (filemap_fault+0x0/0x454) from [<c009ea7c>] (__do_fault+0x54/0x4a8)
[43998.558258] [<c009ea28>] (__do_fault+0x0/0x4a8) from [<c009fd68>] (handle_mm_fault+0x378/0x864)
[43998.558349] [<c009f9f0>] (handle_mm_fault+0x0/0x864) from [<c029b08c>] (do_page_fault+0x16c/0x2c0)
[43998.558410] [<c029af20>] (do_page_fault+0x0/0x2c0) from [<c002c270>] (do_DataAbort+0x40/0xa0)
[43998.558502] [<c002c230>] (do_DataAbort+0x0/0xa0) from [<c02995a0>] (ret_from_exception+0x0/0x10)
[43998.558593] Exception stack(0xcc89bfb0 to 0xcc89bff8)
[43998.558593] bfa0:                                     00069700 40025fb0 00000000 00000030 
[43998.558685] bfc0: 40025fff 40025fb0 40025f96 0000001a 00069700 40025fb1 00000013 bea5ca54 
[43998.558776] bfe0: 0006971a bea5c9c0 0003b904 0003b924 20000050 ffffffff                   
[43998.558868]  r8:00069700 r7:0000001a r6:40025f96 r5:40025fb0 r4:ffffffff
[43998.558929] Code: e14b22b0 e1a00003 e3a02002 e14b21b
Log Entry 25 (at position 24)
<7>mtdoops: Ready 24, 25 (no erase)
[43998.559661] (e5933144) 

Log Entry 26 (at position 25)
[43998.560180] mtdoops: Ready 25, 26 (no erase)
[43998.560363] Kernel panic - not syncing: Fatal exception in interrupt
[43998.560394] Panic info buffer:
[43998.560424] OSSO_PRODUCT_HARDWARE='RX-51'
[43998.560455] OSSO_PRODUCT_NAME='N900'
[43998.560455] OSSO_PRODUCT_FULL_NAME='Nokia N900'
[43998.560485] OSSO_PRODUCT_RELEASE_NAME='Maemo 5'
[43998.560485] OSSO_PRODUCT_RELEASE_FULL_NAME='Maemo 5'
[43998.560516] OSSO_PRODUCT_RELEASE_VERSION='20.2010.36-2.002'
[43998.560516] OSSO_PRODUCT_WLAN_CHANNEL='fcc/us'
[43998.560546] OSSO_PRODUCT_KEYBOARD='English, Dutch'
[43998.560546] OSSO_PRODUCT_REGION='English America'
[43998.560577] OSSO_PRODUCT_SHORT_NAME='Nokia N900'
[43998.560577] OSSO_VERSION='RX-51_2009SE_20.2010.36-2.002_PR_002'
[43998.560607] 

[-- Attachment #3: pending_protect.txt --]
[-- Type: text/plain, Size: 5802 bytes --]

Log Entry 27 (at position 26)
[  216.312866] Unable to handle kernel NULL pointer dereference at virtual address 00000144
[  216.312927] pgd = ce50c000
[  216.312957] [00000144] *pgd=00000000
[  216.313018] Internal error: Oops: 5 [#1] PREEMPT
[  216.313018] Modules linked in: sd_mod scsi_mod iphb rfcomm panic_info_buff sco l2cap ext3 jbd ext4 mbcache omaplfb jbd2 pvrsrvkm bridgedriver ipv6 g_file_storage uinput board_rx51_camera omap_previewer_hack omap34xxcam_mod isp_mod iovmm videobuf_dma_sg videobuf_core omap3_iommu iommu2 iommu dspbridge ssi_mcsaab_imp mmc_block phonet joydev cmt_speech omap_hsmmc wl12xx smc91x mii omap_ssi omap_wdt hci_h4p nokia_av mmc_core mac80211 crc7 tsc2005 bluetooth fmtx_si4713 rtc_twl4030 et8ek8 ad5820 adp1653 smia_sensor lis302dl leds_lp5523 leds_twl4030_vibra rtc_core twl4030_wdt videodev v4l1_compat compat_ioctl32 tsl2563 led_class smiaregs v4l2_int_device
[  216.313598] CPU: 0    Not tainted  (2.6.28.10power46 #1)
[  216.313690] PC is at l2cap_conn_start+0x204/0x2ac [l2cap]
[  216.313812] LR is at hci_conn_security+0x50/0xc8 [bluetooth]
[  216.313842] pc : [<bf2cdb28>]    lr : [<bf07bc2c>]    psr: 20000153
[  216.313873] sp : ce53bda0  ip : ce53bd80  fp : ce53bdcc
[  216.313903] r10: 00000000  r9 : c5522814  r8 : cff6e500
[  216.313934] r7 : cff6e500  r6 : ce53a000  r5 : c5657400  r4 : 00000000
[  216.313995] r3 : 00000000  r2 : 00000002  r1 : 00000000  r0 : 00000000
[  216.314025] Flags: nzCv  IRQs on  FIQs off  Mode SVC_32  ISA ARM  Segment user
[  216.314056] Control: 10c5387d  Table: 8e50c018  DAC: 00000015
[  216.314086] Process dbus-daemon (pid: 735, stack limit = 0xce53a2e8)
[  216.314117] Stack: (0xce53bda0 to 0xce53c000)
[  216.314147] bda0: 00000800 cee57d80 00410040 00020001 00000000 00000002 c5522810 ce53a000 
[  216.314239] bdc0: ce53beec ce53bdd0 bf2cf14c bf2cd930 cfeba3c0 00000000 00000000 cfc65840 
[  216.314331] bde0: 00000000 00000008 00000000 ce53be40 ce53be90 00000008 00000800 00000001 
[  216.314422] be00: ce53a000 ce53bf20 ce53be84 ce53be18 c0213cc0 c028401c 00000040 cc9ab0c0 
[  216.314483] be20: 00000000 cfeba3c0 00000040 00000800 cee57d80 cee2e19c ce53bdd4 ce53be40 
[  216.314575] be40: 00000000 00000000 ce53bf20 00000001 00000000 00000000 00000040 ce53be90 
[  216.314666] be60: ce53be90 cd7ceb40 ce53bf70 00000800 2a07c490 00000000 ce53bf44 ce53be88 
[  216.314758] be80: c00bb8c4 c0213be8 c553687c c553687c cfccdc00 ffffd80d ce53bed4 ce53bea8 
[  216.314849] bea0: c00623ec c0061a74 00000000 a0000153 00000000 c553687c ffffd80d 0008020b 
[  216.314910] bec0: 0000000b 00000010 cff6e500 cfc65840 0000000b ce53a000 ce53a000 0000200b 
[  216.315002] bee0: ce53bf0c ce53bef0 bf2d0930 bf2ce0f8 c5536800 cfc65840 cfccdc00 0000000b 
[  216.315093] bf00: ce53bf34 ce53bf10 bf079b54 bf2d087c 00000000 ce53a000 c03b3080 00000001 
[  216.315185] bf20: 00000014 0000000a ce53bf4c ce53bf38 c005cef8 bf0799fc 00000102 ce53a000 
[  216.315277] bf40: ce53bf7c ce53bf50 c005cccc c005ce8c c038203c 00000049 00000049 00000000 
[  216.315338] bf60: 2a07eb80 00000001 00000000 2a156350 ce53bf94 ce53bf80 c005d0d4 c005cc74 
[  216.315429] bf80: 00000049 00000000 ce53bfac ce53bf98 c002c088 c005d094 ffffffff d8200000 
[  216.315521] bfa0: 00000000 ce53bfb0 c0299384 c002c00c 2a07eb80 00000003 00000003 00000024 
[  216.315612] bfc0: 00000000 2a07eb80 2a07eb80 2a041000 2a07eca0 00000001 2a156350 befee8ec 
[  216.315673] bfe0: 00000371 befee8a0 2a017ce4 2a016608 20000050 ffffffff fd7ff5ff 7753f4f7 
[  216.315765] Backtrace: 
[  216.315795] [<bf2cd924>] (l2cap_conn_start+0x0/0x2ac [l2cap]) from [<bf2cf14c>] (l2cap_recv_frame+0x1060/0x12bc [l2cap])
[  216.315948]  r7:ce53a000 r6:c5522810 r5:00000002 r4:00000000
[  216.315979] [<bf2ce0ec>] (l2cap_recv_frame+0x0/0x12bc [l2cap]) from [<bf2d0930>] (l2cap_recv_acldata+0xc0/0x1f0 [l2cap])
[  216.316131] [<bf2d0870>] (l2cap_recv_acldata+0x0/0x1f0 [l2cap]) from [<bf079b54>] (hci_rx_task+0x164/0x298 [bluetooth])
[  216.316284]  r7:0000000b r6:cfccdc00 r5:cfc65840 r4:c5536800
[  216.316314] [<bf0799f0>] (hci_rx_task+0x0/0x298 [bluetooth]) from [<c005cef8>] (tasklet_action+0x78/0xc0)
[  216.317230] (tasklet_action+0x0/0xc0) from [<c005cccc>] (__do_softirq+0x64/0xf4)
[  216.317291]  r5:ce53a000 r4:00000102
[  216.317321] [<c005cc68>] (__do_softirq+0x0/0xf4) from [<c005d0d4>] (irq_exit+0x4c/0xa8)
[  216.317382] [<c005d088>] (irq_exit+0x0/0xa8) from [<c002c088>] (__exception_text_start+0x88/0xa8)
[  216.317474]  r5:00000000 r4:00000049
[  216.317504] [<c002c000>] (__exception_text_start+0x0/0xa8) from [<c0299384>] (__irq_usr+0x44/0xa0)
[  216.317596] Exception stack(0xce53bfb0 to 0xce53bff8)
[  216.317626] bfa0:                                     2a07eb80 00000003 00000003 00000024 
[  216.317718] bfc0: 00000000 2a07eb80 2a07eb80 2a041000 2a07eca0 00000001 2a156350 befee8ec 
[  216.317779] bfe0: 00000371 befee8a0 2a017ce4 2a016608 20000050 ffffffff                   
[  216.317871]  r5:d8200000 r4:ffffffff
[  216.317901] Code: e14b22b0 e1a00003 e3a02002 e14b21be (e5933144) 

Log Entry 29 (at position 28)
[  216.318481] mtdoops: Ready 28, 29 (no erase)
[  216.318542] Kernel panic - not syncing: Fatal exception in interrupt
[  216.318603] Panic info buffer:
[  216.318634] OSSO_PRODUCT_HARDWARE='RX-51'
[  216.318634] OSSO_PRODUCT_NAME='N900'
[  216.318664] OSSO_PRODUCT_FULL_NAME='Nokia N900'
[  216.318664] OSSO_PRODUCT_RELEASE_NAME='Maemo 5'
[  216.318695] OSSO_PRODUCT_RELEASE_FULL_NAME='Maemo 5'
[  216.318695] OSSO_PRODUCT_RELEASE_VERSION='20.2010.36-2.002'
[  216.318725] OSSO_PRODUCT_WLAN_CHANNEL='fcc/us'
[  216.318725] OSSO_PRODUCT_KEYBOARD='English, Dutch'
[  216.318756] OSSO_PRODUCT_REGION='English America'
[  216.318756] OSSO_PRODUCT_SHORT_NAME='Nokia N900'
[  216.318786] OSSO_VERSION='RX-51_2009SE_20.2010.36-2.002_PR_002'
[  216.318786] 

[-- Attachment #4: cut_no_press.txt --]
[-- Type: text/plain, Size: 43332 bytes --]

l2cap_connect_ind: hdev hci0, bdaddr 01:01:01:01:01:01
l2cap_connect_cfm: hcon cfe3a000 bdaddr 01:01:01:01:01:01 status 0
l2cap_conn_add: hcon cfe3a000 conn c9298700
l2cap_conn_ready: conn c9298700
bluetoothd[943]: link_key_request (sba=02:02:02:02:02:02, dba=03:03:03:03:03:03)
l2cap_security_cfm: conn c9298700
l2cap_recv_acldata: conn c9298700 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x02 len 4 id 0x02
l2cap_connect_req: psm 0x01 scid 0x0041
l2cap_sock_init: sk c74c2a00
__l2cap_chan_add: conn c9298700, psm 0x01, dcid 0x0041
l2cap_sock_set_timer: sk c74c2a00 state 2 timeout 5120
l2cap_build_cmd: conn c9298700, code 0x03, ident 0x02, len 8
l2cap_send_cmd: code 0x03
l2cap_build_cmd: conn c9298700, code 0x0a, ident 0x01, len 2
l2cap_send_cmd: code 0x0a
l2cap_recv_acldata: conn c9298700 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x02 len 4 id 0x03
l2cap_connect_req: psm 0x19 scid 0x0040
l2cap_sock_init: sk c74c2000
__l2cap_chan_add: conn c9298700, psm 0x19, dcid 0x0040
l2cap_sock_set_timer: sk c74c2000 state 2 timeout 5120
l2cap_build_cmd: conn c9298700, code 0x03, ident 0x03, len 8
l2cap_send_cmd: code 0x03
l2cap_build_cmd: conn c9298700, code 0x0a, ident 0x02, len 2
l2cap_send_cmd: code 0x0a
l2cap_recv_acldata: conn c9298700 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x0b len 8 id 0x01
l2cap_information_rsp: type 0x0002 result 0x00
l2cap_conn_start: conn c9298700
l2cap_build_cmd: conn c9298700, code 0x03, ident 0x03, len 8
l2cap_send_cmd: code 0x03
l2cap_build_cmd: conn c9298700, code 0x03, ident 0x02, len 8
l2cap_send_cmd: code 0x03
bluetoothd[943]: link_key_request (sba=02:02:02:02:02:02, dba=03:03:03:03:03:03)
l2cap_recv_acldata: conn c9298700 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x0b len 8 id 0x02
l2cap_information_rsp: type 0x0002 result 0x00
l2cap_conn_start: conn c9298700
l2cap_build_cmd: conn c9298700, code 0x03, ident 0x03, len 8
l2cap_send_cmd: code 0x03
l2cap_sock_accept: sk ce58be00 timeo 0
l2cap_sock_accept: new socket c74c2000
l2cap_sock_getsockopt: sk c74c2000
l2cap_sock_getsockopt_old: sk c74c2000
l2cap_sock_getname: sock c7184480, sk c74c2000
l2cap_sock_getname: sock c7184480, sk c74c2000
l2cap_security_cfm: conn c9298700
l2cap_build_cmd: conn c9298700, code 0x03, ident 0x03, len 8
l2cap_send_cmd: code 0x03
l2cap_recv_acldata: conn c9298700 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x04 len 8 id 0x04
l2cap_config_req: dcid 0x0040 flags 0x00
l2cap_parse_conf_req: sk c74c2a00
l2cap_get_conf_opt: type 0x01 len 2 val 0x30
l2cap_add_conf_opt: type 0x01 len 2 val 0x30
l2cap_build_cmd: conn c9298700, code 0x05, ident 0x04, len 10
l2cap_send_cmd: code 0x05
l2cap_build_conf_req: sk c74c2a00
l2cap_build_cmd: conn c9298700, code 0x04, ident 0x03, len 4
l2cap_send_cmd: code 0x04
l2cap_recv_acldata: conn c9298700 len 14 flags 0x2
l2cap_recv_frame: len 10, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x05 len 6 id 0x03
l2cap_config_rsp: scid 0x0040 flags 0x00 result 0x00
l2cap_chan_ready: sk c74c2a00, parent cd560400
l2cap_sock_clear_timer: sock c74c2a00 state 1
l2cap_sock_accept: sk cd560400 timeo 2147483647
l2cap_sock_accept: new socket c74c2a00
l2cap_sock_getname: sock c7184600, sk c74c2a00
l2cap_recv_acldata: conn c9298700 len 24 flags 0x2
l2cap_recv_frame: len 20, cid 0x0040
l2cap_data_channel: sk c74c2a00, len 20
l2cap_sock_getname: sock c7184600, sk c74c2a00
l2cap_sock_getsockopt: sk c74c2a00
l2cap_sock_getsockopt_old: sk c74c2a00
l2cap_sock_getname: sock c7184600, sk c74c2a00
l2cap_sock_sendmsg: sock c7184600, sk c74c2a00
l2cap_do_send: sk c74c2a00 len 29
l2cap_recv_acldata: conn c9298700 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x06 len 4 id 0x05
l2cap_disconnect_req: scid 0x0040 dcid 0x0041
l2cap_build_cmd: conn c9298700, code 0x07, ident 0x05, len 4
l2cap_send_cmd: code 0x07
l2cap_sock_clear_timer: sock c74c2000 state 7
l2cap_chan_del: sk c74c2000, conn c9298700, err 104
l2cap_sock_release: sock c7184480, sk c74c2000
l2cap_sock_shutdown: sock c7184480, sk c74c2000
l2cap_sock_kill: sk c74c2000 state 9
l2cap_sock_destruct: sk c74c2000
l2cap_recv_acldata: conn c9298700 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x06 len 4 id 0x06
l2cap_disconnect_req: scid 0x0041 dcid 0x0040
l2cap_build_cmd: conn c9298700, code 0x07, ident 0x06, len 4
l2cap_send_cmd: code 0x07
l2cap_sock_clear_timer: sock c74c2a00 state 1
l2cap_chan_del: sk c74c2a00, conn c9298700, err 104
l2cap_sock_release: sock c7184600, sk c74c2a00
l2cap_sock_shutdown: sock c7184600, sk c74c2a00
l2cap_sock_kill: sk c74c2a00 state 9
l2cap_sock_destruct: sk c74c2a00
l2cap_recv_acldata: conn c9298700 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x02 len 4 id 0x07
l2cap_connect_req: psm 0x03 scid 0x0042
l2cap_sock_init: sk c148d200
__l2cap_chan_add: conn c9298700, psm 0x03, dcid 0x0042
l2cap_sock_set_timer: sk c148d200 state 2 timeout 5120
l2cap_build_cmd: conn c9298700, code 0x03, ident 0x07, len 8
l2cap_send_cmd: code 0x03
l2cap_recv_acldata: conn c9298700 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x04 len 8 id 0x08
l2cap_config_req: dcid 0x0040 flags 0x00
l2cap_parse_conf_req: sk c148d200
l2cap_get_conf_opt: type 0x01 len 2 val 0x84
l2cap_add_conf_opt: type 0x01 len 2 val 0x84
l2cap_build_cmd: conn c9298700, code 0x05, ident 0x08, len 10
l2cap_send_cmd: code 0x05
l2cap_build_conf_req: sk c148d200
l2cap_add_conf_opt: type 0x01 len 2 val 0x3f5
l2cap_build_cmd: conn c9298700, code 0x04, ident 0x04, len 8
l2cap_send_cmd: code 0x04
l2cap_recv_acldata: conn c9298700 len 18 flags 0x2
l2cap_recv_frame: len 14, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x05 len 10 id 0x04
l2cap_config_rsp: scid 0x0040 flags 0x00 result 0x00
l2cap_chan_ready: sk c148d200, parent cdbba200
l2cap_sock_clear_timer: sock c148d200 state 1
l2cap_sock_accept: sk cdbba200 timeo 0
l2cap_sock_accept: new socket c148d200
l2cap_recv_acldata: conn c9298700 len 8 flags 0x2
l2cap_recv_frame: len 4, cid 0x0040
l2cap_data_channel: sk c148d200, len 4
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 4
l2cap_recv_acldata: conn c9298700 len 18 flags 0x2
l2cap_recv_frame: len 14, cid 0x0040
l2cap_data_channel: sk c148d200, len 14
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 14
l2cap_recv_acldata: conn c9298700 len 8 flags 0x2
l2cap_recv_frame: len 4, cid 0x0040
l2cap_data_channel: sk c148d200, len 4
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 4
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 8
l2cap_recv_acldata: conn c9298700 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0040
l2cap_data_channel: sk c148d200, len 8
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 8
l2cap_recv_acldata: conn c9298700 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0040
l2cap_data_channel: sk c148d200, len 8
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 5
l2cap_recv_acldata: conn c9298700 len 9 flags 0x2
l2cap_recv_frame: len 5, cid 0x0040
l2cap_data_channel: sk c148d200, len 5
l2cap_recv_acldata: conn c9298700 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x02 len 4 id 0x09
l2cap_connect_req: psm 0x01 scid 0x0043
l2cap_sock_init: sk ccb63c00
__l2cap_chan_add: conn c9298700, psm 0x01, dcid 0x0043
l2cap_sock_set_timer: sk ccb63c00 state 2 timeout 5120
l2cap_build_cmd: conn c9298700, code 0x03, ident 0x09, len 8
l2cap_send_cmd: code 0x03
l2cap_recv_acldata: conn c9298700 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x04 len 8 id 0x0a
l2cap_config_req: dcid 0x0041 flags 0x00
l2cap_parse_conf_req: sk ccb63c00
l2cap_get_conf_opt: type 0x01 len 2 val 0x30
l2cap_add_conf_opt: type 0x01 len 2 val 0x30
l2cap_build_cmd: conn c9298700, code 0x05, ident 0x0a, len 10
l2cap_send_cmd: code 0x05
l2cap_build_conf_req: sk ccb63c00
l2cap_build_cmd: conn c9298700, code 0x04, ident 0x05, len 4
l2cap_send_cmd: code 0x04
l2cap_security_cfm: conn c9298700
l2cap_security_cfm: conn c9298700
l2cap_recv_acldata: conn c9298700 len 14 flags 0x2
l2cap_recv_frame: len 10, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x05 len 6 id 0x05
l2cap_config_rsp: scid 0x0041 flags 0x00 result 0x00
l2cap_chan_ready: sk ccb63c00, parent cd560400
l2cap_sock_clear_timer: sock ccb63c00 state 1
l2cap_sock_accept: sk cd560400 timeo 2147483647
l2cap_sock_accept: new socket ccb63c00
l2cap_sock_getname: sock c7184780, sk ccb63c00
l2cap_recv_acldata: conn c9298700 len 17 flags 0x2
l2cap_recv_acldata: Start: total len 24, frag len 17
l2cap_recv_acldata: conn c9298700 len 7 flags 0x1
l2cap_recv_acldata: Cont: frag len 7 (expecting 7)
l2cap_recv_frame: len 20, cid 0x0041
l2cap_data_channel: sk ccb63c00, len 20
l2cap_sock_getname: sock c7184780, sk ccb63c00
l2cap_sock_getsockopt: sk ccb63c00
l2cap_sock_getsockopt_old: sk ccb63c00
l2cap_sock_getname: sock c7184780, sk ccb63c00
l2cap_sock_sendmsg: sock c7184780, sk ccb63c00
l2cap_do_send: sk ccb63c00 len 25
l2cap_recv_acldata: conn c9298700 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x06 len 4 id 0x0b
l2cap_disconnect_req: scid 0x0043 dcid 0x0041
l2cap_build_cmd: conn c9298700, code 0x07, ident 0x0b, len 4
l2cap_send_cmd: code 0x07
l2cap_sock_clear_timer: sock ccb63c00 state 1
l2cap_chan_del: sk ccb63c00, conn c9298700, err 104
l2cap_sock_release: sock c7184780, sk ccb63c00
l2cap_sock_shutdown: sock c7184780, sk ccb63c00
l2cap_sock_kill: sk ccb63c00 state 9
l2cap_sock_destruct: sk ccb63c00
l2cap_recv_acldata: conn c9298700 len 19 flags 0x2
l2cap_recv_frame: len 15, cid 0x0040
l2cap_data_channel: sk c148d200, len 15
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 18
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 10
l2cap_recv_acldata: conn c9298700 len 19 flags 0x2
l2cap_recv_frame: len 15, cid 0x0040
l2cap_data_channel: sk c148d200, len 15
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 130
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 10
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 10
l2cap_recv_acldata: conn c9298700 len 18 flags 0x2
l2cap_recv_frame: len 14, cid 0x0040
l2cap_data_channel: sk c148d200, len 14
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 28
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 10
l2cap_recv_acldata: conn c9298700 len 28 flags 0x2
l2cap_recv_frame: len 24, cid 0x0040
l2cap_data_channel: sk c148d200, len 24
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 10
l2cap_recv_acldata: conn c9298700 len 19 flags 0x2
l2cap_recv_frame: len 15, cid 0x0040
l2cap_data_channel: sk c148d200, len 15
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 32
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 10
l2cap_recv_acldata: conn c9298700 len 19 flags 0x2
l2cap_recv_frame: len 15, cid 0x0040
l2cap_data_channel: sk c148d200, len 15
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 10
l2cap_recv_acldata: conn c9298700 len 19 flags 0x2
l2cap_recv_frame: len 15, cid 0x0040
l2cap_data_channel: sk c148d200, len 15
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 10
l2cap_recv_acldata: conn c9298700 len 19 flags 0x2
l2cap_recv_frame: len 15, cid 0x0040
l2cap_data_channel: sk c148d200, len 15
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 10
l2cap_recv_acldata: conn c9298700 len 19 flags 0x2
l2cap_recv_frame: len 15, cid 0x0040
l2cap_data_channel: sk c148d200, len 15
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 10
l2cap_sock_create: sock c7184780
l2cap_sock_init: sk c9076200
l2cap_sock_bind: sk c9076200
l2cap_sock_connect: sk c9076200
l2cap_do_connect: 04:04:04:04:04:04 -> 01:01:01:01:01:01 psm 0x19
__l2cap_chan_add: conn c9298700, psm 0x19, dcid 0x0000
l2cap_sock_set_timer: sk c9076200 state 5 timeout 5120
l2cap_build_cmd: conn c9298700, code 0x02, ident 0x06, len 4
l2cap_send_cmd: code 0x02
l2cap_recv_acldata: conn c9298700 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x03 len 8 id 0x06
l2cap_connect_rsp: dcid 0x0044 scid 0x0041 result 0x01 status 0x02
l2cap_recv_acldata: conn c9298700 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x03 len 8 id 0x06
l2cap_connect_rsp: dcid 0x0044 scid 0x0041 result 0x00 status 0x00
l2cap_build_conf_req: sk c9076200
l2cap_build_cmd: conn c9298700, code 0x04, ident 0x07, len 4
l2cap_send_cmd: code 0x04
l2cap_recv_acldata: conn c9298700 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x04 len 8 id 0x0c
l2cap_config_req: dcid 0x0041 flags 0x00
l2cap_parse_conf_req: sk c9076200
l2cap_get_conf_opt: type 0x01 len 2 val 0x37f
l2cap_add_conf_opt: type 0x01 len 2 val 0x37f
l2cap_build_cmd: conn c9298700, code 0x05, ident 0x0c, len 10
l2cap_send_cmd: code 0x05
l2cap_recv_acldata: conn c9298700 len 14 flags 0x2
l2cap_recv_frame: len 10, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x05 len 6 id 0x07
l2cap_config_rsp: scid 0x0041 flags 0x00 result 0x00
l2cap_chan_ready: sk c9076200, parent 00000000
l2cap_sock_clear_timer: sock c9076200 state 1
l2cap_sock_getsockopt: sk c9076200
l2cap_sock_getsockopt_old: sk c9076200
l2cap_sock_getname: sock c7184780, sk c9076200
l2cap_sock_getname: sock c7184780, sk c9076200
l2cap_sock_create: sock c7184900
l2cap_sock_init: sk c453f800
l2cap_sock_bind: sk c453f800
l2cap_sock_connect: sk c453f800
l2cap_do_connect: 04:04:04:04:04:04 -> 01:01:01:01:01:01 psm 0x17
__l2cap_chan_add: conn c9298700, psm 0x17, dcid 0x0000
l2cap_sock_set_timer: sk c453f800 state 5 timeout 5120
l2cap_build_cmd: conn c9298700, code 0x02, ident 0x08, len 4
l2cap_send_cmd: code 0x02
l2cap_sock_sendmsg: sock c7184780, sk c9076200
l2cap_do_send: sk c9076200 len 2
l2cap_recv_acldata: conn c9298700 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x03 len 8 id 0x08
l2cap_connect_rsp: dcid 0x0045 scid 0x0042 result 0x01 status 0x02
l2cap_recv_acldata: conn c9298700 len 10 flags 0x2
l2cap_recv_frame: len 6, cid 0x0041
l2cap_data_channel: sk c9076200, len 6
l2cap_sock_sendmsg: sock c7184780, sk c9076200
l2cap_do_send: sk c9076200 len 3
l2cap_recv_acldata: conn c9298700 len 20 flags 0x2
l2cap_recv_frame: len 16, cid 0x0041
l2cap_data_channel: sk c9076200, len 16
l2cap_sock_sendmsg: sock c7184780, sk c9076200
l2cap_do_send: sk c9076200 len 3
l2cap_recv_acldata: conn c9298700 len 20 flags 0x2
l2cap_recv_frame: len 16, cid 0x0041
l2cap_data_channel: sk c9076200, len 16
l2cap_sock_sendmsg: sock c7184780, sk c9076200
l2cap_do_send: sk c9076200 len 14
l2cap_recv_acldata: conn c9298700 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x03 len 8 id 0x08
l2cap_connect_rsp: dcid 0x0045 scid 0x0042 result 0x00 status 0x00
l2cap_build_conf_req: sk c453f800
l2cap_build_cmd: conn c9298700, code 0x04, ident 0x09, len 4
l2cap_send_cmd: code 0x04
l2cap_recv_acldata: conn c9298700 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x04 len 8 id 0x0d
l2cap_config_req: dcid 0x0042 flags 0x00
l2cap_parse_conf_req: sk c453f800
l2cap_get_conf_opt: type 0x01 len 2 val 0x37f
l2cap_add_conf_opt: type 0x01 len 2 val 0x37f
l2cap_build_cmd: conn c9298700, code 0x05, ident 0x0d, len 10
l2cap_send_cmd: code 0x05
l2cap_recv_acldata: conn c9298700 len 14 flags 0x2
l2cap_recv_frame: len 10, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x05 len 6 id 0x09
l2cap_config_rsp: scid 0x0042 flags 0x00 result 0x00
l2cap_chan_ready: sk c453f800, parent 00000000
l2cap_sock_clear_timer: sock c453f800 state 1
l2cap_sock_getsockopt: sk c453f800
l2cap_sock_getsockopt_old: sk c453f800
l2cap_sock_getname: sock c7184900, sk c453f800
l2cap_sock_getname: sock c7184900, sk c453f800
input: 03:03:03:03:03:03 as /class/input/input4
l2cap_recv_acldata: conn c9298700 len 6 flags 0x2
l2cap_recv_frame: len 2, cid 0x0041
l2cap_data_channel: sk c9076200, len 2
l2cap_sock_sendmsg: sock c7184780, sk c9076200
l2cap_do_send: sk c9076200 len 3
l2cap_recv_acldata: conn c9298700 len 6 flags 0x2
l2cap_recv_frame: len 2, cid 0x0041
l2cap_data_channel: sk c9076200, len 2
l2cap_sock_create: sock c7184a80
l2cap_sock_init: sk c74c2200
l2cap_sock_bind: sk c74c2200
l2cap_sock_connect: sk c74c2200
l2cap_do_connect: 04:04:04:04:04:04 -> 01:01:01:01:01:01 psm 0x19
__l2cap_chan_add: conn c9298700, psm 0x19, dcid 0x0000
l2cap_sock_set_timer: sk c74c2200 state 5 timeout 5120
l2cap_build_cmd: conn c9298700, code 0x02, ident 0x0a, len 4
l2cap_send_cmd: code 0x02
l2cap_recv_acldata: conn c9298700 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x03 len 8 id 0x0a
l2cap_connect_rsp: dcid 0x0046 scid 0x0043 result 0x01 status 0x02
l2cap_recv_acldata: conn c9298700 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x03 len 8 id 0x0a
l2cap_connect_rsp: dcid 0x0046 scid 0x0043 result 0x00 status 0x00
l2cap_build_conf_req: sk c74c2200
l2cap_build_cmd: conn c9298700, code 0x04, ident 0x0b, len 4
l2cap_send_cmd: code 0x04
l2cap_recv_acldata: conn c9298700 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x04 len 8 id 0x0e
l2cap_config_req: dcid 0x0043 flags 0x00
l2cap_parse_conf_req: sk c74c2200
l2cap_get_conf_opt: type 0x01 len 2 val 0x37f
l2cap_add_conf_opt: type 0x01 len 2 val 0x37f
l2cap_build_cmd: conn c9298700, code 0x05, ident 0x0e, len 10
l2cap_send_cmd: code 0x05
l2cap_recv_acldata: conn c9298700 len 14 flags 0x2
l2cap_recv_frame: len 10, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x05 len 6 id 0x0b
l2cap_config_rsp: scid 0x0043 flags 0x00 result 0x00
l2cap_chan_ready: sk c74c2200, parent 00000000
l2cap_sock_clear_timer: sock c74c2200 state 1
l2cap_sock_getsockopt: sk c74c2200
l2cap_sock_getsockopt_old: sk c74c2200
l2cap_sock_getname: sock c7184a80, sk c74c2200
l2cap_sock_getname: sock c7184a80, sk c74c2200
ke_recv[1337]: device_added:2549: udi: /org/freedesktop/Hal/devices/computer_logicaldev_input_1
ke_recv[1337]: device_added:2629: /org/freedesktop/Hal/devices/computer_logicaldev_input_1 is not a storage or volume
l2cap_sock_sendmsg: sock c7184780, sk c9076200
l2cap_do_send: sk c9076200 len 3
l2cap_recv_acldata: conn c9298700 len 6 flags 0x2
l2cap_recv_frame: len 2, cid 0x0041
l2cap_data_channel: sk c9076200, len 2
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184a80, sk c74c2200
l2cap_do_send: sk c74c2200 len 846
l2cap_sock_sendmsg: sock c7184780, sk c9076200
l2cap_do_send: sk c9076200 len 3
l2cap_recv_acldata: conn c9298700 len 6 flags 0x2
l2cap_recv_frame: len 2, cid 0x0041
l2cap_data_channel: sk c9076200, len 2
browser[1505]: GLIB CRITICAL ** Gtk - gtk_widget_show: assertion `GTK_IS_WIDGET (widget)' failed
l2cap_recv_acldata: conn c9298700 len 7 flags 0x2
l2cap_recv_frame: len 3, cid 0x0041
l2cap_data_channel: sk c9076200, len 3
l2cap_sock_sendmsg: sock c7184780, sk c9076200
l2cap_do_send: sk c9076200 len 2
l2cap_recv_acldata: conn c9298700 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x06 len 4 id 0x0f
l2cap_disconnect_req: scid 0x0045 dcid 0x0042
l2cap_build_cmd: conn c9298700, code 0x07, ident 0x0f, len 4
l2cap_send_cmd: code 0x07
l2cap_sock_clear_timer: sock c453f800 state 1
l2cap_chan_del: sk c453f800, conn c9298700, err 104
l2cap_sock_release: sock c7184900, sk c453f800
l2cap_sock_shutdown: sock c7184900, sk c453f800
l2cap_sock_kill: sk c453f800 state 9
l2cap_sock_destruct: sk c453f800
l2cap_recv_acldata: conn c9298700 len 8 flags 0x2
l2cap_recv_frame: len 4, cid 0x0040
l2cap_data_channel: sk c148d200, len 4
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 4
l2cap_recv_acldata: conn c9298700 len 8 flags 0x2
l2cap_recv_frame: len 4, cid 0x0040
l2cap_data_channel: sk c148d200, len 4
l2cap_sock_sendmsg: sock c7184600, sk c148d200
l2cap_do_send: sk c148d200 len 4
l2cap_recv_acldata: conn c9298700 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x06 len 4 id 0x10
l2cap_disconnect_req: scid 0x0042 dcid 0x0040
l2cap_build_cmd: conn c9298700, code 0x07, ident 0x10, len 4
l2cap_send_cmd: code 0x07
l2cap_sock_clear_timer: sock c148d200 state 1
l2cap_chan_del: sk c148d200, conn c9298700, err 104
l2cap_sock_release: sock c7184600, sk c148d200
l2cap_sock_shutdown: sock c7184600, sk c148d200
l2cap_sock_kill: sk c148d200 state 9
l2cap_sock_destruct: sk c148d200
l2cap_recv_acldata: conn c9298700 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0001
l2cap_raw_recv: conn c9298700
l2cap_sig_channel: code 0x06 len 4 id 0x11
l2cap_disconnect_req: scid 0x0046 dcid 0x0043
l2cap_build_cmd: conn c9298700, code 0x07, ident 0x11, len 4
l2cap_send_cmd: code 0x07
l2cap_sock_clear_timer: sock c74c2200 state 1
l2cap_chan_del: sk c74c2200, conn c9298700, err 104
l2cap_sock_shutdown: sock c7184a80, sk c74c2200
l2cap_sock_release: sock c7184a80, sk c74c2200
l2cap_sock_shutdown: sock c7184a80, sk c74c2200
l2cap_sock_kill: sk c74c2200 state 9
l2cap_sock_destruct: sk c74c2200
ke_recv[1337]: device_removed:2638: udi: /org/freedesktop/Hal/devices/computer_logicaldev_input_1
iphbd: client with socket 8 disappeared
l2cap_sock_release: sock c7184780, sk c9076200
l2cap_sock_shutdown: sock c7184780, sk c9076200
l2cap_sock_clear_timer: sock c9076200 state 1
__l2cap_sock_close: sk c9076200 state 1 socket c7184780
l2cap_sock_set_timer: sk c9076200 state 8 timeout 5120
l2cap_build_cmd: conn c9298700, code 0x06, ident 0x0c, len 4
l2cap_send_cmd: code 0x06
l2cap_disconn_cfm: hcon cfe3a000 reason 8
l2cap_conn_del: hcon cfe3a000 conn c9298700, err 110
l2cap_sock_clear_timer: sock c9076200 state 8
l2cap_chan_del: sk c9076200, conn c9298700, err 110
l2cap_sock_kill: sk c9076200 state 9
l2cap_sock_destruct: sk c9076200
kb_lock (GPIO 113) is now closed
kb_lock (GPIO 113) is now open
systemui-tklock[1048]: Method call received from: :1.12, iface: com.nokia.system_ui.request, method: tklock_open

[-- Attachment #5: cut_with_press.txt --]
[-- Type: text/plain, Size: 18770 bytes --]

kb_lock (GPIO 113) is now open
l2cap_connect_ind: hdev hci0, bdaddr 01:01:01:01:01:01
l2cap_connect_cfm: hcon cfe3b000 bdaddr 01:01:01:01:01:01 status 0
l2cap_conn_add: hcon cfe3b000 conn cb807080
l2cap_conn_ready: conn cb807080
bluetoothd[943]: link_key_request (sba=02:02:02:02:02:02, dba=03:03:03:03:03:03)
l2cap_security_cfm: conn cb807080
l2cap_recv_acldata: conn cb807080 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x02 len 4 id 0x02
l2cap_connect_req: psm 0x19 scid 0x0041
l2cap_sock_init: sk ccb63c00
__l2cap_chan_add: conn cb807080, psm 0x19, dcid 0x0041
l2cap_sock_set_timer: sk ccb63c00 state 2 timeout 5120
l2cap_build_cmd: conn cb807080, code 0x03, ident 0x02, len 8
l2cap_send_cmd: code 0x03
l2cap_build_cmd: conn cb807080, code 0x0a, ident 0x01, len 2
l2cap_send_cmd: code 0x0a
l2cap_recv_acldata: conn cb807080 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x02 len 4 id 0x03
l2cap_connect_req: psm 0x01 scid 0x0040
l2cap_sock_init: sk c74c2a00
__l2cap_chan_add: conn cb807080, psm 0x01, dcid 0x0040
l2cap_sock_set_timer: sk c74c2a00 state 2 timeout 5120
l2cap_build_cmd: conn cb807080, code 0x03, ident 0x03, len 8
l2cap_send_cmd: code 0x03
l2cap_build_cmd: conn cb807080, code 0x0a, ident 0x02, len 2
l2cap_send_cmd: code 0x0a
l2cap_recv_acldata: conn cb807080 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x0b len 8 id 0x01
l2cap_information_rsp: type 0x0002 result 0x00
l2cap_conn_start: conn cb807080
l2cap_build_cmd: conn cb807080, code 0x03, ident 0x03, len 8
l2cap_send_cmd: code 0x03
l2cap_build_cmd: conn cb807080, code 0x03, ident 0x02, len 8
l2cap_send_cmd: code 0x03
l2cap_sock_accept: sk ce58be00 timeo 0
l2cap_sock_accept: new socket ccb63c00
l2cap_sock_getsockopt: sk ccb63c00
l2cap_sock_getsockopt_old: sk ccb63c00
l2cap_sock_getname: sock c718f480, sk ccb63c00
l2cap_sock_getname: sock c718f480, sk ccb63c00
bluetoothd[943]: link_key_request (sba=02:02:02:02:02:02, dba=03:03:03:03:03:03)
l2cap_recv_acldata: conn cb807080 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x0b len 8 id 0x02
l2cap_information_rsp: type 0x0002 result 0x00
l2cap_conn_start: conn cb807080
avoided crash in l2cap_conn_start parent 00000000 result 1 status 2
l2cap_recv_acldata: conn cb807080 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x04 len 8 id 0x04
l2cap_config_req: dcid 0x0041 flags 0x00
l2cap_parse_conf_req: sk c74c2a00
l2cap_get_conf_opt: type 0x01 len 2 val 0x30
l2cap_add_conf_opt: type 0x01 len 2 val 0x30
l2cap_build_cmd: conn cb807080, code 0x05, ident 0x04, len 10
l2cap_send_cmd: code 0x05
l2cap_build_conf_req: sk c74c2a00
l2cap_build_cmd: conn cb807080, code 0x04, ident 0x03, len 4
l2cap_send_cmd: code 0x04
l2cap_build_cmd: conn cb807080, code 0x03, ident 0x02, len 8
l2cap_send_cmd: code 0x03
l2cap_security_cfm: conn cb807080
l2cap_sock_clear_timer: sock ccb63c00 state 7
l2cap_recv_acldata: conn cb807080 len 14 flags 0x2
l2cap_recv_frame: len 10, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x05 len 6 id 0x03
l2cap_config_rsp: scid 0x0041 flags 0x00 result 0x00
l2cap_chan_ready: sk c74c2a00, parent cd560400
l2cap_sock_clear_timer: sock c74c2a00 state 1
l2cap_sock_accept: sk cd560400 timeo 2147483647
l2cap_sock_accept: new socket c74c2a00
l2cap_sock_getname: sock c718fd80, sk c74c2a00
l2cap_recv_acldata: conn cb807080 len 17 flags 0x2
l2cap_recv_acldata: Start: total len 24, frag len 17
l2cap_recv_acldata: conn cb807080 len 7 flags 0x1
l2cap_recv_acldata: Cont: frag len 7 (expecting 7)
l2cap_recv_frame: len 20, cid 0x0041
l2cap_data_channel: sk c74c2a00, len 20
l2cap_sock_getname: sock c718fd80, sk c74c2a00
l2cap_sock_getsockopt: sk c74c2a00
l2cap_sock_getsockopt_old: sk c74c2a00
l2cap_sock_getname: sock c718fd80, sk c74c2a00
l2cap_sock_sendmsg: sock c718fd80, sk c74c2a00
l2cap_do_send: sk c74c2a00 len 29
l2cap_recv_acldata: conn cb807080 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x06 len 4 id 0x05
l2cap_disconnect_req: scid 0x0040 dcid 0x0041
l2cap_build_cmd: conn cb807080, code 0x07, ident 0x05, len 4
l2cap_send_cmd: code 0x07
l2cap_sock_clear_timer: sock c74c2a00 state 1
l2cap_chan_del: sk c74c2a00, conn cb807080, err 104
l2cap_sock_release: sock c718fd80, sk c74c2a00
l2cap_sock_shutdown: sock c718fd80, sk c74c2a00
l2cap_sock_kill: sk c74c2a00 state 9
l2cap_sock_destruct: sk c74c2a00
l2cap_recv_acldata: conn cb807080 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x04 len 8 id 0x06
l2cap_config_req: dcid 0x0040 flags 0x00
l2cap_parse_conf_req: sk ccb63c00
l2cap_get_conf_opt: type 0x01 len 2 val 0x37f
l2cap_add_conf_opt: type 0x01 len 2 val 0x37f
l2cap_build_cmd: conn cb807080, code 0x05, ident 0x06, len 10
l2cap_send_cmd: code 0x05
l2cap_build_conf_req: sk ccb63c00
l2cap_build_cmd: conn cb807080, code 0x04, ident 0x04, len 4
l2cap_send_cmd: code 0x04
l2cap_recv_acldata: conn cb807080 len 14 flags 0x2
l2cap_recv_frame: len 10, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x05 len 6 id 0x04
l2cap_config_rsp: scid 0x0040 flags 0x00 result 0x00
l2cap_chan_ready: sk ccb63c00, parent 00000000
l2cap_sock_clear_timer: sock ccb63c00 state 1
l2cap_sock_getsockopt: sk ccb63c00
l2cap_sock_getsockopt_old: sk ccb63c00
l2cap_sock_getname: sock c718f480, sk ccb63c00
l2cap_sock_getname: sock c718f480, sk ccb63c00
l2cap_recv_acldata: conn cb807080 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x02 len 4 id 0x07
l2cap_connect_req: psm 0x03 scid 0x0042
l2cap_sock_init: sk cc8c0e00
__l2cap_chan_add: conn cb807080, psm 0x03, dcid 0x0042
l2cap_sock_set_timer: sk cc8c0e00 state 2 timeout 5120
l2cap_build_cmd: conn cb807080, code 0x03, ident 0x07, len 8
l2cap_send_cmd: code 0x03
l2cap_recv_acldata: conn cb807080 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x04 len 8 id 0x08
l2cap_config_req: dcid 0x0041 flags 0x00
l2cap_parse_conf_req: sk cc8c0e00
l2cap_get_conf_opt: type 0x01 len 2 val 0x84
l2cap_add_conf_opt: type 0x01 len 2 val 0x84
l2cap_build_cmd: conn cb807080, code 0x05, ident 0x08, len 10
l2cap_send_cmd: code 0x05
l2cap_build_conf_req: sk cc8c0e00
l2cap_add_conf_opt: type 0x01 len 2 val 0x3f5
l2cap_build_cmd: conn cb807080, code 0x04, ident 0x05, len 8
l2cap_send_cmd: code 0x04
l2cap_recv_acldata: conn cb807080 len 18 flags 0x2
l2cap_recv_frame: len 14, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x05 len 10 id 0x05
l2cap_config_rsp: scid 0x0041 flags 0x00 result 0x00
l2cap_chan_ready: sk cc8c0e00, parent cdbba200
l2cap_sock_clear_timer: sock cc8c0e00 state 1
l2cap_sock_accept: sk cdbba200 timeo 0
l2cap_sock_accept: new socket cc8c0e00
l2cap_recv_acldata: conn cb807080 len 8 flags 0x2
l2cap_recv_frame: len 4, cid 0x0041
l2cap_data_channel: sk cc8c0e00, len 4
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 4
l2cap_recv_acldata: conn cb807080 len 18 flags 0x2
l2cap_recv_frame: len 14, cid 0x0041
l2cap_data_channel: sk cc8c0e00, len 14
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 14
l2cap_recv_acldata: conn cb807080 len 8 flags 0x2
l2cap_recv_frame: len 4, cid 0x0041
l2cap_data_channel: sk cc8c0e00, len 4
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 4
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 8
l2cap_recv_acldata: conn cb807080 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0041
l2cap_data_channel: sk cc8c0e00, len 8
l2cap_recv_acldata: conn cb807080 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0041
l2cap_data_channel: sk cc8c0e00, len 8
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 8
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 5
l2cap_recv_acldata: conn cb807080 len 9 flags 0x2
l2cap_recv_frame: len 5, cid 0x0041
l2cap_data_channel: sk cc8c0e00, len 5
l2cap_recv_acldata: conn cb807080 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x02 len 4 id 0x09
l2cap_connect_req: psm 0x01 scid 0x0043
l2cap_sock_init: sk ccb63800
__l2cap_chan_add: conn cb807080, psm 0x01, dcid 0x0043
l2cap_sock_set_timer: sk ccb63800 state 2 timeout 5120
l2cap_build_cmd: conn cb807080, code 0x03, ident 0x09, len 8
l2cap_send_cmd: code 0x03
l2cap_recv_acldata: conn cb807080 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x04 len 8 id 0x0a
l2cap_config_req: dcid 0x0042 flags 0x00
l2cap_parse_conf_req: sk ccb63800
l2cap_get_conf_opt: type 0x01 len 2 val 0x30
l2cap_add_conf_opt: type 0x01 len 2 val 0x30
l2cap_build_cmd: conn cb807080, code 0x05, ident 0x0a, len 10
l2cap_send_cmd: code 0x05
l2cap_build_conf_req: sk ccb63800
l2cap_build_cmd: conn cb807080, code 0x04, ident 0x06, len 4
l2cap_send_cmd: code 0x04
l2cap_recv_acldata: conn cb807080 len 14 flags 0x2
l2cap_recv_frame: len 10, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x05 len 6 id 0x06
l2cap_config_rsp: scid 0x0042 flags 0x00 result 0x00
l2cap_chan_ready: sk ccb63800, parent cd560400
l2cap_sock_clear_timer: sock ccb63800 state 1
l2cap_sock_accept: sk cd560400 timeo 2147483647
l2cap_sock_accept: new socket ccb63800
l2cap_sock_getname: sock c718f180, sk ccb63800
l2cap_recv_acldata: conn cb807080 len 24 flags 0x2
l2cap_recv_frame: len 20, cid 0x0042
l2cap_data_channel: sk ccb63800, len 20
l2cap_sock_getname: sock c718f180, sk ccb63800
l2cap_sock_getsockopt: sk ccb63800
l2cap_sock_getsockopt_old: sk ccb63800
l2cap_sock_getname: sock c718f180, sk ccb63800
l2cap_sock_sendmsg: sock c718f180, sk ccb63800
l2cap_do_send: sk ccb63800 len 25
l2cap_recv_acldata: conn cb807080 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x06 len 4 id 0x0b
l2cap_disconnect_req: scid 0x0043 dcid 0x0042
l2cap_build_cmd: conn cb807080, code 0x07, ident 0x0b, len 4
l2cap_send_cmd: code 0x07
l2cap_sock_clear_timer: sock ccb63800 state 1
l2cap_chan_del: sk ccb63800, conn cb807080, err 104
l2cap_sock_release: sock c718f180, sk ccb63800
l2cap_sock_shutdown: sock c718f180, sk ccb63800
l2cap_sock_kill: sk ccb63800 state 9
l2cap_sock_destruct: sk ccb63800
l2cap_recv_acldata: conn cb807080 len 19 flags 0x2
l2cap_recv_frame: len 15, cid 0x0041
l2cap_data_channel: sk cc8c0e00, len 15
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 18
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 10
l2cap_recv_acldata: conn cb807080 len 19 flags 0x2
l2cap_recv_frame: len 15, cid 0x0041
l2cap_data_channel: sk cc8c0e00, len 15
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 130
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 10
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 10
l2cap_sock_sendmsg: sock c718f480, sk ccb63c00
l2cap_do_send: sk ccb63c00 len 2
l2cap_recv_acldata: conn cb807080 len 18 flags 0x2
l2cap_recv_frame: len 14, cid 0x0041
l2cap_data_channel: sk cc8c0e00, len 14
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 28
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 10
l2cap_recv_acldata: conn cb807080 len 10 flags 0x2
l2cap_recv_frame: len 6, cid 0x0040
l2cap_data_channel: sk ccb63c00, len 6
l2cap_sock_sendmsg: sock c718f480, sk ccb63c00
l2cap_do_send: sk ccb63c00 len 3
l2cap_recv_acldata: conn cb807080 len 20 flags 0x2
l2cap_recv_frame: len 16, cid 0x0040
l2cap_data_channel: sk ccb63c00, len 16
l2cap_sock_sendmsg: sock c718f480, sk ccb63c00
l2cap_do_send: sk ccb63c00 len 3
l2cap_recv_acldata: conn cb807080 len 28 flags 0x2
l2cap_recv_frame: len 24, cid 0x0041
l2cap_data_channel: sk cc8c0e00, len 24
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 10
l2cap_recv_acldata: conn cb807080 len 20 flags 0x2
l2cap_recv_frame: len 16, cid 0x0040
l2cap_data_channel: sk ccb63c00, len 16
l2cap_sock_sendmsg: sock c718f480, sk ccb63c00
l2cap_do_send: sk ccb63c00 len 14
l2cap_recv_acldata: conn cb807080 len 19 flags 0x2
l2cap_recv_frame: len 15, cid 0x0041
l2cap_data_channel: sk cc8c0e00, len 15
l2cap_recv_acldata: conn cb807080 len 8 flags 0x2
l2cap_recv_frame: len 4, cid 0x0040
l2cap_data_channel: sk ccb63c00, len 4
l2cap_recv_acldata: conn cb807080 len 6 flags 0x2
l2cap_recv_frame: len 2, cid 0x0040
l2cap_data_channel: sk ccb63c00, len 2
bluetoothd[943]: SET_CONFIGURATION request rejected: Stream End Point in Use (19)
l2cap_sock_sendmsg: sock c718f480, sk ccb63c00
l2cap_do_send: sk ccb63c00 len 4
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 32
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 10
l2cap_sock_create: sock c718f180
l2cap_sock_init: sk ccb63800
l2cap_sock_bind: sk ccb63800
l2cap_sock_connect: sk ccb63800
l2cap_do_connect: 04:04:04:04:04:04 -> 01:01:01:01:01:01 psm 0x17
__l2cap_chan_add: conn cb807080, psm 0x17, dcid 0x0000
l2cap_sock_set_timer: sk ccb63800 state 5 timeout 5120
l2cap_build_cmd: conn cb807080, code 0x02, ident 0x07, len 4
l2cap_send_cmd: code 0x02
l2cap_recv_acldata: conn cb807080 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x03 len 8 id 0x07
l2cap_connect_rsp: dcid 0x0044 scid 0x0042 result 0x01 status 0x02
l2cap_recv_acldata: conn cb807080 len 19 flags 0x2
l2cap_recv_frame: len 15, cid 0x0041
l2cap_data_channel: sk cc8c0e00, len 15
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 10
l2cap_recv_acldata: conn cb807080 len 19 flags 0x2
l2cap_recv_frame: len 15, cid 0x0041
l2cap_data_channel: sk cc8c0e00, len 15
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 10
l2cap_recv_acldata: conn cb807080 len 19 flags 0x2
l2cap_recv_frame: len 15, cid 0x0041
l2cap_data_channel: sk cc8c0e00, len 15
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 10
l2cap_recv_acldata: conn cb807080 len 19 flags 0x2
l2cap_recv_frame: len 15, cid 0x0041
l2cap_data_channel: sk cc8c0e00, len 15
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 10
l2cap_recv_acldata: conn cb807080 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x03 len 8 id 0x07
l2cap_connect_rsp: dcid 0x0044 scid 0x0042 result 0x00 status 0x00
l2cap_build_conf_req: sk ccb63800
l2cap_build_cmd: conn cb807080, code 0x04, ident 0x08, len 4
l2cap_send_cmd: code 0x04
l2cap_recv_acldata: conn cb807080 len 16 flags 0x2
l2cap_recv_frame: len 12, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x04 len 8 id 0x0c
l2cap_config_req: dcid 0x0042 flags 0x00
l2cap_parse_conf_req: sk ccb63800
l2cap_get_conf_opt: type 0x01 len 2 val 0x37f
l2cap_add_conf_opt: type 0x01 len 2 val 0x37f
l2cap_build_cmd: conn cb807080, code 0x05, ident 0x0c, len 10
l2cap_send_cmd: code 0x05
l2cap_recv_acldata: conn cb807080 len 14 flags 0x2
l2cap_recv_frame: len 10, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x05 len 6 id 0x08
l2cap_config_rsp: scid 0x0042 flags 0x00 result 0x00
l2cap_chan_ready: sk ccb63800, parent 00000000
l2cap_sock_clear_timer: sock ccb63800 state 1
l2cap_sock_getsockopt: sk ccb63800
l2cap_sock_getsockopt_old: sk ccb63800
l2cap_sock_getname: sock c718f180, sk ccb63800
l2cap_sock_getname: sock c718f180, sk ccb63800
input: 03:03:03:03:03:03 as /class/input/input9
ke_recv[1337]: device_added:2549: udi: /org/freedesktop/Hal/devices/computer_logicaldev_input_1
ke_recv[1337]: device_added:2629: /org/freedesktop/Hal/devices/computer_logicaldev_input_1 is not a storage or volume
l2cap_recv_acldata: conn cb807080 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x06 len 4 id 0x0d
l2cap_disconnect_req: scid 0x0044 dcid 0x0042
l2cap_build_cmd: conn cb807080, code 0x07, ident 0x0d, len 4
l2cap_send_cmd: code 0x07
l2cap_sock_clear_timer: sock ccb63800 state 1
l2cap_chan_del: sk ccb63800, conn cb807080, err 104
l2cap_recv_acldata: conn cb807080 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x06 len 4 id 0x0e
l2cap_disconnect_req: scid 0x0041 dcid 0x0040
l2cap_build_cmd: conn cb807080, code 0x07, ident 0x0e, len 4
l2cap_send_cmd: code 0x07
l2cap_sock_clear_timer: sock ccb63c00 state 1
l2cap_chan_del: sk ccb63c00, conn cb807080, err 104
l2cap_recv_acldata: conn cb807080 len 8 flags 0x2
l2cap_recv_frame: len 4, cid 0x0041
l2cap_data_channel: sk cc8c0e00, len 4
l2cap_sock_release: sock c718f180, sk ccb63800
l2cap_sock_shutdown: sock c718f180, sk ccb63800
l2cap_sock_kill: sk ccb63800 state 9
l2cap_sock_destruct: sk ccb63800
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 4
ke_recv[1337]: device_removed:2638: udi: /org/freedesktop/Hal/devices/computer_logicaldev_input_1
l2cap_sock_release: sock c718f480, sk ccb63c00
l2cap_sock_shutdown: sock c718f480, sk ccb63c00
l2cap_sock_kill: sk ccb63c00 state 9
l2cap_sock_destruct: sk ccb63c00
l2cap_recv_acldata: conn cb807080 len 8 flags 0x2
l2cap_recv_frame: len 4, cid 0x0041
l2cap_data_channel: sk cc8c0e00, len 4
l2cap_sock_sendmsg: sock c718fd80, sk cc8c0e00
l2cap_do_send: sk cc8c0e00 len 4
l2cap_recv_acldata: conn cb807080 len 12 flags 0x2
l2cap_recv_frame: len 8, cid 0x0001
l2cap_raw_recv: conn cb807080
l2cap_sig_channel: code 0x06 len 4 id 0x0f
l2cap_disconnect_req: scid 0x0042 dcid 0x0041
l2cap_build_cmd: conn cb807080, code 0x07, ident 0x0f, len 4
l2cap_send_cmd: code 0x07
l2cap_sock_clear_timer: sock cc8c0e00 state 1
l2cap_chan_del: sk cc8c0e00, conn cb807080, err 104
l2cap_sock_release: sock c718fd80, sk cc8c0e00
l2cap_sock_shutdown: sock c718fd80, sk cc8c0e00
l2cap_sock_kill: sk cc8c0e00 state 9
l2cap_sock_destruct: sk cc8c0e00
l2cap_disconn_cfm: hcon cfe3b000 reason 19
l2cap_conn_del: hcon cfe3b000 conn cb807080, err 104
kb_lock (GPIO 113) is now closed
systemui-tklock[1048]: Method call received from: :1.12, iface: com.nokia.system_ui.request, method: tklock_close
kb_lock (GPIO 113) is now open
kb_lock (GPIO 113) is now closed
systemui-tklock[1048]: Method call received from: :1.12, iface: com.nokia.system_ui.request, method: tklock_open
kb_lock (GPIO 113) is now open

^ permalink raw reply related

* [bluetooth-next -v2 24/24] Bluetooth: Add key size checks for SMP
From: Vinicius Costa Gomes @ 2011-02-11  1:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes, Anderson Briglia
In-Reply-To: <1297388811-14997-3-git-send-email-vinicius.gomes@openbossa.org>

This patch implements a check in smp cmd pairing request and pairing
response to verify if encryption key maximum size is compatible in both
slave and master when SMP Pairing is requested. Keys are also masked to
the correct negotiated size.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
---
 include/net/bluetooth/l2cap.h |    1 +
 include/net/bluetooth/smp.h   |    3 ++
 net/bluetooth/smp.c           |   52 +++++++++++++++++++++++++++++++---------
 3 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index e2712b0..420981c 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -295,6 +295,7 @@ struct l2cap_conn {
 	__u8		prnd[16];
 	__u8		pcnf[16];
 	__u8		tk[16];
+	__u8		smp_key_size;
 
 	struct timer_list security_timer;
 
diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
index 111853a..4fb7d19 100644
--- a/include/net/bluetooth/smp.h
+++ b/include/net/bluetooth/smp.h
@@ -112,6 +112,9 @@ struct smp_cmd_security_req {
 #define SMP_UNSPECIFIED		0x08
 #define SMP_REPEATED_ATTEMPTS		0x09
 
+#define SMP_MIN_ENC_KEY_SIZE		7
+#define SMP_MAX_ENC_KEY_SIZE		16
+
 /* SMP Commands */
 int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level);
 int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb);
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index a120aa9..79c93e3 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -206,35 +206,51 @@ static void build_pairing_cmd(struct l2cap_conn *conn, struct smp_cmd_pairing *c
 {
 	cmd->io_capability = SMP_IO_NO_INPUT_OUTPUT;
 	cmd->oob_flag = SMP_OOB_NOT_PRESENT;
-	cmd->max_key_size = 16;
+	cmd->max_key_size = SMP_MAX_ENC_KEY_SIZE;
 	cmd->init_key_dist = 0x00;
 	cmd->resp_key_dist = 0x00;
 	cmd->auth_req = authreq;
 }
 
+static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
+{
+	if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
+			(max_key_size < SMP_MIN_ENC_KEY_SIZE))
+		return SMP_ENC_KEY_SIZE;
+
+	conn->smp_key_size = max_key_size;
+
+	return 0;
+}
+
 static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 {
-	struct smp_cmd_pairing *rp = (void *) skb->data;
+	struct smp_cmd_pairing rsp, *req = (void *) skb->data;
+	u8 key_size;
 
 	BT_DBG("conn %p", conn);
 
 	conn->preq[0] = SMP_CMD_PAIRING_REQ;
-	memcpy(&conn->preq[1], rp, sizeof(*rp));
-	skb_pull(skb, sizeof(*rp));
+	memcpy(&conn->preq[1], req, sizeof(*req));
+	skb_pull(skb, sizeof(*req));
 
-	if (rp->oob_flag)
+	if (req->oob_flag)
 		return SMP_OOB_NOT_AVAIL;
 
 	/* We didn't start the pairing, so no requirements */
-	build_pairing_cmd(conn, rp, SMP_AUTH_NONE);
+	build_pairing_cmd(conn, &rsp, SMP_AUTH_NONE);
+
+	key_size = min(req->max_key_size, rsp.max_key_size);
+	if (check_enc_key_size(conn, key_size))
+		return SMP_ENC_KEY_SIZE;
 
 	/* Just works */
 	memset(conn->tk, 0, sizeof(conn->tk));
 
 	conn->pres[0] = SMP_CMD_PAIRING_RSP;
-	memcpy(&conn->pres[1], rp, sizeof(*rp));
+	memcpy(&conn->pres[1], &rsp, sizeof(rsp));
 
-	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp);
+	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
 
 	mod_timer(&conn->security_timer, jiffies +
 					msecs_to_jiffies(SMP_TIMEOUT));
@@ -244,21 +260,27 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 
 static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 {
-	struct smp_cmd_pairing *rp = (void *) skb->data;
+	struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
 	struct smp_cmd_pairing_confirm cp;
 	struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
 	int ret;
-	u8 res[16];
+	u8 res[16], key_size;
 
 	BT_DBG("conn %p", conn);
 
-	skb_pull(skb, sizeof(*rp));
+	skb_pull(skb, sizeof(*rsp));
+
+	req = (void *) &conn->preq[1];
+
+	key_size = min(req->max_key_size, rsp->max_key_size);
+	if (check_enc_key_size(conn, key_size))
+		return SMP_ENC_KEY_SIZE;
 
 	/* Just works */
 	memset(conn->tk, 0, sizeof(conn->tk));
 
 	conn->pres[0] = SMP_CMD_PAIRING_RSP;
-	memcpy(&conn->pres[1], rp, sizeof(*rp));
+	memcpy(&conn->pres[1], rsp, sizeof(*rsp));
 
 	ret = smp_rand(conn->prnd);
 	if (ret)
@@ -350,6 +372,9 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 		smp_s1(tfm, conn->tk, random, conn->prnd, key);
 		swap128(key, hcon->ltk);
 
+		memset(hcon->ltk + conn->smp_key_size, 0,
+				SMP_MAX_ENC_KEY_SIZE - conn->smp_key_size);
+
 		hci_le_start_enc(hcon, hcon->ltk);
 
 		hex_dump_to_buffer(key, sizeof(key), 16, 1, buf, sizeof(buf), 0);
@@ -363,6 +388,9 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 		smp_s1(tfm, conn->tk, conn->prnd, random, key);
 		swap128(key, hcon->ltk);
 
+		memset(hcon->ltk + conn->smp_key_size, 0,
+				SMP_MAX_ENC_KEY_SIZE - conn->smp_key_size);
+
 		hex_dump_to_buffer(key, sizeof(key), 16, 1, buf, sizeof(buf), 0);
 		BT_DBG("key %s", buf);
 	}
-- 
1.7.4


^ permalink raw reply related

* [bluetooth-next -v2 23/24] Bluetooth: Add support for SMP timeout
From: Vinicius Costa Gomes @ 2011-02-11  1:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1297388811-14997-2-git-send-email-vinicius.gomes@openbossa.org>

This patch adds support for disconnecting the link when SMP procedure
takes more than 30 seconds.

SMP begins when either the Pairing Request command is sent or the
Pairing Response is received, and it ends when the link is encrypted
(or terminated). Vol 3, Part H Section 3.4.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 include/net/bluetooth/l2cap.h |    2 +
 net/bluetooth/l2cap_core.c    |   70 ++++++++++++++++++++++++----------------
 net/bluetooth/smp.c           |   14 ++++++++
 3 files changed, 58 insertions(+), 28 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 359dd1b..e2712b0 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -296,6 +296,8 @@ struct l2cap_conn {
 	__u8		pcnf[16];
 	__u8		tk[16];
 
+	struct timer_list security_timer;
+
 	struct l2cap_chan_list chan_list;
 };
 
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 530e531..0ca54d8 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -735,6 +735,36 @@ static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
 	read_unlock(&l->lock);
 }
 
+static void l2cap_conn_del(struct hci_conn *hcon, int err)
+{
+	struct l2cap_conn *conn = hcon->l2cap_data;
+	struct sock *sk;
+
+	if (!conn)
+		return;
+
+	BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
+
+	kfree_skb(conn->rx_skb);
+
+	/* Kill channels */
+	while ((sk = conn->chan_list.head)) {
+		bh_lock_sock(sk);
+		l2cap_chan_del(sk, err);
+		bh_unlock_sock(sk);
+		l2cap_sock_kill(sk);
+	}
+
+	if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
+		del_timer_sync(&conn->info_timer);
+
+	if (hcon->type == LE_LINK)
+		del_timer(&conn->security_timer);
+
+	hcon->l2cap_data = NULL;
+	kfree(conn);
+}
+
 static void l2cap_info_timeout(unsigned long arg)
 {
 	struct l2cap_conn *conn = (void *) arg;
@@ -745,6 +775,13 @@ static void l2cap_info_timeout(unsigned long arg)
 	l2cap_conn_start(conn);
 }
 
+static void security_timeout(unsigned long arg)
+{
+	struct l2cap_conn *conn = (void *) arg;
+
+	l2cap_conn_del(conn->hcon, ETIMEDOUT);
+}
+
 static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
 {
 	struct l2cap_conn *conn = hcon->l2cap_data;
@@ -774,7 +811,10 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
 	spin_lock_init(&conn->lock);
 	rwlock_init(&conn->chan_list.lock);
 
-	if (hcon->type != LE_LINK)
+	if (hcon->type == LE_LINK)
+		setup_timer(&conn->security_timer, security_timeout,
+						(unsigned long) conn);
+	else
 		setup_timer(&conn->info_timer, l2cap_info_timeout,
 						(unsigned long) conn);
 
@@ -783,33 +823,6 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
 	return conn;
 }
 
-static void l2cap_conn_del(struct hci_conn *hcon, int err)
-{
-	struct l2cap_conn *conn = hcon->l2cap_data;
-	struct sock *sk;
-
-	if (!conn)
-		return;
-
-	BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
-
-	kfree_skb(conn->rx_skb);
-
-	/* Kill channels */
-	while ((sk = conn->chan_list.head)) {
-		bh_lock_sock(sk);
-		l2cap_chan_del(sk, err);
-		bh_unlock_sock(sk);
-		l2cap_sock_kill(sk);
-	}
-
-	if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
-		del_timer_sync(&conn->info_timer);
-
-	hcon->l2cap_data = NULL;
-	kfree(conn);
-}
-
 static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
 {
 	struct l2cap_chan_list *l = &conn->chan_list;
@@ -3699,6 +3712,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
 		if (l2cap_pi(sk)->scid == L2CAP_CID_LE_DATA) {
 			if (!status && encrypt) {
 				l2cap_pi(sk)->sec_level = hcon->sec_level;
+				del_timer(&conn->security_timer);
 				l2cap_chan_ready(sk);
 			}
 
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index c12258f..a120aa9 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -27,6 +27,8 @@
 #include <linux/crypto.h>
 #include <crypto/b128ops.h>
 
+#define SMP_TIMEOUT 30000 /* 30 seconds */
+
 static inline void swap128(u8 src[16], u8 dst[16])
 {
 	int i;
@@ -234,6 +236,9 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp);
 
+	mod_timer(&conn->security_timer, jiffies +
+					msecs_to_jiffies(SMP_TIMEOUT));
+
 	return 0;
 }
 
@@ -305,6 +310,9 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
 		smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
 	}
 
+	mod_timer(&conn->security_timer, jiffies +
+					msecs_to_jiffies(SMP_TIMEOUT));
+
 	return 0;
 }
 
@@ -383,6 +391,9 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
 
+	mod_timer(&conn->security_timer, jiffies +
+					msecs_to_jiffies(SMP_TIMEOUT));
+
 	set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
 
 	return 0;
@@ -416,6 +427,9 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 		conn->preq[0] = SMP_CMD_PAIRING_REQ;
 		memcpy(&conn->preq[1], &cp, sizeof(cp));
 
+		mod_timer(&conn->security_timer, jiffies +
+					msecs_to_jiffies(SMP_TIMEOUT));
+
 		smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
 	} else {
 		struct smp_cmd_security_req cp;
-- 
1.7.4


^ permalink raw reply related

* [bluetooth-next -v2 22/24] Bluetooth: Add support for Pairing features exchange
From: Vinicius Costa Gomes @ 2011-02-11  1:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1297388811-14997-1-git-send-email-vinicius.gomes@openbossa.org>

This patch implements a simple version of the SMP Pairing Features
exchange procedure (Vol. 3 Part H, Section 2.3.5.1).

For now, everything that would cause a Pairing Method different of
Just Works to be chosen is rejected.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 include/net/bluetooth/smp.h |   17 ++++++
 net/bluetooth/hci_event.c   |    1 +
 net/bluetooth/smp.c         |  118 ++++++++++++++++++++++--------------------
 3 files changed, 80 insertions(+), 56 deletions(-)

diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
index 36bdd6e..111853a 100644
--- a/include/net/bluetooth/smp.h
+++ b/include/net/bluetooth/smp.h
@@ -38,6 +38,23 @@ struct smp_cmd_pairing {
 	__u8	resp_key_dist;
 } __packed;
 
+#define SMP_IO_DISPLAY_ONLY	0x00
+#define SMP_IO_DISPLAY_YESNO	0x01
+#define SMP_IO_KEYBOARD_ONLY	0x02
+#define SMP_IO_NO_INPUT_OUTPUT	0x03
+#define SMP_IO_KEYBOARD_DISPLAY	0x04
+
+#define SMP_OOB_NOT_PRESENT	0x00
+#define SMP_OOB_PRESENT		0x01
+
+#define SMP_DIST_ENC_KEY	0x01
+#define SMP_DIST_ID_KEY		0x02
+#define SMP_DIST_SIGN		0x04
+
+#define SMP_AUTH_NONE		0x00
+#define SMP_AUTH_BONDING	0x01
+#define SMP_AUTH_MITM		0x04
+
 #define SMP_CMD_PAIRING_CONFIRM	0x03
 struct smp_cmd_pairing_confirm {
 	__u8	confirm_val[16];
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index fece2ee..99c75f4 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1509,6 +1509,7 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *
 				/* Encryption implies authentication */
 				conn->link_mode |= HCI_LM_AUTH;
 				conn->link_mode |= HCI_LM_ENCRYPT;
+				conn->sec_level = conn->pending_sec_level;
 			} else
 				conn->link_mode &= ~HCI_LM_ENCRYPT;
 		}
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 98bb80a..c12258f 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -186,7 +186,31 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
 	hci_send_acl(conn->hcon, skb, 0);
 }
 
-static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
+static __u8 seclevel_to_authreq(__u8 level)
+{
+	switch (level) {
+	case BT_SECURITY_MEDIUM:
+		return SMP_AUTH_BONDING;
+
+	case BT_SECURITY_HIGH:
+		return SMP_AUTH_BONDING | SMP_AUTH_MITM;
+
+	default:
+		return SMP_AUTH_NONE;
+	}
+}
+
+static void build_pairing_cmd(struct l2cap_conn *conn, struct smp_cmd_pairing *cmd, __u8 authreq)
+{
+	cmd->io_capability = SMP_IO_NO_INPUT_OUTPUT;
+	cmd->oob_flag = SMP_OOB_NOT_PRESENT;
+	cmd->max_key_size = 16;
+	cmd->init_key_dist = 0x00;
+	cmd->resp_key_dist = 0x00;
+	cmd->auth_req = authreq;
+}
+
+static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 	struct smp_cmd_pairing *rp = (void *) skb->data;
 
@@ -196,12 +220,11 @@ static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	memcpy(&conn->preq[1], rp, sizeof(*rp));
 	skb_pull(skb, sizeof(*rp));
 
-	rp->io_capability = 0x00;
-	rp->oob_flag = 0x00;
-	rp->max_key_size = 16;
-	rp->init_key_dist = 0x00;
-	rp->resp_key_dist = 0x00;
-	rp->auth_req &= 0x05;
+	if (rp->oob_flag)
+		return SMP_OOB_NOT_AVAIL;
+
+	/* We didn't start the pairing, so no requirements */
+	build_pairing_cmd(conn, rp, SMP_AUTH_NONE);
 
 	/* Just works */
 	memset(conn->tk, 0, sizeof(conn->tk));
@@ -210,9 +233,11 @@ static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	memcpy(&conn->pres[1], rp, sizeof(*rp));
 
 	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp);
+
+	return 0;
 }
 
-static void smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
+static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 	struct smp_cmd_pairing *rp = (void *) skb->data;
 	struct smp_cmd_pairing_confirm cp;
@@ -222,28 +247,31 @@ static void smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	BT_DBG("conn %p", conn);
 
+	skb_pull(skb, sizeof(*rp));
+
 	/* Just works */
 	memset(conn->tk, 0, sizeof(conn->tk));
 
 	conn->pres[0] = SMP_CMD_PAIRING_RSP;
 	memcpy(&conn->pres[1], rp, sizeof(*rp));
-	skb_pull(skb, sizeof(*rp));
 
 	ret = smp_rand(conn->prnd);
 	if (ret)
-		return;
+		return SMP_UNSPECIFIED;
 
 	ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->pres, 0,
 			conn->src, 0, conn->dst, res);
 	if (ret)
-		return;
+		return SMP_UNSPECIFIED;
 
 	swap128(res, cp.confirm_val);
 
 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
+
+	return 0;
 }
 
-static void smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
+static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 	struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
 
@@ -265,20 +293,22 @@ static void smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb
 
 		ret = smp_rand(conn->prnd);
 		if (ret)
-			return;
+			return SMP_UNSPECIFIED;
 
 		ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->pres,
 					0, conn->dst, 0, conn->src, res);
 		if (ret)
-			return;
+			return SMP_CONFIRM_FAILED;
 
 		swap128(res, cp.confirm_val);
 
 		smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
 	}
+
+	return 0;
 }
 
-static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 	struct hci_conn *hcon = conn->hcon;
 	struct crypto_blkcipher *tfm = hcon->hdev->tfm;
@@ -297,19 +327,15 @@ static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 		ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->pres, 0,
 				conn->dst, 0, conn->src, res);
 	if (ret)
-		return;
+		return SMP_UNSPECIFIED;
 
 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
 
 	swap128(res, confirm);
 
 	if (memcmp(conn->pcnf, confirm, sizeof(conn->pcnf)) != 0) {
-		struct smp_cmd_pairing_fail cp;
-
 		BT_ERR("Pairing failed (confirmation values mismatch)");
-		cp.reason = SMP_CONFIRM_FAILED;
-		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(cp), &cp);
-		return;
+		return SMP_CONFIRM_FAILED;
 	}
 
 	if (conn->hcon->out) {
@@ -332,9 +358,11 @@ static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 		hex_dump_to_buffer(key, sizeof(key), 16, 1, buf, sizeof(buf), 0);
 		BT_DBG("key %s", buf);
 	}
+
+	return 0;
 }
 
-static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
+static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 	struct smp_cmd_security_req *rp = (void *) skb->data;
 	struct smp_cmd_pairing cp;
@@ -343,17 +371,12 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	BT_DBG("conn %p", conn);
 
 	if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
-		return;
+		return 0;
 
 	skb_pull(skb, sizeof(*rp));
-	memset(&cp, 0, sizeof(cp));
 
-	cp.io_capability = 0x00;
-	cp.oob_flag = 0x00;
-	cp.max_key_size = 16;
-	cp.init_key_dist = 0x00;
-	cp.resp_key_dist = 0x00;
-	cp.auth_req = rp->auth_req & 0x05;
+	memset(&cp, 0, sizeof(cp));
+	build_pairing_cmd(conn, &cp, rp->auth_req);
 
 	conn->preq[0] = SMP_CMD_PAIRING_REQ;
 	memcpy(&conn->preq[1], &cp, sizeof(cp));
@@ -361,22 +384,8 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
 
 	set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
-}
-
-static __u8 seclevel_to_authreq(__u8 seclevel)
-{
-	switch (seclevel) {
-	case BT_SECURITY_MEDIUM:
-		/* Encrypted, no MITM protection */
-		return HCI_AT_NO_BONDING_MITM;
-
-	case BT_SECURITY_HIGH:
-		/* Bonding, MITM protection */
-		return HCI_AT_GENERAL_BONDING_MITM;
 
-	default:
-		return HCI_AT_NO_BONDING;
-	}
+	return 0;
 }
 
 int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
@@ -402,13 +411,8 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 
 	if (hcon->link_mode & HCI_LM_MASTER) {
 		struct smp_cmd_pairing cp;
-		cp.io_capability = 0x00;
-		cp.oob_flag = 0x00;
-		cp.max_key_size = 16;
-		cp.init_key_dist = 0x00;
-		cp.resp_key_dist = 0x00;
-		cp.auth_req = authreq;
 
+		build_pairing_cmd(conn, &cp, authreq);
 		conn->preq[0] = SMP_CMD_PAIRING_REQ;
 		memcpy(&conn->preq[1], &cp, sizeof(cp));
 
@@ -441,26 +445,28 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	switch (code) {
 	case SMP_CMD_PAIRING_REQ:
-		smp_cmd_pairing_req(conn, skb);
+		reason = smp_cmd_pairing_req(conn, skb);
 		break;
 
 	case SMP_CMD_PAIRING_FAIL:
+		reason = 0;
+		err = -EPERM;
 		break;
 
 	case SMP_CMD_PAIRING_RSP:
-		smp_cmd_pairing_rsp(conn, skb);
+		reason = smp_cmd_pairing_rsp(conn, skb);
 		break;
 
 	case SMP_CMD_SECURITY_REQ:
-		smp_cmd_security_req(conn, skb);
+		reason = smp_cmd_security_req(conn, skb);
 		break;
 
 	case SMP_CMD_PAIRING_CONFIRM:
-		smp_cmd_pairing_confirm(conn, skb);
+		reason = smp_cmd_pairing_confirm(conn, skb);
 		break;
 
 	case SMP_CMD_PAIRING_RANDOM:
-		smp_cmd_pairing_random(conn, skb);
+		reason = smp_cmd_pairing_random(conn, skb);
 		break;
 
 	case SMP_CMD_ENCRYPT_INFO:
-- 
1.7.4


^ permalink raw reply related

* [bluetooth-next -v2 21/24] Bluetooth: Update the security level when link is encrypted
From: Vinicius Costa Gomes @ 2011-02-11  1:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1297388349-14878-20-git-send-email-vinicius.gomes@openbossa.org>

If the pending security level is greater than the current security
level and the link is now encrypted, we should update the link
security level.

This is only useful for LE links, when the only event generated
when SMP is sucessful in the Encrypt Change event.
---
 include/net/bluetooth/hci_core.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 3859b74..5114122 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -679,6 +679,9 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encr
 	if (conn->sec_level == BT_SECURITY_SDP)
 		conn->sec_level = BT_SECURITY_LOW;
 
+	if (conn->pending_sec_level > conn->sec_level)
+		conn->sec_level = conn->pending_sec_level;
+
 	hci_proto_encrypt_cfm(conn, status, encrypt);
 
 	read_lock_bh(&hci_cb_list_lock);
-- 
1.7.4


^ permalink raw reply related

* [bluetooth-next -v2 20/24] Bluetooth: Fix initial security level of LE links
From: Vinicius Costa Gomes @ 2011-02-11  1:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1297388349-14878-20-git-send-email-vinicius.gomes@openbossa.org>

As the default security level (BT_SECURITY_SDP) doesn't make sense for
LE links, initialize LE links with something that makes sense.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 net/bluetooth/hci_conn.c  |    1 +
 net/bluetooth/hci_event.c |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 693771c..ee7dcdd 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -53,6 +53,7 @@ static void hci_le_connect(struct hci_conn *conn)
 	conn->state = BT_CONNECT;
 	conn->out = 1;
 	conn->link_mode |= HCI_LM_MASTER;
+	conn->sec_level = BT_SECURITY_LOW;
 
 	memset(&cp, 0, sizeof(cp));
 	cp.scan_interval = cpu_to_le16(0x0004);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 6d2ebf2..fece2ee 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2462,6 +2462,7 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff
 		goto unlock;
 	}
 
+	conn->sec_level = BT_SECURITY_LOW;
 	conn->handle = __le16_to_cpu(ev->handle);
 	conn->state = BT_CONNECTED;
 
-- 
1.7.4


^ permalink raw reply related

* [bluetooth-next -v2 19/24] Bluetooth: Add support for resuming socket when SMP is finished
From: Vinicius Costa Gomes @ 2011-02-11  1:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1297388349-14878-19-git-send-email-vinicius.gomes@openbossa.org>

This adds support for resuming the user space traffic when SMP
negotiation is complete.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 net/bluetooth/l2cap_core.c |   61 ++++++++++++++++++++++---------------------
 net/bluetooth/l2cap_sock.c |   17 ++++++++++++
 net/bluetooth/smp.c        |   44 +++++++++++++++++++++++--------
 3 files changed, 80 insertions(+), 42 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 82d20eb..530e531 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -668,6 +668,22 @@ clean:
 	bh_unlock_sock(parent);
 }
 
+static void l2cap_chan_ready(struct sock *sk)
+{
+	struct sock *parent = bt_sk(sk)->parent;
+
+	BT_DBG("sk %p, parent %p", sk, parent);
+
+	l2cap_pi(sk)->conf_state = 0;
+	l2cap_sock_clear_timer(sk);
+
+	sk->sk_state = BT_CONNECTED;
+	sk->sk_state_change(sk);
+
+	if (parent)
+		parent->sk_data_ready(parent, 0);
+}
+
 static void l2cap_conn_ready(struct l2cap_conn *conn)
 {
 	struct l2cap_chan_list *l = &conn->chan_list;
@@ -683,15 +699,11 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
 	for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
 		bh_lock_sock(sk);
 
-		if (conn->hcon->type == LE_LINK) {
-			l2cap_sock_clear_timer(sk);
-			sk->sk_state = BT_CONNECTED;
-			sk->sk_state_change(sk);
+		if (l2cap_pi(sk)->scid == L2CAP_CID_LE_DATA) {
 			if (smp_conn_security(conn, l2cap_pi(sk)->sec_level))
-				BT_DBG("Insufficient security");
-		}
+				l2cap_chan_ready(sk);
 
-		if (sk->sk_type != SOCK_SEQPACKET &&
+		} else if (sk->sk_type != SOCK_SEQPACKET &&
 				sk->sk_type != SOCK_STREAM) {
 			l2cap_sock_clear_timer(sk);
 			sk->sk_state = BT_CONNECTED;
@@ -1362,29 +1374,6 @@ int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
 	return size;
 }
 
-static void l2cap_chan_ready(struct sock *sk)
-{
-	struct sock *parent = bt_sk(sk)->parent;
-
-	BT_DBG("sk %p, parent %p", sk, parent);
-
-	l2cap_pi(sk)->conf_state = 0;
-	l2cap_sock_clear_timer(sk);
-
-	if (!parent) {
-		/* Outgoing channel.
-		 * Wake up socket sleeping on connect.
-		 */
-		sk->sk_state = BT_CONNECTED;
-		sk->sk_state_change(sk);
-	} else {
-		/* Incoming channel.
-		 * Wake up socket sleeping on accept.
-		 */
-		parent->sk_data_ready(parent, 0);
-	}
-}
-
 /* Copy frame to all raw sockets on that connection */
 static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
 {
@@ -3705,6 +3694,18 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
 	for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
 		bh_lock_sock(sk);
 
+		BT_DBG("sk->scid %d", l2cap_pi(sk)->scid);
+
+		if (l2cap_pi(sk)->scid == L2CAP_CID_LE_DATA) {
+			if (!status && encrypt) {
+				l2cap_pi(sk)->sec_level = hcon->sec_level;
+				l2cap_chan_ready(sk);
+			}
+
+			bh_unlock_sock(sk);
+			continue;
+		}
+
 		if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
 			bh_unlock_sock(sk);
 			continue;
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index a7eeacc..32211db 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -29,6 +29,7 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/l2cap.h>
+#include <net/bluetooth/smp.h>
 
 /* ---- L2CAP timers ---- */
 static void l2cap_sock_timeout(unsigned long arg)
@@ -613,6 +614,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
 {
 	struct sock *sk = sock->sk;
 	struct bt_security sec;
+	struct l2cap_conn *conn;
 	int len, err = 0;
 	u32 opt;
 
@@ -649,6 +651,21 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
 		}
 
 		l2cap_pi(sk)->sec_level = sec.level;
+
+		conn = l2cap_pi(sk)->conn;
+		if (conn && l2cap_pi(sk)->scid == L2CAP_CID_LE_DATA) {
+			if (!conn->hcon->out) {
+				err = -EINVAL;
+				break;
+			}
+
+			if (!smp_conn_security(conn, sec.level)) {
+				err = -EINVAL;
+				break;
+			}
+
+			sk->sk_state = BT_CONFIG;
+		}
 		break;
 
 	case BT_DEFER_SETUP:
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 22ac14f..98bb80a 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -338,9 +338,13 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 	struct smp_cmd_security_req *rp = (void *) skb->data;
 	struct smp_cmd_pairing cp;
+	struct hci_conn *hcon = conn->hcon;
 
 	BT_DBG("conn %p", conn);
 
+	if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
+		return;
+
 	skb_pull(skb, sizeof(*rp));
 	memset(&cp, 0, sizeof(cp));
 
@@ -355,6 +359,24 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	memcpy(&conn->preq[1], &cp, sizeof(cp));
 
 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
+
+	set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
+}
+
+static __u8 seclevel_to_authreq(__u8 seclevel)
+{
+	switch (seclevel) {
+	case BT_SECURITY_MEDIUM:
+		/* Encrypted, no MITM protection */
+		return HCI_AT_NO_BONDING_MITM;
+
+	case BT_SECURITY_HIGH:
+		/* Bonding, MITM protection */
+		return HCI_AT_GENERAL_BONDING_MITM;
+
+	default:
+		return HCI_AT_NO_BONDING;
+	}
 }
 
 int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
@@ -367,21 +389,16 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 	if (IS_ERR(hcon->hdev->tfm))
 		return PTR_ERR(hcon->hdev->tfm);
 
-	switch (sec_level) {
-	case BT_SECURITY_MEDIUM:
-		/* Encrypted, no MITM protection */
-		authreq = HCI_AT_NO_BONDING_MITM;
-		break;
+	if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
+		return -EINPROGRESS;
 
-	case BT_SECURITY_HIGH:
-		/* Bonding, MITM protection */
-		authreq = HCI_AT_GENERAL_BONDING_MITM;
-		break;
+	if (sec_level == BT_SECURITY_LOW)
+		return 1;
 
-	case BT_SECURITY_LOW:
-	default:
+	if (hcon->sec_level > sec_level)
 		return 1;
-	}
+
+	authreq = seclevel_to_authreq(sec_level);
 
 	if (hcon->link_mode & HCI_LM_MASTER) {
 		struct smp_cmd_pairing cp;
@@ -402,6 +419,9 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 		smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
 	}
 
+	hcon->pending_sec_level = sec_level;
+	set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
+
 	return 0;
 }
 
-- 
1.7.4


^ permalink raw reply related

* [bluetooth-next -v2 18/24] Bluetooth: Add support for LE Start Encryption
From: Vinicius Costa Gomes @ 2011-02-11  1:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1297388349-14878-18-git-send-email-vinicius.gomes@openbossa.org>

This adds support for starting SMP Phase 2 Encryption, when the initial
SMP negotiation is successful. This adds the LE Start Encryption and LE
Long Term Key Request commands and related events.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 include/net/bluetooth/hci.h      |   34 +++++++++++++++++++
 include/net/bluetooth/hci_core.h |    5 +++
 net/bluetooth/hci_conn.c         |   47 ++++++++++++++++++++++++++
 net/bluetooth/hci_event.c        |   67 ++++++++++++++++++++++++++++++++++++++
 net/bluetooth/smp.c              |    9 ++++-
 5 files changed, 161 insertions(+), 1 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index e756f82..46438f4 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -674,6 +674,33 @@ struct hci_cp_le_create_conn {
 
 #define HCI_OP_LE_CREATE_CONN_CANCEL	0x200e
 
+#define HCI_OP_LE_START_ENC		0x2019
+struct hci_cp_le_start_enc {
+	__le16	handle;
+	__u8	rand[8];
+	__le16	ediv;
+	__u8	ltk[16];
+} __packed;
+
+#define HCI_OP_LE_LTK_REPLY		0x201a
+struct hci_cp_le_ltk_reply {
+	__le16	handle;
+	__u8	ltk[16];
+} __packed;
+struct hci_rp_le_ltk_reply {
+	__u8	status;
+	__le16	handle;
+} __packed;
+
+#define HCI_OP_LE_LTK_NEG_REPLY		0x201b
+struct hci_cp_le_ltk_neg_reply {
+	__le16	handle;
+} __packed;
+struct hci_rp_le_ltk_neg_reply {
+	__u8	status;
+	__le16	handle;
+} __packed;
+
 /* ---- HCI Events ---- */
 #define HCI_EV_INQUIRY_COMPLETE		0x01
 
@@ -953,6 +980,13 @@ struct hci_ev_le_conn_complete {
 	__u8     clk_accurancy;
 } __packed;
 
+#define HCI_EV_LE_LTK_REQ		0x05
+struct hci_ev_le_ltk_req {
+	__le16	handle;
+	__u8	random[8];
+	__le16	ediv;
+} __packed;
+
 /* Internal events generated by Bluetooth stack */
 #define HCI_EV_STACK_INTERNAL	0xfd
 struct hci_ev_stack_internal {
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 4bfe38d..3859b74 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -225,6 +225,7 @@ struct hci_conn {
 	__u8		 io_capability;
 	__u8             power_save;
 	__u16            disc_timeout;
+	__u8		 ltk[16];
 	unsigned long	 pend;
 
 	__u8		remote_cap;
@@ -779,4 +780,8 @@ struct hci_sec_filter {
 
 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);
+
 #endif /* __HCI_CORE_H */
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index efcd2b5..693771c 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -183,6 +183,53 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
 	hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
 }
 
+void hci_le_start_enc(struct hci_conn *conn, u8 ltk[16])
+{
+	struct hci_dev *hdev = conn->hdev;
+	struct hci_cp_le_start_enc cp;
+
+	BT_DBG("%p", conn);
+
+	memset(&cp, 0, sizeof(cp));
+
+	cp.handle = cpu_to_le16(conn->handle);
+	memcpy(cp.ltk, ltk, sizeof(cp.ltk));
+
+	hci_send_cmd(hdev, HCI_OP_LE_START_ENC, sizeof(cp), &cp);
+}
+EXPORT_SYMBOL(hci_le_start_enc);
+
+void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16])
+{
+	struct hci_dev *hdev = conn->hdev;
+	struct hci_cp_le_ltk_reply cp;
+
+	BT_DBG("%p", conn);
+
+	memset(&cp, 0, sizeof(cp));
+
+	cp.handle = cpu_to_le16(conn->handle);
+	memcpy(cp.ltk, ltk, sizeof(ltk));
+
+	hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
+}
+EXPORT_SYMBOL(hci_le_ltk_reply);
+
+void hci_le_ltk_neg_reply(struct hci_conn *conn)
+{
+	struct hci_dev *hdev = conn->hdev;
+	struct hci_cp_le_ltk_neg_reply cp;
+
+	BT_DBG("%p", conn);
+
+	memset(&cp, 0, sizeof(cp));
+
+	cp.handle = cpu_to_le16(conn->handle);
+
+	hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(cp), &cp);
+}
+EXPORT_SYMBOL(hci_le_ltk_neg_reply);
+
 /* Device _must_ be locked */
 void hci_sco_setup(struct hci_conn *conn, __u8 status)
 {
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 74f04a2..6d2ebf2 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -796,6 +796,30 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
 	hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
 }
 
+static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	if (rp->status)
+		return;
+
+	hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
+}
+
+static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	if (rp->status)
+		return;
+
+	hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
+}
+
 static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
 {
 	BT_DBG("%s status 0x%x", hdev->name, status);
@@ -1163,6 +1187,11 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
 	hci_dev_unlock(hdev);
 }
 
+static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
+{
+	BT_DBG("%s status 0x%x", hdev->name, status);
+}
+
 static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	__u8 status = *((__u8 *) skb->data);
@@ -1727,6 +1756,14 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
 		hci_cc_le_read_buffer_size(hdev, skb);
 		break;
 
+	case HCI_OP_LE_LTK_REPLY:
+		hci_cc_le_ltk_reply(hdev, skb);
+		break;
+
+	case HCI_OP_LE_LTK_NEG_REPLY:
+		hci_cc_le_ltk_neg_reply(hdev, skb);
+		break;
+
 	default:
 		BT_DBG("%s opcode 0x%x", hdev->name, opcode);
 		break;
@@ -1802,6 +1839,10 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_cs_le_create_conn(hdev, ev->status);
 		break;
 
+	case HCI_OP_LE_START_ENC:
+		hci_cs_le_start_enc(hdev, ev->status);
+		break;
+
 	default:
 		BT_DBG("%s opcode 0x%x", hdev->name, opcode);
 		break;
@@ -2433,6 +2474,28 @@ unlock:
 	hci_dev_unlock(hdev);
 }
 
+static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
+						struct sk_buff *skb)
+{
+	struct hci_ev_le_ltk_req *ev = (void *) skb->data;
+	struct hci_cp_le_ltk_reply cp;
+	struct hci_conn *conn;
+
+	BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
+
+	hci_dev_lock(hdev);
+
+	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
+
+	memset(&cp, 0, sizeof(cp));
+	cp.handle = cpu_to_le16(conn->handle);
+	memcpy(cp.ltk, conn->ltk, sizeof(conn->ltk));
+
+	hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
+
+	hci_dev_unlock(hdev);
+}
+
 static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_ev_le_meta *le_ev = (void *) skb->data;
@@ -2444,6 +2507,10 @@ static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_le_conn_complete_evt(hdev, skb);
 		break;
 
+	case HCI_EV_LE_LTK_REQ:
+		hci_le_ltk_request_evt(hdev, skb);
+		break;
+
 	default:
 		break;
 	}
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index ddc4af6..22ac14f 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -280,13 +280,16 @@ static void smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb
 
 static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 {
-	struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
+	struct hci_conn *hcon = conn->hcon;
+	struct crypto_blkcipher *tfm = hcon->hdev->tfm;
 	int ret;
 	u8 key[16], res[16], random[16], confirm[16], buf[128];
 
 	swap128(skb->data, random);
 	skb_pull(skb, sizeof(random));
 
+	memset(hcon->ltk, 0, sizeof(hcon->ltk));
+
 	if (conn->hcon->out)
 		ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->pres, 0,
 				conn->src, 0, conn->dst, res);
@@ -311,6 +314,9 @@ static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	if (conn->hcon->out) {
 		smp_s1(tfm, conn->tk, random, conn->prnd, key);
+		swap128(key, hcon->ltk);
+
+		hci_le_start_enc(hcon, hcon->ltk);
 
 		hex_dump_to_buffer(key, sizeof(key), 16, 1, buf, sizeof(buf), 0);
 		BT_DBG("key %s", buf);
@@ -321,6 +327,7 @@ static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(r), r);
 
 		smp_s1(tfm, conn->tk, conn->prnd, random, key);
+		swap128(key, hcon->ltk);
 
 		hex_dump_to_buffer(key, sizeof(key), 16, 1, buf, sizeof(buf), 0);
 		BT_DBG("key %s", buf);
-- 
1.7.4


^ permalink raw reply related

* [bluetooth-next -v2 17/24] Bluetooth: Minor fix in SMP methods
From: Vinicius Costa Gomes @ 2011-02-11  1:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Briglia, Vinicius Costa Gomes
In-Reply-To: <1297388349-14878-17-git-send-email-vinicius.gomes@openbossa.org>

From: Anderson Briglia <anderson.briglia@openbossa.org>

Minor fix in smp_conn_security function.

Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 net/bluetooth/smp.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 2679a1b..ddc4af6 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -352,12 +352,13 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 
 int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 {
+	struct hci_conn *hcon = conn->hcon;
 	__u8 authreq;
 
-	BT_DBG("conn %p hcon %p level 0x%2.2x", conn, conn->hcon, sec_level);
+	BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
 
-	if (IS_ERR(conn->hcon->hdev->tfm))
-		return PTR_ERR(conn->hcon->hdev->tfm);
+	if (IS_ERR(hcon->hdev->tfm))
+		return PTR_ERR(hcon->hdev->tfm);
 
 	switch (sec_level) {
 	case BT_SECURITY_MEDIUM:
@@ -375,7 +376,7 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 		return 1;
 	}
 
-	if (conn->hcon->link_mode & HCI_LM_MASTER) {
+	if (hcon->link_mode & HCI_LM_MASTER) {
 		struct smp_cmd_pairing cp;
 		cp.io_capability = 0x00;
 		cp.oob_flag = 0x00;
-- 
1.7.4


^ permalink raw reply related

* [bluetooth-next -v2 16/24] Bluetooth: Add SMP confirmation checks methods
From: Vinicius Costa Gomes @ 2011-02-11  1:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Briglia, Vinicius Costa Gomes
In-Reply-To: <1297388349-14878-16-git-send-email-vinicius.gomes@openbossa.org>

From: Anderson Briglia <anderson.briglia@openbossa.org>

This patch includes support for generating and sending the random value
used to produce the confirmation value.

Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 include/net/bluetooth/l2cap.h |    1 +
 net/bluetooth/smp.c           |   92 ++++++++++++++++++++++++++++++++++------
 2 files changed, 79 insertions(+), 14 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index ceea46d..359dd1b 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -294,6 +294,7 @@ struct l2cap_conn {
 	__u8		pres[7];
 	__u8		prnd[16];
 	__u8		pcnf[16];
+	__u8		tk[16];
 
 	struct l2cap_chan_list chan_list;
 };
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 256eeef..2679a1b 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -203,6 +203,9 @@ static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	rp->resp_key_dist = 0x00;
 	rp->auth_req &= 0x05;
 
+	/* Just works */
+	memset(conn->tk, 0, sizeof(conn->tk));
+
 	conn->pres[0] = SMP_CMD_PAIRING_RSP;
 	memcpy(&conn->pres[1], rp, sizeof(*rp));
 
@@ -213,53 +216,114 @@ static void smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 	struct smp_cmd_pairing *rp = (void *) skb->data;
 	struct smp_cmd_pairing_confirm cp;
+	struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
+	int ret;
+	u8 res[16];
 
 	BT_DBG("conn %p", conn);
 
-	memset(&cp, 0, sizeof(cp));
+	/* Just works */
+	memset(conn->tk, 0, sizeof(conn->tk));
 
 	conn->pres[0] = SMP_CMD_PAIRING_RSP;
 	memcpy(&conn->pres[1], rp, sizeof(*rp));
 	skb_pull(skb, sizeof(*rp));
 
+	ret = smp_rand(conn->prnd);
+	if (ret)
+		return;
+
+	ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->pres, 0,
+			conn->src, 0, conn->dst, res);
+	if (ret)
+		return;
+
+	swap128(res, cp.confirm_val);
+
 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
 }
 
 static void smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
 {
+	struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
+
 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
 
-	if (conn->hcon->out) {
-		struct smp_cmd_pairing_random random;
+	memcpy(conn->pcnf, skb->data, sizeof(conn->pcnf));
+	skb_pull(skb, sizeof(conn->pcnf));
 
-		memset(&random, 0, sizeof(random));
+	if (conn->hcon->out) {
+		u8 random[16];
 
+		swap128(conn->prnd, random);
 		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random),
-								&random);
+								random);
 	} else {
-		struct smp_cmd_pairing_confirm confirm;
+		struct smp_cmd_pairing_confirm cp;
+		int ret;
+		u8 res[16];
 
-		memset(&confirm, 0, sizeof(confirm));
+		ret = smp_rand(conn->prnd);
+		if (ret)
+			return;
 
-		smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(confirm),
-								&confirm);
+		ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->pres,
+					0, conn->dst, 0, conn->src, res);
+		if (ret)
+			return;
+
+		swap128(res, cp.confirm_val);
+
+		smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
 	}
 }
 
 static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 {
-	struct smp_cmd_pairing_random cp;
+	struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
+	int ret;
+	u8 key[16], res[16], random[16], confirm[16], buf[128];
+
+	swap128(skb->data, random);
+	skb_pull(skb, sizeof(random));
+
+	if (conn->hcon->out)
+		ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->pres, 0,
+				conn->src, 0, conn->dst, res);
+	else
+		ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->pres, 0,
+				conn->dst, 0, conn->src, res);
+	if (ret)
+		return;
 
 	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
 
-	skb_pull(skb, sizeof(cp));
+	swap128(res, confirm);
+
+	if (memcmp(conn->pcnf, confirm, sizeof(conn->pcnf)) != 0) {
+		struct smp_cmd_pairing_fail cp;
+
+		BT_ERR("Pairing failed (confirmation values mismatch)");
+		cp.reason = SMP_CONFIRM_FAILED;
+		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(cp), &cp);
+		return;
+	}
 
 	if (conn->hcon->out) {
-		/* FIXME: start encryption */
+		smp_s1(tfm, conn->tk, random, conn->prnd, key);
+
+		hex_dump_to_buffer(key, sizeof(key), 16, 1, buf, sizeof(buf), 0);
+		BT_DBG("key %s", buf);
 	} else {
-		memset(&cp, 0, sizeof(cp));
+		u8 r[16];
+
+		swap128(conn->prnd, r);
+		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(r), r);
+
+		smp_s1(tfm, conn->tk, conn->prnd, random, key);
 
-		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(cp), &cp);
+		hex_dump_to_buffer(key, sizeof(key), 16, 1, buf, sizeof(buf), 0);
+		BT_DBG("key %s", buf);
 	}
 }
 
-- 
1.7.4


^ permalink raw reply related

* [bluetooth-next -v2 15/24] Bluetooth: Add SMP confirmation structs
From: Vinicius Costa Gomes @ 2011-02-11  1:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Briglia, Vinicius Costa Gomes
In-Reply-To: <1297388349-14878-15-git-send-email-vinicius.gomes@openbossa.org>

From: Anderson Briglia <anderson.briglia@openbossa.org>

This patch adds initial support for verifying the confirmation value
that the remote side has sent.

Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 include/net/bluetooth/l2cap.h |    5 +++++
 net/bluetooth/smp.c           |   17 +++++++++++++++++
 2 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 031e9cd..ceea46d 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -290,6 +290,11 @@ struct l2cap_conn {
 
 	__u8		disc_reason;
 
+	__u8		preq[7];
+	__u8		pres[7];
+	__u8		prnd[16];
+	__u8		pcnf[16];
+
 	struct l2cap_chan_list chan_list;
 };
 
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 80a3c7e..256eeef 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -192,6 +192,8 @@ static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	BT_DBG("conn %p", conn);
 
+	conn->preq[0] = SMP_CMD_PAIRING_REQ;
+	memcpy(&conn->preq[1], rp, sizeof(*rp));
 	skb_pull(skb, sizeof(*rp));
 
 	rp->io_capability = 0x00;
@@ -201,17 +203,25 @@ static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	rp->resp_key_dist = 0x00;
 	rp->auth_req &= 0x05;
 
+	conn->pres[0] = SMP_CMD_PAIRING_RSP;
+	memcpy(&conn->pres[1], rp, sizeof(*rp));
+
 	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp);
 }
 
 static void smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 {
+	struct smp_cmd_pairing *rp = (void *) skb->data;
 	struct smp_cmd_pairing_confirm cp;
 
 	BT_DBG("conn %p", conn);
 
 	memset(&cp, 0, sizeof(cp));
 
+	conn->pres[0] = SMP_CMD_PAIRING_RSP;
+	memcpy(&conn->pres[1], rp, sizeof(*rp));
+	skb_pull(skb, sizeof(*rp));
+
 	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
 }
 
@@ -270,6 +280,9 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	cp.resp_key_dist = 0x00;
 	cp.auth_req = rp->auth_req & 0x05;
 
+	conn->preq[0] = SMP_CMD_PAIRING_REQ;
+	memcpy(&conn->preq[1], &cp, sizeof(cp));
+
 	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
 }
 
@@ -306,6 +319,10 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 		cp.init_key_dist = 0x00;
 		cp.resp_key_dist = 0x00;
 		cp.auth_req = authreq;
+
+		conn->preq[0] = SMP_CMD_PAIRING_REQ;
+		memcpy(&conn->preq[1], &cp, sizeof(cp));
+
 		smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
 	} else {
 		struct smp_cmd_security_req cp;
-- 
1.7.4


^ permalink raw reply related

* [bluetooth-next -v2 14/24] Bluetooth: Add support for using the crypto subsystem
From: Vinicius Costa Gomes @ 2011-02-11  1:38 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes, Anderson Briglia
In-Reply-To: <1297388349-14878-14-git-send-email-vinicius.gomes@openbossa.org>

This will allow using the crypto subsystem for encrypting data. As SMP
(Security Manager Protocol) is implemented almost entirely on the host
side and the crypto module already implements the needed methods
(AES-128), it makes sense to use it.

This patch also adds a new Kconfig option to toggle the SMP support.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
---
 include/net/bluetooth/hci_core.h |    2 ++
 net/bluetooth/Kconfig            |   12 ++++++++++++
 net/bluetooth/hci_core.c         |   17 +++++++++++++++++
 net/bluetooth/smp.c              |   17 +++++++++++++++--
 4 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index d30b93c..4bfe38d 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -161,6 +161,8 @@ struct hci_dev {
 
 	__u16			init_last_cmd;
 
+	struct crypto_blkcipher	*tfm;
+
 	struct inquiry_cache	inq_cache;
 	struct hci_conn_hash	conn_hash;
 	struct list_head	blacklist;
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
index e45eae6..b08293b 100644
--- a/net/bluetooth/Kconfig
+++ b/net/bluetooth/Kconfig
@@ -43,6 +43,18 @@ config BT_L2CAP
 	  Say Y here to compile L2CAP support into the kernel or say M to
 	  compile it as module (l2cap).
 
+config BT_SMP
+	bool "Security Manager Protocol support"
+	depends on BT_L2CAP
+	select CRYPTO_BLKCIPHER
+	select CRYPTO_AES
+	help
+	  The Security Manager Protocol (SMP) is used for pairing and
+	  transport specific key distribution. The SMP is used on Low
+	  Energy devices to handle encrypted connections.
+
+	  Say Y here to compile SMP support into the kernel.
+
 config BT_SCO
 	tristate "SCO links support"
 	depends on BT
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 173bebd..c81dc17 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -41,6 +41,7 @@
 #include <linux/interrupt.h>
 #include <linux/notifier.h>
 #include <linux/rfkill.h>
+#include <linux/crypto.h>
 #include <net/sock.h>
 
 #include <asm/system.h>
@@ -1066,6 +1067,14 @@ int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
 	return 0;
 }
 
+static struct crypto_blkcipher *alloc_cypher(void)
+{
+#ifndef CONFIG_BT_SMP
+	return ERR_PTR(-ENOTSUPP);
+#endif
+	return crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
+}
+
 /* Register HCI device */
 int hci_register_dev(struct hci_dev *hdev)
 {
@@ -1142,6 +1151,11 @@ int hci_register_dev(struct hci_dev *hdev)
 	if (!hdev->workqueue)
 		goto nomem;
 
+	hdev->tfm = alloc_cypher();
+	if (IS_ERR(hdev->tfm))
+		BT_INFO("Failed to load transform for ecb(aes): %ld",
+							PTR_ERR(hdev->tfm));
+
 	hci_register_sysfs(hdev);
 
 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
@@ -1190,6 +1204,9 @@ int hci_unregister_dev(struct hci_dev *hdev)
 					!test_bit(HCI_SETUP, &hdev->flags))
 		mgmt_index_removed(hdev->id);
 
+	if (!IS_ERR(hdev->tfm))
+		crypto_free_blkcipher(hdev->tfm);
+
 	hci_notify(hdev, HCI_DEV_UNREG);
 
 	if (hdev->rfkill) {
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 479ff6b..80a3c7e 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -279,6 +279,9 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 
 	BT_DBG("conn %p hcon %p level 0x%2.2x", conn, conn->hcon, sec_level);
 
+	if (IS_ERR(conn->hcon->hdev->tfm))
+		return PTR_ERR(conn->hcon->hdev->tfm);
+
 	switch (sec_level) {
 	case BT_SECURITY_MEDIUM:
 		/* Encrypted, no MITM protection */
@@ -319,6 +322,12 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
 	__u8 reason;
 	int err = 0;
 
+	if (IS_ERR(conn->hcon->hdev->tfm)) {
+		err = PTR_ERR(conn->hcon->hdev->tfm);
+		reason = SMP_PAIRING_NOTSUPP;
+		goto done;
+	}
+
 	skb_pull(skb, sizeof(code));
 
 	switch (code) {
@@ -354,11 +363,15 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
 		BT_DBG("Unknown command code 0x%2.2x", code);
 
 		reason = SMP_CMD_NOTSUPP;
-		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
-								&reason);
 		err = -EOPNOTSUPP;
+		goto done;
 	}
 
+done:
+	if (reason)
+		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
+								&reason);
+
 	kfree_skb(skb);
 	return err;
 }
-- 
1.7.4


^ permalink raw reply related

* [bluetooth-next -v2 13/24] Bluetooth: LE SMP Cryptoolbox functions
From: Vinicius Costa Gomes @ 2011-02-11  1:38 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: Anderson Briglia, Anderson Lizardo, Bruna Moreira,
	Vinicius Costa Gomes
In-Reply-To: <1297388349-14878-13-git-send-email-vinicius.gomes@openbossa.org>

From: Anderson Briglia <anderson.briglia@openbossa.org>

This patch implements SMP crypto functions called ah, c1, s1 and e.
It also implements auxiliary functions. All These functions are needed
for SMP keys generation.

Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
Signed-off-by: Anderson Lizardo <anderson.lizardo@openbossa.org>
Signed-off-by: Bruna Moreira <bruna.moreira@openbossa.org>
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 net/bluetooth/smp.c |  122 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 122 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 9a75891..479ff6b 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -24,6 +24,128 @@
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/l2cap.h>
 #include <net/bluetooth/smp.h>
+#include <linux/crypto.h>
+#include <crypto/b128ops.h>
+
+static inline void swap128(u8 src[16], u8 dst[16])
+{
+	int i;
+	for (i = 0; i < 16; i++)
+		dst[15 - i] = src[i];
+}
+
+static inline void swap56(u8 src[7], u8 dst[7])
+{
+	int i;
+	for (i = 0; i < 7; i++)
+		dst[6 - i] = src[i];
+}
+
+static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
+{
+	struct blkcipher_desc desc;
+	struct scatterlist sg;
+	int err, iv_len;
+	unsigned char iv[128];
+
+	if (tfm == NULL) {
+		BT_ERR("tfm %p", tfm);
+		return -EINVAL;
+	}
+
+	desc.tfm = tfm;
+	desc.flags = 0;
+
+	err = crypto_blkcipher_setkey(tfm, k, 16);
+	if (err) {
+		BT_ERR("cipher setkey failed: %d", err);
+		return err;
+	}
+
+	sg_init_one(&sg, r, 16);
+
+	iv_len = crypto_blkcipher_ivsize(tfm);
+	if (iv_len) {
+		memset(&iv, 0xff, iv_len);
+		crypto_blkcipher_set_iv(tfm, iv, iv_len);
+	}
+
+	err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
+	if (err)
+		BT_ERR("Encrypt data error %d", err);
+
+	return err;
+}
+
+static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
+		u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
+		u8 _rat, bdaddr_t *ra, u8 res[16])
+{
+	u8 p1[16], p2[16], pair[7];
+	bdaddr_t addr;
+	int err;
+
+	/* p1 = pres || preq || _rat || _iat */
+	memset(p1, 0, 16);
+	swap56(pres, pair);
+
+	memcpy(p1, pair, 7);
+	swap56(preq, pair);
+
+	memcpy(p1 + 7, pair, 7);
+	*(p1 + 14) = _rat;
+	*(p1 + 15) = _iat;
+
+	/* p2 = padding || ia || ra */
+	memset(p2, 0, 16);
+	baswap(&addr, ia);
+	memcpy(p2 + 4, &addr, 6);
+	baswap(&addr, ra);
+	memcpy(p2 + 10, &addr, 6);
+
+	/* res = r XOR p1 */
+	u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
+
+	/* res = e(k, res) */
+	err = smp_e(tfm, k, res);
+	if (err) {
+		BT_ERR("Encrypt data error");
+		return err;
+	}
+
+	/* res = res XOR p2 */
+	u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
+
+	/* res = e(k, res) */
+	err = smp_e(tfm, k, res);
+	if (err)
+		BT_ERR("Encrypt data error");
+
+	return err;
+}
+
+static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16],
+			u8 r1[16], u8 r2[16], u8 _r[16])
+{
+	int err;
+
+	/* Just least significant octets from r1 and r2 are considered */
+	memcpy(_r, r1 + 8, 8);
+	memcpy(_r + 8, r2 + 8, 8);
+
+	err = smp_e(tfm, k, _r);
+	if (err)
+		BT_ERR("Encrypt data error");
+
+	return err;
+}
+
+static int smp_rand(u8 *buf)
+{
+	get_random_bytes(buf, 16);
+
+	return 0;
+}
 
 static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
 		u16 dlen, void *data)
-- 
1.7.4


^ permalink raw reply related

* [bluetooth-next -v2 12/24] Bluetooth: simple SMP pairing negotiation
From: Vinicius Costa Gomes @ 2011-02-11  1:38 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Briglia, Vinicius Costa Gomes
In-Reply-To: <1297388349-14878-12-git-send-email-vinicius.gomes@openbossa.org>

From: Anderson Briglia <anderson.briglia@openbossa.org>

This implementation only exchanges SMP messages between the Host and the
Remote. No keys are being generated. TK and STK generation will be
provided in further patches.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
 net/bluetooth/smp.c |  106 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 101 insertions(+), 5 deletions(-)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 8b67a56..9a75891 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -64,6 +64,93 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
 	hci_send_acl(conn->hcon, skb, 0);
 }
 
+static void smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+	struct smp_cmd_pairing *rp = (void *) skb->data;
+
+	BT_DBG("conn %p", conn);
+
+	skb_pull(skb, sizeof(*rp));
+
+	rp->io_capability = 0x00;
+	rp->oob_flag = 0x00;
+	rp->max_key_size = 16;
+	rp->init_key_dist = 0x00;
+	rp->resp_key_dist = 0x00;
+	rp->auth_req &= 0x05;
+
+	smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp);
+}
+
+static void smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+	struct smp_cmd_pairing_confirm cp;
+
+	BT_DBG("conn %p", conn);
+
+	memset(&cp, 0, sizeof(cp));
+
+	smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
+}
+
+static void smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
+
+	if (conn->hcon->out) {
+		struct smp_cmd_pairing_random random;
+
+		memset(&random, 0, sizeof(random));
+
+		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random),
+								&random);
+	} else {
+		struct smp_cmd_pairing_confirm confirm;
+
+		memset(&confirm, 0, sizeof(confirm));
+
+		smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(confirm),
+								&confirm);
+	}
+}
+
+static void smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+	struct smp_cmd_pairing_random cp;
+
+	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
+
+	skb_pull(skb, sizeof(cp));
+
+	if (conn->hcon->out) {
+		/* FIXME: start encryption */
+	} else {
+		memset(&cp, 0, sizeof(cp));
+
+		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(cp), &cp);
+	}
+}
+
+static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+	struct smp_cmd_security_req *rp = (void *) skb->data;
+	struct smp_cmd_pairing cp;
+
+	BT_DBG("conn %p", conn);
+
+	skb_pull(skb, sizeof(*rp));
+	memset(&cp, 0, sizeof(cp));
+
+	cp.io_capability = 0x00;
+	cp.oob_flag = 0x00;
+	cp.max_key_size = 16;
+	cp.init_key_dist = 0x00;
+	cp.resp_key_dist = 0x00;
+	cp.auth_req = rp->auth_req & 0x05;
+
+	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
+}
+
 int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
 {
 	__u8 authreq;
@@ -114,24 +201,33 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	switch (code) {
 	case SMP_CMD_PAIRING_REQ:
-		reason = SMP_PAIRING_NOTSUPP;
-		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
-								&reason);
-		err = -EOPNOTSUPP;
+		smp_cmd_pairing_req(conn, skb);
 		break;
 
 	case SMP_CMD_PAIRING_FAIL:
 		break;
 
 	case SMP_CMD_PAIRING_RSP:
+		smp_cmd_pairing_rsp(conn, skb);
+		break;
+
+	case SMP_CMD_SECURITY_REQ:
+		smp_cmd_security_req(conn, skb);
+		break;
+
 	case SMP_CMD_PAIRING_CONFIRM:
+		smp_cmd_pairing_confirm(conn, skb);
+		break;
+
 	case SMP_CMD_PAIRING_RANDOM:
+		smp_cmd_pairing_random(conn, skb);
+		break;
+
 	case SMP_CMD_ENCRYPT_INFO:
 	case SMP_CMD_MASTER_IDENT:
 	case SMP_CMD_IDENT_INFO:
 	case SMP_CMD_IDENT_ADDR_INFO:
 	case SMP_CMD_SIGN_INFO:
-	case SMP_CMD_SECURITY_REQ:
 	default:
 		BT_DBG("Unknown command code 0x%2.2x", code);
 
-- 
1.7.4


^ permalink raw reply related

* [bluetooth-next -v2 11/24] Bluetooth: Start SMP procedure
From: Vinicius Costa Gomes @ 2011-02-11  1:38 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Briglia, Vinicius Costa Gomes
In-Reply-To: <1297388349-14878-11-git-send-email-vinicius.gomes@openbossa.org>

From: Anderson Briglia <anderson.briglia@openbossa.org>

Start SMP procedure for LE connections. This modification intercepts
l2cap received frames and call proper SMP functions to start the SMP
procedure. By now, no keys are being used.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
---
 net/bluetooth/l2cap_core.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index ec81e2d..82d20eb 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -54,6 +54,7 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/l2cap.h>
+#include <net/bluetooth/smp.h>
 
 #define VERSION "2.15"
 
@@ -686,6 +687,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
 			l2cap_sock_clear_timer(sk);
 			sk->sk_state = BT_CONNECTED;
 			sk->sk_state_change(sk);
+			if (smp_conn_security(conn, l2cap_pi(sk)->sec_level))
+				BT_DBG("Insufficient security");
 		}
 
 		if (sk->sk_type != SOCK_SEQPACKET &&
@@ -3578,6 +3581,11 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
 		l2cap_conless_channel(conn, psm, skb);
 		break;
 
+	case L2CAP_CID_SMP:
+		if (smp_sig_channel(conn, skb))
+			l2cap_conn_del(conn->hcon, EACCES);
+		break;
+
 	default:
 		l2cap_data_channel(conn, cid, skb);
 		break;
-- 
1.7.4


^ permalink raw reply related

* [bluetooth-next -v2 10/24] Bluetooth: Implement the first SMP commands
From: Vinicius Costa Gomes @ 2011-02-11  1:38 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Briglia, Vinicius Costa Gomes
In-Reply-To: <1297388349-14878-10-git-send-email-vinicius.gomes@openbossa.org>

From: Anderson Briglia <anderson.briglia@openbossa.org>

These simple commands will allow the SMP procedure to be started
and terminated with a not supported error. This is the first step
toward something useful.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
---
 include/net/bluetooth/smp.h |   26 ++++++++
 net/bluetooth/Makefile      |    2 +-
 net/bluetooth/smp.c         |  146 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 173 insertions(+), 1 deletions(-)
 create mode 100644 net/bluetooth/smp.c

diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
index 8f2edbf..36bdd6e 100644
--- a/include/net/bluetooth/smp.h
+++ b/include/net/bluetooth/smp.h
@@ -1,3 +1,25 @@
+/*
+   BlueZ - Bluetooth protocol stack for Linux
+   Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License version 2 as
+   published by the Free Software Foundation;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
+   SOFTWARE IS DISCLAIMED.
+*/
+
 #ifndef __SMP_H
 #define __SMP_H
 
@@ -73,4 +95,8 @@ struct smp_cmd_security_req {
 #define SMP_UNSPECIFIED		0x08
 #define SMP_REPEATED_ATTEMPTS		0x09
 
+/* SMP Commands */
+int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level);
+int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb);
+
 #endif /* __SMP_H */
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index 339b429..cf6183c 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -11,4 +11,4 @@ obj-$(CONFIG_BT_CMTP)	+= cmtp/
 obj-$(CONFIG_BT_HIDP)	+= hidp/
 
 bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o
-l2cap-y := l2cap_core.o l2cap_sock.o
+l2cap-y := l2cap_core.o l2cap_sock.o smp.o
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
new file mode 100644
index 0000000..8b67a56
--- /dev/null
+++ b/net/bluetooth/smp.c
@@ -0,0 +1,146 @@
+/*
+   BlueZ - Bluetooth protocol stack for Linux
+   Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License version 2 as
+   published by the Free Software Foundation;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
+   SOFTWARE IS DISCLAIMED.
+*/
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/l2cap.h>
+#include <net/bluetooth/smp.h>
+
+static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
+		u16 dlen, void *data)
+{
+	struct sk_buff *skb;
+	struct l2cap_hdr *lh;
+	int len;
+
+	len = L2CAP_HDR_SIZE + sizeof(code) + dlen;
+
+	if (len > conn->mtu)
+		return NULL;
+
+	skb = bt_skb_alloc(len, GFP_ATOMIC);
+	if (!skb)
+		return NULL;
+
+	lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
+	lh->len = cpu_to_le16(sizeof(code) + dlen);
+	lh->cid = cpu_to_le16(L2CAP_CID_SMP);
+
+	memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code));
+
+	memcpy(skb_put(skb, dlen), data, dlen);
+
+	return skb;
+}
+
+static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
+{
+	struct sk_buff *skb = smp_build_cmd(conn, code, len, data);
+
+	BT_DBG("code 0x%2.2x", code);
+
+	if (!skb)
+		return;
+
+	hci_send_acl(conn->hcon, skb, 0);
+}
+
+int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
+{
+	__u8 authreq;
+
+	BT_DBG("conn %p hcon %p level 0x%2.2x", conn, conn->hcon, sec_level);
+
+	switch (sec_level) {
+	case BT_SECURITY_MEDIUM:
+		/* Encrypted, no MITM protection */
+		authreq = HCI_AT_NO_BONDING_MITM;
+		break;
+
+	case BT_SECURITY_HIGH:
+		/* Bonding, MITM protection */
+		authreq = HCI_AT_GENERAL_BONDING_MITM;
+		break;
+
+	case BT_SECURITY_LOW:
+	default:
+		return 1;
+	}
+
+	if (conn->hcon->link_mode & HCI_LM_MASTER) {
+		struct smp_cmd_pairing cp;
+		cp.io_capability = 0x00;
+		cp.oob_flag = 0x00;
+		cp.max_key_size = 16;
+		cp.init_key_dist = 0x00;
+		cp.resp_key_dist = 0x00;
+		cp.auth_req = authreq;
+		smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
+	} else {
+		struct smp_cmd_security_req cp;
+		cp.auth_req = authreq;
+		smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
+	}
+
+	return 0;
+}
+
+int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+	__u8 code = skb->data[0];
+	__u8 reason;
+	int err = 0;
+
+	skb_pull(skb, sizeof(code));
+
+	switch (code) {
+	case SMP_CMD_PAIRING_REQ:
+		reason = SMP_PAIRING_NOTSUPP;
+		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
+								&reason);
+		err = -EOPNOTSUPP;
+		break;
+
+	case SMP_CMD_PAIRING_FAIL:
+		break;
+
+	case SMP_CMD_PAIRING_RSP:
+	case SMP_CMD_PAIRING_CONFIRM:
+	case SMP_CMD_PAIRING_RANDOM:
+	case SMP_CMD_ENCRYPT_INFO:
+	case SMP_CMD_MASTER_IDENT:
+	case SMP_CMD_IDENT_INFO:
+	case SMP_CMD_IDENT_ADDR_INFO:
+	case SMP_CMD_SIGN_INFO:
+	case SMP_CMD_SECURITY_REQ:
+	default:
+		BT_DBG("Unknown command code 0x%2.2x", code);
+
+		reason = SMP_CMD_NOTSUPP;
+		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
+								&reason);
+		err = -EOPNOTSUPP;
+	}
+
+	kfree_skb(skb);
+	return err;
+}
-- 
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