Linux bluetooth development
 help / color / mirror / Atom feed
* [RFC 00/20] Simple SMP Just Works implementation
From: Vinicius Costa Gomes @ 2010-11-23 15:06 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

Hi,

This is an implementation of the Just Works SMP procedure, on top of the work
done by Ville (included in this series to give some context). The SMP stuff
starts at 11/20.

The most important thing about this series is the discussion that (I hope)
it will cause.

Some things that I would like to point (in no order):

- the SMP function names follow the spec nomeclature, would it be better to
  use more meaningful names?

- the crypto transform is allocated during the adapter registration, is this
  the best place to do this?

- renaming l2cap.c to l2cap_core.c was the only way we could find to keep the
  SMP implementation separated from the "core" l2cap.

I think this is enough to start a discussion.

So, as the Human Torch would say: Flame on! :-)


Anderson Briglia (3):
  Bluetooth: Start SMP procedure
  Bluetooth: simple SMP pairing negotiation
  Bluetooth: LE SMP Cryptoolbox functions

Ville Tervo (10):
  Bluetooth: Add low energy commands and events
  Bluetooth: Add LE connect support
  Bluetooth: Use LE buffers for LE traffic
  Bluetooth: Add LE connection support to L2CAP
  Bluetooth: Add server socket support for LE connection
  Bluetooth: Do not send disconn comand over LE links
  Bluetooth: Treat LE and ACL links separately on timeout
  Bluetooth: Fix locking balance in l2cap_le_conn_ready
  Bluetooth: Add server socket support for LE connection
  Bluetooth: Add SMP command structures

Vinicius Costa Gomes (7):
  Bluetooth: Fix initiated LE connections
  Bluetooth: fix receiving L2CAP packets over LE
  Bluetooth: Implement the first SMP commands
  Bluetooth: Add support for using the crypto subsystem
  Bluetooth: Add support for SMP confirmation checks
  Bluetooth: Add support for LE Start Encryption
  Bluetooth: Add support for resuming socket when SMP is finished

 include/net/bluetooth/hci.h             |   86 ++++++
 include/net/bluetooth/hci_core.h        |   37 +++-
 include/net/bluetooth/l2cap.h           |   10 +
 include/net/bluetooth/smp.h             |   80 ++++++
 net/bluetooth/Makefile                  |    1 +
 net/bluetooth/hci_conn.c                |  104 +++++++-
 net/bluetooth/hci_core.c                |   94 ++++++-
 net/bluetooth/hci_event.c               |  206 ++++++++++++++-
 net/bluetooth/{l2cap.c => l2cap_core.c} |  237 +++++++++++++---
 net/bluetooth/smp.c                     |  465 +++++++++++++++++++++++++++++++
 10 files changed, 1264 insertions(+), 56 deletions(-)
 create mode 100644 include/net/bluetooth/smp.h
 rename net/bluetooth/{l2cap.c => l2cap_core.c} (96%)
 create mode 100644 net/bluetooth/smp.c

-- 
1.7.3.2


^ permalink raw reply

* [PATCH] Extend discover characteristic by UUID in gatttool to fetch all values
From: Sheldon Demario @ 2010-11-23 12:37 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

If the number of characteristics returned exceeds the MTU size, it will
be needed to ask for more data until the handle range is entirely
searched.
---
 attrib/gatttool.c |   24 +++++++++++++++++++++++-
 1 files changed, 23 insertions(+), 1 deletions(-)

diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index d0ef6d3..6ad2cfb 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -401,9 +401,14 @@ done:
 static void char_read_by_uuid_cb(guint8 status, const guint8 *pdu,
 					guint16 plen, gpointer user_data)
 {
+	struct characteristic_data *char_data = user_data;
 	struct att_data_list *list;
 	int i;
 
+	if ((status == ATT_ECODE_ATTR_NOT_FOUND) &&
+			(char_data->start != opt_start))
+		goto done;
+
 	if (status != 0) {
 		g_printerr("Read characteristics by UUID failed: %s\n",
 							att_ecode2str(status));
@@ -418,6 +423,8 @@ static void char_read_by_uuid_cb(guint8 status, const guint8 *pdu,
 		uint8_t *value = list->data[i];
 		int j;
 
+		char_data->start = att_get_u16(value) + 1;
+
 		g_print("handle: 0x%04x \t value: ", att_get_u16(value));
 		value += 2;
 		for (j = 0; j < list->len - 2; j++, value++)
@@ -427,7 +434,14 @@ static void char_read_by_uuid_cb(guint8 status, const guint8 *pdu,
 
 	att_data_list_free(list);
 
+	gatt_read_char_by_uuid(char_data->attrib, char_data->start,
+					char_data->end, opt_uuid,
+					char_read_by_uuid_cb,
+					char_data);
+
+	return;
 done:
+	g_free(char_data);
 	g_main_loop_quit(event_loop);
 }
 
@@ -436,8 +450,16 @@ static gboolean characteristics_read(gpointer user_data)
 	GAttrib *attrib = user_data;
 
 	if (opt_uuid != NULL) {
+		struct characteristic_data *char_data;
+
+		char_data = g_new(struct characteristic_data, 1);
+		char_data->attrib = attrib;
+		char_data->start = opt_start;
+		char_data->end = opt_end;
+
 		gatt_read_char_by_uuid(attrib, opt_start, opt_end, opt_uuid,
-						char_read_by_uuid_cb, attrib);
+						char_read_by_uuid_cb, char_data);
+
 		return FALSE;
 	}
 
-- 
1.7.3.2


^ permalink raw reply related

* Re: [PATCH v6] Bluetooth: btwilink driver
From: Pavan Savoy @ 2010-11-23 12:37 UTC (permalink / raw)
  To: Dan Carpenter, pavan_savoy, marcel, padovan, linux-bluetooth,
	linux-kernel
In-Reply-To: <20101122164623.GB8882@bicker>

Dan, Marcel, Gustavo,

On Mon, Nov 22, 2010 at 10:16 PM, Dan Carpenter <error27@gmail.com> wrote:
> On Mon, Nov 22, 2010 at 06:08:45AM -0500, pavan_savoy@ti.com wrote:
>> +static int bt_ti_probe(struct platform_device *pdev)
>> +{
>> + =C2=A0 =C2=A0 static struct ti_st *hst;
>> + =C2=A0 =C2=A0 struct hci_dev *hdev;
>> + =C2=A0 =C2=A0 int err;
>> +
>> + =C2=A0 =C2=A0 hst =3D kzalloc(sizeof(struct ti_st), GFP_KERNEL);
>> + =C2=A0 =C2=A0 if (!hst)
>> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -ENOMEM;
>> +
>> + =C2=A0 =C2=A0 /* Expose "hciX" device to user space */
>> + =C2=A0 =C2=A0 hdev =3D hci_alloc_dev();
>> + =C2=A0 =C2=A0 if (!hdev) {
>> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 kfree(hst);
>> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -ENOMEM;
>> + =C2=A0 =C2=A0 }
>> +
>> + =C2=A0 =C2=A0 BT_DBG("hdev %p", hdev);
>> +
>> + =C2=A0 =C2=A0 hst->hdev =3D hdev;
>> + =C2=A0 =C2=A0 hdev->bus =3D HCI_UART;
>> + =C2=A0 =C2=A0 hdev->driver_data =3D hst;
>> + =C2=A0 =C2=A0 hdev->open =3D ti_st_open;
>> + =C2=A0 =C2=A0 hdev->close =3D ti_st_close;
>> + =C2=A0 =C2=A0 hdev->flush =3D NULL;
>> + =C2=A0 =C2=A0 hdev->send =3D ti_st_send_frame;
>> + =C2=A0 =C2=A0 hdev->destruct =3D ti_st_destruct;
>> + =C2=A0 =C2=A0 hdev->owner =3D THIS_MODULE;
>> +
>> + =C2=A0 =C2=A0 err =3D hci_register_dev(hdev);
>> + =C2=A0 =C2=A0 if (err < 0) {
>> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 BT_ERR("Can't register HCI d=
evice error %d", err);
>> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 hci_free_dev(hdev);
>
> =C2=A0 =C2=A0 =C2=A0 =C2=A0Should there be a kfree(hst); here? =C2=A0That=
's how it's done in
> =C2=A0 =C2=A0 =C2=A0 =C2=A0bpa10x_probe() from drivers/bluetooth/bpa10x.c
>
>> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return err;
>> + =C2=A0 =C2=A0 }
>> +
>> + =C2=A0 =C2=A0 BT_DBG(" HCI device registered (hdev %p)", hdev);
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0^
> =C2=A0 =C2=A0 =C2=A0 =C2=A0Quite a few places have an extra space at the =
start.
>
>> +
>> + =C2=A0 =C2=A0 dev_set_drvdata(&pdev->dev, hst);
>> + =C2=A0 =C2=A0 return err;
>> +}
>
> regards,
> dan carpenter

Thanks Dan for the comments,
Marcel, Gustavo - Please provide your comments too... So I can bundle
them all and post a v7 ....

> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth=
" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at =C2=A0http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* [PATCH 3/3] Fix telephony maemo6 driver deinitialization
From: Luiz Augusto von Dentz @ 2010-11-23 11:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1290512024-24547-1-git-send-email-luiz.dentz@gmail.com>

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

Remove all match rules and unregister its interface when telephony_exit
is called.
---
 audio/telephony-maemo6.c |   26 ++++++++++++++++++++++++++
 1 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/audio/telephony-maemo6.c b/audio/telephony-maemo6.c
index 72c8e36..47b0bee 100644
--- a/audio/telephony-maemo6.c
+++ b/audio/telephony-maemo6.c
@@ -1948,6 +1948,8 @@ int telephony_init(void)
 				AG_FEATURE_EXTENDED_ERROR_RESULT_CODES |
 				AG_FEATURE_THREE_WAY_CALLING;
 
+	DBG("");
+
 	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
 
 	if (!dbus_connection_add_filter(connection, signal_filter,
@@ -2007,6 +2009,8 @@ int telephony_init(void)
 
 void telephony_exit(void)
 {
+	DBG("");
+
 	g_free(net.operator_name);
 	net.operator_name = NULL;
 
@@ -2017,8 +2021,30 @@ void telephony_exit(void)
 	g_slist_free(calls);
 	calls = NULL;
 
+	dbus_bus_remove_match(connection,
+			"type=signal,interface=" CSD_CALL_INTERFACE, NULL);
+	dbus_bus_remove_match(connection,
+			"type=signal,interface=" CSD_CALL_INSTANCE, NULL);
+	dbus_bus_remove_match(connection,
+			"type=signal,interface=" CSD_CALL_CONFERENCE, NULL);
+	dbus_bus_remove_match(connection,
+			"type=signal,interface=" CSD_CSNET_REGISTRATION,
+			NULL);
+	dbus_bus_remove_match(connection,
+			"type=signal,interface=" CSD_CSNET_OPERATOR,
+			NULL);
+	dbus_bus_remove_match(connection,
+			"type=signal,interface=" CSD_CSNET_SIGNAL,
+			NULL);
+	dbus_bus_remove_match(connection,
+				"type=signal,interface=" SSC_DBUS_IFACE
+				",member=modem_state_changed_ind", NULL);
+
 	dbus_connection_remove_filter(connection, signal_filter, NULL);
 
+	g_dbus_unregister_interface(connection, TELEPHONY_MAEMO_PATH,
+						TELEPHONY_MAEMO_INTERFACE);
+
 	dbus_connection_unref(connection);
 	connection = NULL;
 }
-- 
1.7.1


^ permalink raw reply related

* [PATCH 2/3] Fix telephony dummy driver
From: Luiz Augusto von Dentz @ 2010-11-23 11:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1290512024-24547-1-git-send-email-luiz.dentz@gmail.com>

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

Make it unregister its interface on telephony_exit
---
 audio/telephony-dummy.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/audio/telephony-dummy.c b/audio/telephony-dummy.c
index 06cb798..54b1857 100644
--- a/audio/telephony-dummy.c
+++ b/audio/telephony-dummy.c
@@ -417,6 +417,8 @@ int telephony_init(void)
 				AG_FEATURE_ENHANCED_CALL_STATUS |
 				AG_FEATURE_EXTENDED_ERROR_RESULT_CODES;
 
+	DBG("");
+
 	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
 
 	if (g_dbus_register_interface(connection, TELEPHONY_DUMMY_PATH,
@@ -436,6 +438,10 @@ int telephony_init(void)
 
 void telephony_exit(void)
 {
+	DBG("");
+
+	g_dbus_unregister_interface(connection, TELEPHONY_DUMMY_PATH,
+						TELEPHONY_DUMMY_IFACE);
 	dbus_connection_unref(connection);
 	connection = NULL;
 }
-- 
1.7.1


^ permalink raw reply related

* [PATCH 1/3] Fix not deinitializing telephony driver when there is no adapter powered
From: Luiz Augusto von Dentz @ 2010-11-23 11:33 UTC (permalink / raw)
  To: linux-bluetooth

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

This changes hook telephony driver de/initialization to powered state so
telephony drivers can now free their resources when there is no adapter
active in the system.
---
 audio/manager.c |   59 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/audio/manager.c b/audio/manager.c
index 816c807..8a5616d 100644
--- a/audio/manager.c
+++ b/audio/manager.c
@@ -96,6 +96,7 @@ typedef enum {
 
 struct audio_adapter {
 	struct btd_adapter *btd_adapter;
+	gboolean powered;
 	uint32_t hsp_ag_record_id;
 	uint32_t hfp_ag_record_id;
 	uint32_t hfp_hs_record_id;
@@ -858,6 +859,49 @@ static struct audio_adapter *audio_adapter_get(struct btd_adapter *adapter)
 	return adp;
 }
 
+static void state_changed(struct btd_adapter *adapter, gboolean powered)
+{
+	struct audio_adapter *adp;
+	static gboolean telephony = FALSE;
+	GSList *l;
+
+	DBG("%s powered %s", adapter_get_path(adapter),
+						powered ? "on" : "off");
+
+	/* ignore powered change, adapter is powering down */
+	if (powered && adapter_powering_down(adapter))
+		return;
+
+	adp = find_adapter(adapters, adapter);
+	if (!adp)
+		return;
+
+	adp->powered = powered;
+
+	if (powered) {
+		/* telephony driver already initialized*/
+		if (telephony == TRUE)
+			return;
+		telephony_init();
+		telephony = TRUE;
+		return;
+	}
+
+	/* telephony not initialized just ignore power down */
+	if (telephony == FALSE)
+		return;
+
+	for (l = adapters; l; l = l->next) {
+		adp = l->data;
+
+		if (adp->powered == TRUE)
+			return;
+	}
+
+	telephony_exit();
+	telephony = FALSE;
+}
+
 static int headset_server_probe(struct btd_adapter *adapter)
 {
 	struct audio_adapter *adp;
@@ -871,10 +915,15 @@ static int headset_server_probe(struct btd_adapter *adapter)
 		return -EINVAL;
 
 	err = headset_server_init(adp);
-	if (err < 0)
+	if (err < 0) {
 		audio_adapter_unref(adp);
+		return err;
+	}
 
-	return err;
+	btd_adapter_register_powered_callback(adapter, state_changed);
+	state_changed(adapter, TRUE);
+
+	return 0;
 }
 
 static void headset_server_remove(struct btd_adapter *adapter)
@@ -910,6 +959,8 @@ static void headset_server_remove(struct btd_adapter *adapter)
 		adp->hfp_ag_server = NULL;
 	}
 
+	btd_adapter_unregister_powered_callback(adapter, state_changed);
+
 	audio_adapter_unref(adp);
 }
 
@@ -1177,10 +1228,8 @@ proceed:
 	if (enabled.media)
 		btd_register_adapter_driver(&media_server_driver);
 
-	if (enabled.headset) {
-		telephony_init();
+	if (enabled.headset)
 		btd_register_adapter_driver(&headset_server_driver);
-	}
 
 	if (enabled.gateway)
 		btd_register_adapter_driver(&gateway_server_driver);
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH v2] hciattach: download configuration at user requested baud rate
From: Johan Hedberg @ 2010-11-23 11:11 UTC (permalink / raw)
  To: Suraj Sumangala; +Cc: linux-bluetooth, Jothikumar.Mothilal
In-Reply-To: <1290509963-11918-1-git-send-email-suraj@atheros.com>

Hi Suraj,

On Tue, Nov 23, 2010, Suraj Sumangala wrote:
> This patch support downloading configuration for
> Atheros AR300x HCI UART chip at user requested baud rate
> instead of the initial baud rate.
> ---
>  tools/hciattach.c       |    2 +-
>  tools/hciattach.h       |    3 +-
>  tools/hciattach_ath3k.c |   98 +++++++++++++++++++++++++++++++++-------------
>  3 files changed, 73 insertions(+), 30 deletions(-)

Thanks for the update. Now this patch is also pushed upstream.

Johan

^ permalink raw reply

* Re: [PATCH] hciattach: makes set_speed return error if any one operation fail
From: Johan Hedberg @ 2010-11-23 11:10 UTC (permalink / raw)
  To: Suraj Sumangala; +Cc: linux-bluetooth, Jothikumar.Mothilal
In-Reply-To: <1290508783-31183-1-git-send-email-suraj@atheros.com>

Hi Suraj,

On Tue, Nov 23, 2010, Suraj Sumangala wrote:
> This patch lets set_speed function changing UART baud rate
> to return an error code if any one operation fails
> instead of returning only the last operation's status.
> 
> ---
>  tools/hciattach.c |   13 ++++++++++---
>  1 files changed, 10 insertions(+), 3 deletions(-)

Pushed upstream. Thanks.

Johan

^ permalink raw reply

* Re: [PATCHv4 6/7] Update D-Bus OOB API with RequestPairing method
From: Szymon Janc @ 2010-11-23 11:05 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org
In-Reply-To: <1290509592-9262-7-git-send-email-szymon.janc@tieto.com>

Fixed version (.orig removed)

---
 doc/oob-api.txt |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/doc/oob-api.txt b/doc/oob-api.txt
index 4796e4c..e08f6f8 100644
--- a/doc/oob-api.txt
+++ b/doc/oob-api.txt
@@ -60,3 +60,17 @@ Methods		void RegisterProvider(object provider)
 			Possible errors: org.bluez.Error.ReadFailed
 					 org.bluez.Error.NoProvider
 					 org.bluez.Error.InProgress
+
+--------------------------------------------------------------------------------
+
+Service		unique name
+Interface	org.bluez.Agent
+Object path	freely definable
+
+Methods		void RequestPairing(object device)
+
+			This method gets called when the service daemon
+			needs to confirm incoming pairing request.
+
+			Possible errors: org.bluez.Error.Rejected
+					 org.bluez.Error.Canceled
-- 
1.7.1

^ permalink raw reply related

* [PATCH v2] hciattach: download configuration at user requested baud rate
From: Suraj Sumangala @ 2010-11-23 10:59 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jothikumar.Mothilal, Suraj Sumangala

This patch support downloading configuration for
Atheros AR300x HCI UART chip at user requested baud rate
instead of the initial baud rate.
---
 tools/hciattach.c       |    2 +-
 tools/hciattach.h       |    3 +-
 tools/hciattach_ath3k.c |   98 +++++++++++++++++++++++++++++++++-------------
 3 files changed, 73 insertions(+), 30 deletions(-)

diff --git a/tools/hciattach.c b/tools/hciattach.c
index 7cb8e9e..e4d5aa1 100644
--- a/tools/hciattach.c
+++ b/tools/hciattach.c
@@ -311,7 +311,7 @@ static int texasalt(int fd, struct uart_t *u, struct termios *ti)
 
 static int ath3k_ps(int fd, struct uart_t *u, struct termios *ti)
 {
-	return ath3k_init(fd, u->bdaddr, u->speed);
+	return ath3k_init(fd, u->speed, u->init_speed, u->bdaddr, ti);
 }
 
 static int ath3k_pm(int fd, struct uart_t *u, struct termios *ti)
diff --git a/tools/hciattach.h b/tools/hciattach.h
index 2d26b77..fed0d11 100644
--- a/tools/hciattach.h
+++ b/tools/hciattach.h
@@ -50,6 +50,7 @@ int texas_post(int fd, struct termios *ti);
 int texasalt_init(int fd, int speed, struct termios *ti);
 int stlc2500_init(int fd, bdaddr_t *bdaddr);
 int bgb2xx_init(int dd, bdaddr_t *bdaddr);
-int ath3k_init(int fd, char *bdaddr, int speed);
+int ath3k_init(int fd, int speed, int init_speed, char *bdaddr,
+						struct termios *ti);
 int ath3k_post(int fd, int pm);
 int qualcomm_init(int fd, int speed, struct termios *ti, const char *bdaddr);
diff --git a/tools/hciattach_ath3k.c b/tools/hciattach_ath3k.c
index 70ade30..728e660 100644
--- a/tools/hciattach_ath3k.c
+++ b/tools/hciattach_ath3k.c
@@ -922,14 +922,49 @@ int ath3k_post(int fd, int pm)
 #define WRITE_BAUD_CMD_LEN   6
 #define MAX_CMD_LEN          WRITE_BDADDR_CMD_LEN
 
+static int set_cntrlr_baud(int fd, int speed)
+{
+	int baud;
+	struct timespec tm = { 0, 500000 };
+	unsigned char cmd[MAX_CMD_LEN], rsp[HCI_MAX_EVENT_SIZE];
+	unsigned char *ptr = cmd + 1;
+	hci_command_hdr *ch = (void *)ptr;
+
+	cmd[0] = HCI_COMMAND_PKT;
+
+	/* set controller baud rate to user specified value */
+	ptr = cmd + 1;
+	ch->opcode = htobs(cmd_opcode_pack(HCI_VENDOR_CMD_OGF,
+						HCI_CHG_BAUD_CMD_OCF));
+	ch->plen = 2;
+	ptr += HCI_COMMAND_HDR_SIZE;
+
+	baud = speed/100;
+	ptr[0] = (char)baud;
+	ptr[1] = (char)(baud >> 8);
+
+	if (write(fd, cmd, WRITE_BAUD_CMD_LEN) != WRITE_BAUD_CMD_LEN) {
+		perror("Failed to write change baud rate command");
+		return -ETIMEDOUT;
+	}
+
+	nanosleep(&tm, NULL);
+
+	if (read_hci_event(fd, rsp, sizeof(rsp)) < 0)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
 /*
  * Atheros AR300x specific initialization and configuration file
  * download
  */
-int ath3k_init(int fd, char *bdaddr, int speed)
+int ath3k_init(int fd, int speed, int init_speed, char *bdaddr,
+						struct termios *ti)
 {
 	int r;
-	int baud;
+	int err = 0;
 	struct timespec tm = { 0, 500000 };
 	unsigned char cmd[MAX_CMD_LEN], rsp[HCI_MAX_EVENT_SIZE];
 	unsigned char *ptr = cmd + 1;
@@ -937,11 +972,23 @@ int ath3k_init(int fd, char *bdaddr, int speed)
 
 	cmd[0] = HCI_COMMAND_PKT;
 
+	/* set both controller and host baud rate to maximum possible value */
+	err = set_cntrlr_baud(fd, speed);
+	if (err < 0)
+		return err;
+
+	err = set_speed(fd, ti, speed);
+	if (err < 0) {
+		perror("Can't set required baud rate");
+		return err;
+	}
+
 	/* Download PS and patch */
 	r = ath_ps_download(fd);
 	if (r < 0) {
 		perror("Failed to Download configuration");
-		return -ETIMEDOUT;
+		err = -ETIMEDOUT;
+		goto failed;
 	}
 
 	/* Write BDADDR */
@@ -960,12 +1007,14 @@ int ath3k_init(int fd, char *bdaddr, int speed)
 		if (write(fd, cmd, WRITE_BDADDR_CMD_LEN) !=
 					WRITE_BDADDR_CMD_LEN) {
 			perror("Failed to write BD_ADDR command\n");
-			return -ETIMEDOUT;
+			err = -ETIMEDOUT;
+			goto failed;
 		}
 
 		if (read_hci_event(fd, rsp, sizeof(rsp)) < 0) {
 			perror("Failed to set BD_ADDR\n");
-			return -ETIMEDOUT;
+			err = -ETIMEDOUT;
+			goto failed;
 		}
 	}
 
@@ -975,33 +1024,26 @@ int ath3k_init(int fd, char *bdaddr, int speed)
 	cmd[3] = 0x00;
 
 	r = write(fd, cmd, 4);
-	if (r != 4)
-		return -ETIMEDOUT;
+	if (r != 4) {
+		err = -ETIMEDOUT;
+		goto failed;
+	}
 
 	nanosleep(&tm, NULL);
-	if (read_hci_event(fd, rsp, sizeof(rsp)) < 0)
-		return -ETIMEDOUT;
-
-	/* set controller baud rate to user specified value */
-	ptr = cmd + 1;
-	ch->opcode = htobs(cmd_opcode_pack(HCI_VENDOR_CMD_OGF,
-						HCI_CHG_BAUD_CMD_OCF));
-	ch->plen = 2;
-	ptr += HCI_COMMAND_HDR_SIZE;
-
-	baud = speed/100;
-	ptr[0] = (char)baud;
-	ptr[1] = (char)(baud >> 8);
-
-	if (write(fd, cmd, WRITE_BAUD_CMD_LEN) != WRITE_BAUD_CMD_LEN) {
-		perror("Failed to write change baud rate command");
-		return -ETIMEDOUT;
+	if (read_hci_event(fd, rsp, sizeof(rsp)) < 0) {
+		err = -ETIMEDOUT;
+		goto failed;
 	}
 
-	nanosleep(&tm, NULL);
+	err = set_cntrlr_baud(fd, speed);
+	if (err < 0)
+		return err;
 
-	if (read_hci_event(fd, rsp, sizeof(rsp)) < 0)
-		return -ETIMEDOUT;
+failed:
+	if (err < 0) {
+		set_cntrlr_baud(fd, init_speed);
+		set_speed(fd, ti, init_speed);
+	}
 
-	return 0;
+	return err;
 }
-- 
1.7.0.4


^ permalink raw reply related

* [PATCHv4 7/7] Add RequestPairing method in simple-agent for accepting incoming OOB pairing requests
From: Szymon Janc @ 2010-11-23 10:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1290509592-9262-1-git-send-email-szymon.janc@tieto.com>

---
 test/simple-agent |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/test/simple-agent b/test/simple-agent
index f2cc3dd..bbadd31 100755
--- a/test/simple-agent
+++ b/test/simple-agent
@@ -69,6 +69,16 @@ class Agent(dbus.service.Object):
 		raise Rejected("Mode change by user")
 
 	@dbus.service.method("org.bluez.Agent",
+			in_signature="o", out_signature="")
+
+	def RequestPairing(self, device):
+		print "RequestPairing (%s)" % (device)
+		pair = raw_input("Incoming pairing request, allow? (yes/no): ")
+		if (pair == "yes"):
+			return
+		raise Rejected("Not allowed")
+
+	@dbus.service.method("org.bluez.Agent",
 					in_signature="", out_signature="")
 	def Cancel(self):
 		print "Cancel"
-- 
1.7.1


^ permalink raw reply related

* [PATCHv4 6/7] Update D-Bus OOB API with RequestPairing method
From: Szymon Janc @ 2010-11-23 10:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1290509592-9262-1-git-send-email-szymon.janc@tieto.com>

---
 doc/oob-api.txt      |   14 +++++++++
 doc/oob-api.txt.orig |   79 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 93 insertions(+), 0 deletions(-)
 create mode 100644 doc/oob-api.txt.orig

diff --git a/doc/oob-api.txt b/doc/oob-api.txt
index 4796e4c..e08f6f8 100644
--- a/doc/oob-api.txt
+++ b/doc/oob-api.txt
@@ -60,3 +60,17 @@ Methods		void RegisterProvider(object provider)
 			Possible errors: org.bluez.Error.ReadFailed
 					 org.bluez.Error.NoProvider
 					 org.bluez.Error.InProgress
+
+--------------------------------------------------------------------------------
+
+Service		unique name
+Interface	org.bluez.Agent
+Object path	freely definable
+
+Methods		void RequestPairing(object device)
+
+			This method gets called when the service daemon
+			needs to confirm incoming pairing request.
+
+			Possible errors: org.bluez.Error.Rejected
+					 org.bluez.Error.Canceled
diff --git a/doc/oob-api.txt.orig b/doc/oob-api.txt.orig
new file mode 100644
index 0000000..95dd3a4
--- /dev/null
+++ b/doc/oob-api.txt.orig
@@ -0,0 +1,79 @@
+BlueZ D-Bus OOB API description
+*******************************
+
+Copyright (C) 2010  ST-Ericsson SA
+
+Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
+
+OOB hierarchy
+=================
+
+Service         unique name
+Interface       org.bluez.OobProvider
+Object path     freely definable
+
+Methods		array{byte} hash, array{byte} randomizer
+			RequestRemoteOobData(object device)
+
+			This method gets called when the service daemon needs to
+			get device's hash and randomizer for an OOB
+			authentication. Each array should be 16 bytes long.
+
+			Possible errors: org.bluez.Error.NoData
+
+		void Release()
+
+			This method gets called when D-Bus plug-in for OOB was
+			deactivated. There is no need to unregister provider,
+			because when this method gets called it has already been
+			unregistered.
+
+--------------------------------------------------------------------------------
+
+Service		org.bluez
+Interface	org.bluez.OobManager
+Object path	[variable prefix]/{hci0,hci1,...}
+
+Methods		void RegisterProvider(object provider)
+
+			This method registers provider for D-Bus OOB plug-in.
+			When provider is successfully registered plug-in becomes
+			active. Only one provider per adapter can be registered.
+
+			Possible errors: org.bluez.Error.AlreadyExists
+
+		void UnregisterProvider(object provider)
+
+			This method unregisters provider for D-Bus OOB plug-in.
+
+			Possible errors: org.bluez.Error.DoesNotExist
+
+		array{byte} hash, array{byte} randomizer ReadLocalOobData()
+
+			This method reads local OOB data for adapter. Return
+			value is pair of arrays 16 bytes each. Only registered
+			provider should call this method.
+
+			Note: This method will generate and return new local
+			OOB data.
+
+			Possible errors: org.bluez.Error.ReadFailed
+					 org.bluez.Error.NoProvider
+					 org.bluez.Error.InProgress
+<<<<<<< HEAD
+=======
+
+--------------------------------------------------------------------------------
+
+Service		unique name
+Interface	org.bluez.Agent
+Object path	freely definable
+
+Methods		void RequestPairing(object device)
+
+			This method gets called when the service daemon
+			needs to confirm incoming pairing request.
+
+			Possible errors: org.bluez.Error.Rejected
+					 org.bluez.Error.Canceled
+>>>>>>> 4375d12... doc fix
-- 
1.7.1


^ permalink raw reply related

* [PATCHv4 5/7] Add request for accepting incoming pairing requests with OOB mechanism
From: Szymon Janc @ 2010-11-23 10:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1290509592-9262-1-git-send-email-szymon.janc@tieto.com>

---
 plugins/hciops.c |   41 ++++++++++++++++++++++++++++---------
 src/adapter.c    |    7 ++++++
 src/adapter.h    |    4 +++
 src/agent.c      |   59 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/agent.h      |    3 ++
 src/device.c     |   22 ++++++++++++++++++++
 src/device.h     |    1 +
 src/event.c      |   36 ++++++++++++++++++++++++++++++++
 src/event.h      |    1 +
 9 files changed, 163 insertions(+), 11 deletions(-)

diff --git a/plugins/hciops.c b/plugins/hciops.c
index c62ac51..e54f706 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -663,15 +663,8 @@ static void remote_oob_data_request(int index, void *ptr)
 	adapter = manager_find_adapter(&BDADDR(index));
 	device = adapter_find_device(adapter, da);
 
-	if (!device_get_oob_data(device, NULL, NULL) {
-		remote_oob_data_reply_cp cp;
-
-		bacpy(&cp.bdaddr, dba);
-		device_get_oob_data(device,cp.hash,cp.randomizer);
-
-		hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_REPLY,
-				REMOTE_OOB_DATA_REPLY_CP_SIZE, &cp);
-	} else
+	if (!device_get_oob_data(device, NULL, NULL) ||
+				btd_event_user_pairing(&BDADDR(index), dba))
 		hci_send_cmd(SK(index),
 				OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_NEG_REPLY, 6,
 				ptr);
@@ -2463,6 +2456,34 @@ static int hciops_passkey_reply(int index, bdaddr_t *bdaddr, uint32_t passkey)
 	return err;
 }
 
+static int hciops_pairing_reply(int index, struct btd_device *device,
+					gboolean approved)
+{
+	int err;
+
+	if (approved) {
+		remote_oob_data_reply_cp cp;
+
+		device_get_address(device, &cp.bdaddr);
+		device_get_oob_data(device,cp.hash,cp.randomizer);
+
+		err = hci_send_cmd(SK(index), OGF_LINK_CTL,
+					OCF_REMOTE_OOB_DATA_REPLY,
+					REMOTE_OOB_DATA_REPLY_CP_SIZE, &cp);
+	} else {
+		bdaddr_t bdaddr;
+
+		device_get_address(device, &bdaddr);
+		err = hci_send_cmd(SK(index), OGF_LINK_CTL,
+				OCF_REMOTE_OOB_DATA_NEG_REPLY, 6, &bdaddr);
+	}
+
+	if (err < 0)
+		err = -errno;
+
+	return err;
+}
+
 static int hciops_get_auth_info(int index, bdaddr_t *bdaddr, uint8_t *auth)
 {
 	struct hci_auth_info_req req;
@@ -2571,7 +2592,6 @@ static void hciops_io_capa_request_reply(int index, struct btd_device *device)
 					IO_CAPABILITY_REPLY_CP_SIZE, &cp);
 }
 
-
 static struct btd_adapter_ops hci_ops = {
 	.setup = hciops_setup,
 	.cleanup = hciops_cleanup,
@@ -2607,6 +2627,7 @@ static struct btd_adapter_ops hci_ops = {
 	.pincode_reply = hciops_pincode_reply,
 	.confirm_reply = hciops_confirm_reply,
 	.passkey_reply = hciops_passkey_reply,
+	.pairing_reply = hciops_pairing_reply,
 	.get_auth_info = hciops_get_auth_info,
 	.read_scan_enable = hciops_read_scan_enable,
 	.write_le_host = hciops_write_le_host,
diff --git a/src/adapter.c b/src/adapter.c
index f0c2dad..78b5ce3 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3673,6 +3673,13 @@ int btd_adapter_passkey_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 	return adapter_ops->passkey_reply(adapter->dev_id, bdaddr, passkey);
 }
 
+int btd_adapter_pairing_reply(struct btd_adapter *adapter,
+				struct btd_device *device, gboolean approve)
+{
+	DBG("reply %u", approve);
+	return adapter_ops->pairing_reply(adapter->dev_id, device, approve);
+}
+
 int btd_adapter_get_auth_info(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 								uint8_t *auth)
 {
diff --git a/src/adapter.h b/src/adapter.h
index 16b7f67..e2bd94a 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -225,6 +225,8 @@ struct btd_adapter_ops {
 	int (*pincode_reply) (int index, bdaddr_t *bdaddr, const char *pin);
 	int (*confirm_reply) (int index, bdaddr_t *bdaddr, gboolean success);
 	int (*passkey_reply) (int index, bdaddr_t *bdaddr, uint32_t passkey);
+	int (*pairing_reply) (int index, struct btd_device *device,
+						gboolean success);
 	int (*get_auth_info) (int index, bdaddr_t *bdaddr, uint8_t *auth);
 	int (*read_scan_enable) (int index);
 	int (*write_le_host) (int index, uint8_t le, uint8_t simul);
@@ -276,6 +278,8 @@ int btd_adapter_confirm_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 							gboolean success);
 int btd_adapter_passkey_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 							uint32_t passkey);
+int btd_adapter_pairing_reply(struct btd_adapter *adapter,
+				struct btd_device *device, gboolean approve);
 
 int btd_adapter_get_auth_info(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 								uint8_t *auth);
diff --git a/src/agent.c b/src/agent.c
index 2ddfd6e..7dd969e 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -55,7 +55,8 @@ typedef enum {
 	AGENT_REQUEST_CONFIRMATION,
 	AGENT_REQUEST_PINCODE,
 	AGENT_REQUEST_AUTHORIZE,
-	AGENT_REQUEST_CONFIRM_MODE
+	AGENT_REQUEST_CONFIRM_MODE,
+	AGENT_REQUEST_PAIRING
 } agent_request_type_t;
 
 struct agent {
@@ -693,6 +694,62 @@ failed:
 	return err;
 }
 
+static int pairing_request_new(struct agent_request *req,
+					const char *device_path)
+{
+	struct agent *agent = req->agent;
+
+	req->msg = dbus_message_new_method_call(agent->name, agent->path,
+				"org.bluez.Agent", "RequestPairing");
+	if (req->msg == NULL) {
+		error("Couldn't allocate D-Bus message");
+		return -ENOMEM;
+	}
+
+	dbus_message_append_args(req->msg,
+				DBUS_TYPE_OBJECT_PATH, &device_path,
+				DBUS_TYPE_INVALID);
+
+	if (dbus_connection_send_with_reply(connection, req->msg,
+				&req->call, REQUEST_TIMEOUT) == FALSE) {
+		error("D-Bus send failed");
+		return -EIO;
+	}
+
+	dbus_pending_call_set_notify(req->call, simple_agent_reply, req, NULL);
+
+	return 0;
+}
+
+int agent_request_pairing (struct agent *agent, struct btd_device *device,
+			agent_cb cb, void *user_data, GDestroyNotify destroy)
+{
+	struct agent_request *req;
+	const gchar *dev_path = device_get_path(device);
+	int err;
+
+	if (agent->request)
+		return -EBUSY;
+
+	DBG("Calling Agent.RequestPairing: name=%s, path=%s", agent->name,
+								agent->path);
+
+	req = agent_request_new(agent, AGENT_REQUEST_PAIRING, cb,
+							user_data, destroy);
+
+	err = pairing_request_new(req, dev_path);
+	if (err < 0)
+		goto failed;
+
+	agent->request = req;
+
+	return 0;
+
+failed:
+	agent_request_free(req, FALSE);
+	return err;
+}
+
 static int request_fallback(struct agent_request *req,
 				DBusPendingCallNotifyFunction function)
 {
diff --git a/src/agent.h b/src/agent.h
index e184250..5aa2702 100644
--- a/src/agent.h
+++ b/src/agent.h
@@ -64,6 +64,9 @@ int agent_request_confirmation(struct agent *agent, struct btd_device *device,
 int agent_display_passkey(struct agent *agent, struct btd_device *device,
 				uint32_t passkey);
 
+int agent_request_pairing (struct agent *agent, struct btd_device *device,
+			agent_cb cb, void *user_data, GDestroyNotify destroy);
+
 int agent_cancel(struct agent *agent);
 
 gboolean agent_is_busy(struct agent *agent, void *user_data);
diff --git a/src/device.c b/src/device.c
index fd3c3b3..c1a3bfe 100644
--- a/src/device.c
+++ b/src/device.c
@@ -2243,6 +2243,21 @@ static void passkey_cb(struct agent *agent, DBusError *err,
 	device->authr->agent = NULL;
 }
 
+static void pairing_cb(struct agent *agent, DBusError *err, void *data)
+{
+	struct authentication_req *auth = data;
+	struct btd_device *device = auth->device;
+
+	/* No need to reply anything if the authentication already failed */
+	if (auth->cb == NULL)
+		return;
+
+	((agent_cb) auth->cb)(agent, err, device);
+
+	device->authr->cb = NULL;
+	device->authr->agent = NULL;
+}
+
 int device_request_authentication(struct btd_device *device, auth_type_t type,
 						uint32_t passkey, void *cb)
 {
@@ -2281,6 +2296,10 @@ int device_request_authentication(struct btd_device *device, auth_type_t type,
 	case AUTH_TYPE_NOTIFY:
 		err = agent_display_passkey(agent, device, passkey);
 		break;
+	case AUTH_TYPE_PAIRING:
+		err = agent_request_pairing (agent, device, pairing_cb, auth,
+									NULL);
+		break;
 	case AUTH_TYPE_AUTO:
 		err = 0;
 		break;
@@ -2322,6 +2341,9 @@ static void cancel_authentication(struct authentication_req *auth)
 	case AUTH_TYPE_PASSKEY:
 		((agent_passkey_cb) auth->cb)(agent, &err, 0, device);
 		break;
+	case AUTH_TYPE_PAIRING:
+		((agent_cb) auth->cb)(agent, &err, device);
+		break;
 	case AUTH_TYPE_NOTIFY:
 	case AUTH_TYPE_AUTO:
 		/* User Notify/Auto doesn't require any reply */
diff --git a/src/device.h b/src/device.h
index 1823f65..5e673d0 100644
--- a/src/device.h
+++ b/src/device.h
@@ -33,6 +33,7 @@ typedef enum {
 	AUTH_TYPE_CONFIRM,
 	AUTH_TYPE_NOTIFY,
 	AUTH_TYPE_AUTO,
+	AUTH_TYPE_PAIRING
 } auth_type_t;
 
 struct btd_device *device_create(DBusConnection *conn, struct btd_adapter *adapter,
diff --git a/src/event.c b/src/event.c
index a88a8f5..316273a 100644
--- a/src/event.c
+++ b/src/event.c
@@ -175,6 +175,15 @@ static void passkey_cb(struct agent *agent, DBusError *err, uint32_t passkey,
 	btd_adapter_passkey_reply(adapter, &bdaddr, passkey);
 }
 
+static void pairing_cb(struct agent *agent, DBusError *err, void *user_data)
+{
+	struct btd_device *device = user_data;
+	struct btd_adapter *adapter = device_get_adapter(device);
+	gboolean approve = (err == NULL) ? TRUE : FALSE;
+
+	btd_adapter_pairing_reply(adapter, device, approve);
+}
+
 int btd_event_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey)
 {
 	struct btd_adapter *adapter;
@@ -264,6 +273,33 @@ int btd_event_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey)
 								passkey, NULL);
 }
 
+int btd_event_user_pairing(bdaddr_t *sba, bdaddr_t *dba)
+{
+	struct btd_adapter *adapter;
+	struct btd_device *device;
+	struct agent *agent;
+	uint8_t cap;
+
+	if (!get_adapter_and_device(sba, dba, &adapter, &device, TRUE))
+		return -ENODEV;
+
+	agent = device_get_agent(device);
+	if (!agent)
+		return -ENODEV;
+
+	cap = agent_get_io_capability(agent);
+
+	/* If initiator or agent has no input capability allow pairing
+	 * immediately. */
+	if (device_is_bonding(device, NULL) || cap == 0x00 || cap == 0x03) {
+		btd_adapter_pairing_reply(adapter, device, TRUE);
+		return 0;
+	}
+
+	return device_request_authentication(device, AUTH_TYPE_PAIRING, 0,
+								pairing_cb);
+}
+
 void btd_event_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer,
 								uint8_t status)
 {
diff --git a/src/event.h b/src/event.h
index 5c122ea..3fde56b 100644
--- a/src/event.h
+++ b/src/event.h
@@ -41,6 +41,7 @@ int btd_event_set_io_cap(bdaddr_t *local, bdaddr_t *remote,
 int btd_event_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey);
 int btd_event_user_passkey(bdaddr_t *sba, bdaddr_t *dba);
 int btd_event_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey);
+int btd_event_user_pairing(bdaddr_t *sba, bdaddr_t *dba);
 int btd_event_link_key_notify(bdaddr_t *local, bdaddr_t *peer,
 				uint8_t *key, uint8_t key_type,
 				int pin_length, uint8_t old_key_type);
-- 
1.7.1


^ permalink raw reply related

* [PATCHv4 4/7] Add simple-oobprovider for testing
From: Szymon Janc @ 2010-11-23 10:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1290509592-9262-1-git-send-email-szymon.janc@tieto.com>

---
 test/simple-oobprovider |   57 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 57 insertions(+), 0 deletions(-)
 create mode 100755 test/simple-oobprovider

diff --git a/test/simple-oobprovider b/test/simple-oobprovider
new file mode 100755
index 0000000..e5181f3
--- /dev/null
+++ b/test/simple-oobprovider
@@ -0,0 +1,57 @@
+#!/usr/bin/python
+# Copyright (C) 2010  ST-Ericsson SA
+# Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
+
+import gobject
+
+import sys
+import dbus
+import dbus.service
+import dbus.mainloop.glib
+
+class NoOobData(dbus.DBusException):
+        _dbus_error_name = "org.bluez.Error.NoData"
+
+
+class Provider(dbus.service.Object):
+
+	remotedata = None
+
+	@dbus.service.method("org.bluez.OobProvider",
+					in_signature="s", out_signature="ayay")
+
+	def RequestRemoteOobData(self, device):
+		print "RequestRemoteOobData for %s" % (device)
+		if (self.remotedata != None):
+			return self.remotedata
+		raise NoOobData("No OOB data present")
+
+if __name__ == '__main__':
+	dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+
+	bus = dbus.SystemBus()
+
+	manager = dbus.Interface(bus.get_object("org.bluez", "/"),
+			"org.bluez.Manager")
+
+	adapter_path = manager.DefaultAdapter()
+	adapter = dbus.Interface(bus.get_object("org.bluez",
+			adapter_path), "org.bluez.OobManager")
+	path = "/test/oobprovider"
+	provider = Provider(bus, path)
+
+	mainloop = gobject.MainLoop()
+
+	adapter.RegisterProvider(path)
+
+	print "Local data for %s:" % (adapter_path)
+	print adapter.ReadLocalOobData()
+
+	provider.remotedata = input("Provide remote data (in python syntax):\n")
+
+	print "You may try pairing now"
+
+	mainloop.run()
+
+	#adapter.UnregisterProvider(path)
+	#print "Provider unregistered"
-- 
1.7.1


^ permalink raw reply related

* [PATCHv4 3/7] Add D-Bus OOB API documentation
From: Szymon Janc @ 2010-11-23 10:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1290509592-9262-1-git-send-email-szymon.janc@tieto.com>

---
 Makefile.am     |    2 +-
 doc/oob-api.txt |   62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+), 1 deletions(-)
 create mode 100644 doc/oob-api.txt

diff --git a/Makefile.am b/Makefile.am
index 9607553..ab56edc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -360,7 +360,7 @@ EXTRA_DIST += doc/manager-api.txt \
 		doc/service-api.txt doc/agent-api.txt doc/attribute-api.txt \
 		doc/serial-api.txt doc/network-api.txt \
 		doc/input-api.txt doc/audio-api.txt doc/control-api.txt \
-		doc/hfp-api.txt doc/assigned-numbers.txt
+		doc/hfp-api.txt doc/assigned-numbers.txt doc/oob-api.txt
 
 AM_YFLAGS = -d
 
diff --git a/doc/oob-api.txt b/doc/oob-api.txt
new file mode 100644
index 0000000..4796e4c
--- /dev/null
+++ b/doc/oob-api.txt
@@ -0,0 +1,62 @@
+BlueZ D-Bus OOB API description
+*******************************
+
+Copyright (C) 2010  ST-Ericsson SA
+
+Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
+
+OOB hierarchy
+=================
+
+Service         unique name
+Interface       org.bluez.OobProvider
+Object path     freely definable
+
+Methods		array{byte} hash, array{byte} randomizer
+			RequestRemoteOobData(object device)
+
+			This method gets called when the service daemon needs to
+			get device's hash and randomizer for an OOB
+			authentication. Each array should be 16 bytes long.
+
+			Possible errors: org.bluez.Error.NoData
+
+		void Release()
+
+			This method gets called when D-Bus plug-in for OOB was
+			deactivated. There is no need to unregister provider,
+			because when this method gets called it has already been
+			unregistered.
+
+--------------------------------------------------------------------------------
+
+Service		org.bluez
+Interface	org.bluez.OobManager
+Object path	[variable prefix]/{hci0,hci1,...}
+
+Methods		void RegisterProvider(object provider)
+
+			This method registers provider for D-Bus OOB plug-in.
+			When provider is successfully registered plug-in becomes
+			active. Only one provider per adapter can be registered.
+
+			Possible errors: org.bluez.Error.AlreadyExists
+
+		void UnregisterProvider(object provider)
+
+			This method unregisters provider for D-Bus OOB plug-in.
+
+			Possible errors: org.bluez.Error.DoesNotExist
+
+		array{byte} hash, array{byte} randomizer ReadLocalOobData()
+
+			This method reads local OOB data for adapter. Return
+			value is pair of arrays 16 bytes each. Only registered
+			provider should call this method.
+
+			Note: This method will generate and return new local
+			OOB data.
+
+			Possible errors: org.bluez.Error.ReadFailed
+					 org.bluez.Error.NoProvider
+					 org.bluez.Error.InProgress
-- 
1.7.1


^ permalink raw reply related

* [PATCHv4 2/7] Add D-Bus OOB plugin
From: Szymon Janc @ 2010-11-23 10:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1290509592-9262-1-git-send-email-szymon.janc@tieto.com>

---
 Makefile.am       |    5 +
 acinclude.m4      |    6 +
 plugins/dbusoob.c |  412 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 423 insertions(+), 0 deletions(-)
 create mode 100644 plugins/dbusoob.c

diff --git a/Makefile.am b/Makefile.am
index 47da8eb..9607553 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -218,6 +218,11 @@ builtin_modules += maemo6
 builtin_sources += plugins/maemo6.c
 endif
 
+if DBUSOOBPLUGIN
+builtin_modules += dbusoob
+builtin_sources += plugins/dbusoob.c
+endif
+
 sbin_PROGRAMS += src/bluetoothd
 
 src_bluetoothd_SOURCES = $(gdbus_sources) $(builtin_sources) \
diff --git a/acinclude.m4 b/acinclude.m4
index 287f07d..6704d46 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -193,6 +193,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 	configfiles_enable=yes
 	telephony_driver=dummy
 	maemo6_enable=no
+	dbusoob_enable=no
 
 	AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization], [disable code optimization]), [
 		optimization_enable=${enableval}
@@ -316,6 +317,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 		maemo6_enable=${enableval}
 	])
 
+	AC_ARG_ENABLE(dbusoob, AC_HELP_STRING([--enable-dbusoob], [compile with D-Bus OOB plugin]), [
+		dbusoob_enable=${enableval}
+	])
+
 	AC_ARG_ENABLE(hal, AC_HELP_STRING([--enable-hal], [Use HAL to determine adapter class]), [
 		hal_enable=${enableval}
 	])
@@ -372,4 +377,5 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 	AM_CONDITIONAL(UDEVRULES, test "${udevrules_enable}" = "yes")
 	AM_CONDITIONAL(CONFIGFILES, test "${configfiles_enable}" = "yes")
 	AM_CONDITIONAL(MAEMO6PLUGIN, test "${maemo6_enable}" = "yes")
+	AM_CONDITIONAL(DBUSOOBPLUGIN, test "${dbusoob_enable}" = "yes")
 ])
diff --git a/plugins/dbusoob.c b/plugins/dbusoob.c
new file mode 100644
index 0000000..e137b81
--- /dev/null
+++ b/plugins/dbusoob.c
@@ -0,0 +1,412 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2010  ST-Ericsson SA
+ *
+ *  Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
+ *
+ *
+ *  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
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <gdbus.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/sdp.h>
+
+#include "plugin.h"
+#include "log.h"
+#include "manager.h"
+#include "device.h"
+#include "adapter.h"
+#include "dbus-common.h"
+#include "event.h"
+#include "error.h"
+#include "oob.h"
+
+#define REQUEST_TIMEOUT		(60 * 1000)	/* 60 seconds */
+#define OOB_PROVIDER_INTERFACE	"org.bluez.OobProvider"
+#define OOB_MANAGER_INTERFACE	"org.bluez.OobManager"
+
+struct oob_provider {
+	char *name;
+	char *path;
+	struct btd_adapter *adapter;
+	DBusMessage *msg;
+	guint listener_id;
+	gboolean exited;
+};
+
+static GSList *providers = NULL;
+static DBusConnection *connection = NULL;
+static struct oob_plugin dbusoob;
+
+static void destroy_provider(struct oob_provider *provider)
+{
+	if (!provider->exited)
+		g_dbus_remove_watch(connection, provider->listener_id);
+
+	if (provider->msg)
+		dbus_message_unref(provider->msg);
+
+	DBG("Provider destroyed (%s at %s)", provider->name, provider->path);
+
+	g_free(provider->name);
+	g_free(provider->path);
+	g_free(provider);
+
+	providers = g_slist_remove(providers, provider);
+
+	if (!providers)
+		oob_deactivate_plugin(&dbusoob);
+}
+
+static void provider_exited(DBusConnection *conn, void *user_data)
+{
+	struct oob_provider *provider = user_data;
+
+	DBG("Provider exited without calling Unregister (%s at %s)",
+						provider->name, provider->path);
+
+	provider->exited = TRUE;
+	destroy_provider(provider);
+}
+
+static void create_provider(const char *path, const char *name,
+						struct btd_adapter *adapter)
+{
+	struct oob_provider *provider;
+
+	provider = g_new(struct oob_provider, 1);
+	provider->path = g_strdup(path);
+	provider->name = g_strdup(name);
+	provider->adapter = adapter;
+	provider->msg = NULL;
+	provider->exited = FALSE;
+	provider->listener_id = g_dbus_add_disconnect_watch(connection, name,
+					provider_exited, provider, NULL);
+
+	providers = g_slist_append(providers, provider);
+
+	DBG("OOB provider for %s registered at %s(%s)", provider->path,
+				provider->name, adapter_get_path(adapter));
+
+	oob_activate_plugin(&dbusoob);
+}
+
+static void request_remote_data_reply(DBusPendingCall *call, void *data)
+{
+	DBusMessage *msg;
+	DBusError err;
+	struct btd_device *device = data;
+	uint8_t *hash = NULL;
+	uint8_t *randomizer = NULL;
+	int32_t hlen, rlen;
+
+	msg = dbus_pending_call_steal_reply(call);
+
+	dbus_error_init(&err);
+	if (dbus_set_error_from_message(&err, msg)) {
+		error("Provider replied with an error: %s, %s", err.name,
+								err.message);
+		dbus_error_free(&err);
+		goto error;
+	}
+
+	dbus_error_init(&err);
+	if (!dbus_message_get_args(msg, &err,
+			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, &hlen,
+			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, &rlen,
+			DBUS_TYPE_INVALID) || hlen != 16 || rlen != 16) {
+		error("RequestRemoteOobData reply signature error: %s, %s",
+							err.name, err.message);
+		dbus_error_free(&err);
+		hash = NULL;
+		randomizer = NULL;
+	}
+
+error:
+	dbus_message_unref(msg);
+	dbus_pending_call_unref(call);
+
+	device_set_oob_data(device, hash, randomizer);
+}
+
+static gint provider_adapter_cmp(gconstpointer a, gconstpointer b)
+{
+	const struct oob_provider *provider = a;
+	const struct btd_adapter *adapter = b;
+
+	return provider->adapter != adapter;
+}
+
+static struct oob_provider* find_provider(struct btd_adapter *adapter)
+{
+	GSList *match;
+
+	match = g_slist_find_custom(providers, adapter, provider_adapter_cmp);
+	if (match)
+		return match->data;
+
+	return NULL;
+}
+
+static gboolean request_remote_data(struct btd_device *device)
+{
+	DBusMessage* msg;
+	DBusPendingCall *call = NULL;
+	const gchar *path;
+	gboolean ret = FALSE;
+	struct btd_adapter *adapter = device_get_adapter(device);
+	struct oob_provider *provider;
+
+	provider = find_provider(adapter);
+	if (!provider)
+		return ret;
+
+	msg = dbus_message_new_method_call(provider->name, provider->path,
+				OOB_PROVIDER_INTERFACE, "RequestRemoteOobData");
+
+	if (!msg) {
+		error("Couldn't allocate D-Bus message");
+		goto error;
+	}
+
+	path = device_get_path(device);
+
+	if (!dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &path,
+							DBUS_TYPE_INVALID)) {
+		error ("Couldn't append arguments");
+		goto error;
+	}
+
+	if (!dbus_connection_send_with_reply(connection, msg, &call,
+							REQUEST_TIMEOUT)) {
+		error("D-Bus send failed");
+		goto error;
+	}
+
+	if (!dbus_pending_call_set_notify(call, request_remote_data_reply,
+								device, NULL)) {
+		error("Couldn't set reply notification.");
+		dbus_pending_call_unref(call);
+		goto error;
+	}
+
+	ret = TRUE;
+
+error:
+	if (msg)
+		dbus_message_unref(msg);
+
+	return ret;
+}
+
+static void local_data_read(struct btd_adapter *adapter, uint8_t *hash,
+				uint8_t *randomizer)
+{
+	struct DBusMessage *reply;
+	struct oob_provider *provider;
+
+	provider = find_provider(adapter);
+	if (!provider)
+		return;
+
+	if (hash && randomizer)
+		reply = g_dbus_create_reply(provider->msg,
+			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, 16,
+			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, 16,
+			DBUS_TYPE_INVALID);
+	else
+		reply = g_dbus_create_error(provider->msg,
+					ERROR_INTERFACE ".ReadFailed",
+					"Failed to read local OOB data.");
+
+	dbus_message_unref(provider->msg);
+	provider->msg = NULL;
+
+	if (!reply) {
+		error("Couldn't allocate D-Bus message");
+		return;
+	}
+
+	if (!g_dbus_send_message(connection, reply))
+		error("D-Bus send failed");
+}
+
+static DBusMessage *read_local_data(DBusConnection *conn, DBusMessage *msg,
+								void *data)
+{
+	const char *name;
+	struct btd_adapter *adapter = data;
+	struct oob_provider *provider;
+
+	name = dbus_message_get_sender(msg);
+
+	provider = find_provider(adapter);
+	if (!provider)
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".NoProvider",
+						"No provider registered");
+
+	if (!g_str_equal(provider->name, name))
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".NoProvider",
+							"Not OOB provider");
+
+	if (provider->msg)
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",
+						"Another request in progress.");
+
+	if (btd_adapter_read_local_oob_data(adapter))
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".ReadFailed",
+							"HCI request failed");
+
+	provider->msg = dbus_message_ref(msg);
+	return NULL;
+}
+
+static void release_provider(struct oob_provider *provider)
+{
+	DBusMessage *msg;
+
+	msg = dbus_message_new_method_call(provider->name, provider->path,
+					OOB_PROVIDER_INTERFACE, "Release");
+
+	if (!msg)
+		error("Couldn't allocate D-Bus message");
+	else if (!g_dbus_send_message(connection, msg))
+		error("D-Bus send failed");
+
+	destroy_provider(provider);
+}
+
+static void plugin_deactivated(void)
+{
+	g_slist_foreach(providers, (GFunc) release_provider, NULL);
+	g_slist_free(providers);
+}
+
+static DBusMessage *register_provider(DBusConnection *conn, DBusMessage *msg,
+								void *data)
+{
+	const char *path, *name;
+	struct btd_adapter *adapter = data;
+
+	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+							DBUS_TYPE_INVALID))
+		return NULL;
+
+	if (find_provider(adapter))
+		return g_dbus_create_error(msg,
+					ERROR_INTERFACE ".AlreadyExists",
+					"OOB provider already registered");
+
+	name = dbus_message_get_sender(msg);
+	create_provider(path, name, adapter);
+
+	return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *unregister_provider(DBusConnection *conn, DBusMessage *msg,
+								void *data)
+{
+	const char *path, *name;
+	struct btd_adapter *adapter = data;
+	struct oob_provider *provider;
+
+	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+							DBUS_TYPE_INVALID))
+		return NULL;
+
+	name = dbus_message_get_sender(msg);
+
+	provider = find_provider(adapter);
+	if (!provider)
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".DoesNotExist",
+						"No provider registered");
+
+	if (!g_str_equal(provider->path, path) ||
+			!g_str_equal(provider->name, name))
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".DoesNotExist",
+						"Not a registered provider");
+
+	DBG("OOB provider %s(%s) unregistered", provider->path, provider->name);
+
+	destroy_provider(provider);
+
+	return dbus_message_new_method_return(msg);
+}
+
+static GDBusMethodTable oob_methods[] = {
+	{ "RegisterProvider",	"o",	"",	register_provider	},
+	{ "UnregisterProvider",	"o",	"",	unregister_provider	},
+	{ "ReadLocalOobData",	"",	"ayay",	read_local_data,
+						G_DBUS_METHOD_FLAG_ASYNC},
+	{ }
+};
+
+static int oob_probe(struct btd_adapter *adapter)
+{
+	const char* path = adapter_get_path(adapter);
+
+	if (!g_dbus_register_interface(connection, path, OOB_MANAGER_INTERFACE,
+				oob_methods, NULL, NULL, adapter, NULL)) {
+			error("OOB interface init failed on path %s", path);
+			return -EIO;
+		}
+
+	return 0;
+}
+
+static void oob_remove(struct btd_adapter *adapter)
+{
+	g_dbus_unregister_interface(connection, adapter_get_path(adapter),
+							OOB_MANAGER_INTERFACE);
+}
+
+static struct btd_adapter_driver oob_driver = {
+	.name	= "oob",
+	.probe	= oob_probe,
+	.remove	= oob_remove,
+};
+
+static int dbusoob_init(void)
+{
+	DBG("Setup dbusoob plugin");
+
+	connection = get_dbus_connection();
+
+	dbusoob.request_remote_data = request_remote_data;
+	dbusoob.local_data_read = local_data_read;
+	dbusoob.plugin_deactivated = plugin_deactivated;
+
+	return btd_register_adapter_driver(&oob_driver);
+}
+
+static void dbusoob_exit(void)
+{
+	DBG("Cleanup dbusoob plugin");
+	oob_deactivate_plugin(&dbusoob);
+}
+
+BLUETOOTH_PLUGIN_DEFINE(dbusoob, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
+						dbusoob_init, dbusoob_exit)
-- 
1.7.1


^ permalink raw reply related

* [PATCHv4 1/7] Add support for Out of Band (OOB) association model
From: Szymon Janc @ 2010-11-23 10:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1290509592-9262-1-git-send-email-szymon.janc@tieto.com>

---
 Makefile.am      |    3 +-
 lib/hci.h        |    3 ++
 plugins/hciops.c |   86 +++++++++++++++++++++++++++++++++++++++++++++--------
 src/adapter.c    |   14 ++++++++-
 src/adapter.h    |    6 ++++
 src/device.c     |   74 ++++++++++++++++++++++++++++++++++++++++++++++
 src/device.h     |   12 +++++++
 src/event.c      |   53 +++++++++++++++++++++------------
 src/event.h      |    3 +-
 src/oob.c        |   67 ++++++++++++++++++++++++++++++++++++++++++
 src/oob.h        |   47 +++++++++++++++++++++++++++++
 11 files changed, 332 insertions(+), 36 deletions(-)
 create mode 100644 src/oob.c
 create mode 100644 src/oob.h

diff --git a/Makefile.am b/Makefile.am
index 5f96975..47da8eb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -240,7 +240,8 @@ src_bluetoothd_SOURCES = $(gdbus_sources) $(builtin_sources) \
 			src/adapter.h src/adapter.c \
 			src/device.h src/device.c \
 			src/dbus-common.c src/dbus-common.h \
-			src/event.h src/event.c
+			src/event.h src/event.c \
+			src/oob.c
 src_bluetoothd_LDADD = lib/libbluetooth.la @GLIB_LIBS@ @DBUS_LIBS@ \
 							@CAPNG_LIBS@ -ldl -lrt
 src_bluetoothd_LDFLAGS = -Wl,--export-dynamic \
diff --git a/lib/hci.h b/lib/hci.h
index 0cb120f..409abd9 100644
--- a/lib/hci.h
+++ b/lib/hci.h
@@ -524,6 +524,9 @@ typedef struct {
 
 #define OCF_REMOTE_OOB_DATA_NEG_REPLY	0x0033
 
+#define OOB_DATA_NOT_PRESENT	0x00
+#define OOB_DATA_PRESENT	0x01
+
 #define OCF_IO_CAPABILITY_NEG_REPLY	0x0034
 typedef struct {
 	bdaddr_t	bdaddr;
diff --git a/plugins/hciops.c b/plugins/hciops.c
index 9abe477..c62ac51 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -3,6 +3,7 @@
  *  BlueZ - Bluetooth protocol stack for Linux
  *
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2010  ST-Ericsson SA
  *
  *  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
@@ -47,6 +48,7 @@
 #include "event.h"
 #include "device.h"
 #include "manager.h"
+#include "oob.h"
 
 #define HCI_REQ_TIMEOUT         5000
 
@@ -652,20 +654,41 @@ static void user_passkey_notify(int index, void *ptr)
 
 static void remote_oob_data_request(int index, void *ptr)
 {
-	hci_send_cmd(SK(index), OGF_LINK_CTL,
-				OCF_REMOTE_OOB_DATA_NEG_REPLY, 6, ptr);
+	bdaddr_t *dba = ptr;
+	struct btd_adapter *adapter;
+	struct btd_device *device;
+	char da[18];
+
+	ba2str(dba, da);
+	adapter = manager_find_adapter(&BDADDR(index));
+	device = adapter_find_device(adapter, da);
+
+	if (!device_get_oob_data(device, NULL, NULL) {
+		remote_oob_data_reply_cp cp;
+
+		bacpy(&cp.bdaddr, dba);
+		device_get_oob_data(device,cp.hash,cp.randomizer);
+
+		hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_REPLY,
+				REMOTE_OOB_DATA_REPLY_CP_SIZE, &cp);
+	} else
+		hci_send_cmd(SK(index),
+				OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_NEG_REPLY, 6,
+				ptr);
 }
 
 static void io_capa_request(int index, void *ptr)
 {
 	bdaddr_t *dba = ptr;
 	char sa[18], da[18];
-	uint8_t cap, auth;
 
 	ba2str(&BDADDR(index), sa); ba2str(dba, da);
 	info("io_capa_request (sba=%s, dba=%s)", sa, da);
 
-	if (btd_event_get_io_cap(&BDADDR(index), dba, &cap, &auth) < 0) {
+	/* If failed to establish IO capabilities then send negative reply
+	 * immediately. Positive reply will be sent when IO capabilities are
+	 * established. */
+	if (btd_event_request_io_cap(&BDADDR(index), dba)) {
 		io_capability_neg_reply_cp cp;
 		memset(&cp, 0, sizeof(cp));
 		bacpy(&cp.bdaddr, dba);
@@ -673,15 +696,6 @@ static void io_capa_request(int index, void *ptr)
 		hci_send_cmd(SK(index), OGF_LINK_CTL,
 					OCF_IO_CAPABILITY_NEG_REPLY,
 					IO_CAPABILITY_NEG_REPLY_CP_SIZE, &cp);
-	} else {
-		io_capability_reply_cp cp;
-		memset(&cp, 0, sizeof(cp));
-		bacpy(&cp.bdaddr, dba);
-		cp.capability = cap;
-		cp.oob_data = 0x00;
-		cp.authentication = auth;
-		hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_IO_CAPABILITY_REPLY,
-					IO_CAPABILITY_REPLY_CP_SIZE, &cp);
 	}
 }
 
@@ -995,6 +1009,9 @@ static inline void cmd_status(int index, void *ptr)
 
 	if (opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY))
 		start_inquiry(&BDADDR(index), evt->status, FALSE);
+	else if (opcode == cmd_opcode_pack(OGF_HOST_CTL,
+						OCF_READ_LOCAL_OOB_DATA))
+		oob_local_data_read(&BDADDR(index), NULL, NULL);
 }
 
 static void read_scan_complete(int index, uint8_t status, void *ptr)
@@ -1012,6 +1029,15 @@ static void read_scan_complete(int index, uint8_t status, void *ptr)
 	adapter_mode_changed(adapter, rp->enable);
 }
 
+static void read_local_oob_data_complete(bdaddr_t *local, uint8_t status,
+						read_local_oob_data_rp *rp)
+{
+	if (status)
+		oob_local_data_read(local, NULL, NULL);
+	else
+		oob_local_data_read(local, rp->hash, rp->randomizer);
+}
+
 static inline void cmd_complete(int index, void *ptr)
 {
 	evt_cmd_complete *evt = ptr;
@@ -1083,6 +1109,10 @@ static inline void cmd_complete(int index, void *ptr)
 		ptr += sizeof(evt_cmd_complete);
 		read_tx_power_complete(index, ptr);
 		break;
+	case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_LOCAL_OOB_DATA):
+		ptr += sizeof(evt_cmd_complete);
+		read_local_oob_data_complete(&BDADDR(index), status, ptr);
+		break;
 	};
 }
 
@@ -2514,6 +2544,34 @@ static int hciops_get_remote_version(int index, uint16_t handle,
 	return 0;
 }
 
+static int hciops_read_local_oob_data(int index)
+{
+	if (hci_send_cmd(SK(index), OGF_HOST_CTL, OCF_READ_LOCAL_OOB_DATA, 0, 0)
+			< 0)
+		return -errno;
+
+	return 0;
+}
+
+
+static void hciops_io_capa_request_reply(int index, struct btd_device *device)
+{
+	io_capability_reply_cp cp;
+
+	memset(&cp, 0, sizeof(cp));
+	device_get_address(device, &cp.bdaddr);
+	device_get_local_auth_cap(device, &cp.authentication, &cp.capability);
+	cp.oob_data = device_get_oob_data(device, NULL, NULL)
+			? OOB_DATA_PRESENT : OOB_DATA_NOT_PRESENT;
+
+	DBG("final capabilities reply is cap=0x%02x, auth=0x%02x, oob=0x%02x",
+	cp.capability, cp.authentication, cp.oob_data);
+
+	hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_IO_CAPABILITY_REPLY,
+					IO_CAPABILITY_REPLY_CP_SIZE, &cp);
+}
+
+
 static struct btd_adapter_ops hci_ops = {
 	.setup = hciops_setup,
 	.cleanup = hciops_cleanup,
@@ -2554,6 +2612,8 @@ static struct btd_adapter_ops hci_ops = {
 	.write_le_host = hciops_write_le_host,
 	.get_remote_version = hciops_get_remote_version,
 	.encrypt_link = hciops_encrypt_link,
+	.read_local_oob_data = hciops_read_local_oob_data,
+	.io_capa_request_reply = hciops_io_capa_request_reply
 };
 
 static int hciops_init(void)
diff --git a/src/adapter.c b/src/adapter.c
index 6b4a354..f0c2dad 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3245,7 +3245,8 @@ void adapter_remove_connection(struct btd_adapter *adapter,
 	/* clean pending HCI cmds */
 	device_get_address(device, &bdaddr);
 
-	if (device_is_authenticating(device))
+	if (device_is_authenticating(device) ||
+			device_get_oob_data(device, NULL, NULL))
 		device_cancel_authentication(device, TRUE);
 
 	if (device_is_temporary(device)) {
@@ -3713,3 +3714,14 @@ int btd_adapter_encrypt_link(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 {
 	return adapter_ops->encrypt_link(adapter->dev_id, bdaddr, cb, user_data);
 }
+
+int btd_adapter_read_local_oob_data(struct btd_adapter *adapter)
+{
+	return adapter_ops->read_local_oob_data(adapter->dev_id);
+}
+
+void btd_adapter_io_capa_request_reply(struct btd_adapter *adapter,
+					struct btd_device *device)
+{
+	adapter_ops->io_capa_request_reply(adapter->dev_id, device);
+}
diff --git a/src/adapter.h b/src/adapter.h
index de6a6f5..16b7f67 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -232,6 +232,8 @@ struct btd_adapter_ops {
 						gboolean delayed);
 	int (*encrypt_link) (int index, bdaddr_t *bdaddr, bt_hci_result_t cb,
 							gpointer user_data);
+	int (*read_local_oob_data) (int index);
+	void (*io_capa_request_reply) (int index, struct btd_device *device);
 };
 
 int btd_register_adapter_ops(struct btd_adapter_ops *ops, gboolean priority);
@@ -291,3 +293,7 @@ int btd_adapter_get_remote_version(struct btd_adapter *adapter,
 
 int btd_adapter_encrypt_link(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 				bt_hci_result_t cb, gpointer user_data);
+
+int btd_adapter_read_local_oob_data(struct btd_adapter *adapter);
+void btd_adapter_io_capa_request_reply(struct btd_adapter *adapter,
+					struct btd_device *device);
diff --git a/src/device.c b/src/device.c
index 7c421e3..fd3c3b3 100644
--- a/src/device.c
+++ b/src/device.c
@@ -4,6 +4,7 @@
  *
  *  Copyright (C) 2006-2010  Nokia Corporation
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2010  ST-Ericsson SA
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -59,6 +60,7 @@
 #include "sdp-xml.h"
 #include "storage.h"
 #include "btio.h"
+#include "oob.h"
 
 #define DEFAULT_XML_BUF_SIZE	1024
 #define DISCONNECT_TIMER	2
@@ -132,6 +134,9 @@ struct btd_device {
 	uint8_t		cap;
 	uint8_t		auth;
 
+	uint8_t		local_cap;
+	uint8_t		local_auth;
+
 	uint16_t	handle;			/* Connection handle */
 
 	/* Whether were creating a security mode 3 connection */
@@ -149,6 +154,12 @@ struct btd_device {
 
 	gboolean	has_debug_key;
 	uint8_t		debug_key[16];
+
+	/* For OOB association model */
+	void (*oob_request_cb)(struct btd_device *device);
+	gboolean	has_oob_data;
+	uint8_t		hash[16];
+	uint8_t		randomizer[16];
 };
 
 static uint16_t uuid_list[] = {
@@ -829,6 +840,67 @@ static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg,
 	return NULL;
 }
 
+void device_set_oob_data(struct btd_device *device, uint8_t *hash,
+				uint8_t *randomizer)
+{
+	if (!device)
+		return;
+
+	if (hash && randomizer) {
+		memcpy(device->hash, hash, 16);
+		memcpy(device->randomizer, randomizer, 16);
+		device->has_oob_data = TRUE;
+	}
+
+	if (device->oob_request_cb) {
+		device->oob_request_cb(device);
+		device->oob_request_cb = NULL;
+	}
+}
+
+gboolean device_get_oob_data(struct btd_device *device, uint8_t *hash,
+				uint8_t *randomizer)
+{
+	if (!device || !device->has_oob_data)
+		return FALSE;
+
+	if (hash && randomizer) {
+		memcpy(hash, device->hash, 16);
+		memcpy(randomizer, device->randomizer, 16);
+	}
+
+	return TRUE;
+}
+
+gboolean device_request_oob_data(struct btd_device *device,
+					void (*cb)(struct btd_device *device))
+{
+	if (!device)
+		return FALSE;
+
+	device->oob_request_cb = cb;
+	return oob_request_remote_data(device);
+}
+
+void device_set_local_auth_cap(struct btd_device *device, uint8_t auth,
+				uint8_t cap)
+{
+	if (!device)
+		return;
+
+	device->local_auth = auth;
+	device->local_cap = cap;
+}
+void device_get_local_auth_cap(struct btd_device *device, uint8_t *auth,
+				uint8_t *cap)
+{
+	if (!device)
+		return;
+
+	*auth = device->local_auth;
+	*cap = device->local_cap;
+}
+
 static GDBusMethodTable device_methods[] = {
 	{ "GetProperties",	"",	"a{sv}",	get_properties	},
 	{ "SetProperty",	"sv",	"",		set_property	},
@@ -2264,6 +2336,8 @@ void device_cancel_authentication(struct btd_device *device, gboolean aborted)
 {
 	struct authentication_req *auth = device->authr;
 
+	device->has_oob_data = FALSE;
+
 	if (!auth)
 		return;
 
diff --git a/src/device.h b/src/device.h
index b570bd1..1823f65 100644
--- a/src/device.h
+++ b/src/device.h
@@ -4,6 +4,7 @@
  *
  *  Copyright (C) 2006-2010  Nokia Corporation
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2010  ST-Ericsson SA
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -89,6 +90,17 @@ void device_remove_connection(struct btd_device *device, DBusConnection *conn,
 gboolean device_has_connection(struct btd_device *device, uint16_t handle);
 void device_request_disconnect(struct btd_device *device, DBusMessage *msg);
 
+void device_set_oob_data(struct btd_device *device, uint8_t *hash,
+				uint8_t *randomizer);
+gboolean device_get_oob_data(struct btd_device *device, uint8_t *hash,
+				uint8_t *randomizer);
+gboolean device_request_oob_data(struct btd_device *device,
+					void (*cb)(struct btd_device *device));
+void device_set_local_auth_cap(struct btd_device *device, uint8_t auth,
+				uint8_t cap);
+void device_get_local_auth_cap(struct btd_device *device, uint8_t *auth,
+				uint8_t *cap);
+
 typedef void (*disconnect_watch) (struct btd_device *device, gboolean removal,
 					void *user_data);
 
diff --git a/src/event.c b/src/event.c
index daab71a..a88a8f5 100644
--- a/src/event.c
+++ b/src/event.c
@@ -4,6 +4,7 @@
  *
  *  Copyright (C) 2006-2010  Nokia Corporation
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2010  ST-Ericsson SA
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -274,7 +275,8 @@ void btd_event_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer,
 	if (!get_adapter_and_device(local, peer, &adapter, &device, TRUE))
 		return;
 
-	if (!device_is_authenticating(device)) {
+	if (!device_is_authenticating(device) &&
+			!device_get_oob_data(device, NULL, NULL)) {
 		/* This means that there was no pending PIN or SSP token
 		 * request from the controller, i.e. this is not a new
 		 * pairing */
@@ -724,26 +726,33 @@ void btd_event_returned_link_key(bdaddr_t *local, bdaddr_t *peer)
 	device_set_paired(device, TRUE);
 }
 
-int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
-						uint8_t *cap, uint8_t *auth)
+static void btd_event_io_cap_reply(struct btd_device *device)
+{
+	struct btd_adapter *adapter = device_get_adapter(device);
+
+	btd_adapter_io_capa_request_reply(adapter, device);
+}
+
+int btd_event_request_io_cap(bdaddr_t *local, bdaddr_t *remote)
 {
 	struct btd_adapter *adapter;
 	struct btd_device *device;
 	struct agent *agent = NULL;
 	uint8_t agent_cap;
 	int err;
+	uint8_t cap, auth;
 
 	if (!get_adapter_and_device(local, remote, &adapter, &device, TRUE))
 		return -ENODEV;
 
-	err = btd_adapter_get_auth_info(adapter, remote, auth);
+	err = btd_adapter_get_auth_info(adapter, remote, &auth);
 	if (err < 0)
 		return err;
 
-	DBG("initial authentication requirement is 0x%02x", *auth);
+	DBG("initial authentication requirement is 0x%02x", auth);
 
-	if (*auth == 0xff)
-		*auth = device_get_auth(device);
+	if (auth == 0xff)
+		auth = device_get_auth(device);
 
 	/* Check if the adapter is not pairable and if there isn't a bonding
 	 * in progress */
@@ -752,11 +761,11 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
 		if (device_get_auth(device) < 0x02) {
 			DBG("Allowing no bonding in non-bondable mode");
 			/* No input, no output */
-			*cap = 0x03;
+			cap = 0x03;
 			/* Kernel defaults to general bonding and so
 			 * overwrite for this special case. Otherwise
 			 * non-pairable test cases will fail. */
-			*auth = 0x00;
+			auth = 0x00;
 			goto done;
 		}
 		return -EPERM;
@@ -772,13 +781,13 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
 		}
 
 		/* No agent available, and no bonding case */
-		if (*auth == 0x00 || *auth == 0x04) {
+		if (auth == 0x00 || auth == 0x04) {
 			DBG("Allowing no bonding without agent");
 			/* No input, no output */
-			*cap = 0x03;
+			cap = 0x03;
 			/* If kernel defaults to general bonding, set it
 			 * back to no bonding */
-			*auth = 0x00;
+			auth = 0x00;
 			goto done;
 		}
 
@@ -788,7 +797,7 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
 
 	agent_cap = agent_get_io_capability(agent);
 
-	if (*auth == 0x00 || *auth == 0x04) {
+	if (auth == 0x00 || auth == 0x04) {
 		/* If remote requests dedicated bonding follow that lead */
 		if (device_get_auth(device) == 0x02 ||
 				device_get_auth(device) == 0x03) {
@@ -797,9 +806,9 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
 			 * then require it, otherwise don't */
 			if (device_get_cap(device) == 0x03 ||
 							agent_cap == 0x03)
-				*auth = 0x02;
+				auth = 0x02;
 			else
-				*auth = 0x03;
+				auth = 0x03;
 		}
 
 		/* If remote indicates no bonding then follow that. This
@@ -807,7 +816,7 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
 		 * as default. */
 		if (device_get_auth(device) == 0x00 ||
 					device_get_auth(device) == 0x01)
-			*auth = 0x00;
+			auth = 0x00;
 
 		/* If remote requires MITM then also require it, unless
 		 * our IO capability is NoInputNoOutput (so some
@@ -815,13 +824,19 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
 		if (device_get_auth(device) != 0xff &&
 					(device_get_auth(device) & 0x01) &&
 					agent_cap != 0x03)
-			*auth |= 0x01;
+			auth |= 0x01;
 	}
 
-	*cap = agent_get_io_capability(agent);
+	cap = agent_get_io_capability(agent);
 
 done:
-	DBG("final authentication requirement is 0x%02x", *auth);
+	DBG("final authentication requirement is 0x%02x", auth);
+
+	device_set_local_auth_cap(device, auth, cap);
+
+	/* If failed to request remote OOB data then reply immediately. */
+	if (!device_request_oob_data(device, btd_event_io_cap_reply))
+		btd_event_io_cap_reply(device);
 
 	return 0;
 }
diff --git a/src/event.h b/src/event.h
index 4321949..5c122ea 100644
--- a/src/event.h
+++ b/src/event.h
@@ -35,8 +35,7 @@ void btd_event_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t
 void btd_event_setscan_enable_complete(bdaddr_t *local);
 void btd_event_le_set_scan_enable_complete(bdaddr_t *local, uint8_t status);
 void btd_event_returned_link_key(bdaddr_t *local, bdaddr_t *peer);
-int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
-						uint8_t *cap, uint8_t *auth);
+int btd_event_request_io_cap(bdaddr_t *local, bdaddr_t *remote);
 int btd_event_set_io_cap(bdaddr_t *local, bdaddr_t *remote,
 						uint8_t cap, uint8_t auth);
 int btd_event_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey);
diff --git a/src/oob.c b/src/oob.c
new file mode 100644
index 0000000..3b9714c
--- /dev/null
+++ b/src/oob.c
@@ -0,0 +1,67 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2010  ST-Ericsson SA
+ *
+ *  Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
+ *
+ *
+ *  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 <glib.h>
+#include "manager.h"
+#include "adapter.h"
+#include "oob.h"
+
+static struct oob_plugin *active_plugin = NULL;
+
+void oob_activate_plugin(struct oob_plugin *plugin)
+{
+	if (!plugin)
+		return;
+
+	if (!plugin->local_data_read || !plugin->plugin_deactivated ||
+			!plugin->request_remote_data)
+		return;
+
+	if (active_plugin == plugin)
+		return;
+
+	if (active_plugin)
+		active_plugin->plugin_deactivated();
+
+	active_plugin = plugin;
+}
+
+void oob_deactivate_plugin(struct oob_plugin *plugin)
+{
+	if (active_plugin == plugin)
+		active_plugin = NULL;
+}
+
+gboolean oob_request_remote_data(struct btd_device *device)
+{
+	return active_plugin && active_plugin->request_remote_data(device);
+}
+
+void oob_local_data_read(bdaddr_t *ba, uint8_t *hash, uint8_t *randomizer)
+{
+	if (active_plugin)
+		active_plugin->local_data_read(manager_find_adapter(ba), hash,
+								randomizer);
+}
diff --git a/src/oob.h b/src/oob.h
new file mode 100644
index 0000000..db678de
--- /dev/null
+++ b/src/oob.h
@@ -0,0 +1,47 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2010  ST-Ericsson SA
+ *
+ *  Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
+ *
+ *
+ *  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
+ *
+ */
+
+struct oob_plugin
+{
+	/* If request was successfully send this functions should return TRUE.
+	 * Function should not block for too long. */
+	gboolean (*request_remote_data)(struct btd_device *device);
+
+	/* New local OOB data was read. If corresponding HCI command failed,
+	 * hash and randomizer are NULL */
+	void (*local_data_read)(struct btd_adapter *adapter, uint8_t *hash,
+			uint8_t *randomizer);
+
+	/* Plug-in was deactivated (called only for active plug-in). */
+	void (*plugin_deactivated)(void);
+};
+
+/* These functions are called by OOB plug-in. */
+void oob_activate_plugin(struct oob_plugin *plugin);
+void oob_deactivate_plugin(struct oob_plugin *plugin);
+
+/* These functions are called from stack to interact with OOB plug-in. */
+gboolean oob_request_remote_data(struct btd_device *device);
+void oob_local_data_read(bdaddr_t *ba, uint8_t *hash, uint8_t *randomizer);
-- 
1.7.1


^ permalink raw reply related

* [PATCHv4 0/7] Support for out of band association model
From: Szymon Janc @ 2010-11-23 10:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Changes in this version:
  - code style/flow comments from Johan included
  - changes in D-Bus OOB api - ReadLocalOobData and provider
    register/unregister moved to adapter path (OobManager interface), provider
    is registered per adapter now
  - some bug fixes

Some things I'd like to collect comments about:
  - OobManager interface could be only available on 2.1 or higher adapters
    (this would require some adapter interface to be able check this in
    dbusoob plugin)
  - Agent's RequestPairing method name
  - RequestPairing is called only on device accepting incoming connection when
    it has OOB data for remote device (on RequestRemoteOobData event).
    Consequence is that when only initiator has OOB data RequestPairing is not
    called. We could store initiator's OOB capability in device structure (now
    only auth and cap are stored) to be able to know if initiator has OOB data.
    Yet, in such case RequestRemoteOobData on accepting device will not be 
    called and I have no idea where/when OOB capability should be check to call
    RequestPairing (and reject pairing if necessary)..


Comments are welcome.

BR,
Szymon Janc
on behalf of ST-Ericsson


Szymon Janc (7):
  Add support for Out of Band (OOB) association model
  Add D-Bus OOB plugin
  Add D-Bus OOB API documentation
  Add simple-oobprovider for testing
  Add request for accepting incoming pairing requests with OOB
    mechanism
  Update D-Bus OOB API with RequestPairing method
  Add RequestPairing method in simple-agent for accepting incoming OOB 
       pairing requests

 Makefile.am             |   10 +-
 acinclude.m4            |    6 +
 doc/oob-api.txt         |   76 +++++++++
 doc/oob-api.txt.orig    |   79 +++++++++
 lib/hci.h               |    3 +
 plugins/dbusoob.c       |  412 +++++++++++++++++++++++++++++++++++++++++++++++
 plugins/hciops.c        |  107 +++++++++++--
 src/adapter.c           |   21 +++-
 src/adapter.h           |   10 ++
 src/agent.c             |   59 +++++++-
 src/agent.h             |    3 +
 src/device.c            |   96 +++++++++++
 src/device.h            |   13 ++
 src/event.c             |   89 ++++++++---
 src/event.h             |    4 +-
 src/oob.c               |   67 ++++++++
 src/oob.h               |   47 ++++++
 test/simple-agent       |   10 ++
 test/simple-oobprovider |   57 +++++++
 19 files changed, 1131 insertions(+), 38 deletions(-)
 create mode 100644 doc/oob-api.txt
 create mode 100644 doc/oob-api.txt.orig
 create mode 100644 plugins/dbusoob.c
 create mode 100644 src/oob.c
 create mode 100644 src/oob.h
 create mode 100755 test/simple-oobprovider


^ permalink raw reply

* [PATCH] hciattach: makes set_speed return error if any one operation fail
From: Suraj Sumangala @ 2010-11-23 10:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jothikumar.Mothilal, Suraj Sumangala

This patch lets set_speed function changing UART baud rate
to return an error code if any one operation fails
instead of returning only the last operation's status.

---
 tools/hciattach.c |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/tools/hciattach.c b/tools/hciattach.c
index fd53710..7cb8e9e 100644
--- a/tools/hciattach.c
+++ b/tools/hciattach.c
@@ -144,9 +144,16 @@ static int uart_speed(int s)
 
 int set_speed(int fd, struct termios *ti, int speed)
 {
-	cfsetospeed(ti, uart_speed(speed));
-	cfsetispeed(ti, uart_speed(speed));
-	return tcsetattr(fd, TCSANOW, ti);
+	if (cfsetospeed(ti, uart_speed(speed)) < 0)
+		return -errno;
+
+	if (cfsetispeed(ti, uart_speed(speed)) < 0)
+		return -errno;
+
+	if (tcsetattr(fd, TCSANOW, ti) < 0)
+		return -errno;
+
+	return 0;
 }
 
 /*
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH] hciattach: download configuration at maximum baud rate possible
From: Johan Hedberg @ 2010-11-23 10:15 UTC (permalink / raw)
  To: Suraj Sumangala; +Cc: linux-bluetooth, Jothikumar.Mothilal
In-Reply-To: <4CEB9296.2060702@Atheros.com>

Hi Suraj,

On Tue, Nov 23, 2010, Suraj Sumangala wrote:
> The set_speed function is defined in hciattach.c as
> 
> int set_speed(...)
> {
> 	cfsetospeed(...);
> 	cfsetispeed(...);
> 	return tcsetattr(...);
> }
> 
> I think this function could end up returning Success even if the
> first two function calls failed?

Seems so, yes.

> Does it makes sense to rewrite it to
> 
> int set_speed(...)
> {
> 	if(cfsetospeed(...) < 0)
> 		return -errno;
> 	if(cfsetispeed(...) < 0)
> 		return -errno;

This looks fine, except for the coding style: space between if and (

> 	return tcsetattr(...);

I guess this should be a similar if statement as for the other two
calls, and then a final "return 0" at the end of the function. This
set_speed fix should be in a separate patch though.

Johan

^ permalink raw reply

* Re: [PATCH] hciattach: download configuration at maximum baud rate possible
From: Suraj Sumangala @ 2010-11-23 10:08 UTC (permalink / raw)
  To: linux-bluetooth, Jothikumar.Mothilal
In-Reply-To: <20101123092346.GB28017@jh-x301>

Hi Johan,

On 11/23/2010 2:53 PM, Johan Hedberg wrote:
> In general the patch looks ok'ish, but:
>
>> >  +	if (set_speed(fd, ti, speed)<  0) {
>> >  +		perror("Can't set required baud rate");
>> >  +		return -1;
>> >  +	}
> To be consistent with the other return values, instead of -1 you should
> be returning a proper errno here. I.e. probably something like:
>
> 	if (set_speed(fd, ti, speed)<  0) {
> 		err = -errno;
> 		perror("Can't set required baud rate");
> 		return err;

The set_speed function is defined in hciattach.c as

int set_speed(...)
{
	cfsetospeed(...);
	cfsetispeed(...);
	return tcsetattr(...);
}

I think this function could end up returning Success even if the first 
two function calls failed?

Does it makes sense to rewrite it to

int set_speed(...)
{
	if(cfsetospeed(...) < 0)
		return -errno;
	if(cfsetispeed(...) < 0)
		return -errno;
	return tcsetattr(...);
}

Then, I can return the error code directly in my function call.

Regards
Suraj
	

^ permalink raw reply

* Re: [PATCH] hciattach: download configuration at maximum baud rate possible
From: Johan Hedberg @ 2010-11-23  9:23 UTC (permalink / raw)
  To: Suraj Sumangala; +Cc: linux-bluetooth, Jothikumar.Mothilal
In-Reply-To: <1290423480-29840-1-git-send-email-suraj@atheros.com>

Hi Suraj,

On Mon, Nov 22, 2010, Suraj Sumangala wrote:
> This patch support downloading configuration files for
> Atheros AR300x HCI UART chip at user requested baud rate
> instead of the initial baud rate.
> ---
>  tools/hciattach.c       |    2 +-
>  tools/hciattach.h       |    3 +-
>  tools/hciattach_ath3k.c |   97 +++++++++++++++++++++++++++++++++-------------
>  3 files changed, 72 insertions(+), 30 deletions(-)

In general the patch looks ok'ish, but:

> +	if (set_speed(fd, ti, speed) < 0) {
> +		perror("Can't set required baud rate");
> +		return -1;
> +	}

To be consistent with the other return values, instead of -1 you should
be returning a proper errno here. I.e. probably something like:

	if (set_speed(fd, ti, speed) < 0) {
		err = -errno;
		perror("Can't set required baud rate");
		return err;
	}


> +exit:

Could you use a label name that's more consistent with the rest of the
BlueZ code base. I think "failed" would be the most suitable one here.

Johan

^ permalink raw reply

* Re: [PATCH] Add a runtime option to set the BCSP communication rate
From: Johan Hedberg @ 2010-11-23  9:13 UTC (permalink / raw)
  To: Wade Brown; +Cc: linux-bluetooth
In-Reply-To: <1290466992-5023-1-git-send-email-brownw@us.panasonic.com>

Hi Wade,

On Mon, Nov 22, 2010, Wade Brown wrote:
> ---
>  tools/bccmd.c    |   45 ++++++++++++++++++++++++++++++++++++++++-----
>  tools/csr.h      |    3 ++-
>  tools/csr_bcsp.c |    4 ++--
>  3 files changed, 44 insertions(+), 8 deletions(-)

Pushed upstream. Thanks.

Johan

^ permalink raw reply

* How to change the waiting time when building bluetooth connection
From: Roc Bai @ 2010-11-23  8:06 UTC (permalink / raw)
  To: Gustavo F. Padovan; +Cc: linux-bluetooth

2010/11/22 Gustavo F. Padovan <padovan@profusion.mobi>:
> Hi Roc,
>
> * Roc Bai <buroc83@gmail.com> [2010-11-22 11:13:27 +0800]:
>
>> Hi, All:
>>  When i pair my phone with the PC, i have to quickly input the PIN code
>> with the linux-2.6.35.1 kernel. But i can do it slowly with linux-2.6.26
>> kernel. All the application and library are same. So i think the waiting
>> timeout is changed, but i cann't find the changement. I hope get your help
>> on the issue. Thanks very much!
>>
>> My hcid version is 3.36.
>
> Please move to the latest bluez 4 version and then report it again if it
> is the case.

The same phenomenon. But one strange result, some phone can connect
normally, but some phone should input PIN quickly.  But those phones
can work in the old kernel. I think some phones have special
parameters and the changement of new kernel are sensitive with them.
More idea ?
>
> --
> Gustavo F. Padovan
> http://profusion.mobi
>



-- 
------------------------

Thinking before action, but you are wasting time if you don't do action.

^ permalink raw reply

* sdptool hanging remote
From: Grahame Jordan @ 2010-11-23  5:37 UTC (permalink / raw)
  To: linux-bluetooth

Hi,

I am using bluez-4.77 on a Gumstix Verdex kernel 2.4.32 patch 21

When I run:
sdptool records 00:80:37:2F:06:08"
from the Workstation Ubuntu 10.04 Bluez-4.6? to the Gumstix the Gumstix 
hangs.
It does not hang completely but is very busy. It hangs for about 20 
seconds and then releases for about 1 second
before it locks up again.

I have tried this on several different Gumstix with the same issue.

Changing workstations from Ubuntu 10.04 to Ubuntu 8.04 does make a 
difference.
 From Ubuntu 8.04 there seems to be no problem. blue-utils 3.26?

Appreciate help


Thanks

Grahame Jordan

^ permalink raw reply


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