Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH 11/11] android/hid: Handle uhid events
From: Andrei Emeltchenko @ 2013-11-05  8:29 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: linux-bluetooth
In-Reply-To: <1383603615-9953-12-git-send-email-ravikumar.veeramally@linux.intel.com>

Hi Ravi,

On Tue, Nov 05, 2013 at 12:20:15AM +0200, Ravi kumar Veeramally wrote:
> Handling few uhid events and described scenarios. OUTPUT and
> FEATURE events are not yet handled.
> ---
>  android/hid.c | 40 +++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 39 insertions(+), 1 deletion(-)
> 
> diff --git a/android/hid.c b/android/hid.c
> index 74de02f..fccaa87 100644
> --- a/android/hid.c
> +++ b/android/hid.c
> @@ -149,6 +149,11 @@ static void hid_device_free(struct hid_device *dev)
>  	g_free(dev);
>  }
>  
> +static void handle_uhid_event(struct hid_device *dev, struct uhid_event *ev)
> +{
> +	DBG("unsupported event");
> +}
> +
>  static gboolean uhid_event_cb(GIOChannel *io, GIOCondition cond,
>  							gpointer user_data)
>  {
> @@ -172,7 +177,40 @@ static gboolean uhid_event_cb(GIOChannel *io, GIOCondition cond,
>  	}
>  
>  	DBG("uHID event type %d received", ev.type);
> -	/* TODO Handle events */
> +
> +	switch (ev.type) {
> +	case UHID_START:
> +	case UHID_STOP:
> +		/* These are called to start and stop the underlying hardware.
> +		 * We open the channels before creating the device so the
> +		 * hardware is always ready. No need to handle these.
> +		 * The kernel never destroys a device itself! Only an explicit
> +		 * UHID_DESTROY request can remove a device. */
> +
> +		break;
> +	case UHID_OPEN:
> +	case UHID_CLOSE:
> +		/* OPEN/CLOSE are sent whenever user-space opens any interface
> +		 * provided by the kernel HID device. Whenever the open-count
> +		 * is non-zero we must be ready for I/O. As long as it is zero,
> +		 * we can decide to drop all I/O and put the device
> +		 * asleep This is optional, though. */
> +		break;
> +	case UHID_OUTPUT:
> +	case UHID_FEATURE:
> +		handle_uhid_event(dev, &ev);
> +		break;
> +	case UHID_OUTPUT_EV:
> +		/* This is only sent by kernels prior to linux-3.11. It
> +		 * requires us to parse HID-descriptors in user-space to
> +		 * properly handle it. This is redundant as the kernel
> +		 * does it already. That's why newer kernels assemble
> +		 * the output-reports and send it to us via UHID_OUTPUT. */
> +		DBG("Unsupported uHID event: type %d", ev.u.output_ev.type);

Use handle_uhid_event helper? You could add printing event type there.

Best regards 
Andrei Emeltchenko 

> +		break;
> +	default:
> +		warn("unexpected uHID event");
> +	}
>  
>  	return TRUE;
>  
> -- 
> 1.8.1.2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 06/11] android/hid: Implement hid get report in daemon
From: Johan Hedberg @ 2013-11-05  8:29 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: linux-bluetooth
In-Reply-To: <1383603615-9953-7-git-send-email-ravikumar.veeramally@linux.intel.com>

Hi Ravi,

On Tue, Nov 05, 2013, Ravi kumar Veeramally wrote:
> This patch requests hid device report and reads reply
> message and sends notification to hal.
> ---
>  android/hal-hidhost.c |   1 +
>  android/hal-msg.h     |   8 ++++
>  android/hid.c         | 104 +++++++++++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 111 insertions(+), 2 deletions(-)

Again, I'd split this into separate patches. One to update the
hal-msg.h, one for the daemon and another for the HAL.

> +#define HAL_EV_HID_GET_REPORT		0x84
> +struct hal_ev_hid_get_report {
> +	uint8_t bdaddr[6];
> +	uint8_t status;
> +	uint16_t len;
> +	uint8_t data[0];
> +} __attribute__((packed));

In our hal-ipc.api.txt this event is defined as 0x85. Not 0x84. Is the
code or documentation wrong?

Also, please follow the same alignment for the variables in the struct
as elsewhere in hal-msg.h.

Johan

^ permalink raw reply

* Re: [PATCH 03/11] android/hid: Implement hid get protocol in daemon
From: Johan Hedberg @ 2013-11-05  8:24 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: linux-bluetooth
In-Reply-To: <1383603615-9953-4-git-send-email-ravikumar.veeramally@linux.intel.com>

Hi Ravi,

On Tue, Nov 05, 2013, Ravi kumar Veeramally wrote:
> This patch requests hid device protocol mode and reads reply
> message and sends notification to hal.
> ---
>  android/hal-msg.h |   9 +++++
>  android/hid.c     | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 113 insertions(+), 4 deletions(-)

I've applied patches 1 and 2, but from this one onwards there were
sevaral issues.

> diff --git a/android/hal-msg.h b/android/hal-msg.h
> index f381862..214daa9 100644
> --- a/android/hal-msg.h
> +++ b/android/hal-msg.h
> @@ -442,6 +442,8 @@ struct hal_ev_hid_conn_state {
>  	uint8_t state;
>  } __attribute__((packed));
>  
> +#define HAL_HID_STATUS_OK		0x00
> +
>  #define HAL_EV_HID_INFO			0x82
>  struct hal_ev_hid_info {
>  	uint8_t bdaddr[6];
> @@ -456,6 +458,13 @@ struct hal_ev_hid_info {
>  	uint8_t descr[884];
>  } __attribute__((packed));
>  
> +#define HAL_EV_HID_PROTO_MODE		0x83
> +struct hal_ev_hid_protocol {
> +	uint8_t bdaddr[6];
> +	uint8_t status;
> +	uint8_t mode;
> +} __attribute__((packed));

To be consistent, shouldn't the struct be called hal_ev_hid_proto_mode?

Also, I'd split this hal-msg.h update into a separate patch. Am I right
to assume hal-ipc-api.txt doesn't need updating for this one?

> @@ -76,6 +84,7 @@ struct hid_device {
>  	guint		intr_watch;
>  	int		uhid_fd;
>  	guint		uhid_watch_id;
> +	int		hid_msg;
>  };
>  
>  static int device_cmp(gconstpointer s, gconstpointer user_data)
> @@ -243,12 +252,74 @@ static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond,
>  	return FALSE;
>  }
>  
> +static void bt_hid_notify_protocol_mode(struct hid_device *dev, uint8_t *buf,
> +									int len)

To be consistent with the struct names you might use "proto" instead of
"protocol" here.

> +static gboolean ctrl_io_watch_cb(GIOChannel *chan, gpointer data)
> +{
> +	struct hid_device *dev = data;
> +	int fd, bread;
> +	uint8_t buf[UHID_DATA_MAX];
> +
> +	DBG("");
> +
> +	fd = g_io_channel_unix_get_fd(chan);
> +	bread = read(fd, buf, sizeof(buf));
> +	if (bread < 0) {
> +		error("read: %s(%d)", strerror(errno), -errno);
> +		return TRUE;
> +	}
> +
> +	switch (dev->hid_msg) {
> +	case HID_MSG_GET_PROTOCOL:
> +		bt_hid_notify_protocol_mode(dev, buf, bread);
> +		break;
> +	default:
> +		DBG("unhandled hid msg type 0x%02x", dev->hid_msg);
> +	}
> +
> +	/* reset msg type request */
> +	dev->hid_msg = -1;

Do we really need to do this tracking of what we wrote to the socket.
Isn't it possible to infer the type of procedure from the content of the
data that we read from the socket?

Johan

^ permalink raw reply

* [PATCH] Bluetooth: Fix to set proper bdaddr_type for RFCOMM connect
From: Seung-Woo Kim @ 2013-11-05  8:15 UTC (permalink / raw)
  To: linux-bluetooth, marcel; +Cc: gustavo, johan.hedberg, sw0312.kim, s.syam
In-Reply-To: <FF845DCC-A87F-4B35-A9A4-0F031DC7CE0B@holtmann.org>

L2CAP socket validates proper bdaddr_type for connect, so this
patch fixes to set explictly bdaddr_type for RFCOMM connect.

Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
---
 net/bluetooth/rfcomm/core.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index ca55ea1..facd8a7 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -720,6 +720,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
 	addr.l2_family = AF_BLUETOOTH;
 	addr.l2_psm    = __constant_cpu_to_le16(RFCOMM_PSM);
 	addr.l2_cid    = 0;
+	addr.l2_bdaddr_type = BDADDR_BREDR;
 	*err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
 	if (*err == 0 || *err == -EINPROGRESS)
 		return s;
-- 
1.7.4.1


^ permalink raw reply related

* Re: [PATCH 1/2] Bluetooth: Remove unneeded check in hci_disconn_complete_evt()
From: Johan Hedberg @ 2013-11-05  8:09 UTC (permalink / raw)
  To: Andre Guedes; +Cc: linux-bluetooth
In-Reply-To: <1383587847-16523-2-git-send-email-andre.guedes@openbossa.org>

Hi Andre,

On Mon, Nov 04, 2013, Andre Guedes wrote:
> According to b644ba336 (patch that introduced HCI_CONN_MGMT_CONNECTED
> flag), the HCI_CONN_MGMT_CONNECTED flag tracks when mgmt has been
> notified about the connection.
> 
> That being said, there is no point in checking this flag in hci_
> disconn_complete_evt() since neither mgmt_disconnect_failed() nor
> mgmt_device_disconnected() depend on it. Below follows more details:
>   * mgmt_disconnect_failed() removes pending MGMT_OP_DISCONNECT
>     commands, it doesn't matter if that connection was notified or not.
>   * mgmt_device_disconnected() sends the mgmt event only if the link
>     type is ACL_LINK or LE_LINK. For those connection type, the flag is
>     always set.
> 
> So this patch removes the HCI_CONN_MGMT_CONNECTED check.
> 
> Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
> ---
>  net/bluetooth/hci_event.c | 16 +++++++---------
>  1 file changed, 7 insertions(+), 9 deletions(-)
> 
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index 142aa61..560296d 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -1792,16 +1792,14 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
>  	if (ev->status == 0)
>  		conn->state = BT_CLOSED;
>  
> -	if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
> -		if (ev->status) {
> -			mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
> -					       conn->dst_type, ev->status);
> -		} else {
> -			u8 reason = hci_to_mgmt_reason(ev->reason);
> +	if (ev->status) {
> +		mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
> +				       conn->dst_type, ev->status);
> +	} else {
> +		u8 reason = hci_to_mgmt_reason(ev->reason);
>  
> -			mgmt_device_disconnected(hdev, &conn->dst, conn->type,
> -						 conn->dst_type, reason);
> -		}
> +		mgmt_device_disconnected(hdev, &conn->dst, conn->type,
> +					 conn->dst_type, reason);
>  	}
>  
>  	if (ev->status == 0) {

It looks to me like this would cause an invalid mgmt_device_disconnected
event to be sent of the ACL goes down before we notify over mgmt that
it's connected. This could e.g. happen if the ACL disconnection happens
before we complete the implicit name resolving (which is the main reason
why this flag exists to begin with). Am I missing something here?

Johan

^ permalink raw reply

* Re: [PATCH] Bluetooth: Fix RFCOMM bind fail for L2CAP sock
From: Marcel Holtmann @ 2013-11-05  7:58 UTC (permalink / raw)
  To: Seung-Woo Kim
  Cc: linux-bluetooth@vger.kernel.org development, Gustavo F. Padovan,
	Johan Hedberg, Syam Sidhardhan
In-Reply-To: <5278A066.5020409@samsung.com>

Hi Seung-Woo,

>>> L2CAP socket bind checks its bdaddr type but RFCOMM kernel thread
>>> does not assign proper bdaddr type for L2CAP sock. This can cause
>>> that RFCOMM failure.
>>> 
>>> Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
>>> ---
>>> The issue is came from following commit, but it is only in bluetooth-next tree,
>>> so this patch is not needed for stable tree.
>>> 
>>> commit 80c1a2e76dbb36588facb265ab364b1302f7ef8c
>>> Author: Johan Hedberg <johan.hedberg@intel.com>
>>> Date:   Mon Oct 14 21:17:52 2013 +0300
>>> 
>>>   Bluetooth: Reject invalid bdaddr types for sockets
>>> 
>>> This patch is based on commit cca34b785a21d220176038c45071ffe842e99fd3 of
>>> bluetooth-next tree.
>>> ---
>>> net/bluetooth/rfcomm/core.c |    2 ++
>>> 1 files changed, 2 insertions(+), 0 deletions(-)
>> 
>> good catch. Patch has been applied to bluetooth-next tree.
>> 
>> You might also want to send a patch that adds the l2_bdaddr_type setting before the connect() call.
> 
> Case of kernel_connect() in rfcomm_session_create(), it reuses
> l2_bdaddr_type used for kernel_bind(), so it works fine for me: I tested
> both incoming connection and outgoing connection cases of rfcomm.
> But if you prefer explicit setting for connect(), please let me know.

I realized that it will just work fine. But it is better style to add an explicit setting in the connect() case as well. It is less error prone in the future.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH] Bluetooth: Fix RFCOMM bind fail for L2CAP sock
From: Seung-Woo Kim @ 2013-11-05  7:38 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: linux-bluetooth@vger.kernel.org development, Gustavo F. Padovan,
	Johan Hedberg, Syam Sidhardhan, Seung-Woo Kim
In-Reply-To: <CE0DCFC3-31E3-4693-9C7C-703CA43A0883@holtmann.org>

Hello Marcel Holtmann,

On 2013년 11월 05일 16:26, Marcel Holtmann wrote:
> Hi Seung-Woo,
> 
>> L2CAP socket bind checks its bdaddr type but RFCOMM kernel thread
>> does not assign proper bdaddr type for L2CAP sock. This can cause
>> that RFCOMM failure.
>>
>> Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
>> ---
>> The issue is came from following commit, but it is only in bluetooth-next tree,
>> so this patch is not needed for stable tree.
>>
>> commit 80c1a2e76dbb36588facb265ab364b1302f7ef8c
>> Author: Johan Hedberg <johan.hedberg@intel.com>
>> Date:   Mon Oct 14 21:17:52 2013 +0300
>>
>>    Bluetooth: Reject invalid bdaddr types for sockets
>>
>> This patch is based on commit cca34b785a21d220176038c45071ffe842e99fd3 of
>> bluetooth-next tree.
>> ---
>> net/bluetooth/rfcomm/core.c |    2 ++
>> 1 files changed, 2 insertions(+), 0 deletions(-)
> 
> good catch. Patch has been applied to bluetooth-next tree.
> 
> You might also want to send a patch that adds the l2_bdaddr_type setting before the connect() call.

Case of kernel_connect() in rfcomm_session_create(), it reuses
l2_bdaddr_type used for kernel_bind(), so it works fine for me: I tested
both incoming connection and outgoing connection cases of rfcomm.
But if you prefer explicit setting for connect(), please let me know.

Best Regards,
- Seung-Woo Kim

> 
> Regards
> 
> Marcel
> 
> 

-- 
Seung-Woo Kim
Samsung Software R&D Center
--

^ permalink raw reply

* RE: [BUG] Crash during disconnecting and removing bond from remote device
From: 김승우 @ 2013-11-05  7:29 UTC (permalink / raw)
  To: 'Johan Hedberg'; +Cc: linux-bluetooth, s.syam, sw0312.kim
In-Reply-To: <20131101075718.GA13221@x220.p-661hnu-f1>

Hi Johan Hedberg,

Sorry for late response.

> -----Original Message-----
> From: Johan Hedberg [mailto:johan.hedberg@gmail.com]
> Sent: Friday, November 01, 2013 4:57 PM
> To: Seung-Woo Kim
> Cc: linux-bluetooth@vger.kernel.org; s.syam@samsung.com
> Subject: Re: [BUG] Crash during disconnecting and removing bond from
> remote device
> 
> Hi Seung-Woo Kim,
> 
> On Mon, Oct 28, 2013, Seung-Woo Kim wrote:
> > I used 3.10.14 with RFCOMM tty patches in 3.12-rc, and I tested
> > disconnecting and removing a bond from remote device. and I got
> > following crash.
> 
> This looks like a potentially valid issue, but you'd need to dress up the
> fix as a proper patch (i.e. git format-patch + git send-email). It'd also
> be good if you could confirm that the issue is reproducable with the
> latest bluetooth-next kernel.

I tried with bluetooth-next kernel and there is no issue I mentioned. But
if you consider to apply the patch, then I will post the formatted patch.
Please let me know if you want.

Best Regards,
- Seung-Woo Kim

> 
> Johan


^ permalink raw reply

* Re: [PATCH] Bluetooth: Fix RFCOMM bind fail for L2CAP sock
From: Marcel Holtmann @ 2013-11-05  7:26 UTC (permalink / raw)
  To: Seung-Woo Kim
  Cc: linux-bluetooth@vger.kernel.org development, Gustavo F. Padovan,
	Johan Hedberg, Syam Sidhardhan
In-Reply-To: <1383634944-4141-1-git-send-email-sw0312.kim@samsung.com>

Hi Seung-Woo,

> L2CAP socket bind checks its bdaddr type but RFCOMM kernel thread
> does not assign proper bdaddr type for L2CAP sock. This can cause
> that RFCOMM failure.
> 
> Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
> ---
> The issue is came from following commit, but it is only in bluetooth-next tree,
> so this patch is not needed for stable tree.
> 
> commit 80c1a2e76dbb36588facb265ab364b1302f7ef8c
> Author: Johan Hedberg <johan.hedberg@intel.com>
> Date:   Mon Oct 14 21:17:52 2013 +0300
> 
>    Bluetooth: Reject invalid bdaddr types for sockets
> 
> This patch is based on commit cca34b785a21d220176038c45071ffe842e99fd3 of
> bluetooth-next tree.
> ---
> net/bluetooth/rfcomm/core.c |    2 ++
> 1 files changed, 2 insertions(+), 0 deletions(-)

good catch. Patch has been applied to bluetooth-next tree.

You might also want to send a patch that adds the l2_bdaddr_type setting before the connect() call.

Regards

Marcel


^ permalink raw reply

* [PATCH] Bluetooth: Fix RFCOMM bind fail for L2CAP sock
From: Seung-Woo Kim @ 2013-11-05  7:02 UTC (permalink / raw)
  To: linux-bluetooth, marcel, gustavo, johan.hedberg; +Cc: sw0312.kim, s.syam

L2CAP socket bind checks its bdaddr type but RFCOMM kernel thread
does not assign proper bdaddr type for L2CAP sock. This can cause
that RFCOMM failure.

Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
---
The issue is came from following commit, but it is only in bluetooth-next tree,
so this patch is not needed for stable tree.

commit 80c1a2e76dbb36588facb265ab364b1302f7ef8c
Author: Johan Hedberg <johan.hedberg@intel.com>
Date:   Mon Oct 14 21:17:52 2013 +0300

    Bluetooth: Reject invalid bdaddr types for sockets

This patch is based on commit cca34b785a21d220176038c45071ffe842e99fd3 of
bluetooth-next tree.
---
 net/bluetooth/rfcomm/core.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 94d06cb..ca55ea1 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -694,6 +694,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
 	addr.l2_family = AF_BLUETOOTH;
 	addr.l2_psm    = 0;
 	addr.l2_cid    = 0;
+	addr.l2_bdaddr_type = BDADDR_BREDR;
 	*err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr));
 	if (*err < 0)
 		goto failed;
@@ -1983,6 +1984,7 @@ static int rfcomm_add_listener(bdaddr_t *ba)
 	addr.l2_family = AF_BLUETOOTH;
 	addr.l2_psm    = __constant_cpu_to_le16(RFCOMM_PSM);
 	addr.l2_cid    = 0;
+	addr.l2_bdaddr_type = BDADDR_BREDR;
 	err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr));
 	if (err < 0) {
 		BT_ERR("Bind failed %d", err);
-- 
1.7.4.1

^ permalink raw reply related

* Re: Intel 7260 bluetooth malfunction when it is connected to EHCI bus
From: Hui Wang @ 2013-11-05  2:32 UTC (permalink / raw)
  To: Stevie Trujillo; +Cc: marcel, tedd.an, linux-bluetooth
In-Reply-To: <20131104141539.772e1636@localhost>

On 11/04/2013 09:15 PM, Stevie Trujillo wrote:
> Hello, I've been trying to use my computer as "handsfree" with
> "Hands-Free Profile" using "Intel Corporation Centrino Wireless-N
> 1030". I accept() the BTPROTO_SCO socket, but never recv() any
> data. Your post looked similar!
>
> When googling I found this:
>
> http://www.netbsd.org/docs/guide/en/chap-bluetooth.html#chap-bluetooth-audio
>     SCO Audio will not work with ehci(4) USB controllers, since support
>     for Isochronous data over EHCI is missing in NetBSD.
>
> Does Linux support this? (I have no idea what it means)

Hi Stevie,

Thanks for your input, I don't know the answer of your question, but at 
least the camera works well on the EHCI bus, and camera transfers the 
ISO packets over EHCI bus.

Regards,
Hui.
>
> I'm sorry if this mail is somewhat broken. I could only find your email
> on "gmane" and it had encrypted all your email addresses!
>
> On Mon, 04 Nov 2013 13:59:35 +0800
> Hui Wang <hui.wang-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org> wrote:
>
>> On 11/03/2013 03:05 AM, Marcel Holtmann wrote:
>>> Hi Hui,
>>>
>> <snip>
>>>> The attachment lenovo-k4450-btmon-v1.log is the log of intel 7260
>>>> init procedure + scan headset + connect headset + play sound.
>>> I looked through the logs and the controller init is just fine. So
>>> in theory this should route the SCO audio frames over HCI. For some
>>> reason it does not and I have no idea why not.
>>>
>>> That it makes a different between EHCI and XHCI is strange. I can
>>> not explain this. Maybe Tedd can help you since I have no further
>>> insights in our chips at this moment.
>> Thanks Marcel for your kind help and analysis.
>>
>> Tedd, did you reproduce this issue on the machines with intel 7260 BT
>> module connected to the EHCI bus? Did you have any idea on this issue?
>

^ permalink raw reply

* [PATCH 11/11] android/hid: Handle uhid events
From: Ravi kumar Veeramally @ 2013-11-04 22:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1383603615-9953-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Handling few uhid events and described scenarios. OUTPUT and
FEATURE events are not yet handled.
---
 android/hid.c | 40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/android/hid.c b/android/hid.c
index 74de02f..fccaa87 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -149,6 +149,11 @@ static void hid_device_free(struct hid_device *dev)
 	g_free(dev);
 }
 
+static void handle_uhid_event(struct hid_device *dev, struct uhid_event *ev)
+{
+	DBG("unsupported event");
+}
+
 static gboolean uhid_event_cb(GIOChannel *io, GIOCondition cond,
 							gpointer user_data)
 {
@@ -172,7 +177,40 @@ static gboolean uhid_event_cb(GIOChannel *io, GIOCondition cond,
 	}
 
 	DBG("uHID event type %d received", ev.type);
-	/* TODO Handle events */
+
+	switch (ev.type) {
+	case UHID_START:
+	case UHID_STOP:
+		/* These are called to start and stop the underlying hardware.
+		 * We open the channels before creating the device so the
+		 * hardware is always ready. No need to handle these.
+		 * The kernel never destroys a device itself! Only an explicit
+		 * UHID_DESTROY request can remove a device. */
+
+		break;
+	case UHID_OPEN:
+	case UHID_CLOSE:
+		/* OPEN/CLOSE are sent whenever user-space opens any interface
+		 * provided by the kernel HID device. Whenever the open-count
+		 * is non-zero we must be ready for I/O. As long as it is zero,
+		 * we can decide to drop all I/O and put the device
+		 * asleep This is optional, though. */
+		break;
+	case UHID_OUTPUT:
+	case UHID_FEATURE:
+		handle_uhid_event(dev, &ev);
+		break;
+	case UHID_OUTPUT_EV:
+		/* This is only sent by kernels prior to linux-3.11. It
+		 * requires us to parse HID-descriptors in user-space to
+		 * properly handle it. This is redundant as the kernel
+		 * does it already. That's why newer kernels assemble
+		 * the output-reports and send it to us via UHID_OUTPUT. */
+		DBG("Unsupported uHID event: type %d", ev.u.output_ev.type);
+		break;
+	default:
+		warn("unexpected uHID event");
+	}
 
 	return TRUE;
 
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH 10/11] android/hid: Handle invalid parameters in hal
From: Ravi kumar Veeramally @ 2013-11-04 22:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1383603615-9953-1-git-send-email-ravikumar.veeramally@linux.intel.com>

---
 android/hal-hidhost.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
index 45767b8..412258c 100644
--- a/android/hal-hidhost.c
+++ b/android/hal-hidhost.c
@@ -204,9 +204,8 @@ static bt_status_t hh_get_protocol(bt_bdaddr_t *bd_addr,
 	case BTHH_BOOT_MODE:
 		cmd.mode = HAL_HID_BOOT_PROTOCOL;
 		break;
-	case BTHH_UNSUPPORTED_MODE:
-		cmd.mode = HAL_HID_UNSUPPORTED_PROTOCOL;
-		break;
+	default:
+		return BT_STATUS_PARM_INVALID;
 	}
 
 	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST,
@@ -236,9 +235,8 @@ static bt_status_t hh_set_protocol(bt_bdaddr_t *bd_addr,
 	case BTHH_BOOT_MODE:
 		cmd.mode = HAL_HID_BOOT_PROTOCOL;
 		break;
-	case BTHH_UNSUPPORTED_MODE:
-		cmd.mode = HAL_HID_UNSUPPORTED_PROTOCOL;
-		break;
+	default:
+		return BT_STATUS_PARM_INVALID;
 	}
 
 	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST,
@@ -275,6 +273,8 @@ static bt_status_t hh_get_report(bt_bdaddr_t *bd_addr,
 	case BTHH_FEATURE_REPORT:
 		cmd.type = HAL_HID_FEATURE_REPORT;
 		break;
+	default:
+		return BT_STATUS_PARM_INVALID;
 	}
 
 	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HID_GET_REPORT,
@@ -308,6 +308,8 @@ static bt_status_t hh_set_report(bt_bdaddr_t *bd_addr,
 	case BTHH_FEATURE_REPORT:
 		cmd.type = HAL_HID_FEATURE_REPORT;
 		break;
+	default:
+		return BT_STATUS_PARM_INVALID;
 	}
 
 	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HID_SET_REPORT,
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH 09/11] android/hid: Replace header checking magic number with defines
From: Ravi kumar Veeramally @ 2013-11-04 22:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1383603615-9953-1-git-send-email-ravikumar.veeramally@linux.intel.com>

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

diff --git a/android/hid.c b/android/hid.c
index 2682b21e6..74de02f 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -200,7 +200,7 @@ static gboolean intr_io_watch_cb(GIOChannel *chan, gpointer data)
 	}
 
 	/* Discard non-data packets */
-	if (bread == 0 || buf[0] != 0xA1)
+	if (bread == 0 || buf[0] != (HID_MSG_DATA | HID_DATA_TYPE_INPUT))
 		return TRUE;
 
 	/* send data to uHID device skipping HIDP header byte */
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH 08/11] android/hid: Handle get report notification in hal
From: Ravi kumar Veeramally @ 2013-11-04 22:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1383603615-9953-1-git-send-email-ravikumar.veeramally@linux.intel.com>

---
 android/hal-hidhost.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
index 040d517..45767b8 100644
--- a/android/hal-hidhost.c
+++ b/android/hal-hidhost.c
@@ -68,6 +68,15 @@ static void handle_protocol_mode(void *buf)
 							ev->status, ev->mode);
 }
 
+static void handle_get_report(void *buf)
+{
+	struct hal_ev_hid_get_report *ev = buf;
+
+	if (bt_hh_cbacks->get_report_cb)
+		bt_hh_cbacks->get_report_cb((bt_bdaddr_t *) ev->bdaddr,
+						ev->status, ev->data, ev->len);
+}
+
 /* will be called from notification thread context */
 void bt_notify_hh(uint16_t opcode, void *buf, uint16_t len)
 {
@@ -84,6 +93,9 @@ void bt_notify_hh(uint16_t opcode, void *buf, uint16_t len)
 	case HAL_EV_HID_PROTO_MODE:
 		handle_protocol_mode(buf);
 		break;
+	case HAL_EV_HID_GET_REPORT:
+		handle_get_report(buf);
+		break;
 	default:
 		DBG("Unhandled callback opcode=0x%x", opcode);
 		break;
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH 07/11] android/hid: Implement hid set report in daemon
From: Ravi kumar Veeramally @ 2013-11-04 22:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1383603615-9953-1-git-send-email-ravikumar.veeramally@linux.intel.com>

This patch requests hid device to set report.
---
 android/hal-hidhost.c |  1 +
 android/hal-msg.h     |  1 +
 android/hid.c         | 40 ++++++++++++++++++++++++++++++++++++++--
 3 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
index 027e3b8..040d517 100644
--- a/android/hal-hidhost.c
+++ b/android/hal-hidhost.c
@@ -284,6 +284,7 @@ static bt_status_t hh_set_report(bt_bdaddr_t *bd_addr,
 		return BT_STATUS_PARM_INVALID;
 
 	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
+	cmd.report = report;
 
 	switch (reportType) {
 	case BTHH_INPUT_REPORT:
diff --git a/android/hal-msg.h b/android/hal-msg.h
index eaa5c9c..e1fd027 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -292,6 +292,7 @@ struct hal_cmd_hid_get_report {
 struct hal_cmd_hid_set_report {
 	uint8_t bdaddr[6];
 	uint8_t type;
+	char *report;
 } __attribute__((packed));
 
 #define HAL_OP_HID_SEND_DATA		0x09
diff --git a/android/hid.c b/android/hid.c
index 6cb9604..2682b21e6 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -56,6 +56,7 @@
 
 /* HID message types */
 #define HID_MSG_GET_REPORT	0x40
+#define HID_MSG_SET_REPORT	0x50
 #define HID_MSG_GET_PROTOCOL	0x60
 #define HID_MSG_SET_PROTOCOL	0x70
 #define HID_MSG_DATA		0xa0
@@ -846,9 +847,44 @@ static uint8_t bt_hid_get_report(struct hal_cmd_hid_get_report *cmd,
 static uint8_t bt_hid_set_report(struct hal_cmd_hid_set_report *cmd,
 								uint16_t len)
 {
-	DBG("Not Implemented");
+	struct hid_device *dev;
+	GSList *l;
+	bdaddr_t dst;
+	int fd;
+	uint8_t *req;
+	uint8_t req_size;
 
-	return HAL_STATUS_FAILED;
+	DBG("");
+
+	if (len < sizeof(*cmd))
+		return HAL_STATUS_INVALID;
+
+	android2bdaddr(&cmd->bdaddr, &dst);
+
+	l = g_slist_find_custom(devices, &dst, device_cmp);
+	if (!l)
+		return HAL_STATUS_FAILED;
+
+	dev = l->data;
+	dev->hid_msg = HID_MSG_SET_REPORT;
+	req_size = 1 + strlen(cmd->report);
+	req = g_try_malloc0(req_size);
+	if (!req)
+		return HAL_STATUS_NOMEM;
+
+	req[0] = HID_MSG_SET_REPORT | cmd->type;
+	memcpy(req + 1, cmd->report, req_size - 1);
+
+	fd = g_io_channel_unix_get_fd(dev->ctrl_io);
+
+	if (write(fd, req, req_size) < 0) {
+		error("error while querying device protocol");
+		g_free(req);
+		return HAL_STATUS_FAILED;
+	}
+
+	g_free(req);
+	return HAL_STATUS_SUCCESS;
 }
 
 static uint8_t bt_hid_send_data(struct hal_cmd_hid_send_data *cmd,
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH 06/11] android/hid: Implement hid get report in daemon
From: Ravi kumar Veeramally @ 2013-11-04 22:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1383603615-9953-1-git-send-email-ravikumar.veeramally@linux.intel.com>

This patch requests hid device report and reads reply
message and sends notification to hal.
---
 android/hal-hidhost.c |   1 +
 android/hal-msg.h     |   8 ++++
 android/hid.c         | 104 +++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 111 insertions(+), 2 deletions(-)

diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
index a287e40..027e3b8 100644
--- a/android/hal-hidhost.c
+++ b/android/hal-hidhost.c
@@ -251,6 +251,7 @@ static bt_status_t hh_get_report(bt_bdaddr_t *bd_addr,
 
 	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
 	cmd.id = reportId;
+	cmd.buf = bufferSize;
 
 	switch (reportType) {
 	case BTHH_INPUT_REPORT:
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 214daa9..eaa5c9c 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -465,6 +465,14 @@ struct hal_ev_hid_protocol {
 	uint8_t mode;
 } __attribute__((packed));
 
+#define HAL_EV_HID_GET_REPORT		0x84
+struct hal_ev_hid_get_report {
+	uint8_t bdaddr[6];
+	uint8_t status;
+	uint16_t len;
+	uint8_t data[0];
+} __attribute__((packed));
+
 #define HAL_EV_AV_CONNECTION_STATE	0x81
 struct hal_ev_av_connection_state {
 	uint8_t state;
diff --git a/android/hid.c b/android/hid.c
index 115a1c5..6cb9604 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -55,14 +55,23 @@
 #define UHID_DEVICE_FILE	"/dev/uhid"
 
 /* HID message types */
+#define HID_MSG_GET_REPORT	0x40
 #define HID_MSG_GET_PROTOCOL	0x60
 #define HID_MSG_SET_PROTOCOL	0x70
 #define HID_MSG_DATA		0xa0
 
+/* HID data types */
+#define HID_DATA_TYPE_INPUT	0x01
+#define HID_DATA_TYPE_OUTPUT	0x02
+#define HID_DATA_TYPE_FEATURE	0x03
+
 /* HID protocol header parameters */
 #define HID_PROTO_BOOT		0x00
 #define HID_PROTO_REPORT	0x01
 
+/* HID GET REPORT Size Field */
+#define HID_GET_REPORT_SIZE_FIELD	0x08
+
 static GIOChannel *notification_io = NULL;
 static GIOChannel *ctrl_io = NULL;
 static GIOChannel *intr_io = NULL;
@@ -283,6 +292,52 @@ static void bt_hid_notify_protocol_mode(struct hid_device *dev, uint8_t *buf,
 				HAL_EV_HID_PROTO_MODE, sizeof(ev), &ev, -1);
 }
 
+static void bt_hid_notify_get_report(struct hid_device *dev, uint8_t *buf,
+									int len)
+{
+	struct hal_ev_hid_get_report *ev;
+	int ev_len;
+	char address[18];
+
+	ba2str(&dev->dst, address);
+	DBG("device %s", address);
+
+	ev_len = sizeof(*ev) + sizeof(struct hal_ev_hid_get_report) + 1;
+
+	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_malloc(len);
+		memset(ev, 0, ev_len);
+		ev->status = buf[0];
+		bdaddr2android(&dev->dst, ev->bdaddr);
+		goto send;
+	}
+
+	/* Report porotocol mode reply contains id after hdr, in boot
+	 * protocol mode id doesn't exist */
+	ev_len += (dev->boot_dev) ? (len - 1) : (len - 2);
+	ev = g_malloc(ev_len);
+	memset(ev, 0, ev_len);
+	ev->status = HAL_HID_STATUS_OK;
+	bdaddr2android(&dev->dst, ev->bdaddr);
+
+	/* Report porotocol mode reply contains id after hdr, in boot
+	 * protocol mode id doesn't exist */
+	if (dev->boot_dev) {
+		ev->len = len - 1;
+		memcpy(ev->data, buf + 1, ev->len);
+	} else {
+		ev->len = len - 2;
+		memcpy(ev->data, buf + 2, ev->len);
+	}
+
+send:
+	ipc_send(notification_io, HAL_SERVICE_ID_HIDHOST, HAL_EV_HID_GET_REPORT,
+						ev_len, ev, -1);
+	g_free(ev);
+}
+
 static gboolean ctrl_io_watch_cb(GIOChannel *chan, gpointer data)
 {
 	struct hid_device *dev = data;
@@ -303,6 +358,9 @@ static gboolean ctrl_io_watch_cb(GIOChannel *chan, gpointer data)
 	case HID_MSG_SET_PROTOCOL:
 		bt_hid_notify_protocol_mode(dev, buf, bread);
 		break;
+	case HID_MSG_GET_REPORT:
+		bt_hid_notify_get_report(dev, buf, bread);
+		break;
 	default:
 		DBG("unhandled hid msg type 0x%02x", dev->hid_msg);
 	}
@@ -738,9 +796,51 @@ static uint8_t bt_hid_set_protocol(struct hal_cmd_hid_set_protocol *cmd,
 static uint8_t bt_hid_get_report(struct hal_cmd_hid_get_report *cmd,
 								uint16_t len)
 {
-	DBG("Not Implemented");
+	struct hid_device *dev;
+	GSList *l;
+	bdaddr_t dst;
+	int fd;
+	uint8_t *req;
+	uint8_t req_size;
 
-	return HAL_STATUS_FAILED;
+	DBG("");
+
+	if (len < sizeof(*cmd))
+		return HAL_STATUS_INVALID;
+
+	android2bdaddr(&cmd->bdaddr, &dst);
+
+	l = g_slist_find_custom(devices, &dst, device_cmp);
+	if (!l)
+		return HAL_STATUS_FAILED;
+
+	dev = l->data;
+	dev->hid_msg = HID_MSG_GET_REPORT;
+	req_size = (cmd->buf > 0) ? 4 : 2;
+	req = g_try_malloc0(req_size);
+	if (!req)
+		return HAL_STATUS_NOMEM;
+
+	req[0] = HID_MSG_GET_REPORT | cmd->type;
+
+	if (cmd->buf > 0)
+		req[0] = req[0] | HID_GET_REPORT_SIZE_FIELD;
+
+	req[1] = cmd->id;
+
+	if (cmd->buf > 0)
+		bt_put_le16(cmd->buf, (req + 2));
+
+	fd = g_io_channel_unix_get_fd(dev->ctrl_io);
+
+	if (write(fd, req, req_size) < 0) {
+		error("error while querying device protocol");
+		g_free(req);
+		return HAL_STATUS_FAILED;
+	}
+
+	g_free(req);
+	return HAL_STATUS_SUCCESS;
 }
 
 static uint8_t bt_hid_set_report(struct hal_cmd_hid_set_report *cmd,
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH 05/11] android/hid: Handle protocol mode notification in hal
From: Ravi kumar Veeramally @ 2013-11-04 22:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1383603615-9953-1-git-send-email-ravikumar.veeramally@linux.intel.com>

---
 android/hal-hidhost.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
index c20c785..a287e40 100644
--- a/android/hal-hidhost.c
+++ b/android/hal-hidhost.c
@@ -59,6 +59,15 @@ static void handle_info(void *buf)
 		bt_hh_cbacks->hid_info_cb((bt_bdaddr_t *) ev->bdaddr, info);
 }
 
+static void handle_protocol_mode(void *buf)
+{
+	struct hal_ev_hid_protocol *ev = buf;
+
+	if (bt_hh_cbacks->protocol_mode_cb)
+		bt_hh_cbacks->protocol_mode_cb((bt_bdaddr_t *) ev->bdaddr,
+							ev->status, ev->mode);
+}
+
 /* will be called from notification thread context */
 void bt_notify_hh(uint16_t opcode, void *buf, uint16_t len)
 {
@@ -72,6 +81,9 @@ void bt_notify_hh(uint16_t opcode, void *buf, uint16_t len)
 	case HAL_EV_HID_INFO:
 		handle_info(buf);
 		break;
+	case HAL_EV_HID_PROTO_MODE:
+		handle_protocol_mode(buf);
+		break;
 	default:
 		DBG("Unhandled callback opcode=0x%x", opcode);
 		break;
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH 04/11] android/hid: Implement hid set protocol in daemon
From: Ravi kumar Veeramally @ 2013-11-04 22:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1383603615-9953-1-git-send-email-ravikumar.veeramally@linux.intel.com>

This patch requests hid device to set protocol mode and reads
reply message and sends notification to hal.
---
 android/hid.c | 35 +++++++++++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/android/hid.c b/android/hid.c
index 9a5477d..115a1c5 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -56,6 +56,7 @@
 
 /* HID message types */
 #define HID_MSG_GET_PROTOCOL	0x60
+#define HID_MSG_SET_PROTOCOL	0x70
 #define HID_MSG_DATA		0xa0
 
 /* HID protocol header parameters */
@@ -299,6 +300,7 @@ static gboolean ctrl_io_watch_cb(GIOChannel *chan, gpointer data)
 
 	switch (dev->hid_msg) {
 	case HID_MSG_GET_PROTOCOL:
+	case HID_MSG_SET_PROTOCOL:
 		bt_hid_notify_protocol_mode(dev, buf, bread);
 		break;
 	default:
@@ -699,9 +701,38 @@ static uint8_t bt_hid_get_protocol(struct hal_cmd_hid_get_protocol *cmd,
 static uint8_t bt_hid_set_protocol(struct hal_cmd_hid_set_protocol *cmd,
 								uint16_t len)
 {
-	DBG("Not Implemented");
+	struct hid_device *dev;
+	GSList *l;
+	bdaddr_t dst;
+	int fd;
+	uint8_t hdr[1];
 
-	return HAL_STATUS_FAILED;
+	DBG("");
+
+	if (len < sizeof(*cmd))
+		return HAL_STATUS_INVALID;
+
+	android2bdaddr(&cmd->bdaddr, &dst);
+
+	l = g_slist_find_custom(devices, &dst, device_cmp);
+	if (!l)
+		return HAL_STATUS_FAILED;
+
+	dev = l->data;
+
+	if (dev->boot_dev)
+		return HAL_STATUS_UNSUPPORTED;
+
+	dev->hid_msg = HID_MSG_SET_PROTOCOL;
+	hdr[0] = HID_MSG_SET_PROTOCOL | cmd->mode;
+	fd = g_io_channel_unix_get_fd(dev->ctrl_io);
+
+	if (write(fd, hdr, sizeof(hdr)) < 0) {
+		error("error while setting device protocol");
+		return HAL_STATUS_FAILED;
+	}
+
+	return HAL_STATUS_SUCCESS;
 }
 
 static uint8_t bt_hid_get_report(struct hal_cmd_hid_get_report *cmd,
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH 03/11] android/hid: Implement hid get protocol in daemon
From: Ravi kumar Veeramally @ 2013-11-04 22:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1383603615-9953-1-git-send-email-ravikumar.veeramally@linux.intel.com>

This patch requests hid device protocol mode and reads reply
message and sends notification to hal.
---
 android/hal-msg.h |   9 +++++
 android/hid.c     | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 113 insertions(+), 4 deletions(-)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index f381862..214daa9 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -442,6 +442,8 @@ struct hal_ev_hid_conn_state {
 	uint8_t state;
 } __attribute__((packed));
 
+#define HAL_HID_STATUS_OK		0x00
+
 #define HAL_EV_HID_INFO			0x82
 struct hal_ev_hid_info {
 	uint8_t bdaddr[6];
@@ -456,6 +458,13 @@ struct hal_ev_hid_info {
 	uint8_t descr[884];
 } __attribute__((packed));
 
+#define HAL_EV_HID_PROTO_MODE		0x83
+struct hal_ev_hid_protocol {
+	uint8_t bdaddr[6];
+	uint8_t status;
+	uint8_t mode;
+} __attribute__((packed));
+
 #define HAL_EV_AV_CONNECTION_STATE	0x81
 struct hal_ev_av_connection_state {
 	uint8_t state;
diff --git a/android/hid.c b/android/hid.c
index c0c9aeb..9a5477d 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -54,6 +54,14 @@
 #define L2CAP_PSM_HIDP_INTR	0x13
 #define UHID_DEVICE_FILE	"/dev/uhid"
 
+/* HID message types */
+#define HID_MSG_GET_PROTOCOL	0x60
+#define HID_MSG_DATA		0xa0
+
+/* HID protocol header parameters */
+#define HID_PROTO_BOOT		0x00
+#define HID_PROTO_REPORT	0x01
+
 static GIOChannel *notification_io = NULL;
 static GIOChannel *ctrl_io = NULL;
 static GIOChannel *intr_io = NULL;
@@ -76,6 +84,7 @@ struct hid_device {
 	guint		intr_watch;
 	int		uhid_fd;
 	guint		uhid_watch_id;
+	int		hid_msg;
 };
 
 static int device_cmp(gconstpointer s, gconstpointer user_data)
@@ -243,12 +252,74 @@ static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond,
 	return FALSE;
 }
 
+static void bt_hid_notify_protocol_mode(struct hid_device *dev, uint8_t *buf,
+									int len)
+{
+	struct hal_ev_hid_protocol ev;
+	char address[18];
+
+	ba2str(&dev->dst, address);
+	DBG("device %s", address);
+
+	memset(&ev, 0, sizeof(ev));
+	bdaddr2android(&dev->dst, ev.bdaddr);
+
+	if (buf[0] == HID_MSG_DATA) {
+		ev.status = HAL_HID_STATUS_OK;
+		if (buf[1] == HID_PROTO_REPORT)
+			ev.mode = HAL_HID_REPORT_PROTOCOL;
+		else if (buf[1] == HID_PROTO_BOOT)
+			ev.mode = HAL_HID_BOOT_PROTOCOL;
+		else
+			ev.mode = HAL_HID_UNSUPPORTED_PROTOCOL;
+
+	} else {
+		ev.status = buf[0];
+		ev.mode = HAL_HID_UNSUPPORTED_PROTOCOL;
+	}
+
+	ipc_send(notification_io, HAL_SERVICE_ID_HIDHOST,
+				HAL_EV_HID_PROTO_MODE, sizeof(ev), &ev, -1);
+}
+
+static gboolean ctrl_io_watch_cb(GIOChannel *chan, gpointer data)
+{
+	struct hid_device *dev = data;
+	int fd, bread;
+	uint8_t buf[UHID_DATA_MAX];
+
+	DBG("");
+
+	fd = g_io_channel_unix_get_fd(chan);
+	bread = read(fd, buf, sizeof(buf));
+	if (bread < 0) {
+		error("read: %s(%d)", strerror(errno), -errno);
+		return TRUE;
+	}
+
+	switch (dev->hid_msg) {
+	case HID_MSG_GET_PROTOCOL:
+		bt_hid_notify_protocol_mode(dev, buf, bread);
+		break;
+	default:
+		DBG("unhandled hid msg type 0x%02x", dev->hid_msg);
+	}
+
+	/* reset msg type request */
+	dev->hid_msg = -1;
+
+	return TRUE;
+}
+
 static gboolean ctrl_watch_cb(GIOChannel *chan, GIOCondition cond,
 								gpointer data)
 {
 	struct hid_device *dev = data;
 	char address[18];
 
+	if (cond & G_IO_IN)
+		return ctrl_io_watch_cb(chan, data);
+
 	ba2str(&dev->dst, address);
 	bt_hid_notify_state(dev, HAL_HID_STATE_DISCONNECTED);
 
@@ -395,8 +466,8 @@ static void control_connect_cb(GIOChannel *chan, GError *conn_err,
 	}
 
 	dev->ctrl_watch = g_io_add_watch(dev->ctrl_io,
-					G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-					ctrl_watch_cb, dev);
+				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+				ctrl_watch_cb, dev);
 
 	return;
 
@@ -591,9 +662,38 @@ static uint8_t bt_hid_info(struct hal_cmd_hid_set_info *cmd, uint16_t len)
 static uint8_t bt_hid_get_protocol(struct hal_cmd_hid_get_protocol *cmd,
 								uint16_t len)
 {
-	DBG("Not Implemented");
+	struct hid_device *dev;
+	GSList *l;
+	bdaddr_t dst;
+	int fd;
+	uint8_t hdr[1];
 
-	return HAL_STATUS_FAILED;
+	DBG("");
+
+	if (len < sizeof(*cmd))
+		return HAL_STATUS_INVALID;
+
+	android2bdaddr(&cmd->bdaddr, &dst);
+
+	l = g_slist_find_custom(devices, &dst, device_cmp);
+	if (!l)
+		return HAL_STATUS_FAILED;
+
+	dev = l->data;
+
+	if (dev->boot_dev)
+		return HAL_STATUS_UNSUPPORTED;
+
+	dev->hid_msg = HID_MSG_GET_PROTOCOL;
+	hdr[0] = HID_MSG_GET_PROTOCOL | cmd->mode;
+	fd = g_io_channel_unix_get_fd(dev->ctrl_io);
+
+	if (write(fd, hdr, sizeof(hdr)) < 0) {
+		error("error while querying device protocol");
+		return HAL_STATUS_FAILED;
+	}
+
+	return HAL_STATUS_SUCCESS;
 }
 
 static uint8_t bt_hid_set_protocol(struct hal_cmd_hid_set_protocol *cmd,
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH 02/11] android/hid: Retrieve BOOT_DEVICE attribute from SDP and cache it
From: Ravi kumar Veeramally @ 2013-11-04 22:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1383603615-9953-1-git-send-email-ravikumar.veeramally@linux.intel.com>

It will be usefull to handle when application level requests
get or set protocol from hid device.
---
 android/hid.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/android/hid.c b/android/hid.c
index 2498d2d..c0c9aeb 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -69,6 +69,7 @@ struct hid_device {
 	uint8_t		country;
 	int		rd_size;
 	void		*rd_data;
+	uint8_t		boot_dev;
 	GIOChannel	*ctrl_io;
 	GIOChannel	*intr_io;
 	guint		ctrl_watch;
@@ -446,6 +447,10 @@ static void hid_sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 		if (data)
 			dev->subclass = data->val.uint8;
 
+		data = sdp_data_get(rec, SDP_ATTR_HID_BOOT_DEVICE);
+		if (data)
+			dev->boot_dev = data->val.uint8;
+
 		data = sdp_data_get(rec, SDP_ATTR_HID_DESCRIPTOR_LIST);
 		if (data) {
 			if (!SDP_IS_SEQ(data->dtd))
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH 01/11] android/hid: Rename function name set_state to notify_state
From: Ravi kumar Veeramally @ 2013-11-04 22:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1383603615-9953-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Renaming notification preparation function name from bt_hid_set_state
to bt_hid_notify_state. Rest of the funtions name will have proper
notify* names.
---
 android/hid.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/android/hid.c b/android/hid.c
index 1ee8ed4..2498d2d 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -194,7 +194,7 @@ static gboolean intr_io_watch_cb(GIOChannel *chan, gpointer data)
 	return TRUE;
 }
 
-static void bt_hid_set_state(struct hid_device *dev, uint8_t state)
+static void bt_hid_notify_state(struct hid_device *dev, uint8_t state)
 {
 	struct hal_ev_hid_conn_state ev;
 	char address[18];
@@ -249,7 +249,7 @@ static gboolean ctrl_watch_cb(GIOChannel *chan, GIOCondition cond,
 	char address[18];
 
 	ba2str(&dev->dst, address);
-	bt_hid_set_state(dev, HAL_HID_STATE_DISCONNECTED);
+	bt_hid_notify_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
@@ -296,6 +296,7 @@ static int uhid_create(struct hid_device *dev)
 	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));
+		bt_hid_notify_state(dev, HAL_HID_STATE_NO_HID);
 		return -errno;
 	}
 
@@ -344,7 +345,7 @@ static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err,
 				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
 				intr_watch_cb, dev);
 
-	bt_hid_set_state(dev, HAL_HID_STATE_CONNECTED);
+	bt_hid_notify_state(dev, HAL_HID_STATE_CONNECTED);
 
 	return;
 
@@ -374,7 +375,7 @@ static void control_connect_cb(GIOChannel *chan, GError *conn_err,
 	DBG("");
 
 	if (conn_err) {
-		bt_hid_set_state(dev, HAL_HID_STATE_DISCONNECTED);
+		bt_hid_notify_state(dev, HAL_HID_STATE_DISCONNECTED);
 		error("%s", conn_err->message);
 		goto failed;
 	}
@@ -491,7 +492,7 @@ static void hid_sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 	return;
 
 fail:
-	bt_hid_set_state(dev, HAL_HID_STATE_DISCONNECTED);
+	bt_hid_notify_state(dev, HAL_HID_STATE_DISCONNECTED);
 	hid_device_free(dev);
 }
 
@@ -531,7 +532,7 @@ static uint8_t bt_hid_connect(struct hal_cmd_hid_connect *cmd, uint16_t len)
 	}
 
 	devices = g_slist_append(devices, dev);
-	bt_hid_set_state(dev, HAL_HID_STATE_CONNECTING);
+	bt_hid_notify_state(dev, HAL_HID_STATE_CONNECTING);
 
 	return HAL_STATUS_SUCCESS;
 }
@@ -563,7 +564,7 @@ static uint8_t bt_hid_disconnect(struct hal_cmd_hid_disconnect *cmd,
 	if (dev->ctrl_io)
 		g_io_channel_shutdown(dev->ctrl_io, TRUE, NULL);
 
-	bt_hid_set_state(dev, HAL_HID_STATE_DISCONNECTING);
+	bt_hid_notify_state(dev, HAL_HID_STATE_DISCONNECTING);
 
 	return HAL_STATUS_SUCCESS;
 }
@@ -715,7 +716,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 		dev->ctrl_watch = g_io_add_watch(dev->ctrl_io,
 					G_IO_HUP | G_IO_ERR | G_IO_NVAL,
 					ctrl_watch_cb, dev);
-		bt_hid_set_state(dev, HAL_HID_STATE_CONNECTING);
+		bt_hid_notify_state(dev, HAL_HID_STATE_CONNECTING);
 		break;
 
 	case L2CAP_PSM_HIDP_INTR:
@@ -728,7 +729,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 		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, dev);
-		bt_hid_set_state(dev, HAL_HID_STATE_CONNECTED);
+		bt_hid_notify_state(dev, HAL_HID_STATE_CONNECTED);
 		break;
 	}
 }
-- 
1.8.1.2


^ permalink raw reply related

* [PATCH 00/11] Implemented hid interfaces in daemon and hal
From: Ravi kumar Veeramally @ 2013-11-04 22:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

This patch set implements get/set protocol and get/set report
interfaces and supported functionality in daemon. Sending notifications
and notification handling in hal. Few naming fixes and error handling.
And last handling of few uHID events.

Ravi kumar Veeramally (11):
  android/hid: Rename function name set_state to notify_state
  android/hid: Retrieve BOOT_DEVICE attribute from SDP and cache it
  android/hid: Implement hid get protocol in daemon
  android/hid: Implement hid set protocol in daemon
  android/hid: Handle protocol mode notification in hal
  android/hid: Implement hid get report in daemon
  android/hid: Implement hid set report in daemon
  android/hid: Handle get report notification in hal
  android/hid: Replace header checking magic number with defines
  android/hid: Handle invalid parameters in hal
  android/hid: Handle uhid events

 android/hal-hidhost.c |  40 +++++-
 android/hal-msg.h     |  18 +++
 android/hid.c         | 353 +++++++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 384 insertions(+), 27 deletions(-)

-- 
1.8.1.2


^ permalink raw reply

* Re: [PATCH 1/3] android: Add support for handling get properties commands
From: Johan Hedberg @ 2013-11-04 19:32 UTC (permalink / raw)
  To: Szymon Janc, linux-bluetooth
In-Reply-To: <20131104191918.GE13837@x220.p-661hnu-f1>

Hi,

On Mon, Nov 04, 2013, Johan Hedberg wrote:
> Hi Szymon,
> 
> On Mon, Nov 04, 2013, Szymon Janc wrote:
> > When this commands is received all properties shall be reported to HAL.
> > ---
> >  android/adapter.c | 17 +++++++++++++++++
> >  1 file changed, 17 insertions(+)
> 
> This patch doesn't compile:
> 
>   CC       android/adapter.o
> android/adapter.c: In function ‘get_properties’:
> android/adapter.c:1125:2: error: implicit declaration of function ‘send_adapter_address’ [-Werror=implicit-function-declaration]
>   send_adapter_address();
>   ^
> cc1: all warnings being treated as errors
> make[1]: *** [android/adapter.o] Error 1

Since this was a rather trivial thing introduced by a rename patch from
Andrei E, I went ahead and fixed it myself and applied all three
patches.

Johan

^ permalink raw reply

* Re: [PATCH 1/3] android: Add support for handling get properties commands
From: Johan Hedberg @ 2013-11-04 19:19 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1383579265-24614-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Mon, Nov 04, 2013, Szymon Janc wrote:
> When this commands is received all properties shall be reported to HAL.
> ---
>  android/adapter.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)

This patch doesn't compile:

  CC       android/adapter.o
android/adapter.c: In function ‘get_properties’:
android/adapter.c:1125:2: error: implicit declaration of function ‘send_adapter_address’ [-Werror=implicit-function-declaration]
  send_adapter_address();
  ^
cc1: all warnings being treated as errors
make[1]: *** [android/adapter.o] Error 1

Johan

^ permalink raw reply


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