Linux bluetooth development
 help / color / mirror / Atom feed
* [RFCv1 1/6] android: Add capabilities and set userid
From: Andrei Emeltchenko @ 2013-10-21 11:28 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1382354917-8632-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

The patch set UID as standard Bluetooth user for Android (AID_BLUETOOTH).
For SDP server we need to bind to lower port, acquire this capability.
Other capabilities are required to access management interface.
---
 android/main.c |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 configure.ac   |    4 ++++
 2 files changed, 62 insertions(+)

diff --git a/android/main.c b/android/main.c
index fac1003..4a716be 100644
--- a/android/main.c
+++ b/android/main.c
@@ -33,10 +33,17 @@
 #include <stdbool.h>
 #include <string.h>
 #include <errno.h>
+#include <unistd.h>
+
 #include <sys/signalfd.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 
+#if defined(ANDROID)
+#include <sys/prctl.h>
+#include <private/android_filesystem_config.h>
+#endif
+
 #include <glib.h>
 
 #include "log.h"
@@ -409,6 +416,54 @@ static void cleanup_hal_connection(void)
 	}
 }
 
+static bool set_capabilities(void)
+{
+#if defined(ANDROID)
+	struct __user_cap_header_struct header;
+	struct __user_cap_data_struct cap;
+	gid_t groups[] = {AID_NET_BT, AID_NET_BT_ADMIN, AID_NET_ADMIN};
+
+	DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
+
+	header.version = _LINUX_CAPABILITY_VERSION;
+
+	prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+
+	if (setgid(AID_BLUETOOTH) < 0)
+		warn("%s: setgid(): %s", __func__, strerror(errno));
+
+	if (setuid(AID_BLUETOOTH) < 0)
+		warn("%s: setuid(): %s", __func__, strerror(errno));
+
+	header.version = _LINUX_CAPABILITY_VERSION;
+	header.pid = 0;
+
+	cap.effective = cap.permitted =
+		CAP_TO_MASK(CAP_SETGID) |
+		CAP_TO_MASK(CAP_NET_RAW) |
+		CAP_TO_MASK(CAP_NET_ADMIN) |
+		CAP_TO_MASK(CAP_NET_BIND_SERVICE);
+	cap.inheritable = 0;
+
+	if (capset(&header, &cap) < 0) {
+		error("%s: capset(): %s", __func__, strerror(errno));
+		return false;
+	}
+
+	if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) < 0)
+		warn("%s: setgroups: %s", __func__, strerror(errno));
+
+	if (capget(&header, &cap) < 0)
+		error("%s: capget(): %s", __func__, strerror(errno));
+	else
+		DBG("Caps: eff: 0x%x, perm: 0x%x, inh: 0x%x", cap.effective,
+					cap.permitted, cap.inheritable);
+
+	DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
+#endif
+	return true;
+}
+
 int main(int argc, char *argv[])
 {
 	GOptionContext *context;
@@ -442,6 +497,9 @@ int main(int argc, char *argv[])
 
 	__btd_log_init("*", 0);
 
+	if (!set_capabilities())
+		return EXIT_FAILURE;
+
 	if (!init_mgmt_interface())
 		return EXIT_FAILURE;
 
diff --git a/configure.ac b/configure.ac
index b4d3998..e3b5220 100644
--- a/configure.ac
+++ b/configure.ac
@@ -247,4 +247,8 @@ AC_ARG_ENABLE(android, AC_HELP_STRING([--enable-android],
 					[enable_android=${enableval}])
 AM_CONDITIONAL(ANDROID, test "${enable_android}" = "yes")
 
+if (test "${enable_android}" = "yes"); then
+	AC_CHECK_LIB(cap, capget, dummy=yes, AC_MSG_ERROR(libcap is required))
+fi
+
 AC_OUTPUT(Makefile src/bluetoothd.8 lib/bluez.pc)
-- 
1.7.10.4


^ permalink raw reply related

* [RFCv1 0/6] Set of patches implementing missing IPC functionality
From: Andrei Emeltchenko @ 2013-10-21 11:28 UTC (permalink / raw)
  To: linux-bluetooth

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

This is my set of patches rebased against very recent bluez.git
(most probably there might be some issues related to style used).

These patches add some missing capability to the process, add basic IPC server
and client. Daemon listens for incoming connections from HALs so it acts
as a server, while HALs connect and act as client. Please advise what
are better names for hal-msg and hal-msg-client, should some code be moved
to adapter.c?

Andrei Emeltchenko (6):
  android: Add capabilities and set userid
  android: Handle mgmt changed events
  android: Implement basic HAL server
  android: Add HAL message helpers
  android: Add helper to send fd using SCM_RIGHTS
  android: Add Android HAL callback task

 Makefile.android         |    2 +-
 android/Android.mk       |    9 ++
 android/adapter.c        |  129 ++++++++++++++++++++++
 android/bt-sock.c        |   64 +++++++++++
 android/hal-cb-thread.c  |   86 +++++++++++++++
 android/hal-msg-client.c |  123 +++++++++++++++++++++
 android/hal-msg-client.h |   25 +++++
 android/hal-msg.c        |  267 ++++++++++++++++++++++++++++++++++++++++++++++
 android/hal-msg.h        |    5 +
 android/main.c           |   69 ++++++++++++
 configure.ac             |    4 +
 11 files changed, 782 insertions(+), 1 deletion(-)
 create mode 100644 android/bt-sock.c
 create mode 100644 android/hal-cb-thread.c
 create mode 100644 android/hal-msg-client.c
 create mode 100644 android/hal-msg-client.h
 create mode 100644 android/hal-msg.c

-- 
1.7.10.4


^ permalink raw reply

* Re: [PATCH BlueZ v2] android: Add A2DP skeleton
From: Johan Hedberg @ 2013-10-21 10:44 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1382351241-17513-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Mon, Oct 21, 2013, Luiz Augusto von Dentz wrote:
> This adds initial skeleton for A2DP Android HAL.
> ---
> v2: Adds hal-av.c to Android.mk
> 
>  Makefile.android   |  2 ++
>  android/Android.mk |  1 +
>  android/hal-av.c   | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  android/hal.h      |  2 ++
>  4 files changed, 99 insertions(+)
>  create mode 100644 android/hal-av.c

Applied. Thanks.

Johan

^ permalink raw reply

* [PATCH BlueZ v2] android: Add A2DP skeleton
From: Luiz Augusto von Dentz @ 2013-10-21 10:27 UTC (permalink / raw)
  To: linux-bluetooth

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

This adds initial skeleton for A2DP Android HAL.
---
v2: Adds hal-av.c to Android.mk

 Makefile.android   |  2 ++
 android/Android.mk |  1 +
 android/hal-av.c   | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 android/hal.h      |  2 ++
 4 files changed, 99 insertions(+)
 create mode 100644 android/hal-av.c

diff --git a/Makefile.android b/Makefile.android
index 8196583..f5a5834 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -18,6 +18,7 @@ android_libhal_internal_la_SOURCES = android/hal.h android/hal-bluetooth.c \
 					android/hal-sock.c \
 					android/hal-hidhost.c \
 					android/hal-pan.c \
+					android/hal-av.c \
 					android/hardware/bluetooth.h \
 					android/hardware/bt_av.h \
 					android/hardware/bt_gatt.h \
@@ -61,6 +62,7 @@ EXTRA_DIST += android/hal-bluetooth.c \
 		android/hal-sock.c \
 		android/hal-hidhost.c \
 		android/hal-pan.c \
+		android/hal-av.c \
 		android/hal-log.h
 
 EXTRA_DIST += android/client/terminal.c \
diff --git a/android/Android.mk b/android/Android.mk
index 30b2169..87445ed 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -55,6 +55,7 @@ LOCAL_SRC_FILES := \
 	hal-sock.c \
 	hal-hidhost.c \
 	hal-pan.c \
+	hal-av.c \
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
diff --git a/android/hal-av.c b/android/hal-av.c
new file mode 100644
index 0000000..ef45066
--- /dev/null
+++ b/android/hal-av.c
@@ -0,0 +1,94 @@
+/*
+ * 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 <stdbool.h>
+#include <stddef.h>
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_av.h>
+
+#include "hal-log.h"
+#include "hal.h"
+
+const btav_callbacks_t *cbs = NULL;
+
+static bool interface_ready(void)
+{
+	return cbs != NULL;
+}
+
+static bt_status_t av_connect(bt_bdaddr_t *bd_addr)
+{
+	DBG("");
+
+	if (!interface_ready())
+		return BT_STATUS_NOT_READY;
+
+	if (!bd_addr)
+		return BT_STATUS_PARM_INVALID;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t av_disconnect(bt_bdaddr_t *bd_addr)
+{
+	DBG("");
+
+	if (!interface_ready())
+		return BT_STATUS_NOT_READY;
+
+	if (!bd_addr)
+		return BT_STATUS_PARM_INVALID;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t av_init(btav_callbacks_t *callbacks)
+{
+	DBG("");
+
+	cbs = callbacks;
+
+	/* TODO: enable service */
+
+	return BT_STATUS_SUCCESS;
+}
+
+static void av_cleanup()
+{
+	DBG("");
+
+	if (!interface_ready())
+		return;
+
+	/* TODO: disable service */
+
+	cbs = NULL;
+}
+
+static btav_interface_t iface = {
+	.size = sizeof(iface),
+	.init = av_init,
+	.connect = av_connect,
+	.disconnect = av_disconnect,
+	.cleanup = av_cleanup
+};
+
+btav_interface_t *bt_get_av_interface()
+{
+	return &iface;
+}
diff --git a/android/hal.h b/android/hal.h
index a548e48..d984336 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -18,7 +18,9 @@
 #include <hardware/bt_sock.h>
 #include <hardware/bt_hh.h>
 #include <hardware/bt_pan.h>
+#include <hardware/bt_av.h>
 
 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);
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ] android: Add A2DP skeleton
From: Luiz Augusto von Dentz @ 2013-10-21  8:39 UTC (permalink / raw)
  To: linux-bluetooth

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

This adds initial skeleton for A2DP Android HAL.
---
 Makefile.android |  1 +
 android/hal-av.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 android/hal.h    |  2 ++
 3 files changed, 97 insertions(+)
 create mode 100644 android/hal-av.c

diff --git a/Makefile.android b/Makefile.android
index 8196583..ec9e4be 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -18,6 +18,7 @@ android_libhal_internal_la_SOURCES = android/hal.h android/hal-bluetooth.c \
 					android/hal-sock.c \
 					android/hal-hidhost.c \
 					android/hal-pan.c \
+					android/hal-av.c \
 					android/hardware/bluetooth.h \
 					android/hardware/bt_av.h \
 					android/hardware/bt_gatt.h \
diff --git a/android/hal-av.c b/android/hal-av.c
new file mode 100644
index 0000000..ef45066
--- /dev/null
+++ b/android/hal-av.c
@@ -0,0 +1,94 @@
+/*
+ * 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 <stdbool.h>
+#include <stddef.h>
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_av.h>
+
+#include "hal-log.h"
+#include "hal.h"
+
+const btav_callbacks_t *cbs = NULL;
+
+static bool interface_ready(void)
+{
+	return cbs != NULL;
+}
+
+static bt_status_t av_connect(bt_bdaddr_t *bd_addr)
+{
+	DBG("");
+
+	if (!interface_ready())
+		return BT_STATUS_NOT_READY;
+
+	if (!bd_addr)
+		return BT_STATUS_PARM_INVALID;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t av_disconnect(bt_bdaddr_t *bd_addr)
+{
+	DBG("");
+
+	if (!interface_ready())
+		return BT_STATUS_NOT_READY;
+
+	if (!bd_addr)
+		return BT_STATUS_PARM_INVALID;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t av_init(btav_callbacks_t *callbacks)
+{
+	DBG("");
+
+	cbs = callbacks;
+
+	/* TODO: enable service */
+
+	return BT_STATUS_SUCCESS;
+}
+
+static void av_cleanup()
+{
+	DBG("");
+
+	if (!interface_ready())
+		return;
+
+	/* TODO: disable service */
+
+	cbs = NULL;
+}
+
+static btav_interface_t iface = {
+	.size = sizeof(iface),
+	.init = av_init,
+	.connect = av_connect,
+	.disconnect = av_disconnect,
+	.cleanup = av_cleanup
+};
+
+btav_interface_t *bt_get_av_interface()
+{
+	return &iface;
+}
diff --git a/android/hal.h b/android/hal.h
index a548e48..d984336 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -18,7 +18,9 @@
 #include <hardware/bt_sock.h>
 #include <hardware/bt_hh.h>
 #include <hardware/bt_pan.h>
+#include <hardware/bt_av.h>
 
 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);
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 4/4] android:hal: Register adapter and socket interface on HAL init
From: Szymon Janc @ 2013-10-21  8:08 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382342936-10331-1-git-send-email-szymon.janc@tieto.com>

After daemon is started HAL needs to register those two interfaces
to performe initialization procedure as described in IPC documentation.
---
 android/hal-bluetooth.c | 36 +++++++++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 7 deletions(-)

diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 4174fcf..6af6a6b 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -46,7 +46,7 @@ static int notif_sk = -1;
 
 static pthread_mutex_t cmd_sk_mutex = PTHREAD_MUTEX_INITIALIZER;
 
-static int read_fd(int sk, void *buf, int size, int *fd)
+static int read_with_fd(int sk, void *buf, int size, int *fd)
 {
 	struct msghdr msg;
 	struct iovec iv;
@@ -72,11 +72,13 @@ static int read_fd(int sk, void *buf, int size, int *fd)
 	if(ret < 0)
 		return -EIO;
 
-	cmsg = CMSG_FIRSTHDR(&msg);
-	if (cmsg && cmsg->cmsg_level == SOL_SOCKET &&
-			cmsg->cmsg_type == SCM_RIGHTS &&
-			cmsg->cmsg_len == CMSG_LEN(sizeof(int)))
-		memcpy(fd, CMSG_DATA(cmsg), sizeof(int));
+	/* 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;
+		}
 
 	return ret;
 }
@@ -113,7 +115,7 @@ int hal_send_msg(uint8_t service_id, uint8_t opcode, uint16_t len,
 	}
 
 	if (fd)
-		ret = read_fd(cmd_sk, &rsp, sizeof(rsp), fd);
+		ret = read_with_fd(cmd_sk, &rsp, sizeof(rsp), fd);
 	else
 		ret = read(cmd_sk, &rsp, sizeof(rsp));
 
@@ -241,6 +243,8 @@ static void stop_daemon(void)
 
 static int init(bt_callbacks_t *callbacks)
 {
+	struct hal_msg_cmd_register_module cmd;
+
 	DBG("");
 
 	if (interface_ready())
@@ -251,7 +255,25 @@ static int init(bt_callbacks_t *callbacks)
 
 	bt_hal_cbacks = callbacks;
 
+	cmd.service_id = HAL_SERVICE_ID_BLUETOOTH;
+
+	if (hal_send_msg(HAL_SERVICE_ID_CORE, HAL_MSG_OP_REGISTER_MODULE,
+						sizeof(cmd), &cmd, NULL) != 0 )
+		goto fail;
+
+	cmd.service_id = HAL_SERVICE_ID_SOCK;
+
+	if (hal_send_msg(HAL_SERVICE_ID_CORE, HAL_MSG_OP_REGISTER_MODULE,
+						sizeof(cmd), &cmd, NULL) != 0)
+		goto fail;
+
 	return BT_STATUS_SUCCESS;
+
+fail:
+	stop_daemon();
+	bt_hal_cbacks = NULL;
+	return BT_STATUS_FAIL;
+
 }
 
 static int enable(void)
-- 
1.8.4


^ permalink raw reply related

* [PATCH 3/4] android:hal: Add support for receiving fd in command response
From: Szymon Janc @ 2013-10-21  8:08 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382342936-10331-1-git-send-email-szymon.janc@tieto.com>

If fd is expected together with response it will be stored into passed
pointer.
---
 android/hal-bluetooth.c | 42 ++++++++++++++++++++++++++++++++++++++++--
 android/hal.h           |  2 +-
 2 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index de07108..4174fcf 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -46,8 +46,43 @@ static int notif_sk = -1;
 
 static pthread_mutex_t cmd_sk_mutex = PTHREAD_MUTEX_INITIALIZER;
 
+static int read_fd(int sk, void *buf, int size, int *fd)
+{
+	struct msghdr msg;
+	struct iovec iv;
+	struct cmsghdr *cmsg;
+	char cmsgbuf[CMSG_SPACE(sizeof(int))];
+	int ret;
+
+	*fd = -1;
+
+	memset(&msg, 0, sizeof(msg));
+	memset(cmsgbuf, 0, sizeof(cmsgbuf));
+
+	iv.iov_base = buf;
+	iv.iov_len = size;
+
+	msg.msg_iov = &iv;
+	msg.msg_iovlen = 1;
+
+	msg.msg_control = cmsgbuf;
+	msg.msg_controllen = sizeof(cmsgbuf);
+
+	ret = recvmsg(sk, &msg, 0);
+	if(ret < 0)
+		return -EIO;
+
+	cmsg = CMSG_FIRSTHDR(&msg);
+	if (cmsg && cmsg->cmsg_level == SOL_SOCKET &&
+			cmsg->cmsg_type == SCM_RIGHTS &&
+			cmsg->cmsg_len == CMSG_LEN(sizeof(int)))
+		memcpy(fd, CMSG_DATA(cmsg), sizeof(int));
+
+	return ret;
+}
+
 int hal_send_msg(uint8_t service_id, uint8_t opcode, uint16_t len,
-							const void *param)
+						const void *param, int *fd)
 {
 	int ret;
 	int msg_len = sizeof(struct hal_msg_hdr) + len;
@@ -77,7 +112,10 @@ int hal_send_msg(uint8_t service_id, uint8_t opcode, uint16_t len,
 		return -EIO;
 	}
 
-	ret = read(cmd_sk, &rsp, sizeof(rsp));
+	if (fd)
+		ret = read_fd(cmd_sk, &rsp, sizeof(rsp), fd);
+	else
+		ret = read(cmd_sk, &rsp, sizeof(rsp));
 
 	pthread_mutex_unlock(&cmd_sk_mutex );
 
diff --git a/android/hal.h b/android/hal.h
index cf6e1f7..8062971 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -24,4 +24,4 @@ bthh_interface_t *bt_get_hidhost_interface(void);
 btpan_interface_t *bt_get_pan_interface(void);
 
 int hal_send_msg(uint8_t service_id, uint8_t opcode, uint16_t len,
-							const void *param);
+						const void *param, int *fd);
-- 
1.8.4


^ permalink raw reply related

* [PATCH 2/4] android:hal: Add initial code for sending commands
From: Szymon Janc @ 2013-10-21  8:08 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382342936-10331-1-git-send-email-szymon.janc@tieto.com>

This will be used by all HAL modules to send commands and get response
from daemon. In case of any protocol error negative value is returned.
---
 android/hal-bluetooth.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++
 android/hal.h           |  3 +++
 2 files changed, 57 insertions(+)

diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 589cb1b..de07108 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -23,6 +23,7 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <poll.h>
+#include <pthread.h>
 
 #include <hardware/bluetooth.h>
 #include <hardware/bt_sock.h>
@@ -43,6 +44,59 @@ bt_callbacks_t *bt_hal_cbacks = NULL;
 static int cmd_sk = -1;
 static int notif_sk = -1;
 
+static pthread_mutex_t cmd_sk_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+int hal_send_msg(uint8_t service_id, uint8_t opcode, uint16_t len,
+							const void *param)
+{
+	int ret;
+	int msg_len = sizeof(struct hal_msg_hdr) + len;
+	char buf[msg_len];
+	struct hal_msg_hdr *msg = (struct hal_msg_hdr *)buf;
+	struct {
+		struct hal_msg_hdr hdr;
+		struct hal_msg_rsp_error error;
+	} __attribute__((packed)) rsp;
+
+	if (cmd_sk < 0)
+		return -EBADF;
+
+	msg->service_id = service_id;
+	msg->opcode = opcode;
+	msg->len = len;
+
+	if (len > 0)
+		memcpy(msg + sizeof(msg), param, len);
+
+	memset(&rsp, 0, sizeof(rsp));
+
+	pthread_mutex_lock(&cmd_sk_mutex );
+
+	if (write(cmd_sk, msg, msg_len) != msg_len) {
+		pthread_mutex_unlock(&cmd_sk_mutex );
+		return -EIO;
+	}
+
+	ret = read(cmd_sk, &rsp, sizeof(rsp));
+
+	pthread_mutex_unlock(&cmd_sk_mutex );
+
+	if (ret < (int)sizeof(rsp.hdr))
+		return -EIO;
+
+	ret -= sizeof(rsp.hdr);
+
+	if (rsp.hdr.opcode == opcode && ret == 0)
+		return 0;
+
+	if (ret != sizeof(rsp.error))
+		return -EIO;
+
+	ret = rsp.error.status;
+
+	return ret;
+}
+
 static bool interface_ready(void)
 {
 	return bt_hal_cbacks != NULL;
diff --git a/android/hal.h b/android/hal.h
index a548e48..cf6e1f7 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -22,3 +22,6 @@
 btsock_interface_t *bt_get_sock_interface(void);
 bthh_interface_t *bt_get_hidhost_interface(void);
 btpan_interface_t *bt_get_pan_interface(void);
+
+int hal_send_msg(uint8_t service_id, uint8_t opcode, uint16_t len,
+							const void *param);
-- 
1.8.4


^ permalink raw reply related

* [PATCH 1/4] android: Add missing error status description for Core Service
From: Szymon Janc @ 2013-10-21  8:08 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

We need at least one failed status description.
---
 android/hal-ipc-api.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/android/hal-ipc-api.txt b/android/hal-ipc-api.txt
index 9a8b770..5d8e085 100644
--- a/android/hal-ipc-api.txt
+++ b/android/hal-ipc-api.txt
@@ -117,7 +117,9 @@ Core Service (ID 0)
 
 	Opcode 0x00 - Error response
 
-		Response parameters: Error (1 octet)
+		Response parameters: Status (1 octet)
+
+		Valid status values: 0x01 = Fail
 
 	Opcode 0x01 - Register module command/response
 
-- 
1.8.4


^ permalink raw reply related

* [PATCH BlueZ] android: Add audio plugin protocol to API doc
From: Luiz Augusto von Dentz @ 2013-10-21  7:59 UTC (permalink / raw)
  To: linux-bluetooth

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

This adds audio plugin IPC is used to communicate Android BlueZ daemon
and audio plugin.
---
 android/hal-ipc-api.txt | 76 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/android/hal-ipc-api.txt b/android/hal-ipc-api.txt
index 9a8b770..bc8a128 100644
--- a/android/hal-ipc-api.txt
+++ b/android/hal-ipc-api.txt
@@ -1245,3 +1245,79 @@ Android HAL name: "gatt" (BT_PROFILE_GATT_ID)
 	Opcode 0x9c - Request Write notification
 	Opcode 0x9d - Request Execute Write notification
 	Opcode 0x9e - Response Confirmation notification
+
+Bluetooth Audio Plugin (ID = 10)
+================================
+
+The audio plugin happen to be in a different socket but all the rules for
+HAL socket apply here as well.
+
+	.--Android--.                             .---Audio---.
+	|  daemon   |                             |   Plugin  |
+	|           |          Command            |           |
+	|           | <-------------------------- |           |
+	|           | --------------------------> |           |
+	|           |          Response           |           |
+	|           |                             |           |
+	|           |                             |           |
+	|           |        Notification         |           |
+	|           | --------------------------> |           |
+	|           |                             |           |
+	'-----------'                             '-----------'
+
+Android HAL name: "audio" (BT_AUDIO_ID)
+
+	Opcode 0x00 - Error response
+
+		Response parameters: Status (1 octet)
+
+		Valid status values: 0x01 = Fail
+		                     0x02 = Not ready
+		                     0x03 = No memory
+		                     0x04 = Busy
+		                     0x05 = Done (already completed)
+		                     0x06 = Unsupported
+		                     0x07 = Parameter invalid
+		                     0x08 = Unhandled
+		                     0x09 = Authentication failure
+		                     0x0a = Remote device down
+
+	Opcode 0x01 - Register Audio Endpoint commmand
+
+		Command parameters: Service UUID (16 octets)
+		                    Codec ID (1 octets)
+		                    Codec capabilities length (1 octets)
+		                    Codec capabilities (variable)
+		                    Codec configuration length (1 octets)
+		                    Codec configuration (variable)
+		Response parameters: Endpoint ID (1 octets)
+
+	Opcode 0x02 - Unregister Audio Endpoint command
+
+		Command parameters: Endpoint ID (1 octets)
+
+	Opcode 0x03 - Resume Audio command
+
+		Command parameters: Endpoint ID (1 octets)
+
+	Opcode 0x04 - Suspend Audio command
+
+		Command parameters: Endpoint ID (1 octets)
+
+Notifications:
+
+	Opcode 0x80 - Audio State Changed notification
+
+		Notification paremters: Endpoint ID (1 octets)
+		                        State (1 octets)
+
+		Valid state values: 0x01 = Idle
+		                    0x02 = Suspended
+		                    0x03 = Running
+
+	Opcode 0x81 - New Audio Connection notification
+
+		Notification parameters: Endpoint ID (1 octets)
+		                         Codec configuration length (1 octets)
+		                         Codec configuration (variable)
+		                         File descriptor (inline)
-- 
1.8.3.1


^ permalink raw reply related

* Re: [RFC 0/6] Logging from Android HAL library
From: Johan Hedberg @ 2013-10-20 19:40 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1382291146-23518-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Sun, Oct 20, 2013, Szymon Janc wrote:
> This is an attempt to make library logging API similar to other parts of code.
> It maps log levels used in BlueZ to Android levels and provides log printing
> when HAL library is used by haltest on Linux. Since cutils/log.h is not used
> directly there is no need to stub it on Linux.
> 
> Another advantage is that LOG_TAG and message format is configured in single
> file (eg. modules tags could be easily added to improve readibility of
> non-debug messages)
> 
> Comments are welcome.
> 
> Szymon Janc (6):
>   android: Add wrapper for HAL logging
>   android: Use hal-log.h for logging in bluetooth HAL
>   android: Use hal-log.h for logging in hidhost HAL
>   android: Use hal-log.h for logging in pan HAL
>   android: Use hal-log.h for logging in socket HAL
>   android: Remove not needed cutils/log.h stub
> 
>  Makefile.android        |  9 ++++---
>  android/cutils/log.h    | 29 ---------------------
>  android/hal-bluetooth.c | 68 ++++++++++++++++++++++++-------------------------
>  android/hal-hidhost.c   | 26 +++++++++----------
>  android/hal-log.h       | 35 +++++++++++++++++++++++++
>  android/hal-pan.c       | 16 +++++-------
>  android/hal-sock.c      | 19 ++++++--------
>  7 files changed, 100 insertions(+), 102 deletions(-)
>  delete mode 100644 android/cutils/log.h
>  create mode 100644 android/hal-log.h

Even though you flagged this as RFC it looked fine to me and I like the
idea that we don't need to wrap our brains to different logging
conventions depending on which side of the IPC we are. So all patches
have been applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH v2 0/6] Initial Android IPC
From: Johan Hedberg @ 2013-10-20 19:37 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1382262838-25725-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Sun, Oct 20, 2013, Szymon Janc wrote:
> V2:
> - simplify daemon code
> - sockets handling cleanup
> - other minor fixes
> 
> -- 
> BR
> Szymon Janc
> 
> Szymon Janc (6):
>   android: Fix missing log cleanup on daemon exit
>   android: Improve cutils/log.h stubs
>   android: Define path for HAL communication socket
>   android: Connect daemon to HAL library
>   android: Make HAL library wait for daemon to connect on init
>   android: Remove not needed property_get function form cutils stubs
> 
>  android/cutils/log.h        |  10 ++--
>  android/cutils/properties.h |  27 ----------
>  android/hal-bluetooth.c     | 126 ++++++++++++++++++++++++++++++++++++--------
>  android/hal-msg.h           |   2 +
>  android/main.c              | 124 +++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 234 insertions(+), 55 deletions(-)

All six patches have been applied. Thanks.

Johan

^ permalink raw reply

* [RFC 6/6] android: Remove not needed cutils/log.h stub
From: Szymon Janc @ 2013-10-20 17:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382291146-23518-1-git-send-email-szymon.janc@tieto.com>

---
 Makefile.android     |  2 --
 android/cutils/log.h | 29 -----------------------------
 2 files changed, 31 deletions(-)
 delete mode 100644 android/cutils/log.h

diff --git a/Makefile.android b/Makefile.android
index e9992d9..8196583 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -31,7 +31,6 @@ android_libhal_internal_la_SOURCES = android/hal.h android/hal-bluetooth.c \
 					android/hardware/bt_rc.h \
 					android/hardware/bt_sock.h \
 					android/hardware/hardware.h \
-					android/cutils/log.h \
 					android/cutils/properties.h \
 					android/hal-log.h
 
@@ -93,5 +92,4 @@ EXTRA_DIST += android/hardware/bluetooth.h \
 		android/hardware/bt_rc.h \
 		android/hardware/bt_sock.h \
 		android/hardware/hardware.h \
-		android/cutils/log.h \
 		android/cutils/properties.h
diff --git a/android/cutils/log.h b/android/cutils/log.h
deleted file mode 100644
index 389542b..0000000
--- a/android/cutils/log.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef _CUTILS_LOG_H
-#define _CUTILS_LOG_H
-
-static inline void ALOG() {};
-
-#define ALOGV(...) ALOG("V", __VA_ARGS__)
-#define ALOGD(...) ALOG("D", __VA_ARGS__)
-#define ALOGI(...) ALOG("I", __VA_ARGS__)
-#define ALOGW(...) ALOG("W", __VA_ARGS__)
-#define ALOGE(...) ALOG("E", __VA_ARGS__)
-#define LOG_ALWAYS_FATAL(...)   do { ALOGE(__VA_ARGS__); exit(1); } while (0)
-
-#endif // _CUTILS_LOG_H
-- 
1.8.4


^ permalink raw reply related

* [RFC 5/6] android: Use hal-log.h for logging in socket HAL
From: Szymon Janc @ 2013-10-20 17:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382291146-23518-1-git-send-email-szymon.janc@tieto.com>

This will allow to log both on Android and Linux (in haltest)
---
 android/hal-sock.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/android/hal-sock.c b/android/hal-sock.c
index 31e6b59..dab3756 100644
--- a/android/hal-sock.c
+++ b/android/hal-sock.c
@@ -20,16 +20,14 @@
 #include <hardware/bluetooth.h>
 #include <hardware/bt_sock.h>
 
-#define LOG_TAG "BlueZ"
-#include <cutils/log.h>
-
+#include "hal-log.h"
 #include "hal.h"
 
 static bt_status_t btsock_listen_rfcomm(const char *service_name,
 					const uint8_t *uuid, int chan,
 					int *sock, int flags)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	return BT_STATUS_UNSUPPORTED;
 }
@@ -39,20 +37,20 @@ static bt_status_t listen(btsock_type_t type, const char *service_name,
 					int *sock, int flags)
 {
 	if ((!uuid && chan <= 0) || !sock) {
-		ALOGE("%s: invalid params: uuid %p, chan %d, sock %p",
+		error("%s: invalid params: uuid %p, chan %d, sock %p",
 						__func__, uuid, chan, sock);
 		return BT_STATUS_PARM_INVALID;
 	}
 
-	ALOGD("%s: uuid %p chan %d sock %p type %d service_name %s",
-			__func__, uuid, chan, sock, type, service_name);
+	DBG("uuid %p chan %d sock %p type %d service_name %s",
+					uuid, chan, sock, type, service_name);
 
 	switch (type) {
 	case BTSOCK_RFCOMM:
 		return btsock_listen_rfcomm(service_name, uuid, chan,
 								sock, flags);
 	default:
-		ALOGE("%s: Socket type %d not supported", __func__, type);
+		error("%s: Socket type %d not supported", __func__, type);
 		break;
 	}
 
@@ -64,13 +62,12 @@ static bt_status_t connect(const bt_bdaddr_t *bdaddr, btsock_type_t type,
 					int *sock, int flags)
 {
 	if ((!uuid && chan <= 0) || !bdaddr || !sock) {
-		ALOGE("invalid params: bd_addr %p, uuid %p, chan %d, sock %p",
+		error("invalid params: bd_addr %p, uuid %p, chan %d, sock %p",
 					bdaddr, uuid, chan, sock);
 		return BT_STATUS_PARM_INVALID;
 	}
 
-	ALOGD("%s: uuid %p chan %d sock %p type %d", __func__, uuid, chan,
-								sock, type);
+	DBG("uuid %p chan %d sock %p type %d", uuid, chan, sock, type);
 
 	return BT_STATUS_UNSUPPORTED;
 }
-- 
1.8.4


^ permalink raw reply related

* [RFC 4/6] android: Use hal-log.h for logging in pan HAL
From: Szymon Janc @ 2013-10-20 17:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382291146-23518-1-git-send-email-szymon.janc@tieto.com>

This will allow to log both on Android and Linux (in haltest)
---
 android/hal-pan.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/android/hal-pan.c b/android/hal-pan.c
index f63e83d..645fe8c 100644
--- a/android/hal-pan.c
+++ b/android/hal-pan.c
@@ -21,9 +21,7 @@
 #include <hardware/bluetooth.h>
 #include <hardware/bt_pan.h>
 
-#define LOG_TAG "BlueZ"
-#include <cutils/log.h>
-
+#include "hal-log.h"
 #include "hal.h"
 
 const btpan_callbacks_t *bt_pan_cbacks = NULL;
@@ -35,7 +33,7 @@ static bool interface_ready(void)
 
 static bt_status_t bt_pan_enable(int local_role)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -45,7 +43,7 @@ static bt_status_t bt_pan_enable(int local_role)
 
 static int bt_pan_get_local_role(void)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BTPAN_ROLE_NONE;
@@ -56,7 +54,7 @@ static int bt_pan_get_local_role(void)
 static bt_status_t bt_pan_connect(const bt_bdaddr_t *bd_addr, int local_role,
 					int remote_role)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -69,7 +67,7 @@ static bt_status_t bt_pan_connect(const bt_bdaddr_t *bd_addr, int local_role,
 
 static bt_status_t bt_pan_disconnect(const bt_bdaddr_t *bd_addr)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -82,7 +80,7 @@ static bt_status_t bt_pan_disconnect(const bt_bdaddr_t *bd_addr)
 
 static bt_status_t bt_pan_init(const btpan_callbacks_t *callbacks)
 {
-	ALOGI(__func__);
+	DBG("");
 
 	bt_pan_cbacks = callbacks;
 
@@ -95,7 +93,7 @@ static bt_status_t bt_pan_init(const btpan_callbacks_t *callbacks)
 
 static void bt_pan_cleanup()
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return;
-- 
1.8.4


^ permalink raw reply related

* [RFC 3/6] android: Use hal-log.h for logging in hidhost HAL
From: Szymon Janc @ 2013-10-20 17:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382291146-23518-1-git-send-email-szymon.janc@tieto.com>

This will allow to log both on Android and Linux (in haltest)
---
 android/hal-hidhost.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
index 7436864..8c47e27 100644
--- a/android/hal-hidhost.c
+++ b/android/hal-hidhost.c
@@ -21,9 +21,7 @@
 #include <hardware/bluetooth.h>
 #include <hardware/bt_hh.h>
 
-#define LOG_TAG "BlueZ"
-#include <cutils/log.h>
-
+#include "hal-log.h"
 #include "hal.h"
 
 bthh_callbacks_t *bt_hh_cbacks;
@@ -35,7 +33,7 @@ static bool interface_ready(void)
 
 static bt_status_t bt_hidhost_connect(bt_bdaddr_t *bd_addr)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -48,7 +46,7 @@ static bt_status_t bt_hidhost_connect(bt_bdaddr_t *bd_addr)
 
 static bt_status_t bt_hidhost_disconnect(bt_bdaddr_t *bd_addr)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -61,7 +59,7 @@ static bt_status_t bt_hidhost_disconnect(bt_bdaddr_t *bd_addr)
 
 static bt_status_t bt_hidhost_virtual_unplug(bt_bdaddr_t *bd_addr)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -75,7 +73,7 @@ static bt_status_t bt_hidhost_virtual_unplug(bt_bdaddr_t *bd_addr)
 static bt_status_t bt_hidhost_set_info(bt_bdaddr_t *bd_addr,
 						bthh_hid_info_t hid_info)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -89,7 +87,7 @@ static bt_status_t bt_hidhost_set_info(bt_bdaddr_t *bd_addr,
 static bt_status_t bt_hidhost_get_protocol(bt_bdaddr_t *bd_addr,
 					bthh_protocol_mode_t protocolMode)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -103,7 +101,7 @@ static bt_status_t bt_hidhost_get_protocol(bt_bdaddr_t *bd_addr,
 static bt_status_t bt_hidhost_set_protocol(bt_bdaddr_t *bd_addr,
 					bthh_protocol_mode_t protocolMode)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -119,7 +117,7 @@ static bt_status_t bt_hidhost_get_report(bt_bdaddr_t *bd_addr,
 						uint8_t reportId,
 						int bufferSize)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -134,7 +132,7 @@ static bt_status_t bt_hidhost_set_report(bt_bdaddr_t *bd_addr,
 						bthh_report_type_t reportType,
 						char *report)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -147,7 +145,7 @@ static bt_status_t bt_hidhost_set_report(bt_bdaddr_t *bd_addr,
 
 static bt_status_t bt_hidhost_send_data(bt_bdaddr_t *bd_addr, char *data)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -160,7 +158,7 @@ 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)
 {
-	ALOGI(__func__);
+	DBG("");
 
 	/* store reference to user callbacks */
 	bt_hh_cbacks = callbacks;
@@ -174,7 +172,7 @@ static bt_status_t bt_hidhost_init(bthh_callbacks_t *callbacks)
 
 static void bt_hidhost_cleanup(void)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return;
-- 
1.8.4


^ permalink raw reply related

* [RFC 2/6] android: Use hal-log.h for logging in bluetooth HAL
From: Szymon Janc @ 2013-10-20 17:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382291146-23518-1-git-send-email-szymon.janc@tieto.com>

This will allow to log both on Android and Linux (in haltest).
---
 Makefile.android        |  4 ++-
 android/hal-bluetooth.c | 68 ++++++++++++++++++++++++-------------------------
 2 files changed, 36 insertions(+), 36 deletions(-)

diff --git a/Makefile.android b/Makefile.android
index 244a13b..e9992d9 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -32,7 +32,9 @@ android_libhal_internal_la_SOURCES = android/hal.h android/hal-bluetooth.c \
 					android/hardware/bt_sock.h \
 					android/hardware/hardware.h \
 					android/cutils/log.h \
-					android/cutils/properties.h
+					android/cutils/properties.h \
+					android/hal-log.h
+
 android_libhal_internal_la_CPPFLAGS = -I$(srcdir)/android
 
 noinst_PROGRAMS += android/haltest
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index ce64d3b..035bb0f 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -31,9 +31,7 @@
 
 #include <cutils/properties.h>
 
-#define LOG_TAG "BlueZ"
-#include <cutils/log.h>
-
+#include "hal-log.h"
 #include "hal.h"
 #include "hal-msg.h"
 
@@ -63,19 +61,19 @@ static int accept_connection(int sk)
 	err = poll(&pfd, 1, CONNECT_TIMEOUT);
 	if (err < 0) {
 		err = errno;
-		ALOGE("Failed to poll: %d (%s)", err, strerror(err));
+		error("Failed to poll: %d (%s)", err, strerror(err));
 		return -1;
 	}
 
 	if (err == 0) {
-		ALOGE("bluetoothd connect timeout");
+		error("bluetoothd connect timeout");
 		return -1;
 	}
 
 	new_sk = accept(sk, NULL, NULL);
 	if (new_sk < 0) {
 		err = errno;
-		ALOGE("Failed to accept socket: %d (%s)", err, strerror(err));
+		error("Failed to accept socket: %d (%s)", err, strerror(err));
 		return -1;
 	}
 
@@ -91,7 +89,7 @@ static bool start_daemon(void)
 	sk = socket(AF_LOCAL, SOCK_SEQPACKET, 0);
 	if (sk < 0) {
 		err = errno;
-		ALOGE("Failed to create socket: %d (%s)", err,
+		error("Failed to create socket: %d (%s)", err,
 							strerror(err));
 		return false;
 	}
@@ -103,14 +101,14 @@ static bool start_daemon(void)
 
 	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
 		err = errno;
-		ALOGE("Failed to bind socket: %d (%s)", err, strerror(err));
+		error("Failed to bind socket: %d (%s)", err, strerror(err));
 		close(sk);
 		return false;
 	}
 
 	if (listen(sk, 2) < 0) {
 		err = errno;
-		ALOGE("Failed to listen on socket: %d (%s)", err,
+		error("Failed to listen on socket: %d (%s)", err,
 								strerror(err));
 		close(sk);
 		return false;
@@ -133,7 +131,7 @@ static bool start_daemon(void)
 		return false;
 	}
 
-	ALOGI("bluetoothd connected");
+	info("bluetoothd connected");
 
 	close(sk);
 
@@ -151,7 +149,7 @@ static void stop_daemon(void)
 
 static int init(bt_callbacks_t *callbacks)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (interface_ready())
 		return BT_STATUS_SUCCESS;
@@ -166,14 +164,14 @@ static int init(bt_callbacks_t *callbacks)
 
 static int enable(void)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	return BT_STATUS_UNSUPPORTED;
 }
 
 static int disable(void)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -183,7 +181,7 @@ static int disable(void)
 
 static void cleanup(void)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return;
@@ -195,7 +193,7 @@ static void cleanup(void)
 
 static int get_adapter_properties(void)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -205,7 +203,7 @@ static int get_adapter_properties(void)
 
 static int get_adapter_property(bt_property_type_t type)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -215,7 +213,7 @@ static int get_adapter_property(bt_property_type_t type)
 
 static int set_adapter_property(const bt_property_t *property)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -228,7 +226,7 @@ static int set_adapter_property(const bt_property_t *property)
 
 static int get_remote_device_properties(bt_bdaddr_t *remote_addr)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -239,7 +237,7 @@ static int get_remote_device_properties(bt_bdaddr_t *remote_addr)
 static int get_remote_device_property(bt_bdaddr_t *remote_addr,
 						bt_property_type_t type)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -250,7 +248,7 @@ static int get_remote_device_property(bt_bdaddr_t *remote_addr,
 static int set_remote_device_property(bt_bdaddr_t *remote_addr,
 						const bt_property_t *property)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -260,7 +258,7 @@ static int set_remote_device_property(bt_bdaddr_t *remote_addr,
 
 static int get_remote_service_record(bt_bdaddr_t *remote_addr, bt_uuid_t *uuid)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -270,7 +268,7 @@ static int get_remote_service_record(bt_bdaddr_t *remote_addr, bt_uuid_t *uuid)
 
 static int get_remote_services(bt_bdaddr_t *remote_addr)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -280,7 +278,7 @@ static int get_remote_services(bt_bdaddr_t *remote_addr)
 
 static int start_discovery(void)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -290,7 +288,7 @@ static int start_discovery(void)
 
 static int cancel_discovery(void)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -300,7 +298,7 @@ static int cancel_discovery(void)
 
 static int create_bond(const bt_bdaddr_t *bd_addr)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -313,7 +311,7 @@ static int create_bond(const bt_bdaddr_t *bd_addr)
 
 static int cancel_bond(const bt_bdaddr_t *bd_addr)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -323,7 +321,7 @@ static int cancel_bond(const bt_bdaddr_t *bd_addr)
 
 static int remove_bond(const bt_bdaddr_t *bd_addr)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -334,7 +332,7 @@ static int remove_bond(const bt_bdaddr_t *bd_addr)
 static int pin_reply(const bt_bdaddr_t *bd_addr, uint8_t accept,
 				uint8_t pin_len, bt_pin_code_t *pin_code)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -345,7 +343,7 @@ static int pin_reply(const bt_bdaddr_t *bd_addr, uint8_t accept,
 static int ssp_reply(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
 					uint8_t accept, uint32_t passkey)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -358,7 +356,7 @@ static int ssp_reply(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
 
 static const void *get_profile_interface(const char *profile_id)
 {
-	ALOGD("%s: %s", __func__, profile_id);
+	DBG("%s: %s", __func__, profile_id);
 
 	if (!interface_ready())
 		return NULL;
@@ -377,7 +375,7 @@ static const void *get_profile_interface(const char *profile_id)
 
 static int dut_mode_configure(uint8_t enable)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -387,7 +385,7 @@ static int dut_mode_configure(uint8_t enable)
 
 static int dut_mode_send(uint16_t opcode, uint8_t *buf, uint8_t len)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	if (!interface_ready())
 		return BT_STATUS_NOT_READY;
@@ -423,14 +421,14 @@ static const bt_interface_t bluetooth_if = {
 
 static const bt_interface_t *get_bluetooth_interface(void)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	return &bluetooth_if;
 }
 
 static int close_bluetooth(struct hw_device_t *device)
 {
-	ALOGD(__func__);
+	DBG("");
 
 	cleanup();
 
@@ -442,7 +440,7 @@ static int open_bluetooth(const struct hw_module_t *module, char const *name,
 {
 	bluetooth_device_t *dev = malloc(sizeof(bluetooth_device_t));
 
-	ALOGD(__func__);
+	DBG("");
 
 	memset(dev, 0, sizeof(bluetooth_device_t));
 	dev->common.tag = HARDWARE_DEVICE_TAG;
-- 
1.8.4


^ permalink raw reply related

* [RFC 1/6] android: Add wrapper for HAL logging
From: Szymon Janc @ 2013-10-20 17:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382291146-23518-1-git-send-email-szymon.janc@tieto.com>

Provide logging API similar to standard logging used in daemon. This
will allow to log on both Android and Linux (i.e. in haltest).

Another advantage is that now LOG_TAG and message format are configured
from single location.
---
 Makefile.android  |  3 ++-
 android/hal-log.h | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 1 deletion(-)
 create mode 100644 android/hal-log.h

diff --git a/Makefile.android b/Makefile.android
index dcaca3c..244a13b 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -59,7 +59,8 @@ EXTRA_DIST += android/Android.mk android/log.c android/device.c \
 EXTRA_DIST += android/hal-bluetooth.c \
 		android/hal-sock.c \
 		android/hal-hidhost.c \
-		android/hal-pan.c
+		android/hal-pan.c \
+		android/hal-log.h
 
 EXTRA_DIST += android/client/terminal.c \
 		android/client/haltest.c \
diff --git a/android/hal-log.h b/android/hal-log.h
new file mode 100644
index 0000000..9bd024d
--- /dev/null
+++ b/android/hal-log.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ *
+ */
+
+#define LOG_TAG "BlueZ"
+
+#ifdef __BIONIC__
+#include <cutils/log.h>
+#else
+#include <stdio.h>
+#define LOG_INFO " I"
+#define LOG_WARN " W"
+#define LOG_ERROR " E"
+#define LOG_DEBUG " D"
+#define ALOG(pri, tag, fmt, arg...) printf(tag pri": " fmt"\n", ##arg)
+#endif
+
+#define info(fmt, arg...) ALOG(LOG_INFO, LOG_TAG, fmt, ##arg)
+#define warn(fmt, arg...) ALOG(LOG_WARN, LOG_TAG, fmt, ##arg)
+#define error(fmt, arg...) ALOG(LOG_ERROR, LOG_TAG, fmt, ##arg)
+#define DBG(fmt, arg...) ALOG(LOG_DEBUG, LOG_TAG, "%s:%s() "fmt, __FILE__, \
+							__func__, ##arg)
-- 
1.8.4


^ permalink raw reply related

* [RFC 0/6] Logging from Android HAL library
From: Szymon Janc @ 2013-10-20 17:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Hi,

This is an attempt to make library logging API similar to other parts of code.
It maps log levels used in BlueZ to Android levels and provides log printing
when HAL library is used by haltest on Linux. Since cutils/log.h is not used
directly there is no need to stub it on Linux.

Another advantage is that LOG_TAG and message format is configured in single
file (eg. modules tags could be easily added to improve readibility of
non-debug messages)

Comments are welcome.

Szymon Janc (6):
  android: Add wrapper for HAL logging
  android: Use hal-log.h for logging in bluetooth HAL
  android: Use hal-log.h for logging in hidhost HAL
  android: Use hal-log.h for logging in pan HAL
  android: Use hal-log.h for logging in socket HAL
  android: Remove not needed cutils/log.h stub

 Makefile.android        |  9 ++++---
 android/cutils/log.h    | 29 ---------------------
 android/hal-bluetooth.c | 68 ++++++++++++++++++++++++-------------------------
 android/hal-hidhost.c   | 26 +++++++++----------
 android/hal-log.h       | 35 +++++++++++++++++++++++++
 android/hal-pan.c       | 16 +++++-------
 android/hal-sock.c      | 19 ++++++--------
 7 files changed, 100 insertions(+), 102 deletions(-)
 delete mode 100644 android/cutils/log.h
 create mode 100644 android/hal-log.h

-- 
1.8.4


^ permalink raw reply

* Re: [PATCH v3] Bluetooth: Update Set Discoverable to support LE
From: Marcel Holtmann @ 2013-10-20 16:07 UTC (permalink / raw)
  To: johan.hedberg; +Cc: linux-bluetooth
In-Reply-To: <1382284807-26311-1-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

> This patch updates the Set Discoverable management command to also be
> applicable for LE. In particular this affects the advertising flags
> where we can say "general discoverable" or "limited discoverable".
> 
> Since the device flags may not be up-to-date when the advertising data
> is written this patch introduces a get_adv_discov_flags() helper
> function which also looks at any pending mgmt commands (a pending
> set_discoverable would be the exception when the flags are not yet
> correct).
> 
> The patch also adds HCI_DISCOVERABLE flag clearing to the
> mgmt_discoverable_timeout function, since the code was previously
> relying on the mgmt_discoverable callback to handle this, which is only
> called for the BR/EDR-only HCI_Write_Scan_Enable command.
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> v3:
> * Fix updating advertising flags when switching connectable off while
>   limited discoverable is enabled.
> v2:
> * Fix advertising flags update when disabling connectable while
>  discoverable is enabled.
> * Fix redundant check for HCI_LE_ENABLED
> 
> net/bluetooth/mgmt.c | 80 ++++++++++++++++++++++++++++++++++++++++++++--------
> 1 file changed, 69 insertions(+), 11 deletions(-)

all 9 patches have been applied to bluetooth-next tree.

Regards

Marcel


^ permalink raw reply

* [PATCH v3] Bluetooth: Update Set Discoverable to support LE
From: johan.hedberg @ 2013-10-20 16:00 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1382259320-20009-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

This patch updates the Set Discoverable management command to also be
applicable for LE. In particular this affects the advertising flags
where we can say "general discoverable" or "limited discoverable".

Since the device flags may not be up-to-date when the advertising data
is written this patch introduces a get_adv_discov_flags() helper
function which also looks at any pending mgmt commands (a pending
set_discoverable would be the exception when the flags are not yet
correct).

The patch also adds HCI_DISCOVERABLE flag clearing to the
mgmt_discoverable_timeout function, since the code was previously
relying on the mgmt_discoverable callback to handle this, which is only
called for the BR/EDR-only HCI_Write_Scan_Enable command.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
v3:
 * Fix updating advertising flags when switching connectable off while
   limited discoverable is enabled.
v2:
 * Fix advertising flags update when disabling connectable while
  discoverable is enabled.
 * Fix redundant check for HCI_LE_ENABLED

 net/bluetooth/mgmt.c | 80 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 69 insertions(+), 11 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 796db58..bd91ee5 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -599,12 +599,35 @@ static void update_scan_rsp_data(struct hci_request *req)
 	hci_req_add(req, HCI_OP_LE_SET_SCAN_RSP_DATA, sizeof(cp), &cp);
 }
 
+static u8 get_adv_discov_flags(struct hci_dev *hdev)
+{
+	struct pending_cmd *cmd;
+
+	/* If there's a pending mgmt command the flags will not yet have
+	 * their final values, so check for this first.
+	 */
+	cmd = mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev);
+	if (cmd) {
+		struct mgmt_mode *cp = cmd->param;
+		if (cp->val == 0x01)
+			return LE_AD_GENERAL;
+		else if (cp->val == 0x02)
+			return LE_AD_LIMITED;
+	} else {
+		if (test_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags))
+			return LE_AD_LIMITED;
+		else if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
+			return LE_AD_GENERAL;
+	}
+
+	return 0;
+}
+
 static u8 create_adv_data(struct hci_dev *hdev, u8 *ptr)
 {
 	u8 ad_len = 0, flags = 0;
 
-	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
-		flags |= LE_AD_GENERAL;
+	flags |= get_adv_discov_flags(hdev);
 
 	if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
 		if (lmp_le_br_capable(hdev))
@@ -1120,15 +1143,15 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
 	struct pending_cmd *cmd;
 	struct hci_request req;
 	u16 timeout;
-	u8 scan, status;
+	u8 scan;
 	int err;
 
 	BT_DBG("request for %s", hdev->name);
 
-	status = mgmt_bredr_support(hdev);
-	if (status)
+	if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags) &&
+	    !test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
 		return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
-				  status);
+				  MGMT_STATUS_REJECTED);
 
 	if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02)
 		return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
@@ -1228,6 +1251,12 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
 
 	hci_req_init(&req, hdev);
 
+	/* The procedure for LE-only controllers is much simpler - just
+	 * update the advertising data.
+	 */
+	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
+		goto update_ad;
+
 	scan = SCAN_PAGE;
 
 	if (cp->val) {
@@ -1260,6 +1289,9 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
 
 	hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
 
+update_ad:
+	update_adv_data(&req);
+
 	err = hci_req_run(&req, set_discoverable_complete);
 	if (err < 0)
 		mgmt_pending_remove(cmd);
@@ -1451,8 +1483,17 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
 
 	hci_req_init(&req, hdev);
 
-	if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags) &&
-	    cp->val != test_bit(HCI_PSCAN, &hdev->flags)) {
+	/* If BR/EDR is not enabled and we disable advertising as a
+	 * by-product of disabling connectable, we need to update the
+	 * advertising flags.
+	 */
+	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
+		if (!cp->val) {
+			clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
+			clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
+		}
+		update_adv_data(&req);
+	} else if (cp->val != test_bit(HCI_PSCAN, &hdev->flags)) {
 		if (cp->val) {
 			scan = SCAN_PAGE;
 		} else {
@@ -4348,6 +4389,7 @@ void mgmt_discoverable_timeout(struct hci_dev *hdev)
 	 * safe to unconditionally clear the flag.
 	 */
 	clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
+	clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
 
 	hci_req_init(&req, hdev);
 	if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
@@ -4356,10 +4398,13 @@ void mgmt_discoverable_timeout(struct hci_dev *hdev)
 			    sizeof(scan), &scan);
 	}
 	update_class(&req);
+	update_adv_data(&req);
 	hci_req_run(&req, NULL);
 
 	hdev->discov_timeout = 0;
 
+	new_settings(hdev, NULL);
+
 	hci_dev_unlock(hdev);
 }
 
@@ -4374,13 +4419,26 @@ void mgmt_discoverable(struct hci_dev *hdev, u8 discoverable)
 	if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev))
 		return;
 
-	if (discoverable)
+	if (discoverable) {
 		changed = !test_and_set_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
-	else
+	} else {
+		clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
 		changed = test_and_clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
+	}
+
+	if (changed) {
+		struct hci_request req;
+
+		/* In case this change in discoverable was triggered by
+		 * a disabling of connectable there could be a need to
+		 * update the advertising flags.
+		 */
+		hci_req_init(&req, hdev);
+		update_adv_data(&req);
+		hci_req_run(&req, NULL);
 
-	if (changed)
 		new_settings(hdev, NULL);
+	}
 }
 
 void mgmt_connectable(struct hci_dev *hdev, u8 connectable)
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH v2 6/6] android: Remove not needed property_get function form cutils stubs
From: Szymon Janc @ 2013-10-20  9:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382262838-25725-1-git-send-email-szymon.janc@tieto.com>

This is no longer used as daemon indicates its presence by connecting
socket.
---
 android/cutils/properties.h | 27 ---------------------------
 1 file changed, 27 deletions(-)

diff --git a/android/cutils/properties.h b/android/cutils/properties.h
index 44a712c..f318b01 100644
--- a/android/cutils/properties.h
+++ b/android/cutils/properties.h
@@ -24,33 +24,6 @@
 extern "C" {
 #endif
 
-#define PROPERTY_KEY_MAX   32
-#define PROPERTY_VALUE_MAX  92
-
-/* property_get: returns the length of the value which will never be
-** greater than PROPERTY_VALUE_MAX - 1 and will always be zero terminated.
-** (the length does not include the terminating zero).
-**
-** If the property read fails or returns an empty value, the default
-** value is used (if nonnull).
-*/
-static inline int property_get(const char *key, char *value,
-						const char *default_value)
-{
-	const char *env;
-
-	env = getenv(key);
-	if (!env)
-		env = default_value;
-
-	if (!value || !env)
-		return 0;
-
-	strncpy(value, env, PROPERTY_VALUE_MAX);
-
-	return strlen(value);
-}
-
 /* property_set: returns 0 on success, < 0 on failure
 */
 static inline int property_set(const char *key, const char *value)
-- 
1.8.4


^ permalink raw reply related

* [PATCH v2 5/6] android: Make HAL library wait for daemon to connect on init
From: Szymon Janc @ 2013-10-20  9:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382262838-25725-1-git-send-email-szymon.janc@tieto.com>

After starting up, daemon is responsible for connecting to HAL library.
If this doesn't happen before timeout occured init will fail.
---
 android/hal-bluetooth.c | 126 +++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 103 insertions(+), 23 deletions(-)

diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 2c6c2eb..ce64d3b 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -19,6 +19,10 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdbool.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <poll.h>
 
 #include <hardware/bluetooth.h>
 #include <hardware/bt_sock.h>
@@ -31,41 +35,118 @@
 #include <cutils/log.h>
 
 #include "hal.h"
+#include "hal-msg.h"
 
 #define SERVICE_NAME "bluetoothd"
+#define CONNECT_TIMEOUT (5 * 1000)
 
 bt_callbacks_t *bt_hal_cbacks = NULL;
 
+static int cmd_sk = -1;
+static int notif_sk = -1;
+
 static bool interface_ready(void)
 {
 	return bt_hal_cbacks != NULL;
 }
 
-static bool start_bt_daemon(void)
+static int accept_connection(int sk)
 {
-	int tries = 40; /* wait 4 seconds for completion */
+	int err;
+	struct pollfd pfd;
+	int new_sk;
+
+	memset(&pfd, 0 , sizeof(pfd));
+	pfd.fd = sk;
+	pfd.events = POLLIN;
+
+	err = poll(&pfd, 1, CONNECT_TIMEOUT);
+	if (err < 0) {
+		err = errno;
+		ALOGE("Failed to poll: %d (%s)", err, strerror(err));
+		return -1;
+	}
 
-	ALOGD(__func__);
+	if (err == 0) {
+		ALOGE("bluetoothd connect timeout");
+		return -1;
+	}
+
+	new_sk = accept(sk, NULL, NULL);
+	if (new_sk < 0) {
+		err = errno;
+		ALOGE("Failed to accept socket: %d (%s)", err, strerror(err));
+		return -1;
+	}
+
+	return new_sk;
+}
+
+static bool start_daemon(void)
+{
+	struct sockaddr_un addr;
+	int sk;
+	int err;
+
+	sk = socket(AF_LOCAL, SOCK_SEQPACKET, 0);
+	if (sk < 0) {
+		err = errno;
+		ALOGE("Failed to create socket: %d (%s)", err,
+							strerror(err));
+		return false;
+	}
+
+	memset(&addr, 0, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+
+	memcpy(addr.sun_path, BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH));
+
+	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+		err = errno;
+		ALOGE("Failed to bind socket: %d (%s)", err, strerror(err));
+		close(sk);
+		return false;
+	}
+
+	if (listen(sk, 2) < 0) {
+		err = errno;
+		ALOGE("Failed to listen on socket: %d (%s)", err,
+								strerror(err));
+		close(sk);
+		return false;
+	}
 
 	/* Start Android Bluetooth daemon service */
 	property_set("ctl.start", SERVICE_NAME);
 
-	while (tries-- > 0) {
-		char val[PROPERTY_VALUE_MAX];
-
-		if (property_get("init.svc." SERVICE_NAME, val, NULL)) {
-			if (!strcmp(val, "running")) {
-				ALOGI("Android BlueZ daemon started");
-				return true;
-			}
-		} else {
-			return false;
-		}
+	cmd_sk = accept_connection(sk);
+	if (cmd_sk < 0) {
+		close(sk);
+		return false;
+	}
 
-		usleep(100000);
+	notif_sk = accept_connection(sk);
+	if (notif_sk < 0) {
+		close(sk);
+		close(cmd_sk);
+		cmd_sk = -1;
+		return false;
 	}
 
-	return false;
+	ALOGI("bluetoothd connected");
+
+	close(sk);
+
+	return true;
+}
+
+static void stop_daemon(void)
+{
+	close(cmd_sk);
+	cmd_sk = -1;
+
+	close(notif_sk);
+	notif_sk = 1;
 }
 
 static int init(bt_callbacks_t *callbacks)
@@ -75,15 +156,12 @@ static int init(bt_callbacks_t *callbacks)
 	if (interface_ready())
 		return BT_STATUS_SUCCESS;
 
-	if (start_bt_daemon()) {
-		/* TODO: open channel */
+	if (!start_daemon())
+		return BT_STATUS_FAIL;
 
-		bt_hal_cbacks = callbacks;
+	bt_hal_cbacks = callbacks;
 
-		return BT_STATUS_SUCCESS;
-	}
-
-	return BT_STATUS_UNSUPPORTED;
+	return BT_STATUS_SUCCESS;
 }
 
 static int enable(void)
@@ -110,6 +188,8 @@ static void cleanup(void)
 	if (!interface_ready())
 		return;
 
+	stop_daemon();
+
 	bt_hal_cbacks = NULL;
 }
 
-- 
1.8.4


^ permalink raw reply related

* [PATCH v2 4/6] android: Connect daemon to HAL library
From: Szymon Janc @ 2013-10-20  9:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382262838-25725-1-git-send-email-szymon.janc@tieto.com>

Connect to HAL when adapter initialization is finished. If any problem
with connection occurs or connected socket is closed by remote daemon
shutdowns.
---
 android/main.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 122 insertions(+)

diff --git a/android/main.c b/android/main.c
index cfa728d..2581b87 100644
--- a/android/main.c
+++ b/android/main.c
@@ -32,7 +32,10 @@
 #include <stdlib.h>
 #include <stdbool.h>
 #include <string.h>
+#include <errno.h>
 #include <sys/signalfd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
 
 #include <glib.h>
 
@@ -44,6 +47,7 @@
 #include "src/shared/mgmt.h"
 
 #include "adapter.h"
+#include "hal-msg.h"
 
 #define SHUTDOWN_GRACE_SECONDS 10
 
@@ -55,8 +59,104 @@ static uint8_t mgmt_revision = 0;
 
 static uint16_t adapter_index = MGMT_INDEX_NONE;
 
+static GIOChannel *hal_cmd_io = NULL;
+static GIOChannel *hal_notif_io = NULL;
+
 static volatile sig_atomic_t __terminated = 0;
 
+static gboolean watch_cb(GIOChannel *io, GIOCondition cond,
+							gpointer user_data)
+{
+	info("HAL socket closed, terminating");
+	g_main_loop_quit(event_loop);
+
+	return FALSE;
+}
+
+static GIOChannel *connect_hal(GIOFunc connect_cb)
+{
+	struct sockaddr_un addr;
+	GIOCondition cond;
+	GIOChannel *io;
+	int err, sk;
+
+	sk = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
+	if (sk < 0) {
+		err = errno;
+		error("Failed to create socket: %d (%s)", err, strerror(err));
+		return NULL;
+	}
+
+	io = g_io_channel_unix_new(sk);
+
+	g_io_channel_set_close_on_unref(io, TRUE);
+	g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
+
+	memset(&addr, 0, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+
+	memcpy(addr.sun_path, BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH));
+
+	err = connect(sk, (struct sockaddr *) &addr, sizeof(addr));
+	if (err < 0) {
+		err = -errno;
+		error("Failed to connect HAL socket: %d (%s)", errno,
+							strerror(errno));
+		g_io_channel_unref(io);
+		return NULL;
+	}
+
+	cond = G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
+
+	g_io_add_watch(io, cond, connect_cb, NULL);
+
+	return io;
+}
+
+static gboolean notif_connect_cb(GIOChannel *io, GIOCondition cond,
+							gpointer user_data)
+{
+	DBG("");
+
+	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+		g_main_loop_quit(event_loop);
+		return FALSE;
+	}
+
+	cond = G_IO_ERR | G_IO_HUP | G_IO_NVAL;
+
+	g_io_add_watch(io, cond, watch_cb, NULL);
+
+	info("Successfully connected to HAL");
+
+	/* TODO start handling commands */
+
+	return FALSE;
+}
+
+static gboolean cmd_connect_cb(GIOChannel *io, GIOCondition cond,
+							gpointer user_data)
+{
+	DBG("");
+
+	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+		g_main_loop_quit(event_loop);
+		return FALSE;
+	}
+
+	cond = G_IO_ERR | G_IO_HUP | G_IO_NVAL;
+
+	g_io_add_watch(io, cond, watch_cb, NULL);
+
+	hal_notif_io = connect_hal(notif_connect_cb);
+	if (!hal_notif_io) {
+		error("Cannot connect to HAL, terminating");
+		g_main_loop_quit(event_loop);
+	}
+
+	return FALSE;
+}
+
 static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
 							gpointer user_data)
 {
@@ -141,6 +241,12 @@ static void adapter_ready(struct bt_adapter *adapter, int err)
 	}
 
 	info("Adapter initialized");
+
+	hal_cmd_io = connect_hal(cmd_connect_cb);
+	if (!hal_cmd_io) {
+		error("Cannot connect to HAL, terminating");
+		g_main_loop_quit(event_loop);
+	}
 }
 
 static void mgmt_index_added_event(uint16_t index, uint16_t length,
@@ -290,6 +396,21 @@ static void cleanup_mgmt_interface(void)
 	mgmt_if = NULL;
 }
 
+static void cleanup_hal_connection(void)
+{
+	if (hal_cmd_io) {
+		g_io_channel_shutdown(hal_cmd_io, TRUE, NULL);
+		g_io_channel_unref(hal_cmd_io);
+		hal_cmd_io = NULL;
+	}
+
+	if (hal_notif_io) {
+		g_io_channel_shutdown(hal_notif_io, TRUE, NULL);
+		g_io_channel_unref(hal_notif_io);
+		hal_notif_io = NULL;
+	}
+}
+
 int main(int argc, char *argv[])
 {
 	GOptionContext *context;
@@ -335,6 +456,7 @@ int main(int argc, char *argv[])
 
 	g_source_remove(signal);
 
+	cleanup_hal_connection();
 	stop_sdp_server();
 	cleanup_mgmt_interface();
 	g_main_loop_unref(event_loop);
-- 
1.8.4


^ permalink raw reply related

* [PATCH v2 3/6] android: Define path for HAL communication socket
From: Szymon Janc @ 2013-10-20  9:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382262838-25725-1-git-send-email-szymon.janc@tieto.com>

This socket will be used by android daemon and libhal to communitate.
---
 android/hal-msg.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index 4c5ca69..4440fc8 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -21,6 +21,8 @@
  *
  */
 
+static const char BLUEZ_HAL_SK_PATH[] = "\0bluez_hal_socket";
+
 struct hal_msg_hdr {
 	uint8_t service_id;
 	uint8_t opcode;
-- 
1.8.4


^ permalink raw reply related


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