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

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

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

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


^ permalink raw reply related

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

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

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

diff --git a/Makefile.android b/Makefile.android
index 3e6fec0..bf82928 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -3,7 +3,10 @@ if ANDROID_DAEMON
 noinst_PROGRAMS += android/bluezd
 
 android_bluezd_SOURCES = android/main.c src/log.c \
+				src/sdpd-database.c src/sdpd-server.c \
+				src/sdpd-service.c src/sdpd-request.c \
 				src/shared/util.h src/shared/util.c \
-				src/shared/mgmt.h src/shared/mgmt.c
-android_bluezd_LDADD = @GLIB_LIBS@
+				src/shared/mgmt.h src/shared/mgmt.c \
+				android/bt_adapter.h android/bt_adapter.c
+android_bluezd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
 endif
diff --git a/android/Android.mk b/android/Android.mk
index 36f8798..08e35e4 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -9,6 +9,11 @@ include $(CLEAR_VARS)
 LOCAL_SRC_FILES := \
 	log.c \
 	main.c \
+	bt_adapter.c \
+	../src/sdpd-database.c \
+	../src/sdpd-service.c \
+	../src/sdpd-request.c \
+	../src/sdpd-server.c \
 
 LOCAL_C_INCLUDES := \
 	$(call include-path-for, glib) \
@@ -24,6 +29,7 @@ LOCAL_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\"
 LOCAL_SHARED_LIBRARIES := \
 	libglib \
 	libbluez \
+	libbluetooth \
 
 LOCAL_MODULE := bluezd
 
diff --git a/android/bt_adapter.c b/android/bt_adapter.c
index 9f64839..42facb6 100644
--- a/android/bt_adapter.c
+++ b/android/bt_adapter.c
@@ -23,6 +23,7 @@
 
 #include "bt_adapter.h"
 #include "log.h"
+#include "main.h"
 #include "src/shared/mgmt.h"
 
 struct bt_device *bt_device_ref(struct bt_device *device)
@@ -118,7 +119,7 @@ void adapter_start(struct bt_adapter *adapter)
 
 	/* TODO: CB: report scan mode */
 
-	/* TODO: SDP start here */
+	sdp_start();
 
 	/* TODO: CB: report state on */
 }
@@ -126,4 +127,6 @@ void adapter_start(struct bt_adapter *adapter)
 void adapter_stop(struct bt_adapter *adapter)
 {
 	DBG("disabled %u", adapter->dev_id);
+
+	sdp_stop();
 }
diff --git a/android/main.c b/android/main.c
index 4792919..5fef095 100644
--- a/android/main.c
+++ b/android/main.c
@@ -36,6 +36,8 @@
 
 #include "log.h"
 #include "hcid.h"
+#include "sdpd.h"
+#include "main.h"
 
 #include "lib/bluetooth.h"
 #include "lib/mgmt.h"
@@ -43,12 +45,37 @@
 
 #define SHUTDOWN_GRACE_SECONDS 10
 
+struct main_opts main_opts;
+
 static GMainLoop *event_loop;
 static struct mgmt *mgmt_if = NULL;
 
 static uint8_t mgmt_version = 0;
 static uint8_t mgmt_revision = 0;
 
+GList *adapter_list = NULL;
+struct bt_adapter *default_adapter = NULL;
+
+int sdp_start(void)
+{
+	uint16_t mtu = 0;
+	uint32_t flags = 0;
+
+	DBG("");
+
+	/* sdpd-server use these settings */
+	memset(&main_opts, 0, sizeof(main_opts));
+
+	return start_sdp_server(mtu, flags);
+}
+
+void sdp_stop(void)
+{
+	DBG("");
+
+	stop_sdp_server();
+}
+
 void btd_exit(void)
 {
 	g_main_loop_quit(event_loop);
diff --git a/android/main.h b/android/main.h
new file mode 100644
index 0000000..6ecad14
--- /dev/null
+++ b/android/main.h
@@ -0,0 +1,25 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2013  Intel Corporation. All rights reserved.
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+int sdp_start(void);
+void sdp_stop(void);
-- 
1.7.10.4


^ permalink raw reply related

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

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

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

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


^ permalink raw reply related

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

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

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

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


^ permalink raw reply related

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

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

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

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


^ permalink raw reply related

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

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

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

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


^ permalink raw reply related

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

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

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

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


^ permalink raw reply related

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

Hi John,

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

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

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

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

	Gustavo

^ permalink raw reply

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

Hi Andrei,

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

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

return strcmp(profile, str) == 0;

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

^ permalink raw reply

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

Hi Andrei,

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

Why are you using GList instead of GSList above?

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

Same here.

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

^ permalink raw reply

* Re: [RFC 12/16] android: Add cap to bind to port < 1024
From: Anderson Lizardo @ 2013-09-27 17:17 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: BlueZ development
In-Reply-To: <1380291161-10232-13-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Fri, Sep 27, 2013 at 10:12 AM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> +/**
> + * Include <sys/capability.h> for host build and
> + * also for Android 4.3 when it is added to bionic
> + */
> +#if (defined(__ANDROID_API__) && (__ANDROID_API__ > 17)) || \
> +                                       !defined(__ANDROID_API__)

I think the line below is equivalent to the above but easier to read:

#if !defined(__ANDROID_API__) || (__ANDROID_API__ > 17)

> +static bool android_set_aid_and_cap()
> +{
> +       struct __user_cap_header_struct header;
> +       struct __user_cap_data_struct cap;
> +
> +       DBG("%s: pid %d uid %d gid %d", __func__, getpid(), getuid(), getgid());
> +
> +       header.version = _LINUX_CAPABILITY_VERSION;
> +       header.pid = getpid();
> +       if (capget(&header, &cap) < 0)
> +               error("%s: capget(): %s", __func__, strerror(errno));

It seems you need to "return false" above, otherwise "cap" may have
uninitialized data.

> +
> +       DBG("%s: Cap data 0x%x, 0x%x, 0x%x\n", __func__, cap.effective,
> +                                       cap.permitted, cap.inheritable);
> +
> +       prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
> +
> +       header.version = _LINUX_CAPABILITY_VERSION;
> +       header.pid = 0;
> +
> +       cap.effective = cap.permitted = cap.inheritable =
> +               1 << CAP_NET_RAW |
> +               1 << CAP_NET_ADMIN |
> +               1 << CAP_NET_BIND_SERVICE |
> +               1 << CAP_SYS_RAWIO |
> +               1 << CAP_SYS_NICE |
> +               1 << CAP_SETGID;
> +
> +       if (capset(&header, &cap)) {
> +               error("%s: capset(): %s", __func__, strerror(errno));
> +               return false;
> +       }
> +
> +       DBG("%s: capset(): Success", __func__);
> +       return true;
> +}
> +
>  int main(int argc, char *argv[])
>  {
>         GOptionContext *context;
> @@ -357,6 +407,9 @@ int main(int argc, char *argv[])
>         /* no need to keep parsed option in memory */
>         free_options();
>
> +       if (android_set_aid_and_cap() == false)
> +               exit(1);

IIRC Marcel suggested using EXIT_FAILURE and EXIT_SUCCESS instead of "exit(1)".

> +
>         init_mgmt_interface();
>
>         DBG("Entering main loop");

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

^ permalink raw reply

* Re: [RFC 12/16] android: Add cap to bind to port < 1024
From: Anderson Lizardo @ 2013-09-27 17:21 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: BlueZ development
In-Reply-To: <CAJdJm_O5Og9+3EfB3RgT1c2oF-B1rrQvRi3dGzpHZ3c0j=NXMg@mail.gmail.com>

Hi Andrei,

On Fri, Sep 27, 2013 at 1:17 PM, Anderson Lizardo
<anderson.lizardo@openbossa.org> wrote:
>> +       DBG("%s: capset(): Success", __func__);

The line above seems unnecessary (there are already error/debug
messages on every code path on this function and this one does not add
any extra information).

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

^ permalink raw reply

* Re: [RFC 15/16] android: Implement basic HAL server
From: Anderson Lizardo @ 2013-09-27 17:50 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: BlueZ development
In-Reply-To: <1380291161-10232-16-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Fri, Sep 27, 2013 at 10:12 AM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> +static gboolean io_session_event(GIOChannel *chan, GIOCondition cond,
> +                                                               gpointer data)
> +{
> +       struct hal_msg_hdr hdr;
> +       struct hal_msg_rsp rsp;
> +       uint8_t *buf;
> +       int sock, len, size;
> +       uint8_t status;
> +
> +       if (cond & G_IO_NVAL)
> +               return FALSE;
> +
> +       sock = g_io_channel_unix_get_fd(chan);
> +
> +       if (cond & (G_IO_HUP | G_IO_ERR)) {
> +               error("%s: error condition %d", __func__, cond);
> +               /* TODO: handle */
> +               return FALSE;
> +       }
> +
> +       len = recv(sock, &hdr, sizeof(hdr), MSG_PEEK);
> +       if (len != sizeof(hdr)) {
> +               /* TODO: handle */
> +               return FALSE;
> +       }
> +
> +       size = sizeof(hdr) + hdr.len;
> +       buf = malloc(size);
> +       if (!buf)
> +               return TRUE;
> +
> +       len = recv(sock, buf, size, 0);
> +       if (len != size) {
> +               /* TODO: handle */
> +               free(buf);
> +               return FALSE;
> +       }
> +
> +       status = process_hal_msg(buf, len);
> +
> +       free(buf);
> +
> +       memcpy(&rsp, &hdr, sizeof(hdr));
> +       rsp.hdr.len = sizeof(uint8_t);
> +       rsp.status = status;

You are not using "rsp" on this function (and not TODO comment explaining why).

> +       /* Since daemon would be run also on host we have to grant perms */
> +       chmod(sock_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH |
> +                                                               S_IWOTH);

If it is really necessary to have a world writable socket, better
explain in detail on the comment.

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

^ permalink raw reply

* Re: [RFC 14/16] android: Handle mgmt changed events
From: Anderson Lizardo @ 2013-09-27 17:59 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: BlueZ development
In-Reply-To: <1380291161-10232-15-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Fri, Sep 27, 2013 at 10:12 AM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> +static void mgmt_dev_class_changed_event(uint16_t index, uint16_t length,
> +                                       const void *param, void *user_data)
> +{
> +       struct bt_adapter *adapter = user_data;
> +       const struct mgmt_cod *rp = param;
> +       uint8_t appearance[3];
> +       uint32_t dev_class;
> +
> +       if (length < sizeof(*rp)) {
> +               error("Wrong size of class of device changed parameters");
> +               return;
> +       }
> +
> +       dev_class = rp->val[0] | (rp->val[1] << 8) | (rp->val[2] << 16);
> +
> +       if (dev_class == adapter->dev_class)
> +               return;
> +
> +       DBG("Class: 0x%06x", dev_class);
> +
> +       adapter->dev_class = dev_class;
> +
> +       /* TODO: Inform prop change: Class */
> +
> +       appearance[0] = rp->val[0];
> +       appearance[1] = rp->val[1] & 0x1f;  /* removes service class */
> +       appearance[2] = rp->val[2];
> +
> +       /* TODO: Gatt attrib set*/
> +       (void)appearance;

While it is clear this is incomplete code, doing things like above
just to silence the compiler looks bad. better simply remove the
"appearance" variable (adding it later when you implement GAP
Appearance) and replace it with a TODO or print the value with a
DBG().

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

^ permalink raw reply

* Re: [RFC 10/16] android: Add Android Makefile for libbluetooth
From: Anderson Lizardo @ 2013-09-27 18:01 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: BlueZ development
In-Reply-To: <1380291161-10232-11-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Fri, Sep 27, 2013 at 10:12 AM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> +# to suppress the "pointer of type 'void *' used in arithmetic" warning
> +LOCAL_CFLAGS += -Wno-pointer-arith
> +
> +# to suppress the "missing initializer near initialization" warning
> +LOCAL_CFLAGS += -Wno-missing-field-initializers
> +
> +# to suppress the "may be used uninitialized in this function" warning
> +LOCAL_CFLAGS += -Wno-maybe-uninitialized

I wonder why you are suppressing all those warnings. Do you plan to
re-enable them once the implementation is more complete?

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

^ permalink raw reply

* Re: pull request: bluetooth 2013-09-23
From: John W. Linville @ 2013-09-27 18:04 UTC (permalink / raw)
  To: Gustavo Padovan; +Cc: linux-wireless, linux-bluetooth, linux-kernel
In-Reply-To: <20130927152413.GC13211@joana>

On Fri, Sep 27, 2013 at 12:24:13PM -0300, Gustavo Padovan wrote:
> Hi John,
> 
> 2013-09-26 John W. Linville <linville@tuxdriver.com>:
> 
> > On Mon, Sep 23, 2013 at 06:00:49PM -0300, Gustavo Padovan wrote:

> > > The following changes since commit f4e1a4d3ecbb9e42bdf8e7869ee8a4ebfa27fb20:
> > > 
> > >   rt2800: change initialization sequence to fix system freeze (2013-09-09 14:44:34 -0400)
> > > 
> > > are available in the git repository at:
> > > 
> > >   git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth master
> > > 
> > > for you to fetch changes up to 5bcecf325378218a8e248bb6bcae96ec7362f8ef:
> > > 
> > >   Bluetooth: btusb: Add support for Belkin F8065bf (2013-09-23 17:44:25 -0300)
> > 
> > Pulling now...
> 
> Thanks for pulling. However as Stephen pointed out in the linux-next merge
> conflict email from today we have a style issue, a closing brace bad indented.
> This is from conflict resolution I made last week. I fixed it when merging
> bluetooth.git into bluetooth-next.git. 
> 
> So when pushing this to Dave could you please tell him about this issue and
> that the fix is already provided by bluetooth-next. Do you agree with this
> solution?

I fixed it in my merge for Dave -- I think that will be fine.

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

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

Hi Johan,

>>>>> If either one of the HCI_SETUP or HCI_USER_CHANNEL flags is set the
>>>>> device is not considered valid for mgmt. By having these checks inside
>>>>> the mgmt_valid_hdev function the a couple of places using it can be
>>>>> simplified.
>>>> 
>>>> I looked at doing this and decided not to. Reason was that the device
>>>> gets removed from mgmt anyway.
>>> 
>>> I'm not sure what significance you think "device gets removed from mgmt"
>>> has. All that is is a mgmt event saying that index has been removed. In
>>> addition to that we need to ensure that we don't send any more mgmt
>>> events for such devices and that we don't include such devices in the
>>> response to mgmt_read_index list.
>>> 
>>> These are the two places of the code that my patch simplifies, one is
>>> the check for whether to send a "power on" mgmt event and the other the
>>> response handling of read_index_list.
>> 
>> I have taken care of that part. It is done inside mgmt_control() and
>> in case of a controller in user channel mode it returns invalid index.
> 
> That's great, but it doesn't cover the read_index_list command which we
> were talking about here since the command doesn't target any specific
> controller (as per our mgmt-api.txt it has the value <non-controller> as
> the controller index). The command handler will in this case be invoked
> that that's where it'd be convenient to rely on mgmt_valid_hdev() for
> constructing the response.

the read index list command has a special check for user channel. As I said, I looked into this and opted against extending valid hdev macro since we only need it in a few specific cases. Adding it there resulted in simpler code then some magic macro that is used in more places.

When I wrote the patches for user channel this felt cleaner. I had patches for both ways, but decided to go this route.

>> For the events, I have no idea on how we would generate events if we
>> are not going through hci_event.c when the user channel is active.
> 
> The "powered on" event in question doesn't come from hci_event.c but
> from the hci_dev_open() function, so again this is not covered by the
> existing user channel checks.

How would you trigger a power on event. When user channel is active everything else is blocked. So every other operation will fail. That is taken care of.

In addition you can only activate user channel on a controller that is powered off. That was a conscious design decision. Keep it really simple. User channel mode is exclusive and exclusive to one user at a time.

Regards

Marcel


^ permalink raw reply

* [PATCH] Regression fix revert: "Bluetooth: Add missing reset_resume dev_pm_ops"
From: Hans de Goede @ 2013-09-28 13:25 UTC (permalink / raw)
  To: USB list, linux-bluetooth
  Cc: Hans de Goede, Shuah Khan, Gustavo Padovan, stable

Many btusb devices have 2 modes, a hid mode and a bluetooth hci mode. These
devices default to hid mode for BIOS use. This means that after having been
reset they will revert to HID mode, and are no longer usable as a HCI.

Therefor it is a very bad idea to just blindly make reset_resume point to
the regular resume handler. Note that the btusb driver has no clue how to
switch these devices from hid to hci mode, this is done in userspace through
udev rules, so the proper way to deal with this is to not have a reset-resume
handler and instead let the usb-system re-enumerate the device, and re-run
the udev rules.

I must also note, that the commit message for the commit causing this
problem has a very weak motivation for the change:

"Add missing reset_resume dev_pm_ops. Missing reset_resume results in the
following message after power management device test. This change sets
reset_resume to btusb_resume().

[ 2506.936134] btusb 1-1.5:1.0: no reset_resume for driver btusb?
[ 2506.936137] btusb 1-1.5:1.1: no reset_resume for driver btusb?"

Making a change solely to silence a warning while also changing important
behavior (normal resume handling versus re-enumeration) requires a commit
message with a proper explanation why it is safe to do so, which clearly lacks
here, and unsurprisingly it turns out to not be safe to make this change.

Reverting the commit in question fixes bt no longer working on my Dell
E6430 after a suspend/resume, and I believe it likely also fixes the
following bugs:
https://bugzilla.redhat.com/show_bug.cgi?id=988481
https://bugzilla.redhat.com/show_bug.cgi?id=1010649
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1213239

This reverts commit 502f769662978a2fe99d0caed5e53e3006107381.

Cc: Shuah Khan <shuah.kh@samsung.com>
Cc: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Cc: stable@vger.kernel.org
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/bluetooth/btusb.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 8e16f0a..d0b3d90 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1623,7 +1623,6 @@ static struct usb_driver btusb_driver = {
 #ifdef CONFIG_PM
 	.suspend	= btusb_suspend,
 	.resume		= btusb_resume,
-	.reset_resume	= btusb_resume,
 #endif
 	.id_table	= btusb_table,
 	.supports_autosuspend = 1,
-- 
1.8.3.1


^ permalink raw reply related

* Re: [PATCH 3/8] Bluetooth: Test for HCI_SETUP and HCI_USER_CHANNEL in mgmt_valid_hdev()
From: Johan Hedberg @ 2013-09-28 15:34 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <8F3048F3-3CE4-4257-912C-325A78F2DD6E@holtmann.org>

Hi Marcel,

On Sat, Sep 28, 2013, Marcel Holtmann wrote:
> >>>>> If either one of the HCI_SETUP or HCI_USER_CHANNEL flags is set the
> >>>>> device is not considered valid for mgmt. By having these checks inside
> >>>>> the mgmt_valid_hdev function the a couple of places using it can be
> >>>>> simplified.
> >>>> 
> >>>> I looked at doing this and decided not to. Reason was that the device
> >>>> gets removed from mgmt anyway.
> >>> 
> >>> I'm not sure what significance you think "device gets removed from mgmt"
> >>> has. All that is is a mgmt event saying that index has been removed. In
> >>> addition to that we need to ensure that we don't send any more mgmt
> >>> events for such devices and that we don't include such devices in the
> >>> response to mgmt_read_index list.
> >>> 
> >>> These are the two places of the code that my patch simplifies, one is
> >>> the check for whether to send a "power on" mgmt event and the other the
> >>> response handling of read_index_list.
> >> 
> >> I have taken care of that part. It is done inside mgmt_control() and
> >> in case of a controller in user channel mode it returns invalid index.
> > 
> > That's great, but it doesn't cover the read_index_list command which we
> > were talking about here since the command doesn't target any specific
> > controller (as per our mgmt-api.txt it has the value <non-controller> as
> > the controller index). The command handler will in this case be invoked
> > that that's where it'd be convenient to rely on mgmt_valid_hdev() for
> > constructing the response.
> 
> the read index list command has a special check for user channel. As I
> said, I looked into this and opted against extending valid hdev macro
> since we only need it in a few specific cases. Adding it there
> resulted in simpler code then some magic macro that is used in more
> places.
> 
> When I wrote the patches for user channel this felt cleaner. I had
> patches for both ways, but decided to go this route.

Fair enough.

> >> For the events, I have no idea on how we would generate events if we
> >> are not going through hci_event.c when the user channel is active.
> > 
> > The "powered on" event in question doesn't come from hci_event.c but
> > from the hci_dev_open() function, so again this is not covered by the
> > existing user channel checks.
> 
> How would you trigger a power on event. When user channel is active
> everything else is blocked. So every other operation will fail. That
> is taken care of.
> 
> In addition you can only activate user channel on a controller that is
> powered off. That was a conscious design decision. Keep it really
> simple. User channel mode is exclusive and exclusive to one user at a
> time.

Good point. The only hci_dev_open() call that comes to mind is the one
automatically triggered by the setup stage, but user space doesn't yet
know about the controller at that point.

Johan

^ permalink raw reply

* FW: [PATCH 1/2] obexd:Add Operation property to transfer properties
From: Zheng, Wu @ 2013-09-29  3:03 UTC (permalink / raw)
  To: Von Dentz, Luiz; +Cc: Hedberg, Johan, linux-bluetooth@vger.kernel.org
In-Reply-To: <1380008221-30501-1-git-send-email-wu.zheng@intel.com>

Hi Luiz,

Can you help review the patches? Thanks

Best Regards
Zheng Wu

>-----Original Message-----
>From: linux-bluetooth-owner@vger.kernel.org
>[mailto:linux-bluetooth-owner@vger.kernel.org] On Behalf Of Wu Zheng
>Sent: Tuesday, September 24, 2013 3:37 PM
>To: linux-bluetooth@vger.kernel.org
>Cc: Zheng, Wu
>Subject: [PATCH 1/2] obexd:Add Operation property to transfer properties
>
>Sometime, operation property is needed by the Bluetooth APP.
>Therefore, add the property to transfer properties
>---
> obexd/src/manager.c |   38
>++++++++++++++++++++++++++++++++++++++
> 1 files changed, 38 insertions(+), 0 deletions(-)
>
>diff --git a/obexd/src/manager.c b/obexd/src/manager.c index
>f64b7b9..96976ec 100644
>--- a/obexd/src/manager.c
>+++ b/obexd/src/manager.c
>@@ -35,6 +35,7 @@
>
> #include <btio/btio.h>
> #include <gobex/gobex.h>
>+#include <gobex/gobex-packet.h>
>
> #include "obexd.h"
> #include "obex.h"
>@@ -515,6 +516,41 @@ static gboolean transfer_get_filename(const
>GDBusPropertyTable *property,
> 	return TRUE;
> }
>
>+static gboolean transfer_operation_exists(const GDBusPropertyTable
>*property,
>+								void *data)
>+{
>+	struct obex_transfer *transfer = data;
>+	struct obex_session *session = transfer->session;
>+
>+	if (session->cmd == G_OBEX_OP_PUT &&
>+				session->size != OBJECT_SIZE_DELETE)
>+		return TRUE;
>+	else if (session->cmd == G_OBEX_OP_GET)
>+		return TRUE;
>+	else
>+		return FALSE;
>+}
>+
>+static gboolean transfer_get_operation(const GDBusPropertyTable
>*property,
>+					DBusMessageIter *iter, void *data) {
>+	struct obex_transfer *transfer = data;
>+	struct obex_session *session = transfer->session;
>+	const char *operation;
>+
>+	if (session->cmd == G_OBEX_OP_PUT &&
>+				session->size != OBJECT_SIZE_DELETE)
>+		operation = "PUT";
>+	else if (session->cmd == G_OBEX_OP_GET)
>+		operation = "GET";
>+	else
>+		return FALSE;
>+
>+	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
>&operation);
>+
>+	return TRUE;
>+}
>+
> static gboolean transfer_get_transferred(const GDBusPropertyTable
>*property,
> 					DBusMessageIter *iter, void *data)  { @@ -549,6
>+585,8 @@ static const GDBusPropertyTable transfer_properties[] = {
> 	{ "Time", "t", transfer_get_time, NULL, transfer_time_exists },
> 	{ "Filename", "s", transfer_get_filename, NULL,
> 						transfer_filename_exists },
>+	{ "Operation", "s", transfer_get_operation, NULL,
>+						transfer_operation_exists },
> 	{ "Transferred", "t", transfer_get_transferred },
> 	{ }
> };
>--
>1.7.7
>
>--
>To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
>the body of a message to majordomo@vger.kernel.org More majordomo
>info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH] Bluetooth: Use only 2 bits for controller type information
From: Marcel Holtmann @ 2013-09-29  4:09 UTC (permalink / raw)
  To: linux-bluetooth

The controller type is limited to BR/EDR/LE and AMP controllers. This
can be easily encoded with just 2 bits and still leave enough room
for future controller types.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 4549b5c..ebba5a6 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1610,7 +1610,7 @@ int hci_get_dev_info(void __user *arg)
 
 	strcpy(di.name, hdev->name);
 	di.bdaddr   = hdev->bdaddr;
-	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
+	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x30) << 4);
 	di.flags    = hdev->flags;
 	di.pkt_type = hdev->pkt_type;
 	if (lmp_bredr_capable(hdev)) {
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH] Bluetooth: Replace BDADDR_LOCAL with BDADDR_NONE
From: Marcel Holtmann @ 2013-09-29  8:01 UTC (permalink / raw)
  To: linux-bluetooth

The BDADDR_LOCAL is a relict from userspace and has never been used
within the kernel. So remove that constant and replace it with a new
BDADDR_NONE that is similar to HCI_DEV_NONE with all bits set.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/bluetooth.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index afbc711..5fd5106 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -197,8 +197,8 @@ static inline bool bdaddr_type_is_le(__u8 type)
 	return false;
 }
 
-#define BDADDR_ANY   (&(bdaddr_t) {{0, 0, 0, 0, 0, 0} })
-#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff} })
+#define BDADDR_ANY  (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
+#define BDADDR_NONE (&(bdaddr_t) {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}})
 
 /* Copy, swap, convert BD Address */
 static inline int bacmp(const bdaddr_t *ba1, const bdaddr_t *ba2)
-- 
1.8.3.1


^ permalink raw reply related

* [RFC] Bluetooth: Add command for setting static address
From: Marcel Holtmann @ 2013-09-29  8:05 UTC (permalink / raw)
  To: linux-bluetooth

Add command for setting static address for use as LE random address.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci.h      |  2 ++
 include/net/bluetooth/hci_core.h |  1 +
 include/net/bluetooth/mgmt.h     |  6 ++++++
 net/bluetooth/hci_core.c         |  5 +++++
 net/bluetooth/mgmt.c             | 43 +++++++++++++++++++++++++++++++++++++++-
 5 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 7ede266..809bdf8 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -977,6 +977,8 @@ struct hci_rp_le_read_local_features {
 	__u8     features[8];
 } __packed;
 
+#define HCI_OP_LE_SET_RANDOM_ADDR	0x2005
+
 #define HCI_OP_LE_READ_ADV_TX_POWER	0x2007
 struct hci_rp_le_read_adv_tx_power {
 	__u8	status;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 26cc9f7..e09c305 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -140,6 +140,7 @@ struct hci_dev {
 	__u8		bus;
 	__u8		dev_type;
 	bdaddr_t	bdaddr;
+	bdaddr_t	static_addr;
 	__u8		dev_name[HCI_MAX_NAME_LENGTH];
 	__u8		short_name[HCI_MAX_SHORT_NAME_LENGTH];
 	__u8		eir[HCI_MAX_EIR_LENGTH];
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 421d763..823ec2d 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -354,6 +354,12 @@ struct mgmt_cp_set_device_id {
 
 #define MGMT_OP_SET_ADVERTISING		0x0029
 
+#define MGMT_OP_SET_STATIC_ADDRESS	0x002B
+struct mgmt_cp_set_static_address {
+	bdaddr_t bdaddr;
+} __packed;
+#define MGMT_SET_STATIC_ADDRESS_SIZE	6
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16	opcode;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 4549b5c..3f1fb1b 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -393,6 +393,11 @@ static void le_setup(struct hci_request *req)
 	/* LE-only controllers have LE implicitly enabled */
 	if (!lmp_bredr_capable(hdev))
 		set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
+
+	/* Set random address to static address if configured */
+	if (bacmp(&hdev->static_addr, BDADDR_ANY))
+		hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6,
+			    &hdev->static_addr);
 }
 
 static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 1b5b10f..fdc591b 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -77,6 +77,7 @@ static const u16 mgmt_commands[] = {
 	MGMT_OP_UNBLOCK_DEVICE,
 	MGMT_OP_SET_DEVICE_ID,
 	MGMT_OP_SET_ADVERTISING,
+	MGMT_OP_SET_STATIC_ADDRESS,
 };
 
 static const u16 mgmt_events[] = {
@@ -3230,6 +3231,46 @@ unlock:
 	return err;
 }
 
+static int set_static_address(struct sock *sk, struct hci_dev *hdev,
+			      void *data, u16 len)
+{
+	struct mgmt_cp_set_static_address *cp = data;
+	int err;
+
+	BT_DBG("%s", hdev->name);
+
+	if (!lmp_le_capable(hdev))
+		return cmd_status(sk, hdev->id, MGMT_OP_SET_STATIC_ADDRESS,
+				  MGMT_STATUS_NOT_SUPPORTED);
+
+	if (hdev_is_powered(hdev))
+		return cmd_status(sk, hdev->id, MGMT_OP_SET_STATIC_ADDRESS,
+				  MGMT_STATUS_BUSY);
+
+	if (bacmp(&cp->bdaddr, BDADDR_ANY)) {
+		if (!bacmp(&cp->bdaddr, BDADDR_NONE))
+			return cmd_status(sk, hdev->id,
+					  MGMT_OP_SET_STATIC_ADDRESS,
+					  MGMT_STATUS_INVALID_PARAMS);
+
+		/* Two most significant bits shall be set */
+		if ((cp->bdaddr.b[5] & 0xc0) != 0xc0)
+			return cmd_status(sk, hdev->id,
+					  MGMT_OP_SET_STATIC_ADDRESS,
+					  MGMT_STATUS_INVALID_PARAMS);
+	}
+
+	hci_dev_lock(hdev);
+
+	bacpy(&hdev->static_addr, &cp->bdaddr);
+
+	err = cmd_complete(sk, hdev->id, MGMT_OP_SET_STATIC_ADDRESS, 0, NULL, 0);
+
+	hci_dev_unlock(hdev);
+
+	return err;
+}
+
 static void fast_connectable_complete(struct hci_dev *hdev, u8 status)
 {
 	struct pending_cmd *cmd;
@@ -3442,9 +3483,9 @@ static const struct mgmt_handler {
 	{ unblock_device,         false, MGMT_UNBLOCK_DEVICE_SIZE },
 	{ set_device_id,          false, MGMT_SET_DEVICE_ID_SIZE },
 	{ set_advertising,        false, MGMT_SETTING_SIZE },
+	{ set_static_address,     false, MGMT_SET_STATIC_ADDRESS_SIZE },
 };
 
-
 int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
 {
 	void *buf;
-- 
1.8.3.1


^ permalink raw reply related

* Re: FW: [PATCH 1/2] obexd:Add Operation property to transfer properties
From: Luiz Augusto von Dentz @ 2013-09-29  8:38 UTC (permalink / raw)
  To: Zheng, Wu
  Cc: Von Dentz, Luiz, Hedberg, Johan, linux-bluetooth@vger.kernel.org
In-Reply-To: <2CF57A644018A745B8FE029C7223E16E1179670E@SHSMSX104.ccr.corp.intel.com>

Hi,

On Sun, Sep 29, 2013 at 6:03 AM, Zheng, Wu <wu.zheng@intel.com> wrote:
> Hi Luiz,
>
> Can you help review the patches? Thanks

First, please do not top post.

> Best Regards
> Zheng Wu
>
>>-----Original Message-----
>>From: linux-bluetooth-owner@vger.kernel.org
>>[mailto:linux-bluetooth-owner@vger.kernel.org] On Behalf Of Wu Zheng
>>Sent: Tuesday, September 24, 2013 3:37 PM
>>To: linux-bluetooth@vger.kernel.org
>>Cc: Zheng, Wu
>>Subject: [PATCH 1/2] obexd:Add Operation property to transfer properties
>>
>>Sometime, operation property is needed by the Bluetooth APP.
>>Therefore, add the property to transfer properties
>>---

You probably need to work on to why we need such property, I have no
idea what you are reference to a Bluetooth APP, obviously is not the
application that have created the transfer since that know should know
what operation will be used.

If this is for some kind of download manager application that you are
talking about Im not sure why it would like to know the operation? Is
that to display the direction? Im not really sure this will be
convenient for a download manager but I would not expose the operation
itself probably upload/download or add new status
uploading/downloading.



-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH 2/2] obexd:Add get_address property to transfer properties
From: Luiz Augusto von Dentz @ 2013-09-29  8:40 UTC (permalink / raw)
  To: Wu Zheng; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1380008250-30536-1-git-send-email-wu.zheng@intel.com>

Hi,

On Tue, Sep 24, 2013 at 10:37 AM, Wu Zheng <wu.zheng@intel.com> wrote:
> Sometime, address is needed by the Bluetooth OBEX APP.
> Therefore, add the property to transfer properties
> ---
>  obexd/src/manager.c |   37 +++++++++++++++++++++++++++++++++++++
>  1 files changed, 37 insertions(+), 0 deletions(-)
>
> diff --git a/obexd/src/manager.c b/obexd/src/manager.c
> index 96976ec..b338a72 100644
> --- a/obexd/src/manager.c
> +++ b/obexd/src/manager.c
> @@ -551,6 +551,41 @@ static gboolean transfer_get_operation(const GDBusPropertyTable *property,
>         return TRUE;
>  }
>
> +static gboolean transfer_address_exists(const GDBusPropertyTable *property,
> +                                                               void *data)
> +{
> +       struct obex_transfer *transfer = data;
> +       struct obex_session *session = transfer->session;
> +       char *address;
> +       int err;
> +
> +       err = obex_getpeername(session, &address);
> +       if (err < 0)
> +               return FALSE;
> +
> +       g_free(address);
> +
> +       return TRUE;
> +}
> +
> +static gboolean transfer_get_address(const GDBusPropertyTable *property,
> +                                       DBusMessageIter *iter, void *data)
> +{
> +       struct obex_transfer *transfer = data;
> +       struct obex_session *session = transfer->session;
> +       char *address;
> +       int err;
> +
> +       err = obex_getpeername(session, &address);
> +       if (err < 0)
> +               return FALSE;
> +
> +       dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &address);
> +       g_free(address);
> +
> +       return TRUE;
> +}
> +
>  static gboolean transfer_get_transferred(const GDBusPropertyTable *property,
>                                         DBusMessageIter *iter, void *data)
>  {
> @@ -587,6 +622,8 @@ static const GDBusPropertyTable transfer_properties[] = {
>                                                 transfer_filename_exists },
>         { "Operation", "s", transfer_get_operation, NULL,
>                                                 transfer_operation_exists },
> +       { "Address", "s", transfer_get_address, NULL,
> +                                               transfer_address_exists },
>         { "Transferred", "t", transfer_get_transferred },
>         { }
>  };
> --
> 1.7.7

Nack, you can already access the Address via Session interface.


-- 
Luiz Augusto von Dentz

^ permalink raw reply


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