* [RFCv1 1/6] android: Add capabilities and set userid
2013-10-21 11:28 [RFCv1 0/6] Set of patches implementing missing IPC functionality Andrei Emeltchenko
@ 2013-10-21 11:28 ` Andrei Emeltchenko
2013-10-21 11:28 ` [RFCv1 2/6] android: Handle mgmt changed events Andrei Emeltchenko
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Andrei Emeltchenko @ 2013-10-21 11:28 UTC (permalink / raw)
To: linux-bluetooth
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 [flat|nested] 7+ messages in thread* [RFCv1 2/6] android: Handle mgmt changed events
2013-10-21 11:28 [RFCv1 0/6] Set of patches implementing missing IPC functionality Andrei Emeltchenko
2013-10-21 11:28 ` [RFCv1 1/6] android: Add capabilities and set userid Andrei Emeltchenko
@ 2013-10-21 11:28 ` Andrei Emeltchenko
2013-10-21 11:28 ` [RFCv1 3/6] android: Implement basic HAL server Andrei Emeltchenko
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Andrei Emeltchenko @ 2013-10-21 11:28 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Add code handling changing adapter settings.
---
android/adapter.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 129 insertions(+)
diff --git a/android/adapter.c b/android/adapter.c
index 4009f4d..cae3187 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -69,6 +69,134 @@ failed:
adapter->ready(NULL, err);
}
+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->name, (const char *) rp->name))
+ return;
+
+ DBG("name: %s", rp->name);
+
+ g_free(adapter->name);
+ adapter->name = g_strdup((const char *) rp->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)
+ start_adapter()
+ else
+ stop_adapter()
+ */
+ }
+
+ 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;
+ 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 */
+
+ /* TODO: Gatt attrib set*/
+}
+
+static void register_mgmt_handlers(struct bt_adapter *adapter)
+{
+ mgmt_register(adapter->mgmt, MGMT_EV_NEW_SETTINGS, 0,
+ new_settings_callback, adapter, NULL);
+
+ mgmt_register(adapter->mgmt, MGMT_EV_CLASS_OF_DEV_CHANGED,
+ 0, mgmt_dev_class_changed_event,
+ adapter, NULL);
+
+ mgmt_register(adapter->mgmt, MGMT_EV_LOCAL_NAME_CHANGED,
+ 0, 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;
@@ -128,6 +256,7 @@ static void read_info_complete(uint8_t status, uint16_t length, const void *para
adapter->current_settings = btohs(rp->current_settings);
/* TODO: Register all event notification handlers */
+ register_mgmt_handlers(adapter);
load_link_keys(adapter, NULL);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 7+ messages in thread* [RFCv1 3/6] android: Implement basic HAL server
2013-10-21 11:28 [RFCv1 0/6] Set of patches implementing missing IPC functionality Andrei Emeltchenko
2013-10-21 11:28 ` [RFCv1 1/6] android: Add capabilities and set userid Andrei Emeltchenko
2013-10-21 11:28 ` [RFCv1 2/6] android: Handle mgmt changed events Andrei Emeltchenko
@ 2013-10-21 11:28 ` Andrei Emeltchenko
2013-10-21 11:28 ` [RFCv1 4/6] android: Add HAL message helpers Andrei Emeltchenko
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Andrei Emeltchenko @ 2013-10-21 11:28 UTC (permalink / raw)
To: linux-bluetooth
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 | 2 +-
android/Android.mk | 1 +
android/hal-msg.c | 267 ++++++++++++++++++++++++++++++++++++++++++++++++++++
android/hal-msg.h | 5 +
android/main.c | 11 +++
5 files changed, 285 insertions(+), 1 deletion(-)
create mode 100644 android/hal-msg.c
diff --git a/Makefile.android b/Makefile.android
index 8196583..96f3f22 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -3,7 +3,7 @@ noinst_PROGRAMS += android/bluetoothd
android_bluetoothd_SOURCES = android/main.c \
src/log.c \
- android/hal-msg.h \
+ android/hal-msg.h android/hal-msg.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 \
diff --git a/android/Android.mk b/android/Android.mk
index 30b2169..d5dfde7 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -16,6 +16,7 @@ LOCAL_SRC_FILES := \
main.c \
log.c \
adapter.c \
+ hal-msg.c \
../src/shared/mgmt.c \
../src/shared/util.c \
../src/sdpd-database.c \
diff --git a/android/hal-msg.c b/android/hal-msg.c
new file mode 100644
index 0000000..aa02236
--- /dev/null
+++ b/android/hal-msg.c
@@ -0,0 +1,267 @@
+/*
+ *
+ * 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;
+ uint8_t buf[MAX_HAL_BUF_SIZE];
+ int sock, len;
+ 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, buf, sizeof(buf), 0);
+ if (len <= 0) {
+ error("%s: recv(): %s", __func__, strerror(errno));
+ /* TODO: handle */
+ return FALSE;
+ }
+
+ if (len < (int) sizeof(struct hal_msg_hdr))
+ return FALSE;
+
+ status = process_hal_msg(buf, len);
+
+ hdr = (struct hal_msg_hdr *) buf;
+
+ if (status == 0) {
+ /* Success reply */
+ len = send(sock, hdr, sizeof(*hdr), 0);
+ if (len != sizeof(hdr)) {
+ error("%s: send() rsp: %s", __func__, strerror(errno));
+ /* TODO: handle */
+ return FALSE;
+ }
+ } else {
+ struct hal_msg_rsp {
+ struct hal_msg_hdr hdr;
+ uint8_t status;
+ } rsp;
+
+ rsp.hdr.service_id = hdr->service_id;
+ rsp.hdr.opcode = HAL_MSG_OP_ERROR;
+ rsp.hdr.len = sizeof(rsp.status);
+ rsp.status = status;
+
+ len = send(sock, &rsp, sizeof(rsp), 0);
+ if (len != sizeof(rsp)) {
+ error("%s: send() rsp: %s", __func__, strerror(errno));
+ /* TODO: handle */
+ return FALSE;
+ }
+ }
+
+ 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);
+
+ DBG("");
+
+ 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;
+ size_t len;
+
+ DBG("");
+
+ sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+ if (sock < 0) {
+ error("%s: socket(): %s", __func__, strerror(errno));
+ return sock;
+ }
+
+ len = strlen(sock_path);
+ if (len > sizeof(addr.sun_path) - 1) {
+ error("%s: too big socket name", __func__);
+ return -1;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strcpy(addr.sun_path, sock_path);
+
+ /* let fail for android */
+ if (unlink(addr.sun_path) < 0)
+ warn("%s: unlink() %s failed: %s", __func__, sock_path,
+ strerror(errno));
+
+ 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;
+ }
+
+ chmod(sock_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+
+ 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 4440fc8..f27662a 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -23,6 +23,9 @@
static const char BLUEZ_HAL_SK_PATH[] = "\0bluez_hal_socket";
+void start_hal_srv(const char *sock_path);
+void stop_hal_srv(void);
+
struct hal_msg_hdr {
uint8_t service_id;
uint8_t opcode;
@@ -40,6 +43,8 @@ struct hal_msg_hdr {
#define HAL_SERVICE_ID_AVRCP 8
#define HAL_SERVICE_ID_GATT 9
+#define MAX_HAL_BUF_SIZE 1024
+
/* Core Service */
#define HAL_MSG_OP_ERROR 0x00
diff --git a/android/main.c b/android/main.c
index 4a716be..99db09b 100644
--- a/android/main.c
+++ b/android/main.c
@@ -56,6 +56,14 @@
#include "adapter.h"
#include "hal-msg.h"
+#if defined(ANDROID)
+#define BT_HAL_SOCKET "/tmp/bt_hal"
+#else
+#define BT_HAL_SOCKET "/var/run/bt_hal"
+#endif
+
+#define SHUTDOWN_GRACE_SECONDS 10
+
static GMainLoop *event_loop;
static struct mgmt *mgmt_if = NULL;
@@ -505,6 +513,7 @@ int main(int argc, char *argv[])
/* Use params: mtu = 0, flags = 0 */
start_sdp_server(0, 0);
+ start_hal_srv(BT_HAL_SOCKET);
DBG("Entering main loop");
@@ -513,6 +522,8 @@ int main(int argc, char *argv[])
g_source_remove(signal);
cleanup_hal_connection();
+
+ stop_hal_srv();
stop_sdp_server();
cleanup_mgmt_interface();
g_main_loop_unref(event_loop);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 7+ messages in thread* [RFCv1 4/6] android: Add HAL message helpers
2013-10-21 11:28 [RFCv1 0/6] Set of patches implementing missing IPC functionality Andrei Emeltchenko
` (2 preceding siblings ...)
2013-10-21 11:28 ` [RFCv1 3/6] android: Implement basic HAL server Andrei Emeltchenko
@ 2013-10-21 11:28 ` Andrei Emeltchenko
2013-10-21 11:28 ` [RFCv1 5/6] android: Add helper to send fd using SCM_RIGHTS Andrei Emeltchenko
2013-10-21 11:28 ` [RFCv1 6/6] android: Add Android HAL callback task Andrei Emeltchenko
5 siblings, 0 replies; 7+ messages in thread
From: Andrei Emeltchenko @ 2013-10-21 11:28 UTC (permalink / raw)
To: linux-bluetooth
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 | 123 ++++++++++++++++++++++++++++++++++++++++++++++
android/hal-msg-client.h | 25 ++++++++++
3 files changed, 149 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 d5dfde7..4bd4116 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -56,6 +56,7 @@ LOCAL_SRC_FILES := \
hal-sock.c \
hal-hidhost.c \
hal-pan.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..43af9a1
--- /dev/null
+++ b/android/hal-msg-client.c
@@ -0,0 +1,123 @@
+/*
+ *
+ * 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 "/tmp/bt_hal"
+
+int open_hal_chan(void)
+{
+ int tries = 10;
+ int sock;
+
+ while (tries-- > 0) {
+ sock = socket_local_client(BLUEZ_SOCKET,
+ ANDROID_SOCKET_NAMESPACE_FILESYSTEM,
+ SOCK_SEQPACKET);
+ 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)
+{
+ int len, size;
+ uint8_t buf[MAX_HAL_BUF_SIZE];
+ struct hal_msg_rsp {
+ struct hal_msg_hdr hdr;
+ uint8_t status;
+ } *rsp;
+
+ 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, &buf, sizeof(buf), 0);
+ if (len <= 0) {
+ ALOGE("%s: recv(): %s", __func__, strerror(errno));
+ return BT_STATUS_FAIL;
+ }
+
+ if (len == sizeof(struct hal_msg_hdr))
+ return BT_STATUS_SUCCESS;
+
+ rsp = (struct hal_msg_rsp *) buf;
+
+ ALOGE("%s: error returned: %u", __func__, rsp->status);
+
+ return rsp->status;
+}
+
+int hal_register_module(int sock, uint8_t service_id)
+{
+ struct hal_msg_hdr *hdr;
+ struct hal_msg_cmd_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_cmd_register_module *) hdr + sizeof(*hdr);
+ 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 [flat|nested] 7+ messages in thread* [RFCv1 5/6] android: Add helper to send fd using SCM_RIGHTS
2013-10-21 11:28 [RFCv1 0/6] Set of patches implementing missing IPC functionality Andrei Emeltchenko
` (3 preceding siblings ...)
2013-10-21 11:28 ` [RFCv1 4/6] android: Add HAL message helpers Andrei Emeltchenko
@ 2013-10-21 11:28 ` Andrei Emeltchenko
2013-10-21 11:28 ` [RFCv1 6/6] android: Add Android HAL callback task Andrei Emeltchenko
5 siblings, 0 replies; 7+ messages in thread
From: Andrei Emeltchenko @ 2013-10-21 11:28 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
This is used in accept message to Android framework.
---
android/Android.mk | 1 +
android/bt-sock.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+)
create mode 100644 android/bt-sock.c
diff --git a/android/Android.mk b/android/Android.mk
index 4bd4116..786c9fb 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -57,6 +57,7 @@ LOCAL_SRC_FILES := \
hal-hidhost.c \
hal-pan.c \
hal-msg-client.c \
+ bt-sock.c \
LOCAL_SHARED_LIBRARIES := \
libcutils \
diff --git a/android/bt-sock.c b/android/bt-sock.c
new file mode 100644
index 0000000..68dbe32
--- /dev/null
+++ b/android/bt-sock.c
@@ -0,0 +1,64 @@
+/*
+ * 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 <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+
+#include <cutils/log.h>
+
+int bt_sock_send_acc_fd(int sock_fd, const unsigned char *buf, int len,
+ int send_fd)
+{
+ ssize_t ret;
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ struct iovec iv;
+ char msgbuf[CMSG_SPACE(1)];
+
+ ALOGD("%s: len %d sock_fd %d send_fd %d", __func__, len, sock_fd,
+ send_fd);
+
+ if (sock_fd == -1 || send_fd == -1)
+ return -1;
+
+ memset(&msg, 0, sizeof(msg));
+
+ msg.msg_control = msgbuf;
+ msg.msg_controllen = sizeof(msgbuf);
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(send_fd));
+ memcpy(CMSG_DATA(cmsg), &send_fd, sizeof(send_fd));
+
+ iv.iov_base = (unsigned char *) buf;
+ iv.iov_len = len;
+
+ msg.msg_iov = &iv;
+ msg.msg_iovlen = 1;
+
+ ret = sendmsg(sock_fd, &msg, MSG_NOSIGNAL);
+ if (ret < 0) {
+ ALOGE("%s: sock_fd %d send_fd %d sendmsg ret %d errno %d %s",
+ __func__, sock_fd, send_fd, (int)ret, errno,
+ strerror(errno));
+ return ret;
+ }
+
+ return ret;
+}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 7+ messages in thread* [RFCv1 6/6] android: Add Android HAL callback task
2013-10-21 11:28 [RFCv1 0/6] Set of patches implementing missing IPC functionality Andrei Emeltchenko
` (4 preceding siblings ...)
2013-10-21 11:28 ` [RFCv1 5/6] android: Add helper to send fd using SCM_RIGHTS Andrei Emeltchenko
@ 2013-10-21 11:28 ` Andrei Emeltchenko
5 siblings, 0 replies; 7+ messages in thread
From: Andrei Emeltchenko @ 2013-10-21 11:28 UTC (permalink / raw)
To: linux-bluetooth
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 | 86 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 92 insertions(+)
create mode 100644 android/hal-cb-thread.c
diff --git a/android/Android.mk b/android/Android.mk
index 786c9fb..c5c6e7b 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -58,9 +58,15 @@ LOCAL_SRC_FILES := \
hal-pan.c \
hal-msg-client.c \
bt-sock.c \
+ hal-cb-thread.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..1b1e228
--- /dev/null
+++ b/android/hal-cb-thread.c
@@ -0,0 +1,86 @@
+/*
+ * 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 <stdbool.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <sys/epoll.h>
+#include <hardware/bluetooth.h>
+#include <fcntl.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)
+
+extern bt_callbacks_t *bt_hal_cbacks;
+
+static int epfd;
+
+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 */
+}
+
+int mainloop(void)
+{
+ return EXIT_SUCCESS;
+}
+
+void *hal_cb_task(void *arg)
+{
+ int sock;
+
+ sock = open_hal_chan();
+
+ bthal_thread_associate();
+
+ bthal_thread_disassociate();
+
+ return NULL;
+}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 7+ messages in thread