* Dualshock4 - 'HIDP: Handshake: Unsupported request' after 'unplug virtual cable'.
From: simon @ 2014-01-17 5:09 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frank Praznik
[-- Attachment #1: Type: text/plain, Size: 1706 bytes --]
Hi all,
Frank and I have been working on a kernel driver for the Dualshock 4 and
we're having problems with the BT connection (USB is OK).
When powered on the DS4 will initiate a connection to the PC once it knows
it's Bdaddr (via pairing), but will power off shortly there after. This
seems to be related to incorrect (??) data sent from Bluez, or if no hid
connection is made within a short window.
On the two systems I have tried:
1) Debian with bluez 4.99, I can 'hidd --connect xxx' to hold the
connection. I get joystick data but can't send data to DS4 to drive
ff/leds. (I am told that 'hidd' is deprated)
2) Fedora LiveCD with bluez 5.13. Connection is immediately terminated by
the controller. HCI log attached.
It appears that the controller is insisting on a encrypted link ('noenc'
and 'noauth' make no difference) and does not like the 'unplug virtual
cable' which is sent (presumably as the link is being brought down to
re-start encrypted).
In the BT HID 1.1 spec (page 48) it says
--
If the HIDVirtualCable SDP attribute is set to TRUE, then a Virtual Cable
is considered to be established after both the HID Control and HID
Interrupt L2CAP channels have been opened.
--
However the Fedora system does not have a copy of the SDP records for the
controller, it never pulled them and I have never managed to make a
connection long enough to read them.
My theory is that the controller is rejecting the 'Unplug Virtual Cable'
command as it shouldn't have been established, but I'm not really sure.
I managed use my Debian system to read SDP records but that barfs on
what's sent.... files also attached.
Does anyone have any suggestions on what I should try next?
Thanks, Simon
[-- Attachment #2: hcidump_records.txt.gz --]
[-- Type: application/gzip, Size: 16136 bytes --]
[-- Attachment #3: records.txt --]
[-- Type: text/plain, Size: 673 bytes --]
Service Name: Wireless Controller
Service Description: Game Controller
Service Provider: Sony Computer Entertainment
Service RecHandle: 0x10001
Service Class ID List:
"Human Interface Device" (0x1124)
Protocol Descriptor List:
"L2CAP" (0x0100)
PSM: 17
"HIDP" (0x0011)
Language Base Attr List:
code_ISO639: 0x656e
encoding: 0x6a
base_offset: 0x100
Profile Descriptor List:
"Human Interface Device" (0x1124)
Version: 0x0100
Service RecHandle: 0x10002
Service Class ID List:
"PnP Information" (0x1200)
Protocol Descriptor List:
"L2CAP" (0x0100)
PSM: 1
"SDP" (0x0001)
Profile Descriptor List:
"PnP Information" (0x1200)
Version: 0x0103
[-- Attachment #4: records_raw.txt --]
[-- Type: text/plain, Size: 2851 bytes --]
Sequence
Attribute 0x0000 - ServiceRecordHandle
UINT32 0x00010001
Attribute 0x0001 - ServiceClassIDList
Sequence
UUID16 0x1124 - HumanInterfaceDeviceService (HID)
Attribute 0x0004 - ProtocolDescriptorList
Sequence
Sequence
UUID16 0x0100 - L2CAP
UINT16 0x0011
Sequence
UUID16 0x0011 - HIDP
Attribute 0x0006 - LanguageBaseAttributeIDList
Sequence
UINT16 0x656e
UINT16 0x006a
UINT16 0x0100
Attribute 0x0009 - BluetoothProfileDescriptorList
Sequence
Sequence
UUID16 0x1124 - HumanInterfaceDeviceService (HID)
UINT16 0x0100
Attribute 0x000d - AdditionalProtocolDescriptorLists
Sequence
Sequence
Sequence
UUID16 0x0100 - L2CAP
UINT16 0x0013
Sequence
UUID16 0x0011 - HIDP
Attribute 0x0100
String Wireless Controller\0
Attribute 0x0101
String Game Controller\0
Attribute 0x0102
String Sony Computer Entertainment\0
Attribute 0x0200
UINT16 0x0100
Attribute 0x0201
UINT16 0x0111
Attribute 0x0202
UINT8 0x08
Attribute 0x0203
UINT8 0x00
Attribute 0x0204
Bool False
Attribute 0x0205
Bool True
Attribute 0x0206
Sequence
Sequence
UINT8 0x22
Data 05 01 09 05 a1 01 85 01 09 30 09 31 09 32 09 35 15 00 26 ff 00 75 08 95 04 81 02 09 39 15 00 25 07 75 04 95 01 81 42 05 09 19 01 29 0e 15 00 25 01 75 01 95 0e 81 02 75 06 95 01 81 01 05 01 09 33 09 34 15 00 26 ff 00 75 08 95 02 81 02 06 04 ff 85 02 09 24 95 24 b1 02 85 a3 09 25 95 30 b1 02 85 05 09 26 95 28 b1 02 85 06 09 27 95 34 b1 02 85 07 09 28 95 30 b1 02 85 08 09 29 95 2f b1 02 06 03 ff 85 03 09 21 95 26 b1 02 85 04 09 22 95 2e b1 02 85 f0 09 47 95 3f b1 02 85 f1 09 48 95 3f b1 02 85 f2 09 49 95 0f b1 02 06 00 ff 85 11 09 20 15 00 26 ff 00 75 08 95 4d 81 02 09 21 91 02 85 12 09 22 95 8d 81 02 09 23 91 02 85 13 09 24 95 cd 81 02 09 25 91 02 85 14 09 26 96 0d 01 81 02 09 27 91 02 85 15 09 28 96 4d 01 81 02 09 29 91 02 85 16 09 2a 96 8d 01 81 02 09 2b 91 02 85 17 09 2c 96 cd 01 81 02 09 2d 91 02 85 18 09 2e 96 0d 02 81 02 09 2f 91 02 85 19 09 30 96 22 02 81 02 09 31 91 02 06 80 ff 85 82 09 22 95 3f b1 02 85 83 09 23 b1 02 85 84 09 24 b1 02 85 90 09 30 b1 02 85 91 09 31 b1 02 85 92 09 32 b1 02 85 93 09 33 b1 02 85 a0 09 40 b1 02 85 a4 09 44 b1 02 c0 00
Sequence
Attribute 0x0000 - ServiceRecordHandle
UINT32 0x00010002
Attribute 0x0001 - ServiceClassIDList
Sequence
UUID16 0x1200 - PnPInformation
Attribute 0x0004 - ProtocolDescriptorList
Sequence
Sequence
UUID16 0x0100 - L2CAP
UINT16 0x0001
Sequence
UUID16 0x0001 - SDP
Attribute 0x0009 - BluetoothProfileDescriptorList
Sequence
Sequence
UUID16 0x1200 - PnPInformation
UINT16 0x0103
Attribute 0x0200
UINT16 0x0103
Attribute 0x0201
UINT16 0x054c
Attribute 0x0202
UINT16 0x05c4
Attribute 0x0203
UINT16 0x0100
Attribute 0x0204
Bool True
Attribute 0x0205
UINT16 0x0002
[-- Attachment #5: connect_ds4_fedora_4.txt --]
[-- Type: text/plain, Size: 10027 bytes --]
HCI sniffer - Bluetooth packet analyzer ver 5.12
device: hci0 snap_len: 1500 filter: 0xffffffff
> HCI Event: Connect Request (0x04) plen 10
bdaddr 1C:66:6D:07:C3:E0 class 0x002508 type ACL
< HCI Command: Accept Connection Request (0x01|0x0009) plen 7
bdaddr 1C:66:6D:07:C3:E0 role 0x00
Role: Master
> HCI Event: Command Status (0x0f) plen 4
Accept Connection Request (0x01|0x0009) status 0x00 ncmd 1
> HCI Event: Role Change (0x12) plen 8
status 0x00 bdaddr 1C:66:6D:07:C3:E0 role 0x00
Role: Master
> HCI Event: Connect Complete (0x03) plen 11
status 0x00 handle 41 bdaddr 1C:66:6D:07:C3:E0 type ACL encrypt 0x00
< HCI Command: Read Remote Supported Features (0x01|0x001b) plen 2
handle 41
> HCI Event: Page Scan Repetition Mode Change (0x20) plen 7
bdaddr 1C:66:6D:07:C3:E0 mode 1
> HCI Event: Command Status (0x0f) plen 4
Read Remote Supported Features (0x01|0x001b) status 0x00 ncmd 0
> HCI Event: Max Slots Change (0x1b) plen 3
handle 41 slots 5
> HCI Event: Command Status (0x0f) plen 4
Unknown (0x00|0x0000) status 0x00 ncmd 1
< HCI Command: Change Connection Packet Type (0x01|0x000f) plen 4
handle 41 ptype 0xcc18
Packet type: DM1 DM3 DM5 DH1 DH3 DH5
> HCI Event: Command Status (0x0f) plen 4
Change Connection Packet Type (0x01|0x000f) status 0x00 ncmd 1
> HCI Event: Connection Packet Type Changed (0x1d) plen 5
status 0x00 handle 41 ptype 0xcc18
Packet type: DM1 DM3 DM5 DH1 DH3 DH5
> HCI Event: Read Remote Supported Features (0x0b) plen 11
status 0x00 handle 41
Features: 0xff 0xfe 0x0d 0xfe 0x98 0x7f 0x79 0x87
< HCI Command: Remote Name Request (0x01|0x0019) plen 10
bdaddr 1C:66:6D:07:C3:E0 mode 2 clkoffset 0x0000
> HCI Event: Command Status (0x0f) plen 4
Remote Name Request (0x01|0x0019) status 0x00 ncmd 1
> ACL data: handle 41 flags 0x02 dlen 12
L2CAP(s): Connect req: psm 1 scid 0x0040
< ACL data: handle 41 flags 0x02 dlen 16
L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0040 result 1 status 0
Connection pending - No futher information available
< ACL data: handle 41 flags 0x02 dlen 10
L2CAP(s): Info req: type 2
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 41 packets 1
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 41 packets 1
> ACL data: handle 41 flags 0x02 dlen 16
L2CAP(s): Info rsp: type 2 result 0
Extended feature mask 0x0000
< ACL data: handle 41 flags 0x02 dlen 16
L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0040 result 0 status 0
Connection successful
< ACL data: handle 41 flags 0x02 dlen 12
L2CAP(s): Config req: dcid 0x0040 flags 0x00 clen 0
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 41 packets 1
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 41 packets 1
> ACL data: handle 41 flags 0x02 dlen 16
L2CAP(s): Config req: dcid 0x0040 flags 0x00 clen 4
MTU 672
< ACL data: handle 41 flags 0x02 dlen 18
L2CAP(s): Config rsp: scid 0x0040 flags 0x00 result 0 clen 4
MTU 672
> ACL data: handle 41 flags 0x02 dlen 18
L2CAP(s): Config rsp: scid 0x0040 flags 0x00 result 0 clen 4
MTU 672
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 41 packets 1
> ACL data: handle 41 flags 0x02 dlen 24
L2CAP(d): cid 0x0040 len 20 [psm 1]
SDP SSA Req: tid 0x1 len 0xf
pat uuid-16 0x0100 (L2CAP)
max 2048
aid(s) 0x0000 - 0xffff
cont 00
< ACL data: handle 41 flags 0x02 dlen 192
< ACL data: handle 41 flags 0x01 dlen 192
< ACL data: handle 41 flags 0x01 dlen 93
L2CAP(d): cid 0x0040 len 473 [psm 1]
SDP SSA Rsp: tid 0x1 len 0x1d4
count 465
record #0
aid 0x0000 (SrvRecHndl)
uint 0x10001
aid 0x0001 (SrvClassIDList)
< uuid-16 0x1800 >
aid 0x0004 (ProtocolDescList)
< < uuid-16 0x0100 (L2CAP) uint 0x1f > <
uuid-16 0x0007 uint 0x1 uint 0x8 > >
aid 0x0005 (BrwGrpList)
< uuid-16 0x1002 (PubBrwsGrp) >
aid 0x000a (DocURL)
url "http://www.bluez.org/"
aid 0x000b (ClientExeURL)
url "http://www.bluez.org/"
aid 0x000c (IconURL)
url "http://www.bluez.org/"
aid 0x0100 (SrvName)
str "Generic Access Profile"
aid 0x0102 (ProviderName)
str "BlueZ"
record #1
aid 0x0000 (SrvRecHndl)
uint 0x10002
aid 0x0001 (SrvClassIDList)
< uuid-16 0x1801 >
aid 0x0004 (ProtocolDescList)
< < uuid-16 0x0100 (L2CAP) uint 0x1f > <
uuid-16 0x0007 uint 0x10 uint 0x10 > >
aid 0x0005 (BrwGrpList)
< uuid-16 0x1002 (PubBrwsGrp) >
aid 0x0100 (SrvName)
str "Generic Attribute Profile"
aid 0x0102 (ProviderName)
str "BlueZ"
record #2
aid 0x0000 (SrvRecHndl)
uint 0x10003
aid 0x0001 (SrvClassIDList)
< uuid-16 0x110e (AVRemote) uuid-16 0x110f (AVRemCt) >
aid 0x0004 (ProtocolDescList)
< < uuid-16 0x0100 (L2CAP) uint 0x17 > <
uuid-16 0x0017 (AVCTP) uint 0x103 > >
aid 0x0005 (BrwGrpList)
< uuid-16 0x1002 (PubBrwsGrp) >
aid 0x0009 (BTProfileDescList)
< < uuid-16 0x110e (AVRemote) uint 0x105 > >
aid 0x000d (AdditionalProtocolDescLists)
< < < uuid-16 0x0100 (L2CAP) uint 0x1b > < uuid-16 0x0017 (AVCTP) uint 0x103 > > >
aid 0x0100 (SrvName)
str "AVRCP CT"
aid 0x0311 (SuppFeatures)
uint 0x4f
record #3
aid 0x0000 (SrvRecHndl)
uint 0x10004
aid 0x0001 (SrvClassIDList)
< uuid-16 0x110c (AVRemTarget) >
aid 0x0004 (ProtocolDescList)
< < uuid-16 0x0100 (L2CAP) uint 0x17 > <
uuid-16 0x0017 (AVCTP) uint 0x103 > >
aid 0x0005 (BrwGrpList)
< uuid-16 0x1002 (PubBrwsGrp) >
aid 0x0009 (BTProfileDescList)
< < uuid-16 0x110e (AVRemote) uint 0x104 > >
aid 0x000d (AdditionalProtocolDescLists)
< < < uuid-16 0x0100 (L2CAP) uint 0x1b > < uuid-16 0x0017 (AVCTP) uint 0x103 > > >
aid 0x0100 (SrvName)
str "AVRCP TG"
aid 0x0311 (SuppFeatures)
uint 0x5f
cont 00
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 41 packets 1
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 41 packets 2
> ACL data: handle 41 flags 0x02 dlen 12
L2CAP(s): Disconn req: dcid 0x0040 scid 0x0040
< ACL data: handle 41 flags 0x02 dlen 12
L2CAP(s): Disconn rsp: dcid 0x0040 scid 0x0040
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 41 packets 1
> HCI Event: Remote Name Req Complete (0x07) plen 255
status 0x00 bdaddr 1C:66:6D:07:C3:E0 name 'Wireless Controller'
> HCI Event: Link Key Request (0x17) plen 6
bdaddr 1C:66:6D:07:C3:E0
< HCI Command: Link Key Request Reply (0x01|0x000b) plen 22
bdaddr 1C:66:6D:07:C3:E0 key DCD82F85FA8F56D21A7AFBF7B227F7E9
> HCI Event: Command Complete (0x0e) plen 10
Link Key Request Reply (0x01|0x000b) ncmd 1
status 0x00 bdaddr 1C:66:6D:07:C3:E0
> HCI Event: Encrypt Change (0x08) plen 4 <=============================
status 0x00 handle 41 encrypt 0x01
> ACL data: handle 41 flags 0x02 dlen 12
L2CAP(s): Connect req: psm 17 scid 0x0041
< ACL data: handle 41 flags 0x02 dlen 16
L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0041 result 0 status 0
Connection successful
< ACL data: handle 41 flags 0x02 dlen 12
L2CAP(s): Config req: dcid 0x0041 flags 0x00 clen 0
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 41 packets 1
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 41 packets 1
> ACL data: handle 41 flags 0x02 dlen 16
L2CAP(s): Config req: dcid 0x0040 flags 0x00 clen 4
MTU 672
< ACL data: handle 41 flags 0x02 dlen 18
L2CAP(s): Config rsp: scid 0x0041 flags 0x00 result 0 clen 4
MTU 672
> ACL data: handle 41 flags 0x02 dlen 18
L2CAP(s): Config rsp: scid 0x0040 flags 0x00 result 0 clen 4
MTU 672
< ACL data: handle 41 flags 0x02 dlen 5
L2CAP(d): cid 0x0041 len 1 [psm 17]
HIDP: Control: Virtual cable unplug <======================
< ACL data: handle 41 flags 0x02 dlen 12
L2CAP(s): Disconn req: dcid 0x0041 scid 0x0040
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 41 packets 1
> ACL data: handle 41 flags 0x02 dlen 12
L2CAP(s): Connect req: psm 19 scid 0x0042
< ACL data: handle 41 flags 0x02 dlen 16
L2CAP(s): Connect rsp: dcid 0x0041 scid 0x0042 result 1 status 2
Connection pending - Authorization pending <======================
< ACL data: handle 41 flags 0x02 dlen 16
L2CAP(s): Connect rsp: dcid 0x0041 scid 0x0042 result 3 status 0
Connection refused - security block <=====================
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 41 packets 1
> ACL data: handle 41 flags 0x02 dlen 5
L2CAP(d): cid 0x0040 len 1 [psm 17] <====================
HIDP: Handshake: Unsupported request
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 41 packets 1
> ACL data: handle 41 flags 0x02 dlen 12
L2CAP(s): Disconn rsp: dcid 0x0041 scid 0x0040
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 41 packets 1
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 41 packets 1
> HCI Event: Disconn Complete (0x05) plen 4
status 0x00 handle 41 reason 0x13
Reason: Remote User Terminated Connection <====================
[-- Attachment #6: info --]
[-- Type: application/octet-stream, Size: 157 bytes --]
[General]
Name=
Class=0x002508
SupportedTechnologies=BR/EDR
Trusted=false
Blocked=false
[LinkKey]
Key=0xDCD82F85FA8F56D21A7AFBF7B227F7E9
Type=0
PINLength=4
^ permalink raw reply
* Re: Questions on BlueZ 5.13: device creation API + persistent hid/input pipeline
From: Marcel Holtmann @ 2014-01-16 23:42 UTC (permalink / raw)
To: Petri Gynther; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <CAGXr9JHi5UuDd01POdua1UZ2kY+n=0wGcxaWx4Ta=55fHvZxyw@mail.gmail.com>
Hi Petri,
>>> 2) There is a difference in HID vs HoG hid/input pipeline persistence.
>>> When the Bluetooth classic HID remote disconnects, the corresponding
>>> hid and input kernel devices are destroyed. And when it reconnects,
>>> hid and input devices are created again. This adds a lot of
>>> unnecessary delay at reconnect. And, the first keypress is always lost
>>> on reconnect.
>>>
>>> In contrast, for the Bluetooth LE HoG remote, the hid/input pipeline
>>> is persistent. When HoG remote disconnects, hid and input devices
>>> remain in the system and are reused when the HoG remote reconnects.
>>>
>>> Is there a way to make Bluetooth classic HID behave the same as HoG,
>>> i.e. retain the hid and input kernel devices on disconnect and reuse
>>> them on reconnect?
>>
>> HID and HoG work a little bit different. HID uses a kernel transport driver while HoG uses /dev/uhid to do the work. Porting HID over to use /dev/uhid is certainly a possibility. We have considered that, but nobody has done that work yet.
>>
>> Please remember that HID (with HIDP) is finding its right place in /sys device tree. While all HoG using /dev/uhid are considered virtual devices. There is a semi proposal that we agreed on New Orleans during the PlumbersConf, but I have no idea if David actually implemented it.
>>
>> Another option is to make the HIDP transport smarter and persistent by integrating it into BlueZ 5’s kernel mgmt support. That however means you will need a much more recent Bluetooth subsystem. So 2.6.37 is not getting you anywhere near that even if we change HIDP support.
>
> I'm using BlueZ kernel modules (bluetooth, hidp) from Linux
> backports-3.13-rc2-1, so that is pretty recent code. Works fine on top
> of 2.6.37. However, my HID and input drivers come from 2.6.37, as they
> are not available in backports-3.13-rc2-1.
>
> I understand the difference between HID and HoG. Both hidp and uhid
> are hid_ll_drivers. HID input reports stay entirely in kernel, whereas
> HoG is handled in bluetoothd and input reports are passed back to
> kernel via /dev/uhid.
>
> Assuming the latest HIDP code, what kind of effort would it be to make
> the hid/input pipeline persistent when HID remote disconnects and
> reconnects?
for the HIDP code itself there is actually a lot of work. It does not have the model of persistent connections. It is designed to disconnect and reconnect. Since normally when you disconnect your device it is off. Otherwise you just sniff the connection. It is also a bit legacy reason from where L2CAP only had a concept of sockets and not l2cap_chan that only recently got introduced.
Why you are loosing your first input, that sounds like a bug we should look into. That should actually not happen.
To be honest, the easiest for you might be to run HID over /dev/uhid as well. So HoG and HID are both using /dev/uhid. A port of the input plugin to use /dev/uhid for HID should be straight forward. All the building blocks should be already there.
Regards
Marcel
^ permalink raw reply
* [PATCH 11/11] android/tester: Add HIDhost SendData test
From: Ravi kumar Veeramally @ 2014-01-16 23:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389914751-18545-1-git-send-email-ravikumar.veeramally@linux.intel.com>
---
android/android-tester.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index c79ea16..2ef44ef 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -3208,6 +3208,8 @@ static void setup_hidhost_interface(const void *test_data)
#define HID_SET_OUTPUT_REPORT 0x52
#define HID_SET_FEATURE_REPORT 0x53
+#define HID_SEND_DATA 0xa2
+
static void hid_prepare_reply_protocol_mode(const void *data, uint16_t len)
{
struct test_data *t_data = tester_get_data();
@@ -3242,6 +3244,12 @@ static void hid_prepare_reply_report(const void *data, uint16_t len)
static void hid_intr_cid_hook_cb(const void *data, uint16_t len,
void *user_data)
{
+ uint8_t header = ((uint8_t *) data)[0];
+
+ switch (header) {
+ case HID_SEND_DATA:
+ tester_test_passed();
+ }
}
static void hid_intr_connect_cb(uint16_t handle, uint16_t cid, void *user_data)
@@ -3277,6 +3285,7 @@ static void hid_ctrl_cid_hook_cb(const void *data, uint16_t len,
case HID_SET_INPUT_REPORT:
case HID_SET_OUTPUT_REPORT:
case HID_SET_FEATURE_REPORT:
+ case HID_SEND_DATA:
tester_test_passed();
}
}
@@ -3550,6 +3559,21 @@ static void test_hidhost_set_report(const void *test_data)
tester_test_failed();
}
+static void test_hidhost_send_data(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
+ bt_bdaddr_t bdaddr;
+ bt_status_t bt_status;
+ char *buf = "fe0201";
+
+ data->cb_count = 0;
+ bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
+ bt_status = data->if_hid->send_data(&bdaddr, buf);
+ if (bt_status != BT_STATUS_SUCCESS)
+ tester_test_failed();
+}
+
#define test_bredrle(name, data, test_setup, test, test_teardown) \
do { \
struct test_data *user; \
@@ -3923,5 +3947,9 @@ int main(int argc, char *argv[])
NULL, setup_hidhost_connect,
test_hidhost_set_report, teardown);
+ test_bredrle("HIDHost SendData Success",
+ NULL, setup_hidhost_connect,
+ test_hidhost_send_data, teardown);
+
return tester_run();
}
--
1.8.3.2
^ permalink raw reply related
* [PATCH 10/11] android/tester: Add HIDhost SetReport test
From: Ravi kumar Veeramally @ 2014-01-16 23:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389914751-18545-1-git-send-email-ravikumar.veeramally@linux.intel.com>
---
android/android-tester.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index f8d539d..c79ea16 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -3204,6 +3204,10 @@ static void setup_hidhost_interface(const void *test_data)
#define HID_GET_OUTPUT_REPORT 0x4a
#define HID_GET_FEATURE_REPORT 0x4b
+#define HID_SET_INPUT_REPORT 0x51
+#define HID_SET_OUTPUT_REPORT 0x52
+#define HID_SET_FEATURE_REPORT 0x53
+
static void hid_prepare_reply_protocol_mode(const void *data, uint16_t len)
{
struct test_data *t_data = tester_get_data();
@@ -3268,6 +3272,12 @@ static void hid_ctrl_cid_hook_cb(const void *data, uint16_t len,
case HID_GET_FEATURE_REPORT:
hid_prepare_reply_report(data, len);
break;
+ /* HID device doesnot reply for this commads, so reaching pdu's
+ * to hid device means assuming test passed */
+ case HID_SET_INPUT_REPORT:
+ case HID_SET_OUTPUT_REPORT:
+ case HID_SET_FEATURE_REPORT:
+ tester_test_passed();
}
}
@@ -3525,6 +3535,21 @@ static void test_hidhost_get_report(const void *test_data)
tester_test_failed();
}
+static void test_hidhost_set_report(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
+ bt_bdaddr_t bdaddr;
+ bt_status_t bt_status;
+ char *buf = "010101";
+
+ data->cb_count = 0;
+ bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
+ bt_status = data->if_hid->set_report(&bdaddr, BTHH_INPUT_REPORT, buf);
+ if (bt_status != BT_STATUS_SUCCESS)
+ tester_test_failed();
+}
+
#define test_bredrle(name, data, test_setup, test, test_teardown) \
do { \
struct test_data *user; \
@@ -3894,5 +3919,9 @@ int main(int argc, char *argv[])
&hidhost_test_get_report, setup_hidhost_connect,
test_hidhost_get_report, teardown);
+ test_bredrle("HIDHost SetReport Success",
+ NULL, setup_hidhost_connect,
+ test_hidhost_set_report, teardown);
+
return tester_run();
}
--
1.8.3.2
^ permalink raw reply related
* [PATCH 09/11] android/tester: Add HIDhost GetReport test
From: Ravi kumar Veeramally @ 2014-01-16 23:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389914751-18545-1-git-send-email-ravikumar.veeramally@linux.intel.com>
---
android/android-tester.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index da1fc28..f8d539d 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -3200,6 +3200,10 @@ static void setup_hidhost_interface(const void *test_data)
#define HID_SET_REPORT_PROTOCOL 0x70
#define HID_SET_BOOT_PROTOCOL 0x71
+#define HID_GET_INPUT_REPORT 0x49
+#define HID_GET_OUTPUT_REPORT 0x4a
+#define HID_GET_FEATURE_REPORT 0x4b
+
static void hid_prepare_reply_protocol_mode(const void *data, uint16_t len)
{
struct test_data *t_data = tester_get_data();
@@ -3215,6 +3219,22 @@ static void hid_prepare_reply_protocol_mode(const void *data, uint16_t len)
(void *)pdu, pdu_len);
}
+static void hid_prepare_reply_report(const void *data, uint16_t len)
+{
+ struct test_data *t_data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
+ uint8_t pdu[3] = { 0, 0, 0 };
+ uint16_t pdu_len = 0;
+
+ pdu_len = 3;
+ pdu[0] = 0xa2;
+ pdu[1] = 0x01;
+ pdu[2] = 0x00;
+
+ bthost_send_cid(bthost, t_data->ctrl_handle, t_data->ctrl_cid,
+ (void *)pdu, pdu_len);
+}
+
static void hid_intr_cid_hook_cb(const void *data, uint16_t len,
void *user_data)
{
@@ -3243,6 +3263,11 @@ static void hid_ctrl_cid_hook_cb(const void *data, uint16_t len,
case HID_SET_BOOT_PROTOCOL:
hid_prepare_reply_protocol_mode(data, len);
break;
+ case HID_GET_INPUT_REPORT:
+ case HID_GET_OUTPUT_REPORT:
+ case HID_GET_FEATURE_REPORT:
+ hid_prepare_reply_report(data, len);
+ break;
}
}
@@ -3465,6 +3490,41 @@ static void test_hidhost_set_protocol(const void *test_data)
tester_test_failed();
}
+static void hid_get_report_cb(bt_bdaddr_t *bd_addr, bthh_status_t status,
+ uint8_t *report, int size)
+{
+ struct test_data *data = tester_get_data();
+ const struct hidhost_generic_data *test = data->test_data;
+
+ if (data->cb_count == test->expected_cb_count &&
+ status == test->expected_status &&
+ size == test->expected_report_size)
+ tester_test_passed();
+ else
+ tester_test_failed();
+}
+
+static const struct hidhost_generic_data hidhost_test_get_report = {
+ .expected_hal_cb.get_report_cb = hid_get_report_cb,
+ .expected_cb_count = 1,
+ .expected_status = BTHH_OK,
+ .expected_report_size = 2,
+};
+
+static void test_hidhost_get_report(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
+ bt_bdaddr_t bdaddr;
+ bt_status_t bt_status;
+
+ data->cb_count = 0;
+ bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
+ bt_status = data->if_hid->get_report(&bdaddr, BTHH_INPUT_REPORT, 1, 20);
+ if (bt_status != BT_STATUS_SUCCESS)
+ tester_test_failed();
+}
+
#define test_bredrle(name, data, test_setup, test, test_teardown) \
do { \
struct test_data *user; \
@@ -3830,5 +3890,9 @@ int main(int argc, char *argv[])
&hidhost_test_get_protocol, setup_hidhost_connect,
test_hidhost_set_protocol, teardown);
+ test_bredrle("HIDHost GetReport Success",
+ &hidhost_test_get_report, setup_hidhost_connect,
+ test_hidhost_get_report, teardown);
+
return tester_run();
}
--
1.8.3.2
^ permalink raw reply related
* [PATCH 08/11] android/tester: Add HIDhost SetProtocol test
From: Ravi kumar Veeramally @ 2014-01-16 23:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389914751-18545-1-git-send-email-ravikumar.veeramally@linux.intel.com>
---
android/android-tester.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 56be850..da1fc28 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -3197,6 +3197,8 @@ static void setup_hidhost_interface(const void *test_data)
#define HID_GET_REPORT_PROTOCOL 0x60
#define HID_GET_BOOT_PROTOCOL 0x61
+#define HID_SET_REPORT_PROTOCOL 0x70
+#define HID_SET_BOOT_PROTOCOL 0x71
static void hid_prepare_reply_protocol_mode(const void *data, uint16_t len)
{
@@ -3237,6 +3239,8 @@ static void hid_ctrl_cid_hook_cb(const void *data, uint16_t len,
switch (header) {
case HID_GET_REPORT_PROTOCOL:
case HID_GET_BOOT_PROTOCOL:
+ case HID_SET_REPORT_PROTOCOL:
+ case HID_SET_BOOT_PROTOCOL:
hid_prepare_reply_protocol_mode(data, len);
break;
}
@@ -3447,6 +3451,20 @@ static void test_hidhost_get_protocol(const void *test_data)
tester_test_failed();
}
+static void test_hidhost_set_protocol(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
+ bt_bdaddr_t bdaddr;
+ bt_status_t bt_status;
+
+ data->cb_count = 0;
+ bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
+ bt_status = data->if_hid->set_protocol(&bdaddr, BTHH_REPORT_MODE);
+ if (bt_status != BT_STATUS_SUCCESS)
+ tester_test_failed();
+}
+
#define test_bredrle(name, data, test_setup, test, test_teardown) \
do { \
struct test_data *user; \
@@ -3808,5 +3826,9 @@ int main(int argc, char *argv[])
&hidhost_test_get_protocol, setup_hidhost_connect,
test_hidhost_get_protocol, teardown);
+ test_bredrle("HIDHost SetProtocol Success",
+ &hidhost_test_get_protocol, setup_hidhost_connect,
+ test_hidhost_set_protocol, teardown);
+
return tester_run();
}
--
1.8.3.2
^ permalink raw reply related
* [PATCH 07/11] android/tester: Add HIDhost GetProtocol test
From: Ravi kumar Veeramally @ 2014-01-16 23:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389914751-18545-1-git-send-email-ravikumar.veeramally@linux.intel.com>
---
android/android-tester.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 99 insertions(+), 2 deletions(-)
diff --git a/android/android-tester.c b/android/android-tester.c
index 2adbba1..56be850 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -3195,6 +3195,64 @@ static void setup_hidhost_interface(const void *test_data)
tester_setup_complete();
}
+#define HID_GET_REPORT_PROTOCOL 0x60
+#define HID_GET_BOOT_PROTOCOL 0x61
+
+static void hid_prepare_reply_protocol_mode(const void *data, uint16_t len)
+{
+ struct test_data *t_data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
+ uint8_t pdu[2] = { 0, 0 };
+ uint16_t pdu_len = 0;
+
+ pdu_len = 2;
+ pdu[0] = 0xa0;
+ pdu[1] = 0x00;
+
+ bthost_send_cid(bthost, t_data->ctrl_handle, t_data->ctrl_cid,
+ (void *)pdu, pdu_len);
+}
+
+static void hid_intr_cid_hook_cb(const void *data, uint16_t len,
+ void *user_data)
+{
+}
+
+static void hid_intr_connect_cb(uint16_t handle, uint16_t cid, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+
+ data->intr_handle = handle;
+ data->intr_cid = cid;
+
+ bthost_add_cid_hook(bthost, handle, cid, hid_intr_cid_hook_cb, NULL);
+}
+
+static void hid_ctrl_cid_hook_cb(const void *data, uint16_t len,
+ void *user_data)
+{
+ uint8_t header = ((uint8_t *) data)[0];
+
+ switch (header) {
+ case HID_GET_REPORT_PROTOCOL:
+ case HID_GET_BOOT_PROTOCOL:
+ hid_prepare_reply_protocol_mode(data, len);
+ break;
+ }
+}
+
+static void hid_ctrl_connect_cb(uint16_t handle, uint16_t cid, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+
+ data->ctrl_handle = handle;
+ data->ctrl_cid = cid;
+
+ bthost_add_cid_hook(bthost, handle, cid, hid_ctrl_cid_hook_cb, NULL);
+}
+
static void hid_sdp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
{
struct test_data *t_data = tester_get_data();
@@ -3308,9 +3366,9 @@ static void setup_hidhost_connect(const void *test_data)
/* Emulate SDP (PSM = 1) */
bthost_add_l2cap_server(bthost, 1, hid_sdp_search_cb, NULL);
/* Emulate Control Channel (PSM = 17) */
- bthost_add_l2cap_server(bthost, 17, NULL, NULL);
+ bthost_add_l2cap_server(bthost, 17, hid_ctrl_connect_cb, NULL);
/* Emulate Interrupt Channel (PSM = 19) */
- bthost_add_l2cap_server(bthost, 19, NULL, NULL);
+ bthost_add_l2cap_server(bthost, 19, hid_intr_connect_cb, NULL);
bthost_set_cmd_complete_cb(bthost, emu_powered_complete, data);
bthost_write_scan_enable(bthost, 0x03);
@@ -3354,6 +3412,41 @@ static void test_hidhost_virtual_unplug(const void *test_data)
tester_test_failed();
}
+static void hid_protocol_mode_cb(bt_bdaddr_t *bd_addr, bthh_status_t status,
+ bthh_protocol_mode_t mode)
+{
+ struct test_data *data = tester_get_data();
+ const struct hidhost_generic_data *test = data->test_data;
+
+ if (data->cb_count == test->expected_cb_count &&
+ status == test->expected_status &&
+ mode == test->expected_protocol_mode)
+ tester_test_passed();
+ else
+ tester_test_failed();
+}
+
+static const struct hidhost_generic_data hidhost_test_get_protocol = {
+ .expected_hal_cb.protocol_mode_cb = hid_protocol_mode_cb,
+ .expected_cb_count = 1,
+ .expected_protocol_mode = BTHH_BOOT_MODE,
+ .expected_status = BTHH_OK,
+};
+
+static void test_hidhost_get_protocol(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
+ bt_bdaddr_t bdaddr;
+ bt_status_t bt_status;
+
+ data->cb_count = 0;
+ bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
+ bt_status = data->if_hid->get_protocol(&bdaddr, BTHH_REPORT_MODE);
+ if (bt_status != BT_STATUS_SUCCESS)
+ tester_test_failed();
+}
+
#define test_bredrle(name, data, test_setup, test, test_teardown) \
do { \
struct test_data *user; \
@@ -3711,5 +3804,9 @@ int main(int argc, char *argv[])
&hidhost_test_disconnect, setup_hidhost_connect,
test_hidhost_virtual_unplug, teardown);
+ test_bredrle("HIDHost GetProtocol Success",
+ &hidhost_test_get_protocol, setup_hidhost_connect,
+ test_hidhost_get_protocol, teardown);
+
return tester_run();
}
--
1.8.3.2
^ permalink raw reply related
* [PATCH 06/11] android/tester: Add HIDhost VirtualUnplug test
From: Ravi kumar Veeramally @ 2014-01-16 23:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389914751-18545-1-git-send-email-ravikumar.veeramally@linux.intel.com>
---
android/android-tester.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 8edabb1..2adbba1 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -3340,6 +3340,20 @@ static void test_hidhost_disconnect(const void *test_data)
tester_test_failed();
}
+static void test_hidhost_virtual_unplug(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
+ bt_bdaddr_t bdaddr;
+ bt_status_t bt_status;
+
+ data->cb_count = 0;
+ bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
+ bt_status = data->if_hid->virtual_unplug(&bdaddr);
+ if (bt_status != BT_STATUS_SUCCESS)
+ tester_test_failed();
+}
+
#define test_bredrle(name, data, test_setup, test, test_teardown) \
do { \
struct test_data *user; \
@@ -3693,5 +3707,9 @@ int main(int argc, char *argv[])
&hidhost_test_disconnect, setup_hidhost_connect,
test_hidhost_disconnect, teardown);
+ test_bredrle("HIDHost VirtualUnplug Success",
+ &hidhost_test_disconnect, setup_hidhost_connect,
+ test_hidhost_virtual_unplug, teardown);
+
return tester_run();
}
--
1.8.3.2
^ permalink raw reply related
* [PATCH 05/11] android/tester: Add HIDhost Disconnect test
From: Ravi kumar Veeramally @ 2014-01-16 23:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389914751-18545-1-git-send-email-ravikumar.veeramally@linux.intel.com>
---
android/android-tester.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 0888a68..8edabb1 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -3316,6 +3316,30 @@ static void setup_hidhost_connect(const void *test_data)
bthost_write_scan_enable(bthost, 0x03);
}
+static void hid_discon_cb(bt_bdaddr_t *bd_addr, bthh_connection_state_t state)
+{
+ if (state == BTHH_CONN_STATE_DISCONNECTED)
+ tester_test_passed();
+}
+
+static const struct hidhost_generic_data hidhost_test_disconnect = {
+ .expected_hal_cb.connection_state_cb = hid_discon_cb,
+};
+
+static void test_hidhost_disconnect(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
+ bt_bdaddr_t bdaddr;
+ bt_status_t bt_status;
+
+ data->cb_count = 0;
+ bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
+ bt_status = data->if_hid->disconnect(&bdaddr);
+ if (bt_status != BT_STATUS_SUCCESS)
+ tester_test_failed();
+}
+
#define test_bredrle(name, data, test_setup, test, test_teardown) \
do { \
struct test_data *user; \
@@ -3665,5 +3689,9 @@ int main(int argc, char *argv[])
NULL, setup_hidhost_connect,
test_dummy, teardown);
+ test_bredrle("HIDHost Disconnect Success",
+ &hidhost_test_disconnect, setup_hidhost_connect,
+ test_hidhost_disconnect, teardown);
+
return tester_run();
}
--
1.8.3.2
^ permalink raw reply related
* [PATCH 04/11] android/tester: Add HIDhost Connect test
From: Ravi kumar Veeramally @ 2014-01-16 23:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389914751-18545-1-git-send-email-ravikumar.veeramally@linux.intel.com>
Emulated HID SDP and L2CAP Control and Interrupt channels.
---
android/android-tester.c | 231 +++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 221 insertions(+), 10 deletions(-)
diff --git a/android/android-tester.c b/android/android-tester.c
index 6f0e962..0888a68 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -69,6 +69,16 @@ struct socket_data {
bool test_channel;
};
+struct hidhost_generic_data {
+ bthh_status_t expected_status;
+ int expected_conn_state;
+ int expected_cb_count;
+ bthh_protocol_mode_t expected_protocol_mode;
+ int expected_report;
+ bthh_callbacks_t expected_hal_cb;
+ int expected_report_size;
+};
+
#define WAIT_FOR_SIGNAL_TIME 2 /* in seconds */
#define EMULATOR_SIGNAL "emulator_started"
@@ -97,6 +107,14 @@ struct test_data {
int cb_count;
GSList *expected_properties_list;
+
+ /* hidhost */
+ uint16_t sdp_handle;
+ uint16_t sdp_cid;
+ uint16_t ctrl_handle;
+ uint16_t ctrl_cid;
+ uint16_t intr_handle;
+ uint16_t intr_cid;
};
static char exec_dir[PATH_MAX + 1];
@@ -1933,15 +1951,6 @@ static bt_callbacks_t bt_callbacks = {
.le_test_mode_cb = NULL
};
-static bthh_callbacks_t bthh_callbacks = {
- .size = sizeof(bthh_callbacks),
- .connection_state_cb = NULL,
- .hid_info_cb = NULL,
- .protocol_mode_cb = NULL,
- .idle_time_cb = NULL,
- .get_report_cb = NULL,
- .virtual_unplug_cb = NULL
-};
static void setup(struct test_data *data)
{
@@ -3076,7 +3085,80 @@ clean:
close(sock_fd);
}
-static void setup_hidhost_interface(const void *test_data)
+static void hidhost_connection_state_cb(bt_bdaddr_t *bd_addr,
+ bthh_connection_state_t state)
+{
+ struct test_data *data = tester_get_data();
+ const struct hidhost_generic_data *test = data->test_data;
+
+ data->cb_count++;
+
+ if (state == BTHH_CONN_STATE_CONNECTED)
+ tester_setup_complete();
+
+ if (test && test->expected_hal_cb.connection_state_cb)
+ test->expected_hal_cb.connection_state_cb(bd_addr, state);
+}
+
+static void hidhost_virual_unplug_cb(bt_bdaddr_t *bd_addr, bthh_status_t status)
+{
+ struct test_data *data = tester_get_data();
+ const struct hidhost_generic_data *test = data->test_data;
+
+ data->cb_count++;
+
+ if (test && test->expected_hal_cb.virtual_unplug_cb)
+ test->expected_hal_cb.virtual_unplug_cb(bd_addr, status);
+}
+
+static void hidhost_hid_info_cb(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid)
+{
+ struct test_data *data = tester_get_data();
+ const struct hidhost_generic_data *test = data->test_data;
+
+ data->cb_count++;
+
+ if (test && test->expected_hal_cb.hid_info_cb)
+ test->expected_hal_cb.hid_info_cb(bd_addr, hid);
+}
+
+static void hidhost_protocol_mode_cb(bt_bdaddr_t *bd_addr,
+ bthh_status_t status,
+ bthh_protocol_mode_t mode)
+{
+ struct test_data *data = tester_get_data();
+ const struct hidhost_generic_data *test = data->test_data;
+
+ data->cb_count++;
+
+ if (test && test->expected_hal_cb.protocol_mode_cb)
+ test->expected_hal_cb.protocol_mode_cb(bd_addr, status, mode);
+}
+
+static void hidhost_get_report_cb(bt_bdaddr_t *bd_addr, bthh_status_t status,
+ uint8_t *report, int size)
+{
+ struct test_data *data = tester_get_data();
+ const struct hidhost_generic_data *test = data->test_data;
+
+ data->cb_count++;
+
+ if (test && test->expected_hal_cb.get_report_cb)
+ test->expected_hal_cb.get_report_cb(bd_addr, status, report,
+ size);
+}
+
+static bthh_callbacks_t bthh_callbacks = {
+ .size = sizeof(bthh_callbacks),
+ .connection_state_cb = hidhost_connection_state_cb,
+ .hid_info_cb = hidhost_hid_info_cb,
+ .protocol_mode_cb = hidhost_protocol_mode_cb,
+ .idle_time_cb = NULL,
+ .get_report_cb = hidhost_get_report_cb,
+ .virtual_unplug_cb = hidhost_virual_unplug_cb
+};
+
+static void setup_hidhost(const void *test_data)
{
struct test_data *data = tester_get_data();
bt_status_t status;
@@ -3105,10 +3187,135 @@ static void setup_hidhost_interface(const void *test_data)
tester_setup_failed();
return;
}
+}
+static void setup_hidhost_interface(const void *test_data)
+{
+ setup_hidhost(test_data);
tester_setup_complete();
}
+static void hid_sdp_cid_hook_cb(const void *data, uint16_t len, void *user_data)
+{
+ struct test_data *t_data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
+ uint8_t pdu[] = { 0x07, /* PDU id */
+ 0x00, 0x00, /* Transaction id */
+ 0x01, 0x71, /* Response length */
+ 0x01, 0x6E, /* Attributes length */
+ 0x36, 0x01, 0x6b, 0x36, 0x01, 0x68, 0x09, 0x00,
+ 0x00, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x09, 0x00,
+ 0x01, 0x35, 0x03, 0x19, 0x11, 0x24, 0x09, 0x00,
+ 0x04, 0x35, 0x0d, 0x35, 0x06, 0x19, 0x01, 0x00,
+ 0x09, 0x00, 0x11, 0x35, 0x03, 0x19, 0x00, 0x11,
+ 0x09, 0x00, 0x05, 0x35, 0x03, 0x19, 0x10, 0x02,
+ 0x09, 0x00, 0x06, 0x35, 0x09, 0x09, 0x65, 0x6e,
+ 0x09, 0x00, 0x6a, 0x09, 0x01, 0x00, 0x09, 0x00,
+ 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, 0x11, 0x24,
+ 0x09, 0x01, 0x00, 0x09, 0x00, 0x0d, 0x35, 0x0f,
+ 0x35, 0x0d, 0x35, 0x06, 0x19, 0x01, 0x00, 0x09,
+ 0x00, 0x13, 0x35, 0x03, 0x19, 0x00, 0x11, 0x09,
+ 0x01, 0x00, 0x25, 0x1e, 0x4c, 0x6f, 0x67, 0x69,
+ 0x74, 0x65, 0x63, 0x68, 0x20, 0x42, 0x6c, 0x75,
+ 0x65, 0x74, 0x6f, 0x6f, 0x74, 0x68, 0x20, 0x4d,
+ 0x6f, 0x75, 0x73, 0x65, 0x20, 0x4d, 0x35, 0x35,
+ 0x35, 0x62, 0x09, 0x01, 0x01, 0x25, 0x0f, 0x42,
+ 0x6c, 0x75, 0x65, 0x74, 0x6f, 0x6f, 0x74, 0x68,
+ 0x20, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x09, 0x01,
+ 0x02, 0x25, 0x08, 0x4c, 0x6f, 0x67, 0x69, 0x74,
+ 0x65, 0x63, 0x68, 0x09, 0x02, 0x00, 0x09, 0x01,
+ 0x00, 0x09, 0x02, 0x01, 0x09, 0x01, 0x11, 0x09,
+ 0x02, 0x02, 0x08, 0x80, 0x09, 0x02, 0x03, 0x08,
+ 0x21, 0x09, 0x02, 0x04, 0x28, 0x01, 0x09, 0x02,
+ 0x05, 0x28, 0x01, 0x09, 0x02, 0x06, 0x35, 0x74,
+ 0x35, 0x72, 0x08, 0x22, 0x25, 0x6e, 0x05, 0x01,
+ 0x09, 0x02, 0xa1, 0x01, 0x85, 0x02, 0x09, 0x01,
+ 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x08,
+ 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08,
+ 0x81, 0x02, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31,
+ 0x16, 0x01, 0xf8, 0x26, 0xff, 0x07, 0x75, 0x0c,
+ 0x95, 0x02, 0x81, 0x06, 0x09, 0x38, 0x15, 0x81,
+ 0x25, 0x7f, 0x75, 0x08, 0x95, 0x01, 0x81, 0x06,
+ 0x05, 0x0c, 0x0a, 0x38, 0x02, 0x81, 0x06, 0x05,
+ 0x09, 0x19, 0x09, 0x29, 0x10, 0x15, 0x00, 0x25,
+ 0x01, 0x95, 0x08, 0x75, 0x01, 0x81, 0x02, 0xc0,
+ 0xc0, 0x06, 0x00, 0xff, 0x09, 0x01, 0xa1, 0x01,
+ 0x85, 0x10, 0x75, 0x08, 0x95, 0x06, 0x15, 0x00,
+ 0x26, 0xff, 0x00, 0x09, 0x01, 0x81, 0x00, 0x09,
+ 0x01, 0x91, 0x00, 0xc0, 0x09, 0x02, 0x07, 0x35,
+ 0x08, 0x35, 0x06, 0x09, 0x04, 0x09, 0x09, 0x01,
+ 0x00, 0x09, 0x02, 0x08, 0x28, 0x00, 0x09, 0x02,
+ 0x09, 0x28, 0x01, 0x09, 0x02, 0x0a, 0x28, 0x01,
+ 0x09, 0x02, 0x0b, 0x09, 0x01, 0x00, 0x09, 0x02,
+ 0x0c, 0x09, 0x0c, 0x80, 0x09, 0x02, 0x0d, 0x28,
+ 0x00, 0x09, 0x02, 0x0e, 0x28, 0x01,
+ 0x00 /* no continuation */};
+
+ bthost_send_cid(bthost, t_data->sdp_handle, t_data->sdp_cid,
+ (void *)pdu, sizeof(pdu));
+}
+
+static void hid_sdp_search_cb(uint16_t handle, uint16_t cid, void *user_data)
+{
+ struct test_data *data = tester_get_data();
+ struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+
+ data->sdp_handle = handle;
+ data->sdp_cid = cid;
+
+ bthost_add_cid_hook(bthost, handle, cid, hid_sdp_cid_hook_cb, NULL);
+}
+
+static void emu_powered_complete(uint16_t opcode, uint8_t status,
+ const void *param, uint8_t len,
+ void *user_data)
+{
+ struct test_data *data = tester_get_data();
+ const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
+ bt_bdaddr_t bdaddr;
+ bt_status_t bt_status;
+
+ switch (opcode) {
+ case BT_HCI_CMD_WRITE_SCAN_ENABLE:
+ case BT_HCI_CMD_LE_SET_ADV_ENABLE:
+ break;
+ default:
+ return;
+ }
+
+ if (status) {
+ tester_setup_failed();
+ return;
+ }
+
+ data->cb_count = 0;
+ bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
+ bt_status = data->if_hid->connect(&bdaddr);
+ if (bt_status != BT_STATUS_SUCCESS)
+ tester_setup_failed();
+
+}
+
+static void setup_hidhost_connect(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ struct bthost *bthost;
+
+ setup_hidhost(test_data);
+
+ bthost = hciemu_client_get_host(data->hciemu);
+
+ /* Emulate SDP (PSM = 1) */
+ bthost_add_l2cap_server(bthost, 1, hid_sdp_search_cb, NULL);
+ /* Emulate Control Channel (PSM = 17) */
+ bthost_add_l2cap_server(bthost, 17, NULL, NULL);
+ /* Emulate Interrupt Channel (PSM = 19) */
+ bthost_add_l2cap_server(bthost, 19, NULL, NULL);
+
+ bthost_set_cmd_complete_cb(bthost, emu_powered_complete, data);
+ bthost_write_scan_enable(bthost, 0x03);
+}
+
#define test_bredrle(name, data, test_setup, test, test_teardown) \
do { \
struct test_data *user; \
@@ -3454,5 +3661,9 @@ int main(int argc, char *argv[])
test_bredrle("HIDHost Init", NULL, setup_hidhost_interface,
test_dummy, teardown);
+ test_bredrle("HIDHost Connect Success",
+ NULL, setup_hidhost_connect,
+ test_dummy, teardown);
+
return tester_run();
}
--
1.8.3.2
^ permalink raw reply related
* [PATCH 03/11] android/hidhost: Remove unnecessary check
From: Ravi kumar Veeramally @ 2014-01-16 23:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389914751-18545-1-git-send-email-ravikumar.veeramally@linux.intel.com>
HID device will return unsupported or invalid response for unsupported
or invalid get/set protocol request. Need not to check prior to that.
---
android/hidhost.c | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/android/hidhost.c b/android/hidhost.c
index 8a2668c..968b6f2 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -900,11 +900,6 @@ static void bt_hid_get_protocol(const void *buf, uint16_t len)
dev = l->data;
- if (dev->boot_dev) {
- status = HAL_STATUS_UNSUPPORTED;
- goto failed;
- }
-
hdr = HID_MSG_GET_PROTOCOL | cmd->mode;
fd = g_io_channel_unix_get_fd(dev->ctrl_io);
@@ -955,11 +950,6 @@ static void bt_hid_set_protocol(const void *buf, uint16_t len)
dev = l->data;
- if (dev->boot_dev) {
- status = HAL_STATUS_UNSUPPORTED;
- goto failed;
- }
-
hdr = HID_MSG_SET_PROTOCOL | cmd->mode;
fd = g_io_channel_unix_get_fd(dev->ctrl_io);
--
1.8.3.2
^ permalink raw reply related
* [PATCH 02/11] android/hidhost: Fix miscalculation of get report event struct length
From: Ravi kumar Veeramally @ 2014-01-16 23:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389914751-18545-1-git-send-email-ravikumar.veeramally@linux.intel.com>
---
android/hal-hidhost.c | 3 ++-
android/hidhost.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
index fd3ad2d..5445d08 100644
--- a/android/hal-hidhost.c
+++ b/android/hal-hidhost.c
@@ -73,7 +73,8 @@ static void handle_get_report(void *buf, uint16_t len)
{
struct hal_ev_hidhost_get_report *ev = buf;
- if (len != sizeof(*ev) + ev->len) {
+ if (len != sizeof(*ev) + sizeof(struct hal_ev_hidhost_get_report)
+ + ev->len) {
error("invalid get report event, aborting");
exit(EXIT_FAILURE);
}
diff --git a/android/hidhost.c b/android/hidhost.c
index c004063..8a2668c 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -371,13 +371,14 @@ static void bt_hid_notify_get_report(struct hid_device *dev, uint8_t *buf,
ba2str(&dev->dst, address);
DBG("device %s", address);
- ev_len = sizeof(*ev) + sizeof(struct hal_ev_hidhost_get_report) + 1;
+ ev_len = sizeof(*ev) + sizeof(struct hal_ev_hidhost_get_report);
if (!((buf[0] == (HID_MSG_DATA | HID_DATA_TYPE_INPUT)) ||
(buf[0] == (HID_MSG_DATA | HID_DATA_TYPE_OUTPUT)) ||
(buf[0] == (HID_MSG_DATA | HID_DATA_TYPE_FEATURE)))) {
ev = g_malloc0(ev_len);
ev->status = buf[0];
+ ev->len = 0;
bdaddr2android(&dev->dst, ev->bdaddr);
goto send;
}
--
1.8.3.2
^ permalink raw reply related
* [PATCH 01/11] android/hidhost: Fix connection state notification on profile unregister
From: Ravi kumar Veeramally @ 2014-01-16 23:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389914751-18545-1-git-send-email-ravikumar.veeramally@linux.intel.com>
Issue found while writing end2end tests. Usually profile unregister is
called when final cleanup of bluetoothd. Freeing connected hid devices
through g_slist_foreach is a asynchronous call. Profile is cleaned up
and and ipc also complete cleanup. But free_hid_devices tries to notify
hal which doesn't exist that time. So behaviour is unexpected.
---
android/hidhost.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/android/hidhost.c b/android/hidhost.c
index aed9899..c004063 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -1328,7 +1328,6 @@ static void free_hid_devices(gpointer data, gpointer user_data)
{
struct hid_device *dev = data;
- bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED);
hid_device_free(dev);
}
--
1.8.3.2
^ permalink raw reply related
* [PATCH 00/11] HIDHost E2E tests and fixes
From: Ravi kumar Veeramally @ 2014-01-16 23:25 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
Patch set contains few fixes which are noticed while writing
tests and success test cases for hidhost.
Ravi kumar Veeramally (11):
android/hidhost: Fix connection state notification on profile
unregister
android/hidhost: Fix miscalculation of get report event struct length
android/hidhost: Remove unnecessary check
android/tester: Add HIDhost Connect test
android/tester: Add HIDhost Disconnect test
android/tester: Add HIDhost VirtualUnplug test
android/tester: Add HIDhost GetProtocol test
android/tester: Add HIDhost SetProtocol test
android/tester: Add HIDhost GetReport test
android/tester: Add HIDhost SetReport test
android/tester: Add HIDhost SendData test
android/android-tester.c | 517 ++++++++++++++++++++++++++++++++++++++++++++++-
android/hal-hidhost.c | 3 +-
android/hidhost.c | 14 +-
3 files changed, 511 insertions(+), 23 deletions(-)
--
1.8.3.2
^ permalink raw reply
* Re: Questions on BlueZ 5.13: device creation API + persistent hid/input pipeline
From: Petri Gynther @ 2014-01-16 23:03 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <F4C3DE28-E297-42B1-9FA2-B3335DF0F080@holtmann.org>
Hi Marcel,
Thanks for your reply. Please see inline.
On Thu, Jan 16, 2014 at 2:30 PM, Marcel Holtmann <marcel@holtmann.org> wrot=
e:
> Hi Petri,
>
>> I'm running BlueZ 5.13 userland + backported BlueZ kernel modules on
>> an embedded system that I'm working on. The kernel on the system is
>> 2.6.37-based. I ported uhid driver manually from 3.12.
>>
>> I'm successfully using Bluetooth classic HID remote control and
>> Bluetooth LE HoG remote control on this system. However, I have two
>> questions:
>>
>> 1) The Bluetooth classic remote that I'm using is not discoverable. It
>> is only connectable. When the remote is not paired, it sends its
>> Bluetooth MAC address to the host via IR, and the host needs to add
>> this device to BlueZ's discovered devices database. But, how can I do
>> that via D-Bus API? BlueZ 5 porting guide specifically mentions that "
>> ... we decided to simply get rid of explicit CreateDevice /
>> CreatePairedDevice methods and instead dynamically create device
>> objects as they are discovered during device discovery."
>>
>> So, is there no API available to add non-discoverable devices in BlueZ 5=
?
>>
>> I have worked around this issue by manually adding this remote to
>> <storage path>, so that bluetoothd creates the device on reboot via
>> device_create_from_storage(). But, I would prefer not to restart
>> bluetoothd every time a non-discoverable device needs to be added.
>
> I have never heard of a remote that uses IR to setup the pairing. A creat=
ive way of doing out-of-band pairing.
>
> What I think you are looking for is what the PS3 controllers do when the =
share their details over USB and then after that connect over Bluetooth HID=
. Have a look at plugins/sixaxis.c to see how they do it. BlueZ has a plugi=
n API for doing exactly these kind of automated setup/pairing type of cases=
.
>
> So you want to write a plugin for this remote.
>
> The other plugin you might want to look at is plugins/autopair.c if it ac=
tually requires to also create an encrypted link.
>
Thank you for this info. I will look into plugins/sixaxis.c and
plugins/autopair.c.
>> 2) There is a difference in HID vs HoG hid/input pipeline persistence.
>> When the Bluetooth classic HID remote disconnects, the corresponding
>> hid and input kernel devices are destroyed. And when it reconnects,
>> hid and input devices are created again. This adds a lot of
>> unnecessary delay at reconnect. And, the first keypress is always lost
>> on reconnect.
>>
>> In contrast, for the Bluetooth LE HoG remote, the hid/input pipeline
>> is persistent. When HoG remote disconnects, hid and input devices
>> remain in the system and are reused when the HoG remote reconnects.
>>
>> Is there a way to make Bluetooth classic HID behave the same as HoG,
>> i.e. retain the hid and input kernel devices on disconnect and reuse
>> them on reconnect?
>
> HID and HoG work a little bit different. HID uses a kernel transport driv=
er while HoG uses /dev/uhid to do the work. Porting HID over to use /dev/uh=
id is certainly a possibility. We have considered that, but nobody has done=
that work yet.
>
> Please remember that HID (with HIDP) is finding its right place in /sys d=
evice tree. While all HoG using /dev/uhid are considered virtual devices. T=
here is a semi proposal that we agreed on New Orleans during the PlumbersCo=
nf, but I have no idea if David actually implemented it.
>
> Another option is to make the HIDP transport smarter and persistent by in=
tegrating it into BlueZ 5=E2=80=99s kernel mgmt support. That however means=
you will need a much more recent Bluetooth subsystem. So 2.6.37 is not get=
ting you anywhere near that even if we change HIDP support.
>
> Regards
>
> Marcel
>
I'm using BlueZ kernel modules (bluetooth, hidp) from Linux
backports-3.13-rc2-1, so that is pretty recent code. Works fine on top
of 2.6.37. However, my HID and input drivers come from 2.6.37, as they
are not available in backports-3.13-rc2-1.
I understand the difference between HID and HoG. Both hidp and uhid
are hid_ll_drivers. HID input reports stay entirely in kernel, whereas
HoG is handled in bluetoothd and input reports are passed back to
kernel via /dev/uhid.
Assuming the latest HIDP code, what kind of effort would it be to make
the hid/input pipeline persistent when HID remote disconnects and
reconnects?
-- Petri
^ permalink raw reply
* Re: [PATCH] enable Atheros 0cf3:311e for firmware upload
From: Marcel Holtmann @ 2014-01-16 22:48 UTC (permalink / raw)
To: Oliver Neukum
Cc: Yu-Chen Cho, Gustavo F. Padovan, Johan Hedberg,
linux-bluetooth@vger.kernel.org development, Oliver Neukum
In-Reply-To: <1389883031-10752-2-git-send-email-oliver@neukum.org>
Hi Oliver,
> The device will bind to btusb without firmware, but with the original
> buggy firmware device discovery does not work. No devices are detected.
>
> Device descriptor without firmware:
> T: Bus=03 Lev=01 Prnt=01 Port=02 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=0cf3 ProdID=311e Rev= 0.01
> 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= 16 Ivl=1ms
> E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
> E: Ad=02(O) 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=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
> E: Ad=03(O) 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=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
> E: Ad=03(O) 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=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
> E: Ad=03(O) 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=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
> E: Ad=03(O) 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=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
> E: Ad=03(O) 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=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
> E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
>
> with firmware:
> T: Bus=03 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 3 Spd=12 MxCh= 0
> D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
> P: Vendor=0cf3 ProdID=311e Rev= 0.02
> 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= 16 Ivl=1ms
> E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
> E: Ad=02(O) 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=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
> E: Ad=03(O) 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=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
> E: Ad=03(O) 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=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
> E: Ad=03(O) 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=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
> E: Ad=03(O) 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=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
> E: Ad=03(O) 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=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
> E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
>
> Signed-off-by: Oliver Neukum <oneukum@suse.de>
> ---
> drivers/bluetooth/ath3k.c | 2 ++
> drivers/bluetooth/btusb.c | 1 +
> 2 files changed, 3 insertions(+)
patch has been applied to bluetooth-next tree.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH] add firmware update for Atheros 0cf3:311f
From: Marcel Holtmann @ 2014-01-16 22:48 UTC (permalink / raw)
To: Oliver Neukum
Cc: Yu-Chen Cho, Gustavo F. Padovan, Johan Hedberg,
linux-bluetooth@vger.kernel.org development, Oliver Neukum
In-Reply-To: <1389884578-18479-2-git-send-email-oliver@neukum.org>
Hi Oliver,
> The device is not functional without firmware.
>
> The device without firmware:
> T: Bus=02 Lev=02 Prnt=02 Port=05 Cnt=01 Dev#= 3 Spd=12 MxCh= 0
> D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
> P: Vendor=0cf3 ProdID=311f Rev=00.01
> 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
> I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
>
> The device with firmware:
> T: Bus=02 Lev=02 Prnt=02 Port=05 Cnt=01 Dev#= 4 Spd=12 MxCh= 0
> D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
> P: Vendor=0cf3 ProdID=3007 Rev=00.01
> 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
> I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
>
> Signed-off-by: Oliver Neukum <oneukum@suse.de>
> ---
> drivers/bluetooth/ath3k.c | 2 ++
> drivers/bluetooth/btusb.c | 1 +
> 2 files changed, 3 insertions(+)
patch has been applied to bluetooth-next tree.
Regards
Marcel
^ permalink raw reply
* Re: Questions on BlueZ 5.13: device creation API + persistent hid/input pipeline
From: Marcel Holtmann @ 2014-01-16 22:30 UTC (permalink / raw)
To: Petri Gynther; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <CAGXr9JHw-S5XdXEcp3APN9OKadt7LuoPQmJ2RZkAsRZ8dDJB-w@mail.gmail.com>
Hi Petri,
> I'm running BlueZ 5.13 userland + backported BlueZ kernel modules on
> an embedded system that I'm working on. The kernel on the system is
> 2.6.37-based. I ported uhid driver manually from 3.12.
>
> I'm successfully using Bluetooth classic HID remote control and
> Bluetooth LE HoG remote control on this system. However, I have two
> questions:
>
> 1) The Bluetooth classic remote that I'm using is not discoverable. It
> is only connectable. When the remote is not paired, it sends its
> Bluetooth MAC address to the host via IR, and the host needs to add
> this device to BlueZ's discovered devices database. But, how can I do
> that via D-Bus API? BlueZ 5 porting guide specifically mentions that "
> ... we decided to simply get rid of explicit CreateDevice /
> CreatePairedDevice methods and instead dynamically create device
> objects as they are discovered during device discovery."
>
> So, is there no API available to add non-discoverable devices in BlueZ 5?
>
> I have worked around this issue by manually adding this remote to
> <storage path>, so that bluetoothd creates the device on reboot via
> device_create_from_storage(). But, I would prefer not to restart
> bluetoothd every time a non-discoverable device needs to be added.
I have never heard of a remote that uses IR to setup the pairing. A creative way of doing out-of-band pairing.
What I think you are looking for is what the PS3 controllers do when the share their details over USB and then after that connect over Bluetooth HID. Have a look at plugins/sixaxis.c to see how they do it. BlueZ has a plugin API for doing exactly these kind of automated setup/pairing type of cases.
So you want to write a plugin for this remote.
The other plugin you might want to look at is plugins/autopair.c if it actually requires to also create an encrypted link.
> 2) There is a difference in HID vs HoG hid/input pipeline persistence.
> When the Bluetooth classic HID remote disconnects, the corresponding
> hid and input kernel devices are destroyed. And when it reconnects,
> hid and input devices are created again. This adds a lot of
> unnecessary delay at reconnect. And, the first keypress is always lost
> on reconnect.
>
> In contrast, for the Bluetooth LE HoG remote, the hid/input pipeline
> is persistent. When HoG remote disconnects, hid and input devices
> remain in the system and are reused when the HoG remote reconnects.
>
> Is there a way to make Bluetooth classic HID behave the same as HoG,
> i.e. retain the hid and input kernel devices on disconnect and reuse
> them on reconnect?
HID and HoG work a little bit different. HID uses a kernel transport driver while HoG uses /dev/uhid to do the work. Porting HID over to use /dev/uhid is certainly a possibility. We have considered that, but nobody has done that work yet.
Please remember that HID (with HIDP) is finding its right place in /sys device tree. While all HoG using /dev/uhid are considered virtual devices. There is a semi proposal that we agreed on New Orleans during the PlumbersConf, but I have no idea if David actually implemented it.
Another option is to make the HIDP transport smarter and persistent by integrating it into BlueZ 5’s kernel mgmt support. That however means you will need a much more recent Bluetooth subsystem. So 2.6.37 is not getting you anywhere near that even if we change HIDP support.
Regards
Marcel
^ permalink raw reply
* Questions on BlueZ 5.13: device creation API + persistent hid/input pipeline
From: Petri Gynther @ 2014-01-16 22:17 UTC (permalink / raw)
To: linux-bluetooth
linux-bluetooth:
I'm running BlueZ 5.13 userland + backported BlueZ kernel modules on
an embedded system that I'm working on. The kernel on the system is
2.6.37-based. I ported uhid driver manually from 3.12.
I'm successfully using Bluetooth classic HID remote control and
Bluetooth LE HoG remote control on this system. However, I have two
questions:
1) The Bluetooth classic remote that I'm using is not discoverable. It
is only connectable. When the remote is not paired, it sends its
Bluetooth MAC address to the host via IR, and the host needs to add
this device to BlueZ's discovered devices database. But, how can I do
that via D-Bus API? BlueZ 5 porting guide specifically mentions that "
... we decided to simply get rid of explicit CreateDevice /
CreatePairedDevice methods and instead dynamically create device
objects as they are discovered during device discovery."
So, is there no API available to add non-discoverable devices in BlueZ 5?
I have worked around this issue by manually adding this remote to
<storage path>, so that bluetoothd creates the device on reboot via
device_create_from_storage(). But, I would prefer not to restart
bluetoothd every time a non-discoverable device needs to be added.
2) There is a difference in HID vs HoG hid/input pipeline persistence.
When the Bluetooth classic HID remote disconnects, the corresponding
hid and input kernel devices are destroyed. And when it reconnects,
hid and input devices are created again. This adds a lot of
unnecessary delay at reconnect. And, the first keypress is always lost
on reconnect.
In contrast, for the Bluetooth LE HoG remote, the hid/input pipeline
is persistent. When HoG remote disconnects, hid and input devices
remain in the system and are reused when the HoG remote reconnects.
Is there a way to make Bluetooth classic HID behave the same as HoG,
i.e. retain the hid and input kernel devices on disconnect and reuse
them on reconnect?
^ permalink raw reply
* Re: [PATCH 1/2] android: Add btmgmt to debug builds
From: Marcel Holtmann @ 2014-01-16 22:08 UTC (permalink / raw)
To: Andrzej Kaczmarek; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <1389883945-10707-1-git-send-email-andrzej.kaczmarek@tieto.com>
Hi Andrzej,
> android/Android.mk | 36 ++++++++++++++++++++++++++++++++++++
> 1 file changed, 36 insertions(+)
>
> diff --git a/android/Android.mk b/android/Android.mk
> index 7e97ec8..b3e6a50 100644
> --- a/android/Android.mk
> +++ b/android/Android.mk
> @@ -282,3 +282,39 @@ LOCAL_MODULE_TAGS := optional
> LOCAL_MODULE := bluetoothd-snoop
>
> include $(BUILD_EXECUTABLE)
> +
> +#
> +# btmgmt
> +#
> +
> +include $(CLEAR_VARS)
> +
> +LOCAL_SRC_FILES := \
> + ../tools/btmgmt.c \
> + ../monitor/mainloop.c \
> + ../lib/bluetooth.c \
> + ../lib/sdp.c \
> + ../src/eir.c \
> + ../src/glib-helper.c \
> + ../src/shared/io-mainloop.c \
> + ../src/shared/mgmt.c \
> + ../src/shared/queue.c \
> + ../src/shared/util.c \
> +
> +LOCAL_C_INCLUDES := \
> + $(call include-path-for, glib) \
> + $(call include-path-for, glib)/glib \
> + $(LOCAL_PATH)/.. \
> + $(LOCAL_PATH)/../src \
> + $(LOCAL_PATH)/../lib \
> +
> +LOCAL_SHARED_LIBRARIES := \
> + libglib \
have Johan fix the dependency on GLib instead. It should not be needed anymore.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH] android/a2dp: Fix typo in condition
From: Luiz Augusto von Dentz @ 2014-01-16 15:54 UTC (permalink / raw)
To: Andrzej Kaczmarek; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1389886700-21480-1-git-send-email-andrzej.kaczmarek@tieto.com>
Hi Andrzej,
On Thu, Jan 16, 2014 at 5:38 PM, Andrzej Kaczmarek
<andrzej.kaczmarek@tieto.com> wrote:
> ---
> android/a2dp.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/android/a2dp.c b/android/a2dp.c
> index 9b168ed..2288912 100644
> --- a/android/a2dp.c
> +++ b/android/a2dp.c
> @@ -1262,7 +1262,7 @@ static void bt_stream_open(const void *buf, uint16_t len)
> return;
> }
>
> - if (avdtp_stream_get_transport(setup->stream, &fd, NULL, NULL, NULL)) {
> + if (!avdtp_stream_get_transport(setup->stream, &fd, NULL, NULL, NULL)) {
> error("avdtp_stream_get_transport: failed");
> audio_ipc_send_rsp(AUDIO_OP_OPEN_STREAM, AUDIO_STATUS_FAILED);
> return;
> --
> 1.8.5.2
Applied, thanks.
--
Luiz Augusto von Dentz
^ permalink raw reply
* [PATCH] android/a2dp: Fix typo in condition
From: Andrzej Kaczmarek @ 2014-01-16 15:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
---
android/a2dp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/android/a2dp.c b/android/a2dp.c
index 9b168ed..2288912 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -1262,7 +1262,7 @@ static void bt_stream_open(const void *buf, uint16_t len)
return;
}
- if (avdtp_stream_get_transport(setup->stream, &fd, NULL, NULL, NULL)) {
+ if (!avdtp_stream_get_transport(setup->stream, &fd, NULL, NULL, NULL)) {
error("avdtp_stream_get_transport: failed");
audio_ipc_send_rsp(AUDIO_OP_OPEN_STREAM, AUDIO_STATUS_FAILED);
return;
--
1.8.5.2
^ permalink raw reply related
* [PATCH] add firmware update for Atheros 0cf3:311f
From: oliver @ 2014-01-16 15:02 UTC (permalink / raw)
To: acho, marcel, gustavo, johan.hedberg, linux-bluetooth
Cc: Oliver Neukum, Oliver Neukum
In-Reply-To: <1389884578-18479-1-git-send-email-oliver@neukum.org>
From: Oliver Neukum <oliver@neukum.org>
The device is not functional without firmware.
The device without firmware:
T: Bus=02 Lev=02 Prnt=02 Port=05 Cnt=01 Dev#= 3 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=0cf3 ProdID=311f Rev=00.01
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
I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
The device with firmware:
T: Bus=02 Lev=02 Prnt=02 Port=05 Cnt=01 Dev#= 4 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=0cf3 ProdID=3007 Rev=00.01
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
I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
Signed-off-by: Oliver Neukum <oneukum@suse.de>
---
drivers/bluetooth/ath3k.c | 2 ++
drivers/bluetooth/btusb.c | 1 +
2 files changed, 3 insertions(+)
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index b0a875b..3822621 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -78,6 +78,7 @@ static const struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x0CF3, 0x3008) },
{ USB_DEVICE(0x0CF3, 0x311D) },
{ USB_DEVICE(0x0CF3, 0x311E) },
+ { USB_DEVICE(0x0CF3, 0x311F) },
{ USB_DEVICE(0x0CF3, 0x817a) },
{ USB_DEVICE(0x13d3, 0x3375) },
{ USB_DEVICE(0x04CA, 0x3004) },
@@ -121,6 +122,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311E), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0cf3, 0x311F), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index e15b580..9f61dde 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -145,6 +145,7 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0cf3, 0x311f), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
--
1.8.4
^ permalink raw reply related
* [PATCH] add firmware update for Atheros 0cf3:311f
From: oliver @ 2014-01-16 15:02 UTC (permalink / raw)
To: acho, marcel, gustavo, johan.hedberg, linux-bluetooth
Cc: Oliver Neukum, Oliver Neukum
From: Oliver Neukum <oliver@neukum.org>
The device is not functional without firmware.
The device without firmware:
T: Bus=02 Lev=02 Prnt=02 Port=05 Cnt=01 Dev#= 3 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=0cf3 ProdID=311f Rev=00.01
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
I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
The device with firmware:
T: Bus=02 Lev=02 Prnt=02 Port=05 Cnt=01 Dev#= 4 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=0cf3 ProdID=3007 Rev=00.01
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
I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
Signed-off-by: Oliver Neukum <oneukum@suse.de>
---
drivers/bluetooth/ath3k.c | 2 ++
drivers/bluetooth/btusb.c | 1 +
2 files changed, 3 insertions(+)
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index b0a875b..3822621 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -78,6 +78,7 @@ static const struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x0CF3, 0x3008) },
{ USB_DEVICE(0x0CF3, 0x311D) },
{ USB_DEVICE(0x0CF3, 0x311E) },
+ { USB_DEVICE(0x0CF3, 0x311F) },
{ USB_DEVICE(0x0CF3, 0x817a) },
{ USB_DEVICE(0x13d3, 0x3375) },
{ USB_DEVICE(0x04CA, 0x3004) },
@@ -121,6 +122,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311E), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0cf3, 0x311F), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index e15b580..9f61dde 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -145,6 +145,7 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0cf3, 0x311f), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
--
1.8.4
^ permalink raw reply related
* [PATCH 2/2] android: Add l2ping to debug builds
From: Andrzej Kaczmarek @ 2014-01-16 14:52 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1389883945-10707-1-git-send-email-andrzej.kaczmarek@tieto.com>
---
android/Android.mk | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/android/Android.mk b/android/Android.mk
index b3e6a50..d2009d7 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -318,3 +318,25 @@ LOCAL_MODULE_TAGS := debug
LOCAL_MODULE := btmgmt
include $(BUILD_EXECUTABLE)
+
+#
+# l2ping
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ ../tools/l2ping.c \
+ ../lib/bluetooth.c \
+ ../lib/hci.c \
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/../lib \
+
+LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS)
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE := l2ping
+
+include $(BUILD_EXECUTABLE)
--
1.8.5.2
^ 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