All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] Add pin-code hook to adapter api
@ 2011-07-08 16:34 David Herrmann
  2011-07-08 16:34 ` [PATCH 2/2] Add support for wiimote pairing David Herrmann
  2011-07-13  9:11 ` [PATCH 1/2] Add pin-code hook to adapter api Johan Hedberg
  0 siblings, 2 replies; 3+ messages in thread
From: David Herrmann @ 2011-07-08 16:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: padovan, johan.hedberg, marcel, David Herrmann

Plugins may now register pincode callbacks which are called when the
authentication of a new device requires a pincode. This allows to have
hard-coded binary pins inside the daemon to circumvent the public dbus
api restrictions (only valid UTF8 strings).

The callbacks shall check via VID/PID information whether they support
the device and if not, return 0 so the dbus api is used to query the
current agent for pin input.
---
 src/adapter.c |   19 +++++++++++++++++++
 src/adapter.h |    8 ++++++++
 src/event.c   |   22 +++++++++++++++++++++-
 3 files changed, 48 insertions(+), 1 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 0909a22..689b73b 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -146,6 +146,7 @@ struct btd_adapter {
 	guint off_timer;
 
 	GSList *powered_callbacks;
+	GSList *pin_callbacks;
 
 	GSList *loaded_drivers;
 };
@@ -2573,6 +2574,7 @@ void adapter_remove(struct btd_adapter *adapter)
 	g_slist_free(adapter->devices);
 
 	unload_drivers(adapter);
+	g_slist_free(adapter->pin_callbacks);
 
 	/* Return adapter to down state if it was not up on init */
 	adapter_ops->restore_powered(adapter->dev_id);
@@ -3435,6 +3437,23 @@ int btd_adapter_switch_offline(struct btd_adapter *adapter)
 	return 0;
 }
 
+void btd_adapter_register_pincb(struct btd_adapter *adapter,
+							btd_adapter_pincb_t cb)
+{
+	adapter->pin_callbacks = g_slist_prepend(adapter->pin_callbacks, cb);
+}
+
+void btd_adapter_unregister_pincb(struct btd_adapter *adapter,
+							btd_adapter_pincb_t cb)
+{
+	adapter->pin_callbacks = g_slist_remove(adapter->pin_callbacks, cb);
+}
+
+GSList *btd_adapter_get_pincbs(struct btd_adapter *adapter)
+{
+	return adapter->pin_callbacks;
+}
+
 int btd_register_adapter_ops(struct btd_adapter_ops *ops, gboolean priority)
 {
 	if (ops->setup == NULL)
diff --git a/src/adapter.h b/src/adapter.h
index 38ea3ca..84b0bb0 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -165,6 +165,14 @@ int btd_adapter_restore_powered(struct btd_adapter *adapter);
 int btd_adapter_switch_online(struct btd_adapter *adapter);
 int btd_adapter_switch_offline(struct btd_adapter *adapter);
 
+typedef int (*btd_adapter_pincb_t) (struct btd_adapter *adapter,
+					struct btd_device *dev, char *out);
+void btd_adapter_register_pincb(struct btd_adapter *adapter,
+							btd_adapter_pincb_t cb);
+void btd_adapter_unregister_pincb(struct btd_adapter *adapter,
+							btd_adapter_pincb_t cb);
+GSList *btd_adapter_get_pincbs(struct btd_adapter *adapter);
+
 typedef void (*bt_hci_result_t) (uint8_t status, gpointer user_data);
 
 struct btd_adapter_ops {
diff --git a/src/event.c b/src/event.c
index 86a413e..ecbdaa0 100644
--- a/src/event.c
+++ b/src/event.c
@@ -123,6 +123,26 @@ fail:
 	error("Sending PIN code reply failed: %s (%d)", strerror(-err), -err);
 }
 
+static int get_pin(struct btd_adapter *adapter, struct btd_device *device,
+				bdaddr_t *sba, bdaddr_t *dba, char *pinbuf)
+{
+	GSList *ele;
+	btd_adapter_pincb_t cb;
+	int ret;
+
+	ele = btd_adapter_get_pincbs(adapter);
+	while (ele) {
+		cb = (void*)ele->data;
+		ret = cb(adapter, device, pinbuf);
+		if (ret > 0)
+			return ret;
+
+		ele = ele->next;
+	}
+
+	return read_pin_code(sba, dba, pinbuf);
+}
+
 int btd_event_request_pin(bdaddr_t *sba, bdaddr_t *dba, gboolean secure)
 {
 	struct btd_adapter *adapter;
@@ -134,7 +154,7 @@ int btd_event_request_pin(bdaddr_t *sba, bdaddr_t *dba, gboolean secure)
 		return -ENODEV;
 
 	memset(pin, 0, sizeof(pin));
-	pinlen = read_pin_code(sba, dba, pin);
+	pinlen = get_pin(adapter, device, sba, dba, pin);
 	if (pinlen > 0 && (!secure || pinlen == 16)) {
 		btd_adapter_pincode_reply(adapter, dba, pin, pinlen);
 		return 0;
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] Add support for wiimote pairing
  2011-07-08 16:34 [PATCH 1/2] Add pin-code hook to adapter api David Herrmann
@ 2011-07-08 16:34 ` David Herrmann
  2011-07-13  9:11 ` [PATCH 1/2] Add pin-code hook to adapter api Johan Hedberg
  1 sibling, 0 replies; 3+ messages in thread
From: David Herrmann @ 2011-07-08 16:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: padovan, johan.hedberg, marcel, David Herrmann

The Nintendo Wii Remote requires binary bluetooth addresses as PINs.
This is not possible via dbus agent API. So this adds a plugin that
registers a pin-callback and forces the right pin for every
authentication request of wiimotes.
---
 Makefile.am       |    5 ++
 acinclude.m4      |    6 +++
 plugins/wiimote.c |  111 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 122 insertions(+), 0 deletions(-)
 create mode 100644 plugins/wiimote.c

diff --git a/Makefile.am b/Makefile.am
index fab05eb..f1251b9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -227,6 +227,11 @@ builtin_sources += plugins/storage.c
 builtin_modules += adaptername
 builtin_sources += plugins/adaptername.c
 
+if WIIMOTEPLUGIN
+builtin_modules += wiimote
+builtin_sources += plugins/wiimote.c
+endif
+
 if MAEMO6PLUGIN
 builtin_modules += maemo6
 builtin_sources += plugins/maemo6.c
diff --git a/acinclude.m4 b/acinclude.m4
index af97cce..4073f59 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -213,6 +213,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 	maemo6_enable=no
 	sap_driver=dummy
 	dbusoob_enable=no
+	wiimote_enable=no
 
 	AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization], [disable code optimization]), [
 		optimization_enable=${enableval}
@@ -345,6 +346,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 		dbusoob_enable=${enableval}
 	])
 
+	AC_ARG_ENABLE(wiimote, AC_HELP_STRING([--enable-wiimote], [compile with Wii Remote plugin]), [
+		wiimote_enable=${enableval}
+	])
+
 	AC_ARG_ENABLE(hal, AC_HELP_STRING([--enable-hal], [Use HAL to determine adapter class]), [
 		hal_enable=${enableval}
 	])
@@ -403,4 +408,5 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 	AM_CONDITIONAL(DATAFILES, test "${datafiles_enable}" = "yes")
 	AM_CONDITIONAL(MAEMO6PLUGIN, test "${maemo6_enable}" = "yes")
 	AM_CONDITIONAL(DBUSOOBPLUGIN, test "${dbusoob_enable}" = "yes")
+	AM_CONDITIONAL(WIIMOTEPLUGIN, test "${wiimote_enable}" = "yes")
 ])
diff --git a/plugins/wiimote.c b/plugins/wiimote.c
new file mode 100644
index 0000000..c9b9156
--- /dev/null
+++ b/plugins/wiimote.c
@@ -0,0 +1,111 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2011  David Herrmann <dh.herrmann@googlemail.com>
+ *
+ *
+ *  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 <bluetooth/bluetooth.h>
+
+#include "plugin.h"
+#include "adapter.h"
+#include "device.h"
+#include "log.h"
+#include "storage.h"
+
+/*
+ * Nintendo Wii Remote devices require the bdaddr of the host as pin input for
+ * authentication. This plugin registers a pin-callback and forces this pin
+ * to be used for authentication.
+ *
+ * There are two ways to place the wiimote into discoverable mode.
+ *  - Pressing the red-sync button on the back of the wiimote. This module
+ *    supports pairing via this method. Auto-reconnect should be possible after
+ *    the device was paired once.
+ *  - Pressing the 1+2 buttons on the front of the wiimote. This module does
+ *    not support this method since this method never enables auto-reconnect.
+ *    Hence, pairing is not needed. Use it without pairing if you want.
+ * After connecting the wiimote you should immediately connect to the input
+ * service of the wiimote. If you don't, the wiimote will close the connection.
+ * The wiimote waits about 5 seconds until it turns off again.
+ * Auto-reconnect is only enabled when pairing with the wiimote via the red
+ * sync-button and then connecting to the input service. If you do not connect
+ * to the input service, then auto-reconnect is not enabled.
+ * If enabled, the wiimote connects to the host automatically when any button
+ * is pressed.
+ */
+
+static int wii_pincb(struct btd_adapter *adapter, struct btd_device *device,
+								char *pinbuf)
+{
+	uint16_t vendor, product;
+	bdaddr_t sba, dba;
+	char src_addr[18], dst_addr[18];
+
+	adapter_get_address(adapter, &sba);
+	device_get_address(device, &dba);
+	ba2str(&sba, src_addr);
+	ba2str(&dba, dst_addr);
+
+	if (0 == read_device_id(src_addr, dst_addr, NULL, &vendor, &product,
+									NULL)) {
+		if (vendor == 0x057e && product == 0x0306) {
+			DBG("Forcing fixed pin on detected wiimote %s", dst_addr);
+			memcpy(pinbuf, &sba, 6);
+			return 6;
+		}
+	}
+
+	return 0;
+}
+
+static int wii_probe(struct btd_adapter *adapter)
+{
+	btd_adapter_register_pincb(adapter, wii_pincb);
+
+	return 0;
+}
+
+static void wii_remove(struct btd_adapter *adapter)
+{
+	btd_adapter_unregister_pincb(adapter, wii_pincb);
+}
+
+static struct btd_adapter_driver wii_driver = {
+	.name	= "wiimote",
+	.probe	= wii_probe,
+	.remove	= wii_remove,
+};
+
+static int wii_init(void)
+{
+	return btd_register_adapter_driver(&wii_driver);
+}
+
+static void wii_exit(void)
+{
+	btd_unregister_adapter_driver(&wii_driver);
+}
+
+BLUETOOTH_PLUGIN_DEFINE(wiimote, VERSION,
+		BLUETOOTH_PLUGIN_PRIORITY_LOW, wii_init, wii_exit)
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/2] Add pin-code hook to adapter api
  2011-07-08 16:34 [PATCH 1/2] Add pin-code hook to adapter api David Herrmann
  2011-07-08 16:34 ` [PATCH 2/2] Add support for wiimote pairing David Herrmann
@ 2011-07-13  9:11 ` Johan Hedberg
  1 sibling, 0 replies; 3+ messages in thread
From: Johan Hedberg @ 2011-07-13  9:11 UTC (permalink / raw)
  To: David Herrmann; +Cc: linux-bluetooth, padovan, marcel

Hi David,

On Fri, Jul 08, 2011, David Herrmann wrote:
> +void btd_adapter_register_pincb(struct btd_adapter *adapter,
> +							btd_adapter_pincb_t cb)

Could you call this pin_cb instead of pincb (here and all other places).

> +GSList *btd_adapter_get_pincbs(struct btd_adapter *adapter)
> +{
> +	return adapter->pin_callbacks;
> +}

I think we could have btd_adapter_get_pin instead of your get_pin()
function and then this btd_adapter_get_pincbs wouldn't be needed at all.

> +static int get_pin(struct btd_adapter *adapter, struct btd_device *device,
> +				bdaddr_t *sba, bdaddr_t *dba, char *pinbuf)

For correctness I suppose the return value should really be ssize_t
instead of int. However, then you'll probably want to fix read_pin_code
in storage.c too. Furthermore, if you're passing btd_adapter and
btd_device it's redundant to pass sba and dba too.

> +	GSList *ele;

Call this variable just "l".

> +	ele = btd_adapter_get_pincbs(adapter);
> +	while (ele) {

Please use a for-loop here (the following example assumes you've moved
this internal to adapter.c as I proposed earlier):

	for (l = adapter->pin_callbacks; l != NULL; l = g_slist_next(l)) {
		...

> +		cb = (void*)ele->data;

There's no typecast needed for void*/gpointer. And even if it was the
coding style mandates a space between the case and the variable name.

Johan

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-07-13  9:11 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-08 16:34 [PATCH 1/2] Add pin-code hook to adapter api David Herrmann
2011-07-08 16:34 ` [PATCH 2/2] Add support for wiimote pairing David Herrmann
2011-07-13  9:11 ` [PATCH 1/2] Add pin-code hook to adapter api Johan Hedberg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.