Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [RFC 09/16] android: Add adapter and device struct for BlueZ daemon
From: Anderson Lizardo @ 2013-09-27 17:07 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: BlueZ development
In-Reply-To: <1380291161-10232-10-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Fri, Sep 27, 2013 at 10:12 AM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> +struct bt_adapter {
> +       int refcnt;
> +
> +       uint16_t dev_id;
> +       struct mgmt *mgmt;
> +       bdaddr_t bdaddr;
> +       uint32_t dev_class;
> +
> +       char *name;
> +       char *short_name;
> +
> +       uint32_t supported_settings;
> +       uint32_t current_settings;
> +
> +       GList *found_devices;

Why are you using GList instead of GSList above?

> +};
> +
> +extern GList *adapter_list;

Same here.

Best Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply

* Re: [RFC 03/16] android: Enable Socket interface
From: Anderson Lizardo @ 2013-09-27 16:04 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: BlueZ development
In-Reply-To: <1380291161-10232-4-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Fri, Sep 27, 2013 at 10:12 AM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> +static bool is_profile(const char *profile, const char *str)
> +{
> +       return (strlen(str) == strlen(profile)) &&
> +               (strncmp(profile, str, strlen(str)) == 0);
> +}

If you are using strlen() (which requires both strings have the '\0'
terminator) anyway, why not use just:

return strcmp(profile, str) == 0;

Best Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply

* Re: pull request: bluetooth 2013-09-23
From: Gustavo Padovan @ 2013-09-27 15:24 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, linux-bluetooth, linux-kernel
In-Reply-To: <20130926174750.GB1931@tuxdriver.com>

Hi John,

2013-09-26 John W. Linville <linville@tuxdriver.com>:

> On Mon, Sep 23, 2013 at 06:00:49PM -0300, Gustavo Padovan wrote:
> > Hi John,
> > 
> > First Bluetooth fixes to 3.12, it includes:
> > 
> > * 3 patches to add device id for 3 new hardwares.
> > 
> > * 2 patches from Johan to fix the rfkill behaviour during setup stage
> > 
> > * a small clean up in the rfcomm TTY code that fixes a potential racy
> > condition (by Gianluca Anzolin)
> > 
> > * 2 fixes to proper set encryption key size and security level in the
> > peripheral role of Bluetooth LE devices. (by Andre Guedes)
> > 
> > * a fix for dealing devices where pairing is not necessary, we were keeping
> > the Bluetooth ACL connection alive for too much time. (by Syam Sidhardhan)
> > 
> > Please pull or let me know of any problems! Thanks!
> > 
> > 
> > 	Gustavo
> > 
> > ---
> > The following changes since commit f4e1a4d3ecbb9e42bdf8e7869ee8a4ebfa27fb20:
> > 
> >   rt2800: change initialization sequence to fix system freeze (2013-09-09 14:44:34 -0400)
> > 
> > are available in the git repository at:
> > 
> >   git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth master
> > 
> > for you to fetch changes up to 5bcecf325378218a8e248bb6bcae96ec7362f8ef:
> > 
> >   Bluetooth: btusb: Add support for Belkin F8065bf (2013-09-23 17:44:25 -0300)
> 
> Pulling now...

Thanks for pulling. However as Stephen pointed out in the linux-next merge
conflict email from today we have a style issue, a closing brace bad indented.
This is from conflict resolution I made last week. I fixed it when merging
bluetooth.git into bluetooth-next.git. 

So when pushing this to Dave could you please tell him about this issue and
that the fix is already provided by bluetooth-next. Do you agree with this
solution?

	Gustavo

^ permalink raw reply

* [RFC 16/16] android: Add HAL message helpers
From: Andrei Emeltchenko @ 2013-09-27 14:12 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1380291161-10232-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Add helper to ease opening channel and sending commands.
---
 android/Android.mk       |    1 +
 android/hal_msg_client.c |  112 ++++++++++++++++++++++++++++++++++++++++++++++
 android/hal_msg_client.h |   25 +++++++++++
 3 files changed, 138 insertions(+)
 create mode 100644 android/hal_msg_client.c
 create mode 100644 android/hal_msg_client.h

diff --git a/android/Android.mk b/android/Android.mk
index d16c3f5..4446b2f 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -46,6 +46,7 @@ LOCAL_SRC_FILES := \
 	hal_bluetooth.c \
 	hal_cb_thread.c \
 	hal_bt_sock.c \
+	hal_msg_client.c \
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
diff --git a/android/hal_msg_client.c b/android/hal_msg_client.c
new file mode 100644
index 0000000..87880fe
--- /dev/null
+++ b/android/hal_msg_client.c
@@ -0,0 +1,112 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2013  Intel Corporation. All rights reserved.
+ *
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include <hardware/bluetooth.h>
+#include <cutils/sockets.h>
+#include <cutils/properties.h>
+
+#define LOG_TAG "BlueZ"
+#include <cutils/log.h>
+
+#include "hal_msg.h"
+#include "hal_msg_client.h"
+
+#define BLUEZ_SOCKET "bluez_hal"
+
+int open_hal_chan(void)
+{
+	int tries = 10;
+	int sock;
+
+	while (tries-- > 0) {
+		sock = socket_local_client(BLUEZ_SOCKET,
+					ANDROID_SOCKET_NAMESPACE_RESERVED,
+					SOCK_STREAM);
+		if (sock < 0)
+			ALOGE("%s: Cannot open chan: %s", __func__,
+							strerror(errno));
+		else
+			return sock;
+
+		usleep(100000);
+	}
+
+	return sock;
+}
+
+static int hal_send(int sock, struct hal_msg_hdr *msg)
+{
+	struct hal_msg_rsp rsp;
+	int len, size;
+
+	if (sock < 0) {
+		ALOGE("%s: socket not ready", __func__);
+		return BT_STATUS_NOT_READY;
+	}
+
+	size = sizeof(*msg) + msg->len;
+	len = send(sock, msg, size, 0);
+	if (len != size) {
+		ALOGE("%s: send(): %s", __func__, strerror(errno));
+		close(sock);
+		return BT_STATUS_FAIL;
+	}
+
+	ALOGD("%s: Sent %d bytes", __func__, len);
+
+	len = recv(sock, &rsp, sizeof(rsp), 0);
+	if (len != sizeof(rsp)) {
+		ALOGE("%s: recv(): read %d bytes", __func__, len);
+		return BT_STATUS_FAIL;
+	}
+
+	return rsp.status;
+}
+
+int hal_register_module(int sock, uint8_t service_id)
+{
+	struct hal_msg_hdr *hdr;
+	struct hal_msg_cp_register_module *msg;
+	int err;
+
+	hdr = malloc(sizeof(*hdr) + sizeof(*msg));
+	if (hdr == NULL)
+		return BT_STATUS_NOMEM;
+
+	hdr->service_id = 0;
+	hdr->opcode = HAL_MSG_OP_REGISTER_MODULE;
+	hdr->len = sizeof(*msg);
+
+	msg = (struct  hal_msg_cp_register_module *) hdr->payload;
+	msg->service_id = service_id;
+
+	err = hal_send(sock, hdr);
+
+	free(hdr);
+	return err;
+}
diff --git a/android/hal_msg_client.h b/android/hal_msg_client.h
new file mode 100644
index 0000000..c620dea
--- /dev/null
+++ b/android/hal_msg_client.h
@@ -0,0 +1,25 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2013  Intel Corporation. All rights reserved.
+ *
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+int hal_register_module(int sock, uint8_t service_id);
+int open_hal_chan(void);
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 15/16] android: Implement basic HAL server
From: Andrei Emeltchenko @ 2013-09-27 14:12 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1380291161-10232-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Add basic HAL server on BlueZ daemon side. It will listen for messages
from Android HAL threads.
---
 Makefile.android   |    3 +-
 android/Android.mk |    1 +
 android/hal_msg.c  |  241 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 android/hal_msg.h  |    3 +
 android/main.c     |    4 +
 5 files changed, 251 insertions(+), 1 deletion(-)
 create mode 100644 android/hal_msg.c

diff --git a/Makefile.android b/Makefile.android
index bf82928..8f18e9d 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -7,6 +7,7 @@ android_bluezd_SOURCES = android/main.c src/log.c \
 				src/sdpd-service.c src/sdpd-request.c \
 				src/shared/util.h src/shared/util.c \
 				src/shared/mgmt.h src/shared/mgmt.c \
-				android/bt_adapter.h android/bt_adapter.c
+				android/bt_adapter.h android/bt_adapter.c \
+				android/hal_msg.h android/hal_msg.c
 android_bluezd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
 endif
diff --git a/android/Android.mk b/android/Android.mk
index 08e35e4..d16c3f5 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -10,6 +10,7 @@ LOCAL_SRC_FILES := \
 	log.c \
 	main.c \
 	bt_adapter.c \
+	hal_msg.c \
 	../src/sdpd-database.c \
 	../src/sdpd-service.c \
 	../src/sdpd-request.c \
diff --git a/android/hal_msg.c b/android/hal_msg.c
new file mode 100644
index 0000000..4834230
--- /dev/null
+++ b/android/hal_msg.c
@@ -0,0 +1,241 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2013  Intel Corporation. All rights reserved.
+ *
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; 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 <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+
+#include <glib.h>
+
+#include "log.h"
+#include "hal_msg.h"
+
+static guint watch_id = 0;
+
+static uint8_t hal_register_module(struct hal_msg_hdr *msg)
+{
+	DBG("");
+
+	return 0;
+}
+
+static uint8_t hal_unregister_module(struct hal_msg_hdr *msg)
+{
+	DBG("");
+
+	return 0;
+}
+
+static uint8_t process_hal_service_chan(struct hal_msg_hdr *msg)
+{
+	uint8_t status = -1;
+
+	DBG("");
+
+	switch (msg->opcode) {
+	case HAL_MSG_OP_REGISTER_MODULE:
+		status = hal_register_module(msg);
+		break;
+	case HAL_MSG_OP_UNREGISTER_MODULE:
+		status = hal_unregister_module(msg);
+		break;
+	default:
+		error("%s: unrecognized command on service channel", __func__);
+		break;
+	}
+
+	return status;
+}
+
+static uint8_t sanity_check(struct hal_msg_hdr *msg)
+{
+	/* TODO: Add sanity check here */
+
+	return 0;
+}
+
+static uint8_t process_hal_msg(uint8_t *buf, int len)
+{
+	struct hal_msg_hdr *msg = (struct hal_msg_hdr *) buf;
+	uint8_t status;
+
+	DBG("");
+
+	status = sanity_check(msg);
+	if (status != 0)
+		return status;
+
+	if (msg->service_id == 0)
+		status = process_hal_service_chan(msg);
+
+	return status;
+}
+
+static gboolean io_session_event(GIOChannel *chan, GIOCondition cond,
+								gpointer data)
+{
+	struct hal_msg_hdr hdr;
+	struct hal_msg_rsp rsp;
+	uint8_t *buf;
+	int sock, len, size;
+	uint8_t status;
+
+	if (cond & G_IO_NVAL)
+		return FALSE;
+
+	sock = g_io_channel_unix_get_fd(chan);
+
+	if (cond & (G_IO_HUP | G_IO_ERR)) {
+		error("%s: error condition %d", __func__, cond);
+		/* TODO: handle */
+		return FALSE;
+	}
+
+	len = recv(sock, &hdr, sizeof(hdr), MSG_PEEK);
+	if (len != sizeof(hdr)) {
+		/* TODO: handle */
+		return FALSE;
+	}
+
+	size = sizeof(hdr) + hdr.len;
+	buf = malloc(size);
+	if (!buf)
+		return TRUE;
+
+	len = recv(sock, buf, size, 0);
+	if (len != size) {
+		/* TODO: handle */
+		free(buf);
+		return FALSE;
+	}
+
+	status = process_hal_msg(buf, len);
+
+	free(buf);
+
+	memcpy(&rsp, &hdr, sizeof(hdr));
+	rsp.hdr.len = sizeof(uint8_t);
+	rsp.status = status;
+
+	return TRUE;
+}
+
+static gboolean io_accept_event(GIOChannel *chan, GIOCondition cond,
+								gpointer data)
+{
+	GIOChannel *io;
+	int sock, nsk;
+	struct sockaddr_un addr;
+	socklen_t len = sizeof(addr);
+
+	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL))
+		return FALSE;
+
+	sock = g_io_channel_unix_get_fd(chan);
+
+	nsk = accept(sock, (struct sockaddr *) &addr, &len);
+	if (nsk < 0) {
+		error("%s: accept(): %s", __func__, strerror(errno));
+		return TRUE;
+	}
+
+	io = g_io_channel_unix_new(nsk);
+	g_io_channel_set_close_on_unref(io, TRUE);
+
+	g_io_add_watch(io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+						io_session_event, data);
+
+	g_io_channel_unref(io);
+
+	return TRUE;
+}
+
+static int init_hal_socket(const char *sock_path)
+{
+	struct sockaddr_un addr;
+	int sock;
+
+	sock = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (sock < 0) {
+		error("%s: socket(): %s", __func__, strerror(errno));
+		return sock;
+	}
+
+	memset(&addr, 0, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+	strcpy(addr.sun_path, sock_path);
+
+	unlink(addr.sun_path);
+
+	if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+		error("%s: bind(): %s", __func__, strerror(errno));
+		return -1;
+	}
+
+	if (listen(sock, 5) < 0) {
+		error("%s: listen(): %s", __func__, strerror(errno));
+		return -1;
+	}
+
+	/* Since daemon would be run also on host we have to grant perms */
+	chmod(sock_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH |
+								S_IWOTH);
+
+	return sock;
+}
+
+void start_hal_srv(const char *sock_path)
+{
+	GIOChannel *io;
+	int sock;
+
+	DBG("");
+
+	sock = init_hal_socket(sock_path);
+	if (sock < 0)
+		return;
+
+	io = g_io_channel_unix_new(sock);
+	g_io_channel_set_close_on_unref(io, TRUE);
+
+	watch_id = g_io_add_watch(io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+							io_accept_event, &sock);
+}
+
+void stop_hal_srv(void)
+{
+	DBG("");
+
+	if (watch_id > 0)
+		g_source_remove(watch_id);
+
+	watch_id = 0;
+}
diff --git a/android/hal_msg.h b/android/hal_msg.h
index 2d4436a..fe2a511 100644
--- a/android/hal_msg.h
+++ b/android/hal_msg.h
@@ -29,6 +29,9 @@ typedef struct {
 	uint8_t b[6];
 } __packed __bdaddr_t;
 
+void start_hal_srv(const char *sock_path);
+void stop_hal_srv(void);
+
 struct hal_msg_hdr {
 	uint8_t service_id;
 	uint8_t opcode;
diff --git a/android/main.c b/android/main.c
index 5e0f77f..5acb286 100644
--- a/android/main.c
+++ b/android/main.c
@@ -57,6 +57,8 @@
 #include "lib/mgmt.h"
 #include "src/shared/mgmt.h"
 
+#include "hal_msg.h"
+
 #define SHUTDOWN_GRACE_SECONDS 10
 
 struct main_opts main_opts;
@@ -646,11 +648,13 @@ int main(int argc, char *argv[])
 		exit(1);
 
 	init_mgmt_interface();
+	start_hal_srv("/dev/socket/bluez_hal");
 
 	DBG("Entering main loop");
 
 	g_main_loop_run(event_loop);
 
+	stop_hal_srv();
 	cleanup_mgmt_interface();
 	g_main_loop_unref(event_loop);
 
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 14/16] android: Handle mgmt changed events
From: Andrei Emeltchenko @ 2013-09-27 14:12 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1380291161-10232-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Add code handling changing adapter settings.
---
 android/main.c |  145 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 145 insertions(+)

diff --git a/android/main.c b/android/main.c
index 658cdd2..5e0f77f 100644
--- a/android/main.c
+++ b/android/main.c
@@ -162,6 +162,150 @@ static void load_link_keys_complete(uint8_t status, uint16_t length,
 	DBG("status %u", status);
 }
 
+static void mgmt_local_name_changed_event(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct bt_adapter *adapter = user_data;
+	const struct mgmt_cp_set_local_name *rp = param;
+
+	if (length < sizeof(*rp)) {
+		error("Wrong size of local name changed parameters");
+		return;
+	}
+
+	if (!g_strcmp0(adapter->short_name, (const char *) rp->short_name) &&
+			!g_strcmp0(adapter->name, (const char *) rp->name))
+		return;
+
+	DBG("name: %s short name: %s", rp->name, rp->short_name);
+
+	g_free(adapter->name);
+	adapter->name = g_strdup((const char *) rp->name);
+
+	g_free(adapter->short_name);
+	adapter->short_name = g_strdup((const char *) rp->short_name);
+
+	/* TODO Update services if needed */
+}
+
+static void settings_changed_connectable(struct bt_adapter *adapter)
+{
+	/* TODO */
+}
+
+static void settings_changed_discoverable(struct bt_adapter *adapter)
+{
+	/* TODO */
+}
+
+static void settings_changed(struct bt_adapter *adapter, uint32_t settings)
+{
+	uint32_t changed_mask;
+
+	changed_mask = adapter->current_settings ^ settings;
+
+	adapter->current_settings = settings;
+
+	DBG("0x%08x", changed_mask);
+
+	if (changed_mask & MGMT_SETTING_POWERED) {
+		info("Powered");
+
+		if (adapter->current_settings & MGMT_SETTING_POWERED)
+			adapter_start(adapter);
+		else
+			adapter_stop(adapter);
+	}
+
+	/* Seems not needed for Android */
+	if (changed_mask & MGMT_SETTING_PAIRABLE)
+		DBG("Pairable");
+
+	/*
+	 * There are only 2 scan modes:
+	 * CONNECTABLE and CONNECTABLE_DISCOVERABLE
+	 */
+	if (changed_mask & MGMT_SETTING_CONNECTABLE) {
+		DBG("Connectable");
+
+		settings_changed_connectable(adapter);
+	}
+
+	if (changed_mask & MGMT_SETTING_DISCOVERABLE) {
+		DBG("Discoverable");
+
+		settings_changed_discoverable(adapter);
+	}
+}
+
+static void new_settings_callback(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct bt_adapter *adapter = user_data;
+	uint32_t settings;
+
+	if (length < sizeof(settings)) {
+		error("Wrong size of new settings parameters");
+		return;
+	}
+
+	settings = bt_get_le32(param);
+
+	DBG("settings: 0x%8.8x -> 0x%8.8x", adapter->current_settings,
+								settings);
+
+	if (settings == adapter->current_settings)
+		return;
+
+	settings_changed(adapter, settings);
+}
+
+static void mgmt_dev_class_changed_event(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct bt_adapter *adapter = user_data;
+	const struct mgmt_cod *rp = param;
+	uint8_t appearance[3];
+	uint32_t dev_class;
+
+	if (length < sizeof(*rp)) {
+		error("Wrong size of class of device changed parameters");
+		return;
+	}
+
+	dev_class = rp->val[0] | (rp->val[1] << 8) | (rp->val[2] << 16);
+
+	if (dev_class == adapter->dev_class)
+		return;
+
+	DBG("Class: 0x%06x", dev_class);
+
+	adapter->dev_class = dev_class;
+
+	/* TODO: Inform prop change: Class */
+
+	appearance[0] = rp->val[0];
+	appearance[1] = rp->val[1] & 0x1f;  /* removes service class */
+	appearance[2] = rp->val[2];
+
+	/* TODO: Gatt attrib set*/
+	(void)appearance;
+}
+
+static void register_mgmt_handlers(struct bt_adapter *adapter)
+{
+	mgmt_register(adapter->mgmt, MGMT_EV_NEW_SETTINGS, adapter->dev_id,
+					new_settings_callback, adapter, NULL);
+
+	mgmt_register(adapter->mgmt, MGMT_EV_CLASS_OF_DEV_CHANGED,
+			adapter->dev_id, mgmt_dev_class_changed_event,
+			adapter, NULL);
+
+	mgmt_register(adapter->mgmt, MGMT_EV_LOCAL_NAME_CHANGED,
+			adapter->dev_id, mgmt_local_name_changed_event,
+			adapter, NULL);
+}
+
 static void load_link_keys(struct bt_adapter *adapter, GSList *keys)
 {
 	struct mgmt_cp_load_link_keys *cp;
@@ -222,6 +366,7 @@ static void read_info_complete(uint8_t status, uint16_t length,
 	adapter->current_settings = btohs(rp->current_settings);
 
 	/* TODO: Register all event notification handlers */
+	register_mgmt_handlers(adapter);
 
 	if (adapter->current_settings & MGMT_SETTING_POWERED)
 		adapter_start(adapter);
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 13/16] android: Implement read_info_complete callback
From: Andrei Emeltchenko @ 2013-09-27 14:12 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1380291161-10232-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Handle read info complete callback from mgmt interface.
---
 android/main.c |  112 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 101 insertions(+), 11 deletions(-)

diff --git a/android/main.c b/android/main.c
index 649867d..658cdd2 100644
--- a/android/main.c
+++ b/android/main.c
@@ -51,6 +51,7 @@
 #include "hcid.h"
 #include "sdpd.h"
 #include "main.h"
+#include "bt_adapter.h"
 
 #include "lib/bluetooth.h"
 #include "lib/mgmt.h"
@@ -155,34 +156,123 @@ static GOptionEntry options[] = {
 	{ NULL }
 };
 
-static void read_info_complete(uint8_t status, uint16_t length,
+static void load_link_keys_complete(uint8_t status, uint16_t length,
 					const void *param, void *user_data)
 {
-	/* TODO: Store Controller information */
-
-	/**
-	 * Register all event notification handlers for controller.
-	 *
-	 * The handlers are registered after a succcesful read of the
-	 * controller info. From now on they can track updates and
-	 * notifications.
-	 */
+	DBG("status %u", status);
+}
+
+static void load_link_keys(struct bt_adapter *adapter, GSList *keys)
+{
+	struct mgmt_cp_load_link_keys *cp;
+	uint16_t key_len = g_slist_length(keys);
+	struct mgmt_link_key_info *key;
+	uint16_t len;
+
+	DBG("");
+
+	len = sizeof(*cp) + key_len * sizeof(*key);
+	cp = malloc(len);
+	if (cp == NULL) {
+		error("%s: Not enough memory for link keys loading", __func__);
+		return;
+	}
+
+	cp->debug_keys = 0;
+	cp->key_count = htobs(key_len);
+
+	mgmt_send(adapter->mgmt, MGMT_OP_LOAD_LINK_KEYS, adapter->dev_id, len,
+				cp, load_link_keys_complete, adapter, NULL);
+
+	free(cp);
 }
 
+static void read_info_complete(uint8_t status, uint16_t length,
+					const void *param, void *user_data)
+{
+	const struct mgmt_rp_read_info *rp = param;
+	struct bt_adapter *adapter = user_data;
+
+	DBG("");
+
+	if (status != MGMT_STATUS_SUCCESS) {
+		error("Failed to read info for index %u: %s (0x%02x)",
+			adapter->dev_id, mgmt_errstr(status), status);
+		goto failed;
+	}
+
+	if (length < sizeof(*rp)) {
+		error("Too small read info complete response");
+		goto failed;
+	}
+
+	if (bacmp(&rp->bdaddr, BDADDR_ANY) == 0) {
+		error("No Bluetooth address for index %u", adapter->dev_id);
+		goto failed;
+	}
+
+	/* Store adapter information */
+	bacpy(&adapter->bdaddr, &rp->bdaddr);
+	adapter->dev_class = rp->dev_class[0] | (rp->dev_class[1] << 8) |
+						(rp->dev_class[2] << 16);
+	adapter->name = g_strdup((const char *) rp->name);
+	adapter->short_name = g_strdup((const char *) rp->short_name);
+
+	adapter->supported_settings = btohs(rp->supported_settings);
+	adapter->current_settings = btohs(rp->current_settings);
+
+	/* TODO: Register all event notification handlers */
+
+	if (adapter->current_settings & MGMT_SETTING_POWERED)
+		adapter_start(adapter);
+
+	/* dummy link keys loading */
+	load_link_keys(adapter, NULL);
+
+	return;
+
+failed:
+	adapter_list = g_list_remove(adapter_list, adapter);
+
+	bt_adapter_unref(adapter);
+}
 
 static void mgmt_index_added_event(uint16_t index, uint16_t length,
 					const void *param, void *user_data)
 {
+	struct bt_adapter *adapter;
+
 	info("%s: index %u", __func__, index);
 
+	adapter = bt_adapter_lookup(index);
+	if (adapter) {
+		warn("Ignoring %s for an already existing adapter", __func__);
+		return;
+	}
+
+	adapter = bt_adapter_new(index, mgmt_if);
+	if (adapter == NULL) {
+		error("Unable to create new adapter for index %u", index);
+		return;
+	}
+
+	adapter_list = g_list_append(adapter_list, adapter);
+
+	/* TODO: Add complex logic here */
+	if (index == 0)
+		default_adapter = adapter;
+
 	DBG("sending read info command for index %u", index);
 
 	if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL,
-					read_info_complete, NULL, NULL) > 0)
+					read_info_complete, adapter, NULL) > 0)
 		return;
 
 	error("Failed to read adapter info for index %u", index);
 
+	adapter_list = g_list_remove(adapter_list, adapter);
+
+	bt_adapter_unref(adapter);
 }
 
 static void mgmt_index_removed_event(uint16_t index, uint16_t length,
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 12/16] android: Add cap to bind to port < 1024
From: Andrei Emeltchenko @ 2013-09-27 14:12 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1380291161-10232-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

For SDP server we need to bind to lower port, acquire this capability.
---
 android/main.c |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 configure.ac   |    4 ++++
 2 files changed, 57 insertions(+)

diff --git a/android/main.c b/android/main.c
index 5fef095..649867d 100644
--- a/android/main.c
+++ b/android/main.c
@@ -31,6 +31,19 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/prctl.h>
+#include <linux/capability.h>
+
+/**
+ * Include <sys/capability.h> for host build and
+ * also for Android 4.3 when it is added to bionic
+ */
+#if (defined(__ANDROID_API__) && (__ANDROID_API__ > 17)) || \
+					!defined(__ANDROID_API__)
+#include <sys/capability.h>
+#endif
 
 #include <glib.h>
 
@@ -319,6 +332,43 @@ static void cleanup_mgmt_interface(void)
 	mgmt_if = NULL;
 }
 
+static bool android_set_aid_and_cap()
+{
+	struct __user_cap_header_struct header;
+	struct __user_cap_data_struct cap;
+
+	DBG("%s: pid %d uid %d gid %d", __func__, getpid(), getuid(), getgid());
+
+	header.version = _LINUX_CAPABILITY_VERSION;
+	header.pid = getpid();
+	if (capget(&header, &cap) < 0)
+		error("%s: capget(): %s", __func__, strerror(errno));
+
+	DBG("%s: Cap data 0x%x, 0x%x, 0x%x\n", __func__, cap.effective,
+					cap.permitted, cap.inheritable);
+
+	prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+
+	header.version = _LINUX_CAPABILITY_VERSION;
+	header.pid = 0;
+
+	cap.effective = cap.permitted = cap.inheritable =
+		1 << CAP_NET_RAW |
+		1 << CAP_NET_ADMIN |
+		1 << CAP_NET_BIND_SERVICE |
+		1 << CAP_SYS_RAWIO |
+		1 << CAP_SYS_NICE |
+		1 << CAP_SETGID;
+
+	if (capset(&header, &cap)) {
+		error("%s: capset(): %s", __func__, strerror(errno));
+		return false;
+	}
+
+	DBG("%s: capset(): Success", __func__);
+	return true;
+}
+
 int main(int argc, char *argv[])
 {
 	GOptionContext *context;
@@ -357,6 +407,9 @@ int main(int argc, char *argv[])
 	/* no need to keep parsed option in memory */
 	free_options();
 
+	if (android_set_aid_and_cap() == false)
+		exit(1);
+
 	init_mgmt_interface();
 
 	DBG("Entering main loop");
diff --git a/configure.ac b/configure.ac
index 3b7a5d9..af418d3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -247,4 +247,8 @@ AC_ARG_ENABLE(android-daemon, AC_HELP_STRING([--enable-android-daemon],
 					[android_daemon=${enableval}])
 AM_CONDITIONAL(ANDROID_DAEMON, test "${android_daemon}" = "yes")
 
+if (test "${android_daemon}" = "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

* [RFC 11/16] android: sdp: Reuse BlueZ SDP server in Android
From: Andrei Emeltchenko @ 2013-09-27 14:12 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1380291161-10232-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Reuse existing SDP server code in Android GPL daemon.
---
 Makefile.android     |    7 +++++--
 android/Android.mk   |    6 ++++++
 android/bt_adapter.c |    5 ++++-
 android/main.c       |   27 +++++++++++++++++++++++++++
 android/main.h       |   25 +++++++++++++++++++++++++
 5 files changed, 67 insertions(+), 3 deletions(-)
 create mode 100644 android/main.h

diff --git a/Makefile.android b/Makefile.android
index 3e6fec0..bf82928 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -3,7 +3,10 @@ if ANDROID_DAEMON
 noinst_PROGRAMS += android/bluezd
 
 android_bluezd_SOURCES = android/main.c src/log.c \
+				src/sdpd-database.c src/sdpd-server.c \
+				src/sdpd-service.c src/sdpd-request.c \
 				src/shared/util.h src/shared/util.c \
-				src/shared/mgmt.h src/shared/mgmt.c
-android_bluezd_LDADD = @GLIB_LIBS@
+				src/shared/mgmt.h src/shared/mgmt.c \
+				android/bt_adapter.h android/bt_adapter.c
+android_bluezd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
 endif
diff --git a/android/Android.mk b/android/Android.mk
index 36f8798..08e35e4 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -9,6 +9,11 @@ include $(CLEAR_VARS)
 LOCAL_SRC_FILES := \
 	log.c \
 	main.c \
+	bt_adapter.c \
+	../src/sdpd-database.c \
+	../src/sdpd-service.c \
+	../src/sdpd-request.c \
+	../src/sdpd-server.c \
 
 LOCAL_C_INCLUDES := \
 	$(call include-path-for, glib) \
@@ -24,6 +29,7 @@ LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
 LOCAL_SHARED_LIBRARIES := \
 	libglib \
 	libbluez \
+	libbluetooth \
 
 LOCAL_MODULE := bluezd
 
diff --git a/android/bt_adapter.c b/android/bt_adapter.c
index 9f64839..42facb6 100644
--- a/android/bt_adapter.c
+++ b/android/bt_adapter.c
@@ -23,6 +23,7 @@
 
 #include "bt_adapter.h"
 #include "log.h"
+#include "main.h"
 #include "src/shared/mgmt.h"
 
 struct bt_device *bt_device_ref(struct bt_device *device)
@@ -118,7 +119,7 @@ void adapter_start(struct bt_adapter *adapter)
 
 	/* TODO: CB: report scan mode */
 
-	/* TODO: SDP start here */
+	sdp_start();
 
 	/* TODO: CB: report state on */
 }
@@ -126,4 +127,6 @@ void adapter_start(struct bt_adapter *adapter)
 void adapter_stop(struct bt_adapter *adapter)
 {
 	DBG("disabled %u", adapter->dev_id);
+
+	sdp_stop();
 }
diff --git a/android/main.c b/android/main.c
index 4792919..5fef095 100644
--- a/android/main.c
+++ b/android/main.c
@@ -36,6 +36,8 @@
 
 #include "log.h"
 #include "hcid.h"
+#include "sdpd.h"
+#include "main.h"
 
 #include "lib/bluetooth.h"
 #include "lib/mgmt.h"
@@ -43,12 +45,37 @@
 
 #define SHUTDOWN_GRACE_SECONDS 10
 
+struct main_opts main_opts;
+
 static GMainLoop *event_loop;
 static struct mgmt *mgmt_if = NULL;
 
 static uint8_t mgmt_version = 0;
 static uint8_t mgmt_revision = 0;
 
+GList *adapter_list = NULL;
+struct bt_adapter *default_adapter = NULL;
+
+int sdp_start(void)
+{
+	uint16_t mtu = 0;
+	uint32_t flags = 0;
+
+	DBG("");
+
+	/* sdpd-server use these settings */
+	memset(&main_opts, 0, sizeof(main_opts));
+
+	return start_sdp_server(mtu, flags);
+}
+
+void sdp_stop(void)
+{
+	DBG("");
+
+	stop_sdp_server();
+}
+
 void btd_exit(void)
 {
 	g_main_loop_quit(event_loop);
diff --git a/android/main.h b/android/main.h
new file mode 100644
index 0000000..6ecad14
--- /dev/null
+++ b/android/main.h
@@ -0,0 +1,25 @@
+/*
+ *
+ *  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
+ *
+ */
+
+int sdp_start(void);
+void sdp_stop(void);
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 10/16] android: Add Android Makefile for libbluetooth
From: Andrei Emeltchenko @ 2013-09-27 14:12 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1380291161-10232-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Build libbluetooth library for Android.
---
 android/Android.mk |   55 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/android/Android.mk b/android/Android.mk
index e892249..36f8798 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -84,3 +84,58 @@ LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000
 LOCAL_MODULE    := libbluez
 
 include $(BUILD_SHARED_LIBRARY)
+
+#
+# libbluetooth library
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+	../lib/bluetooth.c \
+	../lib/sdp.c \
+	../lib/hci.c \
+	../lib/uuid.c \
+
+LOCAL_C_INCLUDES := \
+	$(LOCAL_PATH)/../lib/ \
+	$(LOCAL_PATH)/../src/shared \
+
+LOCAL_C_INCLUDES += \
+	$(call include-path-for, glib) \
+	$(call include-path-for, glib)/glib \
+
+LOCAL_CFLAGS += -O3
+
+# to suppress the "pointer of type 'void *' used in arithmetic" warning
+LOCAL_CFLAGS += -Wno-pointer-arith
+
+# to suppress the "missing initializer near initialization" warning
+LOCAL_CFLAGS += -Wno-missing-field-initializers
+
+# to suppress the "may be used uninitialized in this function" warning
+LOCAL_CFLAGS += -Wno-maybe-uninitialized
+
+# Define missing flags for Android 4.2
+LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000
+
+lib_headers := \
+	bluetooth.h \
+	hci.h \
+	hci_lib.h \
+	sco.h \
+	l2cap.h \
+	sdp.h \
+	sdp_lib.h \
+	rfcomm.h \
+	bnep.h \
+	cmtp.h \
+	hidp.h \
+
+$(shell mkdir -p $(LOCAL_PATH)/bluetooth)
+
+$(foreach file,$(lib_headers), $(shell ln -sf ../$(file) $(LOCAL_PATH)/bluetooth/$(file)))
+
+LOCAL_MODULE := libbluetooth
+
+include $(BUILD_SHARED_LIBRARY)
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 09/16] android: Add adapter and device struct for BlueZ daemon
From: Andrei Emeltchenko @ 2013-09-27 14:12 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1380291161-10232-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Adapter structure in BlueZ daemon keeps track of default adapter
and device structure keeps track about found devices.
---
 android/bt_adapter.c |  129 ++++++++++++++++++++++++++++++++++++++++++++++++++
 android/bt_adapter.h |   68 ++++++++++++++++++++++++++
 2 files changed, 197 insertions(+)
 create mode 100644 android/bt_adapter.c
 create mode 100644 android/bt_adapter.h

diff --git a/android/bt_adapter.c b/android/bt_adapter.c
new file mode 100644
index 0000000..9f64839
--- /dev/null
+++ b/android/bt_adapter.c
@@ -0,0 +1,129 @@
+/*
+ *
+ *  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
+ *
+ */
+
+#include "bt_adapter.h"
+#include "log.h"
+#include "src/shared/mgmt.h"
+
+struct bt_device *bt_device_ref(struct bt_device *device)
+{
+	DBG("");
+
+	__sync_fetch_and_add(&device->refcnt, 1);
+
+	return device;
+}
+
+void bt_device_unref(struct bt_device *device)
+{
+	DBG("");
+
+	if (__sync_sub_and_fetch(&device->refcnt, 1))
+		return;
+
+	/* TODO: */
+	DBG("%s: Freeing device %p name %s", __func__, device, device->name);
+
+	free(device->name);
+	free(device);
+}
+
+struct bt_adapter *bt_adapter_lookup(uint16_t index)
+{
+	GList *list;
+
+	for (list = g_list_first(adapter_list); list;
+						list = g_list_next(list)) {
+		struct bt_adapter *adapter = list->data;
+
+		if (adapter->dev_id == index)
+			return adapter;
+	}
+
+	return NULL;
+}
+
+struct bt_adapter *bt_adapter_ref(struct bt_adapter *adapter)
+{
+	DBG("");
+
+	__sync_fetch_and_add(&adapter->refcnt, 1);
+
+	return adapter;
+}
+
+static void bt_adapter_free(struct bt_adapter *adapter)
+{
+	DBG("");
+
+	while (adapter->found_devices) {
+		struct bt_device *device = adapter->found_devices->data;
+
+		adapter->found_devices = g_list_remove(adapter->found_devices,
+								device);
+		bt_device_unref(device);
+	}
+
+	mgmt_unref(adapter->mgmt);
+	free(adapter);
+}
+
+void bt_adapter_unref(struct bt_adapter *adapter)
+{
+	DBG("");
+
+	if (__sync_sub_and_fetch(&adapter->refcnt, 1))
+		return;
+
+	bt_adapter_free(adapter);
+}
+
+struct bt_adapter *bt_adapter_new(uint16_t index, struct mgmt *mgmt_if)
+{
+	struct bt_adapter *adapter;
+
+	adapter = g_try_new0(struct bt_adapter, 1);
+	if (!adapter)
+		return NULL;
+
+	adapter->dev_id = index;
+	adapter->mgmt = mgmt_ref(mgmt_if);
+
+	return bt_adapter_ref(adapter);
+}
+
+void adapter_start(struct bt_adapter *adapter)
+{
+	DBG("enabled %u", adapter->dev_id);
+
+	/* TODO: CB: report scan mode */
+
+	/* TODO: SDP start here */
+
+	/* TODO: CB: report state on */
+}
+
+void adapter_stop(struct bt_adapter *adapter)
+{
+	DBG("disabled %u", adapter->dev_id);
+}
diff --git a/android/bt_adapter.h b/android/bt_adapter.h
new file mode 100644
index 0000000..5634729
--- /dev/null
+++ b/android/bt_adapter.h
@@ -0,0 +1,68 @@
+/*
+ *
+ *  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
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <glib.h>
+
+#include "lib/bluetooth.h"
+
+struct bt_device {
+	int refcnt;
+
+	bdaddr_t bdaddr;
+	uint8_t bdaddr_type;
+	uint32_t cod;
+	char *name;
+};
+
+struct bt_adapter {
+	int refcnt;
+
+	uint16_t dev_id;
+	struct mgmt *mgmt;
+	bdaddr_t bdaddr;
+	uint32_t dev_class;
+
+	char *name;
+	char *short_name;
+
+	uint32_t supported_settings;
+	uint32_t current_settings;
+
+	GList *found_devices;
+};
+
+extern GList *adapter_list;
+
+struct bt_adapter *bt_adapter_lookup(uint16_t index);
+struct bt_adapter *bt_adapter_ref(struct bt_adapter *adapter);
+void bt_adapter_unref(struct bt_adapter *adapter);
+struct bt_adapter *bt_adapter_new(uint16_t index, struct mgmt *mgmt_if);
+
+struct bt_device *bt_device_ref(struct bt_device *device);
+void bt_device_unref(struct bt_device *device);
+
+void adapter_start(struct bt_adapter *adapter);
+void adapter_stop(struct bt_adapter *adapter);
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 08/16] android: Add Android HAL callback task
From: Andrei Emeltchenko @ 2013-09-27 14:12 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1380291161-10232-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Android HAL callback task listens for messages from BlueZ GPL daemon.
---
 android/Android.mk      |    6 ++
 android/hal_cb_thread.c |  144 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 150 insertions(+)
 create mode 100644 android/hal_cb_thread.c

diff --git a/android/Android.mk b/android/Android.mk
index f9c73a2..e892249 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -37,10 +37,16 @@ include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
 	hal_bluetooth.c \
+	hal_cb_thread.c \
 	hal_bt_sock.c \
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
+	libglib \
+
+LOCAL_C_INCLUDES := \
+	$(call include-path-for, glib) \
+	$(call include-path-for, glib)/glib \
 
 LOCAL_MODULE := bluetooth.default
 LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
diff --git a/android/hal_cb_thread.c b/android/hal_cb_thread.c
new file mode 100644
index 0000000..b7aebe8
--- /dev/null
+++ b/android/hal_cb_thread.c
@@ -0,0 +1,144 @@
+/*
+ * 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 <glib.h>
+#include <stdbool.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+#include <errno.h>
+
+#include <hardware/bluetooth.h>
+
+#define LOG_TAG "BlueZ"
+#include <cutils/log.h>
+
+#include "hal_msg.h"
+
+#define HAL_CBACK(base, cb_function, ...)				\
+	do {								\
+		if (base && base->cb_function) {			\
+			ALOGI("CB %s->%s", #base, #cb_function);	\
+			base->cb_function(__VA_ARGS__);			\
+		} else {						\
+			ALOGE("%s: Callback is NULL", __func__);	\
+		}							\
+	} while (0)
+
+static GMainLoop *event_loop;
+
+extern bt_callbacks_t *bt_hal_cbacks;
+
+static void bthal_thread_associate(void)
+{
+	ALOGI(__func__);
+
+	HAL_CBACK(bt_hal_cbacks, thread_evt_cb, ASSOCIATE_JVM);
+}
+
+static void bthal_thread_disassociate(void)
+{
+	ALOGI(__func__);
+
+	HAL_CBACK(bt_hal_cbacks, thread_evt_cb, DISASSOCIATE_JVM);
+
+	bt_hal_cbacks = NULL;
+}
+
+void process_msg(struct hal_msg_hdr *msg)
+{
+	ALOGI(__func__);
+
+	/* TODO: Process messages from daemon */
+}
+
+static gboolean hal_session_event(GIOChannel *iochan, GIOCondition cond,
+				  gpointer data)
+{
+	struct hal_msg_hdr msg;
+	int sock, len, size;
+	uint8_t *buf;
+
+	if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
+		ALOGE("%s: error condition %d", __func__, cond);
+		return FALSE;
+	}
+
+	sock = g_io_channel_unix_get_fd(iochan);
+
+	len = recv(sock, &msg, sizeof(msg), MSG_PEEK);
+	if (len <= 0) {
+		ALOGE("%s: recv(): %s %d", __func__, strerror(errno), sock);
+		return FALSE;
+	}
+
+	size = sizeof(msg) + msg.len;
+
+	ALOGD("%s: Read first %d bytes, total %d", __func__, len, size);
+
+	buf = malloc(size);
+	if (buf == NULL)
+		return FALSE;
+
+	len = recv(sock, buf, size, 0);
+	if (len != size) {
+		ALOGE("%s: recv(): %s %d", __func__, strerror(errno), sock);
+		free(buf);
+		return FALSE;
+	}
+
+	process_msg((struct hal_msg_hdr *) buf);
+
+	free(buf);
+
+	return TRUE;
+}
+
+int hal_cb_init_sock(int sock)
+{
+	GIOChannel *iochan;
+	int id;
+
+	ALOGD("%s: sock %d", __func__, sock);
+
+	iochan = g_io_channel_unix_new(sock);
+	g_io_channel_set_close_on_unref(iochan, TRUE);
+
+	id = g_io_add_watch(iochan, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+			    hal_session_event, &sock);
+
+	ALOGD("%s: Add chan %p watch id %d", __func__, iochan, id);
+
+	g_io_channel_unref(iochan);
+
+	return id;
+}
+
+void *hal_cb_task(void *arg)
+{
+	event_loop = g_main_loop_new(NULL, FALSE);
+
+	bthal_thread_associate();
+
+	g_main_loop_run(event_loop);
+
+	g_main_loop_unref(event_loop);
+
+	bthal_thread_disassociate();
+
+	return NULL;
+}
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 07/16] android: Create HAL API header skeleton
From: Andrei Emeltchenko @ 2013-09-27 14:12 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1380291161-10232-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Header describes the protocol between Android HAL threads and BlueZ
daemon.
---
 android/hal_msg.h |  260 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 260 insertions(+)
 create mode 100644 android/hal_msg.h

diff --git a/android/hal_msg.h b/android/hal_msg.h
new file mode 100644
index 0000000..2d4436a
--- /dev/null
+++ b/android/hal_msg.h
@@ -0,0 +1,260 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2013  Intel Corporation. All rights reserved.
+ *
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef __packed
+#define __packed __attribute__((packed))
+#endif
+
+typedef struct {
+	uint8_t b[6];
+} __packed __bdaddr_t;
+
+struct hal_msg_hdr {
+	uint8_t service_id;
+	uint8_t opcode;
+	uint16_t len;
+	uint8_t payload[0];
+} __packed;
+
+#define HAL_SERVICE_ID_CORE		0
+#define HAL_SERVICE_ID_BLUETOOTH	1
+#define HAL_SERVICE_ID_HIDHOST		3
+#define HAL_SERVICE_ID_PAN		4
+#define HAL_SERVICE_ID_HANDSFREE	5
+#define HAL_SERVICE_ID_AD2P		6
+#define HAL_SERVICE_ID_HEALTH		7
+#define HAL_SERVICE_ID_AVRCP		8
+#define HAL_SERVICE_ID_GATT		9
+
+/* Core Service */
+
+struct hal_msg_rsp {
+	struct hal_msg_hdr hdr;
+	uint8_t status;
+} __packed;
+
+#define HAL_MSG_OP_ERROR		0x00
+struct hal_msg_rp_error {
+	uint8_t status;
+} __packed;
+
+#define HAL_MSG_OP_REGISTER_MODULE	0x02
+struct hal_msg_cp_register_module {
+	uint8_t service_id;
+} __packed;
+
+struct hal_msg_rp_register_module {
+	uint8_t service_id;
+} __packed;
+
+#define HAL_MSG_OP_UNREGISTER_MODULE	0x03
+struct hal_msg_cp_unregister_module {
+	uint8_t service_id;
+} __packed;
+
+/* Bluetooth Core HAL API */
+
+#define HAL_MSG_OP_BT_ENABLE		0x01
+
+#define HAL_MSG_OP_BT_DISABLE		0x02
+
+#define HAL_MSG_OP_BT_GET_ADAPTER_PROPS	0x03
+
+#define HAL_MSG_OP_BT_GET_ADAPTER_PROP	0x04
+struct hal_msg_cp_bt_get_adapter_prop {
+	uint8_t type;
+} __packed;
+
+#define HAL_MSG_OP_BT_SET_ADAPTER_PROP	0x05
+struct hal_msg_cp_bt_set_adapter_prop {
+	uint8_t type;
+	uint16_t len;
+	uint8_t val[0];
+} __packed;
+
+#define HAL_MSG_OP_BT_GET_REMOTE_DEVICE_PROPS	0x06
+struct hal_msg_cp_bt_get_remote_device_props {
+	__bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_GET_REMOTE_DEVICE_PROP	0x07
+struct hal_msg_cp_bt_get_remote_device_prop {
+	__bdaddr_t bdaddr;
+	uint8_t type;
+} __packed;
+
+#define HAL_MSG_OP_BT_SET_REMOTE_DEVICE_PROP	0x08
+struct hal_msg_cp_bt_set_remote_device_prop {
+	__bdaddr_t bdaddr;
+	uint8_t type;
+	uint16_t len;
+	uint8_t val[0];
+} __packed;
+
+#define HAL_MSG_OP_BT_GET_REMOTE_SERVICE_REC	0x09
+struct hal_msg_cp_bt_get_remote_service_rec {
+	__bdaddr_t bdaddr;
+	uint8_t uuid[16];
+} __packed;
+
+#define HAL_MSG_OP_BT_GET_REMOTE_SERVICE	0x0a
+struct hal_msg_cp_bt_get_remote_service {
+	__bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_START_DISCOVERY	0x0b
+
+#define HAL_MSG_OP_BT_CANCEL_DISCOVERY	0x0c
+
+#define HAL_MSG_OP_BT_CREATE_BOND	0x0d
+struct hal_msg_cp_bt_create_bond {
+	__bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_REMOVE_BOND	0x0d
+struct hal_msg_cp_bt_remove_bond {
+	__bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_CANCEL_BOND	0x0f
+struct hal_msg_cp_bt_cancel_bond {
+	__bdaddr_t bdaddr;
+} __packed;
+
+#define HAL_MSG_OP_BT_PIN_REPLY		0x10
+struct hal_msg_cp_bt_pin_reply {
+	__bdaddr_t bdaddr;
+	uint8_t accept;
+	uint8_t pin_len;
+	uint8_t pin_code[16];
+} __packed;
+
+#define HAL_MSG_OP_BT_SSP_REPLY		0x11
+struct hal_msg_cp_bt_ssp_reply {
+	__bdaddr_t bdaddr;
+	uint8_t ssp_variant;
+	uint8_t accept;
+	uint32_t passkey;
+} __packed;
+
+#define HAL_MSG_OP_BT_DUT_MODE_CONF	0x12
+struct hal_msg_cp_bt_dut_mode_conf {
+	uint8_t enable;
+} __packed;
+
+#define HAL_MSG_OP_BT_DUT_MODE_SEND	0x13
+struct hal_msg_cp_bt_dut_mode_send {
+	uint16_t opcode;
+	uint8_t len;
+	uint8_t data[0];
+} __packed;
+
+#define HAL_MSG_OP_BT_LE_TEST_MODE	0x14
+struct hal_msg_cp_bt_le_test_mode {
+	uint16_t opcode;
+	uint8_t len;
+	uint8_t data[0];
+} __packed;
+
+/* 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 {
+	uint8_t state;
+} __packed;
+
+#define HAL_MSG_EV_BT_ADAPTER_PROPS_CHANGED	0x82
+struct hal_property {
+	uint8_t type;
+	uint16_t len;
+	uint8_t val[0];
+} __packed;
+struct hal_msg_ev_bt_adapter_props_changed {
+	uint8_t status;
+	uint8_t num_props;
+	struct hal_property props[0];
+} __packed;
+
+#define HAL_MSG_EV_BT_REMOTE_DEVICE_PROPS	0x83
+struct hal_msg_ev_bt_remote_device_props {
+	uint8_t status;
+	__bdaddr_t bdaddr;
+	uint8_t num_props;
+	struct hal_property props[0];
+} __packed;
+
+#define HAL_MSG_EV_BT_DEVICE_FOUND		0x84
+struct hal_msg_ev_bt_device_found {
+	uint8_t num_props;
+	struct hal_property props[0];
+} __packed;
+
+#define HAL_MSG_EV_BT_DISCOVERY_STATE_CHANGED	0x85
+struct hal_msg_ev_bt_discovery_state_changed {
+	uint8_t state;
+} __packed;
+
+#define HAL_MSG_EV_BT_PIN_REQUEST		0x86
+struct hal_msg_ev_bt_pin_request {
+	__bdaddr_t bdaddr;
+	uint8_t name[249 - 1];
+	uint8_t class_of_dev[3];
+} __packed;
+
+#define HAL_MSG_EV_BT_SSP_REQUEST		0x87
+struct hal_msg_ev_bt_ssp_request {
+	__bdaddr_t bdaddr;
+	uint8_t name[249 - 1];
+	uint8_t class_of_dev[3];
+	uint8_t pairing_variant;
+	uint32_t passkey;
+} __packed;
+
+#define HAL_MSG_EV_BT_BOND_STATE_CHANGED	0x88
+struct hal_msg_ev_bt_bond_state_changed {
+	uint8_t status;
+	__bdaddr_t bdaddr;
+	uint8_t state;
+} __packed;
+
+#define HAL_MSG_EV_BT_ACL_STATE_CHANGED		0x89
+struct hal_msg_ev_bt_acl_state_changed {
+	uint8_t status;
+	__bdaddr_t bdaddr;
+	uint8_t state;
+} __packed;
+
+#define HAL_MSG_EV_BT_DUT_MODE_RECEIVE		0x8a
+struct hal_msg_ev_bt_dut_mode_receive {
+	uint16_t opcode;
+	uint8_t len;
+	uint8_t data[0];
+} __packed;
+
+#define HAL_MSG_EV_BT_LE_TEST_MODE		0x8b
+struct hal_msg_ev_bt_le_test_mode {
+	uint8_t status;
+	uint16_t num_packets;
+} __packed;
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 06/16] android: Add basic mgmt initialization sequence
From: Andrei Emeltchenko @ 2013-09-27 14:12 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1380291161-10232-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Initialize bluetooth controller via mgmt interface.
---
 Makefile.android   |    4 +-
 android/Android.mk |    5 ++
 android/main.c     |  189 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 197 insertions(+), 1 deletion(-)

diff --git a/Makefile.android b/Makefile.android
index 8f65dbf..3e6fec0 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -2,6 +2,8 @@
 if ANDROID_DAEMON
 noinst_PROGRAMS += android/bluezd
 
-android_bluezd_SOURCES = android/main.c src/log.c
+android_bluezd_SOURCES = android/main.c src/log.c \
+				src/shared/util.h src/shared/util.c \
+				src/shared/mgmt.h src/shared/mgmt.c
 android_bluezd_LDADD = @GLIB_LIBS@
 endif
diff --git a/android/Android.mk b/android/Android.mk
index 40cff9a..f9c73a2 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -13,12 +13,17 @@ LOCAL_SRC_FILES := \
 LOCAL_C_INCLUDES := \
 	$(call include-path-for, glib) \
 	$(call include-path-for, glib)/glib \
+
+LOCAL_C_INCLUDES += \
+	$(LOCAL_PATH)/../ \
 	$(LOCAL_PATH)/../src \
+	$(LOCAL_PATH)/../lib \
 
 LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
 
 LOCAL_SHARED_LIBRARIES := \
 	libglib \
+	libbluez \
 
 LOCAL_MODULE := bluezd
 
diff --git a/android/main.c b/android/main.c
index ef62b3d..4792919 100644
--- a/android/main.c
+++ b/android/main.c
@@ -25,6 +25,7 @@
 #include <config.h>
 #endif
 
+#include <stdbool.h>
 #include <signal.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -36,9 +37,17 @@
 #include "log.h"
 #include "hcid.h"
 
+#include "lib/bluetooth.h"
+#include "lib/mgmt.h"
+#include "src/shared/mgmt.h"
+
 #define SHUTDOWN_GRACE_SECONDS 10
 
 static GMainLoop *event_loop;
+static struct mgmt *mgmt_if = NULL;
+
+static uint8_t mgmt_version = 0;
+static uint8_t mgmt_revision = 0;
 
 void btd_exit(void)
 {
@@ -106,6 +115,183 @@ static GOptionEntry options[] = {
 	{ NULL }
 };
 
+static void read_info_complete(uint8_t status, uint16_t length,
+					const void *param, void *user_data)
+{
+	/* TODO: Store Controller information */
+
+	/**
+	 * Register all event notification handlers for controller.
+	 *
+	 * The handlers are registered after a succcesful read of the
+	 * controller info. From now on they can track updates and
+	 * notifications.
+	 */
+}
+
+
+static void mgmt_index_added_event(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	info("%s: index %u", __func__, index);
+
+	DBG("sending read info command for index %u", index);
+
+	if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL,
+					read_info_complete, NULL, NULL) > 0)
+		return;
+
+	error("Failed to read adapter info for index %u", index);
+
+}
+
+static void mgmt_index_removed_event(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	info("%s: index %u", __func__, index);
+}
+
+static void read_index_list_complete(uint8_t status, uint16_t length,
+					const void *param, void *user_data)
+{
+	const struct mgmt_rp_read_index_list *rp = param;
+	uint16_t num;
+	int i;
+
+	info(__func__);
+
+	if (status != MGMT_STATUS_SUCCESS) {
+		error("%s: Failed to read index list: %s (0x%02x)",
+					__func__, mgmt_errstr(status), status);
+		return;
+	}
+
+	if (length < sizeof(*rp)) {
+		error("%s: Wrong size of read index list response", __func__);
+		return;
+	}
+
+	num = btohs(rp->num_controllers);
+
+	DBG("%s: Number of controllers: %d", __func__, num);
+
+	if (num * sizeof(uint16_t) + sizeof(*rp) != length) {
+		error("%s: Incorrect pkt size for index list rsp", __func__);
+		return;
+	}
+
+	for (i = 0; i < num; i++) {
+		uint16_t index;
+
+		index = btohs(rp->index[i]);
+
+		DBG("%s: Found index %u", __func__, index);
+
+		/**
+		 * Use index added event notification.
+		 */
+		mgmt_index_added_event(index, 0, NULL, NULL);
+	}
+}
+
+
+static void read_commands_complete(uint8_t status, uint16_t length,
+					const void *param, void *user_data)
+{
+	const struct mgmt_rp_read_commands *rp = param;
+	uint16_t num_commands, num_events;
+
+	info(__func__);
+
+	if (status != MGMT_STATUS_SUCCESS) {
+		error("Failed to read supported commands: %s (0x%02x)",
+						mgmt_errstr(status), status);
+		return;
+	}
+
+	if (length < sizeof(*rp)) {
+		error("Wrong size of read commands response");
+		return;
+	}
+
+	num_commands = btohs(rp->num_commands);
+	num_events = btohs(rp->num_events);
+
+	DBG("Number of commands: %d", num_commands);
+	DBG("Number of events: %d", num_events);
+}
+
+static void read_version_complete(uint8_t status, uint16_t length,
+					const void *param, void *user_data)
+{
+	const struct mgmt_rp_read_version *rp = param;
+
+	info(__func__);
+
+	if (status != MGMT_STATUS_SUCCESS) {
+		error("Failed to read version information: %s (0x%02x)",
+						mgmt_errstr(status), status);
+		return;
+	}
+
+	if (length < sizeof(*rp)) {
+		error("Wrong size response");
+		return;
+	}
+
+	mgmt_version = rp->version;
+	mgmt_revision = btohs(rp->revision);
+
+	info("Bluetooth management interface %u.%u initialized",
+						mgmt_version, mgmt_revision);
+
+	if (mgmt_version < 1) {
+		error("Version 1.0 or later of management interface required");
+		abort();
+	}
+
+	DBG("sending read supported commands command");
+
+	mgmt_send(mgmt_if, MGMT_OP_READ_COMMANDS, MGMT_INDEX_NONE, 0, NULL,
+					read_commands_complete, NULL, NULL);
+
+	mgmt_register(mgmt_if, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
+					mgmt_index_added_event, NULL, NULL);
+	mgmt_register(mgmt_if, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
+					mgmt_index_removed_event, NULL, NULL);
+
+	DBG("sending read index list command");
+
+	if (mgmt_send(mgmt_if, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0,
+			NULL, read_index_list_complete, NULL, NULL) > 0)
+		return;
+
+	error("Failed to read controller index list");
+}
+
+static bool init_mgmt_interface(void)
+{
+	mgmt_if = mgmt_new_default();
+	if (mgmt_if == NULL) {
+		error("Failed to access management interface");
+		return false;
+	}
+
+	if (mgmt_send(mgmt_if, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE, 0, NULL,
+				read_version_complete, NULL, NULL) == 0) {
+		error("Error sending READ_VERSION mgmt command");
+		return false;
+	}
+
+	return true;
+}
+
+static void cleanup_mgmt_interface(void)
+{
+	mgmt_unref(mgmt_if);
+	mgmt_if = NULL;
+}
+
 int main(int argc, char *argv[])
 {
 	GOptionContext *context;
@@ -144,10 +330,13 @@ int main(int argc, char *argv[])
 	/* no need to keep parsed option in memory */
 	free_options();
 
+	init_mgmt_interface();
+
 	DBG("Entering main loop");
 
 	g_main_loop_run(event_loop);
 
+	cleanup_mgmt_interface();
 	g_main_loop_unref(event_loop);
 
 	info("Exit");
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 05/16] android: Add Android Makefile for mgmt library
From: Andrei Emeltchenko @ 2013-09-27 14:12 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1380291161-10232-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Build libbluez shared library for Android.
---
 android/Android.mk |   30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/android/Android.mk b/android/Android.mk
index 93de803..40cff9a 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -43,3 +43,33 @@ LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := SHARED_LIBRARIES
 
 include $(BUILD_SHARED_LIBRARY)
+
+#
+# mgmt library libbluez
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+	../src/shared/mgmt.c \
+	../src/shared/util.c \
+
+LOCAL_C_INCLUDES := \
+	$(call include-path-for, glib) \
+	$(call include-path-for, glib)/glib \
+
+LOCAL_C_INCLUDES += \
+	$(LOCAL_PATH)/../ \
+
+LOCAL_SHARED_LIBRARIES := \
+	libglib \
+
+# to suppress the "pointer of type 'void *' used in arithmetic" warning
+LOCAL_CFLAGS := -Wno-pointer-arith
+
+# Define missing flags for Android 4.2
+LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000
+
+LOCAL_MODULE    := libbluez
+
+include $(BUILD_SHARED_LIBRARY)
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 04/16] android: Start Android Bluetooth daemon
From: Andrei Emeltchenko @ 2013-09-27 14:12 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1380291161-10232-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Start Android Bluetooth daemon from HAL init(). Make sure
that daemon is in "running" state.
---
 android/hal_bluetooth.c |   54 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)

diff --git a/android/hal_bluetooth.c b/android/hal_bluetooth.c
index 5298618..036091e 100644
--- a/android/hal_bluetooth.c
+++ b/android/hal_bluetooth.c
@@ -23,11 +23,16 @@
 #include <hardware/bluetooth.h>
 #include <hardware/bt_sock.h>
 
+#include <cutils/sockets.h>
+#include <cutils/properties.h>
+
 #define LOG_TAG "BlueZ"
 #include <cutils/log.h>
 
 #include "hal.h"
 
+#define ANDROID_BLUEZ "bluezd"
+
 bt_callbacks_t *bt_hal_cbacks = NULL;
 
 static bool interface_ready(void)
@@ -35,6 +40,49 @@ static bool interface_ready(void)
 	return bt_hal_cbacks != NULL;
 }
 
+static bool is_running(const char *service_name)
+{
+	char val[PROPERTY_VALUE_MAX];
+	char name[PROPERTY_KEY_MAX];
+	int  ret;
+
+	ALOGI(__func__);
+
+	ret = snprintf(name, sizeof(name), "init.svc.%s", service_name);
+	if (ret > (int) sizeof(name) - 1) {
+		ALOGD("Service name '%s' is too long", service_name);
+		return false;
+	}
+
+	if (property_get(name, val, NULL)) {
+		if (strcmp(val, "running") == 0)
+			return true;
+	}
+
+	return false;
+}
+
+static bool start_bt_daemon(void)
+{
+	int tries = 40; /* wait 4 seconds for completion */
+
+	ALOGI(__func__);
+
+	/* Start Android Bluetooth daemon service */
+	property_set("ctl.start", ANDROID_BLUEZ);
+
+	while (tries-- > 0) {
+		if (is_running(ANDROID_BLUEZ) == true) {
+			ALOGI("Android BlueZ daemon started");
+			return true;
+		}
+
+		usleep(100000);
+	}
+
+	return false;
+}
+
 static bool is_profile(const char *profile, const char *str)
 {
 	return (strlen(str) == strlen(profile)) &&
@@ -51,7 +99,11 @@ static int init(bt_callbacks_t *callbacks)
 	/* store reference to user callbacks */
 	bt_hal_cbacks = callbacks;
 
-	/* TODO: Init here bluezd task */
+	if (start_bt_daemon() == true) {
+		/* TODO: open channel */
+
+		return BT_STATUS_SUCCESS;
+	}
 
 	return BT_STATUS_UNSUPPORTED;
 }
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 03/16] android: Enable Socket interface
From: Andrei Emeltchenko @ 2013-09-27 14:12 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1380291161-10232-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Returns socket interface, use header hal.h to avoid externs.
---
 android/hal.h           |   18 ++++++++++++++++++
 android/hal_bluetooth.c |   12 ++++++++++++
 2 files changed, 30 insertions(+)
 create mode 100644 android/hal.h

diff --git a/android/hal.h b/android/hal.h
new file mode 100644
index 0000000..40fbf03
--- /dev/null
+++ b/android/hal.h
@@ -0,0 +1,18 @@
+/*
+ * 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.
+ *
+ */
+
+btsock_interface_t *bt_get_sock_interface(void);
diff --git a/android/hal_bluetooth.c b/android/hal_bluetooth.c
index 9970374..5298618 100644
--- a/android/hal_bluetooth.c
+++ b/android/hal_bluetooth.c
@@ -21,10 +21,13 @@
 #include <stdbool.h>
 
 #include <hardware/bluetooth.h>
+#include <hardware/bt_sock.h>
 
 #define LOG_TAG "BlueZ"
 #include <cutils/log.h>
 
+#include "hal.h"
+
 bt_callbacks_t *bt_hal_cbacks = NULL;
 
 static bool interface_ready(void)
@@ -32,6 +35,12 @@ static bool interface_ready(void)
 	return bt_hal_cbacks != NULL;
 }
 
+static bool is_profile(const char *profile, const char *str)
+{
+	return (strlen(str) == strlen(profile)) &&
+		(strncmp(profile, str, strlen(str)) == 0);
+}
+
 static int init(bt_callbacks_t *callbacks)
 {
 	ALOGD(__func__);
@@ -246,6 +255,9 @@ static const void *get_profile_interface(const char *profile_id)
 	if (interface_ready() == false)
 		return NULL;
 
+	if (is_profile(profile_id, BT_PROFILE_SOCKETS_ID))
+		return bt_get_sock_interface();
+
 	return NULL;
 }
 
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 02/16] android: Add Socket Bluetooth HAL template
From: Andrei Emeltchenko @ 2013-09-27 14:12 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1380291161-10232-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

bt_sock HAL handles Bluetooth sockets for Android.
---
 android/Android.mk    |    1 +
 android/hal_bt_sock.c |   84 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+)
 create mode 100644 android/hal_bt_sock.c

diff --git a/android/Android.mk b/android/Android.mk
index ca9501f..93de803 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -32,6 +32,7 @@ include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
 	hal_bluetooth.c \
+	hal_bt_sock.c \
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
diff --git a/android/hal_bt_sock.c b/android/hal_bt_sock.c
new file mode 100644
index 0000000..cbb42d1
--- /dev/null
+++ b/android/hal_bt_sock.c
@@ -0,0 +1,84 @@
+/*
+ * 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 <stdlib.h>
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_sock.h>
+
+#define LOG_TAG "BlueZ"
+#include <cutils/log.h>
+
+static bt_status_t btsock_listen_rfcomm(const char *service_name,
+					const uint8_t *uuid, int chan,
+					int *sock, int flags)
+{
+	ALOGD(__func__);
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t listen(btsock_type_t type, const char *service_name,
+					const uint8_t *uuid, int chan,
+					int *sock, int flags)
+{
+	if ((uuid == NULL && chan <= 0) || sock == NULL) {
+		ALOGE("%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);
+
+	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);
+	}
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t connect(const bt_bdaddr_t *bdaddr, btsock_type_t type,
+					const uint8_t *uuid, int chan,
+					int *sock, int flags)
+{
+	if ((uuid == NULL && chan <= 0) || bdaddr == NULL || sock == NULL) {
+		ALOGE("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);
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static btsock_interface_t btsock_if = {
+	sizeof(btsock_if),
+	listen,
+	connect
+};
+
+btsock_interface_t *bt_get_sock_interface(void)
+{
+	return &btsock_if;
+}
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 01/16] android: Add Adapter Bluetooth HAL template
From: Andrei Emeltchenko @ 2013-09-27 14:12 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1380291161-10232-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Add template for bluetooth.h Android HAL.
---
 android/Android.mk      |   19 +++
 android/hal_bluetooth.c |  348 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 367 insertions(+)
 create mode 100644 android/hal_bluetooth.c

diff --git a/android/Android.mk b/android/Android.mk
index 5d09f00..ca9501f 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -23,3 +23,22 @@ LOCAL_SHARED_LIBRARIES := \
 LOCAL_MODULE := bluezd
 
 include $(BUILD_EXECUTABLE)
+
+#
+# bluetooth.default.so HAL
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+	hal_bluetooth.c \
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+
+LOCAL_MODULE := bluetooth.default
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/android/hal_bluetooth.c b/android/hal_bluetooth.c
new file mode 100644
index 0000000..9970374
--- /dev/null
+++ b/android/hal_bluetooth.c
@@ -0,0 +1,348 @@
+/*
+ * 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 <stdlib.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include <hardware/bluetooth.h>
+
+#define LOG_TAG "BlueZ"
+#include <cutils/log.h>
+
+bt_callbacks_t *bt_hal_cbacks = NULL;
+
+static bool interface_ready(void)
+{
+	return bt_hal_cbacks != NULL;
+}
+
+static int init(bt_callbacks_t *callbacks)
+{
+	ALOGD(__func__);
+
+	if (interface_ready() == true)
+		return BT_STATUS_SUCCESS;
+
+	/* store reference to user callbacks */
+	bt_hal_cbacks = callbacks;
+
+	/* TODO: Init here bluezd task */
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static int enable(void)
+{
+	ALOGD(__func__);
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static int disable(void)
+{
+	ALOGD(__func__);
+
+	if (interface_ready() == false)
+		return BT_STATUS_NOT_READY;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static void cleanup(void)
+{
+	ALOGD(__func__);
+
+	if (interface_ready() == false)
+		return;
+
+	bt_hal_cbacks = NULL;
+}
+
+static int get_adapter_properties(void)
+{
+	ALOGD(__func__);
+
+	if (interface_ready() == false)
+		return BT_STATUS_NOT_READY;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_adapter_property(bt_property_type_t type)
+{
+	ALOGD(__func__);
+
+	if (interface_ready() == false)
+		return BT_STATUS_NOT_READY;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static int set_adapter_property(const bt_property_t *property)
+{
+	ALOGD(__func__);
+
+	if (interface_ready() == false)
+		return BT_STATUS_NOT_READY;
+
+	if (property == NULL)
+		return BT_STATUS_PARM_INVALID;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_remote_device_properties(bt_bdaddr_t *remote_addr)
+{
+	ALOGD(__func__);
+
+	if (interface_ready() == false)
+		return BT_STATUS_NOT_READY;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_remote_device_property(bt_bdaddr_t *remote_addr,
+						bt_property_type_t type)
+{
+	ALOGD(__func__);
+
+	if (interface_ready() == false)
+		return BT_STATUS_NOT_READY;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static int set_remote_device_property(bt_bdaddr_t *remote_addr,
+						const bt_property_t *property)
+{
+	ALOGD(__func__);
+
+	/* sanity check */
+	if (interface_ready() == false)
+		return BT_STATUS_NOT_READY;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_remote_service_record(bt_bdaddr_t *remote_addr, bt_uuid_t *uuid)
+{
+	ALOGD(__func__);
+
+	if (interface_ready() == false)
+		return BT_STATUS_NOT_READY;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static int get_remote_services(bt_bdaddr_t *remote_addr)
+{
+	ALOGD(__func__);
+
+	if (interface_ready() == false)
+		return BT_STATUS_NOT_READY;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static int start_discovery(void)
+{
+	ALOGD(__func__);
+
+	if (interface_ready() == false)
+		return BT_STATUS_NOT_READY;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static int cancel_discovery(void)
+{
+	ALOGD(__func__);
+
+	if (interface_ready() == false)
+		return BT_STATUS_NOT_READY;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static int create_bond(const bt_bdaddr_t *bd_addr)
+{
+	ALOGD(__func__);
+
+	if (interface_ready() == false)
+		return BT_STATUS_NOT_READY;
+
+	if (bd_addr == NULL)
+		return BT_STATUS_PARM_INVALID;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static int cancel_bond(const bt_bdaddr_t *bd_addr)
+{
+	ALOGD(__func__);
+
+	if (interface_ready() == false)
+		return BT_STATUS_NOT_READY;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static int remove_bond(const bt_bdaddr_t *bd_addr)
+{
+	ALOGD(__func__);
+
+	if (interface_ready() == false)
+		return BT_STATUS_NOT_READY;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+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__);
+
+	if (interface_ready() == false)
+		return BT_STATUS_NOT_READY;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static int ssp_reply(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
+					uint8_t accept, uint32_t passkey)
+{
+
+	ALOGD(__func__);
+
+	if (interface_ready() == false)
+		return BT_STATUS_NOT_READY;
+
+	if (bd_addr == NULL)
+		return BT_STATUS_PARM_INVALID;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static const void *get_profile_interface(const char *profile_id)
+{
+	ALOGD("%s: %s", __func__, profile_id);
+
+	if (interface_ready() == false)
+		return NULL;
+
+	return NULL;
+}
+
+static int dut_mode_configure(uint8_t enable)
+{
+	ALOGD(__func__);
+
+	if (interface_ready() == false)
+		return BT_STATUS_NOT_READY;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+static int dut_mode_send(uint16_t opcode, uint8_t *buf, uint8_t len)
+{
+	ALOGD(__func__);
+
+	if (interface_ready() == false)
+		return BT_STATUS_NOT_READY;
+
+	return BT_STATUS_UNSUPPORTED;
+}
+
+/**
+ * HAL Interface declaration
+ */
+static const bt_interface_t bluetooth_if = {
+	sizeof(bt_interface_t),
+	init,
+	enable,
+	disable,
+	cleanup,
+	get_adapter_properties,
+	get_adapter_property,
+	set_adapter_property,
+	get_remote_device_properties,
+	get_remote_device_property,
+	set_remote_device_property,
+	get_remote_service_record,
+	get_remote_services,
+	start_discovery,
+	cancel_discovery,
+	create_bond,
+	remove_bond,
+	cancel_bond,
+	pin_reply,
+	ssp_reply,
+	get_profile_interface,
+	dut_mode_configure,
+	dut_mode_send
+};
+
+static const bt_interface_t *get_bluetooth_interface(void)
+{
+	ALOGD(__func__);
+
+	return &bluetooth_if;
+}
+
+static int close_bluetooth(struct hw_device_t *device)
+{
+	ALOGD(__func__);
+
+	cleanup();
+
+	return 0;
+}
+
+static int open_bluetooth(const struct hw_module_t *module, char const *name,
+					struct hw_device_t **device)
+{
+	bluetooth_device_t *dev = malloc(sizeof(bluetooth_device_t));
+
+	ALOGD(__func__);
+
+	memset(dev, 0, sizeof(bluetooth_device_t));
+	dev->common.tag = HARDWARE_DEVICE_TAG;
+	dev->common.version = 0;
+	dev->common.module = (struct hw_module_t *) module;
+	dev->common.close = close_bluetooth;
+	dev->get_bluetooth_interface = get_bluetooth_interface;
+
+	*device = (struct hw_device_t *) dev;
+
+	return 0;
+}
+
+static struct hw_module_methods_t bluetooth_module_methods = {
+	.open = open_bluetooth,
+};
+
+struct hw_module_t HAL_MODULE_INFO_SYM = {
+	.tag = HARDWARE_MODULE_TAG,
+	.version_major = 1,
+	.version_minor = 0,
+	.id = BT_HARDWARE_MODULE_ID,
+	.name = "BlueZ Bluetooth stack",
+	.author = "Intel Corporation",
+	.methods = &bluetooth_module_methods
+};
-- 
1.7.10.4


^ permalink raw reply related

* [RFC 00/16] Basic code for Android BlueZ
From: Andrei Emeltchenko @ 2013-09-27 14:12 UTC (permalink / raw)
  To: linux-bluetooth

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

Skeletons for Android Bluetooth and Socket HALs and BlueZ daemon.

Andrei Emeltchenko (16):
  android: Add Adapter Bluetooth HAL template
  android: Add Socket Bluetooth HAL template
  android: Enable Socket interface
  android: Start Android Bluetooth daemon
  android: Add Android Makefile for mgmt library
  android: Add basic mgmt initialization sequence
  android: Create HAL API header skeleton
  android: Add Android HAL callback task
  android: Add adapter and device struct for BlueZ daemon
  android: Add Android Makefile for libbluetooth
  android: sdp: Reuse BlueZ SDP server in Android
  android: Add cap to bind to port < 1024
  android: Implement read_info_complete callback
  android: Handle mgmt changed events
  android: Implement basic HAL server
  android: Add HAL message helpers

 Makefile.android         |   10 +-
 android/Android.mk       |  124 +++++++++++
 android/bt_adapter.c     |  132 ++++++++++++
 android/bt_adapter.h     |   68 +++++++
 android/hal.h            |   18 ++
 android/hal_bluetooth.c  |  412 +++++++++++++++++++++++++++++++++++++
 android/hal_bt_sock.c    |   84 ++++++++
 android/hal_cb_thread.c  |  144 +++++++++++++
 android/hal_msg.c        |  241 ++++++++++++++++++++++
 android/hal_msg.h        |  263 ++++++++++++++++++++++++
 android/hal_msg_client.c |  112 ++++++++++
 android/hal_msg_client.h |   25 +++
 android/main.c           |  508 ++++++++++++++++++++++++++++++++++++++++++++++
 android/main.h           |   25 +++
 configure.ac             |    4 +
 15 files changed, 2168 insertions(+), 2 deletions(-)
 create mode 100644 android/bt_adapter.c
 create mode 100644 android/bt_adapter.h
 create mode 100644 android/hal.h
 create mode 100644 android/hal_bluetooth.c
 create mode 100644 android/hal_bt_sock.c
 create mode 100644 android/hal_cb_thread.c
 create mode 100644 android/hal_msg.c
 create mode 100644 android/hal_msg.h
 create mode 100644 android/hal_msg_client.c
 create mode 100644 android/hal_msg_client.h
 create mode 100644 android/main.h

-- 
1.7.10.4


^ permalink raw reply

* Re: [PATCH 3/8] Bluetooth: Test for HCI_SETUP and HCI_USER_CHANNEL in mgmt_valid_hdev()
From: Johan Hedberg @ 2013-09-27 11:45 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <C7C45B32-4EF9-4FD7-B774-E88917DFAC75@holtmann.org>

Hi Marcel,

On Fri, Sep 27, 2013, Marcel Holtmann wrote:
> >>> If either one of the HCI_SETUP or HCI_USER_CHANNEL flags is set the
> >>> device is not considered valid for mgmt. By having these checks inside
> >>> the mgmt_valid_hdev function the a couple of places using it can be
> >>> simplified.
> >> 
> >> I looked at doing this and decided not to. Reason was that the device
> >> gets removed from mgmt anyway.
> > 
> > I'm not sure what significance you think "device gets removed from mgmt"
> > has. All that is is a mgmt event saying that index has been removed. In
> > addition to that we need to ensure that we don't send any more mgmt
> > events for such devices and that we don't include such devices in the
> > response to mgmt_read_index list.
> > 
> > These are the two places of the code that my patch simplifies, one is
> > the check for whether to send a "power on" mgmt event and the other the
> > response handling of read_index_list.
> 
> I have taken care of that part. It is done inside mgmt_control() and
> in case of a controller in user channel mode it returns invalid index.

That's great, but it doesn't cover the read_index_list command which we
were talking about here since the command doesn't target any specific
controller (as per our mgmt-api.txt it has the value <non-controller> as
the controller index). The command handler will in this case be invoked
that that's where it'd be convenient to rely on mgmt_valid_hdev() for
constructing the response.

> For the events, I have no idea on how we would generate events if we
> are not going through hci_event.c when the user channel is active.

The "powered on" event in question doesn't come from hci_event.c but
from the hci_dev_open() function, so again this is not covered by the
existing user channel checks.

Johan

^ permalink raw reply

* Re: [PATCH 1/2] android: Add skeleton of BlueZ Android daemon
From: Andrei Emeltchenko @ 2013-09-27  6:50 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Lukasz Rymanowski, Frederic Danis, linux-bluetooth
In-Reply-To: <188944FA-9CB2-433B-A3D2-D706DBD6E1BD@holtmann.org>

Hi Marcel,

On Fri, Sep 27, 2013 at 03:56:14AM +0200, Marcel Holtmann wrote:
> Hi Andrei,
> 
> >>>>> Define local mapping to glib path, otherwise this has to be inside
> >>>>> central
> >>>>> place in the build repository.
> >>>>> 
> >>>>> Retrieve Bluetooth version from configure.ac.
> >>>>> ---
> >>>>> .gitignore         |    2 +
> >>>>> Android.mk         |    9 ++++
> >>>>> Makefile.am        |    1 +
> >>>>> Makefile.android   |    7 ++++
> >>>>> android/Android.mk |   24 +++++++++++
> >>>>> android/main.c     |  119
> >>>>> ++++++++++++++++++++++++++++++++++++++++++++++++++++
> >>>>> configure.ac       |    5 +++
> >>>>> 7 files changed, 167 insertions(+)
> >>>>> create mode 100644 Android.mk
> >>>>> create mode 100644 Makefile.android
> >>>>> create mode 100644 android/Android.mk
> >>>>> create mode 100644 android/main.c
> >>>> 
> >>>> 
> >>>> lets split this out a little bit. Code additions should not be intermixed
> >>>> with additions to the build system and especially configure options.
> >>>> 
> >>>> I rather not have a top-level Android.mk. It should be enough to provide
> >>>> an android/Android.mk.
> >> 
> >> BTW, do you expect to have only one Android.mk for the whole project or
> >> this is OK for you to have smaller Android.mk in different subfolders like
> >> /src/shared etc. Both ways are valid.
> > 
> > While having a single huge Android makefile is somehow make sense it would have
> > several disadvantages:
> > - we cannot use local build with "mm" for building for example only tools
> >  or libs
> > - Android.mk will become very large and difficult to read
> 
> I have no idea what this means. Lets start with a single
> android/Android.mk and then go from there. I am strictly against
> cluttering the whole project with Android specific make files.

OK, we will use the single Android makefile, it is actually not that big.

Best regards 
Andrei Emeltchenko 

^ permalink raw reply

* Re: [PATCH 3/8] Bluetooth: Test for HCI_SETUP and HCI_USER_CHANNEL in mgmt_valid_hdev()
From: Marcel Holtmann @ 2013-09-27  2:12 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <20130925100353.GA3158@x220.p-661hnu-f1>

Hi Johan,

>>> If either one of the HCI_SETUP or HCI_USER_CHANNEL flags is set the
>>> device is not considered valid for mgmt. By having these checks inside
>>> the mgmt_valid_hdev function the a couple of places using it can be
>>> simplified.
>> 
>> I looked at doing this and decided not to. Reason was that the device
>> gets removed from mgmt anyway.
> 
> I'm not sure what significance you think "device gets removed from mgmt"
> has. All that is is a mgmt event saying that index has been removed. In
> addition to that we need to ensure that we don't send any more mgmt
> events for such devices and that we don't include such devices in the
> response to mgmt_read_index list.
> 
> These are the two places of the code that my patch simplifies, one is
> the check for whether to send a "power on" mgmt event and the other the
> response handling of read_index_list.

I have taken care of that part. It is done inside mgmt_control() and in case of a controller in user channel mode it returns invalid index.

For the events, I have no idea on how we would generate events if we are not going through hci_event.c when the user channel is active.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH v2 1/3] build: Add skeleton for BlueZ Android
From: Marcel Holtmann @ 2013-09-27  2:08 UTC (permalink / raw)
  To: Frederic Danis; +Cc: linux-bluetooth
In-Reply-To: <1380024798-32017-1-git-send-email-frederic.danis@linux.intel.com>

Hi Fred,

> Makefile.am         |    4 +++-
> Makefile.android    |    4 ++++
> android/Android.mk  |    5 +++++
> bootstrap-configure |    3 ++-
> configure.ac        |    4 ++++
> 5 files changed, 18 insertions(+), 2 deletions(-)
> create mode 100644 Makefile.android
> create mode 100644 android/Android.mk
> 
> diff --git a/Makefile.am b/Makefile.am
> index 4e4b1c5..51204f4 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -179,6 +179,7 @@ test_scripts =
> 
> include Makefile.tools
> include Makefile.obexd
> +include Makefile.android
> 
> if HID2HCI
> rulesdir = @UDEV_DIR@/rules.d
> @@ -293,7 +294,8 @@ pkgconfig_DATA = lib/bluez.pc
> endif
> 
> DISTCHECK_CONFIGURE_FLAGS = --disable-datafiles --enable-library \
> -					--disable-systemd --disable-udev
> +					--disable-systemd --disable-udev \
> +					--enable-android
> 
> DISTCLEANFILES = $(pkgconfig_DATA)
> 
> diff --git a/Makefile.android b/Makefile.android
> new file mode 100644
> index 0000000..5e43730
> --- /dev/null
> +++ b/Makefile.android
> @@ -0,0 +1,4 @@
> +
> +if ANDROID
> +EXTRA_DIST += android/Android.mk
> +endif

as I mentioned in another patch. No need for if around EXTRA_DIST.

> diff --git a/android/Android.mk b/android/Android.mk
> new file mode 100644
> index 0000000..e810654
> --- /dev/null
> +++ b/android/Android.mk
> @@ -0,0 +1,5 @@
> +LOCAL_PATH := $(call my-dir)
> +
> +# Retrieve BlueZ version from configure.ac file
> +BLUEZ_VERSION := $(shell grep AC_INIT $(LOCAL_PATH)/../configure.ac | tr -d ' ' | sed -e 's/.*(.*,\(.*\))/\1/')
> +
> diff --git a/bootstrap-configure b/bootstrap-configure
> index 7a6e7d1..8bde920 100755
> --- a/bootstrap-configure
> +++ b/bootstrap-configure
> @@ -12,4 +12,5 @@ fi
> 		--sysconfdir=/etc \
> 		--localstatedir=/var \
> 		--enable-experimental \
> -		--disable-datafiles $*
> +		--disable-datafiles \
> +		--enable-android $*

Historically --disable-datafiles is always last. And I like to keep it that way. Please add it after --enable-experimental.

> diff --git a/configure.ac b/configure.ac
> index 41c2935..22ab240 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -242,4 +242,8 @@ AC_DEFINE_UNQUOTED(CONFIGDIR, "${configdir}",
> 			[Directory for the configuration files])
> AC_SUBST(CONFIGDIR, "${configdir}")
> 
> +AC_ARG_ENABLE(android, AC_HELP_STRING([--enable-android],
> +			[enable BlueZ Android]), [android=${enableval}])

I would call it BlueZ for Android, but that is minor details.

> +AM_CONDITIONAL(ANDROID, test "${android}" = "yes")

However this should be ${enable_android} like with every other configure option we have.

> +
> AC_OUTPUT(Makefile src/bluetoothd.8 lib/bluez.pc)

Regards

Marcel


^ permalink raw reply

* Re: [PATCH v2 2/3] android: Add skeleton of BlueZ Android daemon
From: Marcel Holtmann @ 2013-09-27  2:05 UTC (permalink / raw)
  To: Frederic Danis; +Cc: linux-bluetooth
In-Reply-To: <1380024798-32017-2-git-send-email-frederic.danis@linux.intel.com>

Hi Fred,

> Define local mapping to glib path, otherwise this has to be inside central
> place in the build repository.
> 
> Retrieve Bluetooth version from configure.ac.
> ---
> .gitignore         |    2 +
> Makefile.android   |    5 +++

I rather keep the changes to a global Makefile separate from the android/ stuff.

> android/Android.mk |   24 ++++++++++++
> android/main.c     |  110 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 141 insertions(+)
> create mode 100644 android/main.c

It is perfectly fine to split this into two patches. Add the *.c file(s) first and in a second patch add the build changes.

> diff --git a/.gitignore b/.gitignore
> index 8a25a3e..3707209 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -98,3 +98,5 @@ unit/test-gobex-packet
> unit/test-gobex-transfer
> unit/test-*.log
> unit/test-*.trs
> +
> +android/bluetoothd
> diff --git a/Makefile.android b/Makefile.android
> index 5e43730..e056dce 100644
> --- a/Makefile.android
> +++ b/Makefile.android
> @@ -1,4 +1,9 @@
> 
> if ANDROID
> +noinst_PROGRAMS += android/bluetoothd
> +
> +android_bluetoothd_SOURCES = android/main.c
> +android_bluetoothd_LDADD = @GLIB_LIBS@
> +
> EXTRA_DIST += android/Android.mk
> endif

You can not put the EXTRA_DIST under an if ANDROID. Make that part global.

I expect that make distcheck works no matter what is configured. Check the final tarballs if all files are actually included.

Regards

Marcel


^ 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