2012-04-18 09:38:08

by Antonio Ospite

[permalink] [raw]
Subject: [PATCH BlueZ v2 0/3] Current status of playstation-peripheral plugin

This is a short summary about Playstation peripherals and their pairing
mechanism, to recap the current status of the playstation-peripheral plugin,
propose a working solution and discuss possible better ones.

>From now on in this message I sometime call a Playstation peripheral
simply a "device".

Bastien, please check if I am forgetting anything :)

WHAT we need the plugin to do:

- When a device is connected via USB:
+ Fetch the (default) adapter bdaddr (from BlueZ) and store it into
the device
+ Fetch the device bdaddr (from the device via USB/HID) and make the
device _trusted_ by the adapter (is "trusted" the correct term
here? Or maybe this is more like a "static association"? Are the
term "trusted" and "associated" in bluetooth context defined
anywhere?)

- When the device is connected via BT:
+ Nothing! It should work automatically.

- Set LEDs when possible.

WHY we need that:

Playstation peripherals require/support USB cable pairing.

It is required in the sense that devices will talk only to adapters
they know.

It is supported in the sense that this mechanism is optional on _some_
devices like the PS3 Keypad.

On the PS3 these cable paired devices can be used via BT without
further association steps once they have been connected
_at_least_once_ via USB to a certain host (with a certain BT adapter
that is), we would like to have the same behavior with BlueZ.

The current HOW:

We have the parameters (uuid, sdp record) to make the device "trusted"
all hardcoded in the plugin and we create the BlueZ files under
/var/lib/bluetooth/<adapter_bdaddr> using blues functions every time
a device is connected via USB.

NOTE: I don't know if we can make BlueZ pull those parameters from the
device itself somehow when the device connects via BT _the_first_time_

It has been suggested that this plugin is kept _external_ for three
reasons:
- it is not worth making bluetoothd bigger for a plugin used by very
few people
- avoid linking bluetoothd to libudev, which is needed by the plugin
- external plugins offer a finer packaging granularity (if the user
need this plugin it just have to install the .so provided by
a package prepared by distributors and restart bluetoothd, no need
to recompile)

But _external_ plugins can only use symbols exported as global in
src/bluetooth.ver, which currently are:

btd_*;
g_dbus_*;
info;
error;
debug;

So to avoid exporting more global symbols, for now I introduced two
new btd_* calls to do what I though I needed.

NOTE: the new functions were three in a first iteration but I managed
to remove one of them.

The three patches below show the current status.

The first two are prerequisites needed if we want to keep the plugin
_external_, the third patch is the plugin itself.

If you have any suggestion about how the development should proceed from
here on I'd like to hear from you.

Thanks,
Antonio

Antonio Ospite (3):
manager: add a btd_manager_get_default_adapter_address_str() call
device: add a btd_device_set_trusted() call
Add playstation-peripheral plugin: USB pairing and LEDs settings

Makefile.am | 7 +
acinclude.m4 | 10 +
plugins/playstation-peripheral-hid.c | 263 ++++++++++++++++++++++++
plugins/playstation-peripheral-hid.h | 10 +
plugins/playstation-peripheral.c | 376 ++++++++++++++++++++++++++++++++++
src/device.c | 74 +++++++
src/device.h | 9 +
src/manager.c | 21 ++
src/manager.h | 1 +
9 files changed, 771 insertions(+)
create mode 100644 plugins/playstation-peripheral-hid.c
create mode 100644 plugins/playstation-peripheral-hid.h
create mode 100644 plugins/playstation-peripheral.c

--
Antonio Ospite
http://ao2.it

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


2012-04-20 14:08:26

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH BlueZ v2 0/3] Current status of playstation-peripheral plugin

Hi Antonio,

On Fri, Apr 20, 2012, Antonio Ospite wrote:
> I'll add this information as a comment in the code.
>
> > > Bastien, please check if I am forgetting anything :)
> > >
> > > WHAT we need the plugin to do:
> > >
> > > - When a device is connected via USB:
> > > + Fetch the (default) adapter bdaddr (from BlueZ) and store it into
> > > the device
> > > + Fetch the device bdaddr (from the device via USB/HID) and make the
> > > device _trusted_ by the adapter (is "trusted" the correct term
> > > here?
> >
> > Setting it as trusted isn't the only thing you're doing. You're making
> > it known (meaning that you fill in details such as its SDP record,
> > including name), then adding it as trusted so that BlueZ doesn't ask the
> > user whether this device is allowed to connect.
> >
> > You need a separate function to make it "known" and insert it into
> > BlueZ's database. _set_trusted() should be a function that takes a
> > single device and a value (whether to trust or untrust), that's it.
> >
> > So you need to split it in 2 separate functions.
>
> OK, so the operations we are doing are:
> - Make the device "known" (add its details to the database of
> devices known by a given adapter)
> - Make the device trusted (enable its connection)
>
> Has the first operation a more official name? How does it relate to
> the "association" operation? Is it a device operation, in the sense
> that we are adding a device, or rather an adapter operation, in the
> sense that we are filling the database of a given adapter?

I'd make it an adapter operation and I'd also suggest to explore the
option of using the same API that devices get added to storage during
"normal" device discovery: btd_event_device_found(). After all you are
discovering a device in this use case. The only speciality is that it
happens over USB instead of traditional Bluetooth inquiry. That way you
would only need to add the set_trusted function and nothing else.

Johan

2012-04-20 12:36:25

by Antonio Ospite

[permalink] [raw]
Subject: Re: [PATCH BlueZ v2 0/3] Current status of playstation-peripheral plugin

On Wed, 18 Apr 2012 12:24:57 +0100
Bastien Nocera <[email protected]> wrote:

> On Wed, 2012-04-18 at 11:38 +0200, Antonio Ospite wrote:
> > This is a short summary about Playstation peripherals and their pairing
> > mechanism, to recap the current status of the playstation-peripheral plugin,
> > propose a working solution and discuss possible better ones.
> >
> > From now on in this message I sometime call a Playstation peripheral
> > simply a "device".
>
> Would be good to have all that information in a README, or the source,
> and list which devices we're capable of handling (Sixaxis? Keypad?
> Headset? Move?).
>

I'll add this information as a comment in the code.

> > Bastien, please check if I am forgetting anything :)
> >
> > WHAT we need the plugin to do:
> >
> > - When a device is connected via USB:
> > + Fetch the (default) adapter bdaddr (from BlueZ) and store it into
> > the device
> > + Fetch the device bdaddr (from the device via USB/HID) and make the
> > device _trusted_ by the adapter (is "trusted" the correct term
> > here?
>
> Setting it as trusted isn't the only thing you're doing. You're making
> it known (meaning that you fill in details such as its SDP record,
> including name), then adding it as trusted so that BlueZ doesn't ask the
> user whether this device is allowed to connect.
>
> You need a separate function to make it "known" and insert it into
> BlueZ's database. _set_trusted() should be a function that takes a
> single device and a value (whether to trust or untrust), that's it.
>
> So you need to split it in 2 separate functions.

OK, so the operations we are doing are:
- Make the device "known" (add its details to the database of
devices known by a given adapter)
- Make the device trusted (enable its connection)

Has the first operation a more official name? How does it relate to
the "association" operation? Is it a device operation, in the sense
that we are adding a device, or rather an adapter operation, in the
sense that we are filling the database of a given adapter?

Thanks,
Antonio

--
Antonio Ospite
http://ao2.it

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


Attachments:
(No filename) (2.25 kB)
(No filename) (198.00 B)
Download all attachments

2012-04-20 12:28:24

by Antonio Ospite

[permalink] [raw]
Subject: Re: [PATCH BlueZ v2 1/3] manager: add a btd_manager_get_default_adapter_address_str() call

On Wed, 18 Apr 2012 12:02:04 +0100
Bastien Nocera <[email protected]> wrote:

> On Wed, 2012-04-18 at 11:38 +0200, Antonio Ospite wrote:
> > Add a new btd_* call to get the default adapter address as a string,
> > meant to be used by _external_ plugins, this is to avoid to make public
> > these symbols:
> >
> > manager_get_default_adapter
> > adapter_get_address
> > bt_malloc
>
> It's already public.
>
> > ba2str
>
> Already public.
>

I think I am messing up the terminology again here, the interface is
public but the symbol is not exported as _global_ in src/bluetooth.ver
so external plugins can't use it.

> > ---
> > Alternatively a version without the _str prefix can be used which
> > returns a bdaddr_t, but I have to make ba2str a global symbol so I can
> > make the conversion to string in the plugin itself.
> >
> > Let me know how do you like that.
>
> ba2str() is in libbluetooth.
> $ grep ba2str /usr/include/bluetooth/bluetooth.h
> int ba2str(const bdaddr_t *ba, char *str);
>
> So it's already public.
>

What I meant is: if you like a version which returns a bdaddr_t rather
than a char* I have to add ba2str to src/bluetooth.ver

Thanks,
Antonio

--
Antonio Ospite
http://ao2.it

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


Attachments:
(No filename) (1.35 kB)
(No filename) (198.00 B)
Download all attachments

2012-04-18 11:24:57

by Bastien Nocera

[permalink] [raw]
Subject: Re: [PATCH BlueZ v2 0/3] Current status of playstation-peripheral plugin

On Wed, 2012-04-18 at 11:38 +0200, Antonio Ospite wrote:
> This is a short summary about Playstation peripherals and their pairing
> mechanism, to recap the current status of the playstation-peripheral plugin,
> propose a working solution and discuss possible better ones.
>
> From now on in this message I sometime call a Playstation peripheral
> simply a "device".

Would be good to have all that information in a README, or the source,
and list which devices we're capable of handling (Sixaxis? Keypad?
Headset? Move?).

> Bastien, please check if I am forgetting anything :)
>
> WHAT we need the plugin to do:
>
> - When a device is connected via USB:
> + Fetch the (default) adapter bdaddr (from BlueZ) and store it into
> the device
> + Fetch the device bdaddr (from the device via USB/HID) and make the
> device _trusted_ by the adapter (is "trusted" the correct term
> here?

Setting it as trusted isn't the only thing you're doing. You're making
it known (meaning that you fill in details such as its SDP record,
including name), then adding it as trusted so that BlueZ doesn't ask the
user whether this device is allowed to connect.

You need a separate function to make it "known" and insert it into
BlueZ's database. _set_trusted() should be a function that takes a
single device and a value (whether to trust or untrust), that's it.

So you need to split it in 2 separate functions.

> Or maybe this is more like a "static association"? Are the
> term "trusted" and "associated" in bluetooth context defined
> anywhere?)
>
> - When the device is connected via BT:
> + Nothing! It should work automatically.
>
> - Set LEDs when possible.
<snip>


2012-04-18 11:02:04

by Bastien Nocera

[permalink] [raw]
Subject: Re: [PATCH BlueZ v2 1/3] manager: add a btd_manager_get_default_adapter_address_str() call

On Wed, 2012-04-18 at 11:38 +0200, Antonio Ospite wrote:
> Add a new btd_* call to get the default adapter address as a string,
> meant to be used by _external_ plugins, this is to avoid to make public
> these symbols:
>
> manager_get_default_adapter
> adapter_get_address
> bt_malloc

It's already public.

> ba2str

Already public.

> ---
>
> Alternatively a version without the _str prefix can be used which
> returns a bdaddr_t, but I have to make ba2str a global symbol so I can
> make the conversion to string in the plugin itself.
>
> Let me know how do you like that.

ba2str() is in libbluetooth.
$ grep ba2str /usr/include/bluetooth/bluetooth.h
int ba2str(const bdaddr_t *ba, char *str);

So it's already public.

>
> src/manager.c | 21 +++++++++++++++++++++
> src/manager.h | 1 +
> 2 files changed, 22 insertions(+)
>
> diff --git a/src/manager.c b/src/manager.c
> index 6244516..fbd5ef8 100644
> --- a/src/manager.c
> +++ b/src/manager.c
> @@ -270,6 +270,27 @@ struct btd_adapter *manager_get_default_adapter(void)
> return manager_find_adapter_by_id(default_adapter_id);
> }
>
> +char *btd_manager_get_default_adapter_address_str(void)
> +{
> + struct btd_adapter *adapter;
> + bdaddr_t adapter_bdaddr;
> + char *str;
> +
> + adapter = manager_get_default_adapter();
> + if (adapter == NULL) {
> + return NULL;
> + }
> +
> + adapter_get_address(adapter, &adapter_bdaddr);
> +
> + str = bt_malloc(18);

You could have used batostr() instead, so you wouldn't have needed to do
the allocation yourself. Use bt_free() to free.

> + if (str == NULL)
> + return NULL;
> +
> + ba2str(&adapter_bdaddr, str);
> + return str;
> +}
> +
> static void manager_remove_adapter(struct btd_adapter *adapter)
> {
> uint16_t dev_id = adapter_get_dev_id(adapter);
> diff --git a/src/manager.h b/src/manager.h
> index 264cd25..7df882e 100644
> --- a/src/manager.h
> +++ b/src/manager.h
> @@ -36,6 +36,7 @@ const char *manager_get_base_path(void);
> struct btd_adapter *manager_find_adapter(const bdaddr_t *sba);
> struct btd_adapter *manager_find_adapter_by_id(int id);
> struct btd_adapter *manager_get_default_adapter(void);
> +char *btd_manager_get_default_adapter_address_str(void);
> void manager_foreach_adapter(adapter_cb func, gpointer user_data);
> GSList *manager_get_adapters(void);
> struct btd_adapter *btd_manager_register_adapter(int id, gboolean up);



2012-04-18 09:38:11

by Antonio Ospite

[permalink] [raw]
Subject: [PATCH BlueZ v2 3/3] Add playstation-peripheral plugin: USB pairing and LEDs settings

Add a plugin which handles the connection of a Playstation peripheral,
when a new hidraw device is connected the plugin:

- Filters udev events, and select the Playstation peripheral
- Sets the Master bluetooth address in the peripheral (USB pairing)
- Sets LEDs to match the joystick system number if needed
(for USB and BT)
- Adds the device to the database of the current default
adapter (BT association)

Signed-off-by: Bastien Nocera <[email protected]>
Signed-off-by: Antonio Ospite <[email protected]>
---

For the first review round plugins/playstation-peripheral.c is the most
interesting file, in particular the handle_device_plug() and
peripheral_pair() functions.

Makefile.am | 7 +
acinclude.m4 | 10 +
plugins/playstation-peripheral-hid.c | 263 ++++++++++++++++++++++++
plugins/playstation-peripheral-hid.h | 10 +
plugins/playstation-peripheral.c | 376 ++++++++++++++++++++++++++++++++++
5 files changed, 666 insertions(+)
create mode 100644 plugins/playstation-peripheral-hid.c
create mode 100644 plugins/playstation-peripheral-hid.h
create mode 100644 plugins/playstation-peripheral.c

diff --git a/Makefile.am b/Makefile.am
index 62705f6..61c7a07 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -267,6 +267,13 @@ builtin_modules += dbusoob
builtin_sources += plugins/dbusoob.c
endif

+if PLAYSTATION_PERIPHERAL_PLUGIN
+plugin_LTLIBRARIES += plugins/playstation-peripheral.la
+plugins_playstation_peripheral_la_SOURCES = plugins/playstation-peripheral.c plugins/playstation-peripheral-hid.c
+plugins_playstation_peripheral_la_LDFLAGS = -module -avoid-version -no-undefined @UDEV_LIBS@
+plugins_playstation_peripheral_la_CFLAGS = -fvisibility=hidden @DBUS_CFLAGS@ @GLIB_CFLAGS@ @UDEV_CFLAGS@
+endif
+
if MAINTAINER_MODE
plugin_LTLIBRARIES += plugins/external-dummy.la
plugins_external_dummy_la_SOURCES = plugins/external-dummy.c
diff --git a/acinclude.m4 b/acinclude.m4
index dcf9a48..06efe2a 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -176,6 +176,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [
sndfile_enable=${sndfile_found}
hal_enable=no
usb_enable=${usb_found}
+ playstation_peripheral_enable=${udev_found}
alsa_enable=${alsa_found}
gstreamer_enable=${gstreamer_found}
audio_enable=yes
@@ -265,6 +266,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [
usb_enable=${enableval}
])

+ AC_ARG_ENABLE(playstation_peripheral, AC_HELP_STRING([--enable-playstation-peripheral], [enable playstation-peripheral plugin]), [
+ playstation_peripheral_enable=${enableval}
+ ])
+
AC_ARG_ENABLE(tools, AC_HELP_STRING([--enable-tools], [install Bluetooth utilities]), [
tools_enable=${enableval}
])
@@ -360,6 +365,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [
AC_DEFINE(HAVE_LIBUSB, 1, [Define to 1 if you have USB library.])
fi

+ if (test "${playstation_peripheral_enable}" = "yes" && test "${udev_found}" = "yes"); then
+ AC_DEFINE(HAVE_PLAYSTATION_PERIPHERAL_PLUGIN, 1, [Define to 1 if you have playstation-peripheral plugin.])
+ fi
+
AM_CONDITIONAL(SNDFILE, test "${sndfile_enable}" = "yes" && test "${sndfile_found}" = "yes")
AM_CONDITIONAL(USB, test "${usb_enable}" = "yes" && test "${usb_found}" = "yes")
AM_CONDITIONAL(SBC, test "${alsa_enable}" = "yes" || test "${gstreamer_enable}" = "yes" ||
@@ -392,4 +401,5 @@ AC_DEFUN([AC_ARG_BLUEZ], [
AM_CONDITIONAL(DBUSOOBPLUGIN, test "${dbusoob_enable}" = "yes")
AM_CONDITIONAL(WIIMOTEPLUGIN, test "${wiimote_enable}" = "yes")
AM_CONDITIONAL(GATTMODULES, test "${gatt_enable}" = "yes")
+ AM_CONDITIONAL(PLAYSTATION_PERIPHERAL_PLUGIN, test "${playstation_peripheral_enable}" = "yes" && test "${udev_found}" = "yes")
])
diff --git a/plugins/playstation-peripheral-hid.c b/plugins/playstation-peripheral-hid.c
new file mode 100644
index 0000000..9c5e530
--- /dev/null
+++ b/plugins/playstation-peripheral-hid.c
@@ -0,0 +1,263 @@
+/*
+ * playstation peripheral plugin: lowlevel hid functions
+ *
+ * Copyright (C) 2011 Antonio Ospite <[email protected]>
+ *
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <linux/hidraw.h>
+
+#include "log.h"
+#include "playstation-peripheral-hid.h"
+
+/* Fallback definitions to compile with older headers */
+#ifndef HIDIOCGFEATURE
+#define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len)
+#endif
+
+#ifndef HIDIOCSFEATURE
+#define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len)
+#endif
+
+#define BDADDR_STR_SIZE 18 /* strlen("00:00:00:00:00:00") + 1 */
+
+#define LED_1 (0x01 << 1)
+#define LED_2 (0x01 << 2)
+#define LED_3 (0x01 << 3)
+#define LED_4 (0x01 << 4)
+
+#define LED_STATUS_OFF 0
+#define LED_STATUS_ON 1
+
+/* Usb cable pairing section */
+static unsigned char *get_feature_report(int fd, uint8_t report_number,
+ unsigned int len)
+{
+ unsigned char *buf;
+ int ret;
+
+ buf = calloc(len, sizeof(*buf));
+ if (buf == NULL) {
+ error("%s:%s() calloc failed", __FILE__, __func__);
+ return NULL;
+ }
+
+ buf[0] = report_number;
+
+ ret = ioctl(fd, HIDIOCGFEATURE(len), buf);
+ if (ret < 0) {
+ error("%s:%s() HIDIOCGFEATURE ret = %d",
+ __FILE__, __func__, ret);
+ free(buf);
+ return NULL;
+ }
+
+ return buf;
+}
+
+static int set_feature_report(int fd, uint8_t *report, int len)
+{
+ int ret;
+
+ ret = ioctl(fd, HIDIOCSFEATURE(len), report);
+ if (ret < 0)
+ error("%s:%s() HIDIOCSFEATURE failed, ret = %d",
+ __FILE__, __func__, ret);
+
+ return ret;
+}
+
+char *sixaxis_get_device_bdaddr(int fd)
+{
+ unsigned char *buf;
+ char *address;
+
+ buf = get_feature_report(fd, 0xf2, 18);
+ if (buf == NULL) {
+ error("%s:%s() cannot get feature report", __FILE__, __func__);
+ return NULL;
+ }
+
+ address = calloc(BDADDR_STR_SIZE, sizeof(*address));
+ if (address == NULL) {
+ error("%s:%s() calloc failed", __FILE__, __func__);
+ free(buf);
+ return NULL;
+ }
+
+ snprintf(address, BDADDR_STR_SIZE,
+ "%02X:%02X:%02X:%02X:%02X:%02X",
+ buf[4], buf[5], buf[6], buf[7], buf[8], buf[9]);
+
+ free(buf);
+ return address;
+}
+
+char *sixaxis_get_master_bdaddr(int fd)
+{
+ unsigned char *buf;
+ char *address;
+
+ buf = get_feature_report(fd, 0xf5, 8);
+ if (buf == NULL) {
+ error("%s:%s() cannot get feature report", __FILE__, __func__);
+ return NULL;
+ }
+
+ address = calloc(BDADDR_STR_SIZE, sizeof(*address));
+ if (address == NULL) {
+ error("%s:%s() calloc failed", __FILE__, __func__);
+ free(buf);
+ return NULL;
+ }
+
+ snprintf(address, BDADDR_STR_SIZE,
+ "%02X:%02X:%02X:%02X:%02X:%02X",
+ buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
+
+ free(buf);
+ return address;
+}
+
+int sixaxis_set_master_bdaddr(int fd, char *adapter_bdaddr)
+{
+ uint8_t *report;
+ uint8_t addr[6];
+ int ret;
+
+ ret = sscanf(adapter_bdaddr,
+ "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
+ &addr[0], &addr[1], &addr[2],
+ &addr[3], &addr[4], &addr[5]);
+ if (ret != 6) {
+ error("%s:%s() Parsing the bt address failed",
+ __FILE__, __func__);
+ return -EINVAL;
+ }
+
+ report = malloc(8);
+ if (report == NULL) {
+ error("%s:%s() malloc failed", __FILE__, __func__);
+ return -ENOMEM;
+ }
+
+ report[0] = 0xf5;
+ report[1] = 0x01;
+
+ report[2] = addr[0];
+ report[3] = addr[1];
+ report[4] = addr[2];
+ report[5] = addr[3];
+ report[6] = addr[4];
+ report[7] = addr[5];
+
+ ret = set_feature_report(fd, report, 8);
+ if (ret < 0) {
+ error("%s:%s() cannot set feature report",
+ __FILE__, __func__);
+ goto out;
+ }
+
+ DBG("New Master Bluetooth address: %s", adapter_bdaddr);
+
+out:
+ free(report);
+ return ret;
+}
+
+
+/* Led setting section */
+static int set_leds(int fd, unsigned char leds_status[4])
+{
+ int ret;
+
+ /*
+ * the total time the led is active (0xff means forever)
+ * | duty_length: how long a cycle is in deciseconds:
+ * | | (0 means "blink very fast")
+ * | | ??? (Maybe a phase shift or duty_length multiplier?)
+ * | | | % of duty_length led is off (0xff means 100%)
+ * | | | | % of duty_length led is on (0xff is 100%)
+ * | | | | |
+ * 0xff, 0x27, 0x10, 0x00, 0x32,
+ */
+ unsigned char leds_report[] = {
+ 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, /* rumble values TBD */
+ 0x00, 0x00, 0x00, 0x00, 0x1e, /* LED_1=0x02, LED_2=0x04 ... */
+ 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_4 */
+ 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_3 */
+ 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_2 */
+ 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_1 */
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+ };
+
+ int leds = 0;
+ if (leds_status[0])
+ leds |= LED_1;
+ if (leds_status[1])
+ leds |= LED_2;
+ if (leds_status[2])
+ leds |= LED_3;
+ if (leds_status[3])
+ leds |= LED_4;
+
+ leds_report[10] = leds;
+
+ ret = write(fd, leds_report, sizeof(leds_report));
+ if (ret < (ssize_t) sizeof(leds_report))
+ error("%s:%s() Unable to write to hidraw device",
+ __FILE__, __func__);
+
+ return ret;
+}
+
+int set_controller_number(int fd, unsigned int n)
+{
+ unsigned char leds_status[4] = {0, 0, 0, 0};
+
+ switch (n) {
+ case 0:
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ leds_status[n - 1] = LED_STATUS_ON;
+ break;
+ case 5:
+ case 6:
+ case 7:
+ leds_status[4 - 1] = LED_STATUS_ON;
+ leds_status[n - 4 - 1] = LED_STATUS_ON;
+ break;
+ default:
+ error("%s:%s() Only 7 controllers supported for now",
+ __FILE__, __func__);
+ return -1;
+ }
+
+ return set_leds(fd, leds_status);
+}
diff --git a/plugins/playstation-peripheral-hid.h b/plugins/playstation-peripheral-hid.h
new file mode 100644
index 0000000..ade8fa0
--- /dev/null
+++ b/plugins/playstation-peripheral-hid.h
@@ -0,0 +1,10 @@
+#ifndef __PLAYSTATION_PERIPHERAL_HID_H
+#define __PLAYSTATION_PERIPHERAL_HID_H
+
+char *sixaxis_get_device_bdaddr(int fd);
+char *sixaxis_get_master_bdaddr(int fd);
+int sixaxis_set_master_bdaddr(int fd, char *adapter_bdaddr);
+
+int set_controller_number(int fd, unsigned int n);
+
+#endif /* __PLAYSTATION_PERIPHERAL_HID_H */
diff --git a/plugins/playstation-peripheral.c b/plugins/playstation-peripheral.c
new file mode 100644
index 0000000..90d69ee
--- /dev/null
+++ b/plugins/playstation-peripheral.c
@@ -0,0 +1,376 @@
+/*
+ * playstation peripheral plugin: support for Playstation peripherals
+ *
+ * Copyright (C) 2009 Bastien Nocera <[email protected]>
+ * Copyright (C) 2011 Antonio Ospite <[email protected]>
+ *
+ *
+ * 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
+ *
+ */
+
+/*
+ * In the following this terminology is used:
+ *
+ * - peripheral: a Playstation peripheral (Sixaxis, DS3, headset, etc.)
+ * - controller: an input peripheral
+ * - adapter: the bluetooth dongle on the host system.
+ * - adapter_bdaddr: the bdaddr of the bluetooth adapter.
+ * - device_bdaddr: the bdaddr of the Playstation peripheral.
+ * - master_bdaddr: the bdaddr of the adapter to be configured into the
+ * Playstation peripheral
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <glib.h>
+
+#define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE 1
+#include <libudev.h>
+
+#include "plugin.h"
+#include "log.h"
+#include "adapter.h"
+#include "device.h"
+#include "manager.h"
+#include "storage.h"
+#include "sdp_lib.h"
+
+#include "playstation-peripheral-hid.h"
+
+struct playstation_peripheral {
+ uint16_t vendor_id;
+ uint16_t product_id;
+ char *name;
+ char *sdp_record;
+ char *uuid;
+
+ /* device specific callbacks to get master/device bdaddr and set
+ * master bdaddr
+ */
+ char * (*get_device_bdaddr)(int);
+ char * (*get_master_bdaddr)(int);
+ int (*set_master_bdaddr) (int, char *);
+};
+
+static struct playstation_peripheral peripherals[] = {
+ {
+ .vendor_id = 0x054c,
+ .product_id = 0x0268,
+ .name = "PLAYSTATION(R)3 Controller",
+ .sdp_record = "3601920900000A000100000900013503191124090004350D35061901000900113503190011090006350909656E09006A0901000900093508350619112409010009000D350F350D350619010009001335031900110901002513576972656C65737320436F6E74726F6C6C65720901012513576972656C65737320436F6E74726F6C6C6572090102251B536F6E7920436F6D707574657220456E7465727461696E6D656E740902000901000902010901000902020800090203082109020428010902052801090206359A35980822259405010904A101A102850175089501150026FF00810375019513150025013500450105091901291381027501950D0600FF8103150026FF0005010901A10075089504350046FF0009300931093209358102C0050175089527090181027508953009019102750895300901B102C0A1028502750895300901B102C0A10285EE750895300901B102C0A10285EF750895300901B102C0C0090207350835060904090901000902082800090209280109020A280109020B09010009020C093E8009020D280009020E2800",
+ .uuid = "00001124-0000-1000-8000-00805f9b34fb",
+ .get_device_bdaddr = sixaxis_get_device_bdaddr,
+ .get_master_bdaddr = sixaxis_get_master_bdaddr,
+ .set_master_bdaddr = sixaxis_set_master_bdaddr,
+ },
+};
+
+static struct udev *ctx;
+static struct udev_monitor *monitor;
+static guint watch_id;
+
+static int create_peripheral_association(const char *adapter_address,
+ const char *device_address,
+ struct playstation_peripheral *peripheral)
+{
+ int ret = 0;
+
+ ret = btd_device_set_trusted(adapter_address, device_address,
+ peripheral->name,
+ 0x0002, /* VersionIDSource = USB Implementer's Forum */
+ peripheral->vendor_id,
+ peripheral->product_id,
+ 0, /* version is hardcoded to 0 for now */
+ peripheral->uuid,
+ peripheral->sdp_record);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int peripheral_pair(int fd, char *adapter_bdaddr,
+ struct playstation_peripheral *peripheral)
+{
+ char *device_bdaddr;
+ char *master_bdaddr;
+ int ret = 0;
+
+ master_bdaddr = peripheral->get_master_bdaddr(fd);
+ if (master_bdaddr == NULL) {
+ DBG("Failed to get the Old master Bluetooth address from the device");
+ return -EPERM;
+ }
+
+ /* Only set the master bdaddr when needed, this is how the PS3 does
+ * it, perhaps to avoid unnecessary writes to some eeprom.
+ */
+ if (g_strcmp0(master_bdaddr, adapter_bdaddr) != 0) {
+ DBG("Old master Bluetooth address was: %s", master_bdaddr);
+ ret = peripheral->set_master_bdaddr(fd, adapter_bdaddr);
+ if (ret < 0) {
+ DBG("Failed to set the master Bluetooth address");
+ free(master_bdaddr);
+ return ret;
+ }
+ }
+
+ device_bdaddr = peripheral->get_device_bdaddr(fd);
+ if (device_bdaddr == NULL) {
+ DBG("Failed to get the Bluetooth address from the device");
+ free(master_bdaddr);
+ return -EPERM;
+ }
+
+ DBG("Device bdaddr %s", device_bdaddr);
+
+ ret = create_peripheral_association(adapter_bdaddr, device_bdaddr, peripheral);
+
+ free(device_bdaddr);
+ free(master_bdaddr);
+ return ret;
+}
+
+static inline struct playstation_peripheral *find_playstation_peripheral(const char *hid_id)
+{
+ unsigned int array_size = sizeof(peripherals)/sizeof(peripherals[0]);
+ unsigned int i;
+ int ret;
+ uint16_t protocol;
+ uint16_t vendor_id;
+ uint16_t product_id;
+
+ ret = sscanf(hid_id, "%hx:%hx:%hx", &protocol, &vendor_id, &product_id);
+ if (ret != 3) {
+ error("%s:%s() Parsing HID_ID failed",
+ __FILE__, __func__);
+ return NULL;
+ }
+
+ for (i = 0; i < array_size; i++) {
+ if (peripherals[i].vendor_id == vendor_id &&
+ peripherals[i].product_id == product_id)
+ return &peripherals[i];
+ }
+
+ return NULL;
+}
+
+static inline int is_usb_peripheral(const char *hid_id)
+{
+ int ret;
+ uint16_t protocol;
+ uint16_t vendor_id;
+ uint16_t product_id;
+
+ ret = sscanf(hid_id, "%hx:%hx:%hx", &protocol, &vendor_id, &product_id);
+ if (ret != 3) {
+ error("%s:%s() Parsing HID_ID failed",
+ __FILE__, __func__);
+ return 0;
+ }
+
+ DBG("%hx:%hx:%hx", protocol, vendor_id, product_id);
+ return (protocol == 3);
+}
+
+static void handle_device_plug(struct udev_device *udevice)
+{
+ struct udev_device *hid_parent;
+ struct udev_enumerate *enumerate;
+ struct udev_list_entry *devices, *dev_list_entry;
+ const char *hid_id;
+ const char *hid_phys;
+ const char *hidraw_node;
+ unsigned char is_usb = FALSE;
+ int js_num = 0;
+ int fd;
+ struct playstation_peripheral *peripheral;
+
+ hid_parent = udev_device_get_parent_with_subsystem_devtype(udevice,
+ "hid", NULL);
+ if (!hid_parent) {
+ error("%s:%s() cannot get parent hid device",
+ __FILE__, __func__);
+ return;
+ }
+
+ hid_id = udev_device_get_property_value(hid_parent, "HID_ID");
+ DBG("HID_ID: %s", hid_id);
+
+ peripheral = find_playstation_peripheral(hid_id);
+ if (!peripheral) {
+ error("No supported peripheral found");
+ return;
+ }
+
+ DBG("Found a Playstation peripheral: %s", peripheral->name);
+
+ hidraw_node = udev_device_get_devnode(udevice);
+
+ /* looking for joysticks */
+ hid_phys = udev_device_get_property_value(hid_parent, "HID_PHYS");
+
+ enumerate = udev_enumerate_new(udev_device_get_udev(udevice));
+ udev_enumerate_add_match_sysname(enumerate, "js*");
+ udev_enumerate_scan_devices(enumerate);
+
+ devices = udev_enumerate_get_list_entry(enumerate);
+ udev_list_entry_foreach(dev_list_entry, devices) {
+ const char *devname;
+ struct udev_device *js_dev;
+ struct udev_device *input_parent;
+ const char *input_phys;
+
+ devname = udev_list_entry_get_name(dev_list_entry);
+ js_dev = udev_device_new_from_syspath(udev_device_get_udev(udevice),
+ devname);
+
+ input_parent = udev_device_get_parent_with_subsystem_devtype(js_dev,
+ "input", NULL);
+ if (!input_parent) {
+ error("%s:%s() cannot get parent input device.",
+ __FILE__, __func__);
+ continue;
+ }
+
+ /* check this is the joystick relative to
+ * the hidraw device above */
+ input_phys = udev_device_get_sysattr_value(input_parent,
+ "phys");
+ if (g_strcmp0(input_phys, hid_phys) == 0) {
+ js_num = atoi(udev_device_get_sysnum(js_dev)) + 1;
+ DBG("joypad device_num: %d", js_num);
+ DBG("hidraw_node: %s", hidraw_node);
+ }
+
+ udev_device_unref(js_dev);
+ }
+
+ udev_enumerate_unref(enumerate);
+
+ fd = open(hidraw_node, O_RDWR);
+ if (fd < 0) {
+ error("%s:%s() hidraw open", __FILE__, __func__);
+ return;
+ }
+
+ is_usb = is_usb_peripheral(hid_id);
+ if (is_usb) {
+ char *adapter_bdaddr;
+
+ adapter_bdaddr = btd_manager_get_default_adapter_address_str();
+ if (adapter_bdaddr == NULL) {
+ error("No adapters, exiting");
+ return;
+ }
+
+ DBG("Adapter bdaddr %s", adapter_bdaddr);
+
+ peripheral_pair(fd, adapter_bdaddr, peripheral);
+ free(adapter_bdaddr);
+ }
+
+ if (js_num > 0)
+ set_controller_number(fd, js_num);
+
+ close(fd);
+}
+
+static gboolean device_event_idle(struct udev_device *udevice)
+{
+ handle_device_plug(udevice);
+ udev_device_unref(udevice);
+ return FALSE;
+}
+
+static gboolean monitor_event(GIOChannel *source, GIOCondition condition,
+ gpointer data)
+{
+ struct udev_device *udevice;
+
+ udevice = udev_monitor_receive_device(monitor);
+ if (udevice == NULL)
+ goto out;
+ if (g_strcmp0(udev_device_get_action(udevice), "add") != 0) {
+ udev_device_unref(udevice);
+ goto out;
+ }
+
+ /* Give UDEV some time to load kernel modules */
+ g_timeout_add_seconds(1, (GSourceFunc) device_event_idle, udevice);
+
+out:
+ return TRUE;
+}
+
+static int playstation_peripheral_init(void)
+{
+ GIOChannel *channel;
+
+ DBG("Setup Playstation peripheral plugin");
+
+ ctx = udev_new();
+ monitor = udev_monitor_new_from_netlink(ctx, "udev");
+ if (monitor == NULL) {
+ error("%s:%s() Could not get udev monitor",
+ __FILE__, __func__);
+ return -1;
+ }
+
+ /* Listen for newly connected hidraw interfaces */
+ udev_monitor_filter_add_match_subsystem_devtype(monitor,
+ "hidraw", NULL);
+ udev_monitor_enable_receiving(monitor);
+
+ channel = g_io_channel_unix_new(udev_monitor_get_fd(monitor));
+ watch_id = g_io_add_watch(channel, G_IO_IN, monitor_event, NULL);
+ g_io_channel_unref(channel);
+
+ return 0;
+}
+
+static void playstation_peripheral_exit(void)
+{
+ DBG("Cleanup Playstation peripheral plugin");
+
+ if (watch_id != 0) {
+ g_source_remove(watch_id);
+ watch_id = 0;
+ }
+ if (monitor != NULL) {
+ udev_monitor_unref(monitor);
+ monitor = NULL;
+ }
+ if (ctx != NULL) {
+ udev_unref(ctx);
+ ctx = NULL;
+ }
+}
+
+BLUETOOTH_PLUGIN_DEFINE(playstation_peripheral, VERSION,
+ BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
+ playstation_peripheral_init,
+ playstation_peripheral_exit)
--
1.7.10


2012-04-18 09:38:10

by Antonio Ospite

[permalink] [raw]
Subject: [PATCH BlueZ v2 2/3] device: add a btd_device_set_trusted() call

Add a new btd_* call to set a device as trusted, meant to be used by
_external_ plugins, this avoid making public these symbols:

record_from_string
store_record
sdp_record_free
str2ba
str2ba
store_device_id
write_trust
dbus_bus_get
manager_find_adapter
adapter_get_device
dbus_connection_unref
---

If BlueZ can pull the required parameters itself from trusted devices this can
be simplified, if not then the name should be fixed to make clearer what the
function does.

src/device.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/device.h | 9 +++++++
2 files changed, 83 insertions(+)

diff --git a/src/device.c b/src/device.c
index ea6fec2..6e434c1 100644
--- a/src/device.c
+++ b/src/device.c
@@ -49,6 +49,7 @@
#include "att.h"
#include "hcid.h"
#include "adapter.h"
+#include "manager.h"
#include "gattrib.h"
#include "attio.h"
#include "device.h"
@@ -2948,6 +2949,79 @@ GSList *btd_device_get_primaries(struct btd_device *device)
return device->primaries;
}

+int btd_device_set_trusted(const char *adapter_address,
+ const char *device_address,
+ char *name,
+ uint16_t vendor_id_source,
+ uint16_t vendor_id,
+ uint16_t product_id,
+ uint16_t version_id,
+ const char *uuid,
+ const char *sdp_record)
+{
+ struct btd_adapter *adapter;
+ struct btd_device *device;
+ DBusConnection *conn;
+ bdaddr_t src;
+ bdaddr_t dst;
+ sdp_record_t *record;
+ int ret = 0;
+
+ record = record_from_string(sdp_record);
+ if (record == NULL) {
+ ret = -ENODEV;
+ goto out;
+ }
+ ret = store_record(adapter_address, device_address, record);
+ sdp_record_free(record);
+ if (ret < 0)
+ goto out;
+
+ str2ba(adapter_address, &src);
+ str2ba(device_address, &dst);
+
+ /* Set the device id */
+ store_device_id(adapter_address, device_address, vendor_id_source, vendor_id,
+ product_id, version_id);
+ /* Don't write a profile here,
+ * it will be updated when the device connects */
+
+ write_trust(adapter_address, device_address, "[all]", TRUE);
+
+ conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+ if (conn == NULL) {
+ DBG("Failed to get on the bus");
+ ret = -EPERM;
+ goto out;
+ }
+
+ adapter = manager_find_adapter(&src);
+ if (adapter == NULL) {
+ DBG("Failed to get the adapter");
+ ret = -EPERM;
+ goto out_dbus_unref;
+ }
+
+ /* This is needed: adapter_find_device() wouldn't need a Dbus
+ * connection but it would not be enough as it only searches for
+ * already existing devices, while adapter_get_device() will create a
+ * new device if necessary.
+ */
+ device = adapter_get_device(conn, adapter, device_address);
+ if (device == NULL) {
+ DBG("Failed to get the device");
+ ret = -ENODEV;
+ goto out_dbus_unref;
+ }
+
+ btd_device_add_uuid(device, uuid);
+
+out_dbus_unref:
+ dbus_connection_unref(conn);
+out:
+ return ret;
+}
+
void btd_device_add_uuid(struct btd_device *device, const char *uuid)
{
GSList *uuid_list;
diff --git a/src/device.h b/src/device.h
index 690c64d..1011e3e 100644
--- a/src/device.h
+++ b/src/device.h
@@ -57,6 +57,15 @@ void device_register_services(DBusConnection *conn, struct btd_device *device,
GSList *prim_list, int psm);
GSList *device_services_from_record(struct btd_device *device,
GSList *profiles);
+int btd_device_set_trusted(const char *adapter_address,
+ const char *device_address,
+ char *name,
+ uint16_t vendor_id_source,
+ uint16_t vendor_id,
+ uint16_t product_id,
+ uint16_t version_id,
+ const char *uuid,
+ const char *sdp_record);
void btd_device_add_uuid(struct btd_device *device, const char *uuid);
struct btd_adapter *device_get_adapter(struct btd_device *device);
void device_get_address(struct btd_device *device, bdaddr_t *bdaddr,
--
1.7.10


2012-04-18 09:38:09

by Antonio Ospite

[permalink] [raw]
Subject: [PATCH BlueZ v2 1/3] manager: add a btd_manager_get_default_adapter_address_str() call

Add a new btd_* call to get the default adapter address as a string,
meant to be used by _external_ plugins, this is to avoid to make public
these symbols:

manager_get_default_adapter
adapter_get_address
bt_malloc
ba2str
---

Alternatively a version without the _str prefix can be used which
returns a bdaddr_t, but I have to make ba2str a global symbol so I can
make the conversion to string in the plugin itself.

Let me know how do you like that.


src/manager.c | 21 +++++++++++++++++++++
src/manager.h | 1 +
2 files changed, 22 insertions(+)

diff --git a/src/manager.c b/src/manager.c
index 6244516..fbd5ef8 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -270,6 +270,27 @@ struct btd_adapter *manager_get_default_adapter(void)
return manager_find_adapter_by_id(default_adapter_id);
}

+char *btd_manager_get_default_adapter_address_str(void)
+{
+ struct btd_adapter *adapter;
+ bdaddr_t adapter_bdaddr;
+ char *str;
+
+ adapter = manager_get_default_adapter();
+ if (adapter == NULL) {
+ return NULL;
+ }
+
+ adapter_get_address(adapter, &adapter_bdaddr);
+
+ str = bt_malloc(18);
+ if (str == NULL)
+ return NULL;
+
+ ba2str(&adapter_bdaddr, str);
+ return str;
+}
+
static void manager_remove_adapter(struct btd_adapter *adapter)
{
uint16_t dev_id = adapter_get_dev_id(adapter);
diff --git a/src/manager.h b/src/manager.h
index 264cd25..7df882e 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -36,6 +36,7 @@ const char *manager_get_base_path(void);
struct btd_adapter *manager_find_adapter(const bdaddr_t *sba);
struct btd_adapter *manager_find_adapter_by_id(int id);
struct btd_adapter *manager_get_default_adapter(void);
+char *btd_manager_get_default_adapter_address_str(void);
void manager_foreach_adapter(adapter_cb func, gpointer user_data);
GSList *manager_get_adapters(void);
struct btd_adapter *btd_manager_register_adapter(int id, gboolean up);
--
1.7.10


2012-05-14 10:37:38

by Antonio Ospite

[permalink] [raw]
Subject: Re: [PATCH BlueZ v2 0/3] Current status of playstation-peripheral plugin

On Fri, 20 Apr 2012 17:08:26 +0300
Johan Hedberg <[email protected]> wrote:

> Hi Antonio,
>
> On Fri, Apr 20, 2012, Antonio Ospite wrote:
> > I'll add this information as a comment in the code.
> >
> > > > Bastien, please check if I am forgetting anything :)
> > > >
> > > > WHAT we need the plugin to do:
> > > >
> > > > - When a device is connected via USB:
> > > > + Fetch the (default) adapter bdaddr (from BlueZ) and store it into
> > > > the device
> > > > + Fetch the device bdaddr (from the device via USB/HID) and make the
> > > > device _trusted_ by the adapter (is "trusted" the correct term
> > > > here?
> > >
> > > Setting it as trusted isn't the only thing you're doing. You're making
> > > it known (meaning that you fill in details such as its SDP record,
> > > including name), then adding it as trusted so that BlueZ doesn't ask the
> > > user whether this device is allowed to connect.
> > >
> > > You need a separate function to make it "known" and insert it into
> > > BlueZ's database. _set_trusted() should be a function that takes a
> > > single device and a value (whether to trust or untrust), that's it.
> > >
> > > So you need to split it in 2 separate functions.
> >
> > OK, so the operations we are doing are:
> > - Make the device "known" (add its details to the database of
> > devices known by a given adapter)
> > - Make the device trusted (enable its connection)
> >
> > Has the first operation a more official name? How does it relate to
> > the "association" operation? Is it a device operation, in the sense
> > that we are adding a device, or rather an adapter operation, in the
> > sense that we are filling the database of a given adapter?
>
> I'd make it an adapter operation and I'd also suggest to explore the
> option of using the same API that devices get added to storage during
> "normal" device discovery: btd_event_device_found(). After all you are
> discovering a device in this use case. The only speciality is that it
> happens over USB instead of traditional Bluetooth inquiry. That way you
> would only need to add the set_trusted function and nothing else.
>

OK, so far I've split the set_trusted() bits and moved the old big
function to adapter.c, it is now called: btd_create_stored_device()

I noticed than set_trusted() (i.e. writing to the trusts file) has to be
called before I create the device when connected via USB, otherwise
the later connection via BT does not succeed.

I am still looking how to use the adapter API in
btd_create_stored_device(), Scott if you are still willing to help I am
sending you the latest patches privately to avoid making too much noise
here for very small incremental changes.

Regards,
Antonio

--
Antonio Ospite
http://ao2.it

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


Attachments:
(No filename) (2.88 kB)
(No filename) (198.00 B)
Download all attachments