* Re: [PATCH] Add support for Logitech Harmony Adapter for PS3
From: Luiz Augusto von Dentz @ 2012-09-10 13:11 UTC (permalink / raw)
To: David Dillow, linux-bluetooth
In-Reply-To: <20120907124559.GA16092@x220>
Hi David, Bastien,
So we are plannin to rid of the fakehid.c in favor of implementing it
properly inside the kernel similarly to what was done to wiimote, so
is there any obstacle for doing that?
The kernel seems to already have some support for sixaxis in
drivers/hid/hid-sony.c, so I suppose the following would enable us to
use it:
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 41c34f2..a34d92c 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -684,6 +684,7 @@
#define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b
#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
#define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f
+#define BT_DEVICE_ID_SONY_PS3_CONTROLLER 0x0306
#define USB_VENDOR_ID_SOUNDGRAPH 0x15c2
#define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 5cd25bd..17dd1bb 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -216,6 +216,8 @@ static const struct hid_device_id sony_devices[] = {
.driver_data = SIXAXIS_CONTROLLER_USB },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY,
USB_DEVICE_ID_SONY_PS3_CONTROLLER),
.driver_data = SIXAXIS_CONTROLLER_BT },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY,
BT_DEVICE_ID_SONY_PS3_CONTROLLER),
+ .driver_data = SIXAXIS_CONTROLLER_BT },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
.driver_data = VAIO_RDESC_CONSTANT },
{ }
--
Luiz Augusto von Dentz
^ permalink raw reply related
* Re: [PATCH RFC] battery: Add generic device battery interface
From: Claudio Takahasi @ 2012-09-10 13:24 UTC (permalink / raw)
To: Chen Ganir; +Cc: linux-bluetooth
In-Reply-To: <504C3044.9000200@ti.com>
Hi Chen Ganir:
On Sun, Sep 9, 2012 at 2:59 AM, Chen Ganir <chen.ganir@ti.com> wrote:
> Claudio,
>
>
> On 09/06/2012 10:34 PM, Claudio Takahasi wrote:
>>
>> Hi Chen Ganir:
>>
>> On Thu, Aug 30, 2012 at 8:26 AM, <chen.ganir@ti.com> wrote:
>>>
>>> From: Chen Ganir <chen.ganir@ti.com>
>>>
>>> Add the D-Bus API documentation for the new generic device battery
>>> interface. This API provides generic access to peer devcice
>>> batteries.
>>> ---
>>> doc/battery-api.txt | 34 ++++++++++++++++++++++++++++++++++
>>> doc/device-api.txt | 5 +++++
>>> 2 files changed, 39 insertions(+)
>>> create mode 100644 doc/battery-api.txt
>>>
>>> diff --git a/doc/battery-api.txt b/doc/battery-api.txt
>>> new file mode 100644
>>> index 0000000..da82024
>>> --- /dev/null
>>> +++ b/doc/battery-api.txt
>>> @@ -0,0 +1,34 @@
>>> +BlueZ D-Bus Battery API description
>>> +****************************************
>>> +
>>> + Texas Instruments, Inc. <chen.ganir@ti.com>
>>> +
>>> +Device Battery hierarchy
>>> +=====================================
>>> +
>>> +Service org.bluez
>>> +Interface org.bluez.Battery
>>> +Object path [variable
>>> prefix]/{hci0,..}/dev_XX_XX_XX_XX_XX_XX/BATTYYYY
>>> +YYYY is numeric value between 0 and 9999.
>>> +
>>> +Methods dict GetProperties()
>>> +
>>> + Returns all properties for the interface. See the
>>> + Properties section for the available properties.
>>> +
>>> +Signals PropertyChanged(string name, variant value)
>>> +
>>> + This signal indicates a changed value of the given
>>> + property.
>>> +
>>> +Properties uint16 Level [readonly]
>>> +
>>> + Battery level (0-100).
>>> +
>>> + uint16 Description [readonly]
>>> +
>>> + Battery description.
>>> +
>>> + uint16 Namespace [readonly]
>>> +
>>> + Battery Namespace.
>>
>>
>> IMO "Description" and "Namespace" should be string:
>> http://developer.bluetooth.org/gatt/Pages/GattNamespaceDescriptors.aspx
>>
>> For BLE Presentation Format is mandatory(Namespace and Description).
>> For AVRCP, probably it doesn't make sense. I recommend to include
>> additional description for these fields.
>>
> After discussing this issue with Johan, we decided to remove the Namespace
> and Description properties from the generic battery. Do you think we should
> have those properties or can we exclude them ? Do you see any use case for
> those properties?
>
IMO, we can remove them. It is easier to extend the API later than
remove properties from the API.
Those properties could be useful for PTS testing or qualification, but
we can use gatttool to discover and read descriptors.
Regards,
Claudio
^ permalink raw reply
* Re: [PATCH BlueZ v3 06/15] gdbus: Implement DBus.Properties.Set method
From: Luiz Augusto von Dentz @ 2012-09-10 13:42 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: Lucas De Marchi, linux-bluetooth
In-Reply-To: <1347049144.21200.130.camel@aeonflux>
Hi Marcel,
On Fri, Sep 7, 2012 at 11:19 PM, Marcel Holtmann <marcel@holtmann.org> wrote:
>> Im afraid you will have to go in detail what you want here, the
>> security table seems to be meant for checking privileges in a method
>> level while we can probably extend it for properties and have
>> privileges also in the properties table, but the security table seems
>> to be global not per interface.
>
> you can specify unique integer identifiers as security label to each
> method. We could extend that to each property. The security label is
> used to pick which security callback to call.
Fair enough, but one thing that we might have to consider is that the
label could be dynamic e.g. when a method call has a special security
policy regarding senders (common when we track senders), so perhaps
instead of having the privileges as it is now we need a callback e.g.
check_privileges which takes the sender and returns the
label/privileges needed.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH] Add support for Logitech Harmony Adapter for PS3
From: Bastien Nocera @ 2012-09-10 13:47 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: David Dillow, linux-bluetooth
In-Reply-To: <CABBYNZ+5E+BC-+9fj0e7iUpEDFJrJBQo8aoMZj8ZEkmiuB=QLA@mail.gmail.com>
Em Mon, 2012-09-10 às 16:11 +0300, Luiz Augusto von Dentz escreveu:
> Hi David, Bastien,
>
> So we are plannin to rid of the fakehid.c in favor of implementing it
> properly inside the kernel similarly to what was done to wiimote, so
> is there any obstacle for doing that?
>
> The kernel seems to already have some support for sixaxis in
> drivers/hid/hid-sony.c, so I suppose the following would enable us to
> use it:
It won't. They're not the same hardware.
> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
> index 41c34f2..a34d92c 100644
> --- a/drivers/hid/hid-ids.h
> +++ b/drivers/hid/hid-ids.h
> @@ -684,6 +684,7 @@
> #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b
> #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
> #define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f
> +#define BT_DEVICE_ID_SONY_PS3_CONTROLLER 0x0306
>
> #define USB_VENDOR_ID_SOUNDGRAPH 0x15c2
> #define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034
> diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
> index 5cd25bd..17dd1bb 100644
> --- a/drivers/hid/hid-sony.c
> +++ b/drivers/hid/hid-sony.c
> @@ -216,6 +216,8 @@ static const struct hid_device_id sony_devices[] = {
> .driver_data = SIXAXIS_CONTROLLER_USB },
> { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY,
> USB_DEVICE_ID_SONY_PS3_CONTROLLER),
> .driver_data = SIXAXIS_CONTROLLER_BT },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY,
> BT_DEVICE_ID_SONY_PS3_CONTROLLER),
> + .driver_data = SIXAXIS_CONTROLLER_BT },
> { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
> .driver_data = VAIO_RDESC_CONSTANT },
> { }
>
^ permalink raw reply
* Re: [PATCH] Add support for Logitech Harmony Adapter for PS3
From: Luiz Augusto von Dentz @ 2012-09-10 13:58 UTC (permalink / raw)
To: Bastien Nocera; +Cc: David Dillow, linux-bluetooth
In-Reply-To: <1347284864.3532.1.camel@sirocco.hadess.net>
Hi Bastien,
On Mon, Sep 10, 2012 at 4:47 PM, Bastien Nocera <hadess@hadess.net> wrote:
> Em Mon, 2012-09-10 às 16:11 +0300, Luiz Augusto von Dentz escreveu:
>> Hi David, Bastien,
>>
>> So we are plannin to rid of the fakehid.c in favor of implementing it
>> properly inside the kernel similarly to what was done to wiimote, so
>> is there any obstacle for doing that?
>>
>> The kernel seems to already have some support for sixaxis in
>> drivers/hid/hid-sony.c, so I suppose the following would enable us to
>> use it:
>
> It won't. They're not the same hardware.
What hardware is that then? And why wouldn't the kernel be able to
support even if it is a different driver?
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH] Add support for Logitech Harmony Adapter for PS3
From: Luiz Augusto von Dentz @ 2012-09-10 19:03 UTC (permalink / raw)
To: Bastien Nocera; +Cc: David Dillow, linux-bluetooth
In-Reply-To: <CABBYNZJpHkt8CGDsfVwirZ=vecb-fhbpPbrVFKt1UR_rA25mSw@mail.gmail.com>
Hi Bastien,
On Mon, Sep 10, 2012 at 4:58 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> Hi Bastien,
>
> On Mon, Sep 10, 2012 at 4:47 PM, Bastien Nocera <hadess@hadess.net> wrote:
>> Em Mon, 2012-09-10 às 16:11 +0300, Luiz Augusto von Dentz escreveu:
>>> Hi David, Bastien,
>>>
>>> So we are plannin to rid of the fakehid.c in favor of implementing it
>>> properly inside the kernel similarly to what was done to wiimote, so
>>> is there any obstacle for doing that?
>>>
>>> The kernel seems to already have some support for sixaxis in
>>> drivers/hid/hid-sony.c, so I suppose the following would enable us to
>>> use it:
>>
>> It won't. They're not the same hardware.
>
> What hardware is that then? And why wouldn't the kernel be able to
> support even if it is a different driver?
So what exactly are the difference between 0x0268 and 0x0306? And why
sixpair.c save as 0x0268 while fakeinput.c uses 0x0306?
Also, after fixing sixpair.c to be able to compile it does add to the
storage but it does not create any object until bluetoothd is
restarted and even after restart it does not allow the device to
connect because it does has the record (although this can be fixed by
automatically add the UUID once we find out it is attempt to connect).
--
Luiz Augusto von Dentz
^ permalink raw reply
* [RFC 0/3] Support for Intel BT USB driver
From: Tedd Ho-Jeong An @ 2012-09-10 21:29 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, Ho, Albert O, tedd.an
[-- Attachment #1: Type: text/plain, Size: 1307 bytes --]
From: Tedd Ho-Jeong AN <tedd.an@intel.com>
These set of patches adds Intel BT USB support. The patch adds an extension
to execute of vendor specific initialization at early stage (before normal
BT controller initialization & after the USB is initialized).
- During the USB probe time, if the VID/PID are matched, it executes a
vendor specific initialization routine and uses a vendor specific HCI
event handler. When completed, the existing HCI event handler is restored.
- When vendor specific initialization completes, normal BT controller
initialization continues.
The rest of patches are Intel specific implementation.
Tedd Ho-Jeong An (3):
Bluetooth: Add initial skeleton for Intel BT USB support
Bluetooth: Implement Intel specific device initialization
Bluetooth: Add timeout for Intel specific device initialization
drivers/bluetooth/Makefile | 2 +-
drivers/bluetooth/btusb.c | 29 +++
drivers/bluetooth/btusb.h | 31 +++
drivers/bluetooth/btusb_intel.c | 420 ++++++++++++++++++++++++++++++++++++++
include/net/bluetooth/hci_core.h | 6 +
net/bluetooth/hci_core.c | 16 ++
6 files changed, 503 insertions(+), 1 deletion(-)
create mode 100644 drivers/bluetooth/btusb.h
create mode 100644 drivers/bluetooth/btusb_intel.c
--
1.7.9.5
[-- Attachment #2: Type: text/html, Size: 6401 bytes --]
^ permalink raw reply
* [RFC 1/3] Bluetooth: Add initial skeleton for Intel BT USB support
From: Tedd Ho-Jeong An @ 2012-09-10 21:29 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, tedd.an, Ho, Albert O
[-- Attachment #1: Type: text/plain, Size: 10191 bytes --]
From: Tedd Ho-Jeong An <tedd.an@intel.com>
This patch adds an initial skeleton for Intel BT USB support.
- Extension to execute of vendor specific initialization at early stage
which is before normal BT controller initialization and after the USB
is initialized.
- Add initial skeleton of Intel specific initialization functions
- Add Intel BT USB VID/PID
Outpu from /sys/kernel/debug/usb/devices:
T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=8087 ProdID=07dc Rev= 0.00
C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=1ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
Signed-off-by: Tedd Ho-Jeong AN <tedd.an@intel.com>
---
drivers/bluetooth/Makefile | 2 +-
drivers/bluetooth/btusb.c | 29 ++++++++++++++
drivers/bluetooth/btusb.h | 31 +++++++++++++++
drivers/bluetooth/btusb_intel.c | 81 ++++++++++++++++++++++++++++++++++++++
include/net/bluetooth/hci_core.h | 6 +++
net/bluetooth/hci_core.c | 16 ++++++++
6 files changed, 164 insertions(+), 1 deletion(-)
create mode 100644 drivers/bluetooth/btusb.h
create mode 100644 drivers/bluetooth/btusb_intel.c
diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
index 4afae20..57c7fe2 100644
--- a/drivers/bluetooth/Makefile
+++ b/drivers/bluetooth/Makefile
@@ -12,7 +12,7 @@ obj-$(CONFIG_BT_HCIBT3C) += bt3c_cs.o
obj-$(CONFIG_BT_HCIBLUECARD) += bluecard_cs.o
obj-$(CONFIG_BT_HCIBTUART) += btuart_cs.o
-obj-$(CONFIG_BT_HCIBTUSB) += btusb.o
+obj-$(CONFIG_BT_HCIBTUSB) += btusb.o btusb_intel.o
obj-$(CONFIG_BT_HCIBTSDIO) += btsdio.o
obj-$(CONFIG_BT_ATH3K) += ath3k.o
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index f637c25..029c5b7 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -27,6 +27,8 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
+#include "btusb.h"
+
#define VERSION "0.6"
static bool ignore_dga;
@@ -47,6 +49,8 @@ static struct usb_driver btusb_driver;
#define BTUSB_BROKEN_ISOC 0x20
#define BTUSB_WRONG_SCO_MTU 0x40
#define BTUSB_ATH3012 0x80
+#define BTUSB_INTEL 0x100
+#define BTUSB_DEV_INIT 0x8000
static struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */
@@ -190,6 +194,9 @@ static struct usb_device_id blacklist_table[] = {
/* Frontline ComProbe Bluetooth Sniffer */
{ USB_DEVICE(0x16d3, 0x0002), .driver_info = BTUSB_SNIFFER },
+ /* Intel Bluetooth device */
+ { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_DEV_INIT | BTUSB_INTEL },
+
{ } /* Terminating entry */
};
@@ -235,6 +242,17 @@ struct btusb_data {
int suspend_count;
};
+struct btusb_vendor_dev {
+ unsigned long info;
+ int (*vsdev_init)(struct hci_dev *hdev);
+ void (*vsdev_event)(struct hci_dev *hdev, struct sk_buff *skb);
+};
+
+static struct btusb_vendor_dev vendor_dev[] = {
+ { BTUSB_INTEL, btusb_intel_init, btusb_intel_event },
+ { 0 }
+};
+
static int inc_tx(struct btusb_data *data)
{
unsigned long flags;
@@ -1069,6 +1087,17 @@ static int btusb_probe(struct usb_interface *intf,
}
}
+ /* vendor specific device initialization */
+ if (id->driver_info & BTUSB_DEV_INIT) {
+ for (i = 0; vendor_dev[i].info; i++) {
+ if (id->driver_info & vendor_dev[i].info) {
+ hdev->vsdev_init = vendor_dev[i].vsdev_init;
+ hdev->vsdev_event = vendor_dev[i].vsdev_event;
+ break;
+ }
+ }
+ }
+
err = hci_register_dev(hdev);
if (err < 0) {
hci_free_dev(hdev);
diff --git a/drivers/bluetooth/btusb.h b/drivers/bluetooth/btusb.h
new file mode 100644
index 0000000..f03040f
--- /dev/null
+++ b/drivers/bluetooth/btusb.h
@@ -0,0 +1,31 @@
+/*
+ *
+ * Generic Bluetooth USB driver
+ *
+ * Copyright (C) 2005-2008 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __BTUSB_H
+#define __BTUSB_H
+
+/* Intel specific device initialization callbacks */
+int btusb_intel_init(struct hci_dev *hdev);
+void btusb_intel_event(struct hci_dev *hdev, struct sk_buff *skb);
+
+#endif /* __BTUSB_H */
diff --git a/drivers/bluetooth/btusb_intel.c b/drivers/bluetooth/btusb_intel.c
new file mode 100644
index 0000000..51c019d
--- /dev/null
+++ b/drivers/bluetooth/btusb_intel.c
@@ -0,0 +1,81 @@
+/*
+ *
+ * Bluetooth USB Driver - Intel device initialization
+ *
+ * Copyright (C) 2012 Intel Corporation
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include "btusb.h"
+
+/* patch state */
+enum intel_patch_state {
+ INTEL_PATCH_PRE,
+ INTEL_PATCH_VER,
+ INTEL_PATCH_PREP_PATCH,
+ INTEL_PATCH_PATCHING,
+ INTEL_PATCH_POST,
+ INTEL_PATCH_COMPLETED,
+ INTEL_PATCH_ERROR
+};
+
+struct intel_patch_data {
+ struct hci_dev *hdev;
+
+ int state;
+};
+
+int btusb_intel_init(struct hci_dev *hdev)
+{
+ struct intel_patch_data *data;
+
+ BT_INFO("Intel BT USB: device initialization - patching device");
+
+ /* initialize the data structure */
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ BT_ERR("failed to allocate the memory for patch data");
+ return -ENOMEM;
+ }
+ hdev->vsdev_init_data = data;
+
+ data->hdev = hdev;
+ data->state = INTEL_PATCH_PRE;
+
+ kfree(data);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(btusb_intel_init);
+
+void btusb_intel_event(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct intel_patch_data *data = hdev->vsdev_init_data;
+
+ BT_DBG("Intel BT USB: HCI event handler state=%d", data->state);
+
+ del_timer(&hdev->cmd_timer);
+ atomic_set(&hdev->cmd_cnt, 1);
+ kfree_skb(skb);
+ return;
+}
+EXPORT_SYMBOL_GPL(btusb_intel_event);
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 6a3337e..cde0ddd 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -275,6 +275,12 @@ struct hci_dev {
int (*send)(struct sk_buff *skb);
void (*notify)(struct hci_dev *hdev, unsigned int evt);
int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
+
+ int vsdev_init_completed;
+ void *vsdev_init_data;
+
+ int (*vsdev_init)(struct hci_dev *hdev);
+ void (*vsdev_event)(struct hci_dev *hdev, struct sk_buff *skb);
};
struct hci_conn {
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e407051..4b23812 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -685,6 +685,17 @@ int hci_dev_open(__u16 dev)
set_bit(HCI_INIT, &hdev->flags);
hdev->init_last_cmd = 0;
+ if (hdev->vsdev_init && !hdev->vsdev_init_completed) {
+ ret = hdev->vsdev_init(hdev);
+ BT_DBG("vsdev_init completed: %d", ret);
+ /* set this flag so vsdev_init() execute only once */
+ hdev->vsdev_init_completed = 1;
+ /* make sure to use generic event handler */
+ hdev->vsdev_event = NULL;
+ if (ret < 0)
+ goto done;
+ }
+
ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
if (lmp_host_le_capable(hdev))
@@ -2119,6 +2130,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
return 0;
}
+EXPORT_SYMBOL(hci_send_cmd);
/* Get data from the previously sent command */
void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
@@ -2800,7 +2812,11 @@ static void hci_rx_work(struct work_struct *work)
switch (bt_cb(skb)->pkt_type) {
case HCI_EVENT_PKT:
BT_DBG("%s Event packet", hdev->name);
+ /* send packet to device init event handler */
+ if (hdev->vsdev_init_completed || !hdev->vsdev_event)
hci_event_packet(hdev, skb);
+ else
+ hdev->vsdev_event(hdev, skb);
break;
case HCI_ACLDATA_PKT:
--
1.7.9.5
[-- Attachment #2: Type: text/html, Size: 56148 bytes --]
^ permalink raw reply related
* [RFC 2/3] Bluetooth: Implement Intel specific device initialization
From: Tedd Ho-Jeong An @ 2012-09-10 21:29 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, tedd.an, Ho, Albert O
[-- Attachment #1: Type: text/plain, Size: 9454 bytes --]
From: Tedd Ho-Jeong An <tedd.an@intel.com>
This patch implements the Intel specific device initialization:
- Enable the device configuration mode
- Read the FW version of the device
- Open the patch file, if exists.
- Send the patch data via HCI command
- Once done, disable the device configuation mode
Signed-off-by: Tedd Ho-Jeong AN <tedd.an@intel.com>
---
drivers/bluetooth/btusb_intel.c | 322 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 321 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btusb_intel.c b/drivers/bluetooth/btusb_intel.c
index 51c019d..d45ddb9 100644
--- a/drivers/bluetooth/btusb_intel.c
+++ b/drivers/bluetooth/btusb_intel.c
@@ -21,12 +21,38 @@
*
*/
#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
#include <linux/errno.h>
+#include <linux/timer.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include "btusb.h"
+/* Intel specific HCI cmd opcodes */
+#define INTEL_HCI_MFG_MODE 0xfc11
+#define INTEL_HCI_GET_VER 0xfc05
+
+/* Intel specific HCI cmd parameter for patch reset */
+#define INTEL_HCI_PATCH_SKIP 0x00
+#define INTEL_HCI_PATCH_DISABLE 0x01
+#define INTEL_HCI_PATCH_ENABLE 0x02
+
+/* Intel specific HCI event status - success */
+#define INTEL_EV_STATUS_SUCCESS 0x00
+
+/* Intel specific patch file location and file extension */
+#define INTEL_PATCH_DIR "intel/"
+#define INTEL_PATCH_EXT ".bseq"
+
+/* Patch entry type flag */
+#define INTEL_PATCH_TYPE_CMD 0x01
+#define INTEL_PATCH_TYPE_EVT 0x02
+
+/* Maximum length of one patch entry */
+#define INTEL_PATCH_MAX_LEN 260
+
/* patch state */
enum intel_patch_state {
INTEL_PATCH_PRE,
@@ -42,11 +68,165 @@ struct intel_patch_data {
struct hci_dev *hdev;
int state;
+ u8 patch_reset;
+
+ struct completion wait_patch_completion;
+
+ char device_ver[32];
+ const struct firmware *fw;
+ const u8 *patch_curr;
+ unsigned int patch_read;
};
+static int intel_send_mfg_cmd(struct hci_dev *hdev, u8 mode, u8 reset)
+{
+ u8 param[2];
+
+ param[0] = mode;
+ param[1] = reset;
+
+ BT_DBG("mfg mode: %02x reset: %02x", mode, reset);
+
+ return hci_send_cmd(hdev, INTEL_HCI_MFG_MODE, 2, param);
+}
+
+static int intel_send_patch_cmd(struct intel_patch_data *data)
+{
+ const u8 *ptr;
+ u8 param[INTEL_PATCH_MAX_LEN];
+ u16 opcode;
+ struct hci_command_hdr *hdr;
+
+ ptr = data->patch_curr;
+ if (*ptr != INTEL_PATCH_TYPE_CMD) {
+ BT_ERR("invalid patch cmd sequence: %02x", *ptr);
+ return -EILSEQ;
+ }
+ ptr++;
+
+ hdr = (void *)ptr;
+ opcode = le16_to_cpu(hdr->opcode);
+
+ ptr += sizeof(*hdr);
+
+ /* update the data before sending the command */
+ data->patch_curr = ptr + hdr->plen;
+ data->patch_read += hdr->plen + 4;
+
+ memcpy(param, ptr, hdr->plen);
+
+ if (hci_send_cmd(data->hdev, opcode, hdr->plen, param) < 0) {
+ BT_ERR("failed to send patch cmd: %04x", opcode);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int intel_verify_cc_evt(struct sk_buff *skb, u16 opcode)
+{
+ u8 status;
+ u16 opc;
+ struct hci_ev_cmd_complete *cc;
+ struct hci_event_hdr *hdr;
+
+ hdr = (void *)skb->data;
+ if (hdr->evt != HCI_EV_CMD_COMPLETE) {
+ BT_ERR("invalid event code: %02x", hdr->evt);
+ return -1;
+ }
+ skb_pull(skb, sizeof(*hdr));
+
+ cc = (void *)skb->data;
+ opc = le16_to_cpu(cc->opcode);
+ if (opc != opcode) {
+ BT_ERR("invalid opcode: %04x", opc);
+ return -1;
+ }
+ skb_pull(skb, sizeof(*cc));
+
+ status = *((u8 *) skb->data);
+ if (status != INTEL_EV_STATUS_SUCCESS) {
+ BT_ERR("event status failed: %02x", status);
+ return -1;
+ }
+ skb_pull(skb, 1);
+
+ return 0;
+}
+
+static int intel_verify_ver_cc_evt(struct sk_buff *skb,
+ struct intel_patch_data *data)
+{
+ int i;
+ if (intel_verify_cc_evt(skb, INTEL_HCI_GET_VER) < 0)
+ return -1;
+
+ for (i = 0; i < skb->len; i++)
+ sprintf(&data->device_ver[i*2], "%02x", skb->data[i]);
+
+ return 0;
+}
+
+static int intel_verify_patch_evt(struct sk_buff *skb,
+ struct intel_patch_data *data)
+{
+ const u8 *ptr;
+ struct hci_event_hdr *s_hdr;
+ struct hci_event_hdr *p_hdr;
+
+ ptr = data->patch_curr;
+ if (INTEL_PATCH_TYPE_EVT != *ptr) {
+ BT_ERR("invalid patch evt sequence: %02x", *ptr);
+ return -EILSEQ;
+ }
+ ptr++;
+
+ p_hdr = (void *)ptr;
+ s_hdr = (void *)skb->data;
+
+ if (p_hdr->evt != s_hdr->evt || p_hdr->plen != s_hdr->plen) {
+ BT_ERR("mismatch evt hdr: %02x %02x", s_hdr->evt, s_hdr->plen);
+ return -1;
+ }
+
+ ptr += sizeof(*p_hdr);
+ skb_pull(skb, sizeof(*s_hdr));
+
+ data->patch_curr = ptr + p_hdr->plen;
+ data->patch_read += p_hdr->plen + 3;
+
+ if (memcmp(ptr, skb->data, s_hdr->plen)) {
+ BT_ERR("mismatch evt data");
+ }
+
+ return 0;
+}
+
+static int intel_prepare_patch_file(struct intel_patch_data *data)
+{
+ char file[120];
+
+ snprintf(file, 120, "%s%s%s", INTEL_PATCH_DIR, data->device_ver,
+ INTEL_PATCH_EXT);
+ BT_DBG("patch file: %s", file);
+
+ if (request_firmware(&data->fw, file, &data->hdev->dev) < 0) {
+ BT_ERR("failed to open patch file: %s", file);
+ return -1;
+ }
+
+ data->patch_read = 0;
+ data->patch_curr = data->fw->data;
+
+ return 0;
+}
+
int btusb_intel_init(struct hci_dev *hdev)
{
+ int ret;
struct intel_patch_data *data;
+ int cont = 1;
BT_INFO("Intel BT USB: device initialization - patching device");
@@ -61,9 +241,93 @@ int btusb_intel_init(struct hci_dev *hdev)
data->hdev = hdev;
data->state = INTEL_PATCH_PRE;
+ init_completion(&data->wait_patch_completion);
+
+ while (cont) {
+ BT_DBG("patch state: %d", data->state);
+ switch (data->state) {
+ case INTEL_PATCH_PRE:
+ /* send cmd to enable the device configuration mode */
+ ret = intel_send_mfg_cmd(hdev, 0x01, 0x00);
+ if (ret < 0) {
+ BT_ERR("failed to send cmd: enter mfg %d", ret);
+ goto exit_error;
+ }
+ break;
+
+ case INTEL_PATCH_VER:
+ /* send cmd to get the device's version */
+ ret = hci_send_cmd(hdev, INTEL_HCI_GET_VER, 0, NULL);
+ if (ret < 0) {
+ BT_ERR("failed to send cmd: get ver %d", ret);
+ goto exit_error;
+ }
+ break;
+
+ case INTEL_PATCH_PREP_PATCH:
+ /* open the patch file if it is available */
+ ret = intel_prepare_patch_file(data);
+ if (ret < 0) {
+ BT_ERR("failed to prepare patch file %d", ret);
+ data->state = INTEL_PATCH_POST;
+ data->patch_reset = INTEL_HCI_PATCH_SKIP;
+ } else {
+ BT_DBG("patch data is setup");
+ data->state = INTEL_PATCH_PATCHING;
+ }
+ /* this is the only state that doesn't expect any evt */
+ goto skip_wait;
+
+ case INTEL_PATCH_PATCHING:
+ /* send patch entry in patch data. one at a time */
+ ret = intel_send_patch_cmd(data);
+ if (ret < 0) {
+ BT_ERR("failed to send cmd: patch cmd %d", ret);
+ goto exit_error;
+ }
+ break;
+
+ case INTEL_PATCH_POST:
+ /* exit the device configuration mode */
+ ret = intel_send_mfg_cmd(hdev, 0x00, data->patch_reset);
+ if (ret < 0) {
+ BT_ERR("failed to send cmd: exit mfg: %d", ret);
+ goto exit_error;
+ }
+ break;
+
+ default:
+ BT_ERR("unknown patch state: %d", data->state);
+ ret = -EILSEQ;
+ goto exit_error;
+ }
+
+ /* waiting for event */
+ ret = wait_for_completion_interruptible(
+ &data->wait_patch_completion);
+ if (ret < 0) {
+ BT_ERR("patch completion error: %d", ret);
+ goto exit_error;
+ }
+
+skip_wait:
+ if (data->state == INTEL_PATCH_ERROR) {
+ BT_ERR("patch error");
+ ret = -EILSEQ;
+ goto exit_error;
+ }
+
+ if (data->state == INTEL_PATCH_COMPLETED) {
+ BT_INFO("patch completed");
+ cont = 0;
+ }
+ }
+
+exit_error:
+ release_firmware(data->fw);
kfree(data);
- return 0;
+ return ret;
}
EXPORT_SYMBOL_GPL(btusb_intel_init);
@@ -73,9 +337,65 @@ void btusb_intel_event(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("Intel BT USB: HCI event handler state=%d", data->state);
+ switch (data->state) {
+ case INTEL_PATCH_PRE:
+ if (intel_verify_cc_evt(skb, INTEL_HCI_MFG_MODE) < 0) {
+ BT_ERR("cmd failed: enter mfg mode");
+ data->state = INTEL_PATCH_ERROR;
+ } else {
+ BT_DBG("cmd success: enter mfg mode");
+ data->state = INTEL_PATCH_VER;
+ }
+ break;
+
+ case INTEL_PATCH_VER:
+ if (intel_verify_ver_cc_evt(skb, data) < 0) {
+ BT_ERR("cmd failed: get version");
+ data->patch_reset = INTEL_HCI_PATCH_SKIP;
+ data->state = INTEL_PATCH_POST;
+ } else {
+ BT_DBG("cmd success: get version");
+ data->state = INTEL_PATCH_PREP_PATCH;
+ }
+ break;
+
+ case INTEL_PATCH_PATCHING:
+ if (intel_verify_patch_evt(skb, data) < 0) {
+ BT_ERR("cmd failed: patch");
+ data->patch_reset = INTEL_HCI_PATCH_DISABLE;
+ data->state = INTEL_PATCH_POST;
+ } else {
+ BT_DBG("cmd success: patch");
+ if (data->patch_read == data->fw->size) {
+ BT_DBG("no more patch to send");
+ data->patch_reset = INTEL_HCI_PATCH_ENABLE;
+ data->state = INTEL_PATCH_POST;
+ } else {
+ BT_DBG("more patch to send");
+ }
+ }
+ break;
+
+ case INTEL_PATCH_POST:
+ if (intel_verify_cc_evt(skb, INTEL_HCI_MFG_MODE) < 0) {
+ BT_ERR("cmd failed: exit mfg mode");
+ data->state = INTEL_PATCH_ERROR;
+ } else {
+ BT_DBG("cmd success: exit mfg mode");
+ data->state = INTEL_PATCH_COMPLETED;
+ }
+ break;
+
+ default:
+ BT_ERR("unknown patch state: %d", data->state);
+ data->state = INTEL_PATCH_ERROR;
+ break;
+ }
+
del_timer(&hdev->cmd_timer);
atomic_set(&hdev->cmd_cnt, 1);
kfree_skb(skb);
+ complete(&data->wait_patch_completion);
return;
}
EXPORT_SYMBOL_GPL(btusb_intel_event);
--
1.7.9.5
[-- Attachment #2: Type: text/html, Size: 65304 bytes --]
^ permalink raw reply related
* [RFC 3/3] Bluetooth: Add timeout for Intel specific device initialization
From: Tedd Ho-Jeong An @ 2012-09-10 21:29 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, tedd.an, Ho, Albert O
[-- Attachment #1: Type: text/plain, Size: 1784 bytes --]
From: Tedd Ho-Jeong An <tedd.an@intel.com>
This patch adds the tiemout for Intel specific device initialization.
Signed-off-by: Tedd Ho-Jeong AN <tedd.an@intel.com>
---
drivers/bluetooth/btusb_intel.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/drivers/bluetooth/btusb_intel.c b/drivers/bluetooth/btusb_intel.c
index d45ddb9..3657203 100644
--- a/drivers/bluetooth/btusb_intel.c
+++ b/drivers/bluetooth/btusb_intel.c
@@ -30,6 +30,9 @@
#include "btusb.h"
+/* patch timeout - 10 seconds */
+#define INTEL_PATCH_TIMEOUT msecs_to_jiffies(10000)
+
/* Intel specific HCI cmd opcodes */
#define INTEL_HCI_MFG_MODE 0xfc11
#define INTEL_HCI_GET_VER 0xfc05
@@ -71,6 +74,7 @@ struct intel_patch_data {
u8 patch_reset;
struct completion wait_patch_completion;
+ struct timer_list patch_timeout;
char device_ver[32];
const struct firmware *fw;
@@ -222,6 +226,16 @@ static int intel_prepare_patch_file(struct intel_patch_data *data)
return 0;
}
+static void intel_patch_timeout(unsigned long arg)
+{
+ struct intel_patch_data *data = (void *)arg;
+
+ BT_ERR("patch timer expired");
+ data->state = INTEL_PATCH_ERROR;
+
+ complete(&data->wait_patch_completion);
+}
+
int btusb_intel_init(struct hci_dev *hdev)
{
int ret;
@@ -243,6 +257,10 @@ int btusb_intel_init(struct hci_dev *hdev)
init_completion(&data->wait_patch_completion);
+ setup_timer(&data->patch_timeout, intel_patch_timeout,
+ (unsigned long) data);
+ mod_timer(&data->patch_timeout, jiffies + INTEL_PATCH_TIMEOUT);
+
while (cont) {
BT_DBG("patch state: %d", data->state);
switch (data->state) {
@@ -324,6 +342,7 @@ skip_wait:
}
exit_error:
+ del_timer_sync(&data->patch_timeout);
release_firmware(data->fw);
kfree(data);
--
1.7.9.5
[-- Attachment #2: Type: text/html, Size: 12273 bytes --]
^ permalink raw reply related
* Dropping connection (bit off-topic)
From: John Tobias @ 2012-09-10 21:35 UTC (permalink / raw)
To: linux-bluetooth
Hello Guys,
I am using pandaboard with USB BLE dongle and an apps in iPhone that
do the advertising. I was able to connect to the said device from my
pandaboard using the following commands:
gatttool -i hci1 -m 27 -I -b 74:xx:xx:xx:xx:xx
connect
But, I've noticed that after 30 secs, the iPhone dropped off the
connection. I am just wondering if anyone here have tried playing with
the iPhone using the ble connection?.
Regards,
John
^ permalink raw reply
* Re: Dropping connection (bit off-topic)
From: John Tobias @ 2012-09-10 21:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <CACUGKYONE6a2PWtOEY4Kgg9TQkX3pCwhW9UJLk5KGVtpL5eVaw@mail.gmail.com>
Addition to that, if iPhone to iPhone bluetooth le connection, it
won't drop the connectivity.
Regards,
John
On Mon, Sep 10, 2012 at 2:35 PM, John Tobias <john.tobias.ph@gmail.com> wrote:
> Hello Guys,
>
> I am using pandaboard with USB BLE dongle and an apps in iPhone that
> do the advertising. I was able to connect to the said device from my
> pandaboard using the following commands:
>
> gatttool -i hci1 -m 27 -I -b 74:xx:xx:xx:xx:xx
> connect
>
> But, I've noticed that after 30 secs, the iPhone dropped off the
> connection. I am just wondering if anyone here have tried playing with
> the iPhone using the ble connection?.
>
> Regards,
>
> John
^ permalink raw reply
* [RFC 0/3] Support for Intel BT USB driver
From: Tedd Ho-Jeong An @ 2012-09-10 22:34 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, albert.o.ho
From: Tedd Ho-Jeong An <tedd.an@intel.com>
These set of patches adds Intel BT USB support. The patch adds an extension
to execute of vendor specific initialization at early stage (before normal
BT controller initialization & after the USB is initialized).
- During the USB probe time, if the VID/PID are matched, it executes a
vendor specific initialization routine and uses a vendor specific HCI
event handler. When completed, the existing HCI event handler is restored.
- When vendor specific initialization completes, normal BT controller
initialization continues.
The rest of patches are Intel specific implementation.
Tedd Ho-Jeong An (3):
Bluetooth: Add initial skeleton for Intel BT USB support
Bluetooth: Implement Intel specific device initialization
Bluetooth: Add timeout for Intel specific device initialization
drivers/bluetooth/Makefile | 2 +-
drivers/bluetooth/btusb.c | 29 +++
drivers/bluetooth/btusb.h | 31 +++
drivers/bluetooth/btusb_intel.c | 420 ++++++++++++++++++++++++++++++++++++++
include/net/bluetooth/hci_core.h | 6 +
net/bluetooth/hci_core.c | 16 ++
6 files changed, 503 insertions(+), 1 deletion(-)
create mode 100644 drivers/bluetooth/btusb.h
create mode 100644 drivers/bluetooth/btusb_intel.c
--
1.7.9.5
^ permalink raw reply
* [RFC 1/3] Bluetooth: Add initial skeleton for Intel BT USB support
From: Tedd Ho-Jeong An @ 2012-09-10 22:35 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, albert.o.ho
From: Tedd Ho-Jeong An <tedd.an@intel.com>
This patch adds an initial skeleton for Intel BT USB support.
- Extension to execute of vendor specific initialization at early stage
which is before normal BT controller initialization and after the USB
is initialized.
- Add initial skeleton of Intel specific initialization functions
- Add Intel BT USB VID/PID
Outpu from /sys/kernel/debug/usb/devices:
T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=8087 ProdID=07dc Rev= 0.00
C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=1ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
Signed-off-by: Tedd Ho-Jeong An <tedd.an@intel.com>
---
drivers/bluetooth/Makefile | 2 +-
drivers/bluetooth/btusb.c | 29 ++++++++++++++
drivers/bluetooth/btusb.h | 31 +++++++++++++++
drivers/bluetooth/btusb_intel.c | 81 ++++++++++++++++++++++++++++++++++++++
include/net/bluetooth/hci_core.h | 6 +++
net/bluetooth/hci_core.c | 16 ++++++++
6 files changed, 164 insertions(+), 1 deletion(-)
create mode 100644 drivers/bluetooth/btusb.h
create mode 100644 drivers/bluetooth/btusb_intel.c
diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
index 4afae20..57c7fe2 100644
--- a/drivers/bluetooth/Makefile
+++ b/drivers/bluetooth/Makefile
@@ -12,7 +12,7 @@ obj-$(CONFIG_BT_HCIBT3C) += bt3c_cs.o
obj-$(CONFIG_BT_HCIBLUECARD) += bluecard_cs.o
obj-$(CONFIG_BT_HCIBTUART) += btuart_cs.o
-obj-$(CONFIG_BT_HCIBTUSB) += btusb.o
+obj-$(CONFIG_BT_HCIBTUSB) += btusb.o btusb_intel.o
obj-$(CONFIG_BT_HCIBTSDIO) += btsdio.o
obj-$(CONFIG_BT_ATH3K) += ath3k.o
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index f637c25..029c5b7 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -27,6 +27,8 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
+#include "btusb.h"
+
#define VERSION "0.6"
static bool ignore_dga;
@@ -47,6 +49,8 @@ static struct usb_driver btusb_driver;
#define BTUSB_BROKEN_ISOC 0x20
#define BTUSB_WRONG_SCO_MTU 0x40
#define BTUSB_ATH3012 0x80
+#define BTUSB_INTEL 0x100
+#define BTUSB_DEV_INIT 0x8000
static struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */
@@ -190,6 +194,9 @@ static struct usb_device_id blacklist_table[] = {
/* Frontline ComProbe Bluetooth Sniffer */
{ USB_DEVICE(0x16d3, 0x0002), .driver_info = BTUSB_SNIFFER },
+ /* Intel Bluetooth device */
+ { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_DEV_INIT | BTUSB_INTEL },
+
{ } /* Terminating entry */
};
@@ -235,6 +242,17 @@ struct btusb_data {
int suspend_count;
};
+struct btusb_vendor_dev {
+ unsigned long info;
+ int (*vsdev_init)(struct hci_dev *hdev);
+ void (*vsdev_event)(struct hci_dev *hdev, struct sk_buff *skb);
+};
+
+static struct btusb_vendor_dev vendor_dev[] = {
+ { BTUSB_INTEL, btusb_intel_init, btusb_intel_event },
+ { 0 }
+};
+
static int inc_tx(struct btusb_data *data)
{
unsigned long flags;
@@ -1069,6 +1087,17 @@ static int btusb_probe(struct usb_interface *intf,
}
}
+ /* vendor specific device initialization */
+ if (id->driver_info & BTUSB_DEV_INIT) {
+ for (i = 0; vendor_dev[i].info; i++) {
+ if (id->driver_info & vendor_dev[i].info) {
+ hdev->vsdev_init = vendor_dev[i].vsdev_init;
+ hdev->vsdev_event = vendor_dev[i].vsdev_event;
+ break;
+ }
+ }
+ }
+
err = hci_register_dev(hdev);
if (err < 0) {
hci_free_dev(hdev);
diff --git a/drivers/bluetooth/btusb.h b/drivers/bluetooth/btusb.h
new file mode 100644
index 0000000..f03040f
--- /dev/null
+++ b/drivers/bluetooth/btusb.h
@@ -0,0 +1,31 @@
+/*
+ *
+ * Generic Bluetooth USB driver
+ *
+ * Copyright (C) 2005-2008 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __BTUSB_H
+#define __BTUSB_H
+
+/* Intel specific device initialization callbacks */
+int btusb_intel_init(struct hci_dev *hdev);
+void btusb_intel_event(struct hci_dev *hdev, struct sk_buff *skb);
+
+#endif /* __BTUSB_H */
diff --git a/drivers/bluetooth/btusb_intel.c b/drivers/bluetooth/btusb_intel.c
new file mode 100644
index 0000000..51c019d
--- /dev/null
+++ b/drivers/bluetooth/btusb_intel.c
@@ -0,0 +1,81 @@
+/*
+ *
+ * Bluetooth USB Driver - Intel device initialization
+ *
+ * Copyright (C) 2012 Intel Corporation
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include "btusb.h"
+
+/* patch state */
+enum intel_patch_state {
+ INTEL_PATCH_PRE,
+ INTEL_PATCH_VER,
+ INTEL_PATCH_PREP_PATCH,
+ INTEL_PATCH_PATCHING,
+ INTEL_PATCH_POST,
+ INTEL_PATCH_COMPLETED,
+ INTEL_PATCH_ERROR
+};
+
+struct intel_patch_data {
+ struct hci_dev *hdev;
+
+ int state;
+};
+
+int btusb_intel_init(struct hci_dev *hdev)
+{
+ struct intel_patch_data *data;
+
+ BT_INFO("Intel BT USB: device initialization - patching device");
+
+ /* initialize the data structure */
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ BT_ERR("failed to allocate the memory for patch data");
+ return -ENOMEM;
+ }
+ hdev->vsdev_init_data = data;
+
+ data->hdev = hdev;
+ data->state = INTEL_PATCH_PRE;
+
+ kfree(data);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(btusb_intel_init);
+
+void btusb_intel_event(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct intel_patch_data *data = hdev->vsdev_init_data;
+
+ BT_DBG("Intel BT USB: HCI event handler state=%d", data->state);
+
+ del_timer(&hdev->cmd_timer);
+ atomic_set(&hdev->cmd_cnt, 1);
+ kfree_skb(skb);
+ return;
+}
+EXPORT_SYMBOL_GPL(btusb_intel_event);
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 6a3337e..cde0ddd 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -275,6 +275,12 @@ struct hci_dev {
int (*send)(struct sk_buff *skb);
void (*notify)(struct hci_dev *hdev, unsigned int evt);
int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
+
+ int vsdev_init_completed;
+ void *vsdev_init_data;
+
+ int (*vsdev_init)(struct hci_dev *hdev);
+ void (*vsdev_event)(struct hci_dev *hdev, struct sk_buff *skb);
};
struct hci_conn {
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e407051..4b23812 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -685,6 +685,17 @@ int hci_dev_open(__u16 dev)
set_bit(HCI_INIT, &hdev->flags);
hdev->init_last_cmd = 0;
+ if (hdev->vsdev_init && !hdev->vsdev_init_completed) {
+ ret = hdev->vsdev_init(hdev);
+ BT_DBG("vsdev_init completed: %d", ret);
+ /* set this flag so vsdev_init() execute only once */
+ hdev->vsdev_init_completed = 1;
+ /* make sure to use generic event handler */
+ hdev->vsdev_event = NULL;
+ if (ret < 0)
+ goto done;
+ }
+
ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
if (lmp_host_le_capable(hdev))
@@ -2119,6 +2130,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
return 0;
}
+EXPORT_SYMBOL(hci_send_cmd);
/* Get data from the previously sent command */
void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
@@ -2800,7 +2812,11 @@ static void hci_rx_work(struct work_struct *work)
switch (bt_cb(skb)->pkt_type) {
case HCI_EVENT_PKT:
BT_DBG("%s Event packet", hdev->name);
+ /* send packet to device init event handler */
+ if (hdev->vsdev_init_completed || !hdev->vsdev_event)
hci_event_packet(hdev, skb);
+ else
+ hdev->vsdev_event(hdev, skb);
break;
case HCI_ACLDATA_PKT:
--
1.7.9.5
^ permalink raw reply related
* [RFC 2/3] Bluetooth: Implement Intel specific device initialization
From: Tedd Ho-Jeong An @ 2012-09-10 22:35 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, albert.o.ho
From: Tedd Ho-Jeong An <tedd.an@intel.com>
This patch implements the Intel specific device initialization:
- Enable the device configuration mode
- Read the FW version of the device
- Open the patch file, if exists.
- Send the patch data via HCI command
- Once done, disable the device configuation mode
Signed-off-by: Tedd Ho-Jeong An <tedd.an@intel.com>
---
drivers/bluetooth/btusb_intel.c | 322 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 321 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btusb_intel.c b/drivers/bluetooth/btusb_intel.c
index 51c019d..d45ddb9 100644
--- a/drivers/bluetooth/btusb_intel.c
+++ b/drivers/bluetooth/btusb_intel.c
@@ -21,12 +21,38 @@
*
*/
#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
#include <linux/errno.h>
+#include <linux/timer.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include "btusb.h"
+/* Intel specific HCI cmd opcodes */
+#define INTEL_HCI_MFG_MODE 0xfc11
+#define INTEL_HCI_GET_VER 0xfc05
+
+/* Intel specific HCI cmd parameter for patch reset */
+#define INTEL_HCI_PATCH_SKIP 0x00
+#define INTEL_HCI_PATCH_DISABLE 0x01
+#define INTEL_HCI_PATCH_ENABLE 0x02
+
+/* Intel specific HCI event status - success */
+#define INTEL_EV_STATUS_SUCCESS 0x00
+
+/* Intel specific patch file location and file extension */
+#define INTEL_PATCH_DIR "intel/"
+#define INTEL_PATCH_EXT ".bseq"
+
+/* Patch entry type flag */
+#define INTEL_PATCH_TYPE_CMD 0x01
+#define INTEL_PATCH_TYPE_EVT 0x02
+
+/* Maximum length of one patch entry */
+#define INTEL_PATCH_MAX_LEN 260
+
/* patch state */
enum intel_patch_state {
INTEL_PATCH_PRE,
@@ -42,11 +68,165 @@ struct intel_patch_data {
struct hci_dev *hdev;
int state;
+ u8 patch_reset;
+
+ struct completion wait_patch_completion;
+
+ char device_ver[32];
+ const struct firmware *fw;
+ const u8 *patch_curr;
+ unsigned int patch_read;
};
+static int intel_send_mfg_cmd(struct hci_dev *hdev, u8 mode, u8 reset)
+{
+ u8 param[2];
+
+ param[0] = mode;
+ param[1] = reset;
+
+ BT_DBG("mfg mode: %02x reset: %02x", mode, reset);
+
+ return hci_send_cmd(hdev, INTEL_HCI_MFG_MODE, 2, param);
+}
+
+static int intel_send_patch_cmd(struct intel_patch_data *data)
+{
+ const u8 *ptr;
+ u8 param[INTEL_PATCH_MAX_LEN];
+ u16 opcode;
+ struct hci_command_hdr *hdr;
+
+ ptr = data->patch_curr;
+ if (*ptr != INTEL_PATCH_TYPE_CMD) {
+ BT_ERR("invalid patch cmd sequence: %02x", *ptr);
+ return -EILSEQ;
+ }
+ ptr++;
+
+ hdr = (void *)ptr;
+ opcode = le16_to_cpu(hdr->opcode);
+
+ ptr += sizeof(*hdr);
+
+ /* update the data before sending the command */
+ data->patch_curr = ptr + hdr->plen;
+ data->patch_read += hdr->plen + 4;
+
+ memcpy(param, ptr, hdr->plen);
+
+ if (hci_send_cmd(data->hdev, opcode, hdr->plen, param) < 0) {
+ BT_ERR("failed to send patch cmd: %04x", opcode);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int intel_verify_cc_evt(struct sk_buff *skb, u16 opcode)
+{
+ u8 status;
+ u16 opc;
+ struct hci_ev_cmd_complete *cc;
+ struct hci_event_hdr *hdr;
+
+ hdr = (void *)skb->data;
+ if (hdr->evt != HCI_EV_CMD_COMPLETE) {
+ BT_ERR("invalid event code: %02x", hdr->evt);
+ return -1;
+ }
+ skb_pull(skb, sizeof(*hdr));
+
+ cc = (void *)skb->data;
+ opc = le16_to_cpu(cc->opcode);
+ if (opc != opcode) {
+ BT_ERR("invalid opcode: %04x", opc);
+ return -1;
+ }
+ skb_pull(skb, sizeof(*cc));
+
+ status = *((u8 *) skb->data);
+ if (status != INTEL_EV_STATUS_SUCCESS) {
+ BT_ERR("event status failed: %02x", status);
+ return -1;
+ }
+ skb_pull(skb, 1);
+
+ return 0;
+}
+
+static int intel_verify_ver_cc_evt(struct sk_buff *skb,
+ struct intel_patch_data *data)
+{
+ int i;
+ if (intel_verify_cc_evt(skb, INTEL_HCI_GET_VER) < 0)
+ return -1;
+
+ for (i = 0; i < skb->len; i++)
+ sprintf(&data->device_ver[i*2], "%02x", skb->data[i]);
+
+ return 0;
+}
+
+static int intel_verify_patch_evt(struct sk_buff *skb,
+ struct intel_patch_data *data)
+{
+ const u8 *ptr;
+ struct hci_event_hdr *s_hdr;
+ struct hci_event_hdr *p_hdr;
+
+ ptr = data->patch_curr;
+ if (INTEL_PATCH_TYPE_EVT != *ptr) {
+ BT_ERR("invalid patch evt sequence: %02x", *ptr);
+ return -EILSEQ;
+ }
+ ptr++;
+
+ p_hdr = (void *)ptr;
+ s_hdr = (void *)skb->data;
+
+ if (p_hdr->evt != s_hdr->evt || p_hdr->plen != s_hdr->plen) {
+ BT_ERR("mismatch evt hdr: %02x %02x", s_hdr->evt, s_hdr->plen);
+ return -1;
+ }
+
+ ptr += sizeof(*p_hdr);
+ skb_pull(skb, sizeof(*s_hdr));
+
+ data->patch_curr = ptr + p_hdr->plen;
+ data->patch_read += p_hdr->plen + 3;
+
+ if (memcmp(ptr, skb->data, s_hdr->plen)) {
+ BT_ERR("mismatch evt data");
+ }
+
+ return 0;
+}
+
+static int intel_prepare_patch_file(struct intel_patch_data *data)
+{
+ char file[120];
+
+ snprintf(file, 120, "%s%s%s", INTEL_PATCH_DIR, data->device_ver,
+ INTEL_PATCH_EXT);
+ BT_DBG("patch file: %s", file);
+
+ if (request_firmware(&data->fw, file, &data->hdev->dev) < 0) {
+ BT_ERR("failed to open patch file: %s", file);
+ return -1;
+ }
+
+ data->patch_read = 0;
+ data->patch_curr = data->fw->data;
+
+ return 0;
+}
+
int btusb_intel_init(struct hci_dev *hdev)
{
+ int ret;
struct intel_patch_data *data;
+ int cont = 1;
BT_INFO("Intel BT USB: device initialization - patching device");
@@ -61,9 +241,93 @@ int btusb_intel_init(struct hci_dev *hdev)
data->hdev = hdev;
data->state = INTEL_PATCH_PRE;
+ init_completion(&data->wait_patch_completion);
+
+ while (cont) {
+ BT_DBG("patch state: %d", data->state);
+ switch (data->state) {
+ case INTEL_PATCH_PRE:
+ /* send cmd to enable the device configuration mode */
+ ret = intel_send_mfg_cmd(hdev, 0x01, 0x00);
+ if (ret < 0) {
+ BT_ERR("failed to send cmd: enter mfg %d", ret);
+ goto exit_error;
+ }
+ break;
+
+ case INTEL_PATCH_VER:
+ /* send cmd to get the device's version */
+ ret = hci_send_cmd(hdev, INTEL_HCI_GET_VER, 0, NULL);
+ if (ret < 0) {
+ BT_ERR("failed to send cmd: get ver %d", ret);
+ goto exit_error;
+ }
+ break;
+
+ case INTEL_PATCH_PREP_PATCH:
+ /* open the patch file if it is available */
+ ret = intel_prepare_patch_file(data);
+ if (ret < 0) {
+ BT_ERR("failed to prepare patch file %d", ret);
+ data->state = INTEL_PATCH_POST;
+ data->patch_reset = INTEL_HCI_PATCH_SKIP;
+ } else {
+ BT_DBG("patch data is setup");
+ data->state = INTEL_PATCH_PATCHING;
+ }
+ /* this is the only state that doesn't expect any evt */
+ goto skip_wait;
+
+ case INTEL_PATCH_PATCHING:
+ /* send patch entry in patch data. one at a time */
+ ret = intel_send_patch_cmd(data);
+ if (ret < 0) {
+ BT_ERR("failed to send cmd: patch cmd %d", ret);
+ goto exit_error;
+ }
+ break;
+
+ case INTEL_PATCH_POST:
+ /* exit the device configuration mode */
+ ret = intel_send_mfg_cmd(hdev, 0x00, data->patch_reset);
+ if (ret < 0) {
+ BT_ERR("failed to send cmd: exit mfg: %d", ret);
+ goto exit_error;
+ }
+ break;
+
+ default:
+ BT_ERR("unknown patch state: %d", data->state);
+ ret = -EILSEQ;
+ goto exit_error;
+ }
+
+ /* waiting for event */
+ ret = wait_for_completion_interruptible(
+ &data->wait_patch_completion);
+ if (ret < 0) {
+ BT_ERR("patch completion error: %d", ret);
+ goto exit_error;
+ }
+
+skip_wait:
+ if (data->state == INTEL_PATCH_ERROR) {
+ BT_ERR("patch error");
+ ret = -EILSEQ;
+ goto exit_error;
+ }
+
+ if (data->state == INTEL_PATCH_COMPLETED) {
+ BT_INFO("patch completed");
+ cont = 0;
+ }
+ }
+
+exit_error:
+ release_firmware(data->fw);
kfree(data);
- return 0;
+ return ret;
}
EXPORT_SYMBOL_GPL(btusb_intel_init);
@@ -73,9 +337,65 @@ void btusb_intel_event(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("Intel BT USB: HCI event handler state=%d", data->state);
+ switch (data->state) {
+ case INTEL_PATCH_PRE:
+ if (intel_verify_cc_evt(skb, INTEL_HCI_MFG_MODE) < 0) {
+ BT_ERR("cmd failed: enter mfg mode");
+ data->state = INTEL_PATCH_ERROR;
+ } else {
+ BT_DBG("cmd success: enter mfg mode");
+ data->state = INTEL_PATCH_VER;
+ }
+ break;
+
+ case INTEL_PATCH_VER:
+ if (intel_verify_ver_cc_evt(skb, data) < 0) {
+ BT_ERR("cmd failed: get version");
+ data->patch_reset = INTEL_HCI_PATCH_SKIP;
+ data->state = INTEL_PATCH_POST;
+ } else {
+ BT_DBG("cmd success: get version");
+ data->state = INTEL_PATCH_PREP_PATCH;
+ }
+ break;
+
+ case INTEL_PATCH_PATCHING:
+ if (intel_verify_patch_evt(skb, data) < 0) {
+ BT_ERR("cmd failed: patch");
+ data->patch_reset = INTEL_HCI_PATCH_DISABLE;
+ data->state = INTEL_PATCH_POST;
+ } else {
+ BT_DBG("cmd success: patch");
+ if (data->patch_read == data->fw->size) {
+ BT_DBG("no more patch to send");
+ data->patch_reset = INTEL_HCI_PATCH_ENABLE;
+ data->state = INTEL_PATCH_POST;
+ } else {
+ BT_DBG("more patch to send");
+ }
+ }
+ break;
+
+ case INTEL_PATCH_POST:
+ if (intel_verify_cc_evt(skb, INTEL_HCI_MFG_MODE) < 0) {
+ BT_ERR("cmd failed: exit mfg mode");
+ data->state = INTEL_PATCH_ERROR;
+ } else {
+ BT_DBG("cmd success: exit mfg mode");
+ data->state = INTEL_PATCH_COMPLETED;
+ }
+ break;
+
+ default:
+ BT_ERR("unknown patch state: %d", data->state);
+ data->state = INTEL_PATCH_ERROR;
+ break;
+ }
+
del_timer(&hdev->cmd_timer);
atomic_set(&hdev->cmd_cnt, 1);
kfree_skb(skb);
+ complete(&data->wait_patch_completion);
return;
}
EXPORT_SYMBOL_GPL(btusb_intel_event);
--
1.7.9.5
^ permalink raw reply related
* [RFC 3/3] Bluetooth: Add timeout for Intel specific device initialization
From: Tedd Ho-Jeong An @ 2012-09-10 22:35 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, albert.o.ho
From: Tedd Ho-Jeong An <tedd.an@intel.com>
This patch adds the tiemout for Intel specific device initialization.
Signed-off-by: Tedd Ho-Jeong An <tedd.an@intel.com>
---
drivers/bluetooth/btusb_intel.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/drivers/bluetooth/btusb_intel.c b/drivers/bluetooth/btusb_intel.c
index d45ddb9..3657203 100644
--- a/drivers/bluetooth/btusb_intel.c
+++ b/drivers/bluetooth/btusb_intel.c
@@ -30,6 +30,9 @@
#include "btusb.h"
+/* patch timeout - 10 seconds */
+#define INTEL_PATCH_TIMEOUT msecs_to_jiffies(10000)
+
/* Intel specific HCI cmd opcodes */
#define INTEL_HCI_MFG_MODE 0xfc11
#define INTEL_HCI_GET_VER 0xfc05
@@ -71,6 +74,7 @@ struct intel_patch_data {
u8 patch_reset;
struct completion wait_patch_completion;
+ struct timer_list patch_timeout;
char device_ver[32];
const struct firmware *fw;
@@ -222,6 +226,16 @@ static int intel_prepare_patch_file(struct intel_patch_data *data)
return 0;
}
+static void intel_patch_timeout(unsigned long arg)
+{
+ struct intel_patch_data *data = (void *)arg;
+
+ BT_ERR("patch timer expired");
+ data->state = INTEL_PATCH_ERROR;
+
+ complete(&data->wait_patch_completion);
+}
+
int btusb_intel_init(struct hci_dev *hdev)
{
int ret;
@@ -243,6 +257,10 @@ int btusb_intel_init(struct hci_dev *hdev)
init_completion(&data->wait_patch_completion);
+ setup_timer(&data->patch_timeout, intel_patch_timeout,
+ (unsigned long) data);
+ mod_timer(&data->patch_timeout, jiffies + INTEL_PATCH_TIMEOUT);
+
while (cont) {
BT_DBG("patch state: %d", data->state);
switch (data->state) {
@@ -324,6 +342,7 @@ skip_wait:
}
exit_error:
+ del_timer_sync(&data->patch_timeout);
release_firmware(data->fw);
kfree(data);
--
1.7.9.5
^ permalink raw reply related
* Re: Dropping connection (bit off-topic)
From: John Tobias @ 2012-09-10 23:34 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <CACUGKYONE6a2PWtOEY4Kgg9TQkX3pCwhW9UJLk5KGVtpL5eVaw@mail.gmail.com>
Just to follow up, I used hcidump and found out an interesting info:
bdaddr 5C:35:3C:72:B2:AF type 1
> HCI Event: Command Status (0x0f) plen 4
LE Create Connection (0x08|0x000d) status 0x00 ncmd 1
> HCI Event: LE Meta Event (0x3e) plen 19
LE Connection Complete
status 0x00 handle 77, role master
bdaddr 5C:35:3C:72:B2:AF (Random)
> ACL data: handle 77 flags 0x02 dlen 11
ATT: Read By Type req (0x08)
start 0x0001, end 0xffff
type-uuid 0x2a00
> HCI Event: Disconn Complete (0x05) plen 4
status 0x00 handle 77 reason 0x13
Reason: Remote User Terminated Connection
The iPhone was requesting for "ATT: Read By Type req (0x08)" and the
gatttool seems not reponding. So, after 30 secs the iPhone dropped the
connection.
Any idea how the gatttool could respond to the said request?.
Regards,
john
On Mon, Sep 10, 2012 at 2:35 PM, John Tobias <john.tobias.ph@gmail.com> wrote:
> Hello Guys,
>
> I am using pandaboard with USB BLE dongle and an apps in iPhone that
> do the advertising. I was able to connect to the said device from my
> pandaboard using the following commands:
>
> gatttool -i hci1 -m 27 -I -b 74:xx:xx:xx:xx:xx
> connect
>
> But, I've noticed that after 30 secs, the iPhone dropped off the
> connection. I am just wondering if anyone here have tried playing with
> the iPhone using the ble connection?.
>
> Regards,
>
> John
^ permalink raw reply
* Re: [RFCv1 01/15] Bluetooth: Set Exended Flowspec flag for HS chan
From: Mat Martineau @ 2012-09-10 23:49 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1346766274-21612-2-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Andrei -
On Tue, 4 Sep 2012, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> For AMP we always assume EFS L2CAP option.
>
> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> ---
> include/net/bluetooth/l2cap.h | 2 ++
> net/bluetooth/l2cap_core.c | 7 ++++++-
> 2 files changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> index 161be83..3ec8679 100644
> --- a/include/net/bluetooth/l2cap.h
> +++ b/include/net/bluetooth/l2cap.h
> @@ -508,6 +508,8 @@ struct l2cap_chan {
> __u32 remote_acc_lat;
> __u32 remote_flush_to;
>
> + __u8 ctrl_id;
> +
How about "remote_amp_id" instead of ctrl_id? The channel move code
tracks local_amp_id. Why does the remote controller id need to be
tracked?
> struct delayed_work chan_timer;
> struct delayed_work retrans_timer;
> struct delayed_work monitor_timer;
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index de6f52c..aea2b50 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -5439,8 +5439,13 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
> void l2cap_chan_create_cfm(struct hci_conn *hcon, u8 remote_id)
> {
> struct amp_mgr *mgr = hcon->amp_mgr;
> + struct l2cap_chan *chan = mgr->bredr_chan;
>
> - l2cap_send_chan_create_req(mgr->bredr_chan, remote_id);
> + /* Set Extended Flow Spec for AMP */
> + set_bit(FLAG_EFS_ENABLE, &chan->flags);
> + chan->ctrl_id = remote_id;
> +
> + l2cap_send_chan_create_req(chan, remote_id);
> }
>
> int l2cap_disconn_ind(struct hci_conn *hcon)
> --
> 1.7.9.5
Regards,
--
Mat Martineau
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply
* Re: Dropping connection (bit off-topic)
From: Vinicius Costa Gomes @ 2012-09-10 23:58 UTC (permalink / raw)
To: John Tobias; +Cc: linux-bluetooth
In-Reply-To: <CACUGKYPwTxRS8JN78J-oPSwz0mhnKvxHg=ybm5vyiKivEpM03A@mail.gmail.com>
Hi John,
On 16:34 Mon 10 Sep, John Tobias wrote:
> Just to follow up, I used hcidump and found out an interesting info:
>
> bdaddr 5C:35:3C:72:B2:AF type 1
> > HCI Event: Command Status (0x0f) plen 4
> LE Create Connection (0x08|0x000d) status 0x00 ncmd 1
> > HCI Event: LE Meta Event (0x3e) plen 19
> LE Connection Complete
> status 0x00 handle 77, role master
> bdaddr 5C:35:3C:72:B2:AF (Random)
> > ACL data: handle 77 flags 0x02 dlen 11
> ATT: Read By Type req (0x08)
> start 0x0001, end 0xffff
> type-uuid 0x2a00
> > HCI Event: Disconn Complete (0x05) plen 4
> status 0x00 handle 77 reason 0x13
> Reason: Remote User Terminated Connection
>
>
> The iPhone was requesting for "ATT: Read By Type req (0x08)" and the
> gatttool seems not reponding. So, after 30 secs the iPhone dropped the
> connection.
>
> Any idea how the gatttool could respond to the said request?.
The problem is that gatttool still hasn't any support for sending
responses. bluetoothd has, if you enable GATT support, 'EnableGatt' in
'/etc/bluetooth/main.conf' (usual location).
But using 'bluetoothd' means that will need to use the D-Bus API, which
makes me wonder that having a simple GATT server inside gatttool makes
some sense, for some use cases.
>
> Regards,
>
> john
>
>
> On Mon, Sep 10, 2012 at 2:35 PM, John Tobias <john.tobias.ph@gmail.com> wrote:
> > Hello Guys,
> >
> > I am using pandaboard with USB BLE dongle and an apps in iPhone that
> > do the advertising. I was able to connect to the said device from my
> > pandaboard using the following commands:
> >
> > gatttool -i hci1 -m 27 -I -b 74:xx:xx:xx:xx:xx
> > connect
> >
> > But, I've noticed that after 30 secs, the iPhone dropped off the
> > connection. I am just wondering if anyone here have tried playing with
> > the iPhone using the ble connection?.
> >
> > Regards,
> >
> > John
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Cheers,
--
Vinicius
^ permalink raw reply
* Re: Dropping connection (bit off-topic)
From: John Tobias @ 2012-09-11 0:45 UTC (permalink / raw)
To: Vinicius Costa Gomes; +Cc: linux-bluetooth
In-Reply-To: <20120910235838.GA26986@samus>
thanks for the info.
Regards,
john
On Mon, Sep 10, 2012 at 4:58 PM, Vinicius Costa Gomes
<vinicius.gomes@openbossa.org> wrote:
> Hi John,
>
> On 16:34 Mon 10 Sep, John Tobias wrote:
>> Just to follow up, I used hcidump and found out an interesting info:
>>
>> bdaddr 5C:35:3C:72:B2:AF type 1
>> > HCI Event: Command Status (0x0f) plen 4
>> LE Create Connection (0x08|0x000d) status 0x00 ncmd 1
>> > HCI Event: LE Meta Event (0x3e) plen 19
>> LE Connection Complete
>> status 0x00 handle 77, role master
>> bdaddr 5C:35:3C:72:B2:AF (Random)
>> > ACL data: handle 77 flags 0x02 dlen 11
>> ATT: Read By Type req (0x08)
>> start 0x0001, end 0xffff
>> type-uuid 0x2a00
>> > HCI Event: Disconn Complete (0x05) plen 4
>> status 0x00 handle 77 reason 0x13
>> Reason: Remote User Terminated Connection
>>
>>
>> The iPhone was requesting for "ATT: Read By Type req (0x08)" and the
>> gatttool seems not reponding. So, after 30 secs the iPhone dropped the
>> connection.
>>
>> Any idea how the gatttool could respond to the said request?.
>
> The problem is that gatttool still hasn't any support for sending
> responses. bluetoothd has, if you enable GATT support, 'EnableGatt' in
> '/etc/bluetooth/main.conf' (usual location).
>
> But using 'bluetoothd' means that will need to use the D-Bus API, which
> makes me wonder that having a simple GATT server inside gatttool makes
> some sense, for some use cases.
>
>>
>> Regards,
>>
>> john
>>
>>
>> On Mon, Sep 10, 2012 at 2:35 PM, John Tobias <john.tobias.ph@gmail.com> wrote:
>> > Hello Guys,
>> >
>> > I am using pandaboard with USB BLE dongle and an apps in iPhone that
>> > do the advertising. I was able to connect to the said device from my
>> > pandaboard using the following commands:
>> >
>> > gatttool -i hci1 -m 27 -I -b 74:xx:xx:xx:xx:xx
>> > connect
>> >
>> > But, I've noticed that after 30 secs, the iPhone dropped off the
>> > connection. I am just wondering if anyone here have tried playing with
>> > the iPhone using the ble connection?.
>> >
>> > Regards,
>> >
>> > John
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
> Cheers,
> --
> Vinicius
^ permalink raw reply
* [PATCH] avctp: Fix reply for message with invalid PID
From: Par-Gunnar Hjalmdahl @ 2012-09-11 6:16 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anurag Gupta, Par-Gunnar Hjalmdahl
Reply for control message with invalid (not registered for reception
of messages) PID should not have message information field present.
This was affecting AVCTP qualification test case TP/NFR/BI-01-C.
---
audio/avctp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/audio/avctp.c b/audio/avctp.c
index 03f3e7f..4e0e8dc 100644
--- a/audio/avctp.c
+++ b/audio/avctp.c
@@ -500,7 +500,7 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
if (avctp->pid != htons(AV_REMOTE_SVCLASS_ID)) {
avctp->ipid = 1;
- avc->code = AVC_CTYPE_REJECTED;
+ packet_size = AVCTP_HEADER_LENGTH;
goto done;
}
--
1.7.11.3
^ permalink raw reply related
* [PATCH 00/10] Implement Generic battery and LE Battery client
From: chen.ganir @ 2012-09-11 7:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: chen.ganir
From: Chen Ganir <chen.ganir@ti.com>
This patch set replaces previous patch sets which implemented the LE battery
GATT Client. This patch set implements a generic device battery D-Bus interface
that can be used to get remote device battery status using D-Bus. In addition,
This patch set also implements the GATT Battery client, which uses the generic
device battery to expose LE device battery status.
see doc/battery-api.txt and doc/device-api.txt for more information.
Chen Ganir (10):
battery: Add generic device battery documentation
battery: Implement Generic device battery
battery: Add GATT Battery Client Service skeleton
battery: Add client connection logic
battery: Discover Characteristic Descriptors
battery: Get Battery ID
battery: Add Battery to device
battery: Read Battery level characteristic
battery: Add support for notifications
battery: Support persistent battery level
Makefile.am | 9 +-
doc/battery-api.txt | 33 +++
doc/device-api.txt | 5 +
lib/uuid.h | 3 +
profiles/battery/battery.c | 590 ++++++++++++++++++++++++++++++++++++++++++++
profiles/battery/battery.h | 24 ++
profiles/battery/main.c | 52 ++++
profiles/battery/manager.c | 61 +++++
profiles/battery/manager.h | 24 ++
src/device.c | 184 ++++++++++++++
src/device.h | 15 ++
test/test-device | 13 +
12 files changed, 1011 insertions(+), 2 deletions(-)
create mode 100644 doc/battery-api.txt
create mode 100644 profiles/battery/battery.c
create mode 100644 profiles/battery/battery.h
create mode 100644 profiles/battery/main.c
create mode 100644 profiles/battery/manager.c
create mode 100644 profiles/battery/manager.h
--
1.7.9.5
^ permalink raw reply
* [PATCH 01/10] battery: Add generic device battery documentation
From: chen.ganir @ 2012-09-11 7:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: chen.ganir
In-Reply-To: <1347349100-24228-1-git-send-email-chen.ganir@ti.com>
From: Chen Ganir <chen.ganir@ti.com>
Add documentation for the generic battery D-Bus interface.
---
doc/battery-api.txt | 33 +++++++++++++++++++++++++++++++++
doc/device-api.txt | 5 +++++
2 files changed, 38 insertions(+)
create mode 100644 doc/battery-api.txt
diff --git a/doc/battery-api.txt b/doc/battery-api.txt
new file mode 100644
index 0000000..d5ef5ed
--- /dev/null
+++ b/doc/battery-api.txt
@@ -0,0 +1,33 @@
+BlueZ D-Bus Battery API description
+****************************************
+
+ Texas Instruments, Inc. <chen.ganir@ti.com>
+
+Device Battery hierarchy
+=====================================
+
+Service org.bluez
+Interface org.bluez.Battery
+Object path [variable prefix]/{hci0,..}/dev_XX_XX_XX_XX_XX_XX/BATTYYYY
+YYYY is numeric value between 0 and 9999.
+
+Methods dict GetProperties()
+
+ Returns all properties for the interface. See the
+ Properties section for the available properties.
+
+ void Refresh()
+
+ Refresh the batterty level. If the battery level changed, the
+ PropertyChanged signal will be sent with the new value.
+
+Signals PropertyChanged(string name, variant value)
+
+ This signal indicates a changed value of the given
+ property.
+
+Properties uint16 Level [readonly]
+
+ Battery level (0-100).
+
+
diff --git a/doc/device-api.txt b/doc/device-api.txt
index 1f0dc96..c98d539 100644
--- a/doc/device-api.txt
+++ b/doc/device-api.txt
@@ -179,3 +179,8 @@ Properties string Address [readonly]
Note that this property can exhibit false-positives
in the case of Bluetooth 2.1 (or newer) devices that
have disabled Extended Inquiry Response support.
+
+ array{object} Batteries [readonly]
+
+ List of device battery object paths that represents the available
+ batteries on the remote device.
--
1.7.9.5
^ permalink raw reply related
* [PATCH 02/10] battery: Implement Generic device battery
From: chen.ganir @ 2012-09-11 7:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: chen.ganir
In-Reply-To: <1347349100-24228-1-git-send-email-chen.ganir@ti.com>
From: Chen Ganir <chen.ganir@ti.com>
Add implementation for the generic battery in bluetooth device.
This patch adds new D-Bus interface for adding/removing/changing
peer device battery status, allowing management of remote device
batteries.
---
src/device.c | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/device.h | 15 +++++
test/test-device | 13 ++++
3 files changed, 212 insertions(+)
diff --git a/src/device.c b/src/device.c
index 02ef35e..ce4d467 100644
--- a/src/device.c
+++ b/src/device.c
@@ -166,6 +166,7 @@ struct btd_device {
gboolean authorizing;
gint ref;
+ GSList *batteries;
GIOChannel *att_io;
guint cleanup_id;
@@ -180,6 +181,26 @@ static uint16_t uuid_list[] = {
0
};
+struct device_battery {
+ DBusConnection *conn;
+ uint16_t level;
+ char *path;
+ struct btd_device *device;
+ RefreshBattFunc refresh_func;
+};
+
+static void battery_free(gpointer user_data)
+{
+ struct device_battery *b = user_data;
+
+ g_dbus_unregister_interface(b->conn, b->path, BATTERY_INTERFACE);
+ dbus_connection_unref(b->conn);
+ btd_device_unref(b->device);
+ g_free(b->path);
+ g_free(b);
+
+}
+
static void browse_request_free(struct browse_req *req)
{
if (req->listener_id)
@@ -259,6 +280,7 @@ static void device_free(gpointer user_data)
g_slist_free_full(device->primaries, g_free);
g_slist_free_full(device->attios, g_free);
g_slist_free_full(device->attios_offline, g_free);
+ g_slist_free_full(device->batteries, battery_free);
attio_cleanup(device);
@@ -433,6 +455,15 @@ static DBusMessage *get_properties(DBusConnection *conn,
ptr = adapter_get_path(adapter);
dict_append_entry(&dict, "Adapter", DBUS_TYPE_OBJECT_PATH, &ptr);
+ /* Batteries */
+ str = g_new0(char *, g_slist_length(device->batteries) + 1);
+ for (i = 0, l = device->batteries; l; l = l->next, i++) {
+ struct device_battery *b = l->data;
+ str[i] = b->path;
+ }
+ dict_append_array(&dict, "Batteries", DBUS_TYPE_OBJECT_PATH, &str, i);
+ g_free(str);
+
dbus_message_iter_close_container(&iter, &dict);
return reply;
@@ -3263,3 +3294,156 @@ void btd_profile_disconnected(struct btd_profile *profile,
{
device->conns = g_slist_remove(device->conns, profile);
}
+
+static void batteries_changed(struct btd_device *device)
+{
+ DBusConnection *conn = get_dbus_connection();
+ char **batteries;
+ GSList *l;
+ int i;
+
+ batteries = g_new0(char *, g_slist_length(device->batteries) + 1);
+ for (i = 0, l = device->batteries; l; l = l->next, i++) {
+ struct device_battery *batt = l->data;
+ batteries[i] = batt->path;
+ }
+
+ emit_array_property_changed(conn, device->path, DEVICE_INTERFACE,
+ "Batteries", DBUS_TYPE_OBJECT_PATH,
+ &batteries, i);
+
+ g_free(batteries);
+}
+
+static DBusMessage *refresh_batt_level(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct device_battery *b = data;
+
+ if (!b->refresh_func)
+ return btd_error_not_supported(msg);
+
+ b->refresh_func(b);
+
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *get_batt_properties(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct device_battery *b = data;
+ DBusMessageIter iter;
+ DBusMessageIter dict;
+ DBusMessage *reply;
+
+ reply = dbus_message_new_method_return(msg);
+ if (reply == NULL)
+ return NULL;
+
+ dbus_message_iter_init_append(reply, &iter);
+
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+ dict_append_entry(&dict, "Level", DBUS_TYPE_UINT16, &b->level);
+
+ dbus_message_iter_close_container(&iter, &dict);
+
+ return reply;
+}
+
+static GDBusMethodTable battery_methods[] = {
+ { GDBUS_METHOD("GetProperties",
+ NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
+ get_batt_properties) },
+ { GDBUS_METHOD("Refresh",
+ NULL, NULL,
+ refresh_batt_level) },
+ { }
+};
+
+static GDBusSignalTable battery_signals[] = {
+ { GDBUS_SIGNAL("PropertyChanged",
+ GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
+ { }
+};
+
+struct device_battery *btd_device_add_battery(struct btd_device *device)
+{
+ struct device_battery *batt;
+ DBusConnection *conn = get_dbus_connection();
+
+ batt = g_new0(struct device_battery, 1);
+ batt->path = g_strdup_printf("%s/BATT%04X", device->path,
+ g_slist_length(device->batteries));
+ batt->conn = dbus_connection_ref(conn);
+
+ if (!g_dbus_register_interface(batt->conn, batt->path,
+ BATTERY_INTERFACE, battery_methods, battery_signals,
+ NULL, batt, NULL)) {
+ error("D-Bus register interface %s failed", BATTERY_INTERFACE);
+ dbus_connection_unref(batt->conn);
+ g_free(batt->path);
+ g_free(batt);
+ return NULL;
+ }
+
+ batt->device = btd_device_ref(device);
+ device->batteries = g_slist_append(device->batteries, batt);
+ batteries_changed(device);
+
+ return batt;
+}
+
+void btd_device_remove_battery(struct device_battery *batt)
+{
+ struct btd_device *dev = batt->device;
+
+ dev->batteries = g_slist_remove(dev->batteries, batt);
+
+ battery_free(batt);
+
+ batteries_changed(dev);
+}
+
+gboolean btd_device_set_battery_opt(struct device_battery *batt,
+ BatteryOption opt1, ...)
+{
+ va_list args;
+ BatteryOption opt = opt1;
+ int level;
+
+ if (!batt)
+ return FALSE;
+
+ va_start(args, opt1);
+
+ while (opt != BATTERY_OPT_INVALID) {
+ switch (opt) {
+ case BATTERY_OPT_LEVEL:
+ level = va_arg(args, int);
+ if (level != batt->level) {
+ batt->level = level;
+ emit_property_changed(batt->conn, batt->path,
+ BATTERY_INTERFACE, "Level",
+ DBUS_TYPE_UINT16, &level);
+ }
+ break;
+ case BATTERY_OPT_REFRESH_FUNC:
+ batt->refresh_func = va_arg(args, RefreshBattFunc);
+ break;
+ default:
+ error("Unknown option %d", opt);
+ return FALSE;
+ }
+
+ opt = va_arg(args, int);
+ }
+
+ va_end(args);
+
+ return TRUE;
+
+}
diff --git a/src/device.h b/src/device.h
index f1d95c6..66eb5e8 100644
--- a/src/device.h
+++ b/src/device.h
@@ -23,8 +23,10 @@
*/
#define DEVICE_INTERFACE "org.bluez.Device"
+#define BATTERY_INTERFACE "org.bluez.Battery"
struct btd_device;
+struct device_battery;
typedef enum {
AUTH_TYPE_PINCODE,
@@ -54,6 +56,14 @@ struct btd_profile {
void (*adapter_remove) (struct btd_adapter *adapter);
};
+typedef void (*RefreshBattFunc) (struct device_battery *batt);
+
+typedef enum {
+ BATTERY_OPT_INVALID = 0,
+ BATTERY_OPT_LEVEL,
+ BATTERY_OPT_REFRESH_FUNC,
+} BatteryOption;
+
void btd_profile_foreach(void (*func)(struct btd_profile *p, void *data),
void *data);
@@ -158,3 +168,8 @@ int device_unblock(DBusConnection *conn, struct btd_device *device,
void device_set_pnpid(struct btd_device *device, uint8_t vendor_id_src,
uint16_t vendor_id, uint16_t product_id,
uint16_t product_ver);
+
+struct device_battery *btd_device_add_battery(struct btd_device *device);
+void btd_device_remove_battery(struct device_battery *batt);
+gboolean btd_device_set_battery_opt(struct device_battery *batt,
+ BatteryOption opt1, ...);
diff --git a/test/test-device b/test/test-device
index 63a96d3..7edb7b8 100755
--- a/test/test-device
+++ b/test/test-device
@@ -37,6 +37,7 @@ if (len(args) < 1):
print("")
print(" list")
print(" services <address>")
+ print(" batteries <address>")
print(" create <address>")
print(" remove <address|path>")
print(" disconnect <address>")
@@ -205,5 +206,17 @@ if (args[0] == "services"):
print(path)
sys.exit(0)
+if (args[0] == "batteries"):
+ if (len(args) < 2):
+ print("Need address parameter")
+ else:
+ path = adapter.FindDevice(args[1])
+ device = dbus.Interface(bus.get_object("org.bluez", path),
+ "org.bluez.Device")
+ properties = device.GetProperties()
+ for path in properties["Batteries"]:
+ print(path)
+ sys.exit(0)
+
print("Unknown command")
sys.exit(1)
--
1.7.9.5
^ permalink raw reply related
* [PATCH 03/10] battery: Add GATT Battery Client Service skeleton
From: chen.ganir @ 2012-09-11 7:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: chen.ganir
In-Reply-To: <1347349100-24228-1-git-send-email-chen.ganir@ti.com>
From: Chen Ganir <chen.ganir@ti.com>
Add support for the Battery Service Gatt Client side. Implement
the basic skeleton.
---
Makefile.am | 9 ++++-
lib/uuid.h | 2 +
profiles/battery/battery.c | 89 ++++++++++++++++++++++++++++++++++++++++++++
profiles/battery/battery.h | 24 ++++++++++++
profiles/battery/main.c | 52 ++++++++++++++++++++++++++
profiles/battery/manager.c | 61 ++++++++++++++++++++++++++++++
profiles/battery/manager.h | 24 ++++++++++++
7 files changed, 259 insertions(+), 2 deletions(-)
create mode 100644 profiles/battery/battery.c
create mode 100644 profiles/battery/battery.h
create mode 100644 profiles/battery/main.c
create mode 100644 profiles/battery/manager.c
create mode 100644 profiles/battery/manager.h
diff --git a/Makefile.am b/Makefile.am
index 4977a05..af5d8a4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -212,7 +212,7 @@ endif
if GATTMODULES
builtin_modules += thermometer alert time gatt_example proximity deviceinfo \
- gatt
+ gatt battery
builtin_sources += profiles/thermometer/main.c \
profiles/thermometer/manager.h \
profiles/thermometer/manager.c \
@@ -241,7 +241,12 @@ builtin_sources += profiles/thermometer/main.c \
profiles/deviceinfo/deviceinfo.c \
profiles/gatt/main.c profiles/gatt/manager.h \
profiles/gatt/manager.c profiles/gatt/gas.h \
- profiles/gatt/gas.c
+ profiles/gatt/gas.c \
+ profiles/battery/main.c \
+ profiles/battery/manager.c \
+ profiles/battery/manager.h \
+ profiles/battery/battery.c \
+ profiles/battery/battery.h
endif
builtin_modules += formfactor
diff --git a/lib/uuid.h b/lib/uuid.h
index aa6efdf..58ad0b3 100644
--- a/lib/uuid.h
+++ b/lib/uuid.h
@@ -56,6 +56,8 @@ extern "C" {
#define PNPID_UUID "00002a50-0000-1000-8000-00805f9b34fb"
#define DEVICE_INFORMATION_UUID "0000180a-0000-1000-8000-00805f9b34fb"
+#define BATTERY_SERVICE_UUID "0000180f-0000-1000-8000-00805f9b34fb"
+
#define GATT_UUID "00001801-0000-1000-8000-00805f9b34fb"
#define IMMEDIATE_ALERT_UUID "00001802-0000-1000-8000-00805f9b34fb"
#define LINK_LOSS_UUID "00001803-0000-1000-8000-00805f9b34fb"
diff --git a/profiles/battery/battery.c b/profiles/battery/battery.c
new file mode 100644
index 0000000..7702e39
--- /dev/null
+++ b/profiles/battery/battery.c
@@ -0,0 +1,89 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * 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 <glib.h>
+#include <bluetooth/uuid.h>
+#include <stdbool.h>
+
+#include "adapter.h"
+#include "device.h"
+#include "att.h"
+#include "gattrib.h"
+#include "gatt.h"
+#include "battery.h"
+
+struct battery {
+ struct btd_device *dev; /* Device reference */
+};
+
+static GSList *servers;
+
+static gint cmp_device(gconstpointer a, gconstpointer b)
+{
+ const struct battery *batt = a;
+ const struct btd_device *dev = b;
+
+ if (dev == batt->dev)
+ return 0;
+
+ return -1;
+}
+
+static void battery_free(gpointer user_data)
+{
+ struct battery *batt = user_data;
+
+ btd_device_unref(batt->dev);
+ g_free(batt);
+}
+
+
+int battery_register(struct btd_device *device)
+{
+ struct battery *batt;
+
+ batt = g_new0(struct battery, 1);
+ batt->dev = btd_device_ref(device);
+
+ servers = g_slist_prepend(servers, batt);
+
+ return 0;
+}
+
+void battery_unregister(struct btd_device *device)
+{
+ struct battery *batt;
+ GSList *l;
+
+ l = g_slist_find_custom(servers, device, cmp_device);
+ if (l == NULL)
+ return;
+
+ batt = l->data;
+ servers = g_slist_remove(servers, batt);
+
+ battery_free(batt);
+}
diff --git a/profiles/battery/battery.h b/profiles/battery/battery.h
new file mode 100644
index 0000000..9933343
--- /dev/null
+++ b/profiles/battery/battery.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * 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
+ *
+ */
+
+int battery_register(struct btd_device *device);
+void battery_unregister(struct btd_device *device);
diff --git a/profiles/battery/main.c b/profiles/battery/main.c
new file mode 100644
index 0000000..d4a23c9
--- /dev/null
+++ b/profiles/battery/main.c
@@ -0,0 +1,52 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * 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 <stdint.h>
+#include <glib.h>
+#include <errno.h>
+
+#include "hcid.h"
+#include "plugin.h"
+#include "manager.h"
+#include "log.h"
+
+static int battery_init(void)
+{
+ if (!main_opts.gatt_enabled) {
+ error("GATT is disabled");
+ return -ENOTSUP;
+ }
+
+ return battery_manager_init();
+}
+
+static void battery_exit(void)
+{
+ battery_manager_exit();
+}
+
+BLUETOOTH_PLUGIN_DEFINE(battery, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
+ battery_init, battery_exit)
diff --git a/profiles/battery/manager.c b/profiles/battery/manager.c
new file mode 100644
index 0000000..72878b2
--- /dev/null
+++ b/profiles/battery/manager.c
@@ -0,0 +1,61 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * 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 <errno.h>
+#include <bluetooth/uuid.h>
+#include <stdbool.h>
+
+#include "adapter.h"
+#include "device.h"
+#include "att.h"
+#include "gattrib.h"
+#include "gatt.h"
+#include "battery.h"
+#include "manager.h"
+
+static int battery_driver_probe(struct btd_device *device, GSList *uuids)
+{
+ return battery_register(device);
+}
+
+static void battery_driver_remove(struct btd_device *device)
+{
+ battery_unregister(device);
+}
+
+static struct btd_profile battery_profile = {
+ .name = "battery",
+ .remote_uuids = BTD_UUIDS(BATTERY_SERVICE_UUID),
+ .device_probe = battery_driver_probe,
+ .device_remove = battery_driver_remove
+};
+
+int battery_manager_init(void)
+{
+ return btd_profile_register(&battery_profile);
+}
+
+void battery_manager_exit(void)
+{
+ btd_profile_unregister(&battery_profile);
+}
diff --git a/profiles/battery/manager.h b/profiles/battery/manager.h
new file mode 100644
index 0000000..b2c849f
--- /dev/null
+++ b/profiles/battery/manager.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * 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
+ *
+ */
+
+int battery_manager_init(void);
+void battery_manager_exit(void);
--
1.7.9.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox