* [PATCHv1 08/15] android: Add adapter and device struct for BlueZ daemon
From: Andrei Emeltchenko @ 2013-10-07 7:38 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1381131496-9417-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 | 56 ++++++++++++++++++++++++++++++++++++++++++++++
android/bt_adapter.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 116 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..e21d50c
--- /dev/null
+++ b/android/bt_adapter.c
@@ -0,0 +1,56 @@
+/*
+ *
+ * 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_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 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..6877cc7
--- /dev/null
+++ b/android/bt_adapter.h
@@ -0,0 +1,60 @@
+/*
+ *
+ * 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;
+};
+
+struct bt_adapter *bt_adapter_new(uint16_t index, struct mgmt *mgmt_if);
+
+void adapter_start(struct bt_adapter *adapter);
+void adapter_stop(struct bt_adapter *adapter);
--
1.7.10.4
^ permalink raw reply related
* [PATCHv1 09/15] android: Add Android Makefile for libbluetooth
From: Andrei Emeltchenko @ 2013-10-07 7:38 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1381131496-9417-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Build libbluetooth library for Android.
---
android/Android.mk | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/android/Android.mk b/android/Android.mk
index f5fd863..8f95a66 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -41,6 +41,7 @@ LOCAL_SHARED_LIBRARIES := \
libglib \
LOCAL_MODULE := bluetoothd
+LOCAL_REQUIRED_MODULES := libbluetooth
include $(BUILD_EXECUTABLE)
@@ -63,3 +64,55 @@ LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
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
+
+# 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)/../lib/bluetooth)
+
+$(foreach file,$(lib_headers), $(shell ln -sf ../$(file) $(LOCAL_PATH)/../lib/bluetooth/$(file)))
+
+LOCAL_MODULE := libbluetooth
+
+include $(BUILD_SHARED_LIBRARY)
--
1.7.10.4
^ permalink raw reply related
* [PATCHv1 10/15] android: sdp: Reuse BlueZ SDP server in Android
From: Andrei Emeltchenko @ 2013-10-07 7:38 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1381131496-9417-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 | 7 +++++++
android/bt_adapter.c | 2 --
android/main.c | 28 ++++++++++++++++++++++++++++
4 files changed, 40 insertions(+), 4 deletions(-)
diff --git a/Makefile.android b/Makefile.android
index 9a2c486..d576b52 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -2,9 +2,12 @@ if ANDROID
noinst_PROGRAMS += android/bluetoothd
android_bluetoothd_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_bluetoothd_LDADD = @GLIB_LIBS@
+ src/shared/mgmt.h src/shared/mgmt.c \
+ android/bt_adapter.h android/bt_adapter.c
+android_bluetoothd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
endif
EXTRA_DIST += android/Android.mk android/log.c
diff --git a/android/Android.mk b/android/Android.mk
index 8f95a66..e7a70d0 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -17,6 +17,11 @@ LOCAL_SRC_FILES := \
log.c \
../src/shared/mgmt.c \
../src/shared/util.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) \
@@ -25,6 +30,7 @@ LOCAL_C_INCLUDES := \
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/../ \
$(LOCAL_PATH)/../src \
+ $(LOCAL_PATH)/../lib \
LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
@@ -39,6 +45,7 @@ LOCAL_CFLAGS += -DSOCK_CLOEXEC=02000000 -DSOCK_NONBLOCK=04000
LOCAL_SHARED_LIBRARIES := \
libglib \
+ libbluetooth \
LOCAL_MODULE := bluetoothd
LOCAL_REQUIRED_MODULES := libbluetooth
diff --git a/android/bt_adapter.c b/android/bt_adapter.c
index e21d50c..6b758bf 100644
--- a/android/bt_adapter.c
+++ b/android/bt_adapter.c
@@ -45,8 +45,6 @@ void adapter_start(struct bt_adapter *adapter)
/* TODO: CB: report scan mode */
- /* TODO: SDP start here */
-
/* TODO: CB: report state on */
}
diff --git a/android/main.c b/android/main.c
index 3580ac7..7968ed0 100644
--- a/android/main.c
+++ b/android/main.c
@@ -36,6 +36,8 @@
#include <glib.h>
#include "log.h"
+#include "hcid.h"
+#include "sdpd.h"
#include "lib/bluetooth.h"
#include "lib/mgmt.h"
@@ -43,12 +45,36 @@
#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;
+static int sdp_start(void)
+{
+ DBG("");
+
+ /* TODO: add logic */
+
+ /* sdpd-server use these settings */
+ memset(&main_opts, 0, sizeof(main_opts));
+
+ /* Use params: mtu = 0, flags = 0 */
+ return start_sdp_server(0, 0);
+}
+
+static void sdp_stop(void)
+{
+ DBG("");
+
+ /* TODO: add logic */
+
+ stop_sdp_server();
+}
+
static gboolean quit_eventloop(gpointer user_data)
{
g_main_loop_quit(event_loop);
@@ -287,11 +313,13 @@ int main(int argc, char *argv[])
sigaction(SIGTERM, &sa, NULL);
init_mgmt_interface();
+ sdp_start();
DBG("Entering main loop");
g_main_loop_run(event_loop);
+ sdp_stop();
cleanup_mgmt_interface();
g_main_loop_unref(event_loop);
--
1.7.10.4
^ permalink raw reply related
* [PATCHv1 11/15] android: Add cap to bind to port < 1024
From: Andrei Emeltchenko @ 2013-10-07 7:38 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1381131496-9417-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 | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 4 ++++
2 files changed, 76 insertions(+)
diff --git a/android/main.c b/android/main.c
index 7968ed0..dab54ce 100644
--- a/android/main.c
+++ b/android/main.c
@@ -32,6 +32,22 @@
#include <stdlib.h>
#include <stdbool.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)
+#include <sys/capability.h>
+#endif
+
+#if defined(__ANDROID_API__)
+#include <private/android_filesystem_config.h>
+#endif
#include <glib.h>
@@ -279,6 +295,59 @@ 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;
+#if defined(__ANDROID_API__)
+ gid_t groups[] = {AID_NET_BT, AID_NET_BT_ADMIN, AID_BLUETOOTH,
+ AID_NET_ADMIN};
+#endif
+
+ DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
+
+ header.version = _LINUX_CAPABILITY_VERSION;
+
+ prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+
+#if defined(__ANDROID_API__)
+ if (setgid(AID_BLUETOOTH) < 0)
+ warn("%s: setgid(): %s", __func__, strerror(errno));
+
+ if (setuid(AID_BLUETOOTH) < 0)
+ warn("%s: setuid(): %s", __func__, strerror(errno));
+#endif
+
+ 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 defined(__ANDROID_API__)
+ if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) < 0)
+ warn("%s: setgroups: %s", __func__, strerror(errno));
+#endif
+ 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());
+
+ return true;
+}
+
int main(int argc, char *argv[])
{
GOptionContext *context;
@@ -312,6 +381,9 @@ int main(int argc, char *argv[])
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
+ if (android_set_aid_and_cap() == false)
+ exit(EXIT_FAILURE);
+
init_mgmt_interface();
sdp_start();
diff --git a/configure.ac b/configure.ac
index 7b1f64a..5406434 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 "${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
* [PATCHv1 12/15] android: Implement read_info_complete callback
From: Andrei Emeltchenko @ 2013-10-07 7:38 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1381131496-9417-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 | 102 +++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 90 insertions(+), 12 deletions(-)
diff --git a/android/main.c b/android/main.c
index dab54ce..3a63eb9 100644
--- a/android/main.c
+++ b/android/main.c
@@ -54,6 +54,7 @@
#include "log.h"
#include "hcid.h"
#include "sdpd.h"
+#include "bt_adapter.h"
#include "lib/bluetooth.h"
#include "lib/mgmt.h"
@@ -69,6 +70,8 @@ static struct mgmt *mgmt_if = NULL;
static uint8_t mgmt_version = 0;
static uint8_t mgmt_revision = 0;
+struct bt_adapter *default_adapter = NULL;
+
static int sdp_start(void)
{
DBG("");
@@ -118,34 +121,109 @@ 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;
+
+ DBG("");
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Failed to read info for index %u: %s (0x%02x)",
+ default_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",
+ default_adapter->dev_id);
+ goto failed;
+ }
+
+ /* Store adapter information */
+ bacpy(&default_adapter->bdaddr, &rp->bdaddr);
+ default_adapter->dev_class = rp->dev_class[0] |
+ (rp->dev_class[1] << 8) |
+ (rp->dev_class[2] << 16);
+ default_adapter->name = g_strdup((const char *) rp->name);
+ default_adapter->short_name = g_strdup((const char *) rp->short_name);
+
+ default_adapter->supported_settings = btohs(rp->supported_settings);
+ default_adapter->current_settings = btohs(rp->current_settings);
+
+ /* TODO: Register all event notification handlers */
+
+ if (default_adapter->current_settings & MGMT_SETTING_POWERED)
+ adapter_start(default_adapter);
+
+ /* dummy link keys loading */
+ load_link_keys(default_adapter, NULL);
+
+ return;
+
+failed:
+ default_adapter = NULL;
+}
static void mgmt_index_added_event(uint16_t index, uint16_t length,
const void *param, void *user_data)
{
info("%s: index %u", __func__, index);
+ if (default_adapter == NULL) {
+ DBG("skip event for index %d", index);
+ return;
+ }
+
+ default_adapter = bt_adapter_new(index, mgmt_if);
+ if (default_adapter == NULL) {
+ error("Unable to create new adapter for index %u", index);
+ return;
+ }
+
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, 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,
--
1.7.10.4
^ permalink raw reply related
* [PATCHv1 13/15] android: Handle mgmt changed events
From: Andrei Emeltchenko @ 2013-10-07 7:38 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1381131496-9417-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 | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 154 insertions(+)
diff --git a/android/main.c b/android/main.c
index 3a63eb9..2cc4efc 100644
--- a/android/main.c
+++ b/android/main.c
@@ -127,6 +127,159 @@ 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 (adapter != default_adapter) {
+ error("Wrong adapter %p", adapter);
+ 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;
+ }
+
+ if (adapter != default_adapter) {
+ error("Wrong adapter %p", adapter);
+ 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;
+ }
+
+ if (adapter != default_adapter) {
+ error("Wrong adapter %p", adapter);
+ 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, 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;
@@ -188,6 +341,7 @@ static void read_info_complete(uint8_t status, uint16_t length,
default_adapter->current_settings = btohs(rp->current_settings);
/* TODO: Register all event notification handlers */
+ register_mgmt_handlers(default_adapter);
if (default_adapter->current_settings & MGMT_SETTING_POWERED)
adapter_start(default_adapter);
--
1.7.10.4
^ permalink raw reply related
* [PATCHv1 14/15] android: Add makefile for hciconfig
From: Andrei Emeltchenko @ 2013-10-07 7:38 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1381131496-9417-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
android/Android.mk | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/android/Android.mk b/android/Android.mk
index e7a70d0..09c4579 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -123,3 +123,37 @@ $(foreach file,$(lib_headers), $(shell ln -sf ../$(file) $(LOCAL_PATH)/../lib/bl
LOCAL_MODULE := libbluetooth
include $(BUILD_SHARED_LIBRARY)
+
+#
+# hciconfig
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ ../tools/csr.c \
+ ../tools/csr_h4.c \
+ ../tools/hciconfig.c \
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/../lib \
+ $(LOCAL_PATH)/../src \
+
+LOCAL_C_INCLUDES += \
+ $(call include-path-for, glib) \
+ $(call include-path-for, glib)/glib \
+
+LOCAL_SHARED_LIBRARIES := \
+ libbluetooth
+
+# to suppress the "pointer of type 'void *' used in arithmetic" warning
+LOCAL_CFLAGS := -Wno-pointer-arith
+
+# to suppress the "warning: missing initializer near initialization.." warning
+LOCAL_CFLAGS += -Wno-missing-field-initializers
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng
+LOCAL_MODULE := hciconfig
+
+include $(BUILD_EXECUTABLE)
--
1.7.10.4
^ permalink raw reply related
* [PATCHv1 15/15] android: Add makefile for hcitool
From: Andrei Emeltchenko @ 2013-10-07 7:38 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1381131496-9417-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
android/Android.mk | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/android/Android.mk b/android/Android.mk
index 09c4579..5798749 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -157,3 +157,41 @@ LOCAL_MODULE_TAGS := eng
LOCAL_MODULE := hciconfig
include $(BUILD_EXECUTABLE)
+
+#
+# hcitool
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ ../tools/hcitool.c \
+ ../src/oui.c \
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/../lib \
+ $(LOCAL_PATH)/../src \
+
+LOCAL_C_INCLUDES += \
+ $(call include-path-for, glib) \
+ $(call include-path-for, glib)/glib \
+
+LOCAL_CFLAGS := \
+ -DSTORAGEDIR=\"/tmp\" \
+ -DVERSION=\"$(BLUEZ_VERSION)\"
+
+# to suppress the "pointer of type 'void *' used in arithmetic" warning
+LOCAL_CFLAGS += -Wno-pointer-arith
+
+# to suppress the "warning: missing initializer near initialization.." warning
+LOCAL_CFLAGS += -Wno-missing-field-initializers
+
+LOCAL_SHARED_LIBRARIES := \
+ libbluetooth \
+ libglib \
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng
+LOCAL_MODULE := hcitool
+
+include $(BUILD_EXECUTABLE)
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH] Bluetooth: Extra sanity check for AMP discover response
From: Andrei Emeltchenko @ 2013-10-07 7:50 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1380999376-9045-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Sat, Oct 05, 2013 at 11:56:16AM -0700, Marcel Holtmann wrote:
> Just in case the Bluetooth standard introduces a third device type,
> make sure that we only include AMP controllers in the AMP discover
> response.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> net/bluetooth/a2mp.c | 18 +++++++-----------
> 1 file changed, 7 insertions(+), 11 deletions(-)
>
> diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
> index 529789d..5278a65 100644
> --- a/net/bluetooth/a2mp.c
> +++ b/net/bluetooth/a2mp.c
> @@ -78,24 +78,20 @@ u8 __next_ident(struct amp_mgr *mgr)
> /* hci_dev_list shall be locked */
> static void __a2mp_add_cl(struct amp_mgr *mgr, struct a2mp_cl *cl)
> {
> - int i = 0;
> struct hci_dev *hdev;
> + int i = 1;
>
> cl[0].id = AMP_ID_BREDR;
> cl[0].type = AMP_TYPE_BREDR;
> cl[0].status = AMP_STATUS_BLUETOOTH_ONLY;
>
> list_for_each_entry(hdev, &hci_dev_list, list) {
> - /* Iterate through AMP controllers */
> - if (hdev->dev_type != HCI_AMP)
> - continue;
> -
> - /* Starting from second entry */
> - ++i;
> -
> - cl[i].id = hdev->id;
> - cl[i].type = hdev->amp_type;
> - cl[i].status = hdev->amp_status;
> + if (hdev->dev_type == HCI_AMP) {
> + cl[i].id = hdev->id;
> + cl[i].type = hdev->amp_type;
> + cl[i].status = hdev->amp_status;
> + i++;
> + }
I wonder did it make sense to merge 3 patches which touches this small
function together?
Best regards
Andrei Emeltchenko
^ permalink raw reply
* Re: [PATCH 1/3] Bluetooth: Power off AMP controllers after setup phase
From: Johan Hedberg @ 2013-10-07 8:14 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1381130767-42488-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Mon, Oct 07, 2013, Marcel Holtmann wrote:
> Even AMP controllers should be powered off after the setup phase. It
> is not a good idea to keep AMP controllers powered on all the time
> if they are not in use.
>
> Power on of the AMP controller can either be done manually via
> command line commands or directly via A2MP. Especially since there
> is an indication in A2MP for powered down controllers that can
> be activated.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> net/bluetooth/hci_core.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
All patches in this set have been applied to bluetooth-next. Thanks.
Johan
^ permalink raw reply
* [PATCH] Bluetooth: Read supported features and commands on AMP controllers
From: Marcel Holtmann @ 2013-10-07 9:31 UTC (permalink / raw)
To: linux-bluetooth
The commands for reading supported features and commands are both
supported by AMP controllers. Issue them during controller init
phase so their values are known.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/hci_core.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 3572611..99f83ab 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -307,6 +307,12 @@ static void amp_init(struct hci_request *req)
/* Read Local Version */
hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
+ /* Read Local Supported Commands */
+ hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
+
+ /* Read Local Supported Features */
+ hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
+
/* Read Local AMP Info */
hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
--
1.8.3.1
^ permalink raw reply related
* [PATCH 1/2] Bluetooth: Read location data on AMP controller init
From: Marcel Holtmann @ 2013-10-07 10:55 UTC (permalink / raw)
To: linux-bluetooth
When initializing an AMP controller, read its current known location
data so that it can be analyzed later on.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci.h | 2 ++
net/bluetooth/hci_core.c | 3 +++
2 files changed, 5 insertions(+)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 3616ea7..c8a91cb 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -851,6 +851,8 @@ struct hci_rp_read_inq_rsp_tx_power {
#define HCI_OP_SET_EVENT_MASK_PAGE_2 0x0c63
+#define HCI_OP_READ_LOCATION_DATA 0x0c64
+
#define HCI_OP_READ_FLOW_CONTROL_MODE 0x0c66
struct hci_rp_read_flow_control_mode {
__u8 status;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 99f83ab..967739c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -318,6 +318,9 @@ static void amp_init(struct hci_request *req)
/* Read Data Blk size */
hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
+
+ /* Read Location Data */
+ hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
}
static void hci_init1_req(struct hci_request *req, unsigned long opt)
--
1.8.3.1
^ permalink raw reply related
* [PATCH 2/2] Bluetooth: Read flow control mode on AMP controller init
From: Marcel Holtmann @ 2013-10-07 10:55 UTC (permalink / raw)
To: linux-bluetooth
When initializing an AMP controller, read its current flow control
mode so that the correct value is used.
The AMP controller defaults to block based flow control and this
extra command is just to double check.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/hci_core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 967739c..0c636ba 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -319,6 +319,9 @@ static void amp_init(struct hci_request *req)
/* Read Data Blk size */
hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
+ /* Read Flow Control Mode */
+ hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL);
+
/* Read Location Data */
hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
}
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCHv1 05/15] android: Start Android Bluetooth daemon
From: Szymon Janc @ 2013-10-07 12:09 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1381131496-9417-6-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Monday 07 of October 2013 10:38:06 Andrei Emeltchenko wrote:
> 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 00f3e8d..f8139a7 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 "btd"
Shouldn't this be 'bluetoothd'?
Service name can be different than binary but I think we should keep it same
to avoid confusion.
> +
> 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 > PROPERTY_KEY_MAX - 1) {
> + ALOGD("Service name '%s' is too long", service_name);
> + return false;
> + }
> +
> + if (property_get(name, val, NULL)) {
Maybe pass "init.svc."ANDROID_BLUEZ directly to property_get()?
> + 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 strcmp(profile, str) == 0;
> @@ -50,7 +98,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;
> + }
bt_hal_cbacks should be set back to NULL here.
>
> return BT_STATUS_UNSUPPORTED;
> }
>
--
BR
Szymon Janc
^ permalink raw reply
* Re: [PATCHv1 11/15] android: Add cap to bind to port < 1024
From: Szymon Janc @ 2013-10-07 12:14 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1381131496-9417-12-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> For SDP server we need to bind to lower port, acquire this capability.
> ---
> android/main.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> configure.ac | 4 ++++
> 2 files changed, 76 insertions(+)
>
> diff --git a/android/main.c b/android/main.c
> index 7968ed0..dab54ce 100644
> --- a/android/main.c
> +++ b/android/main.c
> @@ -32,6 +32,22 @@
> #include <stdlib.h>
> #include <stdbool.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)
> +#include <sys/capability.h>
> +#endif
> +
> +#if defined(__ANDROID_API__)
> +#include <private/android_filesystem_config.h>
> +#endif
>
> #include <glib.h>
>
> @@ -279,6 +295,59 @@ static void cleanup_mgmt_interface(void)
> mgmt_if = NULL;
> }
>
> +static bool android_set_aid_and_cap()
Missing void in ().
> +{
> + struct __user_cap_header_struct header;
> + struct __user_cap_data_struct cap;
> +#if defined(__ANDROID_API__)
> + gid_t groups[] = {AID_NET_BT, AID_NET_BT_ADMIN, AID_BLUETOOTH,
> + AID_NET_ADMIN};
> +#endif
> +
> + DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
> +
> + header.version = _LINUX_CAPABILITY_VERSION;
> +
> + prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
> +
> +#if defined(__ANDROID_API__)
> + if (setgid(AID_BLUETOOTH) < 0)
> + warn("%s: setgid(): %s", __func__, strerror(errno));
> +
> + if (setuid(AID_BLUETOOTH) < 0)
> + warn("%s: setuid(): %s", __func__, strerror(errno));
> +#endif
> +
> + 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 defined(__ANDROID_API__)
> + if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) < 0)
> + warn("%s: setgroups: %s", __func__, strerror(errno));
> +#endif
> + 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());
> +
> + return true;
> +}
> +
> int main(int argc, char *argv[])
> {
> GOptionContext *context;
> @@ -312,6 +381,9 @@ int main(int argc, char *argv[])
> sigaction(SIGINT, &sa, NULL);
> sigaction(SIGTERM, &sa, NULL);
>
> + if (android_set_aid_and_cap() == false)
> + exit(EXIT_FAILURE);
> +
> init_mgmt_interface();
> sdp_start();
>
> diff --git a/configure.ac b/configure.ac
> index 7b1f64a..5406434 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 "${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)
>
--
BR
Szymon Janc
^ permalink raw reply
* Re: [PATCHv1 12/15] android: Implement read_info_complete callback
From: Andrei Emeltchenko @ 2013-10-07 12:26 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1381131496-9417-13-git-send-email-Andrei.Emeltchenko.news@gmail.com>
On Mon, Oct 07, 2013 at 10:38:13AM +0300, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Handle read info complete callback from mgmt interface.
> ---
> android/main.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++-------
> 1 file changed, 90 insertions(+), 12 deletions(-)
>
> diff --git a/android/main.c b/android/main.c
> index dab54ce..3a63eb9 100644
> --- a/android/main.c
> +++ b/android/main.c
> @@ -54,6 +54,7 @@
> #include "log.h"
> #include "hcid.h"
> #include "sdpd.h"
> +#include "bt_adapter.h"
>
> #include "lib/bluetooth.h"
> #include "lib/mgmt.h"
> @@ -69,6 +70,8 @@ static struct mgmt *mgmt_if = NULL;
> static uint8_t mgmt_version = 0;
> static uint8_t mgmt_revision = 0;
>
> +struct bt_adapter *default_adapter = NULL;
> +
> static int sdp_start(void)
> {
> DBG("");
> @@ -118,34 +121,109 @@ 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;
> +
> + DBG("");
> +
> + if (status != MGMT_STATUS_SUCCESS) {
> + error("Failed to read info for index %u: %s (0x%02x)",
> + default_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",
> + default_adapter->dev_id);
> + goto failed;
> + }
> +
> + /* Store adapter information */
> + bacpy(&default_adapter->bdaddr, &rp->bdaddr);
> + default_adapter->dev_class = rp->dev_class[0] |
> + (rp->dev_class[1] << 8) |
> + (rp->dev_class[2] << 16);
> + default_adapter->name = g_strdup((const char *) rp->name);
> + default_adapter->short_name = g_strdup((const char *) rp->short_name);
> +
> + default_adapter->supported_settings = btohs(rp->supported_settings);
> + default_adapter->current_settings = btohs(rp->current_settings);
> +
> + /* TODO: Register all event notification handlers */
> +
> + if (default_adapter->current_settings & MGMT_SETTING_POWERED)
> + adapter_start(default_adapter);
> +
> + /* dummy link keys loading */
> + load_link_keys(default_adapter, NULL);
> +
> + return;
> +
> +failed:
> + default_adapter = NULL;
> +}
>
> static void mgmt_index_added_event(uint16_t index, uint16_t length,
> const void *param, void *user_data)
> {
> info("%s: index %u", __func__, index);
>
> + if (default_adapter == NULL) {
sorry, this should be != NULL
I will send updated version soon.
Best regards
Andrei Emeltchenko
^ permalink raw reply
* Re: [PATCH] Bluetooth: Read supported features and commands on AMP controllers
From: Johan Hedberg @ 2013-10-07 12:53 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1381138299-49639-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Mon, Oct 07, 2013, Marcel Holtmann wrote:
> The commands for reading supported features and commands are both
> supported by AMP controllers. Issue them during controller init
> phase so their values are known.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> net/bluetooth/hci_core.c | 6 ++++++
> 1 file changed, 6 insertions(+)
Applied to bluetooth-next. Thanks.
Johan
^ permalink raw reply
* [RFC 0/2] Basic code for HAL API
From: Andrei Emeltchenko @ 2013-10-07 13:37 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Please comment what is the way to split code between common shared part
and HAL and daemon related.
Currently hal_msg.c is used by "server" - BlueZ daemon and hal_msg_client.c is used
by "client" - Android HAL.
Andrei Emeltchenko (2):
android: Implement basic HAL server
android: Add HAL message helpers
Makefile.android | 3 +-
android/Android.mk | 2 +
android/hal_msg.c | 267 ++++++++++++++++++++++++++++++++++++++++++++++
android/hal_msg.h | 5 +
android/hal_msg_client.c | 123 +++++++++++++++++++++
android/hal_msg_client.h | 25 +++++
android/main.c | 10 ++
7 files changed, 434 insertions(+), 1 deletion(-)
create mode 100644 android/hal_msg.c
create mode 100644 android/hal_msg_client.c
create mode 100644 android/hal_msg_client.h
--
1.7.10.4
^ permalink raw reply
* [RFC 1/2] android: Implement basic HAL server
From: Andrei Emeltchenko @ 2013-10-07 13:37 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1381153036-12631-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 | 267 ++++++++++++++++++++++++++++++++++++++++++++++++++++
android/hal_msg.h | 5 +
android/main.c | 10 ++
5 files changed, 285 insertions(+), 1 deletion(-)
create mode 100644 android/hal_msg.c
diff --git a/Makefile.android b/Makefile.android
index d576b52..4da136b 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -6,7 +6,8 @@ android_bluetoothd_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_bluetoothd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
endif
diff --git a/android/Android.mk b/android/Android.mk
index 5798749..cc5c024 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -18,6 +18,7 @@ LOCAL_SRC_FILES := \
../src/shared/mgmt.c \
../src/shared/util.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..fb7b7a3
--- /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 c6bc883..63551c3 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;
@@ -47,6 +50,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 bfd30d5..8a58371 100644
--- a/android/main.c
+++ b/android/main.c
@@ -60,6 +60,14 @@
#include "lib/mgmt.h"
#include "src/shared/mgmt.h"
+#include "hal_msg.h"
+
+#if defined(__ANDROID_API__)
+#define BT_HAL_SOCKET "/tmp/bt_hal"
+#else
+#define BT_HAL_SOCKET "/var/run/bt_hal"
+#endif
+
#define SHUTDOWN_GRACE_SECONDS 10
struct main_opts main_opts;
@@ -617,11 +625,13 @@ int main(int argc, char *argv[])
init_mgmt_interface();
sdp_start();
+ start_hal_srv(BT_HAL_SOCKET);
DBG("Entering main loop");
g_main_loop_run(event_loop);
+ stop_hal_srv();
sdp_stop();
cleanup_mgmt_interface();
g_main_loop_unref(event_loop);
--
1.7.10.4
^ permalink raw reply related
* [RFC 2/2] android: Add HAL message helpers
From: Andrei Emeltchenko @ 2013-10-07 13:37 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1381153036-12631-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 | 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 cc5c024..3000feb 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -62,6 +62,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
hal_bluetooth.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..fa19599
--- /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_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 0/2] Initial code for PAN and HID HALs
From: Andrei Emeltchenko @ 2013-10-07 13:39 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Slightly modified code from Frederic Danis.
Frederic Danis (2):
android: Add HID Host skeleton
android: Add PAN skeleton
android/Android.mk | 2 +
android/hal.h | 2 +
android/hal_bluetooth.c | 8 ++
android/hal_hidhost.c | 232 +++++++++++++++++++++++++++++++++++++++++++++++
android/hal_pan.c | 130 ++++++++++++++++++++++++++
5 files changed, 374 insertions(+)
create mode 100644 android/hal_hidhost.c
create mode 100644 android/hal_pan.c
--
1.7.10.4
^ permalink raw reply
* [RFC 1/2] android: Add HID Host skeleton
From: Andrei Emeltchenko @ 2013-10-07 13:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1381153158-13207-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Frederic Danis <frederic.danis@linux.intel.com>
---
android/Android.mk | 1 +
android/hal.h | 1 +
android/hal_bluetooth.c | 4 +
android/hal_hidhost.c | 232 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 238 insertions(+)
create mode 100644 android/hal_hidhost.c
diff --git a/android/Android.mk b/android/Android.mk
index cb156d3..d1cd2bc 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -64,6 +64,7 @@ LOCAL_SRC_FILES := \
hal_cb_thread.c \
hal_bt_sock.c \
hal_msg_client.c \
+ hal_hidhost.c \
LOCAL_SHARED_LIBRARIES := \
libcutils \
diff --git a/android/hal.h b/android/hal.h
index 40fbf03..be69339 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -16,3 +16,4 @@
*/
btsock_interface_t *bt_get_sock_interface(void);
+bthh_interface_t *bt_get_hidhost_interface(void);
diff --git a/android/hal_bluetooth.c b/android/hal_bluetooth.c
index f8139a7..46cc794 100644
--- a/android/hal_bluetooth.c
+++ b/android/hal_bluetooth.c
@@ -22,6 +22,7 @@
#include <hardware/bluetooth.h>
#include <hardware/bt_sock.h>
+#include <hardware/bt_hh.h>
#include <cutils/sockets.h>
#include <cutils/properties.h>
@@ -309,6 +310,9 @@ static const void *get_profile_interface(const char *profile_id)
if (is_profile(profile_id, BT_PROFILE_SOCKETS_ID))
return bt_get_sock_interface();
+ if (is_profile(profile_id, BT_PROFILE_HIDHOST_ID))
+ return bt_get_hidhost_interface();
+
return NULL;
}
diff --git a/android/hal_hidhost.c b/android/hal_hidhost.c
new file mode 100644
index 0000000..7340b11
--- /dev/null
+++ b/android/hal_hidhost.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdbool.h>
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_hh.h>
+
+#define LOG_TAG "BlueZ"
+#include <cutils/log.h>
+
+bthh_callbacks_t *bt_hh_cbacks;
+
+static bool interface_ready(void)
+{
+ return bt_hh_cbacks != NULL;
+}
+
+static bt_status_t bt_hidhost_connect(bt_bdaddr_t *bd_addr)
+{
+ ALOGI(__func__);
+
+ /* sanity check */
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (bd_addr == NULL) {
+ ALOGE("invalid parameters, bd_addr:%p", bd_addr);
+ return BT_STATUS_PARM_INVALID;
+ }
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t bt_hidhost_disconnect(bt_bdaddr_t *bd_addr)
+{
+ ALOGI(__func__);
+
+ /* sanity check */
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (bd_addr == NULL) {
+ ALOGE("invalid parameters, bd_addr:%p", bd_addr);
+ return BT_STATUS_PARM_INVALID;
+ }
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t bt_hidhost_virtual_unplug(bt_bdaddr_t *bd_addr)
+{
+ ALOGI(__func__);
+
+ /* sanity check */
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (bd_addr == NULL) {
+ ALOGE("invalid parameters, bd_addr:%p", bd_addr);
+ return BT_STATUS_PARM_INVALID;
+ }
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t bt_hidhost_set_info(bt_bdaddr_t *bd_addr,
+ bthh_hid_info_t hid_info)
+{
+ ALOGI(__func__);
+
+ /* sanity check */
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (bd_addr == NULL) {
+ ALOGE("invalid parameters, bd_addr:%p", bd_addr);
+ return BT_STATUS_PARM_INVALID;
+ }
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t bt_hidhost_get_protocol(bt_bdaddr_t *bd_addr,
+ bthh_protocol_mode_t protocolMode)
+{
+ ALOGI(__func__);
+
+ /* sanity check */
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (bd_addr == NULL) {
+ ALOGE("invalid parameters, bd_addr:%p", bd_addr);
+ return BT_STATUS_PARM_INVALID;
+ }
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t bt_hidhost_set_protocol(bt_bdaddr_t *bd_addr,
+ bthh_protocol_mode_t protocolMode)
+{
+ ALOGI(__func__);
+
+ /* sanity check */
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (bd_addr == NULL) {
+ ALOGE("invalid parameters, bd_addr:%p", bd_addr);
+ return BT_STATUS_PARM_INVALID;
+ }
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t bt_hidhost_get_report(bt_bdaddr_t *bd_addr,
+ bthh_report_type_t reportType,
+ uint8_t reportId,
+ int bufferSize)
+{
+ ALOGI(__func__);
+
+ /* sanity check */
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (bd_addr == NULL) {
+ ALOGE("invalid parameters, bd_addr:%p", bd_addr);
+ return BT_STATUS_PARM_INVALID;
+ }
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t bt_hidhost_set_report(bt_bdaddr_t *bd_addr,
+ bthh_report_type_t reportType,
+ char *report)
+{
+ ALOGI(__func__);
+
+ /* sanity check */
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (bd_addr == NULL || report == NULL) {
+ ALOGE("invalid parameters, bd_addr:%p", bd_addr);
+ return BT_STATUS_PARM_INVALID;
+ }
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t bt_hidhost_send_data(bt_bdaddr_t *bd_addr, char *data)
+{
+ ALOGI(__func__);
+
+ /* sanity check */
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (bd_addr == NULL || data == NULL) {
+ ALOGE("invalid parameters, bd_addr:%p", bd_addr);
+ return BT_STATUS_PARM_INVALID;
+ }
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t bt_hidhost_init(bthh_callbacks_t *callbacks)
+{
+ ALOGI(__func__);
+
+ /* store reference to user callbacks */
+ bt_hh_cbacks = callbacks;
+
+ /* TODO: start HID Host thread */
+
+ /* TODO: enable service */
+
+ return BT_STATUS_SUCCESS;
+}
+
+static void bt_hidhost_cleanup(void)
+{
+ ALOGI(__func__);
+
+ /* sanity check */
+ if (interface_ready() == false)
+ return;
+
+ /* TODO: disable service */
+
+ /* TODO: stop HID Host thread */
+
+ bt_hh_cbacks = NULL;
+}
+
+static bthh_interface_t bt_hidhost_if = {
+ sizeof(bt_hidhost_if),
+ bt_hidhost_init,
+ bt_hidhost_connect,
+ bt_hidhost_disconnect,
+ bt_hidhost_virtual_unplug,
+ bt_hidhost_set_info,
+ bt_hidhost_get_protocol,
+ bt_hidhost_set_protocol,
+ bt_hidhost_get_report,
+ bt_hidhost_set_report,
+ bt_hidhost_send_data,
+ bt_hidhost_cleanup
+};
+
+bthh_interface_t *bt_get_hidhost_interface(void)
+{
+ return &bt_hidhost_if;
+}
--
1.7.10.4
^ permalink raw reply related
* [RFC 2/2] android: Add PAN skeleton
From: Andrei Emeltchenko @ 2013-10-07 13:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1381153158-13207-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Frederic Danis <frederic.danis@linux.intel.com>
---
android/Android.mk | 1 +
android/hal.h | 1 +
android/hal_bluetooth.c | 4 ++
android/hal_pan.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 136 insertions(+)
create mode 100644 android/hal_pan.c
diff --git a/android/Android.mk b/android/Android.mk
index d1cd2bc..453dcd3 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -65,6 +65,7 @@ LOCAL_SRC_FILES := \
hal_bt_sock.c \
hal_msg_client.c \
hal_hidhost.c \
+ hal_pan.c \
LOCAL_SHARED_LIBRARIES := \
libcutils \
diff --git a/android/hal.h b/android/hal.h
index be69339..38b90b2 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -17,3 +17,4 @@
btsock_interface_t *bt_get_sock_interface(void);
bthh_interface_t *bt_get_hidhost_interface(void);
+btpan_interface_t *bt_get_pan_interface(void);
diff --git a/android/hal_bluetooth.c b/android/hal_bluetooth.c
index 46cc794..636c1fe 100644
--- a/android/hal_bluetooth.c
+++ b/android/hal_bluetooth.c
@@ -23,6 +23,7 @@
#include <hardware/bluetooth.h>
#include <hardware/bt_sock.h>
#include <hardware/bt_hh.h>
+#include <hardware/bt_pan.h>
#include <cutils/sockets.h>
#include <cutils/properties.h>
@@ -313,6 +314,9 @@ static const void *get_profile_interface(const char *profile_id)
if (is_profile(profile_id, BT_PROFILE_HIDHOST_ID))
return bt_get_hidhost_interface();
+ if (is_profile(profile_id, BT_PROFILE_PAN_ID))
+ return bt_get_pan_interface();
+
return NULL;
}
diff --git a/android/hal_pan.c b/android/hal_pan.c
new file mode 100644
index 0000000..064b086
--- /dev/null
+++ b/android/hal_pan.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdbool.h>
+
+#include <hardware/bluetooth.h>
+#include <hardware/bt_pan.h>
+
+#define LOG_TAG "BlueZ"
+#include <cutils/log.h>
+
+const btpan_callbacks_t *bt_pan_cbacks = NULL;
+
+static bool interface_ready(void)
+{
+ return bt_pan_cbacks != NULL;
+}
+
+static bt_status_t bt_pan_enable(int local_role)
+{
+ ALOGI(__func__);
+
+ /* sanity check */
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static int bt_pan_get_local_role(void)
+{
+ ALOGI(__func__);
+
+ /* sanity check */
+ if (interface_ready() == false)
+ return BTPAN_ROLE_NONE;
+
+ return BTPAN_ROLE_NONE;
+}
+
+static bt_status_t bt_pan_connect(const bt_bdaddr_t *bd_addr, int local_role,
+ int remote_role)
+{
+ ALOGI(__func__);
+
+ /* sanity check */
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (bd_addr == NULL) {
+ ALOGE("invalid parameters, bd_addr:%p", bd_addr);
+ return BT_STATUS_PARM_INVALID;
+ }
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t bt_pan_disconnect(const bt_bdaddr_t *bd_addr)
+{
+ ALOGI(__func__);
+
+ /* sanity check */
+ if (interface_ready() == false)
+ return BT_STATUS_NOT_READY;
+
+ if (bd_addr == NULL) {
+ ALOGE("invalid parameters, bd_addr:%p", bd_addr);
+ return BT_STATUS_PARM_INVALID;
+ }
+
+ return BT_STATUS_UNSUPPORTED;
+}
+
+static bt_status_t bt_pan_init(const btpan_callbacks_t *callbacks)
+{
+ ALOGI(__func__);
+
+ /* store reference to user callbacks */
+ bt_pan_cbacks = callbacks;
+
+ /* TODO: start HID Host thread */
+
+ /* TODO: enable service */
+
+ return BT_STATUS_SUCCESS;
+}
+
+static void bt_pan_cleanup()
+{
+ ALOGI(__func__);
+
+ /* sanity check */
+ if (interface_ready() == false)
+ return;
+
+ /* TODO: disable service */
+
+ /* TODO: stop PAN thread */
+
+ bt_pan_cbacks = NULL;
+}
+
+static btpan_interface_t bt_pan_if = {
+ sizeof(bt_pan_if),
+ bt_pan_init,
+ bt_pan_enable,
+ bt_pan_get_local_role,
+ bt_pan_connect,
+ bt_pan_disconnect,
+ bt_pan_cleanup
+};
+
+btpan_interface_t *bt_get_pan_interface()
+{
+ return &bt_pan_if;
+}
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH 1/2] Bluetooth: Read location data on AMP controller init
From: Johan Hedberg @ 2013-10-07 14:54 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1381143353-57149-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Mon, Oct 07, 2013, Marcel Holtmann wrote:
> When initializing an AMP controller, read its current known location
> data so that it can be analyzed later on.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> include/net/bluetooth/hci.h | 2 ++
> net/bluetooth/hci_core.c | 3 +++
> 2 files changed, 5 insertions(+)
Both patches in this set have been applied to bluetooth-next. Thanks.
Johan
^ permalink raw reply
* [PATCH] bluetooth: fix variable shadow warnings
From: Johannes Berg @ 2013-10-07 14:56 UTC (permalink / raw)
To: linux-wireless, linux-bluetooth; +Cc: Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
Sparse points out three places where variables are shadowed,
rename two of the variables and remove the duplicate third.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/bluetooth/hci_event.c | 12 +++++++-----
net/bluetooth/l2cap_sock.c | 2 +-
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 94aab73..b5a3736 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1291,9 +1291,11 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
goto unlock;
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
- struct hci_cp_auth_requested cp;
- cp.handle = __cpu_to_le16(conn->handle);
- hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
+ struct hci_cp_auth_requested auth_req;
+
+ auth_req.handle = __cpu_to_le16(conn->handle);
+ hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
+ sizeof(auth_req), &auth_req);
}
unlock:
@@ -3636,8 +3638,8 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
skb_pull(skb, HCI_EVENT_HDR_SIZE);
if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
- struct hci_command_hdr *hdr = (void *) hdev->sent_cmd->data;
- u16 opcode = __le16_to_cpu(hdr->opcode);
+ struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
+ u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
hci_req_cmd_complete(hdev, opcode, 0);
}
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 0098af8..f07e25d 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -683,7 +683,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
}
if (opt == BT_FLUSHABLE_OFF) {
- struct l2cap_conn *conn = chan->conn;
+ conn = chan->conn;
/* proceed further only when we have l2cap_conn and
No Flush support in the LM */
if (!conn || !lmp_no_flush_capable(conn->hcon->hdev)) {
--
1.8.4.rc3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox