Linux bluetooth development
 help / color / mirror / Atom feed
* RE: BUG in Mobile initiated pairing
From: sachin.athanikar @ 2011-02-17 14:40 UTC (permalink / raw)
  To: padovan; +Cc: linux-bluetooth
In-Reply-To: <20110217130322.GA10543@joana>

Hi Gustavo,
Many thanks for the response.

The property changed event "Paired" is not generated when the mobile initiated pairing is successful. So I am not able get an acknowledgement for successful completion of pairing process.

Thanks
Sachin

-----Original Message-----
From: Gustavo F. Padovan [mailto:pao@profusion.mobi] On Behalf Of Gustavo F. Padovan
Sent: Thursday, February 17, 2011 6:33 PM
To: Athanikar, Sachin
Cc: linux-bluetooth@vger.kernel.org
Subject: Re: BUG in Mobile initiated pairing

HI Sachin,

* sachin.athanikar@accenture.com <sachin.athanikar@accenture.com> [2011-02-17 14:17:47 +0530]:

> Hi Gustavo,
>
> I have a question on pairing.
>
> Is standard pairing working fine in BlueZ with all necessary events being generated?
>
> I am using blueZ 4.88 on Ubuntu 10.10.
>
> Adapter initiated pairing:
> -------------------------
> I am using agent.c which is part of test folder of BlueZ code base.
> Agent.c is used for adapter initiated pairing where I am able to get the response and event from BlueZ (observed in DBUS monitor).
>
>
> Mobile Phone initiated pairing:
> ------------------------------------------
> I have modified the agent.c in test folder of BlueZ to accept the mobile initiated pairing request.
>
> When the pairing is initiated from Mobile phone, after the successful pairing, the property changed event for "Paired" is not generated. And even the agent is not released.

The "Paired" is generated, and not releasing the agent is the usual behaviour
for this case.

--
Gustavo F. Padovan
http://profusion.mobi


This message is for the designated recipient only and may contain privileged, proprietary, or otherwise private information.  If you have received it in error, please notify the sender immediately and delete the original.  Any other use of the email by you is prohibited.

^ permalink raw reply

* Re: [PATCH 02/10] Bluetooth: Clean up hci_sniff_subrate_evt function
From: Gustavo F. Padovan @ 2011-02-17 14:30 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth, par-gunnar.p.hjalmdahl, henrik.possung
In-Reply-To: <1297948601-12723-3-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

* Szymon Janc <szymon.janc@tieto.com> [2011-02-17 14:16:33 +0100]:

> Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
> ---
>  net/bluetooth/hci_event.c |    9 ---------
>  1 files changed, 0 insertions(+), 9 deletions(-)

Good catch, applied as well. Thanks.

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* Re: [PATCH 01/10] Bluetooth: Use #include <linux/uaccess.h> instead of <asm/uaccess.h>
From: Gustavo F. Padovan @ 2011-02-17 14:29 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth, par-gunnar.p.hjalmdahl, henrik.possung
In-Reply-To: <1297948601-12723-2-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

* Szymon Janc <szymon.janc@tieto.com> [2011-02-17 14:16:32 +0100]:

> As warned by checkpatch.pl, use #include <linux/uaccess.h> instead of
> <asm/uaccess.h>.
> 
> Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
> ---
>  net/bluetooth/mgmt.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)

Applied, thanks.

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* Re: [PATCH 04/10] Bluetooth: Use EIO code to report HCI error to userpace
From: Szymon Janc @ 2011-02-17 14:23 UTC (permalink / raw)
  To: Ville Tervo
  Cc: linux-bluetooth@vger.kernel.org,
	par-gunnar.p.hjalmdahl@stericsson.com,
	henrik.possung@stericsson.com
In-Reply-To: <20110217134946.GY874@null>

Hi,

> On Thu, Feb 17, 2011 at 02:16:35PM +0100, ext Szymon Janc wrote:
> > Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
> > ---
> >  net/bluetooth/mgmt.c |    7 +++----
> >  1 files changed, 3 insertions(+), 4 deletions(-)
> 
> Some kind of explanation why EIO is better than status would be nice.

As I've mentioned in cover letter:
It is not possible to distinguish in cmd status if error was from kernel
or from HCI. Since in mgmt only kernel sends HCI commands their errors
shouldn't be needed for userspace so report EIO to userspace on HCI error
(if HCI error is needed for debugging, logs can be added on kernel side)

HCI status codes and kernel error codes overlaps  i.e. one can't distinguish
if error was ENOMEM or HCI Command Disallowed as both have value 12.

For userspace is should be enough to just know that HCI failed, not why.
(in fact, currently userspace is not able to determine error too...)

-- 
br
Szymon Janc

^ permalink raw reply

* Re: hidp_output_raw_report, HID_OUTPUT_REPORT and Sixaxis
From: Antonio Ospite @ 2011-02-17 14:19 UTC (permalink / raw)
  To: pascal@pabr.org
  Cc: linux-input, linux-bluetooth, Bastien Nocera, Marcel Holtmann,
	Jiri Kosina, Alan Ott
In-Reply-To: <id3cua$12v$2@dough.gmane.org>

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

On Tue, 30 Nov 2010 18:40:03 +0100
"pascal@pabr.org" <pascal@pabr.org> wrote:

Pascal, you were replying to linux-input only so some of the original
recipients missed your comments.

> Antonio Ospite wrote:
> > +++ b/net/bluetooth/hidp/core.c
> >  	case HID_OUTPUT_REPORT:
> > -		report_type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
> > +		report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_OUPUT;
> 
> > Is it only the Sixaxis which needs the output report as a SET_REPORT
> > operation, or the change above is an actual fix?
> 
> My understanding of the Bluetooth HID Profile specification [1],
> section 7.4.9, is that on the control channel DATA is only for
> responding to an incoming GET_REPORT.  Since Linux is the HID
> Host, it will probably never need to reply to a GET_REPORT.
> So your patch looks good.
>

OK, I managed to study [1] a little bit, so yes, I also think my patch
is acceptable right now, but just because as you note in another
message hidp_output_raw_report() is relying only on the control channel.
In section 7.9.1 there's no mention of DATA for Output reports on the
Control channel (see also Figure 11: SET_ Flow Chart).

So I am resending it, it shouldn't hurt.

> Note that usbhid_output_raw_report() seems to send OUTPUT
> reports as USB interrupt messages and FEATURE reports as
> USB SET_REPORT control messages, which makes sense too.
> It would be nice if hidraw behaved the same over USB and
> over Bluetooth.  Unfortunately I don't think you can drive
> the sixaxis leds with DATA on the Bluetooth interrupt channel.
>

However, even if my patch gets is, Output reports on the Sixaxis will
stop working again as soon as someone implements the behavior you are
suggesting, that is:
  Feature Report -> SET_REPORT on the Control channel
  Output Report  -> DATA on the Interrupt channel

So I am going to submit the hidp_output_raw_report() override in
hid-sony.c as well, does this sound OK?

> 
> [1] http://www.bluetooth.com/Specification%20Documents/HID_SPEC_V10.pdf
> 

Regards,
  Antonio

-- 
Antonio Ospite
http://ao2.it

PGP public key ID: 0x4553B001

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

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

^ permalink raw reply

* [PATCH v2 2/2] Use PSM value to select LE or BR/EDR transport on gatttool
From: Sheldon Demario @ 2011-02-17 14:18 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <1297952321-12523-1-git-send-email-sheldon.demario@openbossa.org>

Removes "le" parameter of gatt_connect() as well the global variables
used to store the le option. LE is now the default transport, if a PSM
value different than zero is given BR/EDR will be selected
---
 attrib/gatttool.c    |    9 +++------
 attrib/gatttool.h    |    2 +-
 attrib/interactive.c |   15 +++++++--------
 attrib/utils.c       |   13 +++++++------
 4 files changed, 18 insertions(+), 21 deletions(-)

diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 96dca5b..7478043 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -53,13 +53,12 @@ static int opt_start = 0x0001;
 static int opt_end = 0xffff;
 static int opt_handle = -1;
 static int opt_mtu = 0;
-static int opt_psm = 0x1f;
+static int opt_psm = 0;
 static gboolean opt_primary = FALSE;
 static gboolean opt_characteristics = FALSE;
 static gboolean opt_char_read = FALSE;
 static gboolean opt_listen = FALSE;
 static gboolean opt_char_desc = FALSE;
-static gboolean opt_le = FALSE;
 static gboolean opt_char_write = FALSE;
 static gboolean opt_char_write_req = FALSE;
 static gboolean opt_interactive = FALSE;
@@ -527,8 +526,6 @@ static GOptionEntry gatt_options[] = {
 		"Characteristics Descriptor Discovery", NULL },
 	{ "listen", 0, 0, G_OPTION_ARG_NONE, &opt_listen,
 		"Listen for notifications and indications", NULL },
-	{ "le", 0, 0, G_OPTION_ARG_NONE, &opt_le,
-		"Use Bluetooth Low Energy transport", NULL },
 	{ "interactive", 'I', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
 		&opt_interactive, "Use interactive mode", NULL },
 	{ NULL },
@@ -591,7 +588,7 @@ int main(int argc, char *argv[])
 	}
 
 	if (opt_interactive) {
-		interactive(opt_dst, opt_le);
+		interactive(opt_dst, opt_psm);
 		goto done;
 	}
 
@@ -616,7 +613,7 @@ int main(int argc, char *argv[])
 	}
 
 	chan = gatt_connect(opt_src, opt_dst, opt_sec_level,
-					opt_psm, opt_mtu, opt_le, connect_cb);
+					opt_psm, opt_mtu, connect_cb);
 	if (chan == NULL) {
 		got_error = TRUE;
 		goto done;
diff --git a/attrib/gatttool.h b/attrib/gatttool.h
index 1fc6a59..7eae18d 100644
--- a/attrib/gatttool.h
+++ b/attrib/gatttool.h
@@ -23,5 +23,5 @@
 
 int interactive(gchar *dst, gboolean le);
 GIOChannel *gatt_connect(const gchar *src, const gchar *dst,
-			const gchar *sec_level, int psm, int mtu, gboolean le,
+			const gchar *sec_level, int psm, int mtu,
 			BtIOConnect connect_cb);
diff --git a/attrib/interactive.c b/attrib/interactive.c
index 71e84bc..b851a40 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -45,9 +45,8 @@ static GString *prompt;
 static gchar *opt_src = NULL;
 static gchar *opt_dst = NULL;
 static gchar *opt_sec_level = NULL;
-static int opt_psm = 0x1f;
+static int opt_psm = 0;
 static int opt_mtu = 0;
-static gboolean opt_le = FALSE;
 
 static void cmd_help(int argcp, char **argvp);
 
@@ -74,10 +73,10 @@ static char *get_prompt(void)
 	else
 		g_string_append_printf(prompt, "[%17s]", "");
 
-	if (opt_le)
-		g_string_append(prompt, "[LE]");
-	else
+	if (opt_psm)
 		g_string_append(prompt, "[BR]");
+	else
+		g_string_append(prompt, "[LE]");
 
 	g_string_append(prompt, "> ");
 
@@ -146,7 +145,7 @@ static void cmd_connect(int argcp, char **argvp)
 
 	set_state(STATE_CONNECTING);
 	iochannel = gatt_connect(opt_src, opt_dst, opt_sec_level, opt_psm,
-						opt_mtu, opt_le, connect_cb);
+						opt_mtu, connect_cb);
 	if (iochannel == NULL)
 		set_state(STATE_DISCONNECTED);
 
@@ -247,7 +246,7 @@ static gboolean prompt_read(GIOChannel *chan, GIOCondition cond,
 	return TRUE;
 }
 
-int interactive(gchar *dst, gboolean le)
+int interactive(gchar *dst, int psm)
 {
 	GIOChannel *pchan;
 	gint events;
@@ -255,7 +254,7 @@ int interactive(gchar *dst, gboolean le)
 	opt_sec_level = strdup("low");
 
 	opt_dst = strdup(dst);
-	opt_le = le;
+	opt_psm = psm;
 
 	prompt = g_string_new(NULL);
 
diff --git a/attrib/utils.c b/attrib/utils.c
index 326c1e8..d648376 100644
--- a/attrib/utils.c
+++ b/attrib/utils.c
@@ -39,19 +39,20 @@
 #define ATT_MIN_MTU_L2CAP	48
 
 GIOChannel *gatt_connect(const gchar *src, const gchar *dst,
-			const gchar *sec_level, int psm, int mtu, gboolean le,
-			BtIOConnect connect_cb)
+				const gchar *sec_level, int psm, int mtu,
+				BtIOConnect connect_cb)
 {
 	GIOChannel *chan;
 	bdaddr_t sba, dba;
 	GError *err = NULL;
 	BtIOSecLevel sec;
+	int minimum_mtu;
 
 	/* This check is required because currently setsockopt() returns no
 	 * errors for MTU values smaller than the allowed minimum. */
-	if (mtu != 0 && mtu < (le ? ATT_MIN_MTU_LE : ATT_MIN_MTU_L2CAP)) {
-		g_printerr("MTU cannot be smaller than %d\n",
-				(le ? ATT_MIN_MTU_LE : ATT_MIN_MTU_L2CAP));
+	minimum_mtu = (psm ? ATT_MIN_MTU_L2CAP : ATT_MIN_MTU_LE);
+	if (mtu != 0 && mtu < minimum_mtu) {
+		g_printerr("MTU cannot be smaller than %d\n", minimum_mtu);
 		return NULL;
 	}
 
@@ -78,7 +79,7 @@ GIOChannel *gatt_connect(const gchar *src, const gchar *dst,
 	else
 		sec = BT_IO_SEC_LOW;
 
-	if (le)
+	if (psm == 0)
 		chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
 				BT_IO_OPT_SOURCE_BDADDR, &sba,
 				BT_IO_OPT_DEST_BDADDR, &dba,
-- 
1.7.1


^ permalink raw reply related

* [PATCH v2 1/2] Move do_connect() to a common file between interactive.c and gatttool.c
From: Sheldon Demario @ 2011-02-17 14:18 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <1297952321-12523-1-git-send-email-sheldon.demario@openbossa.org>

Since do_connect() is used in both interactive.c and gatttool.c
files, it was moved to a new file that should hold all common functions
---
 Makefile.am          |    3 +-
 attrib/gatttool.c    |   76 +++---------------------------------
 attrib/gatttool.h    |    4 +-
 attrib/interactive.c |   14 ++++++-
 attrib/utils.c       |  106 ++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 129 insertions(+), 74 deletions(-)
 create mode 100644 attrib/utils.c

diff --git a/Makefile.am b/Makefile.am
index 7e5d0ee..2a858cd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -182,7 +182,8 @@ bin_PROGRAMS += attrib/gatttool
 attrib_gatttool_SOURCES = attrib/gatttool.c attrib/att.c attrib/gatt.c \
 			  attrib/gattrib.c btio/btio.c \
 			  src/glib-helper.h src/glib-helper.c \
-			  attrib/gatttool.h attrib/interactive.c
+			  attrib/gatttool.h attrib/interactive.c \
+			  attrib/utils.c
 attrib_gatttool_LDADD = lib/libbluetooth.la @GLIB_LIBS@ @READLINE_LIBS@
 endif
 
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 38636f9..96dca5b 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -44,14 +44,10 @@
 #include "gatt.h"
 #include "gatttool.h"
 
-/* Minimum MTU for ATT connections */
-#define ATT_MIN_MTU_LE		23
-#define ATT_MIN_MTU_L2CAP	48
-
 static gchar *opt_src = NULL;
 static gchar *opt_dst = NULL;
 static gchar *opt_value = NULL;
-static gchar *opt_sec_level = "low";
+static gchar *opt_sec_level = NULL;
 static uuid_t *opt_uuid = NULL;
 static int opt_start = 0x0001;
 static int opt_end = 0xffff;
@@ -85,70 +81,6 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
 	}
 }
 
-GIOChannel *do_connect(gchar *dst, gboolean le, BtIOConnect connect_cb)
-{
-	GIOChannel *chan;
-	bdaddr_t sba, dba;
-	GError *err = NULL;
-	BtIOSecLevel sec_level;
-
-	/* This check is required because currently setsockopt() returns no
-	 * errors for MTU values smaller than the allowed minimum. */
-	if (opt_mtu != 0 && opt_mtu < (le ? ATT_MIN_MTU_LE : ATT_MIN_MTU_L2CAP)) {
-		g_printerr("MTU cannot be smaller than %d\n",
-				(le ? ATT_MIN_MTU_LE : ATT_MIN_MTU_L2CAP));
-		return NULL;
-	}
-
-	/* Remote device */
-	if (dst == NULL) {
-		g_printerr("Remote Bluetooth address required\n");
-		return NULL;
-	}
-	str2ba(dst, &dba);
-
-	/* Local adapter */
-	if (opt_src != NULL) {
-		if (!strncmp(opt_src, "hci", 3))
-			hci_devba(atoi(opt_src + 3), &sba);
-		else
-			str2ba(opt_src, &sba);
-	} else
-		bacpy(&sba, BDADDR_ANY);
-
-	if (strcmp(opt_sec_level, "medium") == 0)
-		sec_level = BT_IO_SEC_MEDIUM;
-	else if (strcmp(opt_sec_level, "high") == 0)
-		sec_level = BT_IO_SEC_HIGH;
-	else
-		sec_level = BT_IO_SEC_LOW;
-
-	if (le)
-		chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
-				BT_IO_OPT_SOURCE_BDADDR, &sba,
-				BT_IO_OPT_DEST_BDADDR, &dba,
-				BT_IO_OPT_CID, GATT_CID,
-				BT_IO_OPT_OMTU, opt_mtu,
-				BT_IO_OPT_SEC_LEVEL, sec_level,
-				BT_IO_OPT_INVALID);
-	else
-		chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
-				BT_IO_OPT_SOURCE_BDADDR, &sba,
-				BT_IO_OPT_DEST_BDADDR, &dba,
-				BT_IO_OPT_PSM, opt_psm,
-				BT_IO_OPT_OMTU, opt_mtu,
-				BT_IO_OPT_SEC_LEVEL, sec_level,
-				BT_IO_OPT_INVALID);
-
-	if (err) {
-		g_printerr("%s\n", err->message);
-		g_error_free(err);
-		return NULL;
-	}
-
-	return chan;
-}
-
 static void primary_all_cb(GSList *services, guint8 status, gpointer user_data)
 {
 	GSList *l;
@@ -625,6 +557,8 @@ int main(int argc, char *argv[])
 	GIOChannel *chan;
 	GSourceFunc callback;
 
+	opt_sec_level = strdup("low");
+
 	context = g_option_context_new(NULL);
 	g_option_context_add_main_entries(context, options, NULL);
 
@@ -681,7 +615,8 @@ int main(int argc, char *argv[])
 		goto done;
 	}
 
-	chan = do_connect(opt_dst, opt_le, connect_cb);
+	chan = gatt_connect(opt_src, opt_dst, opt_sec_level,
+					opt_psm, opt_mtu, opt_le, connect_cb);
 	if (chan == NULL) {
 		got_error = TRUE;
 		goto done;
@@ -710,6 +645,7 @@ done:
 	g_free(opt_src);
 	g_free(opt_dst);
 	g_free(opt_uuid);
+	g_free(opt_sec_level);
 
 	if (got_error)
 		exit(EXIT_FAILURE);
diff --git a/attrib/gatttool.h b/attrib/gatttool.h
index 2237330..1fc6a59 100644
--- a/attrib/gatttool.h
+++ b/attrib/gatttool.h
@@ -22,4 +22,6 @@
  */
 
 int interactive(gchar *dst, gboolean le);
-GIOChannel *do_connect(gchar *dst, gboolean le, BtIOConnect connect_cb);
+GIOChannel *gatt_connect(const gchar *src, const gchar *dst,
+			const gchar *sec_level, int psm, int mtu, gboolean le,
+			BtIOConnect connect_cb);
diff --git a/attrib/interactive.c b/attrib/interactive.c
index 02f31b7..71e84bc 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -42,7 +42,11 @@ static GAttrib *attrib = NULL;
 static GMainLoop *event_loop;
 static GString *prompt;
 
+static gchar *opt_src = NULL;
 static gchar *opt_dst = NULL;
+static gchar *opt_sec_level = NULL;
+static int opt_psm = 0x1f;
+static int opt_mtu = 0;
 static gboolean opt_le = FALSE;
 
 static void cmd_help(int argcp, char **argvp);
@@ -141,7 +145,8 @@ static void cmd_connect(int argcp, char **argvp)
 	}
 
 	set_state(STATE_CONNECTING);
-	iochannel = do_connect(opt_dst, opt_le, connect_cb);
+	iochannel = gatt_connect(opt_src, opt_dst, opt_sec_level, opt_psm,
+						opt_mtu, opt_le, connect_cb);
 	if (iochannel == NULL)
 		set_state(STATE_DISCONNECTED);
 
@@ -247,7 +252,9 @@ int interactive(gchar *dst, gboolean le)
 	GIOChannel *pchan;
 	gint events;
 
-	opt_dst = dst;
+	opt_sec_level = strdup("low");
+
+	opt_dst = strdup(dst);
 	opt_le = le;
 
 	prompt = g_string_new(NULL);
@@ -269,5 +276,8 @@ int interactive(gchar *dst, gboolean le)
 	g_main_loop_unref(event_loop);
 	g_string_free(prompt, TRUE);
 
+	g_free(opt_dst);
+	g_free(opt_sec_level);
+
 	return 0;
 }
diff --git a/attrib/utils.c b/attrib/utils.c
new file mode 100644
index 0000000..326c1e8
--- /dev/null
+++ b/attrib/utils.c
@@ -0,0 +1,106 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2011  Nokia Corporation
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <stdlib.h>
+#include <glib.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>
+#include <bluetooth/sdp.h>
+
+#include "gattrib.h"
+#include "gatt.h"
+#include "btio.h"
+#include "gatttool.h"
+
+/* Minimum MTU for ATT connections */
+#define ATT_MIN_MTU_LE		23
+#define ATT_MIN_MTU_L2CAP	48
+
+GIOChannel *gatt_connect(const gchar *src, const gchar *dst,
+			const gchar *sec_level, int psm, int mtu, gboolean le,
+			BtIOConnect connect_cb)
+{
+	GIOChannel *chan;
+	bdaddr_t sba, dba;
+	GError *err = NULL;
+	BtIOSecLevel sec;
+
+	/* This check is required because currently setsockopt() returns no
+	 * errors for MTU values smaller than the allowed minimum. */
+	if (mtu != 0 && mtu < (le ? ATT_MIN_MTU_LE : ATT_MIN_MTU_L2CAP)) {
+		g_printerr("MTU cannot be smaller than %d\n",
+				(le ? ATT_MIN_MTU_LE : ATT_MIN_MTU_L2CAP));
+		return NULL;
+	}
+
+	/* Remote device */
+	if (dst == NULL) {
+		g_printerr("Remote Bluetooth address required\n");
+		return NULL;
+	}
+	str2ba(dst, &dba);
+
+	/* Local adapter */
+	if (src != NULL) {
+		if (!strncmp(src, "hci", 3))
+			hci_devba(atoi(src + 3), &sba);
+		else
+			str2ba(src, &sba);
+	} else
+		bacpy(&sba, BDADDR_ANY);
+
+	if (strcmp(sec_level, "medium") == 0)
+		sec = BT_IO_SEC_MEDIUM;
+	else if (strcmp(sec_level, "high") == 0)
+		sec = BT_IO_SEC_HIGH;
+	else
+		sec = BT_IO_SEC_LOW;
+
+	if (le)
+		chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
+				BT_IO_OPT_SOURCE_BDADDR, &sba,
+				BT_IO_OPT_DEST_BDADDR, &dba,
+				BT_IO_OPT_CID, GATT_CID,
+				BT_IO_OPT_OMTU, mtu,
+				BT_IO_OPT_SEC_LEVEL, sec,
+				BT_IO_OPT_INVALID);
+	else
+		chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
+				BT_IO_OPT_SOURCE_BDADDR, &sba,
+				BT_IO_OPT_DEST_BDADDR, &dba,
+				BT_IO_OPT_PSM, psm,
+				BT_IO_OPT_OMTU, mtu,
+				BT_IO_OPT_SEC_LEVEL, sec,
+				BT_IO_OPT_INVALID);
+
+	if (err) {
+		g_printerr("%s\n", err->message);
+		g_error_free(err);
+		return NULL;
+	}
+
+	return chan;
+}
+
-- 
1.7.1


^ permalink raw reply related

* [PATCH v2 0/2] Clean up in the minimum mtu check
From: Sheldon Demario @ 2011-02-17 14:18 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

Just a little clean up in the minimum mtu check

Sheldon Demario (2):
  Move do_connect() to a common file between interactive.c and
    gatttool.c
  Use PSM value to select LE or BR/EDR transport on gatttool

 Makefile.am          |    3 +-
 attrib/gatttool.c    |   83 ++++-----------------------------------
 attrib/gatttool.h    |    4 +-
 attrib/interactive.c |   25 ++++++++----
 attrib/utils.c       |  107 ++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 137 insertions(+), 85 deletions(-)
 create mode 100644 attrib/utils.c


^ permalink raw reply

* Re: [PATCH 04/10] Bluetooth: Use EIO code to report HCI error to userpace
From: Ville Tervo @ 2011-02-17 13:49 UTC (permalink / raw)
  To: ext Szymon Janc; +Cc: linux-bluetooth, par-gunnar.p.hjalmdahl, henrik.possung
In-Reply-To: <1297948601-12723-5-git-send-email-szymon.janc@tieto.com>

Hi,

On Thu, Feb 17, 2011 at 02:16:35PM +0100, ext Szymon Janc wrote:
> Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
> ---
>  net/bluetooth/mgmt.c |    7 +++----
>  1 files changed, 3 insertions(+), 4 deletions(-)

Some kind of explanation why EIO is better than status would be nice.


> 
> diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
> index aee1da6..dee82fe 100644
> --- a/net/bluetooth/mgmt.c
> +++ b/net/bluetooth/mgmt.c
> @@ -1372,8 +1372,7 @@ int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
>  		return -ENOENT;
>  
>  	if (status != 0)
> -		err = cmd_status(cmd->sk, MGMT_OP_PIN_CODE_REPLY, status, NULL,
> -									0);
> +		err = cmd_status(cmd->sk, MGMT_OP_PIN_CODE_REPLY, EIO, NULL, 0);
>  	else
>  		err = cmd_complete(cmd->sk, MGMT_OP_PIN_CODE_REPLY,
>  						bdaddr, sizeof(*bdaddr));
> @@ -1394,8 +1393,8 @@ int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
>  		return -ENOENT;
>  
>  	if (status != 0)
> -		err = cmd_status(cmd->sk, MGMT_OP_PIN_CODE_NEG_REPLY, status,
> -								NULL, 0);
> +		err = cmd_status(cmd->sk, MGMT_OP_PIN_CODE_NEG_REPLY, EIO, NULL,
> +									0);
>  	else
>  		err = cmd_complete(cmd->sk, MGMT_OP_PIN_CODE_NEG_REPLY,
>  						bdaddr, sizeof(*bdaddr));

-- 
Ville

^ permalink raw reply

* Re: [RFC 2/7] Use memcpy to convert from network to host order on BE hosts
From: Claudio Takahasi @ 2011-02-17 13:46 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth
In-Reply-To: <AANLkTin2rQKfqQS4fKx47XYieM9O8FgCWYBPCVVqJ-2n@mail.gmail.com>

Hi Lizardo,

On Wed, Feb 16, 2011 at 3:02 PM, Anderson Lizardo
<anderson.lizardo@openbossa.org> wrote:
> Hi Claudio,
>
> On Fri, Feb 11, 2011 at 5:37 PM, Claudio Takahasi
> <claudio.takahasi@openbossa.org> wrote:
>> ---
>>  lib/bluetooth.h |    4 +---
>>  1 files changed, 1 insertions(+), 3 deletions(-)
>>
>> diff --git a/lib/bluetooth.h b/lib/bluetooth.h
>> index bc020ad..d8f36f8 100644
>> --- a/lib/bluetooth.h
>> +++ b/lib/bluetooth.h
>> @@ -127,9 +127,7 @@ static inline void btoh128(const uint128_t *src, uint128_t *dst)
>>  #define ntoh64(x) (x)
>>  static inline void ntoh128(const uint128_t *src, uint128_t *dst)
>>  {
>> -       int i;
>> -       for (i = 0; i < 16; i++)
>> -               dst->data[i] = src->data[i];
>> +       memcpy(dst, src, sizeof(uint128_t));
>>  }
>
> I believe this patch is harmless and can be already applied
> independently from other patches on this series, right?
>
> Regards,
> --
> Anderson Lizardo
> Instituto Nokia de Tecnologia - INdT
> Manaus - Brazil
>

Yes, it is harmless. I gonna remove this patch from this series and
also add extra comments to emphasize that it is not converting the
value, it just replace the for by a direct memory copy for BE hosts.

Br,
Claudio

^ permalink raw reply

* [RFCv2 4/4] Bluetooth: check adv_entries in hci_connect() for LE devices
From: anderson.briglia @ 2011-02-17 13:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andre Guedes

From: Andre Guedes <andre.guedes@openbossa.org>

In case we are connecting to a LE device, we need to check the adv_entries
in order to know the bdaddr_type of that device.
Additionally, hci_le_connect() was changed to handle the bdaddr_type
info.

Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
 net/bluetooth/hci_conn.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index e06b856..8166c83 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -45,7 +45,7 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 
-static void hci_le_connect(struct hci_conn *conn)
+static void hci_le_connect(struct hci_conn *conn, u8 bdaddr_type)
 {
 	struct hci_dev *hdev = conn->hdev;
 	struct hci_cp_le_create_conn cp;
@@ -59,6 +59,7 @@ static void hci_le_connect(struct hci_conn *conn)
 	cp.scan_interval = cpu_to_le16(0x0004);
 	cp.scan_window = cpu_to_le16(0x0004);
 	bacpy(&cp.peer_addr, &conn->dst);
+	cp.peer_addr_type = bdaddr_type;
 	cp.conn_interval_min = cpu_to_le16(0x0008);
 	cp.conn_interval_max = cpu_to_le16(0x0100);
 	cp.supervision_timeout = cpu_to_le16(0x0064);
@@ -463,8 +464,13 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
 			return ERR_PTR(-EBUSY);
 		if (IS_ERR(le))
 			return le;
-		if (le->state == BT_OPEN)
-			hci_le_connect(le);
+		if (le->state == BT_OPEN) {
+			struct adv_entry *entry = hci_find_adv_entry(hdev, dst);
+			if (!entry)
+				return ERR_PTR(-EHOSTUNREACH);
+
+			hci_le_connect(le, entry->bdaddr_type);
+		}
 
 		hci_conn_hold(le);
 
-- 
1.7.1


^ permalink raw reply related

* [RFCv2 3/4] Bluetooth: Use ERR_PTR to return error from hci_connect
From: anderson.briglia @ 2011-02-17 13:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ville Tervo

From: Ville Tervo <ville.tervo@nokia.com>

Use ERR_PRT mechanism to return error from hci_connect. This patch also
includes a change to return error if LE link exists already to remote host.

Signed-off-by: Ville Tervo <ville.tervo@nokia.com>
---
 net/bluetooth/hci_conn.c   |   12 +++++++-----
 net/bluetooth/l2cap_core.c |   10 ++++------
 net/bluetooth/sco.c        |    6 +++---
 3 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index ee7dcdd..e06b856 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -305,7 +305,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
 
 	conn = kzalloc(sizeof(struct hci_conn), GFP_ATOMIC);
 	if (!conn)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	bacpy(&conn->dst, dst);
 	conn->hdev  = hdev;
@@ -459,8 +459,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
 		le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
 		if (!le)
 			le = hci_conn_add(hdev, LE_LINK, dst);
-		if (!le)
-			return NULL;
+		else
+			return ERR_PTR(-EBUSY);
+		if (IS_ERR(le))
+			return le;
 		if (le->state == BT_OPEN)
 			hci_le_connect(le);
 
@@ -472,8 +474,8 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
 	acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
 	if (!acl) {
 		acl = hci_conn_add(hdev, ACL_LINK, dst);
-		if (!acl)
-			return NULL;
+		if (IS_ERR(acl))
+			return acl;
 	}
 
 	hci_conn_hold(acl);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 7f30c53..f85be1a 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -869,7 +869,7 @@ int l2cap_do_connect(struct sock *sk)
 	struct hci_conn *hcon;
 	struct hci_dev *hdev;
 	__u8 auth_type;
-	int err;
+	int err = 0;
 
 	BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
 							l2cap_pi(sk)->psm);
@@ -880,8 +880,6 @@ int l2cap_do_connect(struct sock *sk)
 
 	hci_dev_lock_bh(hdev);
 
-	err = -ENOMEM;
-
 	auth_type = l2cap_get_auth_type(sk);
 
 	if (l2cap_pi(sk)->dcid == L2CAP_CID_LE_DATA)
@@ -891,8 +889,10 @@ int l2cap_do_connect(struct sock *sk)
 		hcon = hci_connect(hdev, ACL_LINK, dst,
 					l2cap_pi(sk)->sec_level, auth_type);
 
-	if (!hcon)
+	if (IS_ERR(hcon)) {
+		err = PTR_ERR(hcon);
 		goto done;
+	}
 
 	conn = l2cap_conn_add(hcon, 0);
 	if (!conn) {
@@ -900,8 +900,6 @@ int l2cap_do_connect(struct sock *sk)
 		goto done;
 	}
 
-	err = 0;
-
 	/* Update source addr of the socket */
 	bacpy(src, conn->src);
 
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index c9348dd..26f2f04 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -190,16 +190,16 @@ static int sco_connect(struct sock *sk)
 
 	hci_dev_lock_bh(hdev);
 
-	err = -ENOMEM;
-
 	if (lmp_esco_capable(hdev) && !disable_esco)
 		type = ESCO_LINK;
 	else
 		type = SCO_LINK;
 
 	hcon = hci_connect(hdev, type, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING);
-	if (!hcon)
+	if (IS_ERR(hcon)) {
+		err = PTR_ERR(hcon);
 		goto done;
+	}
 
 	conn = sco_conn_add(hcon, 0);
 	if (!conn) {
-- 
1.7.1


^ permalink raw reply related

* [RFCv2 2/4] Bluetooth: LE advertising info caching
From: anderson.briglia @ 2011-02-17 13:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andre Guedes

From: Andre Guedes <andre.guedes@openbossa.org>

This patch implements a fixed-size circular list to store sensitive
information (bdaddr and bdaddr_type so far) gathered from LE
advertising report events.

The fixed-size circular list has max size equal to 64. Once the buffer
reaches its max size, new advertising entries will replace old ones.

Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
 include/net/bluetooth/hci_core.h |   17 +++++++++
 net/bluetooth/hci_core.c         |   75 ++++++++++++++++++++++++++++++++++++++
 net/bluetooth/hci_event.c        |    5 +--
 3 files changed, 94 insertions(+), 3 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 5114122..5992148 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -82,6 +82,18 @@ struct link_key {
 	u8 pin_len;
 };
 
+struct adv_entry {
+	struct list_head list;
+	bdaddr_t bdaddr;
+	u8 bdaddr_type;
+};
+
+#define ADV_LIST_MAX_SIZE 64
+struct adv_list {
+	struct list_head list;
+	size_t size;
+};
+
 #define NUM_REASSEMBLY 4
 struct hci_dev {
 	struct list_head list;
@@ -171,6 +183,8 @@ struct hci_dev {
 
 	struct list_head	link_keys;
 
+	struct adv_list		adv_entries;
+
 	struct hci_dev_stats	stat;
 
 	struct sk_buff_head	driver_init;
@@ -504,6 +518,9 @@ int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
 						u8 *key, u8 type, u8 pin_len);
 int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
 
+struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr);
+int hci_add_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type);
+
 void hci_del_off_timer(struct hci_dev *hdev);
 
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 013baf9..0d0598b 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1067,6 +1067,78 @@ int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
 	return 0;
 }
 
+static inline void hci_adv_entries_init(struct hci_dev *hdev)
+{
+	hdev->adv_entries.size = 0;
+	INIT_LIST_HEAD(&hdev->adv_entries.list);
+}
+
+static int hci_adv_entries_clear(struct hci_dev *hdev)
+{
+	struct list_head *p, *n;
+
+	list_for_each_safe(p, n, &hdev->adv_entries.list) {
+		struct adv_entry *entry;
+
+		entry = list_entry(p, struct adv_entry, list);
+
+		list_del(p);
+		kfree(entry);
+	}
+
+	hdev->adv_entries.size = 0;
+	return 0;
+
+}
+
+struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr)
+{
+	struct list_head *p;
+
+	list_for_each(p, &hdev->adv_entries.list) {
+		struct adv_entry *k;
+
+		k = list_entry(p, struct adv_entry, list);
+
+		if (bacmp(bdaddr, &k->bdaddr) == 0)
+			return k;
+	}
+
+	return NULL;
+}
+
+int hci_add_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
+{
+	struct adv_entry *entry;
+
+	entry = hci_find_adv_entry(hdev, bdaddr);
+	/* Only new entries should be added to adv_entries. So, if
+	 * bdaddr was found, don't add it. */
+	if (entry)
+		return 0;
+
+	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
+	if (!entry)
+		return -ENOMEM;
+
+	BT_DBG(": %s type %d", batostr(bdaddr), bdaddr_type);
+
+	bacpy(&entry->bdaddr, bdaddr);
+	entry->bdaddr_type = bdaddr_type;
+
+	if (hdev->adv_entries.size < ADV_LIST_MAX_SIZE) {
+		hdev->adv_entries.size += 1;
+	} else {
+		struct list_head *head = &hdev->adv_entries.list;
+		struct list_head *tail = head->prev;
+		list_del(tail);
+	}
+
+	list_add(&entry->list, &hdev->adv_entries.list);
+
+	return 0;
+}
+
 static struct crypto_blkcipher *alloc_cypher(void)
 {
 #ifndef CONFIG_BT_SMP
@@ -1137,6 +1209,8 @@ int hci_register_dev(struct hci_dev *hdev)
 
 	INIT_LIST_HEAD(&hdev->link_keys);
 
+	hci_adv_entries_init(hdev);
+
 	INIT_WORK(&hdev->power_on, hci_power_on);
 	INIT_WORK(&hdev->power_off, hci_power_off);
 	setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev);
@@ -1224,6 +1298,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
 	hci_blacklist_clear(hdev);
 	hci_uuids_clear(hdev);
 	hci_link_keys_clear(hdev);
+	hci_adv_entries_clear(hdev);
 	hci_dev_unlock_bh(hdev);
 
 	__hci_dev_put(hdev);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 1c8d888..3111648 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2507,12 +2507,11 @@ static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
 	num_reports = skb->data[0];
 
 	ev = (void *) &skb->data[1];
-
-	BT_DBG("adv from: %s", batostr(&ev->bdaddr));
+	hci_add_adv_entry(hdev, &ev->bdaddr, ev->bdaddr_type);
 
 	for (i = 1; i < num_reports; i++) {
 		ev = (void *) (ev->data + ev->length + 1);
-		BT_DBG("adv from: %s", batostr(&ev->bdaddr));
+		hci_add_adv_entry(hdev, &ev->bdaddr, ev->bdaddr_type);
 	}
 }
 
-- 
1.7.1


^ permalink raw reply related

* [RFCv2 1/4] Bluetooth: Implement advertising report meta event
From: anderson.briglia @ 2011-02-17 13:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Briglia

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

This patch implements new LE meta event in order to handle advertising
reports.

Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
---
 include/net/bluetooth/hci.h |   18 ++++++++++++++++++
 net/bluetooth/hci_event.c   |   22 ++++++++++++++++++++++
 2 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 46438f4..5180555 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -980,6 +980,24 @@ struct hci_ev_le_conn_complete {
 	__u8     clk_accurancy;
 } __packed;
 
+#define ADV_IND		0x00
+#define ADV_DIRECT_IND	0x01
+#define ADV_SCAN_IND	0x02
+#define ADV_NONCONN_IND	0x03
+#define SCAN_RSP	0x04
+
+#define ADDR_DEV_PUBLIC	0x00
+#define ADDR_DEV_RANDOM	0x01
+
+#define HCI_EV_LE_ADVERTISING_REPORT	0x02
+struct hci_ev_le_advertising_info {
+	__u8	 evt_type;
+	__u8	 bdaddr_type;
+	bdaddr_t bdaddr;
+	__u8	 length;
+	__u8	 data[0];
+} __packed;
+
 #define HCI_EV_LE_LTK_REQ		0x05
 struct hci_ev_le_ltk_req {
 	__le16	handle;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 99c75f4..1c8d888 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2498,6 +2498,24 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
 	hci_dev_unlock(hdev);
 }
 
+static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
+						struct sk_buff *skb)
+{
+	struct hci_ev_le_advertising_info *ev;
+	u8 num_reports, i;
+
+	num_reports = skb->data[0];
+
+	ev = (void *) &skb->data[1];
+
+	BT_DBG("adv from: %s", batostr(&ev->bdaddr));
+
+	for (i = 1; i < num_reports; i++) {
+		ev = (void *) (ev->data + ev->length + 1);
+		BT_DBG("adv from: %s", batostr(&ev->bdaddr));
+	}
+}
+
 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;
@@ -2513,6 +2531,10 @@ static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_le_ltk_request_evt(hdev, skb);
 		break;
 
+	case HCI_EV_LE_ADVERTISING_REPORT:
+		hci_le_adv_report_evt(hdev, skb);
+		break;
+
 	default:
 		break;
 	}
-- 
1.7.1


^ permalink raw reply related

* [RFCv2 0/4] Advertising reports cache
From: anderson.briglia @ 2011-02-17 13:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Briglia

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

The following patches implement a list for advertising report events from LE
devices in order to store the bdaddr and bdaddr type.
Next steps include remove all advertising reports cache from userspace and
implement a mechanism to sync kernel advertising cache and userspace adv cache.

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

Anderson Briglia (1):
  Bluetooth: Implement advertising report meta event

Andre Guedes (2):
  Bluetooth: LE advertising info caching
  Bluetooth: check adv_entries in hci_connect() for LE devices

Ville Tervo (1):
  Bluetooth: Use ERR_PTR to return error from hci_connect

 include/net/bluetooth/hci.h      |   18 +++++++++
 include/net/bluetooth/hci_core.h |   17 +++++++++
 net/bluetooth/hci_conn.c         |   24 ++++++++----
 net/bluetooth/hci_core.c         |   75 ++++++++++++++++++++++++++++++++++++++
 net/bluetooth/hci_event.c        |   21 +++++++++++
 net/bluetooth/l2cap_core.c       |   10 ++---
 net/bluetooth/sco.c              |    6 ++--
 7 files changed, 154 insertions(+), 17 deletions(-)


^ permalink raw reply

* [PATCH 2/2] Use PSM value to select LE or BR/EDR transport on gatttool
From: Sheldon Demario @ 2011-02-17 13:25 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <1297949120-5720-1-git-send-email-sheldon.demario@openbossa.org>

Removes "le" parameter of gatt_connect() as well the global variables
used to store the le option. LE is now the default transport, if a PSM
value different than zero is given BR/EDR will be selected
---
 attrib/gatttool.c    |    9 +++------
 attrib/gatttool.h    |    2 +-
 attrib/interactive.c |   15 +++++++--------
 attrib/utils.c       |   10 +++++-----
 4 files changed, 16 insertions(+), 20 deletions(-)

diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 96dca5b..7478043 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -53,13 +53,12 @@ static int opt_start = 0x0001;
 static int opt_end = 0xffff;
 static int opt_handle = -1;
 static int opt_mtu = 0;
-static int opt_psm = 0x1f;
+static int opt_psm = 0;
 static gboolean opt_primary = FALSE;
 static gboolean opt_characteristics = FALSE;
 static gboolean opt_char_read = FALSE;
 static gboolean opt_listen = FALSE;
 static gboolean opt_char_desc = FALSE;
-static gboolean opt_le = FALSE;
 static gboolean opt_char_write = FALSE;
 static gboolean opt_char_write_req = FALSE;
 static gboolean opt_interactive = FALSE;
@@ -527,8 +526,6 @@ static GOptionEntry gatt_options[] = {
 		"Characteristics Descriptor Discovery", NULL },
 	{ "listen", 0, 0, G_OPTION_ARG_NONE, &opt_listen,
 		"Listen for notifications and indications", NULL },
-	{ "le", 0, 0, G_OPTION_ARG_NONE, &opt_le,
-		"Use Bluetooth Low Energy transport", NULL },
 	{ "interactive", 'I', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
 		&opt_interactive, "Use interactive mode", NULL },
 	{ NULL },
@@ -591,7 +588,7 @@ int main(int argc, char *argv[])
 	}
 
 	if (opt_interactive) {
-		interactive(opt_dst, opt_le);
+		interactive(opt_dst, opt_psm);
 		goto done;
 	}
 
@@ -616,7 +613,7 @@ int main(int argc, char *argv[])
 	}
 
 	chan = gatt_connect(opt_src, opt_dst, opt_sec_level,
-					opt_psm, opt_mtu, opt_le, connect_cb);
+					opt_psm, opt_mtu, connect_cb);
 	if (chan == NULL) {
 		got_error = TRUE;
 		goto done;
diff --git a/attrib/gatttool.h b/attrib/gatttool.h
index 1fc6a59..7eae18d 100644
--- a/attrib/gatttool.h
+++ b/attrib/gatttool.h
@@ -23,5 +23,5 @@
 
 int interactive(gchar *dst, gboolean le);
 GIOChannel *gatt_connect(const gchar *src, const gchar *dst,
-			const gchar *sec_level, int psm, int mtu, gboolean le,
+			const gchar *sec_level, int psm, int mtu,
 			BtIOConnect connect_cb);
diff --git a/attrib/interactive.c b/attrib/interactive.c
index 71e84bc..b851a40 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -45,9 +45,8 @@ static GString *prompt;
 static gchar *opt_src = NULL;
 static gchar *opt_dst = NULL;
 static gchar *opt_sec_level = NULL;
-static int opt_psm = 0x1f;
+static int opt_psm = 0;
 static int opt_mtu = 0;
-static gboolean opt_le = FALSE;
 
 static void cmd_help(int argcp, char **argvp);
 
@@ -74,10 +73,10 @@ static char *get_prompt(void)
 	else
 		g_string_append_printf(prompt, "[%17s]", "");
 
-	if (opt_le)
-		g_string_append(prompt, "[LE]");
-	else
+	if (opt_psm)
 		g_string_append(prompt, "[BR]");
+	else
+		g_string_append(prompt, "[LE]");
 
 	g_string_append(prompt, "> ");
 
@@ -146,7 +145,7 @@ static void cmd_connect(int argcp, char **argvp)
 
 	set_state(STATE_CONNECTING);
 	iochannel = gatt_connect(opt_src, opt_dst, opt_sec_level, opt_psm,
-						opt_mtu, opt_le, connect_cb);
+						opt_mtu, connect_cb);
 	if (iochannel == NULL)
 		set_state(STATE_DISCONNECTED);
 
@@ -247,7 +246,7 @@ static gboolean prompt_read(GIOChannel *chan, GIOCondition cond,
 	return TRUE;
 }
 
-int interactive(gchar *dst, gboolean le)
+int interactive(gchar *dst, int psm)
 {
 	GIOChannel *pchan;
 	gint events;
@@ -255,7 +254,7 @@ int interactive(gchar *dst, gboolean le)
 	opt_sec_level = strdup("low");
 
 	opt_dst = strdup(dst);
-	opt_le = le;
+	opt_psm = psm;
 
 	prompt = g_string_new(NULL);
 
diff --git a/attrib/utils.c b/attrib/utils.c
index 326c1e8..914e05a 100644
--- a/attrib/utils.c
+++ b/attrib/utils.c
@@ -39,8 +39,8 @@
 #define ATT_MIN_MTU_L2CAP	48
 
 GIOChannel *gatt_connect(const gchar *src, const gchar *dst,
-			const gchar *sec_level, int psm, int mtu, gboolean le,
-			BtIOConnect connect_cb)
+				const gchar *sec_level, int psm, int mtu,
+				BtIOConnect connect_cb)
 {
 	GIOChannel *chan;
 	bdaddr_t sba, dba;
@@ -49,9 +49,9 @@ GIOChannel *gatt_connect(const gchar *src, const gchar *dst,
 
 	/* This check is required because currently setsockopt() returns no
 	 * errors for MTU values smaller than the allowed minimum. */
-	if (mtu != 0 && mtu < (le ? ATT_MIN_MTU_LE : ATT_MIN_MTU_L2CAP)) {
+	if (mtu != 0 && mtu < (!psm ? ATT_MIN_MTU_LE : ATT_MIN_MTU_L2CAP)) {
 		g_printerr("MTU cannot be smaller than %d\n",
-				(le ? ATT_MIN_MTU_LE : ATT_MIN_MTU_L2CAP));
+				(!psm ? ATT_MIN_MTU_LE : ATT_MIN_MTU_L2CAP));
 		return NULL;
 	}
 
@@ -78,7 +78,7 @@ GIOChannel *gatt_connect(const gchar *src, const gchar *dst,
 	else
 		sec = BT_IO_SEC_LOW;
 
-	if (le)
+	if (psm == 0)
 		chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
 				BT_IO_OPT_SOURCE_BDADDR, &sba,
 				BT_IO_OPT_DEST_BDADDR, &dba,
-- 
1.7.1


^ permalink raw reply related

* [PATCH 1/2] Move do_connect() to a common file between interactive.c and gatttool.c
From: Sheldon Demario @ 2011-02-17 13:25 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

Since do_connect() is used in both interactive.c and gatttool.c
files, it was moved to a new file that should hold all common functions
---
 Makefile.am          |    3 +-
 attrib/gatttool.c    |   76 +++---------------------------------
 attrib/gatttool.h    |    4 +-
 attrib/interactive.c |   14 ++++++-
 attrib/utils.c       |  106 ++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 129 insertions(+), 74 deletions(-)
 create mode 100644 attrib/utils.c

diff --git a/Makefile.am b/Makefile.am
index 7e5d0ee..2a858cd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -182,7 +182,8 @@ bin_PROGRAMS += attrib/gatttool
 attrib_gatttool_SOURCES = attrib/gatttool.c attrib/att.c attrib/gatt.c \
 			  attrib/gattrib.c btio/btio.c \
 			  src/glib-helper.h src/glib-helper.c \
-			  attrib/gatttool.h attrib/interactive.c
+			  attrib/gatttool.h attrib/interactive.c \
+			  attrib/utils.c
 attrib_gatttool_LDADD = lib/libbluetooth.la @GLIB_LIBS@ @READLINE_LIBS@
 endif
 
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 38636f9..96dca5b 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -44,14 +44,10 @@
 #include "gatt.h"
 #include "gatttool.h"
 
-/* Minimum MTU for ATT connections */
-#define ATT_MIN_MTU_LE		23
-#define ATT_MIN_MTU_L2CAP	48
-
 static gchar *opt_src = NULL;
 static gchar *opt_dst = NULL;
 static gchar *opt_value = NULL;
-static gchar *opt_sec_level = "low";
+static gchar *opt_sec_level = NULL;
 static uuid_t *opt_uuid = NULL;
 static int opt_start = 0x0001;
 static int opt_end = 0xffff;
@@ -85,70 +81,6 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
 	}
 }
 
-GIOChannel *do_connect(gchar *dst, gboolean le, BtIOConnect connect_cb)
-{
-	GIOChannel *chan;
-	bdaddr_t sba, dba;
-	GError *err = NULL;
-	BtIOSecLevel sec_level;
-
-	/* This check is required because currently setsockopt() returns no
-	 * errors for MTU values smaller than the allowed minimum. */
-	if (opt_mtu != 0 && opt_mtu < (le ? ATT_MIN_MTU_LE : ATT_MIN_MTU_L2CAP)) {
-		g_printerr("MTU cannot be smaller than %d\n",
-				(le ? ATT_MIN_MTU_LE : ATT_MIN_MTU_L2CAP));
-		return NULL;
-	}
-
-	/* Remote device */
-	if (dst == NULL) {
-		g_printerr("Remote Bluetooth address required\n");
-		return NULL;
-	}
-	str2ba(dst, &dba);
-
-	/* Local adapter */
-	if (opt_src != NULL) {
-		if (!strncmp(opt_src, "hci", 3))
-			hci_devba(atoi(opt_src + 3), &sba);
-		else
-			str2ba(opt_src, &sba);
-	} else
-		bacpy(&sba, BDADDR_ANY);
-
-	if (strcmp(opt_sec_level, "medium") == 0)
-		sec_level = BT_IO_SEC_MEDIUM;
-	else if (strcmp(opt_sec_level, "high") == 0)
-		sec_level = BT_IO_SEC_HIGH;
-	else
-		sec_level = BT_IO_SEC_LOW;
-
-	if (le)
-		chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
-				BT_IO_OPT_SOURCE_BDADDR, &sba,
-				BT_IO_OPT_DEST_BDADDR, &dba,
-				BT_IO_OPT_CID, GATT_CID,
-				BT_IO_OPT_OMTU, opt_mtu,
-				BT_IO_OPT_SEC_LEVEL, sec_level,
-				BT_IO_OPT_INVALID);
-	else
-		chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
-				BT_IO_OPT_SOURCE_BDADDR, &sba,
-				BT_IO_OPT_DEST_BDADDR, &dba,
-				BT_IO_OPT_PSM, opt_psm,
-				BT_IO_OPT_OMTU, opt_mtu,
-				BT_IO_OPT_SEC_LEVEL, sec_level,
-				BT_IO_OPT_INVALID);
-
-	if (err) {
-		g_printerr("%s\n", err->message);
-		g_error_free(err);
-		return NULL;
-	}
-
-	return chan;
-}
-
 static void primary_all_cb(GSList *services, guint8 status, gpointer user_data)
 {
 	GSList *l;
@@ -625,6 +557,8 @@ int main(int argc, char *argv[])
 	GIOChannel *chan;
 	GSourceFunc callback;
 
+	opt_sec_level = strdup("low");
+
 	context = g_option_context_new(NULL);
 	g_option_context_add_main_entries(context, options, NULL);
 
@@ -681,7 +615,8 @@ int main(int argc, char *argv[])
 		goto done;
 	}
 
-	chan = do_connect(opt_dst, opt_le, connect_cb);
+	chan = gatt_connect(opt_src, opt_dst, opt_sec_level,
+					opt_psm, opt_mtu, opt_le, connect_cb);
 	if (chan == NULL) {
 		got_error = TRUE;
 		goto done;
@@ -710,6 +645,7 @@ done:
 	g_free(opt_src);
 	g_free(opt_dst);
 	g_free(opt_uuid);
+	g_free(opt_sec_level);
 
 	if (got_error)
 		exit(EXIT_FAILURE);
diff --git a/attrib/gatttool.h b/attrib/gatttool.h
index 2237330..1fc6a59 100644
--- a/attrib/gatttool.h
+++ b/attrib/gatttool.h
@@ -22,4 +22,6 @@
  */
 
 int interactive(gchar *dst, gboolean le);
-GIOChannel *do_connect(gchar *dst, gboolean le, BtIOConnect connect_cb);
+GIOChannel *gatt_connect(const gchar *src, const gchar *dst,
+			const gchar *sec_level, int psm, int mtu, gboolean le,
+			BtIOConnect connect_cb);
diff --git a/attrib/interactive.c b/attrib/interactive.c
index 02f31b7..71e84bc 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -42,7 +42,11 @@ static GAttrib *attrib = NULL;
 static GMainLoop *event_loop;
 static GString *prompt;
 
+static gchar *opt_src = NULL;
 static gchar *opt_dst = NULL;
+static gchar *opt_sec_level = NULL;
+static int opt_psm = 0x1f;
+static int opt_mtu = 0;
 static gboolean opt_le = FALSE;
 
 static void cmd_help(int argcp, char **argvp);
@@ -141,7 +145,8 @@ static void cmd_connect(int argcp, char **argvp)
 	}
 
 	set_state(STATE_CONNECTING);
-	iochannel = do_connect(opt_dst, opt_le, connect_cb);
+	iochannel = gatt_connect(opt_src, opt_dst, opt_sec_level, opt_psm,
+						opt_mtu, opt_le, connect_cb);
 	if (iochannel == NULL)
 		set_state(STATE_DISCONNECTED);
 
@@ -247,7 +252,9 @@ int interactive(gchar *dst, gboolean le)
 	GIOChannel *pchan;
 	gint events;
 
-	opt_dst = dst;
+	opt_sec_level = strdup("low");
+
+	opt_dst = strdup(dst);
 	opt_le = le;
 
 	prompt = g_string_new(NULL);
@@ -269,5 +276,8 @@ int interactive(gchar *dst, gboolean le)
 	g_main_loop_unref(event_loop);
 	g_string_free(prompt, TRUE);
 
+	g_free(opt_dst);
+	g_free(opt_sec_level);
+
 	return 0;
 }
diff --git a/attrib/utils.c b/attrib/utils.c
new file mode 100644
index 0000000..326c1e8
--- /dev/null
+++ b/attrib/utils.c
@@ -0,0 +1,106 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2011  Nokia Corporation
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <stdlib.h>
+#include <glib.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>
+#include <bluetooth/sdp.h>
+
+#include "gattrib.h"
+#include "gatt.h"
+#include "btio.h"
+#include "gatttool.h"
+
+/* Minimum MTU for ATT connections */
+#define ATT_MIN_MTU_LE		23
+#define ATT_MIN_MTU_L2CAP	48
+
+GIOChannel *gatt_connect(const gchar *src, const gchar *dst,
+			const gchar *sec_level, int psm, int mtu, gboolean le,
+			BtIOConnect connect_cb)
+{
+	GIOChannel *chan;
+	bdaddr_t sba, dba;
+	GError *err = NULL;
+	BtIOSecLevel sec;
+
+	/* This check is required because currently setsockopt() returns no
+	 * errors for MTU values smaller than the allowed minimum. */
+	if (mtu != 0 && mtu < (le ? ATT_MIN_MTU_LE : ATT_MIN_MTU_L2CAP)) {
+		g_printerr("MTU cannot be smaller than %d\n",
+				(le ? ATT_MIN_MTU_LE : ATT_MIN_MTU_L2CAP));
+		return NULL;
+	}
+
+	/* Remote device */
+	if (dst == NULL) {
+		g_printerr("Remote Bluetooth address required\n");
+		return NULL;
+	}
+	str2ba(dst, &dba);
+
+	/* Local adapter */
+	if (src != NULL) {
+		if (!strncmp(src, "hci", 3))
+			hci_devba(atoi(src + 3), &sba);
+		else
+			str2ba(src, &sba);
+	} else
+		bacpy(&sba, BDADDR_ANY);
+
+	if (strcmp(sec_level, "medium") == 0)
+		sec = BT_IO_SEC_MEDIUM;
+	else if (strcmp(sec_level, "high") == 0)
+		sec = BT_IO_SEC_HIGH;
+	else
+		sec = BT_IO_SEC_LOW;
+
+	if (le)
+		chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
+				BT_IO_OPT_SOURCE_BDADDR, &sba,
+				BT_IO_OPT_DEST_BDADDR, &dba,
+				BT_IO_OPT_CID, GATT_CID,
+				BT_IO_OPT_OMTU, mtu,
+				BT_IO_OPT_SEC_LEVEL, sec,
+				BT_IO_OPT_INVALID);
+	else
+		chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
+				BT_IO_OPT_SOURCE_BDADDR, &sba,
+				BT_IO_OPT_DEST_BDADDR, &dba,
+				BT_IO_OPT_PSM, psm,
+				BT_IO_OPT_OMTU, mtu,
+				BT_IO_OPT_SEC_LEVEL, sec,
+				BT_IO_OPT_INVALID);
+
+	if (err) {
+		g_printerr("%s\n", err->message);
+		g_error_free(err);
+		return NULL;
+	}
+
+	return chan;
+}
+
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH] Pass config parameters to do_connect() on gatttool
From: Sheldon Demario @ 2011-02-17 13:16 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: johan.hedberg
In-Reply-To: <1297804496-8683-1-git-send-email-sheldon.demario@openbossa.org>

Please ignore this patch. I will resent it with a different approach.

Sheldon

On Tue, Feb 15, 2011 at 6:14 PM, Sheldon Demario
<sheldon.demario@openbossa.org> wrote:
> It is desirable that do_connect() doesn't depend on global variables
> in order to make it more independent and reusable. Unifying all these
> connection parameters on a single struct makes the code simpler.
> ---
>  attrib/gatttool.c    |   61 +++++++++++++++++++++++++------------------------
>  attrib/gatttool.h    |   11 ++++++++-
>  attrib/interactive.c |   28 ++++++++++++++---------
>  3 files changed, 58 insertions(+), 42 deletions(-)
>
> diff --git a/attrib/gatttool.c b/attrib/gatttool.c
> index 1e2a8db..d72a49e 100644
> --- a/attrib/gatttool.c
> +++ b/attrib/gatttool.c
> @@ -47,28 +47,24 @@
>  /* Minimum MTU for L2CAP connections over BR/EDR */
>  #define ATT_MIN_MTU_L2CAP 48
>
> -static gchar *opt_src = NULL;
> -static gchar *opt_dst = NULL;
>  static gchar *opt_value = NULL;
> -static gchar *opt_sec_level = "low";
>  static uuid_t *opt_uuid = NULL;
>  static int opt_start = 0x0001;
>  static int opt_end = 0xffff;
>  static int opt_handle = -1;
> -static int opt_mtu = 0;
> -static int opt_psm = 0x1f;
>  static gboolean opt_primary = FALSE;
>  static gboolean opt_characteristics = FALSE;
>  static gboolean opt_char_read = FALSE;
>  static gboolean opt_listen = FALSE;
>  static gboolean opt_char_desc = FALSE;
> -static gboolean opt_le = FALSE;
>  static gboolean opt_char_write = FALSE;
>  static gboolean opt_char_write_req = FALSE;
>  static gboolean opt_interactive = FALSE;
>  static GMainLoop *event_loop;
>  static gboolean got_error = FALSE;
>
> +struct connect_params config;
> +
>  struct characteristic_data {
>        GAttrib *attrib;
>        uint16_t start;
> @@ -84,7 +80,7 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
>        }
>  }
>
> -GIOChannel *do_connect(gchar *dst, gboolean le, BtIOConnect connect_cb)
> +GIOChannel *do_connect(struct connect_params *config, BtIOConnect connect_cb)
>  {
>        GIOChannel *chan;
>        bdaddr_t sba, dba;
> @@ -93,49 +89,49 @@ GIOChannel *do_connect(gchar *dst, gboolean le, BtIOConnect connect_cb)
>
>        /* This check is required because currently setsockopt() returns no
>         * errors for MTU values smaller than the allowed minimum. */
> -       if (opt_mtu != 0 && opt_mtu < ATT_MIN_MTU_L2CAP) {
> +       if (config->mtu != 0 && config->mtu < ATT_MIN_MTU_L2CAP) {
>                g_printerr("MTU cannot be smaller than %d\n",
>                                                        ATT_MIN_MTU_L2CAP);
>                return NULL;
>        }
>
>        /* Remote device */
> -       if (dst == NULL) {
> +       if (config->dst == NULL) {
>                g_printerr("Remote Bluetooth address required\n");
>                return NULL;
>        }
> -       str2ba(dst, &dba);
> +       str2ba(config->dst, &dba);
>
>        /* Local adapter */
> -       if (opt_src != NULL) {
> -               if (!strncmp(opt_src, "hci", 3))
> -                       hci_devba(atoi(opt_src + 3), &sba);
> +       if (config->src != NULL) {
> +               if (!strncmp(config->src, "hci", 3))
> +                       hci_devba(atoi(config->src + 3), &sba);
>                else
> -                       str2ba(opt_src, &sba);
> +                       str2ba(config->src, &sba);
>        } else
>                bacpy(&sba, BDADDR_ANY);
>
> -       if (strcmp(opt_sec_level, "medium") == 0)
> +       if (strcmp(config->sec_level, "medium") == 0)
>                sec_level = BT_IO_SEC_MEDIUM;
> -       else if (strcmp(opt_sec_level, "high") == 0)
> +       else if (strcmp(config->sec_level, "high") == 0)
>                sec_level = BT_IO_SEC_HIGH;
>        else
>                sec_level = BT_IO_SEC_LOW;
>
> -       if (le)
> +       if (config->le)
>                chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
>                                BT_IO_OPT_SOURCE_BDADDR, &sba,
>                                BT_IO_OPT_DEST_BDADDR, &dba,
>                                BT_IO_OPT_CID, GATT_CID,
> -                               BT_IO_OPT_OMTU, opt_mtu,
> +                               BT_IO_OPT_OMTU, config->mtu,
>                                BT_IO_OPT_SEC_LEVEL, sec_level,
>                                BT_IO_OPT_INVALID);
>        else
>                chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
>                                BT_IO_OPT_SOURCE_BDADDR, &sba,
>                                BT_IO_OPT_DEST_BDADDR, &dba,
> -                               BT_IO_OPT_PSM, opt_psm,
> -                               BT_IO_OPT_OMTU, opt_mtu,
> +                               BT_IO_OPT_PSM, config->psm,
> +                               BT_IO_OPT_OMTU, config->mtu,
>                                BT_IO_OPT_SEC_LEVEL, sec_level,
>                                BT_IO_OPT_INVALID);
>
> @@ -594,7 +590,7 @@ static GOptionEntry gatt_options[] = {
>                "Characteristics Descriptor Discovery", NULL },
>        { "listen", 0, 0, G_OPTION_ARG_NONE, &opt_listen,
>                "Listen for notifications and indications", NULL },
> -       { "le", 0, 0, G_OPTION_ARG_NONE, &opt_le,
> +       { "le", 0, 0, G_OPTION_ARG_NONE, &config.le,
>                "Use Bluetooth Low Energy transport", NULL },
>        { "interactive", 'I', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
>                &opt_interactive, "Use interactive mode", NULL },
> @@ -602,15 +598,15 @@ static GOptionEntry gatt_options[] = {
>  };
>
>  static GOptionEntry options[] = {
> -       { "adapter", 'i', 0, G_OPTION_ARG_STRING, &opt_src,
> +       { "adapter", 'i', 0, G_OPTION_ARG_STRING, &config.src,
>                "Specify local adapter interface", "hciX" },
> -       { "device", 'b', 0, G_OPTION_ARG_STRING, &opt_dst,
> +       { "device", 'b', 0, G_OPTION_ARG_STRING, &config.dst,
>                "Specify remote Bluetooth address", "MAC" },
> -       { "mtu", 'm', 0, G_OPTION_ARG_INT, &opt_mtu,
> +       { "mtu", 'm', 0, G_OPTION_ARG_INT, &config.mtu,
>                "Specify the MTU size", "MTU" },
> -       { "psm", 'p', 0, G_OPTION_ARG_INT, &opt_psm,
> +       { "psm", 'p', 0, G_OPTION_ARG_INT, &config.psm,
>                "Specify the PSM for GATT/ATT over BR/EDR", "PSM" },
> -       { "sec-level", 'l', 0, G_OPTION_ARG_STRING, &opt_sec_level,
> +       { "sec-level", 'l', 0, G_OPTION_ARG_STRING, &config.sec_level,
>                "Set security level. Default: low", "[low | medium | high]"},
>        { NULL },
>  };
> @@ -624,6 +620,10 @@ int main(int argc, char *argv[])
>        GIOChannel *chan;
>        GSourceFunc callback;
>
> +       memset(&config, 0, sizeof(config));
> +       config.sec_level = strdup("low");
> +       config.psm = 0x1f;
> +
>        context = g_option_context_new(NULL);
>        g_option_context_add_main_entries(context, options, NULL);
>
> @@ -656,7 +656,7 @@ int main(int argc, char *argv[])
>        }
>
>        if (opt_interactive) {
> -               interactive(opt_dst, opt_le);
> +               interactive(config.dst, config.le);
>                goto done;
>        }
>
> @@ -680,7 +680,7 @@ int main(int argc, char *argv[])
>                goto done;
>        }
>
> -       chan = do_connect(opt_dst, opt_le, connect_cb);
> +       chan = do_connect(&config, connect_cb);
>        if (chan == NULL) {
>                got_error = TRUE;
>                goto done;
> @@ -706,9 +706,10 @@ int main(int argc, char *argv[])
>
>  done:
>        g_option_context_free(context);
> -       g_free(opt_src);
> -       g_free(opt_dst);
> +       g_free(config.src);
> +       g_free(config.dst);
>        g_free(opt_uuid);
> +       g_free(config.sec_level);
>
>        if (got_error)
>                exit(EXIT_FAILURE);
> diff --git a/attrib/gatttool.h b/attrib/gatttool.h
> index 2237330..ec6fa35 100644
> --- a/attrib/gatttool.h
> +++ b/attrib/gatttool.h
> @@ -21,5 +21,14 @@
>  *
>  */
>
> +struct connect_params {
> +       gchar *src;
> +       gchar *dst;
> +       gchar *sec_level;
> +       int psm;
> +       int mtu;
> +       gboolean le;
> +};
> +
>  int interactive(gchar *dst, gboolean le);
> -GIOChannel *do_connect(gchar *dst, gboolean le, BtIOConnect connect_cb);
> +GIOChannel *do_connect(struct connect_params *config, BtIOConnect connect_cb);
> diff --git a/attrib/interactive.c b/attrib/interactive.c
> index 83a0778..284699b 100644
> --- a/attrib/interactive.c
> +++ b/attrib/interactive.c
> @@ -37,8 +37,7 @@ static GAttrib *attrib = NULL;
>  static GMainLoop *event_loop;
>  static GString *prompt;
>
> -static gchar *opt_dst = NULL;
> -static gboolean opt_le = FALSE;
> +struct connect_params config;
>
>  static void cmd_help(int argcp, char **argvp);
>
> @@ -60,12 +59,12 @@ static char *get_prompt(void)
>        else
>                g_string_assign(prompt, "[   ]");
>
> -       if (opt_dst)
> -               g_string_append_printf(prompt, "[%17s]", opt_dst);
> +       if (config.dst)
> +               g_string_append_printf(prompt, "[%17s]", config.dst);
>        else
>                g_string_append_printf(prompt, "[%17s]", "");
>
> -       if (opt_le)
> +       if (config.le)
>                g_string_append(prompt, "[LE]");
>        else
>                g_string_append(prompt, "[BR]");
> @@ -107,17 +106,17 @@ static void cmd_connect(int argcp, char **argvp)
>                return;
>
>        if (argcp > 1) {
> -               g_free(opt_dst);
> -               opt_dst = strdup(argvp[1]);
> +               g_free(config.dst);
> +               config.dst = strdup(argvp[1]);
>        }
>
> -       if (opt_dst == NULL) {
> +       if (config.dst == NULL) {
>                printf("Remote Bluetooth address required\n");
>                return;
>        }
>
>        set_state(STATE_CONNECTING);
> -       iochannel = do_connect(opt_dst, opt_le, connect_cb);
> +       iochannel = do_connect(&config, connect_cb);
>        if (iochannel == NULL)
>                set_state(STATE_DISCONNECTED);
>
> @@ -212,8 +211,12 @@ int interactive(gchar *dst, gboolean le)
>        GIOChannel *pchan;
>        gint events;
>
> -       opt_dst = dst;
> -       opt_le = le;
> +       memset(&config, 0, sizeof(config));
> +       config.sec_level = strdup("low");
> +       config.psm = 0x1f;
> +
> +       config.dst = strdup(dst);
> +       config.le = le;
>
>        prompt = g_string_new(NULL);
>
> @@ -234,5 +237,8 @@ int interactive(gchar *dst, gboolean le)
>        g_main_loop_unref(event_loop);
>        g_string_free(prompt, TRUE);
>
> +       g_free(config.dst);
> +       g_free(config.sec_level);
> +
>        return 0;
>  }
> --
> 1.7.1
>
>

^ permalink raw reply

* [PATCH 10/10] Bluetooth: Log command and status parameters in command status event
From: Szymon Janc @ 2011-02-17 13:16 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc
In-Reply-To: <1297948601-12723-1-git-send-email-szymon.janc@tieto.com>

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

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 571cbcf..208c211 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -49,7 +49,7 @@ static int cmd_status(struct sock *sk, u16 cmd, u8 status, void *data,
 	struct mgmt_hdr *hdr;
 	struct mgmt_ev_cmd_status *ev;
 
-	BT_DBG("sock %p", sk);
+	BT_DBG("sock %p, cmd %u, status %u", sk, cmd, status);
 
 	skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + data_len, GFP_ATOMIC);
 	if (!skb)
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 09/10] Bluetooth: Fix code style issues, make checkpatch less noisy about hci_event.c
From: Szymon Janc @ 2011-02-17 13:16 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc
In-Reply-To: <1297948601-12723-1-git-send-email-szymon.janc@tieto.com>

Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
 net/bluetooth/hci_event.c |  136 +++++++++++++++++++++++++++++---------------
 1 files changed, 89 insertions(+), 47 deletions(-)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index b39c9bb..9fa91c8 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -77,7 +77,8 @@ static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_conn_check_pending(hdev);
 }
 
-static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	BT_DBG("%s", hdev->name);
 }
@@ -148,7 +149,8 @@ static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_dev_unlock(hdev);
 }
 
-static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_cc_read_def_link_policy(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
 
@@ -160,7 +162,8 @@ static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *sk
 	hdev->link_policy = __le16_to_cpu(rp->policy);
 }
 
-static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	__u8 status = *((__u8 *) skb->data);
 	void *sent;
@@ -355,7 +358,8 @@ static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
 	}
 }
 
-static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_cc_write_voice_setting(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	__u8 status = *((__u8 *) skb->data);
 	__u16 setting;
@@ -574,7 +578,8 @@ static void hci_setup_link_policy(struct hci_dev *hdev)
 					sizeof(link_policy), &link_policy);
 }
 
-static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_cc_read_local_commands(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_rp_read_local_commands *rp = (void *) skb->data;
 
@@ -592,7 +597,8 @@ done:
 	hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
 }
 
-static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_cc_read_local_features(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_rp_read_local_features *rp = (void *) skb->data;
 
@@ -1174,7 +1180,8 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_inquiry_complete_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	__u8 status = *((__u8 *) skb->data);
 
@@ -1187,7 +1194,8 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff
 	hci_conn_check_pending(hdev);
 }
 
-static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_inquiry_result_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct inquiry_data data;
 	struct inquiry_info *info = (void *) (skb->data + 1);
@@ -1216,7 +1224,8 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_conn_complete_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_conn_complete *ev = (void *) skb->data;
 	struct hci_conn *conn;
@@ -1294,7 +1303,8 @@ unlock:
 	hci_conn_check_pending(hdev);
 }
 
-static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_conn_request_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_conn_request *ev = (void *) skb->data;
 	int mask = hdev->link_mode;
@@ -1304,7 +1314,8 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
 
 	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
 
-	if ((mask & HCI_LM_ACCEPT) && !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
+	if ((mask & HCI_LM_ACCEPT) &&
+			!hci_blacklist_lookup(hdev, &ev->bdaddr)) {
 		/* Connection accepted */
 		struct inquiry_entry *ie;
 		struct hci_conn *conn;
@@ -1315,7 +1326,8 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
 		if (ie)
 			memcpy(ie->data.dev_class, ev->dev_class, 3);
 
-		conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
+		conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
+								&ev->bdaddr);
 		if (!conn) {
 			conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
 			if (!conn) {
@@ -1367,7 +1379,8 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
 	}
 }
 
-static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_disconn_complete_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_disconn_complete *ev = (void *) skb->data;
 	struct hci_conn *conn;
@@ -1397,7 +1410,8 @@ unlock:
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_auth_complete_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_auth_complete *ev = (void *) skb->data;
 	struct hci_conn *conn;
@@ -1454,7 +1468,8 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_remote_name_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_remote_name *ev = (void *) skb->data;
 	struct hci_conn *conn;
@@ -1475,7 +1490,8 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_encrypt_change_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_encrypt_change *ev = (void *) skb->data;
 	struct hci_conn *conn;
@@ -1510,7 +1526,8 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
 	struct hci_conn *conn;
@@ -1532,7 +1549,8 @@ static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_remote_features_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_remote_features *ev = (void *) skb->data;
 	struct hci_conn *conn;
@@ -1578,17 +1596,20 @@ unlock:
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_remote_version_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	BT_DBG("%s", hdev->name);
 }
 
-static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	BT_DBG("%s", hdev->name);
 }
 
-static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_cmd_complete_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_cmd_complete *ev = (void *) skb->data;
 	__u16 opcode;
@@ -1835,7 +1856,8 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	}
 }
 
-static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_role_change_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_role_change *ev = (void *) skb->data;
 	struct hci_conn *conn;
@@ -1861,7 +1883,8 @@ static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
 	__le16 *ptr;
@@ -1916,7 +1939,8 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
 	tasklet_enable(&hdev->tx_task);
 }
 
-static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_mode_change_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_mode_change *ev = (void *) skb->data;
 	struct hci_conn *conn;
@@ -1944,7 +1968,8 @@ static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_pin_code_request_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_pin_code_req *ev = (void *) skb->data;
 	struct hci_conn *conn;
@@ -1970,7 +1995,8 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_link_key_request_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_link_key_req *ev = (void *) skb->data;
 	struct hci_cp_link_key_reply cp;
@@ -2021,7 +2047,8 @@ not_found:
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_link_key_notify_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_link_key_notify *ev = (void *) skb->data;
 	struct hci_conn *conn;
@@ -2046,7 +2073,8 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_clock_offset_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_clock_offset *ev = (void *) skb->data;
 	struct hci_conn *conn;
@@ -2069,7 +2097,8 @@ static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *sk
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_pkt_type_change_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_pkt_type_change *ev = (void *) skb->data;
 	struct hci_conn *conn;
@@ -2085,7 +2114,8 @@ static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
 	struct inquiry_entry *ie;
@@ -2103,7 +2133,8 @@ static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct inquiry_data data;
 	int num_rsp = *((__u8 *) skb->data);
@@ -2116,7 +2147,8 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
 	hci_dev_lock(hdev);
 
 	if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
-		struct inquiry_info_with_rssi_and_pscan_mode *info = (void *) (skb->data + 1);
+		struct inquiry_info_with_rssi_and_pscan_mode *info;
+		info = (void *) (skb->data + 1);
 
 		for (; num_rsp; num_rsp--) {
 			bacpy(&data.bdaddr, &info->bdaddr);
@@ -2150,7 +2182,8 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_remote_ext_features_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_remote_ext_features *ev = (void *) skb->data;
 	struct hci_conn *conn;
@@ -2194,7 +2227,8 @@ unlock:
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
 	struct hci_conn *conn;
@@ -2249,19 +2283,22 @@ unlock:
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	BT_DBG("%s", hdev->name);
 }
 
-static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_sniff_subrate_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_sniff_subrate *ev = (void *) skb->data;
 
 	BT_DBG("%s status %d", hdev->name, ev->status);
 }
 
-static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct inquiry_data data;
 	struct extended_inquiry_info *info = (void *) (skb->data + 1);
@@ -2276,12 +2313,12 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
 
 	for (; num_rsp; num_rsp--) {
 		bacpy(&data.bdaddr, &info->bdaddr);
-		data.pscan_rep_mode     = info->pscan_rep_mode;
-		data.pscan_period_mode  = info->pscan_period_mode;
-		data.pscan_mode         = 0x00;
+		data.pscan_rep_mode	= info->pscan_rep_mode;
+		data.pscan_period_mode	= info->pscan_period_mode;
+		data.pscan_mode		= 0x00;
 		memcpy(data.dev_class, info->dev_class, 3);
-		data.clock_offset       = info->clock_offset;
-		data.rssi               = info->rssi;
+		data.clock_offset	= info->clock_offset;
+		data.rssi		= info->rssi;
 		data.ssp_mode		= 0x01;
 		info++;
 		hci_inquiry_cache_update(hdev, &data);
@@ -2309,7 +2346,8 @@ static inline u8 hci_get_auth_req(struct hci_conn *conn)
 	return conn->auth_type;
 }
 
-static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_io_capa_request_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_io_capa_request *ev = (void *) skb->data;
 	struct hci_conn *conn;
@@ -2357,7 +2395,8 @@ unlock:
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_io_capa_reply_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_io_capa_reply *ev = (void *) skb->data;
 	struct hci_conn *conn;
@@ -2380,7 +2419,8 @@ unlock:
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
 	struct hci_conn *conn;
@@ -2396,7 +2436,8 @@ static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_remote_host_features_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_remote_host_features *ev = (void *) skb->data;
 	struct inquiry_entry *ie;
@@ -2443,7 +2484,8 @@ static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
 	hci_dev_unlock(hdev);
 }
 
-static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_le_conn_complete_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
 {
 	struct hci_ev_le_conn_complete *ev = (void *) skb->data;
 	struct hci_conn *conn;
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 08/10] Bluetooth: Fix code style issues and make checkpatch silent about hci_core.c
From: Szymon Janc @ 2011-02-17 13:16 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc
In-Reply-To: <1297948601-12723-1-git-send-email-szymon.janc@tieto.com>

Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
 net/bluetooth/hci_core.c |   30 +++++++++++++++++-------------
 1 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 0f5bbb0..60581b7 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -123,8 +123,9 @@ static void hci_req_cancel(struct hci_dev *hdev, int err)
 }
 
 /* Execute request and wait for completion. */
-static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
-				unsigned long opt, __u32 timeout)
+static int __hci_request(struct hci_dev *hdev,
+			void (*req)(struct hci_dev *hdev, unsigned long opt),
+					unsigned long opt, __u32 timeout)
 {
 	DECLARE_WAITQUEUE(wait, current);
 	int err = 0;
@@ -165,8 +166,9 @@ static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev,
 	return err;
 }
 
-static inline int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
-				unsigned long opt, __u32 timeout)
+static inline int hci_request(struct hci_dev *hdev,
+			void (*req)(struct hci_dev *hdev, unsigned long opt),
+					unsigned long opt, __u32 timeout)
 {
 	int ret;
 
@@ -351,7 +353,8 @@ static void inquiry_cache_flush(struct hci_dev *hdev)
 	}
 }
 
-struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
+struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
+							bdaddr_t *bdaddr)
 {
 	struct inquiry_cache *cache = &hdev->inq_cache;
 	struct inquiry_entry *e;
@@ -459,13 +462,13 @@ int hci_inquiry(void __user *arg)
 			goto done;
 	}
 
-	/* for unlimited number of responses we will use buffer with 255 entries */
+	/* for unlimited number of responses use buffer with 255 entries */
 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
 
 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
 	 * copy it to the user space.
 	 */
-	buf = kmalloc(sizeof(struct inquiry_info) *max_rsp, GFP_KERNEL);
+	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
 	if (!buf) {
 		err = -ENOMEM;
 		goto done;
@@ -534,7 +537,6 @@ int hci_dev_open(__u16 dev)
 		set_bit(HCI_INIT, &hdev->flags);
 		hdev->init_last_cmd = 0;
 
-		//__hci_request(hdev, hci_reset_req, 0, HZ);
 		ret = __hci_request(hdev, hci_init_req, 0,
 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
 
@@ -1748,7 +1750,8 @@ EXPORT_SYMBOL(hci_send_sco);
 /* ---- HCI TX task (outgoing data) ---- */
 
 /* HCI Connection scheduler */
-static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
+static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
+								int *quote)
 {
 	struct hci_conn_hash *h = &hdev->conn_hash;
 	struct hci_conn *conn = NULL;
@@ -1833,7 +1836,8 @@ static inline void hci_sched_acl(struct hci_dev *hdev)
 	if (!test_bit(HCI_RAW, &hdev->flags)) {
 		/* ACL tx timeout must be longer than maximum
 		 * link supervision timeout (40.9 seconds) */
-		if (!hdev->acl_cnt && time_after(jiffies, hdev->acl_last_tx + HZ * 45))
+		if (!hdev->acl_cnt &&
+			time_after(jiffies, hdev->acl_last_tx + HZ * 45))
 			hci_link_tx_to(hdev, ACL_LINK);
 	}
 
@@ -1881,7 +1885,7 @@ static inline void hci_sched_esco(struct hci_dev *hdev)
 
 	BT_DBG("%s", hdev->name);
 
-	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, &quote))) {
+	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, &quote)))
 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
 			BT_DBG("skb %p len %d", skb, skb->len);
 			hci_send_frame(skb);
@@ -1890,7 +1894,6 @@ static inline void hci_sched_esco(struct hci_dev *hdev)
 			if (conn->sent == ~0)
 				conn->sent = 0;
 		}
-	}
 }
 
 static inline void hci_sched_le(struct hci_dev *hdev)
@@ -1969,7 +1972,8 @@ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
 	flags  = hci_flags(handle);
 	handle = hci_handle(handle);
 
-	BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
+	BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle,
+									flags);
 
 	hdev->stat.acl_rx++;
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 07/10] Bluetooth: Fix code style issues and make checkpatch silent about hci_core.h
From: Szymon Janc @ 2011-02-17 13:16 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc
In-Reply-To: <1297948601-12723-1-git-send-email-szymon.janc@tieto.com>

Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
 include/net/bluetooth/hci_core.h |   91 +++++++++++++++++++++-----------------
 1 files changed, 51 insertions(+), 40 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index e4f370f..a8a5ecb 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -208,37 +208,37 @@ struct hci_dev {
 struct hci_conn {
 	struct list_head list;
 
-	atomic_t	 refcnt;
-	spinlock_t	 lock;
-
-	bdaddr_t	 dst;
-	__u16		 handle;
-	__u16		 state;
-	__u8             mode;
-	__u8		 type;
-	__u8		 out;
-	__u8		 attempt;
-	__u8		 dev_class[3];
-	__u8             features[8];
-	__u8             ssp_mode;
-	__u16            interval;
-	__u16            pkt_type;
-	__u16            link_policy;
-	__u32		 link_mode;
-	__u8             auth_type;
-	__u8             sec_level;
-	__u8		 pending_sec_level;
-	__u8		 pin_length;
-	__u8		 io_capability;
-	__u8             power_save;
-	__u16            disc_timeout;
-	unsigned long	 pend;
+	atomic_t	refcnt;
+	spinlock_t	lock;
+
+	bdaddr_t	dst;
+	__u16		handle;
+	__u16		state;
+	__u8		mode;
+	__u8		type;
+	__u8		out;
+	__u8		attempt;
+	__u8		dev_class[3];
+	__u8		features[8];
+	__u8		ssp_mode;
+	__u16		interval;
+	__u16		pkt_type;
+	__u16		link_policy;
+	__u32		link_mode;
+	__u8		auth_type;
+	__u8		sec_level;
+	__u8		pending_sec_level;
+	__u8		pin_length;
+	__u8		io_capability;
+	__u8		power_save;
+	__u16		disc_timeout;
+	unsigned long	pend;
 
 	__u8		remote_cap;
 	__u8		remote_oob;
 	__u8		remote_auth;
 
-	unsigned int	 sent;
+	unsigned int	sent;
 
 	struct sk_buff_head data_q;
 
@@ -298,7 +298,8 @@ static inline long inquiry_entry_age(struct inquiry_entry *e)
 	return jiffies - e->timestamp;
 }
 
-struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr);
+struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
+							bdaddr_t *bdaddr);
 void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data);
 
 /* ----- HCI Connections ----- */
@@ -356,7 +357,7 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
 }
 
 static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
-					__u16 handle)
+								__u16 handle)
 {
 	struct hci_conn_hash *h = &hdev->conn_hash;
 	struct list_head *p;
@@ -371,7 +372,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
 }
 
 static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
-					__u8 type, bdaddr_t *ba)
+							__u8 type, bdaddr_t *ba)
 {
 	struct hci_conn_hash *h = &hdev->conn_hash;
 	struct list_head *p;
@@ -386,7 +387,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
 }
 
 static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
-					__u8 type, __u16 state)
+							__u8 type, __u16 state)
 {
 	struct hci_conn_hash *h = &hdev->conn_hash;
 	struct list_head *p;
@@ -411,7 +412,8 @@ int hci_conn_del(struct hci_conn *conn);
 void hci_conn_hash_flush(struct hci_dev *hdev);
 void hci_conn_check_pending(struct hci_dev *hdev);
 
-struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type);
+struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst,
+						__u8 sec_level, __u8 auth_type);
 int hci_conn_check_link_mode(struct hci_conn *conn);
 int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
 int hci_conn_change_link_key(struct hci_conn *conn);
@@ -499,7 +501,8 @@ int hci_get_conn_info(struct hci_dev *hdev, void __user *arg);
 int hci_get_auth_info(struct hci_dev *hdev, void __user *arg);
 int hci_inquiry(void __user *arg);
 
-struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr);
+struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
+							bdaddr_t *bdaddr);
 int hci_blacklist_clear(struct hci_dev *hdev);
 
 int hci_uuids_clear(struct hci_dev *hdev);
@@ -551,16 +554,20 @@ struct hci_proto {
 
 	void		*priv;
 
-	int (*connect_ind)	(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type);
+	int (*connect_ind)	(struct hci_dev *hdev, bdaddr_t *bdaddr,
+								__u8 type);
 	int (*connect_cfm)	(struct hci_conn *conn, __u8 status);
 	int (*disconn_ind)	(struct hci_conn *conn);
 	int (*disconn_cfm)	(struct hci_conn *conn, __u8 reason);
-	int (*recv_acldata)	(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
+	int (*recv_acldata)	(struct hci_conn *conn, struct sk_buff *skb,
+								__u16 flags);
 	int (*recv_scodata)	(struct hci_conn *conn, struct sk_buff *skb);
-	int (*security_cfm)	(struct hci_conn *conn, __u8 status, __u8 encrypt);
+	int (*security_cfm)	(struct hci_conn *conn, __u8 status,
+								__u8 encrypt);
 };
 
-static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
+static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,
+								__u8 type)
 {
 	register struct hci_proto *hp;
 	int mask = 0;
@@ -637,7 +644,8 @@ static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
 		hp->security_cfm(conn, status, encrypt);
 }
 
-static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt)
+static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status,
+								__u8 encrypt)
 {
 	register struct hci_proto *hp;
 
@@ -659,7 +667,8 @@ struct hci_cb {
 
 	char *name;
 
-	void (*security_cfm)	(struct hci_conn *conn, __u8 status, __u8 encrypt);
+	void (*security_cfm)	(struct hci_conn *conn, __u8 status,
+								__u8 encrypt);
 	void (*key_change_cfm)	(struct hci_conn *conn, __u8 status);
 	void (*role_switch_cfm)	(struct hci_conn *conn, __u8 status, __u8 role);
 };
@@ -685,7 +694,8 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
 	read_unlock_bh(&hci_cb_list_lock);
 }
 
-static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt)
+static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status,
+								__u8 encrypt)
 {
 	struct list_head *p;
 
@@ -716,7 +726,8 @@ static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status)
 	read_unlock_bh(&hci_cb_list_lock);
 }
 
-static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, __u8 role)
+static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status,
+								__u8 role)
 {
 	struct list_head *p;
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 06/10] Bluetooth: Add add/remove_remote_oob_data management commands
From: Szymon Janc @ 2011-02-17 13:16 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc
In-Reply-To: <1297948601-12723-1-git-send-email-szymon.janc@tieto.com>

This patch adds commands to add and remove remote OOB data to the managment
interface. Remote data is stored in kernel and used by corresponding HCI
commands and events (also implemented in this patch) when needed.

Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
 include/net/bluetooth/hci.h      |   17 ++++++++
 include/net/bluetooth/hci_core.h |   16 ++++++++
 include/net/bluetooth/mgmt.h     |   14 +++++++
 net/bluetooth/hci_core.c         |   76 ++++++++++++++++++++++++++++++++++++++
 net/bluetooth/hci_event.c        |   41 ++++++++++++++++++++-
 net/bluetooth/mgmt.c             |   73 ++++++++++++++++++++++++++++++++++++
 6 files changed, 236 insertions(+), 1 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 7d1aef9..d1dd7dc 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -415,6 +415,18 @@ struct hci_cp_io_capability_reply {
 	__u8     authentication;
 } __packed;
 
+#define HCI_OP_REMOTE_OOB_DATA_REPLY	0x0430
+struct hci_cp_remote_oob_data_reply {
+	bdaddr_t bdaddr;
+	__u8     hash[16];
+	__u8     randomizer[16];
+} __packed;
+
+#define HCI_OP_REMOTE_OOB_DATA_NEG_REPLY	0x0433
+struct hci_cp_remote_oob_data_neg_reply {
+	bdaddr_t bdaddr;
+} __packed;
+
 #define HCI_OP_IO_CAPABILITY_NEG_REPLY	0x0434
 struct hci_cp_io_capability_neg_reply {
 	bdaddr_t bdaddr;
@@ -943,6 +955,11 @@ struct hci_ev_io_capa_reply {
 	__u8     authentication;
 } __packed;
 
+#define HCI_EV_REMOTE_OOB_DATA_REQUEST	0x35
+struct hci_ev_remote_oob_data_request {
+	bdaddr_t bdaddr;
+} __packed;
+
 #define HCI_EV_SIMPLE_PAIR_COMPLETE	0x36
 struct hci_ev_simple_pair_complete {
 	__u8     status;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 704f265..e4f370f 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -82,6 +82,13 @@ struct link_key {
 	u8 pin_len;
 };
 
+struct oob_data {
+	struct list_head list;
+	bdaddr_t bdaddr;
+	u8 hash[16];
+	u8 randomizer[16];
+};
+
 #define NUM_REASSEMBLY 4
 struct hci_dev {
 	struct list_head list;
@@ -169,6 +176,8 @@ struct hci_dev {
 
 	struct list_head	link_keys;
 
+	struct list_head	remote_oob_data;
+
 	struct hci_dev_stats	stat;
 
 	struct sk_buff_head	driver_init;
@@ -501,6 +510,13 @@ int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
 						u8 *key, u8 type, u8 pin_len);
 int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
 
+int hci_remote_oob_data_clear(struct hci_dev *hdev);
+struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
+							bdaddr_t *bdaddr);
+int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
+								u8 *randomizer);
+int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
+
 void hci_del_off_timer(struct hci_dev *hdev);
 
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 18e2fb6..9bfd30f 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -174,6 +174,20 @@ struct mgmt_rp_read_local_oob_data_failed {
 	__le16 index;
 } __packed;
 
+#define MGMT_OP_ADD_REMOTE_OOB_DATA	0x0018
+struct mgmt_cp_add_remote_oob_data {
+	__le16 index;
+	bdaddr_t bdaddr;
+	__u8 hash[16];
+	__u8 randomizer[16];
+} __packed;
+
+#define MGMT_OP_REMOVE_REMOTE_OOB_DATA	0x0019
+struct mgmt_cp_remove_remote_oob_data {
+	__le16 index;
+	bdaddr_t bdaddr;
+} __packed;
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16 opcode;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 702d565..0f5bbb0 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1078,6 +1078,79 @@ static void hci_cmd_timer(unsigned long arg)
 	tasklet_schedule(&hdev->cmd_task);
 }
 
+struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
+							bdaddr_t *bdaddr)
+{
+	struct list_head *p;
+
+	list_for_each(p, &hdev->remote_oob_data) {
+		struct oob_data *data;
+
+		data = list_entry(p, struct oob_data, list);
+
+		if (bacmp(bdaddr, &data->bdaddr) == 0)
+			return data;
+	}
+
+	return NULL;
+}
+
+int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
+{
+	struct oob_data *data;
+
+	data = hci_find_remote_oob_data(hdev, bdaddr);
+	if (!data)
+		return -ENOENT;
+
+	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
+
+	list_del(&data->list);
+	kfree(data);
+
+	return 0;
+}
+
+int hci_remote_oob_data_clear(struct hci_dev *hdev)
+{
+	struct list_head *p, *n;
+
+	list_for_each_safe(p, n, &hdev->remote_oob_data) {
+		struct oob_data *data;
+
+		data = list_entry(p, struct oob_data, list);
+
+		list_del(p);
+		kfree(data);
+	}
+
+	return 0;
+}
+
+int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
+								u8 *randomizer)
+{
+	struct oob_data *data;
+
+	data = hci_find_remote_oob_data(hdev, bdaddr);
+
+	if (!data) {
+		data = kmalloc(sizeof(*data), GFP_ATOMIC);
+		if (!data)
+			return -ENOMEM;
+
+		bacpy(&data->bdaddr, bdaddr);
+		list_add(&data->list, &hdev->remote_oob_data);
+	}
+
+	memcpy(data->hash, hash, 16);
+	memcpy(data->randomizer, randomizer, 16);
+
+	BT_DBG("%s for %s", hdev->name, batostr(bdaddr));
+
+	return 0;
+}
+
 /* Register HCI device */
 int hci_register_dev(struct hci_dev *hdev)
 {
@@ -1142,6 +1215,8 @@ int hci_register_dev(struct hci_dev *hdev)
 
 	INIT_LIST_HEAD(&hdev->link_keys);
 
+	INIT_LIST_HEAD(&hdev->remote_oob_data);
+
 	INIT_WORK(&hdev->power_on, hci_power_on);
 	INIT_WORK(&hdev->power_off, hci_power_off);
 	setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev);
@@ -1221,6 +1296,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
 	hci_blacklist_clear(hdev);
 	hci_uuids_clear(hdev);
 	hci_link_keys_clear(hdev);
+	hci_remote_oob_data_clear(hdev);
 	hci_dev_unlock_bh(hdev);
 
 	__hci_dev_put(hdev);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 053fcf7..b39c9bb 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2333,9 +2333,14 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff
 
 		bacpy(&cp.bdaddr, &ev->bdaddr);
 		cp.capability = conn->io_capability;
-		cp.oob_data = 0;
 		cp.authentication = hci_get_auth_req(conn);
 
+		if ((conn->out == 1 || conn->remote_oob == 0x01) &&
+				hci_find_remote_oob_data(hdev, &conn->dst))
+			cp.oob_data = 0x01;
+		else
+			cp.oob_data = 0x00;
+
 		hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
 							sizeof(cp), &cp);
 	} else {
@@ -2407,6 +2412,37 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_
 	hci_dev_unlock(hdev);
 }
 
+static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
+{
+	struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
+	struct oob_data *data;
+
+	BT_DBG("%s", hdev->name);
+
+	hci_dev_lock(hdev);
+
+	data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
+	if (data) {
+		struct hci_cp_remote_oob_data_reply cp;
+
+		bacpy(&cp.bdaddr, &ev->bdaddr);
+		memcpy(cp.hash, data->hash, 16);
+		memcpy(cp.randomizer, data->randomizer, 16);
+
+		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
+									&cp);
+	} else {
+		struct hci_cp_remote_oob_data_neg_reply cp;
+
+		bacpy(&cp.bdaddr, &ev->bdaddr);
+		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
+									&cp);
+	}
+
+	hci_dev_unlock(hdev);
+}
+
 static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_ev_le_conn_complete *ev = (void *) skb->data;
@@ -2603,6 +2639,9 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 
 	case HCI_EV_LE_META:
 		hci_le_meta_evt(hdev, skb);
+
+	case HCI_EV_REMOTE_OOB_DATA_REQUEST:
+		hci_remote_oob_data_request_evt(hdev, skb);
 		break;
 
 	default:
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 2847934..571cbcf 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1112,6 +1112,73 @@ unlock:
 	return err;
 }
 
+static int add_remote_oob_data(struct sock *sk, unsigned char *data, u16 len)
+{
+	struct hci_dev *hdev;
+	struct mgmt_cp_add_remote_oob_data *cp;
+	u16 dev_id;
+	int err;
+
+	cp = (void *) data;
+	dev_id = get_unaligned_le16(&cp->index);
+
+	BT_DBG("hci%u ", dev_id);
+
+	hdev = hci_dev_get(dev_id);
+	if (!hdev)
+		return cmd_status(sk, MGMT_OP_ADD_REMOTE_OOB_DATA, ENODEV, NULL,
+									0);
+
+	hci_dev_lock_bh(hdev);
+
+	err = hci_add_remote_oob_data(hdev, &cp->bdaddr, cp->hash,
+								cp->randomizer);
+	if (err < 0)
+		err = cmd_status(sk, MGMT_OP_ADD_REMOTE_OOB_DATA, -err, NULL,
+									0);
+	else
+		err = cmd_complete(sk, MGMT_OP_ADD_REMOTE_OOB_DATA, &dev_id,
+								sizeof(dev_id));
+
+	hci_dev_unlock_bh(hdev);
+	hci_dev_put(hdev);
+
+	return err;
+}
+
+static int remove_remote_oob_data(struct sock *sk, unsigned char *data, u16 len)
+{
+	struct hci_dev *hdev;
+	struct mgmt_cp_remove_remote_oob_data *cp;
+	u16 dev_id;
+	int err;
+
+	cp = (void *) data;
+	dev_id = get_unaligned_le16(&cp->index);
+
+	BT_DBG("hci%u ", dev_id);
+
+	hdev = hci_dev_get(dev_id);
+	if (!hdev)
+		return cmd_status(sk, MGMT_OP_REMOVE_REMOTE_OOB_DATA, ENODEV,
+								NULL, 0);
+
+	hci_dev_lock_bh(hdev);
+
+	err = hci_remove_remote_oob_data(hdev, &cp->bdaddr);
+	if (err < 0)
+		err = cmd_status(sk, MGMT_OP_REMOVE_REMOTE_OOB_DATA, -err, NULL,
+									0);
+	else
+		err = cmd_complete(sk, MGMT_OP_REMOVE_REMOTE_OOB_DATA, &dev_id,
+								sizeof(dev_id));
+
+	hci_dev_unlock_bh(hdev);
+	hci_dev_put(hdev);
+
+	return err;
+}
+
 int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
 {
 	unsigned char *buf;
@@ -1200,6 +1267,12 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
 	case MGMT_OP_READ_LOCAL_OOB_DATA:
 		err = read_local_oob_data(sk, buf + sizeof(*hdr), len);
 		break;
+	case MGMT_OP_ADD_REMOTE_OOB_DATA:
+		err = add_remote_oob_data(sk, buf + sizeof(*hdr), len);
+		break;
+	case MGMT_OP_REMOVE_REMOTE_OOB_DATA:
+		err = remove_remote_oob_data(sk, buf + sizeof(*hdr), len);
+		break;
 	default:
 		BT_DBG("Unknown op %u", opcode);
 		err = cmd_status(sk, opcode, 0x01, NULL, 0);
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 05/10] Bluetooth: Add read_local_oob_data management command
From: Szymon Janc @ 2011-02-17 13:16 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc
In-Reply-To: <1297948601-12723-1-git-send-email-szymon.janc@tieto.com>

This patch adds a command to read local OOB data to the managment interface.
The command maps directly to the Read Local OOB Data HCI command.

Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
 include/net/bluetooth/hci.h      |    7 +++
 include/net/bluetooth/hci_core.h |    2 +
 include/net/bluetooth/mgmt.h     |   14 ++++++
 net/bluetooth/hci_event.c        |   15 ++++++
 net/bluetooth/mgmt.c             |   92 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 130 insertions(+), 0 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index a5f8c46..7d1aef9 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -600,6 +600,13 @@ struct hci_cp_write_ssp_mode {
 	__u8     mode;
 } __packed;
 
+#define HCI_OP_READ_LOCAL_OOB_DATA		0x0c57
+struct hci_rp_read_local_oob_data {
+	__u8     status;
+	__u8     hash[16];
+	__u8     randomizer[16];
+} __packed;
+
 #define HCI_OP_READ_INQ_RSP_TX_POWER	0x0c58
 
 #define HCI_OP_READ_LOCAL_VERSION	0x1001
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 7ee921d..704f265 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -746,6 +746,8 @@ int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status);
 int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr);
 int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
 int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
+int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer,
+								u8 status);
 
 /* HCI info for socket */
 #define hci_pi(sk) ((struct hci_pinfo *) sk)
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index a5cc1e0..18e2fb6 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -160,6 +160,20 @@ struct mgmt_cp_set_io_capability {
 	__u8 io_capability;
 } __packed;
 
+
+#define MGMT_OP_READ_LOCAL_OOB_DATA	0x0017
+struct mgmt_cp_read_local_oob_data {
+	__le16 index;
+} __packed;
+struct mgmt_rp_read_local_oob_data {
+	__le16 index;
+	__u8 hash[16];
+	__u8 randomizer[16];
+} __packed;
+struct mgmt_rp_read_local_oob_data_failed {
+	__le16 index;
+} __packed;
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16 opcode;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 1741936..053fcf7 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -796,6 +796,17 @@ 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_read_local_oob_data_reply(struct hci_dev *hdev,
+							struct sk_buff *skb)
+{
+	struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	mgmt_read_local_oob_data_reply_complete(hdev->id, rp->hash,
+						rp->randomizer, rp->status);
+}
+
 static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
 {
 	BT_DBG("%s status 0x%x", hdev->name, status);
@@ -1723,6 +1734,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
 		hci_cc_pin_code_neg_reply(hdev, skb);
 		break;
 
+	case HCI_OP_READ_LOCAL_OOB_DATA:
+		hci_cc_read_local_oob_data_reply(hdev, skb);
+		break;
+
 	case HCI_OP_LE_READ_BUFFER_SIZE:
 		hci_cc_le_read_buffer_size(hdev, skb);
 		break;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index dee82fe..2847934 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1058,6 +1058,60 @@ static int set_io_capability(struct sock *sk, unsigned char *data, u16 len)
 						&dev_id, sizeof(dev_id));
 }
 
+static int read_local_oob_data(struct sock *sk, unsigned char *data, u16 len)
+{
+	struct hci_dev *hdev;
+	struct mgmt_cp_read_local_oob_data *cp;
+	struct mgmt_rp_read_local_oob_data_failed rp;
+	u16 dev_id;
+	int err;
+
+	cp = (void *) data;
+	dev_id = get_unaligned_le16(&cp->index);
+	rp.index = cp->index;
+
+	BT_DBG("hci%u", dev_id);
+
+	hdev = hci_dev_get(dev_id);
+	if (!hdev)
+		return cmd_status(sk, MGMT_OP_READ_LOCAL_OOB_DATA, ENODEV, &rp,
+								sizeof(rp));
+
+	hci_dev_lock_bh(hdev);
+
+	if (!test_bit(HCI_UP, &hdev->flags)) {
+		err = -ENETDOWN;
+		goto unlock;
+	}
+
+	if (!(hdev->features[6] & LMP_SIMPLE_PAIR)) {
+		err = -EPERM;
+		goto unlock;
+	}
+
+	if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, dev_id)) {
+		err = -EBUSY;
+		goto unlock;
+	}
+
+	err = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_DATA, dev_id, data,
+									len);
+	if (err == 0)
+		err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL);
+
+unlock:
+	if (err < 0) {
+		err = cmd_status(sk, MGMT_OP_READ_LOCAL_OOB_DATA, -err, &rp,
+								sizeof(rp));
+		mgmt_pending_remove(MGMT_OP_READ_LOCAL_OOB_DATA, dev_id);
+	}
+
+	hci_dev_unlock_bh(hdev);
+	hci_dev_put(hdev);
+
+	return err;
+}
+
 int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
 {
 	unsigned char *buf;
@@ -1143,6 +1197,9 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
 	case MGMT_OP_SET_IO_CAPABILITY:
 		err = set_io_capability(sk, buf + sizeof(*hdr), len);
 		break;
+	case MGMT_OP_READ_LOCAL_OOB_DATA:
+		err = read_local_oob_data(sk, buf + sizeof(*hdr), len);
+		break;
 	default:
 		BT_DBG("Unknown op %u", opcode);
 		err = cmd_status(sk, opcode, 0x01, NULL, 0);
@@ -1404,3 +1461,38 @@ int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
 
 	return err;
 }
+
+int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer,
+								u8 status)
+{
+	struct pending_cmd *cmd;
+	int err;
+
+	BT_DBG("hci%u status %u", index, status);
+
+	cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, index);
+	if (!cmd)
+		return -ENOENT;
+
+	if (status) {
+		struct mgmt_rp_read_local_oob_data_failed rp;
+		put_unaligned_le16(index, &rp.index);
+
+		err = cmd_status(cmd->sk, MGMT_OP_READ_LOCAL_OOB_DATA, EIO, &rp,
+								sizeof(rp));
+	} else {
+		struct mgmt_rp_read_local_oob_data rp;
+
+		put_unaligned_le16(index, &rp.index);
+		memcpy(rp.hash, hash, 16);
+		memcpy(rp.randomizer, randomizer, 16);
+
+		err = cmd_complete(cmd->sk, MGMT_OP_READ_LOCAL_OOB_DATA, &rp,
+								sizeof(rp));
+	}
+
+	list_del(&cmd->list);
+	mgmt_pending_free(cmd);
+
+	return err;
+}
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 04/10] Bluetooth: Use EIO code to report HCI error to userpace
From: Szymon Janc @ 2011-02-17 13:16 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc
In-Reply-To: <1297948601-12723-1-git-send-email-szymon.janc@tieto.com>

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

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index aee1da6..dee82fe 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1372,8 +1372,7 @@ int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
 		return -ENOENT;
 
 	if (status != 0)
-		err = cmd_status(cmd->sk, MGMT_OP_PIN_CODE_REPLY, status, NULL,
-									0);
+		err = cmd_status(cmd->sk, MGMT_OP_PIN_CODE_REPLY, EIO, NULL, 0);
 	else
 		err = cmd_complete(cmd->sk, MGMT_OP_PIN_CODE_REPLY,
 						bdaddr, sizeof(*bdaddr));
@@ -1394,8 +1393,8 @@ int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
 		return -ENOENT;
 
 	if (status != 0)
-		err = cmd_status(cmd->sk, MGMT_OP_PIN_CODE_NEG_REPLY, status,
-								NULL, 0);
+		err = cmd_status(cmd->sk, MGMT_OP_PIN_CODE_NEG_REPLY, EIO, NULL,
+									0);
 	else
 		err = cmd_complete(cmd->sk, MGMT_OP_PIN_CODE_NEG_REPLY,
 						bdaddr, sizeof(*bdaddr));
-- 
1.7.0.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