Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCHv1 6/8] android/hal: Add debug prints for every HAL callback
From: Andrei Emeltchenko @ 2013-11-01 13:41 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1383313305-9442-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

This allows us to trace callbacks to Java.
---
 android/hal-bluetooth.c |   14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 91c5f97..7334d24 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -153,6 +153,8 @@ static void handle_adapter_props_changed(void *buf, uint16_t len)
 	struct hal_ev_adapter_props_changed *ev = buf;
 	bt_property_t props[ev->num_props];
 
+	DBG("");
+
 	if (!bt_hal_cbacks->adapter_properties_cb)
 		return;
 
@@ -168,6 +170,8 @@ static void handle_bond_state_change(void *buf)
 	struct hal_ev_bond_state_changed *ev = buf;
 	bt_bdaddr_t *addr = (bt_bdaddr_t *) ev->bdaddr;
 
+	DBG("state %u", ev->state);
+
 	if (bt_hal_cbacks->bond_state_changed_cb)
 		bt_hal_cbacks->bond_state_changed_cb(ev->status, addr,
 								ev->state);
@@ -180,6 +184,8 @@ static void handle_pin_request(void *buf)
 	bt_bdaddr_t *addr = (bt_bdaddr_t *) ev->bdaddr;
 	bt_bdname_t *name = (bt_bdname_t *) ev->name;
 
+	DBG("");
+
 	if (bt_hal_cbacks->pin_request_cb)
 		bt_hal_cbacks->pin_request_cb(addr, name, ev->class_of_dev);
 }
@@ -191,6 +197,8 @@ static void handle_ssp_request(void *buf)
 	bt_bdaddr_t *addr = (bt_bdaddr_t *) ev->bdaddr;
 	bt_bdname_t *name = (bt_bdname_t *) ev->name;
 
+	DBG("");
+
 	if (bt_hal_cbacks->ssp_request_cb)
 		bt_hal_cbacks->ssp_request_cb(addr, name, ev->class_of_dev,
 							ev->pairing_variant,
@@ -218,6 +226,8 @@ static void handle_discovery_state_changed(void *buf)
 {
 	struct hal_ev_discovery_state_changed *ev = buf;
 
+	DBG("");
+
 	if (bt_hal_cbacks->discovery_state_changed_cb)
 		bt_hal_cbacks->discovery_state_changed_cb(ev->state);
 }
@@ -227,6 +237,8 @@ static void handle_device_found(void *buf, uint16_t len)
 	struct hal_ev_device_found *ev = buf;
 	bt_property_t props[ev->num_props];
 
+	DBG("");
+
 	if (!bt_hal_cbacks->device_found_cb)
 		return;
 
@@ -242,6 +254,8 @@ static void handle_device_state_changed(void *buf, uint16_t len)
 	struct hal_ev_remote_device_props *ev = buf;
 	bt_property_t props[ev->num_props];
 
+	DBG("");
+
 	if (!bt_hal_cbacks->remote_device_properties_cb)
 		return;
 
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 5/8] android/daemon: Add debug handlers for unhandled mgmt event
From: Andrei Emeltchenko @ 2013-11-01 13:41 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1383313305-9442-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Add debug prints to some mgmt events.
---
 android/adapter.c |   27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/android/adapter.c b/android/adapter.c
index 5a5fa2e..299a025 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -651,6 +651,24 @@ static void mgmt_device_connected_event(uint16_t index, uint16_t length,
 			HAL_EV_ACL_STATE_CHANGED, sizeof(hal_ev), &hal_ev, -1);
 }
 
+static void mgmt_connect_failed_event(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	DBG("");
+}
+
+static void mgmt_auth_failed_event(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	DBG("");
+}
+
+static void mgmt_device_unpaired_event(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	DBG("");
+}
+
 static void register_mgmt_handlers(void)
 {
 	mgmt_register(adapter->mgmt, MGMT_EV_NEW_SETTINGS, adapter->index,
@@ -691,6 +709,15 @@ static void register_mgmt_handlers(void)
 
 	mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_CONNECTED, adapter->index,
 				mgmt_device_connected_event, NULL, NULL);
+
+	mgmt_register(adapter->mgmt, MGMT_EV_CONNECT_FAILED, adapter->index,
+				mgmt_connect_failed_event, NULL, NULL);
+
+	mgmt_register(adapter->mgmt, MGMT_EV_AUTH_FAILED, adapter->index,
+				mgmt_auth_failed_event, NULL, NULL);
+
+	mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_UNPAIRED, adapter->index,
+				mgmt_device_unpaired_event, NULL, NULL);
 }
 
 static void load_link_keys_complete(uint8_t status, uint16_t length,
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 4/8] android/hal: Handle acl_state_changed event
From: Andrei Emeltchenko @ 2013-11-01 13:41 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1383313305-9442-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

---
 android/hal-bluetooth.c |   15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index a0ee844..91c5f97 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -254,6 +254,18 @@ static void handle_device_state_changed(void *buf, uint16_t len)
 	device_hal_props_cleanup(props, ev->num_props);
 }
 
+static void handle_acl_state_changed(void *buf)
+{
+	struct hal_ev_acl_state_changed *ev = buf;
+	bt_bdaddr_t *addr = (bt_bdaddr_t *) ev->bdaddr;
+
+	DBG("state %u", ev->state);
+
+	if (bt_hal_cbacks->acl_state_changed_cb)
+		bt_hal_cbacks->acl_state_changed_cb(ev->status, addr,
+								ev->state);
+}
+
 /* will be called from notification thread context */
 void bt_notify_adapter(uint16_t opcode, void *buf, uint16_t len)
 {
@@ -287,6 +299,9 @@ void bt_notify_adapter(uint16_t opcode, void *buf, uint16_t len)
 	case HAL_EV_SSP_REQUEST:
 		handle_ssp_request(buf);
 		break;
+	case HAL_EV_ACL_STATE_CHANGED:
+		handle_acl_state_changed(buf);
+		break;
 	default:
 		DBG("Unhandled callback opcode=0x%x", opcode);
 		break;
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 3/8] android/daemon: Implement mgmt device connected event
From: Andrei Emeltchenko @ 2013-11-01 13:41 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1383313305-9442-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Send HAL_EV_ACL_STATE_CHANGED event to HAL through IPC.
---
 android/adapter.c |   26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/android/adapter.c b/android/adapter.c
index 5ce0797..5a5fa2e 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -628,6 +628,29 @@ static void mgmt_device_found_event(uint16_t index, uint16_t length,
 						confirm_name, eir, eir_len);
 }
 
+static void mgmt_device_connected_event(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	const struct mgmt_ev_device_connected *ev = param;
+	struct hal_ev_acl_state_changed hal_ev;
+
+	if (length < sizeof(*ev)) {
+		error("Too short device connected event (%u bytes)", length);
+		return;
+	}
+
+	/* TODO: Update device */
+
+	/* TODO: Check Set bonding state */
+
+	hal_ev.status = HAL_STATUS_SUCCESS;
+	hal_ev.state = HAL_ACL_STATE_CONNECTED;
+	bdaddr2android(&ev->addr.bdaddr, hal_ev.bdaddr);
+
+	ipc_send(notification_io, HAL_SERVICE_ID_BLUETOOTH,
+			HAL_EV_ACL_STATE_CHANGED, sizeof(hal_ev), &hal_ev, -1);
+}
+
 static void register_mgmt_handlers(void)
 {
 	mgmt_register(adapter->mgmt, MGMT_EV_NEW_SETTINGS, adapter->index,
@@ -665,6 +688,9 @@ static void register_mgmt_handlers(void)
 	mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_FOUND,
 					adapter->index, mgmt_device_found_event,
 					NULL, NULL);
+
+	mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_CONNECTED, adapter->index,
+				mgmt_device_connected_event, NULL, NULL);
 }
 
 static void load_link_keys_complete(uint8_t status, uint16_t length,
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 2/8] android/ipc: Update HAL IPC header
From: Andrei Emeltchenko @ 2013-11-01 13:41 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1383313305-9442-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Add ACL states to the header.
---
 android/hal-msg.h |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index 8a344d8..1d256f2 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -405,6 +405,9 @@ struct hal_ev_bond_state_changed {
 	uint8_t state;
 } __attribute__((packed));
 
+#define HAL_ACL_STATE_CONNECTED		0x00
+#define HAL_ACL_STATE_DISCONNECTED	0x01
+
 #define HAL_EV_ACL_STATE_CHANGED	0x89
 struct hal_ev_acl_state_changed {
 	uint8_t status;
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv1 1/8] android/haltest: Fix print device name
From: Andrei Emeltchenko @ 2013-11-01 13:41 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

---
 android/client/textconv.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/android/client/textconv.c b/android/client/textconv.c
index effd1b3..8e6bdb9 100644
--- a/android/client/textconv.c
+++ b/android/client/textconv.c
@@ -258,8 +258,7 @@ char *btproperty2str(const bt_property_t *property)
 	switch (property->type) {
 	case BT_PROPERTY_BDNAME:
 	case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
-		sprintf(p, "%*s", property->len,
-					((bt_bdname_t *) property->val)->name);
+		sprintf(p, "%s", ((bt_bdname_t *) property->val)->name);
 		break;
 
 	case BT_PROPERTY_BDADDR:
-- 
1.7.10.4


^ permalink raw reply related

* RE: l2cap sockets not properly multiplexed on ARM
From: Tim Tisdall @ 2013-11-01 13:35 UTC (permalink / raw)
  To: Anderson Lizardo, Marcel Holtmann
  Cc: Alexander Holler, linux-bluetooth@vger.kernel.org
In-Reply-To: <CAJdJm_O1-=-cEKnuSmT026hr1JOkwiRZfC3Q_qagTWOna5JN7w@mail.gmail.com>

>> I actually need to know if bluetooth-next tree still has this issue. Tha=
t is first and foremost the one thing that needs to be checked.=0A=
=0A=
> I asked Tim to mention the kernel version on x86 vs. the version on=0A=
> ARM, because I vaguely remember this same issue being reported last=0A=
> year (or even 2011) and being fixed (If I find the patch, I will let=0A=
> you know). As Tim mentions later on, on x86 the issue does not happen=0A=
> on 3.8, but it is present on 3.2 (and I suspect it will also be=0A=
> present on 3.4 on x86 as well).=0A=
=0A=
I was going to say yesterday (until my computer suddenly died due to overhe=
ating):  Can't it be assumed that it's okay in bluetooth-next since the iss=
ue seems to be gone with kernels > 3.4?=0A=
=0A=
I was trying to get a 3.4.67 kernel running on one ARM device but unfortuna=
tely I can't seem to get the bluetooth dongle to be recognized (something t=
o do with the USB code, I suspect).  It's probably still an issue, though, =
so I'd really appreciate if you managed to find that patch!=0A=
=0A=
-Tim=0A=
=0A=

^ permalink raw reply

* Re: BUG in rfcomm_sock_getsockopt+0x128/0x200
From: Marcel Holtmann @ 2013-11-01 13:30 UTC (permalink / raw)
  To: Fabio Rossi
  Cc: linux-wireless@vger.kernel.org Wireless,
	linux-bluetooth@vger.kernel.org development
In-Reply-To: <376684294.1810371383311879389.JavaMail.defaultUser@defaultHost>

Hi Fabio,

> I'm using the latest wireless-testing.git and I have found a problem, I get the 
> following kernel trace:
> 
> BUG: unable to handle kernel paging request at 
> 00000009dd50350a                                                                                                                     
> IP: [<ffffffff815b6768>] 
> rfcomm_sock_getsockopt+0x128/0x200                                                                                                                         
> PGD 
> 0                                                                                                                                                                               
> Oops: 0000 [#1] SMP 
> Modules linked in: vboxpci(O) vboxnetadp(O) vboxnetflt(O) vboxdrv(O) fglrx(PO) 
> ath5k ath mac80211 cfg80211
> CPU: 2 PID: 1475 Comm: bluetoothd Tainted: P           O 3.12.0-rc5-wl #4
> Hardware name: System manufacturer System Product Name/P6T DELUXE V2, BIOS 
> 1202    12/22/2010
> task: ffff88032e9ce360 ti: ffff880330654000 task.ti: ffff880330654000
> RIP: 0010:[<ffffffff815b6768>]  [<ffffffff815b6768>] 
> rfcomm_sock_getsockopt+0x128/0x200
> RSP: 0018:ffff880330655ed8  EFLAGS: 00010246
> RAX: 00000009dd503502 RBX: 0000000000000003 RCX: 00007fff7b30e298
> RDX: 0000000000000003 RSI: 0000000000000012 RDI: ffff8800bad88f00
> RBP: ffff880330655f28 R08: 00007fff7b30e29c R09: ffff8803306734d8
> R10: 00007fff7b30e298 R11: 0000000000000202 R12: ffff8800ba83ec00
> R13: 00007fff7b30e298 R14: 0000000000000003 R15: 00007fff7b30e29c
> FS:  00007f31c1d9d700(0000) GS:ffff88033fc80000(0000) knlGS:0000000000000000
> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00000009dd50350a CR3: 000000033048a000 CR4: 00000000000007e0
> Stack:
> ffff880330655f28 ffffffff815b5e2f ffff880330655f18 0002ffff81107bb6
> 0000000600000000 ffff8800bad88f00 0000000000000012 00007fff7b30e298
> 0000000000000003 00007fff7b30e29c ffff880330655f78 ffffffff814c6260
> Call Trace:
> [<ffffffff815b5e2f>] ? rfcomm_sock_setsockopt+0x5f/0x190
> [<ffffffff814c6260>] SyS_getsockopt+0x60/0xb0
> [<ffffffff815e5ba2>] system_call_fastpath+0x16/0x1b
> Code: 02 00 00 00 0f 47 d0 4c 89 ef e8 94 f0 cc ff 83 f8 01 19 c9 f7 d1 83 e1 
> f2 e9 4b ff ff ff 0f 1f 44 00 00 49 8b 84 24 70 02 00 00 <4c> 8b 70 08 4c 89 c0 
> e8 4c f6 cc ff 85 c0 49 89 d7 b9 f2 ff ff 
> RIP  [<ffffffff815b6768>] rfcomm_sock_getsockopt+0x128/0x200
> RSP <ffff880330655ed8>
> CR2: 00000009dd50350a
> ---[ end trace 6e62d73375e99d69 ]—

what socket option is your client program setting? Do you happen to know that. Would make it a lot easier to track this down.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH BlueZ 1/4] android/hid: Rename hdev vars to dev
From: Johan Hedberg @ 2013-11-01 13:24 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1383311321-28429-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Fri, Nov 01, 2013, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> 
> ---
>  android/hid.c | 248 +++++++++++++++++++++++++++++-----------------------------
>  1 file changed, 124 insertions(+), 124 deletions(-)

All four patches have been applied. Thanks.

Johan

^ permalink raw reply

* BUG in rfcomm_sock_getsockopt+0x128/0x200
From: Fabio Rossi @ 2013-11-01 13:17 UTC (permalink / raw)
  To: linux-wireless, linux-bluetooth

I'm using the latest wireless-testing.git and I have found a problem, I get the 
following kernel trace:

BUG: unable to handle kernel paging request at 
00000009dd50350a                                                                                                                     
IP: [<ffffffff815b6768>] 
rfcomm_sock_getsockopt+0x128/0x200                                                                                                                         
PGD 
0                                                                                                                                                                               
Oops: 0000 [#1] SMP 
Modules linked in: vboxpci(O) vboxnetadp(O) vboxnetflt(O) vboxdrv(O) fglrx(PO) 
ath5k ath mac80211 cfg80211
CPU: 2 PID: 1475 Comm: bluetoothd Tainted: P           O 3.12.0-rc5-wl #4
Hardware name: System manufacturer System Product Name/P6T DELUXE V2, BIOS 
1202    12/22/2010
task: ffff88032e9ce360 ti: ffff880330654000 task.ti: ffff880330654000
RIP: 0010:[<ffffffff815b6768>]  [<ffffffff815b6768>] 
rfcomm_sock_getsockopt+0x128/0x200
RSP: 0018:ffff880330655ed8  EFLAGS: 00010246
RAX: 00000009dd503502 RBX: 0000000000000003 RCX: 00007fff7b30e298
RDX: 0000000000000003 RSI: 0000000000000012 RDI: ffff8800bad88f00
RBP: ffff880330655f28 R08: 00007fff7b30e29c R09: ffff8803306734d8
R10: 00007fff7b30e298 R11: 0000000000000202 R12: ffff8800ba83ec00
R13: 00007fff7b30e298 R14: 0000000000000003 R15: 00007fff7b30e29c
FS:  00007f31c1d9d700(0000) GS:ffff88033fc80000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000009dd50350a CR3: 000000033048a000 CR4: 00000000000007e0
Stack:
 ffff880330655f28 ffffffff815b5e2f ffff880330655f18 0002ffff81107bb6
 0000000600000000 ffff8800bad88f00 0000000000000012 00007fff7b30e298
 0000000000000003 00007fff7b30e29c ffff880330655f78 ffffffff814c6260
Call Trace:
 [<ffffffff815b5e2f>] ? rfcomm_sock_setsockopt+0x5f/0x190
 [<ffffffff814c6260>] SyS_getsockopt+0x60/0xb0
 [<ffffffff815e5ba2>] system_call_fastpath+0x16/0x1b
Code: 02 00 00 00 0f 47 d0 4c 89 ef e8 94 f0 cc ff 83 f8 01 19 c9 f7 d1 83 e1 
f2 e9 4b ff ff ff 0f 1f 44 00 00 49 8b 84 24 70 02 00 00 <4c> 8b 70 08 4c 89 c0 
e8 4c f6 cc ff 85 c0 49 89 d7 b9 f2 ff ff 
RIP  [<ffffffff815b6768>] rfcomm_sock_getsockopt+0x128/0x200
 RSP <ffff880330655ed8>
CR2: 00000009dd50350a
---[ end trace 6e62d73375e99d69 ]---

After bisecting the problem I found the following bad commit:

commit 94a86df01082557e2de45865e538d7fb6c46231c
Author: Marcel Holtmann <marcel@holtmann.org>
Date:   Sun Oct 13 10:34:02 2013 -0700

    Bluetooth: Store RFCOMM address information in its own socket structure
    
    The address information of RFCOMM sockets should be stored in its
    own socket structure. Trying to generalize them is not helpful since
    different transports have different address types.
    
    Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
    Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>

Fabio

^ permalink raw reply

* Re: [PATCH] android/client: Fix pin reply call when pin argument missing in cmd
From: Johan Hedberg @ 2013-11-01 13:11 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: linux-bluetooth
In-Reply-To: <1383308405-17782-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Hi Ravi,

On Fri, Nov 01, 2013, Ravi kumar Veeramally wrote:
> If condition checks number of arguments properly but still executes
> EXEC command. It should display error message and return.
> ---
>  android/client/if-bt.c | 11 +++++++----
>  1 file changed, 7 insertions(+), 4 deletions(-)
> 
> diff --git a/android/client/if-bt.c b/android/client/if-bt.c
> index 3d97458..2c3cc4a 100644
> --- a/android/client/if-bt.c
> +++ b/android/client/if-bt.c
> @@ -719,12 +719,15 @@ static void pin_reply_p(int argc, const char **argv)
>  	RETURN_IF_NULL(if_bluetooth);
>  	VERIFY_ADDR_ARG(2, &addr);
>  
> -	if (argc > 3) {
> -		accept = 1;
> -		pin_len = strlen(argv[3]);
> -		memcpy(pin.pin, argv[3], pin_len);
> +	if (argc != 4) {
> +		haltest_error("Usage <address> <pin>\n");
> +		return;
>  	}
>  
> +	accept = 1;
> +	pin_len = strlen(argv[3]);
> +	memcpy(pin.pin, argv[3], pin_len);
> +
>  	EXEC(if_bluetooth->pin_reply, &addr, accept, pin_len, &pin);

It seems to me that the original code might have been trying to do (if
it hadn't been broken like it now is) a negative pin reply in the case
that no parameter was given. At least I don't see any other code trying
to call if_bluetooth->pin_reply with accept=1 in haltest. So I'd
consider fixing that instead.

Johan

^ permalink raw reply

* [PATCH BlueZ 4/4] android/hid: Add handling of HAL_EV_HID_INFO
From: Luiz Augusto von Dentz @ 2013-11-01 13:08 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1383311321-28429-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/hid.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/android/hid.c b/android/hid.c
index 57ad5e4..6e6f606 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -58,6 +58,7 @@ static GSList *devices = NULL;
 struct hid_device {
 	bdaddr_t	dst;
 	uint8_t		state;
+	uint8_t		subclass;
 	uint16_t	vendor;
 	uint16_t	product;
 	uint16_t	version;
@@ -260,6 +261,28 @@ static gboolean ctrl_watch_cb(GIOChannel *chan, GIOCondition cond,
 	return FALSE;
 }
 
+static void bt_hid_set_info(struct hid_device *dev)
+{
+	struct hal_ev_hid_info ev;
+
+	DBG("");
+
+	bdaddr2android(&dev->dst, ev.bdaddr);
+	ev.attr = 0; /* TODO: Check what is this field */
+	ev.subclass = dev->subclass;
+	ev.app_id = 0; /* TODO: Check what is this field */
+	ev.vendor = dev->vendor;
+	ev.product = dev->product;
+	ev.version = dev->version;
+	ev.country = dev->country;
+	ev.descr_len = dev->rd_size;
+	memset(ev.descr, 0, sizeof(ev.descr));
+	memcpy(ev.descr, dev->rd_data, ev.descr_len);
+
+	ipc_send(notification_io, HAL_SERVICE_ID_HIDHOST, HAL_EV_HID_INFO,
+							sizeof(ev), &ev, -1);
+}
+
 static int uhid_create(struct hid_device *dev)
 {
 	GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_NVAL;
@@ -295,6 +318,8 @@ static int uhid_create(struct hid_device *dev)
 	dev->uhid_watch_id = g_io_add_watch(io, cond, uhid_event_cb, dev);
 	g_io_channel_unref(io);
 
+	bt_hid_set_info(dev);
+
 	return 0;
 }
 
@@ -412,6 +437,10 @@ static void hid_sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 		if (data)
 			dev->country = data->val.uint8;
 
+		data = sdp_data_get(rec, SDP_ATTR_HID_DEVICE_SUBCLASS);
+		if (data)
+			dev->subclass = data->val.uint8;
+
 		data = sdp_data_get(rec, SDP_ATTR_HID_DESCRIPTOR_LIST);
 		if (data) {
 			if (!SDP_IS_SEQ(data->dtd))
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ 3/4] android/hal-hidhost: Add implemention of .hid_info_cb
From: Luiz Augusto von Dentz @ 2013-11-01 13:08 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1383311321-28429-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/hal-hidhost.c | 22 ++++++++++++++++++++++
 android/hal-msg.h     | 14 ++++++++++++++
 2 files changed, 36 insertions(+)

diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
index e148dc2..c20c785 100644
--- a/android/hal-hidhost.c
+++ b/android/hal-hidhost.c
@@ -40,6 +40,25 @@ static void handle_conn_state(void *buf)
 								ev->state);
 }
 
+static void handle_info(void *buf)
+{
+	struct hal_ev_hid_info *ev = buf;
+	bthh_hid_info_t info;
+
+	info.attr_mask = ev->attr;
+	info.sub_class = ev->subclass;
+	info.app_id = ev->app_id;
+	info.vendor_id = ev->vendor;
+	info.product_id = ev->product;
+	info.version = ev->version;
+	info.ctry_code = ev->country;
+	info.dl_len = ev->descr_len;
+	memcpy(info.dsc_list, ev->descr, info.dl_len);
+
+	if (bt_hh_cbacks->hid_info_cb)
+		bt_hh_cbacks->hid_info_cb((bt_bdaddr_t *) ev->bdaddr, info);
+}
+
 /* will be called from notification thread context */
 void bt_notify_hh(uint16_t opcode, void *buf, uint16_t len)
 {
@@ -50,6 +69,9 @@ void bt_notify_hh(uint16_t opcode, void *buf, uint16_t len)
 	case HAL_EV_HID_CONN_STATE:
 		handle_conn_state(buf);
 		break;
+	case HAL_EV_HID_INFO:
+		handle_info(buf);
+		break;
 	default:
 		DBG("Unhandled callback opcode=0x%x", opcode);
 		break;
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 8a344d8..9276a2f 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -439,6 +439,20 @@ struct hal_ev_hid_conn_state {
 	uint8_t state;
 } __attribute__((packed));
 
+#define HAL_EV_HID_INFO			0x82
+struct hal_ev_hid_info {
+	uint8_t bdaddr[6];
+	uint8_t attr;
+	uint8_t subclass;
+	uint8_t app_id;
+	uint16_t vendor;
+	uint16_t product;
+	uint16_t version;
+	uint8_t country;
+	uint16_t descr_len;
+	uint8_t descr[884];
+} __attribute__((packed));
+
 #define HAL_EV_AV_CONNECTION_STATE	0x81
 struct hal_ev_av_connection_state {
 	uint8_t state;
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ 2/4] android/hid: Fix passing vendor id as version to uHID
From: Luiz Augusto von Dentz @ 2013-11-01 13:08 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1383311321-28429-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/hid.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/hid.c b/android/hid.c
index bbdc66a..57ad5e4 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -278,7 +278,7 @@ static int uhid_create(struct hid_device *dev)
 	ev.u.create.bus = BUS_BLUETOOTH;
 	ev.u.create.vendor = dev->vendor;
 	ev.u.create.product = dev->product;
-	ev.u.create.version = dev->vendor;
+	ev.u.create.version = dev->version;
 	ev.u.create.country = dev->country;
 	ev.u.create.rd_size = dev->rd_size;
 	ev.u.create.rd_data = dev->rd_data;
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ 1/4] android/hid: Rename hdev vars to dev
From: Luiz Augusto von Dentz @ 2013-11-01 13:08 UTC (permalink / raw)
  To: linux-bluetooth

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

---
 android/hid.c | 248 +++++++++++++++++++++++++++++-----------------------------
 1 file changed, 124 insertions(+), 124 deletions(-)

diff --git a/android/hid.c b/android/hid.c
index f576548..bbdc66a 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -74,10 +74,10 @@ struct hid_device {
 
 static int device_cmp(gconstpointer s, gconstpointer user_data)
 {
-	const struct hid_device *hdev = s;
+	const struct hid_device *dev = s;
 	const bdaddr_t *dst = user_data;
 
-	return bacmp(&hdev->dst, dst);
+	return bacmp(&dev->dst, dst);
 }
 
 static void uhid_destroy(int fd)
@@ -95,38 +95,38 @@ static void uhid_destroy(int fd)
 	close(fd);
 }
 
-static void hid_device_free(struct hid_device *hdev)
+static void hid_device_free(struct hid_device *dev)
 {
-	if (hdev->ctrl_watch > 0)
-		g_source_remove(hdev->ctrl_watch);
+	if (dev->ctrl_watch > 0)
+		g_source_remove(dev->ctrl_watch);
 
-	if (hdev->intr_watch > 0)
-		g_source_remove(hdev->intr_watch);
+	if (dev->intr_watch > 0)
+		g_source_remove(dev->intr_watch);
 
-	if (hdev->intr_io)
-		g_io_channel_unref(hdev->intr_io);
+	if (dev->intr_io)
+		g_io_channel_unref(dev->intr_io);
 
-	if (hdev->ctrl_io)
-		g_io_channel_unref(hdev->ctrl_io);
+	if (dev->ctrl_io)
+		g_io_channel_unref(dev->ctrl_io);
 
-	if (hdev->uhid_watch_id) {
-		g_source_remove(hdev->uhid_watch_id);
-		hdev->uhid_watch_id = 0;
+	if (dev->uhid_watch_id) {
+		g_source_remove(dev->uhid_watch_id);
+		dev->uhid_watch_id = 0;
 	}
 
-	if (hdev->uhid_fd > 0)
-		uhid_destroy(hdev->uhid_fd);
+	if (dev->uhid_fd > 0)
+		uhid_destroy(dev->uhid_fd);
 
-	g_free(hdev->rd_data);
+	g_free(dev->rd_data);
 
-	devices = g_slist_remove(devices, hdev);
-	g_free(hdev);
+	devices = g_slist_remove(devices, dev);
+	g_free(dev);
 }
 
 static gboolean uhid_event_cb(GIOChannel *io, GIOCondition cond,
 							gpointer user_data)
 {
-	struct hid_device *hdev = user_data;
+	struct hid_device *dev = user_data;
 	struct uhid_event ev;
 	ssize_t bread;
 	int fd;
@@ -151,19 +151,19 @@ static gboolean uhid_event_cb(GIOChannel *io, GIOCondition cond,
 	return TRUE;
 
 failed:
-	hdev->uhid_watch_id = 0;
+	dev->uhid_watch_id = 0;
 	return FALSE;
 }
 
 static gboolean intr_io_watch_cb(GIOChannel *chan, gpointer data)
 {
-	struct hid_device *hdev = data;
+	struct hid_device *dev = data;
 	uint8_t buf[UHID_DATA_MAX];
 	struct uhid_event ev;
 	int fd, bread;
 
 	/* Wait uHID if not ready */
-	if (hdev->uhid_fd < 0)
+	if (dev->uhid_fd < 0)
 		return TRUE;
 
 	fd = g_io_channel_unix_get_fd(chan);
@@ -183,26 +183,26 @@ static gboolean intr_io_watch_cb(GIOChannel *chan, gpointer data)
 	ev.u.input.size = bread - 1;
 	memcpy(ev.u.input.data, &buf[1], ev.u.input.size);
 
-	if (write(hdev->uhid_fd, &ev, sizeof(ev)) < 0)
+	if (write(dev->uhid_fd, &ev, sizeof(ev)) < 0)
 		DBG("write: %s (%d)", strerror(errno), errno);
 
 	return TRUE;
 }
 
-static void bt_hid_set_state(struct hid_device *hdev, uint8_t state)
+static void bt_hid_set_state(struct hid_device *dev, uint8_t state)
 {
 	struct hal_ev_hid_conn_state ev;
 	char address[18];
 
-	if (hdev->state == state)
+	if (dev->state == state)
 		return;
 
-	hdev->state = state;
+	dev->state = state;
 
-	ba2str(&hdev->dst, address);
+	ba2str(&dev->dst, address);
 	DBG("device %s state %u", address, state);
 
-	bdaddr2android(&hdev->dst, ev.bdaddr);
+	bdaddr2android(&dev->dst, ev.bdaddr);
 	ev.state = state;
 
 	ipc_send(notification_io, HAL_SERVICE_ID_HIDHOST,
@@ -212,7 +212,7 @@ static void bt_hid_set_state(struct hid_device *hdev, uint8_t state)
 static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond,
 								gpointer data)
 {
-	struct hid_device *hdev = data;
+	struct hid_device *dev = data;
 
 	if (cond & G_IO_IN)
 		return intr_io_watch_cb(chan, data);
@@ -220,19 +220,19 @@ static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond,
 	/* Checking for ctrl_watch avoids a double g_io_channel_shutdown since
 	 * it's likely that ctrl_watch_cb has been queued for dispatching in
 	 * this mainloop iteration */
-	if ((cond & (G_IO_HUP | G_IO_ERR)) && hdev->ctrl_watch)
+	if ((cond & (G_IO_HUP | G_IO_ERR)) && dev->ctrl_watch)
 		g_io_channel_shutdown(chan, TRUE, NULL);
 
-	hdev->intr_watch = 0;
+	dev->intr_watch = 0;
 
-	if (hdev->intr_io) {
-		g_io_channel_unref(hdev->intr_io);
-		hdev->intr_io = NULL;
+	if (dev->intr_io) {
+		g_io_channel_unref(dev->intr_io);
+		dev->intr_io = NULL;
 	}
 
 	/* Close control channel */
-	if (hdev->ctrl_io && !(cond & G_IO_NVAL))
-		g_io_channel_shutdown(hdev->ctrl_io, TRUE, NULL);
+	if (dev->ctrl_io && !(cond & G_IO_NVAL))
+		g_io_channel_shutdown(dev->ctrl_io, TRUE, NULL);
 
 	return FALSE;
 }
@@ -240,34 +240,34 @@ static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond,
 static gboolean ctrl_watch_cb(GIOChannel *chan, GIOCondition cond,
 								gpointer data)
 {
-	struct hid_device *hdev = data;
+	struct hid_device *dev = data;
 	char address[18];
 
-	ba2str(&hdev->dst, address);
-	bt_hid_set_state(hdev, HAL_HID_STATE_DISCONNECTED);
+	ba2str(&dev->dst, address);
+	bt_hid_set_state(dev, HAL_HID_STATE_DISCONNECTED);
 
 	/* Checking for intr_watch avoids a double g_io_channel_shutdown since
 	 * it's likely that intr_watch_cb has been queued for dispatching in
 	 * this mainloop iteration */
-	if ((cond & (G_IO_HUP | G_IO_ERR)) && hdev->intr_watch)
+	if ((cond & (G_IO_HUP | G_IO_ERR)) && dev->intr_watch)
 		g_io_channel_shutdown(chan, TRUE, NULL);
 
-	if (hdev->intr_io && !(cond & G_IO_NVAL))
-		g_io_channel_shutdown(hdev->intr_io, TRUE, NULL);
+	if (dev->intr_io && !(cond & G_IO_NVAL))
+		g_io_channel_shutdown(dev->intr_io, TRUE, NULL);
 
-	hid_device_free(hdev);
+	hid_device_free(dev);
 
 	return FALSE;
 }
 
-static int uhid_create(struct hid_device *hdev)
+static int uhid_create(struct hid_device *dev)
 {
 	GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_NVAL;
 	GIOChannel *io;
 	struct uhid_event ev;
 
-	hdev->uhid_fd = open(UHID_DEVICE_FILE, O_RDWR | O_CLOEXEC);
-	if (hdev->uhid_fd < 0) {
+	dev->uhid_fd = open(UHID_DEVICE_FILE, O_RDWR | O_CLOEXEC);
+	if (dev->uhid_fd < 0) {
 		error("Failed to open uHID device: %s", strerror(errno));
 		return -errno;
 	}
@@ -276,23 +276,23 @@ static int uhid_create(struct hid_device *hdev)
 	ev.type = UHID_CREATE;
 	strcpy((char *) ev.u.create.name, "bluez-input-device");
 	ev.u.create.bus = BUS_BLUETOOTH;
-	ev.u.create.vendor = hdev->vendor;
-	ev.u.create.product = hdev->product;
-	ev.u.create.version = hdev->vendor;
-	ev.u.create.country = hdev->country;
-	ev.u.create.rd_size = hdev->rd_size;
-	ev.u.create.rd_data = hdev->rd_data;
-
-	if (write(hdev->uhid_fd, &ev, sizeof(ev)) < 0) {
+	ev.u.create.vendor = dev->vendor;
+	ev.u.create.product = dev->product;
+	ev.u.create.version = dev->vendor;
+	ev.u.create.country = dev->country;
+	ev.u.create.rd_size = dev->rd_size;
+	ev.u.create.rd_data = dev->rd_data;
+
+	if (write(dev->uhid_fd, &ev, sizeof(ev)) < 0) {
 		error("Failed to create uHID device: %s", strerror(errno));
-		close(hdev->uhid_fd);
-		hdev->uhid_fd = -1;
+		close(dev->uhid_fd);
+		dev->uhid_fd = -1;
 		return -errno;
 	}
 
-	io = g_io_channel_unix_new(hdev->uhid_fd);
+	io = g_io_channel_unix_new(dev->uhid_fd);
 	g_io_channel_set_encoding(io, NULL, NULL);
-	hdev->uhid_watch_id = g_io_add_watch(io, cond, uhid_event_cb, hdev);
+	dev->uhid_watch_id = g_io_add_watch(io, cond, uhid_event_cb, dev);
 	g_io_channel_unref(io);
 
 	return 0;
@@ -301,21 +301,21 @@ static int uhid_create(struct hid_device *hdev)
 static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err,
 							gpointer user_data)
 {
-	struct hid_device *hdev = user_data;
+	struct hid_device *dev = user_data;
 
 	DBG("");
 
 	if (conn_err)
 		goto failed;
 
-	if (uhid_create(hdev) < 0)
+	if (uhid_create(dev) < 0)
 		goto failed;
 
-	hdev->intr_watch = g_io_add_watch(hdev->intr_io,
+	dev->intr_watch = g_io_add_watch(dev->intr_io,
 				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-				intr_watch_cb, hdev);
+				intr_watch_cb, dev);
 
-	bt_hid_set_state(hdev, HAL_HID_STATE_CONNECTED);
+	bt_hid_set_state(dev, HAL_HID_STATE_CONNECTED);
 
 	return;
 
@@ -324,58 +324,58 @@ failed:
 	 * control channel (if we only do unref GLib will close it only
 	 * after returning control to the mainloop */
 	if (!conn_err)
-		g_io_channel_shutdown(hdev->intr_io, FALSE, NULL);
+		g_io_channel_shutdown(dev->intr_io, FALSE, NULL);
 
-	g_io_channel_unref(hdev->intr_io);
-	hdev->intr_io = NULL;
+	g_io_channel_unref(dev->intr_io);
+	dev->intr_io = NULL;
 
-	if (hdev->ctrl_io) {
-		g_io_channel_unref(hdev->ctrl_io);
-		hdev->ctrl_io = NULL;
+	if (dev->ctrl_io) {
+		g_io_channel_unref(dev->ctrl_io);
+		dev->ctrl_io = NULL;
 	}
 }
 
 static void control_connect_cb(GIOChannel *chan, GError *conn_err,
 							gpointer user_data)
 {
-	struct hid_device *hdev = user_data;
+	struct hid_device *dev = user_data;
 	GError *err = NULL;
 	const bdaddr_t *src = bt_adapter_get_address();
 
 	DBG("");
 
 	if (conn_err) {
-		bt_hid_set_state(hdev, HAL_HID_STATE_DISCONNECTED);
+		bt_hid_set_state(dev, HAL_HID_STATE_DISCONNECTED);
 		error("%s", conn_err->message);
 		goto failed;
 	}
 
 	/* Connect to the HID interrupt channel */
-	hdev->intr_io = bt_io_connect(interrupt_connect_cb, hdev, NULL, &err,
+	dev->intr_io = bt_io_connect(interrupt_connect_cb, dev, NULL, &err,
 					BT_IO_OPT_SOURCE_BDADDR, src,
-					BT_IO_OPT_DEST_BDADDR, &hdev->dst,
+					BT_IO_OPT_DEST_BDADDR, &dev->dst,
 					BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR,
 					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
 					BT_IO_OPT_INVALID);
-	if (!hdev->intr_io) {
+	if (!dev->intr_io) {
 		error("%s", err->message);
 		g_error_free(err);
 		goto failed;
 	}
 
-	hdev->ctrl_watch = g_io_add_watch(hdev->ctrl_io,
+	dev->ctrl_watch = g_io_add_watch(dev->ctrl_io,
 					G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-					ctrl_watch_cb, hdev);
+					ctrl_watch_cb, dev);
 
 	return;
 
 failed:
-	hid_device_free(hdev);
+	hid_device_free(dev);
 }
 
 static void hid_sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 {
-	struct hid_device *hdev = data;
+	struct hid_device *dev = data;
 	sdp_list_t *list;
 	GError *gerr = NULL;
 	const bdaddr_t *src = bt_adapter_get_address();
@@ -398,19 +398,19 @@ static void hid_sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 
 		data = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
 		if (data)
-			hdev->vendor = data->val.uint16;
+			dev->vendor = data->val.uint16;
 
 		data = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
 		if (data)
-			hdev->product = data->val.uint16;
+			dev->product = data->val.uint16;
 
 		data = sdp_data_get(rec, SDP_ATTR_VERSION);
 		if (data)
-			hdev->version = data->val.uint16;
+			dev->version = data->val.uint16;
 
 		data = sdp_data_get(rec, SDP_ATTR_HID_COUNTRY_CODE);
 		if (data)
-			hdev->country = data->val.uint8;
+			dev->country = data->val.uint8;
 
 		data = sdp_data_get(rec, SDP_ATTR_HID_DESCRIPTOR_LIST);
 		if (data) {
@@ -432,20 +432,20 @@ static void hid_sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 			if (!data || !SDP_IS_TEXT_STR(data->dtd))
 				goto fail;
 
-			hdev->rd_size = data->unitSize;
-			hdev->rd_data = g_memdup(data->val.str, data->unitSize);
+			dev->rd_size = data->unitSize;
+			dev->rd_data = g_memdup(data->val.str, data->unitSize);
 		}
 	}
 
-	if (hdev->ctrl_io) {
-		if (uhid_create(hdev) < 0)
+	if (dev->ctrl_io) {
+		if (uhid_create(dev) < 0)
 			goto fail;
 		return;
 	}
 
-	hdev->ctrl_io = bt_io_connect(control_connect_cb, hdev, NULL, &gerr,
+	dev->ctrl_io = bt_io_connect(control_connect_cb, dev, NULL, &gerr,
 					BT_IO_OPT_SOURCE_BDADDR, src,
-					BT_IO_OPT_DEST_BDADDR, &hdev->dst,
+					BT_IO_OPT_DEST_BDADDR, &dev->dst,
 					BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
 					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
 					BT_IO_OPT_INVALID);
@@ -458,13 +458,13 @@ static void hid_sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 	return;
 
 fail:
-	bt_hid_set_state(hdev, HAL_HID_STATE_DISCONNECTED);
-	hid_device_free(hdev);
+	bt_hid_set_state(dev, HAL_HID_STATE_DISCONNECTED);
+	hid_device_free(dev);
 }
 
 static uint8_t bt_hid_connect(struct hal_cmd_hid_connect *cmd, uint16_t len)
 {
-	struct hid_device *hdev;
+	struct hid_device *dev;
 	char addr[18];
 	bdaddr_t dst;
 	GSList *l;
@@ -482,23 +482,23 @@ static uint8_t bt_hid_connect(struct hal_cmd_hid_connect *cmd, uint16_t len)
 	if (l)
 		return HAL_STATUS_FAILED;
 
-	hdev = g_new0(struct hid_device, 1);
-	bacpy(&hdev->dst, &dst);
-	hdev->uhid_fd = -1;
+	dev = g_new0(struct hid_device, 1);
+	bacpy(&dev->dst, &dst);
+	dev->uhid_fd = -1;
 
-	ba2str(&hdev->dst, addr);
+	ba2str(&dev->dst, addr);
 	DBG("connecting to %s", addr);
 
 	bt_string2uuid(&uuid, HID_UUID);
-	if (bt_search_service(src, &hdev->dst, &uuid, hid_sdp_search_cb, hdev,
+	if (bt_search_service(src, &dev->dst, &uuid, hid_sdp_search_cb, dev,
 								NULL) < 0) {
 		error("Failed to search sdp details");
-		hid_device_free(hdev);
+		hid_device_free(dev);
 		return HAL_STATUS_FAILED;
 	}
 
-	devices = g_slist_append(devices, hdev);
-	bt_hid_set_state(hdev, HAL_HID_STATE_CONNECTING);
+	devices = g_slist_append(devices, dev);
+	bt_hid_set_state(dev, HAL_HID_STATE_CONNECTING);
 
 	return HAL_STATUS_SUCCESS;
 }
@@ -506,7 +506,7 @@ static uint8_t bt_hid_connect(struct hal_cmd_hid_connect *cmd, uint16_t len)
 static uint8_t bt_hid_disconnect(struct hal_cmd_hid_disconnect *cmd,
 								uint16_t len)
 {
-	struct hid_device *hdev;
+	struct hid_device *dev;
 	GSList *l;
 	bdaddr_t dst;
 
@@ -521,16 +521,16 @@ static uint8_t bt_hid_disconnect(struct hal_cmd_hid_disconnect *cmd,
 	if (!l)
 		return HAL_STATUS_FAILED;
 
-	hdev = l->data;
+	dev = l->data;
 
 	/* Wait either channels to HUP */
-	if (hdev->intr_io)
-		g_io_channel_shutdown(hdev->intr_io, TRUE, NULL);
+	if (dev->intr_io)
+		g_io_channel_shutdown(dev->intr_io, TRUE, NULL);
 
-	if (hdev->ctrl_io)
-		g_io_channel_shutdown(hdev->ctrl_io, TRUE, NULL);
+	if (dev->ctrl_io)
+		g_io_channel_shutdown(dev->ctrl_io, TRUE, NULL);
 
-	bt_hid_set_state(hdev, HAL_HID_STATE_DISCONNECTING);
+	bt_hid_set_state(dev, HAL_HID_STATE_DISCONNECTING);
 
 	return HAL_STATUS_SUCCESS;
 }
@@ -556,7 +556,7 @@ void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len)
 
 static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 {
-	struct hid_device *hdev;
+	struct hid_device *dev;
 	bdaddr_t dst;
 	char address[18];
 	uint16_t psm;
@@ -589,25 +589,25 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 		if (l)
 			return;
 
-		hdev = g_new0(struct hid_device, 1);
-		bacpy(&hdev->dst, &dst);
-		hdev->ctrl_io = g_io_channel_ref(chan);
-		hdev->uhid_fd = -1;
+		dev = g_new0(struct hid_device, 1);
+		bacpy(&dev->dst, &dst);
+		dev->ctrl_io = g_io_channel_ref(chan);
+		dev->uhid_fd = -1;
 
 		bt_string2uuid(&uuid, HID_UUID);
-		if (bt_search_service(src, &hdev->dst, &uuid,
-					hid_sdp_search_cb, hdev, NULL) < 0) {
+		if (bt_search_service(src, &dev->dst, &uuid,
+					hid_sdp_search_cb, dev, NULL) < 0) {
 			error("failed to search sdp details");
-			hid_device_free(hdev);
+			hid_device_free(dev);
 			return;
 		}
 
-		devices = g_slist_append(devices, hdev);
+		devices = g_slist_append(devices, dev);
 
-		hdev->ctrl_watch = g_io_add_watch(hdev->ctrl_io,
+		dev->ctrl_watch = g_io_add_watch(dev->ctrl_io,
 					G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-					ctrl_watch_cb, hdev);
-		bt_hid_set_state(hdev, HAL_HID_STATE_CONNECTING);
+					ctrl_watch_cb, dev);
+		bt_hid_set_state(dev, HAL_HID_STATE_CONNECTING);
 		break;
 
 	case L2CAP_PSM_HIDP_INTR:
@@ -615,12 +615,12 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 		if (!l)
 			return;
 
-		hdev = l->data;
-		hdev->intr_io = g_io_channel_ref(chan);
-		hdev->intr_watch = g_io_add_watch(hdev->intr_io,
+		dev = l->data;
+		dev->intr_io = g_io_channel_ref(chan);
+		dev->intr_watch = g_io_add_watch(dev->intr_io,
 				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-				intr_watch_cb, hdev);
-		bt_hid_set_state(hdev, HAL_HID_STATE_CONNECTED);
+				intr_watch_cb, dev);
+		bt_hid_set_state(dev, HAL_HID_STATE_CONNECTED);
 		break;
 	}
 }
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH] android/client: Fix pin reply call when pin argument missing in cmd
From: Ravi kumar Veeramally @ 2013-11-01 12:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

If condition checks number of arguments properly but still executes
EXEC command. It should display error message and return.
---
 android/client/if-bt.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/android/client/if-bt.c b/android/client/if-bt.c
index 3d97458..2c3cc4a 100644
--- a/android/client/if-bt.c
+++ b/android/client/if-bt.c
@@ -719,12 +719,15 @@ static void pin_reply_p(int argc, const char **argv)
 	RETURN_IF_NULL(if_bluetooth);
 	VERIFY_ADDR_ARG(2, &addr);
 
-	if (argc > 3) {
-		accept = 1;
-		pin_len = strlen(argv[3]);
-		memcpy(pin.pin, argv[3], pin_len);
+	if (argc != 4) {
+		haltest_error("Usage <address> <pin>\n");
+		return;
 	}
 
+	accept = 1;
+	pin_len = strlen(argv[3]);
+	memcpy(pin.pin, argv[3], pin_len);
+
 	EXEC(if_bluetooth->pin_reply, &addr, accept, pin_len, &pin);
 }
 
-- 
1.8.1.2


^ permalink raw reply related

* Re: [RFC] android/daemon: Update CoD and RSSI only when they exist
From: Johan Hedberg @ 2013-11-01 12:07 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1383306399-13750-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Fri, Nov 01, 2013, Andrei Emeltchenko wrote:
> This avoid sending zeroed Class of Device and making it unidentified.
> ...
>  prop[0]: type=BT_PROPERTY_CLASS_OF_DEVICE len=4 val=000000
>  prop[1]: type=BT_PROPERTY_REMOTE_RSSI len=1 val=-75
>  prop[2]: type=BT_PROPERTY_BDNAME len=249 val=Microsoft Bluetooth Number Pad
> ...
> ---
>  android/adapter.c |   30 +++++++++++++++++-------------
>  1 file changed, 17 insertions(+), 13 deletions(-)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [RFC 1/6] android/daemon: Implement mgmt device connected event
From: Johan Hedberg @ 2013-11-01 12:06 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1383305418-13619-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Fri, Nov 01, 2013, Andrei Emeltchenko wrote:
> Send HAL_EV_ACL_STATE_CHANGED event to HAL through IPC.
> ---
>  android/adapter.c |   26 ++++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)

This doesn't compile:

  CC       android/adapter.o
android/adapter.c: In function ‘mgmt_device_connected_event’:
android/adapter.c:641:17: error: ‘HAL_ACL_STATE_CONNECTED’ undeclared (first use in this function)
  hal_ev.state = HAL_ACL_STATE_CONNECTED;
                 ^
android/adapter.c:641:17: note: each undeclared identifier is reported only once for each function it appears in
make[1]: *** [android/adapter.o] Error 1

> +	if (length < sizeof(*ev)) {
> +		error("Too short %s (%u bytes)", __func__, length);
> +		return;
> +	}

This looks a bit weird. The function is not too short but the message
is, not to mention that having to use __func__ for error logs is a bit
counterintuitive. Just put "device connected event" into the string.
Same goes for your device disconnected event patch.

Johan

^ permalink raw reply

* [RFC] android/daemon: Update CoD and RSSI only when they exist
From: Andrei Emeltchenko @ 2013-11-01 11:46 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

This avoid sending zeroed Class of Device and making it unidentified.
...
 prop[0]: type=BT_PROPERTY_CLASS_OF_DEVICE len=4 val=000000
 prop[1]: type=BT_PROPERTY_REMOTE_RSSI len=1 val=-75
 prop[2]: type=BT_PROPERTY_BDNAME len=249 val=Microsoft Bluetooth Number Pad
...
---
 android/adapter.c |   30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/android/adapter.c b/android/adapter.c
index 39389ee..314f711 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -454,19 +454,23 @@ static int fill_device_props(struct hal_property *prop, bdaddr_t *addr,
 {
 	uint8_t num_props = 0;
 
-	/* fill cod */
-	prop->type = HAL_PROP_DEVICE_CLASS;
-	prop->len = sizeof(cod);
-	memcpy(prop->val, &cod, prop->len);
-	prop = ((void *) prop) + sizeof(*prop) + sizeof(cod);
-	num_props++;
-
-	/* fill rssi */
-	prop->type = HAL_PROP_DEVICE_RSSI;
-	prop->len = sizeof(rssi);
-	memcpy(prop->val, &rssi, prop->len);
-	prop = ((void *) prop) + sizeof(*prop) + sizeof(rssi);
-	num_props++;
+	/* fill Class of Device */
+	if (cod) {
+		prop->type = HAL_PROP_DEVICE_CLASS;
+		prop->len = sizeof(cod);
+		memcpy(prop->val, &cod, prop->len);
+		prop = ((void *) prop) + sizeof(*prop) + sizeof(cod);
+		num_props++;
+	}
+
+	/* fill RSSI */
+	if (rssi) {
+		prop->type = HAL_PROP_DEVICE_RSSI;
+		prop->len = sizeof(rssi);
+		memcpy(prop->val, &rssi, prop->len);
+		prop = ((void *) prop) + sizeof(*prop) + sizeof(rssi);
+		num_props++;
+	}
 
 	/* fill name */
 	if (name) {
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 6/6] android/daemon: Add handler for device disconnected
From: Andrei Emeltchenko @ 2013-11-01 11:30 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1383305418-13619-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Send event to callback thread which shall call acl state change callback.
---
 android/adapter.c |   27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/android/adapter.c b/android/adapter.c
index bc4492b..39389ee 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -643,6 +643,29 @@ static void mgmt_device_connected_event(uint16_t index, uint16_t length,
 			HAL_EV_ACL_STATE_CHANGED, sizeof(hal_ev), &hal_ev, -1);
 }
 
+static void mgmt_device_disconnected_event(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	const struct mgmt_ev_device_disconnected *ev = param;
+	struct hal_ev_acl_state_changed hal_ev;
+
+	if (length < sizeof(*ev)) {
+		error("Too short %s (%u bytes)", __func__, length);
+		return;
+	}
+
+	/* TODO: Update device */
+
+	/* TODO: Check Set bonding state */
+
+	hal_ev.status = HAL_STATUS_SUCCESS;
+	hal_ev.state = HAL_ACL_STATE_DISCONNECTED;
+	bdaddr2android(&ev->addr.bdaddr, &hal_ev.bdaddr);
+
+	ipc_send(notification_io, HAL_SERVICE_ID_BLUETOOTH,
+			HAL_EV_ACL_STATE_CHANGED, sizeof(hal_ev), &hal_ev, -1);
+}
+
 static void mgmt_connect_failed_event(uint16_t index, uint16_t length,
 					const void *param, void *user_data)
 {
@@ -696,6 +719,10 @@ static void register_mgmt_handlers(void)
 	mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_CONNECTED, adapter->index,
 				mgmt_device_connected_event, NULL, NULL);
 
+	mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_DISCONNECTED,
+				adapter->index, mgmt_device_disconnected_event,
+				NULL, NULL);
+
 	mgmt_register(adapter->mgmt, MGMT_EV_CONNECT_FAILED, adapter->index,
 				mgmt_connect_failed_event, NULL, NULL);
 
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 5/6] android/hal: Add debug prints for every HAL callback
From: Andrei Emeltchenko @ 2013-11-01 11:30 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1383305418-13619-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

This allows us to trace callbacks to Java.
---
 android/hal-bluetooth.c |   14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 91c5f97..7334d24 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -153,6 +153,8 @@ static void handle_adapter_props_changed(void *buf, uint16_t len)
 	struct hal_ev_adapter_props_changed *ev = buf;
 	bt_property_t props[ev->num_props];
 
+	DBG("");
+
 	if (!bt_hal_cbacks->adapter_properties_cb)
 		return;
 
@@ -168,6 +170,8 @@ static void handle_bond_state_change(void *buf)
 	struct hal_ev_bond_state_changed *ev = buf;
 	bt_bdaddr_t *addr = (bt_bdaddr_t *) ev->bdaddr;
 
+	DBG("state %u", ev->state);
+
 	if (bt_hal_cbacks->bond_state_changed_cb)
 		bt_hal_cbacks->bond_state_changed_cb(ev->status, addr,
 								ev->state);
@@ -180,6 +184,8 @@ static void handle_pin_request(void *buf)
 	bt_bdaddr_t *addr = (bt_bdaddr_t *) ev->bdaddr;
 	bt_bdname_t *name = (bt_bdname_t *) ev->name;
 
+	DBG("");
+
 	if (bt_hal_cbacks->pin_request_cb)
 		bt_hal_cbacks->pin_request_cb(addr, name, ev->class_of_dev);
 }
@@ -191,6 +197,8 @@ static void handle_ssp_request(void *buf)
 	bt_bdaddr_t *addr = (bt_bdaddr_t *) ev->bdaddr;
 	bt_bdname_t *name = (bt_bdname_t *) ev->name;
 
+	DBG("");
+
 	if (bt_hal_cbacks->ssp_request_cb)
 		bt_hal_cbacks->ssp_request_cb(addr, name, ev->class_of_dev,
 							ev->pairing_variant,
@@ -218,6 +226,8 @@ static void handle_discovery_state_changed(void *buf)
 {
 	struct hal_ev_discovery_state_changed *ev = buf;
 
+	DBG("");
+
 	if (bt_hal_cbacks->discovery_state_changed_cb)
 		bt_hal_cbacks->discovery_state_changed_cb(ev->state);
 }
@@ -227,6 +237,8 @@ static void handle_device_found(void *buf, uint16_t len)
 	struct hal_ev_device_found *ev = buf;
 	bt_property_t props[ev->num_props];
 
+	DBG("");
+
 	if (!bt_hal_cbacks->device_found_cb)
 		return;
 
@@ -242,6 +254,8 @@ static void handle_device_state_changed(void *buf, uint16_t len)
 	struct hal_ev_remote_device_props *ev = buf;
 	bt_property_t props[ev->num_props];
 
+	DBG("");
+
 	if (!bt_hal_cbacks->remote_device_properties_cb)
 		return;
 
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 4/6] android/daemon: Add handlers for auth_failed and connect_failed evt
From: Andrei Emeltchenko @ 2013-11-01 11:30 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1383305418-13619-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Add debug prints in a case connection is failing
---
 android/adapter.c |   18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/android/adapter.c b/android/adapter.c
index df56452..bc4492b 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -643,6 +643,18 @@ static void mgmt_device_connected_event(uint16_t index, uint16_t length,
 			HAL_EV_ACL_STATE_CHANGED, sizeof(hal_ev), &hal_ev, -1);
 }
 
+static void mgmt_connect_failed_event(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	DBG("");
+}
+
+static void mgmt_auth_failed_event(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	DBG("");
+}
+
 static void register_mgmt_handlers(void)
 {
 	mgmt_register(adapter->mgmt, MGMT_EV_NEW_SETTINGS, adapter->index,
@@ -683,6 +695,12 @@ static void register_mgmt_handlers(void)
 
 	mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_CONNECTED, adapter->index,
 				mgmt_device_connected_event, NULL, NULL);
+
+	mgmt_register(adapter->mgmt, MGMT_EV_CONNECT_FAILED, adapter->index,
+				mgmt_connect_failed_event, NULL, NULL);
+
+	mgmt_register(adapter->mgmt, MGMT_EV_AUTH_FAILED, adapter->index,
+				mgmt_auth_failed_event, NULL, NULL);
 }
 
 static void load_link_keys_complete(uint8_t status, uint16_t length,
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 3/6] android/hal: Handle acl_state_changed event
From: Andrei Emeltchenko @ 2013-11-01 11:30 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1383305418-13619-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

---
 android/hal-bluetooth.c |   15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index a0ee844..91c5f97 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -254,6 +254,18 @@ static void handle_device_state_changed(void *buf, uint16_t len)
 	device_hal_props_cleanup(props, ev->num_props);
 }
 
+static void handle_acl_state_changed(void *buf)
+{
+	struct hal_ev_acl_state_changed *ev = buf;
+	bt_bdaddr_t *addr = (bt_bdaddr_t *) ev->bdaddr;
+
+	DBG("state %u", ev->state);
+
+	if (bt_hal_cbacks->acl_state_changed_cb)
+		bt_hal_cbacks->acl_state_changed_cb(ev->status, addr,
+								ev->state);
+}
+
 /* will be called from notification thread context */
 void bt_notify_adapter(uint16_t opcode, void *buf, uint16_t len)
 {
@@ -287,6 +299,9 @@ void bt_notify_adapter(uint16_t opcode, void *buf, uint16_t len)
 	case HAL_EV_SSP_REQUEST:
 		handle_ssp_request(buf);
 		break;
+	case HAL_EV_ACL_STATE_CHANGED:
+		handle_acl_state_changed(buf);
+		break;
 	default:
 		DBG("Unhandled callback opcode=0x%x", opcode);
 		break;
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 2/6] android/ipc: Update HAL IPC header
From: Andrei Emeltchenko @ 2013-11-01 11:30 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1383305418-13619-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Add ACL states to the header.
---
 android/hal-msg.h |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index 8a344d8..1d256f2 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -405,6 +405,9 @@ struct hal_ev_bond_state_changed {
 	uint8_t state;
 } __attribute__((packed));
 
+#define HAL_ACL_STATE_CONNECTED		0x00
+#define HAL_ACL_STATE_DISCONNECTED	0x01
+
 #define HAL_EV_ACL_STATE_CHANGED	0x89
 struct hal_ev_acl_state_changed {
 	uint8_t status;
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 1/6] android/daemon: Implement mgmt device connected event
From: Andrei Emeltchenko @ 2013-11-01 11:30 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Send HAL_EV_ACL_STATE_CHANGED event to HAL through IPC.
---
 android/adapter.c |   26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/android/adapter.c b/android/adapter.c
index 4ddd68b..df56452 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -620,6 +620,29 @@ static void mgmt_device_found_event(uint16_t index, uint16_t length,
 						confirm_name, eir, eir_len);
 }
 
+static void mgmt_device_connected_event(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	const struct mgmt_ev_device_connected *ev = param;
+	struct hal_ev_acl_state_changed hal_ev;
+
+	if (length < sizeof(*ev)) {
+		error("Too short %s (%u bytes)", __func__, length);
+		return;
+	}
+
+	/* TODO: Update device */
+
+	/* TODO: Check Set bonding state */
+
+	hal_ev.status = HAL_STATUS_SUCCESS;
+	hal_ev.state = HAL_ACL_STATE_CONNECTED;
+	bdaddr2android(&ev->addr.bdaddr, &hal_ev.bdaddr);
+
+	ipc_send(notification_io, HAL_SERVICE_ID_BLUETOOTH,
+			HAL_EV_ACL_STATE_CHANGED, sizeof(hal_ev), &hal_ev, -1);
+}
+
 static void register_mgmt_handlers(void)
 {
 	mgmt_register(adapter->mgmt, MGMT_EV_NEW_SETTINGS, adapter->index,
@@ -657,6 +680,9 @@ static void register_mgmt_handlers(void)
 	mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_FOUND,
 					adapter->index, mgmt_device_found_event,
 					NULL, NULL);
+
+	mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_CONNECTED, adapter->index,
+				mgmt_device_connected_event, NULL, NULL);
 }
 
 static void load_link_keys_complete(uint8_t status, uint16_t length,
-- 
1.7.10.4


^ permalink raw reply related


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