Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH 5/5] android: Remove not needed include
From: Szymon Janc @ 2013-10-22 13:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382448299-16887-1-git-send-email-szymon.janc@tieto.com>

---
 android/main.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/android/main.c b/android/main.c
index ba153a5..d4916ca 100644
--- a/android/main.c
+++ b/android/main.c
@@ -39,10 +39,6 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 
-#if defined(ANDROID)
-#include <private/android_filesystem_config.h>
-#endif
-
 #include <glib.h>
 
 #include "log.h"
-- 
1.8.4


^ permalink raw reply related

* [PATCH 4/5] android/hal: Use notification socket for daemon lifetime tracking
From: Szymon Janc @ 2013-10-22 13:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382448299-16887-1-git-send-email-szymon.janc@tieto.com>

If daemon exited unexpectedly HAL should be stop. With cleanup
procedure command socket is closed as first so use that to distinguish
correct action.
---
 android/hal-ipc.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index 16f2bd3..f753f10 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -88,8 +88,13 @@ static void *notification_handler(void *data)
 		}
 
 		/* socket was shutdown */
-		if (ret == 0)
-			break;
+		if (ret == 0) {
+			if (cmd_sk == -1)
+				break;
+
+			error("Notification socket closed, aborting");
+			exit(EXIT_FAILURE);
+		}
 
 		if (ret < (ssize_t) sizeof(*hal_msg)) {
 			error("Too small notification (%zd bytes), aborting",
-- 
1.8.4


^ permalink raw reply related

* [PATCH 3/5] adapter/hal: Implement adapter disable call
From: Szymon Janc @ 2013-10-22 13:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382448299-16887-1-git-send-email-szymon.janc@tieto.com>

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

diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index d5019a4..efc5962 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -115,12 +115,19 @@ static int enable(void)
 
 static int disable(void)
 {
+	int ret;
+
 	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
 
-	return BT_STATUS_UNSUPPORTED;
+	ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_MSG_OP_BT_DISABLE, 0, NULL,
+								0, NULL, NULL);
+	if (ret < 0)
+		return -ret;
+
+	return BT_STATUS_SUCCESS;
 }
 
 static void cleanup(void)
-- 
1.8.4


^ permalink raw reply related

* [PATCH 2/5] adapter/hal: Implement adapter enable call
From: Szymon Janc @ 2013-10-22 13:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382448299-16887-1-git-send-email-szymon.janc@tieto.com>

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

diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 2c8a902..d5019a4 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -98,9 +98,19 @@ fail:
 
 static int enable(void)
 {
+	int ret;
+
 	DBG("");
 
-	return BT_STATUS_UNSUPPORTED;
+	if (!interface_ready())
+		return BT_STATUS_NOT_READY;
+
+	ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_MSG_OP_BT_ENABLE, 0, NULL,
+								0, NULL, NULL);
+	if (ret < 0)
+		return -ret;
+
+	return BT_STATUS_SUCCESS;
 }
 
 static int disable(void)
-- 
1.8.4


^ permalink raw reply related

* [PATCH 1/5] android/hal: Unify HALs callbacks pointers definition
From: Szymon Janc @ 2013-10-22 13:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Those are not suppose to be modified or used outside of each HAL.
---
 android/hal-av.c        | 2 +-
 android/hal-bluetooth.c | 2 +-
 android/hal-hidhost.c   | 2 +-
 android/hal-pan.c       | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/android/hal-av.c b/android/hal-av.c
index b1c5276..0fe1b74 100644
--- a/android/hal-av.c
+++ b/android/hal-av.c
@@ -21,7 +21,7 @@
 #include "hal-log.h"
 #include "hal.h"
 
-const btav_callbacks_t *cbs = NULL;
+static const btav_callbacks_t *cbs = NULL;
 
 static bool interface_ready(void)
 {
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 5bad409..2c8a902 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -25,7 +25,7 @@
 #include "hal-msg.h"
 #include "hal-ipc.h"
 
-bt_callbacks_t *bt_hal_cbacks = NULL;
+static const bt_callbacks_t *bt_hal_cbacks = NULL;
 
 static void handle_adapter_state_changed(void *buf)
 {
diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
index e1a3e97..f941f2f 100644
--- a/android/hal-hidhost.c
+++ b/android/hal-hidhost.c
@@ -24,7 +24,7 @@
 #include "hal-msg.h"
 #include "hal-ipc.h"
 
-bthh_callbacks_t *bt_hh_cbacks;
+static const bthh_callbacks_t *bt_hh_cbacks;
 
 static bool interface_ready(void)
 {
diff --git a/android/hal-pan.c b/android/hal-pan.c
index f05a93b..4ca7cbb 100644
--- a/android/hal-pan.c
+++ b/android/hal-pan.c
@@ -21,7 +21,7 @@
 #include "hal-log.h"
 #include "hal.h"
 
-const btpan_callbacks_t *bt_pan_cbacks = NULL;
+static const btpan_callbacks_t *bt_pan_cbacks = NULL;
 
 static bool interface_ready(void)
 {
-- 
1.8.4


^ permalink raw reply related

* Re: [PATCH v3 1/6] android/hal: Make hal.h self contained
From: Johan Hedberg @ 2013-10-22 13:17 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1382445973-8285-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Tue, Oct 22, 2013, Szymon Janc wrote:
> ---
>  android/hal-av.c        | 3 ---
>  android/hal-bluetooth.c | 5 -----
>  android/hal-hidhost.c   | 3 ---
>  android/hal-pan.c       | 3 ---
>  android/hal-sock.c      | 3 ---
>  android/hal.h           | 1 +
>  6 files changed, 1 insertion(+), 17 deletions(-)

All six patches have been applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH] android: Add initial code for hidhost connect and disconnect
From: Luiz Augusto von Dentz @ 2013-10-22 13:05 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1382444176-9105-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Hi Ravi,

On Tue, Oct 22, 2013 at 3:16 PM, Ravi kumar Veeramally
<ravikumar.veeramally@linux.intel.com> wrote:
> ---
>  android/hal-hidhost.c |   45 +++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 37 insertions(+), 8 deletions(-)
>
> diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
> index 8c47e27..d68ee6c 100644
> --- a/android/hal-hidhost.c
> +++ b/android/hal-hidhost.c
> @@ -17,12 +17,17 @@
>
>  #include <stdbool.h>
>  #include <stddef.h>
> +#include <string.h>
>
>  #include <hardware/bluetooth.h>
>  #include <hardware/bt_hh.h>
>
>  #include "hal-log.h"
>  #include "hal.h"
> +#include "hal-msg.h"
> +#include "hal-ipc.h"
> +
> +#define BT_DEVICE_ADDRESS_LENGTH       6
>
>  bthh_callbacks_t *bt_hh_cbacks;
>
> @@ -33,6 +38,8 @@ static bool interface_ready(void)
>
>  static bt_status_t bt_hidhost_connect(bt_bdaddr_t *bd_addr)
>  {
> +       struct hal_msg_cmd_bt_hid_connect cmd;
> +
>         DBG("");
>
>         if (!interface_ready())
> @@ -41,11 +48,22 @@ static bt_status_t bt_hidhost_connect(bt_bdaddr_t *bd_addr)
>         if (!bd_addr)
>                 return BT_STATUS_PARM_INVALID;
>
> -       return BT_STATUS_UNSUPPORTED;
> +       memcpy(cmd.bdaddr, bd_addr, BT_DEVICE_ADDRESS_LENGTH);
> +
> +       if (hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_MSG_OP_BT_HID_CONNECT,
> +                                       sizeof(cmd), &cmd,
> +                                       0, NULL, NULL) < 0) {
> +               error("Failed to connect hid device");
> +               return BT_STATUS_FAIL;
> +       }
> +
> +       return BT_STATUS_SUCCESS;
>  }
>
>  static bt_status_t bt_hidhost_disconnect(bt_bdaddr_t *bd_addr)
>  {
> +       struct hal_msg_cmd_bt_hid_disconnect cmd;
> +
>         DBG("");
>
>         if (!interface_ready())
> @@ -54,7 +72,16 @@ static bt_status_t bt_hidhost_disconnect(bt_bdaddr_t *bd_addr)
>         if (!bd_addr)
>                 return BT_STATUS_PARM_INVALID;
>
> -       return BT_STATUS_UNSUPPORTED;
> +       memcpy(cmd.bdaddr, bd_addr, BT_DEVICE_ADDRESS_LENGTH);
> +
> +       if (hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_MSG_OP_BT_HID_DISCONNECT,
> +                                       sizeof(cmd), &cmd,
> +                                       0, NULL, NULL) < 0) {
> +               error("Failed to disconnect hid device");
> +               return BT_STATUS_FAIL;
> +       }
> +
> +       return BT_STATUS_SUCCESS;
>  }
>
>  static bt_status_t bt_hidhost_virtual_unplug(bt_bdaddr_t *bd_addr)
> @@ -158,14 +185,20 @@ static bt_status_t bt_hidhost_send_data(bt_bdaddr_t *bd_addr, char *data)
>
>  static bt_status_t bt_hidhost_init(bthh_callbacks_t *callbacks)
>  {
> +       struct hal_msg_cmd_register_module cmd;
>         DBG("");
>
>         /* store reference to user callbacks */
>         bt_hh_cbacks = callbacks;
>
> -       /* TODO: start HID Host thread */
> +       cmd.service_id = HAL_SERVICE_ID_HIDHOST;
>
> -       /* TODO: enable service */
> +       if (hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_MSG_OP_REGISTER_MODULE,
> +                                       sizeof(cmd), &cmd, 0, NULL, NULL) < 0) {
> +               error("Failed to register 'hidhost'' service");
> +
> +               return BT_STATUS_FAIL;
> +       }
>
>         return BT_STATUS_SUCCESS;
>  }
> @@ -177,10 +210,6 @@ static void bt_hidhost_cleanup(void)
>         if (!interface_ready())
>                 return;
>
> -       /* TODO: disable service */
> -
> -       /* TODO: stop HID Host thread */
> -
>         bt_hh_cbacks = NULL;
>  }
>
> --
> 1.7.9.5

Applied, thanks.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* [PATCH v3 6/6] android/hal: Add initial support for handling adapter notifications
From: Szymon Janc @ 2013-10-22 12:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382445973-8285-1-git-send-email-szymon.janc@tieto.com>

Only adapter state callback is handled for now.
---
 android/hal-bluetooth.c | 24 ++++++++++++++++++++++++
 android/hal-ipc.c       |  4 ++++
 android/hal.h           |  2 ++
 3 files changed, 30 insertions(+)

diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 6adf0cb..5bad409 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -27,6 +27,30 @@
 
 bt_callbacks_t *bt_hal_cbacks = NULL;
 
+static void handle_adapter_state_changed(void *buf)
+{
+	struct hal_msg_ev_bt_adapter_state_changed *ev = buf;
+
+	if (bt_hal_cbacks->adapter_state_changed_cb)
+		bt_hal_cbacks->adapter_state_changed_cb(ev->state);
+}
+
+/* will be called from notification thread context */
+void bt_notify_adapter(uint16_t opcode, void *buf, uint16_t len)
+{
+	if (!bt_hal_cbacks)
+		return;
+
+	switch (opcode) {
+	case HAL_MSG_EV_BT_ADAPTER_STATE_CHANGED:
+		handle_adapter_state_changed(buf);
+		break;
+	default:
+		DBG("Unhandled callback opcode=0x%x", opcode);
+		break;
+	}
+}
+
 static bool interface_ready(void)
 {
 	return bt_hal_cbacks != NULL;
diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index f1a9d18..16f2bd3 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -27,6 +27,7 @@
 
 #include <cutils/properties.h>
 
+#include "hal.h"
 #include "hal-msg.h"
 #include "hal-log.h"
 #include "hal-ipc.h"
@@ -44,6 +45,9 @@ static pthread_t notif_th = 0;
 static void notification_dispatch(struct hal_msg_hdr *msg, int fd)
 {
 	switch (msg->service_id) {
+	case HAL_SERVICE_ID_BLUETOOTH:
+		bt_notify_adapter(msg->opcode, msg->payload, msg->len);
+		break;
 	default:
 		DBG("Unhandled notification service=%d opcode=0x%x",
 						msg->service_id, msg->opcode);
diff --git a/android/hal.h b/android/hal.h
index e3c4122..ef9a107 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -25,3 +25,5 @@ btsock_interface_t *bt_get_sock_interface(void);
 bthh_interface_t *bt_get_hidhost_interface(void);
 btpan_interface_t *bt_get_pan_interface(void);
 btav_interface_t *bt_get_av_interface(void);
+
+void bt_notify_adapter(uint16_t opcode, void *buf, uint16_t len);
-- 
1.8.4


^ permalink raw reply related

* [PATCH v3 5/6] android/hal: Add initial code for notification handling
From: Szymon Janc @ 2013-10-22 12:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382445973-8285-1-git-send-email-szymon.janc@tieto.com>

This adds a dedicated thread that will read from notification sockets
and dispatch it to appropriate service notification function.
---
 Makefile.android  |   2 +
 android/hal-ipc.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 107 insertions(+), 2 deletions(-)

diff --git a/Makefile.android b/Makefile.android
index 720df69..052d755 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -55,6 +55,8 @@ android_haltest_LDADD = android/libhal-internal.la
 
 android_haltest_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android
 
+android_haltest_LDFLAGS = -pthread
+
 endif
 
 EXTRA_DIST += android/Android.mk android/log.c android/device.c \
diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index 9aac9c0..f1a9d18 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -39,6 +39,95 @@ static int notif_sk = -1;
 
 static pthread_mutex_t cmd_sk_mutex = PTHREAD_MUTEX_INITIALIZER;
 
+static pthread_t notif_th = 0;
+
+static void notification_dispatch(struct hal_msg_hdr *msg, int fd)
+{
+	switch (msg->service_id) {
+	default:
+		DBG("Unhandled notification service=%d opcode=0x%x",
+						msg->service_id, msg->opcode);
+		break;
+	}
+}
+
+static void *notification_handler(void *data)
+{
+	struct msghdr msg;
+	struct iovec iv;
+	struct cmsghdr *cmsg;
+	char cmsgbuf[CMSG_SPACE(sizeof(int))];
+	char buf[BLUEZ_HAL_MTU];
+	struct hal_msg_hdr *hal_msg = (void *) buf;
+	ssize_t ret;
+	int fd;
+
+	while (true) {
+		memset(&msg, 0, sizeof(msg));
+		memset(buf, 0, sizeof(buf));
+		memset(cmsgbuf, 0, sizeof(cmsgbuf));
+
+		iv.iov_base = hal_msg;
+		iv.iov_len = sizeof(buf);
+
+		msg.msg_iov = &iv;
+		msg.msg_iovlen = 1;
+
+		msg.msg_control = cmsgbuf;
+		msg.msg_controllen = sizeof(cmsgbuf);
+
+		ret = recvmsg(notif_sk, &msg, 0);
+		if (ret < 0) {
+			error("Receiving notifications failed, aborting :%s",
+							strerror(errno));
+			exit(EXIT_FAILURE);
+		}
+
+		/* socket was shutdown */
+		if (ret == 0)
+			break;
+
+		if (ret < (ssize_t) sizeof(*hal_msg)) {
+			error("Too small notification (%zd bytes), aborting",
+									ret);
+			exit(EXIT_FAILURE);
+		}
+
+		if (hal_msg->opcode < HAL_MSG_MINIMUM_EVENT) {
+			error("Invalid notification (0x%x), aborting",
+							hal_msg->opcode);
+			exit(EXIT_FAILURE);
+		}
+
+		if (ret != (ssize_t) (sizeof(*hal_msg) + hal_msg->len)) {
+			error("Malformed notification(%zd bytes), aborting",
+									ret);
+			exit(EXIT_FAILURE);
+		}
+
+		fd = -1;
+
+		/* Receive auxiliary data in msg */
+		for (cmsg = CMSG_FIRSTHDR(&msg); !cmsg;
+					cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+			if (cmsg->cmsg_level == SOL_SOCKET
+					&& cmsg->cmsg_type == SCM_RIGHTS) {
+				memcpy(&fd, CMSG_DATA(cmsg), sizeof(int));
+				break;
+			}
+		}
+
+		notification_dispatch(hal_msg, fd);
+	}
+
+	close(notif_sk);
+	notif_sk = -1;
+
+	DBG("exit");
+
+	return NULL;
+}
+
 static int accept_connection(int sk)
 {
 	int err;
@@ -126,6 +215,18 @@ bool hal_ipc_init(void)
 
 	close(sk);
 
+	err = pthread_create(&notif_th, NULL, notification_handler, NULL);
+	if (err < 0) {
+		notif_th = 0;
+		error("Failed to start notification thread: %d (%s)", -err,
+							strerror(-err));
+		close(cmd_sk);
+		cmd_sk = -1;
+		close(notif_sk);
+		notif_sk = -1;
+		return false;
+	}
+
 	return true;
 }
 
@@ -134,8 +235,10 @@ void hal_ipc_cleanup(void)
 	close(cmd_sk);
 	cmd_sk = -1;
 
-	close(notif_sk);
-	notif_sk = -1;
+	shutdown(notif_sk, SHUT_RD);
+
+	pthread_join(notif_th, NULL);
+	notif_th = 0;
 }
 
 int hal_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len, void *param,
-- 
1.8.4


^ permalink raw reply related

* [PATCH v3 4/6] android: Define minimum legal notification event ID
From: Szymon Janc @ 2013-10-22 12:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382445973-8285-1-git-send-email-szymon.janc@tieto.com>

All legal events IDs should be above this value.
---
 android/hal-msg.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index 33acd41..9ff0510 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -32,6 +32,8 @@ struct hal_msg_hdr {
 	uint8_t payload[0];
 } __attribute__((packed));
 
+#define HAL_MSG_MINIMUM_EVENT		0x81
+
 #define HAL_SERVICE_ID_CORE		0
 #define HAL_SERVICE_ID_BLUETOOTH	1
 #define HAL_SERVICE_ID_SOCK		2
-- 
1.8.4


^ permalink raw reply related

* [PATCH v3 3/6] android: Fix non-existing event definition
From: Szymon Janc @ 2013-10-22 12:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382445973-8285-1-git-send-email-szymon.janc@tieto.com>

There is no ERROR notification id.
---
 android/hal-msg.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index a1b539f..33acd41 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -249,7 +249,6 @@ struct hal_msg_cmd_bt_hid_send_data {
 
 /* Notifications and confirmations */
 
-#define HAL_MSG_EV_BT_ERROR			0x80
 
 #define HAL_MSG_EV_BT_ADAPTER_STATE_CHANGED	0x81
 struct hal_msg_ev_bt_adapter_state_changed {
-- 
1.8.4


^ permalink raw reply related

* [PATCH v3 2/6] android: Define helper payload field in hal_msg_hdr
From: Szymon Janc @ 2013-10-22 12:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382445973-8285-1-git-send-email-szymon.janc@tieto.com>

This will allow for convenient access to payload.
---
 android/hal-msg.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index 9dcfbf6..a1b539f 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -29,6 +29,7 @@ struct hal_msg_hdr {
 	uint8_t service_id;
 	uint8_t opcode;
 	uint16_t len;
+	uint8_t payload[0];
 } __attribute__((packed));
 
 #define HAL_SERVICE_ID_CORE		0
-- 
1.8.4


^ permalink raw reply related

* [PATCH v3 1/6] android/hal: Make hal.h self contained
From: Szymon Janc @ 2013-10-22 12:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/hal-av.c        | 3 ---
 android/hal-bluetooth.c | 5 -----
 android/hal-hidhost.c   | 3 ---
 android/hal-pan.c       | 3 ---
 android/hal-sock.c      | 3 ---
 android/hal.h           | 1 +
 6 files changed, 1 insertion(+), 17 deletions(-)

diff --git a/android/hal-av.c b/android/hal-av.c
index ef45066..b1c5276 100644
--- a/android/hal-av.c
+++ b/android/hal-av.c
@@ -18,9 +18,6 @@
 #include <stdbool.h>
 #include <stddef.h>
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_av.h>
-
 #include "hal-log.h"
 #include "hal.h"
 
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 5b07070..6adf0cb 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -20,11 +20,6 @@
 #include <stdbool.h>
 #include <string.h>
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_sock.h>
-#include <hardware/bt_hh.h>
-#include <hardware/bt_pan.h>
-
 #include "hal-log.h"
 #include "hal.h"
 #include "hal-msg.h"
diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
index 8c47e27..2d5d091 100644
--- a/android/hal-hidhost.c
+++ b/android/hal-hidhost.c
@@ -18,9 +18,6 @@
 #include <stdbool.h>
 #include <stddef.h>
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_hh.h>
-
 #include "hal-log.h"
 #include "hal.h"
 
diff --git a/android/hal-pan.c b/android/hal-pan.c
index 645fe8c..f05a93b 100644
--- a/android/hal-pan.c
+++ b/android/hal-pan.c
@@ -18,9 +18,6 @@
 #include <stdbool.h>
 #include <stddef.h>
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_pan.h>
-
 #include "hal-log.h"
 #include "hal.h"
 
diff --git a/android/hal-sock.c b/android/hal-sock.c
index dab3756..364663c 100644
--- a/android/hal-sock.c
+++ b/android/hal-sock.c
@@ -17,9 +17,6 @@
 
 #include <stdlib.h>
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_sock.h>
-
 #include "hal-log.h"
 #include "hal.h"
 
diff --git a/android/hal.h b/android/hal.h
index d984336..e3c4122 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -15,6 +15,7 @@
  *
  */
 
+#include <hardware/bluetooth.h>
 #include <hardware/bt_sock.h>
 #include <hardware/bt_hh.h>
 #include <hardware/bt_pan.h>
-- 
1.8.4


^ permalink raw reply related

* [PATCH] android: Add initial code for hidhost connect and disconnect
From: Ravi kumar Veeramally @ 2013-10-22 12:16 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

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

diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
index 8c47e27..d68ee6c 100644
--- a/android/hal-hidhost.c
+++ b/android/hal-hidhost.c
@@ -17,12 +17,17 @@
 
 #include <stdbool.h>
 #include <stddef.h>
+#include <string.h>
 
 #include <hardware/bluetooth.h>
 #include <hardware/bt_hh.h>
 
 #include "hal-log.h"
 #include "hal.h"
+#include "hal-msg.h"
+#include "hal-ipc.h"
+
+#define BT_DEVICE_ADDRESS_LENGTH	6
 
 bthh_callbacks_t *bt_hh_cbacks;
 
@@ -33,6 +38,8 @@ static bool interface_ready(void)
 
 static bt_status_t bt_hidhost_connect(bt_bdaddr_t *bd_addr)
 {
+	struct hal_msg_cmd_bt_hid_connect cmd;
+
 	DBG("");
 
 	if (!interface_ready())
@@ -41,11 +48,22 @@ static bt_status_t bt_hidhost_connect(bt_bdaddr_t *bd_addr)
 	if (!bd_addr)
 		return BT_STATUS_PARM_INVALID;
 
-	return BT_STATUS_UNSUPPORTED;
+	memcpy(cmd.bdaddr, bd_addr, BT_DEVICE_ADDRESS_LENGTH);
+
+	if (hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_MSG_OP_BT_HID_CONNECT,
+					sizeof(cmd), &cmd,
+					0, NULL, NULL) < 0) {
+		error("Failed to connect hid device");
+		return BT_STATUS_FAIL;
+	}
+
+	return BT_STATUS_SUCCESS;
 }
 
 static bt_status_t bt_hidhost_disconnect(bt_bdaddr_t *bd_addr)
 {
+	struct hal_msg_cmd_bt_hid_disconnect cmd;
+
 	DBG("");
 
 	if (!interface_ready())
@@ -54,7 +72,16 @@ static bt_status_t bt_hidhost_disconnect(bt_bdaddr_t *bd_addr)
 	if (!bd_addr)
 		return BT_STATUS_PARM_INVALID;
 
-	return BT_STATUS_UNSUPPORTED;
+	memcpy(cmd.bdaddr, bd_addr, BT_DEVICE_ADDRESS_LENGTH);
+
+	if (hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_MSG_OP_BT_HID_DISCONNECT,
+					sizeof(cmd), &cmd,
+					0, NULL, NULL) < 0) {
+		error("Failed to disconnect hid device");
+		return BT_STATUS_FAIL;
+	}
+
+	return BT_STATUS_SUCCESS;
 }
 
 static bt_status_t bt_hidhost_virtual_unplug(bt_bdaddr_t *bd_addr)
@@ -158,14 +185,20 @@ static bt_status_t bt_hidhost_send_data(bt_bdaddr_t *bd_addr, char *data)
 
 static bt_status_t bt_hidhost_init(bthh_callbacks_t *callbacks)
 {
+	struct hal_msg_cmd_register_module cmd;
 	DBG("");
 
 	/* store reference to user callbacks */
 	bt_hh_cbacks = callbacks;
 
-	/* TODO: start HID Host thread */
+	cmd.service_id = HAL_SERVICE_ID_HIDHOST;
 
-	/* TODO: enable service */
+	if (hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_MSG_OP_REGISTER_MODULE,
+					sizeof(cmd), &cmd, 0, NULL, NULL) < 0) {
+		error("Failed to register 'hidhost'' service");
+
+		return BT_STATUS_FAIL;
+	}
 
 	return BT_STATUS_SUCCESS;
 }
@@ -177,10 +210,6 @@ static void bt_hidhost_cleanup(void)
 	if (!interface_ready())
 		return;
 
-	/* TODO: disable service */
-
-	/* TODO: stop HID Host thread */
-
 	bt_hh_cbacks = NULL;
 }
 
-- 
1.7.9.5


^ permalink raw reply related

* Re: [PATCH] android/hal: Fix receiving of commands with no response parameter
From: Luiz Augusto von Dentz @ 2013-10-22 12:11 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1382443438-28452-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Tue, Oct 22, 2013 at 3:03 PM, Szymon Janc <szymon.janc@tieto.com> wrote:
> This fix receiving of error response in case command has no reply
> parameters.
> ---
>  android/hal-ipc.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/android/hal-ipc.c b/android/hal-ipc.c
> index 041441d..b264bfe 100644
> --- a/android/hal-ipc.c
> +++ b/android/hal-ipc.c
> @@ -260,6 +260,7 @@ int hal_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len, void *param,
>
>         if (!rsp || rsp_len == 0) {
>                 memset(&err, 0, sizeof(err));
> +               rsp_len = sizeof(err);
>                 rsp = &err;
>         }
>
> --
> 1.8.4

Pushed, thanks.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* [PATCH] android/hal: Fix receiving of commands with no response parameter
From: Szymon Janc @ 2013-10-22 12:03 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

This fix receiving of error response in case command has no reply
parameters.
---
 android/hal-ipc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index 041441d..b264bfe 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -260,6 +260,7 @@ int hal_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len, void *param,
 
 	if (!rsp || rsp_len == 0) {
 		memset(&err, 0, sizeof(err));
+		rsp_len = sizeof(err);
 		rsp = &err;
 	}
 
-- 
1.8.4


^ permalink raw reply related

* [PATCH v2 3/3] android/hal: Add initial support for handling adapter notifications
From: Szymon Janc @ 2013-10-22 11:18 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382440703-21612-1-git-send-email-szymon.janc@tieto.com>

Only adapter state callback is handled for now.
---
 android/hal-bluetooth.c | 24 ++++++++++++++++++++++++
 android/hal-ipc.c       |  4 ++++
 android/hal.h           |  2 ++
 3 files changed, 30 insertions(+)

diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 6adf0cb..5bad409 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -27,6 +27,30 @@
 
 bt_callbacks_t *bt_hal_cbacks = NULL;
 
+static void handle_adapter_state_changed(void *buf)
+{
+	struct hal_msg_ev_bt_adapter_state_changed *ev = buf;
+
+	if (bt_hal_cbacks->adapter_state_changed_cb)
+		bt_hal_cbacks->adapter_state_changed_cb(ev->state);
+}
+
+/* will be called from notification thread context */
+void bt_notify_adapter(uint16_t opcode, void *buf, uint16_t len)
+{
+	if (!bt_hal_cbacks)
+		return;
+
+	switch (opcode) {
+	case HAL_MSG_EV_BT_ADAPTER_STATE_CHANGED:
+		handle_adapter_state_changed(buf);
+		break;
+	default:
+		DBG("Unhandled callback opcode=0x%x", opcode);
+		break;
+	}
+}
+
 static bool interface_ready(void)
 {
 	return bt_hal_cbacks != NULL;
diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index ef58a7c..041441d 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -27,6 +27,7 @@
 
 #include <cutils/properties.h>
 
+#include "hal.h"
 #include "hal-msg.h"
 #include "hal-log.h"
 #include "hal-ipc.h"
@@ -44,6 +45,9 @@ static pthread_t notif_th = 0;
 static void notification_dispatch(struct hal_msg_hdr *msg, int fd)
 {
 	switch (msg->service_id) {
+	case HAL_SERVICE_ID_BLUETOOTH:
+		bt_notify_adapter(msg->opcode, msg + 1, msg->len);
+		break;
 	default:
 		DBG("Unhandled notification service=%d opcode=0x%x",
 						msg->service_id, msg->opcode);
diff --git a/android/hal.h b/android/hal.h
index e3c4122..ef9a107 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -25,3 +25,5 @@ btsock_interface_t *bt_get_sock_interface(void);
 bthh_interface_t *bt_get_hidhost_interface(void);
 btpan_interface_t *bt_get_pan_interface(void);
 btav_interface_t *bt_get_av_interface(void);
+
+void bt_notify_adapter(uint16_t opcode, void *buf, uint16_t len);
-- 
1.8.4


^ permalink raw reply related

* [PATCH v2 2/3] android/hal: Add initial code for notification handling
From: Szymon Janc @ 2013-10-22 11:18 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382440703-21612-1-git-send-email-szymon.janc@tieto.com>

This adds a dedicated thread that will read from notification sockets
and dispatch it to appropriate service notification function.
---
 Makefile.android  |   2 +
 android/hal-ipc.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 107 insertions(+), 2 deletions(-)

diff --git a/Makefile.android b/Makefile.android
index aebc715..889b36e 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -54,6 +54,8 @@ android_haltest_LDADD = android/libhal-internal.la
 
 android_haltest_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android
 
+android_haltest_LDFLAGS = -pthread
+
 endif
 
 EXTRA_DIST += android/Android.mk android/log.c android/device.c \
diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index 8d40271..ef58a7c 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -39,6 +39,95 @@ static int notif_sk = -1;
 
 static pthread_mutex_t cmd_sk_mutex = PTHREAD_MUTEX_INITIALIZER;
 
+static pthread_t notif_th = 0;
+
+static void notification_dispatch(struct hal_msg_hdr *msg, int fd)
+{
+	switch (msg->service_id) {
+	default:
+		DBG("Unhandled notification service=%d opcode=0x%x",
+						msg->service_id, msg->opcode);
+		break;
+	}
+}
+
+static void *notification_handler(void *data)
+{
+	struct msghdr msg;
+	struct iovec iv;
+	struct cmsghdr *cmsg;
+	char cmsgbuf[CMSG_SPACE(sizeof(int))];
+	char buf[BLUEZ_HAL_MTU];
+	struct hal_msg_hdr *hal_msg = (void *) buf;
+	ssize_t ret;
+	int fd;
+
+	while (true) {
+		memset(&msg, 0, sizeof(msg));
+		memset(buf, 0, sizeof(buf));
+		memset(cmsgbuf, 0, sizeof(cmsgbuf));
+
+		iv.iov_base = hal_msg;
+		iv.iov_len = sizeof(buf);
+
+		msg.msg_iov = &iv;
+		msg.msg_iovlen = 1;
+
+		msg.msg_control = cmsgbuf;
+		msg.msg_controllen = sizeof(cmsgbuf);
+
+		ret = recvmsg(notif_sk, &msg, 0);
+		if (ret < 0) {
+			error("Receiving notifications failed, aborting :%s",
+							strerror(errno));
+			exit(EXIT_FAILURE);
+		}
+
+		/* socket was shutdown */
+		if (ret == 0)
+			break;
+
+		if (ret < (ssize_t) sizeof(*hal_msg)) {
+			error("Too small notification (%zd bytes), aborting",
+									ret);
+			exit(EXIT_FAILURE);
+		}
+
+		if (hal_msg->opcode < HAL_MSG_EV_BT_ERROR) {
+			error("Invalid notification (0x%x), aborting",
+							hal_msg->opcode);
+			exit(EXIT_FAILURE);
+		}
+
+		if (ret != (ssize_t) (sizeof(*hal_msg) + hal_msg->len)) {
+			error("Malformed notification(%zd bytes), aborting",
+									ret);
+			exit(EXIT_FAILURE);
+		}
+
+		fd = -1;
+
+		/* Receive auxiliary data in msg */
+		for (cmsg = CMSG_FIRSTHDR(&msg); !cmsg;
+					cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+			if (cmsg->cmsg_level == SOL_SOCKET
+					&& cmsg->cmsg_type == SCM_RIGHTS) {
+				memcpy(&fd, CMSG_DATA(cmsg), sizeof(int));
+				break;
+			}
+		}
+
+		notification_dispatch(hal_msg, fd);
+	}
+
+	close(notif_sk);
+	notif_sk = -1;
+
+	DBG("exit");
+
+	return NULL;
+}
+
 static int accept_connection(int sk)
 {
 	int err;
@@ -126,6 +215,18 @@ bool hal_ipc_init(void)
 
 	close(sk);
 
+	err = pthread_create(&notif_th, NULL, notification_handler, NULL);
+	if (err < 0) {
+		notif_th = 0;
+		error("Failed to start notification thread: %d (%s)", -err,
+							strerror(-err));
+		close(cmd_sk);
+		cmd_sk = -1;
+		close(notif_sk);
+		notif_sk = -1;
+		return false;
+	}
+
 	return true;
 }
 
@@ -134,8 +235,10 @@ void hal_ipc_cleanup(void)
 	close(cmd_sk);
 	cmd_sk = -1;
 
-	close(notif_sk);
-	notif_sk = -1;
+	shutdown(notif_sk, SHUT_RD);
+
+	pthread_join(notif_th, NULL);
+	notif_th = 0;
 }
 
 int hal_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len, void *param,
-- 
1.8.4


^ permalink raw reply related

* [PATCH v2 1/3] android/hal: Make hal.h self contained
From: Szymon Janc @ 2013-10-22 11:18 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/hal-av.c        | 3 ---
 android/hal-bluetooth.c | 5 -----
 android/hal-hidhost.c   | 3 ---
 android/hal-pan.c       | 3 ---
 android/hal-sock.c      | 3 ---
 android/hal.h           | 1 +
 6 files changed, 1 insertion(+), 17 deletions(-)

diff --git a/android/hal-av.c b/android/hal-av.c
index ef45066..b1c5276 100644
--- a/android/hal-av.c
+++ b/android/hal-av.c
@@ -18,9 +18,6 @@
 #include <stdbool.h>
 #include <stddef.h>
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_av.h>
-
 #include "hal-log.h"
 #include "hal.h"
 
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 5b07070..6adf0cb 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -20,11 +20,6 @@
 #include <stdbool.h>
 #include <string.h>
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_sock.h>
-#include <hardware/bt_hh.h>
-#include <hardware/bt_pan.h>
-
 #include "hal-log.h"
 #include "hal.h"
 #include "hal-msg.h"
diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
index 8c47e27..2d5d091 100644
--- a/android/hal-hidhost.c
+++ b/android/hal-hidhost.c
@@ -18,9 +18,6 @@
 #include <stdbool.h>
 #include <stddef.h>
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_hh.h>
-
 #include "hal-log.h"
 #include "hal.h"
 
diff --git a/android/hal-pan.c b/android/hal-pan.c
index 645fe8c..f05a93b 100644
--- a/android/hal-pan.c
+++ b/android/hal-pan.c
@@ -18,9 +18,6 @@
 #include <stdbool.h>
 #include <stddef.h>
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_pan.h>
-
 #include "hal-log.h"
 #include "hal.h"
 
diff --git a/android/hal-sock.c b/android/hal-sock.c
index dab3756..364663c 100644
--- a/android/hal-sock.c
+++ b/android/hal-sock.c
@@ -17,9 +17,6 @@
 
 #include <stdlib.h>
 
-#include <hardware/bluetooth.h>
-#include <hardware/bt_sock.h>
-
 #include "hal-log.h"
 #include "hal.h"
 
diff --git a/android/hal.h b/android/hal.h
index d984336..e3c4122 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -15,6 +15,7 @@
  *
  */
 
+#include <hardware/bluetooth.h>
 #include <hardware/bt_sock.h>
 #include <hardware/bt_hh.h>
 #include <hardware/bt_pan.h>
-- 
1.8.4


^ permalink raw reply related

* [PATCH] android: Add initial UHID code
From: Andrei Emeltchenko @ 2013-10-22 11:17 UTC (permalink / raw)
  To: linux-bluetooth

From: Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>

---
 Makefile.android  |   3 +-
 android/hidhost.c | 244 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 246 insertions(+), 1 deletion(-)
 create mode 100644 android/hidhost.c

diff --git a/Makefile.android b/Makefile.android
index aebc715..4ff3abe 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -9,7 +9,8 @@ android_bluetoothd_SOURCES =	android/main.c \
 				src/shared/util.h src/shared/util.c \
 				src/shared/mgmt.h src/shared/mgmt.c \
 				android/adapter.h android/adapter.c \
-				android/ipc.h android/ipc.c
+				android/ipc.h android/ipc.c \
+				android/hidhost.c
 
 android_bluetoothd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
 
diff --git a/android/hidhost.c b/android/hidhost.c
new file mode 100644
index 0000000..4ab914e
--- /dev/null
+++ b/android/hidhost.c
@@ -0,0 +1,244 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2013  Intel Corporation. All rights reserved.
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdbool.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <linux/uhid.h>
+
+#include "log.h"
+#include "adapter.h"
+#include "device.h"
+
+#define UHID_DEVICE_FILE        "/dev/uhid"
+
+struct input_device {
+	uint16_t                id;
+	struct bt_device       *device;
+	int                     uhid_fd;
+	guint                   uhid_watch_id;
+};
+
+static GSList *devices = NULL;
+
+static int uhid_create(int fd)
+{
+	struct uhid_event ev;
+
+	/* create uHID device */
+	memset(&ev, 0, sizeof(ev));
+	ev.type = UHID_CREATE;
+	strcpy((char *) ev.u.create.name, "bluez-input-device");
+	ev.u.create.vendor = 0;
+	ev.u.create.product = 0;
+	ev.u.create.version = 0;
+	ev.u.create.country = 0;
+	ev.u.create.bus = BUS_BLUETOOTH;
+	ev.u.create.rd_data = 0;
+	ev.u.create.rd_size = 0;
+
+	if (write(fd, &ev, sizeof(ev)) < 0) {
+		error("Failed to create uHID device: %s", strerror(errno));
+		return -errno;
+	}
+
+	return 0;
+}
+
+static void uhid_destroy(int fd)
+{
+	struct uhid_event ev;
+
+	/* destroy uHID device */
+	memset(&ev, 0, sizeof(ev));
+	ev.type = UHID_DESTROY;
+
+	if (write(fd, &ev, sizeof(ev)) < 0)
+		error("Failed to destroy uHID device: %s", strerror(errno));
+}
+
+static int uhid_send_input(int fd, uint8_t *data, ssize_t size)
+{
+	struct uhid_event ev;
+
+	/* send data to uHID device */
+	memset(&ev, 0, sizeof(ev));
+	ev.type = UHID_INPUT;
+	ev.u.input.size = size;
+	memcpy(ev.u.input.data, data, size);
+
+	if (write(fd, &ev, sizeof(ev)) < 0) {
+		error("Failed to send input to uHID device: %s", strerror(errno));
+		return -errno;
+	}
+
+	return 0;
+} 
+
+static int get_report(int fd)
+{
+	/* TODO: prepare get_report request */
+
+	return uhid_send_input(fd, NULL, 0);
+}
+
+static int set_report(int fd)
+{
+	/* TODO: prepare set_report request */
+
+	return uhid_send_input(fd, NULL, 0);
+}
+
+static int get_protocol(int fd)
+{
+	/* TODO: prepare get_protocol request */
+
+	return uhid_send_input(fd, NULL, 0);
+}
+
+static int set_protocol(int fd)
+{
+	/* TODO: prepare set_protocol request */
+
+	return uhid_send_input(fd, NULL, 0);
+}
+
+static gboolean uhid_event_cb(GIOChannel *io, GIOCondition cond,
+                                                        gpointer user_data)
+{
+	struct input_device *inputdev = user_data;
+	struct uhid_event ev;
+	ssize_t bread;
+	int fd;
+
+	if (cond & (G_IO_ERR | G_IO_NVAL))
+		goto failed;
+
+	fd = g_io_channel_unix_get_fd(io);
+	memset(&ev, 0, sizeof(ev));
+
+	bread = read(fd, &ev, sizeof(ev));
+	if (bread < 0) {
+		int err = -errno;
+		DBG("uhid-dev read: %s(%d)", strerror(-err), -err);
+		goto failed;
+	}
+
+	DBG("uHID event type %d received", ev.type);
+
+	switch (ev.type) {
+	case UHID_START:
+	case UHID_STOP:
+	case UHID_OPEN:
+	case UHID_CLOSE:
+		break;
+	case UHID_OUTPUT:
+	case UHID_FEATURE:
+		// TODO inform hal_if through ipc
+		break;
+	case UHID_OUTPUT_EV:
+		DBG("Unsupported uHID output event: type %d code %d value %d",
+			ev.u.output_ev.type, ev.u.output_ev.code,
+			ev.u.output_ev.value);
+		break;
+	default:
+		warn("unexpected uHID event");
+		break;
+	}
+
+	return TRUE;
+
+failed:
+	inputdev->uhid_watch_id = 0;
+	return FALSE;
+}
+
+static struct input_device *input_new_device(struct bt_device *device)
+{
+	struct input_device *inputdev;
+
+	inputdev = g_try_new0(struct input_device, 1);
+	if (!inputdev)
+		return NULL;
+
+	return inputdev;
+}
+
+static void input_free_device(struct input_device *inputdev)
+{
+	devices = g_slist_remove(devices, inputdev);
+	g_free(inputdev);
+}
+
+
+static struct input_device *input_register_device(struct bt_device *device)
+{
+	struct input_device *inputdev;
+	GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_NVAL;
+	GIOChannel *io;
+
+	inputdev = input_new_device(device);
+	if (!inputdev)
+		return NULL;
+
+	inputdev->uhid_fd = open(UHID_DEVICE_FILE, O_RDWR | O_CLOEXEC);
+	if (inputdev->uhid_fd < 0) {
+		error("Failed to open uHID device: %s(%d)", strerror(errno),
+									errno);
+		input_free_device(inputdev);
+		return NULL;
+	}
+
+	io = g_io_channel_unix_new(inputdev->uhid_fd);
+	g_io_channel_set_encoding(io, NULL, NULL);
+	inputdev->uhid_watch_id = g_io_add_watch(io, cond, uhid_event_cb,
+								inputdev);
+	g_io_channel_unref(io);
+
+	devices = g_slist_append(devices, inputdev);
+
+	return inputdev;
+}
+
+static int input_unregister_device(struct input_device *inputdev)
+{
+	if (inputdev->uhid_watch_id) {
+		g_source_remove(inputdev->uhid_watch_id);
+		inputdev->uhid_watch_id = 0;
+	}
+
+	uhid_destroy(inputdev->uhid_fd);
+	close(inputdev->uhid_fd);
+	inputdev->uhid_fd = -1;
+
+	input_free_device(inputdev);
+
+	return 0;
+}
-- 
1.8.1.2


^ permalink raw reply related

* Re: [PATCH 0/3] android: add support for hidhost to haltest
From: Johan Hedberg @ 2013-10-22 11:15 UTC (permalink / raw)
  To: Jerzy Kasenberg; +Cc: linux-bluetooth
In-Reply-To: <1382439747-13864-1-git-send-email-jerzy.kasenberg@tieto.com>

Hi Jerzy,

On Tue, Oct 22, 2013, Jerzy Kasenberg wrote:
> - adds support for hidhost
> - adds tab completion for hidhost
> - adds help for hidhost
> - magic number to #define change for buffer sizes
> 
> Jerzy Kasenberg (3):
>   android: Add definition of buffer sizes to haltest
>   android: Add calls to hidhost interface to haltest
>   android: Add help to hidhost in haltest
> 
>  Makefile.android          |    2 +
>  android/Android.mk        |    1 +
>  android/client/haltest.c  |    1 +
>  android/client/if-bt.c    |   10 +-
>  android/client/if-hh.c    |  431 +++++++++++++++++++++++++++++++++++++++++++++
>  android/client/if-main.h  |    2 +
>  android/client/textconv.c |    2 +-
>  android/client/textconv.h |    2 +
>  8 files changed, 445 insertions(+), 6 deletions(-)
>  create mode 100644 android/client/if-hh.c

All three patches have been applied. Thanks.

Johan

^ permalink raw reply

* [PATCH 3/3] android: Add help to hidhost in haltest
From: Jerzy Kasenberg @ 2013-10-22 11:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jerzy Kasenberg
In-Reply-To: <1382439747-13864-1-git-send-email-jerzy.kasenberg@tieto.com>

This patch adds help to methods of hidhost interface.
This also adds tab completion for hidhost.
---
 android/client/if-hh.c |   86 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 76 insertions(+), 10 deletions(-)

diff --git a/android/client/if-hh.c b/android/client/if-hh.c
index 09eaf9c..e23e4d5 100644
--- a/android/client/if-hh.c
+++ b/android/client/if-hh.c
@@ -68,6 +68,7 @@ SINTMAP(bthh_status_t, -1, "(unknown)")
 	DELEMENT(BTHH_ERR_HDL),
 ENDMAP
 
+static char connected_device_addr[MAX_ADDR_STR_LEN];
 /*
  * Callback for connection state change.
  * state will have one of the values from bthh_connection_state_t
@@ -80,6 +81,8 @@ static void connection_state_cb(bt_bdaddr_t *bd_addr,
 	haltest_info("%s: bd_addr=%s connection_state=%s\n", __func__,
 			bt_bdaddr_t2str(bd_addr, addr),
 					bthh_connection_state_t2str(state));
+	if (state == BTHH_CONN_STATE_CONNECTED)
+		strcpy(connected_device_addr, addr);
 }
 
 /*
@@ -104,7 +107,7 @@ static void hid_info_cb(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info)
 {
 	char addr[MAX_ADDR_STR_LEN];
 
-	/* TODO: print actual hid_info */
+	/* TODO: bluedroid does not seem to ever call this callback */
 	haltest_info("%s: bd_addr=%s\n", __func__,
 						bt_bdaddr_t2str(bd_addr, addr));
 }
@@ -174,6 +177,15 @@ static void init_p(int argc, const char **argv)
 
 /* connect */
 
+static void connect_c(int argc, const const char **argv,
+				enum_func *penum_func, void **puser)
+{
+	if (argc == 3) {
+		*puser = (void *) connected_device_addr;
+		*penum_func = enum_one_string;
+	}
+}
+
 static void connect_p(int argc, const char **argv)
 {
 	bt_bdaddr_t addr;
@@ -186,6 +198,9 @@ static void connect_p(int argc, const char **argv)
 
 /* disconnect */
 
+/* Same completion as connect_c */
+#define disconnect_c connect_c
+
 static void disconnect_p(int argc, const char **argv)
 {
 	bt_bdaddr_t addr;
@@ -198,6 +213,9 @@ static void disconnect_p(int argc, const char **argv)
 
 /* virtual_unplug */
 
+/* Same completion as connect_c */
+#define virtual_unplug_c connect_c
+
 static void virtual_unplug_p(int argc, const char **argv)
 {
 	bt_bdaddr_t addr;
@@ -217,13 +235,25 @@ static void set_info_p(int argc, const char **argv)
 
 	RETURN_IF_NULL(if_hh);
 	VERIFY_ADDR_ARG(2, &addr);
-	/* TODO: not implemented yet */
+	/* TODO: set_info does not seem to be called anywhere */
 
 	EXEC(if_hh->set_info, &addr, hid_info);
 }
 
 /* get_protocol */
 
+static void get_protocol_c(int argc, const const char **argv,
+					enum_func *penum_func, void **puser)
+{
+	if (argc == 3) {
+		*puser = connected_device_addr;
+		*penum_func = enum_one_string;
+	} else if (argc == 4) {
+		*puser = TYPE_ENUM(bthh_protocol_mode_t);
+		*penum_func = enum_defines;
+	}
+}
+
 static void get_protocol_p(int argc, const char **argv)
 {
 	bt_bdaddr_t addr;
@@ -243,6 +273,9 @@ static void get_protocol_p(int argc, const char **argv)
 
 /* set_protocol */
 
+/* Same completion as get_protocol_c */
+#define set_protocol_c get_protocol_c
+
 static void set_protocol_p(int argc, const char **argv)
 {
 	bt_bdaddr_t addr;
@@ -262,6 +295,18 @@ static void set_protocol_p(int argc, const char **argv)
 
 /* get_report */
 
+static void get_report_c(int argc, const const char **argv,
+					enum_func *penum_func, void **puser)
+{
+	if (argc == 3) {
+		*puser = connected_device_addr;
+		*penum_func = enum_one_string;
+	} else if (argc == 4) {
+		*puser = TYPE_ENUM(bthh_report_type_t);
+		*penum_func = enum_defines;
+	}
+}
+
 static void get_report_p(int argc, const char **argv)
 {
 	bt_bdaddr_t addr;
@@ -295,6 +340,18 @@ static void get_report_p(int argc, const char **argv)
 
 /* set_report */
 
+static void set_report_c(int argc, const const char **argv,
+					enum_func *penum_func, void **puser)
+{
+	if (argc == 3) {
+		*puser = connected_device_addr;
+		*penum_func = enum_one_string;
+	} else if (argc == 4) {
+		*puser = TYPE_ENUM(bthh_report_type_t);
+		*penum_func = enum_defines;
+	}
+}
+
 static void set_report_p(int argc, const char **argv)
 {
 	bt_bdaddr_t addr;
@@ -319,6 +376,15 @@ static void set_report_p(int argc, const char **argv)
 
 /* send_data */
 
+static void send_data_c(int argc, const const char **argv,
+					enum_func *penum_func, void **puser)
+{
+	if (argc == 3) {
+		*puser = connected_device_addr;
+		*penum_func = enum_one_string;
+	}
+}
+
 static void send_data_p(int argc, const char **argv)
 {
 	bt_bdaddr_t addr;
@@ -346,15 +412,15 @@ static void cleanup_p(int argc, const char **argv)
 /* Methods available in bthh_interface_t */
 static struct method methods[] = {
 	STD_METHOD(init),
-	STD_METHOD(connect),
-	STD_METHOD(disconnect),
-	STD_METHOD(virtual_unplug),
+	STD_METHODCH(connect, "<addr>"),
+	STD_METHODCH(disconnect, "<addr>"),
+	STD_METHODCH(virtual_unplug, "<addr>"),
 	STD_METHOD(set_info),
-	STD_METHOD(get_protocol),
-	STD_METHOD(set_protocol),
-	STD_METHOD(get_report),
-	STD_METHOD(set_report),
-	STD_METHOD(send_data),
+	STD_METHODCH(get_protocol, "<addr> <mode>"),
+	STD_METHODCH(set_protocol, "<addr> <mode>"),
+	STD_METHODCH(get_report, "<addr> <type> <report_id> <size>"),
+	STD_METHODCH(set_report, "<addr> <type> <hex_encoded_report>"),
+	STD_METHODCH(send_data, "<addr> <hex_encoded_data>"),
 	STD_METHOD(cleanup),
 	END_METHOD
 };
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 2/3] android: Add calls to hidhost interface to haltest
From: Jerzy Kasenberg @ 2013-10-22 11:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jerzy Kasenberg
In-Reply-To: <1382439747-13864-1-git-send-email-jerzy.kasenberg@tieto.com>

This patch adds code so hidhost interface can be tested.
---
 Makefile.android         |    2 +
 android/Android.mk       |    1 +
 android/client/haltest.c |    1 +
 android/client/if-bt.c   |    2 +-
 android/client/if-hh.c   |  365 ++++++++++++++++++++++++++++++++++++++++++++++
 android/client/if-main.h |    2 +
 6 files changed, 372 insertions(+), 1 deletion(-)
 create mode 100644 android/client/if-hh.c

diff --git a/Makefile.android b/Makefile.android
index aebc715..720df69 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -48,6 +48,7 @@ android_haltest_SOURCES = android/client/haltest.c \
 				android/client/textconv.c \
 				android/client/tabcompletion.c \
 				android/client/if-bt.c \
+				android/client/if-hh.c \
 				android/client/hwmodule.c
 
 android_haltest_LDADD = android/libhal-internal.la
@@ -73,6 +74,7 @@ EXTRA_DIST += android/client/terminal.c \
 		android/client/pollhandler.c \
 		android/client/history.c \
 		android/client/if-bt.c \
+		android/client/if-hh.c \
 		android/client/textconv.c \
 		android/client/tabcompletion.c \
 		android/client/textconv.h \
diff --git a/android/Android.mk b/android/Android.mk
index 679c12b..c4b0621 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -83,6 +83,7 @@ LOCAL_SRC_FILES := \
 	client/textconv.c \
 	client/tabcompletion.c \
 	client/if-bt.c \
+	client/if-hh.c \
 
 LOCAL_SHARED_LIBRARIES := libhardware
 
diff --git a/android/client/haltest.c b/android/client/haltest.c
index 4864de1..2894565 100644
--- a/android/client/haltest.c
+++ b/android/client/haltest.c
@@ -31,6 +31,7 @@
 
 const struct interface *interfaces[] = {
 	&bluetooth_if,
+	&hh_if,
 	NULL
 };
 
diff --git a/android/client/if-bt.c b/android/client/if-bt.c
index f65e5f0..5f88a64 100644
--- a/android/client/if-bt.c
+++ b/android/client/if-bt.c
@@ -805,7 +805,7 @@ static void get_profile_interface_p(int argc, const char **argv)
 	else if (strcmp(BT_PROFILE_SOCKETS_ID, id) == 0)
 		pif = &dummy; /* TODO: change when if_sock is there */
 	else if (strcmp(BT_PROFILE_HIDHOST_ID, id) == 0)
-		pif = &dummy; /* TODO: change when if_hh is there */
+		pif = (const void **)&if_hh;
 	else if (strcmp(BT_PROFILE_PAN_ID, id) == 0)
 		pif = &dummy; /* TODO: change when if_pan is there */
 	else if (strcmp(BT_PROFILE_AV_RC_ID, id) == 0)
diff --git a/android/client/if-hh.c b/android/client/if-hh.c
new file mode 100644
index 0000000..09eaf9c
--- /dev/null
+++ b/android/client/if-hh.c
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_hh.h>
+
+#include "if-main.h"
+#include "pollhandler.h"
+
+const bthh_interface_t *if_hh = NULL;
+
+SINTMAP(bthh_protocol_mode_t, -1, "(unknown)")
+	DELEMENT(BTHH_REPORT_MODE),
+	DELEMENT(BTHH_BOOT_MODE),
+	DELEMENT(BTHH_UNSUPPORTED_MODE),
+ENDMAP
+
+SINTMAP(bthh_report_type_t, -1, "(unknown)")
+	DELEMENT(BTHH_INPUT_REPORT),
+	DELEMENT(BTHH_OUTPUT_REPORT),
+	DELEMENT(BTHH_FEATURE_REPORT),
+ENDMAP
+
+SINTMAP(bthh_connection_state_t, -1, "(unknown)")
+	DELEMENT(BTHH_CONN_STATE_CONNECTED),
+	DELEMENT(BTHH_CONN_STATE_CONNECTING),
+	DELEMENT(BTHH_CONN_STATE_DISCONNECTED),
+	DELEMENT(BTHH_CONN_STATE_DISCONNECTING),
+	DELEMENT(BTHH_CONN_STATE_FAILED_MOUSE_FROM_HOST),
+	DELEMENT(BTHH_CONN_STATE_FAILED_KBD_FROM_HOST),
+	DELEMENT(BTHH_CONN_STATE_FAILED_TOO_MANY_DEVICES),
+	DELEMENT(BTHH_CONN_STATE_FAILED_NO_BTHID_DRIVER),
+	DELEMENT(BTHH_CONN_STATE_FAILED_GENERIC),
+	DELEMENT(BTHH_CONN_STATE_UNKNOWN),
+ENDMAP
+
+SINTMAP(bthh_status_t, -1, "(unknown)")
+	DELEMENT(BTHH_OK),
+	DELEMENT(BTHH_HS_HID_NOT_READY),
+	DELEMENT(BTHH_HS_INVALID_RPT_ID),
+	DELEMENT(BTHH_HS_TRANS_NOT_SPT),
+	DELEMENT(BTHH_HS_INVALID_PARAM),
+	DELEMENT(BTHH_HS_ERROR),
+	DELEMENT(BTHH_ERR),
+	DELEMENT(BTHH_ERR_SDP),
+	DELEMENT(BTHH_ERR_PROTO),
+	DELEMENT(BTHH_ERR_DB_FULL),
+	DELEMENT(BTHH_ERR_TOD_UNSPT),
+	DELEMENT(BTHH_ERR_NO_RES),
+	DELEMENT(BTHH_ERR_AUTH_FAILED),
+	DELEMENT(BTHH_ERR_HDL),
+ENDMAP
+
+/*
+ * Callback for connection state change.
+ * state will have one of the values from bthh_connection_state_t
+ */
+static void connection_state_cb(bt_bdaddr_t *bd_addr,
+						bthh_connection_state_t state)
+{
+	char addr[MAX_ADDR_STR_LEN];
+
+	haltest_info("%s: bd_addr=%s connection_state=%s\n", __func__,
+			bt_bdaddr_t2str(bd_addr, addr),
+					bthh_connection_state_t2str(state));
+}
+
+/*
+ * Callback for virtual unplug api.
+ * the status of the virtual unplug
+ */
+static void virtual_unplug_cb(bt_bdaddr_t *bd_addr, bthh_status_t hh_status)
+{
+	char addr[MAX_ADDR_STR_LEN];
+
+	haltest_info("%s: bd_addr=%s hh_status=%s\n", __func__,
+			bt_bdaddr_t2str(bd_addr, addr),
+						bthh_status_t2str(hh_status));
+}
+
+/*
+ * Callback for get hid info
+ * hid_info will contain attr_mask, sub_class, app_id, vendor_id, product_id,
+ * version, ctry_code, len
+ */
+static void hid_info_cb(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info)
+{
+	char addr[MAX_ADDR_STR_LEN];
+
+	/* TODO: print actual hid_info */
+	haltest_info("%s: bd_addr=%s\n", __func__,
+						bt_bdaddr_t2str(bd_addr, addr));
+}
+
+/*
+ * Callback for get/set protocol api.
+ * the protocol mode is one of the value from bthh_protocol_mode_t
+ */
+static void protocol_mode_cb(bt_bdaddr_t *bd_addr, bthh_status_t hh_status,
+						bthh_protocol_mode_t mode)
+{
+	char addr[MAX_ADDR_STR_LEN];
+
+	haltest_info("%s: bd_addr=%s hh_status=%s mode=%s\n", __func__,
+			bt_bdaddr_t2str(bd_addr, addr),
+			bthh_status_t2str(hh_status),
+						bthh_protocol_mode_t2str(mode));
+}
+
+/*
+ * Callback for get/set_idle_time api.
+ */
+static void idle_time_cb(bt_bdaddr_t *bd_addr, bthh_status_t hh_status,
+								int idle_rate)
+{
+	char addr[MAX_ADDR_STR_LEN];
+
+	haltest_info("%s: bd_addr=%s hh_status=%s idle_rate=%d\n", __func__,
+			bt_bdaddr_t2str(bd_addr, addr),
+			bthh_status_t2str(hh_status), idle_rate);
+}
+
+
+/*
+ * Callback for get report api.
+ * if status is ok rpt_data contains the report data
+ */
+static void get_report_cb(bt_bdaddr_t *bd_addr, bthh_status_t hh_status,
+						uint8_t *rpt_data, int rpt_size)
+{
+	char addr[MAX_ADDR_STR_LEN];
+
+	/* TODO: print actual report */
+	haltest_info("%s: bd_addr=%s hh_status=%s rpt_size=%d\n", __func__,
+			bt_bdaddr_t2str(bd_addr, addr),
+			bthh_status_t2str(hh_status), rpt_size);
+}
+
+static bthh_callbacks_t bthh_callbacks = {
+	.size = sizeof(bthh_callbacks),
+	.connection_state_cb = connection_state_cb,
+	.hid_info_cb = hid_info_cb,
+	.protocol_mode_cb = protocol_mode_cb,
+	.idle_time_cb = idle_time_cb,
+	.get_report_cb = get_report_cb,
+	.virtual_unplug_cb = virtual_unplug_cb
+};
+
+/* init */
+
+static void init_p(int argc, const char **argv)
+{
+	RETURN_IF_NULL(if_hh);
+
+	EXEC(if_hh->init, &bthh_callbacks);
+}
+
+/* connect */
+
+static void connect_p(int argc, const char **argv)
+{
+	bt_bdaddr_t addr;
+
+	RETURN_IF_NULL(if_hh);
+	VERIFY_ADDR_ARG(2, &addr);
+
+	EXEC(if_hh->connect, &addr);
+}
+
+/* disconnect */
+
+static void disconnect_p(int argc, const char **argv)
+{
+	bt_bdaddr_t addr;
+
+	RETURN_IF_NULL(if_hh);
+	VERIFY_ADDR_ARG(2, &addr);
+
+	EXEC(if_hh->disconnect, &addr);
+}
+
+/* virtual_unplug */
+
+static void virtual_unplug_p(int argc, const char **argv)
+{
+	bt_bdaddr_t addr;
+
+	RETURN_IF_NULL(if_hh);
+	VERIFY_ADDR_ARG(2, &addr);
+
+	EXEC(if_hh->virtual_unplug, &addr);
+}
+
+/* set_info */
+
+static void set_info_p(int argc, const char **argv)
+{
+	bt_bdaddr_t addr;
+	bthh_hid_info_t hid_info;
+
+	RETURN_IF_NULL(if_hh);
+	VERIFY_ADDR_ARG(2, &addr);
+	/* TODO: not implemented yet */
+
+	EXEC(if_hh->set_info, &addr, hid_info);
+}
+
+/* get_protocol */
+
+static void get_protocol_p(int argc, const char **argv)
+{
+	bt_bdaddr_t addr;
+	bthh_protocol_mode_t protocolMode;
+
+	RETURN_IF_NULL(if_hh);
+	VERIFY_ADDR_ARG(2, &addr);
+
+	if (argc < 4) {
+		haltest_error("No protocol mode specified\n");
+		return;
+	}
+	protocolMode = str2bthh_protocol_mode_t(argv[3]);
+
+	EXEC(if_hh->get_protocol, &addr, protocolMode);
+}
+
+/* set_protocol */
+
+static void set_protocol_p(int argc, const char **argv)
+{
+	bt_bdaddr_t addr;
+	bthh_protocol_mode_t protocolMode;
+
+	RETURN_IF_NULL(if_hh);
+	VERIFY_ADDR_ARG(2, &addr);
+
+	if (argc < 4) {
+		haltest_error("No protocol mode specified\n");
+		return;
+	}
+	protocolMode = str2bthh_protocol_mode_t(argv[3]);
+
+	EXEC(if_hh->set_protocol, &addr, protocolMode);
+}
+
+/* get_report */
+
+static void get_report_p(int argc, const char **argv)
+{
+	bt_bdaddr_t addr;
+	bthh_report_type_t reportType;
+	uint8_t reportId;
+	int bufferSize;
+
+	RETURN_IF_NULL(if_hh);
+	VERIFY_ADDR_ARG(2, &addr);
+
+	if (argc < 4) {
+		haltest_error("No report type specified\n");
+		return;
+	}
+	reportType = str2bthh_report_type_t(argv[3]);
+
+	if (argc < 5) {
+		haltest_error("No reportId specified\n");
+		return;
+	}
+	reportId = (uint8_t) atoi(argv[4]);
+
+	if (argc < 6) {
+		haltest_error("No bufferSize specified\n");
+		return;
+	}
+	bufferSize = atoi(argv[5]);
+
+	EXEC(if_hh->get_report, &addr, reportType, reportId, bufferSize);
+}
+
+/* set_report */
+
+static void set_report_p(int argc, const char **argv)
+{
+	bt_bdaddr_t addr;
+	bthh_report_type_t reportType;
+
+	RETURN_IF_NULL(if_hh);
+	VERIFY_ADDR_ARG(2, &addr);
+
+	if (argc <= 3) {
+		haltest_error("No report type specified\n");
+		return;
+	}
+	reportType = str2bthh_report_type_t(argv[3]);
+
+	if (argc <= 4) {
+		haltest_error("No report specified\n");
+		return;
+	}
+
+	EXEC(if_hh->set_report, &addr, reportType, (char *) argv[4]);
+}
+
+/* send_data */
+
+static void send_data_p(int argc, const char **argv)
+{
+	bt_bdaddr_t addr;
+
+	RETURN_IF_NULL(if_hh);
+	VERIFY_ADDR_ARG(2, &addr);
+
+	if (argc <= 3) {
+		haltest_error("No data to send specified\n");
+		return;
+	}
+
+	EXEC(if_hh->send_data, &addr, (char *) argv[3]);
+}
+
+/* cleanup */
+
+static void cleanup_p(int argc, const char **argv)
+{
+	RETURN_IF_NULL(if_hh);
+
+	EXECV(if_hh->cleanup);
+}
+
+/* Methods available in bthh_interface_t */
+static struct method methods[] = {
+	STD_METHOD(init),
+	STD_METHOD(connect),
+	STD_METHOD(disconnect),
+	STD_METHOD(virtual_unplug),
+	STD_METHOD(set_info),
+	STD_METHOD(get_protocol),
+	STD_METHOD(set_protocol),
+	STD_METHOD(get_report),
+	STD_METHOD(set_report),
+	STD_METHOD(send_data),
+	STD_METHOD(cleanup),
+	END_METHOD
+};
+
+const struct interface hh_if = {
+	.name = "hidhost",
+	.methods = methods
+};
diff --git a/android/client/if-main.h b/android/client/if-main.h
index 6d2b0cb..f8430cf 100644
--- a/android/client/if-main.h
+++ b/android/client/if-main.h
@@ -41,6 +41,7 @@
 
 /* Interfaces from hal that can be populated during application lifetime */
 extern const bt_interface_t *if_bluetooth;
+extern const bthh_interface_t *if_hh;
 
 /*
  * Structure defines top level interfaces that can be used in test tool
@@ -52,6 +53,7 @@ struct interface {
 };
 
 extern const struct interface bluetooth_if;
+extern const struct interface hh_if;
 
 /* Interfaces that will show up in tool (first part of command line) */
 extern const struct interface *interfaces[];
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 1/3] android: Add definition of buffer sizes to haltest
From: Jerzy Kasenberg @ 2013-10-22 11:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jerzy Kasenberg
In-Reply-To: <1382439747-13864-1-git-send-email-jerzy.kasenberg@tieto.com>

This patch adds definition of sizes needed for text representation
of bluetooth address and uuid, this remove usage of magic numbers.
---
 android/client/if-bt.c    |    8 ++++----
 android/client/textconv.c |    2 +-
 android/client/textconv.h |    2 ++
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/android/client/if-bt.c b/android/client/if-bt.c
index 30b41cd..f65e5f0 100644
--- a/android/client/if-bt.c
+++ b/android/client/if-bt.c
@@ -31,14 +31,14 @@ const bt_interface_t *if_bluetooth;
 
 static char *bdaddr2str(const bt_bdaddr_t *bd_addr)
 {
-	static char buf[18];
+	static char buf[MAX_ADDR_STR_LEN];
 
 	return bt_bdaddr_t2str(bd_addr, buf);
 }
 
 static char *btuuid2str(const bt_uuid_t *uuid)
 {
-	static char buf[39];
+	static char buf[MAX_UUID_STR_LEN];
 
 	return bt_uuid_t2str(uuid, buf);
 }
@@ -239,7 +239,7 @@ void add_remote_device(const bt_bdaddr_t *addr)
 
 const char *enum_devices(void *v, int i)
 {
-	static char buf[19];
+	static char buf[MAX_ADDR_STR_LEN];
 
 	if (i >= remote_devices_cnt)
 		return NULL;
@@ -310,7 +310,7 @@ static void discovery_state_changed_cb(bt_discovery_state_t state)
  * Buffer for remote addres that came from one of bind request.
  * It's stored for command completion.
  */
-static char last_remote_addr[18];
+static char last_remote_addr[MAX_ADDR_STR_LEN];
 static bt_ssp_variant_t last_ssp_variant = (bt_ssp_variant_t)-1;
 
 static void pin_request_cb(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *bd_name,
diff --git a/android/client/textconv.c b/android/client/textconv.c
index 3493b1c..de7e23c 100644
--- a/android/client/textconv.c
+++ b/android/client/textconv.c
@@ -137,7 +137,7 @@ char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf)
 {
 	const char *p = (const char *) bd_addr;
 
-	snprintf(buf, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
+	snprintf(buf, MAX_ADDR_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x",
 					p[0], p[1], p[2], p[3], p[4], p[5]);
 
 	return buf;
diff --git a/android/client/textconv.h b/android/client/textconv.h
index 88da641..056e706 100644
--- a/android/client/textconv.h
+++ b/android/client/textconv.h
@@ -99,9 +99,11 @@ static struct int2str __##type##2str[] = {
 #define DELEMENT(s) {s, #s}
 /* End of mapping section */
 
+#define MAX_ADDR_STR_LEN 18
 char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf);
 void str2bt_bdaddr_t(const char *str, bt_bdaddr_t *bd_addr);
 
+#define MAX_UUID_STR_LEN 37
 char *bt_uuid_t2str(const bt_uuid_t *uuid, char *buf);
 void str2bt_uuid_t(const char *str, bt_uuid_t *uuid);
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 0/3] android: add support for hidhost to haltest
From: Jerzy Kasenberg @ 2013-10-22 11:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jerzy Kasenberg

- adds support for hidhost
- adds tab completion for hidhost
- adds help for hidhost
- magic number to #define change for buffer sizes

Jerzy Kasenberg (3):
  android: Add definition of buffer sizes to haltest
  android: Add calls to hidhost interface to haltest
  android: Add help to hidhost in haltest

 Makefile.android          |    2 +
 android/Android.mk        |    1 +
 android/client/haltest.c  |    1 +
 android/client/if-bt.c    |   10 +-
 android/client/if-hh.c    |  431 +++++++++++++++++++++++++++++++++++++++++++++
 android/client/if-main.h  |    2 +
 android/client/textconv.c |    2 +-
 android/client/textconv.h |    2 +
 8 files changed, 445 insertions(+), 6 deletions(-)
 create mode 100644 android/client/if-hh.c

-- 
1.7.9.5


^ 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